stratagus-cvs
[Top][All Lists]
Advanced

[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) {




reply via email to

[Prev in Thread] Current Thread [Next in Thread]