Spell System
KeyMasterOfGozer edited this page 5 years ago

The Spell System is constructed as a meta-data driven engine, much like the NPC lists. The idea here is that to create a new spell, you only have to fill out some meta-data in a few arrays, then make one relatively simple procedure to insert a new spell into the game. The CheatMenu, Learning, Casting, other listings are all already handled by the engine by virtue of the inherent lists.

To make a new spell, you only have to insert the spell into 2 files.

1) spellList

  • basic spell meta-data
  • where spell is executed from
  • where spell is learned

2) spell

  • make a procedure here that is the "guts" of the spell. This does the basics of manipulating the variables as to the actual game impacts fo this spell.

Basic Spell Meta-Data

1) spellMana = How much mana does it cost to cast this spell

2) spellTime = How much time does it take to cast this spell in minutes. This will make time pass as you cast the spell.

3) spellDiff = Difficulty of the spell. Roughly, this equats to what you magic level must be to learn the spell as well as how often it will fail.

4) $spellName = The "Pretty" name of the spell that the user sees.

5) $spellDesc = The description of the spell for the user.

6) spellReq = This lets you assign a spell that must be learned before this spell can be learned. A Prerequisite.

7) $spellOptDesc = The value here is the name of an array of options that the user must pick to execute a spell. For instance, if the spell changes eye color, the array represented here would be a list of eye colors in a user-friendly spelling ('Blue','Brown,'Green').

8) $spellOptVal = The value here is the name of an array of values to be passed to the procedure. These values may not be understandble to the user, for instance if setting eyecolor, 0=blue,1=brown,2=green, you might have values '0','1','2'.

$spellOptDesc and $spellOptVal can be the same array, but do not have to be.

Let's look at some examples:

Teleport:

spellMana['teleport'] = 1000
spellTime['teleport'] = 20
spellDiff['teleport'] = 20
$spellName['teleport'] = 'Teleport'
$spellDesc['teleport'] = 'You can move from one Fairy Circle to another.'
$spellOptDesc['teleport'] = '$treeCircName'
$spellOptVal['teleport'] = '$tpLocations'

Note that this spell has options. The $treeCircName array has Human readable strings for each Option. $tpLocations has the parameter values that the procedure expects. You can use arrays defined anywhere. These happen to be defined in the treeCircle file.

Cosmetica:

spellMana['cosmetica'] = 10000
spellTime['cosmetica'] = 5
spellDiff['cosmetica'] = 50
$spellName['cosmetica'] = 'Cosmetica'
$spellDesc['cosmetica'] = 'Clean and tidy yourself, completely beautifying yourself; hair, makeup, grooming of all kinds.'
$spellReq['cosmetica'] = 'makeup'

Note that since Cosmetica is the more powerful version of Makeup, makeup is listed as the Prequisite spell.

Where Spell is executed from (How to cast a Spell)

Currently there are only 2 execution points.

1) Combat Spells - $combatSpells[] - these are executed in combat

2) Non-Combat Spells - $nonComSpells[] - these are executed from the spell book anywhere in the world.

You should place your new spell into one of the Arrays to represent where the spell should be exectute. You may notice that the spell heal is in both sets. As long as a spell is compatible with both type, you can do that.

Normally, the user will jsut pick the spell to cast from one of those two locations, but one can force a spell cast in code by directly calling the castSpell procedure.

gs 'castSpell', 'regeneration'

Where Spell is learned.

The spell is can also be put into one or more lists that represent where the spell is to be learned from. You may notice there are about a dozen near the bottom of the spellList file. These lists represent groupings of spells, most notably this is where each of these spells will be learned.

One simple line can be inculded as an action for any NPC that will teach one of these spell lists:

	! Show Actions for Learning Spells
	gs 'spellList', 'teacherActions', '$basicSpells', 'lab', 'Tatiana'

This example is from Tatiana's Lab, where she teaches Basic spells. This procedure will add actions for learning any spells in that list that Sveta doesn't already know and that Sveta meets the requirements to learn. She needs pcs_magik at least as high as the spell difficulty and know the Prerequisite spell, if any.

Currently, Tatiana teaches Basic and Healing. Beauty spells are learned by studying in the St. Pete Library. All Elemental spells are taught by Kakuzu in his mansion.

What the spell does

The procedure should most likely be very simple, but it can have up to 3 parts.

1) What happens right now? This instant the spell goes off, stuff happens.

2) The spell can make stuff happen over time. This is generally called ticks. Something happens every minute the spell is active.

3) Something can happen when the Spell's duration is over and the spell goes away.

The last two parts are controlled by the spellTimer procedure. This sets up spell elements to "go off" at a later time.

Let's look at some examples:

Cure Wounds

if $ARGS[0] = 'curewounds':
	if SuccessValue > 0:
		! Remove some pain
		gs 'medical_din','healthTreatment'
		gs 'medical_din','healthTreatment'
		'<b><font color = green>You feel yourself coursing with life.  You feel better already.</font></b>'
	else
		'<b>The spell fizzles.  Nothing seems to happen.</b>'
	end
end

This one simply runs the medical_din procedure twice to boost health for Sveta

Regenerate

if $ARGS[0] = 'regenerate':
	if SuccessValue > 0:
		! How much health is gained per minute
		regenVal = 5 * SuccessValue
		! Immediate health gain
		pcs_health += regenVal
		! If Regenerate is already running, we only extend.
		regenArrIdx = arrpos('$spellTimeName','regenerate')
		if regenArrIdx > -1:
			! if it''s found, then update only
			spellComplete[regenArrIdx] = totminut + 120
			$spellCompExec[regenArrIdx] = 'pcs_health += (5 * <<regenVal>>)'
			$spellTickExec[regenArrIdx] = 'pcs_health += <<regenVal>>'
		else
			! Add Timer:
			!	spellName = 'regenerate'
			!	duration  = 120
			!	CompCode = 'pcs_health += (5 * <<regenVal>>)'
			!	TickCode = 'pcs_health += <<regenVal>>'
			gs 'spellTimer', 'add', 'regenerate', 120, 'pcs_health += (5 * <<regenVal>>)', 'pcs_health += <<regenVal>>'
		end

		'<b><font color = green>Your body surges with life. You feel better already.</font></b>'
		killvar 'regenVal'
		killvar 'regenArrIdx'
	else
		'<b>The spell fizzles.  Nothing seems to happen.</b>'
	end
end

Notice Regenerate gives an immediate health boost (line 6) and also sets up a timer via the spellTimer procedure (line 20). The spellTimer procedure in this case will give a small health boost every minute (TickCode), and finsh with another large health boost (CompCode).