diff --git a/src/ai/ai_magic.cpp b/src/ai/ai_magic.cpp
index d7ec204cd..d7a266ed3 100644
--- a/src/ai/ai_magic.cpp
+++ b/src/ai/ai_magic.cpp
@@ -74,7 +74,8 @@ global void AiCheckMagic(void)
 	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))	{
+		if (unit->Type->CanCastSpell[j] && SpellIsAvailable(player, j) &&
+			SpellTypeById(j)->AutoCast) {
 #ifdef DEBUG
 		    success = // Follow on next line (AutoCastSpell).
 #endif
diff --git a/src/include/spells.h b/src/include/spells.h
index 52984c157..44281d0db 100644
--- a/src/include/spells.h
+++ b/src/include/spells.h
@@ -89,82 +89,81 @@ typedef enum {
 #endif
 }	TargetType;
 
+/*
+**	Pointer on function that cast the spell.
+*/
+typedef int SpellFunc(Unit* caster, const struct _spell_type_* spell, Unit* target,int x, int y);
 
-
-
-typedef union
+typedef struct
 {
-// FIXME rename structure more properly.
-// TTL's below are in ticks: approx: 500=13sec, 1000=25sec, 2000=50sec
-// FIXME use TTL, as in TICKS to live
-    struct {
-	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 TTL;		/// time to live (ticks)
-	int Damage;		/// Damage.
-    } Fireball;
-    
-    struct {
-	int TTL;		/// time to live (ticks)
-    } FlameShield;
+    SpellFunc* CastFunction;
+    union {
+// FIXME time information doesn't work as it should.
+	struct {
+	    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 TTL;		/// time to live (ticks)
+	    int Damage;		/// Damage.
+	} Fireball;
+	
+	struct {
+	    int TTL;		/// time to live (ticks)
+	} FlameShield;
 
-    struct {
-	int HasteTicks;		/// Number of ticks to set Haste to.
-	int SlowTicks;		/// Number of ticks to set Slow to.
-	int BloodlustTicks;	/// Number of ticks to set Bloodlust to.
-	int InvisibilityTicks;	/// Number of ticks to set Invisibility to.
-	int InvincibilityTicks;	/// Number of ticks to set UnholyArmor to.
+	struct {
+	    int HasteTicks;		/// Number of ticks to set Haste to.
+	    int SlowTicks;		/// Number of ticks to set Slow to.
+	    int BloodlustTicks;	/// Number of ticks to set Bloodlust to.
+	    int InvisibilityTicks;	/// Number of ticks to set Invisibility to.
+	    int InvincibilityTicks;	/// Number of ticks to set UnholyArmor to.
 #define BUFF_NOT_AFFECTED 0xC0FF33 /// Don't like the value? The value doesn't like you!
-    } AdjustBuffs;
-    
-    struct {
-	int HP;			/// Target HP gain.(can be negative)
-	int Mana;		/// Target Mana gain.(can be negative)
-	/// This spell is designed to be used wit very small amounts. The spell
-	/// can scale up to MaxMultiCast times. Use 0 for infinite.
-	int MaxMultiCast; 
-    } AdjustVitals;
-    
-    struct {
-	UnitType *revealer;	/// Type of unit to be summoned: (unit-revealer).
-    } HolyVision;
-    
-    struct {
-	UnitType *NewForm;	/// The new form
-	//  TODO: temporary polymorphs would be awesome, but hard to implement
-    } Polymorph;
-    
-    struct {
-	UnitType *UnitType;	/// Type of unit to be summoned.
-	int TTL;		/// Time to live for summoned unit. 0 means infinite
-    } Summon;
-    
-    struct {
-	UnitType *UnitRaised;	/// The unit to spawn from corpses
-	int TTL;		/// Time to live for summon. 0 means infinite.
-    } RaiseDead;
-    //  What about a resurection spell?
+	} AdjustBuffs;
+	
+	struct {
+	    int HP;			/// Target HP gain.(can be negative)
+	    int Mana;		/// Target Mana gain.(can be negative)
+	    /// This spell is designed to be used wit very small amounts. The spell
+	    /// can scale up to MaxMultiCast times. Use 0 for infinite.
+	    int MaxMultiCast; 
+	} AdjustVitals;
+	
+	struct {
+	    UnitType *NewForm;	/// The new form
+	    //  TODO: temporary polymorphs would be awesome, but hard to implement
+	} Polymorph;
+	
+	struct {
+	    UnitType *UnitType;	/// Type of unit to be summoned.
+	    int TTL;		/// Time to live for summoned unit. 0 means infinite
+	} Summon;
+	
+	struct {
+	    UnitType *UnitRaised;	/// The unit to spawn from corpses
+	    int TTL;		/// Time to live for summon. 0 means infinite.
+	} RaiseDead;
+	//  What about a resurection spell?
 
-    struct {
-	int TTL;		/// time to live (ticks)
-	int Damage;		/// Damage.
-    } Runes;
-    
-    struct {
-	int  TTL;		/// time to live (ticks)
-	// FIXME: more configurations
-    } Whirlwind;
+	struct {
+	    int TTL;		/// time to live (ticks)
+	    int Damage;		/// Damage.
+	} Runes;
+	
+	struct {
+	    int  TTL;		/// time to live (ticks)
+	    // FIXME: more configurations
+	} Whirlwind;
+    } Data;
 } SpellActionType;
 
 /*
@@ -242,11 +241,6 @@ typedef struct {
 
 struct _spell_type_;
 
-/*
-**	Pointer on function that cast the spell.
-*/
-typedef int SpellFunc(Unit* caster, const struct _spell_type_* spell, Unit* target,int x, int y);
-
 /**
 **	Base structure of a spell type.
 */
@@ -258,8 +252,7 @@ typedef struct _spell_type_ {
 
     //	Spell Specifications
     TargetType	Target;			/// Targetting information. See TargetType.
-    SpellFunc *CastFunction;		/// function to cast the spell.
-    SpellActionType *SpellAction;	/// More arguments for spell (damage, delay, additional sounds...).
+    SpellActionType *Action;		/// More arguments for spell (damage, delay, additional sounds...).
 #define INFINITE_RANGE 0xFFFFFFF
     int Range;				/// Max range of the target.
     int ManaCost;			/// required mana for each cast
@@ -336,7 +329,6 @@ extern unsigned CclGetSpellByIdent(SCM value);
 **	Spelltype to cast.
 */
 
-SpellFunc CastHolyVision;
 SpellFunc CastAdjustVitals;
 SpellFunc CastAdjustBuffs;
 SpellFunc CastFireball;
@@ -350,7 +342,6 @@ SpellFunc CastRaiseDead;
 SpellFunc CastWhirlwind;
 SpellFunc CastSpawnPortal;
 
-
 //@}
 
 #endif	// !__SPELLS_H__
diff --git a/src/stratagus/script_spell.cpp b/src/stratagus/script_spell.cpp
index c2ec3e1cb..1f8aee882 100644
--- a/src/stratagus/script_spell.cpp
+++ b/src/stratagus/script_spell.cpp
@@ -109,36 +109,36 @@ local void CclParseSpellAction(SCM list, SpellType* spell, SpellActionType *spel
 
     memset(spellaction, 0, sizeof(*spellaction));
     if (gh_eq_p(value,gh_symbol2scm("area-bombardment"))) {
-	spell->CastFunction=CastAreaBombardment;
+	spellaction->CastFunction=CastAreaBombardment;
 	while (!gh_null_p(list)) {
 	    value = gh_car(list);
 	    list=gh_cdr(list);
 	    if (gh_eq_p(value, gh_symbol2scm("fields"))) {
-		spellaction->AreaBombardment.Fields = gh_scm2int(gh_car(list));
+		spellaction->Data.AreaBombardment.Fields = gh_scm2int(gh_car(list));
 		list = gh_cdr(list);
 	    } else if (gh_eq_p(value, gh_symbol2scm("shards"))) {
-		spellaction->AreaBombardment.Shards = gh_scm2int(gh_car(list));
+		spellaction->Data.AreaBombardment.Shards = gh_scm2int(gh_car(list));
 		list = gh_cdr(list);
 	    } else if (gh_eq_p(value, gh_symbol2scm("damage"))) {
-		spellaction->AreaBombardment.Damage = gh_scm2int(gh_car(list));
+		spellaction->Data.AreaBombardment.Damage = gh_scm2int(gh_car(list));
 		list = gh_cdr(list);
 	    } else if (gh_eq_p(value, gh_symbol2scm("start-offset-x"))) {
-		spellaction->AreaBombardment.StartOffsetX = gh_scm2int(gh_car(list));
+		spellaction->Data.AreaBombardment.StartOffsetX = gh_scm2int(gh_car(list));
 		list = gh_cdr(list);
 	    } else if (gh_eq_p(value, gh_symbol2scm("start-offset-y"))) {
-		spellaction->AreaBombardment.StartOffsetY = gh_scm2int(gh_car(list));
+		spellaction->Data.AreaBombardment.StartOffsetY = gh_scm2int(gh_car(list));
 		list = gh_cdr(list);
 	    } else {
 		errl("Unsupported area-bombardment tag",value);
 	    }
 	}
     } else if (gh_eq_p(value,gh_symbol2scm("flame-shield"))) {
-	spell->CastFunction=CastFlameShield;
+	spellaction->CastFunction=CastFlameShield;
 	while (!gh_null_p(list)) {
 	    value = gh_car(list);
 	    list=gh_cdr(list);
 	    if (gh_eq_p(value, gh_symbol2scm("duration"))) {
-		spellaction->FlameShield.TTL = gh_scm2int(gh_car(list));
+		spellaction->Data.FlameShield.TTL = gh_scm2int(gh_car(list));
 		list = gh_cdr(list);
 		/// FIXME:damage, missiles, rotation speed?
 	    } else {
@@ -146,107 +146,107 @@ local void CclParseSpellAction(SCM list, SpellType* spell, SpellActionType *spel
 	    }
 	}
     } else if (gh_eq_p(value,gh_symbol2scm("fireball"))) {
-	spell->CastFunction=CastFireball;
+	spellaction->CastFunction=CastFireball;
 	while (!gh_null_p(list)) {
 	    value = gh_car(list);
 	    list=gh_cdr(list);
 	    if (gh_eq_p(value, gh_symbol2scm("damage"))) {
-		spellaction->Fireball.Damage = gh_scm2int(gh_car(list));
+		spellaction->Data.Fireball.Damage = gh_scm2int(gh_car(list));
 		list = gh_cdr(list);
 	    } else if (gh_eq_p(value, gh_symbol2scm("ttl"))) {
-		spellaction->Fireball.TTL = gh_scm2int(gh_car(list));
+		spellaction->Data.Fireball.TTL = gh_scm2int(gh_car(list));
 		list = gh_cdr(list);
 	    } else {
 		errl("Unsupported fireball tag",value);
 	    }
 	}
     } else if (gh_eq_p(value,gh_symbol2scm("runes"))) {
-	spell->CastFunction=CastRunes;
+	spellaction->CastFunction=CastRunes;
 	while (!gh_null_p(list)) {
 	    value = gh_car(list);
 	    list=gh_cdr(list);
 	    if (gh_eq_p(value, gh_symbol2scm("damage"))) {
-		spellaction->Fireball.Damage = gh_scm2int(gh_car(list));
+		spellaction->Data.Fireball.Damage = gh_scm2int(gh_car(list));
 		list = gh_cdr(list);
 	    } else if (gh_eq_p(value, gh_symbol2scm("ttl"))) {
-		spellaction->Fireball.TTL = gh_scm2int(gh_car(list));
+		spellaction->Data.Fireball.TTL = gh_scm2int(gh_car(list));
 		list = gh_cdr(list);
 	    } else {
 		errl("Unsupported runes tag",value);
 	    }
 	}
     } else if (gh_eq_p(value,gh_symbol2scm("whirlwind"))) {
-	spell->CastFunction=CastWhirlwind;
+	spellaction->CastFunction=CastWhirlwind;
 	while (!gh_null_p(list)) {
 	    value = gh_car(list);
 	    list=gh_cdr(list);
 	    if (gh_eq_p(value, gh_symbol2scm("duration"))) {
-		spellaction->Whirlwind.TTL = gh_scm2int(gh_car(list));
+		spellaction->Data.Whirlwind.TTL = gh_scm2int(gh_car(list));
 		list = gh_cdr(list);
 	    } else {
 		errl("Unsupported runes tag",value);
 	    }
 	}
     } else if (gh_eq_p(value,gh_symbol2scm("adjust-buffs"))) {
-	spell->CastFunction=CastAdjustBuffs;
-	spellaction->AdjustBuffs.HasteTicks=BUFF_NOT_AFFECTED;
-	spellaction->AdjustBuffs.SlowTicks=BUFF_NOT_AFFECTED;
-	spellaction->AdjustBuffs.BloodlustTicks=BUFF_NOT_AFFECTED;
-	spellaction->AdjustBuffs.InvisibilityTicks=BUFF_NOT_AFFECTED;
-	spellaction->AdjustBuffs.InvincibilityTicks=BUFF_NOT_AFFECTED;
+	spellaction->CastFunction=CastAdjustBuffs;
+	spellaction->Data.AdjustBuffs.HasteTicks=BUFF_NOT_AFFECTED;
+	spellaction->Data.AdjustBuffs.SlowTicks=BUFF_NOT_AFFECTED;
+	spellaction->Data.AdjustBuffs.BloodlustTicks=BUFF_NOT_AFFECTED;
+	spellaction->Data.AdjustBuffs.InvisibilityTicks=BUFF_NOT_AFFECTED;
+	spellaction->Data.AdjustBuffs.InvincibilityTicks=BUFF_NOT_AFFECTED;
 	while (!gh_null_p(list)) {
 	    value = gh_car(list);
 	    list=gh_cdr(list);
 	    if (gh_eq_p(value, gh_symbol2scm("haste-ticks"))) {
-		spellaction->AdjustBuffs.HasteTicks = gh_scm2int(gh_car(list));
+		spellaction->Data.AdjustBuffs.HasteTicks = gh_scm2int(gh_car(list));
 		list = gh_cdr(list);
 	    } else if (gh_eq_p(value, gh_symbol2scm("slow-ticks"))) {
-		spellaction->AdjustBuffs.SlowTicks  = gh_scm2int(gh_car(list));
+		spellaction->Data.AdjustBuffs.SlowTicks  = gh_scm2int(gh_car(list));
 		list = gh_cdr(list);
 	    } else if (gh_eq_p(value, gh_symbol2scm("bloodlust-ticks"))) {
-		spellaction->AdjustBuffs.BloodlustTicks  = gh_scm2int(gh_car(list));
+		spellaction->Data.AdjustBuffs.BloodlustTicks  = gh_scm2int(gh_car(list));
 		list = gh_cdr(list);
 	    } else if (gh_eq_p(value, gh_symbol2scm("invisibility-ticks"))) {
-		spellaction->AdjustBuffs.InvisibilityTicks  = gh_scm2int(gh_car(list));
+		spellaction->Data.AdjustBuffs.InvisibilityTicks  = gh_scm2int(gh_car(list));
 		list = gh_cdr(list);
 	    } else if (gh_eq_p(value, gh_symbol2scm("invincibility-ticks"))) {
-		spellaction->AdjustBuffs.InvincibilityTicks  = gh_scm2int(gh_car(list));
+		spellaction->Data.AdjustBuffs.InvincibilityTicks  = gh_scm2int(gh_car(list));
 		list = gh_cdr(list);
 	    } else {
 		errl("Unsupported adjust-buffs tag",value);
 	    }
 	}
     } else if (gh_eq_p(value,gh_symbol2scm("summon"))) {
-	spell->CastFunction=CastSummon;
+	spellaction->CastFunction=CastSummon;
 	while (!gh_null_p(list)) {
 	    value = gh_car(list);
 	    list = gh_cdr(list);
 	    if (gh_eq_p(value, gh_symbol2scm("unit-type"))) {
 		str = gh_scm2newstr(gh_car(list),0);
-		spellaction->Summon.UnitType = UnitTypeByIdent(str);
-		if (!spellaction->Summon.UnitType) {
-		    spellaction->Summon.UnitType = 0;
+		spellaction->Data.Summon.UnitType = UnitTypeByIdent(str);
+		if (!spellaction->Data.Summon.UnitType) {
+		    spellaction->Data.Summon.UnitType = 0;
 		    DebugLevel0("unit type \"%s\" not found for summon spell.\n" _C_ str);
 		}
 		free(str);
 		list = gh_cdr(list);
 	    } else if (gh_eq_p(value, gh_symbol2scm("time-to-live"))) {
-		spellaction->Summon.TTL = gh_scm2int(gh_car(list));
+		spellaction->Data.Summon.TTL = gh_scm2int(gh_car(list));
 		list = gh_cdr(list);
 	    } else {
 		errl("Unsupported summon tag",value);
 	    }
 	}
     } else if (gh_eq_p(value,gh_symbol2scm("spawn-portal"))) {
-	spell->CastFunction=CastSpawnPortal;
+	spellaction->CastFunction=CastSpawnPortal;
 	while (!gh_null_p(list)) {
 	    value = gh_car(list);
 	    list = gh_cdr(list);
 	    if (gh_eq_p(value, gh_symbol2scm("portal-type"))) {
 		str = gh_scm2newstr(gh_car(list),0);
-		spellaction->SpawnPortal.PortalType = UnitTypeByIdent(str);
-		if (!spellaction->SpawnPortal.PortalType) {
-		    spellaction->SpawnPortal.PortalType = 0;
+		spellaction->Data.SpawnPortal.PortalType = UnitTypeByIdent(str);
+		if (!spellaction->Data.SpawnPortal.PortalType) {
+		    spellaction->Data.SpawnPortal.PortalType = 0;
 		    DebugLevel0("unit type \"%s\" not found for spawn-portal.\n" _C_ str);
 		}
 		free(str);
@@ -256,36 +256,36 @@ local void CclParseSpellAction(SCM list, SpellType* spell, SpellActionType *spel
 	    }
 	}
     } else if (gh_eq_p(value,gh_symbol2scm("raise-dead"))) {
-	spell->CastFunction=CastRaiseDead;
+	spellaction->CastFunction=CastRaiseDead;
 	while (!gh_null_p(list)) {
 	    value = gh_car(list);
 	    list = gh_cdr(list);
 	    if (gh_eq_p(value, gh_symbol2scm("unit-raised"))) {
 		str = gh_scm2newstr(gh_car(list),0);
-		spellaction->RaiseDead.UnitRaised = UnitTypeByIdent(str);
-		if (!spellaction->RaiseDead.UnitRaised) {
-		    spellaction->RaiseDead.UnitRaised = 0;
+		spellaction->Data.RaiseDead.UnitRaised = UnitTypeByIdent(str);
+		if (!spellaction->Data.RaiseDead.UnitRaised) {
+		    spellaction->Data.RaiseDead.UnitRaised = 0;
 		    DebugLevel0("unit type \"%s\" not found for summon spell.\n" _C_ str);
 		}
 		free(str);
 		list = gh_cdr(list);
 	    } else if (gh_eq_p(value, gh_symbol2scm("time-to-live"))) {
-		spellaction->RaiseDead.TTL = gh_scm2int(gh_car(list));
+		spellaction->Data.RaiseDead.TTL = gh_scm2int(gh_car(list));
 		list = gh_cdr(list);
 	    } else {
 		errl("Unsupported raise-dead tag",value);
 	    }
 	}
     } else if (gh_eq_p(value,gh_symbol2scm("polymorph"))) {
-	spell->CastFunction=CastPolymorph;
+	spellaction->CastFunction=CastPolymorph;
 	while (!gh_null_p(list)) {
 	    value = gh_car(list);
 	    list = gh_cdr(list);
 	    if (gh_eq_p(value, gh_symbol2scm("new-form"))) {
 		str = gh_scm2newstr(gh_car(list),0);
-		spellaction->Summon.UnitType = UnitTypeByIdent(str);
-		if (!spellaction->Summon.UnitType) {
-		    spellaction->Summon.UnitType = 0;
+		spellaction->Data.Summon.UnitType = UnitTypeByIdent(str);
+		if (!spellaction->Data.Summon.UnitType) {
+		    spellaction->Data.Summon.UnitType = 0;
 		    DebugLevel0("unit type \"%s\" not found for summon spell.\n" _C_ str);
 		}
 		free(str);
@@ -296,18 +296,18 @@ local void CclParseSpellAction(SCM list, SpellType* spell, SpellActionType *spel
 	    }
 	}
     } else if (gh_eq_p(value,gh_symbol2scm("adjust-vitals"))) {
-	spell->CastFunction=CastAdjustVitals;
+	spellaction->CastFunction=CastAdjustVitals;
 	while (!gh_null_p(list)) {
 	    value = gh_car(list);
 	    list=gh_cdr(list);
 	    if (gh_eq_p(value, gh_symbol2scm("hit-points"))) {
-		spellaction->AdjustVitals.HP = gh_scm2int(gh_car(list));
+		spellaction->Data.AdjustVitals.HP = gh_scm2int(gh_car(list));
 		list = gh_cdr(list);
 	    } else if (gh_eq_p(value, gh_symbol2scm("mana-points"))) {
-		spellaction->AdjustVitals.Mana = gh_scm2int(gh_car(list));
+		spellaction->Data.AdjustVitals.Mana = gh_scm2int(gh_car(list));
 		list = gh_cdr(list);
 	    } else if (gh_eq_p(value, gh_symbol2scm("max-multi-cast"))) {
-		spellaction->AdjustVitals.MaxMultiCast = gh_scm2int(gh_car(list));
+		spellaction->Data.AdjustVitals.MaxMultiCast = gh_scm2int(gh_car(list));
 		list = gh_cdr(list);
 	    } else {
 		errl("Unsupported adjust-vitals tag",value);
@@ -396,7 +396,7 @@ local void CclSpellParseCondition(SCM list, ConditionInfo* condition)
 	    condition->TargetSelf=Scm2Condition(gh_car(list));
 	    list=gh_cdr(list);
 	} else if (gh_eq_p(value,gh_symbol2scm("min-hp-percent"))) {
-	    condition->MaxHpPercent=gh_scm2int(gh_car(list));
+	    condition->MinHpPercent=gh_scm2int(gh_car(list));
 	    list=gh_cdr(list);
 	} else if (gh_eq_p(value,gh_symbol2scm("max-hp-percent"))) {
 	    condition->MaxHpPercent=gh_scm2int(gh_car(list));
@@ -525,8 +525,8 @@ local SCM CclDefineSpell(SCM list)
 	    }
 	    list=gh_cdr(list);
 	} else if (gh_eq_p(value,gh_symbol2scm("action"))) {
-	    spell->SpellAction=(SpellActionType*)malloc(sizeof(SpellActionType));
-	    CclParseSpellAction(gh_car(list),spell,spell->SpellAction);
+	    spell->Action=(SpellActionType*)malloc(sizeof(SpellActionType));
+	    CclParseSpellAction(gh_car(list),spell,spell->Action);
 	    list=gh_cdr(list);
 	} else if (gh_eq_p(value,gh_symbol2scm("condition"))) {
 	    spell->Conditions=(ConditionInfo*)malloc(sizeof(ConditionInfo));
@@ -574,6 +574,136 @@ global void SpellCclRegister(void)
     gh_new_procedureN("define-spell", CclDefineSpell);
 }
 
+/*
+**	Save a spell action to a file.
+**
+** 	@param file	File pointer to save to
+**	@param action	Pointer to action to save.
+*/
+local void SaveSpellCondition(CLFile *file,ConditionInfo* condition)
+{
+    char condstrings [3][10] = {
+	"true",			/// CONDITION_TRUE
+	"false",		/// CONDITION_FALSE
+	"only"			/// CONDITION_ONLY
+    };
+
+    DebugCheck(!file);
+    DebugCheck(!condition);
+
+    CLprintf(file,"'( ");
+    //
+    //	First save data related to flags.
+    //	NOTE: (int) is there to keep compilers happy.
+    //
+    CLprintf(file,"undead %s ",condstrings[(int)condition->Undead]);
+    CLprintf(file,"organic %s ",condstrings[(int)condition->Organic]);
+    CLprintf(file,"hero %s ",condstrings[(int)condition->Hero]);
+    CLprintf(file,"coward %s ",condstrings[(int)condition->Coward]);
+    CLprintf(file,"alliance %s ",condstrings[(int)condition->Alliance]);
+    CLprintf(file,"building %s ",condstrings[(int)condition->Building]);
+    CLprintf(file,"self %s ",condstrings[(int)condition->TargetSelf]);
+    //
+    //	Min/Max vital percents
+    //
+    CLprintf(file,"min-hp-percent %d ",condition->MinHpPercent);
+    CLprintf(file,"max-hp-percent %d ",condition->MaxHpPercent);
+    CLprintf(file,"min-mana-percent %d ",condition->MinManaPercent);
+    CLprintf(file,"max-mana-percent %d ",condition->MaxManaPercent);
+    //
+    //	Max buff ticks stuff
+    //
+    CLprintf(file,"max-slow-ticks %d ",condition->MaxSlowTicks);
+    CLprintf(file,"max-haste-ticks %d ",condition->MaxHasteTicks);
+    CLprintf(file,"max-bloodlust-ticks %d ",condition->MaxBloodlustTicks);
+    CLprintf(file,"max-invisibility-ticks %d ",condition->MaxInvisibilityTicks);
+    CLprintf(file,"max-invincibility-ticks %d ",condition->MaxInvincibilityTicks);
+    //
+    //	The end.
+    //
+    CLprintf(file,")\n");
+}
+
+/*
+**	Save a spell action to a file.
+**
+** 	@param file	File pointer to save to
+**	@param action	Pointer to action to save.
+*/
+local void SaveSpellAction(CLFile *file,SpellActionType* action)
+{
+    if (action->CastFunction==CastAreaBombardment) {
+	CLprintf(file," '(area-bombardment fields %d shards %d damage %d start-offset-x %d start-offset-y %d)",
+		action->Data.AreaBombardment.Fields,
+		action->Data.AreaBombardment.Shards,
+		action->Data.AreaBombardment.Damage,
+		action->Data.AreaBombardment.StartOffsetX,
+		action->Data.AreaBombardment.StartOffsetY);
+    } else if (action->CastFunction==CastFireball) {
+	CLprintf(file," '(fireball ttl %d damage %d)",
+		action->Data.Fireball.TTL,
+		action->Data.Fireball.Damage);
+    } else if (action->CastFunction==CastAdjustVitals) {
+	CLprintf(file," '(adjust-vitals");
+	if (action->Data.AdjustVitals.HP) {
+	    CLprintf(file," hit-points %d",action->Data.AdjustVitals.HP);
+	}
+	if (action->Data.AdjustVitals.Mana) {
+	    CLprintf(file," mana-points %d",action->Data.AdjustVitals.Mana);
+	}
+	if (action->Data.AdjustVitals.MaxMultiCast) {
+	    CLprintf(file," max-multi-cast %d",action->Data.AdjustVitals.MaxMultiCast);
+	}
+	CLprintf(file,")\n");
+    } else if (action->CastFunction==CastSummon) {
+	CLprintf(file," '(summon unit-type %s time-to-live %d)",
+		action->Data.Summon.UnitType->Ident,
+		action->Data.Summon.TTL);
+    } else if (action->CastFunction==CastAdjustBuffs) {
+	CLprintf(file," '(adjust-buffs");
+	if (action->Data.AdjustBuffs.HasteTicks!=BUFF_NOT_AFFECTED) {
+	    CLprintf(file," haste-ticks %d",action->Data.AdjustBuffs.HasteTicks);
+	}
+	if (action->Data.AdjustBuffs.SlowTicks!=BUFF_NOT_AFFECTED) {
+	    CLprintf(file," slow-ticks %d",action->Data.AdjustBuffs.SlowTicks);
+	}
+	if (action->Data.AdjustBuffs.BloodlustTicks!=BUFF_NOT_AFFECTED) {
+	    CLprintf(file," bloodlust-ticks %d",action->Data.AdjustBuffs.BloodlustTicks);
+	}
+	if (action->Data.AdjustBuffs.InvisibilityTicks!=BUFF_NOT_AFFECTED) {
+	    CLprintf(file," invisibility-ticks %d",action->Data.AdjustBuffs.InvisibilityTicks);
+	}
+	if (action->Data.AdjustBuffs.InvincibilityTicks!=BUFF_NOT_AFFECTED) {
+	    CLprintf(file," invincibility-ticks %d",action->Data.AdjustBuffs.InvincibilityTicks);
+	}
+	CLprintf(file,")");
+    } else if (action->CastFunction==CastPolymorph) {
+	CLprintf(file," '(polymorph new-form %s)",
+		action->Data.Polymorph.NewForm->Ident);
+    } else if (action->CastFunction==CastRaiseDead) {
+	CLprintf(file," '(raise-dead unit-raised %s time-to-live %d)",
+		action->Data.RaiseDead.UnitRaised->Ident,
+		action->Data.RaiseDead.TTL);
+    } else if (action->CastFunction==CastFlameShield) {
+	CLprintf(file," '(flame-shield duration %d)",
+		action->Data.FlameShield.TTL);
+    } else if (action->CastFunction==CastRunes) {
+	CLprintf(file," '(runes ttl %d damage %d)",
+		action->Data.Runes.TTL,
+		action->Data.Runes.Damage);
+    } else if (action->CastFunction==CastSpawnPortal) {
+	CLprintf(file," '(spawn-portal portal-type %s)",
+		action->Data.SpawnPortal.PortalType->Ident);
+    } else if (action->CastFunction==CastDeathCoil) {
+	CLprintf(file," '(death-coil)");
+	// FIXME: more?
+    } else if (action->CastFunction==CastWhirlwind) {
+	CLprintf(file," '(whirlwind duration %d)",
+		action->Data.Whirlwind.TTL);
+	// FIXME: more?
+    } 
+}
+
 /**
 **	Save spells to a CCL file.
 **	
@@ -624,81 +754,17 @@ global void SaveSpells(CLFile *file)
 	//
 	//  Save the action(effect of the spell)
 	//
-	CLprintf(file,"    'action");
-	if (spell->CastFunction==CastAreaBombardment) {
-	    CLprintf(file," '(area-bombardment fields %d shards %d damage %d start-offset-x %d start-offset-y %d)\n",
-		    spell->SpellAction->AreaBombardment.Fields,
-		    spell->SpellAction->AreaBombardment.Shards,
-		    spell->SpellAction->AreaBombardment.Damage,
-		    spell->SpellAction->AreaBombardment.StartOffsetX,
-		    spell->SpellAction->AreaBombardment.StartOffsetY);
-	} else if (spell->CastFunction==CastFireball) {
-	    CLprintf(file," '(fireball ttl %d damage %d)\n",
-		    spell->SpellAction->Fireball.TTL,
-		    spell->SpellAction->Fireball.Damage);
-	} else if (spell->CastFunction==CastAdjustVitals) {
-	    CLprintf(file," '(adjust-vitals");
-	    if (spell->SpellAction->AdjustVitals.HP) {
-		CLprintf(file," hit-points %d",spell->SpellAction->AdjustVitals.HP);
-	    }
-	    if (spell->SpellAction->AdjustVitals.Mana) {
-		CLprintf(file," mana-points %d",spell->SpellAction->AdjustVitals.Mana);
-	    }
-	    if (spell->SpellAction->AdjustVitals.MaxMultiCast) {
-		CLprintf(file," max-multi-cast %d",spell->SpellAction->AdjustVitals.MaxMultiCast);
-	    }
-	    CLprintf(file,")\n");
-	} else if (spell->CastFunction==CastSummon) {
-	    CLprintf(file," '(summon unit-type %s time-to-live %d)\n",
-		    spell->SpellAction->Summon.UnitType->Ident,
-		    spell->SpellAction->Summon.TTL);
-	} else if (spell->CastFunction==CastAdjustBuffs) {
-	    CLprintf(file," '(adjust-buffs");
-	    if (spell->SpellAction->AdjustBuffs.HasteTicks!=BUFF_NOT_AFFECTED) {
-		CLprintf(file," haste-ticks %d",spell->SpellAction->AdjustBuffs.HasteTicks);
-	    }
-	    if (spell->SpellAction->AdjustBuffs.SlowTicks!=BUFF_NOT_AFFECTED) {
-		CLprintf(file," slow-ticks %d",spell->SpellAction->AdjustBuffs.SlowTicks);
-	    }
-	    if (spell->SpellAction->AdjustBuffs.BloodlustTicks!=BUFF_NOT_AFFECTED) {
-		CLprintf(file," bloodlust-ticks %d",spell->SpellAction->AdjustBuffs.BloodlustTicks);
-	    }
-	    if (spell->SpellAction->AdjustBuffs.InvisibilityTicks!=BUFF_NOT_AFFECTED) {
-		CLprintf(file," invisibility-ticks %d",spell->SpellAction->AdjustBuffs.InvisibilityTicks);
-	    }
-	    if (spell->SpellAction->AdjustBuffs.InvincibilityTicks!=BUFF_NOT_AFFECTED) {
-		CLprintf(file," invincibility-ticks %d",spell->SpellAction->AdjustBuffs.InvincibilityTicks);
-	    }
-	    CLprintf(file,")\n");
-	} else if (spell->CastFunction==CastPolymorph) {
-	    CLprintf(file," '(polymorph new-form %s)\n",
-		    spell->SpellAction->Polymorph.NewForm->Ident);
-	} else if (spell->CastFunction==CastRaiseDead) {
-	    CLprintf(file," '(raise-dead unit-raised %s time-to-live %d)\n",
-		    spell->SpellAction->RaiseDead.UnitRaised->Ident,
-		    spell->SpellAction->RaiseDead.TTL);
-	} else if (spell->CastFunction==CastFlameShield) {
-	    CLprintf(file," '(flame-shield duration %d)\n",
-		    spell->SpellAction->FlameShield.TTL);
-	} else if (spell->CastFunction==CastRunes) {
-	    CLprintf(file," '(runes ttl %d damage %d)\n",
-		    spell->SpellAction->Runes.TTL,
-		    spell->SpellAction->Runes.Damage);
-	} else if (spell->CastFunction==CastSpawnPortal) {
-	    CLprintf(file," '(spawn-portal portal-type %s)\n",
-		    spell->SpellAction->SpawnPortal.PortalType->Ident);
-	} else if (spell->CastFunction==CastDeathCoil) {
-	    CLprintf(file," '(death-coil)\n");
-	    // FIXME: more?
-	} else if (spell->CastFunction==CastWhirlwind) {
-	    CLprintf(file," '(whirlwind duration %d)\n",
-		    spell->SpellAction->Whirlwind.TTL);
-	    // FIXME: more?
-	} 
+	CLprintf(file,"    'action ");
+	SaveSpellAction(file,spell->Action);
+	CLprintf(file,"\n");
 	//
 	//  FIXME: Save conditions
 	//
-	
+	if (spell->Conditions) {
+	    CLprintf(file,"    'condition ");
+	    SaveSpellCondition(file,spell->Conditions);
+	    CLprintf(file,"\n");
+	}
 	//
 	//  FIXME: Save autocast and AI info
 	//
diff --git a/src/stratagus/spells.cpp b/src/stratagus/spells.cpp
index 1690a6934..7f2d8796a 100644
--- a/src/stratagus/spells.cpp
+++ b/src/stratagus/spells.cpp
@@ -451,10 +451,10 @@ global int CastSpawnPortal(Unit *caster, const SpellType *spell __attribute__((u
     
     DebugCheck(!caster);
     DebugCheck(!spell);
-    DebugCheck(!spell->SpellAction);
-    DebugCheck(!spell->SpellAction->SpawnPortal.PortalType);
+    DebugCheck(!spell->Action);
+    DebugCheck(!spell->Action->Data.SpawnPortal.PortalType);
 
-    ptype = spell->SpellAction->SpawnPortal.PortalType;
+    ptype = spell->Action->Data.SpawnPortal.PortalType;
 
     portal = caster->Goal;
     if (portal) {
@@ -505,16 +505,16 @@ global int CastAreaBombardment(Unit *caster, const SpellType *spell,
 
     DebugCheck(!caster);
     DebugCheck(!spell);
-    DebugCheck(!spell->SpellAction);
+    DebugCheck(!spell->Action);
     //assert(x in range, y in range);
 
     mis = NULL;
 
-    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;
+    fields = spell->Action->Data.AreaBombardment.Fields;
+    shards = spell->Action->Data.AreaBombardment.Shards;
+    damage = spell->Action->Data.AreaBombardment.Damage;
+    offsetx = spell->Action->Data.AreaBombardment.StartOffsetX;
+    offsety = spell->Action->Data.AreaBombardment.StartOffsetY;
     while (fields--) {
     	// FIXME : radius configurable...
 	do {
@@ -568,7 +568,7 @@ global int CastDeathCoil(Unit *caster, const SpellType *spell, Unit *target,
 
     DebugCheck(!caster);
     DebugCheck(!spell);
-    DebugCheck(!spell->SpellAction);
+    DebugCheck(!spell->Action);
 // assert(target);
 // assert(x in range, y in range);
 
@@ -615,7 +615,7 @@ global int CastFireball(Unit *caster, const SpellType *spell,
 
     DebugCheck(!caster);
     DebugCheck(!spell);
-    DebugCheck(!spell->SpellAction);
+    DebugCheck(!spell->Action);
     DebugCheck(!spell->Missile);
 
     missile = NULL;
@@ -634,8 +634,8 @@ global int CastFireball(Unit *caster, const SpellType *spell,
     caster->Mana -= spell->ManaCost;
     PlayGameSound(spell->SoundWhenCast.Sound, MaxSampleVolume);
     missile = MakeMissile(spell->Missile, sx, sy, x, y);
-    missile->State = spell->SpellAction->Fireball.TTL - (dist - 1) * 2;
-    missile->TTL = spell->SpellAction->Fireball.TTL;
+    missile->State = spell->Action->Data.Fireball.TTL - (dist - 1) * 2;
+    missile->TTL = spell->Action->Data.Fireball.TTL;
     missile->Controller = SpellFireballController;
     missile->SourceUnit = caster;
     RefsDebugCheck(!caster->Refs || caster->Destroyed);
@@ -662,7 +662,7 @@ global int CastFlameShield(Unit* caster, const SpellType *spell, Unit *target,
 
     DebugCheck(!caster);
     DebugCheck(!spell);
-    DebugCheck(!spell->SpellAction);
+    DebugCheck(!spell->Action);
     DebugCheck(!target);
 //  assert(x in range, y in range);
     DebugCheck(!spell->Missile);
@@ -671,11 +671,11 @@ global int CastFlameShield(Unit* caster, const SpellType *spell, Unit *target,
 
     // get mana cost
     caster->Mana -= spell->ManaCost;
-    target->FlameShield = spell->SpellAction->FlameShield.TTL;
+    target->FlameShield = spell->Action->Data.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->TTL = spell->Action->Data.FlameShield.TTL + i * 7;
 	mis->TargetUnit = target;
 	mis->Controller = SpellFlameShieldController;
 	RefsDebugCheck(!target->Refs || target->Destroyed);
@@ -700,26 +700,26 @@ global int CastAdjustBuffs(Unit *caster, const SpellType *spell, Unit *target,
 {
     DebugCheck(!caster);
     DebugCheck(!spell);
-    DebugCheck(!spell->SpellAction);
+    DebugCheck(!spell->Action);
     DebugCheck(!target);
 
     // get mana cost
     caster->Mana -= spell->ManaCost;
 
-    if (spell->SpellAction->AdjustBuffs.SlowTicks!=BUFF_NOT_AFFECTED) {
-	target->Haste=spell->SpellAction->AdjustBuffs.HasteTicks;
+    if (spell->Action->Data.AdjustBuffs.SlowTicks!=BUFF_NOT_AFFECTED) {
+	target->Haste=spell->Action->Data.AdjustBuffs.HasteTicks;
     }
-    if (spell->SpellAction->AdjustBuffs.SlowTicks!=BUFF_NOT_AFFECTED) {
-	target->Slow=spell->SpellAction->AdjustBuffs.SlowTicks;
+    if (spell->Action->Data.AdjustBuffs.SlowTicks!=BUFF_NOT_AFFECTED) {
+	target->Slow=spell->Action->Data.AdjustBuffs.SlowTicks;
     }
-    if (spell->SpellAction->AdjustBuffs.BloodlustTicks!=BUFF_NOT_AFFECTED) {
-	target->Bloodlust=spell->SpellAction->AdjustBuffs.BloodlustTicks;
+    if (spell->Action->Data.AdjustBuffs.BloodlustTicks!=BUFF_NOT_AFFECTED) {
+	target->Bloodlust=spell->Action->Data.AdjustBuffs.BloodlustTicks;
     }
-    if (spell->SpellAction->AdjustBuffs.InvisibilityTicks!=BUFF_NOT_AFFECTED) {
-	target->Invisible=spell->SpellAction->AdjustBuffs.InvisibilityTicks;
+    if (spell->Action->Data.AdjustBuffs.InvisibilityTicks!=BUFF_NOT_AFFECTED) {
+	target->Invisible=spell->Action->Data.AdjustBuffs.InvisibilityTicks;
     }
-    if (spell->SpellAction->AdjustBuffs.InvincibilityTicks!=BUFF_NOT_AFFECTED) {
-	target->UnholyArmor=spell->SpellAction->AdjustBuffs.InvincibilityTicks;
+    if (spell->Action->Data.AdjustBuffs.InvincibilityTicks!=BUFF_NOT_AFFECTED) {
+	target->UnholyArmor=spell->Action->Data.AdjustBuffs.InvincibilityTicks;
     }
     CheckUnitToBeDrawn(target);
     PlayGameSound(spell->SoundWhenCast.Sound,MaxSampleVolume);
@@ -752,11 +752,11 @@ global int CastAdjustVitals(Unit *caster, const SpellType *spell, Unit *target,
 
     DebugCheck(!caster);
     DebugCheck(!spell);
-    DebugCheck(!spell->SpellAction);
+    DebugCheck(!spell->Action);
     DebugCheck(!target);
 
-    hp = spell->SpellAction->AdjustVitals.HP;
-    mana = spell->SpellAction->AdjustVitals.Mana;
+    hp = spell->Action->Data.AdjustVitals.HP;
+    mana = spell->Action->Data.AdjustVitals.Mana;
     manacost = spell->ManaCost;
 
     //  Healing and harming
@@ -784,8 +784,8 @@ global int CastAdjustVitals(Unit *caster, const SpellType *spell, Unit *target,
     if (manacost) {
 	castcount=min(castcount,caster->Mana/manacost);
     }
-    if (spell->SpellAction->AdjustVitals.MaxMultiCast) {
-	castcount=min(castcount,spell->SpellAction->AdjustVitals.MaxMultiCast);
+    if (spell->Action->Data.AdjustVitals.MaxMultiCast) {
+	castcount=min(castcount,spell->Action->Data.AdjustVitals.MaxMultiCast);
     }
 
     DebugCheck(castcount<0);
@@ -817,43 +817,6 @@ global int CastAdjustVitals(Unit *caster, const SpellType *spell, Unit *target,
     return 0;
 }
 
-/**
-**	Cast holy vision.
-**
-**	@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 CastHolyVision(Unit *caster, const SpellType *spell, Unit *target,
-    int x, int y)
-{
-    DebugCheck(!caster);
-    DebugCheck(!spell);
-    DebugCheck(!spell->SpellAction);
-//  assert(x in range, y in range);
-
-    caster->Mana -= spell->ManaCost;	// get mana cost
-    // FIXME: compact with summon.
-    target = MakeUnit(spell->SpellAction->HolyVision.revealer, caster->Player);
-    target->Orders[0].Action = UnitActionStill;
-    target->HP = 0;
-    target->X = x;
-    target->Y = y;
-//    target->TTL = GameCycle + CYCLES_PER_SECOND + CYCLES_PER_SECOND / 2;
-    target->CurrentSightRange = target->Stats->SightRange;
-    target->Removed = 1;
-    target->CurrentSightRange = target->Stats->SightRange;
-    MapMarkUnitSight(target);
-    target->TTL = GameCycle + target->Type->DecayRate * 6 * CYCLES_PER_SECOND;
-    CheckUnitToBeDrawn(target);
-    PlayGameSound(spell->SoundWhenCast.Sound, MaxSampleVolume);
-    return 0;
-}
-
 /**
 **	Cast polymorph.
 **
@@ -872,10 +835,10 @@ global int CastPolymorph(Unit *caster, const SpellType *spell, Unit *target,
 
     DebugCheck(!caster);
     DebugCheck(!spell);
-    DebugCheck(!spell->SpellAction);
+    DebugCheck(!spell->Action);
     DebugCheck(!target);
 
-    type = spell->SpellAction->Polymorph.NewForm;
+    type = spell->Action->Data.Polymorph.NewForm;
     DebugCheck(!type);
 
     caster->Player->Score += target->Type->Points;
@@ -926,10 +889,10 @@ global int CastRaiseDead(Unit *caster, const SpellType *spell, Unit *target,
 
     DebugCheck(!caster);
     DebugCheck(!spell);
-    DebugCheck(!spell->SpellAction);
+    DebugCheck(!spell->Action);
 //  assert(x in range, y in range);
 
-    skeleton = spell->SpellAction->RaiseDead.UnitRaised;
+    skeleton = spell->Action->Data.RaiseDead.UnitRaised;
     DebugCheck(!skeleton);
 
     corpses = &CorpseList;
@@ -992,7 +955,7 @@ global int CastRunes(Unit *caster, const SpellType *spell,
 
     DebugCheck(!caster);
     DebugCheck(spell);
-    DebugCheck(!spell->SpellAction);
+    DebugCheck(!spell->Action);
 //  assert(x in range, y in range);
 
     mis = NULL;
@@ -1010,7 +973,7 @@ global int CastRunes(Unit *caster, const SpellType *spell,
 		    y * TileSizeY + TileSizeY / 2,
 		    x * TileSizeX + TileSizeX / 2,
 		    y * TileSizeY + TileSizeY / 2);
-	    mis->TTL = spell->SpellAction->Runes.TTL;
+	    mis->TTL = spell->Action->Data.Runes.TTL;
 	    mis->Controller = SpellRunesController;
 	    caster->Mana -= spell->ManaCost / 5;
 	}
@@ -1036,14 +999,14 @@ global int CastSummon(Unit *caster, const SpellType *spell, Unit *target,
 
     DebugCheck(!caster);
     DebugCheck(!spell);
-    DebugCheck(!spell->SpellAction);
-    DebugCheck(!spell->SpellAction->Summon.UnitType);
+    DebugCheck(!spell->Action);
+    DebugCheck(!spell->Action->Data.Summon.UnitType);
 
     DebugLevel0("Summoning\n");
-    ttl=spell->SpellAction->Summon.TTL;
+    ttl=spell->Action->Data.Summon.TTL;
     caster->Mana -= spell->ManaCost;
     // FIXME: johns: the unit is placed on the wrong position
-    target = MakeUnit(spell->SpellAction->Summon.UnitType, caster->Player);
+    target = MakeUnit(spell->Action->Data.Summon.UnitType, caster->Player);
     target->X = x;
     target->Y = y;
     // set life span
@@ -1090,7 +1053,7 @@ global int CastWhirlwind(Unit *caster, const SpellType *spell,
 
     DebugCheck(!caster);
     DebugCheck(!spell);
-    DebugCheck(!spell->SpellAction);
+    DebugCheck(!spell->Action);
 //  assert(x in range, y in range);
 
     mis = NULL;
@@ -1100,7 +1063,7 @@ global int CastWhirlwind(Unit *caster, const SpellType *spell,
     mis = MakeMissile(spell->Missile,
 	    x * TileSizeX + TileSizeX / 2, y * TileSizeY + TileSizeY / 2,
 	    x * TileSizeX + TileSizeX / 2, y * TileSizeY + TileSizeY / 2);
-    mis->TTL = spell->SpellAction->Whirlwind.TTL;
+    mis->TTL = spell->Action->Data.Whirlwind.TTL;
     mis->Controller = SpellWhirlwindController;
     return 0;
 }
@@ -1208,7 +1171,6 @@ local int PassCondition(const Unit* caster,const SpellType* spell,const Unit* ta
 	}
 	if (condition->Building!=CONDITION_TRUE) {
 	    if ((condition->Building==CONDITION_ONLY)^(target->Type->Building)) {
-		DebugLevel0("QQQ\n");
 		return 0;
 	    }
 	}
@@ -1541,7 +1503,7 @@ global int SpellCast(Unit *caster, const SpellType *spell, Unit *target,
     int x, int y)
 {
     DebugCheck(!spell);
-    DebugCheck(!spell->CastFunction);
+    DebugCheck(!spell->Action->CastFunction);
     DebugCheck(!caster);
     DebugCheck(!SpellIsAvailable(caster->Player, spell->Ident));
 
@@ -1555,7 +1517,7 @@ global int SpellCast(Unit *caster, const SpellType *spell, Unit *target,
     }
     DebugLevel3Fn("Spell cast: (%s), %s -> %s (%d,%d)\n" _C_ spell->IdentName _C_
 	    unit->Type->Name _C_ target ? target->Type->Name : "none" _C_ x _C_ y);
-    return CanCastSpell(caster, spell, target, x, y) && spell->CastFunction(caster, spell, target, x, y);
+    return CanCastSpell(caster, spell, target, x, y) && spell->Action->CastFunction(caster, spell, target, x, y);
 }