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: Fri, 26 Sep 2003 11:47:51 -0400

CVSROOT:        /cvsroot/stratagus
Module name:    stratagus
Branch:         
Changes by:     Crestez Leonard <address@hidden>        03/09/26 11:47:51

Modified files:
        data/ccl       : spells.ccl 
        src/action     : action_resource.c 
        src/ai         : ai_magic.c 
        src/clone      : ccl_spell.c spells.c 
        src/include    : spells.h 
        src/siod       : slib.c 

Log message:
        Spell work.

Patches:
Index: stratagus/data/ccl/spells.ccl
diff -u stratagus/data/ccl/spells.ccl:1.1 stratagus/data/ccl/spells.ccl:1.2
--- stratagus/data/ccl/spells.ccl:1.1   Mon Sep 22 15:13:07 2003
+++ stratagus/data/ccl/spells.ccl       Fri Sep 26 11:47:50 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.1 2003/09/22 19:13:07 n0body Exp $

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

 

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

 

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

        'range  6

        'target 'unit

-       'action '( Healing (HP 1) )

+       'action '( healing (HP 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 '( healing (HP -1) )

        'condition '(   UnitTypeflag (true undead)

                        UnitTypeflag (false building)

                        Alliance false

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

        'range  6

        'target 'unit

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

+       'action '( haste (haste 1000 slow 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 '( haste (slow 1000 haste 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 '( haste (bloodlust 1000) )

        'condition '(   UnitTypeflag (true organic)

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

                        Alliance true

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

        'range  6

        'target 'unit

-       'action '( FlameShield (ttl 600))

+       'action '( flame-shield (ttl 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

        'sound-when-cast "flame shield"

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

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

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

 )

 

@@ -258,7 +258,13 @@
        'manacost 25

        'range  12

        'target 'position

-       'action '( Blizzard (fields 5 shards 10 damage 10) )

+       'action '(area-bombardment

+           (fields 5

+            shards 10

+            damage 10

+            ;;  128=4*32=4 tiles

+            start-offset-x -128

+            start-offset-y -128))

        'sound-when-cast "blizzard"

        'missile-when-cast "missile-blizzard"

 ;;     'autocast '(range 12)

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

        'range  12

        'target 'position

-       'action '( DeathAndDecay (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)

@@ -280,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)

@@ -302,7 +308,7 @@
        'manacost 100

        'range  10

        'target 'position ;; FIXME position or organic target

-       'action '( DeathCoil )

+       'action '( death-coil )

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

        'sound-when-cast "death coil"

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

@@ -336,20 +342,9 @@
        'manacost 25

        'range  -1

        'target 'position

-       'action '( CircleOfPower "unit-circle-of-power" )

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

        'sound-when-cast "circle of power"

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

 ;;     'autocast '(range -1)

 )

 

-;(define-caster 'caster "unit-paladin" 'spell "spell-holy-vision" 
"spell-healing" "spell-exorcism")

-;(define-caster 'caster "unit-mage"

-;      'spell "spell-fireball" "spell-slow" "spell-flame-shield" 
"spell-invisibility"

-;              "spell-polymorph" "spell-blizzard")

-;(define-caster 'caster "unit-ogre-mage" 'spell "spell-eye-of-vision" 
"spell-bloodlust" "spell-runes")

-;(define-caster 'caster "unit-death-knight"

-;      'spell "spell-death-coil" "spell-haste" "spell-raise-dead" 
"spell-whirlwind"

-;              "spell-unholy-armor" "spell-death-and-decay")

-

-;(define-caster 'caster ""

-;      'spell "spell-circle-of-power")

Index: stratagus/src/action/action_resource.c
diff -u stratagus/src/action/action_resource.c:1.55 
stratagus/src/action/action_resource.c:1.56
--- stratagus/src/action/action_resource.c:1.55 Sun Sep 14 00:45:52 2003
+++ stratagus/src/action/action_resource.c      Fri Sep 26 11:47:50 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: action_resource.c,v 1.55 2003/09/14 04:45:52 mr-russ Exp $
+//     $Id: action_resource.c,v 1.56 2003/09/26 15:47:50 n0body Exp $
 
 //@{
 
@@ -708,7 +708,8 @@
 */
 global void HandleActionResource(Unit* unit)
 {
-    int ret,newres;
+    int ret;
+    int newres;
 
     DebugLevel3Fn("%s(%d) SubAction %d TTH %d res %s goal %ul\n"
        _C_ unit->Type->Ident _C_ UnitNumber(unit) _C_ unit->SubAction
Index: stratagus/src/ai/ai_magic.c
diff -u stratagus/src/ai/ai_magic.c:1.15 stratagus/src/ai/ai_magic.c:1.16
--- stratagus/src/ai/ai_magic.c:1.15    Thu Sep 25 02:58:35 2003
+++ stratagus/src/ai/ai_magic.c Fri Sep 26 11:47:50 2003
@@ -10,7 +10,7 @@
 //
 /address@hidden ai_magic.c     -       AI magic functions. */
 //
-//      (c) Copyright 2002 by Lutz Sammer
+//      (c) Copyright 2002-2003 by Lutz Sammer, Joris Dauphin
 //
 //      This program is free software; you can redistribute it and/or modify
 //      it under the terms of the GNU General Public License as published by
@@ -26,7 +26,9 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//      $Id: ai_magic.c,v 1.15 2003/09/25 06:58:35 mr-russ Exp $
+//      $Id: ai_magic.c,v 1.16 2003/09/26 15:47:50 n0body Exp $
+
+#ifdef NEW_AI  // {
 
 //@{
 
@@ -47,365 +49,47 @@
 #include "ai_local.h"
 
 /*----------------------------------------------------------------------------
---     Variables
-----------------------------------------------------------------------------*/
-
-local UnitType* AiPaladin;
-local SpellType* AiHolyVision;
-local SpellType* AiHealing;
-local UnitType* AiMage;
-local SpellType* AiSlow;
-local SpellType* AiInvisibility;
-local UnitType* AiOgreMage;
-local SpellType* AiEyeOfVision;
-local SpellType* AiBloodlust;
-local UnitType* AiUnitTypeEyeOfVision;
-local UnitType* AiDeathKnight;
-local SpellType* AiHaste;
-local SpellType* AiUnholyArmor;
-
-/*----------------------------------------------------------------------------
 --     Functions
 ----------------------------------------------------------------------------*/
 
 /**
-**     Init the magic.
-**
-**     @note I will remove the hardcoded stuff, if tested.
-*/
-local void AiInitMagic(void)
-{
-    AiPaladin=UnitTypeByIdent("unit-paladin");
-    AiHolyVision=SpellTypeByIdent("spell-holy-vision");
-    AiHealing=SpellTypeByIdent("spell-healing");
-    AiMage=UnitTypeByIdent("unit-mage");
-    AiSlow=SpellTypeByIdent("spell-slow");
-    AiInvisibility=SpellTypeByIdent("spell-invisibility");
-    AiOgreMage=UnitTypeByIdent("unit-ogre-mage");
-    AiEyeOfVision=SpellTypeByIdent("spell-eye-of-vision");
-    AiBloodlust=SpellTypeByIdent("spell-bloodlust");
-    AiUnitTypeEyeOfVision=UnitTypeByIdent("unit-eye-of-vision");
-    AiDeathKnight=UnitTypeByIdent("unit-death-knight");
-    AiHaste=SpellTypeByIdent("spell-haste");
-    AiUnholyArmor=SpellTypeByIdent("spell-unholy-armor");
-/*
-       "spell-exorcism"
-       "spell-fireball"
-       "spell-flame-shield"
-       "spell-polymorph"
-       "spell-blizzard"
-
-       "spell-runes"
-       "spell-death-coil"
-       "spell-raise-dead"
-       "spell-whirlwind"
-       "spell-death-and-decay"
-*/
-}
-
-/**
-**     Check if the unit should cast the "bloodlust" spell.
-**
-**     If the spell is available and the unit has enough mana, the surrounding
-**     of the unit is checked if any enemy units are in sight. If enemy units
-**     are in sight the spell is casted on own units in range.
-**
-**     @param unit     Magic unit.
-**
-**     @return         True, if a spell is casted.
-*/
-local int AiBloodlustSpell(Unit* unit)
-{
-    if( UpgradeIdentAvailable(AiPlayer->Player,"upgrade-bloodlust") ) {
-       if( AutoCastSpell(unit,AiBloodlust) ) {
-           return 1;
-       }
-    }
-    return 0;
-}
-
-/**
-**     Check if the unit should cast the "eye of vision" spell.
-**
-**     If the unit has nothing to do and the spell is available and the unit
-**     has full mana cast with a change of 1/32 the spell. The spells does
-**     nothing, because the AI cheats and already knows the surroundings.
-**
-**     @param unit     Magic unit.
-**
-**     @return         True, if a spell is casted.
-*/
-local int AiEyeOfVisionSpell(Unit* unit)
-{
-    if( unit->Orders[0].Action==UnitActionStill
-           && UpgradeIdentAvailable(AiPlayer->Player,"upgrade-eye-of-kilrogg")
-           && UpgradeIdentAvailable(AiPlayer->Player,"upgrade-ogre-mage") ) {
-       // s0m3body: each unit can have different MaxMana, the original
-       //              condition is testing MaxMana-10, so let's take unit's
-       //              maxmana * 245/255 as a new threshold
-       if( unit->Mana>(unit->Type->_MaxMana*245)/255 && !SyncRand()%32 ) {
-           if( AutoCastSpell(unit,AiEyeOfVision) ) {
-               return 1;
-           }
-       }
-    }
-    return 0;
-}
-
-/**
-**     Do magic for ogre-mage.
-*/
-local void AiDoOgreMage(Unit* unit)
-{
-    if( AiBloodlustSpell(unit) ) {
-       return;
-    }
-    if( AiEyeOfVisionSpell(unit) ) {
-       return;
-    }
-}
-
-/**
-**     Check if the unit should cast the "slow" spell.
-**
-**     If the spell is available and the unit has enough mana, the surrounding
-**     of the unit is checked if any enemy units are in sight. If enemy units
-**     are in sight the spell is casted on the units in range.
-**
-**     @param unit     Magic unit.
-**
-**     @return         True, if a spell is casted.
-*/
-local int AiSlowSpell(Unit* unit)
-{
-    if( UpgradeIdentAvailable(AiPlayer->Player,"upgrade-slow") ) {
-       if( !SyncRand()%4 && AutoCastSpell(unit,AiSlow) ) {
-           return 1;
-       }
-    }
-    return 0;
-}
-
-/**
-**     Check if the unit should cast the "invisibility" spell.
-**
-**     If the spell is available and the unit has enough mana, the surrounding
-**     of the unit is checked if any enemy units are in sight. If enemy units
-**     are in sight the spell is casted on own units in range.
-**
-**     @param unit     Magic unit.
-**
-**     @return         True, if a spell is casted.
-*/
-local int AiInvisibilitySpell(Unit* unit)
-{
-    if( UpgradeIdentAvailable(AiPlayer->Player,"upgrade-invisibility") ) {
-       if( !SyncRand()%4 && AutoCastSpell(unit,AiInvisibility) ) {
-           return 1;
-       }
-    }
-    return 0;
-}
-
-/**
-**     Do magic for mage.
-*/
-local void AiDoMage(Unit* unit)
-{
-    if (AiSlowSpell(unit)) {
-       return;
-    }
-    if (AiInvisibilitySpell(unit)) {
-       return;
-    }
-}
-
-/**
-**     Check if the unit should cast the "healing" spell.
-**
-**     If the spell is available and the unit has enough mana, the surrounding
-**     of the unit is checked if any ally damaged units are in sight. If ally
-**     damaged units are in sight the spell is casted on own units in range.
-**
-**     @param unit     Magic unit.
-**
-**     @return         True, if a spell is casted.
-*/
-local int AiHealingSpell(Unit* unit)
-{
-    if (UpgradeIdentAvailable(AiPlayer->Player, "upgrade-healing") ) {
-       if( AutoCastSpell(unit,AiHealing) ) {
-           return 1;
-       }
-    }
-    return 0;
-}
-
-/**
-**     Check if the unit should cast the "holy vision" spell.
-**
-**     If the unit has nothing to do and the spell is available and the unit
-**     has full mana cast with a change of 1/32 the spell. The spells does
-**     nothing, because the AI cheats and already knows the surroundings.
-**
-**     @param unit     Magic unit.
-**
-**     @return         True, if a spell is casted.
-*/
-local int AiHolyVisionSpell(Unit* unit)
-{
-    if( unit->Orders[0].Action==UnitActionStill
-           && UpgradeIdentAvailable(AiPlayer->Player,"upgrade-holy-vision")
-           && UpgradeIdentAvailable(AiPlayer->Player,"upgrade-paladin") ) {
-       // s0m3body: each unit can have different MaxMana, the original
-       //              condition is testing MaxMana-10, so let's take unit's
-       //              maxmana * 245/255 as a new threshold
-       if( unit->Mana>(unit->Type->_MaxMana*245)/255 && !SyncRand()%32 ) {
-           if( AutoCastSpell(unit,AiHolyVision) ) {
-               return 1;
-           }
-       }
-    }
-    return 0;
-}
-
-/**
-**     Do magic for paladin.
-*/
-local void AiDoPaladin(Unit* unit)
-{
-    if (AiHealingSpell(unit)) {
-       return;
-    }
-    if (AiHolyVisionSpell(unit)) {
-       return;
-    }
-}
-
-/**
-**     Check if the unit should cast the "haste" spell.
-**
-**     If the spell is available and the unit has enough mana, the surrounding
-**     of the unit is checked if any ally units are in sight. If ally units
-**     are in sight the spell is casted on the units in range.
-**
-**     @param unit     Magic unit.
-**
-**     @return         True, if a spell is casted.
-*/
-local int AiHasteSpell(Unit* unit)
-{
-    if( UpgradeIdentAvailable(AiPlayer->Player,"upgrade-haste") ) {
-       if( !SyncRand()%4 && AutoCastSpell(unit,AiHaste) ) {
-           return 1;
-       }
-    }
-    return 0;
-}
-
-/**
-**     Check if the unit should cast the "unholy armor" spell.
-**
-**     If the spell is available and the unit has enough mana, the surrounding
-**     of the unit is checked if any enemy units are in sight. If enemy units
-**     are in sight the spell is casted on own units in range.
-**
-**     @param unit     Magic unit.
-**
-**     @return         True, if a spell is casted.
-*/
-local int AiUnholyArmorSpell(Unit* unit)
-{
-    if( UpgradeIdentAvailable(AiPlayer->Player,"upgrade-unholy-armor") ) {
-       if( !SyncRand()%4 && AutoCastSpell(unit,AiUnholyArmor) ) {
-           return 1;
-       }
-    }
-    return 0;
-}
-
-/**
-**     Do magic for death knight.
-*/
-local void AiDoDeathKnight(Unit* unit)
-{
-    if (AiHasteSpell(unit)) {
-       return;
-    }
-    if (AiUnholyArmorSpell(unit)) {
-       return;
-    }
-}
-
-/**
 **     Check what computer units can do with magic.
+**     In fact, turn on autocast for AI.
 */
 global void AiCheckMagic(void)
 {
-    int i;
+    int i, j;
     int n;
     Unit** units;
     Unit* unit;
-
-    AiInitMagic();
-
-    n=AiPlayer->Player->TotalNumUnits;
-    units=AiPlayer->Player->Units;
-    for( i=0; i<n; ++i ) {
-       unit=units[i];
-       if( unit->Type->CanCastSpell ) {        // Its a magic unit
-           DebugLevel3Fn("Have mage `%s'\n" _C_ unit->Type->Ident);
-           // FIXME: I hardcode the reactions now
-           if( unit->Type==AiOgreMage ) {
-               AiDoOgreMage(unit);
-           } else if( unit->Type==AiMage ) {
-               AiDoMage(unit);
-           } else if( unit->Type==AiPaladin ) {
-               AiDoPaladin(unit);
-           } else if( unit->Type==AiDeathKnight ) {
-               AiDoDeathKnight(unit);
-           }
-       }
-       //
-       //      Handle casted eyes of vision.
-       //
-       if( unit->Type==AiUnitTypeEyeOfVision ) {
-           if( unit->Orders[0].Action==UnitActionStill ) {
-               int x;
-               int y;
-               int r;
-
-               // Let it move around randomly
-               r=SyncRand()>>4;
-               if( r&0x20 ) {
-                   if( unit->X<(r&0x1F) ) {
-                       x=0;
-                   } else {
-                       x=unit->X-(r&0x1F);
-                   }
-               } else {
-                   x=unit->X+(r&0x1F);
-                   if( x>=TheMap.Width ) {
-                       x=TheMap.Width-1;
-                   }
-               }
-               r>>=6;
-               if( r&0x20 ) {
-                   if( unit->Y<(r&0x1F) ) {
-                       y=0;
-                   } else {
-                       y=unit->Y-(r&0x1F);
-                   }
-               } else {
-                   y=unit->Y+(r&0x1F);
-                   if( y>=TheMap.Height ) {
-                       y=TheMap.Height-1;
-                   }
+    const Player *player;
+#ifdef DEBUG
+    int success;
+#endif
+
+    n = AiPlayer->Player->TotalNumUnits;
+    units = AiPlayer->Player->Units;
+    player = AiPlayer->Player;/*units[0]->Player*/
+    for(i = 0; i < n; ++i) {
+       unit = units[i];
+       //  Check only magic units
+       if(unit->Type->CanCastSpell) {
+           for (j = 0; j < SpellTypeCount; j++) {
+               //  Check if we can cast this spell. SpellIsAvailable checks 
for upgrades.
+               if (unit->Type->CanCastSpell[j] && SpellIsAvailable(player, j)) 
{
+#ifdef DEBUG
+                   success = // Follow on next line (AutoCastSpell).
+#endif
+                   AutoCastSpell(unit, SpellTypeById(j));
+                   DebugLevel3Fn("Mage '%s' cast '%s' : %s\n"
+                               _C_ unit->Type->Ident
+                               _C_ SpellTypeById(j)->Ident
+                               _C_ success ? "success" : "fail");
                }
-               CommandMove(unit,x,y,FlushCommands);
            }
        }
     }
 }
 
 //@}
+#endif // } NEW_AI
Index: stratagus/src/clone/ccl_spell.c
diff -u stratagus/src/clone/ccl_spell.c:1.4 stratagus/src/clone/ccl_spell.c:1.5
--- stratagus/src/clone/ccl_spell.c:1.4 Tue Sep 23 21:56:53 2003
+++ stratagus/src/clone/ccl_spell.c     Fri Sep 26 11:47:50 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA

 //      02111-1307, USA.

 //

-//     $Id: ccl_spell.c,v 1.4 2003/09/24 01:56:53 n0body Exp $

+//     $Id: ccl_spell.c,v 1.5 2003/09/26 15:47:50 n0body Exp $

 //@{

 

 /*----------------------------------------------------------------------------

@@ -48,104 +48,52 @@
 #include "ccl.h"

 

 /**

-       Syntax : 

-;;             // Warning, Some names and specifications should be changed

-;;             // Todo parameter coherency ? negative for dealing damage, 
positive for healing ?

-;;

-;;             ...             : for list.

-;;             {a, b, c}       : choice between a, b, or c.

-;;             name#n          : name is of type number.

-;;             #n                      : Number.

-;;             #t                      : {true, false}

-;;             #target         : {'self, 'Unit, 'position}

-;;             #f_inv          : {unholyarmor, invisibility}

-;;             #f_haste        : {bloodlust, slow, haste, HP, mana, 
HP_percent, mana_percent}

-;;             #f_flag         : {invisibility, bloodlust, unholyarmor, slow, 
haste, flameshield,

-;;                               HP, mana, HP_percent, mana_percent

-;;             #flagtype       : {coward, organic, undead, canattack, building}

-;;             <condition>     : Same syntax as 'condition

-;;

-;;     (define-spell   "IdentName"     // Ident name for call in unit

-;;             'Showname "ShowName"    // Name show in the engine

-;;             'ManaCost #n            // Mana to cast the spell

-;;             'range #n               // Range of the spell (0)

-;;             'Target #target         // Which target is allowed (None by 
default)

-;;             'Action '({

-;;                     Blizzard ('fields #n 'shards #n 'damage #n),

-;;                     CircleOfPower "unit-goal",

-;;                     DeathAndDecay(fields #n shards #n damage #n),

-;;                     DeathCoil,

-;;                     FireBall (ttl #n damage #n),

-;;                     FlameShield (ttl #n),

-;;                     Haste (#f_haste #n ...),

-;;                     Healing (HP#n), // Healing (HP >0) or exorcism (HP < 0)

-;;                     HolyVision "unit-revealer",

-;;                     Invisibility (flag #f_inv value #n missile 
"MissileType")

-;;                     Polymorph "unittype",

-;;                     RaiseDead "skeleton",

-;;                     Runes (ttl #n damage #n),

-;;                     Summon "UnitType",

-;;                     Whirlwind (ttl #n)

-;;                             } )

-;;             'sound-when-cast "SoundConfig"

-;;             'missile-when-cast "MissileType"

-;;             'condition '( {

-;;                     Enemypresence   (#t range #n),                  // 
enemy in range

-;;                     DurationEffect  (#t flag #f_flag value #n),     // 
"f_flag" < #n

-;;                     Alliance        #t,                             // 
check the target is allied.

-;;                     UnitTypeflag    (#t #flagtype),                 // Unit 
is a "type"

-;;                     ...}

-;;                     )

-;;             'autocast '(

-;;                             range #n

-;;                             condition (<condition>)// Additional condition

-;;                             +++order () // which target choose.

-;;             )

-*/

-

-/*

-**     Todo:

-**             Some warnings are displayed only to developers (debugging),

-**     but should be useful for users who modofify or create ccl.

-**     Replace DebugLevel0Fn by appropriated functions.

-*/

-

-/**

 **     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);

+typedef void f_ccl_spell(const char *id, SCM list, SpellType   *spell);

 

 // **************************************************************************

 //             Direct affectation for spell

 // **************************************************************************

 

-/*

-**     Parse the missile for spell.

-**     list = "MissileType"

+/**

+**      Parse the dependency of spell.

+**      list = (upgrade "upgradename")

 */

-local void ccl_spell_missilewhencast(const char *id, SCM list, SpellType 
*spell)

+local void ccl_spell_dependency(const char *id, SCM list, SpellType *spell)

 {

-    char *missilewhencastname = NULL;

-    MissileType *missile = spell->Missile;

-

     assert (id != NULL);

     assert (spell != NULL);

-    missilewhencastname = gh_scm2newstr(list, NULL);

-    spell->Missile = MissileTypeByIdent(missilewhencastname);

-    if (missile != NULL && spell->Missile != missile) {

-       DebugLevel3Fn("Redefinition in spell-type '%s' : %s : '%s' -> '%s'\n"

-               _C_ spell->IdentName _C_ id _C_ spell->Missile->Ident _C_ 
missilewhencastname);

-    }

-    if (spell->Missile == NULL) {

-       DebugLevel0Fn("in spell-type '%s' : %s : '%s' %s\n"

-               _C_ spell->Name _C_ id _C_  missilewhencastname _C_ "does not 
exist");

+

+    char *dependencyName = NULL;

+    SCM  value;

+    int  dependencyId = -1;

+

+    value = gh_car(list);

+

+    if (!gh_eq_p(value, gh_symbol2scm("upgrade"))) {

+       return;

     }

-    free(missilewhencastname);

+    list = gh_cdr(list);

+    value = gh_car(list);

+

+    dependencyName = gh_scm2newstr(value, NULL);

+    dependencyId = UpgradeIdByIdent(dependencyName);

+    if (dependencyId == -1)

+    {// warn user

+       DebugLevel0Fn("Bad upgrade-name '%s'\n" _C_ dependencyName);

+       free(dependencyName);

+       return ;

+    }

+    spell->DependencyId = dependencyId;

+    free(dependencyName);

 }

 

+

 // **************************************************************************

 //             Action parsers for spellAction

 // **************************************************************************

@@ -154,51 +102,36 @@
 **     For blizzard and DeathAndDecay.

 **     list = fields #n shards #n damage #n

 */

-local char ccl_spell_action_blizzard(const char *SpellName, SCM list, 
SpellActionType *spellaction)

+local char CclSpellParseActionAreaBombardment(const char *SpellName, SCM list, 
SpellActionType *spellaction)

 {

-    int fields;

-    int        shards;

-    int        damage;

     SCM        value;

 

     assert(SpellName);

     assert(spellaction != NULL);

 

-    fields = 0;

-    shards = 0;

-    damage = 0;

+    memset(spellaction,sizeof(spellaction),0);

     for (; !gh_null_p(list); list = gh_cdr(list)) {

        value = gh_car(list);

        list = gh_cdr(list);

-       // Todo, Warn for redefinitions ???

        if (gh_eq_p(value, gh_symbol2scm("fields"))) {

-           fields = gh_scm2int(gh_car(list));

+           spellaction->AreaBombardment.Fields = gh_scm2int(gh_car(list));

            continue;

-       }

-       if (gh_eq_p(value, gh_symbol2scm("shards"))) {

-           shards = gh_scm2int(gh_car(list));

+       } else if (gh_eq_p(value, gh_symbol2scm("shards"))) {

+           spellaction->AreaBombardment.Shards = gh_scm2int(gh_car(list));

            continue;

-       }

-       if (gh_eq_p(value, gh_symbol2scm("damage"))) {

-           damage = gh_scm2int(gh_car(list));

+       } 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");

     }

-    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 (fields <= 0 || shards <= 0) {

-       DebugLevel0Fn("in spell-type %s : %s" _C_ SpellName _C_

-               "fields <= 0 or shards <= 0 have no sense");

-       return 0;

-    }

-    spellaction->Blizzard.Fields = fields;

-    spellaction->Blizzard.Shards = shards;

-    spellaction->Blizzard.Damage = damage;

     return 1;

 }

 

@@ -206,7 +139,7 @@
 **     For fireball and Runes.

 **     list = 'ttl #n 'damage #n

 */

-local char ccl_spell_action_fireball(const char *SpellName, SCM list, 
SpellActionType *spellaction)

+local char CclSpellParseActionFireball(const char *SpellName, SCM list, 
SpellActionType *spellaction)

 {

     int        ttl;

     int        damage;

@@ -252,7 +185,7 @@
 **     For flameshield and whirlwind.

 **     list = 'ttl #n

 */

-local char ccl_spell_action_flameshield(const char *SpellName, SCM list, 
SpellActionType *spellaction)

+local char CclSpellParseActionFlameShield(const char *SpellName, SCM list, 
SpellActionType *spellaction)

 {

     int ttl;

     SCM        value;

@@ -288,7 +221,7 @@
 **     One or more.

 **     @todo Free when an error occurs. Do a function to do this.

 */

-local char ccl_spell_action_haste(const char *SpellName, SCM list, 
SpellActionType     *spellaction)

+local char CclSpellParseActionHaste(const char *SpellName, SCM list, 
SpellActionType   *spellaction)

 {

     struct {

        const char *id;

@@ -355,7 +288,7 @@
 **     HP positive for healing, negative for dealing damage.

 **     list = (HP #n)

 */

-local char ccl_spell_action_healing(const char *SpellName, SCM list, 
SpellActionType *spellaction)

+local char CclSpellParseActionHealing(const char *SpellName, SCM list, 
SpellActionType *spellaction)

 {

    

 

@@ -392,7 +325,7 @@
 **     For invisibility and unholyarmor.

 **     list = flag #f_inv value #n missile "missile-name"

 */

-local char ccl_spell_action_invisibility(const char *SpellName, SCM list, 
SpellActionType      *spellaction)

+local char CclSpellParseActionInvisibility(const char *SpellName, SCM list, 
SpellActionType    *spellaction)

 {

     const struct {

        const char *id;

@@ -476,22 +409,19 @@
 **     list = ("unittypename")

 **     @note   WARNING, use for other functions than summon, see 
ccl_spell_action.

 */

-local char ccl_spell_action_summon(const char *SpellName, SCM list, 
SpellActionType *spellaction)

+local char CclSpellParseActionSummon(const char *SpellName, SCM list, 
SpellActionType *spellaction)

 {

-    

-

     char *str;

     UnitType *unittype;

 

-       assert(SpellName);

+    assert(SpellName);

     assert(spellaction != NULL);

 

     str = gh_scm2newstr(list, NULL);

     unittype = UnitTypeByIdent(str);

-    spellaction->summon.unittype = unittype;

+    spellaction->Summon.UnitType = unittype;

     if (unittype == NULL) {

-       DebugLevel0Fn("in spell-type %s : Unittype '%s'doesn't exist" _C_

-               SpellName _C_ str);

+       DebugLevel0Fn("in spell-type %s : Unittype '%s'doesn't exist" _C_ 
SpellName _C_ str);

        free(str);

        return 0;

     }

@@ -518,26 +448,25 @@
 local void ccl_spell_action(const char *id, SCM list, SpellType *spell)

 {

     int                i;

-    static struct {

-           f_spell             *fspell;

+    struct {

+           SpellFunc *fspell;

            const char *id;

            f_ccl_action *f;

     }  parser[] = {

-       {CastBlizzard, "Blizzard", ccl_spell_action_blizzard},

-       {CastCircleOfPower, "CircleOfPower", 
ccl_spell_action_summon/*circleofpower*/},

-       {CastBlizzard, "DeathAndDecay", 
ccl_spell_action_blizzard/*deathanddecay*/},

-       {CastDeathCoil, "DeathCoil", NULL},

-       {CastFireball, "FireBall", ccl_spell_action_fireball},

-       {CastFlameShield, "FlameShield", ccl_spell_action_flameshield},

-       {CastHaste, "Haste", ccl_spell_action_haste},

-       {CastHealing, "Healing", ccl_spell_action_healing},

-       {CastHolyVision, "HolyVision", ccl_spell_action_summon/*holyvision*/},

-       {CastInvisibility, "Invisibility", ccl_spell_action_invisibility},

-       {CastPolymorph, "Polymorph", ccl_spell_action_summon/*polymorph*/},

-       {CastRaiseDead, "RaiseDead", ccl_spell_action_summon/*raisedead*/},

-       {CastRunes, "Runes", ccl_spell_action_fireball/*runes*/},

-       {CastSummon, "Summon", ccl_spell_action_summon},

-       {CastWhirlwind, "Whirlwind", ccl_spell_action_flameshield/*whirlwind*/},

+       {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}

     };

     

@@ -942,6 +871,7 @@
 local SCM CclDefineSpell(SCM list)

 {

     char *identname;

+    char *str;

     SpellType *spell;

     SCM        value;

 

@@ -957,6 +887,7 @@
        memset(spell,0,sizeof(SpellType));

        spell->Ident=SpellTypeCount-1;

        spell->IdentName=identname;

+       spell->DependencyId = -1;

     }

     while (!gh_null_p(list)) {

        value = gh_car(list);

@@ -1008,9 +939,19 @@
            }

            list=gh_cdr(list);

        } else if (gh_eq_p(value,gh_symbol2scm("missile-when-cast"))) {

-           ccl_spell_missilewhencast("missile-when-cast",gh_car(list),spell);

+           str = gh_scm2newstr(gh_car(list), NULL);

+           spell->Missile = MissileTypeByIdent(str);

+           if (spell->Missile == NULL) {

+               DebugLevel0Fn("in spell-type '%s' : missile %s does not exist\n"

+                       _C_ spell->Name _C_ str);

+           }

+           free(str);

            list=gh_cdr(list);

-       } else {

+       } else if (gh_eq_p(value,gh_symbol2scm("depend"))) {

+           ccl_spell_dependency("depend", gh_car(list), spell);

+           list = gh_cdr(list);

+       } else 

+       {

            errl("Unsupported tag", value);

        }

     }

@@ -1050,7 +991,7 @@
            CLprintf(file,"    'sound-when-cast 
\"%s\"\n",spell->SoundWhenCast.Name);

        }

        if (spell->Missile) {

-           CLprintf(file,"    'missile-when-casted 
\"%s\"\n",spell->Missile->Ident);

+           CLprintf(file,"    'missile-when-cast 
\"%s\"\n",spell->Missile->Ident);

        }

        //

        //  Target type.

@@ -1077,23 +1018,25 @@
        //  Save the action(effect of the spell)

        //

        CLprintf(file,"    'action");

-       if (spell->f==CastBlizzard) {

-           CLprintf(file," '(Blizzard (fields %d shards %d damage %d) )\n",

-                   spell->SpellAction->Blizzard.Fields,

-                   spell->SpellAction->Blizzard.Shards,

-                   spell->SpellAction->Blizzard.Damage);

+       if (spell->f==CastAreaBombardment) {

+           CLprintf(file," '(area-bombardment (fields %d shards %d damage %d 
start-offset-x %d start-offset-y %d) )\n",

+                   spell->SpellAction->AreaBombardment.Fields,

+                   spell->SpellAction->AreaBombardment.Shards,

+                   spell->SpellAction->AreaBombardment.Damage,

+                   spell->SpellAction->AreaBombardment.StartOffsetX,

+                   spell->SpellAction->AreaBombardment.StartOffsetY);

        } else if (spell->f==CastFireball) {

-           CLprintf(file," '(FireBall (ttl %d damage %d) )\n",

+           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);

+           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);

+           CLprintf(file," '(Summon 
\"%s\")\n",spell->SpellAction->Summon.UnitType->Ident);

        } else if (spell->f==CastHaste) {

-           CLprintf(file," '(Haste ( ");

+           CLprintf(file," '(haste ( ");

            hinfo=&spell->SpellAction->haste;

            while (hinfo) {

                switch (hinfo->flag) {

@@ -1141,22 +1084,22 @@
                    spell->SpellAction->invisibility.missile->Ident);

        } else if (spell->f==CastPolymorph) {

            CLprintf(file," '(Polymorph \"%s\")\n",

-                   spell->SpellAction->polymorph.unit->Ident);

+                   spell->SpellAction->Polymorph.NewForm->Ident);

        } else if (spell->f==CastRaiseDead) {

            CLprintf(file," '(RaiseDead \"%s\")\n",

-                   spell->SpellAction->raisedead.skeleton->Ident);

+                   spell->SpellAction->RaiseDead.Skeleton->Ident);

        } else if (spell->f==CastFlameShield) {

-           CLprintf(file," '(FlameShield (ttl %d) )\n",

+           CLprintf(file," '(flame-shield (ttl %d) )\n",

                    spell->SpellAction->FlameShield.TTL);

        } else if (spell->f==CastRunes) {

            CLprintf(file," '(Runes (ttl %d damage %d) )\n",

                    spell->SpellAction->runes.TTL,

-                   spell->SpellAction->runes.damage);

-       } else if (spell->f==CastCircleOfPower) {

-           CLprintf(file," '(CircleOfPower \"%s\")\n",

+                   spell->SpellAction->runes.Damage);

+       } else if (spell->f==CastSpawnPortal) {

+           CLprintf(file," '(spawn-portal \"%s\")\n",

                    spell->SpellAction->SpawnPortal.PortalType->Ident);

        } else if (spell->f==CastDeathCoil) {

-           CLprintf(file," '(DeathCoil)\n");

+           CLprintf(file," '(death-coil)\n");

            // FIXME: more?

        } else if (spell->f==CastWhirlwind) {

            CLprintf(file," '(Whirlwind (ttl %d) )\n",

Index: stratagus/src/clone/spells.c
diff -u stratagus/src/clone/spells.c:1.99 stratagus/src/clone/spells.c:1.100
--- stratagus/src/clone/spells.c:1.99   Fri Sep 26 05:15:22 2003
+++ stratagus/src/clone/spells.c        Fri Sep 26 11:47:50 2003
@@ -27,7 +27,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: spells.c,v 1.99 2003/09/26 09:15:22 mr-russ Exp $
+//     $Id: spells.c,v 1.100 2003/09/26 15:47:50 n0body Exp $
 
 /*
 **     And when we cast our final spell
@@ -80,7 +80,7 @@
 
 
 /// How many spell-types are available
-global int SpellTypeCount = 0; // Usefull ?
+global int SpellTypeCount = 0;
 
 /*----------------------------------------------------------------------------
 --     Functions (Spells Controllers/Callbacks)
@@ -120,28 +120,25 @@
     // explosions are on each tile on the way
 
     // approx
-    if (missile->TTL <= missile->State && missile->TTL % 2 == 0)
-    {
+    if (missile->TTL <= missile->State && missile->TTL % 2 == 0) {
        //+TileSize/2 to align gfx to baseline
-               x = missile->X + TileSizeX / 2;
-               y = missile->Y + TileSizeY / 2;
+       x = missile->X + TileSizeX / 2;
+       y = missile->Y + TileSizeY / 2;
 
-               MakeMissile(MissileTypeExplosion, x, y, x, y);
+       MakeMissile(MissileTypeExplosion, x, y, x, y);
 
-               x = x / TileSizeX;
-               y = y / TileSizeY;
+       x = x / TileSizeX;
+       y = y / TileSizeY;
 
        // Effect of the explosion on units
        // NOTE: vladi: this is slightly different than original
        //      now it hits all units in range 1
-               n = SelectUnits(x - 1, y - 1, x + 1, y + 1, table);
-               for (i = 0; i < n; ++i)
-               {
-                       if (table[i]->HP)
-                       {
-                               HitUnit(missile->SourceUnit, table[i], 
FIREBALL_DAMAGE); // Should be missile->damage
-                       }
-               }
+       n = SelectUnits(x - 1, y - 1, x + 1, y + 1, table);
+       for (i = 0; i < n; ++i) {
+           if (table[i]->HP) {
+               HitUnit(missile->SourceUnit, table[i], FIREBALL_DAMAGE); // 
Should be missile->damage
+           }
+       }
     }
 }
 
@@ -154,134 +151,108 @@
 */
 local void SpellDeathCoilController(Missile * missile)
 {
-       Unit    *table[UnitMax];
-       int     i;
-       int     n;
-       Unit    *source;
+    Unit *table[UnitMax];
+    int        i;
+    int        n;
+    Unit *source;
 
     //
     //  missile has not reached target unit/spot
     //
-       if (!(missile->X == missile->DX && missile->Y == missile->DY))
-       {
-               return ;
-       }
-       source = missile->SourceUnit;
-       if (source->Destroyed)
-       {
-               return ;
-       }
-       // source unit still exists
-       //
-       //      Target unit still exists and casted on a special target
-       //
-       if (missile->TargetUnit && !missile->TargetUnit->Destroyed
-               && missile->TargetUnit->HP)
-       {
-               if (missile->TargetUnit->HP <= 50)      // 50 should be 
parametrable
-               {
-                       source->Player->Score += 
missile->TargetUnit->Type->Points;
-                       if( missile->TargetUnit->Type->Building)
-                       {
-                               source->Player->TotalRazings++;
-                       }
-                       else
-                       {
-                               source->Player->TotalKills++;
-                       }
+    if (!(missile->X == missile->DX && missile->Y == missile->DY)) {
+       return ;
+    }
+    source = missile->SourceUnit;
+    if (source->Destroyed) {
+       return ;
+    }
+    // source unit still exists
+    //
+    // Target unit still exists and casted on a special target
+    //
+    if (missile->TargetUnit && !missile->TargetUnit->Destroyed
+           && missile->TargetUnit->HP)  {
+       if (missile->TargetUnit->HP <= 50) {// 50 should be parametrable
+           source->Player->Score += missile->TargetUnit->Type->Points;
+           if( missile->TargetUnit->Type->Building) {
+               source->Player->TotalRazings++;
+           } else {
+               source->Player->TotalKills++;
+           }
 #ifdef USE_HP_FOR_XP
-                       source->XP += missile->TargetUnit->HP;
+           source->XP += missile->TargetUnit->HP;
 #else
-                       source->XP += missile->TargetUnit->Type->Points;
+           source->XP += missile->TargetUnit->Type->Points;
 #endif
-                       ++source->Kills;
-                       missile->TargetUnit->HP = 0;
-                       LetUnitDie(missile->TargetUnit);
-               }
-               else
-               {
+           ++source->Kills;
+           missile->TargetUnit->HP = 0;
+           LetUnitDie(missile->TargetUnit);
+       } else {
 #ifdef USE_HP_FOR_XP
-                       source->XP += 50;
+           source->XP += 50;
 #endif
-                       missile->TargetUnit->HP -= 50;
-               }
-               if (source->Orders[0].Action != UnitActionDie)
-               {
-                       source->HP += 50;
-                       if (source->HP > source->Stats->HitPoints)
-                       {
-                               source->HP = source->Stats->HitPoints;
-                       }
-               }
+           missile->TargetUnit->HP -= 50;
        }
-       else
-    //
-    // No target unit -- try enemies in range 5x5 // Must be parametrable
-    //
-       {
-               int ec = 0;             // enemy count
-               int x = missile->DX / TileSizeX;
-               int y = missile->DY / TileSizeY;
-
-               n = SelectUnits(x - 2, y - 2, x + 2, y + 2, table);
-               if (n == 0)
-               {
-                       return ;
-               }
-           // calculate organic enemy count
-       for (i = 0; i < n; ++i)
-       {
-                       ec += (IsEnemy(source->Player, table[i])
-                       && table[i]->Type->Organic != 0);
-               }
-               if (ec > 0)
-               {       // yes organic enemies found
-                       for (i = 0; i < n; ++i)
-                       {
-                               if (IsEnemy(source->Player, table[i])
-                                   && table[i]->Type->Organic != 0)
-                               {
-                       // disperse damage between them
-                       //NOTE: 1 is the minimal damage
-                                       if (table[i]->HP <= 50 / ec )
-                                       {
-                                               source->Player->Score += 
table[i]->Type->Points;
-                                       if( table[i]->Type->Building )
-                                       {
-                                                       
source->Player->TotalRazings++;
-                                               }
-                                               else
-                                               {
-                                                       
source->Player->TotalKills++;
-                                               }
+       if (source->Orders[0].Action != UnitActionDie) {
+           source->HP += 50;
+           if (source->HP > source->Stats->HitPoints) {
+               source->HP = source->Stats->HitPoints;
+           }
+       }
+    } else {
+//
+//     No target unit -- try enemies in range 5x5 // Must be parametrable
+//
+       int ec = 0;             // enemy count
+       int x = missile->DX / TileSizeX;
+       int y = missile->DY / TileSizeY;
+
+       n = SelectUnits(x - 2, y - 2, x + 2, y + 2, table);
+       if (n == 0) {
+           return ;
+       }
+       // calculate organic enemy count
+       for (i = 0; i < n; ++i) {
+           ec += (IsEnemy(source->Player, table[i])
+           && table[i]->Type->Organic != 0);
+       }
+       if (ec > 0)  {
+           // yes organic enemies found
+           for (i = 0; i < n; ++i) {
+               if (IsEnemy(source->Player, table[i]) && 
table[i]->Type->Organic != 0) {
+                   // disperse damage between them
+                   //NOTE: 1 is the minimal damage
+                   if (table[i]->HP <= 50 / ec ) {
+                       source->Player->Score += table[i]->Type->Points;
+                       if( table[i]->Type->Building ) {
+                           source->Player->TotalRazings++;
+                       } else {
+                           source->Player->TotalKills++;
+                       }
 #ifdef USE_HP_FOR_XP
-                                               source->XP += table[i]->HP;
+                       source->XP += table[i]->HP;
 #else
-                                               source->XP += 
table[i]->Type->Points;
+                       source->XP += table[i]->Type->Points;
 #endif
-                                               ++source->Kills;
-                                               table[i]->HP = 0;
-                                               LetUnitDie(table[i]); // too 
much damage
-                                       }
-                                       else
-                                       {
+                       ++source->Kills;
+                       table[i]->HP = 0;
+                       LetUnitDie(table[i]); // too much damage
+                   } else {
 #ifdef USE_HP_FOR_XP
-                                               source->XP += 50/ec;
+                       source->XP += 50/ec;
 #endif
-                                               table[i]->HP -= 50 / ec;
-                                       }
-                           }
-                       }
-                       if (source->Orders[0].Action!=UnitActionDie)
-                       {
-                               source->HP += 50;
-                               if (source->HP > source->Stats->HitPoints)
-                               {
-                                       source->HP = source->Stats->HitPoints;
-                               }
-                       }
+                       table[i]->HP -= 50 / ec;
+                   }
+               }
+           }
+           if (source->Orders[0].Action!=UnitActionDie) {
+               source->HP += 50;
+               if (source->HP > source->Stats->HitPoints) {
+                   source->HP = source->Stats->HitPoints;
                }
+           }
        }
+    }
 }
 
 /**
@@ -307,32 +278,26 @@
     //
     // Every 4 cycles 4 points damage in tornado center
     //
-    if (!(missile->TTL % 4))
-    {
-               n = SelectUnitsOnTile(x, y, table);
-               for (i = 0; i < n; ++i)
-               {
-                   if (table[i]->HP)
-                   {
-                               HitUnit(missile->SourceUnit,table[i], 
WHIRLWIND_DAMAGE1);// should be missile damage ?
-                   }
-               }
+    if (!(missile->TTL % 4)) {
+       n = SelectUnitsOnTile(x, y, table);
+       for (i = 0; i < n; ++i) {
+           if (table[i]->HP) {
+               HitUnit(missile->SourceUnit,table[i], WHIRLWIND_DAMAGE1);// 
should be missile damage ?
+           }
+       }
     }
     //
     // Every 1/10s 1 points damage on tornado periphery
     //
-    if (!(missile->TTL % (CYCLES_PER_SECOND/10)))
-    {
+    if (!(missile->TTL % (CYCLES_PER_SECOND/10))) {
        // we should parameter this
-               n = SelectUnits(x - 1, y - 1, x + 1, y + 1, table);
-               DebugLevel3Fn("Damage on %d,%d-%d,%d = %d\n" _C_ x-1 _C_ y-1 
_C_ x+1 _C_ y+1 _C_ n);
-               for (i = 0; i < n; ++i)
-               {
-                   if( (table[i]->X != x || table[i]->Y != y) && table[i]->HP)
-                   {
-                               HitUnit(missile->SourceUnit,table[i], 
WHIRLWIND_DAMAGE2); // should be in missile
-                   }
-               }
+       n = SelectUnits(x - 1, y - 1, x + 1, y + 1, table);
+       DebugLevel3Fn("Damage on %d,%d-%d,%d = %d\n" _C_ x-1 _C_ y-1 _C_ x+1 
_C_ y+1 _C_ n);
+       for (i = 0; i < n; ++i) {
+           if( (table[i]->X != x || table[i]->Y != y) && table[i]->HP) {
+               HitUnit(missile->SourceUnit,table[i], WHIRLWIND_DAMAGE2); // 
should be in missile
+           }
+       }
     }
     DebugLevel3Fn( "Whirlwind: %d, %d, TTL: %d\n" _C_
            missile->X _C_ missile->Y _C_ missile->TTL );
@@ -340,7 +305,7 @@
     //
     // Changes direction every 3 seconds (approx.)
     //
-    if (!(missile->TTL % 100)) {       // missile has reached target unit/spot
+    if (!(missile->TTL % 100)) { // missile has reached target unit/spot
        int nx, ny;
 
        do {
@@ -375,23 +340,19 @@
     y = missile->Y / TileSizeY;
 
     n = SelectUnitsOnTile(x, y, table);
-    for (i = 0; i < n; ++i)
-    {
-               if (table[i]->Type->UnitType != UnitTypeFly && table[i]->HP)
-               {
-                   // FIXME: don't use ident!!!
-                   PlayMissileSound(missile, SoundIdForName("explosion"));
-                   MakeMissile(MissileTypeExplosion, missile->X, missile->Y,
-                                               missile->X, missile->Y);
-                   HitUnit(missile->SourceUnit, table[i], RUNE_DAMAGE);
-                   missile->TTL=0;             // Rune can only hit once
-               }
+    for (i = 0; i < n; ++i) {
+       if (table[i]->Type->UnitType != UnitTypeFly && table[i]->HP) {
+           // FIXME: don't use ident!!!
+           PlayMissileSound(missile, SoundIdForName("explosion"));
+           MakeMissile(MissileTypeExplosion, missile->X, missile->Y,
+                                       missile->X, missile->Y);
+           HitUnit(missile->SourceUnit, table[i], RUNE_DAMAGE);
+           missile->TTL=0;             // Rune can only hit once
+       }
     }
     // show rune every 4 seconds (approx.)
-    if (missile->TTL % 100 == 0)
-    {
-               MakeMissile(MissileTypeRune, missile->X, missile->Y,
-                                       missile->X, missile->Y);
+    if (missile->TTL % 100 == 0) {
+       MakeMissile(MissileTypeRune, missile->X, missile->Y,missile->X, 
missile->Y);
     }
 }
 
@@ -409,8 +370,7 @@
        5, 32, 0, 31, -5, 30, -10, 27, -16, 24, -20, 20, -24, 15, -27, 10,
        -30, 5, -31, 0, -32, -5, -31, -10, -30, -16, -27, -20, -24, -24, -20,
        -27, -15, -30, -10, -31, -5, -32, 0, -31, 5, -30, 10, -27, 16, -24,
-       20, -20, 24, -15, 27, -10, 30, -5, 31, 0, 32
-    };
+       20, -20, 24, -15, 27, -10, 30, -5, 31, 0, 32};
     Unit *table[UnitMax];
     int n;
     int i;
@@ -434,33 +394,28 @@
     uh = missile->TargetUnit->Type->Height;
     missile->X = ux * TileSizeX + ix + uw / 2 + dx - 32;
     missile->Y = uy * TileSizeY + iy + uh / 2 + dy - 32 - 16;
-    if (missile->TargetUnit->Orders[0].Action == UnitActionDie)
-    {
-               missile->TTL = i;
+    if (missile->TargetUnit->Orders[0].Action == UnitActionDie) {
+       missile->TTL = i;
     }
-    if (missile->TTL == 0)
-    {
-               missile->TargetUnit->FlameShield = 0;
+    if (missile->TTL == 0) {
+       missile->TargetUnit->FlameShield = 0;
     }
     //vladi: still no have clear idea what is this about :)
     CheckMissileToBeDrawn(missile);
 
     // Only hit 1 out of 8 frames
-    if (missile->TTL & 7)
-    {
-               return;
+    if (missile->TTL & 7) {
+       return;
     }
     n = SelectUnits(ux - 1, uy - 1, ux + 1 + 1, uy + 1 + 1, table);
-    for (i = 0; i < n; ++i)
-    {
-               if (table[i] == missile->TargetUnit)
-               {       // cannot hit target unit
-                       continue;
-               }
-               if (table[i]->HP)
-               {
-                   HitUnit(missile->SourceUnit, table[i], 1);
-               }
+    for (i = 0; i < n; ++i) {
+       if (table[i] == missile->TargetUnit) {
+           // cannot hit target unit
+           continue;
+       }
+       if (table[i]->HP) {
+           HitUnit(missile->SourceUnit, table[i], 1);
+       }
     }
 }
 
@@ -472,82 +427,6 @@
 // Cast the Spell
 // ****************************************************************************
 
-//     Blizzard
-//   NOTE: vladi: blizzard differs than original in this way:
-//   original: launches 50 shards at 5 random spots x 10 for 25 mana.
-
-/**
-**     Cast blizzard.
-**
-**     @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 CastBlizzard(Unit* caster, const SpellType* spell,
-    Unit* target __attribute__((unused)), int x, int y)
-{
-    int fields;
-    int shards;
-    int damage;
-    Missile *mis = NULL;
-    int sx;
-    int sy;
-    int dx;
-    int dy;
-    int i;
-
-    assert(caster);
-    assert(spell);
-    assert(spell->SpellAction);
-    //assert(x in range, y in range);
-
-    fields = spell->SpellAction->Blizzard.Fields;
-    shards = spell->SpellAction->Blizzard.Shards;
-    damage = spell->SpellAction->Blizzard.Damage;
-    while (fields--)
-    {
-       // FIXME : radius configurable...
-               do {
-                   // find new destination in the map
-                   dx = x + SyncRand() % 5 - 2;
-                   dy = y + SyncRand() % 5 - 2;
-               } while (dx < 0 && dy < 0 && dx >= TheMap.Width && dy >= 
TheMap.Height);
-               sx = dx - 4;
-               sy = dy - 4;
-               for (i = 0; i < shards; ++i)
-               {
-                   mis = MakeMissile(spell->Missile,
-                                                           sx * TileSizeX + 
TileSizeX / 2,
-                                                           sy * TileSizeY + 
TileSizeY / 2,
-                                                           dx * TileSizeX + 
TileSizeX / 2,
-                                                           dy * TileSizeY + 
TileSizeY / 2);
-                       if (mis->Type->Speed)
-                       {
-                       mis->Delay = i * mis->Type->Sleep * 2 * TileSizeX / 
mis->Type->Speed;
-                       }
-                       else
-                       {
-                               DebugLevel0Fn("Missile-type '%s' must have 
speed non null" _C_ spell->Missile->Ident);
-                               // Or assert();
-                               // warning : bad conf.
-                       }
-                   mis->Damage = damage;
-                   // FIXME: not correct -- blizzard should continue even if 
mage is
-                   //       destroyed (though it will be quite short time...)
-                   mis->SourceUnit = caster;
-                   RefsDebugCheck(!caster->Refs || caster->Destroyed);
-                   caster->Refs++;
-               }
-    }
-    PlayGameSound(spell->SoundWhenCast.Sound, MaxSampleVolume);
-    caster->Mana -= spell->ManaCost;
-       return caster->Mana > spell->ManaCost;
-}
-
 /**
 **     Cast circle of power.
 **
@@ -559,43 +438,45 @@
 **
 **     @return         =!0 if spell should be repeated, 0 if not
 */
-global int CastCircleOfPower(Unit* caster, const SpellType* spell 
__attribute__((unused)),
+global int CastSpawnPortal(Unit* caster, const SpellType* spell 
__attribute__((unused)),
     Unit* target __attribute__((unused)), int x, int y)
 {
     // FIXME: vladi: cop should be placed only on explored land
-    Unit *cop = NULL;
-    UnitType *ucop = spell->SpellAction->SpawnPortal.PortalType;
-
+    Unit *portal;
+    UnitType *ptype;
+    
     assert(caster);
     assert(spell);
     assert(spell->SpellAction);
     assert(spell->SpellAction->SpawnPortal.PortalType);
-//     assert(x in range, y in range);
 
-    cop = caster->Goal;
-    if (cop)
-    {
-               // FIXME: if cop is already defined --> move it, but it doesn't 
work?
-               RemoveUnit(cop, NULL);
-               PlaceUnit(cop, x, y);
-    }
-    else
-    {
-               cop = MakeUnitAndPlace(x, y, ucop, &Players[PlayerMax - 1]);
+    ptype = spell->SpellAction->SpawnPortal.PortalType;
+
+    portal = caster->Goal;
+    if (portal) {
+       // FIXME: if cop is already defined --> move it, but it doesn't work?
+       RemoveUnit(portal, NULL);
+       PlaceUnit(portal, x, y);
+    } else {
+       portal = MakeUnitAndPlace(x, y, ptype, &Players[PlayerMax - 1]);
     }
-           MakeMissile(spell->Missile,
-               x * TileSizeX + TileSizeX / 2, y * TileSizeY + TileSizeY / 2,
-               x * TileSizeX + TileSizeX / 2, y * TileSizeY + TileSizeY / 2);
-    // Next is used to link to destination circle of power
-    caster->Goal = cop;
-    RefsDebugCheck(!cop->Refs || cop->Destroyed);
-    cop->Refs++;
+    MakeMissile(spell->Missile,
+           x * TileSizeX + TileSizeX / 2, y * TileSizeY + TileSizeY / 2,
+           x * TileSizeX + TileSizeX / 2, y * TileSizeY + TileSizeY / 2);
+    //  Goal is used to link to destination circle of power
+    caster->Goal = portal;
+    RefsDebugCheck(!portal->Refs || portal->Destroyed);
+    portal->Refs++;
     //FIXME: setting destination circle of power should use mana
     return 0;
 }
 
+//     AreaBombardment
+//   NOTE: vladi: blizzard differs than original in this way:
+//   original: launches 50 shards at 5 random spots x 10 for 25 mana.
+
 /**
-**     Cast death and decay.
+**     Cast blizzard.
 **
 **     @param caster   Unit that casts the spell
 **     @param spell    Spell-type pointer
@@ -604,53 +485,61 @@
 **     @param y        Y coord of target spot when/if target does not exist
 **
 **     @return         =!0 if spell should be repeated, 0 if not
-**     @todo   unify DeathAndDecay and blizzard function. (if possible)
 */
-global int CastDeathAndDecay(Unit* caster, const SpellType* spell,
+global int CastAreaBombardment(Unit* caster, const SpellType* spell,
     Unit* target __attribute__((unused)), int x, int y)
 {
-    int fields;                        // blizzard thing, yep :)
+    int fields;
     int shards;
-       int damage;
+    int damage;
     Missile *mis = NULL;
+    int offsetx;
+    int offsety;
     int dx;
     int dy;
     int i;
 
-       assert(caster);
-       assert(spell);
-       assert(spell->SpellAction);
-//     assert(x in range, y in range);
-
-    fields = spell->SpellAction->DeathAndDecay.Fields;
-    shards = spell->SpellAction->DeathAndDecay.Shards;
-    damage = spell->SpellAction->DeathAndDecay.Damage;
-    while (fields--)
-    {
-               do {
-                   // find new destination in the map
-                   dx = x + SyncRand() % 5 - 2;
-                   dy = y + SyncRand() % 5 - 2;
-               } while (dx < 0 && dy < 0 && dx >= TheMap.Width && dy >= 
TheMap.Height);
-               for (i = 0; i < shards; ++i)
-               {
-                   mis = MakeMissile(spell->Missile,
-                           dx * TileSizeX + TileSizeX / 2, dy * TileSizeY + 
TileSizeY / 2,
-                           dx * TileSizeX + TileSizeX / 2, dy * TileSizeY + 
TileSizeY / 2);
-                   mis->Damage = damage;
-                   //FIXME: not correct -- death and decay should continue 
even if
-                   //       death knight is destroyed (though it will be quite
-                   //       short time...)
-                   mis->Delay = i * mis->Type->Sleep
-                           * VideoGraphicFrames(mis->Type->Sprite);
-                   mis->SourceUnit = caster;
-                   RefsDebugCheck(!caster->Refs || caster->Destroyed);
-                   caster->Refs++;
-               }
+    assert(caster);
+    assert(spell);
+    assert(spell->SpellAction);
+    //assert(x in range, y in range);
+
+    fields = spell->SpellAction->AreaBombardment.Fields;
+    shards = spell->SpellAction->AreaBombardment.Shards;
+    damage = spell->SpellAction->AreaBombardment.Damage;
+    offsetx = spell->SpellAction->AreaBombardment.StartOffsetX;
+    offsety = spell->SpellAction->AreaBombardment.StartOffsetY;
+    while (fields--) {
+       // FIXME : radius configurable...
+       do {
+           // find new destination in the map
+           dx = x + SyncRand() % 5 - 2;
+           dy = y + SyncRand() % 5 - 2;
+       } while (dx < 0 && dy < 0 && dx >= TheMap.Width && dy >= TheMap.Height);
+       for (i = 0; i < shards; ++i) {
+           mis = MakeMissile(spell->Missile,
+                   dx * TileSizeX + TileSizeX / 2 + offsetx,
+                   dy * TileSizeY + TileSizeY / 2 + offsety,
+                   dx * TileSizeX + TileSizeX / 2,
+                   dy * TileSizeY + TileSizeY / 2);
+           //  FIXME: This is just patched up, it works, but I have no idea 
why.
+           //  FIXME: What is the reasoning behind all this?
+           if (mis->Type->Speed) {
+               mis->Delay = i * mis->Type->Sleep * 2 * TileSizeX / 
mis->Type->Speed;
+           } else {
+               mis->Delay = i * mis->Type->Sleep * 
VideoGraphicFrames(mis->Type->Sprite);
+           }
+           mis->Damage = damage;
+           // FIXME: not correct -- blizzard should continue even if mage is
+           //       destroyed (though it will be quite short time...)
+           mis->SourceUnit = caster;
+           RefsDebugCheck(!caster->Refs || caster->Destroyed);
+           caster->Refs++;
        }
+    }
     PlayGameSound(spell->SoundWhenCast.Sound, MaxSampleVolume);
     caster->Mana -= spell->ManaCost;
-    return (caster->Mana > spell->ManaCost);
+    return caster->Mana > spell->ManaCost;
 }
 
 /**
@@ -664,8 +553,7 @@
 **
 **     @return         =!0 if spell should be repeated, 0 if not
 */
-global int CastDeathCoil(Unit* caster, const SpellType* spell, Unit* target,
-    int x, int y)
+global int CastDeathCoil(Unit* caster, const SpellType* spell, Unit* 
target,int x, int y)
 {
     Missile *mis = NULL;
     int sx = caster->X;
@@ -674,20 +562,19 @@
     assert(caster);
     assert(spell);
     assert(spell->SpellAction);
-//     assert(target);
-//     assert(x in range, y in range);
+// assert(target);
+// assert(x in range, y in range);
 
     caster->Mana -= spell->ManaCost;
 
     PlayGameSound(spell->SoundWhenCast.Sound, MaxSampleVolume);
     mis = MakeMissile(spell->Missile,
-       sx * TileSizeX + TileSizeX / 2, sy * TileSizeY + TileSizeY / 2,
-       x * TileSizeX + TileSizeX / 2, y * TileSizeY + TileSizeY / 2);
+           sx * TileSizeX + TileSizeX / 2, sy * TileSizeY + TileSizeY / 2,
+           x * TileSizeX + TileSizeX / 2, y * TileSizeY + TileSizeY / 2);
     mis->SourceUnit = caster;
     RefsDebugCheck(!caster->Refs || caster->Destroyed);
     caster->Refs++;
-    if (target)
-    {
+    if (target) {
        mis->TargetUnit = target;
        RefsDebugCheck(!target->Refs || target->Destroyed);
        target->Refs++;
@@ -715,18 +602,16 @@
     int sy;
     int dist;
 
-       assert(caster);
-       assert(spell);
-       assert(spell->SpellAction);
-//     assert(target);
-//     assert(x in range, y in range);
-       assert(spell->Missile);
+    assert(caster);
+    assert(spell);
+    assert(spell->SpellAction);
+    assert(spell->Missile);
 
     // NOTE: fireball can be casted on spot
     sx = caster->X;
     sy = caster->Y;
     dist = MapDistance(sx, sy, x, y);
-       assert(dist != 0);
+    assert(dist != 0);
     x += ((x - sx) * 10) / dist;
     y += ((y - sy) * 10) / dist;
     sx = sx * TileSizeX + TileSizeX / 2;
@@ -759,29 +644,28 @@
 global int CastFlameShield(Unit* caster, const SpellType* spell, Unit* target,
     int x __attribute__((unused)), int y __attribute__((unused)))
 {
-       Missile* mis = NULL;
-       int     i;
+    Missile* mis = NULL;
+    int        i;
 
-       assert(caster);
-       assert(spell);
-       assert(spell->SpellAction);
-       assert(target);
-//     assert(x in range, y in range);
-       assert(spell->Missile);
-
-       // get mana cost
-       caster->Mana -= spell->ManaCost;
-       target->FlameShield = spell->SpellAction->FlameShield.TTL;
-       PlayGameSound(spell->SoundWhenCast.Sound, MaxSampleVolume);
-       for (i = 0; i < 5; i++)
-       {
-               mis = MakeMissile(spell->Missile, 0, 0, 0, 0);
-               mis->TTL = spell->SpellAction->FlameShield.TTL + i * 7;
-               mis->TargetUnit = target;
-               mis->Controller = SpellFlameShieldController;
-               RefsDebugCheck(!target->Refs || target->Destroyed);
-               target->Refs++;
-       }
+    assert(caster);
+    assert(spell);
+    assert(spell->SpellAction);
+    assert(target);
+//  assert(x in range, y in range);
+    assert(spell->Missile);
+
+    // get mana cost
+    caster->Mana -= spell->ManaCost;
+    target->FlameShield = spell->SpellAction->FlameShield.TTL;
+    PlayGameSound(spell->SoundWhenCast.Sound, MaxSampleVolume);
+    for (i = 0; i < 5; i++) {
+       mis = MakeMissile(spell->Missile, 0, 0, 0, 0);
+       mis->TTL = spell->SpellAction->FlameShield.TTL + i * 7;
+       mis->TargetUnit = target;
+       mis->Controller = SpellFlameShieldController;
+       RefsDebugCheck(!target->Refs || target->Destroyed);
+       target->Refs++;
+    }
     return 0;
 }
 
@@ -799,93 +683,69 @@
 global int CastHaste(Unit* caster, const SpellType* spell, Unit* target,
     int x, int y)
 {
-       struct s_haste  *haste;
+    struct s_haste     *haste;
 
-       assert(caster);
-       assert(spell);
-       assert(spell->SpellAction);
-       assert(target);
-
-       // 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)
-                               {
-                                       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)
-                               {
-                                       target->Mana = target->Type->_MaxMana;
-                               }
-                               break;
-                       }
-                       default:
-                       {
-                               // Warn devellopers
-                               assert(0);
-                       }
+    assert(caster);
+    assert(spell);
+    assert(spell->SpellAction);
+    assert(target);
+
+    // 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:
+               // Warn devellopers
+               assert(0);
        }
-       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;
+    }
+    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;
 }
 
 /**
@@ -899,54 +759,49 @@
 **
 **     @return         =!0 if spell should be repeated, 0 if not
 */
-global int CastHealing(Unit* caster, const SpellType* spell, Unit* target,
-    int x, int y)
+global int CastHealing(Unit* caster, const SpellType* spell, Unit* target,int 
x, int y)
 {
-       int     i;
-       int     diffHP;
-       int diffMana = caster->Mana;
-       int     HP = spell->SpellAction->healing.HP;
-       int Mana = spell->ManaCost;
-
-       assert(caster);
-       assert(spell);
-       assert(spell->SpellAction);
-       assert(target);
-
-       // 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
+    int i;
+    int diffHP;
+    int diffMana = caster->Mana;
+    int HP = spell->SpellAction->healing.HP;
+    int Mana = spell->ManaCost;
+
+    assert(caster);
+    assert(spell);
+    assert(spell->SpellAction);
+    assert(target);
+
+    // 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;
-       if (HP < 0)
-       {
+
+    if (HP < 0) {
 #ifdef USE_HP_FOR_XP
-               caster->XP += i * HP;
+       caster->XP += i * HP;
 #endif
-               if (!target->HP)
-               {
-                   caster->Player->Score += target->Type->Points;
-                   if (target->Type->Building)
-                   {
-                               caster->Player->TotalRazings++;
-                   }
-                   else
-                   {
-                               caster->Player->TotalKills++;
-                   }
+       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;
+           caster->XP += target->Type->Points;
 #endif
-                   caster->Kills++;
-                   LetUnitDie(target);
-               }
+           caster->Kills++;
+           LetUnitDie(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);
+    }
+    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;
 }
 
@@ -961,16 +816,15 @@
 **
 **     @return         =!0 if spell should be repeated, 0 if not
 */
-global int CastHolyVision(Unit* caster, const SpellType* spell, Unit* target,
-    int x, int y)
+global int CastHolyVision(Unit* caster, const SpellType* spell, Unit* 
target,int x, int y)
 {
-       assert(caster);
-       assert(spell);
-       assert(spell->SpellAction);
-//     assert(x in range, y in range);
+    assert(caster);
+    assert(spell);
+    assert(spell->SpellAction);
+//  assert(x in range, y in range);
 
     caster->Mana -= spell->ManaCost;   // get mana cost
-    // FIXME Do a fonction to reveal map (use for attack revealer) instead of 
create unit
+    // FIXME: compact with summon.
     target = MakeUnit(spell->SpellAction->holyvision.revealer, caster->Player);
     target->Orders[0].Action = UnitActionStill;
     target->HP = 0;
@@ -997,53 +851,44 @@
 **
 **     @return         =!0 if spell should be repeated, 0 if not
 */
-global int CastInvisibility(Unit* caster, const SpellType* spell, Unit* target,
-    int x, int y)
+global int CastInvisibility(Unit* caster, const SpellType* spell, Unit* 
target,int x, int y)
 {
-       assert(caster);
-       assert(spell);
-       assert(spell->SpellAction);
-       assert(target);
-       assert(spell->SpellAction->invisibility.missile);
-
-       // 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;
-                       }
-                       case flag_unholyarmor:
-                       {
-                               target->UnholyArmor = 
spell->SpellAction->invisibility.value;
-                               target->UnholyArmor /= CYCLES_PER_SECOND;
-                       }
-                       default:
-                       {
-                               assert(0);
-                               // Warn devellopers
-                       }
-               }
-               CheckUnitToBeDrawn(target);
+    assert(caster);
+    assert(spell);
+    assert(spell->SpellAction);
+    assert(target);
+    assert(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!!!
+               assert(0);
        }
-       PlayGameSound(spell->SoundWhenCast.Sound,MaxSampleVolume);
-       MakeMissile(spell->Missile,
-                               x * TileSizeX + TileSizeX / 2, y * TileSizeY + 
TileSizeY / 2,
-                               x * TileSizeX + TileSizeX / 2, y * TileSizeY + 
TileSizeY / 2 );
+       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;
 }
 
@@ -1058,47 +903,42 @@
 **
 **     @return         =!0 if spell should be repeated, 0 if not
 */
-global int CastPolymorph(Unit* caster, const SpellType* spell, Unit* target,
-    int x, int y)
+global int CastPolymorph(Unit* caster, const SpellType* spell, Unit* 
target,int x, int y)
 {
-       UnitType* type = spell->SpellAction->polymorph.unit;
+    UnitType* type = spell->SpellAction->Polymorph.NewForm;
 
-       assert(caster);
-       assert(spell);
-       assert(spell->SpellAction);
-       assert(target);
-       assert(spell->SpellAction->polymorph.unit);
-
-       caster->Player->Score += target->Type->Points;
-       if (target->Type->Building)
-       {
-       caster->Player->TotalRazings++;
-       }
-       else
-       {
-       caster->Player->TotalKills++;
-       }
+    assert(caster);
+    assert(spell);
+    assert(spell->SpellAction);
+    assert(target);
+    assert(type);
+
+    caster->Player->Score += target->Type->Points;
+    if (target->Type->Building) {
+       caster->Player->TotalRazings++;
+    } else {
+       caster->Player->TotalKills++;
+    }
 #ifdef USE_HP_FOR_XP
-       caster->XP += target->HP;
+    caster->XP += target->HP;
 #else
-       caster->XP += target->Type->Points;
+    caster->XP += target->Type->Points;
 #endif
-       caster->Kills++;
-       // as said somewhere else -- no corpses :)
-       RemoveUnit(target,NULL);
-       UnitLost(target);
-       UnitClearOrders(target);
-       ReleaseUnit(target);
-       if (UnitTypeCanMoveTo(x, y, type))
-       {
-           MakeUnitAndPlace(x, y, type, Players + PlayerNumNeutral);
-       }
-       caster->Mana -= spell->ManaCost;
-       PlayGameSound(spell->SoundWhenCast.Sound, MaxSampleVolume);
-       MakeMissile(spell->Missile,
+    caster->Kills++;
+    // as said somewhere else -- no corpses :)
+    RemoveUnit(target,NULL);
+    UnitLost(target);
+    UnitClearOrders(target);
+    ReleaseUnit(target);
+    if (UnitTypeCanMoveTo(x, y, type)) {
+       MakeUnitAndPlace(x, y, type, Players + PlayerNumNeutral);
+    }
+    caster->Mana -= spell->ManaCost;
+    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;
+    return 0;
 }
 
 /**
@@ -1112,47 +952,49 @@
 **
 **     @return         =!0 if spell should be repeated, 0 if not
 */
-global int CastRaiseDead(Unit* caster, const SpellType* spell, Unit* target,
-    int x, int y)
+global int CastRaiseDead(Unit* caster, const SpellType* spell, Unit* 
target,int x, int y)
 {
     Unit **corpses;
     Unit *tempcorpse;
     UnitType *skeleton;
 
-       assert(caster);
-       assert(spell);
-       assert(spell->SpellAction);
-       assert(spell->SpellAction->raisedead.skeleton != NULL);
-//     assert(x in range, y in range);
-    skeleton = spell->SpellAction->raisedead.skeleton;
+    assert(caster);
+    assert(spell);
+    assert(spell->SpellAction);
+//  assert(x in range, y in range);
+    skeleton = spell->SpellAction->RaiseDead.Skeleton;
+    assert(skeleton);
 
     corpses = &CorpseList;
 
-    while (caster->Mana >= spell->ManaCost && *corpses)
-    {
+    while (*corpses) {
        // FIXME: this tries to raise all corps, ohje
        // FIXME: I can raise ships?
-               if ((*corpses)->Orders[0].Action == UnitActionDie
-                       && !(*corpses)->Type->Building
-                       && (*corpses)->X >= x - 1 && (*corpses)->X <= x + 1
-                       && (*corpses)->Y >= y - 1 && (*corpses)->Y <= y + 1)
-               {
-                   // FIXME: did they count on food?
-                   // Can there be more than 1 skeleton created on the same 
tile? yes
-                   target = MakeUnit(skeleton, caster->Player);
-                   target->X = (*corpses)->X;
-                   target->Y = (*corpses)->Y;
-                   DropOutOnSide(target,LookingW,0,0);
-                   // set life span
-                   target->TTL = GameCycle + target->Type->DecayRate * 6 * 
CYCLES_PER_SECOND;
-                   CheckUnitToBeDrawn(target);
-                   tempcorpse = *corpses;
-                   corpses = &(*corpses)->Next;
-                   ReleaseUnit(tempcorpse);
-                   caster->Mana -= spell->ManaCost;
-                   corpses = &(*corpses)->Next;
+       if ((*corpses)->Orders[0].Action == UnitActionDie
+               && !(*corpses)->Type->Building
+               && (*corpses)->X >= x - 1 && (*corpses)->X <= x + 1
+               && (*corpses)->Y >= y - 1 && (*corpses)->Y <= y + 1) {
+           // FIXME: did they count on food?
+           // nobody: unlikely.
+           // Can there be more than 1 skeleton created on the same tile? yes
+           target = MakeUnit(skeleton, caster->Player);
+           target->X = (*corpses)->X;
+           target->Y = (*corpses)->Y;
+           DropOutOnSide(target,LookingW,0,0);
+           // set life span
+           target->TTL = GameCycle + target->Type->DecayRate * 6 * 
CYCLES_PER_SECOND;
+           CheckUnitToBeDrawn(target);
+           tempcorpse = *corpses;
+           corpses = &(*corpses)->Next;
+           ReleaseUnit(tempcorpse);
+           caster->Mana -= spell->ManaCost;
+           if (caster->Mana<spell->ManaCost) {
+               break;
            }
+       } else {
+           corpses=&(*corpses)->Next;
        }
+    }
     PlayGameSound(spell->SoundWhenCast.Sound, MaxSampleVolume);
     MakeMissile(spell->Missile,
            x*TileSizeX+TileSizeX/2, y*TileSizeY+TileSizeY/2,
@@ -1172,44 +1014,43 @@
 **     @return         =!0 if spell should be repeated, 0 if not
 */
 global int CastRunes(Unit* caster, const SpellType* spell,
-    Unit* target __attribute__((unused)), int x, int y)
+       Unit* target __attribute__((unused)), int x, int y)
 {
     Missile *mis = NULL;
-       const int       xx[] = {-1, +1, 0, 0, 0};
-       const int       yy[] = {0, 0, 0, -1, +1};
 
-       int     oldx = x;
-       int     oldy = y;
-       int     i;
-
-       assert(caster);
-       assert(spell);
-       assert(spell->SpellAction);
-//     assert(x in range, y in range);
+    const int xx[] = {-1,+1, 0, 0, 0};
+    const int yy[] = { 0, 0, 0,-1,+1};
+
+    int oldx = x;
+    int oldy = y;
+    int i;
+
+    assert(caster);
+    assert(spell);
+    assert(spell->SpellAction);
+//  assert(x in range, y in range);
 
     PlayGameSound(spell->SoundWhenCast.Sound, MaxSampleVolume);
-       for (i = 0; i < 5; i++)
-       {
-               x = oldx + xx[i];
-               y = oldy + yy[i];
-               
-           if (IsMapFieldEmpty(x - 1, y + 0))
-           {
-                       mis = MakeMissile(spell->Missile,
-                                                               x * TileSizeX + 
TileSizeX / 2,
-                                                               y * TileSizeY + 
TileSizeY / 2,
-                                                               x * TileSizeX + 
TileSizeX / 2,
-                                                               y * TileSizeY + 
TileSizeY / 2);
-                       mis->TTL = spell->SpellAction->runes.TTL;
-                       mis->Controller = SpellRunesController;
-                       caster->Mana -= spell->ManaCost / 5;
-           }
+    for (i = 0; i < 5; i++) {
+       x = oldx + xx[i];
+       y = oldy + yy[i];
+           
+       if (IsMapFieldEmpty(x - 1, y + 0)) {
+           mis = MakeMissile(spell->Missile,
+                   x * TileSizeX + TileSizeX / 2,
+                   y * TileSizeY + TileSizeY / 2,
+                   x * TileSizeX + TileSizeX / 2,
+                   y * TileSizeY + TileSizeY / 2);
+           mis->TTL = spell->SpellAction->runes.TTL;
+           mis->Controller = SpellRunesController;
+           caster->Mana -= spell->ManaCost / 5;
        }
+    }
     return 0;
 }
 
 /**
-**     Cast eye of vision. (summon)
+**     Cast summon spell.
 **
 **     @param caster   Unit that casts the spell
 **     @param spell    Spell-type pointer
@@ -1222,15 +1063,15 @@
 global int CastSummon(Unit* caster, const SpellType* spell, Unit* target,
     int x, int y)
 {
-       assert(caster);
-       assert(spell);
-       assert(spell->SpellAction);
-       assert(spell->SpellAction->summon.unittype != NULL);
-//     assert(x in range, y in range);
+    assert(caster);
+    assert(spell);
+    assert(spell->SpellAction);
+    assert(spell->SpellAction->Summon.UnitType != NULL);
+//  assert(x in range, y in range);
 
     caster->Mana -= spell->ManaCost;
     // FIXME: johns: the unit is placed on the wrong position
-    target = MakeUnit(spell->SpellAction->summon.unittype, caster->Player);
+    target = MakeUnit(spell->SpellAction->Summon.UnitType, caster->Player);
     target->X = x;
     target->Y = y;
     DropOutOnSide(target, LookingW, 0, 0);
@@ -1262,16 +1103,16 @@
 {
     Missile *mis = NULL;
 
-       assert(caster);
-       assert(spell);
-       assert(spell->SpellAction);
-//     assert(x in range, y in range);
+    assert(caster);
+    assert(spell);
+    assert(spell->SpellAction);
+//  assert(x in range, y in range);
 
     caster->Mana -= spell->ManaCost;
     PlayGameSound(spell->SoundWhenCast.Sound, MaxSampleVolume);
     mis = MakeMissile(spell->Missile,
-               x * TileSizeX + TileSizeX / 2, y * TileSizeY + TileSizeY / 2,
-               x * TileSizeX + TileSizeX / 2, y * TileSizeY + TileSizeY / 2);
+           x * TileSizeX + TileSizeX / 2, y * TileSizeY + TileSizeY / 2,
+           x * TileSizeX + TileSizeX / 2, y * TileSizeY + TileSizeY / 2);
     mis->TTL = spell->SpellAction->whirlwind.TTL;
     mis->Controller = SpellWhirlwindController;
     return 0;
@@ -1281,168 +1122,118 @@
 //     Specific conditions
 // ****************************************************************************
 
-/* *************************************
-** property of unittype himself
+/*
+**     Check for unittype properties of unittype himself
 */
-global int             CheckUnitTypeFlag(const t_Conditions    *condition,
-                                                                       const 
Unit* caster,
-                                                                       const 
Unit* target, int x, int y)
-{
-       assert(caster != NULL);
-       assert(condition != NULL);
-
-       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:
-               {
-                       assert(0);
-                       // Warn devellopers
-               }
-       }
+global int CheckUnitTypeFlag(const t_Conditions        *condition,
+       const Unit* caster,const Unit* target, int x, int y)
+{
+    assert(caster != NULL);
+    assert(condition != NULL);
+
+    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:
+           assert(0);
+           // Warn devellopers
+    }
 }
 
-/* *************************************
-** property of alliance
+/*
+**     Check for alliance status.
 */
-global int             CheckAllied(const t_Conditions  *condition,
-                                                       const Unit* caster,
-                                                       const Unit* target, int 
x, int y)
+global int CheckAllied(const t_Conditions *condition,const Unit* caster,const 
Unit* target, int x, int y)
 {
-       assert(caster != NULL);
-
-       return caster->Player == target->Player
-               ||IsAllied(caster->Player, target) ? 1 : 0;
+    assert(caster != NULL);
+    return caster->Player == target->Player || IsAllied(caster->Player, 
target) ? 1 : 0;
 }
 
-/* *************************************
-** property of alliance
+/*
+**     Check if target is self
 */
-global int             Checkhimself(const t_Conditions *condition,
-                                                       const Unit* caster,
-                                                       const Unit* target, int 
x, int y)
+global int Checkhimself(const t_Conditions *condition,const Unit* caster,const 
Unit* target, int x, int y)
 {
-       assert(caster != NULL);
-
-       return caster == target;
+    assert(caster != NULL);
+    return caster == target;
 }
 
-/* *************************************
-** property of target unit itself (no type specific)
+/*
+**     Check duration effects.
 */
-global int             CheckUnitDurationEffect(const t_Conditions      
*condition,
-                                                                               
const Unit* caster,
-                                                                               
const Unit* target, int x, int y)
+global int CheckUnitDurationEffect(const t_Conditions *condition,const Unit* 
caster,const Unit* target, int x, int y)
 {
-       int     ttl;
-       assert(condition);
-       ttl = condition->u.durationeffect.ttl;
+    int ttl;
+    assert(condition);
+    ttl = condition->u.durationeffect.ttl;
 
-       if (target == NULL)
-               return !condition->expectvalue;
+    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
-               }
-               /// Add here the other cases
-               default:
-               {
-                       abort();
-                       // Warn devellopers
-               }
-       }
+    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:
+           abort();
+           // Warn devellopers
+    }
 }
 
 // ****************************************************************************
 //     Specific conditions
 // ****************************************************************************
 
-global int     CheckEnemyPresence(const t_Conditions   *condition,
-                                                       const Unit* caster)
+global int CheckEnemyPresence(const t_Conditions *condition,const Unit* caster)
 {
-       Unit* table[UnitMax];
+    Unit* table[UnitMax];
     int i;
     int n;
-       int range = condition->u.range;
-       int     x = caster->X;
-       int     y = caster->Y;
+    int range = condition->u.range;
+    int        x = caster->X;
+    int        y = caster->Y;
 
-       assert(condition != NULL);
-       assert(caster != NULL);
+    assert(condition != NULL);
+    assert(caster != NULL);
        
 // +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;
-               }
+    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;
+    }
+    return 0;
 }
 
 // ****************************************************************************
@@ -1451,7 +1242,7 @@
 
 local Target *NewTarget(TargetType t, const Unit *unit, int x, int y)
 {
-    Target     *target = (Target *) malloc(sizeof(*target));
+    Target *target = (Target *) malloc(sizeof(*target));
 
     assert(!(unit == NULL && t == TargetUnit));
     assert(!(!(0 <= x && x < TheMap.Width) && t == TargetPosition));
@@ -1469,15 +1260,14 @@
     return NewTarget(TargetNone, NULL, 0, 0);
 }
 
-local Target   *NewTargetUnit(const Unit *unit)
+local Target *NewTargetUnit(const Unit *unit)
 {
     assert(unit != NULL);
-
     return NewTarget(TargetUnit, unit, 0, 0);
 }
 
 
-local Target   *NewTargetPosition(int x, int y)
+local Target *NewTargetPosition(int x, int y)
 {
     assert(0 <= x && x < TheMap.Width);
     assert(0 <= y && y < TheMap.Height);
@@ -1494,30 +1284,27 @@
 */
 local int PassGenericCondition(const Unit* caster,const SpellType* spell,const 
t_Conditions *condition)
 {
-//     const t_Conditions      *condition = NULL;
-       int     ret;
+    int ret;
 
-       assert(caster != NULL);
-       assert(spell != NULL);
+    assert(caster != NULL);
+    assert(spell != NULL);
 
-       // FIXME : Move it in spell->Condition_generic ???
-       // mana is a must!
-    if (caster->Mana < spell->ManaCost)
-       {
-               return 0;
-       }
-       for (/*condition = spell->Condition_generic*/; condition != NULL; 
condition = condition->next)
-       {
-               assert(condition->f.generic != NULL);
-               ret = condition->f.generic(condition, caster);
-               assert(ret == 0 || ret == 1);
-               assert(condition->expectvalue == 0 || condition->expectvalue == 
1);
-               if (ret != condition->expectvalue)
-               {
-                       return 0;
-               }
+    // FIXME : Move it in spell->Condition_generic ???
+    // mana is a must!
+    if (caster->Mana < spell->ManaCost) {
+       return 0;
+    }
+    for (/*condition = spell->Condition_generic*/; condition != NULL; 
condition = condition->next)
+    {
+       assert(condition->f.generic != NULL);
+       ret = condition->f.generic(condition, caster);
+       assert(ret == 0 || ret == 1);
+       assert(condition->expectvalue == 0 || condition->expectvalue == 1);
+       if (ret != condition->expectvalue) {
+           return 0;
        }
-       return 1;
+    }
+    return 1;
 }
 
 /**
@@ -1525,36 +1312,29 @@
 **     @return 1 if condition is ok.
 **     @return 0 else.
 */
-local int              PassSpecificCondition(const Unit* caster,
-                                                                               
const SpellType* spell,
-                                                                           
const Unit* target,         // FIXME : Use an unique struture t_Target ?
-                                                                               
int x,
-                                                                           int 
y,
-                                                                               
const t_Conditions *condition)
-{
-//     const t_Conditions      *condition = NULL;
-       int     ret;
-
-       assert(caster != NULL);
-       assert(spell != NULL);
-
-       for (/*condition = spell->Condition_specific*/; condition != NULL; 
condition = condition->next)
-       {
-               assert(condition->f.specific != NULL);
-               ret = condition->f.specific(condition, caster, target, x, y);
-               assert(ret == 0 || ret == 1);
-               assert(condition->expectvalue == 0 || condition->expectvalue == 
1);
-               if (ret != condition->expectvalue)
-               {
-                       return 0;
-               }
+local int PassSpecificCondition(const Unit* caster,const SpellType* spell,
+       const Unit* target,int x,int y,const t_Conditions *condition)
+{
+    int ret;
+
+    assert(caster != NULL);
+    assert(spell != NULL);
+
+    for (/*condition = spell->Condition_specific*/; condition != NULL; 
condition = condition->next) {
+       assert(condition->f.specific != NULL);
+       ret = condition->f.specific(condition, caster, target, x, y);
+       assert(ret == 0 || ret == 1);
+       assert(condition->expectvalue == 0 || condition->expectvalue == 1);
+       if (ret != condition->expectvalue) {
+           return 0;
        }
-       return 1;
+    }
+    return 1;
 }
 
 
 /**
-**      Select the target for the autocast.
+**     Select the target for the autocast.
 **
 **     @param caster   Unit who would cast the spell.
 **     @param spell    Spell-type pointer.
@@ -1562,88 +1342,71 @@
 **     @return Target* choosen target or Null if spell can't be cast.
 **
 */
-// should be global (for IA) ???
-local Target   *SelectTargetUnitsOfAutoCast(const Unit *caster,
-                                                                               
        const SpellType *spell)
-{
-       assert(spell != NULL);
-       assert(spell->AutoCast != NULL);
-       assert(caster != NULL);
-
-       switch (spell->Target)
-       {
-               case    TargetSelf :
-               {
-                       return NewTargetUnit(caster);
-               }
-               case    TargetNone :
-               {
-                       return NewTargetNone();
-               }
-               case    TargetPosition:
-               {
-                       int x, y;
-                       int range = spell->AutoCast->Range;
-
-                       do
-                       {
-                               x = caster->X + SyncRand() % (2 * range) - 
range;
-                               y = caster->Y + SyncRand() % (2 * range) - 
range;
-                       } while (x < 0 && x <= TheMap.Width
-                                       && y < 0 && y <= TheMap.Height);
-                       
-                       // FIXME : CHOOSE a better POSITION (add info in 
structure ???)
-                       // Just good enought for holyvision...
-                       return NewTargetPosition(SyncRand() % TheMap.Width,
-                                                                       
SyncRand() % TheMap.Height);
+// should be global (for AI) ???
+local Target *SelectTargetUnitsOfAutoCast(const Unit *caster,const SpellType 
*spell)
+{
+    Unit* table[UnitMax];
+    int x;
+    int y;
+    int range;
+    int nb_units;
+    int i;
+    int j;
+
+    assert(spell != NULL);
+    assert(spell->AutoCast != NULL);
+    assert(caster != NULL);
+
+    switch (spell->Target) {
+       case TargetSelf :
+           return NewTargetUnit(caster);
+       case TargetNone :
+           return NewTargetNone();
+       case TargetPosition:
+           range = spell->AutoCast->Range;
+           do {
+               x = caster->X + SyncRand() % (2 * range) - range;
+               y = caster->Y + SyncRand() % (2 * range) - range;
+           } while (x < 0 && x <= TheMap.Width
+                           && y < 0 && y <= TheMap.Height);
+           
+           // FIXME : CHOOSE a better POSITION (add info in structure ???)
+           // Just good enought for holyvision...
+           return NewTargetPosition(x, y);
+       case TargetUnit:
+           x=caster->X;
+           y=caster->Y;
+           range=spell->AutoCast->Range;
+           // ( + 1) would be ( + caster->size) ??
+           nb_units = SelectUnits(caster->X - range, caster->Y - range,
+               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))
 {
+                       table[j++] = table[i];
                }
-               case    TargetUnit:
-               {
-                   Unit* table[UnitMax];
-                   int range = spell->AutoCast->Range;
-                   int nb_units;
-                       int     x = caster->X;
-                       int     y = caster->Y;
-                       int i, j;
-                       // ( + 1) would be ( + caster->size) ??
-                   nb_units = SelectUnits(caster->X - range, caster->Y - range,
-                                                               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))
-                               {
-                                       table[j++] = table[i];
-                               }
-                       }
-                       nb_units = j;
-                       if (nb_units != 0)
-                       {
+           }
+           nb_units = j;
+           if (nb_units != 0) {
 #if 0
 // For the best target
-                               sort(table, nb_units, spell->autocast->f_order);
-                               return NewTargetUnit(table[0]);
+               sort(table, nb_units, spell->autocast->f_order);
+               return NewTargetUnit(table[0]);
 #else
 // For a random valid target
-                               i = SyncRand() % nb_units;
-                               return NewTargetUnit(table[i]);
+               i = SyncRand() % nb_units;
+               return NewTargetUnit(table[i]);
 #endif
-                       }
-               break;
-               }
-               default:
-               {
-                       // Error : add the new cases
-                       // FIXME : Warn developpers
-                       return NULL;
-                       break;
-               }
+           }
+           break;
+       default:
+           // Error : add the new cases
+           // FIXME : Warn developpers
+           return NULL;
+           break;
        }
-       return NULL;    // Can't spell the auto-cast.
+    return NULL;       // Can't spell the auto-cast.
 }
 
 // ****************************************************************************
@@ -1667,10 +1430,7 @@
 global void DoneSpells()
 {
 // FIXME
-#if 0
-
-#endif
-       free(SpellTypeTable);
+    free(SpellTypeTable);
     // nothing yet
 }
 
@@ -1744,6 +1504,22 @@
 // ****************************************************************************
 
 /**
+**     Check if spell is research for player \p player.
+**     @param  player : player for who we want to know if he knows the spell.
+**     @param  id : 
+*/
+global int SpellIsAvailable(const Player* player, int SpellId)
+{
+    assert(player != NULL);
+    assert(0 <= SpellId && SpellId < SpellTypeCount);
+
+    int dependencyId = SpellTypeTable[SpellId].DependencyId;
+
+    return dependencyId == -1 || UpgradeIdAllowed(player, dependencyId) == 'R';
+}
+
+
+/**
 **     Check if the spell can be auto cast.
 **
 **     @param spell    Spell-type pointer
@@ -1752,9 +1528,9 @@
 */
 global int CanAutoCastSpell(const SpellType* spell)
 {
-       assert(spell != NULL);
+    assert(spell != NULL);
 
-       return spell->AutoCast ? 1 : 0;
+    return spell->AutoCast ? 1 : 0;
 }
 
 /**
@@ -1796,34 +1572,29 @@
 **
 **     @return         1 if spell is casted, 0 if not.
 */
-global int     AutoCastSpell(Unit *caster,
-                                                const SpellType* spell)
+global int AutoCastSpell(Unit *caster,const SpellType* spell)
 {
-    Target                             *target = NULL;
+    Target *target = NULL;
 
-       assert(caster != NULL);
-       assert(spell != NULL);
-       assert(0 <= spell->Ident && spell->Ident < SpellTypeCount);
+    assert(caster != NULL);
+    assert(spell != NULL);
+    assert(0 <= spell->Ident && spell->Ident < SpellTypeCount);
     assert(caster->Type->CanCastSpell);
     assert(caster->Type->CanCastSpell[spell->Ident]);
 
-       if (!PassGenericCondition(caster, spell, spell->Condition_generic)
-               || !PassGenericCondition(caster, spell, 
spell->AutoCast->Condition_generic))
-       {
-               return 0;
-       }
-       target = SelectTargetUnitsOfAutoCast(caster, spell);
-       if (target == NULL)
-       {
-               return 0;
-       }
-       else
-       {
-               //      Must move before ?
-               //      FIXME SpellType* of CommandSpellCast must be const.
-               CommandSpellCast(caster, target->X, target->Y, target->unit, 
(SpellType*) spell, FlushCommands);
-               free(target);
-       }
+    if (!PassGenericCondition(caster, spell, spell->Condition_generic)
+           || !PassGenericCondition(caster, spell, 
spell->AutoCast->Condition_generic)) {
+       return 0;
+    }
+    target = SelectTargetUnitsOfAutoCast(caster, spell);
+    if (target == NULL) {
+       return 0;
+    } else {
+       //      Must move before ?
+       //      FIXME SpellType* of CommandSpellCast must be const.
+       CommandSpellCast(caster, target->X, target->Y, target->unit, 
(SpellType*) spell, FlushCommands);
+       free(target);
+    }
     return 1;
 }
 
@@ -1838,12 +1609,12 @@
 **
 **     @return         !=0 if spell should/can continue or 0 to stop
 */
-global int SpellCast(Unit* caster, const SpellType* spell,
-               Unit* target, int x, int y)
+global int SpellCast(Unit* caster, const SpellType* spell,Unit* target, int x, 
int y)
 {
     assert(spell != NULL);
     assert(spell->f != NULL);
     assert(caster != NULL);
+    assert(SpellIsAvailable(caster->Player, spell->Ident));
 
     caster->Invisible = 0;// unit is invisible until attacks // FIXME Must be 
configurable
     if (target) {
Index: stratagus/src/include/spells.h
diff -u stratagus/src/include/spells.h:1.23 stratagus/src/include/spells.h:1.24
--- stratagus/src/include/spells.h:1.23 Fri Sep 26 05:15:22 2003
+++ stratagus/src/include/spells.h      Fri Sep 26 11:47:51 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: spells.h,v 1.23 2003/09/26 09:15:22 mr-russ Exp $
+//     $Id: spells.h,v 1.24 2003/09/26 15:47:51 n0body Exp $
 
 #ifndef __SPELLS_H__
 #define __SPELLS_H__
@@ -98,22 +98,19 @@
 // TTL's below are in ticks: approx: 500=13sec, 1000=25sec, 2000=50sec
 // FIXME use TTL, as in TICKS to live
     struct {
-       int Fields;             /// FIXME doc
-       int Shards;             /// FIXME doc
-       int Damage;             /// damage
-    } Blizzard;
+       int Fields;             /// The size of the affected square
+       int Shards;             /// Number of shards thrown.
+       int Damage;             /// Damage for every shard.
+       /// The offset of the missile start point to the hit location.
+       int StartOffsetX;
+       int StartOffsetY;
+    } AreaBombardment;
     
     struct {
        UnitType *PortalType;   /// The unit type spawned
     } SpawnPortal;
     
     struct {
-       int Fields;             /// FIXME doc
-       int Shards;             /// FIXME doc
-       int Damage;             /// damage
-    } DeathAndDecay;
-    
-    struct {
        int TTL;                /// time to live (ticks)
        int Damage;             /// Damage.
     } Fireball;
@@ -143,24 +140,28 @@
     } invisibility;
     
     struct {
-       UnitType *unit;         /// The new form :)
-    } polymorph;
+       UnitType *NewForm;      /// The new form
+       //  TODO: temporary polymorphs would be awesome, but hard to implement
+    } Polymorph;
     
     struct {
-       UnitType *skeleton;             /// The unit to spwan from corpses
-    } raisedead;
+       UnitType *UnitType;     /// Type of unit to be summoned.
+       int TTL;                /// Time to live for summoned unit. 0 means 
infinite
+    } Summon;
     
     struct {
-       int TTL;                        /// time to live (ticks)
-       int damage;                     /// Damage.
-    } runes;
-    
+       UnitType *Skeleton;     /// The unit to spawn from corpses
+       int TTL;                /// Time to live for summon. 0 means infinite.
+    } RaiseDead;
+    //  What about a resurection spell?
+
     struct {
-       UnitType *unittype;             /// Type of unit to be summoned.
-    } summon;
+       int TTL;                /// time to live (ticks)
+       int Damage;             /// Damage.
+    } runes;
     
     struct {
-       int  TTL;                       /// time to live (ticks)
+       int  TTL;               /// time to live (ticks)
        // FIXME: more configurations
     } whirlwind;
 } SpellActionType;
@@ -246,7 +247,7 @@
 /*
 **     Pointer on function that cast the spell.
 */
-typedef int f_spell(Unit* caster, const struct _spell_type_* spell, Unit* 
target,
+typedef int SpellFunc(Unit* caster, const struct _spell_type_* spell, Unit* 
target,
        int x, int y);
 
 /**
@@ -260,7 +261,7 @@
 
     // Spell Specifications
     TargetType Target;                 /// Targetting information. See 
TargetType.
-    f_spell *f;                                /// function to cast the spell.
+    SpellFunc *f;                              /// 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
@@ -337,21 +338,20 @@
 **     Spelltype to cast.
 */
 
-f_spell        CastHolyVision;
-f_spell        CastHealing;
-f_spell        CastHaste;
-f_spell        CastFireball;
-f_spell        CastFlameShield;
-f_spell        CastInvisibility;
-f_spell        CastPolymorph;
-f_spell        CastBlizzard;
-f_spell        CastSummon;
-f_spell        CastRunes;
-f_spell        CastDeathCoil;
-f_spell        CastRaiseDead;
-f_spell        CastWhirlwind;
-f_spell        CastDeathAndDecay;
-f_spell        CastCircleOfPower;
+SpellFunc CastHolyVision;
+SpellFunc CastHealing;
+SpellFunc CastHaste;
+SpellFunc CastFireball;
+SpellFunc CastFlameShield;
+SpellFunc CastInvisibility;
+SpellFunc CastPolymorph;
+SpellFunc CastAreaBombardment;
+SpellFunc CastSummon;
+SpellFunc CastRunes;
+SpellFunc CastDeathCoil;
+SpellFunc CastRaiseDead;
+SpellFunc CastWhirlwind;
+SpellFunc CastSpawnPortal;
 
 
 /*
Index: stratagus/src/siod/slib.c
diff -u stratagus/src/siod/slib.c:1.27 stratagus/src/siod/slib.c:1.28
--- stratagus/src/siod/slib.c:1.27      Tue Sep 23 05:12:35 2003
+++ stratagus/src/siod/slib.c   Fri Sep 26 11:47:51 2003
@@ -94,7 +94,7 @@
 
 static void init_slib_version(void)
 {setvar(cintern("*slib-version*"),
-       cintern("$Id: slib.c,v 1.27 2003/09/23 09:12:35 martinxyz Exp $"),
+       cintern("$Id: slib.c,v 1.28 2003/09/26 15:47:51 n0body Exp $"),
        NIL);}
 
 char * __stdcall siod_version(void)
@@ -585,66 +585,64 @@
      
 long repl(struct repl_hooks *h)
 {
-
-       LISP x, cw = 0;
-       double rt,ct;
-       assert(h != NULL);
-       while(1)
+    LISP x, cw = 0;
+    double rt,ct;
+    assert(h != NULL);
+    while(1) {
+       if ((gc_kind_copying == 1) &&
+               ((gc_status_flag) || heap >= heap_end))  {
+           rt = myruntime();
+           gc_stop_and_copy();
+           if (siod_verbose_level >= 2) {
+               sprintf(tkbuffer,"GC took %g seconds, %ld compressed to %ld, 
%ld free\n",
+                    
myruntime()-rt,old_heap_used,(long)(heap-heap_org),(long)(heap_end-heap));
+               grepl_puts(tkbuffer, h->repl_puts);
+           }
+       }
+       if (siod_verbose_level >= 2) {
+           grepl_puts("> ", h->repl_puts);
+       }
+       if (h->repl_read == NULL) {
+           x = lread(NIL);
+       } else {
+           x = (*h->repl_read)();
+       }
+       if EQ(x,eof_val) {
+           break;
+       }
+       rt = myruntime();
+       ct = myrealtime();
+       if (gc_kind_copying == 1) {
+           cw = heap;
+       } else {
+           gc_cells_allocated = 0;
+           gc_time_taken = 0.0;
+       }
+       if (h->repl_eval == NULL) {
+           x = leval(x,NIL);
+       } else {
+           x = (*h->repl_eval)(x);
+       }
+       if (gc_kind_copying == 1)
        {
-               if (gc_kind_copying == 1 &&
-                       ((gc_status_flag) || heap >= heap_end))
-       {
-               rt = myruntime();
-                       gc_stop_and_copy();
-                       if (siod_verbose_level >= 2)
-                       {sprintf(tkbuffer,
-                                "GC took %g seconds, %ld compressed to %ld, 
%ld free\n",
-                                
myruntime()-rt,old_heap_used,(long)(heap-heap_org),(long)(heap_end-heap));
-                                grepl_puts(tkbuffer, h->repl_puts);
-                       }
-               }
-               /*
-               if (siod_verbose_level >= 2)
-               grepl_puts("> ", h->repl_puts);
-       */
-               if (h->repl_read == NULL)
-                       x = lread(NIL);
-               else
-                       x = (*h->repl_read)();
-               if EQ(x,eof_val) break;
-               rt = myruntime();
-               ct = myrealtime();
-               if (gc_kind_copying == 1)
-                   cw = heap;
-               else
-                       {gc_cells_allocated = 0;
-                    gc_time_taken = 0.0;}
-               if (h->repl_eval == NULL)
-                       x = leval(x,NIL);
-               else
-                       x = (*h->repl_eval)(x);
-               if (gc_kind_copying == 1)
-                       sprintf(tkbuffer,
-                               "Evaluation took %g seconds %ld cons work, %g 
real.\n",
-                               myruntime()-rt,
-                           (long)(heap-cw),
-                           myrealtime()-ct);
-           else
-             sprintf(tkbuffer,
-                            "Evaluation took %g seconds (%g in gc) %ld cons 
work, %g real.\n",
-                             myruntime()-rt,
-                             gc_time_taken,
-                             gc_cells_allocated,
-                             myrealtime()-ct);
-           if (siod_verbose_level >= 2)
-             grepl_puts(tkbuffer,h->repl_puts);
-           if (h->repl_print == NULL)
-               {if (siod_verbose_level >= 2)
-                                lprint(x,NIL);}
-               else
-                 (*h->repl_print)(x);
-               }
-       return(0);
+           sprintf(tkbuffer,"Evaluation took %g seconds %ld cons work, %g 
real.\n",
+                   myruntime()-rt,(long)(heap-cw),myrealtime()-ct);
+       } else {
+           sprintf(tkbuffer, "Evaluation took %g seconds (%g in gc) %ld cons 
work, %g real.\n",
+                   
myruntime()-rt,gc_time_taken,gc_cells_allocated,myrealtime()-ct);
+       }
+       if (siod_verbose_level >= 2) {
+           grepl_puts(tkbuffer,h->repl_puts);
+       }
+       if (h->repl_print == NULL) {
+           if (siod_verbose_level >= 2) {
+               lprint(x,NIL);
+           }
+       } else {
+             (*h->repl_print)(x);
+       }
+    }
+    return(0);
 }
 
 void set_fatal_exit_hook(void (*fcn)(void))
@@ -940,6 +938,8 @@
 {char *tmp;
  tmp = (char *) malloc((size) ? size : 1);
  if (tmp == (char *)NULL) errl("failed to allocate storage from system",NIL);
+ //  FIXME:  This should be necesary, but it's better to be safe.
+ memset(tmp,0,(size)?size:1);
  return(tmp);}
 
 LISP gen_intern(char *name,long copyp)
@@ -1021,7 +1021,6 @@
 void __stdcall init_storage(void)
 {long j;
  LISP stack_start;
-
 #ifdef DEBUG
  stack_start = NULL;
 #endif
@@ -1418,13 +1417,14 @@
 long looks_pointerp(LISP p)
 {long j;
  LISP h;
- for(j=0;j<nheaps;++j)
+ for(j=0;j<nheaps;++j) {
    if ((h = heaps[j]) &&
        (p >= h) &&
        (p < (h + heap_size)) &&
        (((((char *)p) - ((char *)h)) % sizeof(struct obj)) == 0) &&
        NTYPEP(p,tc_free_cell))
      return(1);
+ }
  return(0);}
 
 void mark_locations_array(LISP *x,long n)




reply via email to

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