changeset 1028:fbde7d8fcdb1

Merge
author Nomad
date Tue, 21 May 2013 11:24:35 +0200
parents 5aba2a5047c4 (current diff) 6afa77761a00 (diff)
children c94d6a37d298
files
diffstat 68 files changed, 4811 insertions(+), 6118 deletions(-) [+]
line wrap: on
line diff
--- a/Actor.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/Actor.cpp	Tue May 21 11:24:35 2013 +0200
@@ -1,9 +1,15 @@
 #include <assert.h>
 
+
+#include "VideoPlayer.h"
+#include "DecalBuilder.h"
+
+#include "Sprites.h"
+#include "stru6.h"
+
+
 #include "Actor.h"
-#include "SpriteObject.h"
 #include "Math.h"
-#include "Party.h"
 #include "Outdoor.h"
 #include "AudioPlayer.h"
 #include "Game.h"
@@ -22,6 +28,7 @@
 #include "GUIFont.h"
 
 #include "MM7.h"
+#include "SpriteObject.h"
 
 
 
@@ -3145,6 +3152,7 @@
     actor->pActorBuffs[i].Reset();
 
   ItemGen drop;
+  drop.Reset();
   switch (actor->pMonsterInfo.uID)
   {
     case MONSTER_HARPY_1: case MONSTER_HARPY_2: case MONSTER_HARPY_3:
--- a/Actor.h	Tue May 21 11:24:26 2013 +0200
+++ b/Actor.h	Tue May 21 11:24:35 2013 +0200
@@ -1,8 +1,7 @@
 #pragma once
-#include "VectorTypes.h"
-#include "Items.h"
 #include "Monsters.h"
 #include "Spells.h"
+#include "Items.h"
 
 
 
--- a/Arcomage.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/Arcomage.cpp	Tue May 21 11:24:35 2013 +0200
@@ -1,5 +1,6 @@
 #include <string>
 
+#include "LightmapBuilder.h"
 #include "Arcomage.h"
 #include "VideoPlayer.h"
 #include "AudioPlayer.h"
@@ -13,7 +14,6 @@
 #include "Events2D.h"
 #include "VectorTypes.h"
 #include "texts.h"
-#include "mm7_data.h"
 
 
 
--- a/AudioPlayer.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/AudioPlayer.cpp	Tue May 21 11:24:35 2013 +0200
@@ -1,6 +1,9 @@
 #include <string>
 #include <assert.h>
 
+#include "stru11.h"
+
+#include "VideoPlayer.h"
 #include "AudioPlayer.h"
 #include "Allocator.h"
 #include "FrameTableInc.h"
@@ -14,13 +17,11 @@
 #include "OSInfo.h"
 #include "Math.h"
 #include "MapInfo.h"
-#include "Actor.h"
 #include "GUIWindow.h"
 #include "Log.h"
 
 #include "Bink_Smacker.h"
 
-#include "mm7_data.h"
 #include "MM7.h"
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CShow.cpp	Tue May 21 11:24:35 2013 +0200
@@ -0,0 +1,80 @@
+#include "CShow.h"
+
+#include "VideoPlayer.h"
+#include "Mouse.h"
+
+void CShow::PlayMovie( MovieType eVideo, bool bShowMouseAfterPlayback )
+{
+    int v3; // edx@5
+    const char *Name; // ecx@5
+    //std::string v5; // [sp-18h] [bp-24h]@4
+    //signed int v6; // [sp-Ch] [bp-18h]@10
+    int ScreenSizeFlag; // [sp-8h] [bp-14h]@4
+    //int v8; // [sp-4h] [bp-10h]@4
+    //char v9; // [sp+0h] [bp-Ch]@14
+    //char v10; // [sp+4h] [bp-8h]@4
+    //int a3; // [sp+Bh] [bp-1h]@14
+
+    if (bNoVideo)
+        return;
+
+    if (pAsyncMouse)
+        pAsyncMouse->Suspend();
+    switch ( eVideo )
+    {
+    case MOVIE_Invalid:
+        MessageBoxW(nullptr, L"No movie", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Show.cpp:40", 0);
+        break;
+    case MOVIE_3DOLogo:
+        ScreenSizeFlag = 0;
+        v3 = 0;
+        Name = "3dologo";
+        VideoPlayer::MovieLoop(Name, v3, ScreenSizeFlag, 1);
+        break;
+    case MOVIE_NWCLogo:
+        ScreenSizeFlag = 1;
+        v3 = 0;
+        Name = "new world logo";
+        VideoPlayer::MovieLoop(Name, v3, ScreenSizeFlag, 1);
+        break;
+    case MOVIE_JVC:
+        ScreenSizeFlag = 1;
+        v3 = 0;
+        Name = "jvc";
+        VideoPlayer::MovieLoop(Name, v3, ScreenSizeFlag, 1);
+        break;
+    case MOVIE_Intro:
+        ScreenSizeFlag = 1;
+        v3 = 0;
+        Name = "Intro";
+        VideoPlayer::MovieLoop(Name, v3, ScreenSizeFlag, 1);
+        break;
+    case MOVIE_Emerald:
+        ScreenSizeFlag = 1;
+        v3 = 0;
+        Name = "Intro Post";
+        VideoPlayer::MovieLoop(Name, v3, ScreenSizeFlag, 1);
+        break;
+    case MOVIE_Death:
+        ScreenSizeFlag = 1;
+        v3 = 2;
+        Name = "losegame";
+        VideoPlayer::MovieLoop(Name, v3, ScreenSizeFlag, 1);
+        break;
+    case MOVIE_Outro:
+        ScreenSizeFlag = 1;
+        v3 = 20;
+        Name = "end_seq1";
+        VideoPlayer::MovieLoop(Name, v3, ScreenSizeFlag, 1);
+        break;
+    default:
+        MessageBoxW(nullptr, L"Invalid movie requested in CShow::Run()", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Show.cpp:72", 0);
+        break;
+    }
+    if ( bShowMouseAfterPlayback )
+    {
+        if (pAsyncMouse)
+            pAsyncMouse->Resume();
+    }
+}
+
--- a/CShow.h	Tue May 21 11:24:26 2013 +0200
+++ b/CShow.h	Tue May 21 11:24:35 2013 +0200
@@ -1,6 +1,4 @@
 #pragma once
-#include "VideoPlayer.h"
-#include "Mouse.h"
 
 
 
@@ -29,80 +27,7 @@
 
   
   //----- (004A952D) --------------------------------------------------------
-  void CShow::PlayMovie(MovieType eVideo, bool bShowMouseAfterPlayback)
-  {
-  int v3; // edx@5
-  const char *Name; // ecx@5
-  //std::string v5; // [sp-18h] [bp-24h]@4
-  //signed int v6; // [sp-Ch] [bp-18h]@10
-  int ScreenSizeFlag; // [sp-8h] [bp-14h]@4
-  //int v8; // [sp-4h] [bp-10h]@4
-  //char v9; // [sp+0h] [bp-Ch]@14
-  //char v10; // [sp+4h] [bp-8h]@4
-  //int a3; // [sp+Bh] [bp-1h]@14
-
-  if (bNoVideo)
-    return;
-
-  if (pAsyncMouse)
-    pAsyncMouse->Suspend();
-  switch ( eVideo )
-  {
-    case MOVIE_Invalid:
-      MessageBoxW(nullptr, L"No movie", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Show.cpp:40", 0);
-      break;
-    case MOVIE_3DOLogo:
-      ScreenSizeFlag = 0;
-      v3 = 0;
-      Name = "3dologo";
-      VideoPlayer::MovieLoop(Name, v3, ScreenSizeFlag, 1);
-      break;
-    case MOVIE_NWCLogo:
-      ScreenSizeFlag = 1;
-      v3 = 0;
-      Name = "new world logo";
-      VideoPlayer::MovieLoop(Name, v3, ScreenSizeFlag, 1);
-      break;
-    case MOVIE_JVC:
-      ScreenSizeFlag = 1;
-      v3 = 0;
-      Name = "jvc";
-      VideoPlayer::MovieLoop(Name, v3, ScreenSizeFlag, 1);
-      break;
-    case MOVIE_Intro:
-      ScreenSizeFlag = 1;
-      v3 = 0;
-      Name = "Intro";
-      VideoPlayer::MovieLoop(Name, v3, ScreenSizeFlag, 1);
-      break;
-    case MOVIE_Emerald:
-      ScreenSizeFlag = 1;
-      v3 = 0;
-      Name = "Intro Post";
-      VideoPlayer::MovieLoop(Name, v3, ScreenSizeFlag, 1);
-      break;
-    case MOVIE_Death:
-      ScreenSizeFlag = 1;
-      v3 = 2;
-      Name = "losegame";
-      VideoPlayer::MovieLoop(Name, v3, ScreenSizeFlag, 1);
-      break;
-    case MOVIE_Outro:
-      ScreenSizeFlag = 1;
-      v3 = 20;
-      Name = "end_seq1";
-      VideoPlayer::MovieLoop(Name, v3, ScreenSizeFlag, 1);
-      break;
-    default:
-      MessageBoxW(nullptr, L"Invalid movie requested in CShow::Run()", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Show.cpp:72", 0);
-      break;
-  }
-  if ( bShowMouseAfterPlayback )
-  {
-    if (pAsyncMouse)
-      pAsyncMouse->Resume();
-  }
-}
+  void CShow::PlayMovie(MovieType eVideo, bool bShowMouseAfterPlayback);
 
 
   void (__thiscall ***vdestructor_ptr)(CShow *, bool);
--- a/Chest.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/Chest.cpp	Tue May 21 11:24:35 2013 +0200
@@ -1,13 +1,14 @@
 #include <stdio.h>
 #include <assert.h>
 
+#include "BSPModel.h"
+#include "Items.h"
 #include "Chest.h"
 #include "FrameTableInc.h"
 #include "Allocator.h"
 #include "LOD.h"
 #include "MapInfo.h"
 #include "Actor.h"
-#include "Indoor.h"
 #include "Outdoor.h"
 #include "DecorationList.h"
 #include "Party.h"
@@ -17,10 +18,10 @@
 #include "ObjectList.h"
 #include "GUIWindow.h"
 #include "Time.h"
-#include "Overlays.h"
 
 #include "mm7_data.h"
 #include "MM7.h"
+#include "SpriteObject.h"
 
 
 
@@ -347,7 +348,7 @@
     if ( !areWeLoadingTexture )
         {
         item_texture->Release();
-        pIcons_LOD->_40F9C5();
+        pIcons_LOD->SyncLoadedFilesCount();
         }
     if ( (texture_cell_width + test_cell_position % chest_cell_width <= chest_cell_width) && 
         (texture_cell_height + test_cell_position / chest_cell_width <= chest_cell_heght) )
@@ -475,7 +476,7 @@
     if ( !areWeLoadingTexture )
     {
       ((Texture *)v9)->Release();
-      pIcons_LOD->_40F9C5();
+      pIcons_LOD->SyncLoadedFilesCount();
     }
     if ( v13 > 0 )
     {
@@ -550,7 +551,7 @@
     if ( !areWeLoadingTexture )
         {
         v8->Release();
-        pIcons_LOD->_40F9C5();
+        pIcons_LOD->SyncLoadedFilesCount();
         }
     chest_cell_width = pChestWidthsByType[pChests[ uChestID].uChestBitmapID];
     chest_cell_row_pos = 0;
@@ -787,7 +788,7 @@
     if ( !areWeLoadingTexture )
     {
         v5->Release();
-        pIcons_LOD->_40F9C5();
+        pIcons_LOD->SyncLoadedFilesCount();
         v10 = v21;
     }
     if ( v10 > 0 )
--- a/Chest.h	Tue May 21 11:24:26 2013 +0200
+++ b/Chest.h	Tue May 21 11:24:35 2013 +0200
@@ -1,5 +1,4 @@
 #pragma once
-#include "Items.h"
 
 
 
--- a/DecalBuilder.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/DecalBuilder.cpp	Tue May 21 11:24:35 2013 +0200
@@ -7,7 +7,7 @@
 
 #include "mm7_data.h"
 
-
+#include "stru9.h"
 
 
 
--- a/Events.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/Events.cpp	Tue May 21 11:24:35 2013 +0200
@@ -1,15 +1,16 @@
 #include <assert.h>
 #include <stdlib.h>
 
+#include "VideoPlayer.h"
+#include "Mouse.h"
+
 #include "MapInfo.h"
 #include "Game.h"
 #include "GUIWindow.h"
-#include "GUIFont.h"
 #include "GUIProgressBar.h"
 #include "Chest.h"
 #include "stru176.h"
 #include "LOD.h"
-#include "NPC.h"
 #include "Actor.h"
 #include "Party.h"
 #include "Math.h"
@@ -17,16 +18,12 @@
 #include "Indoor.h"
 #include "Viewport.h"
 #include "texts.h"
-#include "Texture.h"
 #include "Allocator.h"
-#include "mm7_data.h"
 #include "stru123.h"
 #include "stru159.h"
 #include "Events.h"
 #include "Events2D.h"
 #include "UIHouses.h"
-#include "Weather.h"
-#include "Party.h"
 #include "MM7.h"
 
 
@@ -1337,7 +1334,7 @@
 							pDialogueWindow->Release();
 							dialog_menu_id = HOUSE_DIALOGUE_NULL;
 							pDialogueWindow = 0;
-							pIcons_LOD->_40F9C5();
+							pIcons_LOD->SyncLoadedFilesCount();
 							}
 						OnMapLeave();
 						return;
--- a/GUIButton.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/GUIButton.cpp	Tue May 21 11:24:35 2013 +0200
@@ -1,6 +1,5 @@
 #include "GUIWindow.h"
 #include "GUIFont.h"
-#include "Allocator.h"
 
 #include "mm7_data.h"
 
@@ -157,23 +156,23 @@
 
 
 //----- (00415180) --------------------------------------------------------
-char GUIButton::DrawLabel(const char *edx0, GUIFont *pFont, int a5, int *a9)
-{
+void GUIButton::DrawLabel( const char *label_text, struct GUIFont *pFont, int a5, int uFontShadowColor )
+    {
   const char *v5; // ebx@1
   GUIButton *v6; // esi@1
   int v7; // eax@1
 
-  v5 = edx0;
+  v5 = label_text;
   v6 = this;
   //strlen(edx0);
-  v7 = pFont->GetLineWidth(edx0);
+  v7 = pFont->GetLineWidth(label_text);
   return pParent->DrawText(
            pFont,
            v6->uX + (signed int)(v6->uWidth - v7) / 2,
-           v6->uY + (signed int)(v6->uHeight - LOBYTE(pFont->uFontHeight)) / 2,
+           v6->uY + (signed int)(v6->uHeight - pFont->uFontHeight) / 2,
            a5,
-           v5,
+           label_text,
            0,
            0,
-           (unsigned int)a9);
+           uFontShadowColor);
 }
--- a/GUIWindow.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/GUIWindow.cpp	Tue May 21 11:24:35 2013 +0200
@@ -15,7 +15,6 @@
 #include "Render.h"
 #include "PlayerFrameTable.h"
 #include "SaveLoad.h"
-#include "FactionTable.h"
 #include "StorylineTextTable.h"
 #include "Events2D.h"
 #include "UIHouses.h"
@@ -34,7 +33,7 @@
 struct GUIWindow pWindowList[20];
 
 struct GUIMessageQueue *pMessageQueue_50CBD0 = new GUIMessageQueue;
-
+struct GUIMessageQueue *pMessageQueue_50C9E8 = new GUIMessageQueue;
 
 // inlined
 //----- (mm6c::00420520) --------------------------------------------------
@@ -176,8 +175,8 @@
 // 5075E0: using guessed type int pVisibleWindowsIdxs[20];
 
 //----- (0041D73D) --------------------------------------------------------
-char GUIWindow::_41D73D_draw_buff_tooltip()
-{
+void GUIWindow::_41D73D_draw_buff_tooltip()
+    {
   GUIFont *v1; // esi@1
   GUIWindow *v2; // edi@1
   SpellBuff *v3; // eax@1
@@ -242,7 +241,7 @@
               (unsigned __int8)*v8,
               (unsigned __int8)v8[1]);
       v2->DrawText(a2, 52, v12, v14, v13, 0, 0, 0);
-      LOBYTE(v9) = sub_41D20D_buff_remaining_time_string(v12, v2, v11, a2);
+      sub_41D20D_buff_remaining_time_string(v12, v2, v11, a2);
       v1 = a2;
     }
     ++v18;
@@ -250,7 +249,7 @@
     v8 += 3;
   }
   while ( (signed int)v18 < (signed int)pParty->pPlayers );
-  return v9;
+  
 }
 
 
@@ -297,7 +296,7 @@
   {
 	case WINDOW_GreetingNPC:
 		{
-		pIcons_LOD->_40F9C5();
+		pIcons_LOD->SyncLoadedFilesCount();
 		pCurrentScreen = pMainScreenNum;
 		pKeyActionMap->_459ED1(3);
 		break;
@@ -309,7 +308,7 @@
 		uNumDialogueNPCPortraits = 0;
 		pTexture_Dialogue_Background->Release();
 
-		pIcons_LOD->_40F9C5();
+		pIcons_LOD->SyncLoadedFilesCount();
 		pIcons_LOD->_4114F2();
 		dword_5C35D4 = 0;
 		if ( bFlipOnExit )
@@ -326,7 +325,7 @@
 		pVideoPlayer->Unload();
 		pTexture_outside->Release();
 		pTexture_Dialogue_Background->Release();
-		pIcons_LOD->_40F9C5();
+		pIcons_LOD->SyncLoadedFilesCount();
 		pCurrentScreen = pMainScreenNum;
 		break;
 		}
@@ -345,7 +344,7 @@
 		{
         pTexture_outside->Release();
         pTexture_Dialogue_Background->Release();
-        pIcons_LOD->_40F9C5();
+        pIcons_LOD->SyncLoadedFilesCount();
         pCurrentScreen = pMainScreenNum;
         break;
 		}
@@ -356,7 +355,7 @@
         uNumDialogueNPCPortraits = 0;
         pTexture_Dialogue_Background->Release();
 
-        pIcons_LOD->_40F9C5();
+        pIcons_LOD->SyncLoadedFilesCount();
         pCurrentScreen = pMainScreenNum;
 		}
 	default:
@@ -1240,8 +1239,8 @@
 
 
 //----- (0044CE08) --------------------------------------------------------
-char GUIWindow::DrawText(GUIFont *a2, signed int uX, int uY, unsigned int uFontColor, const char *Str, int a7, int a8, unsigned int uFontShadowColor)
-{
+void GUIWindow::DrawText( GUIFont *a2, signed int uX, int uY, unsigned int uFontColor, const char *Str, int a7, int a8, unsigned int uFontShadowColor )
+    {
   GUIWindow *v9; // edi@1
   GUIFont *v10; // ebx@1
   int v11; // eax@2
@@ -1275,7 +1274,7 @@
   if ( !Str )
   {
     MessageBoxW(nullptr, L"Invalid string passed!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Font.cpp:859", 0);
-    return v11;
+    return;
   }
   v11 = strcmp(Str, "null");
   if ( v11 )
@@ -1350,7 +1349,7 @@
 LABEL_36:
                   v11 = v11 + v13 - 3;
                   if ( v11 > a8 )
-                    return v11;
+                    return;
                   break;
                 }
                 break;
@@ -1402,7 +1401,7 @@
       }
     }
   }
-  return v11;
+  return;
 }
 
 
--- a/GUIWindow.h	Tue May 21 11:24:26 2013 +0200
+++ b/GUIWindow.h	Tue May 21 11:24:35 2013 +0200
@@ -1,5 +1,4 @@
 #pragma once
-#include "Items.h"
 #include "Player.h"
 
 
@@ -120,7 +119,7 @@
   UIMSG_HiredNPC_CastSpell = 143,
   UIMSG_PlayerCreation_VoicePrev = 144,
   UIMSG_PlayerCreation_VoiceNext = 145,
-  UIMSG_92 = 146,
+  UIMSG_SpellScrollUse = 146,
 
   UIMSG_StartNPCDialogue = 161,
   UIMSG_ArrowUp = 162,
@@ -322,7 +321,7 @@
 	                      UIMessageType msg, unsigned int msg_param, unsigned __int8 uHotkey, const char *pName, Texture *pTextures, ...);
   void DrawFlashingInputCursor(signed int a3, int a4, struct GUIFont *a2);
   int DrawTextInRect(GUIFont *a2, unsigned int uX, unsigned int uY, unsigned int uColor, const char *Str1, int Source, int a8);
-  char DrawText(GUIFont *a2, signed int uX, int uY, unsigned int uFontColor, const char *Str, int a7, int a8, unsigned int uFontShadowColor);
+  void DrawText(GUIFont *a2, signed int uX, int uY, unsigned int uFontColor, const char *Str, int a7, int a8, unsigned int uFontShadowColor);
   void DrawTitleText(GUIFont *a2, signed int uHorizontalMargin, unsigned int uVerticalMargin, unsigned __int16 uDefaultColor, const char *pInString, unsigned int uLineSpacing);
   void DrawCurrentTime(__int64 a2);
   void HouseDialogManager();
@@ -332,7 +331,7 @@
   GUIButton *GetControl(unsigned int uID);
   void Release();
   void _41D08F_set_keyboard_control_group(int a2, int a3, int a4, int a5);
-  char _41D73D_draw_buff_tooltip();
+  void _41D73D_draw_buff_tooltip();
 
   static GUIWindow *Create(unsigned int uX, unsigned int uY, unsigned int uWidth, unsigned int uHeight, enum WindowType eType, int a4, int a5);
 
@@ -443,7 +442,7 @@
 
 extern struct GUIMessageQueue *pMessageQueue_50CBD0; // idb
 
-
+extern struct GUIMessageQueue *pMessageQueue_50C9E8; // idb
 
 
 
@@ -498,9 +497,9 @@
 // character ui
 struct GUIWindow *CharacterUI_Initialize(unsigned int _this);
 const char *CharacterUI_GetSkillDescText(unsigned int uPlayerID, PLAYER_SKILL_TYPE uPlayerSkillType);
-char CharacterUI_SkillsTab_ShowHint();
+void CharacterUI_SkillsTab_ShowHint();
 void CharacterUI_StatsTab_ShowHint();
-char CharacterUI_StatsTab_Draw(Player *player);
+void CharacterUI_StatsTab_Draw(Player *player);
 void CharacterUI_SkillsTab_CreateButtons();
 void CharacterUI_SkillsTab_Draw(Player *player);
 void CharacterUI_AwardsTab_Draw(Player *player);
@@ -563,7 +562,7 @@
 #pragma pack(push, 1)
 struct GUIButton
 {
-  char DrawLabel(const char *edx0, struct GUIFont *pFont, int a5, int *a9);
+void DrawLabel(const char *label_text, struct GUIFont *pFont, int a5, int uFontShadowColor);
 
   void Release();
 
--- a/Game.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/Game.cpp	Tue May 21 11:24:35 2013 +0200
@@ -1,10 +1,23 @@
 #include <assert.h>
 
+#include "Vis.h"
+
+#include "LightmapBuilder.h"
+#include "DecalBuilder.h"
+#include "ParticleEngine.h"
+#include "Mouse.h"
+#include "Keyboard.h"
+#include "CShow.h"
+#include "GammaControl.h"
+#include "stru6.h"
+#include "stru9.h"
+#include "stru10.h"
+#include "stru11.h"
+#include "stru12.h"
+
 #include "Game.h"
 #include "Party.h"
 #include "IndoorCamera.h"
-#include "Math.h"
-#include "LightmapBuilder.h"
 #include "Viewport.h"
 #include "Time.h"
 #include "Outdoor.h"
@@ -13,14 +26,12 @@
 #include "LOD.h"
 #include "OSInfo.h"
 #include "GUIWindow.h"
-#include "Party.h"
 #include "TurnEngine.h"
 #include "VideoPlayer.h"
 #include "Bink_Smacker.h"
 #include "Events.h"
 #include "Arcomage.h"
 #include "texts.h"
-#include "Actor.h"
 #include "GUIFont.h"
 #include "Log.h"
 
--- a/Game.h	Tue May 21 11:24:26 2013 +0200
+++ b/Game.h	Tue May 21 11:24:35 2013 +0200
@@ -1,19 +1,5 @@
 #pragma once
-#include "LightmapBuilder.h"
-#include "DecalBuilder.h"
-#include "ParticleEngine.h"
-#include "Vis.h"
-#include "Mouse.h"
-#include "Keyboard.h"
-#include "IndoorCameraD3D.h"
-#include "CShow.h"
-#include "GammaControl.h"
-#include "stru6.h"
-#include "stru9.h"
-#include "stru10.h"
-#include "stru11.h"
-#include "stru12.h"
-
+#include "VectorTypes.h"
 
 
 #define GAME_FLAGS_1_DRAW_BLV_DEBUGS    0x08
@@ -80,6 +66,20 @@
 };
 #pragma pack(pop)
 
+
+class Vis;
+class LightmapBuilder;
+class ParticleEngine;
+class Mouse;
+class Keyboard;
+class ThreadWard;
+class CShow;
+class GammaController;
+struct stru9;
+struct stru10;
+struct stru11;
+struct stru12;
+
 /*  104 */
 #pragma pack(push, 1)
 struct Game
@@ -90,6 +90,7 @@
 protected: Game();
 protected: virtual ~Game();
 
+
 public:
   void _44E904();
   bool InitializeGammaController();
--- a/GammaControl.h	Tue May 21 11:24:26 2013 +0200
+++ b/GammaControl.h	Tue May 21 11:24:35 2013 +0200
@@ -1,5 +1,5 @@
 #pragma once
-#include "Render.h"
+#include "lib\legacy_dx\d3d.h"
 
 #pragma pack(push, 1)
 struct GammaController
--- a/Indoor.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/Indoor.cpp	Tue May 21 11:24:35 2013 +0200
@@ -1,7 +1,13 @@
 #include <assert.h>
 
+#include "LightmapBuilder.h"
+#include "DecalBuilder.h"
+#include "ParticleEngine.h"
+#include "stru9.h"
+#include "stru10.h"
+
+#include "BSPModel.h"
 #include "Outdoor.h"
-#include "Render.h"
 #include "SpriteObject.h"
 #include "Events.h"
 #include "Game.h"
@@ -23,8 +29,6 @@
 #include "PaletteManager.h"
 #include "MapInfo.h"
 #include "IndoorCamera.h"
-#include "GUIWindow.h"
-#include "GUIFont.h"
 
 #include "mm7_data.h"
 #include "MM7.h"
@@ -69,6 +73,21 @@
 };
 
 
+const char *_4E6BDC_loc_names[11]=
+    {
+    "mdt12.blv",
+    "d18.blv",
+    "mdt14.blv",
+    "d37.blv",
+    "mdk01.blv",
+    "mdt01.blv",
+    "mdr01.blv",
+    "mdt10.blv",
+    "mdt09.blv",
+    "mdt15.blv",
+    "mdt11.blv"
+    };
+
 
 //----- (0043F39E) --------------------------------------------------------
 void __fastcall PrepareDrawLists_BLV(IndoorLocation_drawstru *_this)
@@ -145,7 +164,6 @@
 int BLVRenderParams::Reset(IndoorLocation_drawstru *a2)
 {
   IndoorLocation_drawstru *v2; // ebx@1
-  BLVRenderParams *v3; // esi@1
   int v4; // ST08_4@1
   int v5; // ST04_4@1
   int v6; // ST00_4@1
@@ -174,7 +192,6 @@
   int v29; // [sp+24h] [bp+8h]@5
 
   v2 = a2;
-  v3 = this;
   this->field_0_timer_ = a2->field_0_timer;
   this->uFlags = a2->uFlags;
   this->vPartyPos.x = a2->vPosition.x;
@@ -186,82 +203,82 @@
   v6 = this->vPartyPos.x;
   this->sPartyRotX = a2->sRotationX;
   v7 = pIndoor->GetSector(v6, v5, v4);
-  v3->uPartySectorID = v7;
+  this->uPartySectorID = v7;
   if ( !v7 )
   {
-    v8 = v3->vPartyPos.z;
-    v3->vPartyPos.x = pParty->vPosition.x;
+    v8 = this->vPartyPos.z;
+    this->vPartyPos.x = pParty->vPosition.x;
     v9 = pParty->vPosition.y;
-    v10 = v3->vPartyPos.x;
-    v3->vPartyPos.y = pParty->vPosition.y;
-    v3->uPartySectorID = pIndoor->GetSector(v10, v9, v8);
+    v10 = this->vPartyPos.x;
+    this->vPartyPos.y = pParty->vPosition.y;
+    this->uPartySectorID = pIndoor->GetSector(v10, v9, v8);
   }
   if ( pRenderer->pRenderD3D )
   {
-    v3->sCosineY = stru_5C6E00->Cos(v3->sPartyRotY);
-    v3->sSineY = stru_5C6E00->Sin(v3->sPartyRotY);
-    v3->sCosineNegX = stru_5C6E00->Cos(-v3->sPartyRotX);
-    v3->sSineNegX = stru_5C6E00->Sin(-v3->sPartyRotX);
-    v3->fCosineY = cos((3.141592653589793 + 3.141592653589793) * (double)v3->sPartyRotY * 0.00048828125);
-    v3->fSineY = sin((3.141592653589793 + 3.141592653589793) * (double)v3->sPartyRotY * 0.00048828125);
-    v3->fCosineNegX = cos((3.141592653589793 + 3.141592653589793) * (double)-v3->sPartyRotX * 0.00048828125);
-    v3->fSineNegX = sin((3.141592653589793 + 3.141592653589793) * (double)-v3->sPartyRotX * 0.00048828125);
-    v3->field_64 = a2->field_3C;
-    v11 = v3->uViewportW;
-    v12 = v3->uViewportX;
-    v13 = v3->uViewportZ - v12;
-    v14 = v3->uViewportZ + v12;
-    v3->field_70 = v13 + 1;
-    v15 = v3->uViewportY;
-    v3->uViewportHeight = v11 - v15 + 1;
-    v16 = v3->uViewportW;
-    v3->uViewportCenterX = v14 >> 1;
-    v3->uViewportCenterY = (signed int)(v16 + v15) >> 1;
+    this->sCosineY = stru_5C6E00->Cos(this->sPartyRotY);
+    this->sSineY = stru_5C6E00->Sin(this->sPartyRotY);
+    this->sCosineNegX = stru_5C6E00->Cos(-this->sPartyRotX);
+    this->sSineNegX = stru_5C6E00->Sin(-this->sPartyRotX);
+    this->fCosineY = cos((3.141592653589793 + 3.141592653589793) * (double)this->sPartyRotY * 0.00048828125);
+    this->fSineY = sin((3.141592653589793 + 3.141592653589793) * (double)this->sPartyRotY * 0.00048828125);
+    this->fCosineNegX = cos((3.141592653589793 + 3.141592653589793) * (double)-this->sPartyRotX * 0.00048828125);
+    this->fSineNegX = sin((3.141592653589793 + 3.141592653589793) * (double)-this->sPartyRotX * 0.00048828125);
+    this->field_64 = a2->field_3C;
+    v11 = this->uViewportW;
+    v12 = this->uViewportX;
+    v13 = this->uViewportZ - v12;
+    v14 = this->uViewportZ + v12;
+    this->field_70 = v13 + 1;
+    v15 = this->uViewportY;
+    this->uViewportHeight = v11 - v15 + 1;
+    v16 = this->uViewportW;
+    this->uViewportCenterX = v14 >> 1;
+    this->uViewportCenterY = (signed int)(v16 + v15) >> 1;
   }
   else
   {
-    v3->sCosineY = stru_5C6E00->Cos(-v3->sPartyRotY);
-    v3->sSineY = stru_5C6E00->Sin(-v3->sPartyRotY);
-    v3->sCosineNegX = stru_5C6E00->Cos(-v3->sPartyRotX);
-    v3->sSineNegX = stru_5C6E00->Sin(-v3->sPartyRotX);
-    v17 = cos((double)-v3->sPartyRotY * 0.0030664064);
-    v18 = v3->sPartyRotY;
-    v3->fCosineY = v17;
+    this->sCosineY = stru_5C6E00->Cos(-this->sPartyRotY);
+    this->sSineY = stru_5C6E00->Sin(-this->sPartyRotY);
+    this->sCosineNegX = stru_5C6E00->Cos(-this->sPartyRotX);
+    this->sSineNegX = stru_5C6E00->Sin(-this->sPartyRotX);
+    v17 = cos((double)-this->sPartyRotY * 0.0030664064);
+    v18 = this->sPartyRotY;
+    this->fCosineY = v17;
     v19 = sin((double)-v18 * 0.0030664064);
-    v20 = v3->sPartyRotX;
-    v3->fSineY = v19;
+    v20 = this->sPartyRotX;
+    this->fSineY = v19;
     v21 = cos((double)-v20 * 0.0030664064);
-    v22 = v3->sPartyRotX;
-    v3->fCosineNegX = v21;
-    v3->fSineNegX = sin((double)-v22 * 0.0030664064);
-    v23 = v3->uViewportX;
-    v3->field_64 = a2->field_3C;
-    v24 = v3->uViewportZ;
-    v3->field_70 = v3->uViewportZ - v23 + 1;
-    v25 = v3->uViewportW - v3->uViewportY + 1;
-    v3->uViewportHeight = v25;
+    v22 = this->sPartyRotX;
+    this->fCosineNegX = v21;
+    this->fSineNegX = sin((double)-v22 * 0.0030664064);
+    v23 = this->uViewportX;
+    this->field_64 = a2->field_3C;
+    v24 = this->uViewportZ;
+    this->field_70 = this->uViewportZ - v23 + 1;
+    v25 = this->uViewportW - this->uViewportY + 1;
+    this->uViewportHeight = v25;
     v29 = v25;
-    v26 = v3->field_64;
-    v3->uViewportCenterX = (signed int)(v24 + v23) >> 1;
-    v3->uViewportCenterY = v3->uViewportW - ((unsigned __int64)(v26 * (signed __int64)v29) >> 16);
+    v26 = this->field_64;
+    this->uViewportCenterX = (signed int)(v24 + v23) >> 1;
+    this->uViewportCenterY = this->uViewportW - ((unsigned __int64)(v26 * (signed __int64)v29) >> 16);
   }
-  v27 = (unsigned int)(signed __int64)((double)v3->field_70 * 0.5 / tan((double)(v2->field_1C_mb_fov >> 1) * 0.01745329)
+  v27 = (unsigned int)(signed __int64)((double)this->field_70 * 0.5 / tan((double)(v2->field_1C_mb_fov >> 1) * 0.01745329)
                                      + 0.5) << 16;
-  v3->field_40 = v27;
-  LODWORD(v3->field_44) = 4294967296i64 / v27;
-  v3->pRenderTarget = v2->pRenderTarget;
-  v3->uTargetWidth = v2->uTargetWidth;
-  v3->uTargetHeight = v2->uTargetHeight;
-  v3->uViewportX = v2->uViewportX;
-  v3->uViewportY = v2->uViewportY;
-  v3->uViewportZ = v2->uViewportZ;
-  v3->uViewportW = v2->uViewportW;
-  v3->pTargetZBuffer = v2->pTargetZ;
+  this->field_40 = v27;
+  this->field_44 = 0x100000000i64 / v27;
+  this->pRenderTarget = v2->pRenderTarget;
+  this->uTargetWidth = v2->uTargetWidth;
+  this->uTargetHeight = v2->uTargetHeight;
+  this->uViewportX = v2->uViewportX;
+  this->uViewportY = v2->uViewportY;
+  this->uViewportZ = v2->uViewportZ;
+  this->uViewportW = v2->uViewportW;
+  this->pTargetZBuffer = v2->pTargetZ;
   result = 0;
-  v3->field_8C = 0;
-  v3->field_84 = 0;
-  v3->uNumFacesRenderedThisFrame = 0;
-  v3->field_88 = 0;
+  this->field_8C = 0;
+  this->field_84 = 0;
+  this->uNumFacesRenderedThisFrame = 0;
+  this->field_88 = 0;
   pBLVRenderParams->field_90 = 64;
   pBLVRenderParams->field_94 = 6;
   return result;
@@ -395,36 +412,36 @@
 }
 
 //----- (004C0EF2) --------------------------------------------------------
-void BLVFace::FromODM(ODMFace *a2)
+void BLVFace::FromODM(ODMFace *face)
 {
-  this->pFacePlane_old.vNormal.x = a2->pFacePlane.vNormal.x;
-  this->pFacePlane_old.vNormal.y = a2->pFacePlane.vNormal.y;
-  this->pFacePlane_old.vNormal.z = a2->pFacePlane.vNormal.z;
-  this->pFacePlane_old.dist = a2->pFacePlane.dist;
-  this->pFacePlane.vNormal.x = (double)(a2->pFacePlane.vNormal.x & 0xFFFF) * 0.000015259022
-                             + (double)(a2->pFacePlane.vNormal.x >> 16);
-  this->pFacePlane.vNormal.y = (double)(a2->pFacePlane.vNormal.y & 0xFFFF) * 0.000015259022
-                             + (double)(a2->pFacePlane.vNormal.y >> 16);
-  this->pFacePlane.vNormal.z = (double)(a2->pFacePlane.vNormal.z & 0xFFFF) * 0.000015259022
-                             + (double)(a2->pFacePlane.vNormal.z >> 16);
-  this->pFacePlane.dist = (double)(a2->pFacePlane.dist & 0xFFFF) * 0.000015259022 + (double)(a2->pFacePlane.dist >> 16);
-  this->uAttributes = a2->uAttributes;
-  this->pBounding.x1 = a2->pBoundingBox.x1;
-  this->pBounding.y1 = a2->pBoundingBox.y1;
-  this->pBounding.z1 = a2->pBoundingBox.z1;
-  this->pBounding.x2 = a2->pBoundingBox.x2;
-  this->pBounding.y2 = a2->pBoundingBox.y2;
-  this->pBounding.z2 = a2->pBoundingBox.z2;
-  this->zCalc1 = a2->zCalc1;
-  this->zCalc2 = a2->zCalc2;
-  this->zCalc3 = a2->zCalc3;
-  this->pXInterceptDisplacements = a2->pXInterceptDisplacements;
-  this->pYInterceptDisplacements = a2->pYInterceptDisplacements;
-  this->pZInterceptDisplacements = a2->pZInterceptDisplacements;
-  this->uPolygonType = (PolygonType)a2->uPolygonType;
-  this->uNumVertices = a2->uNumVertices;
-  this->uBitmapID = a2->uTextureID;
-  this->pVertexIDs = a2->pVertexIDs;
+  this->pFacePlane_old.vNormal.x = face->pFacePlane.vNormal.x;
+  this->pFacePlane_old.vNormal.y = face->pFacePlane.vNormal.y;
+  this->pFacePlane_old.vNormal.z = face->pFacePlane.vNormal.z;
+  this->pFacePlane_old.dist = face->pFacePlane.dist;
+  this->pFacePlane.vNormal.x = (double)(face->pFacePlane.vNormal.x & 0xFFFF) * 0.000015259022
+                             + (double)(face->pFacePlane.vNormal.x >> 16);
+  this->pFacePlane.vNormal.y = (double)(face->pFacePlane.vNormal.y & 0xFFFF) * 0.000015259022
+                             + (double)(face->pFacePlane.vNormal.y >> 16);
+  this->pFacePlane.vNormal.z = (double)(face->pFacePlane.vNormal.z & 0xFFFF) * 0.000015259022
+                             + (double)(face->pFacePlane.vNormal.z >> 16);
+  this->pFacePlane.dist = (double)(face->pFacePlane.dist & 0xFFFF) * 0.000015259022 + (double)(face->pFacePlane.dist >> 16);
+  this->uAttributes = face->uAttributes;
+  this->pBounding.x1 = face->pBoundingBox.x1;
+  this->pBounding.y1 = face->pBoundingBox.y1;
+  this->pBounding.z1 = face->pBoundingBox.z1;
+  this->pBounding.x2 = face->pBoundingBox.x2;
+  this->pBounding.y2 = face->pBoundingBox.y2;
+  this->pBounding.z2 = face->pBoundingBox.z2;
+  this->zCalc1 = face->zCalc1;
+  this->zCalc2 = face->zCalc2;
+  this->zCalc3 = face->zCalc3;
+  this->pXInterceptDisplacements = face->pXInterceptDisplacements;
+  this->pYInterceptDisplacements = face->pYInterceptDisplacements;
+  this->pZInterceptDisplacements = face->pZInterceptDisplacements;
+  this->uPolygonType = (PolygonType)face->uPolygonType;
+  this->uNumVertices = face->uNumVertices;
+  this->uBitmapID = face->uTextureID;
+  this->pVertexIDs = face->pVertexIDs;
 }
 
 //----- (004B0A25) --------------------------------------------------------
@@ -510,7 +527,8 @@
                      static_vertices_F7B628, pGame->pIndoorCameraD3D->std__vector_000034_prolly_frustrum, 4, false, 0) != 1 || uNumVerticesa )
       {
         a4a = SHIWORD(stru_F8AD28.uCurrentAmbientLightLevel);
-        v17 = (248 - 8 * SHIWORD(stru_F8AD28.uCurrentAmbientLightLevel)) | (((248 - 8 * SHIWORD(stru_F8AD28.uCurrentAmbientLightLevel)) | ((248 - 8 * SHIWORD(stru_F8AD28.uCurrentAmbientLightLevel)) << 8)) << 8);
+        v17 = (248 - 8 * SHIWORD(stru_F8AD28.uCurrentAmbientLightLevel)) | (((248 - 8 * SHIWORD(stru_F8AD28.uCurrentAmbientLightLevel))
+            | ((248 - 8 * SHIWORD(stru_F8AD28.uCurrentAmbientLightLevel)) << 8)) << 8);
         sub_4B0E07(uFaceID);
         pGame->pLightmapBuilder->ApplyLights_IndoorFace(uFaceID);
         pDecalBuilder->ApplyBloodsplatDecals_IndoorFace(uFaceID);
@@ -1638,8 +1656,8 @@
   v1->ptr_0002B0_sector_rdata = 0;
   pAllocator->FreeChunk(v1->ptr_0002B8_sector_lrdata);
   v1->ptr_0002B8_sector_lrdata = 0;
-  pAllocator->FreeChunk(v1->ptr_2AC);
-  v1->ptr_2AC = 0;
+  pAllocator->FreeChunk(v1->pLFaces);
+  v1->pLFaces = 0;
   pAllocator->FreeChunk(v1->pSpawnPoints);
   v3 = v1->pVertices;
   v1->pSpawnPoints = 0;
@@ -2435,30 +2453,30 @@
   pGameLoadingUI_ProgressBar->Progress();
 
   memcpy(pFaces, pData += 4, uNumFaces * sizeof (BLVFace));
-  ptr_2AC = (unsigned __int16 *)pAllocator->AllocNamedChunk(ptr_2AC, blv.uFaces_fdata_Size, "L.FData");
-
-  memcpy(ptr_2AC, pData += uNumFaces * sizeof (BLVFace), blv.uFaces_fdata_Size);
+  pLFaces = (unsigned __int16 *)pAllocator->AllocNamedChunk(pLFaces, blv.uFaces_fdata_Size, "L.FData");
+
+  memcpy(pLFaces, pData += uNumFaces * sizeof (BLVFace), blv.uFaces_fdata_Size);
 
   for (uint i = 0, j = 0; i < uNumFaces; ++i)
   {
     auto pFace = pFaces + i;
 
-    pFace->pVertexIDs = ptr_2AC + j;
+    pFace->pVertexIDs = pLFaces + j;
     
     j += pFace->uNumVertices + 1;
-    pFace->pXInterceptDisplacements = (short *)(ptr_2AC + j);
+    pFace->pXInterceptDisplacements = (short *)(pLFaces + j);
 
     j += pFace->uNumVertices + 1;
-    pFace->pYInterceptDisplacements = (short *)(ptr_2AC + j);
+    pFace->pYInterceptDisplacements = (short *)(pLFaces + j);
 
     j += pFace->uNumVertices + 1;
-    pFace->pZInterceptDisplacements = (short *)(ptr_2AC + j);
+    pFace->pZInterceptDisplacements = (short *)(pLFaces + j);
 
     j += pFace->uNumVertices + 1;
-    pFace->pVertexUIDs = (__int16 *)(ptr_2AC + j);
+    pFace->pVertexUIDs = (__int16 *)(pLFaces + j);
 
     j += pFace->uNumVertices + 1;
-    pFace->pVertexVIDs = (__int16 *)(ptr_2AC + j);
+    pFace->pVertexVIDs = (__int16 *)(pLFaces + j);
 
     j += pFace->uNumVertices + 1;
       /*v93 = &pFaces[v92];
--- a/Indoor.h	Tue May 21 11:24:26 2013 +0200
+++ b/Indoor.h	Tue May 21 11:24:35 2013 +0200
@@ -1,6 +1,5 @@
 #pragma once
 #include "VectorTypes.h"
-#include "IndoorCameraD3D.h"
 #include "Weather.h"
 
 
@@ -283,7 +282,7 @@
 
   char _get_normals(Vec3_int_ *a2, Vec3_int_ *a3);
   struct Texture *GetTexture();
-  void FromODM(struct ODMFace *a2);
+  void FromODM(struct ODMFace *face);
 
   inline bool Invisible() const {return uAttributes & FACE_INVISIBLE;}
   inline bool Visible() const   {return !Invisible();}
@@ -417,7 +416,7 @@
     ptr_0002B8_sector_lrdata = 0;
     ptr_0002B4_doors_ddata = 0;
     ptr_0002B0_sector_rdata = 0;
-    ptr_2AC = 0;
+    pLFaces = 0;
     pVertices = 0;
     pFaces = 0;
     pFaceExtras = 0;
@@ -462,7 +461,7 @@
   unsigned int uNumNodes;
   struct BSPNode *pNodes;
   BLVMapOutlines *pMapOutlines;
-  unsigned __int16 *ptr_2AC;
+  unsigned __int16 *pLFaces;
   unsigned __int16 *ptr_0002B0_sector_rdata;
   unsigned __int16 *ptr_0002B4_doors_ddata;
   unsigned __int16 *ptr_0002B8_sector_lrdata;
@@ -546,7 +545,7 @@
   float fCosineNegX;
   float fSineNegX;
   int field_40;
-  float field_44;
+  int field_44;//float
   unsigned __int16 *pRenderTarget;
   unsigned int uTargetWidth;
   unsigned int uTargetHeight;
--- a/IndoorCameraD3D.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/IndoorCameraD3D.cpp	Tue May 21 11:24:35 2013 +0200
@@ -9,6 +9,8 @@
 #include "LOD.h"
 #include "mm7_data.h"
 
+#include "stru9.h"
+
 //----- (004361EF) --------------------------------------------------------
 IndoorCameraD3D::IndoorCameraD3D()
 {
--- a/Indoor_stuff.h	Tue May 21 11:24:26 2013 +0200
+++ b/Indoor_stuff.h	Tue May 21 11:24:35 2013 +0200
@@ -1,6 +1,6 @@
 #pragma once
 #include "Render.h"
-
+#include "IndoorCameraD3D.h"
 
 
 
--- a/Items.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/Items.cpp	Tue May 21 11:24:35 2013 +0200
@@ -3,7 +3,6 @@
 
 #include "Items.h"
 #include "MapInfo.h"
-#include "FrameTableInc.h"
 #include "Allocator.h"
 #include "GUIWindow.h"
 #include "Events2D.h"
@@ -914,7 +913,7 @@
 				break;
 		}
 
-	//ChanceByTreasureLvl Summ - anti cheating?
+	//ChanceByTreasureLvl Summ - to calculate chance
 	memset(&uChanceByTreasureLvlSumm, 0, 24);
 	for(i=0;i<6;++i)
 		{
--- a/Items.h	Tue May 21 11:24:26 2013 +0200
+++ b/Items.h	Tue May 21 11:24:35 2013 +0200
@@ -124,10 +124,10 @@
 struct ItemGen //0x24
 {
   //----- (0042EB25) --------------------------------------------------------
-  inline ItemGen()
-  {
-    Reset();
-  }
+ // inline ItemGen()
+ // {
+ //   Reset();
+ // }
 
   inline bool Broken()        {return uAttributes & ITEM_BROKEN;}
   inline bool Identified()    {return uAttributes & ITEM_IDENTIFIED;}
@@ -145,10 +145,10 @@
 
 
 
-  int uItemID;
-  int uEnchantmentType;
-  int _bonus_strength;
-  int uSpecEnchantmentType; // 25  +5 levels
+  int uItemID; //0
+  int uEnchantmentType; //4
+  int _bonus_strength;  //8
+  int uSpecEnchantmentType; // 25  +5 levels //0c
                             // 16  Drain Hit Points from target.
                             // 39  Double damage vs Demons.
                             // 40  Double damage vs Dragons
@@ -165,8 +165,8 @@
                             // 68  Adds 6-8 points of Cold damage and +5 Armor Class.
                             // 71  Prevents drowning damage.
                             // 72  Prevents falling damage.
-  int uNumCharges;
-  unsigned int uAttributes;
+  int uNumCharges; //10
+  unsigned int uAttributes;  //14
   unsigned __int8 uBodyAnchor;
   char uMaxCharges;
   char uHolderPlayer;
--- a/LOD.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/LOD.cpp	Tue May 21 11:24:35 2013 +0200
@@ -3,10 +3,10 @@
 #include "Allocator.h"
 #include "PaletteManager.h"
 #include "Viewport.h"
-#include "Log.h"
 
 #include "mm7_data.h"
 
+#include "Sprites.h"
 
 
 
@@ -1236,20 +1236,20 @@
 }
 
 //----- (0040F9C5) --------------------------------------------------------
-int LODFile_IconsBitmaps::_40F9C5()
-{
-  signed int result; // eax@1
+void LODFile_IconsBitmaps::SyncLoadedFilesCount()
+    {
+  signed int loaded_files; // eax@1
   Texture *pTex; // edx@1
 
-  result = this->uNumLoadedFiles;
-  for ( pTex = &this->pTextures[result]; !pTex->pName[0]; --pTex )
-    --result;
-  if ( result < (signed int)this->uNumLoadedFiles )
+  loaded_files = this->uNumLoadedFiles;
+  for ( pTex = &this->pTextures[loaded_files]; !pTex->pName[0]; --pTex )
+    --loaded_files;
+  if ( loaded_files < (signed int)this->uNumLoadedFiles )
   {
-    ++result;
-    this->uNumLoadedFiles = result;
+    ++loaded_files;
+    this->uNumLoadedFiles = loaded_files;
   }
-  return result;
+ 
 }
 
 
--- a/LOD.h	Tue May 21 11:24:26 2013 +0200
+++ b/LOD.h	Tue May 21 11:24:35 2013 +0200
@@ -143,7 +143,7 @@
 {
   LODFile_IconsBitmaps();
   virtual ~LODFile_IconsBitmaps();
-  int _40F9C5();
+  void SyncLoadedFilesCount();
   unsigned int FindTextureByName(const char *pName);
   bool LoadBitmaps(const char *pFilename);
   bool LoadIconsOrEvents(const char *pLODFilename);
--- a/LightmapBuilder.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/LightmapBuilder.cpp	Tue May 21 11:24:35 2013 +0200
@@ -4,10 +4,13 @@
 #include "Outdoor.h"
 #include "Log.h"
 
+#include "OutdoorCamera.h"
+
 #include "mm7_data.h"
 
 
 
+#include "stru9.h"
 
 
 
--- a/MM7.h	Tue May 21 11:24:26 2013 +0200
+++ b/MM7.h	Tue May 21 11:24:35 2013 +0200
@@ -1,5 +1,4 @@
 #pragma once
-#include "OSAPI.h"
 #include <math.h>
 #include <stdio.h>
 #include <stdarg.h>
--- a/MapInfo.h	Tue May 21 11:24:26 2013 +0200
+++ b/MapInfo.h	Tue May 21 11:24:35 2013 +0200
@@ -98,6 +98,7 @@
 extern struct MapStats *pMapStats;
 
 
+extern MapStartPoint uLevel_StartingPointType; // weak
 
 
 void TeleportToStartingPoint(MapStartPoint point); // idb
--- a/Mouse.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/Mouse.cpp	Tue May 21 11:24:35 2013 +0200
@@ -1,13 +1,14 @@
 #include "OSAPI.h"
 
+#include "VideoPlayer.h"
+#include "Vis.h"
 #include "Mouse.h"
 #include "Items.h"
 #include "Party.h"
 #include "LOD.h"
 #include "Game.h"
-#include "Texture.h"
 
-
+#include "stru11.h"
 
 
 
@@ -95,7 +96,7 @@
     {
       if (uCursorTextureID != -1)
         pIcons_LOD->pTextures[uCursorTextureID].Release();
-      pIcons_LOD->_40F9C5();
+      pIcons_LOD->SyncLoadedFilesCount();
     }
     return;
   }
--- a/NPC.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/NPC.cpp	Tue May 21 11:24:35 2013 +0200
@@ -1,14 +1,13 @@
-#include <string.h>
-#include <stdlib.h>
+
 
 #include "Allocator.h"
 #include "texts.h"
-#include "Party.h"
 #include "LOD.h"
 #include "Autonotes.h"
 #include "Awards.h"
 #include "mm7_data.h"
 #include "MM7.h"
+#include "Party.h"
 #include "NPC.h"
 
 int pDialogueNPCCount;
--- a/Outdoor.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/Outdoor.cpp	Tue May 21 11:24:35 2013 +0200
@@ -1,18 +1,19 @@
 #include <assert.h>
 
+#include "stru6.h"
+
+#include "Sprites.h"
+#include "LightmapBuilder.h"
 #include "Outdoor.h"
 #include "Party.h"
 #include "SpriteObject.h"
 #include "LOD.h"
-#include "Render.h"
 #include "Allocator.h"
-#include "Weather.h"
 #include "PaletteManager.h"
 #include "GUIProgressBar.h"
 #include "AudioPlayer.h"
 #include "IndoorCamera.h"
 #include "DecorationList.h"
-#include "TileFrameTable.h"
 #include "Math.h"
 #include "ObjectList.h"
 #include "Game.h"
@@ -27,8 +28,9 @@
 #include "MM7.h"
 
 
-
-
+#include "MapInfo.h"
+#include "OutdoorCamera.h"
+#include "BSPModel.h"
 
 MapStartPoint uLevel_StartingPointType; // weak
 
--- a/Outdoor.h	Tue May 21 11:24:26 2013 +0200
+++ b/Outdoor.h	Tue May 21 11:24:35 2013 +0200
@@ -1,12 +1,9 @@
 #pragma
-#include "BSPModel.h"
-#include "OutdoorCamera.h"
+
 #include "Indoor.h"
 #include "TileFrameTable.h"
-#include "MapInfo.h"
 #include "Weather.h"
 
-
 #define DAY_ATTRIB_FOG  1
 
 /*  256 */
@@ -268,8 +265,6 @@
 
 
 
-extern MapStartPoint uLevel_StartingPointType; // weak
-
 
 
 
--- a/ParticleEngine.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/ParticleEngine.cpp	Tue May 21 11:24:35 2013 +0200
@@ -8,6 +8,8 @@
 #include "Math.h"
 #include "LOD.h"
 
+#include "Sprites.h"
+#include "OutdoorCamera.h"
 #include "mm7_data.h"
 
 //----- (0048AAC5) --------------------------------------------------------
--- a/Party.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/Party.cpp	Tue May 21 11:24:35 2013 +0200
@@ -331,9 +331,9 @@
   memset(pHirelings, 0, 2 * sizeof(*pHirelings));
 
   strcpy(this->pPlayers[0].pName, pGlobalTXT_LocalizationStrings[509]); //Zoltan
-  pParty->pPlayers[0].field_1928 = 17;
-  pParty->pPlayers[0].uFace = 17;
-  pParty->pPlayers[0].field_1924 = 17;
+  pParty->pPlayers[0].uPrevFace = 17;
+  pParty->pPlayers[0].uCurrentFace = 17;
+  pParty->pPlayers[0].uPrevVoiceID = 17;
   pParty->pPlayers[0].uVoiceID = 17;
   pParty->pPlayers[0].uMight = 30;
   pParty->pPlayers[0].uIntelligence = 5;
@@ -346,9 +346,9 @@
   pParty->pPlayers[0].pActiveSkills[PLAYER_SKILL_ARMSMASTER] = 1;        // armsmaster
   pParty->pPlayers[0].pActiveSkills[PLAYER_SKILL_BOW] = 1;         // bow
   pParty->pPlayers[0].pActiveSkills[PLAYER_SKILL_SWORD] = 1;         // sword
-  pParty->pPlayers[1].field_1928 = 3;
-  pParty->pPlayers[1].uFace = 3;
-  pParty->pPlayers[1].field_1924 = 3;
+  pParty->pPlayers[1].uPrevFace = 3;
+  pParty->pPlayers[1].uCurrentFace = 3;
+  pParty->pPlayers[1].uPrevVoiceID = 3;
   pParty->pPlayers[1].uVoiceID = 3;
   strcpy(pParty->pPlayers[1].pName, pGlobalTXT_LocalizationStrings[506]); //Roderic
   pParty->pPlayers[1].uMight = 13;
@@ -362,9 +362,9 @@
   pParty->pPlayers[1].pActiveSkills[PLAYER_SKILL_STEALING] = 1;        // stealing
   pParty->pPlayers[1].pActiveSkills[PLAYER_SKILL_DAGGER] = 1;         // dagger
   pParty->pPlayers[1].pActiveSkills[PLAYER_SKILL_TRAP_DISARM] = 1;        // disarm trap
-  pParty->pPlayers[2].field_1928 = 14;
-  pParty->pPlayers[2].uFace = 14;
-  pParty->pPlayers[2].field_1924 = 14;
+  pParty->pPlayers[2].uPrevFace = 14;
+  pParty->pPlayers[2].uCurrentFace = 14;
+  pParty->pPlayers[2].uPrevVoiceID = 14;
   pParty->pPlayers[2].uVoiceID = 14;
   strcpy(pParty->pPlayers[2].pName, pGlobalTXT_LocalizationStrings[508]); // Serena
   pParty->pPlayers[2].uMight = 12;
@@ -380,13 +380,13 @@
   pParty->pPlayers[2].pActiveSkills[PLAYER_SKILL_MACE] = 1;         // mace
   strcpy(pParty->pPlayers[3].pName, pGlobalTXT_LocalizationStrings[507]); // Alexis
   v3 = 10;
-  pParty->pPlayers[3].field_1928 = 10;
-  pParty->pPlayers[3].uFace = 10;
+  pParty->pPlayers[3].uPrevFace = 10;
+  pParty->pPlayers[3].uCurrentFace = 10;
   //pResMagicBase = (int)&pParty->pPlayers[0].sResMagicBase;
   pParty->pPlayers[3].uEndurance = 13;
   pParty->pPlayers[3].uAccuracy = 13;
   pParty->pPlayers[3].uSpeed = 13;
-  pParty->pPlayers[3].field_1924 = 10;
+  pParty->pPlayers[3].uPrevVoiceID = 10;
   pParty->pPlayers[3].uVoiceID = 10;
   pParty->pPlayers[3].uMight = 5;
   pParty->pPlayers[3].uIntelligence = 30;
@@ -600,8 +600,8 @@
   pPlayers[1].Reset(PLAYER_CLASS_THEIF);
   pPlayers[2].Reset(PLAYER_CLASS_CLERIC);
   pPlayers[3].Reset(PLAYER_CLASS_SORCERER);
-  pPlayers[0].uFace = 17;
-  pPlayers[0].field_1924 = 17;
+  pPlayers[0].uCurrentFace = 17;
+  pPlayers[0].uPrevVoiceID = 17;
   pPlayers[0].uVoiceID = 17;
   pPlayers[0].SetInitialStats();
  
@@ -642,8 +642,8 @@
   strcpy(pPlayers[0].pName, pGlobalTXT_LocalizationStrings[509]);
 
 
-  pPlayers[1].uFace = 3;
-  pPlayers[1].field_1924 = 3;
+  pPlayers[1].uCurrentFace = 3;
+  pPlayers[1].uPrevVoiceID = 3;
   pPlayers[1].uVoiceID = 3;
   pPlayers[1].SetInitialStats();
   v7 = SEX_MALE;
@@ -683,8 +683,8 @@
   pPlayers[1].uSex = v7;
   pPlayers[1].RandomizeName();
   strcpy(pPlayers[1].pName, pGlobalTXT_LocalizationStrings[506]);
-  pPlayers[2].uFace = 14;
-  pPlayers[2].field_1924 = 14;
+  pPlayers[2].uCurrentFace = 14;
+  pPlayers[2].uPrevVoiceID = 14;
   pPlayers[2].uVoiceID = 14;
   pPlayers[2].SetInitialStats();
   v8 = SEX_MALE;
@@ -724,8 +724,8 @@
   pPlayers[2].uSex = v8;
   pPlayers[2].RandomizeName();
   strcpy(pPlayers[2].pName, pGlobalTXT_LocalizationStrings[508]);
-  pPlayers[3].uFace = 10;
-  pPlayers[3].field_1924 = 10;
+  pPlayers[3].uCurrentFace = 10;
+  pPlayers[3].uPrevVoiceID = 10;
   pPlayers[3].uVoiceID = 10;
   pPlayers[3].SetInitialStats();
   v9 = SEX_MALE;
--- a/Player.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/Player.cpp	Tue May 21 11:24:35 2013 +0200
@@ -1,14 +1,15 @@
 #include <assert.h>
 
+#include "stru6.h"
+
+
 #include "OSAPI.h"
 #include "Player.h"
 #include "PlayerFrameTable.h"
-#include "Texture.h"
 #include "AudioPlayer.h"
 #include "Party.h"
 #include "Log.h"
 #include "LOD.h"
-#include "Monsters.h" 
 #include "GUIWindow.h"
 #include "Viewport.h"
 #include "Actor.h"
@@ -112,6 +113,8 @@
 signed int player_stat_bonuses[30] = {30, 25, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5, -6, 0};
 
 
+unsigned char pEquipTypeToBodyAnchor[20] = {1, 1, 2, 3, 0, 4, 5, 6, 7, 8, 10, 9, 1, 0, 0, 0, 0, 0, 0, 0};
+
 
 unsigned short base_recovery_times_per_weapon_type[12] =
 {
@@ -220,27 +223,21 @@
 
 
 //----- (004BE2DD) --------------------------------------------------------
-void Player::SalesProcess(unsigned int a2, int a3, int _2devent_idx)
-{
-  Player *v4; // edi@1
-  char *v5; // esi@1
+void Player::SalesProcess( unsigned int inventory_idnx, int item_index, int _2devent_idx )
+    {
   float v6; // ST04_4@1
-  signed int v7; // eax@1
-  signed int v8; // ebx@1
-
-  auto a4 = _2devent_idx;
-  v4 = this;
-  v5 = (char *)this + 36 * a3;
-  v6 = p2DEvents[a4 - 1].fPriceMultiplier;
-  //v6 = p2DEvents_minus1__20[13 * a4];
-  v7 = ((ItemGen *)(v5 + 532))->GetValue();
-  v8 = GetPriceSell(v7, v6);
-  if ( v5[552] & 2 )
-    v8 = 1;
-  if ( v8 < 1 )
-    v8 = 1;
-  RemoveItemAtInventoryIndex(a2);
-  Party::SetGold(pParty->uNumGold + v8);
+  signed int item_value; // eax@1
+  signed int sell_price; // ebx@1
+
+  item_value =pOwnItems[item_index].GetValue();
+  v6 = p2DEvents[ _2devent_idx - 1].fPriceMultiplier;
+  sell_price = GetPriceSell(item_value, v6);
+  if ( pOwnItems[item_index].Broken() )
+    sell_price = 1;
+  if ( sell_price < 1 )
+    sell_price = 1;
+  RemoveItemAtInventoryIndex(inventory_idnx);
+  Party::SetGold(pParty->uNumGold + sell_price);
 }
 
 
@@ -248,35 +245,21 @@
 //----- (0043EEF3) --------------------------------------------------------
 bool Player::_43EEF3()
 {
-  signed int v1; // esi@1
-  PlayerEquipment *v2; // edx@1
-  bool result; // eax@2
-
-  v1 = 0;
-  v2 = &this->pEquipment;
-  while ( 1 )
-  {
-    result = v2->uShield;
-    if ( v2->uShield )
-    {
-      result = *(int *)&this->pInventoryItems[result-1];
-      if ( result )
+  signed int item_idx; // esi@1
+  signed int item_id; // esi@1
+  for (int i=0; i<16;++i)
       {
-        if ( result != 64 && result != 65 )
-          break;
+     item_idx=pEquipment.pIndices[i];
+     if (item_idx)
+         {
+         item_id=pOwnItems[item_idx-1].uItemID;
+         if (item_id!=64 &&  item_id!= 65 ) //blaster& blaster rifle
+             return false;
+         }
       }
-    }
-    ++v1;
-    v2 = (PlayerEquipment *)((char *)v2 + 4);
-    if ( v1 >= 16 )
-    {
-      LOBYTE(result) = 1;
-      return result;
-    }
-  }
-  LOBYTE(result) = 0;
-  return result;
-}
+      return true;
+  }
+  
 
 
 
@@ -456,7 +439,7 @@
 
   v1 = this;
   v2 = (signed int)window_SpeakInHouse->ptr_1C;
-  if ( v2 == 78 || v2 > 80 && v2 <= 82 )
+  if ( (v2 == 78 || v2 > 80) && v2 <= 82 )
   {
     if ( GetMajorConditionIdx() == 18 )
       goto LABEL_6;
@@ -477,97 +460,66 @@
 
 
 //----- (00421E75) --------------------------------------------------------
-unsigned int Player::GetItemIDAtInventoryIndex(int *a2)
-{
-  int v2; // eax@1
-  unsigned int result; // eax@3
-
-  v2 = *a2;
-  if ( *a2 >= 126 || v2 < 0 )
-  {
-    result = 0;
-  }
-  else
-  {
-    result = this->pInventoryIndices[v2];
-    if ( (result & 0x80000000u) != 0 )
-    {
-      *a2 = -1 - result;
-      result = this->pInventoryIndices[-1 - result];
-    }
-  }
-  return result;
+unsigned int Player::GetItemIDAtInventoryIndex(int *pitem_index)
+{
+  int item_idx; // eax@1
+  int inv_index; // eax@3
+
+  item_idx = *pitem_index;
+  if ( item_idx >125 || item_idx < 0 )
+  {
+    return 0;
+  }
+  
+    inv_index = this->pInventoryIndices[item_idx];
+    if ( inv_index < 0 )
+    {
+      *pitem_index = -1 - inv_index;
+      inv_index = this->pInventoryIndices[-1 - inv_index];
+    }
+
+  return inv_index;
 }
 
 
 
 //----- (004160CA) --------------------------------------------------------
-char Player::_4160CA(int a2)
-{
-  Player *v2; // esi@1
-  signed int v3; // edx@1
-  signed int v4; // ebx@1
-  ItemGen *v5; // eax@1
-  int v6; // edi@2
-  signed int i; // edx@8
-  ItemGen **v8; // ecx@9
-  __int16 v10[137]; // [sp+Ch] [bp-118h]@1
-  __int16 v11; // [sp+11Eh] [bp-6h]@1
-  int v12; // [sp+120h] [bp-4h]@1
-
-  auto a1 = this;
-
-  v12 = a2;
-  v2 = a1;
-  v3 = 0;
-  v10[0] = 0;
-  v4 = 0;
-  memset(&v10[1], 0, 0x110u);
-  v11 = 0;
-  v5 = a1->pInventoryItems;
-  do
-  {
-    v6 = 0;
-    if ( (signed int)v5->uItemID > 0 && (signed int)v5->uItemID <= 134 )
-      v10[v4++] = v3;
-    ++v3;
-    ++v5;
-  }
-  while ( v3 < 138 );
-  if ( v4 )
-  {
-    if ( v12 )
-    {
-      if ( v12 > 0 )
+void Player::ItemsEnchant( int enchant_count )
+    {
+  int avalible_items; // ebx@1
+  int i; // edx@8
+  __int16 item_index_tabl[138]; // [sp+Ch] [bp-118h]@1
+ 
+  avalible_items = 0;
+  memset (item_index_tabl,0,sizeof(item_index_tabl));
+
+  for (i=0; i<138; ++i)
       {
-        do
+       if (( pOwnItems[i].uItemID>0)&&(pOwnItems[i].uItemID<= 134))
+           item_index_tabl[avalible_items++] = i;
+      }
+
+  if ( avalible_items )
+  {
+    if ( enchant_count )
+    {
+    for ( i = 0; i < enchant_count; ++i )
         {
-          LOWORD(v5) = 9 * v10[v6];
-          if ( !(BYTE1(v2->pInventoryItems[v10[v6]].uAttributes) & 2) )
-          {
-            v5 = (ItemGen *)((char *)&v2->pInventoryItems[v10[rand() % v4]] + 20);
-            v5->uItemID |= 2u;
-          }
-          ++v6;
+        if (!(pInventoryItems[item_index_tabl[i]].uAttributes&ITEM_ENCHANTED))
+                pInventoryItems[item_index_tabl[rand() % avalible_items]].uAttributes|=ITEM_ENCHANTED; 
         }
-        while ( v6 < v12 );
-      }
+       
     }
     else
     {
-      for ( i = 0; i < v4; ++i )
+      for ( i = 0; i < avalible_items; ++i )
       {
-        v8 = (ItemGen **)&v2->pInventoryItems[v10[i]].uAttributes;
-        v5 = *v8;
-        if ( !(BYTE1(v5) & 2) )
-        {
-          LOBYTE(v5) = (unsigned __int8)v5 | 2;
-          *v8 = v5;
-        }
+        if (!(pInventoryItems[item_index_tabl[i]].uAttributes&ITEM_ENCHANTED))
+                pInventoryItems[item_index_tabl[i]].uAttributes|=ITEM_ENCHANTED;
       }
     }
   }
-  return (char)v5;
+ ;
 }
 
 //----- (004948B1) --------------------------------------------------------
@@ -698,7 +650,7 @@
       {
         if ( v3 > 11 )
         {
-          if ( v3 == CHARACTER_EXPRESSION_PERTIFIED || v3 > 97 && v3 <= 99 )
+          if ( v3 == CHARACTER_EXPRESSION_PERTIFIED ||( v3 > 97 && v3 <= 99) )
             return;
           goto LABEL_15;
         }
@@ -1102,260 +1054,220 @@
 
 //----- (00492D65) --------------------------------------------------------
 int Player::SetCondition(unsigned int uConditionIdx, int a3)
-{
-  Player *v3; // esi@1
-  Player **v4; // ebx@2
-  Player *v5; // ecx@21
-  Player *v6; // ecx@22
-  Player *v7; // ecx@29
-  Player *v8; // ecx@30
-  Player *v9; // ecx@37
-  Player *v10; // ecx@38
-  Player *v11; // ecx@45
-  Player *v12; // ecx@46
-  char *v13; // eax@49
-  Player *v14; // ecx@58
-  Player *v15; // ecx@59
-  Player *v16; // ecx@60
-  signed int result; // eax@76
-  signed int v18; // ecx@77
-  int v19; // eax@77
-  char v20; // al@80
-  signed int v21; // ebx@82
-  signed int v22; // esi@82
-  int v23; // [sp-8h] [bp-1Ch]@7
-  int v24; // [sp-8h] [bp-1Ch]@15
-  int v25; // [sp-8h] [bp-1Ch]@53
-  int v26; // [sp-4h] [bp-18h]@7
-  signed int v27; // [sp-4h] [bp-18h]@15
-  int v28; // [sp-4h] [bp-18h]@53
-  char *v29; // [sp+Ch] [bp-8h]@1
-  int v30; // [sp+10h] [bp-4h]@2
-  int v31; // [sp+20h] [bp+Ch]@82
-
-  v3 = this;
-  v29 = (char *)this + 8 * uConditionIdx;
-  if ( *(_QWORD *)v29 )
-  {
-LABEL_76:
-    result = 0;
-  }
-  else
-  {
-    v4 = &pPlayers[1];
-    v30 = 0;
-    do
-    {
-      if ( (*v4)->CanAct() )
-        ++v30;
-      ++v4;
-    }
-    while ( (signed int)v4 <= (signed int)&pPlayers[4] );
+    {
+
+    signed int player_sex; // ecx@77
+    char zombi_face; // al@80
+    signed int remainig_player; // ebx@82
+    int players_before; // [sp+10h] [bp-4h]@2
+    int players_after; // [sp+20h] [bp+Ch]@82
+
+    if ( pConditions[uConditionIdx] )
+        return 0;
+    players_before = 0;
+    for (int i=1;i<5;++i)
+        if ( pPlayers[i]->CanAct() )
+            ++players_before;
+
     switch ( uConditionIdx )
-    {
-      case 0u:
-        v26 = 0;
-        v23 = 30;
-        goto LABEL_81;
-      case 1u:
+        {
+    case Condition_Cursed:
+        PlaySound((PlayerSpeech)30, 0);
+        break;
+    case Condition_Weak:
         if ( a3 == 1 && (signed __int64)pParty->pPartyBuffs[13].uExpireTime > 0 )
-          goto LABEL_10;
-        v26 = 0;
-        v23 = 25;
-        goto LABEL_81;
-      case 2u:
-        if ( a3 != 1 )
-          goto LABEL_82;
-        if ( v3->HasEnchantedItemEquipped(22) )
-          goto LABEL_76;
-        v27 = 3;
-        v24 = 505;
-        goto LABEL_16;
-      case 3u:
-        v26 = 0;
-        v23 = 26;
-        goto LABEL_81;
-      case 4u:
-        v26 = 0;
-        v23 = 31;
-        goto LABEL_81;
-      case 5u:
+            {--pParty->pPartyBuffs[13].uPower;
+        if ( pParty->pPartyBuffs[13].uPower < 1u )
+            pParty->pPartyBuffs[13].Reset();
+        return 0;
+            }
+
+        PlaySound((PlayerSpeech)25, 0);
+        break;
+    case Condition_Sleep:
+        if ( a3 == 1 &&(HasEnchantedItemEquipped(22)||WearsItem(505, 3))) 
+            return 0;
+        break;
+
+    case Condition_Fear:
+        PlaySound((PlayerSpeech)26, 0);
+        break;
+    case Condition_Drunk:
+        PlaySound((PlayerSpeech)31, 0);
+        break;
+
+    case Condition_Insane:
         if ( a3 == 1
-          && (v3->HasEnchantedItemEquipped(19) || v5->WearsItem(505, 3) || v6->WearsItem(530, 6)) )
-          goto LABEL_76;
-        v26 = 0;
-        v23 = 29;
-        goto LABEL_81;
-      case 6u:
-      case 8u:
-      case 0xAu:
+            && (HasEnchantedItemEquipped(19) || WearsItem(505, 3) || WearsItem(530, 6)) )
+            return 0;
+
+        PlaySound((PlayerSpeech)29, 0);
+        break;
+    case Condition_Poison1:
+    case Condition_Poison2:
+    case Condition_Poison3:
+        if ( a3 == 1 )
+            {
+            if ( (signed __int64)pParty->pPartyBuffs[13].uExpireTime > 0i64 )
+                {
+                --pParty->pPartyBuffs[13].uPower;
+                if ( pParty->pPartyBuffs[13].uPower < 1u )
+                    pParty->pPartyBuffs[13].Reset();
+                }
+            if ( HasEnchantedItemEquipped(21)
+                || WearsItem(505, 3)
+                || WearsItem(530, 6) )
+                //goto LABEL_76;
+                return 0;
+            }
+
+        //v23 = 27;
+        PlaySound((PlayerSpeech)27, 0);
+        break;
+
+    case Condition_Disease1:
+    case Condition_Disease2:
+    case Condition_Disease3:
         if ( a3 == 1 )
-        {
-          if ( (signed __int64)pParty->pPartyBuffs[13].uExpireTime > 0 )
-          {
+            {            
+            if ( pParty->pPartyBuffs[13].uExpireTime > 0i64 )
+                {
+                --pParty->pPartyBuffs[13].uPower;
+                if ( pParty->pPartyBuffs[13].uPower < 1u )
+                    pParty->pPartyBuffs[13].Reset();
+                return 0;
+                }
+
+            if ( HasEnchantedItemEquipped(18) ||WearsItem(505, 3) || WearsItem(530, 6) )
+                return 0;
+            }
+        PlaySound((PlayerSpeech)28, 0);
+        break;
+    case Condition_Paralyzed:
+        if ( a3 == 1 )
+            {
+            if ( pParty->pPartyBuffs[13].uExpireTime > 0i64 )
+                {
+                --pParty->pPartyBuffs[13].uPower;
+                if ( pParty->pPartyBuffs[13].uPower < 1u )
+                    pParty->pPartyBuffs[13].Reset();
+                return 0;
+                }
+
+            if ( HasEnchantedItemEquipped(20)|| WearsItem(505, 3)|| WearsItem(507, 16)||WearsItem(530, 6))
+                return 0;
+            }
+        break;
+    case Condition_Unconcious:
+        PlaySound(SPEECH_32, 0);
+        if ( sHealth > 0 )
+            sHealth = 0;
+        break;
+    case Condition_Dead:
+        if ( a3 == 1 && (signed __int64)pParty->pPartyBuffs[13].uExpireTime > 0i64 && pParty->pPartyBuffs[13].uSkill >= 4u )
+            {
             --pParty->pPartyBuffs[13].uPower;
             if ( pParty->pPartyBuffs[13].uPower < 1u )
-              pParty->pPartyBuffs[13].Reset();
-          }
-          if ( v3->HasEnchantedItemEquipped(21)
-            || v7->WearsItem(505, 3)
-            || v8->WearsItem(530, 6) )
-            goto LABEL_76;
-        }
-        v26 = 0;
-        v23 = 27;
-        goto LABEL_81;
-      case 7u:
-      case 9u:
-      case 0xBu:
-        if ( a3 != 1 )
-          goto LABEL_40;
-        if ( SHIDWORD(pParty->pPartyBuffs[13].uExpireTime) >= 0
-          && (SHIDWORD(pParty->pPartyBuffs[13].uExpireTime) > 0 || LODWORD(pParty->pPartyBuffs[13].uExpireTime) > 0) )
-          goto LABEL_10;
-        if ( v3->HasEnchantedItemEquipped(18) || v3->WearsItem(505, 3) || v3->WearsItem(530, 6) )
-          goto LABEL_76;
-LABEL_40:
-        v26 = 0;
-        v23 = 28;
-        goto LABEL_81;
-      case 0xCu:
-        if ( a3 != 1 )
-          goto LABEL_82;
-        if ( SHIDWORD(pParty->pPartyBuffs[13].uExpireTime) >= 0
-          && (SHIDWORD(pParty->pPartyBuffs[13].uExpireTime) > 0 || LODWORD(pParty->pPartyBuffs[13].uExpireTime) > 0) )
-          goto LABEL_10;
-        if ( v3->HasEnchantedItemEquipped(20)
-          || v11->WearsItem(505, 3)
-          || v12->WearsItem(507, 16) )
-          goto LABEL_76;
-        v27 = 6;
-        v24 = 530;
-LABEL_16:
-        if ( v3->WearsItem(v24, v27) )
-          goto LABEL_76;
-        goto LABEL_82;
-      case 0xDu:
-        v3->PlaySound(SPEECH_32, 0);
-        v13 = (char *)&v3->sHealth;
-        goto LABEL_70;
-      case 0xEu:
-        if ( a3 == 1 && (signed __int64)pParty->pPartyBuffs[13].uExpireTime > 0 && pParty->pPartyBuffs[13].uSkill >= 4u )
-          goto LABEL_10;
-        v28 = 0;
-        v25 = 33;
-        goto LABEL_67;
-      case 0xFu:
+                pParty->pPartyBuffs[13].Reset();
+            }
+
+        PlaySound((PlayerSpeech)33, 0);
+        if ( sHealth > 0 )
+            sHealth = 0;
+        if ( sMana > 0 )
+            sMana = 0;
+        break;
+    case Condition_Pertified:
         if ( a3 == 1
-          && (SHIDWORD(pParty->pPartyBuffs[13].uExpireTime) >= 0
-           && (SHIDWORD(pParty->pPartyBuffs[13].uExpireTime) > 0 || LODWORD(pParty->pPartyBuffs[13].uExpireTime) > 0)
-           || v3->HasEnchantedItemEquipped(23)
-           || v14->WearsItem(520, 16)
-           || v15->WearsItem(505, 3)
-           || v16->WearsItem(530, 6)) )
-          goto LABEL_76;
-        v26 = 0;
-        v23 = 34;
-        goto LABEL_81;
-      case 0x10u:
-        if ( a3 == 1 && (signed __int64)pParty->pPartyBuffs[13].uExpireTime > 0 && pParty->pPartyBuffs[13].uSkill >= 4u )
-        {
-LABEL_10:
-          --pParty->pPartyBuffs[13].uPower;
-          if ( pParty->pPartyBuffs[13].uPower < 1u )
-            pParty->pPartyBuffs[13].Reset();
-          goto LABEL_76;
+            &&((pParty->pPartyBuffs[13].uExpireTime > 0i64)
+            || HasEnchantedItemEquipped(23)|| WearsItem(520, 16) || WearsItem(505, 3) || WearsItem(530, 6)) )
+
+            return 0;
+        PlaySound((PlayerSpeech)34, 0);
+        break;
+    case Condition_Eradicated:
+        if ( a3 == 1 && ((signed __int64)pParty->pPartyBuffs[13].uExpireTime > 0 )&&( pParty->pPartyBuffs[13].uSkill >= 4u ))
+            {
+            --pParty->pPartyBuffs[13].uPower;
+            if ( pParty->pPartyBuffs[13].uPower < 1u )
+                pParty->pPartyBuffs[13].Reset();
+            return 0;
+            }
+        PlaySound(SPEECH_35, 0);
+        if (sHealth > 0 )
+            sHealth = 0;
+        if ( sMana > 0 )
+            sMana = 0;
+        break;
+    case Condition_Zombie:
+        if ( classType == PLAYER_CLASS_LICH || Eradicated() ||Zombie() || !Dead())
+            return 0;
+        memset(&pConditions[0], 0, sizeof(pConditions));
+        sHealth = GetMaxHealth();
+        sMana = 0;
+        player_sex = 0;
+        uPrevFace = uCurrentFace;
+        uPrevVoiceID = uVoiceID;
+        switch ( uVoiceID )
+            {
+        case 0:
+        case 1:
+        case 2:
+        case 3:
+        case 8:
+        case 9:
+        case 12:
+        case 13:
+        case 16:
+        case 17:
+        case 20:
+        case 23:
+            player_sex = 0;
+            break;
+        case 4:
+        case 5:
+        case 6:
+        case 7:
+        case 10:
+        case 11:
+        case 14:
+        case 15:
+        case 18:
+        case 19:
+        case 21:
+        case 24:
+            player_sex = 1;
+            break;
+        default:
+            break;
+            }
+
+        zombi_face = (player_sex != 0) + 23;
+        uCurrentFace = zombi_face;
+        uVoiceID = zombi_face;
+        PlaySound((PlayerSpeech)SPEECH_99, 0);
+        break;
         }
-        v28 = 0;
-        v25 = SPEECH_35;
-LABEL_67:
-        v3->PlaySound((PlayerSpeech)v25, v28);
-        if ( v3->sHealth > 0 )
-          v3->sHealth = 0;
-        v13 = (char *)&v3->sMana;
-LABEL_70:
-        if ( *(int *)v13 > 0 )
-          *(int *)v13 = 0;
-LABEL_82:
-        v21 = 0;
-        *(_QWORD *)v29 = pParty->uTimePlayed;
-        v31 = 0;
-        v22 = 1;
-        do
-        {
-          if ( pPlayers[v22]->CanAct() )
-          {
-            ++v31;
-            v21 = v22;
-          }
-          ++v22;
-        }
-        while ( v22 <= 4 );
-        if ( v30 == 2 )
-        {
-          if ( v31 == 1 )
-            pPlayers[v21]->PlaySound(SPEECH_107, 0);
-        }
-        result = 1;
-        break;
-      case 0x11u:
-        if ( v3->classType == PLAYER_CLASS_LICH || v3->Eradicated() ||
-            v3->Zombie() || !v3->Dead())
-          goto LABEL_76;
-        memset(v3, 0, 0xA0u);
-        v3->sHealth = v3->GetMaxHealth();
-        v18 = 0;
-        v3->field_1928 = v3->uFace;
-        v19 = v3->uVoiceID;
-        v3->sMana = 0;
-        v3->field_1924 = v19;
-        switch ( v19 )
+
+    remainig_player = 0;
+    pConditions[uConditionIdx] = pParty->uTimePlayed;
+    players_after = 0;
+    for (int i=1;i<5;++i)
         {
-          case 0:
-          case 1:
-          case 2:
-          case 3:
-          case 8:
-          case 9:
-          case 12:
-          case 13:
-          case 16:
-          case 17:
-          case 20:
-          case 23:
-            v18 = 0;
-            break;
-          case 4:
-          case 5:
-          case 6:
-          case 7:
-          case 10:
-          case 11:
-          case 14:
-          case 15:
-          case 18:
-          case 19:
-          case 21:
-          case 24:
-            v18 = 1;
-            break;
-          default:
-            break;
+
+
+        if ( pPlayers[i]->CanAct() )
+            {
+            remainig_player=i;
+            ++players_after;
+            }
         }
-        v26 = 0;
-        v20 = (v18 != 0) + 23;
-        v23 = SPEECH_99;
-        v3->uFace = v20;
-        v3->uVoiceID = v20;
-LABEL_81:
-        v3->PlaySound((PlayerSpeech)v23, v26);
-        goto LABEL_82;
-      default:
-        goto LABEL_82;
-    }
-  }
-  return result;
-}
+    if (( players_before == 2 )&&( players_after == 1 ))
+        {
+        pPlayers[remainig_player]->PlaySound(SPEECH_107, 0);
+        }
+    return 1;
+    }
 
 //----- (00492528) --------------------------------------------------------
 bool Player::CanFitItem(unsigned int uSlot, unsigned int uItemID)
@@ -1376,7 +1288,7 @@
   if ( !areWeLoadingTexture )
   {
     v4->Release();
-    pIcons_LOD->_40F9C5();
+    pIcons_LOD->SyncLoadedFilesCount();
   }
   if ( (signed int)(v5 + (signed int)uSlot % 14) <= 14 && (signed int)(uItemIDa + (signed int)uSlot / 14) <= 9 )
   {
@@ -1471,7 +1383,7 @@
     if ( !areWeLoadingTexture )
     {
       v8->Release();
-      pIcons_LOD->_40F9C5();
+      pIcons_LOD->SyncLoadedFilesCount();
     }
     if ( (signed int)uItemIDa > 0 )
     {
@@ -1514,40 +1426,29 @@
 //----- (00492745) --------------------------------------------------------
 int Player::WearItem(unsigned int uItemID)
 {
-  signed int v2; // eax@1
-  ItemGen *v3; // edx@1
-  int v4; // edi@6
-  char *v5; // eax@6
-  char *v6; // esi@6
-
-  __debugbreak(); // sub is definetly broken
-
-  v2 = 0;
-  v3 = this->pInventoryItems;
-  while ( v3->uItemID )
-  {
-    ++v2;
-    ++v3;
-    if ( v2 >= 126 )
-    {
-      v2 = -1;
-      break;
-    }
-  }
-  if ( v2 != -1 )
-  {
-    v4 = v2 + 1;
-    v5 = (char *)this + 36 * v2;
-    v6 = &byte_4E8394[pItemsTable->pItems[uItemID].uEquipType + 4];
-    *(&this->pEquipment.uShield + (unsigned __int8)*v6) = v4;
-    *((int *)v5 + 133) = uItemID;
-    v5[556] = *v6 + 1;
+  int item_body_anch; // edi@6
+  int item_indx;
+  //find empty slot
+  for(item_indx=0;item_indx<126;++item_indx)
+      if (pInventoryItems[item_indx].uItemID==0)
+          break; 
+  if (item_indx==126) //not found
+      item_indx=-1;
+  
+  if ( item_indx != -1 )
+  {
+
+    pInventoryItems[item_indx].uItemID=uItemID;
+    item_body_anch=pEquipTypeToBodyAnchor[pItemsTable->pItems[uItemID].uEquipType];
+    pEquipment.pIndices[item_body_anch]=item_indx+1;
+    pInventoryItems[item_indx].uBodyAnchor=item_body_anch+1;
+
   }
   return 0;
 }
 
 //----- (004927A8) --------------------------------------------------------
-int Player::AddItem(unsigned int uSlot, unsigned int uItemID)
+int Player::AddItem(int uSlot, unsigned int uItemID)
 {
   signed int v3; // ebx@2
   signed int v4; // edi@3
@@ -1560,7 +1461,7 @@
   if ( uSlot == -1 )
   {
     v3 = 0;
-    while ( 2 )
+    while ( true )
     {
       v4 = 0;
       v5 = v3;
@@ -1594,7 +1495,7 @@
 }
 
 //----- (00492826) --------------------------------------------------------
-int Player::AddItem2(unsigned int uSlot, ItemGen *Src)
+int Player::AddItem2(int uSlot, ItemGen *Src)
 {
   unsigned int v3; // ebx@1
   unsigned int v4; // esi@3
@@ -1610,7 +1511,7 @@
   if ( uSlot == -1 )
   {
     uSlota = 0;
-    while ( 2 )
+    while ( true )
     {
       v4 = uSlota;
       v5 = 0;
@@ -1647,13 +1548,13 @@
   ItemGen *v4; // eax@1
   int result; // eax@6
   //unsigned int v6; // eax@7
-  Texture *v7; // esi@7
+  Texture *item_texture; // esi@7
   unsigned int v8; // edx@9
-  void *v9; // esi@10
-  unsigned int v10; // [sp+4h] [bp-Ch]@7
-  unsigned int v11; // [sp+8h] [bp-8h]@7
+  int *pInvPos; // esi@10
+  unsigned int slot_width; // [sp+4h] [bp-Ch]@7
+  unsigned int slot_height; // [sp+8h] [bp-8h]@7
   Player *v12; // [sp+Ch] [bp-4h]@1
-  unsigned int uSlota; // [sp+18h] [bp+8h]@10
+
 
   v12 = this;
   v3 = 0;
@@ -1674,30 +1575,28 @@
   }
   else
   {
-    v7 = pIcons_LOD->LoadTexturePtr(pItemsTable->pItems[Src->uItemID].pIconName, TEXTURE_16BIT_PALETTE);
-    v10 = GetSizeInInventorySlots(v7->uTextureWidth);
-    v11 = GetSizeInInventorySlots(v7->uTextureHeight);
+    item_texture = pIcons_LOD->LoadTexturePtr(pItemsTable->pItems[Src->uItemID].pIconName, TEXTURE_16BIT_PALETTE);
+    slot_width = GetSizeInInventorySlots(item_texture->uTextureWidth);
+    slot_height = GetSizeInInventorySlots(item_texture->uTextureHeight);
     if ( !areWeLoadingTexture )
     {
-      v7->Release();
-      pIcons_LOD->_40F9C5();
-    }
-    v8 = uSlot;
-    if ( (signed int)v11 > 0 )
-    {
-      uSlota = v11;
-      v9 = &v12->pInventoryIndices[v8];
+      item_texture->Release();
+      pIcons_LOD->SyncLoadedFilesCount();
+    }
+    if ( slot_height > 0 )
+    {
+      pInvPos = &pInventoryIndices[uSlot];
       do
       {
-        if ( (signed int)v10 > 0 )
-          memset32(v9, -1 - v8, v10);
-        v9 = (char *)v9 + 56;
-        --uSlota;
+        if ( slot_width > 0 )
+          memset32(pInvPos, -1 - uSlot, slot_width);
+        pInvPos +=14;
+        --slot_height;
       }
-      while ( uSlota );
-    }
-    v12->pInventoryIndices[v8] = v3 + 1;
-    memcpy(&v12->pInventoryItems[v3], Src, 0x24u);
+      while ( slot_height );
+    }
+    pInventoryIndices[uSlot] = v3 + 1;
+    memcpy(&pInventoryItems[v3], Src, sizeof(ItemGen));
     result = v3 + 1;
   }
   return result;
@@ -1705,83 +1604,74 @@
 // 506128: using guessed type int areWeLoadingTexture;
 
 //----- (0049298B) --------------------------------------------------------
-bool Player::_49298B(ItemGen *a2, int a3, int a4)
-{
+int Player::PutItemArInventoryIndex( ItemGen *item, int item_id, int uSlot )
+    {
   //Player *v4; // ebx@1
   //unsigned int v5; // eax@1
-  Texture *v6; // esi@1
-  void *v7; // esi@4
-  unsigned int v9; // [sp+Ch] [bp-4h]@1
-  unsigned int a2a; // [sp+18h] [bp+8h]@1
-
-  v6 = pIcons_LOD->LoadTexturePtr(pItemsTable->pItems[a2->uItemID].pIconName, TEXTURE_16BIT_PALETTE);
-  v9 = GetSizeInInventorySlots(v6->uTextureWidth);
-  a2a = GetSizeInInventorySlots(v6->uTextureHeight);
+  Texture *item_texture; // esi@1
+  int *pInvPos; // esi@4
+  unsigned int slot_width; // [sp+Ch] [bp-4h]@1
+  unsigned int slot_height; // [sp+18h] [bp+8h]@1
+
+  item_texture = pIcons_LOD->LoadTexturePtr(pItemsTable->pItems[item->uItemID].pIconName, TEXTURE_16BIT_PALETTE);
+  slot_width =  GetSizeInInventorySlots(item_texture->uTextureWidth);
+  slot_height = GetSizeInInventorySlots(item_texture->uTextureHeight);
   if ( !areWeLoadingTexture )
   {
-    v6->Release();
-    pIcons_LOD->_40F9C5();
-  }
-  if ( (signed int)a2a > 0 )
-  {
-    v7 = &pInventoryIndices[a4];
+    item_texture->Release();
+    pIcons_LOD->SyncLoadedFilesCount();
+  }
+  if ( (signed int)slot_height > 0 )
+  {
+    pInvPos = &pInventoryIndices[uSlot]; //14x9
     do
     {
-      if ( (signed int)v9 > 0 )
-        memset32(v7, -1 - a4, v9);
-      v7 = (char *)v7 + 56;
-      --a2a;
-    }
-    while ( a2a );
-  }
-  pInventoryIndices[a4] = a3 + 1;
+      if ( (signed int)slot_width > 0 )
+        memset32(pInvPos, -1 - uSlot, slot_width);
+      pInvPos +=14;
+      --slot_height;
+    }
+    while ( slot_height );
+  }
+  pInventoryIndices[uSlot] = item_id + 1;
   return 1;
 }
 
 // 506128: using guessed type int areWeLoadingTexture;
 
 //----- (00492A36) --------------------------------------------------------
-unsigned int Player::RemoveItemAtInventoryIndex(unsigned int uSlot)
-{
-  int *pIndices; // edi@1
-  ItemGen *v3; // ecx@1
-  unsigned int v4; // esi@1
-  //unsigned int v5; // eax@1
-  Texture *v6; // esi@1
-  unsigned int result; // eax@1
-  unsigned int v8; // ebp@1
-  void *v9; // edx@4
-  unsigned int uSlota; // [sp+14h] [bp+4h]@1
-
-  pIndices = &this->pInventoryIndices[uSlot];
-  v3 = &this->pInventoryItems[*pIndices-1];
-  v4 = v3->uItemID;
-  v3->Reset();
-  v6 = pIcons_LOD->LoadTexturePtr(pItemsTable->pItems[v4].pIconName, TEXTURE_16BIT_PALETTE);
-  uSlota = GetSizeInInventorySlots(v6->uTextureWidth);
-  result = GetSizeInInventorySlots(v6->uTextureHeight);
-  v8 = result;
+void Player::RemoveItemAtInventoryIndex( unsigned int uSlot )
+    {
+
+  ItemGen *item_in_slot; // ecx@1
+  Texture *item_texture; // esi@1
+  unsigned int slot_height; // ebp@1
+  int *pInvPos; // edx@4
+  unsigned int slot_width; // [sp+14h] [bp+4h]@1
+
+  item_in_slot = &this->pInventoryItems[pInventoryIndices[uSlot]-1];  
+  item_texture = pIcons_LOD->LoadTexturePtr(pItemsTable->pItems[item_in_slot->uItemID].pIconName, TEXTURE_16BIT_PALETTE);
+  item_in_slot->Reset();
+  slot_width = GetSizeInInventorySlots(item_texture->uTextureWidth);
+  slot_height = GetSizeInInventorySlots(item_texture->uTextureHeight);
   if ( !areWeLoadingTexture )
   {
-    v6->Release();
-    result = pIcons_LOD->_40F9C5();
-  }
-  if ( (signed int)v8 > 0 )
-  {
-    v9 = pIndices;
+    item_texture->Release();
+    pIcons_LOD->SyncLoadedFilesCount();
+  }
+  if ( slot_height > 0 )
+  {
+    pInvPos = &pInventoryIndices[uSlot];
     do
     {
-      if ( (signed int)uSlota > 0 )
-      {
-        result = 0;
-        memset(v9, 0, 4 * uSlota);
-      }
-      v9 = (char *)v9 + 56;
-      --v8;
-    }
-    while ( v8 );
-  }
-  return result;
+      if (slot_width > 0 )
+        memset32(pInvPos, 0, slot_width);
+      pInvPos += 14;
+      --slot_height;
+    }
+    while ( slot_height );
+  }
+  
 }
 // 506128: using guessed type int areWeLoadingTexture;
 
@@ -1969,7 +1859,7 @@
 //----- (0049107D) --------------------------------------------------------
 int Player::GetBodybuilding()
 {
-  char v1; // al@1
+  int v1; // al@1
   int v2; // ecx@1
   int v4; // eax@3
   signed int v6; // [sp-4h] [bp-4h]@2
@@ -1982,7 +1872,7 @@
   }
   else
   {
-    if ( v1 >= 0 )
+    if ( (v1&0xFF) >= 0 )
     {
       v4 = ((v1 & 0x40) != 0) + 1;
       return v2 * v4;
@@ -1996,28 +1886,28 @@
 //----- (004910A8) --------------------------------------------------------
 int Player::GetMeditation()
 {
-  char v1; // al@1
-  int v2; // ecx@1
+  int v1; // al@1
+  int base_level; // ecx@1
   int v4; // eax@3
   signed int v6; // [sp-4h] [bp-4h]@2
 
   v1 = GetActualSkillLevel(PLAYER_SKILL_MEDITATION);
-  v2 = v1 & 0x3F;
+  base_level = v1 & 0x3F;
   if ( v1 & 0x100 )
   {
     v6 = 5;
   }
   else
   {
-    if ( v1 >= 0 )
+    if ( (v1&0xFF) >= 0 )
     {
       v4 = ((v1 & 0x40) != 0) + 1;
-      return v2 * v4;
+      return base_level * v4;
     }
     v6 = 3;
   }
   v4 = v6;
-  return v2 * v4;
+  return base_level * v4;
 }
 
 //----- (004910D3) --------------------------------------------------------
@@ -2077,7 +1967,6 @@
   int v4; // eax@3
   int v5; // edi@7
   signed int v6; // ebp@7
-  char v8; // al@10
   signed int v10; // [sp-4h] [bp-14h]@2
 
   
@@ -2087,9 +1976,9 @@
       CheckHiredNPCSpeciality(Alchemist) && v7->uEquipType >= 9 )
     return true;
 
-  LOBYTE(v2) = GetActualSkillLevel(PLAYER_SKILL_REPAIR);
+  v2 = GetActualSkillLevel(PLAYER_SKILL_REPAIR);
   v3 = v2;
-  if ( HIBYTE(v2) & 1 )
+  if (v2 & 0x100 )
   {
     v10 = 5;
   }
@@ -2130,15 +2019,15 @@
 
   v1 = this;
   v2 = GetActualSkillLevel(PLAYER_SKILL_MERCHANT);
-  v3 = v1->pActiveSkills[22];
+  v3 = v1->pActiveSkills[PLAYER_SKILL_MERCHANT];
   v4 = v2 & 0x003F;
-  v5 = v1->pActiveSkills[22] & 0x3F;
+  v5 = v1->pActiveSkills[PLAYER_SKILL_MERCHANT] & 0x3F;
   if ( (signed int)SkillToMastery(v2) >= 4 )
     return 10000;
   v7 = GetPartyReputation();
   if ( !v4 )
     return -v7;
-  if ( HIBYTE(v3) & 1 )
+  if ( v3 & 0x100 )
   {
     v9 = 5;
   }
@@ -2167,13 +2056,13 @@
   signed int v8; // [sp-4h] [bp-10h]@4
 
   v1 = this;
-  v2 = (char)GetActualSkillLevel(PLAYER_SKILL_PERCEPTION);
-  v3 = v1->pActiveSkills[26];
+  v2 = GetActualSkillLevel(PLAYER_SKILL_PERCEPTION);
+  v3 = v1->pActiveSkills[PLAYER_SKILL_PERCEPTION];
   v4 = v2 & 0x3F;
-  v5 = v1->pActiveSkills[26] & 0x3F;
+  v5 = v1->pActiveSkills[PLAYER_SKILL_PERCEPTION] & 0x3F;
   if ( (signed int)SkillToMastery(v2) >= 4 )
     return 10000;
-  if ( HIBYTE(v3) & 1 )
+  if ( v3 & 0x100 )
   {
     v8 = 5;
   }
@@ -2202,7 +2091,7 @@
   signed int v8; // [sp-4h] [bp-14h]@6
 
   v1 = this;
-  LOBYTE(v2) = GetActualSkillLevel(PLAYER_SKILL_TRAP_DISARM);
+  v2 = GetActualSkillLevel(PLAYER_SKILL_TRAP_DISARM);
   v3 = v1->pActiveSkills[29];
   v4 = v2 & 0x3F;
   v5 = v1->pActiveSkills[29] & 0x3F;
@@ -2210,7 +2099,7 @@
     return 10000;
   if ( HasEnchantedItemEquipped(35) )
     v4 *= 2;
-  if ( HIBYTE(v3) & 1 )
+  if ( v3 & 0x100 )
   {
     v8 = 5;
   }
@@ -2238,12 +2127,12 @@
   signed int v7; // [sp-4h] [bp-Ch]@3
 
   v1 = this;
-  LOBYTE(v2) = GetActualSkillLevel(PLAYER_SKILL_LEARNING);
+  v2 = GetActualSkillLevel(PLAYER_SKILL_LEARNING);
   v3 = v1->pActiveSkills[36];
   v4 = v2 & 0x3F;
   if ( v2 )
   {
-    if ( HIBYTE(v3) & 1 )
+    if (v3 & 0x100 )
     {
       v7 = 5;
     }
@@ -2285,7 +2174,7 @@
   }
 
   pName[0] = 0;
-  uFace = 0;
+  uCurrentFace = 0;
   uVoiceID = 0;
   memset(pConditions, 0, 20 * sizeof(__int64));
 
@@ -2301,7 +2190,14 @@
   uLevel = sLevelModifier = 0;
   sAgeModifier = 0;
 
-  memset(field_1F5, 0, 30);
+//  memset(field_1F5, 0, 30);
+  pure_luck_used=0;      
+  pure_speed_used=0; 
+  pure_intellect_used=0;  
+  pure_endurance_used=0;  
+  pure_willpower_used=0;       
+  pure_accuracy_used=0;      
+  pure_might_used=0;  
 
   sResFireBase = sResFireBonus = 0;
   sResAirBase = sResAirBonus = 0;
@@ -2380,8 +2276,8 @@
   int v10; // eax@11
   bool result; // eax@15
   std::string v12; // [sp-18h] [bp-40h]@9
-  const char *v13; // [sp-8h] [bp-30h]@9
-  int v14; // [sp-4h] [bp-2Ch]@9
+
+
   int v15[4] = {0, 1, 2, 3}; // [sp+Ch] [bp-1Ch]@3
   //int v16; // [sp+10h] [bp-18h]@3
   //int v17; // [sp+14h] [bp-14h]@3
@@ -2422,7 +2318,7 @@
     {
       v9 = &v20->pPlayers[v15[v8]];
       v19 = &v20->pPlayers[v15[v8]];
-      v10 = v19->AddItem(0xFFFFFFFFu, pItem->uItemID);
+      v10 = v19->AddItem(-1, pItem->uItemID);
       if ( v10 )
         break;
       ++v8;
@@ -2431,7 +2327,7 @@
         if ( !v21 )
         {
           v7->Release();
-          pIcons_LOD->_40F9C5();
+          pIcons_LOD->SyncLoadedFilesCount();
         }
         goto LABEL_15;
       }
@@ -2443,7 +2339,7 @@
     if ( !v21 )
     {
       v7->Release();
-      pIcons_LOD->_40F9C5();
+      pIcons_LOD->SyncLoadedFilesCount();
     }
     result = 1;
   }
@@ -2596,8 +2492,6 @@
 //----- (0048CABC) --------------------------------------------------------
 int Player::GetActualEndurance()
 {
-  int v6; // ebp@5
-
   uint uActualAge = GetBaseAge() + sAgeModifier;
   uint uAgeingMultiplier = 100;
   for (uint i = 0; i < 4; ++i)
@@ -3371,7 +3265,8 @@
     v14 = v3->pEquipment.uArmor;
     if ( v14 )
     {
-      if ( !(v3->field_1F5[36 * v14 + 15] & 2) )
+     // if ( !(v3->field_1F5[36 * v14 + 15] & 2) )
+      if (v3->pOwnItems[v14-1].uAttributes&2) 
       {
         v15 = GetEquippedItemSkillType(EQUIP_ARMOUR) - 10;
         if ( v15 )
@@ -3436,10 +3331,8 @@
 //----- (0048D709) --------------------------------------------------------
 bool Player::WearsItem(int a1, signed int a2)
 {
-  int v3; // edx@2
-  Player *v4; // ecx@2
+
   int v6; // esi@5
-  int v7; // edx@6
 
   if ( a2 >= 16 )
   {
@@ -3674,24 +3567,21 @@
 //----- (0048DBB9) --------------------------------------------------------
 void Player::Heal(int amount)
 {
-  Player *v2; // esi@1
-  signed int v3; // eax@3
-
-  v2 = this;
-  if ( !this->pConditions[16] && !this->pConditions[14] )
-  {
-    v3 = GetMaxHealth();
-    if ( v2->pConditions[17] )
-      v3 /= 2;
-    v2->sHealth += amount;
-    if ( v2->sHealth > v3 )
-      v2->sHealth = v3;
-    if ( v2->pConditions[13] )
-    {
-      if ( v2->sHealth > 0 )
+  signed int max_health; // eax@3
+
+  if ( !pConditions[Condition_Eradicated] && !pConditions[Condition_Dead] )
+  {
+    max_health = GetMaxHealth();
+    if ( pConditions[Condition_Zombie] )
+      max_health /= 2;
+    sHealth += amount;
+    if ( sHealth > max_health )
+        sHealth = max_health;
+    if ( pConditions[Condition_Unconcious] )
+    {
+      if ( sHealth > 0 )
       {
-        LODWORD(v2->pConditions[13]) = 0;
-        HIDWORD(v2->pConditions[13]) = 0;
+        pConditions[Condition_Unconcious] = 0i64;
       }
     }
   }
@@ -3710,7 +3600,7 @@
   //signed int typea; // [sp+14h] [bp+8h]@1
 
   v3 = this;
-  this->pConditions[2] = 0i64;
+  this->pConditions[Condition_Sleep] = 0i64;
   v4 = CalculateIncommingDamage(resistance, type);
   v3->sHealth -= v4;
   //typea = v4;
@@ -3720,13 +3610,13 @@
   if ( v5 < 1 )
   {
     if ( v3->sHealth + v3->uEndurance + GetItemsBonus(CHARACTER_ATTRIBUTE_ENDURANCE, 0) >= 1
-      || (signed __int64)v3->pPlayerBuffs[11].uExpireTime > 0 )
-    {
-      SetCondition(0xDu, 0);
+      || (signed __int64)v3->pPlayerBuffs[PLAYER_BUFF_PRESERVATION].uExpireTime > 0 )
+    {
+      SetCondition(Condition_Unconcious, 0);
     }
     else
     {
-      SetCondition(0xEu, 0);
+      SetCondition(Condition_Dead, 0);
       v6 = LODWORD(pParty->uTimePlayed);
       if ( v3->sHealth > 0 )
         v3->sHealth = 0;
@@ -3736,7 +3626,8 @@
       v7 = v3->pEquipment.uArmor;
       if ( v7 )
       {
-        v8 = &v3->field_1F5[36 * v7 + 15];
+//        v8 = &v3->field_1F5[36 * v7 + 15];
+        v8=(char*)&v3->pOwnItems[v7-1].uAttributes;
         v9 = *(int *)v8;
         if ( !(BYTE1(v9) & 2) )
         {
@@ -3769,7 +3660,6 @@
   unsigned int v15; // edx@17
   int v16; // edx@26
   unsigned int v17; // edx@27
-  Player *v18; // ecx@32
   signed int v19; // edx@38
   int *v20; // ecx@38
   signed int v21; // eax@40
@@ -4153,7 +4043,8 @@
     else
       weapon_recovery = base_recovery_times_per_weapon_type[weapon_desc->uSkillType];
   }
-  if (HasItemEquipped(EQUIP_OFF_HAND) && GetEquippedItemEquipType(EQUIP_OFF_HAND) != EQUIP_SHIELD) // ADD: shield check because shield recovery is added later and can be accidentally doubled
+  if (HasItemEquipped(EQUIP_OFF_HAND) && GetEquippedItemEquipType(EQUIP_OFF_HAND) != EQUIP_SHIELD) 
+      // ADD: shield check because shield recovery is added later and can be accidentally doubled
   {
     auto v12 = &pInventoryItems[pEquipment.uShield - 1];
     auto v12_desc = &pItemsTable->pItems[v12->uItemID];
@@ -4495,7 +4386,6 @@
   signed int v2; // edi@1
   Player *v3; // esi@1
   enum CHARACTER_RACE v4; // ebx@1
-  Player *v5; // ecx@8
   char v6; // zf@18
   int v7; // ebx@28
   int result; // eax@28
@@ -5526,7 +5416,8 @@
       {
         if ( v9 <= 2 )
         {
-          v5 = pItemsTable->pItems[this->pInventoryItems[this->pEquipment.uMainHand].uItemID].uDamageDice + pItemsTable->pItems[this->pInventoryItems[this->pEquipment.uMainHand].uItemID].uDamageMod;
+          v5 = pItemsTable->pItems[this->pInventoryItems[this->pEquipment.uMainHand].uItemID].uDamageDice +
+                 pItemsTable->pItems[this->pInventoryItems[this->pEquipment.uMainHand].uItemID].uDamageMod;
           if ( !v6->pEquipment.uShield )
           {
             if ( pItemsTable->pItems[this->pInventoryItems[this->pEquipment.uMainHand].uItemID].uSkillType == 4 )
@@ -5644,8 +5535,8 @@
 }
 
 //----- (0048F882) --------------------------------------------------------
-char Player::GetActualSkillLevel(PLAYER_SKILL_TYPE uSkillType)
-{
+int Player::GetActualSkillLevel( PLAYER_SKILL_TYPE uSkillType )
+    {
   signed int v2; // esi@1
   unsigned __int16 v3; // ax@126
   char result; // al@127
@@ -5875,10 +5766,10 @@
   }
 
   v3 = pActiveSkills[uSkillType];
-  if ( v2 + (pActiveSkills[uSkillType] & 0x3F) < 60 )
+  if ( v2 + (v3 & 0x3F) < 60 )
     result = v2 + v3;
   else
-    result = v3 & 0xFC | 0x3C;
+    result = v3 & 0xFFFC | 0x3C; //al
   return result;
 }
 
@@ -6343,31 +6234,29 @@
 //                     24   zombie female
 enum CHARACTER_RACE Player::GetRace()
 {
-  if ( uFace > 15 )
-  {
-    if ( uFace >= 16 && uFace <= 19 )
+  if ( uCurrentFace > 15 )
+  {
+    if ( uCurrentFace >= 16 && uCurrentFace <= 19 )
       return CHARACTER_RACE_GOBLIN;
   }
   else
   {
-    if ( uFace >= 12 )
+    if ( uCurrentFace >= 12 )
     {
       return CHARACTER_RACE_DWARF;
     }
     else
     {
-      if ( uFace >= 0 )
-      {
-        if ( uFace <= 7 )
+      
+        if ( uCurrentFace <= 7 )
         {
           return CHARACTER_RACE_HUMAN;
         }
         else
         {
-          if ( uFace <= 11 )
+          if ( uCurrentFace <= 11 )
             return CHARACTER_RACE_ELF;
         }
-      }
     }
   }
   return CHARACTER_RACE_HUMAN;
@@ -6428,12 +6317,9 @@
 }
 
 //----- (004901FC) --------------------------------------------------------
-int Player::SetSexByVoice()
-{
-  __int64 v1; // qax@1
-
-  v1 = this->uVoiceID;
-  switch ( (int)v1 )
+void Player::SetSexByVoice()
+    {
+  switch ( this->uVoiceID)
   {
     case 0:
     case 1:
@@ -6447,7 +6333,7 @@
     case 0x11:
     case 0x14:
     case 0x17:
-      BYTE4(v1) = 0;
+      this->uSex = SEX_MALE;
       break;
     case 4:
     case 5:
@@ -6461,13 +6347,12 @@
     case 0x13:
     case 0x15:
     case 0x18:
-      BYTE4(v1) = 1;
+      this->uSex = SEX_FEMALE;
       break;
     default:
       break;
   }
-  this->uSex = (PLAYER_SEX)BYTE4(v1);
-  return v1;
+ 
 }
 
 //----- (0049024A) --------------------------------------------------------
@@ -6911,9 +6796,9 @@
   __int16 uGreen; // [sp+8h] [bp-8h]@1
   __int16 uRed; // [sp+Ch] [bp-4h]@1
 
-  uRed = TargetColor(0xFFu, 0x23u, 0);
-  uGreen = TargetColor(0, 0xFFu, 0);
-  uWhite = TargetColor(0xFFu, 0xFFu, 0xFFu);
+  uRed =   TargetColor(255,  35,   0);
+  uGreen = TargetColor(0,   255,   0);
+  uWhite = TargetColor(255, 255, 255);
   pBaseAttrValue = StatTable[GetRace()][uStat].uBaseValue;
 
   switch (uStat)
@@ -6938,874 +6823,865 @@
 //----- (004908A8) --------------------------------------------------------
 bool Player::DiscardConditionIfLastsLongerThan(unsigned int uCondition, unsigned __int64 uTime)
 {
-  unsigned __int64 *result; // eax@1
-
-  result = (unsigned __int64 *)((char *)this + 8 * uCondition);
-  if ( *result && (signed __int64)uTime < (signed __int64)*result )
-  {
-    *(int *)result = 0;
-    *((int *)result + 1) = 0;
-    LOBYTE(result) = 1;
+  if ( pConditions[uCondition] && (uTime < pConditions[uCondition]) )
+  {
+    pConditions[uCondition]=0i64;
+    return true;
   }
   else
-  {
-    LOBYTE(result) = 0;
-  }
-  return (bool)result;
+   return false;
 }
 
 //----- (004680ED) --------------------------------------------------------
-void Player::UseItem_DrinkPotion_etc(signed int a2, int a3)
-{
-  Player *v3; // esi@1
-  unsigned int v4; // ebx@4
-  signed int v5; // eax@17
-  unsigned int v6; // eax@26
-  unsigned __int8 v7; // cf@37
-  int v8; // edx@39
-  int v9; // edx@40
-  int v10; // edx@41
-  int v11; // edx@42
-  int v12; // edx@43
-  char *v13; // eax@45
-  AudioPlayer *v14; // ecx@62
-  signed int v15; // edi@68
-  int v16; // edx@73
-  unsigned __int16 *v17; // edi@73
-  unsigned int v18; // eax@73
-  int v19; // eax@74
-  int v20; // eax@75
-  signed int v21; // eax@81
-  const char *v22; // eax@84
-  char *v23; // ecx@90
-  int v24; // esi@96
-  int v25; // eax@109
-  int v26; // eax@113
-  char *v27; // edi@114
-  signed __int64 v28; // qax@120
-  char *v29; // ecx@120
-  int v30; // edi@137
-  int v31; // ST30_4@137
-  int v32; // ST3C_4@137
-  int v33; // ST40_4@137
-  int v34; // ST34_4@137
-  int v35; // ST38_4@137
-  unsigned __int8 v36; // al@173
-  SoundID v37; // [sp-20h] [bp-4Ch]@18
-  SoundID v38; // [sp-20h] [bp-4Ch]@174
-  signed int v39; // [sp-1Ch] [bp-48h]@18
-  signed int v40; // [sp-1Ch] [bp-48h]@174
-  unsigned int v41; // [sp-18h] [bp-44h]@18
-  unsigned int v42; // [sp-18h] [bp-44h]@174
-  signed int v43; // [sp-14h] [bp-40h]@18
-  signed int v44; // [sp-14h] [bp-40h]@174
-  signed int v45; // [sp-10h] [bp-3Ch]@18
-  unsigned __int16 v46; // [sp-10h] [bp-3Ch]@120
-  signed int v47; // [sp-10h] [bp-3Ch]@174
-  int v48; // [sp-Ch] [bp-38h]@18
-  unsigned int v49; // [sp-Ch] [bp-38h]@33
-  unsigned __int16 v50; // [sp-Ch] [bp-38h]@120
-  int v51; // [sp-Ch] [bp-38h]@174
-  unsigned int v52; // [sp-8h] [bp-34h]@18
-  char *v53; // [sp-8h] [bp-34h]@33
-  int v54; // [sp-8h] [bp-34h]@34
-  unsigned int v55; // [sp-8h] [bp-34h]@60
-  int v56; // [sp-8h] [bp-34h]@66
-  const char *v57; // [sp-8h] [bp-34h]@69
-  const char *v58; // [sp-8h] [bp-34h]@89
-  int v59; // [sp-8h] [bp-34h]@120
-  unsigned int v60; // [sp-8h] [bp-34h]@174
-  int v61; // [sp-4h] [bp-30h]@18
-  char *v62; // [sp-4h] [bp-30h]@33
-  char *v63; // [sp-4h] [bp-30h]@34
-  int v64; // [sp-4h] [bp-30h]@60
-  int v65; // [sp-4h] [bp-30h]@66
-  const char *v66; // [sp-4h] [bp-30h]@69
-  signed int v67; // [sp-4h] [bp-30h]@77
-  const char *v68; // [sp-4h] [bp-30h]@89
-  int v69; // [sp-4h] [bp-30h]@110
-  unsigned __int8 v70; // [sp-4h] [bp-30h]@120
-  int v71; // [sp-4h] [bp-30h]@174
-  char *v72; // [sp+20h] [bp-Ch]@68
-  signed int v73; // [sp+24h] [bp-8h]@1
-  char *v74; // [sp+24h] [bp-8h]@23
-  int v75; // [sp+24h] [bp-8h]@73
-  Player *thisb; // [sp+28h] [bp-4h]@1
-  unsigned int thisa; // [sp+28h] [bp-4h]@22
-
-  thisb = this;
-  v3 = &pParty->pPlayers[a2-1];
-  v73 = 1;
-  if ( pParty->bTurnBasedModeOn == 1 && (pTurnEngine->field_4 == 1 || pTurnEngine->field_4 == 3) )
-    return;
-  v4 = 0;
-  if ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uEquipType == 13 )
-  {
-    if ( pParty->pPickedItem.uItemID != 160 )
-    {
-      if ( pParty->pPickedItem.uItemID == 161 )
-      {
-        v27 = (char *)&v3->sMana;
-        *(int *)v27 += 2;
-LABEL_170:
-        if ( *(int *)v27 > v3->GetMaxMana() )
-          *(int *)v27 = v3->GetMaxMana();
-      }
-      else
-      {
-        if ( pParty->pPickedItem.uItemID != 162 )
+void Player::UseItem_DrinkPotion_etc(signed int player_num, int a3)
+    {
+    Player *v3; // esi@1
+    unsigned int v4; // ebx@4
+    signed int v5; // eax@17
+    unsigned int v6; // eax@26
+    unsigned __int8 v7; // cf@37
+    int v8; // edx@39
+    int v9; // edx@40
+    int v10; // edx@41
+    int v11; // edx@42
+    int v12; // edx@43
+    char *v13; // eax@45
+    AudioPlayer *v14; // ecx@62
+    signed int v15; // edi@68
+    int v16; // edx@73
+    unsigned __int16 v17; // edi@73
+    unsigned int v18; // eax@73
+    int v19; // eax@74
+    int v20; // eax@75
+    signed int v21; // eax@81
+    const char *v22; // eax@84
+    char *v23; // ecx@90
+    int scroll_id; // esi@96
+    int v25; // eax@109
+    int v26; // eax@113
+    int new_mana_val; // edi@114
+    signed __int64 v28; // qax@120
+    char *v29; // ecx@120
+    __int64 v30; // edi@137
+    int v31; // ST30_4@137
+    __int64 v32; // ST3C_4@137
+    int v33; // ST40_4@137
+    __int64 v34; // ST34_4@137
+    int v35; // ST38_4@137
+    unsigned __int8 v36; // al@173
+    SoundID v37; // [sp-20h] [bp-4Ch]@18
+    SoundID v38; // [sp-20h] [bp-4Ch]@174
+    signed int v39; // [sp-1Ch] [bp-48h]@18
+    signed int v40; // [sp-1Ch] [bp-48h]@174
+    unsigned int v41; // [sp-18h] [bp-44h]@18
+    unsigned int v42; // [sp-18h] [bp-44h]@174
+    signed int v43; // [sp-14h] [bp-40h]@18
+    signed int v44; // [sp-14h] [bp-40h]@174
+    signed int v45; // [sp-10h] [bp-3Ch]@18
+    unsigned __int16 v46; // [sp-10h] [bp-3Ch]@120
+    signed int v47; // [sp-10h] [bp-3Ch]@174
+    int v48; // [sp-Ch] [bp-38h]@18
+    unsigned int v49; // [sp-Ch] [bp-38h]@33
+    unsigned __int16 v50; // [sp-Ch] [bp-38h]@120
+    int v51; // [sp-Ch] [bp-38h]@174
+    unsigned int v52; // [sp-8h] [bp-34h]@18
+    char *v53; // [sp-8h] [bp-34h]@33
+    int v54; // [sp-8h] [bp-34h]@34
+    unsigned int v55; // [sp-8h] [bp-34h]@60
+    int v56; // [sp-8h] [bp-34h]@66
+    const char *v57; // [sp-8h] [bp-34h]@69
+    const char *v58; // [sp-8h] [bp-34h]@89
+    int v59; // [sp-8h] [bp-34h]@120
+    unsigned int v60; // [sp-8h] [bp-34h]@174
+    int v61; // [sp-4h] [bp-30h]@18
+    char *v62; // [sp-4h] [bp-30h]@33
+    char *v63; // [sp-4h] [bp-30h]@34
+    int v64; // [sp-4h] [bp-30h]@60
+    int v65; // [sp-4h] [bp-30h]@66
+    const char *v66; // [sp-4h] [bp-30h]@69
+    signed int v67; // [sp-4h] [bp-30h]@77
+    const char *v68; // [sp-4h] [bp-30h]@89
+    int v69; // [sp-4h] [bp-30h]@110
+    unsigned __int8 v70; // [sp-4h] [bp-30h]@120
+    int v71; // [sp-4h] [bp-30h]@174
+    char v72; // [sp+20h] [bp-Ch]@68
+    signed int v73; // [sp+24h] [bp-8h]@1
+    char *v74; // [sp+24h] [bp-8h]@23
+    int v75; // [sp+24h] [bp-8h]@73
+    Player *thisb; // [sp+28h] [bp-4h]@1
+    unsigned int thisa; // [sp+28h] [bp-4h]@22
+
+    thisb = this;
+    v3 = &pParty->pPlayers[player_num-1];
+    v73 = 1;
+    if ( pParty->bTurnBasedModeOn == 1 && (pTurnEngine->field_4 == 1 || pTurnEngine->field_4 == 3) )
+        return;
+    v4 = 0;
+    if ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uEquipType == EQUIP_REAGENT )
         {
-LABEL_167:
-          v68 = pParty->pPickedItem.GetDisplayName();
-          v58 = pGlobalTXT_LocalizationStrings[36];
-          goto LABEL_90;
-        }
-        v69 = 2;
-LABEL_111:
-        pParty->pPlayers[a2-1].Heal(v69);
-      }
-LABEL_112:
-      v3->PlaySound(SPEECH_36, 0);
-      goto LABEL_173;
-    }
-LABEL_172:
-    pParty->pPlayers[a2-1].SetCondition(6u, 1);
-    goto LABEL_173;
-  }
-  if ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uEquipType == 14 )
-  {
-    switch ( pParty->pPickedItem.uItemID )
-    {
-      case 0xDEu:
-        v25 = pParty->pPickedItem.uEnchantmentType + 10;
-        goto LABEL_110;
-      case 0xDFu:
-        v26 = pParty->pPickedItem.uEnchantmentType + 10;
-        goto LABEL_114;
-      case 0xE0u:
-        LODWORD(v3->pConditions[1]) = 0;
-        HIDWORD(v3->pConditions[1]) = 0;
-        goto LABEL_112;
-      case 0xE1u:
-        LODWORD(v3->pConditions[11]) = 0;
-        HIDWORD(v3->pConditions[11]) = 0;
-        LODWORD(v3->pConditions[9]) = 0;
-        HIDWORD(v3->pConditions[9]) = 0;
-        LODWORD(v3->pConditions[7]) = 0;
-        HIDWORD(v3->pConditions[7]) = 0;
-        goto LABEL_112;
-      case 0xE2u:
-        LODWORD(v3->pConditions[10]) = 0;
-        HIDWORD(v3->pConditions[10]) = 0;
-        LODWORD(v3->pConditions[8]) = 0;
-        HIDWORD(v3->pConditions[8]) = 0;
-        LODWORD(v3->pConditions[6]) = 0;
-        HIDWORD(v3->pConditions[6]) = 0;
-        goto LABEL_112;
-      case 0xE3u:
-        LODWORD(v3->pConditions[2]) = 0;
-        HIDWORD(v3->pConditions[2]) = 0;
-        goto LABEL_112;
-      case 0xE4u:
-        if ( v3->pConditions[1] )
-          goto LABEL_173;
-        v70 = 0;
-        v59 = 0;
-        v50 = 5;
-        v46 = 3;
-        v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
-        v29 = (char *)&v3->pPlayerBuffs[7];
-        goto LABEL_147;
-      case 0xE5u:
-        v70 = 0;
-        v59 = 0;
-        v50 = 5;
-        v46 = 3;
-        v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
-        v29 = (char *)&v3->pPlayerBuffs[8];
-        goto LABEL_147;
-      case 0xE6u:
-        v70 = 0;
-        v59 = 0;
-        v50 = 5;
-        v46 = 3;
-        v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
-        v29 = (char *)&v3->pPlayerBuffs[1];
-        goto LABEL_147;
-      case 0xE7u:
-        v70 = 0;
-        v59 = 0;
-        v50 = 3 * LOWORD(pParty->pPickedItem.uEnchantmentType);
-        v46 = 0;
-        v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
-        v29 = (char *)&v3->pPlayerBuffs[11];
-        goto LABEL_147;
-      case 0xE8u:
-        v70 = 0;
-        v59 = 0;
-        v50 = 3 * LOWORD(pParty->pPickedItem.uEnchantmentType);
-        v46 = 0;
-        v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
-        v29 = (char *)&v3->pPlayerBuffs[13];
-        goto LABEL_147;
-      case 0xEAu:
-        v70 = 0;
-        v59 = 0;
-        v50 = 5;
-        v46 = 3;
-        v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
-        v29 = (char *)&v3->pPlayerBuffs[14];
-        goto LABEL_147;
-      case 0xEBu:
-        v3->pPlayerBuffs[23].Apply(
-          pParty->uTimePlayed + (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335),
-          3u,
-          5u,
-          0,
-          0);
+        if ( pParty->pPickedItem.uItemID == 160 )
+            { 
+            pParty->pPlayers[player_num-1].SetCondition(Condition_Poison1, 1);
+            }
+        else if ( pParty->pPickedItem.uItemID == 161 )
+            {
+            new_mana_val = v3->sMana;
+            new_mana_val += 2;
+            if ( new_mana_val > v3->GetMaxMana() )
+                new_mana_val = v3->GetMaxMana();
+            v3->PlaySound(SPEECH_36, 0);
+            }
+        else if ( pParty->pPickedItem.uItemID == 162 )
+            {
+            pParty->pPlayers[player_num-1].Heal(2);
+            v3->PlaySound(SPEECH_36, 0);
+            
+            }
+        else
+            {    
+            v68 = pParty->pPickedItem.GetDisplayName();
+            v58 = pGlobalTXT_LocalizationStrings[36];//"%s can not be used that way"
+            sprintfex(pTmpBuf, v58, v68);
+            ShowStatusBarString(pTmpBuf, 2);
+            pAudioPlayer->PlaySound((SoundID)27, 0, 0, -1, 0, 0, 0, 0);
+            return;
+            }
         goto LABEL_173;
-      case 0xEDu:
-        LODWORD(v3->pConditions[3]) = 0;
-        HIDWORD(v3->pConditions[3]) = 0;
-        goto LABEL_112;
-      case 0xEEu:
-        LODWORD(v3->pConditions[0]) = 0;
-        HIDWORD(v3->pConditions[0]) = 0;
-        goto LABEL_112;
-      case 0xEFu:
-        LODWORD(v3->pConditions[5]) = 0;
-        HIDWORD(v3->pConditions[5]) = 0;
-        goto LABEL_112;
-      case 0xF0u:
-        v70 = 0;
-        v59 = 0;
-        v50 = 3 * LOWORD(pParty->pPickedItem.uEnchantmentType);
-        v46 = 0;
-        v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
-        v29 = (char *)&v3->pPlayerBuffs[19];
-        goto LABEL_147;
-      case 0xF1u:
-        v70 = 0;
-        v59 = 0;
-        v50 = 3 * LOWORD(pParty->pPickedItem.uEnchantmentType);
-        v46 = 0;
-        v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
-        v29 = (char *)&v3->pPlayerBuffs[17];
-        goto LABEL_147;
-      case 0xF2u:
-        v70 = 0;
-        v59 = 0;
-        v50 = 3 * LOWORD(pParty->pPickedItem.uEnchantmentType);
-        v46 = 0;
-        v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
-        v29 = (char *)&v3->pPlayerBuffs[20];
-        goto LABEL_147;
-      case 0xF3u:
-        v70 = 0;
-        v59 = 0;
-        v50 = 3 * LOWORD(pParty->pPickedItem.uEnchantmentType);
-        v46 = 0;
-        v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
-        v29 = (char *)&v3->pPlayerBuffs[16];
-        goto LABEL_147;
-      case 0xF4u:
-        v70 = 0;
-        v59 = 0;
-        v50 = 3 * LOWORD(pParty->pPickedItem.uEnchantmentType);
-        v46 = 0;
-        v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
-        v29 = (char *)&v3->pPlayerBuffs[21];
-        goto LABEL_147;
-      case 0xF5u:
-        v70 = 0;
-        v59 = 0;
-        v50 = 3 * LOWORD(pParty->pPickedItem.uEnchantmentType);
-        v46 = 0;
-        v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
-        v29 = (char *)&v3->pPlayerBuffs[15];
-        goto LABEL_147;
-      case 0xFBu:
-        LODWORD(v3->pConditions[12]) = 0;
-        HIDWORD(v3->pConditions[12]) = 0;
-        goto LABEL_112;
-      case 0xFCu:
-        v30 = LODWORD(v3->pConditions[14]);
-        v31 = HIDWORD(v3->pConditions[14]);
-        v32 = LODWORD(v3->pConditions[15]);
-        v33 = HIDWORD(v3->pConditions[15]);
-        v34 = LODWORD(v3->pConditions[16]);
-        v35 = HIDWORD(v3->pConditions[16]);
-        memset(&pParty->pPlayers[a2-1],0,0xA0u);
-        HIDWORD(v3->pConditions[14]) = v31;
-        LODWORD(v3->pConditions[15]) = v32;
-        HIDWORD(v3->pConditions[15]) = v33;
-        LODWORD(v3->pConditions[16]) = v34;
-        LODWORD(v3->pConditions[14]) = v30;
-        HIDWORD(v3->pConditions[16]) = v35;
-        goto LABEL_112;
-      case 0xFDu:
-        v25 = 5 * pParty->pPickedItem.uEnchantmentType;
-LABEL_110:
-        v69 = v25;
-        goto LABEL_111;
-      case 0xFEu:
-        v26 = 5 * pParty->pPickedItem.uEnchantmentType;
-LABEL_114:
-        v27 = (char *)&v3->sMana;
-        *(int *)v27 += v26;
-        goto LABEL_170;
-      case 0xFFu:
-        v70 = 0;
-        v59 = 0;
-        v50 = 3 * LOWORD(pParty->pPickedItem.uEnchantmentType);
-        v46 = 0;
-        v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
-        v29 = (char *)&v3->pPlayerBuffs[18];
-        goto LABEL_147;
-      case 0x100u:
-        v70 = 0;
-        v59 = 0;
-        v50 = 3 * LOWORD(pParty->pPickedItem.uEnchantmentType);
-        v46 = 0;
-        v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
-        v29 = (char *)&v3->pPlayerBuffs[5];
-        goto LABEL_147;
-      case 0x101u:
-        v70 = 0;
-        v59 = 0;
-        v50 = 3 * LOWORD(pParty->pPickedItem.uEnchantmentType);
-        v46 = 0;
-        v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
-        v29 = (char *)v3->pPlayerBuffs;
-        goto LABEL_147;
-      case 0x102u:
-        v70 = 0;
-        v59 = 0;
-        v50 = 3 * LOWORD(pParty->pPickedItem.uEnchantmentType);
-        v46 = 0;
-        v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
-        v29 = (char *)&v3->pPlayerBuffs[22];
-        goto LABEL_147;
-      case 0x103u:
-        v70 = 0;
-        v59 = 0;
-        v50 = 3 * LOWORD(pParty->pPickedItem.uEnchantmentType);
-        v46 = 0;
-        v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
-        v29 = (char *)&v3->pPlayerBuffs[3];
-        goto LABEL_147;
-      case 0x104u:
-        v70 = 0;
-        v59 = 0;
-        v50 = 3 * LOWORD(pParty->pPickedItem.uEnchantmentType);
-        v46 = 0;
-        v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
-        v29 = (char *)&v3->pPlayerBuffs[9];
-        goto LABEL_147;
-      case 0x105u:
-        v70 = 0;
-        v59 = 0;
-        v50 = 3 * LOWORD(pParty->pPickedItem.uEnchantmentType);
-        v46 = 0;
-        v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
-        v29 = (char *)&v3->pPlayerBuffs[2];
-LABEL_147:
-        ((SpellBuff *)v29)->Apply(pParty->uTimePlayed + v28, v46, v50, v59, v70);
-        goto LABEL_112;
-      case 0x106u:
-        LODWORD(v3->pConditions[15]) = 0;
-        HIDWORD(v3->pConditions[15]) = 0;
-        goto LABEL_112;
-      case 0x108u:
-        if ( !*(int *)&v3->field_1F5[3] )
+
+        }
+    if ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uEquipType == EQUIP_POTION )
         {
-          v3->uLuck += 50;
-          *(int *)&v3->field_1F5[3] = 1;
+        switch ( pParty->pPickedItem.uItemID )
+            {
+        case 221: //Catalyst
+            pParty->pPlayers[player_num-1].SetCondition(Condition_Poison1, 1);
+            break;
+        case 222: //Cure Wounds
+            v25 = pParty->pPickedItem.uEnchantmentType + 10;
+            pParty->pPlayers[player_num-1].Heal(v25);
+            v3->PlaySound(SPEECH_36, 0);
+            break;
+        case 223: //Magic Potion
+            v26 = pParty->pPickedItem.uEnchantmentType + 10;
+            new_mana_val = v3->sMana;
+            new_mana_val += v26;
+            if ( new_mana_val > v3->GetMaxMana() )
+                new_mana_val = v3->GetMaxMana();
+            v3->PlaySound(SPEECH_36, 0);
+            break;
+        case 224: //Cure Weakness
+            v3->pConditions[Condition_Weak] = 0i64;
+            v3->PlaySound(SPEECH_36, 0);
+            break;
+        case 225: //Cure Disease
+            v3->pConditions[Condition_Disease3] = 0i64;      
+            v3->pConditions[Condition_Disease2] = 0i64;
+            v3->pConditions[Condition_Disease1] = 0i64;
+            v3->PlaySound(SPEECH_36, 0);
+            break;
+        case 226: //Cure Poison
+            v3->pConditions[Condition_Poison3] = 0i64;
+            v3->pConditions[Condition_Poison2] = 0i64;
+            v3->pConditions[Condition_Poison1] = 0i64;
+            v3->PlaySound(SPEECH_36, 0);
+            break;
+        case 227: //Awaken
+            v3->pConditions[Condition_Sleep] = 0i64;
+            v3->PlaySound(SPEECH_36, 0);
+            break;
+        case 228: //Haste
+            if ( !v3->pConditions[Condition_Weak] )
+                {
+                v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
+                v3->pPlayerBuffs[7].Apply(pParty->uTimePlayed + v28, 3, 5, 0, 0);
+                v3->PlaySound(SPEECH_36, 0);
+                }
+            break;
+        case 229: //Heroism
+            v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
+            v3->pPlayerBuffs[8].Apply(pParty->uTimePlayed + v28, 3, 5, 0, 0);
+            v3->PlaySound(SPEECH_36, 0);
+            break;
+        case 230: //Bless
+            v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
+            v3->pPlayerBuffs[1].Apply(pParty->uTimePlayed + v28, 3, 5, 0, 0);
+            v3->PlaySound(SPEECH_36, 0);
+            break;
+        case 231: //Preservation
+            v50 = 3 * LOWORD(pParty->pPickedItem.uEnchantmentType);
+            v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
+            v3->pPlayerBuffs[11].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
+            v3->PlaySound(SPEECH_36, 0);
+            break;
+        case 232: //Shield
+            v50 = 3 * LOWORD(pParty->pPickedItem.uEnchantmentType);
+            v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
+            v3->pPlayerBuffs[13].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
+            v3->PlaySound(SPEECH_36, 0);
+            break;
+        case 234: //Stoneskin
+            v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
+            v3->pPlayerBuffs[14].Apply(pParty->uTimePlayed + v28, 3, 5, 0, 0);
+            v3->PlaySound(SPEECH_36, 0);
+            break;
+        case 235: //Water Breathing
+            v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335),
+            v3->pPlayerBuffs[23].Apply(pParty->uTimePlayed +v28,  3, 5, 0, 0);
+            break;
+        case 237: //Remove Fear
+            v3->pConditions[Condition_Fear] = 0i64;
+            v3->PlaySound(SPEECH_36, 0);
+            break;
+        case 238: //Remove Curse
+            v3->pConditions[Condition_Cursed] = 0i64;
+            v3->PlaySound(SPEECH_36, 0);
+            break;
+        case 239: //Cure Insanity
+            v3->pConditions[Condition_Insane] = 0i64;
+            v3->PlaySound(SPEECH_36, 0);
+            break;
+        case 240: //Might Boost
+            v50 = 3 * LOWORD(pParty->pPickedItem.uEnchantmentType);
+            v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
+            v3->pPlayerBuffs[19].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
+            v3->PlaySound(SPEECH_36, 0);
+            break;
+        case 241: //Intellect Boost
+            v50 = 3 * LOWORD(pParty->pPickedItem.uEnchantmentType);
+            v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
+            v3->pPlayerBuffs[17].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
+            v3->PlaySound(SPEECH_36, 0);
+            break;
+        case 242: //Personality Boost
+            v50 = 3 * LOWORD(pParty->pPickedItem.uEnchantmentType);
+            v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
+            v3->pPlayerBuffs[20].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
+            v3->PlaySound(SPEECH_36, 0);
+            break;
+        case 243://Endurance Boost
+            v50 = 3 * LOWORD(pParty->pPickedItem.uEnchantmentType);
+            v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
+            v3->pPlayerBuffs[16].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
+            v3->PlaySound(SPEECH_36, 0);
+            break;
+        case 244: //Speed Boost
+            v50 = 3 * LOWORD(pParty->pPickedItem.uEnchantmentType);
+            v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
+            v3->pPlayerBuffs[21].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
+            v3->PlaySound(SPEECH_36, 0);
+            break;
+        case 245: //Accuracy Boost
+            v50 = 3 * LOWORD(pParty->pPickedItem.uEnchantmentType);
+            v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
+            v3->pPlayerBuffs[15].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
+            v3->PlaySound(SPEECH_36, 0);
+            break;
+        case 251: //Cure Paralysis
+            v3->pConditions[Condition_Paralyzed] = 0i64;
+            v3->PlaySound(SPEECH_36, 0);
+            break;
+        case 252://Divine Restoration
+            v30 = v3->pConditions[Condition_Dead];
+            v32 = v3->pConditions[Condition_Pertified];
+            v34 = v3->pConditions[Condition_Eradicated];    
+            memset(&pParty->pPlayers[player_num-1].pConditions,0,sizeof(pConditions));
+            v3->pConditions[Condition_Dead] = v30;
+            v3->pConditions[Condition_Pertified] = v32;
+            v3->pConditions[Condition_Eradicated] = v34;
+            v3->PlaySound(SPEECH_36, 0);
+            break;
+        case 253: //Divine Cure
+            v25 = 5 * pParty->pPickedItem.uEnchantmentType;
+            pParty->pPlayers[player_num-1].Heal(v25);
+            v3->PlaySound(SPEECH_36, 0);
+            break;
+        case 254: //Divine Power
+            v26 = 5 * pParty->pPickedItem.uEnchantmentType;
+            new_mana_val = v3->sMana;
+            new_mana_val += v26;
+            if ( new_mana_val > v3->GetMaxMana() )
+                new_mana_val = v3->GetMaxMana();
+            v3->PlaySound(SPEECH_36, 0);
+            break;
+        case 255: //Luck Boost
+            v50 = 3 * LOWORD(pParty->pPickedItem.uEnchantmentType);
+            v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
+            v3->pPlayerBuffs[18].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
+            v3->PlaySound(SPEECH_36, 0);
+            break;
+        case 256: //Fire Resistance
+            v50 = 3 * LOWORD(pParty->pPickedItem.uEnchantmentType);
+            v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
+            v3->pPlayerBuffs[5].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
+            v3->PlaySound(SPEECH_36, 0);
+            goto LABEL_173;
+        case 257: //Air Resistance
+            v50 = 3 * LOWORD(pParty->pPickedItem.uEnchantmentType);
+            v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
+            v3->pPlayerBuffs[0].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
+            v3->PlaySound(SPEECH_36, 0);
+            break;
+        case 258: //Water Resistance
+            v50 = 3 * LOWORD(pParty->pPickedItem.uEnchantmentType);
+            v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
+            v3->pPlayerBuffs[22].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
+            v3->PlaySound(SPEECH_36, 0);
+            break;
+        case 259: //Earth Resistance
+            v50 = 3 * LOWORD(pParty->pPickedItem.uEnchantmentType);
+            v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
+            v3->pPlayerBuffs[3].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
+            v3->PlaySound(SPEECH_36, 0);
+            break;
+        case 260: //Mind Resistance
+            v50 = 3 * LOWORD(pParty->pPickedItem.uEnchantmentType);
+            v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
+            v3->pPlayerBuffs[9].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
+            v3->PlaySound(SPEECH_36, 0);
+            break;
+        case 261: //Body Resistance
+            v50 = 3 * LOWORD(pParty->pPickedItem.uEnchantmentType);
+            v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
+            v3->pPlayerBuffs[2].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
+            v3->PlaySound(SPEECH_36, 0);
+           break;
+        case 262: //Stone to Flesh
+            v3->pConditions[Condition_Pertified] = 0i64;
+            v3->PlaySound(SPEECH_36, 0);
+            break;
+        case 264: //Pure Luck
+            if ( !v3->pure_luck_used )
+                {
+                v3->uLuck += 50;
+                v3->pure_luck_used = 1;
+                }
+            v3->PlaySound(SPEECH_36, 0);
+            break;
+        case 265: //Pure Speed
+            if ( !v3->pure_speed_used )
+                {
+                v3->uSpeed += 50;
+                v3->pure_speed_used = 1;
+                }
+            v3->PlaySound(SPEECH_36, 0);
+            break;
+        case 266: //Pure Intellect
+            if ( !v3->pure_intellect_used )
+                {
+                v3->uIntelligence += 50;
+                v3->pure_intellect_used = 1;
+                }
+            v3->PlaySound(SPEECH_36, 0);
+           break;
+        case 267: //Pure Endurance
+            if ( !v3->pure_endurance_used )
+                {
+                v3->uEndurance += 50;
+                v3->pure_endurance_used = 1;
+                }
+            v3->PlaySound(SPEECH_36, 0);
+            break;
+        case 268:  //Pure Personality
+            if ( !v3->pure_willpower_used )
+                {
+                v3->uWillpower += 50;
+                v3->pure_willpower_used = 1;
+                }
+            v3->PlaySound(SPEECH_36, 0);
+            break;
+        case 269: //Pure Accuracy
+            if ( !v3->pure_accuracy_used )
+                {
+                v3->uAccuracy += 50;
+                v3->pure_accuracy_used = 1;
+                }
+            v3->PlaySound(SPEECH_36, 0);
+            break;
+        case 270: //Pure Might
+            if ( !v3->pure_might_used )
+                {
+                v3->uMight += 50;
+                v3->pure_might_used = 1;
+                }
+            v3->PlaySound(SPEECH_36, 0);
+            break;
+        case 271: //Rejuvenation
+            v3->sAgeModifier = 0;
+            v3->PlaySound(SPEECH_36, 0);
+           break;
+
+        default:
+            v68 = pParty->pPickedItem.GetDisplayName();
+            v58 = pGlobalTXT_LocalizationStrings[36];  //"%s can not be used that way"
+            sprintfex(pTmpBuf, v58, v68);
+            ShowStatusBarString(pTmpBuf, 2u);
+            pAudioPlayer->PlaySound((SoundID)27, 0, 0, -1, 0, 0, 0, 0);
+            return;
+
+            }
+       // pParty->pPlayers[player_num-1].SetCondition(Condition_Poison1, 1);
+        goto LABEL_173;
         }
-        goto LABEL_112;
-      case 0x109u:
-        if ( !*(int *)&v3->field_1F5[7] )
-        {
-          v3->uSpeed += 50;
-          *(int *)&v3->field_1F5[7] = 1;
-        }
-        goto LABEL_112;
-      case 0x10Au:
-        if ( !*(int *)&v3->field_1F5[11] )
-        {
-          v3->uIntelligence += 50;
-          *(int *)&v3->field_1F5[11] = 1;
-        }
-        goto LABEL_112;
-      case 0x10Bu:
-        if ( !*(int *)&v3->field_1F5[15] )
-        {
-          v3->uEndurance += 50;
-          *(int *)&v3->field_1F5[15] = 1;
-        }
-        goto LABEL_112;
-      case 0x10Cu:
-        if ( !*(int *)&v3->field_1F5[19] )
-        {
-          v3->uWillpower += 50;
-          *(int *)&v3->field_1F5[19] = 1;
-        }
-        goto LABEL_112;
-      case 0x10Du:
-        if ( !*(int *)&v3->field_1F5[23] )
-        {
-          v3->uAccuracy += 50;
-          *(int *)&v3->field_1F5[23] = 1;
-        }
-        goto LABEL_112;
-      case 0x10Eu:
-        if ( !*(int *)&v3->field_1F5[27] )
-        {
-          v3->uMight += 50;
-          *(int *)&v3->field_1F5[27] = 1;
-        }
-        goto LABEL_112;
-      case 0x10Fu:
-        v3->sAgeModifier = 0;
-        goto LABEL_112;
-      case 0xDDu:
-        goto LABEL_172;
-      default:
-        goto LABEL_167;
-    }
-    goto LABEL_172;
-  }
-  if ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uEquipType != 15 )
-  {
-    if ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uEquipType != 16 )
-    {
-      if ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uEquipType != 17 )
-      {
-        if ( pParty->pPickedItem.uItemID == 616 )
+
+
+    if ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uEquipType == EQUIP_SPELL_SCROLL )
         {
-          thisa = pParty->uCurrentMonthWeek + 1;
-          if ( pParty->uCurrentMonth >= 7 )
-            v74 = 0;
-          else
-            v74 = aAttributeNames[pParty->uCurrentMonth];
-          switch ( pParty->uCurrentMonth )
-          {
-            case 0u:
-              v6 = pParty->uCurrentMonthWeek + 1;
-              v3->uMight += thisa;
-              goto LABEL_33;
-            case 1u:
-              v6 = pParty->uCurrentMonthWeek + 1;
-              v3->uIntelligence += thisa;
-              goto LABEL_33;
-            case 2u:
-              v6 = pParty->uCurrentMonthWeek + 1;
-              v3->uWillpower += thisa;
-              goto LABEL_33;
-            case 3u:
-              v6 = pParty->uCurrentMonthWeek + 1;
-              v3->uEndurance += thisa;
-              goto LABEL_33;
-            case 4u:
-              v6 = pParty->uCurrentMonthWeek + 1;
-              v3->uAccuracy += thisa;
-              goto LABEL_33;
-            case 5u:
-              v6 = pParty->uCurrentMonthWeek + 1;
-              v3->uSpeed += thisa;
-              goto LABEL_33;
-            case 6u:
-              v6 = pParty->uCurrentMonthWeek + 1;
-              v3->uLuck += thisa;
-LABEL_33:
-              v62 = pGlobalTXT_LocalizationStrings[121];
-              v53 = v74;
-              v49 = v6;
-              goto LABEL_53;
-            case 7u:
-              party_finds_gold(1000 * thisa, 0);
-              v63 = pGlobalTXT_LocalizationStrings[97];
-              v54 = 1000 * thisa;
-              goto LABEL_38;
-            case 8u:
-              Party::GiveFood(5 * thisa);
-              v63 = pGlobalTXT_LocalizationStrings[653];
-              v54 = 5 * thisa;
-              goto LABEL_38;
+
+
+        if ( pCurrentScreen == SCREEN_CASTING )
+            return;
+        if ( !pParty->pPlayers[player_num-1].CanAct() )
+            {
+
+            
+            v68 = aCharacterConditionNames[v3->GetMajorConditionIdx()];
+        v58 = pGlobalTXT_LocalizationStrings[382];
+        sprintfex(pTmpBuf, v58, v68);
+        v23 = pTmpBuf;
+
+        ShowStatusBarString(v23, 2u);
+        v4 = 0;
+        v61 = v4;
+        v52 = v4;
+        v48 = v4;
+        v45 = v4;
+        v43 = -1;
+        v41 = v4;
+        v39 = v4;
+        v37 = (SoundID)27;
+        pAudioPlayer->PlaySound(v37, v39, v41, v43, v45, v48, v52, v61);
+        return;
+            }
+        if ( bUnderwater == 1 )
+            {
+            v23 = pGlobalTXT_LocalizationStrings[652]; //"You can not do that while you are underwater!"
+            ShowStatusBarString(v23, 2u);
+            v4 = 0;
+            v61 = v4;
+            v52 = v4;
+            v48 = v4;
+            v45 = v4;
+            v43 = -1;
+            v41 = v4;
+            v39 = v4;
+            v37 = (SoundID)27;
+            pAudioPlayer->PlaySound(v37, v39, v41, v43, v45, v48, v52, v61);
+            return;
+            }
+        dword_50C9AC = 1;
+        scroll_id = pParty->pPickedItem.uItemID - 299;
+        if ( scroll_id == 30 || scroll_id == 4 || scroll_id == 91 || scroll_id == 28 ) //Enchant Item scroll, Vampiric Weapon scroll ,Recharge Item ,Fire Aura
+            {
+            pMouse->RemoveHoldingItem();
+            pGUIWindow_CurrentMenu->Release();
+            pIcons_LOD->_4114F2();
+            pCurrentScreen = SCREEN_GAME;
+            viewparams->bRedrawGameUI = 1;
+            _42777D_CastSpell_UseWand_ShootArrow(scroll_id, player_num - 1, 0x85u, 1, 0);
+            }
+        else
+            {
+            _720984_unused = pParty->pPickedItem.uItemID;
+            pMouse->RemoveHoldingItem();
+            pMessageQueue_50C9E8->AddMessage(UIMSG_SpellScrollUse, scroll_id, player_num - 1);
+            if ( pCurrentScreen && pGUIWindow_CurrentMenu
+                && (pGUIWindow_CurrentMenu->eWindowType != WINDOW_null))
+                {
+                pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 0, 0);
+                }
+            }
+        return;
+        }
+
+    if ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uEquipType == EQUIP_BOOK )
+
+        {  
+        v15 = pParty->pPickedItem.uItemID - 400;
+        v72 = v3->spellbook.bHaveSpell[pParty->pPickedItem.uItemID-400];//(char *)&v3->pConditions[0] + pParty->pPickedItem.uItemID + 2;
+        if ( v72 )
+            {
+            v66 = pParty->pPickedItem.GetDisplayName();
+            v57 = pGlobalTXT_LocalizationStrings[380];//"You already know the %s spell"
+LABEL_72:
+            sprintf(pTmpBuf, v57, v66);
+            ShowStatusBarString(pTmpBuf, 2u);
+LABEL_92:
+            v61 = v4;
+            v52 = v4;
+            v48 = v4;
+            v45 = v4;
+            v43 = -1;
+            v41 = v4;
+            v39 = v4;
+            v37 = (SoundID)27;
+LABEL_93:
+            v14 = pAudioPlayer;
+LABEL_63:
+            pAudioPlayer->PlaySound(v37, v39, v41, v43, v45, v48, v52, v61);
+            return;
+            }
+        if ( !pParty->pPlayers[player_num-1].CanAct() )
+            {
+            v66 = aCharacterConditionNames[v3->GetMajorConditionIdx()];
+            v57 = pGlobalTXT_LocalizationStrings[382];//"That player is %s"
+            sprintf(pTmpBuf, v57, v66);
+            ShowStatusBarString(pTmpBuf, 2u);
+            v61 = v4;
+            v52 = v4;
+            v48 = v4;
+            v45 = v4;
+            v43 = -1;
+            v41 = v4;
+            v39 = v4;
+            v37 = (SoundID)27;
+            v14 = pAudioPlayer;
+            pAudioPlayer->PlaySound(v37, v39, v41, v43, v45, v48, v52, v61);
+            return;
+            }
+        v16 = v15 % 11 + 1;
+        v17 = v3->pActiveSkills[v15 / 11 + 12];
+        v75 = v16;
+        v18 = SkillToMastery(v17) - 1;
+        if ( v18 )
+            {
+            v19 = v18 - 1;
+            if ( v19 )
+                {
+                v20 = v19 - 1;
+                if ( v20 )
+                    {
+                    if ( v20 != 1 )
+                        {
+                        v21 = player_num;
+LABEL_83:
+                        if ( v75 > v21 || !v17 )
+                            {
+                            v22 = pParty->pPickedItem.GetDisplayName();
+                            sprintfex(pTmpBuf, pGlobalTXT_LocalizationStrings[381], v22);
+                            ShowStatusBarString(pTmpBuf, 2u);
+                            v3->PlaySound((PlayerSpeech)20, 0);
+                            return; 
+                            }
+                        v72 = 1;
+                        v3->PlaySound(SPEECH_21, 0);
+                        v73 = 0;
+LABEL_173:
+                        v36 = pItemsTable->pItems[pParty->pPickedItem.uItemID].uEquipType;
+                        if ( v36 == EQUIP_POTION )
+                            {
+                            v71 = 0;
+                            v60 = 0;
+                            v51 = 0;
+                            v47 = 0;
+                            v44 = -1;
+                            v42 = 0;
+                            v40 = 0;
+                            v38 = (SoundID)210;
+                            }
+                        else
+                            {
+                            if ( v36 != EQUIP_REAGENT )
+                                {
+LABEL_178:
+                                if ( pGUIWindow_CurrentMenu && pGUIWindow_CurrentMenu->eWindowType != WINDOW_null)
+                                    {
+                                    if ( !v73 )
+                                        {
+                                        pMouse->RemoveHoldingItem();
+                                         return;
+                                         }
+                                    pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 0, 0);
+                                    }
+                                if ( v73 )
+                                    {
+                                    if ( pParty->bTurnBasedModeOn )
+                                        {
+                                        *(&pParty->field_16140 + player_num) = 100;
+                                        thisb->SetRecoveryTime(100);
+                                        pTurnEngine->_40471C();
+                                        }
+                                    else
+                                        {
+                                        thisb->SetRecoveryTime((signed __int64)(flt_6BE3A4_debug_recmod1 * 213.3333333333333));
+                                        }
+                                    }
+                                pMouse->RemoveHoldingItem();
+                                return;
+                                }
+                            v71 = 0;
+                            v60 = 0;
+                            v51 = 0;
+                            v47 = 0;
+                            v44 = -1;
+                            v42 = 0;
+                            v40 = 0;
+                            v38 = (SoundID)211;
+                            }
+                        pAudioPlayer->PlaySound(v38, v40, v42, v44, v47, v51, v60, v71);
+                        goto LABEL_178;
+                        }
+                    v67 = 11;
+                    }
+                else
+                    {
+                    v67 = 10;
+                    }
+                }
+            else
+                {
+                v67 = 7;
+                }
+            }
+        else
+            {
+            v67 = 4;
+            }
+        v21 = v67;
+        goto LABEL_83;
+        }
+
+    if ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uEquipType == EQUIP_MESSAGE_SCROLL )
+
+        {
+        if ( pParty->pPlayers[player_num-1].CanAct() )
+            {
+            CreateMsgScrollWindow(pParty->pPickedItem.uItemID);
+            v65 = 0;
+            v56 = SPEECH_37;
+LABEL_67:
+            v3->PlaySound((PlayerSpeech)v56, v65);
+            return;
+            }
+LABEL_89:
+        v68 = aCharacterConditionNames[v3->GetMajorConditionIdx()];
+        v58 = pGlobalTXT_LocalizationStrings[382];
+LABEL_90:
+        sprintfex(pTmpBuf, v58, v68);
+        v23 = pTmpBuf;
+LABEL_91:
+        ShowStatusBarString(v23, 2u);
+        v4 = 0;
+        v61 = v4;
+        v52 = v4;
+        v48 = v4;
+        v45 = v4;
+        v43 = -1;
+        v41 = v4;
+        v39 = v4;
+        v37 = (SoundID)27;
+        pAudioPlayer->PlaySound(v37, v39, v41, v43, v45, v48, v52, v61);
+        return;
+        }
+    else
+        {
+        if ( pParty->pPickedItem.uItemID == 616 ) //Genie Lamp
+            {
+            thisa = pParty->uCurrentMonthWeek + 1;
+            if ( pParty->uCurrentMonth >= 7 )
+                v74 = 0;
+            else
+                v74 = aAttributeNames[pParty->uCurrentMonth];
+            switch ( pParty->uCurrentMonth )
+                {
+            case 0:
+                v6 = pParty->uCurrentMonthWeek + 1;
+                v3->uMight += thisa;
+                v62 = pGlobalTXT_LocalizationStrings[121]; //"Permanent"	
+                v53 = v74;
+                v49 = v6;
+                sprintf(pTmpBuf, "+%u %s %s", v49, v53, v62);
+                break;
+            case 1:
+                v6 = pParty->uCurrentMonthWeek + 1;
+                v3->uIntelligence += thisa;
+                v62 = pGlobalTXT_LocalizationStrings[121];
+                v53 = v74;
+                v49 = v6;
+                sprintf(pTmpBuf, "+%u %s %s", v49, v53, v62);
+                break;
+            case 2:
+                v6 = pParty->uCurrentMonthWeek + 1;
+                v3->uWillpower += thisa;
+                v62 = pGlobalTXT_LocalizationStrings[121];
+                v53 = v74;
+                v49 = v6;
+                sprintf(pTmpBuf, "+%u %s %s", v49, v53, v62);
+                break;
+            case 3:
+                v6 = pParty->uCurrentMonthWeek + 1;
+                v3->uEndurance += thisa;
+                v62 = pGlobalTXT_LocalizationStrings[121];
+                v53 = v74;
+                v49 = v6;
+                sprintf(pTmpBuf, "+%u %s %s", v49, v53, v62);
+                break;
+            case 4:
+                v6 = pParty->uCurrentMonthWeek + 1;
+                v3->uAccuracy += thisa;
+                v62 = pGlobalTXT_LocalizationStrings[121];
+                v53 = v74;
+                v49 = v6;
+                sprintf(pTmpBuf, "+%u %s %s", v49, v53, v62);
+                break;
+            case 5:
+                v6 = pParty->uCurrentMonthWeek + 1;
+                v3->uSpeed += thisa;
+                v62 = pGlobalTXT_LocalizationStrings[121];
+                v53 = v74;
+                v49 = v6;
+                sprintf(pTmpBuf, "+%u %s %s", v49, v53, v62);
+                break;
+            case 6:
+                v6 = pParty->uCurrentMonthWeek + 1;
+                v3->uLuck += thisa;
+                v62 = pGlobalTXT_LocalizationStrings[121];
+                v53 = v74;
+                v49 = v6;
+                sprintf(pTmpBuf, "+%u %s %s", v49, v53, v62);
+                break;
+            case 7:
+                party_finds_gold(1000 * thisa, 0);
+                v63 = pGlobalTXT_LocalizationStrings[97];//"Gold"
+                v54 = 1000 * thisa;
+                sprintf(pTmpBuf, "+%u %s", v54, v63);
+                break;
+            case 8:
+                Party::GiveFood(5 * thisa); 
+                v63 = pGlobalTXT_LocalizationStrings[653]; //"Food"
+                v54 = 5 * thisa;
+                sprintf(pTmpBuf, "+%u %s", v54, v63);
+                break;
             case 9u:
-              v63 = pGlobalTXT_LocalizationStrings[207];
-              v3->uSkillPoints += 2 * thisa;
-              v54 = 2 * thisa;
-              goto LABEL_38;
-            case 0xAu:
-              v63 = pGlobalTXT_LocalizationStrings[83];
-              v54 = 2500 * thisa;
-              v7 = __CFADD__(2500 * thisa, LODWORD(v3->uExperience));
-              LODWORD(v3->uExperience) += 2500 * thisa;
-              HIDWORD(v3->uExperience) += ((unsigned __int64)(signed int)(2500 * thisa) >> 32) + v7;
-LABEL_38:
-              sprintf(pTmpBuf, "+%u %s", v54, v63);
-              goto LABEL_54;
-            case 0xBu:
-              v8 = rand() % 6;
-              if ( v8 )
-              {
-                v9 = v8 - 1;
-                if ( v9 )
-                {
-                  v10 = v9 - 1;
-                  if ( v10 )
-                  {
-                    v11 = v10 - 1;
-                    if ( v11 )
+                v63 = pGlobalTXT_LocalizationStrings[LOCSTR_SKILL_POINTS];
+                v3->uSkillPoints += 2 * thisa;
+                v54 = 2 * thisa;
+                sprintf(pTmpBuf, "+%u %s", v54, v63);
+                break;
+            case 10:
+                v63 = pGlobalTXT_LocalizationStrings[LOCSTR_EXPIRIENCE];
+                v54 = 2500 * thisa;
+                v3->uExperience += 2500 * thisa;
+                sprintf(pTmpBuf, "+%u %s", v54, v63);
+                break;
+            case 11:
+                v8 = rand() % 6;
+                switch (v8)
                     {
-                      v12 = v11 - 1;
-                      if ( v12 )
-                      {
-                        if ( v12 != 1 )
-                          goto LABEL_52;
-                        v3->sResBodyBase += thisa;
-                        v13 = pGlobalTXT_LocalizationStrings[29];
-                      }
-                      else
-                      {
-                        v3->sResMindBase += thisa;
-                        v13 = pGlobalTXT_LocalizationStrings[142];
-                      }
-                    }
-                    else
-                    {
-                      v3->sResEarthBase += thisa;
-                      v13 = pGlobalTXT_LocalizationStrings[70];
-                    }
-                  }
-                  else
-                  {
+                case 0:
+                    v3->sResFireBase += thisa;
+                    v13 = pGlobalTXT_LocalizationStrings[87];
+                    break;
+                case 1:
+                    v3->sResAirBase += thisa;
+                    v13 = pGlobalTXT_LocalizationStrings[6];
+                    break;
+                case 2:
                     v3->sResWaterBase += thisa;
                     v13 = pGlobalTXT_LocalizationStrings[240];
-                  }
-                }
-                else
-                {
-                  v3->sResAirBase += thisa;
-                  v13 = pGlobalTXT_LocalizationStrings[6];
+                    break;
+                case 3:
+                    v3->sResEarthBase += thisa;
+                    v13 = pGlobalTXT_LocalizationStrings[70];
+                    break;
+                case 4:
+                    v3->sResMindBase += thisa;
+                    v13 = pGlobalTXT_LocalizationStrings[142];
+                    break;
+                case 5:
+                    v3->sResBodyBase += thisa;
+                    v13 = pGlobalTXT_LocalizationStrings[29];
+                    break;
+                    }
+                v62 = pGlobalTXT_LocalizationStrings[121];
+                v53 = v13;
+                v49 = thisa;
+                sprintf(pTmpBuf, "+%u %s %s", v49, v53, v62);
+                break;
+
                 }
-              }
-              else
-              {
-                v3->sResFireBase += thisa;
-                v13 = pGlobalTXT_LocalizationStrings[87];
-              }
-              v74 = v13;
-LABEL_52:
-              v62 = pGlobalTXT_LocalizationStrings[121];
-              v53 = v74;
-              v49 = thisa;
-LABEL_53:
-              sprintf(pTmpBuf, "+%u %s %s", v49, v53, v62);
-LABEL_54:
-              ShowStatusBarString(pTmpBuf, 2u);
-              pMouse->RemoveHoldingItem();
-              pGame->pStru6Instance->SetPlayerBuffAnim(0x97u, a2 - 1);
-              v3->PlaySound(SPEECH_93, 0);
-              pAudioPlayer->PlaySound((SoundID)(SOUND_Bell|0x2), 0, 0, -1, 0, 0, 0, 0);
-              if ( pParty->uDaysPlayed == 6 || pParty->uDaysPlayed == 20 )
-              {
-                v64 = 0;
-                v55 = 16;
-              }
-              else
-              {
-                if ( pParty->uDaysPlayed == 12 || pParty->uDaysPlayed == 26 )
+            ShowStatusBarString(pTmpBuf, 2u);
+            pMouse->RemoveHoldingItem();
+            pGame->pStru6Instance->SetPlayerBuffAnim(0x97u, player_num - 1);
+            v3->PlaySound(SPEECH_93, 0);
+            pAudioPlayer->PlaySound((SoundID)(SOUND_Bell|0x2), 0, 0, -1, 0, 0, 0, 0);
+            if ( pParty->uDaysPlayed == 6 || pParty->uDaysPlayed == 20 )
                 {
-                  v64 = 0;
-                  v55 = 14;
+                v3->SetCondition(Condition_Eradicated, 0);
+                pAudioPlayer->PlaySound((SoundID)215, 0, 0, -1, 0, 0, 0, 0);
                 }
-                else
+            else if ( pParty->uDaysPlayed == 12 || pParty->uDaysPlayed == 26 )
                 {
-                  if ( pParty->uDaysPlayed != 4 && pParty->uDaysPlayed != 25 )
-                    return;
-                  v64 = 0;
-                  v55 = 15;
+                v3->SetCondition(Condition_Dead, 0);
+                pAudioPlayer->PlaySound((SoundID)215, 0, 0, -1, 0, 0, 0, 0);
+                }
+            else  if ( pParty->uDaysPlayed == 4 || pParty->uDaysPlayed == 25 )
+                {
+                v3->SetCondition(Condition_Pertified, 0);
+                pAudioPlayer->PlaySound((SoundID)215, 0, 0, -1, 0, 0, 0, 0);                 
                 }
-              }
-              v3->SetCondition(v55, v64);
-              v61 = 0;
-              v52 = 0;
-              v48 = 0;
-              v45 = 0;
-              v43 = -1;
-              v41 = 0;
-              v39 = 0;
-              v37 = (SoundID)215;
-              v14 = pAudioPlayer;
-              goto LABEL_63;
-            default:
-              goto LABEL_54;
-          }
-        }
-        if ( pParty->pPickedItem.uItemID == 630 )
-        {
-          Party::GiveFood(1u);
-          pAudioPlayer->PlaySound((SoundID)(SOUND_PlayerCantCastSpell|0x2), 0, 0, -1, 0, 0, 0, 0);
-        }
+            return;
+            }
+        else if ( pParty->pPickedItem.uItemID == 630 ) //Red Apple
+            {
+            Party::GiveFood(1u);
+            pAudioPlayer->PlaySound((SoundID)(SOUND_PlayerCantCastSpell|0x2), 0, 0, -1, 0, 0, 0, 0);
+
+            }
+        else if ( pParty->pPickedItem.uItemID == 632 ) //Lute
+                {
+                pAudioPlayer->PlaySound((SoundID)133,  0, 0, -1, 0, 0, 0, 0);
+                return;
+                }
+        else if ( pParty->pPickedItem.uItemID == 633 ) //Faerie Pipes
+                {
+                pAudioPlayer->PlaySound((SoundID)134,  0, 0, -1, 0, 0, 0, 0);
+                return;
+                }
+        else if ( pParty->pPickedItem.uItemID == 634 ) //Gryphonheart's Trumpet
+                {
+                pAudioPlayer->PlaySound((SoundID)135,  0, 0, -1, 0, 0, 0, 0);
+                return;
+                }
+        else if ( pParty->pPickedItem.uItemID == 646 )
+                {
+                pGame->pStru6Instance->SetPlayerBuffAnim(0x97u, player_num - 1);
+                v5 = 8 * player_num + 392;
+                LOBYTE(v5) = PID(OBJECT_Player,player_num - 120);
+                pAudioPlayer->PlaySound(SOUND_20001, v5, 0, -1, 0, 0, 0, 0);
+                v3->AddVariable(VAR_NumSkillPoints, 2);
+                }
+        else if ( pParty->pPickedItem.uItemID == 650 ) //Temple in a Bottle
+                    {
+                    sub_44C28F_open_nwc_dungeon();
+                    return;
+                    }
         else
-        {
-          if ( pParty->pPickedItem.uItemID == 632 )
-          {
-            v61 = 0;
-            v52 = 0;
-            v48 = 0;
-            v45 = 0;
-            v43 = -1;
-            v41 = 0;
-            v39 = 0;
-            v37 = (SoundID)133;
-            goto LABEL_93;
-          }
-          if ( pParty->pPickedItem.uItemID == 633 )
-          {
-            v61 = 0;
-            v52 = 0;
-            v48 = 0;
-            v45 = 0;
-            v43 = -1;
-            v41 = 0;
-            v39 = 0;
-            v37 = (SoundID)134;
-            goto LABEL_93;
-          }
-          if ( pParty->pPickedItem.uItemID == 634 )
-          {
-            v61 = 0;
-            v52 = 0;
-            v48 = 0;
-            v45 = 0;
-            v43 = -1;
-            v41 = 0;
-            v39 = 0;
-            v37 = (SoundID)135;
-            goto LABEL_93;
-          }
-          if ( pParty->pPickedItem.uItemID != 646 )
-          {
-            if ( pParty->pPickedItem.uItemID == 650 )
-            {
-              sub_44C28F_open_nwc_dungeon();
-              return;
-            }
-            goto LABEL_167;
-          }
-          pGame->pStru6Instance->SetPlayerBuffAnim(0x97u, a2 - 1);
-          v5 = 8 * a2 + 392;
-          LOBYTE(v5) = PID(OBJECT_Player,a2 - 120);
-          pAudioPlayer->PlaySound(SOUND_20001, v5, 0, -1, 0, 0, 0, 0);
-          v3->AddVariable(VAR_NumSkillPoints, 2);
-        }
+                {
+   
+                v68 = pParty->pPickedItem.GetDisplayName();
+                v58 = pGlobalTXT_LocalizationStrings[36];
+                sprintfex(pTmpBuf, v58, v68);
+                v23 = pTmpBuf;
+                ShowStatusBarString(v23, 2u);
+                v4 = 0;
+                v61 = v4;
+                v52 = v4;
+                v48 = v4;
+                v45 = v4;
+                v43 = -1;
+                v41 = v4;
+                v39 = v4;
+                v37 = (SoundID)27;
+                pAudioPlayer->PlaySound(v37, v39, v41, v43, v45, v48, v52, v61);
+                return;
+                }
+   
 LABEL_187:
         pMouse->RemoveHoldingItem();
         return;
-      }
-      if ( pParty->pPlayers[a2-1].CanAct() )
-      {
-        sub_467F48(pParty->pPickedItem.uItemID);
-        v65 = 0;
-        v56 = SPEECH_37;
-LABEL_67:
-        v3->PlaySound((PlayerSpeech)v56, v65);
-        return;
-      }
-LABEL_89:
-      v68 = aCharacterConditionNames[v3->GetMajorConditionIdx()];
-      v58 = pGlobalTXT_LocalizationStrings[382];
-LABEL_90:
-      sprintfex(pTmpBuf, v58, v68);
-      v23 = pTmpBuf;
-LABEL_91:
-      ShowStatusBarString(v23, 2u);
-      v4 = 0;
-      goto LABEL_92;
-    }
-    v15 = pParty->pPickedItem.uItemID - 400;
-    v72 = (char *)&v3->spellbook.pFireSpellbook+pParty->pPickedItem.uItemID-400;//(char *)&v3->pConditions[0] + pParty->pPickedItem.uItemID + 2;
-    if ( *v72 )
-    {
-      v66 = pParty->pPickedItem.GetDisplayName();
-      v57 = pGlobalTXT_LocalizationStrings[380];
-LABEL_72:
-      sprintf(pTmpBuf, v57, v66);
-      ShowStatusBarString(pTmpBuf, 2u);
-LABEL_92:
-      v61 = v4;
-      v52 = v4;
-      v48 = v4;
-      v45 = v4;
-      v43 = -1;
-      v41 = v4;
-      v39 = v4;
-      v37 = (SoundID)27;
-LABEL_93:
-      v14 = pAudioPlayer;
-LABEL_63:
-      pAudioPlayer->PlaySound(v37, v39, v41, v43, v45, v48, v52, v61);
-      return;
-    }
-    if ( !pParty->pPlayers[a2-1].CanAct() )
-    {
-      v66 = aCharacterConditionNames[v3->GetMajorConditionIdx()];
-      v57 = pGlobalTXT_LocalizationStrings[382];
-      goto LABEL_72;
-    }
-    v16 = v15 % 11 + 1;
-    v17 = &v3->pActiveSkills[v15 / 11 + 12];
-    v75 = v16;
-    v18 = SkillToMastery(*v17) - 1;
-    if ( v18 )
-    {
-      v19 = v18 - 1;
-      if ( v19 )
-      {
-        v20 = v19 - 1;
-        if ( v20 )
-        {
-          if ( v20 != 1 )
-          {
-            v21 = a2;
-LABEL_83:
-            if ( v75 > v21 || !*v17 )
-            {
-              v22 = pParty->pPickedItem.GetDisplayName();
-              sprintfex(pTmpBuf, pGlobalTXT_LocalizationStrings[381], v22);
-              ShowStatusBarString(pTmpBuf, 2u);
-              v65 = 0;
-              v56 = 20;
-              goto LABEL_67;
-            }
-            *v72 = 1;
-            v3->PlaySound(SPEECH_21, 0);
-            v73 = 0;
-LABEL_173:
-            v36 = pItemsTable->pItems[pParty->pPickedItem.uItemID].uEquipType;
-            if ( v36 == 14 )
-            {
-              v71 = 0;
-              v60 = 0;
-              v51 = 0;
-              v47 = 0;
-              v44 = -1;
-              v42 = 0;
-              v40 = 0;
-              v38 = (SoundID)210;
-            }
-            else
-            {
-              if ( v36 != 13 )
-              {
-LABEL_178:
-                if ( pGUIWindow_CurrentMenu && pGUIWindow_CurrentMenu->eWindowType != WINDOW_null)
-                {
-                  if ( !v73 )
-                    goto LABEL_187;
-                  /*if ( (signed int)pMessageQueue_50CBD0->uNumMessages < 40 )
-                  {
-                    pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].eType = UIMSG_Escape;
-                    pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = 0;
-                    *(&pMessageQueue_50CBD0->uNumMessages + 3 * pMessageQueue_50CBD0->uNumMessages + 3) = 0;
-                    ++pMessageQueue_50CBD0->uNumMessages;
-                  }*/
-                  pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 0, 0);
-                }
-                if ( v73 )
-                {
-                  if ( pParty->bTurnBasedModeOn )
-                  {
-                    *(&pParty->field_16140 + a2) = 100;
-                    thisb->SetRecoveryTime(100);
-                    pTurnEngine->_40471C();
-                  }
-                  else
-                  {
-                    thisb->SetRecoveryTime((signed __int64)(flt_6BE3A4_debug_recmod1 * 213.3333333333333));
-                  }
-                }
-                goto LABEL_187;
-              }
-              v71 = 0;
-              v60 = 0;
-              v51 = 0;
-              v47 = 0;
-              v44 = -1;
-              v42 = 0;
-              v40 = 0;
-              v38 = (SoundID)211;
-            }
-            pAudioPlayer->PlaySound(v38, v40, v42, v44, v47, v51, v60, v71);
-            goto LABEL_178;
-          }
-          v67 = 11;
         }
-        else
-        {
-          v67 = 10;
-        }
-      }
-      else
-      {
-        v67 = 7;
-      }
-    }
-    else
-    {
-      v67 = 4;
-    }
-    v21 = v67;
-    goto LABEL_83;
-  }
-  if ( pCurrentScreen == SCREEN_CASTING )
-    return;
-  if ( !pParty->pPlayers[a2-1].CanAct() )
-    goto LABEL_89;
-  if ( bUnderwater == 1 )
-  {
-    v23 = pGlobalTXT_LocalizationStrings[652];
-    goto LABEL_91;
-  }
-  dword_50C9AC = 1;
-  v24 = pParty->pPickedItem.uItemID - 299;
-  if ( pParty->pPickedItem.uItemID == 329 || v24 == 4 || v24 == 91 || v24 == 28 )
-  {
-    pMouse->RemoveHoldingItem();
-    pGUIWindow_CurrentMenu->Release();
-    pIcons_LOD->_4114F2();
-    pCurrentScreen = SCREEN_GAME;
-    viewparams->bRedrawGameUI = 1;
-    _42777D_CastSpell_UseWand_ShootArrow(v24, a2 - 1, 0x85u, 1, 0);
-  }
-  else
-  {
-    _720984_unused = pParty->pPickedItem.uItemID;
-    pMouse->RemoveHoldingItem();
-    /*if ( dword_50C9E8 < 40 )
-    {
-      dword_50C9EC[3 * dword_50C9E8] = 146;
-      dword_50C9EC[3 * dword_50C9E8 + 1] = v24;
-      dword_50C9EC[3 * dword_50C9E8 + 2] = a2 - 1;
-      ++dword_50C9E8;
-    }*/
-    pMessageQueue_50CBD0->AddMessage(UIMSG_92, 0, 0);
-    if ( pCurrentScreen
-      && pGUIWindow_CurrentMenu
-      && pGUIWindow_CurrentMenu->eWindowType != WINDOW_null)
-      //&& (signed int)pMessageQueue_50CBD0->uNumMessages < 40 )
-    {
-      /*pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].eType = UIMSG_Escape;
-      pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = 0;
-      *(&pMessageQueue_50CBD0->uNumMessages + 3 * pMessageQueue_50CBD0->uNumMessages + 3) = 0;
-      ++pMessageQueue_50CBD0->uNumMessages;*/
-      pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 0, 0);
-    }
-  }
-}
+
+    }
 
 
 
@@ -8648,19 +8524,19 @@
       v4->sResMindBase = 200;
       v4->sResBodyBase = 200;
       v11 = v4->GetSexByVoice();
-      v4->field_1924 = v4->uVoiceID;
-      v4->field_1928 = v4->uFace;
+      v4->uPrevVoiceID = v4->uVoiceID;
+      v4->uPrevFace = v4->uCurrentFace;
       if ( v11 )
       {
-        v4->uFace = 21;
+        v4->uCurrentFace = 21;
         v4->uVoiceID = 21;
       }
       else
       {
-        v4->uFace = 20;
+        v4->uCurrentFace = 20;
         v4->uVoiceID = 20;
       }
-      ReloadPlayerPortraits(currPlayerId, v4->uFace);
+      ReloadPlayerPortraits(currPlayerId, v4->uCurrentFace);
       goto LABEL_124;
     }
 LABEL_64:
--- a/Player.h	Tue May 21 11:24:26 2013 +0200
+++ b/Player.h	Tue May 21 11:24:35 2013 +0200
@@ -319,6 +319,11 @@
       PlayerSpellbookChapter pChapters[9];
       char _pad_1;
     };
+    struct
+        {
+        char bHaveSpell[99];
+        char _pad_1;
+        };
   };
 };
 #pragma pack(pop)
@@ -427,8 +432,8 @@
 #pragma pack(push, 1)
 struct Player
 {
-  enum Condition: unsigned __int32
-  {
+enum Condition: unsigned __int32
+    {
     Condition_Cursed = 0,
     Condition_Weak = 1,
     Condition_Sleep = 2,
@@ -448,7 +453,7 @@
     Condition_Eradicated = 16,
     Condition_Zombie = 17,
     Condition_Good = 18
-  };
+    };
 
   Player();
 
@@ -515,12 +520,12 @@
   int _48EA46_calc_special_bonus_by_items(int a2);
   int GetItemsBonus(enum CHARACTER_ATTRIBUTE_TYPE attr, int a3);
   int GetMagicalBonus(enum CHARACTER_ATTRIBUTE_TYPE a2);
-  char GetActualSkillLevel(PLAYER_SKILL_TYPE uSkillType);
+  int GetActualSkillLevel(PLAYER_SKILL_TYPE uSkillType);
   int GetSkillBonus(enum CHARACTER_ATTRIBUTE_TYPE a2);
   enum CHARACTER_RACE GetRace();
   PLAYER_SEX GetSexByVoice();
   void SetInitialStats();
-  int SetSexByVoice();
+  void SetSexByVoice();
   void Reset(PLAYER_CLASS_TYPE classType);
   PLAYER_SKILL_TYPE GetSkillIdxByOrder(signed int order);
   void DecreaseAttribute(int eAttribute);
@@ -542,11 +547,11 @@
   int CreateItemInInventory(unsigned int uSlot, unsigned int uItemID);
   int HasSkill(unsigned int uSkillType);
   int WearItem(unsigned int uItemID);
-  int AddItem(unsigned int uSlot, unsigned int uItemID);
-  int AddItem2(unsigned int uSlot, ItemGen *Src);
+  int AddItem(int uSlot, unsigned int uItemID);
+  int AddItem2(int uSlot, ItemGen *Src);
   int CreateItemInInventory2(unsigned int uSlot, ItemGen *Src);
-  bool _49298B(ItemGen *a2, int a3, int a4);
-  unsigned int RemoveItemAtInventoryIndex(unsigned int uSlot);
+  int PutItemArInventoryIndex(ItemGen *item, int item_id, int uSlot);
+  void RemoveItemAtInventoryIndex(unsigned int uSlot);
   bool CanAct();
   bool CanSteal();
   bool CanEquip_RaceAndAlignmentCheck(unsigned int uItemID);
@@ -554,7 +559,7 @@
   int _49327B(unsigned int uClass, int a3);
   void PlaySound(PlayerSpeech speech, int a3);
   void PlayEmotion(CHARACTER_EXPRESSION_ID expression, int a3);
-  char _4160CA(int a2);
+  void ItemsEnchant(int enchant_count);
   unsigned int GetItemIDAtInventoryIndex(int *a2);
   int _4B6FF9();
   int _4B824B(float a2);
@@ -568,7 +573,7 @@
   int _4B807C(float a2);
   int _4B8040_condition_time(unsigned int uCondition);
   bool _43EEF3();
-  void SalesProcess(unsigned int a2, int a3, int _2devent_idx);//0x4BE2DD
+  void SalesProcess(unsigned int inventory_idnx, int item_index, int _2devent_idx);//0x4BE2DD
   bool Recover(signed int a2);
   bool CanCastSpell(unsigned int uRequiredMana);
 
@@ -606,7 +611,7 @@
   char pName[16];
   PLAYER_SEX uSex;
   PLAYER_CLASS_TYPE classType;
-  unsigned __int8 uFace;
+  unsigned __int8 uCurrentFace;
   char field_BB;
   unsigned __int16 uMight;
   unsigned __int16 uMightBonus;
@@ -682,10 +687,25 @@
   };
   unsigned char _guilds_member_bits[64];
   PlayerSpells spellbook;
-  char field_1F5[30]; // used to be [31]
-  ItemGen pInventoryItems[126];
-  ItemGen pEquippedItems[12];
-  int pInventoryIndices[126];
+  char field__1F5[2]; // used to be [31]
+  int pure_luck_used;      
+  int pure_speed_used; 
+  int pure_intellect_used;  
+  int pure_endurance_used;  
+  int pure_willpower_used;       
+  int pure_accuracy_used;      
+  int pure_might_used;    
+  union  //214h
+      {
+      struct  
+          {
+          ItemGen pInventoryItems[126];
+          ItemGen pEquippedItems[12];
+      };
+      ItemGen pOwnItems[138];
+      };
+  
+    int pInventoryIndices[126];  
   __int16 sResFireBase;
   __int16 sResAirBase;
   __int16 sResWaterBase;
@@ -710,8 +730,8 @@
   __int16 sResDarkBonus;
   SpellBuff pPlayerBuffs[24];
   unsigned int uVoiceID;
-  int field_1924;
-  int field_1928;
+  int uPrevVoiceID;
+  int uPrevFace;
   int field_192C;
   int field_1930;
   unsigned __int16 uTimeToRecovery;
--- a/Render.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/Render.cpp	Tue May 21 11:24:35 2013 +0200
@@ -1,5 +1,13 @@
 #include <assert.h>
 
+#include "VideoPlayer.h"
+#include "Sprites.h"
+#include "Mouse.h"
+#include "GammaControl.h"
+#include "stru6.h"
+
+#include "DecalBuilder.h"
+#include "ParticleEngine.h"
 #include "Render.h"
 #include "OutdoorCamera.h"
 #include "IndoorCamera.h"
--- a/Render.h	Tue May 21 11:24:26 2013 +0200
+++ b/Render.h	Tue May 21 11:24:35 2013 +0200
@@ -4,7 +4,6 @@
 #include "lib\legacy_dx\d3d.h"
 #include "OSAPI.h"
 
-#include "Sprites.h"
 #include "VectorTypes.h"
 
 struct stru148;
@@ -46,7 +45,8 @@
   Vec2_float_ texcoord;
 };
 
-
+class Sprite;
+class SpriteFrame;
 
 /*  161 */
 #pragma pack(push, 1)
--- a/SaveLoad.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/SaveLoad.cpp	Tue May 21 11:24:35 2013 +0200
@@ -3,7 +3,7 @@
 #include <assert.h>
 
 #include "SaveLoad.h"
-#include "NPC.h"
+#include "BSPModel.h"
 #include "Party.h"
 #include "LOD.h"
 #include "Outdoor.h"
--- a/Spells.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/Spells.cpp	Tue May 21 11:24:35 2013 +0200
@@ -4,7 +4,6 @@
 #include "Overlays.h"
 #include "Allocator.h"
 #include "LOD.h"
-#include "stru123.h"
 #include "texts.h"
 
 #include "mm7_data.h"
--- a/SpriteObject.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/SpriteObject.cpp	Tue May 21 11:24:35 2013 +0200
@@ -1,5 +1,6 @@
 #include <assert.h>
 
+#include "BSPModel.h"
 #include "SpriteObject.h"
 #include "Party.h"
 #include "TurnEngine.h"
--- a/Sprites.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/Sprites.cpp	Tue May 21 11:24:35 2013 +0200
@@ -1,4 +1,5 @@
 #include <string.h>
+#include <algorithm>
 
 #include "Allocator.h"
 #include "Sprites.h"
@@ -217,75 +218,43 @@
 
 //----- (0044D813) --------------------------------------------------------
 signed int SpriteFrameTable::FastFindSprite( char *pSpriteName )
-    {
-  SpriteFrameTable *v2; // esi@1
-  int v3; // eax@1
+{
   signed int result; // eax@2
 
-  v2 = this;
-  BinarySearch(0, this->uNumEFrames, pSpriteName);
-  v3 = v2->field_8;
-  if ( v3 < 0 )
+  int searchResult = BinarySearch(pSpriteName);
+  if ( searchResult < 0 )
     result = 0;
   else
-    result = v2->pSpriteEFrames[v3];
+      result = this->pSpriteEFrames[searchResult];
   return result;
 }
 
 //----- (0044D83A) --------------------------------------------------------
-void SpriteFrameTable::BinarySearch(int a2, int a3, const char *pSpriteName)
+int SpriteFrameTable::BinarySearch( const char *pSpriteName )
 {
-  int v4; // ebx@1
-  SpriteFrameTable *v5; // edi@1
-  int v6; // esi@2
-  int v7; // eax@2
-  int a2a; // [sp+14h] [bp+8h]@2
-
-  v4 = a2;
-  v5 = this;
-  while ( 1 )
-  {
-    a2a = a3 - v4;
-    v6 = (a3 - v4) / 2 + v4;
-    v7 = _strcmpi(pSpriteName, v5->pSpritePFrames[v6]->pIconName);
-    if ( !v7 )
-      v5->field_8 = v6;
-    if ( v4 == a3 )
-      break;
-    if ( v7 >= 0 )
+    int startPos = 0;
+    int endPos = uNumEFrames;
+    while ( 1 )
     {
-      if ( a2a <= 4 )
-      {
-        while ( v4 < a3 )
+        int searchRange = endPos - startPos;
+        int middleFrameIndex = (endPos - startPos) / 2 + startPos;
+        int comparisonResult = _stricmp(pSpriteName, this->pSpritePFrames[middleFrameIndex]->pIconName);
+        if ( !comparisonResult )
         {
-          if ( !_strcmpi(pSpriteName, v5->pSpritePFrames[v4]->pIconName) )
-          {
-LABEL_19:
-            v5->field_8 = v4;
-            return;
-          }
-          ++v4;
+            return middleFrameIndex;
+        }
+        if ( startPos == endPos )
+        {
+            return -1;
         }
-        break;
-      }
-      v4 += (a3 - v4) / 2;
+        if ( comparisonResult >= 0 )
+        {
+            startPos += max(((endPos - startPos) / 2), 1);
+        }
+        else{
+            endPos = max(((endPos - startPos) / 2), 1) + startPos;
+        }
     }
-    else
-    {
-      if ( a2a <= 4 )
-      {
-        while ( v4 < a3 )
-        {
-          if ( !_strcmpi(pSpriteName, v5->pSpritePFrames[v4]->pIconName) )
-            goto LABEL_19;
-          ++v4;
-        }
-        break;
-      }
-      a3 = (a3 - v4) / 2 + v4;
-    }
-  }
-  v5->field_8 = -1;
 }
 
 //----- (0044D8D0) --------------------------------------------------------
--- a/Sprites.h	Tue May 21 11:24:26 2013 +0200
+++ b/Sprites.h	Tue May 21 11:24:35 2013 +0200
@@ -5,18 +5,18 @@
 #pragma pack(push, 1)
 struct Sprite  //28h
 {
-  void Release();
+    void Release();
 
-  const char *pName;  //0
-  int uPaletteID; //4
-  struct IDirectDrawSurface4 *pTextureSurface;  //8
-  struct IDirect3DTexture2 *pTexture;   //ch
-  int uAreaX;  //10h
-  int uAreaY;  //14h
-  int uBufferWidth;  //18h
-  int uBufferHeight;  //1ch
-  int uAreaWidth;  //20h
-  int uAreaHeight; //24h
+    const char *pName;  //0
+    int uPaletteID; //4
+    struct IDirectDrawSurface4 *pTextureSurface;  //8
+    struct IDirect3DTexture2 *pTexture;   //ch
+    int uAreaX;  //10h
+    int uAreaY;  //14h
+    int uBufferWidth;  //18h
+    int uBufferHeight;  //1ch
+    int uAreaWidth;  //20h
+    int uAreaHeight; //24h
 };
 #pragma pack(pop)
 
@@ -25,17 +25,17 @@
 #pragma pack(push, 1)
 struct SpriteFrame
 {
-  char pIconName[12]; 
-  char pTextureName[12]; //c
-  __int16 pHwSpriteIDs[8]; //18h
-  int scale; //28h
-  int uFlags; //2c
-  __int16 uGlowRadius; //30
-  __int16 uPaletteID;  //32
-  __int16 uPaletteIndex;
-  __int16 uAnimTime;
-  __int16 uAnimLength;
-  __int16 _pad;
+    char pIconName[12]; 
+    char pTextureName[12]; //c
+    __int16 pHwSpriteIDs[8]; //18h
+    int scale; //28h
+    int uFlags; //2c
+    __int16 uGlowRadius; //30
+    __int16 uPaletteID;  //32
+    __int16 uPaletteIndex;
+    __int16 uAnimTime;
+    __int16 uAnimLength;
+    __int16 _pad;
 };
 #pragma pack(pop)
 
@@ -43,31 +43,31 @@
 #pragma pack(push, 1)
 struct SpriteFrameTable
 {
-  //----- (0044D4BA) --------------------------------------------------------
-  inline SpriteFrameTable()
-  {
-    uNumSpriteFrames = 0;
-    pSpriteSFrames = nullptr;
-    pSpritePFrames = nullptr;
-    pSpriteEFrames = nullptr;
-  }
-  void ToFile();
-  void FromFile(void *pSerialized);
-  bool FromFileTxt(const char *Args);
-  void ReleaseSFrames();
-  void ResetSomeSpriteFlags();
-  void InitializeSprite(signed int uSpriteID);
-  signed int FastFindSprite(char *pSpriteName);
-  void BinarySearch(int a2, int a3, const char *pSpriteName);
-  SpriteFrame *GetFrame(unsigned int uSpriteID, unsigned int uTime);
-  SpriteFrame *GetFrameBy_x(unsigned int uSpriteID, signed int a3);
+    //----- (0044D4BA) --------------------------------------------------------
+    inline SpriteFrameTable()
+    {
+        uNumSpriteFrames = 0;
+        pSpriteSFrames = nullptr;
+        pSpritePFrames = nullptr;
+        pSpriteEFrames = nullptr;
+    }
+    void ToFile();
+    void FromFile(void *pSerialized);
+    bool FromFileTxt(const char *Args);
+    void ReleaseSFrames();
+    void ResetSomeSpriteFlags();
+    void InitializeSprite(signed int uSpriteID);
+    signed int FastFindSprite(char *pSpriteName);
+    int BinarySearch(const char *pSpriteName);
+    SpriteFrame *GetFrame(unsigned int uSpriteID, unsigned int uTime);
+    SpriteFrame *GetFrameBy_x(unsigned int uSpriteID, signed int a3);
 
-  signed int uNumSpriteFrames;
-  unsigned int uNumEFrames;//field_4;
-  int field_8;
-  struct SpriteFrame *pSpriteSFrames;  //0c
-  struct SpriteFrame **pSpritePFrames; //10h
-  __int16 *pSpriteEFrames; //14h
+    signed int uNumSpriteFrames;
+    unsigned int uNumEFrames;//field_4;
+    int unused_field;          //field_8
+    struct SpriteFrame *pSpriteSFrames;  //0c
+    struct SpriteFrame **pSpritePFrames; //10h
+    __int16 *pSpriteEFrames; //14h
 };
 #pragma pack(pop)
 
--- a/UIBooks.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/UIBooks.cpp	Tue May 21 11:24:35 2013 +0200
@@ -2,43 +2,21 @@
 
 #include "MM7.h"
 
+#include "Mouse.h"
+
 #include "MapInfo.h"
-#include "Game.h"
 #include "GUIWindow.h"
 #include "GUIFont.h"
-#include "GUIProgressBar.h"
 #include "Party.h"
 #include "AudioPlayer.h"
 #include "Outdoor.h"
-#include "IndoorCamera.h"
-#include "Overlays.h"
-#include "Monsters.h"
-#include "Arcomage.h"
 #include "LOD.h"
-#include "Actor.h"
 #include "Allocator.h"
-#include "Events.h"
 #include "Viewport.h"
-#include "FrameTableInc.h"
 #include "Math.h"
-#include "SpriteObject.h"
-#include "ObjectList.h"
-#include "Chest.h"
-#include "PaletteManager.h"
-#include "DecorationList.h"
-#include "SaveLoad.h"
-#include "stru123.h"
-#include "Time.h"
-#include "IconFrameTable.h"
 #include "Awards.h"
 #include "Autonotes.h"
-#include "stru160.h"
-#include "TurnEngine.h"
-#include "CastSpellInfo.h"
-#include "Weather.h"
-#include "stru298.h"
 #include "StorylineTextTable.h"
-#include "Events2D.h"
 #include "texts.h"
 
 #include "mm7_data.h"
@@ -286,7 +264,7 @@
     --v0;
   }
   while ( v0 >= -11 );
-  pIcons_LOD->_40F9C5();
+  pIcons_LOD->SyncLoadedFilesCount();
   v1 = pGUIWindow_CurrentMenu->pControlsHead;
   if ( v1 )
   {
--- a/UICharacter.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/UICharacter.cpp	Tue May 21 11:24:35 2013 +0200
@@ -11,34 +11,11 @@
 #include "AudioPlayer.h"
 #include "Outdoor.h"
 #include "IndoorCamera.h"
-#include "Overlays.h"
-#include "Monsters.h"
-#include "Arcomage.h"
 #include "LOD.h"
-#include "Actor.h"
-#include "Allocator.h"
-#include "Events.h"
 #include "Viewport.h"
-#include "FrameTableInc.h"
-#include "Math.h"
-#include "SpriteObject.h"
-#include "ObjectList.h"
-#include "Chest.h"
-#include "PaletteManager.h"
-#include "DecorationList.h"
-#include "SaveLoad.h"
-#include "stru123.h"
 #include "Time.h"
-#include "IconFrameTable.h"
 #include "Awards.h"
-#include "Autonotes.h"
-#include "stru160.h"
-#include "TurnEngine.h"
 #include "CastSpellInfo.h"
-#include "Weather.h"
-#include "stru298.h"
-#include "StorylineTextTable.h"
-#include "Events2D.h"
 #include "texts.h"
 
 #include "mm7_data.h"
@@ -87,6 +64,8 @@
 unsigned int ui_book_journal_title_color;
 unsigned int ui_book_journal_text_color;
 unsigned int ui_book_journal_text_shadow;
+
+
 void set_default_ui_skin()
 {
   ui_mainmenu_copyright_color = TargetColor(255, 255, 255);
@@ -1079,7 +1058,7 @@
       {
         case 529:
           v60 = 5;
-          v59 = papredoll_flying_feet[pPlayers[uPlayerID]->uFace];
+          v59 = papredoll_flying_feet[pPlayers[uPlayerID]->uCurrentFace];
           break;
         case 512:
           v60 = 6;
@@ -1278,12 +1257,12 @@
           }
         }
       }
-      if ( pPlayers[uPlayerID]->uFace == 12 || pPlayers[uPlayerID]->uFace == 13 )
+      if ( pPlayers[uPlayerID]->uCurrentFace == 12 || pPlayers[uPlayerID]->uCurrentFace == 13 )
       {
-        v122 = papredoll_dbrds[pPlayers[uPlayerID]->uFace];
+        v122 = papredoll_dbrds[pPlayers[uPlayerID]->uCurrentFace];
         if ( v122 != pIcons_LOD->FindTextureByName("Pending") )
-          pRenderer->DrawTextureTransparent(pPaperdoll_BodyX + pPaperdoll_Beards[2 * pPlayers[uPlayerID]->uFace - 24],
-                     pPaperdoll_BodyY + pPaperdoll_Beards[2 * pPlayers[uPlayerID]->uFace - 23],
+          pRenderer->DrawTextureTransparent(pPaperdoll_BodyX + pPaperdoll_Beards[2 * pPlayers[uPlayerID]->uCurrentFace - 24],
+                     pPaperdoll_BodyY + pPaperdoll_Beards[2 * pPlayers[uPlayerID]->uCurrentFace - 23],
                      pIcons_LOD->GetTexture(v122));
       }
     pHelmNum = pPlayers[uPlayerID]->pEquipment.uHelm;//äàëåå øëåì
@@ -1736,33 +1715,33 @@
       wsprintfA(pContainer, "pc23v%dlhu", v3);
       papredoll_dlhus[v0] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE); // Left Fist 2
       pPlayer = pPlayers[v0 + 1];
-      v5 = pPlayer->uFace;
+      v5 = pPlayer->uCurrentFace;
       if ( v5 == 12 || v5 == 13 )
         papredoll_dbrds[(char)v5] = 0;
-      papredoll_flying_feet[pPlayer->uFace] = 0;
+      papredoll_flying_feet[pPlayer->uCurrentFace] = 0;
       IsPlayerWearingWatersuit[v30 + 1] = 1;
     }
     else
     {
       v6 = v30;
-      papredoll_dbods[v30] = pIcons_LOD->LoadTexture(dbod_texnames_by_face[pPlayers[v30 + 1]->uFace], TEXTURE_16BIT_PALETTE);
-      papredoll_dlads[v30] = pIcons_LOD->LoadTexture(dlad_texnames_by_face[pPlayers[v30 + 1]->uFace], TEXTURE_16BIT_PALETTE);
-      papredoll_dlaus[v30] = pIcons_LOD->LoadTexture(dlau_texnames_by_face[pPlayers[v30 + 1]->uFace], TEXTURE_16BIT_PALETTE);
-      papredoll_drhs[v30] = pIcons_LOD->LoadTexture(drh_texnames_by_face[pPlayers[v30 + 1]->uFace], TEXTURE_16BIT_PALETTE);
-      papredoll_dlhs[v30] = pIcons_LOD->LoadTexture(dlh_texnames_by_face[pPlayers[v30 + 1]->uFace], TEXTURE_16BIT_PALETTE);
-      v7 = pIcons_LOD->LoadTexture(dlhu_texnames_by_face[pPlayers[v30 + 1]->uFace], TEXTURE_16BIT_PALETTE);
+      papredoll_dbods[v30] = pIcons_LOD->LoadTexture(dbod_texnames_by_face[pPlayers[v30 + 1]->uCurrentFace], TEXTURE_16BIT_PALETTE);
+      papredoll_dlads[v30] = pIcons_LOD->LoadTexture(dlad_texnames_by_face[pPlayers[v30 + 1]->uCurrentFace], TEXTURE_16BIT_PALETTE);
+      papredoll_dlaus[v30] = pIcons_LOD->LoadTexture(dlau_texnames_by_face[pPlayers[v30 + 1]->uCurrentFace], TEXTURE_16BIT_PALETTE);
+      papredoll_drhs[v30] = pIcons_LOD->LoadTexture(drh_texnames_by_face[pPlayers[v30 + 1]->uCurrentFace], TEXTURE_16BIT_PALETTE);
+      papredoll_dlhs[v30] = pIcons_LOD->LoadTexture(dlh_texnames_by_face[pPlayers[v30 + 1]->uCurrentFace], TEXTURE_16BIT_PALETTE);
+      v7 = pIcons_LOD->LoadTexture(dlhu_texnames_by_face[pPlayers[v30 + 1]->uCurrentFace], TEXTURE_16BIT_PALETTE);
       pPlayer2 = pPlayers[v30 + 1];
       papredoll_dlhus[v30] = v7;
-      v9 = (char *)&pPlayer2->uFace;
+      v9 = (char *)&pPlayer2->uCurrentFace;
       v10 = *v9;
       if ( *v9 == 12 || v10 == 13 )
       {
         wsprintfA(pContainer, "pc%02dbrd", v10 + 1);
-        v9 = (char *)&pPlayers[v6 + 1]->uFace;
+        v9 = (char *)&pPlayers[v6 + 1]->uCurrentFace;
         papredoll_dbrds[*v9] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
       }
       wsprintfA(pContainer, "item281pc%02d", *v9 + 1);
-      papredoll_flying_feet[pPlayers[v6 + 1]->uFace] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+      papredoll_flying_feet[pPlayers[v6 + 1]->uCurrentFace] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
       IsPlayerWearingWatersuit[v30 + 1] = 0;
     }
     ++v30;
@@ -2048,8 +2027,8 @@
 
 
 //----- (00418511) --------------------------------------------------------
-char CharacterUI_StatsTab_Draw(Player *player)
-{
+    void CharacterUI_StatsTab_Draw( Player *player )
+        {
         //Player *pPlayer; // edi@1
         //unsigned int v4; // eax@2
         int v7; // ebp@4
@@ -2342,7 +2321,7 @@
             v111 = UI_GetHealthManaStringColor(v136, 200);
             sprintf(pTmpBuf, format_4E2E00, pGlobalTXT_LocalizationStrings[29], v111, pGlobalTXT_LocalizationStrings[625]);
         }
-        return pGUIWindow_CurrentMenu->DrawText(pFontArrus, 266, v10, 0, pTmpBuf, 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontArrus, 266, v10, 0, pTmpBuf, 0, 0, 0);
 }
 
 //----- (00419100) --------------------------------------------------------
--- a/UIHouses.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/UIHouses.cpp	Tue May 21 11:24:35 2013 +0200
@@ -26,6 +26,7 @@
 #include "mm7_data.h"
 #include "Game.h"
 
+#include "stru159.h"
 int uHouse_ExitPic; // weak
 
 int dword_591080; // weak
@@ -3071,7 +3072,7 @@
       if( (v2 = pMouse->GetCursorPos(&a2)->x - 14, v106.x = (v2 >> 5) + 14 * ((pMouse->GetCursorPos(&v87)->y - 17) >> 5),
           pMouse->GetCursorPos(&v100)->x <= 13) || pMouse->GetCursorPos(&v92)->x >= 462
             || (pNumActiveItem = pPlayer->GetItemIDAtInventoryIndex((int *)&v106.x), !pNumActiveItem)
-            || (pNumActiveItem = 9 * pNumActiveItem, !(pPlayer->field_1F5[4 * pNumActiveItem + 15] & 2)) )
+            || (!(pPlayer->pOwnItems[pNumActiveItem-1].uAttributes& 2)) )
             return;
       v4 = (ItemGen *)&pPlayer->pInventoryItems[pNumActiveItem - 1];
       v10 = pPlayer->SelectPhrasesTransaction(v4, BildingType_ArmorShop, (int)window_SpeakInHouse->ptr_1C, 5);
@@ -4274,10 +4275,10 @@
             pMouse->GetCursorPos(&v140)->x <= 13)
             || pMouse->GetCursorPos(&v138)->x >= 462
             || (v32 = pPlayers[uActiveCharacter]->GetItemIDAtInventoryIndex((int *)&pItemCount), v11 = 0, !v32)
-            || (v33 = 9 * v32, !(pPlayers[uActiveCharacter]->field_1F5[4 * v33 + 15] & 2)) )
+            || (!(pPlayers[uActiveCharacter]->pOwnItems[v32-1].uAttributes& 2)) )
         return;
       v116 = &pPlayers[uActiveCharacter]->pInventoryItems[v33 - 1];
-      v35 = pPlayers[uActiveCharacter]->SelectPhrasesTransaction(&pPlayers[uActiveCharacter]->pInventoryItems[v33 - 1], BildingType_ArmorShop, (int)window_SpeakInHouse->ptr_1C, 5);
+      v35 = pPlayers[uActiveCharacter]->SelectPhrasesTransaction(&pPlayers[uActiveCharacter]->pInventoryItems[v32 - 1], BildingType_ArmorShop, window_SpeakInHouse->par1C, 5);
       v15 = (char *)pMerchantsRepairPhrases[v35];
       v36 = BuilDialogueString(v15, uActiveCharacter - 1, v116, (char *)window_SpeakInHouse->ptr_1C, 5, 0);
       v115 = (174 - pFontArrus->CalcTextHeight(v36, &dialog_window, 0, 0)) / 2 + 138;
@@ -5000,9 +5001,9 @@
             {
             if ( (unsigned int)v61 | v35 )
                 {
-                v37 = LOBYTE(v1->field_1928);
-                v38 = v1->field_1924;
-                v1->uFace = v37;
+                v37 = LOBYTE(v1->uPrevFace);
+                v38 = v1->uPrevVoiceID;
+                v1->uCurrentFace = v37;
                 v1->uVoiceID = v38;
                 ReloadPlayerPortraits(uActiveCharacter - 1, (char)v37);
                 }
@@ -5027,12 +5028,12 @@
               pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, v25);
               return;
             }
-            v1->field_1928 = v1->uFace;
-            v1->field_1924 = v1->uVoiceID;
+            v1->uPrevFace = v1->uCurrentFace;
+            v1->uPrevVoiceID = v1->uVoiceID;
             v1->SetCondition(0x11u, 1);
             v1->uVoiceID = (v1->GetSexByVoice() != 0) + 23;
             v40 = (v1->GetSexByVoice() != 0) + 23;
-            v1->uFace = v40;
+            v1->uCurrentFace = v40;
             ReloadPlayerPortraits(uActiveCharacter - 1, (char)v40);
             LODWORD(v1->pConditions[17]) = LODWORD(pParty->uTimePlayed);
             v39 = (GUIWindow *)HIDWORD(pParty->uTimePlayed);
@@ -6008,7 +6009,8 @@
           *(int *)result <= 13)
       || (result = (int)pMouse->GetCursorPos(&v104), *(int *)result >= 462)
       || (result = pPlayers[uActiveCharacter]->GetItemIDAtInventoryIndex((int *)&v117), v3 = 0, !result)
-      || (result *= 9, !(pPlayers[uActiveCharacter]->field_1F5[4 * result + 15] & 2)) )
+     // || (result *= 9, !(pPlayers[uActiveCharacter]->field_1F5[4 * result + 15] & 2)) )
+        || (!(pPlayers[uActiveCharacter]->pOwnItems[result-1].uAttributes& 2)) )
       return;
     item = &pPlayers[uActiveCharacter]->pInventoryItems[result - 1];
     v29 = pPlayers[uActiveCharacter]->SelectPhrasesTransaction(&pPlayers[uActiveCharacter]->pInventoryItems[result - 1], BildingType_MagicShop, (int)window_SpeakInHouse->ptr_1C, 5);
--- a/UIHouses.h	Tue May 21 11:24:26 2013 +0200
+++ b/UIHouses.h	Tue May 21 11:24:35 2013 +0200
@@ -1,5 +1,4 @@
 #pragma once
-#include "stru159.h"
 
 enum HOUSE_DIALOGUE_MENU: unsigned __int32
 {
@@ -135,6 +134,5 @@
 
 extern int uHouse_ExitPic; // weak
 extern int dword_591080; // weak
-extern  const stru159 pAnimatedRooms[196];
 extern int in_current_building_type; // 00F8B198
 extern HOUSE_DIALOGUE_MENU dialog_menu_id; // 00F8B19C
\ No newline at end of file
--- a/UIMainMenu.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/UIMainMenu.cpp	Tue May 21 11:24:35 2013 +0200
@@ -2,6 +2,9 @@
 
 #include "MM7.h"
 
+#include "Mouse.h"
+#include "Keyboard.h"
+
 #include "MapInfo.h"
 #include "Game.h"
 #include "GUIWindow.h"
--- a/UIOptions.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/UIOptions.cpp	Tue May 21 11:24:35 2013 +0200
@@ -2,6 +2,13 @@
 
 #include "MM7.h"
 
+#include "Keyboard.h"
+#include "IndoorCameraD3D.h"
+#include "CShow.h"
+#include "GammaControl.h"
+#include "stru6.h"
+#include "stru9.h"
+
 #include "MapInfo.h"
 #include "Game.h"
 #include "GUIWindow.h"
@@ -52,7 +59,7 @@
 
 
 //----- (004142D3) --------------------------------------------------------
-char __cdecl GameMenuUI_DrawKeyBindings()
+void GameMenuUI_DrawKeyBindings()
     {
     unsigned int v0; // ebp@1
     int v1; // ecx@2
@@ -284,7 +291,7 @@
         v62 = pKeyActionMap->GetVKeyDisplayName(pWindowList_at_506F50_minus1_indexing[0]);
         v59 = sub_414D24(27);
         }
-    return pGUIWindow_CurrentMenu->DrawText(pFontLucida, v22, 268, v59, v62, 0, 0, 0);
+     pGUIWindow_CurrentMenu->DrawText(pFontLucida, v22, 268, v59, v62, 0, 0, 0);
     }
 
 
--- a/UIPartyCreation.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/UIPartyCreation.cpp	Tue May 21 11:24:35 2013 +0200
@@ -2,6 +2,20 @@
 
 #include "MM7.h"
 
+#include "LightmapBuilder.h"
+#include "DecalBuilder.h"
+#include "ParticleEngine.h"
+#include "Mouse.h"
+#include "Keyboard.h"
+#include "IndoorCameraD3D.h"
+#include "CShow.h"
+#include "GammaControl.h"
+#include "stru6.h"
+#include "stru9.h"
+#include "stru10.h"
+#include "stru11.h"
+#include "stru12.h"
+
 #include "MapInfo.h"
 #include "Game.h"
 #include "GUIWindow.h"
@@ -93,7 +107,7 @@
     for (uint i = 0; i < 4; ++i)
         for (uint j = 0; j < 56; ++j)
             {
-            sprintf(pTmpBuf, "%s%02d", pPlayerPortraitsNames[pParty->pPlayers[i].uFace], j + 1);
+            sprintf(pTmpBuf, "%s%02d", pPlayerPortraitsNames[pParty->pPlayers[i].uCurrentFace], j + 1);
             pTextures_PlayerFaces[i][j] = pIcons_LOD->LoadTexturePtr(pTmpBuf, TEXTURE_16BIT_PALETTE);
             }
 
@@ -199,10 +213,10 @@
 
   pTextCenter = pFontCChar->AlignText_Center(640, pGlobalTXT_LocalizationStrings[51]);
   pGUIWindow_CurrentMenu->DrawText(pFontCChar, pTextCenter + 1, 0, 0, pGlobalTXT_LocalizationStrings[51], 0, 0, 0);
-  pRenderer->DrawTextureTransparent(17, 35, pPlayerPortraits[pParty->pPlayers[0].uFace]);
-  pRenderer->DrawTextureTransparent(176, 35, pPlayerPortraits[pParty->pPlayers[1].uFace]);
-  pRenderer->DrawTextureTransparent(335, 35, pPlayerPortraits[pParty->pPlayers[2].uFace]);
-  pRenderer->DrawTextureTransparent(494, 35, pPlayerPortraits[pParty->pPlayers[3].uFace]);
+  pRenderer->DrawTextureTransparent(17, 35, pPlayerPortraits[pParty->pPlayers[0].uCurrentFace]);
+  pRenderer->DrawTextureTransparent(176, 35, pPlayerPortraits[pParty->pPlayers[1].uCurrentFace]);
+  pRenderer->DrawTextureTransparent(335, 35, pPlayerPortraits[pParty->pPlayers[2].uCurrentFace]);
+  pRenderer->DrawTextureTransparent(494, 35, pPlayerPortraits[pParty->pPlayers[3].uCurrentFace]);
   pFrame = pIconsFrameTable->GetFrame(uIconID_CharacterFrame, pEventTimer->uStartTime);
 
 
--- a/UIPopup.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/UIPopup.cpp	Tue May 21 11:24:35 2013 +0200
@@ -2,6 +2,10 @@
 
 #include "MM7.h"
 
+#include "Mouse.h"
+
+#include "Sprites.h"
+#include "Vis.h"
 #include "MapInfo.h"
 #include "Game.h"
 #include "GUIWindow.h"
@@ -336,7 +340,7 @@
         if ( !areWeLoadingTexture )
             {
             v73->Release();
-            pIcons_LOD->_40F9C5();
+            pIcons_LOD->SyncLoadedFilesCount();
             }
         return;
         }
@@ -360,7 +364,7 @@
         if ( !areWeLoadingTexture )
             {
             v73->Release();
-            pIcons_LOD->_40F9C5();
+            pIcons_LOD->SyncLoadedFilesCount();
             }
         return;
         }
@@ -577,7 +581,7 @@
                         if ( !areWeLoadingTexture )
                             {
                             v73->Release();
-                            pIcons_LOD->_40F9C5();
+                            pIcons_LOD->SyncLoadedFilesCount();
                             }
                         return;
                         }
@@ -598,7 +602,7 @@
             if ( !areWeLoadingTexture )
                 {
                 v73->Release();
-                pIcons_LOD->_40F9C5();
+                pIcons_LOD->SyncLoadedFilesCount();
                 }
             return;
     }
@@ -1543,8 +1547,8 @@
     }
 
 //----- (00417FE5) --------------------------------------------------------
-char __cdecl CharacterUI_SkillsTab_ShowHint()
-    {
+    void CharacterUI_SkillsTab_ShowHint()
+        {
     unsigned int v0; // ecx@1
     unsigned int v1; // eax@1
     GUIButton *i; // esi@6
@@ -1574,9 +1578,9 @@
         }
     else
         {
-        LOBYTE(v1) = sub_4179BC_draw_tooltip(pGlobalTXT_LocalizationStrings[207], pSkillPointsAttributeDescription);
+        sub_4179BC_draw_tooltip(pGlobalTXT_LocalizationStrings[207], pSkillPointsAttributeDescription);
         }
-    return v1;
+    
     }
 
 //----- (00418083) --------------------------------------------------------
--- a/UIRest.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/UIRest.cpp	Tue May 21 11:24:35 2013 +0200
@@ -4,6 +4,7 @@
 
 #include "MapInfo.h"
 #include "Game.h"
+#include "Player.h"
 #include "GUIWindow.h"
 #include "GUIFont.h"
 #include "GUIProgressBar.h"
@@ -113,114 +114,111 @@
 //----- (0041FA01) --------------------------------------------------------
 void __cdecl RestUI_Draw()
     {
-    int v0; // esi@1
-    Player **ppPlayers; // ecx@1
-    Player *pPlayer; // eax@2
+    int live_characters; // esi@1
     unsigned int v3; // eax@15
     //char v4; // al@17
     bool v5; // eax@21
-    GUIButton Dst; // [sp+8h] [bp-DCh]@19
+    GUIButton tmp_button; // [sp+8h] [bp-DCh]@19
     //double v7; // [sp+C4h] [bp-20h]@17
     float v8; // [sp+CCh] [bp-18h]@17
     __int64 v9; // [sp+D0h] [bp-14h]@17
-    unsigned int v10; // [sp+D8h] [bp-Ch]@9
-    __int16 a9[2]; // [sp+DCh] [bp-8h]@1
-    int a5; // [sp+E0h] [bp-4h]@1
+    unsigned int am_pm_hours; // [sp+D8h] [bp-Ch]@9
+    __int16 shadow_color; // [sp+DCh] [bp-8h]@1
+    int text_color; // [sp+E0h] [bp-4h]@1
 
-    v0 = 0;
-    a5 = TargetColor(0xAu, 0, 0);
-    *(int *)a9 = TargetColor(0xE6u, 0xD6u, 0xC1u);
-    ppPlayers = &pPlayers[1];
-    do
+    live_characters = 0;
+    text_color =   TargetColor(10, 0, 0);
+    shadow_color = TargetColor(230, 214, 193);
+    for(int i=1; i<5; ++i)
+        if ( !pPlayers[i]->pConditions[Player::Condition_Dead] && !pPlayers[i]->pConditions[Player::Condition_Eradicated] && pPlayers[i]->sHealth > 0 )
+            ++live_characters;
+
+    if ( live_characters )
         {
-        pPlayer = *ppPlayers;
-        if ( !(*ppPlayers)->pConditions[14] && !pPlayer->pConditions[16] && pPlayer->sHealth > 0 )
-            ++v0;
-        ++ppPlayers;
-        }
-        while ( (signed int)ppPlayers <= (signed int)&pPlayers[4] );
-        if ( v0 )
+        pRenderer->DrawTextureIndexed(8, 8, pIcons_LOD->GetTexture(uTextureID_RestUI_restmain));
+        am_pm_hours = pParty->uCurrentHour;
+        dword_506F1C = pGUIWindow_CurrentMenu->pCurrentPosActiveItem;
+        if ( (signed int)pParty->uCurrentHour <= 12 )
             {
-            pRenderer->DrawTextureIndexed(8, 8, pIcons_LOD->GetTexture(uTextureID_RestUI_restmain));
-            v10 = pParty->uCurrentHour;
-            dword_506F1C = pGUIWindow_CurrentMenu->pCurrentPosActiveItem;
-            if ( (signed int)pParty->uCurrentHour <= 12 )
-                {
-                if ( !v10 )
-                    v10 = 12;
-                }
-            else
-                {
-                v10 -= 12;
-                }
-            pRenderer->DrawTextureIndexed(16u, 26u, pTexture_RestUI_CurrentSkyFrame);
-            if ( pTexture_RestUI_CurrentHourglassFrame )
-                {
-                pTexture_RestUI_CurrentHourglassFrame->Release();
-                pIcons_LOD->_40F9C5();
-                }
-            v3 = pEventTimer->uTimeElapsed + _507CD4_RestUI_hourglass_anim_controller;
-            _507CD4_RestUI_hourglass_anim_controller += pEventTimer->uTimeElapsed;
-            if ( (unsigned int)_507CD4_RestUI_hourglass_anim_controller >= 512 )
-                {
-                v3 = 0;
-                _507CD4_RestUI_hourglass_anim_controller = 0;
-                }
-            v9 = v3;
-            v8 = (double)v3 / 512.0 * 120.0;
-            //v7 = v8 + 6.7553994e15;
-            HIDWORD(v9) = floorf(v8 + 0.5f);//LODWORD(v7);
-            hourglass_icon_idx = (int)floorf(v8 + 0.5f) % 256 + 1;//LOBYTE(v7) + 1;
-            //hourglass_icon_idx = v4;
-            if (hourglass_icon_idx >= 120 )
-                {
-                //v4 = 1;
-                hourglass_icon_idx = 1;
-                }
-            sprintf(pTmpBuf, "hglas%03d", hourglass_icon_idx);
-            pTexture_RestUI_CurrentHourglassFrame = pIcons_LOD->LoadTexturePtr(pTmpBuf, TEXTURE_16BIT_PALETTE);
-            pRenderer->DrawTextureIndexed(0x10Bu, 0x9Fu, pTexture_RestUI_CurrentHourglassFrame);
-            memset(&Dst, 0, 0xBCu);
-            Dst.uX = 24;
-            Dst.uY = 154;
-            Dst.uWidth = 171;
-            Dst.uHeight = 37;
-            Dst.uZ = 194;
-            Dst.uW = 190;
-            Dst.pParent = pButton_RestUI_WaitUntilDawn->pParent;
-            Dst.DrawLabel(pGlobalTXT_LocalizationStrings[183], pFontCreate, a5, *(int **)a9);
-            Dst.pParent = 0;
-            sprintf(pTmpBuf, "\r408%d", uRestUI_FoodRequiredToRest);
-            pGUIWindow_CurrentMenu->DrawText(pFontCreate, 0, 164, a5, pTmpBuf, 0, 0, *(unsigned int *)a9);
-            pButton_RestUI_WaitUntilDawn->DrawLabel(pGlobalTXT_LocalizationStrings[237], pFontCreate, a5, *(int **)a9);
-            pButton_RestUI_Wait1Hour->DrawLabel(pGlobalTXT_LocalizationStrings[239], pFontCreate, a5, *(int **)a9);
-            pButton_RestUI_Wait5Minutes->DrawLabel(pGlobalTXT_LocalizationStrings[238], pFontCreate, a5, *(int **)a9);
-            pButton_RestUI_Exit->DrawLabel(pGlobalTXT_LocalizationStrings[81], pFontCreate, a5, *(int **)a9);
-            memset(&Dst, 0, 0xBCu);
-            Dst.uX = 45;
-            Dst.uY = 199;
-            Dst.uWidth = 185;
-            Dst.uHeight = 30;
-            Dst.uZ = 229;
-            Dst.uW = 228;
-            Dst.pParent = pButton_RestUI_WaitUntilDawn->pParent;
-            Dst.DrawLabel(pGlobalTXT_LocalizationStrings[236], pFontCreate, a5, *(int **)a9);
-            Dst.pParent = 0;
-            v5 = pParty->uCurrentHour >= 0xC && pParty->uCurrentHour < 0x18;
-            sprintf(pTmpBuf, "%d:%02d %s", v10, pParty->uCurrentMinute, aAMPMNames[v5]);
-            pGUIWindow_CurrentMenu->DrawText(pFontCreate, 368, 168, a5, pTmpBuf, 0, 0, *(unsigned int *)a9);
-            sprintf(pTmpBuf, "%s\r190%d", pGlobalTXT_LocalizationStrings[56], pParty->uDaysPlayed + 1);
-            pGUIWindow_CurrentMenu->DrawText(pFontCreate, 350, 190, a5, pTmpBuf, 0, 0, *(unsigned int *)a9);
-            sprintf(pTmpBuf, "%s\r190%d", pGlobalTXT_LocalizationStrings[146], pParty->uCurrentMonth + 1);
-            pGUIWindow_CurrentMenu->DrawText(pFontCreate, 350, 222, a5, pTmpBuf, 0, 0, *(unsigned int *)a9);
-            sprintf(pTmpBuf, "%s\r190%d", pGlobalTXT_LocalizationStrings[245], pParty->uCurrentYear);
-            pGUIWindow_CurrentMenu->DrawText(pFontCreate, 350, 254, a5, pTmpBuf, 0, 0, *(unsigned int *)a9);
-            if ( dword_506F14 )
-                Sleep6Hours();
+            if ( !am_pm_hours )
+                am_pm_hours = 12;
             }
         else
+            {
+            am_pm_hours -= 12;
+            }
+        pRenderer->DrawTextureIndexed(16u, 26u, pTexture_RestUI_CurrentSkyFrame);
+        if ( pTexture_RestUI_CurrentHourglassFrame )
+            {
+            pTexture_RestUI_CurrentHourglassFrame->Release();
+            pIcons_LOD->SyncLoadedFilesCount();
+            }
+        v3 = pEventTimer->uTimeElapsed + _507CD4_RestUI_hourglass_anim_controller;
+        _507CD4_RestUI_hourglass_anim_controller += pEventTimer->uTimeElapsed;
+        if ( (unsigned int)_507CD4_RestUI_hourglass_anim_controller >= 512 )
+            {
+            v3 = 0;
+            _507CD4_RestUI_hourglass_anim_controller = 0;
+            }
+        v9 = v3;
+        v8 = (double)v3 / 512.0 * 120.0;
+        //v7 = v8 + 6.7553994e15;
+        HIDWORD(v9) = floorf(v8 + 0.5f);//LODWORD(v7);
+        hourglass_icon_idx = (int)floorf(v8 + 0.5f) % 256 + 1;//LOBYTE(v7) + 1;
+        //hourglass_icon_idx = v4;
+        if (hourglass_icon_idx >= 120 )
+            hourglass_icon_idx = 1;
+
+        sprintf(pTmpBuf, "hglas%03d", hourglass_icon_idx);
+        pTexture_RestUI_CurrentHourglassFrame = pIcons_LOD->LoadTexturePtr(pTmpBuf, TEXTURE_16BIT_PALETTE);
+        pRenderer->DrawTextureIndexed(267, 159, pTexture_RestUI_CurrentHourglassFrame);
+        memset(&tmp_button, 0, sizeof(GUIButton));
+        tmp_button.uX = 24;
+        tmp_button.uY = 154;
+
+        tmp_button.uZ = 194;
+        tmp_button.uW = 190;
+
+        tmp_button.uWidth = 171;
+        tmp_button.uHeight = 37;
+
+        tmp_button.pParent = pButton_RestUI_WaitUntilDawn->pParent;
+        tmp_button.DrawLabel(pGlobalTXT_LocalizationStrings[183], pFontCreate, text_color, shadow_color);
+        tmp_button.pParent = 0;
+        sprintf(pTmpBuf, "\r408%d", uRestUI_FoodRequiredToRest);
+        pGUIWindow_CurrentMenu->DrawText(pFontCreate, 0, 164, text_color, pTmpBuf, 0, 0, shadow_color);
+        pButton_RestUI_WaitUntilDawn->DrawLabel(pGlobalTXT_LocalizationStrings[237], pFontCreate, text_color, shadow_color);
+        pButton_RestUI_Wait1Hour->DrawLabel(pGlobalTXT_LocalizationStrings[239], pFontCreate, text_color, shadow_color);
+        pButton_RestUI_Wait5Minutes->DrawLabel(pGlobalTXT_LocalizationStrings[238], pFontCreate, text_color, shadow_color);
+        pButton_RestUI_Exit->DrawLabel(pGlobalTXT_LocalizationStrings[81], pFontCreate, text_color, shadow_color);
+        memset(&tmp_button, 0, sizeof(GUIButton));
+        tmp_button.uX = 45;
+        tmp_button.uY = 199;
+
+        tmp_button.uZ = 229;
+        tmp_button.uW = 228;
+
+        tmp_button.uWidth = 185;
+        tmp_button.uHeight = 30;
+
+        tmp_button.pParent = pButton_RestUI_WaitUntilDawn->pParent;
+        tmp_button.DrawLabel(pGlobalTXT_LocalizationStrings[236], pFontCreate, text_color, shadow_color);
+        tmp_button.pParent = 0;
+        v5 = (pParty->uCurrentHour >= 12 && pParty->uCurrentHour < 24)? 1:0;
+        sprintf(pTmpBuf, "%d:%02d %s", am_pm_hours, pParty->uCurrentMinute, aAMPMNames[v5]);
+        pGUIWindow_CurrentMenu->DrawText(pFontCreate, 368, 168, text_color, pTmpBuf, 0, 0, shadow_color);
+        sprintf(pTmpBuf, "%s\r190%d", pGlobalTXT_LocalizationStrings[56], pParty->uDaysPlayed + 1);
+        pGUIWindow_CurrentMenu->DrawText(pFontCreate, 350, 190, text_color, pTmpBuf, 0, 0, shadow_color);
+        sprintf(pTmpBuf, "%s\r190%d", pGlobalTXT_LocalizationStrings[146], pParty->uCurrentMonth + 1);
+        pGUIWindow_CurrentMenu->DrawText(pFontCreate, 350, 222, text_color, pTmpBuf, 0, 0, shadow_color);
+        sprintf(pTmpBuf, "%s\r190%d", pGlobalTXT_LocalizationStrings[245], pParty->uCurrentYear);
+        pGUIWindow_CurrentMenu->DrawText(pFontCreate, 350, 254, text_color, pTmpBuf, 0, 0, shadow_color);
+        if ( dword_506F14 )
+            Sleep6Hours();
+        }
+    else
         {
-          GUIWindow::Create(pButton_RestUI_Exit->uX, pButton_RestUI_Exit->uY, 0, 0, WINDOW_CloseRestWindowBtn,
-           (int)pButton_RestUI_Exit, (int)pGlobalTXT_LocalizationStrings[81]);
+        GUIWindow::Create(pButton_RestUI_Exit->uX, pButton_RestUI_Exit->uY, 0, 0, WINDOW_CloseRestWindowBtn,
+            (int)pButton_RestUI_Exit, (int)pGlobalTXT_LocalizationStrings[81]);
         }
     }
\ No newline at end of file
--- a/UISaveLoad.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/UISaveLoad.cpp	Tue May 21 11:24:35 2013 +0200
@@ -2,6 +2,9 @@
 #include <io.h>
 #include "MM7.h"
 
+#include "Mouse.h"
+#include "Keyboard.h"
+
 #include "MapInfo.h"
 #include "Game.h"
 #include "GUIWindow.h"
--- a/UiGame.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/UiGame.cpp	Tue May 21 11:24:35 2013 +0200
@@ -2,6 +2,22 @@
 
 #include "MM7.h"
 
+#include "BSPModel.h"
+#include "LightmapBuilder.h"
+#include "DecalBuilder.h"
+#include "ParticleEngine.h"
+#include "Mouse.h"
+#include "Keyboard.h"
+#include "IndoorCameraD3D.h"
+#include "CShow.h"
+#include "GammaControl.h"
+#include "stru6.h"
+#include "stru9.h"
+#include "stru10.h"
+#include "stru11.h"
+#include "stru12.h"
+
+#include "Vis.h"
 #include "MapInfo.h"
 #include "Game.h"
 #include "GUIWindow.h"
--- a/VectorTypes.h	Tue May 21 11:24:26 2013 +0200
+++ b/VectorTypes.h	Tue May 21 11:24:35 2013 +0200
@@ -16,20 +16,15 @@
   void Normalize();
 
   
-  //----- (0049B32D) --------------------------------------------------------
-  static Vec3_float_ *Vec3_float_::Cross(Vec3_float_ *v1, Vec3_float_ *pOut, float x, float y, float z)
-  {
-    double v6; // st7@1
-    double v7; // st6@1
+//----- (0049B32D) --------------------------------------------------------
+static Vec3_float_ *Vec3_float_::Cross(Vec3_float_ *v1, Vec3_float_ *pOut, float x, float y, float z)
+{
+  pOut->x = z * v1->y - y * v1->z;
+  pOut->y = x * v1->z - z * v1->x;
+  pOut->z = y * v1->x - x * v1->y;
+  return pOut;
+}
 
-    v6 = x * v1->z - z * v1->x;
-    v7 = y * v1->x - x * v1->y;
-    pOut->x = z * v1->y - y * v1->z;
-    pOut->y = v6;
-    pOut->z = v7;
-    return pOut;
-  }
- 
   //----- (0049B02E) --------------------------------------------------------
   inline static float NegDot(Vec3_float_ *a1, Vec3_float_ *a2, float *a3)
   {
--- a/VideoPlayer.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/VideoPlayer.cpp	Tue May 21 11:24:35 2013 +0200
@@ -2,6 +2,9 @@
 
 #include "Bink_Smacker.h"
 
+#include "CShow.h"
+#include "Mouse.h"
+
 #include "OSInfo.h"
 #include "VideoPlayer.h"
 #include "AudioPlayer.h"
--- a/Vis.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/Vis.cpp	Tue May 21 11:24:35 2013 +0200
@@ -1,5 +1,6 @@
 #include <assert.h>
 
+#include "BSPModel.h"
 #include "Vis.h"
 #include "Outdoor.h"
 #include "Game.h"
@@ -366,6 +367,8 @@
     auto bmodel = &pOutdoor->pBModels[i];
     for (uint j = 0; j < bmodel->uNumFaces; ++j)
     {
+		//if ( i == 77 && j == 17 )//
+		  //__debugbreak();//
       auto face = &bmodel->pFaces[j];
       if (is_part_of_selection(face, filter))
       {
@@ -541,7 +544,7 @@
 }
 
 //----- (004C1C0C) --------------------------------------------------------
-bool Vis::Intersect_Ray_Face(RenderVertexSoft *pRayStart, RenderVertexSoft *pRayEnd, float *pDepth, RenderVertexSoft *a4, BLVFace *a5, unsigned int a6)
+bool Vis::Intersect_Ray_Face(RenderVertexSoft *pRayStart, RenderVertexSoft *pRayEnd, float *pDepth, RenderVertexSoft *Intersection, BLVFace *pFace, unsigned int pBModelID)
 {
   //BLVFace *v7; // ebx@1
   //bool result; // eax@1
@@ -554,7 +557,7 @@
   //char v15; // c0@5
   //char v16; // c2@5
   //char v17; // c3@5
-  double v18; // st5@6
+  double c1; // st5@6
   //__int16 v19; // fps@6
   //char v20; // c0@6
   //char v21; // c2@6
@@ -568,25 +571,24 @@
   //unsigned __int8 v29; // c0@10
   //char v30; // c2@10
   //unsigned __int8 v31; // c3@10
-  //double v32; // st7@11
-  Vec2_short_ v33; // ST1E_4@11
+  double c2; // st7@11
+  //Vec2_short_ v33; // ST1E_4@11
   Vec3_short_ v34; // ST04_6@11
   //float a5a; // [sp+30h] [bp+18h]@10
   //float a5b; // [sp+30h] [bp+18h]@13
 
-  if (a5->Portal() || a5->Invisible())
+  if (pFace->Portal() || pFace->Invisible())
     return false;
 
-  
-  int ray_dir_x = pRayEnd->vWorldPosition.x - pRayStart->vWorldPosition.x,
-      ray_dir_y = pRayEnd->vWorldPosition.y - pRayStart->vWorldPosition.y,
+  int ray_dir_x = pRayEnd->vWorldPosition.x - pRayStart->vWorldPosition.x,//dir_x y z ýòî âåêòîð íàïðàâëåíèÿ
+      ray_dir_y = pRayEnd->vWorldPosition.y - pRayStart->vWorldPosition.y,//òî÷êà  - òî÷êà À  = âåêòîð èç À â Â
       ray_dir_z = pRayEnd->vWorldPosition.z - pRayStart->vWorldPosition.z;
 
-  v9 =   ray_dir_z * a5->pFacePlane.vNormal.z
-           + ray_dir_y  * a5->pFacePlane.vNormal.y
-           + ray_dir_x * a5->pFacePlane.vNormal.x;
+  /*v9 =   ray_dir_z * pFace->pFacePlane.vNormal.z
+           + ray_dir_y  * pFace->pFacePlane.vNormal.y//ñêàëÿðíîå ïðîèçâåäåíèå íàïðàâëåíèÿ ëó÷à è íîðìàëè ê ïîëèãîíó
+           + ray_dir_x * pFace->pFacePlane.vNormal.x;//= êîñèíóñ óãëà ìåæäó äâóìÿ âåêòîðàìè
   if (v9 >= 0)   // ray faces face's normal ( > 0) or parallel ( == 0)
-    return false;
+    return false;*/
 
 //ray   = t dir + start
 //plane = (p - vertex) normal = -d
@@ -599,116 +601,84 @@
 //               dir norm
 
 
-  float dir_mag = sqrtf(ray_dir_x * ray_dir_x + ray_dir_y * ray_dir_y + ray_dir_z * ray_dir_z);
-  float ndir_x = ray_dir_x / dir_mag,
-        ndir_y = ray_dir_y / dir_mag,
-        ndir_z = ray_dir_z / dir_mag;
+  /*float dir_mag = sqrtf(ray_dir_x * ray_dir_x + ray_dir_y * ray_dir_y + ray_dir_z * ray_dir_z);//ìîäóëü âåêòîðà
+  float ndir_x = ray_dir_x / dir_mag,//ndir - íîðìàëèçîâàííîå íàïðàâëåíèå
+        ndir_y = ray_dir_y / dir_mag,// ðåçóëüòàòå íîðìàëèçàöèè ïîëó÷àåòñÿ âåêòîð, íàïðàâëåíèå êîòîðîãî ñîâïàäàåò ñ èñõîäíûì, à ìîäóëü ðàâåí åäèíèöå (åäèíè÷íûé âåêòîð).
+        ndir_z = ray_dir_z / dir_mag;//×òîáû íîðìàëèçîâàòü ïðîèçâîëüíûé âåêòîð, äîñòàòî÷íî ðàçäåëèòü êàæäûé êîìïîíåíò âåêòîðà íà ìîäóëü âåêòîðà
 
-  int face_center_x = (a5->pBounding.x1 + a5->pBounding.x2) / 2,
-      face_center_y = (a5->pBounding.y1 + a5->pBounding.y2) / 2,
-      face_center_z = (a5->pBounding.z1 + a5->pBounding.z2) / 2;
+  int face_center_x = (pFace->pBounding.x1 + pFace->pBounding.x2) / 2,//óñðåäí¸ííûå êîîðäèíàòû áàóíäèíãà
+      face_center_y = (pFace->pBounding.y1 + pFace->pBounding.y2) / 2,
+      face_center_z = (pFace->pBounding.z1 + pFace->pBounding.z2) / 2;
 
-  int to_plane_x = pRayStart->vWorldPosition.x - face_center_x,
+  int to_plane_x = pRayStart->vWorldPosition.x - face_center_x,//âåêòîð èç ãëàñ ê ñåðåäèíå ôåéñà
       to_plane_y = pRayStart->vWorldPosition.y - face_center_y,
-      to_plane_z = pRayStart->vWorldPosition.z - face_center_z;
+      to_plane_z = pRayStart->vWorldPosition.z - face_center_z;*/
 
-  float t = /*-a5->pFacePlane.dist*/ - (to_plane_x * a5->pFacePlane.vNormal.x + to_plane_y * a5->pFacePlane.vNormal.y + to_plane_y * a5->pFacePlane.vNormal.z) /
-                   (ndir_x * a5->pFacePlane.vNormal.x + ndir_y * a5->pFacePlane.vNormal.y + ndir_z * a5->pFacePlane.vNormal.z);
-  if (t <= *pDepth)
+  //float t = /*-pFace->pFacePlane.dist*/ - (to_plane_x * pFace->pFacePlane.vNormal.x + to_plane_y * pFace->pFacePlane.vNormal.y + to_plane_y * pFace->pFacePlane.vNormal.z) /
+            //       (ndir_x * pFace->pFacePlane.vNormal.x + ndir_y * pFace->pFacePlane.vNormal.y + ndir_z * pFace->pFacePlane.vNormal.z);//íàñêîëüêî ñèëüíî ëó÷ èç êàìåðû îòêëîíÿåòñÿ îò ëó÷à äî öåíòðà ôåéñà
+/*  if (t <= *pDepth)
   {
     int intersection_x = pRayStart->vWorldPosition.x + ndir_x * t,
         intersection_y = pRayStart->vWorldPosition.y + ndir_y * t,
         intersection_z = pRayStart->vWorldPosition.z + ndir_z * t;
 
-    if (intersection_x < a5->pBounding.x1 || intersection_x > a5->pBounding.x2 ||
-        intersection_y < a5->pBounding.y1 || intersection_y > a5->pBounding.y2 ||
-        intersection_z < a5->pBounding.z1 || intersection_z > a5->pBounding.z2)
+    if (intersection_x < pFace->pBounding.x1 || intersection_x > pFace->pBounding.x2 ||
+        intersection_y < pFace->pBounding.y1 || intersection_y > pFace->pBounding.y2 ||
+        intersection_z < pFace->pBounding.z1 || intersection_z > pFace->pBounding.z2)
         return false;
 
-    a5->uAttributes |= 0x80000000;
+    pFace->uAttributes |= 0x80000000;
     return true;
   }
 
-  
-  return false;
+  return false;*/
 
-//  v7 = a5;
-  //result = a5->uAttributes;
-  v9 =   pRayEnd->vWorldPosition.z * a5->pFacePlane.vNormal.z
-           + pRayEnd->vWorldPosition.y * a5->pFacePlane.vNormal.y
-           + pRayEnd->vWorldPosition.x * a5->pFacePlane.vNormal.x;
-  if (v9 >= 0)   // ray faces face's normal ( > 0) or parallel ( == 0)
-    return false;
-  
-  a5->uAttributes |= 0x80000000;
-  return false;
 
-  v18 = -(a5->pFacePlane.vNormal.y * pRayStart->vWorldPosition.y
-        + pRayStart->vWorldPosition.x * a5->pFacePlane.vNormal.x
-        + pRayStart->vWorldPosition.z * a5->pFacePlane.vNormal.z
-        + a5->pFacePlane.dist);
-  if (v18 > 0)
-    return false;
-  //UNDEF(v19);
-  //v20 = v9 < 0.0;
-  //v21 = 0;
-  //v22 = v9 == 0.0;
-  //BYTE1(result) = HIBYTE(v19);
-  /*v23 = v18 < 0.0;
-  v24 = 0;
-  v25 = v18 == 0.0;
-  v26 = (BYTE1(result) & 0x41) == 0;
-  BYTE1(result) = HIBYTE(v19);
-  if ( v26 )
-  {
-    if ( v18 < 0.0 )
-      goto LABEL_12;
-  }
-  else
-  {
-    if ( !(v23 | v25) )
-    {
-LABEL_12:
-      LOBYTE(result) = 0;
-      return result;
-    }
-  }*/
-
-  //a5a = v18;
-  v27 = v18 / v9;
-  //HIWORD(result) = HIWORD(pDepth);
-  //UNDEF(v28);
-  //v29 = v27 < *pDepth;
-  //v30 = 0;
-  //v31 = v27 == *pDepth;
-  //BYTE1(result) = HIBYTE(v28);
-
-  if (v27 > *pDepth)
+//c1 = -d-(n*p0)
+  c1 = -pFace->pFacePlane.dist -(pFace->pFacePlane.vNormal.x * pRayStart->vWorldPosition.x
+        + pFace->pFacePlane.vNormal.y * pRayStart->vWorldPosition.y
+        + pFace->pFacePlane.vNormal.z * pRayStart->vWorldPosition.z);
+  //if (c1 > 0)
+    //return false;
+#define EPSILON 0.000001
+//c2 = n*u
+  c2 = pFace->pFacePlane.vNormal.x * ray_dir_y
+       + pFace->pFacePlane.vNormal.y * ray_dir_x 
+       + pFace->pFacePlane.vNormal.z * ray_dir_z;
+  if (c2 > -EPSILON && c2 < EPSILON)   // ray faces face's normal ( > 0) or parallel ( == 0)
     return false;
 
-  a5->uAttributes |= 0x80000000;
+//t = -d-(n*p0)/n*u
+  double t = c1 / c2;//òî÷êà ñîïðèêîñíîâåíèÿ
+
+  //if (t < 0 || t > 1)
+    //return false;
 
-  a4->vWorldPosition.x = v27 * pRayEnd->vWorldPosition.x + pRayStart->vWorldPosition.x;
-  a4->vWorldPosition.y = v27 * pRayEnd->vWorldPosition.y + pRayStart->vWorldPosition.y;
-  a4->vWorldPosition.z = v27 * pRayEnd->vWorldPosition.z + pRayStart->vWorldPosition.z;
-  v33.x = (signed __int64)a4->vWorldPosition.x;
-  v33.y = (signed __int64)a4->vWorldPosition.y;
-  v34.x = v33.x;
-  v34.y = 0;
-  v34.z = (signed __int64)a4->vWorldPosition.z;
+  // p(t) = p0 + tu;
+  // p(t) - âåêòîð óêàçûâàþùèé â òî÷êó íà ïëîñêîñòè
+  // p0 -  íà÷àëî âåêòîðà, òî÷êà íàáëþäàòåëÿ, êàìåðû
+  // t - 
+  // u - âåêòîð íàïðàâëåíèÿ
+  Intersection->vWorldPosition.x = pRayStart->vWorldPosition.x + t * ray_dir_y;//12432 < X < 12656
+  Intersection->vWorldPosition.y = pRayStart->vWorldPosition.y + t * ray_dir_x;//-96 < Y < 1088
+  Intersection->vWorldPosition.z = pRayStart->vWorldPosition.z + t * ray_dir_z;//Z == 192
+
+  v34.x = (signed __int64)Intersection->vWorldPosition.x;
+  v34.y = (signed __int64)Intersection->vWorldPosition.y;
+  v34.z = (signed __int64)Intersection->vWorldPosition.z;
         
-  if ( _4C1D2B(a5, v34, a6) == 0.0)
+  if ( !_4C1D2B(pFace, v34, pBModelID) )
     return false;
 
   //a5b = v27;
-  *pDepth = v27;
+  //*pDepth = t;
   return true;
 }
 
 //----- (004C1D2B) --------------------------------------------------------
-int Vis::_4C1D2B(BLVFace *pFace, Vec3_short_ a2, unsigned int uModelID)
+bool Vis::_4C1D2B(BLVFace *pFace, Vec3_short_ a2, unsigned int uModelID)
 {
-  BLVFace *v4; // esi@1
+  //BLVFace *v4; // esi@1
   int v5; // esi@10
   bool v6; // edi@10
   int v7; // ecx@12
@@ -722,14 +692,16 @@
   int v15; // [sp+10h] [bp-Ch]@10
   signed int v16; // [sp+18h] [bp-4h]@10
 
-  v4 = pFace;
-  if (a2.z < pFace->pBounding.z1 || a2.z > pFace->pBounding.z2 ||
-      a2.x < pFace->pBounding.x1 || a2.x > pFace->pBounding.x2 ||
-      a2.y < pFace->pBounding.y1 || a2.y > pFace->pBounding.y2)
+  //v4 = pFace;
+  if (a2.x < pFace->pBounding.x1 || a2.x > pFace->pBounding.x2 ||
+      a2.y < pFace->pBounding.y1 || a2.y > pFace->pBounding.y2 ||
+      a2.z < pFace->pBounding.z1 || a2.z > pFace->pBounding.z2 )
     return false;
 
+  pFace->uAttributes |= 0x80000000;
+  return true;
   if (uModelID != -1)
-    _4C2186_BLV_IntersectBModel((int *)&pFace, (int *)&uModelID,
+    _4C2186_BLV_IntersectBModel(pFace, uModelID,
                                 word_F8BC48_displaced_face_intersect_plane_coords_a,
                                 word_F8BD18_displaced_face_intersect_plane_coords_b,
                                 &a2, pFace, uModelID);
@@ -739,7 +711,7 @@
                                   word_F8BD18_displaced_face_intersect_plane_coords_b,
                                   &a2, pFace);
   
-  v5 = 2 * v4->uNumVertices;
+  v5 = 2 * pFace->uNumVertices;
   v16 = 0;
   word_F8BC48_displaced_face_intersect_plane_coords_a[v5] = word_F8BC48_displaced_face_intersect_plane_coords_a[0];
   word_F8BD18_displaced_face_intersect_plane_coords_b[v5] = word_F8BD18_displaced_face_intersect_plane_coords_b[0];
@@ -886,172 +858,131 @@
 }
 
 //----- (004C2186) --------------------------------------------------------
-bool Vis::_4C2186_BLV_IntersectBModel(int *a1, int *a2, __int16 *a3, __int16 *a4, Vec3_short_ *a5, BLVFace *a6, unsigned int uModelID)
+bool Vis::_4C2186_BLV_IntersectBModel(BLVFace *pFace, unsigned int ModelID, __int16 *displaced_face_intersect_plane_coords_a, __int16 *displaced_face_intersect_plane_coords_b, Vec3_short_ *a5, BLVFace *face, unsigned int uModelID)
 {
   bool result; // eax@1
-  int *v9; // esi@1
-  unsigned int v10; // ecx@1
-  unsigned int v11; // edx@3
-  signed int v12; // ecx@4
+  //int *v9; // esi@1
+  //unsigned int v10; // ecx@1
+  //unsigned int v11; // edx@3
+  //signed int v12; // ecx@4
   __int16 v13; // si@4
   __int16 *v14; // ecx@4
   unsigned int v15; // edx@8
-  signed int v16; // ecx@9
+  //signed int v16; // ecx@9
   __int16 v17; // si@9
   __int16 *v18; // ecx@9
   unsigned int v19; // edx@12
-  signed int v20; // ecx@13
+  //signed int v20; // ecx@13
   __int16 v21; // si@13
   __int16 *v22; // ecx@13
-  signed int a1a; // [sp+14h] [bp+8h]@1
+  //signed int a1a; // [sp+14h] [bp+8h]@1
   __int16 *a5a; // [sp+24h] [bp+18h]@3
   __int16 *a5b; // [sp+24h] [bp+18h]@8
   __int16 *a5c; // [sp+24h] [bp+18h]@12
 
-  result = (bool)a6;
-  v9 = a1;
-  v10 = a6->uAttributes;
-  a1a = 0;
-  if ( BYTE1(v10) & 1 )
+  //result = (bool)a6;
+  //v9 = pFace;
+  //v10 = pFace->uAttributes;
+  //a1a = 0;
+  if ( BYTE1(pFace->uAttributes) & 1 )
   {
-    *v9 = a5->x;
-    *a2 = a5->y;
-    if ( a6->uNumVertices )
+    pFace->pFacePlane.vNormal.x = a5->x;
+    pFace->pFacePlane.vNormal.y = a5->y;
+    if ( pFace->uNumVertices )
     {
-      v11 = 188 * uModelID + 72;
-      a5a = a4 + 1;
-      do
+      //v11 = 188 * ModelID + 72;
+      a5a = displaced_face_intersect_plane_coords_b + 1;
+      for ( uint i = 0; i < pFace->uNumVertices; ++i )
       {
-        v12 = a1a;
-        a3[2 * a1a] = a6->pXInterceptDisplacements[a1a]
-//                    + *(short *)(*(int *)&pOutdoor->pBModels->pModelName[v11] + 12 * a6->pVertexIDs[a1a]);
-					  + pOutdoor->pBModels[v11].pVertices.pVertices[a6->pVertexIDs[a1a]].x;
-        *(a5a - 1) = a6->pYInterceptDisplacements[v12]
-//                   + *(short *)(*(int *)&pOutdoor->pBModels->pModelName[v11] + 12 * a6->pVertexIDs[v12] + 4);
-					 + pOutdoor->pBModels[v11].pVertices.pVertices[a6->pVertexIDs[v12]].y;
-        *(__int16 *)((char *)a5a + (int)(char *)a3 - (char *)a4) = a6->pXInterceptDisplacements[v12 + 1]
-//                                                            + *(short *)(*(int *)&pOutdoor->pBModels->pModelName[v11]
-//                                                                       + 12 * a6->pVertexIDs[v12 + 1]);
-		+ pOutdoor->pBModels[v11].pVertices.pVertices[a6->pVertexIDs[v12+1]].x;
-        v13 = a6->pYInterceptDisplacements[v12 + 1]
-//            + *(short *)(*(int *)&pOutdoor->pBModels->pModelName[v11] + 12 * a6->pVertexIDs[v12 + 1] + 4);
-		+ pOutdoor->pBModels[v11].pVertices.pVertices[a6->pVertexIDs[v12 + 1]].y;
+        displaced_face_intersect_plane_coords_a[2 * i] = pFace->pXInterceptDisplacements[i] + pOutdoor->pBModels[ModelID].pVertices.pVertices[pFace->pVertexIDs[i]].x;
+        displaced_face_intersect_plane_coords_b[2 * i] = pFace->pYInterceptDisplacements[i] + pOutdoor->pBModels[ModelID].pVertices.pVertices[pFace->pVertexIDs[i]].y;
+        *(__int16 *)((char *)a5a + (int)(char *)displaced_face_intersect_plane_coords_a - (char *)displaced_face_intersect_plane_coords_b) = 
+          pFace->pXInterceptDisplacements[i + 1] + pOutdoor->pBModels[ModelID].pVertices.pVertices[pFace->pVertexIDs[i + 1]].x;
+        v13 = pFace->pYInterceptDisplacements[i + 1] + pOutdoor->pBModels[ModelID].pVertices.pVertices[pFace->pVertexIDs[i + 1]].y;
         v14 = a5a;
-        ++a1a;
         a5a += 2;
         *v14 = v13;
       }
-      while ( a1a < a6->uNumVertices );
     }
   }
   else
   {
-    if ( BYTE1(v10) & 2 )
+    if ( BYTE1(pFace->uAttributes) & 2 )
     {
-      *v9 = a5->x;
-      *a2 = a5->z;
-      if ( a6->uNumVertices )
+      pFace->pFacePlane.vNormal.x = a5->x;
+      pFace->pFacePlane.vNormal.z = a5->z;
+      if ( pFace->uNumVertices )
       {
         v15 = 188 * uModelID + 72;
-        a5b = a4 + 1;
-        do
+        a5b = displaced_face_intersect_plane_coords_b + 1;
+        for ( uint i = 0; i < pFace->uNumVertices; ++i )
         {
-          v16 = a1a;
-          a3[2 * a1a] = a6->pXInterceptDisplacements[a1a]
-//                      + *(short *)(*(int *)&pOutdoor->pBModels->pModelName[v15] + 12 * a6->pVertexIDs[a1a]);
-		  + pOutdoor->pBModels[v15].pVertices.pVertices[a6->pVertexIDs[a1a]].x;
-          *(a5b - 1) = a6->pZInterceptDisplacements[v16]
-//                     + *(short *)(*(int *)&pOutdoor->pBModels->pModelName[v15] + 12 * a6->pVertexIDs[v16] + 8);
-		  + pOutdoor->pBModels[v15].pVertices.pVertices[a6->pVertexIDs[v16]].y;
-		  *(__int16 *)((char *)a5b + (int)a3 - (int)a4) = a6->pXInterceptDisplacements[v16 + 1]
-//                                                              + *(short *)(*(int *)&pOutdoor->pBModels->pModelName[v15]
-//                                                                         + 12 * a6->pVertexIDs[v16 + 1]);
-		  + pOutdoor->pBModels[v15].pVertices.pVertices[a6->pVertexIDs[v16+1]].x;
-          v17 = a6->pZInterceptDisplacements[v16 + 1]
-//              + *(short *)(*(int *)&pOutdoor->pBModels->pModelName[v15] + 12 * a6->pVertexIDs[v16 + 1] + 8);
-		  + pOutdoor->pBModels[v15].pVertices.pVertices[a6->pVertexIDs[v16+1]].z;
+          displaced_face_intersect_plane_coords_a[2 * i] = pFace->pXInterceptDisplacements[i] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i]].x;
+          *(a5b - 1) = pFace->pZInterceptDisplacements[i] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i]].y;
+          *(__int16 *)((char *)a5b + (int)displaced_face_intersect_plane_coords_a - (int)displaced_face_intersect_plane_coords_b) = pFace->pXInterceptDisplacements[i + 1]
+                + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i + 1]].x;
+          v17 = pFace->pZInterceptDisplacements[i + 1] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i + 1]].z;
           v18 = a5b;
-          ++a1a;
           a5b += 2;
           *v18 = v17;
         }
-        while ( a1a < a6->uNumVertices );
       }
     }
     else
     {
-      *v9 = a5->y;
-      *a2 = a5->z;
-      if ( a6->uNumVertices )
+      pFace->pFacePlane.vNormal.y = a5->y;
+      pFace->pFacePlane.vNormal.z = a5->z;
+      if ( pFace->uNumVertices )
       {
         v19 = 188 * uModelID + 72;
-        a5c = a4 + 1;
-        do
+        a5c = displaced_face_intersect_plane_coords_b + 1;
+        for ( uint i = 0; i < pFace->uNumVertices; ++i )
         {
-          v20 = a1a;
-          a3[2 * a1a] = a6->pYInterceptDisplacements[a1a]
-//                      + *(short *)(*(int *)&pOutdoor->pBModels->pModelName[v19] + 12 * a6->pVertexIDs[a1a] + 4);
-		  + pOutdoor->pBModels[v19].pVertices.pVertices[a6->pVertexIDs[a1a]].y;
-          *(a5c - 1) = a6->pZInterceptDisplacements[v20]
-//                     + *(short *)(*(int *)&pOutdoor->pBModels->pModelName[v19] + 12 * a6->pVertexIDs[v20] + 8);
-		  + pOutdoor->pBModels[v19].pVertices.pVertices[a6->pVertexIDs[a1a]].z;
-          *(__int16 *)((char *)a5c + (int)(char *)a3 - (char *)a4) = a6->pYInterceptDisplacements[v20 + 1]
-//                                                              + *(short *)(*(int *)&pOutdoor->pBModels->pModelName[v19]
-//                                                                         + 12 * a6->pVertexIDs[v20 + 1]
-//                                                                         + 4);
-		  + pOutdoor->pBModels[v19].pVertices.pVertices[a6->pVertexIDs[v20+1]].y;
-		  v21 = a6->pZInterceptDisplacements[v20 + 1]
-//              + *(short *)(*(int *)&pOutdoor->pBModels->pModelName[v19] + 12 * a6->pVertexIDs[v20 + 1] + 8);
-		  + pOutdoor->pBModels[v19].pVertices.pVertices[a6->pVertexIDs[v20+1]].z;
+          displaced_face_intersect_plane_coords_a[2 * i] = pFace->pYInterceptDisplacements[i] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i]].y;
+          *(a5c - 1) = pFace->pZInterceptDisplacements[i] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i]].z;
+          *(__int16 *)((char *)a5c + (int)(char *)displaced_face_intersect_plane_coords_a - (char *)displaced_face_intersect_plane_coords_b) = pFace->pYInterceptDisplacements[i + 1]
+                + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i + 1]].y;
+          v21 = pFace->pZInterceptDisplacements[i + 1] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i + 1]].z;
           v22 = a5c;
-          ++a1a;
           a5c += 2;
           *v22 = v21;
         }
-        while ( a1a < a6->uNumVertices );
       }
     }
   }
-  LOBYTE(result) = 1;
-  return result;
+  return true;
 }
 
 //----- (004C248E) --------------------------------------------------------
 void Vis::CastPickRay(RenderVertexSoft *pRay, float fMouseX, float fMouseY, float fPickDepth)
 {
-  int v5; // ebx@1
-  int v6; // edi@1
-  int v7; // esi@1
-  Vec3_int_ v8; // ST08_12@1
-  int v9; // ST04_4@1
-  int v10; // eax@1
+  int pRotY; // esi@1
+  Vec3_int_ pStartR; // ST08_12@1
+  int pRotX; // ST04_4@1
+  int pDepth; // eax@1
   RenderVertexSoft v11[2]; // [sp+2Ch] [bp-74h]@1
-  int v12; // [sp+8Ch] [bp-14h]@1
-  int v13; // [sp+90h] [bp-10h]@1
+  int outx;
   int outz; // [sp+94h] [bp-Ch]@1
   int outy; // [sp+98h] [bp-8h]@1
-  int v16; // [sp+9Ch] [bp-4h]@1
 
-  v5 = pIndoorCamera->pos.y;
-  v6 = pIndoorCamera->pos.x;
-  v13 = pIndoorCamera->pos.x;
-  v12 = pIndoorCamera->pos.y;
-  v16 = pIndoorCamera->pos.z;
-  v7 = pIndoorCamera->sRotationY + UnprojectX((signed __int64)fMouseX);
-  v8.z = v16;
-  v8.x = v6;
-  v8.y = v5;
-  v9 = pIndoorCamera->sRotationX + UnprojectY((signed __int64)fMouseY);
-  v10 = _48B561_mess_with_scaling_along_z(/*(int)&fMouseX, */fPickDepth);
-  Vec3_int_::Rotate(v10, v7, v9, v8, (int *)&fMouseX, &outy, &outz);
+  pRotY = pIndoorCamera->sRotationY + UnprojectX((signed __int64)fMouseX);
+  pStartR.z = pIndoorCamera->pos.z;
+  pStartR.x = pIndoorCamera->pos.x;
+  pStartR.y = pIndoorCamera->pos.y;
+  pRotX = pIndoorCamera->sRotationX + UnprojectY((signed __int64)fMouseY);
+  pDepth = _48B561_mess_with_scaling_along_z(/*(int)&fMouseX, */fPickDepth);
+  Vec3_int_::Rotate(pDepth, pRotY, pRotX, pStartR, &outx, &outy, &outz);
+
   v11[0].flt_2C = 0.0;
-  v11[0].vWorldPosition.x = (double)SLODWORD(fMouseX);
+  v11[0].vWorldPosition.x = (double)outx;
   v11[0].vWorldPosition.y = (double)outy;
   v11[0].vWorldPosition.z = (double)outz;
+
   v11[1].flt_2C = 0.0;
-  v11[1].vWorldPosition.x = (double)v13;
-  v11[1].vWorldPosition.y = (double)v12;
-  v11[1].vWorldPosition.z = (double)v16;
+  v11[1].vWorldPosition.x = (double)pIndoorCamera->pos.x;
+  v11[1].vWorldPosition.y = (double)pIndoorCamera->pos.y;
+  v11[1].vWorldPosition.z = (double)pIndoorCamera->pos.z;
+
   memcpy(pRay, &v11[1], 0x30u);
   memcpy(&pRay[1], v11, sizeof(pRay[1]));
 }
--- a/Vis.h	Tue May 21 11:24:26 2013 +0200
+++ b/Vis.h	Tue May 21 11:24:35 2013 +0200
@@ -110,10 +110,10 @@
   bool SortVectors_x(RenderVertexSoft *a2, int a3, int a4);
   int get_object_zbuf_val(Vis_ObjectInfo *info);
   int get_picked_object_zbuf_val();
-  bool Intersect_Ray_Face(struct RenderVertexSoft *pRayStart, struct RenderVertexSoft *pRayEnd, float *pDepth, RenderVertexSoft *a4, BLVFace *a5, unsigned int a6);
-  int _4C1D2B(BLVFace *pFace, Vec3_short_ a2, unsigned int uModelID);
+  bool Intersect_Ray_Face(struct RenderVertexSoft *pRayStart, struct RenderVertexSoft *pRayEnd, float *pDepth, RenderVertexSoft *Intersection, BLVFace *pFace, unsigned int pBModelID);
+  bool _4C1D2B(BLVFace *pFace, Vec3_short_ a2, unsigned int uModelID);
   bool _4C1EE5_BLV_IntersectBModel_2(int *a1, int *a2, __int16 *a3, __int16 *a4, Vec3_short_ *a5, BLVFace *pFace);
-  bool _4C2186_BLV_IntersectBModel(int *a1, int *a2, __int16 *a3, __int16 *a4, Vec3_short_ *a5, BLVFace *a6, unsigned int uModelID);
+  bool _4C2186_BLV_IntersectBModel(BLVFace *pFace, unsigned int ModelID, __int16 *displaced_face_intersect_plane_coords_a, __int16 *displaced_face_intersect_plane_coords_b, Vec3_short_ *a5, BLVFace *face, unsigned int uModelID);
   void CastPickRay(RenderVertexSoft *pRay, float fMouseX, float fMouseY, float fPickDepth);
   void sort_object_pointers(Vis_ObjectInfo **pPointers, int left, int right);
   bool SortVerticesByX(struct RenderVertexD3D3 *a2, unsigned int uStart, unsigned int uEnd);
--- a/mm7_1.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/mm7_1.cpp	Tue May 21 11:24:35 2013 +0200
@@ -7,44 +7,31 @@
 //#include <defs.h>
 #include <assert.h>
 
+#include "VideoPlayer.h"
+#include "BSPModel.h"
+#include "Mouse.h"
+
+#include "Vis.h"
 #include "MM7.h"
-#include "MapInfo.h"
 #include "Game.h"
 #include "GUIWindow.h"
-#include "GUIFont.h"
-#include "GUIProgressBar.h"
 #include "Party.h"
 #include "AudioPlayer.h"
 #include "Outdoor.h"
-#include "IndoorCamera.h"
 #include "Overlays.h"
-#include "Monsters.h"
-#include "Arcomage.h"
 #include "LOD.h"
 #include "Actor.h"
 #include "Allocator.h"
 #include "Events.h"
 #include "Viewport.h"
-#include "FrameTableInc.h"
-#include "Math.h"
 #include "SpriteObject.h"
 #include "ObjectList.h"
 #include "Chest.h"
-#include "PaletteManager.h"
 #include "DecorationList.h"
-#include "SaveLoad.h"
 #include "stru123.h"
 #include "Time.h"
 #include "IconFrameTable.h"
-#include "Awards.h"
-#include "Autonotes.h"
-#include "stru160.h"
 #include "TurnEngine.h"
-#include "CastSpellInfo.h"
-#include "Weather.h"
-#include "stru298.h"
-#include "StorylineTextTable.h"
-#include "Events2D.h"
 #include "texts.h"
 #include "UIHouses.h"
 #include "mm7_data.h"
@@ -362,8 +349,8 @@
 }
 
 //----- (0041D20D) --------------------------------------------------------
-char __fastcall sub_41D20D_buff_remaining_time_string(int ecx0, GUIWindow *edx0, __int64 a3, GUIFont *a2)
-{
+void __fastcall sub_41D20D_buff_remaining_time_string( int ecx0, struct GUIWindow *edx0, __int64 a3, struct GUIFont *a2 )
+    {
   unsigned int v4; // edi@1
   unsigned int v5; // esi@1
   unsigned int v6; // ebp@1
@@ -427,7 +414,7 @@
     sprintf(pTmpBuf2, "%d %s ", v18, v13);
     strcat(pTmpBuf, pTmpBuf2);
   }
-  return a1->DrawText(a2, 32, uY, 0, pTmpBuf, 0, 0, 0);
+  a1->DrawText(a2, 32, uY, 0, pTmpBuf, 0, 0, 0);
 }
 
 //----- (0041F54A) --------------------------------------------------------
@@ -437,7 +424,7 @@
     pTexture_RestUI_CurrentSkyFrame->Release();
   if ( pTexture_RestUI_CurrentHourglassFrame )
     pTexture_RestUI_CurrentHourglassFrame->Release();
-  pIcons_LOD->_40F9C5();
+  pIcons_LOD->SyncLoadedFilesCount();
   sprintf(pTmpBuf, "TERRA%03d", pParty->uCurrentMinute / 6 + 10 * pParty->uCurrentHour);
   pTexture_RestUI_CurrentSkyFrame = pIcons_LOD->LoadTexturePtr(pTmpBuf, TEXTURE_16BIT_PALETTE);
 }
@@ -468,7 +455,7 @@
       pTexture_RestUI_CurrentHourglassFrame = 0;
       pTexture_RestUI_CurrentSkyFrame = 0;
       pIcons_LOD->_4114F2();
-      pIcons_LOD->_40F9C5();
+      pIcons_LOD->SyncLoadedFilesCount();
       pCurrentScreen = SCREEN_GAME;
       viewparams->bRedrawGameUI = 1;
       if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor)
@@ -697,7 +684,7 @@
   v1 = pIcons_LOD->GetTexture(v0);
   v11 = areWeLoadingTexture;
   if ( uActiveCharacter
-    && (v2 = pPlayers[uActiveCharacter]->AddItem(0xFFFFFFFFu, pParty->pPickedItem.uItemID)) != 0 )
+    && (v2 = pPlayers[uActiveCharacter]->AddItem(-1, pParty->pPickedItem.uItemID)) != 0 )
   {
     memcpy(&pPlayers[uActiveCharacter]->pInventoryItems[v2-1], &pParty->pPickedItem, 0x24u);
 	pMouse->RemoveHoldingItem();
@@ -708,7 +695,7 @@
     v3 = pParty->pPlayers;
 	while ( v3 <= &pParty->pPlayers[3] )
     {
-      v4 = v3->AddItem(0xFFFFFFFFu, pParty->pPickedItem.uItemID);
+      v4 = v3->AddItem(-1, pParty->pPickedItem.uItemID);
       if ( v4 )
 	  {
 		memcpy(&pParty->pPlayers[v12].pInventoryItems[v4], &pParty->pPickedItem, 0x24u);
@@ -763,7 +750,7 @@
   if ( !v11 )
   {
     v1->Release();
-    pIcons_LOD->_40F9C5();
+    pIcons_LOD->SyncLoadedFilesCount();
   }
   return 1;
 }
@@ -782,7 +769,7 @@
   if (pParty->pPickedItem.uItemID)
   {
     //v3 = player;
-    if (auto slot = player->AddItem(0xFFFFFFFFu, pParty->pPickedItem.uItemID))
+    if (auto slot = player->AddItem(-1, pParty->pPickedItem.uItemID))
     {
       memcpy(&player->pInventoryItems[slot-1], &pParty->pPickedItem, 0x24u);
       viewparams->bRedrawGameUI = true;
@@ -974,7 +961,7 @@
             pX = v0->AddItem2(0xFFFFFFFFu, &pParty->pPickedItem);
             if ( !pX )
             {
-              v0->_49298B(&this_, v13 - 1, a4);
+              v0->PutItemArInventoryIndex(&this_, v13 - 1, a4);
               memcpy((void *)a2.y, &this_, sizeof(ItemGen));
               return;
             }
@@ -986,7 +973,7 @@
         }
         v10 = v0->AddItem(a4, v7);
         pX = v10;
-        if ( v10 || (v10 = v0->AddItem(0xFFFFFFFFu, pParty->pPickedItem.uItemID), (pX = v10) != 0) )
+        if ( v10 || (v10 = v0->AddItem(-1, pParty->pPickedItem.uItemID), (pX = v10) != 0) )
         {
           memcpy(&v0->pInventoryItems[v10-1], &pParty->pPickedItem, 0x24u);
           pMouse->RemoveHoldingItem();
@@ -1166,7 +1153,7 @@
 			if (v10 != -1)
 				pIcons_LOD->pTextures[v10].Release();
 			pMouse->RemoveHoldingItem();
-			pIcons_LOD->_40F9C5();
+			pIcons_LOD->SyncLoadedFilesCount();
 			return;
         }
         v11 = pIndoor->pFaceExtras[v3->uFaceExtraID].uEventID;
--- a/mm7_2.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/mm7_2.cpp	Tue May 21 11:24:35 2013 +0200
@@ -1,7 +1,24 @@
 #include <io.h>
 #include <direct.h>
 #include <assert.h>
-
+#include <windows.h>
+
+
+#include "VideoPlayer.h"
+#include "Sprites.h"
+#include "BSPModel.h"
+#include "OutdoorCamera.h"
+
+#include "LightmapBuilder.h"
+#include "DecalBuilder.h"
+#include "ParticleEngine.h"
+#include "Mouse.h"
+#include "Keyboard.h"
+#include "CShow.h"
+#include "GammaControl.h"
+#include "stru6.h"
+
+#include "Vis.h"
 #include "MapInfo.h"
 #include "Game.h"
 #include "GUIWindow.h"
@@ -11,7 +28,6 @@
 #include "Outdoor.h"
 #include "IndoorCamera.h"
 #include "Overlays.h"
-#include "Monsters.h"
 #include "Arcomage.h"
 #include "LOD.h"
 #include "Actor.h"
@@ -32,20 +48,14 @@
 #include "IconFrameTable.h"
 #include "GUIProgressBar.h"
 #include "Bink_Smacker.h"
-#include "TileFrameTable.h"
 #include "PlayerFrameTable.h"
-#include "Awards.h"
-#include "Autonotes.h"
-#include "stru160.h"
 #include "TurnEngine.h"
 #include "FactionTable.h"
 #include "StorylineTextTable.h"
 #include "Random.h"
 #include "CastSpellInfo.h"
 #include "stru298.h"
-#include "stru12.h"
 #include "Events2D.h"
-#include "stru159.h"
 #include "Log.h"
 #include "UIHouses.h"
 #include "texts.h"
@@ -854,7 +864,7 @@
     pDialogueWindow->Release();
     dialog_menu_id = HOUSE_DIALOGUE_NULL;
     pDialogueWindow = 0;
-    pIcons_LOD->_40F9C5();
+    pIcons_LOD->SyncLoadedFilesCount();
     v1 = uNumDialogueNPCPortraits;
     if ( uNumDialogueNPCPortraits != 1 )
     {
@@ -940,7 +950,7 @@
         ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2);
         return;
       }
-      taken_item = pPlayers[uActiveCharacter]->AddItem(0xFFFFFFFFu, bought_item->uItemID);
+      taken_item = pPlayers[uActiveCharacter]->AddItem(-1, bought_item->uItemID);
       if ( taken_item )
       {
         bought_item->SetIdentified();
@@ -1098,7 +1108,7 @@
           }
         }
       }
-      v39 = pPlayers[uActiveCharacter]->AddItem(0xFFFFFFFFu, bought_item->uItemID);
+      v39 = pPlayers[uActiveCharacter]->AddItem(-1, bought_item->uItemID);
       if ( v39 )
       {
         bought_item->SetIdentified();
@@ -9924,14 +9934,14 @@
 }
 
 //----- (00467F48) --------------------------------------------------------
-void __fastcall sub_467F48(signed int a1)
-{
+void CreateMsgScrollWindow( signed int mscroll_id )
+    {
   signed int v1; // esi@1
 
-  v1 = a1;
-  if ( !pGUIWindow_ScrollWindow && a1 >= 700 )
-  {
-    if ( a1 <= 782 )
+  v1 = mscroll_id;
+  if ( !pGUIWindow_ScrollWindow && mscroll_id >= 700 )
+  {
+    if ( mscroll_id <= 782 )
     {
       uTextureID_720980 = pIcons_LOD->LoadTexture("leather", TEXTURE_16BIT_PALETTE);
       pGUIWindow_ScrollWindow = GUIWindow::Create(0, 0, 640, 480, WINDOW_Scroll, v1 - 700, 0);
@@ -9951,8 +9961,8 @@
 }
 
 //----- (00467FB6) --------------------------------------------------------
-char __cdecl CreateScrollWindow()
-{
+void CreateScrollWindow()
+    {
   unsigned int v0; // eax@1
   char *v1; // ST18_4@3
   unsigned int v2; // eax@3
@@ -9985,7 +9995,7 @@
   v2 = TargetColor(0xFFu, 0xFFu, 0x9Bu);
   sprintf(pTmpBuf, format_4E2D80, v2, v1);
   a1.DrawTitleText(pFontCreate, 0, 0, 0, pTmpBuf, 3u);
-  return a1.DrawText(
+  a1.DrawText(
            pFontSmallnum,
            1,
            LOBYTE(pFontCreate->uFontHeight) - 3,
--- a/mm7_3.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/mm7_3.cpp	Tue May 21 11:24:35 2013 +0200
@@ -1,5 +1,17 @@
 #include <assert.h>
 
+
+#include "VideoPlayer.h"
+#include "Sprites.h"
+#include "BSPModel.h"
+#include "OutdoorCamera.h"
+#include "LightmapBuilder.h"
+#include "DecalBuilder.h"
+#include "ParticleEngine.h"
+#include "Mouse.h"
+#include "Keyboard.h"
+#include "stru6.h"
+
 #include "MapInfo.h"
 #include "Game.h"
 #include "GUIWindow.h"
@@ -10,33 +22,23 @@
 #include "Outdoor.h"
 #include "IndoorCamera.h"
 #include "Overlays.h"
-#include "Monsters.h"
-#include "Arcomage.h"
 #include "LOD.h"
 #include "Actor.h"
 #include "Allocator.h"
 #include "Events.h"
 #include "Viewport.h"
-#include "FrameTableInc.h"
 #include "Math.h"
 #include "SpriteObject.h"
 #include "ObjectList.h"
-#include "Chest.h"
 #include "PaletteManager.h"
 #include "DecorationList.h"
-#include "SaveLoad.h"
 #include "stru123.h"
 #include "Time.h"
 #include "IconFrameTable.h"
 #include "TurnEngine.h"
-#include "Awards.h"
-#include "Autonotes.h"
-#include "stru160.h"
-#include "Weather.h"
 #include "stru220.h"
 #include "Events2D.h"
 #include "stru176.h"
-#include "stru159.h"
 #include "stru298.h"
 #include "texts.h"
 #include "Log.h"
@@ -10429,7 +10431,7 @@
 //----- (00486089) --------------------------------------------------------
 void stru148::_486089_normalize_v_18()
 {
-  stru148 *v1; // esi@1
+  //stru148 *v1; // esi@1
   double v2; // st7@1
   double v3; // st6@1
   float v4; // ST18_4@2
@@ -10445,7 +10447,7 @@
   double v14; // ST0C_8@2
   float v15; // [sp+20h] [bp-8h]@1
 
-  v1 = this;
+  //v1 = this;
   v2 = (double)this->v_18.x;
   v15 = v2;
   v3 = (double)this->v_18.y;
@@ -10453,24 +10455,24 @@
   v7 = sqrt(v5 * v5 + v3 * v3 + v2 * v2);
   if ( v7 == 0.0 )
   {
-    v1->v_18.x = 0;
-    v1->v_18.y = 0;
-    v1->v_18.z = 65536;
+    this->v_18.x = 0;
+    this->v_18.y = 0;
+    this->v_18.z = 65536;
   }
   else
   {
     v8 = 1.0 / v7;
     v9 = v8 * v15 * 65536.0;
     v10 = v9 + 6.7553994e15;
-    v1->v_18.x = LODWORD(v10);
+    this->v_18.x = LODWORD(v10);
     v4 = v3;
     v11 = v8 * v4 * 65536.0;
     v12 = v11 + 6.7553994e15;
-    v1->v_18.y = LODWORD(v12);
+    this->v_18.y = LODWORD(v12);
     v6 = v5;
     v13 = v8 * v6 * 65536.0;
     v14 = v13 + 6.7553994e15;
-    v1->v_18.z = LODWORD(v14);
+    this->v_18.z = LODWORD(v14);
   }
 }
 
@@ -14638,7 +14640,7 @@
 //----- (0044C362) --------------------------------------------------------
 void Vec3_int_::Normalize_float()
 {
-  Vec3_int_ *v1; // esi@1
+  //Vec3_int_ *v1; // esi@1
   double v2; // st6@1
   float v3; // ST20_4@1
   double v4; // st5@1
@@ -14653,7 +14655,7 @@
   float v13; // ST14_4@1
   double v14; // ST0C_8@1
 
-  v1 = this;
+  //v1 = this;
   v2 = (double)this->x * 0.000015258789;
   v3 = v2;
   v4 = (double)this->y * 0.000015258789;
@@ -14663,13 +14665,13 @@
   v8 = 1.0 / sqrt(v6 * v6 + v4 * v4 + v2 * v2);
   v9 = v8 * v3 * 65536.0;
   v10 = v9 + 6.7553994e15;
-  v1->x = LODWORD(v10);
+  this->x = LODWORD(v10);
   v11 = v8 * v5 * 65536.0;
   v12 = v11 + 6.7553994e15;
-  v1->y = LODWORD(v12);
+  this->y = LODWORD(v12);
   v13 = v8 * v7 * 65536.0;
   v14 = v13 + 6.7553994e15;
-  v1->z = LODWORD(v14);
+  this->z = LODWORD(v14);
 }
 
 //----- (00401000) --------------------------------------------------------
--- a/mm7_4.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/mm7_4.cpp	Tue May 21 11:24:35 2013 +0200
@@ -1,7 +1,15 @@
-#include <io.h>
-#include <direct.h>
 #include <assert.h>
 
+#include "VideoPlayer.h"
+#include "Sprites.h"
+#include "BSPModel.h"
+#include "OutdoorCamera.h"
+#include "Mouse.h"
+#include "stru6.h"
+#include "stru11.h"
+#include "stru12.h"
+
+#include "LightmapBuilder.h"
 #include "MM7.h"
 #include "MapInfo.h"
 #include "Game.h"
@@ -11,9 +19,6 @@
 #include "AudioPlayer.h"
 #include "Outdoor.h"
 #include "IndoorCamera.h"
-#include "Overlays.h"
-#include "Monsters.h"
-#include "Arcomage.h"
 #include "LOD.h"
 #include "Actor.h"
 #include "Allocator.h"
@@ -23,27 +28,12 @@
 #include "Math.h"
 #include "SpriteObject.h"
 #include "ObjectList.h"
-#include "Chest.h"
-#include "PaletteManager.h"
 #include "DecorationList.h"
-#include "SaveLoad.h"
-#include "stru123.h"
 #include "Time.h"
 #include "IconFrameTable.h"
-#include "GUIProgressBar.h"
-#include "Bink_Smacker.h"
-#include "TileFrameTable.h"
 #include "PlayerFrameTable.h"
 #include "Awards.h"
-#include "Autonotes.h"
-#include "stru160.h"
 #include "TurnEngine.h"
-#include "FactionTable.h"
-#include "StorylineTextTable.h"
-#include "Random.h"
-#include "CastSpellInfo.h"
-#include "stru298.h"
-#include "stru12.h"
 #include "Events2D.h"
 #include "stru159.h"
 #include "texts.h"
@@ -1801,7 +1791,7 @@
 {
   //v2 = a2 - 0.5;
   //v3 = v2 + 6.7553994e15;
-  int v4 = floorf(a2 - 0.5f + 0.5f);
+  int v4 = floorf((a2 - 0.5f) + 0.5f);
   //v7 = (a2 - (double)SLODWORD(v3)) * 65536.0;
   //v5 = v7 + 6.7553994e15;
   //return LODWORD(v5) | (v4 << 16);
@@ -8020,12 +8010,12 @@
 }
 
 //----- (004B46A5) --------------------------------------------------------
-char __fastcall DrawTextAtStatusBar(const char *sText, int font_color)
-{
+void __fastcall DrawTextAtStatusBar( const char *Str, int a5 )
+    {
   int v4; // eax@1
   pRenderer->DrawTextureRGB(0, 352, pTexture_StatusBar);
-  v4 = pFontLucida->AlignText_Center(450, sText);
-  return pPrimaryWindow->DrawText(pFontLucida, v4 + 11, 357, font_color, sText, 0, 0, 0);
+  v4 = pFontLucida->AlignText_Center(450, Str);
+  pPrimaryWindow->DrawText(pFontLucida, v4 + 11, 357, a5, Str, 0, 0, 0);
 }
 
 //----- (004B46F8) --------------------------------------------------------
--- a/mm7_5.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/mm7_5.cpp	Tue May 21 11:24:35 2013 +0200
@@ -1,7 +1,19 @@
 #include <assert.h>
 
+#include "VideoPlayer.h"
+#include "Sprites.h"
+#include "MapInfo.h"
+#include "BSPModel.h"
+#include "OutdoorCamera.h"
+#include "LightmapBuilder.h"
+#include "DecalBuilder.h"
+#include "Mouse.h"
+#include "Keyboard.h"
+#include "GammaControl.h"
+#include "stru11.h"
+
+#include "Vis.h"
 #include "mm7.h"
-#include "MapInfo.h"
 #include "Game.h"
 #include "GUIWindow.h"
 #include "GUIFont.h"
@@ -9,13 +21,9 @@
 #include "Party.h"
 #include "AudioPlayer.h"
 #include "Outdoor.h"
-#include "IndoorCamera.h"
-#include "Overlays.h"
-#include "Monsters.h"
 #include "Arcomage.h"
 #include "LOD.h"
 #include "Actor.h"
-#include "Allocator.h"
 #include "Events.h"
 #include "Viewport.h"
 #include "FrameTableInc.h"
@@ -24,19 +32,11 @@
 #include "ObjectList.h"
 #include "Chest.h"
 #include "PaletteManager.h"
-#include "DecorationList.h"
 #include "SaveLoad.h"
-#include "stru123.h"
 #include "Time.h"
-#include "IconFrameTable.h"
-#include "Awards.h"
-#include "Autonotes.h"
-#include "stru160.h"
 #include "TurnEngine.h"
 #include "CastSpellInfo.h"
-#include "Weather.h"
 #include "stru298.h"
-#include "StorylineTextTable.h"
 #include "Events2D.h"
 #include "texts.h"
 #include "Log.h"
@@ -47,7 +47,7 @@
 void __cdecl GameUI_MsgProc()
 {
   //signed int v0; // edi@6
-  char *v1; // esi@6
+  //char *v1; // esi@6
   unsigned int v2; // edx@7
   Actor *pActor; // ecx@13
   int v4; // ecx@18
@@ -280,8 +280,7 @@
   }
   if ( pMessageQueue_50CBD0->uNumMessages )
   {
-    //v0 = 1;
-    v1 = "";
+    //v1 = "";
     while ( 2 )
     {
       if ( !pMessageQueue_50CBD0->uNumMessages )
@@ -383,7 +382,7 @@
         case UIMSG_StartNewGame:
           if ( dword_6BE138 == 124 || uMessageParam )
           {
-            pIcons_LOD->_40F9C5();
+            pIcons_LOD->SyncLoadedFilesCount();
             pIcons_LOD->_4114F2();
             if ( pMessageQueue_50CBD0->uNumMessages )
               pMessageQueue_50CBD0->uNumMessages = pMessageQueue_50CBD0->pMessages[0].field_8 != 0;
@@ -401,7 +400,7 @@
           stru_506E40.Release();
           continue;
         case UIMSG_Game_OpenLoadGameDialog:
-          pIcons_LOD->_40F9C5();
+          pIcons_LOD->SyncLoadedFilesCount();
           pIcons_LOD->_4114F2();
           if ( pMessageQueue_50CBD0->uNumMessages )
             pMessageQueue_50CBD0->uNumMessages = pMessageQueue_50CBD0->pMessages[0].field_8 != 0;
@@ -412,7 +411,7 @@
         case UIMSG_Quit:
           if ( dword_6BE138 == 132 || uMessageParam )
           {
-            pIcons_LOD->_40F9C5();
+            pIcons_LOD->SyncLoadedFilesCount();
             pIcons_LOD->_4114F2();
             if ( pMessageQueue_50CBD0->uNumMessages )
               pMessageQueue_50CBD0->uNumMessages = pMessageQueue_50CBD0->pMessages[0].field_8 != 0;
@@ -433,7 +432,7 @@
           continue;
         case UIMSG_80:
 			__debugbreak();
-          pIcons_LOD->_40F9C5();
+          pIcons_LOD->SyncLoadedFilesCount();
           pIcons_LOD->_4114F2();
           pGUIWindow_CurrentMenu->Release();
           pCurrentScreen = SCREEN_OPTIONS;
@@ -550,48 +549,48 @@
           pGUIWindow_CurrentMenu->CreateButton(22, 270,
                                                pIcons_LOD->GetTexture(options_menu_skin.uTextureID_TurnSpeed[2])->uTextureWidth,
                                                pIcons_LOD->GetTexture(options_menu_skin.uTextureID_TurnSpeed[2])->uTextureHeight,
-                                               1, 0, UIMSG_SetTurnSpeed, 0x80, 0, v1, 0);
+                                               1, 0, UIMSG_SetTurnSpeed, 0x80, 0, "", 0);
           pGUIWindow_CurrentMenu->CreateButton(93, 270,
                                                pIcons_LOD->GetTexture(options_menu_skin.uTextureID_TurnSpeed[1])->uTextureWidth,
                                                pIcons_LOD->GetTexture(options_menu_skin.uTextureID_TurnSpeed[1])->uTextureHeight,
-                                               1, 0, UIMSG_SetTurnSpeed, 0x40u, 0, v1, 0);
+                                               1, 0, UIMSG_SetTurnSpeed, 0x40u, 0, "", 0);
           pGUIWindow_CurrentMenu->CreateButton(164, 270,
                                                pIcons_LOD->GetTexture(options_menu_skin.uTextureID_TurnSpeed[0])->uTextureWidth,
                                                pIcons_LOD->GetTexture(options_menu_skin.uTextureID_TurnSpeed[0])->uTextureHeight,
-                                               1, 0, UIMSG_SetTurnSpeed, 0, 0, v1, 0);
+                                               1, 0, UIMSG_SetTurnSpeed, 0, 0, "", 0);
 
           pGUIWindow_CurrentMenu->CreateButton(20, 303,
                                                pIcons_LOD->GetTexture(options_menu_skin.uTextureID_WalkSound)->uTextureWidth,
                                                pIcons_LOD->GetTexture(options_menu_skin.uTextureID_WalkSound)->uTextureHeight,
-                                               1, 0, UIMSG_ToggleWalkSound, 0, 0, v1, 0);
+                                               1, 0, UIMSG_ToggleWalkSound, 0, 0, "", 0);
           pGUIWindow_CurrentMenu->CreateButton(128, 303,
                                                pIcons_LOD->GetTexture(options_menu_skin.uTextureID_ShowDamage)->uTextureWidth,
                                                pIcons_LOD->GetTexture(options_menu_skin.uTextureID_ShowDamage)->uTextureHeight,
-                                               1, 0, UIMSG_ToggleShowDamage, 0, 0, v1, 0);
+                                               1, 0, UIMSG_ToggleShowDamage, 0, 0, "", 0);
           pGUIWindow_CurrentMenu->CreateButton(20, 325,
                                                pIcons_LOD->GetTexture(options_menu_skin.uTextureID_AlwaysRun)->uTextureWidth,
                                                pIcons_LOD->GetTexture(options_menu_skin.uTextureID_AlwaysRun)->uTextureHeight,
-                                               1, 0, UIMSG_ToggleAlwaysRun, 0, 0, v1, 0);
+                                               1, 0, UIMSG_ToggleAlwaysRun, 0, 0, "", 0);
           pGUIWindow_CurrentMenu->CreateButton(128, 325,
                                                pIcons_LOD->GetTexture(options_menu_skin.uTextureID_FlipOnExit)->uTextureWidth,
                                                pIcons_LOD->GetTexture(options_menu_skin.uTextureID_FlipOnExit)->uTextureHeight,
-                                               1, 0, UIMSG_ToggleFlipOnExit, 0, 0, v1, 0);
-
-          pBtn_SliderLeft  = pGUIWindow_CurrentMenu->CreateButton(243, 162, 16, 16, 1, 0, UIMSG_ChangeSoundVolume, 4, 0, v1, pIcons_LOD->GetTexture(options_menu_skin.uTextureID_ArrowLeft), 0);
-          pBtn_SliderRight = pGUIWindow_CurrentMenu->CreateButton(435, 162, 16, 16, 1, 0, UIMSG_ChangeSoundVolume, 5, 0, v1, pIcons_LOD->GetTexture(options_menu_skin.uTextureID_ArrowRight), 0);
-          pGUIWindow_CurrentMenu->CreateButton(263, 162, 172, 17, 1, 0, UIMSG_ChangeSoundVolume, 0, 0, v1, 0);
-
-          pBtn_SliderLeft  = pGUIWindow_CurrentMenu->CreateButton(243, 216, 16, 16, 1, 0, UIMSG_ChangeMusicVolume, 4, 0, v1, pIcons_LOD->GetTexture(options_menu_skin.uTextureID_ArrowLeft), 0);
-          pBtn_SliderRight = pGUIWindow_CurrentMenu->CreateButton(435, 216, 16, 16, 1, 0, UIMSG_ChangeMusicVolume, 5, 0, v1, pIcons_LOD->GetTexture(options_menu_skin.uTextureID_ArrowRight), 0);
-          pGUIWindow_CurrentMenu->CreateButton(263, 216, 172, 17, 1, 0, UIMSG_ChangeMusicVolume, 0, 0, v1, 0);
-
-          pBtn_SliderLeft  = pGUIWindow_CurrentMenu->CreateButton(243, 270, 16, 16, 1, 0, UIMSG_ChangeVoiceVolume, 4, 0, v1, pIcons_LOD->GetTexture(options_menu_skin.uTextureID_ArrowLeft), 0);
-          pBtn_SliderRight = pGUIWindow_CurrentMenu->CreateButton(435, 270, 16, 16, 1, 0, UIMSG_ChangeVoiceVolume, 5, 0, v1, pIcons_LOD->GetTexture(options_menu_skin.uTextureID_ArrowRight), 0);
-          pGUIWindow_CurrentMenu->CreateButton(263, 270, 172, 17, 1, 0, UIMSG_ChangeVoiceVolume, 0, 0, v1, 0);
+                                               1, 0, UIMSG_ToggleFlipOnExit, 0, 0, "", 0);
+
+          pBtn_SliderLeft  = pGUIWindow_CurrentMenu->CreateButton(243, 162, 16, 16, 1, 0, UIMSG_ChangeSoundVolume, 4, 0, "", pIcons_LOD->GetTexture(options_menu_skin.uTextureID_ArrowLeft), 0);
+          pBtn_SliderRight = pGUIWindow_CurrentMenu->CreateButton(435, 162, 16, 16, 1, 0, UIMSG_ChangeSoundVolume, 5, 0, "", pIcons_LOD->GetTexture(options_menu_skin.uTextureID_ArrowRight), 0);
+          pGUIWindow_CurrentMenu->CreateButton(263, 162, 172, 17, 1, 0, UIMSG_ChangeSoundVolume, 0, 0, "", 0);
+
+          pBtn_SliderLeft  = pGUIWindow_CurrentMenu->CreateButton(243, 216, 16, 16, 1, 0, UIMSG_ChangeMusicVolume, 4, 0, "", pIcons_LOD->GetTexture(options_menu_skin.uTextureID_ArrowLeft), 0);
+          pBtn_SliderRight = pGUIWindow_CurrentMenu->CreateButton(435, 216, 16, 16, 1, 0, UIMSG_ChangeMusicVolume, 5, 0, "", pIcons_LOD->GetTexture(options_menu_skin.uTextureID_ArrowRight), 0);
+          pGUIWindow_CurrentMenu->CreateButton(263, 216, 172, 17, 1, 0, UIMSG_ChangeMusicVolume, 0, 0, "", 0);
+
+          pBtn_SliderLeft  = pGUIWindow_CurrentMenu->CreateButton(243, 270, 16, 16, 1, 0, UIMSG_ChangeVoiceVolume, 4, 0, "", pIcons_LOD->GetTexture(options_menu_skin.uTextureID_ArrowLeft), 0);
+          pBtn_SliderRight = pGUIWindow_CurrentMenu->CreateButton(435, 270, 16, 16, 1, 0, UIMSG_ChangeVoiceVolume, 5, 0, "", pIcons_LOD->GetTexture(options_menu_skin.uTextureID_ArrowRight), 0);
+          pGUIWindow_CurrentMenu->CreateButton(263, 270, 172, 17, 1, 0, UIMSG_ChangeVoiceVolume, 0, 0, "", 0);
 
           pGUIWindow_CurrentMenu->CreateButton(241, 302, 214, 40, 1, 0, UIMSG_Escape, 0, 0, pGlobalTXT_LocalizationStrings[619], 0); // "Return to Game"
-          pGUIWindow_CurrentMenu->CreateButton( 19, 140, 214, 40, 1, 0, UIMSG_OpenKeyMappingOptions, 0, 0x4Bu, v1, 0);
-          pGUIWindow_CurrentMenu->CreateButton( 19, 194, 214, 40, 1, 0, UIMSG_OpenVideoOptions, 0, 86, v1, 0);
+          pGUIWindow_CurrentMenu->CreateButton( 19, 140, 214, 40, 1, 0, UIMSG_OpenKeyMappingOptions, 0, 0x4Bu, "", 0);
+          pGUIWindow_CurrentMenu->CreateButton( 19, 194, 214, 40, 1, 0, UIMSG_OpenVideoOptions, 0, 86, "", 0);
           continue;
 
         case UIMSG_OpenKeyMappingOptions://Open
@@ -630,7 +629,7 @@
           memset(KeyButtonFlagChangesArray, 0, sizeof(KeyButtonFlagChangesArray));
           //*(_WORD *)KeyButtonArray[28] = 0;
           memcpy(pPrevVirtualCidesMapping, pKeyActionMap->pVirtualKeyCodesMapping, 0x78u);
-          v1 = "";
+          //v1 = "";
           //v0 = 1;
           continue;
         case UIMSG_ChangeKeyButton:
@@ -707,21 +706,21 @@
           uTextureID_507C54 = pIcons_LOD->LoadTexture("opvdG-cl", TEXTURE_16BIT_PALETTE);
           uTextureID_507C58 = pIcons_LOD->LoadTexture("opvdG-tn", TEXTURE_16BIT_PALETTE);
           pGUIWindow_CurrentMenu = GUIWindow::Create(0, 0, 640, 480, WINDOW_VideoOptions, 0, 0);
-          pGUIWindow_CurrentMenu->CreateButton(0xF1u, 0x12Eu, 0xD6u, 0x28u, 1, 0, UIMSG_Escape, 0, 0, v1, 0);
+          pGUIWindow_CurrentMenu->CreateButton(0xF1u, 0x12Eu, 0xD6u, 0x28u, 1, 0, UIMSG_Escape, 0, 0, "", 0);
           if ( pRenderer->pRenderD3D )
           {
-            pGUIWindow_CurrentMenu->CreateButton(0x13u, 0x118u, 0xD6u, 0x12u, 1, 0, UIMSG_ToggleBloodsplats, 0, 0, v1, 0);
-            pGUIWindow_CurrentMenu->CreateButton(0x13u, 0x12Eu, 0xD6u, 0x12u, 1, 0, UIMSG_ToggleColoredLights, 0, 0, v1, 0);
-            pGUIWindow_CurrentMenu->CreateButton(0x13u, 0x144u, 0xD6u, 0x12u, 1, 0, UIMSG_ToggleTint, 0, 0, v1, 0);
+            pGUIWindow_CurrentMenu->CreateButton(0x13u, 0x118u, 0xD6u, 0x12u, 1, 0, UIMSG_ToggleBloodsplats, 0, 0, "", 0);
+            pGUIWindow_CurrentMenu->CreateButton(0x13u, 0x12Eu, 0xD6u, 0x12u, 1, 0, UIMSG_ToggleColoredLights, 0, 0, "", 0);
+            pGUIWindow_CurrentMenu->CreateButton(0x13u, 0x144u, 0xD6u, 0x12u, 1, 0, UIMSG_ToggleTint, 0, 0, "", 0);
           }
           if ( !pRenderer->bWindowMode )
           {
             //v0 = 1;
             if ( GammaController::IsGammaSupported() )
             {
-              pBtn_SliderLeft = pGUIWindow_CurrentMenu->CreateButton(0x15u, 0xA1u, 0x10u, 0x10u, 1, 0, UIMSG_1A9, 4u, 0, v1, pIcons_LOD->GetTexture(uTextureID_507C20), 0);
-              pBtn_SliderRight = pGUIWindow_CurrentMenu->CreateButton(0xD5u, 0xA1u, 0x10u, 0x10u, 1, 0, UIMSG_1A9, 5u, 0, v1, pIcons_LOD->GetTexture(uTextureID_507C24), 0);
-              pGUIWindow_CurrentMenu->CreateButton(42, 162, 170, 18, 1, 0, UIMSG_1A9, 0, 0, v1, 0);
+              pBtn_SliderLeft = pGUIWindow_CurrentMenu->CreateButton(0x15u, 0xA1u, 0x10u, 0x10u, 1, 0, UIMSG_1A9, 4u, 0, "", pIcons_LOD->GetTexture(uTextureID_507C20), 0);
+              pBtn_SliderRight = pGUIWindow_CurrentMenu->CreateButton(0xD5u, 0xA1u, 0x10u, 0x10u, 1, 0, UIMSG_1A9, 5u, 0, "", pIcons_LOD->GetTexture(uTextureID_507C24), 0);
+              pGUIWindow_CurrentMenu->CreateButton(42, 162, 170, 18, 1, 0, UIMSG_1A9, 0, 0, "", 0);
             }
           }
           continue;
@@ -1147,7 +1146,7 @@
                       continue;
                     case SCREEN_OPTIONS://Close
                       options_menu_skin.Relaease();
-                      pIcons_LOD->_40F9C5();
+                      pIcons_LOD->SyncLoadedFilesCount();
                       WriteWindowsRegistryInt("soundflag", (char)uSoundVolumeMultiplier);
                       WriteWindowsRegistryInt("musicflag", (char)uMusicVolimeMultiplier);
                       WriteWindowsRegistryInt("CharVoices", (char)uVoicesVolumeMultiplier);
@@ -1177,9 +1176,9 @@
                       stru_506E40.Release();
                       break;
                     case SCREEN_MENU:
-                      pIcons_LOD->_40F9C5();
+                      pIcons_LOD->SyncLoadedFilesCount();
                       pIcons_LOD->_4114F2();
-                      pIcons_LOD->_40F9C5();
+                      pIcons_LOD->SyncLoadedFilesCount();
                       pIcons_LOD->_4114F2();
                       stru_506E40.Release();
                       break;
@@ -1217,7 +1216,7 @@
                           }
                           while ( thisb < (signed int)&dword_507C08 );
                           memset(&uTextureID_Optkb, 0, 0x14u);
-                          pIcons_LOD->_40F9C5();
+                          pIcons_LOD->SyncLoadedFilesCount();
                           uAction = 0;
                           do
                           {
@@ -1263,7 +1262,7 @@
                       pTexture_RestUI_CurrentHourglassFrame->Release();
                       pTexture_RestUI_CurrentHourglassFrame = 0;
                       pTexture_RestUI_CurrentSkyFrame = 0;
-                      pIcons_LOD->_40F9C5();
+                      pIcons_LOD->SyncLoadedFilesCount();
                       pIcons_LOD->_4114F2();
                       _506F18_num_hours_to_sleep = 0;
                       dword_506F14 = 0;
@@ -2295,10 +2294,7 @@
             pNPCData4 = (NPCData *)((signed int)pGames_LOD->uNumSubDirs / 2);
             v70 = atoi(v216.pProperties[0]);
             if ( v70 <= 0 || v70 >= 77 )
-            {
-              v1 = "";
               continue;
-            }
             v71 = v70;
             strcpy(Str2, pMapStats->pInfos[v70].pFilename);
             pNPCData3 = 0;
@@ -2319,7 +2315,6 @@
                 dword_6BE364_game_settings_1 |= 1u;
                 uGameState = GAME_STATE_2;
                 OnMapLeave();
-                v1 = "";
                 continue;
               }
             }
@@ -2329,10 +2324,7 @@
           else
           {
             if ( v216.uPropCount != 3 )
-            {
-              v1 = "";
               continue;
-            }
             v74 = atoi(v216.pProperties[0]);
             thisi = atoi(v216.pProperties[1]);
             v75 = atoi(v216.pProperties[2]);
@@ -2346,7 +2338,6 @@
                 pParty->vPosition.y = v77;
                 pParty->vPosition.z = v76;
                 pParty->uFallStartY = v76;
-                v1 = "";
                 continue;
               }
             }
@@ -2365,7 +2356,6 @@
                       pParty->vPosition.y = v77;
                       pParty->vPosition.z = v76;
                       pParty->uFallStartY = v76;
-                      v1 = "";
                       continue;
                     }
                   }
@@ -2376,7 +2366,6 @@
             v73 = "Can't jump to that location!";
           }
           ShowStatusBarString(v73, 6u);
-          v1 = "";
           continue;
         case UIMSG_CastQuickSpell:
           if ( bUnderwater == 1 )
@@ -2386,10 +2375,7 @@
             continue;
           }
           if ( !uActiveCharacter || (pPlayer2 = pPlayers[uActiveCharacter], pPlayer2->uTimeToRecovery) )
-          {
-            v1 = "";
             continue;
-          }
           _42777D_CastSpell_UseWand_ShootArrow(pPlayer2->uQuickSpell, uActiveCharacter - 1, 0, 0, uActiveCharacter);
           continue;
         case UIMSG_CastSpell_Monster_Improvement:
@@ -2408,10 +2394,7 @@
           v44 = (unsigned __int16)v81;
           v84 = v83 >> 16;
           if ( PID_TYPE(v44) != 3 || v84 >= 5120 )
-          {
-            v1 = "";
             continue;
-          }
           pSpellInfo = (CastSpellInfo *)pGUIWindow_Settings->ptr_1C;
           if ( uMessage == UIMSG_CastSpell_Shoot_Monster )
           {
@@ -2437,10 +2420,7 @@
         case UIMSG_1C:
 			__debugbreak();
           if ( !uActiveCharacter || pCurrentScreen )
-          {
-            v1 = "";
             continue;
-          }
           ptr_507BC8 = GUIWindow::Create(0, 0, 640, 480, WINDOW_68, uMessageParam, 0);
           pCurrentScreen = SCREEN_19;
           pEventTimer->Pause();
@@ -2448,10 +2428,7 @@
         case UIMSG_1B:
 			__debugbreak();
           if ( !uActiveCharacter )
-          {
-            v1 = "";
             continue;
-          }
           if ( pParty->bTurnBasedModeOn != 1 )
           {
             if ( pActors[uMessageParam].uAIState == 5 )
@@ -2461,10 +2438,7 @@
             continue;
           }
           if ( pTurnEngine->field_4 == 1 || pTurnEngine->field_4 == 3 )
-          {
-            v1 = "";
             continue;
-          }
           if ( !(pTurnEngine->field_18 & 2) )
           {
             if ( pActors[uMessageParam].uAIState == 5 )
@@ -2476,20 +2450,14 @@
 
         case UIMSG_Attack:
           if ( !uActiveCharacter )
-          {
-            v1 = "";
             continue;
-          }
           if ( pParty->bTurnBasedModeOn != 1 )
           {
             _42ECB5_PlayerAttacksActor();
             continue;
           }
           if ( pTurnEngine->field_4 == 1 || pTurnEngine->field_4 == 3 )
-          {
-            v1 = "";
             continue;
-          }
           if ( !(pTurnEngine->field_18 & 2) )
             _42ECB5_PlayerAttacksActor();
           continue;
@@ -2552,10 +2520,7 @@
               v88 = pGlobalTXT_LocalizationStrings[479];// "You can't rest here!"
             ShowStatusBarString(v88, 2);
             if ( !uActiveCharacter )
-            {
-              v1 = "";
               continue;
-            }
             pPlayers[uActiveCharacter]->PlaySound((PlayerSpeech)13, 0);
             continue;
           }
@@ -2579,10 +2544,7 @@
             v88 = pGlobalTXT_LocalizationStrings[479];// "You can't rest here!"
           ShowStatusBarString(v88, 2u);
           if ( !uActiveCharacter )
-          {
-            v1 = "";
             continue;
-          }
           pPlayers[uActiveCharacter]->PlaySound((PlayerSpeech)13, 0);
           continue;
         case UIMSG_Rest8Hour:
@@ -2803,7 +2765,8 @@
                     dword_50C9EC[3 * dword_50C9E8 + 2] = uActiveCharacter - 1;
                     ++dword_50C9E8;
                   }*/
-                  pMessageQueue_50CBD0->AddMessage(UIMSG_CastSpellFromBook, v103, uActiveCharacter - 1);
+                  pMessageQueue_50C9E8->AddMessage(UIMSG_CastSpellFromBook, v103, uActiveCharacter - 1);
+                //  pMessageQueue_50CBD0->AddMessage(UIMSG_CastSpellFromBook, v103, uActiveCharacter - 1);
                 }
                 else
                 {
@@ -2819,7 +2782,7 @@
             _42777D_CastSpell_UseWand_ShootArrow(uMessageParam, v199, 0, 0, 0);
         continue;
 
-        case UIMSG_92:
+        case UIMSG_SpellScrollUse:
 			__debugbreak();
           if ( pTurnEngine->field_4 != 3 )
             _42777D_CastSpell_UseWand_ShootArrow(uMessageParam, v199, 133, 1, 0);
@@ -2943,7 +2906,7 @@
           pCharacterScreen_DetalizBtn = pGUIWindow_CurrentMenu->CreateButton(v121, v123, v125, v128, 1, 0, UIMSG_ChangeDetaliz, 0, 0,
                          pGlobalTXT_LocalizationStrings[64],// "Detail Toggle"
                          0);
-          pCharacterScreen_DollBtn = pGUIWindow_CurrentMenu->CreateButton(0x1DCu, 0, 0xA4u, 0x159u, 1, 0, UIMSG_ClickPaperdoll, 0, 0, v1, 0);
+          pCharacterScreen_DollBtn = pGUIWindow_CurrentMenu->CreateButton(0x1DCu, 0, 0xA4u, 0x159u, 1, 0, UIMSG_ClickPaperdoll, 0, 0, "", 0);
           viewparams->bRedrawGameUI = 1;
           continue;
         case UIMSG_ClickPaperdoll:
@@ -3261,9 +3224,13 @@
       }
     }
   }
-  pMessageQueue_50CBD0->uNumMessages = dword_50C9E8;
-  memcpy(pMessageQueue_50CBD0->pMessages, dword_50C9EC, 12 * dword_50C9E8);
-  dword_50C9E8 = 0;
+  pMessageQueue_50CBD0->uNumMessages = pMessageQueue_50C9E8->uNumMessages;//dword_50C9E8;
+  memcpy(pMessageQueue_50CBD0->pMessages, pMessageQueue_50C9E8->pMessages, sizeof(GUIMessage) * pMessageQueue_50C9E8->uNumMessages);
+  //memcpy(pMessageQueue_50CBD0->pMessages, dword_50C9EC, 12 * dword_50C9E8);
+  //dword_50C9E8 = 0;
+
+
+   pMessageQueue_50C9E8->uNumMessages=0;
   if ( dword_50C9DC )
   {
     /*if ( (signed int)pMessageQueue_50CBD0->uNumMessages < 40 )
@@ -3395,11 +3362,11 @@
           break;
         case UIMSG_PlayerCreation_FacePrev:
           pPlayer = &pParty->pPlayers[pParam];
-          if (!pPlayer->uFace)
-            pPlayer->uFace = 19;
+          if (!pPlayer->uCurrentFace)
+            pPlayer->uCurrentFace = 19;
           else
-            pPlayer->uFace -= 1;
-          pPlayer->uVoiceID = pPlayer->uFace;
+            pPlayer->uCurrentFace -= 1;
+          pPlayer->uVoiceID = pPlayer->uCurrentFace;
           pPlayer->SetInitialStats();
           pPlayer->SetSexByVoice();
           pPlayer->RandomizeName();
@@ -3413,8 +3380,8 @@
           break;
         case UIMSG_PlayerCreation_FaceNext:
           pPlayer = &pParty->pPlayers[pParam];
-          v20 = (char)((int)pPlayer->uFace + 1) % 20;
-          pPlayer->uFace = v20;
+          v20 = (char)((int)pPlayer->uCurrentFace + 1) % 20;
+          pPlayer->uCurrentFace = v20;
           pPlayer->uVoiceID = v20;
           pPlayer->SetInitialStats();
           pPlayer->SetSexByVoice();
@@ -3665,15 +3632,9 @@
 //----- (004369DB) --------------------------------------------------------
 void Vec3_float_::Normalize()
 {
-  Vec3_float_ *v1; // esi@1
-  double v2; // st7@1
-
-  auto a1 = this;
-  v1 = a1;
-  v2 = 1.0 / sqrt(a1->x * a1->x + a1->y * a1->y + a1->z * a1->z);
-  v1->x = v2 * v1->x;
-  v1->y = v2 * v1->y;
-  v1->z = v2 * v1->z;
+  this->x = (1.0 / sqrt(this->x * this->x + this->y * this->y + this->z * this->z)) * this->x;
+  this->y = (1.0 / sqrt(this->x * this->x + this->y * this->y + this->z * this->z)) * this->y;
+  this->z = (1.0 / sqrt(this->x * this->x + this->y * this->y + this->z * this->z)) * this->z;
 }
 
 //----- (004385B5) --------------------------------------------------------
@@ -5397,41 +5358,32 @@
   int v8; // ST14_4@1
   int v9; // edi@1
   int anglea; // [sp+20h] [bp+8h]@1
+
   v7 = sRotX;
   v8 = sDepth;
   v9 = sRotY;
   anglea = (unsigned __int64)(stru_5C6E00->SinCos(sRotX) * (signed __int64)sDepth) >> 16;
-  *outx = v.x + ((unsigned __int64)(stru_5C6E00->SinCos(v9) * (signed __int64)anglea) >> 16);
-  *outy = v.y
-        + ((unsigned __int64)(stru_5C6E00->SinCos(v9 - stru_5C6E00->uIntegerHalfPi)
-                            * (signed __int64)anglea) >> 16);
-  *outz = v.z
-        + ((unsigned __int64)(stru_5C6E00->SinCos(v7 - stru_5C6E00->uIntegerHalfPi) * (signed __int64)v8) >> 16);*/
+  *outx = v.x + ((unsigned __int64)(stru_5C6E00->SinCos(sRotY) * (signed __int64)anglea) >> 16);
+  *outy = v.y + ((unsigned __int64)(stru_5C6E00->SinCos(sRotY - stru_5C6E00->uIntegerHalfPi) * (signed __int64)anglea) >> 16);
+  *outz = v.z + ((unsigned __int64)(stru_5C6E00->SinCos(sRotX - stru_5C6E00->uIntegerHalfPi) * (signed __int64)sDepth) >> 16);*/
 
  float cosf_x = cosf(3.14159265f * sRotX / 1024.0f),
+       sinf_x = sinf(3.14159265f * sRotX / 1024.0f),
        cosf_y = cosf(3.14159265f * sRotY / 1024.0f),
-       sinf_x = sinf(3.14159265f * sRotX / 1024.0f),
        sinf_y = sinf(3.14159265f * sRotY / 1024.0f);
-
- *outx = v.x + ((unsigned __int64)((double)sDepth * cosf_y * cosf_x) >> 16);
- *outy = v.y + ((unsigned __int64)((double)sDepth * sinf_y * cosf_x) >> 16);
- *outz = v.z + ((unsigned __int64)((double)sDepth * sinf_x) >> 16);
+ sDepth = 14000000;
+ *outx = v.x + ((unsigned __int64)(sinf_y * (signed __int64)((unsigned __int64)(cosf_x * (signed __int64)sDepth)>> 16)));
+ *outy = v.y + ((unsigned __int64)(cosf_y * (signed __int64)((unsigned __int64)(cosf_x * (signed __int64)sDepth)>> 16)));
+ *outz = v.z + ((unsigned __int64)(sinf_x * (signed __int64)sDepth) >> 16);
 
 }
 
 //----- (0043AB61) --------------------------------------------------------
 void Vec3_int_::Normalize(int *x, int *y, int *z)
 {
-  int *v3; // edi@1
-  int *v4; // esi@1
-  signed int v5; // eax@1
-
-  v3 = x;
-  v4 = y;
-  v5 = integer_sqrt(*y * *y + *z * *z + *x * *x);
-  *v3 *= 65536 / (v5 | 1);
-  *v4 *= 65536 / (v5 | 1);
-  *z *= 65536 / (v5 | 1);
+  *x *= 65536 / (integer_sqrt(*y * *y + *z * *z + *x * *x) | 1);
+  *y *= 65536 / (integer_sqrt(*y * *y + *z * *z + *x * *x) | 1);
+  *z *= 65536 / (integer_sqrt(*y * *y + *z * *z + *x * *x) | 1);
 }
 
 //----- (0043AE12) --------------------------------------------------------
@@ -6055,10 +6007,10 @@
     papredoll_dlhs[v1] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
     wsprintfA(pContainer, "pc23v%dlhu", v9);
     papredoll_dlhus[v1] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
-    v6 = pPlayers[v1 + 1]->uFace;
+    v6 = pPlayers[v1 + 1]->uCurrentFace;
     if ( v6 == 12 || v6 == 13 )
-      papredoll_dbrds[pPlayers[v8]->uFace] = 0;
-    papredoll_flying_feet[pPlayers[v8]->uFace] = 0;
+      papredoll_dbrds[pPlayers[v8]->uCurrentFace] = 0;
+    papredoll_flying_feet[pPlayers[v8]->uCurrentFace] = 0;
     IsPlayerWearingWatersuit[v8] = 1;
   }
 }
@@ -6080,22 +6032,22 @@
   {
     v2 = &pPlayers[uPlayerID];
     v3 = uPlayerID - 1;
-    papredoll_dbods[v3] = pIcons_LOD->LoadTexture(dbod_texnames_by_face[(*v2)->uFace], TEXTURE_16BIT_PALETTE);
-    papredoll_dlads[v3] = pIcons_LOD->LoadTexture(dlad_texnames_by_face[(*v2)->uFace], TEXTURE_16BIT_PALETTE);
-    papredoll_dlaus[v3] = pIcons_LOD->LoadTexture(dlau_texnames_by_face[(*v2)->uFace], TEXTURE_16BIT_PALETTE);
-    papredoll_drhs[v3] = pIcons_LOD->LoadTexture(drh_texnames_by_face[(*v2)->uFace], TEXTURE_16BIT_PALETTE);
-    papredoll_dlhs[v3] = pIcons_LOD->LoadTexture(dlh_texnames_by_face[(*v2)->uFace], TEXTURE_16BIT_PALETTE);
-    papredoll_dlhus[v3] = pIcons_LOD->LoadTexture(dlhu_texnames_by_face[(*v2)->uFace], TEXTURE_16BIT_PALETTE);
-    v4 = (int)&(*v2)->uFace;
+    papredoll_dbods[v3] = pIcons_LOD->LoadTexture(dbod_texnames_by_face[(*v2)->uCurrentFace], TEXTURE_16BIT_PALETTE);
+    papredoll_dlads[v3] = pIcons_LOD->LoadTexture(dlad_texnames_by_face[(*v2)->uCurrentFace], TEXTURE_16BIT_PALETTE);
+    papredoll_dlaus[v3] = pIcons_LOD->LoadTexture(dlau_texnames_by_face[(*v2)->uCurrentFace], TEXTURE_16BIT_PALETTE);
+    papredoll_drhs[v3] = pIcons_LOD->LoadTexture(drh_texnames_by_face[(*v2)->uCurrentFace], TEXTURE_16BIT_PALETTE);
+    papredoll_dlhs[v3] = pIcons_LOD->LoadTexture(dlh_texnames_by_face[(*v2)->uCurrentFace], TEXTURE_16BIT_PALETTE);
+    papredoll_dlhus[v3] = pIcons_LOD->LoadTexture(dlhu_texnames_by_face[(*v2)->uCurrentFace], TEXTURE_16BIT_PALETTE);
+    v4 = (int)&(*v2)->uCurrentFace;
     v5 = *(char *)v4;
     if ( *(char *)v4 == 12 || v5 == 13 )
     {
       wsprintfA(pContainer, "pc%02dbrd", v5 + 1);
-      v4 = (int)&(*v2)->uFace;
+      v4 = (int)&(*v2)->uCurrentFace;
       papredoll_dbrds[*(char *)v4] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
     }
     wsprintfA(pContainer, "item281pc%02d", *(char *)v4 + 1);
-    papredoll_flying_feet[(*v2)->uFace] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+    papredoll_flying_feet[(*v2)->uCurrentFace] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
     result = v7;
     IsPlayerWearingWatersuit[v7] = 0;
   }
@@ -9165,14 +9117,14 @@
 
 
 //----- (0040D75D) --------------------------------------------------------
-char __fastcall pPrimaryWindow_draws_text(int a1, const char *pText, int *pXY)
-{
+void pPrimaryWindow_draws_text( int a1, const char *pText, int *pXY )
+    {
   const char *v3; // ST0C_4@1
   __int64 v4; // qax@1
 
   v3 = pText;
   v4 = LOBYTE(pFontComic->uFontHeight) - 3;
-  return pPrimaryWindow->DrawText(
+  pPrimaryWindow->DrawText(
            pFontComic,
            *pXY,
            pXY[1] - (((signed int)v4 - HIDWORD(v4)) >> 1) + 3,
@@ -10855,9 +10807,10 @@
           {
             if ( v51 != 5 )
             {
-              v19 = v0->AddItem(0xFFFFFFFFu, 0xDCu);
+              v19 = v0->AddItem(-1, 0xDCu);
               if ( v19 )
-                *(int *)&v0->field_1F5[36 * v19 + 15] = 1;
+               // *(int *)&v0->field_1F5[36 * v19 + 15] = 1;
+                 v0->pOwnItems[v19-1].uAttributes=ITEM_IDENTIFIED;
               v20 = v47 + 50 * v15;
               v0->pInventoryItems[pOut.z].uItemID = v51;
               v0->pInventoryItems[pOut.z].uEnchantmentType = (pParty->pPickedItem.uEnchantmentType
@@ -10879,9 +10832,10 @@
                 *(int *)(a2.y + 532) = pParty->pPickedItem.uItemID;
               else
                 *(int *)(a2.y + 536) = pParty->pPickedItem.uEnchantmentType;
-              v21 = v0->AddItem(0xFFFFFFFFu, 0xDCu);
+              v21 = v0->AddItem(-1, 0xDCu);
               if ( v21 )
-                *(int *)&v0->field_1F5[36 * v21 + 15] = 1;
+                //*(int *)&v0->field_1F5[36 * v21 + 15] = 1;
+                v0->pOwnItems[v21-1].uAttributes=ITEM_IDENTIFIED;
               goto LABEL_74;
             }
             goto LABEL_115;
@@ -10891,7 +10845,7 @@
           v23 = 0;
         }
       }
-      v0->_4160CA(v23);
+      v0->ItemsEnchant(v23);
       pAudioPlayer->PlaySound(SOUND_8, 0, 0, -1, 0, 0, 0, 0);
 
       pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 0, 0);
@@ -11354,8 +11308,8 @@
 }
 
 //----- (004179BC) --------------------------------------------------------
-char __fastcall sub_4179BC_draw_tooltip(const char *a1, const char *a2)
-{
+void __fastcall sub_4179BC_draw_tooltip( const char *a1, const char *a2 )
+    {
   const char *v2; // ebx@1
   const char *v3; // edi@1
   unsigned int v4; // eax@1
@@ -11382,7 +11336,7 @@
   v4 = TargetColor(0xFFu, 0xFFu, 0x9Bu);
   sprintf(pTmpBuf, format_4E2D80, v4, v3);
   Dst.DrawTitleText(pFontCreate, 0, 0, 0, pTmpBuf, 3u);
-  return Dst.DrawText(pFontSmallnum, 1, LOBYTE(pFontLucida->uFontHeight), 0, v2, 0, 0, 0);
+  Dst.DrawText(pFontSmallnum, 1, LOBYTE(pFontLucida->uFontHeight), 0, v2, 0, 0, 0);
 }
 
 //----- (00417AD4) --------------------------------------------------------
--- a/mm7_6.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/mm7_6.cpp	Tue May 21 11:24:35 2013 +0200
@@ -1,44 +1,37 @@
 #include "MM7.h"
 
-#include "MapInfo.h"
+
+
+#include "Sprites.h"
+#include "BSPModel.h"
+#include "OutdoorCamera.h"
+#include "Mouse.h"
+#include "Keyboard.h"
+#include "stru6.h"
+
+#include "Vis.h"
 #include "Game.h"
 #include "GUIWindow.h"
 #include "GUIFont.h"
-#include "GUIProgressBar.h"
 #include "Party.h"
 #include "AudioPlayer.h"
 #include "Outdoor.h"
-#include "IndoorCamera.h"
 #include "Overlays.h"
-#include "Monsters.h"
-#include "Arcomage.h"
 #include "LOD.h"
 #include "Actor.h"
-#include "Allocator.h"
 #include "Events.h"
 #include "Viewport.h"
-#include "FrameTableInc.h"
 #include "Math.h"
 #include "SpriteObject.h"
 #include "ObjectList.h"
-#include "Chest.h"
-#include "PaletteManager.h"
-#include "DecorationList.h"
-#include "SaveLoad.h"
 #include "stru123.h"
 #include "Time.h"
 #include "IconFrameTable.h"
 #include "Awards.h"
-#include "Autonotes.h"
-#include "stru160.h"
 #include "TurnEngine.h"
 #include "CastSpellInfo.h"
-#include "Weather.h"
 #include "stru298.h"
 #include "texts.h"
-#include "StorylineTextTable.h"
-#include "Events2D.h"
-#include "Log.h"
 
 #include "mm7_data.h"
 
@@ -2410,113 +2403,25 @@
 //----- (00427E01) --------------------------------------------------------
 void CastSpellInfo::_427E01_cast_spell()
 {
-  //int v1; // esi@1
   int v2; // edi@1
   CastSpellInfo *pCastSpell; // ebx@2
-  //signed int v4; // eax@8
-  //__int16 v5; // ax@9
   signed int v6; // eax@14
-  //__int16 v7; // ax@23
-  //__int16 v8; // ax@24
-  //char v9; // al@44
-  //int v10; // eax@45
   unsigned __int16 v11; // cx@45
-  //signed int v12; // ecx@48
-  //int v13; // eax@53
   unsigned __int8 v14; // zf@53
-  //unsigned int v15; // edx@53
-  //signed int v16; // eax@53
-  //Player *v17; // esi@70
-  //int v18; // eax@72
-  //int v19; // eax@74
-  Player *v20; // eax@74
   signed int i; // esi@76
-  //int v22; // eax@88
   __int16 v23; // ax@88
-  //int v24; // ecx@93
-  //int v25; // ecx@94
-  //signed __int64 v26; // qax@100
-  //char *v27; // ecx@100
-  //unsigned __int64 v28; // qax@102
-  int v29; // ecx@105
-  int v30; // ecx@106
-  //int v31; // eax@112
-  //int v32; // eax@112
-  //char *v33; // edx@113
-  //int v34; // eax@121
-  //int v35; // eax@123
-  //int v36; // edx@125
-  //int v37; // eax@129
-  //signed int v38; // edi@129
-  //signed int v39; // eax@129
-  //int v40; // ecx@129
-  //int v41; // eax@129
-  //signed int v42; // eax@129
-  //int *v43; // ecx@129
-  //int v44; // eax@132
-  //int v45; // ecx@132
-  int v46; // eax@132
-  //unsigned int v47; // edx@133
-  //int v48; // eax@137
-  //int v49; // eax@137
-  //int v50; // eax@141
   int v51; // eax@146
   __int16 v52; // ax@153
-  //int v53; // eax@153
   signed __int64 v54; // qax@164
-  int v55; // edi@164
-  //stru6 *v56; // eax@165
-  int v57; // eax@169
+  Actor *v55; // edi@164
   signed __int64 v58; // qax@177
-  int v59; // edi@177
+  Actor *pActor; // edi@177
   unsigned __int16 v60; // ax@184
   int v61; // ecx@184
-  //int v62; // eax@186
-  int v63; // ecx@187
-  int v64; // ecx@188
-  int v65; // ecx@189
-  //const char *v66; // ecx@200
-  //unsigned int v67; // edx@201
-  char v68; // al@207
   ItemGen *v69; // esi@211
-  int v70; // ecx@214
-  int v71; // ecx@215
-  int v72; // ecx@216
-  //__int16 v73; // ST1C_2@222
-  //__int16 v74; // ST18_2@222
-  //stru6 *v75; // eax@222
-  //int v76; // ecx@223
-  //int v77; // ecx@224
-  //int v78; // ecx@225
-  //int v79; // eax@227
-  //int v80; // eax@232
-  //__int16 v81; // ST18_2@245
-  //stru6 *v82; // eax@245
-  //signed int v83; // edi@245
-  //__int16 v84; // ST18_2@245
-  //stru6 *v85; // eax@245
-  //__int16 v86; // ST18_2@245
-  //stru6 *v87; // eax@245
-  //__int16 v88; // ST18_2@245
-  //stru6 *v89; // eax@245
   double v90; // st7@245
-  //int v91; // eax@250
   Player *v92; // eax@255
-  //__int16 v93; // ST18_2@260
-  //stru6 *v94; // eax@260
-  //__int16 v95; // ST18_2@260
-  //stru6 *v96; // eax@260
-  //__int16 v97; // ST18_2@260
-  //stru6 *v98; // eax@260
-  //__int16 v99; // ST18_2@260
-  //stru6 *v100; // eax@260
-  //int v101; // ecx@261
-  //int v102; // ecx@262
-  //int v103; // ecx@263
-  //int v104; // eax@265
   int v105; // edi@271
-  //__int16 v106; // ST18_2@272
-  //stru6 *v107; // eax@272
   __int16 v108; // ST1C_2@274
   __int16 v109; // ST18_2@274
   stru6 *v110; // eax@274
@@ -2528,92 +2433,21 @@
   int v116; // edx@279
   int v117; // edx@281
   int v118; // edx@283
-  int v119; // edi@286
-  //int v120; // eax@286
-  //int v121; // eax@286
   signed int v122; // eax@286
-  //int v123; // ecx@288
-  //int v124; // ecx@289
-  //int v125; // ecx@290
-  //int v126; // eax@292
   int v127; // eax@296
-  //__int16 v128; // ST18_2@303
-  //stru6 *v129; // eax@303
-  //__int16 v130; // ST18_2@303
-  //stru6 *v131; // eax@303
-  //__int16 v132; // ST18_2@303
-  //stru6 *v133; // eax@303
-  //__int16 v134; // ST18_2@303
-  //stru6 *v135; // eax@303
-  //unsigned __int64 v136; // qax@304
-  //char *v137; // ecx@304
-  //int v138; // ecx@305
-  int v139; // ecx@306
-  //int v140; // eax@308
-  //__int16 v141; // ST18_2@311
-  //stru6 *v142; // eax@311
-  //__int16 v143; // ST18_2@311
-  //stru6 *v144; // eax@311
-  //__int16 v145; // ST18_2@311
-  //stru6 *v146; // eax@311
-  //__int16 v147; // ST18_2@311
-  //stru6 *v148; // eax@311
-  int v149; // ecx@312
-  int v150; // ecx@313
-  int v151; // ecx@314
-  //signed int v152; // eax@322
   int v153; // ecx@322
   int v154; // eax@322
   int v155; // eax@323
   int v156; // eax@323
-  //int v157; // eax@326
-  double v158; // st7@326
-  double v159; // st6@326
-  //signed __int64 v160; // qtt@334
-  //int v161; // eax@339
   int v162; // edi@340
-  //int v163; // eax@340
   signed int v164; // eax@340
   signed int v165; // edi@340
-  //stru6 *v166; // eax@340
-  //stru6 *v167; // eax@340
   signed int v168; // edi@343
   int v169; // eax@344
-  //int v170; // ecx@346
-  //int v171; // ecx@347
-  //int v172; // ecx@348
-  //int v173; // edi@350
   signed int v174; // edi@355
-  //__int16 v175; // ST18_2@357
-  //stru6 *v176; // eax@357
-  //__int16 v177; // ST18_2@357
-  //stru6 *v178; // eax@357
-  //__int16 v179; // ST18_2@357
-  //stru6 *v180; // eax@357
-  //__int16 v181; // ST18_2@357
-  //stru6 *v182; // eax@357
-  //signed __int64 v183; // qax@357
-  int v184; // ecx@358
-  int v185; // ecx@359
-  int v186; // ecx@360
-  //int v187; // eax@367
   int v188; // esi@369
   int v189; // edi@369
-  //const char *v190; // ecx@377
   signed int v191; // edi@379
-  int v192; // ecx@382
-  //int v193; // ecx@383
-  //int v194; // ecx@384
-  int v195; // eax@386
-  int v196; // eax@387
-  //__int16 v197; // ST18_2@395
-  //stru6 *v198; // eax@395
-  //__int16 v199; // ST18_2@395
-  //stru6 *v200; // eax@395
-  //__int16 v201; // ST18_2@395
-  //stru6 *v202; // eax@395
-  //__int16 v203; // ST18_2@395
-  //stru6 *v204; // eax@395
   signed int v205; // edi@405
   int v206; // eax@407
   __int16 v207; // cx@407
@@ -2628,41 +2462,15 @@
   double v216; // st7@415
   double v217; // st6@415
   signed __int64 v218; // qtt@423
-  //int v219; // ecx@425
-  //int v220; // ecx@426
-  //int v221; // edi@428
-  Player *v222; // edi@434
   char v223; // al@438
-  //int v224; // ecx@442
-  //int v225; // ecx@443
-  //int v226; // eax@451
+
   int v227; // esi@453
   unsigned int v228; // edi@454
   int v229; // edi@466
-  //__int16 v230; // ST18_2@469
-  //stru6 *v231; // eax@469
-  //signed int v232; // esi@469
-  //__int16 v233; // ST18_2@469
-  //stru6 *v234; // eax@469
-  //__int16 v235; // ST18_2@469
-  //stru6 *v236; // eax@469
-  //__int16 v237; // ST18_2@469
-  //stru6 *v238; // eax@469
-  //__int16 v239; // ST1C_2@469
-  char *v240; // ecx@472
+
+  ItemGen *v240; // ecx@472
   double v241; // st7@478
-  signed __int64 v242; // qax@484
-  char *v243; // ecx@484
-  char *v244; // eax@488
-  int v245; // edi@492
-  int v246; // eax@492
-  char *v247; // eax@497
-  char v248; // al@497
-  char v249; // cf@500
-  float v250; // esi@507
-  char v251; // al@507
-  int v252; // edx@510
-  int m; // esi@510
+  ItemGen *v245; // edi@492
   int v254; // eax@513
   int v255; // esi@513
   int v256; // ecx@513
@@ -2672,455 +2480,174 @@
   int v260; // eax@518
   int v261; // esi@519
   int v262; // edx@521
-  int v263; // ecx@521
+  int *v263; // ecx@521
   int v264; // esi@521
   int v265; // edx@521
   int *ii; // eax@522
   int v267; // eax@524
   int v268; // eax@524
-  int v269; // eax@526
-  char *v270; // eax@531
   char v271; // al@531
-  char v272; // cf@534
-  //float v273; // esi@541
-  char v274; // al@541
-  int v275; // edx@544
-  int k; // esi@544
   int v277; // edx@548
   int v278; // ecx@548
   char v279; // al@550
   int v280; // eax@552
-  int v281; // esi@553
+  int *v281; // esi@553
   int v282; // edx@555
-  int v283; // ecx@555
+  int *v283; // ecx@555
   int v284; // esi@555
   int v285; // edx@555
   int *l; // eax@556
-  int v287; // eax@558
-  int v288; // eax@558
-  ItemGen *v289; // eax@560
-  signed int v290; // eax@560
-  unsigned __int8 v291; // al@564
-  char v292; // al@573
-  int v293; // eax@575
   ItemGen *v294; // esi@575
   int v295; // edx@575
   int kk; // edi@575
-  int v297; // edx@579
-  int v298; // ecx@579
-  char v299; // al@581
-  int v300; // eax@583
-  int v301; // edi@584
-  int v302; // edx@586
-  int v303; // ecx@586
-  int v304; // edi@586
-  int v305; // edx@586
-  int *jj; // eax@587
-  int v307; // eax@589
-  int v308; // eax@589
-  char *v309; // ecx@593
-  char v310; // sf@593
-  unsigned __int8 v311; // of@593
-  char v312; // cl@597
   char v313; // al@606pGame->GetStru6()
-  int v314; // edx@607
-  int j; // esi@607
-  unsigned int v316; // eax@613
   const char *v317; // ecx@617
   Player *v318; // ecx@619
   unsigned int v319; // edi@627
-  //int v320; // ecx@629
-  //int v321; // ecx@630
-  //int v322; // edi@632
   int v323; // edi@635
   char *v324; // eax@635
   Player *v325; // ecx@640
-  //int v326; // eax@643
-  //int v327; // eax@648
   int v328; // ecx@651
   int v329; // ecx@652
   int v330; // edi@654
-  //__int16 v331; // ST18_2@658
-  //stru6 *v332; // eax@658
-  //__int16 v333; // ST18_2@658
-  //stru6 *v334; // eax@658
-  //__int16 v335; // ST18_2@658
-  //stru6 *v336; // eax@658
-  //__int16 v337; // ST18_2@658
-  //stru6 *v338; // eax@658
-  //int v339; // ecx@659
-  //int v340; // ecx@660
-  //int v341; // eax@663
   signed int v342; // edi@668
   signed int v343; // edi@670
   unsigned __int64 v344; // ST08_8@670
-  //__int16 v345; // ST1C_2@671
-  //__int16 v346; // ST18_2@671
-  //stru6 *v347; // eax@671
-  //int v348; // ecx@672
-  //int v349; // ecx@673
-  //int v350; // edi@676
   Player *v351; // edi@680
-  //__int16 v352; // ST18_2@685
-  //stru6 *v353; // eax@685
-  int v354; // ecx@686
-  int v355; // ecx@687
-  int v356; // eax@689
   Player *v357; // edi@694
-  //unsigned __int16 v358; // ST1C_2@695
-  //__int16 v359; // ST18_2@695
-  //stru6 *v360; // eax@695
-  //__int16 v361; // ST1C_2@697
-  //__int16 v362; // ST18_2@697
-  //stru6 *v363; // eax@697
-  int v364; // ecx@698
-  int v365; // ecx@699
-  int v366; // eax@701
-  //stru6 *v367; // eax@704
-  //int v368; // eax@704
   Actor *v369; // edi@705
-  //int v370; // eax@706
-  int v371; // ecx@709
-  int v372; // ecx@710
   int v373; // eax@715
   int v374; // eax@717
-  //Player *v375; // edi@717
   int v376; // eax@717
   Player *v377; // ecx@719
-  int v378; // ecx@721
-  int v379; // ecx@722
-  int v380; // eax@724
   int v381; // edi@727
   int v382; // ecx@727
   Player *v383; // eax@728
   int v384; // eax@733
-  //int v385; // edi@736
-  //signed int v386; // eax@736
-  //Player *v387; // edi@738
   int v388; // edi@740
-  //unsigned __int16 v389; // ST1C_2@740
-  //__int16 v390; // ST18_2@740
-  //stru6 *v391; // eax@740
-  int v392; // ecx@742
-  //int v393; // ecx@743
-  //int v394; // ecx@744
-  //int v395; // edi@747
   int v396; // eax@752
   int v397; // eax@757
   int v398; // eax@757
   int v399; // eax@757
-  //char *v400; // esi@757
-  //Game *v401; // ecx@759
-  //__int16 v402; // ST1C_2@759
-  //__int16 v403; // ST18_2@759
-  //stru6 *v404; // eax@759
-  //int v405; // ecx@761
-  //int v406; // ecx@762
-  //int v407; // edi@765
-  //__int16 v408; // ST1C_2@769
-  //__int16 v409; // ST18_2@769
-  //stru6 *v410; // eax@769
-  //int v411; // ecx@772
-  //int v412; // ecx@773
-  //int v413; // edi@775
-  //__int16 v414; // ST1C_2@781
-  //__int16 v415; // ST18_2@781
-  //stru6 *v416; // eax@781
-  int v417; // eax@787
+  Actor *v417; // eax@787
   int v418; // ecx@789
   __int16 v419; // ax@791
   signed int v420; // eax@793
-  int v421; // edx@793
+  ItemGen *v421; // edx@793
   const char *v422; // eax@801
-  int v423; // ecx@808
-  int v424; // ecx@809
-  int v425; // eax@811
   signed int v426; // eax@815
-  //signed int v427; // eax@820
-  int v428; // ecx@825
-  int v429; // ecx@826
-  int v430; // eax@828
-  //stru6 *v431; // eax@831
-  //int v432; // eax@831
   Actor *v433; // edi@832
-  //int v434; // eax@833
   int v435; // ecx@837
-  int v436; // ecx@838
-  //__int16 v437; // ST1C_2@843
-  //__int16 v438; // ST18_2@843
-  //stru6 *v439; // eax@843
   int v440; // eax@843
   int v441; // eax@847
-  //int v442; // ecx@850
-  //int v443; // ecx@851
-  //int v444; // eax@853
   signed int v445; // edi@857
   int v446; // ecx@862
   LevelDecoration *v447; // edi@864
   __int16 v448; // ax@864
   char *v449; // esi@870
   int v450; // eax@870
-  //int v451; // ecx@875
-  //int v452; // ecx@876
-  //int v453; // edi@878
-  //__int16 v454; // ST1C_2@884
-  //__int16 v455; // ST18_2@884
-  //stru6 *v456; // eax@884
-  int v457; // ecx@887
-  int v458; // ecx@888
-  int v459; // eax@890
   signed int v460; // eax@895
   Actor *v461; // eax@897
   unsigned __int16 v462; // cx@897
   signed int v463; // edx@897
-  //int v464; // ecx@905
-  //int v465; // ecx@906
-  //int v466; // edi@909
-  //__int16 v467; // ST1C_2@913
-  //__int16 v468; // ST18_2@913
-  //stru6 *v469; // eax@913
   int v470; // edi@913
   int v471; // eax@917
   int v472; // eax@917
-  //char *v473; // esi@918
-  //__int16 v474; // ST18_2@920
-  //stru6 *v475; // eax@920
-  //__int16 v476; // ST18_2@920
-  //stru6 *v477; // eax@920
-  //__int16 v478; // ST18_2@920
-  //stru6 *v479; // eax@920
-  //__int16 v480; // ST18_2@920
-  //stru6 *v481; // eax@920
-  //__int16 v482; // ST18_2@923
-  //stru6 *v483; // eax@923
-  //__int16 v484; // ST18_2@923
-  //stru6 *v485; // eax@923
-  //__int16 v486; // ST18_2@923
-  //stru6 *v487; // eax@923
-  //__int16 v488; // ST18_2@923
-  //stru6 *v489; // eax@923
-  //__int16 v490; // ST1C_2@924
-  //__int16 v491; // ST18_2@924
-  //stru6 *v492; // eax@924
-  int v493; // ecx@925
-  int v494; // ecx@926
-  //__int16 v495; // ST1C_2@931
-  //__int16 v496; // ST18_2@931
-  //stru6 *v497; // eax@931
   int v498; // edi@931
   int v499; // eax@935
   int v500; // eax@935
   Player *v501; // edi@939
-  //__int16 v502; // ST18_2@940
-  //stru6 *v503; // eax@940
-  //stru6 *v504; // eax@943
   int v505; // eax@943
-  //int v506; // eax@943
   int v507; // edi@944
-  //int v508; // eax@944
   signed int v509; // eax@944
   signed int v510; // edi@944
-  Actor *v511; // edi@946
-  //int v512; // eax@946
-  SpellBuff *v513; // edi@946
-  int v514; // ecx@950
-  //int v515; // ecx@951
-  int v516; // eax@953
-  //int v517; // eax@956
   Actor *v518; // edx@957
   __int16 v519; // cx@958
-  //int v520; // ecx@968
-  //int v521; // ecx@969
-  //int v522; // eax@971
-  //__int16 v523; // ST18_2@975
-  //stru6 *v524; // eax@975
-  //__int16 v525; // ST18_2@975
-  //stru6 *v526; // eax@975
-  //__int16 v527; // ST18_2@975
-  //stru6 *v528; // eax@975
-  //__int16 v529; // ST18_2@975
-  //stru6 *v530; // eax@975
   int v531; // eax@982
-  //int v532; // eax@982
   int v533; // edi@983
-  //int v534; // eax@983
   signed int v535; // eax@983
   signed int v536; // edi@983
   stru6 *v537; // eax@984
-  int v538; // ecx@985
-  int v539; // ecx@986
-  int v540; // eax@988
-  //__int16 v541; // ST18_2@991
-  //stru6 *v542; // eax@991
-  //__int16 v543; // ST18_2@991
-  //stru6 *v544; // eax@991
-  //__int16 v545; // ST18_2@991
-  //stru6 *v546; // eax@991
-  //__int16 v547; // ST18_2@991
-  //stru6 *v548; // eax@991
   double v549; // st7@991
   unsigned __int16 v550; // di@991
-  int v551; // ecx@993
-  //int v552; // ecx@994
   Player *v553; // edi@1001
-  //__int16 v554; // ST18_2@1002
-  //stru6 *v555; // eax@1002
-  //__int16 v556; // ST18_2@1002
-  //stru6 *v557; // eax@1002
-  //__int16 v558; // ST18_2@1002
-  //stru6 *v559; // eax@1002
-  //__int16 v560; // ST18_2@1002
-  //stru6 *v561; // eax@1002
   unsigned __int16 v562; // di@1005
   signed int v563; // eax@1010
   unsigned int v564; // ecx@1011
   signed int v565; // eax@1012
   Player **v566; // ecx@1012
   int v567; // eax@1012
-  //unsigned __int16 v568; // ST1C_2@1012
-  //__int16 v569; // ST18_2@1012
-  //stru6 *v570; // eax@1012
   Player *v571; // eax@1013
   char *v572; // ecx@1013
-  int v573; // ecx@1017
-  int v574; // ecx@1018
-  int v575; // eax@1020
   signed int v576; // eax@1025
   Player *v577; // eax@1026
   int v578; // eax@1028
   __int16 v579; // ax@1029
-  //int v580; // eax@1031
   int v581; // edi@1031
-  //int v582; // eax@1031
-  //__int16 v583; // ST1C_2@1034
-  //__int16 v584; // ST18_2@1034
   char *v585; // esi@1034
-  //stru6 *v586; // eax@1034
   signed int v587; // eax@1035
-  int v588; // ecx@1036
-  int v589; // ecx@1037
-  int v590; // ecx@1038
   char v591; // al@1048
-  int v592; // esi@1052
-  int v593; // ecx@1057
-  //int v594; // ecx@1058
-  //int v595; // eax@1064
+  ItemGen *v592; // esi@1052
   int v596; // esi@1066
   unsigned int v597; // edi@1067
-  int v598; // eax@1079
-  //signed int v599; // eax@1082
   int v600; // edi@1086
   int v601; // edx@1086
   int v602; // eax@1086
   int v603; // ecx@1086
-  //int v604; // eax@1087
-  char *v605; // eax@1089
+  NPCData *pNPCData; // eax@1089
   int v606; // edx@1091
-  int v607; // ecx@1100
+  AwardType *v607; // ecx@1100
   __int16 v608; // ax@1102
   signed int v609; // eax@1104
   int v610; // edi@1106
   unsigned int v611; // eax@1106
   Player *v612; // edi@1106
   DDM_DLV_Header *v613; // eax@1108
-  int v614; // eax@1116
   int v615; // edi@1119
-  //__int16 v616; // ST1C_2@1122
-  //__int16 v617; // ST18_2@1122
-  //stru6 *v618; // eax@1122
   Player *v619; // edi@1123
-  //unsigned __int16 v620; // ST1C_2@1124
-  //__int16 v621; // ST18_2@1124
-  //stru6 *v622; // eax@1124
   signed __int64 v623; // qax@1127
-  //int v624; // eax@1127
   int v625; // edi@1129
-  //int v626; // eax@1129
   signed int v627; // eax@1129
   signed int v628; // edi@1129
   int v629; // ecx@1130
   Player *v630; // eax@1131
   int v631; // eax@1137
-  //int v632; // edi@1140
-  //Player *v633; // eax@1140
-  //signed int v634; // eax@1140
   int v635; // edi@1142
-  //unsigned __int16 v636; // ST1C_2@1142
-  //__int16 v637; // ST18_2@1142
-  //stru6 *v638; // eax@1142
-  //stru6 *v639; // eax@1143
-  int v640; // ecx@1146
-  int v641; // ecx@1147
   int v642; // edi@1156
   int v643; // eax@1156
   int v644; // eax@1156
   signed int v645; // eax@1158
-  //Player *v646; // ebx@1169
-  //int v647; // edi@1169
-  //signed int v648; // ST1C_4@1170
-  //Player *v649; // ecx@1170
-  //unsigned __int64 v650; // [sp-10h] [bp-E94h]@103
-  //unsigned __int16 v651; // [sp-8h] [bp-E8Ch]@100
-  //unsigned __int16 v652; // [sp-8h] [bp-E8Ch]@304
-  //unsigned __int16 v653; // [sp-4h] [bp-E88h]@100
-  //int v654; // [sp-4h] [bp-E88h]@124
-  //unsigned __int16 v655; // [sp-4h] [bp-E88h]@304
   unsigned int v656; // [sp-4h] [bp-E88h]@639
   int v657; // [sp-4h] [bp-E88h]@807
-  //int v658; // [sp+0h] [bp-E84h]@100
   int v659; // [sp+0h] [bp-E84h]@123
   int v660; // [sp+0h] [bp-E84h]@146
   Actor *v661; // [sp+0h] [bp-E84h]@164
-  //int v662; // [sp+0h] [bp-E84h]@304
   unsigned __int64 v663; // [sp+0h] [bp-E84h]@639
   const char *v664; // [sp+0h] [bp-E84h]@802
   int v665; // [sp+0h] [bp-E84h]@807
   int v666; // [sp+4h] [bp-E80h]@12
   PLAYER_SKILL_TYPE v667; // [sp+4h] [bp-E80h]@25
-  //unsigned __int8 v668; // [sp+4h] [bp-E80h]@100
-  //int v669; // [sp+4h] [bp-E80h]@123
-  //Vec3_int_ *v670; // [sp+4h] [bp-E80h]@133
   int v671; // [sp+4h] [bp-E80h]@146
-  unsigned int v672; // [sp+4h] [bp-E80h]@164
-  //unsigned __int8 v673; // [sp+4h] [bp-E80h]@304
-  //__int16 v674; // [sp+4h] [bp-E80h]@684
-  const char *v675; // [sp+4h] [bp-E80h]@800
+  int v675; // [sp+4h] [bp-E80h]@800
   int v676; // [sp+4h] [bp-E80h]@807
   int v677; // [sp+4h] [bp-E80h]@861
-  //int v678; // [sp+4h] [bp-E80h]@997
-  int v679; // [sp+14h] [bp-E70h]@515
+  int v679[800]; // [sp+14h] [bp-E70h]@515
   AIDirection a3; // [sp+C94h] [bp-1F0h]@21
   int v681[4]; // [sp+CB0h] [bp-1D4h]@1137
   int v682[4]; // [sp+CC0h] [bp-1C4h]@731
   ItemGen v683; // [sp+CD0h] [bp-1B4h]@791
   int v684; // [sp+D04h] [bp-180h]@416
   unsigned __int64 v685; // [sp+D08h] [bp-17Ch]@416
-  int x; // [sp+D20h] [bp-164h]@327
   unsigned __int64 v687; // [sp+D24h] [bp-160h]@327
   Vec3_int_ v688; // [sp+D2Ch] [bp-158h]@943
-  //int v689; // [sp+D30h] [bp-154h]@943
-  //int v690; // [sp+D34h] [bp-150h]@943
   Vec3_int_ v691; // [sp+D38h] [bp-14Ch]@137
-  //int v692; // [sp+D3Ch] [bp-148h]@137
-  //int v693; // [sp+D40h] [bp-144h]@137
   Vec3_int_ v694; // [sp+D44h] [bp-140h]@982
-  //int v695; // [sp+D48h] [bp-13Ch]@982
-  //int v696; // [sp+D4Ch] [bp-138h]@982
   Vec3_int_ v697; // [sp+D50h] [bp-134h]@129
-  //int v698; // [sp+D54h] [bp-130h]@129
-  //int v699; // [sp+D58h] [bp-12Ch]@129
   Vec3_int_ v700; // [sp+D5Ch] [bp-128h]@339
   Vec3_int_ v701; // [sp+D68h] [bp-11Ch]@286
-  //int v702; // [sp+D6Ch] [bp-118h]@286
-  //int v703; // [sp+D70h] [bp-114h]@286
   Vec3_int_ v704; // [sp+D74h] [bp-110h]@132
-  //int v705; // [sp+D78h] [bp-10Ch]@132
-  //int v706; // [sp+D7Ch] [bp-108h]@132
   Vec3_int_ v707; // [sp+D80h] [bp-104h]@1127
-  //int v708; // [sp+D84h] [bp-100h]@1127
-  //int v709; // [sp+D88h] [bp-FCh]@1127
   char v710; // [sp+D8Ch] [bp-F8h]@1156
-  //stru277 *v711; // [sp+D90h] [bp-F4h]@1
   __int64 v712; // [sp+D94h] [bp-F0h]@991
   int v713; // [sp+D9Ch] [bp-E8h]@324
   int n; // [sp+DA0h] [bp-E4h]@1
@@ -3131,12 +2658,10 @@
   signed int sRecoveryTime; // [sp+DD0h] [bp-B4h]@53
   char *y; // [sp+DD4h] [bp-B0h]@325
   int v721; // [sp+DD8h] [bp-ACh]@163
-  //SpriteObject a1; // [sp+DDCh] [bp-A8h]@1
   int v723; // [sp+E4Ch] [bp-38h]@1
   ItemGen *_this; // [sp+E50h] [bp-34h]@23
   float v725; // [sp+E54h] [bp-30h]@23
   Player *v726; // [sp+E58h] [bp-2Ch]@131
-  //int v726b;
   float v727; // [sp+E5Ch] [bp-28h]@1
   unsigned int uRequiredMana; // [sp+E60h] [bp-24h]@53
   Player *pPlayer; // [sp+E64h] [bp-20h]@8
@@ -3149,14 +2674,8 @@
   signed int a2; // [sp+E7Ch] [bp-8h]@14
   int amount; // [sp+E80h] [bp-4h]@1
 
-  //auto ecx0 = this;
-
-  //v711 = ecx0;
-
   SpriteObject pSpellSprite; // [sp+DDCh] [bp-A8h]@1
-  //SpriteObject::SpriteObject(&a1);
-
-  //v1 = 0;
+
   v2 = 0;
   amount = 0;
   LODWORD(v733) = 0;
@@ -3297,50 +2816,49 @@
 
     switch ( pCastSpell->spellnum )
     {
-      case SPELL_101:
-        assert(false && "Unknown spell effect #101 (prolly flaming bow arrow");
-      case SPELL_BOW_ARROW:
-      {
-        //v17 = pPlayer;
-        _this = (ItemGen *)1;
-        if ( (signed int)SkillToMastery(pPlayer->pActiveSkills[PLAYER_SKILL_BOW]) >= 3 )
-          _this = (ItemGen *)2;
-        sRecoveryTime = pPlayer->GetAttackRecoveryTime(true);
-        pSpellSprite.stru_24.Reset();
-        pSpellSprite.spell_level = v2;
-        pSpellSprite.spell_id = pCastSpell->spellnum;
-        pSpellSprite.spell_skill = v731;
-        pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-        if ( pPlayer->WearsItem(510, 2) )
-          pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(0xBD6u);
-        pSpellSprite.vPosition.x = pParty->vPosition.x;
-        pSpellSprite.vPosition.y = pParty->vPosition.y;
-        pSpellSprite.uAttributes = 0;
-        pSpellSprite.uSpriteFrameID = 0;
-        pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
-        pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-        pSpellSprite.spell_target_pid = a2;
-        pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
-        pSpellSprite.uFacing = LOWORD(v715.uYawAngle);
-        pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-        v20 = &pParty->pPlayers[pCastSpell->uPlayerID];
-        memcpy(&pSpellSprite.stru_24, &v20[v20->pEquipment.uBow], sizeof(pSpellSprite.stru_24));
-        pSpellSprite.uAttributes = 256;
-        if ( pParty->bTurnBasedModeOn == 1 )
-          pSpellSprite.uAttributes = 260;
-        for ( i = 0; i < (signed int)_this; ++i )
-        {
-          if ( i )
-            pSpellSprite.vPosition.z += 32;
-          pSpellSprite.uSectorID = pIndoor->GetSector(pSpellSprite.vPosition.x, pSpellSprite.vPosition.y, pSpellSprite.vPosition.z);
-          if ( pSpellSprite.Create(v715.uYawAngle, v715.uPitchAngle, pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed,
-               pCastSpell->uPlayerID + 1) != -1 && pParty->bTurnBasedModeOn == 1 )
-            ++pTurnEngine->field_1C;
-        }
-        break;
-      }
-      case SPELL_LASER_PROJECTILE:
-      {
+		case SPELL_101:
+			assert(false && "Unknown spell effect #101 (prolly flaming bow arrow");
+		case SPELL_BOW_ARROW:
+		{
+			amount = 1;
+			if ( SkillToMastery(pPlayer->pActiveSkills[PLAYER_SKILL_BOW]) >= 3 )
+				amount = 2;
+			sRecoveryTime = pPlayer->GetAttackRecoveryTime(true);
+			pSpellSprite.stru_24.Reset();
+			pSpellSprite.spell_level = v2;
+			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_skill = v731;
+			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+			if ( pPlayer->WearsItem(510, 2) )
+				pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(0xBD6u);
+			pSpellSprite.vPosition.x = pParty->vPosition.x;
+			pSpellSprite.vPosition.y = pParty->vPosition.y;
+			pSpellSprite.uAttributes = 0;
+			pSpellSprite.uSpriteFrameID = 0;
+			pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
+			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+			pSpellSprite.spell_target_pid = a2;
+			pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
+			pSpellSprite.uFacing = LOWORD(v715.uYawAngle);
+			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+			pPlayer = &pParty->pPlayers[pCastSpell->uPlayerID];
+			memcpy(&pSpellSprite.stru_24, &pPlayer[pPlayer->pEquipment.uBow], sizeof(pSpellSprite.stru_24));
+			pSpellSprite.uAttributes = 256;
+			if ( pParty->bTurnBasedModeOn == 1 )
+				pSpellSprite.uAttributes = 260;
+			for ( i = 0; i < amount; ++i )
+			{
+				if ( i )
+					pSpellSprite.vPosition.z += 32;
+				pSpellSprite.uSectorID = pIndoor->GetSector(pSpellSprite.vPosition.x, pSpellSprite.vPosition.y, pSpellSprite.vPosition.z);
+				if ( pSpellSprite.Create(v715.uYawAngle, v715.uPitchAngle, pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed,
+					pCastSpell->uPlayerID + 1) != -1 && pParty->bTurnBasedModeOn == 1 )
+				++pTurnEngine->field_1C;
+			}
+			break;
+		}
+		case SPELL_LASER_PROJECTILE:
+		{
 			sRecoveryTime = pPlayer->GetAttackRecoveryTime(0);
 			pSpellSprite.stru_24.Reset();
 			pSpellSprite.spell_id = pCastSpell->spellnum;
@@ -3357,9 +2875,10 @@
 			pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
 			pSpellSprite.uFacing = LOWORD(v715.uYawAngle);
 			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-			memcpy(&pSpellSprite.stru_24,
-				&pParty->pPlayers[pCastSpell->uPlayerID].spellbook.pDarkSpellbook.bIsSpellAvailable[36
-					* pParty->pPlayers[pCastSpell->uPlayerID].pEquipment.uMainHand + 5], sizeof(pSpellSprite.stru_24));
+			pPlayer = &pParty->pPlayers[pCastSpell->uPlayerID];
+			memcpy(&pSpellSprite.stru_24, &pPlayer->pInventoryItems[pPlayer->pEquipment.uMainHand-1],sizeof(pSpellSprite.stru_24));
+			//	&pParty->pPlayers[pCastSpell->uPlayerID].spellbook.pDarkSpellbook.bIsSpellAvailable[36
+			//		* pParty->pPlayers[pCastSpell->uPlayerID].pEquipment.uMainHand + 5], );
 			v23 = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pSpellSprite.vPosition.z);
 			HIBYTE(pSpellSprite.uAttributes) |= 1u;
 			pSpellSprite.uSectorID = v23;
@@ -3369,11 +2888,9 @@
 					pCastSpell->uPlayerID + 1) != -1 && pParty->bTurnBasedModeOn == 1 )
 				++pTurnEngine->field_1C;
 			break;
-      }
-      case SPELL_FIRE_TORCH_LIGHT:
-      {
-			LODWORD(v733) = 3600 * v2;
-
+		}
+		case SPELL_FIRE_TORCH_LIGHT:
+		{
 			switch (v731)
 			{
 				case 1: amount = 2; break;
@@ -3388,210 +2905,200 @@
 			pParty->pPartyBuffs[PARTY_BUFF_TORCHLIGHT].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)3600 * v2 * 4.2666669), v731, amount, 0, 0);
 			LODWORD(v727) = 1;
 			break;
-      }
-      case SPELL_FIRE_FIRE_SPIKE:
-      {
-		v29 = v731 - 2;
-		if ( v29 )
-		{
-			v30 = v29 - 1;
-			if ( v30 )
-			{
-			if ( v30 == 1 )
-				amount = 9;
-			else
-				amount = 3;
-			}
-			else
-			{
-			amount = 7;
-			}
 		}
-		else
-		{
-			amount = 5;
-		}
-		//v31 = v3->uPlayerID;
-		//v32 = 8 * v31;
-		//LOBYTE(v32) = v32 | OBJECT_Player;
-
-		//if ( (signed int)uNumSpriteObjects > 0 )
-		int _v733 = 0;
-		for (uint i = 0; i < uNumSpriteObjects; ++i)
+		case SPELL_FIRE_FIRE_SPIKE:
 		{
-			auto object = pSpriteObjects + i;
-			if (object->uType && object->spell_id == SPELL_FIRE_FIRE_SPIKE && object->spell_caster_pid == PID(OBJECT_Player, pCastSpell->uPlayerID))
-			++_v733;
-			/*v33 = (char *)&pSpriteObjects[0].field_48;
-			v730 = uNumSpriteObjects;
-			do
-			{
-			if ( *((short *)v33 - 36) && *(int *)v33 == 7 && *((int *)v33 + 4) == v32 )
-				++HIDWORD(v733);
-			v33 += 112;
-			--v730;
-			}
-			while ( v730 );*/
-		}
-		if (_v733 > amount)
-		{
-			ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
-			pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-			pCastSpell->spellnum = 0;
-			continue;
-		}
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			break;
-		pSpellSprite.stru_24.Reset();
-		pSpellSprite.spell_id = pCastSpell->spellnum;
-		pSpellSprite.spell_level = v2;
-		pSpellSprite.spell_skill = v731;
-		pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-		pSpellSprite.vPosition.y = pParty->vPosition.y;
-		pSpellSprite.vPosition.x = pParty->vPosition.x;
-		pSpellSprite.uAttributes = 0;
-		pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
-		pSpellSprite.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3);
-		pSpellSprite.uSpriteFrameID = 0;
-		pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-		pSpellSprite.spell_target_pid = a2;
-		pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
-		pSpellSprite.uFacing = LOWORD(v715.uYawAngle);
-		pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-		if ( pParty->bTurnBasedModeOn == 1 )
-			LOBYTE(pSpellSprite.uAttributes) |= 4u;
-		v659 = pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed;
-		if ( pSpellSprite.Create(pParty->sRotationY, pParty->sRotationX + 10, v659, pCastSpell->uPlayerID + 1) != -1 && pParty->bTurnBasedModeOn == 1 )
-			++pTurnEngine->field_1C;
-		LODWORD(v727) = 1;
-		break;
-      }
-      case SPELL_AIR_IMPLOSION:
-      {
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			break;
-		if (!a2)
-		{
-			ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
-			pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-			pCastSpell->spellnum = 0;
-			continue;
-		}
-		if (PID_TYPE(a2) != OBJECT_Actor)
-		{
+			switch (v731)
+			{
+				case 1: amount = 3; break;
+				case 2: amount = 5; break;
+				case 3: amount = 7; break;
+				case 4: amount = 9; break;
+				default:
+				assert(false);
+			}
+
+			//v31 = v3->uPlayerID;
+			//v32 = 8 * v31;
+			//LOBYTE(v32) = v32 | OBJECT_Player;
+
+			//if ( (signed int)uNumSpriteObjects > 0 )
+			int _v733 = 0;
+			for (uint i = 0; i < uNumSpriteObjects; ++i)
+			{
+				auto object = pSpriteObjects + i;
+				if (object->uType && object->spell_id == SPELL_FIRE_FIRE_SPIKE && object->spell_caster_pid == PID(OBJECT_Player, pCastSpell->uPlayerID))
+				++_v733;
+				/*v33 = (char *)&pSpriteObjects[0].field_48;
+				v730 = uNumSpriteObjects;
+				do
+				{
+				if ( *((short *)v33 - 36) && *(int *)v33 == 7 && *((int *)v33 + 4) == v32 )
+					++HIDWORD(v733);
+				v33 += 112;
+				--v730;
+				}
+				while ( v730 );*/
+			}
+			if (_v733 > amount)
+			{
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				pCastSpell->spellnum = 0;
+				continue;
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			pSpellSprite.stru_24.Reset();
+			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_level = v2;
+			pSpellSprite.spell_skill = v731;
+			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+			pSpellSprite.vPosition.y = pParty->vPosition.y;
+			pSpellSprite.vPosition.x = pParty->vPosition.x;
+			pSpellSprite.uAttributes = 0;
+			pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
+			pSpellSprite.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3);
+			pSpellSprite.uSpriteFrameID = 0;
+			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+			pSpellSprite.spell_target_pid = a2;
+			pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
+			pSpellSprite.uFacing = LOWORD(v715.uYawAngle);
+			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+			if ( pParty->bTurnBasedModeOn == 1 )
+				LOBYTE(pSpellSprite.uAttributes) |= 4u;
+			v659 = pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed;
+			if ( pSpellSprite.Create(pParty->sRotationY, pParty->sRotationX + 10, v659, pCastSpell->uPlayerID + 1) != -1 && pParty->bTurnBasedModeOn == 1 )
+				++pTurnEngine->field_1C;
 			LODWORD(v727) = 1;
 			break;
 		}
-		v697.x = 0;
-		v697.y = 0;
-		v697.z = 0;
-		pSpellSprite.stru_24.Reset();
-		pSpellSprite.spell_id = pCastSpell->spellnum;
-		pSpellSprite.spell_level = v2;
-		pSpellSprite.spell_skill = v731;
-		pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-		pSpellSprite.uAttributes = 0;
-		pSpellSprite.uSectorID = 0;
-		pSpellSprite.uSpriteFrameID = 0;
-		pSpellSprite.field_60_distance_related_prolly_lod = 0;
-		pSpellSprite.uFacing = 0;
-		pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-		pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-		pSpellSprite.vPosition.x = pActors[PID_ID(a2)].vPosition.x;
-		pSpellSprite.vPosition.z = pActors[PID_ID(a2)].vPosition.z;
-		pSpellSprite.vPosition.y = pActors[PID_ID(a2)].vPosition.y;
-		pSpellSprite.spell_target_pid = PID(OBJECT_Actor, PID_ID(a2));
-		auto obj_id = pSpellSprite.Create(0, 0, 0, 0);
-		DamageMonsterFromParty(PID(OBJECT_Item, obj_id), PID_ID(a2), &v697);
-		LODWORD(v727) = 1;
-		break;
-      }
-      case SPELL_EARTH_MASS_DISTORTION:
-      {
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			break;
-		if ( !stru_50C198.GetMagicalResistance(&pActors[PID_ID(a2)], 3u) )
+		case SPELL_AIR_IMPLOSION:
 		{
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			if (!a2)
+			{
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				pCastSpell->spellnum = 0;
+				continue;
+			}
+			if (PID_TYPE(a2) != OBJECT_Actor)
+			{
+				LODWORD(v727) = 1;
+				break;
+			}
+			v697.x = 0;
+			v697.y = 0;
+			v697.z = 0;
+			pSpellSprite.stru_24.Reset();
+			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_level = v2;
+			pSpellSprite.spell_skill = v731;
+			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+			pSpellSprite.uAttributes = 0;
+			pSpellSprite.uSectorID = 0;
+			pSpellSprite.uSpriteFrameID = 0;
+			pSpellSprite.field_60_distance_related_prolly_lod = 0;
+			pSpellSprite.uFacing = 0;
+			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+			pSpellSprite.vPosition.x = pActors[PID_ID(a2)].vPosition.x;
+			pSpellSprite.vPosition.z = pActors[PID_ID(a2)].vPosition.z;
+			pSpellSprite.vPosition.y = pActors[PID_ID(a2)].vPosition.y;
+			pSpellSprite.spell_target_pid = PID(OBJECT_Actor, PID_ID(a2));
+			auto obj_id = pSpellSprite.Create(0, 0, 0, 0);
+			DamageMonsterFromParty(PID(OBJECT_Item, obj_id), PID_ID(a2), &v697);
 			LODWORD(v727) = 1;
 			break;
 		}
-		pActors[PID_ID(a2)].pActorBuffs[10].Apply(pMiscTimer->uTotalGameTimeElapsed + 128, 0, 0, 0, 0);
-		v704.x = 0;
-		v704.y = 0;
-		v704.z = 0;
-		pSpellSprite.stru_24.Reset();
-		pSpellSprite.spell_id = pCastSpell->spellnum;
-		pSpellSprite.spell_level = v2;
-		pSpellSprite.spell_skill = v731;
-		pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-		pSpellSprite.uAttributes = 0;
-		pSpellSprite.uSectorID = 0;
-		pSpellSprite.uSpriteFrameID = 0;
-		pSpellSprite.field_60_distance_related_prolly_lod = 0;
-		pSpellSprite.uFacing = 0;
-		pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-		pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-		pSpellSprite.vPosition.x = pActors[PID_ID(a2)].vPosition.x;
-		pSpellSprite.vPosition.y = pActors[PID_ID(a2)].vPosition.y;
-		pSpellSprite.vPosition.z = pActors[PID_ID(a2)].vPosition.z;
-		pSpellSprite.spell_target_pid = PID(OBJECT_Actor, (int)v726);
-		auto obj_id = pSpellSprite.Create(0, 0, 0, 0);
-		DamageMonsterFromParty(PID(OBJECT_Item, obj_id), PID_ID(a2), &v704);
-		LODWORD(v727) = 1;
-		break;
-      }
-      case SPELL_LIGHT_DESTROY_UNDEAD:
-      {
-		if ( !pPlayer->CanCastSpell(uRequiredMana) || !a2 || PID_TYPE(a2) != OBJECT_Actor)
+		case SPELL_EARTH_MASS_DISTORTION:
+		{
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			if ( !stru_50C198.GetMagicalResistance(&pActors[PID_ID(a2)], 3u) )
+			{
+				LODWORD(v727) = 1;
+				break;
+			}
+			pActors[PID_ID(a2)].pActorBuffs[10].Apply(pMiscTimer->uTotalGameTimeElapsed + 128, 0, 0, 0, 0);
+			v704.x = 0;
+			v704.y = 0;
+			v704.z = 0;
+			pSpellSprite.stru_24.Reset();
+			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_level = v2;
+			pSpellSprite.spell_skill = v731;
+			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+			pSpellSprite.uAttributes = 0;
+			pSpellSprite.uSectorID = 0;
+			pSpellSprite.uSpriteFrameID = 0;
+			pSpellSprite.field_60_distance_related_prolly_lod = 0;
+			pSpellSprite.uFacing = 0;
+			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+			pSpellSprite.vPosition.x = pActors[PID_ID(a2)].vPosition.x;
+			pSpellSprite.vPosition.y = pActors[PID_ID(a2)].vPosition.y;
+			pSpellSprite.vPosition.z = pActors[PID_ID(a2)].vPosition.z;
+			pSpellSprite.spell_target_pid = PID(OBJECT_Actor, (int)v726);
+			auto obj_id = pSpellSprite.Create(0, 0, 0, 0);
+			DamageMonsterFromParty(PID(OBJECT_Item, obj_id), PID_ID(a2), &v704);
+			LODWORD(v727) = 1;
 			break;
-		//v730 = a2 >> 3;
-		//HIDWORD(v733) = (int)&pActors[PID_ID(a2)];
-		v691.x = 0;
-		v691.y = 0;
-		v691.z = 0;
-		pSpellSprite.stru_24.Reset();
-		pSpellSprite.spell_id = pCastSpell->spellnum;
-		pSpellSprite.spell_level = v2;
-		pSpellSprite.spell_skill = v731;
-		pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-		pSpellSprite.vPosition.x = pActors[PID_ID(a2)].vPosition.x;
-		pSpellSprite.vPosition.y = pActors[PID_ID(a2)].vPosition.y;
-		pSpellSprite.vPosition.z = pActors[PID_ID(a2)].vPosition.z;
-		pSpellSprite.uAttributes = 0;
-		pSpellSprite.uSectorID = pIndoor->GetSector(pSpellSprite.vPosition.x, pSpellSprite.vPosition.y, pSpellSprite.vPosition.z);
-		pSpellSprite.uSpriteFrameID = 0;
-		pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-		pSpellSprite.spell_target_pid = a2;
-		pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
-		pSpellSprite.uFacing = LOWORD(v715.uYawAngle);
-		pSpellSprite.uAttributes |= 0x80u;
-		pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-		auto obj_id = pSpellSprite.Create(0, 0, 0, 0);
-		if ( !MonsterStats::BelongsToSupertype(*(short *)(HIDWORD(v733) + 96), MONSTER_SUPERTYPE_UNDEAD) )
+		}
+		case SPELL_LIGHT_DESTROY_UNDEAD:
 		{
-			ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
-			pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-			pCastSpell->spellnum = 0;
-			continue;
+			if ( !pPlayer->CanCastSpell(uRequiredMana) || !a2 || PID_TYPE(a2) != OBJECT_Actor)
+				break;
+			//v730 = a2 >> 3;
+			//HIDWORD(v733) = (int)&pActors[PID_ID(a2)];
+			v691.x = 0;
+			v691.y = 0;
+			v691.z = 0;
+			pSpellSprite.stru_24.Reset();
+			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_level = v2;
+			pSpellSprite.spell_skill = v731;
+			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+			pSpellSprite.vPosition.x = pActors[PID_ID(a2)].vPosition.x;
+			pSpellSprite.vPosition.y = pActors[PID_ID(a2)].vPosition.y;
+			pSpellSprite.vPosition.z = pActors[PID_ID(a2)].vPosition.z;
+			pSpellSprite.uAttributes = 0;
+			pSpellSprite.uSectorID = pIndoor->GetSector(pSpellSprite.vPosition.x, pSpellSprite.vPosition.y, pSpellSprite.vPosition.z);
+			pSpellSprite.uSpriteFrameID = 0;
+			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+			pSpellSprite.spell_target_pid = a2;
+			pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
+			pSpellSprite.uFacing = LOWORD(v715.uYawAngle);
+			pSpellSprite.uAttributes |= 0x80u;
+			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+			auto obj_id = pSpellSprite.Create(0, 0, 0, 0);
+			if ( !MonsterStats::BelongsToSupertype(pActor->pMonsterInfo.uID, MONSTER_SUPERTYPE_UNDEAD) )
+			{
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				pCastSpell->spellnum = 0;
+				continue;
+			}
+			DamageMonsterFromParty(PID(OBJECT_Item, obj_id), PID_ID(a2), &v691);
+			LODWORD(v727) = 1;
+			break;
 		}
-		DamageMonsterFromParty(PID(OBJECT_Item, obj_id), PID_ID(a2), &v691);
-		LODWORD(v727) = 1;
-		break;
-      }
-      case SPELL_FIRE_FIRE_BOLT:
-      case SPELL_FIRE_FIREBALL:
-      case SPELL_FIRE_INCINERATE:
-      case SPELL_AIR_LIGHNING_BOLT:
-      case SPELL_WATER_ICE_BOLT:
-      case SPELL_WATER_ICE_BLAST:
-      case SPELL_EARTH_STUN:
-      case SPELL_EARTH_DEADLY_SWARM:
-      case SPELL_MIND_MIND_BLAST:
-      case SPELL_MIND_PSYCHIC_SHOCK:
-      case SPELL_BODY_HARM:
-      case SPELL_LIGHT_LIGHT_BOLT:
-      case SPELL_DARK_DRAGON_BREATH:
-      {
+		case SPELL_FIRE_FIRE_BOLT:
+		case SPELL_FIRE_FIREBALL:
+		case SPELL_FIRE_INCINERATE:
+		case SPELL_AIR_LIGHNING_BOLT:
+		case SPELL_WATER_ICE_BOLT:
+		case SPELL_WATER_ICE_BLAST:
+		case SPELL_EARTH_STUN:
+		case SPELL_EARTH_DEADLY_SWARM:
+		case SPELL_MIND_MIND_BLAST:
+		case SPELL_MIND_PSYCHIC_SHOCK:
+		case SPELL_BODY_HARM:
+		case SPELL_LIGHT_LIGHT_BOLT:
+		case SPELL_DARK_DRAGON_BREATH:
+		{
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
 			pSpellSprite.stru_24.Reset();
@@ -3622,12 +3129,12 @@
 				++pTurnEngine->field_1C;
 			LODWORD(v727) = 1;
 			break;
-      }
-      case SPELL_WATER_ACID_BURST:
-      case SPELL_EARTH_BLADES:
-      case SPELL_BODY_FLYING_FIST:
-      case SPELL_DARK_TOXIC_CLOUD:
-      {
+		}
+		case SPELL_WATER_ACID_BURST:
+		case SPELL_EARTH_BLADES:
+		case SPELL_BODY_FLYING_FIST:
+		case SPELL_DARK_TOXIC_CLOUD:
+		{
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
 			pSpellSprite.stru_24.Reset();
@@ -3657,11 +3164,11 @@
 				++pTurnEngine->field_1C;
 			LODWORD(v727) = 1;
 			break;
-      }
-      case SPELL_LIGHT_SUNRAY:
-      {
+		}
+		case SPELL_LIGHT_SUNRAY:
+		{
 			if ( uCurrentlyLoadedLevelType == LEVEL_Indoor
-				|| uCurrentlyLoadedLevelType == LEVEL_Outdoor && (pParty->uCurrentHour < 5 || pParty->uCurrentHour >= 0x15) )
+				|| uCurrentlyLoadedLevelType == LEVEL_Outdoor && (pParty->uCurrentHour < 5 || pParty->uCurrentHour >= 21) )
 			{
 				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
 				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
@@ -3698,54 +3205,41 @@
 				LODWORD(v727) = 1;
 			}
 			break;
-      }
-      case SPELL_LIGHT_PARALYZE:
-      {
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			break;
-		if (PID_TYPE(a2) != OBJECT_Actor || (v730 = PID_ID(a2), v721 = (int)&pActors[PID_ID(a2)],
-				!stru_50C198.GetMagicalResistance(&pActors[PID_ID(a2)], 9)) )
-		{
-		LODWORD(v727) = 1;
-		break;
 		}
-		Actor::AI_Stand(PID_ID(a2), 4u, 0x80u, 0);
-		v54 = (signed __int64)((double)(23040 * v2) * 0.033333335);
-		v55 = v721;
-		((SpellBuff *)(v721 + 308))->Apply(pParty->uTimePlayed + (signed int)v54, v731, 0, 0, 0);
-		*(char *)(v55 + 38) |= 8u;
-		*(short *)(v55 + 148) = 0;
-		v672 = 0;
-		*(short *)(v55 + 150) = 0;
-		v661 = (Actor *)v55;
-		pGame->GetStru6()->_4A7E89_sparkles_on_actor_after_it_casts_buff(v661, v672);
-		LODWORD(v727) = 1;
-		break;
-      }
-      case SPELL_EARTH_SLOW:
-      {
-			if ( v731 == 2 )
-			{
-				v57 = 300 * v2;
-				amount = 2;
-			}
-			else if ( v731 == 3 )
-			{
-				amount = 4;
-				v57 = 300 * v2;
-			}
-			else if ( v731 == 4 )
-			{
-				v57 = 300 * v2;
-				amount = 8;
-			}
-			else
-			{
-				v57 = 180 * v2;
-				amount = 2;
-			}
-//	LABEL_174:
-			LODWORD(v733) = v57;
+		case SPELL_LIGHT_PARALYZE:
+		{
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			if (PID_TYPE(a2) != OBJECT_Actor || (v730 = PID_ID(a2), v721 = (int)&pActors[PID_ID(a2)],
+					!stru_50C198.GetMagicalResistance(&pActors[PID_ID(a2)], 9)) )
+			{
+				LODWORD(v727) = 1;
+				break;
+			}
+			Actor::AI_Stand(PID_ID(a2), 4u, 0x80u, 0);
+			v54 = (signed __int64)((double)(23040 * v2) * 0.033333335);
+			v55 = &pActors[PID_ID(a2)];
+			v55->pActorBuffs[6].Apply(pParty->uTimePlayed + (signed int)v54, v731, 0, 0, 0);
+			BYTE2(v55->uAttributes) |= 8u;
+			v55->vVelocity.x = 0;
+			//v672 = 0;
+			v55->vVelocity.y = 0;
+			v661 = v55;
+			pGame->GetStru6()->_4A7E89_sparkles_on_actor_after_it_casts_buff(v661, 0);
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_EARTH_SLOW:
+		{
+			switch (v731)
+			{
+				case 1: LODWORD(v733) = 180 * v2; amount = 2; break;
+				case 2: LODWORD(v733) = 300 * v2; amount = 2; break;
+				case 3: LODWORD(v733) = 300 * v2; amount = 4; break;
+				case 4: LODWORD(v733) = 300 * v2; amount = 8; break;
+				default:
+				assert(false);
+			}
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
 			if (PID_TYPE(a2) != OBJECT_Actor
@@ -3757,22 +3251,20 @@
 				break;
 			}
 			v58 = (signed __int64)((double)(23040 * v2) * 0.033333335);
-			v59 = v721;
+			//v59 = v721;
+			pActor = &pActors[PID_ID(a2)];
 			//((SpellBuff *)((char *)&pActors[0].pActorBuffs[7] + v721))->Apply(
-			pActors[PID_ID(a2)].pActorBuffs[7].Apply(pParty->uTimePlayed + (signed int)v58,
-				v731,
-				amount,
-				0,
-				0);
-			*((char *)&pActors[0].uAttributes + v59 + 2) |= 8u;
-			v672 = 0;
+			pActor->pActorBuffs[7].Apply(pParty->uTimePlayed + (signed int)v58,	v731, amount, 0, 0);
+			//*((char *)&pActors[0].uAttributes + v59 + 2) |= 8u;
+			BYTE2(pActor->uAttributes) |= 8u;
+			//v672 = 0;
 			v661 = (Actor *)LODWORD(v718);
-			pGame->GetStru6()->_4A7E89_sparkles_on_actor_after_it_casts_buff(v661, v672);
+			pGame->GetStru6()->_4A7E89_sparkles_on_actor_after_it_casts_buff(v661, 0);
 			LODWORD(v727) = 1;
 			break;
       }
-      case SPELL_MIND_CHARM:
-      {
+		case SPELL_MIND_CHARM:
+		{
 		if ( !pPlayer->CanCastSpell(uRequiredMana) )
 			break;
 
@@ -3826,9 +3318,9 @@
 			pSpellSprite.Create(0, 0, 0, pCastSpell->uPlayerID + 1);
 			LODWORD(v727) = 1;
 			break;
-      }
-      case SPELL_DARK_SHRINKING_RAY:
-      {
+		}
+		case SPELL_DARK_SHRINKING_RAY:
+		{
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
 			pSpellSprite.stru_24.Reset();
@@ -3859,40 +3351,19 @@
 				++pTurnEngine->field_1C;
 			LODWORD(v727) = 1;
 			break;
-      }
-      case SPELL_FIRE_FIRE_AURA:
-      {
-			v63 = v731 - 1;
-			if ( !v63 )
-			{
-				amount = 10;
-				LODWORD(v733) = 3600 * v2;
-			}
-			else
-			{
-			v64 = v63 - 1;
-			if ( !v64 )
-			{
-				amount = 11;
-				LODWORD(v733) = 3600 * v2;
-			}
-			else
-			{
-			v65 = v64 - 1;
-			if ( !v65 )
-			{
-				amount = 12;
-//	LABEL_195:
-				LODWORD(v733) = 3600 * v2;
-			}
-			else if ( v65 == 1 )
-			{
-				LODWORD(v733) = 0;
-				amount = 12;
-			}
-			}
-			}
-//	LABEL_196:
+		}
+		case SPELL_FIRE_FIRE_AURA:
+		{
+			switch (v731)
+			{
+				case 1: LODWORD(v733) = 3600 * v2; amount = 10; break;
+				case 2: LODWORD(v733) = 3600 * v2; amount = 11; break;
+				case 3: LODWORD(v733) = 3600 * v2; amount = 12; break;
+				case 4: LODWORD(v733) = 0; amount = 12; break;
+				default:
+				assert(false);
+			}
+			
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
 			v730c = &pParty->pPlayers[pCastSpell->uPlayerID_2].pInventoryItems[a2];
@@ -3929,99 +3400,89 @@
 			pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
 			pCastSpell->spellnum = 0;
 			continue;
-      }
-      case SPELL_BODY_REGENERATION:
-      {
-		v70 = v731 - 1;
-		LODWORD(v733) = 3600 * v2;
-		if ( v70 && (v71 = v70 - 1) != 0 )
-		{
-			v72 = v71 - 1;
-			if ( v72 )
-			{
-			if ( v72 == 1 )
-				amount = 10;
-			}
-			else
-			{
-			amount = 3;
-			}
 		}
-		else
+		case SPELL_BODY_REGENERATION:
 		{
-			amount = 1;
-		}
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
+			switch (v731)
+			{
+				case 1: LODWORD(v733) = 3600 * v2; amount = 1; break;
+				case 2: LODWORD(v733) = 3600 * v2; amount = 1; break;
+				case 3: LODWORD(v733) = 3600 * v2; amount = 3; break;
+				case 4: LODWORD(v733) = 3600 * v2; amount = 10; break;
+				default:
+				assert(false);
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+
+			pParty->pPlayers[pCastSpell->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_REGENERATION].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)v733 * 4.2666669), v731, amount, 0, 0);
+			LODWORD(v727) = 1;
 			break;
-
-		pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
-
-		pParty->pPlayers[pCastSpell->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_REGENERATION].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)v733 * 4.2666669), v731, amount, 0, 0);
-		LODWORD(v727) = 1;
-		break;
-      }
-      case SPELL_FIRE_PROTECTION_FROM_FIRE:
-      case SPELL_AIR_PROTECTION_FROM_AIR:
-      case SPELL_WATER_PROTECTION_FROM_WATER:
-      case SPELL_EARTH_PROTECTION_FROM_EARTH:
-      case SPELL_MIND_PROTECTION_FROM_MIND:
-      case SPELL_BODY_PROTECTION_FROM_BODY:
-      {
-        LODWORD(v733) = 3600 * v2;
-		if ( v731 > 0 && v731 <= 4)
+		}
+		case SPELL_FIRE_PROTECTION_FROM_FIRE:
+		case SPELL_AIR_PROTECTION_FROM_AIR:
+		case SPELL_WATER_PROTECTION_FROM_WATER:
+		case SPELL_EARTH_PROTECTION_FROM_EARTH:
+		case SPELL_MIND_PROTECTION_FROM_MIND:
+		case SPELL_BODY_PROTECTION_FROM_BODY:
 		{
-	        amount = v731 * v2;
-        }		
-//LABEL_232:
-        //v80 = v3->spellnum;
-        switch (pCastSpell->spellnum)
-        {
-          case SPELL_FIRE_PROTECTION_FROM_FIRE:
-            LODWORD(v725) = PARTY_BUFF_RESIST_FIRE;
-            break;
-          case SPELL_AIR_PROTECTION_FROM_AIR:
-            LODWORD(v725) = PARTY_BUFF_RESIST_AIR;
-            break;
-          case SPELL_WATER_PROTECTION_FROM_WATER:
-            LODWORD(v725) = PARTY_BUFF_RESIST_WATER;
-            break;
-          case SPELL_EARTH_PROTECTION_FROM_EARTH:
-            LODWORD(v725) = PARTY_BUFF_RESIST_EARTH;
-            break;
-          case SPELL_MIND_PROTECTION_FROM_MIND:
-            LODWORD(v725) = PARTY_BUFF_RESIST_MIND;
-            break;
-          case SPELL_BODY_PROTECTION_FROM_BODY:
-            LODWORD(v725) = PARTY_BUFF_RESIST_BODY;
-            break;
-          default:
-            assert(false);
-            continue;
-        }
-        if ( !pPlayer->CanCastSpell(uRequiredMana) )
-          break;
-        pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
-        pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
-        pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
-        pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
-        v90 = (double)(signed int)v733 * 4.2666669;
-        pParty->pPartyBuffs[LODWORD(v725)].Apply(pParty->uTimePlayed + (signed int)(signed __int64)v90, v731, amount, 0, 0);
-        LODWORD(v727) = 1;
-        break;
-      }
-      case SPELL_FIRE_HASTE:
-      {
-			if ( v731 == 1 || v731 == 2 )
-			{
-				LODWORD(v733) = 60 * (v2 + 60);
-			}
-			else if ( v731 == 3 )
-			{
-				LODWORD(v733) = 180 * (v2 + 20);
-			}
-			else if ( v731 == 4 )
-			{
-				LODWORD(v733) = 240 * (v2 + 15);
+			switch (v731)
+			{
+				case 1: 
+				case 2: 
+				case 3: 
+				case 4: LODWORD(v733) = 3600 * v2; amount = v731 * v2; break;
+				default:
+				assert(false);
+			}
+
+			switch (pCastSpell->spellnum)
+			{
+			  case SPELL_FIRE_PROTECTION_FROM_FIRE:
+				LODWORD(v725) = PARTY_BUFF_RESIST_FIRE;
+				break;
+			  case SPELL_AIR_PROTECTION_FROM_AIR:
+				LODWORD(v725) = PARTY_BUFF_RESIST_AIR;
+				break;
+			  case SPELL_WATER_PROTECTION_FROM_WATER:
+				LODWORD(v725) = PARTY_BUFF_RESIST_WATER;
+				break;
+			  case SPELL_EARTH_PROTECTION_FROM_EARTH:
+				LODWORD(v725) = PARTY_BUFF_RESIST_EARTH;
+				break;
+			  case SPELL_MIND_PROTECTION_FROM_MIND:
+				LODWORD(v725) = PARTY_BUFF_RESIST_MIND;
+				break;
+			  case SPELL_BODY_PROTECTION_FROM_BODY:
+				LODWORD(v725) = PARTY_BUFF_RESIST_BODY;
+				break;
+			  default:
+				assert(false);
+				continue;
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+			  break;
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
+			v90 = (double)(signed int)v733 * 4.2666669;
+			pParty->pPartyBuffs[LODWORD(v725)].Apply(pParty->uTimePlayed + (signed int)(signed __int64)v90, v731, amount, 0, 0);
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_FIRE_HASTE:
+		{
+			switch (v731)
+			{
+				case 1: LODWORD(v733) = 60 * (v2 + 60); break;
+				case 2: LODWORD(v733) = 60 * (v2 + 60); break;
+				case 3: LODWORD(v733) = 180 * (v2 + 20); break;
+				case 4: LODWORD(v733) = 240 * (v2 + 15); break;
+				default:
+				assert(false);
 			}
 			if ( pPlayer->CanCastSpell(uRequiredMana) )
 			{
@@ -4045,22 +3506,18 @@
 				}
 			}
 			break;
-      }
-      case SPELL_SPIRIT_BLESS:
-      {
-			if ( v731 == 1 || v731 == 2 )
-			{
-				LODWORD(v733) = 300 * (v2 + 12);
-			}
-			else if ( v731 == 3 )
-			{
-				LODWORD(v733) = 900 * (v2 + 4);
-			}
-			else if ( v731 == 4 )
-			{
-				LODWORD(v733) = 3600 * (v2 + 1);
-			}
-//	LABEL_269:
+		}
+		case SPELL_SPIRIT_BLESS:
+		{
+			switch (v731)
+			{
+				case 1: LODWORD(v733) = 300 * (v2 + 12); break;
+				case 2: LODWORD(v733) = 300 * (v2 + 12); break;
+				case 3: LODWORD(v733) = 900 * (v2 + 4); break;
+				case 4: LODWORD(v733) = 3600 * (v2 + 1); break;
+				default:
+				assert(false);
+			}
 			amount = v2 + 5;
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
@@ -4078,13 +3535,13 @@
 				//v651 = 1;
 				//v28 = pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
 				//v27 = (char *)&pParty->pPlayers[v3->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_BLESS];
-	//LABEL_103:
-			//HIDWORD(v650) = HIDWORD(v28);
-	//LABEL_104:
-			//LODWORD(v650) = v28;
-			pParty->pPlayers[pCastSpell->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_BLESS].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), 1, amount, v111, 0);
-			LODWORD(v727) = 1;
-			break;
+		//LABEL_103:
+				//HIDWORD(v650) = HIDWORD(v28);
+		//LABEL_104:
+				//LODWORD(v650) = v28;
+				pParty->pPlayers[pCastSpell->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_BLESS].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), 1, amount, v111, 0);
+				LODWORD(v727) = 1;
+				break;
 			}
 			v105 = 0;
 			v717 = (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
@@ -4100,9 +3557,9 @@
 			while ( v730b <= &pParty->pPlayers[3] );
 			LODWORD(v727) = 1;
 			break;
-			}
+		}
 		case SPELL_SPIRIT_SPIRIT_LASH:
-			{
+		{
 			if ( pPlayer->CanCastSpell(uRequiredMana) && a2 && PID_TYPE(a2) == OBJECT_Actor)
 			{
 				//v730 = a2 >> 3;
@@ -4115,56 +3572,55 @@
 				v115 = (unsigned int)abs(v112->vPosition.z - pParty->vPosition.z);
 				if ( v113 < v721 )
 				{
-				v116 = v113;
-				v113 = v721;
-				v114 = v116;
+					v116 = v113;
+					v113 = v721;
+					v114 = v116;
 				}
 				if ( v113 < (signed int)v115 )
 				{
-				v117 = v113;
-				v113 = (int)v115;
-				v115 = v117;
+					v117 = v113;
+					v113 = (int)v115;
+					v115 = v117;
 				}
 				if ( v114 < (signed int)v115 )
 				{
-				v118 = v115;
-				v115 = v114;
-				v114 = v118;
+					v118 = v115;
+					v115 = v114;
+					v114 = v118;
 				}
 				_this = (ItemGen *)(((unsigned int)(11 * v114) >> 5) + (v115 >> 2) + v113);
 				if ( (double)(signed int)this <= 307.2 )
 				{
-				v701.x = 0;
-				v701.y = 0;
-				v701.z = 0;
-				pSpellSprite.stru_24.Reset();
-				v119 = HIDWORD(v733);
-				pSpellSprite.spell_id = *(int *)HIDWORD(v733);
-				pSpellSprite.spell_level = v723;
-				pSpellSprite.spell_skill = v731;
-				pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-				pSpellSprite.uAttributes = 0;
-				pSpellSprite.uSectorID = 0;
-				pSpellSprite.uSpriteFrameID = 0;
-				pSpellSprite.field_60_distance_related_prolly_lod = 0;
-				pSpellSprite.spell_caster_pid = PID(OBJECT_Player, *(short *)(v119 + 2));
-				pSpellSprite.uFacing = 0;
-				pSpellSprite.uSoundID = *(short *)(v119 + 16);
-				pSpellSprite.vPosition.x = v112->vPosition.x;
-				pSpellSprite.vPosition.y = v112->vPosition.y;
-				pSpellSprite.vPosition.z = v112->vPosition.z - (unsigned int)(signed __int64)((double)(signed int)v112->uActorHeight * unk_4D8548);
-				pSpellSprite.spell_target_pid = PID(OBJECT_Actor, a2);
-				v122 = pSpellSprite.Create(0, 0, 0, 0);
-				DamageMonsterFromParty(PID(OBJECT_Item, v122), PID_ID(a2), &v701);
-				LODWORD(v727) = 1;
+					v701.x = 0;
+					v701.y = 0;
+					v701.z = 0;
+					pSpellSprite.stru_24.Reset();
+					pSpellSprite.spell_id = pCastSpell->spellnum;
+					pSpellSprite.spell_level = v723;
+					pSpellSprite.spell_skill = v731;
+					pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+					pSpellSprite.uAttributes = 0;
+					pSpellSprite.uSectorID = 0;
+					pSpellSprite.uSpriteFrameID = 0;
+					pSpellSprite.field_60_distance_related_prolly_lod = 0;
+					pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+					pSpellSprite.uFacing = 0;
+					pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+					pSpellSprite.vPosition.x = v112->vPosition.x;
+					pSpellSprite.vPosition.y = v112->vPosition.y;
+					pSpellSprite.vPosition.z = v112->vPosition.z - (unsigned int)(signed __int64)((double)(signed int)v112->uActorHeight * unk_4D8548);
+					pSpellSprite.spell_target_pid = PID(OBJECT_Actor, a2);
+					v122 = pSpellSprite.Create(0, 0, 0, 0);
+					DamageMonsterFromParty(PID(OBJECT_Item, v122), PID_ID(a2), &v701);
+					LODWORD(v727) = 1;
 				}
 				else
 				{
-				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2u);
-				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				*(int *)HIDWORD(v733) = 0;
+					ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2u);
+					pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+					pCastSpell->spellnum = 0;
 				}
-				pCastSpell = (CastSpellInfo *)HIDWORD(v733);
+				//pCastSpell = (CastSpellInfo *)HIDWORD(v733);
 			}
 			break;
 		}
@@ -4172,20 +3628,15 @@
 		case SPELL_EARTH_STONESKIN:
 		case SPELL_SPIRIT_HEROISM:
 		{
-			if( v731 == 1 || v731 == 2 )
-			{
-				LODWORD(v733) = 300 * (v2 + 12);
-			}
-			else if ( v731 == 3 )
-			{
-				LODWORD(v733) = 900 * (v2 + 4);
-			}
-			else if ( v731 == 4 )
-			{
-				LODWORD(v733) = 3600 * (v2 + 1);
-			}
-
-//	LABEL_296:
+			switch (v731)
+			{
+				case 1: LODWORD(v733) = 300 * (v2 + 12); break;
+				case 2: LODWORD(v733) = 300 * (v2 + 12); break;
+				case 3: LODWORD(v733) = 900 * (v2 + 4); break;
+				case 4: LODWORD(v733) = 3600 * (v2 + 1); break;
+				default:
+				assert(false);
+			}
 			v127 = pCastSpell->spellnum;
 			if ( v127 == 17 )
 			{
@@ -4196,15 +3647,15 @@
 			{
 				if ( v127 == 38 )
 				{
-				LODWORD(v725) = 15;
-				amount = v2 + 5;
+					LODWORD(v725) = 15;
+					amount = v2 + 5;
 				}
 				else
 				{
-				if ( v127 != 51 )
-					continue;
-				LODWORD(v725) = 9;
-				amount = v2 + 5;
+					if ( v127 != 51 )
+						continue;
+					LODWORD(v725) = 9;
+					amount = v2 + 5;
 				}
 			}
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
@@ -4218,10 +3669,10 @@
 			pParty->pPartyBuffs[LODWORD(v725)].Apply(pParty->uTimePlayed + (signed int)(signed __int64)v90, v731, amount, 0, 0);
 			LODWORD(v727) = 1;
 			break;
-			}
+		}
 		case SPELL_FIRE_IMMOLATION:
-			{
-			if ( v731 == 4  && v139 == 1 )
+		{
+			if ( v731 == 4 )
 				LODWORD(v733) = 600 * v2;
 			else
 				LODWORD(v733) = 60 * v2;
@@ -4236,18 +3687,19 @@
 			pParty->pPartyBuffs[PARTY_BUFF_IMMOLATION].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, v2, 0, 0);
 			LODWORD(v727) = 1;
 			break;
-			}
+		}
 		case SPELL_FIRE_METEOR_SHOWER:
-			{
-			v149 = v731 - 1;
-			if ( v149 && (v150 = v149 - 1) != 0 && (v151 = v150 - 1) != 0 )
-			{
-				if ( v151 == 1 )
-				_this = (ItemGen *)20;
+		{
+			//v149 = v731 - 1;
+			//if ( v149 && (v150 = v149 - 1) != 0 && (v151 = v150 - 1) != 0 )
+			int i;
+			if ( v731 == 4 )
+			{
+				i = 20;
 			}
 			else
 			{
-				_this = (ItemGen *)16;
+				i = 16;
 			}
 			if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
 			{
@@ -4274,125 +3726,109 @@
 				LODWORD(v727) = pParty->vPosition.y + sub_42EBBE(2048, v156);
 				v154 = pParty->vPosition.z;
 			}
-			HIDWORD(v733) = v154;
-			v713 = v154 + 2500;
-			v721 = 0;
-			LODWORD(v718) = 0;
-			if ( (signed int)_this > 0 )
-			{
-				*(float *)&y = (double)SHIDWORD(v733);
-				*(float *)&v732 = (double)v713;
+			unsigned __int64 k = 0;
+			int j = 0;
+			if ( (signed int)i > 0 )
+			{
 				v730 = LODWORD(v725) == 3 ? a2 : 0;
-				auto _this_cpy = (int)_this;
 				do
 				{
-				//v157 = rand();
-				v158 = (double)SLODWORD(v718);
-				v718 = v158;
-				v159 = (double)v721;
-				*(float *)&v721 = v159;
-				a2 = rand() % 1000;
-				*((float *)&v733 + 1) = (double)(rand() % 1000) + *(float *)&y - *(float *)&v732;
-				//v725 = v159 * v159;
-				*(float *)&_this = v158 * v158;
-				//if ( sqrt(*((float *)&v733 + 1) * *((float *)&v733 + 1) + *(float *)&_this + v725) <= 1.0 )
-				if ( sqrt(*((float *)&v733 + 1) * *((float *)&v733 + 1) + *(float *)&_this + v159 * v159) <= 1.0 )
-				{
-					LODWORD(v687) = 0;
-					HIDWORD(v687) = 0;
-				}
-				else
-				{
-					//x = (signed __int64)sqrt(*(float *)&_this + v725);
-					x = (signed __int64)sqrt(*(float *)&_this + v159 * v159);
-					v687 = __PAIR__(
-							stru_5C6E00->Atan2(x, (signed __int64)*((float *)&v733 + 1)),
-							stru_5C6E00->Atan2((signed __int64)v718, (signed __int64)*(float *)&v721));
+					a2 = rand() % 1000;
+					if ( sqrt((double)(rand() % 1000) - 2500 * 
+								(double)(rand() % 1000) - 2500 + 
+								j * j + k * k) <= 1.0 )
+					{
+						LODWORD(v687) = 0;
+						HIDWORD(v687) = 0;
+					}
+					else
+					{
+						v687 = __PAIR__(
+								stru_5C6E00->Atan2((signed __int64)sqrt((float)(j * j + k * k)), 
+													(double)(rand() % 1000) - 2500),
+													stru_5C6E00->Atan2(j, k));
+					}
+					pSpellSprite.stru_24.Reset();
+					pSpellSprite.spell_id = pCastSpell->spellnum;
+					pSpellSprite.spell_level = v2;
+					pSpellSprite.spell_skill = v731;
+					pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+					pSpellSprite.uAttributes = 0;
+					pSpellSprite.vPosition.x = uRequiredMana;
+					pSpellSprite.vPosition.y = LODWORD(v727);
+					pSpellSprite.uSectorID = 0;
+					pSpellSprite.vPosition.z = a2 + v713;
+					pSpellSprite.uSpriteFrameID = 0;
+					pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+					pSpellSprite.spell_target_pid = v730;
+					pSpellSprite.field_60_distance_related_prolly_lod = stru_50C198._427546(a2 + 2500);
+					pSpellSprite.uFacing = v687;
+					pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+					if ( pParty->bTurnBasedModeOn == 1 )
+						pSpellSprite.uAttributes = 4;
+					if ( pSpellSprite.Create(v687, SHIDWORD(v687), pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed, 0) != -1
+						&& pParty->bTurnBasedModeOn == 1 )
+						++pTurnEngine->field_1C;
+					j = rand() % 1024 - 512;
+					k = rand() % 1024 - 512;
 				}
-				pSpellSprite.stru_24.Reset();
-				pSpellSprite.spell_id = pCastSpell->spellnum;
-				pSpellSprite.spell_level = v2;
-				pSpellSprite.spell_skill = v731;
-				pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-				pSpellSprite.uAttributes = 0;
-				pSpellSprite.vPosition.x = uRequiredMana;
-				pSpellSprite.vPosition.y = LODWORD(v727);
-				pSpellSprite.uSectorID = 0;
-				pSpellSprite.vPosition.z = a2 + v713;
-				pSpellSprite.uSpriteFrameID = 0;
-				pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-				pSpellSprite.spell_target_pid = v730;
-				pSpellSprite.field_60_distance_related_prolly_lod = stru_50C198._427546(a2 + 2500);
-				pSpellSprite.uFacing = v687;
-				pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-				if ( pParty->bTurnBasedModeOn == 1 )
-					pSpellSprite.uAttributes = 4;
-				if ( pSpellSprite.Create(v687, SHIDWORD(v687), pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed, 0) != -1
-					&& pParty->bTurnBasedModeOn == 1 )
-					++pTurnEngine->field_1C;
-				LODWORD(v718) = rand() % 1024 - 512;
-				//v160 = rand();
-				v14 = _this_cpy-- == 1;
-				v721 = (unsigned __int64)(rand() % 1024) - 512;
-				}
-				while ( !v14 );
+				while ( i-- != 1 );
 			}
 			LODWORD(v727) = 1;
 			break;
 		}
 		case SPELL_FIRE_INFERNO:
 		{
-		//v67 = 2;
-		if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor)
-		{
-			ShowStatusBarString(pGlobalTXT_LocalizationStrings[492], 2); // Can't cast Inferno outdoors!
-			pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-			pCastSpell->spellnum = 0;
-			continue;
-		}
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
+			//v67 = 2;
+			if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor)
+			{
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[492], 2); // Can't cast Inferno outdoors!
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				pCastSpell->spellnum = 0;
+				continue;
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			auto _v726 = sub_46A6AC((int)dword_50BF30, 100, 4096);
+			v700.z = 0;
+			v700.y = 0;
+			v700.x = 0;
+			pSpellSprite.stru_24.Reset();
+			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_level = v2;
+			pSpellSprite.spell_skill = v731;
+			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+			pSpellSprite.uAttributes = 0;
+			pSpellSprite.uSectorID = 0;
+			pSpellSprite.uSpriteFrameID = 0;
+			pSpellSprite.field_60_distance_related_prolly_lod = 0;
+			pSpellSprite.uFacing = 0;
+			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+			a2 = 0;
+			if ( (signed int)_v726 > 0 )
+			{
+				do
+				{
+					v162 = dword_50BF30[a2];
+					pSpellSprite.vPosition.x = pActors[v162].vPosition.x;
+					pSpellSprite.vPosition.y = pActors[v162].vPosition.y;
+					pSpellSprite.vPosition.z = pActors[v162].vPosition.z - (unsigned int)(signed __int64)((double)pActors[v162].uActorHeight * unk_4D8548);
+					pSpellSprite.spell_target_pid = PID(OBJECT_Actor, dword_50BF30[a2]);
+					v164 = pSpellSprite.Create(0, 0, 0, 0);
+					v165 = a2;
+					DamageMonsterFromParty(PID(OBJECT_Item, v164), dword_50BF30[a2], &v700);
+					pGame->GetStru6()->_4A81CA(&pSpellSprite);
+					pGame->GetStru6()->FadeScreen__like_Turn_Undead_and_mb_Armageddon(0xFF3C1Eu, 0x40u);
+					a2 = v165 + 1;
+				}
+				while ( v165 + 1 < (signed int)_v726 );
+			}
+			LODWORD(v727) = 1;
 			break;
-		auto _v726 = sub_46A6AC((int)dword_50BF30, 100, 4096);
-		v700.z = 0;
-		v700.y = 0;
-		v700.x = 0;
-		pSpellSprite.stru_24.Reset();
-		pSpellSprite.spell_id = pCastSpell->spellnum;
-		pSpellSprite.spell_level = v2;
-		pSpellSprite.spell_skill = v731;
-		pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-		pSpellSprite.uAttributes = 0;
-		pSpellSprite.uSectorID = 0;
-		pSpellSprite.uSpriteFrameID = 0;
-		pSpellSprite.field_60_distance_related_prolly_lod = 0;
-		pSpellSprite.uFacing = 0;
-		pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-		pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-		a2 = 0;
-		if ( (signed int)_v726 > 0 )
+		}
+		case SPELL_AIR_WIZARD_EYE:
 		{
-			do
-			{
-			v162 = dword_50BF30[a2];
-			pSpellSprite.vPosition.x = pActors[v162].vPosition.x;
-			pSpellSprite.vPosition.y = pActors[v162].vPosition.y;
-			pSpellSprite.vPosition.z = pActors[v162].vPosition.z - (unsigned int)(signed __int64)((double)pActors[v162].uActorHeight * unk_4D8548);
-			pSpellSprite.spell_target_pid = PID(OBJECT_Actor, dword_50BF30[a2]);
-			v164 = pSpellSprite.Create(0, 0, 0, 0);
-			v165 = a2;
-			DamageMonsterFromParty(PID(OBJECT_Item, v164), dword_50BF30[a2], &v700);
-			pGame->GetStru6()->_4A81CA(&pSpellSprite);
-			pGame->GetStru6()->FadeScreen__like_Turn_Undead_and_mb_Armageddon(0xFF3C1Eu, 0x40u);
-			a2 = v165 + 1;
-			}
-			while ( v165 + 1 < (signed int)_v726 );
-		}
-		LODWORD(v727) = 1;
-		break;
-		}
-
-		case SPELL_AIR_WIZARD_EYE:
-			{
 			LODWORD(v733) = 3600 * v2;
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
@@ -4407,22 +3843,17 @@
 			pParty->pPartyBuffs[PARTY_BUFF_WIZARD_EYE].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, 0, 0, 0);
 			LODWORD(v727) = 1;
 			break;
-			}
+		}
 		case SPELL_AIR_FEATHER_FALL:
-			{
-			if ( v731 == 1 )
-			{
-				LODWORD(v733) = 300 * v2;
-			}
-			else if ( v731 == 2 )
-			{
-				LODWORD(v733) = 600 * v2;
-			}
-			else if ( v731 == 3 || v731 == 4 )
-			{
-				LODWORD(v733) = 3600 * v2;
-	//LABEL_353:
-				//LODWORD(v733) = v173;
+		{
+			switch (v731)
+			{
+				case 1: LODWORD(v733) = 300 * v2; break;
+				case 2: LODWORD(v733) = 600 * v2; break;
+				case 3: LODWORD(v733) = 3600 * v2; break;
+				case 4: LODWORD(v733) = 3600 * v2; break;
+				default:
+				assert(false);
 			}
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
@@ -4438,78 +3869,60 @@
 			pParty->pPartyBuffs[PARTY_BUFF_FEATHER_FALL].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, 0, 0, 0);
 			LODWORD(v727) = 1;
 			break;
-			}
+		}
 		case SPELL_AIR_SPARKS:
 		{
-		v184 = v731 - 1;
-		if ( v184 )
-		{
-			v185 = v184 - 1;
-			if ( v185 )
-			{
-			v186 = v185 - 1;
-			if ( v186 )
-			{
-				if ( v186 == 1 )
-				amount = 9;
-			}
-			else
-			{
-				amount = 7;
-			}
-			}
-			else
-			{
-			amount = 5;
-			}
-		}
-		else
-		{
-			amount = 3;
-		}
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
+			switch (v731)
+			{
+				case 1: amount = 3; break;
+				case 2: amount = 5; break;
+				case 3: amount = 7; break;
+				case 4: amount = 9; break;
+				default:
+				assert(false);
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			auto _v726 = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360;
+			pSpellSprite.stru_24.Reset();
+			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_level = v2;
+			pSpellSprite.spell_skill = v731;
+			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+			pSpellSprite.vPosition.y = pParty->vPosition.y;
+			pSpellSprite.vPosition.x = pParty->vPosition.x;
+			pSpellSprite.uAttributes = 0;
+			pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
+			pSpellSprite.uSectorID = pIndoor->GetSector(
+								pParty->vPosition.x,
+								pParty->vPosition.y,
+								pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3);
+			pSpellSprite.uSpriteFrameID = 0;
+			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+			pSpellSprite.spell_target_pid = a2;
+			pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
+			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+			if ( pParty->bTurnBasedModeOn == 1 )
+				LOBYTE(pSpellSprite.uAttributes) |= 4u;
+			v188 = (signed int)_v726 / -2;
+			v189 = (signed int)_v726 / 2;
+			while ( v188 <= v189 )
+			{
+				pSpellSprite.uFacing = v188 + LOWORD(v715.uYawAngle);
+				if ( pSpellSprite.Create(
+						(signed __int16)(v188 + LOWORD(v715.uYawAngle)),
+						v715.uPitchAngle,
+						pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed,
+						pCastSpell->uPlayerID + 1) != -1
+						&& pParty->bTurnBasedModeOn == 1 )
+				+	+pTurnEngine->field_1C;
+				v188 += _v726 / (amount - 1);
+			}
+			LODWORD(v727) = 1;
 			break;
-		auto _v726 = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360;
-		pSpellSprite.stru_24.Reset();
-		pSpellSprite.spell_id = pCastSpell->spellnum;
-		pSpellSprite.spell_level = v2;
-		pSpellSprite.spell_skill = v731;
-		pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-		pSpellSprite.vPosition.y = pParty->vPosition.y;
-		pSpellSprite.vPosition.x = pParty->vPosition.x;
-		pSpellSprite.uAttributes = 0;
-		pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
-		pSpellSprite.uSectorID = pIndoor->GetSector(
-							pParty->vPosition.x,
-							pParty->vPosition.y,
-							pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3);
-		pSpellSprite.uSpriteFrameID = 0;
-		pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-		pSpellSprite.spell_target_pid = a2;
-		pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
-		pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-		if ( pParty->bTurnBasedModeOn == 1 )
-			LOBYTE(pSpellSprite.uAttributes) |= 4u;
-		v188 = (signed int)_v726 / -2;
-		v189 = (signed int)_v726 / 2;
-		while ( v188 <= v189 )
+		}
+		case SPELL_AIR_JUMP:
 		{
-			pSpellSprite.uFacing = v188 + LOWORD(v715.uYawAngle);
-			if ( pSpellSprite.Create(
-					(signed __int16)(v188 + LOWORD(v715.uYawAngle)),
-					v715.uPitchAngle,
-					pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed,
-					pCastSpell->uPlayerID + 1) != -1
-			&& pParty->bTurnBasedModeOn == 1 )
-			++pTurnEngine->field_1C;
-			v188 += _v726 / (amount - 1);
-		}
-		LODWORD(v727) = 1;
-		break;
-		}
-
-		case SPELL_AIR_JUMP:
-			{
 			if ( pParty->uFlags & PARTY_FLAGS_1_FALLING)
 			{
 				ShowStatusBarString(pGlobalTXT_LocalizationStrings[493], 2);  // Can't cast Jump while airborne!
@@ -4526,36 +3939,18 @@
 			pParty->uFallSpeed = 1000;
 			LODWORD(v727) = 1;
 			break;
-			}
+		}
 		case SPELL_AIR_INVISIBILITY:
-			{
-			v192 = v731 - 1;
-			if ( v731 == 1 )
-			{
-				amount = v2;
-				LODWORD(v733) = 600 * v2;
-			}
-			else if ( v731 == 2 )
-			{
-				v196 = 2 * v2;
-				amount = v196;
-				LODWORD(v733) = 600 * v2;
-			}
-			else if ( v731 == 3 )
-			{
-				v196 = 3 * v2;
-				//goto LABEL_389;
-				amount = v196;
-				LODWORD(v733) = 600 * v2;
-			}
-			else if ( v731 == 4 )
-			{
-			amount = 4 * v2;
-			v195 = 3600 * v2;
-//	LABEL_392:
-			LODWORD(v733) = v195;
-			}
-//	LABEL_393:
+		{
+			switch (v731)
+			{
+				case 1: LODWORD(v733) = 600 * v2; amount = v2; break;
+				case 2: LODWORD(v733) = 600 * v2; amount = 2 * v2; break;
+				case 3: LODWORD(v733) = 600 * v2; amount = 3 * v2; break;
+				case 4: LODWORD(v733) = 3600 * v2; amount = 4 * v2; break;
+				default:
+				assert(false);
+			}
 			if (pParty->uFlags & (PARTY_FLAGS_1_ALERT_RED | PARTY_FLAGS_1_ALERT_YELLOW))
 			{
 				ShowStatusBarString(pGlobalTXT_LocalizationStrings[638], 2);  // There are hostile creatures nearby!
@@ -4574,190 +3969,184 @@
 				LODWORD(v727) = 1;
 			}
 			break;
-			}
+		}
 		case SPELL_AIR_FLY:
 		{
-		if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
-		{
-			ShowStatusBarString(pGlobalTXT_LocalizationStrings[494], 2);  // Can not cast Fly indoors!
-			pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-			break;
-		}
-		if ( !pPlayers[pCastSpell->uPlayerID + 1]->GetMaxMana() )
-		{
-			ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2);  // Spell failed
-			pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+			if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
+			{
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[494], 2);  // Can not cast Fly indoors!
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				break;
+			}
+			if ( !pPlayers[pCastSpell->uPlayerID + 1]->GetMaxMana() )
+			{
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2);  // Spell failed
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				break;
+			}
+			LODWORD(v733) = 3600 * v2;
+			if ( v731 == 1 || v731 == 2 || v731 == 3 )
+				amount = 1;
+			else
+				amount = 0;
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			v205 = 0;
+			do
+				pOtherOverlayList->_4418B1(2090, v205++ + 100, 0, 65536);
+			while ( v205 < 4 );
+			v206 = pOtherOverlayList->_4418B1(10008, 203, 0, 65536);
+			v207 = pCastSpell->uPlayerID + 1;
+			v716 = v206;
+
+			pParty->pPartyBuffs[PARTY_BUFF_FLY].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, amount, v206, v207);
+			LODWORD(v727) = 1;
 			break;
 		}
-		LODWORD(v733) = 3600 * v2;
-		if ( v731 == 2 || v731 == 3 || (amount = 0, v731 != 4) )
-			amount = 1;
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			break;
-		v205 = 0;
-		do
-			pOtherOverlayList->_4418B1(2090, v205++ + 100, 0, 65536);
-		while ( v205 < 4 );
-		v206 = pOtherOverlayList->_4418B1(10008, 203, 0, 65536);
-		v207 = pCastSpell->uPlayerID + 1;
-		v716 = v206;
-
-		pParty->pPartyBuffs[PARTY_BUFF_FLY].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, amount, v206, v207);
-		LODWORD(v727) = 1;
-		break;
-		}
-
 		case SPELL_AIR_STARBURST:
 		{
-		//v67 = 2;
-		if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
-		{
-			ShowStatusBarString(pGlobalTXT_LocalizationStrings[495], 2);  // Can't cast Starburst indoors!
-			pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-			pCastSpell->spellnum = 0;
-			continue;
-		}
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			break;
-		v208 = PID_TYPE(a2);
-		LODWORD(v725) = PID_TYPE(a2);
-		if ( v208 == 3 )
-		{
-			v209 = PID_ID(a2);
-			LODWORD(v718) = pActors[v209].vPosition.x;
-			v210 = pActors[v209].vPosition.y;
-			v211 = pActors[v209].vPosition.z;
-			v713 = v210;
-		}
-		else
-		{
-			v212 = stru_5C6E00->Cos(pParty->sRotationY);
-			LODWORD(v718) = pParty->vPosition.x + sub_42EBBE(2048, v212);
-			v213 = stru_5C6E00->Sin(pParty->sRotationY);
-			v214 = sub_42EBBE(2048, v213);
-			v211 = pParty->vPosition.z;
-			v713 = pParty->vPosition.y + v214;
-			v208 = LODWORD(v725);
-		}
-		HIDWORD(v733) = 0;
-		*(float *)&v732 = (double)v211;
-		LODWORD(v725) = v211 + 2500;
-		v721 = 0;
-		*(float *)&y = (double)(v211 + 2500);
-		v730 = v208 == 3 ? a2 : 0;
-		a2 = 20;
-		do
-		{
-			v215 = rand();
-			v216 = (double)v721;
-			v217 = (double)SHIDWORD(v733);
-			*(float *)&uRequiredMana = v217;
-			_this = (ItemGen *)(v215 % 1000);
-			*((float *)&v733 + 1) = (double)(v215 % 1000) + *(float *)&v732 - *(float *)&y;
-			*(float *)&v721 = v217 * v217;
-			//*(float *)&v726 = v216 * v216;
-			if ( sqrt(*((float *)&v733 + 1) * *((float *)&v733 + 1) + v216 * v216 + *(float *)&v721) <= 1.0 )
-			{
-			LODWORD(v685) = 0;
-			HIDWORD(v685) = 0;
+			//v67 = 2;
+			if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
+			{
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[495], 2);  // Can't cast Starburst indoors!
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				pCastSpell->spellnum = 0;
+				continue;
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			v208 = PID_TYPE(a2);
+			LODWORD(v725) = PID_TYPE(a2);
+			if ( v208 == 3 )
+			{
+				v209 = PID_ID(a2);
+				LODWORD(v718) = pActors[v209].vPosition.x;
+				v210 = pActors[v209].vPosition.y;
+				v211 = pActors[v209].vPosition.z;
+				v713 = v210;
 			}
 			else
 			{
-			v684 = (signed __int64)sqrt(v216 * v216 + *(float *)&v721);
-			v685 = __PAIR__(
-						stru_5C6E00->Atan2(v684, (signed __int64)*((float *)&v733 + 1)),
-						stru_5C6E00->Atan2((signed __int64)v216, (signed __int64)*(float *)&uRequiredMana));
-			}
-			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
-			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-			pSpellSprite.uAttributes = 0;
-			pSpellSprite.vPosition.x = LODWORD(v718);
-			pSpellSprite.vPosition.y = v713;
-			pSpellSprite.uSectorID = 0;
-			pSpellSprite.vPosition.z = (int)((char *)_this + LODWORD(v725));
-			pSpellSprite.uSpriteFrameID = 0;
-			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-			pSpellSprite.spell_target_pid = v730;
-			//__debugbreak();//çâåçäîïàä
-			pSpellSprite.field_60_distance_related_prolly_lod = stru_50C198._427546((int)&_this[69].uNumCharges);
-			pSpellSprite.uFacing = v685;
-			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-			if ( pParty->bTurnBasedModeOn == 1 )
-			pSpellSprite.uAttributes = 4;
-			if ( pSpellSprite.Create(v685, SHIDWORD(v685), pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed, 0) != -1
-                   && pParty->bTurnBasedModeOn == 1 )
-              ++pTurnEngine->field_1C;
-			v721 = rand() % 1024 - 512;
-			v218 = rand();
-			v14 = a2-- == 1;
-			HIDWORD(v733) = (unsigned __int64)(v218 % 1024) - 512;
-		}
-		while ( !v14 );
-		LODWORD(v727) = 1;
-		break;
-		}
-
-		case SPELL_WATER_AWAKEN:
-		{
-			if ( v731 == 1 )
-				amount = 180 * v2;
-			else if ( v731 == 2)
-				amount = 3600 * v2;
-			else if ( v731 == 3 )
-				amount = 86400 * v2;
-			else if ( v731 == 4 )
-				amount = 0;
-//	LABEL_433:
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			v222 = pParty->pPlayers;
-			HIDWORD(v733) = (int)(char *)&pParty + 2508;
-			while ( 2 )
-			{
-				if ( v731 == 4 )
+				v212 = stru_5C6E00->Cos(pParty->sRotationY);
+				LODWORD(v718) = pParty->vPosition.x + sub_42EBBE(2048, v212);
+				v213 = stru_5C6E00->Sin(pParty->sRotationY);
+				v214 = sub_42EBBE(2048, v213);
+				v211 = pParty->vPosition.z;
+				v713 = pParty->vPosition.y + v214;
+				v208 = LODWORD(v725);
+			}
+			signed int _v733 = 0;
+			*(float *)&v732 = (double)v211;
+			LODWORD(v725) = v211 + 2500;
+			v721 = 0;
+			*(float *)&y = (double)(v211 + 2500);
+			v730 = v208 == 3 ? a2 : 0;
+			a2 = 20;
+			do
+			{
+				v215 = rand();
+				v216 = (double)v721;
+				v217 = (double)_v733;
+				*(float *)&uRequiredMana = v217;
+				_this = (ItemGen *)(v215 % 1000);
+				*((float *)&v733 + 1) = (double)(v215 % 1000) + *(float *)&v732 - *(float *)&y;
+				*(float *)&v721 = v217 * v217;
+				//*(float *)&v726 = v216 * v216;
+				if ( sqrt(*((float *)&v733 + 1) * *((float *)&v733 + 1) + v216 * v216 + *(float *)&v721) <= 1.0 )
 				{
-				if ( v222->pConditions[2] )
-				{
-					//*((int *)v222 + 4) = 0;
-					//*((int *)v222 + 5) = 0;
-					v222->pConditions[2] = 0;
-					v222->PlaySound(SPEECH_103, 0);
-				}
+					LODWORD(v685) = 0;
+					HIDWORD(v685) = 0;
 				}
 				else
 				{
-				v223 = v222->DiscardConditionIfLastsLongerThan(
-							2u,
-							pParty->uTimePlayed - (signed int)(signed __int64)((double)(amount << 7) * 0.033333335));
-				v222 = (Player *)HIDWORD(v733);
-				if ( v223 )
-					v222->PlaySound(SPEECH_103, 0);
+					v684 = (signed __int64)sqrt(v216 * v216 + *(float *)&v721);
+					v685 = __PAIR__(
+								stru_5C6E00->Atan2(v684, (signed __int64)*((float *)&v733 + 1)),
+								stru_5C6E00->Atan2((signed __int64)v216, (signed __int64)*(float *)&uRequiredMana));
 				}
-				++v222;// += 6972;
-				HIDWORD(v733) = (int)v222;
-				if ( v222 >= &pParty->pPlayers[3] )
+				pSpellSprite.stru_24.Reset();
+				pSpellSprite.spell_id = pCastSpell->spellnum;
+				pSpellSprite.spell_level = v2;
+				pSpellSprite.spell_skill = v731;
+				pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+				pSpellSprite.uAttributes = 0;
+				pSpellSprite.vPosition.x = LODWORD(v718);
+				pSpellSprite.vPosition.y = v713;
+				pSpellSprite.uSectorID = 0;
+				pSpellSprite.vPosition.z = (int)((char *)_this + LODWORD(v725));
+				pSpellSprite.uSpriteFrameID = 0;
+				pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+				pSpellSprite.spell_target_pid = v730;
+				//__debugbreak();//çâåçäîïàä
+				pSpellSprite.field_60_distance_related_prolly_lod = stru_50C198._427546((int)&_this[69].uNumCharges);
+				pSpellSprite.uFacing = v685;
+				pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+				if ( pParty->bTurnBasedModeOn == 1 )
+				pSpellSprite.uAttributes = 4;
+				if ( pSpellSprite.Create(v685, SHIDWORD(v685), pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed, 0) != -1
+					   && pParty->bTurnBasedModeOn == 1 )
+				  ++pTurnEngine->field_1C;
+				v721 = rand() % 1024 - 512;
+				v218 = rand();
+				v14 = a2-- == 1;
+				_v733 = (unsigned __int64)(v218 % 1024) - 512;
+			}
+			while ( !v14 );
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_WATER_AWAKEN:
+		{
+			switch (v731)
+			{
+				case 1: amount = 180 * v2; break;
+				case 2: amount = 3600 * v2; break;
+				case 3: amount = 86400 * v2; break;
+				case 4: amount = 0; break;
+				default:
+				assert(false);
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			for( int i=0; i < 4; i++ )
+			{
+				pPlayer = &pParty->pPlayers[i];
+				if ( v731 == 4 )
 				{
-					LODWORD(v727) = 1;
-					break;
+					if ( pPlayer->pConditions[2] )
+					{
+						//*((int *)v222 + 4) = 0;
+						//*((int *)v222 + 5) = 0;
+						pPlayer->pConditions[2] = 0;
+						pPlayer->PlaySound(SPEECH_103, 0);
+					}
 				}
-			}
-			}
+				else
+				{
+					v223 = pPlayer->DiscardConditionIfLastsLongerThan(
+								2u,
+								pParty->uTimePlayed - (signed int)(signed __int64)((double)(amount << 7) * 0.033333335));
+					if ( v223 )
+						pPlayer->PlaySound(SPEECH_103, 0);
+				}
+			}
+			LODWORD(v727) = 1;
+			break;
+		}
 		case SPELL_WATER_POISON_SPRAY:
 		{
-			if ( v731 == 1 )
-				amount = 1;
-			else if ( v731 == 2 )
-				amount = 3;
-			else if ( v731 == 3 )
-				amount = 5;
-			else if ( v731 == 4 )
-				amount = 7;
+			switch (v731)
+			{
+				case 1: amount = 1; break;
+				case 2: amount = 3; break;
+				case 3: amount = 5; break;
+				case 4: amount = 7; break;
+				default:
+				assert(false);
+			}
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
-			HIDWORD(v733) = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360;
+			signed int _v733 = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360;
 			if ( amount == 1 )
 			{
 				pSpellSprite.stru_24.Reset();
@@ -4805,457 +4194,175 @@
 				pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
 				pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
 				if ( pParty->bTurnBasedModeOn == 1 )
-				LOBYTE(pSpellSprite.uAttributes) |= 4u;
+					LOBYTE(pSpellSprite.uAttributes) |= 4u;
 				v227 = SHIDWORD(v733) / -2;
-				y = (char *)(SHIDWORD(v733) / 2);
-				if ( SHIDWORD(v733) / -2 <= SHIDWORD(v733) / 2 )
-				{
-				v228 = v715.uYawAngle;
-				do
+				signed int _y = _v733 / 2;
+				if ( _v733 / -2 <= _v733 / 2 )
 				{
-					pSpellSprite.uFacing = v227 + v228;
-					if ( pSpellSprite.Create(
-							v227 + v228,
-							v715.uPitchAngle,
-							pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed,
-							pCastSpell->uPlayerID + 1) != -1
-					&& pParty->bTurnBasedModeOn == 1 )
-					++pTurnEngine->field_1C;
-					v227 += SHIDWORD(v733) / (amount - 1);
-				}
-				while ( v227 <= (signed int)y );
+					v228 = v715.uYawAngle;
+					do
+					{
+						pSpellSprite.uFacing = v227 + v228;
+						if ( pSpellSprite.Create(
+								v227 + v228,
+								v715.uPitchAngle,
+								pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed,
+								pCastSpell->uPlayerID + 1) != -1
+								&& pParty->bTurnBasedModeOn == 1 )
+							++pTurnEngine->field_1C;
+						v227 += _v733 / (amount - 1);
+					}
+					while ( v227 <= _y );
 				}
 			}
 			LODWORD(v727) = 1;
 			break;
 		}
 		case SPELL_WATER_WATER_WALK:
-			{
-		if ( !pPlayers[pCastSpell->uPlayerID + 1]->GetMaxMana() )
 		{
-			ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2);  // Spell failed
-			pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+			if ( !pPlayers[pCastSpell->uPlayerID + 1]->GetMaxMana() )
+			{
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2);  // Spell failed
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				break;
+			}
+			if ( v731 == 2 || v731 != 3 && v731 != 4 )
+				v229 = 600 * v2;
+			else
+				v229 = 3600 * v2;
+			LODWORD(v733) = v229;
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			v716 = pOtherOverlayList->_4418B1(10005, 201, 0, 65536);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
+
+			pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].Apply(
+				pParty->uTimePlayed + (signed int)(signed __int64)((double)(v229 << 7) * 0.033333335),
+				v731,
+				amount,
+				v716,
+				pCastSpell->uPlayerID + 1);
+			if ( v731 == 4 )
+				pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].uFlags = 1;
+			LODWORD(v727) = 1;
 			break;
 		}
-		if ( v731 == 2 || v731 != 3 && v731 != 4 )
-			v229 = 600 * v2;
-		else
-			v229 = 3600 * v2;
-		LODWORD(v733) = v229;
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			break;
-		v716 = pOtherOverlayList->_4418B1(10005, 201, 0, 65536);
-		pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
-		pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
-		pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
-		pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
-
-		pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].Apply(
-			pParty->uTimePlayed + (signed int)(signed __int64)((double)(v229 << 7) * 0.033333335),
-			v731,
-			amount,
-			v716,
-			pCastSpell->uPlayerID + 1);
-		if ( v731 == 4 )
-			pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].uFlags = 1;
-		LODWORD(v727) = 1;
-		break;
-			}
 		case SPELL_WATER_RECHARGE_ITEM:
-			{
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			break;
-		v240 = (char *)&pParty->pPlayers[pCastSpell->uPlayerID_2].pInventoryItems[a2];
-		y = v240;
-		if ( pItemsTable->pItems[*(int *)v240].uEquipType != 12 || v240[20] & 2 )
-		{
-			dword_50C9D0 = 113;
-			dword_50C9D4 = 0;
-			dword_50C9D8 = 1;
-
-			ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2);  // Spell failed
-			pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-			pCastSpell->spellnum = 0;
-			continue;
-		}
-		if ( v731 == 1 || v731 == 2 )
-		{
-			v241 = (double)v723 * 0.0099999998 + 0.5;
-		}
-		else if ( v731 == 3 )
-		{
-			v241 = (double)v723 * 0.0099999998 + 0.69999999;
-		}
-		else if ( v731 == 4 )
-		{
-			v241 = (double)v723 * 0.0099999998 + 0.80000001;
-		}
-		else
-		{
-			v241 = 0.0;
-		}
-		if ( v241 > 1.0 )
-			v241 = 1.0;
-//LABEL_484:
-		v732 = (unsigned __int8)v240[25];
-		v242 = (signed __int64)((double)v732 * v241);
-		v243 = y;
-		y[25] = v242;
-		*((int *)v243 + 4) = (unsigned __int8)v242;
-		if ( (unsigned __int8)v242 <= 0 )
-		{
-			*(int *)v243 = 0;
-			dword_50C9D0 = 113;
-			dword_50C9D4 = 0;
-			dword_50C9D8 = 1;
-			ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2u);
-			pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-			pCastSpell->spellnum = 0;
-			v2 = v723;
-			continue;
-		}
-		*((int *)v243 + 5) |= 0x40u;
-					_50C9A8_item_enchantment_timer = 256;
-					LODWORD(v727) = 1;
-					break;
-			}
-		case SPELL_WATER_ENCHANT_ITEM:
-			{
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			break;
-		uRequiredMana = 0;
-		HIDWORD(v733) = 10 * v2;
-		v730 = 1;
-		v244 = (char *)&pParty->pPlayers[pCastSpell->uPlayerID_2];
-		if ( v731 == 1 )
 		{
-			v245 = (int)&v244[36 * a2 + 532];
-			v309 = (char *)&pItemsTable->pItems[*(int *)v245].pIconName;
-			v311 = __OFSUB__(*(int *)v245, 134);
-			v14 = *(int *)v245 == 134;
-			v310 = *(int *)v245 - 134 < 0;
-			LODWORD(v725) = (int)(char *)&pItemsTable + 48 * *(int *)v245 + 4;
-			if ( (unsigned __int8)(v310 ^ v311) | v14 )
-			{
-			if ( *(int *)&v244[36 * a2 + 544] == 0 )
-			{
-				if ( *(int *)&v244[36 * a2 + 536] == 0 )
-				{
-				if ( *(int *)&v244[36 * a2 + 540] == 0 )
-				{
-					v312 = v309[28];
-					if ( v312 )
-					{
-					if ( v312 != 1 )
-					{
-						if ( v312 != 2 )
-						{
-						_this = (ItemGen *)&v244[36 * a2 + 552];
-						if ( !(v244[36 * a2 + 552] & 2) )
-						{
-							if ( ((ItemGen *)v245)->GetValue() < 0x1C2 )
-							{
-							uRequiredMana = 1;
-							v730 = 0;
-							}
-							if ( rand() % 100 >= SHIDWORD(v733) )
-							uRequiredMana = 1;
-							if (!uRequiredMana)
-							{
-							v313 = *(char *)(LODWORD(v725) + 28);
-							if ( v313 == 3 | v313 == 4 | v313 == 5 | v313 == 6 | v313 == 7 | v313 == 8 | v313 == 9 | v313 == 10 | v313 == 11 )
-							{
-								v314 = rand() % 10;//pItemsTable->field_116D8[pItemsTable->pItems[*(int *)v245].uEquipType];
-								*(int *)(v245 + 4) = 0;
-								for ( j = pItemsTable->pEnchantments[0].to_item[pItemsTable->pItems[*(int *)v245].uEquipType
-																			+ 1];
-									;
-									j += pItemsTable->pEnchantments[*(int *)(v245 + 4)].to_item[pItemsTable->pItems[*(int *)v245].uEquipType
-																								+ 1] )
-								{
-								++*(int *)(v245 + 4);
-								if ( j >= v314 )
-									break;
-								}
-								v254 = rand();
-								v255 = 10;//pItemsTable->field_116D8[17];
-								v256 = 10;//pItemsTable->field_116D8[16];
-//LABEL_611:
-								*(int *)(v245 + 8) = v256 + v254 % (v255 - v256 + 1);
-//LABEL_612:
-								_this->uItemID |= 0x20u;
-
-								_50C9A8_item_enchantment_timer = 256;
-								LODWORD(v727) = 1;
-								break;
-							}
-							}
-							else
-							{
-//LABEL_613:					
-							v316 = _this->uItemID;
-							if ( !(BYTE1(v316) & 2) )
-							{
-							LOBYTE(v316) = v316 | 2;
-							_this->uItemID = v316;
-							}
-							}
-						}
-						}
-					}
-					}
-				}
-				}
-			}
-			}
-//LABEL_616:
-			if ( LODWORD(v727) == 0 )
-			{
-				v317 = pGlobalTXT_LocalizationStrings[428];
-				if ( v730 == 0 )
-					v317 = pGlobalTXT_LocalizationStrings[585];
-				ShowStatusBarString(v317, 2u);
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			v240 = &pParty->pPlayers[pCastSpell->uPlayerID_2].pInventoryItems[a2];
+			
+			if ( pItemsTable->pItems[v240->uItemID].uEquipType != 12 || v240->uAttributes & 2 )
+			{
+				dword_50C9D0 = 113;
+				dword_50C9D4 = 0;
+				dword_50C9D8 = 1;
+
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2);  // Spell failed
 				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				v318 =  &pParty->pPlayers[pCastSpell->uPlayerID_2];
 				pCastSpell->spellnum = 0;
-				v318->PlaySound(SPEECH_43, 0);
-			}
+				continue;
+			}
+			if ( v731 == 1 || v731 == 2 )
+			{
+				v241 = (double)v723 * 0.0099999998 + 0.5;
+			}
+			else if ( v731 == 3 )
+			{
+				v241 = (double)v723 * 0.0099999998 + 0.69999999;
+			}
+			else if ( v731 == 4 )
+			{
+				v241 = (double)v723 * 0.0099999998 + 0.80000001;
+			}
+			else
+			{
+				v241 = 0.0;
+			}
+			if ( v241 > 1.0 )
+				v241 = 1.0;
+			int uNewCharges = v240->uMaxCharges * v241;
+			v240->uMaxCharges = uNewCharges;
+			v240->uNumCharges = uNewCharges;
+			if ( uNewCharges <= 0 )
+			{
+				v240 = 0;
+				dword_50C9D0 = 113;
+				dword_50C9D4 = 0;
+				dword_50C9D8 = 1;
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2u);
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				pCastSpell->spellnum = 0;
+				v2 = v723;
+				continue;
+			}
+			v240->uAttributes |= 0x40u;
+			_50C9A8_item_enchantment_timer = 256;
+			LODWORD(v727) = 1;
 			break;
 		}
-		if ( v731 != 2 )
+		case SPELL_WATER_ENCHANT_ITEM:
 		{
-			if ( v731 == 3 )
-			{
-				v245 = (int)&v244[36 * a2 + 532];
-				v269 = *(int *)v245;
-				if ( *(int *)v245 > 134
-					|| *(int *)(v245 + 12) != 0
-					|| *(int *)(v245 + 4) != 0
-					|| *(int *)(v245 + 8) != 0
-					|| (_this = (ItemGen *)(v245 + 20), *(char *)(v245 + 20) & 2) )
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			uRequiredMana = 0;
+			amount = 10 * v2;
+			v730 = 1;
+			pPlayer = &pParty->pPlayers[pCastSpell->uPlayerID_2];
+			v245 = &pPlayer->pInventoryItems[a2];
+			ItemDesc *_v725 = &pItemsTable->pItems[v245->uItemID];
+			if ( 
+				v731 == 1 || v731 == 2 && _v725->uEquipType > 2 ||
+				v731 == 3 || v731 == 4 && 
+				v245->uItemID <= 134 &&
+				v245->uSpecEnchantmentType == 0 &&
+				v245->uEnchantmentType == 0 &&
+				v245->_bonus_strength== 0 &&
+				!v245->Broken() )
+			{
+				if ( v245->GetValue() < 450 || 
+					(v245->GetValue() < 250 && (v731 == 3 || v731 == 4) && _v725->uEquipType >= 0 && _v725->uEquipType <= 2)
+					)
 				{
-					if ( LODWORD(v727) == 0 )
-					{
-						v317 = pGlobalTXT_LocalizationStrings[428];
-						if ( v730 == 0 )
-							v317 = pGlobalTXT_LocalizationStrings[585];
-						ShowStatusBarString(v317, 2u);
-						pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-						v318 =  &pParty->pPlayers[pCastSpell->uPlayerID_2];
-						pCastSpell->spellnum = 0;
-						v318->PlaySound(SPEECH_43, 0);
-					}
-					break;
-				}
-				v270 = (char *)&pItemsTable->pItems[v269].pIconName;
-				LODWORD(v725) = (int)v270;
-				v271 = v270[28];
-				if ( v271 && v271 != 1 && v271 != 2 )
-					v272 = ((ItemGen *)v245)->GetValue() < 0x1C2;
-				else
-					v272 = ((ItemGen *)v245)->GetValue() < 0xFA;
-				if ( v272 )
-				{
-					uRequiredMana = 1;
 					v730 = 0;
 				}
-				if ( rand() % 100 >= SHIDWORD(v733) )
-					uRequiredMana = 1;
-				if (uRequiredMana)
+				if ( rand() % 100 < 10 * v2 || 
+					(rand() % 100 < 80 && (v731 == 3 || v731 == 4 )) ||
+					v245->GetValue() < 450 || 
+					(v245->GetValue() < 250 && (v731 == 3 || v731 == 4) && v271 >= 0 && v271 <= 2)
+					)
 				{
-					v316 = _this->uItemID;
-					if ( !(BYTE1(v316) & 2) )
-					{
-					LOBYTE(v316) = v316 | 2;
-					_this->uItemID = v316;
-					}
-					if ( LODWORD(v727) == 0 )
+					v313 = _v725->uEquipType;
+					if ( _v725->uEquipType >= 3 && _v725->uEquipType <= 11 )
 					{
-						v317 = pGlobalTXT_LocalizationStrings[428];
-						if ( v730 == 0 )
-							v317 = pGlobalTXT_LocalizationStrings[585];
-						ShowStatusBarString(v317, 2u);
-						pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-						v318 =  &pParty->pPlayers[pCastSpell->uPlayerID_2];
-						pCastSpell->spellnum = 0;
-						v318->PlaySound(SPEECH_43, 0);
-					}
-					break;
-				}
-				//v273 = v725;
-				v274 = *(char *)(LODWORD(v725) + 28);
-				if ( v274 == 0 | v274 == 1 | v274 == 2 | v274 == 3 | v274 == 4 | v274 == 5 | v274 == 6 | v274 == 7 | v274 == 8 | v274 == 9 | v274 == 10 | v274 == 11 )
-				{
-					if ( rand() % 100 < 80
-					//&& !(*(char *)(LODWORD(v273) + 28) == 0 | *(char *)(LODWORD(v273) + 28) == 1 | *(char *)(LODWORD(v273) + 28) == 2) )
-					&& !(*(char *)(LODWORD(v725) + 28) == 0 | *(char *)(LODWORD(v725) + 28) == 1 | *(char *)(LODWORD(v725) + 28) == 2) )
-					{
-						v275 = rand() % 10;//pItemsTable->field_116D8[pItemsTable->pItems[*(int *)v245].uEquipType];
-						*(int *)(v245 + 4) = 0;
-						for ( k = pItemsTable->pEnchantments[0].to_item[pItemsTable->pItems[*(int *)v245].uEquipType + 1];
-								;
-								k += pItemsTable->pEnchantments[*(int *)(v245 + 4)].to_item[pItemsTable->pItems[*(int *)v245].uEquipType
-																							+ 1] )
+						v295 = rand() % 10;// pItemsTable->field_116D8[pItemsTable->pItems[_this->uItemID].uEquipType];
+						v245->uEnchantmentType = 0;
+						for ( kk = pItemsTable->pEnchantments[0].to_item[pItemsTable->pItems[v245->uItemID].uEquipType + 1];
+							;
+							kk += pItemsTable->pEnchantments[v294->uEnchantmentType].to_item[pItemsTable->pItems[v245->uItemID].uEquipType + 1] )
 						{
-							++*(int *)(v245 + 4);
-							if ( k >= v275 )
-							break;
+							++v245->uEnchantmentType;
+							if ( kk >= v295 )
+								break;
 						}
-						v254 = rand();
-						v255 = 10;//pItemsTable->field_116D8[19];
-						v256 = 10;//pItemsTable->field_116D8[18];
-						*(int *)(v245 + 8) = v256 + v254 % (v255 - v256 + 1);
-						_this->uItemID |= 0x20u;
-
+						v255 = 10;//pItemsTable->field_116D8[17];
+						v256 = 10;//pItemsTable->field_116D8[16];
+						v245->_bonus_strength = v256 + rand() % (v255 - v256 + 1);
+						v245->uAttributes |= 0x20u;
 						_50C9A8_item_enchantment_timer = 256;
 						LODWORD(v727) = 1;
 						break;
 					}
-					v277 = pItemsTable->pSpecialEnchantments_count;
-					v278 = 0;
-					v725 = 0.0;
-					HIDWORD(v733) = 0;
-					if ( pItemsTable->pSpecialEnchantments_count > 0 )
-					{
-						v730 = (int)&v679;
-						do
-						{
-							v279 = LOBYTE(pItemsTable->pSpecialEnchantments[v278 + 1].pBonusStatement);
-							if ( !v279 || v279 == 1 )
-							{
-								v280 = *(&pItemsTable->pSpecialEnchantments[0].to_item_apply[pItemsTable->pItems[*(int *)v245].uEquipType
-																					+ 4]
-										+ v278 * 28);
-								LODWORD(v725) += v280;
-								if ( v280 )
-								{
-									v281 = v730;
-									v730 += 4;
-									*(int *)v281 = HIDWORD(v733);
-								}
-							}
-							++HIDWORD(v733);
-							++v278;
-						}
-						while ( SHIDWORD(v733) < v277 );
-					}
-					v282 = rand() % SLODWORD(v725);
-					v283 = v679;
-					*(int *)(v245 + 12) = v679;
-					v284 = pItemsTable->pSpecialEnchantments[v283].to_item_apply[pItemsTable->pItems[*(int *)v245].uEquipType + 4];
-					v285 = v282 + 1;
-																		if ( v284 < v285 )
-				{
-				for ( l = &v679; ; l = (int *)v732 )
-				{
-					v287 = (int)(l + 1);
-					v732 = v287;
-					v288 = *(int *)v287;
-					*(int *)(v245 + 12) = v288;
-					v284 += pItemsTable->pSpecialEnchantments[v288].to_item_apply[pItemsTable->pItems[*(int *)v245].uEquipType
-																		+ 4];
-					if ( v284 >= v285 )
-					break;
-				}
-				}
-					++*(int *)(v245 + 12);
-					_this->uItemID |= 0x20u;
-
-					_50C9A8_item_enchantment_timer = 256;
-					LODWORD(v727) = 1;
-					break;
-				}
-			}
-			else
-			{
-				__debugbreak(); // v726 is most probably the caster, filled in case 54
-				if ( v731 != 4
-					|| (v245 = (int)&v726->pInventoryItems[a2], v246 = *(int *)v245, *(int *)v245 > 134)
-					|| v726->pInventoryItems[a2].uSpecEnchantmentType != 0
-					|| v726->pInventoryItems[a2].uEnchantmentType != 0
-					|| v726->pInventoryItems[a2]._bonus_strength != 0
-					|| (_this = (ItemGen *)((char *)&v726->pInventoryItems[a2] + 20), v726->pInventoryItems[a2].Broken()) )
-				{
-					if ( LODWORD(v727) == 0 )
+					else if ( v731 == 3 || v731 == 4)
 					{
-						v317 = pGlobalTXT_LocalizationStrings[428];
-						if ( v730 == 0 )
-							v317 = pGlobalTXT_LocalizationStrings[585];
-						ShowStatusBarString(v317, 2u);
-						pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-						v318 =  &pParty->pPlayers[pCastSpell->uPlayerID_2];
-						pCastSpell->spellnum = 0;
-						v318->PlaySound(SPEECH_43, 0);
-					}
-					break;
-				}
-				v247 = (char *)&pItemsTable->pItems[v246].pIconName;
-				LODWORD(v725) = (int)v247;
-				v248 = v247[28];
-				if ( v248 && v248 != 1 && v248 != 2 )
-					v249 = v726->pInventoryItems[a2].GetValue() < 0x1C2;
-				else
-					v249 = v726->pInventoryItems[a2].GetValue() < 0xFA;
-				if ( v249 )
-				{
-					uRequiredMana = 1;
-					v730 = 0;
-				}
-				if ( rand() % 100 >= SHIDWORD(v733) )
-					uRequiredMana = 1;
-				if (uRequiredMana)
-				{
-					v316 = _this->uItemID;
-					if ( !(BYTE1(v316) & 2) )
-					{
-					LOBYTE(v316) = v316 | 2;
-					_this->uItemID = v316;
-					}
-					if ( LODWORD(v727) == 0 )
-					{
-						v317 = pGlobalTXT_LocalizationStrings[428];
-						if ( v730 == 0 )
-							v317 = pGlobalTXT_LocalizationStrings[585];
-						ShowStatusBarString(v317, 2u);
-						pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-						v318 =  &pParty->pPlayers[pCastSpell->uPlayerID_2];
-						pCastSpell->spellnum = 0;
-						v318->PlaySound(SPEECH_43, 0);
-					}
-					break;
-				}
-				v250 = v725;
-				v251 = *(char *)(LODWORD(v725) + 28);
-				if ( v251 == 0 | v251 == 1 | v251 == 2 | v251 == 3 | v251 == 4 | v251 == 5 | v251 == 6 | v251 == 7 | v251 == 8 | v251 == 9 | v251 == 10 | v251 == 11 )
-				{
-					if ( rand() % 100 < 80
-					&& !(*(char *)(LODWORD(v250) + 28) == 0 | *(char *)(LODWORD(v250) + 28) == 1 | *(char *)(LODWORD(v250) + 28) == 2) )
-					{
-					v252 = rand() % 10;//pItemsTable->field_116D8[pItemsTable->pItems[*(int *)v245].uEquipType];
-					*(int *)(v245 + 4) = 0;
-					for ( m = pItemsTable->pEnchantments[0].to_item[pItemsTable->pItems[*(int *)v245].uEquipType + 1];
-							;
-							m += pItemsTable->pEnchantments[*(int *)(v245 + 4)].to_item[pItemsTable->pItems[*(int *)v245].uEquipType
-																						+ 1] )
-					{
-						++*(int *)(v245 + 4);
-						if ( m >= v252 )
-						break;
-					}
-					v254 = rand();
-					v255 = 10;// pItemsTable->field_116D8[21];
-					v256 =  10;//pItemsTable->field_116D8[20];
-						*(int *)(v245 + 8) = v256 + v254 % (v255 - v256 + 1);
-						_this->uItemID |= 0x20u;
-
-						_50C9A8_item_enchantment_timer = 256;
-						LODWORD(v727) = 1;
-						break;
-					}
 					v257 = pItemsTable->pSpecialEnchantments_count;
 					v258 = 0;
 					v725 = 0.0;
-					HIDWORD(v733) = 0;
+					int _v733 = 0;
 					if ( pItemsTable->pSpecialEnchantments_count > 0 )
 					{
 						v730 = (int)&v679;
@@ -5272,22 +4379,22 @@
 								{
 									v261 = v730;
 									v730 += 4;
-									*(int *)v261 = HIDWORD(v733);
+									*(int *)v261 = _v733;
 								}
 							}
-							++HIDWORD(v733);
+							++_v733;
 							++v258;
 						}
-						while ( SHIDWORD(v733) < v257 );
+						while ( _v733 < v257 );
 					}
 					v262 = rand() % SLODWORD(v725);
 					v263 = v679;
-					*(int *)(v245 + 12) = v679;
-					v264 = pItemsTable->pSpecialEnchantments[v263].to_item_apply[pItemsTable->pItems[*(int *)v245].uEquipType + 4];
+					v245->uSpecEnchantmentType = v679[0];
+					v264 = pItemsTable->pSpecialEnchantments[*v263].to_item_apply[pItemsTable->pItems[*(int *)v245].uEquipType + 4];
 					v265 = v262 + 1;
 					if ( v264 < v265 )
 					{
-						for ( ii = &v679; ; ii = (int *)v732 )
+						for ( ii = v679; ; ii = (int *)v732 )
 						{
 							v267 = (int)(ii + 1);
 							v732 = v267;
@@ -5296,44 +4403,63 @@
 							v264 += pItemsTable->pSpecialEnchantments[v268].to_item_apply[pItemsTable->pItems[*(int *)v245].uEquipType
 																				+ 4];
 							if ( v264 >= v265 )
-							break;
+								break;
 						}
 					}
-					++*(int *)(v245 + 12);
-					_this->uItemID |= 0x20u;
-
-					_50C9A8_item_enchantment_timer = 256;
-					LODWORD(v727) = 1;
-					break;
+
+						v277 = pItemsTable->pSpecialEnchantments_count;
+						v278 = 0;
+						v725 = 0.0;
+						_v733 = 0;
+						if ( pItemsTable->pSpecialEnchantments_count > 0 )
+						{
+							int *_v730 = v679;
+							do
+							{
+								v279 = LOBYTE(pItemsTable->pSpecialEnchantments[v278].pBonusStatement);
+								if ( !v279 || v279 == 1 )
+								{
+									v280 = *(&pItemsTable->pSpecialEnchantments[v278].to_item_apply[pItemsTable->pItems[v245->uItemID].uEquipType]);
+									_v733 += v280;
+									if ( v280 )
+									{
+										v281 = _v730;
+										++_v730;
+										*v281 = _v733;
+									}
+								}
+								++_v733;
+								++v278;
+							}
+							while ( _v733 < v277 );
+						}
+						v282 = rand() % _v733;
+						v283 = v679;
+						v245->uSpecEnchantmentType = v679[0];
+						v284 = pItemsTable->pSpecialEnchantments[*v283].to_item_apply[pItemsTable->pItems[v245->uItemID].uEquipType ];
+						v285 = v282 + 1;
+						for ( l = v679; v284 < v285; ++l )
+						{
+							v245->uSpecEnchantmentType = *(l+1);
+							v284 += pItemsTable->pSpecialEnchantments[*(l+1)].to_item_apply[pItemsTable->pItems[v245->uItemID].uEquipType];
+						}
+						++v245->uSpecEnchantmentType;
+						v245->uAttributes |= 0x20u;
+						_50C9A8_item_enchantment_timer = 256;
+						LODWORD(v727) = 1;
+						break;
+					}
 				}
-			}
-			//v1 = 0;
-			if ( LODWORD(v727) == 0 )
-			{
-				v317 = pGlobalTXT_LocalizationStrings[428];
-				if ( v730 == 0 )
-					v317 = pGlobalTXT_LocalizationStrings[585];
-				ShowStatusBarString(v317, 2u);
-				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				v318 =  &pParty->pPlayers[pCastSpell->uPlayerID_2];
-				pCastSpell->spellnum = 0;
-				v318->PlaySound(SPEECH_43, 0);
-			}
-			break;
-		}
-		v289 = (ItemGen *)&v244[36 * a2 + 532];
-		_this = v289;
-		v290 = v289->uItemID;
-		LODWORD(v725) = (int)(char *)&pItemsTable + 48 * v290 + 4;
-		if ( v290 > 134
-			|| _this->uSpecEnchantmentType != 0
-			|| _this->uEnchantmentType != 0
-			|| _this->_bonus_strength != 0
-			|| (v291 = pItemsTable->pItems[v290].uEquipType) == 0
-			|| v291 == 1
-			|| v291 == 2
-			|| _this->Broken())
-		{
+				else
+				{
+					if ( !(BYTE1(v245->uAttributes) & 2) )
+					{
+						v245->uAttributes |= 2;
+					}
+				}
+						
+			}
+
 			if ( LODWORD(v727) == 0 )
 			{
 				v317 = pGlobalTXT_LocalizationStrings[428];
@@ -5345,650 +4471,545 @@
 				pCastSpell->spellnum = 0;
 				v318->PlaySound(SPEECH_43, 0);
 			}
+
+			break;
+		}
+		case SPELL_WATER_TOWN_PORTAL:
+		{
+			amount = 10 * v2;
+			if ( pPlayer->sMana < (signed int)uRequiredMana )
+				break;
+			if ( pParty->uFlags & (PARTY_FLAGS_1_ALERT_RED | PARTY_FLAGS_1_ALERT_YELLOW) && v731 != 4 || rand() % 100 >= amount && v731 != 4 )
+			{
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				pCastSpell->spellnum = 0;
+				continue;
+			}
+			town_portal_caster_id = LOBYTE(pCastSpell->uPlayerID);
+			pMessageQueue_50CBD0->AddMessage(UIMSG_OnCastTownPortal, 0, 0);
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_WATER_LLOYDS_BEACON:
+		{
+			LODWORD(v733) = 604800 * v2;
+			if ( !_strcmpi(pCurrentMapName, "d05.blv") )
+			{
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				pCastSpell->spellnum = 0;
+				continue;
+			}
+			v319 = uRequiredMana;
+			if ( pPlayer->sMana >= (signed int)uRequiredMana )
+			{
+				pEventTimer->Pause();
+				pMessageQueue_50CBD0->AddMessage(UIMSG_OnCastLloydsBeacon, 0, 0);
+				qword_506350 = (signed int)v733;
+				_506348_current_lloyd_playerid = pCastSpell->uPlayerID;
+				::uRequiredMana = v319;
+				::sRecoveryTime = sRecoveryTime;
+				dword_50633C = pCastSpell->sound_id;
+				dword_506338 = pCastSpell->spellnum;
+				LOBYTE(pCastSpell->field_8) |= 0x20u;
+			}
 			break;
 		}
-		if ( _this->GetValue() < 0x1C2 )
-			uRequiredMana = 1;
-		if ( rand() % 100 >= SHIDWORD(v733) )
-			uRequiredMana = 1;
-		if ( uRequiredMana != 0 )
-		{
-			dword_50C9D0 = 113;
-			dword_50C9D4 = 0;
-			dword_50C9D8 = 1;
-
-			ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
-			pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-			pCastSpell->spellnum = 0;
-			continue;
-		}
-		v292 = *(char *)(LODWORD(v725) + 28);
-		if ( !(v292 == 3 | v292 == 4 | v292 == 5 | v292 == 6 | v292 == 7 | v292 == 8 | v292 == 9 | v292 == 10 | v292 == 11) )
-		{
-			v2 = v723;
-			//v1 = 0;
-
-			dword_50C9D0 = 113;
-			dword_50C9D4 = 0;
-			dword_50C9D8 = 1;
-
-			ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
-			pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-			pCastSpell->spellnum = 0;
-			continue;
-		}
-		if ( rand() % 100 >= 80 )
+		case SPELL_EARTH_STONE_TO_FLESH:
 		{
-			v297 = pItemsTable->pSpecialEnchantments_count;
-			v294 = _this;
-			v298 = 0;
-			v725 = 0.0;
-			HIDWORD(v733) = 0;
-			if ( pItemsTable->pSpecialEnchantments_count > 0 )
-			{
-			v730 = (int)&v679;
-			do
-			{
-				v299 = LOBYTE(pItemsTable->pSpecialEnchantments[v298 + 1].pBonusStatement);
-				if ( !v299 || v299 == 1 )
-				{
-				v300 = *(&pItemsTable->pSpecialEnchantments[0].to_item_apply[pItemsTable->pItems[v294->uItemID].uEquipType + 4]
-						+ v298 * 28);
-				LODWORD(v725) += v300;
-				if ( v300 )
-				{
-					v301 = v730;
-					v730 += 4;
-					*(int *)v301 = HIDWORD(v733);
-				}
-				}
-				++HIDWORD(v733);
-				++v298;
-			}
-			while ( SHIDWORD(v733) < v297 );
-			}
-			v302 = rand() % SLODWORD(v725);
-			v303 = v679;
-			v294->uSpecEnchantmentType = v679;
-			v304 = pItemsTable->pSpecialEnchantments[v303].to_item_apply[pItemsTable->pItems[v294->uItemID].uEquipType + 4];
-			v305 = v302 + 1;
-			if ( v304 < v305 )
-			{
-			for ( jj = &v679; ; jj = (int *)v732 )
-			{
-				v307 = (int)(jj + 1);
-				v732 = v307;
-				v308 = *(int *)v307;
-				v294->uSpecEnchantmentType = v308;
-				v304 += pItemsTable->pSpecialEnchantments[v308].to_item_apply[pItemsTable->pItems[v294->uItemID].uEquipType + 4];
-				if ( v304 >= v305 )
+			__debugbreak(); // missing GM ?
+			switch (v731)
+			{
+				case 1: amount = 3600 * v2; break;
+				case 2: amount = 3600 * v2; break;
+				case 3: amount = 86400 * v2; break;
+				case 4: break;
+				default:
+				assert(false);
+			}
+	//LABEL_634:
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
-			}
-			}
-			++v294->uSpecEnchantmentType;
+			v323 = pCastSpell->uPlayerID_2;
+			v324 = (char *)&pParty->pPlayers[v323].pConditions[15];
+			if ( !pParty->pPlayers[v323].pConditions[15] )
+			{
+				LODWORD(v727) = 1;
+				break;
+			}
+			if ( v731 == 4 )
+			{
+				*(int *)v324 = 0;
+				*((int *)v324 + 1) = 0;
+				LODWORD(v727) = 1;
+				break;
+			}
+			v732 = amount << 7;
+			v663 = (signed __int64)((double)(signed __int64)pParty->uTimePlayed - (double)(amount << 7) * 0.033333335);
+			v656 = 15;
+			v325 = &pParty->pPlayers[v323];
+			v325->DiscardConditionIfLastsLongerThan(v656, v663);
+			LODWORD(v727) = 1;
+			break;
 		}
-		else
-		{
-			v293 = rand();
-			v294 = _this;
-			v295 = v293 % 10;// pItemsTable->field_116D8[pItemsTable->pItems[_this->uItemID].uEquipType];
-			_this->uEnchantmentType = 0;
-			for ( kk = pItemsTable->pEnchantments[0].to_item[pItemsTable->pItems[v294->uItemID].uEquipType + 1];
-				;
-				kk += pItemsTable->pEnchantments[v294->uEnchantmentType].to_item[pItemsTable->pItems[v294->uItemID].uEquipType
-																			+ 1] )
-			{
-			++v294->uEnchantmentType;
-			if ( kk >= v295 )
-				break;
-			}
-			v294->_bonus_strength = 10//pItemsTable->field_116D8[18]
-								+ rand() % 10;//(pItemsTable->field_116D8[19] - pItemsTable->field_116D8[18] + 1);
-		}
-		v294->uAttributes |= 0x20u;
-		_50C9A8_item_enchantment_timer = 256;
-		LODWORD(v727) = 1;
-		break;
-		}
-		case SPELL_WATER_TOWN_PORTAL:
-			{
-		amount = 10 * v2;
-		if ( pPlayer->sMana < (signed int)uRequiredMana )
-			break;
-		if ( pParty->uFlags & (PARTY_FLAGS_1_ALERT_RED | PARTY_FLAGS_1_ALERT_YELLOW) && v731 != 4 || rand() % 100 >= amount && v731 != 4 )
+		case SPELL_EARTH_ROCK_BLAST:
 		{
-			ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
-			pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-			pCastSpell->spellnum = 0;
-			continue;
-		}
-		town_portal_caster_id = LOBYTE(pCastSpell->uPlayerID);
-		pMessageQueue_50CBD0->AddMessage(UIMSG_OnCastTownPortal, 0, 0);
-		LODWORD(v727) = 1;
-		break;
-			}
-		case SPELL_WATER_LLOYDS_BEACON:
-			{
-		LODWORD(v733) = 604800 * v2;
-		if ( !_strcmpi(pCurrentMapName, "d05.blv") )
-		{
-			ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
-			pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-			pCastSpell->spellnum = 0;
-			continue;
-		}
-		v319 = uRequiredMana;
-		if ( pPlayer->sMana >= (signed int)uRequiredMana )
-		{
-			pEventTimer->Pause();
-			pMessageQueue_50CBD0->AddMessage(UIMSG_OnCastLloydsBeacon, 0, 0);
-			qword_506350 = (signed int)v733;
-			_506348_current_lloyd_playerid = pCastSpell->uPlayerID;
-			::uRequiredMana = v319;
-			::sRecoveryTime = sRecoveryTime;
-			dword_50633C = pCastSpell->sound_id;
-			dword_506338 = pCastSpell->spellnum;
-			LOBYTE(pCastSpell->field_8) |= 0x20u;
-		}
-		break;
-			}
-		case SPELL_EARTH_STONE_TO_FLESH:
-			{
-		__debugbreak(); // missing GM ?
-		if ( v731 == 1 || v731 == 2)
-			amount = 3600 * v2;
-		if ( v731 == 3 )
-			amount = 86400 * v2;
-//LABEL_634:
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			break;
-		v323 = pCastSpell->uPlayerID_2;
-		v324 = (char *)&pParty->pPlayers[v323].pConditions[15];
-		if ( !pParty->pPlayers[v323].pConditions[15] )
-		{
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			pSpellSprite.stru_24.Reset();
+			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_level = v2;
+			pSpellSprite.spell_skill = v731;
+			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+			pSpellSprite.vPosition.y = pParty->vPosition.y;
+			pSpellSprite.vPosition.x = pParty->vPosition.x;
+			pSpellSprite.uAttributes = 0;
+			pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
+			pSpellSprite.uSectorID = pIndoor->GetSector(
+								pParty->vPosition.x,
+								pParty->vPosition.y,
+								pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3);
+			pSpellSprite.uSpriteFrameID = 0;
+			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+			pSpellSprite.spell_target_pid = a2;
+			pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
+			pSpellSprite.uFacing = LOWORD(pParty->sRotationY);
+			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+			if ( pParty->bTurnBasedModeOn == 1 )
+				LOBYTE(pSpellSprite.uAttributes) |= 4u;
+
+			v659 = pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed;
+			if ( pSpellSprite.Create(pParty->sRotationY, pParty->sRotationX, v659, pCastSpell->uPlayerID + 1) != -1 && pParty->bTurnBasedModeOn == 1 )
+				++pTurnEngine->field_1C;
 			LODWORD(v727) = 1;
 			break;
 		}
-		if ( v731 == 4 )
+		case SPELL_EARTH_DEATH_BLOSSOM:
 		{
-			*(int *)v324 = 0;
-			*((int *)v324 + 1) = 0;
+			if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
+			{
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				pCastSpell->spellnum = 0;
+				continue;
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			pSpellSprite.uType = 4090;
+			pSpellSprite.stru_24.Reset();
+			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_level = v2;
+			pSpellSprite.spell_skill = v731;
+			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+			pSpellSprite.vPosition.x = pParty->vPosition.x;
+			pSpellSprite.vPosition.y = pParty->vPosition.y;
+			pSpellSprite.uAttributes = 0;
+			pSpellSprite.uSectorID = 0;
+			pSpellSprite.uSpriteFrameID = 0;
+			pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
+			pSpellSprite.field_60_distance_related_prolly_lod = 0;
+			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+			pSpellSprite.spell_target_pid = a2;
+			pSpellSprite.uFacing = LOWORD(pParty->sRotationY);
+			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+			if ( pParty->bTurnBasedModeOn == 1 )
+				pSpellSprite.uAttributes = 4;
+
+			v659 = pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed;
+			if ( pSpellSprite.Create(pParty->sRotationY, stru_5C6E00->uIntegerHalfPi / 2, v659, 0) != -1 && pParty->bTurnBasedModeOn == 1 )
+				++pTurnEngine->field_1C;
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_SPIRIT_DETECT_LIFE:
+		{
+			v328 = v731 - 2;
+			if ( v328 )
+			{
+				v329 = v328 - 1;
+				if ( v329 && v329 != 1 )
+					v330 = 600 * v2;
+				else
+					v330 = 3600 * v2;
+			}
+			else
+			{
+				v330 = 1800 * v2;
+			}
+			LODWORD(v733) = v330;
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
+
+			pParty->pPartyBuffs[PARTY_BUFF_DETECT_LIFE].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, 0, 0, 0);
 			LODWORD(v727) = 1;
 			break;
 		}
-		v732 = amount << 7;
-		v663 = (signed __int64)((double)(signed __int64)pParty->uTimePlayed - (double)(amount << 7) * 0.033333335);
-		v656 = 15;
-		v325 = &pParty->pPlayers[v323];
-		v325->DiscardConditionIfLastsLongerThan(v656, v663);
-		LODWORD(v727) = 1;
-		break;
-		}
-		case SPELL_EARTH_ROCK_BLAST:
-			{
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			break;
-		pSpellSprite.stru_24.Reset();
-		pSpellSprite.spell_id = pCastSpell->spellnum;
-		pSpellSprite.spell_level = v2;
-		pSpellSprite.spell_skill = v731;
-		pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-		pSpellSprite.vPosition.y = pParty->vPosition.y;
-		pSpellSprite.vPosition.x = pParty->vPosition.x;
-		pSpellSprite.uAttributes = 0;
-		pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
-		pSpellSprite.uSectorID = pIndoor->GetSector(
-							pParty->vPosition.x,
-							pParty->vPosition.y,
-							pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3);
-		pSpellSprite.uSpriteFrameID = 0;
-		pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-		pSpellSprite.spell_target_pid = a2;
-		pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
-		pSpellSprite.uFacing = LOWORD(pParty->sRotationY);
-		pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-		if ( pParty->bTurnBasedModeOn == 1 )
-			LOBYTE(pSpellSprite.uAttributes) |= 4u;
-
-		v659 = pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed;
-			if ( pSpellSprite.Create(pParty->sRotationY, pParty->sRotationX, v659, pCastSpell->uPlayerID + 1) != -1 && pParty->bTurnBasedModeOn == 1 )
-			++pTurnEngine->field_1C;
-		LODWORD(v727) = 1;
-		break;
-			}
-		case SPELL_EARTH_DEATH_BLOSSOM:
-			{
-		if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
+		case SPELL_SPIRIT_FATE:
 		{
-			ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
-			pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-			pCastSpell->spellnum = 0;
-			continue;
-		}
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
+			switch (v731)
+			{
+				case 1: amount = 1 * v2; break;
+				case 2: amount = 2 * v2; break;
+				case 3: amount = 4 * v2; break;
+				case 4: amount = 6 * v2; break;
+				default:
+				assert(false);
+			}
+			LODWORD(v733) = 300;
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			v342 = pCastSpell->spell_target_pid;
+			if ( v342 == 0 )
+			{
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+
+				pParty->pPlayers[pCastSpell->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_FATE].Apply(pParty->uTimePlayed + 1280, v731, amount, 0, 0);
+				LODWORD(v727) = 1;
+				break;
+			}
+			if (PID_TYPE(v342) == OBJECT_Actor)
+			{
+				v343 = PID_ID(v342);
+				HIDWORD(v344) = 0 + ((pParty->uTimePlayed + 1280) >> 32);
+				LODWORD(v344) = LODWORD(pParty->uTimePlayed) + 1280;
+				pActors[v343].pActorBuffs[11].Apply(v344, v731, amount, 0, 0);
+				BYTE2(pActors[v343].uAttributes) |= 8u;
+				//v672 = 0;
+				v661 = &pActors[v343];
+				pGame->GetStru6()->_4A7E89_sparkles_on_actor_after_it_casts_buff(v661, 0);
+			}
+			LODWORD(v727) = 1;
 			break;
-		pSpellSprite.uType = 4090;
-		pSpellSprite.stru_24.Reset();
-		pSpellSprite.spell_id = pCastSpell->spellnum;
-		pSpellSprite.spell_level = v2;
-		pSpellSprite.spell_skill = v731;
-		pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-		pSpellSprite.vPosition.x = pParty->vPosition.x;
-		pSpellSprite.vPosition.y = pParty->vPosition.y;
-		pSpellSprite.uAttributes = 0;
-		pSpellSprite.uSectorID = 0;
-		pSpellSprite.uSpriteFrameID = 0;
-		pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
-		pSpellSprite.field_60_distance_related_prolly_lod = 0;
-		pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-		pSpellSprite.spell_target_pid = a2;
-		pSpellSprite.uFacing = LOWORD(pParty->sRotationY);
-		pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-		if ( pParty->bTurnBasedModeOn == 1 )
-			pSpellSprite.uAttributes = 4;
-
-		v659 = pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed;
-			if ( pSpellSprite.Create(pParty->sRotationY, stru_5C6E00->uIntegerHalfPi / 2, v659, 0) != -1 && pParty->bTurnBasedModeOn == 1 )
-			++pTurnEngine->field_1C;
-		LODWORD(v727) = 1;
-		break;
-			}
-		case SPELL_SPIRIT_DETECT_LIFE:
-			{
-		v328 = v731 - 2;
-		if ( v328 )
+		}
+		case SPELL_SPIRIT_REMOVE_CURSE:
 		{
-			v329 = v328 - 1;
-			if ( v329 && v329 != 1 )
-			v330 = 600 * v2;
+			switch (v731)
+			{
+				case 1: amount = 3600 * v2; break;
+				case 2: amount = 3600 * v2; break;
+				case 3: amount = 86400 * v2; break;
+				case 4: amount = 0; break;
+				default:
+				assert(false);
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			v351 = &pParty->pPlayers[pCastSpell->uPlayerID_2];
+			if ( !v351->pConditions[0] )
+			{
+				LODWORD(v727) = 1;
+				break;
+			}
+			if ( v731 == 4 )
+			{
+				LODWORD(v351->pConditions[0]) = 0;
+				HIDWORD(v351->pConditions[0]) = 0;
+			}
 			else
-			v330 = 3600 * v2;
-		}
-		else
-		{
-			v330 = 1800 * v2;
-		}
-		LODWORD(v733) = v330;
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			break;
-		pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
-		pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
-		pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
-		pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
-
-			pParty->pPartyBuffs[PARTY_BUFF_DETECT_LIFE].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, 0, 0, 0);
-		LODWORD(v727) = 1;
-		break;
-			}
-		case SPELL_SPIRIT_FATE:
-			{
-		LODWORD(v733) = 300;
-		if ( v731 == 1 )
-			amount = v2;
-		else if( v731 == 2 )
-			amount = 2 * v2;
-		else if( v731 == 3 )
-			amount = 4 * v2;
-		else if( v731 == 4)
-			amount = 6 * v2;
-//LABEL_667:
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			break;
-		v342 = pCastSpell->spell_target_pid;
-		if ( v342 == 0 )
-		{
+			{
+				v732 = amount << 7;
+				v351->DiscardConditionIfLastsLongerThan(0, (signed __int64)((double)(signed __int64)pParty->uTimePlayed - (double)(amount << 7) * 0.033333335));
+				if ( HIDWORD(pParty->pPlayers[pCastSpell->uPlayerID_2].pConditions[0]) | LODWORD(pParty->pPlayers[pCastSpell->uPlayerID_2].pConditions[0]) )
+				{
+					LODWORD(v727) = 1;
+					break;
+				}
+			}
 			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
-
-			pParty->pPlayers[pCastSpell->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_FATE].Apply(pParty->uTimePlayed + 1280, v731, amount, 0, 0);
 			LODWORD(v727) = 1;
 			break;
 		}
-		if (PID_TYPE(v342) == OBJECT_Actor)
+		case SPELL_SPIRIT_PRESERVATION:
 		{
-			v343 = PID_ID(v342);
-			HIDWORD(v344) = 0 + ((pParty->uTimePlayed + 1280) >> 32);
-			LODWORD(v344) = LODWORD(pParty->uTimePlayed) + 1280;
-			pActors[v343].pActorBuffs[11].Apply(v344, v731, amount, 0, 0);
-			BYTE2(pActors[v343].uAttributes) |= 8u;
-			v672 = 0;
-			v661 = &pActors[v343];
-//LABEL_165:
-			pGame->GetStru6()->_4A7E89_sparkles_on_actor_after_it_casts_buff(v661, v672);
-		}
-		LODWORD(v727) = 1;
-		break;
-			}
-		case SPELL_SPIRIT_REMOVE_CURSE:
-			{
-		if ( v731 == 1 || v731 == 2 )
-			amount = 3600 * v2;
-		else if( v731 == 3)
-			amount = 86400 * v2;
-		else if ( v731 == 4 )
-			amount = 0;
-//LABEL_679:
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			break;
-		v351 = &pParty->pPlayers[pCastSpell->uPlayerID_2];
-		if ( !v351->pConditions[0] )
-		{
-		LODWORD(v727) = 1;
-		break;
-		}
-		if ( v731 == 4 )
-		{
-			LODWORD(v351->pConditions[0]) = 0;
-			HIDWORD(v351->pConditions[0]) = 0;
-		}
-		else
-		{
-			v732 = amount << 7;
-			v351->DiscardConditionIfLastsLongerThan(0, (signed __int64)((double)(signed __int64)pParty->uTimePlayed - (double)(amount << 7) * 0.033333335));
-			if ( HIDWORD(pParty->pPlayers[pCastSpell->uPlayerID_2].pConditions[0]) | LODWORD(pParty->pPlayers[pCastSpell->uPlayerID_2].pConditions[0]) )
-			{
+			if ( v731 == 4 )
+				LODWORD(v733) = 900 * (v2 + 4);
+			else
+				LODWORD(v733) = 300 * (v2 + 12);
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			if ( v731 == 1 || v731 == 2 )
+			{
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+				pParty->pPlayers[pCastSpell->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_PRESERVATION].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, 0, 0, 0);
+				LODWORD(v727) = 1;
+				break;
+			}
+			a2 = 0;
+			v717 = (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
+			v357 = pParty->pPlayers;//[0].pPlayerBuffs[11];
+			do
+			{
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, a2);
+				v357->pPlayerBuffs[PLAYER_BUFF_PRESERVATION].Apply(pParty->uTimePlayed + v717, v731, 0, 0, 0);
+				++a2;
+				++v357;// = (SpellBuff *)((char *)v357 + 6972);
+			}
+			while ( v357 <= &pParty->pPlayers[3] );
 			LODWORD(v727) = 1;
 			break;
-			}
 		}
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
-		LODWORD(v727) = 1;
-		break;
-			}
-		case SPELL_SPIRIT_PRESERVATION:
-			{
-		v354 = v731 - 2;
-		if ( v354 && (v355 = v354 - 1) != 0 && v355 == 1 )
-			v356 = 900 * (v2 + 4);
-		else
-			v356 = 300 * (v2 + 12);
-		LODWORD(v733) = v356;
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			break;
-		if ( v731 == 1 || v731 == 2 )
-		{
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
-
-			pParty->pPlayers[pCastSpell->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_PRESERVATION].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, 0, 0, 0);
-		LODWORD(v727) = 1;
-		break;
-		}
-		a2 = 0;
-		v717 = (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
-		v357 = pParty->pPlayers;//[0].pPlayerBuffs[11];
-		do
-		{
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, a2);
-			v357->pPlayerBuffs[PLAYER_BUFF_PRESERVATION].Apply(pParty->uTimePlayed + v717, v731, 0, 0, 0);
-			++a2;
-			++v357;// = (SpellBuff *)((char *)v357 + 6972);
-		}
-		while ( v357 <= &pParty->pPlayers[3] );
-		LODWORD(v727) = 1;
-		break;
-			}
 		case SPELL_SPIRIT_TURN_UNDEAD:
 		{
-		v364 = v731 - 2;
-		if ( !v364 || (v365 = v364 - 1) != 0 && v365 != 1 )
-			v366 = 60 * (v2 + 3);
-		else
-			v366 = 300 * v2 + 180;
-		LODWORD(v733) = v366;
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
+			if ( v731 == 1 || v731 == 2)
+				LODWORD(v733) = 60 * (v2 + 3);
+			else
+				LODWORD(v733) = 300 * v2 + 180;
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			auto _v726 = sub_46A6AC((int)dword_50BF30, 100, 4096);
+			pGame->GetStru6()->FadeScreen__like_Turn_Undead_and_mb_Armageddon(0xFFFFFFu, 0xC0u);
+			++pSpellSprite.uType;
+			pSpellSprite.stru_24.Reset();
+			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_level = v2;
+			pSpellSprite.spell_skill = v731;
+			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+			pSpellSprite.uAttributes = 0;
+			pSpellSprite.uSectorID = 0;
+			pSpellSprite.uSpriteFrameID = 0;
+			pSpellSprite.field_60_distance_related_prolly_lod = 0;
+			pSpellSprite.uFacing = 0;
+			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+			for ( a2 = 0; a2 < (signed int)_v726; ++a2 )
+			{
+				v369 = &pActors[dword_50BF30[a2]];
+				if ( MonsterStats::BelongsToSupertype(v369->pMonsterInfo.uID, MONSTER_SUPERTYPE_UNDEAD) )
+				{
+					pSpellSprite.vPosition.x = v369->vPosition.x;
+					pSpellSprite.vPosition.y = v369->vPosition.y;
+					pSpellSprite.vPosition.z = v369->vPosition.z - (unsigned int)(signed __int64)((double)v369->uActorHeight * unk_4D8548);
+
+					pSpellSprite.spell_target_pid = PID(OBJECT_Actor, dword_50BF30[a2]);
+					pSpellSprite.Create(0, 0, 0, 0);
+					v369->pActorBuffs[4].Apply(
+						pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335),
+						v731, 0, 0, 0);
+				}
+			}
+			LODWORD(v727) = 1;
 			break;
-		auto _v726 = sub_46A6AC((int)dword_50BF30, 100, 4096);
-		pGame->GetStru6()->FadeScreen__like_Turn_Undead_and_mb_Armageddon(0xFFFFFFu, 0xC0u);
-		++pSpellSprite.uType;
-		pSpellSprite.stru_24.Reset();
-		pSpellSprite.spell_id = pCastSpell->spellnum;
-		pSpellSprite.spell_level = v2;
-		pSpellSprite.spell_skill = v731;
-		pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-		pSpellSprite.uAttributes = 0;
-		pSpellSprite.uSectorID = 0;
-		pSpellSprite.uSpriteFrameID = 0;
-		pSpellSprite.field_60_distance_related_prolly_lod = 0;
-		pSpellSprite.uFacing = 0;
-		pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-		pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-		for ( a2 = 0; a2 < (signed int)_v726; ++a2 )
-		{
-			v369 = &pActors[dword_50BF30[a2]];
-			if ( MonsterStats::BelongsToSupertype(v369->pMonsterInfo.uID, MONSTER_SUPERTYPE_UNDEAD) )
-			{
-			pSpellSprite.vPosition.x = v369->vPosition.x;
-			pSpellSprite.vPosition.y = v369->vPosition.y;
-			pSpellSprite.vPosition.z = v369->vPosition.z - (unsigned int)(signed __int64)((double)v369->uActorHeight * unk_4D8548);
-
-			pSpellSprite.spell_target_pid = PID(OBJECT_Actor, dword_50BF30[a2]);
-			pSpellSprite.Create(0, 0, 0, 0);
-			v369->pActorBuffs[4].Apply(
-				pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335),
-				v731, 0, 0, 0);
-			}
-		}
-		LODWORD(v727) = 1;
-		}
-		break;
-
-		case SPELL_SPIRIT_RAISE_DEAD:
-			{
-		v371 = v731 - 2;
-		if ( v371 && (v372 = v371 - 1) != 0 && v372 == 1 )
-			amount = 0;
-		else
-			amount = 86400 * v2;
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			break;
-		pOtherOverlayList->_4418B1(5080, pCastSpell->uPlayerID_2 + 100, 0, 65536);
-		v373 = pCastSpell->uPlayerID_2;
-		if ( !(HIDWORD(pParty->pPlayers[v373].pConditions[14]) | LODWORD(pParty->pPlayers[v373].pConditions[14])) )
-		{
-		LODWORD(v727) = 1;
-		break;
-		}
-		v14 = v731 == 4;
-		pParty->pPlayers[v373].sHealth = 1;
-		if ( v14 )
-		{
-			v374 = pCastSpell->uPlayerID_2;
-			LODWORD(pParty->pPlayers[v374].pConditions[14]) = 0;
-			HIDWORD(pParty->pPlayers[v374].pConditions[14]) = 0;
-			v376 = pCastSpell->uPlayerID_2;
-			LODWORD(pParty->pPlayers[v376].pConditions[13]) = 0;
-			HIDWORD(pParty->pPlayers[v376].pConditions[13]) = 0;
-		}
-		else
-		{
-			*(float *)&a2 = (double)(amount << 7) * 0.033333335;
-			pParty->pPlayers[pCastSpell->uPlayerID_2].DiscardConditionIfLastsLongerThan(
-			0xEu,
-			(signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2));
-			pParty->pPlayers[pCastSpell->uPlayerID_2].DiscardConditionIfLastsLongerThan(
-			0xDu,
-			(signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2));
 		}
-		v377 = &pParty->pPlayers[pCastSpell->uPlayerID_2];
-		v377->SetCondition(1, 0);
-		LODWORD(v727) = 1;
-		break;
-			}
-		case SPELL_SPIRIT_SHARED_LIFE:
-			{
-		v378 = v731 - 2;
-		if ( v378 && (v379 = v378 - 1) != 0 && v379 == 1 )
-			v380 = 4 * v2;
-		else
-			v380 = 3 * v2;
-		amount = v380;
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			break;
-		v381 = 0;
-		HIDWORD(v733) = amount;
-		v730 = 0;
-		v382 = 1;
-		do
-		{
-			v383 = pPlayers[v382];
-			if ( !v383->pConditions[14] && !v383->pConditions[15] && !v383->pConditions[16] )
-			v682[v381++] = v382;
-			++v382;
-		}
-		while ( v382 <= 4 );
-		v384 = 0;
-		v730 = v381;
-		if ( v381 > 0 )
-		{
-			do
-			HIDWORD(v733) += pPlayers[v682[v384++]]->sHealth;
-			while ( v384 < v381 );
-		}
-		v732 = (signed __int64)((double)SHIDWORD(v733) / (double)v730);
-		HIDWORD(v733) = 0;
-		if ( v381 > 0 )
+		case SPELL_SPIRIT_RAISE_DEAD:
 		{
-			do
-			{
-			//v385 = (ItemGen **)&pPlayers[v682[HIDWORD(v733)]];
-			v726 = pPlayers[v682[HIDWORD(v733)]];
-			v726->sHealth = v732;
-			//v386 = v726->GetMaxHealth();
-			if ( v726->sHealth > v726->GetMaxHealth())
-				v726->sHealth = v726->GetMaxHealth();
-			if ( v726->sHealth > 0 )
-			{
-				v726->pConditions[Player::Condition_Unconcious] = 0;
-			}
-			v388 = HIDWORD(v733);
-
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, LOWORD(v682[HIDWORD(v733)]) - 1);
-			HIDWORD(v733) = v388 + 1;
-			}
-			while ( v388 + 1 < v730 );
-		}
-		LODWORD(v727) = 1;
-		break;
-			}
-		case SPELL_SPIRIT_RESSURECTION:
-			{
-		v392 = v731 - 1;
-		if ( v731 == 1 )
-			amount = 180 * v2;
-		else if ( v731 == 2 )
-			amount = 10800 * v2;
-		else if ( v731 == 3 )
-			amount = 259200 * v2;
-		else if ( v731 == 4 )
-			amount = 0;
-//LABEL_751:
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			break;
-		v396 = pCastSpell->uPlayerID_2;
-		if ( HIDWORD(pParty->pPlayers[v396].pConditions[16]) | LODWORD(pParty->pPlayers[v396].pConditions[16])
-			|| HIDWORD(pParty->pPlayers[v396].pConditions[14]) | LODWORD(pParty->pPlayers[v396].pConditions[14]) )
-		{
-			if ( !(HIDWORD(pParty->pPlayers[v396].pConditions[1]) | LODWORD(pParty->pPlayers[v396].pConditions[1])) )
-			pParty->pPlayers[v396].PlaySound(SPEECH_25, 0);
 			if ( v731 == 4 )
-			{
-			v397 = pCastSpell->uPlayerID_2;
-			LODWORD(pParty->pPlayers[v397].pConditions[16]) = 0;
-			HIDWORD(pParty->pPlayers[v397].pConditions[16]) = 0;
-			v398 = pCastSpell->uPlayerID_2;
-			LODWORD(pParty->pPlayers[v398].pConditions[14]) = 0;
-			HIDWORD(pParty->pPlayers[v398].pConditions[14]) = 0;
-			v399 = pCastSpell->uPlayerID_2;
-			LODWORD(pParty->pPlayers[v399].pConditions[13]) = 0;
-			HIDWORD(pParty->pPlayers[v399].pConditions[13]) = 0;
+				amount = 0;
+			else
+				amount = 86400 * v2;
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			pOtherOverlayList->_4418B1(5080, pCastSpell->uPlayerID_2 + 100, 0, 65536);
+			v373 = pCastSpell->uPlayerID_2;
+			if ( !(HIDWORD(pParty->pPlayers[v373].pConditions[14]) | LODWORD(pParty->pPlayers[v373].pConditions[14])) )
+			{
+				LODWORD(v727) = 1;
+				break;
+			}
+			v14 = v731 == 4;
+			pParty->pPlayers[v373].sHealth = 1;
+			if ( v14 )
+			{
+				v374 = pCastSpell->uPlayerID_2;
+				LODWORD(pParty->pPlayers[v374].pConditions[14]) = 0;
+				HIDWORD(pParty->pPlayers[v374].pConditions[14]) = 0;
+				v376 = pCastSpell->uPlayerID_2;
+				LODWORD(pParty->pPlayers[v376].pConditions[13]) = 0;
+				HIDWORD(pParty->pPlayers[v376].pConditions[13]) = 0;
 			}
 			else
 			{
-			*(float *)&a2 = (double)(amount << 7) * 0.033333335;
-			pParty->pPlayers[pCastSpell->uPlayerID_2].DiscardConditionIfLastsLongerThan( 0x10u,
-				(signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2));
-			pParty->pPlayers[pCastSpell->uPlayerID_2].DiscardConditionIfLastsLongerThan( 0xEu,
-				(signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2));
-			pParty->pPlayers[pCastSpell->uPlayerID_2].DiscardConditionIfLastsLongerThan( 0xDu,
+				*(float *)&a2 = (double)(amount << 7) * 0.033333335;
+				pParty->pPlayers[pCastSpell->uPlayerID_2].DiscardConditionIfLastsLongerThan(
+				0xEu,
 				(signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2));
-			}
-			pParty->pPlayers[pCastSpell->uPlayerID_2].SetCondition(1u, 1);
-
-			pParty->pPlayers[pCastSpell->uPlayerID_2].sHealth = 1;
-
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
-		}
-		LODWORD(v727) = 1;
-		break;
-			}
-		case SPELL_MIND_CURE_PARALYSIS:
-			{
-		if ( v731 == 1 || v731 == 2 )
-			amount = 3600 * v2;
-		else if ( v731 == 4 )
-			amount = 0;
-		else if( v731 == 3 )
-			amount = 86400 * v2;
-//LABEL_768:
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			break;
-
-		pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
-		v323 = pCastSpell->uPlayerID_2;
-		v324 = (char *)&pParty->pPlayers[v323].pConditions[12];
-		if ( !pParty->pPlayers[v323].pConditions[12] )
-		{
-		LODWORD(v727) = 1;
-		break;
-		}
-		if ( v731 == 4 )
-		{
-			*(int *)v324 = 0;
-			*((int *)v324 + 1) = 0;
+				pParty->pPlayers[pCastSpell->uPlayerID_2].DiscardConditionIfLastsLongerThan(
+				0xDu,
+				(signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2));
+			}
+			v377 = &pParty->pPlayers[pCastSpell->uPlayerID_2];
+			v377->SetCondition(1, 0);
 			LODWORD(v727) = 1;
 			break;
 		}
-		v663 = (signed __int64)((double)(signed __int64)pParty->uTimePlayed - (double)(amount << 7) * 0.033333335);
-		v656 = 12;
-		v325 = &pParty->pPlayers[v323];
-		v325->DiscardConditionIfLastsLongerThan(v656, v663);
-		LODWORD(v727) = 1;
-		break;
-			}
-		case SPELL_MIND_REMOVE_FEAR:
+		case SPELL_SPIRIT_SHARED_LIFE:
 		{
-			if( v731 == 1)
-				amount = 180 * v2;
-			else if( v731 == 2 )
-				amount = 3600 * v2;
-			else if( v731 == 3)
-				amount = 86400 * v2;
-			else if( v731 == 4 )
-				amount = 0;
-//LABEL_780:
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			break;
-
-		pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
-		v323 = pCastSpell->uPlayerID_2;
-		v324 = (char *)&pParty->pPlayers[v323].pConditions[3];
-		if ( !pParty->pPlayers[v323].pConditions[3] )
-		{
-		LODWORD(v727) = 1;
-		break;
-		}
-		if ( v731 == 4 )
-		{
-			*(int *)v324 = 0;
-			*((int *)v324 + 1) = 0;
+			if ( v731 == 4 )
+				amount = 4 * v2;
+			else
+				amount = 3 * v2;
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			v381 = 0;
+			signed int _v733 = amount;
+			v730 = 0;
+			v382 = 1;
+			do
+			{
+				v383 = pPlayers[v382];
+				if ( !v383->pConditions[14] && !v383->pConditions[15] && !v383->pConditions[16] )
+				v682[v381++] = v382;
+				++v382;
+			}
+			while ( v382 <= 4 );
+			v384 = 0;
+			v730 = v381;
+			if ( v381 > 0 )
+			{
+				do
+					_v733 += pPlayers[v682[v384++]]->sHealth;
+				while ( v384 < v381 );
+			}
+			v732 = (signed __int64)((double)_v733 / (double)v730);
+			_v733 = 0;
+			if ( v381 > 0 )
+			{
+				do
+				{
+					//v385 = (ItemGen **)&pPlayers[v682[HIDWORD(v733)]];
+					v726 = pPlayers[v682[_v733]];
+					v726->sHealth = v732;
+					//v386 = v726->GetMaxHealth();
+					if ( v726->sHealth > v726->GetMaxHealth())
+						v726->sHealth = v726->GetMaxHealth();
+					if ( v726->sHealth > 0 )
+					{
+						v726->pConditions[Player::Condition_Unconcious] = 0;
+					}
+					v388 = _v733;
+
+					pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, LOWORD(v682[_v733]) - 1);
+					_v733 = v388 + 1;
+				}
+				while ( v388 + 1 < v730 );
+			}
 			LODWORD(v727) = 1;
 			break;
 		}
-		v663 = (signed __int64)((double)(signed __int64)pParty->uTimePlayed - (double)(amount << 7) * 0.033333335);
-		v656 = 3;
-		v325 = &pParty->pPlayers[v323];
-		v325->DiscardConditionIfLastsLongerThan(v656, v663);
-		LODWORD(v727) = 1;
-		break;
+		case SPELL_SPIRIT_RESSURECTION:
+		{
+			switch (v731)
+			{
+				case 1: amount = 180 * v2; break;
+				case 2: amount = 10800 * v2; break;
+				case 3: amount = 259200 * v2; break;
+				case 4: amount = 0; break;
+				default:
+				assert(false);
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			v396 = pCastSpell->uPlayerID_2;
+			if ( HIDWORD(pParty->pPlayers[v396].pConditions[16]) | LODWORD(pParty->pPlayers[v396].pConditions[16])
+				|| HIDWORD(pParty->pPlayers[v396].pConditions[14]) | LODWORD(pParty->pPlayers[v396].pConditions[14]) )
+			{
+				if ( !(HIDWORD(pParty->pPlayers[v396].pConditions[1]) | LODWORD(pParty->pPlayers[v396].pConditions[1])) )
+					pParty->pPlayers[v396].PlaySound(SPEECH_25, 0);
+				if ( v731 == 4 )
+				{
+					v397 = pCastSpell->uPlayerID_2;
+					LODWORD(pParty->pPlayers[v397].pConditions[16]) = 0;
+					HIDWORD(pParty->pPlayers[v397].pConditions[16]) = 0;
+					v398 = pCastSpell->uPlayerID_2;
+					LODWORD(pParty->pPlayers[v398].pConditions[14]) = 0;
+					HIDWORD(pParty->pPlayers[v398].pConditions[14]) = 0;
+					v399 = pCastSpell->uPlayerID_2;
+					LODWORD(pParty->pPlayers[v399].pConditions[13]) = 0;
+					HIDWORD(pParty->pPlayers[v399].pConditions[13]) = 0;
+				}
+				else
+				{
+					*(float *)&a2 = (double)(amount << 7) * 0.033333335;
+					pParty->pPlayers[pCastSpell->uPlayerID_2].DiscardConditionIfLastsLongerThan( 0x10u,
+						(signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2));
+					pParty->pPlayers[pCastSpell->uPlayerID_2].DiscardConditionIfLastsLongerThan( 0xEu,
+						(signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2));
+					pParty->pPlayers[pCastSpell->uPlayerID_2].DiscardConditionIfLastsLongerThan( 0xDu,
+						(signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2));
+				}
+				pParty->pPlayers[pCastSpell->uPlayerID_2].SetCondition(1u, 1);
+				pParty->pPlayers[pCastSpell->uPlayerID_2].sHealth = 1;
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+			}
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_MIND_CURE_PARALYSIS:
+		{
+			switch (v731)
+			{
+				case 1: amount = 3600 * v2; break;
+				case 2: amount = 3600 * v2; break;
+				case 3: amount = 86400 * v2; break;
+				case 4: amount = 0; break;
+				default:
+				assert(false);
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+			v323 = pCastSpell->uPlayerID_2;
+			v324 = (char *)&pParty->pPlayers[v323].pConditions[12];
+			if ( !pParty->pPlayers[v323].pConditions[12] )
+			{
+				LODWORD(v727) = 1;
+				break;
+			}
+			if ( v731 == 4 )
+			{
+				*(int *)v324 = 0;
+				*((int *)v324 + 1) = 0;
+				LODWORD(v727) = 1;
+				break;
+			}
+			v663 = (signed __int64)((double)(signed __int64)pParty->uTimePlayed - (double)(amount << 7) * 0.033333335);
+			v656 = 12;
+			v325 = &pParty->pPlayers[v323];
+			v325->DiscardConditionIfLastsLongerThan(v656, v663);
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_MIND_REMOVE_FEAR:
+		{
+			switch (v731)
+			{
+				case 1: amount = 180 * v2; break;
+				case 2: amount = 3600 * v2; break;
+				case 3: amount = 86400 * v2; break;
+				case 4: amount = 0; break;
+				default:
+				assert(false);
+			}
+
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+			v323 = pCastSpell->uPlayerID_2;
+			v324 = (char *)&pParty->pPlayers[v323].pConditions[3];
+			if ( !pParty->pPlayers[v323].pConditions[3] )
+			{
+				LODWORD(v727) = 1;
+				break;
+			}
+			if ( v731 == 4 )
+			{
+				*(int *)v324 = 0;
+				*((int *)v324 + 1) = 0;
+				LODWORD(v727) = 1;
+				break;
+			}
+			v663 = (signed __int64)((double)(signed __int64)pParty->uTimePlayed - (double)(amount << 7) * 0.033333335);
+			v656 = 3;
+			v325 = &pParty->pPlayers[v323];
+			v325->DiscardConditionIfLastsLongerThan(v656, v663);
+			LODWORD(v727) = 1;
+			break;
 		}
 		case SPELL_MIND_TELEPATHY:
 		{
@@ -5999,22 +5020,22 @@
 				LODWORD(v727) = 1;
 				break;
 			}
-			v417 = (int)&pActors[PID_ID(a2)];
-			v730 = v417;
-			if ( !(*(char *)(v417 + 38) & 0x80) )
-			{
-				((Actor *)v417)->SetRandomGoldIfTheresNoItem();
-				v417 = v730;
-			}
-			v418 = *(int *)(v417 + 672);
-			HIDWORD(v733) = 0;
+			v417 = &pActors[PID_ID(a2)];
+			Actor * _v730 = v417;
+			if ( !(BYTE2(v417->uAttributes) & 0x80) )
+			{
+				v417->SetRandomGoldIfTheresNoItem();
+				v417 = _v730;
+			}
+			v418 = v417->array_000234[3].uItemID;
+			signed int _v733 = 0;
 			if ( pItemsTable->pItems[v418].uEquipType == 18 )
-				HIDWORD(v733) = *(int *)(v417 + 684);
+				_v733 = v417->array_000234[3].uSpecEnchantmentType;
 
 			//ItemGen::ItemGen(&v683);
 			v683.Reset();
 
-			v419 = *(short *)(v730 + 180);
+			v419 = _v730->uCarriedItemID;
 			if (v419)
 			{
 				v683.uItemID = v419;
@@ -6023,97 +5044,63 @@
 			else
 			{
 				v420 = 0;
-				v421 = v730 + 564;
-				while ( !*(int *)v421 || pItemsTable->pItems[*(int *)v421].uEquipType == 18 )
+				v421 = _v730->array_000234;
+				while ( !v421->uItemID || pItemsTable->pItems[v421->uItemID].uEquipType == 18 )
 				{
 					++v420;
-					v421 += 36;
+					++v421;
 					if ( v420 >= 4 )
 						break;
 				}
 				if ( v420 < 4 )
 				{
-				memcpy(&v683, (const void *)(v730 + 36 * v420 + 564), sizeof(v683));
-				v2 = v723;
-				//v1 = 0;
+					memcpy(&v683, &_v730->array_000234[v420], sizeof(v683));
+					v2 = v723;
+					//v1 = 0;
 				}
 			}
 //	LABEL_799:
-			if ( HIDWORD(v733) != 0 )
-			{
-				v675 = (const char *)HIDWORD(v733);
+			if ( _v733 != 0 )
+			{
+				v675 = _v733;
 				if (v683.uItemID)
 				{
 					v422 = v683.GetDisplayName();
 					sprintf(pTmpBuf2, "(%s), and %d gold", v422, v675);
-					ShowStatusBarString(pTmpBuf2, 2u);
-					pSpellSprite.stru_24.Reset();
-					pSpellSprite.spell_id = pCastSpell->spellnum;
-					pSpellSprite.spell_level = v2;
-					pSpellSprite.spell_skill = v731;
-					pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-					pSpellSprite.vPosition.x = *(short *)(v730 + 142);
-					pSpellSprite.vPosition.y = *(short *)(v730 + 144);
-					v676 = *(short *)(v730 + 138);
-					v665 = pSpellSprite.vPosition.y;
-					pSpellSprite.vPosition.z = *(short *)(v730 + 138);
-					v657 = pSpellSprite.vPosition.x;
+
 				}
 				else
 				{
 					v664 = "%d gold";
 					sprintf(pTmpBuf2, v664, v675);
-					ShowStatusBarString(pTmpBuf2, 2u);
-					pSpellSprite.stru_24.Reset();
-					pSpellSprite.spell_id = pCastSpell->spellnum;
-					pSpellSprite.spell_level = v2;
-					pSpellSprite.spell_skill = v731;
-					pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-					pSpellSprite.vPosition.x = *(short *)(v730 + 142);
-					pSpellSprite.vPosition.y = *(short *)(v730 + 144);
-					v676 = *(short *)(v730 + 138);
-					v665 = pSpellSprite.vPosition.y;
-					pSpellSprite.vPosition.z = *(short *)(v730 + 138);
-					v657 = pSpellSprite.vPosition.x;
 				}
 			}
 			else
 			{
 				if (v683.uItemID)
 				{
-					v675 = v683.GetDisplayName();
+					const char *_v675 = v683.GetDisplayName();
 					v664 = "(%s)";
-					sprintf(pTmpBuf2, v664, v675);
-					ShowStatusBarString(pTmpBuf2, 2u);
-					pSpellSprite.stru_24.Reset();
-					pSpellSprite.spell_id = pCastSpell->spellnum;
-					pSpellSprite.spell_level = v2;
-					pSpellSprite.spell_skill = v731;
-					pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-					pSpellSprite.vPosition.x = *(short *)(v730 + 142);
-					pSpellSprite.vPosition.y = *(short *)(v730 + 144);
-					v676 = *(short *)(v730 + 138);
-					v665 = pSpellSprite.vPosition.y;
-					pSpellSprite.vPosition.z = *(short *)(v730 + 138);
-					v657 = pSpellSprite.vPosition.x;
+					sprintf(pTmpBuf2, v664, _v675);
 				}
 				else
 				{
 					strcpy(pTmpBuf2, "nothing");
 					ShowStatusBarString(pTmpBuf2, 2u);
-					pSpellSprite.stru_24.Reset();
-					pSpellSprite.spell_id = pCastSpell->spellnum;
-					pSpellSprite.spell_level = v2;
-					pSpellSprite.spell_skill = v731;
-					pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-					pSpellSprite.vPosition.x = *(short *)(v730 + 142);
-					pSpellSprite.vPosition.y = *(short *)(v730 + 144);
-					v676 = *(short *)(v730 + 138);
-					v665 = pSpellSprite.vPosition.y;
-					pSpellSprite.vPosition.z = *(short *)(v730 + 138);
-					v657 = pSpellSprite.vPosition.x;
 				}
 			}
+			ShowStatusBarString(pTmpBuf2, 2u);
+			pSpellSprite.stru_24.Reset();
+			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_level = v2;
+			pSpellSprite.spell_skill = v731;
+			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+			pSpellSprite.vPosition.x = _v730->vPosition.x;
+			pSpellSprite.vPosition.y = _v730->vPosition.y;
+			v676 = _v730->uActorHeight;
+			v665 = pSpellSprite.vPosition.y;
+			pSpellSprite.vPosition.z = _v730->uActorHeight;
+			v657 = pSpellSprite.vPosition.x;
 			pSpellSprite.uAttributes = 0;
 			pSpellSprite.uSectorID = pIndoor->GetSector(v657, v665, v676);
 			pSpellSprite.uSpriteFrameID = 0;
@@ -6129,26 +5116,15 @@
 		}
 		case SPELL_MIND_BERSERK:
 		{
-			v423 = v731 - 2;
-			if ( !v423 )
-				v425 = 300 * v2;
-			else
-			{
-				v424 = v423 - 1;
-				if ( v424 )
-				{
-					if ( v424 == 1 )
-						v425 = 3600 * v2;
-					else
-//LABEL_813:
-						v425 = 300 * v2;
-				}
-				else
-				{
-					v425 = 600 * v2;
-				}
-			}
-			amount = v425;
+			switch (v731)
+			{
+				case 1: amount = 300 * v2; break;
+				case 2: amount = 300 * v2; break;
+				case 3: amount = 600 * v2; break;
+				case 4: amount = 3600; break;
+				default:
+				assert(false);
+			}
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
 			v426 = PID_ID(a2);
@@ -6249,1001 +5225,939 @@
 		}
 		case SPELL_MIND_MASS_FEAR:
 		{
-		v428 = v731 - 2;
-		if ( v428 && (v429 = v428 - 1) != 0 && v429 == 1 )
-			v430 = 300 * v2;
-		else
-			v430 = 180 * v2;
-		amount = v430;
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			break;
-		auto _v726 = sub_46A6AC((int)dword_50BF30, 100, 4096);
-		pGame->GetStru6()->FadeScreen__like_Turn_Undead_and_mb_Armageddon(0xA0A0Au, 0xC0u);
-		++pSpellSprite.uType;
-		pSpellSprite.stru_24.Reset();
-		pSpellSprite.spell_id = pCastSpell->spellnum;
-		pSpellSprite.spell_level = v2;
-		pSpellSprite.spell_skill = v731;
-		pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-		pSpellSprite.uAttributes = 0;
-		pSpellSprite.uSectorID = 0;
-		pSpellSprite.uSpriteFrameID = 0;
-		pSpellSprite.field_60_distance_related_prolly_lod = 0;
-		pSpellSprite.uFacing = 0;
-		pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-		pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-		for ( a2 = 0; a2 < (signed int)_v726; ++a2 )
-		{
-			v433 = &pActors[dword_50BF30[a2]];
-			if ( MonsterStats::BelongsToSupertype(v433->pMonsterInfo.uID, MONSTER_SUPERTYPE_UNDEAD) )
+			if ( v731 == 4 )
+				amount = 300 * v2;
+			else
+				amount = 180 * v2;
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			auto _v726 = sub_46A6AC((int)dword_50BF30, 100, 4096);
+			pGame->GetStru6()->FadeScreen__like_Turn_Undead_and_mb_Armageddon(0xA0A0Au, 0xC0u);
+			++pSpellSprite.uType;
+			pSpellSprite.stru_24.Reset();
+			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_level = v2;
+			pSpellSprite.spell_skill = v731;
+			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+			pSpellSprite.uAttributes = 0;
+			pSpellSprite.uSectorID = 0;
+			pSpellSprite.uSpriteFrameID = 0;
+			pSpellSprite.field_60_distance_related_prolly_lod = 0;
+			pSpellSprite.uFacing = 0;
+			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+			for ( a2 = 0; a2 < (signed int)_v726; ++a2 )
+			{
+				v433 = &pActors[dword_50BF30[a2]];
+				if ( MonsterStats::BelongsToSupertype(v433->pMonsterInfo.uID, MONSTER_SUPERTYPE_UNDEAD) )
+					break;
+				pSpellSprite.vPosition.x = v433->vPosition.x;
+				pSpellSprite.vPosition.y = v433->vPosition.y;
+				pSpellSprite.vPosition.z = v433->vPosition.z - (unsigned int)(signed __int64)((double)v433->uActorHeight * unk_4D8548);
+
+				pSpellSprite.spell_target_pid = PID(OBJECT_Actor, dword_50BF30[a2]);
+				pSpellSprite.Create(0, 0, 0, 0);
+				if ( stru_50C198.GetMagicalResistance(v433, 7u) )
+				{
+					v433->pActorBuffs[4].Apply(pParty->uTimePlayed + (signed __int64)((double)(amount << 7) * 0.033333335),
+						v731, 0, 0, 0);
+				}
+			}
+			LODWORD(v727) = 1;
 			break;
-			pSpellSprite.vPosition.x = v433->vPosition.x;
-			pSpellSprite.vPosition.y = v433->vPosition.y;
-			pSpellSprite.vPosition.z = v433->vPosition.z - (unsigned int)(signed __int64)((double)v433->uActorHeight * unk_4D8548);
-
-			pSpellSprite.spell_target_pid = PID(OBJECT_Actor, dword_50BF30[a2]);
-			pSpellSprite.Create(0, 0, 0, 0);
-			if ( stru_50C198.GetMagicalResistance(v433, 7u) )
-			{
-			v433->pActorBuffs[4].Apply(pParty->uTimePlayed + (signed __int64)((double)(amount << 7) * 0.033333335),
-				v731, 0, 0, 0);
-			}
-		}
-		LODWORD(v727) = 1;
-		break;
-		}
-
-		case SPELL_MIND_CURE_INSANITY:
-			{
-		v435 = v731 - 2;
-		if ( v435 && (v436 = v435 - 1) != 0 && v436 == 1 )
-			amount = 0;
-		else
-			amount = 86400 * v2;
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			break;
-
-		pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
-		v440 = pCastSpell->uPlayerID_2;
-		if ( HIDWORD(pParty->pPlayers[v440].pConditions[5]) | LODWORD(pParty->pPlayers[v440].pConditions[5]) )
-		{
-			if ( !(HIDWORD(pParty->pPlayers[v440].pConditions[1]) | LODWORD(pParty->pPlayers[v440].pConditions[1])) )
-			pParty->pPlayers[v440].PlaySound(SPEECH_25, 0);
-			if ( v731 == 4 )
-			{
-			v441 = pCastSpell->uPlayerID_2;
-			LODWORD(pParty->pPlayers[v441].pConditions[5]) = 0;
-			HIDWORD(pParty->pPlayers[v441].pConditions[5]) = 0;
-			}
-			else
-			{
-			pParty->pPlayers[pCastSpell->uPlayerID_2].DiscardConditionIfLastsLongerThan(5u,
-				(signed __int64)((double)(signed __int64)pParty->uTimePlayed - (double)(amount << 7) * 0.033333335));
-			}
-			v377 = &pParty->pPlayers[pCastSpell->uPlayerID_2];
-//LABEL_720:
-			v377->SetCondition(1, 0);
 		}
-		LODWORD(v727) = 1;
-		break;
-			}
-		case SPELL_EARTH_TELEKINESIS:
-			{
-		if ( v731 == 1 || v731 == 2 )
-			amount = 2 * v2;
-		else if( v731 == 3 )
-			amount = 3 * v2;
-		else if ( v731 == 4 )
-			amount = 4 * v2;
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			break;
-		v445 = PID_ID(a2);
-		if (PID_TYPE(a2) == OBJECT_Item)
+		case SPELL_MIND_CURE_INSANITY:
 		{
-			v449 = (char *)&pSpriteObjects[v445].stru_24;
-			v450 = *(int *)v449;
-			if ( pItemsTable->pItems[v450].uEquipType == 18 )
-			{
-			party_finds_gold(*((int *)v449 + 3), 0);
-			viewparams->bRedrawGameUI = 1;
-			}
+			v435 = v731 - 2;
+			if ( v731 == 4 )
+				amount = 0;
 			else
-			{
-			sprintfex(pTmpBuf2, pGlobalTXT_LocalizationStrings[471], pItemsTable->pItems[v450].pUnidentifiedName);
-			ShowStatusBarString(pTmpBuf2, 2u);
-			if ( !pParty->AddItem(&pSpriteObjects[v445].stru_24) )
-				pParty->SetHoldingItem(&pSpriteObjects[v445].stru_24);
-			}
-			SpriteObject::OnInteraction(v445);
-		}
-		else
-		{
-			if (PID_TYPE(a2) == OBJECT_Actor)
-			{
-			stru_50C198.LootActor(&pActors[v445]);
-			}
-			else
-			{
-			if (PID_TYPE(a2) != OBJECT_Decoration)
-			{
-				if (PID_TYPE(a2) != OBJECT_BModel)
+				amount = 86400 * v2;
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+			v440 = pCastSpell->uPlayerID_2;
+			if ( HIDWORD(pParty->pPlayers[v440].pConditions[5]) | LODWORD(pParty->pPlayers[v440].pConditions[5]) )
+			{
+				if ( !(HIDWORD(pParty->pPlayers[v440].pConditions[1]) | LODWORD(pParty->pPlayers[v440].pConditions[1])) )
+					pParty->pPlayers[v440].PlaySound(SPEECH_25, 0);
+				if ( v731 == 4 )
 				{
-				LODWORD(v727) = 1;
-				break;
+					v441 = pCastSpell->uPlayerID_2;
+					LODWORD(pParty->pPlayers[v441].pConditions[5]) = 0;
+					HIDWORD(pParty->pPlayers[v441].pConditions[5]) = 0;
 				}
-				dword_507CD8 = 1;
-				v677 = 1;
-				if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
-				v446 = pIndoor->pFaceExtras[pIndoor->pFaces[v445].uFaceExtraID].uEventID;
 				else
-				v446 = pOutdoor->pBModels[a2 >> 9].pFaces[v445 & 0x3F].sCogTriggeredID;
-
-				EventProcessor(v446, a2, v677);
-				LODWORD(v727) = 1;
-				break;
-			}
-			v447 = &pLevelDecorations[v445];
-			dword_507CD8 = 1;
-			v448 = v447->field_16_event_id;
-			if (v448)
-			{
-				v677 = 1;
-				v446 = v448;
-				EventProcessor(v446, a2, v677);
-				LODWORD(v727) = 1;
-				break;
-			}
-			if ( v447->IsInteractive() )
-			{
-				activeLevelDecoration = v447;
-				EventProcessor(stru_5E4C90._decor_events[v447->_idx_in_stru123 - 75] + 380, 0, 1);
-				activeLevelDecoration = NULL;
-			}
-			}
-		}
-		LODWORD(v727) = 1;
-		break;
-			}
-		case SPELL_BODY_CURE_WEAKNESS:
-			{
-		if ( v731 == 1 )
-			amount = 180 * v2;
-		else if( v731 == 2 )
-			amount = 3600 * v2;
-		else if( v731 == 3 )
-			amount = 86400 * v2;
-		else if ( v731 == 4 )
-			amount = 0;
-//LABEL_883:
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			break;
-
-		pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
-		v323 = pCastSpell->uPlayerID_2;
-		v324 = (char *)&pParty->pPlayers[v323].pConditions[1];
-		if ( !pParty->pPlayers[v323].pConditions[1] )
-		{
+				{
+					pParty->pPlayers[pCastSpell->uPlayerID_2].DiscardConditionIfLastsLongerThan(5u,
+						(signed __int64)((double)(signed __int64)pParty->uTimePlayed - (double)(amount << 7) * 0.033333335));
+				}
+				v377 = &pParty->pPlayers[pCastSpell->uPlayerID_2];
+				v377->SetCondition(1, 0);
+			}
 			LODWORD(v727) = 1;
 			break;
 		}
-		if ( v731 == 4 )
+		case SPELL_EARTH_TELEKINESIS:
 		{
-			*(int *)v324 = 0;
-			*((int *)v324 + 1) = 0;
+			switch (v731)
+			{
+				case 1: amount = 2 * v2; break;
+				case 2: amount = 2 * v2; break;
+				case 3: amount = 3 * v2; break;
+				case 4: amount = 4 * v2; break;
+				default:
+				assert(false);
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			v445 = PID_ID(a2);
+			if (PID_TYPE(a2) == OBJECT_Item)
+			{
+				v449 = (char *)&pSpriteObjects[v445].stru_24;
+				v450 = *(int *)v449;
+				if ( pItemsTable->pItems[v450].uEquipType == 18 )
+				{
+					party_finds_gold(*((int *)v449 + 3), 0);
+					viewparams->bRedrawGameUI = 1;
+				}
+				else
+				{
+					sprintfex(pTmpBuf2, pGlobalTXT_LocalizationStrings[471], pItemsTable->pItems[v450].pUnidentifiedName);
+					ShowStatusBarString(pTmpBuf2, 2u);
+					if ( !pParty->AddItem(&pSpriteObjects[v445].stru_24) )
+						pParty->SetHoldingItem(&pSpriteObjects[v445].stru_24);
+				}
+				SpriteObject::OnInteraction(v445);
+			}
+			else
+			{
+				if (PID_TYPE(a2) == OBJECT_Actor)
+				{
+					stru_50C198.LootActor(&pActors[v445]);
+				}
+				else
+				{
+					if (PID_TYPE(a2) != OBJECT_Decoration)
+					{
+						if (PID_TYPE(a2) != OBJECT_BModel)
+						{
+							LODWORD(v727) = 1;
+							break;
+						}
+						dword_507CD8 = 1;
+						v677 = 1;
+						if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
+							v446 = pIndoor->pFaceExtras[pIndoor->pFaces[v445].uFaceExtraID].uEventID;
+						else
+							v446 = pOutdoor->pBModels[a2 >> 9].pFaces[v445 & 0x3F].sCogTriggeredID;
+						EventProcessor(v446, a2, v677);
+						LODWORD(v727) = 1;
+						break;
+					}
+					v447 = &pLevelDecorations[v445];
+					dword_507CD8 = 1;
+					v448 = v447->field_16_event_id;
+					if (v448)
+					{
+						v677 = 1;
+						v446 = v448;
+						EventProcessor(v446, a2, v677);
+						LODWORD(v727) = 1;
+						break;
+					}
+					if ( v447->IsInteractive() )
+					{
+						activeLevelDecoration = v447;
+						EventProcessor(stru_5E4C90._decor_events[v447->_idx_in_stru123 - 75] + 380, 0, 1);
+						activeLevelDecoration = NULL;
+					}
+				}
+			}
 			LODWORD(v727) = 1;
 			break;
 		}
-		v663 = (signed __int64)((double)(signed __int64)pParty->uTimePlayed - (double)(amount << 7) * 0.033333335);
-		v656 = 1;
-		v325 = &pParty->pPlayers[v323];
-		v325->DiscardConditionIfLastsLongerThan(v656, v663);
-		LODWORD(v727) = 1;
-		break;
-		}
-		case SPELL_BODY_FIRST_AID:
-			{
-		v457 = v731 - 2;
-		if ( v457 )
-		{
-			v458 = v457 - 1;
-			if ( v458 )
-			{
-			if ( v458 == 1 )
-				v459 = 5 * v2 + 5;
-			else
-				v459 = 2 * v2 + 5;
-			}
-			else
-			{
-			v459 = 4 * v2 + 5;
-			}
-		}
-		else
-		{
-			v459 = 3 * v2 + 5;
-		}
-		amount = v459;
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			break;
-		v460 = pCastSpell->spell_target_pid;
-		if (!v460)
-		{
-			pParty->pPlayers[pCastSpell->uPlayerID_2].Heal(amount);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
-		}
-		else
+		case SPELL_BODY_CURE_WEAKNESS:
 		{
-			if (PID_TYPE(v460) == OBJECT_Actor)
-			{
-			v461 = &pActors[PID_ID(v460)];
-			v462 = v461->uAIState;
-			v463 = v461->pMonsterInfo.uHP;
-			if ( v462 != 5 )
-			{
-				if ( v462 != 4 )
-				{
-				if ( v462 != 19 )
-				{
-					if ( v462 != 11 )
-					{
-					v461->sCurrentHP += amount;
-					if ( v461->sCurrentHP > v463 )
-						v461->sCurrentHP = v463;
-					}
-				}
-				}
-			}
-			}
-		}
-		LODWORD(v727) = 1;
-		break;
-			}
-		case SPELL_BODY_CURE_POISON:
-			{
-		if ( v731 == 1 || v731 == 2 )
-			amount = 3600 * v2;
-		else if( v731 == 3)
-			amount = 86400 * v2;
-		else if ( v731 == 4 )
-			amount = 0;
-//LABEL_912:
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			break;
-
-		pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
-		v470 = pCastSpell->uPlayerID_2;
-		if ( !(HIDWORD(pParty->pPlayers[v470].pConditions[6]) | LODWORD(pParty->pPlayers[v470].pConditions[6]))
-			&& !(HIDWORD(pParty->pPlayers[v470].pConditions[8]) | LODWORD(pParty->pPlayers[v470].pConditions[8]))
-			&& !(HIDWORD(pParty->pPlayers[v470].pConditions[10]) | LODWORD(pParty->pPlayers[v470].pConditions[10])) )
-		{
+			switch (v731)
+			{
+				case 1: amount = 180 * v2; break;
+				case 2: amount = 3600 * v2; break;
+				case 3: amount = 86400 * v2; break;
+				case 4: amount = 0; break;
+				default:
+				assert(false);
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+			v323 = pCastSpell->uPlayerID_2;
+			v324 = (char *)&pParty->pPlayers[v323].pConditions[1];
+			if ( !pParty->pPlayers[v323].pConditions[1] )
+			{
+				LODWORD(v727) = 1;
+				break;
+			}
+			if ( v731 == 4 )
+			{
+				*(int *)v324 = 0;
+				*((int *)v324 + 1) = 0;
+				LODWORD(v727) = 1;
+				break;
+			}
+			v663 = (signed __int64)((double)(signed __int64)pParty->uTimePlayed - (double)(amount << 7) * 0.033333335);
+			v656 = 1;
+			v325 = &pParty->pPlayers[v323];
+			v325->DiscardConditionIfLastsLongerThan(v656, v663);
 			LODWORD(v727) = 1;
 			break;
 		}
-		if ( v731 == 4 )
+		case SPELL_BODY_FIRST_AID:
 		{
-			LODWORD(pParty->pPlayers[v470].pConditions[6]) = 0;
-			HIDWORD(pParty->pPlayers[v470].pConditions[6]) = 0;
-			v471 = pCastSpell->uPlayerID_2;
-			LODWORD(pParty->pPlayers[v471].pConditions[8]) = 0;
-			HIDWORD(pParty->pPlayers[v471].pConditions[8]) = 0;
-			v472 = pCastSpell->uPlayerID_2;
-			LODWORD(pParty->pPlayers[v472].pConditions[10]) = 0;
-			HIDWORD(pParty->pPlayers[v472].pConditions[10]) = 0;
+			switch (v731)
+			{
+				case 1: amount = 2 * v2 + 5; break;
+				case 2: amount = 3 * v2 + 5; break;
+				case 3: amount = 4 * v2 + 5; break;
+				case 4: amount = 5 * v2 + 5; break;
+				default:
+				assert(false);
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			v460 = pCastSpell->spell_target_pid;
+			if (!v460)
+			{
+				pParty->pPlayers[pCastSpell->uPlayerID_2].Heal(amount);
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+			}
+			else
+			{
+				if (PID_TYPE(v460) == OBJECT_Actor)
+				{
+					v461 = &pActors[PID_ID(v460)];
+					v462 = v461->uAIState;
+					v463 = v461->pMonsterInfo.uHP;
+					if ( v462 != 5 )
+					{
+						if ( v462 != 4 )
+						{
+							if ( v462 != 19 )
+							{
+								if ( v462 != 11 )
+								{
+									v461->sCurrentHP += amount;
+									if ( v461->sCurrentHP > v463 )
+										v461->sCurrentHP = v463;
+								}
+							}
+						}
+					}
+				}
+			}
 			LODWORD(v727) = 1;
 			break;
 		}
-		*(float *)&a2 = (double)(amount << 7) * 0.033333335;
-		pParty->pPlayers[v470].DiscardConditionIfLastsLongerThan(
-			6u,
-			(signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2));
-		pParty->pPlayers[pCastSpell->uPlayerID_2].DiscardConditionIfLastsLongerThan(
-			8u,
-			(signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2));
-		v663 = (signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2);
-		v656 = 10;
-		v325 = &pParty->pPlayers[pCastSpell->uPlayerID_2];
-		v325->DiscardConditionIfLastsLongerThan(v656, v663);
-		LODWORD(v727) = 1;
-		break;
+		case SPELL_BODY_CURE_POISON:
+		{
+			switch (v731)
+			{
+				case 1: amount = 3600 * v2; break;
+				case 2: amount = 3600 * v2; break;
+				case 3: amount = 86400 * v2; break;
+				case 4: amount = 0; break;
+				default:
+				assert(false);
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+			v470 = pCastSpell->uPlayerID_2;
+			if ( !(HIDWORD(pParty->pPlayers[v470].pConditions[6]) | LODWORD(pParty->pPlayers[v470].pConditions[6]))
+				&& !(HIDWORD(pParty->pPlayers[v470].pConditions[8]) | LODWORD(pParty->pPlayers[v470].pConditions[8]))
+				&& !(HIDWORD(pParty->pPlayers[v470].pConditions[10]) | LODWORD(pParty->pPlayers[v470].pConditions[10])) )
+			{
+				LODWORD(v727) = 1;
+				break;
+			}
+			if ( v731 == 4 )
+			{
+				LODWORD(pParty->pPlayers[v470].pConditions[6]) = 0;
+				HIDWORD(pParty->pPlayers[v470].pConditions[6]) = 0;
+				v471 = pCastSpell->uPlayerID_2;
+				LODWORD(pParty->pPlayers[v471].pConditions[8]) = 0;
+				HIDWORD(pParty->pPlayers[v471].pConditions[8]) = 0;
+				v472 = pCastSpell->uPlayerID_2;
+				LODWORD(pParty->pPlayers[v472].pConditions[10]) = 0;
+				HIDWORD(pParty->pPlayers[v472].pConditions[10]) = 0;
+				LODWORD(v727) = 1;
+				break;
+			}
+			*(float *)&a2 = (double)(amount << 7) * 0.033333335;
+			pParty->pPlayers[v470].DiscardConditionIfLastsLongerThan(
+				6u,
+				(signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2));
+			pParty->pPlayers[pCastSpell->uPlayerID_2].DiscardConditionIfLastsLongerThan(
+				8u,
+				(signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2));
+			v663 = (signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2);
+			v656 = 10;
+			v325 = &pParty->pPlayers[pCastSpell->uPlayerID_2];
+			v325->DiscardConditionIfLastsLongerThan(v656, v663);
+			LODWORD(v727) = 1;
+			break;
 		}
 		case SPELL_BODY_PROTECTION_FROM_MAGIC:
-			{
-		amount = v2;
-		LODWORD(v733) = 3600 * v2;
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			break;
-
-		pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
-		pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
-		pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
-		pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
-
-		pParty->pPartyBuffs[PARTY_BUFF_PROTECTION_FROM_MAGIC].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, v2, 0, 0);
-			LODWORD(v727) = 1;
-			break;
-			}
-		case SPELL_BODY_HAMMERHANDS:
-			{
-		LODWORD(v733) = 3600 * v2;
-		amount = v2;
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			break;
-		if ( v731 == 4 )
 		{
+			amount = v2;
+			LODWORD(v733) = 3600 * v2;
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+
 			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
 			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
 			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
 			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
-			v732 = (int)v733 << 7;
-			v717 = (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
-			pParty->pPlayers[0].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].Apply(pParty->uTimePlayed + v717, 4u, v2, v2, 0);
-			pParty->pPlayers[1].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].Apply(pParty->uTimePlayed + v717, 4u, v2, v2, 0);
-			pParty->pPlayers[2].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].Apply(pParty->uTimePlayed + v717, 4u, v2, v2, 0);
-
-			pParty->pPlayers[3].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].Apply(pParty->uTimePlayed + v717, 4, v2, v2, 0);
+
+			pParty->pPartyBuffs[PARTY_BUFF_PROTECTION_FROM_MAGIC].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, v2, 0, 0);
 			LODWORD(v727) = 1;
 			break;
 		}
-		pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
-
-		pParty->pPlayers[pCastSpell->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, v2, v2, 0);
-			LODWORD(v727) = 1;
-			break;
-			}
-		case SPELL_BODY_CURE_DISEASE:
-			{
-		v493 = v731 - 2;
-		if ( v493 && (v494 = v493 - 1) != 0 && v494 == 1 )
-			amount = 0;
-		else
-			amount = 86400 * v2;
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			break;
-
-		pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
-		v498 = pCastSpell->uPlayerID_2;
-		if ( !(HIDWORD(pParty->pPlayers[v498].pConditions[7]) | LODWORD(pParty->pPlayers[v498].pConditions[7]))
-			&& !(HIDWORD(pParty->pPlayers[v498].pConditions[9]) | LODWORD(pParty->pPlayers[v498].pConditions[9]))
-			&& !(HIDWORD(pParty->pPlayers[v498].pConditions[11]) | LODWORD(pParty->pPlayers[v498].pConditions[11])) )
+		case SPELL_BODY_HAMMERHANDS:
 		{
+			LODWORD(v733) = 3600 * v2;
+			amount = v2;
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			if ( v731 == 4 )
+			{
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
+				v732 = (int)v733 << 7;
+				v717 = (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
+				pParty->pPlayers[0].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].Apply(pParty->uTimePlayed + v717, 4u, v2, v2, 0);
+				pParty->pPlayers[1].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].Apply(pParty->uTimePlayed + v717, 4u, v2, v2, 0);
+				pParty->pPlayers[2].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].Apply(pParty->uTimePlayed + v717, 4u, v2, v2, 0);
+
+				pParty->pPlayers[3].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].Apply(pParty->uTimePlayed + v717, 4, v2, v2, 0);
+				LODWORD(v727) = 1;
+				break;
+			}
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+
+			pParty->pPlayers[pCastSpell->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, v2, v2, 0);
 			LODWORD(v727) = 1;
 			break;
 		}
-		if ( v731 == 4 )
-		{
-			LODWORD(pParty->pPlayers[v498].pConditions[7]) = 0;
-			HIDWORD(pParty->pPlayers[v498].pConditions[7]) = 0;
-			v499 = pCastSpell->uPlayerID_2;
-			LODWORD(pParty->pPlayers[v499].pConditions[9]) = 0;
-			HIDWORD(pParty->pPlayers[v499].pConditions[9]) = 0;
-			v500 = pCastSpell->uPlayerID_2;
-			LODWORD(pParty->pPlayers[v500].pConditions[11]) = 0;
-			HIDWORD(pParty->pPlayers[v500].pConditions[11]) = 0;
-		}
-		else
+		case SPELL_BODY_CURE_DISEASE:
 		{
-			*(float *)&a2 = (double)(amount << 7) * 0.033333335;
-			pParty->pPlayers[v498].DiscardConditionIfLastsLongerThan(
-			7u,
-			(signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2));
-			pParty->pPlayers[pCastSpell->uPlayerID_2].DiscardConditionIfLastsLongerThan(
-			9u,
-			(signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2));
-			v663 = (signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2);
-			v656 = 11;
-//LABEL_937:
-			v325 = &pParty->pPlayers[pCastSpell->uPlayerID_2];
-//LABEL_641:
-			v325->DiscardConditionIfLastsLongerThan(v656, v663);
-		}
+			if ( v731 == 4 )
+				amount = 0;
+			else
+				amount = 86400 * v2;
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+			v498 = pCastSpell->uPlayerID_2;
+			if ( !(HIDWORD(pParty->pPlayers[v498].pConditions[7]) | LODWORD(pParty->pPlayers[v498].pConditions[7]))
+				&& !(HIDWORD(pParty->pPlayers[v498].pConditions[9]) | LODWORD(pParty->pPlayers[v498].pConditions[9]))
+				&& !(HIDWORD(pParty->pPlayers[v498].pConditions[11]) | LODWORD(pParty->pPlayers[v498].pConditions[11])) )
+			{
+				LODWORD(v727) = 1;
+				break;
+			}
+			if ( v731 == 4 )
+			{
+				LODWORD(pParty->pPlayers[v498].pConditions[7]) = 0;
+				HIDWORD(pParty->pPlayers[v498].pConditions[7]) = 0;
+				v499 = pCastSpell->uPlayerID_2;
+				LODWORD(pParty->pPlayers[v499].pConditions[9]) = 0;
+				HIDWORD(pParty->pPlayers[v499].pConditions[9]) = 0;
+				v500 = pCastSpell->uPlayerID_2;
+				LODWORD(pParty->pPlayers[v500].pConditions[11]) = 0;
+				HIDWORD(pParty->pPlayers[v500].pConditions[11]) = 0;
+			}
+			else
+			{
+				*(float *)&a2 = (double)(amount << 7) * 0.033333335;
+				pParty->pPlayers[v498].DiscardConditionIfLastsLongerThan(
+				7u,
+				(signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2));
+				pParty->pPlayers[pCastSpell->uPlayerID_2].DiscardConditionIfLastsLongerThan(
+				9u,
+				(signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2));
+				v663 = (signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2);
+				v656 = 11;
+				v325 = &pParty->pPlayers[pCastSpell->uPlayerID_2];
+				v325->DiscardConditionIfLastsLongerThan(v656, v663);
+			}
 			LODWORD(v727) = 1;
 			break;
-			}
+		}
 		case SPELL_BODY_POWER_CURE:
 		{
-		amount = 5 * v2 + 10;
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			break;
-		v501 = pParty->pPlayers;
-		int v1 = 0;
-		do
-		{
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, v1);
-			v501->Heal(amount);
-			++v501;
-			++v1;
-		}
-		while ( (signed int)v501 < (signed int)pParty->pHirelings );
+			amount = 5 * v2 + 10;
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			v501 = pParty->pPlayers;
+			int v1 = 0;
+			do
+			{
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, v1);
+				v501->Heal(amount);
+				++v501;
+				++v1;
+			}
+			while ( (signed int)v501 < (signed int)pParty->pHirelings );
 			LODWORD(v727) = 1;
 			break;
 		}
 		case SPELL_LIGHT_DISPEL_MAGIC:
-			{
-		sRecoveryTime -= v2;
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			break;
-
-		pGame->GetStru6()->FadeScreen__like_Turn_Undead_and_mb_Armageddon(0xAFF0Au, 0xC0u);
-		v505 = sub_46A6AC((int)dword_50BF30, 100, 4096);
-		++pSpellSprite.uType;
-		HIDWORD(v733) = v505;
-		v688.x = 0;
-		v688.y = 0;
-		v688.z = 0;
-		pSpellSprite.stru_24.Reset();
-		pSpellSprite.spell_id = pCastSpell->spellnum;
-		pSpellSprite.spell_level = v2;
-		pSpellSprite.spell_skill = v731;
-		pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-		pSpellSprite.uAttributes = 0;
-		pSpellSprite.uSectorID = 0;
-		pSpellSprite.uSpriteFrameID = 0;
-		pSpellSprite.field_60_distance_related_prolly_lod = 0;
-		pSpellSprite.uFacing = 0;
-		pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-		pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-		a2 = 0;
-		if ( SHIDWORD(v733) > 0 )
 		{
-			do
-			{
-			v507 = dword_50BF30[a2];
-			pSpellSprite.vPosition.x = pActors[v507].vPosition.x;
-			pSpellSprite.vPosition.y = pActors[v507].vPosition.y;
-			pSpellSprite.vPosition.z = pActors[v507].vPosition.z - (unsigned int)(signed __int64)((double)pActors[v507].uActorHeight * unk_4D8548);
-			pSpellSprite.spell_target_pid = PID(OBJECT_Actor, dword_50BF30[a2]);
-			v509 = pSpellSprite.Create(0, 0, 0, 0);
-			v510 = a2;
-			DamageMonsterFromParty(PID(OBJECT_Item, v509), dword_50BF30[a2], (Vec3_int_ *)&v688);
-			a2 = v510 + 1;
-			}
-			while ( v510 + 1 < SHIDWORD(v733) );
-		}
-		for ( a2 = 0; a2 < SHIDWORD(v733); ++a2 )
-		{
-			v511 = &pActors[dword_50BF30[a2]];
-			pSpellSprite.vPosition.x = v511->vPosition.x;
-			pSpellSprite.vPosition.y = v511->vPosition.y;
-			pSpellSprite.vPosition.z = v511->vPosition.z - (unsigned int)(signed __int64)((double)v511->uActorHeight * unk_4D8548);
-			pSpellSprite.spell_target_pid = PID(OBJECT_Actor, dword_50BF30[a2]);
-			pSpellSprite.Create(0, 0, 0, 0);
-			v513 = v511->pActorBuffs;
-			for (int _v726 = 22; _v726 != 0; --_v726)
-			{
-			v513->Reset();
-			++v513;
-			}
-		}
-			LODWORD(v727) = 1;
-			break;
-			}
-		case SPELL_LIGHT_SUMMON_ELEMENTAL:
-			{
-		v514 = v731 - 2;
-		if ( v731 == 1 || v731 == 2 )
-		{
-			v516 = 300 * v2;
-			amount = 1;
-		}
-		else if( v731 == 3 )
-		{
-			v516 = 900 * v2;
-			amount = 3;
-		}
-		else if ( v731 == 4 )
-			{
-			v516 = 900 * v2;
-			amount = 5;
-			}
-		v733 = __PAIR__(0, v516);
-
-		if ( (signed int)uNumActors > 0 )
-		{
-			v518 = pActors;//[0].uAIState;
-			auto _v726 = uNumActors;
-			do
-			{
-			v519 = v518->uAIState;
-			if ( v518->uAIState != 5 && v519 != 11 && v519 != 19 && PID(OBJECT_Player, pCastSpell->uPlayerID) == v518->uSummonerID )
-				++HIDWORD(v733);
-			++v518;
-			--_v726;
-			}
-			while ( _v726 != 0 );
-		}
-		if ( SHIDWORD(v733) >= amount )
-		{
-			ShowStatusBarString(pGlobalTXT_LocalizationStrings[648], 2);  // This character can't summon any more monsters!
-			pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-			pCastSpell->spellnum = 0;
-			continue;
-		}
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			break;
-		sub_44FA4C_spawn_light_elemental(pCastSpell->uPlayerID, v731, v733);
-			LODWORD(v727) = 1;
-			break;
-			}
-		case SPELL_LIGHT_DAY_OF_THE_GODS:
-			{
-		if ( v731 == 1 || v731 == 2 )
-		{
-			LODWORD(v733) = 10800 * v2;
-			amount = 3 * v2 + 10;
-		}
-		else if( v731 == 3 )
-		{
-			LODWORD(v733) = 14400 * v2;
-			amount = 4 * v2 + 10;
-		}
-		else if ( v731 == 4 )
-		{
-			LODWORD(v733) = 18000 * v2;
-			amount = 5 * v2 + 10;
-		}
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			break;
-
-		pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
-		pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
-		pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
-		pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
-
-		pParty->pPartyBuffs[PARTY_BUFF_DAY_OF_GODS].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, amount, 0, 0);
-		LODWORD(v727) = 1;
-		break;
-			}
-		case SPELL_LIGHT_PRISMATIC_LIGHT:
-			{
-		//v67 = 2;
-		if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor)
-		{
-			ShowStatusBarString(pGlobalTXT_LocalizationStrings[497], 2);  // Can't cast Prismatic Light outdoors!
-			pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-			pCastSpell->spellnum = 0;
-			continue;
-		}
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			break;
-		v531 = sub_46A6AC((int)dword_50BF30, 100, 4096);
-		++pSpellSprite.uType;
-		v694.x = 0;
-		v694.y = 0;
-		v694.z = 0;
-		pSpellSprite.stru_24.Reset();
-		pSpellSprite.spell_id = pCastSpell->spellnum;
-		pSpellSprite.spell_level = v2;
-		pSpellSprite.spell_skill = v731;
-		pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-		pSpellSprite.uAttributes = 0;
-		pSpellSprite.uSectorID = 0;
-		pSpellSprite.uSpriteFrameID = 0;
-		pSpellSprite.field_60_distance_related_prolly_lod = 0;
-		pSpellSprite.uFacing = 0;
-		pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-		pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-		a2 = 0;
-		if ( (signed int)v531 > 0 )
-		{
-			do
-			{
-			v533 = dword_50BF30[a2];
-			pSpellSprite.vPosition.x = pActors[v533].vPosition.x;
-			pSpellSprite.vPosition.y = pActors[v533].vPosition.y;
-			pSpellSprite.vPosition.z = pActors[v533].vPosition.z - (unsigned int)(signed __int64)((double)pActors[v533].uActorHeight * unk_4D8548);
-			pSpellSprite.spell_target_pid = PID(OBJECT_Actor, dword_50BF30[a2]);
-			v535 = pSpellSprite.Create(0, 0, 0, 0);
-			v536 = a2;
-			DamageMonsterFromParty(PID(OBJECT_Item, v535), dword_50BF30[a2], &v694);
-			a2 = v536 + 1;
-			}
-			while ( v536 + 1 < (signed int)v531 );
-		}
-		v537 = pGame->GetStru6();
-		pGame->GetStru6()->_4A8BFC();
-			LODWORD(v727) = 1;
-			break;
-			}
-		case SPELL_LIGHT_DAY_OF_PROTECTION:
-		{
-		v538 = v731 - 2;
-		if ( v538 && (v539 = v538 - 1) != 0 && v539 == 1 )
-		{
-			amount = 5 * v2;
-			v540 = 18000 * v2;
-		}
-		else
-		{
-			amount = 4 * v2;
-			v540 = 14400 * v2;
-		}
-		v730 = v540;
-		LODWORD(v733) = v540;
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			break;
-
-		pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
-		pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
-		pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
-		pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
-
-		v732 = v730 << 7;
-		v549 = (double)(v730 << 7) * 0.033333335;
-		*((float *)&v733 + 1) = v549;
-		v712 = (signed __int64)v549;
-		pParty->pPartyBuffs[PARTY_BUFF_RESIST_BODY].Apply(pParty->uTimePlayed + (signed __int64)v549, v731, amount, 0, 0);
-		pParty->pPartyBuffs[PARTY_BUFF_RESIST_MIND].Apply(pParty->uTimePlayed + v712, v731, amount, 0, 0);
-		pParty->pPartyBuffs[PARTY_BUFF_RESIST_FIRE].Apply(pParty->uTimePlayed + v712, v731, amount, 0, 0);
-		pParty->pPartyBuffs[PARTY_BUFF_RESIST_WATER].Apply(pParty->uTimePlayed + v712, v731, amount, 0, 0);
-		pParty->pPartyBuffs[PARTY_BUFF_RESIST_AIR].Apply(pParty->uTimePlayed + v712, v731, amount, 0, 0);
-		pParty->pPartyBuffs[PARTY_BUFF_RESIST_EARTH].Apply(pParty->uTimePlayed + v712, v731, amount, 0, 0);
-		v550 = v2 + 5;
-		pParty->pPartyBuffs[PARTY_BUFF_FEATHER_FALL].Apply(
-			(signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733 + 1)),
-			v731,
-			v550, 0, 0);
-
-		pParty->pPartyBuffs[PARTY_BUFF_WIZARD_EYE].Apply((signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733 + 1)), v731, v550, 0, 0);
+			sRecoveryTime -= v2;
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+
+			pGame->GetStru6()->FadeScreen__like_Turn_Undead_and_mb_Armageddon(0xAFF0Au, 0xC0u);
+			v505 = sub_46A6AC((int)dword_50BF30, 100, 4096);
+			++pSpellSprite.uType;
+			signed int _v733 = v505;
+			v688.x = 0;
+			v688.y = 0;
+			v688.z = 0;
+			pSpellSprite.stru_24.Reset();
+			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_level = v2;
+			pSpellSprite.spell_skill = v731;
+			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+			pSpellSprite.uAttributes = 0;
+			pSpellSprite.uSectorID = 0;
+			pSpellSprite.uSpriteFrameID = 0;
+			pSpellSprite.field_60_distance_related_prolly_lod = 0;
+			pSpellSprite.uFacing = 0;
+			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+			a2 = 0;
+			if ( _v733 > 0 )
+			{
+				do
+				{
+					v507 = dword_50BF30[a2];
+					pSpellSprite.vPosition.x = pActors[v507].vPosition.x;
+					pSpellSprite.vPosition.y = pActors[v507].vPosition.y;
+					pSpellSprite.vPosition.z = pActors[v507].vPosition.z - (unsigned int)(signed __int64)((double)pActors[v507].uActorHeight * unk_4D8548);
+					pSpellSprite.spell_target_pid = PID(OBJECT_Actor, dword_50BF30[a2]);
+					v509 = pSpellSprite.Create(0, 0, 0, 0);
+					v510 = a2;
+					DamageMonsterFromParty(PID(OBJECT_Item, v509), dword_50BF30[a2], &v688);
+					a2 = v510 + 1;
+				}
+				while ( v510 + 1 < _v733 );
+			}
+			for ( a2 = 0; a2 < _v733; ++a2 )
+			{
+				pActor = &pActors[dword_50BF30[a2]];
+				pSpellSprite.vPosition.x = pActor->vPosition.x;
+				pSpellSprite.vPosition.y = pActor->vPosition.y;
+				pSpellSprite.vPosition.z = pActor->vPosition.z - (unsigned int)(signed __int64)((double)pActor->uActorHeight * unk_4D8548);
+				pSpellSprite.spell_target_pid = PID(OBJECT_Actor, dword_50BF30[a2]);
+				pSpellSprite.Create(0, 0, 0, 0);
+				for (int i = 0; i < 22; ++i)
+				{
+					pActor->pActorBuffs[i].Reset();
+				}
+			}
 			LODWORD(v727) = 1;
 			break;
 		}
-
-		case SPELL_LIGHT_HOUR_OF_POWER:
-		{
-		v551 = v731 - 2;
-		if ( v731 == 1 || v731 == 2 )
+		case SPELL_LIGHT_SUMMON_ELEMENTAL:
 		{
-			HIDWORD(v733) = 4;
-			amount = 4;
-		}
-		else if( v731 == 3 )
-		{
-			HIDWORD(v733) = 12;
-			amount = 12;
+			switch (v731)
+			{
+				case 1: v733 = 300 * v2; amount = 1; break;
+				case 2: v733 = 300 * v2; amount = 1; break;
+				case 3: v733 = 900 * v2; amount = 3; break;
+				case 4: v733 = 900 * v2; amount = 5; break;
+				default:
+				assert(false);
+			}
+			//v733 = __PAIR__(0, v516);
+			signed int _v733 = 0;
+			if ( (signed int)uNumActors > 0 )
+			{
+				v518 = pActors;//[0].uAIState;
+				auto _v726 = uNumActors;
+				do
+				{
+					v519 = v518->uAIState;
+					if ( v518->uAIState != 5 && v519 != 11 && v519 != 19 && PID(OBJECT_Player, pCastSpell->uPlayerID) == v518->uSummonerID )
+						++_v733;
+					++v518;
+					--_v726;
+				}
+				while ( _v726 != 0 );
+			}
+			if ( _v733 >= amount )
+			{
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[648], 2);  // This character can't summon any more monsters!
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				pCastSpell->spellnum = 0;
+				continue;
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			sub_44FA4C_spawn_light_elemental(pCastSpell->uPlayerID, v731, v733);
+			LODWORD(v727) = 1;
+			break;
 		}
-		else if( v731 == 4 )
+		case SPELL_LIGHT_DAY_OF_THE_GODS:
 		{
-			amount = 15;
-			HIDWORD(v733) = 20;
-		}
-//LABEL_1000:
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			break;
-		y = (char *)(60 * (v2 * HIDWORD(v733) + 60));
-		v732 = (300 * amount * v2 + 60) << 7;
-		v730 = v2 + 5;
-		int _v726 = 0;
-		v553 = pParty->pPlayers;//[0].pConditions[1];
-		*((float *)&v733 + 1) = (double)v732 * 0.033333335;
-		do
-		{
+			switch (v731)
+			{
+				case 1: LODWORD(v733) = 10800 * v2; amount = 3 * v2 + 10; break;
+				case 2: LODWORD(v733) = 10800 * v2; amount = 3 * v2 + 10; break;
+				case 3: LODWORD(v733) = 14400 * v2; amount = 4 * v2 + 10; break;
+				case 4: LODWORD(v733) = 18000 * v2; amount = 5 * v2 + 10; break;
+				default:
+				assert(false);
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+
 			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
 			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
 			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
 			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
 
-			//((SpellBuff *)(v553 + 6056))->Apply(
-			v553->pPlayerBuffs[4].Apply((signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733 + 1)), v731, v730, 0, 0);
-			if ( *(_QWORD *)v553 )
-			_v726 = 1;
-			++v553;
+			pParty->pPartyBuffs[PARTY_BUFF_DAY_OF_GODS].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, amount, 0, 0);
+			LODWORD(v727) = 1;
+			break;
 		}
-		while ( v553 <= &pParty->pPlayers[3] );
-		v562 = v731;
-		pParty->pPartyBuffs[PARTY_BUFF_HEROISM].Apply((signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733 + 1)), v731, v730, 0, 0);
-		pParty->pPartyBuffs[PARTY_BUFF_SHIELD].Apply((signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733 + 1)), v562, 0, 0, 0);
-		pParty->pPartyBuffs[PARTY_BUFF_STONE_SKIN].Apply((signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733 + 1)), v562, v730, 0, 0);
-		if (!_v726)
+		case SPELL_LIGHT_PRISMATIC_LIGHT:
 		{
-			pParty->pPartyBuffs[PARTY_BUFF_HASTE].Apply((signed __int64)((double)(signed int)((int)y << 7) * 0.033333335 + (double)(signed __int64)pParty->uTimePlayed), v562, v730, 0, 0);
-		}
+			//v67 = 2;
+			if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor)
+			{
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[497], 2);  // Can't cast Prismatic Light outdoors!
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				pCastSpell->spellnum = 0;
+				continue;
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			v531 = sub_46A6AC((int)dword_50BF30, 100, 4096);
+			++pSpellSprite.uType;
+			v694.x = 0;
+			v694.y = 0;
+			v694.z = 0;
+			pSpellSprite.stru_24.Reset();
+			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_level = v2;
+			pSpellSprite.spell_skill = v731;
+			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+			pSpellSprite.uAttributes = 0;
+			pSpellSprite.uSectorID = 0;
+			pSpellSprite.uSpriteFrameID = 0;
+			pSpellSprite.field_60_distance_related_prolly_lod = 0;
+			pSpellSprite.uFacing = 0;
+			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+			a2 = 0;
+			if ( (signed int)v531 > 0 )
+			{
+				do
+				{
+					v533 = dword_50BF30[a2];
+					pSpellSprite.vPosition.x = pActors[v533].vPosition.x;
+					pSpellSprite.vPosition.y = pActors[v533].vPosition.y;
+					pSpellSprite.vPosition.z = pActors[v533].vPosition.z - (unsigned int)(signed __int64)((double)pActors[v533].uActorHeight * unk_4D8548);
+					pSpellSprite.spell_target_pid = PID(OBJECT_Actor, dword_50BF30[a2]);
+					v535 = pSpellSprite.Create(0, 0, 0, 0);
+					v536 = a2;
+					DamageMonsterFromParty(PID(OBJECT_Item, v535), dword_50BF30[a2], &v694);
+					a2 = v536 + 1;
+				}
+				while ( v536 + 1 < (signed int)v531 );
+			}
+			v537 = pGame->GetStru6();
+			pGame->GetStru6()->_4A8BFC();
 			LODWORD(v727) = 1;
 			break;
 		}
-
-
-		case SPELL_LIGHT_DIVINE_INTERVENTION:
-			{
-		amount = 3;
-		if ( pPlayer->uNumDivineInterventionCastsThisDay >= 3u )
-		{
-			ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
-			pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-			pCastSpell->spellnum = 0;
-			continue;
-		}
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			break;
-		a2 = 0;
-		_this = (ItemGen *)&pPlayers[1];
-		do
-		{
-			v563 = 0;
-			do
-			{
-			v564 = _this->uItemID;
-			*(int *)(v563 + _this->uItemID) = 0;
-			v563 += 8;
-			*(int *)(v563 + v564 - 4) = 0;
-			}
-			while ( v563 <= 128 );
-			v565 = ((Player *)_this->uItemID)->GetMaxHealth();
-			v566 = (Player **)_this;
-			*(int *)(_this->uItemID + 6460) = v565;
-			v567 = (*v566)->GetMaxMana();
-			*(int *)(_this->uItemID + 6464) = v567;
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, a2);
-			++a2;
-			_this = (ItemGen *)((char *)_this + 4);
-		}
-		while ( (signed int)this < (signed int)&qword_A750D8 );
-		v571 = pPlayer;
-		v572 = (char *)&pPlayer->sAgeModifier;
-		if ( pPlayer->sAgeModifier + 10 >= 120 )
-			*(short *)v572 = 120;
-		else
-			*(short *)v572 = pPlayer->sAgeModifier + 10;
-		sRecoveryTime += -5 * v2;
-		++v571->uNumDivineInterventionCastsThisDay;
-			LODWORD(v727) = 1;
-			break;
-			}
-		case SPELL_DARK_REANIMATE:
-			{
-		v573 = v731 - 2;
-		if ( v573 )
-		{
-			v574 = v573 - 1;
-			if ( v574 )
-			{
-			if ( v574 == 1 )
-				v575 = 5 * v2;
-			else
-				v575 = 2 * v2;
-			}
-			else
-			{
-			v575 = 4 * v2;
-			}
-		}
-		else
-		{
-			v575 = 3 * v2;
-		}
-		amount = v575;
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			break;
-		v576 = pCastSpell->spell_target_pid;
-		if (!v576)
-		{
-			v585 = (char *)&pParty->pPlayers[pCastSpell->uPlayerID_2];
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
-			if ( *((_QWORD *)v585 + 14) )
-			{
-			((Player *)v585)->SetCondition(0x11u, 1);
-			v587 = ((Player *)v585)->GetSexByVoice();
-			ReloadPlayerPortraits(pCastSpell->uPlayerID_2, (v587 != 0) + 23);
-			*((_QWORD *)v585 + 17) = pParty->uTimePlayed;
-			}
-			break;
-		}
-		v577 = (Player *)(PID_ID(v576));
-		//v726 = v577;
-		if ( v577 == (Player *)-1 )
-		{
-			ShowStatusBarString(pGlobalTXT_LocalizationStrings[496], 2);  // No valid target exists!
-			pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-			pCastSpell->spellnum = 0;
-			continue;
-		}
-		v578 = (int)&pActors[(int)v577];
-		v721 = v578;
-		if ( *(short *)(v578 + 40) > 0 || (v579 = *(short *)(v578 + 176), v579 != 5) && v579 != 4 )
+		case SPELL_LIGHT_DAY_OF_PROTECTION:
 		{
-			ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
-			pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-			pCastSpell->spellnum = 0;
-			continue;
-		}
-		++pSpellSprite.uType;
-		pSpellSprite.stru_24.Reset();
-		pSpellSprite.spell_id = pCastSpell->spellnum;
-		pSpellSprite.spell_level = v2;
-		pSpellSprite.spell_skill = v731;
-		pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-		pSpellSprite.uAttributes = 0;
-		pSpellSprite.uSectorID = 0;
-		pSpellSprite.uSpriteFrameID = 0;
-		pSpellSprite.field_60_distance_related_prolly_lod = 0;
-		v581 = v721;
-		pSpellSprite.uFacing = 0;
-		pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-		pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-		pSpellSprite.vPosition.x = *(short *)(v721 + 142);
-		pSpellSprite.vPosition.y = *(short *)(v721 + 144);
-		v732 = *(short *)(v721 + 138);
-		pSpellSprite.vPosition.z = *(short *)(v721 + 146) - (unsigned int)(signed __int64)((double)v732 * unk_4D8548);
-		pSpellSprite.spell_target_pid = PID(OBJECT_Actor, (int)v577);
-		pSpellSprite.Create(0, 0, 0, 0);
-		if ( *(char *)(v581 + 52) > amount )
-			break;
-		Actor::Resurrect((unsigned int)v577);
-		*(char *)(v581 + 61) = 0;
-		*(char *)(v581 + 53) = 0;
-		*(char *)(v581 + 54) = 0;
-		*(char *)(v581 + 55) = 0;
-		*(char *)(v581 + 56) = 0;
-		*(char *)(v581 + 57) = 0;
-		*(int *)(v581 + 712) = 9999;
-		*(char *)(v581 + 38) &= 0xF7u;
-		*(int *)(v581 + 708) = 0;
-		((SpellBuff *)(v581 + 356))->Reset();
-		((SpellBuff *)(v581 + 228))->Reset();
-		((SpellBuff *)(v581 + 404))->Reset();
-		if ( *(short *)(v581 + 40) > 10 * amount )
-			*(short *)(v581 + 40) = 10 * amount;
-			LODWORD(v727) = 1;
-			break;
-			}
-		case SPELL_DARK_VAMPIRIC_WEAPON:
-			{
-		v588 = v731 - 1;
-		amount = 16;
-		if ( v588 && (v589 = v588 - 1) != 0 && (v590 = v589 - 1) != 0 )
-		{
-			if ( v590 == 1 )
-			LODWORD(v733) = 0;
-		}
-		else
-		{
-			LODWORD(v733) = 3600 * v2;
-		}
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			break;
-		__debugbreak();
-		HIDWORD(v733) = (int)(char *)&pParty + 6972 * pCastSpell->uPlayerID_2 + 36 * a2 + 3040;
-		v732 = (signed int)&pItemsTable->pItems[*(int *)HIDWORD(v733)].pIconName;
-		((ItemGen *)HIDWORD(v733))->UpdateTempBonus(pParty->uTimePlayed);
-		if ( *(int *)HIDWORD(v733) >= 64 && *(int *)HIDWORD(v733) <= 65
-			|| *(char *)(HIDWORD(v733) + 20) & 2
-			|| *(int *)(HIDWORD(v733) + 12) != 0
-			|| *(int *)(HIDWORD(v733) + 4) != 0
-			|| (v591 = *(char *)(v732 + 28)) != 0 && v591 != 1 && v591 != 2
-			|| pItemsTable->IsMaterialNonCommon((ItemGen *)HIDWORD(v733)) )
-		{
-			dword_50C9D0 = 113;
-			dword_50C9D4 = 0;
-			dword_50C9D8 = 1;
-
-			ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
-			pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-			pCastSpell->spellnum = 0;
-			continue;
-		}
-		v592 = HIDWORD(v733);
-		v14 = v731 == 4;
-		*(int *)(HIDWORD(v733) + 12) = 16;
-		if ( !v14 )
-		{
-			v732 = (int)v733 << 7;
-			*(_QWORD *)(v592 + 28) = pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
-			*(int *)(v592 + 20) |= 8u;
-		}
-		*(char *)(v592 + 20) |= 0x80u;
-		_50C9A8_item_enchantment_timer = 256;
-		LODWORD(v727) = 1;
-		break;
-			}
-		case SPELL_DARK_SHARPMETAL:
-		{
-		v593 = v731 - 2;
-		if( v731 == 1 || v731 == 2 )
-			amount = 5;
-		else if( v731 == 3 )
-			amount = 7;
-		else if( v731 == 4 )
-			amount = 9;
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			break;
-		auto _v726 = ((signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360);
-		pSpellSprite.stru_24.Reset();
-		pSpellSprite.spell_id = pCastSpell->spellnum;
-		pSpellSprite.spell_level = v2;
-		pSpellSprite.spell_skill = v731;
-		pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-		pSpellSprite.vPosition.x = pParty->vPosition.x;
-		pSpellSprite.vPosition.y = pParty->vPosition.y;
-		pSpellSprite.uAttributes = 0;
-		pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 2;
-		pSpellSprite.uSectorID = pIndoor->GetSector(
-							pParty->vPosition.x,
-							pParty->vPosition.y,
-							pParty->vPosition.z + (signed int)pParty->uPartyHeight / 2);
-		pSpellSprite.uSpriteFrameID = 0;
-		pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-		pSpellSprite.spell_target_pid = a2;
-		pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
-		pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-		if ( pParty->bTurnBasedModeOn == 1 )
-			LOBYTE(pSpellSprite.uAttributes) |= 4u;
-		v596 = (signed int)_v726 / -2;
-		y = (char *)((signed int)_v726 / 2);
-		if ( (signed int)_v726 / -2 <= (signed int)_v726 / 2 )
-		{
-			v597 = v715.uYawAngle;
-			do
-			{
-			pSpellSprite.uFacing = v596 + v597;
-			if ( pSpellSprite.Create(
-					v596 + v597,
-					v715.uPitchAngle,
-					pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed,
-					pCastSpell->uPlayerID + 1) != -1
-				&& pParty->bTurnBasedModeOn == 1 )
-				++pTurnEngine->field_1C;
-			v596 += _v726 / (amount - 1);
-			}
-			while ( v596 <= (signed int)y );
-		}
+			switch (v731)
+			{
+				case 1: LODWORD(v733) = 14400 * v2; amount = 4 * v2; break;
+				case 2: LODWORD(v733) = 14400 * v2; amount = 4 * v2; break;
+				case 3: LODWORD(v733) = 14400 * v2; amount = 4 * v2; break;
+				case 4: LODWORD(v733) = 18000 * v2; amount = 5 * v2; break;
+				default:
+				assert(false);
+			}
+			v730 = LODWORD(v733);
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
+
+			v732 = v730 << 7;
+			v549 = (double)(v730 << 7) * 0.033333335;
+			*((float *)&v733 + 1) = v549;
+			v712 = (signed __int64)v549;
+			pParty->pPartyBuffs[PARTY_BUFF_RESIST_BODY].Apply(pParty->uTimePlayed + (signed __int64)v549, v731, amount, 0, 0);
+			pParty->pPartyBuffs[PARTY_BUFF_RESIST_MIND].Apply(pParty->uTimePlayed + v712, v731, amount, 0, 0);
+			pParty->pPartyBuffs[PARTY_BUFF_RESIST_FIRE].Apply(pParty->uTimePlayed + v712, v731, amount, 0, 0);
+			pParty->pPartyBuffs[PARTY_BUFF_RESIST_WATER].Apply(pParty->uTimePlayed + v712, v731, amount, 0, 0);
+			pParty->pPartyBuffs[PARTY_BUFF_RESIST_AIR].Apply(pParty->uTimePlayed + v712, v731, amount, 0, 0);
+			pParty->pPartyBuffs[PARTY_BUFF_RESIST_EARTH].Apply(pParty->uTimePlayed + v712, v731, amount, 0, 0);
+			v550 = v2 + 5;
+			pParty->pPartyBuffs[PARTY_BUFF_FEATHER_FALL].Apply(
+				(signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733 + 1)),
+				v731,
+				v550, 0, 0);
+
+			pParty->pPartyBuffs[PARTY_BUFF_WIZARD_EYE].Apply((signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733 + 1)), v731, v550, 0, 0);
 			LODWORD(v727) = 1;
 			break;
 		}
-
-		case SPELL_DARK_CONTROL_UNDEAD:
+		case SPELL_LIGHT_HOUR_OF_POWER:
 		{
+			switch (v731)
+			{
+				case 1: LODWORD(v733) = 4; amount = 4; break;
+				case 2: LODWORD(v733) = 4; amount = 4; break;
+				case 3: LODWORD(v733) = 12; amount = 12; break;
+				case 4: LODWORD(v733) = 20; amount = 15; break;
+				default:
+				assert(false);
+			}
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
-			if ( v731 == 1 || v731 == 2 )
-			{
-				v598 = 180 * v2;
-				LODWORD(v733) = v598;
-			}
-			else if ( v731 == 3 )
-			{
-				v598 = 300 * v2;
-				LODWORD(v733) = v598;
-			}
-			else if ( v731 == 4 )
-				LODWORD(v733) = 29030400;
-//	LABEL_1082:
-			if (PID_TYPE(a2) != OBJECT_Actor)
-			{
-				LODWORD(v727) = 1;
-				break;
-			}
-			v730 = 836 * PID_ID(a2);
-			if ( !MonsterStats::BelongsToSupertype(pActors[PID_ID(a2)].pMonsterInfo.uID, MONSTER_SUPERTYPE_UNDEAD) )
-				break;
-			if ( !stru_50C198.GetMagicalResistance(&pActors[PID_ID(a2)], 0xAu) )
+			y = (char *)(60 * (v2 * LODWORD(v733) + 60));
+			v732 = (300 * amount * v2 + 60) << 7;
+			v730 = v2 + 5;
+			int _v726 = 0;
+			v553 = pParty->pPlayers;//[0].pConditions[1];
+			*((float *)&v733) = (double)v732 * 0.033333335;
+			do
+			{
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
+
+				//((SpellBuff *)(v553 + 6056))->Apply(
+				v553->pPlayerBuffs[4].Apply((signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733)), v731, v730, 0, 0);
+				if ( *(_QWORD *)v553 )
+					_v726 = 1;
+				++v553;
+			}
+			while ( v553 <= &pParty->pPlayers[3] );
+			v562 = v731;
+			pParty->pPartyBuffs[PARTY_BUFF_HEROISM].Apply((signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733)), v731, v730, 0, 0);
+			pParty->pPartyBuffs[PARTY_BUFF_SHIELD].Apply((signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733)), v562, 0, 0, 0);
+			pParty->pPartyBuffs[PARTY_BUFF_STONE_SKIN].Apply((signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733)), v562, v730, 0, 0);
+			if (!_v726)
+			{
+				pParty->pPartyBuffs[PARTY_BUFF_HASTE].Apply((signed __int64)((double)(signed int)((int)y << 7) * 0.033333335 + (double)(signed __int64)pParty->uTimePlayed), v562, v730, 0, 0);
+			}
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_LIGHT_DIVINE_INTERVENTION:
+		{
+			amount = 3;
+			if ( pPlayer->uNumDivineInterventionCastsThisDay >= 3u )
 			{
 				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
 				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
 				pCastSpell->spellnum = 0;
 				continue;
 			}
-			pActors[PID_ID(a2)].pActorBuffs[9].Reset();
-			pActors[PID_ID(a2)].pActorBuffs[1].Reset();
-			pActors[PID_ID(a2)].pActorBuffs[12].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335),
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			a2 = 0;
+			_this = (ItemGen *)&pPlayers[1];
+			do
+			{
+				v563 = 0;
+				do
+				{
+					v564 = _this->uItemID;
+					*(int *)(v563 + _this->uItemID) = 0;
+					v563 += 8;
+					*(int *)(v563 + v564 - 4) = 0;
+				}
+				while ( v563 <= 128 );
+				v565 = ((Player *)_this->uItemID)->GetMaxHealth();
+				v566 = (Player **)_this;
+				*(int *)(_this->uItemID + 6460) = v565;
+				v567 = (*v566)->GetMaxMana();
+				*(int *)(_this->uItemID + 6464) = v567;
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, a2);
+				++a2;
+				_this = (ItemGen *)((char *)_this + 4);
+			}
+			while ( (signed int)this < (signed int)&qword_A750D8 );
+			v571 = pPlayer;
+			v572 = (char *)&pPlayer->sAgeModifier;
+			if ( pPlayer->sAgeModifier + 10 >= 120 )
+				*(short *)v572 = 120;
+			else
+				*(short *)v572 = pPlayer->sAgeModifier + 10;
+			sRecoveryTime += -5 * v2;
+			++v571->uNumDivineInterventionCastsThisDay;
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_DARK_REANIMATE:
+		{
+			switch (v731)
+			{
+				case 1: amount = 2 * v2; break;
+				case 2: amount = 3 * v2; break;
+				case 3: amount = 4 * v2; break;
+				case 4: amount = 5 * v2; break;
+				default:
+				assert(false);
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			v576 = pCastSpell->spell_target_pid;
+			if (!v576)
+			{
+				v585 = (char *)&pParty->pPlayers[pCastSpell->uPlayerID_2];
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+				if ( *((_QWORD *)v585 + 14) )
+				{
+				((Player *)v585)->SetCondition(0x11u, 1);
+				v587 = ((Player *)v585)->GetSexByVoice();
+				ReloadPlayerPortraits(pCastSpell->uPlayerID_2, (v587 != 0) + 23);
+				*((_QWORD *)v585 + 17) = pParty->uTimePlayed;
+				}
+				break;
+			}
+			v577 = (Player *)(PID_ID(v576));
+			//v726 = v577;
+			if ( v577 == (Player *)-1 )
+			{
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[496], 2);  // No valid target exists!
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				pCastSpell->spellnum = 0;
+				continue;
+			}
+			v578 = (int)&pActors[(int)v577];
+			v721 = v578;
+			if ( *(short *)(v578 + 40) > 0 || (v579 = *(short *)(v578 + 176), v579 != 5) && v579 != 4 )
+			{
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				pCastSpell->spellnum = 0;
+				continue;
+			}
+			++pSpellSprite.uType;
+			pSpellSprite.stru_24.Reset();
+			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_level = v2;
+			pSpellSprite.spell_skill = v731;
+			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+			pSpellSprite.uAttributes = 0;
+			pSpellSprite.uSectorID = 0;
+			pSpellSprite.uSpriteFrameID = 0;
+			pSpellSprite.field_60_distance_related_prolly_lod = 0;
+			v581 = v721;
+			pSpellSprite.uFacing = 0;
+			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+			pSpellSprite.vPosition.x = *(short *)(v721 + 142);
+			pSpellSprite.vPosition.y = *(short *)(v721 + 144);
+			v732 = *(short *)(v721 + 138);
+			pSpellSprite.vPosition.z = *(short *)(v721 + 146) - (unsigned int)(signed __int64)((double)v732 * unk_4D8548);
+			pSpellSprite.spell_target_pid = PID(OBJECT_Actor, (int)v577);
+			pSpellSprite.Create(0, 0, 0, 0);
+			if ( *(char *)(v581 + 52) > amount )
+				break;
+			Actor::Resurrect((unsigned int)v577);
+			*(char *)(v581 + 61) = 0;
+			*(char *)(v581 + 53) = 0;
+			*(char *)(v581 + 54) = 0;
+			*(char *)(v581 + 55) = 0;
+			*(char *)(v581 + 56) = 0;
+			*(char *)(v581 + 57) = 0;
+			*(int *)(v581 + 712) = 9999;
+			*(char *)(v581 + 38) &= 0xF7u;
+			*(int *)(v581 + 708) = 0;
+			((SpellBuff *)(v581 + 356))->Reset();
+			((SpellBuff *)(v581 + 228))->Reset();
+			((SpellBuff *)(v581 + 404))->Reset();
+			if ( *(short *)(v581 + 40) > 10 * amount )
+				*(short *)(v581 + 40) = 10 * amount;
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_DARK_VAMPIRIC_WEAPON:
+		{
+			amount = 16;
+			if ( v731 == 4 )
+			{
+				LODWORD(v733) = 0;
+			}
+			else
+			{
+				LODWORD(v733) = 3600 * v2;
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			__debugbreak();
+			//HIDWORD(v733) = (int)(char *)&pParty + 6972 * pCastSpell->uPlayerID_2 + 36 * a2 + 3040;
+			ItemGen *_v733 = &pParty->pPlayers[pCastSpell->uPlayerID_2].pInventoryItems[a2];
+			ItemDesc *_v732 = &pItemsTable->pItems[_v733->uItemID];
+			_v733->UpdateTempBonus(pParty->uTimePlayed);
+			if ( _v733->uItemID >= 64 && _v733->uItemID <= 65
+				|| LOBYTE(_v733->uAttributes) & 2
+				|| _v733->uSpecEnchantmentType != 0
+				|| _v733->uEnchantmentType != 0
+				|| (v591 = _v732->uEquipType) != 0 && v591 != 1 && v591 != 2
+				|| pItemsTable->IsMaterialNonCommon(_v733) )
+			{
+				dword_50C9D0 = 113;
+				dword_50C9D4 = 0;
+				dword_50C9D8 = 1;
+
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				pCastSpell->spellnum = 0;
+				continue;
+			}
+			v592 = _v733;
+			v14 = v731 == 4;
+			_v733->uSpecEnchantmentType = 16;
+			if ( !v14 )
+			{
+				v732 = (int)v733 << 7;
+				v592->uExpireTime = pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
+				v592->uAttributes |= 8u;
+			}
+			LOBYTE(v592->uAttributes) |= 0x80u;
+			_50C9A8_item_enchantment_timer = 256;
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_DARK_SHARPMETAL:
+		{
+			switch (v731)
+			{
+				case 1: amount = 5; break;
+				case 2: amount = 5; break;
+				case 3: amount = 7; break;
+				case 4: amount = 9; break;
+				default:
+				assert(false);
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			auto _v726 = ((signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360);
+			pSpellSprite.stru_24.Reset();
+			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_level = v2;
+			pSpellSprite.spell_skill = v731;
+			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+			pSpellSprite.vPosition.x = pParty->vPosition.x;
+			pSpellSprite.vPosition.y = pParty->vPosition.y;
+			pSpellSprite.uAttributes = 0;
+			pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 2;
+			pSpellSprite.uSectorID = pIndoor->GetSector(
+								pParty->vPosition.x,
+								pParty->vPosition.y,
+								pParty->vPosition.z + (signed int)pParty->uPartyHeight / 2);
+			pSpellSprite.uSpriteFrameID = 0;
+			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+			pSpellSprite.spell_target_pid = a2;
+			pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
+			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+			if ( pParty->bTurnBasedModeOn == 1 )
+				LOBYTE(pSpellSprite.uAttributes) |= 4u;
+			v596 = (signed int)_v726 / -2;
+			y = (char *)((signed int)_v726 / 2);
+			if ( (signed int)_v726 / -2 <= (signed int)_v726 / 2 )
+			{
+				v597 = v715.uYawAngle;
+				do
+				{
+					pSpellSprite.uFacing = v596 + v597;
+					if ( pSpellSprite.Create(
+							v596 + v597,
+							v715.uPitchAngle,
+							pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed,
+							pCastSpell->uPlayerID + 1) != -1
+							&& pParty->bTurnBasedModeOn == 1 )
+						++pTurnEngine->field_1C;
+					v596 += _v726 / (amount - 1);
+				}
+				while ( v596 <= (signed int)y );
+			}
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_DARK_CONTROL_UNDEAD:
+		{
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			switch (v731)
+			{
+				case 1: LODWORD(v733) = 180 * v2; break;
+				case 2: LODWORD(v733) = 180 * v2; break;
+				case 3: LODWORD(v733) = 300 * v2; break;
+				case 4: LODWORD(v733) = 29030400; break;
+				default:
+				assert(false);
+			}
+			if (PID_TYPE(a2) != OBJECT_Actor)
+			{
+				LODWORD(v727) = 1;
+				break;
+			}
+			pActor = &pActors[PID_ID(a2)];
+			if ( !MonsterStats::BelongsToSupertype(pActor->pMonsterInfo.uID, MONSTER_SUPERTYPE_UNDEAD) )
+				break;
+			if ( !stru_50C198.GetMagicalResistance(pActor, 0xAu) )
+			{
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				pCastSpell->spellnum = 0;
+				continue;
+			}
+			pActor->pActorBuffs[9].Reset();
+			pActor->pActorBuffs[1].Reset();
+			pActor->pActorBuffs[12].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335),
 				v731, 0, 0, 0);
 			pSpellSprite.stru_24.Reset();
 			pSpellSprite.spell_id = pCastSpell->spellnum;
 			pSpellSprite.spell_level = v2;
 			pSpellSprite.spell_skill = v731;
 			v60 = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-			v61 = PID_ID(a2);
-//	LABEL_1086:
-			v600 = pActors[v61].vPosition.y;
-			v601 = pActors[v61].vPosition.x;
+			
+			v600 = pActor->vPosition.y;
+			v601 = pActor->vPosition.x;
 			pSpellSprite.uObjectDescID = v60;
 			pSpellSprite.vPosition.x = v601;
-			v602 = pActors[v61].uActorHeight;
-			v603 = pActors[v61].vPosition.z;
+			v602 = pActor->uActorHeight;
+			v603 = pActor->vPosition.z;
 			pSpellSprite.vPosition.y = v600;
 			v676 = v603 + v602;
 			v665 = v600;
 			pSpellSprite.vPosition.z = v603 + v602;
 			v657 = v601;
-//	LABEL_1087:
 			pSpellSprite.uAttributes = 0;
 			pSpellSprite.uSectorID = pIndoor->GetSector(v657, v665, v676);
 			pSpellSprite.uSpriteFrameID = 0;
@@ -7261,41 +6175,41 @@
 		{
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
-			HIDWORD(v733) = 0;
+			int _v733 = 0;
 			memset(&achieved_awards, 0, 4000);
-			_this = 0;
-			v605 = (char *)pParty->pHirelings;
+			int i = 0;
+			pNPCData = pParty->pHirelings;
 			do
 			{
-				if ( *(int *)v605)
+				if ( pNPCData->pName != 0)
 				{
-					v606 = HIDWORD(v733)++;
-					achieved_awards[v606] = (AwardType)(int)((char *)&_this->uItemID + 1);
+					v606 = _v733++;
+					achieved_awards[v606] = (AwardType)(i + 1);
 				}
-				_this = (ItemGen *)((char *)_this + 1);
-				v605 += 76;
-			}
-			while ( (signed int)v605 < (signed int)&pParty->pPickedItem );
-			_this = 0;
+				++i;
+				++pNPCData;
+			}
+			while ( pNPCData <= &pParty->pHirelings[1] );
+			i = 0;
 			if ( (signed int)pNPCStats->uNumNewNPCs > 0)
 			{
-				v730 = (int)pNPCStats->pNewNPCData;
+				pNPCData = pNPCStats->pNewNPCData;
 				__debugbreak(); // data offset
-				HIDWORD(v733) = 4 * HIDWORD(v733) + 6043152;
+				AwardType *_v734 = &achieved_awards[_v733];
 				do
 				{
-					if ( *(char *)(v730 + 8) & 0x80
-						&& (!pParty->pHirelings[0].pName || strcmp(*(const char **)v730, pParty->pHirelings[0].pName))
-						&& (!pParty->pHirelings[1].pName || strcmp(*(const char **)v730, pParty->pHirelings[1].pName)) )
+					if ( pNPCData->uFlags & 0x80
+						&& (!pParty->pHirelings[0].pName || strcmp(pNPCData->pName, pParty->pHirelings[0].pName))
+						&& (!pParty->pHirelings[1].pName || strcmp(pNPCData->pName, pParty->pHirelings[1].pName)) )
 					{
-						v607 = HIDWORD(v733);
-						HIDWORD(v733) += 4;
-						*(int *)v607 = (int)_this + 3;
+						v607 = _v734;
+						++_v734;
+						*v607 = (AwardType)(i + 3);
 					}
-					_this = (ItemGen *)((char *)_this + 1);
-					v730 += 76;
+					++i;
+					++pNPCData;
 				}
-				while ( (signed int)this < (signed int)pNPCStats->uNumNewNPCs );
+				while ( (signed int)i < (signed int)pNPCStats->uNumNewNPCs );
 			}
 			v608 = pCastSpell->uPlayerID_2;
 			if ( v608 != 4 && v608 != 5
@@ -7310,8 +6224,11 @@
 			v610 = 76 * v609;
 			*((int *)&pParty->pPlayers[3].pInstalledBeacons[4].uBeaconTime + 19 * v609) = 0;
 			v611 = pIconsFrameTable->FindIcon("spell96");
-			*(int *)((char *)&pParty->pPlayers[3].pInstalledBeacons[4].uBeaconTime + v610 + 4) = pIconsFrameTable->GetIconAnimLength(v611);
-			*(int *)((char *)&pParty->pPlayers[3].pInstalledBeacons[3].field_18 + v610) = 1;
+			//*(int *)((char *)&pParty->pPlayers[3].pInstalledBeacons[4].uBeaconTime + v610 + 4) = pIconsFrameTable->GetIconAnimLength(v611);
+			pParty->pHirelings[v609-1].evt_B = pIconsFrameTable->GetIconAnimLength(v611);
+			//*(int *)((char *)&pParty->pPlayers[3].pInstalledBeacons[3].field_18 + v610) = 1;
+			pParty->pHirelings[v609-1].field_24 = 1;
+
 			v612 = pParty->pPlayers;
 			do
 			{
@@ -7331,27 +6248,22 @@
 		}
 		case SPELL_DARK_PAIN_REFLECTION:
 		{
-			if ( v731 > 0 && v731 <= 4 )
-			{
-				if ( v731 <= 3 )
-				{
-					v614 = 300 * (v2 + 12);
-				}
-				if ( v731 == 4 )
-				{
-					v614 = 900 * (v2 + 4);
-				}
-				LODWORD(v733) = v614;
-			}
-			v615 = v2 + 5;
-			amount = v615;
+			switch (v731)
+			{
+				case 1: LODWORD(v733) = 300 * (v2 + 12); break;
+				case 2: LODWORD(v733) = 300 * (v2 + 12); break;
+				case 3: LODWORD(v733) = 300 * (v2 + 12); break;
+				case 4: LODWORD(v733) = 900 * (v2 + 4); break;
+				default:
+				assert(false);
+			}
+			amount = v2 + 5;
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
 			if ( v731 != 3 && v731 != 4 )
 			{
 				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
-
-				pParty->pPlayers[pCastSpell->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_PAIN_REFLECTION].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, v615, v716, 0);
+				pParty->pPlayers[pCastSpell->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_PAIN_REFLECTION].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, amount, v716, 0);
 				LODWORD(v727) = 1;
 				break;
 			}
@@ -7375,7 +6287,7 @@
 				break;
 			pGame->GetIndoorCamera();
 			v623 = (signed __int64)pGame->pIndoorCameraD3D->GetPickDepth();
-			HIDWORD(v733) = sub_46A6AC((int)dword_50BF30, 100, v623);
+			signed int _v733 = sub_46A6AC((int)dword_50BF30, 100, v623);
 			v707.x = 0;
 			v707.y = 0;
 			v707.z = 0;
@@ -7393,9 +6305,9 @@
 			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
 			a2 = 0;
 			int _v726 = 0;
-			if ( SHIDWORD(v733) > 0 )
-			{
-				_v726 = (HIDWORD(v733) * (7 * v2 + 25));
+			if ( _v733 > 0 )
+			{
+				_v726 = (_v733 * (7 * v2 + 25));
 				do
 				{
 					v625 = dword_50BF30[a2];
@@ -7409,7 +6321,7 @@
 					DamageMonsterFromParty(PID(OBJECT_Item, v627), dword_50BF30[a2], &v707);
 					a2 = v628 + 1;
 				}
-				while ( v628 + 1 < SHIDWORD(v733) );
+				while ( v628 + 1 < _v733 );
 			}
 			v730 = 0;
 			v629 = 1;
@@ -7430,31 +6342,30 @@
 			}
 			while ( v629 <= 4 );
 			v732 = (signed __int64)((double)(signed int)_v726 / (double)v730);
-			HIDWORD(v733) = 0;
+			_v733 = 0;
 			if ( v730 > 0 )
 			{
 				do
 				{
 					//v632 = 4 * v681[HIDWORD(v733)] + 10965188;
-					v726 = pPlayers[v681[HIDWORD(v733)]];
+					v726 = pPlayers[v681[_v733]];
 					//v633 = pPlayers[v681[HIDWORD(v733)]];
 					v726->sHealth += v732;
 					//v726 = *(Player **)v632;
 					//v634 = v726->GetMaxHealth();
 					if ( v726->sHealth > v726->GetMaxHealth())
 						v726->sHealth = v726->GetMaxHealth();
-					v635 = HIDWORD(v733);
+					v635 = _v733;
 
 					pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, WORD2(v733));
-					HIDWORD(v733) = v635 + 1;
-					}
-					while ( v635 + 1 < v730 );
+					_v733 = v635 + 1;
+				}
+				while ( v635 + 1 < v730 );
 			}
 			pGame->GetStru6()->FadeScreen__like_Turn_Undead_and_mb_Armageddon(0, 0x40u);
 			LODWORD(v727) = 1;
 			break;
 		}
-
 		case SPELL_DARK_ARMAGEDDON:
 		{
 			if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
@@ -7464,8 +6375,9 @@
 				pCastSpell->spellnum = 0;
 				continue;
 			}
-			v640 = v731 - 2;
-			if ( !v640 || (v641 = v640 - 1) == 0 || (amount = 4, v641 != 1) )
+			if ( v731 == 4)
+				amount = 4;
+			else
 				amount = 3;
 			if ( pPlayer->uNumArmageddonCasts >= amount || pParty->armageddon_timer > 0 )
 			{
@@ -8787,13 +7699,14 @@
             }
             else
             {
-              if ( dword_50C9E8 < 40 )
-              {
-                dword_50C9EC[3 * dword_50C9E8] = 25;
-                dword_50C9EC[3 * dword_50C9E8 + 1] = 0;
-                dword_50C9EC[3 * dword_50C9E8 + 2] = 0;
-                ++dword_50C9E8;
-              }
+            /*  if ( dword_50C9E8 < 40 )
+            {
+            dword_50C9EC[3 * dword_50C9E8] = 25;
+            dword_50C9EC[3 * dword_50C9E8 + 1] = 0;
+            dword_50C9EC[3 * dword_50C9E8 + 2] = 0;
+            ++dword_50C9E8;
+            }*/
+            pMessageQueue_50C9E8->AddMessage(UIMSG_CastQuickSpell, 0, 0);
             }
             break;
           case INPUT_Attack:
@@ -8832,12 +7745,13 @@
             }
             break;
           case INPUT_CharCycle:
-            if ( pCurrentScreen == SCREEN_SPELL_BOOK || dword_50C9E8 >= 40 )
+            if ( pCurrentScreen == SCREEN_SPELL_BOOK  )
               break;
-            dword_50C9EC[3 * dword_50C9E8] = 176;
+           /* dword_50C9EC[3 * dword_50C9E8] = 176;|| dword_50C9E8 >= 40
             dword_50C9EC[3 * dword_50C9E8 + 1] = 0;
             dword_50C9EC[3 * dword_50C9E8 + 2] = 0;
-            ++dword_50C9E8;
+            ++dword_50C9E8;*/
+            pMessageQueue_50C9E8->AddMessage(UIMSG_CycleCharacters, 0, 0);
             break;
           case INPUT_LookUp:
             if ( pEventTimer->bPaused )
@@ -8878,21 +7792,23 @@
             }
             break;
           case INPUT_ZoomIn:
-            if ( dword_50C9E8 >= 40 )
+            /*if ( dword_50C9E8 >= 40 )
               break;
             dword_50C9EC[3 * dword_50C9E8] = 367;
             dword_50C9EC[3 * dword_50C9E8 + 1] = 0;
             dword_50C9EC[3 * dword_50C9E8 + 2] = 0;
-            ++dword_50C9E8;
+            ++dword_50C9E8;*/
+              pMessageQueue_50C9E8->AddMessage(UIMSG_ClickZoomOutBtn, 0, 0);
             break;
           case INPUT_ZoomOut:
-            if ( dword_50C9E8 < 40 )
+            /*if ( dword_50C9E8 < 40 )
             {
               dword_50C9EC[3 * dword_50C9E8] = 368;
               dword_50C9EC[3 * dword_50C9E8 + 1] = 0;
               dword_50C9EC[3 * dword_50C9E8 + 2] = 0;
               ++dword_50C9E8;
-            }
+            }*/
+              pMessageQueue_50C9E8->AddMessage(UIMSG_ClickZoomInBtn, 0, 0);
             break;
           case INPUT_AlwaysRun:
             bAlwaysRun = bAlwaysRun == 0;
--- a/mm7_data.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/mm7_data.cpp	Tue May 21 11:24:35 2013 +0200
@@ -1,7 +1,5 @@
 #include "mm7_data.h"
 
-#include "NPC.h"
-#include "Actor.h"
 #include "GUIWindow.h"
 #include "Party.h"
 
@@ -826,20 +824,7 @@
 	"idoor",
 	"isecdoor"
 };
-const char *_4E6BDC_loc_names[11]=
-{
-	"mdt12.blv",
-	"d18.blv",
-	"mdt14.blv",
-	"d37.blv",
-	"mdk01.blv",
-	"mdt01.blv",
-	"mdr01.blv",
-	"mdt10.blv",
-	"mdt09.blv",
-	"mdt15.blv",
-	"mdt11.blv"
-};
+
 char aMer[777]; // idb
 char aMir[777]; // idb
 char aSel[777]; // idb
@@ -1604,8 +1589,8 @@
 int dword_50C9D8; // weak
 int dword_50C9DC; // weak
 struct NPCData *ptr_50C9E0;
-int dword_50C9E8; // idb
-int dword_50C9EC[120]; // weak
+//int dword_50C9E8; // idb
+//int dword_50C9EC[120]; // weak
 int dword_50CDC8;
 int dword_50CDCC; // weak
 int bProcessorIsNotIntel; // weak
--- a/mm7_data.h	Tue May 21 11:24:26 2013 +0200
+++ b/mm7_data.h	Tue May 21 11:24:35 2013 +0200
@@ -1,8 +1,7 @@
 #pragma once
 #include <string>
+#include "VectorTypes.h"
 #include "OSAPI.h"
-#include "SpriteObject.h"
-#include "VectorTypes.h"
 
 typedef char _UNKNOWN;
 
@@ -1032,8 +1031,8 @@
 extern int dword_50C9D8; // weak
 extern int dword_50C9DC; // weak
 extern struct NPCData *ptr_50C9E0;
-extern int dword_50C9E8; // idb
-extern int dword_50C9EC[]; // 50C9EC
+//extern int dword_50C9E8; // idb
+//extern int dword_50C9EC[]; // 50C9EC
 extern int dword_50CDC8;
 extern int dword_50CDCC; // weak
 extern int bProcessorIsNotIntel; // weak
@@ -1521,7 +1520,7 @@
 int __fastcall am_40D402(int, int); // weak
 int __cdecl am_40D444();
 void ModalWindow(const char *pStr, int a4);
-char __fastcall pPrimaryWindow_draws_text(int a1, const char *pText, int *pXY);
+void  pPrimaryWindow_draws_text(int a1, const char *pText, int *pXY);
 void __thiscall am_BeginScene(unsigned __int16 *pPcxPixels, int a2, int a3); // idb
 void __fastcall Blt_Chroma(struct ArcomageRect *pSrcXYZW, int *pTargetXY, int a3, int a4);
 void __fastcall Blt_Copy(struct ArcomageRect *pSrcXYZW, int *pTargetXY, int a3);
@@ -1550,7 +1549,7 @@
 void uGameUIFontShadow_initialize();
 void sub_41420D_press_esc();
 void sub_41426F();
-char GameMenuUI_DrawKeyBindings();
+void GameMenuUI_DrawKeyBindings();
 unsigned int __thiscall sub_414D24(int _this);
 void GameMenuUI_DrawVideoOptions();
 void DrawGameOptions();
@@ -1567,7 +1566,7 @@
 void sub_4178E1();
 unsigned int __fastcall UI_GetHealthManaStringColor(signed int a1, signed int a2);
 signed int __thiscall GetConditionDrawColor(unsigned int uConditionIdx); // idb
-char __fastcall sub_4179BC_draw_tooltip(const char *a1, const char *a2); // idb
+void  __fastcall sub_4179BC_draw_tooltip(const char *a1, const char *a2); // idb
 void FillAwardsData();
 void sub_419220();
 void sub_419379();
@@ -1576,7 +1575,7 @@
 int __fastcall GUI_ReplaceHotkey(unsigned __int8 uOldHotkey, unsigned __int8 uNewHotkey, char bFirstCall);
 void __cdecl MainMenuUI_LoadFontsAndSomeStuff();
 void __cdecl MainMenuUI_Create();
-char __fastcall sub_41D20D_buff_remaining_time_string(int ecx0, struct GUIWindow *edx0, __int64 a3, struct GUIFont *a2);
+void  __fastcall sub_41D20D_buff_remaining_time_string(int ecx0, struct GUIWindow *edx0, __int64 a3, struct GUIFont *a2);
 bool UI_OnKeyDown(unsigned int vkKey);
 void GameUI_DrawItemInfo(struct ItemGen* inspect_item); // idb
 void MonsterPopup_Draw(unsigned int uActorID, struct GUIWindow *edx0);
@@ -1802,9 +1801,9 @@
 std::string *__fastcall _4678E2_make_error_string(std::string *a1, int line, std::string file);
 int __thiscall sub_467D5D(int _this);
 void __thiscall sub_467E7F_EquipBody(unsigned int uEquipType); // idb
-void __fastcall sub_467F48(signed int a1);
+void  CreateMsgScrollWindow(signed int mscroll_id);
 void __cdecl free_book_subwindow();
-char __cdecl CreateScrollWindow();
+void  CreateScrollWindow();
 void __cdecl OnPaperdollLeftClick();
 int __thiscall UnprojectX(int x);
 int __thiscall UnprojectY(int _this);
@@ -1979,7 +1978,7 @@
 void __fastcall sub_4B3FE5(int a4);
 void  NPCHireableDialogPrepare();
 void  _4B4224_UpdateNPCTopics(int _this);
-char __fastcall DrawTextAtStatusBar(const char *Str, int a5);
+void __fastcall DrawTextAtStatusBar(const char *Str, int a5);
 int __fastcall sub_4B46F8(int a1);
 
 signed int __fastcall sub_4BB756(signed int a1);
--- a/stru11.h	Tue May 21 11:24:26 2013 +0200
+++ b/stru11.h	Tue May 21 11:24:35 2013 +0200
@@ -1,6 +1,7 @@
 #pragma once
 
 
+#include "mm7_data.h"
 /*  128 */
 #pragma pack(push, 1)
 struct stru11
--- a/stru159.h	Tue May 21 11:24:26 2013 +0200
+++ b/stru159.h	Tue May 21 11:24:35 2013 +0200
@@ -14,3 +14,6 @@
   unsigned __int16 padding_e;
 };
 #pragma pack(pop)
+
+
+extern  const stru159 pAnimatedRooms[196];
\ No newline at end of file
--- a/stru6.cpp	Tue May 21 11:24:26 2013 +0200
+++ b/stru6.cpp	Tue May 21 11:24:35 2013 +0200
@@ -1,4 +1,7 @@
 #include "stru6.h"
+
+#include "mm7_data.h"
+#include "LightmapBuilder.h"
 #include "SpriteObject.h"
 #include "IndoorCameraD3D.h"
 #include "ParticleEngine.h"