stratagus-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Stratagus-CVS] stratagus data/ccl/spells.ccl data/ccl/stratagu...


From: Crestez Leonard
Subject: [Stratagus-CVS] stratagus data/ccl/spells.ccl data/ccl/stratagu...
Date: Sat, 27 Sep 2003 15:05:47 -0400

CVSROOT:        /cvsroot/stratagus
Module name:    stratagus
Branch:         
Changes by:     Crestez Leonard <address@hidden>        03/09/27 15:05:47

Modified files:
        data/ccl       : spells.ccl stratagus.ccl 
        src/clone      : ccl_spell.c clone.c spells.c 
        src/include    : spells.h stratagus.h 
        src/map        : ccl_map.c 

Log message:
        Lots of spell work.

Patches:
Index: stratagus/data/ccl/spells.ccl
diff -u stratagus/data/ccl/spells.ccl:1.2 stratagus/data/ccl/spells.ccl:1.3
--- stratagus/data/ccl/spells.ccl:1.2   Fri Sep 26 11:47:50 2003
+++ stratagus/data/ccl/spells.ccl       Sat Sep 27 15:05:47 2003
@@ -26,7 +26,7 @@
 ;;      along with this program; if not, write to the Free Software

 ;;      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  
USA

 ;;

-;;     $Id: spells.ccl,v 1.2 2003/09/26 15:47:50 n0body Exp $

+;;     $Id: spells.ccl,v 1.3 2003/09/27 19:05:47 n0body Exp $

 

 ;; For documentation see stratagus/doc/ccl/ccl.html ;; FIXME write and move 
doc.

 

@@ -97,7 +97,7 @@
        'manacost 70

        'range  -1

        'target 'position

-       'action '( HolyVision "unit-revealer" )

+       'action '(summon unit-type unit-revealer time-to-live 100)

        'sound-when-cast "holy vision"

        'missile-when-cast "missile-normal-spell"

        'autocast '(range -1)

@@ -108,7 +108,7 @@
        'manacost 6

        'range  6

        'target 'unit

-       'action '( healing (HP 1) )

+       'action '(adjust-vitals hit-points +1)

        'condition '(   UnitTypeflag (true organic)

                        UnitTypeflag (false building)

                        DurationEffect (false flag HP_percent value 100) ;; HP 
< 100% HPMAX

@@ -127,7 +127,7 @@
        'manacost 4

        'range  10

        'target 'unit

-       'action '( healing (HP -1) )

+       'action '(adjust-vitals hit-points -1)

        'condition '(   UnitTypeflag (true undead)

                        UnitTypeflag (false building)

                        Alliance false

@@ -142,7 +142,7 @@
        'manacost 70

        'range  6

        'target 'none

-       'action '( Summon "unit-eye-of-vision" )

+       'action '(summon unit-type unit-eye-of-vision time-to-live 5000)

        'sound-when-cast "eye of vision"

        'missile-when-cast "missile-normal-spell"

        'autocast '(range 6)

@@ -153,7 +153,7 @@
        'manacost 50

        'range  6

        'target 'unit

-       'action '( haste (haste 1000 slow 0) )

+       'action '(adjust-buffs haste-ticks 1000 slow-ticks 0)

        'condition '(   UnitTypeflag (false building)

                        DurationEffect (false flag haste value 900) ;; haste < 
900 / CYCLE_PER_SECOND

                        Alliance true

@@ -168,7 +168,7 @@
        'manacost 50

        'range  10

        'target 'unit

-       'action '( haste (slow 1000 haste 0) )

+       'action '(adjust-buffs slow-ticks 1000 haste-ticks 0)

        'condition '(   UnitTypeflag (false building)

                        DurationEffect (false flag slow value 900) ;; slow < 
900 / CYCLE_PER_SECOND

                        Alliance true

@@ -183,7 +183,7 @@
        'manacost 50

        'range  6

        'target 'unit

-       'action '( haste (bloodlust 1000) )

+       'action '(adjust-buffs bloodlust-ticks 1000)

        'condition '(   UnitTypeflag (true organic)

                        DurationEffect (false flag bloodlust value 900) ;; 
bloodlust < 900 / CYCLE_PER_SECOND

                        Alliance true

@@ -198,7 +198,7 @@
        'manacost 200

        'range  6

        'target 'unit

-       'action '( Invisibility ( flag invisibility value 2000 missile 
"missile-explosion" ))

+       'action '(adjust-buffs invisibility-ticks 2000)

        'condition '(   UnitTypeflag (false building)

                        DurationEffect (false flag invisibility value 900) ;; 
invisibility < 900 / CYCLE_PER_SECOND

                        Alliance true

@@ -213,7 +213,7 @@
        'manacost 100

        'range  6

        'target 'unit

-       'action '( Invisibility ( flag unholyarmor value 500 missile 
"missile-explosion" ))

+       'action '(adjust-buffs invincibility-ticks 500)

        'condition '(UnitTypeflag (false building)

                        DurationEffect (false flag unholyarmor value 900) ;; 
unholyarmor < 900 / CYCLE_PER_SECOND

                        Alliance true

@@ -228,7 +228,7 @@
        'manacost 50

        'range  6

        'target 'unit

-       'action '( flame-shield (ttl 600))

+       'action '(flame-shield duration 600)

        'condition '(UnitTypeflag (false building)

                        DurationEffect (false flag flameshield value 500) ;; 
flameshield < 900 / CYCLE_PER_SECOND

 ;;                     Alliance false;; On which player (true own , false 
opponents)

@@ -243,7 +243,7 @@
        'manacost 200

        'range  10

        'target 'unit

-       'action '( Polymorph "unit-critter")

+       'action '(polymorph new-form unit-critter)

        'condition '(UnitTypeflag (true organic)

                        Alliance false

                        )

@@ -259,12 +259,12 @@
        'range  12

        'target 'position

        'action '(area-bombardment

-           (fields 5

+            fields 5

             shards 10

             damage 10

             ;;  128=4*32=4 tiles

             start-offset-x -128

-            start-offset-y -128))

+            start-offset-y -128)

        'sound-when-cast "blizzard"

        'missile-when-cast "missile-blizzard"

 ;;     'autocast '(range 12)

@@ -275,7 +275,7 @@
        'manacost 25

        'range  12

        'target 'position

-       'action '(area-bombardment (fields 5 shards 10 damage 10) )

+       'action '(area-bombardment fields 5 shards 10 damage 10)

        'sound-when-cast "death and decay"

        'missile-when-cast "missile-death-and-decay"

 ;;     'autocast '(range 12)

@@ -286,7 +286,7 @@
        'manacost 100

        'range  8

        'target 'position

-       'action '( fireball (ttl 1000 damage 20))

+       'action '(fireball ttl 1000 damage 20)

        'sound-when-cast "fireball throw"

        'missile-when-cast "missile-fireball"

 ;;     'autocast '(range 8)

@@ -297,7 +297,7 @@
        'manacost 200

        'range  10

        'target 'position

-       'action '( Runes (ttl 2000 damage 50))

+       'action '(runes ttl 2000 damage 50)

        'sound-when-cast "runes"

        'missile-when-cast "missile-rune"

 ;;     'autocast '(range 10)

@@ -308,11 +308,11 @@
        'manacost 100

        'range  10

        'target 'position ;; FIXME position or organic target

-       'action '( death-coil )

-;;     'condition '(UnitTypeflag (true organic))

+       'action '(fireball ttl 10000 damage 10000 )

+;      'condition '(UnitTypeflag (true organic))

        'sound-when-cast "death coil"

        'missile-when-cast "missile-death-coil"

-;;     'autocast '(range 6)

+;      'autocast '(range 6)

 )

 

 (define-spell "spell-raise-dead"

@@ -320,7 +320,7 @@
        'manacost 50

        'range  6

        'target 'none

-       'action '( RaiseDead "unit-skeleton" )

+       'action '(raise-dead unit-raised unit-skeleton time-to-live 100)

        'sound-when-cast "raise dead"

        'missile-when-cast "missile-normal-spell"

 ;;     'autocast '(range 6)

@@ -331,7 +331,7 @@
        'manacost 100

        'range  12

        'target 'position

-       'action '( Whirlwind (ttl 801)) ; TODO damage1 4 damage2 1

+       'action '(whirlwind duration 801) ; TODO damage1 4 damage2 1

        'sound-when-cast "whirlwind"

        'missile-when-cast "missile-whirlwind"

 ;;     'autocast '(range 12)

@@ -342,7 +342,7 @@
        'manacost 25

        'range  -1

        'target 'position

-       'action '( spawn-portal "unit-circle-of-power" )

+       'action '(spawn-portal portal-type unit-circle-of-power)

        'sound-when-cast "circle of power"

        'missile-when-cast "missile-normal-spell"

 ;;     'autocast '(range -1)

Index: stratagus/data/ccl/stratagus.ccl
diff -u stratagus/data/ccl/stratagus.ccl:1.17 
stratagus/data/ccl/stratagus.ccl:1.18
--- stratagus/data/ccl/stratagus.ccl:1.17       Sat Sep 27 02:16:36 2003
+++ stratagus/data/ccl/stratagus.ccl    Sat Sep 27 15:05:47 2003
@@ -26,7 +26,7 @@
 ;;      along with this program; if not, write to the Free Software
 ;;      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  
USA
 ;;
-;;     $Id: stratagus.ccl,v 1.17 2003/09/27 06:16:36 mr-russ Exp $
+;;     $Id: stratagus.ccl,v 1.18 2003/09/27 19:05:47 n0body Exp $
 
 ;; For documentation see stratagus/doc/ccl/ccl.html
 
@@ -229,10 +229,6 @@
 ;;     (Auf allgemeinen Wunsch eines einzelnen Herrn :)
 (set-forest-regeneration! 0)
 ;(set-forest-regeneration! 5)
-
-;;     Set depleted % for gold-mines. (n percent, 0 = disabled)
-(set-goldmine-depleted! 0)
-;(set-goldmine-depleted! 5)
 
 ;;     Set burning building percent and rate. (n percent, h HP/second)
 ;;     Buildings with less than n% HP lose h HP every wait cycles.
Index: stratagus/src/clone/ccl_spell.c
diff -u stratagus/src/clone/ccl_spell.c:1.6 stratagus/src/clone/ccl_spell.c:1.7
--- stratagus/src/clone/ccl_spell.c:1.6 Fri Sep 26 14:46:28 2003
+++ stratagus/src/clone/ccl_spell.c     Sat Sep 27 15:05:47 2003
@@ -26,7 +26,7 @@
 //      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 $
+//     $Id: ccl_spell.c,v 1.7 2003/09/27 19:05:47 n0body Exp $
 //@{
 
 /*----------------------------------------------------------------------------
@@ -46,15 +46,6 @@
 #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
 // **************************************************************************
@@ -101,422 +92,232 @@
 // **************************************************************************
 
 /**
-**     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
+**     Parse the action for spell.
+**     list = (action-type lots-of-parameters).
 */
-local char CclSpellParseActionFlameShield(const char *spellname, SCM list,
-    SpellActionType *spellaction)
+local void CclParseSpellAction(SCM list, SpellType* spell, 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;
-}
+    char* str;
+    
+    DebugCheck (spellaction == NULL);
 
-/**
-**     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;
+    SCM        value = list;
+    value = gh_car(value);
 
-    DebugCheck(!spellname);
-    DebugCheck(!spellaction);
+    value=gh_car(list);
+    list=gh_cdr(list);
 
-    lasthaste = NULL;
-    newhaste = &spellaction->haste;
-    while(!gh_null_p(list)) {
-       if (lasthaste != NULL) {
-           newhaste = malloc(sizeof(*newhaste));
-           memset(newhaste, 0, sizeof(*newhaste));
+    memset(spellaction, 0, sizeof(*spellaction));
+    if (gh_eq_p(value,gh_symbol2scm("area-bombardment"))) {
+       spell->CastFunction=CastAreaBombardment;
+       while (!gh_null_p(list)) {
+           value = gh_car(list);
+           list=gh_cdr(list);
+           if (gh_eq_p(value, gh_symbol2scm("fields"))) {
+               spellaction->AreaBombardment.Fields = gh_scm2int(gh_car(list));
+               list = gh_cdr(list);
+           } else if (gh_eq_p(value, gh_symbol2scm("shards"))) {
+               spellaction->AreaBombardment.Shards = gh_scm2int(gh_car(list));
+               list = gh_cdr(list);
+           } else if (gh_eq_p(value, gh_symbol2scm("damage"))) {
+               spellaction->AreaBombardment.Damage = gh_scm2int(gh_car(list));
+               list = gh_cdr(list);
+           } else if (gh_eq_p(value, gh_symbol2scm("start-offset-x"))) {
+               spellaction->AreaBombardment.StartOffsetX = 
gh_scm2int(gh_car(list));
+               list = gh_cdr(list);
+           } else if (gh_eq_p(value, gh_symbol2scm("start-offset-y"))) {
+               spellaction->AreaBombardment.StartOffsetY = 
gh_scm2int(gh_car(list));
+               list = gh_cdr(list);
+           } else {
+               errl("Unsupported area-bombardment tag",value);
+           }
        }
-       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));
+    } else if (gh_eq_p(value,gh_symbol2scm("flame-shield"))) {
+       spell->CastFunction=CastFlameShield;
+       while (!gh_null_p(list)) {
+           value = gh_car(list);
+           list=gh_cdr(list);
+           if (gh_eq_p(value, gh_symbol2scm("duration"))) {
+               spellaction->FlameShield.TTL = gh_scm2int(gh_car(list));
                list = gh_cdr(list);
-               newhaste->next = NULL;
-               break;
+               /// FIXME:damage, missiles, rotation speed?
+           } else {
+               errl("Unsupported flame-shield tag",value);
            }
        }
-       if (parser[i].id == NULL) {
-           DebugLevel0Fn("FIXME : better WARNING : unknow tag");
-           // FIXME : free correctly.
-           return 0;
+    } else if (gh_eq_p(value,gh_symbol2scm("fireball"))) {
+       spell->CastFunction=CastFireball;
+       while (!gh_null_p(list)) {
+           value = gh_car(list);
+           list=gh_cdr(list);
+           if (gh_eq_p(value, gh_symbol2scm("damage"))) {
+               spellaction->Fireball.Damage = gh_scm2int(gh_car(list));
+               list = gh_cdr(list);
+           } else if (gh_eq_p(value, gh_symbol2scm("ttl"))) {
+               spellaction->Fireball.TTL = gh_scm2int(gh_car(list));
+               list = gh_cdr(list);
+           } else {
+               errl("Unsupported fireball tag",value);
+           }
        }
-       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;
+    } else if (gh_eq_p(value,gh_symbol2scm("runes"))) {
+       spell->CastFunction=CastRunes;
+       while (!gh_null_p(list)) {
+           value = gh_car(list);
+           list=gh_cdr(list);
+           if (gh_eq_p(value, gh_symbol2scm("damage"))) {
+               spellaction->Fireball.Damage = gh_scm2int(gh_car(list));
+               list = gh_cdr(list);
+           } else if (gh_eq_p(value, gh_symbol2scm("ttl"))) {
+               spellaction->Fireball.TTL = gh_scm2int(gh_car(list));
+               list = gh_cdr(list);
+           } else {
+               errl("Unsupported runes tag",value);
+           }
        }
-       if (lasthaste != NULL) {
-           lasthaste->next = newhaste;
+    } else if (gh_eq_p(value,gh_symbol2scm("whirlwind"))) {
+       spell->CastFunction=CastWhirlwind;
+       while (!gh_null_p(list)) {
+           value = gh_car(list);
+           list=gh_cdr(list);
+           if (gh_eq_p(value, gh_symbol2scm("duration"))) {
+               spellaction->Whirlwind.TTL = gh_scm2int(gh_car(list));
+               list = gh_cdr(list);
+           } else {
+               errl("Unsupported runes tag",value);
+           }
        }
-       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;
+    } else if (gh_eq_p(value,gh_symbol2scm("adjust-buffs"))) {
+       spell->CastFunction=CastAdjustBuffs;
+       spellaction->AdjustBuffs.HasteTicks=BUFF_NOT_AFFECTED;
+       spellaction->AdjustBuffs.SlowTicks=BUFF_NOT_AFFECTED;
+       spellaction->AdjustBuffs.BloodlustTicks=BUFF_NOT_AFFECTED;
+       spellaction->AdjustBuffs.InvisibilityTicks=BUFF_NOT_AFFECTED;
+       spellaction->AdjustBuffs.InvincibilityTicks=BUFF_NOT_AFFECTED;
+       while (!gh_null_p(list)) {
+           value = gh_car(list);
+           list=gh_cdr(list);
+           if (gh_eq_p(value, gh_symbol2scm("haste-ticks"))) {
+               spellaction->AdjustBuffs.HasteTicks = gh_scm2int(gh_car(list));
+               list = gh_cdr(list);
+           } else if (gh_eq_p(value, gh_symbol2scm("slow-ticks"))) {
+               spellaction->AdjustBuffs.SlowTicks  = gh_scm2int(gh_car(list));
+               list = gh_cdr(list);
+           } else if (gh_eq_p(value, gh_symbol2scm("bloodlust-ticks"))) {
+               spellaction->AdjustBuffs.BloodlustTicks  = 
gh_scm2int(gh_car(list));
+               list = gh_cdr(list);
+           } else if (gh_eq_p(value, gh_symbol2scm("invisibility-ticks"))) {
+               spellaction->AdjustBuffs.InvisibilityTicks  = 
gh_scm2int(gh_car(list));
+               list = gh_cdr(list);
+           } else if (gh_eq_p(value, gh_symbol2scm("invincibility-ticks"))) {
+               spellaction->AdjustBuffs.InvincibilityTicks  = 
gh_scm2int(gh_car(list));
+               list = gh_cdr(list);
+           } else {
+               errl("Unsupported adjust-buffs tag",value);
+           }
        }
-       // 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"))) {
+    } else if (gh_eq_p(value,gh_symbol2scm("summon"))) {
+       spell->CastFunction=CastSummon;
+       while (!gh_null_p(list)) {
            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;
+           list = gh_cdr(list);
+           if (gh_eq_p(value, gh_symbol2scm("unit-type"))) {
+               str = gh_scm2newstr(gh_car(list),0);
+               spellaction->Summon.UnitType = UnitTypeByIdent(str);
+               if (!spellaction->Summon.UnitType) {
+                   spellaction->Summon.UnitType = 0;
+                   DebugLevel0("unit type \"%s\" not found for summon 
spell.\n" _C_ str);
                }
+               free(str);
+               list = gh_cdr(list);
+           } else if (gh_eq_p(value, gh_symbol2scm("time-to-live"))) {
+               spellaction->Summon.TTL = gh_scm2int(gh_car(list));
+               list = gh_cdr(list);
+           } else {
+               errl("Unsupported summon tag",value);
            }
-           continue;
        }
-       if (gh_eq_p(value, gh_symbol2scm("value"))) {
-               sec = gh_scm2int(gh_car(list));
-               continue;
+    } else if (gh_eq_p(value,gh_symbol2scm("spawn-portal"))) {
+       spell->CastFunction=CastSpawnPortal;
+       while (!gh_null_p(list)) {
+           value = gh_car(list);
+           list = gh_cdr(list);
+           if (gh_eq_p(value, gh_symbol2scm("portal-type"))) {
+               str = gh_scm2newstr(gh_car(list),0);
+               spellaction->SpawnPortal.PortalType = UnitTypeByIdent(str);
+               if (!spellaction->SpawnPortal.PortalType) {
+                   spellaction->SpawnPortal.PortalType = 0;
+                   DebugLevel0("unit type \"%s\" not found for 
spawn-portal.\n" _C_ str);
+               }
+               free(str);
+               list = gh_cdr(list);
+           } else {
+               errl("Unsupported spawn-portal tag",value);
+           }
        }
-       if (gh_eq_p(value, gh_symbol2scm("missile"))) {
-           if (missilename != NULL) {
-               free(missilename);
+    } else if (gh_eq_p(value,gh_symbol2scm("raise-dead"))) {
+       spell->CastFunction=CastRaiseDead;
+       while (!gh_null_p(list)) {
+           value = gh_car(list);
+           list = gh_cdr(list);
+           if (gh_eq_p(value, gh_symbol2scm("unit-raised"))) {
+               str = gh_scm2newstr(gh_car(list),0);
+               spellaction->RaiseDead.UnitRaised = UnitTypeByIdent(str);
+               if (!spellaction->RaiseDead.UnitRaised) {
+                   spellaction->RaiseDead.UnitRaised = 0;
+                   DebugLevel0("unit type \"%s\" not found for summon 
spell.\n" _C_ str);
+               }
+               free(str);
+               list = gh_cdr(list);
+           } else if (gh_eq_p(value, gh_symbol2scm("time-to-live"))) {
+               spellaction->RaiseDead.TTL = gh_scm2int(gh_car(list));
+               list = gh_cdr(list);
+           } else {
+               errl("Unsupported raise-dead tag",value);
            }
-           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;
+    } else if (gh_eq_p(value,gh_symbol2scm("polymorph"))) {
+       spell->CastFunction=CastPolymorph;
+       while (!gh_null_p(list)) {
+           value = gh_car(list);
+           list = gh_cdr(list);
+           if (gh_eq_p(value, gh_symbol2scm("new-form"))) {
+               str = gh_scm2newstr(gh_car(list),0);
+               spellaction->Summon.UnitType = UnitTypeByIdent(str);
+               if (!spellaction->Summon.UnitType) {
+                   spellaction->Summon.UnitType = 0;
+                   DebugLevel0("unit type \"%s\" not found for summon 
spell.\n" _C_ str);
                }
+               free(str);
+               list = gh_cdr(list);
+               //FIXME : temp polymorphs? hard to do.
+           } else {
+               errl("Unsupported polymorph tag",value);
            }
-           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);
+    } else if (gh_eq_p(value,gh_symbol2scm("adjust-vitals"))) {
+       spell->CastFunction=CastAdjustVitals;
+       while (!gh_null_p(list)) {
+           value = gh_car(list);
+           list=gh_cdr(list);
+           if (gh_eq_p(value, gh_symbol2scm("hit-points"))) {
+               spellaction->AdjustVitals.HP = gh_scm2int(gh_car(list));
+               list = gh_cdr(list);
+           } else if (gh_eq_p(value, gh_symbol2scm("mana-points"))) {
+               spellaction->AdjustVitals.Mana = gh_scm2int(gh_car(list));
+               list = gh_cdr(list);
+           } else if (gh_eq_p(value, gh_symbol2scm("max-multi-cast"))) {
+               spellaction->AdjustVitals.MaxMultiCast = 
gh_scm2int(gh_car(list));
+               list = gh_cdr(list);
+           } else {
+               errl("Unsupported adjust-vitals tag",value);
+           }
+       }
+    } else {
+       errl("Unsupported action type", value);
     }
 }
 
-
 // **************************************************************************
 //             Generic condition parsers for autocast for spell.
 // **************************************************************************
@@ -917,7 +718,8 @@
            }
            list=gh_cdr(list);
        } else if (gh_eq_p(value,gh_symbol2scm("action"))) {
-           ccl_spell_action("action",gh_car(list),spell);
+           
spell->SpellAction=(SpellActionType*)malloc(sizeof(SpellActionType));
+           CclParseSpellAction(gh_car(list),spell,spell->SpellAction);
            list=gh_cdr(list);
        } else if (gh_eq_p(value,gh_symbol2scm("condition"))) {
            ccl_spell_condition("condition",gh_car(list),spell);
@@ -972,7 +774,6 @@
 global void SaveSpells(CLFile *file)
 {
     SpellType *spell;
-    struct s_haste *hinfo;
 
     DebugCheck(!file);
     
@@ -1016,92 +817,74 @@
        //  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",
+       if (spell->CastFunction==CastAreaBombardment) {
+           CLprintf(file," '(area-bombardment fields %d shards %d damage %d 
start-offset-x %d start-offset-y %d)\n",
                    spell->SpellAction->AreaBombardment.Fields,
                    spell->SpellAction->AreaBombardment.Shards,
                    spell->SpellAction->AreaBombardment.Damage,
                    spell->SpellAction->AreaBombardment.StartOffsetX,
                    spell->SpellAction->AreaBombardment.StartOffsetY);
-       } else if (spell->f==CastFireball) {
-           CLprintf(file," '(fireball (ttl %d damage %d) )\n",
+       } else if (spell->CastFunction==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",
+       } else if (spell->CastFunction==CastAdjustVitals) {
+           CLprintf(file," '(adjust-vitals");
+           if (spell->SpellAction->AdjustVitals.HP) {
+               CLprintf(file," hit-points 
%d",spell->SpellAction->AdjustVitals.HP);
+           }
+           if (spell->SpellAction->AdjustVitals.Mana) {
+               CLprintf(file," mana-points 
%d",spell->SpellAction->AdjustVitals.Mana);
+           }
+           if (spell->SpellAction->AdjustVitals.MaxMultiCast) {
+               CLprintf(file," max-multi-cast 
%d",spell->SpellAction->AdjustVitals.MaxMultiCast);
+           }
+           CLprintf(file,")\n");
+       } else if (spell->CastFunction==CastSummon) {
+           CLprintf(file," '(summon unit-type %s time-to-live %d)\n",
+                   spell->SpellAction->Summon.UnitType->Ident,
+                   spell->SpellAction->Summon.TTL);
+       } else if (spell->CastFunction==CastAdjustBuffs) {
+           CLprintf(file," '(adjust-buffs");
+           if (spell->SpellAction->AdjustBuffs.HasteTicks!=BUFF_NOT_AFFECTED) {
+               CLprintf(file," haste-ticks 
%d",spell->SpellAction->AdjustBuffs.HasteTicks);
+           }
+           if (spell->SpellAction->AdjustBuffs.SlowTicks!=BUFF_NOT_AFFECTED) {
+               CLprintf(file," slow-ticks 
%d",spell->SpellAction->AdjustBuffs.SlowTicks);
+           }
+           if 
(spell->SpellAction->AdjustBuffs.BloodlustTicks!=BUFF_NOT_AFFECTED) {
+               CLprintf(file," bloodlust-ticks 
%d",spell->SpellAction->AdjustBuffs.BloodlustTicks);
+           }
+           if 
(spell->SpellAction->AdjustBuffs.InvisibilityTicks!=BUFF_NOT_AFFECTED) {
+               CLprintf(file," invisibility-ticks 
%d",spell->SpellAction->AdjustBuffs.InvisibilityTicks);
+           }
+           if 
(spell->SpellAction->AdjustBuffs.InvincibilityTicks!=BUFF_NOT_AFFECTED) {
+               CLprintf(file," invincibility-ticks 
%d",spell->SpellAction->AdjustBuffs.InvincibilityTicks);
+           }
+           CLprintf(file,")\n");
+       } else if (spell->CastFunction==CastPolymorph) {
+           CLprintf(file," '(polymorph new-form %s)\n",
                    spell->SpellAction->Polymorph.NewForm->Ident);
-       } else if (spell->f==CastRaiseDead) {
-           CLprintf(file," '(RaiseDead \"%s\")\n",
-                   spell->SpellAction->RaiseDead.Skeleton->Ident);
-       } else if (spell->f==CastFlameShield) {
-           CLprintf(file," '(flame-shield (ttl %d) )\n",
+       } else if (spell->CastFunction==CastRaiseDead) {
+           CLprintf(file," '(raise-dead unit-raised %s time-to-live %d)\n",
+                   spell->SpellAction->RaiseDead.UnitRaised->Ident,
+                   spell->SpellAction->RaiseDead.TTL);
+       } else if (spell->CastFunction==CastFlameShield) {
+           CLprintf(file," '(flame-shield duration %d)\n",
                    spell->SpellAction->FlameShield.TTL);
-       } else if (spell->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",
+       } else if (spell->CastFunction==CastRunes) {
+           CLprintf(file," '(runes ttl %d damage %d)\n",
+                   spell->SpellAction->Runes.TTL,
+                   spell->SpellAction->Runes.Damage);
+       } else if (spell->CastFunction==CastSpawnPortal) {
+           CLprintf(file," '(spawn-portal portal-type %s)\n",
                    spell->SpellAction->SpawnPortal.PortalType->Ident);
-       } else if (spell->f==CastDeathCoil) {
+       } else if (spell->CastFunction==CastDeathCoil) {
            CLprintf(file," '(death-coil)\n");
            // FIXME: more?
-       } else if (spell->f==CastWhirlwind) {
-           CLprintf(file," '(Whirlwind (ttl %d) )\n",
-                   spell->SpellAction->whirlwind.TTL);
+       } else if (spell->CastFunction==CastWhirlwind) {
+           CLprintf(file," '(whirlwind duration %d)\n",
+                   spell->SpellAction->Whirlwind.TTL);
            // FIXME: more?
        } 
        //
Index: stratagus/src/clone/clone.c
diff -u stratagus/src/clone/clone.c:1.204 stratagus/src/clone/clone.c:1.205
--- stratagus/src/clone/clone.c:1.204   Thu Sep 25 02:58:36 2003
+++ stratagus/src/clone/clone.c Sat Sep 27 15:05:47 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: clone.c,v 1.204 2003/09/25 06:58:36 mr-russ Exp $
+//     $Id: clone.c,v 1.205 2003/09/27 19:05:47 n0body Exp $
 
 //@{
 
@@ -249,9 +249,6 @@
     "Stratagus V" VERSION ", (c) 1998-2003 by The Stratagus Project.";
 
 local char* MapName;                   /// Filename of the map to load
-
-    //FIXME: all game global options should be moved in structure like `TheUI'
-global int OptionUseDepletedMines;     /// Use depleted mines or destroy them
 
 /*----------------------------------------------------------------------------
 --     Speedups FIXME: Move to some other more logic place
Index: stratagus/src/clone/spells.c
diff -u stratagus/src/clone/spells.c:1.101 stratagus/src/clone/spells.c:1.102
--- stratagus/src/clone/spells.c:1.101  Fri Sep 26 14:46:28 2003
+++ stratagus/src/clone/spells.c        Sat Sep 27 15:05:47 2003
@@ -27,7 +27,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: spells.c,v 1.101 2003/09/26 18:46:28 jsalmon3 Exp $
+//     $Id: spells.c,v 1.102 2003/09/27 19:05:47 n0body Exp $
 
 /*
 **     And when we cast our final spell
@@ -480,7 +480,7 @@
 //   original: launches 50 shards at 5 random spots x 10 for 25 mana.
 
 /**
-**     Cast blizzard.
+**     Cast area bombardment.
 **
 **     @param caster   Unit that casts the spell
 **     @param spell    Spell-type pointer
@@ -695,11 +695,9 @@
 **
 **     @return         =!0 if spell should be repeated, 0 if not
 */
-global int CastHaste(Unit *caster, const SpellType *spell, Unit *target,
+global int CastAdjustBuffs(Unit *caster, const SpellType *spell, Unit *target,
     int x, int y)
 {
-    struct s_haste *haste;
-
     DebugCheck(!caster);
     DebugCheck(!spell);
     DebugCheck(!spell->SpellAction);
@@ -708,51 +706,20 @@
     // get mana cost
     caster->Mana -= spell->ManaCost;
 
-    for (haste = &spell->SpellAction->haste; haste != NULL; haste = 
haste->next) {
-       // FIXME modify unit (slow, bloodlust, ..) -> flag[] ?
-       switch (haste->flag) {
-           case flag_slow:
-               target->Slow = haste->value / CYCLES_PER_SECOND;
-               break;
-           case flag_haste:
-               target->Haste = haste->value / CYCLES_PER_SECOND;
-               break;
-           case flag_bloodlust:
-               target->Bloodlust = haste->value / CYCLES_PER_SECOND;
-               break;
-           case flag_HP:
-               target->HP = haste->value;
-               if (target->HP <= 0) {
-                   target->HP = 1; // could be to 0 ??
-               }
-               if (target->Stats->HitPoints < target->HP) {
-                   target->HP = target->Stats->HitPoints;
-               }
-               break;
-           case flag_Mana:
-               target->Mana = haste->value;
-               if (target->Type->_MaxMana < target->Mana) {// What is Maxmana 
per unit.
-                   target->Mana = target->Type->_MaxMana;
-               }
-               break;
-           case flag_HP_percent:
-               target->HP = target->HP * haste->value / 100;
-               if (target->HP < 0) {
-                   target->HP = 1; // could be to 0 ??
-               }
-               if (target->Stats->HitPoints < target->HP) {
-                   target->HP = target->Stats->HitPoints;
-               }
-               break;
-           case flag_Mana_percent:
-               target->Mana = target->Mana * haste->value / 100;
-               if (target->Type->_MaxMana < target->Mana) {// What is Maxmana 
per unit.
-                   target->Mana = target->Type->_MaxMana;
-               }
-               break;
-           default:
-               DebugCheck(1);
-       }
+    if (spell->SpellAction->AdjustBuffs.SlowTicks!=BUFF_NOT_AFFECTED) {
+       target->Haste=spell->SpellAction->AdjustBuffs.HasteTicks;
+    }
+    if (spell->SpellAction->AdjustBuffs.SlowTicks!=BUFF_NOT_AFFECTED) {
+       target->Slow=spell->SpellAction->AdjustBuffs.SlowTicks;
+    }
+    if (spell->SpellAction->AdjustBuffs.BloodlustTicks!=BUFF_NOT_AFFECTED) {
+       target->Bloodlust=spell->SpellAction->AdjustBuffs.BloodlustTicks;
+    }
+    if (spell->SpellAction->AdjustBuffs.InvisibilityTicks!=BUFF_NOT_AFFECTED) {
+       target->Invisible=spell->SpellAction->AdjustBuffs.InvisibilityTicks;
+    }
+    if (spell->SpellAction->AdjustBuffs.InvincibilityTicks!=BUFF_NOT_AFFECTED) 
{
+       target->UnholyArmor=spell->SpellAction->AdjustBuffs.InvincibilityTicks;
     }
     CheckUnitToBeDrawn(target);
     PlayGameSound(spell->SoundWhenCast.Sound,MaxSampleVolume);
@@ -773,50 +740,76 @@
 **
 **     @return         =!0 if spell should be repeated, 0 if not
 */
-global int CastHealing(Unit *caster, const SpellType *spell, Unit *target,
+global int CastAdjustVitals(Unit *caster, const SpellType *spell, Unit *target,
     int x, int y)
 {
-    int i;
+    int castcount;
     int diffHP;
     int diffMana;
     int hp;
     int mana;
+    int manacost;
 
     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));
-    // Stop when no mana or full HP
-    caster->Mana -= i * mana;
-    target->HP += i * hp;
+    hp = spell->SpellAction->AdjustVitals.HP;
+    mana = spell->SpellAction->AdjustVitals.Mana;
+    manacost = spell->ManaCost;
+
+    //  Healing and harming
+    if (hp>0) {
+       diffHP = target->Stats->HitPoints - target->HP;
+    } else {
+       diffHP = target->HP;
+    }
+    if (mana>0) {
+       diffMana = target->Type->_MaxMana - target->Mana;
+    } else {
+       diffMana = target->Mana;
+    }
+
+    //  When harming cast again to send the hp to negative values.
+    //  Carefull, a perfect 0 target hp kills too.
+    //  Avoid div by 0 errors too!
+    castcount=0;
+    if (hp) {
+       castcount=max(castcount,diffHP/abs(hp)+( ( (hp<0) && (diffHP%(-hp)>0) ) 
? 1 : 0));
+    }
+    if (mana) {
+       castcount=max(castcount,diffMana/abs(mana)+( ( (mana<0) && 
(diffMana%(-mana)>0) ) ? 1 : 0));
+    }
+    if (manacost) {
+       castcount=min(castcount,caster->Mana/manacost);
+    }
+    if (spell->SpellAction->AdjustVitals.MaxMultiCast) {
+       castcount=min(castcount,spell->SpellAction->AdjustVitals.MaxMultiCast);
+    }
 
+    DebugCheck(castcount<0);
+
+    DebugLevel0Fn("Used to have %d hp and %d mana.\n" _C_ target->HP _C_ 
target->Mana);
+
+    caster->Mana-=castcount*manacost;
     if (hp < 0) {
-#ifdef USE_HP_FOR_XP
-       caster->XP += i * hp;
-#endif
-       if (!target->HP) {
-           caster->Player->Score += target->Type->Points;
-           if (target->Type->Building) {
-               caster->Player->TotalRazings++;
-           } else {
-               caster->Player->TotalKills++;
-           }
-#ifndef USE_HP_FOR_XP
-           caster->XP += target->Type->Points;
-#endif
-           caster->Kills++;
-           LetUnitDie(target);
+       HitUnit(caster,target,castcount*hp);
+    } else {
+       target->HP += castcount * hp;
+       if (target->HP>target->Stats->HitPoints) {
+           target->HP=target->Stats->HitPoints;
        }
     }
+    target->Mana+=castcount*mana;
+    if (target->Mana<0) {
+       target->Mana=0;
+    }
+    if (target->Mana>target->Type->_MaxMana) {
+       target->Mana=target->Type->_MaxMana;
+    }
+
+    DebugLevel0Fn("Unit now has %d hp and %d mana.\n" _C_ target->HP _C_ 
target->Mana);
     PlayGameSound(spell->SoundWhenCast.Sound, MaxSampleVolume);
     MakeMissile(spell->Missile,
            x * TileSizeX + TileSizeX / 2, y * TileSizeY + TileSizeY / 2,
@@ -845,7 +838,7 @@
 
     caster->Mana -= spell->ManaCost;   // get mana cost
     // FIXME: compact with summon.
-    target = MakeUnit(spell->SpellAction->holyvision.revealer, caster->Player);
+    target = MakeUnit(spell->SpellAction->HolyVision.revealer, caster->Player);
     target->Orders[0].Action = UnitActionStill;
     target->HP = 0;
     target->X = x;
@@ -861,59 +854,6 @@
 }
 
 /**
-**     Cast invisibility. (or CastUnholyArmor)
-**
-**     @param caster   Unit that casts the spell
-**     @param spell    Spell-type pointer
-**     @param target   Target unit that spell is addressed to
-**     @param x        X coord of target spot when/if target does not exist
-**     @param y        Y coord of target spot when/if target does not exist
-**
-**     @return         =!0 if spell should be repeated, 0 if not
-*/
-global int CastInvisibility(Unit *caster, const SpellType *spell, Unit *target,
-    int x, int y)
-{
-    DebugCheck(!caster);
-    DebugCheck(!spell);
-    DebugCheck(!spell->SpellAction);
-    DebugCheck(!target);
-    DebugCheck(!spell->SpellAction->invisibility.missile);
-
-    // get mana cost
-    caster->Mana -= spell->ManaCost;
-    if (target->Type->Volatile) {
-       RemoveUnit(target,NULL);
-       UnitLost(target);
-       UnitClearOrders(target);
-       ReleaseUnit(target);
-       MakeMissile(spell->SpellAction->invisibility.missile,
-               x * TileSizeX + TileSizeX / 2, y * TileSizeY + TileSizeY / 2,
-               x * TileSizeX + TileSizeX / 2, y * TileSizeY + TileSizeY / 2);
-    } else {
-       switch (spell->SpellAction->invisibility.flag) {
-           case flag_invisibility:
-               target->Invisible = spell->SpellAction->invisibility.value;
-               target->Invisible /= CYCLES_PER_SECOND;
-               break;
-           case flag_unholyarmor:
-               target->UnholyArmor = spell->SpellAction->invisibility.value;
-               target->UnholyArmor /= CYCLES_PER_SECOND;
-               break;
-           default:
-               //  Something is WRONG!!!
-               DebugCheck(1);
-       }
-       CheckUnitToBeDrawn(target);
-    }
-    PlayGameSound(spell->SoundWhenCast.Sound,MaxSampleVolume);
-    MakeMissile(spell->Missile,
-           x * TileSizeX + TileSizeX / 2, y * TileSizeY + TileSizeY / 2,
-           x * TileSizeX + TileSizeX / 2, y * TileSizeY + TileSizeY / 2 );
-    return 0;
-}
-
-/**
 **     Cast polymorph.
 **
 **     @param caster   Unit that casts the spell
@@ -988,7 +928,7 @@
     DebugCheck(!spell->SpellAction);
 //  assert(x in range, y in range);
 
-    skeleton = spell->SpellAction->RaiseDead.Skeleton;
+    skeleton = spell->SpellAction->RaiseDead.UnitRaised;
     DebugCheck(!skeleton);
 
     corpses = &CorpseList;
@@ -1069,7 +1009,7 @@
                    y * TileSizeY + TileSizeY / 2,
                    x * TileSizeX + TileSizeX / 2,
                    y * TileSizeY + TileSizeY / 2);
-           mis->TTL = spell->SpellAction->runes.TTL;
+           mis->TTL = spell->SpellAction->Runes.TTL;
            mis->Controller = SpellRunesController;
            caster->Mana -= spell->ManaCost / 5;
        }
@@ -1091,12 +1031,14 @@
 global int CastSummon(Unit *caster, const SpellType *spell, Unit *target,
     int x, int y)
 {
+    int ttl;
+
     DebugCheck(!caster);
     DebugCheck(!spell);
     DebugCheck(!spell->SpellAction);
     DebugCheck(!spell->SpellAction->Summon.UnitType);
-//  assert(x in range, y in range);
 
+    ttl=spell->SpellAction->Summon.TTL;
     caster->Mana -= spell->ManaCost;
     // FIXME: johns: the unit is placed on the wrong position
     target = MakeUnit(spell->SpellAction->Summon.UnitType, caster->Player);
@@ -1105,7 +1047,11 @@
     DropOutOnSide(target, LookingW, 0, 0);
 
     // set life span
-    target->TTL = GameCycle + target->Type->DecayRate * 6 * CYCLES_PER_SECOND;
+    if (ttl) {
+       target->TTL=GameCycle+ttl;
+    } else {
+       target->TTL=GameCycle+target->Type->DecayRate * 6 * CYCLES_PER_SECOND;
+    }
     CheckUnitToBeDrawn(target);
 
     PlayGameSound(spell->SoundWhenCast.Sound,MaxSampleVolume);
@@ -1143,7 +1089,7 @@
     mis = MakeMissile(spell->Missile,
            x * TileSizeX + TileSizeX / 2, y * TileSizeY + TileSizeY / 2,
            x * TileSizeX + TileSizeX / 2, y * TileSizeY + TileSizeY / 2);
-    mis->TTL = spell->SpellAction->whirlwind.TTL;
+    mis->TTL = spell->SpellAction->Whirlwind.TTL;
     mis->Controller = SpellWhirlwindController;
     return 0;
 }
@@ -1681,7 +1627,7 @@
     int x, int y)
 {
     DebugCheck(!spell);
-    DebugCheck(!spell->f);
+    DebugCheck(!spell->CastFunction);
     DebugCheck(!caster);
     DebugCheck(!SpellIsAvailable(caster->Player, spell->Ident));
 
@@ -1695,7 +1641,7 @@
     }
     DebugLevel3Fn("Spell cast: (%s), %s -> %s (%d,%d)\n" _C_ spell->IdentName 
_C_
            unit->Type->Name _C_ target ? target->Type->Name : "none" _C_ x _C_ 
y);
-    return CanCastSpell(caster, spell, target, x, y) && spell->f(caster, 
spell, target, x, y);
+    return CanCastSpell(caster, spell, target, x, y) && 
spell->CastFunction(caster, spell, target, x, y);
 }
 
 
Index: stratagus/src/include/spells.h
diff -u stratagus/src/include/spells.h:1.24 stratagus/src/include/spells.h:1.25
--- stratagus/src/include/spells.h:1.24 Fri Sep 26 11:47:51 2003
+++ stratagus/src/include/spells.h      Sat Sep 27 15:05:47 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: spells.h,v 1.24 2003/09/26 15:47:51 n0body Exp $
+//     $Id: spells.h,v 1.25 2003/09/27 19:05:47 n0body Exp $
 
 #ifndef __SPELLS_H__
 #define __SPELLS_H__
@@ -119,25 +119,26 @@
        int TTL;                /// time to live (ticks)
     } FlameShield;
 
-    struct s_haste {
-       int flag;               /// flag for know what variable to set.
-       int value;              /// the set value. (nb sec).
-    struct s_haste *next;      /// Other variable to set ?
-    } haste;
-    
     struct {
-       int HP;                 /// HP gain for manacost.(negative for exorcism)
-    } healing;
+       int HasteTicks;         /// Number of ticks to set Haste to.
+       int SlowTicks;          /// Number of ticks to set Slow to.
+       int BloodlustTicks;     /// Number of ticks to set Bloodlust to.
+       int InvisibilityTicks;  /// Number of ticks to set Invisibility to.
+       int InvincibilityTicks; /// Number of ticks to set UnholyArmor to.
+#define BUFF_NOT_AFFECTED 0xC0FF33 /// Don't like the value? The value doesn't 
like you!
+    } AdjustBuffs;
     
     struct {
-       UnitType *revealer;     /// Type of unit to be summoned: 
(unit-revealer).
-    } holyvision;
+       int HP;                 /// Target HP gain.(can be negative)
+       int Mana;               /// Target Mana gain.(can be negative)
+       /// This spell is designed to be used wit very small amounts. The spell
+       /// can scale up to MaxMultiCast times. Use 0 for infinite.
+       int MaxMultiCast; 
+    } AdjustVitals;
     
     struct {
-       int flag;               /// unholyarmor or invisibility.
-       int value;              /// the set value. (nb sec).
-       MissileType *missile;   /// missile for the target.
-    } invisibility;
+       UnitType *revealer;     /// Type of unit to be summoned: 
(unit-revealer).
+    } HolyVision;
     
     struct {
        UnitType *NewForm;      /// The new form
@@ -150,7 +151,7 @@
     } Summon;
     
     struct {
-       UnitType *Skeleton;     /// The unit to spawn from corpses
+       UnitType *UnitRaised;   /// The unit to spawn from corpses
        int TTL;                /// Time to live for summon. 0 means infinite.
     } RaiseDead;
     //  What about a resurection spell?
@@ -158,12 +159,12 @@
     struct {
        int TTL;                /// time to live (ticks)
        int Damage;             /// Damage.
-    } runes;
+    } Runes;
     
     struct {
        int  TTL;               /// time to live (ticks)
        // FIXME: more configurations
-    } whirlwind;
+    } Whirlwind;
 } SpellActionType;
 
 /*
@@ -261,7 +262,7 @@
 
     // Spell Specifications
     TargetType Target;                 /// Targetting information. See 
TargetType.
-    SpellFunc *f;                              /// function to cast the spell.
+    SpellFunc *CastFunction;           /// function to cast the spell.
     SpellActionType *SpellAction;      /// More arguments for spell (damage, 
delay, additional sounds...).
     int Range;                         /// Max range of the target.
     int ManaCost;                      /// required mana for each cast
@@ -339,11 +340,10 @@
 */
 
 SpellFunc CastHolyVision;
-SpellFunc CastHealing;
-SpellFunc CastHaste;
+SpellFunc CastAdjustVitals;
+SpellFunc CastAdjustBuffs;
 SpellFunc CastFireball;
 SpellFunc CastFlameShield;
-SpellFunc CastInvisibility;
 SpellFunc CastPolymorph;
 SpellFunc CastAreaBombardment;
 SpellFunc CastSummon;
Index: stratagus/src/include/stratagus.h
diff -u stratagus/src/include/stratagus.h:1.15 
stratagus/src/include/stratagus.h:1.16
--- stratagus/src/include/stratagus.h:1.15      Sun Sep 21 06:03:56 2003
+++ stratagus/src/include/stratagus.h   Sat Sep 27 15:05:47 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: stratagus.h,v 1.15 2003/09/21 10:03:56 mr-russ Exp $
+//     $Id: stratagus.h,v 1.16 2003/09/27 19:05:47 n0body Exp $
 
 #ifndef __STRATAGUS_H__
 #define __STRATAGUS_H__
@@ -474,9 +474,6 @@
 extern int SpeedTrain;                 /// Speed factor for training
 extern int SpeedUpgrade;               /// Speed factor for upgrading
 extern int SpeedResearch;              /// Speed factor for researching
-
-    //FIXME: all game global options should be moved in structure like `TheUI'
-extern int OptionUseDepletedMines;      /// Use depleted mines or destroy them
 
 extern unsigned SyncRandSeed;          /// Sync random seed value
 
Index: stratagus/src/map/ccl_map.c
diff -u stratagus/src/map/ccl_map.c:1.39 stratagus/src/map/ccl_map.c:1.40
--- stratagus/src/map/ccl_map.c:1.39    Sat Sep 27 02:16:37 2003
+++ stratagus/src/map/ccl_map.c Sat Sep 27 15:05:47 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: ccl_map.c,v 1.39 2003/09/27 06:16:37 mr-russ Exp $
+//     $Id: ccl_map.c,v 1.40 2003/09/27 19:05:47 n0body Exp $
 
 //@{
 
@@ -478,30 +478,6 @@
 }
 
 /**
-**     Set gold-mine depleted rate.
-**
-**     @param rate     New depleted rate (0 disabled)
-**
-**     @return         Old rate
-*/
-local SCM CclSetGoldmineDepleted(SCM rate)
-{
-    int i;
-    int o;
-
-    i = gh_scm2int(rate);
-    if (i < 0 || i > 100) {
-       PrintFunction();
-       fprintf(stdout, "Deplated rate should be 0-100\n");
-       i = 0;
-    }
-    o = OptionUseDepletedMines;
-    OptionUseDepletedMines = i;
-
-    return gh_int2scm(o);
-}
-
-/**
 **     Set burning buildings percent and rate.
 **
 **     @param percent      Max percent needed to burn buildings
@@ -560,8 +536,7 @@
     gh_new_procedure1_0("set-fog-of-war-brightness!", 
CclSetFogOfWarBrightness);
     gh_new_procedure1_0("set-fog-of-war-saturation!", 
CclSetFogOfWarSaturation);
 
-    gh_new_procedure1_0("set-forest-regeneration!", CclSetForestRegeneration);
-    gh_new_procedure1_0("set-goldmine-depleted!", CclSetGoldmineDepleted);
+    gh_new_procedure1_0("set-forest-regeneration!",CclSetForestRegeneration);
 
     gh_new_procedure3_0("set-burn-buildings!", CclSetBurnBuildings);
 }




reply via email to

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