changeset 2566:30eb6dcac768

big spell fx overhaul
author a.parshin
date Wed, 20 May 2015 21:05:07 +0200
parents 117c219bf913
children d569340b05ff
files Engine/Engine.cpp Engine/Events.cpp Engine/Graphics/Indoor.cpp Engine/Graphics/Outdoor.cpp Engine/Graphics/Render.cpp Engine/Graphics/Viewport.cpp Engine/Graphics/Vis.cpp Engine/MapInfo.cpp Engine/Objects/Actor.cpp Engine/Objects/Chest.cpp Engine/Objects/NPC.cpp Engine/Objects/Player.cpp Engine/Objects/SpriteObject.cpp Engine/Objects/SpriteObject.h Engine/Party.cpp Engine/Spells/CastSpellInfo.cpp Engine/Spells/CastSpellInfo.h Engine/Spells/Spells.cpp Engine/Spells/Spells.h GUI/UI/UIPopup.cpp GUI/UI/UiGame.cpp Game/Game.cpp stru6.cpp stru6.h
diffstat 24 files changed, 1051 insertions(+), 970 deletions(-) [+]
line wrap: on
line diff
--- a/Engine/Engine.cpp	Wed May 20 15:12:33 2015 +0200
+++ b/Engine/Engine.cpp	Wed May 20 21:05:07 2015 +0200
@@ -897,9 +897,8 @@
     char *v3; // eax@1
     unsigned int v5; // eax@3
     char Str1[20]; // [sp+Ch] [bp-18h]@1
-    unsigned int v9; // [sp+20h] [bp-4h]@1
-
-    v9 = bLoading;
+
+    //v9 = bLoading;
     ResetCursor_Palettes_LODs_Level_Audio_SFT_Windows();
     pDecalBuilder->Reset(0);
     pGameLoadingUI_ProgressBar->Initialize(_1_fullscreen_loading_2_box == 1 ? GUIProgressBar::TYPE_Fullscreen :
@@ -928,9 +927,9 @@
     }
     pParty->floor_face_pid = 0;
     if (_stricmp(Str1, "blv"))
-        PrepareToLoadODM(v9, 0);
+        PrepareToLoadODM(bLoading, 0);
     else
-        PrepareToLoadBLV(v9);
+        PrepareToLoadBLV(bLoading);
     pAudioPlayer->SetMapEAX();
     _461103_load_level_sub();
     if (!_stricmp(pCurrentMapName, "d11.blv") || !_stricmp(pCurrentMapName, "d10.blv"))
@@ -1745,6 +1744,7 @@
 bool use_MMT = false;
 bool use_music_folder = false;
 bool for_refactoring = false;
+bool all_spells = true;
 
 //----- (00462C94) --------------------------------------------------------
 bool MM_Main(const wchar_t *pCmdLine)
@@ -2887,16 +2887,16 @@
             a3.z = 0;
             a3.y = 0;
             a3.x = 0;
-            a1.stru_24.Reset();
+            a1.containing_item.Reset();
             a1.spell_level = pParty->pPartyBuffs[PARTY_BUFF_IMMOLATION].uPower;
             a1.spell_skill = pParty->ImmolationSkillLevel();
             v10 = 0;
-            a1.uType = 1070;
+            a1.uType = SPRITE_SPELL_FIRE_IMMOLATION;
             a1.spell_id = SPELL_FIRE_IMMOLATION;
             v10 = 0;
             for (uint i = 0; i > pObjectList->uNumObjects; i++)
             {
-                if (pObjectList->pObjects[i].uObjectID == stru_4E3ACC[8].uType)
+                if (pObjectList->pObjects[i].uObjectID == spell_sprite_mapping[8].uSpriteType)
                     v10 = i;
             }
             a1.uObjectDescID = v10;
--- a/Engine/Events.cpp	Wed May 20 15:12:33 2015 +0200
+++ b/Engine/Events.cpp	Wed May 20 21:05:07 2015 +0200
@@ -715,12 +715,14 @@
         ++curr_seq_num;
         break;
       case EVENT_SummonItem:
-        SpriteObject::sub_42F7EB_DropItemAt(_evt->v5 + ((_evt->v6 + ((_evt->v7 + ((uint)_evt->v8 << 8)) << 8)) << 8),
-          _evt->v9 + ((_evt->v10 + ((_evt->v11 + ((uint)_evt->v12 << 8)) << 8)) << 8),
-          _evt->v13 + ((_evt->v14 + ((_evt->v15 + ((uint)_evt->v16 << 8)) << 8)) << 8),
-          _evt->v17 + ((_evt->v18 + ((_evt->v19 + ((uint)_evt->v20 << 8)) << 8)) << 8),
-          _evt->v21 + ((_evt->v22 + ((_evt->v23 + ((uint)_evt->v24 << 8)) << 8)) << 8),
-          _evt->v25, _evt->v26, 0, 0);
+        SpriteObject::sub_42F7EB_DropItemAt(
+            (SPRITE_OBJECT_TYPE)(_evt->v5 + ((_evt->v6 + ((_evt->v7 + ((uint)_evt->v8 << 8)) << 8)) << 8)),
+            _evt->v9 + ((_evt->v10 + ((_evt->v11 + ((uint)_evt->v12 << 8)) << 8)) << 8),
+            _evt->v13 + ((_evt->v14 + ((_evt->v15 + ((uint)_evt->v16 << 8)) << 8)) << 8),
+            _evt->v17 + ((_evt->v18 + ((_evt->v19 + ((uint)_evt->v20 << 8)) << 8)) << 8),
+            _evt->v21 + ((_evt->v22 + ((_evt->v23 + ((uint)_evt->v24 << 8)) << 8)) << 8),
+            _evt->v25, _evt->v26, 0, 0
+        );
         ++curr_seq_num;
         break;
       case EVENT_Compare:
--- a/Engine/Graphics/Indoor.cpp	Wed May 20 15:12:33 2015 +0200
+++ b/Engine/Graphics/Indoor.cpp	Wed May 20 21:05:07 2015 +0200
@@ -1927,9 +1927,9 @@
 
   for ( uint i = 0; i < uNumSpriteObjects; ++i )
   {
-    if (pSpriteObjects[i].stru_24.uItemID && !(pSpriteObjects[i].uAttributes & 0x0100))
+      if (pSpriteObjects[i].containing_item.uItemID && !(pSpriteObjects[i].uAttributes & 0x0100))
     {
-      pSpriteObjects[i].uType = pItemsTable->pItems[pSpriteObjects[i].stru_24.uItemID].uSpriteID;
+          pSpriteObjects[i].uType = (SPRITE_OBJECT_TYPE)pItemsTable->pItems[pSpriteObjects[i].containing_item.uItemID].uSpriteID;
 
       //uint uObjectID = 0;
       for ( uint j = 0; j < pObjectList->uNumObjects; ++j )
@@ -3098,12 +3098,12 @@
   {
     if (pSpriteObjects[i].uObjectDescID)
     {
-      if ( pSpriteObjects[i].stru_24.uItemID )
+        if (pSpriteObjects[i].containing_item.uItemID)
       {
-        if ( pSpriteObjects[i].stru_24.uItemID != 220 && pItemsTable->pItems[ pSpriteObjects[i].stru_24.uItemID].uEquipType == EQUIP_POTION &&
-            !pSpriteObjects[i].stru_24.uEnchantmentType)
-          pSpriteObjects[i].stru_24.uEnchantmentType = rand() % 15 + 5;
-        pItemsTable->SetSpecialBonus(&pSpriteObjects[i].stru_24);
+          if (pSpriteObjects[i].containing_item.uItemID != 220 && pItemsTable->pItems[pSpriteObjects[i].containing_item.uItemID].uEquipType == EQUIP_POTION &&
+              !pSpriteObjects[i].containing_item.uEnchantmentType)
+            pSpriteObjects[i].containing_item.uEnchantmentType = rand() % 15 + 5;
+        pItemsTable->SetSpecialBonus(&pSpriteObjects[i].containing_item);
       }
     }
   }
@@ -3549,7 +3549,7 @@
           if ( ( pSpriteObjects[i].uType < 1000 || pSpriteObjects[i].uType >= 10000)
             && (pSpriteObjects[i].uType < 500 || pSpriteObjects[i].uType >= 600)
             && (pSpriteObjects[i].uType < 811 || pSpriteObjects[i].uType >= 815)
-            || pEngine->pStru6Instance->_4A81CA(&pSpriteObjects[i]))
+            || pEngine->pStru6Instance->RenderAsSprite(&pSpriteObjects[i]))
           {
             v4 = pSpriteFrameTable->GetFrame(pObjectList->pObjects[pSpriteObjects[i].uObjectDescID].uSpriteID, pSpriteObjects[i].uSpriteFrameID);
             a6 = v4->uGlowRadius * pSpriteObjects[i].field_22_glow_radius_multiplier;
@@ -4451,23 +4451,23 @@
     case OBJECT_Item: // take the item
       if ( pObjectList->pObjects[pSpriteObjects[v17].uObjectDescID].uFlags & 0x10 || v17 >= 1000 || !pSpriteObjects[v17].uObjectDescID )
         return 1;
-      if ( pItemsTable->pItems[pSpriteObjects[v17].stru_24.uItemID].uEquipType == EQUIP_GOLD)
+      if (pItemsTable->pItems[pSpriteObjects[v17].containing_item.uItemID].uEquipType == EQUIP_GOLD)
       {
-        pParty->PartyFindsGold(pSpriteObjects[v17].stru_24.uSpecEnchantmentType, 0);
+          pParty->PartyFindsGold(pSpriteObjects[v17].containing_item.uSpecEnchantmentType, 0);
         viewparams->bRedrawGameUI = 1;
       }
       else
       {
         if ( pParty->pPickedItem.uItemID )
           return 1;
-        sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[471], pItemsTable->pItems[pSpriteObjects[v17].stru_24.uItemID].pUnidentifiedName);//You found an item (%s)!
+        sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[471], pItemsTable->pItems[pSpriteObjects[v17].containing_item.uItemID].pUnidentifiedName);//You found an item (%s)!
         ShowStatusBarString(pTmpBuf2.data(), 2);
-        if ( pSpriteObjects[v17].stru_24.uItemID == 506 )//artefact
+        if (pSpriteObjects[v17].containing_item.uItemID == 506)//artefact
           _449B7E_toggle_bit(pParty->_quest_bits, 184, 1);
-        if ( pSpriteObjects[v17].stru_24.uItemID == 455 )
+        if (pSpriteObjects[v17].containing_item.uItemID == 455)
           _449B7E_toggle_bit(pParty->_quest_bits, 185, 1);
-        if ( !pParty->AddItemToParty(&pSpriteObjects[v17].stru_24) )
-          pParty->SetHoldingItem(&pSpriteObjects[v17].stru_24);
+        if (!pParty->AddItemToParty(&pSpriteObjects[v17].containing_item))
+            pParty->SetHoldingItem(&pSpriteObjects[v17].containing_item);
       }
       SpriteObject::OnInteraction(v17);
       break;
@@ -6055,10 +6055,10 @@
 
   v6 = ecx0;
   v7 = a2;
-  pItemsTable->GenerateItem(v6, v7, &a1.stru_24);
+  pItemsTable->GenerateItem(v6, v7, &a1.containing_item);
   v8 = 0;
-  v9 = pItemsTable->pItems[a1.stru_24.uItemID].uSpriteID;
-  a1.uType = pItemsTable->pItems[a1.stru_24.uItemID].uSpriteID;
+  v9 = pItemsTable->pItems[a1.containing_item.uItemID].uSpriteID;
+  a1.uType = (SPRITE_OBJECT_TYPE)pItemsTable->pItems[a1.containing_item.uItemID].uSpriteID;
   v11 = 0;
   for( int i = 0; i < pObjectList->uNumObjects; i++ )
   {
--- a/Engine/Graphics/Outdoor.cpp	Wed May 20 15:12:33 2015 +0200
+++ b/Engine/Graphics/Outdoor.cpp	Wed May 20 21:05:07 2015 +0200
@@ -2265,13 +2265,13 @@
       {
         if ( !(pSpriteObjects[i].uAttributes & 8) && !(pObjectList->pObjects[pSpriteObjects[i].uObjectDescID].uFlags & 0x10) )
           pSpriteObjects[i].vPosition.z = GetTerrainHeightsAroundParty2(pSpriteObjects[i].vPosition.x, pSpriteObjects[i].vPosition.y, (int *)&v5, 0);
-        if ( pSpriteObjects[i].stru_24.uItemID )
+        if (pSpriteObjects[i].containing_item.uItemID)
         {
-          if ( pSpriteObjects[i].stru_24.uItemID != 220
-            && pItemsTable->pItems[pSpriteObjects[i].stru_24.uItemID].uEquipType == EQUIP_POTION
-            && !pSpriteObjects[i].stru_24.uEnchantmentType )
-             pSpriteObjects[i].stru_24.uEnchantmentType = rand() % 15 + 5;
-          pItemsTable->SetSpecialBonus(&pSpriteObjects[i].stru_24);
+            if (pSpriteObjects[i].containing_item.uItemID != 220
+                && pItemsTable->pItems[pSpriteObjects[i].containing_item.uItemID].uEquipType == EQUIP_POTION
+            && !pSpriteObjects[i].containing_item.uEnchantmentType)
+            pSpriteObjects[i].containing_item.uEnchantmentType = rand() % 15 + 5;
+            pItemsTable->SetSpecialBonus(&pSpriteObjects[i].containing_item);
         }
       }
     }
--- a/Engine/Graphics/Render.cpp	Wed May 20 15:12:33 2015 +0200
+++ b/Engine/Graphics/Render.cpp	Wed May 20 21:05:07 2015 +0200
@@ -604,7 +604,7 @@
           //v2 = *((short *)v0 - 14)
     //v2 = object->uType;
     if ( (object->uType < 1000 || object->uType >= 10000) && (object->uType < 500 || object->uType >= 600)
-       || pEngine->pStru6Instance->_4A81CA(object) )
+       || pEngine->pStru6Instance->RenderAsSprite(object) )
     {
             //a5 = *(short *)v0;
       x = object->vPosition.x;
@@ -9897,7 +9897,7 @@
 
 	result = uLayingItemID;
 	if (pObjectList->pObjects[pSpriteObjects[uLayingItemID].uObjectDescID].uFlags & 0x10)
-		result = _46BFFA_check_object_intercept(uLayingItemID, a2);
+		result = _46BFFA_update_spell_fx(uLayingItemID, a2);
 	return result;
 }
 
@@ -9976,7 +9976,7 @@
 					SpriteObject::OnInteraction(i);
 					continue;
 				}
-				_46BFFA_check_object_intercept(i, PID(OBJECT_Item, i));
+				_46BFFA_update_spell_fx(i, PID(OBJECT_Item, i));
 			}
 		}
 	}
--- a/Engine/Graphics/Viewport.cpp	Wed May 20 15:12:33 2015 +0200
+++ b/Engine/Graphics/Viewport.cpp	Wed May 20 21:05:07 2015 +0200
@@ -288,21 +288,21 @@
     if ( !(pObjectList->pObjects[pSpriteObjects[item_id].uObjectDescID].uFlags & 0x10) && item_id < 1000 && pSpriteObjects[item_id].uObjectDescID
       && (unsigned int)v0 < 0x2000000 )
     {
-      if ( pSpriteObjects[item_id].stru_24.GetItemEquipType() == 18 )
+        if (pSpriteObjects[item_id].containing_item.GetItemEquipType() == 18)
       {
-        pParty->PartyFindsGold(pSpriteObjects[item_id].stru_24.uSpecEnchantmentType, 0);
+            pParty->PartyFindsGold(pSpriteObjects[item_id].containing_item.uSpecEnchantmentType, 0);
         viewparams->bRedrawGameUI = 1;
       }
       else
       {
-        sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[471], pItemsTable->pItems[pSpriteObjects[item_id].stru_24.uItemID].pUnidentifiedName);//You found an item (%s)!
+          sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[471], pItemsTable->pItems[pSpriteObjects[item_id].containing_item.uItemID].pUnidentifiedName);//You found an item (%s)!
         ShowStatusBarString(pTmpBuf2.data(), 2);
-        if ( pSpriteObjects[item_id].stru_24.uItemID == ITEM_ARTIFACT_SPLITTER )
+        if (pSpriteObjects[item_id].containing_item.uItemID == ITEM_ARTIFACT_SPLITTER)
           _449B7E_toggle_bit(pParty->_quest_bits, 184, 1);
-        if ( pSpriteObjects[item_id].stru_24.uItemID == 455 )
+        if (pSpriteObjects[item_id].containing_item.uItemID == 455)
           _449B7E_toggle_bit(pParty->_quest_bits, 185, 1);
-        if ( !pParty->AddItemToParty(&pSpriteObjects[item_id].stru_24) )
-          pParty->SetHoldingItem(&pSpriteObjects[item_id].stru_24);
+        if (!pParty->AddItemToParty(&pSpriteObjects[item_id].containing_item))
+            pParty->SetHoldingItem(&pSpriteObjects[item_id].containing_item);
       }
       SpriteObject::OnInteraction(item_id);
       return;
@@ -311,7 +311,7 @@
       return;
 		__debugbreak();//no checker
     v6 = 0;
-    a1.uType = pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID;
+    a1.uType = (SPRITE_OBJECT_TYPE)pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID;
     if ( (signed int)pObjectList->uNumObjects <= 0 )
       LOWORD(v6) = 0;
     else
@@ -338,7 +338,7 @@
     a1.uAttributes = 8;
     a1.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->sEyelevel + pParty->vPosition.z);
     a1.uSpriteFrameID = 0;
-    memcpy(&a1.stru_24, &pParty->pPickedItem, 0x24u);
+    memcpy(&a1.containing_item, &pParty->pPickedItem, 0x24u);
 
     extern int UnprojectX(int);
     //v9 = UnprojectX(v1->x);
@@ -365,7 +365,7 @@
         return;
 		__debugbreak();//no checker
       v6 = 0;
-      a1.uType = pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID;
+      a1.uType = (SPRITE_OBJECT_TYPE)pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID;
       if ( (signed int)pObjectList->uNumObjects <= 0 )
         LOWORD(v6) = 0;
       else
@@ -392,7 +392,7 @@
       a1.uAttributes = 8;
       a1.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->sEyelevel + pParty->vPosition.z);
       a1.uSpriteFrameID = 0;
-      memcpy(&a1.stru_24, &pParty->pPickedItem, 0x24u);
+      memcpy(&a1.containing_item, &pParty->pPickedItem, 0x24u);
 
       extern int UnprojectX(int);
       //v9 = UnprojectX(v1->x);
@@ -414,7 +414,7 @@
             return;
 		__debugbreak();//no checker
           v6 = 0;
-          a1.uType = pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID;
+          a1.uType = (SPRITE_OBJECT_TYPE)pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID;
           if ( (signed int)pObjectList->uNumObjects <= 0 )
             LOWORD(v6) = 0;
           else
@@ -441,7 +441,7 @@
           a1.uAttributes = 8;
           a1.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->sEyelevel + pParty->vPosition.z);
           a1.uSpriteFrameID = 0;
-          memcpy(&a1.stru_24, &pParty->pPickedItem, 0x24u);
+          memcpy(&a1.containing_item, &pParty->pPickedItem, 0x24u);
 
           extern int UnprojectX(int);
           //v9 = UnprojectX(v1->x);
@@ -500,7 +500,7 @@
         return;
 		__debugbreak();//no checker
       v6 = 0;
-      a1.uType = pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID;
+      a1.uType = (SPRITE_OBJECT_TYPE)pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID;
       if ( (signed int)pObjectList->uNumObjects <= 0 )
         LOWORD(v6) = 0;
       else
@@ -527,7 +527,7 @@
       a1.uAttributes = 8;
       a1.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->sEyelevel + pParty->vPosition.z);
       a1.uSpriteFrameID = 0;
-      memcpy(&a1.stru_24, &pParty->pPickedItem, 0x24u);
+      memcpy(&a1.containing_item, &pParty->pPickedItem, 0x24u);
 
       extern int UnprojectX(int);
       //v9 = UnprojectX(v1->x);
@@ -568,7 +568,7 @@
         }
 		__debugbreak();//no checker
         v6 = 0;
-        a1.uType = pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID;
+        a1.uType = (SPRITE_OBJECT_TYPE)pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID;
         if ( (signed int)pObjectList->uNumObjects <= 0 )
           LOWORD(v6) = 0;
         else
@@ -595,7 +595,7 @@
         a1.uAttributes = 8;
         a1.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->sEyelevel + pParty->vPosition.z);
         a1.uSpriteFrameID = 0;
-        memcpy(&a1.stru_24, &pParty->pPickedItem, 0x24u);
+        memcpy(&a1.containing_item, &pParty->pPickedItem, 0x24u);
 
         extern int UnprojectX(int);
         v9 = UnprojectX(v1->x);
@@ -621,7 +621,7 @@
         }
 		__debugbreak();//no checker
         v6 = 0;
-        a1.uType = pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID;
+        a1.uType = (SPRITE_OBJECT_TYPE)pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID;
         if ( (signed int)pObjectList->uNumObjects <= 0 )
           LOWORD(v6) = 0;
         else
@@ -648,7 +648,7 @@
         a1.uAttributes = 8;
         a1.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->sEyelevel + pParty->vPosition.z);
         a1.uSpriteFrameID = 0;
-        memcpy(&a1.stru_24, &pParty->pPickedItem, 0x24u);
+        memcpy(&a1.containing_item, &pParty->pPickedItem, 0x24u);
 
         extern int UnprojectX(int);
         v9 = UnprojectX(v1->x);
@@ -671,7 +671,7 @@
       return;
 	//__debugbreak();//no checker
     v6 = 0;
-    a1.uType = pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID;
+    a1.uType = (SPRITE_OBJECT_TYPE)pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID;
     if ( (signed int)pObjectList->uNumObjects <= 0 )
       LOWORD(v6) = 0;
     else
@@ -698,7 +698,7 @@
     a1.uAttributes = 8;
     a1.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->sEyelevel + pParty->vPosition.z);
     a1.uSpriteFrameID = 0;
-    memcpy(&a1.stru_24, &pParty->pPickedItem, 0x24u);
+    memcpy(&a1.containing_item, &pParty->pPickedItem, 0x24u);
 
     extern int UnprojectX(int);
     //v9 = UnprojectX(v1->x);
--- a/Engine/Graphics/Vis.cpp	Wed May 20 15:12:33 2015 +0200
+++ b/Engine/Graphics/Vis.cpp	Wed May 20 21:05:07 2015 +0200
@@ -402,28 +402,28 @@
   RenderVertexSoft v3; // [sp+68h] [bp-60h]@1
   RenderVertexSoft v4; // [sp+98h] [bp-30h]@1
 
-  v4.flt_2C = 0.0;
-  v4.vWorldPosition.x = 0.0;
-  v4.vWorldPosition.y = 65536.0;
-  v4.vWorldPosition.z = 0.0;
-  v3.flt_2C = 0.0;
-  v3.vWorldPosition.x = 65536.0;
-  v3.vWorldPosition.y = 0.0;
-  v3.vWorldPosition.z = 0.0;
-  memcpy(&v1, &v3, sizeof(v1));
+  v2.flt_2C = 0.0;
+  v2.vWorldPosition.x = 0.0;
+  v2.vWorldPosition.y = 65536.0;
+  v2.vWorldPosition.z = 0.0;
+
+  v1.flt_2C = 0.0;
+  v1.vWorldPosition.x = 65536.0;
+  v1.vWorldPosition.y = 0.0;
+  v1.vWorldPosition.z = 0.0;
+
   v3.flt_2C = 0.0;
   v3.vWorldPosition.x = 0.0;
   v3.vWorldPosition.y = 65536.0;
   v3.vWorldPosition.z = 0.0;
-  memcpy(&v2, &v4, sizeof(v2));
+
   v4.flt_2C = 0.0;
   v4.vWorldPosition.x = 65536.0;
   v4.vWorldPosition.y = 0.0;
   v4.vWorldPosition.z = 0.0;
+
   memcpy(&this->stru_200C, &v1, 0x60u);
-  memcpy(&v1, &v4, sizeof(v1));
-  memcpy(&v2, &v3, sizeof(v2));
-  memcpy(&this->stru_206C, &v1, 0x60u);
+  memcpy(&this->stru_206C, &v4, 0x60u);
 }
 
 //----- (004C1ABA) --------------------------------------------------------
--- a/Engine/MapInfo.cpp	Wed May 20 15:12:33 2015 +0200
+++ b/Engine/MapInfo.cpp	Wed May 20 21:05:07 2015 +0200
@@ -439,42 +439,42 @@
     if ( a2->uIndex == 1 )
     {
       v14 = rand() % 51 + 50;
-      a1a.stru_24.uItemID = 197;
+      a1a.containing_item.uItemID = 197;
       v34 = v14;
     }
     else if ( a2->uIndex == 2 )
     {
       v14 = rand() % 101 + 100;
-      a1a.stru_24.uItemID = 197;
+      a1a.containing_item.uItemID = 197;
       v34 = v14;
     }
     else if ( a2->uIndex == 3 )
     {
       v14 = rand() % 301 + 200;
-      a1a.stru_24.uItemID = 198;
+      a1a.containing_item.uItemID = 198;
       v34 = v14;
     }
     else if ( a2->uIndex == 4 )
     {
       v14 = rand() % 501 + 500;
-      a1a.stru_24.uItemID = 198;
+      a1a.containing_item.uItemID = 198;
       v34 = v14;
     }
     else if ( a2->uIndex == 5 )
     {
       v14 = rand() % 1001 + 1000;
-      a1a.stru_24.uItemID = 199;
+      a1a.containing_item.uItemID = 199;
       v34 = v14;
     }
     else if ( a2->uIndex == 6 )
     {
       v14 = rand() % 3001 + 2000;
-      a1a.stru_24.uItemID = 199;
+      a1a.containing_item.uItemID = 199;
       v34 = v14;
     }	 
     v15 = 0;
-    v16 = pItemsTable->pItems[a1a.stru_24.uItemID].uSpriteID;
-    a1a.uType = pItemsTable->pItems[a1a.stru_24.uItemID].uSpriteID;
+    v16 = pItemsTable->pItems[a1a.containing_item.uItemID].uSpriteID;
+    a1a.uType = (SPRITE_OBJECT_TYPE)pItemsTable->pItems[a1a.containing_item.uItemID].uSpriteID;
     v18 = 0;
     for( int i = 0; i < pObjectList->uNumObjects; i++ )
     {
@@ -484,18 +484,18 @@
         break;
       }
     }
-    a1a.stru_24.SetIdentified();
+    a1a.containing_item.SetIdentified();
     a1a.uObjectDescID = v18;
-    a1a.stru_24.uSpecEnchantmentType = v34;
+    a1a.containing_item.uSpecEnchantmentType = v34;
   }
   else
   {
-    result = a1a.stru_24.GenerateArtifact();
+      result = a1a.containing_item.GenerateArtifact();
     if ( !result )
       return result;
     v23 = 0;
-    v24 = pItemsTable->pItems[a1a.stru_24.uItemID].uSpriteID;
-    a1a.uType = pItemsTable->pItems[a1a.stru_24.uItemID].uSpriteID;
+    v24 = pItemsTable->pItems[a1a.containing_item.uItemID].uSpriteID;
+    a1a.uType = (SPRITE_OBJECT_TYPE)pItemsTable->pItems[a1a.containing_item.uItemID].uSpriteID;
     v26 = 0;
     for( int i = 0; i < pObjectList->uNumObjects; i++ )
     {
@@ -506,7 +506,7 @@
       }
     }
     a1a.uObjectDescID = v26;
-    a1a.stru_24.Reset();
+    a1a.containing_item.Reset();
   }
   a1a.vPosition.y = a2->vPosition.y;
   a1a.uAttributes = 0;
--- a/Engine/Objects/Actor.cpp	Wed May 20 15:12:33 2015 +0200
+++ b/Engine/Objects/Actor.cpp	Wed May 20 21:05:07 2015 +0200
@@ -278,9 +278,9 @@
     case SPELL_LIGHT_LIGHT_BOLT:
     case SPELL_DARK_TOXIC_CLOUD:
     case SPELL_DARK_DRAGON_BREATH:
-      a1.uType = stru_4E3ACC[uSpellID].uType;
+      a1.uType = spell_sprite_mapping[uSpellID].uSpriteType;
       a1.uObjectDescID = GetObjDescId(uSpellID);
-      a1.stru_24.Reset();
+      a1.containing_item.Reset();
       a1.spell_id = uSpellID;
       a1.spell_level = uSkillLevel;
       a1.vPosition.x = actorPtr->vPosition.x;
@@ -358,8 +358,8 @@
           v32 = stru_5C6E00->Atan2(spellnumb, (int)v28);
           pitch = stru_5C6E00->Atan2(v31, (int)spellnumc);
         }
-        a1.stru_24.Reset();
-        a1.uType = stru_4E3ACC[uSpellID].uType;
+        a1.containing_item.Reset();
+        a1.uType = spell_sprite_mapping[uSpellID].uSpriteType;
         a1.uObjectDescID = GetObjDescId(uSpellID);
         a1.spell_level = uSkillLevel;
         a1.vPosition.x = pParty->vPosition.x;
@@ -403,11 +403,11 @@
       else 
         v10 = 3;
       spellnuma = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360;
-      a1.uType = stru_4E3ACC[uSpellID].uType;
+      a1.uType = spell_sprite_mapping[uSpellID].uSpriteType;
       v118 = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360 / (v10 - 1);
       a1.uObjectDescID = GetObjDescId(uSpellID);
 
-      a1.stru_24.Reset();
+      a1.containing_item.Reset();
       a1.spell_id = SPELL_AIR_SPARKS;
       a1.spell_level = uSkillLevel;
       a1.vPosition.x = actorPtr->vPosition.x;
@@ -615,10 +615,10 @@
         v70 = 3;
 
       spellnume = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360;
-      a1.uType = stru_4E3ACC[uSpellID].uType;
+      a1.uType = spell_sprite_mapping[uSpellID].uSpriteType;
       v116 = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360 / (v70 - 1);
       a1.uObjectDescID = GetObjDescId(uSpellID);
-      a1.stru_24.Reset();
+      a1.containing_item.Reset();
       a1.spell_id = uSpellID;
       a1.spell_level = uSkillLevel;
       a1.vPosition.x = actorPtr->vPosition.x;
@@ -677,7 +677,7 @@
 {
   for (unsigned int i = 0; i < pObjectList->uNumObjects; i++)
   {
-    if (stru_4E3ACC[spellId].uType == pObjectList->pObjects[i].uObjectID)
+      if (spell_sprite_mapping[spellId].uSpriteType == pObjectList->pObjects[i].uObjectID)
     {
       return i;
       break;
@@ -758,40 +758,40 @@
   switch ( type )
   {
     case 1:
-      a1.uType = 545;
+      a1.uType = SPRITE_PROJECTILE_545;
       break;
     case 2:
-      a1.uType = 550;
+        a1.uType = SPRITE_PROJECTILE_550;
       break;
     case 3:
-      a1.uType = 510;
+        a1.uType = SPRITE_PROJECTILE_510;
       break;
     case 4:
-      a1.uType = 500;
+        a1.uType = SPRITE_PROJECTILE_500;
       break;
     case 5:
-      a1.uType = 515;
+        a1.uType = SPRITE_PROJECTILE_515;
       break;
     case 6:
-      a1.uType = 505;
+        a1.uType = SPRITE_PROJECTILE_505;
       break;
     case 7:
-      a1.uType = 530;
+        a1.uType = SPRITE_PROJECTILE_530;
       break;
     case 8:
-      a1.uType = 525;
+        a1.uType = SPRITE_PROJECTILE_525;
       break;
     case 9:
-      a1.uType = 520;
+        a1.uType = SPRITE_PROJECTILE_520;
       break;
     case 10:
-      a1.uType = 535;
+        a1.uType = SPRITE_PROJECTILE_535;
       break;
     case 11:
-      a1.uType = 540;
+        a1.uType = SPRITE_PROJECTILE_540;
       break;
     case 13:
-      a1.uType = 555;
+        a1.uType = SPRITE_PROJECTILE_555;
       break;
     default:
       return;
@@ -811,7 +811,7 @@
     Error("Item not found");
     return;
   }
-  a1.stru_24.Reset();
+  a1.containing_item.Reset();
   a1.spell_id = 0;
   a1.vPosition.x = pActors[uActorID].vPosition.x;
   a1.vPosition.y = pActors[uActorID].vPosition.y;
@@ -862,9 +862,9 @@
 {
   SpriteObject a1; // [sp+Ch] [bp-78h]@1
 
-  a1.uType = 600;
+  a1.uType = SPRITE_600;
   a1.uObjectDescID = GetObjDescId(a1.uType);
-  a1.stru_24.Reset();
+  a1.containing_item.Reset();
   a1.spell_id = 0;
   a1.spell_level = 0;
   a1.spell_skill = 0;
@@ -1986,15 +1986,17 @@
 
   if (rand() % 100 < 20 && drop.uItemID != 0)
   {
-    SpriteObject::sub_42F7EB_DropItemAt(pItemsTable->pItems[drop.uItemID].uSpriteID,
-      actor->vPosition.x,
-      actor->vPosition.y,
-      actor->vPosition.z + 16,
-      rand() % 200 + 200,
-      1,
-      1,
-      0,
-      &drop);
+      SpriteObject::sub_42F7EB_DropItemAt(
+          (SPRITE_OBJECT_TYPE)pItemsTable->pItems[drop.uItemID].uSpriteID,
+          actor->vPosition.x,
+          actor->vPosition.y,
+          actor->vPosition.z + 16,
+          rand() % 200 + 200,
+          1,
+          1,
+          0,
+          &drop
+      );
   }
 
   if (actor->pMonsterInfo.uSpecialAbilityType == MONSTER_SPECIAL_ABILITY_EXPLODE)
@@ -3608,7 +3610,7 @@
         if ( pMonster->pActorBuffs[ACTOR_BUFF_SHIELD].uExpireTime > 0 )
           uDamageAmount /= 2;
         IsAdditionalDamagePossible = true;
-        if ( projectileSprite->stru_24.uItemID != 0 && projectileSprite->stru_24.uSpecEnchantmentType == 3 )  //of carnage
+        if (projectileSprite->containing_item.uItemID != 0 && projectileSprite->containing_item.uSpecEnchantmentType == 3)  //of carnage
         {
           attackElement = DMGT_FIRE;
         }
@@ -3641,7 +3643,7 @@
   {
     if ( projectileSprite )
     {
-      a4 = projectileSprite->stru_24._439DF3_get_additional_damage((int*)&attackElement, &isLifeStealing);
+        a4 = projectileSprite->containing_item._439DF3_get_additional_damage((int*)&attackElement, &isLifeStealing);
       if ( isLifeStealing && pMonster->sCurrentHP > 0 )
       {
         player->sHealth += v61 / 5;
--- a/Engine/Objects/Chest.cpp	Wed May 20 15:12:33 2015 +0200
+++ b/Engine/Objects/Chest.cpp	Wed May 20 21:05:07 2015 +0200
@@ -56,7 +56,7 @@
   int pDepth; // ecx@26
   Vec3_int_ v; // ST4C_12@28
   bool flag_shout; // edi@28
-  int pSpriteID[4]; // [sp+84h] [bp-40h]@16
+  SPRITE_OBJECT_TYPE pSpriteID[4]; // [sp+84h] [bp-40h]@16
   Vec3_int_ pOut; // [sp+A0h] [bp-24h]@28
   int pObjectY; // [sp+B0h] [bp-14h]@21
   int sRotX; // [sp+B4h] [bp-10h]@23
@@ -84,10 +84,10 @@
   {
     if ( pPlayers[uActiveCharacter]->GetDisarmTrap() < 2 * pMapStats->pInfos[pMapID].LockX5 )
     {
-      pSpriteID[0] = 811;
-      pSpriteID[1] = 812;
-      pSpriteID[2] = 813;
-      pSpriteID[3] = 814;
+      pSpriteID[0] = SPRITE_811;
+      pSpriteID[1] = SPRITE_812;
+      pSpriteID[2] = SPRITE_813;
+      pSpriteID[3] = SPRITE_814;
       pRandom = rand() % 4;
       v6 = PID_ID(EvtTargetObj);
       if ( PID_TYPE(EvtTargetObj) == OBJECT_Decoration)
@@ -137,7 +137,7 @@
       Vec3_int_::Rotate(pDepth, sRotX, sRotY, v, &pOut.x, &pOut.z, &pOut.y);
       SpriteObject::sub_42F7EB_DropItemAt(pSpriteID[pRandom], pOut.x, pOut.z, pOut.y, 0, 1, 0, 48, 0);
 
-      pSpellObject.stru_24.Reset();
+      pSpellObject.containing_item.Reset();
       pSpellObject.spell_skill = 0;
       pSpellObject.spell_level = 0;
       pSpellObject.spell_id = 0;
--- a/Engine/Objects/NPC.cpp	Wed May 20 15:12:33 2015 +0200
+++ b/Engine/Objects/NPC.cpp	Wed May 20 21:05:07 2015 +0200
@@ -1711,9 +1711,9 @@
     }
     break;
 
-    case Acolyte:      _42777D_CastSpell_UseWand_ShootArrow(46, 0, 133, 0, 0); break;
-    case Piper:        _42777D_CastSpell_UseWand_ShootArrow(51, 0, 133, 0, 0); break;
-    case FallenWizard: _42777D_CastSpell_UseWand_ShootArrow(86, 0, 133, 0, 0); break;
+    case Acolyte:      _42777D_CastSpell_UseWand_ShootArrow(SPELL_SPIRIT_BLESS, 0, 133, 0, 0); break;
+    case Piper:        _42777D_CastSpell_UseWand_ShootArrow(SPELL_SPIRIT_HEROISM, 0, 133, 0, 0); break;
+    case FallenWizard: _42777D_CastSpell_UseWand_ShootArrow(SPELL_LIGHT_HOUR_OF_POWER, 0, 133, 0, 0); break;
       
     case Teacher:
     case Instructor:
--- a/Engine/Objects/Player.cpp	Wed May 20 15:12:33 2015 +0200
+++ b/Engine/Objects/Player.cpp	Wed May 20 21:05:07 2015 +0200
@@ -4672,7 +4672,7 @@
       pIcons_LOD->RemoveTexturesPackFromTextureList();
       current_screen_type = SCREEN_GAME;
       viewparams->bRedrawGameUI = 1;
-      _42777D_CastSpell_UseWand_ShootArrow(scroll_id, player_num - 1, 0x85u, 1, 0);
+      _42777D_CastSpell_UseWand_ShootArrow((SPELL_TYPE)scroll_id, player_num - 1, 0x85u, 1, 0);
     }
     else
     {
@@ -8149,8 +8149,8 @@
 
   SpriteObject a1a; // [sp+Ch] [bp-74h]@1
   //SpriteObject::SpriteObject(&a1a);
-  a1a.uType = 600;
-  a1a.stru_24.Reset();
+  a1a.uType = SPRITE_600;
+  a1a.containing_item.Reset();
 
   a1a.spell_id = SPELL_FIRE_FIREBALL;
   a1a.spell_level = 8;
--- a/Engine/Objects/SpriteObject.cpp	Wed May 20 15:12:33 2015 +0200
+++ b/Engine/Objects/SpriteObject.cpp	Wed May 20 21:05:07 2015 +0200
@@ -27,10 +27,6 @@
 
 
 
-
-
-
-
 size_t uNumSpriteObjects;
 std::array<SpriteObject, MAX_SPRITE_OBJECTS> pSpriteObjects;
 
@@ -43,7 +39,7 @@
   vVelocity.z = 0;
   vVelocity.y = 0;
   vVelocity.x = 0;
-  uType = 0;
+  uType = SPRITE_NULL;
   uObjectDescID = 0;
   field_61 = 0;
   field_60_distance_related_prolly_lod = 0;
@@ -229,7 +225,7 @@
     {
       if ( pSpriteObjects[uLayingItemID].vPosition.z < v7 )
         pSpriteObjects[uLayingItemID].vPosition.z = v8;
-      if ( !_46BFFA_check_object_intercept(uLayingItemID, 0) )
+      if ( !_46BFFA_update_spell_fx(uLayingItemID, 0) )
         return;
     }
     pSpriteObjects[uLayingItemID].vPosition.z = v8;
@@ -289,7 +285,7 @@
     goto LABEL_92;
   if ( pSpriteObjects[uLayingItemID].vPosition.z < v7 )
     pSpriteObjects[uLayingItemID].vPosition.z = v8;
-  if ( _46BFFA_check_object_intercept(uLayingItemID, 0) )
+  if ( _46BFFA_update_spell_fx(uLayingItemID, 0) )
   {
 LABEL_92:
     stru_721530.field_0 = 0;
@@ -403,7 +399,7 @@
       {
         if ( v29 < v54 )
           pSpriteObjects[uLayingItemID].vPosition.z = v54 + 1;
-        if ( !_46BFFA_check_object_intercept(uLayingItemID, stru_721530.uFaceID) )
+        if ( !_46BFFA_update_spell_fx(uLayingItemID, stru_721530.uFaceID) )
           return;
       }
       if (PID_TYPE(stru_721530.uFaceID) == OBJECT_Decoration)
@@ -613,7 +609,7 @@
       pSpriteObject->vPosition.z += fixpoint_mul(stru_721530.field_7C, stru_721530.direction.z);
       pSpriteObject->uSectorID = stru_721530.uSectorID;
       stru_721530.field_70 += stru_721530.field_7C;
-      if ( pObject->uFlags & OBJECT_DESC_INTERACTABLE && !_46BFFA_check_object_intercept(uLayingItemID, stru_721530.uFaceID) )
+      if ( pObject->uFlags & OBJECT_DESC_INTERACTABLE && !_46BFFA_update_spell_fx(uLayingItemID, stru_721530.uFaceID) )
         return;
       v15 = (signed int)stru_721530.uFaceID >> 3;
       if (PID_TYPE(stru_721530.uFaceID) == OBJECT_Decoration)
@@ -691,7 +687,7 @@
     pSpriteObject->vVelocity.z -= LOWORD(pEventTimer->uTimeElapsed) * GetGravityStrength();
     goto LABEL_25;
   }
-  if ( !(pObject->uFlags & OBJECT_DESC_INTERACTABLE) || _46BFFA_check_object_intercept(uLayingItemID, 0) )
+  if ( !(pObject->uFlags & OBJECT_DESC_INTERACTABLE) || _46BFFA_update_spell_fx(uLayingItemID, 0) )
   {
     pSpriteObject->vPosition.z = v42 + 1;
     if ( pIndoor->pFaces[uFaceID].uPolygonType == POLYGON_Floor )
@@ -977,24 +973,24 @@
 
 
 //----- (0042F7EB) --------------------------------------------------------
-bool SpriteObject::sub_42F7EB_DropItemAt(unsigned int uSpriteID, int x, int y, int z, int a4, int count, int a7, unsigned __int16 attributes, ItemGen *a9)
+bool SpriteObject::sub_42F7EB_DropItemAt(SPRITE_OBJECT_TYPE sprite, int x, int y, int z, int a4, int count, int a7, unsigned __int16 attributes, ItemGen *a9)
 {
   unsigned __int16 pObjectDescID; // ax@7
   SpriteObject pSpellObject; // [sp+Ch] [bp-78h]@1
 
-  pSpellObject.stru_24.Reset();
+  pSpellObject.containing_item.Reset();
   if ( a9 )
-    memcpy(&pSpellObject.stru_24, a9, sizeof(pSpellObject.stru_24));
+      memcpy(&pSpellObject.containing_item, a9, sizeof(pSpellObject.containing_item));
   pSpellObject.spell_skill = 0;
   pSpellObject.spell_level = 0;
   pSpellObject.spell_id = 0;
   pSpellObject.field_54 = 0;
-  pSpellObject.uType = uSpriteID;
+  pSpellObject.uType = sprite;
   pObjectDescID = 0;
   for ( uint i = 0; i < (signed int)pObjectList->uNumObjects; ++i )
   {
-    if ( (short)uSpriteID == pObjectList->pObjects[i].uObjectID )
-      pObjectDescID = i;
+      if (sprite == pObjectList->pObjects[i].uObjectID)
+        pObjectDescID = i;
   }
   pSpellObject.uObjectDescID = pObjectDescID;
   pSpellObject.vPosition.x = x;
@@ -1012,8 +1008,8 @@
     {
       for ( uint i = 1; i < pItemsTable->uAllItemsCount; ++i )
       {
-        if ( pItemsTable->pItems[i].uSpriteID == uSpriteID )
-          pSpellObject.stru_24.uItemID = i;
+          if (pItemsTable->pItems[i].uSpriteID == sprite)
+            pSpellObject.containing_item.uItemID = i;
       }
     }
   }
@@ -1053,13 +1049,13 @@
 
   SpriteObject a1; // [sp+Ch] [bp-70h]@1
   //SpriteObject::SpriteObject(&a1);
-  a1.stru_24.Reset();
+  a1.containing_item.Reset();
 
   a1.spell_skill = 0;
   a1.spell_level = 0;
   a1.spell_id = 0;
   a1.field_54 = 0;
-  a1.uType = 800;
+  a1.uType = SPRITE_800;
   v7 = 0;
   for ( uint i = 0; i < (signed int)pObjectList->uNumObjects; ++i )
   {
@@ -1085,8 +1081,10 @@
   }
 }
 
+
+
 //----- (0046BFFA) --------------------------------------------------------
-bool __fastcall _46BFFA_check_object_intercept(unsigned int uLayingItemID, signed int a2)
+bool __fastcall _46BFFA_update_spell_fx(unsigned int uLayingItemID, signed int a2)
 {
 	ObjectDesc *object; // ebx@1
 	unsigned int v8; // eax@19
@@ -1194,9 +1192,9 @@
 	switch (pSpriteObjects[uLayingItemID].uType)
 	{
 
-	case 1060:
-	case 2030:
-	case 9010:
+    case SPRITE_SPELL_FIRE_FIRE_SPIKE:
+    case SPRITE_SPELL_AIR_SPARKS:
+    case SPRITE_SPELL_DARK_TOXIC_CLOUD:
 	{
 				 //v9 = 0;
 				 if (PID_TYPE(a2) == 6 || PID_TYPE(a2) == 5 || !PID_TYPE(a2))
@@ -1204,7 +1202,7 @@
 				 if (PID_TYPE(a2) != 2)
 				 {
 					 sub_43A97E(uLayingItemID, a2);
-					 ++pSpriteObjects[uLayingItemID].uType;
+                     pSpriteObjects[uLayingItemID].uType = (SPRITE_OBJECT_TYPE)(pSpriteObjects[uLayingItemID].uType + 1);
 					 v95 = 0;
 					 for (v52 = 0; v52 < (signed int)pObjectList->uNumObjects; ++v52)
 					 {
@@ -1228,7 +1226,7 @@
 					 pAudioPlayer->PlaySound((SoundID)v125, v124, 0, -1, 0, v97, 0, 0);
 					 return 0;
 				 }
-				 pSpriteObjects[uLayingItemID].uType = pSpriteObjects[uLayingItemID].uType + 1;
+				 pSpriteObjects[uLayingItemID].uType = (SPRITE_OBJECT_TYPE)(pSpriteObjects[uLayingItemID].uType + 1);
 				 v121 = 0;
 				 for (v119 = 0; v119 < (signed int)pObjectList->uNumObjects; ++v119)
 				 {
@@ -1249,18 +1247,18 @@
 	}
 
 
-	case 500:
-	case 505:
-	case 510:
-	case 515:
-	case 520:
-	case 525:
-	case 530:
-	case 535:
-	case 540:
+    case SPRITE_PROJECTILE_500:
+    case SPRITE_PROJECTILE_505:
+    case SPRITE_PROJECTILE_510:
+    case SPRITE_PROJECTILE_515:
+    case SPRITE_PROJECTILE_520:
+    case SPRITE_PROJECTILE_525:
+    case SPRITE_PROJECTILE_530:
+    case SPRITE_PROJECTILE_535:
+    case SPRITE_PROJECTILE_540:
 	{
 				sub_43A97E(uLayingItemID, a2);
-				++pSpriteObjects[uLayingItemID].uType;
+                pSpriteObjects[uLayingItemID].uType = (SPRITE_OBJECT_TYPE)(pSpriteObjects[uLayingItemID].uType + 1);
 				v12 = 0;
 				for (v10 = 0; v10 < (signed int)pObjectList->uNumObjects; ++v10)
 				{
@@ -1283,10 +1281,10 @@
 				return 0;
 	}
 
-	case 545:
-	case 550:
+    case SPRITE_PROJECTILE_545:
+    case SPRITE_PROJECTILE_550:
 	{
-				if (pSpriteObjects[uLayingItemID].stru_24.uItemID != 405 && pSpriteObjects[uLayingItemID].stru_24.uSpecEnchantmentType != 3)
+        if (pSpriteObjects[uLayingItemID].containing_item.uItemID != 405 && pSpriteObjects[uLayingItemID].containing_item.uSpecEnchantmentType != 3)
 				{
 					pSpriteObjects[uLayingItemID].vVelocity.z = 0;
 					pSpriteObjects[uLayingItemID].vVelocity.y = 0;
@@ -1305,7 +1303,7 @@
 					return 0;
 				}
 				v18 = 0;
-				pSpriteObjects[uLayingItemID].uType = 600;
+                pSpriteObjects[uLayingItemID].uType = SPRITE_600;
 				v22 = 0;
 				for (v19 = 0; v19 < (signed int)pObjectList->uNumObjects; ++v19)
 				{
@@ -1344,9 +1342,9 @@
 				return 0;
 	}
 
-	case 600:
+    case SPRITE_600:
 	{
-				pSpriteObjects[uLayingItemID].uType = 601;
+                pSpriteObjects[uLayingItemID].uType = SPRITE_601;
 				v36 = 0;
 				for (v34 = 0; v34 < (signed int)pObjectList->uNumObjects; ++v34)
 				{
@@ -1373,21 +1371,21 @@
 				return 0;
 	}
 
-	case 1010:
-	case 1100:
-	case 2060:
-	case 3010:
-	case 3030:
-	case 3060:
-	case 4000:
-	case 4030:
-	case 4050:
-	case 4100:
-	case 6010:
-	case 6090:
+    case SPRITE_SPELL_FIRE_FIRE_BOLT:
+    case SPRITE_SPELL_FIRE_INCINERATE:
+    case SPRITE_SPELL_AIR_LIGHNING_BOLT:
+    case SPRITE_SPELL_WATER_POISON_SPRAY:
+    case SPRITE_SPELL_WATER_ICE_BOLT:
+    case SPRITE_SPELL_WATER_ACID_BURST:
+    case SPRITE_SPELL_EARTH_STUN:
+    case SPRITE_SPELL_EARTH_DEADLY_SWARM:
+    case SPRITE_SPELL_EARTH_BLADES:
+    case SPRITE_SPELL_EARTH_MASS_DISTORTION:
+    case SPRITE_SPELL_MIND_MIND_BLAST:
+    case SPRITE_SPELL_MIND_PSYCHIC_SHOCK:
 	{
 				 sub_43A97E(uLayingItemID, a2);
-				 ++pSpriteObjects[uLayingItemID].uType;
+                 pSpriteObjects[uLayingItemID].uType = (SPRITE_OBJECT_TYPE)(pSpriteObjects[uLayingItemID].uType + 1);
 				 v95 = 0;
 				 for (v52 = 0; v52 < (signed int)pObjectList->uNumObjects; ++v52)
 				 {
@@ -1414,10 +1412,10 @@
 	}
 
 
-	case 555:
+	case SPRITE_PROJECTILE_555:
 	{
-				sub_43A97E(uLayingItemID, a2);
-				++pSpriteObjects[uLayingItemID].uType;
+        sub_43A97E(uLayingItemID, a2);
+        pSpriteObjects[uLayingItemID].uType = SPRITE_556;
 				v18 = 0;
 				v22 = 0;
 				v25 = (char *)&pObjectList->pObjects->uObjectID;
@@ -1436,10 +1434,10 @@
 				return 0;
 	}
 
-	case 3090:
+    case SPRITE_SPELL_WATER_ICE_BLAST:
 	{
 				 //v9 = 0;
-				 pSpriteObjects[uLayingItemID].uType = pSpriteObjects[uLayingItemID].uType + 2;
+        pSpriteObjects[uLayingItemID].uType = SPRITE_SPELL_WATER_ICE_BLAST_FALLOUT;
 				 v63 = 0;
 				 for (v61 = 0; v61 < (signed int)pObjectList->uNumObjects; ++v61)
 				 {
@@ -1479,9 +1477,9 @@
 				 return 0;
 	}
 
-	case 3092:
-	{
-				 pSpriteObjects[uLayingItemID].uType = pSpriteObjects[uLayingItemID].uType - 1;
+    case SPRITE_SPELL_WATER_ICE_BLAST_FALLOUT:
+    {
+        pSpriteObjects[uLayingItemID].uType = SPRITE_SPELL_WATER_ICE_BLAST_IMPACT;
 				 v58 = 0;
 				 for (v56 = 0; v56 < (signed int)pObjectList->uNumObjects; ++v56)
 				 {
@@ -1507,11 +1505,11 @@
 				 return 0;
 	}
 
-	case 4070:
+    case SPRITE_SPELL_EARTH_ROCK_BLAST:
 	{
 				 if (PID_TYPE(a2) == 6 || PID_TYPE(a2) == 5 || !PID_TYPE(a2))
-					 return 1;
-				 pSpriteObjects[uLayingItemID].uType = pSpriteObjects[uLayingItemID].uType + 1;
+                     return 1;
+                 pSpriteObjects[uLayingItemID].uType = SPRITE_SPELL_EARTH_ROCK_BLAST_IMPACT;
 				 v71 = 0;
 				 for (v69 = 0; v69 < (signed int)pObjectList->uNumObjects; ++v69)
 				 {
@@ -1538,10 +1536,10 @@
 				 return 0;
 	}
 
-	case 4090:
+    case SPRITE_SPELL_EARTH_DEATH_BLOSSOM:
 	{
 				 //v9 = 0;
-				 pSpriteObjects[uLayingItemID].uType = pSpriteObjects[uLayingItemID].uType + 2;
+        pSpriteObjects[uLayingItemID].uType = SPRITE_SPELL_EARTH_DEATH_BLOSSOM_FALLOUT;
 				 v88 = 0;
 				 for (v86 = 0; v86 < (signed int)pObjectList->uNumObjects; ++v86)
 				 {
@@ -1579,9 +1577,9 @@
 				 return 0;
 	}
 
-	case 4092:
+    case SPRITE_SPELL_EARTH_DEATH_BLOSSOM_FALLOUT:
 	{
-				 pSpriteObjects[uLayingItemID].uType = 4091;
+        pSpriteObjects[uLayingItemID].uType = SPRITE_SPELL_EARTH_DEATH_BLOSSOM_IMPACT;
 				 v83 = 0;
 				 for (v81 = 0; v81 < (signed int)pObjectList->uNumObjects; ++v81)
 				 {
@@ -1608,12 +1606,12 @@
 				 return 0;
 	}
 
-	case 8010:
+    case SPRITE_SPELL_LIGHT_DESTROY_UNDEAD:
 	{
 				 if (PID_TYPE(a2) == 3
 					 && MonsterStats::BelongsToSupertype(pActors[PID_ID(a2)].pMonsterInfo.uID, MONSTER_SUPERTYPE_UNDEAD))
 					 sub_43A97E(uLayingItemID, a2);
-				 ++pSpriteObjects[uLayingItemID].uType;
+                 pSpriteObjects[uLayingItemID].uType = SPRITE_SPELL_LIGHT_DESTROY_UNDEAD_1;
 				 //v9 = 0;
 				 v95 = 0;
 				 for (v52 = 0; v52 < (signed int)pObjectList->uNumObjects; ++v52)
@@ -1641,13 +1639,13 @@
 				 return 0;
 	}
 
-	case 7030:
-	case 7090:
-	case 8000:
-	case 8090:
+    case SPRITE_SPELL_BODY_HARM:
+    case SPRITE_SPELL_BODY_FLYING_FIST:
+    case SPRITE_SPELL_LIGHT_LIGHT_BOLT:
+    case SPRITE_SPELL_LIGHT_SUNRAY:
 	{
 				 sub_43A97E(uLayingItemID, a2);
-				 ++pSpriteObjects[uLayingItemID].uType;
+                 pSpriteObjects[uLayingItemID].uType = (SPRITE_OBJECT_TYPE)(pSpriteObjects[uLayingItemID].uType + 1);
 				 v95 = 0;
 				 for (v52 = 0; v52 < (signed int)pObjectList->uNumObjects; ++v52)
 				 {
@@ -1673,9 +1671,9 @@
 				 return 0;
 	}
 
-	case 6040:
-	case 8030:
-	case 9030:
+    case SPRITE_SPELL_MIND_CHARM:
+    case SPRITE_SPELL_LIGHT_PARALYZE:
+    case SPRITE_SPELL_DARK_SHRINKING_RAY:
 	{
 				 v143 = 17030;
 				 switch (pSpriteObjects[uLayingItemID].uType)
@@ -1700,8 +1698,8 @@
 					 }
 					 pSpriteObjects[uLayingItemID]._46BEF1_apply_spells_aoe();
 					 if (!v138)
-					 {
-						 ++pSpriteObjects[uLayingItemID].uType;
+                     {
+                         pSpriteObjects[uLayingItemID].uType = (SPRITE_OBJECT_TYPE)(pSpriteObjects[uLayingItemID].uType + 1);
 						 v112 = 0;
 						 for (v110 = 0; v110 < (signed int)pObjectList->uNumObjects; ++v110)
 						 {
@@ -1735,7 +1733,7 @@
 				 v137 = pSpriteObjects[uLayingItemID].spell_level;
 				 v152 = pSpriteObjects[uLayingItemID].spell_skill;
 				 v136 = pSpriteObjects[uLayingItemID].spell_id;
-				 if (pSpriteObjects[uLayingItemID].uType == 9030)
+                 if (pSpriteObjects[uLayingItemID].uType == SPRITE_SPELL_DARK_SHRINKING_RAY)
 				 {
 					 v150 = 2;
 					 if (v152 == 2)
@@ -1748,38 +1746,38 @@
 					 pActors[v139].uAttributes |= ACTOR_AGGRESSOR;
 					 v107 = v135;
 				 }
-				 if (pSpriteObjects[uLayingItemID].uType == 6040)
+                 if (pSpriteObjects[uLayingItemID].uType == SPRITE_SPELL_MIND_CHARM)
 				 {
 					 v135 = 7;
 					 v107 = v135;
 				 }
 				 else
 				 {
-					 if (pSpriteObjects[uLayingItemID].uType == 8030)
+                     if (pSpriteObjects[uLayingItemID].uType == SPRITE_SPELL_LIGHT_PARALYZE)
 					 {
 						 v135 = 9;
 						 v107 = v135;
 					 }
 					 else
 					 {
-						 if (pSpriteObjects[uLayingItemID].uType != 9030)
+                         if (pSpriteObjects[uLayingItemID].uType != SPRITE_SPELL_DARK_SHRINKING_RAY)
 						 {
 							 v107 = v136;
 						 }
-						 if (pSpriteObjects[uLayingItemID].uType == 9030)
+                         if (pSpriteObjects[uLayingItemID].uType == SPRITE_SPELL_DARK_SHRINKING_RAY)
 						 {
 							 v135 = 10;
 							 v107 = v135;
 						 }
 					 }
 				 }
-				 if (pSpriteObjects[uLayingItemID].uType != 9030 || v152 != 4)
+                 if (pSpriteObjects[uLayingItemID].uType != SPRITE_SPELL_DARK_SHRINKING_RAY || v152 != 4)
 				 {
 					 v108 = v139;
 					 if (pActors[v139].DoesDmgTypeDoDamage((DAMAGE_TYPE)v107))
 					 {
 						 v138 = 0;
-						 if (pSpriteObjects[uLayingItemID].uType == 8030)
+                         if (pSpriteObjects[uLayingItemID].uType == SPRITE_SPELL_LIGHT_PARALYZE)
 						 {
 							 pActors[v108].uAIState = Standing;
 							 pActors[v108].UpdateAnimation();
@@ -1796,8 +1794,8 @@
 				 pSpriteObjects[uLayingItemID].spell_skill = 0;
 				 pSpriteObjects[uLayingItemID].spell_id = 0;
 				 if (!v138)
-				 {
-					 ++pSpriteObjects[uLayingItemID].uType;
+                 {
+                     pSpriteObjects[uLayingItemID].uType = (SPRITE_OBJECT_TYPE)(pSpriteObjects[uLayingItemID].uType + 1);
 					 v112 = 0;
 					 for (v110 = 0; v110 < (signed int)pObjectList->uNumObjects; ++v110)
 					 {
@@ -1826,10 +1824,10 @@
 				 return 0;
 	}
 
-	case 9040:
+	case SPRITE_SPELL_DARK_SHARPMETAL:
 	{
 				 sub_43A97E(uLayingItemID, a2);
-				 ++pSpriteObjects[uLayingItemID].uType;
+                 pSpriteObjects[uLayingItemID].uType = SPRITE_SPELL_DARK_SHARPMETAL_IMPACT;
 				 v95 = 0;
 				 for (v52 = 0; v52 < (signed int)pObjectList->uNumObjects; ++v52)
 				 {
@@ -1893,19 +1891,19 @@
 		return 1;
 		}*/
 
-	case 1080:
-	case 2100:
+    case SPRITE_SPELL_FIRE_METEOR_SHOWER:
+    case SPRITE_SPELL_AIR_STARBURST:
 	{
 				 if (PID_TYPE(a2) == 3)
 					 return 1;
 				 //else go to next case
 	}
 
-	case 1050:
-	case 9080:
+    case SPRITE_SPELL_FIRE_FIREBALL:
+    case SPRITE_SPELL_DARK_DRAGON_BREATH:
 	{
 				 v95 = 0;
-				 pSpriteObjects[uLayingItemID].uType = pSpriteObjects[uLayingItemID].uType + 1;
+				 pSpriteObjects[uLayingItemID].uType = (SPRITE_OBJECT_TYPE)(pSpriteObjects[uLayingItemID].uType + 1);
 				 for (v146 = 0; v146 < (signed int)pObjectList->uNumObjects; ++v146)
 				 {
 					 if (pSpriteObjects[uLayingItemID].uType == pObjectList->pObjects[v146].uObjectID)
--- a/Engine/Objects/SpriteObject.h	Wed May 20 15:12:33 2015 +0200
+++ b/Engine/Objects/SpriteObject.h	Wed May 20 21:05:07 2015 +0200
@@ -1,5 +1,192 @@
 #pragma once
-#include "Items.h"
+#include "Engine/VectorTypes.h"
+#include "Engine/Objects/Items.h"
+
+
+
+
+enum SPRITE_OBJECT_TYPE : unsigned __int16
+{
+    SPRITE_NULL = 0,
+
+    SPRITE_SPELL_0 = 10,
+
+    SPRITE_PROJECTILE_500 = 500, // blue bolt projectile + smoke   e.g. blue dragon attack
+    SPRITE_PROJECTILE_500_IMPACT = 501,
+    SPRITE_PROJECTILE_505 = 505, // dark-brown bolt
+    SPRITE_PROJECTILE_505_IMPACT = 506,
+    SPRITE_PROJECTILE_510 = 510, // red bolt projectile + smoke   e.g. red dragon attack
+    SPRITE_PROJECTILE_510_IMPACT = 511,
+    SPRITE_PROJECTILE_515 = 515, // deep-blue bolt
+    SPRITE_PROJECTILE_515_IMPACT = 516,
+    SPRITE_PROJECTILE_520 = 520, // light-green bolt
+    SPRITE_PROJECTILE_520_IMPACT = 521,
+    SPRITE_PROJECTILE_525 = 525, // yellow bolt
+    SPRITE_PROJECTILE_525_IMPACT = 526,
+    SPRITE_PROJECTILE_530 = 530, // blue bolt projectile + smoke   e.g. blue dragon attack
+    SPRITE_PROJECTILE_530_IMPACT = 531,
+    SPRITE_PROJECTILE_535 = 535, // white bolt
+    SPRITE_PROJECTILE_535_IMPACT = 536,
+    SPRITE_PROJECTILE_540 = 540, // gray bolt
+    SPRITE_PROJECTILE_540_IMPACT = 541,
+    SPRITE_PROJECTILE_545 = 545,
+    SPRITE_PROJECTILE_550 = 550,
+    SPRITE_PROJECTILE_555 = 555,
+
+    SPRITE_556 = 556, // some red mobile light applied
+    SPRITE_600 = 600, // some reddish mobile light applied
+    SPRITE_601 = 601,
+
+    SPRITE_800 = 800,
+
+    SPRITE_811 = 811,
+    SPRITE_812 = 812,
+    SPRITE_813 = 813,
+    SPRITE_814 = 814,
+
+    SPRITE_SPELL_FIRE_TORCH_LIGHT = 1000,
+    SPRITE_SPELL_FIRE_FIRE_BOLT = 1010,
+    SPRITE_SPELL_FIRE_FIRE_BOLT_IMPACT = 1011,
+    SPRITE_SPELL_FIRE_PROTECTION_FROM_FIRE = 1020,
+    SPRITE_SPELL_FIRE_FIRE_AURA = 1030,
+    SPRITE_SPELL_FIRE_HASTE = 1040,
+    SPRITE_SPELL_FIRE_FIREBALL = 1050,
+    SPRITE_SPELL_FIRE_FIREBALL_IMPACT = 1051,
+    SPRITE_SPELL_FIRE_FIRE_SPIKE = 1060,
+    SPRITE_SPELL_FIRE_FIRE_SPIKE_IMPACT = 1061,
+    SPRITE_SPELL_FIRE_IMMOLATION = 1070,
+    SPRITE_SPELL_FIRE_METEOR_SHOWER = 1080,
+    SPRITE_SPELL_FIRE_METEOR_SHOWER_1 = 1081,
+    SPRITE_SPELL_FIRE_INFERNO = 1090,
+    SPRITE_SPELL_FIRE_INCINERATE = 1100,
+    SPRITE_SPELL_FIRE_INCINERATE_IMPACT = 1101,
+
+    SPRITE_SPELL_AIR_WIZARD_EYE = 2000,
+    SPRITE_SPELL_AIR_FEATHER_FALL = 2010,
+    SPRITE_SPELL_AIR_PROTECTION_FROM_AIR = 2020,
+    SPRITE_SPELL_AIR_SPARKS = 2030,
+    SPRITE_SPELL_AIR_JUMP = 2040,
+    SPRITE_SPELL_AIR_SHIELD = 2050,
+    SPRITE_SPELL_AIR_LIGHNING_BOLT = 2060,
+    SPRITE_SPELL_AIR_LIGHNING_BOLT_IMPACT = 2061,
+    SPRITE_SPELL_AIR_INVISIBILITY = 2070,
+    SPRITE_SPELL_AIR_IMPLOSION = 2080,
+    SPRITE_SPELL_AIR_IMPLOSION_IMPACT = 2081,
+    SPRITE_SPELL_AIR_FLY = 2090,
+    SPRITE_SPELL_AIR_STARBURST = 2100,
+    SPRITE_SPELL_AIR_STARBURST_1 = 2101,
+
+    SPRITE_SPELL_WATER_AWAKEN = 3000,
+    SPRITE_SPELL_WATER_POISON_SPRAY = 3010,
+    SPRITE_SPELL_WATER_POISON_SPRAY_IMPACT = 3011,
+    SPRITE_SPELL_WATER_PROTECTION_FROM_WATER = 3020,
+    SPRITE_SPELL_WATER_ICE_BOLT = 3030,
+    SPRITE_SPELL_WATER_ICE_BOLT_IMPACT = 3031,
+    SPRITE_SPELL_WATER_WATER_WALK = 3040,
+    SPRITE_SPELL_WATER_RECHARGE_ITEM = 3050,
+    SPRITE_SPELL_WATER_ACID_BURST = 3060,
+    SPRITE_SPELL_WATER_ACID_BURST_IMPACT = 3061,
+    SPRITE_SPELL_WATER_ENCHANT_ITEM = 3070,
+    SPRITE_SPELL_WATER_TOWN_PORTAL = 3080,
+    SPRITE_SPELL_WATER_ICE_BLAST = 3090,
+    SPRITE_SPELL_WATER_ICE_BLAST_IMPACT = 3091,
+    SPRITE_SPELL_WATER_ICE_BLAST_FALLOUT = 3092,
+    SPRITE_SPELL_WATER_LLOYDS_BEACON = 3100,
+
+    SPRITE_SPELL_EARTH_STUN = 4000,
+    SPRITE_SPELL_EARTH_SLOW = 4010,
+    SPRITE_SPELL_EARTH_PROTECTION_FROM_EARTH = 4020,
+    SPRITE_SPELL_EARTH_DEADLY_SWARM = 4030,
+    SPRITE_SPELL_EARTH_DEADLY_SWARM_IMPACT = 4031,
+    SPRITE_SPELL_EARTH_STONESKIN = 4040,
+    SPRITE_SPELL_EARTH_BLADES = 4050,
+    SPRITE_SPELL_EARTH_BLADES_IMPACT = 4051,
+    SPRITE_SPELL_EARTH_STONE_TO_FLESH = 4060,
+    SPRITE_SPELL_EARTH_ROCK_BLAST = 4070,
+    SPRITE_SPELL_EARTH_ROCK_BLAST_IMPACT = 4071,
+    SPRITE_SPELL_EARTH_TELEKINESIS = 4080,
+    SPRITE_SPELL_EARTH_DEATH_BLOSSOM = 4090,
+    SPRITE_SPELL_EARTH_DEATH_BLOSSOM_IMPACT = 4091,
+    SPRITE_SPELL_EARTH_DEATH_BLOSSOM_FALLOUT = 4092,
+    SPRITE_SPELL_EARTH_MASS_DISTORTION = 4100,
+
+    SPRITE_SPELL_SPIRIT_DETECT_LIFE = 5000,
+    SPRITE_SPELL_SPIRIT_BLESS = 5010,
+    SPRITE_SPELL_SPIRIT_FATE = 5020,
+    SPRITE_SPELL_SPIRIT_TURN_UNDEAD = 5030,
+    SPRITE_SPELL_SPIRIT_TURN_UNDEAD_1 = 5031,
+    SPRITE_SPELL_SPIRIT_REMOVE_CURSE = 5040,
+    SPRITE_SPELL_SPIRIT_PRESERVATION = 5050,
+    SPRITE_SPELL_SPIRIT_HEROISM = 5060,
+    SPRITE_SPELL_SPIRIT_SPIRIT_LASH = 5070,
+    SPRITE_SPELL_SPIRIT_RAISE_DEAD = 5080,
+    SPRITE_SPELL_SPIRIT_SHARED_LIFE = 5090,
+    SPRITE_SPELL_SPIRIT_RESSURECTION = 5100,
+
+    SPRITE_SPELL_MIND_REMOVE_FEAR = 6000,
+    SPRITE_SPELL_MIND_MIND_BLAST = 6010,
+    SPRITE_SPELL_MIND_MIND_BLAST_IMPACT = 6011,
+    SPRITE_SPELL_MIND_PROTECTION_FROM_MIND = 6020,
+    SPRITE_SPELL_MIND_TELEPATHY = 6030,
+    SPRITE_SPELL_MIND_CHARM = 6040,
+    SPRITE_SPELL_MIND_CURE_PARALYSIS = 6050,
+    SPRITE_SPELL_MIND_BERSERK = 6060,
+    SPRITE_SPELL_MIND_MASS_FEAR = 6070,
+    SPRITE_SPELL_MIND_MASS_FEAR_1 = 6071,
+    SPRITE_SPELL_MIND_CURE_INSANITY = 6080,
+    SPRITE_SPELL_MIND_PSYCHIC_SHOCK = 6090,
+    SPRITE_SPELL_MIND_ENSLAVE = 6100,
+
+    SPRITE_SPELL_BODY_CURE_WEAKNESS = 7000,
+    SPRITE_SPELL_BODY_FIRST_AID = 7010,
+    SPRITE_SPELL_BODY_PROTECTION_FROM_BODY = 7020,
+    SPRITE_SPELL_BODY_HARM = 7030,
+    SPRITE_SPELL_BODY_HARM_IMPACT = 7031,
+    SPRITE_SPELL_BODY_REGENERATION = 7040,
+    SPRITE_SPELL_BODY_CURE_POISON = 7050,
+    SPRITE_SPELL_BODY_HAMMERHANDS = 7060,
+    SPRITE_SPELL_BODY_CURE_DISEASE = 7070,
+    SPRITE_SPELL_BODY_PROTECTION_FROM_MAGIC = 7080,
+    SPRITE_SPELL_BODY_FLYING_FIST = 7090,
+    SPRITE_SPELL_BODY_FLYING_FIST_IMPACT = 7091,
+    SPRITE_SPELL_BODY_POWER_CURE = 7100,
+
+    SPRITE_SPELL_LIGHT_LIGHT_BOLT = 8000,
+    SPRITE_SPELL_LIGHT_LIGHT_BOLT_IMPACT = 8001,
+    SPRITE_SPELL_LIGHT_DESTROY_UNDEAD = 8010,
+    SPRITE_SPELL_LIGHT_DESTROY_UNDEAD_1 = 8011,
+    SPRITE_SPELL_LIGHT_DISPEL_MAGIC = 8020,
+    SPRITE_SPELL_LIGHT_DISPEL_MAGIC_1 = 8021,
+    SPRITE_SPELL_LIGHT_PARALYZE = 8030,
+    SPRITE_SPELL_LIGHT_SUMMON_ELEMENTAL = 8040,
+    SPRITE_SPELL_LIGHT_DAY_OF_THE_GODS = 8050,
+    SPRITE_SPELL_LIGHT_PRISMATIC_LIGHT = 8060,
+    SPRITE_SPELL_LIGHT_PRISMATIC_LIGHT_1 = 8061,
+    SPRITE_SPELL_LIGHT_DAY_OF_PROTECTION = 8070,
+    SPRITE_SPELL_LIGHT_HOUR_OF_POWER = 8080,
+    SPRITE_SPELL_LIGHT_SUNRAY = 8090,
+    SPRITE_SPELL_LIGHT_SUNRAY_IMPACT = 8091,
+    SPRITE_SPELL_LIGHT_DIVINE_INTERVENTION = 8100,
+
+    SPRITE_SPELL_DARK_REANIMATE = 9000,
+    SPRITE_SPELL_DARK_REANIMATE_1 = 9001,
+    SPRITE_SPELL_DARK_TOXIC_CLOUD = 9010,
+    SPRITE_SPELL_DARK_VAMPIRIC_WEAPON = 9020,
+    SPRITE_SPELL_DARK_SHRINKING_RAY = 9030,
+    SPRITE_SPELL_DARK_SHARPMETAL = 9040,
+    SPRITE_SPELL_DARK_SHARPMETAL_IMPACT = 9041,
+    SPRITE_SPELL_DARK_CONTROL_UNDEAD = 9050,
+    SPRITE_SPELL_DARK_PAIN_REFLECTION = 9060,
+    SPRITE_SPELL_DARK_SACRIFICE = 9070,
+    SPRITE_SPELL_DARK_DRAGON_BREATH = 9080,
+    SPRITE_SPELL_DARK_DRAGON_BREATH_1 = 9081,
+    SPRITE_SPELL_DARK_ARMAGEDDON = 9090,
+    SPRITE_SPELL_DARK_SOULDRINKER = 9100,
+
+    SPRITE_SPELL_BOW_ARROW = 545,
+    SPRITE_SPELL_101 = 545,
+    SPRITE_SPELL_LASER_PROJECTILE = 555,
+};
 
 enum
 {
@@ -22,12 +209,13 @@
   static void UpdateObject_fn0_BLV(unsigned int uLayingItemID);
   static void UpdateObject_fn0_ODM(unsigned int uLayingItemID);
   static void OnInteraction(unsigned int uLayingItemID);
-  static bool sub_42F7EB_DropItemAt(unsigned int uSpriteID, int x, int y, int z, int a4, int count, int a7, unsigned __int16 attributes, ItemGen *a9);
+  static bool sub_42F7EB_DropItemAt(SPRITE_OBJECT_TYPE sprite, int x, int y, int z, int a4, int count, int a7, unsigned __int16 attributes, ItemGen *a9);
   static void sub_42F960_create_object(int x, int y, int z);
   static void InitializeSpriteObjects();
 
 
-  unsigned __int16 uType;
+  SPRITE_OBJECT_TYPE uType;
+  //unsigned __int16 uType;
   unsigned __int16 uObjectDescID;
   struct Vec3_int_ vPosition;
   struct Vec3_short_ vVelocity;
@@ -38,7 +226,7 @@
   unsigned __int16 uSpriteFrameID;
   __int16 field_20;
   __int16 field_22_glow_radius_multiplier;
-  struct ItemGen stru_24;
+  struct ItemGen containing_item;
   int spell_id;
   int spell_level;
   int spell_skill;
@@ -58,5 +246,5 @@
 extern size_t uNumSpriteObjects;
 extern std::array<SpriteObject, MAX_SPRITE_OBJECTS> pSpriteObjects;
 
-bool __fastcall _46BFFA_check_object_intercept(unsigned int uLayingItemID, signed int a2);
+bool __fastcall _46BFFA_update_spell_fx(unsigned int uLayingItemID, signed int a2);
 void __fastcall sub_43A97E(unsigned int uLayingItemID, signed int a2); // idb
--- a/Engine/Party.cpp	Wed May 20 15:12:33 2015 +0200
+++ b/Engine/Party.cpp	Wed May 20 21:05:07 2015 +0200
@@ -348,10 +348,10 @@
   this->pPlayers[3].uIntelligence = 30;
   this->pPlayers[3].uWillpower = 9;
   this->pPlayers[3].uLuck = 7;
-  this->pPlayers[3].pActiveSkills[PLAYER_SKILL_LEATHER] = 1;         // leather
-  this->pPlayers[3].pActiveSkills[PLAYER_SKILL_AIR] = 1;        // air
-  this->pPlayers[3].pActiveSkills[PLAYER_SKILL_FIRE] = 1;        // fire
-  this->pPlayers[3].pActiveSkills[PLAYER_SKILL_STAFF] = 1;         // staff
+  this->pPlayers[3].pActiveSkills[PLAYER_SKILL_LEATHER] = 1;
+  this->pPlayers[3].pActiveSkills[PLAYER_SKILL_AIR] = 1;
+  this->pPlayers[3].pActiveSkills[PLAYER_SKILL_FIRE] = 1;
+  this->pPlayers[3].pActiveSkills[PLAYER_SKILL_STAFF] = 1;
 
   for (uNumPlayers = 0; uNumPlayers < 4; uNumPlayers++)
   {
@@ -1063,7 +1063,7 @@
     {
       v5 = pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID;
       v6 = 0;
-      a1.uType = pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID;
+      a1.uType = (SPRITE_OBJECT_TYPE)pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID;
       for ( uint i = 0; i < pObjectList->uNumObjects; i++ )
       {
         if ( v5 == pObjectList->pObjects[i].uObjectID )
@@ -1086,7 +1086,7 @@
         pParty->sEyelevel + pParty->vPosition.z);
       a1.uSpriteFrameID = 0;
       a1.uSectorID = v8;
-      memcpy(&a1.stru_24, &pParty->pPickedItem, sizeof(a1.stru_24));
+      memcpy(&a1.containing_item, &pParty->pPickedItem, sizeof(a1.containing_item));
       a1.Create(pParty->sRotationY, 184, 200, 0);
       pMouse->RemoveHoldingItem();
     }
--- a/Engine/Spells/CastSpellInfo.cpp	Wed May 20 15:12:33 2015 +0200
+++ b/Engine/Spells/CastSpellInfo.cpp	Wed May 20 21:05:07 2015 +0200
@@ -138,7 +138,7 @@
     if (pParty->Invisible())
       pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].Reset();
 
-    if ( pCastSpell->uFlags & 0x3CA )
+    if ( pCastSpell->uFlags & ON_CAST_CastingInProgress )
     {
       if ( !pParty->pPlayers[pCastSpell->uPlayerID].CanAct() )
         _427D48();
@@ -163,8 +163,8 @@
     }
 
 
-    pSpellSprite.uType = stru_4E3ACC[pCastSpell->uSpellID].uType;
-    if (pSpellSprite.uType)
+    pSpellSprite.uType = spell_sprite_mapping[pCastSpell->uSpellID].uSpriteType;
+    if (pSpellSprite.uType != SPRITE_NULL)
     {
       if (PID_TYPE(a2) == OBJECT_Actor)
       {
@@ -267,7 +267,7 @@
         if ( SkillToMastery(pPlayer->pActiveSkills[PLAYER_SKILL_BOW]) >= 3 )
           amount = 2;
         sRecoveryTime = pPlayer->GetAttackRecoveryTime(true);
-        pSpellSprite.stru_24.Reset();
+        pSpellSprite.containing_item.Reset();
         pSpellSprite.spell_level = spell_level;
         pSpellSprite.spell_id = pCastSpell->uSpellID;
         pSpellSprite.spell_skill = skill_level;
@@ -285,7 +285,7 @@
         pSpellSprite.uFacing = LOWORD(v715.uYawAngle);
         pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
         pPlayer = &pParty->pPlayers[pCastSpell->uPlayerID];
-        memcpy(&pSpellSprite.stru_24, &pPlayer->pInventoryItemList[pPlayer->pEquipment.uBow-1], sizeof(pSpellSprite.stru_24));
+        memcpy(&pSpellSprite.containing_item, &pPlayer->pInventoryItemList[pPlayer->pEquipment.uBow - 1], sizeof(pSpellSprite.containing_item));
         pSpellSprite.uAttributes = 256;
         if ( pParty->bTurnBasedModeOn == 1 )
           pSpellSprite.uAttributes = 260;
@@ -303,7 +303,7 @@
       case SPELL_LASER_PROJECTILE://ñòðåëüáà èç áëàñòåðà
       {
         sRecoveryTime = pPlayer->GetAttackRecoveryTime(0);
-        pSpellSprite.stru_24.Reset();
+        pSpellSprite.containing_item.Reset();
         pSpellSprite.spell_id = pCastSpell->uSpellID;
         pSpellSprite.spell_level = v723;
         pSpellSprite.spell_skill = skill_level;
@@ -319,7 +319,7 @@
         pSpellSprite.uFacing = LOWORD(v715.uYawAngle);
         pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
         pPlayer = &pParty->pPlayers[pCastSpell->uPlayerID];
-        memcpy(&pSpellSprite.stru_24, &pPlayer->pInventoryItemList[pPlayer->pEquipment.uMainHand - 1],sizeof(pSpellSprite.stru_24));
+        memcpy(&pSpellSprite.containing_item, &pPlayer->pInventoryItemList[pPlayer->pEquipment.uMainHand - 1], sizeof(pSpellSprite.containing_item));
         //	&pParty->pPlayers[pCastSpell->uPlayerID].spellbook.pDarkSpellbook.bIsSpellAvailable[36
         //		* pParty->pPlayers[pCastSpell->uPlayerID].pEquipment.uMainHand + 5], );
         pSpellSprite.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pSpellSprite.vPosition.z);
@@ -375,7 +375,7 @@
         }
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           break;
-        pSpellSprite.stru_24.Reset();
+        pSpellSprite.containing_item.Reset();
         pSpellSprite.spell_id = pCastSpell->uSpellID;
         pSpellSprite.spell_level = spell_level;
         pSpellSprite.spell_skill = skill_level;
@@ -416,7 +416,7 @@
           v697.x = 0;
           v697.y = 0;
           v697.z = 0;
-          pSpellSprite.stru_24.Reset();
+          pSpellSprite.containing_item.Reset();
           pSpellSprite.spell_id = pCastSpell->uSpellID;
           pSpellSprite.spell_level = spell_level;
           pSpellSprite.spell_skill = skill_level;
@@ -448,7 +448,7 @@
           v704.x = 0;
           v704.y = 0;
           v704.z = 0;
-          pSpellSprite.stru_24.Reset();
+          pSpellSprite.containing_item.Reset();
           pSpellSprite.spell_id = pCastSpell->uSpellID;
           pSpellSprite.spell_level = spell_level;
           pSpellSprite.spell_skill = skill_level;
@@ -478,7 +478,7 @@
         v691.x = 0;
         v691.y = 0;
         v691.z = 0;
-        pSpellSprite.stru_24.Reset();
+        pSpellSprite.containing_item.Reset();
         pSpellSprite.spell_id = pCastSpell->uSpellID;
         pSpellSprite.spell_level = spell_level;
         pSpellSprite.spell_skill = skill_level;
@@ -523,15 +523,15 @@
       {
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           break;
-        pSpellSprite.stru_24.Reset();
+        pSpellSprite.containing_item.Reset();
         pSpellSprite.spell_id = pCastSpell->uSpellID;
         pSpellSprite.spell_level = spell_level;
         pSpellSprite.spell_skill = skill_level;
         pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
         pSpellSprite.vPosition.y = pParty->vPosition.y;
         pSpellSprite.vPosition.x = pParty->vPosition.x;
+        pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
         pSpellSprite.uAttributes = 0;
-        pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
         if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
           pSpellSprite.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3);
         else
@@ -559,7 +559,7 @@
       {
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           break;
-        pSpellSprite.stru_24.Reset();
+        pSpellSprite.containing_item.Reset();
         pSpellSprite.spell_id = pCastSpell->uSpellID;
         pSpellSprite.spell_level = spell_level;
         pSpellSprite.spell_skill = skill_level;
@@ -595,7 +595,7 @@
         }
         if ( pPlayer->CanCastSpell(uRequiredMana) )
         {
-          pSpellSprite.stru_24.Reset();
+            pSpellSprite.containing_item.Reset();
           pSpellSprite.spell_id = pCastSpell->uSpellID;
           pSpellSprite.spell_skill = skill_level;
           pSpellSprite.spell_level = spell_level;
@@ -677,7 +677,7 @@
           pActors[v61].pActorBuffs[ACTOR_BUFF_BERSERK].Reset();
           pActors[v61].pActorBuffs[ACTOR_BUFF_ENSLAVED].Reset();
           pActors[v61].pActorBuffs[ACTOR_BUFF_CHARM].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)(power << 7) * 0.033333335), skill_level, 0, 0, 0);
-          pSpellSprite.stru_24.Reset();
+          pSpellSprite.containing_item.Reset();
           pSpellSprite.spell_id = pCastSpell->uSpellID;
           pSpellSprite.spell_level = spell_level;
           pSpellSprite.spell_skill = skill_level;
@@ -703,7 +703,7 @@
       {
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           break;
-        pSpellSprite.stru_24.Reset();
+        pSpellSprite.containing_item.Reset();
         pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
         pSpellSprite.vPosition.x = pParty->vPosition.x;
         pSpellSprite.vPosition.y = pParty->vPosition.y;
@@ -915,7 +915,7 @@
             v701.x = 0;
             v701.y = 0;
             v701.z = 0;
-            pSpellSprite.stru_24.Reset();
+            pSpellSprite.containing_item.Reset();
             pSpellSprite.spell_id = pCastSpell->uSpellID;
             pSpellSprite.spell_level = v723;
             pSpellSprite.spell_skill = skill_level;
@@ -1052,7 +1052,7 @@
               HIDWORD(v687) = stru_5C6E00->Atan2((signed __int64)sqrt((float)(j * j + k * k)), (double)a2 - 2500);
               LODWORD(v687) = stru_5C6E00->Atan2(j, k);
             }
-            pSpellSprite.stru_24.Reset();
+            pSpellSprite.containing_item.Reset();
             pSpellSprite.spell_id = pCastSpell->uSpellID;
             pSpellSprite.spell_level = spell_level;
             pSpellSprite.spell_skill = skill_level;
@@ -1094,7 +1094,7 @@
         v700.x = 0;
         v700.y = 0;
         v700.z = 0;
-        pSpellSprite.stru_24.Reset();
+        pSpellSprite.containing_item.Reset();
         pSpellSprite.spell_id = pCastSpell->uSpellID;
         pSpellSprite.spell_level = spell_level;
         pSpellSprite.spell_skill = skill_level;
@@ -1113,7 +1113,7 @@
           pSpellSprite.vPosition.z = pActors[_50BF30_actors_in_viewport_ids[i]].vPosition.z - (unsigned int)(signed __int64)((double)pActors[_50BF30_actors_in_viewport_ids[i]].uActorHeight * -0.8);
           pSpellSprite.spell_target_pid = PID(OBJECT_Actor, _50BF30_actors_in_viewport_ids[i]);
           Actor::DamageMonsterFromParty(PID(OBJECT_Item, pSpellSprite.Create(0, 0, 0, 0)), _50BF30_actors_in_viewport_ids[i], &v700);
-          pEngine->GetStru6()->_4A81CA(&pSpellSprite);
+          pEngine->GetStru6()->RenderAsSprite(&pSpellSprite);
           pEngine->GetStru6()->FadeScreen__like_Turn_Undead_and_mb_Armageddon(0xFF3C1E, 0x40);
         }
         spell_sound_flag = true;
@@ -1169,7 +1169,7 @@
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           break;
         int _v726 = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360;
-        pSpellSprite.stru_24.Reset();
+        pSpellSprite.containing_item.Reset();
         pSpellSprite.spell_id = pCastSpell->uSpellID;
         pSpellSprite.spell_level = spell_level;
         pSpellSprite.spell_skill = skill_level;
@@ -1318,7 +1318,7 @@
             HIDWORD(v685) = stru_5C6E00->Atan2((signed __int64)sqrt((float)(j * j + k * k)), ((double)a2 + (double)dist_Z - (double)(dist_Z + 2500)));
             LODWORD(v685) = stru_5C6E00->Atan2(j, k);
           }
-          pSpellSprite.stru_24.Reset();
+          pSpellSprite.containing_item.Reset();
           pSpellSprite.spell_id = pCastSpell->uSpellID;
           pSpellSprite.spell_level = spell_level;
           pSpellSprite.spell_skill = skill_level;
@@ -1394,7 +1394,7 @@
         signed int _v733 = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360;
         if ( amount == 1 )
         {
-          pSpellSprite.stru_24.Reset();
+            pSpellSprite.containing_item.Reset();
           pSpellSprite.spell_id = pCastSpell->uSpellID;
           pSpellSprite.spell_skill = skill_level;
           pSpellSprite.spell_level = spell_level;
@@ -1418,7 +1418,7 @@
         }
         else
         {
-          pSpellSprite.stru_24.Reset();
+            pSpellSprite.containing_item.Reset();
           pSpellSprite.spell_id = pCastSpell->uSpellID;
           pSpellSprite.spell_level = spell_level;
           pSpellSprite.spell_skill = skill_level;
@@ -1726,7 +1726,7 @@
           ::sRecoveryTime = sRecoveryTime;
           lloyds_beacon_sound_id = pCastSpell->sound_id;
           lloyds_beacon_spell_id = pCastSpell->uSpellID;
-          pCastSpell->uFlags |= 0x20u;
+          pCastSpell->uFlags |= ON_CAST_NoRecoverySpell;
         }
         break;
       }
@@ -1761,7 +1761,7 @@
       {
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           break;
-        pSpellSprite.stru_24.Reset();
+        pSpellSprite.containing_item.Reset();
         pSpellSprite.spell_id = pCastSpell->uSpellID;
         pSpellSprite.spell_level = spell_level;
         pSpellSprite.spell_skill = skill_level;
@@ -1797,8 +1797,8 @@
         }
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           break;
-        pSpellSprite.uType = 4090;
-        pSpellSprite.stru_24.Reset();
+        pSpellSprite.uType = SPRITE_SPELL_EARTH_DEATH_BLOSSOM;
+        pSpellSprite.containing_item.Reset();
         pSpellSprite.spell_id = pCastSpell->uSpellID;
         pSpellSprite.spell_level = spell_level;
         pSpellSprite.spell_skill = skill_level;
@@ -1945,8 +1945,9 @@
           break;
         int mon_num = pRenderer->_46À6ÀÑ_GetActorsInViewport(4096);
         pEngine->GetStru6()->FadeScreen__like_Turn_Undead_and_mb_Armageddon(0xFFFFFF, 192);
-        ++pSpellSprite.uType;
-        pSpellSprite.stru_24.Reset();
+        //++pSpellSprite.uType;
+        pSpellSprite.uType = SPRITE_SPELL_SPIRIT_TURN_UNDEAD_1;
+        pSpellSprite.containing_item.Reset();
         pSpellSprite.spell_id = pCastSpell->uSpellID;
         pSpellSprite.spell_level = spell_level;
         pSpellSprite.spell_skill = skill_level;
@@ -2183,7 +2184,7 @@
             }
           }
           ShowStatusBarString(pTmpBuf2.data(), 2);
-          pSpellSprite.stru_24.Reset();
+          pSpellSprite.containing_item.Reset();
           pSpellSprite.spell_id = pCastSpell->uSpellID;
           pSpellSprite.spell_level = spell_level;
           pSpellSprite.spell_skill = skill_level;
@@ -2229,7 +2230,7 @@
             pActors[mon_id].pActorBuffs[ACTOR_BUFF_BERSERK].Apply(pParty->uTimePlayed + (signed __int64)((double)(amount << 7) * 0.033333335), skill_level, 0, 0, 0);
             pActors[mon_id].pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Long;
           }
-          pSpellSprite.stru_24.Reset();
+          pSpellSprite.containing_item.Reset();
           pSpellSprite.spell_id = pCastSpell->uSpellID;
           pSpellSprite.spell_level = spell_level;
           pSpellSprite.spell_skill = skill_level;
@@ -2269,7 +2270,7 @@
             pActors[mon_id].pActorBuffs[ACTOR_BUFF_ENSLAVED].Apply(pParty->uTimePlayed + (signed __int64)((double)(amount << 7) * 0.033333335),
                 skill_level, 0, 0, 0);
           }
-          pSpellSprite.stru_24.Reset();
+          pSpellSprite.containing_item.Reset();
           pSpellSprite.spell_id = pCastSpell->uSpellID;
           pSpellSprite.spell_level = spell_level;
           pSpellSprite.spell_skill = skill_level;
@@ -2301,8 +2302,9 @@
           break;
         int mon_num = pRenderer->_46À6ÀÑ_GetActorsInViewport(4096);
         pEngine->GetStru6()->FadeScreen__like_Turn_Undead_and_mb_Armageddon(0xA0A0A, 192);
-        ++pSpellSprite.uType;
-        pSpellSprite.stru_24.Reset();
+        //++pSpellSprite.uType;
+        pSpellSprite.uType = SPRITE_SPELL_MIND_MASS_FEAR_1;
+        pSpellSprite.containing_item.Reset();
         pSpellSprite.spell_id = pCastSpell->uSpellID;
         pSpellSprite.spell_level = spell_level;
         pSpellSprite.spell_skill = skill_level;
@@ -2371,17 +2373,17 @@
         int obj_id = PID_ID(a2);
         if (PID_TYPE(a2) == OBJECT_Item)
         {
-          if ( pItemsTable->pItems[pSpriteObjects[obj_id].stru_24.uItemID].uEquipType == EQUIP_GOLD )
+            if (pItemsTable->pItems[pSpriteObjects[obj_id].containing_item.uItemID].uEquipType == EQUIP_GOLD)
           {
-            pParty->PartyFindsGold(pSpriteObjects[obj_id].stru_24.uSpecEnchantmentType, 0);
+              pParty->PartyFindsGold(pSpriteObjects[obj_id].containing_item.uSpecEnchantmentType, 0);
             viewparams->bRedrawGameUI = true;
           }
           else
           {
-            sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[471], pItemsTable->pItems[pSpriteObjects[obj_id].stru_24.uItemID].pUnidentifiedName);//Âû íàøëè ^Pv[%s]!
+              sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[471], pItemsTable->pItems[pSpriteObjects[obj_id].containing_item.uItemID].pUnidentifiedName);//Âû íàøëè ^Pv[%s]!
             ShowStatusBarString(pTmpBuf2.data(), 2);
-            if ( !pParty->AddItemToParty(&pSpriteObjects[obj_id].stru_24) )
-              pParty->SetHoldingItem(&pSpriteObjects[obj_id].stru_24);
+            if (!pParty->AddItemToParty(&pSpriteObjects[obj_id].containing_item))
+                pParty->SetHoldingItem(&pSpriteObjects[obj_id].containing_item);
           }
           SpriteObject::OnInteraction(obj_id);
         }
@@ -2392,7 +2394,7 @@
           OpenedTelekinesis = true;
           if ( pLevelDecorations[obj_id].uEventID )
             EventProcessor(pLevelDecorations[obj_id].uEventID, a2, 1);
-          if ( pLevelDecorations[pSpriteObjects[obj_id].stru_24.uItemID].IsInteractive() )
+          if (pLevelDecorations[pSpriteObjects[obj_id].containing_item.uItemID].IsInteractive())
           {
             activeLevelDecoration = &pLevelDecorations[obj_id];
             EventProcessor(stru_5E4C90_MapPersistVars._decor_events[pLevelDecorations[obj_id]._idx_in_stru123 - 75] + 380, 0, 1);
@@ -2587,11 +2589,12 @@
           break;
         pEngine->GetStru6()->FadeScreen__like_Turn_Undead_and_mb_Armageddon(0xAFF0A, 192);
         int mon_num = pRenderer->_46À6ÀÑ_GetActorsInViewport(4096);
-        ++pSpellSprite.uType;
+        //++pSpellSprite.uType;
+        pSpellSprite.uType = SPRITE_SPELL_LIGHT_DISPEL_MAGIC_1;
         v688.x = 0;
         v688.y = 0;
         v688.z = 0;
-        pSpellSprite.stru_24.Reset();
+        pSpellSprite.containing_item.Reset();
         pSpellSprite.spell_id = pCastSpell->uSpellID;
         pSpellSprite.spell_level = spell_level;
         pSpellSprite.spell_skill = skill_level;
@@ -2691,11 +2694,12 @@
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           break;
         int mon_num = pRenderer->_46À6ÀÑ_GetActorsInViewport(4096);
-        ++pSpellSprite.uType;
+        //++pSpellSprite.uType;
+        pSpellSprite.uType = SPRITE_SPELL_LIGHT_PRISMATIC_LIGHT_1;
         v694.x = 0;
         v694.y = 0;
         v694.z = 0;
-        pSpellSprite.stru_24.Reset();
+        pSpellSprite.containing_item.Reset();
         pSpellSprite.spell_id = pCastSpell->uSpellID;
         pSpellSprite.spell_level = spell_level;
         pSpellSprite.spell_skill = skill_level;
@@ -2863,8 +2867,9 @@
           pCastSpell->uSpellID = 0;
           continue;
         }
-        ++pSpellSprite.uType;
-        pSpellSprite.stru_24.Reset();
+        //++pSpellSprite.uType;
+        pSpellSprite.uType = SPRITE_SPELL_DARK_REANIMATE_1;
+        pSpellSprite.containing_item.Reset();
         pSpellSprite.spell_id = pCastSpell->uSpellID;
         pSpellSprite.spell_level = spell_level;
         pSpellSprite.spell_skill = skill_level;
@@ -2955,7 +2960,7 @@
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           break;
         signed int _v726 = ((signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360);
-        pSpellSprite.stru_24.Reset();
+        pSpellSprite.containing_item.Reset();
         pSpellSprite.spell_id = pCastSpell->uSpellID;
         pSpellSprite.spell_level = spell_level;
         pSpellSprite.spell_skill = skill_level;
@@ -3020,7 +3025,7 @@
           pActors[mon_id].pActorBuffs[ACTOR_BUFF_CHARM].Reset();
           pActors[mon_id].pActorBuffs[ACTOR_BUFF_ENSLAVED].Apply(pParty->uTimePlayed + 
                            (signed __int64)((double)(signed int)((int)duration << 7) * 0.033333335), skill_level, 0, 0, 0);
-          pSpellSprite.stru_24.Reset();
+          pSpellSprite.containing_item.Reset();
           pSpellSprite.spell_id = pCastSpell->uSpellID;
           pSpellSprite.spell_level = spell_level;
           pSpellSprite.spell_skill = skill_level;
@@ -3135,7 +3140,7 @@
         v707.x = 0;
         v707.y = 0;
         v707.z = 0;
-        pSpellSprite.stru_24.Reset();
+        pSpellSprite.containing_item.Reset();
         pSpellSprite.spell_id = pCastSpell->uSpellID;
         pSpellSprite.spell_level = spell_level;
         pSpellSprite.spell_skill = skill_level;
@@ -3215,7 +3220,7 @@
           v642 = rand() % 4096 - 2048;
           v643 = rand();
           v732 = GetTerrainHeightsAroundParty2(v642 + pParty->vPosition.x, pParty->vPosition.y + (v643 % 4096 - 2048), &v710, 0);
-          SpriteObject::sub_42F7EB_DropItemAt(4070, v642 + pParty->vPosition.x, pParty->vPosition.y + (v643 % 4096 - 2048), v732 + 16, rand() % 500 + 500, 1, 0, 0, 0);
+          SpriteObject::sub_42F7EB_DropItemAt(SPRITE_SPELL_EARTH_ROCK_BLAST, v642 + pParty->vPosition.x, pParty->vPosition.y + (v643 % 4096 - 2048), v732 + 16, rand() % 500 + 500, 1, 0, 0, 0);
         }
         spell_sound_flag = true;
         break;
@@ -3223,12 +3228,8 @@
       default:
         break;
     }
-    if ( pCastSpell->uFlags & 0x20 )
-    {
-      if ( spell_sound_flag )
-        pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[pCastSpell->uSpellID], 0, 0, -1, 0, pCastSpell->sound_id, 0, 0);
-    }
-    else
+
+    if (~pCastSpell->uFlags & ON_CAST_NoRecoverySpell)
     {
       if ( sRecoveryTime < 0 )
         sRecoveryTime = 0;
@@ -3241,23 +3242,24 @@
           pTurnEngine->ApplyPlayerAction();
       }
       else
-        pPlayer->SetRecoveryTime((signed __int64)(flt_6BE3A4_debug_recmod1 * (double)sRecoveryTime * 2.133333333333333));
-      if ( spell_sound_flag )
-      {
-        pPlayer->PlaySound(SPEECH_49, 0);
-        //if ( spell_sound_flag )
-          pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[pCastSpell->uSpellID], 0, 0, -1, 0, pCastSpell->sound_id, 0,	0);
-      }
+          pPlayer->SetRecoveryTime((signed __int64)(flt_6BE3A4_debug_recmod1 * (double)sRecoveryTime * 2.133333333333333));
+      pPlayer->PlaySound(SPEECH_49, 0);
     }
+    if (spell_sound_flag)
+        pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[pCastSpell->uSpellID], 0, 0, -1, 0, pCastSpell->sound_id, 0, 0);
+
     pCastSpell->uSpellID = 0;
     spell_level = v723;
     continue;
   }
   
 }
+
+
 //----- (00427DA0) --------------------------------------------------------
 size_t PushCastSpellInfo(uint16_t uSpellID, uint16_t uPlayerID, __int16 skill_level, uint16_t uFlags, int spell_sound_id)
 {
+    // uFlags: ON_CAST_*
   for (size_t i = 0; i < CastSpellInfoCount; i++)
   {
     if (!pCastSpellInfo[i].uSpellID)
@@ -3281,7 +3283,7 @@
 {
   for (size_t i = 0; i < CastSpellInfoCount; i++)
   {
-    if (pCastSpellInfo[i].uSpellID && pCastSpellInfo[i].uFlags & 0x3CA)
+    if (pCastSpellInfo[i].uSpellID && pCastSpellInfo[i].uFlags & ON_CAST_CastingInProgress)
     {
       pCastSpellInfo[i].uSpellID = 0;
       pGUIWindow_CastTargetedSpell->Release();
@@ -3294,7 +3296,7 @@
   }
 }
 //----- (0042777D) --------------------------------------------------------
-void _42777D_CastSpell_UseWand_ShootArrow(int a1, unsigned int uPlayerID, unsigned int a4, __int16 a5, int a6)
+void _42777D_CastSpell_UseWand_ShootArrow(SPELL_TYPE spell, unsigned int uPlayerID, unsigned int a4, __int16 flags, int a6)
 {
   unsigned __int16 v9; // cx@16
   unsigned int v10; // eax@18
@@ -3316,23 +3318,22 @@
     //v7 = &pParty->pPlayers[uPlayerID];
   assert(uPlayerID < 4);
   Player* player = &pParty->pPlayers[uPlayerID];
-    if ( !(a5 & 0x10) )
+  if (!(flags & 0x10))
     {
-      switch ( a1 )
+      switch (spell)
       {
         case SPELL_SPIRIT_FATE:
         case SPELL_BODY_FIRST_AID:
         case SPELL_DARK_REANIMATE:
           //HIBYTE(v6) = HIBYTE(a5) | 1;
-          a5 |= 0x0100;
+            flags |= ON_CAST_MonsterSparkles;
           break;
 
         case SPELL_FIRE_FIRE_AURA:
         case SPELL_WATER_RECHARGE_ITEM:
         case SPELL_WATER_ENCHANT_ITEM:
         case SPELL_DARK_VAMPIRIC_WEAPON:
-          //LOBYTE(v6) = a5 | 0x80;
-          a5 |= 0x0080;
+            flags |= ON_CAST_Enchantment;
           break;
 
         case SPELL_FIRE_FIRE_BOLT:
@@ -3363,33 +3364,29 @@
         case SPELL_DARK_SHARPMETAL:
         case SPELL_DARK_DRAGON_BREATH:
           if ( !a6 )
-            a5 |= 0x0008;
+              flags |= ON_CAST_TargetCrosshair;
           break;
         case SPELL_MIND_TELEPATHY:
         case SPELL_MIND_BERSERK:
         case SPELL_MIND_ENSLAVE:
         case SPELL_LIGHT_PARALYZE:
         case SPELL_DARK_CONTROL_UNDEAD:
-//LABEL_9:
-          //v6 = a5 | 8;
-          a5 |= 0x0008;
+            flags |= ON_CAST_TargetCrosshair;
           break;
 
         case SPELL_EARTH_TELEKINESIS:
-          a5 |= 0x0040;
+            flags |= ON_CAST_Telekenesis;
           break;
 
         case SPELL_SPIRIT_BLESS:
           if (a4 && ~a4 & 0x01C0)
-            //goto LABEL_25;
           {
-            a5 |= 0x0002;
+              flags |= ON_CAST_WholeParty_BigImprovementAnim;
             break;
           }
           else if ((player->pActiveSkills[PLAYER_SKILL_SPIRIT] & 0x1C0) == 0)
-            //goto LABEL_25;
           {
-            a5 |= 0x0002;
+              flags |= ON_CAST_WholeParty_BigImprovementAnim;
             break;
           }
           break;
@@ -3405,7 +3402,7 @@
           //goto LABEL_24;
           if ( v11 ^ v12 )
           {
-            a5 |= 0x0002;
+              flags |= ON_CAST_WholeParty_BigImprovementAnim;
             break;
           }
           break;
@@ -3421,7 +3418,7 @@
           //goto LABEL_24;
           if ( v11 ^ v12 )
           {
-            a5 |= 0x0002;
+              flags |= ON_CAST_WholeParty_BigImprovementAnim;
             break;
           }
           break;
@@ -3437,7 +3434,7 @@
           if ( v11 ^ v12 )
             //goto LABEL_25;
           {
-            a5 |= 0x0002;
+              flags |= ON_CAST_WholeParty_BigImprovementAnim;
             break;
           }
           break;
@@ -3453,53 +3450,34 @@
         case SPELL_BODY_REGENERATION:
         case SPELL_BODY_CURE_POISON:
         case SPELL_BODY_CURE_DISEASE:
-//LABEL_25:
-          //v6 = a5 | 2;
-          a5 |= 0x0002;
+            flags |= ON_CAST_WholeParty_BigImprovementAnim;
           break;
 
         case SPELL_DARK_SACRIFICE:
-          //HIBYTE(v6) = HIBYTE(a5) | 2;
-          a5 |= 0x0200;
+            flags |= ON_CAST_DarkSacrifice;
           break;
         default:
           break;
       }
     }
 
-
-    if (a5 & 0x3CA)
+    // clear previous casts
+    if (flags & ON_CAST_CastingInProgress)
     {
       for (uint i = 0; i < CastSpellInfoCount; ++i)
-        if (pCastSpellInfo[i].uFlags & 0x3CA)
+          if (pCastSpellInfo[i].uFlags & ON_CAST_CastingInProgress)
         {
           pCastSpellInfo[i].uSpellID = 0;
           break;
         }
     }
       
-    for (uint i = 0; i < CastSpellInfoCount; ++i)
-    {
-      CastSpellInfo* spell = &pCastSpellInfo[i];
-      if (!spell->uSpellID)
-        continue;
+    CastSpellInfoHelpers::_427D48();
 
-      spell->uSpellID = 0;
-      if (spell->uFlags & 0x3CA)
-      {
-        pGUIWindow_CastTargetedSpell->Release();
-        pGUIWindow_CastTargetedSpell = nullptr;
-        pMouse->SetCursorBitmap("MICON1");
-        GameUI_Footer_TimeLeft = 0;
-        _50C9A0_IsEnchantingInProgress = 0;
-        back_to_game();
-      }
-    }
-
-    int result = PushCastSpellInfo(a1, uPlayerID, a4, a5, a6);
+    int result = PushCastSpellInfo(spell, uPlayerID, a4, flags, a6);
     if ( result != -1 )
     {
-      if ( a5 & 2 )
+        if (flags & ON_CAST_WholeParty_BigImprovementAnim)
       {
         if ( pGUIWindow_CastTargetedSpell )
           return;
@@ -3511,7 +3489,7 @@
         pParty->sub_421B2C_PlaceInInventory_or_DropPickedItem();
         return;
       }
-      if ( a5 & 8 )
+        if (flags & ON_CAST_TargetCrosshair)
       {
         if ( pGUIWindow_CastTargetedSpell )
           return;
@@ -3521,7 +3499,7 @@
         pParty->sub_421B2C_PlaceInInventory_or_DropPickedItem();
         return;
       }
-      if ( a5 & 0x40 )
+        if (flags & ON_CAST_Telekenesis)
       {
         if ( pGUIWindow_CastTargetedSpell )
           return;
@@ -3531,7 +3509,7 @@
         pParty->sub_421B2C_PlaceInInventory_or_DropPickedItem();
         return;
       }
-      if ( (char)a5 < 0 )
+        if (flags & ON_CAST_Enchantment)
       {
         if ( pGUIWindow_CastTargetedSpell )
           return;
@@ -3544,7 +3522,7 @@
         pParty->sub_421B2C_PlaceInInventory_or_DropPickedItem();
         return;
       }
-      if ( HIBYTE(a5) & 1 )
+        if (flags & ON_CAST_MonsterSparkles)
       {
         if ( pGUIWindow_CastTargetedSpell )
           return;
@@ -3556,7 +3534,7 @@
         pGUIWindow_CastTargetedSpell->CreateButton(8, 8, game_viewport_width, game_viewport_height, 1, 0, UIMSG_CastSpell_Monster_Improvement, 0, 0, "", NULL);
         pParty->sub_421B2C_PlaceInInventory_or_DropPickedItem();
       }
-      if ( HIBYTE(a5) & 2 && !pGUIWindow_CastTargetedSpell )
+        if (flags & ON_CAST_DarkSacrifice && !pGUIWindow_CastTargetedSpell)
       {
           pGUIWindow_CastTargetedSpell = new OnCastTargetedSpell(0, 0, window->GetWidth(), window->GetHeight(), (int)&pCastSpellInfo[result], 0);
         pBtn_NPCLeft = pGUIWindow_CastTargetedSpell->CreateButton(469, 178,
--- a/Engine/Spells/CastSpellInfo.h	Wed May 20 15:12:33 2015 +0200
+++ b/Engine/Spells/CastSpellInfo.h	Wed May 20 21:05:07 2015 +0200
@@ -1,8 +1,9 @@
 #pragma once
 
 #include <cstdint>
+#include <array>
 
-#include <array>
+#include "Spells.h"
 
 namespace CastSpellInfoHelpers
 {
@@ -33,4 +34,14 @@
 };
 #pragma pack(pop)
 
-void _42777D_CastSpell_UseWand_ShootArrow(int a1, unsigned int uPlayerID, unsigned int a4, __int16 a5, int a6);
\ No newline at end of file
+
+// flags
+#define ON_CAST_WholeParty_BigImprovementAnim 0x0002
+#define ON_CAST_TargetCrosshair               0x0008
+#define ON_CAST_NoRecoverySpell           0x0020
+#define ON_CAST_Telekenesis                   0x0040
+#define ON_CAST_Enchantment                   0x0080
+#define ON_CAST_MonsterSparkles               0x0100
+#define ON_CAST_DarkSacrifice                 0x0200
+#define ON_CAST_CastingInProgress (ON_CAST_WholeParty_BigImprovementAnim | ON_CAST_TargetCrosshair | ON_CAST_Telekenesis | ON_CAST_Enchantment | ON_CAST_MonsterSparkles | ON_CAST_DarkSacrifice)
+void _42777D_CastSpell_UseWand_ShootArrow(SPELL_TYPE spell, unsigned int uPlayerID, unsigned int a4, __int16 flags, int a6);
\ No newline at end of file
--- a/Engine/Spells/Spells.cpp	Wed May 20 15:12:33 2015 +0200
+++ b/Engine/Spells/Spells.cpp	Wed May 20 21:05:07 2015 +0200
@@ -22,7 +22,7 @@
 #include "stru6.h"
 
 
-std::array<TownPortalData, 6> TownPortalList = //4ECBB8
+std::array<TownPortalData, 6> TownPortalList = // 4ECBB8
 {{
  {Vec3_int_(-5121, 2107, 1), 1536, 0, 21, 0},
  {Vec3_int_(-15148, -10240, 1473), 0, 0, 4, 0},
@@ -32,24 +32,123 @@
  {Vec3_int_(-1837, -4247, 65), 65, 0, 8, 0}
 }} ;
 
-struct SpellStats *pSpellStats;
+struct SpellStats *pSpellStats = nullptr;
 
 
-std::array<stru324_spell, 103> stru_4E3ACC =
+std::array<stru324_spell_id_to_sprite_mapping, 103> spell_sprite_mapping = // 4E3ACC
 {{
-  {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}
+        { SPRITE_SPELL_0, 0 },
+        { SPRITE_SPELL_FIRE_TORCH_LIGHT, 0 },
+        { SPRITE_SPELL_FIRE_FIRE_BOLT, 0 },
+        { SPRITE_SPELL_FIRE_PROTECTION_FROM_FIRE, 0 },
+        { SPRITE_SPELL_FIRE_FIRE_AURA, 0 },
+        { SPRITE_SPELL_FIRE_HASTE, 0 },
+        { SPRITE_SPELL_FIRE_FIREBALL, 0 },
+        { SPRITE_SPELL_FIRE_FIRE_SPIKE, 0 },
+        { SPRITE_SPELL_FIRE_IMMOLATION, 0 },
+        { SPRITE_SPELL_FIRE_METEOR_SHOWER, 0 },
+        { SPRITE_SPELL_FIRE_INFERNO, 0 },
+        { SPRITE_SPELL_FIRE_INCINERATE, 0 },
+
+        { SPRITE_SPELL_AIR_WIZARD_EYE, 0 },
+        { SPRITE_SPELL_AIR_FEATHER_FALL, 0 },
+        { SPRITE_SPELL_AIR_PROTECTION_FROM_AIR, 0 },
+        { SPRITE_SPELL_AIR_SPARKS, 0 },
+        { SPRITE_SPELL_AIR_JUMP, 0 },
+        { SPRITE_SPELL_AIR_SHIELD, 0 },
+        { SPRITE_SPELL_AIR_LIGHNING_BOLT, 0 },
+        { SPRITE_SPELL_AIR_INVISIBILITY, 0 },
+        { SPRITE_SPELL_AIR_IMPLOSION, 0 },
+        { SPRITE_SPELL_AIR_FLY, 0 },
+        { SPRITE_SPELL_AIR_STARBURST, 0 },
+
+        { SPRITE_SPELL_WATER_AWAKEN, 0 },
+        { SPRITE_SPELL_WATER_POISON_SPRAY, 0 },
+        { SPRITE_SPELL_WATER_PROTECTION_FROM_WATER, 0 },
+        { SPRITE_SPELL_WATER_ICE_BOLT, 0 },
+        { SPRITE_SPELL_WATER_WATER_WALK, 0 },
+        { SPRITE_SPELL_WATER_RECHARGE_ITEM, 0 },
+        { SPRITE_SPELL_WATER_ACID_BURST, 0 },
+        { SPRITE_SPELL_WATER_ENCHANT_ITEM, 0 },
+        { SPRITE_SPELL_WATER_TOWN_PORTAL, 0 },
+        { SPRITE_SPELL_WATER_ICE_BLAST, 0 },
+        { SPRITE_SPELL_WATER_LLOYDS_BEACON, 0 },
+
+        { SPRITE_SPELL_EARTH_STUN, 0 },
+        { SPRITE_SPELL_EARTH_SLOW, 0 },
+        { SPRITE_SPELL_EARTH_PROTECTION_FROM_EARTH, 0 },
+        { SPRITE_SPELL_EARTH_DEADLY_SWARM, 0 },
+        { SPRITE_SPELL_EARTH_STONESKIN, 0 },
+        { SPRITE_SPELL_EARTH_BLADES, 0 },
+        { SPRITE_SPELL_EARTH_STONE_TO_FLESH, 0 },
+        { SPRITE_SPELL_EARTH_ROCK_BLAST, 0 },
+        { SPRITE_SPELL_EARTH_TELEKINESIS, 0 },
+        { SPRITE_SPELL_EARTH_DEATH_BLOSSOM, 0 },
+        { SPRITE_SPELL_EARTH_MASS_DISTORTION, 0 },
+
+        { SPRITE_SPELL_SPIRIT_DETECT_LIFE, 0 },
+        { SPRITE_SPELL_SPIRIT_BLESS, 0 },
+        { SPRITE_SPELL_SPIRIT_FATE, 0 },
+        { SPRITE_SPELL_SPIRIT_TURN_UNDEAD, 0 },
+        { SPRITE_SPELL_SPIRIT_REMOVE_CURSE, 0 },
+        { SPRITE_SPELL_SPIRIT_PRESERVATION, 0 },
+        { SPRITE_SPELL_SPIRIT_HEROISM, 0 },
+        { SPRITE_SPELL_SPIRIT_SPIRIT_LASH, 0 },
+        { SPRITE_SPELL_SPIRIT_RAISE_DEAD, 0 },
+        { SPRITE_SPELL_SPIRIT_SHARED_LIFE, 0 },
+        { SPRITE_SPELL_SPIRIT_RESSURECTION, 0 },
+
+        { SPRITE_SPELL_MIND_REMOVE_FEAR, 0 },
+        { SPRITE_SPELL_MIND_MIND_BLAST, 0 },
+        { SPRITE_SPELL_MIND_PROTECTION_FROM_MIND, 0 },
+        { SPRITE_SPELL_MIND_TELEPATHY, 0 },
+        { SPRITE_SPELL_MIND_CHARM, 0 },
+        { SPRITE_SPELL_MIND_CURE_PARALYSIS, 0 },
+        { SPRITE_SPELL_MIND_BERSERK, 0 },
+        { SPRITE_SPELL_MIND_MASS_FEAR, 0 },
+        { SPRITE_SPELL_MIND_CURE_INSANITY, 0 },
+        { SPRITE_SPELL_MIND_PSYCHIC_SHOCK, 0 },
+        { SPRITE_SPELL_MIND_ENSLAVE, 0 },
+
+        { SPRITE_SPELL_BODY_CURE_WEAKNESS, 0 },
+        { SPRITE_SPELL_BODY_FIRST_AID, 0 },
+        { SPRITE_SPELL_BODY_PROTECTION_FROM_BODY, 0 },
+        { SPRITE_SPELL_BODY_HARM, 0 },
+        { SPRITE_SPELL_BODY_REGENERATION, 0 },
+        { SPRITE_SPELL_BODY_CURE_POISON, 0 },
+        { SPRITE_SPELL_BODY_HAMMERHANDS, 0 },
+        { SPRITE_SPELL_BODY_CURE_DISEASE, 0 },
+        { SPRITE_SPELL_BODY_PROTECTION_FROM_MAGIC, 0 },
+        { SPRITE_SPELL_BODY_FLYING_FIST, 0 },
+        { SPRITE_SPELL_BODY_POWER_CURE, 0 },
+
+        { SPRITE_SPELL_LIGHT_LIGHT_BOLT, 0 },
+        { SPRITE_SPELL_LIGHT_DESTROY_UNDEAD, 0 },
+        { SPRITE_SPELL_LIGHT_DISPEL_MAGIC, 0 },
+        { SPRITE_SPELL_LIGHT_PARALYZE, 0 },
+        { SPRITE_SPELL_LIGHT_SUMMON_ELEMENTAL, 0 },
+        { SPRITE_SPELL_LIGHT_DAY_OF_THE_GODS, 0 },
+        { SPRITE_SPELL_LIGHT_PRISMATIC_LIGHT, 0 },
+        { SPRITE_SPELL_LIGHT_DAY_OF_PROTECTION, 0 },
+        { SPRITE_SPELL_LIGHT_HOUR_OF_POWER, 0 },
+        { SPRITE_SPELL_LIGHT_SUNRAY, 0 },
+        { SPRITE_SPELL_LIGHT_DIVINE_INTERVENTION, 0 },
+
+        { SPRITE_SPELL_DARK_REANIMATE, 0 },
+        { SPRITE_SPELL_DARK_TOXIC_CLOUD, 0 },
+        { SPRITE_SPELL_DARK_VAMPIRIC_WEAPON, 0 },
+        { SPRITE_SPELL_DARK_SHRINKING_RAY, 0 },
+        { SPRITE_SPELL_DARK_SHARPMETAL, 0 },
+        { SPRITE_SPELL_DARK_CONTROL_UNDEAD, 0 },
+        { SPRITE_SPELL_DARK_PAIN_REFLECTION, 0 },
+        { SPRITE_SPELL_DARK_SACRIFICE, 0 },
+        { SPRITE_SPELL_DARK_DRAGON_BREATH, 0 },
+        { SPRITE_SPELL_DARK_ARMAGEDDON, 0 },
+        { SPRITE_SPELL_DARK_SOULDRINKER, 0 },
+
+        { SPRITE_SPELL_BOW_ARROW, 0 },
+        { SPRITE_SPELL_101, 0 },
+        { SPRITE_SPELL_LASER_PROJECTILE, 0 }
 }};
 
 
@@ -183,9 +282,9 @@
 	           SpellData(50, 50, 50, 50, 120, 120, 120, 100, 0, 25, 0),
 	           SpellData(55, 55, 55, 55, 250, 250, 250, 250, 50, 1, 0),
 	           SpellData(60, 60, 60, 60, 300, 300, 300, 300, 25, 8, 0)
-  }};
+}};
 
-std::array<unsigned int, 25> wand_spell_ids =
+std::array<SPELL_TYPE, 25> wand_spell_ids =
 {
 // 135 Wand of Fire               136 Wand of Sparks             137 Wand of Poison             138 Wand of Stunning           139 Wand of Harm
   SPELL_FIRE_FIRE_BOLT,           SPELL_AIR_SPARKS,              SPELL_WATER_POISON_SPRAY,      SPELL_EARTH_STUN,              SPELL_BODY_HARM,
@@ -422,8 +521,8 @@
     case SPELL_WATER_POISON_SPRAY:
     case SPELL_AIR_SPARKS:
     case SPELL_EARTH_DEATH_BLOSSOM:
-      a1.uType = stru_4E3ACC[uSpellID].uType;
-      a1.stru_24.Reset();
+      a1.uType = spell_sprite_mapping[uSpellID].uSpriteType;
+      a1.containing_item.Reset();
       a1.spell_id = uSpellID;
       a1.spell_level = uSkill;
       a1.spell_skill = skillMasteryPlusOne;
--- a/Engine/Spells/Spells.h	Wed May 20 15:12:33 2015 +0200
+++ b/Engine/Spells/Spells.h	Wed May 20 21:05:07 2015 +0200
@@ -2,11 +2,15 @@
 
 #include <array>
 
+#include "Engine/Objects/SpriteObject.h"
+
 #include "../VectorTypes.h"
 
 /*  360 */
 enum SPELL_TYPE
 {
+  SPELL_0 = 0,
+
   SPELL_FIRE_TORCH_LIGHT = 1,
   SPELL_FIRE_FIRE_BOLT = 2,
   SPELL_FIRE_PROTECTION_FROM_FIRE = 3,
@@ -208,9 +212,9 @@
 
 /*  364 */
 #pragma pack(push, 1)
-struct stru324_spell
+struct stru324_spell_id_to_sprite_mapping//stru324_spell
 {
-  __int16 uType;
+    SPRITE_OBJECT_TYPE uSpriteType;
   __int16 field_2;
 };
 #pragma pack(pop)
@@ -281,9 +285,9 @@
 
 extern std::array<std::array<struct SpellBookIconPos, 12>, 9> pIconPos;
 
-extern std::array<stru324_spell, 103> stru_4E3ACC;
+extern std::array<stru324_spell_id_to_sprite_mapping, 103> spell_sprite_mapping; // 4E3ACC
 extern std::array<SpellData, 100> pSpellDatas;
-extern std::array<unsigned int, 25> wand_spell_ids;
+extern std::array<SPELL_TYPE, 25> wand_spell_ids;
 
 int _43AFE3_calc_spell_damage(int spellId, int spellLevel, signed int skillMastery, int currentHp);
 
--- a/GUI/UI/UIPopup.cpp	Wed May 20 15:12:33 2015 +0200
+++ b/GUI/UI/UIPopup.cpp	Wed May 20 21:05:07 2015 +0200
@@ -1452,7 +1452,7 @@
         {
           if ( !(pObjectList->pObjects[pSpriteObjects[PID_ID((unsigned __int16)v5)].uObjectDescID].uFlags & 0x10 ) )
           {
-            GameUI_DrawItemInfo(&pSpriteObjects[PID_ID((unsigned __int16)v5)].stru_24);
+              GameUI_DrawItemInfo(&pSpriteObjects[PID_ID((unsigned __int16)v5)].containing_item);
           }
         }
       }
@@ -1855,111 +1855,52 @@
       GameUI_DrawItemInfo(item);
       return;
     }
-    if ( damage_level == 1 )
-    {
-      pPlayers[uActiveCharacter]->RemoveItemAtInventoryIndex(pOut_y);
-      pPlayers[uActiveCharacter]->ReceiveDamage(rand() % 11 + 10, DMGT_FIRE);
-      pAudioPlayer->PlaySound(SOUND_fireBall, 0, 0, -1, 0, 0, 0, 0);
-      pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Escape, 0, 0);
-      v39.z = pParty->vPosition.z + pParty->sEyelevel;
-      v39.x = pParty->vPosition.x;
-      v39.y = pParty->vPosition.y;
 
-      int rot_x, rot_y, rot_z;
-      Vec3_int_::Rotate(64, pParty->sRotationY, pParty->sRotationX, v39, &rot_x, &rot_y, &rot_z);
-      SpriteObject::sub_42F7EB_DropItemAt(0x41Bu, rot_x, rot_y, rot_z, 0, 1, 0, 0, 0);
-      if ( dword_4E455C )
-      {
-        if ( pPlayers[uActiveCharacter]->CanAct() )
-          pPlayers[uActiveCharacter]->PlaySound(SPEECH_17, 0);
-        ShowStatusBarString(pGlobalTXT_LocalizationStrings[444], 2);//Îé!
-        dword_4E455C = 0;
-      }
-      pMouse->RemoveHoldingItem();
-      no_rightlick_in_inventory = 1;
-      return;
-    }
-    if ( damage_level == 2 )
-    {
-      pPlayers[uActiveCharacter]->RemoveItemAtInventoryIndex(pOut_y);
-      pPlayers[uActiveCharacter]->ReceiveDamage(rand() % 71 + 30, DMGT_FIRE);
-      pPlayers[uActiveCharacter]->ItemsEnchant(1);
-      pAudioPlayer->PlaySound(SOUND_fireBall, 0, 0, -1, 0, 0, 0, 0);
-      pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Escape, 0, 0);
-
-      v39.z = pParty->vPosition.z + pParty->sEyelevel;
-      v39.x = pParty->vPosition.x;
-      v39.y = pParty->vPosition.y;
-
-      int rot_x, rot_y, rot_z;
-      Vec3_int_::Rotate(64, pParty->sRotationY, pParty->sRotationX, v39, &rot_x, &rot_y, &rot_z);
-      SpriteObject::sub_42F7EB_DropItemAt(0x41Bu, rot_x, rot_y, rot_z, 0, 1, 0, 0, 0);
-      if ( dword_4E455C )
-      {
-        if ( pPlayers[uActiveCharacter]->CanAct() )
-          pPlayers[uActiveCharacter]->PlaySound(SPEECH_17, 0);
-        ShowStatusBarString(pGlobalTXT_LocalizationStrings[444], 2);//Îé!
-        dword_4E455C = 0;
-      }
-      pMouse->RemoveHoldingItem();
-      no_rightlick_in_inventory = 1;
-      return;
-    }
-    if ( damage_level == 3 )
+    if (damage_level > 0)
     {
-      pPlayers[uActiveCharacter]->RemoveItemAtInventoryIndex(pOut_y);
-      pPlayers[uActiveCharacter]->ReceiveDamage(rand() % 201 + 50, DMGT_FIRE);
-      pPlayers[uActiveCharacter]->ItemsEnchant(5);
-      pAudioPlayer->PlaySound(SOUND_fireBall, 0, 0, -1, 0, 0, 0, 0);
-
-      pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Escape, 0, 0);
-
-      v39.z = pParty->vPosition.z + pParty->sEyelevel;
-      v39.x = pParty->vPosition.x;
-      v39.y = pParty->vPosition.y;
+        pPlayers[uActiveCharacter]->RemoveItemAtInventoryIndex(pOut_y);
 
-      int rot_x, rot_y, rot_z;
-      Vec3_int_::Rotate(64, pParty->sRotationY, pParty->sRotationX, v39, &rot_x, &rot_y, &rot_z);
-      SpriteObject::sub_42F7EB_DropItemAt(0x41Bu, rot_x, rot_y, rot_z, 0, 1, 0, 0, 0);
-      if ( dword_4E455C )
-      {
-        if ( pPlayers[uActiveCharacter]->CanAct() )
-          pPlayers[uActiveCharacter]->PlaySound(SPEECH_17, 0);
-        ShowStatusBarString(pGlobalTXT_LocalizationStrings[444], 2);//Îé!
-        dword_4E455C = 0;
-      }
-      pMouse->RemoveHoldingItem();
-      no_rightlick_in_inventory = 1;
-      return;
+        if (damage_level == 1)
+        {
+            pPlayers[uActiveCharacter]->ReceiveDamage(rand() % 11 + 10, DMGT_FIRE);
+        }
+        else if (damage_level == 2)
+        {
+            pPlayers[uActiveCharacter]->ReceiveDamage(rand() % 71 + 30, DMGT_FIRE);
+            pPlayers[uActiveCharacter]->ItemsEnchant(1);
+        }
+        else if (damage_level == 3)
+        {
+            pPlayers[uActiveCharacter]->ReceiveDamage(rand() % 201 + 50, DMGT_FIRE);
+            pPlayers[uActiveCharacter]->ItemsEnchant(5);        
+        }
+        else if (damage_level >= 4)
+        {
+            pPlayers[uActiveCharacter]->SetCondition(Condition_Eradicated, 0);
+            pPlayers[uActiveCharacter]->ItemsEnchant(0);
+        }
+
+        pAudioPlayer->PlaySound(SOUND_fireBall, 0, 0, -1, 0, 0, 0, 0);
+        pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Escape, 0, 0);
+        v39.z = pParty->vPosition.z + pParty->sEyelevel;
+        v39.x = pParty->vPosition.x;
+        v39.y = pParty->vPosition.y;
+
+        int rot_x, rot_y, rot_z;
+        Vec3_int_::Rotate(64, pParty->sRotationY, pParty->sRotationX, v39, &rot_x, &rot_y, &rot_z);
+        SpriteObject::sub_42F7EB_DropItemAt(SPRITE_SPELL_FIRE_FIREBALL_IMPACT, rot_x, rot_y, rot_z, 0, 1, 0, 0, 0);
+        if (dword_4E455C)
+        {
+            if (pPlayers[uActiveCharacter]->CanAct())
+                pPlayers[uActiveCharacter]->PlaySound(SPEECH_17, 0);
+            ShowStatusBarString(pGlobalTXT_LocalizationStrings[444], 2);//Îé!
+            dword_4E455C = 0;
+        }
+        pMouse->RemoveHoldingItem();
+        no_rightlick_in_inventory = 1;
+        return;
     }
-    if ( damage_level == 4 )
-    {
-      pPlayers[uActiveCharacter]->RemoveItemAtInventoryIndex(pOut_y);
-      pPlayers[uActiveCharacter]->SetCondition(Condition_Eradicated, 0);
-      pPlayers[uActiveCharacter]->ItemsEnchant(0);
-      pAudioPlayer->PlaySound(SOUND_fireBall, 0, 0, -1, 0, 0, 0, 0);
-
-      pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Escape, 0, 0);
-
-      v39.z = pParty->vPosition.z + pParty->sEyelevel;
-      v39.x = pParty->vPosition.x;
-      v39.y = pParty->vPosition.y;
-
-      int rot_x, rot_y, rot_z;
-      Vec3_int_::Rotate(64, pParty->sRotationY, pParty->sRotationX, v39, &rot_x, &rot_y, &rot_z);
-      SpriteObject::sub_42F7EB_DropItemAt(0x41Bu, rot_x, rot_y, rot_z, 0, 1, 0, 0, 0);
-      if ( dword_4E455C )
-      {
-        if ( pPlayers[uActiveCharacter]->CanAct() )
-          pPlayers[uActiveCharacter]->PlaySound(SPEECH_17, 0);
-        ShowStatusBarString(pGlobalTXT_LocalizationStrings[444], 2);//Îé!
-        dword_4E455C = 0;
-      }
-      pMouse->RemoveHoldingItem();
-      no_rightlick_in_inventory = 1;
-      return;
-    }
-    if ( damage_level == 0 )
+    else //if ( damage_level == 0 )
     {
       if ( alchemy_skill_points )
       {
--- a/GUI/UI/UiGame.cpp	Wed May 20 15:12:33 2015 +0200
+++ b/GUI/UI/UiGame.cpp	Wed May 20 21:05:07 2015 +0200
@@ -1583,11 +1583,11 @@
         }
         if ( pickedObjectPID >= 0x2000000u || pParty->pPickedItem.uItemID )
         {
-          GameUI_SetFooterString(pSpriteObjects[pickedObjectID].stru_24.GetDisplayName());
+            GameUI_SetFooterString(pSpriteObjects[pickedObjectID].containing_item.GetDisplayName());
         }
         else
         {
-          sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[470], pSpriteObjects[pickedObjectID].stru_24.GetDisplayName());// "Get %s"
+            sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[470], pSpriteObjects[pickedObjectID].containing_item.GetDisplayName());// "Get %s"
           GameUI_SetFooterString(pTmpBuf.data());
         } //intentional fallthrough
       }
--- a/Game/Game.cpp	Wed May 20 15:12:33 2015 +0200
+++ b/Game/Game.cpp	Wed May 20 21:05:07 2015 +0200
@@ -1037,6 +1037,10 @@
                                     pIcons_LOD->RemoveTexturesPackFromTextureList();
                                     Game_OnEscape();
                                     continue;
+                                case SCREEN_SPELL_BOOK:
+                                    Game_OnEscape();
+                                    continue;
+
                                 default:
                                     __debugbreak(); // which GAME_MENU is this?
                                     Game_OnEscape();
@@ -1812,7 +1816,7 @@
                 }
                 if (!uActiveCharacter || (pPlayer2 = pPlayers[uActiveCharacter], pPlayer2->uTimeToRecovery))
                     continue;
-                _42777D_CastSpell_UseWand_ShootArrow(pPlayer2->uQuickSpell, uActiveCharacter - 1, 0, 0, uActiveCharacter);
+                _42777D_CastSpell_UseWand_ShootArrow((SPELL_TYPE)pPlayer2->uQuickSpell, uActiveCharacter - 1, 0, 0, uActiveCharacter);
                 continue;
             case UIMSG_CastSpell_Monster_Improvement:
             case UIMSG_CastSpell_Shoot_Monster://FireBlow, Lightning, Ice Lightning, Swarm, 
@@ -2191,13 +2195,13 @@
 
             case UIMSG_CastSpellFromBook:
                 if (pTurnEngine->turn_stage != TE_MOVEMENT)
-                    _42777D_CastSpell_UseWand_ShootArrow(uMessageParam, v199, 0, 0, 0);
+                    _42777D_CastSpell_UseWand_ShootArrow((SPELL_TYPE)uMessageParam, v199, 0, 0, 0);
                 continue;
 
             case UIMSG_SpellScrollUse:
                 __debugbreak();
                 if (pTurnEngine->turn_stage != TE_MOVEMENT)
-                    _42777D_CastSpell_UseWand_ShootArrow(uMessageParam, v199, 133, 1, 0);
+                    _42777D_CastSpell_UseWand_ShootArrow((SPELL_TYPE)uMessageParam, v199, 133, 1, 0);
                 continue;
             case UIMSG_SpellBookWindow:
                 if (pTurnEngine->turn_stage == TE_MOVEMENT)
@@ -2662,6 +2666,15 @@
     else
         pAudioPlayer->SetMusicVolume(pSoundVolumeLevels[uMusicVolimeMultiplier] * 64.0f);
 
+
+    extern bool all_spells;
+    if (all_spells)
+    {
+        for (int i = 0; i < 4; ++i)
+            for (int j = 0; j < 99; ++j)
+                pParty->pPlayers[i].spellbook.bHaveSpell[j] = true;
+    }
+
     while (2)
     {
         v16 = 1;
--- a/stru6.cpp	Wed May 20 15:12:33 2015 +0200
+++ b/stru6.cpp	Wed May 20 21:05:07 2015 +0200
@@ -552,7 +552,7 @@
 }
 
 //----- (004A7C07) --------------------------------------------------------
-void stru6::_4A7C07(SpriteObject *a2)
+void stru6::_4A7C07_stun_spell_fx(SpriteObject *a2)
 {
   stru6 *v2; // edi@1
   SpriteObject *v3; // esi@1
@@ -764,7 +764,7 @@
 }
 
 //----- (004A81CA) --------------------------------------------------------
-bool stru6::_4A81CA(SpriteObject *a2)
+bool stru6::RenderAsSprite(SpriteObject *a2)
 {
   //stru6 *v2; // ebx@1
   int result; // eax@1
@@ -785,521 +785,366 @@
   int v18; // eax@140
   int v19; // eax@141
   int v20; // eax@151
-  //unsigned int v21; // [sp-8h] [bp-20h]@66
-  //SpriteObject *v22; // [sp-8h] [bp-20h]@81
-  //unsigned int v23; // [sp-4h] [bp-1Ch]@4
-  //unsigned int v24; // [sp-4h] [bp-1Ch]@5
-//  unsigned int v25; // [sp-4h] [bp-1Ch]@30
-  //unsigned int v26; // [sp-4h] [bp-1Ch]@57
-  //unsigned int v27; // [sp-4h] [bp-1Ch]@66
-  //int v28; // [sp-4h] [bp-1Ch]@81
-  //unsigned int v29; // [sp+0h] [bp-18h]@4
-  //unsigned int v30; // [sp+0h] [bp-18h]@5
-  //int v31; // [sp+0h] [bp-18h]@30
-  //unsigned int v32; // [sp+0h] [bp-18h]@45
-  //float v33; // [sp+0h] [bp-18h]@57
-  //float v34; // [sp+0h] [bp-18h]@66
-  //signed int v35; // [sp+0h] [bp-18h]@81
   char pContainer[7]; // [sp+10h] [bp-8h]@81
 
   //__debugbreak(); // need to refactor carefully & collect data
   //v2 = this;
   result = a2->uType;
 
-  switch (a2->uType)
-  {
-    case 500:   // blue rat bolt for example
-    case 530:
-      _4A73AA_hanging_trace_particles___like_fire_strike_ice_blast_etc(a2, 0x00AAAFF, uTextureID_effpar1);
-    return false;
-
-    case 510:   // dragon fire for example
-      _4A73AA_hanging_trace_particles___like_fire_strike_ice_blast_etc(a2, 0xFF3C1E, uTextureID_effpar1);
-    return false;
-
-    case 545:
-    case 550:
-    case 555: return true;
-
-    case 556:
-      AddMobileLight(a2, 0xFF0000, 256);
-    return false;
-
-    case 600:
-      AddMobileLight(a2, 0xFF3C1E, 256);
-    return true;
-
-    case 1010: // Fire Bolt
-    {
-      _4A73AA_hanging_trace_particles___like_fire_strike_ice_blast_etc(a2, 0xFF3C1E, uTextureID_effpar1);
-      AddMobileLight(a2, 0xFF3C1E, 256);
-    }
-    return false;
-
-    case 1011: // Fire Bolt impact
-    {
-      _4A75CC_single_spell_collision_particle(a2, 0xFF3C1E, uTextureID_effpar1);
-      AddMobileLight(a2, 0xFF3C1E, 256);
-    }
-    return false;
-
-    case 1050: // Fireball
+    switch (a2->uType)
     {
-      _4A73AA_hanging_trace_particles___like_fire_strike_ice_blast_etc(a2, 0xFF3C1E, uTextureID_effpar1);
-      AddMobileLight(a2, 0xFF3C1E, 256);
-    }
-    return false;
+
+        case SPRITE_PROJECTILE_500:
+        case SPRITE_PROJECTILE_530:
+            _4A73AA_hanging_trace_particles___like_fire_strike_ice_blast_etc(a2, 0x00AAAFF, uTextureID_effpar1);
+            return false;
+        case SPRITE_PROJECTILE_500_IMPACT:
+        case SPRITE_PROJECTILE_530_IMPACT:
+            _4A75CC_single_spell_collision_particle(a2, 0xAAAFF, uTextureID_effpar1);
+            return true;
 
-    case 1051: // Fireball hit
-    {
-      AddMobileLight(a2, 0xFF3C1E, 256);
-      //if (pRenderer->pRenderD3D)
-      {
-        result = PID_TYPE(a2->spell_caster_pid);
-        if (PID_TYPE(a2->spell_caster_pid) != OBJECT_Actor &&
-            PID_TYPE(a2->spell_caster_pid) != OBJECT_Item)
-        {
-          if (field_204 != 4)
-          {
-            field_204++;
-            _4A7688_fireball_collision_particle(a2);
-          }
-          return false;
-        }
-      }
-    }
-    return true;
+        case SPRITE_PROJECTILE_505:
+            _4A73AA_hanging_trace_particles___like_fire_strike_ice_blast_etc(a2, 0x5C310E, uTextureID_effpar1);
+            return false;
+        case SPRITE_PROJECTILE_505_IMPACT:
+            _4A75CC_single_spell_collision_particle(a2, 0x5C310E, uTextureID_effpar1);
+            return false;
 
-    case 1081:
-    {
-      _4A7A66_miltiple_spell_collision_partifles___like_after_sparks_or_lightning(a2, 0xFF3C1E, uTextureID_effpar1, 300.0);
-      _4A7A66_miltiple_spell_collision_partifles___like_after_sparks_or_lightning(a2, 0xFF3C1E, uTextureID_effpar1, 250.0);
-      _4A7A66_miltiple_spell_collision_partifles___like_after_sparks_or_lightning(a2, 0xFF3C1E, uTextureID_effpar1, 200.0);
-      AddMobileLight(a2, 0xFF3C1E, 256);
-    }
-    return false;
+        case SPRITE_PROJECTILE_510:
+            _4A73AA_hanging_trace_particles___like_fire_strike_ice_blast_etc(a2, 0xFF3C1E, uTextureID_effpar1);
+            return false;
+        case SPRITE_PROJECTILE_510_IMPACT:
+            _4A75CC_single_spell_collision_particle(a2, 0xFF3C1E, uTextureID_effpar1);
+            return false;
 
-    case 2101:
-    {
-      _4A7A66_miltiple_spell_collision_partifles___like_after_sparks_or_lightning(a2, 0xC8C814, uTextureID_effpar1, 200.0);
-      AddMobileLight(a2, 0xC8C814, 256);
-    }
-    return false;
+        case SPRITE_PROJECTILE_515:
+            _4A73AA_hanging_trace_particles___like_fire_strike_ice_blast_etc(a2, 0x0062D0, uTextureID_effpar1);
+            return false;
+        case SPRITE_PROJECTILE_515_IMPACT:
+            _4A75CC_single_spell_collision_particle(a2, 0x0062D0, uTextureID_effpar1);
+            return false;
 
-    case 3060: // Acid Burst
-      _4A73AA_hanging_trace_particles___like_fire_strike_ice_blast_etc(a2, 0x0AB450, uTextureID_effpar1);
-      AddMobileLight(a2, 0x0AB450, 256);
-    return false;
+        case SPRITE_PROJECTILE_520:
+            _4A73AA_hanging_trace_particles___like_fire_strike_ice_blast_etc(a2, 0x0AB450, uTextureID_effpar1);
+            return false;
+        case SPRITE_PROJECTILE_520_IMPACT:
+            _4A75CC_single_spell_collision_particle(a2, 0x0AB450, uTextureID_effpar1);
+            return false;
 
-    case 9000: return true;
-  }
+        case SPRITE_PROJECTILE_525:
+            _4A73AA_hanging_trace_particles___like_fire_strike_ice_blast_etc(a2, 0xC8C805, uTextureID_effpar1);
+            return false;
+        case SPRITE_PROJECTILE_525_IMPACT:
+            _4A75CC_single_spell_collision_particle(a2, 0xC8C805, uTextureID_effpar1);
+            return false;
 
-  if ( result < 545 )
-  {
-    //__debugbreak(); // find out what kind of spells are these
-					// when summoned light elemental attacks
-	//cast spell from trees in Avlee
-      result -= 500;
-      switch ( result )
-      {
-        case 1:
-        case 31:
-          _4A75CC_single_spell_collision_particle(a2, 0xAAAFF, uTextureID_effpar1);
-          return true;
-        case 5:
-          _4A73AA_hanging_trace_particles___like_fire_strike_ice_blast_etc(a2, 0x5C310E, uTextureID_effpar1);
-          return false;
-        case 15:
-          _4A73AA_hanging_trace_particles___like_fire_strike_ice_blast_etc(a2, 0x0062D0, uTextureID_effpar1);
-          return false;
-        case 16:
-          _4A75CC_single_spell_collision_particle(a2, 0x0062D0, uTextureID_effpar1);
-          return false;
-        case 20:
-          _4A73AA_hanging_trace_particles___like_fire_strike_ice_blast_etc(a2, 0x0AB450, uTextureID_effpar1);
-          return false;
-        case 21:
-          _4A75CC_single_spell_collision_particle(a2, 0x0AB450, uTextureID_effpar1);
-          return false;
-        case 25:
-          _4A73AA_hanging_trace_particles___like_fire_strike_ice_blast_etc(a2, 0xC8C805, uTextureID_effpar1);
-          return false;
-        case 26:
-          _4A75CC_single_spell_collision_particle(a2, 0xC8C805, uTextureID_effpar1);
-          return false;
-        case 35:
-          _4A73AA_hanging_trace_particles___like_fire_strike_ice_blast_etc(a2, 0xFFFFFF, uTextureID_effpar1);
-          return false;
-        case 36:
-          _4A75CC_single_spell_collision_particle(a2, 0xFFFFFF, uTextureID_effpar1);
-        return false;
+        case SPRITE_PROJECTILE_535:
+            _4A73AA_hanging_trace_particles___like_fire_strike_ice_blast_etc(a2, 0xFFFFFF, uTextureID_effpar1);
+            return false;
+        case SPRITE_PROJECTILE_535_IMPACT:
+            _4A75CC_single_spell_collision_particle(a2, 0xFFFFFF, uTextureID_effpar1);
+            return false;
 
-        case 40:
-        _4A73AA_hanging_trace_particles___like_fire_strike_ice_blast_etc(a2, 0x7E7E7E, uTextureID_effpar1);
-        return false;
-
-        case 11:
-          _4A75CC_single_spell_collision_particle(a2, 0xFF3C1E, uTextureID_effpar1);
-          return false;
-        case 6:
-          _4A75CC_single_spell_collision_particle(a2, 0x5C310E, uTextureID_effpar1);
-          return false;
-
-        case 41:
-          _4A75CC_single_spell_collision_particle(a2, 0x7E7E7E, uTextureID_effpar1);
-          return false;
-        default:
-          return false;
-      }
-      return false;
-  }
+        case SPRITE_PROJECTILE_540:
+            _4A73AA_hanging_trace_particles___like_fire_strike_ice_blast_etc(a2, 0x7E7E7E, uTextureID_effpar1);
+            return false;
+        case SPRITE_PROJECTILE_540_IMPACT:
+            _4A75CC_single_spell_collision_particle(a2, 0x7E7E7E, uTextureID_effpar1);
+            return false;
 
-  if ( result <= 4051 )
-  {
-    if ( result != 4051 )
-    {
-      if ( result <= 2031 )
-      {
-        if ( result != 2031 )
-        {
-          if ( result < 1051 )
-          {
-            if ( result < 600 )
-            {
-              _4A75CC_single_spell_collision_particle(a2, 0xFF3C1E, uTextureID_effpar1);
-              return false;
-            }
-            if ( result < 811 )
-              return false;
-            if ( result <= 814 )
-              return true;
+        case SPRITE_PROJECTILE_545:
+        case SPRITE_PROJECTILE_550:
+        case SPRITE_PROJECTILE_555:
+            return true;
+
+
+        case SPRITE_556: __debugbreak();//what kind of effect is this?
+            AddMobileLight(a2, 0xFF0000, 256);
             return false;
 
-          }
-          if ( result <= 1081 )
-          {
-            if (result != 1081)
+        case SPRITE_600: __debugbreak();//what kind of effect is this?
+            AddMobileLight(a2, 0xFF3C1E, 256);
+            return true;
+
+        case 546: case 547: case 548: case 549:
+        case 551: case 552: case 553: case 554: case 557: case 558: case 559:
+        case 560: case 561: case 562: case 563: case 564: case 565: case 566: case 567: case 568: case 569:
+        case 570: case 571: case 572: case 573: case 574: case 575: case 576: case 577: case 578: case 579:
+        case 580: case 581: case 582: case 583: case 584: case 585: case 586: case 587: case 588: case 589:
+        case 590: case 591: case 592: case 593: case 594: case 595: case 596: case 597: case 598: case 599:
+            _4A75CC_single_spell_collision_particle(a2, 0xFF3C1E, uTextureID_effpar1);
+            return false;
+
+        case SPRITE_811:
+        case SPRITE_812:
+        case SPRITE_813:
+        case SPRITE_814:
+            return true;
+
+
+        case SPRITE_SPELL_FIRE_FIRE_BOLT:
+            _4A73AA_hanging_trace_particles___like_fire_strike_ice_blast_etc(a2, 0xFF3C1E, uTextureID_effpar1);
+            AddMobileLight(a2, 0xFF3C1E, 256);
+            return false;
+
+        case SPRITE_SPELL_FIRE_FIRE_BOLT_IMPACT:
+            _4A75CC_single_spell_collision_particle(a2, 0xFF3C1E, uTextureID_effpar1);
+            AddMobileLight(a2, 0xFF3C1E, 256);
+            return false;
+
+
+
+        case SPRITE_SPELL_FIRE_FIREBALL:
+            _4A73AA_hanging_trace_particles___like_fire_strike_ice_blast_etc(a2, 0xFF3C1E, uTextureID_effpar1);
+            AddMobileLight(a2, 0xFF3C1E, 256);
+            return false;
+
+        case SPRITE_SPELL_FIRE_FIREBALL_IMPACT:
+            AddMobileLight(a2, 0xFF3C1E, 256);
+            //if (pRenderer->pRenderD3D)
             {
-              result -= 1060;
-              if ( !result )
-                return true;
-              v7 = result - 1;
-              if ( v7 )
-              {
-                v8 = v7 - 9;
-                if ( !v8 )
+                if (PID_TYPE(a2->spell_caster_pid) != OBJECT_Actor &&
+                    PID_TYPE(a2->spell_caster_pid) != OBJECT_Item)
                 {
-                  _4A75CC_single_spell_collision_particle(a2, 0xFF3C1E, uTextureID_effpar1);
-                  return false;
+                    if (field_204 != 4)
+                    {
+                        field_204++;
+                        _4A7688_fireball_collision_particle(a2);
+                    }
+                    return false;
                 }
-                result = v8 - 10;
-                v9 = result == 0;
-//LABEL_129:
-                if ( v9 )
-                  return true;
-                return false;
-              }
-              _4A7A66_miltiple_spell_collision_partifles___like_after_sparks_or_lightning(a2, 0xFF3C1E, uTextureID_effpar1, 250.0);
-              AddMobileLight(a2, 0xFF3C1E, 256);
-              return false;
             }
-//LABEL_84:
-//            _4A7A66_miltiple_spell_collision_partifles___like_after_sparks_or_lightning(a2, diffuse, v26, v33);
-            //goto LABEL_43;
+            return true;
+
+
+        case SPRITE_SPELL_FIRE_FIRE_SPIKE:
+            return true;
+        case SPRITE_SPELL_FIRE_FIRE_SPIKE_IMPACT:
+            _4A7A66_miltiple_spell_collision_partifles___like_after_sparks_or_lightning(a2, 0xFF3C1E, uTextureID_effpar1, 250.0);
+            AddMobileLight(a2, 0xFF3C1E, 256);
+            return false;
+
+        case SPRITE_SPELL_FIRE_IMMOLATION:
+            _4A75CC_single_spell_collision_particle(a2, 0xFF3C1E, uTextureID_effpar1);
             return false;
-          }
-          v10 = result - 1090;
-          if ( v10 )
-          {
-            result = v10 - 10;
-            if ( !result )
-              return true;
-            v11 = result - 1;
-            if ( !v11 )
-            {
-              //diffuse = 0xFF3C1E;
-              _4A75CC_single_spell_collision_particle(a2, 0xFF3C1E, uTextureID_effpar1);
-              //v32 = v2->uTextureID_effpar1;
-              _4A75CC_single_spell_collision_particle(a2, 0xFF3C1E, uTextureID_effpar1);
-              //goto LABEL_43;
-              AddMobileLight(a2, 0xFF3C1E, 256);
-              return false;
-            }
-            result = v11 - 929;
-            if ( result )
-              return false;
-//LABEL_63:
+
+        case SPRITE_SPELL_FIRE_METEOR_SHOWER:
+            return true;
+        case SPRITE_SPELL_FIRE_METEOR_SHOWER_1:
+            _4A7A66_miltiple_spell_collision_partifles___like_after_sparks_or_lightning(a2, 0xFF3C1E, uTextureID_effpar1, 300.0);
+            _4A7A66_miltiple_spell_collision_partifles___like_after_sparks_or_lightning(a2, 0xFF3C1E, uTextureID_effpar1, 250.0);
+            _4A7A66_miltiple_spell_collision_partifles___like_after_sparks_or_lightning(a2, 0xFF3C1E, uTextureID_effpar1, 200.0);
+            AddMobileLight(a2, 0xFF3C1E, 256);
+            return false;
+
+        case SPRITE_SPELL_FIRE_INFERNO:
+            _4A7A66_miltiple_spell_collision_partifles___like_after_sparks_or_lightning(a2, 0xFF3C1Eu, uTextureID_effpar1, 250.0);
+            return false;
+
+        case SPRITE_SPELL_FIRE_INCINERATE:
+            return true;
+        case SPRITE_SPELL_FIRE_INCINERATE_IMPACT:
+            _4A75CC_single_spell_collision_particle(a2, 0xFF3C1E, uTextureID_effpar1);
+            _4A75CC_single_spell_collision_particle(a2, 0xFF3C1E, uTextureID_effpar1);
+            AddMobileLight(a2, 0xFF3C1E, 256);
+            return false;
+
+
+
+        case SPRITE_SPELL_AIR_SPARKS:
             //if ( !pRenderer->pRenderD3D )
             //  return true;
             _4A78AE_sparks_spell(a2);
             AddMobileLight(a2, 0x64640F, 128);
             return false;
-          }
 
-          _4A7A66_miltiple_spell_collision_partifles___like_after_sparks_or_lightning(a2, 0xFF3C1Eu, uTextureID_effpar1, 250.0);
-          return false;
-        }
-        //goto LABEL_67;
-      }
-      if ( result < 3060 )
-      {
-        if ( result < 2101 )
-        {
-          if ( result != 2060 )
-          {
-            if ( result != 2061 )
-            {
-              if ( result <= 2079 )
-                return false;
-              if ( result <= 2081 )
-              {
-                //if ( pRenderer->pRenderD3D )
-                  _4A77FD_implosion_particle_d3d(a2);
-                /*else
-                  _4A80DC_implosion_particle_sw(a2);*/
-                return false;
-              }
-              v9 = result == 2100;
-                if ( v9 )
-                  return true;
-                return false;
-            }
+        case SPRITE_SPELL_AIR_LIGHNING_BOLT:
+            //if ( !pRenderer->pRenderD3D )
+            //  return true;
+            memcpy(pContainer, "sp18h1", 7);
+            pRnd->SetRange(1, 6);
+            pContainer[5] = pRnd->GetInRange() + '0';
+            AddProjectile(a2, 100, pBitmaps_LOD->LoadTexture(pContainer));
+            return false;
+        case SPRITE_SPELL_AIR_LIGHNING_BOLT_IMPACT:
             _4A7A66_miltiple_spell_collision_partifles___like_after_sparks_or_lightning(a2, 0xC8C814, uTextureID_effpar2, 200.0);
             AddMobileLight(a2, 0xC8C814, 256);
             return false;
-          }
-          //if ( !pRenderer->pRenderD3D )
-          //  return true;
-          memcpy(pContainer, "sp18h1", 7);
-          pRnd->SetRange(1, 6);
-          pContainer[5] = pRnd->GetInRange() + '0';
-          AddProjectile(a2, 100, pBitmaps_LOD->LoadTexture(pContainer));
-          return false;
-        }
-        v12 = result - 3010;
-        if ( !v12 )
-        {
-          _4A73AA_hanging_trace_particles___like_fire_strike_ice_blast_etc(a2, 0xAB450, uTextureID_effpar1);
-          AddMobileLight(a2, 0xAB450, 256);
-          return false;
-        }
-        v13 = v12 - 1;
-        if ( !v13 )
-        {
-          _4A75CC_single_spell_collision_particle(a2, 0xAB450, uTextureID_effpar1);
-          AddMobileLight(a2, 0xAB450, 256);
-          return false;
-        }
-        result = v13 - 19;
-        if ( !result )
-          return true;
-        --result;
-        if ( result )
-          return false;
+
+        case SPRITE_SPELL_AIR_IMPLOSION:
+        case SPRITE_SPELL_AIR_IMPLOSION_IMPACT:
+            //if ( pRenderer->pRenderD3D )
+            _4A77FD_implosion_particle_d3d(a2);
+            /*else
+            _4A80DC_implosion_particle_sw(a2);*/
+            return false;
+
+        case SPRITE_SPELL_AIR_STARBURST:
+            return true;
+        case SPRITE_SPELL_AIR_STARBURST_1:
+            _4A7A66_miltiple_spell_collision_partifles___like_after_sparks_or_lightning(a2, 0xC8C814, uTextureID_effpar1, 200.0);
+            AddMobileLight(a2, 0xC8C814, 256);
+            return false;
+
+
+
+        case SPRITE_SPELL_WATER_POISON_SPRAY:
+            _4A73AA_hanging_trace_particles___like_fire_strike_ice_blast_etc(a2, 0xAB450, uTextureID_effpar1);
+            AddMobileLight(a2, 0xAB450, 256);
+            return false;
+        case SPRITE_SPELL_WATER_POISON_SPRAY_IMPACT:
+            _4A75CC_single_spell_collision_particle(a2, 0xAB450, uTextureID_effpar1);
+            AddMobileLight(a2, 0xAB450, 256);
+            return false;
+
+        case SPRITE_SPELL_WATER_ICE_BOLT:
+            return true;
+        case SPRITE_SPELL_WATER_ICE_BOLT_IMPACT:
+            _4A75CC_single_spell_collision_particle(a2, 0x9EB9F1, uTextureID_effpar1);
+            AddMobileLight(a2, 0x9EB9F1, 256);
+            return false;
+
+        case SPRITE_SPELL_WATER_ACID_BURST:
+            _4A73AA_hanging_trace_particles___like_fire_strike_ice_blast_etc(a2, 0x0AB450, uTextureID_effpar1);
+            AddMobileLight(a2, 0x0AB450, 256);
+            return false;
+        case SPRITE_SPELL_WATER_ACID_BURST_IMPACT:
+            return true;
+
+        case SPRITE_SPELL_WATER_ICE_BLAST:
+            return true;
+        case SPRITE_SPELL_WATER_ICE_BLAST_IMPACT:
+            _4A75CC_single_spell_collision_particle(a2, 0x9EB9F1, uTextureID_effpar1);
+            AddMobileLight(a2, 0x9EB9F1, 256);
+            return false;
+        case SPRITE_SPELL_WATER_ICE_BLAST_FALLOUT:
+            _4A73AA_hanging_trace_particles___like_fire_strike_ice_blast_etc(a2, 0x9EB9F1, uTextureID_effpar1);
+            return false;
+
 
-        _4A75CC_single_spell_collision_particle(a2, 0x9EB9F1, uTextureID_effpar1);
-        AddMobileLight(a2, 0x9EB9F1, 256);
-        return false;
-      }
-      if ( result > 4000 )
-      {
-        result -= 4030;
-        if ( !result || (--result, !result) )
-          return true;
-        result -= 19;
-        v9 = result == 0;
-                if ( v9 )
-                  return true;
-                return false;
-      }
-      if ( result == 4000 )
-      {
-        //if ( !pRenderer->pRenderD3D )
-        //  return true;
-        _4A7C07(a2);
-        return false;
-      }
-      result -= 3061;
-      if ( !result || (result -= 29) == 0 )
-        return true;
-      v14 = result - 1;
-      if ( !v14 )
-      {
-        _4A75CC_single_spell_collision_particle(a2, 0x9EB9F1, uTextureID_effpar1);
-        AddMobileLight(a2, 0x9EB9F1, 256);
-        return false;
-      }
-      result = v14 - 1;
-      if ( result )
-        return false;
-      _4A73AA_hanging_trace_particles___like_fire_strike_ice_blast_etc(a2, 0x9EB9F1, uTextureID_effpar1);
-      return false;
-    }
-    _4A7948_mind_blast_after_effect(a2);
-    return false;
-  }
-  if ( result <= 7090 )
-  {
-    if ( result == 7090 )
-      return true;
-    if ( result > 6030 )
-    {
-      if ( result > 6091 )
-      {
-        result -= 6100;
-        if ( !result )
-          return true;
-        result -= 930;
-        if ( result )
-        {
-          --result;
-          if (!result)
-            _4A75CC_single_spell_collision_particle(a2, 0xF00000, uTextureID_effpar1);
-          return false;
-        }
+        case SPRITE_SPELL_EARTH_STUN:
+            //if ( !pRenderer->pRenderD3D )
+            //  return true;
+            _4A7C07_stun_spell_fx(a2);
+            return false;
+
+        case SPRITE_SPELL_EARTH_DEADLY_SWARM:
+        case SPRITE_SPELL_EARTH_DEADLY_SWARM_IMPACT:
+            return true;
+
+        case SPRITE_SPELL_EARTH_ROCK_BLAST:
+            return true;
+        case SPRITE_SPELL_EARTH_ROCK_BLAST_IMPACT:
+            _4A75CC_single_spell_collision_particle(a2, 0x5C310E, uTextureID_effpar1);
+            return false;
+
+        case SPRITE_SPELL_EARTH_TELEKINESIS:
+            return true;
+
+        case SPRITE_SPELL_EARTH_BLADES:
+            return true;
+        case SPRITE_SPELL_EARTH_BLADES_IMPACT:
+            _4A7948_mind_blast_after_effect(a2);
+            return false;
+
+        case SPRITE_SPELL_EARTH_DEATH_BLOSSOM:
+            _4A73AA_hanging_trace_particles___like_fire_strike_ice_blast_etc(a2, 0x7E7E7E, uTextureID_effpar1);
+            return true;
+        case SPRITE_SPELL_EARTH_DEATH_BLOSSOM_IMPACT:
+            _4A7A66_miltiple_spell_collision_partifles___like_after_sparks_or_lightning(a2, 0x7E7E7E, uTextureID_effpar1, 200.0);
+            return false;
+        case SPRITE_SPELL_EARTH_DEATH_BLOSSOM_FALLOUT:
+            _4A73AA_hanging_trace_particles___like_fire_strike_ice_blast_etc(a2, 0x7E7E7E, uTextureID_effpar1);
+            return false;
+
+        case SPRITE_SPELL_EARTH_MASS_DISTORTION:
+            return false;
+
+        case SPRITE_SPELL_MIND_MIND_BLAST:
+        case SPRITE_SPELL_MIND_TELEPATHY:
+        case SPRITE_SPELL_MIND_BERSERK:
+        case SPRITE_SPELL_MIND_CHARM:
+        case SPRITE_SPELL_MIND_MASS_FEAR:
+        case SPRITE_SPELL_MIND_ENSLAVE:
+        case SPRITE_SPELL_MIND_PSYCHIC_SHOCK:
+            return true;
+
+        case SPRITE_SPELL_MIND_MIND_BLAST_IMPACT:
+            _4A7948_mind_blast_after_effect(a2);
+            return false;
+
+
+
+        case SPRITE_SPELL_BODY_HARM:
             //if ( !pRenderer->pRenderD3D )
             //  return true;
             _4A78AE_sparks_spell(a2);
             AddMobileLight(a2, 0x64640F, 128);
             return false;
-      }
-      if ( result != 6091 )
-      {
-        result -= 6040;
-        if ( !result || (result -= 20) == 0 || (result -= 10) == 0 )
-          return true;
-        result -= 20;
-        v9 = result == 0;
-                if ( v9 )
-                  return true;
-                return false;
-      }
-    }
-    else
-    {
-      if ( result == 6030 )
-        return true;
-      if ( result <= 4091 )
-      {
-        if ( result != 4091 )
-        {
-          result -= 4070;
-          if ( !result )
+        case SPRITE_SPELL_BODY_HARM_IMPACT:
+            _4A75CC_single_spell_collision_particle(a2, 0xF00000, uTextureID_effpar1);
+            return false;
+
+        case SPRITE_SPELL_BODY_FLYING_FIST:
             return true;
-          v15 = result - 1;
-          if ( v15 )
-          {
-            result = v15 - 9;
-            if ( !result )
-              return true;
-            result -= 10;
-            if ( !result )
-            {
-              _4A73AA_hanging_trace_particles___like_fire_strike_ice_blast_etc(a2, 0x7E7E7E, uTextureID_effpar1);
-              return true;
-            }
+        case SPRITE_SPELL_BODY_FLYING_FIST_IMPACT:
+            _4A75CC_single_spell_collision_particle(a2, 0xF00000, uTextureID_effpar1);
+            AddMobileLight(a2, 0xF00000, 256);
             return false;
-          }
-          _4A75CC_single_spell_collision_particle(a2, 0x5C310E, uTextureID_effpar1);
-          return false;
-        }
-        _4A7A66_miltiple_spell_collision_partifles___like_after_sparks_or_lightning(a2, 0x7E7E7E, uTextureID_effpar1, 200.0);
-        return false;
-      }
-      v16 = result - 4092;
-      if ( !v16 )
-      {
-        _4A73AA_hanging_trace_particles___like_fire_strike_ice_blast_etc(a2, 0x7E7E7E, uTextureID_effpar1);
-        return false;
-      }
-      result = v16 - 8;
-      if ( !result )
-        return false;
-      result -= 1910;
-      if ( !result )
-        return true;
-      --result;
-      if ( result )
-        return false;
-    }
-//LABEL_122:
-    _4A7948_mind_blast_after_effect(a2);
-    return false;
-  }
-  if ( result <= 9000 )
-  {
-    if ( result <= 8030 )
-    {
-      if ( result == 8030 )
-        return true;
-      v17 = result - 7091;
-      if ( v17 )
-      {
-        v18 = v17 - 909;
-        if ( !v18 )
-        {
-          _4A73AA_hanging_trace_particles___like_fire_strike_ice_blast_etc(a2, 0xFFFFFF, uTextureID_effpar3);
-          AddMobileLight(a2, 0xFFFFFF, 128);
-          return false;
-        }
-        v19 = v18 - 1;
-        if ( v19 )
-        {
-          result = v19 - 9;
-          if ( !result )
-          {
+
+
+
+        case SPRITE_SPELL_LIGHT_LIGHT_BOLT:
+            _4A73AA_hanging_trace_particles___like_fire_strike_ice_blast_etc(a2, 0xFFFFFF, uTextureID_effpar3);
+            AddMobileLight(a2, 0xFFFFFF, 128);
+            return false;
+        case SPRITE_SPELL_LIGHT_LIGHT_BOLT_IMPACT:
+            _4A75CC_single_spell_collision_particle(a2, 0xFFFFFF, uTextureID_effpar2);
+            AddMobileLight(a2, 0xFFFFFF, 256);
+            return false;
+
+        case SPRITE_SPELL_LIGHT_DESTROY_UNDEAD:
             AddMobileLight(a2, 0xFFFFFF, 64);
             return false;
-          }
-          return false;
-        }
-        _4A75CC_single_spell_collision_particle(a2, 0xFFFFFF, uTextureID_effpar2);
-        AddMobileLight(a2, 0xFFFFFF, 256);
-        return false;
-      }
-      else
-      {
-        _4A75CC_single_spell_collision_particle(a2, 0xF00000, uTextureID_effpar1);
-        AddMobileLight(a2, 0xF00000, 256);
-        return false;
-      }
-    }
-    result -= 8040;
-    if ( !result || (result -= 20) == 0 )
-      return true;
-    v20 = result - 30;
-    if ( v20 )
-    {
-      result = v20 - 1;
-      if ( result )
-        return false;
+
+        case SPRITE_SPELL_LIGHT_PARALYZE:
+            return true;
+
+        case SPRITE_SPELL_LIGHT_SUMMON_ELEMENTAL:
+        case SPRITE_SPELL_LIGHT_PRISMATIC_LIGHT:
+            return true;
+
+        case SPRITE_SPELL_LIGHT_SUNRAY:
+            AddMobileLight(a2, 0xFFFFFFu, 128);
+            //if ( !pRenderer->pRenderD3D )
+            //  return true;
+            AddProjectile(a2, 100, -1);
+            return false;
+        case SPRITE_SPELL_LIGHT_SUNRAY_IMPACT:
+            _4A75CC_single_spell_collision_particle(a2, 0xFFFFFF, uTextureID_effpar3);
+            return false;
+
 
-      _4A75CC_single_spell_collision_particle(a2, 0xFFFFFF, uTextureID_effpar3);
-      return false;
-    }
-    AddMobileLight(a2, 0xFFFFFFu, 128);
-    //if ( !pRenderer->pRenderD3D )
-    //  return true;
-    AddProjectile(a2, 100, -1);
-    return false;
+        case SPRITE_SPELL_DARK_REANIMATE:
+            return true;
+
+        case SPRITE_SPELL_DARK_TOXIC_CLOUD:
+        case SPRITE_SPELL_DARK_SHRINKING_RAY:
+        case SPRITE_SPELL_DARK_CONTROL_UNDEAD:
+            return true;
+
+        case SPRITE_SPELL_DARK_SHARPMETAL:
+            return true;
+        case SPRITE_SPELL_DARK_SHARPMETAL_IMPACT:
+            _4A75CC_single_spell_collision_particle(a2, 0x7E7E7E, uTextureID_effpar1);
+            return false;
+
+        case SPRITE_SPELL_DARK_SACRIFICE:
+        case SPRITE_SPELL_DARK_DRAGON_BREATH:
+        case SPRITE_SPELL_DARK_DRAGON_BREATH_1:
+            return true;
   }
-  if ( result > 9050 )
-  {
-    result -= 9070;
-    if ( !result || (result -= 10) == 0 || (--result, !result) )
-      return true;
-    return false;
-  }
-  if ( result == 9050 || (result -= 9010) == 0 || (result -= 20) == 0 || (result -= 10) == 0 )
-    return true;
-  --result;
-  if ( !result )
-  {
-//LABEL_164:
-    _4A75CC_single_spell_collision_particle(a2, 0x7E7E7E, uTextureID_effpar1);
-    return false;
-  }
-//LABEL_168:
+
   return false;
 }
 
--- a/stru6.h	Wed May 20 15:12:33 2015 +0200
+++ b/stru6.h	Wed May 20 21:05:07 2015 +0200
@@ -127,13 +127,13 @@
   void _4A7948_mind_blast_after_effect(struct SpriteObject *a1);
   bool AddMobileLight(struct SpriteObject *a1, unsigned int uDiffuse, int uRadius);
   void _4A7A66_miltiple_spell_collision_partifles___like_after_sparks_or_lightning(SpriteObject *a1, unsigned int uDiffuse, unsigned int uTextureID, float a4);
-  void _4A7C07(struct SpriteObject *a2);
+  void _4A7C07_stun_spell_fx(struct SpriteObject *a2);
   void AddProjectile(struct SpriteObject *a2, int a3, unsigned int uTextureID);
   void _4A7E89_sparkles_on_actor_after_it_casts_buff(struct Actor *pActor, unsigned int uDiffuse);
   void _4A7F74(int x, int y, int z);
   int _4A806F(struct Actor *pActor);
   //void _4A80DC_implosion_particle_sw(struct SpriteObject *a2);
-  bool _4A81CA(struct SpriteObject *a2);
+  bool RenderAsSprite(struct SpriteObject *a2);
   void SetPlayerBuffAnim(unsigned __int16 uSpellID, unsigned __int16 uPlayerID);
   void FadeScreen__like_Turn_Undead_and_mb_Armageddon(unsigned int uDiffuseColor, unsigned int uFadeTime);
   int _4A8BFC();