-
Notifications
You must be signed in to change notification settings - Fork 68
Spells
SPELLDATA
record is defined in the save file formats.
The parameters Param0-5
each contain three entries, each of which is relative to one of the three possible effects a spell can have (specified in Effects
).
Values for TargetType
:
0x00 Self
0x01 Touch
0x02 Target
Values for Element
:
0x00 Fire
0x01 Ice
0x02 Poison
0x03 Shock
0x04 Magic
0x05 None
Values for Effects
/Subeffects
:
0x00 Cause
0 Disease
1 Poison
2 Paralysis
3 Curse
4 Death
0x01 Continuous Damage
0 Health
1 Fatigue
2 Spell points
0x02 Create
0 Shield
1 Wall
2 Floor
0x03 Cure
0 Disease
1 Poison
2 Paralysis
3 Curse
0x04 Damage
0 Health
1 Fatigue
2 Spell points
0x05 Designate as non-target
0x06 Destroy
0 Wall
1 Floor
2 (not implemented)
0x07 Disintegrate
0x08 (not implemented)
0x09 Drain
0 ???
1 ???
0x0A Elemental resistance
0x0B Fortify attribute
0x0C Heal
0 Stamina
1 Health
2 Spell points
3 Attribute
0x0D Transfer Attribute
0 Attribute
1 Health/Stamina/SP
0x0E (unimplemented)
0x0F Invisibility
0x10 Levitate
0x11 Light
0x12 Lock
0x13 Open
0x14 Regenerate
0x15 Silence
0x16 Spell Absorption
0x17 Spell Reflection
0x18 Spell Resistance
LVL
is the 1-based caster level, as presented in the game UI. []
mean rounding down.
Cause disease
chance <- P0+[LVL/P4]*P1
if chance > rnd() mod 100 then
if caster == player then message("Success")
duration <- LVL*P5
unk1 <- P3
magnitude <- -(P2)
if target == player then
disease <- randomFromList([10, 11, 12, 14, 15, 17, 19, 20, 21, 22, 24, 25, 26]
target.addDisease(disease)
else
target.setStatusFlag(DISEASE)
for i in (STR, AGI, SPD, END)
target.stat[i] <- target.stat[i] + magnitude
endif
else
if caster == player then message("Failure")
endif
Cause poison
if target.hasEffect(POISON_RESIST) then return
if target.class == BARBARIAN then return
chance <- P0+[LVL/P4]*P1
if chance > rnd() mod 100 then
if caster == player then message("Success")
duration <- LVL*P5
unk1 <- P3
magnitude <- -(P2)
magnitude <- target.correctMagnitude(magnitude, POISON)
target.addEffect(<poison>)
else
if caster == player then message("Failure")
endif
Cause paralysis
if target.race == HIGH_ELF then return
if target.class == KNIGHT then return
chance <- P0+[LVL/P4]*P1
if chance > rnd() mod 100 then
if caster == player then message("Success")
duration <- [LVL/P2]*P5 + P5
target.addEffect(<paralyze>)
else
if caster == player then message("Failure")
endif
Cause curse
chance <- P0+[LVL/P4]*P1
if chance > rnd() mod 100 then
if caster == player then message("Success")
duration <- LVL*P5
unk1 <- P3
magnitude <- -(P2)
target.setStatusFlag(CURSE)
for i in (INT, WIL, PER, LUC)
target.stat[i] <- target.stat[i] + magnitude
else
if caster == player then message("Failure")
endif
Cause death
chance <- P0+[LVL/P4]*P1
if chance > rnd() mod 100 then
if caster == player then message("Success")
target.kill()
else
if caster == player then message("Failure")
endif
Continuous damage health
magnitude <- -(rnd(P1, P1 + 1) + rnd(P2, P3 + 1) * [LVL/P4])
duration <- P5
unk1 <- 1
magnitude <- target.damageShield(magnitude) # the magic shield
magnitude <- target.correctMagnitude(magnitude, element)
target.setStatusFlag(DRAINED)
target.addEffect(<dot>)
Continuous damage fatigue
magnitude <- -(rnd(P1, P1 + 1) + rnd(P2, P3 + 1) * [LVL/P4])
duration <- P5
unk1 <- 1
target.setStatusFlag(DRAINED)
target.addEffect(<dot to fatigue>)
Continuous damage spell points
magnitude <- -(rnd(P1, P1 + 1) + rnd(P2, P3 + 1) * [LVL/P4])
duration <- P5
unk1 <- 1
target.setStatusFlag(DRAINED)
target.addEffect(<dot to mana>)
Create shield
target.setShield(P0 + P1*[LVL/P4])
if caster == player then message("Success")
Create wall (floor)
if caster != player then return
if currentZoneType == CITY then
message("Failure")
return
endif
wallsToCreateDestroy <- P0 # (or floorsToCreateDestroy)
Cure disease (paralysis, curse)
chance <- P0 + P1 * [LVL/P4]
if chance > rnd() mod 100 then
if caster == player then message("Success")
target.removeEffect(DISEASE) # PARALYSIS, CURSE
else
if caster == player then message("Failure")
endif
Cure poison
chance <- P0 + P1 * [LVL/P4]
if chance > rnd() mod 100 then
if caster == player then message("Success")
target.removeEffect(POISON)
target.removeEffect(PARALYSIS) # sic
else
if caster == player then message("Failure")
endif
Damage Health
magnitude <- -( rnd(P0, P1+1) + rnd(P2, P3+1) * [LVL/P4] )
magnitude <- target.damageShield(magnitude) # the magic shield
magnitude <- target.correctMagnitude(magnitude, element)
if target.hasEffect(REGENERATION) and target!=player then
target.maxHP <- target.maxHP + magnitude
endif
target.curHP <- min(target.curHP + magnitude, target.maxHP)
if target==player then <check PC death>
<handle the target health change as after the physical attack>
Damage Stamina
magnitude <- -( rnd(P0, P1+1) + rnd(P2, P3+1) * [LVL/P4] )
target.curStamina <- target.curStamina + magnitude
Damage Spellpoints
magnitude <- -( rnd(P0, P1+1) + rnd(P2, P3+1) * [LVL/P4] )
target.curMana <- max(target.curMana + magnitude, 0)
Designate as non-target
chance <- P0 + P1 * [LVL/P4]
if chance > rnd() mod 100 then
if caster == player then message("Success")
duration <- ([LVL/P2] + 1) * P5
if flag & 0x100 then opt <- 0 else opt <- -1
target.setTimer(TIMER_NONTARGET, duration, opt)
target.addEffect(NONTARGET)
else
if caster == player then message("Failure")
Destroy wall (floor)
if caster != player then return
if currentZoneType == CITY then
message("Failure")
return
endif
wallsToCreateDestroy <- -(P0) # (or floorsToCreateDestroy)
Desintegrate
chance <- P0 + P1 * [LVL/P4]
if chance > rnd() mod 100 then
if caster == player then message("Success")
target.curHP <- -1
<handle the target health change as after the physical attack>
else
if caster == player then message("Failure")
Drain Attribute (to do)
Elemental resistance
duration <- P0 + P1 * [LVL/P4]
chance <- P5 * [(player.level + 1)/P2]
target.setTimer(TIMER_FIRERESISTANCE+element, duration, chance)
target.addEffect(FIRERESISTANCE+element)
Different spell effects use different parameters:
Drain Attribute
param0 pts of attribute drained for param5 rounds per level. Target recover
attribute at param1 pts per param4 rounds
Fortify attribute
+param0 pts of attribute for param5 rnds per level. attribute loss of param1
pts per param4 rounds.
Heal attribute
param0 to param1 pts to attribute +param2 to param3 per param4 levels
Transfer attribute
Transfers param0 pts of attribute from target to caster
Invisibility
param0 rounds + param1 rounds per param4 levels
Levitate
param0 rounds + param1 rounds per param4 levels
Light
param5 rounds per level
Lock
param0 chance of locking. duration is param5 rounds per param2 levels
lock strength + param1 % per param4 levels
Open
param0 chance of unlocking, + param1% per param4 levels
Regenerate
param0 health every param1 rounds for param4 rounds per level
Silence
param0 chance of silencing for param5 rounds per param2 levels, + param1 %
per param4 levels
Spell Absorption
param0 chance to absorb + param1 % per param4 levels. duration is param5
rounds per param2 levels
Spell reflection
param0 chance to reflect + param1 % per param4 levels. duration is param5
rounds per param2 levels
Spell resistance
param0 chance to resist + param1 % per param4 levels. duration is param5
rounds per param2 levels
0 Strength
1 Intelligence
2 Willpower
3 Agility
4 Speed
5 Endurance
6 Personality
7 Luck
(to do)
a int duration
b string "not" if (flag & 0x80)
c string attribute
e string "caster"
f string "is a projectile" if (flag & 0x80) else "follows the caster"
# int spell parameter
% string "%"