Spell stuff. Autocast disabled. HolyVision implemented with summon. Save conditions.
This commit is contained in:
parent
fb06d9d144
commit
7d4a583f6b
4 changed files with 309 additions and 289 deletions
src
|
@ -74,7 +74,8 @@ global void AiCheckMagic(void)
|
|||
if(unit->Type->CanCastSpell) {
|
||||
for (j = 0; j < SpellTypeCount; j++) {
|
||||
// Check if we can cast this spell. SpellIsAvailable checks for upgrades.
|
||||
if (unit->Type->CanCastSpell[j] && SpellIsAvailable(player, j)) {
|
||||
if (unit->Type->CanCastSpell[j] && SpellIsAvailable(player, j) &&
|
||||
SpellTypeById(j)->AutoCast) {
|
||||
#ifdef DEBUG
|
||||
success = // Follow on next line (AutoCastSpell).
|
||||
#endif
|
||||
|
|
|
@ -89,82 +89,81 @@ typedef enum {
|
|||
#endif
|
||||
} TargetType;
|
||||
|
||||
/*
|
||||
** Pointer on function that cast the spell.
|
||||
*/
|
||||
typedef int SpellFunc(Unit* caster, const struct _spell_type_* spell, Unit* target,int x, int y);
|
||||
|
||||
|
||||
|
||||
typedef union
|
||||
typedef struct
|
||||
{
|
||||
// FIXME rename structure more properly.
|
||||
// TTL's below are in ticks: approx: 500=13sec, 1000=25sec, 2000=50sec
|
||||
// FIXME use TTL, as in TICKS to live
|
||||
struct {
|
||||
int Fields; /// The size of the affected square
|
||||
int Shards; /// Number of shards thrown.
|
||||
int Damage; /// Damage for every shard.
|
||||
/// The offset of the missile start point to the hit location.
|
||||
int StartOffsetX;
|
||||
int StartOffsetY;
|
||||
} AreaBombardment;
|
||||
|
||||
struct {
|
||||
UnitType *PortalType; /// The unit type spawned
|
||||
} SpawnPortal;
|
||||
|
||||
struct {
|
||||
int TTL; /// time to live (ticks)
|
||||
int Damage; /// Damage.
|
||||
} Fireball;
|
||||
|
||||
struct {
|
||||
int TTL; /// time to live (ticks)
|
||||
} FlameShield;
|
||||
SpellFunc* CastFunction;
|
||||
union {
|
||||
// FIXME time information doesn't work as it should.
|
||||
struct {
|
||||
int Fields; /// The size of the affected square
|
||||
int Shards; /// Number of shards thrown.
|
||||
int Damage; /// Damage for every shard.
|
||||
/// The offset of the missile start point to the hit location.
|
||||
int StartOffsetX;
|
||||
int StartOffsetY;
|
||||
} AreaBombardment;
|
||||
|
||||
struct {
|
||||
UnitType *PortalType; /// The unit type spawned
|
||||
} SpawnPortal;
|
||||
|
||||
struct {
|
||||
int TTL; /// time to live (ticks)
|
||||
int Damage; /// Damage.
|
||||
} Fireball;
|
||||
|
||||
struct {
|
||||
int TTL; /// time to live (ticks)
|
||||
} FlameShield;
|
||||
|
||||
struct {
|
||||
int HasteTicks; /// Number of ticks to set Haste to.
|
||||
int SlowTicks; /// Number of ticks to set Slow to.
|
||||
int BloodlustTicks; /// Number of ticks to set Bloodlust to.
|
||||
int InvisibilityTicks; /// Number of ticks to set Invisibility to.
|
||||
int InvincibilityTicks; /// Number of ticks to set UnholyArmor to.
|
||||
struct {
|
||||
int HasteTicks; /// Number of ticks to set Haste to.
|
||||
int SlowTicks; /// Number of ticks to set Slow to.
|
||||
int BloodlustTicks; /// Number of ticks to set Bloodlust to.
|
||||
int InvisibilityTicks; /// Number of ticks to set Invisibility to.
|
||||
int InvincibilityTicks; /// Number of ticks to set UnholyArmor to.
|
||||
#define BUFF_NOT_AFFECTED 0xC0FF33 /// Don't like the value? The value doesn't like you!
|
||||
} AdjustBuffs;
|
||||
|
||||
struct {
|
||||
int HP; /// Target HP gain.(can be negative)
|
||||
int Mana; /// Target Mana gain.(can be negative)
|
||||
/// This spell is designed to be used wit very small amounts. The spell
|
||||
/// can scale up to MaxMultiCast times. Use 0 for infinite.
|
||||
int MaxMultiCast;
|
||||
} AdjustVitals;
|
||||
|
||||
struct {
|
||||
UnitType *revealer; /// Type of unit to be summoned: (unit-revealer).
|
||||
} HolyVision;
|
||||
|
||||
struct {
|
||||
UnitType *NewForm; /// The new form
|
||||
// TODO: temporary polymorphs would be awesome, but hard to implement
|
||||
} Polymorph;
|
||||
|
||||
struct {
|
||||
UnitType *UnitType; /// Type of unit to be summoned.
|
||||
int TTL; /// Time to live for summoned unit. 0 means infinite
|
||||
} Summon;
|
||||
|
||||
struct {
|
||||
UnitType *UnitRaised; /// The unit to spawn from corpses
|
||||
int TTL; /// Time to live for summon. 0 means infinite.
|
||||
} RaiseDead;
|
||||
// What about a resurection spell?
|
||||
} AdjustBuffs;
|
||||
|
||||
struct {
|
||||
int HP; /// Target HP gain.(can be negative)
|
||||
int Mana; /// Target Mana gain.(can be negative)
|
||||
/// This spell is designed to be used wit very small amounts. The spell
|
||||
/// can scale up to MaxMultiCast times. Use 0 for infinite.
|
||||
int MaxMultiCast;
|
||||
} AdjustVitals;
|
||||
|
||||
struct {
|
||||
UnitType *NewForm; /// The new form
|
||||
// TODO: temporary polymorphs would be awesome, but hard to implement
|
||||
} Polymorph;
|
||||
|
||||
struct {
|
||||
UnitType *UnitType; /// Type of unit to be summoned.
|
||||
int TTL; /// Time to live for summoned unit. 0 means infinite
|
||||
} Summon;
|
||||
|
||||
struct {
|
||||
UnitType *UnitRaised; /// The unit to spawn from corpses
|
||||
int TTL; /// Time to live for summon. 0 means infinite.
|
||||
} RaiseDead;
|
||||
// What about a resurection spell?
|
||||
|
||||
struct {
|
||||
int TTL; /// time to live (ticks)
|
||||
int Damage; /// Damage.
|
||||
} Runes;
|
||||
|
||||
struct {
|
||||
int TTL; /// time to live (ticks)
|
||||
// FIXME: more configurations
|
||||
} Whirlwind;
|
||||
struct {
|
||||
int TTL; /// time to live (ticks)
|
||||
int Damage; /// Damage.
|
||||
} Runes;
|
||||
|
||||
struct {
|
||||
int TTL; /// time to live (ticks)
|
||||
// FIXME: more configurations
|
||||
} Whirlwind;
|
||||
} Data;
|
||||
} SpellActionType;
|
||||
|
||||
/*
|
||||
|
@ -242,11 +241,6 @@ typedef struct {
|
|||
|
||||
struct _spell_type_;
|
||||
|
||||
/*
|
||||
** Pointer on function that cast the spell.
|
||||
*/
|
||||
typedef int SpellFunc(Unit* caster, const struct _spell_type_* spell, Unit* target,int x, int y);
|
||||
|
||||
/**
|
||||
** Base structure of a spell type.
|
||||
*/
|
||||
|
@ -258,8 +252,7 @@ typedef struct _spell_type_ {
|
|||
|
||||
// Spell Specifications
|
||||
TargetType Target; /// Targetting information. See TargetType.
|
||||
SpellFunc *CastFunction; /// function to cast the spell.
|
||||
SpellActionType *SpellAction; /// More arguments for spell (damage, delay, additional sounds...).
|
||||
SpellActionType *Action; /// More arguments for spell (damage, delay, additional sounds...).
|
||||
#define INFINITE_RANGE 0xFFFFFFF
|
||||
int Range; /// Max range of the target.
|
||||
int ManaCost; /// required mana for each cast
|
||||
|
@ -336,7 +329,6 @@ extern unsigned CclGetSpellByIdent(SCM value);
|
|||
** Spelltype to cast.
|
||||
*/
|
||||
|
||||
SpellFunc CastHolyVision;
|
||||
SpellFunc CastAdjustVitals;
|
||||
SpellFunc CastAdjustBuffs;
|
||||
SpellFunc CastFireball;
|
||||
|
@ -350,7 +342,6 @@ SpellFunc CastRaiseDead;
|
|||
SpellFunc CastWhirlwind;
|
||||
SpellFunc CastSpawnPortal;
|
||||
|
||||
|
||||
//@}
|
||||
|
||||
#endif // !__SPELLS_H__
|
||||
|
|
|
@ -109,36 +109,36 @@ local void CclParseSpellAction(SCM list, SpellType* spell, SpellActionType *spel
|
|||
|
||||
memset(spellaction, 0, sizeof(*spellaction));
|
||||
if (gh_eq_p(value,gh_symbol2scm("area-bombardment"))) {
|
||||
spell->CastFunction=CastAreaBombardment;
|
||||
spellaction->CastFunction=CastAreaBombardment;
|
||||
while (!gh_null_p(list)) {
|
||||
value = gh_car(list);
|
||||
list=gh_cdr(list);
|
||||
if (gh_eq_p(value, gh_symbol2scm("fields"))) {
|
||||
spellaction->AreaBombardment.Fields = gh_scm2int(gh_car(list));
|
||||
spellaction->Data.AreaBombardment.Fields = gh_scm2int(gh_car(list));
|
||||
list = gh_cdr(list);
|
||||
} else if (gh_eq_p(value, gh_symbol2scm("shards"))) {
|
||||
spellaction->AreaBombardment.Shards = gh_scm2int(gh_car(list));
|
||||
spellaction->Data.AreaBombardment.Shards = gh_scm2int(gh_car(list));
|
||||
list = gh_cdr(list);
|
||||
} else if (gh_eq_p(value, gh_symbol2scm("damage"))) {
|
||||
spellaction->AreaBombardment.Damage = gh_scm2int(gh_car(list));
|
||||
spellaction->Data.AreaBombardment.Damage = gh_scm2int(gh_car(list));
|
||||
list = gh_cdr(list);
|
||||
} else if (gh_eq_p(value, gh_symbol2scm("start-offset-x"))) {
|
||||
spellaction->AreaBombardment.StartOffsetX = gh_scm2int(gh_car(list));
|
||||
spellaction->Data.AreaBombardment.StartOffsetX = gh_scm2int(gh_car(list));
|
||||
list = gh_cdr(list);
|
||||
} else if (gh_eq_p(value, gh_symbol2scm("start-offset-y"))) {
|
||||
spellaction->AreaBombardment.StartOffsetY = gh_scm2int(gh_car(list));
|
||||
spellaction->Data.AreaBombardment.StartOffsetY = gh_scm2int(gh_car(list));
|
||||
list = gh_cdr(list);
|
||||
} else {
|
||||
errl("Unsupported area-bombardment tag",value);
|
||||
}
|
||||
}
|
||||
} else if (gh_eq_p(value,gh_symbol2scm("flame-shield"))) {
|
||||
spell->CastFunction=CastFlameShield;
|
||||
spellaction->CastFunction=CastFlameShield;
|
||||
while (!gh_null_p(list)) {
|
||||
value = gh_car(list);
|
||||
list=gh_cdr(list);
|
||||
if (gh_eq_p(value, gh_symbol2scm("duration"))) {
|
||||
spellaction->FlameShield.TTL = gh_scm2int(gh_car(list));
|
||||
spellaction->Data.FlameShield.TTL = gh_scm2int(gh_car(list));
|
||||
list = gh_cdr(list);
|
||||
/// FIXME:damage, missiles, rotation speed?
|
||||
} else {
|
||||
|
@ -146,107 +146,107 @@ local void CclParseSpellAction(SCM list, SpellType* spell, SpellActionType *spel
|
|||
}
|
||||
}
|
||||
} else if (gh_eq_p(value,gh_symbol2scm("fireball"))) {
|
||||
spell->CastFunction=CastFireball;
|
||||
spellaction->CastFunction=CastFireball;
|
||||
while (!gh_null_p(list)) {
|
||||
value = gh_car(list);
|
||||
list=gh_cdr(list);
|
||||
if (gh_eq_p(value, gh_symbol2scm("damage"))) {
|
||||
spellaction->Fireball.Damage = gh_scm2int(gh_car(list));
|
||||
spellaction->Data.Fireball.Damage = gh_scm2int(gh_car(list));
|
||||
list = gh_cdr(list);
|
||||
} else if (gh_eq_p(value, gh_symbol2scm("ttl"))) {
|
||||
spellaction->Fireball.TTL = gh_scm2int(gh_car(list));
|
||||
spellaction->Data.Fireball.TTL = gh_scm2int(gh_car(list));
|
||||
list = gh_cdr(list);
|
||||
} else {
|
||||
errl("Unsupported fireball tag",value);
|
||||
}
|
||||
}
|
||||
} else if (gh_eq_p(value,gh_symbol2scm("runes"))) {
|
||||
spell->CastFunction=CastRunes;
|
||||
spellaction->CastFunction=CastRunes;
|
||||
while (!gh_null_p(list)) {
|
||||
value = gh_car(list);
|
||||
list=gh_cdr(list);
|
||||
if (gh_eq_p(value, gh_symbol2scm("damage"))) {
|
||||
spellaction->Fireball.Damage = gh_scm2int(gh_car(list));
|
||||
spellaction->Data.Fireball.Damage = gh_scm2int(gh_car(list));
|
||||
list = gh_cdr(list);
|
||||
} else if (gh_eq_p(value, gh_symbol2scm("ttl"))) {
|
||||
spellaction->Fireball.TTL = gh_scm2int(gh_car(list));
|
||||
spellaction->Data.Fireball.TTL = gh_scm2int(gh_car(list));
|
||||
list = gh_cdr(list);
|
||||
} else {
|
||||
errl("Unsupported runes tag",value);
|
||||
}
|
||||
}
|
||||
} else if (gh_eq_p(value,gh_symbol2scm("whirlwind"))) {
|
||||
spell->CastFunction=CastWhirlwind;
|
||||
spellaction->CastFunction=CastWhirlwind;
|
||||
while (!gh_null_p(list)) {
|
||||
value = gh_car(list);
|
||||
list=gh_cdr(list);
|
||||
if (gh_eq_p(value, gh_symbol2scm("duration"))) {
|
||||
spellaction->Whirlwind.TTL = gh_scm2int(gh_car(list));
|
||||
spellaction->Data.Whirlwind.TTL = gh_scm2int(gh_car(list));
|
||||
list = gh_cdr(list);
|
||||
} else {
|
||||
errl("Unsupported runes tag",value);
|
||||
}
|
||||
}
|
||||
} else if (gh_eq_p(value,gh_symbol2scm("adjust-buffs"))) {
|
||||
spell->CastFunction=CastAdjustBuffs;
|
||||
spellaction->AdjustBuffs.HasteTicks=BUFF_NOT_AFFECTED;
|
||||
spellaction->AdjustBuffs.SlowTicks=BUFF_NOT_AFFECTED;
|
||||
spellaction->AdjustBuffs.BloodlustTicks=BUFF_NOT_AFFECTED;
|
||||
spellaction->AdjustBuffs.InvisibilityTicks=BUFF_NOT_AFFECTED;
|
||||
spellaction->AdjustBuffs.InvincibilityTicks=BUFF_NOT_AFFECTED;
|
||||
spellaction->CastFunction=CastAdjustBuffs;
|
||||
spellaction->Data.AdjustBuffs.HasteTicks=BUFF_NOT_AFFECTED;
|
||||
spellaction->Data.AdjustBuffs.SlowTicks=BUFF_NOT_AFFECTED;
|
||||
spellaction->Data.AdjustBuffs.BloodlustTicks=BUFF_NOT_AFFECTED;
|
||||
spellaction->Data.AdjustBuffs.InvisibilityTicks=BUFF_NOT_AFFECTED;
|
||||
spellaction->Data.AdjustBuffs.InvincibilityTicks=BUFF_NOT_AFFECTED;
|
||||
while (!gh_null_p(list)) {
|
||||
value = gh_car(list);
|
||||
list=gh_cdr(list);
|
||||
if (gh_eq_p(value, gh_symbol2scm("haste-ticks"))) {
|
||||
spellaction->AdjustBuffs.HasteTicks = gh_scm2int(gh_car(list));
|
||||
spellaction->Data.AdjustBuffs.HasteTicks = gh_scm2int(gh_car(list));
|
||||
list = gh_cdr(list);
|
||||
} else if (gh_eq_p(value, gh_symbol2scm("slow-ticks"))) {
|
||||
spellaction->AdjustBuffs.SlowTicks = gh_scm2int(gh_car(list));
|
||||
spellaction->Data.AdjustBuffs.SlowTicks = gh_scm2int(gh_car(list));
|
||||
list = gh_cdr(list);
|
||||
} else if (gh_eq_p(value, gh_symbol2scm("bloodlust-ticks"))) {
|
||||
spellaction->AdjustBuffs.BloodlustTicks = gh_scm2int(gh_car(list));
|
||||
spellaction->Data.AdjustBuffs.BloodlustTicks = gh_scm2int(gh_car(list));
|
||||
list = gh_cdr(list);
|
||||
} else if (gh_eq_p(value, gh_symbol2scm("invisibility-ticks"))) {
|
||||
spellaction->AdjustBuffs.InvisibilityTicks = gh_scm2int(gh_car(list));
|
||||
spellaction->Data.AdjustBuffs.InvisibilityTicks = gh_scm2int(gh_car(list));
|
||||
list = gh_cdr(list);
|
||||
} else if (gh_eq_p(value, gh_symbol2scm("invincibility-ticks"))) {
|
||||
spellaction->AdjustBuffs.InvincibilityTicks = gh_scm2int(gh_car(list));
|
||||
spellaction->Data.AdjustBuffs.InvincibilityTicks = gh_scm2int(gh_car(list));
|
||||
list = gh_cdr(list);
|
||||
} else {
|
||||
errl("Unsupported adjust-buffs tag",value);
|
||||
}
|
||||
}
|
||||
} else if (gh_eq_p(value,gh_symbol2scm("summon"))) {
|
||||
spell->CastFunction=CastSummon;
|
||||
spellaction->CastFunction=CastSummon;
|
||||
while (!gh_null_p(list)) {
|
||||
value = gh_car(list);
|
||||
list = gh_cdr(list);
|
||||
if (gh_eq_p(value, gh_symbol2scm("unit-type"))) {
|
||||
str = gh_scm2newstr(gh_car(list),0);
|
||||
spellaction->Summon.UnitType = UnitTypeByIdent(str);
|
||||
if (!spellaction->Summon.UnitType) {
|
||||
spellaction->Summon.UnitType = 0;
|
||||
spellaction->Data.Summon.UnitType = UnitTypeByIdent(str);
|
||||
if (!spellaction->Data.Summon.UnitType) {
|
||||
spellaction->Data.Summon.UnitType = 0;
|
||||
DebugLevel0("unit type \"%s\" not found for summon spell.\n" _C_ str);
|
||||
}
|
||||
free(str);
|
||||
list = gh_cdr(list);
|
||||
} else if (gh_eq_p(value, gh_symbol2scm("time-to-live"))) {
|
||||
spellaction->Summon.TTL = gh_scm2int(gh_car(list));
|
||||
spellaction->Data.Summon.TTL = gh_scm2int(gh_car(list));
|
||||
list = gh_cdr(list);
|
||||
} else {
|
||||
errl("Unsupported summon tag",value);
|
||||
}
|
||||
}
|
||||
} else if (gh_eq_p(value,gh_symbol2scm("spawn-portal"))) {
|
||||
spell->CastFunction=CastSpawnPortal;
|
||||
spellaction->CastFunction=CastSpawnPortal;
|
||||
while (!gh_null_p(list)) {
|
||||
value = gh_car(list);
|
||||
list = gh_cdr(list);
|
||||
if (gh_eq_p(value, gh_symbol2scm("portal-type"))) {
|
||||
str = gh_scm2newstr(gh_car(list),0);
|
||||
spellaction->SpawnPortal.PortalType = UnitTypeByIdent(str);
|
||||
if (!spellaction->SpawnPortal.PortalType) {
|
||||
spellaction->SpawnPortal.PortalType = 0;
|
||||
spellaction->Data.SpawnPortal.PortalType = UnitTypeByIdent(str);
|
||||
if (!spellaction->Data.SpawnPortal.PortalType) {
|
||||
spellaction->Data.SpawnPortal.PortalType = 0;
|
||||
DebugLevel0("unit type \"%s\" not found for spawn-portal.\n" _C_ str);
|
||||
}
|
||||
free(str);
|
||||
|
@ -256,36 +256,36 @@ local void CclParseSpellAction(SCM list, SpellType* spell, SpellActionType *spel
|
|||
}
|
||||
}
|
||||
} else if (gh_eq_p(value,gh_symbol2scm("raise-dead"))) {
|
||||
spell->CastFunction=CastRaiseDead;
|
||||
spellaction->CastFunction=CastRaiseDead;
|
||||
while (!gh_null_p(list)) {
|
||||
value = gh_car(list);
|
||||
list = gh_cdr(list);
|
||||
if (gh_eq_p(value, gh_symbol2scm("unit-raised"))) {
|
||||
str = gh_scm2newstr(gh_car(list),0);
|
||||
spellaction->RaiseDead.UnitRaised = UnitTypeByIdent(str);
|
||||
if (!spellaction->RaiseDead.UnitRaised) {
|
||||
spellaction->RaiseDead.UnitRaised = 0;
|
||||
spellaction->Data.RaiseDead.UnitRaised = UnitTypeByIdent(str);
|
||||
if (!spellaction->Data.RaiseDead.UnitRaised) {
|
||||
spellaction->Data.RaiseDead.UnitRaised = 0;
|
||||
DebugLevel0("unit type \"%s\" not found for summon spell.\n" _C_ str);
|
||||
}
|
||||
free(str);
|
||||
list = gh_cdr(list);
|
||||
} else if (gh_eq_p(value, gh_symbol2scm("time-to-live"))) {
|
||||
spellaction->RaiseDead.TTL = gh_scm2int(gh_car(list));
|
||||
spellaction->Data.RaiseDead.TTL = gh_scm2int(gh_car(list));
|
||||
list = gh_cdr(list);
|
||||
} else {
|
||||
errl("Unsupported raise-dead tag",value);
|
||||
}
|
||||
}
|
||||
} else if (gh_eq_p(value,gh_symbol2scm("polymorph"))) {
|
||||
spell->CastFunction=CastPolymorph;
|
||||
spellaction->CastFunction=CastPolymorph;
|
||||
while (!gh_null_p(list)) {
|
||||
value = gh_car(list);
|
||||
list = gh_cdr(list);
|
||||
if (gh_eq_p(value, gh_symbol2scm("new-form"))) {
|
||||
str = gh_scm2newstr(gh_car(list),0);
|
||||
spellaction->Summon.UnitType = UnitTypeByIdent(str);
|
||||
if (!spellaction->Summon.UnitType) {
|
||||
spellaction->Summon.UnitType = 0;
|
||||
spellaction->Data.Summon.UnitType = UnitTypeByIdent(str);
|
||||
if (!spellaction->Data.Summon.UnitType) {
|
||||
spellaction->Data.Summon.UnitType = 0;
|
||||
DebugLevel0("unit type \"%s\" not found for summon spell.\n" _C_ str);
|
||||
}
|
||||
free(str);
|
||||
|
@ -296,18 +296,18 @@ local void CclParseSpellAction(SCM list, SpellType* spell, SpellActionType *spel
|
|||
}
|
||||
}
|
||||
} else if (gh_eq_p(value,gh_symbol2scm("adjust-vitals"))) {
|
||||
spell->CastFunction=CastAdjustVitals;
|
||||
spellaction->CastFunction=CastAdjustVitals;
|
||||
while (!gh_null_p(list)) {
|
||||
value = gh_car(list);
|
||||
list=gh_cdr(list);
|
||||
if (gh_eq_p(value, gh_symbol2scm("hit-points"))) {
|
||||
spellaction->AdjustVitals.HP = gh_scm2int(gh_car(list));
|
||||
spellaction->Data.AdjustVitals.HP = gh_scm2int(gh_car(list));
|
||||
list = gh_cdr(list);
|
||||
} else if (gh_eq_p(value, gh_symbol2scm("mana-points"))) {
|
||||
spellaction->AdjustVitals.Mana = gh_scm2int(gh_car(list));
|
||||
spellaction->Data.AdjustVitals.Mana = gh_scm2int(gh_car(list));
|
||||
list = gh_cdr(list);
|
||||
} else if (gh_eq_p(value, gh_symbol2scm("max-multi-cast"))) {
|
||||
spellaction->AdjustVitals.MaxMultiCast = gh_scm2int(gh_car(list));
|
||||
spellaction->Data.AdjustVitals.MaxMultiCast = gh_scm2int(gh_car(list));
|
||||
list = gh_cdr(list);
|
||||
} else {
|
||||
errl("Unsupported adjust-vitals tag",value);
|
||||
|
@ -396,7 +396,7 @@ local void CclSpellParseCondition(SCM list, ConditionInfo* condition)
|
|||
condition->TargetSelf=Scm2Condition(gh_car(list));
|
||||
list=gh_cdr(list);
|
||||
} else if (gh_eq_p(value,gh_symbol2scm("min-hp-percent"))) {
|
||||
condition->MaxHpPercent=gh_scm2int(gh_car(list));
|
||||
condition->MinHpPercent=gh_scm2int(gh_car(list));
|
||||
list=gh_cdr(list);
|
||||
} else if (gh_eq_p(value,gh_symbol2scm("max-hp-percent"))) {
|
||||
condition->MaxHpPercent=gh_scm2int(gh_car(list));
|
||||
|
@ -525,8 +525,8 @@ local SCM CclDefineSpell(SCM list)
|
|||
}
|
||||
list=gh_cdr(list);
|
||||
} else if (gh_eq_p(value,gh_symbol2scm("action"))) {
|
||||
spell->SpellAction=(SpellActionType*)malloc(sizeof(SpellActionType));
|
||||
CclParseSpellAction(gh_car(list),spell,spell->SpellAction);
|
||||
spell->Action=(SpellActionType*)malloc(sizeof(SpellActionType));
|
||||
CclParseSpellAction(gh_car(list),spell,spell->Action);
|
||||
list=gh_cdr(list);
|
||||
} else if (gh_eq_p(value,gh_symbol2scm("condition"))) {
|
||||
spell->Conditions=(ConditionInfo*)malloc(sizeof(ConditionInfo));
|
||||
|
@ -574,6 +574,136 @@ global void SpellCclRegister(void)
|
|||
gh_new_procedureN("define-spell", CclDefineSpell);
|
||||
}
|
||||
|
||||
/*
|
||||
** Save a spell action to a file.
|
||||
**
|
||||
** @param file File pointer to save to
|
||||
** @param action Pointer to action to save.
|
||||
*/
|
||||
local void SaveSpellCondition(CLFile *file,ConditionInfo* condition)
|
||||
{
|
||||
char condstrings [3][10] = {
|
||||
"true", /// CONDITION_TRUE
|
||||
"false", /// CONDITION_FALSE
|
||||
"only" /// CONDITION_ONLY
|
||||
};
|
||||
|
||||
DebugCheck(!file);
|
||||
DebugCheck(!condition);
|
||||
|
||||
CLprintf(file,"'( ");
|
||||
//
|
||||
// First save data related to flags.
|
||||
// NOTE: (int) is there to keep compilers happy.
|
||||
//
|
||||
CLprintf(file,"undead %s ",condstrings[(int)condition->Undead]);
|
||||
CLprintf(file,"organic %s ",condstrings[(int)condition->Organic]);
|
||||
CLprintf(file,"hero %s ",condstrings[(int)condition->Hero]);
|
||||
CLprintf(file,"coward %s ",condstrings[(int)condition->Coward]);
|
||||
CLprintf(file,"alliance %s ",condstrings[(int)condition->Alliance]);
|
||||
CLprintf(file,"building %s ",condstrings[(int)condition->Building]);
|
||||
CLprintf(file,"self %s ",condstrings[(int)condition->TargetSelf]);
|
||||
//
|
||||
// Min/Max vital percents
|
||||
//
|
||||
CLprintf(file,"min-hp-percent %d ",condition->MinHpPercent);
|
||||
CLprintf(file,"max-hp-percent %d ",condition->MaxHpPercent);
|
||||
CLprintf(file,"min-mana-percent %d ",condition->MinManaPercent);
|
||||
CLprintf(file,"max-mana-percent %d ",condition->MaxManaPercent);
|
||||
//
|
||||
// Max buff ticks stuff
|
||||
//
|
||||
CLprintf(file,"max-slow-ticks %d ",condition->MaxSlowTicks);
|
||||
CLprintf(file,"max-haste-ticks %d ",condition->MaxHasteTicks);
|
||||
CLprintf(file,"max-bloodlust-ticks %d ",condition->MaxBloodlustTicks);
|
||||
CLprintf(file,"max-invisibility-ticks %d ",condition->MaxInvisibilityTicks);
|
||||
CLprintf(file,"max-invincibility-ticks %d ",condition->MaxInvincibilityTicks);
|
||||
//
|
||||
// The end.
|
||||
//
|
||||
CLprintf(file,")\n");
|
||||
}
|
||||
|
||||
/*
|
||||
** Save a spell action to a file.
|
||||
**
|
||||
** @param file File pointer to save to
|
||||
** @param action Pointer to action to save.
|
||||
*/
|
||||
local void SaveSpellAction(CLFile *file,SpellActionType* action)
|
||||
{
|
||||
if (action->CastFunction==CastAreaBombardment) {
|
||||
CLprintf(file," '(area-bombardment fields %d shards %d damage %d start-offset-x %d start-offset-y %d)",
|
||||
action->Data.AreaBombardment.Fields,
|
||||
action->Data.AreaBombardment.Shards,
|
||||
action->Data.AreaBombardment.Damage,
|
||||
action->Data.AreaBombardment.StartOffsetX,
|
||||
action->Data.AreaBombardment.StartOffsetY);
|
||||
} else if (action->CastFunction==CastFireball) {
|
||||
CLprintf(file," '(fireball ttl %d damage %d)",
|
||||
action->Data.Fireball.TTL,
|
||||
action->Data.Fireball.Damage);
|
||||
} else if (action->CastFunction==CastAdjustVitals) {
|
||||
CLprintf(file," '(adjust-vitals");
|
||||
if (action->Data.AdjustVitals.HP) {
|
||||
CLprintf(file," hit-points %d",action->Data.AdjustVitals.HP);
|
||||
}
|
||||
if (action->Data.AdjustVitals.Mana) {
|
||||
CLprintf(file," mana-points %d",action->Data.AdjustVitals.Mana);
|
||||
}
|
||||
if (action->Data.AdjustVitals.MaxMultiCast) {
|
||||
CLprintf(file," max-multi-cast %d",action->Data.AdjustVitals.MaxMultiCast);
|
||||
}
|
||||
CLprintf(file,")\n");
|
||||
} else if (action->CastFunction==CastSummon) {
|
||||
CLprintf(file," '(summon unit-type %s time-to-live %d)",
|
||||
action->Data.Summon.UnitType->Ident,
|
||||
action->Data.Summon.TTL);
|
||||
} else if (action->CastFunction==CastAdjustBuffs) {
|
||||
CLprintf(file," '(adjust-buffs");
|
||||
if (action->Data.AdjustBuffs.HasteTicks!=BUFF_NOT_AFFECTED) {
|
||||
CLprintf(file," haste-ticks %d",action->Data.AdjustBuffs.HasteTicks);
|
||||
}
|
||||
if (action->Data.AdjustBuffs.SlowTicks!=BUFF_NOT_AFFECTED) {
|
||||
CLprintf(file," slow-ticks %d",action->Data.AdjustBuffs.SlowTicks);
|
||||
}
|
||||
if (action->Data.AdjustBuffs.BloodlustTicks!=BUFF_NOT_AFFECTED) {
|
||||
CLprintf(file," bloodlust-ticks %d",action->Data.AdjustBuffs.BloodlustTicks);
|
||||
}
|
||||
if (action->Data.AdjustBuffs.InvisibilityTicks!=BUFF_NOT_AFFECTED) {
|
||||
CLprintf(file," invisibility-ticks %d",action->Data.AdjustBuffs.InvisibilityTicks);
|
||||
}
|
||||
if (action->Data.AdjustBuffs.InvincibilityTicks!=BUFF_NOT_AFFECTED) {
|
||||
CLprintf(file," invincibility-ticks %d",action->Data.AdjustBuffs.InvincibilityTicks);
|
||||
}
|
||||
CLprintf(file,")");
|
||||
} else if (action->CastFunction==CastPolymorph) {
|
||||
CLprintf(file," '(polymorph new-form %s)",
|
||||
action->Data.Polymorph.NewForm->Ident);
|
||||
} else if (action->CastFunction==CastRaiseDead) {
|
||||
CLprintf(file," '(raise-dead unit-raised %s time-to-live %d)",
|
||||
action->Data.RaiseDead.UnitRaised->Ident,
|
||||
action->Data.RaiseDead.TTL);
|
||||
} else if (action->CastFunction==CastFlameShield) {
|
||||
CLprintf(file," '(flame-shield duration %d)",
|
||||
action->Data.FlameShield.TTL);
|
||||
} else if (action->CastFunction==CastRunes) {
|
||||
CLprintf(file," '(runes ttl %d damage %d)",
|
||||
action->Data.Runes.TTL,
|
||||
action->Data.Runes.Damage);
|
||||
} else if (action->CastFunction==CastSpawnPortal) {
|
||||
CLprintf(file," '(spawn-portal portal-type %s)",
|
||||
action->Data.SpawnPortal.PortalType->Ident);
|
||||
} else if (action->CastFunction==CastDeathCoil) {
|
||||
CLprintf(file," '(death-coil)");
|
||||
// FIXME: more?
|
||||
} else if (action->CastFunction==CastWhirlwind) {
|
||||
CLprintf(file," '(whirlwind duration %d)",
|
||||
action->Data.Whirlwind.TTL);
|
||||
// FIXME: more?
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
** Save spells to a CCL file.
|
||||
**
|
||||
|
@ -624,81 +754,17 @@ global void SaveSpells(CLFile *file)
|
|||
//
|
||||
// Save the action(effect of the spell)
|
||||
//
|
||||
CLprintf(file," 'action");
|
||||
if (spell->CastFunction==CastAreaBombardment) {
|
||||
CLprintf(file," '(area-bombardment fields %d shards %d damage %d start-offset-x %d start-offset-y %d)\n",
|
||||
spell->SpellAction->AreaBombardment.Fields,
|
||||
spell->SpellAction->AreaBombardment.Shards,
|
||||
spell->SpellAction->AreaBombardment.Damage,
|
||||
spell->SpellAction->AreaBombardment.StartOffsetX,
|
||||
spell->SpellAction->AreaBombardment.StartOffsetY);
|
||||
} else if (spell->CastFunction==CastFireball) {
|
||||
CLprintf(file," '(fireball ttl %d damage %d)\n",
|
||||
spell->SpellAction->Fireball.TTL,
|
||||
spell->SpellAction->Fireball.Damage);
|
||||
} else if (spell->CastFunction==CastAdjustVitals) {
|
||||
CLprintf(file," '(adjust-vitals");
|
||||
if (spell->SpellAction->AdjustVitals.HP) {
|
||||
CLprintf(file," hit-points %d",spell->SpellAction->AdjustVitals.HP);
|
||||
}
|
||||
if (spell->SpellAction->AdjustVitals.Mana) {
|
||||
CLprintf(file," mana-points %d",spell->SpellAction->AdjustVitals.Mana);
|
||||
}
|
||||
if (spell->SpellAction->AdjustVitals.MaxMultiCast) {
|
||||
CLprintf(file," max-multi-cast %d",spell->SpellAction->AdjustVitals.MaxMultiCast);
|
||||
}
|
||||
CLprintf(file,")\n");
|
||||
} else if (spell->CastFunction==CastSummon) {
|
||||
CLprintf(file," '(summon unit-type %s time-to-live %d)\n",
|
||||
spell->SpellAction->Summon.UnitType->Ident,
|
||||
spell->SpellAction->Summon.TTL);
|
||||
} else if (spell->CastFunction==CastAdjustBuffs) {
|
||||
CLprintf(file," '(adjust-buffs");
|
||||
if (spell->SpellAction->AdjustBuffs.HasteTicks!=BUFF_NOT_AFFECTED) {
|
||||
CLprintf(file," haste-ticks %d",spell->SpellAction->AdjustBuffs.HasteTicks);
|
||||
}
|
||||
if (spell->SpellAction->AdjustBuffs.SlowTicks!=BUFF_NOT_AFFECTED) {
|
||||
CLprintf(file," slow-ticks %d",spell->SpellAction->AdjustBuffs.SlowTicks);
|
||||
}
|
||||
if (spell->SpellAction->AdjustBuffs.BloodlustTicks!=BUFF_NOT_AFFECTED) {
|
||||
CLprintf(file," bloodlust-ticks %d",spell->SpellAction->AdjustBuffs.BloodlustTicks);
|
||||
}
|
||||
if (spell->SpellAction->AdjustBuffs.InvisibilityTicks!=BUFF_NOT_AFFECTED) {
|
||||
CLprintf(file," invisibility-ticks %d",spell->SpellAction->AdjustBuffs.InvisibilityTicks);
|
||||
}
|
||||
if (spell->SpellAction->AdjustBuffs.InvincibilityTicks!=BUFF_NOT_AFFECTED) {
|
||||
CLprintf(file," invincibility-ticks %d",spell->SpellAction->AdjustBuffs.InvincibilityTicks);
|
||||
}
|
||||
CLprintf(file,")\n");
|
||||
} else if (spell->CastFunction==CastPolymorph) {
|
||||
CLprintf(file," '(polymorph new-form %s)\n",
|
||||
spell->SpellAction->Polymorph.NewForm->Ident);
|
||||
} else if (spell->CastFunction==CastRaiseDead) {
|
||||
CLprintf(file," '(raise-dead unit-raised %s time-to-live %d)\n",
|
||||
spell->SpellAction->RaiseDead.UnitRaised->Ident,
|
||||
spell->SpellAction->RaiseDead.TTL);
|
||||
} else if (spell->CastFunction==CastFlameShield) {
|
||||
CLprintf(file," '(flame-shield duration %d)\n",
|
||||
spell->SpellAction->FlameShield.TTL);
|
||||
} else if (spell->CastFunction==CastRunes) {
|
||||
CLprintf(file," '(runes ttl %d damage %d)\n",
|
||||
spell->SpellAction->Runes.TTL,
|
||||
spell->SpellAction->Runes.Damage);
|
||||
} else if (spell->CastFunction==CastSpawnPortal) {
|
||||
CLprintf(file," '(spawn-portal portal-type %s)\n",
|
||||
spell->SpellAction->SpawnPortal.PortalType->Ident);
|
||||
} else if (spell->CastFunction==CastDeathCoil) {
|
||||
CLprintf(file," '(death-coil)\n");
|
||||
// FIXME: more?
|
||||
} else if (spell->CastFunction==CastWhirlwind) {
|
||||
CLprintf(file," '(whirlwind duration %d)\n",
|
||||
spell->SpellAction->Whirlwind.TTL);
|
||||
// FIXME: more?
|
||||
}
|
||||
CLprintf(file," 'action ");
|
||||
SaveSpellAction(file,spell->Action);
|
||||
CLprintf(file,"\n");
|
||||
//
|
||||
// FIXME: Save conditions
|
||||
//
|
||||
|
||||
if (spell->Conditions) {
|
||||
CLprintf(file," 'condition ");
|
||||
SaveSpellCondition(file,spell->Conditions);
|
||||
CLprintf(file,"\n");
|
||||
}
|
||||
//
|
||||
// FIXME: Save autocast and AI info
|
||||
//
|
||||
|
|
|
@ -451,10 +451,10 @@ global int CastSpawnPortal(Unit *caster, const SpellType *spell __attribute__((u
|
|||
|
||||
DebugCheck(!caster);
|
||||
DebugCheck(!spell);
|
||||
DebugCheck(!spell->SpellAction);
|
||||
DebugCheck(!spell->SpellAction->SpawnPortal.PortalType);
|
||||
DebugCheck(!spell->Action);
|
||||
DebugCheck(!spell->Action->Data.SpawnPortal.PortalType);
|
||||
|
||||
ptype = spell->SpellAction->SpawnPortal.PortalType;
|
||||
ptype = spell->Action->Data.SpawnPortal.PortalType;
|
||||
|
||||
portal = caster->Goal;
|
||||
if (portal) {
|
||||
|
@ -505,16 +505,16 @@ global int CastAreaBombardment(Unit *caster, const SpellType *spell,
|
|||
|
||||
DebugCheck(!caster);
|
||||
DebugCheck(!spell);
|
||||
DebugCheck(!spell->SpellAction);
|
||||
DebugCheck(!spell->Action);
|
||||
//assert(x in range, y in range);
|
||||
|
||||
mis = NULL;
|
||||
|
||||
fields = spell->SpellAction->AreaBombardment.Fields;
|
||||
shards = spell->SpellAction->AreaBombardment.Shards;
|
||||
damage = spell->SpellAction->AreaBombardment.Damage;
|
||||
offsetx = spell->SpellAction->AreaBombardment.StartOffsetX;
|
||||
offsety = spell->SpellAction->AreaBombardment.StartOffsetY;
|
||||
fields = spell->Action->Data.AreaBombardment.Fields;
|
||||
shards = spell->Action->Data.AreaBombardment.Shards;
|
||||
damage = spell->Action->Data.AreaBombardment.Damage;
|
||||
offsetx = spell->Action->Data.AreaBombardment.StartOffsetX;
|
||||
offsety = spell->Action->Data.AreaBombardment.StartOffsetY;
|
||||
while (fields--) {
|
||||
// FIXME : radius configurable...
|
||||
do {
|
||||
|
@ -568,7 +568,7 @@ global int CastDeathCoil(Unit *caster, const SpellType *spell, Unit *target,
|
|||
|
||||
DebugCheck(!caster);
|
||||
DebugCheck(!spell);
|
||||
DebugCheck(!spell->SpellAction);
|
||||
DebugCheck(!spell->Action);
|
||||
// assert(target);
|
||||
// assert(x in range, y in range);
|
||||
|
||||
|
@ -615,7 +615,7 @@ global int CastFireball(Unit *caster, const SpellType *spell,
|
|||
|
||||
DebugCheck(!caster);
|
||||
DebugCheck(!spell);
|
||||
DebugCheck(!spell->SpellAction);
|
||||
DebugCheck(!spell->Action);
|
||||
DebugCheck(!spell->Missile);
|
||||
|
||||
missile = NULL;
|
||||
|
@ -634,8 +634,8 @@ global int CastFireball(Unit *caster, const SpellType *spell,
|
|||
caster->Mana -= spell->ManaCost;
|
||||
PlayGameSound(spell->SoundWhenCast.Sound, MaxSampleVolume);
|
||||
missile = MakeMissile(spell->Missile, sx, sy, x, y);
|
||||
missile->State = spell->SpellAction->Fireball.TTL - (dist - 1) * 2;
|
||||
missile->TTL = spell->SpellAction->Fireball.TTL;
|
||||
missile->State = spell->Action->Data.Fireball.TTL - (dist - 1) * 2;
|
||||
missile->TTL = spell->Action->Data.Fireball.TTL;
|
||||
missile->Controller = SpellFireballController;
|
||||
missile->SourceUnit = caster;
|
||||
RefsDebugCheck(!caster->Refs || caster->Destroyed);
|
||||
|
@ -662,7 +662,7 @@ global int CastFlameShield(Unit* caster, const SpellType *spell, Unit *target,
|
|||
|
||||
DebugCheck(!caster);
|
||||
DebugCheck(!spell);
|
||||
DebugCheck(!spell->SpellAction);
|
||||
DebugCheck(!spell->Action);
|
||||
DebugCheck(!target);
|
||||
// assert(x in range, y in range);
|
||||
DebugCheck(!spell->Missile);
|
||||
|
@ -671,11 +671,11 @@ global int CastFlameShield(Unit* caster, const SpellType *spell, Unit *target,
|
|||
|
||||
// get mana cost
|
||||
caster->Mana -= spell->ManaCost;
|
||||
target->FlameShield = spell->SpellAction->FlameShield.TTL;
|
||||
target->FlameShield = spell->Action->Data.FlameShield.TTL;
|
||||
PlayGameSound(spell->SoundWhenCast.Sound, MaxSampleVolume);
|
||||
for (i = 0; i < 5; i++) {
|
||||
mis = MakeMissile(spell->Missile, 0, 0, 0, 0);
|
||||
mis->TTL = spell->SpellAction->FlameShield.TTL + i * 7;
|
||||
mis->TTL = spell->Action->Data.FlameShield.TTL + i * 7;
|
||||
mis->TargetUnit = target;
|
||||
mis->Controller = SpellFlameShieldController;
|
||||
RefsDebugCheck(!target->Refs || target->Destroyed);
|
||||
|
@ -700,26 +700,26 @@ global int CastAdjustBuffs(Unit *caster, const SpellType *spell, Unit *target,
|
|||
{
|
||||
DebugCheck(!caster);
|
||||
DebugCheck(!spell);
|
||||
DebugCheck(!spell->SpellAction);
|
||||
DebugCheck(!spell->Action);
|
||||
DebugCheck(!target);
|
||||
|
||||
// get mana cost
|
||||
caster->Mana -= spell->ManaCost;
|
||||
|
||||
if (spell->SpellAction->AdjustBuffs.SlowTicks!=BUFF_NOT_AFFECTED) {
|
||||
target->Haste=spell->SpellAction->AdjustBuffs.HasteTicks;
|
||||
if (spell->Action->Data.AdjustBuffs.SlowTicks!=BUFF_NOT_AFFECTED) {
|
||||
target->Haste=spell->Action->Data.AdjustBuffs.HasteTicks;
|
||||
}
|
||||
if (spell->SpellAction->AdjustBuffs.SlowTicks!=BUFF_NOT_AFFECTED) {
|
||||
target->Slow=spell->SpellAction->AdjustBuffs.SlowTicks;
|
||||
if (spell->Action->Data.AdjustBuffs.SlowTicks!=BUFF_NOT_AFFECTED) {
|
||||
target->Slow=spell->Action->Data.AdjustBuffs.SlowTicks;
|
||||
}
|
||||
if (spell->SpellAction->AdjustBuffs.BloodlustTicks!=BUFF_NOT_AFFECTED) {
|
||||
target->Bloodlust=spell->SpellAction->AdjustBuffs.BloodlustTicks;
|
||||
if (spell->Action->Data.AdjustBuffs.BloodlustTicks!=BUFF_NOT_AFFECTED) {
|
||||
target->Bloodlust=spell->Action->Data.AdjustBuffs.BloodlustTicks;
|
||||
}
|
||||
if (spell->SpellAction->AdjustBuffs.InvisibilityTicks!=BUFF_NOT_AFFECTED) {
|
||||
target->Invisible=spell->SpellAction->AdjustBuffs.InvisibilityTicks;
|
||||
if (spell->Action->Data.AdjustBuffs.InvisibilityTicks!=BUFF_NOT_AFFECTED) {
|
||||
target->Invisible=spell->Action->Data.AdjustBuffs.InvisibilityTicks;
|
||||
}
|
||||
if (spell->SpellAction->AdjustBuffs.InvincibilityTicks!=BUFF_NOT_AFFECTED) {
|
||||
target->UnholyArmor=spell->SpellAction->AdjustBuffs.InvincibilityTicks;
|
||||
if (spell->Action->Data.AdjustBuffs.InvincibilityTicks!=BUFF_NOT_AFFECTED) {
|
||||
target->UnholyArmor=spell->Action->Data.AdjustBuffs.InvincibilityTicks;
|
||||
}
|
||||
CheckUnitToBeDrawn(target);
|
||||
PlayGameSound(spell->SoundWhenCast.Sound,MaxSampleVolume);
|
||||
|
@ -752,11 +752,11 @@ global int CastAdjustVitals(Unit *caster, const SpellType *spell, Unit *target,
|
|||
|
||||
DebugCheck(!caster);
|
||||
DebugCheck(!spell);
|
||||
DebugCheck(!spell->SpellAction);
|
||||
DebugCheck(!spell->Action);
|
||||
DebugCheck(!target);
|
||||
|
||||
hp = spell->SpellAction->AdjustVitals.HP;
|
||||
mana = spell->SpellAction->AdjustVitals.Mana;
|
||||
hp = spell->Action->Data.AdjustVitals.HP;
|
||||
mana = spell->Action->Data.AdjustVitals.Mana;
|
||||
manacost = spell->ManaCost;
|
||||
|
||||
// Healing and harming
|
||||
|
@ -784,8 +784,8 @@ global int CastAdjustVitals(Unit *caster, const SpellType *spell, Unit *target,
|
|||
if (manacost) {
|
||||
castcount=min(castcount,caster->Mana/manacost);
|
||||
}
|
||||
if (spell->SpellAction->AdjustVitals.MaxMultiCast) {
|
||||
castcount=min(castcount,spell->SpellAction->AdjustVitals.MaxMultiCast);
|
||||
if (spell->Action->Data.AdjustVitals.MaxMultiCast) {
|
||||
castcount=min(castcount,spell->Action->Data.AdjustVitals.MaxMultiCast);
|
||||
}
|
||||
|
||||
DebugCheck(castcount<0);
|
||||
|
@ -817,43 +817,6 @@ global int CastAdjustVitals(Unit *caster, const SpellType *spell, Unit *target,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
** Cast holy vision.
|
||||
**
|
||||
** @param caster Unit that casts the spell
|
||||
** @param spell Spell-type pointer
|
||||
** @param target Target unit that spell is addressed to
|
||||
** @param x X coord of target spot when/if target does not exist
|
||||
** @param y Y coord of target spot when/if target does not exist
|
||||
**
|
||||
** @return =!0 if spell should be repeated, 0 if not
|
||||
*/
|
||||
global int CastHolyVision(Unit *caster, const SpellType *spell, Unit *target,
|
||||
int x, int y)
|
||||
{
|
||||
DebugCheck(!caster);
|
||||
DebugCheck(!spell);
|
||||
DebugCheck(!spell->SpellAction);
|
||||
// assert(x in range, y in range);
|
||||
|
||||
caster->Mana -= spell->ManaCost; // get mana cost
|
||||
// FIXME: compact with summon.
|
||||
target = MakeUnit(spell->SpellAction->HolyVision.revealer, caster->Player);
|
||||
target->Orders[0].Action = UnitActionStill;
|
||||
target->HP = 0;
|
||||
target->X = x;
|
||||
target->Y = y;
|
||||
// target->TTL = GameCycle + CYCLES_PER_SECOND + CYCLES_PER_SECOND / 2;
|
||||
target->CurrentSightRange = target->Stats->SightRange;
|
||||
target->Removed = 1;
|
||||
target->CurrentSightRange = target->Stats->SightRange;
|
||||
MapMarkUnitSight(target);
|
||||
target->TTL = GameCycle + target->Type->DecayRate * 6 * CYCLES_PER_SECOND;
|
||||
CheckUnitToBeDrawn(target);
|
||||
PlayGameSound(spell->SoundWhenCast.Sound, MaxSampleVolume);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
** Cast polymorph.
|
||||
**
|
||||
|
@ -872,10 +835,10 @@ global int CastPolymorph(Unit *caster, const SpellType *spell, Unit *target,
|
|||
|
||||
DebugCheck(!caster);
|
||||
DebugCheck(!spell);
|
||||
DebugCheck(!spell->SpellAction);
|
||||
DebugCheck(!spell->Action);
|
||||
DebugCheck(!target);
|
||||
|
||||
type = spell->SpellAction->Polymorph.NewForm;
|
||||
type = spell->Action->Data.Polymorph.NewForm;
|
||||
DebugCheck(!type);
|
||||
|
||||
caster->Player->Score += target->Type->Points;
|
||||
|
@ -926,10 +889,10 @@ global int CastRaiseDead(Unit *caster, const SpellType *spell, Unit *target,
|
|||
|
||||
DebugCheck(!caster);
|
||||
DebugCheck(!spell);
|
||||
DebugCheck(!spell->SpellAction);
|
||||
DebugCheck(!spell->Action);
|
||||
// assert(x in range, y in range);
|
||||
|
||||
skeleton = spell->SpellAction->RaiseDead.UnitRaised;
|
||||
skeleton = spell->Action->Data.RaiseDead.UnitRaised;
|
||||
DebugCheck(!skeleton);
|
||||
|
||||
corpses = &CorpseList;
|
||||
|
@ -992,7 +955,7 @@ global int CastRunes(Unit *caster, const SpellType *spell,
|
|||
|
||||
DebugCheck(!caster);
|
||||
DebugCheck(spell);
|
||||
DebugCheck(!spell->SpellAction);
|
||||
DebugCheck(!spell->Action);
|
||||
// assert(x in range, y in range);
|
||||
|
||||
mis = NULL;
|
||||
|
@ -1010,7 +973,7 @@ global int CastRunes(Unit *caster, const SpellType *spell,
|
|||
y * TileSizeY + TileSizeY / 2,
|
||||
x * TileSizeX + TileSizeX / 2,
|
||||
y * TileSizeY + TileSizeY / 2);
|
||||
mis->TTL = spell->SpellAction->Runes.TTL;
|
||||
mis->TTL = spell->Action->Data.Runes.TTL;
|
||||
mis->Controller = SpellRunesController;
|
||||
caster->Mana -= spell->ManaCost / 5;
|
||||
}
|
||||
|
@ -1036,14 +999,14 @@ global int CastSummon(Unit *caster, const SpellType *spell, Unit *target,
|
|||
|
||||
DebugCheck(!caster);
|
||||
DebugCheck(!spell);
|
||||
DebugCheck(!spell->SpellAction);
|
||||
DebugCheck(!spell->SpellAction->Summon.UnitType);
|
||||
DebugCheck(!spell->Action);
|
||||
DebugCheck(!spell->Action->Data.Summon.UnitType);
|
||||
|
||||
DebugLevel0("Summoning\n");
|
||||
ttl=spell->SpellAction->Summon.TTL;
|
||||
ttl=spell->Action->Data.Summon.TTL;
|
||||
caster->Mana -= spell->ManaCost;
|
||||
// FIXME: johns: the unit is placed on the wrong position
|
||||
target = MakeUnit(spell->SpellAction->Summon.UnitType, caster->Player);
|
||||
target = MakeUnit(spell->Action->Data.Summon.UnitType, caster->Player);
|
||||
target->X = x;
|
||||
target->Y = y;
|
||||
// set life span
|
||||
|
@ -1090,7 +1053,7 @@ global int CastWhirlwind(Unit *caster, const SpellType *spell,
|
|||
|
||||
DebugCheck(!caster);
|
||||
DebugCheck(!spell);
|
||||
DebugCheck(!spell->SpellAction);
|
||||
DebugCheck(!spell->Action);
|
||||
// assert(x in range, y in range);
|
||||
|
||||
mis = NULL;
|
||||
|
@ -1100,7 +1063,7 @@ global int CastWhirlwind(Unit *caster, const SpellType *spell,
|
|||
mis = MakeMissile(spell->Missile,
|
||||
x * TileSizeX + TileSizeX / 2, y * TileSizeY + TileSizeY / 2,
|
||||
x * TileSizeX + TileSizeX / 2, y * TileSizeY + TileSizeY / 2);
|
||||
mis->TTL = spell->SpellAction->Whirlwind.TTL;
|
||||
mis->TTL = spell->Action->Data.Whirlwind.TTL;
|
||||
mis->Controller = SpellWhirlwindController;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1208,7 +1171,6 @@ local int PassCondition(const Unit* caster,const SpellType* spell,const Unit* ta
|
|||
}
|
||||
if (condition->Building!=CONDITION_TRUE) {
|
||||
if ((condition->Building==CONDITION_ONLY)^(target->Type->Building)) {
|
||||
DebugLevel0("QQQ\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -1541,7 +1503,7 @@ global int SpellCast(Unit *caster, const SpellType *spell, Unit *target,
|
|||
int x, int y)
|
||||
{
|
||||
DebugCheck(!spell);
|
||||
DebugCheck(!spell->CastFunction);
|
||||
DebugCheck(!spell->Action->CastFunction);
|
||||
DebugCheck(!caster);
|
||||
DebugCheck(!SpellIsAvailable(caster->Player, spell->Ident));
|
||||
|
||||
|
@ -1555,7 +1517,7 @@ global int SpellCast(Unit *caster, const SpellType *spell, Unit *target,
|
|||
}
|
||||
DebugLevel3Fn("Spell cast: (%s), %s -> %s (%d,%d)\n" _C_ spell->IdentName _C_
|
||||
unit->Type->Name _C_ target ? target->Type->Name : "none" _C_ x _C_ y);
|
||||
return CanCastSpell(caster, spell, target, x, y) && spell->CastFunction(caster, spell, target, x, y);
|
||||
return CanCastSpell(caster, spell, target, x, y) && spell->Action->CastFunction(caster, spell, target, x, y);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue