Small stuff in spells, and forgot to add spells.ccl
This commit is contained in:
parent
ca87e52689
commit
ed288ae27e
3 changed files with 208 additions and 336 deletions
|
@ -96,74 +96,74 @@ typedef union
|
|||
{
|
||||
// FIXME rename structure more properly.
|
||||
// TTL's below are in ticks: approx: 500=13sec, 1000=25sec, 2000=50sec
|
||||
// FIXME use TTL or nb_of_second ?
|
||||
struct {
|
||||
int fields; /// FIXME doc
|
||||
int shards; /// FIXME doc
|
||||
int damage; /// damage
|
||||
} blizzard;
|
||||
|
||||
struct {
|
||||
UnitType *goal; /// FIXME: compact to Summon
|
||||
} circleofpower;
|
||||
|
||||
struct {
|
||||
int fields; /// FIXME doc
|
||||
int shards; /// FIXME doc
|
||||
int damage; /// damage
|
||||
} deathanddecay;
|
||||
|
||||
struct {
|
||||
int TTL; /// time to live (ticks)
|
||||
int damage; /// Damage.
|
||||
} fireball;
|
||||
|
||||
struct {
|
||||
int TTL; /// time to live (ticks)
|
||||
} flameshield;
|
||||
// FIXME use TTL, as in TICKS to live
|
||||
struct {
|
||||
int Fields; /// FIXME doc
|
||||
int Shards; /// FIXME doc
|
||||
int Damage; /// damage
|
||||
} Blizzard;
|
||||
|
||||
struct {
|
||||
UnitType *PortalType; /// The unit type spawned
|
||||
} SpawnPortal;
|
||||
|
||||
struct {
|
||||
int Fields; /// FIXME doc
|
||||
int Shards; /// FIXME doc
|
||||
int Damage; /// damage
|
||||
} DeathAndDecay;
|
||||
|
||||
struct {
|
||||
int TTL; /// time to live (ticks)
|
||||
int Damage; /// Damage.
|
||||
} Fireball;
|
||||
|
||||
struct {
|
||||
int TTL; /// time to live (ticks)
|
||||
} FlameShield;
|
||||
|
||||
struct s_haste {
|
||||
int flag; /// flag for know what variable to set.
|
||||
int value; /// the set value. (nb sec).
|
||||
struct s_haste *next; /// Other variable to set ?
|
||||
} haste;
|
||||
|
||||
struct {
|
||||
int HP; /// HP gain for manacost.(negative for exorcism)
|
||||
} healing;
|
||||
|
||||
struct {
|
||||
UnitType *revealer; /// Type of unit to be summoned: (unit-revealer).
|
||||
} holyvision;
|
||||
|
||||
struct {
|
||||
int flag; /// unholyarmor or invisibility.
|
||||
int value; /// the set value. (nb sec).
|
||||
MissileType *missile; /// missile for the target.
|
||||
} invisibility;
|
||||
|
||||
struct {
|
||||
UnitType *unit; /// The new form :)
|
||||
} polymorph;
|
||||
|
||||
struct {
|
||||
UnitType *skeleton; /// The unit to spwan from corpses
|
||||
} raisedead;
|
||||
|
||||
struct {
|
||||
int TTL; /// time to live (ticks)
|
||||
int damage; /// Damage.
|
||||
} runes;
|
||||
|
||||
struct {
|
||||
UnitType *unittype; /// Type of unit to be summoned.
|
||||
} summon;
|
||||
|
||||
struct {
|
||||
int TTL; /// time to live (ticks)
|
||||
// FIXME: more configurations
|
||||
} whirlwind;
|
||||
} t_SpellAction;
|
||||
struct s_haste {
|
||||
int flag; /// flag for know what variable to set.
|
||||
int value; /// the set value. (nb sec).
|
||||
struct s_haste *next; /// Other variable to set ?
|
||||
} haste;
|
||||
|
||||
struct {
|
||||
int HP; /// HP gain for manacost.(negative for exorcism)
|
||||
} healing;
|
||||
|
||||
struct {
|
||||
UnitType *revealer; /// Type of unit to be summoned: (unit-revealer).
|
||||
} holyvision;
|
||||
|
||||
struct {
|
||||
int flag; /// unholyarmor or invisibility.
|
||||
int value; /// the set value. (nb sec).
|
||||
MissileType *missile; /// missile for the target.
|
||||
} invisibility;
|
||||
|
||||
struct {
|
||||
UnitType *unit; /// The new form :)
|
||||
} polymorph;
|
||||
|
||||
struct {
|
||||
UnitType *skeleton; /// The unit to spwan from corpses
|
||||
} raisedead;
|
||||
|
||||
struct {
|
||||
int TTL; /// time to live (ticks)
|
||||
int damage; /// Damage.
|
||||
} runes;
|
||||
|
||||
struct {
|
||||
UnitType *unittype; /// Type of unit to be summoned.
|
||||
} summon;
|
||||
|
||||
struct {
|
||||
int TTL; /// time to live (ticks)
|
||||
// FIXME: more configurations
|
||||
} whirlwind;
|
||||
} SpellActionType;
|
||||
|
||||
/*
|
||||
** *******************
|
||||
|
@ -194,12 +194,10 @@ struct s_Conditions;
|
|||
/*
|
||||
** Specific conditions.
|
||||
*/
|
||||
typedef int f_specific_condition(const struct s_Conditions *condition,
|
||||
const Unit* caster,
|
||||
const Unit* target, int x, int y);
|
||||
typedef int f_specific_condition(const struct s_Conditions *condition,
|
||||
const Unit* caster,const Unit* target,int x,int y);
|
||||
|
||||
typedef int f_generic_condition(const struct s_Conditions *condition,
|
||||
const Unit* caster);
|
||||
typedef int f_generic_condition(const struct s_Conditions *condition,const Unit* caster);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -208,24 +206,24 @@ typedef int f_generic_condition(const struct s_Conditions *condition,
|
|||
** @todo Move more parameters into this structure.
|
||||
*/
|
||||
typedef struct s_Conditions {
|
||||
int expectvalue; ///< Value expected (condition is true or false)
|
||||
union {
|
||||
f_specific_condition *specific; ///< Fonction that evaluate the condition.
|
||||
f_generic_condition *generic; ///< Fonction that evaluate the condition.
|
||||
} f;
|
||||
union {
|
||||
int range; ///< range
|
||||
// struct {
|
||||
// t_SpecificConditions c1;
|
||||
// t_SpecificConditions c2;
|
||||
// } or; //
|
||||
unsigned int flag; ///< flag
|
||||
struct {
|
||||
unsigned int flag;
|
||||
unsigned int ttl;
|
||||
} durationeffect; ///< durationeffect
|
||||
} u;
|
||||
struct s_Conditions *next; ///< for list.
|
||||
int expectvalue; /// Value expected (function expected result, true or false)
|
||||
union {
|
||||
f_specific_condition *specific; /// Evaluation Function for the condition.
|
||||
f_generic_condition *generic; /// Evaluation Function for the condition.
|
||||
} f;
|
||||
union {
|
||||
int range; /// range
|
||||
// struct {
|
||||
// t_SpecificConditions c1;
|
||||
// t_SpecificConditions c2;
|
||||
// } or; //
|
||||
unsigned int flag; ///< flag
|
||||
struct {
|
||||
unsigned int flag;
|
||||
unsigned int ttl;
|
||||
} durationeffect; ///< durationeffect
|
||||
} u;
|
||||
struct s_Conditions *next; ///< for list.
|
||||
} t_Conditions;
|
||||
|
||||
|
||||
|
@ -261,10 +259,10 @@ typedef struct _spell_type_ {
|
|||
char *Name; /// Spell name shown by the engine
|
||||
|
||||
// Spell Specifications
|
||||
TargetType which_sort_of_target; /// for identify what sort of target is valid.
|
||||
f_spell *f; /// function to cast the spell.
|
||||
t_SpellAction *SpellAction; /// More arguments for spell (damage, delay, additional sounds...).
|
||||
int Range; /// Max range of the target.
|
||||
TargetType Target; /// Targetting information. See TargetType.
|
||||
f_spell *f; /// function to cast the spell.
|
||||
SpellActionType *SpellAction; /// More arguments for spell (damage, delay, additional sounds...).
|
||||
int Range; /// Max range of the target.
|
||||
unsigned int ManaCost; /// required mana for each cast
|
||||
|
||||
t_Conditions *Condition_generic; /// Conditions to cast the spell. (generic (no test for each target))
|
||||
|
@ -273,8 +271,8 @@ typedef struct _spell_type_ {
|
|||
t_AutoCast *AutoCast; /// AutoCast information
|
||||
|
||||
// Uses for graphics and sounds
|
||||
SoundConfig SoundWhenCasted; /// sound played if casted
|
||||
MissileType *Missile; /// missile fired on cast
|
||||
SoundConfig SoundWhenCast; /// sound played if cast
|
||||
MissileType *Missile; /// missile fired on cast
|
||||
} SpellType;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
|
|
|
@ -87,8 +87,8 @@
|
|||
;; Summon "UnitType",
|
||||
;; Whirlwind (ttl #n)
|
||||
;; } )
|
||||
;; 'SoundWhenCasted "SoundConfig"
|
||||
;; 'MissileWhenCasted "MissileType"
|
||||
;; 'sound-when-casted "SoundConfig"
|
||||
;; 'missile-when-casted "MissileType"
|
||||
;; 'condition '( {
|
||||
;; Enemypresence (#t range #n), // enemy in range
|
||||
;; DurationEffect (#t flag #f_flag value #n), // "f_flag" < #n
|
||||
|
@ -122,124 +122,6 @@ typedef void f_ccl_spell(const char *id, SCM list, SpellType *spell);
|
|||
// Direct affectation for spell
|
||||
// **************************************************************************
|
||||
|
||||
/**
|
||||
** Parse the New Showname for spell.
|
||||
** list = "ShowName"
|
||||
*/
|
||||
local void ccl_spell_showname(const char *id, SCM list, SpellType *spelltype)
|
||||
{
|
||||
char *str = NULL;
|
||||
|
||||
assert (id != NULL);
|
||||
assert (spelltype != NULL);
|
||||
|
||||
str = gh_scm2newstr(list, NULL);
|
||||
if (spelltype->Name != NULL && strcmp(spelltype->Name, str)) {
|
||||
// warn user
|
||||
DebugLevel3Fn("Redefinition in spell-type '%s' : %s : '%s' -> '%s'\n"
|
||||
_C_ spelltype->IdentName _C_ id _C_ spelltype->Name _C_ str);
|
||||
}
|
||||
free(spelltype->Name);
|
||||
spelltype->Name = str;
|
||||
}
|
||||
|
||||
/**
|
||||
** Parse the New Manacost for spell.
|
||||
** list = #n
|
||||
*/
|
||||
local void ccl_spell_manacost(const char *id, SCM list, SpellType *spelltype)
|
||||
{
|
||||
int manacost;
|
||||
|
||||
assert (id != NULL);
|
||||
assert (spelltype != NULL);
|
||||
|
||||
manacost = gh_scm2int(list);
|
||||
if (spelltype->ManaCost != -1 && spelltype->ManaCost != manacost)
|
||||
{// warning user
|
||||
DebugLevel3Fn("Redefinition in spell-type '%s' : %s : '%d' -> '%d'\n"
|
||||
_C_ spelltype->IdentName _C_ id _C_ spelltype->ManaCost _C_ manacost);
|
||||
}
|
||||
spelltype->ManaCost = manacost;
|
||||
}
|
||||
|
||||
/**
|
||||
** Parse the New range for spell.
|
||||
** list = #n
|
||||
*/
|
||||
local void ccl_spell_range(const char *id, SCM list, SpellType *spelltype)
|
||||
{
|
||||
int range;
|
||||
|
||||
assert (id != NULL);
|
||||
assert (spelltype != NULL);
|
||||
|
||||
range = gh_scm2int(list);
|
||||
if (spelltype->Range != 0 && spelltype->Range != range) {
|
||||
DebugLevel3Fn("Redefinition in spell-type '%s' : %s : '%d' -> '%d'\n"
|
||||
_C_ spelltype->IdentName _C_ id _C_ spelltype->Range _C_ range);
|
||||
}
|
||||
spelltype->Range = range;
|
||||
}
|
||||
|
||||
/**
|
||||
** Parse the target for spell.
|
||||
** list = #target
|
||||
** @note FIXME : Usefull ? depend of Spell Action, yes for self...
|
||||
*/
|
||||
local void ccl_spell_target(const char *id, SCM list, SpellType *spelltype)
|
||||
{
|
||||
struct {
|
||||
const char *ident;
|
||||
TargetType e;
|
||||
} correspondance[] = {
|
||||
{"none", TargetNone},
|
||||
{"self", TargetSelf},
|
||||
{"unit", TargetUnit},
|
||||
{"position", TargetPosition},
|
||||
{ NULL, 0}};
|
||||
TargetType which_sort_of_target;
|
||||
int i;
|
||||
|
||||
assert (id != NULL);
|
||||
assert (spelltype != NULL);
|
||||
|
||||
which_sort_of_target = spelltype->which_sort_of_target;
|
||||
for (i = 0; correspondance[i].ident != NULL; i++) {
|
||||
if (gh_eq_p(list, gh_symbol2scm((char *) correspondance[i].ident))) {
|
||||
spelltype->which_sort_of_target = correspondance[i].e;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (correspondance[i].ident == NULL) {
|
||||
errl("Unsupported tag", list);
|
||||
spelltype->which_sort_of_target = -1;
|
||||
return ;
|
||||
}
|
||||
// Redefinition.
|
||||
if (which_sort_of_target != spelltype->which_sort_of_target
|
||||
&& which_sort_of_target != TargetNone) {
|
||||
const char *s1 = NULL;
|
||||
const char *s2 = NULL;
|
||||
|
||||
for (i = 0; correspondance[i].ident != NULL; i++) {
|
||||
if (which_sort_of_target == correspondance[i].e) {
|
||||
s1 = correspondance[i].ident;
|
||||
continue;
|
||||
}
|
||||
if (spelltype->which_sort_of_target == correspondance[i].e) {
|
||||
s2 = correspondance[i].ident;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (s1 != NULL) {
|
||||
DebugLevel3Fn("Redefinition in spell-type '%s' : %s : '%s' -> '%s'\n"
|
||||
_C_ spelltype->IdentName _C_ id _C_ s1 _C_ s2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
** Parse the sound for spell.
|
||||
** list = "soundname"
|
||||
|
@ -253,7 +135,7 @@ local void ccl_spell_soundwhencast(const char *id, SCM list, SpellType *spell)
|
|||
assert (spell != NULL);
|
||||
|
||||
NewSoundName = gh_scm2newstr(list,NULL);
|
||||
OldSoundName = spell->SoundWhenCasted.Name;
|
||||
OldSoundName = spell->SoundWhenCast.Name;
|
||||
|
||||
if (OldSoundName && strcmp(NewSoundName,OldSoundName)) {
|
||||
DebugLevel3Fn("Redefinition of sound when casted for '%s' : %s : '%s' -> '%s'\n"
|
||||
|
@ -261,17 +143,17 @@ local void ccl_spell_soundwhencast(const char *id, SCM list, SpellType *spell)
|
|||
}
|
||||
|
||||
//Free the old stuff.
|
||||
free(spell->SoundWhenCasted.Sound);
|
||||
free(spell->SoundWhenCast.Sound);
|
||||
free(OldSoundName);
|
||||
|
||||
spell->SoundWhenCasted.Sound = SoundIdForName(NewSoundName);
|
||||
if (spell->SoundWhenCasted.Sound == NULL) {
|
||||
spell->SoundWhenCast.Sound = SoundIdForName(NewSoundName);
|
||||
if (spell->SoundWhenCast.Sound == NULL) {
|
||||
DebugLevel3Fn("in spell-type '%s' : %s : sound '%s' does not exist\n"
|
||||
_C_ spell->IdentName _C_ id _C_ NewSoundName);
|
||||
free(NewSoundName);
|
||||
NewSoundName=NULL;
|
||||
}
|
||||
spell->SoundWhenCasted.Name=NewSoundName;
|
||||
spell->SoundWhenCast.Name=NewSoundName;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -308,7 +190,7 @@ local void ccl_spell_missilewhencast(const char *id, SCM list, SpellType *spell)
|
|||
** For blizzard and DeathAndDecay.
|
||||
** list = fields #n shards #n damage #n
|
||||
*/
|
||||
local char ccl_spell_action_blizzard(const char *SpellName, SCM list, t_SpellAction *spellaction)
|
||||
local char ccl_spell_action_blizzard(const char *SpellName, SCM list, SpellActionType *spellaction)
|
||||
{
|
||||
int fields;
|
||||
int shards;
|
||||
|
@ -350,9 +232,9 @@ local char ccl_spell_action_blizzard(const char *SpellName, SCM list, t_SpellAct
|
|||
"fields <= 0 or shards <= 0 have no sense");
|
||||
return 0;
|
||||
}
|
||||
spellaction->blizzard.fields = fields;
|
||||
spellaction->blizzard.shards = shards;
|
||||
spellaction->blizzard.damage = damage;
|
||||
spellaction->Blizzard.Fields = fields;
|
||||
spellaction->Blizzard.Shards = shards;
|
||||
spellaction->Blizzard.Damage = damage;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -360,7 +242,7 @@ local char ccl_spell_action_blizzard(const char *SpellName, SCM list, t_SpellAct
|
|||
** For fireball and Runes.
|
||||
** list = 'ttl #n 'damage #n
|
||||
*/
|
||||
local char ccl_spell_action_fireball(const char *SpellName, SCM list, t_SpellAction *spellaction)
|
||||
local char ccl_spell_action_fireball(const char *SpellName, SCM list, SpellActionType *spellaction)
|
||||
{
|
||||
int ttl;
|
||||
int damage;
|
||||
|
@ -397,8 +279,8 @@ local char ccl_spell_action_fireball(const char *SpellName, SCM list, t_SpellAct
|
|||
"TTL <= 0 have no sense");
|
||||
return 0;
|
||||
}
|
||||
spellaction->fireball.TTL = ttl;
|
||||
spellaction->fireball.damage = damage;
|
||||
spellaction->Fireball.TTL = ttl;
|
||||
spellaction->Fireball.Damage = damage;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -406,7 +288,7 @@ local char ccl_spell_action_fireball(const char *SpellName, SCM list, t_SpellAct
|
|||
** For flameshield and whirlwind.
|
||||
** list = 'ttl #n
|
||||
*/
|
||||
local char ccl_spell_action_flameshield(const char *SpellName, SCM list, t_SpellAction *spellaction)
|
||||
local char ccl_spell_action_flameshield(const char *SpellName, SCM list, SpellActionType *spellaction)
|
||||
{
|
||||
int ttl;
|
||||
SCM value;
|
||||
|
@ -432,7 +314,7 @@ local char ccl_spell_action_flameshield(const char *SpellName, SCM list, t_Spell
|
|||
"ttl <= 0 have no sense");// ttl must be positive.
|
||||
return 0;
|
||||
}
|
||||
spellaction->flameshield.TTL = ttl;
|
||||
spellaction->FlameShield.TTL = ttl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -442,7 +324,7 @@ local char ccl_spell_action_flameshield(const char *SpellName, SCM list, t_Spell
|
|||
** One or more.
|
||||
** @todo Free when an error occurs. Do a function to do this.
|
||||
*/
|
||||
local char ccl_spell_action_haste(const char *SpellName, SCM list, t_SpellAction *spellaction)
|
||||
local char ccl_spell_action_haste(const char *SpellName, SCM list, SpellActionType *spellaction)
|
||||
{
|
||||
struct {
|
||||
const char *id;
|
||||
|
@ -509,7 +391,7 @@ local char ccl_spell_action_haste(const char *SpellName, SCM list, t_SpellAction
|
|||
** HP positive for healing, negative for dealing damage.
|
||||
** list = (HP #n)
|
||||
*/
|
||||
local char ccl_spell_action_healing(const char *SpellName, SCM list, t_SpellAction *spellaction)
|
||||
local char ccl_spell_action_healing(const char *SpellName, SCM list, SpellActionType *spellaction)
|
||||
{
|
||||
assert(SpellName);
|
||||
assert(spellaction != NULL);
|
||||
|
@ -546,7 +428,7 @@ local char ccl_spell_action_healing(const char *SpellName, SCM list, t_SpellActi
|
|||
** For invisibility and unholyarmor.
|
||||
** list = flag #f_inv value #n missile "missile-name"
|
||||
*/
|
||||
local char ccl_spell_action_invisibility(const char *SpellName, SCM list, t_SpellAction *spellaction)
|
||||
local char ccl_spell_action_invisibility(const char *SpellName, SCM list, SpellActionType *spellaction)
|
||||
{
|
||||
const struct {
|
||||
const char *id;
|
||||
|
@ -630,7 +512,7 @@ local char ccl_spell_action_invisibility(const char *SpellName, SCM list, t_Spel
|
|||
** list = ("unittypename")
|
||||
** @note WARNING, use for other functions than summon, see ccl_spell_action.
|
||||
*/
|
||||
local char ccl_spell_action_summon(const char *SpellName, SCM list, t_SpellAction *spellaction)
|
||||
local char ccl_spell_action_summon(const char *SpellName, SCM list, SpellActionType *spellaction)
|
||||
{
|
||||
assert(SpellName);
|
||||
assert(spellaction != NULL);
|
||||
|
@ -661,7 +543,7 @@ local char ccl_spell_action_summon(const char *SpellName, SCM list, t_SpellActio
|
|||
** @param list : argument for spell.
|
||||
** @param spellaction : What we want modify.
|
||||
*/
|
||||
typedef char f_ccl_action(const char *spellname, SCM list, t_SpellAction *spellaction);
|
||||
typedef char f_ccl_action(const char *spellname, SCM list, SpellActionType *spellaction);
|
||||
|
||||
/*
|
||||
** Parse the action for spell.
|
||||
|
@ -706,7 +588,7 @@ local void ccl_spell_action(const char *id, SCM list, SpellType *spell)
|
|||
DebugLevel3Fn("%s %d\n" _C_ parser[i].id _C_ sizeof(*spell->SpellAction));
|
||||
list = gh_cdr(list);
|
||||
free(spell->SpellAction);// FIXME : Use a destructor : free pointer, list..
|
||||
spell->SpellAction = (t_SpellAction *) malloc(sizeof (*spell->SpellAction));
|
||||
spell->SpellAction = (SpellActionType *) malloc(sizeof (*spell->SpellAction));
|
||||
memset(spell->SpellAction, 0, sizeof(*spell->SpellAction));
|
||||
if (parser[i].f(spell->IdentName, gh_car(list), spell->SpellAction) == 0) {
|
||||
// Error in function : it is to the function to warn..
|
||||
|
@ -1067,32 +949,6 @@ local void ccl_spell_autocast(const char *id, SCM list, SpellType *spell)
|
|||
&spell->AutoCast->Condition_generic,&spell->AutoCast->Condition_specific);
|
||||
}
|
||||
|
||||
/*
|
||||
** Constructor of SpellType.
|
||||
*/
|
||||
local SpellType * NewSpellType(char *identname)
|
||||
{
|
||||
assert(identname != NULL);
|
||||
|
||||
SpellType *spell = (SpellType *) malloc(sizeof(*spell));
|
||||
|
||||
spell->Ident = SpellTypeCount++;
|
||||
spell->IdentName = strdup(identname);
|
||||
spell->Name = NULL;
|
||||
spell->which_sort_of_target = -1;
|
||||
spell->f = NULL;
|
||||
spell->SpellAction = NULL;
|
||||
spell->Range = 0;
|
||||
spell->ManaCost = (unsigned int) -1;
|
||||
spell->Condition_generic = NULL;
|
||||
spell->Condition_specific = NULL;
|
||||
spell->AutoCast = NULL;
|
||||
spell->SoundWhenCasted.Name = NULL;
|
||||
spell->SoundWhenCasted.Sound = NULL;
|
||||
spell->Missile = NULL;
|
||||
return spell;
|
||||
}
|
||||
|
||||
/**
|
||||
** Parse Spell.
|
||||
**
|
||||
|
@ -1101,53 +957,70 @@ local SpellType * NewSpellType(char *identname)
|
|||
local SCM CclDefineSpell(SCM list)
|
||||
{
|
||||
char *identname;
|
||||
SpellType *spelltype;
|
||||
SpellType *spell;
|
||||
SCM value;
|
||||
int i;
|
||||
static struct {
|
||||
const char *ident;
|
||||
f_ccl_spell *f;
|
||||
} parser[] = {
|
||||
{"showname", ccl_spell_showname},
|
||||
{"manacost", ccl_spell_manacost},
|
||||
{"range", ccl_spell_range},
|
||||
{"target", ccl_spell_target},
|
||||
{"action", ccl_spell_action},
|
||||
{"condition", ccl_spell_condition},
|
||||
{"autocast", ccl_spell_autocast},
|
||||
{"SoundWhenCasted", ccl_spell_soundwhencast},
|
||||
{"MissileWhenCasted", ccl_spell_missilewhencast},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
identname = gh_scm2newstr(gh_car(list), NULL);
|
||||
list = gh_cdr(list);
|
||||
spelltype = SpellTypeByIdent(identname);
|
||||
if (spelltype != NULL) {
|
||||
spell = SpellTypeByIdent(identname);
|
||||
if (spell != NULL) {
|
||||
DebugLevel0Fn("Redefining spell-type `%s'\n" _C_ identname);
|
||||
free(identname);
|
||||
} else {
|
||||
spelltype = NewSpellType(identname);
|
||||
free(identname);
|
||||
SpellTypeTable = realloc(SpellTypeTable,(1+SpellTypeCount)*sizeof(SpellType)); // FIXME
|
||||
SpellTypeTable[spelltype->Ident] = *spelltype;
|
||||
spelltype = &SpellTypeTable[spelltype->Ident];
|
||||
SpellTypeTable = realloc(SpellTypeTable,(1+SpellTypeCount)*sizeof(SpellType));
|
||||
spell = &SpellTypeTable[SpellTypeCount++];
|
||||
memset(spell,0,sizeof(SpellType));
|
||||
spell->Ident=SpellTypeCount-1;
|
||||
spell->IdentName=identname;
|
||||
}
|
||||
while (!gh_null_p(list)) {
|
||||
value = gh_car(list);
|
||||
list = gh_cdr(list);
|
||||
for (i = 0; parser[i].ident != NULL; i++) {
|
||||
if (gh_eq_p(value, gh_symbol2scm((char *) parser[i].ident))) {
|
||||
parser[i].f(parser[i].ident, gh_car(list), spelltype);
|
||||
list = gh_cdr(list);
|
||||
break;
|
||||
if (gh_eq_p(value,gh_symbol2scm("showname"))) {
|
||||
if (spell->Name) {
|
||||
free(spell->Name);
|
||||
}
|
||||
}
|
||||
if (parser[i].ident == NULL) {
|
||||
spell->Name=gh_scm2newstr(gh_car(list), NULL);
|
||||
list=gh_cdr(list);
|
||||
} else if (gh_eq_p(value,gh_symbol2scm("manacost"))) {
|
||||
spell->ManaCost=gh_scm2int(gh_car(list));
|
||||
list=gh_cdr(list);
|
||||
} else if (gh_eq_p(value,gh_symbol2scm("range"))) {
|
||||
spell->Range=gh_scm2int(gh_car(list));
|
||||
list=gh_cdr(list);
|
||||
} else if (gh_eq_p(value,gh_symbol2scm("target"))) {
|
||||
value=gh_car(list);
|
||||
if (gh_eq_p(value,gh_symbol2scm("none"))) {
|
||||
spell->Target=TargetNone;
|
||||
} else if (gh_eq_p(value,gh_symbol2scm("self"))) {
|
||||
spell->Target=TargetSelf;
|
||||
} else if (gh_eq_p(value,gh_symbol2scm("unit"))) {
|
||||
spell->Target=TargetSelf;
|
||||
} else if (gh_eq_p(value,gh_symbol2scm("position"))) {
|
||||
spell->Target=TargetPosition;
|
||||
} else {
|
||||
errl("Unsupported spell target type tag",value);
|
||||
}
|
||||
list=gh_cdr(list);
|
||||
} else if (gh_eq_p(value,gh_symbol2scm("action"))) {
|
||||
ccl_spell_action("action",gh_car(list),spell);
|
||||
list=gh_cdr(list);
|
||||
} else if (gh_eq_p(value,gh_symbol2scm("condition"))) {
|
||||
ccl_spell_condition("condition",gh_car(list),spell);
|
||||
list=gh_cdr(list);
|
||||
} else if (gh_eq_p(value,gh_symbol2scm("autocast"))) {
|
||||
ccl_spell_autocast("autocast",gh_car(list),spell);
|
||||
list=gh_cdr(list);
|
||||
} else if (gh_eq_p(value,gh_symbol2scm("sound-when-cast"))) {
|
||||
ccl_spell_soundwhencast("sound-when-cast",gh_car(list),spell);
|
||||
list=gh_cdr(list);
|
||||
} else if (gh_eq_p(value,gh_symbol2scm("missile-when-cast"))) {
|
||||
ccl_spell_missilewhencast("missile-when-cast",gh_car(list),spell);
|
||||
list=gh_cdr(list);
|
||||
} else {
|
||||
errl("Unsupported tag", value);
|
||||
}
|
||||
}
|
||||
// FIXME : Verify spell is completed.
|
||||
return SCM_UNSPECIFIED;
|
||||
}
|
||||
|
||||
|
@ -1180,17 +1053,17 @@ global void SaveSpells(CLFile* file)
|
|||
CLprintf(file," 'showname \"%s\"\n",spell->Name);
|
||||
CLprintf(file," 'manacost %d\n",spell->ManaCost);
|
||||
CLprintf(file," 'range %d\n",spell->Range);
|
||||
if (spell->SoundWhenCasted.Name) {
|
||||
CLprintf(file," 'SoundWhenCasted \"%s\"\n",spell->SoundWhenCasted.Name);
|
||||
if (spell->SoundWhenCast.Name) {
|
||||
CLprintf(file," 'sound-when-cast \"%s\"\n",spell->SoundWhenCast.Name);
|
||||
}
|
||||
if (spell->Missile) {
|
||||
CLprintf(file," 'MissileWhenCasted \"%s\"\n",spell->Missile->Ident);
|
||||
CLprintf(file," 'missile-when-casted \"%s\"\n",spell->Missile->Ident);
|
||||
}
|
||||
//
|
||||
// Target type.
|
||||
//
|
||||
CLprintf(file," 'target '");
|
||||
switch (spell->which_sort_of_target) {
|
||||
switch (spell->Target) {
|
||||
case TargetSelf:
|
||||
CLprintf(file,"self\n");
|
||||
break;
|
||||
|
@ -1213,13 +1086,13 @@ global void SaveSpells(CLFile* file)
|
|||
CLprintf(file," 'action");
|
||||
if (spell->f==CastBlizzard) {
|
||||
CLprintf(file," '(Blizzard (fields %d shards %d damage %d) )\n",
|
||||
spell->SpellAction->blizzard.fields,
|
||||
spell->SpellAction->blizzard.shards,
|
||||
spell->SpellAction->blizzard.damage);
|
||||
spell->SpellAction->Blizzard.Fields,
|
||||
spell->SpellAction->Blizzard.Shards,
|
||||
spell->SpellAction->Blizzard.Damage);
|
||||
} else if (spell->f==CastFireball) {
|
||||
CLprintf(file," '(FireBall (ttl %d damage %d) )\n",
|
||||
spell->SpellAction->fireball.TTL,
|
||||
spell->SpellAction->fireball.damage);
|
||||
spell->SpellAction->Fireball.TTL,
|
||||
spell->SpellAction->Fireball.Damage);
|
||||
} else if (spell->f==CastHolyVision) {
|
||||
CLprintf(file," '(HolyVision \"%s\" )\n",spell->SpellAction->holyvision.revealer->Ident);
|
||||
} else if (spell->f==CastHealing) {
|
||||
|
@ -1281,14 +1154,14 @@ global void SaveSpells(CLFile* file)
|
|||
spell->SpellAction->raisedead.skeleton->Ident);
|
||||
} else if (spell->f==CastFlameShield) {
|
||||
CLprintf(file," '(FlameShield (ttl %d) )\n",
|
||||
spell->SpellAction->flameshield.TTL);
|
||||
spell->SpellAction->FlameShield.TTL);
|
||||
} else if (spell->f==CastRunes) {
|
||||
CLprintf(file," '(Runes (ttl %d damage %d) )\n",
|
||||
spell->SpellAction->runes.TTL,
|
||||
spell->SpellAction->runes.damage);
|
||||
} else if (spell->f==CastCircleOfPower) {
|
||||
CLprintf(file," '(CircleOfPower \"%s\")\n",
|
||||
spell->SpellAction->circleofpower.goal->Ident);
|
||||
spell->SpellAction->SpawnPortal.PortalType->Ident);
|
||||
} else if (spell->f==CastDeathCoil) {
|
||||
CLprintf(file," '(DeathCoil)\n");
|
||||
// FIXME: more?
|
||||
|
@ -1300,6 +1173,7 @@ global void SaveSpells(CLFile* file)
|
|||
//
|
||||
// FIXME: Save conditions
|
||||
//
|
||||
|
||||
//
|
||||
// FIXME: Save autocast and AI info
|
||||
//
|
||||
|
|
|
@ -505,9 +505,9 @@ global int CastBlizzard(Unit* caster, const SpellType* spell,
|
|||
int dy;
|
||||
int i;
|
||||
|
||||
fields = spell->SpellAction->blizzard.fields;
|
||||
shards = spell->SpellAction->blizzard.shards;
|
||||
damage = spell->SpellAction->blizzard.damage;
|
||||
fields = spell->SpellAction->Blizzard.Fields;
|
||||
shards = spell->SpellAction->Blizzard.Shards;
|
||||
damage = spell->SpellAction->Blizzard.Damage;
|
||||
while (fields--)
|
||||
{
|
||||
// FIXME : radius configurable...
|
||||
|
@ -543,7 +543,7 @@ global int CastBlizzard(Unit* caster, const SpellType* spell,
|
|||
caster->Refs++;
|
||||
}
|
||||
}
|
||||
PlayGameSound(spell->SoundWhenCasted.Sound, MaxSampleVolume);
|
||||
PlayGameSound(spell->SoundWhenCast.Sound, MaxSampleVolume);
|
||||
caster->Mana -= spell->ManaCost;
|
||||
return caster->Mana > spell->ManaCost;
|
||||
}
|
||||
|
@ -562,15 +562,15 @@ global int CastBlizzard(Unit* caster, const SpellType* spell,
|
|||
global int CastCircleOfPower(Unit* caster, const SpellType* spell __attribute__((unused)),
|
||||
Unit* target __attribute__((unused)), int x, int y)
|
||||
{
|
||||
assert(caster);
|
||||
assert(spell);
|
||||
assert(spell->SpellAction);
|
||||
assert(spell->SpellAction->circleofpower.goal);
|
||||
assert(caster);
|
||||
assert(spell);
|
||||
assert(spell->SpellAction);
|
||||
assert(spell->SpellAction->SpawnPortal.PortalType);
|
||||
// assert(x in range, y in range);
|
||||
|
||||
// FIXME: vladi: cop should be placed only on explored land
|
||||
Unit *cop = NULL;
|
||||
UnitType *ucop = spell->SpellAction->circleofpower.goal;
|
||||
UnitType *ucop = spell->SpellAction->SpawnPortal.PortalType;
|
||||
|
||||
cop = caster->Goal;
|
||||
if (cop)
|
||||
|
@ -622,9 +622,9 @@ global int CastDeathAndDecay(Unit* caster, const SpellType* spell,
|
|||
int dy;
|
||||
int i;
|
||||
|
||||
fields = spell->SpellAction->deathanddecay.fields;
|
||||
shards = spell->SpellAction->deathanddecay.shards;
|
||||
damage = spell->SpellAction->deathanddecay.damage;
|
||||
fields = spell->SpellAction->DeathAndDecay.Fields;
|
||||
shards = spell->SpellAction->DeathAndDecay.Shards;
|
||||
damage = spell->SpellAction->DeathAndDecay.Damage;
|
||||
while (fields--)
|
||||
{
|
||||
do {
|
||||
|
@ -648,7 +648,7 @@ global int CastDeathAndDecay(Unit* caster, const SpellType* spell,
|
|||
caster->Refs++;
|
||||
}
|
||||
}
|
||||
PlayGameSound(spell->SoundWhenCasted.Sound, MaxSampleVolume);
|
||||
PlayGameSound(spell->SoundWhenCast.Sound, MaxSampleVolume);
|
||||
caster->Mana -= spell->ManaCost;
|
||||
return (caster->Mana > spell->ManaCost);
|
||||
}
|
||||
|
@ -679,7 +679,7 @@ global int CastDeathCoil(Unit* caster, const SpellType* spell, Unit* target,
|
|||
|
||||
caster->Mana -= spell->ManaCost;
|
||||
|
||||
PlayGameSound(spell->SoundWhenCasted.Sound, MaxSampleVolume);
|
||||
PlayGameSound(spell->SoundWhenCast.Sound, MaxSampleVolume);
|
||||
mis = MakeMissile(spell->Missile,
|
||||
sx * TileSizeX + TileSizeX / 2, sy * TileSizeY + TileSizeY / 2,
|
||||
x * TileSizeX + TileSizeX / 2, y * TileSizeY + TileSizeY / 2);
|
||||
|
@ -734,10 +734,10 @@ global int CastFireball(Unit* caster, const SpellType* spell,
|
|||
x = x * TileSizeX + TileSizeX / 2;
|
||||
y = y * TileSizeY + TileSizeY / 2;
|
||||
caster->Mana -= spell->ManaCost;
|
||||
PlayGameSound(spell->SoundWhenCasted.Sound, MaxSampleVolume);
|
||||
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->SpellAction->Fireball.TTL - (dist - 1) * 2;
|
||||
missile->TTL = spell->SpellAction->Fireball.TTL;
|
||||
missile->Controller = SpellFireballController;
|
||||
missile->SourceUnit = caster;
|
||||
RefsDebugCheck(!caster->Refs || caster->Destroyed);
|
||||
|
@ -771,12 +771,12 @@ global int CastFlameShield(Unit* caster, const SpellType* spell, Unit* target,
|
|||
|
||||
// get mana cost
|
||||
caster->Mana -= spell->ManaCost;
|
||||
target->FlameShield = spell->SpellAction->flameshield.TTL;
|
||||
PlayGameSound(spell->SoundWhenCasted.Sound, MaxSampleVolume);
|
||||
target->FlameShield = spell->SpellAction->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->SpellAction->FlameShield.TTL + i * 7;
|
||||
mis->TargetUnit = target;
|
||||
mis->Controller = SpellFlameShieldController;
|
||||
RefsDebugCheck(!target->Refs || target->Destroyed);
|
||||
|
@ -880,7 +880,7 @@ global int CastHaste(Unit* caster, const SpellType* spell, Unit* target,
|
|||
}
|
||||
}
|
||||
CheckUnitToBeDrawn(target);
|
||||
PlayGameSound(spell->SoundWhenCasted.Sound,MaxSampleVolume);
|
||||
PlayGameSound(spell->SoundWhenCast.Sound,MaxSampleVolume);
|
||||
MakeMissile(spell->Missile,
|
||||
x*TileSizeX+TileSizeX/2, y*TileSizeY+TileSizeY/2,
|
||||
x*TileSizeX+TileSizeX/2, y*TileSizeY+TileSizeY/2 );
|
||||
|
@ -942,7 +942,7 @@ global int CastHealing(Unit* caster, const SpellType* spell, Unit* target,
|
|||
LetUnitDie(target);
|
||||
}
|
||||
}
|
||||
PlayGameSound(spell->SoundWhenCasted.Sound, MaxSampleVolume);
|
||||
PlayGameSound(spell->SoundWhenCast.Sound, MaxSampleVolume);
|
||||
MakeMissile(spell->Missile,
|
||||
x * TileSizeX + TileSizeX / 2, y * TileSizeY + TileSizeY / 2,
|
||||
x * TileSizeX + TileSizeX / 2, y * TileSizeY + TileSizeY / 2);
|
||||
|
@ -981,7 +981,7 @@ global int CastHolyVision(Unit* caster, const SpellType* spell, Unit* target,
|
|||
MapMarkUnitSight(target);
|
||||
target->TTL = GameCycle + target->Type->DecayRate * 6 * CYCLES_PER_SECOND;
|
||||
CheckUnitToBeDrawn(target);
|
||||
PlayGameSound(spell->SoundWhenCasted.Sound, MaxSampleVolume);
|
||||
PlayGameSound(spell->SoundWhenCast.Sound, MaxSampleVolume);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1039,7 +1039,7 @@ global int CastInvisibility(Unit* caster, const SpellType* spell, Unit* target,
|
|||
}
|
||||
CheckUnitToBeDrawn(target);
|
||||
}
|
||||
PlayGameSound(spell->SoundWhenCasted.Sound,MaxSampleVolume);
|
||||
PlayGameSound(spell->SoundWhenCast.Sound,MaxSampleVolume);
|
||||
MakeMissile(spell->Missile,
|
||||
x * TileSizeX + TileSizeX / 2, y * TileSizeY + TileSizeY / 2,
|
||||
x * TileSizeX + TileSizeX / 2, y * TileSizeY + TileSizeY / 2 );
|
||||
|
@ -1093,7 +1093,7 @@ global int CastPolymorph(Unit* caster, const SpellType* spell, Unit* target,
|
|||
MakeUnitAndPlace(x, y, type, Players + PlayerNumNeutral);
|
||||
}
|
||||
caster->Mana -= spell->ManaCost;
|
||||
PlayGameSound(spell->SoundWhenCasted.Sound, MaxSampleVolume);
|
||||
PlayGameSound(spell->SoundWhenCast.Sound, MaxSampleVolume);
|
||||
MakeMissile(spell->Missile,
|
||||
x*TileSizeX+TileSizeX/2, y*TileSizeY+TileSizeY/2,
|
||||
x*TileSizeX+TileSizeX/2, y*TileSizeY+TileSizeY/2 );
|
||||
|
@ -1151,7 +1151,7 @@ global int CastRaiseDead(Unit* caster, const SpellType* spell, Unit* target,
|
|||
corpses = &(*corpses)->Next;
|
||||
}
|
||||
}
|
||||
PlayGameSound(spell->SoundWhenCasted.Sound, MaxSampleVolume);
|
||||
PlayGameSound(spell->SoundWhenCast.Sound, MaxSampleVolume);
|
||||
MakeMissile(spell->Missile,
|
||||
x*TileSizeX+TileSizeX/2, y*TileSizeY+TileSizeY/2,
|
||||
x*TileSizeX+TileSizeX/2, y*TileSizeY+TileSizeY/2 );
|
||||
|
@ -1185,7 +1185,7 @@ global int CastRunes(Unit* caster, const SpellType* spell,
|
|||
int oldy = y;
|
||||
int i;
|
||||
|
||||
PlayGameSound(spell->SoundWhenCasted.Sound, MaxSampleVolume);
|
||||
PlayGameSound(spell->SoundWhenCast.Sound, MaxSampleVolume);
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
x = oldx + xx[i];
|
||||
|
@ -1237,7 +1237,7 @@ global int CastSummon(Unit* caster, const SpellType* spell, Unit* target,
|
|||
target->TTL = GameCycle + target->Type->DecayRate * 6 * CYCLES_PER_SECOND;
|
||||
CheckUnitToBeDrawn(target);
|
||||
|
||||
PlayGameSound(spell->SoundWhenCasted.Sound,MaxSampleVolume);
|
||||
PlayGameSound(spell->SoundWhenCast.Sound,MaxSampleVolume);
|
||||
MakeMissile(spell->Missile,
|
||||
x*TileSizeX+TileSizeX/2, y*TileSizeY+TileSizeY/2,
|
||||
x*TileSizeX+TileSizeX/2, y*TileSizeY+TileSizeY/2 );
|
||||
|
@ -1266,7 +1266,7 @@ global int CastWhirlwind(Unit* caster, const SpellType* spell,
|
|||
Missile *mis = NULL;
|
||||
|
||||
caster->Mana -= spell->ManaCost;
|
||||
PlayGameSound(spell->SoundWhenCasted.Sound, MaxSampleVolume);
|
||||
PlayGameSound(spell->SoundWhenCast.Sound, MaxSampleVolume);
|
||||
mis = MakeMissile(spell->Missile,
|
||||
x * TileSizeX + TileSizeX / 2, y * TileSizeY + TileSizeY / 2,
|
||||
x * TileSizeX + TileSizeX / 2, y * TileSizeY + TileSizeY / 2);
|
||||
|
@ -1567,7 +1567,7 @@ local Target *SelectTargetUnitsOfAutoCast(const Unit *caster,
|
|||
assert(spell->AutoCast != NULL);
|
||||
assert(caster != NULL);
|
||||
|
||||
switch (spell->which_sort_of_target)
|
||||
switch (spell->Target)
|
||||
{
|
||||
case TargetSelf :
|
||||
{
|
||||
|
@ -1777,7 +1777,7 @@ global int CanCastSpell(const Unit* caster,const SpellType* spell,
|
|||
|
||||
if (!caster->Type->CanCastSpell
|
||||
|| !caster->Type->CanCastSpell[spell->Ident]
|
||||
|| (spell->which_sort_of_target == TargetUnit && target == NULL)) {
|
||||
|| (spell->Target == TargetUnit && target == NULL)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue