changeset 1055:010a844ef4a0

Слияние
author Ritor1
date Wed, 22 May 2013 22:23:04 +0600
parents 5520fdca7a74 (current diff) 306ec23b37df (diff)
children 86a7e8f9ca33
files Vis.cpp mm7_5.cpp
diffstat 76 files changed, 6577 insertions(+), 8864 deletions(-) [+]
line wrap: on
line diff
--- a/Actor.cpp	Wed May 22 22:22:36 2013 +0600
+++ b/Actor.cpp	Wed May 22 22:23:04 2013 +0600
@@ -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"
 
 
 
@@ -219,107 +226,6 @@
   }
 }
 
-//----- (00445D4A) --------------------------------------------------------
-void Actor::InitializeDialogue(int bPlayerSaysHello)
-{
-  NPCData *pNPCInfo; // ebp@1
-  int v9; // esi@8
-  int pNumberContacts; // eax@11
-  char pContainer[32]; // [sp+14h] [bp-28h]@3
-
-  dword_A74CDC = -1;
-  dword_AE336C = -1;
-  pEventTimer->Pause();
-  pMiscTimer->Pause();
-  pAudioPlayer->StopChannels(-1, -1);
-  uDialogueType = 0;
-  sDialogue_SpeakingActorNPC_ID = this->sNPC_ID;
-  pDialogue_SpeakingActor = this;
-  pNPCInfo = GetNPCData(this->sNPC_ID);
-  if ( (pNPCInfo->uFlags & 3) != 2 )
-    pNPCInfo->uFlags = pNPCInfo->uFlags + 1;
-
-  switch (pParty->alignment)
-  {
-    case PartyAlignment_Good:    sprintf(pContainer, "evt%02d-b", const_2()); break;
-    case PartyAlignment_Neutral: sprintf(pContainer, "evt%02d", const_2()); break;
-    case PartyAlignment_Evil:    sprintf(pContainer, "evt%02d-c", const_2()); break;
-  }
-
-  pDialogueNPCCount = 0;
-  uNumDialogueNPCPortraits = 1;
-  pTexture_Dialogue_Background = pIcons_LOD->LoadTexturePtr(pContainer, TEXTURE_16BIT_PALETTE);
-  sprintf(pContainer, "npc%03u", pNPCInfo->uPortraitID);
-  v9 = 0;
-  pDialogueNPCPortraits[0] = pIcons_LOD->LoadTexturePtr(pContainer, TEXTURE_16BIT_PALETTE);
-  dword_591084 = areWeLoadingTexture;
-  uTextureID_right_panel_loop = uTextureID_right_panel;
-  if ( !pNPCInfo->Hired() && pNPCInfo->Location2D >= 0 )
-  {
-    if ( (signed int)pParty->GetPartyFame() <= pNPCInfo->fame
-      || (pNumberContacts = pNPCInfo->uFlags & 0xFFFFFF7F, (pNumberContacts & 0x80000000u) != 0) )
-    {
-      v9 = 1;
-    }
-	else
-	{
-		if ( pNumberContacts > 1 )
-		{
-		  if ( pNumberContacts == 2 )
-		  {
-			v9 = 3;
-		  }
-		  else
-		  {
-			  if ( pNumberContacts != 3 )
-			  {
-				if ( pNumberContacts != 4 )
-				  v9 = 1;
-			  }
-			  else
-			  {
-				v9 = 2;
-			  }
-		  }
-		}
-		else if ( pNPCInfo->rep )
-		{
-		  v9 = 2;
-		}
-	}
-  }
-  if ( (sDialogue_SpeakingActorNPC_ID & 0x80000000u) != 0 )
-    v9 = 4;
-  pDialogueWindow = GUIWindow::Create(0, 0, 640, 480, WINDOW_Dialogue, v9, 0);//pNumberContacts = 1, v9 = 0; pNumberContacts = 2, v9 = 3;
-  if (pNPCInfo->Hired())
-  {
-    if ( !pNPCInfo->bHasUsedTheAbility )
-    {
-      if ( pNPCInfo->uProfession >= 10 )
-      {
-        if ( pNPCInfo->uProfession <= 12 || pNPCInfo->uProfession > 32 && (pNPCInfo->uProfession <= 34 
-             || pNPCInfo->uProfession > 38 && (pNPCInfo->uProfession <= 43 || pNPCInfo->uProfession == 52)) )
-        {
-          pDialogueWindow->CreateButton(480, 250, 140, LOBYTE(pFontArrus->uFontHeight) - 3, 1, 0, UIMSG_SelectNPCDialogueOption, 9, 0, "", 0);
-          pDialogueWindow->_41D08F_set_keyboard_control_group(4, 1, 0, 1);
-        }
-      }
-    }
-  }
-
-  pDialogueWindow->CreateButton( 61, 424, 31, 40, 2, 94, UIMSG_SelectCharacter, 1, '1', "", 0);
-  pDialogueWindow->CreateButton(177, 424, 31, 40, 2, 94, UIMSG_SelectCharacter, 2, '2', "", 0);
-  pDialogueWindow->CreateButton(292, 424, 31, 40, 2, 94, UIMSG_SelectCharacter, 3, '3', "", 0);
-  pDialogueWindow->CreateButton(407, 424, 31, 40, 2, 94, UIMSG_SelectCharacter, 4, '4', "", 0);
-
-  if (bPlayerSaysHello && uActiveCharacter && !pNPCInfo->Hired())
-  {
-    if (pParty->uCurrentHour < 5 || pParty->uCurrentHour > 21)
-      pPlayers[uActiveCharacter]->PlaySound(SPEECH_GoodEvening, 0);
-    else
-      pPlayers[uActiveCharacter]->PlaySound(SPEECH_GoodDay, 0);
-  }
-}
   
 //----- (0040894B) --------------------------------------------------------
 bool Actor::CanAct()
@@ -3145,6 +3051,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	Wed May 22 22:22:36 2013 +0600
+++ b/Actor.h	Wed May 22 22:23:04 2013 +0600
@@ -1,8 +1,7 @@
 #pragma once
-#include "VectorTypes.h"
-#include "Items.h"
 #include "Monsters.h"
 #include "Spells.h"
+#include "Items.h"
 
 
 
@@ -188,7 +187,6 @@
   void SetRandomGoldIfTheresNoItem();
   bool CanAct();
   bool IsNotAlive();
-  void InitializeDialogue(int bPlayerSaysHello);
   bool IsPeasant();
 
   
--- a/Arcomage.cpp	Wed May 22 22:22:36 2013 +0600
+++ b/Arcomage.cpp	Wed May 22 22:23:04 2013 +0600
@@ -1,5 +1,7 @@
 #include <string>
+#include <assert.h>
 
+#include "LightmapBuilder.h"
 #include "Arcomage.h"
 #include "VideoPlayer.h"
 #include "AudioPlayer.h"
@@ -13,7 +15,6 @@
 #include "Events2D.h"
 #include "VectorTypes.h"
 #include "texts.h"
-#include "mm7_data.h"
 
 
 
@@ -2038,7 +2039,8 @@
     {
       //nullsub_1();
       //nullsub_1();
-      inv_strcpy(pAreYouSureWishToLeave, Dest);
+      assert(false && "Invalid strcpy params");
+      inv_strcpy(nullptr, Dest);
       v5 = 0;//unk::const_0(&unk_4E19FC, 0);
       //nullsub_1();
       if ( v5 == 1 )
--- a/AudioPlayer.cpp	Wed May 22 22:22:36 2013 +0600
+++ b/AudioPlayer.cpp	Wed May 22 22:23:04 2013 +0600
@@ -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"
 
 
--- a/AudioPlayer.h	Wed May 22 22:22:36 2013 +0600
+++ b/AudioPlayer.h	Wed May 22 22:23:04 2013 +0600
@@ -102,6 +102,8 @@
   SOUND_OpenChest = 208,
   SOUND_PlayerCantCastSpell = 0xD1,
   SOUND_Bell = 0xD9,
+  SOUND_OpenBook = 230,
+  SOUND_CloseBook = 231,
   SOUND_20001 = 0x4E21,
 };
 
--- a/Bink_Smacker.h	Wed May 22 22:22:36 2013 +0600
+++ b/Bink_Smacker.h	Wed May 22 22:23:04 2013 +0600
@@ -144,6 +144,13 @@
         HDC lastdc;
 };
 
+#define SMACKBUFFER555      0x80000000
+#define SMACKBUFFER565      0xC0000000
+
+#define SMACKBLIT1X                1
+#define SMACKBLIT2X                2
+#define SMACKBLIT2XSMOOTHING       4
+#define SMACKBLIT2XINTERLACE       8
 
 
 int __stdcall SmackSoundUseMSS(HDIGDRIVER hDrv);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CShow.cpp	Wed May 22 22:23:04 2013 +0600
@@ -0,0 +1,34 @@
+#include <assert.h>
+
+#include "CShow.h"
+
+#include "VideoPlayer.h"
+#include "Mouse.h"
+
+void CShow::PlayMovie(MovieType eVideo, bool bShowMouseAfterPlayback)
+{
+  if (bNoVideo) return;
+
+  if (pAsyncMouse)
+    pAsyncMouse->Suspend();
+
+  switch (eVideo)
+  {
+    case MOVIE_3DOLogo: VideoPlayer::MovieLoop("3dologo", 0, 0, 1);        break;
+    case MOVIE_NWCLogo: VideoPlayer::MovieLoop("new world logo", 0, 1, 1); break;
+    case MOVIE_JVC:     VideoPlayer::MovieLoop("jvc", 0, 1, 1);            break;
+    case MOVIE_Intro:   VideoPlayer::MovieLoop("Intro", 0, 1, 1);          break;
+    case MOVIE_Emerald: VideoPlayer::MovieLoop("Intro Post", 0, 1, 1);     break;
+    case MOVIE_Death:   VideoPlayer::MovieLoop("losegame", 2, 1, 1);       break;
+    case MOVIE_Outro:   VideoPlayer::MovieLoop("end_seq1", 20, 1, 1);      break;
+
+    default:
+      assert(false && "Invalid movie requested in " __FUNCTION__);
+      break;
+  }
+
+  if (bShowMouseAfterPlayback)
+    if (pAsyncMouse)
+      pAsyncMouse->Resume();
+}
+
--- a/CShow.h	Wed May 22 22:22:36 2013 +0600
+++ b/CShow.h	Wed May 22 22:23:04 2013 +0600
@@ -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 PlayMovie(MovieType eVideo, bool bShowMouseAfterPlayback);
 
 
   void (__thiscall ***vdestructor_ptr)(CShow *, bool);
--- a/Chest.cpp	Wed May 22 22:22:36 2013 +0600
+++ b/Chest.cpp	Wed May 22 22:23:04 2013 +0600
@@ -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	Wed May 22 22:22:36 2013 +0600
+++ b/Chest.h	Wed May 22 22:23:04 2013 +0600
@@ -1,5 +1,4 @@
 #pragma once
-#include "Items.h"
 
 
 
--- a/DecalBuilder.cpp	Wed May 22 22:22:36 2013 +0600
+++ b/DecalBuilder.cpp	Wed May 22 22:23:04 2013 +0600
@@ -7,7 +7,7 @@
 
 #include "mm7_data.h"
 
-
+#include "stru9.h"
 
 
 
--- a/Events.cpp	Wed May 22 22:22:36 2013 +0600
+++ b/Events.cpp	Wed May 22 22:23:04 2013 +0600
@@ -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"
 
 
@@ -532,7 +529,7 @@
 					memset(&Dst, 0, 0x344u);
 					dword_5B65D0_dialogue_actor_npc_id = _evt->v5 + ((_evt->v6 + ((_evt->v7 + ((unsigned int)_evt->v8 << 8)) << 8)) << 8);
 					Dst.sNPC_ID = dword_5B65D0_dialogue_actor_npc_id;
-					Dst.InitializeDialogue(0);
+					GameUI_InitializeDialogue(&Dst, false);
 					}
 				else
 					{
@@ -1260,7 +1257,7 @@
 					{
 					if ( pRenderer->pRenderD3D && !pRenderer->bWindowMode )
 						pRenderer->_49FD3A();
-					sub_444839_move_map(_evt->v29, _evt->v30, v135, v132, v126, v129, v95, v134, (char *)&_evt->v31);
+					TransitionUI_Load(_evt->v29, _evt->v30, v135, v132, v126, v129, v95, v134, (char *)&_evt->v31);
 					dword_5C3418 = uEventID;
 					dword_5C341C = curr_seq_num + 1;
 					goto LABEL_301;
@@ -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	Wed May 22 22:22:36 2013 +0600
+++ b/GUIButton.cpp	Wed May 22 22:23:04 2013 +0600
@@ -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	Wed May 22 22:22:36 2013 +0600
+++ b/GUIWindow.cpp	Wed May 22 22:23:04 2013 +0600
@@ -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) --------------------------------------------------
@@ -100,7 +99,6 @@
     for ( i = uNumVisibleWindows; i >= 0; --i )
     {
       result = 84 * pVisibleWindowsIdxs[i];
-      //for ( j = *(GUIButton **)((char *)pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_ + result); j; j = j->pNext )
       for ( j = pWindowList[pVisibleWindowsIdxs[i] - 1].pControlsHead; j; j = j->pNext )
         j->field_28 = 0;
     }
@@ -108,7 +106,6 @@
   for ( k = uNumVisibleWindows; k >= 0; --k )
   {
     result = 84 * pVisibleWindowsIdxs[k];
-    //for ( l = *(GUIButton **)((char *)pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_ + result); l; l = l->pNext )
     for ( l = pWindowList[pVisibleWindowsIdxs[k] - 1].pControlsHead; l; l = l->pNext )
     {
       LOBYTE(result) = v10;
@@ -176,8 +173,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 +239,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,130 +247,10 @@
     v8 += 3;
   }
   while ( (signed int)v18 < (signed int)pParty->pPlayers );
-  return v9;
+  
 }
 
 
-//----- (0041D3B7) --------------------------------------------------------
-void GUIWindow::DrawQuickCharRecord()
-    {
-  Player *pPlayer; // esi@1
-  int v6; // eax@5
-  int v7; // ebx@5
-  unsigned int v8; // ecx@5
-  int v9; // ebx@5
-  unsigned int v10; // eax@5
-  int v11; // eax@5
-  unsigned int v12; // ecx@5
-  Texture *v13; // eax@6
-  unsigned int v14; // eax@12
-  PlayerFrame *v15; // eax@12
-  unsigned int v16; // eax@15
-  unsigned int v20; // eax@15
-  unsigned int v24; // eax@15
-  unsigned int v25; // eax@15
-  unsigned __int8 v28; // al@15
-  char *v29; // eax@16
-  __int64 v35; // ST38_8@22
-  int v36; // esi@22
-  unsigned int v38; // eax@22
-  char *v39; // eax@24
-  signed int uFramesetID; // [sp+20h] [bp-8h]@9
-  int uFramesetIDa; // [sp+20h] [bp-8h]@18
-
-  pPlayer = &pParty->pPlayers[(unsigned int)ptr_1C];
-
-  uint numActivePlayerBuffs = 0;
-
-  for (uint i = 0; i < 24; ++i)
-    if (pPlayer->pPlayerBuffs[i].uExpireTime > 0)
-      ++numActivePlayerBuffs;
-
-  v6 = pFontArrus->uFontHeight + 162;
-  uFrameHeight = v6;
-  v7 = (numActivePlayerBuffs - 1) * pFontArrus->uFontHeight;
-  v8 = uFrameX;
-  v9 = v6 + v7;
-  v10 = uFrameWidth;
-  uFrameHeight = v9;
-  v11 = v10 + v8 - 1;
-  v12 = uFrameY;
-  uFrameZ = v11;
-  uFrameW = v9 + v12 - 1;
-  DrawMessageBox(0);
-  if (pPlayer->Eradicated())
-    v13 = pTexture_PlayerFaceEradicated;
-  else if (pPlayer->Dead())
-    v13 = pTexture_PlayerFaceDead;
-  else
-  {
-      uFramesetID = pPlayerFrameTable->GetFrameIdByExpression(pPlayer->expression);
-      if ( !uFramesetID )
-        uFramesetID = 1;
-      if ( pPlayer->expression == CHARACTER_EXPRESSION_21)
-      {
-        v15 = pPlayerFrameTable->GetFrameBy_y(&pPlayer->_expression21_frameset, &pPlayer->_expression21_animtime, pMiscTimer->uTimeElapsed);
-      }
-      else
-      {
-        v14 = pMiscTimer->Time();
-        v15 = pPlayerFrameTable->GetFrameBy_x(uFramesetID, v14);
-      }
-      pPlayer->field_1AA2 = v15->uTextureID - 1;
-      v13 = pTextures_PlayerFaces[(unsigned int)ptr_1C][v15->uTextureID-1];
-  }
-
-  pRenderer->DrawTextureTransparent(uFrameX + 24, uFrameY + 24, v13);
-  v16 = TargetColor(0xFFu, 0xFFu, 0x9Bu);
-  sprintf(pTmpBuf, "\f%05d", v16);
-  sprintfex(pTmpBuf2, pGlobalTXT_LocalizationStrings[429], pPlayer->pName, pClassNames[pPlayer->classType]);
-  strcat(pTmpBuf, pTmpBuf2);
-  strcat(pTmpBuf, "\f00000\n");
-  v20 = UI_GetHealthManaStringColor(pPlayer->sHealth, pPlayer->GetMaxHealth());
-  sprintf(pTmpBuf2, "%s : \f%05u%d\f00000 / %d\n", pGlobalTXT_LocalizationStrings[108],
-          v20, pPlayer->sHealth, pPlayer->GetMaxHealth());
-  strcat(pTmpBuf, pTmpBuf2);
-  v24 = UI_GetHealthManaStringColor(pPlayer->sMana, pPlayer->GetMaxMana());
-  sprintf(pTmpBuf2, "%s : \f%05u%d\f00000 / %d\n", pGlobalTXT_LocalizationStrings[212],
-          v24, pPlayer->sMana, pPlayer->GetMaxMana());
-  strcat(pTmpBuf, pTmpBuf2);
-  v25 = pPlayer->GetMajorConditionIdx();
-  sprintf(pTmpBuf2, "%s: \f%05d%s\f00000\n", pGlobalTXT_LocalizationStrings[47],
-          GetConditionDrawColor(v25), aCharacterConditionNames[v25]);
-  strcat(pTmpBuf, pTmpBuf2);
-  v28 = pPlayer->uQuickSpell;
-  if ( v28 )
-    v29 = pSpellStats->pInfos[v28].pShortName;
-  else
-    v29 = pGlobalTXT_LocalizationStrings[153];
-  sprintf((char*)pTmpBuf2, "%s: %s", (char*)pGlobalTXT_LocalizationStrings[172], v29);
-  strcat((char*)pTmpBuf, (char*)pTmpBuf2);
-  DrawText(pFontArrus, 120, 22, 0, pTmpBuf, 0, 0, 0);
-
-  uFramesetIDa = 0;
-  for (uint i = 0; i < 24; ++i)
-  {
-    auto buff = pPlayer->pPlayerBuffs + i;
-    if (buff->uExpireTime > 0)
-    {
-      v35 = buff->uExpireTime - pParty->uTimePlayed;
-      v36 = uFramesetIDa++ * pFontComic->uFontHeight + 134;
-      v38 = TargetColor(
-              _4E2AD8_ui_colors[i * 3],
-              _4E2AD8_ui_colors[i * 3 + 1],
-              _4E2AD8_ui_colors[i * 3 + 2]);
-      DrawText(pFontComic, 52, v36, v38, aSpellNames[20 + i], 0, 0, 0);
-      sub_41D20D_buff_remaining_time_string(v36, this, v35, pFontComic);
-    }
-  }
-
-  v39 = "";
-  if ( uFramesetIDa == 0 )
-    v39 = pGlobalTXT_LocalizationStrings[153];
-  sprintf(pTmpBuf, pGlobalTXT_LocalizationStrings[450], v39);
-  DrawText(pFontArrus, 14, 114, 0, pTmpBuf, 0, 0, 0);
-}
-
 //----- (0041D08F) --------------------------------------------------------
 void GUIWindow::_41D08F_set_keyboard_control_group(int a2, int a3, int a4, int a5)
 {
@@ -417,7 +294,7 @@
   {
 	case WINDOW_GreetingNPC:
 		{
-		pIcons_LOD->_40F9C5();
+		pIcons_LOD->SyncLoadedFilesCount();
 		pCurrentScreen = pMainScreenNum;
 		pKeyActionMap->_459ED1(3);
 		break;
@@ -429,7 +306,7 @@
 		uNumDialogueNPCPortraits = 0;
 		pTexture_Dialogue_Background->Release();
 
-		pIcons_LOD->_40F9C5();
+		pIcons_LOD->SyncLoadedFilesCount();
 		pIcons_LOD->_4114F2();
 		dword_5C35D4 = 0;
 		if ( bFlipOnExit )
@@ -446,7 +323,7 @@
 		pVideoPlayer->Unload();
 		pTexture_outside->Release();
 		pTexture_Dialogue_Background->Release();
-		pIcons_LOD->_40F9C5();
+		pIcons_LOD->SyncLoadedFilesCount();
 		pCurrentScreen = pMainScreenNum;
 		break;
 		}
@@ -465,7 +342,7 @@
 		{
         pTexture_outside->Release();
         pTexture_Dialogue_Background->Release();
-        pIcons_LOD->_40F9C5();
+        pIcons_LOD->SyncLoadedFilesCount();
         pCurrentScreen = pMainScreenNum;
         break;
 		}
@@ -476,7 +353,7 @@
         uNumDialogueNPCPortraits = 0;
         pTexture_Dialogue_Background->Release();
 
-        pIcons_LOD->_40F9C5();
+        pIcons_LOD->SyncLoadedFilesCount();
         pCurrentScreen = pMainScreenNum;
 		}
 	default:
@@ -768,7 +645,7 @@
       }
       break;
 
-  case WINDOW_HistoryBook:
+  case WINDOW_JournalBook:
   {
       pSpellBookPagesTextr_11  = pIcons_LOD->LoadTexturePtr("sbplayrnot", TEXTURE_16BIT_PALETTE);
       pTex_tab_an_6b__zoom_on  = pIcons_LOD->LoadTexturePtr("tab-an-6b", TEXTURE_16BIT_PALETTE);
@@ -939,7 +816,7 @@
   if ( v17 )
   {
     v18 = pFontLucida->CalcTextHeight(v17, &v19, 0, 0);
-    v19.DrawTitleText(pFontLucida, 0, (signed int)(v16 - v18) / 2 - 14, 0, v17, 3u);
+    v19.DrawTitleText(pFontLucida, 0, (signed int)(v16 - v18) / 2 - 14, 0, v17, 3);
   }
 }
 
@@ -1360,8 +1237,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
@@ -1395,7 +1272,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 )
@@ -1470,7 +1347,7 @@
 LABEL_36:
                   v11 = v11 + v13 - 3;
                   if ( v11 > a8 )
-                    return v11;
+                    return;
                   break;
                 }
                 break;
@@ -1522,7 +1399,7 @@
       }
     }
   }
-  return v11;
+  return;
 }
 
 
--- a/GUIWindow.h	Wed May 22 22:22:36 2013 +0600
+++ b/GUIWindow.h	Wed May 22 22:23:04 2013 +0600
@@ -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,
@@ -302,7 +301,7 @@
   WINDOW_AutonotesBook = 0xC9,
   WINDOW_MapsBook = 0xCA,
   WINDOW_CalendarBook = 0xCB,
-  WINDOW_HistoryBook = 0xE0,
+  WINDOW_JournalBook = 0xE0,
 };
 
 struct GUIButton;
@@ -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,8 +331,7 @@
   GUIButton *GetControl(unsigned int uID);
   void Release();
   void _41D08F_set_keyboard_control_group(int a2, int a3, int a4, int a5);
-  void DrawQuickCharRecord();
-  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);
 
@@ -444,7 +442,7 @@
 
 extern struct GUIMessageQueue *pMessageQueue_50CBD0; // idb
 
-
+extern struct GUIMessageQueue *pMessageQueue_50C9E8; // idb
 
 
 
@@ -466,7 +464,17 @@
 void draw_leather();
 
 
+// main menu ui
+void MainMenuUI_LoadFontsAndSomeStuff();
+void MainMenuUI_Create();
+MENU_STATE MainMenuUI_Credits_Loop();
 
+// save & load ui
+void SaveUI_Load();
+void SaveUI_Draw();
+
+void LoadUI_Draw();
+void LoadUI_Load(unsigned int uDialogueType); // idb
 
 // game ui
 void GameUI_DrawRightPanel();
@@ -481,16 +489,22 @@
 void GameUI_Footer_2();
 void GameUI_SetFooterString(const char *pStr);
 void GameUI_DrawMinimap(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW, unsigned int uZoom, unsigned int bRedrawOdmMinimap);
+auto GameUI_GetMinimapHintText() -> const char *;
 void GameUI_DrawPartySpells();
 void GameUI_DrawTorchlightAndWizardEye();
 void GameUI_DrawCharacterSelectionFrame();
+void GameUI_CharacterQuickRecord_Draw(GUIWindow *window, Player *player);
+void GameUI_DrawNPCPopup(void *_this);
 
-
+void GameUI_InitializeDialogue(Actor *actor, int bPlayerSaysHello);
+void GameUI_DrawBranchlessDialogue();
+void GameUI_DrawDialogue();
 
 
-
-
-
+// game menu ui
+void GameMenuUI_DrawKeyBindings();
+void GameMenuUI_DrawVideoOptions();
+void GameMenuUI_Options_Draw();
 
 
 
@@ -498,9 +512,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);
@@ -516,28 +530,38 @@
 
 
 
-//book ui
+// book ui
 void BookUI_Draw(WindowType book);
 void BookUI_Questbook_Draw();
 void BookUI_Autonotes_Draw();
 void BookUI_Map_Draw();
 void BookUI_Calendar_Draw();
+void BookUI_Journal_Draw();
 
 void OnCloseSpellBook();
 void InitializeBookTextures();
 void InitializeBookFonts();
-void DrawSpellBookContent();
-void DrawBook_History();
+void DrawSpellBookContent(Player *player);
 unsigned int __cdecl DrawLloydBeaconsScreen();
 void DrawTownPortalScreen();
 void LoadSpellbook(unsigned int uID); // idb
 void DrawSpellDescriptionPopup(int spell_index);
+void sub_41140B();
+void sub_411473();
 
 
 
+// rest ui
+void RestUI_Load();
+void RestUI_Draw();
 
 
+// transition & travel ui
+void TransitionUI_Load(uint anim_id, uint exit_pic_id, int x, int y, int z, int directiony, int directionx, int a8, const char *pLocationName);
+void TransitionUI_Draw();
 
+void TravelUI_Load();
+void TravelUI_Draw();
 
 
 
@@ -562,7 +586,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();
 
@@ -692,6 +716,7 @@
 
 extern int uTextureID_GameUI_CharSelectionFrame; // 50C98C
 
+extern unsigned int ui_mainmenu_copyright_color;
 extern unsigned int ui_character_default_text_color;
 extern unsigned int ui_character_skill_highlight_color;
 extern unsigned int ui_character_header_text_color;
@@ -707,9 +732,25 @@
 extern unsigned int ui_game_minimap_decoration_color_1;
 extern unsigned int ui_game_minimap_projectile_color;
 extern unsigned int ui_game_minimap_treasure_color;
+extern unsigned int ui_game_character_record_playerbuff_colors[24];
+extern unsigned int ui_gamemenu_video_gamma_title_color;
+extern unsigned int ui_gamemenu_keys_action_name_color;
+extern unsigned int ui_gamemenu_keys_key_selection_blink_color_1;
+extern unsigned int ui_gamemenu_keys_key_selection_blink_color_2;
+extern unsigned int ui_gamemenu_keys_key_default_color;
 extern unsigned int ui_book_quests_title_color;
 extern unsigned int ui_book_quests_text_color;
 extern unsigned int ui_book_autonotes_title_color;
 extern unsigned int ui_book_autonotes_text_color;
 extern unsigned int ui_book_map_title_color;
-extern unsigned int ui_book_map_coordinates_color;
\ No newline at end of file
+extern unsigned int ui_book_map_coordinates_color;
+extern unsigned int ui_book_calendar_title_color;
+extern unsigned int ui_book_calendar_time_color;
+extern unsigned int ui_book_calendar_day_color;
+extern unsigned int ui_book_calendar_month_color;
+extern unsigned int ui_book_calendar_year_color;
+extern unsigned int ui_book_calendar_moon_color;
+extern unsigned int ui_book_calendar_location_color;
+extern unsigned int ui_book_journal_title_color;
+extern unsigned int ui_book_journal_text_color;
+extern unsigned int ui_book_journal_text_shadow;
\ No newline at end of file
--- a/Game.cpp	Wed May 22 22:22:36 2013 +0600
+++ b/Game.cpp	Wed May 22 22:23:04 2013 +0600
@@ -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"
 
@@ -362,11 +373,6 @@
       pEventTimer->Update();
       pMiscTimer->Update();
 
-      static int gtc_old = GetTickCount();
-      int gtc = GetTickCount();
-      Log::Warning(L"Evt/Msc/GTC dt: %u/%u/%u", pEventTimer->uTimeElapsed, pMiscTimer->uTimeElapsed, gtc - gtc_old);
-      gtc_old = gtc;
-
       OnTimer(0);
       GameUI_StatusBar_UpdateTimedString(0);
       if ( pMiscTimer->bPaused && !pEventTimer->bPaused )
--- a/Game.h	Wed May 22 22:22:36 2013 +0600
+++ b/Game.h	Wed May 22 22:23:04 2013 +0600
@@ -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	Wed May 22 22:22:36 2013 +0600
+++ b/GammaControl.h	Wed May 22 22:23:04 2013 +0600
@@ -1,5 +1,5 @@
 #pragma once
-#include "Render.h"
+#include "lib\legacy_dx\d3d.h"
 
 #pragma pack(push, 1)
 struct GammaController
--- a/Indoor.cpp	Wed May 22 22:22:36 2013 +0600
+++ b/Indoor.cpp	Wed May 22 22:23:04 2013 +0600
@@ -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	Wed May 22 22:22:36 2013 +0600
+++ b/Indoor.h	Wed May 22 22:23:04 2013 +0600
@@ -1,6 +1,5 @@
 #pragma once
 #include "VectorTypes.h"
-#include "IndoorCameraD3D.h"
 #include "Weather.h"
 
 
@@ -253,6 +252,7 @@
 #define FACE_PORTAL             0x00000001 // portal/two-sided
 #define FACE_CAN_SATURATE_COLOR 0x00000002
 #define FACE_FLUID              0x00000010 // wavy animated water or lava
+#define FACE_DONT_CACHE_TEXTURE 0x00000040 // do not load face texture if it isn't loaded already
 #define FACE_XY_PLANE           0x00000100
 #define FACE_XZ_PLANE           0x00000200
 #define FACE_YZ_PLANE           0x00000400
@@ -283,7 +283,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 +417,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 +462,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 +546,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	Wed May 22 22:22:36 2013 +0600
+++ b/IndoorCameraD3D.cpp	Wed May 22 22:23:04 2013 +0600
@@ -9,6 +9,8 @@
 #include "LOD.h"
 #include "mm7_data.h"
 
+#include "stru9.h"
+
 //----- (004361EF) --------------------------------------------------------
 IndoorCameraD3D::IndoorCameraD3D()
 {
--- a/Indoor_stuff.h	Wed May 22 22:22:36 2013 +0600
+++ b/Indoor_stuff.h	Wed May 22 22:23:04 2013 +0600
@@ -1,6 +1,6 @@
 #pragma once
 #include "Render.h"
-
+#include "IndoorCameraD3D.h"
 
 
 
--- a/Items.cpp	Wed May 22 22:22:36 2013 +0600
+++ b/Items.cpp	Wed May 22 22:23:04 2013 +0600
@@ -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	Wed May 22 22:22:36 2013 +0600
+++ b/Items.h	Wed May 22 22:23:04 2013 +0600
@@ -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/Keyboard.cpp	Wed May 22 22:22:36 2013 +0600
+++ b/Keyboard.cpp	Wed May 22 22:23:04 2013 +0600
@@ -44,9 +44,9 @@
 
   ResetKeys();
 
-  dword_506E68 = -1;
+  uGameMenuUI_CurentlySelectedKeyIdx = -1;
 }
-// 506E68: using guessed type int dword_506E68;
+// 506E68: using guessed type int uGameMenuUI_CurentlySelectedKeyIdx;
 
 //----- (00459CC4) --------------------------------------------------------
 void KeyboardActionMapping::SetDefaultMapping()
@@ -155,7 +155,7 @@
   int v3; // [sp-4h] [bp-4h]@3
 
   pKeyActionMap->uLastKeyPressed = a2;
-  if ( dword_506E68 == -1 )
+  if ( uGameMenuUI_CurentlySelectedKeyIdx == -1 )
   {
     if ( pKeyActionMap->field_204 == 1 )
     {
@@ -215,7 +215,7 @@
   pKeyActionMap->_459ED1(v3);
   return 1;
 }
-// 506E68: using guessed type int dword_506E68;
+// 506E68: using guessed type int uGameMenuUI_CurentlySelectedKeyIdx;
 
 //----- (00459FFC) --------------------------------------------------------
 void KeyboardActionMapping::ReadMappings()
--- a/LOD.cpp	Wed May 22 22:22:36 2013 +0600
+++ b/LOD.cpp	Wed May 22 22:23:04 2013 +0600
@@ -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	Wed May 22 22:22:36 2013 +0600
+++ b/LOD.h	Wed May 22 22:23:04 2013 +0600
@@ -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	Wed May 22 22:22:36 2013 +0600
+++ b/LightmapBuilder.cpp	Wed May 22 22:23:04 2013 +0600
@@ -4,10 +4,13 @@
 #include "Outdoor.h"
 #include "Log.h"
 
+#include "OutdoorCamera.h"
+
 #include "mm7_data.h"
 
 
 
+#include "stru9.h"
 
 
 
--- a/MM7.h	Wed May 22 22:22:36 2013 +0600
+++ b/MM7.h	Wed May 22 22:23:04 2013 +0600
@@ -1,5 +1,4 @@
 #pragma once
-#include "OSAPI.h"
 #include <math.h>
 #include <stdio.h>
 #include <stdarg.h>
--- a/MapInfo.h	Wed May 22 22:22:36 2013 +0600
+++ b/MapInfo.h	Wed May 22 22:23:04 2013 +0600
@@ -98,6 +98,7 @@
 extern struct MapStats *pMapStats;
 
 
+extern MapStartPoint uLevel_StartingPointType; // weak
 
 
 void TeleportToStartingPoint(MapStartPoint point); // idb
--- a/Mouse.cpp	Wed May 22 22:22:36 2013 +0600
+++ b/Mouse.cpp	Wed May 22 22:23:04 2013 +0600
@@ -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	Wed May 22 22:22:36 2013 +0600
+++ b/NPC.cpp	Wed May 22 22:23:04 2013 +0600
@@ -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	Wed May 22 22:22:36 2013 +0600
+++ b/Outdoor.cpp	Wed May 22 22:23:04 2013 +0600
@@ -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
 
@@ -1933,7 +1935,7 @@
 
       auto *face = &model->pFaces[j];
       //pFilename = (char *)v149 + (unsigned int)v60[v48].pFaces;
-      if (~face->uAttributes & 0x40)
+      if (~face->uAttributes & FACE_DONT_CACHE_TEXTURE)
       {
         v62 = pBitmaps_LOD->LoadTexture(texFilename);
 //        v63 = (ODMFace *)pFilename;
@@ -1945,7 +1947,7 @@
       {
         v62 = pBitmaps_LOD->LoadTexture(texFilename);
         //v63 = (ODMFace *)pFilename;
-        face->uAttributes &= 0xFFBFu;
+        face->uAttributes &= ~FACE_DONT_CACHE_TEXTURE;
 LABEL_68:
         face->uTextureID = v62;
         //v145 = (signed __int16)v62 != -1 ? &pBitmaps_LOD->pTextures[(signed __int16)v62] : 0;
@@ -1959,9 +1961,9 @@
       if (face->sCogTriggeredID)
       {
         if (face->HasEventHint())
-          face->uAttributes |= 0x1000u;
+          face->uAttributes |= 0x1000;
         else
-          face->uAttributes &= 0xEFFFu;
+          face->uAttributes &= ~0x1000;
       }
       //++v144;
       //v60 = pBModels;
--- a/Outdoor.h	Wed May 22 22:22:36 2013 +0600
+++ b/Outdoor.h	Wed May 22 22:23:04 2013 +0600
@@ -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 */
@@ -91,6 +88,7 @@
   inline bool Visible() const   {return !Invisible();}
   inline bool Portal() const    {return uAttributes & FACE_PORTAL;}
   inline bool Fluid() const     {return uAttributes & FACE_FLUID;}
+  inline bool Clickable() const {return uAttributes & FACE_CLICKABLE;}
 
   struct Plane_int_ pFacePlane;
   int zCalc1;
@@ -268,8 +266,6 @@
 
 
 
-extern MapStartPoint uLevel_StartingPointType; // weak
-
 
 
 
--- a/ParticleEngine.cpp	Wed May 22 22:22:36 2013 +0600
+++ b/ParticleEngine.cpp	Wed May 22 22:23:04 2013 +0600
@@ -8,6 +8,8 @@
 #include "Math.h"
 #include "LOD.h"
 
+#include "Sprites.h"
+#include "OutdoorCamera.h"
 #include "mm7_data.h"
 
 //----- (0048AAC5) --------------------------------------------------------
@@ -235,10 +237,10 @@
   int v42; // ecx@18
   int v43; // eax@18
   unsigned __int64 v44; // qax@18
-  double v45; // st7@18
-  int v46; // ecx@18
-  float v47; // ST18_4@18
-  unsigned __int64 v48; // qax@18
+  //double v45; // st7@18
+  //int v46; // ecx@18
+  //float v47; // ST18_4@18
+  //unsigned __int64 v48; // qax@18
   int y_int_; // [sp+10h] [bp-40h]@2
   int a2; // [sp+18h] [bp-38h]@10
   int x_int; // [sp+20h] [bp-30h]@2
@@ -371,14 +373,9 @@
       pParticle->uScreenSpaceX = v42;
       v44 = v43 * (signed __int64)v24;
       //uParticleID = v44 >> 16;
-      v45 = pParticle->flt_28;
       LODWORD(v44) = (signed int)(v44 >> 16) >> 16;
-      v46 = pBLVRenderParams->uViewportCenterY - v44;
       pParticle->uScreenSpaceY = pBLVRenderParams->uViewportCenterY - v44;
-      v47 = v45;
-      v48 = _48B561_mess_with_scaling_along_z(/*v46, */v47) * (signed __int64)pParticle->_screenspace_scale;
-      //_uParticleID = v48 >> 16;
-      pParticle->_screenspace_scale = v48 >> 16;
+      pParticle->_screenspace_scale = fixpoint_sub0(fixpoint_from_float(pParticle->flt_28), pParticle->_screenspace_scale);
       pParticle->sZValue = z;
       return true;
     }
@@ -403,9 +400,9 @@
   LODWORD(v6) = 0;
   HIDWORD(v6) = floorf(pParticle->flt_5C + 0.5f);
   //v7 = pParticle->flt_28;
-  pParticle->_screenspace_scale = v6 / x;
+  //pParticle->_screenspace_scale = v6 / x;
   //v8 = v7;
-  pParticle->_screenspace_scale = (unsigned __int64)(_48B561_mess_with_scaling_along_z(/*v9, */pParticle->flt_28) * (signed __int64)pParticle->_screenspace_scale) >> 16;
+  pParticle->_screenspace_scale = fixpoint_sub0(fixpoint_from_float(pParticle->flt_28), v6 / x);
   pParticle->sZValue = x;
   return true;
 }
@@ -446,10 +443,10 @@
   signed __int64 v29; // qtt@13
   //int v30; // eax@13
   //int v31; // ST1C_4@13
-  double v32; // st7@13
+  //double v32; // st7@13
   signed int v33; // eax@13
-  int v34; // ecx@13
-  float v35; // ST04_4@13
+  //int v34; // ecx@13
+  //float v35; // ST04_4@13
   int v36; // eax@13
   int v37; // esi@15
   //double v39; // [sp+10h] [bp-40h]@2
@@ -564,12 +561,10 @@
       //v31 = v6->_screenspace_scale;
       v6->uScreenSpaceX = pViewport->uScreenCenterX
                         - ((signed int)((unsigned __int64)(v6->_screenspace_scale * (signed __int64)v16) >> 16) >> 16);
-      v32 = v6->flt_28;
       v33 = (signed int)((unsigned __int64)(v6->_screenspace_scale * (signed __int64)v40) >> 16) >> 16;
-      v34 = pViewport->uScreenCenterY - v33;
+      //v34 = pViewport->uScreenCenterY - v33;
       v6->uScreenSpaceY = pViewport->uScreenCenterY - v33;
-      v35 = v32;
-      v6->_screenspace_scale = (unsigned __int64)(_48B561_mess_with_scaling_along_z(/*v34, */v35) * (signed __int64)v6->_screenspace_scale) >> 16;
+      v6->_screenspace_scale = fixpoint_sub0(fixpoint_from_float(v6->flt_28), v6->_screenspace_scale);
       v6->sZValue = X_4;
       v36 = v6->uScreenSpaceX;
       if ( v36 >= (signed int)pViewport->uViewportTL_X )
--- a/Party.cpp	Wed May 22 22:22:36 2013 +0600
+++ b/Party.cpp	Wed May 22 22:23:04 2013 +0600
@@ -28,6 +28,26 @@
 
 
 
+
+
+//----- (0044A56A) --------------------------------------------------------
+void Party::CountHirelings()
+{
+  field_70A = 0;
+
+  for (int i = 0; i < pNPCStats->uNumNewNPCs; ++i)
+  {
+    auto npc = pNPCStats->pNewNPCData + i;
+    if (npc->Hired() &&
+        (!pHirelings[0].pName || strcmp(npc->pName, pHirelings[0].pName)))
+    {
+      if (!pHirelings[1].pName || strcmp(npc->pName, pHirelings[1].pName))
+        ++field_70A;
+    }
+  }
+}
+
+
 // inlined
 //----- (mm6c::004858D0) --------------------------------------------------
 void Party::Zero()
@@ -331,9 +351,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 +366,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 +382,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 +400,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 +620,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 +662,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 +703,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 +744,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;
@@ -786,17 +806,17 @@
     pPartyBuffs[i].Reset();
 
 
-  pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] = 100;
+  pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] = 100;  // default character ui - stats
   uFlags = 0;
   memset(_autonote_bits, 0, 12);
   memset(_quest_bits, 0, 64);
   memset(pIsArtifactFound, 0, 29);
-  _449B7E_toggle_bit(_quest_bits, 1, 1);
-  _449B7E_toggle_bit(_quest_bits, 2, 1);
-  _449B7E_toggle_bit(_quest_bits, 3, 1);
-  _449B7E_toggle_bit(_quest_bits, 4, 1);
-  _449B7E_toggle_bit(_quest_bits, 5, 1);
-  _449B7E_toggle_bit(_quest_bits, 6, 1);
+  _449B7E_toggle_bit(_quest_bits, PARTY_QUEST_EMERALD_RED_POTION_ACTIVE, 1);
+  _449B7E_toggle_bit(_quest_bits, PARTY_QUEST_EMERALD_SEASHELL_ACTIVE, 1);
+  _449B7E_toggle_bit(_quest_bits, PARTY_QUEST_EMERALD_LONGBOW_ACTIVE, 1);
+  _449B7E_toggle_bit(_quest_bits, PARTY_QUEST_EMERALD_PLATE_ACTIVE, 1);
+  _449B7E_toggle_bit(_quest_bits, PARTY_QUEST_EMERALD_LUTE_ACTIVE, 1);
+  _449B7E_toggle_bit(_quest_bits, PARTY_QUEST_EMERALD_HAT_ACTIVE, 1);
 
   memset(field_3C._shop_ban_times,0,53*sizeof(__int64));
 
@@ -828,7 +848,7 @@
       v0 = pActors;//[0].pMonsterInfo.uMovementType;
       do
       {
-		if ( v0->Actor::CanAct() && v0->pMonsterInfo.uHostilityType != 4 && v0->pMonsterInfo.uMovementType != 5 )
+        if ( v0->Actor::CanAct() && v0->pMonsterInfo.uHostilityType != MonsterInfo::Hostility_Long && v0->pMonsterInfo.uMovementType != 5 )
         {
 		  v1 = abs(v0->vPosition.x - pParty->vPosition.x);
 		  v2 = abs(v0->vPosition.y - pParty->vPosition.y);
@@ -1015,8 +1035,8 @@
       memset(hireling, 0, sizeof(*hireling));
 
       pParty->field_709 = 0;
-      Party__CountHirelings();
-      viewparams->bRedrawGameUI = 1;
+      pParty->CountHirelings();
+      viewparams->bRedrawGameUI = true;
     }
   }
 }
--- a/Party.h	Wed May 22 22:22:36 2013 +0600
+++ b/Party.h	Wed May 22 22:23:04 2013 +0600
@@ -10,6 +10,13 @@
 
 enum PARTY_QUEST_BITS: unsigned __int32
 {
+  PARTY_QUEST_EMERALD_RED_POTION_ACTIVE = 1,
+  PARTY_QUEST_EMERALD_SEASHELL_ACTIVE = 2,
+  PARTY_QUEST_EMERALD_LONGBOW_ACTIVE = 3,
+  PARTY_QUEST_EMERALD_PLATE_ACTIVE = 4,
+  PARTY_QUEST_EMERALD_LUTE_ACTIVE = 5,
+  PARTY_QUEST_EMERALD_HAT_ACTIVE = 6,
+
   PARTY_QUEST_EVENMORN_MAP_FOUND = 64,
   PARTY_QUEST_FINISHED_EMERALD_ISLE = 136,
   PARTY_QUEST_FOUNTAIN_HARMONDALE = 206,
@@ -163,6 +170,7 @@
   bool _497FC5_check_party_perception_against_level();
   bool AddItem(ItemGen *pItem);
   void Yell();
+  void CountHirelings();
   
   static void SetGold(unsigned int uNumGold);
   static void TakeGold(unsigned int uNumGold);
--- a/Player.cpp	Wed May 22 22:22:36 2013 +0600
+++ b/Player.cpp	Wed May 22 22:23:04 2013 +0600
@@ -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
@@ -4641,31 +4531,25 @@
 //----- (0048EA46) --------------------------------------------------------
 int Player::_48EA46_calc_special_bonus_by_items(int a2)
 {
-  int v3; // esi@1
-  int v4; // edx@2
-  int v5; // eax@3
-  char *v6; // eax@4
-
-  v3 = 0;
-  while ( 1 )
-  {
-    if ( !HasItemEquipped((ITEM_EQUIP_TYPE)v3) )
-      goto LABEL_11;
-    v5 = pEquipment.pIndices[v3]  - 1;
-    if ( a2 != 17 )
-    {
-      if ( a2 != 24 || this->pInventoryItems[v5].uSpecEnchantmentType != 24 )
-        goto LABEL_11;
-      return 5;
-    }
-    v6 = (char *)this + 36 * v5;
-    if ( *((int *)v6 + 133) == 533 || *((int *)v6 + 136) == 17 )
-      return 50;
-LABEL_11:
-    ++v3;
-    if ( (signed int)v3 >= 16 )
-      return 0;
-  }
+  int inv_indx; // eax@3
+
+  for (int i=EQUIP_OFF_HAND; i<EQUIP_BOOK; ++i )
+      {
+      if ( !HasItemEquipped((ITEM_EQUIP_TYPE)i) )
+          continue;
+      inv_indx = pEquipment.pIndices[i]  - 1;
+      if (a2==17)
+          {
+          if ((pInventoryItems[inv_indx].uSpecEnchantmentType==17)||(pInventoryItems[inv_indx].uItemID=533)) //Elven Chainmail+Increases rate of Recovery
+              return 50;
+          }
+      if (a2==24)
+          {
+          if (pInventoryItems[inv_indx].uSpecEnchantmentType==24) //Increased Knockback.
+              return 5;
+          }
+      }
+  return 0;
 }
 
 //----- (0048EAAE) --------------------------------------------------------
@@ -5526,7 +5410,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 +5529,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 +5760,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 +6228,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 +6311,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 +6327,7 @@
     case 0x11:
     case 0x14:
     case 0x17:
-      BYTE4(v1) = 0;
+      this->uSex = SEX_MALE;
       break;
     case 4:
     case 5:
@@ -6461,13 +6341,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 +6790,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,880 +6817,698 @@
 //----- (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
+    signed int v5; // eax@17
+    int v8; // edx@39
+    char *v13; // eax@45
+    signed int v15; // edi@68
+    int v16; // edx@73
+    unsigned __int16 v17; // edi@73
+    unsigned int v18; // eax@73
+    const char *v22; // eax@84
+    int scroll_id; // esi@96
+    int v25; // eax@109
+    int v26; // eax@113
+    int new_mana_val; // edi@114
+    signed __int64 v28; // qax@120
+    __int64 v30; // edi@137
+    __int64 v32; // ST3C_4@137
+    __int64 v34; // ST34_4@137
+    unsigned __int16 v50; // [sp-Ch] [bp-38h]@120
+    const char *v66; // [sp-4h] [bp-30h]@69
+    signed int v67; // [sp-4h] [bp-30h]@77
+    const char *v68; // [sp-4h] [bp-30h]@89
+    char v72; // [sp+20h] [bp-Ch]@68
+    signed int v73; // [sp+24h] [bp-8h]@1
+    char*  v74; // [sp+24h] [bp-8h]@23
+    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;
+    if ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uEquipType == EQUIP_REAGENT )
         {
-LABEL_167:
-          v68 = pParty->pPickedItem.GetDisplayName();
-          v58 = pGlobalTXT_LocalizationStrings[36];
-          goto LABEL_90;
+        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();
+            sprintfex(pTmpBuf, pGlobalTXT_LocalizationStrings[36], v68);//"%s can not be used that way"
+            ShowStatusBarString(pTmpBuf, 2);
+            pAudioPlayer->PlaySound((SoundID)27, 0, 0, -1, 0, 0, 0, 0);
+            return;
+            }
+        pAudioPlayer->PlaySound((SoundID)211, 0, 0, -1, 0, 0, 0, 0);
+
+        if ( pGUIWindow_CurrentMenu && pGUIWindow_CurrentMenu->eWindowType != WINDOW_null)
+            {
+            pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 0, 0);
+            }
+        if ( v73 )
+            {
+            if ( pParty->bTurnBasedModeOn )
+                {
+                pParty->pTurnBasedPlayerRecoveryTimes[player_num-1] = 100;
+                thisb->SetRecoveryTime(100);
+                pTurnEngine->_40471C();
+                }
+            else
+                {
+                thisb->SetRecoveryTime((signed __int64)(flt_6BE3A4_debug_recmod1 * 213.3333333333333));
+                }
+            }
+        pMouse->RemoveHoldingItem();
+        return;
+
+
         }
-        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);
-        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;
-        }
-        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;
+        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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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);
+            break;
+        case 257: //Air Resistance
+            v50 = 3 * 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 * 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 * 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 * 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 * 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();
+            sprintfex(pTmpBuf, pGlobalTXT_LocalizationStrings[36], v68);//"%s can not be used that way"
+            ShowStatusBarString(pTmpBuf, 2u);
+            pAudioPlayer->PlaySound((SoundID)27, 0, 0, -1, 0, 0, 0, 0);
+            return;
+            }
+        pAudioPlayer->PlaySound((SoundID)210, 0, 0, -1, 0, 0, 0, 0);
+        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->pTurnBasedPlayerRecoveryTimes[player_num-1] = 100;
+                thisb->SetRecoveryTime(100);
+                pTurnEngine->_40471C();
+                }
+            else
+                {
+                thisb->SetRecoveryTime((signed __int64)(flt_6BE3A4_debug_recmod1 * 213.3333333333333));
+                }
+            }
+        pMouse->RemoveHoldingItem();
+        return;
+    
         }
-        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()];
+        sprintfex(pTmpBuf, pGlobalTXT_LocalizationStrings[382], v68);
+        ShowStatusBarString(pTmpBuf, 2u);
+        pAudioPlayer->PlaySound((SoundID)27, 0, 0, -1, 0, 0, 0, 0);
+        return;
+            }
+        if ( bUnderwater == 1 )
+            {
+            ShowStatusBarString(pGlobalTXT_LocalizationStrings[652], 2u);//"You can not do that while you are underwater!"
+            pAudioPlayer->PlaySound((SoundID)27, 0, 0, -1, 0, 0, 0, 0);
+            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();
+            sprintfex(pTmpBuf, pGlobalTXT_LocalizationStrings[380], v66);//"You already know the %s spell"
+            ShowStatusBarString(pTmpBuf, 2u);
+            pAudioPlayer->PlaySound((SoundID)27, 0, 0, -1, 0, 0, 0, 0);
+            return;
+            }
+        if ( !pParty->pPlayers[player_num-1].CanAct() )
+            {
+            v66 = aCharacterConditionNames[v3->GetMajorConditionIdx()];
+            sprintfex(pTmpBuf, pGlobalTXT_LocalizationStrings[382], v66);//"That player is %s"
+            ShowStatusBarString(pTmpBuf, 2u);
+            pAudioPlayer->PlaySound((SoundID)27, 0, 0, -1, 0, 0, 0, 0);
+            return;
+            }
+        v16 = v15 % 11 + 1;
+        v17 = v3->pActiveSkills[v15 / 11 + 12];
+        v18 = SkillToMastery(v17) - 1;
+        switch (v18)
+            {
+        case 0: v67 = 4; break;
+        case 1: v67 = 7; break;
+        case 2: v67 = 10; break;
+        case 3: v67 = 11; break;
+        default:
+            v67 = player_num;   
+            }
+  
+        if ( v16 > v67 || !v17 )
+            {
+            v22 = pParty->pPickedItem.GetDisplayName();
+            sprintfex(pTmpBuf, pGlobalTXT_LocalizationStrings[381], v22); //"You don't have the skill to learn %s"
+            ShowStatusBarString(pTmpBuf, 2u);
+            v3->PlaySound((PlayerSpeech)20, 0);
+            return; 
+            }
+     //   v72 = 1;
+        v3->PlaySound(SPEECH_21, 0);
+        v73 = 0;
+
+
+        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->pTurnBasedPlayerRecoveryTimes[player_num-1] = 100;
+                thisb->SetRecoveryTime(100);
+                pTurnEngine->_40471C();
+                }
+            else
+                {
+                thisb->SetRecoveryTime((signed __int64)(flt_6BE3A4_debug_recmod1 * 213.3333333333333));
+                }
+            }
+        pMouse->RemoveHoldingItem();
+        return;
+
+        }
+
+    if ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uEquipType == EQUIP_MESSAGE_SCROLL )
+
+        {
+        if ( pParty->pPlayers[player_num-1].CanAct() )
+            {
+            CreateMsgScrollWindow(pParty->pPickedItem.uItemID);
+            v3->PlaySound(SPEECH_37, 0);
+            return;
+            }
+        v68 = aCharacterConditionNames[v3->GetMajorConditionIdx()];
+        sprintfex(pTmpBuf, pGlobalTXT_LocalizationStrings[382], v68);
+        ShowStatusBarString(pTmpBuf, 2u);
+        pAudioPlayer->PlaySound((SoundID)27, 0, 0, -1, 0, 0, 0, 0);
+        return;
+        }
+    else
+        {
+        if ( pParty->pPickedItem.uItemID == 616 ) //Genie Lamp
+            {
+            thisa = pParty->uCurrentMonthWeek + 1;
+            if ( pParty->uCurrentMonth >= 7 )
+                v74 = NULL;
+            else
+                v74 = aAttributeNames[pParty->uCurrentMonth];
+            switch ( pParty->uCurrentMonth )
+                {
+            case 0:
+                v3->uMight += thisa;
+                sprintf(pTmpBuf, "+%u %s %s", thisa, v74, pGlobalTXT_LocalizationStrings[121]);//"Permanent"	
+                break;
+            case 1:
+                v3->uIntelligence += thisa;
+                sprintf(pTmpBuf, "+%u %s %s", thisa, v74, pGlobalTXT_LocalizationStrings[121]);//"Permanent"	
+                break;
+            case 2:
+                v3->uWillpower += thisa;
+                sprintf(pTmpBuf, "+%u %s %s", thisa, v74, pGlobalTXT_LocalizationStrings[121]);//"Permanent"	
+                break;
+            case 3:
+                v3->uEndurance += thisa;
+                sprintf(pTmpBuf, "+%u %s %s", thisa, v74, pGlobalTXT_LocalizationStrings[121]);//"Permanent"	
+                break;
+            case 4:
+                v3->uAccuracy += thisa;
+               sprintf(pTmpBuf, "+%u %s %s", thisa, v74, pGlobalTXT_LocalizationStrings[121]);//"Permanent"	
+                break;
+            case 5:
+                v3->uSpeed += thisa;
+                sprintf(pTmpBuf, "+%u %s %s", thisa, v74, pGlobalTXT_LocalizationStrings[121]);//"Permanent"	
+                break;
+            case 6:
+                v3->uLuck += thisa;
+               sprintf(pTmpBuf, "+%u %s %s", thisa, v74, pGlobalTXT_LocalizationStrings[121]);//"Permanent"	
+                break;
+            case 7:
+                party_finds_gold(1000 * thisa, 0);
+                sprintf(pTmpBuf, "+%u %s", 1000 * thisa, pGlobalTXT_LocalizationStrings[97]);//"Gold"
+                break;
+            case 8:
+                Party::GiveFood(5 * thisa); 
+                sprintf(pTmpBuf, "+%u %s",5 * thisa , pGlobalTXT_LocalizationStrings[653]);//"Food"
+                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 )
+                v3->uSkillPoints += 2 * thisa;
+                sprintf(pTmpBuf, "+%u %s", 2 * thisa, pGlobalTXT_LocalizationStrings[LOCSTR_SKILL_POINTS]);
+                break;
+            case 10:
+                v3->uExperience += 2500 * thisa;
+                sprintf(pTmpBuf, "+%u %s", 2500 * thisa, pGlobalTXT_LocalizationStrings[LOCSTR_EXPIRIENCE]);
+                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;
+                    }
+                sprintf(pTmpBuf, "+%u %s %s", thisa, v13, pGlobalTXT_LocalizationStrings[121]);
+                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)219, 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 ) //Horseshoe
+                {
+                pGame->pStru6Instance->SetPlayerBuffAnim(0x97u, player_num - 1);
+                v5 = PID(OBJECT_Player,player_num + 49);
+                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);
-        }
-LABEL_187:
+                {
+   
+                v68 = pParty->pPickedItem.GetDisplayName();
+                sprintfex(pTmpBuf, pGlobalTXT_LocalizationStrings[36],v68);//"%s can not be used that way"
+                ShowStatusBarString(pTmpBuf, 2u);
+                pAudioPlayer->PlaySound((SoundID)27, 0, 0, -1, 0, 0, 0, 0);
+                return;
+                }
+
         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);
-    }
-  }
-}
+
+    }
 
 
 
 //----- (00449BB4) --------------------------------------------------------
 bool Player::CompareVariable( enum VariableType VarNum, signed int pValue )
-	{
+{
   Player *v3; // esi@1
   signed int v4; // edi@1
   unsigned int v5; // eax@8
@@ -7946,8 +7643,8 @@
       case VAR_NPCs2:
         return pNPCStats->pNewNPCData[pValue].Hired();
       case VAR_MonthEquals|VAR_CurrentSP:
-        test_bit_value = 0x80u >> ((signed __int16)a1 - 1) % 8;
-        our_bit_value = this->field_1A50[((signed __int16)a1 - 1)/8];
+        test_bit_value = 0x80u >> ((signed __int16)pValue - 1) % 8;
+        our_bit_value = this->field_1A50[((signed __int16)pValue - 1)/8];
         if ( !((unsigned __int8)test_bit_value & our_bit_value) )
           return v4 >= pValue;
         v4 = pValue;
@@ -8008,8 +7705,8 @@
   }
   if ( VarNum == VAR_AutoNotes )
   {
-    test_bit_value = 0x80u >> ((signed __int16)(a1 - 1) - 1) % 8;
-    our_bit_value = pParty->_autonote_bits[((signed __int16)(a1 - 1) - 1) /8];
+    test_bit_value = 0x80u >> ((signed __int16)(pValue - 1) - 1) % 8;
+    our_bit_value = pParty->_autonote_bits[((signed __int16)(pValue - 1) - 1) /8];
     if ( !((unsigned __int8)test_bit_value & our_bit_value) )
       return false;
     return true;
@@ -8078,8 +7775,8 @@
           v12 = GetActualAge();
           goto _j_cmp_against_arg;
         case VAR_Award:
-          test_bit_value = 0x80u >> ((signed __int16)a1 - 1) % 8;
-          our_bit_value = this->_guilds_member_bits[((signed __int16)a1 - 1) /8];
+          test_bit_value = 0x80u >> ((signed __int16)pValue - 1) % 8;
+          our_bit_value = this->_guilds_member_bits[((signed __int16)pValue - 1) /8];
           if ( !((unsigned __int8)test_bit_value & our_bit_value) )
             return true;
           return false;
@@ -8379,8 +8076,8 @@
             case VAR_NPCs2:
               pParty->field_709 = 0;
               LOBYTE(pNPCStats->pNewNPCData[var_value].uFlags) |= 0x80u;
-              Party__CountHirelings();
-              viewparams->bRedrawGameUI = 1;
+              pParty->CountHirelings();
+              viewparams->bRedrawGameUI = true;
               break;
             case VAR_NumSkillPoints:
               this->uSkillPoints = var_value;
@@ -8648,19 +8345,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:
@@ -9335,8 +9032,8 @@
           case VAR_NPCs2:
             pParty->field_709 = 0;
             LOBYTE(pNPCStats->pNewNPCData[val].uFlags) |= 0x80u;
-            Party__CountHirelings();
-            viewparams->bRedrawGameUI = 1;
+            pParty->CountHirelings();
+            viewparams->bRedrawGameUI = true;
             break;
           case VAR_NumSkillPoints:
             Dst->uSkillPoints += val;
@@ -9451,8 +9148,8 @@
               {
                 pParty->field_709 = 0;
                 LOBYTE(pNPCStats->pNewNPCData[(int)pValue].uFlags) &= 0x7Fu;
-                Party__CountHirelings();
-                viewparams->bRedrawGameUI = 1;
+                pParty->CountHirelings();
+                viewparams->bRedrawGameUI = true;
               }
               break;
             case 241:
@@ -9478,7 +9175,7 @@
               if ( pParty->pHirelings[1].uProfession == pValue )
                 memset(&pParty->pHirelings[1], 0, 0x4Cu);
               pParty->field_709 = 0;
-              Party__CountHirelings();
+              pParty->CountHirelings();
               break;
             case 243:
               v17 = (char *)&this->uSkillPoints;
--- a/Player.h	Wed May 22 22:22:36 2013 +0600
+++ b/Player.h	Wed May 22 22:23:04 2013 +0600
@@ -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	Wed May 22 22:22:36 2013 +0600
+++ b/Render.cpp	Wed May 22 22:23:04 2013 +0600
@@ -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	Wed May 22 22:22:36 2013 +0600
+++ b/Render.h	Wed May 22 22:23:04 2013 +0600
@@ -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	Wed May 22 22:22:36 2013 +0600
+++ b/SaveLoad.cpp	Wed May 22 22:23:04 2013 +0600
@@ -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	Wed May 22 22:22:36 2013 +0600
+++ b/Spells.cpp	Wed May 22 22:23:04 2013 +0600
@@ -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	Wed May 22 22:22:36 2013 +0600
+++ b/SpriteObject.cpp	Wed May 22 22:23:04 2013 +0600
@@ -1,5 +1,6 @@
 #include <assert.h>
 
+#include "BSPModel.h"
 #include "SpriteObject.h"
 #include "Party.h"
 #include "TurnEngine.h"
--- a/Sprites.cpp	Wed May 22 22:22:36 2013 +0600
+++ b/Sprites.cpp	Wed May 22 22:23:04 2013 +0600
@@ -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	Wed May 22 22:22:36 2013 +0600
+++ b/Sprites.h	Wed May 22 22:23:04 2013 +0600
@@ -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/Time.cpp	Wed May 22 22:22:36 2013 +0600
+++ b/Time.cpp	Wed May 22 22:23:04 2013 +0600
@@ -21,7 +21,7 @@
 //----- (00426317) --------------------------------------------------------
 unsigned __int64 Timer::Time()
 {
-  uint v2 = (timeGetTime() * 128) / 1000;
+  uint v2 = TimeQuant * timeGetTime() / 1000;
   if (v2 < uStartTime)
     uStartTime = 0;
   return v2;
--- a/Time.h	Wed May 22 22:22:36 2013 +0600
+++ b/Time.h	Wed May 22 22:23:04 2013 +0600
@@ -40,6 +40,14 @@
   unsigned int uTimeElapsed;
   int dt_in_some_format;
   unsigned int uTotalGameTimeElapsed;
+
+  static const unsigned int TimeQuant = 128;
+  static const unsigned int Minute = 2 * TimeQuant;
+  static const unsigned int Hour = 60 * Minute;
+  static const unsigned int Day = 24 * Hour;
+  static const unsigned int Week = 7 * Day;
+  static const unsigned int Month = 4 * Week;
+  static const unsigned int Year = 12 * Month;
 };
 
 #pragma pack(pop)
@@ -47,11 +55,4 @@
 
 
 extern Timer *pMiscTimer;
-extern Timer *pEventTimer;
-
-const unsigned int Minute = 256;
-const unsigned int Hour = 60 * Minute;
-const unsigned int Day = 24 * Hour;
-const unsigned int Week = 7 * Day;
-const unsigned int Month = 4 * Week;
-const unsigned int Year = 12 * Month;
\ No newline at end of file
+extern Timer *pEventTimer;
\ No newline at end of file
--- a/UIBooks.cpp	Wed May 22 22:22:36 2013 +0600
+++ b/UIBooks.cpp	Wed May 22 22:23:04 2013 +0600
@@ -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"
@@ -58,32 +36,59 @@
     case WINDOW_QuestBook:     BookUI_Questbook_Draw();  break;
     case WINDOW_AutonotesBook: BookUI_Autonotes_Draw();  break;
     case WINDOW_MapsBook:      BookUI_Map_Draw();        break;
-    case WINDOW_CalendarBook:  BookUI_Calendar_Draw();      break;
+    case WINDOW_CalendarBook:  BookUI_Calendar_Draw();   break;
+    case WINDOW_JournalBook:   BookUI_Journal_Draw();    break;
+
     case WINDOW_LloydsBeacon:  DrawLloydBeaconsScreen(); break;
     case WINDOW_TownPortal:    DrawTownPortalScreen();   break;
-    case WINDOW_HistoryBook:   DrawBook_History();       break;
   }
 }
 
 
 
+//----- (00413D3C) --------------------------------------------------------
+static const char *GetDayPart()
+{
+  if (pParty->uCurrentHour <= 4)
+    return pGlobalTXT_LocalizationStrings[567]; // "Night"
+  else if (pParty->uCurrentHour == 5)
+    return pGlobalTXT_LocalizationStrings[55]; // "Dawn"
+  else if (pParty->uCurrentHour == 20)
+    return pGlobalTXT_LocalizationStrings[566]; // "Dusk"
+  else
+    return pGlobalTXT_LocalizationStrings[56]; // "Day"
+}
+
+
+
 //----- (00413D6F) --------------------------------------------------------
 void BookUI_Calendar_Draw()
 {
   unsigned int v0; // esi@1
-  char *v1; // eax@5
+  //char *v1; // eax@5
   int v2; // ecx@5
   char *v3; // eax@6
   GUIWindow a1; // [sp+Ch] [bp-60h]@5
   unsigned int v6; // [sp+60h] [bp-Ch]@1
-  int v7; // [sp+64h] [bp-8h]@1
-  int a5; // [sp+68h] [bp-4h]@1
+  //int v7; // [sp+64h] [bp-8h]@1
+  //int a5; // [sp+68h] [bp-4h]@1
+
+  
+  static unsigned int pDayMoonPhase[28] = // 4E1B18
+  {
+    0, 0, 0,
+    1, 1, 1, 1,
+    2, 2, 2,
+    3, 3, 3, 3,
+    4, 4, 4,
+    3, 3, 3, 3,
+    2, 2, 2,
+    1, 1, 1, 1
+  };
+
 
   v0 = pParty->uCurrentHour;
-  v6 = pMapStats->GetMapInfo(pCurrentMapName);
-  a5 = TargetColor(0x4Bu, 0x4Bu, 0x4Bu);
   pRenderer->DrawTextureIndexed(pViewport->uViewportTL_X, pViewport->uViewportTL_Y, pSpellBookPagesTextr_13);
-  v7 = (unsigned __int8)pDayMoonPhase[pParty->uDaysPlayed];
   if ( (signed int)v0 <= 12 )
   {
     if ( !v0 )
@@ -99,7 +104,9 @@
   a1.uFrameHeight = game_viewport_height;
   a1.uFrameZ = game_viewport_z;
   a1.uFrameW = game_viewport_w;
-  a1.DrawTitleText(pBook2Font, 0, 0x16u, 0, pGlobalTXT_LocalizationStrings[186], 3u);
+  a1.DrawTitleText(pBook2Font, 0, 0x16u, ui_book_calendar_title_color, pGlobalTXT_LocalizationStrings[186], 3); // "Time in Erathia"
+
+  v2 = 0;
   if ( pParty->uCurrentHour >= 12 )
   {
     if ( pParty->uCurrentHour >= 24 )
@@ -107,42 +114,40 @@
 	else
 		v2=1;
   }
-  else
-    v2=0;
-  v1 = GetDayPart();
-  sprintf(
-    pTmpBuf,
-    "%s\t100:\t110%d:%02d %s - %s",
-    pGlobalTXT_LocalizationStrings[526],
-    v0,
-    pParty->uCurrentMinute,
-    aAMPMNames[v2],
-    v1);
-  a1.DrawText(pBookFont, 70, 55, a5, pTmpBuf, 0, 0, 0);
-  sprintf(
-    pTmpBuf,
-    "%s\t100:\t110%d - %s",
-    pGlobalTXT_LocalizationStrings[56],
-    pParty->uDaysPlayed + 1,
-    aDayNames[pParty->uDaysPlayed % 7]);
-  a1.DrawText(pBookFont, 70, 2 * LOBYTE(pBookFont->uFontHeight) + 49, a5, pTmpBuf, 0, 0, 0);
-  sprintf(
-    pTmpBuf,
-    "%s\t100:\t110%d - %s",
-    pGlobalTXT_LocalizationStrings[146],
-    pParty->uCurrentMonth + 1,
-    aMonthNames[pParty->uCurrentMonth]);
-  a1.DrawText(pBookFont, 70, 4 * LOBYTE(pBookFont->uFontHeight) + 43, a5, pTmpBuf, 0, 0, 0);
-  sprintf(pTmpBuf, "%s\t100:\t110%d", pGlobalTXT_LocalizationStrings[245], pParty->uCurrentYear);
-  a1.DrawText(pBookFont, 70, 6 * LOBYTE(pBookFont->uFontHeight) + 37, a5, pTmpBuf, 0, 0, 0);
-  sprintf(pTmpBuf, "%s\t100:\t110%s", pGlobalTXT_LocalizationStrings[530], aMoonPhaseNames[v7]);
-  a1.DrawText(pBookFont, 70, 8 * LOBYTE(pBookFont->uFontHeight) + 31, a5, pTmpBuf, 0, 0, 0);
+
+  sprintf(pTmpBuf, "%s\t100:\t110%d:%02d %s - %s",
+          pGlobalTXT_LocalizationStrings[526], // "Time"
+          v0,
+          pParty->uCurrentMinute,
+          aAMPMNames[v2],
+          GetDayPart());
+  a1.DrawText(pBookFont, 70, 55, ui_book_calendar_time_color, pTmpBuf, 0, 0, 0);
+
+  sprintf(pTmpBuf, "%s\t100:\t110%d - %s",
+          pGlobalTXT_LocalizationStrings[56], // "Day"
+          pParty->uDaysPlayed + 1,
+          aDayNames[pParty->uDaysPlayed % 7]);
+  a1.DrawText(pBookFont, 70, 2 * LOBYTE(pBookFont->uFontHeight) + 49, ui_book_calendar_day_color, pTmpBuf, 0, 0, 0);
+
+  sprintf(pTmpBuf, "%s\t100:\t110%d - %s",
+          pGlobalTXT_LocalizationStrings[146], // "Month"
+          pParty->uCurrentMonth + 1,
+          aMonthNames[pParty->uCurrentMonth]);
+  a1.DrawText(pBookFont, 70, 4 * LOBYTE(pBookFont->uFontHeight) + 43, ui_book_calendar_month_color, pTmpBuf, 0, 0, 0);
+
+  sprintf(pTmpBuf, "%s\t100:\t110%d", pGlobalTXT_LocalizationStrings[245], pParty->uCurrentYear); // "Year"
+  a1.DrawText(pBookFont, 70, 6 * LOBYTE(pBookFont->uFontHeight) + 37, ui_book_calendar_year_color, pTmpBuf, 0, 0, 0);
+
+  sprintf(pTmpBuf, "%s\t100:\t110%s", pGlobalTXT_LocalizationStrings[530], aMoonPhaseNames[pDayMoonPhase[pParty->uDaysPlayed]]); // "Moon"
+  a1.DrawText(pBookFont, 70, 8 * LOBYTE(pBookFont->uFontHeight) + 31, ui_book_calendar_moon_color, pTmpBuf, 0, 0, 0);
+  
+  v6 = pMapStats->GetMapInfo(pCurrentMapName);
   if ( v6 )
     v3 = pMapStats->pInfos[v6].pName;
   else
     v3 = "Unknown";
-  sprintf(pTmpBuf, "%s\t100:\t110%s", pGlobalTXT_LocalizationStrings[531], v3);
-  a1.DrawText(pBookFont, 70, 10 * LOBYTE(pBookFont->uFontHeight) + 25, a5, pTmpBuf, 0, 0, 0);
+  sprintf(pTmpBuf, "%s\t100:\t110%s", pGlobalTXT_LocalizationStrings[531], v3); // "Location"
+  a1.DrawText(pBookFont, 70, 10 * LOBYTE(pBookFont->uFontHeight) + 25, ui_book_calendar_location_color, pTmpBuf, 0, 0, 0);
 }
 
 
@@ -159,7 +164,7 @@
   if ( !pIcons_LOD->uNumPrevLoadedFiles )
     pIcons_LOD->uNumPrevLoadedFiles = pIcons_LOD->uNumLoadedFiles;
 
-  pAudioPlayer->PlaySound((SoundID)230, 0, 0, -1, 0, 0, 0, 0);
+  pAudioPlayer->PlaySound(SOUND_OpenBook, 0, 0, -1, 0, 0, 0, 0);
   pSpellBookPagesTextr_9 = pIcons_LOD->LoadTexturePtr("book", TEXTURE_16BIT_PALETTE);
   pTexture_pagemask = pIcons_LOD->LoadTexturePtr("pagemask", TEXTURE_16BIT_PALETTE);
   pTexture_506448   = pIcons_LOD->LoadTexturePtr("ib-m5-u", TEXTURE_16BIT_PALETTE);
@@ -167,7 +172,7 @@
   pTexture_50643C   = pIcons_LOD->LoadTexturePtr("ib-m6-u",TEXTURE_16BIT_PALETTE);
   //v0 = 1;
 
-  static const char *texNames[9] =
+  static const char *texNames[9] = // 004E24EC
   {
     "SBFB00", "SBAB00", "SBWB00", "SBEB00",
     "SBSB00", "SBMB00", "SBBB00", "SBLB00",
@@ -191,10 +196,12 @@
 void InitializeBookFonts()
 {
   pAudioPlayer->StopChannels(-1, -1);
+
   ++pIcons_LOD->uTexturePacksCount;
   if ( !pIcons_LOD->uNumPrevLoadedFiles )
     pIcons_LOD->uNumPrevLoadedFiles = pIcons_LOD->uNumLoadedFiles;
-  pAudioPlayer->PlaySound((SoundID)230, 0, 0, -1, 0, 0, 0, 0);
+
+  pAudioPlayer->PlaySound(SOUND_OpenBook, 0, 0, -1, 0, 0, 0, 0);
   pTexture_mapbordr = pIcons_LOD->LoadTexturePtr("mapbordr", TEXTURE_16BIT_PALETTE);
   pBookFont = LoadFont("book.fnt", "FONTPAL", NULL);
   pBook2Font = LoadFont("book2.fnt", "FONTPAL", NULL);
@@ -243,12 +250,11 @@
 }
 
 //----- (0041140B) --------------------------------------------------------
-GUIWindow *sub_41140B()
+void sub_41140B()
 {
   signed int v0; // esi@1
   GUIButton *v1; // eax@3
   GUIButton *v2; // esi@4
-  GUIWindow *result; // eax@5
 
   v0 = 0;
   do
@@ -258,7 +264,7 @@
     --v0;
   }
   while ( v0 >= -11 );
-  pIcons_LOD->_40F9C5();
+  pIcons_LOD->SyncLoadedFilesCount();
   v1 = pGUIWindow_CurrentMenu->pControlsHead;
   if ( v1 )
   {
@@ -272,9 +278,7 @@
   }
   pGUIWindow_CurrentMenu->pControlsHead = 0;
   pGUIWindow_CurrentMenu->pControlsTail = 0;
-  result = pGUIWindow_CurrentMenu;
   pGUIWindow_CurrentMenu->uNumControls = 0;
-  return result;
 }
 
 //----- (00411473) --------------------------------------------------------
@@ -289,7 +293,7 @@
       pTextures_tabs[i][0]->Release();
       pTextures_tabs[i][1]->Release();
       }
-  pAudioPlayer->PlaySound((SoundID)231, 0, 0, -1, 0, 0, 0, 0);
+  pAudioPlayer->PlaySound(SOUND_CloseBook, 0, 0, -1, 0, 0, 0, 0);
   pIcons_LOD->_4114F2();
 }
 
@@ -298,19 +302,18 @@
 void OnCloseSpellBook()
 {
   pAllocator->FreeChunk(pSpellFont);
-  pSpellFont = 0;
+  pSpellFont = nullptr;
   pAllocator->FreeChunk(pBookFont);
-  pBookFont = 0;
+  pBookFont = nullptr;
   pAllocator->FreeChunk(pBook2Font);
-  pBook2Font = 0;
+  pBook2Font = nullptr;
   pAllocator->FreeChunk(pAutonoteFont);
-  pAutonoteFont = 0;
+  pAutonoteFont = nullptr;
   pTexture_mapbordr->Release();
-  pAudioPlayer->PlaySound((SoundID)231, 0, 0, -1, 0, 0, 0, 0);
+  pAudioPlayer->PlaySound(SOUND_CloseBook, 0, 0, -1, 0, 0, 0, 0);
   pIcons_LOD->_4114F2();
   dword_506364 = 0;
 }
-// 506364: using guessed type int dword_506364;
 
 
 
@@ -318,224 +321,8 @@
 
 
 
-//----- (00412AF9) --------------------------------------------------------
-void sub_412AF9()
-{
-  int v0; // ecx@1
-
-  v0 = 0;
-  if ( uActiveCharacter )
-	  v0 = pParty->pPlayers[uActiveCharacter-1].lastOpenedSpellbookPage;//*((char *)&pParty->pPartyBuffs[5].uExpireTime + 6972 * uActiveCharacter + 2);
-  pRenderer->DrawTextureIndexed(8u, 8u, pSpellBookPagesTextr[v0]);
-  pRenderer->DrawTextureIndexed(0x1DCu, 0x1C2u, pTexture_50643C);
-  pRenderer->DrawTextureIndexed(0x231u, 0x1C2u, pTexture_506448);
-}
-
-//----- (00412B58) --------------------------------------------------------
-void DrawSpellBookContent()
-{
-  Player *v0; // ebx@1
-  int v1; // ebp@1
-  unsigned int v2; // eax@1
-  Texture *v3; // edi@1
-  int v4; // esi@1
-  Texture *v5; // eax@3
-  Texture *v6; // edx@5
-  int v7; // eax@8
-  int v8; // eax@11
-  POINT *v9; // esi@13
-  int v10; // eax@13
-  Texture *v11; // edx@14
-  int v12; // eax@15
-  signed int v13; // ecx@18
-  unsigned int v14; // esi@18
-  unsigned int v15; // edi@18
-  Texture *pPageTexture; // eax@21
-  unsigned int v17; // [sp-Ch] [bp-2Ch]@8
-  unsigned int v18; // [sp-Ch] [bp-2Ch]@15
-  unsigned int v19; // [sp-8h] [bp-28h]@8
-  unsigned int v20; // [sp-8h] [bp-28h]@15
-  Texture *v21; // [sp-4h] [bp-24h]@15
-  signed int v22; // [sp-4h] [bp-24h]@22
-  Texture *v23; // [sp+10h] [bp-10h]@5
-  POINT a2; // [sp+18h] [bp-8h]@13
-  POINT v24;
-  int v25;
-
-  sub_412AF9();
-  v0 = pPlayers[uActiveCharacter];
-  v1 = 11 * v0->lastOpenedSpellbookPage;
-  v2 = pIcons_LOD->FindTextureByName("Pending");
-  v3 = pIcons_LOD->GetTexture(v2);
-  pRenderer->ClearZBuffer(0, 479);
-  v4 = 1;
-  if ( __OFSUB__(v1, v1 + 11) ^ 1 )
-  {
-    do
-    {
-      if ( *(&v0->_guilds_member_bits[v1 + 63] + v4) )
-      {
-        v5 = (Texture *)dword_506408[v4];
-        if ( v5 != v3 )
-        {
-          if ( quick_spell_at_page == v4 )
-          {
-            v6 = dword_5063D8[v4];
-            v23 = dword_5063D8[v4];
-          }
-          else
-          {
-            v23 = dword_506408[v4];
-            v6 = v5;
-          }
-          if ( v6->pLevelOfDetail0_prolly_alpha_mask )
-          {
-			v7 = v0->lastOpenedSpellbookPage;
-           // v7 =  (12 * v0->lastOpenedSpellbookPage + pSpellbookSpellIndices[v0->lastOpenedSpellbookPage][v4]);
-            v19 = pViewport->uViewportTL_Y +  pIconPos[v7][pSpellbookSpellIndices[v7][v4]].Ypos;
-            v17 = pViewport->uViewportTL_X +  pIconPos[v7][pSpellbookSpellIndices[v7][v4]].Xpos;
-            if ( BYTE1(v6->pBits) & 2 )
-              pRenderer->DrawTextureTransparent(v17, v19, v6);
-            else
-              pRenderer->DrawTextureIndexed(v17, v19, v6);
-            pRenderer->DrawMaskToZBuffer(pIconPos[v7][pSpellbookSpellIndices[v7][v4]].Xpos,
-				               pIconPos[v7][pSpellbookSpellIndices[v7][v4]].Ypos, v23, v4);
-          }
-        }
-      }
-      ++v4;
-    }
-    while ( v4 + v1 - 1 < v1 + 11 );
-  }
-  v9 = pMouse->GetCursorPos(&a2);
-  v10 = pRenderer->pActiveZBuffer[v9->x + pSRZBufferLineOffsets[pMouse->GetCursorPos(&v24)->y]] & 0xFFFF;
-  if ( v10 )
-  {
-    v11 = dword_5063D8[v10];
-    if ( v11->pLevelOfDetail0_prolly_alpha_mask )
-    {
-      v21 = dword_5063D8[v10];
-	  v12 = v0->lastOpenedSpellbookPage;
-    //  v12 = (12 * v0->lastOpenedSpellbookPage + pSpellbookSpellIndices[v0->lastOpenedSpellbookPage][v10]);
-      v20 = pViewport->uViewportTL_Y +  pIconPos[v12][pSpellbookSpellIndices[v12][v10]].Ypos;
-      v18 = pViewport->uViewportTL_X +  pIconPos[v12][pSpellbookSpellIndices[v12][v10]].Xpos;
-      if ( BYTE1(v11->pBits) & 2 )
-        pRenderer->DrawTextureTransparent(v18, v20, v21);
-      else
-        pRenderer->DrawTextureIndexed(v18, v20, v21);
-    }
-  }
-  v13 = 0;
-  a2.x = (LONG)&v0->pActiveSkills[12];
-  v14 = (unsigned int)&v0->pActiveSkills[12];
-  v15 = (unsigned int)&v0->pActiveSkills[12];
-  v25 = 0;
-  do
-  {
-    if ( *(short *)a2.x )
-    {
-      if ( v0->lastOpenedSpellbookPage == v13 )
-      {
-        pPageTexture = pTextures_tabs[v13][1];
-        switch ( v13 )
-        {
-          case 0:
-            v14 = 406;
-            v22 = 9;
-            goto LABEL_27;
-          case 1:
-            v14 = 406;
-            goto LABEL_38;
-          case 2:
-            v14 = 406;
-            v22 = 84;
-            goto LABEL_27;
-          case 3:
-            v14 = 406;
-            goto LABEL_26;
-          case 4:
-            v14 = 407;
-            goto LABEL_29;
-          case 5:
-            v15 = 196;
-            goto LABEL_34;
-          case 6:
-            v15 = 234;
-            goto LABEL_34;
-          case 7:
-            v15 = 272;
-            goto LABEL_34;
-          case 8:
-            v15 = 309;
-LABEL_34:
-            v14 = 405;
-            break;
-          default:
-            break;
-        }
-      }
-      else
-      {
-        pPageTexture = pTextures_tabs[v13][0];
-        switch ( v13 )
-        {
-          case 0:
-            v14 = 415;
-            v22 = 10;
-            goto LABEL_27;
-          case 1:
-            v14 = 415;
-LABEL_38:
-            v22 = 46;
-            goto LABEL_27;
-          case 2:
-            v14 = 415;
-            v22 = 83;
-            goto LABEL_27;
-          case 3:
-            v14 = 415;
-LABEL_26:
-            v22 = 121;
-LABEL_27:
-            v15 = v22;
-            break;
-          case 4:
-            v14 = 415;
-LABEL_29:
-            v15 = 158;
-            break;
-          case 5:
-            v15 = 196;
-            goto LABEL_46;
-          case 6:
-            v15 = 234;
-            goto LABEL_46;
-          case 7:
-            v15 = 271;
-            goto LABEL_46;
-          case 8:
-            v15 = 307;
-LABEL_46:
-            v14 = 416;
-            break;
-          default:
-            break;
-        }
-      }
-      pRenderer->DrawTextureTransparent(v14, v15, pPageTexture);
-      v13 = v25;
-    }
-    a2.x += 2;
-    ++v13;
-    v25 = v13;
-  }
-  while ( v13 < 9 );
-}
-// 506408: using guessed type int dword_506408[];
-// 50654C: using guessed type int dword_50654C;
-
 //----- (00412E85) --------------------------------------------------------
-void DrawBook_History()
+void BookUI_Journal_Draw()
 {
   unsigned int v0; // eax@3
   unsigned int v1; // eax@7
@@ -567,6 +354,7 @@
     v0 = pViewport->uViewportTL_X + 398;
   }
   pRenderer->DrawTextureTransparent(v0, v11, v13);
+
   if ( BtnDown_flag || dword_506528 + num_achieved_awards >= num_achieved_awards_2 )
   {
     v14 = pTex_tab_an_7a__zoot_off;
@@ -580,6 +368,7 @@
     v1 = pViewport->uViewportTL_X + 398;
   }
   pRenderer->DrawTextureTransparent(v1, v12, v14);
+
   if ( !byte_5C6D50[dword_506528] )
   {
     v2 = achieved_awards[dword_506528];
@@ -591,8 +380,9 @@
     a1.uFrameZ = game_viewport_z;
     a1.uFrameW = game_viewport_w;
     if ( v3 )
-      a1.DrawTitleText(pBook2Font, 0, 22, 0, v3, 3);
+      a1.DrawTitleText(pBook2Font, 0, 22, ui_book_journal_title_color, v3, 3);
   }
+
   a1.uFrameX = 48;
   a1.uFrameY = 70;
   a1.uFrameWidth = 360;
@@ -603,14 +393,14 @@
   a1.uFrameW = a1.uFrameHeight + 69;
   if ( BtnDown_flag && dword_506528 + num_achieved_awards < num_achieved_awards_2 )
   {
-    pAudioPlayer->PlaySound((SoundID)230, 0, 0, -1, 0, 0, 0, 0);
+    pAudioPlayer->PlaySound(SOUND_OpenBook, 0, 0, -1, 0, 0, 0, 0);
     v5 = dword_50651C++;
     dword_506528 += num_achieved_awards;
     byte_506130[v5] = num_achieved_awards;
   }
   if ( BtnUp_flag && dword_50651C )
   {
-    pAudioPlayer->PlaySound((SoundID)230, 0, 0, -1, 0, 0, 0, 0);
+    pAudioPlayer->PlaySound(SOUND_OpenBook, 0, 0, -1, 0, 0, 0, 0);
     --dword_50651C;
     dword_506528 -= (unsigned __int8)byte_506130[dword_50651C];
   }
@@ -635,7 +425,7 @@
   if ( v7 )
   {
     v9 = pAutonoteFont->_44C6C2(v8, &a1, 1u, (unsigned __int8)byte_5C6D50[dword_506528]);
-    a1.DrawText(pAutonoteFont, 1, 0, 0, (const char *)v9, 0, a1.uFrameY + a1.uFrameHeight, 0);
+    a1.DrawText(pAutonoteFont, 1, 0, ui_book_journal_text_color, (const char *)v9, 0, a1.uFrameY + a1.uFrameHeight, ui_book_journal_text_shadow);
     ++num_achieved_awards;
   }
 }
@@ -701,14 +491,14 @@
   a1.uFrameW = 333;
   if ( BtnDown_flag && dword_506528 + num_achieved_awards < num_achieved_awards_2 )
   {
-    pAudioPlayer->PlaySound((SoundID)230, 0, 0, -1, 0, 0, 0, 0);
+    pAudioPlayer->PlaySound(SOUND_OpenBook, 0, 0, -1, 0, 0, 0, 0);
     v2 = dword_50651C++;
     dword_506528 += num_achieved_awards;
     byte_506130[v2] = num_achieved_awards;
   }
   if ( BtnUp_flag && dword_50651C )
   {
-    pAudioPlayer->PlaySound((SoundID)230, 0, 0, -1, 0, 0, 0, 0);
+    pAudioPlayer->PlaySound(SOUND_OpenBook, 0, 0, -1, 0, 0, 0, 0);
     --dword_50651C;
     dword_506528 -= (unsigned __int8)byte_506130[dword_50651C];
   }
@@ -1002,14 +792,14 @@
         v11 = dword_50651C++;
         byte_506130[v11] = num_achieved_awards;
         dword_506528 = v10;
-        pAudioPlayer->PlaySound((SoundID)230, 0, 0, -1, 0, 0, 0, 0);
+        pAudioPlayer->PlaySound(SOUND_OpenBook, 0, 0, -1, 0, 0, 0, 0);
       }
     }
     if ( BtnUp_flag && dword_50651C )
     {
       --dword_50651C;
       dword_506528 -= (unsigned __int8)byte_506130[dword_50651C];
-      pAudioPlayer->PlaySound((SoundID)230, 0, 0, -1, 0, 0, 0, 0);
+      pAudioPlayer->PlaySound(SOUND_OpenBook, 0, 0, -1, 0, 0, 0, 0);
     }
     if ( !num_achieved_awards || dword_506528 < 1 )
     {
@@ -1677,3 +1467,225 @@
 
 
 
+
+
+//----- (00412AF9) --------------------------------------------------------
+static void BookUI_Spellbook_DrawCurrentSchoolBackground()
+{
+  int v0; // ecx@1
+
+  v0 = 0;
+  if ( uActiveCharacter )
+	  v0 = pParty->pPlayers[uActiveCharacter - 1].lastOpenedSpellbookPage;//*((char *)&pParty->pPartyBuffs[5].uExpireTime + 6972 * uActiveCharacter + 2);
+  pRenderer->DrawTextureIndexed(8, 8, pSpellBookPagesTextr[v0]);
+  pRenderer->DrawTextureIndexed(0x1DCu, 0x1C2u, pTexture_50643C);
+  pRenderer->DrawTextureIndexed(0x231u, 0x1C2u, pTexture_506448);
+}
+
+
+
+
+
+//----- (00412B58) --------------------------------------------------------
+void DrawSpellBookContent(Player *player)
+{
+  //Player *v0; // ebx@1
+  int v1; // ebp@1
+  //unsigned int v2; // eax@1
+  Texture *v3; // edi@1
+  int v4; // esi@1
+  Texture *v5; // eax@3
+  Texture *v6; // edx@5
+  int v7; // eax@8
+  int v8; // eax@11
+  POINT *v9; // esi@13
+  int v10; // eax@13
+  Texture *v11; // edx@14
+  int v12; // eax@15
+  signed int v13; // ecx@18
+  unsigned int v14; // esi@18
+  unsigned int v15; // edi@18
+  Texture *pPageTexture; // eax@21
+  unsigned int v17; // [sp-Ch] [bp-2Ch]@8
+  unsigned int v18; // [sp-Ch] [bp-2Ch]@15
+  unsigned int v19; // [sp-8h] [bp-28h]@8
+  unsigned int v20; // [sp-8h] [bp-28h]@15
+  Texture *v21; // [sp-4h] [bp-24h]@15
+  signed int v22; // [sp-4h] [bp-24h]@22
+  Texture *v23; // [sp+10h] [bp-10h]@5
+  POINT a2; // [sp+18h] [bp-8h]@13
+  POINT v24;
+  int v25;
+
+  BookUI_Spellbook_DrawCurrentSchoolBackground();
+
+  //v0 = pPlayers[uActiveCharacter];
+  v1 = 11 * player->lastOpenedSpellbookPage;
+  //v2 = pIcons_LOD->FindTextureByName("Pending");
+  v3 = pIcons_LOD->GetTexture(pIcons_LOD->FindTextureByName("Pending"));
+  pRenderer->ClearZBuffer(0, 479);
+  v4 = 1;
+  if ( __OFSUB__(v1, v1 + 11) ^ 1 )
+  {
+    do
+    {
+      if ( *(&player->_guilds_member_bits[v1 + 63] + v4) )
+      {
+        v5 = (Texture *)dword_506408[v4];
+        if ( v5 != v3 )
+        {
+          if ( quick_spell_at_page == v4 )
+          {
+            v6 = dword_5063D8[v4];
+            v23 = dword_5063D8[v4];
+          }
+          else
+          {
+            v23 = dword_506408[v4];
+            v6 = v5;
+          }
+          if ( v6->pLevelOfDetail0_prolly_alpha_mask )
+          {
+			v7 = player->lastOpenedSpellbookPage;
+           // v7 =  (12 * v0->lastOpenedSpellbookPage + pSpellbookSpellIndices[v0->lastOpenedSpellbookPage][v4]);
+            v19 = pViewport->uViewportTL_Y +  pIconPos[v7][pSpellbookSpellIndices[v7][v4]].Ypos;
+            v17 = pViewport->uViewportTL_X +  pIconPos[v7][pSpellbookSpellIndices[v7][v4]].Xpos;
+            if ( BYTE1(v6->pBits) & 2 )
+              pRenderer->DrawTextureTransparent(v17, v19, v6);
+            else
+              pRenderer->DrawTextureIndexed(v17, v19, v6);
+            pRenderer->DrawMaskToZBuffer(pIconPos[v7][pSpellbookSpellIndices[v7][v4]].Xpos,
+				               pIconPos[v7][pSpellbookSpellIndices[v7][v4]].Ypos, v23, v4);
+          }
+        }
+      }
+      ++v4;
+    }
+    while ( v4 + v1 - 1 < v1 + 11 );
+  }
+
+
+  v9 = pMouse->GetCursorPos(&a2);
+  v10 = pRenderer->pActiveZBuffer[v9->x + pSRZBufferLineOffsets[pMouse->GetCursorPos(&v24)->y]] & 0xFFFF;
+  if ( v10 )
+  {
+    v11 = dword_5063D8[v10];
+    if ( v11->pLevelOfDetail0_prolly_alpha_mask )
+    {
+      v21 = dword_5063D8[v10];
+	  v12 = player->lastOpenedSpellbookPage;
+    //  v12 = (12 * v0->lastOpenedSpellbookPage + pSpellbookSpellIndices[v0->lastOpenedSpellbookPage][v10]);
+      v20 = pViewport->uViewportTL_Y +  pIconPos[v12][pSpellbookSpellIndices[v12][v10]].Ypos;
+      v18 = pViewport->uViewportTL_X +  pIconPos[v12][pSpellbookSpellIndices[v12][v10]].Xpos;
+      if ( BYTE1(v11->pBits) & 2 )
+        pRenderer->DrawTextureTransparent(v18, v20, v21);
+      else
+        pRenderer->DrawTextureIndexed(v18, v20, v21);
+    }
+  }
+  v13 = 0;
+  a2.x = (LONG)&player->pActiveSkills[12];
+  v14 = (unsigned int)&player->pActiveSkills[12];
+  v15 = (unsigned int)&player->pActiveSkills[12];
+  v25 = 0;
+  do
+  {
+    if ( *(short *)a2.x )
+    {
+      if ( player->lastOpenedSpellbookPage == v13 )
+      {
+        pPageTexture = pTextures_tabs[v13][1];
+        switch ( v13 )
+        {
+          case 0:
+            v14 = 406;
+            v22 = 9;
+            goto LABEL_27;
+          case 1:
+            v14 = 406;
+            goto LABEL_38;
+          case 2:
+            v14 = 406;
+            v22 = 84;
+            goto LABEL_27;
+          case 3:
+            v14 = 406;
+            goto LABEL_26;
+          case 4:
+            v14 = 407;
+            goto LABEL_29;
+          case 5:
+            v15 = 196;
+            goto LABEL_34;
+          case 6:
+            v15 = 234;
+            goto LABEL_34;
+          case 7:
+            v15 = 272;
+            goto LABEL_34;
+          case 8:
+            v15 = 309;
+LABEL_34:
+            v14 = 405;
+            break;
+          default:
+            break;
+        }
+      }
+      else
+      {
+        pPageTexture = pTextures_tabs[v13][0];
+        switch ( v13 )
+        {
+          case 0:
+            v14 = 415;
+            v22 = 10;
+            goto LABEL_27;
+          case 1:
+            v14 = 415;
+LABEL_38:
+            v22 = 46;
+            goto LABEL_27;
+          case 2:
+            v14 = 415;
+            v22 = 83;
+            goto LABEL_27;
+          case 3:
+            v14 = 415;
+LABEL_26:
+            v22 = 121;
+LABEL_27:
+            v15 = v22;
+            break;
+          case 4:
+            v14 = 415;
+LABEL_29:
+            v15 = 158;
+            break;
+          case 5:
+            v15 = 196;
+            goto LABEL_46;
+          case 6:
+            v15 = 234;
+            goto LABEL_46;
+          case 7:
+            v15 = 271;
+            goto LABEL_46;
+          case 8:
+            v15 = 307;
+LABEL_46:
+            v14 = 416;
+            break;
+          default:
+            break;
+        }
+      }
+      pRenderer->DrawTextureTransparent(v14, v15, pPageTexture);
+      v13 = v25;
+    }
+    a2.x += 2;
+    ++v13;
+    v25 = v13;
+  }
+  while ( v13 < 9 );
+}
\ No newline at end of file
--- a/UICharacter.cpp	Wed May 22 22:22:36 2013 +0600
+++ b/UICharacter.cpp	Wed May 22 22:23:04 2013 +0600
@@ -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"
@@ -49,6 +26,7 @@
 int bRingsShownInCharScreen; // 5118E0
 
 
+unsigned int ui_mainmenu_copyright_color;
 
 unsigned int ui_character_default_text_color;
 unsigned int ui_character_skill_highlight_color;
@@ -66,6 +44,13 @@
 unsigned int ui_game_minimap_decoration_color_1;
 unsigned int ui_game_minimap_projectile_color;
 unsigned int ui_game_minimap_treasure_color;
+unsigned int ui_game_character_record_playerbuff_colors[24];
+
+unsigned int ui_gamemenu_video_gamma_title_color;
+unsigned int ui_gamemenu_keys_action_name_color;
+unsigned int ui_gamemenu_keys_key_selection_blink_color_1;
+unsigned int ui_gamemenu_keys_key_selection_blink_color_2;
+unsigned int ui_gamemenu_keys_key_default_color;
 
 unsigned int ui_book_quests_title_color;
 unsigned int ui_book_quests_text_color;
@@ -73,8 +58,24 @@
 unsigned int ui_book_autonotes_text_color;
 unsigned int ui_book_map_title_color;
 unsigned int ui_book_map_coordinates_color;
+
+unsigned int ui_book_calendar_title_color;
+unsigned int ui_book_calendar_time_color;
+unsigned int ui_book_calendar_day_color;
+unsigned int ui_book_calendar_month_color;
+unsigned int ui_book_calendar_year_color;
+unsigned int ui_book_calendar_moon_color;
+unsigned int ui_book_calendar_location_color;
+
+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);
+
   ui_character_default_text_color = TargetColor(255, 255, 255);
   ui_character_header_text_color = TargetColor(255, 255, 155);
   ui_character_bonus_text_color = TargetColor(0, 255, 0);
@@ -98,6 +99,36 @@
   ui_game_minimap_decoration_color_1 = TargetColor(255, 255, 255);
   ui_game_minimap_projectile_color = TargetColor(255, 0, 0);
   ui_game_minimap_treasure_color = TargetColor(0, 0, 255);
+  ui_game_character_record_playerbuff_colors[0] = TargetColor(150, 212, 255);
+  ui_game_character_record_playerbuff_colors[1] = TargetColor(225, 225, 225);
+  ui_game_character_record_playerbuff_colors[2] = TargetColor(255, 128, 0);
+  ui_game_character_record_playerbuff_colors[3] = TargetColor(128, 128, 128);
+  ui_game_character_record_playerbuff_colors[4] = TargetColor(225, 225, 225);
+  ui_game_character_record_playerbuff_colors[5] = TargetColor(255, 85, 0);
+  ui_game_character_record_playerbuff_colors[6] = TargetColor(255, 128, 0);
+  ui_game_character_record_playerbuff_colors[7] = TargetColor(255, 85, 0);
+  ui_game_character_record_playerbuff_colors[8] = TargetColor(225, 225, 225);
+  ui_game_character_record_playerbuff_colors[9] = TargetColor(235, 15, 255);
+  ui_game_character_record_playerbuff_colors[10] = TargetColor(192, 192, 240);
+  ui_game_character_record_playerbuff_colors[11] = TargetColor(225, 225, 225);
+  ui_game_character_record_playerbuff_colors[12] = TargetColor(255, 128, 0);
+  ui_game_character_record_playerbuff_colors[13] = TargetColor(150, 212, 255);
+  ui_game_character_record_playerbuff_colors[14] = TargetColor(128, 128, 128);
+  ui_game_character_record_playerbuff_colors[15] = TargetColor(255, 255, 155);
+  ui_game_character_record_playerbuff_colors[16] = TargetColor(255, 255, 155);
+  ui_game_character_record_playerbuff_colors[17] = TargetColor(255, 255, 155);
+  ui_game_character_record_playerbuff_colors[18] = TargetColor(255, 255, 155);
+  ui_game_character_record_playerbuff_colors[19] = TargetColor(255, 255, 155);
+  ui_game_character_record_playerbuff_colors[20] = TargetColor(255, 255, 155);
+  ui_game_character_record_playerbuff_colors[21] = TargetColor(255, 255, 155);
+  ui_game_character_record_playerbuff_colors[22] = TargetColor(0, 128, 255);
+  ui_game_character_record_playerbuff_colors[23] = TargetColor(0, 128, 255);
+
+  ui_gamemenu_video_gamma_title_color = TargetColor(255, 255, 155);
+  ui_gamemenu_keys_action_name_color = TargetColor(255, 255, 255);
+  ui_gamemenu_keys_key_selection_blink_color_1 = TargetColor(50, 0, 0);
+  ui_gamemenu_keys_key_selection_blink_color_2 = TargetColor(225, 205, 35);
+  ui_gamemenu_keys_key_default_color = TargetColor(255, 255, 255);
 
   ui_book_quests_title_color = TargetColor(255, 255, 255);
   ui_book_quests_text_color = TargetColor(255, 255, 255);
@@ -105,6 +136,18 @@
   ui_book_autonotes_text_color = TargetColor(255, 255, 255);
   ui_book_map_title_color = TargetColor(255, 255, 255);
   ui_book_map_coordinates_color = TargetColor(255, 255, 255);
+
+  ui_book_calendar_title_color = TargetColor(255, 255, 255);
+  ui_book_calendar_time_color = TargetColor(75, 75, 75);
+  ui_book_calendar_day_color = TargetColor(75, 75, 75);
+  ui_book_calendar_month_color = TargetColor(75, 75, 75);
+  ui_book_calendar_year_color = TargetColor(75, 75, 75);
+  ui_book_calendar_moon_color = TargetColor(75, 75, 75);
+  ui_book_calendar_location_color = TargetColor(75, 75, 75);
+
+  ui_book_journal_title_color = TargetColor(255, 255, 255);
+  ui_book_journal_text_color = TargetColor(255, 255, 255);
+  ui_book_journal_text_shadow = TargetColor(0, 0, 0);
 }
 
 
@@ -1027,7 +1070,7 @@
       {
         case 529:
           v60 = 5;
-          v59 = papredoll_flying_feet[pPlayers[uPlayerID]->uFace];
+          v59 = papredoll_flying_feet[pPlayers[uPlayerID]->uCurrentFace];
           break;
         case 512:
           v60 = 6;
@@ -1226,12 +1269,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;// 
@@ -1684,33 +1727,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;
@@ -1996,8 +2039,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
@@ -2290,7 +2333,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	Wed May 22 22:22:36 2013 +0600
+++ b/UIHouses.cpp	Wed May 22 22:23:04 2013 +0600
@@ -26,6 +26,7 @@
 #include "mm7_data.h"
 #include "Game.h"
 
+#include "stru159.h"
 int uHouse_ExitPic; // weak
 
 int dword_591080; // weak
@@ -2096,7 +2097,7 @@
 		v6 = TargetColor(0xFFu, 0xFFu, 0xFFu);
 		v7 = v5->pName;
 		v8 = TargetColor(0xFFu, 0xFFu, 0x9Bu);
-		sprintf(pTmpBuf, &byte_4F0F98, v8, v7, v6);
+		sprintf(pTmpBuf, "\f%05d%s\f%05d", v8, v7, v6);
 		sprintf(pTmpBuf2, dword_F8B1A4, pTmpBuf, 100 * v5->uLevel);
 		current_npc_text = pTmpBuf2;
 		memcpy(&a1, pDialogueWindow, sizeof(a1));
@@ -2122,9 +2123,9 @@
 		v0 = window_SpeakInHouse;
 		if ( window_SpeakInHouse->field_40 == 1 )
 		{
-			sprintf(pTmpBuf, "%s\n%s", pGlobalTXT_LocalizationStrings[606], pGlobalTXT_LocalizationStrings[112]);
+			sprintf(pTmpBuf, "%s\n%s", pGlobalTXT_LocalizationStrings[606], pGlobalTXT_LocalizationStrings[112]); // "Pay"   "How Much?"
 			_this.DrawTitleText(pFontArrus, 0, 0x92u, v30, pTmpBuf, 3u);
-			_this.DrawTitleText(pFontArrus, 0, 0xBAu, v28, (const char *)pKeyActionMap->pPressedKeysBuffer, 3u);
+			_this.DrawTitleText(pFontArrus, 0, 0xBAu, v28, (const char *)pKeyActionMap->pPressedKeysBuffer, 3);
 			v3 = pFontArrus;
 			v4 = pFontArrus->GetLineWidth((const char *)pKeyActionMap->pPressedKeysBuffer);
 			_this.DrawFlashingInputCursor(v4 / 2 + 80, 185, v3);
@@ -2136,15 +2137,7 @@
 			v2 = v1;
 			if ( v1 <= 0 )
 			{
-			//LABEL_8:
 				pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
-				/*if ( (signed int)pMessageQueue_50CBD0->uNumMessages < 40 )
-				{
-				pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].eType = UIMSG_Escape;
-				pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = 1;
-				*(&pMessageQueue_50CBD0->uNumMessages + 3 * pMessageQueue_50CBD0->uNumMessages + 3) = 0;
-				++pMessageQueue_50CBD0->uNumMessages;
-				}*/
 				return;
 			}
 			if ( v1 > pParty->uNumGold )
@@ -2176,8 +2169,8 @@
   }
   return;
 }
-// F8B19C: using guessed type int dword_F8B19C;
-// F8B1A0: using guessed type __int16 word_F8B1A0;
+
+
 
 //----- (004B7D7E) --------------------------------------------------------
 void __cdecl BankDialog()
@@ -3071,7 +3064,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 +4267,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 +4993,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 +5020,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 +6001,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	Wed May 22 22:22:36 2013 +0600
+++ b/UIHouses.h	Wed May 22 22:23:04 2013 +0600
@@ -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	Wed May 22 22:22:36 2013 +0600
+++ b/UIMainMenu.cpp	Wed May 22 22:23:04 2013 +0600
@@ -2,6 +2,9 @@
 
 #include "MM7.h"
 
+#include "Mouse.h"
+#include "Keyboard.h"
+
 #include "MapInfo.h"
 #include "Game.h"
 #include "GUIWindow.h"
@@ -46,40 +49,44 @@
 
 
 //----- (0041B578) --------------------------------------------------------
-void __cdecl MainMenuUI_LoadFontsAndSomeStuff()
-    {
-    pIcons_LOD->SetupPalettes(pRenderer->uTargetRBits,
-        pRenderer->uTargetGBits,
-        pRenderer->uTargetBBits);
-    pPaletteManager->SetColorChannelInfo(pRenderer->uTargetRBits,
-        pRenderer->uTargetGBits,
-        pRenderer->uTargetBBits);
-    pPaletteManager->RecalculateAll();
+void MainMenuUI_LoadFontsAndSomeStuff()
+{
+  pIcons_LOD->SetupPalettes(pRenderer->uTargetRBits,
+                            pRenderer->uTargetGBits,
+                            pRenderer->uTargetBBits);
+  pPaletteManager->SetColorChannelInfo(pRenderer->uTargetRBits,
+                                       pRenderer->uTargetGBits,
+                                       pRenderer->uTargetBBits);
+  pPaletteManager->RecalculateAll();
 
-    for (uint i = 0; i < 480; ++i)
-        pSRZBufferLineOffsets[i] = 640 * i;
+  for (uint i = 0; i < 480; ++i)
+    pSRZBufferLineOffsets[i] = 640 * i;
 
-    pRenderer->ResetTextureClipRect();
+  pRenderer->ResetTextureClipRect();
+
+  uTextureID_FONTPAL = pIcons_LOD->LoadTexture("FONTPAL", TEXTURE_16BIT_PALETTE);
 
-    uTextureID_FONTPAL = pIcons_LOD->LoadTexture("FONTPAL", TEXTURE_16BIT_PALETTE);
-    pFontArrus = LoadFont("arrus.fnt", "FONTPAL", NULL);
-    pFontLucida = LoadFont("lucida.fnt", "FONTPAL", NULL);
-    pFontCreate = LoadFont("create.fnt", "FONTPAL", NULL);
-    pFontSmallnum = LoadFont("smallnum.fnt", "FONTPAL", NULL);
-    pFontComic = LoadFont("comic.fnt", "FONTPAL", NULL);
-    pFontArrus->field_3 = 0;
-    pFontLucida->field_3 = 0;
-    pFontCreate->field_3 = 0;
+  pFontArrus = LoadFont("arrus.fnt", "FONTPAL", nullptr);
+  pFontArrus->field_3 = 0;
+
+  pFontLucida = LoadFont("lucida.fnt", "FONTPAL", nullptr);
+  pFontLucida->field_3 = 0;
+
+  pFontCreate = LoadFont("create.fnt", "FONTPAL", nullptr);
+  pFontCreate->field_3 = 0;
 
-    for (uint i = 0; i < 20; ++i)
-        pWindowList[i].eWindowType = WINDOW_null;
+  pFontSmallnum = LoadFont("smallnum.fnt", "FONTPAL", nullptr);
+  pFontComic = LoadFont("comic.fnt", "FONTPAL", nullptr);
 
-    uNumVisibleWindows = -1;
-    memset(pVisibleWindowsIdxs, 0, sizeof(pVisibleWindowsIdxs));
-    }
+  for (uint i = 0; i < 20; ++i)
+    pWindowList[i].eWindowType = WINDOW_null;
+
+  uNumVisibleWindows = -1;
+  memset(pVisibleWindowsIdxs, 0, sizeof(pVisibleWindowsIdxs));
+}
 
 //----- (004415C5) --------------------------------------------------------
-void LoadPartyBuffIcons()
+static void LoadPartyBuffIcons()
 {
   for (uint i = 0; i < 14; ++i)
   {
@@ -93,8 +100,8 @@
 }
 
 //----- (0041B690) --------------------------------------------------------
-void __cdecl MainMenuUI_Create()
-    {
+void MainMenuUI_Create()
+{
     //unsigned int v0; // eax@1
     //unsigned int v1; // eax@1
     //unsigned int v2; // eax@1
@@ -170,14 +177,14 @@
     pPrimaryWindow->CreateButton(0xB1u, 0x1A8u, 0x1Fu, 0x28u, 2, 94, UIMSG_SelectCharacter, 2, '2', "", 0);
     pPrimaryWindow->CreateButton(0x124u, 0x1A8u, 0x1Fu, 0x28u, 2, 94, UIMSG_SelectCharacter, 3, '3', "", 0);
     pPrimaryWindow->CreateButton(0x197u, 0x1A8u, 0x1Fu, 0x28u, 2, 94, UIMSG_SelectCharacter, 4, '4', "", 0);
-    pPrimaryWindow->CreateButton(0x18u, 0x194u, 5u, 0x31u, 1, 93, UIMSG_0, 1u, 0, "", 0);
-    pPrimaryWindow->CreateButton(0x8Bu, 0x194u, 5u, 0x31u, 1, 93, UIMSG_0, 2u, 0, "", 0);
-    pPrimaryWindow->CreateButton(0xFFu, 0x194u, 5u, 0x31u, 1, 93, UIMSG_0, 3u, 0, "", 0);
-    pPrimaryWindow->CreateButton(0x172u, 0x194u, 5u, 0x31u, 1, 93, UIMSG_0, 4u, 0, "", 0);
-    pPrimaryWindow->CreateButton(0x61u, 0x194u, 5u, 0x31u, 1, 93, UIMSG_0, 1u, 0, "", 0);
-    pPrimaryWindow->CreateButton(0xD4u, 0x194u, 5u, 0x31u, 1, 93, UIMSG_0, 2u, 0, "", 0);
-    pPrimaryWindow->CreateButton(0x148u, 0x194u, 5u, 0x31u, 1, 93, UIMSG_0, 3u, 0, "", 0);
-    pPrimaryWindow->CreateButton(0x1BBu, 0x194u, 5u, 0x31u, 1, 93, UIMSG_0, 4u, 0, "", 0);
+    pPrimaryWindow->CreateButton(0x18u, 0x194u, 5u, 0x31u, 1, 93, UIMSG_0, 1, 0, "", 0);
+    pPrimaryWindow->CreateButton(0x8Bu, 0x194u, 5u, 0x31u, 1, 93, UIMSG_0, 2, 0, "", 0);
+    pPrimaryWindow->CreateButton(0xFFu, 0x194u, 5u, 0x31u, 1, 93, UIMSG_0, 3, 0, "", 0);
+    pPrimaryWindow->CreateButton(0x172u, 0x194u, 5u, 0x31u, 1, 93, UIMSG_0, 4, 0, "", 0);
+    pPrimaryWindow->CreateButton(0x61u, 0x194u, 5u, 0x31u, 1, 93, UIMSG_0, 1, 0, "", 0);
+    pPrimaryWindow->CreateButton(0xD4u, 0x194u, 5u, 0x31u, 1, 93, UIMSG_0, 2, 0, "", 0);
+    pPrimaryWindow->CreateButton(0x148u, 0x194u, 5u, 0x31u, 1, 93, UIMSG_0, 3, 0, "", 0);
+    pPrimaryWindow->CreateButton(0x1BBu, 0x194u, 5u, 0x31u, 1, 93, UIMSG_0, 4, 0, "", 0);
 
     uTextureID_ib_td1_A = pIcons_LOD->LoadTexture("ib-td1-A", TEXTURE_16BIT_PALETTE);
     v6 = pIcons_LOD->GetTexture(uTextureID_ib_td1_A);
@@ -254,7 +261,7 @@
 }
 
 //----- (004979D2) --------------------------------------------------------
-MENU_STATE __cdecl CreditsMenu__Loop()
+MENU_STATE MainMenuUI_Credits_Loop()
 {
         char *v0; // eax@5
         char *v1; // edi@5
--- a/UIOptions.cpp	Wed May 22 22:22:36 2013 +0600
+++ b/UIOptions.cpp	Wed May 22 22:23:04 2013 +0600
@@ -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"
@@ -49,98 +56,43 @@
 OptionsMenuSkin options_menu_skin; // 507C60
 
 
+bool GameMenuUI_InvaligKeyBindingsFlags[28]; // 506E6C
+//----- (00414D24) --------------------------------------------------------
+static unsigned int GameMenuUI_GetKeyBindingColor(int key_index)
+{
+  if (uGameMenuUI_CurentlySelectedKeyIdx == key_index)
+  {
+    if (GetTickCount() % 1000 < 500)
+      return ui_gamemenu_keys_key_selection_blink_color_1;
+    else
+      return ui_gamemenu_keys_key_selection_blink_color_2;
+  }
+  else if (GameMenuUI_InvaligKeyBindingsFlags[key_index])
+  {
+    int intensity;
 
+    int time = GetTickCount() % 800;
+    if (time < 400)
+      intensity = - 70 + 70 * time / 400;
+    else
+      intensity = + 70 - 70 * time / 800;
+
+    return TargetColor(185 + intensity, 40 + intensity / 4, 40 + intensity / 4);
+  }
+
+  return ui_gamemenu_keys_key_default_color;
+}
 
 //----- (004142D3) --------------------------------------------------------
-char __cdecl GameMenuUI_DrawKeyBindings()
-    {
-    unsigned int v0; // ebp@1
-    int v1; // ecx@2
-    unsigned int v2; // eax@6
-    GUIWindow *v3; // edx@6
+void GameMenuUI_DrawKeyBindings()
+{
     signed int v4; // ecx@7
     signed int v5; // eax@8
-    const char *v6; // ST0C_4@16
-    unsigned int v7; // eax@16
-    const char *v8; // ST0C_4@16
-    unsigned int v9; // eax@16
-    const char *v10; // ST0C_4@16
-    unsigned int v11; // eax@16
-    const char *v12; // ST0C_4@16
-    unsigned int v13; // eax@16
-    const char *v14; // ST0C_4@16
-    unsigned int v15; // eax@16
-    const char *v16; // ST0C_4@16
-    unsigned int v17; // eax@16
-    const char *v18; // ST0C_4@16
-    unsigned int v19; // eax@16
-    const char *v20; // ST0C_4@16
-    unsigned int v21; // eax@16
-    signed int v22; // ebp@16
-    const char *v23; // ST0C_4@16
-    unsigned int v24; // eax@16
-    const char *v25; // ST0C_4@16
-    unsigned int v26; // eax@16
-    const char *v27; // ST0C_4@16
-    unsigned int v28; // eax@16
-    const char *v29; // ST0C_4@16
-    unsigned int v30; // eax@16
-    const char *v31; // ST0C_4@16
-    unsigned int v32; // eax@16
-    const char *v33; // ST0C_4@17
-    unsigned int v34; // eax@17
-    const char *v35; // ST0C_4@17
-    unsigned int v36; // eax@17
-    const char *v37; // ST0C_4@17
-    unsigned int v38; // eax@17
-    const char *v39; // ST0C_4@17
-    unsigned int v40; // eax@17
-    const char *v41; // ST0C_4@17
-    unsigned int v42; // eax@17
-    const char *v43; // ST0C_4@17
-    unsigned int v44; // eax@17
-    const char *v45; // ST0C_4@17
-    unsigned int v46; // eax@17
-    const char *v47; // ST0C_4@17
-    unsigned int v48; // eax@17
-    const char *v49; // ST0C_4@17
-    unsigned int v50; // eax@17
-    const char *v51; // ST0C_4@17
-    unsigned int v52; // eax@17
-    const char *v53; // ST0C_4@17
-    unsigned int v54; // eax@17
-    const char *v55; // ST0C_4@17
-    unsigned int v56; // eax@17
-    const char *v57; // ST0C_4@17
-    unsigned int v58; // eax@17
-    unsigned int v59; // eax@18
-    //int v61; // [sp-14h] [bp-28h]@16
-    const char *v62; // [sp-10h] [bp-24h]@16
-    unsigned int a5; // [sp+10h] [bp-4h]@1
-
-    v0 = TargetColor(0xFFu, 0xFFu, 0xFFu);
-    a5 = v0;
-    if ( byte_4E28FC )
-        {
-        v1 = dword_507C0C + 15;
-        dword_507C0C = v1;
-        if ( v1 == 255 )
-            byte_4E28FC = 0;
-        }
-    else
-        {
-        v1 = dword_507C0C - 15;
-        dword_507C0C = v1;
-        if ( v1 == 15 )
-            byte_4E28FC = 1;
-        }
-    v2 = TargetColor(v1, 0, 0);
-    v3 = pGUIWindow_CurrentMenu;
-    dword_507C08 = v2;
+    
     if ( pGUIWindow_CurrentMenu->field_40 == 2 )
         {
-        pPrevVirtualCidesMapping[dword_506E68] = pKeyActionMap->pPressedKeysBuffer[0];
-        memset(&KeyButtonFlagChangesArray, 0, sizeof(KeyButtonFlagChangesArray));
+        pPrevVirtualCidesMapping[uGameMenuUI_CurentlySelectedKeyIdx] = pKeyActionMap->pPressedKeysBuffer[0];
+        memset(GameMenuUI_InvaligKeyBindingsFlags, 0, sizeof(GameMenuUI_InvaligKeyBindingsFlags));
         v4 = 0;
         do
             {
@@ -149,8 +101,8 @@
                 {
                 if ( v4 != v5 && pPrevVirtualCidesMapping[v4] == pPrevVirtualCidesMapping[v5] )
                     {
-                    KeyButtonFlagChangesArray[v4] = 1;
-                    KeyButtonFlagChangesArray[v5] = 1;
+                    GameMenuUI_InvaligKeyBindingsFlags[v4] = true;
+                    GameMenuUI_InvaligKeyBindingsFlags[v5] = true;
                     }
                 ++v5;
                 }
@@ -158,168 +110,86 @@
                 ++v4;
             }
             while ( v4 < 28 );
-            dword_506E68 = -1;
-            v3->field_40 = 0;
+            uGameMenuUI_CurentlySelectedKeyIdx = -1;
+            pGUIWindow_CurrentMenu->field_40 = 0;
         }
     pRenderer->DrawTextureIndexed(8, 8, pIcons_LOD->GetTexture(uTextureID_Optkb[0]));
     if ( KeyboardPageNum == 1 )
     {
         pRenderer->DrawTextureIndexed(0x13, 0x12E, pIcons_LOD->GetTexture(uTextureID_Optkb[3]));
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 23, 142, v0, "Ш", 0, 0, 0);
-        v6 = pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[0]);
-        v7 = sub_414D24(0);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 142, v7, v6, 0, 0, 0);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 23, 163, v0, "", 0, 0, 0);
-        v8 = pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[1]);
-        v9 = sub_414D24(1);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 163, v9, v8, 0, 0, 0);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 23, 184, v0, "", 0, 0, 0);
-        v10 = pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[2]);
-        v11 = sub_414D24(2);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 184, v11, v10, 0, 0, 0);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 23, 205, v0, "", 0, 0, 0);
-        v12 = pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[3]);
-        v13 = sub_414D24(3);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 205, v13, v12, 0, 0, 0);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 23, 226, v0, "", 0, 0, 0);
-        v14 = pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[4]);
-        v15 = sub_414D24(4);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 226, v15, v14, 0, 0, 0);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 23, 247, v0, "", 0, 0, 0);
-        v16 = pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[5]);
-        v17 = sub_414D24(5);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 247, v17, v16, 0, 0, 0);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 23, 268, v0, ".", 0, 0, 0);
-        v18 = pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[6]);
-        v19 = sub_414D24(6);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 268, v19, v18, 0, 0, 0);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 142, v0, ". .", 0, 0, 0);
-        v20 = pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[7]);
-        v21 = sub_414D24(7);
-        v22 = 350;
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 350, 142, v21, v20, 0, 0, 0);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 163, a5, "", 0, 0, 0);
-        v23 = pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[8]);
-        v24 = sub_414D24(8);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 350, 163, v24, v23, 0, 0, 0);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 184, a5, ".", 0, 0, 0);
-        v25 = pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[9]);
-        v26 = sub_414D24(9);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 350, 184, v26, v25, 0, 0, 0);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 205, a5, ".", 0, 0, 0);
-        v27 = pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[10]);
-        v28 = sub_414D24(10);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 350, 205, v28, v27, 0, 0, 0);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 226, a5, "", 0, 0, 0);
-        v29 = pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[11]);
-        v30 = sub_414D24(11);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 350, 226, v30, v29, 0, 0, 0);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 247, a5, ". ", 0, 0, 0);
-        v31 = pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[12]);
-        v32 = sub_414D24(12);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 350, 247, v32, v31, 0, 0, 0);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 268, a5, "", 0, 0, 0);
 
-        v62 = pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[13]);
-        v59 = sub_414D24(13);
-        }
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 23, 142, ui_gamemenu_keys_action_name_color, "Ш", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 142, GameMenuUI_GetKeyBindingColor(0), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[0]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 23, 163, ui_gamemenu_keys_action_name_color, "", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 163, GameMenuUI_GetKeyBindingColor(1), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[1]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 23, 184, ui_gamemenu_keys_action_name_color, "", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 184, GameMenuUI_GetKeyBindingColor(2), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[2]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 23, 205, ui_gamemenu_keys_action_name_color, "", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 205, GameMenuUI_GetKeyBindingColor(3), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[3]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 23, 226, ui_gamemenu_keys_action_name_color, "", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 226, GameMenuUI_GetKeyBindingColor(4), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[4]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 23, 247, ui_gamemenu_keys_action_name_color, "", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 247, GameMenuUI_GetKeyBindingColor(5), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[5]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 23, 268, ui_gamemenu_keys_action_name_color, ".", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 268, GameMenuUI_GetKeyBindingColor(6), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[6]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 142, ui_gamemenu_keys_action_name_color, ". .", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 350, 142, GameMenuUI_GetKeyBindingColor(7), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[7]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 163, ui_gamemenu_keys_action_name_color, "", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 350, 163, GameMenuUI_GetKeyBindingColor(8), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[8]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 184, ui_gamemenu_keys_action_name_color, ".", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 350, 184, GameMenuUI_GetKeyBindingColor(9), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[9]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 205, ui_gamemenu_keys_action_name_color, ".", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 350, 205, GameMenuUI_GetKeyBindingColor(10), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[10]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 226, ui_gamemenu_keys_action_name_color, "", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 350, 226, GameMenuUI_GetKeyBindingColor(11), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[11]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 247, ui_gamemenu_keys_action_name_color, ". ", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 350, 247, GameMenuUI_GetKeyBindingColor(12), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[12]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 268, ui_gamemenu_keys_action_name_color, "", 0, 0, 0);
+     pGUIWindow_CurrentMenu->DrawText(pFontLucida, 350, 268, GameMenuUI_GetKeyBindingColor(13), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[13]), 0, 0, 0);
+    }
     else
-        {
+    {
         pRenderer->DrawTextureIndexed(0x7F, 0x12E, pIcons_LOD->GetTexture(uTextureID_Optkb[4]));
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 23, 142, v0, ". ", 0, 0, 0);
-        v33 = pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[14]);
-        v34 = sub_414D24(14);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 142, v34, v33, 0, 0, 0);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 23, 163, v0, "", 0, 0, 0);
-        v35 = pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[15]);
-        v36 = sub_414D24(15);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 163, v36, v35, 0, 0, 0);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 23, 184, v0, ". ", 0, 0, 0);
-        v37 = pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[16]);
-        v38 = sub_414D24(16);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 184, v38, v37, 0, 0, 0);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 23, 205, v0, "", 0, 0, 0);
-        v39 = pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[17]);
-        v40 = sub_414D24(17);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 205, v40, v39, 0, 0, 0);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 23, 226, v0, "", 0, 0, 0);
-        v41 = pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[18]);
-        v42 = sub_414D24(18);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 226, v42, v41, 0, 0, 0);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 23, 247, v0, "", 0, 0, 0);
-        v43 = pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[19]);
-        v44 = sub_414D24(19);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 247, v44, v43, 0, 0, 0);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 23, 268, v0, ". ", 0, 0, 0);
-        v45 = pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[20]);
-        v46 = sub_414D24(20);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 268, v46, v45, 0, 0, 0);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 142, v0, ". ", 0, 0, 0);
-        v47 = pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[21]);
-        v48 = sub_414D24(21);
-        v22 = 350;
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 350, 142, v48, v47, 0, 0, 0);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 163, a5, ". Ш", 0, 0, 0);
-        v49 = pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[22]);
-        v50 = sub_414D24(22);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 350, 163, v50, v49, 0, 0, 0);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 184, a5, "", 0, 0, 0);
-        v51 = pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[23]);
-        v52 = sub_414D24(23);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 350, 184, v52, v51, 0, 0, 0);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 205, a5, "", 0, 0, 0);
-        v53 = pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[24]);
-        v54 = sub_414D24(24);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 350, 205, v54, v53, 0, 0, 0);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 226, a5, ". ", 0, 0, 0);
-        v55 = pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[25]);
-        v56 = sub_414D24(25);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 350, 226, v56, v55, 0, 0, 0);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 247, a5, ". ", 0, 0, 0);
-        v57 = pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[26]);
-        v58 = sub_414D24(26);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 350, 247, v58, v57, 0, 0, 0);
-        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 268, a5, "", 0, 0, 0);
 
-        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, 23, 142, ui_gamemenu_keys_action_name_color, ". ", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 142, GameMenuUI_GetKeyBindingColor(14), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[14]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 23, 163, ui_gamemenu_keys_action_name_color, "", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 163, GameMenuUI_GetKeyBindingColor(15), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[15]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 23, 184, ui_gamemenu_keys_action_name_color, ". ", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 184, GameMenuUI_GetKeyBindingColor(16), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[16]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 23, 205, ui_gamemenu_keys_action_name_color, "", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 205, GameMenuUI_GetKeyBindingColor(17), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[17]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 23, 226, ui_gamemenu_keys_action_name_color, "", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 226, GameMenuUI_GetKeyBindingColor(18), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[18]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 23, 247, ui_gamemenu_keys_action_name_color, "", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 247, GameMenuUI_GetKeyBindingColor(19), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[19]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 23, 268, ui_gamemenu_keys_action_name_color, ". ", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 268, GameMenuUI_GetKeyBindingColor(20), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[20]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 142, ui_gamemenu_keys_action_name_color, ". ", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 350, 142, GameMenuUI_GetKeyBindingColor(21), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[21]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 163, ui_gamemenu_keys_action_name_color, ". Ш", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 350, 163, GameMenuUI_GetKeyBindingColor(22), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[22]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 184, ui_gamemenu_keys_action_name_color, "", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 350, 184, GameMenuUI_GetKeyBindingColor(23), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[23]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 205, ui_gamemenu_keys_action_name_color, "", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 350, 205, GameMenuUI_GetKeyBindingColor(24), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[24]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 226, ui_gamemenu_keys_action_name_color, ". ", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 350, 226, GameMenuUI_GetKeyBindingColor(25), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[25]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 247, ui_gamemenu_keys_action_name_color, ". ", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 350, 247, GameMenuUI_GetKeyBindingColor(26), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[26]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 268, ui_gamemenu_keys_action_name_color, "", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 350, 268, GameMenuUI_GetKeyBindingColor(27), pKeyActionMap->GetVKeyDisplayName(pWindowList_at_506F50_minus1_indexing[0]), 0, 0, 0);
     }
+}
 
 
-//----- (00414D24) --------------------------------------------------------
-unsigned int __thiscall sub_414D24(int _this)
-    {
-    int v1; // esi@1
-    unsigned int v2; // edi@1
-    unsigned int v3; // ebx@1
-    unsigned int result; // eax@1
 
-    v1 = _this;
-    v2 = TargetColor(0xE1u, 0xCDu, 0x23u);
-    v3 = TargetColor(0xFu, 0, 0);
-    result = TargetColor(0xFFu, 0xFFu, 0xFFu);
-    if ( dword_506E68 == v1 )
-        {
-        if ( GetTickCount() % 0x3E8 <= 0x1F4 )
-            result = v3;
-        else
-            result = v2;
-        }
-    else
-        {
-        if ( KeyButtonFlagChangesArray[v1] )
-            result = dword_507C08;
-        }
-    return result;
-    }
 
 //----- (00414D9A) --------------------------------------------------------
 void GameMenuUI_DrawVideoOptions()
 {
     const char *v0; // ST0C_4@3
-    unsigned __int16 v1; // ax@3
+    //unsigned __int16 v1; // ax@3
     //int v2; // eax@10
     GUIWindow v3; // [sp+8h] [bp-54h]@3
 
@@ -338,8 +208,8 @@
         v3.uFrameHeight = 79;
         v3.uFrameZ = 232;
         v3.uFrameW = 268;
-        v1 = TargetColor(0xFFu, 0xFFu, 0x9Bu);
-        v3.DrawTitleText(pFontSmallnum, 0, 0, v1, v0, 3u);
+        //v1 = TargetColor(0xFFu, 0xFFu, 0x9Bu);
+        v3.DrawTitleText(pFontSmallnum, 0, 0, ui_gamemenu_video_gamma_title_color, v0, 3u);
         }
 
     if (!pRenderer->pRenderD3D)
@@ -362,7 +232,7 @@
 
 
 //----- (00414F82) --------------------------------------------------------
-void DrawGameOptions()
+void GameMenuUI_Options_Draw()
 {
   pRenderer->DrawTextureIndexed(8,   8, pIcons_LOD->GetTexture(uTextureID_Options));
   pRenderer->DrawTextureIndexed(8, 132, pIcons_LOD->GetTexture(options_menu_skin.uTextureID_Background));
--- a/UIPartyCreation.cpp	Wed May 22 22:22:36 2013 +0600
+++ b/UIPartyCreation.cpp	Wed May 22 22:23:04 2013 +0600
@@ -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	Wed May 22 22:22:36 2013 +0600
+++ b/UIPopup.cpp	Wed May 22 22:23:04 2013 +0600
@@ -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) --------------------------------------------------------
@@ -1969,7 +1973,7 @@
                     pWindow.uFrameX = 38;
                     pWindow.uFrameY = 60;
                     pAudioPlayer->StopChannels(-1, -1);
-                    pWindow.DrawQuickCharRecord();
+                    GameUI_CharacterQuickRecord_Draw(&pWindow, pPlayers[(int)pWindow.ptr_1C + 1]);
                     }
                 }
             else if ( (signed int)pX > (signed int)pViewport->uViewportBR_X )
@@ -1998,12 +2002,12 @@
                         {
                         pAudioPlayer->StopChannels(-1, -1);
                         v3 = 0;
-                        sub_416B01(v3);
+                        GameUI_DrawNPCPopup(v3);
                         }
                     }
                 else
                     {
-                    pWindow.Hint = _4443D5_GetMinimapRightClickText();
+                    pWindow.Hint = (char *)GameUI_GetMinimapHintText();
                     pWindow.uFrameWidth = 256;
                     pWindow.uFrameX = 130;
                     pWindow.uFrameY = 140;
--- a/UIRest.cpp	Wed May 22 22:22:36 2013 +0600
+++ b/UIRest.cpp	Wed May 22 22:23:04 2013 +0600
@@ -4,6 +4,7 @@
 
 #include "MapInfo.h"
 #include "Game.h"
+#include "Player.h"
 #include "GUIWindow.h"
 #include "GUIFont.h"
 #include "GUIProgressBar.h"
@@ -46,18 +47,18 @@
 
 
 //----- (0041F6C1) --------------------------------------------------------
-void __cdecl RestUI_Initialize()
+void RestUI_Load()
 {
     Player *v0; // eax@10
 
     if ( !dword_506F14 )
         pAudioPlayer->StopChannels(-1, -1);
-    if ( pCurrentScreen )
-        {
+    if ( pCurrentScreen != SCREEN_GAME)
+    {
         pGUIWindow_CurrentMenu->Release();
         pCurrentScreen = SCREEN_GAME;
-        viewparams->bRedrawGameUI = 1;
-        }
+        viewparams->bRedrawGameUI = true;
+    }
     pEventTimer->Pause();
     if ( dword_506F14 != 2 )
         GUIWindow::Create(518, 450, 0, 0, WINDOW_PressedButton2, (int)pBtn_Rest, 0);
@@ -86,11 +87,13 @@
         --uRestUI_FoodRequiredToRest;
     if ( uRestUI_FoodRequiredToRest < 1 )
         uRestUI_FoodRequiredToRest = 1;
-    if ( !_strcmpi(pCurrentMapName, "d29.blv") && (unsigned __int16)_449B57_test_bit(pParty->_quest_bits, 98) )
+    if ( !_strcmpi(pCurrentMapName, "d29.blv") && _449B57_test_bit(pParty->_quest_bits, 98) )
         uRestUI_FoodRequiredToRest = 0;
+
     ++pIcons_LOD->uTexturePacksCount;
     if ( !pIcons_LOD->uNumPrevLoadedFiles )
         pIcons_LOD->uNumPrevLoadedFiles = pIcons_LOD->uNumLoadedFiles;
+
     pCurrentScreen = SCREEN_REST;
     _507CD4_RestUI_hourglass_anim_controller = 0;
     uTextureID_RestUI_restmain = pIcons_LOD->LoadTexture("restmain", TEXTURE_16BIT_PALETTE);
@@ -103,124 +106,118 @@
     LoadActualSkyFrame();
 
     pGUIWindow_CurrentMenu = GUIWindow::Create(0, 0, 640u, 480u, WINDOW_Rest, 0, 0);
-    pButton_RestUI_Exit          = pGUIWindow_CurrentMenu->CreateButton(280, 297, 154, 37, 1, 0, UIMSG_ExitRest,       0, 0,     "", pIcons_LOD->GetTexture(uTextureID_RestUI_restexit), 0);
-    pButton_RestUI_Main          = pGUIWindow_CurrentMenu->CreateButton( 24, 154, 225, 37, 1, 0, UIMSG_Rest8Hour,      0, 0x52u, "", pIcons_LOD->GetTexture(uTextureID_RestUI_restb4), 0);
-    pButton_RestUI_WaitUntilDawn = pGUIWindow_CurrentMenu->CreateButton( 61, 232, 154, 33, 1, 0, UIMSG_AlreadyResting, 0, 0x44u, "", pIcons_LOD->GetTexture(uTextureID_RestUI_restb1), 0);
-    pButton_RestUI_Wait1Hour     = pGUIWindow_CurrentMenu->CreateButton( 61, 264, 154, 33, 1, 0, UIMSG_Wait1Hour,      0, 0x48u, "", pIcons_LOD->GetTexture(uTextureID_RestUI_restb2), 0);
-    pButton_RestUI_Wait5Minutes  = pGUIWindow_CurrentMenu->CreateButton( 61, 296, 154, 33, 1, 0, UIMSG_Wait5Minutes,   0, 0x4Du, "", pIcons_LOD->GetTexture(uTextureID_RestUI_restb3), 0);
+    pButton_RestUI_Exit          = pGUIWindow_CurrentMenu->CreateButton(280, 297, 154, 37, 1, 0, UIMSG_ExitRest,       0,   0, "", pIcons_LOD->GetTexture(uTextureID_RestUI_restexit), 0);
+    pButton_RestUI_Main          = pGUIWindow_CurrentMenu->CreateButton( 24, 154, 225, 37, 1, 0, UIMSG_Rest8Hour,      0, 'R', "", pIcons_LOD->GetTexture(uTextureID_RestUI_restb4), 0);
+    pButton_RestUI_WaitUntilDawn = pGUIWindow_CurrentMenu->CreateButton( 61, 232, 154, 33, 1, 0, UIMSG_AlreadyResting, 0, 'D', "", pIcons_LOD->GetTexture(uTextureID_RestUI_restb1), 0);
+    pButton_RestUI_Wait1Hour     = pGUIWindow_CurrentMenu->CreateButton( 61, 264, 154, 33, 1, 0, UIMSG_Wait1Hour,      0, 'H', "", pIcons_LOD->GetTexture(uTextureID_RestUI_restb2), 0);
+    pButton_RestUI_Wait5Minutes  = pGUIWindow_CurrentMenu->CreateButton( 61, 296, 154, 33, 1, 0, UIMSG_Wait5Minutes,   0, 'M', "", pIcons_LOD->GetTexture(uTextureID_RestUI_restb3), 0);
 }
 
 //----- (0041FA01) --------------------------------------------------------
-void __cdecl RestUI_Draw()
-    {
-    int v0; // esi@1
-    Player **ppPlayers; // ecx@1
-    Player *pPlayer; // eax@2
+void RestUI_Draw()
+{
+    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
-        {
-          GUIWindow::Create(pButton_RestUI_Exit->uX, pButton_RestUI_Exit->uY, 0, 0, WINDOW_CloseRestWindowBtn,
-           (int)pButton_RestUI_Exit, (int)pGlobalTXT_LocalizationStrings[81]);
+            {
+            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]); // "Exit Rest"
     }
\ No newline at end of file
--- a/UISaveLoad.cpp	Wed May 22 22:22:36 2013 +0600
+++ b/UISaveLoad.cpp	Wed May 22 22:23:04 2013 +0600
@@ -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"
@@ -45,7 +48,7 @@
 
 
 //----- (004601B7) --------------------------------------------------------
-void GameUI_MainMenu_DoDrawLoad(int a1)
+static void UI_DrawSaveLoad(bool save)
 {
   unsigned __int16 v1; // bx@1
   unsigned int v2; // edi@4
@@ -84,18 +87,17 @@
   unsigned int pSaveFiles; // [sp+70h] [bp-14h]@10
   __int64 pAMPM2; // [sp+74h] [bp-10h]@10
   int pYear; // [sp+7Ch] [bp-8h]@10
-  int a4; // [sp+80h] [bp-4h]@1
+  //int a4; // [sp+80h] [bp-4h]@1
   int pFilesID;
 
   v1 = 255;
-  a4 = a1;
   TargetColor(0xFF, 0xFF, 0xFF);
   TargetColor(0xFF, 0xFF, 0x9B);
   pRenderer->BeginScene();
   if ( GetCurrentMenuID() != MENU_SAVELOAD && GetCurrentMenuID() != MENU_LoadingProcInMainMenu )
   {
     pRenderer->DrawTextureIndexed(8, 8, pIcons_LOD->GetTexture(uTextureID_loadsave));
-    if ( a4 )
+    if (save)
     {
       v2 = uTextureID_save_up;
       v3 = uTextureID_LS_saveU;
@@ -210,11 +212,11 @@
   }
   else
   {
-    if ( a4 )
+    if ( save )
       pSaveFiles = 40;
     else
       pSaveFiles = uNumSavegameFiles;
-    a4 = 199;
+    int a4 = 199;
     pFilesID = pSaveListPosition;
     pSlotName = (const char *)(&pSavegameHeader[pSaveListPosition]);//draw name for save slot
     do
@@ -243,27 +245,20 @@
 // 6A0C9C: using guessed type int dword_6A0C9C;
 
 //----- (004606F7) --------------------------------------------------------
-void __cdecl GameUI_MainMenu_DrawLoad()
+void LoadUI_Draw()
 {
-  GameUI_MainMenu_DoDrawLoad(0);
+  UI_DrawSaveLoad(false);
 }
 
 //----- (004606FE) --------------------------------------------------------
-void __cdecl sub_4606FE()
+void SaveUI_Draw()
 {
-  GameUI_MainMenu_DoDrawLoad(1);
+  UI_DrawSaveLoad(true);
 }
 
 
-void __cdecl FreeSavegameThumbnails()
-    {
-    for (int i = 0; i < 40; ++i)
-        //pAllocator->FreeChunk(pSavegameThumbnails[i].pPixels);
-        pSavegameThumbnails[i].Release();
-    }
-
 //----- (0045E361) --------------------------------------------------------
-void __fastcall GameUI_DrawLoadMenu(unsigned int uDialogueType)
+void LoadUI_Load(unsigned int uDialogueType)
 {
     unsigned int v1; // ebp@5
     unsigned int v2; // eax@5
@@ -386,7 +381,7 @@
 }
 
 //----- (0045E93E) --------------------------------------------------------
-void  GameUI_DrawSaveMenu()
+void SaveUI_Load()
 {
     unsigned int v0; // ebp@4
     unsigned int v1; // eax@4
--- a/UITransition.cpp	Wed May 22 22:22:36 2013 +0600
+++ b/UITransition.cpp	Wed May 22 22:23:04 2013 +0600
@@ -0,0 +1,280 @@
+#include <assert.h>
+#include <io.h>
+
+#include "Mouse.h"
+#include "Keyboard.h"
+#include "VideoPlayer.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 "stru159.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"
+
+
+
+
+
+//----- (00444839) --------------------------------------------------------
+void TransitionUI_Load(uint anim_id, uint exit_pic_id, int x, int y, int z, int directiony, int directionx, int a8, const char *pLocationName)
+{
+  //unsigned int v9; // ebx@1
+  //int v10; // edi@1
+  //signed int v11; // eax@1
+  unsigned int v12; // eax@6
+  const char *v13; // ST0C_4@6
+  unsigned int v14; // eax@8
+  const char *v15; // eax@14
+  unsigned int v16; // eax@16
+  //unsigned int result; // eax@26
+  const char *v18; // [sp-8h] [bp-40h]@9
+  //const char *v19; // [sp-4h] [bp-3Ch]@2
+  char *v20; // [sp-4h] [bp-3Ch]@9
+  const char *v21; // [sp-4h] [bp-3Ch]@11
+  char pContainer[40]; // [sp+Ch] [bp-2Ch]@1
+  unsigned int v23; // [sp+34h] [bp-4h]@1
+
+  //v9 = a1;
+  //v10 = a2;
+  v23 = IndoorLocation::GetLocationIndex(pLocationName);
+  dword_59117C_teleportx = x;
+  dword_591178_teleporty = y;
+  dword_591174_teleportz = z;
+  dword_591170_teleport_directiony = directiony;
+  dword_59116C_teleport_directionx = directionx;
+  dword_591168_teleport_speedz = a8;
+  dword_591164_teleport_map_name = (char *)pLocationName;
+  uCurrentHouse_Animation = anim_id;
+  pEventTimer->Pause();
+  pAudioPlayer->StopChannels(-1, -1);
+
+  switch (pParty->alignment)
+  {
+    case PartyAlignment_Good:    sprintfex(pContainer, "evt%02d-b", const_2()); break;
+    case PartyAlignment_Neutral: sprintfex(pContainer, "evt%02d", const_2());   break;
+    case PartyAlignment_Evil:    sprintfex(pContainer, "evt%02d-c", const_2()); break;
+    default: assert(false);
+  }
+
+  v12 = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+  v13 = pHouse_ExitPictures[exit_pic_id];
+  pTexture_Dialogue_Background = &pIcons_LOD->pTextures[v12];
+  pTexture_outside = pIcons_LOD->LoadTexturePtr(v13, TEXTURE_16BIT_PALETTE);
+  if (anim_id)
+  {
+    if ( !v23 )
+      //pVideoPlayer->OpenHouseMovie(pAnimatedRooms[p2DEvents_minus1___02[26 * v9]].field_0, 1u);
+      pVideoPlayer->OpenHouseMovie(pAnimatedRooms[p2DEvents[anim_id - 1].uAnimationID].video_name, 1);
+  }
+  else if ( !v23 )
+  {
+      v14 = pMapStats->GetMapInfo(pCurrentMapName);
+      if ( v14 )
+      {
+        sprintfex(sHouseName, pGlobalTXT_LocalizationStrings[410], pMapStats->pInfos[v14].pName); // "Leave %s"
+        goto LABEL_20;
+      }
+      v21 = pGlobalTXT_LocalizationStrings[79];
+      goto LABEL_19;
+  }
+  v15 = pLocationName;
+  if ( *pLocationName == 48 )
+    v15 = pCurrentMapName;
+  v16 = pMapStats->GetMapInfo(v15);
+  if ( v16 )
+  {
+    sprintfex(sHouseName, pGlobalTXT_LocalizationStrings[411], pMapStats->pInfos[v16].pName);
+    goto LABEL_20;
+  }
+  v21 = pGlobalTXT_LocalizationStrings[73];
+LABEL_19:
+  strcpy(sHouseName, v21);
+LABEL_20:
+  pDialogueWindow = GUIWindow::Create(0, 0, 640, 480, WINDOW_Transition, 0, (int)sHouseName);
+  //if ( BYTE1(pAnimatedRooms[p2DEvents_minus1___02[26 * v9]].field_C) )
+  if ( pAnimatedRooms[p2DEvents[anim_id - 1].uAnimationID].uRoomSoundId )
+    PlayHouseSound(anim_id, HouseSound_Greeting);
+  if ( uCurrentlyLoadedLevelType == LEVEL_Indoor && uActiveCharacter && pParty->uFlags & 0x30 )
+    pPlayers[uActiveCharacter]->PlaySound(SPEECH_47, 0);
+  if ( v23 )
+    uCurrentHouse_Animation = v23;
+}
+
+
+
+
+//----- (00444C8F) --------------------------------------------------------
+void TravelUI_Load()
+{
+  //signed int v0; // eax@1
+  unsigned int v1; // eax@6
+  GUIWindow *result; // eax@9
+  //const char *v3; // [sp-4h] [bp-2Ch]@2
+  char pContainer[32]; // [sp+0h] [bp-28h]@1
+
+  pEventTimer->Pause();
+
+  switch (pParty->alignment)
+  {
+    case PartyAlignment_Good:    sprintfex(pContainer, "evt%02d-b", const_2()); break;
+    case PartyAlignment_Neutral: sprintfex(pContainer, "evt%02d", const_2());   break;
+    case PartyAlignment_Evil:    sprintfex(pContainer, "evt%02d-c", const_2()); break;
+    default: assert(false);
+  }
+
+  pTexture_Dialogue_Background = pIcons_LOD->LoadTexturePtr(pContainer, TEXTURE_16BIT_PALETTE);
+  pTexture_outside = pIcons_LOD->LoadTexturePtr("outside", TEXTURE_16BIT_PALETTE);
+  v1 = pMapStats->GetMapInfo(pCurrentMapName);
+  if ( v1 )
+    sprintfex(sHouseName, pGlobalTXT_LocalizationStrings[410], pMapStats->pInfos[v1].pName);// "Leave %s"
+  else
+    strcpy(sHouseName, pGlobalTXT_LocalizationStrings[79]);// "Exit"
+  pDialogueWindow = GUIWindow::Create(0, 0, 640, 480, WINDOW_ChangeLocation, 0, (int)sHouseName);
+}
+
+
+
+//----- (00444DCA) --------------------------------------------------------
+void TravelUI_Draw()
+{
+  unsigned int v0; // edi@1
+  MapInfo *v1; // edi@2
+  signed int v3; // eax@2
+  int v4; // eax@5
+  const char *v5; // [sp-Ch] [bp-90h]@3
+  signed int v6; // [sp-8h] [bp-8Ch]@3
+  GUIWindow v7; // [sp+Ch] [bp-78h]@1
+  char pDestinationMapName[32]; // [sp+60h] [bp-24h]@1
+  unsigned int v9; // [sp+80h] [bp-4h]@1
+
+  memcpy(&v7, pPrimaryWindow, sizeof(v7));
+  v9 = pMapStats->GetMapInfo(pCurrentMapName);
+  pOutdoor->GetTravelDestination(pParty->vPosition.x, pParty->vPosition.y, pDestinationMapName, 20);
+  v0 = pMapStats->GetMapInfo(pDestinationMapName);
+  pRenderer->DrawTextureIndexed(0x1DDu, 0, pTexture_Dialogue_Background);
+  pRenderer->DrawTextureTransparent(0x1D4u, 0, &pIcons_LOD->pTextures[uTextureID_right_panel_loop]);
+  pRenderer->DrawTextureIndexed(pNPCPortraits_x[0][0], pNPCPortraits_y[0][0], pTexture_outside);
+  pRenderer->DrawTextureIndexed(0x22Cu, 0x1C3u, pIcons_LOD->GetTexture(uTextureID_x_x_u));
+  pRenderer->DrawTextureIndexed(0x1DCu, 0x1C3u, pIcons_LOD->GetTexture(uTextureID_x_ok_u));
+  if ( v0 )
+  {
+    v1 = &pMapStats->pInfos[v0];
+    v7.uFrameX = 493;
+    v7.uFrameWidth = 126;
+    v7.uFrameZ = 366;
+    v7.DrawTitleText(pFontCreate, 0, 4u, 0, v1->pName, 3);
+    v7.uFrameX = 483;
+    v7.uFrameWidth = 148;
+    v7.uFrameZ = 334;
+    v3 = GetTravelTime();
+    if ( v3 == 1 )
+    {
+      v6 = 1;
+      v5 = pGlobalTXT_LocalizationStrings[663]; // "It will take %d day to cross to %s."
+    }
+    else
+    {
+      v6 = v3;
+      v5 = pGlobalTXT_LocalizationStrings[128]; // "It will take %d days to travel to %s."
+    }
+    sprintfex(pTmpBuf, v5, v6, v1->pName);
+    strcat(pTmpBuf, "\n \n");
+    sprintfex(pTmpBuf2, pGlobalTXT_LocalizationStrings[126], pMapStats->pInfos[v9].pName);
+    strcat(pTmpBuf, pTmpBuf2);
+    v4 = pFontCreate->CalcTextHeight(pTmpBuf, &v7, 0, 0);
+    v7.DrawTitleText(pFontCreate, 0, (212 - v4) / 2 + 101, 0, pTmpBuf, 3);
+    _unused_5B5924_is_travel_ui_drawn = 1;
+  }
+}
+
+
+
+//----- (00444A51) --------------------------------------------------------
+void TransitionUI_Draw()
+{
+  MapInfo *pMapInfo; // esi@5
+  char *v1; // eax@6
+  std::string v3; // [sp-18h] [bp-84h]@11
+  unsigned int v4; // [sp-10h] [bp-7Ch]@12
+  int v5; // [sp-Ch] [bp-78h]@12
+  const char *v6; // [sp-8h] [bp-74h]@11
+  signed int v7; // [sp-4h] [bp-70h]@11
+  GUIWindow v8; // [sp+Ch] [bp-60h]@1
+  unsigned int v9; // [sp+60h] [bp-Ch]@1
+  unsigned int v10; // [sp+64h] [bp-8h]@1
+  int a3; // [sp+6Bh] [bp-1h]@11
+
+  memcpy(&v8, pPrimaryWindow, sizeof(v8));
+  v10 = pMapStats->GetMapInfo(pCurrentMapName);
+  v9 = IndoorLocation::GetLocationIndex(dword_591164_teleport_map_name);
+  pRenderer->DrawTextureIndexed(0x1DDu, 0, pTexture_Dialogue_Background);
+  pRenderer->DrawTextureIndexed(pNPCPortraits_x[0][0] - 4, pNPCPortraits_y[0][0] - 4, pIcons_LOD->GetTexture(uTextureID_50795C));
+  pRenderer->DrawTextureIndexed(pNPCPortraits_x[0][0], pNPCPortraits_y[0][0], pTexture_outside);
+  uTextureID_right_panel_loop = uTextureID_right_panel;
+  pRenderer->DrawTextureTransparent(468, 0, pIcons_LOD->GetTexture(uTextureID_right_panel));
+  pRenderer->DrawTextureIndexed(556, 451, pIcons_LOD->GetTexture(uTextureID_x_x_u));
+  pRenderer->DrawTextureIndexed(476, 451, pIcons_LOD->GetTexture(uTextureID_x_ok_u));
+  if ( (pVideoPlayer->AnyMovieLoaded() || v9) && *dword_591164_teleport_map_name != ' ' )
+    v10 = pMapStats->GetMapInfo(dword_591164_teleport_map_name);
+  pMapInfo = &pMapStats->pInfos[v10];
+  v8.uFrameX = 493;
+  v8.uFrameWidth = 126;
+  v8.uFrameZ = 366;
+  v8.DrawTitleText(pFontCreate, 0, 5u, 0, pMapInfo->pName, 3);
+  v8.uFrameX = 483;
+  v8.uFrameWidth = 148;
+  v8.uFrameZ = 334;
+
+  v1 = "";
+  if ( uCurrentHouse_Animation )
+  {
+    v1 = pTransitionStrings[uCurrentHouse_Animation];
+    v4 = (212 - pFontCreate->CalcTextHeight(v1, &v8, 0, 0)) / 2 + 101;
+    v8.DrawTitleText(pFontCreate, 0, v4, 0, v1, 3);
+  }
+  else if ( v10 )
+  {
+    sprintfex(pTmpBuf, pGlobalTXT_LocalizationStrings[409], pMapInfo->pName);// "Do you wish to leave %s?"
+    v4 = (212 - pFontCreate->CalcTextHeight(pTmpBuf, &v8, 0, 0)) / 2 + 101;
+    v8.DrawTitleText(pFontCreate, 0, v4, 0, pTmpBuf, 3);
+  }
+  else assert(false);
+
+  _unused_5B5924_is_travel_ui_drawn = true;
+}
--- a/UiGame.cpp	Wed May 22 22:22:36 2013 +0600
+++ b/UiGame.cpp	Wed May 22 22:23:04 2013 +0600
@@ -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"
@@ -51,6 +67,762 @@
 int uTextureID_GameUI_CharSelectionFrame; // 50C98C
 
 
+
+
+
+
+//----- (00445D4A) --------------------------------------------------------
+void GameUI_InitializeDialogue(Actor *actor, int bPlayerSaysHello)
+{
+  NPCData *pNPCInfo; // ebp@1
+  int v9; // esi@8
+  int pNumberContacts; // eax@11
+  char pContainer[32]; // [sp+14h] [bp-28h]@3
+
+  dword_A74CDC = -1;
+  dword_AE336C = -1;
+  pEventTimer->Pause();
+  pMiscTimer->Pause();
+  pAudioPlayer->StopChannels(-1, -1);
+  uDialogueType = 0;
+  sDialogue_SpeakingActorNPC_ID = actor->sNPC_ID;
+  pDialogue_SpeakingActor = actor;
+  pNPCInfo = GetNPCData(actor->sNPC_ID);
+  if ( (pNPCInfo->uFlags & 3) != 2 )
+    pNPCInfo->uFlags = pNPCInfo->uFlags + 1;
+
+  switch (pParty->alignment)
+  {
+    case PartyAlignment_Good:    sprintfex(pContainer, "evt%02d-b", const_2()); break;
+    case PartyAlignment_Neutral: sprintfex(pContainer, "evt%02d", const_2());   break;
+    case PartyAlignment_Evil:    sprintfex(pContainer, "evt%02d-c", const_2()); break;
+  }
+
+  pDialogueNPCCount = 0;
+  uNumDialogueNPCPortraits = 1;
+  pTexture_Dialogue_Background = pIcons_LOD->LoadTexturePtr(pContainer, TEXTURE_16BIT_PALETTE);
+  sprintfex(pContainer, "npc%03u", pNPCInfo->uPortraitID);
+  v9 = 0;
+  pDialogueNPCPortraits[0] = pIcons_LOD->LoadTexturePtr(pContainer, TEXTURE_16BIT_PALETTE);
+  dword_591084 = areWeLoadingTexture;
+  uTextureID_right_panel_loop = uTextureID_right_panel;
+  if ( !pNPCInfo->Hired() && pNPCInfo->Location2D >= 0 )
+  {
+    if ( (signed int)pParty->GetPartyFame() <= pNPCInfo->fame
+      || (pNumberContacts = pNPCInfo->uFlags & 0xFFFFFF7F, (pNumberContacts & 0x80000000u) != 0) )
+    {
+      v9 = 1;
+    }
+	else
+	{
+		if ( pNumberContacts > 1 )
+		{
+		  if ( pNumberContacts == 2 )
+		  {
+			v9 = 3;
+		  }
+		  else
+		  {
+			  if ( pNumberContacts != 3 )
+			  {
+				if ( pNumberContacts != 4 )
+				  v9 = 1;
+			  }
+			  else
+			  {
+				v9 = 2;
+			  }
+		  }
+		}
+		else if ( pNPCInfo->rep )
+		{
+		  v9 = 2;
+		}
+	}
+  }
+  if (sDialogue_SpeakingActorNPC_ID < 0)
+    v9 = 4;
+  pDialogueWindow = GUIWindow::Create(0, 0, 640, 480, WINDOW_Dialogue, v9, 0);//pNumberContacts = 1, v9 = 0; pNumberContacts = 2, v9 = 3;
+  if (pNPCInfo->Hired())
+  {
+    if ( !pNPCInfo->bHasUsedTheAbility )
+    {
+      if ( pNPCInfo->uProfession >= 10 )
+      {
+        if ( pNPCInfo->uProfession <= 12 || pNPCInfo->uProfession > 32 && (pNPCInfo->uProfession <= 34 
+             || pNPCInfo->uProfession > 38 && (pNPCInfo->uProfession <= 43 || pNPCInfo->uProfession == 52)) )
+        {
+          pDialogueWindow->CreateButton(480, 250, 140, LOBYTE(pFontArrus->uFontHeight) - 3, 1, 0, UIMSG_SelectNPCDialogueOption, 9, 0, "", 0);
+          pDialogueWindow->_41D08F_set_keyboard_control_group(4, 1, 0, 1);
+        }
+      }
+    }
+  }
+
+  pDialogueWindow->CreateButton( 61, 424, 31, 40, 2, 94, UIMSG_SelectCharacter, 1, '1', "", 0);
+  pDialogueWindow->CreateButton(177, 424, 31, 40, 2, 94, UIMSG_SelectCharacter, 2, '2', "", 0);
+  pDialogueWindow->CreateButton(292, 424, 31, 40, 2, 94, UIMSG_SelectCharacter, 3, '3', "", 0);
+  pDialogueWindow->CreateButton(407, 424, 31, 40, 2, 94, UIMSG_SelectCharacter, 4, '4', "", 0);
+
+  if (bPlayerSaysHello && uActiveCharacter && !pNPCInfo->Hired())
+  {
+    if (pParty->uCurrentHour < 5 || pParty->uCurrentHour > 21)
+      pPlayers[uActiveCharacter]->PlaySound(SPEECH_GoodEvening, 0);
+    else
+      pPlayers[uActiveCharacter]->PlaySound(SPEECH_GoodDay, 0);
+  }
+}
+
+//----- (00445350) --------------------------------------------------------
+void GameUI_DrawDialogue()
+{
+  NPCData *pNPC; // ebx@2
+  int pGreetType; // eax@2
+  unsigned __int16 v2; // di@2
+  //unsigned int v3; // eax@2
+  char *v4; // esi@3
+  //int v5; // eax@11
+  //char *v6; // ecx@13
+  //char *v7; // eax@16
+  //unsigned int v8; // edi@19
+  //char *v9; // ecx@27
+  char *v10; // eax@29
+  //int v11; // eax@30
+  int v12; // esi@39
+  char *v13; // eax@41
+  GUIButton *v14; // eax@43
+  //GUIButton *v15; // edi@43
+  signed int v16; // eax@44
+  //unsigned int v23; // eax@53
+  //const char *v24; // eax@59
+  //unsigned __int16 v30; // cx@83
+  int v31; // ecx@86
+  int v32; // ebx@93
+  unsigned int v33; // eax@93
+  GUIWindow *v34; // ecx@93
+  int v35; // esi@93
+  int i; // eax@93
+  GUIButton *v37; // eax@94
+  int v38; // eax@95
+  signed int v39; // esi@99
+  signed int v40; // eax@102
+  unsigned int v41; // ebx@102
+  int v42; // edi@102
+  GUIButton *v43; // esi@103
+  int v44; // eax@104
+  unsigned int v45; // ecx@104
+  unsigned __int16 *v46; // edx@104
+  unsigned __int16 v47; // ax@104
+  GUIWindow pWindow; // [sp+4h] [bp-110h]@39
+  int v49; // [sp+Ch] [bp-108h]@39
+  int v50; // [sp+14h] [bp-100h]@39
+  GUIWindow v51; // [sp+58h] [bp-BCh]@2
+  GUIWindow v52; // [sp+ACh] [bp-68h]@42
+  char *Str; // [sp+100h] [bp-14h]@104
+  //int v54; // [sp+104h] [bp-10h]@2
+  //unsigned __int16 *v55; // [sp+108h] [bp-Ch]@82
+  GUIFont *pOutString; // [sp+10Ch] [bp-8h]@39
+  char *pInString=NULL; // [sp+110h] [bp-4h]@32
+
+  if ( !pDialogueWindow )
+    return;
+
+  memcpy(&v51, pDialogueWindow, sizeof(v51));
+  pNPC = GetNPCData(sDialogue_SpeakingActorNPC_ID);
+  pGreetType = GetGreetType(sDialogue_SpeakingActorNPC_ID);
+  v51.uFrameWidth -= 10;
+  v51.uFrameZ -= 10;
+  //v54 = v1;
+  TargetColor(0xFFu, 0xFFu, 0xFFu);
+  TargetColor(0xE1u, 0xCDu, 0x23u);
+  v2 = TargetColor(0x15u, 0x99u, 0xE9u);
+  pRenderer->DrawTextureIndexed(477, 0, pTexture_Dialogue_Background);
+  pRenderer->DrawTextureTransparent(468, 0, (Texture *)(uTextureID_right_panel_loop != -1 ? &pIcons_LOD->pTextures[uTextureID_right_panel_loop] : 0));
+  pRenderer->DrawTextureIndexed(pNPCPortraits_x[0][0] - 4, pNPCPortraits_y[0][0] - 4, (Texture *)(uTextureID_50795C != -1 ? &pIcons_LOD->pTextures[uTextureID_50795C] : 0));
+  pRenderer->DrawTextureIndexed(pNPCPortraits_x[0][0], pNPCPortraits_y[0][0], pDialogueNPCPortraits[0]);
+
+  if (pNPC->uProfession)
+  {
+    assert(pNPC->uProfession < sizeof(aNPCProfessionNames) / sizeof(*aNPCProfessionNames)); // sometimes buffer overflows; errors emerge both here and in dialogue text
+    sprintfex(pTmpBuf, pGlobalTXT_LocalizationStrings[429], pNPC->pName, aNPCProfessionNames[pNPC->uProfession]);//^Pi[%s] %s
+  }
+  else
+    strcpy(pTmpBuf, pNPC->pName);
+
+  v51.DrawTitleText(pFontArrus, 483, 112, v2, pTmpBuf, 3);
+  pParty->GetPartyFame();
+
+  pInString = nullptr;
+  switch (uDialogueType)
+  {
+    case DIALOGUE_13:
+      pInString = BuilDialogueString(pNPCStats->pProfessions[pNPC->uProfession - 1].pJoinText, uActiveCharacter - 1, 0, 0, 0, 0);
+    break;
+
+    case DIALOGUE_PROFESSION_DETAILS:
+    {
+      auto prof = pNPCStats->pProfessions + pNPC->uProfession - 1;
+
+      if (dialogue_show_profession_details)
+        pInString = BuilDialogueString(prof->pBenefits, uActiveCharacter - 1, 0, 0, 0, 0);
+      else if (pNPC->Hired())
+        pInString = BuilDialogueString(prof->pDismissText, uActiveCharacter - 1, 0, 0, 0, 0);
+      else
+        pInString = BuilDialogueString(prof->pJoinText, uActiveCharacter - 1, 0, 0, 0, 0);
+    }
+    break;
+
+
+    case DIALOGUE_ARENA_WELCOME:
+      pInString = pGlobalTXT_LocalizationStrings[574]; // "Welcome to the Arena of Life and Death.  Remember, you are only allowed one arena combat per visit.  To fight an arena battle, select the option that best describes your abilities and return to me- if you survive:"
+    break;
+
+    case DIALOGUE_ARENA_FIGHT_NOT_OVER_YET:
+      pInString = pGlobalTXT_LocalizationStrings[577]; //"Get back in there you wimps:"
+    break;
+
+    case DIALOGUE_ARENA_REWARD:
+      sprintfex(pTmpBuf, pGlobalTXT_LocalizationStrings[576], gold_transaction_amount);// "Congratulations on your win: here's your stuff: %u gold."
+      pInString = pTmpBuf;
+    break;
+
+    case DIALOGUE_ARENA_ALREADY_WON:
+      pInString = pGlobalTXT_LocalizationStrings[582]; // "You already won this trip to the Arena:"
+    break;
+
+    default:
+      if (uDialogueType > DIALOGUE_18 && uDialogueType < DIALOGUE_23 && !byte_5B0938[0])
+      {
+        pInString = (char *)current_npc_text;
+      }
+      else if (pGreetType == 1)//QuestNPC_greet
+      {
+        if (pNPC->greet)
+        {
+          if ((pNPC->uFlags & 3) == 2)
+            pInString = pNPCStats->pNPCGreetings[pNPC->greet - 1].pGreeting2;
+          else
+            pInString = pNPCStats->pNPCGreetings[pNPC->greet - 1].pGreeting1;
+        }
+      }
+      else if (pGreetType == 2)//HiredNPC_greet
+      {
+        auto prof = pNPCStats->pProfessions + pNPC->uProfession - 1;
+
+        if (pNPC->Hired())
+          pInString = BuilDialogueString(prof->pDismissText, uActiveCharacter - 1, 0, 0, 0, 0);
+        else
+          pInString = BuilDialogueString(prof->pJoinText, uActiveCharacter - 1, 0, 0, 0, 0);
+      }
+    break;
+  }
+
+  if (pInString)
+  {
+    pWindow.uFrameWidth = game_viewport_width;
+    pWindow.uFrameZ = 452;
+    auto font = pFontArrus;
+    v12 = pFontArrus->CalcTextHeight(pInString, &pWindow, 13, 0) + 7;
+    if ( 352 - v12 < 8 )
+    {
+      font = pFontCreate;
+       v12 = pFontCreate->CalcTextHeight(pInString, &pWindow, 13, 0) + 7;
+    }
+    if (uTextureID_Leather != -1)
+      pRenderer->_4A6A68(8, 352 - v12, &pIcons_LOD->pTextures[uTextureID_Leather], pIcons_LOD->pTextures[uTextureID_Leather].uTextureHeight - v12);
+    pRenderer->DrawTextureIndexed(8u, 347 - v12, pTexture_591428);
+    v13 = FitTextInAWindow(pInString, font,  &pWindow, 0xDu, 0);
+    pDialogueWindow->DrawText(font, 13, 354 - v12, 0, v13, 0, 0, 0);
+  }
+
+
+  memcpy(&v52, pDialogueWindow, sizeof(v52));
+  v52.uFrameX = 483;
+  v52.uFrameWidth = 148;
+  v52.uFrameZ = 334;
+  for (int i = v52.pStartingPosActiveItem;
+       i < v52.pStartingPosActiveItem + v52.pNumPresenceButton; ++i)
+  {
+    v14 = v52.GetControl(i);
+    //v15 = v14;
+    if ( !v14 )
+      break;
+    v16 = v14->msg_param;
+
+    if ( v16 > 88 )
+      v14->pButtonName[0] = 0;
+	else if (v16 == 88)
+      strcpy(v14->pButtonName, pGlobalTXT_LocalizationStrings[581]); // Lord
+    else if (v16 == 87)
+      strcpy(v14->pButtonName, pGlobalTXT_LocalizationStrings[580]); // Knight
+    else if (v16 == 86)
+      strcpy(v14->pButtonName, pGlobalTXT_LocalizationStrings[579]); // Squire
+    else if (v16 == 85)
+      strcpy(v14->pButtonName, pGlobalTXT_LocalizationStrings[578]); // Page
+    else if (v16 == 77)
+      strcpy(v14->pButtonName, pGlobalTXT_LocalizationStrings[407]); // Details
+    else if (v16 == 76)
+    {
+      if (pNPC->Hired())
+        sprintf(v14->pButtonName, (const char*)pGlobalTXT_LocalizationStrings[408], pNPC->pName); // Release %s
+      else
+        strcpy(v14->pButtonName, pGlobalTXT_LocalizationStrings[406]); // Hire
+    }
+	else if (v16 == 24)
+    {
+      __debugbreak(); // learn conditions of this event
+      auto topic = pNPCTopics[pNPC->evt_F - 1].pTopic;//(&dword_721660)[8 * v23];
+      if (!topic)
+      {
+        v14->pButtonName[0] = 0;
+        v14->msg_param = 0;
+      }
+      else
+        strcpy(v14->pButtonName, topic);
+    }
+	else if (v16 == 9)
+      strcpy(v14->pButtonName, GetProfessionActionText(pNPC->uProfession));
+	else if (v16 == 19)
+	{
+     // __debugbreak(); // learn conditions of this event Scavenger Hunt
+      auto topic = pNPCTopics[pNPC->evt_A - 1].pTopic;//(&dword_721660)[8 * v23];
+      if (!topic)
+      {
+        v14->pButtonName[0] = 0;
+        v14->msg_param = 0;
+      }
+      else strcpy(v14->pButtonName, topic);
+	}
+	else if (v16 == 20)
+	{
+      //__debugbreak(); // learn conditions of this event instruments
+      auto topic = pNPCTopics[pNPC->evt_B - 1].pTopic;//(&dword_721660)[8 * v23];
+      if (!topic)
+      {
+        v14->pButtonName[0] = 0;
+        v14->msg_param = 0;
+      }
+      else strcpy(v14->pButtonName, topic);
+	}
+	else if (v16 == 21)
+	{
+      //__debugbreak(); // learn conditions of this event
+      auto topic = pNPCTopics[pNPC->evt_C - 1].pTopic;//(&dword_721660)[8 * v23];
+      if (!topic)
+      {
+        v14->pButtonName[0] = 0;
+        v14->msg_param = 0;
+      }
+      else strcpy(v14->pButtonName, topic);
+	}
+	else if (v16 == 22)
+	{
+      //__debugbreak(); // learn conditions of this event
+      auto topic = pNPCTopics[pNPC->evt_D - 1].pTopic;//(&dword_721660)[8 * v23];
+      if (!topic)
+      {
+        v14->pButtonName[0] = 0;
+        v14->msg_param = 0;
+      }
+      else strcpy(v14->pButtonName, topic);
+	}
+	else if (v16 == 23)
+	{
+      //__debugbreak(); // learn conditions of this event
+      auto topic = pNPCTopics[pNPC->evt_E - 1].pTopic;//(&dword_721660)[8 * v23];
+      if (!topic)
+      {
+        v14->pButtonName[0] = 0;
+        v14->msg_param = 0;
+      }
+      else strcpy(v14->pButtonName, topic);
+	}
+	else if (v16 == 13)
+	{
+      if (pNPC->Hired())
+        sprintf(v14->pButtonName, pGlobalTXT_LocalizationStrings[408], pNPC->pName); // Release %s
+      else
+        strcpy(v14->pButtonName, pGlobalTXT_LocalizationStrings[122]); // Join
+	}
+	else
+      v14->pButtonName[0] = 0;
+	
+
+    if (pParty->field_7B5_in_arena_quest && pParty->field_7B5_in_arena_quest != -1)
+    {
+      int num_dead_actors = 0;
+      pInString = 0;
+      for (uint i = 0; i < uNumActors; ++i)
+      {
+        if (pActors[i].uAIState == Dead || pActors[i].uAIState == Removed ||
+            pActors[i].uAIState  == Disabled)
+          ++num_dead_actors;
+        else
+        {
+          int sumonner_type = PID_TYPE(pActors[i].uSummonerID);
+          if (sumonner_type == OBJECT_Player)
+            ++num_dead_actors;
+        }
+      }
+      if (num_dead_actors == uNumActors)
+        strcpy(v14->pButtonName, pGlobalTXT_LocalizationStrings[658]); // Collect Prize
+    }
+  }
+
+
+  v32 = 0;
+  //pInString = (char *)TargetColor(0xFFu, 0xFFu, 0xFFu);
+  v33 = TargetColor(0xE1u, 0xCDu, 0x23u);
+  v34 = pDialogueWindow;
+  //v54 = v33;
+  v35 = pDialogueWindow->pStartingPosActiveItem;
+  for ( i = v35 + pDialogueWindow->pNumPresenceButton; v35 < i; i = pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem )
+  {
+    v37 = v34->GetControl(v35);
+    if ( !v37 )
+    {
+      v34 = pDialogueWindow;
+      break;
+    }
+    v38 = pFontArrus->CalcTextHeight(v37->pButtonName, &v52, 0, 0);
+    v34 = pDialogueWindow;
+    v32 += v38;
+    ++v35;
+  }
+  v39 = v34->pNumPresenceButton;
+  if ( v39 )
+  {
+    pOutString = (GUIFont *)((174 - v32) / v39);
+    if ( (174 - v32) / v39 > 32 )
+      pOutString = (GUIFont *)32;
+    int v55 = 1;
+    v40 = 174 - (int)pOutString * v39 - v32;
+    v41 = v34->pStartingPosActiveItem;
+    v42 = v40 / 2 - (signed int)pOutString / 2 + 138;
+    if ( (signed int)v41 < (signed int)(v41 + v39) )
+    {
+      do
+      {
+        v43 = v34->GetControl(v41);
+        if ( !v43 )
+          break;
+        v43->uY = (unsigned int)((char *)pOutString + v42);
+        Str = v43->pButtonName;
+        v44 = pFontArrus->CalcTextHeight(v43->pButtonName, &v52, 0, 0);
+        v45 = v43->uY;
+        v46 = (unsigned short *)v55;
+        v43->uHeight = v44;
+        v42 = v45 + v44 - 1;
+        v43->uW = v42;
+        v47 = v33;
+        if ( (unsigned __int16 *)pDialogueWindow->pCurrentPosActiveItem != v46 )
+          v47 = TargetColor(0xFFu, 0xFFu, 0xFFu);
+        v52.DrawTitleText(pFontArrus, 0, v45, v47, Str, 3u);
+        v34 = pDialogueWindow;
+        ++v55;
+        ++v41;
+      }
+      while ( (signed int)v41 < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem );
+    }
+  }
+  pRenderer->DrawTextureIndexed(471, 445, pIcons_LOD->GetTexture(uExitCancelTextureId));
+}
+
+
+
+//----- (00444FBE) --------------------------------------------------------
+void GameUI_DrawBranchlessDialogue()
+{
+  //GUIFont *v0; // esi@1
+  int v1; // esi@4
+  char *v2; // eax@6
+  int v3; // edi@12
+  char Str[200]; // [sp+Ch] [bp-120h]@12
+  GUIWindow v5; // [sp+D4h] [bp-58h]@4
+  GUIFont *pFont; // [sp+128h] [bp-4h]@1
+
+  pFont = pFontArrus;
+  if ( current_npc_text && !byte_5B0938[0] )
+    strcpy(byte_5B0938, current_npc_text);
+  v5.uFrameWidth = game_viewport_width;
+  v5.uFrameZ = 452;
+  v1 = pFontArrus->CalcTextHeight(byte_5B0938, &v5, 12, 0) + 7;
+  if ( 352 - v1 < 8 )
+  {
+    pFont = pFontCreate;
+    v1 = pFontCreate->CalcTextHeight(byte_5B0938, &v5, 12, 0) + 7;
+  }
+  pRenderer->_4A6A68(8, 352 - v1,
+    pIcons_LOD->GetTexture(uTextureID_Leather),
+    pIcons_LOD->GetTexture(uTextureID_Leather)->uTextureHeight - v1);
+  pRenderer->DrawTextureIndexed(8, 347 - v1, pTexture_591428);
+  v2 = FitTextInAWindow(byte_5B0938, pFont, &v5, 0xCu, 0);
+  pGUIWindow2->DrawText(pFont, 12, 354 - v1, 0, v2, 0, 0, 0);
+  pRenderer->DrawTextureRGB(0, 0x160u, pTexture_StatusBar);
+  if ( pGUIWindow2->field_40 != 1 )
+  {
+    if ( pGUIWindow2->field_40 == 2 )
+    {
+      pGUIWindow2->field_40 = 0;
+      strcpy(GameUI_Footer_TimedString, (const char *)pKeyActionMap->pPressedKeysBuffer);
+LABEL_16:
+      sub_4452BB();
+      return;
+    }
+    if ( pGUIWindow2->field_40 != 3 )
+      return;
+    pGUIWindow2->field_40 = 0;
+LABEL_15:
+    memset(GameUI_Footer_TimedString, 0, 0xC8u);
+    goto LABEL_16;
+  }
+  if ( pGUIWindow2->ptr_1C == (void *)26 )
+  {
+    sprintf(Str, "%s %s", GameUI_Footer_TimedString, pKeyActionMap->pPressedKeysBuffer);
+    v3 = pFontLucida->GetLineWidth(Str);
+    pGUIWindow2->DrawText(pFontLucida, 13, 357, 0, Str, 0, 0, 0);
+    pGUIWindow2->DrawFlashingInputCursor(v3 + 13, 357, pFontLucida);
+    return;
+  }
+  if ( pKeyActionMap->pPressedKeysBuffer[0] )
+  {
+    pKeyActionMap->_459ED1(0);
+    goto LABEL_15;
+  }
+}
+
+
+//----- (004443D5) --------------------------------------------------------
+const char *GameUI_GetMinimapHintText()
+{
+  int v0; // ST20_4@1
+  unsigned int v1; // esi@1
+  signed int v2; // ebx@1
+  double v3; // st7@1
+  int v4; // esi@3
+  int v5; // edi@4
+  int v6; // eax@4
+  int v7; // eax@4
+  BSPModel *v8; // ecx@4
+  unsigned __int8 v9; // zf@5
+  char v10; // sf@5
+  unsigned __int8 v11; // of@5
+  ODMFace *v12; // eax@6
+  __int16 v13; // cx@6
+  const char *v14; // eax@8
+  const char *v15; // edi@8
+  char *result; // eax@12
+  unsigned int v17; // eax@14
+  unsigned int v18; // [sp+Ch] [bp-20h]@1
+  int v19; // [sp+10h] [bp-1Ch]@1
+  int v20; // [sp+14h] [bp-18h]@1
+  char *v21; // [sp+18h] [bp-14h]@1
+  unsigned int pY; // [sp+1Ch] [bp-10h]@1
+  int v23; // [sp+20h] [bp-Ch]@1
+  int v24; // [sp+24h] [bp-8h]@1
+  int pX; // [sp+28h] [bp-4h]@1
+
+  v24 = pParty->vPosition.x;
+  v0 = pParty->vPosition.y;
+  v1 = pOutdoor->uNumBModels;
+  *(float *)&v23 = (double)(signed int)viewparams->uMinimapZoom * 0.000015258789;
+  v2 = 0;
+  v18 = pOutdoor->uNumBModels;
+  v21 = 0;
+  pMouse->GetClickPos((unsigned int *)&pX, &pY);
+  v3 = 1.0 / *(float *)&v23;
+  v23 = pX - 557;
+  v19 = (signed __int64)((double)(pX - 557) * v3 + (double)v24);
+  v20 = (signed __int64)((double)v0 - (double)(signed int)(pY - 74) * v3);
+  if ( uCurrentlyLoadedLevelType != LEVEL_Outdoor || (*(float *)&v23 = 0.0, (signed int)v1 <= 0) )
+  {
+LABEL_14:
+    v17 = pMapStats->GetMapInfo(pCurrentMapName);
+    if ( v17 == v2 )
+      result = "No Maze Info for this maze on file!";
+    else
+      result = pMapStats->pInfos[v17].pName;
+  }
+  else
+  {
+    v4 = 0;
+    while ( 1 )
+    {
+      pX = pOutdoor->pBModels[v4].vBoundingCenter.x - v19;
+      pY = pOutdoor->pBModels[v4].vBoundingCenter.y - v20;
+      v5 = abs((signed)pY);
+      v6 = abs((signed)pX);
+      v7 = int_get_vector_length(v6, v5, v2);
+      v8 = &pOutdoor->pBModels[0];
+      if ( v7 < 2 * pOutdoor->pBModels[v4].sBoundingRadius )
+      {
+        v11 = __OFSUB__(pOutdoor->pBModels[v4].uNumFaces, v2);
+        v9 = pOutdoor->pBModels[v4].uNumFaces == v2;
+        v10 = ((pOutdoor->pBModels[v4].uNumFaces - v2) & 0x80000000u) != 0;
+        v24 = v2;
+        if ( !((unsigned __int8)(v10 ^ v11) | v9) )
+        {
+          do
+          {
+            v12 = &v8[v4].pFaces[v2 / 0x134u];
+            v13 = v12->sCogTriggeredID;
+            if ( v13 )
+            {
+              if ( !(BYTE2(v12->uAttributes) & 0x10) )
+              {
+                v14 = GetEventHintString(v13);
+                v15 = v14;
+                if ( v14 )
+                {
+                  if ( _strcmpi(v14, "") )
+                    v21 = (char *)v15;
+                }
+              }
+            }
+            ++v24;
+            v8 = pOutdoor->pBModels;
+            v2 += 308;
+          }
+          while ( v24 < (signed int)pOutdoor->pBModels[v4].uNumFaces );
+        }
+        result = v21;
+        v2 = 0;
+        if ( v21 )
+          break;
+      }
+      ++v23;
+      ++v4;
+      if ( v23 >= (signed int)v18 )
+        goto LABEL_14;
+    }
+  }
+  return result;
+}
+
+
+
+
+
+//----- (0041D3B7) --------------------------------------------------------
+void GameUI_CharacterQuickRecord_Draw(GUIWindow *window, Player *player)
+{
+  //Player *pPlayer; // esi@1
+  int v6; // eax@5
+  int v7; // ebx@5
+  //unsigned int v8; // ecx@5
+  int v9; // ebx@5
+  //unsigned int v10; // eax@5
+  //int v11; // eax@5
+  //unsigned int v12; // ecx@5
+  Texture *v13; // eax@6
+  unsigned int v14; // eax@12
+  PlayerFrame *v15; // eax@12
+  //unsigned int v16; // eax@15
+  unsigned int v20; // eax@15
+  unsigned int v24; // eax@15
+  unsigned int v25; // eax@15
+  unsigned __int8 v28; // al@15
+  char *v29; // eax@16
+  __int64 v35; // ST38_8@22
+  int v36; // esi@22
+  unsigned int v38; // eax@22
+  char *v39; // eax@24
+  signed int uFramesetID; // [sp+20h] [bp-8h]@9
+  int uFramesetIDa; // [sp+20h] [bp-8h]@18
+
+  uint numActivePlayerBuffs = 0;
+  for (uint i = 0; i < 24; ++i)
+    if (player->pPlayerBuffs[i].uExpireTime > 0)
+      ++numActivePlayerBuffs;
+
+  v6 = pFontArrus->uFontHeight + 162;
+  v7 = (numActivePlayerBuffs - 1) * pFontArrus->uFontHeight;
+  v9 = v6 + v7;
+  window->uFrameHeight = v9;
+  window->uFrameZ = window->uFrameWidth + window->uFrameX - 1;
+  window->uFrameW = v9 + window->uFrameY - 1;
+  window->DrawMessageBox(0);
+
+  if (player->Eradicated())
+    v13 = pTexture_PlayerFaceEradicated;
+  else if (player->Dead())
+    v13 = pTexture_PlayerFaceDead;
+  else
+  {
+      uFramesetID = pPlayerFrameTable->GetFrameIdByExpression(player->expression);
+      if ( !uFramesetID )
+        uFramesetID = 1;
+      if ( player->expression == CHARACTER_EXPRESSION_21)
+      {
+        v15 = pPlayerFrameTable->GetFrameBy_y(&player->_expression21_frameset, &player->_expression21_animtime, pMiscTimer->uTimeElapsed);
+      }
+      else
+      {
+        v14 = pMiscTimer->Time();
+        v15 = pPlayerFrameTable->GetFrameBy_x(uFramesetID, v14);
+      }
+      player->field_1AA2 = v15->uTextureID - 1;
+      v13 = pTextures_PlayerFaces[(unsigned int)window->ptr_1C][v15->uTextureID - 1];
+  }
+
+  pRenderer->DrawTextureTransparent(window->uFrameX + 24, window->uFrameY + 24, v13);
+
+  sprintfex(pTmpBuf, "\f%05d", ui_character_header_text_color);
+  sprintfex(pTmpBuf2, pGlobalTXT_LocalizationStrings[429], player->pName, pClassNames[player->classType]); // "%s the %s"
+  strcat(pTmpBuf, pTmpBuf2);
+  strcat(pTmpBuf, "\f00000\n");
+
+  v20 = UI_GetHealthManaStringColor(player->sHealth, player->GetMaxHealth());
+  sprintf(pTmpBuf2, "%s : \f%05u%d\f00000 / %d\n",
+          pGlobalTXT_LocalizationStrings[108], // "Hit Points"
+          v20, player->sHealth, player->GetMaxHealth());
+  strcat(pTmpBuf, pTmpBuf2);
+
+  v24 = UI_GetHealthManaStringColor(player->sMana, player->GetMaxMana());
+  sprintf(pTmpBuf2, "%s : \f%05u%d\f00000 / %d\n",
+          pGlobalTXT_LocalizationStrings[212], // "Spell Points"
+          v24, player->sMana, player->GetMaxMana());
+  strcat(pTmpBuf, pTmpBuf2);
+
+  v25 = player->GetMajorConditionIdx();
+  sprintf(pTmpBuf2, "%s: \f%05d%s\f00000\n",
+          pGlobalTXT_LocalizationStrings[47], // "Condition
+          GetConditionDrawColor(v25), aCharacterConditionNames[v25]);
+  strcat(pTmpBuf, pTmpBuf2);
+
+  v28 = player->uQuickSpell;
+  if ( v28 )
+    v29 = pSpellStats->pInfos[v28].pShortName;
+  else
+    v29 = pGlobalTXT_LocalizationStrings[153];
+  sprintfex(pTmpBuf2, "%s: %s", pGlobalTXT_LocalizationStrings[172], v29); // "Quick Spell"
+  strcat(pTmpBuf, pTmpBuf2);
+
+  window->DrawText(pFontArrus, 120, 22, 0, pTmpBuf, 0, 0, 0);
+
+  uFramesetIDa = 0;
+  for (uint i = 0; i < 24; ++i)
+  {
+    auto buff = player->pPlayerBuffs + i;
+    if (buff->uExpireTime > 0)
+    {
+      v35 = buff->uExpireTime - pParty->uTimePlayed;
+      v36 = uFramesetIDa++ * pFontComic->uFontHeight + 134;
+      v38 = ui_game_character_record_playerbuff_colors[i];
+      window->DrawText(pFontComic, 52, v36, v38, aSpellNames[20 + i], 0, 0, 0);
+      sub_41D20D_buff_remaining_time_string(v36, window, v35, pFontComic);
+    }
+  }
+
+  v39 = "";
+  if ( uFramesetIDa == 0 )
+    v39 = pGlobalTXT_LocalizationStrings[153]; // "None"
+  sprintf(pTmpBuf, pGlobalTXT_LocalizationStrings[450], v39); // "Active Spells: %s"
+  window->DrawText(pFontArrus, 14, 114, 0, pTmpBuf, 0, 0, 0);
+}
+
+
+
 //----- (0041A57E) --------------------------------------------------------
 void GameUI_QuickRef_Draw()
 {
@@ -654,7 +1426,7 @@
         }
         if (PID_TYPE(v18) == OBJECT_BModel)
         {
-          if ( v18 < (signed int)0x2000000u )
+          if ( HIWORD(v18) < 512)
           {
             if ( uCurrentlyLoadedLevelType != LEVEL_Indoor)
             {
--- a/VectorTypes.h	Wed May 22 22:22:36 2013 +0600
+++ b/VectorTypes.h	Wed May 22 22:23:04 2013 +0600
@@ -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	Wed May 22 22:22:36 2013 +0600
+++ b/VideoPlayer.cpp	Wed May 22 22:23:04 2013 +0600
@@ -2,6 +2,9 @@
 
 #include "Bink_Smacker.h"
 
+#include "CShow.h"
+#include "Mouse.h"
+
 #include "OSInfo.h"
 #include "VideoPlayer.h"
 #include "AudioPlayer.h"
@@ -322,6 +325,11 @@
 
   pRenderer->EndScene();
   pRenderer->Present();
+
+  #ifndef _DEBUG
+    Sleep(1500);   // let the copyright window stay for a while
+  #endif
+
   if (!bNoSound && pAudioPlayer->hAILRedbook )
   {
     pAudioPlayer->SetMusicVolume((signed __int64)(pSoundVolumeLevels[uMusicVolimeMultiplier] * 64.0));
@@ -445,14 +453,14 @@
     if ( a2.dwRBitMask == 0xF800 )
     {
       if ( a2.dwGBitMask == 0x7E0 && a2.dwBBitMask == 0x1F )
-        return 0xC0000000u;
+        return SMACKBUFFER565;
     }
     else
     {
       if ( a2.dwRBitMask == 0x7C00
         && a2.dwGBitMask == 0x3E0
         && a2.dwBBitMask == 0x1F )
-        return 0x80000000u;
+        return SMACKBUFFER555;
     }
     MessageBoxA(0, "Unsupported pixel format.", "Smacker Error", 0);
   }
@@ -808,12 +816,7 @@
       Unload();
   }
 }
-// 4D83D8: using guessed type int __stdcall SmackBlitSetPalette(int, int, int);
-// 4D83DC: using guessed type int __stdcall SmackBlitClear(int, int, int, int, int, int, int, int);
-// 4D83E0: using guessed type int __stdcall SmackToBufferRect(int, int);
-// 4D83E4: using guessed type int __stdcall SmackDoFrame(int);
-// 4D83E8: using guessed type int __stdcall SmackNextFrame(int);
-// 4D8404: using guessed type int __stdcall SmackBlit(int, int, int, int, int, int, int, int, int, int, int);
+
 
 //----- (004BF08B) --------------------------------------------------------
 void VideoPlayer::SmackUpdatePalette(HWND hWnd)
@@ -1060,23 +1063,18 @@
         return;
       }
       SmackToBuffer(pVideoPlayer->pSmackerMovie, 0, 0, pVideoPlayer->pSmackerMovie->Width, pVideoPlayer->pSmackerMovie->Height, v9, 0);
+
+      v10 = SmackCheckSurfaceFromat();
       if ( a4 )
       {
-        if ( (unsigned int)uCPUSpeed < 165 )
-        {
-          Log::Warning(L"Smacker seems to use lower resolution because it thinks CPU is slow");
-          v10 = SmackCheckSurfaceFromat() | 2;
-        }
+        v10 |= SMACKBLIT2X;
+
+        if (uCPUSpeed >= 165 )
+          v10 |= SMACKBLIT2XSMOOTHING;
         else
-        {
-          v10 = SmackCheckSurfaceFromat();
-          LOBYTE(v10) = v10 | 6;
-        }
+          Log::Warning(L"Smacker seems to use lower resolution because it thinks CPU is slow");
       }
-      else
-      {
-        v10 = SmackCheckSurfaceFromat();
-      }
+
       v11 = SmackBlitOpen(v10);
       pVideoPlayer->pSmackMovieBlit = v11;
       if ( !v11 )
--- a/Viewport.cpp	Wed May 22 22:22:36 2013 +0600
+++ b/Viewport.cpp	Wed May 22 22:23:04 2013 +0600
@@ -19,6 +19,7 @@
     br_x = sBR_X;
     if ( sTL_X > sBR_X )
         {
+          __debugbreak(); // check this code
         br_x = sBR_X ^ sTL_X ^ sBR_X;                           // swap x's
         tl_x = br_x ^ sBR_X ^ sTL_X;
         }
@@ -26,6 +27,7 @@
     br_y = sBR_Y;
     if ( sTL_Y > sBR_Y )
         {
+          __debugbreak(); // check this code
         br_y = sBR_Y ^ sTL_Y ^ sBR_Y;                           // swap y's 
         tl_y = br_y ^ sBR_Y ^ sTL_Y;
         }
--- a/Vis.cpp	Wed May 22 22:22:36 2013 +0600
+++ b/Vis.cpp	Wed May 22 22:23:04 2013 +0600
@@ -1,5 +1,6 @@
 #include <assert.h>
 
+#include "BSPModel.h"
 #include "Vis.h"
 #include "Outdoor.h"
 #include "Game.h"
@@ -327,7 +328,7 @@
             if ( Intersect_Ray_Face(pRay, pRay + 1, &fDepth, &a1, &pIndoor->pFaces[pFaceID], 0xFFFFFFFFu) )
             {
               pGame->pIndoorCameraD3D->ViewTransform(&a1, 1);
-              v9 = _48B561_mess_with_scaling_along_z(/*v8, */a1.vWorldViewPosition.x);
+              v9 = fixpoint_from_float(/*v8, */a1.vWorldViewPosition.x);
               LOWORD(v9) = 0;
               v15 = (void *)((PID(OBJECT_BModel,pFaceID)) + v9);
               pNumPointers = &list->uNumPointers;
@@ -366,8 +367,8 @@
     auto bmodel = &pOutdoor->pBModels[i];
     for (uint j = 0; j < bmodel->uNumFaces; ++j)
     {
-		if ( i == 77 && j == 17 )//
-		  __debugbreak();//
+		//if ( i == 77 && j == 17 )//
+		  //__debugbreak();//
       auto face = &bmodel->pFaces[j];
       if (is_part_of_selection(face, filter))
       {
@@ -378,7 +379,8 @@
         if (Intersect_Ray_Face(pRay, pRay + 1, &fDepth, &intersection, &blv_face, i))
         {
           pGame->pIndoorCameraD3D->ViewTransform(&intersection, 1);
-          int v13 = _48B561_mess_with_scaling_along_z(/*v12, */intersection.vWorldViewPosition.x);
+          int v13 = fixpoint_from_float(/*v12, */intersection.vWorldViewPosition.x);
+          v13 &= 0xFFFF0000;
           v13 += PID(OBJECT_BModel, j | (i << 6));
 
           list->AddObject(face, VisObjectType_Face, v13);
@@ -543,11 +545,11 @@
 }
 
 //----- (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
-  double c2; // st7@3
+  double v9; // st7@3
   //__int16 v10; // fps@3
   //char v11; // c0@3
   //char v12; // c2@3
@@ -557,7 +559,6 @@
   //char v16; // c2@5
   //char v17; // c3@5
   double c1; // st5@6
-  double v9;
   //__int16 v19; // fps@6
   //char v20; // c0@6
   //char v21; // c2@6
@@ -566,30 +567,29 @@
   //char v24; // c2@6
   //unsigned __int8 v25; // c3@6
   //char v26; // zf@6
-  double t2; // st6@10
+  double v27; // st6@10
   //__int16 v28; // fps@10
   //unsigned __int8 v29; // c0@10
   //char v30; // c2@10
   //unsigned __int8 v31; // c3@10
-  //double v32; // st7@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
@@ -602,83 +602,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;*/
 
-//  v7 = a5;
-  //result = a5->uAttributes;
- 
-  //a5->uAttributes |= 0x80000000;
-  //return false;
 
-  c1 = -a5->pFacePlane.dist -(a5->pFacePlane.vNormal.x * pRayStart->vWorldPosition.x 
-         + a5->pFacePlane.vNormal.y * pRayStart->vWorldPosition.y
-         + a5->pFacePlane.vNormal.z * pRayStart->vWorldPosition.z);
-  if (c1 > 0)
+//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;
 
-  c2 = a5->pFacePlane.vNormal.x * ray_dir_x  + a5->pFacePlane.vNormal.y *ray_dir_y + a5->pFacePlane.vNormal.z * ray_dir_z;
-  //if (v9 >= 0)   // ray faces face's normal ( > 0) or parallel ( == 0)
+//t = -d-(n*p0)/n*u
+  double t = c1 / c2;// 
+
+  //if (t < 0 || t > 1)
     //return false;
 
-  //t = -d-(n * p0)/n * u
-  t2 = c1 / c2;
-
-  if (t2 > *pDepth)
-    return false;
-
-  //a5->uAttributes |= 0x80000000;
+  // 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
 
-  a4->vWorldPosition.x = pRayStart->vWorldPosition.x + t2 * ray_dir_x;//12432 < X < 12656
-  a4->vWorldPosition.y = pRayStart->vWorldPosition.y + t2 * ray_dir_y;//-96 < Y < 1088
-  a4->vWorldPosition.z = pRayStart->vWorldPosition.z + t2 * ray_dir_z;//Z == 192
-
-  v34.x = (signed __int64)a4->vWorldPosition.x;
-  v34.y = (signed __int64)a4->vWorldPosition.y;
-  v34.z = (signed __int64)a4->vWorldPosition.z;
+  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) )
+  if ( !_4C1D2B(pFace, v34, pBModelID) )
     return false;
 
   //a5b = v27;
-  //*pDepth = t2;
+  //*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
@@ -692,16 +693,16 @@
   int v15; // [sp+10h] [bp-Ch]@10
   signed int v16; // [sp+18h] [bp-4h]@10
 
-  v4 = pFace;
+  //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)
+      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);
@@ -711,7 +712,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];
@@ -760,261 +761,183 @@
 //----- (004C1EE5) --------------------------------------------------------
 bool Vis::_4C1EE5_BLV_IntersectBModel_2(int *a1, int *a2, __int16 *a3, __int16 *a4, Vec3_short_ *a5, BLVFace *pFace)
 {
-  bool result; // eax@1
-  unsigned int v8; // ecx@1
-  Vec3_short_ *v9; // ecx@2
-  __int16 *v10; // edx@3
-  signed int v11; // ecx@4
-  char v12; // zf@6
-  Vec3_short_ *v13; // ecx@6
-  int v14; // edx@7
-  __int16 *v15; // edx@8
-  signed int v16; // ecx@9
-  int v17; // edx@11
-  __int16 *v18; // edx@12
-  signed int v19; // ecx@13
-  signed int a5a; // [sp+24h] [bp+18h]@2
-  signed int a5b; // [sp+24h] [bp+18h]@7
-  signed int a5c; // [sp+24h] [bp+18h]@11
+  if (pFace->uAttributes & FACE_XY_PLANE)
+  {
+    *a1 = a5->x;
+    *a2 = a5->y;
+
+    for (uint i = 0; i < pFace->uNumVertices; ++i)
+    {
+      a3[2 * i] = pFace->pXInterceptDisplacements[i] + pIndoor->pVertices[pFace->pVertexIDs[i]].x;
+      a3[2 * i + 1] = pFace->pXInterceptDisplacements[i + 1] + pIndoor->pVertices[pFace->pVertexIDs[i + 1]].x;
+
+      a4[2 * i] = pFace->pYInterceptDisplacements[i] + pIndoor->pVertices[pFace->pVertexIDs[i]].y;
+      a4[2 * i + 1] = pFace->pYInterceptDisplacements[i + 1] + pIndoor->pVertices[pFace->pVertexIDs[i + 1]].y;
+    }
+  }
+  else if (pFace->uAttributes & FACE_XZ_PLANE)
+  {
+    *a1 = a5->x;
+    *a2 = a5->z;
 
-  result = (bool)pFace;
-  v8 = pFace->uAttributes;
-  if ( BYTE1(v8) & 1 )
-  {
-    v9 = a5;
-    a5a = 0;
-    *a1 = v9->x;
-    *a2 = v9->y;
-    if ( pFace->uNumVertices )
+    for (uint i = 0; i < pFace->uNumVertices; ++i)
     {
-      v10 = a4 + 1;
-      do
-      {
-        v11 = a5a;
-        a3[2 * a5a] = pFace->pXInterceptDisplacements[a5a] + pIndoor->pVertices[pFace->pVertexIDs[a5a]].x;
-        *(v10 - 1) = pFace->pYInterceptDisplacements[v11] + pIndoor->pVertices[pFace->pVertexIDs[v11]].y;
-        *(__int16 *)((char *)v10 + (int)a3 - (int)a4) = pFace->pXInterceptDisplacements[v11 + 1]
-                                                            + pIndoor->pVertices[pFace->pVertexIDs[v11 + 1]].x;
-        ++a5a;
-        *v10 = pFace->pYInterceptDisplacements[v11 + 1] + pIndoor->pVertices[pFace->pVertexIDs[v11 + 1]].y;
-        v10 += 2;
-      }
-      while ( a5a < pFace->uNumVertices );
+      a3[2 * i] = pFace->pXInterceptDisplacements[i] + pIndoor->pVertices[pFace->pVertexIDs[i]].x;
+      a3[2 * i + 1] = pFace->pXInterceptDisplacements[i + 1] + pIndoor->pVertices[pFace->pVertexIDs[i + 1]].x;
+
+      a4[2 * i] = pFace->pZInterceptDisplacements[i] + pIndoor->pVertices[pFace->pVertexIDs[i]].z;
+      a4[2 * i + 1] = pFace->pZInterceptDisplacements[i + 1] + pIndoor->pVertices[pFace->pVertexIDs[i + 1]].z;
+    }
+  }
+  else if (pFace->uAttributes & FACE_YZ_PLANE)
+  {
+    *a1 = a5->y;
+    *a2 = a5->z;
+
+    for (uint i = 0; i < pFace->uNumVertices; ++i)
+    {
+      a3[2 * i] = pFace->pYInterceptDisplacements[i] + pIndoor->pVertices[pFace->pVertexIDs[i]].y;
+      a3[2 * i + 1] = pFace->pYInterceptDisplacements[i + 1] + pIndoor->pVertices[pFace->pVertexIDs[i + 1]].y;
+
+      a4[2 * i] = pFace->pZInterceptDisplacements[i] + pIndoor->pVertices[pFace->pVertexIDs[i]].z;
+      a4[2 * i + 1] = pFace->pZInterceptDisplacements[i + 1] + pIndoor->pVertices[pFace->pVertexIDs[i + 1]].z;
     }
   }
   else
   {
-    v12 = (BYTE1(v8) & 2) == 0;
-    v13 = a5;
-    if ( v12 )
+    assert(false);
+    return false;
+  }
+
+  return true;
+}
+
+//----- (004C2186) --------------------------------------------------------
+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
+  __int16 v13; // si@4
+  __int16 *v14; // ecx@4
+  unsigned int v15; // edx@8
+  //signed int v16; // ecx@9
+  __int16 v17; // si@9
+  __int16 *v18; // ecx@9
+  unsigned int v19; // edx@12
+  //signed int v20; // ecx@13
+  __int16 v21; // si@13
+  __int16 *v22; // ecx@13
+  //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 = pFace;
+  //v10 = pFace->uAttributes;
+  //a1a = 0;
+  if ( BYTE1(pFace->uAttributes) & 1 )
+  {
+    pFace->pFacePlane.vNormal.x = a5->x;
+    pFace->pFacePlane.vNormal.y = a5->y;
+    if ( pFace->uNumVertices )
     {
-      v17 = a5->y;
-      a5c = 0;
-      *a1 = v17;
-      *a2 = v13->z;
+      //v11 = 188 * ModelID + 72;
+      a5a = displaced_face_intersect_plane_coords_b + 1;
+      for ( uint i = 0; i < pFace->uNumVertices; ++i )
+      {
+        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;
+        a5a += 2;
+        *v14 = v13;
+      }
+    }
+  }
+  else
+  {
+    if ( BYTE1(pFace->uAttributes) & 2 )
+    {
+      pFace->pFacePlane.vNormal.x = a5->x;
+      pFace->pFacePlane.vNormal.z = a5->z;
       if ( pFace->uNumVertices )
       {
-        v18 = a4 + 1;
-        do
+        v15 = 188 * uModelID + 72;
+        a5b = displaced_face_intersect_plane_coords_b + 1;
+        for ( uint i = 0; i < pFace->uNumVertices; ++i )
         {
-          v19 = a5c;
-          a3[2 * a5c] = pFace->pYInterceptDisplacements[a5c] + pIndoor->pVertices[pFace->pVertexIDs[a5c]].y;
-          *(v18 - 1) = pFace->pZInterceptDisplacements[v19] + pIndoor->pVertices[pFace->pVertexIDs[v19]].z;
-          *(__int16 *)((char *)v18 + (int)(char *)a3 - (char *)a4) = pFace->pYInterceptDisplacements[v19 + 1]
-                                                              + pIndoor->pVertices[pFace->pVertexIDs[v19 + 1]].y;
-          ++a5c;
-          *v18 = pFace->pZInterceptDisplacements[v19 + 1] + pIndoor->pVertices[pFace->pVertexIDs[v19 + 1]].z;
-          v18 += 2;
+          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;
+          a5b += 2;
+          *v18 = v17;
         }
-        while ( a5c < pFace->uNumVertices );
       }
     }
     else
     {
-      v14 = a5->x;
-      a5b = 0;
-      *a1 = v14;
-      *a2 = v13->z;
+      pFace->pFacePlane.vNormal.y = a5->y;
+      pFace->pFacePlane.vNormal.z = a5->z;
       if ( pFace->uNumVertices )
       {
-        v15 = a4 + 1;
-        do
+        v19 = 188 * uModelID + 72;
+        a5c = displaced_face_intersect_plane_coords_b + 1;
+        for ( uint i = 0; i < pFace->uNumVertices; ++i )
         {
-          v16 = a5b;
-          a3[2 * a5b] = pFace->pXInterceptDisplacements[a5b] + pIndoor->pVertices[pFace->pVertexIDs[a5b]].x;
-          *(v15 - 1) = pFace->pZInterceptDisplacements[v16] + pIndoor->pVertices[pFace->pVertexIDs[v16]].z;
-          *(__int16 *)((char *)v15 + (int)a3 - (int)a4) = pFace->pXInterceptDisplacements[v16 + 1]
-                                                              + pIndoor->pVertices[pFace->pVertexIDs[v16 + 1]].x;
-          ++a5b;
-          *v15 = pFace->pZInterceptDisplacements[v16 + 1] + pIndoor->pVertices[pFace->pVertexIDs[v16 + 1]].z;
-          v15 += 2;
+          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;
+          a5c += 2;
+          *v22 = v21;
         }
-        while ( a5b < pFace->uNumVertices );
       }
     }
   }
-  LOBYTE(result) = 1;
-  return result;
-}
-
-//----- (004C2186) --------------------------------------------------------
-bool Vis::_4C2186_BLV_IntersectBModel(int *a1, int *a2, __int16 *a3, __int16 *a4, Vec3_short_ *a5, BLVFace *a6, 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
-  __int16 v13; // si@4
-  __int16 *v14; // ecx@4
-  unsigned int v15; // edx@8
-  signed int v16; // ecx@9
-  __int16 v17; // si@9
-  __int16 *v18; // ecx@9
-  unsigned int v19; // edx@12
-  signed int v20; // ecx@13
-  __int16 v21; // si@13
-  __int16 *v22; // ecx@13
-  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 )
-  {
-    *v9 = a5->x;
-    *a2 = a5->y;
-    if ( a6->uNumVertices )
-    {
-      v11 = 188 * uModelID + 72;
-      a5a = a4 + 1;
-      do
-      {
-        v12 = a1a;
-        a3[2 * a1a] = a6->pXInterceptDisplacements[a1a]
-//                    + *(short *)(*(int *)&pOutdoor->pBModels->pModelName[v11] + 12 * a6->pVertexIDs[a1a]);
-					  + pOutdoor->pBModels[uModelID].pVertices.pVertices[a6->pVertexIDs[a1a]].x;
-        *(a5a - 1) = a6->pYInterceptDisplacements[v12]
-//                   + *(short *)(*(int *)&pOutdoor->pBModels->pModelName[v11] + 12 * a6->pVertexIDs[v12] + 4);
-					 + pOutdoor->pBModels[uModelID].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[uModelID].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[uModelID].pVertices.pVertices[a6->pVertexIDs[v12 + 1]].y;
-        v14 = a5a;
-        ++a1a;
-        a5a += 2;
-        *v14 = v13;
-      }
-      while ( a1a < a6->uNumVertices );
-    }
-  }
-  else
-  {
-    if ( BYTE1(v10) & 2 )
-    {
-      *v9 = a5->x;
-      *a2 = a5->z;
-      if ( a6->uNumVertices )
-      {
-        v15 = 188 * uModelID + 72;
-        a5b = a4 + 1;
-        do
-        {
-          v16 = a1a;
-          a3[2 * a1a] = a6->pXInterceptDisplacements[a1a]
-//                      + *(short *)(*(int *)&pOutdoor->pBModels->pModelName[v15] + 12 * a6->pVertexIDs[a1a]);
-		  + pOutdoor->pBModels[uModelID].pVertices.pVertices[a6->pVertexIDs[a1a]].x;
-          *(a5b - 1) = a6->pZInterceptDisplacements[v16]
-//                     + *(short *)(*(int *)&pOutdoor->pBModels->pModelName[v15] + 12 * a6->pVertexIDs[v16] + 8);
-		  + pOutdoor->pBModels[uModelID].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[uModelID].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[uModelID].pVertices.pVertices[a6->pVertexIDs[v16+1]].z;
-          v18 = a5b;
-          ++a1a;
-          a5b += 2;
-          *v18 = v17;
-        }
-        while ( a1a < a6->uNumVertices );
-      }
-    }
-    else
-    {
-      *v9 = a5->y;
-      *a2 = a5->z;
-      if ( a6->uNumVertices )
-      {
-        v19 = 188 * uModelID + 72;
-        a5c = a4 + 1;
-        do
-        {
-          v20 = a1a;
-          a3[2 * a1a] = a6->pYInterceptDisplacements[a1a]
-//                      + *(short *)(*(int *)&pOutdoor->pBModels->pModelName[v19] + 12 * a6->pVertexIDs[a1a] + 4);
-		  + pOutdoor->pBModels[uModelID].pVertices.pVertices[a6->pVertexIDs[a1a]].y;
-          *(a5c - 1) = a6->pZInterceptDisplacements[v20]
-//                     + *(short *)(*(int *)&pOutdoor->pBModels->pModelName[v19] + 12 * a6->pVertexIDs[v20] + 8);
-		  + pOutdoor->pBModels[uModelID].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[uModelID].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[uModelID].pVertices.pVertices[a6->pVertexIDs[v20+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 pRotX; // esi@1
-  Vec3_int_ v8; // ST08_12@1
-  int pRotY; // ST04_4@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 outx;
   int outz; // [sp+94h] [bp-Ch]@1
   int outy; // [sp+98h] [bp-8h]@1
 
-  pRotX = pIndoorCamera->sRotationY + UnprojectX((signed __int64)fMouseX);
-  v8.z = pIndoorCamera->pos.z;
-  v8.x = pIndoorCamera->pos.x;
-  v8.y = pIndoorCamera->pos.y;
-  pRotY = pIndoorCamera->sRotationX + UnprojectY((signed __int64)fMouseY);
-  pDepth = _48B561_mess_with_scaling_along_z(/*(int)&fMouseX, */fPickDepth);
-  Vec3_int_::Rotate(pDepth, pRotX, pRotY, v8, &outx, &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 = fixpoint_from_float(fPickDepth);
+  Vec3_int_::Rotate(pDepth, pRotY, pRotX, pStartR, &outx, &outy, &outz);
+
   v11[0].flt_2C = 0.0;
   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)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	Wed May 22 22:22:36 2013 +0600
+++ b/Vis.h	Wed May 22 22:23:04 2013 +0600
@@ -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	Wed May 22 22:22:36 2013 +0600
+++ b/mm7_1.cpp	Wed May 22 22:23:04 2013 +0600
@@ -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();
@@ -997,7 +984,7 @@
 }
 
 //----- (0042213C) --------------------------------------------------------
-void __cdecl OnGameViewportClick()
+void OnGameViewportClick()
 {
   signed int v0; // ebx@2
   POINT *v1; // esi@3
@@ -1099,14 +1086,14 @@
     }
     else
     {
-      if ( PID_TYPE(v0) != OBJECT_BModel || (signed)v0 >= 0x2000000 )
+      if ( PID_TYPE(v0) != OBJECT_BModel || HIWORD(v0) >= 512 )
 	  {
           v4 = pParty->pPickedItem.uItemID;
           if ( !pParty->pPickedItem.uItemID )
             return;
           goto LABEL_14;
 	  }
-      v2 = (signed int)(unsigned __int16)v0 >> 3;
+      v2 = PID_ID(v0);
       if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
       {
         v3 = &pIndoor->pFaces[v2];
@@ -1166,15 +1153,15 @@
 			if (v10 != -1)
 				pIcons_LOD->pTextures[v10].Release();
 			pMouse->RemoveHoldingItem();
-			pIcons_LOD->_40F9C5();
+			pIcons_LOD->SyncLoadedFilesCount();
 			return;
         }
         v11 = pIndoor->pFaceExtras[v3->uFaceExtraID].uEventID;
       }
       else
       {
-        v12 = &pOutdoor->pBModels[(signed int)(unsigned __int16)v0 >> 9].pFaces[v2 & 0x3F];
-        if ( !(v12->uAttributes & 0x2000000) )
+        v12 = &pOutdoor->pBModels[(signed int)(v0 & 0xFFFF) >> 9].pFaces[v2 & 0x3F];
+        if ( !v12->Clickable())
           goto LABEL_11;
         v11 = v12->sCogTriggeredID;
       }
@@ -1201,7 +1188,7 @@
   {
     if ( !v17->GetActorsRelation(0) && !(BYTE2(v17->uAttributes) & 8) )
     {
-      if ( (unsigned int)v0 >= 0x2000000 )
+      if ( HIWORD(v0) >= 512)
 	  {
           v4 = pParty->pPickedItem.uItemID;
           if ( !pParty->pPickedItem.uItemID )
--- a/mm7_2.cpp	Wed May 22 22:22:36 2013 +0600
+++ b/mm7_2.cpp	Wed May 22 22:23:04 2013 +0600
@@ -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();
@@ -6663,7 +6673,7 @@
         pTexture_PCX.Load("lsave640.pcx", 0);
         pGUIWindow2 = GUIWindow::Create(0, 0, 640, 480, WINDOW_MainMenu, 0, 0);
         pCurrentScreen = SCREEN_LOADGAME;
-        GameUI_DrawLoadMenu(0);
+        LoadUI_Load(0);
       }
       pWindow = pGUIWindow_CurrentMenu;
     }
@@ -6876,10 +6886,10 @@
           return 0;
 
         //SubMenu "Time"
-        case 40009:  pParty->uTimePlayed += Day;   return 0;
-        case 40010:  pParty->uTimePlayed += Week;   return 0;
-        case 40011:  pParty->uTimePlayed += Month;   return 0;
-        case 40012:  pParty->uTimePlayed += Year;   return 0;
+        case 40009:  pParty->uTimePlayed += Timer::Day;   return 0;
+        case 40010:  pParty->uTimePlayed += Timer::Week;   return 0;
+        case 40011:  pParty->uTimePlayed += Timer::Month;   return 0;
+        case 40012:  pParty->uTimePlayed += Timer::Year;   return 0;
 
         //SubMenu "Items"
         case 40015:
@@ -7225,7 +7235,7 @@
       }
         return DefWindowProcA(hWnd, Msg, wParam, lParam);
     }
-    if ( dword_506E68 != -1 )
+    if ( uGameMenuUI_CurentlySelectedKeyIdx != -1 )
     {
       pKeyActionMap->_459F10(wParam);
       return DefWindowProcA(hWnd, Msg, wParam, lParam);
@@ -9501,8 +9511,7 @@
         {
          if ( pAudioPlayer->hAILRedbook )
           AIL_redbook_stop(pAudioPlayer->hAILRedbook);
-         extern MENU_STATE __cdecl CreditsMenu__Loop();
-         CreditsMenu__Loop();
+         MainMenuUI_Credits_Loop();
          break;
         }
         if (GetCurrentMenuID() == MENU_5 || GetCurrentMenuID() == MENU_LoadingProcInMainMenu)
@@ -9924,14 +9933,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 +9960,8 @@
 }
 
 //----- (00467FB6) --------------------------------------------------------
-char __cdecl CreateScrollWindow()
-{
+void CreateScrollWindow()
+    {
   unsigned int v0; // eax@1
   char *v1; // ST18_4@3
   unsigned int v2; // eax@3
@@ -9985,7 +9994,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,
@@ -10544,10 +10553,11 @@
   if ( pRenderer->pRenderD3D )
   {
     pGame->PickKeyboard(GetAsyncKeyState(VK_CONTROL) & 0x8001, &vis_sprite_filter_3, &vis_door_filter);
-    v1 = (int *)pGame->pVisInstance->get_picked_object_zbuf_val();
-    if ( v1 != (int *)-1 )
-      DoInteractionWithTopmostZObject((unsigned __int16)v1, (signed int)(unsigned __int16)v1 >> 3);
-  }
+    auto pid = pGame->pVisInstance->get_picked_object_zbuf_val();
+    if ( pid != -1 )
+      DoInteractionWithTopmostZObject(pid & 0xFFFF, PID_ID(pid));
+  }
+
   v22 = 0;
   v1 = (int *)((signed int)(viewparams->uScreen_BttmR_X + viewparams->uScreen_topL_X) >> 1);//wrong pointer
   if ( (signed int)viewparams->uScreen_topL_Y < (signed int)viewparams->uScreen_BttmR_Y )
@@ -10656,7 +10666,7 @@
   BLVFace *v4; // eax@9
   unsigned int v5; // ecx@9
   unsigned __int16 v6; // ax@11
-  ODMFace *v7; // eax@16
+  //ODMFace *v7; // eax@16
   LevelDecoration *v8; // esi@19
   __int16 v9; // ax@19
   int v10; // eax@22
@@ -10782,34 +10792,36 @@
       break;
 
     default:
-      if ( PID_TYPE(a1) != OBJECT_BModel)
-      {
-        MessageBoxW(nullptr, L"Warning: Invalid ID reached!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Mouse.cpp:2020", 0);
-        return 1;
-      }
-      if ( uCurrentlyLoadedLevelType != LEVEL_Indoor )
-      {
-        if ( a1 >> 9 >= pOutdoor->uNumBModels
-          || (v7 = &pOutdoor->pBModels[a1 >> 9].pFaces[(PID_ID(a1)) & 0x3F], BYTE2(v7->uAttributes) & 0x10)
-          || (v6 = v7->sCogTriggeredID) == 0 )
+      MessageBoxW(nullptr, L"Warning: Invalid ID reached!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Mouse.cpp:2020", 0);
+      return 1;
+
+    case OBJECT_BModel:
+      if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor )
+      {
+        int bmodel_id = a1 >> 9,
+            face_id = PID_ID(a1) &0x3F;
+        if (bmodel_id >= pOutdoor->uNumBModels)
+          return 1;
+        auto face = &pOutdoor->pBModels[bmodel_id].pFaces[face_id];
+        if (face->uAttributes & 0x100000 || (v6 = face->sCogTriggeredID) == 0 )
           return 1;
         EventProcessor((signed __int16)v6, v2, 1);
-        return 0;
-      }
-      v4 = &pIndoor->pFaces[PID_ID(a1)];
-      v5 = v4->uAttributes;
-      if ( !(v5 & 0x2000000) )
-      {
-        ShowNothingHereStatus();
-        return 1;
-      }
-      if ( v5 & 0x100000 || (v6 = pIndoor->pFaceExtras[v4->uFaceExtraID].uEventID) == 0 )
-        return 1;
-      if ( pCurrentScreen != SCREEN_BRANCHLESS_NPC_DIALOG )
-	  {
-        EventProcessor((signed __int16)v6, v2, 1);
-        return 0;
-	  }
+      }
+      else
+      {
+        v4 = &pIndoor->pFaces[PID_ID(a1)];
+        v5 = v4->uAttributes;
+        if ( !(v5 & 0x2000000) )
+        {
+          ShowNothingHereStatus();
+          return 1;
+        }
+        if ( v5 & 0x100000 || (v6 = pIndoor->pFaceExtras[v4->uFaceExtraID].uEventID) == 0 )
+          return 1;
+        if ( pCurrentScreen != SCREEN_BRANCHLESS_NPC_DIALOG )
+          EventProcessor((signed __int16)v6, v2, 1);
+      }
+      return 0;
       break;
   }
   return 0;
@@ -11322,7 +11334,7 @@
     else
     {
       pAudioPlayer->StopChannels(-1, -1);
-      UI_CreateTravelDialogue();
+      TravelUI_Load();
     }
   }
   UpdateActors_ODM();
--- a/mm7_3.cpp	Wed May 22 22:22:36 2013 +0600
+++ b/mm7_3.cpp	Wed May 22 22:23:04 2013 +0600
@@ -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);
   }
 }
 
@@ -12039,113 +12041,6 @@
     LoadLevel_InitializeLevelStr();
 }
 
-//----- (004443D5) --------------------------------------------------------
-char *__cdecl _4443D5_GetMinimapRightClickText()
-{
-  int v0; // ST20_4@1
-  unsigned int v1; // esi@1
-  signed int v2; // ebx@1
-  double v3; // st7@1
-  int v4; // esi@3
-  int v5; // edi@4
-  int v6; // eax@4
-  int v7; // eax@4
-  BSPModel *v8; // ecx@4
-  unsigned __int8 v9; // zf@5
-  char v10; // sf@5
-  unsigned __int8 v11; // of@5
-  ODMFace *v12; // eax@6
-  __int16 v13; // cx@6
-  const char *v14; // eax@8
-  const char *v15; // edi@8
-  char *result; // eax@12
-  unsigned int v17; // eax@14
-  unsigned int v18; // [sp+Ch] [bp-20h]@1
-  int v19; // [sp+10h] [bp-1Ch]@1
-  int v20; // [sp+14h] [bp-18h]@1
-  char *v21; // [sp+18h] [bp-14h]@1
-  unsigned int pY; // [sp+1Ch] [bp-10h]@1
-  int v23; // [sp+20h] [bp-Ch]@1
-  int v24; // [sp+24h] [bp-8h]@1
-  int pX; // [sp+28h] [bp-4h]@1
-
-  v24 = pParty->vPosition.x;
-  v0 = pParty->vPosition.y;
-  v1 = pOutdoor->uNumBModels;
-  *(float *)&v23 = (double)(signed int)viewparams->uMinimapZoom * 0.000015258789;
-  v2 = 0;
-  v18 = pOutdoor->uNumBModels;
-  v21 = 0;
-  pMouse->GetClickPos((unsigned int *)&pX, &pY);
-  v3 = 1.0 / *(float *)&v23;
-  v23 = pX - 557;
-  v19 = (signed __int64)((double)(pX - 557) * v3 + (double)v24);
-  v20 = (signed __int64)((double)v0 - (double)(signed int)(pY - 74) * v3);
-  if ( uCurrentlyLoadedLevelType != LEVEL_Outdoor || (*(float *)&v23 = 0.0, (signed int)v1 <= 0) )
-  {
-LABEL_14:
-    v17 = pMapStats->GetMapInfo(pCurrentMapName);
-    if ( v17 == v2 )
-      result = "No Maze Info for this maze on file!";
-    else
-      result = pMapStats->pInfos[v17].pName;
-  }
-  else
-  {
-    v4 = 0;
-    while ( 1 )
-    {
-      pX = pOutdoor->pBModels[v4].vBoundingCenter.x - v19;
-      pY = pOutdoor->pBModels[v4].vBoundingCenter.y - v20;
-      v5 = abs((signed)pY);
-      v6 = abs((signed)pX);
-      v7 = int_get_vector_length(v6, v5, v2);
-      v8 = &pOutdoor->pBModels[0];
-      if ( v7 < 2 * pOutdoor->pBModels[v4].sBoundingRadius )
-      {
-        v11 = __OFSUB__(pOutdoor->pBModels[v4].uNumFaces, v2);
-        v9 = pOutdoor->pBModels[v4].uNumFaces == v2;
-        v10 = ((pOutdoor->pBModels[v4].uNumFaces - v2) & 0x80000000u) != 0;
-        v24 = v2;
-        if ( !((unsigned __int8)(v10 ^ v11) | v9) )
-        {
-          do
-          {
-            v12 = &v8[v4].pFaces[v2 / 0x134u];
-            v13 = v12->sCogTriggeredID;
-            if ( v13 )
-            {
-              if ( !(BYTE2(v12->uAttributes) & 0x10) )
-              {
-                v14 = GetEventHintString(v13);
-                v15 = v14;
-                if ( v14 )
-                {
-                  if ( _strcmpi(v14, "") )
-                    v21 = (char *)v15;
-                }
-              }
-            }
-            ++v24;
-            v8 = pOutdoor->pBModels;
-            v2 += 308;
-          }
-          while ( v24 < (signed int)pOutdoor->pBModels[v4].uNumFaces );
-        }
-        result = v21;
-        v2 = 0;
-        if ( v21 )
-          break;
-      }
-      ++v23;
-      ++v4;
-      if ( v23 >= (signed int)v18 )
-        goto LABEL_14;
-    }
-  }
-  return result;
-}
-
 //----- (00444564) --------------------------------------------------------
 const char *__cdecl sub_444564()
 {
@@ -12230,102 +12125,6 @@
   return result;
 }
 
-//----- (00444A51) --------------------------------------------------------
-void TransitionUI_Draw()
-{
-  MapInfo *pMapInfo; // esi@5
-  char *v1; // eax@6
-  std::string v3; // [sp-18h] [bp-84h]@11
-  unsigned int v4; // [sp-10h] [bp-7Ch]@12
-  int v5; // [sp-Ch] [bp-78h]@12
-  const char *v6; // [sp-8h] [bp-74h]@11
-  signed int v7; // [sp-4h] [bp-70h]@11
-  GUIWindow v8; // [sp+Ch] [bp-60h]@1
-  unsigned int v9; // [sp+60h] [bp-Ch]@1
-  unsigned int v10; // [sp+64h] [bp-8h]@1
-  int a3; // [sp+6Bh] [bp-1h]@11
-
-  memcpy(&v8, pPrimaryWindow, sizeof(v8));
-  v10 = pMapStats->GetMapInfo(pCurrentMapName);
-  v9 = IndoorLocation::GetLocationIndex(dword_591164_teleport_map_name);
-  pRenderer->DrawTextureIndexed(0x1DDu, 0, pTexture_Dialogue_Background);
-  pRenderer->DrawTextureIndexed(pNPCPortraits_x[0][0] - 4, pNPCPortraits_y[0][0] - 4, pIcons_LOD->GetTexture(uTextureID_50795C));
-  pRenderer->DrawTextureIndexed(pNPCPortraits_x[0][0], pNPCPortraits_y[0][0], pTexture_outside);
-  uTextureID_right_panel_loop = uTextureID_right_panel;
-  pRenderer->DrawTextureTransparent(468, 0, pIcons_LOD->GetTexture(uTextureID_right_panel));
-  pRenderer->DrawTextureIndexed(556, 451, pIcons_LOD->GetTexture(uTextureID_x_x_u));
-  pRenderer->DrawTextureIndexed(476, 451, pIcons_LOD->GetTexture(uTextureID_x_ok_u));
-  if ( (pVideoPlayer->AnyMovieLoaded() || v9) && *dword_591164_teleport_map_name != ' ' )
-    v10 = pMapStats->GetMapInfo(dword_591164_teleport_map_name);
-  pMapInfo = &pMapStats->pInfos[v10];
-  v8.uFrameX = 493;
-  v8.uFrameWidth = 126;
-  v8.uFrameZ = 366;
-  v8.DrawTitleText(pFontCreate, 0, 5u, 0, pMapInfo->pName, 3);
-  v8.uFrameX = 483;
-  v8.uFrameWidth = 148;
-  v8.uFrameZ = 334;
-
-  v1 = "";
-  if ( uCurrentHouse_Animation )
-  {
-    v1 = pTransitionStrings[uCurrentHouse_Animation];
-    v4 = (212 - pFontCreate->CalcTextHeight(v1, &v8, 0, 0)) / 2 + 101;
-    v8.DrawTitleText(pFontCreate, 0, v4, 0, v1, 3);
-  }
-  else if ( v10 )
-  {
-    sprintfex(pTmpBuf, pGlobalTXT_LocalizationStrings[409], pMapInfo->pName);// "Do you wish to leave %s?"
-    v4 = (212 - pFontCreate->CalcTextHeight(pTmpBuf, &v8, 0, 0)) / 2 + 101;
-    v8.DrawTitleText(pFontCreate, 0, v4, 0, pTmpBuf, 3);
-  }
-  else assert(false);
-
-  _unused_5B5924_is_travel_ui_drawn = true;
-}
-
-//----- (00444C8F) --------------------------------------------------------
-void UI_CreateTravelDialogue()
-{
-  //signed int v0; // eax@1
-  unsigned int v1; // eax@6
-  GUIWindow *result; // eax@9
-  //const char *v3; // [sp-4h] [bp-2Ch]@2
-  char pContainer[32]; // [sp+0h] [bp-28h]@1
-
-  pEventTimer->Pause();
-  /*v0 = const_2();
-  sprintf(pContainer, "evt%02d", v0);
-  if ( pParty->uAlignment )
-  {
-    if ( pParty->uAlignment != 2 )
-      goto LABEL_6;
-    v3 = "-c";
-  }
-  else
-  {
-    v3 = "-b";
-  }
-  strcat(pContainer, v3);
-LABEL_6:*/
-  switch (pParty->alignment)
-  {
-    case PartyAlignment_Good:    sprintf(pContainer, "evt%02d-b", const_2()); break;
-    case PartyAlignment_Neutral: sprintf(pContainer, "evt%02d", const_2());   break;
-    case PartyAlignment_Evil:    sprintf(pContainer, "evt%02d-c", const_2()); break;
-    default: assert(false);
-  }
-
-  pTexture_Dialogue_Background = pIcons_LOD->LoadTexturePtr(pContainer, TEXTURE_16BIT_PALETTE);
-  pTexture_outside = pIcons_LOD->LoadTexturePtr("outside", TEXTURE_16BIT_PALETTE);
-  v1 = pMapStats->GetMapInfo(pCurrentMapName);
-  if ( v1 )
-    sprintfex(sHouseName, pGlobalTXT_LocalizationStrings[410], pMapStats->pInfos[v1].pName);// "Leave %s"
-  else
-    strcpy(sHouseName, pGlobalTXT_LocalizationStrings[79]);// "Exit"
-  pDialogueWindow = GUIWindow::Create(0, 0, 640, 480, WINDOW_ChangeLocation, 0, (int)sHouseName);
-}
-
 //----- (00444D80) --------------------------------------------------------
 signed int __cdecl GetTravelTime()
 {
@@ -12346,123 +12145,6 @@
 }
 // 6BD07C: using guessed type int uDefaultTravelTime_ByFoot;
 
-//----- (00444DCA) --------------------------------------------------------
-void __cdecl TravelUI_Draw()
-{
-  unsigned int v0; // edi@1
-  MapInfo *v1; // edi@2
-  signed int v3; // eax@2
-  int v4; // eax@5
-  const char *v5; // [sp-Ch] [bp-90h]@3
-  signed int v6; // [sp-8h] [bp-8Ch]@3
-  GUIWindow v7; // [sp+Ch] [bp-78h]@1
-  char pDestinationMapName[32]; // [sp+60h] [bp-24h]@1
-  unsigned int v9; // [sp+80h] [bp-4h]@1
-
-  memcpy(&v7, pPrimaryWindow, sizeof(v7));
-  v9 = pMapStats->GetMapInfo(pCurrentMapName);
-  pOutdoor->GetTravelDestination(pParty->vPosition.x, pParty->vPosition.y, pDestinationMapName, 20);
-  v0 = pMapStats->GetMapInfo(pDestinationMapName);
-  pRenderer->DrawTextureIndexed(0x1DDu, 0, pTexture_Dialogue_Background);
-  pRenderer->DrawTextureTransparent(0x1D4u, 0, &pIcons_LOD->pTextures[uTextureID_right_panel_loop]);
-  pRenderer->DrawTextureIndexed(pNPCPortraits_x[0][0], pNPCPortraits_y[0][0], pTexture_outside);
-  pRenderer->DrawTextureIndexed(0x22Cu, 0x1C3u, pIcons_LOD->GetTexture(uTextureID_x_x_u));
-  pRenderer->DrawTextureIndexed(0x1DCu, 0x1C3u, pIcons_LOD->GetTexture(uTextureID_x_ok_u));
-  if ( v0 )
-  {
-    v1 = &pMapStats->pInfos[v0];
-    v7.uFrameX = 493;
-    v7.uFrameWidth = 126;
-    v7.uFrameZ = 366;
-    v7.DrawTitleText(pFontCreate, 0, 4u, 0, v1->pName, 3);
-    v7.uFrameX = 483;
-    v7.uFrameWidth = 148;
-    v7.uFrameZ = 334;
-    v3 = GetTravelTime();
-    if ( v3 == 1 )
-    {
-      v6 = 1;
-      v5 = pGlobalTXT_LocalizationStrings[663]; // "It will take %d day to cross to %s."
-    }
-    else
-    {
-      v6 = v3;
-      v5 = pGlobalTXT_LocalizationStrings[128]; // "It will take %d days to travel to %s."
-    }
-    sprintfex(pTmpBuf, v5, v6, v1->pName);
-    strcat(pTmpBuf, "\n \n");
-    sprintfex(pTmpBuf2, pGlobalTXT_LocalizationStrings[126], pMapStats->pInfos[v9].pName);
-    strcat(pTmpBuf, pTmpBuf2);
-    v4 = pFontCreate->CalcTextHeight(pTmpBuf, &v7, 0, 0);
-    v7.DrawTitleText(pFontCreate, 0, (212 - v4) / 2 + 101, 0, pTmpBuf, 3u);
-    _unused_5B5924_is_travel_ui_drawn = 1;
-  }
-}
-
-//----- (00444FBE) --------------------------------------------------------
-void __cdecl DrawBranchlessDialogueUI()
-{
-  GUIFont *v0; // esi@1
-  int v1; // esi@4
-  char *v2; // eax@6
-  int v3; // edi@12
-  char Str[200]; // [sp+Ch] [bp-120h]@12
-  GUIWindow v5; // [sp+D4h] [bp-58h]@4
-  GUIFont *pFont; // [sp+128h] [bp-4h]@1
-
-  v0 = pFontArrus;
-  pFont = pFontArrus;
-  if ( current_npc_text && !byte_5B0938[0] )
-    strcpy(byte_5B0938, current_npc_text);
-  v5.uFrameWidth = game_viewport_width;
-  v5.uFrameZ = 452;
-  v1 = pFontArrus->CalcTextHeight(byte_5B0938, &v5, 12, 0) + 7;
-  if ( 352 - v1 < 8 )
-  {
-    pFont = pFontCreate;
-    v1 = pFontCreate->CalcTextHeight(byte_5B0938, &v5, 12, 0) + 7;
-  }
-  pRenderer->_4A6A68(
-    8u,
-    352 - v1,
-    (Texture *)(uTextureID_Leather != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_Leather] : 0),
-    (uTextureID_Leather != -1 ? pIcons_LOD->pTextures[uTextureID_Leather].uTextureHeight : 26) - v1);
-  pRenderer->DrawTextureIndexed(8u, 347 - v1, pTexture_591428);
-  v2 = FitTextInAWindow(byte_5B0938, pFont, &v5, 0xCu, 0);
-  pGUIWindow2->DrawText(pFont, 12, 354 - v1, 0, v2, 0, 0, 0);
-  pRenderer->DrawTextureRGB(0, 0x160u, pTexture_StatusBar);
-  if ( pGUIWindow2->field_40 != 1 )
-  {
-    if ( pGUIWindow2->field_40 == 2 )
-    {
-      pGUIWindow2->field_40 = 0;
-      strcpy(GameUI_Footer_TimedString, (const char *)pKeyActionMap->pPressedKeysBuffer);
-LABEL_16:
-      sub_4452BB();
-      return;
-    }
-    if ( pGUIWindow2->field_40 != 3 )
-      return;
-    pGUIWindow2->field_40 = 0;
-LABEL_15:
-    memset(GameUI_Footer_TimedString, 0, 0xC8u);
-    goto LABEL_16;
-  }
-  if ( pGUIWindow2->ptr_1C == (void *)26 )
-  {
-    sprintf(Str, "%s %s", GameUI_Footer_TimedString, pKeyActionMap->pPressedKeysBuffer);
-    v3 = pFontLucida->GetLineWidth(Str);
-    pGUIWindow2->DrawText(pFontLucida, 13, 357, 0, Str, 0, 0, 0);
-    pGUIWindow2->DrawFlashingInputCursor(v3 + 13, 357, pFontLucida);
-    return;
-  }
-  if ( pKeyActionMap->pPressedKeysBuffer[0] )
-  {
-    pKeyActionMap->_459ED1(0);
-    goto LABEL_15;
-  }
-}
-
 //----- (004451A8) --------------------------------------------------------
 void __fastcall sub_4451A8_press_any_key(int a1, int a2, int a4)
 {
@@ -12522,359 +12204,6 @@
     return pNPCTopics[407].pTopic;
 }
 
-//----- (00445350) --------------------------------------------------------
-void __cdecl DrawDialogueUI()
-{
-  NPCData *pNPC; // ebx@2
-  int pGreetType; // eax@2
-  unsigned __int16 v2; // di@2
-  //unsigned int v3; // eax@2
-  char *v4; // esi@3
-  //int v5; // eax@11
-  //char *v6; // ecx@13
-  //char *v7; // eax@16
-  //unsigned int v8; // edi@19
-  //char *v9; // ecx@27
-  char *v10; // eax@29
-  //int v11; // eax@30
-  int v12; // esi@39
-  char *v13; // eax@41
-  GUIButton *v14; // eax@43
-  //GUIButton *v15; // edi@43
-  signed int v16; // eax@44
-  //unsigned int v23; // eax@53
-  //const char *v24; // eax@59
-  //unsigned __int16 v30; // cx@83
-  int v31; // ecx@86
-  int v32; // ebx@93
-  unsigned int v33; // eax@93
-  GUIWindow *v34; // ecx@93
-  int v35; // esi@93
-  int i; // eax@93
-  GUIButton *v37; // eax@94
-  int v38; // eax@95
-  signed int v39; // esi@99
-  signed int v40; // eax@102
-  unsigned int v41; // ebx@102
-  int v42; // edi@102
-  GUIButton *v43; // esi@103
-  int v44; // eax@104
-  unsigned int v45; // ecx@104
-  unsigned __int16 *v46; // edx@104
-  unsigned __int16 v47; // ax@104
-  GUIWindow pWindow; // [sp+4h] [bp-110h]@39
-  int v49; // [sp+Ch] [bp-108h]@39
-  int v50; // [sp+14h] [bp-100h]@39
-  GUIWindow v51; // [sp+58h] [bp-BCh]@2
-  GUIWindow v52; // [sp+ACh] [bp-68h]@42
-  char *Str; // [sp+100h] [bp-14h]@104
-  //int v54; // [sp+104h] [bp-10h]@2
-  //unsigned __int16 *v55; // [sp+108h] [bp-Ch]@82
-  GUIFont *pOutString; // [sp+10Ch] [bp-8h]@39
-  char *pInString=NULL; // [sp+110h] [bp-4h]@32
-
-  if ( !pDialogueWindow )
-    return;
-  memcpy(&v51, pDialogueWindow, sizeof(v51));
-  pNPC = GetNPCData(sDialogue_SpeakingActorNPC_ID);
-  pGreetType = GetGreetType(sDialogue_SpeakingActorNPC_ID);
-  v51.uFrameWidth -= 10;
-  v51.uFrameZ -= 10;
-  //v54 = v1;
-  TargetColor(0xFFu, 0xFFu, 0xFFu);
-  TargetColor(0xE1u, 0xCDu, 0x23u);
-  v2 = TargetColor(0x15u, 0x99u, 0xE9u);
-  pRenderer->DrawTextureIndexed(477, 0, pTexture_Dialogue_Background);
-  pRenderer->DrawTextureTransparent(468, 0, (Texture *)(uTextureID_right_panel_loop != -1 ? &pIcons_LOD->pTextures[uTextureID_right_panel_loop] : 0));
-  pRenderer->DrawTextureIndexed(pNPCPortraits_x[0][0] - 4, pNPCPortraits_y[0][0] - 4, (Texture *)(uTextureID_50795C != -1 ? &pIcons_LOD->pTextures[uTextureID_50795C] : 0));
-  pRenderer->DrawTextureIndexed(pNPCPortraits_x[0][0], pNPCPortraits_y[0][0], pDialogueNPCPortraits[0]);
-
-  if (pNPC->uProfession)
-  {
-    assert(pNPC->uProfession < sizeof(aNPCProfessionNames) / sizeof(*aNPCProfessionNames)); // sometimes buffer overflows; errors emerge both here and in dialogue text
-    sprintfex(pTmpBuf, pGlobalTXT_LocalizationStrings[429], pNPC->pName, aNPCProfessionNames[pNPC->uProfession]);//^Pi[%s] %s
-  }
-  else
-    strcpy(pTmpBuf, pNPC->pName);
-
-  v51.DrawTitleText(pFontArrus, 483, 112, v2, pTmpBuf, 3);
-  pParty->GetPartyFame();
-
-  pInString = nullptr;
-  switch (uDialogueType)
-  {
-    case DIALOGUE_13:
-      pInString = BuilDialogueString(pNPCStats->pProfessions[pNPC->uProfession - 1].pJoinText, uActiveCharacter - 1, 0, 0, 0, 0);
-    break;
-
-    case DIALOGUE_PROFESSION_DETAILS:
-    {
-      auto prof = pNPCStats->pProfessions + pNPC->uProfession - 1;
-
-      if (dialogue_show_profession_details)
-        pInString = BuilDialogueString(prof->pBenefits, uActiveCharacter - 1, 0, 0, 0, 0);
-      else if (pNPC->Hired())
-        pInString = BuilDialogueString(prof->pDismissText, uActiveCharacter - 1, 0, 0, 0, 0);
-      else
-        pInString = BuilDialogueString(prof->pJoinText, uActiveCharacter - 1, 0, 0, 0, 0);
-    }
-    break;
-
-
-    case DIALOGUE_ARENA_WELCOME:
-      pInString = pGlobalTXT_LocalizationStrings[574]; // "Welcome to the Arena of Life and Death.  Remember, you are only allowed one arena combat per visit.  To fight an arena battle, select the option that best describes your abilities and return to me- if you survive:"
-    break;
-
-    case DIALOGUE_ARENA_FIGHT_NOT_OVER_YET:
-      pInString = pGlobalTXT_LocalizationStrings[577]; //"Get back in there you wimps:"
-    break;
-
-    case DIALOGUE_ARENA_REWARD:
-      sprintfex(pTmpBuf, pGlobalTXT_LocalizationStrings[576], gold_transaction_amount);// "Congratulations on your win: here's your stuff: %u gold."
-      pInString = pTmpBuf;
-    break;
-
-    case DIALOGUE_ARENA_ALREADY_WON:
-      pInString = pGlobalTXT_LocalizationStrings[582]; // "You already won this trip to the Arena:"
-    break;
-
-    default:
-      if (uDialogueType > DIALOGUE_18 && uDialogueType < DIALOGUE_23 && !byte_5B0938[0])
-      {
-        pInString = (char *)current_npc_text;
-      }
-      else if (pGreetType == 1)//QuestNPC_greet
-      {
-        if (pNPC->greet)
-        {
-          if ((pNPC->uFlags & 3) == 2)
-            pInString = pNPCStats->pNPCGreetings[pNPC->greet - 1].pGreeting2;
-          else
-            pInString = pNPCStats->pNPCGreetings[pNPC->greet - 1].pGreeting1;
-        }
-      }
-      else if (pGreetType == 2)//HiredNPC_greet
-      {
-        auto prof = pNPCStats->pProfessions + pNPC->uProfession - 1;
-
-        if (pNPC->Hired())
-          pInString = BuilDialogueString(prof->pDismissText, uActiveCharacter - 1, 0, 0, 0, 0);
-        else
-          pInString = BuilDialogueString(prof->pJoinText, uActiveCharacter - 1, 0, 0, 0, 0);
-      }
-    break;
-  }
-
-  if (pInString)
-  {
-    pWindow.uFrameWidth = game_viewport_width;
-    pWindow.uFrameZ = 452;
-    auto font = pFontArrus;
-    v12 = pFontArrus->CalcTextHeight(pInString, &pWindow, 13, 0) + 7;
-    if ( 352 - v12 < 8 )
-    {
-      font = pFontCreate;
-       v12 = pFontCreate->CalcTextHeight(pInString, &pWindow, 13, 0) + 7;
-    }
-    if (uTextureID_Leather != -1)
-      pRenderer->_4A6A68(8, 352 - v12, &pIcons_LOD->pTextures[uTextureID_Leather], pIcons_LOD->pTextures[uTextureID_Leather].uTextureHeight - v12);
-    pRenderer->DrawTextureIndexed(8u, 347 - v12, pTexture_591428);
-    v13 = FitTextInAWindow(pInString, font,  &pWindow, 0xDu, 0);
-    pDialogueWindow->DrawText(font, 13, 354 - v12, 0, v13, 0, 0, 0);
-  }
-
-
-  memcpy(&v52, pDialogueWindow, sizeof(v52));
-  v52.uFrameX = 483;
-  v52.uFrameWidth = 148;
-  v52.uFrameZ = 334;
-  for (int i = v52.pStartingPosActiveItem;
-       i < v52.pStartingPosActiveItem + v52.pNumPresenceButton; ++i)
-  {
-    v14 = v52.GetControl(i);
-    //v15 = v14;
-    if ( !v14 )
-      break;
-    v16 = v14->msg_param;
-
-    if ( v16 > 88 )
-      v14->pButtonName[0] = 0;
-	else if (v16 == 88)
-      strcpy(v14->pButtonName, pGlobalTXT_LocalizationStrings[581]); // Lord
-    else if (v16 == 87)
-      strcpy(v14->pButtonName, pGlobalTXT_LocalizationStrings[580]); // Knight
-    else if (v16 == 86)
-      strcpy(v14->pButtonName, pGlobalTXT_LocalizationStrings[579]); // Squire
-    else if (v16 == 85)
-      strcpy(v14->pButtonName, pGlobalTXT_LocalizationStrings[578]); // Page
-    else if (v16 == 77)
-      strcpy(v14->pButtonName, pGlobalTXT_LocalizationStrings[407]); // Details
-    else if (v16 == 76)
-    {
-      if (pNPC->Hired())
-        sprintf(v14->pButtonName, (const char*)pGlobalTXT_LocalizationStrings[408], pNPC->pName); // Release %s
-      else
-        strcpy(v14->pButtonName, pGlobalTXT_LocalizationStrings[406]); // Hire
-    }
-	else if (v16 == 24)
-    {
-      __debugbreak(); // learn conditions of this event
-      auto topic = pNPCTopics[pNPC->evt_F - 1].pTopic;//(&dword_721660)[8 * v23];
-      if (!topic)
-      {
-        v14->pButtonName[0] = 0;
-        v14->msg_param = 0;
-      }
-      else
-        strcpy(v14->pButtonName, topic);
-    }
-	else if (v16 == 9)
-      strcpy(v14->pButtonName, GetProfessionActionText(pNPC->uProfession));
-	else if (v16 == 19)
-	{
-     // __debugbreak(); // learn conditions of this event Scavenger Hunt
-      auto topic = pNPCTopics[pNPC->evt_A - 1].pTopic;//(&dword_721660)[8 * v23];
-      if (!topic)
-      {
-        v14->pButtonName[0] = 0;
-        v14->msg_param = 0;
-      }
-      else strcpy(v14->pButtonName, topic);
-	}
-	else if (v16 == 20)
-	{
-      //__debugbreak(); // learn conditions of this event instruments
-      auto topic = pNPCTopics[pNPC->evt_B - 1].pTopic;//(&dword_721660)[8 * v23];
-      if (!topic)
-      {
-        v14->pButtonName[0] = 0;
-        v14->msg_param = 0;
-      }
-      else strcpy(v14->pButtonName, topic);
-	}
-	else if (v16 == 21)
-	{
-      //__debugbreak(); // learn conditions of this event
-      auto topic = pNPCTopics[pNPC->evt_C - 1].pTopic;//(&dword_721660)[8 * v23];
-      if (!topic)
-      {
-        v14->pButtonName[0] = 0;
-        v14->msg_param = 0;
-      }
-      else strcpy(v14->pButtonName, topic);
-	}
-	else if (v16 == 22)
-	{
-      //__debugbreak(); // learn conditions of this event
-      auto topic = pNPCTopics[pNPC->evt_D - 1].pTopic;//(&dword_721660)[8 * v23];
-      if (!topic)
-      {
-        v14->pButtonName[0] = 0;
-        v14->msg_param = 0;
-      }
-      else strcpy(v14->pButtonName, topic);
-	}
-	else if (v16 == 23)
-	{
-      //__debugbreak(); // learn conditions of this event
-      auto topic = pNPCTopics[pNPC->evt_E - 1].pTopic;//(&dword_721660)[8 * v23];
-      if (!topic)
-      {
-        v14->pButtonName[0] = 0;
-        v14->msg_param = 0;
-      }
-      else strcpy(v14->pButtonName, topic);
-	}
-	else if (v16 == 13)
-	{
-      if (pNPC->Hired())
-        sprintf(v14->pButtonName, pGlobalTXT_LocalizationStrings[408], pNPC->pName); // Release %s
-      else
-        strcpy(v14->pButtonName, pGlobalTXT_LocalizationStrings[122]); // Join
-	}
-	else
-      v14->pButtonName[0] = 0;
-	
-
-    if (pParty->field_7B5_in_arena_quest && pParty->field_7B5_in_arena_quest != -1)
-    {
-      int num_dead_actors = 0;
-      pInString = 0;
-      for (uint i = 0; i < uNumActors; ++i)
-      {
-        if (pActors[i].uAIState == Dead || pActors[i].uAIState == Removed ||
-            pActors[i].uAIState  == Disabled)
-          ++num_dead_actors;
-        else
-        {
-          int sumonner_type = PID_TYPE(pActors[i].uSummonerID);
-          if (sumonner_type == OBJECT_Player)
-            ++num_dead_actors;
-        }
-      }
-      if (num_dead_actors == uNumActors)
-        strcpy(v14->pButtonName, pGlobalTXT_LocalizationStrings[658]); // Collect Prize
-    }
-  }
-
-
-  v32 = 0;
-  //pInString = (char *)TargetColor(0xFFu, 0xFFu, 0xFFu);
-  v33 = TargetColor(0xE1u, 0xCDu, 0x23u);
-  v34 = pDialogueWindow;
-  //v54 = v33;
-  v35 = pDialogueWindow->pStartingPosActiveItem;
-  for ( i = v35 + pDialogueWindow->pNumPresenceButton; v35 < i; i = pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem )
-  {
-    v37 = v34->GetControl(v35);
-    if ( !v37 )
-    {
-      v34 = pDialogueWindow;
-      break;
-    }
-    v38 = pFontArrus->CalcTextHeight(v37->pButtonName, &v52, 0, 0);
-    v34 = pDialogueWindow;
-    v32 += v38;
-    ++v35;
-  }
-  v39 = v34->pNumPresenceButton;
-  if ( v39 )
-  {
-    pOutString = (GUIFont *)((174 - v32) / v39);
-    if ( (174 - v32) / v39 > 32 )
-      pOutString = (GUIFont *)32;
-    int v55 = 1;
-    v40 = 174 - (int)pOutString * v39 - v32;
-    v41 = v34->pStartingPosActiveItem;
-    v42 = v40 / 2 - (signed int)pOutString / 2 + 138;
-    if ( (signed int)v41 < (signed int)(v41 + v39) )
-    {
-      do
-      {
-        v43 = v34->GetControl(v41);
-        if ( !v43 )
-          break;
-        v43->uY = (unsigned int)((char *)pOutString + v42);
-        Str = v43->pButtonName;
-        v44 = pFontArrus->CalcTextHeight(v43->pButtonName, &v52, 0, 0);
-        v45 = v43->uY;
-        v46 = (unsigned short *)v55;
-        v43->uHeight = v44;
-        v42 = v45 + v44 - 1;
-        v43->uW = v42;
-        v47 = v33;
-        if ( (unsigned __int16 *)pDialogueWindow->pCurrentPosActiveItem != v46 )
-          v47 = TargetColor(0xFFu, 0xFFu, 0xFFu);
-        v52.DrawTitleText(pFontArrus, 0, v45, v47, Str, 3u);
-        v34 = pDialogueWindow;
-        ++v55;
-        ++v41;
-      }
-      while ( (signed int)v41 < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem );
-    }
-  }
-  pRenderer->DrawTextureIndexed(471, 445, pIcons_LOD->GetTexture(uExitCancelTextureId));
-}
 
 //----- (00445C8B) --------------------------------------------------------
 int __fastcall GetGreetType(signed int SpeakingNPC_ID)
@@ -14427,13 +13756,8 @@
     _5B65A8_npcdata_uflags_or_other = 0;
   }
 }
-// 5B65A8: using guessed type int _5B65A8_npcdata_uflags_or_other;
-// 5B65AC: using guessed type int _5B65AC_npcdata_fame_or_other;
-// 5B65B0: using guessed type int _5B65B0_npcdata_rep_or_other;
-// 5B65B4: using guessed type int _5B65B4_npcdata_loword_house_or_other;
-// 5B65B8: using guessed type int _5B65B8_npcdata_hiword_house_or_other;
-// 5B65BC: using guessed type int dword_5B65BC;
-// 5B65C0: using guessed type int dword_5B65C0;
+
+
 
 //----- (00449A49) --------------------------------------------------------
 __int16 __fastcall sub_449A49_door_switch_animation(unsigned int uDoorID, int a2)
@@ -14530,7 +13854,7 @@
 
 //----- (00449B57) --------------------------------------------------------
 bool _449B57_test_bit( unsigned __int8 *a1, __int16 a2 )
-    {
+{
   return a1[(a2 - 1) >> 3] & (0x80u >> (a2 - 1) % 8);
 }
 
@@ -14548,23 +13872,6 @@
     pArray[v3 / 8] &= ~set_bit;
 }
 
-//----- (0044A56A) --------------------------------------------------------
-void __cdecl Party__CountHirelings()
-{
-  pParty->field_70A = 0;
-
-  for (int i = 0; i < pNPCStats->uNumNewNPCs; ++i)
-  {
-    auto npc = pNPCStats->pNewNPCData + i;
-    if (npc->Hired() &&
-        (!pParty->pHirelings[0].pName || strcmp(npc->pName, pParty->pHirelings[0].pName)))
-    {
-      if (!pParty->pHirelings[1].pName || strcmp(npc->pName, pParty->pHirelings[1].pName))
-        ++pParty->field_70A;
-    }
-  }
-}
-
 //----- (0044C175) --------------------------------------------------------
 void __fastcall ShowStatusBarString(const char *pString, unsigned int uNumSeconds)
 {
@@ -14581,7 +13888,7 @@
 }
 
 //----- (0044C1D0) --------------------------------------------------------
-void __cdecl ShowNothingHereStatus()
+void ShowNothingHereStatus()
 {
   if ( !GameUI_Footer_TimeLeft )
     ShowStatusBarString(pGlobalTXT_LocalizationStrings[521], 2u);// Nothing here
@@ -14619,26 +13926,33 @@
 //----- (0044C2F4) --------------------------------------------------------
 int LevelDecoration::IsInteractive()
 {
-  signed int v1; // eax@1
-
-  v1 = this->uDecorationDescID;
-  if ( v1 > 34 )
-  {
-    if ( v1 == 184 || v1 == 187 || v1 == 190 || v1 > 205 && v1 <= 221 )
-      return 1;
-  }
-  else
-  {
-    if ( v1 == 34 || v1 >= 4 && (v1 <= 6 || v1 == 11 || v1 > 12 && (v1 <= 14 || v1 == 24)) )
-      return 1;
-  }
-  return 0;
+  switch (uDecorationDescID)
+  {
+    case 4:    // trash pile
+    case 5:    // campfire
+    case 6:    // cauldron
+    case 11:   // fruit plate
+    case 13:   // trash pile
+    case 14:   // dirt
+    case 24:   // keg
+    case 184:  // fire
+    case 187:  // fire
+    case 190:  // fire
+      return true;
+  }
+
+  if (uDecorationDescID >= 206 && uDecorationDescID <= 209) // lighthouse fire
+    return true;
+  if (uDecorationDescID >= 210 && uDecorationDescID <= 221) // magic pedistal
+    return true;
+
+  return false;
 }
 
 //----- (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 +13967,8 @@
   float v13; // ST14_4@1
   double v14; // ST0C_8@1
 
-  v1 = this;
+  assert(false);
+  //v1 = this;
   v2 = (double)this->x * 0.000015258789;
   v3 = v2;
   v4 = (double)this->y * 0.000015258789;
@@ -14663,13 +13978,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	Wed May 22 22:22:36 2013 +0600
+++ b/mm7_4.cpp	Wed May 22 22:23:04 2013 +0600
@@ -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"
@@ -1533,80 +1523,6 @@
   
   for (int i = 0; i < 12; ++i)
     v2->pMemBlocks[i] = new stru12_MemoryBlock(640);
-  /*
-  v3 = (stru12_MemoryBlock *)operator new(8u);
-  if ( v3 )
-    v4 = AllocAlignedMem(v3, 640);
-  else
-    v4 = 0;
-  v2->pMemBlocks[0] = v4;
-  /*v5 = (stru12_MemoryBlock *)operator new(8u);
-  if ( v5 )
-    v6 = AllocAlignedMem(v5, 640);
-  else
-    v6 = 0;
-  v2->pMemBlocks[1] = v6;
-  v7 = (stru12_MemoryBlock *)operator new(8u);
-  if ( v7 )
-    v8 = AllocAlignedMem(v7, 640);
-  else
-    v8 = 0;
-  v2->pMemBlocks[2] = v8;
-  v9 = (stru12_MemoryBlock *)operator new(8u);
-  if ( v9 )
-    v10 = AllocAlignedMem(v9, 640);
-  else
-    v10 = 0;
-  v2->pMemBlocks[3] = v10;
-  v11 = (stru12_MemoryBlock *)operator new(8u);
-  if ( v11 )
-    v12 = AllocAlignedMem(v11, 640);
-  else
-    v12 = 0;
-  v2->pMemBlocks[4] = v12;
-  v13 = (stru12_MemoryBlock *)operator new(8u);
-  if ( v13 )
-    v14 = AllocAlignedMem(v13, 640);
-  else
-    v14 = 0;
-  v2->pMemBlocks[5] = v14;
-  v15 = (stru12_MemoryBlock *)operator new(8u);
-  if ( v15 )
-    v16 = AllocAlignedMem(v15, 640);
-  else
-    v16 = 0;
-  v2->pMemBlocks[6] = v16;
-  v17 = (stru12_MemoryBlock *)operator new(8u);
-  if ( v17 )
-    v18 = AllocAlignedMem(v17, 640);
-  else
-    v18 = 0;
-  v2->pMemBlocks[7] = v18;
-  v19 = (stru12_MemoryBlock *)operator new(8u);
-  if ( v19 )
-    v20 = AllocAlignedMem(v19, 640);
-  else
-    v20 = 0;
-  v2->pMemBlocks[8] = v20;
-  v21 = (stru12_MemoryBlock *)operator new(8u);
-  if ( v21 )
-    v22 = AllocAlignedMem(v21, 640);
-  else
-    v22 = 0;
-  v2->pMemBlocks[9] = v22;
-  v23 = (stru12_MemoryBlock *)operator new(8u);
-  if ( v23 )
-    v24 = AllocAlignedMem(v23, 640);
-  else
-    v24 = 0;
-  v2->pMemBlocks[10] = v24;
-  v25 = (stru12_MemoryBlock *)operator new(8u);
-  if ( v25 )
-    v26 = AllocAlignedMem(v25, 640);
-  else
-    v26 = 0;
-  v2->field_8C = 0;
-  v2->pMemBlocks[11] = v26;*/
 }
 
 //----- (00489810) --------------------------------------------------------
@@ -1614,41 +1530,6 @@
 {
   for (int i = 0; i < 12; ++i)
     delete pMemBlocks[i];
-  /*if ( v2 )
-    stru12_MemoryBlock::dtor(v2, 1);
-  v3 = v1->pMemBlocks[1];
-  if ( v3 )
-    stru12_MemoryBlock::dtor(v3, 1);
-  v4 = v1->pMemBlocks[2];
-  if ( v4 )
-    stru12_MemoryBlock::dtor(v4, 1);
-  v5 = v1->pMemBlocks[3];
-  if ( v5 )
-    stru12_MemoryBlock::dtor(v5, 1);
-  v6 = v1->pMemBlocks[4];
-  if ( v6 )
-    stru12_MemoryBlock::dtor(v6, 1);
-  v7 = v1->pMemBlocks[5];
-  if ( v7 )
-    stru12_MemoryBlock::dtor(v7, 1);
-  v8 = v1->pMemBlocks[6];
-  if ( v8 )
-    stru12_MemoryBlock::dtor(v8, 1);
-  v9 = v1->pMemBlocks[7];
-  if ( v9 )
-    stru12_MemoryBlock::dtor(v9, 1);
-  v10 = v1->pMemBlocks[8];
-  if ( v10 )
-    stru12_MemoryBlock::dtor(v10, 1);
-  v11 = v1->pMemBlocks[9];
-  if ( v11 )
-    stru12_MemoryBlock::dtor(v11, 1);
-  v12 = v1->pMemBlocks[10];
-  if ( v12 )
-    stru12_MemoryBlock::dtor(v12, 1);
-  v13 = v1->pMemBlocks[11];
-  if ( v13 )
-    stru12_MemoryBlock::dtor(v13, 1);*/
 }
 
 //----- (004898BF) --------------------------------------------------------
@@ -1797,16 +1678,12 @@
 }
 
 //----- (0048B561) --------------------------------------------------------
-int _48B561_mess_with_scaling_along_z(/*int a1, */float a2)
+int fixpoint_from_float(float val)
 {
-  //v2 = a2 - 0.5;
-  //v3 = v2 + 6.7553994e15;
-  int v4 = floorf(a2 - 0.5f + 0.5f);
-  //v7 = (a2 - (double)SLODWORD(v3)) * 65536.0;
-  //v5 = v7 + 6.7553994e15;
-  //return LODWORD(v5) | (v4 << 16);
-  int v5 = floorf((a2 - v4) * 65536.0f + 0.5f);
-  return v5 | (v4 << 16);
+  //  float X.Yf -> int XXXX YYYY
+  int left = floorf((val - 0.5f) + 0.5f);
+  int right = floorf((val - left) * 65536.0f);
+  return (left << 16) | right;
 }
 
 //----- (00491E3A) --------------------------------------------------------
@@ -2368,7 +2245,7 @@
 }
 
 //----- (00494035) --------------------------------------------------------
-void __cdecl _494035_timed_effects__water_walking_damage__etc()
+void _494035_timed_effects__water_walking_damage__etc()
 {
   signed __int64 v0; // qax@1
   signed __int64 v1; // ST30_8@1
@@ -6803,7 +6680,7 @@
   //LOBYTE(v2->uFlags) |= 0x80u;
   pCurrentNPCInfo->uFlags |= 128;
   pParty->field_709 = 0;
-  Party__CountHirelings();
+  pParty->CountHirelings();
   if ( pParty->pHirelings[0].pName )
   {
     memcpy(&pParty->pHirelings[1], pCurrentNPCInfo, sizeof(pParty->pHirelings[1]));
@@ -6818,7 +6695,7 @@
   }
   strcpy(v22, v24);
   pParty->field_709 = 0;
-  Party__CountHirelings();
+  pParty->CountHirelings();
   PrepareHouse((HOUSE_ID)(int)window_SpeakInHouse->ptr_1C);
   dialog_menu_id = HOUSE_DIALOGUE_MAIN;
 
@@ -7411,8 +7288,8 @@
           v30 = TargetColor(0xFFu, 0xFFu, 0xFFu);
           v31 = *(int *)v29;
           v32 = TargetColor(0xFFu, 0xFFu, 0x9Bu);
-          sprintf(pTmpBuf, &byte_4F0F98, v32, v31, v30);
-          sprintf(pTmpBuf2, dword_F8B1A4, pTmpBuf, 100 * (unsigned __int8)v29[8]);
+          sprintfex(pTmpBuf, "\f%05d%s\f%05d", v32, v31, v30);
+          sprintfex(pTmpBuf2, dword_F8B1A4, pTmpBuf, 100 * (unsigned __int8)v29[8]);
           current_npc_text = pTmpBuf2;
           v15 = "";
           goto LABEL_45;
@@ -8020,12 +7897,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) --------------------------------------------------------
@@ -8102,7 +7979,7 @@
 				memset(v11, 0, sizeof(NPCData));
 			}
 			pParty->field_709 = 0;
-			Party__CountHirelings();
+			pParty->CountHirelings();
 			dword_591084 = 0;
 			pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
 			dword_7241C8 = 0;
@@ -8150,7 +8027,7 @@
 			}
 			strcpy(v13, v15);
 			pParty->field_709 = 0;
-			Party__CountHirelings();
+			pParty->CountHirelings();
 
 			pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
 
@@ -8213,7 +8090,7 @@
 				memset(v11, 0, sizeof(NPCData));
 			}
 			pParty->field_709 = 0;
-			Party__CountHirelings();
+			pParty->CountHirelings();
 			dword_591084 = 0;
 			pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
 			dword_7241C8 = 0;
@@ -9083,107 +8960,3 @@
  
   return result;
 }
-
-//----- (00444839) --------------------------------------------------------
-unsigned int __fastcall sub_444839_move_map(unsigned int a1, int a2, int x, int y, int z, int directiony, int directionx, int a8, const char *pLocationName)
-{
-  unsigned int v9; // ebx@1
-  int v10; // edi@1
-  //signed int v11; // eax@1
-  unsigned int v12; // eax@6
-  const char *v13; // ST0C_4@6
-  unsigned int v14; // eax@8
-  const char *v15; // eax@14
-  unsigned int v16; // eax@16
-  unsigned int result; // eax@26
-  const char *v18; // [sp-8h] [bp-40h]@9
-  //const char *v19; // [sp-4h] [bp-3Ch]@2
-  char *v20; // [sp-4h] [bp-3Ch]@9
-  const char *v21; // [sp-4h] [bp-3Ch]@11
-  char pContainer[40]; // [sp+Ch] [bp-2Ch]@1
-  unsigned int v23; // [sp+34h] [bp-4h]@1
-
-  v9 = a1;
-  v10 = a2;
-  v23 = IndoorLocation::GetLocationIndex(pLocationName);
-  dword_59117C_teleportx = x;
-  dword_591178_teleporty = y;
-  dword_591174_teleportz = z;
-  dword_591170_teleport_directiony = directiony;
-  dword_59116C_teleport_directionx = directionx;
-  dword_591168_teleport_speedz = a8;
-  dword_591164_teleport_map_name = (char *)pLocationName;
-  uCurrentHouse_Animation = v9;
-  pEventTimer->Pause();
-  pAudioPlayer->StopChannels(-1, -1);
-
-  switch (pParty->alignment)
-  {
-    case PartyAlignment_Good:    sprintf(pContainer, "evt%02d-b", const_2()); break;
-    case PartyAlignment_Neutral: sprintf(pContainer, "evt%02d", const_2()); break;
-    case PartyAlignment_Evil:    sprintf(pContainer, "evt%02d-c", const_2()); break;
-    default: assert(false);
-  }
-  /*v11 = const_2();
-  sprintf(pContainer, "evt%02d", v11);
-  if ( pParty->uAlignment )
-  {
-    if ( pParty->uAlignment != 2 )
-      goto LABEL_6;
-    v19 = "-c";
-  }
-  else
-  {
-    v19 = "-b";
-  }
-  strcat(pContainer, v19);*/
-
-//LABEL_6:
-  v12 = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
-  v13 = pHouse_ExitPictures[v10];
-  pTexture_Dialogue_Background = &pIcons_LOD->pTextures[v12];
-  pTexture_outside = pIcons_LOD->LoadTexturePtr(v13, TEXTURE_16BIT_PALETTE);
-  if ( v9 )
-  {
-    if ( !v23 )
-      //pVideoPlayer->OpenHouseMovie(pAnimatedRooms[p2DEvents_minus1___02[26 * v9]].field_0, 1u);
-      pVideoPlayer->OpenHouseMovie(pAnimatedRooms[p2DEvents[v9 - 1].uAnimationID].video_name, 1u);
-  }
-  else
-  {
-    if ( !v23 )
-    {
-      v14 = pMapStats->GetMapInfo(pCurrentMapName);
-      if ( v14 )
-      {
-        sprintfex(sHouseName, pGlobalTXT_LocalizationStrings[410], pMapStats->pInfos[v14].pName);
-        goto LABEL_20;
-      }
-      v21 = pGlobalTXT_LocalizationStrings[79];
-      goto LABEL_19;
-    }
-  }
-  v15 = pLocationName;
-  if ( *pLocationName == 48 )
-    v15 = pCurrentMapName;
-  v16 = pMapStats->GetMapInfo(v15);
-  if ( v16 )
-  {
-    sprintfex(sHouseName, pGlobalTXT_LocalizationStrings[411], pMapStats->pInfos[v16].pName);
-    goto LABEL_20;
-  }
-  v21 = pGlobalTXT_LocalizationStrings[73];
-LABEL_19:
-  strcpy(sHouseName, v21);
-LABEL_20:
-  pDialogueWindow = GUIWindow::Create(0, 0, 640, 480, WINDOW_Transition, 0, (int)sHouseName);
-  //if ( BYTE1(pAnimatedRooms[p2DEvents_minus1___02[26 * v9]].field_C) )
-  if ( pAnimatedRooms[p2DEvents[v9 - 1].uAnimationID].uRoomSoundId )
-    PlayHouseSound(v9, HouseSound_Greeting);
-  if ( uCurrentlyLoadedLevelType == LEVEL_Indoor && uActiveCharacter && pParty->uFlags & 0x30 )
-    pPlayers[uActiveCharacter]->PlaySound(SPEECH_47, 0);
-  result = v23;
-  if ( v23 )
-    uCurrentHouse_Animation = v23;
-  return result;
-}
--- a/mm7_5.cpp	Wed May 22 22:22:36 2013 +0600
+++ b/mm7_5.cpp	Wed May 22 22:23:04 2013 +0600
@@ -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
@@ -275,13 +275,12 @@
     memset(&actor, 0, 0x344u);
     dword_5B65D0_dialogue_actor_npc_id = bDialogueUI_InitializeActor_NPC_ID;
     actor.sNPC_ID = bDialogueUI_InitializeActor_NPC_ID;
-    actor.InitializeDialogue(0);
+    GameUI_InitializeDialogue(&actor, false);
     bDialogueUI_InitializeActor_NPC_ID = 0;
   }
   if ( pMessageQueue_50CBD0->uNumMessages )
   {
-    //v0 = 1;
-    v1 = "";
+    //v1 = "";
     while ( 2 )
     {
       if ( !pMessageQueue_50CBD0->uNumMessages )
@@ -307,7 +306,7 @@
           dword_5B65D0_dialogue_actor_npc_id = pActors[uMessageParam].sNPC_ID;
           pActor = &pActors[uMessageParam];
           //goto _actor_init_dlg;
-          pActor->InitializeDialogue(1);
+          GameUI_InitializeDialogue(pActor, true);
           continue;
         case UIMSG_StartHireling1Dialogue:
         case UIMSG_StartHireling2Dialogue:
@@ -360,7 +359,7 @@
               memset(&actor, 0, 0x344u);
               actor.sNPC_ID += -1 - (unsigned __int8)pParty->field_709 - hireling_idx;
               pActor = &actor;
-              pActor->InitializeDialogue(1);
+              GameUI_InitializeDialogue(&actor, true);
             }
           }
           continue;
@@ -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,18 +400,18 @@
           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;
           pGUIWindow_CurrentMenu->Release();
           pCurrentScreen = SCREEN_LOADGAME;
-          GameUI_DrawLoadMenu(1);
+          LoadUI_Load(1);
           continue;
         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;
@@ -516,7 +515,7 @@
         case UIMSG_Game_OpenSaveGameDialog:
           pGUIWindow_CurrentMenu->Release();
           pCurrentScreen = SCREEN_SAVEGAME;
-          GameUI_DrawSaveMenu();
+          SaveUI_Load();
           continue;
         case UIMSG_Game_OpenOptionsDialog://Open
           if ( pMessageQueue_50CBD0->uNumMessages )
@@ -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
@@ -625,16 +624,16 @@
           pGUIWindow_CurrentMenu->CreateButton(350u, 224u, 70u, 0x13u, 1, 0, UIMSG_ChangeKeyButton, 0xBu, 0, "", 0);
           pGUIWindow_CurrentMenu->CreateButton(350u, 243u, 70u, 0x13u, 1, 0, UIMSG_ChangeKeyButton, 0xCu, 0, "", 0);
           pGUIWindow_CurrentMenu->CreateButton(350u, 262u, 70u, 0x13u, 1, 0, UIMSG_ChangeKeyButton, 0xDu, 0, "", 0);
-          dword_506E68 = -1;
+          uGameMenuUI_CurentlySelectedKeyIdx = -1;
           KeyboardPageNum = 1;
-          memset(KeyButtonFlagChangesArray, 0, sizeof(KeyButtonFlagChangesArray));
+          memset(GameMenuUI_InvaligKeyBindingsFlags, 0, sizeof(GameMenuUI_InvaligKeyBindingsFlags));
           //*(_WORD *)KeyButtonArray[28] = 0;
           memcpy(pPrevVirtualCidesMapping, pKeyActionMap->pVirtualKeyCodesMapping, 0x78u);
-          v1 = "";
+          //v1 = "";
           //v0 = 1;
           continue;
         case UIMSG_ChangeKeyButton:
-          if ( dword_506E68 != -1 )
+          if ( uGameMenuUI_CurentlySelectedKeyIdx != -1 )
           {
             pAudioPlayer->PlaySound((SoundID)27, 0, 0, -1, 0, 0, 0, 0);
             continue;
@@ -642,7 +641,7 @@
           v14 = uMessageParam;
           if ( KeyboardPageNum != 1 )
             v14 = uMessageParam + 14;
-          dword_506E68 = v14;
+          uGameMenuUI_CurentlySelectedKeyIdx = v14;
           pKeyActionMap->EnterText(0, 1, pGUIWindow_CurrentMenu);
           continue;
         case UIMSG_ResetKeyMapping:
@@ -670,7 +669,7 @@
             v18 = uAction++;
             v13 = uAction > 28;
             v12 = uAction - 28 < 0;
-            KeyButtonFlagChangesArray[v18] = 0;
+            GameMenuUI_InvaligKeyBindingsFlags[v18] = 0;
           }
           while ( v12 ^ v13 );
           pAudioPlayer->PlaySound((SoundID)219, 0, 0, -1, 0, 0, 0, 0);
@@ -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;
@@ -1200,24 +1199,27 @@
                       WriteWindowsRegistryInt("GammaPos", uGammaPos);
                       stru_506E40.Release();
                       break;
+
                     case SCREEN_KEYBOARD_OPTIONS://Return to game
                       v197 = 1;
                       v32 = 0;
-                      while ( KeyButtonFlagChangesArray[v32] != 1 )
+                      while ( !GameMenuUI_InvaligKeyBindingsFlags[v32])
                       {
                         ++v32;
                         if ( v32 >= 28 )
                         {
                           thisb = (signed int)&uTextureID_Optkb;
+                          assert(false && "Invalid condition values");
                           do
                           {
                             if ( *(int *)thisb )
                               pIcons_LOD->pTextures[*(int *)thisb].Release();
                             thisb += 4;
                           }
-                          while ( thisb < (signed int)&dword_507C08 );
+                          while ( thisb < (signed int)0x00507C08 );
+
                           memset(&uTextureID_Optkb, 0, 0x14u);
-                          pIcons_LOD->_40F9C5();
+                          pIcons_LOD->SyncLoadedFilesCount();
                           uAction = 0;
                           do
                           {
@@ -1263,7 +1265,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;
@@ -1342,7 +1344,7 @@
                       pGUIWindow_CurrentMenu = 0;
                       pEventTimer->Resume();
                       pCurrentScreen = SCREEN_GAME;
-                      viewparams->bRedrawGameUI = 1;
+                      viewparams->bRedrawGameUI = true;
                       pIcons_LOD->_4355F7();
                       continue;
                     case SCREEN_INPUT_BLV://click escape
@@ -1353,34 +1355,34 @@
                       {
                         pParty->field_709 = 0;
                         LOBYTE(pNPCStats->pNewNPCData[dword_5B65CC].uFlags) &= 0x7Fu;
-                        Party__CountHirelings();
-                        viewparams->bRedrawGameUI = 1;
+                        pParty->CountHirelings();
+                        viewparams->bRedrawGameUI = true;
                         dword_5B65CC = 0;
                       }
                       DialogueEnding();
                       pCurrentScreen = SCREEN_GAME;
-                      viewparams->bRedrawGameUI = 1;
+                      viewparams->bRedrawGameUI = true;
                       continue;
                     case SCREEN_NPC_DIALOGUE://click escape
                       if ( dword_5B65CC )
                       {
                         pParty->field_709 = 0;
                         LOBYTE(pNPCStats->pNewNPCData[dword_5B65CC].uFlags) &= 0x7Fu;
-                        Party__CountHirelings();
-                        viewparams->bRedrawGameUI = 1;
+                        pParty->CountHirelings();
+                        viewparams->bRedrawGameUI = true;
                         dword_5B65CC = 0;
                       }
                       //goto LABEL_317;
                       DialogueEnding();
                       pCurrentScreen = SCREEN_GAME;
-                      viewparams->bRedrawGameUI = 1;
+                      viewparams->bRedrawGameUI = true;
                       continue;
                     case SCREEN_BRANCHLESS_NPC_DIALOG://click escape
                       memset(GameUI_Footer_TimedString, 0, 0xC8u);
                       sub_4452BB();
                       DialogueEnding();
                       pCurrentScreen = SCREEN_GAME;
-                      viewparams->bRedrawGameUI = 1;
+                      viewparams->bRedrawGameUI = true;
                       continue;
                     case SCREEN_CHANGE_LOCATION://click escape
                       if ( pParty->vPosition.x < -22528 )
@@ -1393,7 +1395,7 @@
                         pParty->vPosition.y = 22528;
                       DialogueEnding();
                       pCurrentScreen = SCREEN_GAME;
-                      viewparams->bRedrawGameUI = 1;
+                      viewparams->bRedrawGameUI = true;
                       continue;
                     case SCREEN_VIDEO:
                       pVideoPlayer->Unload();
@@ -1426,7 +1428,7 @@
                       pGUIWindow_CurrentMenu = 0;
                       pEventTimer->Resume();
                       pCurrentScreen = SCREEN_GAME;
-                      viewparams->bRedrawGameUI = 1;
+                      viewparams->bRedrawGameUI = true;
                       pIcons_LOD->_4355F7();
                       continue;
                     default:
@@ -1482,7 +1484,7 @@
                   pGUIWindow_CurrentMenu = 0;
                   pEventTimer->Resume();
                   pCurrentScreen = SCREEN_GAME;
-                  viewparams->bRedrawGameUI = 1;
+                  viewparams->bRedrawGameUI = true;
                   pIcons_LOD->_4355F7();
                   continue;
                 }
@@ -1514,7 +1516,7 @@
               pGUIWindow_CurrentMenu = 0;
               pEventTimer->Resume();
               pCurrentScreen = SCREEN_GAME;
-              viewparams->bRedrawGameUI = 1;
+              viewparams->bRedrawGameUI = true;
               pIcons_LOD->_4355F7();
               continue;
             }
@@ -1524,10 +1526,12 @@
               GUIWindow::Create(0x25Au, 0x1C2u, 0, 0, WINDOW_PressedButton2, (int)pBtn_GameSettings, 1);
               pEventTimer->Pause();
               pAudioPlayer->StopChannels(-1, -1);
+              pCurrentScreen = SCREEN_MENU;
+              
               ++pIcons_LOD->uTexturePacksCount;
-              pCurrentScreen = 1;
               if ( !pIcons_LOD->uNumPrevLoadedFiles )
                 pIcons_LOD->uNumPrevLoadedFiles = pIcons_LOD->uNumLoadedFiles;
+
               pGUIWindow_CurrentMenu = GUIWindow::Create(0, 0, 640, 480, WINDOW_OptionsButtons, 0, 0);
               uTextureID_Options = pIcons_LOD->LoadTexture("options", TEXTURE_16BIT_PALETTE);
               uTextureID_New1 = pIcons_LOD->LoadTexture("new1", TEXTURE_16BIT_PALETTE);
@@ -1663,12 +1667,12 @@
           pVideoPlayer->Unload();
           DialogueEnding();
           start_event_seq_number = 0;
-          viewparams->bRedrawGameUI = 1;
+          viewparams->bRedrawGameUI = true;
           continue;
         case UIMSG_CycleCharacters:
           v39 = GetAsyncKeyState(VK_SHIFT);
           uActiveCharacter = CycleCharacter(v39);
-          viewparams->bRedrawGameUI = 1;
+          viewparams->bRedrawGameUI = true;
           continue;
         case UIMSG_OnTravelByFoot:
           if ( pMessageQueue_50CBD0->uNumMessages )
@@ -2295,10 +2299,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 +2320,6 @@
                 dword_6BE364_game_settings_1 |= 1u;
                 uGameState = GAME_STATE_2;
                 OnMapLeave();
-                v1 = "";
                 continue;
               }
             }
@@ -2329,10 +2329,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 +2343,6 @@
                 pParty->vPosition.y = v77;
                 pParty->vPosition.z = v76;
                 pParty->uFallStartY = v76;
-                v1 = "";
                 continue;
               }
             }
@@ -2365,7 +2361,6 @@
                       pParty->vPosition.y = v77;
                       pParty->vPosition.z = v76;
                       pParty->uFallStartY = v76;
-                      v1 = "";
                       continue;
                     }
                   }
@@ -2376,7 +2371,6 @@
             v73 = "Can't jump to that location!";
           }
           ShowStatusBarString(v73, 6u);
-          v1 = "";
           continue;
         case UIMSG_CastQuickSpell:
           if ( bUnderwater == 1 )
@@ -2386,10 +2380,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 +2399,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 +2425,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 +2433,7 @@
         case UIMSG_1B:
 			__debugbreak();
           if ( !uActiveCharacter )
-          {
-            v1 = "";
             continue;
-          }
           if ( pParty->bTurnBasedModeOn != 1 )
           {
             if ( pActors[uMessageParam].uAIState == 5 )
@@ -2461,10 +2443,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 +2455,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;
@@ -2522,7 +2495,7 @@
           continue;
         case UIMSG_RentRoom:
           dword_506F14 = 2;
-          RestUI_Initialize();
+          RestUI_Load();
           v86 = 60 * (_494820_training_time(pParty->uCurrentHour) + 1) - pParty->uCurrentMinute;
           _506F18_num_hours_to_sleep = v86;
           if ( uMessageParam == 111 || uMessageParam == 114 || uMessageParam == 116 )
@@ -2552,10 +2525,7 @@
               v88 = pGlobalTXT_LocalizationStrings[479];// "You can't rest here!"
             ShowStatusBarString(v88, 2);
             if ( !uActiveCharacter )
-            {
-              v1 = "";
               continue;
-            }
             pPlayers[uActiveCharacter]->PlaySound((PlayerSpeech)13, 0);
             continue;
           }
@@ -2566,7 +2536,7 @@
           }
           if ( !(pParty->uFlags & 0x88) )
           {
-            RestUI_Initialize();
+            RestUI_Load();
             continue;
           }
           if ( pParty->bTurnBasedModeOn == 1 )
@@ -2579,10 +2549,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 +2770,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 +2787,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 +2911,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 +3229,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 +3367,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 +3385,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 +3637,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) --------------------------------------------------------
@@ -5393,22 +5359,26 @@
 //----- (0043AA99) --------------------------------------------------------
 void __fastcall Vec3_int_::Rotate(int sDepth, int sRotY, int sRotX, Vec3_int_ v, int *outx, int *outy, int *outz)
 {
+/*  int v7; // ebx@1
+  int v8; // ST14_4@1
+  int v9; // edi@1
   int anglea; // [sp+20h] [bp+8h]@1
 
-/*  anglea = (unsigned __int64)(stru_5C6E00->SinCos(sRotX) * (signed __int64)sDepth) >> 16;
+  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(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);
-
- sDepth = 14000000;
- anglea = (unsigned __int64)(cosf_x * (signed __int64)sDepth) >> 16;
- *outx = v.x + (unsigned __int64)(sinf_y * (signed __int64)anglea);
- *outy = v.y + (unsigned __int64)(cosf_y * (signed __int64)anglea);
+ //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);
 
 }
@@ -5416,16 +5386,9 @@
 //----- (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) --------------------------------------------------------
@@ -5455,10 +5418,7 @@
   }
   else
   {
-    result = (flt_4E4A80[v2] - *(float *)&aAuthenticamd[4 * v2 + 12])
-           * (v3 - flt_4E4A80[v2 + 4])
-           / (flt_4E4A80[v2 + 5] - flt_4E4A80[v2 + 4])
-           + flt_4E4A80[v2];
+    result = (flt_4E4A80[v2] - flt_4E4A80[v2 - 3]) * (v3 - flt_4E4A80[v2 + 4]) / (flt_4E4A80[v2 + 5] - flt_4E4A80[v2 + 4]) + flt_4E4A80[v2];
   }
   return result;
 }
@@ -6049,10 +6009,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;
   }
 }
@@ -6074,22 +6034,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;
   }
@@ -9159,14 +9119,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,
@@ -9950,21 +9910,6 @@
 // 4E1D3A: using guessed type __int16 word_4E1D3A[];
 
 
-//----- (00413D3C) --------------------------------------------------------
-char *__cdecl GetDayPart()
-{
-  if ( pParty->uCurrentHour > 4 )
-  {
-    if ( pParty->uCurrentHour == 5 )
-      return pGlobalTXT_LocalizationStrings[55];
-    if ( pParty->uCurrentHour == 20 )
-      return pGlobalTXT_LocalizationStrings[566];
-    if ( pParty->uCurrentHour <= 0x14 || pParty->uCurrentHour > 0x17 )
-      return pGlobalTXT_LocalizationStrings[56];
-  }
-  return pGlobalTXT_LocalizationStrings[567];
-}
-
 //----- (00413FF1) --------------------------------------------------------
 void SetMonthNames()
 {
@@ -10107,23 +10052,25 @@
   Dst.uFrameY = 470 - Dst.uFrameHeight;
   Dst.uFrameZ = Dst.uFrameX + Dst.uFrameWidth - 1;
   Dst.uFrameW = 469;
+  //Dst.Hint = "abcagfdsgsg ljsrengvlkjesnfkjwnef";
   Dst.DrawMessageBox(0);
+
   Dst.uFrameWidth -= 24;
   Dst.uFrameX += 12;
   Dst.uFrameY += 12;
   Dst.uFrameHeight -= 12;
   Dst.uFrameZ = Dst.uFrameX + Dst.uFrameWidth - 1;
   Dst.uFrameW = Dst.uFrameY + Dst.uFrameHeight - 1;
-  Dst.DrawTitleText(pFontSmallnum, 0, 0xCu, 0, pGlobalTXT_LocalizationStrings[157], 3u);
+  Dst.DrawTitleText(pFontSmallnum, 0, 0xCu, ui_mainmenu_copyright_color, pGlobalTXT_LocalizationStrings[157], 3);
 }
 
 
 
 //----- (004156F0) --------------------------------------------------------
-void __cdecl GUI_UpdateWindows() 
+void GUI_UpdateWindows() 
 {
   GUIWindow *pWindow; // esi@4
-  unsigned int pWindowType; // eax@4
+  //unsigned int pWindowType; // eax@4
   char *pHint; // edx@66
   GUIButton *pButtonPtr_1C; // ebp@79
   char *pHint1; // edx@80
@@ -10151,7 +10098,6 @@
   for ( i = 1; i <= uNumVisibleWindows; ++i )
   {
     pWindow = &pWindowList[pVisibleWindowsIdxs[i] - 1];
-    pWindowType = pWindow->eWindowType;
     switch (pWindow->eWindowType)
     {
       case WINDOW_OptionsButtons:
@@ -10168,7 +10114,7 @@
       }
       case WINDOW_Options:
       {
-        DrawGameOptions();
+        GameMenuUI_Options_Draw();
         continue;
       }
       case WINDOW_Book:
@@ -10178,7 +10124,7 @@
       }
       case WINDOW_Dialogue:
       {
-        DrawDialogueUI();
+        GameUI_DrawDialogue();
         continue;
       }
       case WINDOW_QuickReference:
@@ -10198,12 +10144,12 @@
       }
       case WINDOW_SpellBook:
       {
-        DrawSpellBookContent();
+        DrawSpellBookContent(pPlayers[uActiveCharacter]);
         continue;
       }
       case WINDOW_GreetingNPC:
       {
-        DrawBranchlessDialogueUI();
+        GameUI_DrawBranchlessDialogue();
         continue;
       }
       case WINDOW_Chest:
@@ -10223,12 +10169,12 @@
       }
       case WINDOW_SaveLoadButtons:
       {
-        sub_4606FE();
+        SaveUI_Draw();
         continue;
       }
       case WINDOW_MainMenu_Load:
       {
-        GameUI_MainMenu_DrawLoad();
+        LoadUI_Draw();
         continue;
       }
       case WINDOW_HouseInterior:
@@ -10491,7 +10437,7 @@
         pButton = (GUIButton *)pWindow->ptr_1C;
         pRenderer->DrawTextureIndexed(pWindow->uFrameY,
                                       pWindow->uFrameX, pButton->pTextures[0]);
-        viewparams->bRedrawGameUI = 1;
+        viewparams->bRedrawGameUI = true;
         continue;
       }
       case WINDOW_CharacterWindow_Inventory:
@@ -10538,7 +10484,7 @@
 }
 
 //----- (00416196) --------------------------------------------------------
-void __cdecl identify_item()
+void identify_item()
 {
   Player *v0; // esi@2
   POINT *v1; // edi@2
@@ -10826,13 +10772,7 @@
       pAudioPlayer->PlaySound(SOUND_8, 0, 0, -1, 0, 0, 0, 0);
 
       pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 0, 0);
-      /*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;
-      }*/
+
       v42 = (int *)&a2.y;
       v41 = (int *)&y.y;
       v40 = (int *)&pOut;
@@ -10862,9 +10802,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
@@ -10886,9 +10827,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;
@@ -10898,17 +10840,11 @@
           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);
-      /*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;
-      }*/
+
       v42 = (int *)&a2.y;
       v41 = (int *)&y.y;
       v40 = (int *)&pOut;
@@ -10975,7 +10911,7 @@
 
 
 //----- (00416B01) --------------------------------------------------------
-void __thiscall sub_416B01(void *_this)//PopupWindowForBenefitAndJoinText
+void GameUI_DrawNPCPopup(void *_this)//PopupWindowForBenefitAndJoinText
 {
   int v1; // edi@2
   int v2; // ecx@2
@@ -11361,8 +11297,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
@@ -11389,7 +11325,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	Wed May 22 22:22:36 2013 +0600
+++ b/mm7_6.cpp	Wed May 22 22:23:04 2013 +0600
@@ -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	Wed May 22 22:22:36 2013 +0600
+++ b/mm7_data.cpp	Wed May 22 22:23:04 2013 +0600
@@ -1,7 +1,5 @@
 #include "mm7_data.h"
 
-#include "NPC.h"
-#include "Actor.h"
 #include "GUIWindow.h"
 #include "Party.h"
 
@@ -388,14 +386,6 @@
 char pDeckMaster[12];
 char aIxf[4]; // idb
 _UNKNOWN unk_4E19FC; // weak
-char pAreYouSureWishToLeave[32];
-char asc_4E1A28[4]; // idb
-char aUsxfs[13];
-char aLayout_pcx[11]; // weak
-char aSprites_pcx[12]; // weak
-char aProblemInBlit_[777]; // idb
-char aEWorkMsdevMm7M[777]; // idb
-char aProblemInBli_0[777]; // idb
 char aD[777]; // idb
 char asc_4E1AB0[777]; // idb
 char aWb_0[777]; // idb
@@ -407,7 +397,6 @@
 char aIcons[777]; // idb
 char aPending[777]; // idb
 char aCanTFindS[777]; // idb
-char pDayMoonPhase[28];
 char *spellbook_texture_filename_suffices[8] = {"f", "a", "w", "e", "s", "m", "b", "l"}; // weak
 __int16 word_4E1D3A[777]; // weak
 __int16 pTownPortalBook_xs[6] = {260, 324, 147, 385, 390,  19};
@@ -498,7 +487,6 @@
 char aS100110DS[777]; // idb
 char aS100110D02dSS[777]; // idb
 int pCurrentScreen = SCREEN_VIDEO; // 004E28F8
-char byte_4E28FC; // weak
 unsigned int uGammaPos;
 int BtnTurnCoord[8] = 
 {
@@ -513,7 +501,6 @@
 int pMagicSkills[9]  = {PLAYER_SKILL_FIRE,    PLAYER_SKILL_AIR,        PLAYER_SKILL_WATER,        PLAYER_SKILL_EARTH,   PLAYER_SKILL_SPIRIT,     PLAYER_SKILL_MIND,     PLAYER_SKILL_BODY,        PLAYER_SKILL_LIGHT,      PLAYER_SKILL_DARK};
 unsigned int pHealthBarPos[4] = {22, 137, 251, 366};
 unsigned int pManaBarPos[4] = {102, 217, 331, 447};
-char _4E2AD8_ui_colors[72];
 char _4E2B21_buff_spell_tooltip_colors[80];
 char monster_popup_y_offsets[88] =
 {
@@ -530,123 +517,22 @@
 
 
 const char *format_4E2D80 = "\f%05d%s\f00000\n";
-char format_4E2D90[8];
-char aS03d03dS000_0[777]; // idb
-char aS03d03dS000[777]; // idb
 //const char *format_4E2DC8 = "\f%05d";
-char aS[777]; // idb
-char aLuSLuS[777]; // idb
 const char *format_4E2DE8 = "\f%05d%s\f00000 - ";
-char asc_4E2DFC[3]; // idb
 const char *format_4E2E00 = "%s\f%05u\xD\r180%s\n"; // idb
 const char *format_4E2E10 = "%s\f%05u\t110%d\f00000 / %d\n";
-char aS100S_0[777]; // idb
-char aS100S[777]; // idb
-char aS100D[777]; // idb
-char aS180[6]; // idb
-char aS_6[2]; // idb
-char aSS_0[777]; // idb
-char aS_5[4]; // idb
-char string_4E3294[8];
-char Format[777]; // idb
-char aMem03i_txt[777]; // idb
-char aMemory[777]; // idb
-char aIdSSizeI[16]; // idb
 __int16 word_4E3C66[777]; // idb
 int dword_4E455C; // weak
 int dword_4E4560[6];
 int dword_4E4578[6];
 int dword_4E4590[6];
 int dword_4E45A8[6];
-char aDDSDDS[777]; // idb
-char asc_4E45DC[777]; // idb
-char aD02dSSDSD[777]; // idb
-char aButtexi1[777]; // idb
-char aCanTJumpToThat[777]; // idb
-char aNoMapFoundForS[777]; // idb
-char global_a2[777]; // idb
-char aSSS[777]; // idb
-char aNotInMapStats[17]; // weak
-char aD47_blv[777]; // idb
-char aOut15_odm[777]; // idb
-char Delim[777]; // idb
-char aGamma_pcx[777];
-char aQuit1[777]; // idb
-char aControls1[777]; // idb
-char aSave1[777]; // idb
-char aLoad1[777]; // idb
-char aNew1[777]; // idb
-char aOptions[777]; // idb
-char aGammapos[9]; // weak
-char aBloodsplats[777]; // idb
-char aTinting[777]; // idb
-char aColoredLights[777]; // idb
-char aTurndelta[777]; // idb
-char aFliponexit[777]; // idb
-char pKey[777]; // idb
-char aGraphicsmode[777]; // idb
-char aShowdamage[777]; // idb
-char aWalksound[777]; // idb
-char aCharvoices[777]; // idb
-char aMusicflag[777]; // idb
-char aSoundflag[777]; // idb
-char aOpvdgTn[777]; // idb
-char aOpvdgCl[777]; // idb
-char aOpvdgBs[777]; // idb
-char aOpvdhTn[777]; // idb
-char aOpvdhCl[777]; // idb
-char aOpvdhBs[777]; // idb
-char aOptvid[777]; // idb
-char aOptkb_2[777]; // idb
-char aOptkb_1[777]; // idb
-char aResume1[777]; // idb
-char aOptkb_h[777]; // idb
-char aOptkb[777]; // idb
-char aOption01[777]; // idb
-char aOption02[777]; // idb
-char aOption03[777]; // idb
-char aOption04[777]; // idb
-char aConvol90[777]; // idb
-char aConvol80[777]; // idb
-char aConvol70[777]; // idb
-char aConvol60[777]; // idb
-char aConvol50[777]; // idb
-char aConvol40[777]; // idb
-char aConvol30[777]; // idb
-char aConvol20[777]; // idb
-char aConvol10[777]; // idb
-char aConvol00[777]; // idb
-char aCon_smoo[777]; // idb
-char aCon_arrr[777]; // idb
-char aCon_arrl[777]; // idb
-char aCon_32x[777]; // idb
-char aCon_16x[777]; // idb
-char aControlbg[777]; // idb
-char aTitle_pcx[10]; // weak
-char aEWorkMsdevMm_0[777]; // idb
-char aDraw_debug_lin[777]; // idb
-char aGenuineintel[13]; // weak
-char asc_4E4938[13]; // weak
-int dword_4E4948[777]; // weak
-int dword_4E494C[777]; // weak
-int dword_4E49D0[777]; // weak
 _UNKNOWN dword_4E49D4; // idb
 int dword_4E4A18[777]; // weak
 int dword_4E4A1C[777]; // weak
 int dword_4E4A40[777]; // weak
 int dword_4E4A44[777]; // weak
-char aCentaurhauls[13]; // weak
-char aCyrixinstead[13]; // weak
-char aAuthenticamd[13]; // weak
 float flt_4E4A80[10];
-char aInvalidPlayerI[777]; // idb
-char aEWorkMsdevMm_1[777]; // idb
-char aEWorkMsdevMm_2[777]; // idb
-char aErrorNoKeyboar[25]; // weak
-char aInvalidDeviceP[777]; // idb
-char aInvalidDevic_0[777]; // idb
-char aEWorkMsdevMm_3[777]; // idb
-char aErrorNoMouseFo[22]; // weak
 int pPaperdoll_BodyX = 481; // 004E4C28
 int pPaperdoll_BodyY = 0;   // 004E4C2C
 int paperdoll_Armor[4][17][2] = //4E4E30
@@ -753,24 +639,6 @@
   0x83, 0xD8,
   0x7B, 0xD8,
 };
-char aItem092v3[777]; // idb
-char aIbCd5D[777]; // idb
-char aItem281pc02d[777]; // idb
-char aPc02dbrd[777]; // idb
-char aPc23vDlhu[777]; // idb
-char aPc23vDlh[777]; // idb
-char aPc23vDrh[777]; // idb
-char aPc23vDlau[777]; // idb
-char aPc23vDlad[777]; // idb
-char aPc23vDbod[777]; // idb
-char aBackhand[777]; // idb
-char aBackdoll[777]; // idb
-char aMagnifB[777]; // idb
-char aItem3_3dvDa2[777]; // idb
-char aItem3_3dvDa1[15]; // weak
-char aItem3_3dvD[13]; // weak
-char aItem64v1[9]; // weak
-char aEffpar01[777]; // idb
 
 int pPartySpellbuffsUI_XYs[14][2] =
 {
@@ -788,14 +656,6 @@
    3, 6, 15, 8, 3, 12, 0
 };
 
-char aSpell27[777]; // idb
-char aSpell21[777]; // idb
-char aIsn02d[777]; // idb
-char aBardataB[777]; // idb
-char aBardata[8]; // weak
-char aBardataC[10]; // weak
-char aLoadprog[777]; // idb
-char aLoadingD_pcx[777]; // idb
 int pNPCPortraits_x[6][6] =     // 004E5E50
 {
   {521,   0,   0,   0,   0,  0},
@@ -828,123 +688,10 @@
 	"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
-char aEle[777]; // idb
-char aDar[777]; // idb
-char aLig[777]; // idb
-char aBod[777]; // idb
-char aMin[777]; // idb
-char aSpi[777]; // idb
-char aEar[777]; // idb
-char aWat[777]; // idb
-char aAir[777]; // idb
-char aFir[777]; // idb
-char aBan[777]; // idb
-char aTav[777]; // idb
-char aTow[777]; // idb
-char aTra[777]; // idb
-char aTem[777]; // idb
-char aBoa[777]; // idb
-char aSta[777]; // idb
-char aAlc[777]; // idb
-char aMag[777]; // idb
-char aArm[777]; // idb
-char aWea[777]; // idb
-char asc_4E7BD4[2]; // idb
-char a2devents_txt[777]; // idb
-char aFileSSizeLuBuf[777]; // idb
-char aGlobal_evt[777]; // idb
-char aMax_event_text[777]; // idb
-char aS_str[777]; // idb
-char aS_evt[777]; // idb
-char aNoMazeInfoForT[36]; // weak
-char aC[777]; // idb
-char aB[3]; // weak
-char aEvt02d[777]; // idb
-char aNoTransitionTe[777]; // idb
-char aEWorkMsdevMm_4[777]; // idb
-char asc_4E7CD4[777]; // idb
-char aSS_1[777]; // idb
-char aNpcIdExceedsMa[777]; // idb
-char aNpc03u[777]; // idb
-char aPcout01[777]; // idb
-char aArbiterEvil[777]; // idb
-char aArbiterGood[777]; // idb
-char a0[777]; // idb
-char aPartyStart[777]; // idb
-char aNorthStart[12]; // weak
-char aSouthStart[12]; // weak
-char aEastStart[11]; // weak
-char aWestStart[11]; // weak
-char aUnableToFindDo[777]; // idb
-char aNwc_blv[777]; // idb
-char aUnableToOpenS[777]; // idb
-char aInvalidStringP[777]; // idb
-char aEWorkMsdevMm_5[777]; // idb
-char aNull[777]; // idb
-char aInvalidStrin_0[777]; // idb
-char aSI[777]; // idb
-char aS7[4]; // weak
-char aS6[777]; // idb
-char aS5[4]; // weak
-char aS1[777]; // idb
-char aS3[4]; // weak
-char aS0[777]; // idb
-char aS2[4]; // weak
-char aS4[4]; // weak
-char aUnableToSaveDs[777]; // idb
-char aDataDsft_bin[777]; // idb
-char aPFrames[777]; // idb
-char aEFrames[777]; // idb
-char aSFrames[777]; // idb
-char aMirror7[777]; // idb
-char aMirror6[777]; // idb
-char aMirror5[777]; // idb
-char aMirror4[777]; // idb
-char aMirror3[777]; // idb
-char aMirror2[777]; // idb
-char aMirror1[777]; // idb
-char aMirror0[777]; // idb
-char aLuminous[777]; // idb
-char a1[777]; // idb
-char aNew[777]; // idb
-char pMessag[777]; // idb
-char aCspriteframeta[777]; // idb
-char aR[777]; // idb
-char aNew_0[777]; // idb
-char aUnableToSaveDt[777]; // idb
-char aDataDtft_bin[777]; // idb
-char aTxtFrames[777]; // idb
-char aCtexturefram_1[777]; // idb
-char aCtexturefram_0[777]; // idb
-char aCtextureframet[777]; // idb
+
 int bWinNT4_0; // weak
-char aEWorkMsdevMm_6[777]; // idb
-char aTheVisObjectPo[777]; // idb
-char aSpriteOutlineC[777]; // idb
-char aUndefinedCobje[777]; // idb
-char aEWorkMsdevMm_7[777]; // idb
-char aGammaControlNo[777]; // idb
 __int16 word_4E8152[11] = {0, 0, 0, 90, 8, 2, 70, 20, 10, 50, 30};
 
-char aD3dTextureName[777]; // idb
-char aLogd3d_txt[777]; // idb
 char byte_4E8394[204] =
 {
   0, 0, 0, 0, 1, 1, 2, 3, 0, 4, 5, 6, 7, 8, 10, 9, 1, 0, 0, 0, 0, 0, 0,
@@ -1278,59 +1025,13 @@
   "MAGSHELF", "MAGSHELF", "MAGSHELF", "MAGSHELF",
   "MAGSHELF", "MAGSHELF", "MAGSHELF"
 };
-//__int16 word_4F03FE[777]; // weak
-//__int16 word_4F0400[777]; // weak
-/*__int16 word_4F0404[] =
-{
-	0, 0, 1, 0x17, 0x1B, 0x14, 0x14, 1, 0x17, 0x18, 0x1C,
-	0x14, 2, 0x17, 0x18, 0x19, 0x14, 2, 0x1B, 0x1B, 0x1A, 0x1A,
-	4, 0x18, 0x1E, 0x19, 0x1B, 4, 0x18, 0x1E, 0x19, 0x1B, 3, 0x1E,
-	0x18, 0x14, 0x14, 2, 0x14, 0x14, 0x14, 0x14, 3, 0x1B, 0x1B, 0x1A, 0x1A,
-	3, 0x1C, 0x1C, 0x19, 0x19, 2, 0x17, 0x17, 0x18, 0x18,
-	3, 0x17, 0x17, 0x1A, 0x1A, 2, 0x1E, 0x1A, 0x1A, 0x1A, 2, 0x1C,
-	0x19, 0x1C, 0x1D, 0, 0
-};*/
-//__int16 word_4F0498[777]; // weak
-/*__int16 word_4F0498[] =
-{
-1, 0x23, 0x23, 0x26, 0x26, 1, 0x1F, 0x1F, 0x1F, 0x22, 1, 0x23, 0x23,
-0x26, 0x26, 1, 0x1F, 0x1F, 0x20, 0x22, 2, 0x23, 0x23,
-0x26, 0x26, 2, 0x1F, 0x20, 0x20, 0x21, 2, 0x23, 0x23,
-0x26, 0x26, 2, 0x1F, 0x1F, 0x20, 0x20, 4, 0x23, 0x23,
-0x26, 0x26, 4, 0x1F, 0x20, 0x21, 0x22, 4, 0x23, 0x23, 0x26, 0x26,
-4, 0x1F, 0x20, 0x21, 0x22, 3, 0x23, 0x23, 0x26, 0x26, 3,
-0x1F, 0x1F, 0x1F, 0x1F, 2, 0x23, 0x23, 0x26, 0x26, 2, 0x1F, 0x20,
-0x22, 0x22, 3, 0x23, 0x23, 0x26, 0x26, 3, 0x1F, 0x1F,
-0x20, 0x20, 3, 0x23, 0x23, 0x26, 0x26, 3, 0x20, 0x20, 0x20,
-0x21, 3, 0x23, 0x23, 0x26, 0x26, 3, 0x1F, 0x1F, 0x1F, 0x20
-};*/
-//__int16 word_4F0576[777]; // weak
-/*__int16 word_4F0576[] =
-{
-0x23, 0x23, 0x26, 0x26, 3, 0x21, 0x1F, 0x20, 0x22, 3, 0x23, 0x23,
-0x26, 0x26, 3, 0x21, 0x1F, 0x20, 0x22, 4, 0x23, 0x23, 0x26, 0x26,
-4, 0x21, 0x1F, 0x20, 0x22, 0x1, 0x1, 0x2, 0x2, 0x4, 0x4,
-3, 2, 2, 2, 2, 2, 2, 0, 0x1, 0x1, 0x2, 0x2, 0x3, 0x3, 0x4, 0x4,
-2, 2, 2, 2, 0x0, 0x0, 1, 0, 0xA3, 0xA3, 0xA2, 0xA1, 0xA0,
-2, 0, 0xA3, 0xA3, 0xA2, 0xA1, 0xA0, 2, 0, 0xA3, 0xA3,
-0xA2, 0xA1, 0xA0, 2, 0, 0x0A3, 0x0A3, 0xA2, 0xA1, 0xA0,
-3, 0, 0xA3, 0xA3, 0xA2, 0xA1, 0xA0, 3, 0, 0xA3, 0xA3,
-0xA2, 0xA1, 0xA0
-};*/
 
-//__int16 word_4F0578[777]; // weak
-//__int16 word_4F05AE[777]; // weak
-
-//__int16 word_4F063E[290];
-//__int16 word_4F06D8[22];
 int guild_mambership_flags[32]={
    54, 54, 54, 54, 52, 52, 52, 52, 55, 55, 55, 55, 53, 53,
 	   53, 53, 58, 58, 58, 58, 57, 57, 57, 57, 56, 56,
 	   56, 56, 59, 59, 60, 60};
 __int16 word_4F0754[49];
-//__int16 word_4F07B6[88];
-//__int16 _word_4F0866_pMaxLevelPerTrainingHallType_negindexing[14];
-__int16 _4F0882_evt_VAR_PlayerItemInHands_vals[54]=
+__int16 _4F0882_evt_VAR_PlayerItemInHands_vals[54] =
 {
 	0x0D4, 0x270, 0x0D5, 0x21C, 0x0D6, 0x2BE, 0x0D7, 0x2BD, 0x0D8, 0x289, 
 	0x0D9, 0x258, 0x0DA, 0x2AB, 0x0DB, 0x281, 0x0DC, 0x280, 0x0DD,
@@ -1354,40 +1055,6 @@
 					       4, 7, 10, 11,
 					       7, 11,
 						   7, 11};
-char aS03d[777]; // idb
-char byte_4F0F98; // idb
-char sz[777]; // idb
-char aSSSSSS[777]; // idb
-char aSDS[777]; // idb
-char aSS_3[777]; // idb
-char aSSSS[777]; // idb
-char aS_2[777]; // idb
-char aErrorlog_txt[777]; // idb
-char aUnsupportedPix[777]; // idb
-char aSmackerError[777]; // idb
-char aCS[777]; // idb
-char aAnimsMagic7_vi[777]; // idb
-char aVideoFileError[777]; // idb
-char aCanTOpenFileAn[777]; // idb
-char aAnimsMight7_vi[777]; // idb
-char aCanTLoadS[777]; // idb
-char aS_smk[777]; // idb
-char aUnsupportedBin[27]; // weak
-char aEWorkMsdevM_29[777]; // idb
-char aFailedToOpenBl[777]; // idb
-char aCanTAllocateMe[33]; // weak
-char aCanTLoadFileAn[777]; // idb
-char aS_bik[777]; // idb
-char aMm7_win_pcx[777]; // idb
-char aLuSLuSLuS[777]; // idb
-char aEndgame_fnt[777]; // idb
-char aWinbg_pcx[10]; // weak
-char aDefaultCaseRea[777]; // idb
-char aUnsupportedExc[71]; // weak
-char aEWorkMsdevM_30[777]; // idb
-char aUndefinedTypeR[777]; // idb
-char aUnknownPointer[777]; // idb
-char a1_1_3[6]; // weak
 double dbl_4F2870; // weak
 int dword_4F288C; // weak
 double dbl_4F5372; // weak
@@ -1509,8 +1176,7 @@
 int dword_506984; // weak
 int dword_506988; // weak
 int dword_50698C; // weak
-int dword_506E68; // weak
-char KeyButtonFlagChangesArray[28]; // weak
+int uGameMenuUI_CurentlySelectedKeyIdx; // 506E68
 unsigned int pPrevVirtualCidesMapping[27];
 int KeyboardPageNum; // weak
 int dword_506F0C[777]; // idb
@@ -1546,8 +1212,6 @@
 int dword_507B98_ctrl_pressed; // weak
 unsigned int uActiveCharacter;
 int dword_507BF0_is_there_popup_onscreen; // weak
-int dword_507C08; // weak
-int dword_507C0C; // weak
 int dword_507CBC; // weak
 int dword_507CC0; // weak
 __int64 GameUI_RightPanel_BookFlashTimer; // weak
@@ -1562,26 +1226,16 @@
 int _50B834_view_transformed_zs[45];
 int dword_50B918[777];
 int _50B924_view_transformed_xs[45];
-//int unk_50B9D4[777]; // idb
 int _50B9D8_screen_space_y[777];
 int dword_50B9E4[777];
-//int dword_50B9E0_ys[777]; // idb
-//int dword_50B9EC[777]; // idb
 int dword_50B9F0[2]; // idb
-//int dword_50BAE8_xs[777];
-//int dword_50BAF4_xs[777];
-//int dword_50B9F8[777]; // idb
 int dword_50B9FC_ys[3 + 45];
 int dword_50BA08_ys[48]; // idb
-//int dword_50BAC4[777]; // weak
 int _50BAC8_screen_space_x[777]; // idb
-//int dword_50BAD0[777]; // weak
 int dword_50BAD4[777]; // weak
-//int dword_50BADC_xs[777]; // weak
 int dword_50BAE0[777]; // weak
 int dword_50BAE8[777]; // weak
 int dword_50BAEC_xs[3 + 45]; // weak
-//int dword_50BAF4[777]; // weak
 int dword_50BAF8_xs[48]; // weak
 int dword_50BC10[777]; // weak
 int dword_50BDA0[777]; // weak
@@ -1606,8 +1260,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	Wed May 22 22:22:36 2013 +0600
+++ b/mm7_data.h	Wed May 22 22:23:04 2013 +0600
@@ -1,8 +1,7 @@
 #pragma once
 #include <string>
+#include "VectorTypes.h"
 #include "OSAPI.h"
-#include "SpriteObject.h"
-#include "VectorTypes.h"
 
 typedef char _UNKNOWN;
 
@@ -322,14 +321,6 @@
 extern char pDeckMaster[12];
 extern char aIxf[4]; // idb
 extern _UNKNOWN unk_4E19FC; // weak
-extern char pAreYouSureWishToLeave[32];
-extern char asc_4E1A28[4]; // idb
-extern char aUsxfs[13];
-extern char aLayout_pcx[11]; // weak
-extern char aSprites_pcx[12]; // weak
-extern char aProblemInBlit_[]; // idb
-extern char aEWorkMsdevMm7M[]; // idb
-extern char aProblemInBli_0[]; // idb
 extern char aD[]; // idb
 extern char asc_4E1AB0[]; // idb
 extern char aWb_0[]; // idb
@@ -341,7 +332,6 @@
 extern char aIcons[]; // idb
 extern char aPending[]; // idb
 extern char aCanTFindS[]; // idb
-extern char pDayMoonPhase[28];
 extern int paperdoll_Weapon[4][16][2];
 extern char *spellbook_texture_filename_suffices[]; // weak
 extern __int16 word_4E1D3A[]; // weak
@@ -432,7 +422,6 @@
 extern char aS100110DS[]; // idb
 extern char aS100110D02dSS[]; // idb
 extern int pCurrentScreen; // 004E28F8
-extern char byte_4E28FC; // weak
 extern unsigned int uGammaPos;
 extern int BtnTurnCoord[8];
 extern __int16 RightClickPortraitXmin[4];
@@ -444,7 +433,6 @@
 extern int pMagicSkills[9];
 extern unsigned int pHealthBarPos[4];
 extern unsigned int pManaBarPos[4];
-extern char _4E2AD8_ui_colors[72];
 extern char _4E2B21_buff_spell_tooltip_colors[80];
 extern char monster_popup_y_offsets[]; // weak
 extern unsigned char hourglass_icon_idx; // weak
@@ -452,118 +440,21 @@
 
 extern const char *format_4E2D80;
 extern char format_4E2D90[8];
-//extern const char *format_4E2DC8;
 extern const char *format_4E2DE8; // idb
-extern char asc_4E2DFC[3]; // idb
 extern const char *format_4E2E00; // idb
 extern const char *format_4E2E10; // format text of resistance in Stats screen
-extern char aS100S_0[]; // idb
-extern char aS100S[]; // idb
-extern char aS100D[]; // idb
-extern char aS180[6]; // idb
-extern char aS_6[2]; // idb
-extern char aSS_0[]; // idb
-extern char aS_5[4]; // idb
-extern char string_4E3294[8];
-extern char Format[]; // idb
-extern char aMem03i_txt[]; // idb
-extern char aMemory[]; // idb
-extern char aIdSSizeI[16]; // idb
 extern __int16 word_4E3C66[]; // idb
 extern int dword_4E455C; // weak
 extern int dword_4E4560[6];
 extern int dword_4E4578[6];
 extern int dword_4E4590[6];
 extern int dword_4E45A8[6];
-extern char aDDSDDS[]; // idb
-extern char asc_4E45DC[]; // idb
-extern char aD02dSSDSD[]; // idb
-extern char aButtexi1[]; // idb
-extern char aCanTJumpToThat[]; // idb
-extern char aNoMapFoundForS[]; // idb
-extern char global_a2[]; // idb
-extern char aSSS[]; // idb
-extern char aNotInMapStats[17]; // weak
-extern char aD47_blv[]; // idb
-extern char aOut15_odm[]; // idb
-extern char Delim[]; // idb
-extern char aGamma_pcx[];
-extern char aQuit1[]; // idb
-extern char aControls1[]; // idb
-extern char aSave1[]; // idb
-extern char aLoad1[]; // idb
-extern char aNew1[]; // idb
-extern char aOptions[]; // idb
-extern char aGammapos[9]; // weak
-extern char aBloodsplats[]; // idb
-extern char aTinting[]; // idb
-extern char aColoredLights[]; // idb
-extern char aTurndelta[]; // idb
-extern char aFliponexit[]; // idb
-extern char pKey[]; // idb
-extern char aGraphicsmode[]; // idb
-extern char aShowdamage[]; // idb
-extern char aWalksound[]; // idb
-extern char aCharvoices[]; // idb
-extern char aMusicflag[]; // idb
-extern char aSoundflag[]; // idb
-extern char aOpvdgTn[]; // idb
-extern char aOpvdgCl[]; // idb
-extern char aOpvdgBs[]; // idb
-extern char aOpvdhTn[]; // idb
-extern char aOpvdhCl[]; // idb
-extern char aOpvdhBs[]; // idb
-extern char aOptvid[]; // idb
-extern char aOptkb_2[]; // idb
-extern char aOptkb_1[]; // idb
-extern char aResume1[]; // idb
-extern char aOptkb_h[]; // idb
-extern char aOptkb[]; // idb
-extern char aOption01[]; // idb
-extern char aOption02[]; // idb
-extern char aOption03[]; // idb
-extern char aOption04[]; // idb
-extern char aConvol90[]; // idb
-extern char aConvol80[]; // idb
-extern char aConvol70[]; // idb
-extern char aConvol60[]; // idb
-extern char aConvol50[]; // idb
-extern char aConvol40[]; // idb
-extern char aConvol30[]; // idb
-extern char aConvol20[]; // idb
-extern char aConvol10[]; // idb
-extern char aConvol00[]; // idb
-extern char aCon_smoo[]; // idb
-extern char aCon_arrr[]; // idb
-extern char aCon_arrl[]; // idb
-extern char aCon_32x[]; // idb
-extern char aCon_16x[]; // idb
-extern char aControlbg[]; // idb
-extern char aTitle_pcx[10]; // weak
-extern char aEWorkMsdevMm_0[]; // idb
-extern char aDraw_debug_lin[]; // idb
-extern char aGenuineintel[13]; // weak
-extern char asc_4E4938[13]; // weak
-extern int dword_4E4948[]; // weak
-extern int dword_4E494C[]; // weak
-extern int dword_4E49D0[]; // weak
 extern _UNKNOWN dword_4E49D4; // idb
 extern int dword_4E4A18[]; // weak
 extern int dword_4E4A1C[]; // weak
 extern int dword_4E4A40[]; // weak
 extern int dword_4E4A44[]; // weak
-extern char aCentaurhauls[13]; // weak
-extern char aCyrixinstead[13]; // weak
-extern char aAuthenticamd[13]; // weak
 extern float flt_4E4A80[10];
-extern char aInvalidPlayerI[]; // idb
-extern char aEWorkMsdevMm_1[]; // idb
-extern char aEWorkMsdevMm_2[]; // idb
-extern char aErrorNoKeyboar[25]; // weak
-extern char aInvalidDeviceP[]; // idb
-extern char aInvalidDevic_0[]; // idb
-extern char aEWorkMsdevMm_3[]; // idb
-extern char aErrorNoMouseFo[22]; // weak
 extern int pPaperdoll_BodyX; // weak
 extern int pPaperdoll_BodyY; // weak
 extern int paperdoll_Armor[4][17][2];
@@ -581,143 +472,16 @@
 extern int pPaperdoll_SecondLeftHand[4][2];
 extern int pPaperdoll_RightHand[4][2];
 extern int pPaperdollLeftEmptyHand[4][2];
-extern char aItem092v3[]; // idb
-extern char aIbCd5D[]; // idb
-extern char aItem281pc02d[]; // idb
-extern char aPc02dbrd[]; // idb
-extern char aPc23vDlhu[]; // idb
-extern char aPc23vDlh[]; // idb
-extern char aPc23vDrh[]; // idb
-extern char aPc23vDlau[]; // idb
-extern char aPc23vDlad[]; // idb
-extern char aPc23vDbod[]; // idb
-extern char aBackhand[]; // idb
-extern char aBackdoll[]; // idb
-extern char aMagnifB[]; // idb
-extern char aItem3_3dvDa2[]; // idb
-extern char aItem3_3dvDa1[15]; // weak
-extern char aItem3_3dvD[13]; // weak
-extern char aItem64v1[9]; // weak
-extern char aEffpar01[]; // idb
 extern int pPartySpellbuffsUI_XYs[14][2];
 extern unsigned char byte_4E5DD8[]; // weak
 extern unsigned __int8 pPartySpellbuffsUI_smthns[14];
-extern char aSpell27[]; // idb
-extern char aSpell21[]; // idb
-extern char aIsn02d[]; // idb
-extern char aBardataB[]; // idb
-extern char aBardata[8]; // weak
-extern char aBardataC[10]; // weak
-extern char aLoadprog[]; // idb
-extern char aLoadingD_pcx[]; // idb
 extern int pNPCPortraits_x[6][6]; // 004E5E50
 extern int pNPCPortraits_y[6][6]; // 004E5EE0
 extern const char *pHouse_ExitPictures[11];
 extern const char *_4E6BDC_loc_names[11];
-extern char aOutside[]; // idb
-extern char aMer[]; // idb
-extern char aMir[]; // idb
-extern char aSel[]; // idb
-extern char aEle[]; // idb
-extern char aDar[]; // idb
-extern char aLig[]; // idb
-extern char aBod[]; // idb
-extern char aMin[]; // idb
-extern char aSpi[]; // idb
-extern char aEar[]; // idb
-extern char aWat[]; // idb
-extern char aAir[]; // idb
-extern char aFir[]; // idb
-extern char aBan[]; // idb
-extern char aTav[]; // idb
-extern char aTow[]; // idb
-extern char aTra[]; // idb
-extern char aTem[]; // idb
-extern char aBoa[]; // idb
-extern char aSta[]; // idb
-extern char aAlc[]; // idb
-extern char aMag[]; // idb
-extern char aArm[]; // idb
-extern char aWea[]; // idb
-extern char asc_4E7BD4[2]; // idb
-extern char a2devents_txt[]; // idb
-extern char aFileSSizeLuBuf[]; // idb
-extern char aGlobal_evt[]; // idb
-extern char aMax_event_text[]; // idb
-extern char aS_str[]; // idb
-extern char aS_evt[]; // idb
-extern char aNoMazeInfoForT[36]; // weak
-extern char aC[]; // idb
-extern char aB[3]; // weak
-extern char aEvt02d[]; // idb
-extern char aNoTransitionTe[]; // idb
-extern char aEWorkMsdevMm_4[]; // idb
-extern char asc_4E7CD4[]; // idb
-extern char aSS_1[]; // idb
-extern char aNpcIdExceedsMa[]; // idb
-extern char aNpc03u[]; // idb
-extern char aPcout01[]; // idb
-extern char aArbiterEvil[]; // idb
-extern char aArbiterGood[]; // idb
-extern char a0[]; // idb
-extern char aPartyStart[]; // idb
-extern char aNorthStart[12]; // weak
-extern char aSouthStart[12]; // weak
-extern char aEastStart[11]; // weak
-extern char aWestStart[11]; // weak
-extern char aUnableToFindDo[]; // idb
-extern char aNwc_blv[]; // idb
-extern char aUnableToOpenS[]; // idb
-extern char aInvalidStringP[]; // idb
-extern char aEWorkMsdevMm_5[]; // idb
-extern char aNull[]; // idb
-extern char aInvalidStrin_0[]; // idb
-extern char aSI[]; // idb
-extern char aS7[4]; // weak
-extern char aS6[]; // idb
-extern char aS5[4]; // weak
-extern char aS1[]; // idb
-extern char aS3[4]; // weak
-extern char aS0[]; // idb
-extern char aS2[4]; // weak
-extern char aS4[4]; // weak
-extern char aUnableToSaveDs[]; // idb
-extern char aDataDsft_bin[]; // idb
-extern char aPFrames[]; // idb
-extern char aEFrames[]; // idb
-extern char aSFrames[]; // idb
-extern char aMirror7[]; // idb
-extern char aMirror6[]; // idb
-extern char aMirror5[]; // idb
-extern char aMirror4[]; // idb
-extern char aMirror3[]; // idb
-extern char aMirror2[]; // idb
-extern char aMirror1[]; // idb
-extern char aMirror0[]; // idb
-extern char aLuminous[]; // idb
-extern char a1[]; // idb
-extern char aNew[]; // idb
-extern char pMessag[]; // idb
-extern char aCspriteframeta[]; // idb
-extern char aR[]; // idb
-extern char aNew_0[]; // idb
-extern char aUnableToSaveDt[]; // idb
-extern char aDataDtft_bin[]; // idb
-extern char aTxtFrames[]; // idb
-extern char aCtexturefram_1[]; // idb
-extern char aCtexturefram_0[]; // idb
-extern char aCtextureframet[]; // idb
 extern int bWinNT4_0; // weak
-extern char aEWorkMsdevMm_6[]; // idb
-extern char aTheVisObjectPo[]; // idb
-extern char aSpriteOutlineC[]; // idb
-extern char aUndefinedCobje[]; // idb
-extern char aEWorkMsdevMm_7[]; // idb
-extern char aGammaControlNo[]; // idb
 extern __int16 word_4E8152[11];
 extern char byte_4E8168[7][14];
-extern char aD3dTextureName[]; // idb
-extern char aLogd3d_txt[]; // idb
 extern char byte_4E8394[]; // weak
 #include "Texture.h"
 extern stru355 stru_4E82A4;// = {0x20, 0x41, 0, 0x20, 0xFF0000, 0xFF00, 0xFF, 0xFF000000};
@@ -744,7 +508,6 @@
 extern const char *dlhu_texnames_by_face[25];
 extern unsigned char byte_4ECF08[48][25];
 extern unsigned char SoundSetAction[110][8]; // weak
-//extern unsigned char byte_4ED498; // weak
 extern __int16 pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[4];
 extern char byte_4ED970_skill_learn_ability_by_class_table[36][37];
 extern int dword_4EDEA0[]; // weak
@@ -764,59 +527,15 @@
 extern void *off_4EFDB0; // weak
 extern int dword_4F031C[]; // weak
 extern const char *off_4F03B8[]; // idb
-//extern __int16 word_4F03FE[]; // weak
-//extern __int16 word_4F0400[]; // weak
-//extern __int16 word_4F0404[];
-//extern __int16 word_4F0498[]; // weak
 extern __int16 word_4F0576[]; // weak
 
-//extern __int16 word_4F05AE[]; // weak
-
-//extern __int16 word_4F063E[290];
-//extern __int16 word_4F06D8[22];
 extern int guild_mambership_flags[32];
 extern __int16 word_4F0754[49];
-//extern __int16 word_4F07B6[88];
-//extern __int16 _word_4F0866_pMaxLevelPerTrainingHallType_negindexing[14];
 extern __int16 _4F0882_evt_VAR_PlayerItemInHands_vals[54];
 extern unsigned short pMaxLevelPerTrainingHallType[];
 extern int price_for_membership[]; // weak
 extern Vec2_int_ pMonsterArenaPlacements[20];
 extern __int16 word_4F0F30[32]; // weak
-extern char aS03d[]; // idb
-extern char byte_4F0F98; // idb
-extern char sz[]; // idb
-extern char aSSSSSS[]; // idb
-extern char aSDS[]; // idb
-extern char aSS_3[]; // idb
-extern char aSSSS[]; // idb
-extern char aS_2[]; // idb
-extern char aErrorlog_txt[]; // idb
-extern char aUnsupportedPix[]; // idb
-extern char aSmackerError[]; // idb
-extern char aCS[]; // idb
-extern char aAnimsMagic7_vi[]; // idb
-extern char aVideoFileError[]; // idb
-extern char aCanTOpenFileAn[]; // idb
-extern char aAnimsMight7_vi[]; // idb
-extern char aCanTLoadS[]; // idb
-extern char aS_smk[]; // idb
-extern char aUnsupportedBin[27]; // weak
-extern char aEWorkMsdevM_29[]; // idb
-extern char aFailedToOpenBl[]; // idb
-extern char aCanTAllocateMe[33]; // weak
-extern char aCanTLoadFileAn[]; // idb
-extern char aS_bik[]; // idb
-extern char aMm7_win_pcx[]; // idb
-extern char aLuSLuSLuS[]; // idb
-extern char aEndgame_fnt[]; // idb
-extern char aWinbg_pcx[10]; // weak
-extern char aDefaultCaseRea[]; // idb
-extern char aUnsupportedExc[71]; // weak
-extern char aEWorkMsdevM_30[]; // idb
-extern char aUndefinedTypeR[]; // idb
-extern char aUnknownPointer[]; // idb
-extern char a1_1_3[6]; // weak
 extern double dbl_4F2870; // weak
 extern int dword_4F288C; // weak
 extern double dbl_4F5372; // weak
@@ -937,8 +656,8 @@
 extern int dword_506984; // weak
 extern int dword_506988; // weak
 extern int dword_50698C; // weak
-extern int dword_506E68; // weak
-extern char KeyButtonFlagChangesArray[28]; // weak
+extern int uGameMenuUI_CurentlySelectedKeyIdx; // 506E68
+extern bool GameMenuUI_InvaligKeyBindingsFlags[28]; // 506E6C
 extern unsigned int pPrevVirtualCidesMapping[27];
 extern int KeyboardPageNum; // weak
 extern int dword_506F0C[]; // idb
@@ -974,8 +693,6 @@
 extern int dword_507B98_ctrl_pressed; // weak
 extern unsigned int uActiveCharacter;
 extern int dword_507BF0_is_there_popup_onscreen; // weak
-extern int dword_507C08; // weak
-extern int dword_507C0C; // weak
 extern int dword_507CBC; // weak
 extern int dword_507CC0; // weak
 extern __int64 GameUI_RightPanel_BookFlashTimer; // weak
@@ -990,26 +707,16 @@
 extern int _50B834_view_transformed_zs[];
 extern int dword_50B918[];
 extern int _50B924_view_transformed_xs[];
-//extern int unk_50B9D4[]; // idb
 extern int _50B9D8_screen_space_y[];
 extern int dword_50B9E4[];
-//extern int dword_50B9E0_ys[]; // idb
-//extern int dword_50B9EC[]; // idb
 extern int dword_50B9F0[]; // idb
-//extern int dword_50BAE8_xs[];
-//extern int dword_50BAF4_xs[];
-//extern int dword_50B9F8_xs[]; // idb
 extern int dword_50B9FC_ys[];
 extern int dword_50BA08_ys[]; // idb
-//extern int dword_50BAC4[]; // weak
 extern int _50BAC8_screen_space_x[]; // idb
-//extern int dword_50BAD0[]; // weak
 extern int dword_50BAD4[]; // weak
-//extern int dword_50BADC_xs[]; // weak
 extern int dword_50BAE0[]; // weak
 extern int dword_50BAE8[]; // weak
 extern int dword_50BAEC_xs[]; // weak
-//extern int dword_50BAF4[]; // weak
 extern int dword_50BAF8_xs[]; // weak
 extern int dword_50BC10[]; // weak
 extern int dword_50BDA0[]; // weak
@@ -1034,8 +741,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
@@ -1056,11 +763,6 @@
 extern int papredoll_flying_feet[]; // idb
 extern int paperdoll_boots_texture[4][6];
 extern int paperdoll_cloak_collar_texture[4][10]; // weak
-//extern int dword_51179C; // weak
-//extern int dword_5117A0; // weak
-//extern int dword_5117A4; // weak
-//extern int dword_5117A8; // weak
-//extern int dword_5117AC; // weak
 extern int paperdoll_cloak_texture[4][10];
 extern int bRingsShownInCharScreen; // weak
 extern int _unused000; // weak
@@ -1523,7 +1225,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);
@@ -1546,26 +1248,17 @@
 void __fastcall sub_40F92A(int *pZBuffer, struct Texture *a2, int a3); // idb
 void __cdecl SetMoonPhaseNames();
 signed int __fastcall sub_410D99_get_map_index(int a1);
-struct GUIWindow *__cdecl sub_41140B();
-void __cdecl sub_411473();
 void __fastcall LoadThumbnailLloydTexture(unsigned int uSlot, unsigned int uPlayer);
-void  sub_412AF9();
-char *GetDayPart();
 void SetAttributeNames();
 void uGameUIFontMain_initialize();
 void uGameUIFontShadow_initialize();
 void sub_41420D_press_esc();
 void sub_41426F();
-char GameMenuUI_DrawKeyBindings();
-unsigned int __thiscall sub_414D24(int _this);
-void GameMenuUI_DrawVideoOptions();
-void DrawGameOptions();
 void __fastcall DrawPopupWindow(unsigned int uX, unsigned int uY, unsigned int uWidth, unsigned int uHeight); // idb
 void DrawCopyrightWindow();
 void LoadFonts_and_DrawCopyrightWindow();
 void GUI_UpdateWindows();
 void identify_item();
-void __thiscall sub_416B01(void *_this);
 void __thiscall sub_416D62_ShowPopupWindow_MonsterRecord_ItemInfo_etcsub_416D62(struct Vec2_int_ *_this);
 void UI_OnMouseLeftClick(int *pXY); // idb
 void __thiscall sub_417871(int *pXY);
@@ -1573,24 +1266,20 @@
 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();
 unsigned int __fastcall GetSizeInInventorySlots(unsigned int uNumPixels);
 struct GUIButton *__fastcall GUI_HandleHotkey(unsigned __int8 uHotkey); // idb
 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);
 void __cdecl nullsub_3(); // idb
 void __cdecl LoadActualSkyFrame();
 void __cdecl Sleep6Hours();
-void __cdecl RestUI_Initialize();
-void __cdecl RestUI_Draw(); // idb
 void __cdecl sub_42038D();
 
 void __fastcall party_finds_gold(unsigned int uNumGold, int _1_dont_share_with_followers___2_the_same_but_without_a_message__else_normal); // idb
@@ -1676,7 +1365,6 @@
 void __fastcall sub_4406BC(unsigned int node_id, unsigned int uFirstNode); // idb
 void __fastcall sub_440BED(struct IndoorLocation_drawstru *_this);
 bool sub_44100D();
-void LoadPartyBuffIcons();
 __int16 __fastcall sub_441A4E(int a1);
 void DrawBook_Map_sub(unsigned int tl_x, unsigned int tl_y, unsigned int br_x, int br_y, int _48074); // idb
 void Initialize2DA();
@@ -1686,19 +1374,12 @@
 void __cdecl OnMapLeave();
 void /*__usercall*/ OnMapLoad();
 void __thiscall Level_LoadEvtAndStr(const char *pLevelName);
-char *__cdecl _4443D5_GetMinimapRightClickText();
 const char *__cdecl sub_444564();
 char *__thiscall GetEventHintString(unsigned int uEventID); // idb
-unsigned int __fastcall sub_444839_move_map(unsigned int a1, int a2, int x, int y, int z, int directiony, int directionx, int a8, const char *pLocationName); // idb
-void TransitionUI_Draw();
-void UI_CreateTravelDialogue();
 signed int __cdecl GetTravelTime();
-void __cdecl TravelUI_Draw();
-void __cdecl DrawBranchlessDialogueUI();
 void __fastcall sub_4451A8_press_any_key(int a1, int a2, int a4);
 void __cdecl sub_4452BB();
 const char *GetProfessionActionText(int a1);
-void __cdecl DrawDialogueUI();
 struct NPCData *__fastcall GetNPCData(signed int npcid);
 struct NPCData *__fastcall GetNewNPCData(signed int npcid, int a2);
 int __fastcall GetGreetType(signed int SpeakingNPC_ID);
@@ -1722,7 +1403,6 @@
 __int16 __fastcall sub_449A49_door_switch_animation(unsigned int uDoorID, int a2); // idb
 bool _449B57_test_bit(unsigned __int8 *a1, __int16 a2);
 void _449B7E_toggle_bit(unsigned char *pArray, __int16 a2, unsigned __int16 bToggle); // idb
-void __cdecl Party__CountHirelings();
 void __fastcall ShowStatusBarString(const char *pString, unsigned int uNumSeconds);
 void __cdecl ShowNothingHereStatus();
 signed int __cdecl const_2();
@@ -1757,14 +1437,9 @@
 void *__thiscall unknown_vdtor_6(void *_this, bool a2);
 unsigned short * MakeScreenshot(signed int width, signed int height);
 void __thiscall SaveScreenshot(const char *pFilename);
-void __fastcall GameUI_DrawLoadMenu(unsigned int uDialogueType); // idb
-void __cdecl GameUI_DrawSaveMenu();
 void __fastcall LoadGame(unsigned int uSlot); // idb
 void SaveGame(bool IsAutoSAve, bool NotSaveWorld);
 void __fastcall DoSavegame(unsigned int uSlot); // idb
-void GameUI_MainMenu_DoDrawLoad(int a1);
-void GameUI_MainMenu_DrawLoad();
-void __cdecl sub_4606FE();
 void __cdecl TryLoadLevelFromLOD();
 void __cdecl sub_46080D();
 bool __cdecl Initialize_GamesLOD_NewLOD();
@@ -1801,16 +1476,15 @@
 void __cdecl MM7Initialization();
 int __cdecl AbortWithError();
 void Abortf(const char *Format, ...);
-void FreeSavegameThumbnails();
 void SetCurrentMenuID(enum MENU_STATE); // idb
 enum MENU_STATE GetCurrentMenuID();
 void *__thiscall output_debug_string(void *_this, std::string a2, const char *a3, int a4);
 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);
@@ -1912,7 +1586,6 @@
 bool __fastcall HSV2RGB(float *a1, float *a2, float *a3, float a4, float a5, float a6);
 void __fastcall RGB2HSV(float *a1, float *a2, float a3, float a4, float a5, float *a6);
 unsigned int ReplaceHSV(unsigned int uColor, float a2, float gamma, float a4);
-int _48B561_mess_with_scaling_along_z(/*int a1, */float a2);
 signed int __cdecl PlayerCreation_Chose4Skills();
 signed int __cdecl PlayerCreation_ComputeAttributeBonus();
 void LoadPlayerPortraintsAndVoices();
@@ -1985,7 +1658,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);
@@ -2028,6 +1701,7 @@
 int fixpoint_sub0(int, int);
 int fixpoint_div(int, int);
 int fixpoint_mul(int, int);
+int fixpoint_from_float(float value);
 
 
 #define ErrD3D(hr) do {extern void ErrHR(HRESULT, const char *, const char *, const char *, int); ErrHR(hr, "Direct3D", __FUNCTION__, __FILE__, __LINE__);} while(0)
--- a/stru11.h	Wed May 22 22:22:36 2013 +0600
+++ b/stru11.h	Wed May 22 22:23:04 2013 +0600
@@ -1,6 +1,7 @@
 #pragma once
 
 
+#include "mm7_data.h"
 /*  128 */
 #pragma pack(push, 1)
 struct stru11
--- a/stru159.h	Wed May 22 22:22:36 2013 +0600
+++ b/stru159.h	Wed May 22 22:23:04 2013 +0600
@@ -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	Wed May 22 22:22:36 2013 +0600
+++ b/stru6.cpp	Wed May 22 22:23:04 2013 +0600
@@ -1,4 +1,7 @@
 #include "stru6.h"
+
+#include "mm7_data.h"
+#include "LightmapBuilder.h"
 #include "SpriteObject.h"
 #include "IndoorCameraD3D.h"
 #include "ParticleEngine.h"
@@ -708,7 +711,7 @@
     v4 = (double)v2 * 0.0001953125 + 0.2;
   }
   v5 = v4;
-  return _48B561_mess_with_scaling_along_z(/*v2, */v5);
+  return fixpoint_from_float(v5);
 }
 
 //----- (004A80DC) --------------------------------------------------------