changeset 488:a3939d5067c4

Spells
author Nomad
date Wed, 27 Feb 2013 22:15:30 +0200
parents 7887a9cf9e7b
children c92dd0242fb6
files Actor.cpp Party.h Player.cpp Player.h SaveLoad.cpp Spells.cpp Spells.h mm7_2.cpp mm7_3.cpp mm7_4.cpp mm7_6.cpp stru277.h stru6.cpp
diffstat 13 files changed, 775 insertions(+), 1007 deletions(-) [+]
line wrap: on
line diff
--- a/Actor.cpp	Wed Feb 27 17:29:05 2013 +0200
+++ b/Actor.cpp	Wed Feb 27 22:15:30 2013 +0200
@@ -561,7 +561,7 @@
               v10 = v105;
 LABEL_29:
               spellnuma = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360;
-              a1.uItemType = stru_4E3ACC[15].uItemType;
+              a1.uItemType = stru_4E3ACC[15].field_0;
               v118 = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360 / (v10 - 1);
               v11 = 0;
               if ( (signed int)pObjectList->uNumObjects <= 0 )
@@ -572,7 +572,7 @@
               else
               {
                 v12 = &pObjectList->pObjects->uObjectID;
-                while ( stru_4E3ACC[15].uItemType != *v12 )
+                while ( stru_4E3ACC[15].field_0 != *v12 )
                 {
                   ++v11;
                   v12 += 28;
@@ -642,7 +642,7 @@
               return;
             }
 LABEL_159:
-            a1.uItemType = stru_4E3ACC[spellnum].uItemType;
+            a1.uItemType = stru_4E3ACC[spellnum].field_0;
             v119 = 0.0;
             if ( (signed int)pObjectList->uNumObjects <= 0 )
             {
@@ -790,7 +790,7 @@
                 pitch = stru_5C6E00->Atan2(v31, (signed __int64)spellnumc);
               }
               a1.stru_24.Reset();
-              a1.uItemType = stru_4E3ACC[9].uItemType;
+              a1.uItemType = stru_4E3ACC[9].field_0;
               spellnumd = 0;
               if ( (signed int)pObjectList->uNumObjects <= 0 )
               {
@@ -1334,7 +1334,7 @@
   v70 = v108;
 LABEL_179:
   spellnume = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360;
-  a1.uItemType = stru_4E3ACC[93].uItemType;
+  a1.uItemType = stru_4E3ACC[SPELL_DARK_SHARPMETAL].field_0;
   v116 = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360 / (v70 - 1);
   v71 = 0;
   if ( (signed int)pObjectList->uNumObjects <= 0 )
@@ -1345,7 +1345,7 @@
   else
   {
     v72 = &pObjectList->pObjects->uObjectID;
-    while ( stru_4E3ACC[93].uItemType != *v72 )
+    while ( stru_4E3ACC[SPELL_DARK_SHARPMETAL].field_0 != *v72 )
     {
       ++v71;
       v72 += 28;
--- a/Party.h	Wed Feb 27 17:29:05 2013 +0200
+++ b/Party.h	Wed Feb 27 22:15:30 2013 +0200
@@ -28,26 +28,26 @@
 /*  347 */
 enum PARTY_BUFF_INDEX
 {
-  PARTY_BUFF_RESIST_AIR = 0x0,
-  PARTY_BUFF_RESIST_BODY = 0x1,
-  PARTY_BUFF_DAY_OF_GODS = 0x2,
-  PARTY_BUFF_DETECT_LIFE = 0x3,
-  PARTY_BUFF_RESIST_EARTH = 0x4,
-  PARTY_BUFF_FEATHER_FALL = 0x5,
-  PARTY_BUFF_RESIST_FIRE = 0x6,
-  PARTY_BUFF_FLY = 0x7,
-  PARTY_BUFF_HASTE = 0x8,
-  PARTY_BUFF_HEROISM = 0x9,
-  PARTY_BUFF_IMMOLATION = 0xA,
+  PARTY_BUFF_RESIST_AIR = 0,
+  PARTY_BUFF_RESIST_BODY = 1,
+  PARTY_BUFF_DAY_OF_GODS = 2,
+  PARTY_BUFF_DETECT_LIFE = 3,
+  PARTY_BUFF_RESIST_EARTH = 4,
+  PARTY_BUFF_FEATHER_FALL = 5,
+  PARTY_BUFF_RESIST_FIRE = 6,
+  PARTY_BUFF_FLY = 7,
+  PARTY_BUFF_HASTE = 8,
+  PARTY_BUFF_HEROISM = 9,
+  PARTY_BUFF_IMMOLATION = 10,
   PARTY_BUFF_INVISIBILITY = 11,
-  PARTY_BUFF_RESIST_MIND = 0xC,
-  PARTY_BUFF_PROTECTION_FROM_MAGIC = 0xD,
-  PARTY_BUFF_SHIELD = 0xE,
-  PARTY_BUFF_STONE_SKIN = 0xF,
-  PARTY_BUFF_TORCHLIGHT = 0x10,
-  PARTY_BUFF_RESIST_WATER = 0x11,
-  PARTY_BUFF_WATER_WALK = 0x12,
-  PARTY_BUFF_WIZARD_EYE = 0x13,
+  PARTY_BUFF_RESIST_MIND = 12,
+  PARTY_BUFF_PROTECTION_FROM_MAGIC = 13,
+  PARTY_BUFF_SHIELD = 14,
+  PARTY_BUFF_STONE_SKIN = 15,
+  PARTY_BUFF_TORCHLIGHT = 16,
+  PARTY_BUFF_RESIST_WATER = 17,
+  PARTY_BUFF_WATER_WALK = 18,
+  PARTY_BUFF_WIZARD_EYE = 19,
 };
 
 
--- a/Player.cpp	Wed Feb 27 17:29:05 2013 +0200
+++ b/Player.cpp	Wed Feb 27 22:15:30 2013 +0200
@@ -189,21 +189,14 @@
 //----- (00427730) --------------------------------------------------------
 bool Player::CanCastSpell(unsigned int uRequiredMana)
 {
-  int v2; // eax@1
-  bool result; // eax@2
-
-  v2 = this->sMana;
-  if ( v2 >= (signed int)uRequiredMana )
-  {
-    this->sMana = v2 - uRequiredMana;
-    result = 1;
-  }
-  else
-  {
-    pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-    result = 0;
-  }
-  return result;
+  if (sMana >= uRequiredMana)
+  {
+    sMana -= uRequiredMana;
+    return true;
+  }
+
+  pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+  return false;
 }
 
 
@@ -4150,7 +4143,7 @@
     v9 = *(int *)v8;
     v3 = (char *)&pItemsTable->pItems[v9].pIconName;
     if ( v3[28] == 12 )
-      v10 = *(&pSpellDatas[0].field_A + 10 * *((int *)&pSpellDatas[66].field_8 + v9));
+      v10 = *(&pSpellDatas[0].uExpertLevelRecovery + 10 * *((int *)&pSpellDatas[66].uNormalLevelRecovery + v9));
     else
       v10 = (unsigned __int16)word_4EDED8[(unsigned __int8)v3[29]];
     v47 = v10;
--- a/Player.h	Wed Feb 27 17:29:05 2013 +0200
+++ b/Player.h	Wed Feb 27 22:15:30 2013 +0200
@@ -5,7 +5,12 @@
 
 
 
-
+#define PLAYER_BUFF_BLESS            1
+#define PLAYER_BUFF_FATE             4
+#define PLAYER_BUFF_HAMMERHANDS      6
+#define PLAYER_BUFF_PAIN_REFLECTION 10
+#define PLAYER_BUFF_PRESERVATION    11
+#define PLAYER_BUFF_REGENERATION    12
 
 
 /*  301 */
@@ -565,6 +570,7 @@
   inline bool Dead()       {return pConditions[Condition::Condition_Dead] != 0;}
   inline bool Eradicated() {return pConditions[Condition::Condition_Eradicated] != 0;}
   inline bool Zombie()     {return pConditions[Condition::Condition_Zombie] != 0;}
+  inline bool Cursed()     {return pConditions[Condition::Condition_Cursed] != 0;}
 
 
 
--- a/SaveLoad.cpp	Wed Feb 27 17:29:05 2013 +0200
+++ b/SaveLoad.cpp	Wed Feb 27 22:15:30 2013 +0200
@@ -183,7 +183,7 @@
         if (pItemsTable->pItems[uItemID].uEquipType == 12)
         {
           __debugbreak();
-          v31 = *((int *)&pSpellDatas[66].field_8 + uItemID);
+          v31 = *((int *)&pSpellDatas[66].uNormalLevelRecovery + uItemID);
           stru_A750F8[i]._494836(v31, i + 9);
         }
       }
--- a/Spells.cpp	Wed Feb 27 17:29:05 2013 +0200
+++ b/Spells.cpp	Wed Feb 27 22:15:30 2013 +0200
@@ -16,7 +16,22 @@
 struct SpellStats *pSpellStats;
 
 
-stru324_spell stru_4E3ACC[102];
+stru324_spell stru_4E3ACC[100] =
+{
+  {10, 0},
+  {1000, 0}, {1010, 0}, {1020, 0}, {1030, 0}, {1040, 0}, {1050, 0}, {1060, 0}, {1070, 0}, {1080, 0}, {1090, 0}, {1100, 0},
+  {2000, 0}, {2010, 0}, {2020, 0}, {2030, 0}, {2040, 0}, {2050, 0}, {2060, 0}, {2070, 0}, {2080, 0}, {2090, 0}, {2100, 0},
+  {3000, 0}, {3010, 0}, {3020, 0}, {3030, 0}, {3040, 0}, {3050, 0}, {3060, 0}, {3070, 0}, {3080, 0}, {3090, 0}, {3100, 0},
+  {4000, 0}, {4010, 0}, {4020, 0}, {4030, 0}, {4040, 0}, {4050, 0}, {4060, 0}, {4070, 0}, {4080, 0}, {4090, 0}, {4100, 0},
+  {5000, 0}, {5010, 0}, {5020, 0}, {5030, 0}, {5040, 0}, {5050, 0}, {5060, 0}, {5070, 0}, {5080, 0}, {5090, 0}, {5100, 0},
+  {6000, 0}, {6010, 0}, {6020, 0}, {6030, 0}, {6040, 0}, {6050, 0}, {6060, 0}, {6070, 0}, {6080, 0}, {6090, 0}, {6100, 0},
+  {7000, 0}, {7010, 0}, {7020, 0}, {7030, 0}, {7040, 0}, {7050, 0}, {7060, 0}, {7070, 0}, {7080, 0}, {7090, 0}, {7100, 0},
+  {8000, 0}, {8010, 0}, {8020, 0}, {8030, 0}, {8040, 0}, {8050, 0}, {8060, 0}, {8070, 0}, {8080, 0}, {8090, 0}, {8100, 0},
+  {9000, 0}, {9010, 0}, {9020, 0}, {9030, 0}, {9040, 0}, {9050, 0}, {9060, 0}, {9070, 0}, {9080, 0}, {9090, 0}, {9100, 0}
+  //{545, 0},
+  //{545, 0},
+  //{555, 0}
+};
  //9 spellbook pages  11 spells per page 9*11 =99 +1 zero struct at 0. It counted from 1!
 SpellData pSpellDatas[100]={
 					 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
--- a/Spells.h	Wed Feb 27 17:29:05 2013 +0200
+++ b/Spells.h	Wed Feb 27 22:15:30 2013 +0200
@@ -111,7 +111,16 @@
   SPELL_DARK_SACRIFICE = 96,
   SPELL_DARK_DRAGON_BREATH = 97,
   SPELL_DARK_ARMAGEDDON = 98,
-  SPELL_DARK_SOULDRINKER = 99
+  SPELL_DARK_SOULDRINKER = 99,
+
+  SPELL_BOW_ARROW = 100,
+  SPELL_101 = 101,
+  SPELL_102 = 102,
+
+  SPELL_150 = 150,
+  SPELL_151 = 151,
+  SPELL_152 = 152,
+  SPELL_153 = 153
 };
 
 
@@ -199,7 +208,7 @@
 #pragma pack(push, 1)
 struct stru324_spell
 {
-  __int16 uItemType;
+  __int16 field_0;
   __int16 field_2;
 };
 #pragma pack(pop)
@@ -208,21 +217,28 @@
 #pragma pack(push, 1)
 struct SpellData
 {
-union
-	{
-  unsigned __int16 mana_per_skill[4];
-  struct
-	  {
-  unsigned __int16 uNormalLevelMana;
-  unsigned __int16 uExpertLevelMana;
-  unsigned __int16 uMasterLevelMana;
-  unsigned __int16 uMagisterLevelMana;
-	  };
-	};
-  unsigned __int16 field_8;
-  __int16 field_A;
-  __int16 field_C;
-  __int16 field_E;
+  union
+  {
+    unsigned __int16 mana_per_skill[4];
+    struct
+    {
+      unsigned __int16 uNormalLevelMana;
+      unsigned __int16 uExpertLevelMana;
+      unsigned __int16 uMasterLevelMana;
+      unsigned __int16 uMagisterLevelMana;
+    };
+  };
+  union
+  {
+    unsigned __int16 recovery_per_skill[4];
+    struct
+    {
+      unsigned __int16 uNormalLevelRecovery;
+      unsigned __int16 uExpertLevelRecovery;
+      unsigned __int16 uMasterLevelRecovery;
+      unsigned __int16 uMagisterLevelRecovery;
+    };
+  };
   __int16 field_10;
   __int16 field_12;
  // char field_12;
--- a/mm7_2.cpp	Wed Feb 27 17:29:05 2013 +0200
+++ b/mm7_2.cpp	Wed Feb 27 22:15:30 2013 +0200
@@ -14576,7 +14576,7 @@
 LABEL_74:
         if ( v50 )
           stru_A750F8[uActiveCharacter - 1]._494836(
-            *((int *)&pSpellDatas[66].field_8 + v50),
+            *((int *)&pSpellDatas[66].uNormalLevelRecovery + v50),
             uActiveCharacter - 1 + 9);
         break;
       case 1u:
--- a/mm7_3.cpp	Wed Feb 27 17:29:05 2013 +0200
+++ b/mm7_3.cpp	Wed Feb 27 22:15:30 2013 +0200
@@ -16405,7 +16405,7 @@
   LayingItem a1; // [sp+38h] [bp-7Ch]@12
   //LayingItem::LayingItem(&a1);
 
-  a1.uItemType = stru_4E3ACC[spellnum_].uItemType;
+  a1.uItemType = stru_4E3ACC[spellnum_].field_0;
   if ( spellnum_ > 58 )
   {
     if ( spellnum_ == 69 )
--- a/mm7_4.cpp	Wed Feb 27 17:29:05 2013 +0200
+++ b/mm7_4.cpp	Wed Feb 27 22:15:30 2013 +0200
@@ -3481,7 +3481,7 @@
       else
       {
         v11 = &pObjectList->pObjects->uObjectID;
-        while ( stru_4E3ACC[8].uItemType != *v11 )
+        while ( stru_4E3ACC[8].field_0 != *v11 )
         {
           ++v10;
           v11 += 28;
--- a/mm7_6.cpp	Wed Feb 27 17:29:05 2013 +0200
+++ b/mm7_6.cpp	Wed Feb 27 22:15:30 2013 +0200
@@ -2514,7 +2514,7 @@
 }
 
 //----- (00427DA0) --------------------------------------------------------
-unsigned int stru277::PushStru277(__int16 a2, __int16 uPlayerID, __int16 a4, __int16 a5, int a6)
+unsigned int stru277::PushStru277(__int16 a2, __int16 uPlayerID, __int16 skill_level, __int16 a5, int a6)
 {
   unsigned int result; // eax@1
   stru277 *v7; // edx@1
@@ -2535,9 +2535,9 @@
   if ( a5 & 0x10 )
     v8->uPlayerID_2 = uPlayerID;
   v8->field_6 = 0;
-  *(int *)&v8->field_C = 0;
+  v8->spell_target_pid = 0;
   v8->field_8 = a5;
-  v8->field_A = a4;
+  v8->forced_spell_skill_level = skill_level;
   v8->field_10 = a6;
 LABEL_8:
   if ( result == 10 )
@@ -2551,19 +2551,19 @@
   //int v1; // esi@1
   int v2; // edi@1
   stru277 *v3; // ebx@2
-  signed int v4; // eax@8
-  __int16 v5; // ax@9
+  //signed int v4; // eax@8
+  //__int16 v5; // ax@9
   signed int v6; // eax@14
-  __int16 v7; // ax@23
-  __int16 v8; // ax@24
-  char v9; // al@44
-  int v10; // eax@45
+  //__int16 v7; // ax@23
+  //__int16 v8; // ax@24
+  //char v9; // al@44
+  //int v10; // eax@45
   unsigned __int16 v11; // cx@45
   signed int v12; // ecx@48
   int v13; // eax@53
   unsigned __int8 v14; // zf@53
-  unsigned int v15; // edx@53
-  signed int v16; // eax@53
+  //unsigned int v15; // edx@53
+  //signed int v16; // eax@53
   Player *v17; // esi@70
   int v18; // eax@72
   int v19; // eax@74
@@ -2571,11 +2571,11 @@
   signed int i; // esi@76
   int v22; // eax@88
   __int16 v23; // ax@88
-  int v24; // ecx@93
-  int v25; // ecx@94
-  signed __int64 v26; // qax@100
-  char *v27; // ecx@100
-  unsigned __int64 v28; // qax@102
+  //int v24; // ecx@93
+  //int v25; // ecx@94
+  //signed __int64 v26; // qax@100
+  //char *v27; // ecx@100
+  //unsigned __int64 v28; // qax@102
   int v29; // ecx@105
   int v30; // ecx@106
   int v31; // eax@112
@@ -2603,7 +2603,7 @@
   int v53; // eax@153
   signed __int64 v54; // qax@164
   int v55; // edi@164
-  stru6 *v56; // eax@165
+  //stru6 *v56; // eax@165
   int v57; // eax@169
   signed __int64 v58; // qax@177
   int v59; // edi@177
@@ -2620,41 +2620,41 @@
   int v70; // ecx@214
   int v71; // ecx@215
   int v72; // ecx@216
-  __int16 v73; // ST1C_2@222
-  __int16 v74; // ST18_2@222
-  stru6 *v75; // eax@222
+  //__int16 v73; // ST1C_2@222
+  //__int16 v74; // ST18_2@222
+  //stru6 *v75; // eax@222
   int v76; // ecx@223
   int v77; // ecx@224
   int v78; // ecx@225
   int v79; // eax@227
-  int v80; // eax@232
-  __int16 v81; // ST18_2@245
-  stru6 *v82; // eax@245
+  //int v80; // eax@232
+  //__int16 v81; // ST18_2@245
+  //stru6 *v82; // eax@245
   signed int v83; // edi@245
-  __int16 v84; // ST18_2@245
-  stru6 *v85; // eax@245
-  __int16 v86; // ST18_2@245
-  stru6 *v87; // eax@245
-  __int16 v88; // ST18_2@245
-  stru6 *v89; // eax@245
+  //__int16 v84; // ST18_2@245
+  //stru6 *v85; // eax@245
+  //__int16 v86; // ST18_2@245
+  //stru6 *v87; // eax@245
+  //__int16 v88; // ST18_2@245
+  //stru6 *v89; // eax@245
   double v90; // st7@245
   int v91; // eax@250
   Player *v92; // eax@255
-  __int16 v93; // ST18_2@260
-  stru6 *v94; // eax@260
-  __int16 v95; // ST18_2@260
-  stru6 *v96; // eax@260
-  __int16 v97; // ST18_2@260
-  stru6 *v98; // eax@260
-  __int16 v99; // ST18_2@260
-  stru6 *v100; // eax@260
+  //__int16 v93; // ST18_2@260
+  //stru6 *v94; // eax@260
+  //__int16 v95; // ST18_2@260
+  //stru6 *v96; // eax@260
+  //__int16 v97; // ST18_2@260
+  //stru6 *v98; // eax@260
+  //__int16 v99; // ST18_2@260
+  //stru6 *v100; // eax@260
   int v101; // ecx@261
   int v102; // ecx@262
   int v103; // ecx@263
   int v104; // eax@265
   int v105; // edi@271
-  __int16 v106; // ST18_2@272
-  stru6 *v107; // eax@272
+  //__int16 v106; // ST18_2@272
+  //stru6 *v107; // eax@272
   __int16 v108; // ST1C_2@274
   __int16 v109; // ST18_2@274
   stru6 *v110; // eax@274
@@ -2675,27 +2675,27 @@
   int v125; // ecx@290
   int v126; // eax@292
   int v127; // eax@296
-  __int16 v128; // ST18_2@303
-  stru6 *v129; // eax@303
-  __int16 v130; // ST18_2@303
-  stru6 *v131; // eax@303
-  __int16 v132; // ST18_2@303
-  stru6 *v133; // eax@303
-  __int16 v134; // ST18_2@303
-  stru6 *v135; // eax@303
-  unsigned __int64 v136; // qax@304
-  char *v137; // ecx@304
+  //__int16 v128; // ST18_2@303
+  //stru6 *v129; // eax@303
+  //__int16 v130; // ST18_2@303
+  //stru6 *v131; // eax@303
+  //__int16 v132; // ST18_2@303
+  //stru6 *v133; // eax@303
+  //__int16 v134; // ST18_2@303
+  //stru6 *v135; // eax@303
+  //unsigned __int64 v136; // qax@304
+  //char *v137; // ecx@304
   int v138; // ecx@305
   int v139; // ecx@306
   int v140; // eax@308
-  __int16 v141; // ST18_2@311
-  stru6 *v142; // eax@311
-  __int16 v143; // ST18_2@311
-  stru6 *v144; // eax@311
-  __int16 v145; // ST18_2@311
-  stru6 *v146; // eax@311
-  __int16 v147; // ST18_2@311
-  stru6 *v148; // eax@311
+  //__int16 v141; // ST18_2@311
+  //stru6 *v142; // eax@311
+  //__int16 v143; // ST18_2@311
+  //stru6 *v144; // eax@311
+  //__int16 v145; // ST18_2@311
+  //stru6 *v146; // eax@311
+  //__int16 v147; // ST18_2@311
+  //stru6 *v148; // eax@311
   int v149; // ecx@312
   int v150; // ecx@313
   int v151; // ecx@314
@@ -2713,8 +2713,8 @@
   int v163; // eax@340
   signed int v164; // eax@340
   signed int v165; // edi@340
-  stru6 *v166; // eax@340
-  stru6 *v167; // eax@340
+  //stru6 *v166; // eax@340
+  //stru6 *v167; // eax@340
   signed int v168; // edi@343
   int v169; // eax@344
   int v170; // ecx@346
@@ -2722,15 +2722,15 @@
   int v172; // ecx@348
   int v173; // edi@350
   signed int v174; // edi@355
-  __int16 v175; // ST18_2@357
-  stru6 *v176; // eax@357
-  __int16 v177; // ST18_2@357
-  stru6 *v178; // eax@357
-  __int16 v179; // ST18_2@357
-  stru6 *v180; // eax@357
-  __int16 v181; // ST18_2@357
-  stru6 *v182; // eax@357
-  signed __int64 v183; // qax@357
+  //__int16 v175; // ST18_2@357
+  //stru6 *v176; // eax@357
+  //__int16 v177; // ST18_2@357
+  //stru6 *v178; // eax@357
+  //__int16 v179; // ST18_2@357
+  //stru6 *v180; // eax@357
+  //__int16 v181; // ST18_2@357
+  //stru6 *v182; // eax@357
+  //signed __int64 v183; // qax@357
   int v184; // ecx@358
   int v185; // ecx@359
   int v186; // ecx@360
@@ -2744,14 +2744,14 @@
   int v194; // ecx@384
   int v195; // eax@386
   int v196; // eax@387
-  __int16 v197; // ST18_2@395
-  stru6 *v198; // eax@395
-  __int16 v199; // ST18_2@395
-  stru6 *v200; // eax@395
-  __int16 v201; // ST18_2@395
-  stru6 *v202; // eax@395
-  __int16 v203; // ST18_2@395
-  stru6 *v204; // eax@395
+  //__int16 v197; // ST18_2@395
+  //stru6 *v198; // eax@395
+  //__int16 v199; // ST18_2@395
+  //stru6 *v200; // eax@395
+  //__int16 v201; // ST18_2@395
+  //stru6 *v202; // eax@395
+  //__int16 v203; // ST18_2@395
+  //stru6 *v204; // eax@395
   signed int v205; // edi@405
   int v206; // eax@407
   __int16 v207; // cx@407
@@ -2777,15 +2777,15 @@
   int v227; // esi@453
   unsigned int v228; // edi@454
   int v229; // edi@466
-  __int16 v230; // ST18_2@469
-  stru6 *v231; // eax@469
-  signed int v232; // esi@469
-  __int16 v233; // ST18_2@469
-  stru6 *v234; // eax@469
-  __int16 v235; // ST18_2@469
-  stru6 *v236; // eax@469
-  __int16 v237; // ST18_2@469
-  stru6 *v238; // eax@469
+  //__int16 v230; // ST18_2@469
+  //stru6 *v231; // eax@469
+  //signed int v232; // esi@469
+  //__int16 v233; // ST18_2@469
+  //stru6 *v234; // eax@469
+  //__int16 v235; // ST18_2@469
+  //stru6 *v236; // eax@469
+  //__int16 v237; // ST18_2@469
+  //stru6 *v238; // eax@469
   __int16 v239; // ST1C_2@469
   char *v240; // ecx@472
   double v241; // st7@478
@@ -2860,7 +2860,7 @@
   char v310; // sf@593
   unsigned __int8 v311; // of@593
   char v312; // cl@597
-  char v313; // al@606
+  char v313; // al@606pGame->GetStru6()
   int v314; // edx@607
   int j; // esi@607
   unsigned int v316; // eax@613
@@ -2878,43 +2878,43 @@
   int v328; // ecx@651
   int v329; // ecx@652
   int v330; // edi@654
-  __int16 v331; // ST18_2@658
-  stru6 *v332; // eax@658
-  __int16 v333; // ST18_2@658
-  stru6 *v334; // eax@658
-  __int16 v335; // ST18_2@658
-  stru6 *v336; // eax@658
-  __int16 v337; // ST18_2@658
-  stru6 *v338; // eax@658
+  //__int16 v331; // ST18_2@658
+  //stru6 *v332; // eax@658
+  //__int16 v333; // ST18_2@658
+  //stru6 *v334; // eax@658
+  //__int16 v335; // ST18_2@658
+  //stru6 *v336; // eax@658
+  //__int16 v337; // ST18_2@658
+  //stru6 *v338; // eax@658
   int v339; // ecx@659
   int v340; // ecx@660
   int v341; // eax@663
   signed int v342; // edi@668
   signed int v343; // edi@670
   unsigned __int64 v344; // ST08_8@670
-  __int16 v345; // ST1C_2@671
-  __int16 v346; // ST18_2@671
-  stru6 *v347; // eax@671
+  //__int16 v345; // ST1C_2@671
+  //__int16 v346; // ST18_2@671
+  //stru6 *v347; // eax@671
   int v348; // ecx@672
   int v349; // ecx@673
   int v350; // edi@676
   Player *v351; // edi@680
-  __int16 v352; // ST18_2@685
-  stru6 *v353; // eax@685
+  //__int16 v352; // ST18_2@685
+  //stru6 *v353; // eax@685
   int v354; // ecx@686
   int v355; // ecx@687
   int v356; // eax@689
   Player *v357; // edi@694
-  unsigned __int16 v358; // ST1C_2@695
-  __int16 v359; // ST18_2@695
-  stru6 *v360; // eax@695
-  __int16 v361; // ST1C_2@697
-  __int16 v362; // ST18_2@697
-  stru6 *v363; // eax@697
+  //unsigned __int16 v358; // ST1C_2@695
+  //__int16 v359; // ST18_2@695
+  //stru6 *v360; // eax@695
+  //__int16 v361; // ST1C_2@697
+  //__int16 v362; // ST18_2@697
+  //stru6 *v363; // eax@697
   int v364; // ecx@698
   int v365; // ecx@699
   int v366; // eax@701
-  stru6 *v367; // eax@704
+  //stru6 *v367; // eax@704
   int v368; // eax@704
   Actor *v369; // edi@705
   int v370; // eax@706
@@ -2936,9 +2936,9 @@
   signed int v386; // eax@736
   Player *v387; // edi@738
   int v388; // edi@740
-  unsigned __int16 v389; // ST1C_2@740
-  __int16 v390; // ST18_2@740
-  stru6 *v391; // eax@740
+  //unsigned __int16 v389; // ST1C_2@740
+  //__int16 v390; // ST18_2@740
+  //stru6 *v391; // eax@740
   int v392; // ecx@742
   int v393; // ecx@743
   int v394; // ecx@744
@@ -2948,22 +2948,22 @@
   int v398; // eax@757
   int v399; // eax@757
   char *v400; // esi@757
-  Game *v401; // ecx@759
-  __int16 v402; // ST1C_2@759
-  __int16 v403; // ST18_2@759
-  stru6 *v404; // eax@759
+  //Game *v401; // ecx@759
+  //__int16 v402; // ST1C_2@759
+  //__int16 v403; // ST18_2@759
+  //stru6 *v404; // eax@759
   int v405; // ecx@761
   int v406; // ecx@762
   int v407; // edi@765
-  __int16 v408; // ST1C_2@769
-  __int16 v409; // ST18_2@769
-  stru6 *v410; // eax@769
+  //__int16 v408; // ST1C_2@769
+  //__int16 v409; // ST18_2@769
+  //stru6 *v410; // eax@769
   int v411; // ecx@772
   int v412; // ecx@773
   int v413; // edi@775
-  __int16 v414; // ST1C_2@781
-  __int16 v415; // ST18_2@781
-  stru6 *v416; // eax@781
+  //__int16 v414; // ST1C_2@781
+  //__int16 v415; // ST18_2@781
+  //stru6 *v416; // eax@781
   int v417; // eax@787
   int v418; // ecx@789
   __int16 v419; // ax@791
@@ -2978,15 +2978,15 @@
   int v428; // ecx@825
   int v429; // ecx@826
   int v430; // eax@828
-  stru6 *v431; // eax@831
+  //stru6 *v431; // eax@831
   int v432; // eax@831
   Actor *v433; // edi@832
   int v434; // eax@833
   int v435; // ecx@837
   int v436; // ecx@838
-  __int16 v437; // ST1C_2@843
-  __int16 v438; // ST18_2@843
-  stru6 *v439; // eax@843
+  //__int16 v437; // ST1C_2@843
+  //__int16 v438; // ST18_2@843
+  //stru6 *v439; // eax@843
   int v440; // eax@843
   int v441; // eax@847
   int v442; // ecx@850
@@ -3001,9 +3001,9 @@
   int v451; // ecx@875
   int v452; // ecx@876
   int v453; // edi@878
-  __int16 v454; // ST1C_2@884
-  __int16 v455; // ST18_2@884
-  stru6 *v456; // eax@884
+  //__int16 v454; // ST1C_2@884
+  //__int16 v455; // ST18_2@884
+  //stru6 *v456; // eax@884
   int v457; // ecx@887
   int v458; // ecx@888
   int v459; // eax@890
@@ -3014,44 +3014,44 @@
   int v464; // ecx@905
   int v465; // ecx@906
   int v466; // edi@909
-  __int16 v467; // ST1C_2@913
-  __int16 v468; // ST18_2@913
-  stru6 *v469; // eax@913
+  //__int16 v467; // ST1C_2@913
+  //__int16 v468; // ST18_2@913
+  //stru6 *v469; // eax@913
   int v470; // edi@913
   int v471; // eax@917
   int v472; // eax@917
   char *v473; // esi@918
-  __int16 v474; // ST18_2@920
-  stru6 *v475; // eax@920
-  __int16 v476; // ST18_2@920
-  stru6 *v477; // eax@920
-  __int16 v478; // ST18_2@920
-  stru6 *v479; // eax@920
-  __int16 v480; // ST18_2@920
-  stru6 *v481; // eax@920
-  __int16 v482; // ST18_2@923
-  stru6 *v483; // eax@923
-  __int16 v484; // ST18_2@923
-  stru6 *v485; // eax@923
-  __int16 v486; // ST18_2@923
-  stru6 *v487; // eax@923
-  __int16 v488; // ST18_2@923
-  stru6 *v489; // eax@923
-  __int16 v490; // ST1C_2@924
-  __int16 v491; // ST18_2@924
-  stru6 *v492; // eax@924
+  //__int16 v474; // ST18_2@920
+  //stru6 *v475; // eax@920
+  //__int16 v476; // ST18_2@920
+  //stru6 *v477; // eax@920
+  //__int16 v478; // ST18_2@920
+  //stru6 *v479; // eax@920
+  //__int16 v480; // ST18_2@920
+  //stru6 *v481; // eax@920
+  //__int16 v482; // ST18_2@923
+  //stru6 *v483; // eax@923
+  //__int16 v484; // ST18_2@923
+  //stru6 *v485; // eax@923
+  //__int16 v486; // ST18_2@923
+  //stru6 *v487; // eax@923
+  //__int16 v488; // ST18_2@923
+  //stru6 *v489; // eax@923
+  //__int16 v490; // ST1C_2@924
+  //__int16 v491; // ST18_2@924
+  //stru6 *v492; // eax@924
   int v493; // ecx@925
   int v494; // ecx@926
-  __int16 v495; // ST1C_2@931
-  __int16 v496; // ST18_2@931
-  stru6 *v497; // eax@931
+  //__int16 v495; // ST1C_2@931
+  //__int16 v496; // ST18_2@931
+  //stru6 *v497; // eax@931
   int v498; // edi@931
   int v499; // eax@935
   int v500; // eax@935
   Player *v501; // edi@939
-  __int16 v502; // ST18_2@940
-  stru6 *v503; // eax@940
-  stru6 *v504; // eax@943
+  //__int16 v502; // ST18_2@940
+  //stru6 *v503; // eax@940
+  //stru6 *v504; // eax@943
   int v505; // eax@943
   int v506; // eax@943
   int v507; // edi@944
@@ -3070,14 +3070,14 @@
   int v520; // ecx@968
   int v521; // ecx@969
   int v522; // eax@971
-  __int16 v523; // ST18_2@975
-  stru6 *v524; // eax@975
-  __int16 v525; // ST18_2@975
-  stru6 *v526; // eax@975
-  __int16 v527; // ST18_2@975
-  stru6 *v528; // eax@975
-  __int16 v529; // ST18_2@975
-  stru6 *v530; // eax@975
+  //__int16 v523; // ST18_2@975
+  //stru6 *v524; // eax@975
+  //__int16 v525; // ST18_2@975
+  //stru6 *v526; // eax@975
+  //__int16 v527; // ST18_2@975
+  //stru6 *v528; // eax@975
+  //__int16 v529; // ST18_2@975
+  //stru6 *v530; // eax@975
   int v531; // eax@982
   int v532; // eax@982
   int v533; // edi@983
@@ -3088,36 +3088,36 @@
   int v538; // ecx@985
   int v539; // ecx@986
   int v540; // eax@988
-  __int16 v541; // ST18_2@991
-  stru6 *v542; // eax@991
-  __int16 v543; // ST18_2@991
-  stru6 *v544; // eax@991
-  __int16 v545; // ST18_2@991
-  stru6 *v546; // eax@991
-  __int16 v547; // ST18_2@991
+  //__int16 v541; // ST18_2@991
+  //stru6 *v542; // eax@991
+  //__int16 v543; // ST18_2@991
+  //stru6 *v544; // eax@991
+  //__int16 v545; // ST18_2@991
+  //stru6 *v546; // eax@991
+  //__int16 v547; // ST18_2@991
   stru6 *v548; // eax@991
   double v549; // st7@991
   unsigned __int16 v550; // di@991
   int v551; // ecx@993
   int v552; // ecx@994
   Player *v553; // edi@1001
-  __int16 v554; // ST18_2@1002
-  stru6 *v555; // eax@1002
-  __int16 v556; // ST18_2@1002
-  stru6 *v557; // eax@1002
-  __int16 v558; // ST18_2@1002
-  stru6 *v559; // eax@1002
-  __int16 v560; // ST18_2@1002
-  stru6 *v561; // eax@1002
+  //__int16 v554; // ST18_2@1002
+  //stru6 *v555; // eax@1002
+  //__int16 v556; // ST18_2@1002
+  //stru6 *v557; // eax@1002
+  //__int16 v558; // ST18_2@1002
+  //stru6 *v559; // eax@1002
+  //__int16 v560; // ST18_2@1002
+  //stru6 *v561; // eax@1002
   unsigned __int16 v562; // di@1005
   signed int v563; // eax@1010
   unsigned int v564; // ecx@1011
   signed int v565; // eax@1012
   Player **v566; // ecx@1012
   int v567; // eax@1012
-  unsigned __int16 v568; // ST1C_2@1012
-  __int16 v569; // ST18_2@1012
-  stru6 *v570; // eax@1012
+  //unsigned __int16 v568; // ST1C_2@1012
+  //__int16 v569; // ST18_2@1012
+  //stru6 *v570; // eax@1012
   Player *v571; // eax@1013
   char *v572; // ecx@1013
   int v573; // ecx@1017
@@ -3130,10 +3130,10 @@
   int v580; // eax@1031
   int v581; // edi@1031
   int v582; // eax@1031
-  __int16 v583; // ST1C_2@1034
-  __int16 v584; // ST18_2@1034
+  //__int16 v583; // ST1C_2@1034
+  //__int16 v584; // ST18_2@1034
   char *v585; // esi@1034
-  stru6 *v586; // eax@1034
+  //stru6 *v586; // eax@1034
   signed int v587; // eax@1035
   int v588; // ecx@1036
   int v589; // ecx@1037
@@ -3163,13 +3163,13 @@
   DDM_DLV_Header *v613; // eax@1108
   int v614; // eax@1116
   int v615; // edi@1119
-  __int16 v616; // ST1C_2@1122
-  __int16 v617; // ST18_2@1122
-  stru6 *v618; // eax@1122
+  //__int16 v616; // ST1C_2@1122
+  //__int16 v617; // ST18_2@1122
+  //stru6 *v618; // eax@1122
   Player *v619; // edi@1123
-  unsigned __int16 v620; // ST1C_2@1124
-  __int16 v621; // ST18_2@1124
-  stru6 *v622; // eax@1124
+  //unsigned __int16 v620; // ST1C_2@1124
+  //__int16 v621; // ST18_2@1124
+  //stru6 *v622; // eax@1124
   signed __int64 v623; // qax@1127
   int v624; // eax@1127
   int v625; // edi@1129
@@ -3183,44 +3183,44 @@
   Player *v633; // eax@1140
   signed int v634; // eax@1140
   int v635; // edi@1142
-  unsigned __int16 v636; // ST1C_2@1142
-  __int16 v637; // ST18_2@1142
-  stru6 *v638; // eax@1142
-  stru6 *v639; // eax@1143
+  //unsigned __int16 v636; // ST1C_2@1142
+  //__int16 v637; // ST18_2@1142
+  //stru6 *v638; // eax@1142
+  //stru6 *v639; // eax@1143
   int v640; // ecx@1146
   int v641; // ecx@1147
   int v642; // edi@1156
   int v643; // eax@1156
   int v644; // eax@1156
   signed int v645; // eax@1158
-  Player *v646; // ebx@1169
-  int v647; // edi@1169
-  signed int v648; // ST1C_4@1170
-  Player *v649; // ecx@1170
-  unsigned __int64 v650; // [sp-10h] [bp-E94h]@103
-  unsigned __int16 v651; // [sp-8h] [bp-E8Ch]@100
-  unsigned __int16 v652; // [sp-8h] [bp-E8Ch]@304
-  unsigned __int16 v653; // [sp-4h] [bp-E88h]@100
+  //Player *v646; // ebx@1169
+  //int v647; // edi@1169
+  //signed int v648; // ST1C_4@1170
+  //Player *v649; // ecx@1170
+  //unsigned __int64 v650; // [sp-10h] [bp-E94h]@103
+  //unsigned __int16 v651; // [sp-8h] [bp-E8Ch]@100
+  //unsigned __int16 v652; // [sp-8h] [bp-E8Ch]@304
+  //unsigned __int16 v653; // [sp-4h] [bp-E88h]@100
   int v654; // [sp-4h] [bp-E88h]@124
-  unsigned __int16 v655; // [sp-4h] [bp-E88h]@304
+  //unsigned __int16 v655; // [sp-4h] [bp-E88h]@304
   unsigned int v656; // [sp-4h] [bp-E88h]@639
   int v657; // [sp-4h] [bp-E88h]@807
-  int v658; // [sp+0h] [bp-E84h]@100
+  //int v658; // [sp+0h] [bp-E84h]@100
   int v659; // [sp+0h] [bp-E84h]@123
   int v660; // [sp+0h] [bp-E84h]@146
   Actor *v661; // [sp+0h] [bp-E84h]@164
-  int v662; // [sp+0h] [bp-E84h]@304
+  //int v662; // [sp+0h] [bp-E84h]@304
   unsigned __int64 v663; // [sp+0h] [bp-E84h]@639
   const char *v664; // [sp+0h] [bp-E84h]@802
   int v665; // [sp+0h] [bp-E84h]@807
   int v666; // [sp+4h] [bp-E80h]@12
   enum PLAYER_SKILL_TYPE v667; // [sp+4h] [bp-E80h]@25
-  unsigned __int8 v668; // [sp+4h] [bp-E80h]@100
+  //unsigned __int8 v668; // [sp+4h] [bp-E80h]@100
   int v669; // [sp+4h] [bp-E80h]@123
   Vec3_int_ *v670; // [sp+4h] [bp-E80h]@133
   int v671; // [sp+4h] [bp-E80h]@146
   unsigned int v672; // [sp+4h] [bp-E80h]@164
-  unsigned __int8 v673; // [sp+4h] [bp-E80h]@304
+  //unsigned __int8 v673; // [sp+4h] [bp-E80h]@304
   __int16 v674; // [sp+4h] [bp-E80h]@684
   const char *v675; // [sp+4h] [bp-E80h]@800
   int v676; // [sp+4h] [bp-E80h]@807
@@ -3318,30 +3318,31 @@
       goto LABEL_1166;
     }
     pPlayer = &pParty->pPlayers[v3->uPlayerID];
-    v4 = *(int *)&v3->field_C;
-    if (v4)
-      goto LABEL_18;
-    v5 = v3->spellnum;
-    if ( v3->spellnum == 79 || v5 == 48 || v5 == 94 )
-      v666 = 1;
-    else
-      v666 = 0;
-    a2 = stru_50C198.FindClosestActor(5120, 1, v666);
-    v6 = pMouse->uPointingObjectID;
-    if ( pMouse->uPointingObjectID && (v6 & 7) == OBJECT_Actor && pActors[v6 >> 3].CanAct() )
+
+    a2 = v3->spell_target_pid;
+    if (!a2)
     {
-      v4 = pMouse->uPointingObjectID;
-LABEL_18:
-      a2 = v4;
+      if (v3->spellnum == SPELL_LIGHT_DESTROY_UNDEAD ||
+          v3->spellnum == SPELL_SPIRIT_TURN_UNDEAD ||
+          v3->spellnum == SPELL_DARK_CONTROL_UNDEAD )
+        v666 = 1;
+      else
+        v666 = 0;
+
+      a2 = stru_50C198.FindClosestActor(5120, 1, v666);
+      v6 = pMouse->uPointingObjectID;
+      if ( pMouse->uPointingObjectID && (v6 & 7) == OBJECT_Actor && pActors[v6 >> 3].CanAct() )
+        a2 = pMouse->uPointingObjectID;
     }
-    a1.uItemType = stru_4E3ACC[v3->spellnum].uItemType;
+
+
+    a1.uItemType = stru_4E3ACC[v3->spellnum].field_0;
     if (a1.uItemType)
     {
       if ( (a2 & 7) == OBJECT_Actor)
       {
         memcpy(&v715, Actor::GetDirectionInfo((8 * v3->uPlayerID + 8) | OBJECT_Player, a2, &a3, 0), sizeof(v715));
         v2 = v723;
-        //v1 = 0;
       }
       else
       {
@@ -3349,94 +3350,46 @@
         v715.uPitchAngle = pParty->sRotationX;
       }
     }
-    v7 = v3->field_A;
+
     LODWORD(v725) = 0;
     _this = 0;
-    if (!v7)
+    if (v3->forced_spell_skill_level)
+    {
+      v11 = v3->forced_spell_skill_level;
+      v723 = v11 & 0x3F;
+      v2 = v723;
+    }
+    else
     {
-      v8 = v3->spellnum;
-      if ( v3->spellnum >= 12 )
-      {
-        if ( v8 >= 23 )
-        {
-          if ( v8 >= 34 )
-          {
-            if ( v8 >= 45 )
-            {
-              if ( v8 >= 56 )
-              {
-                if ( v8 >= 67 )
-                {
-                  if ( v8 >= 78 )
-                  {
-                    if ( v8 >= 89 )
-                    {
-                      if ( v8 >= 100 )
-                      {
-                        if ( v8 != 100 )
-                        {
-LABEL_45:
-                          HIWORD(v10) = HIWORD(pPlayer);
-                          v11 = pPlayer->pActiveSkills[LODWORD(v725)];
-                          goto LABEL_47;
-                        }
-                        v667 = (PLAYER_SKILL_TYPE)5;
-                      }
-                      else
-                      {
-                        v667 = (PLAYER_SKILL_TYPE)20;
-                      }
-                    }
-                    else
-                    {
-                      v667 = (PLAYER_SKILL_TYPE)19;
-                    }
-                  }
-                  else
-                  {
-                    v667 = (PLAYER_SKILL_TYPE)18;
-                  }
-                }
-                else
-                {
-                  v667 = (PLAYER_SKILL_TYPE)17;
-                }
-              }
-              else
-              {
-                v667 = (PLAYER_SKILL_TYPE)16;
-              }
-            }
-            else
-            {
-              v667 = (PLAYER_SKILL_TYPE)15;
-            }
-          }
-          else
-          {
-            v667 = (PLAYER_SKILL_TYPE)14;
-          }
-        }
-        else
-        {
-          v667 = (PLAYER_SKILL_TYPE)13;
-        }
-      }
-      else
-      {
-        v667 = (PLAYER_SKILL_TYPE)12;
-      }
+      //v667 = PLAYER_SKILL_STAFF;
+      if (v3->spellnum < SPELL_AIR_WIZARD_EYE)
+        v667 = PLAYER_SKILL_FIRE;
+      else if (v3->spellnum < SPELL_WATER_AWAKEN)
+        v667 = PLAYER_SKILL_AIR;
+      else if (v3->spellnum < SPELL_EARTH_STUN)
+        v667 = PLAYER_SKILL_WATER;
+      else if (v3->spellnum < SPELL_SPIRIT_DETECT_LIFE)
+        v667 = PLAYER_SKILL_EARTH;
+      else if (v3->spellnum < SPELL_MIND_REMOVE_FEAR)
+        v667 = PLAYER_SKILL_SPIRIT;
+      else if (v3->spellnum < SPELL_BODY_CURE_WEAKNESS)
+        v667 = PLAYER_SKILL_MIND;
+      else if (v3->spellnum < SPELL_LIGHT_LIGHT_BOLT)
+        v667 = PLAYER_SKILL_BODY;
+      else if (v3->spellnum < SPELL_DARK_REANIMATE)
+        v667 = PLAYER_SKILL_LIGHT;
+      else if (v3->spellnum < SPELL_BOW_ARROW)
+        v667 = PLAYER_SKILL_DARK;
+      else if (v3->spellnum == SPELL_BOW_ARROW)
+        v667 = PLAYER_SKILL_BOW;
+      else assert(false && "Unknown spell");
+
       LODWORD(v725) = v667;
-      v9 = pPlayer->GetActualSkillLevel(v667);
-      v723 = v9 & 0x3F;
-      v2 = v9 & 0x3F;
-      goto LABEL_45;
+      v723 = pPlayer->GetActualSkillLevel(v667) & 0x3F;
+      v2 = v723;
+      v11 = pPlayer->pActiveSkills[LODWORD(v725)];
     }
-    v11 = v7;
-    v10 = v7 & 0x3F;
-    v723 = v10;
-    v2 = v10;
-LABEL_47:
+
     if ( HIBYTE(v11) & 1 )
     {
       v12 = 4;
@@ -3446,7 +3399,6 @@
     {
       if ( (v11 & 0x80u) == 0 )
       {
-        v10 = ((v11 & 0x40) != 0) + 1;
         v731 = ((v11 & 0x40) != 0) + 1;
       }
       else
@@ -3455,30 +3407,23 @@
       }
       v12 = v731;
     }
-    LOWORD(v10) = v3->spellnum;
-    v730 = v10;
-    v13 = v12 + 10 * (signed __int16)v10;
-    v14 = v3->field_A == 0;
-    v15 = (unsigned __int16)word_4E3C66[v13];   // pSpellDatas [negoffset] indexing
-    v16 = *(unsigned __int16 *)((char *)&pSpellDatas[0].uMagisterLevelMana + v13 * 2);
-    uRequiredMana = v15;
-    sRecoveryTime = v16;
-    if ( !v14 )
+
+    v730 = v3->spellnum;
+    v13 = v12 + 10 * v3->spellnum;
+    if (v3->forced_spell_skill_level)
       uRequiredMana = 0;
-    if ( pParty->uCurrentHour == 0 )
-    {
-      if ( pParty->uCurrentMinute != 0 )
-        goto LABEL_62;
-      if ( LODWORD(v725) == 20 )
-        goto LABEL_61;
-    }
-    if ( pParty->uCurrentHour == 12 && pParty->uCurrentMinute == 0 && LODWORD(v725) == 19 )
-LABEL_61:
+    else 
+      uRequiredMana = pSpellDatas[v3->spellnum].mana_per_skill[v12 - 1];
+    sRecoveryTime = pSpellDatas[v3->spellnum].recovery_per_skill[v12 - 1];
+
+    if (LODWORD(v725) == PLAYER_SKILL_DARK && pParty->uCurrentHour == 0 && pParty->uCurrentMinute == 0 ||
+        LODWORD(v725) == PLAYER_SKILL_LIGHT && pParty->uCurrentHour == 12 && pParty->uCurrentMinute)
       uRequiredMana = 0;
-LABEL_62:
-    if ( (signed __int16)v730 >= 100 || ((pPlayer->sMana - uRequiredMana) & 0x80000000u) == 0 )
+
+    if (v3->spellnum >= PLAYER_SKILL_BOW || pPlayer->sMana >= uRequiredMana)
       break;
-    ShowStatusBarString(pGlobalTXT_LocalizationStrings[586], 2u);
+
+    ShowStatusBarString(pGlobalTXT_LocalizationStrings[586], 2u); // "Not enough spell points"
 LABEL_203:
     v3->spellnum = 0;
 LABEL_1166:
@@ -3486,19 +3431,41 @@
     if ( n >= 10 )
       return;
   }
-  if ( !pPlayer->pConditions[0] || (signed __int16)v730 >= 100 )
-    goto LABEL_69;
-  if ( rand() % 100 >= 50 )
-  {
-    v12 = v731;
-LABEL_69:
+  
+  if (pPlayer->Cursed() && v730 < SPELL_BOW_ARROW)
+    if (rand() % 100 < 50)
+    {
+      if ( pParty->bTurnBasedModeOn == 0 )
+      {
+        //v646 = pPlayer;
+        pPlayer->SetRecoveryTime((signed __int64)(flt_6BE3A4_debug_recmod1 * 213.3333333333333));
+        //v647 = n;
+      }
+      else
+      {
+        //v647 = n;
+        //v646 = pPlayer;
+        //v648 = sRecoveryTime;
+        //v649 = pPlayer;
+        pParty->pTurnBasedPlayerRecoveryTimes[v711[n].uPlayerID] = 100;
+        pPlayer->SetRecoveryTime(sRecoveryTime);
+        pTurnEngine->_40471C();
+      }
+
+      ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2u); // "Spell failed"
+      pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+      v711[n].spellnum = 0;
+      pPlayer->sMana -= uRequiredMana;
+      return;
+    }
+
     switch ( v3->spellnum )
     {
-      case 100:
-      case 101:
+      case SPELL_BOW_ARROW:
+      case SPELL_101:
         v17 = pPlayer;
         _this = (ItemGen *)1;
-        if ( (signed int)SkillToMastery(pPlayer->pActiveSkills[5]) >= 3 )
+        if ( (signed int)SkillToMastery(pPlayer->pActiveSkills[PLAYER_SKILL_BOW]) >= 3 )
           _this = (ItemGen *)2;
         sRecoveryTime = v17->GetAttackRecoveryTime(1);
         a1.stru_24.Reset();
@@ -3539,8 +3506,9 @@
             && pParty->bTurnBasedModeOn == 1 )
             ++pTurnEngine->field_1C;
         }
-        goto LABEL_83;
-      case 102:
+        goto play_sound_and_continue;
+
+      case SPELL_102:
         sRecoveryTime = pPlayer->GetAttackRecoveryTime(0);
         a1.stru_24.Reset();
         a1.field_48 = v3->spellnum;
@@ -3577,31 +3545,27 @@
                v3->uPlayerID + 1) != -1
           && pParty->bTurnBasedModeOn == 1 )
           ++pTurnEngine->field_1C;
-        goto LABEL_83;
-      case 1:
+        goto play_sound_and_continue;
+
+      case SPELL_FIRE_TORCH_LIGHT:
         LODWORD(v733) = 3600 * v2;
-        v24 = v12 - 2;
-        if ( v24 )
-        {
-          v25 = v24 - 1;
-          if ( v25 && v25 != 1 )
-            amount = 2;
-          else
-            amount = 4;
-        }
-        else
-        {
-          amount = 3;
-        }
+
+        switch (v12)
+        {
+          case 1: amount = 2; break;
+          case 2: amount = 3; break;
+          case 3:
+          case 4: amount = 4; break;
+          default:
+            assert(false);
+        }
+
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
-        v668 = 0;
-        v658 = 0;
-        v653 = amount;
-        v651 = v731;
-        v26 = (signed __int64)((double)(signed int)v733 * 4.2666669);
-        v27 = (char *)&pParty->pPartyBuffs[16];
-        goto LABEL_101;
+          goto play_sound_and_continue;
+
+        pParty->pPartyBuffs[PARTY_BUFF_TORCHLIGHT].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)3600 * v2 * 4.2666669), v731, amount, 0, 0);
+        goto LABEL_1056;
+
       case 7:
         v29 = v12 - 2;
         if ( v29 )
@@ -3643,7 +3607,7 @@
         if ( SHIDWORD(v733) > amount )
           goto LABEL_200;
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         a1.stru_24.Reset();
         a1.field_48 = v3->spellnum;
         a1.field_4C = v2;
@@ -3673,7 +3637,7 @@
         goto LABEL_124;
       case 20:
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         if (!a2)
           goto LABEL_200;
         if ( (a2 & 7) != OBJECT_Actor)
@@ -3710,7 +3674,7 @@
         goto LABEL_133;
       case 44:
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         v726 = (Player *)(a2 >> 3);
         HIDWORD(v733) = 836 * (a2 >> 3);
         if ( !stru_50C198.GetMagicalResistance(&pActors[a2 >> 3], 3u) )
@@ -3751,7 +3715,7 @@
         goto LABEL_139;
       case 79:
         if ( !pPlayer->CanCastSpell(uRequiredMana) || !a2 || (a2 & 7) != OBJECT_Actor)
-          goto LABEL_83;
+          goto play_sound_and_continue;
         v730 = a2 >> 3;
         v693 = 0;
         HIDWORD(v733) = (int)&pActors[a2 >> 3];
@@ -3801,7 +3765,7 @@
       case 78:
       case 97:
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         a1.stru_24.Reset();
         a1.field_48 = v3->spellnum;
         a1.field_4C = v2;
@@ -3833,7 +3797,7 @@
       case 76:
       case 90:
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         a1.stru_24.Reset();
         a1.field_48 = v3->spellnum;
         a1.field_4C = v2;
@@ -3850,10 +3814,10 @@
           goto LABEL_200;
         if ( pPlayer->CanCastSpell(uRequiredMana) )
           goto LABEL_152;
-        goto LABEL_83;
+        goto play_sound_and_continue;
       case 81:
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         if ( !a2
           || (a2 & 7) != OBJECT_Actor
           || (v730 = a2 >> 3,
@@ -3896,7 +3860,7 @@
 LABEL_174:
         LODWORD(v733) = v57;
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         if ( (a2 & 7) != OBJECT_Actor
           || (v721 = 836 * (a2 >> 3),
               LODWORD(v718) = (int)&pActors[a2 >> 3],
@@ -3918,7 +3882,7 @@
         goto LABEL_165;
       case 60:
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         v730 = 836 * (a2 >> 3);
         if ( !stru_50C198.GetMagicalResistance(&pActors[a2>>3], 7u) )
           goto LABEL_1056;
@@ -3950,7 +3914,7 @@
         goto LABEL_1086;
       case 92:
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         a1.stru_24.Reset();
         a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uItemType);
         a1.vPosition.x = pParty->vPosition.x;
@@ -4001,7 +3965,7 @@
         }
 LABEL_196:
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         v730c = &pParty->pPlayers[v3->uPlayerID_2].pInventoryItems[a2];
         v726 = (Player *)&pItemsTable->pItems[v730c->uItemID].pIconName;
         v730c->UpdateTempBonus(pParty->uTimePlayed);
@@ -4034,7 +3998,7 @@
                     dword_50C9A8 = 256;
 LABEL_1056:
                     LODWORD(v727) = 1;
-LABEL_83:
+play_sound_and_continue:
                     if ( v3->field_8 & 0x20 )
                     {
 LABEL_1162:
@@ -4095,7 +4059,8 @@
         ShowStatusBarString(v66, v67);
         pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
         goto LABEL_203;
-      case 71:
+
+      case SPELL_BODY_REGENERATION:
         v70 = v12 - 1;
         LODWORD(v733) = 3600 * v2;
         if ( v70 && (v71 = v70 - 1) != 0 )
@@ -4116,24 +4081,19 @@
           amount = 1;
         }
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
-        v73 = v3->uPlayerID_2;
-        v74 = v3->spellnum;
-        v75 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v74, v73);
-        v668 = 0;
-        v658 = 0;
-        v653 = amount;
-        v651 = v731;
-        v28 = pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)v733 * 4.2666669);
-        v27 = (char *)&pParty->pPlayers[v3->uPlayerID_2].pPlayerBuffs[12];
-        goto LABEL_103;
-      case 3:
-      case 14:
-      case 25:
-      case 36:
-      case 58:
-      case 69:
+          goto play_sound_and_continue;
+
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, v3->uPlayerID_2);
+
+        pParty->pPlayers[v3->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_REGENERATION].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)v733 * 4.2666669), v731, amount, 0, 0);
+        goto LABEL_1056;
+
+      case SPELL_FIRE_PROTECTION_FROM_FIRE:
+      case SPELL_AIR_PROTECTION_FROM_AIR:
+      case SPELL_WATER_PROTECTION_FROM_WATER:
+      case SPELL_EARTH_PROTECTION_FROM_EARTH:
+      case SPELL_MIND_PROTECTION_FROM_MIND:
+      case SPELL_BODY_PROTECTION_FROM_BODY:
         v76 = v12 - 1;
         LODWORD(v733) = 3600 * v2;
         if ( v76 )
@@ -4164,48 +4124,46 @@
           amount = v2;
         }
 LABEL_232:
-        v80 = v3->spellnum;
-        switch ( v80 )
-        {
-          case 3:
-            LODWORD(v725) = 6;
+        //v80 = v3->spellnum;
+        switch (v3->spellnum)
+        {
+          case SPELL_FIRE_PROTECTION_FROM_FIRE:
+            LODWORD(v725) = PARTY_BUFF_RESIST_FIRE;
             break;
-          case 14:
-            LODWORD(v725) = 0;
+          case SPELL_AIR_PROTECTION_FROM_AIR:
+            LODWORD(v725) = PARTY_BUFF_RESIST_AIR;
             break;
-          case 25:
-            LODWORD(v725) = 17;
+          case SPELL_WATER_PROTECTION_FROM_WATER:
+            LODWORD(v725) = PARTY_BUFF_RESIST_WATER;
+            break;
+          case SPELL_EARTH_PROTECTION_FROM_EARTH:
+            LODWORD(v725) = PARTY_BUFF_RESIST_EARTH;
             break;
-          case 36:
-            LODWORD(v725) = 4;
+          case SPELL_MIND_PROTECTION_FROM_MIND:
+            LODWORD(v725) = PARTY_BUFF_RESIST_MIND;
             break;
-          case 58:
-            LODWORD(v725) = 12;
+          case SPELL_BODY_PROTECTION_FROM_BODY:
+            LODWORD(v725) = PARTY_BUFF_RESIST_BODY;
             break;
           default:
-            if ( v80 != 69 )
-              goto LABEL_1166;
-            LODWORD(v725) = 1;
-            break;
+            assert(false);
+            goto LABEL_1166;
         }
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
-        v81 = v3->spellnum;
-        v82 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v81, 0);
+          goto play_sound_and_continue;
+
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 0);
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 1);
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 2);
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 3);
         v83 = 1;
-        v84 = v3->spellnum;
-        v85 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v84, 1);
-        v86 = v3->spellnum;
-        v87 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v86, 2);
-        v88 = v3->spellnum;
-        v89 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v88, 3);
+
         v90 = (double)(signed int)v733 * 4.2666669;
-        goto LABEL_304;
-      case 5:
+        pParty->pPartyBuffs[LODWORD(v725)].Apply(pParty->uTimePlayed + (signed int)(signed __int64)v90, v731, amount, 0, 0);
+          LODWORD(v727) = 1;
+        goto play_sound_and_continue;
+
+      case SPELL_FIRE_HASTE:
         if ( v12 <= 0 )
           goto LABEL_254;
         if ( v12 <= 2 )
@@ -4241,25 +4199,17 @@
           if (LODWORD(v727))
           {
             v726 = (Player *)((int)v733 << 7);
-            pParty->pPartyBuffs[8].Apply(
-              pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335),
-              v731, 0, 0, 0);
-            v93 = v3->spellnum;
-            v94 = pGame->GetStru6();
-            pGame->GetStru6()->SetPlayerBuffAnim(v93, 0);
-            v95 = v3->spellnum;
-            v96 = pGame->GetStru6();
-            pGame->GetStru6()->SetPlayerBuffAnim(v95, 1);
-            v97 = v3->spellnum;
-            v98 = pGame->GetStru6();
-            pGame->GetStru6()->SetPlayerBuffAnim(v97, 2);
-            v99 = v3->spellnum;
-            v100 = pGame->GetStru6();
-            pGame->GetStru6()->SetPlayerBuffAnim(v99, 3);
+            pParty->pPartyBuffs[PARTY_BUFF_HASTE].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, 0, 0, 0);
+
+            pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 0);
+            pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 1);
+            pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 2);
+            pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 3);
           }
         }
-        goto LABEL_83;
-      case 46:
+        goto play_sound_and_continue;
+
+      case SPELL_SPIRIT_BLESS:
         v101 = v12 - 1;
         if ( v101 && (v102 = v101 - 1) != 0 )
         {
@@ -4283,7 +4233,7 @@
 LABEL_269:
         amount = v2 + 5;
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         if ( v731 == 1 )
         {
           v108 = v3->uPlayerID_2;
@@ -4291,15 +4241,20 @@
           v110 = pGame->GetStru6();
           pGame->GetStru6()->SetPlayerBuffAnim(v109, v108);
           v111 = pOtherOverlayList->_4418B1(10000, v3->uPlayerID_2 + 310, 0, 65536);
-          v668 = 0;
+          //v668 = 0;
           v716 = v111;
-          v658 = v111;
-          v653 = amount;
+          //v658 = v111;
+          //v653 = amount;
           v726 = (Player *)((int)v733 << 7);
-          v651 = 1;
-          v28 = pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
-          v27 = (char *)&pParty->pPlayers[v3->uPlayerID_2].pPlayerBuffs[1];
-          goto LABEL_103;
+          //v651 = 1;
+          //v28 = pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
+          //v27 = (char *)&pParty->pPlayers[v3->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_BLESS];
+//LABEL_103:
+        //HIDWORD(v650) = HIDWORD(v28);
+//LABEL_104:
+        //LODWORD(v650) = v28;
+        pParty->pPlayers[v3->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_BLESS].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), 1, amount, v111, 0);
+        goto LABEL_1056;
         }
         v105 = 0;
         v726 = (Player *)((int)v733 << 7);
@@ -4307,9 +4262,7 @@
         v730b = pParty->pPlayers;//[0].pPlayerBuffs[1];
         do
         {
-          v106 = v3->spellnum;
-          v107 = pGame->GetStru6();
-          pGame->GetStru6()->SetPlayerBuffAnim(v106, v105);
+          pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, v105);
           v716 = pOtherOverlayList->_4418B1(10000, v105 + 310, 0, 65536);
 		  v730b->pPlayerBuffs[1].Apply(pParty->uTimePlayed + v717, v731, amount, v716, 0);
           ++v730b;
@@ -4317,6 +4270,7 @@
         }
 		while ( v730b <= &pParty->pPlayers[3] );
         goto LABEL_1056;
+
       case 52:
         if ( pPlayer->CanCastSpell(uRequiredMana) && a2 && (a2 & 7) == OBJECT_Actor)
         {
@@ -4386,10 +4340,11 @@
           }
           v3 = (stru277 *)HIDWORD(v733);
         }
-        goto LABEL_83;
-      case 17:
-      case 38:
-      case 51:
+        goto play_sound_and_continue;
+
+      case SPELL_AIR_SHIELD:
+      case SPELL_EARTH_STONESKIN:
+      case SPELL_SPIRIT_HEROISM:
         v123 = v12 - 1;
         if ( v123 && (v124 = v123 - 1) != 0 )
         {
@@ -4433,31 +4388,20 @@
           }
         }
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
-        v128 = v3->spellnum;
-        v129 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v128, 0);
+          goto play_sound_and_continue;
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 0);
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 1);
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 2);
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 3);
         v83 = 1;
-        v130 = v3->spellnum;
-        v131 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v130, 1);
-        v132 = v3->spellnum;
-        v133 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v132, 2);
-        v134 = v3->spellnum;
-        v135 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v134, 3);
         v726 = (Player *)((int)v733 << 7);
         v90 = (double)(signed int)((int)v733 << 7) * 0.033333335;
-LABEL_304:
-        v673 = 0;
-        v662 = 0;
-        v655 = amount;
-        v652 = v731;
-        v136 = pParty->uTimePlayed + (signed int)(signed __int64)v90;
-        v137 = (char *)&pParty->pPartyBuffs[LODWORD(v725)];
-        goto LABEL_977;
-      case 8:
+//LABEL_304:
+        pParty->pPartyBuffs[LODWORD(v725)].Apply(pParty->uTimePlayed + (signed int)(signed __int64)v90, v731, amount, 0, 0);
+          LODWORD(v727) = v83;
+        goto play_sound_and_continue;
+
+      case SPELL_FIRE_IMMOLATION:
         v138 = v12 - 2;
         if ( v138 && (v139 = v138 - 1) != 0 && v139 == 1 )
           v140 = 600 * v2;
@@ -4465,27 +4409,18 @@
           v140 = 60 * v2;
         LODWORD(v733) = v140;
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
-        v141 = v3->spellnum;
-        v142 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v141, 0);
-        v143 = v3->spellnum;
-        v144 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v143, 1);
-        v145 = v3->spellnum;
-        v146 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v145, 2);
-        v147 = v3->spellnum;
-        v148 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v147, 3);
-        v668 = 0;
+          goto play_sound_and_continue;
+
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 0);
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 1);
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 2);
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 3);
+
         v726 = (Player *)((int)v733 << 7);
-        v658 = 0;
-        v653 = v2;
-        v651 = v731;
-        v26 = (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
-        v27 = (char *)&pParty->pPartyBuffs[10];
-        goto LABEL_102;
+
+        pParty->pPartyBuffs[PARTY_BUFF_IMMOLATION].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, v2, 0, 0);
+        goto LABEL_1056;
+
       case 9:
         v149 = v12 - 1;
         if ( v149 && (v150 = v149 - 1) != 0 && (v151 = v150 - 1) != 0 )
@@ -4503,7 +4438,7 @@
           goto LABEL_201;
         }
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         LODWORD(v725) = a2 & 7;
         if ( (a2 & 7) == OBJECT_Actor)
         {
@@ -4596,7 +4531,7 @@
           goto LABEL_202;
         }
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         v726 = (Player *)sub_46A6AC((int)dword_50BF30, 100, 4096);
         v700.z = 0;
         v700.y = 0;
@@ -4632,19 +4567,18 @@
             v164 = a1.Create(0, 0, 0, 0);
             v165 = a2;
             DamageMonsterFromParty(8 * v164 | AI_OBJECT_LAYING_ITEM, dword_50BF30[a2], &v700);
-            v166 = pGame->GetStru6();
-            v166->_4A81CA(&a1);
-            v167 = pGame->GetStru6();
-            v167->FadeScreen__like_Turn_Undead_and_mb_Armageddon(0xFF3C1Eu, 0x40u);
+            pGame->GetStru6()->_4A81CA(&a1);
+            pGame->GetStru6()->FadeScreen__like_Turn_Undead_and_mb_Armageddon(0xFF3C1Eu, 0x40u);
             a2 = v165 + 1;
           }
           while ( v165 + 1 < (signed int)v726 );
         }
         goto LABEL_1056;
-      case 12:
+
+      case SPELL_AIR_WIZARD_EYE:
         LODWORD(v733) = 3600 * v2;
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         v168 = 0;
         do
         {
@@ -4652,14 +4586,13 @@
           v716 = v169;
         }
         while ( v168 < 4 );
-        v668 = 0;
+
         v732 = (int)v733 << 7;
-        v658 = 0;
-        v653 = 0;
-        v651 = v731;
-        v28 = pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
-        goto LABEL_992;
-      case 13:
+
+        pParty->pPartyBuffs[PARTY_BUFF_WIZARD_EYE].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, 0, 0, 0);
+        goto LABEL_1056;
+
+      case SPELL_AIR_FEATHER_FALL:
         v170 = v12 - 1;
         if ( !v170 )
         {
@@ -4680,33 +4613,22 @@
           LODWORD(v733) = v173;
         }
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         v174 = 0;
         do
           pOtherOverlayList->_4418B1(2010, v174++ + 100, 0, 65536);
         while ( v174 < 4 );
-        v175 = v3->spellnum;
-        v176 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v175, 0);
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 0);
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 1);
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 2);
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 3);
         v83 = 1;
-        v177 = v3->spellnum;
-        v178 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v177, 1);
-        v179 = v3->spellnum;
-        v180 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v179, 2);
-        v181 = v3->spellnum;
-        v182 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v181, 3);
-        v673 = 0;
         v732 = (int)v733 << 7;
-        v662 = 0;
-        v655 = 0;
-        v652 = v731;
-        v183 = (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
-        v137 = (char *)&pParty->pPartyBuffs[5];
-        goto LABEL_976;
-      case 15:
+          pParty->pPartyBuffs[PARTY_BUFF_FEATHER_FALL].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, 0, 0, 0);
+          LODWORD(v727) = v83;
+        goto play_sound_and_continue;
+
+      case SPELL_AIR_SPARKS:
         v184 = v12 - 1;
         if ( v184 )
         {
@@ -4734,7 +4656,7 @@
           amount = 3;
         }
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         v726 = (Player *)((signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360);
         v732 = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360 / (amount - 1);
         a1.stru_24.Reset();
@@ -4781,7 +4703,7 @@
           goto LABEL_462;
         }
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         v191 = 0;
         do
           pOtherOverlayList->_4418B1(2040, v191++ + 100, 0, 65536);
@@ -4789,7 +4711,8 @@
         BYTE1(pParty->uFlags) |= 1u;
         pParty->uFallSpeed = 1000;
         goto LABEL_1056;
-      case 19:
+
+      case SPELL_AIR_INVISIBILITY:
         v192 = v12 - 1;
         if ( !v192 )
         {
@@ -4826,34 +4749,17 @@
         }
         if ( pPlayer->CanCastSpell(uRequiredMana) )
         {
-          v197 = v3->spellnum;
-          v198 = pGame->GetStru6();
-          pGame->GetStru6()->SetPlayerBuffAnim(v197, 0);
+          pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 0);
+          pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 1);
+          pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 2);
+          pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 3);
           v83 = 1;
-          v199 = v3->spellnum;
-          v200 = pGame->GetStru6();
-          pGame->GetStru6()->SetPlayerBuffAnim(v199, 1);
-          v201 = v3->spellnum;
-          v202 = pGame->GetStru6();
-          pGame->GetStru6()->SetPlayerBuffAnim(v201, 2);
-          v203 = v3->spellnum;
-          v204 = pGame->GetStru6();
-          pGame->GetStru6()->SetPlayerBuffAnim(v203, 3);
-          v673 = 0;
           v732 = (int)v733 << 7;
-          v662 = 0;
-          v655 = amount;
-          v652 = v731;
-          v183 = (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
-          v137 = (char *)&pParty->pPartyBuffs[11];
-LABEL_976:
-          v136 = pParty->uTimePlayed + v183;
-LABEL_977:
-          ((SpellBuff *)v137)->Apply(v136, v652, v655, v662, v673);
-LABEL_978:
+
+          pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, amount, 0, 0);
           LODWORD(v727) = v83;
         }
-        goto LABEL_83;
+        goto play_sound_and_continue;
       case 21:
         if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
         {
@@ -4861,7 +4767,7 @@
 LABEL_462:
           ShowStatusBarString(v190, 2u);
           pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-          goto LABEL_83;
+          goto play_sound_and_continue;
         }
         if ( !pPlayers[v3->uPlayerID + 1]->GetMaxMana() )
         {
@@ -4873,7 +4779,7 @@
         if ( v731 == 2 || v731 == 3 || (amount = 0, v731 != 4) )
           amount = 1;
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         v205 = 0;
         do
           pOtherOverlayList->_4418B1(2090, v205++ + 100, 0, 65536);
@@ -4881,23 +4787,12 @@
         v206 = pOtherOverlayList->_4418B1(10008, 203, 0, 65536);
         v207 = v3->uPlayerID + 1;
         v716 = v206;
-        v668 = v207;
-        v658 = v206;
-        v653 = amount;
+
         v732 = (int)v733 << 7;
-        v651 = v731;
-        v26 = (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
-        v27 = (char *)&pParty->pPartyBuffs[7];
-LABEL_101:
-        v26 = (signed int)v26;
-LABEL_102:
-        v28 = pParty->uTimePlayed + v26;
-LABEL_103:
-        HIDWORD(v650) = HIDWORD(v28);
-LABEL_104:
-        LODWORD(v650) = v28;
-        ((SpellBuff *)v27)->Apply(v650, v651, v653, v658, v668);
+
+        pParty->pPartyBuffs[PARTY_BUFF_FLY].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, amount, v206, v207);
         goto LABEL_1056;
+
       case 22:
         v67 = 2;
         if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
@@ -4906,7 +4801,7 @@
           goto LABEL_202;
         }
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         v208 = a2 & 7;
         LODWORD(v725) = a2 & 7;
         if ( v208 == 3 )
@@ -5016,7 +4911,7 @@
         amount = v221;
 LABEL_433:
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         v222 = (char *)pParty->pPlayers;
         HIDWORD(v733) = (int)(char *)&pParty + 2508;
         break;
@@ -5042,7 +4937,7 @@
           amount = 3;
         }
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         HIDWORD(v733) = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360;
         if ( amount == 1 )
         {
@@ -5137,21 +5032,12 @@
           v229 = 3600 * v2;
         LODWORD(v733) = v229;
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         v716 = pOtherOverlayList->_4418B1(10005, 201, 0, 65536);
-        v230 = v3->spellnum;
-        v231 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v230, 0);
-        v232 = 1;
-        v233 = v3->spellnum;
-        v234 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v233, 1);
-        v235 = v3->spellnum;
-        v236 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v235, 2);
-        v237 = v3->spellnum;
-        v238 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v237, 3);
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 0);
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 1);
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 2);
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 3);
         v239 = v3->uPlayerID + 1;
         v732 = v229 << 7;
         pParty->pPartyBuffs[18].Apply(
@@ -5162,11 +5048,11 @@
           v239);
         if ( v731 == 4 )
           pParty->pPartyBuffs[18].uFlags = 1;
-        LODWORD(v727) = v232;
-        goto LABEL_83;
+        LODWORD(v727) = 1;
+        goto play_sound_and_continue;
       case 28:
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         v240 = (char *)&pParty->pPlayers[v3->uPlayerID_2].pInventoryItems[a2];
         y = v240;
         if ( pItemsTable->pItems[*(int *)v240].uEquipType != 12 || v240[20] & 2 )
@@ -5214,7 +5100,7 @@
         goto LABEL_1055;
       case 30:
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         uRequiredMana = 0;
         HIDWORD(v733) = 10 * v2;
         v730 = 1;
@@ -5308,7 +5194,7 @@
             v3->spellnum = 0;
             v318->PlaySound(SPEECH_43, 0);
           }
-          goto LABEL_83;
+          goto play_sound_and_continue;
         }
         if ( v731 != 2 )
         {
@@ -5614,7 +5500,7 @@
       case 31:
         amount = 10 * v2;
         if ( pPlayer->sMana < (signed int)uRequiredMana )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         if ( pParty->uFlags & 0x30 && v12 != 4 || rand() % 100 >= amount && v731 != 4 )
           goto LABEL_200;
         byte_50C0C0 = LOBYTE(v3->uPlayerID);
@@ -5637,7 +5523,7 @@
           dword_506338 = v3->spellnum;
           LOBYTE(v3->field_8) |= 0x20u;
         }
-        goto LABEL_83;
+        goto play_sound_and_continue;
       case 40:
         v320 = v12 - 2;
         if ( !v320 )
@@ -5657,7 +5543,7 @@
         amount = v322;
 LABEL_634:
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         v323 = v3->uPlayerID_2;
         v324 = (char *)&pParty->pPlayers[v323].pConditions[15];
         if ( !pParty->pPlayers[v323].pConditions[15] )
@@ -5670,7 +5556,7 @@
         goto LABEL_640;
       case 41:
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         a1.stru_24.Reset();
         a1.field_48 = v3->spellnum;
         a1.field_4C = v2;
@@ -5702,7 +5588,7 @@
         if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
           goto LABEL_200;
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         a1.uItemType = 4090;
         a1.stru_24.Reset();
         a1.field_48 = v3->spellnum;
@@ -5732,7 +5618,8 @@
 LABEL_125:
         v36 = pParty->sRotationY;
         goto LABEL_157;
-      case 45:
+
+      case SPELL_SPIRIT_DETECT_LIFE:
         v328 = v12 - 2;
         if ( v328 )
         {
@@ -5748,29 +5635,21 @@
         }
         LODWORD(v733) = v330;
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
-        v331 = v3->spellnum;
-        v332 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v331, 0);
+          goto play_sound_and_continue;
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 0);
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 1);
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 2);
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 3);
         v83 = 1;
-        v333 = v3->spellnum;
-        v334 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v333, 1);
-        v335 = v3->spellnum;
-        v336 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v335, 2);
-        v337 = v3->spellnum;
-        v338 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v337, 3);
-        v673 = 0;
+
         v732 = (int)v733 << 7;
-        v662 = 0;
-        v655 = 0;
-        v652 = v731;
-        v183 = (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
-        v137 = (char *)&pParty->pPartyBuffs[3];
-        goto LABEL_976;
-      case 47:
+
+         pParty->pPartyBuffs[PARTY_BUFF_DETECT_LIFE].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, 0, 0, 0);
+          LODWORD(v727) = v83;
+
+        goto play_sound_and_continue;
+
+      case SPELL_SPIRIT_FATE:
         LODWORD(v733) = 300;
         v339 = v12 - 2;
         if ( v339 )
@@ -5797,22 +5676,14 @@
         amount = v341;
 LABEL_667:
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
-        v342 = *(int *)&v3->field_C;
+          goto play_sound_and_continue;
+        v342 = v3->spell_target_pid;
         if ( v342 == 0 )
         {
-          v345 = v3->uPlayerID_2;
-          v346 = v3->spellnum;
-          v347 = pGame->GetStru6();
-          pGame->GetStru6()->SetPlayerBuffAnim(v346, v345);
-          v668 = 0;
-          v658 = 0;
-          v653 = amount;
-          LODWORD(v28) = LODWORD(pParty->uTimePlayed) + 1280;
-          v651 = v731;
-          HIDWORD(v650) = 0 + ((pParty->uTimePlayed + 1280) >> 32);
-          v27 = (char *)&pParty->pPlayers[v3->uPlayerID_2].pPlayerBuffs[4];
-          goto LABEL_104;
+          pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, v3->uPlayerID_2);
+
+          pParty->pPlayers[v3->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_FATE].Apply(pParty->uTimePlayed + 1280, v731, amount, 0, 0);
+          goto LABEL_1056;
         }
         if ( (v342 & 7) == OBJECT_Actor)
         {
@@ -5824,10 +5695,10 @@
           v672 = 0;
           v661 = &pActors[v343];
 LABEL_165:
-          v56 = pGame->GetStru6();
           pGame->GetStru6()->_4A7E89_sparkles_on_actor_after_it_casts_buff(v661, v672);
         }
         goto LABEL_1056;
+
       case 49:
         v348 = v12 - 2;
         if ( !v348 )
@@ -5850,7 +5721,7 @@
         amount = v350;
 LABEL_679:
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         v351 = &pParty->pPlayers[v3->uPlayerID_2];
         if ( !v351->pConditions[0] )
           goto LABEL_1056;
@@ -5868,7 +5739,7 @@
           goto LABEL_1056;
         v674 = v3->uPlayerID_2;
         goto LABEL_685;
-      case 50:
+      case SPELL_SPIRIT_PRESERVATION:
         v354 = v12 - 2;
         if ( v354 && (v355 = v354 - 1) != 0 && v355 == 1 )
           v356 = 900 * (v2 + 4);
@@ -5876,21 +5747,15 @@
           v356 = 300 * (v2 + 12);
         LODWORD(v733) = v356;
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         if ( v731 == 1 || v731 == 2 )
         {
-          v361 = v3->uPlayerID_2;
-          v362 = v3->spellnum;
-          v363 = pGame->GetStru6();
-          pGame->GetStru6()->SetPlayerBuffAnim(v362, v361);
-          v668 = 0;
+          pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, v3->uPlayerID_2);
+
           v732 = (int)v733 << 7;
-          v658 = 0;
-          v653 = 0;
-          v651 = v731;
-          v28 = pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
-          v27 = (char *)&pParty->pPlayers[v3->uPlayerID_2].pPlayerBuffs[11];
-          goto LABEL_103;
+
+          pParty->pPlayers[v3->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_PRESERVATION].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, 0, 0, 0);
+          goto LABEL_1056;
         }
         a2 = 0;
         v732 = (int)v733 << 7;
@@ -5898,11 +5763,8 @@
         v357 = pParty->pPlayers;//[0].pPlayerBuffs[11];
         do
         {
-          v358 = a2;
-          v359 = v3->spellnum;
-          v360 = pGame->GetStru6();
-          pGame->GetStru6()->SetPlayerBuffAnim(v359, v358);
-		  v357->pPlayerBuffs[11].Apply(pParty->uTimePlayed + v717, v731, 0, 0, 0);
+          pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, a2);
+		  v357->pPlayerBuffs[PLAYER_BUFF_PRESERVATION].Apply(pParty->uTimePlayed + v717, v731, 0, 0, 0);
           ++a2;
           ++v357;// = (SpellBuff *)((char *)v357 + 6972);
         }
@@ -5916,9 +5778,8 @@
           v366 = 300 * v2 + 180;
         LODWORD(v733) = v366;
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         v726 = (Player *)sub_46A6AC((int)dword_50BF30, 100, 4096);
-        v367 = pGame->GetStru6();
         pGame->GetStru6()->FadeScreen__like_Turn_Undead_and_mb_Armageddon(0xFFFFFFu, 0xC0u);
         ++a1.uItemType;
         a1.stru_24.Reset();
@@ -5963,7 +5824,7 @@
         else
           amount = 86400 * v2;
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         pOtherOverlayList->_4418B1(5080, v3->uPlayerID_2 + 100, 0, 65536);
         v373 = v3->uPlayerID_2;
         if ( !(HIDWORD(pParty->pPlayers[v373].pConditions[14]) | LODWORD(pParty->pPlayers[v373].pConditions[14])) )
@@ -6000,7 +5861,7 @@
           v380 = 3 * v2;
         amount = v380;
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         v381 = 0;
         HIDWORD(v733) = amount;
         v730 = 0;
@@ -6040,15 +5901,14 @@
               HIDWORD(v387->pConditions[13]) = 0;
             }
             v388 = HIDWORD(v733);
-            v389 = LOWORD(v682[HIDWORD(v733)]) - 1;
-            v390 = v3->spellnum;
-            v391 = pGame->GetStru6();
-            pGame->GetStru6()->SetPlayerBuffAnim(v390, v389);
+
+            pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, LOWORD(v682[HIDWORD(v733)]) - 1);
             HIDWORD(v733) = v388 + 1;
           }
           while ( v388 + 1 < v730 );
         }
         goto LABEL_1056;
+
       case 55:
         v392 = v12 - 1;
         if ( !v392 )
@@ -6074,7 +5934,7 @@
           amount = 0;
 LABEL_751:
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         v396 = v3->uPlayerID_2;
         if ( HIDWORD(pParty->pPlayers[v396].pConditions[16]) | LODWORD(pParty->pPlayers[v396].pConditions[16])
           || HIDWORD(pParty->pPlayers[v396].pConditions[14]) | LODWORD(pParty->pPlayers[v396].pConditions[14]) )
@@ -6109,18 +5969,18 @@
           }
           v83 = 1;
           pParty->pPlayers[v3->uPlayerID_2].SetCondition(1u, 1);
-          v401 = pGame;
+
           pParty->pPlayers[v3->uPlayerID_2].sHealth = 1;
-          v402 = v3->uPlayerID_2;
-          v403 = v3->spellnum;
-          v404 = pGame->GetStru6();
-          pGame->GetStru6()->SetPlayerBuffAnim(v403, v402);
+
+          pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, v3->uPlayerID_2);
         }
         else
         {
           v83 = 1;
         }
-        goto LABEL_978;
+          LODWORD(v727) = v83;
+        goto play_sound_and_continue;
+
       case 61:
         v405 = v12 - 2;
         if ( !v405 )
@@ -6143,11 +6003,9 @@
         amount = v407;
 LABEL_768:
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
-        v408 = v3->uPlayerID_2;
-        v409 = v3->spellnum;
-        v410 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v409, v408);
+          goto play_sound_and_continue;
+
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, v3->uPlayerID_2);
         v323 = v3->uPlayerID_2;
         v324 = (char *)&pParty->pPlayers[v323].pConditions[12];
         if ( !pParty->pPlayers[v323].pConditions[12] )
@@ -6184,11 +6042,9 @@
         amount = v413;
 LABEL_780:
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
-        v414 = v3->uPlayerID_2;
-        v415 = v3->spellnum;
-        v416 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v415, v414);
+          goto play_sound_and_continue;
+
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, v3->uPlayerID_2);
         v323 = v3->uPlayerID_2;
         v324 = (char *)&pParty->pPlayers[v323].pConditions[3];
         if ( !pParty->pPlayers[v323].pConditions[3] )
@@ -6201,7 +6057,7 @@
         goto LABEL_640;
       case 59:
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         if ( a2 == 0 || (a2 & 7) != OBJECT_Actor)
           goto LABEL_1056;
         v417 = (int)&pActors[a2 >> 3];
@@ -6292,7 +6148,7 @@
         }
         amount = v425;
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         v426 = a2 >> 3;
         if ( (a2 & 7) != OBJECT_Actor)
           goto LABEL_1056;
@@ -6316,14 +6172,14 @@
         goto LABEL_1086;
       case 66:
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         amount = 600 * v2;
         v427 = a2 >> 3;
         if ( (a2 & 7) != OBJECT_Actor)
           goto LABEL_1056;
         v730 = 836 * v427;
         if ( MonsterStats::BelongsToSupertype(pActors[v427].pMonsterInfo.uID, MONSTER_SUPERTYPE_UNDEAD) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         if ( stru_50C198.GetMagicalResistance(&pActors[v427], 7u) )
         {
           pActors[v427].pActorBuffs[9].Reset();
@@ -6348,9 +6204,8 @@
           v430 = 180 * v2;
         amount = v430;
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         v726 = (Player *)sub_46A6AC((int)dword_50BF30, 100, 4096);
-        v431 = pGame->GetStru6();
         pGame->GetStru6()->FadeScreen__like_Turn_Undead_and_mb_Armageddon(0xA0A0Au, 0xC0u);
         ++a1.uItemType;
         a1.stru_24.Reset();
@@ -6397,11 +6252,9 @@
         else
           amount = 86400 * v2;
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
-        v437 = v3->uPlayerID_2;
-        v438 = v3->spellnum;
-        v439 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v438, v437);
+          goto play_sound_and_continue;
+
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, v3->uPlayerID_2);
         v440 = v3->uPlayerID_2;
         if ( HIDWORD(pParty->pPlayers[v440].pConditions[5]) | LODWORD(pParty->pPlayers[v440].pConditions[5]) )
         {
@@ -6444,7 +6297,7 @@
         }
         amount = v444;
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         v445 = a2 >> 3;
         if ( (a2 & 7) == OBJECT_Item)
         {
@@ -6530,11 +6383,9 @@
         amount = v453;
 LABEL_883:
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
-        v454 = v3->uPlayerID_2;
-        v455 = v3->spellnum;
-        v456 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v455, v454);
+          goto play_sound_and_continue;
+
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, v3->uPlayerID_2);
         v323 = v3->uPlayerID_2;
         v324 = (char *)&pParty->pPlayers[v323].pConditions[1];
         if ( !pParty->pPlayers[v323].pConditions[1] )
@@ -6575,17 +6426,15 @@
         }
         amount = v459;
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
-        v460 = *(int *)&v3->field_C;
+          goto play_sound_and_continue;
+        v460 = v3->spell_target_pid;
         if (!v460)
         {
           pParty->pPlayers[v3->uPlayerID_2].Heal(amount);
 LABEL_904:
           v674 = v3->uPlayerID_2;
 LABEL_685:
-          v352 = v3->spellnum;
-          v353 = pGame->GetStru6();
-          pGame->GetStru6()->SetPlayerBuffAnim(v352, v674);
+          pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, v674);
         }
         else
         {
@@ -6634,11 +6483,9 @@
         amount = v466;
 LABEL_912:
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
-        v467 = v3->uPlayerID_2;
-        v468 = v3->spellnum;
-        v469 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v468, v467);
+          goto play_sound_and_continue;
+
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, v3->uPlayerID_2);
         v470 = v3->uPlayerID_2;
         if ( !(HIDWORD(pParty->pPlayers[v470].pConditions[6]) | LODWORD(pParty->pPlayers[v470].pConditions[6]))
           && !(HIDWORD(pParty->pPlayers[v470].pConditions[8]) | LODWORD(pParty->pPlayers[v470].pConditions[8]))
@@ -6667,76 +6514,51 @@
         v663 = (signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2);
         v656 = 10;
         goto LABEL_937;
+
+
       case 75:
         amount = v2;
         LODWORD(v733) = 3600 * v2;
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
-        v474 = v3->spellnum;
-        v475 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v474, 0);
-        v476 = v3->spellnum;
-        v477 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v476, 1);
-        v478 = v3->spellnum;
-        v479 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v478, 2);
-        v480 = v3->spellnum;
-        v481 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v480, 3);
-        v668 = 0;
+          goto play_sound_and_continue;
+
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 0);
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 1);
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 2);
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 3);
+
         v732 = (int)v733 << 7;
-        v658 = 0;
-        v653 = v2;
-        v651 = v731;
-        v26 = (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
-        v27 = (char *)&pParty->pPartyBuffs[13];
-        goto LABEL_101;
+
+        pParty->pPartyBuffs[PARTY_BUFF_PROTECTION_FROM_MAGIC].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, v2, 0, 0);
+        goto LABEL_1056;
+
       case 73:
         LODWORD(v733) = 3600 * v2;
         amount = v2;
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         if ( v731 == 4 )
         {
-          v482 = v3->spellnum;
-          v483 = pGame->GetStru6();
-          pGame->GetStru6()->SetPlayerBuffAnim(v482, 0);
-          v484 = v3->spellnum;
-          v485 = pGame->GetStru6();
-          pGame->GetStru6()->SetPlayerBuffAnim(v484, 1);
-          v486 = v3->spellnum;
-          v487 = pGame->GetStru6();
-          pGame->GetStru6()->SetPlayerBuffAnim(v486, 2);
-          v488 = v3->spellnum;
-          v489 = pGame->GetStru6();
-          pGame->GetStru6()->SetPlayerBuffAnim(v488, 3);
+          pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 0);
+          pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 1);
+          pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 2);
+          pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 3);
           v732 = (int)v733 << 7;
           v717 = (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
-          pParty->pPlayers[0].pPlayerBuffs[6].Apply(pParty->uTimePlayed + v717, 4u, v2, v2, 0);
-          pParty->pPlayers[1].pPlayerBuffs[6].Apply(pParty->uTimePlayed + v717, 4u, v2, v2, 0);
-          pParty->pPlayers[2].pPlayerBuffs[6].Apply(pParty->uTimePlayed + v717, 4u, v2, v2, 0);
-          v668 = 0;
-          v658 = v2;
-          v653 = v2;
-          LODWORD(v28) = LODWORD(pParty->uTimePlayed) + v717;
-          v651 = 4;
-          HIDWORD(v650) = (pParty->uTimePlayed + v717) >> 32;
-          v27 = (char *)&pParty->pPlayers[3].pPlayerBuffs[6];
-          goto LABEL_104;
-        }
-        v490 = v3->uPlayerID_2;
-        v491 = v3->spellnum;
-        v492 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v491, v490);
-        v668 = 0;
+          pParty->pPlayers[0].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].Apply(pParty->uTimePlayed + v717, 4u, v2, v2, 0);
+          pParty->pPlayers[1].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].Apply(pParty->uTimePlayed + v717, 4u, v2, v2, 0);
+          pParty->pPlayers[2].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].Apply(pParty->uTimePlayed + v717, 4u, v2, v2, 0);
+
+          pParty->pPlayers[3].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].Apply(pParty->uTimePlayed + v717, 4, v2, v2, 0);
+          goto LABEL_1056;
+          //goto LABEL_104;
+        }
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, v3->uPlayerID_2);
+
         v732 = (int)v733 << 7;
-        v658 = v2;
-        v653 = v2;
-        v651 = v731;
-        v28 = pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
-        v27 = (char *)&pParty->pPlayers[v3->uPlayerID_2].pPlayerBuffs[6];
-        goto LABEL_103;
+
+        pParty->pPlayers[v3->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, v2, v2, 0);
+        goto LABEL_1056;
       case 74:
         v493 = v12 - 2;
         if ( v493 && (v494 = v493 - 1) != 0 && v494 == 1 )
@@ -6744,11 +6566,9 @@
         else
           amount = 86400 * v2;
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
-        v495 = v3->uPlayerID_2;
-        v496 = v3->spellnum;
-        v497 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v496, v495);
+          goto play_sound_and_continue;
+
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, v3->uPlayerID_2);
         v498 = v3->uPlayerID_2;
         if ( !(HIDWORD(pParty->pPlayers[v498].pConditions[7]) | LODWORD(pParty->pPlayers[v498].pConditions[7]))
           && !(HIDWORD(pParty->pPlayers[v498].pConditions[9]) | LODWORD(pParty->pPlayers[v498].pConditions[9]))
@@ -6787,14 +6607,12 @@
       {
         amount = 5 * v2 + 10;
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         v501 = pParty->pPlayers;
         int v1 = 0;
         do
         {
-          v502 = v3->spellnum;
-          v503 = pGame->GetStru6();
-          pGame->GetStru6()->SetPlayerBuffAnim(v502, v1);
+          pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, v1);
           v501->Heal(amount);
           ++v501;
           ++v1;
@@ -6805,8 +6623,8 @@
       case 80:
         sRecoveryTime -= v2;
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
-        v504 = pGame->GetStru6();
+          goto play_sound_and_continue;
+
         pGame->GetStru6()->FadeScreen__like_Turn_Undead_and_mb_Armageddon(0xAFF0Au, 0xC0u);
         v505 = sub_46A6AC((int)dword_50BF30, 100, 4096);
         ++a1.uItemType;
@@ -6918,7 +6736,7 @@
           goto LABEL_201;
         }
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         sub_44FA4C_spawn_light_elemental(v3->uPlayerID, v731, v733);
         goto LABEL_1056;
       case 83:
@@ -6947,28 +6765,21 @@
         }
         amount = v522;
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
-        v523 = v3->spellnum;
-        v524 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v523, 0);
+          goto play_sound_and_continue;
+
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 0);
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 1);
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 2);
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 3);
         v83 = 1;
-        v525 = v3->spellnum;
-        v526 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v525, 1);
-        v527 = v3->spellnum;
-        v528 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v527, 2);
-        v529 = v3->spellnum;
-        v530 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v529, 3);
-        v673 = 0;
+
         v732 = (int)v733 << 7;
-        v662 = 0;
-        v655 = amount;
-        v652 = v731;
-        v183 = (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
-        v137 = (char *)&pParty->pPartyBuffs[2];
-        goto LABEL_976;
+
+        pParty->pPartyBuffs[PARTY_BUFF_DAY_OF_GODS].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, amount, 0, 0);
+          LODWORD(v727) = v83;
+
+        goto play_sound_and_continue;
+
       case 84:
         v67 = 2;
         if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor)
@@ -6977,7 +6788,7 @@
           goto LABEL_202;
         }
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         v531 = sub_46A6AC((int)dword_50BF30, 100, 4096);
         ++a1.uItemType;
         v726 = (Player *)v531;
@@ -7022,7 +6833,8 @@
         v537 = pGame->GetStru6();
         pGame->GetStru6()->_4A8BFC();
         goto LABEL_1056;
-      case 85:
+
+      case SPELL_LIGHT_DAY_OF_PROTECTION:
         v538 = v12 - 2;
         if ( v538 && (v539 = v538 - 1) != 0 && v539 == 1 )
         {
@@ -7037,42 +6849,31 @@
         v730 = v540;
         LODWORD(v733) = v540;
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
-        v541 = v3->spellnum;
-        v542 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v541, 0);
-        v543 = v3->spellnum;
-        v544 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v543, 1);
-        v545 = v3->spellnum;
-        v546 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v545, 2);
-        v547 = v3->spellnum;
-        v548 = pGame->GetStru6();
-        pGame->GetStru6()->SetPlayerBuffAnim(v547, 3);
+          goto play_sound_and_continue;
+
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 0);
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 1);
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 2);
+        pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 3);
+
         v732 = v730 << 7;
         v549 = (double)(v730 << 7) * 0.033333335;
         *((float *)&v733 + 1) = v549;
         v712 = (signed __int64)v549;
-        pParty->pPartyBuffs[ 1].Apply(pParty->uTimePlayed + (signed __int64)v549, v731, amount, 0, 0);
-        pParty->pPartyBuffs[12].Apply(pParty->uTimePlayed + v712, v731, amount, 0, 0);
-        pParty->pPartyBuffs[ 6].Apply(pParty->uTimePlayed + v712, v731, amount, 0, 0);
-        pParty->pPartyBuffs[17].Apply(pParty->uTimePlayed + v712, v731, amount, 0, 0);
-        pParty->pPartyBuffs[ 0].Apply(pParty->uTimePlayed + v712, v731, amount, 0, 0);
-        pParty->pPartyBuffs[ 4].Apply(pParty->uTimePlayed + v712, v731, amount, 0, 0);
+        pParty->pPartyBuffs[PARTY_BUFF_RESIST_BODY].Apply(pParty->uTimePlayed + (signed __int64)v549, v731, amount, 0, 0);
+        pParty->pPartyBuffs[PARTY_BUFF_RESIST_MIND].Apply(pParty->uTimePlayed + v712, v731, amount, 0, 0);
+        pParty->pPartyBuffs[PARTY_BUFF_RESIST_FIRE].Apply(pParty->uTimePlayed + v712, v731, amount, 0, 0);
+        pParty->pPartyBuffs[PARTY_BUFF_RESIST_WATER].Apply(pParty->uTimePlayed + v712, v731, amount, 0, 0);
+        pParty->pPartyBuffs[PARTY_BUFF_RESIST_AIR].Apply(pParty->uTimePlayed + v712, v731, amount, 0, 0);
+        pParty->pPartyBuffs[PARTY_BUFF_RESIST_EARTH].Apply(pParty->uTimePlayed + v712, v731, amount, 0, 0);
         v550 = v2 + 5;
-        pParty->pPartyBuffs[ 5].Apply(
+        pParty->pPartyBuffs[PARTY_BUFF_FEATHER_FALL].Apply(
           (signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733 + 1)),
           v731,
           v550, 0, 0);
-        v668 = 0;
-        v658 = 0;
-        v653 = v550;
-        v651 = v731;
-        v28 = (signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733 + 1));
-LABEL_992:
-        v27 = (char *)&pParty->pPartyBuffs[19];
-        goto LABEL_103;
+
+        pParty->pPartyBuffs[PARTY_BUFF_WIZARD_EYE].Apply((signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733 + 1)), v731, v550, 0, 0);
+        goto LABEL_1056;
       case 86:
         v551 = v12 - 2;
         if ( !v551 )
@@ -7097,7 +6898,7 @@
         HIDWORD(v733) = v678;
 LABEL_1000:
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         y = (char *)(60 * (v2 * HIDWORD(v733) + 60));
         v732 = (300 * amount * v2 + 60) << 7;
         v730 = v2 + 5;
@@ -7106,54 +6907,33 @@
         *((float *)&v733 + 1) = (double)v732 * 0.033333335;
         do
         {
-          v554 = v3->spellnum;
-          v555 = pGame->GetStru6();
-          pGame->GetStru6()->SetPlayerBuffAnim(v554, 0);
-          v556 = v3->spellnum;
-          v557 = pGame->GetStru6();
-          pGame->GetStru6()->SetPlayerBuffAnim(v556, 1);
-          v558 = v3->spellnum;
-          v559 = pGame->GetStru6();
-          pGame->GetStru6()->SetPlayerBuffAnim(v558, 2);
-          v560 = v3->spellnum;
-          v561 = pGame->GetStru6();
-          pGame->GetStru6()->SetPlayerBuffAnim(v560, 3);
+          pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 0);
+          pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 1);
+          pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 2);
+          pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 3);
+
           //((SpellBuff *)(v553 + 6056))->Apply(
-		  v553->pPlayerBuffs[4].Apply(
-            (signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733 + 1)),
-            v731, v730, 0, 0);
+		  v553->pPlayerBuffs[4].Apply((signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733 + 1)), v731, v730, 0, 0);
           if ( *(_QWORD *)v553 )
             v726 = (Player *)1;
           ++v553;
         }
         while ( v553 <= &pParty->pPlayers[3] );
         v562 = v731;
-        pParty->pPartyBuffs[9].Apply(
-          (signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733 + 1)),
-          v731, v730, 0, 0);
-        pParty->pPartyBuffs[14].Apply(
-          (signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733 + 1)),
-          v562, 0, 0, 0);
-        pParty->pPartyBuffs[15].Apply(
-          (signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733 + 1)),
-          v562, v730, 0, 0);
+        pParty->pPartyBuffs[PARTY_BUFF_HEROISM].Apply((signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733 + 1)), v731, v730, 0, 0);
+        pParty->pPartyBuffs[PARTY_BUFF_SHIELD].Apply((signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733 + 1)), v562, 0, 0, 0);
+        pParty->pPartyBuffs[PARTY_BUFF_STONE_SKIN].Apply((signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733 + 1)), v562, v730, 0, 0);
         if (v726)
           goto LABEL_1056;
-        v668 = 0;
         v732 = (int)y << 7;
-        v658 = 0;
-        v653 = v730;
-        v651 = v562;
-        v28 = (signed __int64)((double)(signed int)((int)y << 7) * 0.033333335
-                             + (double)(signed __int64)pParty->uTimePlayed);
-        v27 = (char *)&pParty->pPartyBuffs[8];
-        goto LABEL_103;
+        pParty->pPartyBuffs[PARTY_BUFF_HASTE].Apply((signed __int64)((double)(signed int)((int)y << 7) * 0.033333335 + (double)(signed __int64)pParty->uTimePlayed), v562, v730, 0, 0);
+        goto LABEL_1056;
       case 88:
         amount = 3;
         if ( pPlayer->uNumDivineInterventionCastsThisDay >= 3u )
           goto LABEL_200;
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         a2 = 0;
         _this = (ItemGen *)&pPlayers[1];
         do
@@ -7171,11 +6951,8 @@
           v566 = (Player **)_this;
           *(int *)(_this->uItemID + 6460) = v565;
           v567 = (*v566)->GetMaxMana();
-          v568 = a2;
           *(int *)(_this->uItemID + 6464) = v567;
-          v569 = v3->spellnum;
-          v570 = pGame->GetStru6();
-          pGame->GetStru6()->SetPlayerBuffAnim(v569, v568);
+          pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, a2);
           ++a2;
           _this = (ItemGen *)((char *)_this + 4);
         }
@@ -7212,15 +6989,12 @@
         }
         amount = v575;
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
-        v576 = *(int *)&v3->field_C;
+          goto play_sound_and_continue;
+        v576 = v3->spell_target_pid;
         if (!v576)
         {
-          v583 = v3->uPlayerID_2;
-          v584 = v3->spellnum;
           v585 = (char *)&pParty->pPlayers[v3->uPlayerID_2];
-          v586 = pGame->GetStru6();
-          pGame->GetStru6()->SetPlayerBuffAnim(v584, v583);
+          pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, v3->uPlayerID_2);
           if ( *((_QWORD *)v585 + 14) )
           {
             ((Player *)v585)->SetCondition(0x11u, 1);
@@ -7228,7 +7002,7 @@
             ReloadPlayerPortraits(v3->uPlayerID_2, (v587 != 0) + 23);
             *((_QWORD *)v585 + 17) = pParty->uTimePlayed;
           }
-          goto LABEL_83;
+          goto play_sound_and_continue;
         }
         v577 = (Player *)(v576 >> 3);
         v726 = v577;
@@ -7267,7 +7041,7 @@
         a1.field_5C = v582;
         a1.Create(0, 0, 0, 0);
         if ( *(char *)(v581 + 52) > amount )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         Actor::Resurrect((unsigned int)v726);
         *(char *)(v581 + 61) = 0;
         *(char *)(v581 + 53) = 0;
@@ -7297,7 +7071,7 @@
           LODWORD(v733) = 3600 * v2;
         }
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         HIDWORD(v733) = (int)(char *)&pParty + 6972 * v3->uPlayerID_2 + 36 * a2 + 3040;
         v732 = (signed int)&pItemsTable->pItems[*(int *)HIDWORD(v733)].pIconName;
         ((ItemGen *)HIDWORD(v733))->UpdateTempBonus(pParty->uTimePlayed);
@@ -7338,7 +7112,7 @@
           amount = 7;
         }
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         v726 = (Player *)((signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360);
         v732 = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360 / (amount - 1);
         a1.stru_24.Reset();
@@ -7385,7 +7159,7 @@
         goto LABEL_1056;
       case 94:
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         if ( v731 == 1 || v731 == 2 )
         {
           v598 = 180 * v2;
@@ -7406,7 +7180,7 @@
           goto LABEL_1056;
         v730 = 836 * v599;
         if ( !MonsterStats::BelongsToSupertype(pActors[v599].pMonsterInfo.uID, MONSTER_SUPERTYPE_UNDEAD) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         if ( !stru_50C198.GetMagicalResistance(&pActors[v599], 0xAu) )
           goto LABEL_200;
         pActors[v599].pActorBuffs[9].Reset();
@@ -7450,7 +7224,7 @@
         goto LABEL_1056;
       case 96:
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         HIDWORD(v733) = 0;
         memset(&pStru179, 0, 0xFA0u);
         _this = 0;
@@ -7494,9 +7268,7 @@
         v610 = 76 * v609;
         *((int *)&pParty->pPlayers[3].pInstalledBeacons[4].uBeaconTime + 19 * v609) = 0;
         v611 = pIconsFrameTable->FindIcon("spell96");
-        *(int *)((char *)&pParty->pPlayers[3].pInstalledBeacons[4].uBeaconTime + v610 + 4) = pIconsFrameTable->GetIconAnimLength(
-                                                                                                 v611);
-        v232 = 1;
+        *(int *)((char *)&pParty->pPlayers[3].pInstalledBeacons[4].uBeaconTime + v610 + 4) = pIconsFrameTable->GetIconAnimLength(v611);
         *(int *)((char *)&pParty->pPlayers[3].pInstalledBeacons[3].field_18 + v610) = 1;
         v612 = pParty->pPlayers;
         do
@@ -7512,8 +7284,8 @@
         v613->uReputation += 15;
         if ( v613->uReputation > 10000 )
           v613->uReputation = 10000;
-        LODWORD(v727) = v232;
-        goto LABEL_83;
+        LODWORD(v727) = 1;
+        goto play_sound_and_continue;
       case 95:
         if ( v12 <= 0 )
           goto LABEL_1119;
@@ -7532,21 +7304,15 @@
         v615 = v2 + 5;
         amount = v615;
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         if ( v731 != 3 && v731 != 4 )
         {
-          v616 = v3->uPlayerID_2;
-          v617 = v3->spellnum;
-          v618 = pGame->GetStru6();
-          pGame->GetStru6()->SetPlayerBuffAnim(v617, v616);
-          v668 = 0;
-          v658 = v716;
+          pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, v3->uPlayerID_2);
+
           v732 = (int)v733 << 7;
-          v653 = v615;
-          v651 = v731;
-          v28 = pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
-          v27 = (char *)&pParty->pPlayers[v3->uPlayerID_2].pPlayerBuffs[10];
-          goto LABEL_103;
+
+          pParty->pPlayers[v3->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_PAIN_REFLECTION].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, v615, v716, 0);
+          goto LABEL_1056;
         }
         a2 = 0;
         v732 = (int)v733 << 7;
@@ -7554,11 +7320,8 @@
         v619 = pParty->pPlayers;//[0].pPlayerBuffs[10];
         do
         {
-          v620 = a2;
-          v621 = v3->spellnum;
-          v622 = pGame->GetStru6();
-          pGame->GetStru6()->SetPlayerBuffAnim(v621, v620);
-		  v619->pPlayerBuffs[10].Apply(pParty->uTimePlayed + v717, v731, amount, v716, 0);
+          pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, a2);
+		  v619->pPlayerBuffs[PLAYER_BUFF_PAIN_REFLECTION].Apply(pParty->uTimePlayed + v717, v731, amount, v716, 0);
           ++a2;
           ++v619;
         }
@@ -7566,7 +7329,7 @@
         goto LABEL_1056;
       case 99:
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         v726 = 0;
         pGame->GetIndoorCamera();
         v623 = (signed __int64)GetPickDepth();
@@ -7642,15 +7405,12 @@
             if ( v726->sHealth > v634 )
               *(int *)(*(int *)v632 + 6460) = v726->GetMaxHealth();
             v635 = HIDWORD(v733);
-            v636 = WORD2(v733);
-            v637 = v3->spellnum;
-            v638 = pGame->GetStru6();
-            pGame->GetStru6()->SetPlayerBuffAnim(v637, v636);
+
+            pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, WORD2(v733));
             HIDWORD(v733) = v635 + 1;
           }
           while ( v635 + 1 < v730 );
         }
-        v639 = pGame->GetStru6();
         pGame->GetStru6()->FadeScreen__like_Turn_Undead_and_mb_Armageddon(0, 0x40u);
         goto LABEL_1056;
       case 98:
@@ -7665,7 +7425,7 @@
         if ( pPlayer->uNumArmageddonCasts >= amount || pParty->armageddon_timer > 0 )
           goto LABEL_200;
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          goto LABEL_83;
+          goto play_sound_and_continue;
         pParty->armageddon_timer = 256;
         pParty->field_16140 = v2;
         ++pPlayer->uNumArmageddonCasts;
@@ -7686,7 +7446,7 @@
         while ( *(float *)&v726 != 0.0 );
         goto LABEL_1056;
       default:
-        goto LABEL_83;
+        goto play_sound_and_continue;
     }
     while ( 2 )
     {
@@ -7716,27 +7476,6 @@
         goto LABEL_1056;
       continue;
     }
-  }
-  if ( pParty->bTurnBasedModeOn == 0 )
-  {
-    v646 = pPlayer;
-    pPlayer->SetRecoveryTime((signed __int64)(flt_6BE3A4_debug_recmod1 * 213.3333333333333));
-    v647 = n;
-  }
-  else
-  {
-    v647 = n;
-    v646 = pPlayer;
-    v648 = sRecoveryTime;
-    v649 = pPlayer;
-    pParty->pTurnBasedPlayerRecoveryTimes[v711[n].uPlayerID] = 100;
-    v649->SetRecoveryTime(v648);
-    pTurnEngine->_40471C();
-  }
-  ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2u);
-  pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-  v711[v647].spellnum = 0;
-  v646->sMana -= uRequiredMana;
 }
 //----- (0042EB42) --------------------------------------------------------
 __int16 ObjectList::ObjectIDByItemID(unsigned __int16 uItemID)
@@ -8027,7 +7766,7 @@
     shooting_wand = true;
 
     int main_hand_idx = player->pEquipment.uMainHand;
-    _42777D_CastSpell_UseWand_ShootArrow(*((int *)&pSpellDatas[66].field_8 + player->pInventoryItems[main_hand_idx - 1].uItemID), uActiveCharacter - 1, 8, 0, uActiveCharacter + 8);
+    _42777D_CastSpell_UseWand_ShootArrow(*((int *)&pSpellDatas[66].uNormalLevelRecovery + player->pInventoryItems[main_hand_idx - 1].uItemID), uActiveCharacter - 1, 8, 0, uActiveCharacter + 8);
 
     if (!--player->pInventoryItems[main_hand_idx - 1].uNumCharges)
       player->pEquipment.uMainHand = 0;
--- a/stru277.h	Wed Feb 27 17:29:05 2013 +0200
+++ b/stru277.h	Wed Feb 27 22:15:30 2013 +0200
@@ -18,7 +18,7 @@
   }
 
   void _427D48(unsigned int uPlayerID);
-  unsigned int PushStru277(__int16 a2, __int16 uPlayerID, __int16 a4, __int16 a5, int a6);
+  unsigned int PushStru277(__int16 a2, __int16 uPlayerID, __int16 skill_level, __int16 a5, int a6);
   struct GUIWindow *sub_4219BE();
   void _427E01_cast_spell();
 
@@ -27,9 +27,8 @@
   __int16 uPlayerID_2;
   __int16 field_6;
   __int16 field_8;
-  __int16 field_A;
-  __int16 field_C;
-  __int16 field_E;
+  __int16 forced_spell_skill_level;
+  int spell_target_pid;
   int field_10;
 };
 #pragma pack(pop)
--- a/stru6.cpp	Wed Feb 27 17:29:05 2013 +0200
+++ b/stru6.cpp	Wed Feb 27 22:15:30 2013 +0200
@@ -1336,12 +1336,12 @@
 
   switch (uSpellID)
   {
-    case 153:
+    case SPELL_153:
       __debugbreak(); // spell id == 153 wtf
       v6 = "zapp";
     break;
       
-    case 150:
+    case SPELL_150:
       __debugbreak(); // spell id == 150 wtf
     case SPELL_AIR_FEATHER_FALL:
     case SPELL_SPIRIT_DETECT_LIFE:
@@ -1349,7 +1349,7 @@
       v6 = "spboost1";
     break;
       
-    case 151:
+    case SPELL_151:
       __debugbreak(); // spell id == 151 wtf
     case SPELL_AIR_INVISIBILITY:
     case SPELL_WATER_WATER_WALK:
@@ -1357,7 +1357,7 @@
       v6 = "spboost2";
     break;
       
-    case 152:
+    case SPELL_152:
       __debugbreak(); // spell id == 152 wtf
     case SPELL_LIGHT_HOUR_OF_POWER:
     case SPELL_LIGHT_DAY_OF_THE_GODS: