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 src/action/action...


From: Crestez Leonard
Subject: [Stratagus-CVS] stratagus data/ccl/spells.ccl src/action/action...
Date: Mon, 29 Sep 2003 13:04:15 -0400

CVSROOT:        /cvsroot/stratagus
Module name:    stratagus
Branch:         
Changes by:     Crestez Leonard <address@hidden>        03/09/29 13:04:15

Modified files:
        data/ccl       : spells.ccl 
        src/action     : action_spellcast.c actions.c 
        src/clone      : ccl_spell.c spells.c 
        src/include    : spells.h 

Log message:
        Lots of spell work. Rewrite conditions. Fix mana bug.

Patches:
Index: stratagus/data/ccl/spells.ccl
diff -u stratagus/data/ccl/spells.ccl:1.3 stratagus/data/ccl/spells.ccl:1.4
--- stratagus/data/ccl/spells.ccl:1.3   Sat Sep 27 15:05:47 2003
+++ stratagus/data/ccl/spells.ccl       Mon Sep 29 13:04:11 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.3 2003/09/27 19:05:47 n0body Exp $

+;;     $Id: spells.ccl,v 1.4 2003/09/29 17:04:11 n0body Exp $

 

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

 

@@ -95,12 +95,12 @@
 (define-spell "spell-holy-vision"

        'showname "Holy Vision"

        'manacost 70

-       'range  -1

+       'range 'infinite

        'target 'position

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

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

        'sound-when-cast "holy vision"

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

-       'autocast '(range -1)

+;      'autocast '(range -1)

 )

 

 (define-spell "spell-healing"

@@ -108,18 +108,23 @@
        'manacost 6

        'range  6

        'target 'unit

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

-       'condition '(   UnitTypeflag (true organic)

-                       UnitTypeflag (false building)

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

-                       Alliance true

-                       )

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

+       'condition '(

+           organic only

+           building false

+           max-hp-percent 100)

        'sound-when-cast "healing"

        'missile-when-cast "missile-heal-effect"

        'autocast '(range 6

-               condition (UnitTypeflag (false coward)

-                       )

-               )

+           condition (

+               coward false

+               alliance only

+               ;; 50% in battle, 100 while waiting? could be an idea

+               ;; This way we could stop healing all the time, just when an

+               ;; unit drops under 50 percent.

+               max-hp-percent 100

+           )

+       )

 )

 

 (define-spell "spell-exorcism"

@@ -128,13 +133,14 @@
        'range  10

        'target 'unit

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

-       'condition '(   UnitTypeflag (true undead)

-                       UnitTypeflag (false building)

-                       Alliance false

-                       )

+       'condition '(

+           undead only

+           building false ; any undead buildings?

+           alliance false

+       )

        'sound-when-cast "exorcism"

        'missile-when-cast "missile-exorcism"

-       'autocast '(range 10 condition (UnitTypeflag (false coward)))

+       'autocast '(range 10 condition (coward false alliance false))

 )

 

 (define-spell "spell-eye-of-vision"

@@ -154,13 +160,13 @@
        'range  6

        'target 'unit

        '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

-                       )

+       'condition '(

+           building false

+           max-haste-ticks 10 ;; FIXME: proper value?

+       )

        'sound-when-cast "haste"

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

-       'autocast '(range 6 condition (UnitTypeflag (false coward)))

+       'autocast '(range 6 condition (coward false alliance only))

 )

 

 (define-spell "spell-slow"

@@ -169,13 +175,12 @@
        'range  10

        'target 'unit

        '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

-                       )

+       'condition '(

+           building false

+           max-slow-ticks 10)

        'sound-when-cast "slow"

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

-       'autocast '(range 10 condition (UnitTypeflag (false coward)))

+       'autocast '(range 10 condition (coward false alliance only))

 )

 

 (define-spell "spell-bloodlust"

@@ -184,13 +189,12 @@
        'range  6

        'target 'unit

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

-       'condition '(   UnitTypeflag (true organic)

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

-                       Alliance true

-                       )

+       'condition '(

+           organic only

+           max-bloodlust-ticks 10)

        'sound-when-cast "bloodlust"

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

-       'autocast '(range 6 condition (UnitTypeflag (false coward)))

+       'autocast '(range 6 condition (coward false alliance only))

 )

 

 (define-spell "spell-invisibility"

@@ -199,13 +203,12 @@
        'range  6

        'target 'unit

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

-       'condition '(   UnitTypeflag (false building)

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

-                       Alliance true

-                       )

+       'condition '(

+           building false

+           max-invisibility-ticks 10)

        'sound-when-cast "invisibility"

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

-       'autocast '(range 6 condition (UnitTypeflag (false coward)))

+       'autocast '(range 6 condition (coward false))

 )

 

 (define-spell "spell-unholy-armor"

@@ -214,13 +217,12 @@
        'range  6

        'target 'unit

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

-       'condition '(UnitTypeflag (false building)

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

-                       Alliance true

-                       )

+       'condition '(

+           building false

+           max-invincibility-ticks 10)

        'sound-when-cast "unholyarmor"

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

-       'autocast '(range 6 condition (UnitTypeflag (false coward)))

+       'autocast '(range 6 condition (coward false alliance only))

 )

 

 (define-spell "spell-flame-shield"

@@ -229,13 +231,12 @@
        'range  6

        'target 'unit

        '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)

-                       );; FIXME

+       ;; I think it's better if we can cast it multiple times and the effects 
stack.

+       ;; Can be casted, and is effective on both allies and enemies

+       'condition '(building false)

        'sound-when-cast "flame shield"

        'missile-when-cast "missile-flame-shield" ; NOT use

-       'autocast '(range 6 condition (UnitTypeflag (false coward)))

+       'autocast '(range 6 condition (coward false))

 )

 

 (define-spell "spell-polymorph"

@@ -244,12 +245,11 @@
        'range  10

        'target 'unit

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

-       'condition '(UnitTypeflag (true organic)

-                       Alliance false

-                       )

+       'condition '(organic only)

        'sound-when-cast "polymorph"

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

-       'autocast '(range 10 condition (UnitTypeflag (false coward)))

+       ;;  Only cast on the strongest units!!!

+       'autocast '(range 10 condition (alliance false min-hp-percent 75))

 )

 

 

Index: stratagus/src/action/action_spellcast.c
diff -u stratagus/src/action/action_spellcast.c:1.32 
stratagus/src/action/action_spellcast.c:1.33
--- stratagus/src/action/action_spellcast.c:1.32        Sun Sep 14 00:45:52 2003
+++ stratagus/src/action/action_spellcast.c     Mon Sep 29 13:04:12 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: action_spellcast.c,v 1.32 2003/09/14 04:45:52 mr-russ Exp $
+//     $Id: action_spellcast.c,v 1.33 2003/09/29 17:04:12 n0body Exp $
 
 /*
 ** This is inherited from action_attack.c, actually spell casting will
@@ -208,12 +208,14 @@
            }
            return;
        }
+       // FIXME FIXME FIXME: Check if already in range and skip straight to 
2(casting)
        NewResetPath(unit);
        unit->Value=0;          // repeat spell on next pass? (defaults to `no')
        unit->SubAction=1;
        // FALL THROUGH
     case 1:                            // Move to the target.
-       if( (spell = unit->Orders[0].Arg1)->Range != 0x7F ) {
+       // FIXME: crashes with huge ranges.
+       if( (spell = unit->Orders[0].Arg1)->Range != INFINITE_RANGE ) {
            SpellMoveToTarget(unit);
            break;
        } else {
Index: stratagus/src/action/actions.c
diff -u stratagus/src/action/actions.c:1.94 stratagus/src/action/actions.c:1.95
--- stratagus/src/action/actions.c:1.94 Sat Sep 27 02:16:36 2003
+++ stratagus/src/action/actions.c      Mon Sep 29 13:04:13 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: actions.c,v 1.94 2003/09/27 06:16:36 mr-russ Exp $
+//     $Id: actions.c,v 1.95 2003/09/29 17:04:13 n0body Exp $
 
 //@{
 
@@ -353,7 +353,7 @@
     if( unit->TTL && unit->TTL<(GameCycle-unit->HP) ) {
        DebugLevel0Fn("Unit must die %lu %lu!\n" _C_ unit->TTL
                _C_ GameCycle);
-       if( !--unit->HP ) {
+       if( --unit->HP<0 ) {
            LetUnitDie(unit);
            deadunit|=1;
        }
@@ -585,10 +585,6 @@
            continue;
        }
 
-       if( --unit->Wait ) {            // Wait until counter reached
-           continue;
-       }
-
        if( blinkthiscycle && unit->Blink ) {   // clear blink flag
            --unit->Blink;
        }
@@ -609,6 +605,10 @@
        }
        if( burnthiscycle ) {
            BurnBuilding(unit);
+       }
+       
+       if( --unit->Wait ) {            // Wait until counter reached
+           continue;
        }
 
        HandleUnitAction(unit);
Index: stratagus/src/clone/ccl_spell.c
diff -u stratagus/src/clone/ccl_spell.c:1.8 stratagus/src/clone/ccl_spell.c:1.9
--- stratagus/src/clone/ccl_spell.c:1.8 Sat Sep 27 16:27:29 2003
+++ stratagus/src/clone/ccl_spell.c     Mon Sep 29 13:04:14 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: ccl_spell.c,v 1.8 2003/09/27 20:27:29 n0body Exp $
+//     $Id: ccl_spell.c,v 1.9 2003/09/29 17:04:14 n0body Exp $
 //@{
 
 /*----------------------------------------------------------------------------
@@ -318,314 +318,117 @@
     }
 }
 
-// **************************************************************************
-//             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
+**     Get a condition value from a scm object.
+**     
+**     @param  value           scm value to convert.
+**
+**     @return CONDITION_TRUE, CONDITION_FALSE, CONDITION_ONLY or -1 on error.
 */
-void ccl_alliance(const char *spellname, const char *id, SCM list,
-    t_Conditions **generic, t_Conditions **specific)
+local char Scm2Condition(SCM value)
 {
-    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 ;
+    if (gh_eq_p(value,gh_symbol2scm("true"))) {
+       return CONDITION_TRUE;
+    } else if (gh_eq_p(value,gh_symbol2scm("false"))) {
+       return CONDITION_FALSE;
+    } else if (gh_eq_p(value,gh_symbol2scm("only"))) {
+       return CONDITION_ONLY;
+    } else {
+       errl("Bad condition result",value);
+       return -1;
     }
-    cond->f.specific = CheckAllied;
-    pushback_condition(specific, cond);
 }
 
 /**
 **     Parse the Condition for spell.
+**     
+**     @param list             SCM object to parse
+**     @param condition        pointer to condition to fill with data.
+**
+**     @notes: conditions must be allocated. All data already in is LOST.
 */
-local void ccl_spell_all_condition(const char *spellname, const char *id,
-    SCM list, t_Conditions **generic, t_Conditions **specific)
+local void CclSpellParseCondition(SCM list, ConditionInfo* condition)
 {
-    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)) {
+    //
+    // Initializations:
+    //
+
+    // Set everything to 0:
+    memset(condition,0,sizeof(ConditionInfo));
+    // Flags are defaulted to 0(CONDITION_TRUE)
+
+    // Initialize min/max stuff to values with no effect.
+    condition->MinHpPercent=-10;
+    condition->MaxHpPercent=1000;
+    condition->MinManaPercent=-10;
+    condition->MaxManaPercent=1000;
+    //  Buffs too.
+    condition->MaxHasteTicks=0xFFFFFFF;
+    condition->MaxSlowTicks=0xFFFFFFF;
+    condition->MaxBloodlustTicks=0xFFFFFFF;
+    condition->MaxInvisibilityTicks=0xFFFFFFF;
+    condition->MaxInvincibilityTicks=0xFFFFFFF;
+    //  Now parse the list and set values.
+    while (!gh_null_p(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;
-           }
+       list = gh_cdr(list);
+       if (gh_eq_p(value,gh_symbol2scm("undead"))) {
+           condition->Undead=Scm2Condition(gh_car(list));
+           list=gh_cdr(list);
+       } else if (gh_eq_p(value,gh_symbol2scm("organic"))) {
+           condition->Organic=Scm2Condition(gh_car(list));
+           list=gh_cdr(list);
+       } else if (gh_eq_p(value,gh_symbol2scm("hero"))) {
+           condition->Hero=Scm2Condition(gh_car(list));
+           list=gh_cdr(list);
+       } else if (gh_eq_p(value,gh_symbol2scm("coward"))) {
+           condition->Coward=Scm2Condition(gh_car(list));
+           list=gh_cdr(list);
+       } else if (gh_eq_p(value,gh_symbol2scm("alliance"))) {
+           condition->Alliance=Scm2Condition(gh_car(list));
+           list=gh_cdr(list);
+       } else if (gh_eq_p(value,gh_symbol2scm("building"))) {
+           condition->Building=Scm2Condition(gh_car(list));
+           list=gh_cdr(list);
+       } else if (gh_eq_p(value,gh_symbol2scm("self"))) {
+           condition->TargetSelf=Scm2Condition(gh_car(list));
+           list=gh_cdr(list);
+       } else if (gh_eq_p(value,gh_symbol2scm("min-hp-percent"))) {
+           condition->MaxHpPercent=gh_scm2int(gh_car(list));
+           list=gh_cdr(list);
+       } else if (gh_eq_p(value,gh_symbol2scm("max-hp-percent"))) {
+           condition->MaxHpPercent=gh_scm2int(gh_car(list));
+           list=gh_cdr(list);
+       } else if (gh_eq_p(value,gh_symbol2scm("min-mana-percent"))) {
+           condition->MinManaPercent=gh_scm2int(gh_car(list));
+           list=gh_cdr(list);
+       } else if (gh_eq_p(value,gh_symbol2scm("max-mana-percent"))) {
+           condition->MaxManaPercent=gh_scm2int(gh_car(list));
+           list=gh_cdr(list);
+       } else if (gh_eq_p(value,gh_symbol2scm("max-slow-ticks"))) {
+           condition->MaxSlowTicks=gh_scm2int(gh_car(list));
+           list=gh_cdr(list);
+       } else if (gh_eq_p(value,gh_symbol2scm("max-haste-ticks"))) {
+           condition->MaxHasteTicks=gh_scm2int(gh_car(list));
+           list=gh_cdr(list);
+       } else if (gh_eq_p(value,gh_symbol2scm("max-bloodlust-ticks"))) {
+           condition->MaxBloodlustTicks=gh_scm2int(gh_car(list));
+           list=gh_cdr(list);
+       } else if (gh_eq_p(value,gh_symbol2scm("max-invisibility-ticks"))) {
+           condition->MaxInvisibilityTicks=gh_scm2int(gh_car(list));
+           list=gh_cdr(list);
+       } else if (gh_eq_p(value,gh_symbol2scm("max-invincibility-ticks"))) {
+           condition->MaxInvincibilityTicks=gh_scm2int(gh_car(list));
+           list=gh_cdr(list);
+       } else {
+           errl("Unsuported condition tag",value);
        }
-       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)
@@ -658,8 +461,8 @@
     }
     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);
+    spell->AutoCast->Condition=(ConditionInfo*)malloc(sizeof(ConditionInfo));
+    CclSpellParseCondition(value,spell->AutoCast->Condition);
 }
 
 /**
@@ -701,7 +504,11 @@
            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));
+           if (gh_eq_p(gh_car(list),gh_symbol2scm("infinite"))) {
+               spell->Range=INFINITE_RANGE;
+           } else {
+               spell->Range=gh_scm2int(gh_car(list));
+           }
            list=gh_cdr(list);
        } else if (gh_eq_p(value,gh_symbol2scm("target"))) {
            value=gh_car(list);
@@ -710,7 +517,7 @@
            } else if (gh_eq_p(value,gh_symbol2scm("self"))) {
                spell->Target=TargetSelf;
            } else if (gh_eq_p(value,gh_symbol2scm("unit"))) {
-               spell->Target=TargetSelf;
+               spell->Target=TargetUnit;
            } else if (gh_eq_p(value,gh_symbol2scm("position"))) {
                spell->Target=TargetPosition;
            } else {
@@ -722,7 +529,8 @@
            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);
+           spell->Conditions=(ConditionInfo*)malloc(sizeof(ConditionInfo));
+           CclSpellParseCondition(gh_car(list),spell->Conditions);
            list=gh_cdr(list);
        } else if (gh_eq_p(value,gh_symbol2scm("autocast"))) {
            ccl_spell_autocast("autocast",gh_car(list),spell);
Index: stratagus/src/clone/spells.c
diff -u stratagus/src/clone/spells.c:1.102 stratagus/src/clone/spells.c:1.103
--- stratagus/src/clone/spells.c:1.102  Sat Sep 27 15:05:47 2003
+++ stratagus/src/clone/spells.c        Mon Sep 29 13:04:14 2003
@@ -27,7 +27,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: spells.c,v 1.102 2003/09/27 19:05:47 n0body Exp $
+//     $Id: spells.c,v 1.103 2003/09/29 17:04:14 n0body Exp $
 
 /*
 **     And when we cast our final spell
@@ -846,6 +846,7 @@
 //    target->TTL = GameCycle + CYCLES_PER_SECOND + CYCLES_PER_SECOND / 2;
     target->CurrentSightRange = target->Stats->SightRange;
     target->Removed = 1;
+    target->CurrentSightRange = target->Stats->SightRange;
     MapMarkUnitSight(target);
     target->TTL = GameCycle + target->Type->DecayRate * 6 * CYCLES_PER_SECOND;
     CheckUnitToBeDrawn(target);
@@ -1038,21 +1039,31 @@
     DebugCheck(!spell->SpellAction);
     DebugCheck(!spell->SpellAction->Summon.UnitType);
 
+    DebugLevel0("Summoning\n");
     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);
     target->X = x;
     target->Y = y;
-    DropOutOnSide(target, LookingW, 0, 0);
-
     // set life span
     if (ttl) {
        target->TTL=GameCycle+ttl;
     } else {
        target->TTL=GameCycle+target->Type->DecayRate * 6 * CYCLES_PER_SECOND;
     }
-    CheckUnitToBeDrawn(target);
+    //
+    // Revealers are always removed, since they don't have graphics
+    //
+    if (target->Type->Revealer) {
+       DebugLevel0Fn("new unit is a revealer, removed.\n");
+       target->Removed=1;
+       target->CurrentSightRange = target->Stats->SightRange;
+       MapMarkUnitSight(target);
+    } else {
+       DropOutOnSide(target, LookingW, 0, 0);
+       CheckUnitToBeDrawn(target);
+    }
 
     PlayGameSound(spell->SoundWhenCast.Sound,MaxSampleVolume);
     MakeMissile(spell->Missile,
@@ -1095,137 +1106,6 @@
 }
 
 // ****************************************************************************
-//     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)
-{
-    DebugCheck(!caster);
-    DebugCheck(!condition);
-
-    if (target == NULL) {
-       return !condition->expectvalue;
-    }
-    // FIXME Modify unit struture for an array of boolean ?
-    switch (condition->u.flag) {
-       case flag_coward:
-           return target->Type->Coward;
-       case flag_organic:
-           return target->Type->Organic;
-       case flag_isundead:
-           return target->Type->IsUndead;
-       case flag_canattack:
-           return target->Type->CanAttack;
-       case flag_building:
-           return target->Type->Building;
-       default:
-           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)
-{
-    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)
-{
-    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)
-{
-    int ttl;
-
-    DebugCheck(!condition);
-
-    ttl = condition->u.durationeffect.ttl;
-
-    if (target == NULL) {
-       return !condition->expectvalue;
-    }
-
-    switch (condition->u.durationeffect.flag) {
-       case flag_invisibility:
-           return (target->Invisible >= ttl / CYCLES_PER_SECOND);
-       case flag_bloodlust:
-           return (target->Bloodlust >= ttl / CYCLES_PER_SECOND);
-       case flag_slow:
-           return (target->Slow >= ttl / CYCLES_PER_SECOND);
-       case flag_haste:
-           return (target->Haste >= ttl / CYCLES_PER_SECOND);
-       case flag_unholyarmor:
-           return (target->UnholyArmor >= ttl / CYCLES_PER_SECOND);
-       case flag_flameshield:
-           return (target->FlameShield >= ttl);
-       case flag_HP:
-           return (target->HP >= ttl);
-       case flag_Mana:
-           return (target->Mana >= ttl);
-       case flag_HP_percent:
-           return (target->HP * 100 >= ttl * target->Stats->HitPoints); // 
FIXME
-       case flag_Mana_percent:
-           return (target->Mana * 100 >= ttl * target->Type->_MaxMana); // 
FIXME : MaxMana.
-       /// Add here the other cases
-       default:
-           DebugCheck(1);
-           return !condition->expectvalue;
-    }
-}
-
-// ****************************************************************************
-//     Specific conditions
-// ****************************************************************************
-
-/**
-**     FIXME: docu
-*/
-global int CheckEnemyPresence(const t_Conditions *condition, const Unit 
*caster)
-{
-    Unit *table[UnitMax];
-    int i;
-    int n;
-    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])) {
-           return 1;
-       }
-    }
-    return 0;
-}
-
-// ****************************************************************************
 // Target constructor
 // ****************************************************************************
 
@@ -1281,61 +1161,98 @@
 //     Main local functions
 // ****************************************************************************
 
-/**
-**     Check all generic conditions.
+/*
+**     Check the condition.
+**
+**     @param caster           Pointer to caster unit.
+**     @param spell            Pointer to the spell to cast.
+**     @param target           Pointer to target unit, or 0 if it is a 
position spell.
+**     @param x                X position, or -1 if it is an unit spell.
+**     @param y                Y position, or -1 if it is an unit spell.
+**     @param condition        Pointer to condition info.
+**
+**     @return 1 if passed, 0 otherwise.
 */
-local int PassGenericCondition(const Unit *caster, const SpellType *spell,
-    const t_Conditions *condition)
+local int PassCondition(const Unit* caster,const SpellType* spell,const Unit* 
target,
+       int x,int y,const ConditionInfo* condition)
 {
-    int ret;
-
-    DebugCheck(!caster);
-    DebugCheck(!spell);
-
-    // FIXME : Move it in spell->Condition_generic ???
-    // mana is a must!
-    if (caster->Mana < spell->ManaCost) {
+    //
+    // Check caster mana. FIXME: move somewhere else?
+    //
+    if (caster->Mana<spell->ManaCost) {
+       return 0;
+    }
+    //
+    // Casting an unit spell without a target. 
+    //
+    if (spell->Target==TargetUnit&&!target) {
        return 0;
     }
-    /*condition = spell->Condition_generic*/
-    for (; condition != NULL; condition = condition->next) {
-       DebugCheck(!condition->f.generic);
-       ret = condition->f.generic(condition, caster);
-       DebugCheck(!(ret == 0 || ret == 1));
-       DebugCheck(!(condition->expectvalue == 0 || condition->expectvalue == 
1));
-       if (ret != condition->expectvalue) {
+    if (!condition) {
+       // no condition, pass.
+       return 1;
+    }
+    //
+    // Now check conditions regarding the target unit.
+    //
+    if (target) {
+       if (condition->Undead!=CONDITION_TRUE) {
+           if ((condition->Undead==CONDITION_ONLY)^(target->Type->IsUndead)) {
+               return 0;
+           }
+       }
+       if (condition->Organic!=CONDITION_TRUE) {
+           if ((condition->Organic==CONDITION_ONLY)^(target->Type->Organic)) {
+               return 0;
+           }
+       }
+       if (condition->Building!=CONDITION_TRUE) {
+           if ((condition->Building==CONDITION_ONLY)^(target->Type->Building)) 
{
+               DebugLevel0("QQQ\n");
+               return 0;
+           }
+       }
+       if (condition->Hero!=CONDITION_TRUE) {
+           if ((condition->Hero==CONDITION_ONLY)^(target->Type->Hero)) {
+               return 0;
+           }
+       }
+       if (condition->Coward!=CONDITION_TRUE) {
+           if ((condition->Coward==CONDITION_ONLY)^(target->Type->Coward)) {
+               return 0;
+           }
+       }
+       if (condition->Alliance!=CONDITION_TRUE) {
+           if 
((condition->Alliance==CONDITION_ONLY)^(IsAllied(caster->Player,target))) {
+               return 0;
+           }
+       }
+       if (condition->TargetSelf!=CONDITION_TRUE) {
+           if ((condition->TargetSelf==CONDITION_ONLY)^(caster==target)) {
+               return 0;
+           }
+       }
+       //
+       //      Check vitals now.
+       //
+       if (condition->MinHpPercent*target->Stats->HitPoints>target->HP) {
            return 0;
        }
-    }
-    return 1;
-}
-
-/**
-**     Check all specific conditions.
-**     @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)
-{
-    int ret;
-
-    DebugCheck(!caster);
-    DebugCheck(!spell);
-
-    for (/*condition = spell->Condition_specific*/; condition != NULL; 
condition = condition->next) {
-       DebugCheck(!condition->f.specific);
-       ret = condition->f.specific(condition, caster, target, x, y);
-       DebugCheck(!(ret == 0 || ret == 1));
-       DebugCheck(!(condition->expectvalue == 0 || condition->expectvalue == 
1));
-       if (ret != condition->expectvalue) {
+       if (condition->MaxHpPercent*target->Stats->HitPoints<target->HP) {
            return 0;
        }
+       if (target->Type->CanCastSpell) {
+           if (condition->MinManaPercent*target->Type->_MaxMana>target->Mana) {
+               return 0;
+           }
+           if (condition->MaxManaPercent*target->Type->_MaxMana<target->Mana) {
+               return 0;
+           }
+       }
     }
     return 1;
 }
 
-
 /**
 **     Select the target for the autocast.
 **
@@ -1385,8 +1302,7 @@
                caster->X + range + 1, caster->Y + range + 1,table);
            // For all Unit, check if it is a possible target
            for (i = 0, j = 0; i < nb_units; i++) {
-               if 
(PassSpecificCondition(caster,spell,table[i],x,y,spell->Condition_specific)
-                       && 
PassSpecificCondition(caster,spell,table[i],x,y,spell->AutoCast->Condition_specific))
 {
+               if (PassCondition(caster,spell,table[i],x,y,spell->Conditions)) 
{
                        table[j++] = table[i];
                }
            }
@@ -1572,8 +1488,7 @@
        return 0;
     }
 
-    return PassGenericCondition(caster, spell, spell->Condition_generic)
-           && 
PassSpecificCondition(caster,spell,target,x,y,spell->Condition_specific);
+    return PassCondition(caster,spell,target,x,y,spell->Conditions);
 }
 
 /**
@@ -1596,10 +1511,9 @@
 
     target = NULL;
 
-    if (!PassGenericCondition(caster, spell, spell->Condition_generic)
-           || !PassGenericCondition(caster, spell, 
spell->AutoCast->Condition_generic)) {
+/*    if (PassCondition(caster,spell,target,x,y,spell->Conditions))
        return 0;
-    }
+    }*/
     target = SelectTargetUnitsOfAutoCast(caster, spell);
     if (target == NULL) {
        return 0;
Index: stratagus/src/include/spells.h
diff -u stratagus/src/include/spells.h:1.25 stratagus/src/include/spells.h:1.26
--- stratagus/src/include/spells.h:1.25 Sat Sep 27 15:05:47 2003
+++ stratagus/src/include/spells.h      Mon Sep 29 13:04:15 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: spells.h,v 1.25 2003/09/27 19:05:47 n0body Exp $
+//     $Id: spells.h,v 1.26 2003/09/29 17:04:15 n0body Exp $
 
 #ifndef __SPELLS_H__
 #define __SPELLS_H__
@@ -187,46 +187,46 @@
 */
 
 /**
-**     Informations about the conditions of autocasting mode and simple cast.
+**     Conditions for a spell.
 **
 **     @todo   Move more parameters into this structure.
 */
-struct s_Conditions;
-
-/*
-**      Specific conditions.
-*/
-typedef        int f_specific_condition(const struct s_Conditions *condition,
-       const Unit* caster,const Unit* target,int x,int y);
-
-typedef        int f_generic_condition(const struct s_Conditions 
*condition,const Unit* caster);
-
-
-/**
-**     Informations about the condition of autocasting mode.
-**
-**     @todo   Move more parameters into this structure.
-*/
-typedef struct s_Conditions {
-    int expectvalue;                           /// Value expected (function 
expected result, true or false)
-    union {
-       f_specific_condition *specific;         /// Evaluation Function for the 
condition.
-       f_generic_condition  *generic;          /// Evaluation Function for the 
condition.
-    } f;
-    union {
-       int range;      /// range
-//     struct {
-//         t_SpecificConditions c1;
-//         t_SpecificConditions c2;
-//     } or;           //
-       unsigned int flag;      ///< flag
-       struct {
-           unsigned int        flag;
-           unsigned int        ttl;
-       } durationeffect;       ///< durationeffect
-    } u;
-    struct s_Conditions        *next;  ///< for list.
-} t_Conditions;
+typedef struct ConditionInfo {
+    //
+    // Conditions that check specific flags. Possible values are the defines 
below.
+    //
+#define CONDITION_FALSE 1
+#define CONDITION_TRUE  0
+#define CONDITION_ONLY  2
+    char Undead;               /// Target is undead.
+    char Organic;              /// Target is organic.
+    char Hero;                 /// Target is hero. Set this to false for 
instant-kill spells.
+    char Coward;               /// Target is coward. Don't bloodlust them.
+    char Alliance;             /// Target is allied.
+    char Building;             /// Target is a building.
+    char TargetSelf;           /// Target is the same as the caster.
+       /// FIXME: NOT IMPLEMENTED:
+    char UnitBuffed;           /// Target is buffed(haste/slow/bloodlust). 
Dispel magic?
+    //
+    // Conditions related to vitals:
+    // 
+    int MinHpPercent;          /// Target must have more hp than that.
+    int MaxHpPercent;          /// Target must have less hp than that. Used 
for heal-like spells.
+    int MinManaPercent;                /// Target must have more mana than 
that. Mana drain spells?
+    int MaxManaPercent;                /// Target must have less mana than 
that. Mana fountains?
+    //
+    // Conditions related to buffs:
+    // 
+    int MaxHasteTicks;         /// Target must less haste ticks left.
+    int MaxSlowTicks;          /// Target must less slow ticks left.
+    int MaxBloodlustTicks;     /// Target must less bloodlust ticks left.
+    int MaxInvisibilityTicks;  /// Target must less bloodlust ticks left.
+    int MaxInvincibilityTicks; /// Target must less bloodlust ticks left.
+    //
+    // FIXME: more? feel free to add, here and to
+    // FIXME: PassCondition, CclSpellParseCondition, SaveSpells
+    //
+} ConditionInfo;
 
 
 /**
@@ -234,22 +234,18 @@
 **
 */
 typedef struct {
-       t_Conditions    *Condition_generic;             ///< Conditions to cast 
the spell. (generic (no test for each target))
-       t_Conditions    *Condition_specific;    ///< Conditions to cast the 
spell. (target specific (ex:Hp full))
-// Something to have a position target
-       int                             Range;                                  
                /// Max range of the target.
-#if 0  // When sort supported
-       t_f_order                       *f;                                     
                /// Sort functions for the best target.
-#endif
-} t_AutoCast;
+    ConditionInfo *Condition;          /// Conditions to cast the spell.
+    int Range;                         /// Max range of the target.
+    /// FIXME: Add stuff here for target preference.
+    /// FIXME: Heal units with the lowest hit points first.
+} AutoCastInfo;
 
 struct _spell_type_;
 
 /*
 **     Pointer on function that cast the spell.
 */
-typedef int SpellFunc(Unit* caster, const struct _spell_type_* spell, Unit* 
target,
-       int x, int y);
+typedef int SpellFunc(Unit* caster, const struct _spell_type_* spell, Unit* 
target,int x, int y);
 
 /**
 **     Base structure of a spell type.
@@ -264,14 +260,15 @@
     TargetType Target;                 /// Targetting information. See 
TargetType.
     SpellFunc *CastFunction;           /// function to cast the spell.
     SpellActionType *SpellAction;      /// More arguments for spell (damage, 
delay, additional sounds...).
+#define INFINITE_RANGE 0xFFFFFFF
     int Range;                         /// Max range of the target.
     int ManaCost;                      /// required mana for each cast
 
     int DependencyId;                  /// Id of upgrade, -1 if no upgrade 
needed for cast the spell.
-    t_Conditions *Condition_generic;   /// Conditions to cast the spell. 
(generic (no test for each target))
-    t_Conditions *Condition_specific;  /// Conditions to cast the spell. 
(target specific (ex:Hp full))
+    ConditionInfo *Conditions;         /// Conditions to cast the spell. 
(generic (no test for each target))
+
 //     Autocast        // FIXME : can use different for AI ? Use it in this 
structure ?
-    t_AutoCast *AutoCast;                                      /// AutoCast 
information
+    AutoCastInfo *AutoCast;            /// AutoCast information
 
 //     Uses for graphics and sounds
     SoundConfig SoundWhenCast;         /// sound played if cast
@@ -353,18 +350,6 @@
 SpellFunc CastWhirlwind;
 SpellFunc CastSpawnPortal;
 
-
-/*
-**     generic condition.
-*/
-f_generic_condition    CheckEnemyPresence;
-
-/*
-**     Specific condition.
-*/
-f_specific_condition   CheckUnitTypeFlag;
-f_specific_condition   CheckAllied;
-f_specific_condition   CheckUnitDurationEffect;
 
 //@}
 




reply via email to

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