[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Stratagus-CVS] stratagus/src/clone ccl_spell.c spells.c
From: |
Jimmy Salmon |
Subject: |
[Stratagus-CVS] stratagus/src/clone ccl_spell.c spells.c |
Date: |
Fri, 26 Sep 2003 14:46:28 -0400 |
CVSROOT: /cvsroot/stratagus
Module name: stratagus
Branch:
Changes by: Jimmy Salmon <address@hidden> 03/09/26 14:46:28
Modified files:
src/clone : ccl_spell.c spells.c
Log message:
More cleanup
Patches:
Index: stratagus/src/clone/ccl_spell.c
diff -u stratagus/src/clone/ccl_spell.c:1.5 stratagus/src/clone/ccl_spell.c:1.6
--- stratagus/src/clone/ccl_spell.c:1.5 Fri Sep 26 11:47:50 2003
+++ stratagus/src/clone/ccl_spell.c Fri Sep 26 14:46:28 2003
@@ -1,1120 +1,1118 @@
-// _________ __ __
-// / _____// |_____________ _/ |______ ____ __ __ ______
-// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
-// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
-// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
-// \/ \/ \//_____/ \/
-// ______________________ ______________________
-// T H E W A R B E G I N S
-// Stratagus - A free fantasy real time strategy game engine
-//
-/address@hidden ccl_spells.c - The spell ccl functions.. */
-//
-// (c) Copyright 1998-2003 by Joris DAUPHIN
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; version 2 dated June, 1991.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-//
-// $Id: ccl_spell.c,v 1.5 2003/09/26 15:47:50 n0body Exp $
-//@{
-
-/*----------------------------------------------------------------------------
--- Includes
-----------------------------------------------------------------------------*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-
-#include "stratagus.h"
-/*
-#include "video.h"
-#include "tileset.h"
-#include "unittype.h"
-*/
-#include "spells.h"
-#include "ccl_sound.h"
-#include "ccl.h"
-
-/**
-** pointer on function.
-** @param id : last keyword recognized.
-** @param list : list to be parsed. (just the args).
-** @param spell : spelltype to modify.
-** FIXME: remove all this cruft
-*/
-typedef void f_ccl_spell(const char *id, SCM list, SpellType *spell);
-
-// **************************************************************************
-// Direct affectation for spell
-// **************************************************************************
-
-/**
-** Parse the dependency of spell.
-** list = (upgrade "upgradename")
-*/
-local void ccl_spell_dependency(const char *id, SCM list, SpellType *spell)
-{
- assert (id != NULL);
- assert (spell != NULL);
-
- char *dependencyName = NULL;
- SCM value;
- int dependencyId = -1;
-
- value = gh_car(list);
-
- if (!gh_eq_p(value, gh_symbol2scm("upgrade"))) {
- return;
- }
- list = gh_cdr(list);
- value = gh_car(list);
-
- dependencyName = gh_scm2newstr(value, NULL);
- dependencyId = UpgradeIdByIdent(dependencyName);
- if (dependencyId == -1)
- {// warn user
- DebugLevel0Fn("Bad upgrade-name '%s'\n" _C_ dependencyName);
- free(dependencyName);
- return ;
- }
- spell->DependencyId = dependencyId;
- free(dependencyName);
-}
-
-
-// **************************************************************************
-// Action parsers for spellAction
-// **************************************************************************
-
-/**
-** For blizzard and DeathAndDecay.
-** list = fields #n shards #n damage #n
-*/
-local char CclSpellParseActionAreaBombardment(const char *SpellName, SCM list,
SpellActionType *spellaction)
-{
- SCM value;
-
- assert(SpellName);
- assert(spellaction != NULL);
-
- memset(spellaction,sizeof(spellaction),0);
- for (; !gh_null_p(list); list = gh_cdr(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));
- continue;
- } else if (gh_eq_p(value, gh_symbol2scm("shards"))) {
- spellaction->AreaBombardment.Shards = gh_scm2int(gh_car(list));
- continue;
- } else if (gh_eq_p(value, gh_symbol2scm("damage"))) {
- spellaction->AreaBombardment.Damage = gh_scm2int(gh_car(list));
- continue;
- } else if (gh_eq_p(value, gh_symbol2scm("start-offset-x"))) {
- spellaction->AreaBombardment.StartOffsetX =
gh_scm2int(gh_car(list));
- continue;
- } else if (gh_eq_p(value, gh_symbol2scm("start-offset-y"))) {
- spellaction->AreaBombardment.StartOffsetY =
gh_scm2int(gh_car(list));
- continue;
- }
- // warning user : unknow tag
- DebugLevel0Fn("FIXME : better WARNING : unknow tag");
- }
- return 1;
-}
-
-/**
-** For fireball and Runes.
-** list = 'ttl #n 'damage #n
-*/
-local char CclSpellParseActionFireball(const char *SpellName, SCM list,
SpellActionType *spellaction)
-{
- int ttl;
- int damage;
- SCM value;
-
- assert(SpellName);
- assert(spellaction != NULL);
-
- ttl = 0;
- damage = 0;
- for (; !gh_null_p(list); list = gh_cdr(list)) {
- value = gh_car(list);
- list = gh_cdr(list);
- // Todo, Warn for redefinition ???
- if (gh_eq_p(value, gh_symbol2scm("ttl"))) {
- ttl = gh_scm2int(gh_car(list));
- continue;
- }
- if (gh_eq_p(value, gh_symbol2scm("damage"))) {
- damage = gh_scm2int(gh_car(list));
- continue;
- }
- // warning user : unknow tag
- DebugLevel0Fn("FIXME : better WARNING : unknow tag");
- }
- if (damage == 0) {
- DebugLevel0Fn("in spell-type %s : %s" _C_ SpellName _C_
- "damage == 0 have no sense : Positive to deal damage, negative
for healing.");
- return 0;
- }
- if (ttl <= 0) {
- // TTL must be positive.
- DebugLevel0Fn("in spell-type %s : %s" _C_ SpellName _C_
- "TTL <= 0 have no sense");
- return 0;
- }
- spellaction->Fireball.TTL = ttl;
- spellaction->Fireball.Damage = damage;
- return 1;
-}
-
-/**
-** For flameshield and whirlwind.
-** list = 'ttl #n
-*/
-local char CclSpellParseActionFlameShield(const char *SpellName, SCM list,
SpellActionType *spellaction)
-{
- int ttl;
- SCM value;
-
- assert(SpellName);
- assert(spellaction != NULL);
-
- ttl = 0;
- for (; !gh_null_p(list); list = gh_cdr(list)) {
- value = gh_car(list);
- list = gh_cdr(list);
- // Todo, Warn for redefinition ???
- if (gh_eq_p(value, gh_symbol2scm("ttl")))
- {
- ttl = gh_scm2int(gh_car(list));
- continue;
- }
- // Warning user : unknow tag
- DebugLevel0Fn("FIXME : better WARNING : unknow tag");
- }
- if (ttl <= 0) {
- DebugLevel0Fn("in spell-type %s : %s" _C_ SpellName _C_
- "ttl <= 0 have no sense");// ttl must be positive.
- return 0;
- }
- spellaction->FlameShield.TTL = ttl;
- return 1;
-}
-
-/**
-** For haste, slow and bloodlust.
-** list = *haste #n *slow #n *bloodlust #n
-** One or more.
-** @todo Free when an error occurs. Do a function to do this.
-*/
-local char CclSpellParseActionHaste(const char *SpellName, SCM list,
SpellActionType *spellaction)
-{
- struct {
- const char *id;
- int flag;
- } parser[] = {
- {"haste", flag_haste},
- {"slow", flag_slow},
- {"bloodlust", flag_bloodlust},
- {"HP", flag_HP},
- {"mana", flag_Mana},
- {"HP_percent", flag_HP_percent},
- {"mana_percent", flag_Mana_percent},
- {NULL, 0}
- };
-
- int i;
- SCM value;
- struct s_haste *lasthaste;
- struct s_haste *newhaste;
-
- assert(SpellName);
- assert(spellaction != NULL);
-
- lasthaste = NULL;
- newhaste = &spellaction->haste;
- while(!gh_null_p(list)) {
- if (lasthaste != NULL) {
- newhaste = malloc(sizeof(*newhaste));
- memset(newhaste, 0, sizeof(*newhaste));
- }
- value = gh_car(list);
- list = gh_cdr(list);
- for (i = 0; parser[i].id != NULL; i++) {
- if (gh_eq_p(value, gh_symbol2scm((char *) parser[i].id))) {
- newhaste->flag = parser[i].flag;
- newhaste->value = gh_scm2int(gh_car(list));
- list = gh_cdr(list);
- newhaste->next = NULL;
- break;
- }
- }
- if (parser[i].id == NULL) {
- DebugLevel0Fn("FIXME : better WARNING : unknow tag");
- // FIXME : free correctly.
- return 0;
- }
- if (spellaction->haste.value < 0) {
- DebugLevel0Fn("in spell-type %s : %s" _C_ SpellName _C_
- "value < 0 have no sense : "
- "nul to desactivate, positive te activate.");// value == 0
have no sense.
- // FIXME : free correctly.
- return 0;
- }
- if (lasthaste != NULL) {
- lasthaste->next = newhaste;
- }
- lasthaste = newhaste;
- }
- return 1;
-}
-
-/**
-** For healing or dealing damage.
-** HP positive for healing, negative for dealing damage.
-** list = (HP #n)
-*/
-local char CclSpellParseActionHealing(const char *SpellName, SCM list,
SpellActionType *spellaction)
-{
-
-
- SCM value;
- int HP = 0;
- assert(SpellName);
- assert(spellaction != NULL);
- for (; !gh_null_p(list); list = gh_cdr(list)) {
- value = gh_car(list);
- list = gh_cdr(list);
- // Todo, Warn for redefinition ???
- if (gh_eq_p(value, gh_symbol2scm("HP"))) {
- HP = gh_scm2int(gh_car(list));
- continue;
- }
- // Warning user : unknow tag
- DebugLevel0Fn("FIXME : better WARNING : unknow tag");
- }
- if (spellaction->healing.HP != 0 && spellaction->healing.HP != HP) {
- DebugLevel3Fn("Redefinition in spell-type '%s' : %s : '%d' -> '%d'\n"
- _C_ SpellName _C_ "HP" _C_ spellaction->healing.HP _C_ HP);
- }
- spellaction->healing.HP = HP;
- if (HP == 0) {
- DebugLevel0Fn("in spell-type %s : %s" _C_ SpellName _C_
- "HP == 0 have no sense : "
- "Positive for healing, negative to deal damages.");
- return 0;
- }
- return 1;
-}
-
-/**
-** For invisibility and unholyarmor.
-** list = flag #f_inv value #n missile "missile-name"
-*/
-local char CclSpellParseActionInvisibility(const char *SpellName, SCM list,
SpellActionType *spellaction)
-{
- const struct {
- const char *id;
- int flag;
- } parser[] = {
- {"unholyarmor", flag_unholyarmor},
- {"invisibility", flag_invisibility},
- {NULL, 0}
- };
- SCM value;
- int i;
- int flag;
- int sec;
- char *missilename;
- flag = -1;
- sec = 0;
- missilename=NULL;
-
- assert(SpellName);
- assert(spellaction != NULL);
-
- for (; !gh_null_p(list); list = gh_cdr(list)) {
- value = gh_car(list);
- list = gh_cdr(list);
- // Todo, Warn for redefinition ???
- if (gh_eq_p(value, gh_symbol2scm("flag"))) {
- value = gh_car(list);
- flag = -1;
- for (i = 0; parser[i].id != NULL; i++) {
- if (gh_eq_p(value, gh_symbol2scm((char *) parser[i].id))) {
- flag = parser[i].flag;
- break;
- }
- }
- continue;
- }
- if (gh_eq_p(value, gh_symbol2scm("value"))) {
- sec = gh_scm2int(gh_car(list));
- continue;
- }
- if (gh_eq_p(value, gh_symbol2scm("missile"))) {
- if (missilename != NULL) {
- free(missilename);
- }
- missilename = gh_scm2newstr(gh_car(list), NULL);
- continue;
- }
- // Warning user : unknow tag
- DebugLevel0Fn("FIXME : better WARNING : unknow tag");
- }
- if (missilename == NULL) {
- DebugLevel0Fn("FIXME : better WARNING : must define
(correctly)missilename");
- return 0;
- }
- if (flag == -1) {
- DebugLevel0Fn("FIXME : better WARNING : must define (correctly)
missilename");
- free(missilename);
- return 0;
- }
- if (sec <= 0) {
- DebugLevel0Fn("FIXME : better WARNING : must define (correctly)
missilename");
- free(missilename);
- return 0;
- }
- spellaction->invisibility.flag = flag;
- spellaction->invisibility.value = sec;
- spellaction->invisibility.missile = MissileTypeByIdent(missilename);
- if (spellaction->invisibility.missile == NULL) {
- // Warning user : Missile doesn't exist (yet).
- DebugLevel0Fn("in spell-type %s : '%s' %s " _C_ SpellName _C_
missilename
- _C_ "does not exist.");
- free(missilename);
- return 0;
- }
- free(missilename);
- return 1;
-}
-
-/**
-** For summoning
-** list = ("unittypename")
-** @note WARNING, use for other functions than summon, see
ccl_spell_action.
-*/
-local char CclSpellParseActionSummon(const char *SpellName, SCM list,
SpellActionType *spellaction)
-{
- char *str;
- UnitType *unittype;
-
- assert(SpellName);
- assert(spellaction != NULL);
-
- str = gh_scm2newstr(list, NULL);
- unittype = UnitTypeByIdent(str);
- spellaction->Summon.UnitType = unittype;
- if (unittype == NULL) {
- DebugLevel0Fn("in spell-type %s : Unittype '%s'doesn't exist" _C_
SpellName _C_ str);
- free(str);
- return 0;
- }
- free(str);
- return 1;
-}
-
-// **************************************************************************
-// main Action parsers for spellAction
-// **************************************************************************
-
-/*
-** return false if a problem occurs (unit not found...)
-** @param spellname : name of spell to display errors and warning.
-** @param list : argument for spell.
-** @param spellaction : What we want modify.
-*/
-typedef char f_ccl_action(const char *spellname, SCM list, SpellActionType
*spellaction);
-
-/*
-** Parse the action for spell.
-** list = ('Spell '(parameter))
-*/
-local void ccl_spell_action(const char *id, SCM list, SpellType *spell)
-{
- int i;
- struct {
- SpellFunc *fspell;
- const char *id;
- f_ccl_action *f;
- } parser[] = {
- {CastAreaBombardment, "area-bombardment",
CclSpellParseActionAreaBombardment},
- {CastSpawnPortal, "spawn-portal",
CclSpellParseActionSummon/*circleofpower*/},
- {CastDeathCoil, "death-coil", NULL},
- {CastFireball, "fireball", CclSpellParseActionFireball},
- {CastFlameShield, "flame-shield", CclSpellParseActionFlameShield},
- {CastHaste, "haste", CclSpellParseActionHaste},
- {CastHealing, "healing", CclSpellParseActionHealing},
- {CastHolyVision, "HolyVision", CclSpellParseActionSummon/*holyvision*/},
- {CastInvisibility, "Invisibility", CclSpellParseActionInvisibility},
- {CastPolymorph, "Polymorph", CclSpellParseActionSummon/*polymorph*/},
- {CastRaiseDead, "RaiseDead", CclSpellParseActionSummon/*raisedead*/},
- {CastRunes, "Runes", CclSpellParseActionFireball/*runes*/},
- {CastSummon, "Summon", CclSpellParseActionSummon},
- {CastWhirlwind, "Whirlwind",
CclSpellParseActionFlameShield/*whirlwind*/},
- {0, NULL, NULL}
- };
-
- SCM value = list;
- value = gh_car(value);
-
- assert (id != NULL);
- assert (spell != NULL);
-
- for (i = 0; parser[i].id != NULL; i++) {
- if (gh_eq_p(value, gh_symbol2scm((char *) parser[i].id))) {
- spell->f = parser[i].fspell;
- if (parser[i].f) {
- 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 = (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..
- free(spell->SpellAction);// FIXME : Use a destructor : free
pointer, list..
- spell->SpellAction = NULL;
- spell->f = NULL;
- }
- }
- break;
- }
- }
- if (parser[i].id == NULL) {
- // Warning user : bad flag.
- free(spell->SpellAction);// FIXME : Use a destructor : free pointer,
list..
- spell->SpellAction = NULL;
- spell->f = NULL;
- errl("Unsupported tag", value);
- }
-}
-
-
-// **************************************************************************
-// Generic condition parsers for autocast for spell.
-// **************************************************************************
-
-/**
-** To pushback the condition \p cond to the list \p begin.
-** @param begin : begin of the list.
-** @param cond : condition to add.
-*/
-local void pushback_condition(t_Conditions **begin, t_Conditions *cond)
-{
-
-
- t_Conditions *next;
-
- assert(begin != NULL);
- assert(cond != NULL);
-
- if (*begin == NULL) {
- *begin = cond;
- return ;
- }
- for(next = *begin; next->next != NULL; next = next->next) {
- next->next = cond;
- }
-}
-
-/*
-** Pointer on function to parse 'condition.
-** @param spellName : name of spell modified.
-** @param id : last keyword recognized.
-** @param list : args for \p id.
-** @param generic : list for generic conditions.
-** @param specific : list for specific conditions.
-*/
-typedef void f_ccl_condition(const char *spellName, const char *id, SCM
list,
- t_Conditions **generic, t_Conditions **specific);
-
-/**
-** Parsing true or false.
-** factorisation of code.
-** @param SpellName : Name of spell.
-** @param id : last keywork.
-** @param expectvalue : OUTPUT <- 1 if true 0 else
-*/
-local int ccl_true(const char *SpellName, const char *id, int *expectvalue,
SCM value)
-{
- assert(SpellName);
- assert(id);
- assert(expectvalue);
-
- *expectvalue = 0;
- if (gh_eq_p(value, gh_symbol2scm("true"))) {
- *expectvalue = 1;
- return 1;
- }
- if (gh_eq_p(value, gh_symbol2scm("false"))) {
- return 1;
- }
-// Warning user : Unknown flag
- DebugLevel0Fn("In spell-type %s : %s : %s\n"
- _C_ SpellName _C_ id _C_ "Argument must be true or false");
- return 0;
-}
-
-/*
-** Parse the Condition for spell.
-** list = #t #flagtype
-*/
-local void ccl_UnitTypeFlag(const char *SpellName, const char *id, SCM list,
- t_Conditions **generic, t_Conditions **specific)
-{
-
-
- SCM value;
- t_Conditions *cond;
-
-
-
- struct {
- const char *id;
- int flag;
- } parser[] = {
- {"building", flag_building},
- {"coward", flag_coward},
- {"canattack", flag_canattack},
- {"organic", flag_organic},
- {"undead", flag_isundead},
- {NULL, 0}
- };
- int i;
-
- assert(id != NULL);
- assert(SpellName != NULL);
- assert(generic != NULL);
- assert(specific != NULL);
-
-
- cond = malloc(sizeof(*cond));
- memset(cond, 0, sizeof(*cond));
- value = gh_car(list);
- if (!ccl_true(SpellName, id, &cond->expectvalue, value)) {
- free(cond);
- return ;
- }
- list = gh_cdr(list);
- value = gh_car(list);
- for (i = 0; parser[i].id != NULL; i++) {
- if (gh_eq_p(value, gh_symbol2scm((char *)parser[i].id))) {
- cond->u.flag = parser[i].flag;
- break;
- }
- }
- if (parser[i].id == NULL) {
- DebugLevel0Fn("FIXME : WARNING : unknow flag");
- free(cond);
- return ;
- }
- cond->f.specific = CheckUnitTypeFlag;
- pushback_condition(specific, cond);
-}
-
-/**
-** Parse the Condition for spell.
-** list = #t #f_flag #n
-*/
-local void ccl_DurationEffect(const char *SpellName, const char *id, SCM
list,
- t_Conditions **generic, t_Conditions **specific)
-{
-
-
- SCM value;
- t_Conditions *cond;
- struct {
- const char *id;
- int flag;
- } parser[] = {
- {"bloodlust", flag_bloodlust},
- {"flameshield", flag_flameshield},
- {"haste", flag_haste},
- {"invisibility", flag_invisibility},
- {"slow", flag_slow},
- {"unholyarmor", flag_unholyarmor},
- {"HP", flag_HP},
- {"mana", flag_Mana},
- {"HP_percent", flag_HP_percent},
- {"mana_percent", flag_Mana_percent},
- {NULL, 0}
- };
- int i;
-
- assert(id != NULL);
- assert(SpellName != NULL);
- assert(generic != NULL);
- assert(specific != NULL);
-
- cond = malloc(sizeof(*cond));
- memset(cond, 0, sizeof(*cond));
- value = gh_car(list);
- if (!ccl_true(SpellName, id, &cond->expectvalue, value)) {
- free(cond);
- return ;
- }
- list = gh_cdr(list);
- value = gh_car(list);
- if (!gh_eq_p(value, gh_symbol2scm("flag"))) {
- DebugLevel0Fn("FIXME : WARNING : unknow flag");
- free(cond);
- return ;
- }
- list = gh_cdr(list);
- value = gh_car(list);
- for (i = 0; parser[i].id != NULL; i++) {
- if (gh_eq_p(value, gh_symbol2scm((char *)parser[i].id))) {
- cond->u.durationeffect.flag = parser[i].flag;
- break;
- }
- }
- if (parser[i].id == NULL) {
- DebugLevel0Fn("FIXME : WARNING : unknow flag");
- // FIXME : WARNING.
- free(cond);
- return ;
- }
- list = gh_cdr(list);
- value = gh_car(list);
- if (!gh_eq_p(value, gh_symbol2scm("value"))) {
- DebugLevel0Fn("FIXME : WARNING : unknow flag");
- free(cond);
- return ;
- }
- list = gh_cdr(list);
- value = gh_car(list);
- cond->u.durationeffect.ttl = gh_scm2int(value);
- cond->f.specific = CheckUnitDurationEffect;
- pushback_condition(specific, cond);
-}
-
-/*
-** For enemy presence
-** list = #t range #n
-*/
-void ccl_enemy_presence(const char *SpellName, const char *id, SCM list,
- t_Conditions **generic, t_Conditions **specific)
-{
-
- SCM value;
- t_Conditions *cond;
-
- assert(id != NULL);
- assert(SpellName != NULL);
- assert(generic != NULL);
- assert(specific != NULL);
-
- cond = malloc(sizeof(*cond));
- memset(cond, 0, sizeof(*cond));
- value = gh_car(list);
- if (!ccl_true(SpellName, id, &cond->expectvalue, value)) {
- free(cond);
- return ;
- }
- list = gh_cdr(list);
- value = gh_car(list);
- if (!gh_eq_p(value, gh_symbol2scm("range"))) {
- DebugLevel0Fn("FIXME : WARNING : unknow flag");
- free(cond);
- return ;
- }
- list = gh_cdr(list);
- value = gh_car(list);
- cond->f.generic = CheckEnemyPresence; // In spell.c
- cond->u.range = gh_scm2int(value);
- if (cond->u.range <= 0 && cond->u.range != -1/*no limit*/) {
- DebugLevel0Fn("FIXME : WARNING : range <= 0");
- // Warn : range <= 0 have no sens, must be strict positive. or = -1
- free(cond);
- return ;
- }
- pushback_condition(generic, cond);
-}
-
-/*
-** For enemy presence
-** list = #t
-*/
-void ccl_alliance(const char *SpellName, const char *id, SCM list,
- t_Conditions **generic, t_Conditions **specific)
-{
-
-
- SCM value;
- t_Conditions *cond;
-
- assert(id != NULL);
- assert(SpellName != NULL);
- assert(generic != NULL);
- assert(specific != NULL);
-
- cond = malloc(sizeof(*cond));
- memset(cond, 0, sizeof(*cond));
- value = /*gh_car(*/list/*)*/;
- if (!ccl_true(SpellName, id, &cond->expectvalue, value)) {// warn
user
- free(cond);
- return ;
- }
- cond->f.specific = CheckAllied;
- pushback_condition(specific, cond);
-}
-
-/*
-** Parse the Condition for spell.
-*/
-local void ccl_spell_all_condition(const char*SpellName, const char *id, SCM
list,
- t_Conditions **generic, t_Conditions **specific)
-{
-
-
- int i;
- struct {
- const char *id;
- f_ccl_condition *f;
- } parser[] = {
- {"UnitTypeflag", ccl_UnitTypeFlag},
- {"DurationEffect", ccl_DurationEffect},
- {"Enemypresence", ccl_enemy_presence},
- {"Alliance", ccl_alliance},
- { NULL, 0}
- };
-
- SCM value;
-
- assert(id != NULL);
- assert(SpellName != NULL);
- assert(generic != NULL);
- assert(specific != NULL);
-
-
- for (; !gh_null_p(list); list = gh_cdr(list)) {
- value = gh_car(list);
- for (i = 0; parser[i].id != NULL; i++) {
- if (gh_eq_p(value, gh_symbol2scm((char *) parser[i].id))) {
- list = gh_cdr(list);
- parser[i].f(SpellName, parser[i].id, gh_car(list), generic,
specific);
- break;
- }
- }
- assert(parser[i].id);
- }
-}
-
-/*
-** Parse the Condition for spell.
-*/
-local void ccl_spell_condition(const char *id, SCM list, SpellType *spell)
-{
- assert(id != NULL);
- assert(spell != NULL);
-
- ccl_spell_all_condition(spell->IdentName, id, list,
- &spell->Condition_generic,&spell->Condition_specific);
-}
-
-local void ccl_spell_autocast(const char *id, SCM list, SpellType *spell)
-{
-
-
- SCM value;
- int range;
-
- assert(id != NULL);
- assert(spell != NULL);
-
- value = gh_car(list);
- if (!gh_eq_p(value, gh_symbol2scm("range"))) {
- return ;
- }
-
- list = gh_cdr(list);
- value = gh_car(list);
- range = gh_scm2int(value);
- if (range <= 0 && range != -1/*no limit*/) {
- // Warn : range <= 0 have no sens, must be strict positive. or = -1
- return ;
- }
- spell->AutoCast = malloc(sizeof(*spell->AutoCast));
- memset(spell->AutoCast, 0, sizeof(*spell->AutoCast));
- spell->AutoCast->Range = range;
- list = gh_cdr(list);
- value = gh_car(list);
- if (!gh_eq_p(value, gh_symbol2scm("condition"))) {
- return ;
- }
- list = gh_cdr(list);
- value = gh_car(list);
- ccl_spell_all_condition(spell->IdentName, "Autocast conditions", value,
-
&spell->AutoCast->Condition_generic,&spell->AutoCast->Condition_specific);
-}
-
-/**
-** Parse Spell.
-**
-** @param list List describing Spell.
-*/
-local SCM CclDefineSpell(SCM list)
-{
- char *identname;
- char *str;
- SpellType *spell;
- SCM value;
-
- identname = gh_scm2newstr(gh_car(list), NULL);
- list = gh_cdr(list);
- spell = SpellTypeByIdent(identname);
- if (spell != NULL) {
- DebugLevel0Fn("Redefining spell-type `%s'\n" _C_ identname);
- free(identname);
- } else {
- SpellTypeTable =
realloc(SpellTypeTable,(1+SpellTypeCount)*sizeof(SpellType));
- spell = &SpellTypeTable[SpellTypeCount++];
- memset(spell,0,sizeof(SpellType));
- spell->Ident=SpellTypeCount-1;
- spell->IdentName=identname;
- spell->DependencyId = -1;
- }
- while (!gh_null_p(list)) {
- value = gh_car(list);
- list = gh_cdr(list);
- if (gh_eq_p(value,gh_symbol2scm("showname"))) {
- if (spell->Name) {
- free(spell->Name);
- }
- 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"))) {
- // Free the old name, get the new one
- free(spell->SoundWhenCast.Name);
- spell->SoundWhenCast.Name=gh_scm2newstr(gh_car(list),0);
-
spell->SoundWhenCast.Sound=SoundIdForName(spell->SoundWhenCast.Name);
- // Check for sound.
- if (!spell->SoundWhenCast.Sound) {
- free(spell->SoundWhenCast.Name);
- spell->SoundWhenCast.Name=0;
- }
- list=gh_cdr(list);
- } else if (gh_eq_p(value,gh_symbol2scm("missile-when-cast"))) {
- str = gh_scm2newstr(gh_car(list), NULL);
- spell->Missile = MissileTypeByIdent(str);
- if (spell->Missile == NULL) {
- DebugLevel0Fn("in spell-type '%s' : missile %s does not exist\n"
- _C_ spell->Name _C_ str);
- }
- free(str);
- list=gh_cdr(list);
- } else if (gh_eq_p(value,gh_symbol2scm("depend"))) {
- ccl_spell_dependency("depend", gh_car(list), spell);
- list = gh_cdr(list);
- } else
- {
- errl("Unsupported tag", value);
- }
- }
- return SCM_UNSPECIFIED;
-}
-
-/**
-** Register CCL features for Spell.
-*/
-global void SpellCclRegister(void)
-{
- gh_new_procedureN("define-spell", CclDefineSpell);
-}
-
-/**
-** Save spells to a CCL file.
-**
-** @param file The file to save to.
-*/
-global void SaveSpells(CLFile* file)
-{
- SpellType* spell;
- struct s_haste *hinfo;
-
- assert(file);
-
- for (spell=SpellTypeTable;spell<SpellTypeTable+SpellTypeCount;++spell) {
- CLprintf(file,"(define-spell\n");
- //
- // Misc small stuff.
- //
- CLprintf(file," \"%s\"\n",spell->IdentName);
- CLprintf(file," 'showname \"%s\"\n",spell->Name);
- CLprintf(file," 'manacost %d\n",spell->ManaCost);
- CLprintf(file," 'range %d\n",spell->Range);
- if (spell->SoundWhenCast.Name) {
- CLprintf(file," 'sound-when-cast
\"%s\"\n",spell->SoundWhenCast.Name);
- }
- if (spell->Missile) {
- CLprintf(file," 'missile-when-cast
\"%s\"\n",spell->Missile->Ident);
- }
- //
- // Target type.
- //
- CLprintf(file," 'target '");
- switch (spell->Target) {
- case TargetSelf:
- CLprintf(file,"self\n");
- break;
- case TargetNone:
- CLprintf(file,"none\n");
- break;
- case TargetPosition:
- CLprintf(file,"position\n");
- break;
- case TargetUnit:
- CLprintf(file,"unit\n");
- break;
- default:
- DebugLevel0("Bad spell, can't save.\n");
- DebugCheck(1);
- }
- //
- // Save the action(effect of the spell)
- //
- CLprintf(file," 'action");
- if (spell->f==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->f==CastFireball) {
- CLprintf(file," '(fireball (ttl %d damage %d) )\n",
- 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) {
- CLprintf(file," '(healing (HP %d)
)\n",spell->SpellAction->healing.HP);
- } else if (spell->f==CastSummon) {
- CLprintf(file," '(Summon
\"%s\")\n",spell->SpellAction->Summon.UnitType->Ident);
- } else if (spell->f==CastHaste) {
- CLprintf(file," '(haste ( ");
- hinfo=&spell->SpellAction->haste;
- while (hinfo) {
- switch (hinfo->flag) {
- case flag_haste:
- CLprintf(file,"haste");
- break;
- case flag_slow:
- CLprintf(file,"slow");
- break;
- case flag_bloodlust:
- CLprintf(file,"bloodlust");
- break;
- case flag_HP:
- CLprintf(file,"HP");
- break;
- case flag_Mana:
- CLprintf(file,"mana");
- break;
- case flag_HP_percent:
- CLprintf(file,"HP_percent");
- break;
- case flag_Mana_percent:
- CLprintf(file,"mana_percent");
- break;
- default:
- DebugLevel0("wrong haste flags?\n");
- DebugCheck(1);
- }
- CLprintf(file," %d ",hinfo->value);
- hinfo=hinfo->next;
- }
- CLprintf(file,") )\n");
- } else if (spell->f==CastInvisibility) {
- CLprintf(file," '(Invisibility ( flag ");
- if (spell->SpellAction->invisibility.flag==flag_invisibility) {
- CLprintf(file,"invisibility");
- } else if (spell->SpellAction->invisibility.flag==flag_unholyarmor)
{
- CLprintf(file,"unholyarmor");
- } else {
- DebugLevel0("Wrong flags?\n");
- DebugCheck(1);
- }
- CLprintf(file," value %d missile \"%s\") )\n",
- spell->SpellAction->invisibility.value,
- spell->SpellAction->invisibility.missile->Ident);
- } else if (spell->f==CastPolymorph) {
- CLprintf(file," '(Polymorph \"%s\")\n",
- spell->SpellAction->Polymorph.NewForm->Ident);
- } else if (spell->f==CastRaiseDead) {
- CLprintf(file," '(RaiseDead \"%s\")\n",
- spell->SpellAction->RaiseDead.Skeleton->Ident);
- } else if (spell->f==CastFlameShield) {
- CLprintf(file," '(flame-shield (ttl %d) )\n",
- 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==CastSpawnPortal) {
- CLprintf(file," '(spawn-portal \"%s\")\n",
- spell->SpellAction->SpawnPortal.PortalType->Ident);
- } else if (spell->f==CastDeathCoil) {
- CLprintf(file," '(death-coil)\n");
- // FIXME: more?
- } else if (spell->f==CastWhirlwind) {
- CLprintf(file," '(Whirlwind (ttl %d) )\n",
- spell->SpellAction->whirlwind.TTL);
- // FIXME: more?
- }
- //
- // FIXME: Save conditions
- //
-
- //
- // FIXME: Save autocast and AI info
- //
- CLprintf(file,")\n");
- }
-}
-
-//@}
+// _________ __ __
+// / _____// |_____________ _/ |______ ____ __ __ ______
+// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
+// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
+// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
+// \/ \/ \//_____/ \/
+// ______________________ ______________________
+// T H E W A R B E G I N S
+// Stratagus - A free fantasy real time strategy game engine
+//
+/address@hidden ccl_spells.c - The spell ccl functions.. */
+//
+// (c) Copyright 1998-2003 by Joris DAUPHIN
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 dated June, 1991.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+//
+// $Id: ccl_spell.c,v 1.6 2003/09/26 18:46:28 jsalmon3 Exp $
+//@{
+
+/*----------------------------------------------------------------------------
+-- Includes
+----------------------------------------------------------------------------*/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "stratagus.h"
+/*
+#include "video.h"
+#include "tileset.h"
+#include "unittype.h"
+*/
+#include "spells.h"
+#include "ccl_sound.h"
+#include "ccl.h"
+
+/**
+** pointer on function.
+** @param id : last keyword recognized.
+** @param list : list to be parsed. (just the args).
+** @param spell : spelltype to modify.
+** FIXME: remove all this cruft
+*/
+typedef void f_ccl_spell(const char *id, SCM list, SpellType *spell);
+
+// **************************************************************************
+// Direct affectation for spell
+// **************************************************************************
+
+/**
+** Parse the dependency of spell.
+** list = (upgrade "upgradename")
+*/
+local void ccl_spell_dependency(const char *id, SCM list, SpellType *spell)
+{
+ char *dependencyName;
+ SCM value;
+ int dependencyId;
+
+ DebugCheck(!id);
+ DebugCheck(!spell);
+
+ dependencyName = NULL;
+ dependencyId = -1;
+
+ value = gh_car(list);
+
+ if (!gh_eq_p(value, gh_symbol2scm("upgrade"))) {
+ return;
+ }
+ list = gh_cdr(list);
+ value = gh_car(list);
+
+ dependencyName = gh_scm2newstr(value, NULL);
+ dependencyId = UpgradeIdByIdent(dependencyName);
+ if (dependencyId == -1) {
+ // warn user
+ DebugLevel0Fn("Bad upgrade-name '%s'\n" _C_ dependencyName);
+ free(dependencyName);
+ return ;
+ }
+ spell->DependencyId = dependencyId;
+ free(dependencyName);
+}
+
+
+// **************************************************************************
+// Action parsers for spellAction
+// **************************************************************************
+
+/**
+** For blizzard and DeathAndDecay.
+** list = fields #n shards #n damage #n
+*/
+local char CclSpellParseActionAreaBombardment(const char *spellname,
+ SCM list, SpellActionType *spellaction)
+{
+ SCM value;
+
+ DebugCheck(!spellname);
+ DebugCheck(!spellaction);
+
+ memset(spellaction, sizeof(spellaction), 0);
+ for (; !gh_null_p(list); list = gh_cdr(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));
+ continue;
+ } else if (gh_eq_p(value, gh_symbol2scm("shards"))) {
+ spellaction->AreaBombardment.Shards = gh_scm2int(gh_car(list));
+ continue;
+ } else if (gh_eq_p(value, gh_symbol2scm("damage"))) {
+ spellaction->AreaBombardment.Damage = gh_scm2int(gh_car(list));
+ continue;
+ } else if (gh_eq_p(value, gh_symbol2scm("start-offset-x"))) {
+ spellaction->AreaBombardment.StartOffsetX =
gh_scm2int(gh_car(list));
+ continue;
+ } else if (gh_eq_p(value, gh_symbol2scm("start-offset-y"))) {
+ spellaction->AreaBombardment.StartOffsetY =
gh_scm2int(gh_car(list));
+ continue;
+ }
+ // warning user : unknow tag
+ DebugLevel0Fn("FIXME : better WARNING : unknow tag");
+ }
+ return 1;
+}
+
+/**
+** For fireball and Runes.
+** list = 'ttl #n 'damage #n
+*/
+local char CclSpellParseActionFireball(const char *SpellName, SCM list,
+ SpellActionType *spellaction)
+{
+ int ttl;
+ int damage;
+ SCM value;
+
+ DebugCheck(!SpellName);
+ DebugCheck(!spellaction);
+
+ ttl = 0;
+ damage = 0;
+ for (; !gh_null_p(list); list = gh_cdr(list)) {
+ value = gh_car(list);
+ list = gh_cdr(list);
+ // Todo, Warn for redefinition ???
+ if (gh_eq_p(value, gh_symbol2scm("ttl"))) {
+ ttl = gh_scm2int(gh_car(list));
+ continue;
+ }
+ if (gh_eq_p(value, gh_symbol2scm("damage"))) {
+ damage = gh_scm2int(gh_car(list));
+ continue;
+ }
+ // warning user : unknow tag
+ DebugLevel0Fn("FIXME : better WARNING : unknow tag");
+ }
+ if (damage == 0) {
+ DebugLevel0Fn("in spell-type %s : %s" _C_ SpellName _C_
+ "damage == 0 have no sense : Positive to deal damage, negative
for healing.");
+ return 0;
+ }
+ if (ttl <= 0) {
+ // TTL must be positive.
+ DebugLevel0Fn("in spell-type %s : %s" _C_ SpellName _C_
+ "TTL <= 0 have no sense");
+ return 0;
+ }
+ spellaction->Fireball.TTL = ttl;
+ spellaction->Fireball.Damage = damage;
+ return 1;
+}
+
+/**
+** For flameshield and whirlwind.
+** list = 'ttl #n
+*/
+local char CclSpellParseActionFlameShield(const char *spellname, SCM list,
+ SpellActionType *spellaction)
+{
+ int ttl;
+ SCM value;
+
+ DebugCheck(!spellname);
+ DebugCheck(!spellaction);
+
+ ttl = 0;
+ for (; !gh_null_p(list); list = gh_cdr(list)) {
+ value = gh_car(list);
+ list = gh_cdr(list);
+ // Todo, Warn for redefinition ???
+ if (gh_eq_p(value, gh_symbol2scm("ttl"))) {
+ ttl = gh_scm2int(gh_car(list));
+ continue;
+ }
+ // Warning user : unknow tag
+ DebugLevel0Fn("FIXME : better WARNING : unknow tag");
+ }
+ if (ttl <= 0) {
+ DebugLevel0Fn("in spell-type %s : %s" _C_ spellname _C_
+ "ttl <= 0 have no sense");// ttl must be positive.
+ return 0;
+ }
+ spellaction->FlameShield.TTL = ttl;
+ return 1;
+}
+
+/**
+** For haste, slow and bloodlust.
+** list = *haste #n *slow #n *bloodlust #n
+** One or more.
+** @todo Free when an error occurs. Do a function to do this.
+*/
+local char CclSpellParseActionHaste(const char *spellname, SCM list,
+ SpellActionType *spellaction)
+{
+ struct {
+ const char *id;
+ int flag;
+ } parser[] = {
+ {"haste", flag_haste},
+ {"slow", flag_slow},
+ {"bloodlust", flag_bloodlust},
+ {"HP", flag_HP},
+ {"mana", flag_Mana},
+ {"HP_percent", flag_HP_percent},
+ {"mana_percent", flag_Mana_percent},
+ {NULL, 0}
+ };
+ int i;
+ SCM value;
+ struct s_haste *lasthaste;
+ struct s_haste *newhaste;
+
+ DebugCheck(!spellname);
+ DebugCheck(!spellaction);
+
+ lasthaste = NULL;
+ newhaste = &spellaction->haste;
+ while(!gh_null_p(list)) {
+ if (lasthaste != NULL) {
+ newhaste = malloc(sizeof(*newhaste));
+ memset(newhaste, 0, sizeof(*newhaste));
+ }
+ value = gh_car(list);
+ list = gh_cdr(list);
+ for (i = 0; parser[i].id != NULL; i++) {
+ if (gh_eq_p(value, gh_symbol2scm((char *) parser[i].id))) {
+ newhaste->flag = parser[i].flag;
+ newhaste->value = gh_scm2int(gh_car(list));
+ list = gh_cdr(list);
+ newhaste->next = NULL;
+ break;
+ }
+ }
+ if (parser[i].id == NULL) {
+ DebugLevel0Fn("FIXME : better WARNING : unknow tag");
+ // FIXME : free correctly.
+ return 0;
+ }
+ if (spellaction->haste.value < 0) {
+ DebugLevel0Fn("in spell-type %s : %s" _C_ spellname _C_
+ "value < 0 have no sense : "
+ "nul to desactivate, positive te activate.");// value == 0
have no sense.
+ // FIXME : free correctly.
+ return 0;
+ }
+ if (lasthaste != NULL) {
+ lasthaste->next = newhaste;
+ }
+ lasthaste = newhaste;
+ }
+ return 1;
+}
+
+/**
+** For healing or dealing damage.
+** HP positive for healing, negative for dealing damage.
+** list = (HP #n)
+*/
+local char CclSpellParseActionHealing(const char *spellname, SCM list,
+ SpellActionType *spellaction)
+{
+ SCM value;
+ int hp;
+
+ DebugCheck(!spellname);
+ DebugCheck(!spellaction);
+
+ hp = 0;
+
+ for (; !gh_null_p(list); list = gh_cdr(list)) {
+ value = gh_car(list);
+ list = gh_cdr(list);
+ // Todo, Warn for redefinition ???
+ if (gh_eq_p(value, gh_symbol2scm("HP"))) {
+ hp = gh_scm2int(gh_car(list));
+ continue;
+ }
+ // Warning user : unknow tag
+ DebugLevel0Fn("FIXME : better WARNING : unknow tag");
+ }
+ if (spellaction->healing.HP != 0 && spellaction->healing.HP != hp) {
+ DebugLevel3Fn("Redefinition in spell-type '%s' : %s : '%d' -> '%d'\n"
+ _C_ SpellName _C_ "HP" _C_ spellaction->healing.HP _C_ hp);
+ }
+ spellaction->healing.HP = hp;
+ if (hp == 0) {
+ DebugLevel0Fn("in spell-type %s : %s" _C_ spellname _C_
+ "HP == 0 have no sense : "
+ "Positive for healing, negative to deal damages.");
+ return 0;
+ }
+ return 1;
+}
+
+/**
+** For invisibility and unholyarmor.
+** list = flag #f_inv value #n missile "missile-name"
+*/
+local char CclSpellParseActionInvisibility(const char *spellname, SCM list,
+ SpellActionType *spellaction)
+{
+ const struct {
+ const char *id;
+ int flag;
+ } parser[] = {
+ {"unholyarmor", flag_unholyarmor},
+ {"invisibility", flag_invisibility},
+ {NULL, 0}
+ };
+ SCM value;
+ int i;
+ int flag;
+ int sec;
+ char *missilename;
+
+ flag = -1;
+ sec = 0;
+ missilename = NULL;
+
+ DebugCheck(!spellname);
+ DebugCheck(!spellaction);
+
+ for (; !gh_null_p(list); list = gh_cdr(list)) {
+ value = gh_car(list);
+ list = gh_cdr(list);
+ // Todo, Warn for redefinition ???
+ if (gh_eq_p(value, gh_symbol2scm("flag"))) {
+ value = gh_car(list);
+ flag = -1;
+ for (i = 0; parser[i].id != NULL; i++) {
+ if (gh_eq_p(value, gh_symbol2scm((char *) parser[i].id))) {
+ flag = parser[i].flag;
+ break;
+ }
+ }
+ continue;
+ }
+ if (gh_eq_p(value, gh_symbol2scm("value"))) {
+ sec = gh_scm2int(gh_car(list));
+ continue;
+ }
+ if (gh_eq_p(value, gh_symbol2scm("missile"))) {
+ if (missilename != NULL) {
+ free(missilename);
+ }
+ missilename = gh_scm2newstr(gh_car(list), NULL);
+ continue;
+ }
+ // Warning user : unknow tag
+ DebugLevel0Fn("FIXME : better WARNING : unknow tag");
+ }
+ if (missilename == NULL) {
+ DebugLevel0Fn("FIXME : better WARNING : must define
(correctly)missilename");
+ return 0;
+ }
+ if (flag == -1) {
+ DebugLevel0Fn("FIXME : better WARNING : must define (correctly)
missilename");
+ free(missilename);
+ return 0;
+ }
+ if (sec <= 0) {
+ DebugLevel0Fn("FIXME : better WARNING : must define (correctly)
missilename");
+ free(missilename);
+ return 0;
+ }
+ spellaction->invisibility.flag = flag;
+ spellaction->invisibility.value = sec;
+ spellaction->invisibility.missile = MissileTypeByIdent(missilename);
+ if (spellaction->invisibility.missile == NULL) {
+ // Warning user : Missile doesn't exist (yet).
+ DebugLevel0Fn("in spell-type %s : '%s' %s " _C_ spellname _C_
missilename
+ _C_ "does not exist.");
+ free(missilename);
+ return 0;
+ }
+ free(missilename);
+ return 1;
+}
+
+/**
+** For summoning
+** list = ("unittypename")
+** @note WARNING, use for other functions than summon, see
ccl_spell_action.
+*/
+local char CclSpellParseActionSummon(const char *spellname, SCM list,
+ SpellActionType *spellaction)
+{
+ char *str;
+ UnitType *unittype;
+
+ DebugCheck(!spellname);
+ DebugCheck(!spellaction);
+
+ str = gh_scm2newstr(list, NULL);
+ unittype = UnitTypeByIdent(str);
+ spellaction->Summon.UnitType = unittype;
+ if (unittype == NULL) {
+ DebugLevel0Fn("in spell-type %s : Unittype '%s'doesn't exist" _C_
+ spellname _C_ str);
+ free(str);
+ return 0;
+ }
+ free(str);
+ return 1;
+}
+
+// **************************************************************************
+// main Action parsers for spellAction
+// **************************************************************************
+
+/**
+** return false if a problem occurs (unit not found...)
+** @param spellname : name of spell to display errors and warning.
+** @param list : argument for spell.
+** @param spellaction : What we want modify.
+*/
+typedef char f_ccl_action(const char *spellname, SCM list, SpellActionType
*spellaction);
+
+/**
+** Parse the action for spell.
+** list = ('Spell '(parameter))
+*/
+local void ccl_spell_action(const char *id, SCM list, SpellType *spell)
+{
+ int i;
+ struct {
+ SpellFunc *fspell;
+ const char *id;
+ f_ccl_action *f;
+ } parser[] = {
+ {CastAreaBombardment, "area-bombardment",
CclSpellParseActionAreaBombardment},
+ {CastSpawnPortal, "spawn-portal",
CclSpellParseActionSummon/*circleofpower*/},
+ {CastDeathCoil, "death-coil", NULL},
+ {CastFireball, "fireball", CclSpellParseActionFireball},
+ {CastFlameShield, "flame-shield", CclSpellParseActionFlameShield},
+ {CastHaste, "haste", CclSpellParseActionHaste},
+ {CastHealing, "healing", CclSpellParseActionHealing},
+ {CastHolyVision, "HolyVision", CclSpellParseActionSummon/*holyvision*/},
+ {CastInvisibility, "Invisibility", CclSpellParseActionInvisibility},
+ {CastPolymorph, "Polymorph", CclSpellParseActionSummon/*polymorph*/},
+ {CastRaiseDead, "RaiseDead", CclSpellParseActionSummon/*raisedead*/},
+ {CastRunes, "Runes", CclSpellParseActionFireball/*runes*/},
+ {CastSummon, "Summon", CclSpellParseActionSummon},
+ {CastWhirlwind, "Whirlwind",
CclSpellParseActionFlameShield/*whirlwind*/},
+ {0, NULL, NULL}
+ };
+ SCM value;
+
+ value = list;
+ value = gh_car(value);
+
+ DebugCheck(!id);
+ DebugCheck(!spell);
+
+ for (i = 0; parser[i].id != NULL; i++) {
+ if (gh_eq_p(value, gh_symbol2scm((char *) parser[i].id))) {
+ spell->f = parser[i].fspell;
+ if (parser[i].f) {
+ 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 = (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..
+ free(spell->SpellAction);// FIXME : Use a destructor : free
pointer, list..
+ spell->SpellAction = NULL;
+ spell->f = NULL;
+ }
+ }
+ break;
+ }
+ }
+ if (parser[i].id == NULL) {
+ // Warning user : bad flag.
+ free(spell->SpellAction);// FIXME : Use a destructor : free pointer,
list..
+ spell->SpellAction = NULL;
+ spell->f = NULL;
+ errl("Unsupported tag", value);
+ }
+}
+
+
+// **************************************************************************
+// Generic condition parsers for autocast for spell.
+// **************************************************************************
+
+/**
+** To pushback the condition \p cond to the list \p begin.
+** @param begin : begin of the list.
+** @param cond : condition to add.
+*/
+local void pushback_condition(t_Conditions **begin, t_Conditions *cond)
+{
+ t_Conditions *next;
+
+ DebugCheck(!begin);
+ DebugCheck(!cond);
+
+ if (*begin == NULL) {
+ *begin = cond;
+ return ;
+ }
+ for(next = *begin; next->next != NULL; next = next->next) {
+ next->next = cond;
+ }
+}
+
+/**
+** Pointer on function to parse 'condition.
+** @param spellName : name of spell modified.
+** @param id : last keyword recognized.
+** @param list : args for \p id.
+** @param generic : list for generic conditions.
+** @param specific : list for specific conditions.
+*/
+typedef void f_ccl_condition(const char *spellname, const char *id, SCM list,
+ t_Conditions **generic, t_Conditions **specific);
+
+/**
+** Parsing true or false.
+** factorisation of code.
+** @param SpellName : Name of spell.
+** @param id : last keywork.
+** @param expectvalue : OUTPUT <- 1 if true 0 else
+*/
+local int ccl_true(const char *spellname, const char *id, int *expectvalue,
+ SCM value)
+{
+ DebugCheck(!spellname);
+ DebugCheck(!id);
+ DebugCheck(!expectvalue);
+
+ *expectvalue = 0;
+ if (gh_eq_p(value, gh_symbol2scm("true"))) {
+ *expectvalue = 1;
+ return 1;
+ }
+ if (gh_eq_p(value, gh_symbol2scm("false"))) {
+ return 1;
+ }
+// Warning user : Unknown flag
+ DebugLevel0Fn("In spell-type %s : %s : %s\n"
+ _C_ spellname _C_ id _C_ "Argument must be true or false");
+ return 0;
+}
+
+/**
+** Parse the Condition for spell.
+** list = #t #flagtype
+*/
+local void ccl_UnitTypeFlag(const char *spellname, const char *id, SCM list,
+ t_Conditions **generic, t_Conditions **specific)
+{
+ SCM value;
+ t_Conditions *cond;
+ struct {
+ const char *id;
+ int flag;
+ } parser[] = {
+ {"building", flag_building},
+ {"coward", flag_coward},
+ {"canattack", flag_canattack},
+ {"organic", flag_organic},
+ {"undead", flag_isundead},
+ {NULL, 0}
+ };
+ int i;
+
+ DebugCheck(!id);
+ DebugCheck(!spellname);
+ DebugCheck(!generic);
+ DebugCheck(!specific);
+
+
+ cond = malloc(sizeof(*cond));
+ memset(cond, 0, sizeof(*cond));
+ value = gh_car(list);
+ if (!ccl_true(spellname, id, &cond->expectvalue, value)) {
+ free(cond);
+ return ;
+ }
+ list = gh_cdr(list);
+ value = gh_car(list);
+ for (i = 0; parser[i].id != NULL; i++) {
+ if (gh_eq_p(value, gh_symbol2scm((char *)parser[i].id))) {
+ cond->u.flag = parser[i].flag;
+ break;
+ }
+ }
+ if (parser[i].id == NULL) {
+ DebugLevel0Fn("FIXME : WARNING : unknow flag");
+ free(cond);
+ return ;
+ }
+ cond->f.specific = CheckUnitTypeFlag;
+ pushback_condition(specific, cond);
+}
+
+/**
+** Parse the Condition for spell.
+** list = #t #f_flag #n
+*/
+local void ccl_DurationEffect(const char *spellname, const char *id, SCM list,
+ t_Conditions **generic, t_Conditions **specific)
+{
+ SCM value;
+ t_Conditions *cond;
+ struct {
+ const char *id;
+ int flag;
+ } parser[] = {
+ {"bloodlust", flag_bloodlust},
+ {"flameshield", flag_flameshield},
+ {"haste", flag_haste},
+ {"invisibility", flag_invisibility},
+ {"slow", flag_slow},
+ {"unholyarmor", flag_unholyarmor},
+ {"HP", flag_HP},
+ {"mana", flag_Mana},
+ {"HP_percent", flag_HP_percent},
+ {"mana_percent", flag_Mana_percent},
+ {NULL, 0}
+ };
+ int i;
+
+ DebugCheck(!id);
+ DebugCheck(!spellname);
+ DebugCheck(!generic);
+ DebugCheck(!specific);
+
+ cond = malloc(sizeof(*cond));
+ memset(cond, 0, sizeof(*cond));
+ value = gh_car(list);
+ if (!ccl_true(spellname, id, &cond->expectvalue, value)) {
+ free(cond);
+ return ;
+ }
+ list = gh_cdr(list);
+ value = gh_car(list);
+ if (!gh_eq_p(value, gh_symbol2scm("flag"))) {
+ DebugLevel0Fn("FIXME : WARNING : unknow flag");
+ free(cond);
+ return ;
+ }
+ list = gh_cdr(list);
+ value = gh_car(list);
+ for (i = 0; parser[i].id != NULL; i++) {
+ if (gh_eq_p(value, gh_symbol2scm((char *)parser[i].id))) {
+ cond->u.durationeffect.flag = parser[i].flag;
+ break;
+ }
+ }
+ if (parser[i].id == NULL) {
+ DebugLevel0Fn("FIXME : WARNING : unknow flag");
+ // FIXME : WARNING.
+ free(cond);
+ return ;
+ }
+ list = gh_cdr(list);
+ value = gh_car(list);
+ if (!gh_eq_p(value, gh_symbol2scm("value"))) {
+ DebugLevel0Fn("FIXME : WARNING : unknow flag");
+ free(cond);
+ return ;
+ }
+ list = gh_cdr(list);
+ value = gh_car(list);
+ cond->u.durationeffect.ttl = gh_scm2int(value);
+ cond->f.specific = CheckUnitDurationEffect;
+ pushback_condition(specific, cond);
+}
+
+/**
+** For enemy presence
+** list = #t range #n
+*/
+void ccl_enemy_presence(const char *spellname, const char *id, SCM list,
+ t_Conditions **generic, t_Conditions **specific)
+{
+ SCM value;
+ t_Conditions *cond;
+
+ DebugCheck(!id);
+ DebugCheck(!spellname);
+ DebugCheck(!generic);
+ DebugCheck(!specific);
+
+ cond = malloc(sizeof(*cond));
+ memset(cond, 0, sizeof(*cond));
+ value = gh_car(list);
+ if (!ccl_true(spellname, id, &cond->expectvalue, value)) {
+ free(cond);
+ return ;
+ }
+ list = gh_cdr(list);
+ value = gh_car(list);
+ if (!gh_eq_p(value, gh_symbol2scm("range"))) {
+ DebugLevel0Fn("FIXME : WARNING : unknow flag");
+ free(cond);
+ return ;
+ }
+ list = gh_cdr(list);
+ value = gh_car(list);
+ cond->f.generic = CheckEnemyPresence; // In spell.c
+ cond->u.range = gh_scm2int(value);
+ if (cond->u.range <= 0 && cond->u.range != -1/*no limit*/) {
+ DebugLevel0Fn("FIXME : WARNING : range <= 0");
+ // Warn : range <= 0 have no sens, must be strict positive. or = -1
+ free(cond);
+ return ;
+ }
+ pushback_condition(generic, cond);
+}
+
+/**
+** For enemy presence
+** list = #t
+*/
+void ccl_alliance(const char *spellname, const char *id, SCM list,
+ t_Conditions **generic, t_Conditions **specific)
+{
+ SCM value;
+ t_Conditions *cond;
+
+ DebugCheck(!id);
+ DebugCheck(!spellname);
+ DebugCheck(!generic);
+ DebugCheck(!specific);
+
+ cond = malloc(sizeof(*cond));
+ memset(cond, 0, sizeof(*cond));
+ value = /*gh_car(*/list/*)*/;
+ if (!ccl_true(spellname, id, &cond->expectvalue, value)) {// warn
user
+ free(cond);
+ return ;
+ }
+ cond->f.specific = CheckAllied;
+ pushback_condition(specific, cond);
+}
+
+/**
+** Parse the Condition for spell.
+*/
+local void ccl_spell_all_condition(const char *spellname, const char *id,
+ SCM list, t_Conditions **generic, t_Conditions **specific)
+{
+ int i;
+ struct {
+ const char *id;
+ f_ccl_condition *f;
+ } parser[] = {
+ {"UnitTypeflag", ccl_UnitTypeFlag},
+ {"DurationEffect", ccl_DurationEffect},
+ {"Enemypresence", ccl_enemy_presence},
+ {"Alliance", ccl_alliance},
+ { NULL, 0}
+ };
+ SCM value;
+
+ DebugCheck(!id);
+ DebugCheck(!spellname);
+ DebugCheck(!generic);
+ DebugCheck(!specific);
+
+ for (; !gh_null_p(list); list = gh_cdr(list)) {
+ value = gh_car(list);
+ for (i = 0; parser[i].id != NULL; i++) {
+ if (gh_eq_p(value, gh_symbol2scm((char *) parser[i].id))) {
+ list = gh_cdr(list);
+ parser[i].f(spellname, parser[i].id, gh_car(list), generic,
specific);
+ break;
+ }
+ }
+ DebugCheck(!parser[i].id);
+ }
+}
+
+/**
+** Parse the Condition for spell.
+*/
+local void ccl_spell_condition(const char *id, SCM list, SpellType *spell)
+{
+ DebugCheck(!id);
+ DebugCheck(!spell);
+
+ ccl_spell_all_condition(spell->IdentName, id, list,
+ &spell->Condition_generic,&spell->Condition_specific);
+}
+
+/**
+** FIXME: docu
+*/
+local void ccl_spell_autocast(const char *id, SCM list, SpellType *spell)
+{
+ SCM value;
+ int range;
+
+ DebugCheck(!id);
+ DebugCheck(!spell);
+
+ value = gh_car(list);
+ if (!gh_eq_p(value, gh_symbol2scm("range"))) {
+ return ;
+ }
+
+ list = gh_cdr(list);
+ value = gh_car(list);
+ range = gh_scm2int(value);
+ if (range <= 0 && range != -1/*no limit*/) {
+ // Warn : range <= 0 have no sens, must be strict positive. or = -1
+ return ;
+ }
+ spell->AutoCast = malloc(sizeof(*spell->AutoCast));
+ memset(spell->AutoCast, 0, sizeof(*spell->AutoCast));
+ spell->AutoCast->Range = range;
+ list = gh_cdr(list);
+ value = gh_car(list);
+ if (!gh_eq_p(value, gh_symbol2scm("condition"))) {
+ return ;
+ }
+ list = gh_cdr(list);
+ value = gh_car(list);
+ ccl_spell_all_condition(spell->IdentName, "Autocast conditions", value,
+
&spell->AutoCast->Condition_generic,&spell->AutoCast->Condition_specific);
+}
+
+/**
+** Parse Spell.
+**
+** @param list List describing Spell.
+*/
+local SCM CclDefineSpell(SCM list)
+{
+ char *identname;
+ char *str;
+ SpellType *spell;
+ SCM value;
+
+ identname = gh_scm2newstr(gh_car(list), NULL);
+ list = gh_cdr(list);
+ spell = SpellTypeByIdent(identname);
+ if (spell != NULL) {
+ DebugLevel0Fn("Redefining spell-type `%s'\n" _C_ identname);
+ free(identname);
+ } else {
+ SpellTypeTable =
realloc(SpellTypeTable,(1+SpellTypeCount)*sizeof(SpellType));
+ spell = &SpellTypeTable[SpellTypeCount++];
+ memset(spell,0,sizeof(SpellType));
+ spell->Ident=SpellTypeCount-1;
+ spell->IdentName=identname;
+ spell->DependencyId = -1;
+ }
+ while (!gh_null_p(list)) {
+ value = gh_car(list);
+ list = gh_cdr(list);
+ if (gh_eq_p(value,gh_symbol2scm("showname"))) {
+ if (spell->Name) {
+ free(spell->Name);
+ }
+ 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"))) {
+ // Free the old name, get the new one
+ free(spell->SoundWhenCast.Name);
+ spell->SoundWhenCast.Name=gh_scm2newstr(gh_car(list),0);
+
spell->SoundWhenCast.Sound=SoundIdForName(spell->SoundWhenCast.Name);
+ // Check for sound.
+ if (!spell->SoundWhenCast.Sound) {
+ free(spell->SoundWhenCast.Name);
+ spell->SoundWhenCast.Name=0;
+ }
+ list=gh_cdr(list);
+ } else if (gh_eq_p(value,gh_symbol2scm("missile-when-cast"))) {
+ str = gh_scm2newstr(gh_car(list), NULL);
+ spell->Missile = MissileTypeByIdent(str);
+ if (spell->Missile == NULL) {
+ DebugLevel0Fn("in spell-type '%s' : missile %s does not exist\n"
+ _C_ spell->Name _C_ str);
+ }
+ free(str);
+ list=gh_cdr(list);
+ } else if (gh_eq_p(value,gh_symbol2scm("depend"))) {
+ ccl_spell_dependency("depend", gh_car(list), spell);
+ list = gh_cdr(list);
+ } else
+ {
+ errl("Unsupported tag", value);
+ }
+ }
+ return SCM_UNSPECIFIED;
+}
+
+/**
+** Register CCL features for Spell.
+*/
+global void SpellCclRegister(void)
+{
+ gh_new_procedureN("define-spell", CclDefineSpell);
+}
+
+/**
+** Save spells to a CCL file.
+**
+** @param file The file to save to.
+*/
+global void SaveSpells(CLFile *file)
+{
+ SpellType *spell;
+ struct s_haste *hinfo;
+
+ DebugCheck(!file);
+
+ for (spell = SpellTypeTable; spell < SpellTypeTable + SpellTypeCount;
++spell) {
+ CLprintf(file,"(define-spell\n");
+ //
+ // Misc small stuff.
+ //
+ CLprintf(file," \"%s\"\n",spell->IdentName);
+ CLprintf(file," 'showname \"%s\"\n",spell->Name);
+ CLprintf(file," 'manacost %d\n",spell->ManaCost);
+ CLprintf(file," 'range %d\n",spell->Range);
+ if (spell->SoundWhenCast.Name) {
+ CLprintf(file," 'sound-when-cast
\"%s\"\n",spell->SoundWhenCast.Name);
+ }
+ if (spell->Missile) {
+ CLprintf(file," 'missile-when-cast
\"%s\"\n",spell->Missile->Ident);
+ }
+ //
+ // Target type.
+ //
+ CLprintf(file," 'target '");
+ switch (spell->Target) {
+ case TargetSelf:
+ CLprintf(file,"self\n");
+ break;
+ case TargetNone:
+ CLprintf(file,"none\n");
+ break;
+ case TargetPosition:
+ CLprintf(file,"position\n");
+ break;
+ case TargetUnit:
+ CLprintf(file,"unit\n");
+ break;
+ default:
+ DebugLevel0("Bad spell, can't save.\n");
+ DebugCheck(1);
+ }
+ //
+ // Save the action(effect of the spell)
+ //
+ CLprintf(file," 'action");
+ if (spell->f==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->f==CastFireball) {
+ CLprintf(file," '(fireball (ttl %d damage %d) )\n",
+ 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) {
+ CLprintf(file," '(healing (HP %d)
)\n",spell->SpellAction->healing.HP);
+ } else if (spell->f==CastSummon) {
+ CLprintf(file," '(Summon
\"%s\")\n",spell->SpellAction->Summon.UnitType->Ident);
+ } else if (spell->f==CastHaste) {
+ CLprintf(file," '(haste ( ");
+ hinfo=&spell->SpellAction->haste;
+ while (hinfo) {
+ switch (hinfo->flag) {
+ case flag_haste:
+ CLprintf(file,"haste");
+ break;
+ case flag_slow:
+ CLprintf(file,"slow");
+ break;
+ case flag_bloodlust:
+ CLprintf(file,"bloodlust");
+ break;
+ case flag_HP:
+ CLprintf(file,"HP");
+ break;
+ case flag_Mana:
+ CLprintf(file,"mana");
+ break;
+ case flag_HP_percent:
+ CLprintf(file,"HP_percent");
+ break;
+ case flag_Mana_percent:
+ CLprintf(file,"mana_percent");
+ break;
+ default:
+ DebugLevel0("wrong haste flags?\n");
+ DebugCheck(1);
+ }
+ CLprintf(file," %d ",hinfo->value);
+ hinfo=hinfo->next;
+ }
+ CLprintf(file,") )\n");
+ } else if (spell->f==CastInvisibility) {
+ CLprintf(file," '(Invisibility ( flag ");
+ if (spell->SpellAction->invisibility.flag==flag_invisibility) {
+ CLprintf(file,"invisibility");
+ } else if (spell->SpellAction->invisibility.flag==flag_unholyarmor)
{
+ CLprintf(file,"unholyarmor");
+ } else {
+ DebugLevel0("Wrong flags?\n");
+ DebugCheck(1);
+ }
+ CLprintf(file," value %d missile \"%s\") )\n",
+ spell->SpellAction->invisibility.value,
+ spell->SpellAction->invisibility.missile->Ident);
+ } else if (spell->f==CastPolymorph) {
+ CLprintf(file," '(Polymorph \"%s\")\n",
+ spell->SpellAction->Polymorph.NewForm->Ident);
+ } else if (spell->f==CastRaiseDead) {
+ CLprintf(file," '(RaiseDead \"%s\")\n",
+ spell->SpellAction->RaiseDead.Skeleton->Ident);
+ } else if (spell->f==CastFlameShield) {
+ CLprintf(file," '(flame-shield (ttl %d) )\n",
+ 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==CastSpawnPortal) {
+ CLprintf(file," '(spawn-portal \"%s\")\n",
+ spell->SpellAction->SpawnPortal.PortalType->Ident);
+ } else if (spell->f==CastDeathCoil) {
+ CLprintf(file," '(death-coil)\n");
+ // FIXME: more?
+ } else if (spell->f==CastWhirlwind) {
+ CLprintf(file," '(Whirlwind (ttl %d) )\n",
+ spell->SpellAction->whirlwind.TTL);
+ // FIXME: more?
+ }
+ //
+ // FIXME: Save conditions
+ //
+
+ //
+ // FIXME: Save autocast and AI info
+ //
+ CLprintf(file,")\n");
+ }
+}
+
+//@}
Index: stratagus/src/clone/spells.c
diff -u stratagus/src/clone/spells.c:1.100 stratagus/src/clone/spells.c:1.101
--- stratagus/src/clone/spells.c:1.100 Fri Sep 26 11:47:50 2003
+++ stratagus/src/clone/spells.c Fri Sep 26 14:46:28 2003
@@ -27,7 +27,7 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
//
-// $Id: spells.c,v 1.100 2003/09/26 15:47:50 n0body Exp $
+// $Id: spells.c,v 1.101 2003/09/26 18:46:28 jsalmon3 Exp $
/*
** And when we cast our final spell
@@ -50,7 +50,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <assert.h>
#include "stratagus.h"
@@ -67,7 +66,7 @@
----------------------------------------------------------------------------*/
// TODO Move this in missile.c and remove Hardcoded string.
-MissileType* MissileTypeRune = NULL; // MissileTypeByIdent("missile-rune");
+MissileType *MissileTypeRune; // MissileTypeByIdent("missile-rune");
/*----------------------------------------------------------------------------
-- Variables
@@ -76,11 +75,11 @@
/**
** Define the names and effects of all im play available spells.
*/
-global SpellType *SpellTypeTable = NULL;
+global SpellType *SpellTypeTable;
/// How many spell-types are available
-global int SpellTypeCount = 0;
+global int SpellTypeCount;
/*----------------------------------------------------------------------------
-- Functions (Spells Controllers/Callbacks)
@@ -149,7 +148,7 @@
**
** @todo Move this code into the missile code
*/
-local void SpellDeathCoilController(Missile * missile)
+local void SpellDeathCoilController(Missile *missile)
{
Unit *table[UnitMax];
int i;
@@ -200,12 +199,16 @@
}
}
} else {
-//
-// No target unit -- try enemies in range 5x5 // Must be parametrable
-//
- int ec = 0; // enemy count
- int x = missile->DX / TileSizeX;
- int y = missile->DY / TileSizeY;
+ //
+ // No target unit -- try enemies in range 5x5 // Must be parametrable
+ //
+ int ec; // enemy count
+ int x;
+ int y;
+
+ ec = 0;
+ x = missile->DX / TileSizeX;
+ y = missile->DY / TileSizeY;
n = SelectUnits(x - 2, y - 2, x + 2, y + 2, table);
if (n == 0) {
@@ -306,7 +309,8 @@
// Changes direction every 3 seconds (approx.)
//
if (!(missile->TTL % 100)) { // missile has reached target unit/spot
- int nx, ny;
+ int nx;
+ int ny;
do {
// find new destination in the map
@@ -328,7 +332,7 @@
**
** @todo Move this code into the missile code
*/
-local void SpellRunesController(Missile * missile)
+local void SpellRunesController(Missile *missile)
{
Unit *table[UnitMax];
int i;
@@ -363,7 +367,7 @@
**
** @todo Move this code into the missile code
*/
-local void SpellFlameShieldController(Missile * missile)
+local void SpellFlameShieldController(Missile *missile)
{
static int fs_dc[] = {
0, 32, 5, 31, 10, 30, 16, 27, 20, 24, 24, 20, 27, 15, 30, 10, 31,
@@ -438,17 +442,17 @@
**
** @return =!0 if spell should be repeated, 0 if not
*/
-global int CastSpawnPortal(Unit* caster, const SpellType* spell
__attribute__((unused)),
- Unit* target __attribute__((unused)), int x, int y)
+global int CastSpawnPortal(Unit *caster, const SpellType *spell
__attribute__((unused)),
+ Unit *target __attribute__((unused)), int x, int y)
{
// FIXME: vladi: cop should be placed only on explored land
Unit *portal;
UnitType *ptype;
- assert(caster);
- assert(spell);
- assert(spell->SpellAction);
- assert(spell->SpellAction->SpawnPortal.PortalType);
+ DebugCheck(!caster);
+ DebugCheck(!spell);
+ DebugCheck(!spell->SpellAction);
+ DebugCheck(!spell->SpellAction->SpawnPortal.PortalType);
ptype = spell->SpellAction->SpawnPortal.PortalType;
@@ -486,24 +490,26 @@
**
** @return =!0 if spell should be repeated, 0 if not
*/
-global int CastAreaBombardment(Unit* caster, const SpellType* spell,
- Unit* target __attribute__((unused)), int x, int y)
+global int CastAreaBombardment(Unit *caster, const SpellType *spell,
+ Unit *target __attribute__((unused)), int x, int y)
{
int fields;
int shards;
int damage;
- Missile *mis = NULL;
+ Missile *mis;
int offsetx;
int offsety;
int dx;
int dy;
int i;
- assert(caster);
- assert(spell);
- assert(spell->SpellAction);
+ DebugCheck(!caster);
+ DebugCheck(!spell);
+ DebugCheck(!spell->SpellAction);
//assert(x in range, y in range);
+ mis = NULL;
+
fields = spell->SpellAction->AreaBombardment.Fields;
shards = spell->SpellAction->AreaBombardment.Shards;
damage = spell->SpellAction->AreaBombardment.Damage;
@@ -553,18 +559,23 @@
**
** @return =!0 if spell should be repeated, 0 if not
*/
-global int CastDeathCoil(Unit* caster, const SpellType* spell, Unit*
target,int x, int y)
+global int CastDeathCoil(Unit *caster, const SpellType *spell, Unit *target,
+ int x, int y)
{
- Missile *mis = NULL;
- int sx = caster->X;
- int sy = caster->Y;
-
- assert(caster);
- assert(spell);
- assert(spell->SpellAction);
+ Missile *mis;
+ int sx;
+ int sy;
+
+ DebugCheck(!caster);
+ DebugCheck(!spell);
+ DebugCheck(!spell->SpellAction);
// assert(target);
// assert(x in range, y in range);
+ mis = NULL;
+ sx = caster->X;
+ sy = caster->Y;
+
caster->Mana -= spell->ManaCost;
PlayGameSound(spell->SoundWhenCast.Sound, MaxSampleVolume);
@@ -594,24 +605,26 @@
**
** @return =!0 if spell should be repeated, 0 if not
*/
-global int CastFireball(Unit* caster, const SpellType* spell,
- Unit* target __attribute__((unused)), int x, int y)
+global int CastFireball(Unit *caster, const SpellType *spell,
+ Unit *target __attribute__((unused)), int x, int y)
{
- Missile *missile = NULL;
+ Missile *missile;
int sx;
int sy;
int dist;
- assert(caster);
- assert(spell);
- assert(spell->SpellAction);
- assert(spell->Missile);
+ DebugCheck(!caster);
+ DebugCheck(!spell);
+ DebugCheck(!spell->SpellAction);
+ DebugCheck(!spell->Missile);
+
+ missile = NULL;
// NOTE: fireball can be casted on spot
sx = caster->X;
sy = caster->Y;
dist = MapDistance(sx, sy, x, y);
- assert(dist != 0);
+ DebugCheck(!dist);
x += ((x - sx) * 10) / dist;
y += ((y - sy) * 10) / dist;
sx = sx * TileSizeX + TileSizeX / 2;
@@ -641,18 +654,20 @@
**
** @return =!0 if spell should be repeated, 0 if not
*/
-global int CastFlameShield(Unit* caster, const SpellType* spell, Unit* target,
+global int CastFlameShield(Unit* caster, const SpellType *spell, Unit *target,
int x __attribute__((unused)), int y __attribute__((unused)))
{
- Missile* mis = NULL;
+ Missile *mis;
int i;
- assert(caster);
- assert(spell);
- assert(spell->SpellAction);
- assert(target);
+ DebugCheck(!caster);
+ DebugCheck(!spell);
+ DebugCheck(!spell->SpellAction);
+ DebugCheck(!target);
// assert(x in range, y in range);
- assert(spell->Missile);
+ DebugCheck(!spell->Missile);
+
+ mis = NULL;
// get mana cost
caster->Mana -= spell->ManaCost;
@@ -680,15 +695,15 @@
**
** @return =!0 if spell should be repeated, 0 if not
*/
-global int CastHaste(Unit* caster, const SpellType* spell, Unit* target,
+global int CastHaste(Unit *caster, const SpellType *spell, Unit *target,
int x, int y)
{
- struct s_haste *haste;
+ struct s_haste *haste;
- assert(caster);
- assert(spell);
- assert(spell->SpellAction);
- assert(target);
+ DebugCheck(!caster);
+ DebugCheck(!spell);
+ DebugCheck(!spell->SpellAction);
+ DebugCheck(!target);
// get mana cost
caster->Mana -= spell->ManaCost;
@@ -736,8 +751,7 @@
}
break;
default:
- // Warn devellopers
- assert(0);
+ DebugCheck(1);
}
}
CheckUnitToBeDrawn(target);
@@ -759,30 +773,35 @@
**
** @return =!0 if spell should be repeated, 0 if not
*/
-global int CastHealing(Unit* caster, const SpellType* spell, Unit* target,int
x, int y)
+global int CastHealing(Unit *caster, const SpellType *spell, Unit *target,
+ int x, int y)
{
int i;
int diffHP;
- int diffMana = caster->Mana;
- int HP = spell->SpellAction->healing.HP;
- int Mana = spell->ManaCost;
-
- assert(caster);
- assert(spell);
- assert(spell->SpellAction);
- assert(target);
+ int diffMana;
+ int hp;
+ int mana;
+
+ DebugCheck(!caster);
+ DebugCheck(!spell);
+ DebugCheck(!spell->SpellAction);
+ DebugCheck(!target);
+
+ diffMana = caster->Mana;
+ hp = spell->SpellAction->healing.HP;
+ mana = spell->ManaCost;
// Healing or exorcism
- diffHP = (HP > 0) ? target->Stats->HitPoints - target->HP : target->HP;
- i = min(diffHP / HP + (diffHP % HP ? 1 : 0),
- diffMana / Mana + (diffMana % Mana ? 1 : 0));
+ diffHP = (hp > 0) ? target->Stats->HitPoints - target->HP : target->HP;
+ i = min(diffHP / hp + (diffHP % hp ? 1 : 0),
+ diffMana / mana + (diffMana % mana ? 1 : 0));
// Stop when no mana or full HP
- caster->Mana -= i * Mana;
- target->HP += i * HP;
+ caster->Mana -= i * mana;
+ target->HP += i * hp;
- if (HP < 0) {
+ if (hp < 0) {
#ifdef USE_HP_FOR_XP
- caster->XP += i * HP;
+ caster->XP += i * hp;
#endif
if (!target->HP) {
caster->Player->Score += target->Type->Points;
@@ -816,11 +835,12 @@
**
** @return =!0 if spell should be repeated, 0 if not
*/
-global int CastHolyVision(Unit* caster, const SpellType* spell, Unit*
target,int x, int y)
+global int CastHolyVision(Unit *caster, const SpellType *spell, Unit *target,
+ int x, int y)
{
- assert(caster);
- assert(spell);
- assert(spell->SpellAction);
+ DebugCheck(!caster);
+ DebugCheck(!spell);
+ DebugCheck(!spell->SpellAction);
// assert(x in range, y in range);
caster->Mana -= spell->ManaCost; // get mana cost
@@ -851,13 +871,14 @@
**
** @return =!0 if spell should be repeated, 0 if not
*/
-global int CastInvisibility(Unit* caster, const SpellType* spell, Unit*
target,int x, int y)
+global int CastInvisibility(Unit *caster, const SpellType *spell, Unit *target,
+ int x, int y)
{
- assert(caster);
- assert(spell);
- assert(spell->SpellAction);
- assert(target);
- assert(spell->SpellAction->invisibility.missile);
+ DebugCheck(!caster);
+ DebugCheck(!spell);
+ DebugCheck(!spell->SpellAction);
+ DebugCheck(!target);
+ DebugCheck(!spell->SpellAction->invisibility.missile);
// get mana cost
caster->Mana -= spell->ManaCost;
@@ -881,7 +902,7 @@
break;
default:
// Something is WRONG!!!
- assert(0);
+ DebugCheck(1);
}
CheckUnitToBeDrawn(target);
}
@@ -903,15 +924,18 @@
**
** @return =!0 if spell should be repeated, 0 if not
*/
-global int CastPolymorph(Unit* caster, const SpellType* spell, Unit*
target,int x, int y)
+global int CastPolymorph(Unit *caster, const SpellType *spell, Unit *target,
+ int x, int y)
{
- UnitType* type = spell->SpellAction->Polymorph.NewForm;
+ UnitType *type;
+
+ DebugCheck(!caster);
+ DebugCheck(!spell);
+ DebugCheck(!spell->SpellAction);
+ DebugCheck(!target);
- assert(caster);
- assert(spell);
- assert(spell->SpellAction);
- assert(target);
- assert(type);
+ type = spell->SpellAction->Polymorph.NewForm;
+ DebugCheck(!type);
caster->Player->Score += target->Type->Points;
if (target->Type->Building) {
@@ -952,18 +976,20 @@
**
** @return =!0 if spell should be repeated, 0 if not
*/
-global int CastRaiseDead(Unit* caster, const SpellType* spell, Unit*
target,int x, int y)
+global int CastRaiseDead(Unit *caster, const SpellType *spell, Unit *target,
+ int x, int y)
{
Unit **corpses;
Unit *tempcorpse;
UnitType *skeleton;
- assert(caster);
- assert(spell);
- assert(spell->SpellAction);
+ DebugCheck(!caster);
+ DebugCheck(!spell);
+ DebugCheck(!spell->SpellAction);
// assert(x in range, y in range);
+
skeleton = spell->SpellAction->RaiseDead.Skeleton;
- assert(skeleton);
+ DebugCheck(!skeleton);
corpses = &CorpseList;
@@ -1013,23 +1039,25 @@
**
** @return =!0 if spell should be repeated, 0 if not
*/
-global int CastRunes(Unit* caster, const SpellType* spell,
- Unit* target __attribute__((unused)), int x, int y)
+global int CastRunes(Unit *caster, const SpellType *spell,
+ Unit *target __attribute__((unused)), int x, int y)
{
- Missile *mis = NULL;
-
+ Missile *mis;
const int xx[] = {-1,+1, 0, 0, 0};
const int yy[] = { 0, 0, 0,-1,+1};
-
- int oldx = x;
- int oldy = y;
+ int oldx;
+ int oldy;
int i;
- assert(caster);
- assert(spell);
- assert(spell->SpellAction);
+ DebugCheck(!caster);
+ DebugCheck(spell);
+ DebugCheck(!spell->SpellAction);
// assert(x in range, y in range);
+ mis = NULL;
+ oldx = x;
+ oldy = y;
+
PlayGameSound(spell->SoundWhenCast.Sound, MaxSampleVolume);
for (i = 0; i < 5; i++) {
x = oldx + xx[i];
@@ -1060,13 +1088,13 @@
**
** @return =!0 if spell should be repeated, 0 if not
*/
-global int CastSummon(Unit* caster, const SpellType* spell, Unit* target,
+global int CastSummon(Unit *caster, const SpellType *spell, Unit *target,
int x, int y)
{
- assert(caster);
- assert(spell);
- assert(spell->SpellAction);
- assert(spell->SpellAction->Summon.UnitType != NULL);
+ DebugCheck(!caster);
+ DebugCheck(!spell);
+ DebugCheck(!spell->SpellAction);
+ DebugCheck(!spell->SpellAction->Summon.UnitType);
// assert(x in range, y in range);
caster->Mana -= spell->ManaCost;
@@ -1098,16 +1126,18 @@
**
** @return =!0 if spell should be repeated, 0 if not
*/
-global int CastWhirlwind(Unit* caster, const SpellType* spell,
- Unit* target __attribute__((unused)), int x, int y)
+global int CastWhirlwind(Unit *caster, const SpellType *spell,
+ Unit *target __attribute__((unused)), int x, int y)
{
- Missile *mis = NULL;
+ Missile *mis;
- assert(caster);
- assert(spell);
- assert(spell->SpellAction);
+ DebugCheck(!caster);
+ DebugCheck(!spell);
+ DebugCheck(!spell->SpellAction);
// assert(x in range, y in range);
+ mis = NULL;
+
caster->Mana -= spell->ManaCost;
PlayGameSound(spell->SoundWhenCast.Sound, MaxSampleVolume);
mis = MakeMissile(spell->Missile,
@@ -1122,17 +1152,18 @@
// Specific conditions
// ****************************************************************************
-/*
+/**
** Check for unittype properties of unittype himself
*/
global int CheckUnitTypeFlag(const t_Conditions *condition,
- const Unit* caster,const Unit* target, int x, int y)
+ const Unit *caster, const Unit *target, int x, int y)
{
- assert(caster != NULL);
- assert(condition != NULL);
+ DebugCheck(!caster);
+ DebugCheck(!condition);
- if (target == NULL)
- return !condition->expectvalue;
+ if (target == NULL) {
+ return !condition->expectvalue;
+ }
// FIXME Modify unit struture for an array of boolean ?
switch (condition->u.flag) {
case flag_coward:
@@ -1146,36 +1177,41 @@
case flag_building:
return target->Type->Building;
default:
- assert(0);
- // Warn devellopers
+ DebugCheck(1);
+ return !condition->expectvalue;
}
}
-/*
+/**
** Check for alliance status.
*/
-global int CheckAllied(const t_Conditions *condition,const Unit* caster,const
Unit* target, int x, int y)
+global int CheckAllied(const t_Conditions *condition, const Unit *caster,
+ const Unit *target, int x, int y)
{
- assert(caster != NULL);
+ DebugCheck(!caster);
return caster->Player == target->Player || IsAllied(caster->Player,
target) ? 1 : 0;
}
-/*
+/**
** Check if target is self
*/
-global int Checkhimself(const t_Conditions *condition,const Unit* caster,const
Unit* target, int x, int y)
+global int CheckHimself(const t_Conditions *condition, const Unit *caster,
+ const Unit *target, int x, int y)
{
- assert(caster != NULL);
+ DebugCheck(!caster);
return caster == target;
}
-/*
+/**
** Check duration effects.
*/
-global int CheckUnitDurationEffect(const t_Conditions *condition,const Unit*
caster,const Unit* target, int x, int y)
+global int CheckUnitDurationEffect(const t_Conditions *condition,
+ const Unit *caster, const Unit *target, int x, int y)
{
int ttl;
- assert(condition);
+
+ DebugCheck(!condition);
+
ttl = condition->u.durationeffect.ttl;
if (target == NULL) {
@@ -1205,8 +1241,8 @@
return (target->Mana * 100 >= ttl * target->Type->_MaxMana); //
FIXME : MaxMana.
/// Add here the other cases
default:
- abort();
- // Warn devellopers
+ DebugCheck(1);
+ return !condition->expectvalue;
}
}
@@ -1214,19 +1250,26 @@
// Specific conditions
// ****************************************************************************
-global int CheckEnemyPresence(const t_Conditions *condition,const Unit* caster)
+/**
+** FIXME: docu
+*/
+global int CheckEnemyPresence(const t_Conditions *condition, const Unit
*caster)
{
- Unit* table[UnitMax];
+ Unit *table[UnitMax];
int i;
int n;
- int range = condition->u.range;
- int x = caster->X;
- int y = caster->Y;
-
- assert(condition != NULL);
- assert(caster != NULL);
-
-// +1 should be + Caster_tile_Size ?
+ int range;
+ int x;
+ int y;
+
+ DebugCheck(!condition);
+ DebugCheck(!caster);
+
+ range = condition->u.range;
+ x = caster->X;
+ y = caster->Y;
+
+ // FIXME: +1 should be + Caster_tile_Size ?
n = SelectUnits(x - range, y - range,x + range + 1, y + range + 1,table);
for (i = 0; i < n; ++i) {
if (IsEnemy(caster->Player, table[i])) {
@@ -1240,13 +1283,18 @@
// Target constructor
// ****************************************************************************
+/**
+** FIXME: docu
+*/
local Target *NewTarget(TargetType t, const Unit *unit, int x, int y)
{
- Target *target = (Target *) malloc(sizeof(*target));
+ Target *target;
+
+ target = (Target *)malloc(sizeof(*target));
- assert(!(unit == NULL && t == TargetUnit));
- assert(!(!(0 <= x && x < TheMap.Width) && t == TargetPosition));
- assert(!(!(0 <= y && y < TheMap.Height) && t == TargetPosition));
+ DebugCheck(unit == NULL && t == TargetUnit);
+ DebugCheck(!(0 <= x && x < TheMap.Width) && t == TargetPosition);
+ DebugCheck(!(0 <= y && y < TheMap.Height) && t == TargetPosition);
target->which_sort_of_target = t;
target->unit = (Unit *)unit;
@@ -1255,22 +1303,30 @@
return target;
}
-local Target *NewTargetNone()
+/**
+** FIXME: docu
+*/
+local Target *NewTargetNone(void)
{
return NewTarget(TargetNone, NULL, 0, 0);
}
+/**
+** FIXME: docu
+*/
local Target *NewTargetUnit(const Unit *unit)
{
- assert(unit != NULL);
+ DebugCheck(!unit);
return NewTarget(TargetUnit, unit, 0, 0);
}
-
+/**
+** FIXME: docu
+*/
local Target *NewTargetPosition(int x, int y)
{
- assert(0 <= x && x < TheMap.Width);
- assert(0 <= y && y < TheMap.Height);
+ DebugCheck(!(0 <= x && x < TheMap.Width));
+ DebugCheck(!(0 <= y && y < TheMap.Height));
return NewTarget(TargetPosition, NULL, x, y);
}
@@ -1282,24 +1338,25 @@
/**
** Check all generic conditions.
*/
-local int PassGenericCondition(const Unit* caster,const SpellType* spell,const
t_Conditions *condition)
+local int PassGenericCondition(const Unit *caster, const SpellType *spell,
+ const t_Conditions *condition)
{
int ret;
- assert(caster != NULL);
- assert(spell != NULL);
+ DebugCheck(!caster);
+ DebugCheck(!spell);
// FIXME : Move it in spell->Condition_generic ???
// mana is a must!
if (caster->Mana < spell->ManaCost) {
return 0;
}
- for (/*condition = spell->Condition_generic*/; condition != NULL;
condition = condition->next)
- {
- assert(condition->f.generic != NULL);
+ /*condition = spell->Condition_generic*/
+ for (; condition != NULL; condition = condition->next) {
+ DebugCheck(!condition->f.generic);
ret = condition->f.generic(condition, caster);
- assert(ret == 0 || ret == 1);
- assert(condition->expectvalue == 0 || condition->expectvalue == 1);
+ DebugCheck(!(ret == 0 || ret == 1));
+ DebugCheck(!(condition->expectvalue == 0 || condition->expectvalue ==
1));
if (ret != condition->expectvalue) {
return 0;
}
@@ -1312,19 +1369,19 @@
** @return 1 if condition is ok.
** @return 0 else.
*/
-local int PassSpecificCondition(const Unit* caster,const SpellType* spell,
- const Unit* target,int x,int y,const t_Conditions *condition)
+local int PassSpecificCondition(const Unit *caster, const SpellType *spell,
+ const Unit *target, int x, int y, const t_Conditions *condition)
{
int ret;
- assert(caster != NULL);
- assert(spell != NULL);
+ DebugCheck(!caster);
+ DebugCheck(!spell);
for (/*condition = spell->Condition_specific*/; condition != NULL;
condition = condition->next) {
- assert(condition->f.specific != NULL);
+ DebugCheck(!condition->f.specific);
ret = condition->f.specific(condition, caster, target, x, y);
- assert(ret == 0 || ret == 1);
- assert(condition->expectvalue == 0 || condition->expectvalue == 1);
+ DebugCheck(!(ret == 0 || ret == 1));
+ DebugCheck(!(condition->expectvalue == 0 || condition->expectvalue ==
1));
if (ret != condition->expectvalue) {
return 0;
}
@@ -1342,8 +1399,8 @@
** @return Target* choosen target or Null if spell can't be cast.
**
*/
-// should be global (for AI) ???
-local Target *SelectTargetUnitsOfAutoCast(const Unit *caster,const SpellType
*spell)
+// FIXME: should be global (for AI) ???
+local Target *SelectTargetUnitsOfAutoCast(const Unit *caster, const SpellType
*spell)
{
Unit* table[UnitMax];
int x;
@@ -1353,9 +1410,9 @@
int i;
int j;
- assert(spell != NULL);
- assert(spell->AutoCast != NULL);
- assert(caster != NULL);
+ DebugCheck(!spell);
+ DebugCheck(!spell->AutoCast);
+ DebugCheck(!caster);
switch (spell->Target) {
case TargetSelf :
@@ -1371,7 +1428,7 @@
&& y < 0 && y <= TheMap.Height);
// FIXME : CHOOSE a better POSITION (add info in structure ???)
- // Just good enought for holyvision...
+ // Just good enough for holyvision...
return NewTargetPosition(x, y);
case TargetUnit:
x=caster->X;
@@ -1446,13 +1503,14 @@
**
** @return Spell id (index in spell-type table)
*/
-global int SpellIdByIdent(const char *IdentName)
+global int SpellIdByIdent(const char *ident)
{
int id;
- assert(IdentName != NULL);
+
+ DebugCheck(!ident);
for (id = 0; id < SpellTypeCount; ++id) {
- if (strcmp(SpellTypeTable[id].IdentName, IdentName) == 0) {
+ if (strcmp(SpellTypeTable[id].IdentName, ident) == 0) {
return id;
}
}
@@ -1466,20 +1524,25 @@
**
** @return spell-type struct pointer.
*/
-global SpellType *SpellTypeByIdent(const char *IdentName)
+global SpellType *SpellTypeByIdent(const char *ident)
{
int id;
- assert(IdentName != NULL);
- id = SpellIdByIdent(IdentName);
+ DebugCheck(!ident);
+
+ id = SpellIdByIdent(ident);
return (id == -1 ? NULL : &SpellTypeTable[id]);
}
+/**
+** FIXME: docu
+*/
global unsigned CclGetSpellByIdent(SCM value)
{
int i;
- for( i=0; i<SpellTypeCount; ++i ) {
- if( gh_eq_p(value,gh_symbol2scm(SpellTypeTable[i].IdentName)) ) {
+
+ for (i = 0; i < SpellTypeCount; ++i) {
+ if (gh_eq_p(value, gh_symbol2scm(SpellTypeTable[i].IdentName))) {
return i;
}
}
@@ -1495,7 +1558,7 @@
*/
global SpellType *SpellTypeById(int id)
{
- assert(0 <= id && id < SpellTypeCount);
+ DebugCheck(!(0 <= id && id < SpellTypeCount));
return &SpellTypeTable[id];
}
@@ -1508,12 +1571,14 @@
** @param player : player for who we want to know if he knows the spell.
** @param id :
*/
-global int SpellIsAvailable(const Player* player, int SpellId)
+global int SpellIsAvailable(const Player *player, int spellid)
{
- assert(player != NULL);
- assert(0 <= SpellId && SpellId < SpellTypeCount);
+ int dependencyId;
+
+ DebugCheck(!player);
+ DebugCheck(!(0 <= spellid && spellid < SpellTypeCount));
- int dependencyId = SpellTypeTable[SpellId].DependencyId;
+ dependencyId = SpellTypeTable[spellid].DependencyId;
return dependencyId == -1 || UpgradeIdAllowed(player, dependencyId) == 'R';
}
@@ -1526,9 +1591,9 @@
**
** @return 1 if spell can be cast, 0 if not
*/
-global int CanAutoCastSpell(const SpellType* spell)
+global int CanAutoCastSpell(const SpellType *spell)
{
- assert(spell != NULL);
+ DebugCheck(!spell);
return spell->AutoCast ? 1 : 0;
}
@@ -1544,15 +1609,16 @@
**
** @return =!0 if spell should/can casted, 0 if not
*/
-global int CanCastSpell(const Unit* caster,const SpellType* spell,
- const Unit* target, // FIXME : Use an unique
struture t_Target ?
- int x,int y)
-{
- assert(caster != NULL);
- assert(spell != NULL);
-// And caster must know the spell
+global int CanCastSpell(const Unit *caster, const SpellType *spell,
+ const Unit *target, // FIXME : Use an unique struture t_Target ?
+ int x, int y)
+{
+ DebugCheck(!caster);
+ DebugCheck(!spell);
+
+ // And caster must know the spell
// FIXME spell->Ident < MaxSpell
- assert(caster->Type->CanCastSpell &&
caster->Type->CanCastSpell[spell->Ident]);
+ DebugCheck(!(caster->Type->CanCastSpell &&
caster->Type->CanCastSpell[spell->Ident]));
if (!caster->Type->CanCastSpell
|| !caster->Type->CanCastSpell[spell->Ident]
@@ -1572,15 +1638,17 @@
**
** @return 1 if spell is casted, 0 if not.
*/
-global int AutoCastSpell(Unit *caster,const SpellType* spell)
+global int AutoCastSpell(Unit *caster, const SpellType *spell)
{
- Target *target = NULL;
+ Target *target;
- assert(caster != NULL);
- assert(spell != NULL);
- assert(0 <= spell->Ident && spell->Ident < SpellTypeCount);
- assert(caster->Type->CanCastSpell);
- assert(caster->Type->CanCastSpell[spell->Ident]);
+ DebugCheck(!caster);
+ DebugCheck(!spell);
+ DebugCheck(!(0 <= spell->Ident && spell->Ident < SpellTypeCount));
+ DebugCheck(!(caster->Type->CanCastSpell));
+ DebugCheck(!(caster->Type->CanCastSpell[spell->Ident]));
+
+ target = NULL;
if (!PassGenericCondition(caster, spell, spell->Condition_generic)
|| !PassGenericCondition(caster, spell,
spell->AutoCast->Condition_generic)) {
@@ -1609,12 +1677,13 @@
**
** @return !=0 if spell should/can continue or 0 to stop
*/
-global int SpellCast(Unit* caster, const SpellType* spell,Unit* target, int x,
int y)
+global int SpellCast(Unit *caster, const SpellType *spell, Unit *target,
+ int x, int y)
{
- assert(spell != NULL);
- assert(spell->f != NULL);
- assert(caster != NULL);
- assert(SpellIsAvailable(caster->Player, spell->Ident));
+ DebugCheck(!spell);
+ DebugCheck(!spell->f);
+ DebugCheck(!caster);
+ DebugCheck(!SpellIsAvailable(caster->Player, spell->Ident));
caster->Invisible = 0;// unit is invisible until attacks // FIXME Must be
configurable
if (target) {
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Stratagus-CVS] stratagus/src/clone ccl_spell.c spells.c,
Jimmy Salmon <=