changeset 1057:37498d2cceed

Слияние
author Ritor1
date Thu, 23 May 2013 21:37:22 +0600
parents 86a7e8f9ca33 (current diff) d48c762de563 (diff)
children cbb1baa606aa
files Vis.cpp mm7_5.cpp
diffstat 42 files changed, 1557 insertions(+), 4432 deletions(-) [+]
line wrap: on
line diff
--- a/Actor.cpp	Thu May 23 21:36:57 2013 +0600
+++ b/Actor.cpp	Thu May 23 21:37:22 2013 +0600
@@ -992,11 +992,11 @@
       do
       {
         v58 = (*v57)->GetActualWillpower();
-        v59 = (*v57)->_48EA1B_get_static_effect(v58);
+        v59 = (*v57)->GetParameterBonus(v58);
         v60 = (*v57)->GetActualIntelligence();
-        v61 = ((*v57)->_48EA1B_get_static_effect(v60) + v59) >> 1;
+        v61 = ((*v57)->GetParameterBonus(v60) + v59) >> 1;
         v62 = (*v57)->GetActualLuck();
-        v63 = v61 + (*v57)->_48EA1B_get_static_effect(v62) + 30;
+        v63 = v61 + (*v57)->GetParameterBonus(v62) + 30;
         if ( rand() % v63 < 30 )
         {
           v64 = 6048;
@@ -3114,9 +3114,7 @@
     if ( (signed __int64)v2->pActorBuffs[3].uExpireTime <= 0 )
     {
       v12 = 0;
-      v11 = 0;
-      v10 = 0;
-      v9 = 0;
+     
       v8 = -1;
     }
     else
@@ -3142,12 +3140,10 @@
         v6 = 33075;
       }
       v12 = v6;
-      v11 = 0;
-      v10 = 0;
-      v9 = 0;
+      
       v8 = 0;
     }
-    pAudioPlayer->PlaySound((SoundID)(signed __int16)v3, PID(OBJECT_Actor, uActorID), 0, v8, v9, v10, v11, v12);
+    pAudioPlayer->PlaySound((SoundID)(signed __int16)v3, PID(OBJECT_Actor, uActorID), 0, v8, 0, 0, 0, v12);
   }
 }
 
@@ -3160,14 +3156,14 @@
   unsigned int v8; // ecx@1
   char v9; // zf@1
   AIDirection *v10; // esi@6
-  int v12; // ecx@19
-  unsigned int v13; // eax@19
+  //int v12; // ecx@19
+  //unsigned int v13; // eax@19
   AIDirection a3; // [sp+Ch] [bp-5Ch]@7
-  AIDirection v15; // [sp+28h] [bp-40h]@7
+  //AIDirection v15; // [sp+28h] [bp-40h]@7
   AIDirection v16; // [sp+44h] [bp-24h]@7
-  unsigned int v17; // [sp+60h] [bp-8h]@1
+  //unsigned int v17; // [sp+60h] [bp-8h]@1
   unsigned int v18; // [sp+64h] [bp-4h]@1
-  int v19; // [sp+70h] [bp+8h]@19
+  //int v19; // [sp+70h] [bp+8h]@19
 
   v5 = uActorID;
   v6 = 0;
@@ -3175,7 +3171,6 @@
   v18 = a2;
   v8 = PID(OBJECT_Actor,uActorID);
   v9 = v7->pMonsterInfo.uFlying == 0;
-  v17 = v5;
   if ( !v9 && !pParty->bFlying )
   {
     if ( v7->pMonsterInfo.uMissleAttack1Type )
@@ -3183,12 +3178,11 @@
     else
       v6 = pParty->uPartyHeight;
   }
+
   v10 = pDir;
   if ( !pDir )
   {
-    memcpy(&v15, Actor::GetDirectionInfo(v8, a2, &a3, v6), sizeof(v15));
-    memcpy(&v16, &v15, sizeof(v16));
-    v5 = v17;
+    memcpy(&v16, Actor::GetDirectionInfo(v8, a2, &a3, v6), sizeof(v16));
     v10 = &v16;
   }
   if ( MonsterStats::BelongsToSupertype(v7->pMonsterInfo.uID, MONSTER_SUPERTYPE_TREANT) )
@@ -3213,16 +3207,10 @@
   v18 = 16;
   if ( arg0 % 2 )
     v18 = -16;
-  v12 = ((unsigned __int64)(stru_5C6E00->Cos(v18 + stru_5C6E00->uIntegerPi + v10->uYawAngle) * (signed __int64)v10->uDistanceXZ) >> 16)
-      + pParty->vPosition.x;
-  v13 = stru_5C6E00->uIntegerPi + v10->uYawAngle;
-  v17 = v12;
-  v19 = stru_5C6E00->Sin(v18 + v13);
+
   v7->uYawAngle = stru_5C6E00->Atan2(
-                    v17 - v7->vPosition.x,
-                    pParty->vPosition.y
-                  + ((unsigned __int64)(v19 * (signed __int64)v10->uDistanceXZ) >> 16)
-                  - v7->vPosition.y);
+                    pParty->vPosition.x + fixpoint_sub0(stru_5C6E00->Cos(v18 + stru_5C6E00->uIntegerPi + v10->uYawAngle), v10->uDistanceXZ) - v7->vPosition.x,
+                    pParty->vPosition.y + fixpoint_sub0(stru_5C6E00->Sin(v18 + stru_5C6E00->uIntegerPi + v10->uYawAngle), v10->uDistanceXZ) - v7->vPosition.y);
   if ( uActionLength )
     v7->uCurrentActionLength = uActionLength;
   else
--- a/Arcomage.cpp	Thu May 23 21:36:57 2013 +0600
+++ b/Arcomage.cpp	Thu May 23 21:37:22 2013 +0600
@@ -267,7 +267,7 @@
     TranslateMessage(&pArcomageGame->msg);
     DispatchMessageA(&pArcomageGame->msg);
   }
-  if (pAsyncMouse)
+  /*if (pAsyncMouse)
   {
     EnterCriticalSection(&pGame->pThreadWardInstance->csAsyncMouse);
     v4 = *((unsigned int *)pAsyncMouse + 7);
@@ -297,7 +297,7 @@
     if ( !*((unsigned char *)pAsyncMouse + 90) )
       pArcomageGame->field_F6 = 1;
     LeaveCriticalSection(&pGame->pThreadWardInstance->csAsyncMouse);
-  }
+  }*/
   memcpy(v2, &pArcomageGame->stru1, 0xCu);
   return pArcomageGame->stru1.field_0 != 0;
 }
@@ -1423,11 +1423,7 @@
     ++v3;
   }
   while ( (signed int)v3 < (signed int)&unk_5052C8 );
-  if (pAsyncMouse)
-  {
-    pAsyncMouse->_409E3D(*((unsigned char *)pAsyncMouse + 103));
-    pAsyncMouse->_46B944();
-  }
+
   pArcomageGame->pGameBackground.Release();
   pArcomageGame->pSprites.Release();
   pArcomageGame->bGameInProgress = 0;
@@ -5754,8 +5750,6 @@
   int pXY[2]; // [sp+18h] [bp-Ch]@5
   int v10; // [sp+20h] [bp-4h]@3
 
-  if (pAsyncMouse)
-    pAsyncMouse->_409E3D(1);
   pAudioPlayer->StopChannels(-1, -1);
   strcpy(pArcomageGame->pPlayer1Name, pArcomagePlayer1Name);
   strcpy(pArcomageGame->pPlayer2Name, pArcomagePlayer2Name);
--- a/CShow.cpp	Thu May 23 21:36:57 2013 +0600
+++ b/CShow.cpp	Thu May 23 21:37:22 2013 +0600
@@ -9,9 +9,6 @@
 {
   if (bNoVideo) return;
 
-  if (pAsyncMouse)
-    pAsyncMouse->Suspend();
-
   switch (eVideo)
   {
     case MOVIE_3DOLogo: VideoPlayer::MovieLoop("3dologo", 0, 0, 1);        break;
@@ -26,9 +23,5 @@
       assert(false && "Invalid movie requested in " __FUNCTION__);
       break;
   }
-
-  if (bShowMouseAfterPlayback)
-    if (pAsyncMouse)
-      pAsyncMouse->Resume();
 }
 
--- a/Chest.cpp	Thu May 23 21:36:57 2013 +0600
+++ b/Chest.cpp	Thu May 23 21:37:22 2013 +0600
@@ -66,10 +66,10 @@
   char *v26; // edx@29
   unsigned __int16 v27; // ax@32
   //SpriteObject a1; // [sp+14h] [bp-B0h]@28
-  int v29; // [sp+84h] [bp-40h]@16
-  int v30; // [sp+88h] [bp-3Ch]@16
-  int v31; // [sp+8Ch] [bp-38h]@16
-  int v32; // [sp+90h] [bp-34h]@16
+  int v29[4]; // [sp+84h] [bp-40h]@16
+  //int v30; // [sp+88h] [bp-3Ch]@16
+  //int v31; // [sp+8Ch] [bp-38h]@16
+  //int v32; // [sp+90h] [bp-34h]@16
   float v33; // [sp+94h] [bp-30h]@23
   //char *v34; // [sp+98h] [bp-2Ch]@5
   int v35; // [sp+9Ch] [bp-28h]@16
@@ -105,10 +105,10 @@
     goto LABEL_12;
   if ( pPlayers[uActiveCharacter]->GetDisarmTrap() < 2 * pMapStats->pInfos[v2].LockX5 )
   {
-    v29 = 811;
-    v30 = 812;
-    v31 = 813;
-    v32 = 814;
+    v29[0] = 811;
+    v29[1] = 812;
+    v29[2] = 813;
+    v29[3] = 814;
     v5 = rand() % 4;
     v6 = PID_ID(EvtTargetObj);
     v35 = v5;
--- a/Events.cpp	Thu May 23 21:36:57 2013 +0600
+++ b/Events.cpp	Thu May 23 21:37:22 2013 +0600
@@ -6,6 +6,7 @@
 
 #include "MapInfo.h"
 #include "Game.h"
+#include "Outdoor.h"
 #include "GUIWindow.h"
 #include "GUIProgressBar.h"
 #include "Chest.h"
@@ -24,6 +25,7 @@
 #include "Events.h"
 #include "Events2D.h"
 #include "UIHouses.h"
+#include "Log.h"
 #include "MM7.h"
 
 
@@ -56,7 +58,7 @@
 
 //----- (00443CE1) --------------------------------------------------------
 unsigned int LoadEventsToBuffer(const char *pContainerName, char *pBuffer, unsigned int uBufferSize)
-	{
+{
 	FILE *pLodFile; // eax@1
 	unsigned int uTextureSize; // esi@3
 	char Args[60]; // [sp+8h] [bp-B4h]@6
@@ -109,6 +111,7 @@
 		pGlobalEVT_Index[events_count].event_sequence_num=current_hdr->evt_sequence_num;
 		pGlobalEVT_Index[events_count].uEventOffsetInEVT=offset_in;			
 		offset_in+=current_hdr->evt_size+1;
+
 		current_hdr=(raw_event_header *)&pGlobalEVT[offset_in];
 		}
 	uGlobalEVT_NumEvents = events_count;
@@ -117,6 +120,7 @@
 }
 
 
+
 //----- (00443EF8) --------------------------------------------------------
 void  LoadLevel_InitializeLevelEvt()
 	{
@@ -148,25 +152,117 @@
         pLevelEVT_Index[events_count].event_sequence_num=current_hdr->evt_sequence_num;
         pLevelEVT_Index[events_count].uEventOffsetInEVT=offset_in;			
         offset_in+=current_hdr->evt_size+1;
+
         current_hdr=(raw_event_header *)&pLevelEVT[offset_in];
         }
     uLevelEVT_NumEvents = events_count;
 
 /*
-	for (uint i = 0, j = 0; j < uLevelEVT_Size; ++i)
+EmeraldIsle::Variables:
+[0] ???
+[1] ???
+[2] Luck Fountain uses left
+[3] Gold Fountain used this week
+[4] Gold Fountain total uses
+
+Emerald Isle #111 // ???
+	OnLongTimer
+	Set(Map.Variables[0], 30)
+	Set(Map.Variables[1], 30)
+
+
+Emerald Isle #114 // month timer - manage luck fountain
+0		LocationName
+0	    if (Player.BaseLuck >= 15)
+		{
+2			SetFooterString(11) // Refreshing!
+3			return
+		}
+		else
+		{
+1			if (Map.Variables[2] >= 1)
+			{
+4				Sub(Map.Variables[2], 1)
+5				Add(Player.BaseLuck, 2)
+6				SetFooterString(25) // +2 Luck (Permament)
+7				return
+			}
+			else
+			{
+2				SetFooterString(11) // Refreshing!
+3				return
+			}
+		}
+
+8		Initialize
+9		Set	Map.Variables[2], 8
+
+
+
+Emerald Isle #115 // week timer - gold fountain in the center of town
+0	LocationName
+0	if (Map.Variables[4] < 3)
+	{
+1		if (Map.Variables[3] == 1)
 		{
-		pLevelEVT_Index[i].uEventID = pLevelEVT[j + 1] + ((unsigned short)pLevelEVT[j + 2] << 8);
-		pLevelEVT_Index[i].event_sequence_num = pLevelEVT[j + 3];
-		pLevelEVT_Index[i].uEventOffsetInEVT = j;
-		j += pLevelEVT[j] + 1;
-		uLevelEVT_NumEvents++;
-		}*/
+2			if (Party.Gold < 201)
+			{
+3				if (Player.BaseLuck >= 15)
+				{
+5					Add(Map.Variables[3], 1)
+6					Add(Party.Gold, 1000)
+7					Add(Map.Variables[4], 1)
+8					goto return
+				}
+				else
+				{
+4					goto 9
+				}
+			}
+		}
+	}
+9	SetFooterString(11)	// Refreshing!
+10	return
+
+11	Initialize
+12	Set(Map.Variables[3], 0)
+
+
+
+
+
+Emerald Isle #220	// day timer - monster spawner
+0	LocationName
+0	OnLongTimer
+1	if (NumAliveActors(group=20) != 0)
+2		return
+3	SpawnMonsters(1, level=1, count=10, x=-336, y=14512, z=0,  group=20)
+4	SpawnMonsters(1, level=2, count=5,  x=16,   y=16352, z=90, group=20)
+5	SpawnMonsters(1, level=1, count=10, x=480,  y=18288, z=6,  group=20)
+
+
+
+Emerald Isle #200	// margareth dock tip
+0	if (!QBits.QuestDone[17])
+	{
+1		InitiateNPCDialogue(npc=19)
+	}
+2	return
+
+
+Emerald Isle #201	// margareth armoury tip
+0	if (!QBits.QuestDone[17])
+	{
+1		InitiateNPCDialogue(npc=20)
+	}
+2	return
+*/
 	}
 
 
 //----- (0044684A) --------------------------------------------------------
-void  EventProcessor(int uEventID, int targetObj, int canShowMessages)
-	{
+void EventProcessor(int uEventID, int targetObj, int canShowMessages, int entry_line)
+{
 	unsigned int v3; // eax@5
 	signed int v4; // esi@7
 	//char *v5; // eax@8
@@ -320,7 +416,8 @@
 		return;
 		}
 	player_choose = (uActiveCharacter == 0)?6:4;  //4 - active or  6 - random player if active =0
-	curr_seq_num = start_event_seq_number;
+	curr_seq_num = entry_line;
+
 	if ( activeLevelDecoration )
 		{
 		uSomeEVT_NumEvents = uGlobalEVT_NumEvents;
@@ -356,11 +453,11 @@
 			case EVENT_CheckSeason:
 				//
 				if ( !sub_4465DF_check_season(_evt->v5) )
-					{
+                {
 					++curr_seq_num;
 					v4 = v124;
 					break;
-					}
+                }
 				v124 = -1;
 				curr_seq_num = _evt->v6 - 1;
 			    ++curr_seq_num;
@@ -375,8 +472,7 @@
 					pVideoPlayer->Unload();
 				pVideoPlayer->bStopBeforeSchedule = 0;
 				pVideoPlayer->pResetflag = 0;
-				if (pAsyncMouse)
-					pAsyncMouse->Suspend();
+
 				v128 = pCurrentScreen;
 				//v13 = &pSomeEVT[v9];
 				//v14 = (unsigned __int8)v13[5];
@@ -400,8 +496,7 @@
 						if ( v128 == 13 )
 							pVideoPlayer->OpenHouseMovie(pAnimatedRooms[uCurrentHouse_Animation].video_name, 1u);
 						}
-					if (pAsyncMouse)
-						pAsyncMouse->Resume();
+
 					++curr_seq_num;
 					v4 = v124;
 					
@@ -423,8 +518,6 @@
 						if ( v128 == 13 )
 							pVideoPlayer->OpenHouseMovie(pAnimatedRooms[uCurrentHouse_Animation].video_name, 1u);
 						}
-					if (pAsyncMouse)
-						pAsyncMouse->Resume();
 					++curr_seq_num;
 					v4 = v124;
 					
@@ -447,8 +540,6 @@
 					if ( v128 == 13 )
 						pVideoPlayer->OpenHouseMovie(pAnimatedRooms[uCurrentHouse_Animation].video_name, 1u);
 					}
-				if (pAsyncMouse)
-					pAsyncMouse->Resume();
 				++curr_seq_num;
 				v4 = v124;
 				
@@ -986,13 +1077,17 @@
 					pPlayer->AddVariable((enum VariableType)EVT_WORD(_evt->v5), pValue);
 				}
                 v83 = EVT_WORD(_evt->v5);
-                if ( v83 == 21 || v83 == 22 || v83 == 23 || v83 == 24 )
-                    viewparams->bRedrawGameUI = 1;
+                if (v83 == 21 ||  // gold well on emerald isle
+                    v83 == 22 || v83 == 23 || v83 == 24 )
+                {
+                  __debugbreak(); // find out what these decorations are
+                    viewparams->bRedrawGameUI = true;
+                }
                 ++curr_seq_num;
                 v4 = v124;
                 break;
 			case EVENT_InputString:
-				if ( !start_event_seq_number )
+				if ( !entry_line )
 					{
 					strcpy(GameUI_Footer_TimedString, &pLevelStr[pLevelStrOffsets[EVT_DWORD(_evt->v5 )]]);
 					v105 = curr_seq_num;
@@ -1037,7 +1132,7 @@
 					v115 = EVT_DWORD(_evt->v7 );
 					v89 = (unsigned __int8)v86;
 					v88 = &pParty->pPlayers[v89];
-					v88->ReceiveDamage(v115, v119);
+					v88->ReceiveDamage(v115, (DAMAGE_TYPE)v119);
 					++curr_seq_num;
 					v4 = v124;
 					break;
@@ -1056,7 +1151,7 @@
 					v119 = _evt->v6;
 					v88 = pPlayers[uActiveCharacter];
 					v115 = EVT_DWORD(_evt->v7 );
-					v88->ReceiveDamage(v115, v119);
+					v88->ReceiveDamage(v115, (DAMAGE_TYPE)v119);
 					++curr_seq_num;
 					v4 = v124;
 					break;
@@ -1067,7 +1162,7 @@
 					v115 = EVT_DWORD(_evt->v7 );
 					v89 = rand() % 4;
 					v88 = &pParty->pPlayers[v89];
-					v88->ReceiveDamage(v115, v119);
+					v88->ReceiveDamage(v115, (DAMAGE_TYPE)v119);
 					++curr_seq_num;
 					v4 = v124;
 					
@@ -1078,7 +1173,7 @@
 				v87 = pParty->pPlayers;
 				do
 					{
-					v87->ReceiveDamage(v85, _evt->v6);
+					v87->ReceiveDamage(v85, (DAMAGE_TYPE)_evt->v6);
 					++v87;
 					}
 					while ( (signed int)v87 < (signed int)pParty->pHirelings );
--- a/Events.h	Thu May 23 21:36:57 2013 +0600
+++ b/Events.h	Thu May 23 21:37:22 2013 +0600
@@ -99,7 +99,7 @@
   EVENT_ForPartyMember = 0x23,
   EVENT_Jmp = 0x24,
   EVENT_OnMapReload = 0x25,
-  EVENT_OnLongTimer = 0x26,
+  EVENT_Initialize = 0x26,
   EVENT_SetNPCTopic = 0x27,
   EVENT_MoveNPC = 0x28,
   EVENT_GiveItem = 0x29,
@@ -256,7 +256,12 @@
   VAR_Stoned = 0x78,
   VAR_Eradicated = 0x79,
   VAR_MajorCondition = 0x7A,
-  VAR_MapPersistentVariable_0 = 0x7B,
+  VAR_MapPersistentVariable_0 = 123,
+  VAR_MapPersistentVariable_1 = 124,
+  VAR_MapPersistentVariable_2 = 125,
+  VAR_MapPersistentVariable_3 = 126,
+  VAR_MapPersistentVariable_4 = 127,
+  VAR_MapPersistentVariable_5 = 0x80,
   VAR_NPCs = 0xD6,
   VAR_Reputation = 0xD7,
   VAR_ActiveSpells = 0xDE,
@@ -321,9 +326,9 @@
 
 
 unsigned int LoadEventsToBuffer(const char *pContainerName, char *pBuffer, unsigned int uBufferSize);
-void  Initialize_GlobalEVT();
-void  LoadLevel_InitializeLevelEvt();
-void  EventProcessor(int uEventID, int a2, int a3);
+void Initialize_GlobalEVT();
+void LoadLevel_InitializeLevelEvt();
+void EventProcessor(int uEventID, int a2, int a3, int entry_line = 0);
 
 
 
--- a/GUIProgressBar.cpp	Thu May 23 21:36:57 2013 +0600
+++ b/GUIProgressBar.cpp	Thu May 23 21:37:22 2013 +0600
@@ -43,8 +43,6 @@
   }
 
   //v2 = this;
-  if (pAsyncMouse)
-    pAsyncMouse->Suspend();
   if (pLoadingBg.pPixels)
     return false;
 
@@ -145,8 +143,6 @@
   int v3; // edi@7
 
   v1 = this;
-  if (pAsyncMouse)
-    pAsyncMouse->Resume();
   if ( v1->uType == 1 )
   {
     if ( !v1->pLoadingBg.pPixels )
--- a/GUIWindow.cpp	Thu May 23 21:36:57 2013 +0600
+++ b/GUIWindow.cpp	Thu May 23 21:37:22 2013 +0600
@@ -35,6 +35,22 @@
 struct GUIMessageQueue *pMessageQueue_50CBD0 = new GUIMessageQueue;
 struct GUIMessageQueue *pMessageQueue_50C9E8 = new GUIMessageQueue;
 
+
+
+
+
+
+
+//----- (004141CA) --------------------------------------------------------
+void ModalWindow(const char *pStr, int a4)
+{
+  pEventTimer->Pause();
+  dword_506F0C[0] = pCurrentScreen;
+  ptr_507BDC = GUIWindow::Create(0, 0, 640, 480, WINDOW_FinalWindow, a4, (int)pStr);
+  pCurrentScreen = SCREEN_PRESS_ESCAPE_MESSAGE;
+}
+// 4E28F8: using guessed type int pCurrentScreen;
+
 // inlined
 //----- (mm6c::00420520) --------------------------------------------------
 void GUIMessageQueue::Flush()
@@ -296,7 +312,7 @@
 		{
 		pIcons_LOD->SyncLoadedFilesCount();
 		pCurrentScreen = pMainScreenNum;
-		pKeyActionMap->_459ED1(3);
+		pKeyActionMap->SetWindowInputStatus(3);
 		break;
 		}
 	case WINDOW_HouseInterior:
--- a/GUIWindow.h	Thu May 23 21:36:57 2013 +0600
+++ b/GUIWindow.h	Thu May 23 21:37:22 2013 +0600
@@ -307,6 +307,12 @@
 struct GUIButton;
 struct Texture;
 
+
+#define WINDOW_INPUT_NONE        0
+#define WINDOW_INPUT_IN_PROGRESS 1
+#define WINDOW_INPUT_CONFIRMED   2
+#define WINDOW_INPUT_CANCELLED   3
+
 /*  155 */
 #pragma pack(push, 1)
 struct GUIWindow
@@ -354,7 +360,7 @@
   int field_34;
   int pStartingPosActiveItem;
   int numVisibleWindows;
-  int field_40;
+  int receives_keyboard_input_2; //  0  no input   1 currently typing   2 enter pressed   3 escape pressed
   int receives_keyboard_input;
   char *Hint;
   GUIButton *pControlsHead;
@@ -543,7 +549,7 @@
 void InitializeBookFonts();
 void DrawSpellBookContent(Player *player);
 unsigned int __cdecl DrawLloydBeaconsScreen();
-void DrawTownPortalScreen();
+void BookUI_DrawTownPortalMap();
 void LoadSpellbook(unsigned int uID); // idb
 void DrawSpellDescriptionPopup(int spell_index);
 void sub_41140B();
--- a/Game.cpp	Thu May 23 21:36:57 2013 +0600
+++ b/Game.cpp	Thu May 23 21:37:22 2013 +0600
@@ -319,10 +319,7 @@
     dword_6BE340 = 2;
     // uGame_if_0_else_ui_id__11_save__else_load__8_drawSpellInfoPopup__22_final_window__26_keymapOptions__2_options__28_videoOptions = 0;
     pCurrentScreen = SCREEN_GAME;
-    if (pAsyncMouse)
-      pAsyncMouse->Resume();
-    if (pGame->pKeyboardInstance->bUsingAsynKeyboard && pAsyncKeyboard )
-      pAsyncKeyboard->Resume();
+
     if ( pRenderer->pRenderD3D )
       pGame->pVisInstance->_4C1A02();
 
@@ -351,8 +348,6 @@
         pRenderer->Present();
         continue;
       }
-      if (pAsyncMouse)
-        pAsyncMouse->_46B736_consume_click_lists(1);
       if ( pVideoPlayer->pSmackerMovie && !SmackWait(pVideoPlayer->pSmackerMovie) )
       {
         pRenderer->BeginScene();
@@ -760,10 +755,7 @@
 {
   struct tagRECT Rect; // [sp+0h] [bp-10h]@6
 
-  if (pAsyncMouse)
-    pAsyncMouse->Suspend();
-  if (pGame->pKeyboardInstance->bUsingAsynKeyboard && pAsyncKeyboard)
-    pAsyncKeyboard->Suspend();
+
   WriteWindowsRegistryInt("startinwindow", pRenderer->bWindowMode);
   if ( GetWindowRect(hWnd, &Rect) && pRenderer->bWindowMode )
   {
@@ -773,10 +765,7 @@
   WriteWindowsRegistryInt("valAlwaysRun", bAlwaysRun);
   pItemsTable->Release();
   pNPCStats->Release();
-  if (pAsyncKeyboard)
-    pAsyncKeyboard->Release();
-  if (pAsyncMouse)
-    pAsyncMouse->Release();
+
   if (pMouse)
     pMouse->Deactivate();
 
--- a/Items.h	Thu May 23 21:36:57 2013 +0600
+++ b/Items.h	Thu May 23 21:37:22 2013 +0600
@@ -1,6 +1,18 @@
 #pragma once
 
-
+enum DAMAGE_TYPE:unsigned int
+    {
+    DMGT_FIRE   = 0,
+    DMGT_ELECTR = 1,
+    DMGT_COLD   = 2,
+    DMGT_3      = 3,
+    DMGT_PHISYCAL= 4,
+    DMGT_5      = 5,
+    DMGT_SPIRIT = 6,
+    DMGT_MIND   = 7,
+    DMGT_BODY   = 8,
+    DMGT_DARK   =10
+    };
 
 
 
--- a/Keyboard.cpp	Thu May 23 21:36:57 2013 +0600
+++ b/Keyboard.cpp	Thu May 23 21:37:22 2013 +0600
@@ -113,7 +113,7 @@
 }
 
 //----- (00459E5A) --------------------------------------------------------
-void KeyboardActionMapping::EnterText(int a2, int pNumWord, GUIWindow *pWindow)
+void KeyboardActionMapping::EnterText(int a2, int max_string_len, GUIWindow *pWindow)
 {
   KeyboardActionMapping *v4; // esi@1
 
@@ -124,29 +124,17 @@
     v4->field_204 = 2;
   else
     v4->field_204 = 1;
-  v4->field_FC = pNumWord;
+  v4->max_input_string_len = max_string_len;
   v4->pWindow = pWindow;
-  pWindow->field_40 = 1;
-  if ( LOBYTE(pGame->pKeyboardInstance->bUsingAsynKeyboard) )
-  {
-    if ( pAsyncKeyboard )
-      pAsyncKeyboard->Suspend();
-  }
+  pWindow->receives_keyboard_input_2 = WINDOW_INPUT_IN_PROGRESS;
 }
 
 //----- (00459ED1) --------------------------------------------------------
-void KeyboardActionMapping::_459ED1(int a2)
+void KeyboardActionMapping::SetWindowInputStatus(int a2)
 {
-  KeyboardActionMapping *v2; // esi@1
-  GUIWindow *v3; // esi@4
-
-  v2 = this;
-  if (pGame->pKeyboardInstance->bUsingAsynKeyboard && pAsyncKeyboard)
-    pAsyncKeyboard->Resume();
-  v2->field_204 = 0;
-  v3 = v2->pWindow;
-  if ( v3 )
-    v3->field_40 = a2;
+  field_204 = 0;
+  if ( pWindow )
+    pWindow->receives_keyboard_input_2 = a2;
 }
 
 //----- (00459F10) --------------------------------------------------------
@@ -167,7 +155,7 @@
           goto LABEL_3;
         if ( a2 == 27 )
           goto LABEL_15;
-        if ( this->uNumKeysPressed >= this->field_FC )
+        if ( this->uNumKeysPressed >= this->max_input_string_len )
           return 1;
         pKeyActionMap->pPressedKeysBuffer[pKeyActionMap->uNumKeysPressed] = a2;
         ++pKeyActionMap->uNumKeysPressed;
@@ -188,7 +176,7 @@
         {
           if ( (signed int)a2 >= 48 && (signed int)a2 <= 57 )
           {
-            if ( pKeyActionMap->uNumKeysPressed < this->field_FC )
+            if ( pKeyActionMap->uNumKeysPressed < this->max_input_string_len )
             {
               pKeyActionMap->pPressedKeysBuffer[pKeyActionMap->uNumKeysPressed] = a2;
               ++pKeyActionMap->uNumKeysPressed;
@@ -212,7 +200,7 @@
 LABEL_3:
   v3 = 2;
 LABEL_4:
-  pKeyActionMap->_459ED1(v3);
+  pKeyActionMap->SetWindowInputStatus(v3);
   return 1;
 }
 // 506E68: using guessed type int uGameMenuUI_CurentlySelectedKeyIdx;
@@ -651,7 +639,7 @@
   const char *v28; // eax@1
   const char *v29; // eax@1
 
-  v2 = GetVKeyDisplayName(this->pVirtualKeyCodesMapping[0]);
+  v2 = GetVKeyDisplayName(pVirtualKeyCodesMapping[0]);
   WriteWindowsRegistryString("KEY_FORWARD", v2);
   v3 = GetVKeyDisplayName(pVirtualKeyCodesMapping[1]);
   WriteWindowsRegistryString("KEY_BACKWARD", v3);
@@ -948,893 +936,22 @@
 //----- (0045B019) --------------------------------------------------------
 void Keyboard::EnterCriticalSection()
 {
-  if (bUsingAsynKeyboard)
-    AsyncKeyboard::EnterCriticalSection();
 }
 
 //----- (0045B06E) --------------------------------------------------------
 bool Keyboard::IsShiftHeld()
 {
-  if (bUsingAsynKeyboard)
-  {
-    if ( pAsyncKeyboard->_45B4EC(0x2Au) )
-    {
-      return true;
-    }
-    return pAsyncKeyboard->_45B4EC(0x36u) != 0;
-  }
-  else
-    return GetAsyncKeyState(VK_SHIFT);
+  return GetAsyncKeyState(VK_SHIFT);
 }
 
 //----- (0045B0A9) --------------------------------------------------------
 bool Keyboard::IsKeyBeingHeld(int vKey)
 {
-  void *v2; // esi@2
-  char v3; // bl@2
-  bool result;
-
-  if (bUsingAsynKeyboard)
-  {
-    __debugbreak();
-    /*
-    v2 = pAsyncKeyboard;
-    EnterCriticalSection(&pGame->pThreadWardInstance->csAsyncKeyboard);
-    v3 = *((unsigned char *)v2 + (unsigned __int8)AsyncKeyboard::map_key(v2, vKey) + 265) >> 7;
-    LeaveCriticalSection(&pGame->pThreadWardInstance->csAsyncKeyboard);
-    return v3;*/
-  }
-  else
-    //return (GetAsyncKeyState(vKey) & 0x8001) != 0;
-    result = GetAsyncKeyState(vKey);
-  return result;
+  return GetAsyncKeyState(vKey) & 0x8001;
 }
 
 //----- (0045B0CE) --------------------------------------------------------
 bool Keyboard::WasKeyPressed(int vKey)
 {
-  void *v2; // esi@2
-  char v3; // bl@2
-  bool result; // eax@2
-
-  if ( this->bUsingAsynKeyboard )
-  {
-    __debugbreak();
-    /*v2 = pAsyncKeyboard;
-    EnterCriticalSection(&pGame->pThreadWardInstance->csAsyncKeyboard);
-    v3 = *((unsigned char *)v2 + (unsigned __int8)AsyncKeyboard::map_key(v2, vKey) + 521) >> 7;
-    LeaveCriticalSection(&pGame->pThreadWardInstance->csAsyncKeyboard);
-    LOBYTE(result) = v3;*/
-  }
-  else
-  {
-    result = GetAsyncKeyState(vKey);
-    //LOBYTE(result) = result & 1;
-  }
-  return result;
-}
-
-//----- (0045B10A) --------------------------------------------------------
-AsyncKeyboard::AsyncKeyboard()
-{
-  *(unsigned int *)(this + 4) = 0;
-  *(unsigned char *)(this + 8) = 0;
-
-  if (!Initialize())
-    MessageBoxW(nullptr, L"Could not initialize asynchronos keyboard object", nullptr, 0);
-}
-// 4D86B8: using guessed type int (__stdcall *AsyncKeyboard_pvdtor)(char);
-// 4DBD94: using guessed type int dword_4DBD94;
-
-
-//----- (0045B15E) --------------------------------------------------------
-AsyncKeyboard::~AsyncKeyboard()
-{
-  __debugbreak();
-  /*
-  void *v1; // esi@1
-  char *v2; // edi@1
-  int v3; // ecx@1
-
-  v1 = this;
-  v2 = (char *)this + 1804;
-  v3 = *((unsigned int *)this + 451);
-  if ( v3 )
-    (**(void (__stdcall ***)(unsigned int))v3)(1);
-  *(unsigned int *)v2 = 0;
-  return TerminateThread(*((HANDLE *)v1 + 1), 0x1F4u);*/
-}
-// 4D86B8: using guessed type int (__stdcall *AsyncKeyboard_pvdtor)(char);
-
-//----- (0045B18E) --------------------------------------------------------
-bool AsyncKeyboard::Initialize()
-{
-  _45B1B1();
-  if (_45B229())
-    return CreateDirectInputKeyboard() != 0;
-  return false;
-}
-
-//----- (0045B1B1) --------------------------------------------------------
-void AsyncKeyboard::_45B1B1()
-{
-  void *v1; // esi@1
-
-  v1 = this;
-  memset((char *)this + 9, 0, 0x100u);
-  memset((char *)v1 + 265, 0, 0x100u);
-  memset((char *)v1 + 521, 0, 0x100u);
-  memset((char *)v1 + 780, 0, 0x400u);
-}
-
-//----- (0045B1FD) --------------------------------------------------------
-void AsyncKeyboard::EnterCriticalSection()
-{
-  __debugbreak();
-  //EnterCriticalSection(&pGame->pThreadWardInstance->csAsyncKeyboard);
-}
-
-//----- (0045B213) --------------------------------------------------------
-void AsyncKeyboard::LeaveCriticalSection()
-{
-  __debugbreak();
-  //LeaveCriticalSection(&pGame->pThreadWardInstance->csAsyncKeyboard);
-}
-
-//----- (0045B229) --------------------------------------------------------
-char AsyncKeyboard::_45B229()
-{
-  __debugbreak();
-  return 0;
-  /*void *v1; // esi@1
-  HANDLE v2; // eax@1
-  char result; // al@2
-  DWORD ThreadId; // [sp+0h] [bp-4h]@1
-
-  ThreadId = (DWORD)this;
-  v1 = this;
-  v2 = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)AsyncKeyboardThread, this, 4u, &ThreadId);
-  *((unsigned int *)v1 + 1) = v2;
-  if ( v2 )
-    result = SetThreadPriority(v2, 15) != 0;
-  else
-    result = 0;
-  return result;*/
-}
-
-//----- (0045B260) --------------------------------------------------------
-char AsyncKeyboard::CreateDirectInputKeyboard()
-{
-  __debugbreak();
-  return 0;
-  /*v1 = this;
-  v2 = new DirectInputKeyboard;
-  *((void **)v1 + 451) = v2;
-
-  return v2 != 0;*/
-}
-
-//----- (0045B2A7) --------------------------------------------------------
-void AsyncKeyboard::Resume()
-{
-  __debugbreak();
-  /*void *v1; // esi@1
-  std::string v2; // [sp-18h] [bp-24h]@2
-  const char *v3; // [sp-8h] [bp-14h]@2
-  int v4; // [sp-4h] [bp-10h]@2
-  std::string *v5; // [sp+4h] [bp-8h]@2
-  int a3; // [sp+Bh] [bp-1h]@2
-
-  v1 = this;
-  if ( *((unsigned int *)this + 451) )
-  {
-    EnterCriticalSection(&pGame->pThreadWardInstance->csAsyncKeyboard);
-    _45B1B1();
-    DirectInputKeyboard::set_acquire(*((DirectInputKeyboard **)v1 + 451), (int *)1);
-    ResumeThread(*((HANDLE *)v1 + 1));
-    LeaveCriticalSection(&pGame->pThreadWardInstance->csAsyncKeyboard);
-  }
-  else
-  {
-    MessageBoxW(nullptr, L"Invalid DI_Keyboard, bailing out of resume()", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\KeyboardAsync.cpp:97", 0);
-  }*/
-}
-
-//----- (0045B329) --------------------------------------------------------
-void AsyncKeyboard::Suspend()
-{
-  __debugbreak();
-  /*void *v1; // esi@1
-  std::string v2; // [sp-18h] [bp-24h]@2
-  const char *v3; // [sp-8h] [bp-14h]@2
-  int v4; // [sp-4h] [bp-10h]@2
-  std::string *v5; // [sp+4h] [bp-8h]@2
-  int a3; // [sp+Bh] [bp-1h]@2
-
-  v1 = this;
-  if ( *((unsigned int *)this + 451) )
-  {
-    EnterCriticalSection(&pGame->pThreadWardInstance->csAsyncKeyboard);
-    SuspendThread(*((HANDLE *)v1 + 1));
-    DirectInputKeyboard::set_acquire(*((DirectInputKeyboard **)v1 + 451), 0);
-    LeaveCriticalSection(&pGame->pThreadWardInstance->csAsyncKeyboard);
-  }
-  else
-  {
-    MessageBoxW(nullptr, L"Invalid DI_Keyboard, bailing out of suspend()", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\KeyboardAsync.cpp:115", 0);
-  }*/
-}
-
-//----- (0045B3A4) --------------------------------------------------------
-char AsyncKeyboard::_45B3A4()
-{
-  __debugbreak();
-  return 0;
-  /**((unsigned char *)this + 8) = 1;
-  Sleep(0x85u);
-  return 1;*/
-}
-
-
-//----- (00465C53) --------------------------------------------------------
-void AsyncKeyboard::Release()
-{
-  __debugbreak();
-  /*if ( LOBYTE(pGame->pKeyboardInstance->bUsingAsynKeyboard) )
-  {
-    if ( pAsyncKeyboard )
-    {
-      pAsyncKeyboard->Suspend();
-      if ( pAsyncKeyboard )
-        (**(void (__stdcall ***)(int))pAsyncKeyboard)(1);
-    }
-    pAsyncKeyboard = 0;
-  }*/
-}
-
-//----- (0045B3B6) --------------------------------------------------------
-void AsyncKeyboard::Thread()
-{
-  __debugbreak();
-  /*void *v1; // esi@1
-  signed int v2; // ecx@3
-  int v3; // eax@3
-  DWORD v4; // edx@6
-  std::string v5; // [sp-18h] [bp-2Ch]@2
-  const char *v6; // [sp-8h] [bp-1Ch]@2
-  int v7; // [sp-4h] [bp-18h]@2
-  DWORD v8; // [sp+Ch] [bp-8h]@2
-  int a3; // [sp+13h] [bp-1h]@2
-
-  v1 = this;
-  if ( *((unsigned int *)this + 451) )
-  {
-    ::EnterCriticalSection(&pGame->pThreadWardInstance->csAsyncKeyboard);
-    v8 = timeGetTime();
-    memcpy((char *)v1 + 9, (const void *)(*((unsigned int *)v1 + 451) + 29), 0x100u);
-    (*((DirectInputKeyboard **)v1 + 451)->_43B8EC();
-    memcpy((char *)v1 + 265, (const void *)(*((unsigned int *)v1 + 451) + 29), 0x100u);
-    v2 = 0;
-    v3 = (int)((char *)v1 + 780);
-    do
-    {
-      if ( *((unsigned char *)v1 + v2 + 265) & 0x80 )
-      {
-        if ( v8 - *(unsigned int *)v3 > 0xC8 )
-        {
-          v4 = v8;
-          *((unsigned char *)v1 + v2 + 521) |= 0x80u;
-          *(unsigned int *)v3 = v4;
-        }
-      }
-      ++v2;
-      v3 += 4;
-    }
-    while ( v2 < 256 );
-    ::LeaveCriticalSection(&pGame->pThreadWardInstance->csAsyncKeyboard);
-  }
-  else
-  {
-    MessageBoxW(nullptr, L"Invalid DI_Keyboard, bailing out of update_keyboard_data()", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\KeyboardAsync.cpp:169", 0);
-  }*/
-}
-
-//----- (0045B4EC) --------------------------------------------------------
-char AsyncKeyboard::_45B4EC(unsigned __int8 a2)
-{
-  __debugbreak();
-  return 0;
-  /*void *v2; // esi@1
-  char v3; // bl@1
-
-  v2 = this;
-  EnterCriticalSection(&pGame->pThreadWardInstance->csAsyncKeyboard);
-  v3 = *((unsigned char *)v2 + a2 + 265) >> 7;
-  LeaveCriticalSection(&pGame->pThreadWardInstance->csAsyncKeyboard);
-  return v3;*/
+  return GetAsyncKeyState(vKey) & 1;
 }
-
-//----- (0045B57D) --------------------------------------------------------
-char AsyncKeyboard::map_key(int key)
-{
-  __debugbreak();
-  return 0;
-  /*char result; // al@2
-  std::string v3; // [sp-18h] [bp-1Ch]@99
-  const char *v4; // [sp-8h] [bp-Ch]@99
-  int v5; // [sp-4h] [bp-8h]@99
-  void *v6; // [sp+0h] [bp-4h]@1
-
-  v6 = this;
-  switch ( key )
-  {
-    case 8:
-      result = 14;
-      break;
-    case 9:
-      result = 15;
-      break;
-    case 13:
-      result = 28;
-      break;
-    case 16:
-    case 161:
-      result = 54;
-      break;
-    case 160:
-      result = 42;
-      break;
-    case 17:
-    case 163:
-      result = -99;
-      break;
-    case 162:
-      result = 29;
-      break;
-    case 18:
-      result = -72;
-      break;
-    case 20:
-      result = 58;
-      break;
-    case 21:
-      result = 112;
-      break;
-    case 25:
-      result = -108;
-      break;
-    case 27:
-      result = 1;
-      break;
-    case 28:
-      result = 121;
-      break;
-    case 29:
-      result = 123;
-      break;
-    case 32:
-      result = 57;
-      break;
-    case 33:
-      result = -55;
-      break;
-    case 34:
-      result = -47;
-      break;
-    case 35:
-      result = -49;
-      break;
-    case 36:
-      result = -57;
-      break;
-    case 37:
-      result = -53;
-      break;
-    case 38:
-      result = -56;
-      break;
-    case 39:
-      result = -51;
-      break;
-    case 40:
-      result = -48;
-      break;
-    case 42:
-      result = -73;
-      break;
-    case 45:
-      result = -46;
-      break;
-    case 46:
-      result = -45;
-      break;
-    case 48:
-      result = 11;
-      break;
-    case 49:
-      result = 2;
-      break;
-    case 50:
-      result = 3;
-      break;
-    case 51:
-      result = 4;
-      break;
-    case 52:
-      result = 5;
-      break;
-    case 53:
-      result = 6;
-      break;
-    case 54:
-      result = 7;
-      break;
-    case 55:
-      result = 8;
-      break;
-    case 56:
-      result = 9;
-      break;
-    case 57:
-      result = 10;
-      break;
-    case 65:
-      result = 30;
-      break;
-    case 66:
-      result = 48;
-      break;
-    case 67:
-      result = 46;
-      break;
-    case 68:
-      result = 32;
-      break;
-    case 69:
-      result = 18;
-      break;
-    case 70:
-      result = 33;
-      break;
-    case 71:
-      result = 34;
-      break;
-    case 72:
-      result = 35;
-      break;
-    case 73:
-      result = 23;
-      break;
-    case 74:
-      result = 36;
-      break;
-    case 75:
-      result = 37;
-      break;
-    case 76:
-      result = 38;
-      break;
-    case 77:
-      result = 50;
-      break;
-    case 78:
-      result = 49;
-      break;
-    case 79:
-      result = 24;
-      break;
-    case 80:
-      result = 25;
-      break;
-    case 81:
-      result = 16;
-      break;
-    case 82:
-      result = 19;
-      break;
-    case 83:
-      result = 31;
-      break;
-    case 84:
-      result = 20;
-      break;
-    case 85:
-      result = 22;
-      break;
-    case 86:
-      result = 47;
-      break;
-    case 87:
-      result = 17;
-      break;
-    case 88:
-      result = 45;
-      break;
-    case 89:
-      result = 21;
-      break;
-    case 90:
-      result = 44;
-      break;
-    case 91:
-      result = -37;
-      break;
-    case 92:
-      result = -36;
-      break;
-    case 93:
-      result = -35;
-      break;
-    case 96:
-      result = 82;
-      break;
-    case 97:
-      result = 79;
-      break;
-    case 98:
-      result = 80;
-      break;
-    case 99:
-      result = 81;
-      break;
-    case 100:
-      result = 75;
-      break;
-    case 101:
-      result = 76;
-      break;
-    case 102:
-      result = 77;
-      break;
-    case 103:
-      result = 71;
-      break;
-    case 104:
-      result = 72;
-      break;
-    case 105:
-      result = 73;
-      break;
-    case 106:
-      result = 55;
-      break;
-    case 107:
-      result = 78;
-      break;
-    case 109:
-      result = 74;
-      break;
-    case 110:
-      result = 83;
-      break;
-    case 111:
-      result = -75;
-      break;
-    case 112:
-      result = 59;
-      break;
-    case 113:
-      result = 60;
-      break;
-    case 114:
-      result = 61;
-      break;
-    case 115:
-      result = 62;
-      break;
-    case 116:
-      result = 63;
-      break;
-    case 117:
-      result = 64;
-      break;
-    case 118:
-      result = 65;
-      break;
-    case 119:
-      result = 66;
-      break;
-    case 120:
-      result = 67;
-      break;
-    case 121:
-      result = 68;
-      break;
-    case 122:
-      result = 87;
-      break;
-    case 123:
-      result = 88;
-      break;
-    case 124:
-      result = 100;
-      break;
-    case 125:
-      result = 101;
-      break;
-    case 126:
-      result = 102;
-      break;
-    case 144:
-      result = 69;
-      break;
-    case 145:
-      result = 70;
-      break;
-    default:
-      MessageBoxW(nullptr, L"Uknown key detected!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\KeyboardAsync.cpp:999", 0);
-      goto LABEL_100;
-    case 1:
-    case 2:
-    case 3:
-    case 4:
-    case 12:
-    case 19:
-    case 23:
-    case 24:
-    case 30:
-    case 31:
-    case 41:
-    case 43:
-    case 44:
-    case 47:
-    case 108:
-    case 127:
-    case 128:
-    case 129:
-    case 130:
-    case 131:
-    case 132:
-    case 133:
-    case 134:
-    case 135:
-LABEL_100:
-      result = -1;
-      break;
-  }
-  return result;*/
-}
-
-//----- (0045BA60) --------------------------------------------------------
-int __stdcall AsyncKeyboard::ThreadStarter(AsyncKeyboard *pInstance)
-{
-  __debugbreak();
-  return 0;
-  /*while ( 1 )
-  {
-    while ( !pAsyncKeyboard )
-      ;
-    if ( *((unsigned char *)pAsyncKeyboard + 8) )
-      ExitThread(0);
-    pAsyncKeyboard->Thread();
-    Sleep(0x21u);
-  }*/
-}
-
-
-
-
-
-
-
-
-/*
-//----- (0043B76D) --------------------------------------------------------
-DirectInputKeyboard *__thiscall DirectInputKeyboard::DirectInputKeyboard(DirectInputKeyboard *this)
-{
-  DirectInputKeyboard *v1; // esi@1
-  HRESULT v2; // eax@5
-  unsigned int uVersion; // [sp-18h] [bp-20h]@3
-  IDirectInput **ppDirectInput; // [sp-14h] [bp-1Ch]@3
-  int v6; // [sp-10h] [bp-18h]@3
-  const char *v7; // [sp-Ch] [bp-14h]@3
-  int v8; // [sp-8h] [bp-10h]@3
-  unsigned int v9; // [sp-4h] [bp-Ch]@3
-  CheckHRESULT_stru0 v10; // [sp+4h] [bp-4h]@5
-
-  v1 = this;
-  this->field_8 = 0;
-  LOBYTE(this->field_1C) = 0;
-  this->vdestructor_ptr = &pDirectInputKeyboard_pvdtor;
-  if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion != 4 )
-  {
-    v9 = 1;
-    v8 = 28;
-    v7 = "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\DirectInputKeyboard.cpp";
-    v6 = 0;
-    ppDirectInput = &this->pDirectInput;
-    uVersion = 0x500u;
-  }
-  else
-  {
-    v9 = 1;
-    v8 = 26;
-    v7 = "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\DirectInputKeyboard.cpp";
-    v6 = 0;
-    ppDirectInput = &this->pDirectInput;
-    uVersion = 0x300u;
-  }
-  v2 = DirectInputCreateA(hInstance, uVersion, ppDirectInput, v6);
-  CheckHRESULT(&v10, v2, v7, v8, v9);
-  DirectInputKeyboard::CreateDevice(v1);
-  DirectInputKeyboard::43B87B(v1);
-  return v1;
-}
-// 4C8880: using guessed type int __stdcall DirectInputCreateA(int, int, int, int);
-
-//----- (0043B7E3) --------------------------------------------------------
-void __thiscall DirectInputKeyboard::vdtor(DirectInputKeyboard *this, bool a2)
-{
-  void *v2; // esi@1
-
-  v2 = this;
-  DirectInputKeyboard::dtor(this);
-  if ( a2 & 1 )
-    free(v2);
-}
-
-//----- (0043B7FF) --------------------------------------------------------
-void __thiscall DirectInputKeyboard::dtor(DirectInputKeyboard *this)
-{
-  DirectInputKeyboard *v1; // esi@1
-  int v2; // eax@1
-
-  v1 = this;
-  v2 = this->field_8;
-  this->vdestructor_ptr = &pDirectInputKeyboard_pvdtor;
-  if ( v2 )
-  {
-    (*(void (__stdcall **)(int))(*(int *)v2 + 32))(v2);
-    (*(void (__stdcall **)(int))(*(int *)v1->field_8 + 8))(v1->field_8);
-    v1->field_8 = 0;
-  }
-  v1->pDirectInput->lpVtbl->Release(v1->pDirectInput);
-  v1->pDirectInput = 0;
-}
-
-//----- (0043B831) --------------------------------------------------------
-void __thiscall DirectInputKeyboard::CreateDevice(DirectInputKeyboard *this)
-{
-  DirectInputKeyboard *v1; // esi@1
-  HRESULT v2; // eax@1
-  int v3; // [sp+4h] [bp-4h]@1
-
-  v1 = this;
-  v2 = ((int (__stdcall *)(IDirectInput *, signed int, int (__stdcall *)(int, int), DirectInputKeyboard *, signed int))this->pDirectInput->lpVtbl->field_10)(
-         this->pDirectInput,
-         3,
-         DirectInputKeyboard_enumerator_43B9B9,
-         this,
-         1);
-  CheckHRESULT((CheckHRESULT_stru0 *)&v3, v2, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\DirectInputKeyboard.cpp", 52, 1u);
-  if ( !LOBYTE(v1->field_1C) )
-  {
-    v3 = (int)"Error: No keyboard found";
-    _CxxThrowException((int)&v3, (int)&dword_4DBD94);
-  }
-}
-// 43B9B9: using guessed type int __stdcall DirectInputKeyboard_enumerator_43B9B9(int, int);
-// 4DBD94: using guessed type int dword_4DBD94;
-
-//----- (0043B87B) --------------------------------------------------------
-void __thiscall DirectInputKeyboard::43B87B(DirectInputKeyboard *ecx0)
-{
-  char *v1; // esi@1
-  HRESULT v2; // eax@1
-  HRESULT v3; // eax@1
-  HRESULT v4; // eax@1
-  unsigned int v5; // [sp+0h] [bp-Ch]@0
-  char this; // [sp+8h] [bp-4h]@1
-
-  v1 = (char *)&ecx0->field_8;
-  v2 = ((int (__stdcall *)(IDirectInput *, int *, int *, int, int))ecx0->pDirectInput->lpVtbl->field_C)(
-         ecx0->pDirectInput,
-         &ecx0->field_C,
-         &ecx0->field_8,
-         0,
-         "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\DirectInputKeyboard.cpp");
-  CheckHRESULT((CheckHRESULT_stru0 *)&this, v2, (const char *)0x3C, 1, v5);
-  v3 = (*(int (__stdcall **)(int, int))(**(int **)v1 + 44))(*(int *)v1, dword_4C9890);
-  CheckHRESULT((CheckHRESULT_stru0 *)&this, v3, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\DirectInputKeyboard.cpp", 63, 1u);
-  v4 = (*(int (__stdcall **)(int, HWND, signed int))(**(int **)v1 + 52))(*(int *)v1, hWnd, 6);
-  CheckHRESULT((CheckHRESULT_stru0 *)&this, v4, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\DirectInputKeyboard.cpp", 64, 1u);
-  (*(void (__cdecl **)(int))(**(int **)v1 + 28))(*(int *)v1);
-}
-// 4C9890: using guessed type int dword_4C9890[10];
-
-//----- (0043B8EC) --------------------------------------------------------
-char __thiscall DirectInputKeyboard::43B8EC(DirectInputKeyboard *this)
-{
-  DirectInputKeyboard *v1; // esi@1
-  int v2; // eax@1
-  char result; // al@2
-  char *v4; // ebx@3
-  int v5; // esi@5
-  HRESULT v6; // eax@5
-  std::string v7; // [sp-18h] [bp-2Ch]@2
-  int v8; // [sp-Ch] [bp-20h]@5
-  const char *v9; // [sp-8h] [bp-1Ch]@2
-  int v10; // [sp-4h] [bp-18h]@2
-  std::string *v13; // [sp+Ch] [bp-8h]@2
-  int a3; // [sp+13h] [bp-1h]@2
-
-  v1 = this;
-  v2 = this->field_8;
-  if ( v2 )
-  {
-    v4 = (char *)&this->field_1C + 1;
-    if ( (*(int (__stdcall **)(int, signed int, char *))(*(int *)v2 + 36))(v2, 256, (char *)&this->field_1C + 1) == -2147024866 )
-    {
-      if ( !(*(int (__stdcall **)(int))(*(int *)v1->field_8 + 28))(v1->field_8) )
-      {
-        v5 = v1->field_8;
-        v10 = 1;
-        v9 = (const char *)79;
-        v8 = (int)"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\DirectInputKeyboard.cpp";
-        v6 = (*(int (__stdcall **)(int, signed int, char *))(*(int *)v5 + 36))(v5, 256, v4);
-        CheckHRESULT((CheckHRESULT_stru0 *)&v13, v6, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\DirectInputKeyboard.cpp", 79, 1u);
-      }
-    }
-    result = 1;
-  }
-  else
-  {
-    MessageBoxW(nullptr, L"Invalid Device pointer, bailing out of update_data()", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\DirectInputKeyboard.cpp:72", 0);
-    result = 0;
-  }
-  return result;
-}
-
-//----- (0043B96E) --------------------------------------------------------
-char __thiscall DirectInputKeyboard::set_acquire(DirectInputKeyboard *this, int *a2)
-{
-  int v2; // eax@1
-  char result; // al@2
-  int v4; // ecx@3
-  std::string v5; // [sp-18h] [bp-1Ch]@2
-  const char *v6; // [sp-8h] [bp-Ch]@2
-  int v7; // [sp-4h] [bp-8h]@2
-  DirectInputKeyboard *v8; // [sp+0h] [bp-4h]@1
-
-  v8 = this;
-  v2 = this->field_8;
-  if ( v2 )
-  {
-    v4 = *(int *)v2;
-    v7 = v2;
-    if ( (char)a2 )
-      (*(void (__stdcall **)(int))(v4 + 28))(v7);
-    else
-      (*(void (__stdcall **)(int))(v4 + 32))(v7);
-    result = 1;
-  }
-  else
-  {
-    MessageBoxW(nullptr, L"Invalid Device pointer, bailing out of set_acquire()", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\DirectInputKeyboard.cpp:89", 0);
-    result = 0;
-  }
-  return result;
-}
-
-//----- (0043B9B9) --------------------------------------------------------
-signed int __stdcall DirectInputKeyboard_enumerator_43B9B9(int a1, int a2)
-{
-  signed int result; // eax@2
-
-  if ( *(char *)(a1 + 36) & 3 )
-  {
-    *(int *)(a2 + 12) = *(int *)(a1 + 4);
-    *(int *)(a2 + 16) = *(int *)(a1 + 8);
-    *(int *)(a2 + 20) = *(int *)(a1 + 12);
-    *(int *)(a2 + 24) = *(int *)(a1 + 16);
-    *(char *)(a2 + 28) = 1;
-    result = 0;
-  }
-  else
-  {
-    result = 1;
-  }
-  return result;
-}
-// 43B9B9: using guessed type int __stdcall DirectInputKeyboard_enumerator_43B9B9(int, int);
-*/
\ No newline at end of file
--- a/Keyboard.h	Thu May 23 21:36:57 2013 +0600
+++ b/Keyboard.h	Thu May 23 21:37:22 2013 +0600
@@ -56,8 +56,8 @@
   void ReadMappings();
   void StoreMappings();
   bool _459F10(unsigned int a2);
-  void _459ED1(int a2);
-  void EnterText(int a2, int a3, struct GUIWindow *pWindow);
+  void SetWindowInputStatus(int a2);
+  void EnterText(int a2, int max_string_len, struct GUIWindow *pWindow);
   void ResetKeys();
   void SetDefaultMapping();
 
@@ -66,7 +66,7 @@
   int field_8;
   unsigned int pVirtualKeyCodesMapping[30];
   KeyToggleType pToggleTypes[30];
-  int field_FC;
+  int max_input_string_len;
   unsigned __int8 pPressedKeysBuffer[257];
   unsigned __int8 uNumKeysPressed;
   char field_202;
@@ -91,30 +91,6 @@
 #pragma pack(pop)
 
 
-#pragma pack(push, 1)
-struct AsyncKeyboard
-{
-   AsyncKeyboard();
-  ~AsyncKeyboard();
-
-  bool Initialize();
-  char map_key(int key);
-  char _45B4EC(unsigned __int8 a2);
-  void Thread();
-  char _45B3A4();
-  void Suspend();
-  void Resume();
-  char CreateDirectInputKeyboard();
-  char _45B229();
-  void _45B1B1();
-  void Release();
-
-  static int __stdcall ThreadStarter(AsyncKeyboard *pInstance);
-  static void EnterCriticalSection();
-  static void LeaveCriticalSection();
-};
-#pragma pack(pop)
 
 
-extern struct KeyboardActionMapping *pKeyActionMap;
-extern struct AsyncKeyboard *pAsyncKeyboard;
\ No newline at end of file
+extern struct KeyboardActionMapping *pKeyActionMap;
\ No newline at end of file
--- a/Math.h	Thu May 23 21:36:57 2013 +0600
+++ b/Math.h	Thu May 23 21:37:22 2013 +0600
@@ -24,5 +24,10 @@
 #pragma pack(pop)
 
 
+int fixpoint_sub0(int, int);
+int fixpoint_div(int, int);
+int fixpoint_mul(int, int);
+int fixpoint_from_float(float value);
+
 
 extern struct stru193_math *stru_5C6E00;
\ No newline at end of file
--- a/Mouse.cpp	Thu May 23 21:36:57 2013 +0600
+++ b/Mouse.cpp	Thu May 23 21:37:22 2013 +0600
@@ -15,7 +15,6 @@
 
 
 Mouse *pMouse;
-AsyncMouse *pAsyncMouse;
 
 
 
@@ -24,19 +23,8 @@
 //----- (00469860) --------------------------------------------------------
 void Mouse::GetClickPos(unsigned int *pX, unsigned int *pY)
 {
-  unsigned int v3; // eax@2
-
-  if (pAsyncMouse)
-  {
-    *pX = *((int *)pAsyncMouse + 6);
-    v3 = *((int *)pAsyncMouse + 7);
-  }
-  else
-  {
-    *pX = this->uMouseClickX;
-    v3 = this->uMouseClickY;
-  }
-  *pY = v3;
+  *pX = uMouseClickX;
+  *pY = uMouseClickY;
 }
 
 //----- (004698A6) --------------------------------------------------------
@@ -64,7 +52,7 @@
 {
   Mouse *v2; // esi@1
   HCURSOR v3; // eax@10
-  int v4; // ecx@10
+  //int v4; // ecx@10
   double v5; // st7@11
   float v6; // ST04_4@12
   LONG v7; // eax@14
@@ -106,21 +94,18 @@
   {
     v3 = LoadCursorA(GetModuleHandleW(nullptr), "Arrow");
     SetClassLongA(hWnd, GCL_HCURSOR, (LONG)v3);
-    v4 = (int)pAsyncMouse;
-    if (pAsyncMouse)
+    /*if (pAsyncMouse)
     {
       v10 = 0.0;
       v5 = 0.0;
 //LABEL_12:
       v6 = v5;
-      pAsyncMouse->SetHotspot(v6, v10);
-	  if ( !pAsyncMouse || (pAsyncMouse->LoadCursor(pName), !pAsyncMouse) )
-	  {
+
 		GetCursorPos(&Point);
 		SetCursorPos(Point.x, Point.y);
-	  }
+
 	  return;
-    }
+    }*/
     GetCursorPos(&Point);
 	ClientToScreen(hWnd,&Point);
     SetCursorPos(Point.x, Point.y);
@@ -130,8 +115,7 @@
   {
     v7 = (LONG)LoadCursorA(GetModuleHandleW(nullptr), "Target");
     SetClassLongA(hWnd, -12, v7);
-    v4 = (int)pAsyncMouse;
-    if (pAsyncMouse)
+    /*if (pAsyncMouse)
     {
       v10 = 14.0;
       v5 = 14.0;
@@ -143,7 +127,7 @@
 		SetCursorPos(Point.x, Point.y);
 	  }
 	  return;
-    }
+    }*/
 //LABEL_20:
     GetCursorPos(&Point);
     SetCursorPos(Point.x, Point.y);
@@ -155,11 +139,9 @@
     SetClassLongA(hWnd, -12, v8);
   }
 //LABEL_18:
-  if ( !pAsyncMouse || (pAsyncMouse->LoadCursor(pName), !pAsyncMouse) )
-  {
+
     GetCursorPos(&Point);
     SetCursorPos(Point.x, Point.y);
-  }
 }
 // 506128: using guessed type int areWeLoadingTexture;
 
@@ -173,26 +155,26 @@
 
   v1 = this;
   this->field_8 = 1;
-  if (pAsyncMouse)
+  /*if (pAsyncMouse)
   {
     v2 = *((int *)pAsyncMouse + 6);
     Point.x = *((int *)pAsyncMouse + 6);
     result = *((int *)pAsyncMouse + 7);
   }
   else
-  {
+  {*/
     GetCursorPos(&Point);
     if ( pRenderer->bWindowMode )
       ScreenToClient(hWnd, &Point);
     result = Point.y;
     v2 = Point.x;
-  }
+  //}
   v1->uMouseClickX = v2;
   v1->uMouseClickY = result;
   if ( pRenderer->bWindowMode )
     goto LABEL_16;
-  if (pAsyncMouse)
-    goto LABEL_24;
+  //if (pAsyncMouse)
+  //  goto LABEL_24;
   if ( v2 < 0 )
     v2 = 0;
   if ( result < 0 )
@@ -203,8 +185,8 @@
   {
     result = 479;
 LABEL_16:
-    if (pAsyncMouse)
-      goto LABEL_24;
+    //if (pAsyncMouse)
+    //  goto LABEL_24;
     if ( pRenderer->bWindowMode && (v2 < 0 || result < 0 || v2 > 639 || result > 479) )
       goto LABEL_23;
   }
@@ -262,26 +244,9 @@
 //----- (00469C39) --------------------------------------------------------
 POINT *Mouse::GetCursorPos(POINT *a2)
 {
-  void *v2; // edx@1
-  POINT *result; // eax@1
-  unsigned int v4; // ecx@2
-  unsigned int v5; // edx@3
-
-  v2 = pAsyncMouse;
-  result = a2;
-  if (pAsyncMouse)
-  {
-    a2->x = *((int *)pAsyncMouse + 6);
-    v4 = *((int *)v2 + 7);
-  }
-  else
-  {
-    v5 = this->uMouseClickX;
-    v4 = this->uMouseClickY;
-    a2->x = v5;
-  }
-  a2->y = v4;
-  return result;
+  a2->x = this->uMouseClickX;
+  a2->y = this->uMouseClickY;
+  return a2;
 }
 
 //----- (00469C65) --------------------------------------------------------
@@ -458,16 +423,10 @@
   {
     pTextureID = pIcons_LOD->LoadTexture(pItemsTable->pItems[pParty->pPickedItem.uItemID].pIconName, TEXTURE_16BIT_PALETTE);
     pTexture = (Texture *)(pTextureID != -1 ? (int)&pIcons_LOD->pTextures[pTextureID] : 0);
-    if (pAsyncMouse)
-    {
-      v4 = *((int *)pAsyncMouse + 6);
-      v5 = *((int *)pAsyncMouse + 7);
-    }
-    else
-    {
+
       v4 = pMouse->uMouseClickX;
       v5 = pMouse->uMouseClickY;
-    }
+
     v6 = v5;
     a2 = v4;
     v15 = v5;
@@ -572,1492 +531,3 @@
   uMouseClickY = y;
 }
 
-
-//----- (00409E3D) --------------------------------------------------------
-void AsyncMouse::_409E3D(char a2)
-{
-  if ( *((unsigned char *)this + 128) & 1 )
-    *((unsigned char *)this + 103) = 1;
-  else
-    *((unsigned char *)this + 103) = 0;
-  if ( a2 )
-    *((unsigned int *)this + 32) |= 1u;
-  else
-    *((unsigned int *)this + 32) &= 0xFFFFFFFEu;
-}
-
-//----- (00465C2C) --------------------------------------------------------
-void AsyncMouse::Release()
-{
-  if (pAsyncMouse)
-  {
-    pAsyncMouse->Suspend();
-    if (pAsyncMouse)
-      (**(void (__stdcall ***)(int))pAsyncMouse)(1);
-  }
-  pAsyncMouse = 0;
-}
-
-
-
-
-//----- (0046ACA9) --------------------------------------------------------
-AsyncMouse::AsyncMouse(IDirectDrawSurface *a2)
-{
-  IDirectDrawSurface *v2; // eax@1
-  void *v3; // esi@1
-  char *v4; // edi@1
-  double v5; // ST14_8@3
-  double v6; // ST14_8@3
-
-  v2 = a2;
-  v3 = this;
-  *((int *)this + 16) = -1;
-  *((int *)this + 3) = (int)v2;
-  LOBYTE(v2) = BYTE3(a2);
-  v4 = (char *)this + 104;
-  *((int *)this + 1) = 0;
-  *((char *)this + 20) = 0;
-  *((int *)this + 17) = 0;
-  *((int *)this + 18) = 0;
-  *((char *)this + 88) = 1;
-  *((char *)this + 91) = 0;
-  *((char *)this + 93) = 0;
-  *((char *)this + 94) = 0;
-  *((char *)this + 95) = 0;
-  *((char *)this + 96) = 0;
-  *((char *)this + 97) = 0;
-  *((char *)this + 98) = 0;
-  *((char *)this + 99) = 0;
-  *((char *)this + 100) = 0;
-  *((char *)this + 101) = 0;
-  *((char *)this + 102) = 0;
-  *((char *)this + 104) = (char)v2;
-  *((int *)this + 27) = (int)AsyncMouse::unk_46BD09(0, 0);
-  *((int *)v4 + 2) = 0;
-  *((char *)v3 + 116) = BYTE3(a2);
-  *((int *)v3 + 30) = (int)AsyncMouse::unk_46BD09(0, 0);
-  *((int *)v3 + 31) = 0;
-  *((int *)v3 + 32) = 0;
-  *((int *)v3 + 33) = 0;
-  *(int *)v3 = 5080880;
-  if ( !Initialize(this) )
-  {
-    MessageBoxW(nullptr, L"Could not initialize CMouseAsync object", nullptr, 0);
-  }
-  *((int *)v3 + 12) = 0;
-  *((int *)v3 + 13) = 0;
-  *((int *)v3 + 14) = 0;
-  *((int *)v3 + 15) = 0;
-  v5 = (float)0.0 + 6.7553994e15;
-  *((int *)v3 + 10) = LODWORD(v5);
-  v6 = (float)0.0 + 6.7553994e15;
-  a2 = (IDirectDrawSurface *)LODWORD(v6);
-  *((int *)v3 + 32) |= 1u;
-  *((int *)v3 + 11) = LODWORD(v6);
-  *((char *)v3 + 103) = 1;
-}
-// 4DBD94: using guessed type int dword_4DBD94;
-
-
-
-//----- (0046ADE2) --------------------------------------------------------
-AsyncMouse::~AsyncMouse()
-{
-  void *v1; // esi@1
-  char *v2; // edi@1
-  int v3; // ecx@1
-
-  v1 = this;
-  //*(int *)this = AsyncMouse_pvdtor;
-  v2 = (char *)this + 132;
-  v3 = *((int *)this + 33);
-  if ( v3 )
-    (**(void (__stdcall ***)(int))v3)(1);
-  *(int *)v2 = 0;
-  TerminateThread(*((HANDLE *)v1 + 4), 0xFAu);
-  SetWindowPos(hWnd, (HWND)0xFFFFFFFE, uWindowX, uWindowY, 640, 480, 0);
-  //AsyncMouse::dtor_sub_46BC73((int)((char *)v1 + 116));
-  //AsyncMouse::dtor_sub_46BC73((int)((char *)v1 + 104));
-}
-// 4D8730: using guessed type int (__stdcall *AsyncMouse_pvdtor[2])(char);
-
-
-
-
-
-
-
-
-
-
-
-
-
-//----- (0046AE6E) --------------------------------------------------------
-char AsyncMouse::Initialize(LPVOID lpParameter)
-{
-  void *v1; // esi@1
-  char result; // al@2
-
-  v1 = lpParameter;
-  if ( LoadCursorImage() && _46B072() )
-    result = CreateDisrectInputMouse() != 0;
-  else
-    result = 0;
-  return result;
-}
-
-//----- (0046AE97) --------------------------------------------------------
-char AsyncMouse::LoadCursor(const char *pContainer)
-{
-  __debugbreak();
-  return 0;
-  /*
-  void *v2; // esi@1
-  int v3; // eax@1
-  HRESULT v4; // eax@1
-  char result; // al@3
-  HRESULT a2; // [sp+8h] [bp-B0h]@1
-  int v7; // [sp+58h] [bp-60h]@1
-  char v9; // [sp+B4h] [bp-4h]@1
-
-  v2 = this;
-  EnterCriticalSection(&pGame->pThreadWardInstance->cs2);
-  v3 = *((int *)v2 + 1);
-  a2 = 100;
-  v7 = 0;
-  v4 = (*(int (__stdcall **)(int, int, int, int, signed int, HRESULT *))(*(int *)v3 + 20))(
-         v3,
-         0,
-         0,
-         0,
-         1024,
-         &a2);
-  ErrHR(v4, "DirectInput", __FUNCTION__, __FILE__, __LINE__);
-  
-  Texture thisa; // [sp+6Ch] [bp-4Ch]@1
-  //Texture::Texture(&thisa);
-
-  if ( pIcons_LOD->LoadTextureFromLOD(&thisa, pContainer, TEXTURE_16BIT_PALETTE) != -1
-    && DrawCursor(&thisa, *((IDirectDrawSurface4 **)v2 + 1), 0) )
-  {
-    thisa.Release();
-    LeaveCriticalSection(&pGame->pThreadWardInstance->cs2);
-    result = 1;
-  }
-  else
-  {
-    result = 0;
-  }
-  return result;*/
-}
-
-//----- (0046AF50) --------------------------------------------------------
-char AsyncMouse::LoadCursorImage()
-{
-  void *v1; // ebx@1
-  int v2; // eax@2
-  int v3; // esi@4
-  char result; // al@5
-  //const char *v5; // eax@6
-  //std::string v6; // [sp-18h] [bp-12Ch]@9
-  const char *v7; // [sp-8h] [bp-11Ch]@9
-  int v8; // [sp-4h] [bp-118h]@9
-  DDSURFACEDESC2 Dst; // [sp+Ch] [bp-108h]@1
-  int v10; // [sp+88h] [bp-8Ch]@2
-  int v11; // [sp+8Ch] [bp-88h]@2
-  int v12; // [sp+90h] [bp-84h]@2
-  int v13; // [sp+94h] [bp-80h]@2
-  char v14; // [sp+D0h] [bp-44h]@2
-  int v15; // [sp+F0h] [bp-24h]@2
-  int v16; // [sp+104h] [bp-10h]@4
-  int v17; // [sp+108h] [bp-Ch]@4
-  std::string *v18; // [sp+10Ch] [bp-8h]@9
-  int a3; // [sp+113h] [bp-1h]@9
-
-  v1 = this;
-  memset(&Dst, 0, 0x7Cu);
-  Dst.dwSize = 124;
-  if ( pRenderer->pDirectDraw4->GetDisplayMode(&Dst)
-    || (memset(&v10, 0, 0x7Cu),
-        v10 = 124,
-        v11 = 4103,
-        v15 = 2112,
-        v12 = 32,
-        v13 = 32,
-        v2 = *((int *)v1 + 3),
-        memcpy(&v14, &Dst.ddpfPixelFormat, 0x20u),
-        (*(int (__stdcall **)(int, int *, char *, int))(**(int **)v2 + 24))(
-          *(int *)v2,
-          &v10,
-          (char *)v1 + 4,
-          0))
-    || (*(int (__stdcall **)(int, int *, char *, int))(***((int ***)v1 + 3) + 24))(
-         **((int **)v1 + 3),
-         &v10,
-         (char *)v1 + 8,
-         0)
-    || (v3 = *((int *)v1 + 1),
-        v16 = 0,
-        v17 = 0,
-        (*(int (__stdcall **)(int, signed int, int *))(*(int *)v3 + 116))(v3, 8, &v16)) )
-  {
-    result = 0;
-    return false;
-  }
-  else
-  {
-    if ( !LoadCursor("micon1") )
-    {
-      MessageBoxW(nullptr, L"Could not load async mouse cursor image", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\MouseAsync.cpp:182", 0);
-    }
-    result = 1;
-    return true;
-  }
-  return result;
-}
-// 4D86F0: using guessed type int dword_4D86F0;
-
-//----- (0046B072) --------------------------------------------------------
-char AsyncMouse::_46B072()
-{
-  DWORD v1; // esi@1
-  HANDLE v2; // eax@1
-  char result; // al@2
-  DWORD ThreadId; // [sp+0h] [bp-4h]@1
-
-  ThreadId = (DWORD)this;
-  v1 = (DWORD)this;
-  v2 = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)AsyncMouseThread, this, 4u, &ThreadId);
-  *(int *)(v1 + 16) = (int)v2;
-  if ( v2 )
-    result = SetThreadPriority(v2, 15) != 0;
-  else
-    result = 0;
-  return result;
-}
-
-//----- (0046B0A9) --------------------------------------------------------
-char AsyncMouse::CreateDisrectInputMouse()
-{
-  __debugbreak();
-  /*
-  void *v1; // esi@1
-  DirectInputMouse *v2; // ecx@1
-  DirectInputMouse *v3; // eax@2
-
-  v1 = this;
-  v2 = (DirectInputMouse *)operator new(0x2Cu);
-  if ( v2 )
-    v3 = DirectInputMouse::DirectInputMouse(v2);
-  else
-    v3 = 0;
-  *((int *)v1 + 33) = v3;
-  return v3 != 0;*/
-  return 0;
-}
-
-//----- (0046B0ED) --------------------------------------------------------
-int AsyncMouse::_46B0ED()
-{
-  __debugbreak();
-  /*
-  int v1; // esi@1
-  int v2; // ecx@1
-  int result; // eax@2
-
-  v1 = this + 132;
-  v2 = *(int *)(this + 132);
-  if ( v2 )
-    result = (**(int (__stdcall ***)(int))v2)(1);
-  *(int *)v1 = 0;
-  return result;*/
-  return 0;
-}
-// 46B0ED: using guessed type int __thiscall AsyncMouse__46B0ED(int);
-
-//----- (0046B105) --------------------------------------------------------
-void AsyncMouse::Resume()
-{
-  __debugbreak();
-  /*
-  void *v1; // esi@1
-
-  v1 = this;
-  EnterCriticalSection(&pGame->pThreadWardInstance->cs3);
-  AsyncMouse::CreateDisrectInputMouse(v1);
-  AsyncMouse::Clip();
-  ResumeThread(*((HANDLE *)v1 + 4));
-  *((char *)v1 + 88) = 0;
-  LeaveCriticalSection(&pGame->pThreadWardInstance->cs3);*/
-}
-
-//----- (0046B14F) --------------------------------------------------------
-void AsyncMouse::Suspend()
-{
-  void *v1; // esi@1
-  //Vis *v2; // eax@3
-  std::string v3; // [sp-18h] [bp-24h]@2
-  const char *v4; // [sp-8h] [bp-14h]@2
-  int v5; // [sp-4h] [bp-10h]@2
-  std::string *v6; // [sp+4h] [bp-8h]@2
-  int a3; // [sp+Bh] [bp-1h]@2
-
-  v1 = this;
-  if ( *((int *)this + 33) )
-  {
-    //v2 = pGame->pVisInstance;
-    if (pGame->pVisInstance)
-      pGame->pVisInstance->default_list.uNumPointers = 0;
-
-    EnterCriticalSection(&pGame->pThreadWardInstance->cs3);
-    SuspendThread(*((HANDLE *)v1 + 4));
-    _46B0ED();
-    LeaveCriticalSection(&pGame->pThreadWardInstance->cs3);
-  }
-  else
-  {
-      MessageBoxW(nullptr, L"DI_Mouse pointer invalid; bailing out from suspend()", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\MouseAsync.cpp:233", 0);
-  }
-}
-// 46B0ED: using guessed type int __thiscall AsyncMouse__46B0ED(int);
-
-//----- (0046B1DD) --------------------------------------------------------
-char AsyncMouse::_46B1DD()
-{
-  *((char *)this + 20) = 1;
-  Sleep(118);
-  return 1;
-}
-
-//----- (0046B1EC) --------------------------------------------------------
-bool AsyncMouse::DrawCursor(Texture *a1, IDirectDrawSurface4 *a2, int a3)
-{
-  __debugbreak();
-  /*
-  bool result; // eax@1
-  unsigned __int16 *v5; // ebx@2
-  unsigned __int8 *v6; // edx@2
-  int v7; // esi@2
-  int v8; // ecx@2
-  LPVOID v9; // edi@2
-  int v10; // ecx@5
-  DDSURFACEDESC2 Dst; // [sp+0h] [bp-84h]@1
-  __int32 v12; // [sp+7Ch] [bp-8h]@3
-  int v13; // [sp+80h] [bp-4h]@3
-
-  Dst.dwSize = 124;
-  result = pRenderer->LockSurface_DDraw4(a2, &Dst, DDLOCK_WAIT);
-  if ( result )
-  {
-    v5 = a1->pPalette16;
-    v6 = a1->pLevelOfDetail0_prolly_alpha_mask;
-    v7 = a1->uTextureWidth;
-    v8 = a1->uTextureHeight;
-    v9 = Dst.lpSurface;
-    if ( v8 > 0 )
-    {
-      v12 = 2 * (Dst.lPitch / 2 - v7);
-      v13 = v8;
-      do
-      {
-        if ( v7 > 0 )
-        {
-          v10 = v7;
-          do
-          {
-            if ( v5[*v6] )
-              *(short *)v9 = v5[*v6];
-            v9 = (char *)v9 + 2;
-            ++v6;
-            --v10;
-          }
-          while ( v10 );
-        }
-        v9 = (char *)v9 + v12;
-        --v13;
-      }
-      while ( v13 );
-    }
-    result = a2->Unlock(
-               v6,
-               a2,
-               a3);
-  }
-  LOBYTE(result) = 1;
-  return result;*/
-  return 0;
-}
-
-//----- (0046B289) --------------------------------------------------------
-bool AsyncMouse::_46B289(int a2, char a3)
-{
-  char v3; // dl@1
-  bool result; // eax@33
-  char v5; // [sp+2h] [bp-2h]@1
-  char v6; // [sp+3h] [bp-1h]@1
-
-  v3 = *((char *)this + 93);
-  v6 = *((char *)this + 94);
-  v5 = *((char *)this + 95);
-  if ( a3 & 1 )
-  {
-    *((char *)this + 93) = 1;
-  }
-  else
-  {
-    if ( v3 )
-      *((char *)this + 99) = 1;
-    else
-      *((char *)this + 99) = 0;
-    *((char *)this + 93) = 0;
-  }
-  if ( a3 & 2 )
-  {
-    *((char *)this + 94) = 1;
-  }
-  else
-  {
-    if ( v6 )
-      *((char *)this + 100) = 1;
-    else
-      *((char *)this + 100) = 0;
-    *((char *)this + 94) = 0;
-  }
-  if ( a3 & 4 )
-  {
-    *((char *)this + 95) = 1;
-  }
-  else
-  {
-    if ( v5 )
-      *((char *)this + 101) = 1;
-    else
-      *((char *)this + 101) = 0;
-    *((char *)this + 95) = 0;
-  }
-  *((char *)this + 96) = v3 != *((char *)this + 93);
-  *((char *)this + 97) = v6 != *((char *)this + 94);
-  *((char *)this + 98) = v5 != *((char *)this + 95);
-  if ( *((char *)this + 99) && *((char *)this + 96) || *((char *)this + 100) && *((char *)this + 97) )
-    *((char *)this + 102) = 1;
-  LOBYTE(result) = 1;
-  return result;
-}
-
-//----- (0046B342) --------------------------------------------------------
-void AsyncMouse::SetHotspot(float hotspotx, float hotspoty)
-{
-  double v3; // ST00_8@1
-  double v4; // ST00_8@1
-
-  v3 = hotspotx + 6.7553994e15;
-  *(int *)(this + 40) = LODWORD(v3);
-  v4 = hotspoty + 6.7553994e15;
-  *(int *)(this + 44) = LODWORD(v4);
-}
-
-//----- (0046B37C) --------------------------------------------------------
-int AsyncMouse::UpdateData(int a2)
-{
-  __debugbreak();
-  /*
-  void *v2; // edi@1
-  int result; // eax@2
-  int v4; // eax@3
-  int v5; // esi@3
-  std::string v6; // [sp-18h] [bp-28h]@2
-  const char *v7; // [sp-8h] [bp-18h]@2
-  int v8; // [sp-4h] [bp-14h]@2
-  std::string *v9; // [sp+8h] [bp-8h]@2
-  int a3; // [sp+Fh] [bp-1h]@2
-
-  v2 = this;
-  if ( *((int *)this + 33) )
-  {
-    EnterCriticalSection(&pGame->pThreadWardInstance->cs3);
-    DirectInputMouse::_43BB89(*((DirectInputMouse **)v2 + 33));
-    v4 = *((int *)v2 + 33);
-    v5 = v4 + 32;
-    _46B289(v4 + 32, *(int *)(v4 + 40));
-    LeaveCriticalSection(&pGame->pThreadWardInstance->cs3);
-    result = a2;
-    *(int *)a2 = *(int *)v5;
-    *(int *)(a2 + 4) = *(int *)(v5 + 4);
-  }
-  else
-  {
-    MessageBoxW(nullptr, L"DI_Mouse pointer invalid bailing out from update_mouse_data()", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\MouseAsync.cpp:446", 0);
-    result = a2;
-    *(int *)a2 = 0;
-    *(int *)(a2 + 4) = 0;
-  }
-  return result;*/
-  return 0;
-}
-
-//----- (0046B420) --------------------------------------------------------
-char AsyncMouse::Thread()
-{
-  void *v1; // esi@1
-  char result; // al@2
-  int v3; // eax@3
-  int v4; // ecx@3
-  int v5; // eax@3
-  int v6; // ecx@3
-  int v7; // [sp+4h] [bp-8h]@3
-  int v8; // [sp+8h] [bp-4h]@3
-
-  v1 = this;
-  if ( *((char *)this + 20) )
-  {
-    result = 0;
-  }
-  else
-  {
-    UpdateData((int)&v7);
-    _46BA8D(v7, v8);
-    _46B958(v7 - *((int *)v1 + 10), v8 - *((int *)v1 + 11));
-    _46B492((int)&v7);
-    _46B5D5((int)&v7);
-    v3 = v7;
-    v4 = v8;
-    *((int *)v1 + 6) = v7;
-    v5 = v3 - *((int *)v1 + 10);
-    *((int *)v1 + 7) = v4;
-    v6 = v4 - *((int *)v1 + 11);
-    *((int *)v1 + 8) = v5;
-    result = 1;
-    *((int *)v1 + 9) = v6;
-  }
-  return result;
-}
-
-//----- (0046B492) --------------------------------------------------------
-void AsyncMouse::_46B492(int a2)
-{
-  __debugbreak();
-  /*
-  void *v2; // edi@1
-  int v3; // esi@3
-  int v4; // eax@5
-  int v5; // ecx@5
-  int v6; // eax@8
-  int v7; // ecx@8
-  int v8; // eax@11
-  int v9; // esi@11
-  int v10; // [sp+Ch] [bp-1Ch]@5
-  int v11; // [sp+10h] [bp-18h]@5
-  int v12; // [sp+14h] [bp-14h]@5
-  int v13; // [sp+18h] [bp-10h]@5
-  int v14; // [sp+24h] [bp-4h]@5
-
-  v2 = this;
-  EnterCriticalSection(&pGame->pThreadWardInstance->csAsyncMouse);
-  if ( *((int *)v2 + 28) > 0x80u )
-    _46BCAB((char *)v2 + 104);
-  v3 = a2;
-  if ( *((char *)v2 + 93) && *((char *)v2 + 96) )
-  {
-    v4 = *(int *)a2;
-    v5 = *(int *)(a2 + 4);
-    v13 = 1;
-    v10 = 5080884;
-    v11 = v4;
-    v12 = v5;
-    v14 = 0;
-    AsyncMouse::unk_46BCD2((char *)v2 + 104, (int)&a2, *((int *)v2 + 27), (int)&v10);
-    v14 = -1;
-  }
-  if ( *((char *)v2 + 94) && *((char *)v2 + 97) )
-  {
-    v6 = *(int *)v3;
-    v7 = *(int *)(v3 + 4);
-    v13 = 2;
-    v10 = 5080884;
-    v11 = v6;
-    v12 = v7;
-    v14 = 1;
-    AsyncMouse::unk_46BCD2((char *)v2 + 104, (int)&a2, *((int *)v2 + 27), (int)&v10);
-    v14 = -1;
-  }
-  if ( *((char *)v2 + 95) && *((char *)v2 + 98) )
-  {
-    v8 = *(int *)v3;
-    v9 = *(int *)(v3 + 4);
-    v13 = 4;
-    v10 = 5080884;
-    v11 = v8;
-    v12 = v9;
-    v14 = 2;
-    AsyncMouse::unk_46BCD2((char *)v2 + 104, (int)&a2, *((int *)v2 + 27), (int)&v10);
-  }
-  LeaveCriticalSection(&pGame->pThreadWardInstance->csAsyncMouse);*/
-}
-
-//----- (0046B5D5) --------------------------------------------------------
-void AsyncMouse::_46B5D5(int a2)
-{
-  __debugbreak();
-  /*
-  void *v2; // esi@1
-  DWORD v3; // eax@3
-  char v4; // zf@3
-  int v5; // edi@3
-  int v6; // eax@6
-  int v7; // ecx@6
-  int v8; // eax@11
-  int v9; // ecx@11
-  int v10; // eax@16
-  int v11; // edi@16
-  int (__stdcall **v12)(char); // [sp+Ch] [bp-20h]@6
-  int v13; // [sp+10h] [bp-1Ch]@6
-  int v14; // [sp+14h] [bp-18h]@6
-  int v15; // [sp+18h] [bp-14h]@6
-  DWORD v16; // [sp+1Ch] [bp-10h]@3
-  int v17; // [sp+28h] [bp-4h]@6
-
-  v2 = this;
-  EnterCriticalSection(&pGame->pThreadWardInstance->csAsyncMouse);
-  if ( *((int *)v2 + 31) > 0x80u )
-    _46BCAB((char *)v2 + 116);
-  v3 = timeGetTime();
-  v4 = *((char *)v2 + 93) == 0;
-  v5 = a2;
-  v16 = v3;
-  if ( !v4 && *((char *)v2 + 96) )
-  {
-    if ( v3 - *((int *)v2 + 19) < 0xFA )
-    {
-      v6 = *(int *)a2;
-      v7 = *(int *)(a2 + 4);
-      v15 = 1;
-      v12 = &AsyncMouse::unk::vdtor_ptr;
-      v13 = v6;
-      v14 = v7;
-      v17 = 0;
-      AsyncMouse::unk_46BCD2((char *)v2 + 116, (int)&a2, *((int *)v2 + 30), (int)&v12);
-      v17 = -1;
-      v3 = v16;
-    }
-    *((int *)v2 + 19) = v3;
-  }
-  if ( *((char *)v2 + 94) && *((char *)v2 + 97) )
-  {
-    if ( v3 - *((int *)v2 + 20) < 0xFA )
-    {
-      v8 = *(int *)v5;
-      v9 = *(int *)(v5 + 4);
-      v15 = 2;
-      //v12 = &AsyncMouse::unk::vdtor_ptr;
-      v13 = v8;
-      v14 = v9;
-      v17 = 1;
-      AsyncMouse::unk_46BCD2((char *)v2 + 116, (int)&a2, *((int *)v2 + 30), (int)&v12);
-      v17 = -1;
-      v3 = v16;
-    }
-    *((int *)v2 + 20) = v3;
-  }
-  if ( *((char *)v2 + 95) && *((char *)v2 + 98) )
-  {
-    if ( v3 - *((int *)v2 + 21) < 0xFA )
-    {
-      v10 = *(int *)v5;
-      v11 = *(int *)(v5 + 4);
-      v15 = 4;
-      //v12 = &AsyncMouse::unk::vdtor_ptr;
-      v13 = v10;
-      v14 = v11;
-      v17 = 2;
-      AsyncMouse::unk_46BCD2((char *)v2 + 116, (int)&a2, *((int *)v2 + 30), (int)&v12);
-      v3 = v16;
-    }
-    *((int *)v2 + 21) = v3;
-  }
-  LeaveCriticalSection(&pGame->pThreadWardInstance->csAsyncMouse);*/
-}
-
-//----- (0046B736) --------------------------------------------------------
-void AsyncMouse::_46B736_consume_click_lists(char a2)
-{
-  __debugbreak();
-  /*
-  void *v2; // esi@1
-
-  v2 = this;
-  _46B76F();
-  _46B879();
-  if ( a2 )
-  {
-    _46BCAB((char *)v2 + 104);
-    _46BCAB((char *)v2 + 116);
-  }
-  if ( *((char *)v2 + 102) )
-  {
-    back_to_game();
-    *((char *)v2 + 102) = 0;
-  }*/
-}
-
-//----- (0046B76F) --------------------------------------------------------
-void AsyncMouse::_46B76F()
-{
-  __debugbreak();
-  /*
-  char *v0; // ebx@1
-  int v1; // eax@1
-  int v2; // edi@1
-  int v3; // eax@2
-  unsigned int *v4; // esi@2
-  unsigned int v5; // ST08_4@7
-  unsigned int v6; // ST04_4@7
-  float v7; // ST00_4@7
-  unsigned int v8; // ST08_4@9
-  unsigned int v9; // ST04_4@9
-  float v10; // ST00_4@9
-
-  EnterCriticalSection(&pGame->pThreadWardInstance->csAsyncMouse);
-  v0 = (char *)pAsyncMouse + 108;
-  v1 = *((int *)pAsyncMouse + 27);
-  v2 = *(int *)v1;
-  if ( *(int *)v1 != v1 )
-  {
-    do
-    {
-      v3 = *(int *)(v2 + 20);
-      v4 = (unsigned int *)(v2 + 12);
-      if ( v3 & 1 )
-      {
-        pGame->PickMouse(512.0, *v4, *(int *)(v2 + 16), 0, &a3, &a4);
-        if ( GetCurrentMenuID() == 6 )
-          UI_OnKeyDown(VK_SELECT);
-        UI_OnMouseLeftClick((int *)(v2 + 12));
-      }
-      else
-      {
-        if ( v3 & 2 )
-        {
-          v5 = *(int *)(v2 + 16);
-          v6 = *v4;
-          v7 = GetPickDepth();
-          pGame->PickMouse(v7, v6, v5, 0, &stru_F93E30, &a5);
-          sub_416D62_ShowPopupWindow_MonsterRecord_ItemInfo_etcsub_416D62((Vec2_int_ *)(v2 + 12));
-        }
-        else
-        {
-          if ( v3 & 4 )
-          {
-            v8 = *(int *)(v2 + 16);
-            v9 = *v4;
-            v10 = GetPickDepth();
-            pGame->PickMouse(v10, v9, v8, 1, &a3, &a5);
-          }
-        }
-      }
-      v2 = *(int *)v2;
-    }
-    while ( v2 != *(int *)v0 );
-  }
-  LeaveCriticalSection(&pGame->pThreadWardInstance->csAsyncMouse);*/
-}
-
-//----- (0046B879) --------------------------------------------------------
-void AsyncMouse::_46B879()
-{
-  __debugbreak();
-  /*
-  char *v0; // ebx@1
-  int v1; // eax@1
-  int v2; // edi@1
-  int v3; // eax@2
-  unsigned int *v4; // esi@2
-  unsigned int v5; // ST08_4@5
-  unsigned int v6; // ST04_4@5
-  float v7; // ST00_4@5
-
-  EnterCriticalSection(&pGame->pThreadWardInstance->csAsyncMouse);
-  v0 = (char *)pAsyncMouse + 120;
-  v1 = *((int *)pAsyncMouse + 30);
-  v2 = *(int *)v1;
-  if ( *(int *)v1 != v1 )
-  {
-    do
-    {
-      v3 = *(int *)(v2 + 20);
-      v4 = (unsigned int *)(v2 + 12);
-      if ( v3 & 1 )
-      {
-        pGame->PickMouse(512.0, *v4, *(int *)(v2 + 16), 0, &a3, &a4);
-        sub_4178C4();
-      }
-      else
-      {
-        if ( v3 & 2 )
-        {
-          v5 = *(int *)(v2 + 16);
-          v6 = *v4;
-          v7 = GetPickDepth();
-          pGame->PickMouse(v7, v6, v5, 0, &stru_F93E30, &a4);
-          sub_4178E1();
-        }
-        else
-        {
-          if ( v3 & 4 )
-            nullsub_1();
-        }
-      }
-      v2 = *(int *)v2;
-    }
-    while ( v2 != *(int *)v0 );
-  }
-  LeaveCriticalSection(&pGame->pThreadWardInstance->csAsyncMouse);*/
-}
-
-//----- (0046B944) --------------------------------------------------------
-int AsyncMouse::_46B944()
-{
-  __debugbreak();
-  /*
-  void *v1; // esi@1
-
-  v1 = this;
-  _46BCAB((char *)this + 104);
-  return _46BCAB((char *)v1 + 116);*/
-  return 0;
-}
-// 46BCAB: using guessed type int __thiscall AsyncMouse__46BCAB(int);
-
-//----- (0046B958) --------------------------------------------------------
-char AsyncMouse::_46B958(int a2, int a3)
-{
-  __debugbreak();
-  /*
-  void *v3; // esi@1
-  char result; // al@3
-  int v5; // edx@6
-  int v6; // eax@6
-  int v7; // eax@12
-  int v8; // edi@13
-  int v9; // eax@19
-  struct IDirectDrawSurface4 *v10; // ST08_4@21
-  DDBLTFX v11; // [sp+4h] [bp-74h]@21
-  RECT v12; // [sp+68h] [bp-10h]@19
-
-  v3 = this;
-  if ( pRenderer->pFrontBuffer4 && !pRenderer->pFrontBuffer4->IsLost() )
-  {
-    EnterCriticalSection(&pGame->pThreadWardInstance->cs2);
-    if ( *((char *)v3 + 88) )
-      pRenderer->pFrontBuffer4->BltFast(
-        *((int *)v3 + 8),
-        *((int *)v3 + 9),
-        (LPDIRECTDRAWSURFACE4)*((int *)v3 + 2),
-        (LPRECT)((char *)v3 + 48),
-        16u);
-    v5 = 640 - a2;
-    v6 = 640 - a2;
-    if ( 640 - a2 >= 31 )
-      v6 = 31;
-    if ( v6 >= 0 )
-    {
-      if ( v5 >= 31 )
-        v5 = 31;
-    }
-    else
-    {
-      v5 = 0;
-    }
-    v7 = 480 - a3;
-    if ( 480 - a3 >= 31 )
-      v8 = 31;
-    else
-      v8 = 480 - a3;
-    if ( v8 >= 0 )
-    {
-      if ( v7 >= 31 )
-        v7 = 31;
-    }
-    else
-    {
-      v7 = 0;
-    }
-    *((int *)v3 + 13) = 0;
-    *((int *)v3 + 14) = v5;
-    v12.right = a2 + v5;
-    *((int *)v3 + 12) = 0;
-    *((int *)v3 + 15) = v7;
-    v12.left = a2;
-    v12.bottom = a3 + v7;
-    v9 = *((int *)v3 + 2);
-    v12.top = a3;
-    (*(void (__stdcall **)(int, int, int, IDirectDrawSurface4 *, RECT *, signed int))(*(int *)v9 + 28))(
-      v9,
-      0,
-      0,
-      pRenderer->pFrontBuffer4,
-      &v12,
-      16);
-    if ( !*((char *)v3 + 90) || *((char *)v3 + 128) & 1 )
-    {
-      v10 = (struct IDirectDrawSurface4 *)*((int *)v3 + 1);
-      v11.dwSize = 100;
-      v11.dwDDFX = 8;
-      pRenderer->pFrontBuffer4->Blt(
-        &v12,
-        v10,
-        (LPRECT)((char *)v3 + 48),
-        16812032u,
-        &v11);
-    }
-    *((char *)v3 + 88) = 1;
-    LeaveCriticalSection(&pGame->pThreadWardInstance->cs2);
-    result = 1;
-  }
-  else
-  {
-    result = 0;
-  }
-  return result;*/
-  return 0;
-}
-
-//----- (0046BA8D) --------------------------------------------------------
-char AsyncMouse::_46BA8D(int a2, int a3)
-{
-  __debugbreak();
-  /*
-  void *v3; // esi@1
-  DWORD v4; // eax@1
-
-  v3 = this;
-  v4 = timeGetTime();
-  if ( v4 - *((int *)v3 + 16) <= 0x32 )
-  {
-    *((char *)v3 + 91) = *((char *)v3 + 90) == 1;
-    *((char *)v3 + 90) = 0;
-  }
-  else
-  {
-    if ( *((char *)v3 + 90) )
-      *((char *)v3 + 91) = 0;
-    else
-      *((char *)v3 + 91) = 1;
-    *((char *)v3 + 90) = 1;
-  }
-  if ( a2 != *((int *)v3 + 17) || a3 != *((int *)v3 + 18) )
-  {
-    *((int *)v3 + 16) = v4;
-    *((int *)v3 + 17) = a2;
-    *((int *)v3 + 18) = a3;
-  }
-  return *((char *)v3 + 90);*/
-  return 0;
-}
-
-//----- (0046BAEC) --------------------------------------------------------
-void AsyncMouse::_46BAEC()
-{
-  void *v1; // esi@1
-
-  v1 = this;
-  EnterCriticalSection(&pGame->pThreadWardInstance->cs2);
-  *((char *)v1 + 88) = 0;
-}
-
-//----- (0046BB0A) --------------------------------------------------------
-void AsyncMouse::_46BB0A()
-{
-  __debugbreak();
-  /*
-  void *v1; // esi@1
-  int v2; // eax@1
-  int v3; // edx@1
-  int v4; // ecx@1
-  int v5; // edx@1
-  int v6; // eax@1
-  char v7; // zf@1
-  struct IDirectDrawSurface4 *v8; // ST08_4@8
-  int v9; // [sp+8h] [bp-74h]@8
-  int v10; // [sp+Ch] [bp-70h]@8
-  int v11; // [sp+6Ch] [bp-10h]@1
-  int v12; // [sp+70h] [bp-Ch]@1
-  int v13; // [sp+74h] [bp-8h]@1
-  int v14; // [sp+78h] [bp-4h]@1
-
-  v1 = this;
-  v2 = *((int *)this + 17) - *((int *)this + 10);
-  v3 = *((int *)this + 14);
-  v4 = *((int *)this + 18) - *((int *)this + 11);
-  v11 = v2;
-  v5 = v2 + v3;
-  v6 = *((int *)v1 + 15);
-  v12 = v4;
-  v7 = *((char *)v1 + 90) == 0;
-  v13 = v5;
-  v14 = v4 + v6;
-  if ( v7 || *((char *)v1 + 128) & 1 )
-  {
-    if ( *((char *)v1 + 88) )
-      pRenderer->pFrontBuffer4->BltFast(
-        *((int *)v1 + 8),
-        *((int *)v1 + 9),
-        (LPDIRECTDRAWSURFACE4)*((int *)v1 + 2),
-        (LPRECT)((char *)v1 + 48),
-        16u);
-    (*(void (__stdcall **)(int, int, int, IDirectDrawSurface4 *, int *, signed int))(**((int **)v1 + 2) + 28))(
-      *((int *)v1 + 2),
-      0,
-      0,
-      pRenderer->pFrontBuffer4,
-      &v11,
-      16);
-  }
-  if ( *((char *)v1 + 90) && !(*((char *)v1 + 128) & 1) )
-  {
-    v8 = (struct IDirectDrawSurface4 *)*((int *)v1 + 1);
-    v9 = 100;
-    v10 = 8;
-    pRenderer->pFrontBuffer4->Blt(
-      (LPRECT)&v11,
-      v8,
-      (LPRECT)((char *)v1 + 48),
-      16812032u,
-      (LPDDBLTFX)&v9);
-  }
-  LeaveCriticalSection(&pGame->pThreadWardInstance->cs2);*/
-}
-
-//----- (0046BBD0) --------------------------------------------------------
-void *AsyncMouse::Clip()
-{
-  __debugbreak();
-  /*
-  void *result; // eax@1
-  std::string v1; // [sp-18h] [bp-30h]@2
-  const char *v2; // [sp-8h] [bp-20h]@2
-  int v3; // [sp-4h] [bp-1Ch]@2
-  RECT Rect; // [sp+0h] [bp-18h]@1
-  std::string *v5; // [sp+10h] [bp-8h]@2
-  int a3; // [sp+17h] [bp-1h]@2
-
-  SetWindowPos(hWnd, HWND_MESSAGE|0x2, 320, 240, 640, 480, 0);
-  Rect.left = 325;
-  Rect.top = 245;
-  Rect.right = 326;
-  Rect.bottom = 246;
-  result = (void *)ClipCursor(&Rect);
-  if ( !result )
-  {
-          MessageBoxW(nullptr, L"Could not clip cursor to screen!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\MouseAsync.cpp:827", 0);
-  }
-  return result;*/
-  return 0;
-}
-
-//----- (0046BC4E) --------------------------------------------------------
-void __stdcall AsyncMouse::AsyncMouseThread(int a1)
-{
-  __debugbreak();
-  /*
-  while ( 1 )
-  {
-    while ( !pAsyncMouse )
-      Sleep(1);
-    if ( !AsyncMouse::Thread(pAsyncMouse) )
-      ExitThread(0);
-    Sleep(18);
-  }*/
-}
-
-//----- (0046BC73) --------------------------------------------------------
-void AsyncMouse::dtor_sub_46BC73()
-{
-  __debugbreak();
-  /*
-  int v1; // edi@1
-  void **v2; // ebx@1
-  void *v3; // esi@1
-  void *v4; // eax@2
-  int v5; // [sp+0h] [bp-4h]@1
-
-  v5 = this;
-  v1 = this;
-  v2 = *(void ***)(this + 4);
-  v3 = *v2;
-  while ( v3 != v2 )
-  {
-    v4 = v3;
-    v3 = *(void **)v3;
-    AsyncMouse::unk_46BD2D((void *)v1, (int)&v5, v4);
-  }
-  free(*(void **)(v1 + 4));
-  *(int *)(v1 + 4) = 0;
-  *(int *)(v1 + 8) = 0;*/
-}
-
-//----- (0046BCAB) --------------------------------------------------------
-int AsyncMouse::_46BCAB()
-{
-  __debugbreak();
-  /*
-  void *v1; // ebx@1
-  void **v2; // edi@1
-  void *v3; // esi@1
-  void *v4; // eax@2
-  int result; // eax@2
-  int v6; // [sp+0h] [bp-4h]@1
-
-  v6 = this;
-  v1 = (void *)this;
-  v2 = *(void ***)(this + 4);
-  v3 = *v2;
-  while ( v3 != v2 )
-  {
-    v4 = v3;
-    v3 = *(void **)v3;
-    result = AsyncMouse::unk_46BD2D(v1, (int)&v6, v4);
-  }
-  return result;*/
-  return 0;
-}
-// 46BCAB: using guessed type int __thiscall AsyncMouse__46BCAB(int);
-
-//----- (0046BCD2) --------------------------------------------------------
-int AsyncMouse::unk_46BCD2(int a2, int a3, int a4)
-{
-  __debugbreak();
-  /*
-  void *v4; // edi@1
-  void *v5; // eax@1
-  void *v6; // esi@1
-  int result; // eax@1
-
-  v4 = this;
-  v5 = AsyncMouse::unk_46BD09((void *)a3, *(void **)(a3 + 4));
-  v6 = v5;
-  *(int *)(a3 + 4) = v5;
-  **((int **)v5 + 1) = v5;
-  AsyncMouse::unk_46BD66((char *)v5 + 8, a4);
-  result = a2;
-  ++*((int *)v4 + 2);
-  *(int *)a2 = v6;
-  return result;*/
-  return 0;
-}
-// 46BD66: using guessed type int __fastcall AsyncMouse__unk__46BD66(int, int);
-
-//----- (0046BD09) --------------------------------------------------------
-void *AsyncMouse::unk_46BD09(void *a1, void *a2)
-{
-  __debugbreak();
-  /*
-  void *result; // eax@1
-  void *v3; // ecx@1
-  void *v4; // ecx@3
-
-  result = operator new(0x18u);
-  v3 = a1;
-  if ( !a1 )
-    v3 = result;
-  *(int *)result = v3;
-  v4 = a2;
-  if ( !a2 )
-    v4 = result;
-  *((int *)result + 1) = v4;
-  return result;*/
-  return 0;
-}
-
-//----- (0046BD2D) --------------------------------------------------------
-int AsyncMouse::unk_46BD2D(int a2, void *a3)
-{
-  __debugbreak();
-  /*
-  void *v3; // edi@1
-  int v4; // ebx@1
-  int result; // eax@1
-
-  v3 = this;
-  v4 = *(int *)a3;
-  **((int **)a3 + 1) = *(int *)a3;
-  *(int *)(*(int *)a3 + 4) = *((int *)a3 + 1);
-  (**((void (__stdcall ***)(int))a3 + 2))(0);
-  free(a3);
-  result = a2;
-  --*((int *)v3 + 2);
-  *(int *)a2 = v4;
-  return result;*/
-  return 0;
-}
-
-//----- (0046BD66) --------------------------------------------------------
-int AsyncMouse::unk_46BD66(int a1, int a2)
-{
-  int result; // eax@2
-
-  if ( a1 )
-  {
-    *(int *)(a1 + 4) = *(int *)(a2 + 4);
-    *(int *)(a1 + 8) = *(int *)(a2 + 8);
-    result = *(int *)(a2 + 12);
-    *(int *)(a1 + 12) = result;
-    //*(int *)a1 = &AsyncMouse::unk::vdtor_ptr;
-  }
-  return result;
-}
-// 46BD66: using guessed type int __fastcall AsyncMouse__unk__46BD66(int, int);
-// 4D8734: using guessed type int (__stdcall *AsyncMouse__unk__vdtor_ptr)(char);
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/*
-//----- (0043B9FF) --------------------------------------------------------
-DirectInputMouse *__thiscall DirectInputMouse::DirectInputMouse(DirectInputMouse *this)
-{
-  DirectInputMouse *v1; // esi@1
-  HRESULT v2; // eax@5
-  signed int v4; // [sp-18h] [bp-24h]@3
-  char *v5; // [sp-14h] [bp-20h]@3
-  int v6; // [sp-10h] [bp-1Ch]@3
-  const char *v7; // [sp-Ch] [bp-18h]@3
-  int v8; // [sp-8h] [bp-14h]@3
-  unsigned int v9; // [sp-4h] [bp-10h]@3
-  CheckHRESULT_stru0 v10; // [sp+8h] [bp-4h]@5
-
-  v1 = this;
-  this->field_8 = 0;
-  LOBYTE(this->field_1C) = 0;
-  this->field_28 = 0;
-  this->vdestructor_ptr = (int)&DirectInputMouse_pvdtor;
-  if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion != 4 )
-  {
-    v9 = 1;
-    v8 = 30;
-    v7 = "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\DirectInputMouse.cpp";
-    v6 = 0;
-    v5 = (char *)&this->pDirectInput;
-    v4 = 1280;
-  }
-  else
-  {
-    v9 = 1;
-    v8 = 28;
-    v7 = "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\DirectInputMouse.cpp";
-    v6 = 0;
-    v5 = (char *)&this->pDirectInput;
-    v4 = 768;
-  }
-  v2 = DirectInputCreateA(hInstance, v4, v5, v6);
-  CheckHRESULT(&v10, v2, v7, v8, v9);
-  DirectInputMouse::CreateDevice(v1);
-  DirectInputMouse::43BB18(v1);
-  v1->field_20 = 0;
-  v1->field_24 = 0;
-  return v1;
-}
-// 4C8880: using guessed type int __stdcall DirectInputCreateA(int, int, int, int);
-// 4D8608: using guessed type int (__stdcall *DirectInputMouse_pvdtor)(char);
-
-//----- (0043BA80) --------------------------------------------------------
-void *__thiscall DirectInputMouse::vdtor(void *this, bool a2)
-{
-  void *v2; // esi@1
-
-  v2 = this;
-  DirectInputMouse::dtor(this);
-  if ( a2 & 1 )
-    free(v2);
-  return v2;
-}
-
-//----- (0043BA9C) --------------------------------------------------------
-int __thiscall DirectInputMouse::dtor(void *this)
-{
-  void *v1; // esi@1
-  int v2; // eax@1
-  int result; // eax@3
-
-  v1 = this;
-  v2 = *((int *)this + 2);
-  *(int *)this = &DirectInputMouse_pvdtor;
-  if ( v2 )
-  {
-    (*(void (__stdcall **)(int))(*(int *)v2 + 32))(v2);
-    (*(void (__stdcall **)(int))(**((int **)v1 + 2) + 8))(*((int *)v1 + 2));
-    *((int *)v1 + 2) = 0;
-  }
-  result = (*(int (__stdcall **)(int))(**((int **)v1 + 1) + 8))(*((int *)v1 + 1));
-  *((int *)v1 + 1) = 0;
-  return result;
-}
-// 4D8608: using guessed type int (__stdcall *DirectInputMouse_pvdtor)(char);
-
-//----- (0043BACE) --------------------------------------------------------
-void __thiscall DirectInputMouse::CreateDevice(DirectInputMouse *this)
-{
-  DirectInputMouse *v1; // esi@1
-  HRESULT v2; // eax@1
-  CheckHRESULT_stru0 v3; // [sp+4h] [bp-4h]@1
-
-  v1 = this;
-  v2 = ((int (__stdcall *)(int, int, int, int, int))this->pDirectInput->lpVtbl->field_10)(
-         this->pDirectInput,
-         2,
-         DirectInputMouse_enumerator,
-         this,
-         1);
-  CheckHRESULT(&v3, v2, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\DirectInputMouse.cpp", 57, 1u);
-  if ( !LOBYTE(v1->field_1C) )
-  {
-    v3.vdestructor_ptr = (void (__thiscall ***)(CheckHRESULT_stru0 *, bool))"Error: No mouse found";
-    _CxxThrowException((int)&v3, (int)&dword_4DBD94);
-  }
-}
-// 43BC61: using guessed type int __stdcall DirectInputMouse_enumerator(int, int);
-// 4DBD94: using guessed type int dword_4DBD94;
-
-//----- (0043BB18) --------------------------------------------------------
-int __thiscall DirectInputMouse::43BB18(DirectInputMouse *this)
-{
-  char *v1; // esi@1
-  HRESULT v2; // eax@1
-  HRESULT v3; // eax@1
-  HRESULT v4; // eax@1
-  unsigned int v6; // [sp+0h] [bp-Ch]@0
-  CheckHRESULT_stru0 v7; // [sp+8h] [bp-4h]@1
-
-  v1 = (char *)&this->field_8;
-  v2 = ((int (__stdcall *)(int, int, int, int, int))this->pDirectInput->lpVtbl->field_C)(
-         this->pDirectInput,
-         &this->field_C,
-         &this->field_8,
-         0,
-         "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\DirectInputMouse.cpp");
-  CheckHRESULT(&v7, v2, (const char *)0x40, 1, v6);
-  v3 = (*(int (__stdcall **)(int, int))(**(int **)v1 + 44))(*(int *)v1, dword_4C9920);
-  CheckHRESULT(&v7, v3, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\DirectInputMouse.cpp", 65, 1u);
-  v4 = (*(int (__stdcall **)(int, int, int))(**(int **)v1 + 52))(*(int *)v1, hWnd, 6);
-  CheckHRESULT(&v7, v4, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\DirectInputMouse.cpp", 66, 1u);
-  return (*(int (__cdecl **)(int))(**(int **)v1 + 28))(*(int *)v1);
-}
-// 4C9920: using guessed type int dword_4C9920[16];
-
-//----- (0043BB89) --------------------------------------------------------
-bool __thiscall DirectInputMouse::43BB89(DirectInputMouse *this)
-{
-  DirectInputMouse *v1; // esi@1
-  bool result; // eax@1
-  HRESULT v3; // eax@5
-  __int32 v4; // ecx@6
-  __int32 v5; // eax@6
-  __int32 v6; // edx@6
-  int v7; // ecx@12
-  bool v8; // ecx@12
-  signed int v9; // edx@12
-  HRESULT a2; // [sp+4h] [bp-14h]@3
-  int v11; // [sp+8h] [bp-10h]@12
-  char v12; // [sp+10h] [bp-8h]@18
-  char v13; // [sp+11h] [bp-7h]@20
-  char v14; // [sp+12h] [bp-6h]@22
-  char v15; // [sp+13h] [bp-5h]@24
-  char v18; // [sp+14h] [bp-4h]@5
-
-  v1 = this;
-  result = this->field_8;
-  if ( result )
-  {
-    if ( (*(int (__stdcall **)(bool, signed int, HRESULT *))(*(int *)result + 36))(result, 16, &a2) == -2147024866
-      && !(*(int (__stdcall **)(int))(*(int *)v1->field_8 + 28))(v1->field_8) )
-    {
-      v3 = (*(int (__stdcall **)(int, signed int, HRESULT *))(*(int *)v1->field_8 + 36))(v1->field_8, 16, &a2);
-      CheckHRESULT((CheckHRESULT_stru0 *)&v18, v3, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\DirectInputMouse.cpp", 80, 1u);
-    }
-    v4 = v1->field_20 + a2;
-    v5 = 640;
-    v6 = v1->field_20 + a2;
-    if ( v4 >= 640 )
-      v6 = 640;
-    if ( v6 >= 0 )
-    {
-      if ( v4 < 640 )
-        v5 = v1->field_20 + a2;
-    }
-    else
-    {
-      v5 = 0;
-    }
-    v7 = v11;
-    v1->field_20 = v5;
-    v8 = v1->field_24 + v7;
-    result = 480;
-    v9 = v8;
-    if ( v8 >= 480 )
-      v9 = 480;
-    if ( v9 >= 0 )
-    {
-      if ( v8 < 480 )
-        result = v8;
-    }
-    else
-    {
-      result = 0;
-    }
-    v1->field_28 = 0;
-    v1->field_24 = result;
-    if ( v12 & 0x80 )
-      v1->field_28 = 1;
-    if ( v13 & 0x80 )
-      v1->field_28 |= 2u;
-    if ( v14 & 0x80 )
-      v1->field_28 |= 4u;
-    if ( v15 & 0x80 )
-      v1->field_28 |= 8u;
-    LOBYTE(result) = 1;
-  }
-  else
-  {
-    LOBYTE(result) = 0;
-  }
-  return result;
-}
-
-//----- (0043BC61) --------------------------------------------------------
-signed int __stdcall DirectInputMouse_enumerator(int a1, int a2)
-{
-  signed int result; // eax@2
-
-  if ( *(char *)(a1 + 36) & 2 )
-  {
-    *(int *)(a2 + 12) = *(int *)(a1 + 4);
-    *(int *)(a2 + 16) = *(int *)(a1 + 8);
-    *(int *)(a2 + 20) = *(int *)(a1 + 12);
-    *(int *)(a2 + 24) = *(int *)(a1 + 16);
-    *(char *)(a2 + 28) = 1;
-    result = 0;
-  }
-  else
-  {
-    result = 1;
-  }
-  return result;
-}
-// 43BC61: using guessed type int __stdcall DirectInputMouse_enumerator(int, int);
-*/
\ No newline at end of file
--- a/Mouse.h	Thu May 23 21:36:57 2013 +0600
+++ b/Mouse.h	Thu May 23 21:37:22 2013 +0600
@@ -135,53 +135,7 @@
 #pragma pack(pop)
 
 
-#pragma pack(push, 1)
-struct AsyncMouse
-{
-   AsyncMouse(struct IDirectDrawSurface *);
-  ~AsyncMouse();
-
-  char Initialize(LPVOID lpParameter);
-  char LoadCursor(const char *pContainer);
-  char LoadCursorImage();
-  char _46B072();
-  char CreateDisrectInputMouse();
-  int _46B0ED();
-  void Resume();
-  void Suspend();
-  char _46B1DD();
-  bool DrawCursor(struct Texture *a1, struct IDirectDrawSurface4 *a2, int a3);
-  bool _46B289(int a2, char a3);
-  void SetHotspot(float hotspotx, float hotspoty);
-  int UpdateData(int a2);
-  char Thread();
-  void _46B492(int a2);
-  void _46B5D5(int a2);
-  void _46B736_consume_click_lists(char a2);
-  void _46B76F();
-  void _46B879();
-  int _46B944();
-  char _46B958(int a2, int a3);
-  char _46BA8D(int a2, int a3);
-  void _46BAEC();
-  void _46BB0A();
-  void *Clip();
-  void dtor_sub_46BC73();
-  int _46BCAB();
-  int unk_46BCD2(int a2, int a3, int a4);
-  void *unk_46BD09(void *a1, void *a2);
-  int unk_46BD2D(int a2, void *a3);
-  int unk_46BD66(int a1, int a2);
-
-  static void __stdcall AsyncMouseThread(int a1);
-
-  void _409E3D(char a2);
-  void Release();
-};
-#pragma pack(pop)
 
 
 
-
-extern Mouse *pMouse;
-extern AsyncMouse *pAsyncMouse;
\ No newline at end of file
+extern Mouse *pMouse;
\ No newline at end of file
--- a/OSAPI.cpp	Thu May 23 21:36:57 2013 +0600
+++ b/OSAPI.cpp	Thu May 23 21:37:22 2013 +0600
@@ -6,6 +6,7 @@
 OSVersion *pVersion = nullptr;
 
 
+
 //----- (00462C94) --------------------------------------------------------
 int __stdcall wWinMain(HINSTANCE hInstance, HINSTANCE, wchar_t *lpCmdLine, int nShowCmd)
 {
--- a/Outdoor.h	Thu May 23 21:36:57 2013 +0600
+++ b/Outdoor.h	Thu May 23 21:37:22 2013 +0600
@@ -3,6 +3,7 @@
 #include "Indoor.h"
 #include "TileFrameTable.h"
 #include "Weather.h"
+#include "BSPModel.h"
 
 #define DAY_ATTRIB_FOG  1
 
@@ -195,7 +196,7 @@
   unsigned int uNumBModels;
   struct OutdoorLocationTerrain pTerrain;
   void *pCmap;
-  struct BSPModel *pBModels;
+  BSPModel *pBModels;
   unsigned int numFaceIDListElems;
   unsigned __int16 *pFaceIDLIST;
   unsigned int *pOMAP;
--- a/Party.h	Thu May 23 21:36:57 2013 +0600
+++ b/Party.h	Thu May 23 21:37:22 2013 +0600
@@ -17,6 +17,8 @@
   PARTY_QUEST_EMERALD_LUTE_ACTIVE = 5,
   PARTY_QUEST_EMERALD_HAT_ACTIVE = 6,
 
+  PARTY_QUEST_EMERALD_MARGARETH_OFF = 17,
+
   PARTY_QUEST_EVENMORN_MAP_FOUND = 64,
   PARTY_QUEST_FINISHED_EMERALD_ISLE = 136,
   PARTY_QUEST_FOUNTAIN_HARMONDALE = 206,
--- a/Player.cpp	Thu May 23 21:36:57 2013 +0600
+++ b/Player.cpp	Thu May 23 21:37:22 2013 +0600
@@ -103,14 +103,14 @@
 unsigned char pAgeingSpeedMultiplier[4]        = {100, 100,  40, 10};
 unsigned char pAgeingLuckMultiplier[4]         = {100, 100, 100, 100};
 
-unsigned int pAgeingTable[4] = {50, 100, 150, 65535};
+signed int pAgeingTable[4] = {50, 100, 150, 0xFFFF};
 
 unsigned int pConditionImportancyTable[18] = {16, 15, 14, 17, 13, 2, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 1, 0};
 
-short word_4EDFFC[30] = {500, 400, 350, 300, 275, 250, 225, 200, 175,
+short param_to_bonus_table[29] = {500, 400, 350, 300, 275, 250, 225, 200, 175,
                          150, 125, 100,  75,  50,  40,  35,  30,  25,  21,
-                         19,   17,  15,  13,  11,   9,   7,   5,   3,   0, 0};
-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};
+                         19,   17,  15,  13,  11,   9,   7,   5,   3,   0};
+signed int parameter_to_bonus_value[29] = {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};
 
 
 unsigned char pEquipTypeToBodyAnchor[20] = {1, 1, 2, 3, 0, 4, 5, 6, 7, 8, 10, 9, 1, 0, 0, 0, 0, 0, 0, 0};
@@ -264,9 +264,9 @@
 
 
 //----- (004B8040) --------------------------------------------------------
-int Player::_4B8040_condition_time(unsigned int uCondition)
-{
-  return (unsigned int)((signed __int64)((double)this->pConditions[uCondition] * 0.234375) / 60 / 60) / 0x18 % 7 + 1;
+int Player::GetConditionDayOfWeek( unsigned int uCondition )
+    {
+  return (unsigned int)(((signed __int64)((double)this->pConditions[uCondition] * 0.234375) / 60 / 60) / 24) % 7 + 1;
 }
 
 //----- (004B807C) --------------------------------------------------------
@@ -298,7 +298,7 @@
       v10 = 10;
       v9 = 16;
 LABEL_6:
-      v11 = _4B8040_condition_time(v9);
+      v11 = GetConditionDayOfWeek(v9);
       goto LABEL_13;
     }
   }
@@ -306,7 +306,7 @@
   v5 = 0;
   do
   {
-    v6 = _4B8040_condition_time(v5);
+    v6 = GetConditionDayOfWeek(v5);
     if ( v6 > v4 )
       v4 = v6;
     ++v5;
@@ -2574,42 +2574,41 @@
 //----- (0048CC33) --------------------------------------------------------
 int Player::GetActualLuck()
 {
-  Player *v1; // esi@1
-  unsigned int v2; // eax@7
-  signed int v3; // ecx@7
-  signed int v4; // ebx@10
-  int v5; // edi@11
-  int v6; // ebp@11
-  signed int v8; // [sp+10h] [bp-4h]@1
-
-  v8 = 0;
-  v1 = this;
+  signed int curr_age; // eax@7
+  signed int i; // ecx@7
+  signed int age_luck_pc; // ebx@10
+  int condition_luck_pc; // edi@11
+  int items_luck_bonus; // ebp@11
+  signed int npc_luck_bonus; // [sp+10h] [bp-4h]@1
+  signed int magic_luck_bonus; // [sp+10h] [bp-4h]@1
+  int full_luck;
+
+  npc_luck_bonus = 0;
   if ( CheckHiredNPCSpeciality(Fool) )
-    v8 = 5;
+    npc_luck_bonus = 5;
   if ( CheckHiredNPCSpeciality(ChimneySweep) )
-    v8 += 20;
+    npc_luck_bonus += 20;
   if ( CheckHiredNPCSpeciality(Psychic) )
-    v8 += 10;
-  v2 = v1->sAgeModifier + GetBaseAge();
-  v3 = 0;
-  while ( (signed int)v2 >= (signed int)pAgeingTable[v3] )
-  {
-    ++v3;
-    if ( v3 >= 4 )
-    {
-      v4 = 100;
-      goto LABEL_11;
-    }
-  }
-  v4 = pAgeingLuckMultiplier[v3];
-LABEL_11:
-  v5 = pConditionLuckMultiplier[GetMajorConditionIdx()];
-  v6 = GetItemsBonus(CHARACTER_ATTRIBUTE_LUCK, 0);
-  return GetMagicalBonus(CHARACTER_ATTRIBUTE_LUCK)
-       + v6
-       + v8
-       + v5 * v4 * v1->uLuck / 100 / 100
-       + v1->uLuckBonus;
+    npc_luck_bonus += 10;
+  curr_age = sAgeModifier + GetBaseAge();
+  i = 0;
+  while ( curr_age >= pAgeingTable[i] )
+  {
+    ++i;
+    if ( i >= 4 )
+      break;
+  }
+  if (i < 4)
+    age_luck_pc = pAgeingLuckMultiplier[i];
+  else
+    age_luck_pc = 100;
+
+  condition_luck_pc = pConditionLuckMultiplier[GetMajorConditionIdx()];
+  items_luck_bonus = GetItemsBonus(CHARACTER_ATTRIBUTE_LUCK, 0);
+  magic_luck_bonus = GetMagicalBonus(CHARACTER_ATTRIBUTE_LUCK);
+  full_luck = magic_luck_bonus  + items_luck_bonus   + npc_luck_bonus+  uLuckBonus
+                + condition_luck_pc * age_luck_pc * uLuck / 100 / 100;
+   return full_luck;
 }
 
 //----- (0048CCF5) --------------------------------------------------------
@@ -2623,7 +2622,7 @@
 
   v2 = this;
   v3 = GetActualAccuracy();
-  v4 = _48EA1B_get_static_effect(v3);
+  v4 = GetParameterBonus(v3);
   v5 = GetSkillBonus(CHARACTER_ATTRIBUTE_ATTACK);
   v6 = GetItemsBonus(CHARACTER_ATTRIBUTE_ATTACK, a2);
   return v4 + v5 + v6 + GetMagicalBonus(CHARACTER_ATTRIBUTE_ATTACK) + v2->_some_attack_bonus;
@@ -2640,15 +2639,14 @@
   int v6; // esi@1
   signed int result; // eax@1
 
-  v1 = this;
+ 
   v2 = GetActualMight();
-  v3 = _48EA1B_get_static_effect(v2);
+  v3 = GetParameterBonus(v2);
   v4 = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MIN, 0) + v3;
   v5 = GetSkillBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS) + v4;
-  v6 = v1->_melee_dmg_bonus + GetMagicalBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS) + v5;
-  result = 1;
-  if ( v6 >= 1 )
-    result = v6;
+  result = _melee_dmg_bonus + GetMagicalBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS) + v5;
+  if ( result < 1 )
+    result = 1;
   return result;
 }
 
@@ -2665,7 +2663,7 @@
 
   v1 = this;
   v2 = GetActualMight();
-  v3 = _48EA1B_get_static_effect(v2);
+  v3 = GetParameterBonus(v2);
   v4 = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MAX, 0) + v3;
   v5 = GetSkillBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS) + v4;
   v6 = v1->_melee_dmg_bonus + GetMagicalBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS) + v5;
@@ -2868,7 +2866,7 @@
   if ( !a2 )
   {
     v22 = GetActualMight();
-    v23 = _48EA1B_get_static_effect(v22);
+    v23 = GetParameterBonus(v22);
     v24 = GetSkillBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS) + v23;
     v21 += v5->_melee_dmg_bonus + GetMagicalBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS) + v24;
   }
@@ -2894,7 +2892,7 @@
   if ( v2 < 64 || v2 > 65 )
   {
     v4 = GetActualAccuracy();
-    v5 = _48EA1B_get_static_effect(v4);
+    v5 = GetParameterBonus(v4);
     v6 = GetItemsBonus(CHARACTER_ATTRIBUTE_RANGED_ATTACK, 0) + v5;
     v7 = GetSkillBonus(CHARACTER_ATTRIBUTE_RANGED_ATTACK) + v6;
     v3 = v1->_ranged_atk_bonus + GetMagicalBonus(CHARACTER_ATTRIBUTE_RANGED_ATTACK) + v7;
@@ -2917,9 +2915,9 @@
   int result; // eax@6
 
   v1 = this;
-  v2 = GetItemsBonus(CHARACTER_ATTRIBUTE_RANGED_DAMAGE_MIN, 0);
-  v3 = GetSkillBonus(CHARACTER_ATTRIBUTE_RANGED_DAMAGE_BONUS) + v2;
-  v4 = v1->_ranged_dmg_bonus + GetMagicalBonus(CHARACTER_ATTRIBUTE_RANGED_DAMAGE_BONUS) + v3;
+  v2 = GetItemsBonus(CHARACTER_ATTRIBUTE_RANGED_DMG_MIN, 0);
+  v3 = GetSkillBonus(CHARACTER_ATTRIBUTE_RANGED_DMG_BONUS) + v2;
+  v4 = v1->_ranged_dmg_bonus + GetMagicalBonus(CHARACTER_ATTRIBUTE_RANGED_DMG_BONUS) + v3;
   v5 = v1->pActiveSkills[5];
   if ( v5 && (signed int)SkillToMastery(v5) >= 4 && HasItemEquipped(EQUIP_BOW) )
     v4 += v1->pActiveSkills[5] & 0x3F;
@@ -2941,9 +2939,9 @@
   int result; // eax@6
 
   v1 = this;
-  v2 = GetItemsBonus(CHARACTER_ATTRIBUTE_RANGED_DAMAGE_MAX, 0);
-  v3 = GetSkillBonus(CHARACTER_ATTRIBUTE_RANGED_DAMAGE_BONUS) + v2;
-  v4 = v1->_ranged_dmg_bonus + GetMagicalBonus(CHARACTER_ATTRIBUTE_RANGED_DAMAGE_BONUS) + v3;
+  v2 = GetItemsBonus(CHARACTER_ATTRIBUTE_RANGED_DMG_MAX, 0);
+  v3 = GetSkillBonus(CHARACTER_ATTRIBUTE_RANGED_DMG_BONUS) + v2;
+  v4 = v1->_ranged_dmg_bonus + GetMagicalBonus(CHARACTER_ATTRIBUTE_RANGED_DMG_BONUS) + v3;
   v5 = v1->pActiveSkills[5];
   if ( v5 && (signed int)SkillToMastery(v5) >= 4 && HasItemEquipped(EQUIP_BOW) )
     v4 += v1->pActiveSkills[5] & 0x3F;
@@ -3038,114 +3036,97 @@
 //----- (0048D2EA) --------------------------------------------------------
 char *Player::GetMeleeDamageString()
 {
-  Player *v1; // esi@1
-  signed int v2; // eax@1
-  signed int v3; // edi@3
-  signed int v4; // eax@3
-  signed int v5; // ST0C_4@6
-  char *v6; // edi@6
-  signed int v7; // ST08_4@7
-  unsigned int v8; // eax@8
-  signed int v9; // esi@9
+signed int itemid; // eax@1
+int min_damage; // edi@3
+int max_damage; // eax@3
 
   static char player__getmeleedamagestring_static_buff[40]; // idb
 
-  v1 = this;
-  v2 = *(int *)&this->pInventoryItems[this->pEquipment.uMainHand-1];
-  if ( v2 < 64 || v2 > 65 )
-  {
-    v3 = GetMeleeDamageMinimal();
-    v4 = GetMeleeDamageMaximal();
-  }
+  if ( pEquipment.uMainHand)
+      {
+      itemid= pOwnItems[this->pEquipment.uMainHand-1].uItemID;
+      if ( itemid < 64 || itemid > 65 ) //blasters
+          {
+          min_damage = GetMeleeDamageMinimal();
+          max_damage = GetMeleeDamageMaximal();
+          }
+      else
+          {  //for blasters
+          min_damage = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MIN, 0);
+          max_damage = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MAX, 0);
+          }
+      if ( max_damage )
+          {
+          if ( min_damage == max_damage )
+              {
+              sprintf(player__getmeleedamagestring_static_buff, "%d", min_damage);
+              }
+          else
+              {
+              sprintf(player__getmeleedamagestring_static_buff, "%d - %d", min_damage, max_damage);
+              }
+          }
+      else
+          {
+          strcpy(player__getmeleedamagestring_static_buff, "N/A");
+          }
+
+      if (( itemid >= 135 )&&( itemid <= 159 )) //wands
+          {
+          strcpy(player__getmeleedamagestring_static_buff, pGlobalTXT_LocalizationStrings[595]); //"Wand"
+          }
+      }
   else
-  {
-    v3 = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MIN, 0);
-    v4 = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MAX, 0);
-  }
-  if ( v3 == v4 )
-  {
-    v5 = v3;
-    v6 = player__getmeleedamagestring_static_buff;
-    sprintf(player__getmeleedamagestring_static_buff, "%d", v5);
-  }
-  else
-  {
-    v7 = v3;
-    v6 = player__getmeleedamagestring_static_buff;
-    sprintf(player__getmeleedamagestring_static_buff, "%d - %d", v7, v4);
-  }
-  v8 = v1->pEquipment.uMainHand;
-  if ( v8 )
-  {
-    v9 = *(int *)&v1->pInventoryItems[v8-1];
-    if ( v9 >= 135 )
-    {
-      if ( v9 <= 159 )
-        strcpy(v6, pGlobalTXT_LocalizationStrings[595]);
-    }
-  }
-  return v6;
+      strcpy(player__getmeleedamagestring_static_buff, "N/A");
+  return player__getmeleedamagestring_static_buff;
 }
 
 //----- (0048D396) --------------------------------------------------------
 char *Player::GetRangedDamageString()
-{
-  Player *v1; // esi@1
-  signed int v2; // eax@1
-  int v3; // edi@3
-  int v4; // eax@3
-  char *v5; // edi@6
-  int v6; // ST0C_4@8
-  int v7; // ST08_4@9
-  unsigned int v8; // eax@10
-  signed int v9; // esi@11
-  
-  static char player__getrangeddamagestring_static_buff[40]; // idb
-
-  v1 = this;
-  v2 = *(int *)&this->pInventoryItems[this->pEquipment.uMainHand-1];
-  if ( v2 < 64 || v2 > 65 )
-  {
-    v3 = GetRangedDamageMin();
-    v4 = GetRangedDamageMax();
-  }
-  else
-  {
-    v3 = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MIN, 1);
-    v4 = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MAX, 1);
-  }
-  if ( v4 )
-  {
-    if ( v3 == v4 )
-    {
-      v6 = v3;
-      v5 = player__getrangeddamagestring_static_buff;
-      sprintf(player__getrangeddamagestring_static_buff, "%d", v6);
-    }
+    {
+    signed int itemid; // eax@1
+    int min_damage; // edi@3
+    int max_damage; // eax@3
+
+    static char player__getrangeddamagestring_static_buff[40]; // idb
+    if ( pEquipment.uMainHand)
+        {
+        itemid= pOwnItems[this->pEquipment.uMainHand-1].uItemID;
+        if ( itemid < 64 || itemid > 65 ) //blasters
+            {
+            min_damage = GetRangedDamageMin();
+            max_damage = GetRangedDamageMax();
+            }
+        else
+            {  //for blasters
+            min_damage = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MIN, 1);
+            max_damage = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MAX, 1);
+            }
+        if ( max_damage )
+            {
+            if ( min_damage == max_damage )
+                {
+                sprintf(player__getrangeddamagestring_static_buff, "%d", min_damage);
+                }
+            else
+                {
+                sprintf(player__getrangeddamagestring_static_buff, "%d - %d", min_damage, max_damage);
+                }
+            }
+        else
+            {
+            strcpy(player__getrangeddamagestring_static_buff, "N/A");
+            }
+
+        if (( itemid >= 135 )&&( itemid <= 159 )) //wands
+            {
+            strcpy(player__getrangeddamagestring_static_buff, pGlobalTXT_LocalizationStrings[595]); //"Wand"
+            }
+        }
     else
-    {
-      v7 = v3;
-      v5 = player__getrangeddamagestring_static_buff;
-      sprintf(player__getrangeddamagestring_static_buff, "%d - %d", v7, v4);
-    }
-  }
-  else
-  {
-    v5 = player__getrangeddamagestring_static_buff;
-    strcpy(player__getrangeddamagestring_static_buff, "N/A");
-  }
-  v8 = v1->pEquipment.uMainHand;
-  if ( v8 )
-  {
-    v9 = *(int *)&v1->pInventoryItems[v8-1];
-    if ( v9 >= 135 )
-    {
-      if ( v9 <= 159 )
-        strcpy(v5, pGlobalTXT_LocalizationStrings[595]);
-    }
-  }
-  return v5;
-}
+        strcpy(player__getrangeddamagestring_static_buff, "N/A");
+    return player__getrangeddamagestring_static_buff;
+    }
 
 //----- (0048D45A) --------------------------------------------------------
 bool Player::CanTrainToNextLevel()
@@ -3174,117 +3155,74 @@
 }
 
 //----- (0048D4B3) --------------------------------------------------------
-int Player::CalculateIncommingDamage(int resistance, signed int type)
-{
-  Player *v3; // esi@1
-  int v4; // edi@8
-  int v6; // eax@21
-  signed int v7; // ebx@21
-  int v8; // eax@22
-  signed int v9; // ebx@22
-  int v10; // eax@23
-  signed int v11; // ebx@23
-  int v12; // eax@24
-  signed int v13; // edi@24
-  unsigned int v14; // eax@27
-  int v15; // eax@29
-  double v16; // st7@32
-  enum CHARACTER_ATTRIBUTE_TYPE v17; // [sp-4h] [bp-10h]@9
-  signed int v18; // [sp+8h] [bp-4h]@17
-
-  v3 = this;
-  if ( !resistance )
-  {
-    v17 = (CHARACTER_ATTRIBUTE_TYPE)10;
-    goto LABEL_16;
-  }
-  if ( resistance == 1 )
-  {
-    v17 = (CHARACTER_ATTRIBUTE_TYPE)11;
-    goto LABEL_16;
-  }
-  if ( resistance == 2 )
-  {
-    v17 = (CHARACTER_ATTRIBUTE_TYPE)12;
-    goto LABEL_16;
-  }
-  if ( resistance == 3 )
-  {
-    v17 = (CHARACTER_ATTRIBUTE_TYPE)13;
-    goto LABEL_16;
-  }
-  if ( resistance == 6 )
-  {
-    v17 = (CHARACTER_ATTRIBUTE_TYPE)33;
-    goto LABEL_16;
-  }
-  if ( resistance == 7 )
-  {
-    v17 = (CHARACTER_ATTRIBUTE_TYPE)14;
-    goto LABEL_16;
-  }
-  if ( resistance == 8 )
-  {
-    v17 = (CHARACTER_ATTRIBUTE_TYPE)15;
-LABEL_16:
-    v4 = GetActualResistance(v17);
-    goto LABEL_17;
-  }
-  v4 = 0;
-LABEL_17:
-  v18 = type;
-  if ( v3->classType == PLAYER_CLASS_LICH && v4 >= 200 )
+int Player::CalculateIncommingDamage( DAMAGE_TYPE dmg_type, int amount )
+    {
+
+  int resist_value; // edi@8
+  int player_luck; // eax@21
+  signed int res_rand_divider; // ebx@2
+  int armor_skill; // eax@29
+  enum CHARACTER_ATTRIBUTE_TYPE player_resist; // [sp-4h] [bp-10h]@9
+  signed int result_amount_dmg; // [sp+8h] [bp-4h]@17
+
+  player_resist=CHARACTER_ATTRIBUTE_STRENGTH;
+  switch(dmg_type)
+      {
+      case DMGT_FIRE:   player_resist=CHARACTER_ATTRIBUTE_RESIST_FIRE; break;
+      case DMGT_ELECTR: player_resist=CHARACTER_ATTRIBUTE_RESIST_AIR;  break;
+      case DMGT_COLD:   player_resist=CHARACTER_ATTRIBUTE_RESIST_WATER; break;
+      case DMGT_3: player_resist=CHARACTER_ATTRIBUTE_RESIST_EARTH; break;
+      
+      case DMGT_SPIRIT: player_resist=CHARACTER_ATTRIBUTE_RESIST_SPIRIT;break;
+      case DMGT_MIND: player_resist=CHARACTER_ATTRIBUTE_RESIST_MIND; break;
+      case DMGT_BODY: player_resist=CHARACTER_ATTRIBUTE_RESIST_BODY; break;
+      }
+  if (player_resist)
+    resist_value = GetActualResistance(player_resist);
+  else
+    resist_value = 0;
+
+  result_amount_dmg = amount;
+  if ( classType == PLAYER_CLASS_LICH && resist_value >= 200 )
     return 0;
-  if ( v4 )
-  {
-    v6 = GetActualLuck();
-    v7 = _48EA1B_get_static_effect(v6) + v4 + 30;
-    if ( rand() % v7 >= 30 )
-    {
-      v18 = type >> 1;
-      v8 = GetActualLuck();
-      v9 = _48EA1B_get_static_effect(v8) + v4 + 30;
-      if ( rand() % v9 >= 30 )
+  player_luck = GetActualLuck();
+  res_rand_divider = GetParameterBonus(player_luck) + resist_value + 30;
+
+  if ( resist_value )
+  { 
+    if ( rand() % res_rand_divider >= 30 )
+    {
+      result_amount_dmg = amount >> 1;
+      if ( rand() % res_rand_divider >= 30 )
       {
-        v18 = type >> 2;
-        v10 = GetActualLuck();
-        v11 = _48EA1B_get_static_effect(v10) + v4 + 30;
-        if ( rand() % v11 >= 30 )
+        result_amount_dmg = amount >> 2;
+        if ( rand() % res_rand_divider >= 30 )
         {
-          v18 = type >> 3;
-          v12 = GetActualLuck();
-          v13 = _48EA1B_get_static_effect(v12) + v4 + 30;
-          if ( rand() % v13 >= 30 )
-            v18 = type >> 4;
+          result_amount_dmg = amount >> 3;
+          if ( rand() % res_rand_divider >= 30 )
+            result_amount_dmg = amount >> 4;
         }
       }
     }
   }
-  if ( resistance == 4 )
-  {
-    v14 = v3->pEquipment.uArmor;
-    if ( v14 )
-    {
-     // if ( !(v3->field_1F5[36 * v14 + 15] & 2) )
-      if (v3->pOwnItems[v14-1].uAttributes&2) 
+  if (( dmg_type == DMGT_PHISYCAL )&&( pEquipment.uArmor ))
+  {
+      if (!pOwnItems[pEquipment.uArmor-1].Broken()) 
       {
-        v15 = GetEquippedItemSkillType(EQUIP_ARMOUR) - 10;
-        if ( v15 )
+        armor_skill = GetEquippedItemSkillType(EQUIP_ARMOUR);
+        if ( armor_skill==PLAYER_SKILL_PLATE )
         {
-          if ( v15 != 1 || (signed int)SkillToMastery(v3->pActiveSkills[11]) < 3 )
-            return v18;
-          v16 = (double)v18 * 0.5;
-          return (signed __int64)v16;
+          if ( SkillToMastery(pActiveSkills[PLAYER_SKILL_PLATE]) >= 3 )
+              return (int)(double)result_amount_dmg * 0.5;
         }
-        if ( (signed int)SkillToMastery(v3->pActiveSkills[10]) >= 4 )
+        if (armor_skill==PLAYER_SKILL_CHAIN )
         {
-          v16 = (double)v18 * 0.66670001;
-          return (signed __int64)v16;
+          if (SkillToMastery(pActiveSkills[PLAYER_SKILL_CHAIN]) == 4) 
+             return (int)(double)result_amount_dmg * 0.66670001;
         }
       }
-    }
-  }
-  return v18;
+  }
+  return result_amount_dmg;
 }
 
 //----- (0048D62C) --------------------------------------------------------
@@ -3311,8 +3249,9 @@
 {
   auto i = pEquipment.pIndices[uEquipIndex];
   if (i)
-    return ~pInventoryItems[i - 1].uAttributes & 0x02;
-  else return false;
+    return ~(pInventoryItems[i - 1].uAttributes & ITEM_BROKEN);
+  else 
+    return false;
 }
 
 //----- (0048D6D0) --------------------------------------------------------
@@ -3588,58 +3527,45 @@
 }
 
 //----- (0048DC1E) --------------------------------------------------------
-int Player::ReceiveDamage(signed int type, int resistance)
-{
-  Player *v3; // esi@1
-  signed int v4; // eax@1
-  int v5; // eax@1
-  bool v6; // ebx@1
-  unsigned int v7; // eax@8
-  char *v8; // ecx@9
-  int v9; // eax@9
-  //signed int typea; // [sp+14h] [bp+8h]@1
-
-  v3 = this;
-  this->pConditions[Condition_Sleep] = 0i64;
-  v4 = CalculateIncommingDamage(resistance, type);
-  v3->sHealth -= v4;
-  //typea = v4;
-  v5 = v3->sHealth;
-  v6 = v5 < -10;
-  LOBYTE(v6) = v5 <= -10;
-  if ( v5 < 1 )
-  {
-    if ( v3->sHealth + v3->uEndurance + GetItemsBonus(CHARACTER_ATTRIBUTE_ENDURANCE, 0) >= 1
-      || (signed __int64)v3->pPlayerBuffs[PLAYER_BUFF_PRESERVATION].uExpireTime > 0 )
+int Player::ReceiveDamage( signed int amount, DAMAGE_TYPE dmg_type )
+    {
+  signed int recieved_dmg; // eax@1
+  unsigned int armor_indx; // eax@8
+  bool broke_armor;
+ 
+  pConditions[Condition_Sleep] = 0i64;
+  recieved_dmg = CalculateIncommingDamage(dmg_type, amount);
+  sHealth -= recieved_dmg;
+  broke_armor = sHealth <= -10;
+  if ( sHealth < 1 ) //
+  {
+    if ( (sHealth + uEndurance + GetItemsBonus(CHARACTER_ATTRIBUTE_ENDURANCE, 0) >= 1)
+      || pPlayerBuffs[PLAYER_BUFF_PRESERVATION].uExpireTime > 0i64 )
     {
       SetCondition(Condition_Unconcious, 0);
     }
     else
     {
       SetCondition(Condition_Dead, 0);
-      v6 = LODWORD(pParty->uTimePlayed);
-      if ( v3->sHealth > 0 )
-        v3->sHealth = 0;
-    }
-    if ( v6 )
-    {
-      v7 = v3->pEquipment.uArmor;
-      if ( v7 )
+      //v6 = LODWORD(pParty->uTimePlayed); ???? if equals 0 do not broke armor?
+      if ( sHealth > 0 )
+        sHealth = 0;
+    }
+    if (broke_armor )
+    {
+      armor_indx = pEquipment.uArmor;
+      if ( armor_indx )
       {
-//        v8 = &v3->field_1F5[36 * v7 + 15];
-        v8=(char*)&v3->pOwnItems[v7-1].uAttributes;
-        v9 = *(int *)v8;
-        if ( !(BYTE1(v9) & 2) )
+        if ( !pOwnItems[armor_indx-1].uAttributes & ITEM_ENCHANTED)
         {
-          LOBYTE(v9) = v9 | 2;
-          *(int *)v8 = v9;
+          pOwnItems[armor_indx-1].uAttributes|=ITEM_BROKEN;
         }
       }
     }
   }
-  if ( v4 && CanAct() )
+  if ( recieved_dmg && CanAct() )
     PlaySound(SPEECH_24, 0);
-  return v4;
+  return recieved_dmg;
 }
 
 //----- (0048DCF6) --------------------------------------------------------
@@ -3730,9 +3656,9 @@
       goto LABEL_47;
     case 22:
       v8 = GetActualWillpower();
-      v9 = _48EA1B_get_static_effect(v8);
+      v9 = GetParameterBonus(v8);
       v10 = GetActualIntelligence();
-      v11 = (_48EA1B_get_static_effect(v10) + v9) >> 1;
+      v11 = (GetParameterBonus(v10) + v9) >> 1;
       break;
     case 17:
       v12 = 0;
@@ -3805,7 +3731,7 @@
       v47 = (unsigned __int8)v46[rand() % v4];
       v6 = GetActualAccuracy();
 LABEL_46:
-      v7 = _48EA1B_get_static_effect(v6);
+      v7 = GetParameterBonus(v6);
 LABEL_47:
       v11 = v7;
       break;
@@ -3814,7 +3740,7 @@
       break;
   }
   v22 = GetActualLuck();
-  v23 = _48EA1B_get_static_effect(v22) + v11 + 30;
+  v23 = GetParameterBonus(v22) + v11 + 30;
   if ( rand() % v23 >= 30 )
   {
 LABEL_87:
@@ -4110,7 +4036,7 @@
     shield_recovery = shield_base_recovery * SkillToMastery(pActiveSkills[skill_type]);
   }
 
-  uint player_speed_recovery_reduction = _48EA1B_get_static_effect(GetActualSpeed()),
+  uint player_speed_recovery_reduction = GetParameterBonus(GetActualSpeed()),
        sword_axe_bow_recovery_reduction = 0;
   bool shooting_laser = false;
   if (weapon_desc)
@@ -4171,7 +4097,7 @@
   int v4; // esi@1
   int v6; // esi@1
 
-  v3 = _48EA1B_get_static_effect(GetActualEndurance());
+  v3 = GetParameterBonus(GetActualEndurance());
   v4 = pBaseHealthPerLevelByClass[classType] * (GetActualLevel() + v3);
   v6 = uFullHealthBonus
      + pBaseHealthByClass[classType / 4]
@@ -4209,7 +4135,7 @@
     case 0x22u:
     case 0x23u:
       v2 = GetActualIntelligence();
-      v3 = _48EA1B_get_static_effect(v2);
+      v3 = GetParameterBonus(v2);
       goto LABEL_6;
     case 9u:
     case 0xAu:
@@ -4223,7 +4149,7 @@
     case 0x1Au:
     case 0x1Bu:
       v2 = GetActualWillpower();
-      v3 = _48EA1B_get_static_effect(v2);
+      v3 = GetParameterBonus(v2);
       goto LABEL_6;
     case 0x15u:
     case 0x16u:
@@ -4233,9 +4159,9 @@
     case 0x1Eu:
     case 0x1Fu:
       v4 = GetActualWillpower();
-      v5 = _48EA1B_get_static_effect(v4);
+      v5 = GetParameterBonus(v4);
       v6 = GetActualIntelligence();
-      v3 = _48EA1B_get_static_effect(v6) + v5;
+      v3 = GetParameterBonus(v6) + v5;
 LABEL_6:
       v7 = pBaseManaPerLevelByClass[classType] * (GetActualLevel() + v3);
       v8 = GetItemsBonus(CHARACTER_ATTRIBUTE_MANA, 0) + v7;
@@ -4267,7 +4193,7 @@
 
   v1 = this;
   v2 = GetActualSpeed();
-  v3 = _48EA1B_get_static_effect(v2);
+  v3 = GetParameterBonus(v2);
   v4 = GetItemsBonus(CHARACTER_ATTRIBUTE_AC_BONUS, 0) + v3;
   v5 = GetSkillBonus(CHARACTER_ATTRIBUTE_AC_BONUS) + v4;
   if ( v5 >= 1 )
@@ -4290,7 +4216,7 @@
 
   v1 = this;
   v2 = GetActualSpeed();
-  v3 = _48EA1B_get_static_effect(v2);
+  v3 = GetParameterBonus(v2);
   v4 = GetItemsBonus(CHARACTER_ATTRIBUTE_AC_BONUS, 0) + v3;
   v5 = GetSkillBonus(CHARACTER_ATTRIBUTE_AC_BONUS) + v4;
   v6 = v1->sACModifier + GetMagicalBonus(CHARACTER_ATTRIBUTE_AC_BONUS) + v5;
@@ -4516,16 +4442,17 @@
 }
 
 //----- (0048EA1B) --------------------------------------------------------
-int Player::_48EA1B_get_static_effect(int a2)
-{
-  __int16 v2; // cx@1
-  int v3; // eax@1
-
-  v2 = word_4EDFFC[0];
-  v3 = 0;
-  while ( a2 < v2 && v2 )
-    v2 = word_4EDFFC[v3++ + 1];
-  return player_stat_bonuses[v3];
+int Player::GetParameterBonus( int player_parameter )
+    {
+  int i; // eax@1
+  i = 0;
+  while (param_to_bonus_table[i])
+      { 
+      if (player_parameter >= param_to_bonus_table[i])
+          break;
+      ++i;    
+      }   
+  return parameter_to_bonus_value[i];
 }
 
 //----- (0048EA46) --------------------------------------------------------
@@ -4556,7 +4483,7 @@
 int Player::GetItemsBonus(CHARACTER_ATTRIBUTE_TYPE attr, int a3)
 {
   CHARACTER_ATTRIBUTE_TYPE v3; // esi@1
-  signed int v4; // eax@1
+ // signed int v4; // eax@1
   int v5; // edi@1
   Player *v6; // ebx@1
   Player *v8; // ecx@48
@@ -4617,145 +4544,73 @@
   int v63; // [sp+18h] [bp-4h]@101
   ItemGen *attra; // [sp+20h] [bp+4h]@101
   unsigned int v65; // [sp+24h] [bp+8h]@95
+  bool no_skills;
 
   v3 = attr;
-  v4 = 36;
   v5 = 0;
   v6 = this;
   v62 = 0;
   v61 = 0;
 
+  
+  no_skills=false;
   switch (attr)
-  {
-    case CHARACTER_ATTRIBUTE_LEVEL:
-      if (HasEnchantedItemEquipped(25))
-        return 5;
-      return 0;
-  };
-
-  if ( (signed int)attr > 36 )
-  {
-    switch ( attr )
-    {
-      case 37:
-        v58 = 15;
-        goto LABEL_35;
-      case 38:
-        v58 = 16;
-        goto LABEL_35;
-      case 39:
-        v58 = 17;
-        goto LABEL_35;
-      case 40:
-        v58 = 18;
-        goto LABEL_35;
-      case 41:
-        v58 = 19;
-        goto LABEL_35;
-      case 42:
-        v58 = 20;
-        goto LABEL_35;
-      case 43:
-        v58 = 25;
-        goto LABEL_35;
-      case 44:
-        v58 = 5;
-        goto LABEL_35;
-      case 45:
-        v58 = 8;
-        goto LABEL_35;
-      case 46:
-        goto LABEL_36;
-      default:
-        break;
-    }
-  }
-  else
-  {
-    if ( attr == 36 )
-    {
-      v58 = 14;
-    }
-    else
-    {
-      if ( (signed int)attr > 21 )
       {
-        switch ( attr )
-        {
-          case 22:
-            v58 = 30;
-            break;
-          case 23:
-            v58 = 31;
-            break;
-          case 34:
-            v58 = 12;
-            break;
-          default:
-            if ( attr != 35 )
-              goto LABEL_38;
-            v58 = 13;
-            break;
-        }
+  case  CHARACTER_ATTRIBUTE_SKILL_ALCHEMY:      v58 = PLAYER_SKILL_ALCHEMY;      break;
+  case  CHARACTER_ATTRIBUTE_SKILL_STEALING:     v58 = PLAYER_SKILL_STEALING;     break;
+  case  CHARACTER_ATTRIBUTE_SKILL_TRAP_DISARM:  v58 = PLAYER_SKILL_TRAP_DISARM;  break;
+  case  CHARACTER_ATTRIBUTE_SKILL_ITEM_ID:      v58 = PLAYER_SKILL_ITEM_ID;      break;
+  case  CHARACTER_ATTRIBUTE_SKILL_MONSTER_ID:   v58 = PLAYER_SKILL_MONSTER_ID;   break;
+  case  CHARACTER_ATTRIBUTE_SKILL_ARMSMASTER:   v58 = PLAYER_SKILL_ARMSMASTER;   break;
+  case  CHARACTER_ATTRIBUTE_SKILL_DODGE:        v58 = PLAYER_SKILL_DODGE;        break;
+  case  CHARACTER_ATTRIBUTE_SKILL_UNARMED:      v58 = PLAYER_SKILL_UNARMED;      break;
+  case  CHARACTER_ATTRIBUTE_SKILL_FIRE:         v58 = PLAYER_SKILL_FIRE;         break;
+  case  CHARACTER_ATTRIBUTE_SKILL_AIR:          v58 = PLAYER_SKILL_AIR;          break;
+  case  CHARACTER_ATTRIBUTE_SKILL_WATER:        v58 = PLAYER_SKILL_WATER;        break;
+  case  CHARACTER_ATTRIBUTE_SKILL_EARTH:        v58 = PLAYER_SKILL_EARTH;        break;
+  case  CHARACTER_ATTRIBUTE_SKILL_SPIRIT:       v58 = PLAYER_SKILL_SPIRIT;       break;
+  case  CHARACTER_ATTRIBUTE_SKILL_MIND:         v58 = PLAYER_SKILL_MIND;         break;
+  case  CHARACTER_ATTRIBUTE_SKILL_BODY:         v58 = PLAYER_SKILL_BODY;         break;
+  case  CHARACTER_ATTRIBUTE_SKILL_LIGHT:        v58 = PLAYER_SKILL_LIGHT;        break;
+  case  CHARACTER_ATTRIBUTE_SKILL_DARK:         v58 = PLAYER_SKILL_DARK;         break;
+  case  CHARACTER_ATTRIBUTE_SKILL_MEDITATION:   v58 = PLAYER_SKILL_MEDITATION;   break;
+  case  CHARACTER_ATTRIBUTE_SKILL_BOW:          v58 = PLAYER_SKILL_BOW;          break;
+  case  CHARACTER_ATTRIBUTE_SKILL_SHIELD:       v58 = PLAYER_SKILL_SHIELD;       break;
+  case  CHARACTER_ATTRIBUTE_SKILL_LEARNING:     v58 = PLAYER_SKILL_LEARNING;     break;
+  default:
+      no_skills=true;
       }
-      else
+  if (!no_skills)
       {
-        switch ( attr )
-        {
-          case 21:
-            v58 = 33;
-            break;
-          case 16:
-            v58 = 35;
-            break;
-          case 17:
-            v58 = 34;
-            break;
-          case 18:
-            v58 = 29;
-            break;
-          case 19:
-            v58 = 21;
-            break;
-          default:
-            if ( attr != 20 )
-              goto LABEL_38;
-            v58 = 32;
-            break;
-        }
+      if ( !this->pActiveSkills[v58] )
+        return 0;
       }
-    }
-LABEL_35:
-    v4 = v58;
-LABEL_36:
-    if ( !this->pActiveSkills[v4] )
-      return 0;
-  }
-LABEL_38:
+
   if ( (signed int)attr > 28 )
   {
     if ( (signed int)attr < 29 )
       return v5 + v62 + v61;
-    if ( (signed int)attr <= 30 )
+    if ( (signed int)attr <= CHARACTER_ATTRIBUTE_RANGED_DMG_BONUS )
     {
       if ( HasItemEquipped(EQUIP_BOW) )
-        v5 = pItemsTable->pItems[*(int *)&v6->pInventoryItems[v6->pEquipment.uBow-1]].uDamageMod;
+        v5 = pItemsTable->pItems[v6->pOwnItems[v6->pEquipment.uBow-1].uItemID].uDamageMod;
       return v5 + v62 + v61;
     }
-    if ( attr == 31 )
+    if ( attr == CHARACTER_ATTRIBUTE_RANGED_DMG_MIN )
     {
       if ( !HasItemEquipped(EQUIP_BOW) )
         return v5 + v62 + v61;
-      v57 = *(int *)&v6->pInventoryItems[v6->pEquipment.uBow-1];
+      v57 = v6->pOwnItems[v6->pEquipment.uBow-1].uItemID;
       v5 = pItemsTable->pItems[v57].uDamageMod;
       v56 = pItemsTable->pItems[v57].uDamageDice;
-      goto LABEL_366;
-    }
-    if ( attr == 32 )
+      v5 += v56;
+      return v5 + v62 + v61;
+    }
+    if ( attr == CHARACTER_ATTRIBUTE_RANGED_DMG_MAX )
     {
       if ( !HasItemEquipped(EQUIP_BOW) )
         return v5 + v62 + v61;
-      v20 = *(int *)&v6->pInventoryItems[v6->pEquipment.uBow-1];
+      v20 = v6->pOwnItems[v6->pEquipment.uBow-1].uItemID;
       v5 = pItemsTable->pItems[v20].uDamageDice * pItemsTable->pItems[v20].uDamageRoll;
 LABEL_365:
       v56 = pItemsTable->pItems[v20].uDamageMod;
@@ -5331,7 +5186,7 @@
         return v5 + v62 + v61;
     }
   }
-  if ( attr == 28 )
+  if ( attr == CHARACTER_ATTRIBUTE_MELEE_DMG_MAX )
   {
     if ( IsUnarmed() != 1 )
     {
@@ -5342,7 +5197,7 @@
         {
           if ( v22 <= 2 )
           {
-			  v23 = this->pInventoryItems[this->pEquipment.uMainHand].uItemID;
+			  v23 = this->pOwnItems[this->pEquipment.uMainHand].uItemID;
             if ( v6->pEquipment.uShield || pItemsTable->pItems[v23].uSkillType != 4 )
             {
               v24 = v23;
@@ -5358,11 +5213,18 @@
           }
         }
       }
-      if ( a3 || !v6->HasItemEquipped(EQUIP_OFF_HAND) || (v28 = v6->GetEquippedItemEquipType(EQUIP_OFF_HAND), v28 < 0) || v28 > 2 )
-        return v5 + v62 + v61;
+      
+      if ( a3 || !v6->HasItemEquipped(EQUIP_OFF_HAND) )
+          {
+
+          v28 = v6->GetEquippedItemEquipType(EQUIP_OFF_HAND);
+          if ((v28 < 0) || v28 > 2 )
+              return v5 + v62 + v61;
+        }
       v15 = pItemsTable->pItems[v29].uDamageMod;
       v14 = pItemsTable->pItems[v29].uDamageDice * pItemsTable->pItems[v29].uDamageRoll;
-      goto LABEL_88;
+      v5 += v15 + v14;
+      return v5 + v62 + v61;
     }
     v59 = 3;
 LABEL_74:
@@ -5371,11 +5233,18 @@
   }
   if ( (signed int)attr < 0 )
     return v5 + v62 + v61;
-  if ( (signed int)attr <= 23 )
+  if ( (signed int)attr <= CHARACTER_ATTRIBUTE_SKILL_UNARMED )
     goto LABEL_95;
-  if ( (signed int)attr <= 24 )
+  if ( attr == CHARACTER_ATTRIBUTE_LEVEL )
+      {
+      if ( !Player::HasEnchantedItemEquipped(25) )
+          return v5 + v62 + v61;
+      v5 = 5;
+      return v5 + v62 + v61;
+      }
+  if ( (signed int)attr <= CHARACTER_ATTRIBUTE_LEVEL )
     return v5 + v62 + v61;
-  if ( (signed int)attr <= 26 )
+  if ( (signed int)attr <= CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS )
   {
     if ( IsUnarmed() == 1 )
     {
@@ -5388,15 +5257,17 @@
       if ( v17 >= 0 )
       {
         if ( v17 <= 2 )
-          v5 = pItemsTable->pItems[*(int *)&v6->pInventoryItems[v6->pEquipment.uMainHand-1]].uDamageMod;
+          v5 = pItemsTable->pItems[v6->pOwnItems[v6->pEquipment.uMainHand-1].uItemID].uDamageMod;
       }
     }
     if ( a3 || !v6->HasItemEquipped(EQUIP_OFF_HAND) || (v19 = v6->GetEquippedItemEquipType(EQUIP_OFF_HAND), v19 < 0) || v19 > 2 )
       return v5 + v62 + v61;
-    v20 = *(int *)&v6->pInventoryItems[v6->pEquipment.uShield - 1];
-    goto LABEL_365;
-  }
-  if ( attr == 27 )
+    v20 = v6->pOwnItems[v6->pEquipment.uShield - 1].uItemID;
+    v56 = pItemsTable->pItems[v20].uDamageMod;
+    v5 += v56;
+    return v5 + v62 + v61;
+  }
+  if ( attr == CHARACTER_ATTRIBUTE_MELEE_DMG_MIN )
   {
     if ( IsUnarmed() == 1 )
     {
@@ -5410,20 +5281,25 @@
       {
         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->pOwnItems[this->pEquipment.uMainHand].uItemID].uDamageDice +
+                 pItemsTable->pItems[this->pOwnItems[this->pEquipment.uMainHand].uItemID].uDamageMod;
           if ( !v6->pEquipment.uShield )
           {
-            if ( pItemsTable->pItems[this->pInventoryItems[this->pEquipment.uMainHand].uItemID].uSkillType == 4 )
+            if ( pItemsTable->pItems[this->pOwnItems[this->pEquipment.uMainHand].uItemID].uSkillType == 4 )
               ++v5;
           }
         }
       }
     }
-    if ( a3 || !v6->HasItemEquipped(EQUIP_OFF_HAND) || (v12 = v6->GetEquippedItemEquipType(EQUIP_OFF_HAND), v12 < 0) || v12 > 2 )
-      return v5 + v62 + v61;
-    v14 = pItemsTable->pItems[this->pInventoryItems[this->pEquipment.uShield].uItemID].uDamageMod;
-    v15 = pItemsTable->pItems[this->pInventoryItems[this->pEquipment.uShield].uItemID].uDamageDice;
+    
+    if ( a3 || !v6->HasItemEquipped(EQUIP_OFF_HAND))
+        {
+        v12 = v6->GetEquippedItemEquipType(EQUIP_OFF_HAND);
+        if  ((v12 < 0) || v12 > 2 )
+                return v5 + v62 + v61;
+        }
+    v14 = pItemsTable->pItems[this->pOwnItems[this->pEquipment.uShield].uItemID].uDamageMod;
+    v15 = pItemsTable->pItems[this->pOwnItems[this->pEquipment.uShield].uItemID].uDamageDice;
 LABEL_88:
     v5 += v15 + v14;
   }
@@ -5549,8 +5425,7 @@
         v2 = 6;
       if ( CheckHiredNPCSpeciality(Sage) )
         v2 += 6;
-      v8 = (CHARACTER_ATTRIBUTE_TYPE)20;
-      v2 += GetItemsBonus(v8, 0);
+      v2 += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_MONSTER_ID, 0);
     }
     break;
 
@@ -5560,8 +5435,7 @@
           v2 = 2;
         if ( CheckHiredNPCSpeciality(Weaponsmaster) )
           v2 += 3;
-        v8 = (CHARACTER_ATTRIBUTE_TYPE)21;
-      v2 += GetItemsBonus(v8, 0);
+      v2 += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_ARMSMASTER, 0);
     }
     break;
 
@@ -5569,8 +5443,7 @@
     {
       if (CheckHiredNPCSpeciality(Burglar))
           v2 = 8;
-      v8 = (CHARACTER_ATTRIBUTE_TYPE)17;
-      v2 += GetItemsBonus(v8, 0);
+      v2 += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_STEALING, 0);
     }
     break;
 
@@ -5581,8 +5454,7 @@
           v2 = 4;
         if ( CheckHiredNPCSpeciality(Apothecary) )
           v2 += 8;
-        v8 = (CHARACTER_ATTRIBUTE_TYPE)16;
-      v2 += GetItemsBonus(v8, 0);
+        v2 += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_ALCHEMY, 0);
     }
     break;
 
@@ -5594,8 +5466,7 @@
           v2 += 15;
         if ( CheckHiredNPCSpeciality(Scholar) )
           v2 += 5;
-        v8 = (CHARACTER_ATTRIBUTE_TYPE)46;
-      v2 += GetItemsBonus(v8, 0);
+      v2 += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_LEARNING, 0);
     }
     break;
 
@@ -5603,8 +5474,7 @@
     {
       if (CheckHiredNPCSpeciality(Monk) )
         v2 = 2;
-      v8 = (CHARACTER_ATTRIBUTE_TYPE)23;
-      v2 += GetItemsBonus(v8, 0);
+      v2 += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_UNARMED, 0);
     }
     break;
 
@@ -5612,18 +5482,15 @@
     {
       if ( CheckHiredNPCSpeciality(Monk) )
         v2 = 2;
-      v8 = (CHARACTER_ATTRIBUTE_TYPE)22;
-      v2 += GetItemsBonus(v8, 0);
+      v2 += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_DODGE, 0);
     }
     break;
     
     case PLAYER_SKILL_BOW:
-      v8 = (CHARACTER_ATTRIBUTE_TYPE)44;
-      v2 += GetItemsBonus(v8, 0);
+      v2 += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_BOW, 0);
     break;
     case PLAYER_SKILL_SHIELD:
-      v8 = (CHARACTER_ATTRIBUTE_TYPE)45;
-      v2 += GetItemsBonus(v8, 0);
+      v2 += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_SHIELD, 0);
     break;
 
     case PLAYER_SKILL_EARTH:
@@ -5635,8 +5502,7 @@
             v2 += 4;
           if ( classType == PLAYER_CLASS_WARLOCK && PartyHasDragon() )
             v2 += 3;
-      v8 = (CHARACTER_ATTRIBUTE_TYPE)37;
-      v2 += GetItemsBonus(v8, 0);
+      v2 += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_EARTH, 0);
     break;
     case PLAYER_SKILL_FIRE:
       if ( CheckHiredNPCSpeciality(Apprentice) )
@@ -5647,8 +5513,7 @@
             v2 += 4;
           if ( classType == PLAYER_CLASS_WARLOCK && PartyHasDragon() )
             v2 += 3;
-      v8 = (CHARACTER_ATTRIBUTE_TYPE)34;
-      v2 += GetItemsBonus(v8, 0);
+      v2 += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_FIRE, 0);
     break;
     case PLAYER_SKILL_AIR:
       if ( CheckHiredNPCSpeciality(Apprentice) )
@@ -5659,8 +5524,7 @@
             v2 += 4;
           if ( classType == PLAYER_CLASS_WARLOCK && PartyHasDragon() )
             v2 += 3;
-      v8 = (CHARACTER_ATTRIBUTE_TYPE)35;
-      v2 += GetItemsBonus(v8, 0);
+      v2 += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_AIR, 0);
     break;
     case PLAYER_SKILL_WATER:
       if ( CheckHiredNPCSpeciality(Apprentice) )
@@ -5671,8 +5535,7 @@
             v2 += 4;
           if ( classType == PLAYER_CLASS_WARLOCK && PartyHasDragon() )
             v2 += 3;
-      v8 = (CHARACTER_ATTRIBUTE_TYPE)36;
-      v2 += GetItemsBonus(v8, 0);
+      v2 += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_WATER, 0);
     break;
     case PLAYER_SKILL_SPIRIT:
           if ( CheckHiredNPCSpeciality(Acolyte2) )
@@ -5681,8 +5544,7 @@
             v2 += 3;
           if ( CheckHiredNPCSpeciality(Prelate) )
             v2 += 4;
-      v8 = (CHARACTER_ATTRIBUTE_TYPE)38;
-      v2 += GetItemsBonus(v8, 0);
+      v2 += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_SPIRIT, 0);
     break;
     case PLAYER_SKILL_MIND:
           if ( CheckHiredNPCSpeciality(Acolyte2) )
@@ -5691,8 +5553,7 @@
             v2 += 3;
           if ( CheckHiredNPCSpeciality(Prelate) )
             v2 += 4;
-      v8 = (CHARACTER_ATTRIBUTE_TYPE)39;
-      v2 += GetItemsBonus(v8, 0);
+      v2 += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_MIND, 0);
     break;
     case PLAYER_SKILL_BODY:
           if ( CheckHiredNPCSpeciality(Acolyte2) )
@@ -5701,17 +5562,14 @@
             v2 += 3;
           if ( CheckHiredNPCSpeciality(Prelate) )
             v2 += 4;
-      v8 = (CHARACTER_ATTRIBUTE_TYPE)40;
-      v2 += GetItemsBonus(v8, 0);
+      v2 += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_BODY, 0);
     break;
     case PLAYER_SKILL_LIGHT:
-      v8 = (CHARACTER_ATTRIBUTE_TYPE)41;
-      v2 += GetItemsBonus(v8, 0);
+      v2 += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_LIGHT, 0);
     break;
     case PLAYER_SKILL_DARK:
     {
-      v8 = (CHARACTER_ATTRIBUTE_TYPE)42;
-      v2 += GetItemsBonus(v8, 0);
+      v2 += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_DARK, 0);
     }
     break;
 
@@ -5738,12 +5596,10 @@
     break;
 
     case PLAYER_SKILL_ITEM_ID:
-      v8 = (CHARACTER_ATTRIBUTE_TYPE)19;
-      v2 += GetItemsBonus(v8, 0);
+      v2 += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_ITEM_ID, 0);
       break;
     case PLAYER_SKILL_MEDITATION:
-      v8 = (CHARACTER_ATTRIBUTE_TYPE)43;
-      v2 += GetItemsBonus(v8, 0);
+      v2 += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_MEDITATION, 0);
     break;
     case PLAYER_SKILL_TRAP_DISARM:
     {
@@ -5753,8 +5609,7 @@
         v2 += 6;
       if ( CheckHiredNPCSpeciality(Burglar) )
         v2 += 8;
-      v8 = (CHARACTER_ATTRIBUTE_TYPE)18;
-      v2 += GetItemsBonus(v8, 0);
+      v2 += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_TRAP_DISARM, 0);
     }
     break;
   }
@@ -6599,43 +6454,43 @@
   pStep = StatTable[0][v2].uBaseStep;
     switch ( eAttribute )
     {
-      case CHARACTER_MIGHT:
+      case CHARACTER_ATTRIBUTE_STRENGTH:
         if ( this->uMight <= pBaseValue )
           pStep = pDroppedStep;
         if ( this->uMight - pStep >= uMinValue )
          this->uMight -= pStep;
         break;
-	  case CHARACTER_INTELLIGANCE:
+	  case CHARACTER_ATTRIBUTE_INTELLIGENCE:
         if ( this->uIntelligence <= pBaseValue )
           pStep = pDroppedStep;
         if ( this->uIntelligence - pStep >= uMinValue )
           this->uIntelligence -= pStep;
         break;
-      case CHARACTER_WILLPOWER:
+      case CHARACTER_ATTRIBUTE_WILLPOWER:
         if ( this->uWillpower <= pBaseValue )
           pStep = pDroppedStep;
         if ( this->uWillpower - pStep >= uMinValue )
           this->uWillpower -= pStep;
         break;
-      case CHARACTER_ENDURANCE:
+      case CHARACTER_ATTRIBUTE_ENDURANCE:
         if ( this->uEndurance <= pBaseValue )
           pStep = pDroppedStep;
         if ( this->uEndurance - pStep >= uMinValue )
           this->uEndurance -= pStep;
         break;
-      case CHARACTER_ACCURACY:
+      case CHARACTER_ATTRIBUTE_ACCURACY:
         if ( this->uAccuracy <= pBaseValue )
           pStep = pDroppedStep;
         if ( this->uAccuracy - pStep >= uMinValue )
           this->uAccuracy -= pStep;
         break;
-      case CHARACTER_SPEED:
+      case CHARACTER_ATTRIBUTE_SPEED:
         if ( this->uSpeed <= pBaseValue )
           pStep = pDroppedStep;
         if ( this->uSpeed - pStep >= uMinValue )
           this->uSpeed -= pStep;
         break;
-      case CHARACTER_LUCK:
+      case CHARACTER_ATTRIBUTE_LUCK:
 		if ( this->uLuck <= pBaseValue )
           pStep = pDroppedStep;
         if ( this->uLuck - pStep >= uMinValue )
@@ -7504,8 +7359,6 @@
 
     }
 
-
-
 //----- (00449BB4) --------------------------------------------------------
 bool Player::CompareVariable( enum VariableType VarNum, signed int pValue )
 {
@@ -9277,7 +9130,7 @@
           pAudioPlayer->PlaySound(SOUND_20001, v8, 0, -1, 0, 0, 0, 0);
           return result;
         case VAR_CurrentHP:
-          ReceiveDamage((signed int)pValue, 4);
+          ReceiveDamage((signed int)pValue, DMGT_PHISYCAL);
           pGame->pStru6Instance->SetPlayerBuffAnim(0x98u, v4);
           v8 = 8 * v4 + 400;
           LOBYTE(v8) = PID(OBJECT_Player,v4 - 112);
--- a/Player.h	Thu May 23 21:36:57 2013 +0600
+++ b/Player.h	Thu May 23 21:37:22 2013 +0600
@@ -143,47 +143,61 @@
   CHARACTER_RACE_GOBLIN = 2,
   CHARACTER_RACE_DWARF = 3,
 };
-enum CHARACTER_ATTRIBUTE
-{
-  CHARACTER_MIGHT = 0x0,
-  CHARACTER_INTELLIGANCE = 0x1,
-  CHARACTER_WILLPOWER = 0x2,
-  CHARACTER_ENDURANCE = 0x3,
-  CHARACTER_ACCURACY = 0x4,
-  CHARACTER_SPEED = 0x5,
-  CHARACTER_LUCK = 0x6,
-};
-
-
 
 /*  332 */
 enum CHARACTER_ATTRIBUTE_TYPE
 {
-  CHARACTER_ATTRIBUTE_STRENGTH = 0x0,
-  CHARACTER_ATTRIBUTE_INTELLIGENCE = 0x1,
-  CHARACTER_ATTRIBUTE_WILLPOWER = 0x2,
-  CHARACTER_ATTRIBUTE_ENDURANCE = 0x3,
-  CHARACTER_ATTRIBUTE_ACCURACY = 0x4,
-  CHARACTER_ATTRIBUTE_SPEED = 0x5,
-  CHARACTER_ATTRIBUTE_LUCK = 0x6,
-  CHARACTER_ATTRIBUTE_HEALTH = 0x7,
-  CHARACTER_ATTRIBUTE_MANA = 0x8,
-  CHARACTER_ATTRIBUTE_AC_BONUS = 0x9,
-  CHARACTER_ATTRIBUTE_RESIST_FIRE = 0xA,
-  CHARACTER_ATTRIBUTE_RESIST_AIR = 0xB,
-  CHARACTER_ATTRIBUTE_RESIST_WATER = 0xC,
-  CHARACTER_ATTRIBUTE_RESIST_EARTH = 0xD,
-  CHARACTER_ATTRIBUTE_RESIST_MIND = 0xE,
-  CHARACTER_ATTRIBUTE_RESIST_BODY = 0xF,
-  CHARACTER_ATTRIBUTE_LEVEL = 0x18,
-  CHARACTER_ATTRIBUTE_ATTACK = 0x19,
-  CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS = 0x1A,
-  CHARACTER_ATTRIBUTE_MELEE_DMG_MIN = 0x1B,
-  CHARACTER_ATTRIBUTE_MELEE_DMG_MAX = 0x1C,
-  CHARACTER_ATTRIBUTE_RANGED_ATTACK = 0x1D,
-  CHARACTER_ATTRIBUTE_RANGED_DAMAGE_BONUS = 0x1E,
-  CHARACTER_ATTRIBUTE_RANGED_DAMAGE_MIN = 0x1F,
-  CHARACTER_ATTRIBUTE_RANGED_DAMAGE_MAX = 0x20,
+  CHARACTER_ATTRIBUTE_STRENGTH          = 0,
+  CHARACTER_ATTRIBUTE_INTELLIGENCE      = 1,
+  CHARACTER_ATTRIBUTE_WILLPOWER         = 2,
+  CHARACTER_ATTRIBUTE_ENDURANCE         = 3,
+  CHARACTER_ATTRIBUTE_ACCURACY          = 4,
+  CHARACTER_ATTRIBUTE_SPEED             = 5,
+  CHARACTER_ATTRIBUTE_LUCK              = 6,
+  CHARACTER_ATTRIBUTE_HEALTH            = 7,
+  CHARACTER_ATTRIBUTE_MANA              = 8,
+  CHARACTER_ATTRIBUTE_AC_BONUS          = 9,
+
+  CHARACTER_ATTRIBUTE_RESIST_FIRE       = 10,
+  CHARACTER_ATTRIBUTE_RESIST_AIR        = 11,
+  CHARACTER_ATTRIBUTE_RESIST_WATER      = 12,
+  CHARACTER_ATTRIBUTE_RESIST_EARTH      = 13,
+  CHARACTER_ATTRIBUTE_RESIST_MIND       = 14,
+  CHARACTER_ATTRIBUTE_RESIST_BODY       = 15,
+
+  CHARACTER_ATTRIBUTE_SKILL_ALCHEMY     = 16,
+  CHARACTER_ATTRIBUTE_SKILL_STEALING    = 17,
+  CHARACTER_ATTRIBUTE_SKILL_TRAP_DISARM = 18,
+  CHARACTER_ATTRIBUTE_SKILL_ITEM_ID     = 19,
+  CHARACTER_ATTRIBUTE_SKILL_MONSTER_ID  = 20,
+  CHARACTER_ATTRIBUTE_SKILL_ARMSMASTER  = 21,
+  CHARACTER_ATTRIBUTE_SKILL_DODGE       = 22,
+  CHARACTER_ATTRIBUTE_SKILL_UNARMED     = 23,
+
+  CHARACTER_ATTRIBUTE_LEVEL             = 24,
+  CHARACTER_ATTRIBUTE_ATTACK            = 25,
+  CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS   = 26,
+  CHARACTER_ATTRIBUTE_MELEE_DMG_MIN     = 27,
+  CHARACTER_ATTRIBUTE_MELEE_DMG_MAX     = 28,
+  CHARACTER_ATTRIBUTE_RANGED_ATTACK     = 29,
+  CHARACTER_ATTRIBUTE_RANGED_DMG_BONUS  = 30,
+  CHARACTER_ATTRIBUTE_RANGED_DMG_MIN    = 31,
+  CHARACTER_ATTRIBUTE_RANGED_DMG_MAX    = 32,
+  CHARACTER_ATTRIBUTE_RESIST_SPIRIT     = 33,
+
+  CHARACTER_ATTRIBUTE_SKILL_FIRE        = 34,
+  CHARACTER_ATTRIBUTE_SKILL_AIR         = 35,
+  CHARACTER_ATTRIBUTE_SKILL_WATER       = 36,
+  CHARACTER_ATTRIBUTE_SKILL_EARTH       = 37,
+  CHARACTER_ATTRIBUTE_SKILL_SPIRIT      = 38,
+  CHARACTER_ATTRIBUTE_SKILL_MIND        = 39,
+  CHARACTER_ATTRIBUTE_SKILL_BODY        = 40,
+  CHARACTER_ATTRIBUTE_SKILL_LIGHT       = 41,
+  CHARACTER_ATTRIBUTE_SKILL_DARK        = 42,
+  CHARACTER_ATTRIBUTE_SKILL_MEDITATION  = 43,
+  CHARACTER_ATTRIBUTE_SKILL_BOW         = 44,
+  CHARACTER_ATTRIBUTE_SKILL_SHIELD      = 45,
+  CHARACTER_ATTRIBUTE_SKILL_LEARNING    = 46
 };
 
 /*  328 */
@@ -491,7 +505,7 @@
   char *GetRangedDamageString();
   bool CanTrainToNextLevel();
   unsigned int GetExperienceDisplayColor();
-  int CalculateIncommingDamage(int resistance, signed int type);
+  int CalculateIncommingDamage(DAMAGE_TYPE dmg_type, int amount);
   ITEM_EQUIP_TYPE   GetEquippedItemEquipType(ITEM_EQUIP_TYPE uEquipSlot);
   PLAYER_SKILL_TYPE GetEquippedItemSkillType(ITEM_EQUIP_TYPE uEquipSlot);
   bool IsUnarmed();
@@ -501,7 +515,7 @@
   bool StealFromShop(struct ItemGen *a2, int a3, int a4, int a5, int *a6);
   int StealFromActor(unsigned int uActorID, int _steal_perm, int reputation);
   void Heal(int amount);
-  int ReceiveDamage(signed int type, int resistance);
+  int ReceiveDamage(signed int amount, DAMAGE_TYPE dmg_type);
   int _48DCF6(int a2, struct Actor *pActor);
   unsigned int GetSpellSchool(unsigned int uSpellID);
   int GetAttackRecoveryTime(bool bRangedAttack);
@@ -516,7 +530,7 @@
   void SetRecoveryTime(signed int sRecoveryTime);
   void RandomizeName();
   unsigned int GetMajorConditionIdx();
-  int _48EA1B_get_static_effect(int a2);
+  int GetParameterBonus(int player_parameter);
   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);
@@ -571,7 +585,7 @@
   int GetBuyingPrice(unsigned int uRealValue, float price_multiplier);
   int GetPriceSell(int uRealValue, float price_multiplier);
   int _4B807C(float a2);
-  int _4B8040_condition_time(unsigned int uCondition);
+  int GetConditionDayOfWeek(unsigned int uCondition);
   bool _43EEF3();
   void SalesProcess(unsigned int inventory_idnx, int item_index, int _2devent_idx);//0x4BE2DD
   bool Recover(signed int a2);
--- a/Render.cpp	Thu May 23 21:36:57 2013 +0600
+++ b/Render.cpp	Thu May 23 21:37:22 2013 +0600
@@ -5549,11 +5549,7 @@
     {
       if ( v1->field_40110 )
       {
-        if (pAsyncMouse)
-          pAsyncMouse->_46BAEC();
         pRenderD3D->Present(false);
-        if (pAsyncMouse)
-          pAsyncMouse->_46BB0A();
       }
     }
     else
@@ -6518,8 +6514,6 @@
   result = pSurface->Lock(0, pDesc, uLockFlags, 0);
   if ( result == DDERR_SURFACELOST )
   {
-    if (pAsyncMouse)
-      pAsyncMouse->Suspend();
     v6 = v4->Restore();
     if ( v6 )
     {
@@ -6548,8 +6542,6 @@
     if ( pRenderer->pRenderD3D )
       pRenderD3D->HandleLostResources();
     result = pRenderer->pDirectDraw4->RestoreAllSurfaces();
-    if (pAsyncMouse)
-      pAsyncMouse->Resume();
   }
   else
   {
@@ -10923,10 +10915,6 @@
       BYTE1(dword_6BE364_game_settings_1) &= 0xEFu;
     else
       pMiscTimer->Resume();
-    pAsyncMouse->Release();
-    CreateAsyncMouse();
-    if (pAsyncMouse)
-      pAsyncMouse->Clip();
   }
 }
 // 6BE364: using guessed type int dword_6BE364_game_settings_1;
--- a/SpriteObject.cpp	Thu May 23 21:36:57 2013 +0600
+++ b/SpriteObject.cpp	Thu May 23 21:37:22 2013 +0600
@@ -1080,7 +1080,7 @@
       if ( (*v12)->CanAct() && (v13 = (*v12)->GetPerception() + 20, rand() % v13 > 20) )
         (*v12)->PlaySound(SPEECH_6, 0);
       else
-        (*v12)->ReceiveDamage(v11, v18);
+        (*v12)->ReceiveDamage(v11, (DAMAGE_TYPE)v18);
       ++v12;
     }
     while ( (signed int)v12 <= (signed int)&pPlayers[4] );
--- a/UIBooks.cpp	Thu May 23 21:36:57 2013 +0600
+++ b/UIBooks.cpp	Thu May 23 21:37:22 2013 +0600
@@ -27,6 +27,151 @@
 
 
 
+//----- (00411150) --------------------------------------------------------
+void BookUI_DrawTownPortalMap()
+{
+  //signed int v0; // edi@1
+  //__int16 v1; // dx@8
+  //POINT *v2; // edi@17
+  int v3; // edi@17
+  //__int16 v4; // dx@24
+  GUIWindow v6; // [sp+Ch] [bp-64h]@1
+  //POINT v7; // [sp+60h] [bp-10h]@17
+  POINT a2; // [sp+68h] [bp-8h]@17
+
+  pRenderer->ClearZBuffer(0, 479);
+  pRenderer->DrawTextureTransparent(8, 8, pTexture_CurrentBook);
+  pRenderer->DrawTextureTransparent(471, 445, pIcons_LOD->GetTexture(uExitCancelTextureId));
+
+  v6.uFrameX = game_viewport_x;
+  v6.uFrameY = game_viewport_y;
+  v6.uFrameWidth = game_viewport_width;
+  v6.uFrameHeight = game_viewport_height;
+  v6.uFrameZ = game_viewport_z;
+  v6.uFrameW = game_viewport_w;
+  
+  const uint fountain_bits_lut[] = {PARTY_QUEST_FOUNTAIN_HARMONDALE,
+                                    PARTY_QUEST_FOUNTAIN_PIERPONT,
+                                    PARTY_QUEST_FOUNTAIN_NIGHON,
+                                    PARTY_QUEST_FOUNTAIN_EVENMORN_ISLE,
+                                    PARTY_QUEST_FOUNTAIN_CELESTIA,
+                                    PARTY_QUEST_FOUNTAIN_THE_PIT};
+  for (uint i = 0; i < 6; ++i)
+  {
+
+    if (_449B57_test_bit(pParty->_quest_bits, fountain_bits_lut[i]))
+      pRenderer->DrawMaskToZBuffer(pTownPortalBook_xs[i],
+                                   pTownPortalBook_ys[i],
+                                   pTexture_TownPortalIcons[i], i + 1);
+  }
+
+/*  v0 = 0;
+  do
+  {
+    if ( !v0 )
+    {
+      v1 = 206;
+LABEL_14:
+      if ( !(unsigned __int16)_449B57_test_bit(pParty->_quest_bits, v1) )
+        goto LABEL_16;
+      goto LABEL_15;
+    }
+    if ( v0 == 1 )
+    {
+      v1 = 208;
+      goto LABEL_14;
+    }
+    if ( v0 == 2 )
+    {
+      v1 = 207;
+      goto LABEL_14;
+    }
+    if ( v0 == 3 )
+    {
+      v1 = 211;
+      goto LABEL_14;
+    }
+    if ( v0 == 4 )
+    {
+      v1 = 209;
+      goto LABEL_14;
+    }
+    if ( v0 == 5 )
+    {
+      v1 = 210;
+      goto LABEL_14;
+    }
+LABEL_15:
+    pRenderer->DrawMaskToZBuffer(
+      pTownPortalBook_xs[v0],
+      pTownPortalBook_ys[v0],
+      *(&pTexture_TownPortalHarmn + v0),
+      v0 + 1);
+LABEL_16:
+    ++v0;
+  }
+  while ( v0 < 6 );*/
+
+  pMouse->GetCursorPos(&a2);
+  //v2 = pMouse->GetCursorPos(&a2);
+  v3 = pRenderer->pActiveZBuffer[a2.x + pSRZBufferLineOffsets[a2.y]] & 0xFFFF;
+
+  if (v3)
+  {
+    if (_449B57_test_bit(pParty->_quest_bits, fountain_bits_lut[v3 - 1]))
+      pRenderer->DrawTextureIndexed(pTownPortalBook_xs[v3 - 1], pTownPortalBook_ys[v3 - 1], pTexture_TownPortalIcons[v3 - 1]);
+  }
+  v6.DrawTitleText(pBook2Font, 0, 22u, 0, pGlobalTXT_LocalizationStrings[10], 3u);
+
+
+/*  if ( !v3 )                                    // Town Portal
+  {
+    v6.DrawTitleText(pBook2Font, 0, 22, 0, pGlobalTXT_LocalizationStrings[10], 3);  // "Town Portal"
+    return;
+  }
+  if ( v3 == 1 )
+  {
+    v4 = 206;
+LABEL_30:
+    if ( (unsigned __int16)_449B57_test_bit(pParty->_quest_bits, v4) )
+      goto LABEL_31;
+    v6.DrawTitleText(pBook2Font, 0, 22u, 0, pGlobalTXT_LocalizationStrings[10], 3u);  // "Town Portal"
+    return;
+  }
+  if ( v3 == 2 )
+  {
+    v4 = 208;
+    goto LABEL_30;
+  }
+  if ( v3 == 3 )
+  {
+    v4 = 207;
+    goto LABEL_30;
+  }
+  if ( v3 == 4 )
+  {
+    v4 = 211;
+    goto LABEL_30;
+  }
+  if ( v3 == 5 )
+  {
+    v4 = 209;
+    goto LABEL_30;
+  }
+  if ( v3 == 6 )
+  {
+    v4 = 210;
+    goto LABEL_30;
+  }
+LABEL_31:
+  pRenderer->DrawTextureIndexed(word_4E1D3A[v3], pTownPortalBook_xs[v3 + 5], *(&pTex_tab_an_6b__zoom_on + v3));
+  v6.DrawTitleText(pBook2Font, 0, 22u, 0, pGlobalTXT_LocalizationStrings[10], 3u);*/
+}
+// 4E1D3A: using guessed type __int16 word_4E1D3A[];
+
+
+
+
 //----- (00413CC6) --------------------------------------------------------
 void BookUI_Draw(WindowType book)
 {
@@ -40,7 +185,7 @@
     case WINDOW_JournalBook:   BookUI_Journal_Draw();    break;
 
     case WINDOW_LloydsBeacon:  DrawLloydBeaconsScreen(); break;
-    case WINDOW_TownPortal:    DrawTownPortalScreen();   break;
+    case WINDOW_TownPortal:    BookUI_DrawTownPortalMap();   break;
   }
 }
 
--- a/UIHouses.cpp	Thu May 23 21:36:57 2013 +0600
+++ b/UIHouses.cpp	Thu May 23 21:37:22 2013 +0600
@@ -476,7 +476,7 @@
 		pMessageQueue_50CBD0->uNumMessages = pMessageQueue_50CBD0->pMessages[0].field_8 != 0;
 	viewparams->bRedrawGameUI = 1;
 	uDialogueType = 0;
-	pKeyActionMap->_459ED1(3);
+	pKeyActionMap->SetWindowInputStatus(3);
 	pKeyActionMap->ResetKeys();
 	if (uHouseID == HOUSE_600 || uHouseID == HOUSE_601)
 		{
@@ -531,8 +531,7 @@
 				return 0;
 				}
 			}
-		if ( !start_event_seq_number )
-			pAudioPlayer->StopChannels(-1, -1);
+        pAudioPlayer->StopChannels(-1, -1);
 
 		uCurrentHouse_Animation = p2DEvents[uHouseID - 1].uAnimationID;
 		in_current_building_type = pAnimatedRooms[uCurrentHouse_Animation].uBuildingType;
@@ -2121,9 +2120,9 @@
 	case HOUSE_DIALOGUE_TOWNHALL_100:
 		{
 		v0 = window_SpeakInHouse;
-		if ( window_SpeakInHouse->field_40 == 1 )
+		if ( window_SpeakInHouse->receives_keyboard_input_2 == WINDOW_INPUT_IN_PROGRESS)
 		{
-			sprintf(pTmpBuf, "%s\n%s", pGlobalTXT_LocalizationStrings[606], pGlobalTXT_LocalizationStrings[112]); // "Pay"   "How Much?"
+			sprintfex(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, 3);
 			v3 = pFontArrus;
@@ -2131,7 +2130,7 @@
 			_this.DrawFlashingInputCursor(v4 / 2 + 80, 185, v3);
 			return;
 		}
-		if ( window_SpeakInHouse->field_40 == 2 )
+		if ( window_SpeakInHouse->receives_keyboard_input_2 == WINDOW_INPUT_CONFIRMED)
 		{
 			v1 = atoi((const char *)pKeyActionMap->pPressedKeysBuffer);
 			v2 = v1;
@@ -2155,9 +2154,9 @@
 				pPlayers[uActiveCharacter]->PlaySound(SPEECH_81, 0);
 			v0 = window_SpeakInHouse;
 		}
-		if ( window_SpeakInHouse->field_40 == 3 )
+		if ( window_SpeakInHouse->receives_keyboard_input_2 == WINDOW_INPUT_CANCELLED)
 		{
-			v0->field_40 = 0;
+			v0->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
 			pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
 		}
 		break;
@@ -2176,7 +2175,7 @@
 void __cdecl BankDialog()
 {
   GUIWindow *v0; // eax@4
-  int v1; // ecx@5
+  //int v1; // ecx@5
   int v2; // eax@6
   unsigned int v3; // esi@6
   GUIFont *v4; // ST10_4@12
@@ -2216,24 +2215,15 @@
 	case HOUSE_DIALOGUE_BANK_7:
 		{
 		v0 = window_SpeakInHouse;
-		if ( window_SpeakInHouse->field_40 != 1 )
+		if ( window_SpeakInHouse->receives_keyboard_input_2 != WINDOW_INPUT_IN_PROGRESS)
 		{
-			v1 = window_SpeakInHouse->field_40 - 2;
-			if ( window_SpeakInHouse->field_40 == 2 )
+			if ( window_SpeakInHouse->receives_keyboard_input_2 == WINDOW_INPUT_CONFIRMED)
 			{
 				v6 = atoi((const char *)pKeyActionMap->pPressedKeysBuffer);
 				v7 = v6;
 				if ( !v6 )
 				{
-//LABEL_17:
 					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 ( v6 > pParty->uNumGold )
@@ -2249,13 +2239,13 @@
 						pPlayers[uActiveCharacter]->PlaySound(SPEECH_81, 0);
 				}
 				v0 = window_SpeakInHouse;
-				v0->field_40 = 0;
+				v0->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
 				pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
 				return;
 			}
-			if ( v1 != 1 )
+			if (window_SpeakInHouse->receives_keyboard_input_2 != WINDOW_INPUT_CANCELLED)
 				return;
-			v0->field_40 = 0;
+			v0->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
 			pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
 			return;      
 		}
@@ -2273,12 +2263,11 @@
 	case HOUSE_DIALOGUE_BANK_8:
 		{
 		v0 = window_SpeakInHouse;
-		if ( window_SpeakInHouse->field_40 != 1 )
+		if ( window_SpeakInHouse->receives_keyboard_input_2 != WINDOW_INPUT_IN_PROGRESS)
 		{
-			v1 = window_SpeakInHouse->field_40 - 2;
-			if ( window_SpeakInHouse->field_40 == 2 )
+			if ( window_SpeakInHouse->receives_keyboard_input_2 == WINDOW_INPUT_CONFIRMED)
 			{
-				window_SpeakInHouse->field_40 = 0;
+				window_SpeakInHouse->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
 				v2 = atoi((const char *)pKeyActionMap->pPressedKeysBuffer);
 				v3 = v2;
 				if ( v2 )
@@ -2294,18 +2283,19 @@
 						pParty->uNumGoldInBank -= v3;
 					}
 				}
+                v0->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
 				pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
 				return;
 			}
-			if ( v1 != 1 )
+			if ( window_SpeakInHouse->receives_keyboard_input_2 != WINDOW_INPUT_CANCELLED)
 				return;
-			v0->field_40 = 0;
+			v0->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
 			pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
 			return;  
 		}
 		v11 = pGlobalTXT_LocalizationStrings[112];
 		v10 = pGlobalTXT_LocalizationStrings[244];
-		sprintf(pTmpBuf, "%s\n%s", v10, v11);
+		sprintfex(pTmpBuf, "%s\n%s", v10, v11);
 		_this.DrawTitleText(pFontArrus, 0, 0x92u, v14[0], pTmpBuf, 3u);
 		_this.DrawTitleText(pFontArrus, 0, 0xBAu, v13[0], (const char *)pKeyActionMap->pPressedKeysBuffer, 3u);
 		v4 = pFontArrus;
@@ -4797,7 +4787,7 @@
     HIDWORD(v59) = TargetColor(0xFFu, 0xFFu, 0x9Bu);
     v1 = pPlayers[uActiveCharacter];
     //v2 = pPlayers[uActiveCharacter]->_4B807C(p2DEvents_minus1__20[13 * (unsigned int)v0->ptr_1C]);
-    v2 = pPlayers[uActiveCharacter]->_4B807C(p2DEvents[(unsigned int)v0->ptr_1C - 1].fPriceMultiplier);
+    v2 = pPlayers[uActiveCharacter]->_4B807C(p2DEvents[v0->par1C - 1].fPriceMultiplier);
     HIDWORD(v60) = v2;
     if ( dialog_menu_id != HOUSE_DIALOGUE_MAIN )
     {
--- a/UIMainMenu.cpp	Thu May 23 21:36:57 2013 +0600
+++ b/UIMainMenu.cpp	Thu May 23 21:37:22 2013 +0600
@@ -359,8 +359,6 @@
                 }
             else
                 {
-                if (pAsyncMouse)
-                    pAsyncMouse->_46B736_consume_click_lists(1);
                 pRenderer->BeginScene();
                 pRenderer->DrawTextureRGB(0, 0, &pTexture);
                 pRenderer->SetTextureClipRect(pX, pY, pX + v20, pY + a4);
--- a/UIOptions.cpp	Thu May 23 21:36:57 2013 +0600
+++ b/UIOptions.cpp	Thu May 23 21:37:22 2013 +0600
@@ -89,7 +89,7 @@
     signed int v4; // ecx@7
     signed int v5; // eax@8
     
-    if ( pGUIWindow_CurrentMenu->field_40 == 2 )
+    if ( pGUIWindow_CurrentMenu->receives_keyboard_input_2 == WINDOW_INPUT_CONFIRMED)
         {
         pPrevVirtualCidesMapping[uGameMenuUI_CurentlySelectedKeyIdx] = pKeyActionMap->pPressedKeysBuffer[0];
         memset(GameMenuUI_InvaligKeyBindingsFlags, 0, sizeof(GameMenuUI_InvaligKeyBindingsFlags));
@@ -111,7 +111,7 @@
             }
             while ( v4 < 28 );
             uGameMenuUI_CurentlySelectedKeyIdx = -1;
-            pGUIWindow_CurrentMenu->field_40 = 0;
+            pGUIWindow_CurrentMenu->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
         }
     pRenderer->DrawTextureIndexed(8, 8, pIcons_LOD->GetTexture(uTextureID_Optkb[0]));
     if ( KeyboardPageNum == 1 )
--- a/UIPartyCreation.cpp	Thu May 23 21:36:57 2013 +0600
+++ b/UIPartyCreation.cpp	Thu May 23 21:37:22 2013 +0600
@@ -257,16 +257,16 @@
     pGUIWindow_CurrentMenu->DrawText(pFontCreate, pIntervalX + 73, 100, 0, pClassNames[player->classType], 0, 0, 0);
     pRenderer->DrawTextureTransparent(pIntervalX + 77, 50, pTexture_IC_KNIGHT[player->classType / 4]);
 
-    if ( pGUIWindow_CurrentMenu->field_40 && pGUIWindow_CurrentMenu->ptr_1C == (void *)i )
+    if ( pGUIWindow_CurrentMenu->receives_keyboard_input_2 != WINDOW_INPUT_NONE && pGUIWindow_CurrentMenu->ptr_1C == (void *)i )
     {
-      switch ( pGUIWindow_CurrentMenu->field_40 )
+      switch ( pGUIWindow_CurrentMenu->receives_keyboard_input_2 )
       {
-        case 1://press name panel
+        case WINDOW_INPUT_IN_PROGRESS://press name panel
           v17 = pGUIWindow_CurrentMenu->DrawTextInRect(pFontCreate, 159 * (int)pGUIWindow_CurrentMenu->ptr_1C + 18, 124, 0, (const char *)pKeyActionMap->pPressedKeysBuffer, 120, 1);
           pGUIWindow_CurrentMenu->DrawFlashingInputCursor(159 * (unsigned int)pGUIWindow_CurrentMenu->ptr_1C + v17 + 20, 124, pFontCreate);
           break;
-        case 2: // press enter
-          pGUIWindow_CurrentMenu->field_40 = 0;
+        case WINDOW_INPUT_CONFIRMED: // press enter
+          pGUIWindow_CurrentMenu->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
           v120 = strlen((const char *)pKeyActionMap->pPressedKeysBuffer);
           v126 = 0;
           v133 = 0;
@@ -286,8 +286,8 @@
           pGUIWindow_CurrentMenu->DrawTextInRect(pFontCreate, pIntervalX, 124, 0, player->pName, 130, 0);
           *(short *)&player->field_1988[27] = 1;
           break;
-        case 3: // press escape
-          pGUIWindow_CurrentMenu->field_40 = 0;
+        case WINDOW_INPUT_CANCELLED: // press escape
+          pGUIWindow_CurrentMenu->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
           pGUIWindow_CurrentMenu->DrawTextInRect(pFontCreate, pIntervalX, 124, 0, player->pName, 130, 0);
           SetCurrentMenuID(MENU_NAMEPANELESC);
           break;
@@ -657,10 +657,10 @@
   }
   while ( uControlParamd < 9 );
 
-  pPlayerCreationUI_BtnOK    = pGUIWindow_CurrentMenu->CreateButton(580, 431, 51, 39, 1, 0, UIMSG_PlayerCreationClickOK, 0, 0xD, "", pIcons_LOD->GetTexture(uTextureID_BUTTMAKE), 0);
-  pPlayerCreationUI_BtnReset = pGUIWindow_CurrentMenu->CreateButton(527, 431, 51, 39, 1, 0, UIMSG_PlayerCreationClickReset, 0, 0x43, "", pIcons_LOD->GetTexture(uTextureID_BUTTMAKE2), 0);
-  pPlayerCreationUI_BtnMinus = pGUIWindow_CurrentMenu->CreateButton(523, 393, 20, 35, 1, 0, UIMSG_PlayerCreationClickMinus, 0, 0x2D, "", pTexture_buttminu, 0);
-  pPlayerCreationUI_BtnPlus  = pGUIWindow_CurrentMenu->CreateButton(613, 393, 20, 35, 1, 0, UIMSG_PlayerCreationClickPlus, 1, 0x2B, "", pTexture_buttplus, 0);
+  pPlayerCreationUI_BtnOK    = pGUIWindow_CurrentMenu->CreateButton(580, 431, 51, 39, 1, 0, UIMSG_PlayerCreationClickOK, 0, '\r', "", pIcons_LOD->GetTexture(uTextureID_BUTTMAKE), 0);
+  pPlayerCreationUI_BtnReset = pGUIWindow_CurrentMenu->CreateButton(527, 431, 51, 39, 1, 0, UIMSG_PlayerCreationClickReset, 0, 'C', "", pIcons_LOD->GetTexture(uTextureID_BUTTMAKE2), 0);
+  pPlayerCreationUI_BtnMinus = pGUIWindow_CurrentMenu->CreateButton(523, 393, 20, 35, 1, 0, UIMSG_PlayerCreationClickMinus, 0, '-', "", pTexture_buttminu, 0);
+  pPlayerCreationUI_BtnPlus  = pGUIWindow_CurrentMenu->CreateButton(613, 393, 20, 35, 1, 0, UIMSG_PlayerCreationClickPlus, 1, '+', "", pTexture_buttplus, 0);
 
   pFontCChar = LoadFont("cchar.fnt", "FONTPAL", NULL);
 }
@@ -708,16 +708,13 @@
   v26 = 0;
   pTexture_PCX.Release();
   pTexture_PCX.Load("makeme.pcx", 0);
-  if (pAsyncMouse)
-    pAsyncMouse->Resume();
+
   v2 = 6;
-  pGUIWindow_CurrentMenu->field_40 = 0;
+  pGUIWindow_CurrentMenu->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
 //LABEL_27:
   SetCurrentMenuID((MENU_STATE)v2);
   while ( GetCurrentMenuID() == MENU_CREATEPARTY )
   {
-    if (pAsyncMouse)
-      pAsyncMouse->_46B736_consume_click_lists(1);
     uMouseX = pMouse->GetCursorPos(&v25)->x;
     uMouseY = pMouse->GetCursorPos(&v25)->y;
     pControlsHead = pGUIWindow_CurrentMenu->pControlsHead;
@@ -911,7 +908,5 @@
   }
 
   pAudioPlayer->StopChannels(-1, -1);
-  if (pAsyncMouse)
-    pAsyncMouse->Suspend();
   return v26;
 }
\ No newline at end of file
--- a/UISaveLoad.cpp	Thu May 23 21:36:57 2013 +0600
+++ b/UISaveLoad.cpp	Thu May 23 21:37:22 2013 +0600
@@ -180,23 +180,16 @@
     pWindow.DrawTitleText(pFontSmallnum, 0, 0, 0, pTmpBuf, 3u);
     v1 = 255;
   }
-  if ( pGUIWindow_CurrentMenu->field_40 == 2 )
+  if ( pGUIWindow_CurrentMenu->receives_keyboard_input_2 == WINDOW_INPUT_CONFIRMED)
   {
-    pGUIWindow_CurrentMenu->field_40 = 0;
+    pGUIWindow_CurrentMenu->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
     strcpy((char *)&pSavegameHeader + 100 * uLoadGameUI_SelectedSlot, (const char *)pKeyActionMap->pPressedKeysBuffer);
-    /*if ( (signed int)pMessageQueue_50CBD0->uNumMessages < 40 )
-    {
-      pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].eType = UIMSG_SaveGame;
-      pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = 0;
-      *(&pMessageQueue_50CBD0->uNumMessages + 3 * pMessageQueue_50CBD0->uNumMessages + 3) = 0;
-      ++pMessageQueue_50CBD0->uNumMessages;
-    }*/
     pMessageQueue_50CBD0->AddMessage(UIMSG_SaveGame, 0, 0);
   }
   else
   {
-    if ( pGUIWindow_CurrentMenu->field_40 == 3 )
-      pGUIWindow_CurrentMenu->field_40 = 0;
+    if ( pGUIWindow_CurrentMenu->receives_keyboard_input_2 == WINDOW_INPUT_CANCELLED)
+      pGUIWindow_CurrentMenu->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
   }
   if (GetCurrentMenuID() == MENU_LoadingProcInMainMenu)
   {
@@ -225,7 +218,7 @@
         break;
       short clr;
       HIDWORD(pAMPM2) = clr = (pFilesID == uLoadGameUI_SelectedSlot ? TargetColor(v1, v1, 0x64) : 0);
-      if ( pGUIWindow_CurrentMenu->field_40 != 1 || pFilesID != uLoadGameUI_SelectedSlot )
+      if ( pGUIWindow_CurrentMenu->receives_keyboard_input_2 != WINDOW_INPUT_IN_PROGRESS || pFilesID != uLoadGameUI_SelectedSlot )
       {
         pGUIWindow_CurrentMenu->DrawTextInRect(pFontSmallnum, 0x1B, a4, clr, pSlotName, 185, 0);
       }
--- a/UiGame.cpp	Thu May 23 21:36:57 2013 +0600
+++ b/UiGame.cpp	Thu May 23 21:37:22 2013 +0600
@@ -70,6 +70,257 @@
 
 
 
+//----- (00421D00) --------------------------------------------------------
+void __fastcall GameUI_OnPlayerPortraitLeftClick(unsigned int uPlayerID)
+{
+  //unsigned int v1; // esi@1
+  //int v2; // eax@2
+  //Player *v3; // ecx@2
+  //Player *v4; // ecx@5
+  unsigned int v5; // [sp-4h] [bp-10h]@21
+
+  //v1 = uPlayerID;
+  auto player = &pParty->pPlayers[uPlayerID - 1];
+  if (pParty->pPickedItem.uItemID)
+  {
+    //v3 = player;
+    if (auto slot = player->AddItem(-1, pParty->pPickedItem.uItemID))
+    {
+      memcpy(&player->pInventoryItems[slot-1], &pParty->pPickedItem, 0x24u);
+      viewparams->bRedrawGameUI = true;
+      pMouse->RemoveHoldingItem();
+      return;
+    }
+
+    if (!player->CanAct())
+    {
+      player = pPlayers[uActiveCharacter];
+    }
+    if(player->CanAct() || !pPlayers[uActiveCharacter]->CanAct())
+		player->PlaySound(SPEECH_NoRoom, 0);
+  }
+
+//LABEL_9:
+  if (pCurrentScreen == SCREEN_GAME)
+  {
+    viewparams->bRedrawGameUI = true;
+    if ( uActiveCharacter != uPlayerID )
+      //goto LABEL_27;
+    {
+      if ( pPlayers[uPlayerID]->uTimeToRecovery )
+        return;
+
+      uActiveCharacter = uPlayerID;
+      return;
+    }
+    v5 = 7;
+//LABEL_22:
+    pGUIWindow_CurrentMenu = CharacterUI_Initialize(v5);
+    return;
+  }
+  if ( pCurrentScreen == SCREEN_SPELL_BOOK )
+    return;
+  if ( pCurrentScreen == SCREEN_CHEST )
+  {
+//LABEL_23:
+    viewparams->bRedrawGameUI = true;
+    if ( uActiveCharacter == uPlayerID )
+    {
+      pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] = 103;
+      pCurrentScreen = SCREEN_CHEST_INVENTORY;
+      //goto LABEL_28;
+      uActiveCharacter = uPlayerID;
+      return;
+    }
+//LABEL_27:
+    if ( pPlayers[uPlayerID]->uTimeToRecovery )
+      return;
+    //goto LABEL_28;
+    uActiveCharacter = uPlayerID;
+    return;
+  }
+  if ( pCurrentScreen != SCREEN_HOUSE )
+  {
+    if ( pCurrentScreen == SCREEN_E )
+    {
+//LABEL_28:
+      uActiveCharacter = uPlayerID;
+      return;
+    }
+    if ( pCurrentScreen != SCREEN_CHEST_INVENTORY )
+    {
+      viewparams->bRedrawGameUI = true;
+      uActiveCharacter = uPlayerID;
+      if ( pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] == 102 )
+        FillAwardsData();
+      return;
+    }
+    //goto LABEL_23;
+    viewparams->bRedrawGameUI = true;
+    if ( uActiveCharacter == uPlayerID )
+    {
+      pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] = 103;
+      pCurrentScreen = SCREEN_CHEST_INVENTORY;
+      //goto LABEL_28;
+      uActiveCharacter = uPlayerID;
+      return;
+    }
+//LABEL_27:
+    if ( pPlayers[uPlayerID]->uTimeToRecovery )
+      return;
+    //goto LABEL_28;
+    uActiveCharacter = uPlayerID;
+    return;
+  }
+  if ( window_SpeakInHouse->receives_keyboard_input_2 == WINDOW_INPUT_IN_PROGRESS)
+    return;
+  viewparams->bRedrawGameUI = true;
+  if ( uActiveCharacter != uPlayerID )
+    //goto LABEL_28;
+    uActiveCharacter = uPlayerID;
+    return;
+  if (dialog_menu_id == HOUSE_DIALOGUE_SHOP_BUY_STANDARD || dialog_menu_id == HOUSE_DIALOGUE_SHOP_6)
+  {
+    __debugbreak(); // fix indexing
+    pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] = 103;
+    v5 = 14;
+    //goto LABEL_22;
+    pGUIWindow_CurrentMenu = CharacterUI_Initialize(v5);
+    return;
+  }
+}
+// 4E28F8: using guessed type int pCurrentScreen;
+// F8B19C: using guessed type int dword_F8B19C;
+
+//----- (00416B01) --------------------------------------------------------
+void GameUI_DrawNPCPopup(void *_this)//PopupWindowForBenefitAndJoinText
+{
+  int v1; // edi@2
+  int v2; // ecx@2
+  NPCData *v3; // eax@2
+  NPCData *v4; // esi@7
+  NPCData *v5; // eax@16
+  NPCData *v6; // esi@16
+  const CHAR *v7; // eax@18
+  unsigned int v8; // eax@25
+  unsigned int v9; // eax@25
+  const char *v10; // ST14_4@26
+  char *v11; // esi@26
+  const char *v12; // ST18_4@27
+  unsigned __int16 v13; // ax@28
+  char *v14; // eax@28
+  GUIWindow a1; // [sp+Ch] [bp-60h]@23
+  int a2; // [sp+60h] [bp-Ch]@16
+  void *v17; // [sp+64h] [bp-8h]@1
+  LPCSTR lpsz; // [sp+68h] [bp-4h]@6
+
+  v17 = _this;
+  if ( bNoNPCHiring != 1 )
+  {
+    v1 = 0;
+    v2 = 0;
+    v3 = pParty->pHirelings;
+    /*do
+    {
+      if ( v3->pName )
+        pTmpBuf[v1++] = v2;
+      ++v3;
+      ++v2;
+    }
+    while ( (signed int)v3 < (signed int)&pParty->pPickedItem );*/
+    for (int i = 0; i < 2; ++i)
+    {
+     if (pParty->pHirelings[i].pName)
+        pTmpBuf[v1++] = i;
+    }
+    lpsz = 0;
+    if ( (signed int)pNPCStats->uNumNewNPCs > 0 )
+    {
+      /*v4 = pNPCStats->pNewNPCData;
+      do
+      {
+        if ( v4->uFlags & 0x80
+          && (!pParty->pHirelings[0].pName || strcmp(v4->pName, pParty->pHirelings[0].pName))
+          && (!pParty->pHirelings[1].pName || strcmp(v4->pName, pParty->pHirelings[1].pName)) )
+          pTmpBuf[v1++] = (char)lpsz + 2;
+        ++lpsz;
+        ++v4;
+      }
+      while ( (signed int)lpsz < (signed int)pNPCStats->uNumNewNPCs );*/
+      for (int i = 0; i < pNPCStats->uNumNewNPCs; ++i)
+      {
+        if (pNPCStats->pNewNPCData[i].Hired())
+        {
+          if (!pParty->pHirelings[0].pName || strcmp((char *)pNPCStats->pNewNPCData[i].pName, (char *)pParty->pHirelings[0].pName))
+          {
+            if (!pParty->pHirelings[1].pName || strcmp((char *)pNPCStats->pNewNPCData[i].pName, (char *)pParty->pHirelings[1].pName))
+              pTmpBuf[v1++] = i + 2;
+          }
+        }
+      }
+    }
+    if ( (signed int)((char *)v17 + (unsigned __int8)pParty->field_709) < v1 )
+    {
+      sDialogue_SpeakingActorNPC_ID = -1 - (unsigned __int8)pParty->field_709 - (int)v17;
+      v5 = GetNewNPCData(sDialogue_SpeakingActorNPC_ID, (int)&a2);
+      v6 = v5;
+      if ( v5 )
+      {
+        if ( a2 == 57 )
+          v7 = pNPCTopics[512].pText; // Baby dragon
+        else
+          v7 = (const CHAR *)pNPCStats->pProfessions[v5->uProfession].pBenefits;
+        lpsz = v7;
+        if ( !v7 )
+        {
+          lpsz = (LPCSTR)pNPCStats->pProfessions[v5->uProfession].pJoinText;
+          if ( !lpsz )
+            lpsz = "";
+        }
+        a1.Hint = 0;
+        a1.uFrameX = 38;
+        a1.uFrameY = 60;
+        a1.uFrameWidth = 276;
+        a1.uFrameZ = 313;
+        a1.uFrameHeight = pFontArrus->CalcTextHeight(lpsz, &a1, 0, 0)
+                        + 2 * LOBYTE(pFontArrus->uFontHeight)
+                        + 24;
+        if ( (signed int)a1.uFrameHeight < 130 )
+          a1.uFrameHeight = 130;
+        a1.uFrameWidth = 400;
+        a1.uFrameZ = a1.uFrameX + 399;
+        a1.DrawMessageBox(0);
+        sprintfex(pTmpBuf2, "NPC%03d", v6->uPortraitID);
+        v8 = pIcons_LOD->LoadTexture(pTmpBuf2, TEXTURE_16BIT_PALETTE);
+        pRenderer->DrawTextureIndexed(
+          a1.uFrameX + 22,
+          a1.uFrameY + 36,
+          (Texture *)(v8 != -1 ? &pIcons_LOD->pTextures[v8] : 0));
+        v9 = v6->uProfession;
+        if ( v9 )
+        {
+          v10 = v6->pName;
+          v11 = pTmpBuf;
+          sprintfex(pTmpBuf, pGlobalTXT_LocalizationStrings[429], v10, aNPCProfessionNames[v9]);
+        }
+        else
+        {
+          v12 = v6->pName;
+          v11 = pTmpBuf;
+          strcpy(pTmpBuf, v12);
+        }
+        v13 = TargetColor(0xFFu, 0xFFu, 0x9Bu);
+        a1.DrawTitleText(pFontArrus, 0, 0xCu, v13, v11, 3u);
+        a1.uFrameWidth -= 24;
+        a1.uFrameZ = a1.uFrameX + a1.uFrameWidth - 1;
+        v14 = BuilDialogueString((char *)lpsz, uActiveCharacter - 1, 0, 0, 0, 0);
+        a1.DrawText(pFontArrus, 100, 36, 0, v14, 0, 0, 0);
+      }
+    }
+  }
+}
+
+
 
 //----- (00445D4A) --------------------------------------------------------
 void GameUI_InitializeDialogue(Actor *actor, int bPlayerSaysHello)
@@ -559,19 +810,19 @@
   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->receives_keyboard_input_2 != WINDOW_INPUT_IN_PROGRESS)
   {
-    if ( pGUIWindow2->field_40 == 2 )
+    if ( pGUIWindow2->receives_keyboard_input_2 == WINDOW_INPUT_CONFIRMED)
     {
-      pGUIWindow2->field_40 = 0;
+      pGUIWindow2->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
       strcpy(GameUI_Footer_TimedString, (const char *)pKeyActionMap->pPressedKeysBuffer);
 LABEL_16:
       sub_4452BB();
       return;
     }
-    if ( pGUIWindow2->field_40 != 3 )
+    if ( pGUIWindow2->receives_keyboard_input_2 != WINDOW_INPUT_CANCELLED)
       return;
-    pGUIWindow2->field_40 = 0;
+    pGUIWindow2->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
 LABEL_15:
     memset(GameUI_Footer_TimedString, 0, 0xC8u);
     goto LABEL_16;
@@ -586,7 +837,7 @@
   }
   if ( pKeyActionMap->pPressedKeysBuffer[0] )
   {
-    pKeyActionMap->_459ED1(0);
+    pKeyActionMap->SetWindowInputStatus(0);
     goto LABEL_15;
   }
 }
--- a/Viewport.cpp	Thu May 23 21:36:57 2013 +0600
+++ b/Viewport.cpp	Thu May 23 21:37:22 2013 +0600
@@ -4,6 +4,7 @@
 #include "VectorTypes.h"
 #include "Indoor.h"
 #include "Render.h"
+#include "Math.h"
 #include "mm7_data.h"
 
 
@@ -232,7 +233,7 @@
         {
         indoor_center_x = 0;
         indoor_center_y = 0;
-        uMinimapZoom = dword_576E2C;
+        uMinimapZoom = _576E2C_current_minimap_zoom;
         field_28 = dword_576E28;
         }
     field_2C = 384;
--- a/Vis.cpp	Thu May 23 21:36:57 2013 +0600
+++ b/Vis.cpp	Thu May 23 21:37:22 2013 +0600
@@ -6,7 +6,9 @@
 #include "Game.h"
 #include "Actor.h"
 #include "IndoorCamera.h"
+#include "OutdoorCamera.h"
 #include "Viewport.h"
+#include "Math.h"
 #include "Log.h"
 
 #include "mm7_data.h"
@@ -367,8 +369,8 @@
     auto bmodel = &pOutdoor->pBModels[i];
     for (uint j = 0; j < bmodel->uNumFaces; ++j)
     {
-		//if ( i == 77 && j == 17 )//
-		  //__debugbreak();//
+		//if ( i == 1 && j == 30 )//
+            //__debugbreak();//
       auto face = &bmodel->pFaces[j];
       if (is_part_of_selection(face, filter))
       {
@@ -547,144 +549,120 @@
 //----- (004C1C0C) --------------------------------------------------------
 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 v9; // st7@3
-  //__int16 v10; // fps@3
-  //char v11; // c0@3
-  //char v12; // c2@3
-  //char v13; // c3@3
-  //__int16 v14; // fps@5
-  //char v15; // c0@5
-  //char v16; // c2@5
-  //char v17; // c3@5
-  double c1; // st5@6
-  //__int16 v19; // fps@6
-  //char v20; // c0@6
-  //char v21; // c2@6
-  //char v22; // c3@6
-  //unsigned __int8 v23; // c0@6
-  //char v24; // c2@6
-  //unsigned __int8 v25; // c3@6
-  //char v26; // zf@6
-  double v27; // st6@10
-  //__int16 v28; // fps@10
-  //unsigned __int8 v29; // c0@10
-  //char v30; // c2@10
-  //unsigned __int8 v31; // c3@10
-  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
+  float c1; // st5@6
+  float c2; // st7@11
+  Vec3_short_ IntersectPoint; // ST04_6@11
+
 
   if (pFace->Portal() || pFace->Invisible())
     return false;
 
-  int ray_dir_x = pRayEnd->vWorldPosition.x - pRayStart->vWorldPosition.x,//dir_x y z   
-      ray_dir_y = pRayEnd->vWorldPosition.y - pRayStart->vWorldPosition.y,//  -    =     
+  int ray_dir_x = pRayEnd->vWorldPosition.x - pRayStart->vWorldPosition.x,//calculate the direction vector of the line(   )
+      ray_dir_y = pRayEnd->vWorldPosition.y - pRayStart->vWorldPosition.y,
       ray_dir_z = pRayEnd->vWorldPosition.z - pRayStart->vWorldPosition.z;
 
-  /*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;*/
-
-//ray   = t dir + start
-//plane = (p - vertex) normal = -d
-//
-//
-//(t dir + start - vertex) normal = -d
-//
-//      -d - (start - vertex) norm
-//t =       --------------------
-//               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 -  
-        ndir_y = ray_dir_y / dir_mag,//    ,     ,     ( ).
-        ndir_z = ray_dir_z / dir_mag;//   ,        
-
-  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,//     
-      to_plane_y = pRayStart->vWorldPosition.y - face_center_y,
-      to_plane_z = pRayStart->vWorldPosition.z - face_center_z;*/
-
-  //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 < 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;
-
-    pFace->uAttributes |= 0x80000000;
-    return true;
-  }
-
-  return false;*/
-
-
 //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
+  if (c1 > 0)
+    return false;
+#define EPSILON 1e-6
 //c2 = n*u
-  c2 = pFace->pFacePlane.vNormal.x * ray_dir_y
+  c2 = pFace->pFacePlane.vNormal.x * ray_dir_y// get length of the line(    )
        + 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;
 
 //t = -d-(n*p0)/n*u
-  double t = c1 / c2;// 
-
-  //if (t < 0 || t > 1)
-    //return false;
+  float t = c1 / c2;//How far is crossing the line in percent for 0 to 1(       0  1 )
 
-  // p(t) = p0 + tu;
-  // p(t) -      
-  // p0 -   ,  , 
-  // t - 
-  // u -  
-  Intersection->vWorldPosition.x = pRayStart->vWorldPosition.x + t * ray_dir_y;//12432 < X < 12656
-  Intersection->vWorldPosition.y = pRayStart->vWorldPosition.y + t * ray_dir_x;//-96 < Y < 1088
-  Intersection->vWorldPosition.z = pRayStart->vWorldPosition.z + t * ray_dir_z;//Z == 192
-
-  v34.x = (signed __int64)Intersection->vWorldPosition.x;
-  v34.y = (signed __int64)Intersection->vWorldPosition.y;
-  v34.z = (signed __int64)Intersection->vWorldPosition.z;
-        
-  if ( !_4C1D2B(pFace, v34, pBModelID) )
+  if (t < 0 || t > 1)
     return false;
 
-  //a5b = v27;
-  //*pDepth = t;
+// p(t) = p0 + tu;
+  Intersection->vWorldPosition.x = pRayStart->vWorldPosition.x + t * ray_dir_y;// add the interest to the start line(     )
+  Intersection->vWorldPosition.y = pRayStart->vWorldPosition.y + t * ray_dir_x;
+  Intersection->vWorldPosition.z = pRayStart->vWorldPosition.z + t * ray_dir_z;
+
+  IntersectPoint.x = (signed __int64)Intersection->vWorldPosition.x;
+  IntersectPoint.y = (signed __int64)Intersection->vWorldPosition.y;
+  IntersectPoint.z = (signed __int64)Intersection->vWorldPosition.z;
+
+  if ( !CheckIntersectBModel(pFace, IntersectPoint, pBModelID) )
+    return false;
+
+  *pDepth = t;//Record the distance from the origin of the ray (    )
   return true;
 }
 
 //----- (004C1D2B) --------------------------------------------------------
-bool Vis::_4C1D2B(BLVFace *pFace, Vec3_short_ a2, unsigned int uModelID)
+bool Vis::CheckIntersectBModel(BLVFace *pFace, Vec3_short_ IntersectPoint, unsigned int uModelID)
 {
-  //BLVFace *v4; // esi@1
   int v5; // esi@10
   bool v6; // edi@10
-  int v7; // ecx@12
-  signed int v8; // edx@12
-  signed int v9; // eax@13
+  signed int v10; // ebx@14
+  int v15; // [sp+10h] [bp-Ch]@10
+  signed int v16; // [sp+18h] [bp-4h]@10
+
+  int a = 0, b = 0;
+
+  if (IntersectPoint.x < pFace->pBounding.x1 || IntersectPoint.x > pFace->pBounding.x2 ||
+      IntersectPoint.y < pFace->pBounding.y1 || IntersectPoint.y > pFace->pBounding.y2 ||
+      IntersectPoint.z < pFace->pBounding.z1 || IntersectPoint.z > pFace->pBounding.z2 )
+    return false;
+
+  pFace->uAttributes |= 0x80000000;
+
+  if (uModelID != -1)
+    ODM_CreateIntersectFacesVertexCoordList(&a, &b, intersect_face_vertex_coords_list_a, intersect_face_vertex_coords_list_b,
+                                &IntersectPoint, pFace, uModelID);
+  else
+    BLV_CreateIntersectFacesVertexCoordList(&a, &b, intersect_face_vertex_coords_list_a, intersect_face_vertex_coords_list_b,
+                                  &IntersectPoint, pFace);
+  v5 = 2 * pFace->uNumVertices;
+  v16 = 0;
+  intersect_face_vertex_coords_list_a[v5] = intersect_face_vertex_coords_list_a[0];
+  intersect_face_vertex_coords_list_b[v5] = intersect_face_vertex_coords_list_b[0];
+  v6 = intersect_face_vertex_coords_list_b[0] >= b;
+  if (v5 <= 0)
+    return false;
+  for ( uint i = 0; i < v5; ++i )
+  {
+    if ( v16 >= 2 )
+      break;
+    if ( v6 ^ intersect_face_vertex_coords_list_b[i + 1] >= b )
+    {
+      if ( intersect_face_vertex_coords_list_a[i + 1] >= a )
+        v10 = 0;
+      else
+        v10 = 2;
+      v10 |= intersect_face_vertex_coords_list_a[i] < a ? 1 : 0;
+      if ( v10 != 3 )
+      {
+        if ( !v10)
+          ++v16;
+        else
+        {
+          int _v1 = fixpoint_div(intersect_face_vertex_coords_list_a[i + 1] - intersect_face_vertex_coords_list_a[i],
+                                 intersect_face_vertex_coords_list_b[i + 1] - intersect_face_vertex_coords_list_b[i]);
+          int _v2 = fixpoint_mul(b - intersect_face_vertex_coords_list_b[i], _v1) + 32768;
+
+          if (intersect_face_vertex_coords_list_a[i] + (_v2 >> 16) >= a)
+            ++v16;
+        }
+      }
+    }
+    v6 = intersect_face_vertex_coords_list_b[i + 1] >= b;
+  }
+
+  if ( v16 != 1 )
+    return false;
+  return true;
+/*
+  int v5; // esi@10
+  bool v6; // edi@10
   signed int v10; // ebx@14
   int v11; // edi@16
   signed int v12; // ST28_4@18
@@ -693,219 +671,192 @@
   int v15; // [sp+10h] [bp-Ch]@10
   signed int v16; // [sp+18h] [bp-4h]@10
 
-  //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 )
+  int a = 0, b = 0;
+
+  if (IntersectPoint.x < pFace->pBounding.x1 || IntersectPoint.x > pFace->pBounding.x2 ||
+      IntersectPoint.y < pFace->pBounding.y1 || IntersectPoint.y > pFace->pBounding.y2 ||
+      IntersectPoint.z < pFace->pBounding.z1 || IntersectPoint.z > pFace->pBounding.z2 )
     return false;
 
   pFace->uAttributes |= 0x80000000;
-  return true;
+
   if (uModelID != -1)
-    _4C2186_BLV_IntersectBModel(pFace, uModelID,
-                                word_F8BC48_displaced_face_intersect_plane_coords_a,
-                                word_F8BD18_displaced_face_intersect_plane_coords_b,
-                                &a2, pFace, uModelID);
+    ODM_CreateIntersectFacesVertexCoordList(&a, &b, intersect_face_vertex_coords_list_a, intersect_face_vertex_coords_list_b,
+                                &IntersectPoint, pFace, uModelID);
   else
-    _4C1EE5_BLV_IntersectBModel_2((int *)&pFace, (int *)&uModelID,
-                                  word_F8BC48_displaced_face_intersect_plane_coords_a,
-                                  word_F8BD18_displaced_face_intersect_plane_coords_b,
-                                  &a2, pFace);
-  
+    BLV_CreateIntersectFacesVertexCoordList(&a, &b, intersect_face_vertex_coords_list_a, intersect_face_vertex_coords_list_b,
+                                  &IntersectPoint, pFace);
   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];
-  v15 = 0;
-  v6 = word_F8BD18_displaced_face_intersect_plane_coords_b[0] >= (signed int)uModelID;
+  intersect_face_vertex_coords_list_a[v5] = intersect_face_vertex_coords_list_a[0];
+  intersect_face_vertex_coords_list_b[v5] = intersect_face_vertex_coords_list_b[0];
+  v6 = intersect_face_vertex_coords_list_b[0] >= b;
   if (v5 <= 0)
     return false;
-
-  do
+  for ( uint i = 0; i < v5; ++i )
   {
     if ( v16 >= 2 )
       break;
-    v7 = 2 * v15;
-    v8 = word_F8BD18_displaced_face_intersect_plane_coords_b[ + v15 + 1];
-    if ( v6 ^ v8 >= (signed int)uModelID )
+    if ( v6 ^ intersect_face_vertex_coords_list_b[i + 1] >= b )
     {
-      v9 = word_F8BC48_displaced_face_intersect_plane_coords_a[v7/2 + 1];
-      if ( v9 >= (signed int)pFace )
+      if ( intersect_face_vertex_coords_list_a[i + 1] >= a )
         v10 = 0;
       else
         v10 = 2;
-      v11 = v10 | word_F8BC48_displaced_face_intersect_plane_coords_a[v7/2] < (signed int)pFace;
+      v11 = v10 | intersect_face_vertex_coords_list_a[i] < a;
       if ( v11 != 3 )
       {
         if ( !v11
-          || (v12 = v9 - word_F8BC48_displaced_face_intersect_plane_coords_a[v7/2],
+          || (v12 = intersect_face_vertex_coords_list_a[i + 1] - intersect_face_vertex_coords_list_a[i],
               LODWORD(v13) = v12 << 16,
               HIDWORD(v13) = v12 >> 16,
-              word_F8BC48_displaced_face_intersect_plane_coords_a[v7/2]
-            + ((signed int)(((unsigned __int64)(v13 / (v8 - word_F8BD18_displaced_face_intersect_plane_coords_b[v7/2])
-                                              * (signed int)((uModelID - word_F8BD18_displaced_face_intersect_plane_coords_b[v7/2]) << 16)) >> 16) + 32768) >> 16) >= (signed int)pFace) )
+              intersect_face_vertex_coords_list_a[i]
+            + ((signed int)(((unsigned __int64)(v13 / (intersect_face_vertex_coords_list_b[i + 1] - intersect_face_vertex_coords_list_b[i])
+                                              * (signed int)((b - intersect_face_vertex_coords_list_b[i]) << 16)) >> 16) + 32768) >> 16) >= a) )
           ++v16;
       }
     }
-    ++v15;
-    v6 = v8 >= (signed int)uModelID;
+    v6 = intersect_face_vertex_coords_list_b[i + 1] >= b;
   }
-  while ( v15 < v5 );
-  result = 1;
+  result = true;
   if ( v16 != 1 )
-LABEL_25:
-    result = 0;
+    result = false;
   return result;
+}*/
 }
 
 //----- (004C1EE5) --------------------------------------------------------
-bool Vis::_4C1EE5_BLV_IntersectBModel_2(int *a1, int *a2, __int16 *a3, __int16 *a4, Vec3_short_ *a5, BLVFace *pFace)
+void Vis::BLV_CreateIntersectFacesVertexCoordList(int *a, int *b, __int16 *intersect_face_vertex_coords_list_a, __int16 *intersect_face_vertex_coords_list_b, Vec3_short_ *IntersectPoint, BLVFace *pFace)
 {
   if (pFace->uAttributes & FACE_XY_PLANE)
   {
-    *a1 = a5->x;
-    *a2 = a5->y;
+    *a = IntersectPoint->x;
+    *b = IntersectPoint->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;
+      intersect_face_vertex_coords_list_a[2 * i]     = pFace->pXInterceptDisplacements[i]     + pIndoor->pVertices[pFace->pVertexIDs[i]].x;
+      intersect_face_vertex_coords_list_a[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;
+      intersect_face_vertex_coords_list_b[2 * i]     = pFace->pYInterceptDisplacements[i]     + pIndoor->pVertices[pFace->pVertexIDs[i]].y;
+      intersect_face_vertex_coords_list_b[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;
+    *a = IntersectPoint->x;
+    *b = IntersectPoint->z;
 
     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;
+      intersect_face_vertex_coords_list_a[2 * i]     = pFace->pXInterceptDisplacements[i]     + pIndoor->pVertices[pFace->pVertexIDs[i]].x;
+      intersect_face_vertex_coords_list_a[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;
+      intersect_face_vertex_coords_list_b[2 * i]     = pFace->pZInterceptDisplacements[i]     + pIndoor->pVertices[pFace->pVertexIDs[i]].z;
+      intersect_face_vertex_coords_list_b[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;
+    *a = IntersectPoint->y;
+    *b = IntersectPoint->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;
+      intersect_face_vertex_coords_list_a[2 * i]     = pFace->pYInterceptDisplacements[i]     + pIndoor->pVertices[pFace->pVertexIDs[i]].y;
+      intersect_face_vertex_coords_list_a[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;
+      intersect_face_vertex_coords_list_b[2 * i]     = pFace->pZInterceptDisplacements[i]     + pIndoor->pVertices[pFace->pVertexIDs[i]].z;
+      intersect_face_vertex_coords_list_b[2 * i + 1] = pFace->pZInterceptDisplacements[i + 1] + pIndoor->pVertices[pFace->pVertexIDs[i + 1]].z;
     }
   }
-  else
-  {
-    assert(false);
-    return false;
-  }
-
-  return true;
+  else assert(false);
 }
 
 //----- (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)
+void Vis::ODM_CreateIntersectFacesVertexCoordList(int *a, int *b, __int16 *intersect_face_vertex_coords_list_a, __int16 *intersect_face_vertex_coords_list_b, Vec3_short_ *IntersectPoint, BLVFace *pFace, 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
+  if (pFace->uAttributes & FACE_XY_PLANE)
+  {
+    *a = IntersectPoint->x;
+    *b = IntersectPoint->y;
+
+    for (int i = 0; i < pFace->uNumVertices; ++i)
+    {
+      intersect_face_vertex_coords_list_a[2 * i]     = pFace->pXInterceptDisplacements[i]     + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i]].x;
+      intersect_face_vertex_coords_list_a[i * 2 + 1] = pFace->pXInterceptDisplacements[i + 1] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i + 1]].x;
+
+      intersect_face_vertex_coords_list_b[2 * i]     = pFace->pYInterceptDisplacements[i]     + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i]].y;
+      intersect_face_vertex_coords_list_b[i * 2 + 1] = pFace->pYInterceptDisplacements[i + 1] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i + 1]].y;
+    }
+  }
+  else if (pFace->uAttributes & FACE_XZ_PLANE)
+  {
+    *a = IntersectPoint->x;
+    *b = IntersectPoint->z;
+
+    for (int i = 0; i < pFace->uNumVertices; ++i)
+    {
+      intersect_face_vertex_coords_list_a[2 * i]     = pFace->pXInterceptDisplacements[i]     + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i]].x;
+      intersect_face_vertex_coords_list_a[i * 2 + 1] = pFace->pXInterceptDisplacements[i + 1] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i + 1]].x;
 
-  //result = (bool)a6;
-  //v9 = pFace;
-  //v10 = pFace->uAttributes;
-  //a1a = 0;
-  if ( BYTE1(pFace->uAttributes) & 1 )
+      intersect_face_vertex_coords_list_b[2 * i]     = pFace->pZInterceptDisplacements[i]     + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i]].z;
+      intersect_face_vertex_coords_list_b[i * 2 + 1] = pFace->pZInterceptDisplacements[i + 1] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i + 1]].z;
+    }
+  }
+  else if (pFace->uAttributes & FACE_YZ_PLANE)
   {
-    pFace->pFacePlane.vNormal.x = a5->x;
-    pFace->pFacePlane.vNormal.y = a5->y;
-    if ( pFace->uNumVertices )
+      *a = IntersectPoint->y;
+      *b = IntersectPoint->z;
+
+    for (int i = 0; i < pFace->uNumVertices; ++i)
     {
-      //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;
-      }
+      intersect_face_vertex_coords_list_a[2 * i]     = pFace->pYInterceptDisplacements[i]     + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i]].y;
+      intersect_face_vertex_coords_list_a[i * 2 + 1] = pFace->pYInterceptDisplacements[i + 1] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i + 1]].y;
+
+      intersect_face_vertex_coords_list_b[2 * i]     = pFace->pZInterceptDisplacements[i]     + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i]].z;
+      intersect_face_vertex_coords_list_b[i * 2 + 1] = pFace->pZInterceptDisplacements[i + 1] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i + 1]].z;
     }
   }
+  else assert(false);
+}
+
+//----- (0046A0A1) --------------------------------------------------------
+int UnprojectX(int x)
+{
+  int v3; // [sp-4h] [bp-8h]@5
+
+  if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
+  {
+    if ( pRenderer->pRenderD3D )
+      v3 = pGame->pIndoorCameraD3D->fov;
+    else
+      v3 = pIndoorCamera->flt_1C_fov;
+  }
   else
   {
-    if ( BYTE1(pFace->uAttributes) & 2 )
-    {
-      pFace->pFacePlane.vNormal.x = a5->x;
-      pFace->pFacePlane.vNormal.z = a5->z;
-      if ( pFace->uNumVertices )
-      {
-        v15 = 188 * uModelID + 72;
-        a5b = 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[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;
-        }
-      }
-    }
+    v3 = pOutdoorCamera->int_fov_rad;
+  }
+  return stru_5C6E00->Atan2(x - pViewport->uScreenCenterX, v3) - stru_5C6E00->uIntegerHalfPi;
+}
+
+//----- (0046A0F6) --------------------------------------------------------
+int UnprojectY(int y)
+{
+  int v3; // [sp-4h] [bp-8h]@5
+
+  if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
+  {
+    if ( pRenderer->pRenderD3D )
+      v3 = pGame->pIndoorCameraD3D->fov;
     else
-    {
-      pFace->pFacePlane.vNormal.y = a5->y;
-      pFace->pFacePlane.vNormal.z = a5->z;
-      if ( pFace->uNumVertices )
-      {
-        v19 = 188 * uModelID + 72;
-        a5c = displaced_face_intersect_plane_coords_b + 1;
-        for ( uint i = 0; i < pFace->uNumVertices; ++i )
-        {
-          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;
-        }
-      }
-    }
+      v3 = pIndoorCamera->flt_1C_fov;
   }
-  return true;
+  else
+  {
+    v3 = pOutdoorCamera->int_fov_rad;
+  }
+  return stru_5C6E00->Atan2(y - pViewport->uScreenCenterY, v3) - stru_5C6E00->uIntegerHalfPi;
 }
 
 //----- (004C248E) --------------------------------------------------------
--- a/Vis.h	Thu May 23 21:36:57 2013 +0600
+++ b/Vis.h	Thu May 23 21:37:22 2013 +0600
@@ -111,9 +111,9 @@
   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 *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(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 CheckIntersectBModel(BLVFace *pFace, Vec3_short_ IntersectPoint, unsigned int uModelID);
+  void BLV_CreateIntersectFacesVertexCoordList(int *a, int *b, __int16 *intersect_face_vertex_coords_list_a, __int16 *intersect_face_vertex_coords_list_b, Vec3_short_ *IntersectPoint, BLVFace *pFace);
+  void ODM_CreateIntersectFacesVertexCoordList(int *a, int *b, __int16 *intersect_face_vertex_coords_list_a, __int16 *intersect_face_vertex_coords_list_b, Vec3_short_ *IntersectPoint, BLVFace *pFace, 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	Thu May 23 21:36:57 2013 +0600
+++ b/mm7_1.cpp	Thu May 23 21:37:22 2013 +0600
@@ -384,7 +384,7 @@
     v10 = pGlobalTXT_LocalizationStrings[57];   // Days
     if ( v19 <= 1 )
       v10 = pGlobalTXT_LocalizationStrings[56]; // Day
-    sprintf(pTmpBuf2, "%d %s ", v19, v10);
+    sprintfex(pTmpBuf2, "%d %s ", v19, v10);
     strcat(pTmpBuf, pTmpBuf2);
   }
   if ( v9 )
@@ -393,7 +393,7 @@
       v11 = pGlobalTXT_LocalizationStrings[109];// Hour
     else
       v11 = pGlobalTXT_LocalizationStrings[110];// Hours
-    sprintf(pTmpBuf2, "%d %s ", v9, v11);
+    sprintfex(pTmpBuf2, "%d %s ", v9, v11);
     strcat(pTmpBuf, pTmpBuf2);
   }
   if ( v17 && !v19 )
@@ -402,7 +402,7 @@
       v12 = pGlobalTXT_LocalizationStrings[437];// Minute
     else
       v12 = pGlobalTXT_LocalizationStrings[436];// Minutes
-    sprintf(pTmpBuf2, "%d %s ", v17, v12);
+    sprintfex(pTmpBuf2, "%d %s ", v17, v12);
     strcat(pTmpBuf, pTmpBuf2);
   }
   if ( v18 && !v9 )
@@ -411,7 +411,7 @@
       v13 = pGlobalTXT_LocalizationStrings[439];// Second
     else
       v13 = pGlobalTXT_LocalizationStrings[438];// Seconds
-    sprintf(pTmpBuf2, "%d %s ", v18, v13);
+    sprintfex(pTmpBuf2, "%d %s ", v18, v13);
     strcat(pTmpBuf, pTmpBuf2);
   }
   a1->DrawText(a2, 32, uY, 0, pTmpBuf, 0, 0, 0);
@@ -434,10 +434,10 @@
 {
   if ( _506F18_num_hours_to_sleep < 6 )
   {
-    pParty->pPlayers[3].pConditions[2] = 0i64;
-    pParty->pPlayers[2].pConditions[2] = 0i64;
-    pParty->pPlayers[1].pConditions[2] = 0i64;
-    pParty->pPlayers[0].pConditions[2] = 0i64;
+    pParty->pPlayers[3].SetAsleep(false);
+    pParty->pPlayers[2].SetAsleep(false);
+    pParty->pPlayers[1].SetAsleep(false);
+    pParty->pPlayers[0].SetAsleep(false);
     if ( _506F18_num_hours_to_sleep )
     {
       Rest(_506F18_num_hours_to_sleep);
@@ -484,6 +484,7 @@
   POINT v3; // [sp+0h] [bp-10h]@2
   POINT a2; // [sp+8h] [bp-8h]@1
 
+  __debugbreak(); // invalid indexing
   if ( pMouse->GetCursorPos(&a2)->y < 350 )
   {
     v0 = pMouse->GetCursorPos(&a2);
@@ -755,127 +756,6 @@
   return 1;
 }
 
-//----- (00421D00) --------------------------------------------------------
-void __fastcall GameUI_OnPlayerPortraitLeftClick(unsigned int uPlayerID)
-{
-  //unsigned int v1; // esi@1
-  //int v2; // eax@2
-  //Player *v3; // ecx@2
-  //Player *v4; // ecx@5
-  unsigned int v5; // [sp-4h] [bp-10h]@21
-
-  //v1 = uPlayerID;
-  auto player = &pParty->pPlayers[uPlayerID - 1];
-  if (pParty->pPickedItem.uItemID)
-  {
-    //v3 = player;
-    if (auto slot = player->AddItem(-1, pParty->pPickedItem.uItemID))
-    {
-      memcpy(&player->pInventoryItems[slot-1], &pParty->pPickedItem, 0x24u);
-      viewparams->bRedrawGameUI = true;
-      pMouse->RemoveHoldingItem();
-      return;
-    }
-
-    if (!player->CanAct())
-    {
-      player = pPlayers[uActiveCharacter];
-    }
-    if(player->CanAct() || !pPlayers[uActiveCharacter]->CanAct())
-		player->PlaySound(SPEECH_NoRoom, 0);
-  }
-
-//LABEL_9:
-  if (pCurrentScreen == SCREEN_GAME)
-  {
-    viewparams->bRedrawGameUI = true;
-    if ( uActiveCharacter != uPlayerID )
-      //goto LABEL_27;
-    {
-      if ( pPlayers[uPlayerID]->uTimeToRecovery )
-        return;
-
-      uActiveCharacter = uPlayerID;
-      return;
-    }
-    v5 = 7;
-//LABEL_22:
-    pGUIWindow_CurrentMenu = CharacterUI_Initialize(v5);
-    return;
-  }
-  if ( pCurrentScreen == SCREEN_SPELL_BOOK )
-    return;
-  if ( pCurrentScreen == SCREEN_CHEST )
-  {
-//LABEL_23:
-    viewparams->bRedrawGameUI = true;
-    if ( uActiveCharacter == uPlayerID )
-    {
-      pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] = 103;
-      pCurrentScreen = SCREEN_CHEST_INVENTORY;
-      //goto LABEL_28;
-      uActiveCharacter = uPlayerID;
-      return;
-    }
-//LABEL_27:
-    if ( pPlayers[uPlayerID]->uTimeToRecovery )
-      return;
-    //goto LABEL_28;
-    uActiveCharacter = uPlayerID;
-    return;
-  }
-  if ( pCurrentScreen != SCREEN_HOUSE )
-  {
-    if ( pCurrentScreen == SCREEN_E )
-    {
-//LABEL_28:
-      uActiveCharacter = uPlayerID;
-      return;
-    }
-    if ( pCurrentScreen != SCREEN_CHEST_INVENTORY )
-    {
-      viewparams->bRedrawGameUI = true;
-      uActiveCharacter = uPlayerID;
-      if ( pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] == 102 )
-        FillAwardsData();
-      return;
-    }
-    //goto LABEL_23;
-    viewparams->bRedrawGameUI = true;
-    if ( uActiveCharacter == uPlayerID )
-    {
-      pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] = 103;
-      pCurrentScreen = SCREEN_CHEST_INVENTORY;
-      //goto LABEL_28;
-      uActiveCharacter = uPlayerID;
-      return;
-    }
-//LABEL_27:
-    if ( pPlayers[uPlayerID]->uTimeToRecovery )
-      return;
-    //goto LABEL_28;
-    uActiveCharacter = uPlayerID;
-    return;
-  }
-  if ( window_SpeakInHouse->field_40 == 1 )
-    return;
-  viewparams->bRedrawGameUI = true;
-  if ( uActiveCharacter != uPlayerID )
-    //goto LABEL_28;
-    uActiveCharacter = uPlayerID;
-    return;
-  if (dialog_menu_id == HOUSE_DIALOGUE_SHOP_BUY_STANDARD || dialog_menu_id == HOUSE_DIALOGUE_SHOP_6)
-  {
-    __debugbreak(); // fix indexing
-    pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] = 103;
-    v5 = 14;
-    //goto LABEL_22;
-    pGUIWindow_CurrentMenu = CharacterUI_Initialize(v5);
-    return;
-  }
-}
-// 4E28F8: using guessed type int pCurrentScreen;
-// F8B19C: using guessed type int dword_F8B19C;
 
 //----- (00421EA6) --------------------------------------------------------
 void __cdecl OnInventoryLeftClick()
@@ -994,7 +874,7 @@
   unsigned __int16 v5; // dx@14
   signed int v6; // eax@14
   char *v7; // esi@15
-  int *v8; // eax@19
+  //int *v8; // eax@19
   int v9; // eax@19
   unsigned int v10; // eax@19
   int v11; // ecx@21
@@ -1011,25 +891,22 @@
   ItemGen *v22; // esi@62
   unsigned int v23; // eax@62
   SpriteObject a1; // [sp+Ch] [bp-80h]@1
-  POINT v25; // [sp+7Ch] [bp-10h]@3
+  //POINT v25; // [sp+7Ch] [bp-10h]@3
   POINT a2; // [sp+84h] [bp-8h]@3
 
   if ( pRenderer->pRenderD3D )
-  {
     v0 = pGame->pVisInstance->get_picked_object_zbuf_val();
-  }
   else
   {
     v1 = pMouse->GetCursorPos(&a2);
-    v0 = pRenderer->pActiveZBuffer[v1->x + pSRZBufferLineOffsets[pMouse->GetCursorPos(&v25)->y]];
+    v0 = pRenderer->pActiveZBuffer[v1->x + pSRZBufferLineOffsets[v1->y]];
   }
+
   if ( PID_TYPE(v0) == OBJECT_Item)
   {
     a2.y = (signed int)(unsigned __int16)v0 >> 3;
     v21 = (signed int)(unsigned __int16)v0 >> 3;
-    if ( !(pObjectList->pObjects[pSpriteObjects[v21].uObjectDescID].uFlags & 0x10)
-      && a2.y < 1000
-      && pSpriteObjects[v21].uObjectDescID
+    if ( !(pObjectList->pObjects[pSpriteObjects[v21].uObjectDescID].uFlags & 0x10) && a2.y < 1000 && pSpriteObjects[v21].uObjectDescID
       && (unsigned int)v0 < 0x2000000 )
     {
       v22 = &pSpriteObjects[v21].stru_24;
@@ -1113,9 +990,7 @@
 			v6 = 0;
 			a1.uType = v5;
 			if ( (signed int)pObjectList->uNumObjects <= 0 )
-			{
 				LOWORD(v6) = 0;
-			}
 			else
 			{
 				v7 = (char *)&pObjectList->pObjects->uObjectID;
@@ -1138,18 +1013,14 @@
 			a1.uSoundID = 0;
 			a1.uFacing = 0;
 			a1.uAttributes = 8;
-			a1.uSectorID = pIndoor->GetSector(
-								pParty->vPosition.x,
-								pParty->vPosition.y,
-								pParty->sEyelevel + pParty->vPosition.z);
+			a1.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->sEyelevel + pParty->vPosition.z);
 			a1.uSpriteFrameID = 0;
 			memcpy(&a1.stru_24, &pParty->pPickedItem, 0x24u);
-			v8 = (int *)pMouse->GetCursorPos(&v25);
-			v9 = UnprojectX(*v8);
+
+            extern int UnprojectX(int);
+			v9 = UnprojectX(v1->x);
 			a1.Create(pParty->sRotationY + v9, 184, 200, 0);
-			v10 = pIcons_LOD->LoadTexture(
-					pItemsTable->pItems[pParty->pPickedItem.uItemID].pIconName,
-					TEXTURE_16BIT_PALETTE);
+			v10 = pIcons_LOD->LoadTexture(pItemsTable->pItems[pParty->pPickedItem.uItemID].pIconName, TEXTURE_16BIT_PALETTE);
 			if (v10 != -1)
 				pIcons_LOD->pTextures[v10].Release();
 			pMouse->RemoveHoldingItem();
@@ -1526,6 +1397,10 @@
   uGameUIFontShadow = TargetColor(v5, v4, v6);
 }
 
+
+
+
+
 //----- (00423AEE) --------------------------------------------------------
 void __cdecl reset_some_strus_flt_2Cs()
 {
--- a/mm7_2.cpp	Thu May 23 21:36:57 2013 +0600
+++ b/mm7_2.cpp	Thu May 23 21:37:22 2013 +0600
@@ -802,7 +802,7 @@
 
   if ( pMessageQueue_50CBD0->uNumMessages )
     pMessageQueue_50CBD0->uNumMessages = pMessageQueue_50CBD0->pMessages[0].field_8 != 0;
-  pKeyActionMap->_459ED1(3);
+  pKeyActionMap->SetWindowInputStatus(3);
   pKeyActionMap->ResetKeys();
   activeLevelDecoration = NULL;
   current_npc_text = 0;
@@ -3820,33 +3820,31 @@
   MonsterDesc *v8; // edi@16
   unsigned __int16 v9; // ax@16
   int v10; // ebx@16
-  int v11; // edi@16
-  int v12; // eax@16
-  int v13; // ecx@16
-  int v14; // ebx@16
+  //int v11; // edi@16
+  //int v12; // eax@16
+  //int v13; // ecx@16
+  //int v14; // ebx@16
   const char *v15; // [sp-4h] [bp-24h]@2
-  unsigned __int16 v16; // [sp+0h] [bp-20h]@1
-  int v17; // [sp+4h] [bp-1Ch]@1
+  //unsigned __int16 v16; // [sp+0h] [bp-20h]@1
+  //int v17; // [sp+4h] [bp-1Ch]@1
   unsigned int uFaceID; // [sp+8h] [bp-18h]@16
   int v19; // [sp+Ch] [bp-14h]@16
   size_t v20; // [sp+10h] [bp-10h]@6
   int v21; // [sp+14h] [bp-Ch]@14
-  int v22; // [sp+18h] [bp-8h]@14
+  //int v22; // [sp+18h] [bp-8h]@14
   unsigned int v23; // [sp+1Ch] [bp-4h]@6
 
-  v16 = a2;
-  v17 = a1;
+  //v16 = a2;
+  //v17 = a1;
   if ( a2 == 4 )
   {
     v15 = "Elemental Light C";
   }
-  else
-  {
-    if ( a2 == 3 )
+  else if ( a2 == 3 )
       v15 = "Elemental Light B";
     else
       v15 = "Elemental Light A";
-  }
+
   v23 = pMonsterList->GetMonsterIDByName(v15);
   v3 = 0;
   v20 = uNumActors;
@@ -3855,7 +3853,7 @@
     v4 = pActors;//[0].uAIState;
     while ( v4->uAIState != Removed )
     {
-      ++v3;
+      ++v3; 
       ++v4;
       if ( v3 >= (signed int)uNumActors )
         break;
@@ -3866,7 +3864,7 @@
   if ( v20 != uNumActors || (result = uNumActors + 1, (signed int)(uNumActors + 1) < 500) )
   {
     v21 = 0;
-    v22 = pParty->vPosition.z;
+    //v22 = pParty->vPosition.z;
     if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
       v21 = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z);
     v6 = &pActors[v20];
@@ -3886,22 +3884,21 @@
     v6->pMonsterInfo.uExp = 0;
     v6->uMovementSpeed = v9;
     v10 = rand() % 2048;
-    v11 = ((unsigned __int64)(stru_5C6E00->Cos(v10) * (signed __int64)v19) >> 16) + pParty->vPosition.x;
+    //v11 = pParty->vPosition.x + fixpoint_sub0(stru_5C6E00->Cos(v10), v19);
     uFaceID = stru_5C6E00->Sin(v10);
-    v23 = (unsigned __int64)(uFaceID * (signed __int64)v19) >> 16;
-    v12 = pParty->vPosition.y;
-    v13 = (unsigned __int64)(uFaceID * (signed __int64)v19) >> 16;
-    v6->vInitialPosition.x = v11;
-    v14 = v13 + v12;
-    LOWORD(v12) = v22;
-    v6->vInitialPosition.z = v22;
-    v6->vPosition.z = v12;
-    LOWORD(v12) = v21;
-    v6->vPosition.x = v11;
-    v6->vInitialPosition.y = v14;
-    v6->vPosition.y = v14;
+    //v12 = pParty->vPosition.y;
+    //v13 = fixpoint_sub0(uFaceID, v19);
+    //v14 = pParty->vPosition.y + fixpoint_sub0(uFaceID, v19);
+    //LOWORD(v12) = v22;
+    v6->vInitialPosition.x = pParty->vPosition.x + fixpoint_sub0(stru_5C6E00->Cos(v10), v19);
+    v6->vPosition.x = v6->vInitialPosition.x;
+    v6->vInitialPosition.y = pParty->vPosition.y + fixpoint_sub0(uFaceID, v19);
+    v6->vPosition.y = v6->vInitialPosition.y;
+    v6->vInitialPosition.z = pParty->vPosition.z;
+    v6->vPosition.z = v6->vInitialPosition.z;
+    //LOWORD(v12) = v21;
     v6->uTetherDistance = 256;
-    v6->uSectorID = v12;
+    v6->uSectorID = v21;
     v6->PrepareSprites(0);
     v6->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly;
     v6->uAlly = 9999;
@@ -3911,19 +3908,17 @@
     v6->uCurrentActionLength = 256;
     v6->UpdateAnimation();
     if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor
-      || (v22 = pParty->vPosition.z,
-          result = pIndoor->GetSector(v11, v14, pParty->vPosition.z),
+      || (result = pIndoor->GetSector(v6->vPosition.x, v6->vPosition.y, v6->vPosition.z),
           result == v21)
-      && (result = BLV_GetFloorLevel(v11, v14, v22, result, &uFaceID), result != -30000)
-      && (result = abs(result - v22), result <= 1024) )
+      && (result = BLV_GetFloorLevel(v6->vPosition.x, v6->vPosition.y, v6->vPosition.z, result, &uFaceID), result != -30000)
+      && (result = abs(result - pParty->vPosition.z), result <= 1024) )
     {
       if ( v20 == uNumActors )
         ++uNumActors;
-      v6->uSummonerID = PID(OBJECT_Player,v17);
-      result = v6->pActorBuffs[2].Apply(
-                 pParty->uTimePlayed + (signed __int64)((double)(a3 << 7) * 0.033333335),
-                 v16,
-                 v17,
+      v6->uSummonerID = PID(OBJECT_Player, a1);
+      result = v6->pActorBuffs[2].Apply(pParty->uTimePlayed + (a3 * 128) / 30.0f,
+                 a2,
+                 a1,
                  0,
                  0);
     }
@@ -6634,10 +6629,7 @@
   GUIWindow *pWindow; // [sp+4h] [bp-38h]@11
   
   pCurrentScreen = SCREEN_GAME;
-  if (pAsyncMouse)
-    pAsyncMouse->Resume();
-  if ( LOBYTE(pGame->pKeyboardInstance->bUsingAsynKeyboard) && pAsyncKeyboard )
-    pAsyncKeyboard->Resume();
+
   pGUIWindow2 = 0;
   pAudioPlayer->StopChannels(-1, -1);
   pMouse->RemoveHoldingItem();
@@ -6694,12 +6686,10 @@
     {
       pRenderer->BeginScene();
       pRenderer->DrawTextureRGB(0, 0, &pTexture_PCX);
-      if (pAsyncMouse)
-        pAsyncMouse->_46B736_consume_click_lists(1);
+
       GUI_MainMenuMessageProc();
       GUI_UpdateWindows();
-      if (pAsyncMouse)
-        pAsyncMouse->_46B736_consume_click_lists(1);
+
       if (GetCurrentMenuID() != MENU_MAIN)
       {
         if (GetCurrentMenuID() == MENU_LoadingProcInMainMenu)
@@ -7016,8 +7006,6 @@
       case WM_LBUTTONDOWN:
         if ( pArcomageGame->bGameInProgress )
         {
-          if (pAsyncMouse)
-            return DefWindowProcA(hWnd, Msg, wParam, lParam);
           pArcomageGame->stru1.field_0 = 7;
           ArcomageGame::OnMouseClick(0, 1);
           return DefWindowProcA(hWnd, Msg, wParam, lParam);
@@ -7031,27 +7019,19 @@
         {
           if ( pVideoPlayer->pVideoFrame.pPixels != (unsigned __int16 *)v31 )
             pVideoPlayer->bStopBeforeSchedule = 1;
-          if (!pAsyncMouse)
-            pMouse->SetMouseClick((unsigned __int16)lParam, lParam >> 16);
+
+          pMouse->SetMouseClick((unsigned __int16)lParam, lParam >> 16);
           if (pGame)
           {
-            if (pAsyncMouse)
-              //goto _def_wnd_proc;
-              return DefWindowProcA(hWnd, Msg, wParam, lParam);
             v33 = pGame->pIndoorCameraD3D->GetPickDepth();
             pGame->PickMouse(v33, (unsigned __int16)lParam, lParam >> 16, v31, &vis_sprite_filter_2, &vis_door_filter);
           }
-          if (!pAsyncMouse)
-          {
+
             sub_416D62_ShowPopupWindow_MonsterRecord_ItemInfo_etcsub_416D62(0);
             return DefWindowProcA(hWnd, Msg, wParam, lParam);
-          }
-          //goto _def_wnd_proc;
-          return DefWindowProcA(hWnd, Msg, wParam, lParam);
-        }
-        if (pAsyncMouse)
-          //goto _def_wnd_proc;
-          return DefWindowProcA(hWnd, Msg, wParam, lParam);
+
+        }
+
         pArcomageGame->stru1.field_0 = 8;
         ArcomageGame::OnMouseClick(1, 1);
         return DefWindowProcA(hWnd, Msg, wParam, lParam);
@@ -7060,14 +7040,9 @@
         if ( !pArcomageGame->bGameInProgress )
           //goto LABEL_218;
         {
-          if ( pAsyncMouse != v32 )
-            return DefWindowProcA(hWnd, Msg, wParam, lParam);
           back_to_game();
           return DefWindowProcA(hWnd, Msg, wParam, lParam);
         }
-        if (pAsyncMouse)
-          //goto _def_wnd_proc;
-          return DefWindowProcA(hWnd, Msg, wParam, lParam);
         pArcomageGame->stru1.field_0 = 3;
         ArcomageGame::OnMouseClick(0, 0);
         return DefWindowProcA(hWnd, Msg, wParam, lParam);
@@ -7076,15 +7051,10 @@
         if ( !pArcomageGame->bGameInProgress )
         {
 //LABEL_218:
-          if ( pAsyncMouse != v32 )
-            //goto _def_wnd_proc;
-            return DefWindowProcA(hWnd, Msg, wParam, lParam);
+
           back_to_game();
           return DefWindowProcA(hWnd, Msg, wParam, lParam);
         }
-        if (pAsyncMouse)
-          //goto _def_wnd_proc;
-          return DefWindowProcA(hWnd, Msg, wParam, lParam);
         pArcomageGame->stru1.field_0 = 4;
         v29 = 0;
         //goto LABEL_262;
@@ -7095,9 +7065,6 @@
       case WM_LBUTTONDBLCLK:
         if ( pArcomageGame->bGameInProgress )
         {
-          if (pAsyncMouse)
-            //goto _def_wnd_proc;
-            return DefWindowProcA(hWnd, Msg, wParam, lParam);
           pArcomageGame->stru1.field_0 = 7;
           return DefWindowProcA(hWnd, Msg, wParam, lParam);
         }
@@ -7106,7 +7073,6 @@
         if ( pVideoPlayer->pVideoFrame.pPixels )
           pVideoPlayer->bStopBeforeSchedule = 1;
 
-        if ( !pAsyncMouse )
           pMouse->SetMouseClick((unsigned __int16)lParam, lParam >> 16);
 
         if (GetCurrentMenuID() != MENU_CREATEPARTY)
@@ -7117,13 +7083,12 @@
           pMouse->SetMouseClick((unsigned __int16)lParam, lParam >> 16);
         }
 
-        if (!pAsyncMouse)
-        {
+
           if (pGame)
             pGame->PickMouse(512.0, (unsigned __int16)lParam, lParam >> 16, false, &vis_sprite_filter_3, &vis_door_filter);
 
           UI_OnMouseLeftClick(0);
-        }
+
         return DefWindowProcA(hWnd, Msg, wParam, lParam);
 
       case WM_RBUTTONDBLCLK:
@@ -7133,40 +7098,29 @@
 //LABEL_240:
           if ( pVideoPlayer->pVideoFrame.pPixels != (unsigned __int16 *)v31 )
             pVideoPlayer->bStopBeforeSchedule = 1;
-          if (!pAsyncMouse)
+
             pMouse->SetMouseClick((unsigned __int16)lParam, lParam >> 16);
           if (pGame)
           {
-            if (pAsyncMouse)
-              //goto _def_wnd_proc;
-              return DefWindowProcA(hWnd, Msg, wParam, lParam);
             v33 = pGame->pIndoorCameraD3D->GetPickDepth();
             pGame->PickMouse(v33, (unsigned __int16)lParam, lParam >> 16, v31, &vis_sprite_filter_2, &vis_door_filter);
           }
-          if (!pAsyncMouse)
-          {
+
             sub_416D62_ShowPopupWindow_MonsterRecord_ItemInfo_etcsub_416D62(0);
             return DefWindowProcA(hWnd, Msg, wParam, lParam);
-          }
-          //goto _def_wnd_proc;
-          return DefWindowProcA(hWnd, Msg, wParam, lParam);
-        }
-        if (pAsyncMouse)
-          //goto _def_wnd_proc;
-          return DefWindowProcA(hWnd, Msg, wParam, lParam);
+
+        }
         pArcomageGame->stru1.field_0 = 8;
         return DefWindowProcA(hWnd, Msg, wParam, lParam);
       case WM_MBUTTONDOWN:
         if ( pRenderer->pRenderD3D )
         {
-          if ( pGame && !pAsyncMouse )
+          if ( pGame )
           {
             v34 = pGame->pIndoorCameraD3D->GetPickDepth();
             pGame->PickMouse(v34, (unsigned __int16)lParam, lParam >> 16, 1, &vis_sprite_filter_3, &vis_face_filter);
             return DefWindowProcA(hWnd, Msg, wParam, lParam);
           }
-          //goto _def_wnd_proc;
-          return DefWindowProcA(hWnd, Msg, wParam, lParam);
         }
         if ( !pGame )
           //goto _def_wnd_proc;
@@ -7176,9 +7130,6 @@
       case WM_MOUSEMOVE:
         if ( pArcomageGame->bGameInProgress )
         {
-          if (pAsyncMouse)
-            //goto _def_wnd_proc;
-            return DefWindowProcA(hWnd, Msg, wParam, lParam);
           pXY[0] = (unsigned __int16)lParam;
           pXY[1] = lParam >> 16;
           ArcomageGame::OnMouseMove((POINT *)pXY);
@@ -7188,9 +7139,6 @@
         }
         else
         {
-          if (pAsyncMouse)
-            //goto _def_wnd_proc;
-            return DefWindowProcA(hWnd, Msg, wParam, lParam);
           pMouse->SetMouseClick((unsigned __int16)lParam, lParam >> 16);
         }
         return DefWindowProcA(hWnd, Msg, wParam, lParam);
@@ -7254,14 +7202,6 @@
         if ( wParam == VK_ESCAPE )
         {
           pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, window_SpeakInHouse != 0, 0);
-          /*if ( (signed int)pMessageQueue_50CBD0->uNumMessages < 40 )
-          {
-            v12 = window_SpeakInHouse == 0;
-            pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].eType = UIMSG_Escape;
-            pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = !v12;
-            *(&pMessageQueue_50CBD0->uNumMessages + 3 * pMessageQueue_50CBD0->uNumMessages + 3) = 0;
-            ++pMessageQueue_50CBD0->uNumMessages;
-          }*/
           return 0;
         }
         if ( wParam <= VK_HOME )
@@ -7278,7 +7218,7 @@
           SendMessageA(hWnd, WM_COMMAND, v37, v38);
           return 0;
         }
-        if ( pCurrentScreen
+        if ( pCurrentScreen != SCREEN_GAME
           && pCurrentScreen != SCREEN_PRESS_ESCAPE_MESSAGE )
           return 0;
       }
@@ -7930,8 +7870,7 @@
             Abortf(pGlobalTXT_LocalizationStrings[62]);
         }
         BYTE1(dword_6BE364_game_settings_1) &= 0xFEu;
-        if (pAsyncMouse)
-          pAsyncMouse->Resume();
+
         if ( pArcomageGame->bGameInProgress )
         {
           pArcomageGame->field_F9 = 1;
@@ -7946,9 +7885,8 @@
             BYTE1(dword_6BE364_game_settings_1) &= 0xFBu;
           else
             pMiscTimer->Resume();
-          if ( LOBYTE(pGame->pKeyboardInstance->bUsingAsynKeyboard) && pAsyncKeyboard )
-            pAsyncKeyboard->Resume();
-          viewparams->bRedrawGameUI = 1;
+
+          viewparams->bRedrawGameUI = true;
           if ( pVideoPlayer->pSmackerMovie )
           {
             pRenderer->RestoreFrontBuffer();
@@ -7968,8 +7906,7 @@
           dword_4E98BC_bApplicationActive = 0;
         if ( (pVideoPlayer->pSmackerMovie || pVideoPlayer->pBinkMovie) && pVideoPlayer->bPlayingMovie )
           pVideoPlayer->bStopBeforeSchedule = 1;
-        if (pAsyncMouse)
-          pAsyncMouse->Suspend();
+
         if ( pRenderer->bUserDirect3D && pRenderer->uAcquiredDirect3DDevice == 1 )
           SetWindowPos(::hWnd, (HWND)0xFFFFFFFE, 0, 0, 0, 0, 0x18u);
         ClipCursor(0);
@@ -7982,8 +7919,7 @@
           BYTE1(dword_6BE364_game_settings_1) |= 4u;
         else
           pMiscTimer->Pause();
-        if ( pGame && LOBYTE(pGame->pKeyboardInstance->bUsingAsynKeyboard) && pAsyncKeyboard )
-          pAsyncKeyboard->Suspend();
+
         pAudioPlayer->StopChannels(-1, -1);
         if ( pAudioPlayer->hAILRedbook )
           AIL_redbook_pause(pAudioPlayer->hAILRedbook);
@@ -8011,15 +7947,9 @@
     SetPriorityClass(v6, 0x20u);
     if ( pGame )
     {
-      v7 = pGame->pKeyboardInstance;
-      if ( v7 )
-      {
-        if ( LOBYTE(v7->bUsingAsynKeyboard) && pAsyncKeyboard )
-          pAsyncKeyboard->_45B3A4();
-      }
-    }
-    if (pAsyncMouse)
-      pAsyncMouse->_46B1DD();
+
+    }
+
     PostQuitMessage(0);
     return 0;
   }
@@ -8031,11 +7961,7 @@
       if ( pRenderer->bUserDirect3D && pRenderer->uAcquiredDirect3DDevice == 1 )
         SetWindowPos(::hWnd, (HWND)0xFFFFFFFE, 0, 0, 0, 0, 0x18u);
       ClipCursor(0);
-      if (pAsyncMouse)
-      {
-        pAsyncMouse->Suspend();
-        return DefWindowProcA(hWnd, Msg, wParam, lParam);
-      }
+
     }
 //_def_wnd_proc:
     return DefWindowProcA(hWnd, Msg, wParam, lParam);
@@ -8070,14 +7996,9 @@
     //goto _def_wnd_proc;
     return DefWindowProcA(hWnd, Msg, wParam, lParam);
   }
-  if ( ::hWnd != (HWND)wParam || (dword_4E98BC_bApplicationActive = 1, pRenderer->bWindowMode) || !pAsyncMouse )
+  if ( ::hWnd != (HWND)wParam || (dword_4E98BC_bApplicationActive = 1, pRenderer->bWindowMode) || true )
     return DefWindowProcA(hWnd, Msg, wParam, lParam);
-  pAsyncMouse->Resume();
-  if ( !pAsyncMouse )
-    //goto _def_wnd_proc;
-    return DefWindowProcA(hWnd, Msg, wParam, lParam);
-  pAsyncMouse->Clip();
-  return DefWindowProcA(hWnd, Msg, wParam, lParam);
+
 }
 
 //----- (00464479) --------------------------------------------------------
@@ -9073,8 +8994,6 @@
     SetMenu(hWnd, 0);
     SetWindowLongA(hWnd, GWL_EXSTYLE, 0);
     SetWindowLongA(hWnd, GWL_STYLE, WS_VISIBLE);
-    if (pAsyncMouse)
-      pAsyncMouse->Clip();
     pRenderer->InitializeFullscreen(hWnd);
   }
   else
@@ -9155,8 +9074,6 @@
   char pContainer[32]; // [sp+10h] [bp-Ch]@9
 
   pMouse->Initialize(hWnd);
-  CreateAsyncMouse();
-  CreateAsyncKeyboard();
 
   pItemsTable = new ItemsTable;
   pItemsTable->Initialize();
@@ -9243,7 +9160,7 @@
     }
 
   Initialize_GamesLOD_NewLOD();
-  dword_576E2C = 512;
+  _576E2C_current_minimap_zoom = 512;
   dword_576E28 = 9;
 }
 
@@ -9392,7 +9309,7 @@
   char test[1024];
   sprintfex(test, "^Pi[%s]: ^R[;;]", "");
 
-
+  bool bNoMargareth = false;
   if (pCmdLine && *pCmdLine)
   {
     if (wcsstr(pCmdLine, L"-usedefs"))
@@ -9419,6 +9336,8 @@
       bNoCD = true;
     if (wcsstr(pCmdLine, L"-new_sky"))
       new_sky = true;
+    if (wcsstr(pCmdLine, L"-nomarg"))
+      bNoMargareth = true;
   }
 
 
@@ -9494,6 +9413,9 @@
           bFlashQuestBook = true;
           pGame->pCShow->PlayMovie(MOVIE_Emerald, 0);
           SaveNewGame();
+
+          if (bNoMargareth)
+            _449B7E_toggle_bit(pParty->_quest_bits, PARTY_QUEST_EMERALD_MARGARETH_OFF, 1);
           pGame->Loop();
 
           if (uGameState == GAME_STATE_NEWGAME_OUT_GAMEMENU)
@@ -9523,10 +9445,7 @@
           if (GetCurrentMenuID() != MENU_10)
             goto LABEL_49;
           pMouse->Activate(0);
-          if (pAsyncMouse)
-            pAsyncMouse->Suspend();
-          if ( LOBYTE(pGame->pKeyboardInstance->bUsingAsynKeyboard) && pAsyncKeyboard )
-            pAsyncKeyboard->Suspend();
+
           pParty->Reset();
           pParty->CreateDefaultParty(1);
           crt_init_globals_46271C();
@@ -9534,19 +9453,12 @@
           if ( !GetOpenFileNameA((LPOPENFILENAMEA)&ofn) )
           {
             pMouse->Activate(1);
-            if (pAsyncMouse)
-              pAsyncMouse->Resume();
-            if ( LOBYTE(pGame->pKeyboardInstance->bUsingAsynKeyboard) && pAsyncKeyboard )
-              pAsyncKeyboard->Resume();
+
             break;
           }
           _chdir("..\\");
           strcpy(pCurrentMapName, ofn.lpstrFileTitle);
           pMouse->Activate(1);
-          if (pAsyncMouse)
-            pAsyncMouse->Resume();
-          if ( LOBYTE(pGame->pKeyboardInstance->bUsingAsynKeyboard) && pAsyncKeyboard )
-            pAsyncKeyboard->Resume();
         }
 //LABEL_48:
         pGame->Loop();
@@ -9591,35 +9503,6 @@
 }
 // 507BF0: using guessed type int dword_507BF0_is_there_popup_onscreen;
 
-//----- (00465F5A) --------------------------------------------------------
-void __cdecl CreateAsyncMouse()
-{
-  LOG_DECOMPILATION_WARNING();
-  /*
-  if (!pAsyncMouse &&
-      pRenderer->bUserDirect3D &&
-      pRenderer->uAcquiredDirect3DDevice == 1)
-  {
-    pAsyncMouse = new AsyncMouse(&pRenderer->pDirectDraw4);
-    if (pAsyncMouse)
-      pAsyncMouse->Resume();
-  }*/
-}
-
-//----- (00465FF0) --------------------------------------------------------
-void __cdecl CreateAsyncKeyboard()
-{
-  LOG_DECOMPILATION_WARNING();
-  /*
-  if (!pAsyncKeyboard &&
-      pGame->pKeyboardInstance->bUsingAsynKeyboard)
-  {
-    pAsyncKeyboard = new AsyncKeyboard;
-    if (pAsyncKeyboard)
-      pAsyncKeyboard->Resume();
-  }*/
-}
-
 //----- (00466082) --------------------------------------------------------
 void MM6_Initialize(const wchar_t *pIniFilename)
 {
@@ -9862,11 +9745,6 @@
 };
 void SetCurrentMenuID(MENU_STATE uMenu)
 {
-  if ((int)uCurrentMenuID != -1)
-  {
-    if (pGame->pKeyboardInstance->bUsingAsynKeyboard && pAsyncKeyboard)
-      pAsyncKeyboard->Resume();
-  }
   uCurrentMenuID = uMenu;
 
   Log::Warning(L"CurrentMenu = %s", MENU_STATE_to_string(uMenu));
@@ -9878,33 +9756,60 @@
   return uCurrentMenuID;
 }
 
-//----- (00467D5D) --------------------------------------------------------
-int __thiscall sub_467D5D(int _this)
-{
-  return *(int *)(_this + 7204);
-}
 
 //----- (00467E7F) --------------------------------------------------------
-void __thiscall sub_467E7F_EquipBody(unsigned int uEquipType)
-{
-  unsigned int v1; // esi@1
+void sub_467E7F_EquipBody(ITEM_EQUIP_TYPE uEquipType)
+{
+  //unsigned int v1; // esi@1
   int v2; // ebx@1
   Player *v3; // eax@1
   int v4; // edx@1
   int v5; // esi@2
-  int v6; // eax@2
+  //int v6; // eax@2
   unsigned int v7; // eax@3
   ItemGen _this; // [sp+Ch] [bp-30h]@1
-  Player *v9; // [sp+30h] [bp-Ch]@1
+  //Player *v9; // [sp+30h] [bp-Ch]@1
   int v10; // [sp+34h] [bp-8h]@1
   int *v11; // [sp+38h] [bp-4h]@1
 
-  v1 = uEquipType;
+  static unsigned char byte_4E8398[200] = // 4E8398
+  {
+     1, // EQUIP_OFF_HAND
+     1, // EQUIP_MAIN_HAND
+     2, // EQUIP_BOW
+     3, // EQUIP_ARMOUR
+     0, // EQUIP_SHIELD
+     4, // EQUIP_HELMET
+     5, // EQUIP_BELT
+     6, // EQUIP_CLOAK
+     7, // EQUIP_GAUNTLETS
+     8, // EQUIP_BOOTS
+    10, // EQUIP_RING
+     9, // EQUIP_AMULET
+     1, // EQUIP_WAND
+     0, // EQUIP_REAGENT
+     0, // EQUIP_POTION
+     0, // EQUIP_SPELL_SCROLL
+     0, // EQUIP_BOOK
+     0, // EQUIP_MESSAGE_SCROLL
+     0, // EQUIP_GOLD
+     0, // EQUIP_GEM
+     0, // EQUIP_NONE
+  // ???
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+     0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0,  0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0,
+     0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0,  0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,  1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0,  0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 3, 3, 3, 3, 3, 3, 1, 1, 1,
+     1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2,  2, 0, 0, 0, 0, 0
+};
+
   _this.Reset();
-  v2 = (unsigned __int8)byte_4E8394[v1 + 4];
+  v2 = byte_4E8398[uEquipType];
   v3 = pPlayers[uActiveCharacter];
-  v9 = v3;
-  v11 = (int *)((char *)&v3->pEquipment + 4 * v2);
+  v11 = (int *)&v3->pEquipment.pIndices[v2];
   v4 = *v11;
   v10 = *v11;
   if ( v10 )
@@ -9914,18 +9819,17 @@
     *(char *)(v5 + 556) = 0;
     pParty->pPickedItem.Reset();
     pParty->SetHoldingItem((ItemGen *)(v5 + 532));
-    v6 = v10;
     _this.uBodyAnchor = v2 + 1;
     memcpy((void *)(v5 + 532), &_this, 0x24u);
-    *v11 = v6;
+    *v11 = v10;
   }
   else
   {
     v7 = v3->FindFreeInventorySlot();
-    if ( (v7 & 0x80000000u) == 0 )
+    if (v7 >= 0)
     {
       pParty->pPickedItem.uBodyAnchor = v2 + 1;
-      memcpy(&v9->pInventoryItems[v7], &pParty->pPickedItem, sizeof(v9->pInventoryItems[v7]));
+      memcpy(&v3->pInventoryItems[v7], &pParty->pPickedItem, sizeof(v3->pInventoryItems[v7]));
       *v11 = v7 + 1;
       pMouse->RemoveHoldingItem();
     }
@@ -10105,7 +10009,7 @@
     }
     if ( pParty->pPickedItem.uItemID == 604 )
     {
-      sub_467E7F_EquipBody(3);
+      sub_467E7F_EquipBody((ITEM_EQUIP_TYPE)3);
       WetsuitOn(uActiveCharacter);
       return;
     }
@@ -10130,7 +10034,7 @@
 			pAudioPlayer->PlaySound(SOUND_27, 0, 0, -1, 0, 0, 0, 0);
 			return;
 		}
-        sub_467E7F_EquipBody(v6);
+        sub_467E7F_EquipBody((ITEM_EQUIP_TYPE)v6);
         if ( pParty->pPickedItem.uItemID == 604 )
           WetsuitOff(uActiveCharacter);
         return;
@@ -10247,16 +10151,10 @@
         if ( pSkillType == 2 && (unsigned __int16)(pPlayers[uActiveCharacter]->pActiveSkills[2] & 0xFFC0)
           || pSkillType == 1 && (signed int)SkillToMastery(pPlayers[uActiveCharacter]->pActiveSkills[1]) >= 3 )
         {
-          if (pAsyncMouse)
-          {
-            v18 = *((int *)pAsyncMouse + 6);
-            v19 = *((int *)pAsyncMouse + 7);
-          }
-          else
-          {
+
             v18 = pMouse->uMouseClickX;
             v19 = pMouse->uMouseClickY;
-          }
+
           v49 = v19;
           if ( (signed int)v18 >= 560 )
           {
@@ -10413,18 +10311,10 @@
     }
     return;
   }
-  if (pAsyncMouse)
-  {
-    v32 = *((int *)pAsyncMouse + 6);
-    v33 = *((int *)pAsyncMouse + 7);
-    v49 = *((int *)pAsyncMouse + 7);
-    v48 = v32;
-  }
-  else
-  {
+
     v32 = pMouse->uMouseClickX;
     v33 = pMouse->uMouseClickY;
-  }
+
   v34 = pRenderer->pActiveZBuffer[v32 + pSRZBufferLineOffsets[v33]] & 0xFFFF;
   if ( v34 )
   {
@@ -10482,47 +10372,6 @@
   }
 }
 
-//----- (0046A0A1) --------------------------------------------------------
-int __thiscall UnprojectX(int x)
-{
-  double v1; // st7@3
-  int v3; // [sp-4h] [bp-8h]@5
-
-  if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
-  {
-    if ( pRenderer->pRenderD3D )
-      v1 = pGame->pIndoorCameraD3D->fov;
-    else
-      v1 = pIndoorCamera->flt_1C_fov;
-    v3 = (signed __int64)v1;
-  }
-  else
-  {
-    v3 = pOutdoorCamera->int_fov_rad;
-  }
-  return stru_5C6E00->Atan2(x - pViewport->uScreenCenterX, v3) - stru_5C6E00->uIntegerHalfPi;
-}
-
-//----- (0046A0F6) --------------------------------------------------------
-int __thiscall UnprojectY(int _this)
-{
-  double v1; // st7@3
-  int v3; // [sp-4h] [bp-8h]@5
-
-  if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
-  {
-    if ( pRenderer->pRenderD3D )
-      v1 = pGame->pIndoorCameraD3D->fov;
-    else
-      v1 = pIndoorCamera->flt_1C_fov;
-    v3 = (signed __int64)v1;
-  }
-  else
-  {
-    v3 = pOutdoorCamera->int_fov_rad;
-  }
-  return stru_5C6E00->Atan2(_this - pViewport->uScreenCenterY, v3) - stru_5C6E00->uIntegerHalfPi;
-}
 
 //----- (0046A14B) --------------------------------------------------------
 void OnPressSpace()
@@ -10556,7 +10405,14 @@
     auto pid = pGame->pVisInstance->get_picked_object_zbuf_val();
     if ( pid != -1 )
       DoInteractionWithTopmostZObject(pid & 0xFFFF, PID_ID(pid));
-  }
+    return;
+  }
+
+  
+  // software render stuff following
+
+  static int dword_720660[100]; // 720660
+  static int dword_7207F0[100]; // 7207F0
 
   v22 = 0;
   v1 = (int *)((signed int)(viewparams->uScreen_BttmR_X + viewparams->uScreen_topL_X) >> 1);//wrong pointer
@@ -10602,8 +10458,8 @@
 					++v22;
 					++v4;
 					v8 = *v21;
-					dword_7207EC[v4] = v7;
-					dword_72065C[v4] = v8;
+					dword_7207F0[v4 - 1] = v7;
+					dword_720660[v4 - 1] = v8;
 				  }
 			  }
 			  else if ( (unsigned int)*v21 <= 0x2000000 )
@@ -10613,8 +10469,8 @@
 					++v22;
 					++v4;
 					v8 = *v21;
-					dword_7207EC[v4] = v7;
-					dword_72065C[v4] = v8;
+					dword_7207F0[v4 - 1] = v7;
+					dword_720660[v4 - 1] = v8;
 				  }
 			  }
 			  v1 = v21 + 2;
@@ -10744,13 +10600,6 @@
           if ( v13->sNPC_ID )
           {
             pMessageQueue_50CBD0->AddMessage(UIMSG_StartNPCDialogue, v12, 0);
-            /*if ( (signed int)pMessageQueue_50CBD0->uNumMessages < 40 )
-            {
-              pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].eType = UIMSG_StartNPCDialogue;
-              pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = v12;
-              *(&pMessageQueue_50CBD0->uNumMessages + 3 * pMessageQueue_50CBD0->uNumMessages + 3) = 0;
-              ++pMessageQueue_50CBD0->uNumMessages;
-            }*/
           }
           else
           {
@@ -10947,15 +10796,15 @@
           v6 = PID_ID(v5);
           v7 = v6;
           v8 = pActors[v6].uAIState;
-          if ( v8 != 5 )
-          {
-            if ( v8 != 4 )
-            {
-              if ( v8 != 11 )
+          if ( v8 != Dead )
+          {
+            if ( v8 != Dying )
+            {
+              if ( v8 != Removed )
               {
-                if ( v8 != 19 )
+                if ( v8 != Disabled )
                 {
-                  if ( v8 != 17 )
+                  if ( v8 != Summoned )
                   {
                     v9 = (double)a3;
                     if ( pGame->pVisInstance->DoesRayIntersectBillboard(v9, a1a) )
--- a/mm7_3.cpp	Thu May 23 21:36:57 2013 +0600
+++ b/mm7_3.cpp	Thu May 23 21:37:22 2013 +0600
@@ -1662,8 +1662,8 @@
       auto player = pParty->pPlayers + i;
       if (!player->HasEnchantedItemEquipped(72) && !player->WearsItem(ITEM_ARTIFACT_HERMES_SANDALS, 8))
       {
-        player->ReceiveDamage((pParty->uFallStartY - party_z) * (0.1f * player->GetMaxHealth()) / 256, 4);
-        v10 = (double)(20 - player->_48EA1B_get_static_effect(player->GetActualEndurance())) * flt_6BE3A4_debug_recmod1 * 2.133333333333333;
+        player->ReceiveDamage((pParty->uFallStartY - party_z) * (0.1f * player->GetMaxHealth()) / 256, DMGT_PHISYCAL);
+        v10 = (double)(20 - player->GetParameterBonus(player->GetActualEndurance())) * flt_6BE3A4_debug_recmod1 * 2.133333333333333;
         player->SetRecoveryTime((signed __int64)v10);
       }
     }
@@ -2301,8 +2301,8 @@
       {
         player->ReceiveDamage(
             (signed int)((pParty->uFallStartY - pZ) * (unsigned __int64)(player->GetMaxHealth() / 10)) / 256,
-            4);
-        v105 = 20 - player->_48EA1B_get_static_effect(player->GetActualEndurance());
+            DMGT_PHISYCAL);
+        v105 = 20 - player->GetParameterBonus(player->GetActualEndurance());
         player->SetRecoveryTime((signed __int64)((double)v105 * flt_6BE3A4_debug_recmod1 * 2.133333333333333));
       }
       //}
@@ -3081,9 +3081,9 @@
               v110 = (*v74)->GetMaxHealth();
               (*v74)->ReceiveDamage(
                 (signed int)((pParty->uFallStartY - v70) * (unsigned __int64)(signed __int64)((double)v110 * 0.1)) / 256,
-                4);
+                DMGT_PHISYCAL);
               v75 = (*v74)->GetActualEndurance();
-              v110 = 20 - (*v74)->_48EA1B_get_static_effect(v75);
+              v110 = 20 - (*v74)->GetParameterBonus(v75);
               (*v74)->SetRecoveryTime(
                 (signed __int64)((double)v110 * flt_6BE3A4_debug_recmod1 * 2.133333333333333));
               ++v74;
@@ -3203,9 +3203,9 @@
             v110 = (*v84)->GetMaxHealth();
             (*v84)->ReceiveDamage(
               (signed int)((pParty->uFallStartY - v81) * (unsigned __int64)(signed __int64)((double)v110 * 0.1)) / 256,
-              4);
+              DMGT_PHISYCAL);
             v85 = (*v84)->GetActualEndurance();
-            v110 = 20 - (*v84)->_48EA1B_get_static_effect(v85);
+            v110 = 20 - (*v84)->GetParameterBonus(v85);
             (*v84)->SetRecoveryTime((signed __int64)((double)v110 * flt_6BE3A4_debug_recmod1 * 2.133333333333333));
             ++v84;
           }
@@ -11855,11 +11855,9 @@
     for (uint i = 0; i < uLevelEVT_NumEvents; ++i)
     {
 		test_event=(_evt_raw*)&pLevelEVT[pLevelEVT_Index[i].uEventOffsetInEVT];
-      if ( test_event->_e_type== EVENT_OnMapLeave )
-      {
-        start_event_seq_number = pLevelEVT_Index[i].event_sequence_num;
-        EventProcessor(pLevelEVT_Index[i].uEventID, 0, 1);
-        start_event_seq_number = 0;
+      if ( test_event->_e_type == EVENT_OnMapLeave )
+      {
+        EventProcessor(pLevelEVT_Index[i].uEventID, 0, 1, pLevelEVT_Index[i].event_sequence_num);
       }
     }
   }
@@ -11909,11 +11907,9 @@
 		}
 		else if (_evt->_e_type == EVENT_OnMapReload)
 		{
-			start_event_seq_number = pEvent.event_sequence_num;
-			EventProcessor(pEvent.uEventID, 0, 0);
-			start_event_seq_number = 0;
+			EventProcessor(pEvent.uEventID, 0, 0, pEvent.event_sequence_num);
 		}
-		else if (_evt->_e_type == EVENT_OnTimer || _evt->_e_type == EVENT_OnLongTimer)
+		else if (_evt->_e_type == EVENT_OnTimer || _evt->_e_type == EVENT_Initialize)
 		{
 			v3 = &array_5B5928_timers[dword_5B65C8_timers_count];
 			v20 = pOutdoor->loc_time.uLastVisitDay;
@@ -11936,7 +11932,7 @@
 
 			v3->time_left_to_fire = ((unsigned short)_evt->v12 << 8) + _evt->v11;
             v3->fire_interval = ((unsigned short)_evt->v12 << 8) + _evt->v11;
-			if (v3->timer_evt_type  == EVENT_OnLongTimer && !(short)v6 )
+			if (v3->timer_evt_type  == EVENT_Initialize && !(short)v6 )
 			{
 				if ( v20 )
 					v18 = pParty->uTimePlayed - v20;
@@ -12157,8 +12153,7 @@
   {
     if ( pParty->uFlags & 2 )
       pGame->Draw();
-    if ( !start_event_seq_number )
-      pAudioPlayer->StopChannels(-1, -1);
+    pAudioPlayer->StopChannels(-1, -1);
     pMiscTimer->Pause();
     pEventTimer->Pause();
     dword_5C3418 = v4;
@@ -12178,9 +12173,7 @@
   pGUIWindow2->Release();
   pGUIWindow2 = 0;
   activeLevelDecoration = _591094_decoration;
-  start_event_seq_number = dword_5C341C;
-  EventProcessor(dword_5C3418, 0, 1);
-  start_event_seq_number = 0;
+  EventProcessor(dword_5C3418, 0, 1, dword_5C341C);
   activeLevelDecoration = NULL;
   pEventTimer->Resume();
 }
@@ -12381,7 +12374,7 @@
 }
 
 //----- (004466C4) --------------------------------------------------------
-int NPC_EventProcessor( int npc_event_id )
+int NPC_EventProcessor(int npc_event_id, int entry_line)
 	{
   signed int event_index; // ebp@1
   int evt_seq_num; // esi@3
@@ -12392,7 +12385,7 @@
   event_index = 0;
   if ( !npc_event_id )
     return 0;
-  evt_seq_num = start_event_seq_number;
+  evt_seq_num = entry_line;
   pSomeOtherEVT = pGlobalEVT;
   uSomeOtherEVT_NumEvents = uGlobalEVT_NumEvents;
   memcpy(pSomeOtherEVT_Events, pGlobalEVT_Index, sizeof(EventIndex)*4400);
@@ -12842,11 +12835,7 @@
       else
       {
         timer->time_left_to_fire = timer->fire_interval;
-
-        start_event_seq_number = timer->timer_evt_seq_num;
-        EventProcessor(timer->timer_evt_ID, 0, 1);
-
-        start_event_seq_number = 0;
+        EventProcessor(timer->timer_evt_ID, 0, 1, timer->timer_evt_seq_num);
       }
     }
     else
@@ -12862,13 +12851,10 @@
           next_trigger_time = 7 * 60 * 60 * 24; // 1 week
 
         timer->next_fire_time += (next_trigger_time * 128) / 3.0f;
-        if (timer->next_fire_time < pParty->uTimePlayed) // make sure in wont fire several times in a row is big time interval has lapsed
+        if (timer->next_fire_time < pParty->uTimePlayed) // make sure in wont fire several times in a row if big time interval has lapsed
           timer->next_fire_time = pParty->uTimePlayed;
 
-        start_event_seq_number = timer->timer_evt_seq_num;
-        EventProcessor(timer->timer_evt_ID, 0, 1);
-
-        start_event_seq_number = 0;
+        EventProcessor(timer->timer_evt_ID, 0, 1, timer->timer_evt_seq_num);
       }
     }
   }
@@ -14552,7 +14538,7 @@
 				{
 					pPlayer = *v8;
 					if ( !(*v8)->pConditions[14] && !pPlayer->pConditions[15] && !pPlayer->pConditions[16] )
-						pPlayer->ReceiveDamage(v4, 5);
+						pPlayer->ReceiveDamage(v4, DMGT_5);
 					++v8;
 				}
 				while ( (signed int)v8 <= (signed int)&pPlayers[4] );
--- a/mm7_4.cpp	Thu May 23 21:36:57 2013 +0600
+++ b/mm7_4.cpp	Thu May 23 21:37:22 2013 +0600
@@ -2395,7 +2395,7 @@
         {
           v14 = pPlayers[v12];
           v15 = (double)pPlayers[v12]->GetMaxHealth() * 0.1;
-          v14->ReceiveDamage((signed __int64)v15, 0);
+          v14->ReceiveDamage((signed __int64)v15, DMGT_FIRE);
           if ( pParty->uFlags & 4 )
           {
             strcpy(GameUI_Footer_TimedString, pGlobalTXT_LocalizationStrings[660]);
@@ -2424,7 +2424,7 @@
     {
       v17 = *v16;
       v18 = (double)(*v16)->GetMaxHealth() * 0.1;
-      v17->ReceiveDamage((signed __int64)v18, 0);
+      v17->ReceiveDamage((signed __int64)v18, DMGT_FIRE);
       if ( pParty->uFlags & 0x200 )
       {
         strcpy(GameUI_Footer_TimedString, pGlobalTXT_LocalizationStrings[661]);
--- a/mm7_5.cpp	Thu May 23 21:36:57 2013 +0600
+++ b/mm7_5.cpp	Thu May 23 21:37:22 2013 +0600
@@ -457,8 +457,8 @@
           GUIWindow::Create(241, 302, 106, 42, WINDOW_SaveLoadBtn, (int)pBtnLoadSlot, 0);
           continue;
         case UIMSG_SelectLoadSlot:
-          if ( pGUIWindow_CurrentMenu->field_40 == 1 )
-            pKeyActionMap->_459ED1(0);
+          if ( pGUIWindow_CurrentMenu->receives_keyboard_input_2 == WINDOW_INPUT_IN_PROGRESS)
+            pKeyActionMap->SetWindowInputStatus(WINDOW_INPUT_NONE);
           if ( pCurrentScreen != SCREEN_SAVEGAME || uLoadGameUI_SelectedSlot != pSaveListPosition + uMessageParam )
           {
             v10 = pSaveListPosition + uMessageParam;
@@ -466,23 +466,6 @@
             {
               pMessageQueue_50CBD0->AddMessage(UIMSG_SaveLoadBtn, 0, 0);
               pMessageQueue_50CBD0->AddMessage(UIMSG_LoadGame, 0, 0);
-              /*if ( (signed int)pMessageQueue_50CBD0->uNumMessages < 40 )
-              {
-                pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].eType = UIMSG_SaveLoadBtn;
-                pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = 0;
-                *(&pMessageQueue_50CBD0->uNumMessages + 3 * pMessageQueue_50CBD0->uNumMessages + 3) = 0;
-                //v11 = pMessageQueue_50CBD0->uNumMessages + 1;
-                //v13 = pMessageQueue_50CBD0->uNumMessages + 1 > 40;
-                //v12 = (signed int)pMessageQueue_50CBD0->uNumMessages - 39 < 0;
-                ++pMessageQueue_50CBD0->uNumMessages;
-                if ( v12 ^ v13 )
-                {
-                  pMessageQueue_50CBD0->pMessages[v11].eType = UIMSG_LoadGame;
-                  pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = 0;
-                  *(&pMessageQueue_50CBD0->uNumMessages + 3 * pMessageQueue_50CBD0->uNumMessages + 3) = 0;
-                  ++pMessageQueue_50CBD0->uNumMessages;
-                }
-              }*/
             }
             uLoadGameUI_SelectedSlot = v10;
             dword_6BE138 = v10;
@@ -504,9 +487,9 @@
           stru_506E40.Release();
           continue;
         case UIMSG_SaveGame:
-          if ( pGUIWindow_CurrentMenu->field_40 == 1 )
-          {
-            pKeyActionMap->_459ED1(0);
+          if ( pGUIWindow_CurrentMenu->receives_keyboard_input_2 == WINDOW_INPUT_IN_PROGRESS)
+          {
+            pKeyActionMap->SetWindowInputStatus(WINDOW_INPUT_NONE);
             strcpy((char *)&pSavegameHeader[uLoadGameUI_SelectedSlot], (const char *)pKeyActionMap->pPressedKeysBuffer);
           }
           DoSavegame(uLoadGameUI_SelectedSlot);
@@ -1655,10 +1638,8 @@
           }
           else
           {
-            start_event_seq_number = dword_5C341C;
-            EventProcessor(dword_5C3418, 0, 1);
-          }
-          start_event_seq_number = 0;
+            EventProcessor(dword_5C3418, 0, 1, dword_5C341C);
+          }
           if ( !_strcmpi(byte_6BE3B0, "d05.blv") )
             pParty->uTimePlayed += 1474560i64;
           continue;
@@ -1666,7 +1647,6 @@
           CloseWindowBackground();
           pVideoPlayer->Unload();
           DialogueEnding();
-          start_event_seq_number = 0;
           viewparams->bRedrawGameUI = true;
           continue;
         case UIMSG_CycleCharacters:
@@ -3186,13 +3166,13 @@
           v119 = 2048;
           if ( (signed int)v118 <= 2048 )
           {
-            dword_576E2C = v118;
+            _576E2C_current_minimap_zoom = v118;
             dword_576E28 = viewparams->field_28;
             break;
           }
           viewparams->field_28 = 11;
           viewparams->uMinimapZoom = v119;
-          dword_576E2C = v119;
+          _576E2C_current_minimap_zoom = v119;
           dword_576E28 = viewparams->field_28;
           break;
         case UIMSG_ClickZoomInBtn:
@@ -3213,7 +3193,7 @@
               v118 = v119;
               viewparams->uMinimapZoom = v119;
             }
-            dword_576E2C = v118;
+            _576E2C_current_minimap_zoom = v118;
             dword_576E28 = viewparams->field_28;
           }
           else
@@ -3464,8 +3444,8 @@
           break;
         case UIMSG_SelectLoadSlot:
             //main menu save/load wnd   clicking on savegame lines
-          if (pGUIWindow_CurrentMenu->field_40 == 1)
-            pKeyActionMap->_459ED1(0);
+          if (pGUIWindow_CurrentMenu->receives_keyboard_input_2 == WINDOW_INPUT_IN_PROGRESS)
+            pKeyActionMap->SetWindowInputStatus(WINDOW_INPUT_NONE);
           if ( pCurrentScreen != SCREEN_SAVEGAME || uLoadGameUI_SelectedSlot != pParam + pSaveListPosition )
           {
             //load clicked line
@@ -4760,7 +4740,7 @@
     && (SHIDWORD(pMonster->pActorBuffs[20].uExpireTime) > (signed int)v41
      || LODWORD(pMonster->pActorBuffs[20].uExpireTime) > v41)
     && uDamageAmount != v41 )
-    player->ReceiveDamage(uDamageAmount, a2);
+    player->ReceiveDamage(uDamageAmount, (DAMAGE_TYPE)a2);
   v50 = 24;
   v59 = 20 * v61 / (signed int)pMonster->pMonsterInfo.uHP;
   if ( (player->_48EA46_calc_special_bonus_by_items(24) || hit_will_stun != v41)
@@ -5012,7 +4992,7 @@
 LABEL_43:
     if ( !(dword_6BE368_debug_settings_2 & 0x10) )
     {
-      v24 = v6->ReceiveDamage(v77, v22);
+      v24 = v6->ReceiveDamage(v77, (DAMAGE_TYPE)v22);
       if ( SHIDWORD(v6->pPlayerBuffs[10].uExpireTime) >= 0
         && (SHIDWORD(v6->pPlayerBuffs[10].uExpireTime) > 0 || LODWORD(v6->pPlayerBuffs[10].uExpireTime)) )
       {
@@ -5075,7 +5055,7 @@
     if ( !pParty->bTurnBasedModeOn )
     {
       v35 = v6->GetActualEndurance();
-      v36 = (double)(20 - v6->_48EA1B_get_static_effect(v35)) * flt_6BE3A4_debug_recmod1 * 2.133333333333333;
+      v36 = (double)(20 - v6->GetParameterBonus(v35)) * flt_6BE3A4_debug_recmod1 * 2.133333333333333;
       v6->SetRecoveryTime((signed __int64)v36);
     }
     if ( v77 )
@@ -5197,7 +5177,7 @@
 LABEL_133:
         if ( !(dword_6BE368_debug_settings_2 & 0x10) )
         {
-          v54 = v45->ReceiveDamage(v77, v50);
+          v54 = v45->ReceiveDamage(v77, (DAMAGE_TYPE)v50);
           if ( SHIDWORD(v45->pPlayerBuffs[10].uExpireTime) >= 0 )
           {
             if ( SHIDWORD(v45->pPlayerBuffs[10].uExpireTime) > 0 || LODWORD(v45->pPlayerBuffs[10].uExpireTime) )
@@ -5263,7 +5243,7 @@
         if ( !pParty->bTurnBasedModeOn )
         {
           v65 = v45->GetActualEndurance();
-          v66 = (double)(20 - v45->_48EA1B_get_static_effect(v65))
+          v66 = (double)(20 - v45->GetParameterBonus(v65))
               * flt_6BE3A4_debug_recmod1
               * 2.133333333333333;
           v45->SetRecoveryTime((signed __int64)v66);
@@ -5294,7 +5274,7 @@
       v68 = pParty->pPlayers[uActorID].CalculateRangedDamageTo(0);
       v69 = 0;
     }
-    a4b->ReceiveDamage(v68, v69);
+    a4b->ReceiveDamage(v68, (DAMAGE_TYPE)v69);
     if ( v38 == OBJECT_Player && !qword_A750D8 )
     {
       qword_A750D8 = 256i64;
@@ -5359,28 +5339,14 @@
 //----- (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
-
-  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_y = sinf(3.14159265f * sRotY / 1024.0f);
- //sDepth = 14000000;
+
  *outx = v.x + ((unsigned __int64)(sinf_y * (signed __int64)((unsigned __int64)(cosf_x * (signed __int64)sDepth)>> 16)));
  *outy = v.y + ((unsigned __int64)(cosf_y * (signed __int64)((unsigned __int64)(cosf_x * (signed __int64)sDepth)>> 16)));
  *outz = v.z + ((unsigned __int64)(sinf_x * (signed __int64)sDepth) >> 16);
-
 }
 
 //----- (0043AB61) --------------------------------------------------------
@@ -9767,149 +9733,6 @@
 }
 
 
-//----- (00411150) --------------------------------------------------------
-void DrawTownPortalScreen()
-{
-  //signed int v0; // edi@1
-  //__int16 v1; // dx@8
-  //POINT *v2; // edi@17
-  int v3; // edi@17
-  //__int16 v4; // dx@24
-  GUIWindow v6; // [sp+Ch] [bp-64h]@1
-  //POINT v7; // [sp+60h] [bp-10h]@17
-  POINT a2; // [sp+68h] [bp-8h]@17
-
-  pRenderer->ClearZBuffer(0, 479);
-  pRenderer->DrawTextureTransparent(8, 8, pTexture_CurrentBook);
-  pRenderer->DrawTextureTransparent(471, 445, pIcons_LOD->GetTexture(uExitCancelTextureId));
-
-  v6.uFrameX = game_viewport_x;
-  v6.uFrameY = game_viewport_y;
-  v6.uFrameWidth = game_viewport_width;
-  v6.uFrameHeight = game_viewport_height;
-  v6.uFrameZ = game_viewport_z;
-  v6.uFrameW = game_viewport_w;
-  
-  const uint fountain_bits_lut[] = {PARTY_QUEST_FOUNTAIN_HARMONDALE,
-                                    PARTY_QUEST_FOUNTAIN_PIERPONT,
-                                    PARTY_QUEST_FOUNTAIN_NIGHON,
-                                    PARTY_QUEST_FOUNTAIN_EVENMORN_ISLE,
-                                    PARTY_QUEST_FOUNTAIN_CELESTIA,
-                                    PARTY_QUEST_FOUNTAIN_THE_PIT};
-  for (uint i = 0; i < 6; ++i)
-  {
-
-    if (_449B57_test_bit(pParty->_quest_bits, fountain_bits_lut[i]))
-      pRenderer->DrawMaskToZBuffer(pTownPortalBook_xs[i],
-                                   pTownPortalBook_ys[i],
-                                   pTexture_TownPortalIcons[i], i + 1);
-  }
-
-/*  v0 = 0;
-  do
-  {
-    if ( !v0 )
-    {
-      v1 = 206;
-LABEL_14:
-      if ( !(unsigned __int16)_449B57_test_bit(pParty->_quest_bits, v1) )
-        goto LABEL_16;
-      goto LABEL_15;
-    }
-    if ( v0 == 1 )
-    {
-      v1 = 208;
-      goto LABEL_14;
-    }
-    if ( v0 == 2 )
-    {
-      v1 = 207;
-      goto LABEL_14;
-    }
-    if ( v0 == 3 )
-    {
-      v1 = 211;
-      goto LABEL_14;
-    }
-    if ( v0 == 4 )
-    {
-      v1 = 209;
-      goto LABEL_14;
-    }
-    if ( v0 == 5 )
-    {
-      v1 = 210;
-      goto LABEL_14;
-    }
-LABEL_15:
-    pRenderer->DrawMaskToZBuffer(
-      pTownPortalBook_xs[v0],
-      pTownPortalBook_ys[v0],
-      *(&pTexture_TownPortalHarmn + v0),
-      v0 + 1);
-LABEL_16:
-    ++v0;
-  }
-  while ( v0 < 6 );*/
-
-  pMouse->GetCursorPos(&a2);
-  //v2 = pMouse->GetCursorPos(&a2);
-  v3 = pRenderer->pActiveZBuffer[a2.x + pSRZBufferLineOffsets[a2.y]] & 0xFFFF;
-
-  if (v3)
-  {
-    if (_449B57_test_bit(pParty->_quest_bits, fountain_bits_lut[v3 - 1]))
-      pRenderer->DrawTextureIndexed(pTownPortalBook_xs[v3 - 1], pTownPortalBook_ys[v3 - 1], pTexture_TownPortalIcons[v3 - 1]);
-  }
-  v6.DrawTitleText(pBook2Font, 0, 22u, 0, pGlobalTXT_LocalizationStrings[10], 3u);
-
-
-/*  if ( !v3 )                                    // Town Portal
-  {
-    v6.DrawTitleText(pBook2Font, 0, 22, 0, pGlobalTXT_LocalizationStrings[10], 3);  // "Town Portal"
-    return;
-  }
-  if ( v3 == 1 )
-  {
-    v4 = 206;
-LABEL_30:
-    if ( (unsigned __int16)_449B57_test_bit(pParty->_quest_bits, v4) )
-      goto LABEL_31;
-    v6.DrawTitleText(pBook2Font, 0, 22u, 0, pGlobalTXT_LocalizationStrings[10], 3u);  // "Town Portal"
-    return;
-  }
-  if ( v3 == 2 )
-  {
-    v4 = 208;
-    goto LABEL_30;
-  }
-  if ( v3 == 3 )
-  {
-    v4 = 207;
-    goto LABEL_30;
-  }
-  if ( v3 == 4 )
-  {
-    v4 = 211;
-    goto LABEL_30;
-  }
-  if ( v3 == 5 )
-  {
-    v4 = 209;
-    goto LABEL_30;
-  }
-  if ( v3 == 6 )
-  {
-    v4 = 210;
-    goto LABEL_30;
-  }
-LABEL_31:
-  pRenderer->DrawTextureIndexed(word_4E1D3A[v3], pTownPortalBook_xs[v3 + 5], *(&pTex_tab_an_6b__zoom_on + v3));
-  v6.DrawTitleText(pBook2Font, 0, 22u, 0, pGlobalTXT_LocalizationStrings[10], 3u);*/
-}
-// 4E1D3A: using guessed type __int16 word_4E1D3A[];
-
-
 //----- (00413FF1) --------------------------------------------------------
 void SetMonthNames()
 {
@@ -9980,17 +9803,6 @@
 
 
 
-
-//----- (004141CA) --------------------------------------------------------
-void ModalWindow(const char *pStr, int a4)
-{
-  pEventTimer->Pause();
-  dword_506F0C[0] = pCurrentScreen;
-  ptr_507BDC = GUIWindow::Create(0, 0, 640, 480, WINDOW_FinalWindow, a4, (int)pStr);
-  pCurrentScreen = SCREEN_PRESS_ESCAPE_MESSAGE;
-}
-// 4E28F8: using guessed type int pCurrentScreen;
-
 //----- (0041420D) --------------------------------------------------------
 void __cdecl sub_41420D_press_esc()
 {
@@ -10014,13 +9826,7 @@
 
   v0 = ptr_507BDC;
   pMessageQueue_50CBD0->AddMessage((UIMessageType)(int)ptr_507BDC->ptr_1C, 0, 0);
-  /*if ( (signed int)pMessageQueue_50CBD0->uNumMessages < 40 )
-  {
-    pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].eType = (UIMessageType)(int)ptr_507BDC->ptr_1C;
-    pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = 0;
-    *(&pMessageQueue_50CBD0->uNumMessages + 3 * pMessageQueue_50CBD0->uNumMessages + 3) = 0;
-    ++pMessageQueue_50CBD0->uNumMessages;
-  }*/
+
   v0->Release();
   ptr_507BDC = 0;
   pCurrentScreen = dword_506F0C[0];
@@ -10223,7 +10029,7 @@
       case WINDOW_50:
       {
         v27 = TargetColor(255, 255, 255);
-        if ( ptr_507BD0->field_40 == 1 )
+        if ( ptr_507BD0->receives_keyboard_input_2 == WINDOW_INPUT_IN_PROGRESS)
         {
           ptr_507BD0->DrawMessageBox(0);
           ptr_507BD0->DrawText(pFontCreate, 30, 40, v27, (const char *)pKeyActionMap->pPressedKeysBuffer, 0, 0, 0);
@@ -10231,19 +10037,19 @@
           ptr_507BD0->DrawFlashingInputCursor(v31 + 30, 40, pFontCreate);
           continue;
         }
-        if ( ptr_507BD0->field_40 == 2 )
+        if ( ptr_507BD0->receives_keyboard_input_2 == WINDOW_INPUT_CONFIRMED)
         {
-          pWindow->field_40 = 0;
+          pWindow->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
           pMessageQueue_50CBD0->AddMessage((UIMessageType)(int)ptr_507BD0->ptr_1C, 0, 0);
           pEventTimer->Resume();
           ptr_507BD0->Release();
-          pCurrentScreen = 0;
-          viewparams->bRedrawGameUI = 1;
+          pCurrentScreen = SCREEN_GAME;
+          viewparams->bRedrawGameUI = true;
           continue;
         }
-        if ( ptr_507BD0->field_40 == 3 )
+        if ( ptr_507BD0->receives_keyboard_input_2 == WINDOW_INPUT_CANCELLED)
         {
-          pWindow->field_40 = 0;
+          pWindow->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
           pEventTimer->Resume();
           ptr_507BD0->Release();
           continue;
@@ -10260,7 +10066,7 @@
           pWindow->Release();
           pEventTimer->Resume();
           pCurrentScreen = 0;
-          viewparams->bRedrawGameUI = 1;
+          viewparams->bRedrawGameUI = true;
           v26 = atoi((const char *)pKeyActionMap->pPressedKeysBuffer);
           if ( v26 > 0 )
           {
@@ -10768,7 +10574,7 @@
     {
       v0->RemoveItemAtInventoryIndex(v18);
       v26 = rand();
-      v0->ReceiveDamage(v26 % 11 + 10, 0);
+      v0->ReceiveDamage(v26 % 11 + 10, DMGT_FIRE);
       pAudioPlayer->PlaySound(SOUND_8, 0, 0, -1, 0, 0, 0, 0);
 
       pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 0, 0);
@@ -10784,7 +10590,7 @@
       {
         v0->RemoveItemAtInventoryIndex(v18);
         v25 = rand();
-        v0->ReceiveDamage(v25 % 71 + 30, 0);
+        v0->ReceiveDamage(v25 % 71 + 30, DMGT_FIRE);
         v23 = 1;
       }
       else
@@ -10793,7 +10599,7 @@
         {
           v0->RemoveItemAtInventoryIndex(v18);
           v24 = rand();
-          v0->ReceiveDamage(v24 % 201 + 50, 0);
+          v0->ReceiveDamage(v24 % 201 + 50, DMGT_FIRE);
           v23 = 5;
         }
         else
@@ -10910,134 +10716,6 @@
 }
 
 
-//----- (00416B01) --------------------------------------------------------
-void GameUI_DrawNPCPopup(void *_this)//PopupWindowForBenefitAndJoinText
-{
-  int v1; // edi@2
-  int v2; // ecx@2
-  NPCData *v3; // eax@2
-  NPCData *v4; // esi@7
-  NPCData *v5; // eax@16
-  NPCData *v6; // esi@16
-  const CHAR *v7; // eax@18
-  unsigned int v8; // eax@25
-  unsigned int v9; // eax@25
-  const char *v10; // ST14_4@26
-  char *v11; // esi@26
-  const char *v12; // ST18_4@27
-  unsigned __int16 v13; // ax@28
-  char *v14; // eax@28
-  GUIWindow a1; // [sp+Ch] [bp-60h]@23
-  int a2; // [sp+60h] [bp-Ch]@16
-  void *v17; // [sp+64h] [bp-8h]@1
-  LPCSTR lpsz; // [sp+68h] [bp-4h]@6
-
-  v17 = _this;
-  if ( bNoNPCHiring != 1 )
-  {
-    v1 = 0;
-    v2 = 0;
-    v3 = pParty->pHirelings;
-    /*do
-    {
-      if ( v3->pName )
-        pTmpBuf[v1++] = v2;
-      ++v3;
-      ++v2;
-    }
-    while ( (signed int)v3 < (signed int)&pParty->pPickedItem );*/
-    for (int i = 0; i < 2; ++i)
-    {
-     if (pParty->pHirelings[i].pName)
-        pTmpBuf[v1++] = i;
-    }
-    lpsz = 0;
-    if ( (signed int)pNPCStats->uNumNewNPCs > 0 )
-    {
-      /*v4 = pNPCStats->pNewNPCData;
-      do
-      {
-        if ( v4->uFlags & 0x80
-          && (!pParty->pHirelings[0].pName || strcmp(v4->pName, pParty->pHirelings[0].pName))
-          && (!pParty->pHirelings[1].pName || strcmp(v4->pName, pParty->pHirelings[1].pName)) )
-          pTmpBuf[v1++] = (char)lpsz + 2;
-        ++lpsz;
-        ++v4;
-      }
-      while ( (signed int)lpsz < (signed int)pNPCStats->uNumNewNPCs );*/
-      for (int i = 0; i < pNPCStats->uNumNewNPCs; ++i)
-      {
-        if (pNPCStats->pNewNPCData[i].Hired())
-        {
-          if (!pParty->pHirelings[0].pName || strcmp((char *)pNPCStats->pNewNPCData[i].pName, (char *)pParty->pHirelings[0].pName))
-          {
-            if (!pParty->pHirelings[1].pName || strcmp((char *)pNPCStats->pNewNPCData[i].pName, (char *)pParty->pHirelings[1].pName))
-              pTmpBuf[v1++] = i + 2;
-          }
-        }
-      }
-    }
-    if ( (signed int)((char *)v17 + (unsigned __int8)pParty->field_709) < v1 )
-    {
-      sDialogue_SpeakingActorNPC_ID = -1 - (unsigned __int8)pParty->field_709 - (int)v17;
-      v5 = GetNewNPCData(sDialogue_SpeakingActorNPC_ID, (int)&a2);
-      v6 = v5;
-      if ( v5 )
-      {
-        if ( a2 == 57 )
-          v7 = pNPCTopics[512].pText; // Baby dragon
-        else
-          v7 = (const CHAR *)pNPCStats->pProfessions[v5->uProfession].pBenefits;
-        lpsz = v7;
-        if ( !v7 )
-        {
-          lpsz = (LPCSTR)pNPCStats->pProfessions[v5->uProfession].pJoinText;
-          if ( !lpsz )
-            lpsz = "";
-        }
-        a1.Hint = 0;
-        a1.uFrameX = 38;
-        a1.uFrameY = 60;
-        a1.uFrameWidth = 276;
-        a1.uFrameZ = 313;
-        a1.uFrameHeight = pFontArrus->CalcTextHeight(lpsz, &a1, 0, 0)
-                        + 2 * LOBYTE(pFontArrus->uFontHeight)
-                        + 24;
-        if ( (signed int)a1.uFrameHeight < 130 )
-          a1.uFrameHeight = 130;
-        a1.uFrameWidth = 400;
-        a1.uFrameZ = a1.uFrameX + 399;
-        a1.DrawMessageBox(0);
-        sprintf(pTmpBuf2, "NPC%03d", v6->uPortraitID);
-        v8 = pIcons_LOD->LoadTexture(pTmpBuf2, TEXTURE_16BIT_PALETTE);
-        pRenderer->DrawTextureIndexed(
-          a1.uFrameX + 22,
-          a1.uFrameY + 36,
-          (Texture *)(v8 != -1 ? &pIcons_LOD->pTextures[v8] : 0));
-        v9 = v6->uProfession;
-        if ( v9 )
-        {
-          v10 = v6->pName;
-          v11 = pTmpBuf;
-          sprintfex(pTmpBuf, pGlobalTXT_LocalizationStrings[429], v10, aNPCProfessionNames[v9]);
-        }
-        else
-        {
-          v12 = v6->pName;
-          v11 = pTmpBuf;
-          strcpy(pTmpBuf, v12);
-        }
-        v13 = TargetColor(0xFFu, 0xFFu, 0x9Bu);
-        a1.DrawTitleText(pFontArrus, 0, 0xCu, v13, v11, 3u);
-        a1.uFrameWidth -= 24;
-        a1.uFrameZ = a1.uFrameX + a1.uFrameWidth - 1;
-        v14 = BuilDialogueString((char *)lpsz, uActiveCharacter - 1, 0, 0, 0, 0);
-        a1.DrawText(pFontArrus, 100, 36, 0, v14, 0, 0, 0);
-      }
-    }
-  }
-}
-
 
 
 
@@ -11197,26 +10875,6 @@
   }
 }
 
-//----- (004178C4) --------------------------------------------------------
-void __cdecl sub_4178C4()
-{
-  if ( pArcomageGame->bGameInProgress == 1 )
-  {
-    if (pAsyncMouse)
-      pArcomageGame->stru1.field_0 = 7;
-  }
-}
-
-//----- (004178E1) --------------------------------------------------------
-void __cdecl sub_4178E1()
-{
-  if ( pArcomageGame->bGameInProgress == 1 )
-  {
-    if (pAsyncMouse)
-      pArcomageGame->stru1.field_0 = 8;
-  }
-}
-
 //----- (004178FE) --------------------------------------------------------
 unsigned int __fastcall UI_GetHealthManaStringColor(signed int a1, signed int a2)
 {
--- a/mm7_6.cpp	Thu May 23 21:36:57 2013 +0600
+++ b/mm7_6.cpp	Thu May 23 21:37:22 2013 +0600
@@ -7446,15 +7446,18 @@
   }
 
   //pParty->uFlags2 |= PARTY_FLAGS_2_RUNNING;
-  for ( uint i = 0; i < 30; ++i )
+
+
+    //  WUT? double event trigger
+  /*for ( uint i = 0; i < 30; ++i )
   {
     if ( pKeyActionMap->pToggleTypes[i] )
       v14 = pGame->pKeyboardInstance->WasKeyPressed(pKeyActionMap->pVirtualKeyCodesMapping[i]);
     else
       v14 = pGame->pKeyboardInstance->IsKeyBeingHeld(pKeyActionMap->pVirtualKeyCodesMapping[i]);
-    if ( v14 && i == 9 )
+    if ( v14 )
     {
-      if ( !pCurrentScreen )
+      if (pCurrentScreen == SCREEN_GAME)
       {
         pMessageQueue_50CBD0->AddMessage(UIMSG_Game_Action, 0, 0);
         continue;
@@ -7480,7 +7483,7 @@
         //pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 0, 0);
       }
     }
-  }
+  }*/
   if ( !pEventTimer->bPaused )
   {
     for ( uint i = 0; i < 30; ++i )
@@ -7699,13 +7702,6 @@
             }
             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;
-            }*/
             pMessageQueue_50C9E8->AddMessage(UIMSG_CastQuickSpell, 0, 0);
             }
             break;
@@ -7819,12 +7815,4 @@
       }
     }
   }
-  if (pGame->pKeyboardInstance->bUsingAsynKeyboard)
-  {
-    AsyncKeyboard::LeaveCriticalSection();
-    //v16 = pAsyncKeyboard;
-    AsyncKeyboard::EnterCriticalSection();
-    memset((char *)pAsyncKeyboard + 521, 0, 0x100u);
-    AsyncKeyboard::LeaveCriticalSection();
-  }
 }
--- a/mm7_data.cpp	Thu May 23 21:36:57 2013 +0600
+++ b/mm7_data.cpp	Thu May 23 21:37:22 2013 +0600
@@ -692,18 +692,6 @@
 int bWinNT4_0; // weak
 __int16 word_4E8152[11] = {0, 0, 0, 90, 8, 2, 70, 20, 10, 50, 30};
 
-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,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0,
-  1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0,  0, 0, 0, 0, 1, 0, 1, 1, 1,
-  0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0,  0, 0, 0, 0, 1, 1, 1, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,  1, 1, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0,  0, 0, 0, 1, 1, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 3, 3, 3, 3, 3, 3, 1,
-  1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2,  2, 0, 0, 0, 0, 0
-};
 stru355 stru_4E82A4 = {0x20, 0x41, 0, 0x20, 0xFF0000, 0xFF00, 0xFF, 0xFF000000};
 stru355 stru_4EFCBC = {0x20, 0x41, 0, 0x10, 0x7C00, 0x3E0, 0x1F, 0x8000};
 char byte_4E94D0 = 5; // weak
@@ -1292,7 +1280,7 @@
 unsigned int uIconIdx_FlySpell;
 unsigned int uIconIdx_WaterWalk;
 int dword_576E28; // weak
-int dword_576E2C; // weak
+int _576E2C_current_minimap_zoom; // weak
 __int64 _5773B8_event_timer; // weak
 int _5773C0_unused; // weak
 
@@ -1318,7 +1306,6 @@
 struct Texture *pTexture_outside; // idb
 struct Texture *pTexture_Dialogue_Background;
 _UNKNOWN unk_597F10; // weak
-int start_event_seq_number; // weak
 char byte_5B0938[2000];
 int EvtTargetObj; // 0x5B5920
 int _unused_5B5924_is_travel_ui_drawn = false; // 005B5924
@@ -1511,10 +1498,6 @@
 int aborting_app; // weak
 int dword_720020_zvalues[100];
 int dword_7201B0_zvalues[299];
-int dword_72065C[777]; // weak
-int dword_720660[777]; // idb
-int dword_7207EC[777]; // weak
-int dword_7207F0[777]; // idb
 int uTextureID_720980; // weak
 int _720984_unused; // weak
 char _72098C_unused; // weak
@@ -1647,8 +1630,8 @@
 //_UNKNOWN unk_F8BA50; // weak
 char byte_F8BC0C; // weak
 int bGameoverLoop = 0; // weak
-__int16 word_F8BC48_displaced_face_intersect_plane_coords_a[104]; // idb
-__int16 word_F8BD18_displaced_face_intersect_plane_coords_b[104]; // idb
+__int16 intersect_face_vertex_coords_list_a[104]; // word_F8BC48
+__int16 intersect_face_vertex_coords_list_b[104]; // word_F8BD18
 int dword_F93F20; // weak
 int dword_F93F70; // weak
 
--- a/mm7_data.h	Thu May 23 21:36:57 2013 +0600
+++ b/mm7_data.h	Thu May 23 21:37:22 2013 +0600
@@ -482,7 +482,6 @@
 extern int bWinNT4_0; // weak
 extern __int16 word_4E8152[11];
 extern char byte_4E8168[7][14];
-extern char byte_4E8394[]; // weak
 #include "Texture.h"
 extern stru355 stru_4E82A4;// = {0x20, 0x41, 0, 0x20, 0xFF0000, 0xFF00, 0xFF, 0xFF000000};
 extern stru355 stru_4EFCBC;// = {0x20, 0x41, 0, 0x10, 0x7C00, 0x3E0, 0x1F, 0x8000};
@@ -774,7 +773,7 @@
 extern unsigned int uIconIdx_FlySpell;
 extern unsigned int uIconIdx_WaterWalk;
 extern int dword_576E28; // weak
-extern int dword_576E2C; // weak
+extern int _576E2C_current_minimap_zoom; // weak
 extern __int64 _5773B8_event_timer; // weak
 extern int _5773C0_unused; // weak
 
@@ -800,7 +799,6 @@
 extern struct Texture *pTexture_outside; // idb
 extern struct Texture *pTexture_Dialogue_Background;
 extern _UNKNOWN unk_597F10; // weak
-extern int start_event_seq_number; // weak
 extern char byte_5B0938[2000];
 extern int EvtTargetObj; // weak
 extern int _unused_5B5924_is_travel_ui_drawn; // 005B5924
@@ -995,9 +993,6 @@
 extern int aborting_app; // weak
 extern int dword_720020_zvalues[100];
 extern int dword_7201B0_zvalues[299];
-extern int dword_72065C[]; // weak
-extern int dword_720660[]; // idb
-extern int dword_7207EC[]; // weak
 extern int dword_7207F0[]; // idb
 extern int uTextureID_720980; // weak
 extern int _720984_unused; // weak
@@ -1139,8 +1134,8 @@
 //extern _UNKNOWN unk_F8BA50; // weak
 extern char byte_F8BC0C; // weak
 extern int bGameoverLoop; // weak
-extern __int16 word_F8BC48_displaced_face_intersect_plane_coords_a[]; // idb
-extern __int16 word_F8BD18_displaced_face_intersect_plane_coords_b[]; // idb
+extern __int16 intersect_face_vertex_coords_list_a[]; // word_F8BC48
+extern __int16 intersect_face_vertex_coords_list_b[]; // word_F8BD18
 //extern _UNKNOWN unk_F8EA04; // weak
 //extern _UNKNOWN unk_F8F8F8; // weak
 extern int dword_F93F20; // weak
@@ -1262,8 +1257,6 @@
 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);
-void sub_4178C4();
-void sub_4178E1();
 unsigned int __fastcall UI_GetHealthManaStringColor(signed int a1, signed int a2);
 signed int __thiscall GetConditionDrawColor(unsigned int uConditionIdx); // idb
 void  __fastcall sub_4179BC_draw_tooltip(const char *a1, const char *a2); // idb
@@ -1389,7 +1382,7 @@
 int sub_4465DF_check_season(int a1);
 int __fastcall IsActorAlive(unsigned int uType, unsigned int uParam, unsigned int uNumAlive); // idb
 // void __cdecl crt_construct_5773C4();
-int NPC_EventProcessor(int npc_event_id);
+int NPC_EventProcessor(int npc_event_id, int entry_line = 0);
 
 void __fastcall sub_448518_npc_set_item(int npc, unsigned int item, int a3);
 void __fastcall sub_44861E_set_texture(unsigned int uFaceCog, const char *pFilename);
@@ -1480,14 +1473,12 @@
 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
+#include "Items.h"
+void sub_467E7F_EquipBody(ITEM_EQUIP_TYPE uEquipType); // idb
 void  CreateMsgScrollWindow(signed int mscroll_id);
 void __cdecl free_book_subwindow();
 void  CreateScrollWindow();
 void __cdecl OnPaperdollLeftClick();
-int __thiscall UnprojectX(int x);
-int __thiscall UnprojectY(int _this);
 void OnPressSpace();
 char __fastcall DoInteractionWithTopmostZObject(int a1, int a2);
 int __fastcall sub_46A6AC(int a1, int a2, int a3);
@@ -1698,11 +1689,6 @@
 signed int __fastcall SpawnRandomTreasure(struct MapInfo *a1, struct SpawnPointMM7 *a2);
 void DamageMonsterFromParty(signed int a1, unsigned int uActorID_Monster, struct Vec3_int_ *pVelocity);
 
-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/stru6.cpp	Thu May 23 21:36:57 2013 +0600
+++ b/stru6.cpp	Thu May 23 21:37:22 2013 +0600
@@ -19,6 +19,7 @@
 #include "PaletteManager.h"
 #include "Overlays.h"
 #include "stru160.h"
+#include "Math.h"
 
 #include "MM7.h"