changeset 2569:d433439699be

Слияние
author Ritor1
date Thu, 21 May 2015 18:33:07 +0600
parents f2f2595fe308 (current diff) d569340b05ff (diff)
children 4d199006c716
files Engine/Engine.cpp stru6.cpp stru6.h
diffstat 40 files changed, 4080 insertions(+), 4152 deletions(-) [+]
line wrap: on
line diff
--- a/Build/Visual Studio 2013/World of Might and Magic.vcxproj	Thu May 21 18:32:45 2015 +0600
+++ b/Build/Visual Studio 2013/World of Might and Magic.vcxproj	Thu May 21 18:33:07 2015 +0600
@@ -141,6 +141,7 @@
     <ClCompile Include="..\..\Engine\Spells\CastSpellInfo.cpp" />
     <ClCompile Include="..\..\Engine\Spells\Spells.cpp" />
     <ClCompile Include="..\..\Engine\stru298.cpp" />
+    <ClCompile Include="..\..\Engine\stru6.cpp" />
     <ClCompile Include="..\..\Engine\Tables\FactionTable.cpp" />
     <ClCompile Include="..\..\Engine\Tables\FrameTableInc.cpp" />
     <ClCompile Include="..\..\Engine\Tables\IconFrameTable.cpp" />
@@ -257,7 +258,6 @@
     <ClCompile Include="..\..\Media\Video\Bink_Smacker.cpp" />
     <ClCompile Include="..\..\OSAPI.cpp" />
     <ClCompile Include="..\..\OSWindow.cpp" />
-    <ClCompile Include="..\..\stru6.cpp" />
     <ClCompile Include="..\..\_deleted.cpp" />
   </ItemGroup>
   <ItemGroup>
@@ -324,6 +324,7 @@
     <ClInclude Include="..\..\Engine\stru298.h" />
     <ClInclude Include="..\..\Engine\stru314.h" />
     <ClInclude Include="..\..\Engine\stru367.h" />
+    <ClInclude Include="..\..\Engine\stru6.h" />
     <ClInclude Include="..\..\Engine\Tables\FactionTable.h" />
     <ClInclude Include="..\..\Engine\Tables\FrameTableInc.h" />
     <ClInclude Include="..\..\Engine\Tables\IconFrameTable.h" />
@@ -522,7 +523,6 @@
     <ClInclude Include="..\..\OSAPI.h" />
     <ClInclude Include="..\..\OSInfo.h" />
     <ClInclude Include="..\..\OSWindow.h" />
-    <ClInclude Include="..\..\stru6.h" />
   </ItemGroup>
   <ItemGroup>
     <None Include="..\..\Engine\Graphics\Shaders\UI.hlsl" />
--- a/Build/Visual Studio 2013/World of Might and Magic.vcxproj.filters	Thu May 21 18:32:45 2015 +0600
+++ b/Build/Visual Studio 2013/World of Might and Magic.vcxproj.filters	Thu May 21 18:33:07 2015 +0600
@@ -483,7 +483,6 @@
     <ClCompile Include="..\..\Engine\SaveLoad.cpp">
       <Filter>Engine</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\stru6.cpp" />
     <ClCompile Include="..\..\GUI\NewUI\Core\UIControlModule_wrap.cxx">
       <Filter>GUI\NewUI\Core</Filter>
     </ClCompile>
@@ -616,6 +615,9 @@
     <ClCompile Include="..\..\Engine\Serialization\LegacyImages.cpp">
       <Filter>Engine\Serialization</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\Engine\stru6.cpp">
+      <Filter>Engine</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\lib\libavcodec\avcodec.h">
@@ -1260,7 +1262,6 @@
     <ClInclude Include="..\..\Engine\stru159.h">
       <Filter>Engine</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\stru6.h" />
     <ClInclude Include="..\..\GUI\NewUI\Core\UIControl.h">
       <Filter>GUI\NewUI\Core</Filter>
     </ClInclude>
@@ -1396,6 +1397,9 @@
     <ClInclude Include="..\..\Engine\Serialization\LegacyImages.h">
       <Filter>Engine\Serialization</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\Engine\stru6.h">
+      <Filter>Engine</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="..\..\lib\OpenAL\lib\x86\avcodec-55.def">
--- a/Engine/Engine.cpp	Thu May 21 18:32:45 2015 +0600
+++ b/Engine/Engine.cpp	Thu May 21 18:33:07 2015 +0600
@@ -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;
@@ -2954,7 +2954,7 @@
                     }
                     else
                     {
-                        v25 = pParty->pPlayers[v49].pInventoryItemList[_idx - 1].uSpecEnchantmentType;
+                        v25 = pParty->pPlayers[v49].pInventoryItemList[_idx - 1].special_enchantment;
                         if (v25 == 37 //of Regeneration("Regenerate 1hp/x while walking, etc")
                             || v25 == 44 //of Life("HP (+10), Regen hpts")
                             || v25 == 50 //of The Phoenix("Fire Res (+30), Regen hpts") && 
--- a/Engine/Events.cpp	Thu May 21 18:32:45 2015 +0600
+++ b/Engine/Events.cpp	Thu May 21 18:33:07 2015 +0600
@@ -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	Thu May 21 18:32:45 2015 +0600
+++ b/Engine/Graphics/Indoor.cpp	Thu May 21 18:33:07 2015 +0600
@@ -34,7 +34,7 @@
 #include "Lights.h"
 
 #include "Sprites.h"
-#include "stru6.h"
+#include "Engine/stru6.h"
 #include "ParticleEngine.h"
 #include "../texts.h"
 #include "GUI/GUIWindow.h"
@@ -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;
@@ -4445,75 +4445,36 @@
 {
   int v17; // edi@36
 
-  v17 = PID_ID(a1);
-  switch ( PID_TYPE(a1) )
-  {
-    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)
-      {
-        pParty->PartyFindsGold(pSpriteObjects[v17].stru_24.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)!
-        ShowStatusBarString(pTmpBuf2.data(), 2);
-        if ( pSpriteObjects[v17].stru_24.uItemID == 506 )//artefact
-          _449B7E_toggle_bit(pParty->_quest_bits, 184, 1);
-        if ( pSpriteObjects[v17].stru_24.uItemID == 455 )
-          _449B7E_toggle_bit(pParty->_quest_bits, 185, 1);
-        if ( !pParty->AddItemToParty(&pSpriteObjects[v17].stru_24) )
-          pParty->SetHoldingItem(&pSpriteObjects[v17].stru_24);
-      }
-      SpriteObject::OnInteraction(v17);
-      break;
+    v17 = PID_ID(a1);
+    switch ( PID_TYPE(a1) )
+    {
+        case OBJECT_Item: // take the item
+        {
+            if (pObjectList->pObjects[pSpriteObjects[v17].uObjectDescID].uFlags & 0x10
+                || v17 >= 1000
+                || !pSpriteObjects[v17].uObjectDescID)
+                return 1;
+
+            extern void ItemInteraction(unsigned int item_id);
+            ItemInteraction(v17);
+            break;
+        }
 
     case OBJECT_Actor:
       if ( pActors[v17].uAIState == Dying || pActors[v17].uAIState == Summoned )
         return 1;
-      if ( pActors[v17].uAIState == Dead )
-        pActors[v17].LootActor();
+      if (pActors[v17].uAIState == Dead)
+          pActors[v17].LootActor();
       else
       {
-        if ( !pActors[v17].GetActorsRelation(0) && pActors[v17].ActorFriend() && pActors[v17].CanAct() )
-        {
-          Actor::AI_FaceObject(v17, 4, 0, 0);
-          if ( pActors[v17].sNPC_ID )
-            pMessageQueue_50CBD0->AddGUIMessage(UIMSG_StartNPCDialogue, v17, 0);
-          else
-          {
-            if ( pNPCStats->pGroups_copy[pActors[v17].uGroup] )
-            {
-              if ( pNPCStats->pCatchPhrases[pNPCStats->pGroups_copy[pActors[v17].uGroup]] )
-              {
-                pParty->uFlags |= 2;
-                strcpy(byte_5B0938.data(), pNPCStats->pCatchPhrases[pNPCStats->pGroups_copy[pActors[v17].uGroup]]);
-                sub_4451A8_press_any_key(0, 0, 0);
-              }
-            }
-          }
-        }
+          extern bool ActorInteraction(unsigned int id);
+          ActorInteraction(v17);
       }
       break;
 
     case OBJECT_Decoration:
-      if ( pLevelDecorations[v17].uEventID )
-      {
-        EventProcessor(pLevelDecorations[v17].uEventID, a1, 1);
-        pLevelDecorations[v17].uFlags |= LEVEL_DECORATION_VISIBLE_ON_MAP;
-      }
-      else
-      {
-        if ( !pLevelDecorations[v17].IsInteractive() )
-          return 1;
-        activeLevelDecoration = &pLevelDecorations[v17];
-        EventProcessor(stru_5E4C90_MapPersistVars._decor_events[pLevelDecorations[v17]._idx_in_stru123 - 75] + 380, 0, 1);
-        activeLevelDecoration = nullptr;
-      }
+        extern void DecorationInteraction(unsigned int id, unsigned int pid);
+        DecorationInteraction(v17, a1);
       break;
 
     default:
@@ -6055,10 +6016,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	Thu May 21 18:32:45 2015 +0600
+++ b/Engine/Graphics/Outdoor.cpp	Thu May 21 18:33:07 2015 +0600
@@ -17,8 +17,8 @@
 #include "Engine/Events.h"
 #include "Engine/ZlibWrapper.h"
 #include "Engine/MMT.h"
-
-#include "stru6.h"
+#include "Engine/stru6.h"
+
 #include "Weather.h"
 #include "Sprites.h"
 #include "LightmapBuilder.h"
@@ -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	Thu May 21 18:32:45 2015 +0600
+++ b/Engine/Graphics/Render.cpp	Thu May 21 18:33:07 2015 +0600
@@ -12,7 +12,7 @@
 #include "Sprites.h"
 #include "IO/Mouse.h"
 #include "GammaControl.h"
-#include "stru6.h"
+#include "Engine/stru6.h"
 #include "GUI/GUIWindow.h"
 #include "DecalBuilder.h"
 #include "ParticleEngine.h"
@@ -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	Thu May 21 18:32:45 2015 +0600
+++ b/Engine/Graphics/Viewport.cpp	Thu May 21 18:33:07 2015 +0600
@@ -256,6 +256,128 @@
   }
   uMapBookMapZoom = 384;
 }
+
+
+
+
+
+
+void ItemInteraction(unsigned int item_id)
+{
+    if (pItemsTable->pItems[pSpriteObjects[item_id].containing_item.uItemID].uEquipType == EQUIP_GOLD)
+    {
+        pParty->PartyFindsGold(pSpriteObjects[item_id].containing_item.special_enchantment, 0);
+        viewparams->bRedrawGameUI = 1;
+    }
+    else
+    {
+        if (pParty->pPickedItem.uItemID)
+            return;
+
+        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].containing_item.uItemID == ITEM_ARTIFACT_SPLITTER)
+            _449B7E_toggle_bit(pParty->_quest_bits, 184, 1);
+        if (pSpriteObjects[item_id].containing_item.uItemID == ITEM_SPELLBOOK_MIND_REMOVE_FEAR)
+            _449B7E_toggle_bit(pParty->_quest_bits, 185, 1);
+        if (!pParty->AddItemToParty(&pSpriteObjects[item_id].containing_item))
+            pParty->SetHoldingItem(&pSpriteObjects[item_id].containing_item);
+    }
+    SpriteObject::OnInteraction(item_id);
+}
+
+bool ActorInteraction(unsigned int id)
+{
+    if (!pActors[id].GetActorsRelation(0) && pActors[id].ActorFriend() && pActors[id].CanAct())
+    {
+        Actor::AI_FaceObject(id, 4, 0, 0);
+        if (pActors[id].sNPC_ID)
+            pMessageQueue_50CBD0->AddGUIMessage(UIMSG_StartNPCDialogue, id, 0);
+        else
+        {
+            if (pNPCStats->pGroups_copy[pActors[id].uGroup])
+            {
+                if (pNPCStats->pCatchPhrases[pNPCStats->pGroups_copy[pActors[id].uGroup]])
+                {
+                    pParty->uFlags |= 2;
+                    strcpy(byte_5B0938.data(), pNPCStats->pCatchPhrases[pNPCStats->pGroups_copy[pActors[id].uGroup]]);
+                    sub_4451A8_press_any_key(0, 0, 0);
+                }
+            }
+        }
+        return true;
+    }
+    return false;
+}
+
+void DecorationInteraction(unsigned int id, unsigned int pid)
+{
+    if (pLevelDecorations[id].uEventID)
+    {
+        EventProcessor(pLevelDecorations[id].uEventID, pid, 1);
+        pLevelDecorations[id].uFlags |= LEVEL_DECORATION_VISIBLE_ON_MAP;
+    }
+    else
+    {
+        if (pLevelDecorations[id].IsInteractive())
+        {
+            activeLevelDecoration = &pLevelDecorations[id];
+            EventProcessor(stru_5E4C90_MapPersistVars._decor_events[pLevelDecorations[id]._idx_in_stru123 - 75] + 380, 0, 1);
+            activeLevelDecoration = nullptr;
+        }
+    }
+}
+
+
+void DropHeldItem()
+{
+    if (!pParty->pPickedItem.uItemID)
+        return;
+
+    SpriteObject a1; // [sp+Ch] [bp-80h]@1
+    POINT *v1; // esi@3
+    __debugbreak();//no checker
+    int v6 = 0;
+    a1.uType = (SPRITE_OBJECT_TYPE)pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID;
+    if ((signed int)pObjectList->uNumObjects <= 0)
+        LOWORD(v6) = 0;
+    else
+    {
+        auto v7 = (char *)&pObjectList->pObjects->uObjectID;
+        while (pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID != *(short *)v7)
+        {
+            ++v6;
+            v7 += 56;
+            if (v6 >= (signed int)pObjectList->uNumObjects)
+            {
+                LOWORD(v6) = 0;
+                break;
+            }
+        }
+    }
+    a1.uObjectDescID = v6;
+    a1.vPosition.y = pParty->vPosition.y;
+    a1.spell_caster_pid = OBJECT_Player;
+    a1.vPosition.x = pParty->vPosition.x;
+    a1.vPosition.z = pParty->sEyelevel + pParty->vPosition.z;
+    a1.uSoundID = 0;
+    a1.uFacing = 0;
+    a1.uAttributes = 8;
+    a1.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->sEyelevel + pParty->vPosition.z);
+    a1.uSpriteFrameID = 0;
+    memcpy(&a1.containing_item, &pParty->pPickedItem, 0x24u);
+
+    extern int UnprojectX(int);
+    //v9 = UnprojectX(v1->x);
+    a1.Create(pParty->sRotationY + UnprojectX(v1->x), 184, 200, 0);
+    auto pTextureID = pIcons_LOD->LoadTexture(pParty->pPickedItem.GetIconName(), TEXTURE_16BIT_PALETTE);
+    if (pTextureID != -1)
+        pIcons_LOD->pTextures[pTextureID].Release();
+    pMouse->RemoveHoldingItem();
+    pIcons_LOD->SyncLoadedFilesCount();
+}
+
+
 //----- (0042213C) --------------------------------------------------------
 void OnGameViewportClick()
 {
@@ -274,6 +396,8 @@
   POINT a2; // [sp+84h] [bp-8h]@3
 
   int clickable_distance = 512;
+  int distance = HIWORD(v0);
+  bool in_range = distance < clickable_distance;
 
   v1 = pMouse->GetCursorPos(&a2);
   //if ( pRenderer->pRenderD3D )
@@ -285,429 +409,98 @@
   {
     int item_id = PID_ID(v0);
     //v21 = (signed int)(unsigned __int16)v0 >> 3;
-    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 )
-      {
-        pParty->PartyFindsGold(pSpriteObjects[item_id].stru_24.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)!
-        ShowStatusBarString(pTmpBuf2.data(), 2);
-        if ( pSpriteObjects[item_id].stru_24.uItemID == ITEM_ARTIFACT_SPLITTER )
-          _449B7E_toggle_bit(pParty->_quest_bits, 184, 1);
-        if ( pSpriteObjects[item_id].stru_24.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);
-      }
-      SpriteObject::OnInteraction(item_id);
-      return;
-    }
-    if ( !pParty->pPickedItem.uItemID )
-      return;
-		__debugbreak();//no checker
-    v6 = 0;
-    a1.uType = pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID;
-    if ( (signed int)pObjectList->uNumObjects <= 0 )
-      LOWORD(v6) = 0;
-    else
+    if (pObjectList->pObjects[pSpriteObjects[item_id].uObjectDescID].uFlags & 0x10 || item_id >= 1000 || !pSpriteObjects[item_id].uObjectDescID
+        || !in_range)
     {
-      v7 = (char *)&pObjectList->pObjects->uObjectID;
-      while ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID != *(short *)v7 )
-      {
-        ++v6;
-        v7 += 56;
-        if ( v6 >= (signed int)pObjectList->uNumObjects )
-        {
-          LOWORD(v6) = 0;
-          break;
-        }
-      }
+        if (pParty->pPickedItem.uItemID)
+            DropHeldItem();
     }
-    a1.uObjectDescID = v6;
-    a1.vPosition.y = pParty->vPosition.y;
-    a1.spell_caster_pid = OBJECT_Player;
-    a1.vPosition.x = pParty->vPosition.x;
-    a1.vPosition.z = pParty->sEyelevel + pParty->vPosition.z;
-    a1.uSoundID = 0;
-    a1.uFacing = 0;
-    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);
-
-    extern int UnprojectX(int);
-    //v9 = UnprojectX(v1->x);
-    a1.Create(pParty->sRotationY + UnprojectX(v1->x), 184, 200, 0);
-    pTextureID = pIcons_LOD->LoadTexture(pParty->pPickedItem.GetIconName(), TEXTURE_16BIT_PALETTE);
-    if (pTextureID != -1)
-      pIcons_LOD->pTextures[pTextureID].Release();
-    pMouse->RemoveHoldingItem();
-    pIcons_LOD->SyncLoadedFilesCount();
-    return;
+    else
+        ItemInteraction(item_id);
   }
-  if ( PID_TYPE(v0) == OBJECT_Actor)
+  else if ( PID_TYPE(v0) == OBJECT_Actor)
   {
     int mon_id = PID_ID(v0);
     //a2.y = v16;
     if ( pActors[mon_id].uAIState == Dead )
     {
-      if ( (unsigned int)v0 < 0x2000000 )//distance limit for loot monster
+        if (in_range)
+            pActors[mon_id].LootActor();
+        else if (pParty->pPickedItem.uItemID)
+            DropHeldItem();
+    }
+    else if ( GetAsyncKeyState(VK_SHIFT) >= 0 )
+    {
+        if (!in_range)
+        {
+            if (pParty->pPickedItem.uItemID)
+                DropHeldItem();
+        }
+        else if (!ActorInteraction(mon_id))
+        {
+            if (pParty->bTurnBasedModeOn == true && pTurnEngine->turn_stage == TE_MOVEMENT)
+                pTurnEngine->field_18 |= TE_FLAG_8;
+            else
+                pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Attack, 0, 0);
+        }
+    }
+    else if ( pParty->bTurnBasedModeOn == true && pTurnEngine->turn_stage == TE_MOVEMENT )
+        pParty->uFlags |= PARTY_FLAGS_1_FALLING;
+    else if ( uActiveCharacter && sub_427769_isSpellQuickCastableOnShiftClick(pPlayers[uActiveCharacter]->uQuickSpell))
+        pMessageQueue_50CBD0->AddGUIMessage(UIMSG_CastQuickSpell, 0, 0);
+  }
+  else if ( PID_TYPE(v0) == OBJECT_Decoration)
+  {
+      int id = PID_ID(v0);
+      if (distance - pDecorationList->pDecorations[pLevelDecorations[id].uDecorationDescID].uRadius >= clickable_distance)
       {
-        pActors[mon_id].LootActor();
-        return;
-      }
-      if ( !pParty->pPickedItem.uItemID )
-        return;
-		__debugbreak();//no checker
-      v6 = 0;
-      a1.uType = pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID;
-      if ( (signed int)pObjectList->uNumObjects <= 0 )
-        LOWORD(v6) = 0;
-      else
-      {
-        v7 = (char *)&pObjectList->pObjects->uObjectID;
-        while ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID != *(short *)v7 )
-        {
-          ++v6;
-          v7 += 56;
-          if ( v6 >= (signed int)pObjectList->uNumObjects )
-          {
-            LOWORD(v6) = 0;
-            break;
-          }
-        }
+          if (pParty->pPickedItem.uItemID)
+              DropHeldItem();
       }
-      a1.uObjectDescID = v6;
-      a1.vPosition.y = pParty->vPosition.y;
-      a1.spell_caster_pid = OBJECT_Player;
-      a1.vPosition.x = pParty->vPosition.x;
-      a1.vPosition.z = pParty->sEyelevel + pParty->vPosition.z;
-      a1.uSoundID = 0;
-      a1.uFacing = 0;
-      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);
-
-      extern int UnprojectX(int);
-      //v9 = UnprojectX(v1->x);
-      a1.Create(pParty->sRotationY + UnprojectX(v1->x), 184, 200, 0);
-      pTextureID = pIcons_LOD->LoadTexture(pParty->pPickedItem.GetIconName(), TEXTURE_16BIT_PALETTE);
-      if (pTextureID != -1)
-        pIcons_LOD->pTextures[pTextureID].Release();
-      pMouse->RemoveHoldingItem();
-      pIcons_LOD->SyncLoadedFilesCount();
-      return;
-    }
-    if ( GetAsyncKeyState(VK_SHIFT) >= 0 )
-    {
-      if ( !pActors[mon_id].GetActorsRelation(0) && pActors[mon_id].ActorFriend() )
+      else
+          DecorationInteraction(id, v0);
+  }
+  else if (PID_TYPE(v0) == OBJECT_BModel && in_range)
+  {
+      if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
       {
-        if ( HIWORD(v0) >= clickable_distance)
-        {
-          if ( !pParty->pPickedItem.uItemID )
-            return;
-		__debugbreak();//no checker
-          v6 = 0;
-          a1.uType = pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID;
-          if ( (signed int)pObjectList->uNumObjects <= 0 )
-            LOWORD(v6) = 0;
+          if (!pIndoor->pFaces[PID_ID(v0)].Clickable())
+          {
+              if (!pParty->pPickedItem.uItemID)
+              {
+                  ShowNothingHereStatus();
+                  if (!pParty->pPickedItem.uItemID)
+                      return;
+              }
+              else
+                  DropHeldItem();
+          }
           else
           {
-            v7 = (char *)&pObjectList->pObjects->uObjectID;
-            while ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID != *(short *)v7 )
-            {
-              ++v6;
-              v7 += 56;
-              if ( v6 >= (signed int)pObjectList->uNumObjects )
-              {
-                LOWORD(v6) = 0;
-                break;
-              }
-            }
+              pEventID = pIndoor->pFaceExtras[pIndoor->pFaces[PID_ID(v0)].uFaceExtraID].uEventID;
+              EventProcessor(pEventID, (unsigned __int16)v0, 1);
           }
-          a1.uObjectDescID = v6;
-          a1.vPosition.y = pParty->vPosition.y;
-          a1.spell_caster_pid = OBJECT_Player;
-          a1.vPosition.x = pParty->vPosition.x;
-          a1.vPosition.z = pParty->sEyelevel + pParty->vPosition.z;
-          a1.uSoundID = 0;
-          a1.uFacing = 0;
-          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);
-
-          extern int UnprojectX(int);
-          //v9 = UnprojectX(v1->x);
-          a1.Create(pParty->sRotationY + UnprojectX(v1->x), 184, 200, 0);
-          pTextureID = pIcons_LOD->LoadTexture(pParty->pPickedItem.GetIconName(), TEXTURE_16BIT_PALETTE);
-          if (pTextureID != -1)
-            pIcons_LOD->pTextures[pTextureID].Release();
-          pMouse->RemoveHoldingItem();
-          pIcons_LOD->SyncLoadedFilesCount();
-          return;
-        }
-        if ( !pActors[mon_id].CanAct() )
-          return;
-        //v18 = mon_id;
-        Actor::AI_FaceObject(mon_id, 4, 0, 0);
-        if ( !pActors[mon_id].sNPC_ID )
-        {
-          if ( pNPCStats->pGroups_copy[pActors[mon_id].uGroup] )
-          {
-            if ( pNPCStats->pCatchPhrases[pNPCStats->pGroups_copy[pActors[mon_id].uGroup]] )
-            {
-              pParty->uFlags |= 2;
-              strcpy(byte_5B0938.data(), pNPCStats->pCatchPhrases[pNPCStats->pGroups_copy[pActors[mon_id].uGroup]]);
-              sub_4451A8_press_any_key(0, 0, 0);
-            }
-          }
-          return;
-        }
-        pMessageQueue_50CBD0->AddGUIMessage(UIMSG_StartNPCDialogue, mon_id, 0);
-        return;
-      }
-      if ( pParty->bTurnBasedModeOn == true && pTurnEngine->turn_stage == TE_MOVEMENT )
-      {
-        pTurnEngine->field_18 |= TE_FLAG_8;
-        return;
-      }
-      pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Attack, 0, 0);
-    }
-    else
-    {
-      if ( pParty->bTurnBasedModeOn == true && pTurnEngine->turn_stage == TE_MOVEMENT )
-      {
-        pParty->uFlags |= PARTY_FLAGS_1_FALLING;
-        return;
       }
-      if ( uActiveCharacter && sub_427769_isSpellQuickCastableOnShiftClick(pPlayers[uActiveCharacter]->uQuickSpell))
-        pMessageQueue_50CBD0->AddGUIMessage(UIMSG_CastQuickSpell, 0, 0);
-    }
-    return;
-  }
-  if ( PID_TYPE(v0) == OBJECT_Decoration)
-  {
-    if ( (signed int)(((unsigned int)v0 >> 16) - pDecorationList->pDecorations[pLevelDecorations[(signed int)(unsigned __int16)v0 >> 3].uDecorationDescID].uRadius) >= clickable_distance )
-    {
-      if ( !pParty->pPickedItem.uItemID )
-        return;
-		__debugbreak();//no checker
-      v6 = 0;
-      a1.uType = pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID;
-      if ( (signed int)pObjectList->uNumObjects <= 0 )
-        LOWORD(v6) = 0;
-      else
-      {
-        v7 = (char *)&pObjectList->pObjects->uObjectID;
-        while ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID != *(short *)v7 )
-        {
-          ++v6;
-          v7 += 56;
-          if ( v6 >= (signed int)pObjectList->uNumObjects )
-          {
-            LOWORD(v6) = 0;
-            break;
-          }
-        }
-      }
-      a1.uObjectDescID = v6;
-      a1.vPosition.y = pParty->vPosition.y;
-      a1.spell_caster_pid = OBJECT_Player;
-      a1.vPosition.x = pParty->vPosition.x;
-      a1.vPosition.z = pParty->sEyelevel + pParty->vPosition.z;
-      a1.uSoundID = 0;
-      a1.uFacing = 0;
-      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);
-
-      extern int UnprojectX(int);
-      //v9 = UnprojectX(v1->x);
-      a1.Create(pParty->sRotationY + UnprojectX(v1->x), 184, 200, 0);
-      pTextureID = pIcons_LOD->LoadTexture(pParty->pPickedItem.GetIconName(), TEXTURE_16BIT_PALETTE);
-      if (pTextureID != -1)
-        pIcons_LOD->pTextures[pTextureID].Release();
-      pMouse->RemoveHoldingItem();
-      pIcons_LOD->SyncLoadedFilesCount();
-      return;
-    }
-    if ( !pLevelDecorations[(signed int)(unsigned __int16)v0 >> 3].uEventID )
-    {
-      if ( pLevelDecorations[(signed int)(unsigned __int16)v0 >> 3].IsInteractive() )
-      {
-        v15 = stru_5E4C90_MapPersistVars._decor_events[pLevelDecorations[(signed int)(unsigned __int16)v0 >> 3]._idx_in_stru123 - 75] + 380;
-        activeLevelDecoration = &pLevelDecorations[(signed int)(unsigned __int16)v0 >> 3];
-        EventProcessor(v15, 0, 1);
-        activeLevelDecoration = nullptr;
-      }
-      return;
-    }
-    pEventID = pLevelDecorations[(signed int)(unsigned __int16)v0 >> 3].uEventID;
-    EventProcessor(pEventID, (unsigned __int16)v0, 1);
-    return;
-  }
-  if ( PID_TYPE(v0) == OBJECT_BModel && HIWORD(v0) < clickable_distance)
-  {
-    if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
-    {
-      if ( !pIndoor->pFaces[PID_ID(v0)].Clickable() )
+      else if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor)
       {
-        if ( !pParty->pPickedItem.uItemID )
-        {
-          ShowNothingHereStatus();
-          if ( !pParty->pPickedItem.uItemID )
-            return;
-        }
-		__debugbreak();//no checker
-        v6 = 0;
-        a1.uType = pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID;
-        if ( (signed int)pObjectList->uNumObjects <= 0 )
-          LOWORD(v6) = 0;
-        else
-        {
-          v7 = (char *)&pObjectList->pObjects->uObjectID;
-          while ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID != *(short *)v7 )
-          {
-            ++v6;
-            v7 += 56;
-            if ( v6 >= (signed int)pObjectList->uNumObjects )
-            {
-              LOWORD(v6) = 0;
-              break;
-            }
-          }
-        }
-        a1.uObjectDescID = v6;
-        a1.vPosition.y = pParty->vPosition.y;
-        a1.spell_caster_pid = OBJECT_Player;
-        a1.vPosition.x = pParty->vPosition.x;
-        a1.vPosition.z = pParty->sEyelevel + pParty->vPosition.z;
-        a1.uSoundID = 0;
-        a1.uFacing = 0;
-        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);
-
-        extern int UnprojectX(int);
-        v9 = UnprojectX(v1->x);
-        a1.Create(pParty->sRotationY + v9, 184, 200, 0);
-        pTextureID = pIcons_LOD->LoadTexture(pParty->pPickedItem.GetIconName(), TEXTURE_16BIT_PALETTE);
-        if (pTextureID != -1)
-          pIcons_LOD->pTextures[pTextureID].Release();
-        pMouse->RemoveHoldingItem();
-        pIcons_LOD->SyncLoadedFilesCount();
-        return;
-      }
-      pEventID = pIndoor->pFaceExtras[pIndoor->pFaces[PID_ID(v0)].uFaceExtraID].uEventID;
-    }
-    if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor)
-    {
-      if ( !pOutdoor->pBModels[(signed int)(v0 & 0xFFFF) >> 9].pFaces[PID_ID(v0) & 0x3F].Clickable())
-      {
-       if ( !pParty->pPickedItem.uItemID )
-        {
-          ShowNothingHereStatus();
-          if ( !pParty->pPickedItem.uItemID )
-            return;
-        }
-		__debugbreak();//no checker
-        v6 = 0;
-        a1.uType = pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID;
-        if ( (signed int)pObjectList->uNumObjects <= 0 )
-          LOWORD(v6) = 0;
-        else
-        {
-          v7 = (char *)&pObjectList->pObjects->uObjectID;
-          while ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID != *(short *)v7 )
+          if (!pOutdoor->pBModels[(signed int)(v0 & 0xFFFF) >> 9].pFaces[PID_ID(v0) & 0x3F].Clickable())
           {
-            ++v6;
-            v7 += 56;
-            if ( v6 >= (signed int)pObjectList->uNumObjects )
-            {
-              LOWORD(v6) = 0;
-              break;
-            }
+              if (!pParty->pPickedItem.uItemID)
+              {
+                  ShowNothingHereStatus();
+                  if (!pParty->pPickedItem.uItemID)
+                      return;
+              }
+              else
+                  DropHeldItem();
           }
-        }
-        a1.uObjectDescID = v6;
-        a1.vPosition.y = pParty->vPosition.y;
-        a1.spell_caster_pid = OBJECT_Player;
-        a1.vPosition.x = pParty->vPosition.x;
-        a1.vPosition.z = pParty->sEyelevel + pParty->vPosition.z;
-        a1.uSoundID = 0;
-        a1.uFacing = 0;
-        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);
-
-        extern int UnprojectX(int);
-        v9 = UnprojectX(v1->x);
-        a1.Create(pParty->sRotationY + v9, 184, 200, 0);
-        pTextureID = pIcons_LOD->LoadTexture(pParty->pPickedItem.GetIconName(), TEXTURE_16BIT_PALETTE);
-        if (pTextureID != -1)
-          pIcons_LOD->pTextures[pTextureID].Release();
-        pMouse->RemoveHoldingItem();
-        pIcons_LOD->SyncLoadedFilesCount();
-        return;
-      }
-      pEventID = pOutdoor->pBModels[(signed int)(v0 & 0xFFFF) >> 9].pFaces[PID_ID(v0) & 0x3F].sCogTriggeredID;
+          else
+          {
+              pEventID = pOutdoor->pBModels[(signed int)(v0 & 0xFFFF) >> 9].pFaces[PID_ID(v0) & 0x3F].sCogTriggeredID;
+              EventProcessor(pEventID, (unsigned __int16)v0, 1);
+          }
     }
-    EventProcessor(pEventID, (unsigned __int16)v0, 1);
-    return;
   }
-  if ( PID_TYPE(v0) != OBJECT_BModel || HIWORD(v0) >= clickable_distance )
-  {
-    if ( !pParty->pPickedItem.uItemID )
-      return;
-	//__debugbreak();//no checker
-    v6 = 0;
-    a1.uType = pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID;
-    if ( (signed int)pObjectList->uNumObjects <= 0 )
-      LOWORD(v6) = 0;
-    else
-    {
-      v7 = (char *)&pObjectList->pObjects->uObjectID;
-      while ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID != *(short *)v7 )
-      {
-        ++v6;
-        v7 += 56;
-        if ( v6 >= (signed int)pObjectList->uNumObjects )
-        {
-          LOWORD(v6) = 0;
-          break;
-        }
-      }
-    }
-    a1.uObjectDescID = v6;
-    a1.vPosition.y = pParty->vPosition.y;
-    a1.spell_caster_pid = OBJECT_Player;
-    a1.vPosition.x = pParty->vPosition.x;
-    a1.vPosition.z = pParty->sEyelevel + pParty->vPosition.z;
-    a1.uSoundID = 0;
-    a1.uFacing = 0;
-    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);
-
-    extern int UnprojectX(int);
-    //v9 = UnprojectX(v1->x);
-    a1.Create(pParty->sRotationY + UnprojectX(v1->x), 184, 200, 0);
-    pTextureID = pIcons_LOD->LoadTexture(pParty->pPickedItem.GetIconName(), TEXTURE_16BIT_PALETTE);
-    if (pTextureID != -1)
-      pIcons_LOD->pTextures[pTextureID].Release();
-    pMouse->RemoveHoldingItem();
-    pIcons_LOD->SyncLoadedFilesCount();
-    return;
-  }
+  else if (pParty->pPickedItem.uItemID)
+      DropHeldItem();
 }
--- a/Engine/Graphics/Vis.cpp	Thu May 21 18:32:45 2015 +0600
+++ b/Engine/Graphics/Vis.cpp	Thu May 21 18:33:07 2015 +0600
@@ -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	Thu May 21 18:32:45 2015 +0600
+++ b/Engine/MapInfo.cpp	Thu May 21 18:33:07 2015 +0600
@@ -386,7 +386,6 @@
   signed int result; // eax@1
   signed __int64 v12; // qtt@1
   int v13; // ebx@1
-  int v14; // edx@10
   signed int v15; // ebx@20
   unsigned __int16 v16; // dx@20
 //  ObjectDesc *v17; // ecx@21
@@ -438,43 +437,37 @@
     }
     if ( a2->uIndex == 1 )
     {
-      v14 = rand() % 51 + 50;
-      a1a.stru_24.uItemID = 197;
-      v34 = v14;
+      a1a.containing_item.uItemID = ITEM_GOLD_SMALL;
+      v34 = rand() % 51 + 50;
     }
     else if ( a2->uIndex == 2 )
     {
-      v14 = rand() % 101 + 100;
-      a1a.stru_24.uItemID = 197;
-      v34 = v14;
+      a1a.containing_item.uItemID = ITEM_GOLD_SMALL;
+      v34 = rand() % 101 + 100;
     }
     else if ( a2->uIndex == 3 )
     {
-      v14 = rand() % 301 + 200;
-      a1a.stru_24.uItemID = 198;
-      v34 = v14;
+      a1a.containing_item.uItemID = ITEM_GOLD_MEDIUM;
+      v34 = rand() % 301 + 200;
     }
     else if ( a2->uIndex == 4 )
     {
-      v14 = rand() % 501 + 500;
-      a1a.stru_24.uItemID = 198;
-      v34 = v14;
+      a1a.containing_item.uItemID = ITEM_GOLD_MEDIUM;
+      v34 = rand() % 501 + 500;
     }
     else if ( a2->uIndex == 5 )
     {
-      v14 = rand() % 1001 + 1000;
-      a1a.stru_24.uItemID = 199;
-      v34 = v14;
+      a1a.containing_item.uItemID = ITEM_GOLD_LARGE;
+      v34 = rand() % 1001 + 1000;
     }
     else if ( a2->uIndex == 6 )
     {
-      v14 = rand() % 3001 + 2000;
-      a1a.stru_24.uItemID = 199;
-      v34 = v14;
+      a1a.containing_item.uItemID = ITEM_GOLD_LARGE;
+      v34 = rand() % 3001 + 2000;
     }	 
     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 +477,18 @@
         break;
       }
     }
-    a1a.stru_24.SetIdentified();
+    a1a.containing_item.SetIdentified();
     a1a.uObjectDescID = v18;
-    a1a.stru_24.uSpecEnchantmentType = v34;
+    a1a.containing_item.special_enchantment = (ITEM_ENCHANTMENT)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 +499,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	Thu May 21 18:32:45 2015 +0600
+++ b/Engine/Objects/Actor.cpp	Thu May 21 18:33:07 2015 +0600
@@ -9,7 +9,7 @@
 #include "../Graphics/PaletteManager.h"
 #include "../Graphics/DecalBuilder.h"
 #include "../Graphics/Sprites.h"
-#include "../../stru6.h"
+#include "Engine/stru6.h"
 #include "Actor.h"
 #include "../OurMath.h"
 #include "../Graphics/Outdoor.h"
@@ -144,17 +144,17 @@
   {
     if ( bGive )
     {
-      if ( pActors[uActorID].uCarriedItemID == 0)
+        if (pActors[uActorID].uCarriedItemID == ITEM_NULL)
         pActors[uActorID].uCarriedItemID = uItemID;
-      else if ( pActors[uActorID].ActorHasItems[0].uItemID == 0)
+      else if (pActors[uActorID].ActorHasItems[0].uItemID == ITEM_NULL)
         pActors[uActorID].ActorHasItems[0].uItemID = uItemID;
-      else if ( pActors[uActorID].ActorHasItems[1].uItemID == 0)
+      else if (pActors[uActorID].ActorHasItems[1].uItemID == ITEM_NULL)
         pActors[uActorID].ActorHasItems[1].uItemID = uItemID;
     }
     else
     {
       if ( pActors[uActorID].uCarriedItemID == uItemID )
-        pActors[uActorID].uCarriedItemID = 0;
+          pActors[uActorID].uCarriedItemID = ITEM_NULL;
       else if ( pActors[uActorID].ActorHasItems[0].uItemID == uItemID )
         pActors[uActorID].ActorHasItems[0].Reset();
       else if ( pActors[uActorID].ActorHasItems[1].uItemID == uItemID )
@@ -187,28 +187,28 @@
 //----- (004086E9) --------------------------------------------------------
 void Actor::SetRandomGoldIfTheresNoItem()
 {
-  int v2; // edi@1
-
-  v2 = 0;
-  if ( !this->ActorHasItems[3].uItemID )
-  {
-    if ( this->pMonsterInfo.uTreasureDiceRolls )
+    int v2; // edi@1
+
+    v2 = 0;
+    if (!this->ActorHasItems[3].uItemID)
     {
-      for (int i = 0; i < this->pMonsterInfo.uTreasureDiceRolls; i++)
-        v2 += rand() % this->pMonsterInfo.uTreasureDiceSides + 1;
-      if ( v2 )
-      {
-        this->ActorHasItems[3].uItemID = 197;
-        this->ActorHasItems[3].uSpecEnchantmentType = v2;    //actual gold amount
-      }
+        if (this->pMonsterInfo.uTreasureDiceRolls)
+        {
+            for (int i = 0; i < this->pMonsterInfo.uTreasureDiceRolls; i++)
+                v2 += rand() % this->pMonsterInfo.uTreasureDiceSides + 1;
+            if (v2)
+            {
+                this->ActorHasItems[3].uItemID = ITEM_GOLD_SMALL;
+                this->ActorHasItems[3].special_enchantment = (ITEM_ENCHANTMENT)v2;    //actual gold amount
+            }
+        }
     }
-  }
-  if ( rand() % 100 < this->pMonsterInfo.uTreasureDropChance )
-  {
-    if ( this->pMonsterInfo.uTreasureLevel )
-      pItemsTable->GenerateItem(this->pMonsterInfo.uTreasureLevel, this->pMonsterInfo.uTreasureType, &this->ActorHasItems[2]);
-  }
-  this->uAttributes |= ACTOR_HAS_ITEM;
+    if (rand() % 100 < this->pMonsterInfo.uTreasureDropChance)
+    {
+        if (this->pMonsterInfo.uTreasureLevel)
+            pItemsTable->GenerateItem(this->pMonsterInfo.uTreasureLevel, this->pMonsterInfo.uTreasureType, &this->ActorHasItems[2]);
+    }
+    this->uAttributes |= ACTOR_HAS_ITEM;
 }
 
 //----- (00404AC7) --------------------------------------------------------
@@ -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;
@@ -1968,7 +1968,7 @@
     break;
 
     case MONSTER_OOZE_1: case MONSTER_OOZE_2: case MONSTER_OOZE_3:
-      drop.uItemID = ITEM_OOZE_ECTOPLASM_BOTTLE;
+      drop.uItemID = ITEM_OOZE_ENDOPLASM_VIAL;
     break;
 
     case MONSTER_TROLL_1: case MONSTER_TROLL_2: case MONSTER_TROLL_3:
@@ -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.special_enchantment == 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(&attackElement, &isLifeStealing);
       if ( isLifeStealing && pMonster->sCurrentHP > 0 )
       {
         player->sHealth += v61 / 5;
@@ -3661,7 +3663,7 @@
             item = player->GetOffHandItem();
           else
             item = player->GetMainHandItem();
-          a4 = item->_439DF3_get_additional_damage((int*)&attackElement, &isLifeStealing);
+          a4 = item->_439DF3_get_additional_damage(&attackElement, &isLifeStealing);
           if ( isLifeStealing && pMonster->sCurrentHP > 0 )
           {
             player->sHealth += v61 / 5;
@@ -3723,7 +3725,7 @@
     && uDamageAmount != 0 )
     player->ReceiveDamage(uDamageAmount, attackElement);
   int knockbackValue = 20 * v61 / (signed int)pMonster->pMonsterInfo.uHP;
-  if ( (player->GetSpecialItemBonus(24) || hit_will_stun) && pMonster->DoesDmgTypeDoDamage(DMGT_EARTH) )
+  if ((player->GetSpecialItemBonus(ITEM_ENCHANTMENT_OF_FORCE) || hit_will_stun) && pMonster->DoesDmgTypeDoDamage(DMGT_EARTH))
   {
     extraRecoveryTime = 20;
     knockbackValue = 10;
@@ -3763,6 +3765,9 @@
   }
   Actor::AddBloodsplatOnDamageOverlay(uActorID_Monster, 1, v61);
 }
+
+
+
 //----- (004BBF61) --------------------------------------------------------
 void Actor::Arena_summon_actor( int monster_id, __int16 x, int y, int z )
 {
@@ -4149,7 +4154,7 @@
   {
     if ( this->ActorHasItems[3].uItemID != 0 &&  this->ActorHasItems[3].GetItemEquipType() == EQUIP_GOLD )
     {
-      v14 = this->ActorHasItems[3].uSpecEnchantmentType;
+      v14 = this->ActorHasItems[3].special_enchantment;
       this->ActorHasItems[3].Reset();
       if ( v14 )
       {
--- a/Engine/Objects/Chest.cpp	Thu May 21 18:32:45 2015 +0600
+++ b/Engine/Objects/Chest.cpp	Thu May 21 18:33:07 2015 +0600
@@ -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;
@@ -729,7 +729,7 @@
       v4 = pChests[(int)pGUIWindow_CurrentMenu->par1C].pInventoryIndices[v3] - 1;
       if ( pChests[(int)pGUIWindow_CurrentMenu->par1C].igChestItems[v4].GetItemEquipType() == EQUIP_GOLD )
       {
-        pParty->PartyFindsGold(pChests[(int)pGUIWindow_CurrentMenu->par1C].igChestItems[v4].uSpecEnchantmentType, 0); 
+        pParty->PartyFindsGold(pChests[(int)pGUIWindow_CurrentMenu->par1C].igChestItems[v4].special_enchantment, 0); 
         viewparams->bRedrawGameUI = 1;
       }
       else
--- a/Engine/Objects/Items.cpp	Thu May 21 18:32:45 2015 +0600
+++ b/Engine/Objects/Items.cpp	Thu May 21 18:33:07 2015 +0600
@@ -159,101 +159,101 @@
 
 
 //----- (00439DF3) --------------------------------------------------------
-int ItemGen::_439DF3_get_additional_damage(int *damage_type, bool *draintargetHP)
-	{
+int ItemGen::_439DF3_get_additional_damage(DAMAGE_TYPE *damage_type, bool *draintargetHP)
+{
     *draintargetHP = false;
-	*damage_type = 0;
-	if ( !uItemID )
-		return 0;
-	UpdateTempBonus(pParty->uTimePlayed);
-	if (uItemID == 501 )  //Iron Feather -sword
-		{
-		*damage_type = 1;
-		return rand() % 10 + 6;
-		}
-	if (uItemID == 507 ) //Ghoulsbane  -axe
-		{
-		*damage_type = 0;
-		return rand() % 16 + 3;
-		}
-	if ( uItemID == 510 ) //Ullyses  -bow
-		{
-		*damage_type = 2;
-		return rand() % 4 + 9;
-		}
-	if ( uItemID == 517 ) //Old Nick -dagger
-		{
-		*damage_type = 8;
-		return 8;
-		}
+    *damage_type = DMGT_FIRE;
+    if (uItemID == ITEM_NULL)
+        return 0;
+
+    UpdateTempBonus(pParty->uTimePlayed);
+    if (uItemID == ITEM_ARTIFACT_IRON_FEATHER)
+    {
+        *damage_type = DMGT_ELECTR;
+        return rand() % 10 + 6;
+    }
+    if (uItemID == ITEM_ARTIFACT_GHOULSBANE)
+    {
+        *damage_type = DMGT_FIRE;
+        return rand() % 16 + 3;
+    }
+    if (uItemID == ITEM_ARTEFACT_ULLYSES)
+    {
+        *damage_type = DMGT_COLD;
+        return rand() % 4 + 9;
+    }
+    if (uItemID == ITEM_RELIC_OLD_NICK)
+    {
+        *damage_type = DMGT_BODY;
+        return 8;
+    }
 
-	switch (uSpecEnchantmentType)
-		{
-	case 4:  //Adds 3-4 points of Cold damage.
-		*damage_type = 2;
-		return rand() % 2 + 3;
-		break;
-	case 5:  //Adds 6-8 points of Cold damage.
-		*damage_type = 2;
-		return rand() % 3 + 6;
-		break;
-	case 6: //Adds 9-12 points of Cold damage.
-		*damage_type = 2;
-		return rand() % 4 + 9;
-		break;
-	case 7: //Adds 2-5 points of Electrical damage.
-		*damage_type = 1;
-		return rand() % 4 + 2;
-		break;
-	case 8: //Adds 4-10 points of Electrical damage.
-		*damage_type = 1;
-		return rand() % 7 + 4;
-		break;
-	case 9: //Adds 6-15 points of Electrical damage.
-		*damage_type = 1;
-		return rand() % 10 + 6;
-		break;
-	case 10: //Adds 1-6 points of Fire damage.
-		*damage_type = 0;
-		return GetDiceResult(1, 6);
-		break;
-	case 11: //Adds 2-12 points of Fire damage.
-		*damage_type = 0;
-		return GetDiceResult(2, 6);
-		break;
-	case 12: //Adds 3-18 points of Fire damage.
-		*damage_type = 0;
-		return GetDiceResult(3, 6);
-		break;
-	case 13: //Adds 5 points of Body damage.
-		*damage_type = 8;
-		return 5;
-		break;
-	case 14: //Adds 8 points of Body damage.
-		*damage_type = 8;
-		return 8;
-		break;
-	case 15: //Adds 12 points of Body damage.
-		*damage_type = 8;
-		return 12;
-		break;
-	case 16: //Drain Hit Points from target.
-	case 41: //Drain Hit Points from target and Increased Weapon speed.
-		*damage_type = 10;
-		*draintargetHP = true;
-		return 0;
-		break;
-	case 46:  //Adds 10-20 points of Fire damage and +25 Might.
-		*damage_type = 0;
-		return rand() % 11 + 10;
-		break;
-	default:
-		*damage_type = 0;
-		return 0;
+    switch (special_enchantment)
+    {
+    case ITEM_ENCHANTMENT_OF_COLD:
+        *damage_type = DMGT_COLD;
+        return rand() % 2 + 3;
+        break;
+    case ITEM_ENCHANTMENT_OF_FROST:
+        *damage_type = DMGT_COLD;
+        return rand() % 3 + 6;
+        break;
+    case ITEM_ENCHANTMENT_OF_ICE:
+        *damage_type = DMGT_COLD;
+        return rand() % 4 + 9;
+        break;
+    case ITEM_ENCHANTMENT_OF_SPARKS:
+        *damage_type = DMGT_ELECTR;
+        return rand() % 4 + 2;
+        break;
+    case ITEM_ENCHANTMENT_OF_LIGHTNING:
+        *damage_type = DMGT_ELECTR;
+        return rand() % 7 + 4;
+        break;
+    case ITEM_ENCHANTMENT_OF_THUNDERBOLTS:
+        *damage_type = DMGT_ELECTR;
+        return rand() % 10 + 6;
+        break;
+    case ITEM_ENCHANTMENT_OF_FIRE:
+        *damage_type = DMGT_FIRE;
+        return GetDiceResult(1, 6);
+        break;
+    case ITEM_ENCHANTMENT_OF_FLAME:
+        *damage_type = DMGT_FIRE;
+        return GetDiceResult(2, 6);
+        break;
+    case ITEM_ENCHANTMENT_OF_INFERNOS:
+        *damage_type = DMGT_FIRE;
+        return GetDiceResult(3, 6);
+        break;
+    case ITEM_ENCHANTMENT_OF_POISON:
+        *damage_type = DMGT_BODY;
+        return 5;
+        break;
+    case ITEM_ENCHANTMENT_OF_VENOM:
+        *damage_type = DMGT_BODY;
+        return 8;
+        break;
+    case ITEM_ENCHANTMENT_OF_ACID:
+        *damage_type = DMGT_BODY;
+        return 12;
+        break;
+    case ITEM_ENCHANTMENT_VAMPIRIC:
+    case ITEM_ENCHANTMENT_OF_DARKNESS:
+        *damage_type = DMGT_DARK;
+        *draintargetHP = true;
+        return 0;
+        break;
 
-		}
-
-	}
+    case ITEM_ENCHANTMENT_OF_DRAGON:
+        *damage_type = DMGT_FIRE;
+        return rand() % 11 + 10;
+        break;
+    default:
+        *damage_type = DMGT_FIRE;
+        return 0;
+    }
+}
 
 
 //----- (00402F07) --------------------------------------------------------
@@ -262,10 +262,10 @@
   this->uHolderPlayer = 0;
   this->uAttributes = 0;
   this->uNumCharges = 0;
-  this->uSpecEnchantmentType = 0;
+  this->special_enchantment = ITEM_ENCHANTMENT_NULL;
   this->m_enchantmentStrength = 0;
   this->uEnchantmentType = 0;
-  this->uItemID = 0;
+  this->uItemID = ITEM_NULL;
   this->uBodyAnchor = 0;
   this->uExpireTime = 0i64;
 }
@@ -278,7 +278,7 @@
     if ( uTimePlayed > (signed __int64)this->uExpireTime )
     {
       this->uEnchantmentType = 0;
-      this->uSpecEnchantmentType = 0;
+      this->special_enchantment = ITEM_ENCHANTMENT_NULL;
       this->uAttributes = this->uAttributes&(~ITEM_TEMP_BONUS);
     }
   }
@@ -315,414 +315,414 @@
 //----- (00456D84) --------------------------------------------------------
 void ItemsTable::Initialize()
 {
-  std::map<std::string, ITEM_EQUIP_TYPE, ci_less> equipStatMap;
-  equipStatMap["weapon"] = EQUIP_SINGLE_HANDED;
-  equipStatMap["weapon2"] = EQUIP_TWO_HANDED;
-  equipStatMap["weapon1or2"] = EQUIP_SINGLE_HANDED;
-  equipStatMap["missile"] = EQUIP_BOW;
-  equipStatMap["bow"] = EQUIP_BOW;
-  equipStatMap["armor"] = EQUIP_ARMOUR;
-  equipStatMap["shield"] = EQUIP_SHIELD;
-  equipStatMap["helm"] = EQUIP_HELMET;
-  equipStatMap["belt"] = EQUIP_BELT;
-  equipStatMap["cloak"] = EQUIP_CLOAK;
-  equipStatMap["gauntlets"] = EQUIP_GAUNTLETS;
-  equipStatMap["boots"] = EQUIP_BOOTS;
-  equipStatMap["ring"] = EQUIP_RING;
-  equipStatMap["amulet"] = EQUIP_AMULET;
-  equipStatMap["weaponw"] = EQUIP_WAND;
-  equipStatMap["herb"] = EQUIP_REAGENT;
-  equipStatMap["reagent"] = EQUIP_REAGENT;
-  equipStatMap["bottle"] = EQUIP_POTION;
-  equipStatMap["sscroll"] = EQUIP_SPELL_SCROLL;
-  equipStatMap["book"] = EQUIP_BOOK;
-  equipStatMap["mscroll"] = EQUIP_MESSAGE_SCROLL;
-  equipStatMap["gold"] = EQUIP_GOLD;
-  equipStatMap["gem"] = EQUIP_GEM;
+    std::map<std::string, ITEM_EQUIP_TYPE, ci_less> equipStatMap;
+    equipStatMap["weapon"] = EQUIP_SINGLE_HANDED;
+    equipStatMap["weapon2"] = EQUIP_TWO_HANDED;
+    equipStatMap["weapon1or2"] = EQUIP_SINGLE_HANDED;
+    equipStatMap["missile"] = EQUIP_BOW;
+    equipStatMap["bow"] = EQUIP_BOW;
+    equipStatMap["armor"] = EQUIP_ARMOUR;
+    equipStatMap["shield"] = EQUIP_SHIELD;
+    equipStatMap["helm"] = EQUIP_HELMET;
+    equipStatMap["belt"] = EQUIP_BELT;
+    equipStatMap["cloak"] = EQUIP_CLOAK;
+    equipStatMap["gauntlets"] = EQUIP_GAUNTLETS;
+    equipStatMap["boots"] = EQUIP_BOOTS;
+    equipStatMap["ring"] = EQUIP_RING;
+    equipStatMap["amulet"] = EQUIP_AMULET;
+    equipStatMap["weaponw"] = EQUIP_WAND;
+    equipStatMap["herb"] = EQUIP_REAGENT;
+    equipStatMap["reagent"] = EQUIP_REAGENT;
+    equipStatMap["bottle"] = EQUIP_POTION;
+    equipStatMap["sscroll"] = EQUIP_SPELL_SCROLL;
+    equipStatMap["book"] = EQUIP_BOOK;
+    equipStatMap["mscroll"] = EQUIP_MESSAGE_SCROLL;
+    equipStatMap["gold"] = EQUIP_GOLD;
+    equipStatMap["gem"] = EQUIP_GEM;
 
-  std::map<std::string, PLAYER_SKILL_TYPE, ci_less> equipSkillMap;
-  equipSkillMap["staff"] = PLAYER_SKILL_STAFF;
-  equipSkillMap["sword"] = PLAYER_SKILL_SWORD;
-  equipSkillMap["dagger"] = PLAYER_SKILL_DAGGER;
-  equipSkillMap["axe"] = PLAYER_SKILL_AXE;
-  equipSkillMap["spear"] = PLAYER_SKILL_SPEAR;
-  equipSkillMap["bow"] = PLAYER_SKILL_BOW;
-  equipSkillMap["mace"] = PLAYER_SKILL_MACE;
-  equipSkillMap["blaster"] = PLAYER_SKILL_BLASTER;
-  equipSkillMap["shield"] = PLAYER_SKILL_SHIELD;
-  equipSkillMap["leather"] = PLAYER_SKILL_LEATHER;
-  equipSkillMap["chain"] = PLAYER_SKILL_CHAIN;
-  equipSkillMap["plate"] = PLAYER_SKILL_PLATE;
-  equipSkillMap["club"] = PLAYER_SKILL_CLUB;
-  
-  std::map<std::string, ITEM_MATERIAL, ci_less> materialMap;
-  materialMap["artifact"] = MATERIAL_ARTEFACT;
-  materialMap["relic"] = MATERIAL_RELIC;
-  materialMap["special"] = MATERIAL_SPECIAL;
+    std::map<std::string, PLAYER_SKILL_TYPE, ci_less> equipSkillMap;
+    equipSkillMap["staff"] = PLAYER_SKILL_STAFF;
+    equipSkillMap["sword"] = PLAYER_SKILL_SWORD;
+    equipSkillMap["dagger"] = PLAYER_SKILL_DAGGER;
+    equipSkillMap["axe"] = PLAYER_SKILL_AXE;
+    equipSkillMap["spear"] = PLAYER_SKILL_SPEAR;
+    equipSkillMap["bow"] = PLAYER_SKILL_BOW;
+    equipSkillMap["mace"] = PLAYER_SKILL_MACE;
+    equipSkillMap["blaster"] = PLAYER_SKILL_BLASTER;
+    equipSkillMap["shield"] = PLAYER_SKILL_SHIELD;
+    equipSkillMap["leather"] = PLAYER_SKILL_LEATHER;
+    equipSkillMap["chain"] = PLAYER_SKILL_CHAIN;
+    equipSkillMap["plate"] = PLAYER_SKILL_PLATE;
+    equipSkillMap["club"] = PLAYER_SKILL_CLUB;
 
-  char* test_string;
-  int item_counter;
+    std::map<std::string, ITEM_MATERIAL, ci_less> materialMap;
+    materialMap["artifact"] = MATERIAL_ARTEFACT;
+    materialMap["relic"] = MATERIAL_RELIC;
+    materialMap["special"] = MATERIAL_SPECIAL;
 
-	pMapStats = new MapStats;
-	pMapStats->Initialize();
+    char* test_string;
+    int item_counter;
+
+    pMapStats = new MapStats;
+    pMapStats->Initialize();
 
-	pMonsterStats = new MonsterStats;
-	pMonsterStats->Initialize();
-	pMonsterStats->InitializePlacements();
+    pMonsterStats = new MonsterStats;
+    pMonsterStats->Initialize();
+    pMonsterStats->InitializePlacements();
 
-	pSpellStats = new SpellStats;
-	pSpellStats->Initialize();
+    pSpellStats = new SpellStats;
+    pSpellStats->Initialize();
 
-	LoadPotions();
-	LoadPotionNotes();
+    LoadPotions();
+    LoadPotionNotes();
 
-	pFactionTable = new FactionTable;
-	pFactionTable->Initialize();
+    pFactionTable = new FactionTable;
+    pFactionTable->Initialize();
 
-	pStorylineText = new StorylineText;
-	pStorylineText->Initialize();
+    pStorylineText = new StorylineText;
+    pStorylineText->Initialize();
 
-	pStdItemsTXT_Raw = (char *)pEvents_LOD->LoadRaw("stditems.txt", 0);
-	strtok(pStdItemsTXT_Raw, "\r");
-	strtok(NULL, "\r");
-	strtok(NULL, "\r");
-	strtok(NULL, "\r");
-	//Standard Bonuses by Group	
-	for (int i=0;i<24;++i)
-		{
-		test_string = strtok(NULL, "\r") + 1;
-    auto tokens = Tokenize(test_string, '\t');
-    pEnchantments[i].pBonusStat=RemoveQuotes(tokens[0]);
-    pEnchantments[i].pOfName=RemoveQuotes(tokens[1]);
-    for (int j = 0; j < 9; j++)
+    pStdItemsTXT_Raw = (char *)pEvents_LOD->LoadRaw("stditems.txt", 0);
+    strtok(pStdItemsTXT_Raw, "\r");
+    strtok(NULL, "\r");
+    strtok(NULL, "\r");
+    strtok(NULL, "\r");
+    //Standard Bonuses by Group	
+    for (int i = 0; i < 24; ++i)
     {
-      pEnchantments[i].to_item[j]=atoi(tokens[j+2]);
+        test_string = strtok(NULL, "\r") + 1;
+        auto tokens = Tokenize(test_string, '\t');
+        pEnchantments[i].pBonusStat = RemoveQuotes(tokens[0]);
+        pEnchantments[i].pOfName = RemoveQuotes(tokens[1]);
+        for (int j = 0; j < 9; j++)
+        {
+            pEnchantments[i].to_item[j] = atoi(tokens[j + 2]);
+        }
     }
-	}
 
-	memset(&pEnchantmentsSumm, 0, 36);
-	for(int i=0;i<9;++i)
-		{
-		for (int j=0;j<24;++j)
-			pEnchantmentsSumm[i]+=pEnchantments[j].to_item[i];
-		}
+    memset(&pEnchantmentsSumm, 0, 36);
+    for (int i = 0; i < 9; ++i)
+    {
+        for (int j = 0; j < 24; ++j)
+            pEnchantmentsSumm[i] += pEnchantments[j].to_item[i];
+    }
 
-	//Bonus range for Standard by Level
-	strtok(NULL, "\r");
-	strtok(NULL, "\r");
-	strtok(NULL, "\r");
-	strtok(NULL, "\r");
-	strtok(NULL, "\r");
-	for(int i=0;i<6;++i) //counted from 1
-  {
-    test_string = strtok(NULL, "\r") + 1;
-    auto tokens = Tokenize(test_string, '\t');
-    Assert(tokens.size() == 4, "Invalid number of tokens");
-    bonus_ranges[i].minR = atoi(tokens[2]);
-    bonus_ranges[i].maxR =atoi(tokens[3]);
-	}
+    //Bonus range for Standard by Level
+    strtok(NULL, "\r");
+    strtok(NULL, "\r");
+    strtok(NULL, "\r");
+    strtok(NULL, "\r");
+    strtok(NULL, "\r");
+    for (int i = 0; i < 6; ++i) //counted from 1
+    {
+        test_string = strtok(NULL, "\r") + 1;
+        auto tokens = Tokenize(test_string, '\t');
+        Assert(tokens.size() == 4, "Invalid number of tokens");
+        bonus_ranges[i].minR = atoi(tokens[2]);
+        bonus_ranges[i].maxR = atoi(tokens[3]);
+    }
 
 
-	pSpcItemsTXT_Raw = (char *)pEvents_LOD->LoadRaw("spcitems.txt", 0);
-	strtok(pSpcItemsTXT_Raw, "\r");
-	strtok(NULL, "\r");
-	strtok(NULL, "\r");
-	strtok(NULL, "\r");
-	for (int i=0;i<72;++i)
-	{
-    test_string = strtok(NULL, "\r") + 1;
-    auto tokens = Tokenize(test_string, '\t');
-    Assert(tokens.size() >= 17, "Invalid number of tokens");
-    pSpecialEnchantments[i].pBonusStatement=RemoveQuotes(tokens[0]);
-    pSpecialEnchantments[i].pNameAdd= RemoveQuotes(tokens[1]);
-    for (int j = 0; j < 12; j++)
+    pSpcItemsTXT_Raw = (char *)pEvents_LOD->LoadRaw("spcitems.txt", 0);
+    strtok(pSpcItemsTXT_Raw, "\r");
+    strtok(NULL, "\r");
+    strtok(NULL, "\r");
+    strtok(NULL, "\r");
+    for (int i = 0; i < 72; ++i)
     {
-      pSpecialEnchantments[i].to_item_apply[j]=atoi(tokens[j+2]);
+        test_string = strtok(NULL, "\r") + 1;
+        auto tokens = Tokenize(test_string, '\t');
+        Assert(tokens.size() >= 17, "Invalid number of tokens");
+        pSpecialEnchantments[i].pBonusStatement = RemoveQuotes(tokens[0]);
+        pSpecialEnchantments[i].pNameAdd = RemoveQuotes(tokens[1]);
+        for (int j = 0; j < 12; j++)
+        {
+            pSpecialEnchantments[i].to_item_apply[j] = atoi(tokens[j + 2]);
+        }
+        int res;
+        res = atoi(tokens[14]);
+        if (!res)
+        {
+            ++tokens[14];
+            while (*tokens[14] == ' ')//fix X 2 case
+                ++tokens[14];
+            res = atoi(tokens[14]);
+        }
+        pSpecialEnchantments[i].iValue = res;
+        pSpecialEnchantments[i].iTreasureLevel = tolower(tokens[15][0]) - 97;
     }
-    int res;
-    res=atoi(tokens[14]);
-    if(!res)
+
+    pSpecialEnchantments_count = 71;
+    memset(&pSpecialEnchantmentsSumm, 0, 96);
+    for (int i = 0; i < 12; ++i)
     {
-      ++tokens[14]; 
-      while (*tokens[14]==' ')//fix X 2 case
-        ++tokens[14]; 
-      res=atoi(tokens[14]);
-    }				
-    pSpecialEnchantments[i].iValue=res;
-    pSpecialEnchantments[i].iTreasureLevel=  tolower(tokens[15][0]) - 97;
-	}
+        for (unsigned int j = 0; j <= pSpecialEnchantments_count; ++j)
+            pSpecialEnchantmentsSumm[i] += pSpecialEnchantments[j].to_item_apply[i];
+    }
 
-	pSpecialEnchantments_count = 71;
-	memset(&pSpecialEnchantmentsSumm, 0, 96);
-	for(int i=0;i<12;++i)
-		{
-		for (unsigned int j=0;j<=pSpecialEnchantments_count;++j)
-			pSpecialEnchantmentsSumm[i]+=pSpecialEnchantments[j].to_item_apply[i];
-		}
-
-	InitializeBuildingResidents();
+    InitializeBuildingResidents();
 
-	pItemsTXT_Raw = (char*) pEvents_LOD->LoadRaw("items.txt", 0);
-	strtok(pItemsTXT_Raw, "\r");
-	strtok(NULL, "\r");
-	uAllItemsCount = 0;
-	item_counter = 0;
-	while (item_counter < 800)
-	{
-	test_string = strtok(NULL, "\r") + 1;
-    auto tokens = Tokenize(test_string, '\t');
-    item_counter=atoi(tokens[0]);
-    uAllItemsCount=item_counter;
-    pItems[item_counter].pIconName = RemoveQuotes(tokens[1]);
-    pItems[item_counter].pName = RemoveQuotes(tokens[2]);
-    pItems[item_counter].uValue=atoi(tokens[3]);
-    auto findResult = equipStatMap.find(tokens[4]);
-    pItems[item_counter].uEquipType = findResult == equipStatMap.end() ? EQUIP_NONE : findResult->second;
-    auto findResult2 = equipSkillMap.find(tokens[5]);
-    pItems[item_counter].uSkillType = findResult2 == equipSkillMap.end() ? PLAYER_SKILL_MISC : findResult2->second;
-    auto tokens2 = Tokenize(tokens[6], 'd');
-    if (tokens2.size() == 2)
-    {
-      pItems[item_counter].uDamageDice=atoi(tokens2[0]);
-      pItems[item_counter].uDamageRoll=atoi(tokens2[1]);
-    }
-    else if (tolower(tokens2[0][0]) != 's')
-    {
-      pItems[item_counter].uDamageDice=atoi(tokens2[0]);
-      pItems[item_counter].uDamageRoll=1;
-    }
-    else
+    pItemsTXT_Raw = (char*)pEvents_LOD->LoadRaw("items.txt", 0);
+    strtok(pItemsTXT_Raw, "\r");
+    strtok(NULL, "\r");
+    uAllItemsCount = 0;
+    item_counter = 0;
+    while (item_counter < 800)
     {
-      pItems[item_counter].uDamageDice=0;
-      pItems[item_counter].uDamageRoll=0;
+        test_string = strtok(NULL, "\r") + 1;
+        auto tokens = Tokenize(test_string, '\t');
+        item_counter = atoi(tokens[0]);
+        uAllItemsCount = item_counter;
+        pItems[item_counter].pIconName = RemoveQuotes(tokens[1]);
+        pItems[item_counter].pName = RemoveQuotes(tokens[2]);
+        pItems[item_counter].uValue = atoi(tokens[3]);
+        auto findResult = equipStatMap.find(tokens[4]);
+        pItems[item_counter].uEquipType = findResult == equipStatMap.end() ? EQUIP_NONE : findResult->second;
+        auto findResult2 = equipSkillMap.find(tokens[5]);
+        pItems[item_counter].uSkillType = findResult2 == equipSkillMap.end() ? PLAYER_SKILL_MISC : findResult2->second;
+        auto tokens2 = Tokenize(tokens[6], 'd');
+        if (tokens2.size() == 2)
+        {
+            pItems[item_counter].uDamageDice = atoi(tokens2[0]);
+            pItems[item_counter].uDamageRoll = atoi(tokens2[1]);
+        }
+        else if (tolower(tokens2[0][0]) != 's')
+        {
+            pItems[item_counter].uDamageDice = atoi(tokens2[0]);
+            pItems[item_counter].uDamageRoll = 1;
+        }
+        else
+        {
+            pItems[item_counter].uDamageDice = 0;
+            pItems[item_counter].uDamageRoll = 0;
+        }
+        pItems[item_counter].uDamageMod = atoi(tokens[7]);
+        auto findResult3 = materialMap.find(tokens[8]);
+        pItems[item_counter].uMaterial = findResult3 == materialMap.end() ? MATERIAL_COMMON : findResult3->second;
+        pItems[item_counter].uItemID_Rep_St = atoi(tokens[9]);
+        pItems[item_counter].pUnidentifiedName = RemoveQuotes(tokens[10]);
+        pItems[item_counter].uSpriteID = atoi(tokens[11]);
+
+        pItems[item_counter]._additional_value = 0;
+        pItems[item_counter]._bonus_type = 0;
+        if (pItems[item_counter].uMaterial == MATERIAL_SPECIAL)
+        {
+            for (int ii = 0; ii < 24; ++ii)
+            {
+                if (!_stricmp(tokens[12], pEnchantments[ii].pOfName))
+                {
+                    pItems[item_counter]._bonus_type = ii + 1;
+                    break;
+                }
+            }
+            if (!pItems[item_counter]._bonus_type)
+            {
+                for (int ii = 0; ii < 72; ++ii)
+                {
+                    if (!_stricmp(tokens[12], pSpecialEnchantments[ii].pNameAdd))
+                    {
+                        pItems[item_counter]._additional_value = ii + 1;
+                    }
+                }
+            }
+        }
+
+        if ((pItems[item_counter].uMaterial == MATERIAL_SPECIAL) && (pItems[item_counter]._bonus_type))
+        {
+            char b_s = atoi(tokens[13]);
+            if (b_s)
+                pItems[item_counter]._bonus_strength = b_s;
+            else
+                pItems[item_counter]._bonus_strength = 1;
+        }
+        else
+            pItems[item_counter]._bonus_strength = 0;
+        pItems[item_counter].uEquipX = atoi(tokens[14]);
+        pItems[item_counter].uEquipY = atoi(tokens[15]);
+        pItems[item_counter].pDescription = RemoveQuotes(tokens[16]);
+        item_counter++;
     }
-    pItems[item_counter].uDamageMod=atoi(tokens[7]);
-    auto findResult3 = materialMap.find(tokens[8]);
-    pItems[item_counter].uMaterial = findResult3 == materialMap.end() ? MATERIAL_COMMON : findResult3->second;
-    pItems[item_counter].uItemID_Rep_St=atoi(tokens[9]);
-    pItems[item_counter].pUnidentifiedName = RemoveQuotes(tokens[10]);
-    pItems[item_counter].uSpriteID=atoi(tokens[11]);
 
-    pItems[item_counter]._additional_value=0;
-    pItems[item_counter]._bonus_type=0;
-    if (pItems[item_counter].uMaterial==MATERIAL_SPECIAL)
+    uAllItemsCount = item_counter;
+    pRndItemsTXT_Raw = (char *)pEvents_LOD->LoadRaw("rnditems.txt", 0);
+    strtok(pRndItemsTXT_Raw, "\r");
+    strtok(NULL, "\r");
+    strtok(NULL, "\r");
+    strtok(NULL, "\r");
+    for (item_counter = 0; item_counter < 619; item_counter++)
     {
-      for(int ii=0; ii<24; ++ii)
-      {
-        if (!_stricmp(tokens[12],pEnchantments[ii].pOfName))
-        {
-          pItems[item_counter]._bonus_type=ii+1;
-          break;
-        }
-      }
-      if (!pItems[item_counter]._bonus_type)
-      {
-        for(int ii=0; ii<72; ++ii)
-        {
-          if (!_stricmp(tokens[12],pSpecialEnchantments[ii].pNameAdd))
-          {
-            pItems[item_counter]._additional_value=ii+1;
-          }
-        }
-      }
+        test_string = strtok(NULL, "\r") + 1;
+        auto tokens = Tokenize(test_string, '\t');
+        Assert(tokens.size() > 7, "Invalid number of tokens");
+        item_counter = atoi(tokens[0]);
+        pItems[item_counter].uChanceByTreasureLvl1 = atoi(tokens[2]);
+        pItems[item_counter].uChanceByTreasureLvl2 = atoi(tokens[3]);
+        pItems[item_counter].uChanceByTreasureLvl3 = atoi(tokens[4]);
+        pItems[item_counter].uChanceByTreasureLvl4 = atoi(tokens[5]);
+        pItems[item_counter].uChanceByTreasureLvl5 = atoi(tokens[6]);
+        pItems[item_counter].uChanceByTreasureLvl6 = atoi(tokens[7]);
+    }
+
+    //ChanceByTreasureLvl Summ - to calculate chance
+    memset(&uChanceByTreasureLvlSumm, 0, 24);
+    for (int i = 0; i < 6; ++i)
+    {
+        for (int j = 1; j < item_counter; ++j)
+            uChanceByTreasureLvlSumm[i] += pItems[j].uChanceByTreasureLvl[i];
     }
 
-    if ((pItems[item_counter].uMaterial==MATERIAL_SPECIAL)&&(pItems[item_counter]._bonus_type))
+    strtok(NULL, "\r");
+    strtok(NULL, "\r");
+    strtok(NULL, "\r");
+    strtok(NULL, "\r");
+    strtok(NULL, "\r");
+    for (int i = 0; i < 3; ++i)
     {
-      char b_s=atoi(tokens[13]);
-      if (b_s)
-        pItems[item_counter]._bonus_strength=b_s;
-      else
-        pItems[item_counter]._bonus_strength=1;
+        test_string = strtok(NULL, "\r") + 1;
+        auto tokens = Tokenize(test_string, '\t');
+        Assert(tokens.size() > 7, "Invalid number of tokens");
+        switch (i)
+        {
+        case 0:
+            uBonusChanceStandart[0] = atoi(tokens[2]);
+            uBonusChanceStandart[1] = atoi(tokens[3]);
+            uBonusChanceStandart[2] = atoi(tokens[4]);
+            uBonusChanceStandart[3] = atoi(tokens[5]);
+            uBonusChanceStandart[4] = atoi(tokens[6]);
+            uBonusChanceStandart[5] = atoi(tokens[7]);
+            break;
+        case 1:
+            uBonusChanceSpecial[0] = atoi(tokens[2]);
+            uBonusChanceSpecial[1] = atoi(tokens[3]);
+            uBonusChanceSpecial[2] = atoi(tokens[4]);
+            uBonusChanceSpecial[3] = atoi(tokens[5]);
+            uBonusChanceSpecial[4] = atoi(tokens[6]);
+            uBonusChanceSpecial[5] = atoi(tokens[7]);
+            break;
+        case 2:
+            uBonusChanceWpSpecial[0] = atoi(tokens[2]);
+            uBonusChanceWpSpecial[1] = atoi(tokens[3]);
+            uBonusChanceWpSpecial[2] = atoi(tokens[4]);
+            uBonusChanceWpSpecial[3] = atoi(tokens[5]);
+            uBonusChanceWpSpecial[4] = atoi(tokens[6]);
+            uBonusChanceWpSpecial[5] = atoi(tokens[7]);
+            break;
+        }
     }
-    else
-      pItems[item_counter]._bonus_strength=0;
-    pItems[item_counter].uEquipX=atoi(tokens[14]);
-    pItems[item_counter].uEquipY=atoi(tokens[15]);
-    pItems[item_counter].pDescription = RemoveQuotes(tokens[16]);
-    item_counter++;
-	}
-
-	uAllItemsCount = item_counter;
-	pRndItemsTXT_Raw = (char *)pEvents_LOD->LoadRaw("rnditems.txt", 0);
-	strtok(pRndItemsTXT_Raw, "\r");
-	strtok(NULL, "\r");
-	strtok(NULL, "\r");
-	strtok(NULL, "\r");
-  for (item_counter = 0; item_counter < 619; item_counter++)
-		{
-		test_string = strtok(NULL, "\r") + 1;
-    auto tokens = Tokenize(test_string, '\t');
-    Assert(tokens.size() > 7, "Invalid number of tokens");
-    item_counter = atoi(tokens[0]);
-    pItems[item_counter].uChanceByTreasureLvl1=atoi(tokens[2]);
-    pItems[item_counter].uChanceByTreasureLvl2=atoi(tokens[3]);
-    pItems[item_counter].uChanceByTreasureLvl3=atoi(tokens[4]);
-    pItems[item_counter].uChanceByTreasureLvl4=atoi(tokens[5]);
-    pItems[item_counter].uChanceByTreasureLvl5=atoi(tokens[6]);
-    pItems[item_counter].uChanceByTreasureLvl6=atoi(tokens[7]);
-  }
+    free(pRndItemsTXT_Raw);
+    pRndItemsTXT_Raw = nullptr;
 
-	//ChanceByTreasureLvl Summ - to calculate chance
-	memset(&uChanceByTreasureLvlSumm, 0, 24);
-	for(int i=0;i<6;++i)
-		{
-		for (int j=1;j<item_counter;++j)
-			uChanceByTreasureLvlSumm[i]+=pItems[j].uChanceByTreasureLvl[i];
-		}
-
-	strtok(NULL, "\r");
-	strtok(NULL, "\r");
-	strtok(NULL, "\r");
-	strtok(NULL, "\r");
-	strtok(NULL, "\r");
-	for (int i=0;i<3;++i)
-		{
-		test_string = strtok(NULL, "\r") + 1;
-    auto tokens = Tokenize(test_string, '\t');
-    Assert(tokens.size() > 7, "Invalid number of tokens");
-      switch (i)
-      {
-      case 0:
-        uBonusChanceStandart[0]=atoi(tokens[2]);
-        uBonusChanceStandart[1]=atoi(tokens[3]);
-        uBonusChanceStandart[2]=atoi(tokens[4]);
-        uBonusChanceStandart[3]=atoi(tokens[5]);
-        uBonusChanceStandart[4]=atoi(tokens[6]);
-        uBonusChanceStandart[5]=atoi(tokens[7]);
-        break;
-      case 1:
-        uBonusChanceSpecial[0]=atoi(tokens[2]);
-        uBonusChanceSpecial[1]=atoi(tokens[3]);
-        uBonusChanceSpecial[2]=atoi(tokens[4]);
-        uBonusChanceSpecial[3]=atoi(tokens[5]);
-        uBonusChanceSpecial[4]=atoi(tokens[6]);
-        uBonusChanceSpecial[5]=atoi(tokens[7]);
-        break;
-      case 2:
-        uBonusChanceWpSpecial[0]=atoi(tokens[2]);
-        uBonusChanceWpSpecial[1]=atoi(tokens[3]);
-        uBonusChanceWpSpecial[2]=atoi(tokens[4]);
-        uBonusChanceWpSpecial[3]=atoi(tokens[5]);
-        uBonusChanceWpSpecial[4]=atoi(tokens[6]);
-        uBonusChanceWpSpecial[5]=atoi(tokens[7]);
-        break;
-      }
-		}
-  free(pRndItemsTXT_Raw);
-  pRndItemsTXT_Raw = nullptr;
+    pSkillDescTXT_Raw = (char *)pEvents_LOD->LoadRaw("skilldes.txt", 0);
+    strtok(pSkillDescTXT_Raw, "\r");
+    for (int i = 0; i < 37; ++i)
+    {
+        test_string = strtok(NULL, "\r") + 1;
+        auto tokens = Tokenize(test_string, '\t');
+        Assert(tokens.size() >= 6, "Invalid number of tokens");
+        pSkillDesc[i] = RemoveQuotes(tokens[1]);
+        pNormalSkillDesc[i] = RemoveQuotes(tokens[2]);
+        pExpertSkillDesc[i] = RemoveQuotes(tokens[3]);
+        pMasterSkillDesc[i] = RemoveQuotes(tokens[4]);
+        pGrandSkillDesc[i] = RemoveQuotes(tokens[5]);
+    }
 
-	pSkillDescTXT_Raw = (char *)pEvents_LOD->LoadRaw("skilldes.txt", 0);
-	strtok(pSkillDescTXT_Raw, "\r");
-	for (int i=0; i<37; ++i)
-		{
-		test_string = strtok(NULL, "\r") + 1;
-    auto tokens = Tokenize(test_string, '\t');
-    Assert(tokens.size() >= 6, "Invalid number of tokens");
-    pSkillDesc[i] = RemoveQuotes(tokens[1]);
-    pNormalSkillDesc[i] = RemoveQuotes(tokens[2]);
-    pExpertSkillDesc[i] = RemoveQuotes(tokens[3]);
-    pMasterSkillDesc[i] = RemoveQuotes(tokens[4]);
-    pGrandSkillDesc[i] = RemoveQuotes(tokens[5]);
-	}
-
-	pStatsTXT_Raw = (char *)pEvents_LOD->LoadRaw("stats.txt", 0);
-	strtok(pStatsTXT_Raw, "\r");
-	for (int i=0; i<26; ++i)
-		{
-		test_string = strtok(NULL, "\r") + 1;
-    auto tokens = Tokenize(test_string, '\t');
-    Assert(tokens.size() == 2, "Invalid number of tokens");
-    switch (i)
+    pStatsTXT_Raw = (char *)pEvents_LOD->LoadRaw("stats.txt", 0);
+    strtok(pStatsTXT_Raw, "\r");
+    for (int i = 0; i < 26; ++i)
     {
-    case 0:
-    case 1:
-    case 2:
-    case 3:
-    case 4:
-    case 5:
-    case 6:
-      pAttributeDescriptions[i] = RemoveQuotes(tokens[1]);
-      break;
-    case 7:
-      pHealthPointsAttributeDescription = RemoveQuotes(tokens[1]);
-      break;
-    case 8:
-      pArmourClassAttributeDescription = RemoveQuotes(tokens[1]);
-      break;
-    case 9:
-      pSpellPointsAttributeDescription = RemoveQuotes(tokens[1]);
-      break;
-    case 10:
-      pPlayerConditionAttributeDescription = RemoveQuotes(tokens[1]);
-      break;
-    case 11:
-      pFastSpellAttributeDescription = RemoveQuotes(tokens[1]);
-      break;
-    case 12:
-      pPlayerAgeAttributeDescription = RemoveQuotes(tokens[1]);
-      break;
-    case 13:
-      pPlayerLevelAttributeDescription = RemoveQuotes(tokens[1]);
-      break;
-    case 14:
-      pPlayerExperienceAttributeDescription = RemoveQuotes(tokens[1]);
-      break;
-    case 15:
-      pAttackBonusAttributeDescription = RemoveQuotes(tokens[1]);
-      break;
-    case 16:
-      pAttackDamageAttributeDescription = RemoveQuotes(tokens[1]);
-      break;
-    case 17:
-      pMissleBonusAttributeDescription = RemoveQuotes(tokens[1]);
-      break;
-    case 18:
-      pMissleDamageAttributeDescription = RemoveQuotes(tokens[1]);
-      break;
-    case 19:
-      pFireResistanceAttributeDescription = RemoveQuotes(tokens[1]);
-      break;
-    case 20:
-      pAirResistanceAttributeDescription = RemoveQuotes(tokens[1]);
-      break;
-    case 21:
-      pWaterResistanceAttributeDescription = RemoveQuotes(tokens[1]);
-      break;
-    case 22:
-      pEarthResistanceAttributeDescription = RemoveQuotes(tokens[1]);
-      break;
-    case 23:
-      pMindResistanceAttributeDescription = RemoveQuotes(tokens[1]);
-      break;
-    case 24:
-      pBodyResistanceAttributeDescription = RemoveQuotes(tokens[1]);
-      break;
-    case 25:
-      pSkillPointsAttributeDescription = RemoveQuotes(tokens[1]);
-      break;  
+        test_string = strtok(NULL, "\r") + 1;
+        auto tokens = Tokenize(test_string, '\t');
+        Assert(tokens.size() == 2, "Invalid number of tokens");
+        switch (i)
+        {
+        case 0:
+        case 1:
+        case 2:
+        case 3:
+        case 4:
+        case 5:
+        case 6:
+            pAttributeDescriptions[i] = RemoveQuotes(tokens[1]);
+            break;
+        case 7:
+            pHealthPointsAttributeDescription = RemoveQuotes(tokens[1]);
+            break;
+        case 8:
+            pArmourClassAttributeDescription = RemoveQuotes(tokens[1]);
+            break;
+        case 9:
+            pSpellPointsAttributeDescription = RemoveQuotes(tokens[1]);
+            break;
+        case 10:
+            pPlayerConditionAttributeDescription = RemoveQuotes(tokens[1]);
+            break;
+        case 11:
+            pFastSpellAttributeDescription = RemoveQuotes(tokens[1]);
+            break;
+        case 12:
+            pPlayerAgeAttributeDescription = RemoveQuotes(tokens[1]);
+            break;
+        case 13:
+            pPlayerLevelAttributeDescription = RemoveQuotes(tokens[1]);
+            break;
+        case 14:
+            pPlayerExperienceAttributeDescription = RemoveQuotes(tokens[1]);
+            break;
+        case 15:
+            pAttackBonusAttributeDescription = RemoveQuotes(tokens[1]);
+            break;
+        case 16:
+            pAttackDamageAttributeDescription = RemoveQuotes(tokens[1]);
+            break;
+        case 17:
+            pMissleBonusAttributeDescription = RemoveQuotes(tokens[1]);
+            break;
+        case 18:
+            pMissleDamageAttributeDescription = RemoveQuotes(tokens[1]);
+            break;
+        case 19:
+            pFireResistanceAttributeDescription = RemoveQuotes(tokens[1]);
+            break;
+        case 20:
+            pAirResistanceAttributeDescription = RemoveQuotes(tokens[1]);
+            break;
+        case 21:
+            pWaterResistanceAttributeDescription = RemoveQuotes(tokens[1]);
+            break;
+        case 22:
+            pEarthResistanceAttributeDescription = RemoveQuotes(tokens[1]);
+            break;
+        case 23:
+            pMindResistanceAttributeDescription = RemoveQuotes(tokens[1]);
+            break;
+        case 24:
+            pBodyResistanceAttributeDescription = RemoveQuotes(tokens[1]);
+            break;
+        case 25:
+            pSkillPointsAttributeDescription = RemoveQuotes(tokens[1]);
+            break;
+        }
     }
-  }
-  
-	pClassTXT_Raw = 0;
-	pClassTXT_Raw = (char *)pEvents_LOD->LoadRaw("class.txt", 0);
-	strtok(pClassTXT_Raw, "\r");
-	for (int i=0; i<36; ++i)
-		{
-		test_string = strtok(NULL, "\r") + 1;
-    auto tokens = Tokenize(test_string, '\t');
-    Assert(tokens.size() == 3, "Invalid number of tokens");
-    pClassDescriptions[i]=RemoveQuotes(tokens[1]);
-	}
+
+    pClassTXT_Raw = 0;
+    pClassTXT_Raw = (char *)pEvents_LOD->LoadRaw("class.txt", 0);
+    strtok(pClassTXT_Raw, "\r");
+    for (int i = 0; i < 36; ++i)
+    {
+        test_string = strtok(NULL, "\r") + 1;
+        auto tokens = Tokenize(test_string, '\t');
+        Assert(tokens.size() == 3, "Invalid number of tokens");
+        pClassDescriptions[i] = RemoveQuotes(tokens[1]);
+    }
 
 
-  
-  ItemGen::PopulateSpecialBonusMap();
-  ItemGen::PopulateArtifactBonusMap();
-  ItemGen::PopulateRegularBonusMap();
-  
 
-	}
+    ItemGen::PopulateSpecialBonusMap();
+    ItemGen::PopulateArtifactBonusMap();
+    ItemGen::PopulateRegularBonusMap();
+
+
+}
 
 //----- (00456D17) --------------------------------------------------------
 void ItemsTable::SetSpecialBonus(ItemGen *pItem)
@@ -730,7 +730,7 @@
   if ( pItems[pItem->uItemID].uMaterial == MATERIAL_SPECIAL )
   {
     pItem->uEnchantmentType = pItems[pItem->uItemID]._bonus_type;
-    pItem->uSpecEnchantmentType = pItems[pItem->uItemID]._additional_value;
+    pItem->special_enchantment = (ITEM_ENCHANTMENT)pItems[pItem->uItemID]._additional_value;
     pItem->m_enchantmentStrength = pItems[pItem->uItemID]._bonus_strength;
   }
 }
@@ -878,9 +878,9 @@
 		return uBaseValue;
 	if (uEnchantmentType )
 		return uBaseValue + 100 * m_enchantmentStrength;;
-	if (uSpecEnchantmentType )
+	if (special_enchantment )
 		{
-		bonus = pItemsTable->pSpecialEnchantments[uSpecEnchantmentType].iTreasureLevel;
+		bonus = pItemsTable->pSpecialEnchantments[special_enchantment].iTreasureLevel;
 		if ( bonus > 10 )
 			return uBaseValue + bonus;
 		else
@@ -935,30 +935,30 @@
     }
     else
     {
-      if ( !uSpecEnchantmentType )
+      if ( !special_enchantment )
         return item__getname_buffer.data();
-      if ( uSpecEnchantmentType == 16 //Drain Hit Points from target.
-        || uSpecEnchantmentType == 39 //Double damage vs Demons.
-        || uSpecEnchantmentType == 40 //Double damage vs Dragons
-        || uSpecEnchantmentType == 45 //+5 Speed and Accuracy
-        || uSpecEnchantmentType == 56 //+5 Might and Endurance.
-        || uSpecEnchantmentType == 57 //+5 Intellect and Personality.
-        || uSpecEnchantmentType == 58 //Increased Value.
-        || uSpecEnchantmentType == 60 //+3 Unarmed and Dodging skills
-        || uSpecEnchantmentType == 61 //+3 Stealing and Disarm skills.
-        || uSpecEnchantmentType == 59  //Increased Weapon speed.
-        || uSpecEnchantmentType == 63 //Double Damage vs. Elves.
-        || uSpecEnchantmentType == 64 //Double Damage vs. Undead.
-        || uSpecEnchantmentType == 67 //Adds 5 points of Body damage and +2 Disarm skill.
-        || uSpecEnchantmentType == 68 ) //Adds 6-8 points of Cold damage and +5 Armor Class.
+      if ( special_enchantment == 16 //Drain Hit Points from target.
+        || special_enchantment == 39 //Double damage vs Demons.
+        || special_enchantment == 40 //Double damage vs Dragons
+        || special_enchantment == 45 //+5 Speed and Accuracy
+        || special_enchantment == 56 //+5 Might and Endurance.
+        || special_enchantment == 57 //+5 Intellect and Personality.
+        || special_enchantment == 58 //Increased Value.
+        || special_enchantment == 60 //+3 Unarmed and Dodging skills
+        || special_enchantment == 61 //+3 Stealing and Disarm skills.
+        || special_enchantment == 59  //Increased Weapon speed.
+        || special_enchantment == 63 //Double Damage vs. Elves.
+        || special_enchantment == 64 //Double Damage vs. Undead.
+        || special_enchantment == 67 //Adds 5 points of Body damage and +2 Disarm skill.
+        || special_enchantment == 68 ) //Adds 6-8 points of Cold damage and +5 Armor Class.
       {  //enchantment and name positions inverted!
         sprintf( item__getname_buffer.data(), "%s %s",
-				  pItemsTable->pSpecialEnchantments[uSpecEnchantmentType-1].pNameAdd,
+				  pItemsTable->pSpecialEnchantments[special_enchantment-1].pNameAdd,
 				  pItemsTable->pItems[uItemID].pName);
         return item__getname_buffer.data();
       }
       strcat(item__getname_buffer.data(), " ");
-	  nameModificator = pItemsTable->pSpecialEnchantments[uSpecEnchantmentType-1].pNameAdd;
+	  nameModificator = pItemsTable->pSpecialEnchantments[special_enchantment-1].pNameAdd;
     }
     strcat(item__getname_buffer.data(), nameModificator);
   }
@@ -968,7 +968,7 @@
 
 //----- (00456620) --------------------------------------------------------
 void ItemsTable::GenerateItem(int treasure_level, unsigned int uTreasureType, ItemGen *out_item)
-  {
+{
     int treasureLevelMinus1; // ebx@3
     int current_chance; // ebx@43
     int tmp_chance; // ecx@47
@@ -979,7 +979,7 @@
     unsigned int v27; // eax@89
     int v32; // ecx@91
     int v33; // eax@91
-//    unsigned int v34; // eax@97
+    //    unsigned int v34; // eax@97
     int v45; // eax@120
     int v46; // edx@120
     int j; // eax@121
@@ -994,12 +994,12 @@
 
 
     treasureLevelMinus1 = treasure_level - 1;
-    if ( uTreasureType ) //generate known treasure type
+    if (uTreasureType) //generate known treasure type
     {
         ITEM_EQUIP_TYPE   requested_equip;
         PLAYER_SKILL_TYPE requested_skill = PLAYER_SKILL_INVALID;
         switch (uTreasureType)
-            {
+        {
         case 20: requested_equip = EQUIP_SINGLE_HANDED; break;
         case 21: requested_equip = EQUIP_ARMOUR; break;
         case 22: requested_skill = PLAYER_SKILL_MISC; break;
@@ -1031,147 +1031,147 @@
             __debugbreak(); // check this condition
             requested_equip = (ITEM_EQUIP_TYPE)(uTreasureType - 1);
             break;
-            }
+        }
         memset(val_list, 0, sizeof(val_list));
         total_chance = 0;
-        j=0;
+        j = 0;
         //a2a = 1;
         if (requested_skill == PLAYER_SKILL_INVALID)  // no skill for this item needed
+        {
+            for (uint i = 1; i < 500; ++i)
             {
-            for (uint i = 1; i < 500; ++i)
+                if (pItems[i].uEquipType == requested_equip)
                 {
-                if (pItems[i].uEquipType == requested_equip)
-                    {
                     val_list[j] = i;
                     ++j;
                     total_chance += pItems[i].uChanceByTreasureLvl[treasure_level - 1];
-                    }
                 }
             }
+        }
         else  //have needed skill
-            {
+        {
             for (uint i = 1; i < 500; ++i)
-                {
+            {
                 if (pItems[i].uSkillType == requested_skill)
-                    {
+                {
                     val_list[j] = i;
                     ++j;
                     total_chance += pItems[i].uChanceByTreasureLvl[treasure_level - 1];
-                    }
                 }
             }
+        }
 
         current_chance = 0;
-        if ( total_chance )
+        if (total_chance)
         {
-          current_chance = rand() % total_chance + 1;
-          tmp_chance = 0;
-          j=0;
-          while(tmp_chance < current_chance)
-          {
-            out_item->uItemID = val_list[j];
-            tmp_chance += pItems[val_list[j]].uChanceByTreasureLvl[treasure_level - 1];
-            ++j;
-          }
+            current_chance = rand() % total_chance + 1;
+            tmp_chance = 0;
+            j = 0;
+            while (tmp_chance < current_chance)
+            {
+                out_item->uItemID = val_list[j];
+                tmp_chance += pItems[val_list[j]].uChanceByTreasureLvl[treasure_level - 1];
+                ++j;
+            }
         }
         else
         {
-          out_item->uItemID = 1;
+            out_item->uItemID = ITEM_LONGSWORD_1;
         }
     }
     else
     {
-   //artifact
-        if ( treasureLevelMinus1 == 5 )
+        //artifact
+        if (treasureLevelMinus1 == 5)
         {
-          v56 = 0;
-          for(int i=0; i<29; ++i) 
-            v56 += pParty->pIsArtifactFound[i];
-          v17 = rand() % 29;
-          if ((rand() % 100 < 5) && !pParty->pIsArtifactFound[v17] && v56 < 13)
-          {
-            pParty->pIsArtifactFound[v17] = 1;
-            out_item->uAttributes = 0;
-            out_item->uItemID = v17 + 500;
-            SetSpecialBonus(out_item);
-            return;
-          }
+            v56 = 0;
+            for (int i = 0; i < 29; ++i)
+                v56 += pParty->pIsArtifactFound[i];
+            v17 = rand() % 29;
+            if ((rand() % 100 < 5) && !pParty->pIsArtifactFound[v17] && v56 < 13)
+            {
+                pParty->pIsArtifactFound[v17] = 1;
+                out_item->uAttributes = 0;
+                out_item->uItemID = v17 + ITEM_ARTIFACT_PUCK;
+                SetSpecialBonus(out_item);
+                return;
+            }
         }
-        
+
         v57 = 0;
         v18 = rand() % this->uChanceByTreasureLvlSumm[treasure_level - 1] + 1;
         while (v57 < v18)
         {
-          ++out_item->uItemID;
-          v57 += pItems[out_item->uItemID].uChanceByTreasureLvl[treasureLevelMinus1];
+            ++out_item->uItemID;
+            v57 += pItems[out_item->uItemID].uChanceByTreasureLvl[treasureLevelMinus1];
         }
     }
-    if (out_item->GetItemEquipType() == EQUIP_POTION && out_item->uItemID != ITEM_POTION_BOTTLE )
+    if (out_item->GetItemEquipType() == EQUIP_POTION && out_item->uItemID != ITEM_POTION_BOTTLE)
     {// if it potion set potion spec
-      out_item->uEnchantmentType = 0;
-      for (int i=0; i<2; ++i)
-        out_item->uEnchantmentType += rand() % 4 + 1;
-      out_item->uEnchantmentType = out_item->uEnchantmentType * treasure_level; 
+        out_item->uEnchantmentType = 0;
+        for (int i = 0; i < 2; ++i)
+            out_item->uEnchantmentType += rand() % 4 + 1;
+        out_item->uEnchantmentType = out_item->uEnchantmentType * treasure_level;
     }
 
-    if ( out_item->uItemID == ITEM_SPELLBOOK_LIGHT_DIVINE_INTERVENTION
-        && !(unsigned __int16)_449B57_test_bit(pParty->_quest_bits, 239) )
+    if (out_item->uItemID == ITEM_SPELLBOOK_LIGHT_DIVINE_INTERVENTION
+        && !(unsigned __int16)_449B57_test_bit(pParty->_quest_bits, 239))
         out_item->uItemID = ITEM_SPELLBOOK_LIGHT_SUN_BURST;
-    if ( pItemsTable->pItems[out_item->uItemID].uItemID_Rep_St )
+    if (pItemsTable->pItems[out_item->uItemID].uItemID_Rep_St)
         out_item->uAttributes = 0;
     else
         out_item->uAttributes = 1;
 
-    if ( out_item->GetItemEquipType() != EQUIP_POTION )
-        {
-        out_item->uSpecEnchantmentType = 0;
+    if (out_item->GetItemEquipType() != EQUIP_POTION)
+    {
+        out_item->special_enchantment = ITEM_ENCHANTMENT_NULL;
         out_item->uEnchantmentType = 0;
-        }
+    }
     //try get special enhansment
     switch (out_item->GetItemEquipType())
-        {
+    {
     case EQUIP_SINGLE_HANDED:
-    case EQUIP_TWO_HANDED :   
-    case EQUIP_BOW :    
-        if ( !uBonusChanceWpSpecial[treasureLevelMinus1] )
+    case EQUIP_TWO_HANDED:
+    case EQUIP_BOW:
+        if (!uBonusChanceWpSpecial[treasureLevelMinus1])
             return;
-        if ((uint)(rand() % 100)>=uBonusChanceWpSpecial[treasureLevelMinus1])
+        if ((uint)(rand() % 100) >= uBonusChanceWpSpecial[treasureLevelMinus1])
             return;
         break;
-    case      EQUIP_ARMOUR :        
-    case      EQUIP_SHIELD :         
-    case      EQUIP_HELMET  :       
-    case      EQUIP_BELT   :          
-    case      EQUIP_CLOAK  :        
-    case      EQUIP_GAUNTLETS :      
-    case      EQUIP_BOOTS  :        
-    case      EQUIP_RING   : 
-        
-        if ( !uBonusChanceStandart[treasureLevelMinus1] )
+    case      EQUIP_ARMOUR:
+    case      EQUIP_SHIELD:
+    case      EQUIP_HELMET:
+    case      EQUIP_BELT:
+    case      EQUIP_CLOAK:
+    case      EQUIP_GAUNTLETS:
+    case      EQUIP_BOOTS:
+    case      EQUIP_RING:
+
+        if (!uBonusChanceStandart[treasureLevelMinus1])
             return;
         special_chance = rand() % 100;
-        if ( special_chance < uBonusChanceStandart[treasureLevelMinus1])
+        if (special_chance < uBonusChanceStandart[treasureLevelMinus1])
+        {
+            v26 = rand() % pEnchantmentsSumm[out_item->GetItemEquipType() - 3] + 1;
+            v27 = 0;
+            while (v27 < v26)
             {
-              v26 = rand() %pEnchantmentsSumm[out_item->GetItemEquipType()-3] + 1; 
-              v27 = 0;
-              while(v27 < v26)
-              {
                 ++out_item->uEnchantmentType;
-                v27+=pEnchantments[out_item->uEnchantmentType].to_item[out_item->GetItemEquipType()-3];
-              }
+                v27 += pEnchantments[out_item->uEnchantmentType].to_item[out_item->GetItemEquipType() - 3];
+            }
 
             v33 = rand() % (bonus_ranges[treasureLevelMinus1].maxR - bonus_ranges[treasureLevelMinus1].minR + 1);
             out_item->m_enchantmentStrength = v33 + bonus_ranges[treasureLevelMinus1].minR;
             v32 = out_item->uEnchantmentType - 1;
-            if ( v32 == 21 || v32 == 22 || v32 == 23 ) //Armsmaster skill, Dodge skill, Unarmed skill 
-                out_item->m_enchantmentStrength = out_item->m_enchantmentStrength/2;
-            if ( out_item->m_enchantmentStrength <= 0 )
+            if (v32 == 21 || v32 == 22 || v32 == 23) //Armsmaster skill, Dodge skill, Unarmed skill 
+                out_item->m_enchantmentStrength = out_item->m_enchantmentStrength / 2;
+            if (out_item->m_enchantmentStrength <= 0)
                 out_item->m_enchantmentStrength = 1;
             return;
-            
-            }
-        else if ( special_chance >= uBonusChanceStandart[treasureLevelMinus1] + uBonusChanceSpecial[treasureLevelMinus1] )
-          return;
+
+        }
+        else if (special_chance >= uBonusChanceStandart[treasureLevelMinus1] + uBonusChanceSpecial[treasureLevelMinus1])
+            return;
         break;
     case EQUIP_WAND:
         out_item->uNumCharges = rand() % 6 + out_item->GetDamageMod() + 1;
@@ -1179,38 +1179,38 @@
         return;
     default:
         return;
-        }
+    }
 
-    j=0;
-    int spc_sum=0;
+    j = 0;
+    int spc_sum = 0;
     int spc;
     memset(&val_list, 0, 3200);
-    for (unsigned int i=0; i<pSpecialEnchantments_count;++i)
+    for (unsigned int i = 0; i < pSpecialEnchantments_count; ++i)
     {
-      int tr_lv= pSpecialEnchantments[i].iTreasureLevel;
-      if ((treasure_level - 1 == 2) && ( tr_lv == 1 || tr_lv == 0 ) ||
-        (treasure_level - 1 == 3) && (tr_lv == 2 || tr_lv == 1 || tr_lv == 0) ||
-        (treasure_level - 1 == 4) && (tr_lv == 3 || tr_lv == 2 || tr_lv == 1) ||
-        (treasure_level - 1 == 5) && (tr_lv == 3)
-        )
-      {
-        spc=pSpecialEnchantments[i].to_item_apply[out_item->GetItemEquipType()];
-        spc_sum+=spc;
-        if(spc)
+        int tr_lv = pSpecialEnchantments[i].iTreasureLevel;
+        if ((treasure_level - 1 == 2) && (tr_lv == 1 || tr_lv == 0) ||
+            (treasure_level - 1 == 3) && (tr_lv == 2 || tr_lv == 1 || tr_lv == 0) ||
+            (treasure_level - 1 == 4) && (tr_lv == 3 || tr_lv == 2 || tr_lv == 1) ||
+            (treasure_level - 1 == 5) && (tr_lv == 3)
+            )
         {
-          val_list[j++]=i;  
+            spc = pSpecialEnchantments[i].to_item_apply[out_item->GetItemEquipType()];
+            spc_sum += spc;
+            if (spc)
+            {
+                val_list[j++] = i;
+            }
         }
-      }
     }
 
-    v46 = rand()%spc_sum+1;//   1  spc_sum
-    j=0;
+    v46 = rand() % spc_sum + 1;//   1  spc_sum
+    j = 0;
     v45 = 0;
-    while (v45<v46)
+    while (v45 < v46)
     {
-      ++j;
-      out_item->uSpecEnchantmentType=val_list[j];
-      v45+=pSpecialEnchantments[val_list[j]].to_item_apply[out_item->GetItemEquipType()];
+        ++j;
+        out_item->special_enchantment = (ITEM_ENCHANTMENT)val_list[j];
+        v45 += pSpecialEnchantments[val_list[j]].to_item_apply[out_item->GetItemEquipType()];
     }
 }
 
@@ -1658,7 +1658,7 @@
 
 void ItemGen::GetItemBonusSpecialEnchantment( Player* owner, CHARACTER_ATTRIBUTE_TYPE attrToGet, int* additiveBonus, int* halfSkillBonus )
 {
-  auto bonusList = ItemGen::specialBonusMap.find(this->uSpecEnchantmentType);
+  auto bonusList = ItemGen::specialBonusMap.find(this->special_enchantment);
   if (bonusList == ItemGen::specialBonusMap.end())
   {
     return;
@@ -1787,7 +1787,7 @@
         if (item_count < 6)
         {
           pParty->StandartItemsInShops[shop_index][item_count].Reset();
-          pParty->StandartItemsInShops[shop_index][item_count].uItemID = 220;  //potion bottle
+          pParty->StandartItemsInShops[shop_index][item_count].uItemID = ITEM_POTION_BOTTLE;  //potion bottle
           continue;
         }
         else
@@ -1840,7 +1840,7 @@
         if (item_count < 6)
         {
           pParty->SpecialItemsInShops[shop_index][item_count].Reset();
-          pParty->SpecialItemsInShops[shop_index][item_count].uItemID = rand() % 32 + 740;  //mscrool
+          pParty->SpecialItemsInShops[shop_index][item_count].uItemID = rand() % 32 + ITEM_RECIPE_REJUVENATION;  //mscrool
           continue;
         }
         else
@@ -1859,7 +1859,7 @@
 
 //----- (00450218) --------------------------------------------------------
 void GenerateItemsInChest()
-    {
+{
     unsigned int mapType; // eax@1
     MapInfo *currMapInfo; // esi@1
     ItemGen *currItem; // ebx@2
@@ -1875,82 +1875,82 @@
 
     mapType = pMapStats->GetMapInfo(pCurrentMapName);
     currMapInfo = &pMapStats->pInfos[mapType];
-    for(int i=1; i<20;++i)
+    for (int i = 1; i < 20; ++i)
     {
-        for(int j=0; j<140;++j)
+        for (int j = 0; j < 140; ++j)
         {
 
             currItem = &pChests[i].igChestItems[j];
-            if ( currItem->uItemID < 0 )
+            if (currItem->uItemID < 0)
             {
                 additionaItemCount = rand() % 5; //additional items in chect
-                treasureLevelBot = byte_4E8168[abs(currItem->uItemID)-1][2*currMapInfo->Treasure_prob];
-                treasureLevelTop = byte_4E8168[abs(currItem->uItemID)-1][2*currMapInfo->Treasure_prob+1];
+                treasureLevelBot = byte_4E8168[abs(currItem->uItemID) - 1][2 * currMapInfo->Treasure_prob];
+                treasureLevelTop = byte_4E8168[abs(currItem->uItemID) - 1][2 * currMapInfo->Treasure_prob + 1];
                 treasureLevelRange = treasureLevelTop - treasureLevelBot + 1;
                 resultTreasureLevel = treasureLevelBot + rand() % treasureLevelRange;  //treasure level 
-                if (resultTreasureLevel<7)
+                if (resultTreasureLevel < 7)
                 {
-                  v11 = 0;
-                  do 
-                  {
-                    whatToGenerateProb = rand() % 100;
-                    if (whatToGenerateProb<20)
-                    {
-                      currItem->Reset();
-                    }
-                    else if (whatToGenerateProb<60) //generate gold
+                    v11 = 0;
+                    do
                     {
-                      goldAmount=0;
-                      currItem->Reset();
-                      switch (resultTreasureLevel)
-                      {
-                      case 1: //small gold
-                        goldAmount = rand() % 51 + 50;
-                        currItem->uItemID = 197;
-                        break;
-                      case 2://small gold
-                        goldAmount = rand() % 101 + 100;
-                        currItem->uItemID = 197;
-                        break;
-                      case 3:  //medium
-                        goldAmount = rand() % 301 + 200;
-                        currItem->uItemID = 198;
-                        break;
-                      case 4: //medium
-                        goldAmount = rand() % 501 + 500;
-                        currItem->uItemID = 198;
-                        break;
-                      case 5: //big
-                        goldAmount = rand() % 1001 + 1000;
-                        currItem->uItemID = 199;
-                        break;
-                      case 6: //big
-                        goldAmount = rand() % 3001 + 2000;
-                        currItem->uItemID = 199;
-                        break;
-                      }
-                      currItem->SetIdentified();
-                      currItem->uSpecEnchantmentType = goldAmount;
-                    }
-                    else
-                    {
-                      pItemsTable->GenerateItem(resultTreasureLevel, 0, currItem);
-                    }
-                    v12 = 0;
-                    while ( !(pChests[i].igChestItems[v12].uItemID==0) &&(v12<140))
-                    {
-                      ++v12;
-                    }
-                    if (v12 >= 140)
-                      break;
-                    currItem=&pChests[i].igChestItems[v12];
-                    v11++;
-                  } while (v11 < additionaItemCount + 1); // + 1 because it's the item at pChests[i].igChestItems[j] and the additional ones
+                        whatToGenerateProb = rand() % 100;
+                        if (whatToGenerateProb < 20)
+                        {
+                            currItem->Reset();
+                        }
+                        else if (whatToGenerateProb < 60) //generate gold
+                        {
+                            goldAmount = 0;
+                            currItem->Reset();
+                            switch (resultTreasureLevel)
+                            {
+                            case 1:
+                                goldAmount = rand() % 51 + 50;
+                                currItem->uItemID = ITEM_GOLD_SMALL;
+                                break;
+                            case 2:
+                                goldAmount = rand() % 101 + 100;
+                                currItem->uItemID = ITEM_GOLD_SMALL;
+                                break;
+                            case 3:
+                                goldAmount = rand() % 301 + 200;
+                                currItem->uItemID = ITEM_GOLD_MEDIUM;
+                                break;
+                            case 4:
+                                goldAmount = rand() % 501 + 500;
+                                currItem->uItemID = ITEM_GOLD_MEDIUM;
+                                break;
+                            case 5:
+                                goldAmount = rand() % 1001 + 1000;
+                                currItem->uItemID = ITEM_GOLD_LARGE;
+                                break;
+                            case 6:
+                                goldAmount = rand() % 3001 + 2000;
+                                currItem->uItemID = ITEM_GOLD_LARGE;
+                                break;
+                            }
+                            currItem->SetIdentified();
+                            currItem->special_enchantment = (ITEM_ENCHANTMENT)goldAmount;
+                        }
+                        else
+                        {
+                            pItemsTable->GenerateItem(resultTreasureLevel, 0, currItem);
+                        }
+                        v12 = 0;
+                        while (!(pChests[i].igChestItems[v12].uItemID == ITEM_NULL) && (v12 < 140))
+                        {
+                            ++v12;
+                        }
+                        if (v12 >= 140)
+                            break;
+                        currItem = &pChests[i].igChestItems[v12];
+                        v11++;
+                    } while (v11 < additionaItemCount + 1); // + 1 because it's the item at pChests[i].igChestItems[j] and the additional ones
                 }
                 else
                     currItem->GenerateArtifact();
             }
-        }			
+        }
     }
 
 }
--- a/Engine/Objects/Items.h	Thu May 21 18:32:45 2015 +0600
+++ b/Engine/Objects/Items.h	Thu May 21 18:33:07 2015 +0600
@@ -3,20 +3,20 @@
 #include <map>
 #include "../NZIArray.h"
 
-enum DAMAGE_TYPE:unsigned int
-    {
-    DMGT_FIRE   = 0,
+enum DAMAGE_TYPE: unsigned int
+{
+    DMGT_FIRE = 0,
     DMGT_ELECTR = 1,
-    DMGT_COLD   = 2,
-    DMGT_EARTH      = 3,
-    DMGT_PHISYCAL= 4,
+    DMGT_COLD = 2,
+    DMGT_EARTH = 3,
+    DMGT_PHISYCAL = 4,
     DMGT_MAGICAL = 5,
     DMGT_SPIRIT = 6,
-    DMGT_MIND   = 7,
-    DMGT_BODY   = 8,
-    DMGT_LIGHT  = 9,
-    DMGT_DARK   =10
-    };
+    DMGT_MIND = 7,
+    DMGT_BODY = 8,
+    DMGT_LIGHT = 9,
+    DMGT_DARK = 10
+};
 
 
 
@@ -35,6 +35,33 @@
   ITEM_HARDENED = 0x200,
 };
 
+enum ITEM_ENCHANTMENT : unsigned int
+{
+    ITEM_ENCHANTMENT_NULL = 0,
+
+    ITEM_ENCHANTMENT_OF_COLD = 4,         // Adds 3-4 points of cold damage
+    ITEM_ENCHANTMENT_OF_FROST = 5,        // Adds 6-8 points of cold damage
+    ITEM_ENCHANTMENT_OF_ICE = 6,          // Adds 9-12 points of cold damage
+    ITEM_ENCHANTMENT_OF_SPARKS = 7,       // Adds 2-5 points of electrical damage
+    ITEM_ENCHANTMENT_OF_LIGHTNING = 8,    // Adds 4-10 points of electrical damage
+    ITEM_ENCHANTMENT_OF_THUNDERBOLTS = 9, // Adds 6-15 points of electrical damage
+    ITEM_ENCHANTMENT_OF_FIRE = 10,        // Adds 1-6 points of fire damage
+    ITEM_ENCHANTMENT_OF_FLAME = 11,       // Adds 2-12 points of fire damage
+    ITEM_ENCHANTMENT_OF_INFERNOS = 12,    // Adds 3-18 points of fire damage
+    ITEM_ENCHANTMENT_OF_POISON = 13,      // Adds 5 points of body damage
+    ITEM_ENCHANTMENT_OF_VENOM = 14,       // Adds 8 points of body damage
+    ITEM_ENCHANTMENT_OF_ACID = 15,        // Adds 12 points of body damage
+    ITEM_ENCHANTMENT_VAMPIRIC = 16,       // 20% of damage dealt given to wielder
+    ITEM_ENCHANTMENT_OF_RECOVERY = 17,    // Increases rate of Recovery
+
+    ITEM_ENCHANTMENT_OF_FORCE = 24,       // Increases Knockback
+
+    ITEM_ENCHANTMENT_40 = 40,
+    ITEM_ENCHANTMENT_OF_DARKNESS = 41,    // Vampiric and Swift
+
+    ITEM_ENCHANTMENT_OF_DRAGON = 46,      // Adds 10-20 points of fire damage and +25 Might
+};
+
 
 enum ITEM_MATERIAL
 {
@@ -47,34 +74,56 @@
 /*  330 */
 enum ITEM_TYPE
 {
+    ITEM_NULL = 0,
   ITEM_LONGSWORD_1 = 0x1,
-  ITEM_DAGGER_1 = 0xF,
-  ITEM_AXE_1 = 0x17,
-  ITEM_SPEAR_1 = 0x1F,
-  ITEM_CROSSBOW_1 = 0x2F,
-  ITEM_MACE_1 = 0x32,
-  ITEM_STAFF_1 = 0x3D,
+  ITEM_DAGGER_1 = 15,
+  ITEM_AXE_1 = 23,
+  ITEM_SPEAR_1 = 31,
+  ITEM_CROSSBOW_1 = 47,
+  ITEM_MACE_1 = 50,
+  ITEM_STAFF_1 = 61,
   ITEM_BLASTER = 64,
   ITEM_LASER_RIFLE = 65,
-  ITEM_LEATHER_1 = 0x42,
-  ITEM_CHAINMAIL_1 = 0x47,
-  ITEM_PLATE_1 = 0x4C,
-  ITEM_BUCKLER_1 = 0x54,
-  ITEM_GAUNTLETS_1 = 0x6E,
-  ITEM_BOOTS_1 = 0x73,
+  ITEM_LEATHER_1 = 66,
+  ITEM_CHAINMAIL_1 = 71,
+  ITEM_PLATE_1 = 76,
+  ITEM_BUCKLER_1 = 84,
+  ITEM_GAUNTLETS_1 = 110,
+  ITEM_BOOTS_1 = 115,
   ITEM_WAND_FIRE = 135,
   ITEM_WAND_STUN = 138,
-  ITEM_WAND_INCENERATION = 0x9F,
+  ITEM_WAND_INCENERATION = 159,
+  ITEM_160 = 160,
+  ITEM_161 = 161,
+  ITEM_162 = 162,
+  ITEM_GOLD_SMALL = 197,
+  ITEM_GOLD_MEDIUM = 198,
+  ITEM_GOLD_LARGE = 199,
   ITEM_REAGENT_WIDOWSWEEP_BERRIES = 200,
-  ITEM_TROLL_BLOOD = 0xCA,
-  ITEM_DRAGON_EYE = 0xCC,
-  ITEM_HARPY_FEATHER = 0xCF,
-  ITEM_DEVIL_ICHOR = 0xD6,
-  ITEM_OOZE_ECTOPLASM_BOTTLE = 0xD9,
+  ITEM_REAGENT_CRUSHED_ROSE_PETALS = 201,
+  ITEM_TROLL_BLOOD = 202,
+  ITEM_TROLL_RUBY = 203,
+  ITEM_DRAGON_EYE = 204,
+  ITEM_PHIMA_ROOT = 205,
+  ITEM_METEORITE_FRAGMENT = 206,
+  ITEM_HARPY_FEATHER = 207,
+  ITEM_MOONSTONE = 208,
+  ITEM_ELVISH_TOADSTOOL = 209,
+  ITEM_POPPYSNAPS = 210,
+  ITEM_FAE_DUST = 211,
+  ITEM_SULFUR = 212,
+  ITEM_GARNET = 213,
+  ITEM_DEVIL_ICHOR = 214,
+  ITEM_MUSHROOM = 215,
+  ITEM_OBSIDIAN = 216,
+  ITEM_OOZE_ENDOPLASM_VIAL = 217,
+  ITEM_MERCURY = 218,
   ITEM_REAGENT_PHILOSOPHERS_STONE = 219,
   ITEM_POTION_BOTTLE = 220,
   ITEM_POTION_CATALYST = 221,
   ITEM_POTION_CURE_WOUNDS = 222,
+  ITEM_POTION_MAGIC_POTION = 223,
+  ITEM_POTION_CURE_WEAKNESS = 224,
   ITEM_POTION_CURE_DISEASE = 225,
   ITEM_POTION_AWAKEN = 227,
   ITEM_POTION_HASTE = 228,
@@ -89,19 +138,20 @@
   ITEM_POTION_STONE_TO_FLESH = 262,
   ITEM_POTION_SLAYING_POTION = 263,
   ITEM_POTION_REJUVENATION = 271,
-  ITEM_SPELLBOOK_TORCHLIGHT = 400,//0x190
-  ITEM_SPELLBOOK_FIRE_STRIKE = 401,//0x191,
-  ITEM_SPELLBOOK_AIR_FEATHER_FALL = 0x19C,
-  ITEM_SPELLBOOK_WATER_POISON_SPRAY = 0x1A7,
-  ITEM_SPELLBOOK_EARTH_SLOW = 0x1B2,
-  ITEM_SPELLBOOK_SPIRIT_BLESS = 0x1BD,
-  ITEM_SPELLBOOK_MIND_MIND_BLAST = 0x1C8,
-  ITEM_SPELLBOOK_BODY_FIRST_AID = 0x1D3,
-  ITEM_SPELLBOOK_BODY_HEAL = 0x1D6,
-  ITEM_SPELLBOOK_BODY_BREAK_POISON = 0x1D7,
-  ITEM_SPELLBOOK_LIGHT_LIGHT_BOLT = 0x1DD,
-  ITEM_SPELLBOOK_LIGHT_SUN_BURST = 0x1E6,
-  ITEM_SPELLBOOK_LIGHT_DIVINE_INTERVENTION = 0x1E7,
+  ITEM_SPELLBOOK_TORCHLIGHT = 400,
+  ITEM_SPELLBOOK_FIRE_STRIKE = 401,
+  ITEM_SPELLBOOK_AIR_FEATHER_FALL = 412,
+  ITEM_SPELLBOOK_WATER_POISON_SPRAY = 423,
+  ITEM_SPELLBOOK_EARTH_SLOW = 434,
+  ITEM_SPELLBOOK_SPIRIT_BLESS = 445,
+  ITEM_SPELLBOOK_MIND_REMOVE_FEAR = 455,
+  ITEM_SPELLBOOK_MIND_MIND_BLAST = 456,
+  ITEM_SPELLBOOK_BODY_FIRST_AID = 467,
+  ITEM_SPELLBOOK_BODY_HEAL = 470,
+  ITEM_SPELLBOOK_BODY_BREAK_POISON = 471,
+  ITEM_SPELLBOOK_LIGHT_LIGHT_BOLT = 477,
+  ITEM_SPELLBOOK_LIGHT_SUN_BURST = 486,
+  ITEM_SPELLBOOK_LIGHT_DIVINE_INTERVENTION = 487,
   ITEM_ARTIFACT_PUCK = 500,//0x1F4,
   ITEM_ARTIFACT_IRON_FEATHER = 501,
   ITEM_ARTIFACT_WALLACE = 502,
@@ -112,7 +162,7 @@
   ITEM_ARTIFACT_GHOULSBANE = 507,//1FA
   ITEM_ARTIFACT_GIBBET = 508,//1FA
   ITEM_ARTIFACT_CHARELE = 509,//1FA
-  ITEM_ARTEFACT_ULLYSES =510, 
+  ITEM_ARTEFACT_ULLYSES = 510, 
   ITEM_ARTEFACT_HANDS_OF_THE_MASTER =511, 
   ITEM_ARTIFACT_LEAGUE_BOOTS = 512,//200
   ITEM_ARTIFACT_RULERS_RING = 513,
@@ -158,6 +208,18 @@
   ITEM_LICH_JAR_FULL = 601,
   ITEM_WETSUIT = 604,
   ITEM_LICH_JAR_EMPTY = 615,
+  ITEM_GENIE_LAMP = 616,
+
+  ITEM_RED_APPLE = 630,
+
+  ITEM_LUTE = 632,
+  ITEM_FAERIE_PIPES = 633,
+  ITEM_GRYPHONHEARTS_TRUMPET = 634,
+
+  ITEM_HORSESHOE = 646,
+
+  ITEM_TEMPLE_IN_A_BOTTLE = 650,
+
   ITEM_RECIPE_REJUVENATION = 740,
   ITEM_RECIPE_BODY_RESISTANCE = 771,
 };
@@ -251,7 +313,7 @@
   const char *GetIdentifiedName();
   void UpdateTempBonus(__int64 uTimePlayed);
   void Reset();
-  int _439DF3_get_additional_damage(int *a2, bool *vampiyr);
+  int _439DF3_get_additional_damage(DAMAGE_TYPE *a2, bool *vampiyr);
 
   ITEM_EQUIP_TYPE GetItemEquipType();
   unsigned char GetPlayerSkillType();
@@ -263,7 +325,7 @@
   int uItemID; //0
   int uEnchantmentType; //4
   int m_enchantmentStrength;  //8
-  int uSpecEnchantmentType; // 25  +5 levels //0c
+  ITEM_ENCHANTMENT special_enchantment; // 25  +5 levels //0c
                             // 16  Drain Hit Points from target.
                             // 35  Increases chance of disarming.
                             // 39  Double damage vs Demons.
--- a/Engine/Objects/NPC.cpp	Thu May 21 18:32:45 2015 +0600
+++ b/Engine/Objects/NPC.cpp	Thu May 21 18:33:07 2015 +0600
@@ -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	Thu May 21 18:32:45 2015 +0600
+++ b/Engine/Objects/Player.cpp	Thu May 21 18:33:07 2015 +0600
@@ -5,8 +5,7 @@
 #define _CRT_SECURE_NO_WARNINGS
 
 #include "Engine/Engine.h"
-
-#include "stru6.h"
+#include "Engine/stru6.h"
 
 #include "Player.h"
 #include "../Tables/PlayerFrameTable.h"
@@ -798,14 +797,14 @@
   }
   return false;
 }
-// 506128: using guessed type int areWeLoadingTexture;
+
 
 //----- (004925E6) --------------------------------------------------------
 int Player::FindFreeInventoryListSlot()
 {
   for (int i = 0; i < 126; i++ )
   {
-    if (pInventoryItemList[i].uItemID == 0)
+    if (pInventoryItemList[i].uItemID == ITEM_NULL)
     {
       return i;
     }
@@ -1573,7 +1572,7 @@
   int totalDmg = pItemsTable->pItems[itemId].uDamageMod + diceResult;
   if ( uTargetActorID > 0)
   {
-    int enchType = weapon->uSpecEnchantmentType;
+    int enchType = weapon->special_enchantment;
     if ( MonsterStats::BelongsToSupertype(uTargetActorID, MONSTER_SUPERTYPE_UNDEAD) && (enchType == 64 || itemId == ITEM_ARTIFACT_GHOULSBANE || itemId == ITEM_ARTIFACT_GIBBET || itemId == ITEM_RELIC_JUSTICE) )
     {
       totalDmg *= 2;
@@ -1688,7 +1687,7 @@
   v9 = pItemsTable->pItems[v5].uDamageMod + v17;
   if ( a2 )
   {
-    v10 = v4->uSpecEnchantmentType;
+    v10 = v4->special_enchantment;
     if ( v10 == 64 && MonsterStats::BelongsToSupertype(a2, MONSTER_SUPERTYPE_UNDEAD))
     {
       v9 *= 2;
@@ -1719,7 +1718,7 @@
 
   ItemGen* mainHandItem = GetMainHandItem();
 
-  if (mainHandItem != nullptr && ( mainHandItem->uItemID >= 135 ) && ( mainHandItem->uItemID <= 159 ))
+  if (mainHandItem != nullptr && (mainHandItem->uItemID >= ITEM_WAND_FIRE) && (mainHandItem->uItemID <= ITEM_WAND_INCENERATION))
   {
     strcpy(player__getmeleedamagestring_static_buff, pGlobalTXT_LocalizationStrings[595]); //"Wand"
     return player__getmeleedamagestring_static_buff;
@@ -1898,7 +1897,7 @@
   for (uint i = 0; i < 16; ++i)
   {
     if (HasItemEquipped((ITEM_EQUIP_TYPE)i) &&
-      GetNthEquippedIndexItem(i)->uSpecEnchantmentType == uEnchantment)
+      GetNthEquippedIndexItem(i)->special_enchantment == uEnchantment)
       return true;
   }
   return false;
@@ -2030,10 +2029,10 @@
         enchBonusSum += rand() % StealingEnchantmentBonusForSkill[stealingMastery] + 1;
       if ( actroPtr->ActorHasItems[3].GetItemEquipType() != EQUIP_GOLD )
         return 2;
-      enchTypePtr = &actroPtr->ActorHasItems[3].uSpecEnchantmentType;
+      enchTypePtr = (int *)&actroPtr->ActorHasItems[3].special_enchantment;
       if ( (int)enchBonusSum >= *enchTypePtr )
       {
-        actroPtr->ActorHasItems[3].uItemID = 0;
+        actroPtr->ActorHasItems[3].uItemID = ITEM_NULL;
         *enchTypePtr = 0;
       }
       else
@@ -2101,9 +2100,7 @@
     return 2;
   }
 }
-// 4EDEA0: using guessed type int dword_4EDEA0[];
-// 4EDEB4: using guessed type int dword_4EDEB4[];
-// 4EDEC4: using guessed type int dword_4EDEC4[];
+
 
 //----- (0048DBB9) --------------------------------------------------------
 void Player::Heal(int amount)
@@ -2195,6 +2192,7 @@
       v6 = GetActualWillpower();
       v11 = GetParameterBonus(v6);
       break;
+
     case SPECIAL_ATTACK_WEAK:
     case SPECIAL_ATTACK_SLEEP:
     case SPECIAL_ATTACK_DRUNK:
@@ -2206,14 +2204,17 @@
       v6 = GetActualEndurance();
       v11 = GetParameterBonus(v6);
       break;
+
     case SPECIAL_ATTACK_INSANE:
     case SPECIAL_ATTACK_PARALYZED:
     case SPECIAL_ATTACK_FEAR:
       v11 = GetActualResistance(CHARACTER_ATTRIBUTE_RESIST_MIND);
       break;
+
     case SPECIAL_ATTACK_PETRIFIED:
       v11 = GetActualResistance(CHARACTER_ATTRIBUTE_RESIST_EARTH);
       break;
+
     case SPECIAL_ATTACK_POISON_WEAK:
     case SPECIAL_ATTACK_POISON_MEDIUM:
     case SPECIAL_ATTACK_POISON_SEVERE:
@@ -2221,11 +2222,13 @@
     case SPECIAL_ATTACK_ERADICATED:
       v11 = GetActualResistance(CHARACTER_ATTRIBUTE_RESIST_BODY);
       break;
+
     case SPECIAL_ATTACK_MANA_DRAIN:
       v8 = GetActualWillpower();
       v10 = GetActualIntelligence();
       v11 = (GetParameterBonus(v10) + GetParameterBonus(v8)) / 2;
       break;
+
     case SPECIAL_ATTACK_BREAK_ANY:
       for (int i = 0; i < 138; i++)
       {
@@ -2238,6 +2241,7 @@
       v48 = &this->pInventoryItemList[v46[rand() % v4]];
       v11 = 3 * (pItemsTable->pItems[v48->uItemID].uMaterial + v48->GetDamageMod());
       break;
+
     case SPECIAL_ATTACK_BREAK_ARMOR:
       for (int i = 0; i < 16; i++ )
       {
@@ -2254,6 +2258,7 @@
       v48 = &this->pInventoryItemList[v46[rand() % v4]];
       v11 = 3 * (pItemsTable->pItems[v48->uItemID].uMaterial + v48->GetDamageMod());
       break;
+
     case SPECIAL_ATTACK_BREAK_WEAPON:
       for (int i = 0; i < 16; i++ )
       {
@@ -2271,6 +2276,7 @@
       v48 = &this->pInventoryItemList[v46[rand() % v4]];
       v11 = 3 * (pItemsTable->pItems[v48->uItemID].uMaterial + v48->GetDamageMod());
       break;
+
     case SPECIAL_ATTACK_STEAL:
       for ( int i = 0; i < 126; i++ )
       {
@@ -2290,6 +2296,7 @@
       v6 = GetActualAccuracy();
       v11 = GetParameterBonus(v6);
       break;
+
     default:
       v11 = 0;
       break;
@@ -2316,96 +2323,112 @@
         pEngine->pStru6Instance->SetPlayerBuffAnim(0x99u, v3);
         return 1;
         break;
+
       case SPECIAL_ATTACK_WEAK:
         SetCondition(Condition_Weak, 1);
         pAudioPlayer->PlaySound(SOUND_star1, 0, 0, -1, 0, 0, 0, 0);
         pEngine->pStru6Instance->SetPlayerBuffAnim(0x99, v3);
         return 1;
         break;
+
       case SPECIAL_ATTACK_SLEEP:
         SetCondition(Condition_Sleep, 1);
         pAudioPlayer->PlaySound(SOUND_star1, 0, 0, -1, 0, 0, 0, 0);
         pEngine->pStru6Instance->SetPlayerBuffAnim(0x99, v3);
         return 1;
         break;
+
       case SPECIAL_ATTACK_DRUNK:
         SetCondition(Condition_Drunk, 1);
         pAudioPlayer->PlaySound(SOUND_star1, 0, 0, -1, 0, 0, 0, 0);
         pEngine->pStru6Instance->SetPlayerBuffAnim(0x99, v3);
         return 1;
         break;
+
       case SPECIAL_ATTACK_INSANE:
         SetCondition(Condition_Insane, 1);
         pAudioPlayer->PlaySound(SOUND_star4, 0, 0, -1, 0, 0, 0, 0);
         pEngine->pStru6Instance->SetPlayerBuffAnim(0x99, v3);
         return 1;
         break;
+
       case SPECIAL_ATTACK_POISON_WEAK:
         SetCondition(Condition_Poison_Weak, 1);
         pAudioPlayer->PlaySound(SOUND_star2, 0, 0, -1, 0, 0, 0, 0);
         pEngine->pStru6Instance->SetPlayerBuffAnim(0x99, v3);
         return 1;
         break;
+
       case SPECIAL_ATTACK_POISON_MEDIUM:
         SetCondition(Condition_Poison_Medium, 1);
         pAudioPlayer->PlaySound(SOUND_star2, 0, 0, -1, 0, 0, 0, 0);
         pEngine->pStru6Instance->SetPlayerBuffAnim(0x99, v3);
         return 1;
         break;
+
       case SPECIAL_ATTACK_POISON_SEVERE:
         SetCondition(Condition_Poison_Severe, 1);
         pAudioPlayer->PlaySound(SOUND_star2, 0, 0, -1, 0, 0, 0, 0);
         pEngine->pStru6Instance->SetPlayerBuffAnim(0x99, v3);
         return 1;
         break;
+
       case SPECIAL_ATTACK_DISEASE_WEAK:
         SetCondition(Condition_Disease_Weak, 1);
         pAudioPlayer->PlaySound(SOUND_star2, 0, 0, -1, 0, 0, 0, 0);
         pEngine->pStru6Instance->SetPlayerBuffAnim(0x99, v3);
         return 1;
         break;
+
       case SPECIAL_ATTACK_DISEASE_MEDIUM:
         SetCondition(Condition_Disease_Medium, 1);
         pAudioPlayer->PlaySound(SOUND_star2, 0, 0, -1, 0, 0, 0, 0);
         pEngine->pStru6Instance->SetPlayerBuffAnim(0x99, v3);
         return 1;
         break;
+
       case SPECIAL_ATTACK_DISEASE_SEVERE:
         SetCondition(Condition_Disease_Severe, 1);
         pAudioPlayer->PlaySound(SOUND_star2, 0, 0, -1, 0, 0, 0, 0);
         pEngine->pStru6Instance->SetPlayerBuffAnim(0x99, v3);
         return 1;
         break;
+
       case SPECIAL_ATTACK_PARALYZED:
         SetCondition(Condition_Paralyzed, 1);
         pAudioPlayer->PlaySound(SOUND_star4, 0, 0, -1, 0, 0, 0, 0);
         pEngine->pStru6Instance->SetPlayerBuffAnim(0x99u, v3);
         return 1;
         break;
+
       case SPECIAL_ATTACK_UNCONSCIOUS:
         SetCondition(Condition_Unconcious, 1);
         pAudioPlayer->PlaySound(SOUND_star4, 0, 0, -1, 0, 0, 0, 0);
         pEngine->pStru6Instance->SetPlayerBuffAnim(0x99u, v3);
         return 1;
         break;
+
       case SPECIAL_ATTACK_DEAD:
         SetCondition(Condition_Dead, 1);
         pAudioPlayer->PlaySound(SOUND_eradicate, 0, 0, -1, 0, 0, 0, 0);
         pEngine->pStru6Instance->SetPlayerBuffAnim(0x99u, v3);
         return 1;
         break;
+
       case SPECIAL_ATTACK_PETRIFIED:
         SetCondition(Condition_Pertified, 1);
         pAudioPlayer->PlaySound(SOUND_eradicate, 0, 0, -1, 0, 0, 0, 0);
         pEngine->pStru6Instance->SetPlayerBuffAnim(0x99u, v3);
         return 1;
         break;
+
       case SPECIAL_ATTACK_ERADICATED:
         SetCondition(Condition_Eradicated, 1);
         pAudioPlayer->PlaySound(SOUND_eradicate, 0, 0, -1, 0, 0, 0, 0);
         pEngine->pStru6Instance->SetPlayerBuffAnim(0x99u, v3);
         return 1;
         break;
+
       case SPECIAL_ATTACK_BREAK_ANY:
       case SPECIAL_ATTACK_BREAK_ARMOR:
       case SPECIAL_ATTACK_BREAK_WEAPON:
@@ -2418,6 +2441,7 @@
         pEngine->pStru6Instance->SetPlayerBuffAnim(0x99u, v3);
         return 1;
         break;
+
       case SPECIAL_ATTACK_STEAL:
         PlaySound(SPEECH_40, 0);
         v27 = pActor->ActorHasItems;
@@ -2436,6 +2460,7 @@
         pEngine->pStru6Instance->SetPlayerBuffAnim(0x99u, v3);
         return 1;
         break;
+
       case SPECIAL_ATTACK_AGING:
         PlaySound(SPEECH_42, 0);
         ++this->sAgeModifier;
@@ -2443,6 +2468,7 @@
         pEngine->pStru6Instance->SetPlayerBuffAnim(0x99u, v3);
         return 1;
         break;
+
       case SPECIAL_ATTACK_MANA_DRAIN:
         PlaySound(SPEECH_41, 0);
         this->sMana = 0;
@@ -2450,12 +2476,14 @@
         pEngine->pStru6Instance->SetPlayerBuffAnim(0x99u, v3);
         return 1;
         break;
+
       case SPECIAL_ATTACK_FEAR:
         SetCondition(Condition_Fear, 1);
         pAudioPlayer->PlaySound(SOUND_star1, 0, 0, -1, 0, 0, 0, 0);
         pEngine->pStru6Instance->SetPlayerBuffAnim(0x99u, v3);
         return 1;
         break;
+
       default:
         return 0;
     }
@@ -2580,9 +2608,9 @@
   uint weapon_enchantment_recovery_reduction = 0;
   if ( weapon  )
   {
-    if (weapon->uSpecEnchantmentType == 59 ||
-        weapon->uSpecEnchantmentType == 41 ||
-        weapon->uSpecEnchantmentType == 500)
+    if (weapon->special_enchantment == 59 ||
+        weapon->special_enchantment == 41 ||
+        weapon->special_enchantment == 500)
       weapon_enchantment_recovery_reduction = 20;
   }
 
@@ -2854,7 +2882,7 @@
 {
   int v3; // qax@1
 
-  v3 = (int)(dt * GetSpecialItemBonus(17) * 0.01 + dt);
+  v3 = (int)(dt * GetSpecialItemBonus(ITEM_ENCHANTMENT_OF_RECOVERY) * 0.01 + dt);
 
   //Log::Warning(L"Recover(dt = %u/%u - %u", dt, (uint)v3, (uint)uTimeToRecovery);
 
@@ -2920,20 +2948,22 @@
 }
 
 //----- (0048EA46) --------------------------------------------------------
-int Player::GetSpecialItemBonus( int enchantmentId )
+int Player::GetSpecialItemBonus(ITEM_ENCHANTMENT enchantment)
 {
   for (int i = EQUIP_SINGLE_HANDED; i < EQUIP_BOOK; ++i )
   {
     if ( HasItemEquipped((ITEM_EQUIP_TYPE)i) )
     {
-      if (enchantmentId == 17)
+        if (enchantment == ITEM_ENCHANTMENT_OF_RECOVERY)
       {
-        if ((GetNthEquippedIndexItem(i)->uSpecEnchantmentType == 17) || (GetNthEquippedIndexItem(i)->uItemID == 533)) //Elven Chainmail+Increases rate of Recovery
-          return 50;
+          if (GetNthEquippedIndexItem(i)->special_enchantment == ITEM_ENCHANTMENT_OF_RECOVERY
+              || (GetNthEquippedIndexItem(i)->uItemID == ITEM_ELVEN_CHAINMAIL)
+          )
+            return 50;
       }
-      if (enchantmentId == 24) 
+        if (enchantment == ITEM_ENCHANTMENT_OF_FORCE)
       {
-        if (GetNthEquippedIndexItem(i)->uSpecEnchantmentType == 24) //Increased Knockback.
+            if (GetNthEquippedIndexItem(i)->special_enchantment == ITEM_ENCHANTMENT_OF_FORCE)
           return 5;
       }
     }
@@ -4299,11 +4329,11 @@
       return;
   if ( pParty->pPickedItem.GetItemEquipType() == EQUIP_REAGENT )
   {
-    if ( pParty->pPickedItem.uItemID == 160 )
+      if (pParty->pPickedItem.uItemID == ITEM_161)
     { 
       playerAffected->SetCondition(Condition_Poison_Weak, 1);
     }
-    else if ( pParty->pPickedItem.uItemID == 161 )
+      else if (pParty->pPickedItem.uItemID == ITEM_161)
     {
       new_mana_val = playerAffected->sMana;
       new_mana_val += 2;
@@ -4311,7 +4341,7 @@
         new_mana_val = playerAffected->GetMaxMana();
       playerAffected->PlaySound(SPEECH_36, 0);
     }
-    else if ( pParty->pPickedItem.uItemID == 162 )
+      else if (pParty->pPickedItem.uItemID == ITEM_162)
     {
       playerAffected->Heal(2);
       playerAffected->PlaySound(SPEECH_36, 0);
@@ -4672,7 +4702,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
     {
@@ -4775,7 +4805,7 @@
   }
   else
   {
-    if (pParty->pPickedItem.uItemID == 616) //Genie Lamp
+      if (pParty->pPickedItem.uItemID == ITEM_GENIE_LAMP)
     {
       thisa = pParty->uCurrentMonthWeek + 1;
       if ( pParty->uCurrentMonth >= 7 )
@@ -4885,34 +4915,34 @@
       }
       return;
       }
-      else if ( pParty->pPickedItem.uItemID == 630 ) //Red Apple
+      else if (pParty->pPickedItem.uItemID == ITEM_RED_APPLE)
       {
           Party::GiveFood(1);
           pAudioPlayer->PlaySound(SOUND_eat, 0, 0, -1, 0, 0, 0, 0);
       }
-      else if ( pParty->pPickedItem.uItemID == 632 ) //Lute
+      else if (pParty->pPickedItem.uItemID == ITEM_LUTE)
       {
         pAudioPlayer->PlaySound(SOUND_luteguitar,  0, 0, -1, 0, 0, 0, 0);
         return;
       }
-      else if ( pParty->pPickedItem.uItemID == 633 ) //Faerie Pipes
+      else if (pParty->pPickedItem.uItemID == ITEM_FAERIE_PIPES)
       {
         pAudioPlayer->PlaySound(SOUND_panflute,  0, 0, -1, 0, 0, 0, 0);
         return;
       }
-      else if ( pParty->pPickedItem.uItemID == 634 ) //Gryphonheart's Trumpet
+      else if (pParty->pPickedItem.uItemID == ITEM_GRYPHONHEARTS_TRUMPET)
       {
         pAudioPlayer->PlaySound(SOUND_trumpet,  0, 0, -1, 0, 0, 0, 0);
         return;
       }
-      else if ( pParty->pPickedItem.uItemID == 646 ) //Horseshoe
+      else if (pParty->pPickedItem.uItemID == ITEM_HORSESHOE)
       {
         pEngine->pStru6Instance->SetPlayerBuffAnim(SPELL_QUEST_COMPLETED, player_num - 1);
         v5 = PID(OBJECT_Player, player_num + 49);
         pAudioPlayer->PlaySound(SOUND_quest, v5, 0, -1, 0, 0, 0, 0);
         playerAffected->AddVariable(VAR_NumSkillPoints, 2);
       }
-      else if ( pParty->pPickedItem.uItemID == 650 ) //Temple in a Bottle
+      else if (pParty->pPickedItem.uItemID == ITEM_TEMPLE_IN_A_BOTTLE)
       {
         TeleportToNWCDungeon();
         return;
@@ -8149,8 +8179,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/Player.h	Thu May 21 18:32:45 2015 +0600
+++ b/Engine/Objects/Player.h	Thu May 21 18:33:07 2015 +0600
@@ -538,7 +538,7 @@
   void RandomizeName();
   unsigned int GetMajorConditionIdx();
   int GetParameterBonus(int player_parameter);
-  int GetSpecialItemBonus(int enchantmentId);
+  int GetSpecialItemBonus(ITEM_ENCHANTMENT enchantment);
   int GetItemsBonus(enum CHARACTER_ATTRIBUTE_TYPE attr, bool a3 = false);
   int GetMagicalBonus(enum CHARACTER_ATTRIBUTE_TYPE a2);
   int GetActualSkillLevel(PLAYER_SKILL_TYPE uSkillType);
--- a/Engine/Objects/SpriteObject.cpp	Thu May 21 18:32:45 2015 +0600
+++ b/Engine/Objects/SpriteObject.cpp	Thu May 21 18:33:07 2015 +0600
@@ -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.special_enchantment != 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	Thu May 21 18:32:45 2015 +0600
+++ b/Engine/Objects/SpriteObject.h	Thu May 21 18:33:07 2015 +0600
@@ -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	Thu May 21 18:32:45 2015 +0600
+++ b/Engine/Party.cpp	Thu May 21 18:33:07 2015 +0600
@@ -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/Serialization/LegacyImages.cpp	Thu May 21 18:32:45 2015 +0600
+++ b/Engine/Serialization/LegacyImages.cpp	Thu May 21 18:33:07 2015 +0600
@@ -244,7 +244,7 @@
     this->uItemID = item->uItemID;
     this->uEnchantmentType = item->uEnchantmentType;
     this->m_enchantmentStrength = item->m_enchantmentStrength;
-    this->uSpecEnchantmentType = item->uSpecEnchantmentType;
+    this->special_enchantment = item->special_enchantment;
     this->uNumCharges = item->uNumCharges;
     this->uAttributes = item->uAttributes;
     this->uBodyAnchor = item->uBodyAnchor;
@@ -259,7 +259,7 @@
     item->uItemID = this->uItemID;
     item->uEnchantmentType = this->uEnchantmentType;
     item->m_enchantmentStrength = this->m_enchantmentStrength;
-    item->uSpecEnchantmentType = this->uSpecEnchantmentType;
+    item->special_enchantment = (ITEM_ENCHANTMENT)this->special_enchantment;
     item->uNumCharges = this->uNumCharges;
     item->uAttributes = this->uAttributes;
     item->uBodyAnchor = this->uBodyAnchor;
--- a/Engine/Serialization/LegacyImages.h	Thu May 21 18:32:45 2015 +0600
+++ b/Engine/Serialization/LegacyImages.h	Thu May 21 18:33:07 2015 +0600
@@ -47,7 +47,7 @@
     /* 00 */ int uItemID;
     /* 04 */ int uEnchantmentType;
     /* 08 */ int m_enchantmentStrength;
-    /* 0C */ int uSpecEnchantmentType;
+    /* 0C */ int special_enchantment;
     // 25  +5 levels
     // 16  Drain Hit Points from target.
     // 35  Increases chance of disarming.
--- a/Engine/Spells/CastSpellInfo.cpp	Thu May 21 18:32:45 2015 +0600
+++ b/Engine/Spells/CastSpellInfo.cpp	Thu May 21 18:33:07 2015 +0600
@@ -1,16 +1,15 @@
 #define _CRTDBG_MAP_ALLOC
+#define _CRT_SECURE_NO_WARNINGS
 #include <stdlib.h>
 #include <crtdbg.h>
 
-#define _CRT_SECURE_NO_WARNINGS
-
 #include "Engine/Engine.h"
 
 #include "CastSpellInfo.h"
 #include "../Objects/Actor.h"
 #include "../Party.h"
 #include "IO/Mouse.h"
-#include "../../stru6.h"
+#include "Engine/stru6.h"
 #include "GUI/GUIWindow.h"
 #include "Media/Audio/AudioPlayer.h"
 #include "../Graphics/Outdoor.h"
@@ -138,7 +137,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 +162,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 +266,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 +284,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 +302,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 +318,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 +374,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 +415,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 +447,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 +477,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 +522,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 +558,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 +594,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 +676,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 +702,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;
@@ -745,12 +744,12 @@
         v730c->UpdateTempBonus(pParty->uTimePlayed);
         if ( v730c->uItemID < 64 || v730c->uItemID > 65 
          && !v730c->IsBroken()
-         && !v730c->uSpecEnchantmentType
+         && !v730c->special_enchantment
          && !v730c->uEnchantmentType
          && ( _item->uEquipType == EQUIP_SINGLE_HANDED || _item->uEquipType == EQUIP_TWO_HANDED || _item->uEquipType == EQUIP_BOW)
          && !pItemsTable->IsMaterialNonCommon(v730c) )
         {
-          v730c->uSpecEnchantmentType = amount;
+            v730c->special_enchantment = (ITEM_ENCHANTMENT)amount;
           if ( skill_level != 4 )
           {
             v730c->uExpireTime = pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)duration << 7) * 0.033333335);
@@ -915,7 +914,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 +1051,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 +1093,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 +1112,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 +1168,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 +1317,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 +1393,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 +1417,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;
@@ -1542,7 +1541,7 @@
         ItemDesc *_v725 = &pItemsTable->pItems[v245->uItemID];
         if ((skill_level == 1 || skill_level == 2 /*&& _v725->uEquipType > EQUIP_BOW*/ || skill_level == 3 || skill_level == 4) && 
             v245->uItemID <= 134 &&
-            v245->uSpecEnchantmentType == 0 && v245->uEnchantmentType == 0 &&
+            v245->special_enchantment == 0 && v245->uEnchantmentType == 0 &&
             v245->m_enchantmentStrength== 0 && !v245->IsBroken() ) //  
         {
           if ( (v245->GetValue() < 450 && ( skill_level == 1 || skill_level == 2 ))
@@ -1618,7 +1617,7 @@
                   }
                   v262 = rand() % v725;
                   v263 = v679;
-                  v245->uSpecEnchantmentType = v679[0];
+                  v245->special_enchantment = (ITEM_ENCHANTMENT)v679[0];
                   v264 = pItemsTable->pSpecialEnchantments[*v263].to_item_apply[v245->GetItemEquipType() + 4];
                   v265 = v262 + 1;
                   if ( v264 < v265 )
@@ -1658,15 +1657,15 @@
                   }
                   v282 = rand() % _v733;
                   v283 = v679;
-                  v245->uSpecEnchantmentType = v679[0];
+                  v245->special_enchantment = (ITEM_ENCHANTMENT)v679[0];
                   v284 = pItemsTable->pSpecialEnchantments[*v283].to_item_apply[v245->GetItemEquipType() ];
                   v285 = v282 + 1;
                   for ( l = v679; v284 < v285; ++l )
                   {
-                    v245->uSpecEnchantmentType = *(l+1);
+                      v245->special_enchantment = (ITEM_ENCHANTMENT)*(l + 1);
                     v284 += pItemsTable->pSpecialEnchantments[*(l+1)].to_item_apply[v245->GetItemEquipType()];
                   }
-                  ++v245->uSpecEnchantmentType;
+                  v245->special_enchantment = (ITEM_ENCHANTMENT)(v245->special_enchantment + 1);
                   v245->uAttributes |= 0x20u;
                   _50C9A8_item_enchantment_timer = 256;
                   spell_sound_flag = true;
@@ -1726,7 +1725,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 +1760,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 +1796,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 +1944,9 @@
           break;
         int mon_num = pRenderer->_466_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;
@@ -2149,7 +2149,7 @@
             pActors[mon_id].SetRandomGoldIfTheresNoItem();
           int gold_num = 0;
           if ( pItemsTable->pItems[pActors[mon_id].ActorHasItems[3].uItemID].uEquipType == EQUIP_GOLD )
-            gold_num = pActors[mon_id].ActorHasItems[3].uSpecEnchantmentType;
+            gold_num = pActors[mon_id].ActorHasItems[3].special_enchantment;
           ItemGen item;
           item.Reset();
           if (pActors[mon_id].uCarriedItemID)
@@ -2183,7 +2183,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 +2229,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 +2269,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 +2301,9 @@
           break;
         int mon_num = pRenderer->_466_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 +2372,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.special_enchantment, 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 +2393,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 +2588,12 @@
           break;
         pEngine->GetStru6()->FadeScreen__like_Turn_Undead_and_mb_Armageddon(0xAFF0A, 192);
         int mon_num = pRenderer->_466_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 +2693,12 @@
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           break;
         int mon_num = pRenderer->_466_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 +2866,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;
@@ -2915,7 +2919,7 @@
         item->UpdateTempBonus(pParty->uTimePlayed);
         if ( item->uItemID >= 64 && item->uItemID <= 65//blasters
             || LOBYTE(item->uAttributes) & 2
-            || item->uSpecEnchantmentType != 0
+            || item->special_enchantment != 0
             || item->uEnchantmentType != 0
             || pItemsTable->pItems[item->uItemID].uEquipType != EQUIP_SINGLE_HANDED 
             && pItemsTable->pItems[item->uItemID].uEquipType != EQUIP_TWO_HANDED
@@ -2930,7 +2934,7 @@
           pCastSpell->uSpellID = 0;
           continue;
         }
-        item->uSpecEnchantmentType = 16;
+        item->special_enchantment = ITEM_ENCHANTMENT_VAMPIRIC;
         if ( skill_level != 4 )
         {
           item->uExpireTime = pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)duration << 7) * 0.033333335);
@@ -2955,7 +2959,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 +3024,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 +3139,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 +3219,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 +3227,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 +3241,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 +3282,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 +3295,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 +3317,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 +3363,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 +3401,7 @@
           //goto LABEL_24;
           if ( v11 ^ v12 )
           {
-            a5 |= 0x0002;
+              flags |= ON_CAST_WholeParty_BigImprovementAnim;
             break;
           }
           break;
@@ -3421,7 +3417,7 @@
           //goto LABEL_24;
           if ( v11 ^ v12 )
           {
-            a5 |= 0x0002;
+              flags |= ON_CAST_WholeParty_BigImprovementAnim;
             break;
           }
           break;
@@ -3437,7 +3433,7 @@
           if ( v11 ^ v12 )
             //goto LABEL_25;
           {
-            a5 |= 0x0002;
+              flags |= ON_CAST_WholeParty_BigImprovementAnim;
             break;
           }
           break;
@@ -3453,53 +3449,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 +3488,7 @@
         pParty->sub_421B2C_PlaceInInventory_or_DropPickedItem();
         return;
       }
-      if ( a5 & 8 )
+        if (flags & ON_CAST_TargetCrosshair)
       {
         if ( pGUIWindow_CastTargetedSpell )
           return;
@@ -3521,7 +3498,7 @@
         pParty->sub_421B2C_PlaceInInventory_or_DropPickedItem();
         return;
       }
-      if ( a5 & 0x40 )
+        if (flags & ON_CAST_Telekenesis)
       {
         if ( pGUIWindow_CastTargetedSpell )
           return;
@@ -3531,7 +3508,7 @@
         pParty->sub_421B2C_PlaceInInventory_or_DropPickedItem();
         return;
       }
-      if ( (char)a5 < 0 )
+        if (flags & ON_CAST_Enchantment)
       {
         if ( pGUIWindow_CastTargetedSpell )
           return;
@@ -3544,7 +3521,7 @@
         pParty->sub_421B2C_PlaceInInventory_or_DropPickedItem();
         return;
       }
-      if ( HIBYTE(a5) & 1 )
+        if (flags & ON_CAST_MonsterSparkles)
       {
         if ( pGUIWindow_CastTargetedSpell )
           return;
@@ -3556,7 +3533,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	Thu May 21 18:32:45 2015 +0600
+++ b/Engine/Spells/CastSpellInfo.h	Thu May 21 18:33:07 2015 +0600
@@ -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	Thu May 21 18:32:45 2015 +0600
+++ b/Engine/Spells/Spells.cpp	Thu May 21 18:33:07 2015 +0600
@@ -1,28 +1,27 @@
 #define _CRTDBG_MAP_ALLOC
+#define _CRT_SECURE_NO_WARNINGS
 #include <stdlib.h>
 #include <crtdbg.h>
-
-#define _CRT_SECURE_NO_WARNINGS
 #include <stdlib.h>
 
 #include "Engine/Engine.h"
+#include "Engine/LOD.h"
+#include "Engine/texts.h"
+#include "Engine/stru6.h"
+#include "Engine/Graphics/Overlays.h"
+#include "Engine/Graphics/Indoor.h"
+#include "Engine/Objects/SpriteObject.h"
+#include "Engine/Objects/ObjectList.h"
+#include "Engine/Objects/Actor.h"
 
 #include "Spells.h"
-#include "Engine/Graphics/Overlays.h"
-#include "../LOD.h"
-#include "../texts.h"
-
 #include "../Party.h"
 #include "../OurMath.h"
-#include "Engine/Objects/SpriteObject.h"
-#include "Engine/Objects/ObjectList.h"
-#include "Engine/Graphics/Indoor.h"
+
 #include "Media/Audio/AudioPlayer.h"
-#include "Engine/Objects/Actor.h"
-#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 +31,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 +281,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 +520,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	Thu May 21 18:32:45 2015 +0600
+++ b/Engine/Spells/Spells.h	Thu May 21 18:33:07 2015 +0600
@@ -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);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Engine/stru6.cpp	Thu May 21 18:33:07 2015 +0600
@@ -0,0 +1,2005 @@
+#define _CRTDBG_MAP_ALLOC
+#include <stdlib.h>
+#include <crtdbg.h>
+
+#define _CRT_SECURE_NO_WARNINGS
+
+#include "Engine/Engine.h"
+
+#include "stru6.h"
+
+#include "Engine/Graphics/LightmapBuilder.h"
+#include "Engine/Objects/SpriteObject.h"
+#include "Engine/Graphics/ParticleEngine.h"
+#include "Engine/LOD.h"
+#include "Engine/Graphics/Sprites.h"
+#include "Engine/Objects/ObjectList.h"
+#include "Engine/Objects/Actor.h"
+#include "Engine/Random.h"
+#include "Engine/Tables/IconFrameTable.h"
+#include "Engine/Timer.h"
+#include "Engine/Graphics/Viewport.h"
+#include "Engine/Graphics/Overlays.h"
+#include "Engine/stru160.h"
+#include "Engine/OurMath.h"
+#include "Engine/Graphics/Lights.h"
+#include "Engine/Graphics/Indoor.h"
+
+
+
+
+//----- (004A7063) --------------------------------------------------------
+unsigned int ModulateColor(unsigned int diffuse, float multiplier)
+{
+  float alpha = multiplier * ((diffuse >> 24) & 0xFF);
+  int   a = (int)floorf(alpha + 0.5f);
+  a = max(0, min(255, a));
+
+  float red = multiplier * ((diffuse >> 16) & 0xFF);
+  int   r = (int)floorf(red + 0.5f);
+  r = max(0, min(255, r));
+  
+  float green = multiplier * ((diffuse >> 8) & 0xFF);
+  int   g = (int)floorf(green + 0.5f);
+  g = max(0, min(255, g));
+  
+  float blue = multiplier * ((diffuse >> 0) & 0xFF);
+  int   b = (int)floorf(blue + 0.5f);
+  b = max(0, min(255, b));
+
+  return (a << 24) | (r << 16) | (g << 8) | b;
+}
+
+
+//----- (0042620A) --------------------------------------------------------
+bool sr_42620A(RenderVertexSoft *p)
+{
+//  __int16 v1; // fps@1
+  unsigned __int8 v2; // c0@2
+  char v3; // c2@2
+  unsigned __int8 v4; // c3@2
+//  bool result; // eax@2
+  unsigned __int8 v6; // c0@4
+  char v7; // c2@4
+  unsigned __int8 v8; // c3@4
+  unsigned __int8 v9; // c0@6
+  char v10; // c2@6
+  unsigned __int8 v11; // c3@6
+  double v12; // st6@7
+  float v13; // ST04_4@7
+  float v14; // ST00_4@7
+  double v15; // st7@7
+  double v16; // st6@8
+  float v17; // ST04_4@8
+  float v18; // ST00_4@8
+  double v19; // st7@8
+
+  //UNDEF(v1);
+  if ( p->vWorldViewPosition.x < 300.0
+    || (v2 = 300.0 < p[1].vWorldViewPosition.x,
+        v3 = 0,
+        v4 = 300.0 == p[1].vWorldViewPosition.x,
+        //BYTE1(result) = HIBYTE(v1),
+        !(v2 | v4)) )
+  {
+    if ( p->vWorldViewPosition.x < 300.0 )
+    {
+      v6 = 300.0 < p[1].vWorldViewPosition.x;
+      v7 = 0;
+      v8 = 300.0 == p[1].vWorldViewPosition.x;
+      //BYTE1(result) = HIBYTE(v1);
+      if ( !(v6 | v8) )
+      {
+        //LOBYTE(result) = 0;
+        return false;
+      }
+    }
+    v9 = 300.0 < p->vWorldViewPosition.x;
+    v10 = 0;
+    v11 = 300.0 == p->vWorldViewPosition.x;
+    //BYTE1(result) = HIBYTE(v1);
+    if ( v9 | v11 )
+    {
+      v16 = 1.0 / (p->vWorldViewPosition.x - p[1].vWorldViewPosition.x);
+      v17 = (p->vWorldViewPosition.y - p[1].vWorldViewPosition.y) * v16;
+      v18 = (p->vWorldViewPosition.z - p[1].vWorldViewPosition.z) * v16;
+      v19 = 300.0 - p[1].vWorldViewPosition.x;
+      p[1].vWorldViewPosition.x = v19 + p[1].vWorldViewPosition.x;
+      p[1].vWorldViewPosition.y = v17 * v19 + p[1].vWorldViewPosition.y;
+      p[1].vWorldViewPosition.z = v19 * v18 + p[1].vWorldViewPosition.z;
+    }
+    else
+    {
+      v12 = 1.0 / (p[1].vWorldViewPosition.x - p->vWorldViewPosition.x);
+      v13 = (p[1].vWorldViewPosition.y - p->vWorldViewPosition.y) * v12;
+      v14 = (p[1].vWorldViewPosition.z - p->vWorldViewPosition.z) * v12;
+      v15 = 300.0 - p->vWorldViewPosition.x;
+      p->vWorldViewPosition.x = v15 + p->vWorldViewPosition.x;
+      p->vWorldViewPosition.y = v13 * v15 + p->vWorldViewPosition.y;
+      p->vWorldViewPosition.z = v15 * v14 + p->vWorldViewPosition.z;
+    }
+  }
+  //LOBYTE(result) = 1;
+  return true;
+}
+
+
+
+//----- (004775C4) --------------------------------------------------------
+stru6_stru1_indoor_sw_billboard::~stru6_stru1_indoor_sw_billboard()
+{
+    delete [] pArray1;
+    pArray1 = nullptr;
+
+    delete [] pArray2;
+    pArray2 = nullptr;
+}
+
+
+//----- (00478211) --------------------------------------------------------
+void stru6_stru1_indoor_sw_billboard::Initialize(int a2)
+{
+  uNumVec4sInArray1 = 66;
+  pArray1 = new stru16x[66];
+
+  uNumVec3sInArray2 = 128;
+  pArray2 = new stru160[128];
+
+  for (uint i = 0; i < uNumVec4sInArray1; ++i)
+  {
+    pArray1[i].field_0 = array_4EB8B8[i].field_0;
+    pArray1[i].field_4 = array_4EB8B8[i].field_4;
+    pArray1[i].field_8 = array_4EB8B8[i].field_8;
+    pArray1[i].field_C = a2;
+  }
+  memcpy(pArray2, array_4EBBD0_x.data()/*array_4EBBD0*/, uNumVec3sInArray2 * sizeof(stru160));
+}
+
+//----- (0047829F) --------------------------------------------------------
+void stru6_stru1_indoor_sw_billboard::_47829F_sphere_particle(float x_offset, float y_offset, float z_offset, float scale, int diffuse)
+{
+  int v7 = 0;
+
+  for (unsigned int i = 0; i < uNumVec3sInArray2; ++i)
+  {
+    for (unsigned int j = 0; j < 3; ++j)
+    {
+      field_14[j].x = x_offset + scale * *(&pArray1->field_0 + 4 * *(int *)((char *)&pArray2->field_0 + v7));
+      field_14[j].y = y_offset + scale * *(&pArray1->field_4 + 4 * *(int *)((char *)&pArray2->field_0 + v7));
+      field_14[j].z = z_offset + scale * *(&pArray1->field_8 + 4 * *(int *)((char *)&pArray2->field_0 + v7));
+      //int v10 = *(int *)((char *)&pArray2->field_0 + v7);
+
+      field_14[j].diffuse = *((int *)&pArray1[1].field_0 + 4 * (*(int *)((char *)&pArray2->field_0 + v7)));
+      v7 += 4;
+    }
+
+    uNumVertices = 3;
+    if ( sub_477C61() && sub_477F63() )
+    {
+      if ( sub_47802A() )
+        pRenderer->_4A4CC9_AddSomeBillboard(this, diffuse);
+    }
+  }
+}
+
+
+
+
+//----- (004A71FE) --------------------------------------------------------
+void stru6::DoAddProjectile(float srcX, float srcY, float srcZ, float dstX, float dstY, float dstZ, unsigned int uTextureID)
+{
+  //int v8; // eax@1
+
+  //v8 = uNumProjectiles;
+  if (uNumProjectiles < 32)
+  {
+    pProjectiles[uNumProjectiles].srcX = srcX;
+    pProjectiles[uNumProjectiles].srcY = srcY;
+    pProjectiles[uNumProjectiles].srcZ = srcZ;
+    pProjectiles[uNumProjectiles].dstX = dstX;
+    pProjectiles[uNumProjectiles].dstY = dstY;
+    pProjectiles[uNumProjectiles].dstZ = dstZ;
+    pProjectiles[uNumProjectiles++].uTextureID = uTextureID;
+  }
+}
+
+//----- (004A7298) --------------------------------------------------------
+void stru6::DrawProjectiles()
+{
+  float v10; // ST1C_4@8
+  float v11; // ST0C_4@8
+  IDirect3DTexture2 *v12; // [sp+20h] [bp-78h]@6
+  RenderVertexSoft v[2]; // [sp+30h] [bp-68h]@1
+  
+  for (uint i = 0; i < uNumProjectiles; ++i)
+  {
+    ProjectileAnim* p = &pProjectiles[i];
+
+    v[0].vWorldPosition.x = p->srcX;
+    v[0].vWorldPosition.y = p->srcY;
+    v[0].vWorldPosition.z = p->srcZ;
+    v[1].vWorldPosition.x = p->dstX;
+    v[1].vWorldPosition.y = p->dstY;
+    v[1].vWorldPosition.z = p->dstZ;
+    pIndoorCameraD3D->ViewTransform(v, 2);
+
+    sr_42620A(v);
+
+    pIndoorCameraD3D->Project(v, 2, 0);
+
+    if (p->uTextureID != -1)
+      v12 = pBitmaps_LOD->pHardwareTextures[p->uTextureID];
+    else
+      v12 = 0;
+
+    v10 = pIndoorCameraD3D->fov_x / v[1].vWorldViewPosition.x * 20.0;
+    v11 = pIndoorCameraD3D->fov_x / v[0].vWorldViewPosition.x * 20.0;
+    pRenderer->DrawProjectile(
+        v[0].vWorldViewProjX,
+        v[0].vWorldViewProjY,
+        v[0].vWorldViewPosition.x,
+         v11,
+        v[1].vWorldViewProjX,
+        v[1].vWorldViewProjY,
+        v[1].vWorldViewPosition.x,
+         v10,
+         v12);
+   }
+}
+
+//----- (004A73AA) --------------------------------------------------------
+void stru6::_4A73AA_hanging_trace_particles___like_fire_strike_ice_blast_etc(SpriteObject *a2, unsigned int uDiffuse, unsigned int uTextureID)
+{
+  stru6 *v4; // edi@1
+  SpriteObject *v5; // esi@1
+  int v6; // eax@1
+  stru6_stru2 *v7; // eax@2
+  double v8; // st7@2
+  double v9; // st6@2
+  double v10; // st7@3
+  Particle_sw local_0; // [sp+8h] [bp-68h]@1
+  float x; // [sp+78h] [bp+8h]@2
+
+  v4 = this;
+  memset(&local_0, 0, 0x68u);
+  v5 = a2;
+  v6 = a2->field_54;
+  if ( v6 )
+  {
+    v7 = &v4->array_4[v6 & 0x1F];
+    x = ((double)a2->vPosition.x - v7->flt_0_x) * 0.5 + v7->flt_0_x;
+    v8 = ((double)v5->vPosition.y - v7->flt_4_y) * 0.5 + v7->flt_4_y;
+    v9 = ((double)v5->vPosition.z - v7->flt_8_z) * 0.5 + v7->flt_8_z;
+    local_0.type = ParticleType_Bitmap | ParticleType_Rotating | ParticleType_8;
+    local_0.uDiffuse = uDiffuse;
+    local_0.x = x + 4.0;
+    local_0.y = v8;
+    local_0.z = v9;
+    local_0.r = 0.0;
+    local_0.g = 0.0;
+    local_0.b = 0.0;
+    local_0.timeToLive = (rand() & 0x40) + 96;
+    local_0.uTextureID = uTextureID;
+    local_0.flt_28 = 1.0;
+    pEngine->pParticleEngine->AddParticle(&local_0);
+    local_0.x = x - 4.0;
+    pEngine->pParticleEngine->AddParticle(&local_0);
+    local_0.x = (double)v5->vPosition.x + 4.0;
+    local_0.y = (double)v5->vPosition.y;
+    local_0.z = (double)v5->vPosition.z;
+    pEngine->pParticleEngine->AddParticle(&local_0);
+    local_0.x = (double)v5->vPosition.x - 4.0;
+    pEngine->pParticleEngine->AddParticle(&local_0);
+    v4->array_4[v5->field_54 & 0x1F].flt_0_x = (double)v5->vPosition.x;
+    v4->array_4[v5->field_54 & 0x1F].flt_4_y = (double)v5->vPosition.y;
+    v4->array_4[v5->field_54 & 0x1F].flt_8_z = (double)v5->vPosition.z;
+  }
+  else
+  {
+    a2->field_54 = v4->field_0++;
+    v4->array_4[a2->field_54 & 0x1F].flt_0_x = (double)a2->vPosition.x;
+    v4->array_4[a2->field_54 & 0x1F].flt_4_y = (double)a2->vPosition.y;
+    v4->array_4[a2->field_54 & 0x1F].flt_8_z = (double)a2->vPosition.z;
+    v10 = (double)a2->vPosition.x;
+    local_0.type = ParticleType_Bitmap | ParticleType_Rotating | ParticleType_8;
+    local_0.uDiffuse = uDiffuse;
+    local_0.x = v10 + 4.0;
+    local_0.y = (double)a2->vPosition.y;
+    local_0.z = (double)a2->vPosition.z;
+    local_0.r = 0.0;
+    local_0.g = 0.0;
+    local_0.b = 0.0;
+    local_0.flt_28 = 1.0;
+    local_0.timeToLive = (rand() & 0x7F) + 128;
+    local_0.uTextureID = uTextureID;
+    pEngine->pParticleEngine->AddParticle(&local_0);
+    local_0.x = (double)a2->vPosition.x - 4.0;
+    pEngine->pParticleEngine->AddParticle(&local_0);
+  }
+}
+
+//----- (004A75CC) --------------------------------------------------------
+void stru6::_4A75CC_single_spell_collision_particle(SpriteObject *a1, unsigned int uDiffuse, unsigned int uTextureID)
+{
+  double v4; // st7@1
+  signed int v5; // edi@1
+  Particle_sw local_0; // [sp+8h] [bp-68h]@1
+
+  memset(&local_0, 0, 0x68u);
+  local_0.type = ParticleType_Bitmap | ParticleType_Rotating | ParticleType_1;
+  local_0.x = (double)a1->vPosition.x;
+  local_0.y = (double)a1->vPosition.y;
+  v4 = (double)a1->vPosition.z;
+  local_0.uDiffuse = uDiffuse;
+  local_0.z = v4;
+  v5 = 10;
+  local_0.timeToLive = (rand() & 0x7F) + 128;
+  local_0.uTextureID = uTextureID;
+  local_0.flt_28 = 1.0;
+  do
+  {
+    local_0.r = (double)(rand() & 0x1FF) - 255.0;
+    local_0.g = (double)(rand() & 0x1FF) - 255.0;
+    local_0.b = (double)(rand() & 0x1FF) - 255.0;
+    pEngine->pParticleEngine->AddParticle(&local_0);
+    --v5;
+  }
+  while ( v5 );
+}
+
+//----- (004A7688) --------------------------------------------------------
+void stru6::_4A7688_fireball_collision_particle(SpriteObject *a2)
+{
+  double v3; // st7@1
+  double v4; // st7@2
+  Particle_sw local_0; // [sp+1Ch] [bp-7Ch]@1
+
+  memset(&local_0, 0, 0x68u);
+
+  v3 = (double)a2->uSpriteFrameID / (double)pObjectList->pObjects[a2->uObjectDescID].uLifetime;
+  if ( v3 >= 0.75 )
+    v4 = (1.0 - v3) * 4.0;
+  else
+    v4 = v3 * 1.333333333333333;
+
+  local_0.type = ParticleType_Bitmap | ParticleType_Rotating | ParticleType_1;
+  local_0.uDiffuse = 0xFF3C1E;
+  local_0.x = (double)a2->vPosition.x;
+  local_0.y = (double)a2->vPosition.y;
+  local_0.z = (double)a2->vPosition.z;
+  local_0.timeToLive = (rand() & 0x7F) + 128;
+  local_0.uTextureID = pBitmaps_LOD->LoadTexture("effpar01", TEXTURE_DEFAULT);
+  local_0.flt_28 = 1.0;
+
+  // 10 fireball sparks 
+  for (unsigned int i = 0; i < 10; ++i)
+  {
+    local_0.r = (rand() & 0x1FF) - 255;
+    local_0.g = (rand() & 0x1FF) - 255;
+    local_0.b = (rand() & 0x1FF) - 255;
+    pEngine->pParticleEngine->AddParticle(&local_0);
+  }
+
+  pStru1->_47829F_sphere_particle((double)a2->vPosition.x, (double)a2->vPosition.y, (double)a2->vPosition.z, 
+                                              (double)floorf(0.5f + (512.0 * v3)), ModulateColor(0xFF3C1E, v4));
+}
+
+//----- (004A77FD) --------------------------------------------------------
+void stru6::_4A77FD_implosion_particle_d3d(SpriteObject *a1)
+{
+  double v4; // st7@1
+  double v5; // st7@2
+  int v7; // eax@4
+  float v8; // ST0C_4@4
+  float v9; // ST08_4@4
+  float v10; // ST04_4@4
+  float v11; // ST00_4@4
+  float v12; // [sp+28h] [bp-4h]@1
+
+  v4 = (double)a1->uSpriteFrameID / (double)pObjectList->pObjects[a1->uObjectDescID].uLifetime;
+  v12 = 512.0 - v4 * 512.0;
+  if ( v4 >= 0.75 )
+    v5 = v4 * 4.0;
+  else
+    v5 = v4 * 1.333333333333333;
+
+  v7 = ModulateColor(0x7E7E7E, v5);
+  v8 = (double)floorf(0.5f + v12);
+  v9 = (double)a1->vPosition.z;
+  v10 = (double)a1->vPosition.y;
+  v11 = (double)a1->vPosition.x;
+  pStru1->_47829F_sphere_particle(v11, v10, v9, v8, v7);
+}
+
+//----- (004A78AE) --------------------------------------------------------
+void stru6::_4A78AE_sparks_spell(SpriteObject *a1)
+{
+  ObjectDesc *v2; // esi@1
+  unsigned int v3; // eax@1
+  double v4; // st7@1
+  Particle_sw local_0; // [sp+8h] [bp-68h]@1
+
+  v2 = &pObjectList->pObjects[a1->uObjectDescID];
+  memset(&local_0, 0, 0x68u);
+  v3 = a1->uSpriteFrameID;
+  local_0.x = (double)a1->vPosition.x;
+  v4 = (double)a1->vPosition.y;
+  local_0.type = ParticleType_Sprite;
+  local_0.uDiffuse = 0x7F7F7F;
+  local_0.timeToLive = 1;
+  local_0.y = v4;
+  local_0.z = (double)a1->vPosition.z;
+  local_0.r = 0.0;
+  local_0.g = 0.0;
+  local_0.b = 0.0;
+  local_0.uTextureID = pSpriteFrameTable->GetFrame(v2->uSpriteID, v3)->pHwSpriteIDs[0];
+  LODWORD(local_0.flt_28) = 0x40000000u;
+  pEngine->pParticleEngine->AddParticle(&local_0);
+}
+
+//----- (004A7948) --------------------------------------------------------
+void stru6::_4A7948_mind_blast_after_effect(SpriteObject *a1)
+{
+  ObjectDesc *v2; // esi@1
+  unsigned int v3; // eax@1
+  double v4; // st7@1
+  char v5; // al@1
+  signed int v6; // edi@1
+  Particle_sw Dst; // [sp+8h] [bp-68h]@1
+
+  v2 = &pObjectList->pObjects[a1->uObjectDescID];
+  memset(&Dst, 0, 0x68u);
+  v3 = a1->uSpriteFrameID;
+  Dst.x = (double)a1->vPosition.x;
+  v4 = (double)a1->vPosition.y;
+  Dst.type = ParticleType_Sprite | ParticleType_Rotating | ParticleType_1;
+  Dst.uDiffuse = 0x7F7F7F;
+  Dst.y = v4;
+  Dst.z = (double)a1->vPosition.z;
+  Dst.uTextureID = pSpriteFrameTable->GetFrame(v2->uSpriteID, v3)->pHwSpriteIDs[0];
+  v5 = rand();
+  v6 = 10;
+  Dst.flt_28 = 1.0;
+  Dst.timeToLive = (v5 & 0x7F) + 128;
+  do
+  {
+    Dst.r = (double)(rand() & 0x1FF) - 255.0;
+    Dst.g = (double)(rand() & 0x1FF) - 255.0;
+    Dst.b = (double)(rand() & 0x1FF) - 255.0;
+    pEngine->pParticleEngine->AddParticle(&Dst);
+    --v6;
+  }
+  while ( v6 );
+}
+
+//----- (004A7A27) --------------------------------------------------------
+bool stru6::AddMobileLight(SpriteObject *a1, unsigned int uDiffuse, int uRadius)
+{
+  return pMobileLightsStack->AddLight(a1->vPosition.x, a1->vPosition.y, a1->vPosition.z, a1->uSectorID, uRadius,
+           (uDiffuse & 0x00FF0000) >> 16,
+           (uDiffuse & 0x0000FF00) >> 8,
+           uDiffuse & 0x000000FF,
+           _4E94D3_light_type);
+}
+// 4E94D3: using guessed type char _4E94D3_light_type;
+
+//----- (004A7A66) --------------------------------------------------------
+void stru6::_4A7A66_miltiple_spell_collision_partifles___like_after_sparks_or_lightning(SpriteObject *a1, unsigned int uDiffuse, unsigned int uTextureID, float a4)
+{
+  int v5; // eax@1
+  char v6; // al@1
+  double v7; // st6@1
+  double v8; // st6@1
+  double v9; // st7@1
+  double v10; // st6@1
+  Particle_sw local_0; // [sp+0h] [bp-6Ch]@1
+  float v12; // [sp+68h] [bp-4h]@1
+  float a1a; // [sp+74h] [bp+8h]@1
+  float uDiffusea; // [sp+78h] [bp+Ch]@1
+  float uTextureIDa; // [sp+7Ch] [bp+10h]@1
+
+  memset(&local_0, 0, 0x68u);
+  local_0.type = ParticleType_Bitmap | ParticleType_Rotating | ParticleType_1;
+  local_0.x = (double)a1->vPosition.x;
+  v5 = a1->vPosition.z;
+  local_0.y = (double)a1->vPosition.y;
+  local_0.uDiffuse = uDiffuse;
+  local_0.z = (double)(v5 + 32);
+  v6 = rand();
+  local_0.flt_28 = 1.0;
+  v7 = 0.0 * a4;
+  local_0.timeToLive = (v6 & 0x7F) + 128;
+  local_0.uTextureID = uTextureID;
+  a1a = v7;
+  local_0.r = v7;
+  local_0.g = a4;
+  local_0.b = a4;
+  pEngine->pParticleEngine->AddParticle(&local_0);
+  v8 = 0.70710677 * a4;
+  uDiffusea = v8;
+  local_0.r = v8;
+  local_0.g = v8;
+  local_0.b = a4;
+  pEngine->pParticleEngine->AddParticle(&local_0);
+  local_0.g = a1a;
+  local_0.r = a4;
+  local_0.b = a4;
+  pEngine->pParticleEngine->AddParticle(&local_0);
+  local_0.r = uDiffusea;
+  local_0.b = a4;
+  v9 = -uDiffusea;
+  uTextureIDa = v9;
+  local_0.g = v9;
+  pEngine->pParticleEngine->AddParticle(&local_0);
+  v10 = -1.0 * a4;
+  local_0.r = a1a;
+  v12 = v10;
+  local_0.g = v10;
+  local_0.b = a4;
+  pEngine->pParticleEngine->AddParticle(&local_0);
+  local_0.b = a4;
+  local_0.r = uTextureIDa;
+  local_0.g = uTextureIDa;
+  pEngine->pParticleEngine->AddParticle(&local_0);
+  local_0.r = v12;
+  local_0.g = a1a;
+  local_0.b = a4;
+  pEngine->pParticleEngine->AddParticle(&local_0);
+  local_0.r = uTextureIDa;
+  local_0.g = uDiffusea;
+  local_0.b = a4;
+  pEngine->pParticleEngine->AddParticle(&local_0);
+}
+
+//----- (004A7C07) --------------------------------------------------------
+void stru6::_4A7C07_stun_spell_fx(SpriteObject *a2)
+{
+  stru6 *v2; // edi@1
+  SpriteObject *v3; // esi@1
+  int v4; // eax@1
+  ObjectDesc *v5; // ebx@1
+  stru6_stru2 *v6; // eax@2
+  double v7; // st6@2
+  double v8; // st5@2
+  double v9; // st4@2
+  char v10; // al@2
+  double v11; // st7@2
+  double v12; // st7@3
+  Particle_sw local_0; // [sp+Ch] [bp-68h]@1
+  float a2a; // [sp+7Ch] [bp+8h]@2
+
+  v2 = this;
+  memset(&local_0, 0, 0x68u);
+  v3 = a2;
+  v4 = a2->field_54;
+  v5 = &pObjectList->pObjects[a2->uObjectDescID];
+  if ( v4 )
+  {
+    v6 = &v2->array_4[v4 & 0x1F];
+    v7 = ((double)a2->vPosition.x - v6->flt_0_x) * 0.5 + v6->flt_0_x;
+    v8 = ((double)a2->vPosition.y - v6->flt_4_y) * 0.5 + v6->flt_4_y;
+    v9 = ((double)a2->vPosition.z - v6->flt_8_z) * 0.5 + v6->flt_8_z;
+    local_0.type = ParticleType_Sprite;
+    local_0.uDiffuse = 0xFFFFFF;
+    a2a = v9;
+    local_0.x = v7;
+    local_0.z = a2a;
+    local_0.y = v8;
+    local_0.r = 0.0;
+    local_0.g = 0.0;
+    local_0.b = 0.0;
+    v10 = rand();
+    LODWORD(local_0.flt_28) = 0x40400000u;
+    local_0.timeToLive = (v10 & 0x3F) + 64;
+    local_0.uTextureID = pSpriteFrameTable->GetFrame(v5->uSpriteID, v3->uSpriteFrameID)->pHwSpriteIDs[0];
+    pEngine->pParticleEngine->AddParticle(&local_0);
+    v11 = (double)v3->vPosition.x;
+    LODWORD(local_0.flt_28) = 0x40800000u;
+    local_0.x = v11;
+    local_0.y = (double)v3->vPosition.y;
+    local_0.z = (double)v3->vPosition.z;
+    local_0.timeToLive = (rand() & 0x3F) + 64;
+    pEngine->pParticleEngine->AddParticle(&local_0);
+    v2->array_4[v3->field_54 & 0x1F].flt_0_x = (double)v3->vPosition.x;
+    v2->array_4[v3->field_54 & 0x1F].flt_4_y = (double)v3->vPosition.y;
+    v2->array_4[v3->field_54 & 0x1F].flt_8_z = (double)v3->vPosition.z;
+  }
+  else
+  {
+    a2->field_54 = v2->field_0++;
+    v2->array_4[a2->field_54 & 0x1F].flt_0_x = (double)a2->vPosition.x;
+    v2->array_4[a2->field_54 & 0x1F].flt_4_y = (double)a2->vPosition.y;
+    v2->array_4[a2->field_54 & 0x1F].flt_8_z = (double)a2->vPosition.z;
+    v12 = (double)a2->vPosition.x;
+    local_0.type = ParticleType_Sprite;
+    local_0.uDiffuse = 0xFFFFFF;
+    LODWORD(local_0.flt_28) = 0x40000000u;
+    local_0.x = v12;
+    local_0.y = (double)a2->vPosition.y;
+    local_0.z = (double)a2->vPosition.z;
+    local_0.r = 0.0;
+    local_0.g = 0.0;
+    local_0.b = 0.0;
+    local_0.timeToLive = (rand() & 0x3F) + 64;
+    local_0.uTextureID = pSpriteFrameTable->GetFrame(v5->uSpriteID, a2->uSpriteFrameID)->pHwSpriteIDs[0];
+    pEngine->pParticleEngine->AddParticle(&local_0);
+  }
+}
+
+//----- (004A7E05) --------------------------------------------------------
+void stru6::AddProjectile(SpriteObject *a2, int a3, unsigned int uTextureID)
+{
+  if (a2->field_54)
+  {
+    DoAddProjectile(array_4[a2->field_54 & 0x1F].flt_0_x,
+                    array_4[a2->field_54 & 0x1F].flt_4_y,
+                    array_4[a2->field_54 & 0x1F].flt_8_z,
+                    a2->vPosition.x,
+                    a2->vPosition.y,
+                    a2->vPosition.z,
+                    uTextureID);
+  }
+  else
+  {
+    a2->field_54 = field_0++;
+    array_4[a2->field_54 & 0x1F].flt_0_x = (double)a2->vPosition.x;
+    array_4[a2->field_54 & 0x1F].flt_4_y = (double)a2->vPosition.y;
+    array_4[a2->field_54 & 0x1F].flt_8_z = (double)a2->vPosition.z;
+  }
+}
+
+//----- (004A7E89) --------------------------------------------------------
+void stru6::_4A7E89_sparkles_on_actor_after_it_casts_buff(Actor *pActor, unsigned int uDiffuse)
+{
+  Actor *v3; // edi@1
+  int v4; // ebx@3
+  //int result; // eax@5
+  Particle_sw Dst; // [sp+Ch] [bp-6Ch]@1
+  int v7; // [sp+74h] [bp-4h]@2
+  signed int pActora; // [sp+80h] [bp+8h]@1
+
+  memset(&Dst, 0, 0x68u);
+  Dst.type = ParticleType_Bitmap | ParticleType_Rotating | ParticleType_8;
+  Dst.timeToLive = (rand() & 0x7F) + 128;
+  v3 = pActor;
+  Dst.uTextureID = pBitmaps_LOD->LoadTexture("effpar02", TEXTURE_DEFAULT);
+  pActora = 50;
+  Dst.flt_28 = 1.0;
+  do
+  {
+    v7 = (unsigned __int8)rand() + v3->vPosition.x - 127;
+    Dst.x = (double)v7;
+    v7 = (unsigned __int8)rand() + v3->vPosition.y - 127;
+    Dst.y = (double)v7;
+    v7 = v3->vPosition.z + (unsigned __int8)rand();
+    Dst.z = (double)v7;
+    if ( uDiffuse )
+    {
+      Dst.uDiffuse = uDiffuse;
+    }
+    else
+    {
+      v4 = rand() << 16;
+      Dst.uDiffuse = rand() | v4;
+    }
+    pEngine->pParticleEngine->AddParticle(&Dst);
+    --pActora;
+  }
+  while ( pActora );
+}
+
+//----- (004A7F74) --------------------------------------------------------
+void stru6::_4A7F74(int x, int y, int z)
+{
+  stru6 *v4; // esi@1
+  char v5; // al@1
+  signed int v6; // edi@1
+  unsigned int v7; // eax@1
+  double v8; // st7@2
+  double v9; // st7@2
+  Particle_sw local_0; // [sp+8h] [bp-78h]@1
+  double v11; // [sp+70h] [bp-10h]@1
+  double v12; // [sp+78h] [bp-8h]@1
+  float z1; // [sp+88h] [bp+8h]@2
+
+  v4 = this;
+  memset(&local_0, 0, 0x68u);
+  local_0.type = ParticleType_Bitmap | ParticleType_Rotating | ParticleType_1;
+  local_0.uDiffuse = 0x7E7E7E;
+  v5 = rand();
+  local_0.flt_28 = 1.0;
+  v6 = 8;
+  local_0.timeToLive = (v5 & 0x7F) + 128;
+  v7 = v4->uTextureID_effpar1;
+  v12 = (double)x;
+  local_0.uTextureID = v7;
+  v11 = (double)y;
+  do
+  {
+    v8 = pRnd->GetRandom();
+    local_0.x = v8 * 40.0 - 20.0 + v12;
+    v9 = pRnd->GetRandom();
+    z1 = (double)z;
+    local_0.z = z1;
+    local_0.y = v9 * 40.0 - 20.0 + v11;
+    local_0.r = pRnd->GetRandom() * 400.0 - 200.0;
+    local_0.g = pRnd->GetRandom() * 400.0 - 200.0;
+    local_0.b = pRnd->GetRandom() * 150.0 + 50.0;
+    pEngine->pParticleEngine->AddParticle(&local_0);
+    --v6;
+  }
+  while ( v6 );
+}
+
+//----- (004A806F) --------------------------------------------------------
+int stru6::_4A806F(Actor *pActor)
+{
+  int v2; // ecx@1
+  unsigned int v3; // eax@1
+  double v4; // st7@2
+  float v5; // ST00_4@6
+
+  v2 = (int)pActor;
+  v3 = LODWORD(pActor->pActorBuffs[ACTOR_BUFF_MASS_DISTORTION].uExpireTime) - pMiscTimer->uTotalGameTimeElapsed;
+  if ( (signed int)v3 <= 64 )
+  {
+    if ( (v3 & 0x80000000u) != 0 )
+    {
+      pActor->pActorBuffs[ACTOR_BUFF_MASS_DISTORTION].uExpireTime = 0i64;
+      v4 = 1.0;
+    }
+    else
+    {
+      v2 = v3 * v3;
+      v4 = 1.0 - (double)(signed int)(v3 * v3) * 0.0001953125;
+    }
+  }
+  else
+  {
+    v2 = (v3 - 64) * (v3 - 64);
+    v4 = (double)v2 * 0.0001953125 + 0.2;
+  }
+  v5 = v4;
+  return fixpoint_from_float(v5);
+}
+
+//----- (004A81CA) --------------------------------------------------------
+bool stru6::RenderAsSprite(SpriteObject *a2)
+{
+  //stru6 *v2; // ebx@1
+  int result; // eax@1
+//  int v4; // eax@27
+  //unsigned int diffuse; // esi@41
+  //int v6; // ecx@49
+  int v7; // eax@54
+  int v8; // eax@55
+  char v9; // zf@56
+  int v10; // eax@59
+  int v11; // eax@61
+  int v12; // eax@85
+  int v13; // eax@86
+  int v14; // eax@96
+  int v15; // eax@111
+  int v16; // eax@118
+  int v17; // eax@139
+  int v18; // eax@140
+  int v19; // eax@141
+  int v20; // eax@151
+  char pContainer[7]; // [sp+10h] [bp-8h]@81
+
+  //__debugbreak(); // need to refactor carefully & collect data
+  //v2 = this;
+  result = a2->uType;
+
+    switch (a2->uType)
+    {
+
+        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 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 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 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 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 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;
+
+        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 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;
+
+        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;
+
+        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)
+            {
+                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_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;
+
+        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;
+
+        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;
+
+        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;
+
+
+        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;
+        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;
+        case SPRITE_SPELL_BODY_FLYING_FIST_IMPACT:
+            _4A75CC_single_spell_collision_particle(a2, 0xF00000, uTextureID_effpar1);
+            AddMobileLight(a2, 0xF00000, 256);
+            return false;
+
+
+
+        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;
+
+        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;
+
+
+        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;
+  }
+
+  return false;
+}
+
+//----- (004A89BD) --------------------------------------------------------
+void stru6::SetPlayerBuffAnim(unsigned __int16 uSpellID, unsigned __int16 uPlayerID)
+{
+  //stru6 *v3; // edi@1
+  PlayerBuffAnim *v4; // esi@1
+  const char *v6; // [sp-4h] [bp-10h]@2
+
+  v4 = &pPlayerBuffs[uPlayerID];
+  v4->uSpellAnimTimeElapsed = 0;
+  v4->bRender = uSpellID != 0;
+
+  switch (uSpellID)
+  {
+    case SPELL_DISEASE:
+      v6 = "zapp";
+    break;
+      
+    case BECOME_MAGIC_GUILD_MEMBER:
+    case SPELL_AIR_FEATHER_FALL:
+    case SPELL_SPIRIT_DETECT_LIFE:
+    case SPELL_SPIRIT_FATE:
+      v6 = "spboost1";
+    break;
+      
+    case SPELL_QUEST_COMPLETED:
+    case SPELL_AIR_INVISIBILITY:
+    case SPELL_WATER_WATER_WALK:
+    case SPELL_SPIRIT_PRESERVATION:
+      v6 = "spboost2";
+    break;
+      
+    case SPELL_152:
+      __debugbreak(); // spell id == 152 wtf
+    case SPELL_LIGHT_HOUR_OF_POWER:
+    case SPELL_LIGHT_DAY_OF_THE_GODS:
+    case SPELL_LIGHT_DAY_OF_PROTECTION:
+    case SPELL_LIGHT_DIVINE_INTERVENTION:
+      v6 = "spboost3";
+    break;
+
+    case SPELL_SPIRIT_REMOVE_CURSE:
+    case SPELL_MIND_REMOVE_FEAR:
+    case SPELL_BODY_CURE_WEAKNESS:
+      v6 = "spheal1";
+    break;
+
+    case SPELL_SPIRIT_SHARED_LIFE:
+    case SPELL_MIND_CURE_PARALYSIS:
+    case SPELL_MIND_CURE_INSANITY:
+    case SPELL_BODY_FIRST_AID:
+    case SPELL_BODY_CURE_POISON:
+    case SPELL_BODY_CURE_DISEASE:
+    case SPELL_DARK_SACRIFICE:
+      v6 = "spheal2";
+    break;
+
+    case SPELL_BODY_POWER_CURE:
+    case SPELL_DARK_SOULDRINKER:
+      v6 = "spheal3";
+    break;
+
+    case SPELL_FIRE_PROTECTION_FROM_FIRE:
+    case SPELL_FIRE_IMMOLATION:
+      v6 = "spell03";
+    break;
+
+    case SPELL_FIRE_HASTE:                  v6 = "spell05"; break;
+    case SPELL_AIR_PROTECTION_FROM_AIR:     v6 = "spell14"; break;
+    case SPELL_AIR_SHIELD:                  v6 = "spell17"; break;
+    case SPELL_WATER_PROTECTION_FROM_WATER: v6 = "spell25"; break;
+    case SPELL_EARTH_PROTECTION_FROM_EARTH: v6 = "spell36"; break;
+    case SPELL_EARTH_STONESKIN:             v6 = "spell38"; break;
+    case SPELL_SPIRIT_BLESS:                v6 = "spell46"; break;
+    case SPELL_SPIRIT_HEROISM:              v6 = "spell51"; break;
+    case SPELL_SPIRIT_RESSURECTION:         v6 = "spell55"; break;
+    case SPELL_MIND_PROTECTION_FROM_MIND:   v6 = "spell58"; break;
+    case SPELL_BODY_PROTECTION_FROM_BODY:   v6 = "spell69"; break;
+    case SPELL_BODY_REGENERATION:           v6 = "spell71"; break;
+    case SPELL_BODY_HAMMERHANDS:            v6 = "spell73"; break;
+    case SPELL_BODY_PROTECTION_FROM_MAGIC:  v6 = "spell75"; break;
+
+    default:
+      v4->bRender = false;
+      return;
+  }
+  
+  v4->uSpellIconID = pIconsFrameTable->FindIcon(v6);
+  if (v4->bRender)
+    v4->uSpellAnimTime = 8 * pIconsFrameTable->pIcons[v4->uSpellIconID].uAnimLength;
+}
+
+//----- (004A8BDF) --------------------------------------------------------
+void stru6::FadeScreen__like_Turn_Undead_and_mb_Armageddon(unsigned int uDiffuseColor, unsigned int uFadeTime)
+{
+  this->uFadeTime = uFadeTime;
+  this->uFadeLength = uFadeTime;
+  this->uFadeColor = uDiffuseColor;
+}
+
+//----- (004A8BFC) --------------------------------------------------------
+int stru6::_4A8BFC() //for SPELL_LIGHT_PRISMATIC_LIGHT
+{
+  uAnimLength = 8 * pSpriteFrameTable->pSpriteSFrames[pSpriteFrameTable->FastFindSprite("spell84")].uAnimLength;
+  return uAnimLength;
+}
+
+//----- (004A8C27) --------------------------------------------------------
+void stru6::RenderSpecialEffects()
+{
+  double v4; // st7@4
+  double v5; // st6@4
+  float v7; // ST14_4@6
+  unsigned int v8; // ST14_4@8
+  SpriteFrame *v10; // eax@8
+  int v11; // edi@8
+  RenderVertexD3D3 vd3d[4]; // [sp+60h] [bp-8Ch]@9
+
+  if (uNumProjectiles)
+  {
+    DrawProjectiles();
+    uNumProjectiles = 0;
+  }
+
+  field_204 = 0;
+  if ( uFadeTime > 0 )
+  {
+    v4 = (double)uFadeTime / (double)uFadeLength;
+    v5 = 1.0 - v4 * v4;
+    //v6 = v5;
+    if ( v5 > 0.9 )
+      v5 = 1.0 - (v5 - 0.9) * 10.0;
+    v7 = v5;
+    pRenderer->ScreenFade(uFadeColor, v7);
+    uFadeTime -= pEventTimer->uTimeElapsed;
+  }
+
+  if (uAnimLength > 0)
+  {
+    v8 = 8 * pSpriteFrameTable->pSpriteSFrames[pSpriteFrameTable->FastFindSprite("spell84")].uAnimLength - uAnimLength;
+    v10 = pSpriteFrameTable->GetFrame(pSpriteFrameTable->FastFindSprite("spell84"), v8);
+    v11 = v10->pHwSpriteIDs[0];
+    uAnimLength -= pEventTimer->uTimeElapsed;
+    //if ( pRenderer->pRenderD3D )
+    //{
+      vd3d[0].pos.x = (double)(signed int)pViewport->uViewportTL_X;
+      vd3d[0].pos.y = (double)(signed int)pViewport->uViewportTL_Y;
+      vd3d[0].pos.z = 0.0;
+      vd3d[0].diffuse = 0x7F7F7Fu;
+      vd3d[0].specular = 0;
+      vd3d[0].rhw = 1.0;
+      vd3d[0].texcoord.x = 0.0;
+      vd3d[0].texcoord.y = 0.0;
+
+      vd3d[1].pos.x = (double)(signed int)pViewport->uViewportTL_X;
+      vd3d[1].pos.y = (double)(pViewport->uViewportBR_Y + 1);
+      vd3d[1].pos.z = 0.0;
+      vd3d[1].diffuse = 0x7F7F7Fu;
+      vd3d[1].specular = 0;
+      vd3d[1].rhw = 1.0;
+      vd3d[1].texcoord.x = 0.0;
+      vd3d[1].texcoord.y = 1.0;
+
+      vd3d[2].pos.x = (double)(signed int)pViewport->uViewportBR_X;
+      vd3d[2].pos.y = (double)(pViewport->uViewportBR_Y + 1);
+      vd3d[2].pos.z = 0.0;
+      vd3d[2].diffuse = 0x7F7F7Fu;
+      vd3d[2].specular = 0;
+      vd3d[2].rhw = 1.0;
+      vd3d[2].texcoord.x = 1.0;
+      vd3d[2].texcoord.y = 1.0;
+
+      vd3d[3].pos.x = (double)(signed int)pViewport->uViewportBR_X;
+      vd3d[3].pos.y = (double)(signed int)pViewport->uViewportTL_Y;
+      vd3d[3].pos.z = 0.0;
+      vd3d[3].diffuse = 0x7F7F7Fu;
+      vd3d[3].specular = 0;
+      vd3d[3].rhw = 1.0;
+      vd3d[3].texcoord.x = 1.0;
+      vd3d[3].texcoord.y = 0.0;
+
+      pRenderer->DrawSpecialEffectsQuad(vd3d, pSprites_LOD->pHardwareSprites[v11].pTexture);
+    //}
+    /*else
+    {
+      vsr.pTarget = pRenderer->pTargetSurface;
+      vsr.sParentBillboardID = -1;
+      vsr.pTargetZ = pRenderer->pActiveZBuffer;
+      vsr.uScreenSpaceX = (signed int)(pViewport->uViewportBR_X - pViewport->uViewportTL_X) / 2;
+      vsr.uScreenSpaceY = pViewport->uViewportBR_Y;
+      v24 = 16777216;
+      LODWORD(v18) = 0;
+      HIDWORD(v18) = (signed __int16)(LOWORD(pViewport->uViewportBR_X) - LOWORD(pViewport->uViewportTL_X));
+      vsr._screenspace_x_scaler_packedfloat = v18 / 0x1000000;
+      LODWORD(v18) = 0;
+      HIDWORD(v18) = (signed __int16)(LOWORD(pViewport->uViewportBR_Y) - LOWORD(pViewport->uViewportTL_Y));
+      v26 = v18 / 16777216;
+      vsr._screenspace_y_scaler_packedfloat = v18 / 0x1000000;
+      vsr.pPalette = PaletteManager::Get_Dark_or_Red_LUT(v70->uPaletteIndex, 0, 1);
+      vsr.uTargetPitch = pRenderer->uTargetSurfacePitch;
+      vsr.sParentBillboardID = -1;
+      vsr.uViewportX = pViewport->uViewportTL_X;
+      vsr.uViewportZ = pViewport->uViewportBR_X;
+      vsr.uViewportY = pViewport->uViewportTL_Y;
+      vsr.sZValue = 0;
+      vsr.uViewportW = pViewport->uViewportBR_Y;
+      vsr.uFlags = 0;
+      if ( v11 >= 0 )
+        pSprites_LOD->pSpriteHeaders[v11].DrawSprite_sw(&vsr, 1);
+    }*/
+  }
+}
+
+//----- (004A902A) --------------------------------------------------------
+void stru6::DrawPlayerBuffAnims()
+{
+  for (uint i = 0; i < 4; ++i)
+  {
+    PlayerBuffAnim* buff = &pPlayerBuffs[i];
+    if (!buff->bRender)
+      continue;
+
+    buff->uSpellAnimTimeElapsed += pEventTimer->uTimeElapsed;
+    if (buff->uSpellAnimTimeElapsed >= buff->uSpellAnimTime)
+    {
+      buff->bRender = false;
+      continue;
+    }
+
+    IconFrame* icon = pIconsFrameTable->GetFrame(buff->uSpellIconID, buff->uSpellAnimTimeElapsed);
+    pRenderer->DrawTextureIndexedAlpha(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i], 385, pIcons_LOD->GetTexture(icon->uTextureID));
+
+    pOtherOverlayList->bRedraw = true;
+  }
+}
+
+//----- (004A90A0) --------------------------------------------------------
+void stru6::LoadAnimations()
+{
+  uTextureID_effpar1 = pBitmaps_LOD->LoadTexture("effpar01", TEXTURE_DEFAULT);
+  uTextureID_effpar2 = pBitmaps_LOD->LoadTexture("effpar02", TEXTURE_DEFAULT);
+  uTextureID_effpar3 = pBitmaps_LOD->LoadTexture("effpar03", TEXTURE_DEFAULT);
+  uSpriteID_sp57c = pSprites_LOD->LoadSprite("sp57c", 6);
+
+  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("zapp"));
+  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spheal1"));
+  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spheal2"));
+  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spheal3"));
+  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spboost1"));
+  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spboost2"));
+  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spboost3"));
+  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spell03"));
+  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spell05"));
+  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spell14"));
+  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spell17"));
+  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spell21"));
+  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spell25"));
+  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spell27"));
+  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spell36"));
+  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spell38"));
+  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spell46"));
+  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spell51"));
+  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spell55"));
+  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spell58"));
+  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spell69"));
+  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spell71"));
+  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spell73"));
+  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spell75"));
+  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spell96"));
+
+  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell01"));
+  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell02"));
+  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell03"));
+  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell09"));
+  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell11"));
+  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell18"));
+  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell22"));
+  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell26"));
+  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell29"));
+  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell39"));
+  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell39c"));
+  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell41"));
+  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell57c"));
+  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell62"));
+  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell65"));
+  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell66"));
+  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell70"));
+  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell76"));
+  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell84"));
+  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell90"));
+  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell92"));
+  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell93"));
+  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell97"));
+  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell97c"));
+  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell97c"));
+}
+
+//----- (004775ED) --------------------------------------------------------
+int stru6_stru1_indoor_sw_billboard::_4775ED(float a2)
+{
+	char *v2; // edi@1
+	//int v3; // eax@1
+	char *v4; // edx@2
+	char *v5; // esi@3
+	double v6; // st7@6
+	signed __int64 v7; // ST84_8@6
+	double v8; // ST0C_8@6
+	int v9; // esi@6
+	double v10; // ST44_8@6
+	int v11; // ecx@6
+	double v12; // ST34_8@6
+	int v13; // ecx@6
+	double v14; // ST14_8@6
+	double v15; // st7@8
+	unsigned int v16; // ecx@8
+	signed __int64 v17; // ST64_8@8
+	double v18; // ST24_8@8
+	int v19; // edi@8
+	double v20; // ST3C_8@8
+	int v21; // ecx@8
+	double v22; // ST2C_8@8
+	int v23; // ST9C_4@8
+	double v24; // ST1C_8@8
+	int *v25; // edi@8
+	int v26; // esi@8
+	int *v27; // edi@10
+	int v28; // esi@10
+	//  int result; // eax@12
+	__int64 v30; // [sp+A8h] [bp-30h]@8
+	float v31; // [sp+B0h] [bp-28h]@6
+	float v32; // [sp+B4h] [bp-24h]@6
+	int v33; // [sp+B8h] [bp-20h]@6
+	int v34; // [sp+BCh] [bp-1Ch]@2
+	stru6_stru1_indoor_sw_billboard *v35; // [sp+C0h] [bp-18h]@1
+	float v36; // [sp+C4h] [bp-14h]@6
+	int v37; // [sp+C8h] [bp-10h]@6
+	int v38; // [sp+CCh] [bp-Ch]@1
+	float v39; // [sp+D0h] [bp-8h]@6
+	int *v40; // [sp+D4h] [bp-4h]@2
+
+	//  __debugbreak();// ,           
+	v2 = (char *)&this->field_64[4 * this->uNumVertices];
+	v38 = 0;
+	*(int *)v2 = this->field_64[0];
+	v2 += 4;
+	*(int *)v2 = this->field_64[1];
+	v2 += 4;
+	*(int *)v2 = this->field_64[2];
+	*((int *)v2 + 1) = this->field_64[3];
+	//v3 = this->uNumVertices;
+	v35 = this;
+	if (this->uNumVertices > 0)
+	{
+		v40 = &this->field_64[20];
+		v4 = (char *)&this->field_64[3] + 3;
+
+		//while ( 1 )
+		for (v34 = this->uNumVertices; v34; --v34)
+		{
+			v5 = v4 - 15;
+			if (*(float *)(v4 - 15) <= (double)a2 && *(float *)(v4 + 1) <= (double)a2)
+			{
+				v4 += 16;
+				//--v34;
+				//if ( !v34 )
+				//return this->uNumVertices = v38;
+				continue;
+			}
+			if (*(float *)v5 <= (double)a2)
+			{
+				v6 = (a2 - *(float *)v5) / (*(float *)(v4 + 1) - *(float *)v5);
+				v7 = (unsigned __int8)v4[16] - (unsigned int)(unsigned __int8)*v4;
+				v36 = v6;
+				v31 = (*(float *)(v4 + 5) - *(float *)(v4 - 11)) * v6 + *(float *)(v4 - 11);
+				v32 = (*(float *)(v4 + 9) - *(float *)(v4 - 7)) * v6 + *(float *)(v4 - 7);
+				*(float *)&v37 = (double)v7 * v6;
+				v8 = *(float *)&v37 + 6.7553994e15;
+				v9 = (unsigned __int8)*v4;
+				*(float *)&v37 = (double)((unsigned __int8)v4[15] - (unsigned int)(unsigned __int8)*(v4 - 1)) * v36;
+				v10 = *(float *)&v37 + 6.7553994e15;
+				v11 = (unsigned __int8)*(v4 - 2);
+				v37 = LODWORD(v10) + (unsigned __int8)*(v4 - 1);
+				v39 = (double)((unsigned int)(unsigned __int8)v4[14] - v11) * v36;
+				v12 = v39 + 6.7553994e15;
+				v13 = LODWORD(v12) + (unsigned __int8)*(v4 - 2);
+				v39 = (double)((*(int *)(v4 + 13) & 0xFF) - (*(int *)(v4 - 3) & 0xFFu)) * v36;
+				v14 = v39 + 6.7553994e15;
+				v33 = (LODWORD(v14) + (*(int *)(v4 - 3) & 0xFF)) | ((v13 | ((v37 | ((LODWORD(v8) + v9) << 8)) << 8)) << 8);
+				//this = v35;
+				v5 = (char *)&v30 + 4;
+			}
+			else if (*(float *)(v4 + 1) <= (double)a2)
+			{
+				v15 = (a2 - *(float *)v5) / (*(float *)(v4 + 1) - *(float *)v5);
+				v16 = (unsigned __int8)*v4;
+				HIDWORD(v30) = LODWORD(a2);
+				v17 = (unsigned __int8)v4[16] - v16;
+				v36 = v15;
+				v31 = (*(float *)(v4 + 5) - *(float *)(v4 - 11)) * v15 + *(float *)(v4 - 11);
+				v32 = (*(float *)(v4 + 9) - *(float *)(v4 - 7)) * v15 + *(float *)(v4 - 7);
+				v39 = (double)v17 * v15;
+				v18 = v39 + 6.7553994e15;
+				v19 = (unsigned __int8)*v4;
+				v39 = (double)((unsigned __int8)v4[15] - (unsigned int)(unsigned __int8)*(v4 - 1)) * v36;
+				v20 = v39 + 6.7553994e15;
+				v21 = (unsigned __int8)*(v4 - 2);
+				v37 = LODWORD(v20) + (unsigned __int8)*(v4 - 1);
+				v39 = (double)((unsigned int)(unsigned __int8)v4[14] - v21) * v36;
+				v22 = v39 + 6.7553994e15;
+				v23 = LODWORD(v22) + (unsigned __int8)*(v4 - 2);
+				v39 = (double)((*(int *)(v4 + 13) & 0xFF) - (*(int *)(v4 - 3) & 0xFFu)) * v36;
+				v24 = v39 + 6.7553994e15;
+				v33 = (LODWORD(v24) + (*(int *)(v4 - 3) & 0xFF)) | ((v23 | ((v37 | ((LODWORD(v18) + v19) << 8)) << 8)) << 8);
+				v25 = v40;
+				*v40 = *(int *)v5;
+				v26 = (int)(v5 + 4);
+				++v25;
+				*v25 = *(int *)v26;
+				v26 += 4;
+				++v25;
+				++v38;
+				v40 += 4;
+				*v25 = *(int *)v26;
+				v25[1] = *(int *)(v26 + 4);
+				v5 = (char *)&v30 + 4;
+			}
+			v27 = v40;
+			++v38;
+			*v40 = *(int *)v5;
+			v28 = (int)(v5 + 4);
+			++v27;
+			*v27 = *(int *)v28;
+			v28 += 4;
+			++v27;
+			v40 += 4;
+			*v27 = *(int *)v28;
+			v27[1] = *(int *)(v28 + 4);
+			v4 += 16;
+			//--v34;
+			//if ( !v34 )
+			//return this->uNumVertices = v38;
+		}
+	}
+	return this->uNumVertices = v38;
+}
+
+//----- (00477927) --------------------------------------------------------
+int stru6_stru1_indoor_sw_billboard::_477927(float a2)
+{
+	char *v2; // edi@1
+	int v3; // eax@1
+	char *v4; // edx@2
+	char *v5; // esi@3
+	double v6; // st7@6
+	signed __int64 v7; // ST84_8@6
+	double v8; // ST0C_8@6
+	int v9; // esi@6
+	double v10; // ST44_8@6
+	int v11; // ecx@6
+	double v12; // ST34_8@6
+	int v13; // ecx@6
+	double v14; // ST14_8@6
+	double v15; // st7@8
+	unsigned int v16; // ecx@8
+	signed __int64 v17; // ST64_8@8
+	double v18; // ST24_8@8
+	int v19; // edi@8
+	double v20; // ST3C_8@8
+	int v21; // ecx@8
+	double v22; // ST2C_8@8
+	int v23; // ST9C_4@8
+	double v24; // ST1C_8@8
+	int *v25; // edi@8
+	int v26; // esi@8
+	int *v27; // edi@10
+	int v28; // esi@10
+	//  int result; // eax@12
+	__int64 v30; // [sp+A8h] [bp-30h]@8
+	float v31; // [sp+B0h] [bp-28h]@6
+	float v32; // [sp+B4h] [bp-24h]@6
+	int v33; // [sp+B8h] [bp-20h]@6
+	int v34; // [sp+BCh] [bp-1Ch]@2
+	stru6_stru1_indoor_sw_billboard *v35; // [sp+C0h] [bp-18h]@1
+	float v36; // [sp+C4h] [bp-14h]@6
+	int v37; // [sp+C8h] [bp-10h]@6
+	int v38; // [sp+CCh] [bp-Ch]@1
+	float v39; // [sp+D0h] [bp-8h]@6
+	int *v40; // [sp+D4h] [bp-4h]@2
+
+	__debugbreak();// 
+	v2 = (char *)&this->field_64[4 * this->uNumVertices];
+	v38 = 0;
+	*(int *)v2 = this->field_64[0];
+	v2 += 4;
+	*(int *)v2 = this->field_64[1];
+	v2 += 4;
+	*(int *)v2 = this->field_64[2];
+	*((int *)v2 + 1) = this->field_64[3];
+	v3 = this->uNumVertices;
+	v35 = this;
+	if (v3 > 0)
+	{
+		v40 = &this->field_64[20];
+		v4 = (char *)&this->field_64[3] + 3;
+		v34 = v3;
+		while (1)
+		{
+			v5 = v4 - 15;
+			if (*(float *)(v4 - 15) >= (double)a2 && *(float *)(v4 + 1) >= (double)a2)
+			{
+				v4 += 16;
+				--v34;
+				if (!v34)
+					return this->uNumVertices = v38;
+				continue;
+			}
+			if (*(float *)v5 >= (double)a2)
+			{
+				v6 = (a2 - *(float *)v5) / (*(float *)(v4 + 1) - *(float *)v5);
+				v7 = (unsigned __int8)v4[16] - (unsigned int)(unsigned __int8)*v4;
+				v36 = v6;
+				v31 = (*(float *)(v4 + 5) - *(float *)(v4 - 11)) * v6 + *(float *)(v4 - 11);
+				v32 = (*(float *)(v4 + 9) - *(float *)(v4 - 7)) * v6 + *(float *)(v4 - 7);
+				*(float *)&v37 = (double)v7 * v6;
+				v8 = *(float *)&v37 + 6.7553994e15;
+				v9 = (unsigned __int8)*v4;
+				*(float *)&v37 = (double)((unsigned __int8)v4[15] - (unsigned int)(unsigned __int8)*(v4 - 1)) * v36;
+				v10 = *(float *)&v37 + 6.7553994e15;
+				v11 = (unsigned __int8)*(v4 - 2);
+				v37 = LODWORD(v10) + (unsigned __int8)*(v4 - 1);
+				v39 = (double)((unsigned int)(unsigned __int8)v4[14] - v11) * v36;
+				v12 = v39 + 6.7553994e15;
+				v13 = LODWORD(v12) + (unsigned __int8)*(v4 - 2);
+				v39 = (double)((*(int *)(v4 + 13) & 0xFF) - (*(int *)(v4 - 3) & 0xFFu)) * v36;
+				v14 = v39 + 6.7553994e15;
+				v33 = (LODWORD(v14) + (*(int *)(v4 - 3) & 0xFF)) | ((v13 | ((v37 | ((LODWORD(v8) + v9) << 8)) << 8)) << 8);
+				//this = v35;
+				v5 = (char *)&v30 + 4;
+			}
+			else if (*(float *)(v4 + 1) >= (double)a2)
+			{
+				v15 = (a2 - *(float *)v5) / (*(float *)(v4 + 1) - *(float *)v5);
+				v16 = (unsigned __int8)*v4;
+				HIDWORD(v30) = LODWORD(a2);
+				v17 = (unsigned __int8)v4[16] - v16;
+				v36 = v15;
+				v31 = (*(float *)(v4 + 5) - *(float *)(v4 - 11)) * v15 + *(float *)(v4 - 11);
+				v32 = (*(float *)(v4 + 9) - *(float *)(v4 - 7)) * v15 + *(float *)(v4 - 7);
+				v39 = (double)v17 * v15;
+				v18 = v39 + 6.7553994e15;
+				v19 = (unsigned __int8)*v4;
+				v39 = (double)((unsigned __int8)v4[15] - (unsigned int)(unsigned __int8)*(v4 - 1)) * v36;
+				v20 = v39 + 6.7553994e15;
+				v21 = (unsigned __int8)*(v4 - 2);
+				v37 = LODWORD(v20) + (unsigned __int8)*(v4 - 1);
+				v39 = (double)((unsigned int)(unsigned __int8)v4[14] - v21) * v36;
+				v22 = v39 + 6.7553994e15;
+				v23 = LODWORD(v22) + (unsigned __int8)*(v4 - 2);
+				v39 = (double)((*(int *)(v4 + 13) & 0xFF) - (*(int *)(v4 - 3) & 0xFFu)) * v36;
+				v24 = v39 + 6.7553994e15;
+				v33 = (LODWORD(v24) + (*(int *)(v4 - 3) & 0xFF)) | ((v23 | ((v37 | ((LODWORD(v18) + v19) << 8)) << 8)) << 8);
+				v25 = v40;
+				*v40 = *(int *)v5;
+				v26 = (int)(v5 + 4);
+				++v25;
+				*v25 = *(int *)v26;
+				v26 += 4;
+				++v25;
+				++v38;
+				v40 += 4;
+				*v25 = *(int *)v26;
+				v25[1] = *(int *)(v26 + 4);
+				v5 = (char *)&v30 + 4;
+			}
+			v27 = v40;
+			++v38;
+			*v40 = *(int *)v5;
+			v28 = (int)(v5 + 4);
+			++v27;
+			*v27 = *(int *)v28;
+			v28 += 4;
+			++v27;
+			v40 += 4;
+			*v27 = *(int *)v28;
+			v27[1] = *(int *)(v28 + 4);
+			v4 += 16;
+			--v34;
+			if (!v34)
+				return this->uNumVertices = v38;
+		}
+	}
+	return this->uNumVertices = v38;
+}
+
+//----- (00477C61) --------------------------------------------------------
+int stru6_stru1_indoor_sw_billboard::sub_477C61()
+{
+	//stru6_stru1_indoor_sw_billboard *v1; // ebx@1
+	int v2; // ecx@2
+	int v3; // eax@3
+	double v4; // st7@4
+	double v5; // st7@5
+	double v6; // st6@5
+	double v7; // st5@6
+	float v8; // ST30_4@8
+	float v9; // ST24_4@8
+	double v10; // st7@8
+	double v11; // st6@8
+	double v12; // st5@8
+	float v13; // ST24_4@13
+	int v14; // esi@13
+	char *v15; // esi@15
+	//signed int v16; // eax@16
+	//  __int16 v17; // fps@16
+	//  unsigned __int8 v18; // c2@16
+	//  unsigned __int8 v19; // c3@16
+	double v20; // st6@16
+	float v21; // ST18_4@17
+	float v22; // ST2C_4@17
+	float v23; // ST34_4@17
+	float v24; // ST24_4@17
+	double v25; // st7@17
+	double v26; // st6@17
+	float v27; // ST34_4@18
+	float v28; // ST30_4@18
+	int v29; // eax@19
+	signed int v31; // [sp+8h] [bp-28h]@15
+	float v32; // [sp+Ch] [bp-24h]@16
+	float v33; // [sp+14h] [bp-1Ch]@16
+	float v34; // [sp+18h] [bp-18h]@16
+	float v35; // [sp+1Ch] [bp-14h]@17
+	float v36; // [sp+20h] [bp-10h]@4
+	float v37; // [sp+24h] [bp-Ch]@4
+	float v38; // [sp+24h] [bp-Ch]@16
+	float v39; // [sp+28h] [bp-8h]@9
+	float v40; // [sp+28h] [bp-8h]@16
+	float v41; // [sp+2Ch] [bp-4h]@6
+	float v42; // [sp+2Ch] [bp-4h]@9
+
+	//__debugbreak();// ,       
+	if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
+	{
+
+		if (this->uNumVertices > 0)
+		{
+			v3 = (int)&this->field_14[1];
+			//do
+			for (v2 = 0; v2 < this->uNumVertices; ++v2)
+			{
+				v4 = *(float *)(v3 - 4);
+				LODWORD(v37) = *(int *)v3;
+				LODWORD(v36) = *(int *)(v3 + 4);
+				if (pIndoorCameraD3D->sRotationX)
+				{
+					v5 = v4 - (double)pIndoorCameraD3D->vPartyPos.x;
+					v6 = v37 - (double)pIndoorCameraD3D->vPartyPos.y;
+					//if ( pRenderer->pRenderD3D )
+					//{
+					v41 = pIndoorCameraD3D->fRotationYSine * v6 + pIndoorCameraD3D->fRotationYCosine * v5;
+					v7 = pIndoorCameraD3D->fRotationYSine * v5 - pIndoorCameraD3D->fRotationYCosine * v6;
+					/*}
+					else
+					{
+					v41 = pBLVRenderParams->fCosineY * v5 - pBLVRenderParams->fSineY * v6;
+					v7 = pBLVRenderParams->fSineY * v5 + pBLVRenderParams->fCosineY * v6;
+					}*/
+					v8 = v7;
+					v9 = v36 - (double)pIndoorCameraD3D->vPartyPos.z;
+					v10 = pIndoorCameraD3D->fRotationXCosine * v41 - pIndoorCameraD3D->fRotationXSine * v9;
+					v11 = v8;
+					v12 = pIndoorCameraD3D->fRotationXCosine * v9 + pIndoorCameraD3D->fRotationXSine * v41;
+				}
+				else
+				{
+					v42 = v4 - (double)pIndoorCameraD3D->vPartyPos.x;
+					v39 = v37 - (double)pIndoorCameraD3D->vPartyPos.y;
+					//if ( pRenderer->pRenderD3D )
+					//{
+					v10 = pIndoorCameraD3D->fRotationYSine * v39 + pIndoorCameraD3D->fRotationYCosine * v42;
+					v11 = pIndoorCameraD3D->fRotationYSine * v42 - pIndoorCameraD3D->fRotationYCosine * v39;
+					/*}
+					else
+					{
+					v10 = pBLVRenderParams->fCosineY * v42 - pBLVRenderParams->fSineY * v39;
+					v11 = pBLVRenderParams->fSineY * v42 + pBLVRenderParams->fCosineY * v39;
+					}*/
+					v12 = v36 - (double)pIndoorCameraD3D->vPartyPos.z;
+				}
+				v13 = v12;
+				//++v2;
+				*(int *)(v3 + 84) = LODWORD(v13);
+				v14 = *(int *)(v3 + 8);
+				*(float *)(v3 + 76) = v10;
+				*(int *)(v3 + 88) = v14;
+				*(float *)(v3 + 80) = v11;
+				v3 += 16;
+			}
+			//while ( v2 < this->uNumVertices );
+		}
+	}
+	else
+	{
+		v15 = (char *)&this->field_14[1];
+		//do
+		for (v31 = 3; v31; --v31)
+		{
+			v40 = (double)stru_5C6E00->Cos(pIndoorCameraD3D->sRotationX) * 0.0000152587890625;
+			v32 = (double)stru_5C6E00->Sin(pIndoorCameraD3D->sRotationX) * 0.0000152587890625;
+			v34 = (double)stru_5C6E00->Cos(pIndoorCameraD3D->sRotationY) * 0.0000152587890625;
+			v33 = (double)stru_5C6E00->Sin(pIndoorCameraD3D->sRotationY) * 0.0000152587890625;
+			//v16 = stru_5C6E00->Sin(pODMRenderParams->rotation_y);
+			LODWORD(v38) = *(int *)v15;
+			//UNDEF(v17);
+			v20 = *((float *)v15 - 1) - (double)pIndoorCameraD3D->vPartyPos.x;
+			//if ( v19 | v18 )
+			if (pIndoorCameraD3D->vPartyPos.x == 0)
+			{
+				v27 = v20;
+				LODWORD(v35) = *((int *)v15 + 1);
+				v28 = v38 - (double)pIndoorCameraD3D->vPartyPos.y;
+				v25 = v33 * v28 + v34 * v27;
+				v26 = v34 * v28 - v33 * v27;
+			}
+			else
+			{
+				v21 = v20;
+				v22 = v38 - (double)pIndoorCameraD3D->vPartyPos.y;
+				v23 = v33 * v22 + v34 * v21;
+				v24 = *((float *)v15 + 1) - (double)pIndoorCameraD3D->vPartyPos.z;
+				v25 = v32 * v24 + v40 * v23;
+				v26 = v34 * v22 - v33 * v21;
+				v35 = v40 * v24 - v32 * v23;
+			}
+			*((int *)v15 + 21) = LODWORD(v35);
+			v29 = *((int *)v15 + 2);
+			*((float *)v15 + 19) = v25;
+			*((int *)v15 + 22) = v29;
+			*((float *)v15 + 20) = v26;
+			v15 += 16;
+			//--v31;
+		}
+		//while ( v31 );
+	}
+	this->uNumVertices = 3;
+	return 1;
+}
+
+//----- (00477F63) --------------------------------------------------------
+bool stru6_stru1_indoor_sw_billboard::sub_477F63()
+{
+	signed int v1; // ebx@1
+	double v3; // st7@2
+	//int v4; // edx@4
+	char *v5; // ecx@5
+	int v6; // edi@5
+	float v7; // ST08_4@13
+	signed int v9; // [sp+Ch] [bp-8h]@1
+	float v10; // [sp+10h] [bp-4h]@2
+
+	//__debugbreak();// 
+	v1 = 0;
+	v9 = 0;
+	if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
+	{
+		v10 = 16192.0;
+		v3 = (double)pBLVRenderParams->fov_rad_fixpoint * 0.000015258789;
+	}
+	else if (uCurrentlyLoadedLevelType == LEVEL_Outdoor)
+	{
+		v10 = (double)pODMRenderParams->shading_dist_mist;
+		v3 = 8.0;
+	}
+	else
+		__debugbreak();//Error
+	if (this->uNumVertices <= 0)
+	{
+		memcpy(&this->field_14[40], &this->field_14[20], 16 * this->uNumVertices);
+		return this->uNumVertices != 0;
+	}
+	v5 = (char *)&this->field_14[20];
+	for (v6 = 0; v6 < this->uNumVertices; v6++)
+	{
+		if (v3 >= *(float *)v5 || *(float *)v5 >= (double)v10)
+		{
+			if (v3 < *(float *)v5)
+				v9 = 1;
+			else
+				v1 = 1;
+		}
+		v5 += 16;
+	}
+	if (!v1)
+	{
+		if (v9)
+		{
+			this->_477927(v10);
+			return this->uNumVertices != 0;
+		}
+		memcpy(&this->field_14[40], &this->field_14[20], 16 * this->uNumVertices);
+		return this->uNumVertices != 0;
+	}
+	v7 = v3;
+	_4775ED(v7);
+	return this->uNumVertices != 0;
+}
+
+//----- (0047802A) --------------------------------------------------------
+int stru6_stru1_indoor_sw_billboard::sub_47802A()
+{
+	double v6; // st7@4
+	signed int v16; // [sp+38h] [bp-Ch]@1
+	int a6; // [sp+3Ch] [bp-8h]@5
+	int a5; // [sp+40h] [bp-4h]@5
+
+	//  __debugbreak(); //  this->field_B4[i*4+16]
+	v16 = 0;
+	if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
+	{
+		for (int i = 0; i < this->uNumVertices; i++)
+		{
+			v6 = (double)pBLVRenderParams->fov_rad_fixpoint * 0.000015258789 / this->field_B4[i * 4];
+			//if ( pRenderer->pRenderD3D )
+			{
+				pIndoorCameraD3D->Project(round_to_int(this->field_B4[i * 4]), round_to_int(this->field_B4[i * 4 + 1]), round_to_int(this->field_B4[i * 4 + 2]),
+					&a5, &a6);
+				this->field_B4[i * 4 + 16] = (double)a5;
+				this->field_B4[i * 4 + 17] = (double)a6;
+				this->field_B4[i * 4 + 18] = round_to_int(this->field_B4[i * 4]);
+			}
+			/*else
+			{
+			this->field_B4[i*4+16] = (double)pBLVRenderParams->uViewportCenterX - v6 * this->field_B4[i*4+1];
+			this->field_B4[i*4+17] = (double)pBLVRenderParams->uViewportCenterY - v6 * this->field_B4[i*4+2];
+			this->field_B4[i*4+18] = this->field_B4[i*4];
+			}*/
+			this->field_B4[i * 4 + 19] = this->field_B4[i * 4 + 3];
+			if ((double)(signed int)pViewport->uViewportTL_X <= this->field_B4[i * 4 + 16] && (double)(signed int)pViewport->uViewportBR_X > this->field_B4[i * 4 + 16]
+				&& (double)(signed int)pViewport->uViewportTL_Y <= this->field_B4[i * 4 + 17] && (double)(signed int)pViewport->uViewportBR_Y > this->field_B4[i * 4 + 17])
+				v16 = 1;
+		}
+	}
+	else
+	{
+		for (int i = 0; i < this->uNumVertices; i++)
+		{
+			this->field_B4[i * 4 + 20] = (double)pViewport->uScreenCenterX - (double)pODMRenderParams->int_fov_rad / this->field_B4[i * 4] * this->field_B4[i * 4 + 1];
+			this->field_B4[i * 4 + 21] = (double)pViewport->uScreenCenterY - (double)pODMRenderParams->int_fov_rad / this->field_B4[i * 4] * this->field_B4[i * 4 + 2];
+			*((int *)&this->field_B4[i * 4 + 22]) = (int)this->field_B4[i * 4];
+			*((int *)&this->field_B4[i * 4 + 23]) = this->field_B4[i * 4 + 3];
+			if ((double)(signed int)pViewport->uViewportTL_X <= this->field_B4[i * 4 + 20] && (double)(signed int)pViewport->uViewportBR_X > this->field_B4[i * 4 + 20]
+				&& (double)(signed int)pViewport->uViewportTL_Y <= this->field_B4[i * 4 + 21] && (double)(signed int)pViewport->uViewportBR_Y > this->field_B4[i * 4 + 21])
+				v16 = 1;
+		}
+	}
+	return v16;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Engine/stru6.h	Thu May 21 18:33:07 2015 +0600
@@ -0,0 +1,169 @@
+#pragma once
+
+
+/*  120 */
+#pragma pack(push, 1)
+struct stru6_stru1_indoor_sw_billboard
+{
+  //----- (004775B1) --------------------------------------------------------
+  inline stru6_stru1_indoor_sw_billboard()
+  {
+    uNumVertices = 0;
+    uNumVec4sInArray1 = 0;
+    uNumVec3sInArray2 = 0;
+    pArray1 = nullptr;
+    pArray2 = nullptr;
+  }
+
+  //----- (004775C4) --------------------------------------------------------
+  virtual ~stru6_stru1_indoor_sw_billboard();
+
+  int _4775ED(float a2);
+  int _477927(float a2);
+  int sub_477C61();
+  bool sub_477F63();
+  int sub_47802A();
+  void Initialize(int a2);
+  void _47829F_sphere_particle(float x_offset, float y_offset, float z_offset, float scale, int diffuse);
+
+
+  struct local_01
+  {
+    float x;
+    float y;
+    float z;
+    int   diffuse;
+  };
+
+  unsigned int uNumVec4sInArray1;
+  struct stru16x *pArray1;
+  unsigned int uNumVec3sInArray2;
+  struct stru160 *pArray2;
+  int uNumVertices;
+  local_01 field_14[5];
+  int field_64[20];
+  float field_B4[20];
+  local_01 field_104[5];
+};
+#pragma pack(pop)
+
+
+/*  122 */
+#pragma pack(push, 1)
+struct PlayerBuffAnim
+{
+  inline PlayerBuffAnim():
+    bRender(false), uSpellAnimTime(0), uSpellIconID(0)
+  {}
+
+  __int16 bRender;
+  __int16 field_2;
+  int uSpellAnimTimeElapsed;
+  int uSpellAnimTime;
+  int uSpellIconID;
+};
+#pragma pack(pop)
+
+
+/*  307 */
+#pragma pack(push, 1)
+struct ProjectileAnim
+{
+  float srcX;
+  float srcY;
+  float srcZ;
+  float dstX;
+  float dstY;
+  float dstZ;
+  int uTextureID;
+};
+#pragma pack(pop)
+
+
+/*  306 */
+#pragma pack(push, 1)
+struct stru6_stru2
+{
+  //int field_0;
+  float flt_0_x;
+  float flt_4_y;
+  float flt_8_z;
+  int   field_C;
+};
+#pragma pack(pop)
+
+
+
+/*  121 */
+#pragma pack(push, 1)
+struct stru6
+{
+  //----- (004A7155) --------------------------------------------------------
+  stru6()
+  {
+    this->field_204 = 0;
+    this->uFadeTime = 0;
+    this->uNumProjectiles = 0;
+    this->field_0 = 0;
+	this->uAnimLength = 0;
+
+    pStru1 = new stru6_stru1_indoor_sw_billboard;
+    pStru1->Initialize(0xFF3C1Eu);
+  }
+  //----- (004A71DC) --------------------------------------------------------
+  ~stru6()
+  {
+    delete pStru1;
+    pStru1 = nullptr;
+  }
+
+  void DoAddProjectile(float srcX, float srcY, float srcZ, float dstX, float dstY, float dstZ, unsigned int uTextureID);
+  void DrawProjectiles();
+  void _4A73AA_hanging_trace_particles___like_fire_strike_ice_blast_etc(struct SpriteObject *a2, unsigned int uDiffuse, unsigned int uTextureID);
+  void _4A75CC_single_spell_collision_particle(struct SpriteObject *a1, unsigned int uDiffuse, unsigned int uTextureID);
+  void _4A7688_fireball_collision_particle(struct SpriteObject *a2);
+  void _4A77FD_implosion_particle_d3d(struct SpriteObject *a1);
+  void _4A78AE_sparks_spell(struct SpriteObject *a1);
+  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_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 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();
+  void RenderSpecialEffects();
+  void DrawPlayerBuffAnims();
+  void LoadAnimations();
+
+
+  int field_0;
+  stru6_stru2 array_4[31];
+  int field_1F4;
+  int field_1F8;
+  int field_1FC;
+  int field_200;
+  int field_204;
+  PlayerBuffAnim pPlayerBuffs[4];
+  ProjectileAnim pProjectiles[32];
+  int uNumProjectiles;
+  stru6_stru1_indoor_sw_billboard *pStru1;
+  int field_5D0;
+  int uAnimLength;
+  int uFadeTime;
+  int uFadeLength;
+  int uFadeColor;
+  unsigned int uTextureID_effpar1;
+  unsigned int uTextureID_effpar2;
+  unsigned int uTextureID_effpar3;
+  unsigned int uSpriteID_sp57c;
+  int field_5F4;
+};
+#pragma pack(pop)
+
+
--- a/GUI/UI/UIArena.cpp	Thu May 21 18:32:45 2015 +0600
+++ b/GUI/UI/UIArena.cpp	Thu May 21 18:33:07 2015 +0600
@@ -1,9 +1,8 @@
 #define _CRTDBG_MAP_ALLOC
+#define _CRT_SECURE_NO_WARNINGS
 #include <stdlib.h>
 #include <crtdbg.h>
 
-#define _CRT_SECURE_NO_WARNINGS
-
 #include "Engine/Engine.h"
 
 #include "../../Engine/Graphics/Sprites.h"
--- a/GUI/UI/UICharacter.cpp	Thu May 21 18:32:45 2015 +0600
+++ b/GUI/UI/UICharacter.cpp	Thu May 21 18:33:07 2015 +0600
@@ -1,8 +1,7 @@
 #define _CRTDBG_MAP_ALLOC
+#define _CRT_SECURE_NO_WARNINGS
 #include <stdlib.h>
 #include <crtdbg.h>
-
-#define _CRT_SECURE_NO_WARNINGS
 #include <algorithm> 
 
 #include "Engine/Engine.h"
@@ -910,7 +909,7 @@
       item = player->GetMainHandItem();
       item_X = pPaperdoll_BodyX + paperdoll_Weapon[pBodyComplection][1][0] - pItemsTable->pItems[item->uItemID].uEquipX;
       item_Y = pPaperdoll_BodyY + paperdoll_Weapon[pBodyComplection][1][1] - pItemsTable->pItems[item->uItemID].uEquipY;
-      if ( item->uItemID == 64 )  //blaster
+      if (item->uItemID == ITEM_BLASTER)
         v166 = "item64v1";
       else
         v166 = item->GetIconName();
@@ -1479,7 +1478,7 @@
       item = player->GetMainHandItem();
       item_X = pPaperdoll_BodyX + paperdoll_Weapon[pBodyComplection][1][0] - pItemsTable->pItems[item->uItemID].uEquipX;
       item_Y = pPaperdoll_BodyY + paperdoll_Weapon[pBodyComplection][1][1] - pItemsTable->pItems[item->uItemID].uEquipY;
-      if ( item->uItemID == 64 )
+      if (item->uItemID == ITEM_BLASTER)
         v181 = "item64v1";
       else
         v181 = item->GetIconName();
--- a/GUI/UI/UIPartyCreation.cpp	Thu May 21 18:32:45 2015 +0600
+++ b/GUI/UI/UIPartyCreation.cpp	Thu May 21 18:33:07 2015 +0600
@@ -663,44 +663,44 @@
 
       switch (j)
       {
-        case PLAYER_SKILL_STAFF:   pParty->pPlayers[i].AddItem(-1, 61); break;
-        case PLAYER_SKILL_SWORD:   pParty->pPlayers[i].AddItem(-1, 1); break;
-        case PLAYER_SKILL_DAGGER:  pParty->pPlayers[i].AddItem(-1, 15); break;
-        case PLAYER_SKILL_AXE:     pParty->pPlayers[i].AddItem(-1, 23); break;
-        case PLAYER_SKILL_SPEAR:   pParty->pPlayers[i].AddItem(-1, 31); break;
-        case PLAYER_SKILL_BOW:     pParty->pPlayers[i].AddItem(-1, 47); break;
-        case PLAYER_SKILL_MACE:    pParty->pPlayers[i].AddItem(-1, 50); break;
+        case PLAYER_SKILL_STAFF:   pParty->pPlayers[i].AddItem(-1, ITEM_STAFF_1); break;
+        case PLAYER_SKILL_SWORD:   pParty->pPlayers[i].AddItem(-1, ITEM_LONGSWORD_1); break;
+        case PLAYER_SKILL_DAGGER:  pParty->pPlayers[i].AddItem(-1, ITEM_DAGGER_1); break;
+        case PLAYER_SKILL_AXE:     pParty->pPlayers[i].AddItem(-1, ITEM_AXE_1); break;
+        case PLAYER_SKILL_SPEAR:   pParty->pPlayers[i].AddItem(-1, ITEM_SPEAR_1); break;
+        case PLAYER_SKILL_BOW:     pParty->pPlayers[i].AddItem(-1, ITEM_CROSSBOW_1); break;
+        case PLAYER_SKILL_MACE:    pParty->pPlayers[i].AddItem(-1, ITEM_MACE_1); break;
         case PLAYER_SKILL_BLASTER: Error("No blasters at startup :p");
-        case PLAYER_SKILL_SHIELD:  pParty->pPlayers[i].AddItem(-1, 84); break;
-        case PLAYER_SKILL_LEATHER: pParty->pPlayers[i].AddItem(-1, 66); break;
-        case PLAYER_SKILL_CHAIN:   pParty->pPlayers[i].AddItem(-1, 71); break;
-        case PLAYER_SKILL_PLATE:   pParty->pPlayers[i].AddItem(-1, 76); break;
+        case PLAYER_SKILL_SHIELD:  pParty->pPlayers[i].AddItem(-1, ITEM_BUCKLER_1); break;
+        case PLAYER_SKILL_LEATHER: pParty->pPlayers[i].AddItem(-1, ITEM_LEATHER_1); break;
+        case PLAYER_SKILL_CHAIN:   pParty->pPlayers[i].AddItem(-1, ITEM_CHAINMAIL_1); break;
+        case PLAYER_SKILL_PLATE:   pParty->pPlayers[i].AddItem(-1, ITEM_PLATE_1); break;
         case PLAYER_SKILL_FIRE:
-          pParty->pPlayers[i].AddItem(-1, 0x191);
+            pParty->pPlayers[i].AddItem(-1, ITEM_SPELLBOOK_FIRE_STRIKE);
           pParty->pPlayers[i].spellbook.pFireSpellbook.bIsSpellAvailable[0] = true;
         break;
         case PLAYER_SKILL_AIR:
-          pParty->pPlayers[i].AddItem(-1, 0x19C);
+            pParty->pPlayers[i].AddItem(-1, ITEM_SPELLBOOK_AIR_FEATHER_FALL);
           pParty->pPlayers[i].spellbook.pAirSpellbook.bIsSpellAvailable[0] = true;
         break;
         case PLAYER_SKILL_WATER:
-          pParty->pPlayers[i].AddItem(-1, 0x1A7);
+            pParty->pPlayers[i].AddItem(-1, ITEM_SPELLBOOK_WATER_POISON_SPRAY);
           pParty->pPlayers[i].spellbook.pWaterSpellbook.bIsSpellAvailable[0] = true;
         break;
         case PLAYER_SKILL_EARTH:
-          pParty->pPlayers[i].AddItem(-1, 0x1B2);
+            pParty->pPlayers[i].AddItem(-1, ITEM_SPELLBOOK_EARTH_SLOW);
           pParty->pPlayers[i].spellbook.pEarthSpellbook.bIsSpellAvailable[0] = true;
         break;
         case PLAYER_SKILL_SPIRIT:
-          pParty->pPlayers[i].AddItem(-1, 0x1BD);
+            pParty->pPlayers[i].AddItem(-1, ITEM_SPELLBOOK_SPIRIT_BLESS);
           pParty->pPlayers[i].spellbook.pSpiritSpellbook.bIsSpellAvailable[0] = true;
         break;
         case PLAYER_SKILL_MIND:
-          pParty->pPlayers[i].AddItem(-1, 0x1C8);
+            pParty->pPlayers[i].AddItem(-1, ITEM_SPELLBOOK_MIND_MIND_BLAST);
           pParty->pPlayers[i].spellbook.pMindSpellbook.bIsSpellAvailable[0] = true;
         break;
         case PLAYER_SKILL_BODY:
-          pParty->pPlayers[i].AddItem(-1, 0x1D3);
+            pParty->pPlayers[i].AddItem(-1, ITEM_SPELLBOOK_BODY_FIRST_AID);
           pParty->pPlayers[i].spellbook.pBodySpellbook.bIsSpellAvailable[0] = true;
         break;
         case PLAYER_SKILL_LIGHT:
@@ -714,11 +714,11 @@
         case PLAYER_SKILL_PERCEPTION:
         case PLAYER_SKILL_TRAP_DISARM:
         case PLAYER_SKILL_LEARNING:
-          pParty->pPlayers[i].AddItem(-1, 0xDC);
+            pParty->pPlayers[i].AddItem(-1, ITEM_POTION_BOTTLE);
           pParty->pPlayers[i].AddItem(-1, 5 * (rand() % 3 + 40));
         break;
-        case PLAYER_SKILL_DODGE:   pParty->pPlayers[i].AddItem(-1, 115); break;
-        case PLAYER_SKILL_UNARMED: pParty->pPlayers[i].AddItem(-1, 110); break;
+        case PLAYER_SKILL_DODGE:   pParty->pPlayers[i].AddItem(-1, ITEM_BOOTS_1); break;
+        case PLAYER_SKILL_UNARMED: pParty->pPlayers[i].AddItem(-1, ITEM_GAUNTLETS_1); break;
         default:
           break;
       }
--- a/GUI/UI/UIPopup.cpp	Thu May 21 18:32:45 2015 +0600
+++ b/GUI/UI/UIPopup.cpp	Thu May 21 18:33:07 2015 +0600
@@ -157,7 +157,7 @@
     inspect_item->SetIdentified();
   v77 = 0;
   if (inspect_item->GetItemEquipType() == EQUIP_GOLD)
-    v77 = inspect_item->uSpecEnchantmentType;
+    v77 = inspect_item->special_enchantment;
   if ( uActiveCharacter )
   {
   //try to identify
@@ -300,8 +300,8 @@
       sprintf(out_text + 200, "%s: %d", pGlobalTXT_LocalizationStrings[449], inspect_item->GetDamageDice()); //"Power"
     else if ( inspect_item->uEnchantmentType )
       sprintf(out_text + 200, "%s: %s +%d", pGlobalTXT_LocalizationStrings[210], pItemsTable->pEnchantments[inspect_item->uEnchantmentType-1].pBonusStat, inspect_item->m_enchantmentStrength); //"Special"
-    else  if ( inspect_item->uSpecEnchantmentType )
-      sprintf(out_text + 200, "%s: %s", pGlobalTXT_LocalizationStrings[210], pItemsTable->pSpecialEnchantments[inspect_item->uSpecEnchantmentType-1].pBonusStatement);
+    else  if ( inspect_item->special_enchantment )
+      sprintf(out_text + 200, "%s: %s", pGlobalTXT_LocalizationStrings[210], pItemsTable->pSpecialEnchantments[inspect_item->special_enchantment-1].pBonusStatement);
     else if ( inspect_item->uNumCharges )
       sprintf(out_text + 200, "%s: %lu", pGlobalTXT_LocalizationStrings[464], inspect_item->uNumCharges); //"Charges"
   }
@@ -323,7 +323,7 @@
                                      TEXTURE_16BIT_PALETTE)->uTextureHeight + v81 + 54;
   if ( (signed int)Str > (signed int)iteminfo_window.uFrameHeight )
     iteminfo_window.uFrameHeight = (unsigned int)Str;
-  if ( inspect_item->uAttributes & ITEM_TEMP_BONUS && (inspect_item->uSpecEnchantmentType || inspect_item->uEnchantmentType) )
+  if ( inspect_item->uAttributes & ITEM_TEMP_BONUS && (inspect_item->special_enchantment || inspect_item->uEnchantmentType) )
     iteminfo_window.uFrameHeight += LOBYTE(pFontComic->uFontHeight);
   v85 = 0;
   if ( pFontArrus->uFontHeight )
@@ -375,7 +375,7 @@
   }
   else
   {
-    if ( (inspect_item->uAttributes & ITEM_TEMP_BONUS) && (inspect_item->uSpecEnchantmentType || inspect_item->uEnchantmentType) )
+    if ( (inspect_item->uAttributes & ITEM_TEMP_BONUS) && (inspect_item->special_enchantment || inspect_item->uEnchantmentType) )
     {
       init_summoned_item(&v67, inspect_item->uExpireTime - pParty->uTimePlayed);
       strcpy(pTmpBuf.data(), "Duration:");
@@ -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);
           }
         }
       }
@@ -1719,7 +1719,7 @@
       if (item->uItemID >= ITEM_BLASTER && item->uItemID <= ITEM_LASER_RIFLE ||
           item->uItemID >= ITEM_ARTIFACT_PUCK ||
           item->IsBroken() ||
-          item->uSpecEnchantmentType ||
+          item->special_enchantment ||
           item->uEnchantmentType ||
           item->GetItemEquipType() >= EQUIP_ARMOUR)  // only melee weapons and bows
       {
@@ -1731,18 +1731,22 @@
       item->UpdateTempBonus(pParty->uTimePlayed);
       if (pParty->pPickedItem.uItemID == ITEM_POTION_SLAYING_POTION)
       {
-        item->uSpecEnchantmentType = 40; // of Slaying
+          item->special_enchantment = ITEM_ENCHANTMENT_40; // of Slaying
         v31 = (double)(1800 * pParty->pPickedItem.uEnchantmentType * 128);
       }
       else
       {
-        static int _4E2904_enchantment_by_potion_lut[] =
-        {
-          164, 93, 22,
-          164, 93, 22,
-          11, 5, 13, 7, 59
-        };
-        item->uSpecEnchantmentType = _4E2904_enchantment_by_potion_lut[pParty->pPickedItem.uItemID - 240];
+          static ITEM_ENCHANTMENT _4E2904_enchantment_by_potion_lut[] =
+          {
+              (ITEM_ENCHANTMENT)164, (ITEM_ENCHANTMENT)93, (ITEM_ENCHANTMENT)22,
+              (ITEM_ENCHANTMENT)164, (ITEM_ENCHANTMENT)93, (ITEM_ENCHANTMENT)22,
+              ITEM_ENCHANTMENT_OF_FLAME,
+              ITEM_ENCHANTMENT_OF_FROST,
+              ITEM_ENCHANTMENT_OF_POISON,
+              ITEM_ENCHANTMENT_OF_SPARKS,
+              (ITEM_ENCHANTMENT)59
+          };
+        item->special_enchantment = _4E2904_enchantment_by_potion_lut[pParty->pPickedItem.uItemID - 240];
         v31 = (double)(1800 * pParty->pPickedItem.uEnchantmentType * 128);
       }
 
@@ -1764,33 +1768,36 @@
     pPlayers[uActiveCharacter]->pInventoryItemList[item_pid].uEnchantmentType = alchemy_skill_points + pParty->pPickedItem.GetDamageDice();
     switch ( pParty->pPickedItem.uItemID )
     {
-      case 200:
-      case 201:
-      case 202:
-      case 203:
-      case 204:
-        pPlayers[uActiveCharacter]->pInventoryItemList[item_pid].uItemID = 222;
+    case ITEM_REAGENT_WIDOWSWEEP_BERRIES:
+    case ITEM_REAGENT_CRUSHED_ROSE_PETALS:
+    case ITEM_TROLL_BLOOD:
+    case ITEM_TROLL_RUBY:
+    case ITEM_DRAGON_EYE:
+          pPlayers[uActiveCharacter]->pInventoryItemList[item_pid].uItemID = ITEM_POTION_CURE_WOUNDS;
         break;
-      case 205:
-      case 206:
-      case 207:
-      case 208:
-      case 209:
-        pPlayers[uActiveCharacter]->pInventoryItemList[item_pid].uItemID = 223;
+
+    case ITEM_PHIMA_ROOT:
+    case ITEM_METEORITE_FRAGMENT:
+    case ITEM_HARPY_FEATHER:
+    case ITEM_MOONSTONE:
+    case ITEM_ELVISH_TOADSTOOL:
+          pPlayers[uActiveCharacter]->pInventoryItemList[item_pid].uItemID = ITEM_POTION_MAGIC_POTION;
         break;
-      case 210:
-      case 211:
-      case 212:
-      case 213:
-      case 214:
-        pPlayers[uActiveCharacter]->pInventoryItemList[item_pid].uItemID = 224;
+
+    case ITEM_POPPYSNAPS:
+    case ITEM_FAE_DUST:
+    case ITEM_SULFUR:
+    case ITEM_GARNET:
+    case ITEM_DEVIL_ICHOR:
+          pPlayers[uActiveCharacter]->pInventoryItemList[item_pid].uItemID = ITEM_POTION_CURE_WEAKNESS;
         break;
-      case 215:
-      case 216:
-      case 217:
-      case 218:
-      case 219:
-        pPlayers[uActiveCharacter]->pInventoryItemList[item_pid].uItemID = 221;
+
+    case ITEM_MUSHROOM:
+    case ITEM_OBSIDIAN:
+    case ITEM_OOZE_ENDOPLASM_VIAL:
+    case ITEM_MERCURY:
+    case ITEM_REAGENT_PHILOSOPHERS_STONE:
+          pPlayers[uActiveCharacter]->pInventoryItemList[item_pid].uItemID = ITEM_POTION_CATALYST;
         break;
       default:
         break;
@@ -1855,119 +1862,60 @@
       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 )
       {
-        if ( pPlayers[uActiveCharacter]->pInventoryItemList[item_pid].uItemID == 221 || pParty->pPickedItem.uItemID == 221 )//catalyst()
+          if (pPlayers[uActiveCharacter]->pInventoryItemList[item_pid].uItemID == ITEM_POTION_CATALYST || pParty->pPickedItem.uItemID == ITEM_POTION_CATALYST)
         {
-          if ( pPlayers[uActiveCharacter]->pInventoryItemList[item_pid].uItemID == 221 )
+            if (pPlayers[uActiveCharacter]->pInventoryItemList[item_pid].uItemID == ITEM_POTION_CATALYST)
             pPlayers[uActiveCharacter]->pInventoryItemList[item_pid].uItemID = pParty->pPickedItem.uItemID;
-          if ( pParty->pPickedItem.uItemID == 221 )
+          if (pParty->pPickedItem.uItemID == ITEM_POTION_CATALYST)
             pPlayers[uActiveCharacter]->pInventoryItemList[item_pid].uEnchantmentType = pParty->pPickedItem.uEnchantmentType;
         }
         else
@@ -1977,7 +1925,7 @@
                                             + pPlayers[uActiveCharacter]->pInventoryItemList[item_pid].uEnchantmentType) / 2;
           pPlayers[uActiveCharacter]->SetVariable(VAR_AutoNotes, pItemsTable->potion_note[potion1_id][potion2_id]);
         }
-        int bottle = pPlayers[uActiveCharacter]->AddItem(-1, 220);//
+          int bottle = pPlayers[uActiveCharacter]->AddItem(-1, ITEM_POTION_BOTTLE);
         if ( bottle )
           pPlayers[uActiveCharacter]->pOwnItems[bottle - 1].uAttributes = ITEM_IDENTIFIED;
         if ( !(pItemsTable->pItems[pPlayers[uActiveCharacter]->pInventoryItemList[item_pid].uItemID].uItemID_Rep_St) )
--- a/GUI/UI/UiGame.cpp	Thu May 21 18:32:45 2015 +0600
+++ b/GUI/UI/UiGame.cpp	Thu May 21 18:33:07 2015 +0600
@@ -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	Thu May 21 18:32:45 2015 +0600
+++ b/Game/Game.cpp	Thu May 21 18:33:07 2015 +0600
@@ -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/IO/Mouse.cpp	Thu May 21 18:32:45 2015 +0600
+++ b/IO/Mouse.cpp	Thu May 21 18:33:07 2015 +0600
@@ -772,6 +772,8 @@
           for ( v4 = pWindowList[v3]->pStartingPosActiveItem; v4 < v29; ++v4 )
           {
             pButton = pWindowList[v3]->pControlsHead;
+            if (!pButton)
+                continue;
             if ( v4 > 0 )
             {
               for ( v15 = v4; v15; --v15 )
--- a/Media/Audio/AudioPlayer.cpp	Thu May 21 18:32:45 2015 +0600
+++ b/Media/Audio/AudioPlayer.cpp	Thu May 21 18:33:07 2015 +0600
@@ -1,8 +1,7 @@
 #define _CRTDBG_MAP_ALLOC
+#define _CRT_SECURE_NO_WARNINGS
 #include <stdlib.h>
 #include <crtdbg.h>
-
-#define _CRT_SECURE_NO_WARNINGS
 #include <sstream>
 #include <string>
 
--- a/Media/MediaPlayer.cpp	Thu May 21 18:32:45 2015 +0600
+++ b/Media/MediaPlayer.cpp	Thu May 21 18:33:07 2015 +0600
@@ -1,12 +1,10 @@
 #define _CRTDBG_MAP_ALLOC
+#define _CRT_SECURE_NO_WARNINGS
 #include <stdlib.h>
 #include <crtdbg.h>
-
 #include <vector>
 #include <deque>
 
-#define _CRT_SECURE_NO_WARNINGS
-
 #include "Engine/Engine.h"
 
 #include "IO/Mouse.h"
--- a/OSWindow.cpp	Thu May 21 18:32:45 2015 +0600
+++ b/OSWindow.cpp	Thu May 21 18:33:07 2015 +0600
@@ -1,9 +1,8 @@
 #define _CRTDBG_MAP_ALLOC
+#define _CRT_SECURE_NO_WARNINGS
 #include <stdlib.h>
 #include <crtdbg.h>
 
-#define _CRT_SECURE_NO_WARNINGS
-
 #include "OSWindow.h"
 
 #include "Engine/Engine.h"
--- a/stru6.cpp	Thu May 21 18:32:45 2015 +0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2160 +0,0 @@
-#define _CRTDBG_MAP_ALLOC
-#include <stdlib.h>
-#include <crtdbg.h>
-
-#define _CRT_SECURE_NO_WARNINGS
-
-#include "Engine/Engine.h"
-
-#include "stru6.h"
-
-#include "Engine/Graphics/LightmapBuilder.h"
-#include "Engine/Objects/SpriteObject.h"
-#include "Engine/Graphics/ParticleEngine.h"
-#include "Engine/LOD.h"
-#include "Engine/Graphics/Sprites.h"
-#include "Engine/Objects/ObjectList.h"
-#include "Engine/Objects/Actor.h"
-#include "Engine/Random.h"
-#include "Engine/Tables/IconFrameTable.h"
-#include "Engine/Timer.h"
-#include "Engine/Graphics/Viewport.h"
-#include "Engine/Graphics/Overlays.h"
-#include "Engine/stru160.h"
-#include "Engine/OurMath.h"
-#include "Engine/Graphics/Lights.h"
-#include "Engine/Graphics/Indoor.h"
-
-
-
-
-//----- (004A7063) --------------------------------------------------------
-unsigned int ModulateColor(unsigned int diffuse, float multiplier)
-{
-  float alpha = multiplier * ((diffuse >> 24) & 0xFF);
-  int   a = (int)floorf(alpha + 0.5f);
-  a = max(0, min(255, a));
-
-  float red = multiplier * ((diffuse >> 16) & 0xFF);
-  int   r = (int)floorf(red + 0.5f);
-  r = max(0, min(255, r));
-  
-  float green = multiplier * ((diffuse >> 8) & 0xFF);
-  int   g = (int)floorf(green + 0.5f);
-  g = max(0, min(255, g));
-  
-  float blue = multiplier * ((diffuse >> 0) & 0xFF);
-  int   b = (int)floorf(blue + 0.5f);
-  b = max(0, min(255, b));
-
-  return (a << 24) | (r << 16) | (g << 8) | b;
-}
-
-
-//----- (0042620A) --------------------------------------------------------
-bool sr_42620A(RenderVertexSoft *p)
-{
-//  __int16 v1; // fps@1
-  unsigned __int8 v2; // c0@2
-  char v3; // c2@2
-  unsigned __int8 v4; // c3@2
-//  bool result; // eax@2
-  unsigned __int8 v6; // c0@4
-  char v7; // c2@4
-  unsigned __int8 v8; // c3@4
-  unsigned __int8 v9; // c0@6
-  char v10; // c2@6
-  unsigned __int8 v11; // c3@6
-  double v12; // st6@7
-  float v13; // ST04_4@7
-  float v14; // ST00_4@7
-  double v15; // st7@7
-  double v16; // st6@8
-  float v17; // ST04_4@8
-  float v18; // ST00_4@8
-  double v19; // st7@8
-
-  //UNDEF(v1);
-  if ( p->vWorldViewPosition.x < 300.0
-    || (v2 = 300.0 < p[1].vWorldViewPosition.x,
-        v3 = 0,
-        v4 = 300.0 == p[1].vWorldViewPosition.x,
-        //BYTE1(result) = HIBYTE(v1),
-        !(v2 | v4)) )
-  {
-    if ( p->vWorldViewPosition.x < 300.0 )
-    {
-      v6 = 300.0 < p[1].vWorldViewPosition.x;
-      v7 = 0;
-      v8 = 300.0 == p[1].vWorldViewPosition.x;
-      //BYTE1(result) = HIBYTE(v1);
-      if ( !(v6 | v8) )
-      {
-        //LOBYTE(result) = 0;
-        return false;
-      }
-    }
-    v9 = 300.0 < p->vWorldViewPosition.x;
-    v10 = 0;
-    v11 = 300.0 == p->vWorldViewPosition.x;
-    //BYTE1(result) = HIBYTE(v1);
-    if ( v9 | v11 )
-    {
-      v16 = 1.0 / (p->vWorldViewPosition.x - p[1].vWorldViewPosition.x);
-      v17 = (p->vWorldViewPosition.y - p[1].vWorldViewPosition.y) * v16;
-      v18 = (p->vWorldViewPosition.z - p[1].vWorldViewPosition.z) * v16;
-      v19 = 300.0 - p[1].vWorldViewPosition.x;
-      p[1].vWorldViewPosition.x = v19 + p[1].vWorldViewPosition.x;
-      p[1].vWorldViewPosition.y = v17 * v19 + p[1].vWorldViewPosition.y;
-      p[1].vWorldViewPosition.z = v19 * v18 + p[1].vWorldViewPosition.z;
-    }
-    else
-    {
-      v12 = 1.0 / (p[1].vWorldViewPosition.x - p->vWorldViewPosition.x);
-      v13 = (p[1].vWorldViewPosition.y - p->vWorldViewPosition.y) * v12;
-      v14 = (p[1].vWorldViewPosition.z - p->vWorldViewPosition.z) * v12;
-      v15 = 300.0 - p->vWorldViewPosition.x;
-      p->vWorldViewPosition.x = v15 + p->vWorldViewPosition.x;
-      p->vWorldViewPosition.y = v13 * v15 + p->vWorldViewPosition.y;
-      p->vWorldViewPosition.z = v15 * v14 + p->vWorldViewPosition.z;
-    }
-  }
-  //LOBYTE(result) = 1;
-  return true;
-}
-
-
-
-//----- (004775C4) --------------------------------------------------------
-stru6_stru1_indoor_sw_billboard::~stru6_stru1_indoor_sw_billboard()
-{
-    delete [] pArray1;
-    pArray1 = nullptr;
-
-    delete [] pArray2;
-    pArray2 = nullptr;
-}
-
-
-//----- (00478211) --------------------------------------------------------
-void stru6_stru1_indoor_sw_billboard::Initialize(int a2)
-{
-  uNumVec4sInArray1 = 66;
-  pArray1 = new stru16x[66];
-
-  uNumVec3sInArray2 = 128;
-  pArray2 = new stru160[128];
-
-  for (uint i = 0; i < uNumVec4sInArray1; ++i)
-  {
-    pArray1[i].field_0 = array_4EB8B8[i].field_0;
-    pArray1[i].field_4 = array_4EB8B8[i].field_4;
-    pArray1[i].field_8 = array_4EB8B8[i].field_8;
-    pArray1[i].field_C = a2;
-  }
-  memcpy(pArray2, array_4EBBD0_x.data()/*array_4EBBD0*/, uNumVec3sInArray2 * sizeof(stru160));
-}
-
-//----- (0047829F) --------------------------------------------------------
-void stru6_stru1_indoor_sw_billboard::_47829F_sphere_particle(float x_offset, float y_offset, float z_offset, float scale, int diffuse)
-{
-  int v7 = 0;
-
-  for (unsigned int i = 0; i < uNumVec3sInArray2; ++i)
-  {
-    for (unsigned int j = 0; j < 3; ++j)
-    {
-      field_14[j].x = x_offset + scale * *(&pArray1->field_0 + 4 * *(int *)((char *)&pArray2->field_0 + v7));
-      field_14[j].y = y_offset + scale * *(&pArray1->field_4 + 4 * *(int *)((char *)&pArray2->field_0 + v7));
-      field_14[j].z = z_offset + scale * *(&pArray1->field_8 + 4 * *(int *)((char *)&pArray2->field_0 + v7));
-      //int v10 = *(int *)((char *)&pArray2->field_0 + v7);
-
-      field_14[j].diffuse = *((int *)&pArray1[1].field_0 + 4 * (*(int *)((char *)&pArray2->field_0 + v7)));
-      v7 += 4;
-    }
-
-    uNumVertices = 3;
-    if ( sub_477C61() && sub_477F63() )
-    {
-      if ( sub_47802A() )
-        pRenderer->_4A4CC9_AddSomeBillboard(this, diffuse);
-    }
-  }
-}
-
-
-
-
-//----- (004A71FE) --------------------------------------------------------
-void stru6::DoAddProjectile(float srcX, float srcY, float srcZ, float dstX, float dstY, float dstZ, unsigned int uTextureID)
-{
-  //int v8; // eax@1
-
-  //v8 = uNumProjectiles;
-  if (uNumProjectiles < 32)
-  {
-    pProjectiles[uNumProjectiles].srcX = srcX;
-    pProjectiles[uNumProjectiles].srcY = srcY;
-    pProjectiles[uNumProjectiles].srcZ = srcZ;
-    pProjectiles[uNumProjectiles].dstX = dstX;
-    pProjectiles[uNumProjectiles].dstY = dstY;
-    pProjectiles[uNumProjectiles].dstZ = dstZ;
-    pProjectiles[uNumProjectiles++].uTextureID = uTextureID;
-  }
-}
-
-//----- (004A7298) --------------------------------------------------------
-void stru6::DrawProjectiles()
-{
-  float v10; // ST1C_4@8
-  float v11; // ST0C_4@8
-  IDirect3DTexture2 *v12; // [sp+20h] [bp-78h]@6
-  RenderVertexSoft v[2]; // [sp+30h] [bp-68h]@1
-  
-  for (uint i = 0; i < uNumProjectiles; ++i)
-  {
-    ProjectileAnim* p = &pProjectiles[i];
-
-    v[0].vWorldPosition.x = p->srcX;
-    v[0].vWorldPosition.y = p->srcY;
-    v[0].vWorldPosition.z = p->srcZ;
-    v[1].vWorldPosition.x = p->dstX;
-    v[1].vWorldPosition.y = p->dstY;
-    v[1].vWorldPosition.z = p->dstZ;
-    pIndoorCameraD3D->ViewTransform(v, 2);
-
-    sr_42620A(v);
-
-    pIndoorCameraD3D->Project(v, 2, 0);
-
-    if (p->uTextureID != -1)
-      v12 = pBitmaps_LOD->pHardwareTextures[p->uTextureID];
-    else
-      v12 = 0;
-
-    v10 = pIndoorCameraD3D->fov_x / v[1].vWorldViewPosition.x * 20.0;
-    v11 = pIndoorCameraD3D->fov_x / v[0].vWorldViewPosition.x * 20.0;
-    pRenderer->DrawProjectile(
-        v[0].vWorldViewProjX,
-        v[0].vWorldViewProjY,
-        v[0].vWorldViewPosition.x,
-         v11,
-        v[1].vWorldViewProjX,
-        v[1].vWorldViewProjY,
-        v[1].vWorldViewPosition.x,
-         v10,
-         v12);
-   }
-}
-
-//----- (004A73AA) --------------------------------------------------------
-void stru6::_4A73AA_hanging_trace_particles___like_fire_strike_ice_blast_etc(SpriteObject *a2, unsigned int uDiffuse, unsigned int uTextureID)
-{
-  stru6 *v4; // edi@1
-  SpriteObject *v5; // esi@1
-  int v6; // eax@1
-  stru6_stru2 *v7; // eax@2
-  double v8; // st7@2
-  double v9; // st6@2
-  double v10; // st7@3
-  Particle_sw local_0; // [sp+8h] [bp-68h]@1
-  float x; // [sp+78h] [bp+8h]@2
-
-  v4 = this;
-  memset(&local_0, 0, 0x68u);
-  v5 = a2;
-  v6 = a2->field_54;
-  if ( v6 )
-  {
-    v7 = &v4->array_4[v6 & 0x1F];
-    x = ((double)a2->vPosition.x - v7->flt_0_x) * 0.5 + v7->flt_0_x;
-    v8 = ((double)v5->vPosition.y - v7->flt_4_y) * 0.5 + v7->flt_4_y;
-    v9 = ((double)v5->vPosition.z - v7->flt_8_z) * 0.5 + v7->flt_8_z;
-    local_0.type = ParticleType_Bitmap | ParticleType_Rotating | ParticleType_8;
-    local_0.uDiffuse = uDiffuse;
-    local_0.x = x + 4.0;
-    local_0.y = v8;
-    local_0.z = v9;
-    local_0.r = 0.0;
-    local_0.g = 0.0;
-    local_0.b = 0.0;
-    local_0.timeToLive = (rand() & 0x40) + 96;
-    local_0.uTextureID = uTextureID;
-    local_0.flt_28 = 1.0;
-    pEngine->pParticleEngine->AddParticle(&local_0);
-    local_0.x = x - 4.0;
-    pEngine->pParticleEngine->AddParticle(&local_0);
-    local_0.x = (double)v5->vPosition.x + 4.0;
-    local_0.y = (double)v5->vPosition.y;
-    local_0.z = (double)v5->vPosition.z;
-    pEngine->pParticleEngine->AddParticle(&local_0);
-    local_0.x = (double)v5->vPosition.x - 4.0;
-    pEngine->pParticleEngine->AddParticle(&local_0);
-    v4->array_4[v5->field_54 & 0x1F].flt_0_x = (double)v5->vPosition.x;
-    v4->array_4[v5->field_54 & 0x1F].flt_4_y = (double)v5->vPosition.y;
-    v4->array_4[v5->field_54 & 0x1F].flt_8_z = (double)v5->vPosition.z;
-  }
-  else
-  {
-    a2->field_54 = v4->field_0++;
-    v4->array_4[a2->field_54 & 0x1F].flt_0_x = (double)a2->vPosition.x;
-    v4->array_4[a2->field_54 & 0x1F].flt_4_y = (double)a2->vPosition.y;
-    v4->array_4[a2->field_54 & 0x1F].flt_8_z = (double)a2->vPosition.z;
-    v10 = (double)a2->vPosition.x;
-    local_0.type = ParticleType_Bitmap | ParticleType_Rotating | ParticleType_8;
-    local_0.uDiffuse = uDiffuse;
-    local_0.x = v10 + 4.0;
-    local_0.y = (double)a2->vPosition.y;
-    local_0.z = (double)a2->vPosition.z;
-    local_0.r = 0.0;
-    local_0.g = 0.0;
-    local_0.b = 0.0;
-    local_0.flt_28 = 1.0;
-    local_0.timeToLive = (rand() & 0x7F) + 128;
-    local_0.uTextureID = uTextureID;
-    pEngine->pParticleEngine->AddParticle(&local_0);
-    local_0.x = (double)a2->vPosition.x - 4.0;
-    pEngine->pParticleEngine->AddParticle(&local_0);
-  }
-}
-
-//----- (004A75CC) --------------------------------------------------------
-void stru6::_4A75CC_single_spell_collision_particle(SpriteObject *a1, unsigned int uDiffuse, unsigned int uTextureID)
-{
-  double v4; // st7@1
-  signed int v5; // edi@1
-  Particle_sw local_0; // [sp+8h] [bp-68h]@1
-
-  memset(&local_0, 0, 0x68u);
-  local_0.type = ParticleType_Bitmap | ParticleType_Rotating | ParticleType_1;
-  local_0.x = (double)a1->vPosition.x;
-  local_0.y = (double)a1->vPosition.y;
-  v4 = (double)a1->vPosition.z;
-  local_0.uDiffuse = uDiffuse;
-  local_0.z = v4;
-  v5 = 10;
-  local_0.timeToLive = (rand() & 0x7F) + 128;
-  local_0.uTextureID = uTextureID;
-  local_0.flt_28 = 1.0;
-  do
-  {
-    local_0.r = (double)(rand() & 0x1FF) - 255.0;
-    local_0.g = (double)(rand() & 0x1FF) - 255.0;
-    local_0.b = (double)(rand() & 0x1FF) - 255.0;
-    pEngine->pParticleEngine->AddParticle(&local_0);
-    --v5;
-  }
-  while ( v5 );
-}
-
-//----- (004A7688) --------------------------------------------------------
-void stru6::_4A7688_fireball_collision_particle(SpriteObject *a2)
-{
-  double v3; // st7@1
-  double v4; // st7@2
-  Particle_sw local_0; // [sp+1Ch] [bp-7Ch]@1
-
-  memset(&local_0, 0, 0x68u);
-
-  v3 = (double)a2->uSpriteFrameID / (double)pObjectList->pObjects[a2->uObjectDescID].uLifetime;
-  if ( v3 >= 0.75 )
-    v4 = (1.0 - v3) * 4.0;
-  else
-    v4 = v3 * 1.333333333333333;
-
-  local_0.type = ParticleType_Bitmap | ParticleType_Rotating | ParticleType_1;
-  local_0.uDiffuse = 0xFF3C1E;
-  local_0.x = (double)a2->vPosition.x;
-  local_0.y = (double)a2->vPosition.y;
-  local_0.z = (double)a2->vPosition.z;
-  local_0.timeToLive = (rand() & 0x7F) + 128;
-  local_0.uTextureID = pBitmaps_LOD->LoadTexture("effpar01", TEXTURE_DEFAULT);
-  local_0.flt_28 = 1.0;
-
-  // 10 fireball sparks 
-  for (unsigned int i = 0; i < 10; ++i)
-  {
-    local_0.r = (rand() & 0x1FF) - 255;
-    local_0.g = (rand() & 0x1FF) - 255;
-    local_0.b = (rand() & 0x1FF) - 255;
-    pEngine->pParticleEngine->AddParticle(&local_0);
-  }
-
-  pStru1->_47829F_sphere_particle((double)a2->vPosition.x, (double)a2->vPosition.y, (double)a2->vPosition.z, 
-                                              (double)floorf(0.5f + (512.0 * v3)), ModulateColor(0xFF3C1E, v4));
-}
-
-//----- (004A77FD) --------------------------------------------------------
-void stru6::_4A77FD_implosion_particle_d3d(SpriteObject *a1)
-{
-  double v4; // st7@1
-  double v5; // st7@2
-  int v7; // eax@4
-  float v8; // ST0C_4@4
-  float v9; // ST08_4@4
-  float v10; // ST04_4@4
-  float v11; // ST00_4@4
-  float v12; // [sp+28h] [bp-4h]@1
-
-  v4 = (double)a1->uSpriteFrameID / (double)pObjectList->pObjects[a1->uObjectDescID].uLifetime;
-  v12 = 512.0 - v4 * 512.0;
-  if ( v4 >= 0.75 )
-    v5 = v4 * 4.0;
-  else
-    v5 = v4 * 1.333333333333333;
-
-  v7 = ModulateColor(0x7E7E7E, v5);
-  v8 = (double)floorf(0.5f + v12);
-  v9 = (double)a1->vPosition.z;
-  v10 = (double)a1->vPosition.y;
-  v11 = (double)a1->vPosition.x;
-  pStru1->_47829F_sphere_particle(v11, v10, v9, v8, v7);
-}
-
-//----- (004A78AE) --------------------------------------------------------
-void stru6::_4A78AE_sparks_spell(SpriteObject *a1)
-{
-  ObjectDesc *v2; // esi@1
-  unsigned int v3; // eax@1
-  double v4; // st7@1
-  Particle_sw local_0; // [sp+8h] [bp-68h]@1
-
-  v2 = &pObjectList->pObjects[a1->uObjectDescID];
-  memset(&local_0, 0, 0x68u);
-  v3 = a1->uSpriteFrameID;
-  local_0.x = (double)a1->vPosition.x;
-  v4 = (double)a1->vPosition.y;
-  local_0.type = ParticleType_Sprite;
-  local_0.uDiffuse = 0x7F7F7F;
-  local_0.timeToLive = 1;
-  local_0.y = v4;
-  local_0.z = (double)a1->vPosition.z;
-  local_0.r = 0.0;
-  local_0.g = 0.0;
-  local_0.b = 0.0;
-  local_0.uTextureID = pSpriteFrameTable->GetFrame(v2->uSpriteID, v3)->pHwSpriteIDs[0];
-  LODWORD(local_0.flt_28) = 0x40000000u;
-  pEngine->pParticleEngine->AddParticle(&local_0);
-}
-
-//----- (004A7948) --------------------------------------------------------
-void stru6::_4A7948_mind_blast_after_effect(SpriteObject *a1)
-{
-  ObjectDesc *v2; // esi@1
-  unsigned int v3; // eax@1
-  double v4; // st7@1
-  char v5; // al@1
-  signed int v6; // edi@1
-  Particle_sw Dst; // [sp+8h] [bp-68h]@1
-
-  v2 = &pObjectList->pObjects[a1->uObjectDescID];
-  memset(&Dst, 0, 0x68u);
-  v3 = a1->uSpriteFrameID;
-  Dst.x = (double)a1->vPosition.x;
-  v4 = (double)a1->vPosition.y;
-  Dst.type = ParticleType_Sprite | ParticleType_Rotating | ParticleType_1;
-  Dst.uDiffuse = 0x7F7F7F;
-  Dst.y = v4;
-  Dst.z = (double)a1->vPosition.z;
-  Dst.uTextureID = pSpriteFrameTable->GetFrame(v2->uSpriteID, v3)->pHwSpriteIDs[0];
-  v5 = rand();
-  v6 = 10;
-  Dst.flt_28 = 1.0;
-  Dst.timeToLive = (v5 & 0x7F) + 128;
-  do
-  {
-    Dst.r = (double)(rand() & 0x1FF) - 255.0;
-    Dst.g = (double)(rand() & 0x1FF) - 255.0;
-    Dst.b = (double)(rand() & 0x1FF) - 255.0;
-    pEngine->pParticleEngine->AddParticle(&Dst);
-    --v6;
-  }
-  while ( v6 );
-}
-
-//----- (004A7A27) --------------------------------------------------------
-bool stru6::AddMobileLight(SpriteObject *a1, unsigned int uDiffuse, int uRadius)
-{
-  return pMobileLightsStack->AddLight(a1->vPosition.x, a1->vPosition.y, a1->vPosition.z, a1->uSectorID, uRadius,
-           (uDiffuse & 0x00FF0000) >> 16,
-           (uDiffuse & 0x0000FF00) >> 8,
-           uDiffuse & 0x000000FF,
-           _4E94D3_light_type);
-}
-// 4E94D3: using guessed type char _4E94D3_light_type;
-
-//----- (004A7A66) --------------------------------------------------------
-void stru6::_4A7A66_miltiple_spell_collision_partifles___like_after_sparks_or_lightning(SpriteObject *a1, unsigned int uDiffuse, unsigned int uTextureID, float a4)
-{
-  int v5; // eax@1
-  char v6; // al@1
-  double v7; // st6@1
-  double v8; // st6@1
-  double v9; // st7@1
-  double v10; // st6@1
-  Particle_sw local_0; // [sp+0h] [bp-6Ch]@1
-  float v12; // [sp+68h] [bp-4h]@1
-  float a1a; // [sp+74h] [bp+8h]@1
-  float uDiffusea; // [sp+78h] [bp+Ch]@1
-  float uTextureIDa; // [sp+7Ch] [bp+10h]@1
-
-  memset(&local_0, 0, 0x68u);
-  local_0.type = ParticleType_Bitmap | ParticleType_Rotating | ParticleType_1;
-  local_0.x = (double)a1->vPosition.x;
-  v5 = a1->vPosition.z;
-  local_0.y = (double)a1->vPosition.y;
-  local_0.uDiffuse = uDiffuse;
-  local_0.z = (double)(v5 + 32);
-  v6 = rand();
-  local_0.flt_28 = 1.0;
-  v7 = 0.0 * a4;
-  local_0.timeToLive = (v6 & 0x7F) + 128;
-  local_0.uTextureID = uTextureID;
-  a1a = v7;
-  local_0.r = v7;
-  local_0.g = a4;
-  local_0.b = a4;
-  pEngine->pParticleEngine->AddParticle(&local_0);
-  v8 = 0.70710677 * a4;
-  uDiffusea = v8;
-  local_0.r = v8;
-  local_0.g = v8;
-  local_0.b = a4;
-  pEngine->pParticleEngine->AddParticle(&local_0);
-  local_0.g = a1a;
-  local_0.r = a4;
-  local_0.b = a4;
-  pEngine->pParticleEngine->AddParticle(&local_0);
-  local_0.r = uDiffusea;
-  local_0.b = a4;
-  v9 = -uDiffusea;
-  uTextureIDa = v9;
-  local_0.g = v9;
-  pEngine->pParticleEngine->AddParticle(&local_0);
-  v10 = -1.0 * a4;
-  local_0.r = a1a;
-  v12 = v10;
-  local_0.g = v10;
-  local_0.b = a4;
-  pEngine->pParticleEngine->AddParticle(&local_0);
-  local_0.b = a4;
-  local_0.r = uTextureIDa;
-  local_0.g = uTextureIDa;
-  pEngine->pParticleEngine->AddParticle(&local_0);
-  local_0.r = v12;
-  local_0.g = a1a;
-  local_0.b = a4;
-  pEngine->pParticleEngine->AddParticle(&local_0);
-  local_0.r = uTextureIDa;
-  local_0.g = uDiffusea;
-  local_0.b = a4;
-  pEngine->pParticleEngine->AddParticle(&local_0);
-}
-
-//----- (004A7C07) --------------------------------------------------------
-void stru6::_4A7C07(SpriteObject *a2)
-{
-  stru6 *v2; // edi@1
-  SpriteObject *v3; // esi@1
-  int v4; // eax@1
-  ObjectDesc *v5; // ebx@1
-  stru6_stru2 *v6; // eax@2
-  double v7; // st6@2
-  double v8; // st5@2
-  double v9; // st4@2
-  char v10; // al@2
-  double v11; // st7@2
-  double v12; // st7@3
-  Particle_sw local_0; // [sp+Ch] [bp-68h]@1
-  float a2a; // [sp+7Ch] [bp+8h]@2
-
-  v2 = this;
-  memset(&local_0, 0, 0x68u);
-  v3 = a2;
-  v4 = a2->field_54;
-  v5 = &pObjectList->pObjects[a2->uObjectDescID];
-  if ( v4 )
-  {
-    v6 = &v2->array_4[v4 & 0x1F];
-    v7 = ((double)a2->vPosition.x - v6->flt_0_x) * 0.5 + v6->flt_0_x;
-    v8 = ((double)a2->vPosition.y - v6->flt_4_y) * 0.5 + v6->flt_4_y;
-    v9 = ((double)a2->vPosition.z - v6->flt_8_z) * 0.5 + v6->flt_8_z;
-    local_0.type = ParticleType_Sprite;
-    local_0.uDiffuse = 0xFFFFFF;
-    a2a = v9;
-    local_0.x = v7;
-    local_0.z = a2a;
-    local_0.y = v8;
-    local_0.r = 0.0;
-    local_0.g = 0.0;
-    local_0.b = 0.0;
-    v10 = rand();
-    LODWORD(local_0.flt_28) = 0x40400000u;
-    local_0.timeToLive = (v10 & 0x3F) + 64;
-    local_0.uTextureID = pSpriteFrameTable->GetFrame(v5->uSpriteID, v3->uSpriteFrameID)->pHwSpriteIDs[0];
-    pEngine->pParticleEngine->AddParticle(&local_0);
-    v11 = (double)v3->vPosition.x;
-    LODWORD(local_0.flt_28) = 0x40800000u;
-    local_0.x = v11;
-    local_0.y = (double)v3->vPosition.y;
-    local_0.z = (double)v3->vPosition.z;
-    local_0.timeToLive = (rand() & 0x3F) + 64;
-    pEngine->pParticleEngine->AddParticle(&local_0);
-    v2->array_4[v3->field_54 & 0x1F].flt_0_x = (double)v3->vPosition.x;
-    v2->array_4[v3->field_54 & 0x1F].flt_4_y = (double)v3->vPosition.y;
-    v2->array_4[v3->field_54 & 0x1F].flt_8_z = (double)v3->vPosition.z;
-  }
-  else
-  {
-    a2->field_54 = v2->field_0++;
-    v2->array_4[a2->field_54 & 0x1F].flt_0_x = (double)a2->vPosition.x;
-    v2->array_4[a2->field_54 & 0x1F].flt_4_y = (double)a2->vPosition.y;
-    v2->array_4[a2->field_54 & 0x1F].flt_8_z = (double)a2->vPosition.z;
-    v12 = (double)a2->vPosition.x;
-    local_0.type = ParticleType_Sprite;
-    local_0.uDiffuse = 0xFFFFFF;
-    LODWORD(local_0.flt_28) = 0x40000000u;
-    local_0.x = v12;
-    local_0.y = (double)a2->vPosition.y;
-    local_0.z = (double)a2->vPosition.z;
-    local_0.r = 0.0;
-    local_0.g = 0.0;
-    local_0.b = 0.0;
-    local_0.timeToLive = (rand() & 0x3F) + 64;
-    local_0.uTextureID = pSpriteFrameTable->GetFrame(v5->uSpriteID, a2->uSpriteFrameID)->pHwSpriteIDs[0];
-    pEngine->pParticleEngine->AddParticle(&local_0);
-  }
-}
-
-//----- (004A7E05) --------------------------------------------------------
-void stru6::AddProjectile(SpriteObject *a2, int a3, unsigned int uTextureID)
-{
-  if (a2->field_54)
-  {
-    DoAddProjectile(array_4[a2->field_54 & 0x1F].flt_0_x,
-                    array_4[a2->field_54 & 0x1F].flt_4_y,
-                    array_4[a2->field_54 & 0x1F].flt_8_z,
-                    a2->vPosition.x,
-                    a2->vPosition.y,
-                    a2->vPosition.z,
-                    uTextureID);
-  }
-  else
-  {
-    a2->field_54 = field_0++;
-    array_4[a2->field_54 & 0x1F].flt_0_x = (double)a2->vPosition.x;
-    array_4[a2->field_54 & 0x1F].flt_4_y = (double)a2->vPosition.y;
-    array_4[a2->field_54 & 0x1F].flt_8_z = (double)a2->vPosition.z;
-  }
-}
-
-//----- (004A7E89) --------------------------------------------------------
-void stru6::_4A7E89_sparkles_on_actor_after_it_casts_buff(Actor *pActor, unsigned int uDiffuse)
-{
-  Actor *v3; // edi@1
-  int v4; // ebx@3
-  //int result; // eax@5
-  Particle_sw Dst; // [sp+Ch] [bp-6Ch]@1
-  int v7; // [sp+74h] [bp-4h]@2
-  signed int pActora; // [sp+80h] [bp+8h]@1
-
-  memset(&Dst, 0, 0x68u);
-  Dst.type = ParticleType_Bitmap | ParticleType_Rotating | ParticleType_8;
-  Dst.timeToLive = (rand() & 0x7F) + 128;
-  v3 = pActor;
-  Dst.uTextureID = pBitmaps_LOD->LoadTexture("effpar02", TEXTURE_DEFAULT);
-  pActora = 50;
-  Dst.flt_28 = 1.0;
-  do
-  {
-    v7 = (unsigned __int8)rand() + v3->vPosition.x - 127;
-    Dst.x = (double)v7;
-    v7 = (unsigned __int8)rand() + v3->vPosition.y - 127;
-    Dst.y = (double)v7;
-    v7 = v3->vPosition.z + (unsigned __int8)rand();
-    Dst.z = (double)v7;
-    if ( uDiffuse )
-    {
-      Dst.uDiffuse = uDiffuse;
-    }
-    else
-    {
-      v4 = rand() << 16;
-      Dst.uDiffuse = rand() | v4;
-    }
-    pEngine->pParticleEngine->AddParticle(&Dst);
-    --pActora;
-  }
-  while ( pActora );
-}
-
-//----- (004A7F74) --------------------------------------------------------
-void stru6::_4A7F74(int x, int y, int z)
-{
-  stru6 *v4; // esi@1
-  char v5; // al@1
-  signed int v6; // edi@1
-  unsigned int v7; // eax@1
-  double v8; // st7@2
-  double v9; // st7@2
-  Particle_sw local_0; // [sp+8h] [bp-78h]@1
-  double v11; // [sp+70h] [bp-10h]@1
-  double v12; // [sp+78h] [bp-8h]@1
-  float z1; // [sp+88h] [bp+8h]@2
-
-  v4 = this;
-  memset(&local_0, 0, 0x68u);
-  local_0.type = ParticleType_Bitmap | ParticleType_Rotating | ParticleType_1;
-  local_0.uDiffuse = 0x7E7E7E;
-  v5 = rand();
-  local_0.flt_28 = 1.0;
-  v6 = 8;
-  local_0.timeToLive = (v5 & 0x7F) + 128;
-  v7 = v4->uTextureID_effpar1;
-  v12 = (double)x;
-  local_0.uTextureID = v7;
-  v11 = (double)y;
-  do
-  {
-    v8 = pRnd->GetRandom();
-    local_0.x = v8 * 40.0 - 20.0 + v12;
-    v9 = pRnd->GetRandom();
-    z1 = (double)z;
-    local_0.z = z1;
-    local_0.y = v9 * 40.0 - 20.0 + v11;
-    local_0.r = pRnd->GetRandom() * 400.0 - 200.0;
-    local_0.g = pRnd->GetRandom() * 400.0 - 200.0;
-    local_0.b = pRnd->GetRandom() * 150.0 + 50.0;
-    pEngine->pParticleEngine->AddParticle(&local_0);
-    --v6;
-  }
-  while ( v6 );
-}
-
-//----- (004A806F) --------------------------------------------------------
-int stru6::_4A806F(Actor *pActor)
-{
-  int v2; // ecx@1
-  unsigned int v3; // eax@1
-  double v4; // st7@2
-  float v5; // ST00_4@6
-
-  v2 = (int)pActor;
-  v3 = LODWORD(pActor->pActorBuffs[ACTOR_BUFF_MASS_DISTORTION].uExpireTime) - pMiscTimer->uTotalGameTimeElapsed;
-  if ( (signed int)v3 <= 64 )
-  {
-    if ( (v3 & 0x80000000u) != 0 )
-    {
-      pActor->pActorBuffs[ACTOR_BUFF_MASS_DISTORTION].uExpireTime = 0i64;
-      v4 = 1.0;
-    }
-    else
-    {
-      v2 = v3 * v3;
-      v4 = 1.0 - (double)(signed int)(v3 * v3) * 0.0001953125;
-    }
-  }
-  else
-  {
-    v2 = (v3 - 64) * (v3 - 64);
-    v4 = (double)v2 * 0.0001953125 + 0.2;
-  }
-  v5 = v4;
-  return fixpoint_from_float(v5);
-}
-
-//----- (004A81CA) --------------------------------------------------------
-bool stru6::_4A81CA(SpriteObject *a2)
-{
-  //stru6 *v2; // ebx@1
-  int result; // eax@1
-//  int v4; // eax@27
-  //unsigned int diffuse; // esi@41
-  //int v6; // ecx@49
-  int v7; // eax@54
-  int v8; // eax@55
-  char v9; // zf@56
-  int v10; // eax@59
-  int v11; // eax@61
-  int v12; // eax@85
-  int v13; // eax@86
-  int v14; // eax@96
-  int v15; // eax@111
-  int v16; // eax@118
-  int v17; // eax@139
-  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
-    {
-      _4A73AA_hanging_trace_particles___like_fire_strike_ice_blast_etc(a2, 0xFF3C1E, uTextureID_effpar1);
-      AddMobileLight(a2, 0xFF3C1E, 256);
-    }
-    return false;
-
-    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 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 2101:
-    {
-      _4A7A66_miltiple_spell_collision_partifles___like_after_sparks_or_lightning(a2, 0xC8C814, uTextureID_effpar1, 200.0);
-      AddMobileLight(a2, 0xC8C814, 256);
-    }
-    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 9000: return true;
-  }
-
-  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 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;
-  }
-
-  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;
-            return false;
-
-          }
-          if ( result <= 1081 )
-          {
-            if (result != 1081)
-            {
-              result -= 1060;
-              if ( !result )
-                return true;
-              v7 = result - 1;
-              if ( v7 )
-              {
-                v8 = v7 - 9;
-                if ( !v8 )
-                {
-                  _4A75CC_single_spell_collision_particle(a2, 0xFF3C1E, uTextureID_effpar1);
-                  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 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:
-            //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;
-            }
-            _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;
-
-        _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;
-        }
-            //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 )
-            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;
-            }
-            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 )
-          {
-            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;
-
-      _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;
-  }
-  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;
-}
-
-//----- (004A89BD) --------------------------------------------------------
-void stru6::SetPlayerBuffAnim(unsigned __int16 uSpellID, unsigned __int16 uPlayerID)
-{
-  //stru6 *v3; // edi@1
-  PlayerBuffAnim *v4; // esi@1
-  const char *v6; // [sp-4h] [bp-10h]@2
-
-  v4 = &pPlayerBuffs[uPlayerID];
-  v4->uSpellAnimTimeElapsed = 0;
-  v4->bRender = uSpellID != 0;
-
-  switch (uSpellID)
-  {
-    case SPELL_DISEASE:
-      v6 = "zapp";
-    break;
-      
-    case BECOME_MAGIC_GUILD_MEMBER:
-    case SPELL_AIR_FEATHER_FALL:
-    case SPELL_SPIRIT_DETECT_LIFE:
-    case SPELL_SPIRIT_FATE:
-      v6 = "spboost1";
-    break;
-      
-    case SPELL_QUEST_COMPLETED:
-    case SPELL_AIR_INVISIBILITY:
-    case SPELL_WATER_WATER_WALK:
-    case SPELL_SPIRIT_PRESERVATION:
-      v6 = "spboost2";
-    break;
-      
-    case SPELL_152:
-      __debugbreak(); // spell id == 152 wtf
-    case SPELL_LIGHT_HOUR_OF_POWER:
-    case SPELL_LIGHT_DAY_OF_THE_GODS:
-    case SPELL_LIGHT_DAY_OF_PROTECTION:
-    case SPELL_LIGHT_DIVINE_INTERVENTION:
-      v6 = "spboost3";
-    break;
-
-    case SPELL_SPIRIT_REMOVE_CURSE:
-    case SPELL_MIND_REMOVE_FEAR:
-    case SPELL_BODY_CURE_WEAKNESS:
-      v6 = "spheal1";
-    break;
-
-    case SPELL_SPIRIT_SHARED_LIFE:
-    case SPELL_MIND_CURE_PARALYSIS:
-    case SPELL_MIND_CURE_INSANITY:
-    case SPELL_BODY_FIRST_AID:
-    case SPELL_BODY_CURE_POISON:
-    case SPELL_BODY_CURE_DISEASE:
-    case SPELL_DARK_SACRIFICE:
-      v6 = "spheal2";
-    break;
-
-    case SPELL_BODY_POWER_CURE:
-    case SPELL_DARK_SOULDRINKER:
-      v6 = "spheal3";
-    break;
-
-    case SPELL_FIRE_PROTECTION_FROM_FIRE:
-    case SPELL_FIRE_IMMOLATION:
-      v6 = "spell03";
-    break;
-
-    case SPELL_FIRE_HASTE:                  v6 = "spell05"; break;
-    case SPELL_AIR_PROTECTION_FROM_AIR:     v6 = "spell14"; break;
-    case SPELL_AIR_SHIELD:                  v6 = "spell17"; break;
-    case SPELL_WATER_PROTECTION_FROM_WATER: v6 = "spell25"; break;
-    case SPELL_EARTH_PROTECTION_FROM_EARTH: v6 = "spell36"; break;
-    case SPELL_EARTH_STONESKIN:             v6 = "spell38"; break;
-    case SPELL_SPIRIT_BLESS:                v6 = "spell46"; break;
-    case SPELL_SPIRIT_HEROISM:              v6 = "spell51"; break;
-    case SPELL_SPIRIT_RESSURECTION:         v6 = "spell55"; break;
-    case SPELL_MIND_PROTECTION_FROM_MIND:   v6 = "spell58"; break;
-    case SPELL_BODY_PROTECTION_FROM_BODY:   v6 = "spell69"; break;
-    case SPELL_BODY_REGENERATION:           v6 = "spell71"; break;
-    case SPELL_BODY_HAMMERHANDS:            v6 = "spell73"; break;
-    case SPELL_BODY_PROTECTION_FROM_MAGIC:  v6 = "spell75"; break;
-
-    default:
-      v4->bRender = false;
-      return;
-  }
-  
-  v4->uSpellIconID = pIconsFrameTable->FindIcon(v6);
-  if (v4->bRender)
-    v4->uSpellAnimTime = 8 * pIconsFrameTable->pIcons[v4->uSpellIconID].uAnimLength;
-}
-
-//----- (004A8BDF) --------------------------------------------------------
-void stru6::FadeScreen__like_Turn_Undead_and_mb_Armageddon(unsigned int uDiffuseColor, unsigned int uFadeTime)
-{
-  this->uFadeTime = uFadeTime;
-  this->uFadeLength = uFadeTime;
-  this->uFadeColor = uDiffuseColor;
-}
-
-//----- (004A8BFC) --------------------------------------------------------
-int stru6::_4A8BFC() //for SPELL_LIGHT_PRISMATIC_LIGHT
-{
-  uAnimLength = 8 * pSpriteFrameTable->pSpriteSFrames[pSpriteFrameTable->FastFindSprite("spell84")].uAnimLength;
-  return uAnimLength;
-}
-
-//----- (004A8C27) --------------------------------------------------------
-void stru6::RenderSpecialEffects()
-{
-  double v4; // st7@4
-  double v5; // st6@4
-  float v7; // ST14_4@6
-  unsigned int v8; // ST14_4@8
-  SpriteFrame *v10; // eax@8
-  int v11; // edi@8
-  RenderVertexD3D3 vd3d[4]; // [sp+60h] [bp-8Ch]@9
-
-  if (uNumProjectiles)
-  {
-    DrawProjectiles();
-    uNumProjectiles = 0;
-  }
-
-  field_204 = 0;
-  if ( uFadeTime > 0 )
-  {
-    v4 = (double)uFadeTime / (double)uFadeLength;
-    v5 = 1.0 - v4 * v4;
-    //v6 = v5;
-    if ( v5 > 0.9 )
-      v5 = 1.0 - (v5 - 0.9) * 10.0;
-    v7 = v5;
-    pRenderer->ScreenFade(uFadeColor, v7);
-    uFadeTime -= pEventTimer->uTimeElapsed;
-  }
-
-  if (uAnimLength > 0)
-  {
-    v8 = 8 * pSpriteFrameTable->pSpriteSFrames[pSpriteFrameTable->FastFindSprite("spell84")].uAnimLength - uAnimLength;
-    v10 = pSpriteFrameTable->GetFrame(pSpriteFrameTable->FastFindSprite("spell84"), v8);
-    v11 = v10->pHwSpriteIDs[0];
-    uAnimLength -= pEventTimer->uTimeElapsed;
-    //if ( pRenderer->pRenderD3D )
-    //{
-      vd3d[0].pos.x = (double)(signed int)pViewport->uViewportTL_X;
-      vd3d[0].pos.y = (double)(signed int)pViewport->uViewportTL_Y;
-      vd3d[0].pos.z = 0.0;
-      vd3d[0].diffuse = 0x7F7F7Fu;
-      vd3d[0].specular = 0;
-      vd3d[0].rhw = 1.0;
-      vd3d[0].texcoord.x = 0.0;
-      vd3d[0].texcoord.y = 0.0;
-
-      vd3d[1].pos.x = (double)(signed int)pViewport->uViewportTL_X;
-      vd3d[1].pos.y = (double)(pViewport->uViewportBR_Y + 1);
-      vd3d[1].pos.z = 0.0;
-      vd3d[1].diffuse = 0x7F7F7Fu;
-      vd3d[1].specular = 0;
-      vd3d[1].rhw = 1.0;
-      vd3d[1].texcoord.x = 0.0;
-      vd3d[1].texcoord.y = 1.0;
-
-      vd3d[2].pos.x = (double)(signed int)pViewport->uViewportBR_X;
-      vd3d[2].pos.y = (double)(pViewport->uViewportBR_Y + 1);
-      vd3d[2].pos.z = 0.0;
-      vd3d[2].diffuse = 0x7F7F7Fu;
-      vd3d[2].specular = 0;
-      vd3d[2].rhw = 1.0;
-      vd3d[2].texcoord.x = 1.0;
-      vd3d[2].texcoord.y = 1.0;
-
-      vd3d[3].pos.x = (double)(signed int)pViewport->uViewportBR_X;
-      vd3d[3].pos.y = (double)(signed int)pViewport->uViewportTL_Y;
-      vd3d[3].pos.z = 0.0;
-      vd3d[3].diffuse = 0x7F7F7Fu;
-      vd3d[3].specular = 0;
-      vd3d[3].rhw = 1.0;
-      vd3d[3].texcoord.x = 1.0;
-      vd3d[3].texcoord.y = 0.0;
-
-      pRenderer->DrawSpecialEffectsQuad(vd3d, pSprites_LOD->pHardwareSprites[v11].pTexture);
-    //}
-    /*else
-    {
-      vsr.pTarget = pRenderer->pTargetSurface;
-      vsr.sParentBillboardID = -1;
-      vsr.pTargetZ = pRenderer->pActiveZBuffer;
-      vsr.uScreenSpaceX = (signed int)(pViewport->uViewportBR_X - pViewport->uViewportTL_X) / 2;
-      vsr.uScreenSpaceY = pViewport->uViewportBR_Y;
-      v24 = 16777216;
-      LODWORD(v18) = 0;
-      HIDWORD(v18) = (signed __int16)(LOWORD(pViewport->uViewportBR_X) - LOWORD(pViewport->uViewportTL_X));
-      vsr._screenspace_x_scaler_packedfloat = v18 / 0x1000000;
-      LODWORD(v18) = 0;
-      HIDWORD(v18) = (signed __int16)(LOWORD(pViewport->uViewportBR_Y) - LOWORD(pViewport->uViewportTL_Y));
-      v26 = v18 / 16777216;
-      vsr._screenspace_y_scaler_packedfloat = v18 / 0x1000000;
-      vsr.pPalette = PaletteManager::Get_Dark_or_Red_LUT(v70->uPaletteIndex, 0, 1);
-      vsr.uTargetPitch = pRenderer->uTargetSurfacePitch;
-      vsr.sParentBillboardID = -1;
-      vsr.uViewportX = pViewport->uViewportTL_X;
-      vsr.uViewportZ = pViewport->uViewportBR_X;
-      vsr.uViewportY = pViewport->uViewportTL_Y;
-      vsr.sZValue = 0;
-      vsr.uViewportW = pViewport->uViewportBR_Y;
-      vsr.uFlags = 0;
-      if ( v11 >= 0 )
-        pSprites_LOD->pSpriteHeaders[v11].DrawSprite_sw(&vsr, 1);
-    }*/
-  }
-}
-
-//----- (004A902A) --------------------------------------------------------
-void stru6::DrawPlayerBuffAnims()
-{
-  for (uint i = 0; i < 4; ++i)
-  {
-    PlayerBuffAnim* buff = &pPlayerBuffs[i];
-    if (!buff->bRender)
-      continue;
-
-    buff->uSpellAnimTimeElapsed += pEventTimer->uTimeElapsed;
-    if (buff->uSpellAnimTimeElapsed >= buff->uSpellAnimTime)
-    {
-      buff->bRender = false;
-      continue;
-    }
-
-    IconFrame* icon = pIconsFrameTable->GetFrame(buff->uSpellIconID, buff->uSpellAnimTimeElapsed);
-    pRenderer->DrawTextureIndexedAlpha(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i], 385, pIcons_LOD->GetTexture(icon->uTextureID));
-
-    pOtherOverlayList->bRedraw = true;
-  }
-}
-
-//----- (004A90A0) --------------------------------------------------------
-void stru6::LoadAnimations()
-{
-  uTextureID_effpar1 = pBitmaps_LOD->LoadTexture("effpar01", TEXTURE_DEFAULT);
-  uTextureID_effpar2 = pBitmaps_LOD->LoadTexture("effpar02", TEXTURE_DEFAULT);
-  uTextureID_effpar3 = pBitmaps_LOD->LoadTexture("effpar03", TEXTURE_DEFAULT);
-  uSpriteID_sp57c = pSprites_LOD->LoadSprite("sp57c", 6);
-
-  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("zapp"));
-  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spheal1"));
-  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spheal2"));
-  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spheal3"));
-  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spboost1"));
-  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spboost2"));
-  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spboost3"));
-  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spell03"));
-  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spell05"));
-  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spell14"));
-  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spell17"));
-  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spell21"));
-  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spell25"));
-  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spell27"));
-  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spell36"));
-  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spell38"));
-  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spell46"));
-  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spell51"));
-  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spell55"));
-  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spell58"));
-  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spell69"));
-  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spell71"));
-  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spell73"));
-  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spell75"));
-  pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("spell96"));
-
-  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell01"));
-  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell02"));
-  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell03"));
-  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell09"));
-  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell11"));
-  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell18"));
-  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell22"));
-  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell26"));
-  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell29"));
-  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell39"));
-  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell39c"));
-  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell41"));
-  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell57c"));
-  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell62"));
-  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell65"));
-  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell66"));
-  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell70"));
-  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell76"));
-  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell84"));
-  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell90"));
-  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell92"));
-  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell93"));
-  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell97"));
-  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell97c"));
-  pSpriteFrameTable->InitializeSprite(pSpriteFrameTable->FastFindSprite("spell97c"));
-}
-
-//----- (004775ED) --------------------------------------------------------
-int stru6_stru1_indoor_sw_billboard::_4775ED(float a2)
-{
-	char *v2; // edi@1
-	//int v3; // eax@1
-	char *v4; // edx@2
-	char *v5; // esi@3
-	double v6; // st7@6
-	signed __int64 v7; // ST84_8@6
-	double v8; // ST0C_8@6
-	int v9; // esi@6
-	double v10; // ST44_8@6
-	int v11; // ecx@6
-	double v12; // ST34_8@6
-	int v13; // ecx@6
-	double v14; // ST14_8@6
-	double v15; // st7@8
-	unsigned int v16; // ecx@8
-	signed __int64 v17; // ST64_8@8
-	double v18; // ST24_8@8
-	int v19; // edi@8
-	double v20; // ST3C_8@8
-	int v21; // ecx@8
-	double v22; // ST2C_8@8
-	int v23; // ST9C_4@8
-	double v24; // ST1C_8@8
-	int *v25; // edi@8
-	int v26; // esi@8
-	int *v27; // edi@10
-	int v28; // esi@10
-	//  int result; // eax@12
-	__int64 v30; // [sp+A8h] [bp-30h]@8
-	float v31; // [sp+B0h] [bp-28h]@6
-	float v32; // [sp+B4h] [bp-24h]@6
-	int v33; // [sp+B8h] [bp-20h]@6
-	int v34; // [sp+BCh] [bp-1Ch]@2
-	stru6_stru1_indoor_sw_billboard *v35; // [sp+C0h] [bp-18h]@1
-	float v36; // [sp+C4h] [bp-14h]@6
-	int v37; // [sp+C8h] [bp-10h]@6
-	int v38; // [sp+CCh] [bp-Ch]@1
-	float v39; // [sp+D0h] [bp-8h]@6
-	int *v40; // [sp+D4h] [bp-4h]@2
-
-	//  __debugbreak();// ,           
-	v2 = (char *)&this->field_64[4 * this->uNumVertices];
-	v38 = 0;
-	*(int *)v2 = this->field_64[0];
-	v2 += 4;
-	*(int *)v2 = this->field_64[1];
-	v2 += 4;
-	*(int *)v2 = this->field_64[2];
-	*((int *)v2 + 1) = this->field_64[3];
-	//v3 = this->uNumVertices;
-	v35 = this;
-	if (this->uNumVertices > 0)
-	{
-		v40 = &this->field_64[20];
-		v4 = (char *)&this->field_64[3] + 3;
-
-		//while ( 1 )
-		for (v34 = this->uNumVertices; v34; --v34)
-		{
-			v5 = v4 - 15;
-			if (*(float *)(v4 - 15) <= (double)a2 && *(float *)(v4 + 1) <= (double)a2)
-			{
-				v4 += 16;
-				//--v34;
-				//if ( !v34 )
-				//return this->uNumVertices = v38;
-				continue;
-			}
-			if (*(float *)v5 <= (double)a2)
-			{
-				v6 = (a2 - *(float *)v5) / (*(float *)(v4 + 1) - *(float *)v5);
-				v7 = (unsigned __int8)v4[16] - (unsigned int)(unsigned __int8)*v4;
-				v36 = v6;
-				v31 = (*(float *)(v4 + 5) - *(float *)(v4 - 11)) * v6 + *(float *)(v4 - 11);
-				v32 = (*(float *)(v4 + 9) - *(float *)(v4 - 7)) * v6 + *(float *)(v4 - 7);
-				*(float *)&v37 = (double)v7 * v6;
-				v8 = *(float *)&v37 + 6.7553994e15;
-				v9 = (unsigned __int8)*v4;
-				*(float *)&v37 = (double)((unsigned __int8)v4[15] - (unsigned int)(unsigned __int8)*(v4 - 1)) * v36;
-				v10 = *(float *)&v37 + 6.7553994e15;
-				v11 = (unsigned __int8)*(v4 - 2);
-				v37 = LODWORD(v10) + (unsigned __int8)*(v4 - 1);
-				v39 = (double)((unsigned int)(unsigned __int8)v4[14] - v11) * v36;
-				v12 = v39 + 6.7553994e15;
-				v13 = LODWORD(v12) + (unsigned __int8)*(v4 - 2);
-				v39 = (double)((*(int *)(v4 + 13) & 0xFF) - (*(int *)(v4 - 3) & 0xFFu)) * v36;
-				v14 = v39 + 6.7553994e15;
-				v33 = (LODWORD(v14) + (*(int *)(v4 - 3) & 0xFF)) | ((v13 | ((v37 | ((LODWORD(v8) + v9) << 8)) << 8)) << 8);
-				//this = v35;
-				v5 = (char *)&v30 + 4;
-			}
-			else if (*(float *)(v4 + 1) <= (double)a2)
-			{
-				v15 = (a2 - *(float *)v5) / (*(float *)(v4 + 1) - *(float *)v5);
-				v16 = (unsigned __int8)*v4;
-				HIDWORD(v30) = LODWORD(a2);
-				v17 = (unsigned __int8)v4[16] - v16;
-				v36 = v15;
-				v31 = (*(float *)(v4 + 5) - *(float *)(v4 - 11)) * v15 + *(float *)(v4 - 11);
-				v32 = (*(float *)(v4 + 9) - *(float *)(v4 - 7)) * v15 + *(float *)(v4 - 7);
-				v39 = (double)v17 * v15;
-				v18 = v39 + 6.7553994e15;
-				v19 = (unsigned __int8)*v4;
-				v39 = (double)((unsigned __int8)v4[15] - (unsigned int)(unsigned __int8)*(v4 - 1)) * v36;
-				v20 = v39 + 6.7553994e15;
-				v21 = (unsigned __int8)*(v4 - 2);
-				v37 = LODWORD(v20) + (unsigned __int8)*(v4 - 1);
-				v39 = (double)((unsigned int)(unsigned __int8)v4[14] - v21) * v36;
-				v22 = v39 + 6.7553994e15;
-				v23 = LODWORD(v22) + (unsigned __int8)*(v4 - 2);
-				v39 = (double)((*(int *)(v4 + 13) & 0xFF) - (*(int *)(v4 - 3) & 0xFFu)) * v36;
-				v24 = v39 + 6.7553994e15;
-				v33 = (LODWORD(v24) + (*(int *)(v4 - 3) & 0xFF)) | ((v23 | ((v37 | ((LODWORD(v18) + v19) << 8)) << 8)) << 8);
-				v25 = v40;
-				*v40 = *(int *)v5;
-				v26 = (int)(v5 + 4);
-				++v25;
-				*v25 = *(int *)v26;
-				v26 += 4;
-				++v25;
-				++v38;
-				v40 += 4;
-				*v25 = *(int *)v26;
-				v25[1] = *(int *)(v26 + 4);
-				v5 = (char *)&v30 + 4;
-			}
-			v27 = v40;
-			++v38;
-			*v40 = *(int *)v5;
-			v28 = (int)(v5 + 4);
-			++v27;
-			*v27 = *(int *)v28;
-			v28 += 4;
-			++v27;
-			v40 += 4;
-			*v27 = *(int *)v28;
-			v27[1] = *(int *)(v28 + 4);
-			v4 += 16;
-			//--v34;
-			//if ( !v34 )
-			//return this->uNumVertices = v38;
-		}
-	}
-	return this->uNumVertices = v38;
-}
-
-//----- (00477927) --------------------------------------------------------
-int stru6_stru1_indoor_sw_billboard::_477927(float a2)
-{
-	char *v2; // edi@1
-	int v3; // eax@1
-	char *v4; // edx@2
-	char *v5; // esi@3
-	double v6; // st7@6
-	signed __int64 v7; // ST84_8@6
-	double v8; // ST0C_8@6
-	int v9; // esi@6
-	double v10; // ST44_8@6
-	int v11; // ecx@6
-	double v12; // ST34_8@6
-	int v13; // ecx@6
-	double v14; // ST14_8@6
-	double v15; // st7@8
-	unsigned int v16; // ecx@8
-	signed __int64 v17; // ST64_8@8
-	double v18; // ST24_8@8
-	int v19; // edi@8
-	double v20; // ST3C_8@8
-	int v21; // ecx@8
-	double v22; // ST2C_8@8
-	int v23; // ST9C_4@8
-	double v24; // ST1C_8@8
-	int *v25; // edi@8
-	int v26; // esi@8
-	int *v27; // edi@10
-	int v28; // esi@10
-	//  int result; // eax@12
-	__int64 v30; // [sp+A8h] [bp-30h]@8
-	float v31; // [sp+B0h] [bp-28h]@6
-	float v32; // [sp+B4h] [bp-24h]@6
-	int v33; // [sp+B8h] [bp-20h]@6
-	int v34; // [sp+BCh] [bp-1Ch]@2
-	stru6_stru1_indoor_sw_billboard *v35; // [sp+C0h] [bp-18h]@1
-	float v36; // [sp+C4h] [bp-14h]@6
-	int v37; // [sp+C8h] [bp-10h]@6
-	int v38; // [sp+CCh] [bp-Ch]@1
-	float v39; // [sp+D0h] [bp-8h]@6
-	int *v40; // [sp+D4h] [bp-4h]@2
-
-	__debugbreak();// 
-	v2 = (char *)&this->field_64[4 * this->uNumVertices];
-	v38 = 0;
-	*(int *)v2 = this->field_64[0];
-	v2 += 4;
-	*(int *)v2 = this->field_64[1];
-	v2 += 4;
-	*(int *)v2 = this->field_64[2];
-	*((int *)v2 + 1) = this->field_64[3];
-	v3 = this->uNumVertices;
-	v35 = this;
-	if (v3 > 0)
-	{
-		v40 = &this->field_64[20];
-		v4 = (char *)&this->field_64[3] + 3;
-		v34 = v3;
-		while (1)
-		{
-			v5 = v4 - 15;
-			if (*(float *)(v4 - 15) >= (double)a2 && *(float *)(v4 + 1) >= (double)a2)
-			{
-				v4 += 16;
-				--v34;
-				if (!v34)
-					return this->uNumVertices = v38;
-				continue;
-			}
-			if (*(float *)v5 >= (double)a2)
-			{
-				v6 = (a2 - *(float *)v5) / (*(float *)(v4 + 1) - *(float *)v5);
-				v7 = (unsigned __int8)v4[16] - (unsigned int)(unsigned __int8)*v4;
-				v36 = v6;
-				v31 = (*(float *)(v4 + 5) - *(float *)(v4 - 11)) * v6 + *(float *)(v4 - 11);
-				v32 = (*(float *)(v4 + 9) - *(float *)(v4 - 7)) * v6 + *(float *)(v4 - 7);
-				*(float *)&v37 = (double)v7 * v6;
-				v8 = *(float *)&v37 + 6.7553994e15;
-				v9 = (unsigned __int8)*v4;
-				*(float *)&v37 = (double)((unsigned __int8)v4[15] - (unsigned int)(unsigned __int8)*(v4 - 1)) * v36;
-				v10 = *(float *)&v37 + 6.7553994e15;
-				v11 = (unsigned __int8)*(v4 - 2);
-				v37 = LODWORD(v10) + (unsigned __int8)*(v4 - 1);
-				v39 = (double)((unsigned int)(unsigned __int8)v4[14] - v11) * v36;
-				v12 = v39 + 6.7553994e15;
-				v13 = LODWORD(v12) + (unsigned __int8)*(v4 - 2);
-				v39 = (double)((*(int *)(v4 + 13) & 0xFF) - (*(int *)(v4 - 3) & 0xFFu)) * v36;
-				v14 = v39 + 6.7553994e15;
-				v33 = (LODWORD(v14) + (*(int *)(v4 - 3) & 0xFF)) | ((v13 | ((v37 | ((LODWORD(v8) + v9) << 8)) << 8)) << 8);
-				//this = v35;
-				v5 = (char *)&v30 + 4;
-			}
-			else if (*(float *)(v4 + 1) >= (double)a2)
-			{
-				v15 = (a2 - *(float *)v5) / (*(float *)(v4 + 1) - *(float *)v5);
-				v16 = (unsigned __int8)*v4;
-				HIDWORD(v30) = LODWORD(a2);
-				v17 = (unsigned __int8)v4[16] - v16;
-				v36 = v15;
-				v31 = (*(float *)(v4 + 5) - *(float *)(v4 - 11)) * v15 + *(float *)(v4 - 11);
-				v32 = (*(float *)(v4 + 9) - *(float *)(v4 - 7)) * v15 + *(float *)(v4 - 7);
-				v39 = (double)v17 * v15;
-				v18 = v39 + 6.7553994e15;
-				v19 = (unsigned __int8)*v4;
-				v39 = (double)((unsigned __int8)v4[15] - (unsigned int)(unsigned __int8)*(v4 - 1)) * v36;
-				v20 = v39 + 6.7553994e15;
-				v21 = (unsigned __int8)*(v4 - 2);
-				v37 = LODWORD(v20) + (unsigned __int8)*(v4 - 1);
-				v39 = (double)((unsigned int)(unsigned __int8)v4[14] - v21) * v36;
-				v22 = v39 + 6.7553994e15;
-				v23 = LODWORD(v22) + (unsigned __int8)*(v4 - 2);
-				v39 = (double)((*(int *)(v4 + 13) & 0xFF) - (*(int *)(v4 - 3) & 0xFFu)) * v36;
-				v24 = v39 + 6.7553994e15;
-				v33 = (LODWORD(v24) + (*(int *)(v4 - 3) & 0xFF)) | ((v23 | ((v37 | ((LODWORD(v18) + v19) << 8)) << 8)) << 8);
-				v25 = v40;
-				*v40 = *(int *)v5;
-				v26 = (int)(v5 + 4);
-				++v25;
-				*v25 = *(int *)v26;
-				v26 += 4;
-				++v25;
-				++v38;
-				v40 += 4;
-				*v25 = *(int *)v26;
-				v25[1] = *(int *)(v26 + 4);
-				v5 = (char *)&v30 + 4;
-			}
-			v27 = v40;
-			++v38;
-			*v40 = *(int *)v5;
-			v28 = (int)(v5 + 4);
-			++v27;
-			*v27 = *(int *)v28;
-			v28 += 4;
-			++v27;
-			v40 += 4;
-			*v27 = *(int *)v28;
-			v27[1] = *(int *)(v28 + 4);
-			v4 += 16;
-			--v34;
-			if (!v34)
-				return this->uNumVertices = v38;
-		}
-	}
-	return this->uNumVertices = v38;
-}
-
-//----- (00477C61) --------------------------------------------------------
-int stru6_stru1_indoor_sw_billboard::sub_477C61()
-{
-	//stru6_stru1_indoor_sw_billboard *v1; // ebx@1
-	int v2; // ecx@2
-	int v3; // eax@3
-	double v4; // st7@4
-	double v5; // st7@5
-	double v6; // st6@5
-	double v7; // st5@6
-	float v8; // ST30_4@8
-	float v9; // ST24_4@8
-	double v10; // st7@8
-	double v11; // st6@8
-	double v12; // st5@8
-	float v13; // ST24_4@13
-	int v14; // esi@13
-	char *v15; // esi@15
-	//signed int v16; // eax@16
-	//  __int16 v17; // fps@16
-	//  unsigned __int8 v18; // c2@16
-	//  unsigned __int8 v19; // c3@16
-	double v20; // st6@16
-	float v21; // ST18_4@17
-	float v22; // ST2C_4@17
-	float v23; // ST34_4@17
-	float v24; // ST24_4@17
-	double v25; // st7@17
-	double v26; // st6@17
-	float v27; // ST34_4@18
-	float v28; // ST30_4@18
-	int v29; // eax@19
-	signed int v31; // [sp+8h] [bp-28h]@15
-	float v32; // [sp+Ch] [bp-24h]@16
-	float v33; // [sp+14h] [bp-1Ch]@16
-	float v34; // [sp+18h] [bp-18h]@16
-	float v35; // [sp+1Ch] [bp-14h]@17
-	float v36; // [sp+20h] [bp-10h]@4
-	float v37; // [sp+24h] [bp-Ch]@4
-	float v38; // [sp+24h] [bp-Ch]@16
-	float v39; // [sp+28h] [bp-8h]@9
-	float v40; // [sp+28h] [bp-8h]@16
-	float v41; // [sp+2Ch] [bp-4h]@6
-	float v42; // [sp+2Ch] [bp-4h]@9
-
-	//__debugbreak();// ,       
-	if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
-	{
-
-		if (this->uNumVertices > 0)
-		{
-			v3 = (int)&this->field_14[1];
-			//do
-			for (v2 = 0; v2 < this->uNumVertices; ++v2)
-			{
-				v4 = *(float *)(v3 - 4);
-				LODWORD(v37) = *(int *)v3;
-				LODWORD(v36) = *(int *)(v3 + 4);
-				if (pIndoorCameraD3D->sRotationX)
-				{
-					v5 = v4 - (double)pIndoorCameraD3D->vPartyPos.x;
-					v6 = v37 - (double)pIndoorCameraD3D->vPartyPos.y;
-					//if ( pRenderer->pRenderD3D )
-					//{
-					v41 = pIndoorCameraD3D->fRotationYSine * v6 + pIndoorCameraD3D->fRotationYCosine * v5;
-					v7 = pIndoorCameraD3D->fRotationYSine * v5 - pIndoorCameraD3D->fRotationYCosine * v6;
-					/*}
-					else
-					{
-					v41 = pBLVRenderParams->fCosineY * v5 - pBLVRenderParams->fSineY * v6;
-					v7 = pBLVRenderParams->fSineY * v5 + pBLVRenderParams->fCosineY * v6;
-					}*/
-					v8 = v7;
-					v9 = v36 - (double)pIndoorCameraD3D->vPartyPos.z;
-					v10 = pIndoorCameraD3D->fRotationXCosine * v41 - pIndoorCameraD3D->fRotationXSine * v9;
-					v11 = v8;
-					v12 = pIndoorCameraD3D->fRotationXCosine * v9 + pIndoorCameraD3D->fRotationXSine * v41;
-				}
-				else
-				{
-					v42 = v4 - (double)pIndoorCameraD3D->vPartyPos.x;
-					v39 = v37 - (double)pIndoorCameraD3D->vPartyPos.y;
-					//if ( pRenderer->pRenderD3D )
-					//{
-					v10 = pIndoorCameraD3D->fRotationYSine * v39 + pIndoorCameraD3D->fRotationYCosine * v42;
-					v11 = pIndoorCameraD3D->fRotationYSine * v42 - pIndoorCameraD3D->fRotationYCosine * v39;
-					/*}
-					else
-					{
-					v10 = pBLVRenderParams->fCosineY * v42 - pBLVRenderParams->fSineY * v39;
-					v11 = pBLVRenderParams->fSineY * v42 + pBLVRenderParams->fCosineY * v39;
-					}*/
-					v12 = v36 - (double)pIndoorCameraD3D->vPartyPos.z;
-				}
-				v13 = v12;
-				//++v2;
-				*(int *)(v3 + 84) = LODWORD(v13);
-				v14 = *(int *)(v3 + 8);
-				*(float *)(v3 + 76) = v10;
-				*(int *)(v3 + 88) = v14;
-				*(float *)(v3 + 80) = v11;
-				v3 += 16;
-			}
-			//while ( v2 < this->uNumVertices );
-		}
-	}
-	else
-	{
-		v15 = (char *)&this->field_14[1];
-		//do
-		for (v31 = 3; v31; --v31)
-		{
-			v40 = (double)stru_5C6E00->Cos(pIndoorCameraD3D->sRotationX) * 0.0000152587890625;
-			v32 = (double)stru_5C6E00->Sin(pIndoorCameraD3D->sRotationX) * 0.0000152587890625;
-			v34 = (double)stru_5C6E00->Cos(pIndoorCameraD3D->sRotationY) * 0.0000152587890625;
-			v33 = (double)stru_5C6E00->Sin(pIndoorCameraD3D->sRotationY) * 0.0000152587890625;
-			//v16 = stru_5C6E00->Sin(pODMRenderParams->rotation_y);
-			LODWORD(v38) = *(int *)v15;
-			//UNDEF(v17);
-			v20 = *((float *)v15 - 1) - (double)pIndoorCameraD3D->vPartyPos.x;
-			//if ( v19 | v18 )
-			if (pIndoorCameraD3D->vPartyPos.x == 0)
-			{
-				v27 = v20;
-				LODWORD(v35) = *((int *)v15 + 1);
-				v28 = v38 - (double)pIndoorCameraD3D->vPartyPos.y;
-				v25 = v33 * v28 + v34 * v27;
-				v26 = v34 * v28 - v33 * v27;
-			}
-			else
-			{
-				v21 = v20;
-				v22 = v38 - (double)pIndoorCameraD3D->vPartyPos.y;
-				v23 = v33 * v22 + v34 * v21;
-				v24 = *((float *)v15 + 1) - (double)pIndoorCameraD3D->vPartyPos.z;
-				v25 = v32 * v24 + v40 * v23;
-				v26 = v34 * v22 - v33 * v21;
-				v35 = v40 * v24 - v32 * v23;
-			}
-			*((int *)v15 + 21) = LODWORD(v35);
-			v29 = *((int *)v15 + 2);
-			*((float *)v15 + 19) = v25;
-			*((int *)v15 + 22) = v29;
-			*((float *)v15 + 20) = v26;
-			v15 += 16;
-			//--v31;
-		}
-		//while ( v31 );
-	}
-	this->uNumVertices = 3;
-	return 1;
-}
-
-//----- (00477F63) --------------------------------------------------------
-bool stru6_stru1_indoor_sw_billboard::sub_477F63()
-{
-	signed int v1; // ebx@1
-	double v3; // st7@2
-	//int v4; // edx@4
-	char *v5; // ecx@5
-	int v6; // edi@5
-	float v7; // ST08_4@13
-	signed int v9; // [sp+Ch] [bp-8h]@1
-	float v10; // [sp+10h] [bp-4h]@2
-
-	//__debugbreak();// 
-	v1 = 0;
-	v9 = 0;
-	if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
-	{
-		v10 = 16192.0;
-		v3 = (double)pBLVRenderParams->fov_rad_fixpoint * 0.000015258789;
-	}
-	else if (uCurrentlyLoadedLevelType == LEVEL_Outdoor)
-	{
-		v10 = (double)pODMRenderParams->shading_dist_mist;
-		v3 = 8.0;
-	}
-	else
-		__debugbreak();//Error
-	if (this->uNumVertices <= 0)
-	{
-		memcpy(&this->field_14[40], &this->field_14[20], 16 * this->uNumVertices);
-		return this->uNumVertices != 0;
-	}
-	v5 = (char *)&this->field_14[20];
-	for (v6 = 0; v6 < this->uNumVertices; v6++)
-	{
-		if (v3 >= *(float *)v5 || *(float *)v5 >= (double)v10)
-		{
-			if (v3 < *(float *)v5)
-				v9 = 1;
-			else
-				v1 = 1;
-		}
-		v5 += 16;
-	}
-	if (!v1)
-	{
-		if (v9)
-		{
-			this->_477927(v10);
-			return this->uNumVertices != 0;
-		}
-		memcpy(&this->field_14[40], &this->field_14[20], 16 * this->uNumVertices);
-		return this->uNumVertices != 0;
-	}
-	v7 = v3;
-	_4775ED(v7);
-	return this->uNumVertices != 0;
-}
-
-//----- (0047802A) --------------------------------------------------------
-int stru6_stru1_indoor_sw_billboard::sub_47802A()
-{
-	double v6; // st7@4
-	signed int v16; // [sp+38h] [bp-Ch]@1
-	int a6; // [sp+3Ch] [bp-8h]@5
-	int a5; // [sp+40h] [bp-4h]@5
-
-	//  __debugbreak(); //  this->field_B4[i*4+16]
-	v16 = 0;
-	if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
-	{
-		for (int i = 0; i < this->uNumVertices; i++)
-		{
-			v6 = (double)pBLVRenderParams->fov_rad_fixpoint * 0.000015258789 / this->field_B4[i * 4];
-			//if ( pRenderer->pRenderD3D )
-			{
-				pIndoorCameraD3D->Project(round_to_int(this->field_B4[i * 4]), round_to_int(this->field_B4[i * 4 + 1]), round_to_int(this->field_B4[i * 4 + 2]),
-					&a5, &a6);
-				this->field_B4[i * 4 + 16] = (double)a5;
-				this->field_B4[i * 4 + 17] = (double)a6;
-				this->field_B4[i * 4 + 18] = round_to_int(this->field_B4[i * 4]);
-			}
-			/*else
-			{
-			this->field_B4[i*4+16] = (double)pBLVRenderParams->uViewportCenterX - v6 * this->field_B4[i*4+1];
-			this->field_B4[i*4+17] = (double)pBLVRenderParams->uViewportCenterY - v6 * this->field_B4[i*4+2];
-			this->field_B4[i*4+18] = this->field_B4[i*4];
-			}*/
-			this->field_B4[i * 4 + 19] = this->field_B4[i * 4 + 3];
-			if ((double)(signed int)pViewport->uViewportTL_X <= this->field_B4[i * 4 + 16] && (double)(signed int)pViewport->uViewportBR_X > this->field_B4[i * 4 + 16]
-				&& (double)(signed int)pViewport->uViewportTL_Y <= this->field_B4[i * 4 + 17] && (double)(signed int)pViewport->uViewportBR_Y > this->field_B4[i * 4 + 17])
-				v16 = 1;
-		}
-	}
-	else
-	{
-		for (int i = 0; i < this->uNumVertices; i++)
-		{
-			this->field_B4[i * 4 + 20] = (double)pViewport->uScreenCenterX - (double)pODMRenderParams->int_fov_rad / this->field_B4[i * 4] * this->field_B4[i * 4 + 1];
-			this->field_B4[i * 4 + 21] = (double)pViewport->uScreenCenterY - (double)pODMRenderParams->int_fov_rad / this->field_B4[i * 4] * this->field_B4[i * 4 + 2];
-			*((int *)&this->field_B4[i * 4 + 22]) = (int)this->field_B4[i * 4];
-			*((int *)&this->field_B4[i * 4 + 23]) = this->field_B4[i * 4 + 3];
-			if ((double)(signed int)pViewport->uViewportTL_X <= this->field_B4[i * 4 + 20] && (double)(signed int)pViewport->uViewportBR_X > this->field_B4[i * 4 + 20]
-				&& (double)(signed int)pViewport->uViewportTL_Y <= this->field_B4[i * 4 + 21] && (double)(signed int)pViewport->uViewportBR_Y > this->field_B4[i * 4 + 21])
-				v16 = 1;
-		}
-	}
-	return v16;
-}
--- a/stru6.h	Thu May 21 18:32:45 2015 +0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,169 +0,0 @@
-#pragma once
-
-
-/*  120 */
-#pragma pack(push, 1)
-struct stru6_stru1_indoor_sw_billboard
-{
-  //----- (004775B1) --------------------------------------------------------
-  inline stru6_stru1_indoor_sw_billboard()
-  {
-    uNumVertices = 0;
-    uNumVec4sInArray1 = 0;
-    uNumVec3sInArray2 = 0;
-    pArray1 = nullptr;
-    pArray2 = nullptr;
-  }
-
-  //----- (004775C4) --------------------------------------------------------
-  virtual ~stru6_stru1_indoor_sw_billboard();
-
-  int _4775ED(float a2);
-  int _477927(float a2);
-  int sub_477C61();
-  bool sub_477F63();
-  int sub_47802A();
-  void Initialize(int a2);
-  void _47829F_sphere_particle(float x_offset, float y_offset, float z_offset, float scale, int diffuse);
-
-
-  struct local_01
-  {
-    float x;
-    float y;
-    float z;
-    int   diffuse;
-  };
-
-  unsigned int uNumVec4sInArray1;
-  struct stru16x *pArray1;
-  unsigned int uNumVec3sInArray2;
-  struct stru160 *pArray2;
-  int uNumVertices;
-  local_01 field_14[5];
-  int field_64[20];
-  float field_B4[20];
-  local_01 field_104[5];
-};
-#pragma pack(pop)
-
-
-/*  122 */
-#pragma pack(push, 1)
-struct PlayerBuffAnim
-{
-  inline PlayerBuffAnim():
-    bRender(false), uSpellAnimTime(0), uSpellIconID(0)
-  {}
-
-  __int16 bRender;
-  __int16 field_2;
-  int uSpellAnimTimeElapsed;
-  int uSpellAnimTime;
-  int uSpellIconID;
-};
-#pragma pack(pop)
-
-
-/*  307 */
-#pragma pack(push, 1)
-struct ProjectileAnim
-{
-  float srcX;
-  float srcY;
-  float srcZ;
-  float dstX;
-  float dstY;
-  float dstZ;
-  int uTextureID;
-};
-#pragma pack(pop)
-
-
-/*  306 */
-#pragma pack(push, 1)
-struct stru6_stru2
-{
-  //int field_0;
-  float flt_0_x;
-  float flt_4_y;
-  float flt_8_z;
-  int   field_C;
-};
-#pragma pack(pop)
-
-
-
-/*  121 */
-#pragma pack(push, 1)
-struct stru6
-{
-  //----- (004A7155) --------------------------------------------------------
-  stru6()
-  {
-    this->field_204 = 0;
-    this->uFadeTime = 0;
-    this->uNumProjectiles = 0;
-    this->field_0 = 0;
-	this->uAnimLength = 0;
-
-    pStru1 = new stru6_stru1_indoor_sw_billboard;
-    pStru1->Initialize(0xFF3C1Eu);
-  }
-  //----- (004A71DC) --------------------------------------------------------
-  ~stru6()
-  {
-    delete pStru1;
-    pStru1 = nullptr;
-  }
-
-  void DoAddProjectile(float srcX, float srcY, float srcZ, float dstX, float dstY, float dstZ, unsigned int uTextureID);
-  void DrawProjectiles();
-  void _4A73AA_hanging_trace_particles___like_fire_strike_ice_blast_etc(struct SpriteObject *a2, unsigned int uDiffuse, unsigned int uTextureID);
-  void _4A75CC_single_spell_collision_particle(struct SpriteObject *a1, unsigned int uDiffuse, unsigned int uTextureID);
-  void _4A7688_fireball_collision_particle(struct SpriteObject *a2);
-  void _4A77FD_implosion_particle_d3d(struct SpriteObject *a1);
-  void _4A78AE_sparks_spell(struct SpriteObject *a1);
-  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 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);
-  void SetPlayerBuffAnim(unsigned __int16 uSpellID, unsigned __int16 uPlayerID);
-  void FadeScreen__like_Turn_Undead_and_mb_Armageddon(unsigned int uDiffuseColor, unsigned int uFadeTime);
-  int _4A8BFC();
-  void RenderSpecialEffects();
-  void DrawPlayerBuffAnims();
-  void LoadAnimations();
-
-
-  int field_0;
-  stru6_stru2 array_4[31];
-  int field_1F4;
-  int field_1F8;
-  int field_1FC;
-  int field_200;
-  int field_204;
-  PlayerBuffAnim pPlayerBuffs[4];
-  ProjectileAnim pProjectiles[32];
-  int uNumProjectiles;
-  stru6_stru1_indoor_sw_billboard *pStru1;
-  int field_5D0;
-  int uAnimLength;
-  int uFadeTime;
-  int uFadeLength;
-  int uFadeColor;
-  unsigned int uTextureID_effpar1;
-  unsigned int uTextureID_effpar2;
-  unsigned int uTextureID_effpar3;
-  unsigned int uSpriteID_sp57c;
-  int field_5F4;
-};
-#pragma pack(pop)
-
-