changeset 1306:13b7be8b06a0

Слияние
author Ritor1
date Sun, 23 Jun 2013 14:27:57 +0600
parents 1ab9bff65f01 (current diff) bedc304ab617 (diff)
children d346e11b550b
files Actor.cpp DecorationList.cpp GUIWindow.cpp Indoor.cpp ObjectList.cpp Outdoor.cpp SaveLoad.cpp Spells.cpp SpriteObject.cpp Texture.cpp UI/UIHouses.cpp UIHouses.cpp mm7_1.cpp mm7_2.cpp mm7_3.cpp
diffstat 57 files changed, 32236 insertions(+), 19159 deletions(-) [+]
line wrap: on
line diff
--- a/Actor.cpp	Sun Jun 23 14:27:32 2013 +0600
+++ b/Actor.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -33,10 +33,10 @@
 
 #include "MM7.h"
 #include "SpriteObject.h"
+#include "stru298.h"
+#include "Log.h"
+#include "Texts.h"
 #include "Allocator.h"
-#include "PaletteManager.h"
-
-
 
 
 
@@ -3981,6 +3981,1480 @@
   }
   return result;
 }
+// 46DF1A: using guessed type int __fastcall 46DF1A_collide_against_actor(int, int);
+//----- (0046DF1A) --------------------------------------------------------
+signed int __fastcall _46DF1A_collide_against_actor(int a1, int a2)
+{
+  Actor *v2; // edi@1
+  unsigned __int16 v3; // ax@1
+  int v4; // esi@6
+  int v5; // ecx@8
+  int v6; // eax@10
+  int v7; // edx@12
+  int v8; // ecx@14
+  int v9; // eax@14
+  int v10; // ebx@14
+  int v11; // esi@14
+  int v12; // ebx@15
+  int v13; // ebx@17
+  unsigned int v14; // eax@20
+  signed int result; // eax@21
+  int v16; // [sp+Ch] [bp-10h]@1
+  int v17; // [sp+10h] [bp-Ch]@14
+  int v18; // [sp+14h] [bp-8h]@14
+  int v19; // [sp+18h] [bp-4h]@14
+
+  v16 = a1;
+  v2 = &pActors[a1];
+  v3 = v2->uAIState;
+  if ( v3 == 11 || v3 == 4 || v3 == 19 || v3 == 5 || v3 == 17 )
+    goto LABEL_25;
+  v4 = v2->uActorRadius;
+  if ( a2 )
+    v4 = a2;
+  v5 = v2->vPosition.x;
+  if ( stru_721530.sMaxX > v5 + v4
+    || stru_721530.sMinX < v5 - v4
+    || (v6 = v2->vPosition.y, stru_721530.sMaxY > v6 + v4)
+    || stru_721530.sMinY < v6 - v4
+    || (v7 = v2->vPosition.z, stru_721530.sMaxZ > v7 + v2->uActorHeight)
+    || stru_721530.sMinZ < v7
+    || (v8 = v5 - stru_721530.normal.x,
+        v9 = v6 - stru_721530.normal.y,
+        v10 = stru_721530.prolly_normal_d + v4,
+        v17 = stru_721530.prolly_normal_d + v4,
+        v11 = (v8 * stru_721530.field_58.y - v9 * stru_721530.field_58.x) >> 16,
+        v18 = v8,
+        v19 = v9,
+        abs((v8 * stru_721530.field_58.y - v9 * stru_721530.field_58.x) >> 16) > v10)
+    || (v12 = (v18 * stru_721530.field_58.x + v19 * stru_721530.field_58.y) >> 16, v12 <= 0)
+    || (signed int)(((unsigned __int64)(stru_721530.field_58.z * (signed __int64)v12) >> 16) + stru_721530.normal.z) < v2->vPosition.z )
+  {
+LABEL_25:
+    result = 0;
+  }
+  else
+  {
+    v13 = v12 - integer_sqrt(v17 * v17 - v11 * v11);
+    if ( v13 < 0 )
+      v13 = 0;
+    if ( v13 < stru_721530.field_7C )
+    {
+      stru_721530.field_7C = v13;
+      v14 = 8 * v16;
+      LOBYTE(v14) = PID(OBJECT_Actor,v16);
+      stru_721530.uFaceID = v14;
+    }
+    result = 1;
+  }
+  return result;
+}
+//----- (00401A91) --------------------------------------------------------
+void __cdecl UpdateActorAI()
+{
+	//unsigned int v0; // esi@4
+	int v1; // eax@7
+	//int v2; // ecx@7
+	//int v3; // eax@7
+	signed int v4; // edi@10
+	Actor *v5; // esi@12
+	signed int sDmg; // eax@14
+	__int16 v7; // cx@14
+	//Player **v8; // esi@20
+	Player *pPlayer; // ecx@21
+	Actor *pActor; // esi@34
+	//__int16 v11; // ax@34
+	//unsigned int v12; // eax@47
+	//signed int v13; // edi@47
+	//SpellBuff *v14; // ebx@47
+	//unsigned int v15; // edi@67
+	//char *v16; // eax@67
+	//unsigned int v17; // edx@67
+	//unsigned int v18; // ecx@67
+	//unsigned __int16 v19; // ax@72
+	//int *v20; // esi@80
+	//Actor *v21; // ebx@80
+	unsigned __int16 v22; // ax@86
+	//signed int v23; // eax@94
+	//unsigned int v24; // eax@102
+	//signed int v25; // edi@102
+	//SpellBuff *v26; // esi@102
+	unsigned int v27; // ecx@123
+	unsigned int v28; // eax@123
+	//unsigned int v29; // eax@127
+	AIDirection *v30; // eax@129
+	unsigned __int16 v31; // ax@132
+	//unsigned int v32; // esi@142
+	int v33; // eax@144
+	int v34; // eax@147
+	char v35; // al@150
+	unsigned int v36; // edi@152
+	signed int v37; // eax@154
+	//unsigned __int8 v38; // sf@158
+	//unsigned __int8 v39; // of@158
+	//signed int v40; // edx@166
+	//unsigned int v41; // ecx@166
+	double v42; // st7@176
+	double v43; // st6@176
+	//bool v44; // eax@189
+	bool v45; // eax@192
+	unsigned __int8 v46; // cl@197
+	double v47; // st7@206
+	//double v48; // st7@207
+	//char v49; // zf@208
+	//char v50; // zf@214
+	//signed int v51; // edx@219
+	//unsigned int v52; // ecx@219
+	__int16 v53; // fps@224
+	//unsigned __int8 v54; // c0@224
+	//unsigned __int8 v55; // c3@224
+	//double v56; // st7@226
+	AIDirection *v57; // eax@246
+	double v58; // st7@246
+	//signed int v59; // [sp-18h] [bp-C8h]@213
+	//int v60; // [sp-14h] [bp-C4h]@144
+	//int v61; // [sp-14h] [bp-C4h]@168
+	//AIDirection *v62; // [sp-14h] [bp-C4h]@213
+	//signed int v63; // [sp-14h] [bp-C4h]@216
+	unsigned int v64; // [sp-14h] [bp-C4h]@219
+	unsigned int v65; // [sp-10h] [bp-C0h]@144
+	char v66; // [sp-10h] [bp-C0h]@147
+	//AIDirection *v67; // [sp-10h] [bp-C0h]@167
+	//int v68; // [sp-10h] [bp-C0h]@168
+	//AIDirection *v69; // [sp-10h] [bp-C0h]@206
+	int v70; // [sp-10h] [bp-C0h]@213
+	//AIDirection *v71; // [sp-10h] [bp-C0h]@216
+	AIDirection v72; // [sp+0h] [bp-B0h]@246
+	AIDirection a3; // [sp+1Ch] [bp-94h]@129
+	AIDirection v74; // [sp+38h] [bp-78h]@246
+	AIDirection v75; // [sp+54h] [bp-5Ch]@129
+	int target_pid_type; // [sp+70h] [bp-40h]@83
+	signed int a1; // [sp+74h] [bp-3Ch]@129
+	int v78; // [sp+78h] [bp-38h]@79
+	AIDirection pDir; // [sp+7Ch] [bp-34h]@129
+	float v80; // [sp+98h] [bp-18h]@33
+	int v81; // [sp+9Ch] [bp-14h]@100
+	//int v82; // [sp+A0h] [bp-10h]@45
+	//unsigned int uActorID; // [sp+A4h] [bp-Ch]@32
+	unsigned int v84; // [sp+A8h] [bp-8h]@11
+	signed int target_pid; // [sp+ACh] [bp-4h]@83
+	AIState uAIState;
+	int v38;
+	
+	if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor)
+		MakeActorAIList_ODM();
+	else
+		MakeActorAIList_BLV();
+	
+	//v0 = 0;
+	if ( uCurrentlyLoadedLevelType != LEVEL_Indoor && pParty->armageddon_timer > 0 )
+	{
+		if ( pParty->armageddon_timer > 417 )
+		{
+			pParty->armageddon_timer = 0;
+		}
+		else
+		{
+			pParty->sRotationY = (stru_5C6E00->uIntegerDoublePi - 1) & (pParty->sRotationY + rand() % 16 - 8);
+			pParty->sRotationX = pParty->sRotationX + rand() % 16 - 8;
+			if ( pParty->sRotationX > 128) 
+				pParty->sRotationX = 128;
+			else if ( pParty->sRotationX < -128 )
+				pParty->sRotationX = -128;
+				
+			pParty->uFlags |= 2u;
+			pParty->armageddon_timer -= pMiscTimer->uTimeElapsed;
+			v4 = pParty->field_16140 + 50;
+			if ( pParty->armageddon_timer <= 0 )
+			{
+				pParty->armageddon_timer = 0;
+				for(int i = 0; i < uNumActors; i++)
+				{
+					pActor=&pActors[i];
+					if ( pActor->CanAct() )
+					{
+						sDmg = stru_50C198.CalcMagicalDamageToActor(pActor, 5, v4);
+						pActor->sCurrentHP -= stru_50C198.CalcMagicalDamageToActor(pActor, 5, v4);
+						if ( sDmg )
+						{
+							if ( pActor->sCurrentHP >= 0 )
+							{
+								Actor::AI_Stun(i, 4, 0);
+							}
+							else
+							{
+								Actor::Die(i);
+								if ( pActor->pMonsterInfo.uExp )
+									GivePartyExp(pMonsterStats->pInfos[pActor->pMonsterInfo.uID].uExp);
+							}
+						}
+					}
+				}
+				for(int i = 1; i <= 4; i++)
+				{
+					pPlayer = pPlayers[i];
+					if ( !pPlayer->pConditions[14] && !pPlayer->pConditions[15] && !pPlayer->pConditions[16] )
+						pPlayer->ReceiveDamage(v4, DMGT_5);
+				}
+			}
+			if (pTurnEngine->field_1C)
+				--pTurnEngine->field_1C;
+		}
+	}
+	
+	if (pParty->bTurnBasedModeOn)
+	{
+		pTurnEngine->_405E14();
+		return;
+	}
+	
+	
+	//uActorID = v0;
+	for (uint i = 0; i < uNumActors; ++i)
+	{
+		pActor = &pActors[i];
+		//LODWORD(v80) = (int)(char *)pActors + 176; // uAIState
+		//do
+		//{
+			//pActor = (Actor *)(LODWORD(v80) - 176);
+			//v11 = *(unsigned int *)LODWORD(v80);
+			//v49 = *(unsigned int *)LODWORD(v80) == 5;
+			ai_near_actors_targets_pid[i] = OBJECT_Player;
+			if (pActor->uAIState == Dead || pActor->uAIState == Removed || pActor->uAIState == Disabled || pActor->uAttributes & 0x0400)
+				continue;
+			
+			if (!pActor->sCurrentHP && pActor->uAIState != Dying)
+				Actor::Die(i);
+			
+			//v84 = *(_QWORD *)(LODWORD(v80) + 84) <= 0i64 ? 0 : 1;
+			//v82 = *(_QWORD *)(LODWORD(v80) + 52) <= 0i64 ? 0 : 1;
+			//v12 = 0;
+			//v13 = 0;
+			//v14 = (SpellBuff *)(LODWORD(v80) + 36);
+			for (uint j = 0; j < 22; ++j)
+			{
+				if (j != 10)
+				pActor->pActorBuffs[j]._4585CA(pParty->uTimePlayed);
+			}
+			/*do
+			{
+				if ( v13 != 10 )
+				{
+					v14->_4585CA(pParty->uTimePlayed);
+					v12 = 0;
+				}
+				++v13;
+				++v14;
+			}
+			while ( v13 < 22 );*/
+			if ( (signed __int64)pActor->pActorBuffs[ACTOR_BUFF_SHRINK].uExpireTime < 0 )
+			//&& SHIDWORD(pActor->pActorBuffs[3].uExpireTime) <= (signed int)v12 && (SHIDWORD(pActor->pActorBuffs[3].uExpireTime) < (signed int)v12
+			// || LODWORD(pActor->pActorBuffs[3].uExpireTime) <= v12) )
+				pActor->uActorHeight = pMonsterList->pMonsters[pActor->pMonsterInfo.uID - 1].uMonsterHeight;
+			if ( (signed __int64)pActor->pActorBuffs[ACTOR_BUFF_CHARM].uExpireTime > 0 )
+				pActor->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly;
+			// not sure
+			else  if ( (signed __int64)pActor->pActorBuffs[ACTOR_BUFF_CHARM].uExpireTime < 0 )
+				pActor->pMonsterInfo.uHostilityType = pMonsterStats->pInfos[pActor->pMonsterInfo.uID].uHostilityType;
+			
+			if ((signed __int64)pActor->pActorBuffs[ACTOR_BUFF_PARALYZED].uExpireTime > 0 
+				|| (signed __int64)pActor->pActorBuffs[ACTOR_BUFF_STONED].uExpireTime > 0)
+				continue;
+			
+			//v15 = pMiscTimer->uTimeElapsed;
+			//v16 = (char *)&pActor->pMonsterInfo.uRecoveryTime;
+			//v17 = pActor->uCurrentActionTime;
+			//v18 = pActor->pMonsterInfo.uRecoveryTime;
+			if (pActor->pMonsterInfo.uRecoveryTime)
+			{
+				if (pActor->pMonsterInfo.uRecoveryTime < pMiscTimer->uTimeElapsed)
+					pActor->pMonsterInfo.uRecoveryTime = 0;
+				else 
+					pActor->pMonsterInfo.uRecoveryTime -= pMiscTimer->uTimeElapsed;
+			}
+			
+			pActor->uCurrentActionTime += pMiscTimer->uTimeElapsed;
+			if (pActor->uCurrentActionTime < pActor->uCurrentActionLength)
+				continue;
+			
+			//v19 = actor->uAIState;
+			if (pActor->uAIState == Dying)
+				pActor->uAIState = Dead;
+			else
+			{
+				if (pActor->uAIState != Summoned)
+				{
+					Actor::AI_StandOrBored(i, OBJECT_Player, 256, nullptr);
+					continue;
+				}
+				pActor->uAIState = Standing;
+			}
+			
+			pActor->uCurrentActionTime = 0;
+			pActor->uCurrentActionLength = 0;
+			pActor->UpdateAnimation();
+			//LABEL_78:
+			//++uActorID;
+			//LODWORD(v80) += 836;
+		//}
+		//while ( (signed int)uActorID < (signed int)uNumActors );
+	}
+	
+	
+	v78 = 0;
+	int actor_id = -1;
+	if ( ai_arrays_size > 0 )
+	{
+		//while ( 1 )
+		for(v78 = 0; v78 < ai_arrays_size; ++v78)
+		{
+			actor_id = ai_near_actors_ids[v78];
+			assert(actor_id < uNumActors);
+			
+			//v20 = &ai_near_actors_targets_pid[actor_id];
+			pActor = &pActors[actor_id];
+			Actor::_SelectTarget(actor_id, &ai_near_actors_targets_pid[actor_id], true);
+			if (pActor->pMonsterInfo.uHostilityType && !ai_near_actors_targets_pid[actor_id])
+				pActor->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly;
+			target_pid = ai_near_actors_targets_pid[actor_id];
+			target_pid_type = PID_TYPE(target_pid);
+			if ( target_pid_type == OBJECT_Actor)
+				v80 = 0.5;
+			else
+				v80 = 1.0;
+			v22 = pActor->uAIState;
+			if ( v22 == Dying || v22 == Dead || v22 == Removed || v22 == Disabled || v22 == Summoned)
+			{
+				continue;
+			}
+			if ( !pActor->sCurrentHP )
+				Actor::Die(actor_id);
+			for(int i=0;i<22;i++)
+			{
+				if ( i != 10 )
+				{
+					pActor->pActorBuffs[i]._4585CA(pParty->uTimePlayed);
+				}
+			}
+			if ( (signed __int64)pActor->pActorBuffs[ACTOR_BUFF_SHRINK].uExpireTime < 0 )
+				pActor->uActorHeight = pMonsterList->pMonsters[pActor->pMonsterInfo.uID - 1].uMonsterHeight;
+			if ( (signed __int64)pActor->pActorBuffs[ACTOR_BUFF_CHARM].uExpireTime > 0 )
+				pActor->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly;
+			// not sure
+			else if ( (signed __int64)pActor->pActorBuffs[ACTOR_BUFF_CHARM].uExpireTime < 0 )
+				pActor->pMonsterInfo.uHostilityType = pMonsterStats->pInfos[pActor->pMonsterInfo.uID].uHostilityType;
+			if ( (signed __int64)pActor->pActorBuffs[2].uExpireTime < 0 )
+			{
+				pActor->uAIState = Removed;
+				continue;
+			}
+			if ( (signed __int64)pActor->pActorBuffs[5].uExpireTime > 0
+				|| (signed __int64)pActor->pActorBuffs[6].uExpireTime > 0)
+			{
+				continue;
+			}
+			v27 = pMiscTimer->uTimeElapsed;
+			v28 = pActor->pMonsterInfo.uRecoveryTime;
+			pActor->uCurrentActionTime += pMiscTimer->uTimeElapsed;
+			if ( (signed int)v28 > 0 )
+				pActor->pMonsterInfo.uRecoveryTime = v28 - v27;
+			if ( pActor->pMonsterInfo.uRecoveryTime < 0 )
+				pActor->pMonsterInfo.uRecoveryTime = 0;
+			if ( !(pActor->uAttributes & 0x8000) )
+				pActor->uAttributes |= 0x8000;
+			a1 = PID(OBJECT_Actor,actor_id);
+			v30 = Actor::GetDirectionInfo(PID(OBJECT_Actor,actor_id), target_pid, &a3, 0);
+			memcpy(&v75, v30, sizeof(v75));
+			memcpy(&pDir, &v75, sizeof(pDir));
+			uAIState = pActor->uAIState; 
+			/*if ( v21->pMonsterInfo.uHostilityType != MonsterInfo::Hostility_Friendly
+				&& (signed int)v21->pMonsterInfo.uRecoveryTime <= 0
+				&& v80 * 307.2 >= (double)(signed int)v75.uDistance
+				&& (uAIState == Pursuing || uAIState == Standing || uAIState == Tethered || uAIState == Fidgeting)
+				|| ( v21->pMonsterInfo.uMissleAttack1Type && uAIState == Stunned ) )
+			{
+				v32 = actor_id;
+			}
+			else
+			*/
+			if ( pActor->pMonsterInfo.uHostilityType == MonsterInfo::Hostility_Friendly
+				|| (signed int)pActor->pMonsterInfo.uRecoveryTime > 0
+				|| v80 * 307.2 < (double)(signed int)v75.uDistance
+				|| uAIState != Pursuing && uAIState != Standing && uAIState != Tethered && uAIState != Fidgeting
+				&&  !pActor->pMonsterInfo.uMissleAttack1Type || uAIState != Stunned )
+			{
+				if ( (signed int)pActor->uCurrentActionTime < pActor->uCurrentActionLength )
+				{
+					continue;
+				}
+				else if ( pActor->uAIState == AttackingMelee )
+				{
+					v35 = stru_50C198.special_ability_use_check(pActor, actor_id);
+					stru_50FE08.Add(
+						a1,
+						5120,
+						pActor->vPosition.x,
+						pActor->vPosition.y,
+						pActor->vPosition.z + ((signed int)pActor->uActorHeight >> 1),
+						v35,
+						1
+					);
+				}
+				else if ( pActor->uAIState == AttackingRanged1 )
+				{
+					v34 = pActor->pMonsterInfo.uMissleAttack1Type;
+					Actor::AI_RangedAttack(actor_id, &pDir, v34, 0);
+				}
+				else if ( pActor->uAIState == AttackingRanged2 )
+				{
+					v34 = pActor->pMonsterInfo.uMissleAttack2Type;
+					Actor::AI_RangedAttack(actor_id, &pDir, v34, 1);
+				}
+				else if ( pActor->uAIState == AttackingRanged3 )
+				{
+					v65 = pActor->pMonsterInfo.uSpellSkillAndMastery1;
+					v33 = pActor->pMonsterInfo.uSpell1ID;
+					Actor::AI_SpellAttack(actor_id, &pDir, v33, 2, v65);
+				}
+				else if ( pActor->uAIState == AttackingRanged4 )
+				{
+					v65 = pActor->pMonsterInfo.uSpellSkillAndMastery2;
+					v33 = pActor->pMonsterInfo.uSpell2ID;
+					Actor::AI_SpellAttack(actor_id, &pDir, v33, 3, v65);
+				}
+			}
+
+			v36 = v75.uDistance;
+			if ( pActor->pMonsterInfo.uHostilityType == MonsterInfo::Hostility_Friendly)
+			{
+				if ( target_pid_type == OBJECT_Actor )
+				{
+					v36 = v75.uDistance;
+					//v37 = (unsigned __int8)*(&byte_5C8D1A[89 * (pActor->pMonsterInfo.uID - 1) / 3]
+					//	+ (pActors[PID_ID(target_pid)].pMonsterInfo.uID - 1) / 3);
+                    v37 =pFactionTable->relations[(pActor->pMonsterInfo.uID-1) / 3 + 1][(pActors[PID_ID(target_pid)].pMonsterInfo.uID - 1) / 3 + 1];
+				}
+				else
+				{
+					v37 = 4;
+				}
+				v38=0;
+				if ( v37 == 2 )
+				{
+					//v39 = __OFSUB__(v36, 1024);
+					//v38 = ((v36 - 1024) & 0x80000000u) != 0;
+					v38 = 1024;
+				}
+				else if ( v37 == 3 )
+				{
+					//v39 = __OFSUB__(v36, 2560);
+					//v38 = ((v36 - 2560) & 0x80000000u) != 0;
+					v38 = 2560;
+				}
+				else if ( v37 == 4 )
+				{
+					//v39 = __OFSUB__(v36, 5120);
+					//v38 = ((v36 - 5120) & 0x80000000u) != 0;
+					v38 = 5120;
+				}
+				if ( v37 >= 1 && v37 <= 4 && v36 < v38  || v37 == 1 )
+					pActor->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Long;
+			}
+
+			if ( (signed __int64)pActor->pActorBuffs[4].uExpireTime > 0 )
+			{
+				if ( (signed int)v36 >= 10240 )
+				{
+					Actor::AI_4032B2(actor_id, target_pid, 1024, 0);
+				}
+				else
+				{
+					//peasents after attacked
+					//guard after attacked
+					Actor::AI_Flee(actor_id, target_pid, 0, &pDir);
+				}
+				continue;
+			}
+
+			if ( pActor->pMonsterInfo.uHostilityType == MonsterInfo::Hostility_Long && target_pid )
+			{
+
+				if ( pActor->pMonsterInfo.uAIType == 1 )
+				{
+					if ( pActor->pMonsterInfo.uMovementType == 5 )
+					{
+						Actor::AI_Stand(actor_id, target_pid, (signed __int64)((double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333),	&pDir);
+					}
+					else
+					{
+						Actor::AI_Flee(actor_id, target_pid, 0, &pDir);
+						continue;
+					}
+						
+				}
+				if ( !(pActor->uAttributes & 0x020000) )
+				{
+					if ( pActor->pMonsterInfo.uAIType == 2 || pActor->pMonsterInfo.uAIType == 3)
+					{
+						if ( pActor->pMonsterInfo.uAIType == 2 )
+							v43 = (double)(signed int)pActor->pMonsterInfo.uHP * 0.2;
+						if ( pActor->pMonsterInfo.uAIType == 3 )
+							v43 = (double)(signed int)pActor->pMonsterInfo.uHP * 0.1;
+						v84 = pActor->sCurrentHP;
+						v42 = (double)(signed int)v84;
+						if ( v43 > v42 && (signed int)v36 < 10240 )
+						{
+							Actor::AI_Flee(actor_id, target_pid, 0, &pDir);
+							continue;
+						}
+					}
+				}
+				
+				v81 = v36 - pActor->uActorRadius;
+				if ( target_pid_type == OBJECT_Actor )
+					v81 -= pActors[PID_ID(target_pid)].uActorRadius;
+				if ( v81 < 0 )
+					v81 = 0;
+				rand();
+				pActor->uAttributes &= 0xFFFBFFFF;
+				if ( v81 < 5120 )
+				{
+					v45 = stru_50C198.special_ability_use_check(pActor, actor_id);
+					if ( v45 == 0 )
+					{
+						if ( pActor->pMonsterInfo.uMissleAttack1Type )
+						{
+							if ( (signed int)pActor->pMonsterInfo.uRecoveryTime <= 0 )
+							{
+								Actor::AI_MissileAttack1(actor_id, target_pid, &pDir);
+							}
+							else if ( pActor->pMonsterInfo.uMovementType == 5 )
+							{
+								v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+								v64 = (signed __int64)v47;
+								Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
+							}
+							else
+							{
+								v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+								if ( v80 * 307.2 > (double)v81 )
+								{
+									v64 = (signed __int64)v47;
+									Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
+								}
+								else
+								{
+									Actor::AI_Pursue1(actor_id, target_pid, actor_id, (signed __int64)v47, &pDir);
+								}
+							}
+						}
+						else
+						{
+							if ( (double)v81 >= v80 * 307.2 )
+							{
+								if ( v81 >= 1024 )
+								{
+									if ( pActor->pMonsterInfo.uMovementType == 5 )
+									{
+										v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+										v64 = (signed __int64)v47;
+										Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
+									}
+									else
+									{
+										//monsters
+										Actor::AI_Pursue3(actor_id, target_pid, 0, &pDir);
+									}
+								}
+								else if ( pActor->pMonsterInfo.uMovementType == 5 )
+								{
+									v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+									v64 = (signed __int64)v47;
+									Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
+								}
+								else
+								{
+									v70 = (signed __int64)v80 * 307.2;
+									//monsters
+									//guard after player runs away
+									// follow player
+									Actor::AI_Pursue2(actor_id, target_pid, 0, &pDir, v70);
+								}
+							}
+							else if ( (signed int)pActor->pMonsterInfo.uRecoveryTime > 0 )
+							{
+								v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+								v64 = (signed __int64)v47;
+								Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
+							}
+							else
+							{
+								//monsters
+								Actor::AI_MeleeAttack(actor_id, target_pid, &pDir);
+							}
+						}
+						continue;
+					}
+					else if ( v45 == 2 || v45 == 3 )
+					{
+						if ( v45 == 2 )
+							v46 = pActor->pMonsterInfo.uSpell1ID;
+						else
+							v46 = pActor->pMonsterInfo.uSpell2ID;
+						if ( v46 )
+						{
+							if ( (signed int)pActor->pMonsterInfo.uRecoveryTime <= 0 )
+							{
+								if ( v45 == 2 )
+									Actor::AI_SpellAttack1(actor_id, target_pid, &pDir);
+								else
+									Actor::AI_SpellAttack2(actor_id, target_pid, &pDir);
+							}
+							else if ( v80 * 307.2 > (double)v81 || pActor->pMonsterInfo.uMovementType == 5 )
+							{
+								v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+								v64 = (signed __int64)v47;
+								Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
+							}
+							else
+							{
+								v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+								Actor::AI_Pursue1(actor_id, target_pid, actor_id, (signed __int64)v47, &pDir);
+							}
+						}
+						else
+						{
+							if ( (double)v81 >= v80 * 307.2 )
+							{
+								if ( v81 >= 1024 )
+								{
+									if ( pActor->pMonsterInfo.uMovementType == 5 )
+									{
+										v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+										v64 = (signed __int64)v47;
+										Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
+									}
+									else
+									{
+										Actor::AI_Pursue3(actor_id, target_pid, 256, &pDir);
+									}
+								}
+								else if ( pActor->pMonsterInfo.uMovementType == 5 )
+								{
+									v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+									v64 = (signed __int64)v47;
+									Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
+								}
+								else
+								{
+									v70 = (signed __int64)v80 * 307.2;
+									Actor::AI_Pursue2(actor_id, target_pid, 0, &pDir, v70);
+								}
+							}
+							else if ( (signed int)pActor->pMonsterInfo.uRecoveryTime > 0 )
+							{
+								v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+								v64 = (signed __int64)v47;
+								Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
+							}
+							else
+							{
+								Actor::AI_MeleeAttack(actor_id, target_pid, &pDir);
+							}
+						}
+						continue;
+					}
+				}
+			}
+			
+			if ( pActor->pMonsterInfo.uHostilityType != MonsterInfo::Hostility_Long || !target_pid || v81 >= 5120 || v45 != 1 )
+			{
+				if ( !pActor->pMonsterInfo.uMovementType )
+				{
+					Actor::AI_4032B2(actor_id, 4, 1024, 0);
+				}
+				else if ( pActor->pMonsterInfo.uMovementType == 1 )
+				{
+					Actor::AI_4032B2(actor_id, 4, 2560, 0);
+				}
+				else if ( pActor->pMonsterInfo.uMovementType == 2 )
+				{
+					Actor::AI_4032B2(actor_id, 4, 5120, 0);
+				}
+				else if ( pActor->pMonsterInfo.uMovementType == 4 )
+				{
+					Actor::AI_4032B2(actor_id, 4, 10240, 0);
+				}
+				else if ( pActor->pMonsterInfo.uMovementType == 5 )
+				{
+					v57 = Actor::GetDirectionInfo(a1, 4u, &v72, 0);
+					v58 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+					memcpy(&v74, v57, sizeof(v74));
+					memcpy(&pDir, &v74, sizeof(pDir));
+					v64 = (signed __int64)v58;
+					Actor::AI_Stand(actor_id, 4, v64, &pDir);
+				}				
+			}
+			else if ( !pActor->pMonsterInfo.uMissleAttack2Type )
+			{
+				if ( (double)v81 >= v80 * 307.2 )
+				{
+					if ( v81 >= 1024 )
+					{
+						if ( pActor->pMonsterInfo.uMovementType == 5 )
+						{
+							v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+							v64 = (signed __int64)v47;
+							Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
+						}
+						else
+						{
+							Actor::AI_Pursue3(actor_id, target_pid, 256, &pDir);
+						}
+					}
+					else if ( pActor->pMonsterInfo.uMovementType == 5 )
+					{
+						v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+						v64 = (signed __int64)v47;
+						Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
+					}
+					else
+					{
+						v70 = (signed __int64)v80 * 307.2;
+						Actor::AI_Pursue2(actor_id, target_pid, 0, &pDir, v70);
+					}
+				}
+				else if ( (signed int)pActor->pMonsterInfo.uRecoveryTime > 0 )
+				{
+					v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+					v64 = (signed __int64)v47;
+					Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
+				}
+				else
+				{
+					Actor::AI_MeleeAttack(actor_id, target_pid, &pDir);
+				}
+			}
+			else if ( (signed int)pActor->pMonsterInfo.uRecoveryTime > 0 )
+			{
+				v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+				if ( v80 * 307.2 > (double)v81 || pActor->pMonsterInfo.uMovementType == 5 )
+				{
+					v64 = (signed __int64)v47;
+					Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
+				}
+				else
+				{
+					Actor::AI_Pursue1(actor_id, target_pid, actor_id, (signed __int64)v47, &pDir);
+				}
+			}
+			else
+			{
+				Actor::AI_MissileAttack2(actor_id, target_pid, &pDir);
+			}		
+		}
+	}
+}
+//----- (0044665D) --------------------------------------------------------
+// uType:     0 -> any monster
+//            1 -> uParam is GroupID
+//            2 -> uParam is MonsterID
+//            3 -> uParam is ActorID
+// uNumAlive: 0 -> all must be alive
+int __fastcall IsActorAlive(unsigned int uType, unsigned int uParam, unsigned int uNumAlive)
+{
+  unsigned int uAliveActors; // eax@6
+  int v5; // ecx@10
+  unsigned int uTotalActors; // [sp+0h] [bp-4h]@1
+
+  uTotalActors = 0;
+  if ( uType )
+  {
+    if ( uType == 1 )
+    {
+      uAliveActors = SearchActorByGroup(&uTotalActors, uParam);
+    }
+    else
+    {
+      if ( uType == 2 )
+      {
+        uAliveActors = SearchActorByMonsterID(&uTotalActors, uParam);
+      }
+      else
+      {
+        if ( uType != 3 )
+          return 0;
+        uAliveActors = SearchActorByID(&uTotalActors, uParam);
+      }
+    }
+  }
+  else
+  {
+    uAliveActors = SearchAliveActors(&uTotalActors);
+  }
+  v5 = 0;
+  if ( uNumAlive )
+    LOBYTE(v5) = (signed int)uAliveActors >= (signed int)uNumAlive;
+  else
+    LOBYTE(v5) = uTotalActors == uAliveActors;
+  return v5;
+}
+//----- (00408B54) --------------------------------------------------------
+unsigned int __fastcall SearchActorByID(unsigned int *pTotalActors, unsigned int a2)
+{
+  unsigned int v2; // edi@1
+  unsigned int *v3; // esi@1
+  int v4; // eax@1
+  unsigned int v5; // ebx@1
+  unsigned int v6; // edx@1
+
+  v2 = a2;
+  v3 = pTotalActors;
+  v4 = GetAlertStatus();
+  v5 = 0;
+  *v3 = 0;
+  v6 = pActors[v2].uAttributes;
+  if ( (v6 & 0x100000) == v4 )
+  {
+    *v3 = 1;
+    if ( pActors[v2].IsNotAlive() == 1 )
+      v5 = 1;
+  }
+  return v5;
+}
+//----- (00408AE7) --------------------------------------------------------
+unsigned int __fastcall SearchActorByGroup(unsigned int *pTotalActors, unsigned int uGroup)
+{
+  unsigned int *v2; // esi@1
+  signed int v3; // ebx@1
+  Actor *v4; // edi@2
+  int v5; // eax@3
+  unsigned int v7; // [sp+8h] [bp-Ch]@1
+  int v8; // [sp+Ch] [bp-8h]@1
+  unsigned int v9; // [sp+10h] [bp-4h]@1
+
+  v7 = uGroup;
+  v2 = pTotalActors;
+  v3 = 0;
+  v8 = GetAlertStatus();
+  *v2 = 0;
+  v9 = 0;
+  if ( (signed int)uNumActors > 0 )
+  {
+    v4 = pActors.data();//[0].uGroup;
+    do
+    {
+	  v5 = v4->uAttributes;
+      if ( (v5 & 0x100000) == v8 )
+      {
+		if ( v4->uGroup == v7 )
+        {
+          ++*v2;
+          if ( v4->IsNotAlive() == 1 )
+            ++v9;
+        }
+      }
+      ++v3;
+      ++v4;
+    }
+    while ( v3 < (signed int)uNumActors );
+  }
+  return v9;
+}
+//----- (00408A7E) --------------------------------------------------------
+unsigned int __fastcall SearchActorByMonsterID(unsigned int *pTotalActors, int uMonsterID)
+{
+  unsigned int *v2; // esi@1
+  signed int v3; // ebx@1
+  Actor *v4; // edi@2
+  int v5; // eax@3
+  int v7; // [sp+8h] [bp-Ch]@1
+  int v8; // [sp+Ch] [bp-8h]@1
+  unsigned int v9; // [sp+10h] [bp-4h]@1
+
+  v7 = uMonsterID;
+  v2 = pTotalActors;
+  v3 = 0;
+  v8 = GetAlertStatus();
+  *v2 = 0;
+  v9 = 0;
+  if ( (signed int)uNumActors > 0 )
+  {
+    v4 = pActors.data();//[0].pMonsterInfo.uID;
+    do
+    {
+	  v5 = v4->uAttributes;                // actor::attributes
+      if ( (v5 & 0x100000) == v8 )
+      {
+		if ( v4->pMonsterInfo.field_33 == v7 )
+        {
+          ++*v2;
+          if ( v4->IsNotAlive() == 1 )
+            ++v9;
+        }
+      }
+      ++v3;
+      ++v4;
+    }
+    while ( v3 < (signed int)uNumActors );
+  }
+  return v9;
+}
+//----- (00408A27) --------------------------------------------------------
+unsigned int __thiscall SearchAliveActors(unsigned int *pTotalActors)
+{
+  unsigned int *v1; // esi@1
+  int v2; // eax@1
+  unsigned int v3; // ebp@1
+  signed int v4; // ebx@1
+  Actor *v5; // edi@2
+  unsigned int v6; // eax@3
+  int v8; // [sp+Ch] [bp-4h]@1
+
+  v1 = pTotalActors;
+  v2 = GetAlertStatus();
+  v3 = 0;
+  v4 = 0;
+  *v1 = 0;
+  v8 = v2;
+  if ( (signed int)uNumActors > 0 )
+  {
+    v5 = pActors.data();
+    do
+    {
+      v6 = v5->uAttributes;
+      if ( (v6 & 0x100000) == v8 )
+      {
+        ++*v1;
+        if ( v5->IsNotAlive() == 1 )
+          ++v3;
+      }
+      ++v4;
+      ++v5;
+    }
+    while ( v4 < (signed int)uNumActors );
+  }
+  return v3;
+}
+//----- (00408768) --------------------------------------------------------
+void InitializeActors()
+{
+  signed int v5; // [sp+Ch] [bp-10h]@1
+  signed int v6; // [sp+10h] [bp-Ch]@1
+  signed int v7; // [sp+14h] [bp-8h]@1
+  signed int v8; // [sp+18h] [bp-4h]@1
+
+  v8 = 0;
+  v6 = 0;
+  v7 = 0;
+  v5 = 0;
+  if ( !_stricmp(pCurrentMapName.data(), "d25.blv") )
+    v8 = 1;
+  if ( !_stricmp(pCurrentMapName.data(), "d26.blv") )
+    v6 = 1;
+  if (_449B57_test_bit(pParty->_quest_bits, 99))
+    v7 = 1;
+  if (_449B57_test_bit(pParty->_quest_bits, 100))
+    v5 = 1;
+
+  Log::Warning(L"%S %S %u", __FILE__, __FUNCTION__, __LINE__); // ai_near_actors_targets_pid[i] for AI_Stand seems always 0;  original code behaviour is identical
+  for (uint i = 0; i < uNumActors; ++i)
+  {
+    auto actor = &pActors[i];
+
+    if (actor->CanAct() || actor->uAIState == Disabled)
+    {
+      actor->vPosition.x = actor->vInitialPosition.x;
+      actor->vPosition.y = actor->vInitialPosition.y;
+      actor->vPosition.z = actor->vInitialPosition.z;
+      actor->sCurrentHP = actor->pMonsterInfo.uHP;
+      if (actor->uAIState != Disabled)
+      {
+        Actor::AI_Stand(i, ai_near_actors_targets_pid[i], actor->pMonsterInfo.uRecoveryTime, 0);
+      }
+    }
+
+    actor->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly;
+
+    if (!v8 || v7)
+      if (!v6 || v5)
+        if (actor->IsPeasant())
+          BYTE2(actor->uAttributes) &= 0xF7u;
+
+    BYTE2(actor->uAttributes) &= 0x7Fu;
+    if (BYTE2(actor->uAttributes) & 0x40)
+        Actor::_4031C1_update_job(i, pParty->uCurrentHour, 1);
+  }
+}
+//----- (00439474) --------------------------------------------------------
+void DamageMonsterFromParty(signed int a1, unsigned int uActorID_Monster, Vec3_int_ *pVelocity)
+{
+  //signed int v3; // eax@1
+  SpriteObject *v4; // ebx@1
+  //int v5; // edx@3
+  //bool uPlayerID; // eax@3
+  //Player *pPlayer; // edi@4
+  Actor *pMonster; // esi@7
+  //SpriteObject *v9; // ebx@12
+  int v10; // eax@12
+  int v11; // ebx@12
+  unsigned int v12; // ecx@12
+  int v13; // edx@15
+  int v14; // edx@17
+  int v15; // eax@24
+  unsigned __int16 v16; // cx@25
+  int v17; // eax@29
+  int v18; // eax@38
+  unsigned __int8 v19; // zf@38
+  unsigned __int8 v20; // sf@38
+  int v21; // edx@44
+  int v22; // eax@44
+  unsigned __int8 v23; // zf@44
+  unsigned __int8 v24; // sf@44
+  int v25; // edx@51
+  int v26; // ecx@51
+  //signed int v27; // eax@51
+  //int v28; // eax@53
+  signed int v29; // eax@76
+  signed int v30; // eax@84
+  signed int v31; // eax@92
+  int v32; // eax@94
+  int v33; // eax@100
+  int v34; // eax@104
+  signed int v35; // eax@104
+  double v36; // st7@104
+  float v37; // ST08_4@104
+  float v38; // ST04_4@104
+  float v39; // ST00_4@104
+  int v40; // ebx@107
+  unsigned int v41; // ebx@109
+  signed __int64 v42; // qax@125
+  unsigned __int16 v43; // ax@132
+  char v44; // bl@132
+  unsigned __int16 v45; // ax@132
+  unsigned __int64 v46; // [sp+Ch] [bp-60h]@6
+  const char *v47; // [sp+14h] [bp-58h]@104
+  char *pPlayerName; // [sp+18h] [bp-54h]@12
+  char *pMonsterName; // [sp+1Ch] [bp-50h]@6
+  int v50; // [sp+20h] [bp-4Ch]@6
+  //unsigned __int64 *v51; // [sp+30h] [bp-3Ch]@6
+  int v52; // [sp+34h] [bp-38h]@12
+  //int v53; // [sp+38h] [bp-34h]@10
+  //int v54; // [sp+3Ch] [bp-30h]@1
+  //int v55; // [sp+40h] [bp-2Ch]@12
+  signed int a4; // [sp+44h] [bp-28h]@1
+  PlayerEquipment *v57; // [sp+48h] [bp-24h]@10
+  //int v58; // [sp+4Ch] [bp-20h]@10
+  int v59; // [sp+50h] [bp-1Ch]@1
+  unsigned int uActorID_Monster_; // [sp+54h] [bp-18h]@1
+  int v61; // [sp+58h] [bp-14h]@1
+  bool v62; // [sp+5Ch] [bp-10h]@1
+  int uDamageAmount; // [sp+60h] [bp-Ch]@1
+  int a2; // [sp+64h] [bp-8h]@27
+  int a3; // [sp+6Bh] [bp-1h]@6
+
+  //v3 = a1;
+  v4 = 0;
+  uActorID_Monster_ = uActorID_Monster;
+  //v54 = a1;
+  uDamageAmount = 0;
+  a4 = 0;
+  v61 = 0;
+  v59 = 0;
+  v62 = 0;
+  if ( PID_TYPE(a1) == OBJECT_Item)
+  {
+    v4 = &pSpriteObjects[PID_ID(a1)];
+    //uDamageAmount = (int)v4;
+    v61 = v4->field_60_distance_related_prolly_lod;
+    a1 = v4->spell_caster_pid;
+    //v54 = v4->field_58_pid;
+  }
+  //v5 = a1 & 7;
+  //uPlayerID = a1 >> 3;
+  if (PID_TYPE(a1) != OBJECT_Player)
+    return;
+
+  assert(PID_ID(abs(a1)) < 4);
+  auto player = &pParty->pPlayers[PID_ID(a1)];
+  pMonster = &pActors[uActorID_Monster_];
+  //uPlayerID = pMonster->IsAlive();
+  if (pMonster->IsNotAlive())
+    return;
+
+  BYTE1(pMonster->uAttributes) |= 0xC0u;
+  if ( pMonster->uAIState == Fleeing )
+    pMonster->uAttributes |= 0x20000u;
+  //v57 = 0;
+  //v53 = 0;
+  //v58 = 0;
+  bool hit_will_stun = false,
+       hit_will_paralyze = false;
+  if ( !v4 )
+  {
+    //v51 = (unsigned __int64 *)player->pEquipment.uMainHand;
+    int main_hand_idx = player->pEquipment.uMainHand;
+    v59 = 1;
+    if ( player->HasItemEquipped(EQUIP_MAIN_HAND) )
+    {
+      auto main_hand_skill = pItemsTable->pItems[player->pInventoryItems[main_hand_idx - 1].uItemID].uSkillType;
+      //v55 = pItemsTable->pItems[player->pInventoryItems[main_hand_idx - 1].uItemID].uSkillType;
+      //v28 = SkillToMastery(player->pActiveSkills[v55]);
+      auto main_hand_mastery = SkillToMastery(player->pActiveSkills[main_hand_skill]);
+      //uDamageAmount = v28;
+      switch (main_hand_skill)
+      {
+        case PLAYER_SKILL_STAFF:
+          if (main_hand_mastery >= 3)
+          {
+            if (rand() % 100 < (player->GetActualSkillLevel(PLAYER_SKILL_STAFF) & 0x3F))  // stun chance when mastery >= 3
+              hit_will_stun = true;
+          }
+        break;
+
+        case PLAYER_SKILL_MACE:
+          if (main_hand_mastery >= 3)
+          {
+            if (rand() % 100 < (player->GetActualSkillLevel(PLAYER_SKILL_MACE) & 0x3F))
+              hit_will_stun = true;
+          }
+          if (main_hand_mastery >= 4)
+          {
+            if (rand() % 100 < (player->GetActualSkillLevel(PLAYER_SKILL_MACE) & 0x3F))
+              hit_will_paralyze = true;
+          }
+        break;
+      }
+    }
+    v50 = pMonster->pMonsterInfo.uID;
+    a2 = 4;
+    //v27 = player->CalculateMeleeDamageTo(0, 0, v50);
+    uDamageAmount = player->CalculateMeleeDamageTo(0, 0, v50);
+    //if ( !v57 )
+      goto LABEL_67;
+    //goto LABEL_69;
+  }
+
+
+  v19 = v4->spell_id == SPELL_DARK_SOULDRINKER;
+  v61 = v4->field_60_distance_related_prolly_lod;
+  if ( !v19 )
+  {
+    //v9 = (SpriteObject *)uDamageAmount;
+	v50 = pParty->vPosition.x - v4->vPosition.x;
+    //v55 = abs(v50);
+    pMonsterName = (char *)(pParty->vPosition.y - v4->vPosition.y);
+    //v51 = (unsigned __int64 *)abs((int)pMonsterName);
+    pPlayerName = (char *)(pParty->vPosition.z - v4->vPosition.z);
+    v52 = abs((int)pPlayerName);
+    v61 = abs(v50);
+    v10 = abs(v50);
+    v11 = (int)abs((int)pMonsterName);
+    v12 = v52;
+    if ( v10 < v11)
+    {
+      v10 = (int)v11;
+      v11 = v10;
+    }
+    if ( v10 < v52 )
+    {
+      v13 = v10;
+      v10 = v52;
+      v12 = v13;
+    }
+    if ( v11 < (signed int)v12 )
+    {
+      v14 = v12;
+      v12 = v11;
+      v11 = v14;
+    }
+    //uPlayerID = ((unsigned int)(11 * v11) >> 5) + (v12 >> 2) + v10;
+    v61 = ((unsigned int)(11 * v11) >> 5) + (v12 >> 2) + v10;
+    if ( v61 >= 2560 )
+    {
+      if ( v61 >= 5120 && !(BYTE1(pMonster->uAttributes) & 4) )
+        return;
+      v61 = 2;
+    }
+    else
+    {
+      v61 = 1;
+    }
+    //v4 = (SpriteObject *)uDamageAmount;
+  }
+
+  v15 = v4->spell_id;
+  if ( v15 == SPELL_LASER_PROJECTILE )
+  {
+    v16 = player->pActiveSkills[7];
+    v61 = 1;
+    if ( (signed int)SkillToMastery(v16) >= 3 )
+      a4 = player->pActiveSkills[7] & 0x3F;
+    a2 = 4;
+    uDamageAmount = player->CalculateMeleeDamageTo(1, 1, 0);
+    goto LABEL_67;
+  }
+  if ( v15 != SPELL_BOW_ARROW )
+  {
+    if ( v15 == SPELL_101 )
+    {
+      a2 = 0;
+      v18 = player->CalculateRangedDamageTo(0);
+      v19 = HIDWORD(pMonster->pActorBuffs[15].uExpireTime) == 0;
+      v20 = SHIDWORD(pMonster->pActorBuffs[15].uExpireTime) < 0;
+      uDamageAmount = v18;
+      if ( !v20 && (!(v20 | v19) || LODWORD(pMonster->pActorBuffs[15].uExpireTime)) )
+        uDamageAmount >>= 1;
+      v59 = 1;
+      goto LABEL_67;
+    }
+    if ( v15 == SPELL_EARTH_BLADES )
+    {
+      a4 = 5 * v4->spell_level;
+      a2 = player->GetSpellSchool(0x27u);
+      v21 = v4->spell_level;
+      v50 = pMonster->sCurrentHP;
+      pMonsterName = (char *)v4->spell_skill;
+      v22 = _43AFE3_calc_spell_damage(39, v21, v4->spell_skill, v50);
+      v23 = HIDWORD(pMonster->pActorBuffs[15].uExpireTime) == 0;
+      v24 = SHIDWORD(pMonster->pActorBuffs[15].uExpireTime) < 0;
+      uDamageAmount = v22;
+      if ( !v24 && (!(v24 | v23) || LODWORD(pMonster->pActorBuffs[15].uExpireTime)) )
+        uDamageAmount >>= 1;
+      v59 = 0;
+LABEL_67:
+      if ( !stru_50C198.PlayerHitOrMiss(player, pMonster, v61, a4) )
+      {
+//LABEL_68:
+        player->PlaySound(SPEECH_52, 0);
+        return;
+      }
+      goto LABEL_69;
+    }
+    if ( v15 == SPELL_EARTH_STUN )
+    {
+      uDamageAmount = 0;
+      a2 = 4;
+      hit_will_stun = 1;
+      goto LABEL_67;
+    }
+    a2 = player->GetSpellSchool(v4->spell_id);
+    v25 = v4->spell_level;
+    v26 = v4->spell_id;
+    v50 = pMonster->sCurrentHP;
+    pMonsterName = (char *)v4->spell_skill;
+    //v27 = _43AFE3_calc_spell_damage(v26, v25, (signed int)pMonsterName, v50);
+    v59 = 0;
+    //v57 = (PlayerEquipment *)1;
+//LABEL_65:
+    uDamageAmount = _43AFE3_calc_spell_damage(v26, v25, v4->spell_skill, v50);
+    //if ( !v57 )
+    //  goto LABEL_67;
+    goto LABEL_69;
+  }
+  v50 = pMonster->word_000086_some_monster_id;
+  a2 = 4;
+  v17 = player->CalculateRangedDamageTo(v50);
+  v19 = v4->stru_24.uItemID == 0;
+  uDamageAmount = v17;
+  v57 = 0;
+  if ( !v19 && v4->stru_24.uSpecEnchantmentType == 3 )
+  {
+    a2 = 0;
+    v57 = (PlayerEquipment *)1;
+  }
+  if ( SHIDWORD(pMonster->pActorBuffs[15].uExpireTime) >= 0
+    && (SHIDWORD(pMonster->pActorBuffs[15].uExpireTime) > 0 || LODWORD(pMonster->pActorBuffs[15].uExpireTime)) )
+    uDamageAmount >>= 1;
+  v59 = 1;
+//LABEL_66:
+  if ( !v57 )
+    goto LABEL_67;
+LABEL_69:
+  if (player->Weak())
+    uDamageAmount /= 1;
+  if ( (signed __int64)pMonster->pActorBuffs[5].uExpireTime > 0 )
+    uDamageAmount = 0;
+  v61 = stru_50C198.CalcMagicalDamageToActor(pMonster, a2, uDamageAmount);
+  if ( !v4 && player->IsUnarmed() && (signed __int64)player->pPlayerBuffs[6].uExpireTime > 0 )
+  {
+    v50 = player->pPlayerBuffs[6].uPower;
+    v29 = stru_50C198.CalcMagicalDamageToActor(pMonster, 8, v50);
+    v61 += v29;
+  }
+  uDamageAmount = v61;
+  if ( v59 )
+  {
+    if ( v4 )
+    {
+      a4 = v4->stru_24._439DF3_get_additional_damage(&a2, &v62);
+      if ( v62 && pMonster->sCurrentHP > 0 )
+      {
+        player->sHealth += v61 / 5;
+        if ( player->sHealth > player->GetMaxHealth() )
+          player->sHealth = player->GetMaxHealth();
+        v62 = 0;
+      }
+      v30 = stru_50C198.CalcMagicalDamageToActor(pMonster, a2, a4);
+      uDamageAmount = v61 + v30;
+    }
+    else
+    {
+      v59 = 0;
+      v57 = &player->pEquipment;
+      do
+      {
+        if ( player->HasItemEquipped((ITEM_EQUIP_TYPE)v59) )
+        {
+          auto _s = (ItemGen *)&player->pInventoryItems[v57->uShield - 1];
+          a4 = _s->_439DF3_get_additional_damage(&a2, &v62);
+          if ( v62 && pMonster->sCurrentHP > 0 )
+          {
+            player->sHealth += v61 / 5;
+            if ( player->sHealth > player->GetMaxHealth() )
+              player->sHealth = player->GetMaxHealth();
+            v62 = 0;
+          }
+          v31 = stru_50C198.CalcMagicalDamageToActor(pMonster, a2, a4);
+          uDamageAmount += v31;
+        }
+        ++v59;
+        v57 = (PlayerEquipment *)((char *)v57 + 4);
+      }
+      while ( v59 <= 1 );
+    }
+  }
+  v32 = uDamageAmount;
+  pMonster->sCurrentHP -= uDamageAmount;
+  if ( !v32 && !hit_will_stun )
+  {
+    player->PlaySound(SPEECH_52, 0);
+    return;
+  }
+  if ( pMonster->sCurrentHP > 0 )
+  {
+    Actor::AI_Stun(uActorID_Monster_, a1, 0);
+    Actor::AggroSurroundingPeasants(uActorID_Monster_, 1);
+    if ( bShowDamage )
+    {
+      v50 = uDamageAmount;
+      pMonsterName = (char *)pMonster;
+      pPlayerName = player->pName;
+      if ( v4 )
+        v47 = pGlobalTXT_LocalizationStrings[189];// "%s shoots %s for %lu points"
+      else
+        v47 = pGlobalTXT_LocalizationStrings[164];// "%s hits %s for %lu damage"
+      sprintfex(pTmpBuf.data(), v47, pPlayerName, pMonsterName, v50);
+      ShowStatusBarString(pTmpBuf.data(), 2u);
+    }
+    v41 = 0;
+  }
+  else
+  {
+    if ( pMonsterStats->pInfos[pMonster->pMonsterInfo.uID].bQuestMonster & 1 )
+    {
+      v33 = byte_4D864C && BYTE2(pGame->uFlags) & 8 ? 10 * pMonster->uActorRadius : pMonster->uActorRadius;
+      //v55 = v33;
+      if ( pRenderer->pRenderD3D )
+      {
+        if ( pGame->uFlags2 & GAME_FLAGS_2_DRAW_BLOODSPLATS )
+        {
+          v50 = 0;
+          pMonsterName = 0;
+          v34 = pMonster->vPosition.z;
+          *(float *)&pPlayerName = (double)v33;
+          //v51 = (unsigned __int64 *)v34;
+          *(float *)&v47 = 0.0;
+          v35 = pMonster->vPosition.y;
+          *((float *)&v46 + 1) = 0.0;
+          *(float *)&v46 = 1.0;
+          v36 = (double)(signed int)pMonster->vPosition.z;
+          //v51 = (unsigned __int64 *)v35;
+          v37 = v36;
+          //v51 = (unsigned __int64 *)pMonster->vPosition.x;
+          v38 = (double)v35;
+          v39 = (double)(signed int)pMonster->vPosition.x;
+          pDecalBuilder->AddBloodsplat(v39, v38, v37, 1.0, 0.0, 0.0, *(float *)&pPlayerName, 0, 0);
+        }
+      }
+    }
+    Actor::Die(uActorID_Monster_);
+    Actor::ApplyFineForKillingPeasant(uActorID_Monster_);
+    Actor::AggroSurroundingPeasants(uActorID_Monster_, 1);
+    if ( pMonster->pMonsterInfo.uExp )
+      GivePartyExp(pMonsterStats->pInfos[pMonster->pMonsterInfo.uID].uExp);
+    v40 = SPEECH_51;
+    if ( rand() % 100 < 20 )
+      v40 = ((signed int)pMonster->pMonsterInfo.uHP >= 100) + 1;
+    player->PlaySound((PlayerSpeech)v40, 0);
+    v41 = 0;
+    if ( bShowDamage )
+    {
+      v50 = (int)pMonster;
+      pMonsterName = (char *)uDamageAmount;
+      pPlayerName = player->pName;             // "%s inflicts %lu points killing %s"
+      sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[175], player->pName, uDamageAmount, pMonster);
+      ShowStatusBarString(pTmpBuf.data(), 2u);
+    }
+  }
+  if ( SHIDWORD(pMonster->pActorBuffs[20].uExpireTime) >= (signed int)v41
+    && (SHIDWORD(pMonster->pActorBuffs[20].uExpireTime) > (signed int)v41
+     || LODWORD(pMonster->pActorBuffs[20].uExpireTime) > v41)
+    && uDamageAmount != v41 )
+    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)
+    && stru_50C198.GetMagicalResistance(pMonster, 3u) )
+  {
+    LODWORD(v42) = 20;
+    v59 = 10;
+    if ( pParty->bTurnBasedModeOn == v41 )
+      v42 = (signed __int64)(flt_6BE3A8_debug_recmod2 * 42.66666666666666);
+    pMonster->pMonsterInfo.uRecoveryTime += v42;
+    if ( bShowDamage != v41 )
+    {
+      v50 = (int)pMonster;
+      pMonsterName = player->pName;            // "%s stuns %s"
+      sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[635], player->pName, pMonster);
+      ShowStatusBarString(pTmpBuf.data(), 2u);
+    }
+  }
+  if ( hit_will_paralyze != v41 )
+  {
+    if ( pMonster->CanAct() )
+    {
+      if ( stru_50C198.GetMagicalResistance(pMonster, 3) )
+      {
+        LOBYTE(v43) = player->GetActualSkillLevel(PLAYER_SKILL_MACE);
+        v44 = v43;
+        v45 = SkillToMastery(v43);
+        //v51 = (unsigned __int64 *)(7680 * (v44 & 0x3F));
+        v46 = pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)(7680 * (v44 & 0x3F)) * 0.033333335);
+        pMonster->pActorBuffs[6].Apply(v46, v45, 0, 0, 0);
+        if ( bShowDamage )
+        {
+          v50 = (int)pMonster;
+          pMonsterName = player->pName;        // "%s paralyzes %s"
+          sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[636], player->pName, pMonster);
+          ShowStatusBarString(pTmpBuf.data(), 2u);
+        }
+      }
+    }
+  }
+  if ( v59 > 10 )
+    v59 = 10;
+  if ( !MonsterStats::BelongsToSupertype(pMonster->pMonsterInfo.uID, MONSTER_SUPERTYPE_TREANT) )
+  {
+    pVelocity->x = (unsigned __int64)(v59 * (signed __int64)pVelocity->x) >> 16;
+    pVelocity->y = (unsigned __int64)(v59 * (signed __int64)pVelocity->y) >> 16;
+    pVelocity->z = (unsigned __int64)(v59 * (signed __int64)pVelocity->z) >> 16;
+    pMonster->vVelocity.x = 50 * LOWORD(pVelocity->x);
+    pMonster->vVelocity.y = 50 * LOWORD(pVelocity->y);
+    pMonster->vVelocity.z = 50 * LOWORD(pVelocity->z);
+  }
+  Actor::AddBloodsplatOnDamageOverlay(uActorID_Monster_, 1, v61);
+}
 //----- (004BBF61) --------------------------------------------------------
 void __fastcall _4BBF61_summon_actor(int a1, __int16 x, int y, int z)
 {
@@ -4057,60 +5531,4 @@
     while ( v13 );
     ++uNumActors;
   }
-}
-//----- (00450B0A) --------------------------------------------------------
-bool __fastcall SpawnActor(unsigned int uMonsterID)
-{
-  unsigned int v1; // ebx@1
-  bool result; // eax@2
-  MonsterDesc *v3; // esi@5
-  MonsterInfo *v4; // edi@5
-  Vec3_int_ v5; // ST08_12@5
-  unsigned int v6; // ecx@5
-  Actor *v7; // eax@7
-  Actor actor; // [sp+4h] [bp-350h]@5
-  Vec3_int_ pOut; // [sp+348h] [bp-Ch]@5
-
-  v1 = uMonsterID;
-  if ( uNumActors == 499 )
-  {
-    result = 0;
-  }
-  else
-  {
-    if ( (signed int)uMonsterID >= (signed int)pMonsterList->uNumMonsters )
-      v1 = 0;
-    v3 = &pMonsterList->pMonsters[v1];
-    v4 = &pMonsterStats->pInfos[v1 + 1];
-    memset(&actor, 0, 0x344u);
-    strcpy(actor.pActorName, v4->pName);
-    actor.sCurrentHP = LOWORD(v4->uHP);
-    memcpy(&actor.pMonsterInfo, &pMonsterStats->pInfos[v1 + 1], 0x58u);
-    actor.word_000086_some_monster_id = v1 + 1;
-    actor.uActorRadius = v3->uMonsterRadius;
-    actor.uActorHeight = v3->uMonsterHeight;
-    actor.uMovementSpeed = v3->uMovementSpeed;
-    v5 = pParty->vPosition;
-    Vec3_int_::Rotate(200, pParty->sRotationY, 0, v5, &pOut.x, &pOut.z, &pOut.y);
-    actor.vInitialPosition.x = pOut.x;
-    actor.vPosition.x = pOut.x;
-    actor.uTetherDistance = 256;
-    actor.vInitialPosition.y = LOWORD(pOut.z);
-    actor.vPosition.y = LOWORD(pOut.z);
-    actor.vInitialPosition.z = LOWORD(pOut.y);
-    actor.vPosition.z = LOWORD(pOut.y);
-    pSprites_LOD->DeleteSomeSprites();
-    pPaletteManager->ResetNonTestLocked();
-    v6 = uNumActors - 1;
-    if ( dword_5C6DF8 == 1 )
-    {
-      dword_5C6DF8 = 0;
-      v6 = uNumActors++;
-    }
-    v7 = &pActors[v6];
-    memcpy(v7, &actor, 0x344u);
-    v7->PrepareSprites(1);
-    result = 1;
-  }
-  return result;
 }
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CastSpellInfo.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -0,0 +1,4534 @@
+#include "CastSpellInfo.h"
+#include "Actor.h"
+#include "Party.h"
+#include "mm7_data.h"
+#include "MM7.h"
+#include "BSPModel.h"
+#include "Mouse.h"
+#include "stru6.h"
+#include "Game.h"
+#include "GUIWindow.h"
+#include "GUIFont.h"
+#include "AudioPlayer.h"
+#include "Outdoor.h"
+#include "Overlays.h"
+#include "Events.h"
+#include "Viewport.h"
+#include "Math.h"
+#include "SpriteObject.h"
+#include "ObjectList.h"
+#include "stru123.h"
+#include "Time.h"
+#include "IconFrameTable.h"
+#include "Awards.h"
+#include "TurnEngine.h"
+#include "texts.h"
+#include "LOD.h"
+
+//----- (00427E01) --------------------------------------------------------
+void CastSpellInfo::_427E01_cast_spell()
+{
+  int v2; // edi@1
+  CastSpellInfo *pCastSpell; // ebx@2
+  signed int v6; // eax@14
+  unsigned __int16 v11; // cx@45
+  unsigned __int8 v14; // zf@53
+  signed int i; // esi@76
+  __int16 v23; // ax@88
+  int v51; // eax@146
+  __int16 v52; // ax@153
+  signed __int64 v54; // qax@164
+  Actor *v55; // edi@164
+  signed __int64 v58; // qax@177
+  Actor *pActor; // edi@177
+  unsigned __int16 v60; // ax@184
+  int v61; // ecx@184
+  ItemGen *v69; // esi@211
+  double v90; // st7@245
+  Player *v92; // eax@255
+  int v105; // edi@271
+  __int16 v108; // ST1C_2@274
+  __int16 v109; // ST18_2@274
+  stru6 *v110; // eax@274
+  int v111; // eax@274
+  Actor *v112; // esi@278
+  int v113; // eax@278
+  int v114; // ebx@278
+  unsigned int v115; // ecx@278
+  int v116; // edx@279
+  int v117; // edx@281
+  int v118; // edx@283
+  signed int v122; // eax@286
+  int v127; // eax@296
+  int v153; // ecx@322
+  int v154; // eax@322
+  int v155; // eax@323
+  int v156; // eax@323
+  int v162; // edi@340
+  signed int v164; // eax@340
+  signed int v165; // edi@340
+  signed int v168; // edi@343
+  int v169; // eax@344
+  signed int v174; // edi@355
+  int v188; // esi@369
+  int v189; // edi@369
+  signed int v191; // edi@379
+  signed int v205; // edi@405
+  int v206; // eax@407
+  __int16 v207; // cx@407
+  int v208; // eax@411
+  signed int v209; // ecx@412
+  int v210; // edx@412
+  signed int v211; // ecx@412
+  int v212; // eax@413
+  int v213; // eax@413
+  int v214; // eax@413
+  int v215; // eax@415
+  double v216; // st7@415
+  double v217; // st6@415
+  signed __int64 v218; // qtt@423
+  char v223; // al@438
+
+  int v227; // esi@453
+  unsigned int v228; // edi@454
+  int v229; // edi@466
+
+  ItemGen *v240; // ecx@472
+  double v241; // st7@478
+  ItemGen *v245; // edi@492
+  int v254; // eax@513
+  int v255; // esi@513
+  int v256; // ecx@513
+  int v257; // edx@514
+  int v258; // ecx@514
+  char v259; // al@516
+  int v260; // eax@518
+  int v261; // esi@519
+  int v262; // edx@521
+  int *v263; // ecx@521
+  int v264; // esi@521
+  int v265; // edx@521
+  int *ii; // eax@522
+  int v267; // eax@524
+  int v268; // eax@524
+  char v271; // al@531
+  int v277; // edx@548
+  int v278; // ecx@548
+  char v279; // al@550
+  int v280; // eax@552
+  int *v281; // esi@553
+  int v282; // edx@555
+  int *v283; // ecx@555
+  int v284; // esi@555
+  int v285; // edx@555
+  int *l; // eax@556
+  ItemGen *v294; // esi@575
+  int v295; // edx@575
+  int kk; // edi@575
+  char v313; // al@606pGame->GetStru6()
+  const char *v317; // ecx@617
+  Player *v318; // ecx@619
+  unsigned int v319; // edi@627
+  int v323; // edi@635
+  char *v324; // eax@635
+  Player *v325; // ecx@640
+  int v328; // ecx@651
+  int v329; // ecx@652
+  int v330; // edi@654
+  signed int v342; // edi@668
+  signed int v343; // edi@670
+  unsigned __int64 v344; // ST08_8@670
+  Player *v351; // edi@680
+  Player *v357; // edi@694
+  Actor *v369; // edi@705
+  int v373; // eax@715
+  int v374; // eax@717
+  int v376; // eax@717
+  Player *v377; // ecx@719
+  int v381; // edi@727
+  int v382; // ecx@727
+  Player *v383; // eax@728
+  int v384; // eax@733
+  int v388; // edi@740
+  int v396; // eax@752
+  int v397; // eax@757
+  int v398; // eax@757
+  int v399; // eax@757
+  Actor *v417; // eax@787
+  int v418; // ecx@789
+  __int16 v419; // ax@791
+  signed int v420; // eax@793
+  ItemGen *v421; // edx@793
+  const char *v422; // eax@801
+  signed int v426; // eax@815
+  Actor *v433; // edi@832
+  int v435; // ecx@837
+  int v440; // eax@843
+  int v441; // eax@847
+  signed int v445; // edi@857
+  int v446; // ecx@862
+  LevelDecoration *v447; // edi@864
+  __int16 v448; // ax@864
+  char *v449; // esi@870
+  int v450; // eax@870
+  signed int v460; // eax@895
+  Actor *v461; // eax@897
+  unsigned __int16 v462; // cx@897
+  signed int v463; // edx@897
+  int v470; // edi@913
+  int v471; // eax@917
+  int v472; // eax@917
+  int v498; // edi@931
+  int v499; // eax@935
+  int v500; // eax@935
+  Player *v501; // edi@939
+  int v505; // eax@943
+  int v507; // edi@944
+  signed int v509; // eax@944
+  //signed int v510; // edi@944
+  Actor *v518; // edx@957
+  __int16 v519; // cx@958
+  int v531; // eax@982
+  int v533; // edi@983
+  signed int v535; // eax@983
+  signed int v536; // edi@983
+  stru6 *v537; // eax@984
+  double v549; // st7@991
+  unsigned __int16 v550; // di@991
+  Player *v553; // edi@1001
+  unsigned __int16 v562; // di@1005
+  signed int v563; // eax@1010
+  unsigned int v564; // ecx@1011
+  signed int v565; // eax@1012
+  Player **v566; // ecx@1012
+  int v567; // eax@1012
+  Player *v571; // eax@1013
+  char *v572; // ecx@1013
+  signed int v576; // eax@1025
+  Player *v577; // eax@1026
+  int v578; // eax@1028
+  __int16 v579; // ax@1029
+  int v581; // edi@1031
+  char *v585; // esi@1034
+  signed int v587; // eax@1035
+  char v591; // al@1048
+  ItemGen *v592; // esi@1052
+  int v596; // esi@1066
+  unsigned int v597; // edi@1067
+  int v600; // edi@1086
+  int v601; // edx@1086
+  int v602; // eax@1086
+  int v603; // ecx@1086
+  NPCData *pNPCData; // eax@1089
+  int v606; // edx@1091
+  AwardType *v607; // ecx@1100
+  __int16 v608; // ax@1102
+  signed int v609; // eax@1104
+  int v610; // edi@1106
+  unsigned int v611; // eax@1106
+  Player *v612; // edi@1106
+  DDM_DLV_Header *v613; // eax@1108
+  int v615; // edi@1119
+  Player *v619; // edi@1123
+  signed __int64 v623; // qax@1127
+  int v625; // edi@1129
+  signed int v627; // eax@1129
+  signed int v628; // edi@1129
+  int v629; // ecx@1130
+  Player *v630; // eax@1131
+  int v631; // eax@1137
+  int v635; // edi@1142
+  int v642; // edi@1156
+  int v643; // eax@1156
+  int v644; // eax@1156
+  signed int v645; // eax@1158
+  unsigned int v656; // [sp-4h] [bp-E88h]@639
+  int v657; // [sp-4h] [bp-E88h]@807
+  int v659; // [sp+0h] [bp-E84h]@123
+  int v660; // [sp+0h] [bp-E84h]@146
+  Actor *v661; // [sp+0h] [bp-E84h]@164
+  unsigned __int64 v663; // [sp+0h] [bp-E84h]@639
+  const char *v664; // [sp+0h] [bp-E84h]@802
+  int v665; // [sp+0h] [bp-E84h]@807
+  int v666; // [sp+4h] [bp-E80h]@12
+  PLAYER_SKILL_TYPE v667; // [sp+4h] [bp-E80h]@25
+  int v671; // [sp+4h] [bp-E80h]@146
+  int v675; // [sp+4h] [bp-E80h]@800
+  int v676; // [sp+4h] [bp-E80h]@807
+  int v677; // [sp+4h] [bp-E80h]@861
+  int v679[800]; // [sp+14h] [bp-E70h]@515
+  AIDirection a3; // [sp+C94h] [bp-1F0h]@21
+  int v681[4]; // [sp+CB0h] [bp-1D4h]@1137
+  int v682[4]; // [sp+CC0h] [bp-1C4h]@731
+  ItemGen v683; // [sp+CD0h] [bp-1B4h]@791
+  int v684; // [sp+D04h] [bp-180h]@416
+  unsigned __int64 v685; // [sp+D08h] [bp-17Ch]@416
+  unsigned __int64 v687; // [sp+D24h] [bp-160h]@327
+  Vec3_int_ v688; // [sp+D2Ch] [bp-158h]@943
+  Vec3_int_ v691; // [sp+D38h] [bp-14Ch]@137
+  Vec3_int_ v694; // [sp+D44h] [bp-140h]@982
+  Vec3_int_ v697; // [sp+D50h] [bp-134h]@129
+  Vec3_int_ v700; // [sp+D5Ch] [bp-128h]@339
+  Vec3_int_ v701; // [sp+D68h] [bp-11Ch]@286
+  Vec3_int_ v704; // [sp+D74h] [bp-110h]@132
+  Vec3_int_ v707; // [sp+D80h] [bp-104h]@1127
+  int v710; // [sp+D8Ch] [bp-F8h]@1156
+  __int64 v712; // [sp+D94h] [bp-F0h]@991
+  int v713; // [sp+D9Ch] [bp-E8h]@324
+  int n; // [sp+DA0h] [bp-E4h]@1
+  AIDirection v715; // [sp+DA4h] [bp-E0h]@21
+  int v716; // [sp+DC0h] [bp-C4h]@272
+  __int64 v717; // [sp+DC4h] [bp-C0h]@271
+  float v718; // [sp+DCCh] [bp-B8h]@176
+  signed int sRecoveryTime; // [sp+DD0h] [bp-B4h]@53
+  char *y; // [sp+DD4h] [bp-B0h]@325
+  int v721; // [sp+DD8h] [bp-ACh]@163
+  int v723; // [sp+E4Ch] [bp-38h]@1
+  ItemGen *_this; // [sp+E50h] [bp-34h]@23
+  float v725; // [sp+E54h] [bp-30h]@23
+  Player *v726; // [sp+E58h] [bp-2Ch]@131
+  float v727; // [sp+E5Ch] [bp-28h]@1
+  unsigned int uRequiredMana; // [sp+E60h] [bp-24h]@53
+  Player *pPlayer; // [sp+E64h] [bp-20h]@8
+  int v730; // [sp+E68h] [bp-1Ch]@53
+  Player *v730b;
+  ItemGen *v730c;
+  int v731; // [sp+E6Ch] [bp-18h]@48
+  signed int v732; // [sp+E70h] [bp-14h]@325
+  unsigned __int64 v733; // [sp+E74h] [bp-10h]@1
+  signed int a2; // [sp+E7Ch] [bp-8h]@14
+  int amount; // [sp+E80h] [bp-4h]@1
+
+  SpriteObject pSpellSprite; // [sp+DDCh] [bp-A8h]@1
+
+  v2 = 0;
+  amount = 0;
+  LODWORD(v733) = 0;
+  v723 = 0;
+  v727 = 0.0;
+  for(n = 0; n < 10; ++n)
+  {
+    pCastSpell = &this[n];
+    HIDWORD(v733) = (int)pCastSpell;
+    if ( pCastSpell->spellnum == 0 )
+      continue;
+
+    if (pParty->Invisible())
+      pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].Reset();
+
+    if ( pCastSpell->field_8 & 0x3CA )
+    {
+      if ( !pParty->pPlayers[pCastSpell->uPlayerID].CanAct() )
+        this->_427D48(1);
+      continue;
+    }
+    pPlayer = &pParty->pPlayers[pCastSpell->uPlayerID];
+
+    a2 = pCastSpell->spell_target_pid;
+    if (!pCastSpell->spell_target_pid)
+    {
+      if (pCastSpell->spellnum == SPELL_LIGHT_DESTROY_UNDEAD ||
+          pCastSpell->spellnum == SPELL_SPIRIT_TURN_UNDEAD ||
+          pCastSpell->spellnum == SPELL_DARK_CONTROL_UNDEAD )
+        v666 = 1;
+      else
+        v666 = 0;
+
+      a2 = stru_50C198.FindClosestActor(5120, 1, v666);
+      v6 = pMouse->uPointingObjectID;
+      if ( pMouse->uPointingObjectID && PID_TYPE(v6) == OBJECT_Actor && pActors[PID_ID(v6)].CanAct() )
+        a2 = pMouse->uPointingObjectID;
+    }
+
+
+    pSpellSprite.uType = stru_4E3ACC[pCastSpell->spellnum].uType;
+    if (pSpellSprite.uType)
+    {
+      if (PID_TYPE(a2) == OBJECT_Actor)
+      {
+        memcpy(&v715, Actor::GetDirectionInfo(PID(OBJECT_Player, pCastSpell->uPlayerID + 1), a2, &a3, 0), sizeof(v715));
+        v2 = v723;
+      }
+      else
+      {
+        v715.uYawAngle = pParty->sRotationY;
+        v715.uPitchAngle = pParty->sRotationX;
+      }
+    }
+
+    LODWORD(v725) = 0;
+    _this = 0;
+    if (pCastSpell->forced_spell_skill_level)
+    {
+      v11 = pCastSpell->forced_spell_skill_level;
+      v723 = v11 & 0x3F; // 6 bytes
+      v2 = v723;
+    }
+    else
+    {
+      //v667 = PLAYER_SKILL_STAFF;
+      if (pCastSpell->spellnum < SPELL_AIR_WIZARD_EYE)
+        v667 = PLAYER_SKILL_FIRE;
+      else if (pCastSpell->spellnum < SPELL_WATER_AWAKEN)
+        v667 = PLAYER_SKILL_AIR;
+      else if (pCastSpell->spellnum < SPELL_EARTH_STUN)
+        v667 = PLAYER_SKILL_WATER;
+      else if (pCastSpell->spellnum < SPELL_SPIRIT_DETECT_LIFE)
+        v667 = PLAYER_SKILL_EARTH;
+      else if (pCastSpell->spellnum < SPELL_MIND_REMOVE_FEAR)
+        v667 = PLAYER_SKILL_SPIRIT;
+      else if (pCastSpell->spellnum < SPELL_BODY_CURE_WEAKNESS)
+        v667 = PLAYER_SKILL_MIND;
+      else if (pCastSpell->spellnum < SPELL_LIGHT_LIGHT_BOLT)
+        v667 = PLAYER_SKILL_BODY;
+      else if (pCastSpell->spellnum < SPELL_DARK_REANIMATE)
+        v667 = PLAYER_SKILL_LIGHT;
+      else if (pCastSpell->spellnum < SPELL_BOW_ARROW)
+        v667 = PLAYER_SKILL_DARK;
+      else if (pCastSpell->spellnum == SPELL_BOW_ARROW)
+        v667 = PLAYER_SKILL_BOW;
+      else assert(false && "Unknown spell");
+
+      LODWORD(v725) = v667;
+      v723 = pPlayer->GetActualSkillLevel(v667) & 0x3F;
+      v2 = v723;
+      v11 = pPlayer->pActiveSkills[LODWORD(v725)];
+    }
+
+	v731 = SkillToMastery(v11);
+
+    if (pCastSpell->forced_spell_skill_level)
+      uRequiredMana = 0;
+    else 
+      uRequiredMana = pSpellDatas[pCastSpell->spellnum - 1].mana_per_skill[v731 - 1];
+    sRecoveryTime = pSpellDatas[pCastSpell->spellnum - 1].recovery_per_skill[v731 - 1];
+
+    if (LODWORD(v725) == PLAYER_SKILL_DARK && pParty->uCurrentHour == 0 && pParty->uCurrentMinute == 0 ||
+        LODWORD(v725) == PLAYER_SKILL_LIGHT && pParty->uCurrentHour == 12 && pParty->uCurrentMinute == 0)
+      uRequiredMana = 0;
+
+    if (pCastSpell->spellnum < SPELL_BOW_ARROW && pPlayer->sMana < uRequiredMana)
+    {
+      ShowStatusBarString(pGlobalTXT_LocalizationStrings[586], 2u); // "Not enough spell points"
+      pCastSpell->spellnum = 0;
+      continue;
+    }
+    v730 = pCastSpell->spellnum;
+    if (pPlayer->Cursed() && pCastSpell->spellnum < SPELL_BOW_ARROW && rand() % 100 < 50)
+    {
+      if (!pParty->bTurnBasedModeOn)
+      {
+        //v646 = pPlayer;
+        pPlayer->SetRecoveryTime((signed __int64)(flt_6BE3A4_debug_recmod1 * 213.3333333333333));
+        //v647 = n;
+      }
+      else
+      {
+        //v647 = n;
+        //v646 = pPlayer;
+        //v648 = sRecoveryTime;
+        //v649 = pPlayer;
+        pParty->pTurnBasedPlayerRecoveryTimes[this[n].uPlayerID] = 100;
+        pPlayer->SetRecoveryTime(sRecoveryTime);
+        pTurnEngine->_40471C();
+      }
+      ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2u); // "Spell failed"
+      pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+      this[n].spellnum = 0;
+      pPlayer->sMana -= uRequiredMana;
+      return;
+    }
+
+    switch ( pCastSpell->spellnum )
+    {
+		case SPELL_101:
+			assert(false && "Unknown spell effect #101 (prolly flaming bow arrow");
+		case SPELL_BOW_ARROW:
+		{
+			amount = 1;
+			if ( SkillToMastery(pPlayer->pActiveSkills[PLAYER_SKILL_BOW]) >= 3 )
+				amount = 2;
+			sRecoveryTime = pPlayer->GetAttackRecoveryTime(true);
+			pSpellSprite.stru_24.Reset();
+			pSpellSprite.spell_level = v2;
+			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_skill = v731;
+			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+			if ( pPlayer->WearsItem(ITEM_ARTEFACT_ULLYSES, EQUIP_BOW) )
+				pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(0xBD6u);
+			pSpellSprite.vPosition.x = pParty->vPosition.x;
+			pSpellSprite.vPosition.y = pParty->vPosition.y;
+			pSpellSprite.uAttributes = 0;
+			pSpellSprite.uSpriteFrameID = 0;
+			pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
+			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+			pSpellSprite.spell_target_pid = a2;
+			pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
+			pSpellSprite.uFacing = LOWORD(v715.uYawAngle);
+			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+			pPlayer = &pParty->pPlayers[pCastSpell->uPlayerID];
+			memcpy(&pSpellSprite.stru_24, &pPlayer->pInventoryItems[pPlayer->pEquipment.uBow-1], sizeof(pSpellSprite.stru_24));
+			pSpellSprite.uAttributes = 256;
+			if ( pParty->bTurnBasedModeOn == 1 )
+				pSpellSprite.uAttributes = 260;
+			for ( i = 0; i < amount; ++i )
+			{
+				if ( i )
+					pSpellSprite.vPosition.z += 32;
+				pSpellSprite.uSectorID = pIndoor->GetSector(pSpellSprite.vPosition.x, pSpellSprite.vPosition.y, pSpellSprite.vPosition.z);
+				if ( pSpellSprite.Create(v715.uYawAngle, v715.uPitchAngle, pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed,
+					pCastSpell->uPlayerID + 1) != -1 && pParty->bTurnBasedModeOn == 1 )
+				++pTurnEngine->field_1C;
+			}
+			break;
+		}
+		case SPELL_LASER_PROJECTILE:
+		{
+			sRecoveryTime = pPlayer->GetAttackRecoveryTime(0);
+			pSpellSprite.stru_24.Reset();
+			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_level = v723;
+			pSpellSprite.spell_skill = v731;
+			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+			pSpellSprite.vPosition.x = pParty->vPosition.x;
+			pSpellSprite.vPosition.y = pParty->vPosition.y;
+			pSpellSprite.uAttributes = 0;
+			pSpellSprite.uSpriteFrameID = 0;
+			pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 2;
+			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+			pSpellSprite.spell_target_pid = a2;
+			pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
+			pSpellSprite.uFacing = LOWORD(v715.uYawAngle);
+			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+			pPlayer = &pParty->pPlayers[pCastSpell->uPlayerID];
+			memcpy(&pSpellSprite.stru_24, &pPlayer->pInventoryItems[pPlayer->pEquipment.uMainHand-1],sizeof(pSpellSprite.stru_24));
+			//	&pParty->pPlayers[pCastSpell->uPlayerID].spellbook.pDarkSpellbook.bIsSpellAvailable[36
+			//		* pParty->pPlayers[pCastSpell->uPlayerID].pEquipment.uMainHand + 5], );
+			v23 = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pSpellSprite.vPosition.z);
+			HIBYTE(pSpellSprite.uAttributes) |= 1u;
+			pSpellSprite.uSectorID = v23;
+			if ( pParty->bTurnBasedModeOn == 1 )
+				LOBYTE(pSpellSprite.uAttributes) |= 4u;
+			if ( pSpellSprite.Create(v715.uYawAngle, v715.uPitchAngle, pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed,
+					pCastSpell->uPlayerID + 1) != -1 && pParty->bTurnBasedModeOn == 1 )
+				++pTurnEngine->field_1C;
+			break;
+		}
+		case SPELL_FIRE_TORCH_LIGHT:
+		{
+			switch (v731)
+			{
+				case 1: amount = 2; break;
+				case 2: amount = 3; break;
+				case 3:
+				case 4: amount = 4; break;
+				default:
+				assert(false);
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			pParty->pPartyBuffs[PARTY_BUFF_TORCHLIGHT].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)3600 * v2 * 4.2666669), v731, amount, 0, 0);
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_FIRE_FIRE_SPIKE:
+		{
+			switch (v731)
+			{
+				case 1: amount = 3; break;
+				case 2: amount = 5; break;
+				case 3: amount = 7; break;
+				case 4: amount = 9; break;
+				default:
+				assert(false);
+			}
+
+			//v31 = v3->uPlayerID;
+			//v32 = 8 * v31;
+			//LOBYTE(v32) = v32 | OBJECT_Player;
+
+			//if ( (signed int)uNumSpriteObjects > 0 )
+			int _v733 = 0;
+			for (uint i = 0; i < uNumSpriteObjects; ++i)
+			{
+				auto object = &pSpriteObjects[i];
+				if (object->uType && object->spell_id == SPELL_FIRE_FIRE_SPIKE && object->spell_caster_pid == PID(OBJECT_Player, pCastSpell->uPlayerID))
+				++_v733;
+				/*v33 = (char *)&pSpriteObjects[0].field_48;
+				v730 = uNumSpriteObjects;
+				do
+				{
+				if ( *((short *)v33 - 36) && *(int *)v33 == 7 && *((int *)v33 + 4) == v32 )
+					++HIDWORD(v733);
+				v33 += 112;
+				--v730;
+				}
+				while ( v730 );*/
+			}
+			if (_v733 > amount)
+			{
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				pCastSpell->spellnum = 0;
+				continue;
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			pSpellSprite.stru_24.Reset();
+			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_level = v2;
+			pSpellSprite.spell_skill = v731;
+			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+			pSpellSprite.vPosition.y = pParty->vPosition.y;
+			pSpellSprite.vPosition.x = pParty->vPosition.x;
+			pSpellSprite.uAttributes = 0;
+			pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
+			pSpellSprite.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3);
+			pSpellSprite.uSpriteFrameID = 0;
+			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+			pSpellSprite.spell_target_pid = a2;
+			pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
+			pSpellSprite.uFacing = LOWORD(v715.uYawAngle);
+			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+			if ( pParty->bTurnBasedModeOn == 1 )
+				LOBYTE(pSpellSprite.uAttributes) |= 4u;
+			v659 = pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed;
+			if ( pSpellSprite.Create(pParty->sRotationY, pParty->sRotationX + 10, v659, pCastSpell->uPlayerID + 1) != -1 && pParty->bTurnBasedModeOn == 1 )
+				++pTurnEngine->field_1C;
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_AIR_IMPLOSION:
+		{
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			if (!a2)
+			{
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				pCastSpell->spellnum = 0;
+				continue;
+			}
+			if (PID_TYPE(a2) != OBJECT_Actor)
+			{
+				LODWORD(v727) = 1;
+				break;
+			}
+			v697.x = 0;
+			v697.y = 0;
+			v697.z = 0;
+			pSpellSprite.stru_24.Reset();
+			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_level = v2;
+			pSpellSprite.spell_skill = v731;
+			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+			pSpellSprite.uAttributes = 0;
+			pSpellSprite.uSectorID = 0;
+			pSpellSprite.uSpriteFrameID = 0;
+			pSpellSprite.field_60_distance_related_prolly_lod = 0;
+			pSpellSprite.uFacing = 0;
+			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+			pSpellSprite.vPosition.x = pActors[PID_ID(a2)].vPosition.x;
+			pSpellSprite.vPosition.z = pActors[PID_ID(a2)].vPosition.z;
+			pSpellSprite.vPosition.y = pActors[PID_ID(a2)].vPosition.y;
+			pSpellSprite.spell_target_pid = PID(OBJECT_Actor, PID_ID(a2));
+			auto obj_id = pSpellSprite.Create(0, 0, 0, 0);
+			DamageMonsterFromParty(PID(OBJECT_Item, obj_id), PID_ID(a2), &v697);
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_EARTH_MASS_DISTORTION:
+		{
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			if ( !stru_50C198.GetMagicalResistance(&pActors[PID_ID(a2)], 3u) )
+			{
+				LODWORD(v727) = 1;
+				break;
+			}
+			pActors[PID_ID(a2)].pActorBuffs[10].Apply(pMiscTimer->uTotalGameTimeElapsed + 128, 0, 0, 0, 0);
+			v704.x = 0;
+			v704.y = 0;
+			v704.z = 0;
+			pSpellSprite.stru_24.Reset();
+			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_level = v2;
+			pSpellSprite.spell_skill = v731;
+			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+			pSpellSprite.uAttributes = 0;
+			pSpellSprite.uSectorID = 0;
+			pSpellSprite.uSpriteFrameID = 0;
+			pSpellSprite.field_60_distance_related_prolly_lod = 0;
+			pSpellSprite.uFacing = 0;
+			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+			pSpellSprite.vPosition.x = pActors[PID_ID(a2)].vPosition.x;
+			pSpellSprite.vPosition.y = pActors[PID_ID(a2)].vPosition.y;
+			pSpellSprite.vPosition.z = pActors[PID_ID(a2)].vPosition.z;
+			pSpellSprite.spell_target_pid = PID(OBJECT_Actor, PID_ID(a2));
+			auto obj_id = pSpellSprite.Create(0, 0, 0, 0);
+			DamageMonsterFromParty(PID(OBJECT_Item, obj_id), PID_ID(a2), &v704);
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_LIGHT_DESTROY_UNDEAD:
+		{
+			if ( !pPlayer->CanCastSpell(uRequiredMana) || !a2 || PID_TYPE(a2) != OBJECT_Actor)
+				break;
+			//v730 = a2 >> 3;
+			//HIDWORD(v733) = (int)&pActors[PID_ID(a2)];
+			v691.x = 0;
+			v691.y = 0;
+			v691.z = 0;
+			pSpellSprite.stru_24.Reset();
+			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_level = v2;
+			pSpellSprite.spell_skill = v731;
+			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+			pSpellSprite.vPosition.x = pActors[PID_ID(a2)].vPosition.x;
+			pSpellSprite.vPosition.y = pActors[PID_ID(a2)].vPosition.y;
+			pSpellSprite.vPosition.z = pActors[PID_ID(a2)].vPosition.z;
+			pSpellSprite.uAttributes = 0;
+			pSpellSprite.uSectorID = pIndoor->GetSector(pSpellSprite.vPosition.x, pSpellSprite.vPosition.y, pSpellSprite.vPosition.z);
+			pSpellSprite.uSpriteFrameID = 0;
+			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+			pSpellSprite.spell_target_pid = a2;
+			pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
+			pSpellSprite.uFacing = LOWORD(v715.uYawAngle);
+			pSpellSprite.uAttributes |= 0x80u;
+			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+			auto obj_id = pSpellSprite.Create(0, 0, 0, 0);
+			if ( !MonsterStats::BelongsToSupertype(pActor->pMonsterInfo.uID, MONSTER_SUPERTYPE_UNDEAD) )
+			{
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				pCastSpell->spellnum = 0;
+				continue;
+			}
+			DamageMonsterFromParty(PID(OBJECT_Item, obj_id), PID_ID(a2), &v691);
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_FIRE_FIRE_BOLT:
+		case SPELL_FIRE_FIREBALL:
+		case SPELL_FIRE_INCINERATE:
+		case SPELL_AIR_LIGHNING_BOLT:
+		case SPELL_WATER_ICE_BOLT:
+		case SPELL_WATER_ICE_BLAST:
+		case SPELL_EARTH_STUN:
+		case SPELL_EARTH_DEADLY_SWARM:
+		case SPELL_MIND_MIND_BLAST:
+		case SPELL_MIND_PSYCHIC_SHOCK:
+		case SPELL_BODY_HARM:
+		case SPELL_LIGHT_LIGHT_BOLT:
+		case SPELL_DARK_DRAGON_BREATH:
+		{
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			pSpellSprite.stru_24.Reset();
+			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_level = v2;
+			pSpellSprite.spell_skill = v731;
+			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+			pSpellSprite.vPosition.y = pParty->vPosition.y;
+			pSpellSprite.vPosition.x = pParty->vPosition.x;
+			pSpellSprite.uAttributes = 0;
+			pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
+			if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
+				pSpellSprite.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3);
+			else
+				pSpellSprite.uSectorID = 0;
+			pSpellSprite.uSpriteFrameID = 0;
+			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+			pSpellSprite.spell_target_pid = a2;
+			pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
+			pSpellSprite.uFacing = LOWORD(v715.uYawAngle);
+			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+			if ( pParty->bTurnBasedModeOn == 1 )
+				LOBYTE(pSpellSprite.uAttributes) |= 4u;
+			if ( pCastSpell->spellnum == SPELL_AIR_LIGHNING_BOLT )
+				LOBYTE(pSpellSprite.uAttributes) |= 0x40u;
+			v659 = pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed;
+			if ( pSpellSprite.Create(v715.uYawAngle, v715.uPitchAngle, v659, pCastSpell->uPlayerID + 1) != -1 && pParty->bTurnBasedModeOn == 1 )
+				++pTurnEngine->field_1C;
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_WATER_ACID_BURST:
+		case SPELL_EARTH_BLADES:
+		case SPELL_BODY_FLYING_FIST:
+		case SPELL_DARK_TOXIC_CLOUD:
+		{
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			pSpellSprite.stru_24.Reset();
+			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_level = v2;
+			pSpellSprite.spell_skill = v731;
+			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+			v51 = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 2;
+			pSpellSprite.vPosition.y = pParty->vPosition.y;
+			v671 = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 2;
+			v660 = pParty->vPosition.y;
+			pSpellSprite.uAttributes = 0;
+			pSpellSprite.vPosition.x = pParty->vPosition.x;
+			pSpellSprite.vPosition.z = v51;
+			v52 = pIndoor->GetSector(pParty->vPosition.x, v660, v671);
+			pSpellSprite.uSpriteFrameID = 0;
+			pSpellSprite.uSectorID = v52;
+			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+			pSpellSprite.spell_target_pid = a2;
+			pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
+			pSpellSprite.uFacing = LOWORD(v715.uYawAngle);
+			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+			if ( pParty->bTurnBasedModeOn == 1 )
+				LOBYTE(pSpellSprite.uAttributes) |= 4u;
+			v659 = pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed;
+			if ( pSpellSprite.Create(v715.uYawAngle, v715.uPitchAngle, v659, pCastSpell->uPlayerID + 1) != -1 && pParty->bTurnBasedModeOn == 1 )
+				++pTurnEngine->field_1C;
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_LIGHT_SUNRAY:
+		{
+			if ( uCurrentlyLoadedLevelType == LEVEL_Indoor
+				|| uCurrentlyLoadedLevelType == LEVEL_Outdoor && (pParty->uCurrentHour < 5 || pParty->uCurrentHour >= 21) )
+			{
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				pCastSpell->spellnum = 0;
+				continue;
+			}
+			if ( pPlayer->CanCastSpell(uRequiredMana) )
+			{
+				pSpellSprite.stru_24.Reset();
+				pSpellSprite.spell_id = pCastSpell->spellnum;
+				pSpellSprite.spell_skill = v731;
+				pSpellSprite.spell_level = v2;
+				pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+				pSpellSprite.vPosition.y = pParty->vPosition.y;
+				v51 = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
+				v671 = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
+				v660 = pParty->vPosition.y;
+				pSpellSprite.uAttributes = 0;
+				pSpellSprite.vPosition.x = pParty->vPosition.x;
+				pSpellSprite.vPosition.z = v51;
+				v52 = pIndoor->GetSector(pParty->vPosition.x, v660, v671);
+				pSpellSprite.uSpriteFrameID = 0;
+				pSpellSprite.uSectorID = v52;
+				pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+				pSpellSprite.spell_target_pid = a2;
+				pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
+				pSpellSprite.uFacing = LOWORD(v715.uYawAngle);
+				pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+				if ( pParty->bTurnBasedModeOn == 1 )
+					LOBYTE(pSpellSprite.uAttributes) |= 4u;
+				v659 = pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed;
+				if ( pSpellSprite.Create(v715.uYawAngle, v715.uPitchAngle, v659, pCastSpell->uPlayerID + 1) != -1 && pParty->bTurnBasedModeOn == 1 )
+					++pTurnEngine->field_1C;
+				LODWORD(v727) = 1;
+			}
+			break;
+		}
+		case SPELL_LIGHT_PARALYZE:
+		{
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			if (PID_TYPE(a2) != OBJECT_Actor || (v730 = PID_ID(a2), v721 = (int)&pActors[PID_ID(a2)],
+					!stru_50C198.GetMagicalResistance(&pActors[PID_ID(a2)], 9)) )
+			{
+				LODWORD(v727) = 1;
+				break;
+			}
+			Actor::AI_Stand(PID_ID(a2), 4u, 0x80u, 0);
+			v54 = (signed __int64)((double)(23040 * v2) * 0.033333335);
+			v55 = &pActors[PID_ID(a2)];
+			v55->pActorBuffs[6].Apply(pParty->uTimePlayed + (signed int)v54, v731, 0, 0, 0);
+			BYTE2(v55->uAttributes) |= 8u;
+			v55->vVelocity.x = 0;
+			//v672 = 0;
+			v55->vVelocity.y = 0;
+			v661 = v55;
+			pGame->GetStru6()->_4A7E89_sparkles_on_actor_after_it_casts_buff(v661, 0);
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_EARTH_SLOW:
+		{
+			switch (v731)
+			{
+				case 1: LODWORD(v733) = 180 * v2; amount = 2; break;
+				case 2: LODWORD(v733) = 300 * v2; amount = 2; break;
+				case 3: LODWORD(v733) = 300 * v2; amount = 4; break;
+				case 4: LODWORD(v733) = 300 * v2; amount = 8; break;
+				default:
+				assert(false);
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			if (PID_TYPE(a2) != OBJECT_Actor
+				|| (v721 = 836 * PID_ID(a2),
+					LODWORD(v718) = (int)&pActors[PID_ID(a2)],
+					!stru_50C198.GetMagicalResistance(&pActors[PID_ID(a2)], 3u)) )
+			{
+				LODWORD(v727) = 1;
+				break;
+			}
+			v58 = (signed __int64)((double)(23040 * v2) * 0.033333335);
+			//v59 = v721;
+			pActor = &pActors[PID_ID(a2)];
+			//((SpellBuff *)((char *)&pActors[0].pActorBuffs[7] + v721))->Apply(
+			pActor->pActorBuffs[7].Apply(pParty->uTimePlayed + (signed int)v58,	v731, amount, 0, 0);
+			//*((char *)&pActors[0].uAttributes + v59 + 2) |= 8u;
+			BYTE2(pActor->uAttributes) |= 8u;
+			//v672 = 0;
+			v661 = (Actor *)LODWORD(v718);
+			pGame->GetStru6()->_4A7E89_sparkles_on_actor_after_it_casts_buff(v661, 0);
+			LODWORD(v727) = 1;
+			break;
+      }
+		case SPELL_MIND_CHARM:
+		{
+		if ( !pPlayer->CanCastSpell(uRequiredMana) )
+			break;
+
+		if ( !stru_50C198.GetMagicalResistance(&pActors[PID_ID(a2)], 7u) )
+		{
+			LODWORD(v727) = 1;
+			break;
+		}
+
+		uint power = 300 * v2;
+		if ( v731 == 2 )
+		{
+			power = 600 * v2;
+		}
+		else if ( v731 == 3 )
+			power  = 29030400;
+
+		//((SpellBuff *)((char *)&pActors[0].pActorBuffs[9] + v730))->Reset();
+		pActors[PID_ID(a2)].pActorBuffs[9].Reset();
+		//((SpellBuff *)((char *)&pActors[0].pActorBuffs[12] + v730))->Reset();
+		pActors[PID_ID(a2)].pActorBuffs[12].Reset();
+		//((SpellBuff *)((char *)&pActors[0].pActorBuffs[1] + v730))->Apply(
+		pActors[PID_ID(a2)].pActorBuffs[1].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)(power << 7) * 0.033333335),
+			v731, 0, 0, 0);
+		pSpellSprite.stru_24.Reset();
+		pSpellSprite.spell_id = pCastSpell->spellnum;
+		pSpellSprite.spell_level = v2;
+		pSpellSprite.spell_skill = v731;
+		v60 = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+		v61 = PID_ID(a2);
+			v600 = pActors[v61].vPosition.y;
+			v601 = pActors[v61].vPosition.x;
+			pSpellSprite.uObjectDescID = v60;
+			pSpellSprite.vPosition.x = v601;
+			v602 = pActors[v61].uActorHeight;
+			v603 = pActors[v61].vPosition.z;
+			pSpellSprite.vPosition.y = v600;
+			v676 = v603 + v602;
+			v665 = v600;
+			pSpellSprite.vPosition.z = v603 + v602;
+			v657 = v601;
+			pSpellSprite.uAttributes = 0;
+			pSpellSprite.uSectorID = pIndoor->GetSector(v657, v665, v676);
+			pSpellSprite.uSpriteFrameID = 0;
+			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+			pSpellSprite.spell_target_pid = a2;
+			pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
+			pSpellSprite.uFacing = LOWORD(v715.uYawAngle);
+			LOBYTE(pSpellSprite.uAttributes) |= 0x80u;
+			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+			pSpellSprite.Create(0, 0, 0, pCastSpell->uPlayerID + 1);
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_DARK_SHRINKING_RAY:
+		{
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			pSpellSprite.stru_24.Reset();
+			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+			pSpellSprite.vPosition.x = pParty->vPosition.x;
+			pSpellSprite.vPosition.y = pParty->vPosition.y;
+			pSpellSprite.uAttributes = 0;
+			pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
+			pSpellSprite.uSectorID = pIndoor->GetSector(
+								pParty->vPosition.x,
+								pParty->vPosition.y,
+								pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3);
+			pSpellSprite.uSpriteFrameID = 0;
+			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+			pSpellSprite.spell_target_pid = a2;
+			pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
+			pSpellSprite.uFacing = LOWORD(v715.uYawAngle);
+			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+			pSpellSprite.spell_skill = v731;
+			pSpellSprite.spell_id = SPELL_FIRE_PROTECTION_FROM_FIRE;
+			pSpellSprite.spell_level = 300 * v2;
+				if ( pParty->bTurnBasedModeOn == 1 )
+				LOBYTE(pSpellSprite.uAttributes) |= 4u;
+
+				v659 = pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed;
+
+				if ( pSpellSprite.Create(v715.uYawAngle, v715.uPitchAngle, v659, pCastSpell->uPlayerID + 1) != -1 && pParty->bTurnBasedModeOn == 1 )
+				++pTurnEngine->field_1C;
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_FIRE_FIRE_AURA:
+		{
+			switch (v731)
+			{
+				case 1: LODWORD(v733) = 3600 * v2; amount = 10; break;
+				case 2: LODWORD(v733) = 3600 * v2; amount = 11; break;
+				case 3: LODWORD(v733) = 3600 * v2; amount = 12; break;
+				case 4: LODWORD(v733) = 0; amount = 12; break;
+				default:
+				assert(false);
+			}
+			
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			v730c = &pParty->pPlayers[pCastSpell->uPlayerID_2].pInventoryItems[a2];
+			auto _itm = &pItemsTable->pItems[v730c->uItemID];
+			v730c->UpdateTempBonus(pParty->uTimePlayed);
+			if ( v730c->uItemID < 64 || v730c->uItemID > 65 
+				&& !v730c->Broken()
+				&& !v730c->uSpecEnchantmentType
+				&& !v730c->uEnchantmentType
+				&& ( _itm->uEquipType == 0 || _itm->uEquipType == 1 || _itm->uEquipType == 2)
+				&& !pItemsTable->IsMaterialNonCommon(v730c) )
+			{
+				v69 = v730c;
+				v14 = v731 == 4;
+				v730c->uSpecEnchantmentType = amount;
+				if ( !v14 )
+				{
+					v69->uExpireTime = pParty->uTimePlayed
+										+ (signed int)(signed __int64)((double)(signed int)((int)v733 << 7)
+																		* 0.033333335);
+					v69->uAttributes |= 8u;
+				}
+				v69->uAttributes |= 0x10u;
+				_50C9A8_item_enchantment_timer = 256;
+				LODWORD(v727) = 1;
+				break;
+			}
+
+			dword_50C9D0 = 113;
+			dword_50C9D4 = 0;
+			dword_50C9D8 = 1;
+
+			ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
+			pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+			pCastSpell->spellnum = 0;
+			continue;
+		}
+		case SPELL_BODY_REGENERATION:
+		{
+			switch (v731)
+			{
+				case 1: LODWORD(v733) = 3600 * v2; amount = 1; break;
+				case 2: LODWORD(v733) = 3600 * v2; amount = 1; break;
+				case 3: LODWORD(v733) = 3600 * v2; amount = 3; break;
+				case 4: LODWORD(v733) = 3600 * v2; amount = 10; break;
+				default:
+				assert(false);
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+
+			pParty->pPlayers[pCastSpell->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_REGENERATION].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)v733 * 4.2666669), v731, amount, 0, 0);
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_FIRE_PROTECTION_FROM_FIRE:
+		case SPELL_AIR_PROTECTION_FROM_AIR:
+		case SPELL_WATER_PROTECTION_FROM_WATER:
+		case SPELL_EARTH_PROTECTION_FROM_EARTH:
+		case SPELL_MIND_PROTECTION_FROM_MIND:
+		case SPELL_BODY_PROTECTION_FROM_BODY:
+		{
+			switch (v731)
+			{
+				case 1: 
+				case 2: 
+				case 3: 
+				case 4: LODWORD(v733) = 3600 * v2; amount = v731 * v2; break;
+				default:
+				assert(false);
+			}
+
+			switch (pCastSpell->spellnum)
+			{
+			  case SPELL_FIRE_PROTECTION_FROM_FIRE:
+				LODWORD(v725) = PARTY_BUFF_RESIST_FIRE;
+				break;
+			  case SPELL_AIR_PROTECTION_FROM_AIR:
+				LODWORD(v725) = PARTY_BUFF_RESIST_AIR;
+				break;
+			  case SPELL_WATER_PROTECTION_FROM_WATER:
+				LODWORD(v725) = PARTY_BUFF_RESIST_WATER;
+				break;
+			  case SPELL_EARTH_PROTECTION_FROM_EARTH:
+				LODWORD(v725) = PARTY_BUFF_RESIST_EARTH;
+				break;
+			  case SPELL_MIND_PROTECTION_FROM_MIND:
+				LODWORD(v725) = PARTY_BUFF_RESIST_MIND;
+				break;
+			  case SPELL_BODY_PROTECTION_FROM_BODY:
+				LODWORD(v725) = PARTY_BUFF_RESIST_BODY;
+				break;
+			  default:
+				assert(false);
+				continue;
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+			  break;
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
+			v90 = (double)(signed int)v733 * 4.2666669;
+			pParty->pPartyBuffs[LODWORD(v725)].Apply(pParty->uTimePlayed + (signed int)(signed __int64)v90, v731, amount, 0, 0);
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_FIRE_HASTE:
+		{
+			switch (v731)
+			{
+				case 1: LODWORD(v733) = 60 * (v2 + 60); break;
+				case 2: LODWORD(v733) = 60 * (v2 + 60); break;
+				case 3: LODWORD(v733) = 180 * (v2 + 20); break;
+				case 4: LODWORD(v733) = 240 * (v2 + 15); break;
+				default:
+				assert(false);
+			}
+			if ( pPlayer->CanCastSpell(uRequiredMana) )
+			{
+				v92 = pParty->pPlayers;//[0].pConditions[1];
+				LODWORD(v727) = 1;
+				do
+				{
+					if ( v92->pConditions[1] )
+						LODWORD(v727) = 0;
+					++v92;
+				}
+				while ( v92 <= &pParty->pPlayers[3] );
+				if (LODWORD(v727))
+				{
+					pParty->pPartyBuffs[PARTY_BUFF_HASTE].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, 0, 0, 0);
+
+					pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
+					pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
+					pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
+					pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
+				}
+			}
+			break;
+		}
+		case SPELL_SPIRIT_BLESS:
+		{
+			switch (v731)
+			{
+				case 1: LODWORD(v733) = 300 * (v2 + 12); break;
+				case 2: LODWORD(v733) = 300 * (v2 + 12); break;
+				case 3: LODWORD(v733) = 900 * (v2 + 4); break;
+				case 4: LODWORD(v733) = 3600 * (v2 + 1); break;
+				default:
+				assert(false);
+			}
+			amount = v2 + 5;
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			if ( v731 == 1 )
+			{
+				v108 = pCastSpell->uPlayerID_2;
+				v109 = pCastSpell->spellnum;
+				v110 = pGame->GetStru6();
+				pGame->GetStru6()->SetPlayerBuffAnim(v109, v108);
+				v111 = pOtherOverlayList->_4418B1(10000, pCastSpell->uPlayerID_2 + 310, 0, 65536);
+				//v668 = 0;
+				v716 = v111;
+				//v658 = v111;
+				//v653 = amount;
+				//v651 = 1;
+				//v28 = pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
+				//v27 = (char *)&pParty->pPlayers[v3->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_BLESS];
+		//LABEL_103:
+				//HIDWORD(v650) = HIDWORD(v28);
+		//LABEL_104:
+				//LODWORD(v650) = v28;
+				pParty->pPlayers[pCastSpell->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_BLESS].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), 1, amount, v111, 0);
+				LODWORD(v727) = 1;
+				break;
+			}
+			v105 = 0;
+			v717 = (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
+			v730b = pParty->pPlayers;//[0].pPlayerBuffs[1];
+			do
+			{
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, v105);
+				v716 = pOtherOverlayList->_4418B1(10000, v105 + 310, 0, 65536);
+				v730b->pPlayerBuffs[1].Apply(pParty->uTimePlayed + v717, v731, amount, v716, 0);
+				++v730b;
+				++v105;
+			}
+			while ( v730b <= &pParty->pPlayers[3] );
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_SPIRIT_SPIRIT_LASH:
+		{
+			if ( pPlayer->CanCastSpell(uRequiredMana) && a2 && PID_TYPE(a2) == OBJECT_Actor)
+			{
+				//v730 = a2 >> 3;
+				v112 = &pActors[PID_ID(a2)];
+				//v726 = (Player *)abs(v112->vPosition.z - pParty->vPosition.z);
+				v721 = abs(v112->vPosition.y - pParty->vPosition.y);
+				v113 = abs(v112->vPosition.x - pParty->vPosition.x);
+				_this = (ItemGen *)v113;
+				v114 = v721;
+				v115 = (unsigned int)abs(v112->vPosition.z - pParty->vPosition.z);
+				if ( v113 < v721 )
+				{
+					v116 = v113;
+					v113 = v721;
+					v114 = v116;
+				}
+				if ( v113 < (signed int)v115 )
+				{
+					v117 = v113;
+					v113 = (int)v115;
+					v115 = v117;
+				}
+				if ( v114 < (signed int)v115 )
+				{
+					v118 = v115;
+					v115 = v114;
+					v114 = v118;
+				}
+				_this = (ItemGen *)(((unsigned int)(11 * v114) >> 5) + (v115 >> 2) + v113);
+				if ( (double)(signed int)this <= 307.2 )
+				{
+					v701.x = 0;
+					v701.y = 0;
+					v701.z = 0;
+					pSpellSprite.stru_24.Reset();
+					pSpellSprite.spell_id = pCastSpell->spellnum;
+					pSpellSprite.spell_level = v723;
+					pSpellSprite.spell_skill = v731;
+					pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+					pSpellSprite.uAttributes = 0;
+					pSpellSprite.uSectorID = 0;
+					pSpellSprite.uSpriteFrameID = 0;
+					pSpellSprite.field_60_distance_related_prolly_lod = 0;
+					pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+					pSpellSprite.uFacing = 0;
+					pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+					pSpellSprite.vPosition.x = v112->vPosition.x;
+					pSpellSprite.vPosition.y = v112->vPosition.y;
+					pSpellSprite.vPosition.z = v112->vPosition.z - (unsigned int)(signed __int64)((double)(signed int)v112->uActorHeight * unk_4D8548);
+					pSpellSprite.spell_target_pid = PID(OBJECT_Actor, a2);
+					v122 = pSpellSprite.Create(0, 0, 0, 0);
+					DamageMonsterFromParty(PID(OBJECT_Item, v122), PID_ID(a2), &v701);
+					LODWORD(v727) = 1;
+				}
+				else
+				{
+					ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2u);
+					pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+					pCastSpell->spellnum = 0;
+				}
+				//pCastSpell = (CastSpellInfo *)HIDWORD(v733);
+			}
+			break;
+		}
+		case SPELL_AIR_SHIELD:
+		case SPELL_EARTH_STONESKIN:
+		case SPELL_SPIRIT_HEROISM:
+		{
+			switch (v731)
+			{
+				case 1: LODWORD(v733) = 300 * (v2 + 12); break;
+				case 2: LODWORD(v733) = 300 * (v2 + 12); break;
+				case 3: LODWORD(v733) = 900 * (v2 + 4); break;
+				case 4: LODWORD(v733) = 3600 * (v2 + 1); break;
+				default:
+				assert(false);
+			}
+			v127 = pCastSpell->spellnum;
+			if ( v127 == 17 )
+			{
+				amount = 0;
+				LODWORD(v725) = 14;
+			}
+			else
+			{
+				if ( v127 == 38 )
+				{
+					LODWORD(v725) = 15;
+					amount = v2 + 5;
+				}
+				else
+				{
+					if ( v127 != 51 )
+						continue;
+					LODWORD(v725) = 9;
+					amount = v2 + 5;
+				}
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
+			v90 = (double)(signed int)((int)v733 << 7) * 0.033333335;
+	//LABEL_304:
+			pParty->pPartyBuffs[LODWORD(v725)].Apply(pParty->uTimePlayed + (signed int)(signed __int64)v90, v731, amount, 0, 0);
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_FIRE_IMMOLATION:
+		{
+			if ( v731 == 4 )
+				LODWORD(v733) = 600 * v2;
+			else
+				LODWORD(v733) = 60 * v2;
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
+
+			pParty->pPartyBuffs[PARTY_BUFF_IMMOLATION].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, v2, 0, 0);
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_FIRE_METEOR_SHOWER:
+		{
+			//v149 = v731 - 1;
+			//if ( v149 && (v150 = v149 - 1) != 0 && (v151 = v150 - 1) != 0 )
+			int i;
+			if ( v731 == 4 )
+			{
+				i = 20;
+			}
+			else
+			{
+				i = 16;
+			}
+			if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
+			{
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[491], 2);  // Can't cast Meteor Shower indoors!
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				pCastSpell->spellnum = 0;
+				continue;
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			LODWORD(v725) = PID_TYPE(a2);
+			if (PID_TYPE(a2) == OBJECT_Actor)
+			{
+				uRequiredMana = pActors[PID_ID(a2)].vPosition.x;
+				v153 = pActors[PID_ID(a2)].vPosition.y;
+				v154 = pActors[PID_ID(a2)].vPosition.z;
+				LODWORD(v727) = v153;
+			}
+			else
+			{
+				v155 = stru_5C6E00->Cos(pParty->sRotationY);
+				uRequiredMana = pParty->vPosition.x + sub_42EBBE(2048, v155);
+				v156 = stru_5C6E00->Sin(pParty->sRotationY);
+				LODWORD(v727) = pParty->vPosition.y + sub_42EBBE(2048, v156);
+				v154 = pParty->vPosition.z;
+			}
+			unsigned __int64 k = 0;
+			int j = 0;
+			if ( (signed int)i > 0 )
+			{
+				v730 = LODWORD(v725) == 3 ? a2 : 0;
+				do
+				{
+					a2 = rand() % 1000;
+					if ( sqrt((double)(rand() % 1000) - 2500 * 
+								(double)(rand() % 1000) - 2500 + 
+								j * j + k * k) <= 1.0 )
+					{
+						LODWORD(v687) = 0;
+						HIDWORD(v687) = 0;
+					}
+					else
+					{
+						v687 = __PAIR__(
+								stru_5C6E00->Atan2((signed __int64)sqrt((float)(j * j + k * k)), 
+													(double)(rand() % 1000) - 2500),
+													stru_5C6E00->Atan2(j, k));
+					}
+					pSpellSprite.stru_24.Reset();
+					pSpellSprite.spell_id = pCastSpell->spellnum;
+					pSpellSprite.spell_level = v2;
+					pSpellSprite.spell_skill = v731;
+					pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+					pSpellSprite.uAttributes = 0;
+					pSpellSprite.vPosition.x = uRequiredMana;
+					pSpellSprite.vPosition.y = LODWORD(v727);
+					pSpellSprite.uSectorID = 0;
+					pSpellSprite.vPosition.z = a2 + v154;
+					pSpellSprite.uSpriteFrameID = 0;
+					pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+					pSpellSprite.spell_target_pid = v730;
+					pSpellSprite.field_60_distance_related_prolly_lod = stru_50C198._427546(a2 + 2500);
+					pSpellSprite.uFacing = v687;
+					pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+					if ( pParty->bTurnBasedModeOn == 1 )
+						pSpellSprite.uAttributes = 4;
+					if ( pSpellSprite.Create(v687, SHIDWORD(v687), pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed, 0) != -1
+						&& pParty->bTurnBasedModeOn == 1 )
+						++pTurnEngine->field_1C;
+					j = rand() % 1024 - 512;
+					k = rand() % 1024 - 512;
+				}
+				while ( i-- != 1 );
+			}
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_FIRE_INFERNO:
+		{
+			//v67 = 2;
+			if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor)
+			{
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[492], 2); // Can't cast Inferno outdoors!
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				pCastSpell->spellnum = 0;
+				continue;
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			auto _v726 = sub_46A6AC((int)dword_50BF30.data(), 100, 4096);
+			v700.z = 0;
+			v700.y = 0;
+			v700.x = 0;
+			pSpellSprite.stru_24.Reset();
+			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_level = v2;
+			pSpellSprite.spell_skill = v731;
+			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+			pSpellSprite.uAttributes = 0;
+			pSpellSprite.uSectorID = 0;
+			pSpellSprite.uSpriteFrameID = 0;
+			pSpellSprite.field_60_distance_related_prolly_lod = 0;
+			pSpellSprite.uFacing = 0;
+			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+			a2 = 0;
+			if ( (signed int)_v726 > 0 )
+			{
+				do
+				{
+					v162 = dword_50BF30[a2];
+					pSpellSprite.vPosition.x = pActors[v162].vPosition.x;
+					pSpellSprite.vPosition.y = pActors[v162].vPosition.y;
+					pSpellSprite.vPosition.z = pActors[v162].vPosition.z - (unsigned int)(signed __int64)((double)pActors[v162].uActorHeight * unk_4D8548);
+					pSpellSprite.spell_target_pid = PID(OBJECT_Actor, dword_50BF30[a2]);
+					v164 = pSpellSprite.Create(0, 0, 0, 0);
+					v165 = a2;
+					DamageMonsterFromParty(PID(OBJECT_Item, v164), dword_50BF30[a2], &v700);
+					pGame->GetStru6()->_4A81CA(&pSpellSprite);
+					pGame->GetStru6()->FadeScreen__like_Turn_Undead_and_mb_Armageddon(0xFF3C1Eu, 0x40u);
+					a2 = v165 + 1;
+				}
+				while ( v165 + 1 < (signed int)_v726 );
+			}
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_AIR_WIZARD_EYE:
+		{
+			LODWORD(v733) = 3600 * v2;
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			v168 = 0;
+			do
+			{
+				v169 = pOtherOverlayList->_4418B1(2000, v168++ + 100, 0, 65536);
+				v716 = v169;
+			}
+			while ( v168 < 4 );
+
+			pParty->pPartyBuffs[PARTY_BUFF_WIZARD_EYE].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, 0, 0, 0);
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_AIR_FEATHER_FALL:
+		{
+			switch (v731)
+			{
+				case 1: LODWORD(v733) = 300 * v2; break;
+				case 2: LODWORD(v733) = 600 * v2; break;
+				case 3: LODWORD(v733) = 3600 * v2; break;
+				case 4: LODWORD(v733) = 3600 * v2; break;
+				default:
+				assert(false);
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			v174 = 0;
+			do
+				pOtherOverlayList->_4418B1(2010, v174++ + 100, 0, 65536);
+			while ( v174 < 4 );
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
+
+			pParty->pPartyBuffs[PARTY_BUFF_FEATHER_FALL].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, 0, 0, 0);
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_AIR_SPARKS:
+		{
+			switch (v731)
+			{
+				case 1: amount = 3; break;
+				case 2: amount = 5; break;
+				case 3: amount = 7; break;
+				case 4: amount = 9; break;
+				default:
+				assert(false);
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			auto _v726 = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360;
+			pSpellSprite.stru_24.Reset();
+			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_level = v2;
+			pSpellSprite.spell_skill = v731;
+			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+			pSpellSprite.vPosition.y = pParty->vPosition.y;
+			pSpellSprite.vPosition.x = pParty->vPosition.x;
+			pSpellSprite.uAttributes = 0;
+			pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
+			pSpellSprite.uSectorID = pIndoor->GetSector(
+								pParty->vPosition.x,
+								pParty->vPosition.y,
+								pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3);
+			pSpellSprite.uSpriteFrameID = 0;
+			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+			pSpellSprite.spell_target_pid = a2;
+			pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
+			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+			if ( pParty->bTurnBasedModeOn == 1 )
+				LOBYTE(pSpellSprite.uAttributes) |= 4u;
+			v188 = (signed int)_v726 / -2;
+			v189 = (signed int)_v726 / 2;
+			while ( v188 <= v189 )
+			{
+				pSpellSprite.uFacing = v188 + LOWORD(v715.uYawAngle);
+				if ( pSpellSprite.Create(
+						(signed __int16)(v188 + LOWORD(v715.uYawAngle)),
+						v715.uPitchAngle,
+						pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed,
+						pCastSpell->uPlayerID + 1) != -1
+						&& pParty->bTurnBasedModeOn == 1 )
+				    ++pTurnEngine->field_1C;
+				v188 += _v726 / (amount - 1);
+			}
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_AIR_JUMP:
+		{
+			if ( pParty->uFlags & PARTY_FLAGS_1_FALLING)
+			{
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[493], 2);  // Can't cast Jump while airborne!
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				break;
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			v191 = 0;
+			do
+				pOtherOverlayList->_4418B1(2040, v191++ + 100, 0, 65536);
+			while ( v191 < 4 );
+			BYTE1(pParty->uFlags) |= 1u;
+			pParty->uFallSpeed = 1000;
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_AIR_INVISIBILITY:
+		{
+			switch (v731)
+			{
+				case 1: LODWORD(v733) = 600 * v2; amount = v2; break;
+				case 2: LODWORD(v733) = 600 * v2; amount = 2 * v2; break;
+				case 3: LODWORD(v733) = 600 * v2; amount = 3 * v2; break;
+				case 4: LODWORD(v733) = 3600 * v2; amount = 4 * v2; break;
+				default:
+				assert(false);
+			}
+			if (pParty->uFlags & (PARTY_FLAGS_1_ALERT_RED | PARTY_FLAGS_1_ALERT_YELLOW))
+			{
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[638], 2);  // There are hostile creatures nearby!
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				pCastSpell->spellnum = 0;
+				continue;
+			}
+			if ( pPlayer->CanCastSpell(uRequiredMana) )
+			{
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
+
+				pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, amount, 0, 0);
+				LODWORD(v727) = 1;
+			}
+			break;
+		}
+		case SPELL_AIR_FLY:
+		{
+			if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
+			{
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[494], 2);  // Can not cast Fly indoors!
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				break;
+			}
+			if ( !pPlayers[pCastSpell->uPlayerID + 1]->GetMaxMana() )
+			{
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2);  // Spell failed
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				break;
+			}
+			LODWORD(v733) = 3600 * v2;
+			if ( v731 == 1 || v731 == 2 || v731 == 3 )
+				amount = 1;
+			else
+				amount = 0;
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			v205 = 0;
+			do
+				pOtherOverlayList->_4418B1(2090, v205++ + 100, 0, 65536);
+			while ( v205 < 4 );
+			v206 = pOtherOverlayList->_4418B1(10008, 203, 0, 65536);
+			v207 = pCastSpell->uPlayerID + 1;
+			v716 = v206;
+
+			pParty->pPartyBuffs[PARTY_BUFF_FLY].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, amount, v206, v207);
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_AIR_STARBURST:
+		{
+			//v67 = 2;
+			if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
+			{
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[495], 2);  // Can't cast Starburst indoors!
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				pCastSpell->spellnum = 0;
+				continue;
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			v208 = PID_TYPE(a2);
+			LODWORD(v725) = PID_TYPE(a2);
+			if ( v208 == 3 )
+			{
+				v209 = PID_ID(a2);
+				LODWORD(v718) = pActors[v209].vPosition.x;
+				v210 = pActors[v209].vPosition.y;
+				v211 = pActors[v209].vPosition.z;
+				v713 = v210;
+			}
+			else
+			{
+				v212 = stru_5C6E00->Cos(pParty->sRotationY);
+				LODWORD(v718) = pParty->vPosition.x + sub_42EBBE(2048, v212);
+				v213 = stru_5C6E00->Sin(pParty->sRotationY);
+				v214 = sub_42EBBE(2048, v213);
+				v211 = pParty->vPosition.z;
+				v713 = pParty->vPosition.y + v214;
+				v208 = LODWORD(v725);
+			}
+			signed int _v733 = 0;
+			*(float *)&v732 = (double)v211;
+			LODWORD(v725) = v211 + 2500;
+			v721 = 0;
+			*(float *)&y = (double)(v211 + 2500);
+			v730 = v208 == 3 ? a2 : 0;
+			a2 = 20;
+			do
+			{
+				v215 = rand();
+				v216 = (double)v721;
+				v217 = (double)_v733;
+				*(float *)&uRequiredMana = v217;
+				_this = (ItemGen *)(v215 % 1000);
+				*((float *)&v733 + 1) = (double)(v215 % 1000) + *(float *)&v732 - *(float *)&y;
+				*(float *)&v721 = v217 * v217;
+				//*(float *)&v726 = v216 * v216;
+				if ( sqrt(*((float *)&v733 + 1) * *((float *)&v733 + 1) + v216 * v216 + *(float *)&v721) <= 1.0 )
+				{
+					LODWORD(v685) = 0;
+					HIDWORD(v685) = 0;
+				}
+				else
+				{
+					v684 = (signed __int64)sqrt(v216 * v216 + *(float *)&v721);
+					v685 = __PAIR__(
+								stru_5C6E00->Atan2(v684, (signed __int64)*((float *)&v733 + 1)),
+								stru_5C6E00->Atan2((signed __int64)v216, (signed __int64)*(float *)&uRequiredMana));
+				}
+				pSpellSprite.stru_24.Reset();
+				pSpellSprite.spell_id = pCastSpell->spellnum;
+				pSpellSprite.spell_level = v2;
+				pSpellSprite.spell_skill = v731;
+				pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+				pSpellSprite.uAttributes = 0;
+				pSpellSprite.vPosition.x = LODWORD(v718);
+				pSpellSprite.vPosition.y = v713;
+				pSpellSprite.uSectorID = 0;
+				pSpellSprite.vPosition.z = (int)((char *)_this + LODWORD(v725));
+				pSpellSprite.uSpriteFrameID = 0;
+				pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+				pSpellSprite.spell_target_pid = v730;
+				//__debugbreak();//
+				pSpellSprite.field_60_distance_related_prolly_lod = stru_50C198._427546((int)&_this[69].uNumCharges);
+				pSpellSprite.uFacing = v685;
+				pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+				if ( pParty->bTurnBasedModeOn == 1 )
+				pSpellSprite.uAttributes = 4;
+				if ( pSpellSprite.Create(v685, SHIDWORD(v685), pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed, 0) != -1
+					   && pParty->bTurnBasedModeOn == 1 )
+				  ++pTurnEngine->field_1C;
+				v721 = rand() % 1024 - 512;
+				v218 = rand();
+				v14 = a2-- == 1;
+				_v733 = (unsigned __int64)(v218 % 1024) - 512;
+			}
+			while ( !v14 );
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_WATER_AWAKEN:
+		{
+			switch (v731)
+			{
+				case 1: amount = 180 * v2; break;
+				case 2: amount = 3600 * v2; break;
+				case 3: amount = 86400 * v2; break;
+				case 4: amount = 0; break;
+				default:
+				assert(false);
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			for( int i=0; i < 4; i++ )
+			{
+				pPlayer = &pParty->pPlayers[i];
+				if ( v731 == 4 )
+				{
+					if ( pPlayer->pConditions[2] )
+					{
+						//*((int *)v222 + 4) = 0;
+						//*((int *)v222 + 5) = 0;
+						pPlayer->pConditions[2] = 0;
+						pPlayer->PlaySound(SPEECH_103, 0);
+					}
+				}
+				else
+				{
+					v223 = pPlayer->DiscardConditionIfLastsLongerThan(
+								2u,
+								pParty->uTimePlayed - (signed int)(signed __int64)((double)(amount << 7) * 0.033333335));
+					if ( v223 )
+						pPlayer->PlaySound(SPEECH_103, 0);
+				}
+			}
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_WATER_POISON_SPRAY:
+		{
+			switch (v731)
+			{
+				case 1: amount = 1; break;
+				case 2: amount = 3; break;
+				case 3: amount = 5; break;
+				case 4: amount = 7; break;
+				default:
+				assert(false);
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			signed int _v733 = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360;
+			if ( amount == 1 )
+			{
+				pSpellSprite.stru_24.Reset();
+				pSpellSprite.spell_id = pCastSpell->spellnum;
+				pSpellSprite.spell_skill = v731;
+				pSpellSprite.spell_level = v2;
+				pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+				pSpellSprite.vPosition.y = pParty->vPosition.y;
+				v51 = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
+				v671 = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
+				v660 = pParty->vPosition.y;
+//	LABEL_153:
+				pSpellSprite.uAttributes = 0;
+				pSpellSprite.vPosition.x = pParty->vPosition.x;
+				pSpellSprite.vPosition.z = v51;
+				v52 = pIndoor->GetSector(pParty->vPosition.x, v660, v671);
+				pSpellSprite.uSpriteFrameID = 0;
+				pSpellSprite.uSectorID = v52;
+				pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+				pSpellSprite.spell_target_pid = a2;
+				pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
+				pSpellSprite.uFacing = LOWORD(v715.uYawAngle);
+				pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+				if ( pParty->bTurnBasedModeOn == 1 )
+					LOBYTE(pSpellSprite.uAttributes) |= 4u;
+				v659 = pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed;
+				if ( pSpellSprite.Create(v715.uYawAngle, v715.uPitchAngle, v659, pCastSpell->uPlayerID + 1) != -1 && pParty->bTurnBasedModeOn == 1 )
+					++pTurnEngine->field_1C;
+			}
+			else
+			{
+				pSpellSprite.stru_24.Reset();
+				pSpellSprite.spell_id = pCastSpell->spellnum;
+				pSpellSprite.spell_level = v2;
+				pSpellSprite.spell_skill = v731;
+				pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+				pSpellSprite.vPosition.y = pParty->vPosition.y;
+				pSpellSprite.vPosition.x = pParty->vPosition.x;
+				pSpellSprite.uAttributes = 0;
+				pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
+				pSpellSprite.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3);
+				pSpellSprite.uSpriteFrameID = 0;
+				pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+				pSpellSprite.spell_target_pid = a2;
+				pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
+				pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+				if ( pParty->bTurnBasedModeOn == 1 )
+					LOBYTE(pSpellSprite.uAttributes) |= 4u;
+				v227 = _v733 / -2;
+				signed int _y = _v733 / 2;
+				if ( _v733 / -2 <= _v733 / 2 )
+				{
+					v228 = v715.uYawAngle;
+					do
+					{
+						pSpellSprite.uFacing = v227 + v228;
+						if ( pSpellSprite.Create(
+								v227 + v228,
+								v715.uPitchAngle,
+								pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed,
+								pCastSpell->uPlayerID + 1) != -1
+								&& pParty->bTurnBasedModeOn == 1 )
+							++pTurnEngine->field_1C;
+						v227 += _v733 / (amount - 1);
+					}
+					while ( v227 <= _y );
+				}
+			}
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_WATER_WATER_WALK:
+		{
+			if ( !pPlayers[pCastSpell->uPlayerID + 1]->GetMaxMana() )
+			{
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2);  // Spell failed
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				break;
+			}
+			if ( v731 == 2 || v731 != 3 && v731 != 4 )
+				v229 = 600 * v2;
+			else
+				v229 = 3600 * v2;
+			LODWORD(v733) = v229;
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			v716 = pOtherOverlayList->_4418B1(10005, 201, 0, 65536);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
+
+			pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].Apply(
+				pParty->uTimePlayed + (signed int)(signed __int64)((double)(v229 << 7) * 0.033333335),
+				v731,
+				amount,
+				v716,
+				pCastSpell->uPlayerID + 1);
+			if ( v731 == 4 )
+				pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].uFlags = 1;
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_WATER_RECHARGE_ITEM:
+		{
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			v240 = &pParty->pPlayers[pCastSpell->uPlayerID_2].pInventoryItems[a2];
+			
+			if ( pItemsTable->pItems[v240->uItemID].uEquipType != 12 || v240->uAttributes & 2 )
+			{
+				dword_50C9D0 = 113;
+				dword_50C9D4 = 0;
+				dword_50C9D8 = 1;
+
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2);  // Spell failed
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				pCastSpell->spellnum = 0;
+				continue;
+			}
+			if ( v731 == 1 || v731 == 2 )
+			{
+				v241 = (double)v723 * 0.0099999998 + 0.5;
+			}
+			else if ( v731 == 3 )
+			{
+				v241 = (double)v723 * 0.0099999998 + 0.69999999;
+			}
+			else if ( v731 == 4 )
+			{
+				v241 = (double)v723 * 0.0099999998 + 0.80000001;
+			}
+			else
+			{
+				v241 = 0.0;
+			}
+			if ( v241 > 1.0 )
+				v241 = 1.0;
+			int uNewCharges = v240->uMaxCharges * v241;
+			v240->uMaxCharges = uNewCharges;
+			v240->uNumCharges = uNewCharges;
+			if ( uNewCharges <= 0 )
+			{
+				v240 = 0;
+				dword_50C9D0 = 113;
+				dword_50C9D4 = 0;
+				dword_50C9D8 = 1;
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2u);
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				pCastSpell->spellnum = 0;
+				v2 = v723;
+				continue;
+			}
+			v240->uAttributes |= 0x40u;
+			_50C9A8_item_enchantment_timer = 256;
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_WATER_ENCHANT_ITEM:
+		{
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			uRequiredMana = 0;
+			amount = 10 * v2;
+			v730 = 1;
+			pPlayer = &pParty->pPlayers[pCastSpell->uPlayerID_2];
+			v245 = &pPlayer->pInventoryItems[a2];
+			ItemDesc *_v725 = &pItemsTable->pItems[v245->uItemID];
+			if ( 
+				v731 == 1 || v731 == 2 && _v725->uEquipType > 2 ||
+				v731 == 3 || v731 == 4 && 
+				v245->uItemID <= 134 &&
+				v245->uSpecEnchantmentType == 0 &&
+				v245->uEnchantmentType == 0 &&
+				v245->_bonus_strength== 0 &&
+				!v245->Broken() )
+			{
+				if ( v245->GetValue() < 450 || 
+					(v245->GetValue() < 250 && (v731 == 3 || v731 == 4) && _v725->uEquipType >= 0 && _v725->uEquipType <= 2)
+					)
+				{
+					v730 = 0;
+				}
+				if ( rand() % 100 < 10 * v2 || 
+					(rand() % 100 < 80 && (v731 == 3 || v731 == 4 )) ||
+					v245->GetValue() < 450 || 
+					(v245->GetValue() < 250 && (v731 == 3 || v731 == 4) && v271 >= 0 && v271 <= 2)
+					)
+				{
+					v313 = _v725->uEquipType;
+					if ( _v725->uEquipType >= 3 && _v725->uEquipType <= 11 )
+					{
+						v295 = rand() % 10;// pItemsTable->field_116D8[pItemsTable->pItems[_this->uItemID].uEquipType];
+						v245->uEnchantmentType = 0;
+						for ( kk = pItemsTable->pEnchantments[0].to_item[pItemsTable->pItems[v245->uItemID].uEquipType + 1];
+							;
+							kk += pItemsTable->pEnchantments[v294->uEnchantmentType].to_item[pItemsTable->pItems[v245->uItemID].uEquipType + 1] )
+						{
+							++v245->uEnchantmentType;
+							if ( kk >= v295 )
+								break;
+						}
+						v255 = 10;//pItemsTable->field_116D8[17];
+						v256 = 10;//pItemsTable->field_116D8[16];
+						v245->_bonus_strength = v256 + rand() % (v255 - v256 + 1);
+						v245->uAttributes |= 0x20u;
+						_50C9A8_item_enchantment_timer = 256;
+						LODWORD(v727) = 1;
+						break;
+					}
+					else if ( v731 == 3 || v731 == 4)
+					{
+					v257 = pItemsTable->pSpecialEnchantments_count;
+					v258 = 0;
+					v725 = 0.0;
+					int _v733 = 0;
+					if ( pItemsTable->pSpecialEnchantments_count > 0 )
+					{
+						v730 = (int)&v679;
+						do
+						{
+							v259 = LOBYTE(pItemsTable->pSpecialEnchantments[v258 + 1].pBonusStatement);
+							if ( !v259 || v259 == 1 )
+							{
+								v260 = *(&pItemsTable->pSpecialEnchantments[0].to_item_apply[pItemsTable->pItems[*(int *)v245].uEquipType
+																					+ 4]
+										+ v258 * 28);
+								LODWORD(v725) += v260;
+								if ( v260 )
+								{
+									v261 = v730;
+									v730 += 4;
+									*(int *)v261 = _v733;
+								}
+							}
+							++_v733;
+							++v258;
+						}
+						while ( _v733 < v257 );
+					}
+					v262 = rand() % SLODWORD(v725);
+					v263 = v679;
+					v245->uSpecEnchantmentType = v679[0];
+					v264 = pItemsTable->pSpecialEnchantments[*v263].to_item_apply[pItemsTable->pItems[*(int *)v245].uEquipType + 4];
+					v265 = v262 + 1;
+					if ( v264 < v265 )
+					{
+						for ( ii = v679; ; ii = (int *)v732 )
+						{
+							v267 = (int)(ii + 1);
+							v732 = v267;
+							v268 = *(int *)v267;
+							*(int *)(v245 + 12) = v268;
+							v264 += pItemsTable->pSpecialEnchantments[v268].to_item_apply[pItemsTable->pItems[*(int *)v245].uEquipType
+																				+ 4];
+							if ( v264 >= v265 )
+								break;
+						}
+					}
+
+						v277 = pItemsTable->pSpecialEnchantments_count;
+						v278 = 0;
+						v725 = 0.0;
+						_v733 = 0;
+						if ( pItemsTable->pSpecialEnchantments_count > 0 )
+						{
+							int *_v730 = v679;
+							do
+							{
+								v279 = LOBYTE(pItemsTable->pSpecialEnchantments[v278].pBonusStatement);
+								if ( !v279 || v279 == 1 )
+								{
+									v280 = *(&pItemsTable->pSpecialEnchantments[v278].to_item_apply[pItemsTable->pItems[v245->uItemID].uEquipType]);
+									_v733 += v280;
+									if ( v280 )
+									{
+										v281 = _v730;
+										++_v730;
+										*v281 = _v733;
+									}
+								}
+								++_v733;
+								++v278;
+							}
+							while ( _v733 < v277 );
+						}
+						v282 = rand() % _v733;
+						v283 = v679;
+						v245->uSpecEnchantmentType = v679[0];
+						v284 = pItemsTable->pSpecialEnchantments[*v283].to_item_apply[pItemsTable->pItems[v245->uItemID].uEquipType ];
+						v285 = v282 + 1;
+						for ( l = v679; v284 < v285; ++l )
+						{
+							v245->uSpecEnchantmentType = *(l+1);
+							v284 += pItemsTable->pSpecialEnchantments[*(l+1)].to_item_apply[pItemsTable->pItems[v245->uItemID].uEquipType];
+						}
+						++v245->uSpecEnchantmentType;
+						v245->uAttributes |= 0x20u;
+						_50C9A8_item_enchantment_timer = 256;
+						LODWORD(v727) = 1;
+						break;
+					}
+				}
+				else
+				{
+					if ( !(BYTE1(v245->uAttributes) & 2) )
+					{
+						v245->uAttributes |= 2;
+					}
+				}
+						
+			}
+
+			if ( LODWORD(v727) == 0 )
+			{
+				v317 = pGlobalTXT_LocalizationStrings[428];
+				if ( v730 == 0 )
+					v317 = pGlobalTXT_LocalizationStrings[585];
+				ShowStatusBarString(v317, 2u);
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				v318 =  &pParty->pPlayers[pCastSpell->uPlayerID_2];
+				pCastSpell->spellnum = 0;
+				v318->PlaySound(SPEECH_43, 0);
+			}
+
+			break;
+		}
+		case SPELL_WATER_TOWN_PORTAL:
+		{
+			amount = 10 * v2;
+			if ( pPlayer->sMana < (signed int)uRequiredMana )
+				break;
+			if ( pParty->uFlags & (PARTY_FLAGS_1_ALERT_RED | PARTY_FLAGS_1_ALERT_YELLOW) && v731 != 4 || rand() % 100 >= amount && v731 != 4 )
+			{
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				pCastSpell->spellnum = 0;
+				continue;
+			}
+			town_portal_caster_id = LOBYTE(pCastSpell->uPlayerID);
+			pMessageQueue_50CBD0->AddMessage(UIMSG_OnCastTownPortal, 0, 0);
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_WATER_LLOYDS_BEACON:
+		{
+			LODWORD(v733) = 604800 * v2;
+			if ( !_stricmp(pCurrentMapName.data(), "d05.blv") )
+			{
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				pCastSpell->spellnum = 0;
+				continue;
+			}
+			v319 = uRequiredMana;
+			if ( pPlayer->sMana >= (signed int)uRequiredMana )
+			{
+				pEventTimer->Pause();
+				pMessageQueue_50CBD0->AddMessage(UIMSG_OnCastLloydsBeacon, 0, 0);
+				qword_506350 = (signed int)v733;
+				_506348_current_lloyd_playerid = pCastSpell->uPlayerID;
+				::uRequiredMana = v319;
+				::sRecoveryTime = sRecoveryTime;
+				dword_50633C = pCastSpell->sound_id;
+				dword_506338 = pCastSpell->spellnum;
+				LOBYTE(pCastSpell->field_8) |= 0x20u;
+			}
+			break;
+		}
+		case SPELL_EARTH_STONE_TO_FLESH:
+		{
+			__debugbreak(); // missing GM ?
+			switch (v731)
+			{
+				case 1: amount = 3600 * v2; break;
+				case 2: amount = 3600 * v2; break;
+				case 3: amount = 86400 * v2; break;
+				case 4: break;
+				default:
+				assert(false);
+			}
+	//LABEL_634:
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			v323 = pCastSpell->uPlayerID_2;
+			v324 = (char *)&pParty->pPlayers[v323].pConditions[15];
+			if ( !pParty->pPlayers[v323].pConditions[15] )
+			{
+				LODWORD(v727) = 1;
+				break;
+			}
+			if ( v731 == 4 )
+			{
+				*(int *)v324 = 0;
+				*((int *)v324 + 1) = 0;
+				LODWORD(v727) = 1;
+				break;
+			}
+			v732 = amount << 7;
+			v663 = (signed __int64)((double)(signed __int64)pParty->uTimePlayed - (double)(amount << 7) * 0.033333335);
+			v656 = 15;
+			v325 = &pParty->pPlayers[v323];
+			v325->DiscardConditionIfLastsLongerThan(v656, v663);
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_EARTH_ROCK_BLAST:
+		{
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			pSpellSprite.stru_24.Reset();
+			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_level = v2;
+			pSpellSprite.spell_skill = v731;
+			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+			pSpellSprite.vPosition.y = pParty->vPosition.y;
+			pSpellSprite.vPosition.x = pParty->vPosition.x;
+			pSpellSprite.uAttributes = 0;
+			pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
+			pSpellSprite.uSectorID = pIndoor->GetSector(
+								pParty->vPosition.x,
+								pParty->vPosition.y,
+								pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3);
+			pSpellSprite.uSpriteFrameID = 0;
+			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+			pSpellSprite.spell_target_pid = a2;
+			pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
+			pSpellSprite.uFacing = LOWORD(pParty->sRotationY);
+			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+			if ( pParty->bTurnBasedModeOn == 1 )
+				LOBYTE(pSpellSprite.uAttributes) |= 4u;
+
+			v659 = pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed;
+			if ( pSpellSprite.Create(pParty->sRotationY, pParty->sRotationX, v659, pCastSpell->uPlayerID + 1) != -1 && pParty->bTurnBasedModeOn == 1 )
+				++pTurnEngine->field_1C;
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_EARTH_DEATH_BLOSSOM:
+		{
+			if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
+			{
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				pCastSpell->spellnum = 0;
+				continue;
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			pSpellSprite.uType = 4090;
+			pSpellSprite.stru_24.Reset();
+			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_level = v2;
+			pSpellSprite.spell_skill = v731;
+			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+			pSpellSprite.vPosition.x = pParty->vPosition.x;
+			pSpellSprite.vPosition.y = pParty->vPosition.y;
+			pSpellSprite.uAttributes = 0;
+			pSpellSprite.uSectorID = 0;
+			pSpellSprite.uSpriteFrameID = 0;
+			pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
+			pSpellSprite.field_60_distance_related_prolly_lod = 0;
+			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+			pSpellSprite.spell_target_pid = a2;
+			pSpellSprite.uFacing = LOWORD(pParty->sRotationY);
+			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+			if ( pParty->bTurnBasedModeOn == 1 )
+				pSpellSprite.uAttributes = 4;
+
+			v659 = pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed;
+			if ( pSpellSprite.Create(pParty->sRotationY, stru_5C6E00->uIntegerHalfPi / 2, v659, 0) != -1 && pParty->bTurnBasedModeOn == 1 )
+				++pTurnEngine->field_1C;
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_SPIRIT_DETECT_LIFE:
+		{
+			v328 = v731 - 2;
+			if ( v328 )
+			{
+				v329 = v328 - 1;
+				if ( v329 && v329 != 1 )
+					v330 = 600 * v2;
+				else
+					v330 = 3600 * v2;
+			}
+			else
+			{
+				v330 = 1800 * v2;
+			}
+			LODWORD(v733) = v330;
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
+
+			pParty->pPartyBuffs[PARTY_BUFF_DETECT_LIFE].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, 0, 0, 0);
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_SPIRIT_FATE:
+		{
+			switch (v731)
+			{
+				case 1: amount = 1 * v2; break;
+				case 2: amount = 2 * v2; break;
+				case 3: amount = 4 * v2; break;
+				case 4: amount = 6 * v2; break;
+				default:
+				assert(false);
+			}
+			LODWORD(v733) = 300;
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			v342 = pCastSpell->spell_target_pid;
+			if ( v342 == 0 )
+			{
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+
+				pParty->pPlayers[pCastSpell->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_FATE].Apply(pParty->uTimePlayed + 1280, v731, amount, 0, 0);
+				LODWORD(v727) = 1;
+				break;
+			}
+			if (PID_TYPE(v342) == OBJECT_Actor)
+			{
+				v343 = PID_ID(v342);
+				HIDWORD(v344) = 0 + ((pParty->uTimePlayed + 1280) >> 32);
+				LODWORD(v344) = LODWORD(pParty->uTimePlayed) + 1280;
+				pActors[v343].pActorBuffs[11].Apply(v344, v731, amount, 0, 0);
+				BYTE2(pActors[v343].uAttributes) |= 8u;
+				//v672 = 0;
+				v661 = &pActors[v343];
+				pGame->GetStru6()->_4A7E89_sparkles_on_actor_after_it_casts_buff(v661, 0);
+			}
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_SPIRIT_REMOVE_CURSE:
+		{
+			switch (v731)
+			{
+				case 1: amount = 3600 * v2; break;
+				case 2: amount = 3600 * v2; break;
+				case 3: amount = 86400 * v2; break;
+				case 4: amount = 0; break;
+				default:
+				assert(false);
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			v351 = &pParty->pPlayers[pCastSpell->uPlayerID_2];
+			if ( !v351->pConditions[0] )
+			{
+				LODWORD(v727) = 1;
+				break;
+			}
+			if ( v731 == 4 )
+			{
+				LODWORD(v351->pConditions[0]) = 0;
+				HIDWORD(v351->pConditions[0]) = 0;
+			}
+			else
+			{
+				v732 = amount << 7;
+				v351->DiscardConditionIfLastsLongerThan(0, (signed __int64)((double)(signed __int64)pParty->uTimePlayed - (double)(amount << 7) * 0.033333335));
+				if ( HIDWORD(pParty->pPlayers[pCastSpell->uPlayerID_2].pConditions[0]) | LODWORD(pParty->pPlayers[pCastSpell->uPlayerID_2].pConditions[0]) )
+				{
+					LODWORD(v727) = 1;
+					break;
+				}
+			}
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_SPIRIT_PRESERVATION:
+		{
+			if ( v731 == 4 )
+				LODWORD(v733) = 900 * (v2 + 4);
+			else
+				LODWORD(v733) = 300 * (v2 + 12);
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			if ( v731 == 1 || v731 == 2 )
+			{
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+				pParty->pPlayers[pCastSpell->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_PRESERVATION].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, 0, 0, 0);
+				LODWORD(v727) = 1;
+				break;
+			}
+			a2 = 0;
+			v717 = (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
+			v357 = pParty->pPlayers;//[0].pPlayerBuffs[11];
+			do
+			{
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, a2);
+				v357->pPlayerBuffs[PLAYER_BUFF_PRESERVATION].Apply(pParty->uTimePlayed + v717, v731, 0, 0, 0);
+				++a2;
+				++v357;// = (SpellBuff *)((char *)v357 + 6972);
+			}
+			while ( v357 <= &pParty->pPlayers[3] );
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_SPIRIT_TURN_UNDEAD:
+		{
+			if ( v731 == 1 || v731 == 2)
+				LODWORD(v733) = 60 * (v2 + 3);
+			else
+				LODWORD(v733) = 300 * v2 + 180;
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			auto _v726 = sub_46A6AC((int)dword_50BF30.data(), 100, 4096);
+			pGame->GetStru6()->FadeScreen__like_Turn_Undead_and_mb_Armageddon(0xFFFFFFu, 0xC0u);
+			++pSpellSprite.uType;
+			pSpellSprite.stru_24.Reset();
+			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_level = v2;
+			pSpellSprite.spell_skill = v731;
+			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+			pSpellSprite.uAttributes = 0;
+			pSpellSprite.uSectorID = 0;
+			pSpellSprite.uSpriteFrameID = 0;
+			pSpellSprite.field_60_distance_related_prolly_lod = 0;
+			pSpellSprite.uFacing = 0;
+			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+			for ( a2 = 0; a2 < (signed int)_v726; ++a2 )
+			{
+				v369 = &pActors[dword_50BF30[a2]];
+				if ( MonsterStats::BelongsToSupertype(v369->pMonsterInfo.uID, MONSTER_SUPERTYPE_UNDEAD) )
+				{
+					pSpellSprite.vPosition.x = v369->vPosition.x;
+					pSpellSprite.vPosition.y = v369->vPosition.y;
+					pSpellSprite.vPosition.z = v369->vPosition.z - (unsigned int)(signed __int64)((double)v369->uActorHeight * unk_4D8548);
+
+					pSpellSprite.spell_target_pid = PID(OBJECT_Actor, dword_50BF30[a2]);
+					pSpellSprite.Create(0, 0, 0, 0);
+					v369->pActorBuffs[4].Apply(
+						pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335),
+						v731, 0, 0, 0);
+				}
+			}
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_SPIRIT_RAISE_DEAD:
+		{
+			if ( v731 == 4 )
+				amount = 0;
+			else
+				amount = 86400 * v2;
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			pOtherOverlayList->_4418B1(5080, pCastSpell->uPlayerID_2 + 100, 0, 65536);
+			v373 = pCastSpell->uPlayerID_2;
+			if ( !(HIDWORD(pParty->pPlayers[v373].pConditions[14]) | LODWORD(pParty->pPlayers[v373].pConditions[14])) )
+			{
+				LODWORD(v727) = 1;
+				break;
+			}
+			v14 = v731 == 4;
+			pParty->pPlayers[v373].sHealth = 1;
+			if ( v14 )
+			{
+				v374 = pCastSpell->uPlayerID_2;
+				LODWORD(pParty->pPlayers[v374].pConditions[14]) = 0;
+				HIDWORD(pParty->pPlayers[v374].pConditions[14]) = 0;
+				v376 = pCastSpell->uPlayerID_2;
+				LODWORD(pParty->pPlayers[v376].pConditions[13]) = 0;
+				HIDWORD(pParty->pPlayers[v376].pConditions[13]) = 0;
+			}
+			else
+			{
+				*(float *)&a2 = (double)(amount << 7) * 0.033333335;
+				pParty->pPlayers[pCastSpell->uPlayerID_2].DiscardConditionIfLastsLongerThan(
+				0xEu,
+				(signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2));
+				pParty->pPlayers[pCastSpell->uPlayerID_2].DiscardConditionIfLastsLongerThan(
+				0xDu,
+				(signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2));
+			}
+			v377 = &pParty->pPlayers[pCastSpell->uPlayerID_2];
+			v377->SetCondition(1, 0);
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_SPIRIT_SHARED_LIFE:
+		{
+			if ( v731 == 4 )
+				amount = 4 * v2;
+			else
+				amount = 3 * v2;
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			v381 = 0;
+			signed int _v733 = amount;
+			v730 = 0;
+			v382 = 1;
+			do
+			{
+				v383 = pPlayers[v382];
+				if ( !v383->pConditions[14] && !v383->pConditions[15] && !v383->pConditions[16] )
+				v682[v381++] = v382;
+				++v382;
+			}
+			while ( v382 <= 4 );
+			v384 = 0;
+			v730 = v381;
+			if ( v381 > 0 )
+			{
+				do
+					_v733 += pPlayers[v682[v384++]]->sHealth;
+				while ( v384 < v381 );
+			}
+			v732 = (signed __int64)((double)_v733 / (double)v730);
+			_v733 = 0;
+			if ( v381 > 0 )
+			{
+				do
+				{
+					//v385 = (ItemGen **)&pPlayers[v682[HIDWORD(v733)]];
+					v726 = pPlayers[v682[_v733]];
+					v726->sHealth = v732;
+					//v386 = v726->GetMaxHealth();
+					if ( v726->sHealth > v726->GetMaxHealth())
+						v726->sHealth = v726->GetMaxHealth();
+					if ( v726->sHealth > 0 )
+					{
+						v726->pConditions[Player::Condition_Unconcious] = 0;
+					}
+					v388 = _v733;
+
+					pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, LOWORD(v682[_v733]) - 1);
+					_v733 = v388 + 1;
+				}
+				while ( v388 + 1 < v730 );
+			}
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_SPIRIT_RESSURECTION:
+		{
+			switch (v731)
+			{
+				case 1: amount = 180 * v2; break;
+				case 2: amount = 10800 * v2; break;
+				case 3: amount = 259200 * v2; break;
+				case 4: amount = 0; break;
+				default:
+				assert(false);
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			v396 = pCastSpell->uPlayerID_2;
+			if ( HIDWORD(pParty->pPlayers[v396].pConditions[16]) | LODWORD(pParty->pPlayers[v396].pConditions[16])
+				|| HIDWORD(pParty->pPlayers[v396].pConditions[14]) | LODWORD(pParty->pPlayers[v396].pConditions[14]) )
+			{
+				if ( !(HIDWORD(pParty->pPlayers[v396].pConditions[1]) | LODWORD(pParty->pPlayers[v396].pConditions[1])) )
+					pParty->pPlayers[v396].PlaySound(SPEECH_25, 0);
+				if ( v731 == 4 )
+				{
+					v397 = pCastSpell->uPlayerID_2;
+					LODWORD(pParty->pPlayers[v397].pConditions[16]) = 0;
+					HIDWORD(pParty->pPlayers[v397].pConditions[16]) = 0;
+					v398 = pCastSpell->uPlayerID_2;
+					LODWORD(pParty->pPlayers[v398].pConditions[14]) = 0;
+					HIDWORD(pParty->pPlayers[v398].pConditions[14]) = 0;
+					v399 = pCastSpell->uPlayerID_2;
+					LODWORD(pParty->pPlayers[v399].pConditions[13]) = 0;
+					HIDWORD(pParty->pPlayers[v399].pConditions[13]) = 0;
+				}
+				else
+				{
+					*(float *)&a2 = (double)(amount << 7) * 0.033333335;
+					pParty->pPlayers[pCastSpell->uPlayerID_2].DiscardConditionIfLastsLongerThan( 0x10u,
+						(signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2));
+					pParty->pPlayers[pCastSpell->uPlayerID_2].DiscardConditionIfLastsLongerThan( 0xEu,
+						(signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2));
+					pParty->pPlayers[pCastSpell->uPlayerID_2].DiscardConditionIfLastsLongerThan( 0xDu,
+						(signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2));
+				}
+				pParty->pPlayers[pCastSpell->uPlayerID_2].SetCondition(1u, 1);
+				pParty->pPlayers[pCastSpell->uPlayerID_2].sHealth = 1;
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+			}
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_MIND_CURE_PARALYSIS:
+		{
+			switch (v731)
+			{
+				case 1: amount = 3600 * v2; break;
+				case 2: amount = 3600 * v2; break;
+				case 3: amount = 86400 * v2; break;
+				case 4: amount = 0; break;
+				default:
+				assert(false);
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+			v323 = pCastSpell->uPlayerID_2;
+			v324 = (char *)&pParty->pPlayers[v323].pConditions[12];
+			if ( !pParty->pPlayers[v323].pConditions[12] )
+			{
+				LODWORD(v727) = 1;
+				break;
+			}
+			if ( v731 == 4 )
+			{
+				*(int *)v324 = 0;
+				*((int *)v324 + 1) = 0;
+				LODWORD(v727) = 1;
+				break;
+			}
+			v663 = (signed __int64)((double)(signed __int64)pParty->uTimePlayed - (double)(amount << 7) * 0.033333335);
+			v656 = 12;
+			v325 = &pParty->pPlayers[v323];
+			v325->DiscardConditionIfLastsLongerThan(v656, v663);
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_MIND_REMOVE_FEAR:
+		{
+			switch (v731)
+			{
+				case 1: amount = 180 * v2; break;
+				case 2: amount = 3600 * v2; break;
+				case 3: amount = 86400 * v2; break;
+				case 4: amount = 0; break;
+				default:
+				assert(false);
+			}
+
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+			v323 = pCastSpell->uPlayerID_2;
+			v324 = (char *)&pParty->pPlayers[v323].pConditions[3];
+			if ( !pParty->pPlayers[v323].pConditions[3] )
+			{
+				LODWORD(v727) = 1;
+				break;
+			}
+			if ( v731 == 4 )
+			{
+				*(int *)v324 = 0;
+				*((int *)v324 + 1) = 0;
+				LODWORD(v727) = 1;
+				break;
+			}
+			v663 = (signed __int64)((double)(signed __int64)pParty->uTimePlayed - (double)(amount << 7) * 0.033333335);
+			v656 = 3;
+			v325 = &pParty->pPlayers[v323];
+			v325->DiscardConditionIfLastsLongerThan(v656, v663);
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_MIND_TELEPATHY:
+		{
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			if (PID_TYPE(a2) != OBJECT_Actor)
+			{
+				LODWORD(v727) = 1;
+				break;
+			}
+			v417 = &pActors[PID_ID(a2)];
+			Actor * _v730 = v417;
+			if ( !(BYTE2(v417->uAttributes) & 0x80) )
+			{
+				v417->SetRandomGoldIfTheresNoItem();
+				v417 = _v730;
+			}
+			v418 = v417->array_000234[3].uItemID;
+			signed int _v733 = 0;
+			if ( pItemsTable->pItems[v418].uEquipType == 18 )
+				_v733 = v417->array_000234[3].uSpecEnchantmentType;
+
+			//ItemGen::ItemGen(&v683);
+			v683.Reset();
+
+			v419 = _v730->uCarriedItemID;
+			if (v419)
+			{
+				v683.uItemID = v419;
+				//goto LABEL_799;
+			}
+			else
+			{
+				v420 = 0;
+				v421 = _v730->array_000234;
+				while ( !v421->uItemID || pItemsTable->pItems[v421->uItemID].uEquipType == 18 )
+				{
+					++v420;
+					++v421;
+					if ( v420 >= 4 )
+						break;
+				}
+				if ( v420 < 4 )
+				{
+					memcpy(&v683, &_v730->array_000234[v420], sizeof(v683));
+					v2 = v723;
+					//v1 = 0;
+				}
+			}
+//	LABEL_799:
+			if ( _v733 != 0 )
+			{
+				v675 = _v733;
+				if (v683.uItemID)
+				{
+					v422 = v683.GetDisplayName();
+					sprintf(pTmpBuf2.data(), "(%s), and %d gold", v422, v675);
+
+				}
+				else
+				{
+					v664 = "%d gold";
+					sprintf(pTmpBuf2.data(), v664, v675);
+				}
+			}
+			else
+			{
+				if (v683.uItemID)
+				{
+					const char *_v675 = v683.GetDisplayName();
+					v664 = "(%s)";
+					sprintf(pTmpBuf2.data(), v664, _v675);
+				}
+				else
+				{
+					strcpy(pTmpBuf2.data(), "nothing");
+					ShowStatusBarString(pTmpBuf2.data(), 2u);
+				}
+			}
+			ShowStatusBarString(pTmpBuf2.data(), 2u);
+			pSpellSprite.stru_24.Reset();
+			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_level = v2;
+			pSpellSprite.spell_skill = v731;
+			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+			pSpellSprite.vPosition.x = _v730->vPosition.x;
+			pSpellSprite.vPosition.y = _v730->vPosition.y;
+			v676 = _v730->uActorHeight;
+			v665 = pSpellSprite.vPosition.y;
+			pSpellSprite.vPosition.z = _v730->uActorHeight;
+			v657 = pSpellSprite.vPosition.x;
+			pSpellSprite.uAttributes = 0;
+			pSpellSprite.uSectorID = pIndoor->GetSector(v657, v665, v676);
+			pSpellSprite.uSpriteFrameID = 0;
+			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+			pSpellSprite.spell_target_pid = a2;
+			pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
+			pSpellSprite.uFacing = LOWORD(v715.uYawAngle);
+			LOBYTE(pSpellSprite.uAttributes) |= 0x80u;
+			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+			pSpellSprite.Create(0, 0, 0, pCastSpell->uPlayerID + 1);
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_MIND_BERSERK:
+		{
+			switch (v731)
+			{
+				case 1: amount = 300 * v2; break;
+				case 2: amount = 300 * v2; break;
+				case 3: amount = 600 * v2; break;
+				case 4: amount = 3600; break;
+				default:
+				assert(false);
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			v426 = PID_ID(a2);
+			if (PID_TYPE(a2) != OBJECT_Actor)
+			{
+				LODWORD(v727) = 1;
+				break;
+			}
+			v730 = 836 * v426;
+			if ( stru_50C198.GetMagicalResistance(&pActors[v426], 7u) )
+			{
+				pActors[v426].pActorBuffs[1].Reset();
+				pActors[v426].pActorBuffs[12].Reset();
+				pActors[v426].pActorBuffs[9].Apply(
+				pParty->uTimePlayed + (signed __int64)((double)(amount << 7) * 0.033333335),
+				v731, 0, 0, 0);
+				pActors[v426].pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Long;
+			}
+			pSpellSprite.stru_24.Reset();
+			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_level = v2;
+			pSpellSprite.spell_skill = v731;
+			v60 = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+			v61 = v426;
+			v600 = pActors[v61].vPosition.y;
+			v601 = pActors[v61].vPosition.x;
+			pSpellSprite.uObjectDescID = v60;
+			pSpellSprite.vPosition.x = v601;
+			v602 = pActors[v61].uActorHeight;
+			v603 = pActors[v61].vPosition.z;
+			pSpellSprite.vPosition.y = v600;
+			v676 = v603 + v602;
+			v665 = v600;
+			pSpellSprite.vPosition.z = v603 + v602;
+			v657 = v601;
+			pSpellSprite.uAttributes = 0;
+			pSpellSprite.uSectorID = pIndoor->GetSector(v657, v665, v676);
+			pSpellSprite.uSpriteFrameID = 0;
+			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+			pSpellSprite.spell_target_pid = a2;
+			pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
+			pSpellSprite.uFacing = LOWORD(v715.uYawAngle);
+			LOBYTE(pSpellSprite.uAttributes) |= 0x80u;
+			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+			pSpellSprite.Create(0, 0, 0, pCastSpell->uPlayerID + 1);
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_MIND_ENSLAVE:
+		{
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			amount = 600 * v2;
+			if (PID_TYPE(a2) != OBJECT_Actor)
+			{
+				LODWORD(v727) = 1;
+				break;
+			}
+			v730 = 836 * PID_ID(a2);
+			if ( MonsterStats::BelongsToSupertype(pActors[PID_ID(a2)].pMonsterInfo.uID, MONSTER_SUPERTYPE_UNDEAD) )
+				break;
+			if ( stru_50C198.GetMagicalResistance(&pActors[PID_ID(a2)], 7u) )
+			{
+				pActors[PID_ID(a2)].pActorBuffs[9].Reset();
+				pActors[PID_ID(a2)].pActorBuffs[1].Reset();
+				pActors[PID_ID(a2)].pActorBuffs[12].Apply(pParty->uTimePlayed + (signed __int64)((double)(amount << 7) * 0.033333335),
+				v731, 0, 0, 0);
+			}
+			pSpellSprite.stru_24.Reset();
+			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_level = v2;
+			pSpellSprite.spell_skill = v731;
+			v60 = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+			v61 = PID_ID(a2);
+			v600 = pActors[v61].vPosition.y;
+			v601 = pActors[v61].vPosition.x;
+			pSpellSprite.uObjectDescID = v60;
+			pSpellSprite.vPosition.x = v601;
+			v602 = pActors[v61].uActorHeight;
+			v603 = pActors[v61].vPosition.z;
+			pSpellSprite.vPosition.y = v600;
+			v676 = v603 + v602;
+			v665 = v600;
+			pSpellSprite.vPosition.z = v603 + v602;
+			v657 = v601;
+			pSpellSprite.uAttributes = 0;
+			pSpellSprite.uSectorID = pIndoor->GetSector(v657, v665, v676);
+			pSpellSprite.uSpriteFrameID = 0;
+			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+			pSpellSprite.spell_target_pid = a2;
+			pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
+			pSpellSprite.uFacing = LOWORD(v715.uYawAngle);
+			LOBYTE(pSpellSprite.uAttributes) |= 0x80u;
+			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+			pSpellSprite.Create(0, 0, 0, pCastSpell->uPlayerID + 1);
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_MIND_MASS_FEAR:
+		{
+			if ( v731 == 4 )
+				amount = 300 * v2;
+			else
+				amount = 180 * v2;
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			auto _v726 = sub_46A6AC((int)dword_50BF30.data(), 100, 4096);
+			pGame->GetStru6()->FadeScreen__like_Turn_Undead_and_mb_Armageddon(0xA0A0Au, 0xC0u);
+			++pSpellSprite.uType;
+			pSpellSprite.stru_24.Reset();
+			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_level = v2;
+			pSpellSprite.spell_skill = v731;
+			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+			pSpellSprite.uAttributes = 0;
+			pSpellSprite.uSectorID = 0;
+			pSpellSprite.uSpriteFrameID = 0;
+			pSpellSprite.field_60_distance_related_prolly_lod = 0;
+			pSpellSprite.uFacing = 0;
+			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+			for ( a2 = 0; a2 < (signed int)_v726; ++a2 )
+			{
+				v433 = &pActors[dword_50BF30[a2]];
+				if ( MonsterStats::BelongsToSupertype(v433->pMonsterInfo.uID, MONSTER_SUPERTYPE_UNDEAD) )
+					break;
+				pSpellSprite.vPosition.x = v433->vPosition.x;
+				pSpellSprite.vPosition.y = v433->vPosition.y;
+				pSpellSprite.vPosition.z = v433->vPosition.z - (unsigned int)(signed __int64)((double)v433->uActorHeight * unk_4D8548);
+
+				pSpellSprite.spell_target_pid = PID(OBJECT_Actor, dword_50BF30[a2]);
+				pSpellSprite.Create(0, 0, 0, 0);
+				if ( stru_50C198.GetMagicalResistance(v433, 7u) )
+				{
+					v433->pActorBuffs[4].Apply(pParty->uTimePlayed + (signed __int64)((double)(amount << 7) * 0.033333335),
+						v731, 0, 0, 0);
+				}
+			}
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_MIND_CURE_INSANITY:
+		{
+			v435 = v731 - 2;
+			if ( v731 == 4 )
+				amount = 0;
+			else
+				amount = 86400 * v2;
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+			v440 = pCastSpell->uPlayerID_2;
+			if ( HIDWORD(pParty->pPlayers[v440].pConditions[5]) | LODWORD(pParty->pPlayers[v440].pConditions[5]) )
+			{
+				if ( !(HIDWORD(pParty->pPlayers[v440].pConditions[1]) | LODWORD(pParty->pPlayers[v440].pConditions[1])) )
+					pParty->pPlayers[v440].PlaySound(SPEECH_25, 0);
+				if ( v731 == 4 )
+				{
+					v441 = pCastSpell->uPlayerID_2;
+					LODWORD(pParty->pPlayers[v441].pConditions[5]) = 0;
+					HIDWORD(pParty->pPlayers[v441].pConditions[5]) = 0;
+				}
+				else
+				{
+					pParty->pPlayers[pCastSpell->uPlayerID_2].DiscardConditionIfLastsLongerThan(5u,
+						(signed __int64)((double)(signed __int64)pParty->uTimePlayed - (double)(amount << 7) * 0.033333335));
+				}
+				v377 = &pParty->pPlayers[pCastSpell->uPlayerID_2];
+				v377->SetCondition(1, 0);
+			}
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_EARTH_TELEKINESIS:
+		{
+			switch (v731)
+			{
+				case 1: amount = 2 * v2; break;
+				case 2: amount = 2 * v2; break;
+				case 3: amount = 3 * v2; break;
+				case 4: amount = 4 * v2; break;
+				default:
+				assert(false);
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			v445 = PID_ID(a2);
+			if (PID_TYPE(a2) == OBJECT_Item)
+			{
+				v449 = (char *)&pSpriteObjects[v445].stru_24;
+				v450 = *(int *)v449;
+				if ( pItemsTable->pItems[v450].uEquipType == 18 )
+				{
+					party_finds_gold(*((int *)v449 + 3), 0);
+					viewparams->bRedrawGameUI = 1;
+				}
+				else
+				{
+					sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[471], pItemsTable->pItems[v450].pUnidentifiedName);
+					ShowStatusBarString(pTmpBuf2.data(), 2u);
+					if ( !pParty->AddItem(&pSpriteObjects[v445].stru_24) )
+						pParty->SetHoldingItem(&pSpriteObjects[v445].stru_24);
+				}
+				SpriteObject::OnInteraction(v445);
+			}
+			else
+			{
+				if (PID_TYPE(a2) == OBJECT_Actor)
+				{
+					stru_50C198.LootActor(&pActors[v445]);
+				}
+				else
+				{
+					if (PID_TYPE(a2) != OBJECT_Decoration)
+					{
+						if (PID_TYPE(a2) != OBJECT_BModel)
+						{
+							LODWORD(v727) = 1;
+							break;
+						}
+						dword_507CD8 = 1;
+						v677 = 1;
+						if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
+							v446 = pIndoor->pFaceExtras[pIndoor->pFaces[v445].uFaceExtraID].uEventID;
+						else
+							v446 = pOutdoor->pBModels[a2 >> 9].pFaces[v445 & 0x3F].sCogTriggeredID;
+						EventProcessor(v446, a2, v677);
+						LODWORD(v727) = 1;
+						break;
+					}
+					v447 = &pLevelDecorations[v445];
+					dword_507CD8 = 1;
+					v448 = v447->field_16_event_id;
+					if (v448)
+					{
+						v677 = 1;
+						v446 = v448;
+						EventProcessor(v446, a2, v677);
+						LODWORD(v727) = 1;
+						break;
+					}
+					if ( v447->IsInteractive() )
+					{
+						activeLevelDecoration = v447;
+						EventProcessor(stru_5E4C90._decor_events[v447->_idx_in_stru123 - 75] + 380, 0, 1);
+						activeLevelDecoration = NULL;
+					}
+				}
+			}
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_BODY_CURE_WEAKNESS:
+		{
+			switch (v731)
+			{
+				case 1: amount = 180 * v2; break;
+				case 2: amount = 3600 * v2; break;
+				case 3: amount = 86400 * v2; break;
+				case 4: amount = 0; break;
+				default:
+				assert(false);
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+			v323 = pCastSpell->uPlayerID_2;
+			v324 = (char *)&pParty->pPlayers[v323].pConditions[1];
+			if ( !pParty->pPlayers[v323].pConditions[1] )
+			{
+				LODWORD(v727) = 1;
+				break;
+			}
+			if ( v731 == 4 )
+			{
+				*(int *)v324 = 0;
+				*((int *)v324 + 1) = 0;
+				LODWORD(v727) = 1;
+				break;
+			}
+			v663 = (signed __int64)((double)(signed __int64)pParty->uTimePlayed - (double)(amount << 7) * 0.033333335);
+			v656 = 1;
+			v325 = &pParty->pPlayers[v323];
+			v325->DiscardConditionIfLastsLongerThan(v656, v663);
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_BODY_FIRST_AID:
+		{
+			switch (v731)
+			{
+				case 1: amount = 2 * v2 + 5; break;
+				case 2: amount = 3 * v2 + 5; break;
+				case 3: amount = 4 * v2 + 5; break;
+				case 4: amount = 5 * v2 + 5; break;
+				default:
+				assert(false);
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			v460 = pCastSpell->spell_target_pid;
+			if (!v460)
+			{
+				pParty->pPlayers[pCastSpell->uPlayerID_2].Heal(amount);
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+			}
+			else
+			{
+				if (PID_TYPE(v460) == OBJECT_Actor)
+				{
+					v461 = &pActors[PID_ID(v460)];
+					v462 = v461->uAIState;
+					v463 = v461->pMonsterInfo.uHP;
+					if ( v462 != 5 )
+					{
+						if ( v462 != 4 )
+						{
+							if ( v462 != 19 )
+							{
+								if ( v462 != 11 )
+								{
+									v461->sCurrentHP += amount;
+									if ( v461->sCurrentHP > v463 )
+										v461->sCurrentHP = v463;
+								}
+							}
+						}
+					}
+				}
+			}
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_BODY_CURE_POISON:
+		{
+			switch (v731)
+			{
+				case 1: amount = 3600 * v2; break;
+				case 2: amount = 3600 * v2; break;
+				case 3: amount = 86400 * v2; break;
+				case 4: amount = 0; break;
+				default:
+				assert(false);
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+			v470 = pCastSpell->uPlayerID_2;
+			if ( !(HIDWORD(pParty->pPlayers[v470].pConditions[6]) | LODWORD(pParty->pPlayers[v470].pConditions[6]))
+				&& !(HIDWORD(pParty->pPlayers[v470].pConditions[8]) | LODWORD(pParty->pPlayers[v470].pConditions[8]))
+				&& !(HIDWORD(pParty->pPlayers[v470].pConditions[10]) | LODWORD(pParty->pPlayers[v470].pConditions[10])) )
+			{
+				LODWORD(v727) = 1;
+				break;
+			}
+			if ( v731 == 4 )
+			{
+				LODWORD(pParty->pPlayers[v470].pConditions[6]) = 0;
+				HIDWORD(pParty->pPlayers[v470].pConditions[6]) = 0;
+				v471 = pCastSpell->uPlayerID_2;
+				LODWORD(pParty->pPlayers[v471].pConditions[8]) = 0;
+				HIDWORD(pParty->pPlayers[v471].pConditions[8]) = 0;
+				v472 = pCastSpell->uPlayerID_2;
+				LODWORD(pParty->pPlayers[v472].pConditions[10]) = 0;
+				HIDWORD(pParty->pPlayers[v472].pConditions[10]) = 0;
+				LODWORD(v727) = 1;
+				break;
+			}
+			*(float *)&a2 = (double)(amount << 7) * 0.033333335;
+			pParty->pPlayers[v470].DiscardConditionIfLastsLongerThan(
+				6u,
+				(signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2));
+			pParty->pPlayers[pCastSpell->uPlayerID_2].DiscardConditionIfLastsLongerThan(
+				8u,
+				(signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2));
+			v663 = (signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2);
+			v656 = 10;
+			v325 = &pParty->pPlayers[pCastSpell->uPlayerID_2];
+			v325->DiscardConditionIfLastsLongerThan(v656, v663);
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_BODY_PROTECTION_FROM_MAGIC:
+		{
+			amount = v2;
+			LODWORD(v733) = 3600 * v2;
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
+
+			pParty->pPartyBuffs[PARTY_BUFF_PROTECTION_FROM_MAGIC].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, v2, 0, 0);
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_BODY_HAMMERHANDS:
+		{
+			LODWORD(v733) = 3600 * v2;
+			amount = v2;
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			if ( v731 == 4 )
+			{
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
+				v732 = (int)v733 << 7;
+				v717 = (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
+				pParty->pPlayers[0].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].Apply(pParty->uTimePlayed + v717, 4u, v2, v2, 0);
+				pParty->pPlayers[1].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].Apply(pParty->uTimePlayed + v717, 4u, v2, v2, 0);
+				pParty->pPlayers[2].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].Apply(pParty->uTimePlayed + v717, 4u, v2, v2, 0);
+
+				pParty->pPlayers[3].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].Apply(pParty->uTimePlayed + v717, 4, v2, v2, 0);
+				LODWORD(v727) = 1;
+				break;
+			}
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+
+			pParty->pPlayers[pCastSpell->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, v2, v2, 0);
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_BODY_CURE_DISEASE:
+		{
+			if ( v731 == 4 )
+				amount = 0;
+			else
+				amount = 86400 * v2;
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+			v498 = pCastSpell->uPlayerID_2;
+			if ( !(HIDWORD(pParty->pPlayers[v498].pConditions[7]) | LODWORD(pParty->pPlayers[v498].pConditions[7]))
+				&& !(HIDWORD(pParty->pPlayers[v498].pConditions[9]) | LODWORD(pParty->pPlayers[v498].pConditions[9]))
+				&& !(HIDWORD(pParty->pPlayers[v498].pConditions[11]) | LODWORD(pParty->pPlayers[v498].pConditions[11])) )
+			{
+				LODWORD(v727) = 1;
+				break;
+			}
+			if ( v731 == 4 )
+			{
+				LODWORD(pParty->pPlayers[v498].pConditions[7]) = 0;
+				HIDWORD(pParty->pPlayers[v498].pConditions[7]) = 0;
+				v499 = pCastSpell->uPlayerID_2;
+				LODWORD(pParty->pPlayers[v499].pConditions[9]) = 0;
+				HIDWORD(pParty->pPlayers[v499].pConditions[9]) = 0;
+				v500 = pCastSpell->uPlayerID_2;
+				LODWORD(pParty->pPlayers[v500].pConditions[11]) = 0;
+				HIDWORD(pParty->pPlayers[v500].pConditions[11]) = 0;
+			}
+			else
+			{
+				*(float *)&a2 = (double)(amount << 7) * 0.033333335;
+				pParty->pPlayers[v498].DiscardConditionIfLastsLongerThan(
+				7u,
+				(signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2));
+				pParty->pPlayers[pCastSpell->uPlayerID_2].DiscardConditionIfLastsLongerThan(
+				9u,
+				(signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2));
+				v663 = (signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2);
+				v656 = 11;
+				v325 = &pParty->pPlayers[pCastSpell->uPlayerID_2];
+				v325->DiscardConditionIfLastsLongerThan(v656, v663);
+			}
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_BODY_POWER_CURE:
+		{
+			amount = 5 * v2 + 10;
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			v501 = pParty->pPlayers;
+			int v1 = 0;
+			do
+			{
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, v1);
+				v501->Heal(amount);
+				++v501;
+				++v1;
+			}
+			while ( (signed int)v501 < (signed int)pParty->pHirelings );
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_LIGHT_DISPEL_MAGIC:
+		{
+			sRecoveryTime -= v2;
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+
+			pGame->GetStru6()->FadeScreen__like_Turn_Undead_and_mb_Armageddon(0xAFF0Au, 0xC0u);
+			v505 = sub_46A6AC((int)dword_50BF30.data(), 100, 4096);
+			++pSpellSprite.uType;
+			//signed int _v733 = v505;
+			v688.x = 0;
+			v688.y = 0;
+			v688.z = 0;
+			pSpellSprite.stru_24.Reset();
+			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_level = v2;
+			pSpellSprite.spell_skill = v731;
+			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+			pSpellSprite.uAttributes = 0;
+			pSpellSprite.uSectorID = 0;
+			pSpellSprite.uSpriteFrameID = 0;
+			pSpellSprite.field_60_distance_related_prolly_lod = 0;
+			pSpellSprite.uFacing = 0;
+			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+			a2 = 0;
+			for ( a2 = 0; a2 < v505; ++a2 )
+			{
+				v507 = dword_50BF30[a2];
+				pSpellSprite.vPosition.x = pActors[v507].vPosition.x;
+				pSpellSprite.vPosition.y = pActors[v507].vPosition.y;
+				pSpellSprite.vPosition.z = pActors[v507].vPosition.z - (unsigned int)(signed __int64)((double)pActors[v507].uActorHeight * unk_4D8548);
+				pSpellSprite.spell_target_pid = PID(OBJECT_Actor, dword_50BF30[a2]);
+				v509 = pSpellSprite.Create(0, 0, 0, 0);
+				DamageMonsterFromParty(PID(OBJECT_Item, v509), dword_50BF30[a2], &v688);
+			}
+			for ( a2 = 0; a2 < v505; ++a2 )
+			{
+				pActor = &pActors[dword_50BF30[a2]];
+				pSpellSprite.vPosition.x = pActor->vPosition.x;
+				pSpellSprite.vPosition.y = pActor->vPosition.y;
+				pSpellSprite.vPosition.z = pActor->vPosition.z - (unsigned int)(signed __int64)((double)pActor->uActorHeight * unk_4D8548);
+				pSpellSprite.spell_target_pid = PID(OBJECT_Actor, dword_50BF30[a2]);
+				pSpellSprite.Create(0, 0, 0, 0);
+				for (int i = 0; i < 22; ++i)
+				{
+					pActor->pActorBuffs[i].Reset();
+				}
+			}
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_LIGHT_SUMMON_ELEMENTAL:
+		{
+			switch (v731)
+			{
+				case 1: v733 = 300 * v2; amount = 1; break;
+				case 2: v733 = 300 * v2; amount = 1; break;
+				case 3: v733 = 900 * v2; amount = 3; break;
+				case 4: v733 = 900 * v2; amount = 5; break;
+				default:
+				assert(false);
+			}
+			//v733 = __PAIR__(0, v516);
+			signed int _v733 = 0;
+			if ( (signed int)uNumActors > 0 )
+			{
+				v518 = pActors.data();//[0].uAIState;
+				auto _v726 = uNumActors;
+				do
+				{
+					v519 = v518->uAIState;
+					if ( v518->uAIState != 5 && v519 != 11 && v519 != 19 && PID(OBJECT_Player, pCastSpell->uPlayerID) == v518->uSummonerID )
+						++_v733;
+					++v518;
+					--_v726;
+				}
+				while ( _v726 != 0 );
+			}
+			if ( _v733 >= amount )
+			{
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[648], 2);  // This character can't summon any more monsters!
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				pCastSpell->spellnum = 0;
+				continue;
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			sub_44FA4C_spawn_light_elemental(pCastSpell->uPlayerID, v731, v733);
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_LIGHT_DAY_OF_THE_GODS:
+		{
+			switch (v731)
+			{
+				case 1: LODWORD(v733) = 10800 * v2; amount = 3 * v2 + 10; break;
+				case 2: LODWORD(v733) = 10800 * v2; amount = 3 * v2 + 10; break;
+				case 3: LODWORD(v733) = 14400 * v2; amount = 4 * v2 + 10; break;
+				case 4: LODWORD(v733) = 18000 * v2; amount = 5 * v2 + 10; break;
+				default:
+				assert(false);
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
+
+			pParty->pPartyBuffs[PARTY_BUFF_DAY_OF_GODS].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, amount, 0, 0);
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_LIGHT_PRISMATIC_LIGHT:
+		{
+			//v67 = 2;
+			if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor)
+			{
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[497], 2);  // Can't cast Prismatic Light outdoors!
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				pCastSpell->spellnum = 0;
+				continue;
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			v531 = sub_46A6AC((int)dword_50BF30.data(), 100, 4096);
+			++pSpellSprite.uType;
+			v694.x = 0;
+			v694.y = 0;
+			v694.z = 0;
+			pSpellSprite.stru_24.Reset();
+			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_level = v2;
+			pSpellSprite.spell_skill = v731;
+			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+			pSpellSprite.uAttributes = 0;
+			pSpellSprite.uSectorID = 0;
+			pSpellSprite.uSpriteFrameID = 0;
+			pSpellSprite.field_60_distance_related_prolly_lod = 0;
+			pSpellSprite.uFacing = 0;
+			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+			a2 = 0;
+			if ( (signed int)v531 > 0 )
+			{
+				do
+				{
+					v533 = dword_50BF30[a2];
+					pSpellSprite.vPosition.x = pActors[v533].vPosition.x;
+					pSpellSprite.vPosition.y = pActors[v533].vPosition.y;
+					pSpellSprite.vPosition.z = pActors[v533].vPosition.z - (unsigned int)(signed __int64)((double)pActors[v533].uActorHeight * unk_4D8548);
+					pSpellSprite.spell_target_pid = PID(OBJECT_Actor, dword_50BF30[a2]);
+					v535 = pSpellSprite.Create(0, 0, 0, 0);
+					v536 = a2;
+					DamageMonsterFromParty(PID(OBJECT_Item, v535), dword_50BF30[a2], &v694);
+					a2 = v536 + 1;
+				}
+				while ( v536 + 1 < (signed int)v531 );
+			}
+			v537 = pGame->GetStru6();
+			pGame->GetStru6()->_4A8BFC();
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_LIGHT_DAY_OF_PROTECTION:
+		{
+			switch (v731)
+			{
+				case 1: LODWORD(v733) = 14400 * v2; amount = 4 * v2; break;
+				case 2: LODWORD(v733) = 14400 * v2; amount = 4 * v2; break;
+				case 3: LODWORD(v733) = 14400 * v2; amount = 4 * v2; break;
+				case 4: LODWORD(v733) = 18000 * v2; amount = 5 * v2; break;
+				default:
+				assert(false);
+			}
+			v730 = LODWORD(v733);
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
+
+			v732 = v730 << 7;
+			v549 = (double)(v730 << 7) * 0.033333335;
+			*((float *)&v733 + 1) = v549;
+			v712 = (signed __int64)v549;
+			pParty->pPartyBuffs[PARTY_BUFF_RESIST_BODY].Apply(pParty->uTimePlayed + (signed __int64)v549, v731, amount, 0, 0);
+			pParty->pPartyBuffs[PARTY_BUFF_RESIST_MIND].Apply(pParty->uTimePlayed + v712, v731, amount, 0, 0);
+			pParty->pPartyBuffs[PARTY_BUFF_RESIST_FIRE].Apply(pParty->uTimePlayed + v712, v731, amount, 0, 0);
+			pParty->pPartyBuffs[PARTY_BUFF_RESIST_WATER].Apply(pParty->uTimePlayed + v712, v731, amount, 0, 0);
+			pParty->pPartyBuffs[PARTY_BUFF_RESIST_AIR].Apply(pParty->uTimePlayed + v712, v731, amount, 0, 0);
+			pParty->pPartyBuffs[PARTY_BUFF_RESIST_EARTH].Apply(pParty->uTimePlayed + v712, v731, amount, 0, 0);
+			v550 = v2 + 5;
+			pParty->pPartyBuffs[PARTY_BUFF_FEATHER_FALL].Apply(
+				(signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733 + 1)),
+				v731,
+				v550, 0, 0);
+
+			pParty->pPartyBuffs[PARTY_BUFF_WIZARD_EYE].Apply((signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733 + 1)), v731, v550, 0, 0);
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_LIGHT_HOUR_OF_POWER:
+		{
+			switch (v731)
+			{
+				case 1: LODWORD(v733) = 4; amount = 4; break;
+				case 2: LODWORD(v733) = 4; amount = 4; break;
+				case 3: LODWORD(v733) = 12; amount = 12; break;
+				case 4: LODWORD(v733) = 20; amount = 15; break;
+				default:
+				assert(false);
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			y = (char *)(60 * (v2 * LODWORD(v733) + 60));
+			v732 = (300 * amount * v2 + 60) << 7;
+			v730 = v2 + 5;
+			int _v726 = 0;
+			v553 = pParty->pPlayers;//[0].pConditions[1];
+			*((float *)&v733) = (double)v732 * 0.033333335;
+			do
+			{
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
+
+				//((SpellBuff *)(v553 + 6056))->Apply(
+				v553->pPlayerBuffs[4].Apply((signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733)), v731, v730, 0, 0);
+				if ( *(_QWORD *)v553 )
+					_v726 = 1;
+				++v553;
+			}
+			while ( v553 <= &pParty->pPlayers[3] );
+			v562 = v731;
+			pParty->pPartyBuffs[PARTY_BUFF_HEROISM].Apply((signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733)), v731, v730, 0, 0);
+			pParty->pPartyBuffs[PARTY_BUFF_SHIELD].Apply((signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733)), v562, 0, 0, 0);
+			pParty->pPartyBuffs[PARTY_BUFF_STONE_SKIN].Apply((signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733)), v562, v730, 0, 0);
+			if (!_v726)
+			{
+				pParty->pPartyBuffs[PARTY_BUFF_HASTE].Apply((signed __int64)((double)(signed int)((int)y << 7) * 0.033333335 + (double)(signed __int64)pParty->uTimePlayed), v562, v730, 0, 0);
+			}
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_LIGHT_DIVINE_INTERVENTION:
+		{
+			amount = 3;
+			if ( pPlayer->uNumDivineInterventionCastsThisDay >= 3u )
+			{
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				pCastSpell->spellnum = 0;
+				continue;
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			a2 = 0;
+			_this = (ItemGen *)&pPlayers[1];
+			do
+			{
+				v563 = 0;
+				do
+				{
+					v564 = _this->uItemID;
+					*(int *)(v563 + _this->uItemID) = 0;
+					v563 += 8;
+					*(int *)(v563 + v564 - 4) = 0;
+				}
+				while ( v563 <= 128 );
+				v565 = ((Player *)_this->uItemID)->GetMaxHealth();
+				v566 = (Player **)_this;
+				*(int *)(_this->uItemID + 6460) = v565;
+				v567 = (*v566)->GetMaxMana();
+				*(int *)(_this->uItemID + 6464) = v567;
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, a2);
+				++a2;
+				_this = (ItemGen *)((char *)_this + 4);
+			}
+			while ( (signed int)this < (signed int)&qword_A750D8 );
+			v571 = pPlayer;
+			v572 = (char *)&pPlayer->sAgeModifier;
+			if ( pPlayer->sAgeModifier + 10 >= 120 )
+				*(short *)v572 = 120;
+			else
+				*(short *)v572 = pPlayer->sAgeModifier + 10;
+			sRecoveryTime += -5 * v2;
+			++v571->uNumDivineInterventionCastsThisDay;
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_DARK_REANIMATE:
+		{
+			switch (v731)
+			{
+				case 1: amount = 2 * v2; break;
+				case 2: amount = 3 * v2; break;
+				case 3: amount = 4 * v2; break;
+				case 4: amount = 5 * v2; break;
+				default:
+				assert(false);
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			v576 = pCastSpell->spell_target_pid;
+			if (!v576)
+			{
+				v585 = (char *)&pParty->pPlayers[pCastSpell->uPlayerID_2];
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+				if ( *((_QWORD *)v585 + 14) )
+				{
+				((Player *)v585)->SetCondition(0x11u, 1);
+				v587 = ((Player *)v585)->GetSexByVoice();
+				ReloadPlayerPortraits(pCastSpell->uPlayerID_2, (v587 != 0) + 23);
+				*((_QWORD *)v585 + 17) = pParty->uTimePlayed;
+				}
+				break;
+			}
+			v577 = (Player *)(PID_ID(v576));
+			//v726 = v577;
+			if ( v577 == (Player *)-1 )
+			{
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[496], 2);  // No valid target exists!
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				pCastSpell->spellnum = 0;
+				continue;
+			}
+			v578 = (int)&pActors[(int)v577];
+			v721 = v578;
+			if ( *(short *)(v578 + 40) > 0 || (v579 = *(short *)(v578 + 176), v579 != 5) && v579 != 4 )
+			{
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				pCastSpell->spellnum = 0;
+				continue;
+			}
+			++pSpellSprite.uType;
+			pSpellSprite.stru_24.Reset();
+			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_level = v2;
+			pSpellSprite.spell_skill = v731;
+			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+			pSpellSprite.uAttributes = 0;
+			pSpellSprite.uSectorID = 0;
+			pSpellSprite.uSpriteFrameID = 0;
+			pSpellSprite.field_60_distance_related_prolly_lod = 0;
+			v581 = v721;
+			pSpellSprite.uFacing = 0;
+			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+			pSpellSprite.vPosition.x = *(short *)(v721 + 142);
+			pSpellSprite.vPosition.y = *(short *)(v721 + 144);
+			v732 = *(short *)(v721 + 138);
+			pSpellSprite.vPosition.z = *(short *)(v721 + 146) - (unsigned int)(signed __int64)((double)v732 * unk_4D8548);
+			pSpellSprite.spell_target_pid = PID(OBJECT_Actor, (int)v577);
+			pSpellSprite.Create(0, 0, 0, 0);
+			if ( *(char *)(v581 + 52) > amount )
+				break;
+			Actor::Resurrect((unsigned int)v577);
+			*(char *)(v581 + 61) = 0;
+			*(char *)(v581 + 53) = 0;
+			*(char *)(v581 + 54) = 0;
+			*(char *)(v581 + 55) = 0;
+			*(char *)(v581 + 56) = 0;
+			*(char *)(v581 + 57) = 0;
+			*(int *)(v581 + 712) = 9999;
+			*(char *)(v581 + 38) &= 0xF7u;
+			*(int *)(v581 + 708) = 0;
+			((SpellBuff *)(v581 + 356))->Reset();
+			((SpellBuff *)(v581 + 228))->Reset();
+			((SpellBuff *)(v581 + 404))->Reset();
+			if ( *(short *)(v581 + 40) > 10 * amount )
+				*(short *)(v581 + 40) = 10 * amount;
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_DARK_VAMPIRIC_WEAPON:
+		{
+			amount = 16;
+			if ( v731 == 4 )
+			{
+				LODWORD(v733) = 0;
+			}
+			else
+			{
+				LODWORD(v733) = 3600 * v2;
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			__debugbreak();
+			//HIDWORD(v733) = (int)(char *)&pParty + 6972 * pCastSpell->uPlayerID_2 + 36 * a2 + 3040;
+			ItemGen *_v733 = &pParty->pPlayers[pCastSpell->uPlayerID_2].pInventoryItems[a2];
+			ItemDesc *_v732 = &pItemsTable->pItems[_v733->uItemID];
+			_v733->UpdateTempBonus(pParty->uTimePlayed);
+			if ( _v733->uItemID >= 64 && _v733->uItemID <= 65
+				|| LOBYTE(_v733->uAttributes) & 2
+				|| _v733->uSpecEnchantmentType != 0
+				|| _v733->uEnchantmentType != 0
+				|| (v591 = _v732->uEquipType) != 0 && v591 != 1 && v591 != 2
+				|| pItemsTable->IsMaterialNonCommon(_v733) )
+			{
+				dword_50C9D0 = 113;
+				dword_50C9D4 = 0;
+				dword_50C9D8 = 1;
+
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				pCastSpell->spellnum = 0;
+				continue;
+			}
+			v592 = _v733;
+			v14 = v731 == 4;
+			_v733->uSpecEnchantmentType = 16;
+			if ( !v14 )
+			{
+				v732 = (int)v733 << 7;
+				v592->uExpireTime = pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
+				v592->uAttributes |= 8u;
+			}
+			LOBYTE(v592->uAttributes) |= 0x80u;
+			_50C9A8_item_enchantment_timer = 256;
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_DARK_SHARPMETAL:
+		{
+			switch (v731)
+			{
+				case 1: amount = 5; break;
+				case 2: amount = 5; break;
+				case 3: amount = 7; break;
+				case 4: amount = 9; break;
+				default:
+				assert(false);
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			auto _v726 = ((signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360);
+			pSpellSprite.stru_24.Reset();
+			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_level = v2;
+			pSpellSprite.spell_skill = v731;
+			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+			pSpellSprite.vPosition.x = pParty->vPosition.x;
+			pSpellSprite.vPosition.y = pParty->vPosition.y;
+			pSpellSprite.uAttributes = 0;
+			pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 2;
+			pSpellSprite.uSectorID = pIndoor->GetSector(
+								pParty->vPosition.x,
+								pParty->vPosition.y,
+								pParty->vPosition.z + (signed int)pParty->uPartyHeight / 2);
+			pSpellSprite.uSpriteFrameID = 0;
+			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+			pSpellSprite.spell_target_pid = a2;
+			pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
+			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+			if ( pParty->bTurnBasedModeOn == 1 )
+				LOBYTE(pSpellSprite.uAttributes) |= 4u;
+			v596 = (signed int)_v726 / -2;
+			y = (char *)((signed int)_v726 / 2);
+			if ( (signed int)_v726 / -2 <= (signed int)_v726 / 2 )
+			{
+				v597 = v715.uYawAngle;
+				do
+				{
+					pSpellSprite.uFacing = v596 + v597;
+					if ( pSpellSprite.Create(
+							v596 + v597,
+							v715.uPitchAngle,
+							pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed,
+							pCastSpell->uPlayerID + 1) != -1
+							&& pParty->bTurnBasedModeOn == 1 )
+						++pTurnEngine->field_1C;
+					v596 += _v726 / (amount - 1);
+				}
+				while ( v596 <= (signed int)y );
+			}
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_DARK_CONTROL_UNDEAD:
+		{
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			switch (v731)
+			{
+				case 1: LODWORD(v733) = 180 * v2; break;
+				case 2: LODWORD(v733) = 180 * v2; break;
+				case 3: LODWORD(v733) = 300 * v2; break;
+				case 4: LODWORD(v733) = 29030400; break;
+				default:
+				assert(false);
+			}
+			if (PID_TYPE(a2) != OBJECT_Actor)
+			{
+				LODWORD(v727) = 1;
+				break;
+			}
+			pActor = &pActors[PID_ID(a2)];
+			if ( !MonsterStats::BelongsToSupertype(pActor->pMonsterInfo.uID, MONSTER_SUPERTYPE_UNDEAD) )
+				break;
+			if ( !stru_50C198.GetMagicalResistance(pActor, 0xAu) )
+			{
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				pCastSpell->spellnum = 0;
+				continue;
+			}
+			pActor->pActorBuffs[9].Reset();
+			pActor->pActorBuffs[1].Reset();
+			pActor->pActorBuffs[12].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335),
+				v731, 0, 0, 0);
+			pSpellSprite.stru_24.Reset();
+			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_level = v2;
+			pSpellSprite.spell_skill = v731;
+			v60 = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+			
+			v600 = pActor->vPosition.y;
+			v601 = pActor->vPosition.x;
+			pSpellSprite.uObjectDescID = v60;
+			pSpellSprite.vPosition.x = v601;
+			v602 = pActor->uActorHeight;
+			v603 = pActor->vPosition.z;
+			pSpellSprite.vPosition.y = v600;
+			v676 = v603 + v602;
+			v665 = v600;
+			pSpellSprite.vPosition.z = v603 + v602;
+			v657 = v601;
+			pSpellSprite.uAttributes = 0;
+			pSpellSprite.uSectorID = pIndoor->GetSector(v657, v665, v676);
+			pSpellSprite.uSpriteFrameID = 0;
+			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+			pSpellSprite.spell_target_pid = a2;
+			pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
+			pSpellSprite.uFacing = LOWORD(v715.uYawAngle);
+			LOBYTE(pSpellSprite.uAttributes) |= 0x80u;
+			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+			pSpellSprite.Create(0, 0, 0, pCastSpell->uPlayerID + 1);
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_DARK_SACRIFICE:
+		{
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			int _v733 = 0;
+			memset(&achieved_awards, 0, 4000);
+			int i = 0;
+			pNPCData = pParty->pHirelings;
+			do
+			{
+				if ( pNPCData->pName != 0)
+				{
+					v606 = _v733++;
+					achieved_awards[v606] = (AwardType)(i + 1);
+				}
+				++i;
+				++pNPCData;
+			}
+			while ( pNPCData <= &pParty->pHirelings[1] );
+			i = 0;
+			if ( (signed int)pNPCStats->uNumNewNPCs > 0)
+			{
+				pNPCData = pNPCStats->pNewNPCData;
+				//__debugbreak(); // data offset
+				AwardType *_v734 = &achieved_awards[_v733];
+				do
+				{
+					if ( pNPCData->uFlags & 0x80
+						&& (!pParty->pHirelings[0].pName || strcmp(pNPCData->pName, pParty->pHirelings[0].pName))
+						&& (!pParty->pHirelings[1].pName || strcmp(pNPCData->pName, pParty->pHirelings[1].pName)) )
+					{
+						v607 = _v734;
+						++_v734;
+						*v607 = (AwardType)(i + 3);
+					}
+					++i;
+					++pNPCData;
+				}
+				while ( (signed int)i < (signed int)pNPCStats->uNumNewNPCs );
+			}
+			v608 = pCastSpell->uPlayerID_2;
+			if ( v608 != 4 && v608 != 5
+				|| (v609 = (signed int)*(&pFontCChar + v608 + (unsigned __int8)pParty->field_709), v609 <= 0)
+				|| v609 >= 3 )
+			{
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				pCastSpell->spellnum = 0;
+				continue;
+			}
+			v610 = 76 * v609;
+			//*((int *)&pParty->pPlayers[3].pInstalledBeacons[4].uBeaconTime + 19 * v609) = 0;
+			pParty->pHirelings[v609-1].evt_B = 0;
+			v611 = pIconsFrameTable->FindIcon("spell96");
+			//*(int *)((char *)&pParty->pPlayers[3].pInstalledBeacons[4].uBeaconTime + v610 + 4) = pIconsFrameTable->GetIconAnimLength(v611);
+			pParty->pHirelings[v609-1].evt_C = pIconsFrameTable->GetIconAnimLength(v611);
+			//*(int *)((char *)&pParty->pPlayers[3].pInstalledBeacons[3].field_18 + v610) = 1;
+			pParty->pHirelings[v609-1].evt_A = 1;
+
+			v612 = pParty->pPlayers;
+			do
+			{
+				v612->sHealth = v612->GetMaxHealth();
+				v612->sMana = v612->GetMaxMana();
+				++v612;
+			}
+			while ( v612 <= &pParty->pPlayers[3] );
+			v613 = &pOutdoor->ddm;
+			if ( uCurrentlyLoadedLevelType != LEVEL_Outdoor)
+				v613 = &pIndoor->dlv;
+			v613->uReputation += 15;
+			if ( v613->uReputation > 10000 )
+				v613->uReputation = 10000;
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_DARK_PAIN_REFLECTION:
+		{
+			switch (v731)
+			{
+				case 1: LODWORD(v733) = 300 * (v2 + 12); break;
+				case 2: LODWORD(v733) = 300 * (v2 + 12); break;
+				case 3: LODWORD(v733) = 300 * (v2 + 12); break;
+				case 4: LODWORD(v733) = 900 * (v2 + 4); break;
+				default:
+				assert(false);
+			}
+			amount = v2 + 5;
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			if ( v731 != 3 && v731 != 4 )
+			{
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+				pParty->pPlayers[pCastSpell->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_PAIN_REFLECTION].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, amount, v716, 0);
+				LODWORD(v727) = 1;
+				break;
+			}
+			a2 = 0;
+			v717 = (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
+			v619 = pParty->pPlayers;//[0].pPlayerBuffs[10];
+			do
+			{
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, a2);
+				v619->pPlayerBuffs[PLAYER_BUFF_PAIN_REFLECTION].Apply(pParty->uTimePlayed + v717, v731, amount, v716, 0);
+				++a2;
+				++v619;
+			}
+			while ( v619 <= &pParty->pPlayers[3] );
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_DARK_SOULDRINKER:
+		{
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			pGame->GetIndoorCamera();
+			v623 = (signed __int64)pGame->pIndoorCameraD3D->GetPickDepth();
+			signed int _v733 = sub_46A6AC((int)dword_50BF30.data(), 100, v623);
+			v707.x = 0;
+			v707.y = 0;
+			v707.z = 0;
+			pSpellSprite.stru_24.Reset();
+			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_level = v2;
+			pSpellSprite.spell_skill = v731;
+			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
+			pSpellSprite.uAttributes = 0;
+			pSpellSprite.uSectorID = 0;
+			pSpellSprite.uSpriteFrameID = 0;
+			pSpellSprite.field_60_distance_related_prolly_lod = 0;
+			pSpellSprite.uFacing = 0;
+			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
+			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
+			a2 = 0;
+			int _v726 = 0;
+			if ( _v733 > 0 )
+			{
+				_v726 = (_v733 * (7 * v2 + 25));
+				do
+				{
+					v625 = dword_50BF30[a2];
+					pSpellSprite.vPosition.x = pActors[v625].vPosition.x;
+					pSpellSprite.vPosition.y = pActors[v625].vPosition.y;
+					//v732 = pActors[v625].uActorHeight;
+					pSpellSprite.vPosition.z = pActors[v625].vPosition.z - (unsigned int)(signed __int64)((double)pActors[v625].uActorHeight * unk_4D8548);
+					pSpellSprite.spell_target_pid = PID(OBJECT_Actor, dword_50BF30[a2]);
+					v627 = pSpellSprite.Create(0, 0, 0, 0);
+					v628 = a2;
+					DamageMonsterFromParty(PID(OBJECT_Item, v627), dword_50BF30[a2], &v707);
+					a2 = v628 + 1;
+				}
+				while ( v628 + 1 < _v733 );
+			}
+			v730 = 0;
+			v629 = 1;
+			do
+			{
+				v630 = pPlayers[v629];
+				if ( !v630->pConditions[2]
+				&& !v630->pConditions[12]
+				&& !v630->pConditions[13]
+				&& !v630->pConditions[14]
+				&& !v630->pConditions[15]
+								&& !v630->pConditions[16] )
+				{
+					v631 = v730++;
+					v681[v631] = v629;
+				}
+				++v629;
+			}
+			while ( v629 <= 4 );
+			v732 = (signed __int64)((double)(signed int)_v726 / (double)v730);
+			_v733 = 0;
+			if ( v730 > 0 )
+			{
+				do
+				{
+					//v632 = 4 * v681[HIDWORD(v733)] + 10965188;
+					v726 = pPlayers[v681[_v733]];
+					//v633 = pPlayers[v681[HIDWORD(v733)]];
+					v726->sHealth += v732;
+					//v726 = *(Player **)v632;
+					//v634 = v726->GetMaxHealth();
+					if ( v726->sHealth > v726->GetMaxHealth())
+						v726->sHealth = v726->GetMaxHealth();
+					v635 = _v733;
+
+					pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, WORD2(v733));
+					_v733 = v635 + 1;
+				}
+				while ( v635 + 1 < v730 );
+			}
+			pGame->GetStru6()->FadeScreen__like_Turn_Undead_and_mb_Armageddon(0, 0x40u);
+			LODWORD(v727) = 1;
+			break;
+		}
+		case SPELL_DARK_ARMAGEDDON:
+		{
+			if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
+			{
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[499], 2);  // Can't cast Armageddon indoors!
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				pCastSpell->spellnum = 0;
+				continue;
+			}
+			if ( v731 == 4)
+				amount = 4;
+			else
+				amount = 3;
+			if ( pPlayer->uNumArmageddonCasts >= amount || pParty->armageddon_timer > 0 )
+			{
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
+				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
+				pCastSpell->spellnum = 0;
+				continue;
+			}
+			if ( !pPlayer->CanCastSpell(uRequiredMana) )
+				break;
+			pParty->armageddon_timer = 256;
+			pParty->field_16140 = v2;
+			++pPlayer->uNumArmageddonCasts;
+			if ( pParty->bTurnBasedModeOn == 1 )
+				++pTurnEngine->field_1C;
+			auto _v726 = 50;
+			do
+			{
+				v642 = rand() % 4096 - 2048;
+				v643 = rand();
+				v721 = v642 + pParty->vPosition.x;
+				y = (char *)(pParty->vPosition.y + v643 % 4096 - 2048);
+				v732 = GetTerrainHeightsAroundParty2(v642 + pParty->vPosition.x, (int)y, &v710, 0);
+				v644 = rand();
+				sub_42F7EB_DropItemAt(0xFE6u, v721, (int)y, v732 + 16, v644 % 500 + 500, 1, 0, 0, 0);
+				--_v726;
+			}
+			while ( _v726 != 0 );
+			LODWORD(v727) = 1;
+			break;
+		}
+
+		default:
+			break;
+	}
+	if ( pCastSpell->field_8 & 0x20 )
+	{
+		if ( v727 != 0.0 )
+			pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[pCastSpell->spellnum], 0, 0, -1, 0, pCastSpell->sound_id, 0, 0);
+	}
+	else
+	{
+		if ( sRecoveryTime < 0 )
+			sRecoveryTime = 0;
+		if ( pParty->bTurnBasedModeOn )
+		{
+			v645 = sRecoveryTime;
+			pParty->pTurnBasedPlayerRecoveryTimes[pCastSpell->uPlayerID] = sRecoveryTime;
+			pPlayer->SetRecoveryTime(v645);
+			if ( !some_active_character )
+				pTurnEngine->_40471C();
+		}
+		else
+		{
+			pPlayer->SetRecoveryTime(
+				(signed __int64)(flt_6BE3A4_debug_recmod1 * (double)sRecoveryTime * 2.133333333333333));
+		}
+		if ( v727 != 0.0 )
+		{
+			pPlayer->PlaySound(SPEECH_49, 0);
+			if ( v727 != 0.0 )
+				pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[pCastSpell->spellnum], 0, 0, -1, 0, pCastSpell->sound_id, 0,	0);
+		}
+	}
+	pCastSpell->spellnum = 0;
+	v2 = v723;
+	continue;
+  }
+  
+}
+//----- (00427DA0) --------------------------------------------------------
+unsigned int CastSpellInfo::PushCastSpellInfo(__int16 a2, __int16 uPlayerID, __int16 skill_level, __int16 a5, int spell_sound_id)
+{
+  unsigned int result; // eax@1
+  CastSpellInfo *v7; // edx@1
+  CastSpellInfo *v8; // ecx@5
+
+  result = 0;
+  v7 = this;
+  while ( v7->spellnum )
+  {
+    ++result;
+    ++v7;
+    if ( (signed int)result >= 10 )
+      goto LABEL_8;
+  }
+  v8 = &this[result];
+  v8->spellnum = a2;
+  v8->uPlayerID = uPlayerID;
+  if ( a5 & 0x10 )
+    v8->uPlayerID_2 = uPlayerID;
+  v8->field_6 = 0;
+  v8->spell_target_pid = 0;
+  v8->field_8 = a5;
+  v8->forced_spell_skill_level = skill_level;
+  v8->sound_id = spell_sound_id;
+LABEL_8:
+  if ( result == 10 )
+    result = -1;
+  return result;
+}
+//----- (00427D48) --------------------------------------------------------
+void CastSpellInfo::_427D48(unsigned int uPlayerID)
+{
+  CastSpellInfo *v2; // esi@1
+  signed int v3; // ebx@1
+
+  v2 = this;
+  v3 = 10;
+  do
+  {
+    if ( v2->spellnum )
+    {
+      if ( v2->field_8 & 0x3CA )
+      {
+        v2->spellnum = 0;
+        pGUIWindow_Settings->Release();
+        pGUIWindow_Settings = 0;
+        pMouse->SetCursorBitmap("MICON1");
+        GameUI_Footer_TimeLeft = 0;
+        unk_50C9A0 = 0;
+        back_to_game();
+      }
+    }
+    ++v2;
+    --v3;
+  }
+  while ( v3 );
+}
+//----- (0042777D) --------------------------------------------------------
+void _42777D_CastSpell_UseWand_ShootArrow(int a1, unsigned int uPlayerID, unsigned int a4, __int16 a5, int a6)
+{
+  //bool result; // eax@2
+  //__int16 v6; // bx@4
+  //Player *v7; // eax@4
+  //char v8; // zf@12
+  unsigned __int16 v9; // cx@16
+  unsigned int v10; // eax@18
+  unsigned __int8 v11; // sf@18
+  unsigned __int8 v12; // of@18
+  unsigned __int16 v13; // cx@21
+  unsigned int v14; // eax@23
+  //stru277 *v15; // esi@27
+  //stru277 *v16; // eax@28
+  //GUIWindow *v17; // eax@43
+  //GUIWindow *v18; // [sp-30h] [bp-48h]@44
+  //unsigned int v19; // [sp-2Ch] [bp-44h]@44
+  //unsigned int v20; // [sp-28h] [bp-40h]@44
+  //unsigned int v21; // [sp-24h] [bp-3Ch]@44
+  //unsigned int v22; // [sp-20h] [bp-38h]@44
+  //int v23; // [sp-1Ch] [bp-34h]@44
+  //int v24; // [sp-18h] [bp-30h]@44
+  //unsigned int v25; // [sp-14h] [bp-2Ch]@43
+  //unsigned int v26; // [sp-10h] [bp-28h]@43
+  //unsigned __int8 v27; // [sp-Ch] [bp-24h]@43
+  //char *v28; // [sp-8h] [bp-20h]@43
+  //Texture *v29; // [sp-4h] [bp-1Ch]@43
+  //__int16 a3a; // [sp+10h] [bp-8h]@1
+  //__int16 a2a; // [sp+14h] [bp-4h]@1
+
+  //a3a = uPlayerID;
+  //a2a = a1;
+  
+  //if ( pParty->bTurnBasedModeOn != 1
+  //  || (result = pTurnEngine->field_4, pTurnEngine->field_4 != 1) && pTurnEngine->field_4 != 3 )
+  if (pParty->bTurnBasedModeOn)
+  {
+    if (pTurnEngine->field_4 == 1 || pTurnEngine->field_4 == 3)
+      return;
+  }
+
+
+    //v6 = a5;
+    //v7 = &pParty->pPlayers[uPlayerID];
+  assert(uPlayerID < 4);
+  auto player = &pParty->pPlayers[uPlayerID];
+    if ( !(a5 & 0x10) )
+    {
+      switch ( a1 )
+      {
+        case SPELL_SPIRIT_FATE:
+        case SPELL_BODY_FIRST_AID:
+        case SPELL_DARK_REANIMATE:
+          //HIBYTE(v6) = HIBYTE(a5) | 1;
+          a5 |= 0x0100;
+          break;
+
+        case SPELL_FIRE_FIRE_AURA:
+        case SPELL_WATER_RECHARGE_ITEM:
+        case SPELL_WATER_ENCHANT_ITEM:
+        case SPELL_DARK_VAMPIRIC_WEAPON:
+          //LOBYTE(v6) = a5 | 0x80;
+          a5 |= 0x0080;
+          break;
+
+        case SPELL_FIRE_FIRE_BOLT:
+        case SPELL_FIRE_FIREBALL:
+        case SPELL_FIRE_INCINERATE:
+        case SPELL_AIR_LIGHNING_BOLT:
+        case SPELL_AIR_IMPLOSION:
+        case SPELL_WATER_POISON_SPRAY:
+        case SPELL_WATER_ICE_BOLT:
+        case SPELL_WATER_ACID_BURST:
+        case SPELL_WATER_ICE_BLAST:
+        case SPELL_EARTH_STUN:
+        case SPELL_EARTH_SLOW:
+        case SPELL_EARTH_DEADLY_SWARM:
+        case SPELL_EARTH_BLADES:
+        case SPELL_EARTH_MASS_DISTORTION:
+        case SPELL_SPIRIT_SPIRIT_LASH:
+        case SPELL_MIND_MIND_BLAST:
+        case SPELL_MIND_CHARM:
+        case SPELL_MIND_PSYCHIC_SHOCK:
+        case SPELL_BODY_HARM:
+        case SPELL_BODY_FLYING_FIST:
+        case SPELL_LIGHT_LIGHT_BOLT:
+        case SPELL_LIGHT_DESTROY_UNDEAD:
+        case SPELL_LIGHT_SUNRAY:
+        case SPELL_DARK_TOXIC_CLOUD:
+        case SPELL_DARK_SHRINKING_RAY:
+        case SPELL_DARK_SHARPMETAL:
+        case SPELL_DARK_DRAGON_BREATH:
+          if ( !a6 )
+            a5 |= 0x0008;
+          break;
+        case SPELL_MIND_TELEPATHY:
+        case SPELL_MIND_BERSERK:
+        case SPELL_MIND_ENSLAVE:
+        case SPELL_LIGHT_PARALYZE:
+        case SPELL_DARK_CONTROL_UNDEAD:
+//LABEL_9:
+          //v6 = a5 | 8;
+          a5 |= 0x0008;
+          break;
+
+        case SPELL_EARTH_TELEKINESIS:
+          a5 |= 0x0040;
+          break;
+
+        case SPELL_SPIRIT_BLESS:
+          if (a4 && ~a4 & 0x01C0)
+            //goto LABEL_25;
+          {
+            a5 |= 0x0002;
+            break;
+          }
+          else if ((player->pActiveSkills[PLAYER_SKILL_SPIRIT] & 0x1C0) == 0)
+            //goto LABEL_25;
+          {
+            a5 |= 0x0002;
+            break;
+          }
+          break;
+
+        case SPELL_SPIRIT_PRESERVATION:
+          v9 = a4;
+          if ( !a4 )
+            v9 = player->pActiveSkills[PLAYER_SKILL_SPIRIT];
+          //goto LABEL_18;
+          v10 = SkillToMastery(v9);
+          v12 = __OFSUB__(v10, 3);
+          v11 = ((v10 - 3) & 0x80000000u) != 0;
+          //goto LABEL_24;
+          if ( v11 ^ v12 )
+          {
+            a5 |= 0x0002;
+            break;
+          }
+          break;
+
+        case SPELL_DARK_PAIN_REFLECTION:
+          v9 = a4;
+          if ( !a4 )
+            v9 = player->pActiveSkills[PLAYER_SKILL_DARK];
+//LABEL_18:
+          v10 = SkillToMastery(v9);
+          v12 = __OFSUB__(v10, 3);
+          v11 = ((v10 - 3) & 0x80000000u) != 0;
+          //goto LABEL_24;
+          if ( v11 ^ v12 )
+          {
+            a5 |= 0x0002;
+            break;
+          }
+          break;
+
+        case SPELL_BODY_HAMMERHANDS:
+          v13 = a4;
+          if ( !a4 )
+            v13 = player->pActiveSkills[PLAYER_SKILL_BODY];
+          v14 = SkillToMastery(v13);
+          v12 = __OFSUB__(v14, 4);
+          v11 = ((v14 - 4) & 0x80000000u) != 0;
+//LABEL_24:
+          if ( v11 ^ v12 )
+            //goto LABEL_25;
+          {
+            a5 |= 0x0002;
+            break;
+          }
+          break;
+
+        case SPELL_EARTH_STONE_TO_FLESH:
+        case SPELL_SPIRIT_REMOVE_CURSE:
+        case SPELL_SPIRIT_RAISE_DEAD:
+        case SPELL_SPIRIT_RESSURECTION:
+        case SPELL_MIND_REMOVE_FEAR:
+        case SPELL_MIND_CURE_PARALYSIS:
+        case SPELL_MIND_CURE_INSANITY:
+        case SPELL_BODY_CURE_WEAKNESS:
+        case SPELL_BODY_REGENERATION:
+        case SPELL_BODY_CURE_POISON:
+        case SPELL_BODY_CURE_DISEASE:
+//LABEL_25:
+          //v6 = a5 | 2;
+          a5 |= 0x0002;
+          break;
+
+        case SPELL_DARK_SACRIFICE:
+          //HIBYTE(v6) = HIBYTE(a5) | 2;
+          a5 |= 0x0200;
+          break;
+        default:
+          break;
+      }
+    }
+
+
+    if (a5 & 0x3CA)
+    {
+      assert(sizeof(pCastSpellInfo) / sizeof(*pCastSpellInfo.data()) == 10);
+      for (uint i = 0; i < 10; ++i)
+        if (pCastSpellInfo[i].field_8 & 0x3CA)
+        {
+          pCastSpellInfo[i].spellnum = 0;
+          break;
+        }
+    }
+      
+    assert(sizeof(pCastSpellInfo) / sizeof(*pCastSpellInfo.data()) == 10);
+    for (uint i = 0; i < 10; ++i)
+    {
+      auto spell = &pCastSpellInfo[i];
+      if (!spell->spellnum)
+        continue;
+
+      spell->spellnum = 0;
+      if (spell->field_8 & 0x3CA)
+      {
+        pGUIWindow_Settings->Release();
+        pGUIWindow_Settings = nullptr;
+        pMouse->SetCursorBitmap("MICON1");
+        GameUI_Footer_TimeLeft = 0;
+        unk_50C9A0 = 0;
+        back_to_game();
+      }
+    }
+
+    int result = pCastSpellInfo.data()->PushCastSpellInfo(a1, uPlayerID, a4, a5, a6);
+    if ( result != -1 )
+    {
+      if ( a5 & 2 )
+      {
+        if ( pGUIWindow_Settings )
+          return;
+        pGUIWindow_Settings = GUIWindow::Create(0, 0, 640, 480, WINDOW_CastSpell, (int)&pCastSpellInfo[result], 0);
+        pGUIWindow_Settings->CreateButton(52, 422, 35, 0, 2, 0, UIMSG_CastSpell_Character_Big_Improvement, 0, 49, "", 0);
+        pGUIWindow_Settings->CreateButton(165, 422, 35, 0, 2, 0, UIMSG_CastSpell_Character_Big_Improvement, 1, 50, "", 0);
+        pGUIWindow_Settings->CreateButton(280, 422, 35, 0, 2, 0, UIMSG_CastSpell_Character_Big_Improvement, 2, 51, "", 0);
+        pGUIWindow_Settings->CreateButton(390, 422, 35, 0, 2, 0, UIMSG_CastSpell_Character_Big_Improvement, 3, 52, "", 0);
+        sub_421B2C_PlaceInInventory_or_DropPickedItem();
+        return;
+      }
+      if ( a5 & 8 )
+      {
+        if ( pGUIWindow_Settings )
+          return;
+
+        pGUIWindow_Settings = GUIWindow::Create(0, 0, 640, 480, WINDOW_CastSpell, (int)&pCastSpellInfo[result], 0);
+        pGUIWindow_Settings->CreateButton(game_viewport_x, game_viewport_y, game_viewport_width, game_viewport_height, 1, 0, UIMSG_CastSpell_Shoot_Monster, 0, 0, "", 0);
+        sub_421B2C_PlaceInInventory_or_DropPickedItem();
+        return;
+      }
+      if ( a5 & 0x40 )
+      {
+        if ( pGUIWindow_Settings )
+          return;
+
+        pGUIWindow_Settings = GUIWindow::Create(0, 0, 640, 480, WINDOW_CastSpell, (int)&pCastSpellInfo[result], 0);
+        pGUIWindow_Settings->CreateButton(game_viewport_x, game_viewport_y, game_viewport_width, game_viewport_height, 1, 0, UIMSG_CastSpell_BE, 0, 0, "", 0);
+        sub_421B2C_PlaceInInventory_or_DropPickedItem();
+        return;
+      }
+      if ( (char)a5 < 0 )
+      {
+        if ( pGUIWindow_Settings )
+          return;
+        ++pIcons_LOD->uTexturePacksCount;
+        if ( !pIcons_LOD->uNumPrevLoadedFiles )
+          pIcons_LOD->uNumPrevLoadedFiles = pIcons_LOD->uNumLoadedFiles;
+        pGUIWindow_Settings = pCastSpellInfo[result].sub_4219BE();
+        unk_50C9A0 = 1;
+        some_active_character = uActiveCharacter;
+        sub_421B2C_PlaceInInventory_or_DropPickedItem();
+        return;
+      }
+      if ( HIBYTE(a5) & 1 )
+      {
+        if ( pGUIWindow_Settings )
+          return;
+        pGUIWindow_Settings = GUIWindow::Create(0, 0, 640, 480, WINDOW_CastSpell, (int)&pCastSpellInfo[result], 0);
+        pGUIWindow_Settings->CreateButton(0x34u, 0x1A6u, 0x23u, 0, 2, 0, UIMSG_CastSpell_Character_Small_Improvement, 0, 0x31u, "", 0);
+        pGUIWindow_Settings->CreateButton(0xA5u, 0x1A6u, 0x23u, 0, 2, 0, UIMSG_CastSpell_Character_Small_Improvement, 1, 0x32u, "", 0);
+        pGUIWindow_Settings->CreateButton(0x118u, 0x1A6u, 0x23u, 0, 2, 0, UIMSG_CastSpell_Character_Small_Improvement, 2, 0x33u, "", 0);
+        pGUIWindow_Settings->CreateButton(0x186u, 0x1A6u, 0x23u, 0, 2, 0, UIMSG_CastSpell_Character_Small_Improvement, 3, 0x34u, "", 0);
+        pGUIWindow_Settings->CreateButton(8, 8, game_viewport_width, game_viewport_height, 1, 0, UIMSG_CastSpell_Monster_Improvement, 0, 0, "", NULL);
+        sub_421B2C_PlaceInInventory_or_DropPickedItem();
+      }
+      if ( HIBYTE(a5) & 2 && !pGUIWindow_Settings )
+      {
+        pGUIWindow_Settings = GUIWindow::Create(0, 0, 640, 480, WINDOW_CastSpell, (int)&pCastSpellInfo[result], 0);
+        pBtn_NPCLeft = pGUIWindow_Settings->CreateButton(469, 178,
+                       pIcons_LOD->GetTexture(uTextureID_Btn_NPCLeft)->uTextureWidth,
+                       pIcons_LOD->GetTexture(uTextureID_Btn_NPCLeft)->uTextureHeight,
+                       1, 0, UIMSG_ScrollNPCPanel, 0, 0, "",
+                       pIcons_LOD->GetTexture(uTextureID_Btn_NPCLeft), 0);
+        pBtn_NPCRight = pGUIWindow_Settings->CreateButton(626, 178,
+                       pIcons_LOD->GetTexture(uTextureID_Btn_NPCRight)->uTextureWidth,
+                       pIcons_LOD->GetTexture(uTextureID_Btn_NPCRight)->uTextureHeight,
+                       1, 0, UIMSG_ScrollNPCPanel, 1, 0, "",
+                       pIcons_LOD->GetTexture(uTextureID_Btn_NPCRight), 0);
+        pGUIWindow_Settings->CreateButton(491, 149, 64, 74, 1, 0, UIMSG_HiredNPC_CastSpell, 4, 0x35u, "", 0);
+        pGUIWindow_Settings->CreateButton(561, 149, 64, 74, 1, 0, UIMSG_HiredNPC_CastSpell, 5, 0x36u, "", 0);
+      }
+    }
+}
+
+const wchar_t *UIMessage2String(UIMessageType msg)
+{
+  #define CASE(xxx) case xxx: swprintf(b, wcslen(L"%03X/%s"), L"%03X/%s", msg, L#xxx); return b;
+  static wchar_t b[256]; // bad for threads
+  switch (msg)
+  {
+    CASE(UIMSG_SelectSpell)
+    CASE(UIMSG_ChangeGameState)
+    CASE(UIMSG_Attack)
+    CASE(UIMSG_PlayArcomage)
+    CASE(UIMSG_MainMenu_ShowPartyCreationWnd)
+    CASE(UIMSG_MainMenu_ShowLoadWindow)
+    CASE(UIMSG_ShowCredits)
+    CASE(UIMSG_ExitToWindows)
+    CASE(UIMSG_PlayerCreationChangeName)
+    CASE(UIMSG_PlayerCreationClickPlus)
+    CASE(UIMSG_PlayerCreationClickMinus)
+    CASE(UIMSG_PlayerCreationSelectActiveSkill)
+    CASE(UIMSG_PlayerCreationSelectClass)
+    CASE(UIMSG_PlayerCreationClickOK)
+    CASE(UIMSG_PlayerCreationClickReset)
+    CASE(UIMSG_ClickBooksBtn)
+    CASE(UIMSG_PlayerCreationRemoveUpSkill)
+    CASE(UIMSG_PlayerCreationRemoveDownSkill)
+    CASE(UIMSG_SPellbook_ShowHightlightedSpellInfo)
+    CASE(UIMSG_LoadGame)
+    CASE(UIMSG_SaveGame)
+    CASE(UIMSG_ShowStatus_DateTime)
+    CASE(UIMSG_ShowStatus_ManaHP)
+    CASE(UIMSG_ShowStatus_Player)
+    CASE(UIMSG_Wait5Minutes)
+    CASE(UIMSG_Wait1Hour)
+    CASE(UIMSG_ShowStatus_Food)
+    CASE(UIMSG_ShowStatus_Funds)
+    CASE(UIMSG_QuickReference)
+    CASE(UIMSG_GameMenuButton)
+    CASE(UIMSG_AlreadyResting)
+    CASE(UIMSG_SelectCharacter)
+    CASE(UIMSG_ChangeSoundVolume)
+    CASE(UIMSG_ChangeMusicVolume)
+    CASE(UIMSG_Escape)
+    CASE(UIMSG_PlayerCreation_SelectAttribute)
+    CASE(UIMSG_InventoryLeftClick)
+    CASE(UIMSG_SkillUp)
+    CASE(UIMSG_GameMenu_ReturnToGame)
+    CASE(UIMSG_StartNewGame)
+    CASE(UIMSG_Game_OpenLoadGameDialog)
+    CASE(UIMSG_Game_OpenSaveGameDialog)
+    CASE(UIMSG_Game_OpenOptionsDialog)
+    CASE(UIMSG_SetGraphicsMode)
+    CASE(UIMSG_Quit)
+    CASE(UIMSG_StartHireling1Dialogue)
+    CASE(UIMSG_StartHireling2Dialogue)
+    CASE(UIMSG_SelectNPCDialogueOption)
+    CASE(UIMSG_CastSpellFromBook)
+    CASE(UIMSG_PlayerCreation_VoicePrev)
+    CASE(UIMSG_PlayerCreation_VoiceNext)
+    CASE(UIMSG_StartNPCDialogue)
+    CASE(UIMSG_ArrowUp)
+    CASE(UIMSG_DownArrow)
+    CASE(UIMSG_SaveLoadBtn)
+    CASE(UIMSG_SelectLoadSlot)
+    CASE(UIMSG_Cancel)
+    CASE(UIMSG_ExitRest)
+    CASE(UIMSG_PlayerCreation_FacePrev)
+    CASE(UIMSG_PlayerCreation_FaceNext)
+    CASE(UIMSG_CycleCharacters)
+    CASE(UIMSG_SetTurnSpeed)
+    CASE(UIMSG_ToggleWalkSound)
+    CASE(UIMSG_ChangeVoiceVolume)
+    CASE(UIMSG_ToggleShowDamage)
+    CASE(UIMSG_ScrollNPCPanel)
+    CASE(UIMSG_ShowFinalWindow)
+    CASE(UIMSG_OpenQuestBook)
+    CASE(UIMSG_OpenAutonotes)
+    CASE(UIMSG_OpenMapBook)
+    CASE(UIMSG_OpenCalendar)
+    CASE(UIMSG_OpenHistoryBook)
+    CASE(UIMSG_ToggleAlwaysRun)
+    CASE(UIMSG_ToggleFlipOnExit)
+    CASE(UIMSG_Game_Action)
+    CASE(UIMSG_RentRoom)
+    CASE(UIMSG_TransitionUI_Confirm)
+    CASE(UIMSG_OpenKeyMappingOptions)
+    CASE(UIMSG_SelectKeyPage1)
+    CASE(UIMSG_SelectKeyPage2)
+    CASE(UIMSG_ResetKeyMapping)
+    CASE(UIMSG_ChangeKeyButton)
+    CASE(UIMSG_OpenVideoOptions)
+    CASE(UIMSG_ToggleBloodsplats)
+    CASE(UIMSG_ToggleColoredLights)
+    CASE(UIMSG_ToggleTint)
+    default:
+      swprintf(b, wcslen(L"UIMSG_%03X") , L"UIMSG_%03X", msg); return b;
+  };
+  #undef CASE
+}
\ No newline at end of file
--- a/Chest.cpp	Sun Jun 23 14:27:32 2013 +0600
+++ b/Chest.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -26,8 +26,8 @@
 #include "mm7_data.h"
 #include "MM7.h"
 #include "SpriteObject.h"
-
-
+#include "Mouse.h"
+#include "Viewport.h"
 
 size_t uNumChests; // idb
 struct ChestList *pChestList;
@@ -825,3 +825,49 @@
     v3->Reset();
 }
 // 506128: using guessed type int areWeLoadingTexture;
+//----- (00420E01) --------------------------------------------------------
+void __cdecl OnChestLeftClick()
+{
+  int chest_id; // edi@1
+  POINT *v1; // esi@2
+  int v2; // eax@2
+  int v3; // ebx@4
+  int v4; // esi@6
+  int v5; // ecx@6
+  //SpriteObject v6; // [sp+Ch] [bp-80h]@1
+  POINT v7; // [sp+7Ch] [bp-10h]@2
+  POINT a2; // [sp+84h] [bp-8h]@2
+  
+  SpriteObject v6; // [sp+Ch] [bp-80h]@1
+  //SpriteObject::SpriteObject(&v6);
+
+  chest_id = pGUIWindow_CurrentMenu->par1C;
+  if ( pParty->pPickedItem.uItemID )
+  {
+    if ( Chest::PutItemInChest(-1, &pParty->pPickedItem, pGUIWindow_CurrentMenu->par1C) )
+      pMouse->RemoveHoldingItem();
+  }
+  else
+  {
+    v1 = pMouse->GetCursorPos(&a2);
+    v2 = pRenderer->pActiveZBuffer[v1->x + pSRZBufferLineOffsets[pMouse->GetCursorPos((POINT *)&v7)->y]] & 0xFFFF;
+    if ( v2 )
+    {
+      if ( v2 )
+        v3 = v2 - 1;
+      else
+        v3 = -1;
+      v4 = pChests[chest_id].pInventoryIndices[v3] - 1;
+      if ( pItemsTable->pItems[pChests[chest_id].igChestItems[v4].uItemID].uEquipType == EQUIP_GOLD )
+      {
+        party_finds_gold(pChests[chest_id].igChestItems[v4].uSpecEnchantmentType, 0); 
+        viewparams->bRedrawGameUI = 1;
+      }
+      else
+      {
+        pParty->SetHoldingItem(&pChests[chest_id].igChestItems[v4]);
+      }
+      sub_420B13(v4, v3);
+    }
+  }
+}
\ No newline at end of file
--- a/DecorationList.cpp	Sun Jun 23 14:27:32 2013 +0600
+++ b/DecorationList.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -1,27 +1,10 @@
+#include "Sprites.h"
 #include "DecorationList.h"
-#include <string>
 #include "Allocator.h"
-#include "mm7_data.h"
-#include "Sprites.h"
+#include "MM7.h"
 #include "FrameTableInc.h"
-
-
-//----- (00458600) --------------------------------------------------------
-void DecorationList::ToFile()
-{
-  DecorationList *v1; // esi@1
-  FILE *v2; // eax@1
-  FILE *v3; // edi@1
-
-  v1 = this;
-  v2 = fopen("data\\ddeclist.bin", "wb");
-  v3 = v2;
-  if ( !v2 )
-    Abortf("Unable to save ddeclist.bin!");
-  fwrite(v1, 4u, 1u, v2);
-  fwrite(v1->pDecorations, 0x54u, v1->uNumDecorations, v3);
-  fclose(v3);
-}
+#include "mm7_data.h"
+#include "Indoor.h"
 
 //----- (0045864C) --------------------------------------------------------
 void DecorationList::FromFile(void *pSerialized)
@@ -235,7 +218,35 @@
   fclose(File);
   return 1;
 }
+//----- (00458600) --------------------------------------------------------
+void DecorationList::ToFile()
+{
+  DecorationList *v1; // esi@1
+  FILE *v2; // eax@1
+  FILE *v3; // edi@1
 
+  v1 = this;
+  v2 = fopen("data\\ddeclist.bin", "wb");
+  v3 = v2;
+  if ( !v2 )
+    Abortf("Unable to save ddeclist.bin!");
+  fwrite(v1, 4u, 1u, v2);
+  fwrite(v1->pDecorations, 0x54u, v1->uNumDecorations, v3);
+  fclose(v3);
+}
+//----- (004583B0) --------------------------------------------------------
+LevelDecoration::LevelDecoration()
+{
+  this->field_1A = 0;
+  this->field_18 = 0;
+  this->vPosition.z = 0;
+  this->vPosition.y = 0;
+  this->vPosition.x = 0;
+  this->uDecorationDescID = 0;
+  this->field_2 = 0;
+  this->field_16_event_id = 0;
+  this->uCog = 0;
+}
 //----- (004488B6) --------------------------------------------------------
 unsigned __int16 DecorationList::GetDecorIdByName(const char *pName)
 {
--- a/Events.cpp	Sun Jun 23 14:27:32 2013 +0600
+++ b/Events.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -30,7 +30,7 @@
 #include "stru159.h"
 #include "Events.h"
 #include "Events2D.h"
-#include "UIHouses.h"
+#include "UI\UIHouses.h"
 #include "Log.h"
 #include "MM7.h"
 
@@ -57,8 +57,7 @@
 std::array<char, 9216> pLevelEVT;
 std::array<EventIndex, 4400> pLevelEVT_Index;
 
-
-std::array<_2devent, 525> p2DEvents; // weak
+_2devent p2DEvents[525];
 
 
 
@@ -1534,3 +1533,57 @@
 		}
 	}
 
+//----- (00444732) --------------------------------------------------------
+char *GetEventHintString(unsigned int uEventID)
+{
+  signed int event_index; // edx@1
+  int event_pos; // esi@4
+  char *result; // eax@6
+  unsigned int str_index; // eax@9
+  int i; // esi@11
+ _evt_raw*  test_evt;
+ _evt_raw*  last_evt;
+
+  event_index = 0;
+  if ( uLevelEVT_NumEvents <= 0 )
+    return NULL;
+ 
+    //v2 = (char *)&pLevelEVT_Index[0].uEventOffsetInEVT;
+    while ( 1 )
+    {
+      if ( pLevelEVT_Index[event_index].uEventID == uEventID )
+      {
+		test_evt=(_evt_raw*)&pLevelEVT[pLevelEVT_Index[event_index].uEventOffsetInEVT];
+		last_evt=test_evt;
+        event_pos = pLevelEVT_Index[event_index+1].uEventOffsetInEVT;
+        if ( test_evt->_e_type == EVENT_MouseOver )
+          break;
+      }
+      ++event_index;
+      if ( event_index >= uLevelEVT_NumEvents )
+       return NULL;
+    }
+	test_evt=(_evt_raw*)&pLevelEVT[event_pos];
+    if ( test_evt->_e_type== EVENT_SpeakInHouse )
+    {
+      str_index = EVT_DWORD(test_evt->v5);
+      result = (char *)p2DEvents[str_index - 1].pName;
+    }
+    else
+    {
+      for ( i = event_index+1; pLevelEVT_Index[i].uEventID  == uEventID; ++i )
+      {
+        event_pos = pLevelEVT_Index[i].uEventOffsetInEVT;
+		test_evt=(_evt_raw*)&pLevelEVT[event_pos];
+        if ( test_evt->_e_type == EVENT_SpeakInHouse )
+        {
+          str_index = EVT_DWORD(test_evt->v5);
+          if ( str_index < 600 )
+            return (char *)p2DEvents[str_index - 1].pName;
+        }
+      }
+      result = &pLevelStr[pLevelStrOffsets[EVT_BYTE(last_evt->v5)]];
+    }
+ 
+  return result;
+}
--- a/Events2D.h	Sun Jun 23 14:27:32 2013 +0600
+++ b/Events2D.h	Sun Jun 23 14:27:57 2013 +0600
@@ -63,5 +63,4 @@
 };
 #pragma pack(pop)
 
-
-extern std::array<_2devent, 525> p2DEvents; // weak
\ No newline at end of file
+extern _2devent p2DEvents[525];
\ No newline at end of file
--- a/GUIButton.cpp	Sun Jun 23 14:27:32 2013 +0600
+++ b/GUIButton.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -1,8 +1,9 @@
 #include "GUIWindow.h"
 #include "GUIFont.h"
 
-
-
+#include "mm7_data.h"
+#include "LOD.h"
+#include "Texts.h"
 
 
 
@@ -175,3 +176,81 @@
            0,
            uFontShadowColor);
 }
+//----- (004B36CC) --------------------------------------------------------
+void CreateButtonInColumn( int column_pos, unsigned int control_id )
+{
+     pDialogueWindow->CreateButton( 480, 30 * column_pos + 146, 140, 30,  1,  0, UIMSG_SelectShopDialogueOption,  control_id,  0,   "",   0);
+}
+//----- (00419379) --------------------------------------------------------
+void __cdecl sub_419379()
+{
+  GUIButton *pButton; // esi@2
+
+  if ( dword_507CBC )
+  {
+    dword_507CBC = 0;
+	ptr_507BA4->Release();
+    pBtn_Up->Release();
+    pBtn_Down->Release();
+    pBtn_Down = 0;
+    pBtn_Up = 0;
+    for ( pButton = pGUIWindow_CurrentMenu->pControlsHead; pButton; pButton = pButton->pNext )
+    {
+      if ( pButton->msg == UIMSG_InventoryLeftClick )
+      {
+        pButton->uX = dword_50698C_uX;
+        pButton->uY = dword_506988_uY;
+        pButton->uZ = dword_506984_uZ;
+        pButton->uW = dword_506980_uW;
+        pGUIWindow_CurrentMenu->_41D08F_set_keyboard_control_group(1, 0, 0, 0);
+      }
+    }
+  }
+}
+//----- (00419220) --------------------------------------------------------
+void __cdecl sub_419220()
+{
+  GUIButton *i; // eax@2
+
+  if ( !dword_507CBC )
+  {
+    dword_507CBC = 1;
+    for ( i = pGUIWindow_CurrentMenu->pControlsHead; i; i = i->pNext )
+    {
+      if ( i->msg == UIMSG_InventoryLeftClick )
+      {
+        dword_50698C_uX = i->uX;
+        dword_506988_uY = i->uY;
+        dword_506984_uZ = i->uZ;
+        dword_506980_uW = i->uW;
+        i->uW = 0;
+        i->uZ = 0;
+        i->uY = 0;
+        i->uX = 0;
+      }
+    }
+    pBtn_Up = pGUIWindow_CurrentMenu->CreateButton(438, 46,
+                   pIcons_LOD->GetTexture(uTextureID_ar_up_up)->uTextureWidth,
+                   pIcons_LOD->GetTexture(uTextureID_ar_up_up)->uTextureHeight,
+                   1, 0, UIMSG_ClickAwardsUpBtn, 0, 0, "",
+                   pIcons_LOD->GetTexture(uTextureID_ar_up_up),
+                   pIcons_LOD->GetTexture(uTextureID_ar_up_dn), 0);
+    pBtn_Down = pGUIWindow_CurrentMenu->CreateButton(438, 292,
+                   pIcons_LOD->GetTexture(uTextureID_ar_dn_up)->uTextureWidth,
+                   pIcons_LOD->GetTexture(uTextureID_ar_dn_up)->uTextureHeight,
+                   1, 0, UIMSG_ClickAwardsDownBtn, 0, 0, "",
+                   pIcons_LOD->GetTexture(uTextureID_ar_dn_up),
+                   pIcons_LOD->GetTexture(uTextureID_ar_dn_dn), 0);
+    ptr_507BA4 = pGUIWindow_CurrentMenu->CreateButton(440, 62, 16, 232, 1, 0, UIMSG_ClickAwardScrollBar, 0, 0, "", 0);
+  }
+}
+//----- (004BCA33) --------------------------------------------------------
+void UI_CreateEndConversationButton()
+{
+  pDialogueWindow->Release();
+  pDialogueWindow = GUIWindow::Create(0, 0, 640, 345, WINDOW_MainMenu, 0, 0);
+  pBtn_ExitCancel = pDialogueWindow->CreateButton( 471, 445,  169, 35, 1, 0, UIMSG_Escape,  0,  0,
+                 pGlobalTXT_LocalizationStrings[74],  //"End Conversation"
+                 pIcons_LOD->GetTexture(uExitCancelTextureId), 0);
+  pDialogueWindow->CreateButton(8, 8, 450, 320, 1, 0, UIMSG_BuyInShop_Identify_Repair, 0, 0, "", 0);
+}
\ No newline at end of file
--- a/GUIFont.cpp	Sun Jun 23 14:27:32 2013 +0600
+++ b/GUIFont.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -653,3 +653,14 @@
 		}
 	return &temp_string[0];
 	}
+//----- (00414162) --------------------------------------------------------
+void uGameUIFontMain_initialize()
+{
+  uGameUIFontMain = TargetColor(0xAu, 0, 0);
+}
+
+//----- (00414174) --------------------------------------------------------
+void uGameUIFontShadow_initialize()
+{
+  uGameUIFontShadow = TargetColor(0xE6u, 214u, 193u);
+}
\ No newline at end of file
--- a/GUIWindow.cpp	Sun Jun 23 14:27:32 2013 +0600
+++ b/GUIWindow.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -21,10 +21,11 @@
 #include "SaveLoad.h"
 #include "StorylineTextTable.h"
 #include "Events2D.h"
-#include "UIHouses.h"
+#include "UI\UIHouses.h"
 #include "texts.h"
 #include "Autonotes.h"
 #include "Awards.h"
+#include "Chest.h"
 
 
 #include "mm7_data.h"
@@ -1861,7 +1862,658 @@
   }
   return pWindow;
 }
+//----- (004B3EF0) --------------------------------------------------------
+void DrawJoinGuildWindow( int pEventCode )
+{
+  uDialogueType = 81;//enum JoinGuildDialog
+  current_npc_text = (char *)pNPCTopics[pEventCode + 99].pText;
+  ContractSelectText(pEventCode);
+  pDialogueWindow->Release();
+  pDialogueWindow = GUIWindow::Create(0, 0, 640, 0x15E, WINDOW_MainMenu, pEventCode, 0);
+  pBtn_ExitCancel = pDialogueWindow->CreateButton(471, 445, 169, 35, 1, 0, UIMSG_Escape,                    0, 0, pGlobalTXT_LocalizationStrings[34], pIcons_LOD->GetTexture(uExitCancelTextureId), 0); // Cancel
+                    pDialogueWindow->CreateButton(  0,   0,   0,  0, 1, 0, UIMSG_BuyInShop_Identify_Repair, 0, 0, "", 0);
+                    pDialogueWindow->CreateButton(480, 160, 140, 30, 1, 0, UIMSG_ClickNPCTopic,             0x52u, 0, pGlobalTXT_LocalizationStrings[122], 0);
+  pDialogueWindow->_41D08F_set_keyboard_control_group(1, 1, 0, 2);
+  dialog_menu_id = HOUSE_DIALOGUE_OTHER;
+}
+//----- (0044603D) --------------------------------------------------------
+void __cdecl DialogueEnding()
+{
+  sDialogue_SpeakingActorNPC_ID = 0;
+  pDialogueWindow->Release();
+  pDialogueWindow = 0;
+  pMiscTimer->Resume();
+  pEventTimer->Resume();
+}
+//----- (004156F0) --------------------------------------------------------
+void GUI_UpdateWindows() 
+{
+  GUIWindow *pWindow; // esi@4
+  //unsigned int pWindowType; // eax@4
+  const char *pHint; // edx@66
+  GUIButton *pButtonPtr_1C; // ebp@79
+  char *pHint1; // edx@80
+  int v26; // eax@98
+  unsigned int v27; // ebp@106
+  GUIWindow *pGUIWindow2; // ecx@109
+  GUIFont *pGUIFont; // ST1C_4@115
+  int v31; // eax@115
+  GUIButton *pButton; // ebp@118
+  int v39; // eax@129
+  unsigned int pNumMessages; // eax@142
+  GUIButton *pGUIButton; // ebp@146
+  //unsigned int pX; // [sp-1Ch] [bp-124h]@17
+  //unsigned int pY; // [sp-18h] [bp-120h]@17
+  //Texture *pTexture; // [sp-14h] [bp-11Ch]@17
+  //Texture *pTexture2; // [sp-14h] [bp-11Ch]@86
+  int i; // [sp+0h] [bp-108h]@3
+  ItemGen pItemGen; // [sp+4h] [bp-104h]@98
+  GUIButton GUIButton2; // [sp+28h] [bp-E0h]@133
+  ItemGen ItemGen2; // [sp+E4h] [bp-24h]@129
 
+  if (GetCurrentMenuID() != MENU_CREATEPARTY)
+    UI_OnKeyDown(VK_NEXT);
+
+  for ( i = 1; i <= uNumVisibleWindows; ++i )
+  {
+    pWindow = &pWindowList[pVisibleWindowsIdxs[i] - 1];
+    switch (pWindow->eWindowType)
+    {
+      case WINDOW_OptionsButtons:
+      {
+        pRenderer->DrawTextureIndexed(pViewport->uViewportTL_Y,
+                                      pViewport->uViewportTL_X, pIcons_LOD->GetTexture(uTextureID_Options));
+        viewparams->bRedrawGameUI = 1;
+        continue;
+      }
+      case WINDOW_CharacterRecord:
+      {
+        CharacterUI_CharacterScreen_Draw(pPlayers[uActiveCharacter]);
+        continue;
+      }
+      case WINDOW_Options:
+      {
+        GameMenuUI_Options_Draw();
+        continue;
+      }
+      case WINDOW_Book:
+      {
+        BookUI_Draw((WindowType)(int)pWindow->ptr_1C);
+        continue;
+      }
+      case WINDOW_Dialogue:
+      {
+        GameUI_DrawDialogue();
+        continue;
+      }
+      case WINDOW_QuickReference:
+      {
+        GameUI_QuickRef_Draw();
+        continue;
+      }
+      case WINDOW_Rest:
+      {
+        RestUI_Draw();
+        continue;
+      }
+      case WINDOW_ChangeLocation:
+      {
+        TravelUI_Draw();
+        continue;
+      }
+      case WINDOW_SpellBook:
+      {
+        DrawSpellBookContent(pPlayers[uActiveCharacter]);
+        continue;
+      }
+      case WINDOW_GreetingNPC:
+      {
+        GameUI_DrawBranchlessDialogue();
+        continue;
+      }
+      case WINDOW_Chest:
+      {
+        if ( pCurrentScreen == SCREEN_CHEST )
+        {
+          Chest::DrawChestUI((unsigned int)pWindow->ptr_1C);
+        }
+        else if ( pCurrentScreen == SCREEN_CHEST_INVENTORY )
+        {
+          pRenderer->ClearZBuffer(0, 479);
+          draw_leather();
+          CharacterUI_InventoryTab_Draw(pPlayers[uActiveCharacter], true);
+          pRenderer->DrawTextureIndexed(pBtn_ExitCancel->uX, pBtn_ExitCancel->uY, pIcons_LOD->GetTexture(uExitCancelTextureId));
+        }
+        continue;
+      }
+      case WINDOW_SaveLoadButtons:
+      {
+        SaveUI_Draw();
+        continue;
+      }
+      case WINDOW_MainMenu_Load:
+      {
+        LoadUI_Draw();
+        continue;
+      }
+      case WINDOW_HouseInterior:
+      {
+        pWindowList[pVisibleWindowsIdxs[i] - 1].HouseDialogManager();
+        if ( !window_SpeakInHouse )
+          continue;
+        if ( (signed int)window_SpeakInHouse->ptr_1C >= 53 )
+          continue;
+        if ( pParty->field_3C._shop_ban_times[(signed int)window_SpeakInHouse->ptr_1C] <=pParty->uTimePlayed )
+        {
+          if ( (signed int)window_SpeakInHouse->ptr_1C < 53 )
+          {
+            pParty->field_3C._shop_ban_times[(signed int)window_SpeakInHouse->ptr_1C] = 0;
+          }
+          continue;
+        }
+        pNumMessages = pMessageQueue_50CBD0->uNumMessages;
+        pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 0, 0);
+        continue;
+      }
+      case WINDOW_Transition:
+      {
+        TransitionUI_Draw();
+        continue;
+      }
+      case WINDOW_Scroll:
+      {
+        CreateScrollWindow();
+        continue;
+      }
+      case WINDOW_CastSpell_InInventory:
+      {
+        pRenderer->ClearZBuffer(0, 479);
+        draw_leather();
+        CharacterUI_InventoryTab_Draw(pPlayers[uActiveCharacter], true);
+        CharacterUI_DrawPaperdoll(pPlayers[uActiveCharacter]);
+        pRenderer->DrawTextureTransparent(pBtn_ExitCancel->uX, pBtn_ExitCancel->uY, pIcons_LOD->GetTexture(uTextureID_x_x_u));
+        continue;
+      }
+      case WINDOW_FinalWindow:
+      {
+        sub_41420D_press_esc();
+        continue;
+      }
+      case WINDOW_50:
+      {
+        v27 = TargetColor(255, 255, 255);
+        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);
+          v31 = pFontCreate->GetLineWidth((const char *)pKeyActionMap->pPressedKeysBuffer);
+          ptr_507BD0->DrawFlashingInputCursor(v31 + 30, 40, pFontCreate);
+          continue;
+        }
+        if ( ptr_507BD0->receives_keyboard_input_2 == WINDOW_INPUT_CONFIRMED)
+        {
+          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 = SCREEN_GAME;
+          viewparams->bRedrawGameUI = true;
+          continue;
+        }
+        if ( ptr_507BD0->receives_keyboard_input_2 == WINDOW_INPUT_CANCELLED)
+        {
+          pWindow->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
+          pEventTimer->Resume();
+          ptr_507BD0->Release();
+          continue;
+        }
+      }
+      case WINDOW_59:
+      {
+        pWindow->DrawMessageBox(0);
+        pWindow->DrawText(pFontLucida, 10, 20, 0, "Making item number", 0, 0, 0);
+        pWindow->DrawText(pFontLucida, 10, 40, 0, (const char *)pKeyActionMap->pPressedKeysBuffer, 0, 0, 0);
+        if ( !pKeyActionMap->field_204 )
+        {
+          ItemGen2.Reset();
+          pWindow->Release();
+          pEventTimer->Resume();
+          pCurrentScreen = 0;
+          viewparams->bRedrawGameUI = true;
+          v26 = atoi((const char *)pKeyActionMap->pPressedKeysBuffer);
+          if ( v26 > 0 )
+          {
+            if ( v26 < 800 )
+            {
+              ItemGen2.uAttributes |= 1u;
+              ItemGen2.uItemID = v26;
+              if ( pItemsTable->pItems[v26].uEquipType == 12 )
+              {
+                ItemGen2.uNumCharges = rand() % 6 + pItemsTable->pItems[ItemGen2.uItemID].uDamageMod + 1;
+                ItemGen2.uMaxCharges = LOBYTE(ItemGen2.uNumCharges);
+              }
+              else
+              {
+                if ( v26 >= 221 && v26 < 271 )
+                  ItemGen2.uEnchantmentType = rand() % 10 + 1;
+              }
+              pItemsTable->SetSpecialBonus(&ItemGen2);
+              pParty->SetHoldingItem(&ItemGen2);
+            }
+          }
+        }
+        continue;
+      }
+      case WINDOW_PressedButton2:
+      {
+        if ( pWindow->Hint != (char *)1 )
+          pAudioPlayer->PlaySound((SoundID)75, 0, 0, -1, 0, 0, 0, 0);
+        pButton = (GUIButton *)pWindow->ptr_1C;
+        if ( pButton->uX >= 0 && pButton->uX <= 640 )
+        {
+          if ( pButton->uY >= 0 && pButton->uY <= 480 )
+          {
+            pRenderer->DrawTextureIndexed(pWindow->uFrameX, pWindow->uFrameY, pButton->pTextures[0]);
+            viewparams->bRedrawGameUI = 1;
+            if ( pWindow->Hint )
+            {
+              if ( pWindow->Hint != (char *)1 )
+                pButton->DrawLabel(pWindow->Hint, pFontCreate, 0, 0);
+            }
+            pWindow->Release();
+            continue;
+          }
+        }
+        viewparams->bRedrawGameUI = 1;
+        if ( pWindow->Hint )
+        {
+          if ( pWindow->Hint != (char *)1 )
+            pButton->DrawLabel(pWindow->Hint, pFontCreate, 0, 0);
+        }
+        pWindow->Release();
+        continue;
+      }
+      case WINDOW_CharactersPressedButton:
+      {
+        if ( pWindow->Hint != (char *)1 )
+          pAudioPlayer->PlaySound((SoundID)75, 0, 0, -1, 0, 0, 0, 0);
+        pButton = (GUIButton *)pWindow->ptr_1C;
+        pRenderer->DrawTextureIndexed(pWindow->uFrameX, pWindow->uFrameY, pButton->pTextures[1]);
+        viewparams->bRedrawGameUI = 1;
+        if ( pWindow->Hint )
+        {
+          if ( pWindow->Hint != (char *)1 )
+            pButton->DrawLabel(pWindow->Hint, pFontCreate, 0, 0);
+        }
+        pWindow->Release();
+        continue;
+      }
+      case WINDOW_PressedButton:
+      {
+        if ( pWindow->Hint != (char *)1 )
+          pAudioPlayer->PlaySound((SoundID)75, 0, 0, -1, 0, 0, 0, 0);
+        pButton = (GUIButton *)pWindow->ptr_1C;
+        pRenderer->DrawTextureTransparent(pWindow->uFrameX, pWindow->uFrameY, pButton->pTextures[0]);
+        viewparams->bRedrawGameUI = 1;
+        if ( pWindow->Hint )
+        {
+          if ( pWindow->Hint != (char *)1 )
+            pButton->DrawLabel(pWindow->Hint, pFontCreate, 0, 0);
+        }
+        pWindow->Release();
+        continue;
+      }
+      case WINDOW_5D:
+      {
+        if ( pWindow->Hint != (char *)1 )
+          pAudioPlayer->PlaySound((SoundID)75, 0, 0, -1, 0, 0, 0, 0);
+        pButton = (GUIButton *)pWindow->ptr_1C;
+        pRenderer->DrawTextureTransparent(pWindow->uFrameX, pWindow->uFrameY, pButton->pTextures[1]);
+        viewparams->bRedrawGameUI = 1;
+        pWindow->Release();
+        continue;
+      }
+      case WINDOW_SaveLoadBtn:
+      {
+        if (pWindow->Hint != (char *)1)
+          pAudioPlayer->PlaySound(SOUND_Button2, 0, 0, -1, 0, 0, 0, 0);
+        pButton = (GUIButton *)pWindow->ptr_1C;
+        pRenderer->DrawTextureIndexed(pWindow->uFrameX, pWindow->uFrameY, pButton->pTextures[0]);
+        pHint = pWindow->Hint;
+        viewparams->bRedrawGameUI = 1;
+        if ( pHint && pHint != (char *)1 )
+          pButton->DrawLabel(pHint, pFontCreate, 0, 0);
+        pWindow->Release();
+        if (pCurrentScreen == SCREEN_SAVEGAME)
+          pMessageQueue_50CBD0->AddMessage(UIMSG_SaveGame, 0, 0);
+        else
+          pMessageQueue_50CBD0->AddMessage(UIMSG_LoadGame, 0, 0);
+        continue;
+      }
+      case WINDOW_LoadGame_CancelBtn:
+      {
+        if ( pWindow->Hint != (char *)1 )
+          pAudioPlayer->PlaySound((SoundID)75, 0, 0, -1, 0, 0, 0, 0);
+        pButton = (GUIButton *)pWindow->ptr_1C;
+        pRenderer->DrawTextureTransparent(pWindow->uFrameX, pWindow->uFrameY, pButton->pTextures[0]);
+        viewparams->bRedrawGameUI = 1;
+        if ( pWindow->Hint && pWindow->Hint != (char *)1 )
+          pButton->DrawLabel(pWindow->Hint, pFontCreate, 0, 0);
+        pWindow->Release();
+        pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 0, 0);
+        continue;
+      }
+      case WINDOW_CloseRestWindowBtn:
+      {
+        if ( pWindow->Hint != (char *)1 )
+          pAudioPlayer->PlaySound(SOUND_Button2, 0, 0, -1, 0, 0, 0, 0);
+        pGUIButton = (GUIButton *)pWindow->ptr_1C;
+        pRenderer->DrawTextureIndexed(pWindow->uFrameX, pWindow->uFrameY, pGUIButton->pTextures[0]);
+        pHint = pWindow->Hint;
+        viewparams->bRedrawGameUI = 1;
+        if ( pHint && pHint != (char *)1 )
+          pGUIButton->DrawLabel(pHint, pFontCreate, 0, 0);
+        pWindow->Release();
+        pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 0, 0);
+        continue;
+      }
+      case WINDOW_ExitCharacterWindow:
+      {
+        if ( pWindow->Hint != (char *)1 )
+          pAudioPlayer->PlaySound(SOUND_Button2, 0, 0, -1, 0, 0, 0, 0);
+        pButton = (GUIButton *)pWindow->ptr_1C;
+        pRenderer->DrawTextureIndexed(pWindow->uFrameX, pWindow->uFrameY, pButton->pTextures[1]);
+        pHint = pWindow->Hint;
+        viewparams->bRedrawGameUI = 1;
+        if ( pHint && pHint != (char *)1 )
+          pButton->DrawLabel(pHint, pFontCreate, 0, 0);
+        pWindow->Release();
+        pNumMessages = pMessageQueue_50CBD0->uNumMessages;
+        pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 0, 0);
+        continue;
+      }
+      case WINDOW_RestWindow:
+      {
+        memset(&GUIButton2, 0, 0xBCu);
+        GUIButton2.uZ = 197;
+        GUIButton2.uW = 197;
+        GUIButton2.uX = 27;
+        GUIButton2.uY = 161;
+        GUIButton2.uWidth = 171;
+        GUIButton2.uHeight = 37;
+        GUIButton2.pParent = pButton_RestUI_WaitUntilDawn->pParent;
+        pAudioPlayer->PlaySound(SOUND_Button2, 0, 0, -1, 0, 0, 0, 0);
+        pRenderer->DrawTextureIndexed(pWindow->uFrameX, pWindow->uFrameY, *((Texture **)pWindow->ptr_1C + 15));
+        viewparams->bRedrawGameUI = 1;
+        GUIButton2.DrawLabel(pGlobalTXT_LocalizationStrings[183], pFontCreate, 0, 0);//   8 
+        GUIButton2.pParent = 0;
+        pGUIWindow2 = pWindow;
+        pGUIWindow2->Release();
+        continue;
+      }
+      case WINDOW_BooksWindow:
+      {
+        pButton = (GUIButton *)pWindow->ptr_1C;
+        pRenderer->DrawTextureIndexed(pWindow->uFrameY,
+                                      pWindow->uFrameX, pButton->pTextures[0]);
+        viewparams->bRedrawGameUI = true;
+        continue;
+      }
+      case WINDOW_CharacterWindow_Inventory:
+      {
+        pWindow->DrawMessageBox(0);
+        pWindow->DrawText(pFontLucida, 10, 20, 0, "Making item number", 0, 0, 0);
+        pWindow->DrawText(pFontLucida, 10, 40, 0, (const char *)pKeyActionMap->pPressedKeysBuffer, 0, 0, 0);
+        if ( !pKeyActionMap->field_204 )
+        {
+          ItemGen2.Reset();
+          pWindow->Release();
+          pEventTimer->Resume();
+          pCurrentScreen = SCREEN_GAME;
+          viewparams->bRedrawGameUI = 1;
+          v39 = atoi((const char *)pKeyActionMap->pPressedKeysBuffer);
+          if ( v39 > 0 )
+          {
+            if ( v39 < 800 )
+              SpawnActor(v39);
+          }
+        }
+        continue;
+      }
+      case WINDOW_KeyMappingOptions:
+      {
+        GameMenuUI_DrawKeyBindings();
+        continue;
+      }
+      case WINDOW_VideoOptions:
+      {
+        GameMenuUI_DrawVideoOptions();
+        continue;
+      }
+      default:
+      {
+        continue;
+      }
+    }
+  }
+  if ( GetCurrentMenuID() == -1 )
+    GameUI_DrawFoodAndGold();
+  if ( sub_4637E0_is_there_popup_onscreen() )
+    sub_416D62_ShowPopupWindow_MonsterRecord_ItemInfo_etcsub_416D62(0);
+}
+//----- (00415485) --------------------------------------------------------
+void DrawCopyrightWindow()
+{
+  GUIWindow Dst; // [sp+8h] [bp-54h]@1
+
+  memset(&Dst, 0, 0x54u);
+  Dst.uFrameWidth = 624;
+  Dst.uFrameHeight = 256;
+  Dst.uFrameX = 8;
+  Dst.uFrameY = 30;                             // c 1999 The 3DO Company.
+  Dst.uFrameHeight = pFontSmallnum->CalcTextHeight(pGlobalTXT_LocalizationStrings[157], &Dst, 24, 0)
+                   + 2 * LOBYTE(pFontSmallnum->uFontHeight)
+                   + 24;
+  Dst.uFrameY = 470 - Dst.uFrameHeight;
+  Dst.uFrameZ = Dst.uFrameX + Dst.uFrameWidth - 1;
+  Dst.uFrameW = 469;
+  //Dst.Hint = "abcagfdsgsg ljsrengvlkjesnfkjwnef";
+  Dst.DrawMessageBox(0);
+
+  Dst.uFrameWidth -= 24;
+  Dst.uFrameX += 12;
+  Dst.uFrameY += 12;
+  Dst.uFrameHeight -= 12;
+  Dst.uFrameZ = Dst.uFrameX + Dst.uFrameWidth - 1;
+  Dst.uFrameW = Dst.uFrameY + Dst.uFrameHeight - 1;
+  Dst.DrawTitleText(pFontSmallnum, 0, 0xCu, ui_mainmenu_copyright_color, pGlobalTXT_LocalizationStrings[157], 3);
+}
+//----- (0041420D) --------------------------------------------------------
+void __cdecl sub_41420D_press_esc()
+{
+  GUIWindow pWindow; // [sp+4h] [bp-54h]@1
+
+  sprintf(pTmpBuf2.data(), "%s\n \n%s", ptr_507BDC->Hint, pGlobalTXT_LocalizationStrings[61]);// Press Escape
+  pWindow.Hint = pTmpBuf2.data();
+  pWindow.uFrameWidth = 400;
+  pWindow.uFrameHeight = 100;
+  pWindow.uFrameX = 120;
+  pWindow.uFrameY = 140;
+  pWindow.uFrameZ = 519;
+  pWindow.uFrameW = 239;
+  pWindow.DrawMessageBox(0);
+}
+
+//----- (0041426F) --------------------------------------------------------
+void __cdecl sub_41426F()
+{
+  GUIWindow *pWindow; // ecx@1
+
+  pWindow = ptr_507BDC;
+  pMessageQueue_50CBD0->AddMessage((UIMessageType)(int)ptr_507BDC->ptr_1C, 0, 0);
+
+  pWindow->Release();
+  ptr_507BDC = 0;
+  pCurrentScreen = dword_506F0C[0];
+  pEventTimer->Resume();
+}
+//----- (00410DEC) --------------------------------------------------------
+unsigned int __cdecl DrawLloydBeaconsScreen()
+{
+  Player *pPlayer; // esi@1
+  char *v1; // eax@1
+  unsigned __int16 v2; // ax@6
+  unsigned int result; // eax@11
+  unsigned int v4; // esi@13
+  unsigned int v5; // ecx@13
+  char v6; // zf@13
+  LloydBeacon *v7; // esi@14
+  int v8; // eax@14
+  unsigned __int64 v9; // kr08_8@14
+  unsigned int v10; // esi@14
+  unsigned int v11; // eax@14
+  char *v12; // eax@19
+  char *v13; // ecx@22
+  int v14; // eax@27
+  Texture *v19; // [sp-4h] [bp-8Ch]@4
+  GUIWindow pWindow; // [sp+Ch] [bp-7Ch]@1
+  unsigned int v23; // [sp+64h] [bp-24h]@14
+  __int64 v24; // [sp+68h] [bp-20h]@14
+  unsigned int v25; // [sp+70h] [bp-18h]@13
+  char *Str; // [sp+74h] [bp-14h]@14
+  int v27; // [sp+78h] [bp-10h]@11
+  LloydBeacon *v28; // [sp+7Ch] [bp-Ch]@12
+  RGBTexture *v29; // [sp+80h] [bp-8h]@12
+  int uNumMaxBeacons; // [sp+84h] [bp-4h]@6
+
+  pPlayer = &pParty->pPlayers[_506348_current_lloyd_playerid];
+  pRenderer->DrawTextureIndexed(8u, 8u, pTexture_LloydBeacons[(unsigned __int8)bRecallingBeacon]);
+  v1 = pGlobalTXT_LocalizationStrings[523];     // Recall Beacon
+  pWindow.uFrameX = game_viewport_x;
+  pWindow.uFrameY = game_viewport_y;
+  pWindow.uFrameWidth = 428;
+  pWindow.uFrameHeight = game_viewport_height;
+  pWindow.uFrameZ = 435;
+  pWindow.uFrameW = game_viewport_w;
+  if ( !bRecallingBeacon )
+    v1 = pGlobalTXT_LocalizationStrings[375];   // Set Beacon
+  sprintf(pTmpBuf.data(), "%s", v1);
+  pWindow.DrawTitleText(pBook2Font, 0, 22u, 0, pTmpBuf.data(), 3u);
+  if ( bRecallingBeacon )
+  {
+    pRenderer->DrawTextureTransparent(pBtn_Book_1->uX, pBtn_Book_1->uY, pTex_tab_an_6b__zoom_on);
+    v19 = pTex_tab_an_6a__zoom_off;
+  }
+  else
+  {
+    pRenderer->DrawTextureTransparent(pBtn_Book_1->uX, pBtn_Book_1->uY, pTex_tab_an_6a__zoom_off);
+    v19 = pTex_tab_an_6b__zoom_on;
+  }
+  pRenderer->DrawTextureTransparent(pBtn_Book_2->uX, pBtn_Book_2->uY, v19);
+  v2 = pPlayer->pActiveSkills[14];
+  uNumMaxBeacons = 1;
+  if ( HIBYTE(v2) & 1 || (v2 & 0x80u) != 0 )
+  {
+    uNumMaxBeacons = 5;
+  }
+  else
+  {
+    if ( v2 & 0x40 )
+      uNumMaxBeacons = 3;
+  }
+  result = 0;
+  v27 = 0;
+  if ( uNumMaxBeacons > 0 )
+  {
+    v29 = pSavegameThumbnails.data();
+    v28 = pPlayer->pInstalledBeacons;
+    while ( 1 )
+    {
+      pWindow.uFrameWidth = 92;
+      v4 = result;
+      pWindow.uFrameHeight = 68;
+      v5 = pLloydsBeaconsPreviewXs[result];
+      pWindow.uFrameY = pLloydsBeaconsPreviewYs[result];
+      v25 = pWindow.uFrameY;
+      pWindow.uFrameX = v5;
+      pWindow.uFrameW = pWindow.uFrameY + 67;
+      v6 = v29->pPixels == 0;
+      pWindow.uFrameZ = v5 + 91;
+      if ( !v6 )
+        break;
+      if ( !bRecallingBeacon )
+      {
+        pRenderer->DrawTextureTransparent(pLloydsBeacons_SomeXs[v4], pLloydsBeacons_SomeYs[v4], pTexture_CurrentBook);
+        v14 = pSpellFont->CalcTextHeight(pGlobalTXT_LocalizationStrings[19], &pWindow, 0, 0);
+        pWindow.DrawTitleText(pSpellFont, 0, (signed int)pWindow.uFrameHeight / 2 - v14 / 2, 1, pGlobalTXT_LocalizationStrings[19], 3);
+      }
+LABEL_29:
+      ++v29;
+      ++v28;
+      result = v27++ + 1;
+      if ( v27 >= uNumMaxBeacons )
+        goto LABEL_30;
+    }
+    pRenderer->DrawTextureTransparent(pLloydsBeacons_SomeXs[v4], pLloydsBeacons_SomeYs[v4], pTexture_CurrentBook);
+    pRenderer->DrawTextureRGB(pLloydsBeaconsPreviewXs[v4], pLloydsBeaconsPreviewYs[v4], v29);
+    v7 = v28;
+    Str = pMapStats->pInfos[sub_410D99_get_map_index(HIWORD(v28->field_18))].pName;
+    v8 = pSpellFont->CalcTextHeight(Str, &pWindow, 0, 0);
+    pWindow.uFrameY += -6 - v8;
+    pWindow.DrawTitleText(pSpellFont, 0, 0, 1u, Str, 3u);
+    v9 = v7->uBeaconTime - pParty->uTimePlayed;
+    LODWORD(v24) = LODWORD(v7->uBeaconTime) - LODWORD(pParty->uTimePlayed);
+    HIDWORD(v24) = HIDWORD(v9);
+    v23 = (unsigned __int64)((signed __int64)((double)v24 * 0.234375) / 60 / 60) >> 32;
+    v10 = (signed __int64)((double)v24 * 0.234375) / 60 / 60;
+    v11 = v10 / 0x18;
+    if ( (unsigned int)((signed __int64)((double)v24 * 0.234375) / 60 / 60) / 0x18 )
+    {
+      v13 = pGlobalTXT_LocalizationStrings[57]; // Days
+      if ( v11 > 1 )
+      {
+        sprintf(pTmpBuf.data(), "%lu %s", v11 + 1, v13);
+        pWindow.uFrameY = v25 + pWindow.uFrameHeight + 4;
+        pWindow.DrawTitleText(pSpellFont, 0, 0, 1, pTmpBuf.data(), 3);
+        goto LABEL_29;
+      }
+    }
+    else
+    {
+      if ( (signed __int64)(__PAIR__(v23, v10) + 1) <= 23 )
+      {
+        if ( (v23 & 0x80000000u) != 0 || (signed int)v23 <= 0 && v10 <= 1 )
+          v12 = pGlobalTXT_LocalizationStrings[109];// Hour
+        else
+          v12 = pGlobalTXT_LocalizationStrings[110];// Hours
+        sprintf(pTmpBuf.data(), "%lu %s", v10 + 1, v12);
+        pWindow.uFrameY = v25 + pWindow.uFrameHeight + 4;
+        pWindow.DrawTitleText(pSpellFont, 0, 0, 1, pTmpBuf.data(), 3);
+        goto LABEL_29;
+      }
+    }
+    v13 = pGlobalTXT_LocalizationStrings[56];   // Day
+    sprintf(pTmpBuf.data(), "%lu %s", v11 + 1, v13);
+    pWindow.uFrameY = v25 + pWindow.uFrameHeight + 4;
+    pWindow.DrawTitleText(pSpellFont, 0, 0, 1, pTmpBuf.data(), 3);
+    goto LABEL_29;
+  }
+LABEL_30:
+  if ( byte_506360 )
+  {
+    /*result = pMessageQueue_50CBD0->uNumMessages;
+    if ( (signed int)pMessageQueue_50CBD0->uNumMessages < 40 )
+    {
+      pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].eType = UIMSG_CloseAfterInstallBeacon;
+      pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = 0;
+      result = 3 * pMessageQueue_50CBD0->uNumMessages + 3;
+      *(&pMessageQueue_50CBD0->uNumMessages + result) = 0;
+      ++pMessageQueue_50CBD0->uNumMessages;
+    }*/
+    pMessageQueue_50CBD0->AddMessage(UIMSG_CloseAfterInstallBeacon, 0, 0);
+  }
+  return result;
+}
 //----- (00467FB6) --------------------------------------------------------
 void CreateScrollWindow()
     {
@@ -1897,9 +2549,16 @@
   v2 = TargetColor(0xFFu, 0xFFu, 0x9Bu);
   sprintf(pTmpBuf.data(), format_4E2D80, v2, v1);
   a1.DrawTitleText(pFontCreate, 0, 0, 0, pTmpBuf.data(), 3u);
-  a1.DrawText(pFontSmallnum, 1, LOBYTE(pFontCreate->uFontHeight) - 3, 0, pScrolls[(unsigned int)pGUIWindow_ScrollWindow->ptr_1C], 0, 0, 0);
+  a1.DrawText(
+           pFontSmallnum,
+           1,
+           LOBYTE(pFontCreate->uFontHeight) - 3,
+           0,
+           pScrolls[(unsigned int)pGUIWindow_ScrollWindow->ptr_1C],
+           0,
+           0,
+           0);
 }
-
 //----- (00467F48) --------------------------------------------------------
 void CreateMsgScrollWindow( signed int mscroll_id )
     {
@@ -1914,4 +2573,13 @@
       pGUIWindow_ScrollWindow = GUIWindow::Create(0, 0, 640, 480, WINDOW_Scroll, v1 - 700, 0);
     }
   }
+}
+//----- (00467F9F) --------------------------------------------------------
+void __cdecl free_book_subwindow()
+{
+  if ( pGUIWindow_ScrollWindow )
+  {
+    pGUIWindow_ScrollWindow->Release();
+    pGUIWindow_ScrollWindow = 0;
+  }
 }
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IconFrameTable.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -0,0 +1,248 @@
+#include "IconFrameTable.h"
+#include "LOD.h"
+#include "mm7_data.h"
+#include "Allocator.h"
+#include "FrameTableInc.h"
+
+//----- (00494F3A) --------------------------------------------------------
+unsigned int IconFrameTable::FindIcon(const char *pIconName)
+{
+  IconFrameTable *v2; // esi@1
+  int v3; // ebx@1
+  unsigned int uID; // edi@1
+  unsigned int result; // eax@4
+
+  v2 = this;
+  v3 = 0;
+  uID = 0;
+  if ( (signed int)this->uNumIcons <= 0 )
+  {
+LABEL_4:
+    result = 0;
+  }
+  else
+  {
+    while ( _stricmp(pIconName, v2->pIcons[v3].pAnimationName) )
+    {
+      ++uID;
+      ++v3;
+      if ( (signed int)uID >= (signed int)v2->uNumIcons )
+        goto LABEL_4;
+    }
+    result = uID;
+  }
+  return result;
+}
+
+//----- (00494F70) --------------------------------------------------------
+IconFrame *IconFrameTable::GetFrame(unsigned int uIconID, unsigned int uFrameID)
+{
+  IconFrame *v3; // edi@1
+  IconFrame *v4; // ecx@1
+  __int16 v5; // dx@2
+  int v6; // edx@3
+  unsigned int v7; // eax@3
+  char *i; // ecx@3
+  int v9; // esi@5
+  IconFrame *result; // eax@6
+
+  v3 = this->pIcons;
+  v4 = &v3[uIconID];
+  if ( v4->uFlags & 1 && (v5 = v4->uAnimLength) != 0 )
+  {
+    v6 = ((signed int)uFrameID >> 3) % (unsigned __int16)v5;
+    v7 = uIconID;
+    for ( i = (char *)&v4->uAnimTime; ; i += 32 )
+    {
+      v9 = *(short *)i;
+      if ( v6 <= v9 )
+        break;
+      v6 -= v9;
+      ++v7;
+    }
+    result = &v3[v7];
+  }
+  else
+  {
+    result = &v3[uIconID];
+  }
+  return result;
+}
+
+//----- (00494FBF) --------------------------------------------------------
+void IconFrameTable::InitializeAnimation(unsigned int uIconID)
+{
+  IconFrameTable *v2; // esi@1
+  unsigned int v3; // edi@3
+  const char *i; // eax@3
+  IconFrame *v5; // eax@5
+
+  v2 = this;
+  if ( (signed int)uIconID <= (signed int)this->uNumIcons && (uIconID & 0x80000000u) == 0 )
+  {
+    v3 = uIconID;
+    for ( i = this->pIcons[uIconID].pTextureName; ; i = v5[v3].pTextureName )
+    {
+      v2->pIcons[v3].uTextureID = pIcons_LOD->LoadTexture(i, TEXTURE_16BIT_PALETTE);
+      v5 = v2->pIcons;
+      if ( !(v5[v3].uFlags & 1) )
+        break;
+      ++v3;
+    }
+  }
+}
+
+//----- (0049500A) --------------------------------------------------------
+void IconFrameTable::ToFile()
+{
+  IconFrameTable *v1; // esi@1
+  FILE *v2; // eax@1
+  FILE *v3; // edi@1
+
+  auto Str = this;
+
+  v1 = Str;
+  v2 = fopen("data\\dift.bin", "wb");
+  v3 = v2;
+  if ( !v2 )
+    Abortf("Unable to save dift.bin!");
+  fwrite(v1, 4u, 1u, v2);
+  fwrite(v1->pIcons, 0x20u, v1->uNumIcons, v3);
+  fclose(v3);
+}
+
+//----- (00495056) --------------------------------------------------------
+void IconFrameTable::FromFile(void *pSerialized)
+{
+  uNumIcons = *(int *)pSerialized;
+  pIcons = (IconFrame *)pAllocator->AllocNamedChunk(pIcons, 32 * uNumIcons, "I Frames");
+  memcpy(pIcons, (char *)pSerialized + 4, 32 * uNumIcons);
+}
+
+//----- (0049509D) --------------------------------------------------------
+int IconFrameTable::FromFileTxt(const char *Args)
+{
+  IconFrameTable *v2; // ebx@1
+  FILE *v3; // eax@1
+  int v4; // esi@3
+  void *v5; // eax@10
+  FILE *v6; // ST0C_4@12
+  char *i; // eax@12
+  const char *v8; // ST00_4@15
+  int v9; // eax@16
+  int v10; // edx@20
+  int v11; // ecx@21
+  int v12; // eax@22
+  signed int j; // edx@25
+  IconFrame *v14; // ecx@26
+  int v15; // esi@26
+  int k; // eax@27
+  signed int result; // eax@11
+  char Buf; // [sp+Ch] [bp-2F8h]@3
+  FrameTableTxtLine v19; // [sp+200h] [bp-104h]@4
+  FrameTableTxtLine v20; // [sp+27Ch] [bp-88h]@4
+  int v21; // [sp+2F8h] [bp-Ch]@3
+  int v22; // [sp+2FCh] [bp-8h]@3
+  FILE *File; // [sp+300h] [bp-4h]@1
+  int Argsa; // [sp+30Ch] [bp+8h]@26
+
+  v2 = this;
+  //TileTable::dtor((TileTable *)this);
+  v3 = fopen(Args, "r");
+  File = v3;
+  if ( !v3 )
+    Abortf("IconFrameTable::load - Unable to open file: %s.", Args);
+  v4 = 0;
+  v21 = 0;
+  v22 = 1;
+  if ( fgets(&Buf, 490, v3) )
+  {
+    do
+    {
+      *strchr(&Buf, 10) = 0;
+      memcpy(&v20, frame_table_txt_parser(&Buf, &v19), sizeof(v20));
+      if ( v20.uPropCount && *v20.pProperties[0] != 47 )
+      {
+        if ( v20.uPropCount < 3 )
+          Abortf("IconFrameTable::loadText, too few arguments, %s line %i.", Args, v22);
+        ++v21;
+      }
+      ++v22;
+    }
+    while ( fgets(&Buf, 490, File) );
+    v4 = v21;
+  }
+  v2->uNumIcons = v4;
+  v5 = pAllocator->AllocNamedChunk(v2->pIcons, 32 * v4, "I Frames");
+  v2->pIcons = (IconFrame *)v5;
+  if ( v5 )
+  {
+    v6 = File;
+    v2->uNumIcons = 0;
+    fseek(v6, 0, 0);
+    for ( i = fgets(&Buf, 490, File); i; i = fgets(&Buf, 490, File) )
+    {
+      *strchr(&Buf, 10) = 0;
+      memcpy(&v20, frame_table_txt_parser(&Buf, &v19), sizeof(v20));
+      if ( v20.uPropCount && *v20.pProperties[0] != 47 )
+      {
+        strcpy(v2->pIcons[v2->uNumIcons].pAnimationName, v20.pProperties[0]);
+        strcpy(v2->pIcons[v2->uNumIcons].pTextureName, v20.pProperties[1]);
+        v8 = v20.pProperties[2];
+        v2->pIcons[v2->uNumIcons].uFlags = 0;
+        if ( !_stricmp(v8, "new") )
+        {
+          v9 = (int)&v2->pIcons[v2->uNumIcons].uFlags;
+          *(char *)v9 |= 4u;
+        }
+        v2->pIcons[v2->uNumIcons].uAnimTime = atoi(v20.pProperties[3]);
+        v2->pIcons[v2->uNumIcons].uAnimLength = 0;
+        v2->pIcons[v2->uNumIcons++].uTextureID = 0;
+      }
+    }
+    fclose(File);
+    v10 = 0;
+    if ( (signed int)(v2->uNumIcons - 1) > 0 )
+    {
+      v11 = 0;
+      do
+      {
+        v12 = (int)&v2->pIcons[v11];
+        if ( !(*(char *)(v12 + 60) & 4) )
+          *(char *)(v12 + 28) |= 1u;
+        ++v10;
+        ++v11;
+      }
+      while ( v10 < (signed int)(v2->uNumIcons - 1) );
+    }
+    for ( j = 0; j < (signed int)v2->uNumIcons; *(short *)(Argsa + 26) = v15 )
+    {
+      v14 = v2->pIcons;
+      Argsa = (int)&v14[j];
+      v15 = *(short *)(Argsa + 24);
+      if ( *(char *)(Argsa + 28) & 1 )
+      {
+        ++j;
+        for ( k = (int)&v14[j]; *(char *)(k + 28) & 1; k += 32 )
+        {
+          v15 += *(short *)(k + 24);
+          ++j;
+        }
+        LOWORD(v15) = v14[j].uAnimTime + v15;
+      }
+      ++j;
+    }
+    result = 1;
+  }
+  else
+  {
+    fclose(File);
+    result = 0;
+  }
+  return result;
+}
+//----- (0042EB78) --------------------------------------------------------
+int IconFrameTable::GetIconAnimLength(unsigned int uIconID)
+{
+  return 8 * this->pIcons[uIconID].uAnimLength;
+}
\ No newline at end of file
--- a/Indoor.cpp	Sun Jun 23 14:27:32 2013 +0600
+++ b/Indoor.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -37,10 +37,13 @@
 
 #include "mm7_data.h"
 #include "MM7.h"
-
-
-
-
+#include "Sprites.h"
+#include "Game.h"
+#include "stru6.h"
+#include "ParticleEngine.h"
+#include "Outdoor_stuff.h"
+#include "texts.h"
+#include "GUIWindow.h"
 
 
 
@@ -1335,7 +1338,7 @@
         nodes[num_nodes].uViewportZ = pBLVRenderParams->uViewportZ;
         nodes[num_nodes].uViewportY = pBLVRenderParams->uViewportY;
         nodes[num_nodes].uViewportW = pBLVRenderParams->uViewportW;
-        nodes[num_nodes].field_C._43F9E1(pBLVRenderParams->uViewportX, pBLVRenderParams->uViewportY,
+        nodes[num_nodes].field_C.GetViewportData(pBLVRenderParams->uViewportX, pBLVRenderParams->uViewportY,
                                          pBLVRenderParams->uViewportZ, pBLVRenderParams->uViewportW);
         AddBspNodeToRenderList(++num_nodes - 1);
         return;
@@ -1491,7 +1494,7 @@
         v3->nodes[v3->num_nodes].uViewportZ = LOWORD(pBLVRenderParams->uViewportZ);
         v3->nodes[v3->num_nodes].uViewportY = LOWORD(pBLVRenderParams->uViewportY);
         v3->nodes[v3->num_nodes].uViewportW = LOWORD(pBLVRenderParams->uViewportW);
-        v3->nodes[v3->num_nodes++].field_C._43F9E1(
+        v3->nodes[v3->num_nodes++].field_C.GetViewportData(
           SLOWORD(pBLVRenderParams->uViewportX),
           pBLVRenderParams->uViewportY,
           SLOWORD(pBLVRenderParams->uViewportZ),
@@ -4639,7 +4642,2198 @@
     }
   }
 }
-
+//----- (0046CEC3) --------------------------------------------------------
+int BLV_GetFloorLevel(int x, int y, int z, unsigned int uSectorID, unsigned int *pFaceID)
+{
+  int v13; // ecx@13
+  signed int v14; // ebx@14
+  int v15; // eax@16
+  //int v16; // edx@19
+  //int v17; // ST18_4@19
+  //signed int v18; // edx@19
+  //signed __int64 v19; // qtt@19
+  int v21; // eax@27
+  //int v22; // ecx@29
+  signed int v28; // eax@45
+  int v29; // ebx@47
+  int v30; // edx@49
+  //int v31; // ST10_4@49
+  //signed int v32; // edx@49
+  signed __int64 v33; // qtt@49
+  //signed int v34; // eax@54
+  //signed int v35; // esi@56
+  //int result; // eax@57
+  int v38; // edx@62
+  //int v44; // [sp+20h] [bp-20h]@10
+  bool v47; // [sp+24h] [bp-1Ch]@43
+  bool v48; // [sp+28h] [bp-18h]@10
+  bool v49; // [sp+28h] [bp-18h]@41
+  bool v50; // [sp+2Ch] [bp-14h]@12
+  signed int v53; // [sp+30h] [bp-10h]@10
+  signed int v54; // [sp+30h] [bp-10h]@41
+  signed int v55; // [sp+34h] [bp-Ch]@1
+
+  //LOG_DECOMPILATION_WARNING();
+
+  static int blv_floor_id[50]; // 00721200
+  static int blv_floor_level[50]; // 007212C8
+
+  static __int16 word_721390_ys[104]; // idb
+  static __int16 word_721460_xs[104]; // idb
+
+  auto pSector = &pIndoor->pSectors[uSectorID];
+  v55 = 0;
+  for (uint i = 0; i < pSector->uNumFloors; ++i)
+  {
+    auto pFloor = &pIndoor->pFaces[pSector->pFloors[i]];
+    if (pFloor->Clickable())
+      continue;
+
+    assert(pFloor->uNumVertices);
+    if (x <= pFloor->pBounding.x2 && x >= pFloor->pBounding.x1 &&
+        y <= pFloor->pBounding.y2 && y >= pFloor->pBounding.y1)
+    {
+      for (uint j = 0; j < pFloor->uNumVertices; ++j)
+      {
+        word_721460_xs[2 * j] =     pFloor->pXInterceptDisplacements[j] + pIndoor->pVertices[pFloor->pVertexIDs[j]].x;
+        word_721460_xs[2 * j + 1] = pFloor->pXInterceptDisplacements[j] + pIndoor->pVertices[pFloor->pVertexIDs[j + 1]].x;
+        word_721390_ys[2 * j] =     pFloor->pYInterceptDisplacements[j] + pIndoor->pVertices[pFloor->pVertexIDs[j]].y;
+        word_721390_ys[2 * j + 1] = pFloor->pYInterceptDisplacements[j] + pIndoor->pVertices[pFloor->pVertexIDs[j + 1]].y;
+      }
+      word_721460_xs[2 * pFloor->uNumVertices] = word_721460_xs[0];
+      word_721390_ys[2 * pFloor->uNumVertices] = word_721390_ys[0];
+
+      v50 = word_721390_ys[0] >= y;
+      v53 = 0;
+
+      for (uint j = 0; j < 2 * pFloor->uNumVertices; ++j)
+      {
+        if (v53 >= 2)
+          break;
+
+        v48 = v50;
+        v50 = word_721390_ys[j + 1] >= y;
+
+          v13 = i;
+          if (v48 == v50)
+            continue;
+
+            v14 = word_721460_xs[j + 1] >= x ? 0 : 2;
+            v15 = v14 | (word_721460_xs[j] < x);
+
+          if (v15 == 3)
+            continue;
+          else if (!v15)
+            ++v53;
+          else
+          {
+            auto a_div_b = fixpoint_div(y - word_721390_ys[j], word_721390_ys[j + 1] - word_721390_ys[j]);
+            auto res = fixpoint_sub0((signed int)word_721460_xs[j + 1] - (signed int)word_721460_xs[j], a_div_b);
+
+            if (res + word_721460_xs[j] >= x)
+                ++v53;
+          }
+      }
+
+
+        if ( v53 == 1 )
+        {
+          if ( v55 >= 50 )
+            break;
+          if ( pFloor->uPolygonType == POLYGON_Floor || pFloor->uPolygonType == POLYGON_Ceiling )
+          {
+            v21 = pIndoor->pVertices[pFloor->pVertexIDs[0]].z;
+          }
+          else
+          {
+            v21 = fixpoint_sub0(pFloor->zCalc1, x) + fixpoint_sub0(pFloor->zCalc2, y) + (short)(pFloor->zCalc3 >> 16);
+          }
+          blv_floor_level[v55] = v21;
+          blv_floor_id[v55] = pSector->pFloors[i];
+          v55++;
+        }
+    }
+  }
+
+
+  if ( pSector->field_0 & 8 )
+  {
+    for (uint i = 0; i < pSector->uNumPortals; ++i)
+    {
+      auto portal = &pIndoor->pFaces[pSector->pPortals[i]];
+      if (portal->uPolygonType != POLYGON_Floor)
+        continue;
+
+      if (!portal->uNumVertices)
+        continue;
+
+      if (x <= portal->pBounding.x2 && x >= portal->pBounding.x1 &&
+          y <= portal->pBounding.y2 && y >= portal->pBounding.y1 )
+      {
+        for (uint j = 0; j < portal->uNumVertices; ++j)
+        {
+          word_721460_xs[2 * j] =     portal->pXInterceptDisplacements[j] + pIndoor->pVertices[portal->pVertexIDs[j]].x;
+          word_721460_xs[2 * j + 1] = portal->pXInterceptDisplacements[j + 1] + pIndoor->pVertices[portal->pVertexIDs[j + 1]].x;
+          word_721390_ys[2 * j] =     portal->pYInterceptDisplacements[j] + pIndoor->pVertices[portal->pVertexIDs[j]].y;
+          word_721390_ys[2 * j + 1] = portal->pYInterceptDisplacements[j + 1] + pIndoor->pVertices[portal->pVertexIDs[j + 1]].y;
+        }
+        word_721460_xs[2 * portal->uNumVertices] = word_721460_xs[0];
+        word_721390_ys[2 * portal->uNumVertices] = word_721390_ys[0];
+        v54 = 0;
+        v47 = word_721390_ys[0] >= y;
+
+          for (uint j = 0; j < 2 * portal->uNumVertices; ++j)
+          {
+            v49 = v47;
+            if ( v54 >= 2 )
+              break;
+            v47 = word_721390_ys[j + 1] >= y;
+            if ( v49 != v47 )
+            {
+              v28 = word_721460_xs[j + 1] >= x ? 0 : 2;
+              v29 = v28 | (word_721460_xs[j] < x);
+              if ( v29 != 3 )
+              {
+                if ( !v29 )
+                  ++v54;
+                else
+                {
+                  auto a_div_b = fixpoint_div(y - word_721390_ys[j], word_721390_ys[j + 1] - word_721390_ys[j]);
+                  auto res = fixpoint_sub0(word_721460_xs[j + 1] - word_721460_xs[j], a_div_b);
+                  if (res + word_721460_xs[j] >= x)
+                    ++v54;
+                }
+              }
+            }
+          }
+          if ( v54 == 1 )
+          {
+            if ( v55 >= 50 )
+              break;
+            blv_floor_level[v55] = -29000;
+            blv_floor_id[v55] = pSector->pPortals[i];
+            v55++;
+          }
+      }
+    }
+  }
+  if ( v55 == 1 )
+  {
+    *pFaceID = blv_floor_id[0];
+    return blv_floor_level[0];
+  }
+  if ( !v55 )
+    return -30000;
+  *pFaceID = blv_floor_id[0];
+  //result = blv_floor_level[0];
+
+    /*for ( v35 = 1; v35 < v55; ++v35 )
+    {
+      if ( blv_floor_level[0] <= z + 5 )
+      {
+        if ( blv_floor_level[v35] >= blv_floor_level[0] || blv_floor_level[v35] > z + 5 )
+          continue;
+        blv_floor_level[0] = blv_floor_level[v35];
+        *pFaceID = blv_floor_id[v35];
+        continue;
+      }
+      if ( blv_floor_level[v35] < blv_floor_level[0] )
+      {
+        blv_floor_level[0] = blv_floor_level[v35];
+        *pFaceID = blv_floor_id[v35];
+      }
+    }*/
+
+    
+  int result = blv_floor_level[0];
+  for (uint i = 1; i < v55; ++i)
+  {
+      v38 = blv_floor_level[i];
+      if ( result <= z + 5 )
+      {
+        if ( v38 > result && v38 <= z + 5 )
+        {
+          result = blv_floor_level[i];
+          *pFaceID = blv_floor_id[i];
+        }
+      }
+      else if ( v38 < result )
+      {
+        result = blv_floor_level[i];
+        *pFaceID = blv_floor_id[i];
+      }
+  }
+
+  return result;
+}
+//----- (004016FA) --------------------------------------------------------
+int __cdecl MakeActorAIList_BLV()
+{
+  Actor *v0; // esi@2
+  int v1; // eax@4
+  int v2; // ebx@4
+  unsigned int v3; // ecx@4
+  int v4; // edx@5
+  int v5; // edx@7
+  unsigned int v6; // edx@9
+  unsigned int v7; // ST24_4@10
+  int v8; // eax@10
+  int v9; // edi@10
+  int v10; // ebx@14
+  char v11; // zf@16
+  int v12; // eax@22
+  int v13; // edx@24
+  int v14; // ecx@25
+  int v15; // ebx@26
+  unsigned int *v16; // ecx@27
+  unsigned int v17; // esi@27
+  int v18; // ecx@31
+  signed int v19; // edi@31
+  Actor *v20; // esi@32
+  bool v21; // eax@33
+  int v22; // eax@34
+  signed int v23; // ebx@36
+  Actor *v24; // esi@37
+  signed int v25; // eax@40
+  int v26; // eax@43
+  int v27; // ebx@45
+  int j; // edi@45
+  unsigned int v29; // eax@46
+  int v30; // eax@48
+  int v31; // ecx@51
+  int v32; // eax@51
+  signed int v33; // eax@53
+  __int64 v34; // qax@55
+  char *v35; // ecx@56
+  int v37; // [sp+Ch] [bp-18h]@1
+  int v38; // [sp+10h] [bp-14h]@4
+  int v39; // [sp+14h] [bp-10h]@4
+  int v40; // [sp+18h] [bp-Ch]@10
+  int v41; // [sp+18h] [bp-Ch]@29
+  int i; // [sp+18h] [bp-Ch]@31
+  signed int v43; // [sp+1Ch] [bp-8h]@1
+  signed int v44; // [sp+1Ch] [bp-8h]@25
+  int v45; // [sp+20h] [bp-4h]@1
+
+//  __debugbreak(); // refactor for blv ai
+  pParty->uFlags &= 0xFFFFFFCFu;
+  v37 = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z);
+  v45 = 0;
+  v43 = 0;
+  if ( (signed int)uNumActors > 0 )
+  {
+    v0 = pActors.data();//[0].uAttributes;
+    do
+    {
+      BYTE1(v0->uAttributes) &= 0xFBu;
+      if ( ! v0->CanAct() )
+        goto LABEL_60;
+	  v39 = abs(pParty->vPosition.z - v0->vPosition.z);
+	  v38 = abs(pParty->vPosition.y - v0->vPosition.y);
+	  v1 = abs(pParty->vPosition.x - v0->vPosition.x);
+      v2 = v38;
+      v3 = v39;
+      if ( v1 < v38 )
+      {
+        v4 = v1;
+        v1 = v38;
+        v2 = v4;
+      }
+      if ( v1 < v39 )
+      {
+        v5 = v1;
+        v1 = v39;
+        v3 = v5;
+      }
+      if ( v2 < (signed int)v3 )
+      {
+        v6 = v3;
+        v3 = v2;
+        v2 = v6;
+      }
+      v7 = ((unsigned int)(11 * v2) >> 5) + (v3 >> 2) + v1;
+      v8 = v0->uActorRadius;
+      v9 = v7 - v8;
+      v40 = v7 - v8;
+      if ( v40 < 0 )
+      {
+        v9 = 0;
+        v40 = 0;
+      }
+      if ( v9 < 10240 )
+      {
+        v10 = v0->uAttributes & 0xFEFFFFFF;
+        v0->uAttributes = v10;
+        if ( v10 & 0x80000 || v0->GetActorsRelation(0) )
+        {
+          v11 = (pParty->uFlags & 0x10) == 0;
+          v0->uAttributes = v10 | 0x1000000;
+          if ( v11 && (double)v40 < 307.2 )
+            pParty->uFlags |= 0x10u;
+          if ( !(pParty->uFlags & 0x20) && v9 < 5120 )
+            pParty->uFlags |= 0x20u;
+        }
+        v12 = v45++;
+        ai_near_actors_distances[v12] = v9;
+        ai_near_actors_ids[v12] = v43;
+      }
+      else
+      {
+LABEL_60:
+        BYTE1(v0->uAttributes) &= 0xBFu;
+      }
+      ++v43;
+      ++v0;
+    }
+    while ( v43 < (signed int)uNumActors );
+  }
+  v13 = 0;
+  if ( v45 > 0 )
+  {
+    v14 = 1;
+    v44 = 1;
+    do
+    {
+      while ( 1 )
+      {
+        v41 = v14;
+        if ( v14 >= v45 )
+          break;
+        v15 = ai_near_actors_distances[v13];
+        if ( v15 > ai_near_actors_distances[v14] )
+        {
+          v16 = &ai_near_actors_ids[v14];
+          v17 = ai_near_actors_ids[v13];
+          ai_near_actors_ids[v13] = *v16;
+          *v16 = v17;
+          v14 = v41;
+          ai_near_actors_distances[v13] = ai_near_actors_distances[v41];
+          ai_near_actors_distances[v41] = v15;
+        }
+        ++v14;
+      }
+      ++v13;
+      v14 = v44 + 1;
+      v44 = v14;
+    }
+    while ( v14 - 1 < v45 );
+  }
+  v18 = 0;
+  v19 = 0;
+  for ( i = 0; v18 < v45; i = v18 )
+  {
+    v20 = &pActors[ai_near_actors_ids[v18]];
+    if ( v20->uAttributes & 0x8000
+      || (v21 = sub_4070EF_prolly_collide_objects(PID(OBJECT_Actor,ai_near_actors_ids[v18]), 4u), v18 = i, v21) )
+    {
+      v22 = ai_near_actors_ids[v18];
+      v20->uAttributes |= 0x8000u;
+      ai_array_4F6638_actor_ids[v19] = v22;
+      ai_array_4F5E68[v19++] = ai_near_actors_distances[v18];
+      if ( v19 >= 30 )
+        break;
+    }
+    ++v18;
+  }
+  v23 = 0;
+  ai_arrays_size = v19;
+  if ( (signed int)uNumActors > 0 )
+  {
+    v24 = pActors.data();//[0].uAttributes;
+    do
+    {
+      if ( v24->CanAct() && v24->uSectorID == v37 )
+      {
+        v25 = 0;
+        if ( v19 <= 0 )
+        {
+LABEL_43:
+          v26 = ai_arrays_size;
+          BYTE1(v24->uAttributes) |= 0x40u;
+          ++ai_arrays_size;
+          ai_array_4F6638_actor_ids[v26] = v23;
+        }
+        else
+        {
+          while ( ai_array_4F6638_actor_ids[v25] != v23 )
+          {
+            ++v25;
+            if ( v25 >= v19 )
+              goto LABEL_43;
+          }
+        }
+      }
+      ++v23;
+      ++v24;
+    }
+    while ( v23 < (signed int)uNumActors );
+  }
+  v27 = ai_arrays_size;
+  for ( j = 0; j < v45; ++j )
+  {
+    v29 = ai_near_actors_ids[j];
+    if ( pActors[v29].uAttributes & 0xC000 && pActors[v29].CanAct() )
+    {
+      v30 = 0;
+      if ( v27 <= 0 )
+      {
+LABEL_51:
+        v31 = ai_arrays_size;
+        v32 = ai_near_actors_ids[j];
+        ++ai_arrays_size;
+        ai_array_4F6638_actor_ids[v31] = v32;
+      }
+      else
+      {
+        while ( ai_array_4F6638_actor_ids[v30] != ai_near_actors_ids[j] )
+        {
+          ++v30;
+          if ( v30 >= v27 )
+            goto LABEL_51;
+        }
+      }
+    }
+  }
+  v33 = ai_arrays_size;
+  if ( ai_arrays_size > 30 )
+  {
+    v33 = 30;
+    ai_arrays_size = 30;
+  }
+  memcpy(ai_near_actors_ids.data(), ai_array_4F6638_actor_ids.data(), 4 * v33);
+  memcpy(ai_near_actors_distances.data(), ai_array_4F5E68.data(), 4 * ai_arrays_size);
+  v34 = (unsigned int)ai_arrays_size;
+  if ( ai_arrays_size > 0 )
+  {
+    do
+    {
+      v35 = (char *)&pActors[ai_near_actors_ids[HIDWORD(v34)]].uAttributes;
+      v35[1] |= 4u;
+      ++HIDWORD(v34);
+    }
+    while ( SHIDWORD(v34) < (signed int)v34 );
+  }
+  return v34;
+}
+//----- (0043FDED) --------------------------------------------------------
+void PrepareActorRenderList_BLV()
+{
+  RenderBillboard *v0; // esi@0
+  unsigned __int16 v3; // ax@3
+  unsigned int v4; // eax@5
+  unsigned __int16 v5; // cx@5
+  int v6; // esi@5
+  unsigned int v7; // eax@7
+  int v8; // eax@10
+  SpriteFrame *v9; // eax@16
+  SpriteFrame *v10; // ebx@18
+  //int *v11; // eax@18
+  int v12; // ecx@28
+  //IndoorCameraD3D **v14; // eax@36
+  double v15; // st7@36
+  float v16; // eax@36
+  //double v17; // ST30_8@36
+  signed __int64 v18; // qtt@36
+  int v19; // ST5C_4@36
+  signed __int64 v20; // qtt@37
+  int v21; // ST5C_4@37
+  signed __int16 v22; // cx@39
+  int v23; // ST50_4@40
+  signed int v24; // ecx@40
+  int v25; // edx@44
+  __int16 v26; // ax@44
+  //MonsterDesc *v27; // edx@44
+  //int v28; // ecx@44
+  unsigned __int8 v29; // zf@44
+  unsigned __int8 v30; // sf@44
+  unsigned int v31; // [sp-8h] [bp-5Ch]@15
+  int v32; // [sp+1Ch] [bp-38h]@5
+  int a3; // [sp+20h] [bp-34h]@5
+  int a2; // [sp+24h] [bp-30h]@5
+  int a1a; // [sp+28h] [bp-2Ch]@5
+  __int16 a5; // [sp+2Ch] [bp-28h]@5
+  int a5a; // [sp+2Ch] [bp-28h]@36
+  int a5b; // [sp+2Ch] [bp-28h]@40
+  __int16 v41; // [sp+3Ch] [bp-18h]@18
+  int a6; // [sp+40h] [bp-14h]@34
+  int v43; // [sp+44h] [bp-10h]@34
+  int z; // [sp+48h] [bp-Ch]@32
+  signed int y; // [sp+4Ch] [bp-8h]@32
+  int x; // [sp+50h] [bp-4h]@32
+
+  for (uint i = 0; i < uNumActors; ++i)
+  {
+    auto p = &pActors[i];
+
+    if (p->uAIState == Removed ||
+        p->uAIState == Disabled)
+      continue;
+
+    a5 = p->uSectorID;
+    a2 = p->vPosition.y;
+    a1a = p->vPosition.x;
+    a3 = p->vPosition.z;
+    v4 = stru_5C6E00->Atan2(a1a - pBLVRenderParams->vPartyPos.x, a2 - pBLVRenderParams->vPartyPos.y);
+    LOWORD(v0) = p->uYawAngle;
+    v5 = p->uCurrentActionAnimation;
+    v6 = ((signed int)((char *)v0 + ((signed int)stru_5C6E00->uIntegerPi >> 3) - v4 + stru_5C6E00->uIntegerPi) >> 8) & 7;
+    v32 = v6;
+    if ( pParty->bTurnBasedModeOn )
+    {
+      if ( v5 == 1 )
+      {
+        v7 = pMiscTimer->uTotalGameTimeElapsed;
+        goto LABEL_10;
+      }
+    }
+    else
+    {
+      if ( v5 == 1 )
+      {
+        v7 = pBLVRenderParams->field_0_timer_;
+LABEL_10:
+        v8 = i * 32 + v7;
+        goto LABEL_12;
+      }
+    }
+    v8 = p->uCurrentActionTime;
+LABEL_12:
+    if (p->pActorBuffs[5].uExpireTime > 0i64 || p->pActorBuffs[6].uExpireTime > 0i64 )
+      v8 = 0;
+    v31 = p->pSpriteIDs[v5];
+    if (p->uAIState == Resurrected)
+      v9 = pSpriteFrameTable->GetFrameBy_x(v31, v8);
+    else
+      v9 = pSpriteFrameTable->GetFrame(v31, v8);
+    v41 = 0;
+    v10 = v9;
+    //v11 = (int *)v9->uFlags;
+    if (v9->uFlags & 2)
+      v41 = 2;
+    if (v9->uFlags & 0x40000)
+      v41 |= 0x40u;
+    if (v9->uFlags & 0x20000)
+      LOBYTE(v41) = v41 | 0x80;
+    v0 = (RenderBillboard *)(256 << v6);
+    if ( (unsigned int)v0 & v9->uFlags)
+      v41 |= 4u;
+    if ( v10->uGlowRadius )
+    {
+      //LOBYTE(v11) = byte_4E94D3;
+      pMobileLightsStack->AddLight(
+        a1a,
+        a2,
+        a3,
+        a5,
+        v10->uGlowRadius,
+        0xFFu,
+        0xFFu,
+        0xFFu,
+        byte_4E94D3);
+    }
+    v12 = 0;
+    if ( pBspRenderer->uNumVisibleNotEmptySectors <= 0 )
+      continue;
+    while (pBspRenderer->pVisibleSectorIDs_toDrawDecorsActorsEtcFrom[v12] != p->uSectorID)
+    {
+      ++v12;
+      if ( v12 >= pBspRenderer->uNumVisibleNotEmptySectors )
+        goto _continue;
+    }
+    if ( !pGame->pIndoorCameraD3D->ApplyViewTransform_TrueIfStillVisible(a1a, a2, a3, &x, &y, &z, 1)
+      || (v0 = (RenderBillboard *)abs(x), (signed int)v0 < abs(y)) )
+      continue;
+    pGame->pIndoorCameraD3D->Project(x, y, z, &v43, &a6);
+    v0 = &pBillboardRenderList[uNumBillboardsToDraw];
+    if (uNumBillboardsToDraw >= 500)
+      break;
+    ++uNumBillboardsToDraw;
+    ++uNumSpritesDrawnThisFrame;
+    p->uAttributes |= 8u;
+    v29 = pRenderer->pRenderD3D == 0;
+    v0->uHwSpriteID = v10->pHwSpriteIDs[v32];
+    v0->uPalette = v10->uPaletteIndex;
+    v0->uIndoorSectorID = a5;
+    if ( v29 )
+    {
+      LODWORD(v20) = pBLVRenderParams->field_40 << 16;
+      HIDWORD(v20) = pBLVRenderParams->field_40 >> 16;
+      v21 = v20 / x;
+      v0->_screenspace_x_scaler_packedfloat = (unsigned __int64)(v10->scale * v20 / x) >> 16;
+      a5a = (unsigned __int64)(v10->scale * (signed __int64)v21) >> 16;
+    }
+    else
+    {
+      //v14 = &pGame->pIndoorCameraD3D;
+      v0->fov_x = pGame->pIndoorCameraD3D->fov_x;
+      v15 = pGame->pIndoorCameraD3D->fov_y;
+      v16 = v0->fov_x;
+      v0->fov_y = v15;
+      //v17 = v16 + 6.7553994e15;
+      LODWORD(v18) = 0;
+      HIDWORD(v18) = floorf(v16 + 0.5f);
+      v19 = v18 / x;
+      v0->_screenspace_x_scaler_packedfloat = (unsigned __int64)(v10->scale * v18 / x) >> 16;
+      a5a = (unsigned __int64)(v10->scale * (signed __int64)v19) >> 16;
+    }
+    v0->_screenspace_y_scaler_packedfloat = a5a;
+    if ( (signed __int64)p->pActorBuffs[3].uExpireTime <= 0 )
+    {
+      if ( (signed __int64)p->pActorBuffs[10].uExpireTime > 0 )
+      {
+        a5b = (unsigned __int64)(pGame->pStru6Instance->_4A806F(p) * (signed __int64)v0->_screenspace_y_scaler_packedfloat) >> 16;
+        goto LABEL_43;
+      }
+    }
+    else
+    {
+      v22 = p->pActorBuffs[3].uPower;
+      if ( v22 )
+      {
+        v23 = (unsigned __int64)(65536 / (unsigned __int16)v22 * (signed __int64)v0->_screenspace_x_scaler_packedfloat) >> 16;
+        v24 = p->pActorBuffs[3].uPower;
+        v0->_screenspace_x_scaler_packedfloat = v23;
+        a5b = (unsigned __int64)(65536 / v24 * (signed __int64)v0->_screenspace_y_scaler_packedfloat) >> 16;
+LABEL_43:
+        v0->_screenspace_y_scaler_packedfloat = a5b;
+        goto LABEL_44;
+      }
+    }
+LABEL_44:
+    HIWORD(v25) = HIWORD(x);
+    v0->world_x = a1a;
+    v0->world_y = a2;
+    v0->world_z = a3;
+    v0->uScreenSpaceX = v43;
+    v0->uScreenSpaceY = a6;
+    LOWORD(v25) = 0;
+    LOBYTE(v26) = v41;
+
+    //v0->sZValue = v25 + (PID(OBJECT_Actor,i));
+    v0->actual_z = HIWORD(x);
+    v0->object_pid = PID(OBJECT_Actor,i);
+
+    v29 = HIDWORD(p->pActorBuffs[5].uExpireTime) == 0;
+    v30 = HIDWORD(p->pActorBuffs[5].uExpireTime) < 0;
+    v0->field_1E = v41;
+    v0->pSpriteFrame = v10;
+    v0->uTintColor = pMonsterList->pMonsters[p->pMonsterInfo.uID - 1].uTintColor;
+    if ( !v30 && (!(v30 | v29) || LODWORD(p->pActorBuffs[5].uExpireTime)) )
+    {
+      HIBYTE(v26) = HIBYTE(v41) | 1;
+      v0->field_1E = v26;
+    }
+    
+_continue:
+    ;
+  }
+}
+//----- (0044028F) --------------------------------------------------------
+void PrepareItemsRenderList_BLV()
+{
+  ObjectDesc *v1; // ebx@4
+  __int16 v2; // ax@5
+  RenderBillboard *v3; // esi@12
+  SpriteFrame *v4; // eax@12
+  SpriteFrame *v5; // ebx@12
+  unsigned int v6; // eax@12
+  int v7; // ecx@12
+  int v8; // edx@12
+  int v9; // ecx@12
+  unsigned __int16 v10; // ax@12
+  int *v11; // eax@20
+  //char v12; // zf@26
+  __int64 v18; // ST5C_4@27
+  signed __int64 v19; // qtt@28
+  int v20; // ST5C_4@28
+  //int v21; // edx@29
+  __int16 v22; // ax@29
+  //int v23; // eax@29
+  SpriteFrame *v24; // [sp+1Ch] [bp-40h]@12
+  //__int16 a5; // [sp+28h] [bp-34h]@12
+  int a6; // [sp+2Ch] [bp-30h]@12
+  int a2; // [sp+30h] [bp-2Ch]@12
+  int a1; // [sp+34h] [bp-28h]@12
+  int v30; // [sp+38h] [bp-24h]@12
+  int v31; // [sp+38h] [bp-24h]@27
+  int a3; // [sp+40h] [bp-1Ch]@12
+  signed __int16 v34; // [sp+44h] [bp-18h]@14
+  int v35; // [sp+48h] [bp-14h]@25
+  int v36; // [sp+4Ch] [bp-10h]@25
+  signed int z; // [sp+50h] [bp-Ch]@24
+  signed int y; // [sp+54h] [bp-8h]@24
+  signed int x; // [sp+58h] [bp-4h]@24
+
+  for (uint i = 0; i < uNumSpriteObjects; ++i)
+  {
+    auto p = &pSpriteObjects[i];
+    if (p->uObjectDescID)
+    {
+      v1 = &pObjectList->pObjects[p->uObjectDescID];
+        if ( !(v1->uFlags & 1) )
+         {
+          if ( ((v2 = p->uType, v2 < 1000) || v2 >= 10000)
+            && (v2 < 500 || v2 >= 600)
+            && (v2 < 811 || v2 >= 815)
+            || pGame->pStru6Instance->_4A81CA(p))
+          {
+            //a5 = p->uSectorID;
+            a1 = p->vPosition.x;
+            a2 = p->vPosition.y;
+            a3 = p->vPosition.z;
+            v3 = &pBillboardRenderList[uNumBillboardsToDraw];
+            v4 = pSpriteFrameTable->GetFrame(v1->uSpriteID, p->uSpriteFrameID);
+            v5 = v4;
+            v24 = v4;
+            v30 = v4->uFlags;
+            a6 = v4->uGlowRadius * p->field_22_glow_radius_multiplier;
+            v6 = stru_5C6E00->Atan2(p->vPosition.x - pBLVRenderParams->vPartyPos.x,
+                                    p->vPosition.y - pBLVRenderParams->vPartyPos.y);
+            LOWORD(v7) = p->uFacing;
+            v8 = v30;
+            v9 = ((signed int)(stru_5C6E00->uIntegerPi + ((signed int)stru_5C6E00->uIntegerPi >> 3) + v7 - v6) >> 8) & 7;
+            v10 = v5->pHwSpriteIDs[v9];
+            v3->uHwSpriteID = v10;
+            if ( v30 & 0x20 )
+            {
+              v8 = v30;
+              a3 -= (signed int)((unsigned __int64)(v5->scale * (signed __int64)pSprites_LOD->pSpriteHeaders[(signed __int16)v10].uHeight) >> 16) >> 1;
+            }
+            v34 = 0;
+            if ( v8 & 2 )
+              v34 = 2;
+            if ( v8 & 0x40000 )
+              v34 |= 0x40u;
+            if ( v8 & 0x20000 )
+              LOBYTE(v34) = v34 | 0x80;
+            v11 = (int *)(256 << v9);
+            if ( (256 << v9) & v8 )
+              v34 |= 4u;
+            if ( a6 )
+            {
+              LOBYTE(v11) = byte_4E94D3;
+              pMobileLightsStack->AddLight(
+                a1,
+                a2,
+                a3,
+                p->uSectorID,
+                a6,
+                v1->uParticleTrailColorR,
+                v1->uParticleTrailColorG,
+                v1->uParticleTrailColorB,
+                byte_4E94D3);
+            }
+            if ( pGame->pIndoorCameraD3D->ApplyViewTransform_TrueIfStillVisible(
+                   a1,
+                   a2,
+                   a3,
+                   &x,
+                   &y,
+                   &z,
+                   1) )
+            {
+              pGame->pIndoorCameraD3D->Project(x, y, z, &v36, &v35);
+
+              assert(uNumBillboardsToDraw < 500);
+              //if ( (signed int)uNumBillboardsToDraw >= 500 )
+              //  return;
+              ++uNumBillboardsToDraw;
+              ++uNumSpritesDrawnThisFrame;
+              p->uAttributes |= 1u;
+              //v12 = pRenderer->pRenderD3D == 0;
+              v3->uPalette = v24->uPaletteIndex;
+              v3->uIndoorSectorID = p->uSectorID;
+              if ( pRenderer->pRenderD3D )
+              {
+                v3->fov_x = pGame->pIndoorCameraD3D->fov_x;
+                v3->fov_y = pGame->pIndoorCameraD3D->fov_y;
+                LODWORD(v18) = 0;
+                HIDWORD(v18) = (int)floorf(v3->fov_x + 0.5f);
+                v18 = v18 / x;
+                v3->_screenspace_x_scaler_packedfloat = (unsigned __int64)(v24->scale * v18) >> 16;
+                v31 = (unsigned __int64)(v24->scale * v18) >> 16;
+              }
+              else
+              {
+                LODWORD(v19) = pBLVRenderParams->field_40 << 16;
+                HIDWORD(v19) = pBLVRenderParams->field_40 >> 16;
+                v20 = v19 / x;
+                v3->_screenspace_x_scaler_packedfloat = (unsigned __int64)(v24->scale * v19 / x) >> 16;
+                v31 = (unsigned __int64)(v24->scale * (signed __int64)v20) >> 16;
+              }
+              //HIWORD(v21) = HIWORD(x);
+              //LOWORD(v21) = 0;
+              v3->_screenspace_y_scaler_packedfloat = v31;
+              v3->field_1E = v34;
+              v3->world_x = a1;
+              v3->world_y = a2;
+              v3->world_z = a3;
+              v3->uScreenSpaceX = v36;
+              v22 = v35;
+              v3->uTintColor = 0;
+              v3->uScreenSpaceY = v22;
+              //v23 = 8 * i;
+              //LOBYTE(v23) = PID(OBJECT_Item,i);
+              v3->pSpriteFrame = v24;
+              //v12 = (p->uAttributes & 0x20) == 0;
+              //v3->sZValue = v21 + v23;
+              v3->actual_z = HIWORD(x);
+              v3->object_pid = PID(OBJECT_Item,i);
+              if (p->uAttributes & 0x20)
+              {
+                if ( !pRenderer->pRenderD3D )
+                  v3->sZValue = 0;
+              }
+            }
+          }
+        }
+      }
+  }
+}
+
+//----- (00440639) --------------------------------------------------------
+void AddBspNodeToRenderList(unsigned int node_id)
+{
+  BLVSector *pSector; // esi@1
+
+  pSector = &pIndoor->pSectors[pBspRenderer->nodes[node_id].uSectorID];
+  if ( pRenderer->pRenderD3D )
+  {
+    for (uint i = 0; i < pSector->uNumNonBSPFaces; ++i)
+      //Log::Warning(L"Non-BSP face: %X", v3->pFaceIDs[v2]);
+      pBspRenderer->AddFaceToRenderList_d3d(node_id, pSector->pFaceIDs[i]);
+  }
+  else
+  {
+    for (uint i = 0; i < pSector->uNumNonBSPFaces; ++i)
+      pBspRenderer->AddFaceToRenderList_sw(node_id, pSector->pFaceIDs[i]);
+  }
+  if ( pSector->field_0 & 0x10 )
+    sub_4406BC(node_id, pSector->uFirstBSPNode);
+}
+
+//----- (004406BC) --------------------------------------------------------
+void __fastcall sub_4406BC(unsigned int node_id, unsigned int uFirstNode)
+{
+  BLVSector *pSector; // esi@2
+  BSPNode *pNode; // edi@2
+  BLVFace *pFace; // eax@2
+  int v5; // ecx@2
+  __int16 v6; // ax@6
+  int v7; // ebp@10
+  int v8; // ebx@10
+  __int16 v9; // di@18
+  //int v10; // [sp+10h] [bp-Ch]@1
+  //bool v11; // [sp+14h] [bp-8h]@5
+  BspRenderer_stru0 *node; // [sp+18h] [bp-4h]@1
+
+  //Log::Warning(L"sub_4406BC(%u, %u)", a1, uFirstNode);
+
+  //v10 = a1;
+  node = &pBspRenderer->nodes[node_id];
+  while ( 1 )
+  {
+    pSector = &pIndoor->pSectors[node->uSectorID];
+    pNode = &pIndoor->pNodes[uFirstNode];
+    pFace = &pIndoor->pFaces[pSector->pFaceIDs[pNode->uCoplanarOffset]];
+    v5 = pFace->pFacePlane_old.dist + pBLVRenderParams->vPartyPos.x * pFace->pFacePlane_old.vNormal.x
+       + pBLVRenderParams->vPartyPos.y * pFace->pFacePlane_old.vNormal.y + pBLVRenderParams->vPartyPos.z * pFace->pFacePlane_old.vNormal.z;//plane equation
+    if (pFace->Portal() && pFace->uSectorID != node->uSectorID )
+      v5 = -v5;
+    //v11 = v5 > 0;
+    if ( v5 <= 0 )
+      v6 = pNode->uFront;
+    else
+      v6 = pNode->uBack;
+    if ( v6 != -1 )
+      sub_4406BC(node_id, v6);
+    v7 = pNode->uCoplanarOffset;
+    v8 = v7 + pNode->uCoplanarSize;
+
+    //Log::Warning(L"Node %u: %X to %X (%hX)", uFirstNode, v7, v8, v2->pFaceIDs[v7]);
+    
+    if ( pRenderer->pRenderD3D )
+    {
+      while ( v7 < v8 )
+        pBspRenderer->AddFaceToRenderList_d3d(node_id, pSector->pFaceIDs[v7++]);
+    }
+    else
+    {
+      while ( v7 < v8 )
+        pBspRenderer->AddFaceToRenderList_sw(node_id, pSector->pFaceIDs[v7++]);
+    }
+    v9 = v5 > 0 ? pNode->uFront : pNode->uBack;
+    if ( v9 == -1 )
+      break;
+    uFirstNode = v9;
+  }
+}
+//----- (0043FA33) --------------------------------------------------------
+void __fastcall PrepareDecorationsRenderList_BLV(unsigned int uDecorationID, unsigned int uSectorID)
+{
+  LevelDecoration *v2; // esi@1
+  DecorationDesc *v3; // ebx@2
+  __int16 v4; // ax@2
+  double v5; // st7@3
+  int v6; // eax@5
+  int v7; // edx@5
+  unsigned int v8; // edi@5
+  int v9; // edi@5
+  int v10; // eax@7
+  SpriteFrame *v11; // eax@7
+  SpriteFrame *v12; // esi@7
+  int v13; // eax@7
+  int v14; // ebx@16
+  RenderBillboard *v15; // ecx@17
+  char v16; // zf@18
+  IndoorCameraD3D **v17; // eax@19
+  double v18; // st7@19
+  //float v19; // eax@19
+  signed __int64 v20; // qtt@19
+  signed __int64 v21; // qtt@20
+  //int v22; // edx@21
+  //int v23; // eax@21
+  Particle_sw local_0; // [sp+Ch] [bp-A0h]@3
+  //double v25; // [sp+74h] [bp-38h]@19
+  //unsigned int v26; // [sp+7Ch] [bp-30h]@1
+  int a2; // [sp+80h] [bp-2Ch]@5
+  int a3; // [sp+84h] [bp-28h]@5
+  int a1; // [sp+88h] [bp-24h]@5
+  int v30; // [sp+8Ch] [bp-20h]@7
+  //float v31; // [sp+90h] [bp-1Ch]@1
+  int a5; // [sp+94h] [bp-18h]@17
+  int z; // [sp+98h] [bp-14h]@15
+  int a6; // [sp+9Ch] [bp-10h]@17
+  int y; // [sp+A0h] [bp-Ch]@15
+  int x; // [sp+A4h] [bp-8h]@15
+  int v37; // [sp+A8h] [bp-4h]@5
+
+  //v26 = uDecorationID;
+  //LODWORD(v31) = uSectorID;
+  v2 = &pLevelDecorations[uDecorationID];
+  if (v2->field_2 & 0x20)
+    return;
+
+    v3 = &pDecorationList->pDecorations[v2->uDecorationDescID];
+    v4 = v3->uFlags;
+    if (v3->uFlags & DECORATION_EMITS_FIRE)
+    {
+      memset(&local_0, 0, 0x68u);               // fire,  like at the Pit's tavern
+      v5 = (double)v2->vPosition.x;
+      local_0.type = ParticleType_Bitmap | ParticleType_Rotating | ParticleType_8;
+      local_0.uDiffuse = 0xFF3C1E;
+      local_0.x = v5;
+      local_0.y = (double)v2->vPosition.y;
+      local_0.z = (double)v2->vPosition.z;
+      local_0.flt_10 = 0.0;
+      local_0.flt_14 = 0.0;
+      local_0.flt_18 = 0.0;
+      local_0.flt_28 = 1.0;
+      local_0.timeToLive = (rand() & 0x80) + 128;
+      local_0.uTextureID = pBitmaps_LOD->LoadTexture("effpar01");
+      pGame->pParticleEngine->AddParticle(&local_0);
+      return;
+    }
+
+
+      if (v4 & DECORATION_DONT_DRAW)
+        return;
+
+        v6 = v2->vPosition.x;
+        v7 = v2->vPosition.z;
+        a2 = v2->vPosition.y;
+        a1 = v6;
+        a3 = v7;
+        v8 = v2->field_10_y_rot
+           + ((signed int)stru_5C6E00->uIntegerPi >> 3)
+           - stru_5C6E00->Atan2(v6 - pBLVRenderParams->vPartyPos.x, a2 - pBLVRenderParams->vPartyPos.y);
+        v37 = pBLVRenderParams->field_0_timer_;
+        v9 = ((signed int)(stru_5C6E00->uIntegerPi + v8) >> 8) & 7;
+        if (pParty->bTurnBasedModeOn)
+          v37 = pMiscTimer->uTotalGameTimeElapsed;
+        v10 = abs(v2->vPosition.x + v2->vPosition.y);
+        v11 = pSpriteFrameTable->GetFrame(v3->uSpriteID, v37 + v10);
+        v30 = 0;
+        v12 = v11;
+        v13 = v11->uFlags;
+        if ( v13 & 2 )
+          v30 = 2;
+        if ( v13 & 0x40000 )
+          v30 |= 0x40u;
+        if ( v13 & 0x20000 )
+          LOBYTE(v30) = v30 | 0x80;
+        if ( (256 << v9) & v13 )
+          v30 |= 4u;
+        if ( pGame->pIndoorCameraD3D->ApplyViewTransform_TrueIfStillVisible(a1, a2, a3, &x, &y, &z, 1) )
+        {
+          v14 = abs(x);
+          if ( v14 >= abs(y) )
+          {
+            pGame->pIndoorCameraD3D->Project(x, y, z, &a5, &a6);
+
+            v15 = &pBillboardRenderList[uNumBillboardsToDraw];
+            assert(uNumBillboardsToDraw < 500);
+
+              ++uNumBillboardsToDraw;
+              ++uNumDecorationsDrawnThisFrame;
+              v16 = pRenderer->pRenderD3D == 0;
+              v15->uHwSpriteID = v12->pHwSpriteIDs[v9];
+              v15->uPalette = v12->uPaletteIndex;
+              v15->uIndoorSectorID = uSectorID;
+              if ( v16 )
+              {
+                LODWORD(v21) = pBLVRenderParams->field_40 << 16;
+                HIDWORD(v21) = pBLVRenderParams->field_40 >> 16;
+                v37 = v21 / x;
+                //LODWORD(v31) = v12->scale;
+                v37 = v21 / x;
+                v15->_screenspace_x_scaler_packedfloat = (unsigned __int64)(v12->scale * v21 / x) >> 16;
+                v37 = (unsigned __int64)(v12->scale * (signed __int64)v37) >> 16;
+              }
+              else
+              {
+                v17 = &pGame->pIndoorCameraD3D;
+                v15->fov_x = pGame->pIndoorCameraD3D->fov_x;
+                v18 = (*v17)->fov_y;
+                //v19 = v15->fov_x;
+                v15->fov_y = v18;
+                //v31 = v19;
+                //v25 = v19 + 6.7553994e15;
+                //v25 = floorf(v15->fov_x + 0.5f);
+                LODWORD(v20) = 0;
+                HIDWORD(v20) = floorf(v15->fov_x + 0.5f);
+                v37 = v20 / x;
+                //LODWORD(v31) = v12->scale;
+                v37 = (unsigned __int64)(v12->scale * v20 / x) >> 16;
+                v15->_screenspace_x_scaler_packedfloat = (unsigned __int64)(v12->scale * v20 / x) >> 16;
+                //v31 = v15->fov_y;
+                //v25 = v31 + 6.7553994e15;
+                //v25 = floorf(v15->fov_y + 0.5f);
+                LODWORD(v20) = 0;
+                HIDWORD(v20) = floorf(v15->fov_y + 0.5f);
+                v37 = v20 / x;
+                v37 = (unsigned __int64)(v12->scale * v20 / x) >> 16;
+              }
+              //HIWORD(v22) = HIWORD(x);
+              //LOWORD(v22) = 0;
+              v15->_screenspace_y_scaler_packedfloat = v37;
+              v15->field_1E = v30;
+              v15->world_x = a1;
+              v15->world_y = a2;
+              v15->world_z = a3;
+              v15->uScreenSpaceX = a5;
+              v15->uScreenSpaceY = a6;
+              //v23 = 8 * uDecorationID;
+              //LOBYTE(v23) = PID(OBJECT_Decoration,uDecorationID);
+
+              //v15->sZValue = v22 + v23;
+              v15->actual_z = HIWORD(x);
+              v15->object_pid = PID(OBJECT_Decoration,uDecorationID);
+
+              v15->uTintColor = 0;
+              v15->pSpriteFrame = v12;
+          }
+        }
+}
+//----- (0043F953) --------------------------------------------------------
+void PrepareBspRenderList_BLV()
+{
+  pBspRenderer->num_faces = 0;
+
+  if (pBLVRenderParams->uPartySectorID)
+  {
+    pBspRenderer->nodes[0].uSectorID = pBLVRenderParams->uPartySectorID;
+    pBspRenderer->nodes[0].uViewportW = pBLVRenderParams->uViewportW;
+    pBspRenderer->nodes[0].uViewportZ = pBLVRenderParams->uViewportZ;
+    pBspRenderer->nodes[0].uViewportY = pBLVRenderParams->uViewportY;
+    pBspRenderer->nodes[0].uViewportX = pBLVRenderParams->uViewportX;
+    pBspRenderer->nodes[0].field_C.GetViewportData(pBLVRenderParams->uViewportX, pBLVRenderParams->uViewportY,
+                                           pBLVRenderParams->uViewportZ, pBLVRenderParams->uViewportW);
+    pBspRenderer->nodes[0].uFaceID = -1;
+    pBspRenderer->nodes[0].viewing_portal_id = -1;
+    pBspRenderer->num_nodes = 1;
+    AddBspNodeToRenderList(0);
+  }
+
+  pBspRenderer->MakeVisibleSectorList();
+}
+
+//----- (0043F9E1) --------------------------------------------------------
+void BspRenderer_stru2::GetViewportData(__int16 x, int y, __int16 z, int w)
+{
+  _viewport_space_y = y;
+  _viewport_space_w = w;
+
+  for (uint i = 0; i < 480; ++i)
+  {
+    if ( i < y || i > w )
+    {
+      viewport_left_side[i] = 640;
+      viewport_right_side[i] = -1;
+    }
+    else
+    {
+      viewport_left_side[i] = x;
+      viewport_right_side[i] = z;
+    } 
+  }
+}
+//----- (0048653D) --------------------------------------------------------
+int stru149::_48653D(int a2, int a3, int a4, int a5, int a6, int a7)//portal frustum culling
+{
+  stru149 *v7; // esi@1
+  int v8; // edi@1
+  int v9; // eax@1
+  //int v10; // edx@1
+  //int v11; // ecx@1
+  int v12; // eax@1
+  int v13; // ebx@2
+  int v14; // ecx@2
+  int v15; // eax@2
+  int v16; // ST14_4@3
+  int v17; // ST10_4@3
+  int v18; // eax@5
+  int v19; // ST10_4@6
+  int v20; // eax@8
+  int v21; // ST10_4@9
+  int v22; // eax@10
+  int v23; // ecx@10
+  int v24; // eax@10
+  int result; // eax@10
+  //int v26; // [sp+14h] [bp-14h]@1
+  int v27; // [sp+18h] [bp-10h]@1
+  int v28; // [sp+1Ch] [bp-Ch]@1
+  int v29; // [sp+24h] [bp-4h]@1
+  int v30; // [sp+30h] [bp+8h]@10
+  int v31; // [sp+3Ch] [bp+14h]@10
+
+  v7 = this;
+  v8 = stru_5C6E00->Cos(pBLVRenderParams->sPartyRotY);
+  v29 = stru_5C6E00->Sin(pBLVRenderParams->sPartyRotY);
+  v28 = stru_5C6E00->Cos(pBLVRenderParams->sPartyRotX);
+  v9 = stru_5C6E00->Sin(pBLVRenderParams->sPartyRotX);
+  //v11 = -pBLVRenderParams->vPartyPos.y;
+  //v26 = -pBLVRenderParams->vPartyPos.x;
+  v27 = v9;
+  v12 = -pBLVRenderParams->vPartyPos.z;
+  if ( pBLVRenderParams->sPartyRotX )
+  {
+    v16 = v8 * -pBLVRenderParams->vPartyPos.x + v29 * -pBLVRenderParams->vPartyPos.y;
+    v13 = v28;
+    v17 = -65536 * pBLVRenderParams->vPartyPos.z;
+    v7->field_0_party_dir_x = ((unsigned __int64)(v16 * (signed __int64)v28) >> 16)
+                + ((unsigned __int64)(-65536 * pBLVRenderParams->vPartyPos.z * (signed __int64)v27) >> 16);
+    v7->field_4_party_dir_y = v8 * -pBLVRenderParams->vPartyPos.y - v29 * -pBLVRenderParams->vPartyPos.x;
+    v14 = v27;
+    v15 = ((unsigned __int64)(v17 * (signed __int64)v28) >> 16) - ((unsigned __int64)(v16 * (signed __int64)v27) >> 16);
+  }
+  else
+  {
+    v7->field_0_party_dir_x = v8 * -pBLVRenderParams->vPartyPos.x + v29 * -pBLVRenderParams->vPartyPos.y;
+    v13 = v28;
+    v7->field_4_party_dir_y = v8 * -pBLVRenderParams->vPartyPos.y - v29 * -pBLVRenderParams->vPartyPos.x;
+    v14 = v27;
+    v15 = v12 << 16;
+  }
+  v7->field_8 = v15;
+  if ( pBLVRenderParams->sPartyRotX )
+  {
+    v19 = ((unsigned __int64)(a2 * (signed __int64)v8) >> 16) + ((unsigned __int64)(a3 * (signed __int64)v29) >> 16);
+    v7->field_C = ((unsigned __int64)(v19 * (signed __int64)v13) >> 16)
+                + ((unsigned __int64)(a4 * (signed __int64)v14) >> 16);
+    v7->field_10 = ((unsigned __int64)(a3 * (signed __int64)v8) >> 16)
+                 - ((unsigned __int64)(a2 * (signed __int64)v29) >> 16);
+    v18 = ((unsigned __int64)(a4 * (signed __int64)v13) >> 16) - ((unsigned __int64)(v19 * (signed __int64)v14) >> 16);
+  }
+  else
+  {
+    v7->field_C = ((unsigned __int64)(a2 * (signed __int64)v8) >> 16)
+                + ((unsigned __int64)(a3 * (signed __int64)v29) >> 16);
+    v7->field_10 = ((unsigned __int64)(a3 * (signed __int64)v8) >> 16)
+                 - ((unsigned __int64)(a2 * (signed __int64)v29) >> 16);
+    v18 = a4;
+  }
+  v7->field_14 = v18;
+  if ( pBLVRenderParams->sPartyRotX )
+  {
+    v21 = ((unsigned __int64)(a5 * (signed __int64)v8) >> 16) + ((unsigned __int64)(a6 * (signed __int64)v29) >> 16);
+    v7->field_18 = ((unsigned __int64)(v21 * (signed __int64)v13) >> 16)
+                 + ((unsigned __int64)(a7 * (signed __int64)v14) >> 16);
+    v7->field_1C = ((unsigned __int64)(a6 * (signed __int64)v8) >> 16)
+                 - ((unsigned __int64)(a5 * (signed __int64)v29) >> 16);
+    v20 = ((unsigned __int64)(a7 * (signed __int64)v13) >> 16) - ((unsigned __int64)(v21 * (signed __int64)v14) >> 16);
+  }
+  else
+  {
+    v7->field_18 = ((unsigned __int64)(a5 * (signed __int64)v8) >> 16)
+                 + ((unsigned __int64)(a6 * (signed __int64)v29) >> 16);
+    v7->field_1C = ((unsigned __int64)(a6 * (signed __int64)v8) >> 16)
+                 - ((unsigned __int64)(a5 * (signed __int64)v29) >> 16);
+    v20 = a7;
+  }
+  v7->field_18 = -v7->field_18;
+  v7->field_1C = -v7->field_1C;
+  v7->field_20 = v20;
+  v22 = v7->field_C;
+  v7->field_20 = -v7->field_20;
+  v23 = ((unsigned __int64)(v22 * (signed __int64)v7->field_0_party_dir_x) >> 16)
+      + ((unsigned __int64)(v7->field_10 * (signed __int64)v7->field_4_party_dir_y) >> 16)
+      + ((unsigned __int64)(v7->field_14 * (signed __int64)v7->field_8) >> 16);
+  v30 = v7->field_18;
+  v24 = v7->field_0_party_dir_x;
+  v7->field_24 = v23;
+  v31 = (unsigned __int64)(v30 * (signed __int64)v24) >> 16;
+  result = (unsigned __int64)(v7->field_1C * (signed __int64)v7->field_4_party_dir_y) >> 16;
+  v7->field_28 = v31 + result + ((unsigned __int64)(v7->field_20 * (signed __int64)v7->field_8) >> 16);
+  return result;
+}
+//----- (00407A1C) --------------------------------------------------------
+bool __fastcall sub_407A1C(int x, int z, int y, Vec3_int_ v)
+{
+  unsigned int v4; // esi@1
+  Vec3_int_ v5; // ST08_12@2
+  int v6; // edi@2
+  int v7; // ebx@2
+  int v8; // esi@2
+  signed int v9; // ecx@2
+  int v10; // eax@2
+  int v11; // ecx@4
+  int v12; // eax@4
+  int v13; // ebx@4
+  int v14; // edx@6
+  char *v15; // edi@16
+  ODMFace *v16; // esi@19
+  int v17; // ST34_4@25
+  int v18; // ST38_4@25
+  int v19; // eax@25
+  char v20; // zf@25
+  int v21; // ebx@25
+  int v22; // eax@26
+  signed int v23; // edi@26
+  int v24; // ST34_4@30
+  signed __int64 v25; // qtt@31
+  int v26; // eax@31
+  Vec3_int_ v27; // ST08_12@37
+  Vec3_int_ v28; // ST08_12@37
+  int v29; // edi@37
+  int v30; // ebx@37
+  int v31; // esi@37
+  signed int v32; // ecx@37
+  int v33; // eax@37
+  int v34; // ecx@39
+  int v35; // eax@39
+  int v36; // ebx@39
+  int v37; // edx@41
+  char *v38; // edi@51
+  ODMFace *v39; // esi@54
+  int v40; // ebx@60
+  int v41; // eax@61
+  signed int v42; // edi@61
+  signed __int64 v43; // qtt@66
+  int v44; // eax@66
+  Vec3_int_ v45; // ST08_12@73
+  int v46; // edi@73
+  int v47; // ebx@73
+  int v48; // esi@73
+  signed int v49; // ecx@73
+  int v50; // eax@73
+  int v51; // edx@75
+  int v52; // ecx@75
+  int v53; // eax@75
+  int v54; // ebx@75
+  int v55; // edi@77
+  int v56; // ecx@77
+  int v57; // eax@81
+  int v58; // esi@81
+  int v59; // eax@90
+  BLVSector *v60; // edx@90
+  int v61; // ecx@90
+  BLVFace *v62; // esi@91
+  int v63; // ST34_4@98
+  int v64; // ST30_4@98
+  int v65; // eax@98
+  int v66; // ebx@98
+  int v67; // eax@99
+  signed int v68; // edi@99
+  int v69; // ST2C_4@103
+  signed __int64 v70; // qtt@104
+  int v71; // eax@104
+  Vec3_int_ v72; // ST08_12@111
+  Vec3_int_ v73; // ST08_12@111
+  int v74; // edi@111
+  int v75; // ebx@111
+  int v76; // esi@111
+  signed int v77; // ecx@111
+  int v78; // eax@111
+  int v79; // edx@113
+  int v80; // ecx@113
+  int v81; // eax@113
+  int v82; // ebx@113
+  int v83; // edi@115
+  int v84; // ecx@115
+  int v85; // eax@119
+  int v86; // esi@119
+  int v87; // ecx@128
+  BLVSector *v88; // eax@128
+  int v89; // ecx@128
+  BLVFace *v90; // esi@129
+  int v91; // ebx@136
+  int v92; // eax@137
+  signed int v93; // edi@137
+  signed __int64 v94; // qtt@142
+  int v95; // eax@142
+  Vec3_int_ v97; // [sp-18h] [bp-94h]@1
+  int v98; // [sp-Ch] [bp-88h]@88
+  int v99; // [sp-Ch] [bp-88h]@126
+  int v100; // [sp-8h] [bp-84h]@88
+  int v101; // [sp-8h] [bp-84h]@126
+  int v102; // [sp-4h] [bp-80h]@88
+  int v103; // [sp-4h] [bp-80h]@126
+  int v104; // [sp+Ch] [bp-70h]@13
+  int v105; // [sp+Ch] [bp-70h]@48
+  int v106; // [sp+10h] [bp-6Ch]@18
+  int v107; // [sp+10h] [bp-6Ch]@98
+  int v108; // [sp+10h] [bp-6Ch]@104
+  int v109; // [sp+18h] [bp-64h]@25
+  int v110; // [sp+18h] [bp-64h]@31
+  int i; // [sp+18h] [bp-64h]@90
+  int v112; // [sp+18h] [bp-64h]@128
+  signed int v113; // [sp+20h] [bp-5Ch]@1
+  signed int v114; // [sp+24h] [bp-58h]@1
+  unsigned __int64 a4; // [sp+28h] [bp-54h]@1
+  unsigned int a4_8; // [sp+30h] [bp-4Ch]@1
+  int v117; // [sp+34h] [bp-48h]@4
+  int v118; // [sp+34h] [bp-48h]@39
+  int v119; // [sp+34h] [bp-48h]@75
+  int v120; // [sp+34h] [bp-48h]@113
+  int v121; // [sp+38h] [bp-44h]@4
+  int v122; // [sp+38h] [bp-44h]@39
+  int v123; // [sp+38h] [bp-44h]@76
+  int v124; // [sp+38h] [bp-44h]@114
+  int v125; // [sp+3Ch] [bp-40h]@4
+  int v126; // [sp+3Ch] [bp-40h]@39
+  int v127; // [sp+3Ch] [bp-40h]@77
+  int v128; // [sp+3Ch] [bp-40h]@115
+  int v129; // [sp+40h] [bp-3Ch]@11
+  int v130; // [sp+40h] [bp-3Ch]@46
+  int v131; // [sp+40h] [bp-3Ch]@78
+  int v132; // [sp+40h] [bp-3Ch]@116
+  int v133; // [sp+44h] [bp-38h]@10
+  int v134; // [sp+44h] [bp-38h]@45
+  int v135; // [sp+44h] [bp-38h]@81
+  int v136; // [sp+44h] [bp-38h]@119
+  int v137; // [sp+48h] [bp-34h]@7
+  int v138; // [sp+48h] [bp-34h]@42
+  int v139; // [sp+48h] [bp-34h]@82
+  int v140; // [sp+48h] [bp-34h]@120
+  int v141; // [sp+4Ch] [bp-30h]@6
+  int v142; // [sp+4Ch] [bp-30h]@41
+  int v143; // [sp+4Ch] [bp-30h]@75
+  int v144; // [sp+4Ch] [bp-30h]@113
+  int v145; // [sp+50h] [bp-2Ch]@5
+  int v146; // [sp+50h] [bp-2Ch]@40
+  int v147; // [sp+50h] [bp-2Ch]@75
+  int v148; // [sp+50h] [bp-2Ch]@113
+  int v149; // [sp+54h] [bp-28h]@4
+  int v150; // [sp+54h] [bp-28h]@39
+  int v151; // [sp+54h] [bp-28h]@75
+  int v152; // [sp+54h] [bp-28h]@113
+  int sDepth; // [sp+58h] [bp-24h]@17
+  int sDeptha; // [sp+58h] [bp-24h]@52
+  int sDepthb; // [sp+58h] [bp-24h]@90
+  char *a5; // [sp+5Ch] [bp-20h]@16
+  char *a5a; // [sp+5Ch] [bp-20h]@51
+  signed int a5b; // [sp+5Ch] [bp-20h]@83
+  signed int a5c; // [sp+5Ch] [bp-20h]@121
+  signed int v160; // [sp+60h] [bp-1Ch]@12
+  signed int v161; // [sp+60h] [bp-1Ch]@47
+  int v162; // [sp+60h] [bp-1Ch]@128
+  int v163; // [sp+64h] [bp-18h]@2
+  int outx; // [sp+68h] [bp-14h]@2
+  int outy; // [sp+6Ch] [bp-10h]@2
+  int outz; // [sp+70h] [bp-Ch]@2
+  Vec3_int_ pOut; // [sp+74h] [bp-8h]@2
+  int ya; // [sp+84h] [bp+8h]@60
+  int yb; // [sp+84h] [bp+8h]@136
+  int ve; // [sp+88h] [bp+Ch]@60
+  int va; // [sp+88h] [bp+Ch]@60
+  int vb; // [sp+88h] [bp+Ch]@66
+  int vf; // [sp+88h] [bp+Ch]@136
+  int vc; // [sp+88h] [bp+Ch]@136
+  int vd; // [sp+88h] [bp+Ch]@142
+  int v_4; // [sp+8Ch] [bp+10h]@60
+  int v_4a; // [sp+8Ch] [bp+10h]@65
+  int v_4b; // [sp+8Ch] [bp+10h]@136
+  int v_4c; // [sp+8Ch] [bp+10h]@141
+  int v_8; // [sp+90h] [bp+14h]@53
+
+  a4 = __PAIR__(z, x);
+  v4 = stru_5C6E00->Atan2(v.x - x, v.y - z);
+  v114 = 0;
+  v97.z = y;
+  v113 = 0;
+  a4_8 = v4;
+  *(_QWORD *)&v97.x = a4;
+  if ( uCurrentlyLoadedLevelType != LEVEL_Outdoor)
+  {
+    Vec3_int_::Rotate(32, stru_5C6E00->uIntegerHalfPi + v4, 0, v97, &pOut.x, &pOut.y, &outz);
+    v45.z = v.z;
+    *(_QWORD *)&v45.x = *(_QWORD *)&v;
+    Vec3_int_::Rotate(32, stru_5C6E00->uIntegerHalfPi + v4, 0, v45, &outx, &outy, &v163);
+    v46 = outy - pOut.y;
+    v47 = v163 - outz;
+    v48 = outx - pOut.x;
+    v49 = integer_sqrt(v48 * v48 + v46 * v46 + v47 * v47);
+    v50 = 65536;
+    if ( v49 )
+      v50 = 65536 / v49;
+    v51 = outx;
+    v143 = v48 * v50;
+    v52 = v46 * v50;
+    v53 = v47 * v50;
+    v54 = pOut.x;
+    v147 = v52;
+    v151 = v53;
+    v119 = pOut.x;
+    if ( pOut.x < outx )
+    {
+      v123 = outx;
+    }
+    else
+    {
+      v119 = outx;
+      v123 = pOut.x;
+    }
+    v55 = pOut.y;
+    v56 = outy;
+    v127 = pOut.y;
+    if ( pOut.y < outy )
+    {
+      v131 = outy;
+    }
+    else
+    {
+      v127 = outy;
+      v131 = pOut.y;
+    }
+    v57 = v163;
+    v58 = outz;
+    v135 = outz;
+    if ( outz < v163 )
+    {
+      v139 = v163;
+    }
+    else
+    {
+      v135 = v163;
+      v139 = outz;
+    }
+    a5b = 0;
+    while ( !v114 )
+    {
+      if ( a5b )
+      {
+        v102 = v58;
+        v100 = v55;
+        v98 = v54;
+      }
+      else
+      {
+        v102 = v57;
+        v100 = v56;
+        v98 = v51;
+      }
+      v59 = pIndoor->GetSector(v98, v100, v102);
+      v60 = pIndoor->pSectors;
+      v61 = 116 * v59;
+      sDepthb = 0;
+      for ( i = 116 * v59;
+            sDepthb < *(__int16 *)((char *)&pIndoor->pSectors->uNumWalls + v61)
+                    + 2 * *(__int16 *)((char *)&pIndoor->pSectors->uNumFloors + v61);
+            ++sDepthb )
+      {
+        v62 = &pIndoor->pFaces[(*(unsigned __int16 **)((char *)&v60->pWalls + v61))[sDepthb]];
+        if ( v62->Portal()
+          || v119 > v62->pBounding.x2
+          || v123 < v62->pBounding.x1
+          || v127 > v62->pBounding.y2
+          || v131 < v62->pBounding.y1
+          || v135 > v62->pBounding.z2
+          || v139 < v62->pBounding.z1
+          || (v63 = (unsigned __int64)(v143 * (signed __int64)v62->pFacePlane_old.vNormal.x) >> 16,
+              v64 = (unsigned __int64)(v151 * (signed __int64)v62->pFacePlane_old.vNormal.z) >> 16,
+              v65 = (unsigned __int64)(v147 * (signed __int64)v62->pFacePlane_old.vNormal.y) >> 16,
+              v20 = v63 + v64 + v65 == 0,
+              v66 = v63 + v64 + v65,
+              v107 = v63 + v64 + v65,
+              v20) )
+          goto LABEL_107;
+        v67 = outz * v62->pFacePlane_old.vNormal.z;
+        v68 = -(v62->pFacePlane_old.dist
+              + v67
+              + pOut.y * v62->pFacePlane_old.vNormal.y
+              + pOut.x * v62->pFacePlane_old.vNormal.x);
+        if ( v66 <= 0 )
+        {
+          if ( v62->pFacePlane_old.dist
+             + v67
+             + pOut.y * v62->pFacePlane_old.vNormal.y
+             + pOut.x * v62->pFacePlane_old.vNormal.x < 0 )
+            goto LABEL_107;
+        }
+        else
+        {
+          if ( v62->pFacePlane_old.dist
+             + v67
+             + pOut.y * v62->pFacePlane_old.vNormal.y
+             + pOut.x * v62->pFacePlane_old.vNormal.x > 0 )
+            goto LABEL_107;
+        }
+        v69 = abs(-(v62->pFacePlane_old.dist
+                  + v67
+                  + pOut.y * v62->pFacePlane_old.vNormal.y
+                  + pOut.x * v62->pFacePlane_old.vNormal.x)) >> 14;
+        if ( v69 <= abs(v66) )
+        {
+          LODWORD(v70) = v68 << 16;
+          HIDWORD(v70) = v68 >> 16;
+          v71 = v70 / v107;
+          v108 = v70 / v107;
+          if ( v71 >= 0 )
+          {
+            if ( sub_4075DB(
+                   pOut.x + ((signed int)(((unsigned __int64)(v108 * (signed __int64)v143) >> 16) + 32768) >> 16),
+                   pOut.y + ((signed int)(((unsigned __int64)(v108 * (signed __int64)v147) >> 16) + 32768) >> 16),
+                   outz + ((signed int)(((unsigned __int64)(v108 * (signed __int64)v151) >> 16) + 32768) >> 16),
+                   v62) )
+            {
+              v114 = 1;
+              break;
+            }
+          }
+        }
+        v61 = i;
+LABEL_107:
+        v60 = pIndoor->pSectors;
+      }
+      ++a5b;
+      if ( a5b >= 2 )
+        break;
+      v57 = v163;
+      v56 = outy;
+      v51 = outx;
+      v58 = outz;
+      v55 = pOut.y;
+      v54 = pOut.x;
+    }
+    v72.z = y;
+    *(_QWORD *)&v72.x = a4;
+    Vec3_int_::Rotate(32, a4_8 - stru_5C6E00->uIntegerHalfPi, 0, v72, &pOut.x, &pOut.y, &outz);
+    v73.z = v.z;
+    *(_QWORD *)&v73.x = *(_QWORD *)&v;
+    Vec3_int_::Rotate(32, a4_8 - stru_5C6E00->uIntegerHalfPi, 0, v73, &outx, &outy, &v163);
+    v74 = outy - pOut.y;
+    v75 = v163 - outz;
+    v76 = outx - pOut.x;
+    v77 = integer_sqrt(v76 * v76 + v74 * v74 + v75 * v75);
+    v78 = 65536;
+    if ( v77 )
+      v78 = 65536 / v77;
+    v79 = outx;
+    v144 = v76 * v78;
+    v80 = v74 * v78;
+    v81 = v75 * v78;
+    v82 = pOut.x;
+    v148 = v80;
+    v152 = v81;
+    v120 = pOut.x;
+    if ( pOut.x < outx )
+    {
+      v124 = outx;
+    }
+    else
+    {
+      v120 = outx;
+      v124 = pOut.x;
+    }
+    v83 = pOut.y;
+    v84 = outy;
+    v128 = pOut.y;
+    if ( pOut.y < outy )
+    {
+      v132 = outy;
+    }
+    else
+    {
+      v128 = outy;
+      v132 = pOut.y;
+    }
+    v85 = v163;
+    v86 = outz;
+    v136 = outz;
+    if ( outz < v163 )
+    {
+      v140 = v163;
+    }
+    else
+    {
+      v136 = v163;
+      v140 = outz;
+    }
+    a5c = 0;
+    while ( 1 )
+    {
+      if ( v113 )
+        return !v114 || !v113;
+      if ( a5c )
+      {
+        v103 = v86;
+        v101 = v83;
+        v99 = v82;
+      }
+      else
+      {
+        v103 = v85;
+        v101 = v84;
+        v99 = v79;
+      }
+      v87 = pIndoor->GetSector(v99, v101, v103);
+      v88 = pIndoor->pSectors;
+      v89 = 116 * v87;
+      v162 = 0;
+      v112 = v89;
+      if ( *(__int16 *)((char *)&pIndoor->pSectors->uNumWalls + v89)
+         + 2 * *(__int16 *)((char *)&pIndoor->pSectors->uNumFloors + v89) > 0 )
+        break;
+LABEL_148:
+      ++a5c;
+      if ( a5c >= 2 )
+        return !v114 || !v113;
+      v85 = v163;
+      v84 = outy;
+      v79 = outx;
+      v86 = outz;
+      v83 = pOut.y;
+      v82 = pOut.x;
+    }
+    while ( 1 )
+    {
+      v90 = &pIndoor->pFaces[(*(unsigned __int16 **)((char *)&v88->pWalls + v89))[v162]];
+      if ( v90->Portal()
+        || v120 > v90->pBounding.x2
+        || v124 < v90->pBounding.x1
+        || v128 > v90->pBounding.y2
+        || v132 < v90->pBounding.y1
+        || v136 > v90->pBounding.z2
+        || v140 < v90->pBounding.z1
+        || (yb = (unsigned __int64)(v144 * (signed __int64)v90->pFacePlane_old.vNormal.x) >> 16,
+            v_4b = (unsigned __int64)(v148 * (signed __int64)v90->pFacePlane_old.vNormal.y) >> 16,
+            vf = (unsigned __int64)(v152 * (signed __int64)v90->pFacePlane_old.vNormal.z) >> 16,
+            v20 = yb + vf + v_4b == 0,
+            v91 = yb + vf + v_4b,
+            vc = yb + vf + v_4b,
+            v20) )
+        goto LABEL_145;
+      v92 = outz * v90->pFacePlane_old.vNormal.z;
+      v93 = -(v90->pFacePlane_old.dist
+            + v92
+            + pOut.y * v90->pFacePlane_old.vNormal.y
+            + pOut.x * v90->pFacePlane_old.vNormal.x);
+      if ( v91 <= 0 )
+      {
+        if ( v90->pFacePlane_old.dist
+           + v92
+           + pOut.y * v90->pFacePlane_old.vNormal.y
+           + pOut.x * v90->pFacePlane_old.vNormal.x < 0 )
+          goto LABEL_145;
+      }
+      else
+      {
+        if ( v90->pFacePlane_old.dist
+           + v92
+           + pOut.y * v90->pFacePlane_old.vNormal.y
+           + pOut.x * v90->pFacePlane_old.vNormal.x > 0 )
+          goto LABEL_145;
+      }
+      v_4c = abs(-(v90->pFacePlane_old.dist
+                 + v92
+                 + pOut.y * v90->pFacePlane_old.vNormal.y
+                 + pOut.x * v90->pFacePlane_old.vNormal.x)) >> 14;
+      if ( v_4c <= abs(v91) )
+      {
+        LODWORD(v94) = v93 << 16;
+        HIDWORD(v94) = v93 >> 16;
+        v95 = v94 / vc;
+        vd = v94 / vc;
+        if ( v95 >= 0 )
+        {
+          if ( sub_4075DB(
+                 pOut.x + ((signed int)(((unsigned __int64)(vd * (signed __int64)v144) >> 16) + 32768) >> 16),
+                 pOut.y + ((signed int)(((unsigned __int64)(vd * (signed __int64)v148) >> 16) + 32768) >> 16),
+                 outz + ((signed int)(((unsigned __int64)(vd * (signed __int64)v152) >> 16) + 32768) >> 16),
+                 v90) )
+          {
+            v113 = 1;
+            goto LABEL_148;
+          }
+        }
+      }
+      v89 = v112;
+LABEL_145:
+      v88 = pIndoor->pSectors;
+      ++v162;
+      if ( v162 >= *(__int16 *)((char *)&pIndoor->pSectors->uNumWalls + v89)
+                 + 2 * *(__int16 *)((char *)&pIndoor->pSectors->uNumFloors + v89) )
+        goto LABEL_148;
+    }
+  }
+  Vec3_int_::Rotate(32, stru_5C6E00->uIntegerHalfPi + v4, 0, v97, &pOut.x, &pOut.y, &outz);
+  v5.z = v.z;
+  *(_QWORD *)&v5.x = *(_QWORD *)&v;
+  Vec3_int_::Rotate(32, stru_5C6E00->uIntegerHalfPi + v4, 0, v5, &outx, &outy, &v163);
+  v6 = outy - pOut.y;
+  v7 = v163 - outz;
+  v8 = outx - pOut.x;
+  v9 = integer_sqrt(v8 * v8 + v6 * v6 + v7 * v7);
+  v10 = 65536;
+  if ( v9 )
+    v10 = 65536 / v9;
+  v125 = v8 * v10;
+  v11 = v10;
+  v12 = v7 * v10;
+  v13 = pOut.x;
+  v117 = v12;
+  v121 = v6 * v11;
+  v149 = pOut.x;
+  if ( pOut.x < outx )
+  {
+    v145 = outx;
+  }
+  else
+  {
+    v149 = outx;
+    v145 = pOut.x;
+  }
+  v14 = outy;
+  v141 = pOut.y;
+  if ( pOut.y < outy )
+  {
+    v137 = outy;
+  }
+  else
+  {
+    v141 = outy;
+    v137 = pOut.y;
+  }
+  v133 = outz;
+  if ( outz < v163 )
+  {
+    v129 = v163;
+  }
+  else
+  {
+    v133 = v163;
+    v129 = outz;
+  }
+  v160 = 0;
+  if ( (signed int)pOutdoor->uNumBModels > 0 )
+  {
+    v104 = 0;
+    while ( 1 )
+    {
+      v15 = (char *)&pOutdoor->pBModels[v104].pVertices;
+      a5 = (char *)&pOutdoor->pBModels[v104].pVertices;
+      if ( sub_4088E9(v13, pOut.y, outx, v14, pOutdoor->pBModels[v104].vPosition.x, pOutdoor->pBModels[v104].vPosition.y) <= pOutdoor->pBModels[v104].sBoundingRadius + 128 )
+      {
+        sDepth = 0;
+        if ( *((int *)v15 + 2) > 0 )
+          break;
+      }
+LABEL_36:
+      ++v160;
+      ++v104;
+      if ( v160 >= (signed int)pOutdoor->uNumBModels )
+        goto LABEL_37;
+      v14 = outy;
+      v13 = pOut.x;
+    }
+    v106 = 0;
+    while ( 1 )
+    {
+      v16 = (ODMFace *)(v106 + *((int *)a5 + 4));
+      if ( v149 > v16->pBoundingBox.x2
+        || v145 < v16->pBoundingBox.x1
+        || v141 > v16->pBoundingBox.y2
+        || v137 < v16->pBoundingBox.y1
+        || v133 > v16->pBoundingBox.z2
+        || v129 < v16->pBoundingBox.z1
+        || (v17 = (unsigned __int64)(v125 * (signed __int64)v16->pFacePlane.vNormal.x) >> 16,
+            v18 = (unsigned __int64)(v121 * (signed __int64)v16->pFacePlane.vNormal.y) >> 16,
+            v19 = (unsigned __int64)(v117 * (signed __int64)v16->pFacePlane.vNormal.z) >> 16,
+            v20 = v17 + v18 + v19 == 0,
+            v21 = v17 + v18 + v19,
+            v109 = v17 + v18 + v19,
+            v20) )
+        goto LABEL_33;
+      v22 = pOut.y * v16->pFacePlane.vNormal.y;
+      v23 = -(v16->pFacePlane.dist + v22 + outz * v16->pFacePlane.vNormal.z + pOut.x * v16->pFacePlane.vNormal.x);
+      if ( v21 <= 0 )
+      {
+        if ( v16->pFacePlane.dist + v22 + outz * v16->pFacePlane.vNormal.z + pOut.x * v16->pFacePlane.vNormal.x < 0 )
+          goto LABEL_33;
+      }
+      else
+      {
+        if ( v16->pFacePlane.dist + v22 + outz * v16->pFacePlane.vNormal.z + pOut.x * v16->pFacePlane.vNormal.x > 0 )
+          goto LABEL_33;
+      }
+      v24 = abs(-(v16->pFacePlane.dist + v22 + outz * v16->pFacePlane.vNormal.z + pOut.x * v16->pFacePlane.vNormal.x)) >> 14;
+      if ( v24 <= abs(v21) )
+      {
+        LODWORD(v25) = v23 << 16;
+        HIDWORD(v25) = v23 >> 16;
+        v26 = v25 / v109;
+        v110 = v25 / v109;
+        if ( v26 >= 0 )
+        {
+          if ( sub_4077F1(
+                 pOut.x + ((signed int)(((unsigned __int64)(v110 * (signed __int64)v125) >> 16) + 32768) >> 16),
+                 pOut.y + ((signed int)(((unsigned __int64)(v110 * (signed __int64)v121) >> 16) + 32768) >> 16),
+                 outz + ((signed int)(((unsigned __int64)(v110 * (signed __int64)v117) >> 16) + 32768) >> 16),
+                 v16,
+                 (BSPVertexBuffer *)a5) )
+          {
+            v114 = 1;
+            goto LABEL_36;
+          }
+        }
+      }
+LABEL_33:
+      ++sDepth;
+      v106 += 308;
+      if ( sDepth >= *((int *)a5 + 2) )
+        goto LABEL_36;
+    }
+  }
+LABEL_37:
+  v27.z = y;
+  *(_QWORD *)&v27.x = a4;
+  Vec3_int_::Rotate(32, a4_8 - stru_5C6E00->uIntegerHalfPi, 0, v27, &pOut.x, &pOut.y, &outz);
+  v28.z = v.z;
+  *(_QWORD *)&v28.x = *(_QWORD *)&v;
+  Vec3_int_::Rotate(32, a4_8 - stru_5C6E00->uIntegerHalfPi, 0, v28, &outx, &outy, &v163);
+  v29 = outy - pOut.y;
+  v30 = v163 - outz;
+  v31 = outx - pOut.x;
+  v32 = integer_sqrt(v31 * v31 + v29 * v29 + v30 * v30);
+  v33 = 65536;
+  if ( v32 )
+    v33 = 65536 / v32;
+  v126 = v31 * v33;
+  v34 = v33;
+  v35 = v30 * v33;
+  v36 = pOut.x;
+  v118 = v35;
+  v122 = v29 * v34;
+  v150 = pOut.x;
+  if ( pOut.x < outx )
+  {
+    v146 = outx;
+  }
+  else
+  {
+    v150 = outx;
+    v146 = pOut.x;
+  }
+  v37 = outy;
+  v142 = pOut.y;
+  if ( pOut.y < outy )
+  {
+    v138 = outy;
+  }
+  else
+  {
+    v142 = outy;
+    v138 = pOut.y;
+  }
+  v134 = outz;
+  if ( outz < v163 )
+  {
+    v130 = v163;
+  }
+  else
+  {
+    v134 = v163;
+    v130 = outz;
+  }
+  v161 = 0;
+  if ( (signed int)pOutdoor->uNumBModels > 0 )
+  {
+    v105 = 0;
+    while ( 1 )
+    {
+      v38 = (char *)&pOutdoor->pBModels[v105].pVertices;
+      a5a = (char *)&pOutdoor->pBModels[v105].pVertices;
+      if ( sub_4088E9(v36, pOut.y, outx, v37, pOutdoor->pBModels[v105].vPosition.x, pOutdoor->pBModels[v105].vPosition.y) <= pOutdoor->pBModels[v105].sBoundingRadius + 128 )
+      {
+        sDeptha = 0;
+        if ( *((int *)v38 + 2) > 0 )
+          break;
+      }
+LABEL_71:
+      ++v161;
+      ++v105;
+      if ( v161 >= (signed int)pOutdoor->uNumBModels )
+        return !v114 || !v113;
+      v37 = outy;
+      v36 = pOut.x;
+    }
+    v_8 = 0;
+    while ( 1 )
+    {
+      v39 = (ODMFace *)(v_8 + *((int *)a5a + 4));
+      if ( v150 > v39->pBoundingBox.x2
+        || v146 < v39->pBoundingBox.x1
+        || v142 > v39->pBoundingBox.y2
+        || v138 < v39->pBoundingBox.y1
+        || v134 > v39->pBoundingBox.z2
+        || v130 < v39->pBoundingBox.z1
+        || (ya = (unsigned __int64)(v126 * (signed __int64)v39->pFacePlane.vNormal.x) >> 16,
+            ve = (unsigned __int64)(v122 * (signed __int64)v39->pFacePlane.vNormal.y) >> 16,
+            v_4 = (unsigned __int64)(v118 * (signed __int64)v39->pFacePlane.vNormal.z) >> 16,
+            v20 = ya + ve + v_4 == 0,
+            v40 = ya + ve + v_4,
+            va = ya + ve + v_4,
+            v20) )
+        goto LABEL_68;
+      v41 = pOut.y * v39->pFacePlane.vNormal.y;
+      v42 = -(v39->pFacePlane.dist + v41 + outz * v39->pFacePlane.vNormal.z + pOut.x * v39->pFacePlane.vNormal.x);
+      if ( v40 <= 0 )
+      {
+        if ( v39->pFacePlane.dist + v41 + outz * v39->pFacePlane.vNormal.z + pOut.x * v39->pFacePlane.vNormal.x < 0 )
+          goto LABEL_68;
+      }
+      else
+      {
+        if ( v39->pFacePlane.dist + v41 + outz * v39->pFacePlane.vNormal.z + pOut.x * v39->pFacePlane.vNormal.x > 0 )
+          goto LABEL_68;
+      }
+      v_4a = abs(-(v39->pFacePlane.dist + v41 + outz * v39->pFacePlane.vNormal.z + pOut.x * v39->pFacePlane.vNormal.x)) >> 14;
+      if ( v_4a <= abs(v40) )
+      {
+        LODWORD(v43) = v42 << 16;
+        HIDWORD(v43) = v42 >> 16;
+        v44 = v43 / va;
+        vb = v43 / va;
+        if ( v44 >= 0 )
+        {
+          if ( sub_4077F1(
+                 pOut.x + ((signed int)(((unsigned __int64)(vb * (signed __int64)v126) >> 16) + 32768) >> 16),
+                 pOut.y + ((signed int)(((unsigned __int64)(vb * (signed __int64)v122) >> 16) + 32768) >> 16),
+                 outz + ((signed int)(((unsigned __int64)(vb * (signed __int64)v118) >> 16) + 32768) >> 16),
+                 v39,
+                 (BSPVertexBuffer *)a5a) )
+          {
+            v113 = 1;
+            goto LABEL_71;
+          }
+        }
+      }
+LABEL_68:
+      ++sDeptha;
+      v_8 += 308;
+      if ( sDeptha >= *((int *)a5a + 2) )
+        goto LABEL_71;
+    }
+  }
+  return !v114 || !v113;
+}
+//----- (0043F333) --------------------------------------------------------
+void BspRenderer::MakeVisibleSectorList()
+{
+  int v6; // ebx@3
+
+  uNumVisibleNotEmptySectors = 0;
+  for (uint i = 0; i < num_nodes; ++i)
+  {
+      if (!uNumVisibleNotEmptySectors)
+      {
+        pVisibleSectorIDs_toDrawDecorsActorsEtcFrom[uNumVisibleNotEmptySectors++] = nodes[i].uSectorID;
+        continue;
+      }
+      
+      v6 = 0;
+        while (pVisibleSectorIDs_toDrawDecorsActorsEtcFrom[v6] != nodes[i].uSectorID )
+        {
+          ++v6;
+          if ( v6 >= uNumVisibleNotEmptySectors)
+          {
+            pVisibleSectorIDs_toDrawDecorsActorsEtcFrom[uNumVisibleNotEmptySectors++] = nodes[i].uSectorID;
+          }
+        }
+
+  }
+}
+//----- (0046A334) --------------------------------------------------------
+char __fastcall DoInteractionWithTopmostZObject(int a1, int a2)
+{
+  int v2; // edx@1
+  BLVFace *v4; // eax@9
+  unsigned int v5; // ecx@9
+  unsigned __int16 v6; // ax@11
+  //ODMFace *v7; // eax@16
+  LevelDecoration *v8; // esi@19
+  __int16 v9; // ax@19
+  int v10; // eax@22
+  int v11; // ecx@22
+  int v12; // edi@23
+  Actor *v13; // esi@23
+  unsigned __int16 v14; // ax@23
+  unsigned __int16 v15; // ax@33
+  const char *v16; // eax@34
+  int v17; // edi@36
+  int v18; // eax@36
+  ItemGen *v19; // esi@39
+  unsigned int v20; // eax@39
+  int v21; // ecx@40
+  std::string v22; // [sp-18h] [bp-2Ch]@5
+  const char *v23; // [sp-8h] [bp-1Ch]@5
+  int v24; // [sp-4h] [bp-18h]@5
+  char v25; // [sp+8h] [bp-Ch]@5
+  int v26; // [sp+Ch] [bp-8h]@1
+  int a3; // [sp+13h] [bp-1h]@5
+
+  v26 = a2;
+  v2 = a1;
+  switch ( PID_TYPE(a1) )
+  {
+    case OBJECT_Item: // take the item
+      v17 = PID_ID(a1);
+      v26 = PID_ID(a1);
+      v18 = PID_ID(a1);
+      if ( pObjectList->pObjects[pSpriteObjects[v18].uObjectDescID].uFlags & 0x10
+        || v17 >= 1000
+        || !pSpriteObjects[v18].uObjectDescID )
+        return 1;
+      v19 = &pSpriteObjects[v18].stru_24;
+      v20 = pSpriteObjects[v18].stru_24.uItemID;
+      if ( pItemsTable->pItems[v20].uEquipType == EQUIP_GOLD)
+      {
+        party_finds_gold(v19->uSpecEnchantmentType, 0);
+        viewparams->bRedrawGameUI = 1;
+        v21 = v17;
+      }
+      else
+      {
+        if ( pParty->pPickedItem.uItemID )
+          return 1;
+        v24 = (int)pItemsTable->pItems[v20].pUnidentifiedName;
+        sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[471], v24);
+        ShowStatusBarString(pTmpBuf2.data(), 2u);
+        if ( v19->uItemID == 506 )
+          _449B7E_toggle_bit(pParty->_quest_bits, 184, 1u);
+        if ( v19->uItemID == 455 )
+          _449B7E_toggle_bit(pParty->_quest_bits, 185, 1u);
+        if ( !pParty->AddItem(v19) )
+          pParty->SetHoldingItem(v19);
+        v21 = v26;
+      }
+      SpriteObject::OnInteraction(v21);
+      break;
+
+    case OBJECT_Actor:
+      v12 = PID_ID(a1);
+      v13 = &pActors[PID_ID(a1)];
+      v14 = v13->uAIState;
+      if ( v14 == 4 || v14 == 17 )
+        return 1;
+      if ( v14 == 5 )
+      {
+        stru_50C198.LootActor(&pActors[PID_ID(a1)]);
+      }
+      else
+      {
+        if ( !v13->GetActorsRelation(0) && !(BYTE2(v13->uAttributes) & 8) && v13->CanAct() )
+        {
+          Actor::AI_FaceObject(v12, 4u, 0, 0);
+          if ( v13->sNPC_ID )
+          {
+            pMessageQueue_50CBD0->AddMessage(UIMSG_StartNPCDialogue, v12, 0);
+          }
+          else
+          {
+            v15 = pNPCStats->pGroups_copy[v13->uGroup];
+            if ( v15 )
+            {
+              v16 = pNPCStats->pCatchPhrases[v15];
+              if ( v16 )
+              {
+                pParty->uFlags |= 2u;
+                strcpy(byte_5B0938.data(), v16);
+                sub_4451A8_press_any_key(0, 0, 0);
+              }
+            }
+          }
+        }
+      }
+      break;
+
+    case OBJECT_Decoration:
+      v8 = &pLevelDecorations[PID_ID(a1)];
+      v9 = v8->field_16_event_id;
+      if ( v9 )
+      {
+        EventProcessor(v9, a1, 1);
+        LOBYTE(v8->field_2) |= 8u;
+      }
+      else
+      {
+        if ( !pLevelDecorations[PID_ID(a1)].IsInteractive() )
+          return 1;
+        v10 = v8->_idx_in_stru123;
+        v24 = 1;
+        v11 = stru_5E4C90._decor_events[v10 - 75] + 380;
+        activeLevelDecoration = v8;
+        EventProcessor(v11, 0, 1);
+        activeLevelDecoration = NULL;
+      }
+      break;
+
+    default:
+      MessageBoxW(nullptr, L"Warning: Invalid ID reached!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Mouse.cpp:2020", 0);
+      return 1;
+
+    case OBJECT_BModel:
+      if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor )
+      {
+        int bmodel_id = a1 >> 9,
+            face_id = PID_ID(a1) & 0x3F;
+        if (bmodel_id >= pOutdoor->uNumBModels)
+          return 1;
+        auto face = &pOutdoor->pBModels[bmodel_id].pFaces[face_id];
+        if (face->uAttributes & 0x100000 || face->sCogTriggeredID == 0 )
+          return 1;
+        EventProcessor((signed __int16)face->sCogTriggeredID, v2, 1);
+      }
+      else
+      {
+        v4 = &pIndoor->pFaces[PID_ID(a1)];
+        v5 = v4->uAttributes;
+        if ( !(v5 & 0x2000000) )
+        {
+          ShowNothingHereStatus();
+          return 1;
+        }
+        if ( v5 & 0x100000 || (v6 = pIndoor->pFaceExtras[v4->uFaceExtraID].uEventID) == 0 )
+          return 1;
+        if ( pCurrentScreen != SCREEN_BRANCHLESS_NPC_DIALOG )
+          EventProcessor((signed __int16)v6, v2, 1);
+      }
+      return 0;
+      break;
+  }
+  return 0;
+}
 //----- (0046BDF1) --------------------------------------------------------
 void __cdecl BLV_UpdateUserInputAndOther()
 {
@@ -4648,4 +6842,850 @@
   UpdateActors_BLV();
   BLV_UpdateDoors();
   check_event_triggers();
+}
+//----- (00424829) --------------------------------------------------------
+bool sub_424829(int pNumVertices, BspRenderer_stru2 *a2, BspRenderer_stru2 *a3, int uFaceID)
+{
+  //int v4; // edi@1
+  //BspRenderer_stru2 *v5; // ebx@1
+  int v6; // eax@3
+  int min_y; // esi@5
+  int max_y; // edx@5
+  //int v9; // ecx@6
+  int v10; // eax@12
+  //int v11; // edi@13
+  //int v12; // edx@18
+  int v13; // eax@22
+  //int v14; // edi@28
+  int v15; // ecx@29
+  //int v16; // edi@30
+  //int v17; // edx@35
+  int v18; // eax@39
+  int v19; // eax@44
+  int v20; // ecx@44
+  //int v21; // edi@45
+  int v22; // edi@46
+  //__int16 *v23; // ecx@47
+  int v24; // edx@48
+  //int v25; // eax@50
+  int v26; // eax@55
+  signed int v27; // edi@55
+  //int v28; // edx@56
+  int v29; // edx@57
+  //int v30; // eax@59
+  int v31; // eax@64
+  signed int v32; // edi@64
+  //int v33; // edx@65
+  int v34; // eax@66
+  int v35; // dx@66
+  __int16 v36; // dx@67
+  __int16 v37; // di@67
+  __int16 v38; // dx@67
+  //BspRenderer_stru2 *v39; // ecx@69
+  //int v40; // edx@69
+  //int v41; // edi@70
+  //__int16 *v42; // eax@76
+  //__int16 *v43; // eax@81
+  //__int16 *v45; // eax@87
+  int v46; // edx@87
+  //__int16 v47; // cx@88
+  //int v48; // eax@93
+  int v49; // esi@93
+  //__int16 *v50; // ecx@94
+  //int v51; // eax@95
+  //int v52; // eax@97
+  int v53; // [sp+Ch] [bp-34h]@44
+  int v54; // [sp+10h] [bp-30h]@0
+  int v55; // [sp+14h] [bp-2Ch]@12
+  //__int16 *v56; // [sp+14h] [bp-2Ch]@47
+  //__int16 v57; // [sp+14h] [bp-2Ch]@76
+  //__int16 v58; // [sp+14h] [bp-2Ch]@81
+  int v59; // [sp+14h] [bp-2Ch]@87
+  //BspRenderer_stru2 *v60; // [sp+18h] [bp-28h]@1
+  int v61; // [sp+1Ch] [bp-24h]@29
+  int v62; // [sp+20h] [bp-20h]@0
+  signed int v63; // [sp+24h] [bp-1Ch]@3
+  signed int v64; // [sp+28h] [bp-18h]@3
+  int v65; // [sp+2Ch] [bp-14h]@5
+  //int v66; // [sp+2Ch] [bp-14h]@39
+  //int v67; // [sp+30h] [bp-10h]@22
+  int v68; // [sp+34h] [bp-Ch]@12
+  int v69; // [sp+34h] [bp-Ch]@29
+  int v70; // [sp+34h] [bp-Ch]@46
+  int v71; // [sp+34h] [bp-Ch]@75
+  int v72; // [sp+34h] [bp-Ch]@80
+  //int v73; // [sp+38h] [bp-8h]@11
+  //int v74; // [sp+3Ch] [bp-4h]@1
+  //int a3a; // [sp+48h] [bp+8h]@76
+  //int a3b; // [sp+48h] [bp+8h]@87
+
+  //try graphic engine with function returning 1 always, and without
+  //return true;
+  if ( pNumVertices <= 1 )
+    return false;
+  min_y = stru_50B700._screen_space_y[0];
+  v65 = 0;
+  max_y = stru_50B700._screen_space_y[0];
+  if ( !stru_50B700.field_0 )
+  {
+    v63 = 1;
+    v64 = -1;
+  }
+  else 
+  {
+    v63 = -1;
+    v64 = 1;
+  }
+
+  for ( v6 = 1; v6 < pNumVertices; ++v6 )
+  {
+    if ( stru_50B700._screen_space_y[v6] >= min_y )
+    {
+      if ( stru_50B700._screen_space_y[v6] > max_y )
+        max_y = stru_50B700._screen_space_y[v6];
+    }
+    if ( stru_50B700._screen_space_y[v6] < min_y )
+    {
+      v65 = v6;
+      min_y = stru_50B700._screen_space_y[v6];
+    }
+  }
+  if ( max_y == min_y )
+    return false;
+
+  v10 = v65;
+  a2->_viewport_space_y = min_y;
+  a2->_viewport_space_w = max_y;
+  v55 = v65;
+
+  for ( v68 = 0; v68 < pNumVertices; ++v68 )
+  {
+    v10 += v64;
+    if ( v10 < pNumVertices )
+    {
+      if ( v10 < 0 )
+        v10 += pNumVertices;
+    }
+    else
+      v10 -= pNumVertices;
+    if ( stru_50B700._screen_space_y[v10] <= stru_50B700._screen_space_y[v65] )
+    {
+      v55 = v10;
+      v65 = v10;
+    }
+    if ( stru_50B700._screen_space_y[v10] == max_y )
+      break;
+  }
+  v13 = v55 + v64;
+  if ( v13 < pNumVertices )
+  {
+    if ( v13 < 0 )
+      v13 += pNumVertices;
+  }
+  else
+    v13 -= pNumVertices;
+  if ( stru_50B700._screen_space_y[v13] != stru_50B700._screen_space_y[v55] )
+  {
+    v62 = stru_50B700._screen_space_x[v55] << 16;
+    v54 = ((stru_50B700._screen_space_x[v13] - stru_50B700._screen_space_x[v55]) << 16) / (stru_50B700._screen_space_y[v13] - stru_50B700._screen_space_y[v55]);
+    a2->viewport_left_side[min_y] = LOWORD(stru_50B700._screen_space_x[v55]);
+  }
+  v15 = v65;
+  v61 = v65;
+
+  for ( v69 = 0; v69 < pNumVertices; ++v69 )
+  {
+    v15 += v63;
+    if ( v15 < pNumVertices )
+    {
+      if ( v15 < 0 )
+        v15 += pNumVertices;
+    }
+    else
+      v15 -= pNumVertices;
+    if ( stru_50B700._screen_space_y[v15] <= stru_50B700._screen_space_y[v65] )
+    {
+      v61 = v15;
+      v65 = v15;
+    }
+    if ( stru_50B700._screen_space_y[v15] == max_y )
+      break;
+  }
+  v18 = v63 + v61;
+  if ( v18 < pNumVertices )
+  {
+    if ( v18 < 0 )
+      v18 += pNumVertices;
+  }
+  else
+    v18 -= pNumVertices;
+  v19 = v18;
+  v20 = v61;
+  if ( stru_50B700._screen_space_y[v19] != stru_50B700._screen_space_y[v61] )
+  {
+    v61 = stru_50B700._screen_space_x[v20] << 16;
+    v53 = ((stru_50B700._screen_space_x[v19] - stru_50B700._screen_space_x[v20]) << 16) / stru_50B700._screen_space_y[v19] - stru_50B700._screen_space_y[v20];
+    a2->viewport_right_side[max_y] = LOWORD(stru_50B700._screen_space_x[v20]);
+  }
+  v22 = min_y;
+  if ( min_y <= max_y )
+  {
+    //v56 = &a2->array_3D8[v7];
+    //v23 = &a2->array_18[v7];
+    for ( v70 = min_y; v70 <= max_y; ++v70 )
+    {
+      v24 = v13;
+      if ( v22 >= stru_50B700._screen_space_y[v13] && v22 != max_y )
+      {
+        v13 = v64 + v13;
+        if ( v13 < pNumVertices )
+        {
+          if ( v13 < 0 )
+            v13 += pNumVertices;
+        }
+        else
+          v13 -= pNumVertices;
+        v26 = v13;
+        //v27 = stru_50B700._screen_space_y[v26] - stru_50B700._screen_space_y[v24];
+        if ( stru_50B700._screen_space_y[v26] - stru_50B700._screen_space_y[v24] > 0 )
+        {
+          v54 = ((stru_50B700._screen_space_x[v26] - stru_50B700._screen_space_x[v24]) << 16) / stru_50B700._screen_space_y[v26] - stru_50B700._screen_space_y[v24];
+          v62 = stru_50B700._screen_space_x[v24] << 16;
+        }
+      }
+      v29 = v18;
+      if ( v70 >= stru_50B700._screen_space_y[v18] && v70 != max_y )
+      {
+        v18 += v63;
+        if ( v18 < pNumVertices )
+        {
+          if ( v18 < 0 )
+            v18 += pNumVertices;
+        }
+        else
+          v18 -= pNumVertices;
+        v31 = v18;
+        //v32 = stru_50B700._screen_space_y[v31] - stru_50B700._screen_space_y[v29];
+        if ( stru_50B700._screen_space_y[v31] - stru_50B700._screen_space_y[v29] > 0 )
+        {
+          v53 = ((stru_50B700._screen_space_x[v31] - stru_50B700._screen_space_x[v29]) << 16) / stru_50B700._screen_space_y[v31] - stru_50B700._screen_space_y[v29];
+          v61 = stru_50B700._screen_space_x[v29] << 16;
+        }
+      }
+	  //v34 = (char *)a2->array_18 - (char *)a2->array_3D8;
+	  //v35 = *(__int16 *)((char *)&a2->array_3D8[v70] + v34);
+      //v35 = HIWORD(v62);
+      a2->viewport_left_side[v70] = HIWORD(v62);
+      a2->viewport_right_side[v70] = HIWORD(v61);
+      //v34 = &a2->array_3D8[v70];
+      //v35 = a2->array_3D8[v70];
+      if ( a2->viewport_left_side[v70] > a2->viewport_right_side[v70] )
+      {
+        v36 = a2->viewport_left_side[v70] ^ a2->viewport_right_side[v70];
+        v37 = a2->viewport_right_side[v70];
+        a2->viewport_left_side[v70] = v36;
+        v38 = v37 ^ v36;
+        a2->viewport_left_side[v70] ^= v38;
+        a2->viewport_right_side[v70] = v38;
+      }
+      //++v56;
+      v62 += v54;
+      v22 = v70 + 1;
+      v61 += v53;
+      //++v23;
+    }
+  }
+  if ( max_y < a3->_viewport_space_y )
+    return false;
+  if ( min_y > a3->_viewport_space_w )
+    return false;
+  if ( min_y < a3->_viewport_space_y )
+    min_y = a3->_viewport_space_y;
+  if ( max_y > a3->_viewport_space_w )
+    max_y = a3->_viewport_space_w;
+  if ( min_y <= max_y )
+  {
+    //a3a = (char *)a2 - (char *)a3;
+    //v42 = &a3->array_3D8[v7];
+    //v57 = *(__int16 *)((char *)v42 + a3a);
+    for ( v71 = min_y; v71 <= max_y; ++v71 )
+    {
+      if ( a2->viewport_left_side[v71] >= a3->viewport_left_side[v71] && a2->viewport_left_side[v71] <= a3->viewport_right_side[v71] )
+        break;
+      //++v57;
+      ++min_y;
+      //++v42;
+    }
+  }
+  if ( max_y < min_y )
+    return false;
+  //a3a = (char *)a2 - (char *)a3;
+  //v43 = &a3->array_3D8[v8];
+  //v58 = *(__int16 *)((char *)v43 + a3a);
+  for ( v72 = max_y; v72 >= min_y; --v72 )
+  {
+    if ( a2->viewport_right_side[v72] >= a3->viewport_left_side[v72] && a2->viewport_left_side[v72] <= a3->viewport_right_side[v72] )
+      break;
+    //--v58;
+    --max_y;
+    //--v43;
+    //v8 = v8;
+  }
+  if ( min_y >= max_y )
+    return false;
+  //a3b = (char *)a3 - (char *)a2;
+  v59 = min_y;
+  //v45 = &a2->array_18[v7];
+  
+  for ( v46 = max_y - min_y + 1; v46; --v46 )
+  {
+    //v47 = *(__int16 *)((char *)v45 + a3b);
+    if ( a2->viewport_left_side[v59] < a3->viewport_left_side[v59] )
+      a2->viewport_left_side[v59] = a3->viewport_left_side[v59];
+    if ( a2->viewport_right_side[v59] > a3->viewport_right_side[v59] )
+      a2->viewport_right_side[v59] = a3->viewport_right_side[v59];
+    ++v59;
+    //++v45;
+  }
+  a2->_viewport_space_y = min_y;
+  a2->_viewport_space_w = max_y;
+  a2->field_8 = a2->viewport_left_side[min_y];
+  //v48 = a2->viewport_right_side[v7];
+  a2->field_10 = min_y;
+  a2->field_14 = min_y;
+  a2->field_C = a2->viewport_right_side[min_y];
+  v49 = min_y + 1;
+  if ( v49 <= max_y )
+  {
+    //v50 = &a2->array_3D8[v49];
+    for ( v49; v49 <= max_y; ++v49 )
+    {
+      //v51 = a2->array_18[v49];
+      if ( a2->viewport_left_side[v49] < a2->field_8 )
+      {
+        a2->field_8 = a2->viewport_left_side[v49];
+        a2->field_10 = v49;
+      }
+      if ( a2->viewport_right_side[v49] > a2->field_C )
+      {
+        a2->field_C = a2->viewport_right_side[v49];
+        a2->field_14 = v49;
+      }
+      //++v50;
+    }
+  }
+  return true;
+}
+//----- (00423B5D) --------------------------------------------------------
+int __fastcall sub_423B5D(unsigned int uFaceID)
+{
+  BLVFace *pFace; // ebx@1
+  Vec3_short_ *v2; // esi@1
+  //int v3; // ST28_4@1
+  //__int16 v4; // ST2C_2@1
+  signed int v5; // esi@1
+  //Vec3_short_ *v6; // eax@4
+  signed int v7; // edi@5
+  signed int v8; // eax@5
+  signed int v9; // ecx@10
+  int v10; // eax@10
+  int v11; // edx@11
+  int v12; // ST28_4@12
+  signed int v13; // edx@12
+  signed __int64 v14; // qtt@12
+  char *v15; // ebx@12
+  int v16; // ST28_4@14
+  signed int v17; // eax@14
+  signed __int64 v18; // qtt@14
+  signed int v19; // edx@15
+  signed int v20; // edx@17
+  signed int v21; // ebx@19
+  signed int v22; // esi@20
+  int v23; // edi@21
+  int v24; // eax@21
+  int v25; // eax@22
+  int v26; // eax@22
+  signed int v27; // ST30_4@24
+  signed __int64 v28; // qtt@24
+  int v29; // ST18_4@25
+  int v30; // eax@26
+  int v31; // eax@27
+  int v32; // eax@27
+  signed int v33; // ST30_4@29
+  signed __int64 v34; // qtt@29
+  int v35; // ST30_4@30
+  signed int v36; // edi@31
+  unsigned int v37; // eax@31
+  bool v38; // edx@31
+  int v39; // ecx@31
+  int v40; // ecx@32
+  int v41; // esi@32
+  int v42; // eax@34
+  signed int v43; // ebx@41
+  unsigned int v44; // eax@41
+  signed int v45; // ecx@42
+  int v46; // esi@42
+  int v47; // eax@44
+  signed int v48; // edi@51
+  unsigned int v49; // eax@51
+  bool v50; // edx@51
+  int v51; // ecx@51
+  int v52; // ecx@52
+  int v53; // esi@52
+  int v54; // eax@54
+  int v55; // ebx@61
+  unsigned int v56; // eax@61
+  signed int v57; // ecx@62
+  int v58; // esi@62
+  int v59; // eax@64
+  char v61; // zf@72
+  signed int v62; // edx@75
+  int v63; // ecx@76
+  int v64; // esi@76
+  int v65; // ecx@83
+  signed int v66; // [sp+14h] [bp-14h]@3
+  int v67; // [sp+14h] [bp-14h]@34
+  int v68; // [sp+14h] [bp-14h]@44
+  int v69; // [sp+14h] [bp-14h]@54
+  int v70; // [sp+14h] [bp-14h]@64
+  signed int v71; // [sp+14h] [bp-14h]@75
+  IndoorCameraD3D *_this; // [sp+18h] [bp-10h]@1
+  bool thisa; // [sp+18h] [bp-10h]@9
+  int thisb; // [sp+18h] [bp-10h]@12
+  int thisc; // [sp+18h] [bp-10h]@20
+  bool thisd; // [sp+18h] [bp-10h]@41
+  bool thise; // [sp+18h] [bp-10h]@61
+  int thisf; // [sp+18h] [bp-10h]@74
+  signed int v79; // [sp+1Ch] [bp-Ch]@9
+  int v80; // [sp+1Ch] [bp-Ch]@76
+  bool v81; // [sp+20h] [bp-8h]@10
+  bool v82; // [sp+20h] [bp-8h]@32
+  bool v83; // [sp+20h] [bp-8h]@42
+  bool v84; // [sp+20h] [bp-8h]@52
+  bool v85; // [sp+20h] [bp-8h]@62
+  signed int v86; // [sp+24h] [bp-4h]@9
+  signed int v87; // [sp+24h] [bp-4h]@19
+  signed int v88; // [sp+24h] [bp-4h]@31
+  signed int v89; // [sp+24h] [bp-4h]@41
+  signed int v90; // [sp+24h] [bp-4h]@51
+  signed int v91; // [sp+24h] [bp-4h]@61
+
+  pFace = &pIndoor->pFaces[uFaceID];
+  _this = pGame->pIndoorCameraD3D;
+  v2 = &pIndoor->pVertices[pIndoor->pFaces[uFaceID].pVertexIDs[0]];
+  //v3 = *(_DWORD *)pIndoor->pVertices[pIndoor->pFaces[uFaceID].pVertexIDs[0]].x;
+  //v4 = pIndoor->pVertices[pIndoor->pFaces[uFaceID].pVertexIDs[0]].z;
+  v5 = 0;
+  if ( pFace->pFacePlane_old.vNormal.x * (pIndoor->pVertices[pIndoor->pFaces[uFaceID].pVertexIDs[0]].x - pBLVRenderParams->vPartyPos.x)
+     + pFace->pFacePlane_old.vNormal.y * (pIndoor->pVertices[pIndoor->pFaces[uFaceID].pVertexIDs[0]].y - pBLVRenderParams->vPartyPos.y)
+     + pFace->pFacePlane_old.vNormal.z * (pIndoor->pVertices[pIndoor->pFaces[uFaceID].pVertexIDs[0]].z - pBLVRenderParams->vPartyPos.z) < 0 )
+  {
+    stru_50B700.field_0 = 1;
+  }
+  else
+  {
+    stru_50B700.field_0 = 0;
+    if ( !(pFace->uAttributes & 1) )
+      return 0;
+  }
+  v66 = pFace->uNumVertices;
+  if ( (signed int)pFace->uNumVertices > 0 )
+  {
+    do
+    {
+      //v6 = &pIndoor->pVertices[pFace->pVertexIDs[v5]];
+      pGame->pIndoorCameraD3D->ApplyViewTransform_TrueIfStillVisible(
+        pIndoor->pVertices[pFace->pVertexIDs[v5]].x,
+        pIndoor->pVertices[pFace->pVertexIDs[v5]].y,
+        pIndoor->pVertices[pFace->pVertexIDs[v5]].z,
+        &stru_50B700._view_transformed_xs[v5 + 3],
+        &stru_50B700._view_transformed_zs[v5 + 3],
+        &stru_50B700._view_transformed_ys[v5 + 3],
+        0);
+      ++v5;
+    }
+    while ( v5 < v66 );
+  }
+  v7 = v66;
+  v8 = 0;
+  if ( v66 <= 0 )
+    return 0;
+  do
+  {
+    if ( stru_50B700._view_transformed_xs[v8 + 3] >= 524288 )
+      break;
+    ++v8;
+  }
+  while ( v8 < v66 );
+  if ( v8 >= v66 )
+    return 0;
+  v79 = 0;
+  stru_50B700._view_transformed_xs[v66 + 3] = stru_50B700._view_transformed_xs[3];
+  stru_50B700._view_transformed_zs[v66 + 3] = stru_50B700._view_transformed_zs[3];
+  stru_50B700._view_transformed_ys[v66 + 3] = stru_50B700._view_transformed_ys[3];
+  thisa = stru_50B700._view_transformed_xs[3] >= 524288;
+  v86 = 1;
+  if ( v66 >= 1 )
+  {
+    do
+    {
+      v9 = v86;
+      v10 = stru_50B700._view_transformed_xs[v86 + 3];
+      v81 = v10 >= 524288;
+      if ( thisa ^ v81 )
+      {
+        v11 = stru_50B700._view_transformed_xs[v9 + 2];
+        if ( v10 >= 524288 )
+        {
+          v12 = v10 - v11;
+          v13 = 524288 - v11;
+          LODWORD(v14) = v13 << 16;
+          HIDWORD(v14) = v13 >> 16;
+          v15 = (char *)&stru_50B700._view_transformed_ys[v9 + 2];
+          stru_50B700._view_transformed_zs[v79] = ((unsigned __int64)((stru_50B700._view_transformed_zs[v9 + 3]
+                                                                     - stru_50B700._view_transformed_zs[v9 + 2])
+                                                                    * v14
+                                                                    / v12) >> 16)
+                                                + stru_50B700._view_transformed_zs[v9 + 2];
+          thisb = (unsigned __int64)((stru_50B700._view_transformed_ys[v9 + 3] - stru_50B700._view_transformed_ys[v9 + 2])
+                                   * v14
+                                   / v12) >> 16;
+        }
+        else
+        {
+          v16 = v11 - v10;
+          v17 = 524288 - v10;
+          LODWORD(v18) = v17 << 16;
+          HIDWORD(v18) = v17 >> 16;
+          v15 = (char *)&stru_50B700._view_transformed_ys[v9 + 3];
+          stru_50B700._view_transformed_zs[v79] = ((unsigned __int64)((stru_50B700._view_transformed_zs[v9 + 2]
+                                                                     - stru_50B700._view_transformed_zs[v9 + 3])
+                                                                    * v18
+                                                                    / v16) >> 16)
+                                                + stru_50B700._view_transformed_zs[v9 + 3];
+          thisb = (unsigned __int64)((stru_50B700._view_transformed_ys[v9 + 2] - stru_50B700._view_transformed_ys[v9 + 3])
+                                   * v18
+                                   / v16) >> 16;
+        }
+        v19 = v79++;
+        v7 = v66;
+        stru_50B700._view_transformed_ys[v19] = thisb + *(_DWORD *)v15;
+        stru_50B700._view_transformed_xs[v19] = 524288;
+      }
+      if ( v81 )
+      {
+        v20 = v79++;
+        stru_50B700._view_transformed_xs[v20] = stru_50B700._view_transformed_xs[v9 + 3];
+        stru_50B700._view_transformed_zs[v20] = stru_50B700._view_transformed_zs[v9 + 3];
+        stru_50B700._view_transformed_ys[v20] = stru_50B700._view_transformed_ys[v9 + 3];
+      }
+      ++v86;
+      thisa = v81;
+    }
+    while ( v86 <= v7 );
+  }
+  v87 = 0;
+  v21 = v79;
+  stru_50B700._view_transformed_xs[v79] = stru_50B700._view_transformed_xs[0];
+  stru_50B700._view_transformed_zs[v79] = stru_50B700._view_transformed_zs[0];
+  for ( stru_50B700._view_transformed_ys[v79] = stru_50B700._view_transformed_ys[0];
+        v87 < v79;
+        stru_50B700._screen_space_y[v22 + 12] = pBLVRenderParams->uViewportCenterY - v35 )
+  {
+    v22 = v87;
+    thisc = abs(stru_50B700._view_transformed_xs[v87]);
+    if ( abs(stru_50B700._view_transformed_zs[v87]) >> 13 <= thisc )
+    {
+      v27 = stru_50B700._view_transformed_zs[v22];
+      LODWORD(v28) = v27 << 16;
+      HIDWORD(v28) = v27 >> 16;
+      v26 = v28 / stru_50B700._view_transformed_xs[v22];
+      v23 = 0;
+    }
+    else
+    {
+      v23 = 0;
+      v24 = 0;
+      if ( stru_50B700._view_transformed_zs[v22] >= 0 )
+      {
+        LOBYTE(v24) = stru_50B700._view_transformed_xs[v22] >= 0;
+        v26 = ((v24 - 1) & 0xFF800000) + 4194304;
+      }
+      else
+      {
+        LOBYTE(v24) = stru_50B700._view_transformed_xs[v22] >= 0;
+        v25 = v24 - 1;
+        v26 = (v25 & 0x800000) - 4194304;
+      }
+    }
+    v29 = stru_50B700._view_transformed_ys[v22];
+    stru_50B700._screen_space_x[v22 + 12] = v26;
+    if ( abs(v29) >> 13 <= thisc )
+    {
+      v33 = stru_50B700._view_transformed_ys[v22];
+      LODWORD(v34) = v33 << 16;
+      HIDWORD(v34) = v33 >> 16;
+      v32 = v34 / stru_50B700._view_transformed_xs[v22];
+    }
+    else
+    {
+      v30 = 0;
+      if ( stru_50B700._view_transformed_ys[v22] >= v23 )
+      {
+        LOBYTE(v30) = stru_50B700._view_transformed_xs[v22] >= v23;
+        v32 = ((v30 - 1) & 0xFF800000) + 4194304;
+      }
+      else
+      {
+        LOBYTE(v30) = stru_50B700._view_transformed_xs[v22] >= v23;
+        v31 = v30 - 1;
+        v32 = (v31 & 0x800000) - 4194304;
+      }
+    }
+    stru_50B700._screen_space_y[v22 + 12] = v32;
+    stru_50B700._screen_space_x[v22 + 12] = (unsigned __int64)(SHIWORD(pBLVRenderParams->field_40)
+                                                             * (signed __int64)stru_50B700._screen_space_x[v22 + 12]) >> 16;
+    v35 = (unsigned __int64)(SHIWORD(pBLVRenderParams->field_40) * (signed __int64)stru_50B700._screen_space_y[v22 + 12]) >> 16;
+    stru_50B700._screen_space_x[v22 + 12] = pBLVRenderParams->uViewportCenterX - stru_50B700._screen_space_x[v22 + 12];
+    ++v87;
+  }
+  v36 = 0;
+  stru_50B700._screen_space_x[v21 + 12] = stru_50B700._screen_space_x[12];
+  stru_50B700._screen_space_y[v21 + 12] = stru_50B700._screen_space_y[12];
+  v37 = pBLVRenderParams->uViewportX;
+  v38 = stru_50B700._screen_space_x[12] < (signed int)pBLVRenderParams->uViewportX;
+  LOBYTE(v38) = stru_50B700._screen_space_x[12] >= (signed int)pBLVRenderParams->uViewportX;
+  v39 = 1;
+  v88 = 1;
+  if ( v79 < 1 )
+    return 0;
+  do
+  {
+    v40 = v39;
+    v41 = stru_50B700._screen_space_x[v40 + 12];
+    v82 = v41 >= (signed int)v37;
+    if ( v38 ^ v82 )
+    {
+      if ( v41 >= (signed int)v37 )
+      {
+        v67 = (signed int)(v37 - stru_50B700._screen_space_x[v40 + 11])
+            * (signed __int64)(stru_50B700._screen_space_y[v40 + 12] - stru_50B700._screen_space_y[v40 + 11])
+            / (v41 - stru_50B700._screen_space_x[v40 + 11]);
+        v42 = stru_50B700._screen_space_y[v40 + 11];
+      }
+      else
+      {
+        v67 = (signed int)(v37 - v41)
+            * (signed __int64)(stru_50B700._screen_space_y[v40 + 11] - stru_50B700._screen_space_y[v40 + 12])
+            / (stru_50B700._screen_space_x[v40 + 11] - v41);
+        v42 = stru_50B700._screen_space_y[v40 + 12];
+      }
+      ++v36;
+      stru_50B700._screen_space_y[v36 + 8] = v67 + v42;
+      v37 = pBLVRenderParams->uViewportX;
+      stru_50B700._screen_space_x[v36 + 8] = pBLVRenderParams->uViewportX;
+    }
+    v38 = v82;
+    if ( v82 )
+    {
+      stru_50B700._screen_space_x[v36 + 9] = stru_50B700._screen_space_x[v40 + 12];
+      stru_50B700._screen_space_y[v36++ + 9] = stru_50B700._screen_space_y[v40 + 12];
+    }
+    v39 = v88++ + 1;
+  }
+  while ( v88 <= v79 );
+  if ( !v36
+    || (v43 = 0,
+        stru_50B700._screen_space_x[v36 + 9] = stru_50B700._screen_space_x[9],
+        stru_50B700._screen_space_y[v36 + 9] = stru_50B700._screen_space_y[9],
+        v44 = pBLVRenderParams->uViewportZ,
+        thisd = stru_50B700._screen_space_x[9] <= (signed int)pBLVRenderParams->uViewportZ,
+        v89 = 1,
+        v36 < 1) )
+    return 0;
+  do
+  {
+    v45 = v89;
+    v46 = stru_50B700._screen_space_x[v89 + 9];
+    v83 = v46 <= (signed int)v44;
+    if ( thisd ^ v83 )
+    {
+      if ( v46 <= (signed int)v44 )
+      {
+        v68 = (signed int)(v44 - stru_50B700._screen_space_x[v45 + 8])
+            * (signed __int64)(stru_50B700._screen_space_y[v45 + 9] - stru_50B700._screen_space_y[v45 + 8])
+            / (v46 - stru_50B700._screen_space_x[v45 + 8]);
+        v47 = stru_50B700._screen_space_y[v45 + 8];
+      }
+      else
+      {
+        v68 = (signed int)(v44 - v46)
+            * (signed __int64)(stru_50B700._screen_space_y[v45 + 8] - stru_50B700._screen_space_y[v45 + 9])
+            / (stru_50B700._screen_space_x[v45 + 8] - v46);
+        v47 = stru_50B700._screen_space_y[v45 + 9];
+      }
+      ++v43;
+      stru_50B700._screen_space_y[v43 + 5] = v68 + v47;
+      v44 = pBLVRenderParams->uViewportZ;
+      stru_50B700._screen_space_x[v43 + 5] = pBLVRenderParams->uViewportZ;
+    }
+    if ( v83 )
+    {
+      stru_50B700._screen_space_x[v43 + 6] = stru_50B700._screen_space_x[v45 + 9];
+      stru_50B700._screen_space_y[v43++ + 6] = stru_50B700._screen_space_y[v45 + 9];
+    }
+    ++v89;
+    thisd = v83;
+  }
+  while ( v89 <= v36 );
+  if ( !v43
+    || (v48 = 0,
+        stru_50B700._screen_space_x[v43 + 6] = stru_50B700._screen_space_x[6],
+        stru_50B700._screen_space_y[v43 + 6] = stru_50B700._screen_space_y[6],
+        v49 = pBLVRenderParams->uViewportY,
+        v50 = stru_50B700._screen_space_y[6] < (signed int)pBLVRenderParams->uViewportY,
+        LOBYTE(v50) = stru_50B700._screen_space_y[6] >= (signed int)pBLVRenderParams->uViewportY,
+        v51 = 1,
+        v90 = 1,
+        v43 < 1) )
+    return 0;
+  do
+  {
+    v52 = v51;
+    v53 = stru_50B700._screen_space_y[v52 + 6];
+    v84 = v53 >= (signed int)v49;
+    if ( v50 ^ v84 )
+    {
+      if ( v53 >= (signed int)v49 )
+      {
+        v69 = (signed int)(v49 - stru_50B700._screen_space_y[v52 + 5])
+            * (signed __int64)(stru_50B700._screen_space_x[v52 + 6] - stru_50B700._screen_space_x[v52 + 5])
+            / (v53 - stru_50B700._screen_space_y[v52 + 5]);
+        v54 = stru_50B700._screen_space_x[v52 + 5];
+      }
+      else
+      {
+        v69 = (signed int)(v49 - v53)
+            * (signed __int64)(stru_50B700._screen_space_x[v52 + 5] - stru_50B700._screen_space_x[v52 + 6])
+            / (stru_50B700._screen_space_y[v52 + 5] - v53);
+        v54 = stru_50B700._screen_space_x[v52 + 6];
+      }
+      ++v48;
+      stru_50B700._screen_space_x[v48 + 2] = v69 + v54;
+      v49 = pBLVRenderParams->uViewportY;
+      stru_50B700._screen_space_y[v48 + 2] = pBLVRenderParams->uViewportY;
+    }
+    v50 = v84;
+    if ( v84 )
+    {
+      stru_50B700._screen_space_x[v48 + 3] = stru_50B700._screen_space_x[v52 + 6];
+      stru_50B700._screen_space_y[v48++ + 3] = stru_50B700._screen_space_y[v52 + 6];
+    }
+    v51 = v90++ + 1;
+  }
+  while ( v90 <= v43 );
+  if ( !v48
+    || (v55 = 0,
+        stru_50B700._screen_space_x[v48 + 3] = stru_50B700._screen_space_x[3],
+        stru_50B700._screen_space_y[v48 + 3] = stru_50B700._screen_space_y[3],
+        v56 = pBLVRenderParams->uViewportW,
+        thise = stru_50B700._screen_space_y[3] <= (signed int)pBLVRenderParams->uViewportW,
+        v91 = 1,
+        v48 < 1) )
+    return 0;
+  do
+  {
+    v57 = v91;
+    v58 = stru_50B700._screen_space_y[v91 + 3];
+    v85 = v58 <= (signed int)v56;
+    if ( thise ^ v85 )
+    {
+      if ( v58 <= (signed int)v56 )
+      {
+        v70 = (signed int)(v56 - stru_50B700._screen_space_y[v57 + 2])
+            * (signed __int64)(stru_50B700._screen_space_x[v57 + 3] - stru_50B700._screen_space_x[v57 + 2])
+            / (v58 - stru_50B700._screen_space_y[v57 + 2]);
+        v59 = stru_50B700._screen_space_x[v57 + 2];
+      }
+      else
+      {
+        v70 = (signed int)(v56 - v58)
+            * (signed __int64)(stru_50B700._screen_space_x[v57 + 2] - stru_50B700._screen_space_x[v57 + 3])
+            / (stru_50B700._screen_space_y[v57 + 2] - v58);
+        v59 = stru_50B700._screen_space_x[v57 + 3];
+      }
+      ++v55;
+      //stru_50B700._screen_space_y[v55 + 59] = v70 + v59;
+	  stru_50B700._screen_space_x[v55 - 1] = v70 + v59;
+      v56 = pBLVRenderParams->uViewportW;
+      //stru_50B700._view_transformed_xs[v55 + 47] = pBLVRenderParams->uViewportW;
+	  stru_50B700._screen_space_y[v55 - 1] = pBLVRenderParams->uViewportW;
+    }
+    if ( v85 )
+    {
+      stru_50B700._screen_space_x[v55] = stru_50B700._screen_space_x[v57 + 3];
+      stru_50B700._screen_space_y[v55++] = stru_50B700._screen_space_y[v57 + 3];
+    }
+    ++v91;
+    thise = v85;
+  }
+  while ( v91 <= v48 );
+  if ( !v55 )
+    return 0;
+  v61 = pRenderer->pRenderD3D == 0;
+  stru_50B700._screen_space_x[v55] = stru_50B700._screen_space_x[0];
+  stru_50B700._screen_space_y[v55] = stru_50B700._screen_space_y[0];
+  if ( v61 && v55 > 3 )
+  {
+    stru_50B700._screen_space_x[v55 + 1] = stru_50B700._screen_space_x[1];
+    stru_50B700._screen_space_y[v55 + 1] = stru_50B700._screen_space_y[1];
+    thisf = 2 * (stru_50B700.field_0 != 0) - 1;
+    if ( v55 > 0 )
+    {
+      v62 = 1;
+      v71 = 1;
+      do
+      {
+        v63 = v62 - 1;
+        v64 = v62 + 1;
+        v80 = v62 + 1;
+        if ( v62 - 1 >= v55 )
+          v63 -= v55;
+        if ( v62 >= v55 )
+          v62 -= v55;
+        if ( v64 >= v55 )
+          v64 -= v55;
+        if ( thisf
+           * ((stru_50B700._screen_space_y[v64] - stru_50B700._screen_space_y[v63])
+            * (stru_50B700._screen_space_x[v62] - stru_50B700._screen_space_x[v63])
+            - (stru_50B700._screen_space_y[v62] - stru_50B700._screen_space_y[v63])
+            * (stru_50B700._screen_space_x[v64] - stru_50B700._screen_space_x[v63])) < 0 )
+        {
+          v62 = v80;
+          v71 = v80;
+        }
+        else
+        {
+          v62 = v71;
+          v65 = v71;
+          if ( v71 < v55 || (v65 = v71 - v55, v71 - v55 < v55) )
+          {
+            memcpy(
+              &stru_50B700._screen_space_y[v65],
+              &stru_50B700._screen_space_y[v65 + 1],
+              4 * ((unsigned int)(4 * (v55 - v65)) >> 2));
+            memcpy(
+              &stru_50B700._screen_space_x[v65],
+              &stru_50B700._screen_space_x[v65 + 1],
+              4 * ((unsigned int)(4 * (v55 - v65)) >> 2));
+          }
+          --v55;
+        }
+      }
+      while ( v62 - 1 < v55 );
+    }
+    stru_50B700._screen_space_x[v55] = stru_50B700._screen_space_x[0];
+    stru_50B700._screen_space_y[v55] = stru_50B700._screen_space_y[0];
+  }
+  return v55;
 }
\ No newline at end of file
--- a/Indoor_stuff.h	Sun Jun 23 14:27:32 2013 +0600
+++ b/Indoor_stuff.h	Sun Jun 23 14:27:57 2013 +0600
@@ -8,7 +8,7 @@
 #pragma pack(push, 1)
 struct BspRenderer_stru2
 {
-  void _43F9E1(__int16 x, int y, __int16 z, int w);
+  void GetViewportData(__int16 x, int y, __int16 z, int w);
 
   int _viewport_space_y;
   int _viewport_space_w;
--- a/Items.cpp	Sun Jun 23 14:27:32 2013 +0600
+++ b/Items.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -2348,5 +2348,178 @@
 		return  a4;
 		}
 	}
+//----- (0043C91D) --------------------------------------------------------
+int __fastcall GetItemTextureFilename(char *pOut, signed int item_id, int index, int shoulder)
+{
+  int result; // eax@2
+  char v5; // zf@3
+  const char *v6; // [sp-Ch] [bp-18h]@88
+  signed int v7; // [sp-8h] [bp-14h]@61
+  int v8; // [sp-4h] [bp-10h]@61
+  signed int v9; // [sp-4h] [bp-10h]@69
 
+  result = 0; //BUG   fn is void
+  if ( item_id <= 500 )
+  {
+    //v5 = *((char *)&pBloodsplatContainer->std__vector_pBloodsplats[62].field_20 + a2 + 2) == 0;
+    v5 = party_has_equipment[(item_id - 100) + 32 + 2] == 0;
+    switch ( item_id )
+    {
+      case 516:
+        v5 = byte_5111F6[2] == 0;
+        break;
+      case 505:
+        v5 = byte_5111F6[1] == 0;
+        break;
+      case 504:
+        v5 = byte_5111F6[0] == 0;
+        break;
+      case 533:
+        v5 = byte_5111F6[16] == 0;
+        break;
+      case 512:
+        v5 = byte_5111F6[3] == 0;
+        break;
+      case 521:
+        v5 = byte_5111F6[4] == 0;
+        break;
+      case 522:
+        v5 = byte_5111F6[5] == 0;
+        break;
+      case 523:
+        v5 = byte_5111F6[6] == 0;
+        break;
+      case 532:
+        v5 = byte_5111F6[7] == 0;
+        break;
+      case 544:
+        v5 = byte_5111F6[8] == 0;
+        break;
+      case 524:
+        v5 = byte_5111F6[9] == 0;
+        break;
+      case 535:
+        v5 = byte_5111F6[10] == 0;
+        break;
+      case 525:
+        v5 = byte_5111F6[11] == 0;
+        break;
+      case 530:
+        v5 = byte_5111F6[12] == 0;
+        break;
+      case 547:
+        v5 = byte_5111F6[13] == 0;
+        break;
+      case 548:
+        v5 = byte_5111F6[14] == 0;
+        break;
+      case 550:
+        v5 = byte_5111F6[15] == 0;
+        break;
+      default:
+        break;
+    }
+    if ( v5 )
+      return result;
+    result = 516;
+    if ( item_id < 66 || item_id > 78 )
+    {
+      if ( item_id == 516 )
+      {
+        if ( !shoulder )
+          return sprintf(pOut, "item%3.3dv%d", 234, index);
+        if ( shoulder == 1 )
+          return sprintf(pOut, "item%3.3dv%da1", 234, index);
+        if ( shoulder == 2 )
+          return sprintf(pOut, "item%3.3dv%da2", 234, index);
+      }
+      if ( item_id != 504 && item_id != 505 && item_id != 533 )
+      {
+        if ( (item_id < 100 || item_id > 104) && item_id != 524 && item_id != 535 )
+        {
+          if ( item_id >= 115 && item_id <= 119 || item_id == 512 )
+          {
+            if ( item_id == 512 )
+              item_id = 312;
+            return sprintf(pOut, "item%3.3dv%d", item_id, index);
+          }
+          if ( (item_id < 89 || item_id > 99) && item_id != 521 && item_id != 522 && item_id != 523 && item_id != 532 && item_id != 544 )
+          {
+            result = 525;
+            if ( (item_id < 105 || item_id > 109) && item_id != 525 && item_id != 530 && item_id != 547 && item_id != 548 && item_id != 550 )
+              return result;
+            switch ( item_id )
+            {
+              case 525:
+                item_id = 325;
+                break;
+              case 530:
+                item_id = 330;
+                break;
+              case 547:
+                item_id = 347;
+                break;
+              case 548:
+                item_id = 348;
+                break;
+              case 550:
+                item_id = 350;
+                break;
+            }
+            if ( !shoulder )
+              return sprintf(pOut, "item%3.3dv%d", item_id, index);
+            return sprintf(pOut, "item%3.3dv%da1", item_id, index);
+          }
+          if ( item_id == 521 )
+            return sprintf(pOut, "item%3.3dv%d", 239, index);
+          if ( item_id == 522 )
+            return sprintf(pOut, "item%3.3dv%d", 240, index);
+          if ( item_id == 523 )
+            return sprintf(pOut, "item%3.3dv%d", 241, index);
+          if ( item_id != 532 )
+          {
+            if ( item_id == 544 )
+              item_id = 344;
+            return sprintf(pOut, "item%3.3dv%d", item_id, index);
+          }
+          return sprintf(pOut, "item%3.3dv%d", 93, index);
+        }
+        if ( item_id == 524 )
+          return sprintf(pOut, "item%3.3dv%d", 324, index);
+        if ( item_id == 535 )
+          item_id = 104;
+        return sprintf(pOut, "item%3.3dv%d", item_id, index);
+      }
+    }
+    if ( item_id != 516 )
+    {
+      switch ( item_id )
+      {
+        case 504:
+          item_id = 235;
+          break;
+        case 505:
+          item_id = 236;
+          break;
+        case 533:
+          item_id = 73;
+          break;
+      }
+      if ( !shoulder )
+        return sprintf(pOut, "item%3.3dv%d", item_id, index);
+      if ( shoulder == 1 )
+        return sprintf(pOut, "item%3.3dv%da1", item_id, index);
+      if ( shoulder == 2 )
+        return sprintf(pOut, "item%3.3dv%da2", item_id, index);
+    }
+    if ( !shoulder )
+      return sprintf(pOut, "item%3.3dv%d", 234, index);
+    if ( shoulder == 1 )
+      return sprintf(pOut, "item%3.3dv%da1", 234, index);
+    if ( shoulder == 2 )
+      return sprintf(pOut, "item%3.3dv%da2", 234, index);
+  }
+  result = item_id - 504;
+  return result;
+}
 
--- a/Keyboard.cpp	Sun Jun 23 14:27:32 2013 +0600
+++ b/Keyboard.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -9,10 +9,13 @@
 #include "OSInfo.h"
 
 #include "mm7_data.h"
-
-
-
-
+#include "Vis.h"
+#include "MM7.h"
+#include "Actor.h"
+#include "DecorationList.h"
+#include "Indoor.h"
+#include "viewport.h"
+#include "AudioPlayer.h"
 
 
 struct KeyboardActionMapping *pKeyActionMap;
@@ -958,3 +961,144 @@
 {
   return GetAsyncKeyState(vKey) & 1;
 }
+//----- (0046A14B) --------------------------------------------------------
+void OnPressSpace()
+{
+  //SHORT v0; // ax@2
+  int *v1; // eax@2
+  char *v2; // ebx@5
+  unsigned int v3; // esi@5
+  signed int v4; // edi@7
+  unsigned int v5; // edx@7
+  int v6; // ecx@8
+  int v7; // eax@8
+  int v8; // ecx@17
+  int *v9; // esi@22
+  signed int v10; // ebx@22
+  int i; // edi@23
+  int v12; // edx@24
+  int v13; // ecx@24
+  int j; // esi@28
+  int v16; // [sp+4h] [bp-1Ch]@0
+  char *v17; // [sp+8h] [bp-18h]@5
+  unsigned int v18; // [sp+Ch] [bp-14h]@5
+  int v19; // [sp+10h] [bp-10h]@8
+  int *v20; // [sp+14h] [bp-Ch]@5
+  int *v21; // [sp+18h] [bp-8h]@7
+  int v22; // [sp+1Ch] [bp-4h]@4
+
+  if ( pRenderer->pRenderD3D )
+  {
+    pGame->PickKeyboard(GetAsyncKeyState(VK_CONTROL) & 0x8001, &vis_sprite_filter_3, &vis_door_filter);
+    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
+  if ( (signed int)viewparams->uScreen_topL_Y < (signed int)viewparams->uScreen_BttmR_Y )
+  {
+	  v2 = (char *)v1 - 50;
+	  v1 = (int *)((char *)v1 + 50);
+	  v3 = 640 * viewparams->uScreen_topL_Y;
+	  v17 = v2;
+	  v20 = v1;
+	  v18 = ((viewparams->uScreen_BttmR_Y - viewparams->uScreen_topL_Y - 1) >> 1) + 1;
+	  do
+	  {
+		if ( (signed int)v2 < (signed int)v20 )
+		{
+			v1 = &pRenderer->pActiveZBuffer[(int)&v2[v3]];
+			v21 = &pRenderer->pActiveZBuffer[(int)&v2[v3]];
+			v4 = v22;
+			v5 = (((char *)v20 - v2 - 1) >> 1) + 1;
+			do
+			{
+			  v6 = 0;
+			  v7 = *v1 & 0xFFFF;
+			  v19 = 0;
+			  if ( v4 > 0 )
+			  {
+				do
+				{
+				  if ( dword_7207F0[v6] == v7 )
+					break;
+				  ++v6;
+				  v19 = v6;
+				}
+				while ( v6 < v22 );
+			  }
+			  if ( PID_TYPE(v7) == OBJECT_Decoration)
+			  {
+				v16 = (unsigned int)PID_ID(v7);
+				if ( (signed int)(((unsigned int)*v21 >> 16)
+								- pDecorationList->pDecorations[pLevelDecorations[(unsigned int)PID_ID(v7)].uDecorationDescID].uRadius) <= 512 )
+				  if ( v19 == v22 && v4 < 100 )
+				  {
+					++v22;
+					++v4;
+					v8 = *v21;
+					dword_7207F0[v4 - 1] = v7;
+					dword_720660[v4 - 1] = v8;
+				  }
+			  }
+			  else if ( (unsigned int)*v21 <= 0x2000000 )
+			  {
+				  if ( v19 == v22 && v4 < 100 )
+				  {
+					++v22;
+					++v4;
+					v8 = *v21;
+					dword_7207F0[v4 - 1] = v7;
+					dword_720660[v4 - 1] = v8;
+				  }
+			  }
+			  v1 = v21 + 2;
+			  --v5;
+			  v21 += 2;
+			}
+			while ( v5 );
+			v2 = v17;
+		}
+		v3 += 1280;
+		--v18;
+	  }
+	  while ( v18 );
+  }
+  if ( v22 > 0 )
+  {
+    v9 = dword_720660;
+    v10 = 1;
+    do
+    {
+      for ( i = v10; i < v22; ++i )
+      {
+        v12 = *v9;
+        v13 = dword_720660[i];
+        if ( v13 < *v9 )
+        {
+          *v9 = v13;
+          dword_720660[i] = v12;
+        }
+      }
+      ++v10;
+      ++v9;
+      LOBYTE(v1) = v10 - 1;
+    }
+    while ( v10 - 1 < v22 );
+  }
+  for ( j = 0; j < v22; ++j )
+  {
+    LOBYTE(v1) = DoInteractionWithTopmostZObject(dword_720660[j] & 0xFFFF, v16);
+    if ( !(char)v1 )
+      break;
+  }
+}
--- a/LOD.cpp	Sun Jun 23 14:27:32 2013 +0600
+++ b/LOD.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -2947,3 +2947,57 @@
 //  }
 //  return v4;
 }
+//----- (0046082C) --------------------------------------------------------
+bool Initialize_GamesLOD_NewLOD()
+{
+  pGames_LOD = new LODWriteableFile;
+  pGames_LOD->AllocSubIndicesAndIO(300, 0);
+  if (pGames_LOD->LoadFile("data\\games.lod", 1))
+  {
+    pNew_LOD = new LODWriteableFile;
+    pNew_LOD->AllocSubIndicesAndIO(300, 100000);
+    return true;
+  }
+  return false;
+}
+//----- (00460706) --------------------------------------------------------
+void TryLoadLevelFromLOD()
+{
+  FILE *v0; // eax@1
+  FILE *v1; // esi@1
+  __int32 v2; // edi@2
+  char Ext[256]; // [sp+4h] [bp-40Ch]@1
+  char Dir[256]; // [sp+104h] [bp-30Ch]@1
+  char Filename[256]; // [sp+204h] [bp-20Ch]@1
+  char a1[260]; // [sp+304h] [bp-10Ch]@1
+  char Drive[4]; // [sp+408h] [bp-8h]@1
+  int DstBuf; // [sp+40Ch] [bp-4h]@2
+
+  strcpy(a1, pCurrentMapName.data());
+  _splitpath(a1, Drive, Dir, Filename, Ext);
+  sprintf(a1, "levels\\%s%s", Filename, ".lod");
+  v0 = fopen(a1, "rb");
+  v1 = v0;
+  if ( v0 )
+  {
+    fseek(v0, 0, 2);
+    v2 = ftell(v1);
+    rewind(v1);
+    ptr_6A0D08 = pAllocator->AllocNamedChunk(ptr_6A0D08, v2, "LevelLod");
+    fread(ptr_6A0D08, v2, 1u, v1);
+    fseek(v1, v2 - 6, 0);
+    DstBuf = 0;
+    fread(&DstBuf, 4u, 1u, v1);
+    fread(&_6A0D10_txt_lod_loading__unused, 2u, 1u, v1);
+    _6A0D0C_txt_lod_loading = (int)((char *)ptr_6A0D08 + DstBuf);
+    fclose(v1);
+  }
+}
+
+//----- (0046080D) --------------------------------------------------------
+void __cdecl sub_46080D()
+{
+  pAllocator->FreeChunk(ptr_6A0D08);
+  ptr_6A0D08 = 0;
+  _6A0D0C_txt_lod_loading = 0;
+}
--- a/Log.cpp	Sun Jun 23 14:27:32 2013 +0600
+++ b/Log.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -32,3 +32,20 @@
   WriteConsole(hStdOut, L"\r\n", 2, &w, nullptr);
 }
 
+//----- (004BE386) --------------------------------------------------------
+void __fastcall log_error(const char *pMessage)
+{
+  const char *v1; // edi@1
+  FILE *f; // eax@1
+  FILE *v3; // esi@1
+
+  v1 = pMessage;
+  f = fopen("errorlog.txt", "a");
+  v3 = f;
+  if ( f )
+  {
+    fprintf(f, "%s\n", v1);
+    fclose(v3);
+    fflush(v3);
+  }
+}
\ No newline at end of file
--- a/Monsters.cpp	Sun Jun 23 14:27:32 2013 +0600
+++ b/Monsters.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -1173,3 +1173,85 @@
     }
     assert(false && "Monster not found!");
 }
+//----- (00438BDF) --------------------------------------------------------
+bool MonsterStats::BelongsToSupertype(unsigned int uMonsterInfoID, enum MONSTER_SUPERTYPE eSupertype)
+{
+  unsigned __int8 v2; // zf@15
+  char v3; // sf@15
+  unsigned __int8 v4; // of@15
+  bool result; // eax@33
+
+  switch ( eSupertype )
+  {
+    case MONSTER_SUPERTYPE_UNDEAD:
+      if ( (signed int)uMonsterInfoID >= MONSTER_GHOST_1 && (signed int)uMonsterInfoID <= MONSTER_GHOST_3
+        || (signed int)uMonsterInfoID >= MONSTER_LICH_1 && (signed int)uMonsterInfoID <= MONSTER_LICH_3
+        || (signed int)uMonsterInfoID >= MONSTER_SKELETON_1 && (signed int)uMonsterInfoID <= MONSTER_SKELETON_3
+        || (signed int)uMonsterInfoID >= MONSTER_VAMPIRE_1 && (signed int)uMonsterInfoID <= MONSTER_VAMPIRE_3
+        || (signed int)uMonsterInfoID >= MONSTER_WIGHT_1 && (signed int)uMonsterInfoID <= MONSTER_WIGHT_3
+        || (signed int)uMonsterInfoID >= MONSTER_ZOMBIE_1 && (signed int)uMonsterInfoID <= MONSTER_ZOMBIE_3 )
+        goto ret_true;
+      if ( (signed int)uMonsterInfoID < MONSTER_GHOUL_1 )
+        goto ret_false;
+      v4 = __OFSUB__(uMonsterInfoID, (int)MONSTER_GHOUL_3);
+      v2 = uMonsterInfoID == MONSTER_GHOUL_3;
+      v3 = ((uMonsterInfoID - MONSTER_GHOUL_3) & 0x80000000u) != 0;
+      goto false_if_outside;
+    case MONSTER_SUPERTYPE_KREEGAN:
+      if ( (signed int)uMonsterInfoID < MONSTER_DEVIL_1 )
+        goto ret_false;
+      v4 = __OFSUB__(uMonsterInfoID, (int)MONSTER_DEVIL_3);
+      v2 = uMonsterInfoID == MONSTER_DEVIL_3;
+      v3 = ((uMonsterInfoID - MONSTER_DEVIL_3) & 0x80000000u) != 0;
+      goto false_if_outside;
+    case MONSTER_SUPERTYPE_ELF:
+      if ( (signed int)uMonsterInfoID >= MONSTER_PEASANT_ELF_FEMALE_1_1
+        && (signed int)uMonsterInfoID <= MONSTER_PEASANT_ELF_MALE_3_3
+        || (signed int)uMonsterInfoID >= MONSTER_ELF_ARCHER_1 && (signed int)uMonsterInfoID <= MONSTER_ELF_ARCHER_3 )
+        goto ret_true;
+      if ( (signed int)uMonsterInfoID < MONSTER_ELF_SPEARMAN_1 )
+        goto ret_false;
+      v4 = __OFSUB__(uMonsterInfoID, (int)MONSTER_ELF_SPEARMAN_3);
+      v2 = uMonsterInfoID == MONSTER_ELF_SPEARMAN_3;
+      v3 = ((uMonsterInfoID - MONSTER_ELF_SPEARMAN_3) & 0x80000000u) != 0;
+      goto false_if_outside;
+    case MONSTER_SUPERTYPE_DRAGON:
+      if ( (signed int)uMonsterInfoID < MONSTER_DRAGON_1 )
+        goto ret_false;
+      v4 = __OFSUB__(uMonsterInfoID, (int)MONSTER_DRAGON_3);
+      v2 = uMonsterInfoID == MONSTER_DRAGON_3;
+      v3 = ((uMonsterInfoID - MONSTER_DRAGON_3) & 0x80000000u) != 0;
+      goto false_if_outside;
+    case MONSTER_SUPERTYPE_WATER_ELEMENTAL:
+      if ( (signed int)uMonsterInfoID < MONSTER_ELEMENTAL_WATER_1 )
+        goto ret_false;
+      v4 = __OFSUB__(uMonsterInfoID, (int)MONSTER_ELEMENTAL_WATER_3);
+      v2 = uMonsterInfoID == MONSTER_ELEMENTAL_WATER_3;
+      v3 = ((uMonsterInfoID - MONSTER_ELEMENTAL_WATER_3) & 0x80000000u) != 0;
+      goto false_if_outside;
+    case MONSTER_SUPERTYPE_TREANT:
+      if ( (signed int)uMonsterInfoID < MONSTER_TREANT_1 )
+        goto ret_false;
+      v4 = __OFSUB__(uMonsterInfoID, (int)MONSTER_TREANT_3);
+      v2 = uMonsterInfoID == MONSTER_TREANT_3;
+      v3 = ((uMonsterInfoID - MONSTER_TREANT_3) & 0x80000000u) != 0;
+      goto false_if_outside;
+    case MONSTER_SUPERTYPE_TITAN:
+      if ( (signed int)uMonsterInfoID < MONSTER_TITAN_1 )
+        goto ret_false;
+      v4 = __OFSUB__(uMonsterInfoID, (int)MONSTER_TITAN_3);
+      v2 = uMonsterInfoID == MONSTER_TITAN_3;
+      v3 = ((uMonsterInfoID - MONSTER_TITAN_3) & 0x80000000u) != 0;
+false_if_outside:
+      if ( !((unsigned __int8)(v3 ^ v4) | v2) )
+        goto ret_false;
+ret_true:
+      result = 1;
+      break;
+    default:
+ret_false:
+      result = 0;
+      break;
+  }
+  return result;
+}
\ No newline at end of file
--- a/Mouse.cpp	Sun Jun 23 14:27:32 2013 +0600
+++ b/Mouse.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -13,9 +13,13 @@
 #include "Game.h"
 
 #include "stru11.h"
-
-
-
+#include "TurnEngine.h"
+#include "Viewport.h"
+#include "GUIWindow.h"
+#include "Vis.h"
+#include "Actor.h"
+#include "MM7.h"
+#include "AudioPlayer.h"
 
 
 Mouse *pMouse;
@@ -502,4 +506,413 @@
   uMouseClickX = x;
   uMouseClickY = y;
 }
+//----- (004175C0) --------------------------------------------------------
+void UI_OnMouseLeftClick(int *pXY)
+{
+  int *pXY_; // esi@1
+  signed int y; // eax@7
+  signed int x; // ecx@7
+  unsigned int v4; // eax@11
+  signed int v5; // eax@17
+  signed int v6; // esi@19
+  int v7; // esi@30
+  GUIWindow *v8; // edx@31
+  GUIButton *i; // esi@37
+  signed int v10; // eax@50
+  int v11; // ecx@52
+  unsigned int pX; // [sp+14h] [bp-8h]@7
+  unsigned int pY; // [sp+18h] [bp-4h]@7
 
+  pXY_ = pXY;
+  if ( pCurrentScreen == SCREEN_VIDEO
+    || sub_4637E0_is_there_popup_onscreen() )
+    return;
+  if ( pGUIWindow2 && pGUIWindow2->ptr_1C == (void *)33 )
+  {
+    sub_4452BB();
+    return;
+  }
+  if ( pXY_ )
+  {
+    x = *pXY_;
+    y = pXY_[1];
+    pX = *pXY_;
+    pY = y;
+  }
+  else
+  {
+    pMouse->GetClickPos(&pX, &pY);
+    y = pY;
+    x = pX;
+  }
+  if ( pCurrentScreen != SCREEN_GAME || !dword_507B98_ctrl_pressed )
+    goto LABEL_30;
+  v4 = GetCurrentMenuID();
+  x = pX;
+  if ( (v4 & 0x80000000u) == 0
+    || (signed int)pX < (signed int)pViewport->uViewportTL_X
+    || (signed int)pX > (signed int)pViewport->uViewportBR_X )
+  {
+    y = pY;
+LABEL_30:
+    v7 = uNumVisibleWindows;
+    if ( uNumVisibleWindows < 0 )
+      return;
+    while ( 1 )
+    {
+      //v8 = (GUIWindow *)&pWindowList_at_506F50_minus1_indexing[21 * pVisibleWindowsIdxs[v7]];
+      v8 = &pWindowList[pVisibleWindowsIdxs[v7] - 1];
+      if ( x >= (signed int)v8->uFrameX )
+      {
+        if ( x <= (signed int)v8->uFrameZ && y >= (signed int)v8->uFrameY && y <= (signed int)v8->uFrameW )
+          break;
+      }
+      --v7;
+      if ( v7 < 0 )
+        return;
+    }
+    for ( i = v8->pControlsHead; ; i = i->pNext )
+    {
+      if ( !i )
+        return;
+      if ( i->uButtonType == 1 )
+        goto LABEL_41;
+      if ( i->uButtonType != 2 )
+        break;
+      if ( (signed int)(signed __int64)sqrt((double)((x - i->uX) * (x - i->uX) + (y - i->uY) * (y - i->uY))) < (signed int)i->uWidth )
+        goto LABEL_50;
+      y = pY;
+      x = pX;
+LABEL_45:
+      ;
+    }
+    if ( i->uButtonType != 3 )
+      goto LABEL_45;
+LABEL_41:
+    if ( x >= (signed int)i->uX && x <= (signed int)i->uZ && y >= (signed int)i->uY && y <= (signed int)i->uW )
+    {
+LABEL_50:
+      i->field_2C_is_pushed = 1;
+      v10 = pMessageQueue_50CBD0->uNumMessages;
+      if ( pMessageQueue_50CBD0->uNumMessages )
+      {
+        v10 = pMessageQueue_50CBD0->pMessages[0].field_8 != 0;
+        pMessageQueue_50CBD0->uNumMessages = pMessageQueue_50CBD0->pMessages[0].field_8 != 0;
+      }
+      //v11 = i->uControlParam;
+      pMessageQueue_50CBD0->AddMessage(i->msg, i->msg_param, 0);
+      return;
+    }
+    goto LABEL_45;
+  }
+  y = pY;
+  if ( (signed int)pY < (signed int)pViewport->uViewportTL_Y || (signed int)pY > (signed int)pViewport->uViewportBR_Y )
+    goto LABEL_30;
+  if ( pRenderer->pRenderD3D )
+    v5 = pGame->pVisInstance->get_picked_object_zbuf_val();
+  else
+    v5 = pRenderer->pActiveZBuffer[pX + pSRZBufferLineOffsets[pY]];
+  v6 = (unsigned __int16)v5;
+  if (PID_TYPE(v5) == OBJECT_Actor
+    && uActiveCharacter
+    && v5 < 0x2000000
+    && pPlayers[uActiveCharacter]->CanAct()
+    && pPlayers[uActiveCharacter]->CanSteal() )
+  {
+    /*if ( (signed int)pMessageQueue_50CBD0->uNumMessages < 40 )
+    {
+      pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].eType = UIMSG_1B;
+      pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = v6 >> 3;
+      *(&pMessageQueue_50CBD0->uNumMessages + 3 * pMessageQueue_50CBD0->uNumMessages + 3) = 0;
+      ++pMessageQueue_50CBD0->uNumMessages;
+    }*/
+    pMessageQueue_50CBD0->AddMessage(UIMSG_1B, PID_ID(v6), 0);
+
+    if ( pParty->bTurnBasedModeOn == 1 )
+    {
+      if ( pTurnEngine->field_4 == 3 )
+        pTurnEngine->field_18 |= 8u;
+    }
+  }
+}
+
+
+
+//----- (00417871) --------------------------------------------------------
+void __thiscall sub_417871(int *pXY)
+{
+  POINT v1; // [sp+0h] [bp-18h]@5
+  POINT a2; // [sp+8h] [bp-10h]@5
+  unsigned int pY; // [sp+10h] [bp-8h]@3
+  unsigned int pX; // [sp+14h] [bp-4h]@3
+
+  if ( !pRenderer->pRenderD3D )
+  {
+    if ( pXY )
+    {
+      pX = *pXY;
+      pY = pXY[1];
+    }
+    else
+    {
+      pMouse->GetClickPos(&pX, &pY);
+    }
+    pMouse->GetCursorPos(&a2);
+    pMouse->GetCursorPos(&v1);
+  }
+}
+//----- (0041CD4F) --------------------------------------------------------
+bool UI_OnKeyDown(unsigned int vkKey)
+{
+  //unsigned int v1; // edi@1
+  //unsigned int v2; // eax@2
+  int v3; // esi@3
+  int v4; // ecx@10
+  GUIButton *pButton; // eax@11
+  int v6; // edx@12
+  int v7; // ecx@20
+  char v8; // zf@21
+  //GUIButton *v9; // ecx@24
+  int v10; // esi@24
+  //int v11; // edx@26
+  int v12; // edx@28
+  int v13; // esi@32
+  //GUIButton *v14; // eax@37
+  int v15; // edx@38
+  int v17; // ecx@50
+  int v18; // edx@50
+  //GUIButton *v19; // ecx@54
+  int v20; // esi@54
+  //int v21; // edx@56
+  int v22; // ecx@59
+  int v23; // edx@59
+  int v24; // ecx@60
+  int v25; // esi@63
+  //unsigned int v26; // [sp+Ch] [bp-14h]@1
+  //int v27; // [sp+10h] [bp-10h]@1
+  int v28; // [sp+14h] [bp-Ch]@10
+  int v29; // [sp+14h] [bp-Ch]@36
+  unsigned int uClickX; // [sp+18h] [bp-8h]@10
+  unsigned int uClickY; // [sp+1Ch] [bp-4h]@10
+
+  //v1 = 0;
+  //v27 = uNumVisibleWindows;
+  if ( uNumVisibleWindows < 0 )
+    return false;
+  //v2 = pMessageQueue_50CBD0->uNumMessages;
+  for (int i = uNumVisibleWindows; i >= 0; --i)
+  //while ( 1 )
+  {
+    v3 = pVisibleWindowsIdxs[i] - 1;
+    if (!pWindowList[v3].receives_keyboard_input)
+      continue;
+
+    switch (vkKey)
+    {
+      case VK_LEFT:
+      {
+        v12 = pWindowList[v3].field_34;
+        if ( pWindowList[v3].pCurrentPosActiveItem - pWindowList[v3].pStartingPosActiveItem - v12 >= 0 )
+        {
+          v8 = pCurrentScreen == SCREEN_PARTY_CREATION;
+          pWindowList[v3].pCurrentPosActiveItem -= v12;
+          if ( v8 )
+          {
+            pAudioPlayer->PlaySound(SOUND_Button, 0, 0, -1, 0, 0, 0, 0);
+            //v2 = pMessageQueue_50CBD0->uNumMessages;
+          }
+        }
+        if ( pWindowList[v3].field_30 != 0 )
+        {
+          break;
+        }
+        pButton = pWindowList[v3].pControlsHead;
+        v13 = pWindowList[v3].pCurrentPosActiveItem;
+        if ( v13 > 0)
+        {
+          do
+          {
+            pButton = pButton->pNext;
+            --v13;
+          }
+          while ( v13 );
+        }
+        pMessageQueue_50CBD0->AddMessage(pButton->msg, pButton->msg_param, 0);
+        break;
+      }
+      case VK_RIGHT:
+      {
+        v7 = pWindowList[v3].pCurrentPosActiveItem + pWindowList[v3].field_34;
+        if ( v7 < pWindowList[v3].pNumPresenceButton + pWindowList[v3].pStartingPosActiveItem )
+        {
+          v8 = pCurrentScreen == SCREEN_PARTY_CREATION;
+          pWindowList[v3].pCurrentPosActiveItem = v7;
+          if ( v8 )
+          {
+            pAudioPlayer->PlaySound(SOUND_Button, 0, 0, -1, 0, 0, 0, 0);
+            //v2 = pMessageQueue_50CBD0->uNumMessages;
+          }
+        }
+        if ( pWindowList[v3].field_30 != 0 )
+        {
+          break;
+        }
+        pButton = pWindowList[v3].pControlsHead;
+        v10 = pWindowList[v3].pCurrentPosActiveItem;
+        if ( v10 > 0)
+        {
+          do
+          {
+            pButton = pButton->pNext;
+            --v10;
+          }
+          while ( v10 );
+        }
+        pMessageQueue_50CBD0->AddMessage(pButton->msg, pButton->msg_param, 0);
+        break;
+      }
+      case VK_DOWN:
+      {
+        v17 = pWindowList[v3].pStartingPosActiveItem;
+        v18 = pWindowList[v3].pCurrentPosActiveItem;
+        if ( v18 >= pWindowList[v3].pNumPresenceButton + v17 - 1 )
+          pWindowList[v3].pCurrentPosActiveItem = v17;
+        else
+          pWindowList[v3].pCurrentPosActiveItem = v18 + 1;
+        if ( pWindowList[v3].field_30 != 0 )
+          return true;
+        pButton = pWindowList[v3].pControlsHead;
+        v20 = pWindowList[v3].pCurrentPosActiveItem;
+        if ( v20 > 0)
+        {
+          do
+          {
+            pButton = pButton->pNext;
+            --v20;
+          }
+          while ( v20 );
+        }
+        pMessageQueue_50CBD0->AddMessage(pButton->msg, pButton->msg_param, 0);
+        return true;
+      }
+      case VK_SELECT:
+      {
+        pMouse->GetClickPos(&uClickX, &uClickY);
+        v4 = pWindowList[v3].pStartingPosActiveItem;
+        v28 = v4 + pWindowList[v3].pNumPresenceButton;
+        if ( v4 < v4 + pWindowList[v3].pNumPresenceButton )
+        {
+          while ( 1 )
+          {
+            pButton = pWindowList[v3].pControlsHead;
+            if ( v4 > 0 )
+            {
+              v6 = v4;
+              do
+              {
+                pButton = pButton->pNext;
+                --v6;
+              }
+              while ( v6 );
+            }
+            if ( (signed int)uClickX >= (signed int)pButton->uX//test for StatsTab in PlayerCreation Window
+               && (signed int)uClickX <= (signed int)pButton->uZ
+               && (signed int)uClickY >= (signed int)pButton->uY
+               && (signed int)uClickY <= (signed int)pButton->uW )
+              break;
+            ++v4;
+            if ( v4 >= v28 )
+            {
+              //v1 = 0;
+              //v2 = pMessageQueue_50CBD0->uNumMessages;
+              //--i;
+              //if ( i < 0 )
+                return false;
+              //continue;
+            }
+          }
+          pWindowList[v3].pCurrentPosActiveItem = v4;
+          return true;
+        }
+        //v2 = pMessageQueue_50CBD0->uNumMessages;
+        break;
+      }
+      case VK_UP:
+      {
+        v22 = pWindowList[v3].pCurrentPosActiveItem;
+        v23 = pWindowList[v3].pStartingPosActiveItem;
+        if ( v22 <= v23 )
+          v24 = pWindowList[v3].pNumPresenceButton + v23 - 1;
+        else
+          v24 = v22 - 1;
+        v8 = pWindowList[v3].field_30 == 0;
+        pWindowList[v3].pCurrentPosActiveItem = v24;
+        if ( !v8 )
+          return true;
+        pButton = pWindowList[v3].pControlsHead;
+        v25 = pWindowList[v3].pCurrentPosActiveItem;
+        if ( v25 > 0)
+        {
+          do
+          {
+            pButton = pButton->pNext;
+            --v25;
+          }
+          while ( v25 );
+        }
+        pMessageQueue_50CBD0->AddMessage(pButton->msg, pButton->msg_param, 0);
+        return true;
+      }
+      case VK_NEXT:
+      {  
+        //if ( pWindowList[v3].field_30 != 0 )   //crashed at skill draw
+        //{
+        //  pMouse->GetClickPos(&uClickX, &uClickY);
+        //  v4 = pWindowList[v3].pStartingPosActiveItem;
+        //  v29 = v4 + pWindowList[v3].pNumPresenceButton; //num buttons more than buttons 
+        //  if ( v4 < v29 )
+        //  {
+        //    while ( 1 )
+        //    {
+        //      pButton = pWindowList[v3].pControlsHead;
+        //      if ( v4 > 0 )
+        //      {
+        //        v15 = v4;
+        //        do
+        //        {
+        //          pButton = pButton->pNext;
+        //          --v15;
+        //        }
+        //        while ( v15 );
+        //      }
+        //      if ( (signed int)uClickX >= (signed int)pButton->uX
+        //        && (signed int)uClickX <= (signed int)pButton->uZ
+        //        && (signed int)uClickY >= (signed int)pButton->uY
+        //        && (signed int)uClickY <= (signed int)pButton->uW )
+        //      {
+        //        pWindowList[v3].pCurrentPosActiveItem = v4;
+        //        return true;
+        //      }
+        //      ++v4;
+        //      if ( v4 >= v29 )
+        //      {
+        //        //v1 = 0;
+        //        //v2 = pMessageQueue_50CBD0->uNumMessages;
+        //        break;
+        //      }
+        //    }
+        //  }
+        //  else
+        //  {
+        //    //v2 = pMessageQueue_50CBD0->uNumMessages;
+        //  }
+        //}
+        break;
+      }
+      default:
+      {
+        break;
+      }
+    }
+  }
+}
\ No newline at end of file
--- a/NPC.cpp	Sun Jun 23 14:27:32 2013 +0600
+++ b/NPC.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -11,6 +11,12 @@
 #include "MM7.h"
 #include "Party.h"
 #include "NPC.h"
+#include "GUIWindow.h"
+#include "VideoPlayer.h"
+#include "Events.h"
+#include "UI\UIHouses.h"
+#include "Indoor.h"
+#include "MapInfo.h"
 
 int pDialogueNPCCount;
 std::array<struct Texture *, 6> pDialogueNPCPortraits;
@@ -1270,3 +1276,606 @@
 		}
 	}
 
+//----- (004B2001) --------------------------------------------------------
+void __fastcall ClickNPCTopic(signed int uMessageParam)
+{
+  //signed int v1; // eax@1
+  NPCData *pCurrentNPCInfo; // ebp@1
+  int pEventNumber; // ecx@8
+  Player *v4; // esi@20
+  //int v5; // eax@28
+  //int v6; // eax@31
+  //int v7; // eax@34
+  //int v8; // eax@37
+  //int v9; // eax@40
+  //unsigned int v10; // eax@43
+  char *v12; // eax@53
+  char *v13; // eax@56
+  char *v14; // eax@57
+  char *v15; // eax@58
+  //unsigned int v16; // ebp@62
+  char *v17; // ecx@63
+  char *v18; // eax@65
+  const char *v19; // ecx@68
+  //unsigned int v20; // eax@69
+  signed int pPrice; // ecx@70
+  char *v22; // [sp-Ch] [bp-18h]@73
+  //int v23; // [sp-8h] [bp-14h]@49
+  char *v24; // [sp-8h] [bp-14h]@73
+  //int v25; // [sp-4h] [bp-10h]@49
+
+  uDialogueType = uMessageParam + 1;
+  pCurrentNPCInfo = HouseNPCData[(unsigned int)((char *)pDialogueNPCCount + -(dword_591080 != 0) )];//- 1
+  if ( uMessageParam <= 24 )
+  {
+  switch ( uMessageParam )
+  {
+    case 13:
+      current_npc_text = pNPCStats->pProfessions[pCurrentNPCInfo->uProfession].pJoinText;//(char *)*(&pNPCStats->field_13A64 + 5 * v2->uProfession);
+      current_npc_text = BuilDialogueString((char *)current_npc_text, uActiveCharacter - 1, 0, 0, 0, 0);
+      NPCHireableDialogPrepare();
+      dialogue_show_profession_details = false;
+      goto _return;
+    case 19:
+      pEventNumber = pCurrentNPCInfo->evt_A;
+      break;
+    case 20:
+      pEventNumber = pCurrentNPCInfo->evt_B;
+      break;
+    case 21:
+      pEventNumber = pCurrentNPCInfo->evt_C;
+      break;
+    case 22:
+      pEventNumber = pCurrentNPCInfo->evt_D;
+      break;
+    case 23:
+      pEventNumber = pCurrentNPCInfo->evt_E;
+      break;
+    case 24:
+      pEventNumber = pCurrentNPCInfo->evt_F;
+      break;
+    default:
+      goto _return;
+  }
+  /*switch ( pEventNumber )
+  {
+    case 139:
+      sub_4B1ECE();
+      goto _return;
+    case 311:
+      sub_4BBA85_bounties();
+    goto _return;
+  }*/
+  if ( pEventNumber < 200 || pEventNumber > 310 )
+    {
+      if ( pEventNumber < 400 || pEventNumber > 410 )
+      {
+        if ( pEventNumber == 139 )
+        {
+          sub_4B1ECE();
+        }
+        else
+        { 
+          if ( pEventNumber == 311 )
+          {
+            sub_4BBA85_bounties();
+          }
+          else
+          {
+            current_npc_text = 0;
+            activeLevelDecoration = (LevelDecoration*)1;
+            EventProcessor(pEventNumber, 0, 1);
+            activeLevelDecoration = NULL;
+          }
+        }
+      }
+      else
+      {
+        dword_F8B1D8 = uMessageParam;
+        DrawJoinGuildWindow(pEventNumber - 400);
+      }
+    }
+    else
+    {
+      sub_4B3FE5(pEventNumber);
+    }
+    goto _return;
+  }
+  if ( uMessageParam != 76 )
+  {
+    if ( uMessageParam == 77 )
+    {
+      //v16 = pCurrentNPCInfo->uProfession;
+      if (dialogue_show_profession_details)
+        v17 = pNPCStats->pProfessions[pCurrentNPCInfo->uProfession - 1].pJoinText;
+      else
+        v17 = pNPCStats->pProfessions[pCurrentNPCInfo->uProfession - 1].pBenefits;
+      current_npc_text = v17;
+      v18 = BuilDialogueString(v17, uActiveCharacter - 1, 0, 0, 0, 0);
+      dialogue_show_profession_details = ~dialogue_show_profession_details;
+      current_npc_text = v18;
+    }
+    else
+    {
+      if ( uMessageParam == 79 )
+      {
+        if ( contract_approved )
+        {
+          Party::TakeGold(gold_transaction_amount);
+          if ( uActiveCharacter )
+          {
+            v12 = (char *)&pPlayers[uActiveCharacter]->pActiveSkills[dword_F8B1AC_award_bit_number];
+            *(short *)v12 &= 0x3Fu;
+            switch ( dword_F8B1B0 )
+            {
+              case 2:
+                v15 = (char *)&pPlayers[uActiveCharacter]->pActiveSkills[dword_F8B1AC_award_bit_number];
+                *v15 |= 0x40u;
+                break;
+              case 3:
+                v14 = (char *)&pPlayers[uActiveCharacter]->pActiveSkills[dword_F8B1AC_award_bit_number];
+                *v14 |= 0x80u;
+                break;
+              case 4:
+                v13 = (char *)&pPlayers[uActiveCharacter]->pActiveSkills[dword_F8B1AC_award_bit_number];
+                v13[1] |= 1u;
+                break;
+            }
+            pPlayers[uActiveCharacter]->PlaySound(SPEECH_85, 0);
+          }
+          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;
+          }*/
+        }
+      }
+      else
+      {
+        if ( uMessageParam == 82 && contract_approved ) //join guild
+        {
+          Party::TakeGold(gold_transaction_amount);
+          v4 = pParty->pPlayers;
+          do
+          {
+            v4->SetVariable(VAR_Award, dword_F8B1AC_award_bit_number);
+            ++v4;
+          }
+          while ( (signed int)v4 < (signed int)pParty->pHirelings );
+          switch ( dword_F8B1D8 )
+          {
+            case 19:
+              pEventNumber = pCurrentNPCInfo->evt_A;
+              if ( pEventNumber >= 400 && pEventNumber <= 416 )
+                pCurrentNPCInfo->evt_A = 0;
+              break;
+            case 20:
+              pEventNumber = pCurrentNPCInfo->evt_B;
+              if ( pEventNumber >= 400 && pEventNumber <= 416 )
+                pCurrentNPCInfo->evt_B = 0;
+              break;
+            case 21:
+              pEventNumber = pCurrentNPCInfo->evt_C;
+              if ( pEventNumber >= 400 && pEventNumber <= 416 )
+                pCurrentNPCInfo->evt_C = 0;
+              break;
+            case 22:
+              pEventNumber = pCurrentNPCInfo->evt_D;
+              if ( pEventNumber >= 400 && pEventNumber <= 416 )
+                pCurrentNPCInfo->evt_D = 0;
+              break;
+            case 23:
+              pEventNumber = pCurrentNPCInfo->evt_E;
+              if ( pEventNumber >= 400 && pEventNumber <= 416 )
+                pCurrentNPCInfo->evt_E = 0;
+              break;
+            case 24:
+              pEventNumber = pCurrentNPCInfo->evt_F;
+              if ( pEventNumber >= 400 && pEventNumber <= 416)
+                pCurrentNPCInfo->evt_F = 0;
+              break;
+          }
+          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;
+          }*/
+          //v11 = uActiveCharacter;
+          if ( uActiveCharacter )
+          {
+            pPlayers[uActiveCharacter]->PlaySound((PlayerSpeech)SPEECH_86, 0);
+            goto _return;
+          }
+        }
+      }
+    }
+    goto _return;
+  }
+  if ( pParty->pHirelings[0].pName && pParty->pHirelings[1].pName )
+  {
+    ShowStatusBarString(pGlobalTXT_LocalizationStrings[533], 2);// ""I cannot join you, you're party is full""
+    goto _return;
+  }
+  if ( pCurrentNPCInfo->uProfession != 51 )
+  {
+    pPrice = pNPCStats->pProfessions[pCurrentNPCInfo->uProfession - 1].uHirePrice;
+    if ( pParty->uNumGold < pPrice )
+    {
+      ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2);
+      dialogue_show_profession_details = false;
+      uDialogueType = 13;
+      current_npc_text = pNPCStats->pProfessions[pCurrentNPCInfo->uProfession - 1].pJoinText;
+      current_npc_text = BuilDialogueString((char *)current_npc_text, uActiveCharacter - 1, 0, 0, 0, 0);
+      if ( uActiveCharacter )
+        pPlayers[uActiveCharacter]->PlaySound(SPEECH_NotEnoughGold, 0);
+      ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2);
+      goto _return;
+    }
+    Party::TakeGold(pPrice);
+  }
+  //LOBYTE(v2->uFlags) |= 0x80u;
+  pCurrentNPCInfo->uFlags |= 128;
+  pParty->field_709 = 0;
+  pParty->CountHirelings();
+  if ( pParty->pHirelings[0].pName )
+  {
+    memcpy(&pParty->pHirelings[1], pCurrentNPCInfo, sizeof(pParty->pHirelings[1]));
+    v24 = pCurrentNPCInfo->pName;
+    v22 = pParty->pHireling2Name;
+  }
+  else
+  {
+    memcpy(pParty->pHirelings, pCurrentNPCInfo, 0x4Cu);
+    v24 = pCurrentNPCInfo->pName;
+    v22 = pParty->pHireling1Name;
+  }
+  strcpy(v22, v24);
+  pParty->field_709 = 0;
+  pParty->CountHirelings();
+  PrepareHouse((HOUSE_ID)(int)window_SpeakInHouse->ptr_1C);
+  dialog_menu_id = HOUSE_DIALOGUE_MAIN;
+
+  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;
+  }*/
+  if ( uActiveCharacter )
+    pPlayers[uActiveCharacter]->PlaySound((PlayerSpeech)61, 0);
+_return:
+  pVideoPlayer->_4BF5B2();//HouseVideo
+}
+//----- (004B29F2) --------------------------------------------------------
+const char * ContractSelectText( int pEventCode )
+{
+  static const int dialogue_base=110;
+  contract_approved = 0;
+  dword_F8B1AC_award_bit_number = pEventCode + 50;
+  gold_transaction_amount = price_for_membership[pEventCode];
+  if ( pPlayers[uActiveCharacter]->CanAct() )
+  {
+    if ( (unsigned __int16)_449B57_test_bit((unsigned __int8 *)pPlayers[uActiveCharacter]->_guilds_member_bits, dword_F8B1AC_award_bit_number) )
+    {
+      return pNPCTopics[dialogue_base+13].pText;
+    }
+    else
+    {
+      if ( gold_transaction_amount <= pParty->uNumGold )
+      {
+        contract_approved = 1;
+        return pNPCTopics[pEventCode + dialogue_base].pText;
+      }
+      else
+      {
+        return pNPCTopics[dialogue_base+14].pText; 
+      }
+    }
+  }
+  else
+  {
+    return pNPCTopics[dialogue_base+12].pText; 
+  }
+}
+//----- (004B40E6) --------------------------------------------------------
+void NPCHireableDialogPrepare()
+    {
+  signed int v0; // ebx@1
+  NPCData *v1; // edi@1
+
+  v0 = 0;
+  v1 = HouseNPCData[(unsigned int)((char *)pDialogueNPCCount + -(dword_591080 != 0) )];//- 1
+  pDialogueWindow->Release();
+  pDialogueWindow = GUIWindow::Create(0, 0, 640, 0x15Eu, WINDOW_MainMenu, 0, 0);
+  pBtn_ExitCancel = pDialogueWindow->CreateButton( 0x1D7u, 0x1BDu,  0xA9u,   0x23u,  1,  0,  UIMSG_Escape,  0,   0,
+                 pGlobalTXT_LocalizationStrings[34], //"Cancel"
+                 pIcons_LOD->GetTexture(uExitCancelTextureId),
+                 0);
+  pDialogueWindow->CreateButton(0, 0, 0, 0, 1, 0, UIMSG_BuyInShop_Identify_Repair, 0, 0, "", 0);
+  if ( pNPCStats->pProfessions[v1->uProfession].pBenefits)//*(&pNPCStats->field_13A5C + 5 * v1->uProfession) )
+  {
+    pDialogueWindow->CreateButton( 0x1E0u,  0xA0u,  0x8Cu,  0x1Eu,   1,  0,  UIMSG_ClickNPCTopic,  0x4Du,   0,
+      pGlobalTXT_LocalizationStrings[407], 0);//"More Information"   
+    v0 = 1;
+  }
+  pDialogueWindow->CreateButton(  0x1E0u,  30 * v0 + 160,  0x8Cu,  0x1Eu,  1,  0,  UIMSG_ClickNPCTopic,  0x4Cu,  0,
+    pGlobalTXT_LocalizationStrings[406],  0); //"Hire"
+  pDialogueWindow->_41D08F_set_keyboard_control_group(v0 + 1, 1, 0, 2);
+  dialog_menu_id = HOUSE_DIALOGUE_OTHER;
+}
+
+//----- (004B4224) --------------------------------------------------------
+void _4B4224_UpdateNPCTopics( int _this )
+	{
+  int num_menu_buttons; // ebx@1
+  int i; // ebp@5
+ // signed int v4; // ebp@9
+  int v6; // eax@16
+  int v8; // eax@21
+  int v10; // eax@26
+  int v12; // eax@31
+  int v14; // eax@36
+  int v16; // eax@41
+  NPCData *v17; // [sp+10h] [bp-4h]@4
+
+  num_menu_buttons = 0;
+  pDialogueNPCCount = (_this + 1);
+  if ( _this + 1 == uNumDialogueNPCPortraits && uHouse_ExitPic )
+  {
+    pDialogueWindow->Release();
+    pDialogueWindow = GUIWindow::Create(0, 0, 640, 480, WINDOW_MainMenu, 0, 0);
+    sprintfex(sHouseName.data(), pGlobalTXT_LocalizationStrings[LOCSTR_ENTER_S], pMapStats->pInfos[uHouse_ExitPic].pName);
+    pBtn_ExitCancel = pDialogueWindow->CreateButton(566, 445, 75, 33, 1, 0, UIMSG_Escape, 0, 'N', pGlobalTXT_LocalizationStrings[34], pIcons_LOD->GetTexture(uTextureID_BUTTDESC2), 0);// "Cancel"
+    pBtn_YES        = pDialogueWindow->CreateButton(486, 445, 75, 33, 1, 0, UIMSG_BF,     1, 'Y', sHouseName.data(), pIcons_LOD->GetTexture(uTextureID_BUTTYES2), 0);
+    pDialogueWindow->CreateButton( pNPCPortraits_x[0][0], pNPCPortraits_y[0][0], 63u, 73u, 1, 0,  UIMSG_BF, 1u, 0x20u,  sHouseName.data(), 0);
+    pDialogueWindow->CreateButton(8, 8, 460, 344, 1, 0, UIMSG_BF, 1, 0x59u, sHouseName.data(), 0);
+  }
+  else
+  {
+    v17 = HouseNPCData[_this + 1 - ((dword_591080 != 0) )];//+ 1
+    if ( dialog_menu_id == HOUSE_DIALOGUE_OTHER )
+    {
+      pDialogueWindow->Release();
+    }
+    else
+    {
+      for ( i = 0; i < uNumDialogueNPCPortraits; ++i )
+        dword_5913F4[i]->Release();
+    }
+    pDialogueWindow = GUIWindow::Create(0, 0, 640, 0x159u, WINDOW_MainMenu, 0, 0);
+    pBtn_ExitCancel = pDialogueWindow->CreateButton(  471u,  445u,  169u, 35u,  1,   0, UIMSG_Escape,  0,  0,
+                   pGlobalTXT_LocalizationStrings[74],// "End Conversation"
+                   pIcons_LOD->GetTexture(uExitCancelTextureId),   0);
+    pDialogueWindow->CreateButton(8u, 8u, 0x1C2u, 0x140u, 1, 0, UIMSG_BuyInShop_Identify_Repair, 0, 0, "", 0);
+    if ( pDialogueNPCCount == 1 && dword_591080 )
+    {
+      sub_4B3B42(in_current_building_type);
+    }
+    else
+    {
+      if ( v17->joins )
+      {
+        num_menu_buttons = 1;
+        pDialogueWindow->CreateButton(480u, 160u, 140u, 30, 1, 0, UIMSG_ClickNPCTopic, 0xDu, 0, "", 0);
+      }
+      if ( v17->evt_A)
+      {
+        if ( num_menu_buttons < 4 )
+        {
+          v6 = NPC_EventProcessor(v17->evt_A);
+          if ( v6 == 1 || v6 == 2 )
+            pDialogueWindow->CreateButton(  480u, 30 * num_menu_buttons++ + 160,  140u, 30u, 1, 0, UIMSG_ClickNPCTopic, 0x13u,  0, "",  0);
+        }
+      }
+      if ( v17->evt_B )
+      {
+        if ( num_menu_buttons < 4 )
+        {
+          v8 = NPC_EventProcessor(v17->evt_B);
+          if ( v8 == 1 || v8 == 2 )
+            pDialogueWindow->CreateButton( 480u,  30 * num_menu_buttons++ + 160,  140u, 30u,  1, 0,  UIMSG_ClickNPCTopic,  0x14u,  0, "",  0);
+        }
+      }
+      if ( v17->evt_C )
+      {
+        if ( num_menu_buttons < 4 )
+        {
+          v10 = NPC_EventProcessor(v17->evt_C);
+          if ( v10 == 1 || v10 == 2 )
+            pDialogueWindow->CreateButton(  480u,  30 * num_menu_buttons++ + 160,  140u, 30u,  1,  0, UIMSG_ClickNPCTopic, 0x15u, 0, "",  0);
+        }
+      }
+ 
+      if ( v17->evt_D )
+      {
+        if ( num_menu_buttons < 4 )
+        {
+          v12 = NPC_EventProcessor(v17->evt_D);
+          if ( v12 == 1 || v12 == 2 )
+            pDialogueWindow->CreateButton( 0x1E0u, 30 * num_menu_buttons++ + 160,  0x8Cu, 0x1Eu, 1, 0, UIMSG_ClickNPCTopic, 0x16u,  0, "",  0);
+        }
+      }
+      if ( v17->evt_E )
+      {
+        if ( num_menu_buttons < 4 )
+        {
+          v14 = NPC_EventProcessor(v17->evt_E);
+          if ( v14 == 1 || v14 == 2 )
+            pDialogueWindow->CreateButton( 0x1E0u, 30 * num_menu_buttons++ + 160,  0x8Cu,  0x1Eu,  1,  0,  UIMSG_ClickNPCTopic, 0x17u,  0, "",  0);
+        }
+      }
+      if ( v17->evt_F )
+      {
+        if ( num_menu_buttons < 4 )
+        {
+          v16 = NPC_EventProcessor(v17->evt_F);
+          if ( v16 == 1 || v16 == 2 )
+            pDialogueWindow->CreateButton( 0x1E0u, 30 * num_menu_buttons++ + 160,  0x8Cu,  0x1Eu, 1, 0, UIMSG_ClickNPCTopic, 0x18u, 0, "",  0);
+        }
+      }
+      pDialogueWindow->_41D08F_set_keyboard_control_group(num_menu_buttons, 1, 0, 2);
+      dword_F8B1E0 = pDialogueWindow->pNumPresenceButton;
+    }
+    dialog_menu_id = HOUSE_DIALOGUE_MAIN;
+  }
+ 
+}
+//----- (004466C4) --------------------------------------------------------
+int NPC_EventProcessor(int npc_event_id, int entry_line)
+	{
+  signed int event_index; // ebp@1
+  int evt_seq_num; // esi@3
+  bool ready_to_exit; // [sp+Ch] [bp-Ch]@3
+  signed int npc_activity; // [sp+10h] [bp-8h]@3
+  int result;
+
+  event_index = 0;
+  if ( !npc_event_id )
+    return 0;
+  evt_seq_num = entry_line;
+  pSomeOtherEVT = pGlobalEVT.data();
+  uSomeOtherEVT_NumEvents = uGlobalEVT_NumEvents;
+  memcpy(pSomeOtherEVT_Events.data(), pGlobalEVT_Index.data(), sizeof(EventIndex)*4400);
+  npc_activity = 1;
+  ready_to_exit = false;
+  if ( uSomeOtherEVT_NumEvents <= 0 )
+    return 2;
+  do
+  {
+    if ( (pSomeOtherEVT_Events[event_index].uEventID == npc_event_id) && (pSomeOtherEVT_Events[event_index].event_sequence_num == evt_seq_num) )
+    {
+	  _evt_raw *_evt = (_evt_raw *)&pSomeOtherEVT[pSomeOtherEVT_Events[event_index].uEventOffsetInEVT];
+	  switch(_evt->_e_type)
+		  {
+	  case EVENT_Exit:
+		   //exit
+		  if ( ready_to_exit )
+			  result = npc_activity != 0;
+		  else
+			   result = 2;
+		  return result;
+		  break;
+	  case EVENT_OnCanShowDialogItemCmp:
+		  ready_to_exit = true;
+		  //v8 = (unsigned __int8)v7[7] + (((unsigned __int8)v7[8] + (((unsigned __int8)v7[9] + ((unsigned __int8)v7[10] << 8)) << 8)) << 8);
+		  for(int i=0; i<4; ++i)
+			  {  
+			//  if (pParty->pPlayers[i].CompareVariable((enum VariableType)((unsigned __int8)pSomeOtherEVT[v6 + 5] + ((unsigned __int8)pSomeOtherEVT[v6 + 6] << 8)),
+				//  v8))
+			  if (pParty->pPlayers[i].CompareVariable((enum VariableType)EVT_WORD(_evt->v5), EVT_DWORD(_evt->v7)))
+				  {
+				  event_index = -1;
+				  evt_seq_num = EVT_BYTE(_evt->v11)-1;//(unsigned __int8)pSomeOtherEVT[v6 + 11] - 1;
+				  break;
+				  }
+			}
+		  break;
+	  case EVENT_EndCanShowDialogItem :
+		  if ( ready_to_exit )
+			  result = npc_activity != 0;
+		  else
+			  result = 2;
+		  return result;
+		  break;
+	  case EVENT_SetCanShowDialogItem :
+		  ready_to_exit = true;
+		  npc_activity = EVT_BYTE(_evt->v5); //(unsigned __int8)v7[5];
+		  break;
+	  case EVENT_IsActorAssasinated :
+		//  if (IsActorAlive( (unsigned __int8)v7[5], 
+		//	  (unsigned __int8)v7[6] + (((unsigned __int8)v7[7] + (((unsigned __int8)v7[8] + ((unsigned __int8)v7[9] << 8)) << 8)) << 8),
+			//  (unsigned __int8)v7[10]) )
+			if (IsActorAlive( EVT_BYTE(_evt->v5),  EVT_DWORD(_evt->v6), EVT_BYTE(_evt->v10)))
+			  {  // drop linear sequense, going to new seq
+				event_index = -1;
+				evt_seq_num = EVT_BYTE(_evt->v11)-1;//(unsigned __int8)pSomeOtherEVT[v6 + 11] - 1;
+			  }
+		  break;	  
+		  }
+		++evt_seq_num;
+    }
+    ++event_index;
+  }
+  while ( event_index < uSomeOtherEVT_NumEvents );
+  if ( ready_to_exit )
+    result = npc_activity != 0;
+  else
+    result = 2;
+  return result;
+}
+//----- (00445C8B) --------------------------------------------------------
+int __fastcall GetGreetType(signed int SpeakingNPC_ID)
+{
+  signed int v1; // ebx@1
+  int v3; // edi@6
+  int v4; // ecx@6
+  int v5; // edx@6
+  NPCData *v6; // eax@6
+  char *v7; // ebp@11
+  NPCData *v8; // esi@11
+
+  v1 = 0;
+  if ( SpeakingNPC_ID >= 0 )
+  {
+    if ( SpeakingNPC_ID < 5000 )
+      return 1;//QuestNPC_greet
+    return 2;//HiredNPC_greet
+  }
+  if ( SpeakingNPC_ID >= 5000 )
+    return 2;
+  v3 = abs((int)sDialogue_SpeakingActorNPC_ID) - 1;
+  v4 = 0;
+  v5 = 0;
+  v6 = pParty->pHirelings;
+  do
+  {
+    if ( v6->pName )
+      pTmpBuf[v4++] = v5;
+    ++v6;
+    ++v5;
+  }
+  while ( (signed int)v6 < (signed int)&pParty->pPickedItem );
+  if ( (signed int)pNPCStats->uNumNewNPCs > 0 )
+  {
+    v7 = &pTmpBuf[v4];
+    v8 = pNPCStats->pNewNPCData;
+    do
+    {
+      if (v8->Hired() && (!pParty->pHirelings[0].pName || strcmp(v8->pName, pParty->pHirelings[0].pName)) )
+      {
+        if ( !pParty->pHirelings[1].pName || strcmp(v8->pName, pParty->pHirelings[1].pName) )
+          *v7++ = v1 + 2;
+      }
+      ++v1;
+      ++v8;
+    }
+    while ( v1 < (signed int)pNPCStats->uNumNewNPCs );
+  }
+  return ((unsigned __int8)pTmpBuf[v3] < 2) + 1;
+}
+//----- (00445308) --------------------------------------------------------
+const char *GetProfessionActionText(int a1)
+{
+  if ( a1 == 10
+    || a1 == 11
+    || a1 == 12
+    || a1 == 33
+    || a1 == 34
+    || a1 == 39
+    || a1 == 40
+    || a1 == 41
+    || a1 == 42
+    || a1 == 43
+    || a1 == 52 )
+    return pNPCStats->pProfessions[a1 - 1].pActionText;
+  else
+    return pNPCTopics[407].pTopic;
+}
--- a/ObjectList.cpp	Sun Jun 23 14:27:32 2013 +0600
+++ b/ObjectList.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -1,9 +1,36 @@
 #include "ObjectList.h"
 #include "mm7_data.h"
 #include "Sprites.h"
+#include "FrameTableInc.h"
 #include "Allocator.h"
-#include "FrameTableInc.h"
+
+//----- (0042EB42) --------------------------------------------------------
+__int16 ObjectList::ObjectIDByItemID(unsigned __int16 uItemID)
+{
+  unsigned int v2; // edx@1
+  signed int v3; // eax@1
+  char *v4; // ecx@2
 
+  v2 = this->uNumObjects;
+  v3 = 0;
+  if ( (signed int)this->uNumObjects <= 0 )
+  {
+LABEL_5:
+    LOWORD(v3) = 0;
+  }
+  else
+  {
+    v4 = (char *)&this->pObjects->uObjectID;
+    while ( uItemID != *(short *)v4 )
+    {
+      ++v3;
+      v4 += 56;
+      if ( v3 >= (signed int)v2 )
+        goto LABEL_5;
+    }
+  }
+  return v3;
+}
 //----- (00459064) --------------------------------------------------------
 void ObjectList::InitializeSprites()
 {
--- a/Outdoor.cpp	Sun Jun 23 14:27:32 2013 +0600
+++ b/Outdoor.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -3171,7 +3171,384 @@
   else
     return true;
 }
+//----- (0046D49E) --------------------------------------------------------
+int __fastcall ODM_GetFloorLevel(int X, signed int Y, int Z, int __unused, int *pIsOnWater, int *a6, int bWaterWalk)
+{
+  BSPModel *pBModel; // esi@4
+  ODMFace *pFace; // ecx@11
+  int v14; // edx@20
+  signed int v18; // edx@26
+  int v19; // eax@28
+  int v20; // edx@30
+  int v21; // ST1C_4@30
+  signed int v22; // edx@30
+  signed __int64 v23; // qtt@30
+  int v24; // eax@36
+  signed int v25; // ecx@38
+  int result; // eax@42
+  signed int v27; // ecx@43
+  int v28; // edi@44
+  signed int v29; // edx@44
+  int v30; // esi@45
+  int v31; // eax@45
+  ODMFace *v32; // eax@57
+  int v33; // ecx@59
+  int v36; // [sp+14h] [bp-2Ch]@24
+  int v38; // [sp+1Ch] [bp-24h]@2
+  int v39; // [sp+20h] [bp-20h]@9
+  signed int pBModelNum; // [sp+28h] [bp-18h]@1
+  int pFaceNum; // [sp+2Ch] [bp-14h]@8
+  bool v43; // [sp+30h] [bp-10h]@22
+  bool v44; // [sp+34h] [bp-Ch]@24
+  signed int v46; // [sp+3Ch] [bp-4h]@1
+  signed int v48; // [sp+58h] [bp+18h]@22
+  signed int v49; // [sp+58h] [bp+18h]@43
 
+  v46 = 1;
+  dword_721160[0] = -1;
+  dword_721110[0] = -1;
+  odm_floor_level[0] = GetTerrainHeightsAroundParty2(X, Y, pIsOnWater, bWaterWalk);
+  
+  for ( pBModelNum = 0; pBModelNum < pOutdoor->uNumBModels; ++pBModelNum )
+  {
+    pBModel = &pOutdoor->pBModels[pBModelNum];
+    if ( X <= pBModel->sMaxX && X >= pBModel->sMinX &&
+         Y <= pBModel->sMaxY && Y >= pBModel->sMinY )
+    {
+      if ( pBModel->uNumFaces > 0 )
+      {
+        v39 = 0;
+        for ( pFaceNum = 0; pFaceNum < pBModel->uNumFaces; ++pFaceNum )
+        {
+          pFace = &pBModel->pFaces[pFaceNum];
+          if ( (pFace->uPolygonType == POLYGON_Floor || pFace->uPolygonType == POLYGON_InBetweenFloorAndWall)
+            && !(pFace->uAttributes & 0x20000000)
+            && X <= pFace->pBoundingBox.x2 && X >= pFace->pBoundingBox.x1
+            && Y <= pFace->pBoundingBox.y2 && Y >= pFace->pBoundingBox.y1 )
+          {
+            
+              for ( uint i = 0; i < pFace->uNumVertices; ++i)
+              {
+                word_721040[2 * i] = pFace->pXInterceptDisplacements[i] + pBModel->pVertices.pVertices[pFace->pVertexIDs[i]].x;
+                word_720F70[2 * i] = pFace->pXInterceptDisplacements[i + 1] + pBModel->pVertices.pVertices[pFace->pVertexIDs[i]].y;
+                word_721040[2 * i + 1] = pFace->pXInterceptDisplacements[i] + pBModel->pVertices.pVertices[pFace->pVertexIDs[i + 1]].x;
+                word_720F70[2 * i + 1] = pFace->pXInterceptDisplacements[i + 1] + pBModel->pVertices.pVertices[pFace->pVertexIDs[i + 1]].y;
+              }
+            word_721040[2 * pFace->uNumVertices] = word_721040[0];
+            word_720F70[2 * pFace->uNumVertices] = word_720F70[0];
+            v43 = word_720F70[0] >= Y;
+            v48 = 0;
+            if ( 2 * pFace->uNumVertices > 0 )
+            {
+              for ( int i = 0; i < 2 * pFace->uNumVertices; ++i )
+              {
+                if ( v48 >= 2 )
+                  break;
+                v36 = word_720F70[i + 1];
+                v44 = word_720F70[i + 1] >= Y;
+                if ( v43 != v44 )
+                {
+                  v18 = word_721040[i + 1] >= X ? 0 : 2;
+                  v19 = v18 | (word_721040[i] < X);
+                  if ( v19 != 3 )
+                  {
+                    if ( !v19 )
+                      ++v48;
+                    else
+                    {
+                      LODWORD(v23) = (Y - word_720F70[i]) << 16;
+                      HIDWORD(v23) = (Y - word_720F70[i]) >> 16;
+                      v22 = ((((word_721040[i + 1] - word_721040[i]) * v23 / (v36 - word_720F70[i])) >> 16) + word_721040[i]);
+                      if ( v22 >= X) 
+                        ++v48;
+                    }
+                  }
+                }
+                v43 = v44;
+              }
+              if ( v48 == 1 )
+              {
+                if ( v46 >= 20 )
+                  break;
+                if ( pFace->uPolygonType == POLYGON_Floor )
+                  v24 = pBModel->pVertices.pVertices[pFace->pVertexIDs[0]].z;
+                else
+                  v24 = ((unsigned __int64)(pFace->zCalc1 * (signed __int64)X) >> 16) + ((unsigned __int64)(pFace->zCalc2 * (signed __int64)Y) >> 16)
+                + HIWORD(pFace->zCalc3);
+                v25 = v46++;
+                odm_floor_level[v25] = v24;
+                dword_721160[v25] = pBModelNum;
+                dword_721110[v25] = pFaceNum;
+              }
+            }
+          }
+
+        }
+      }
+    }
+  }
+  if ( v46 == 1 )
+  {
+    *a6 = 0;
+    return odm_floor_level[0];
+  }
+  v27 = 0;
+  if ( v46 <= 1 )
+    *a6 = 0;
+  else
+  {
+    //v29 = 1;
+    for ( v49 = 1; v49 < v46; ++v49 )
+    {
+      if ( odm_floor_level[v49] == odm_floor_level[0] )
+      {
+        v27 = v49;
+        //++v29;
+        break;
+      }
+      if ( odm_floor_level[0] > Z + 5 )
+      {
+        if ( odm_floor_level[v49] >= odm_floor_level[0] )
+        {
+          //++v29;
+          break;
+        }
+        v27 = v49;
+        //++v29;
+        break;
+      }
+      if ( odm_floor_level[v49] > odm_floor_level[0] && odm_floor_level[v49] <= Z + 5 )
+      {
+        v27 = v49;
+        //++v29;
+      }
+    }
+    if ( !v27 )
+      *a6 = 0;
+    else
+      *a6 = dword_721110[v27] | (dword_721160[v27] << 6);
+  }
+  if ( v27 )
+  {
+    v32 = &pOutdoor->pBModels[dword_721160[v27]].pFaces[dword_721110[v27]];
+    *pIsOnWater = false;
+    if ( v32->Fluid())
+      *pIsOnWater = true;
+  }
+  if ( odm_floor_level[v27] >= odm_floor_level[0] )
+    odm_floor_level[0] = odm_floor_level[v27];
+  return odm_floor_level[0];
+}
+//not sure if right- or left-handed coordinate space assumed, so this could be normal of inverse normal
+// for a right-handed system, that would be an inverse normal
+//----- (0046DCC8) --------------------------------------------------------
+void ODM_GetTerrainNormalAt(int pos_x, int pos_z, Vec3_int_ *out)
+{
+  auto grid_x = WorldPosToGridCellX(pos_x);
+  auto grid_z = WorldPosToGridCellZ(pos_z) - 1;
+
+  auto grid_pos_x1 = GridCellToWorldPosX(grid_x);
+  auto grid_pos_x2 = GridCellToWorldPosX(grid_x + 1);
+  auto grid_pos_z1 = GridCellToWorldPosZ(grid_z);
+  auto grid_pos_z2 = GridCellToWorldPosZ(grid_z + 1);
+
+  auto x1z1_y = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z);
+  auto x2z1_y = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z);
+  auto x2z2_y = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z + 1);
+  auto x1z2_y = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z + 1);
+
+  float side1_dx, side1_dy, side1_dz,
+        side2_dx, side2_dy, side2_dz;
+
+  auto dx = abs(pos_x - grid_pos_x1),
+       dz = abs(grid_pos_z1 - pos_z);
+  if (dz >= dx)
+  {
+    side1_dy = (double)(x1z1_y - x1z2_y);
+    side2_dy = (double)(x2z2_y - x1z2_y);
+    side2_dx = (double)(grid_pos_x2 - grid_pos_x1);
+    side1_dx = (double)(grid_pos_x1 - grid_pos_x2);
+    side2_dz = 0.0;//(double)(grid_pos_z2 - grid_pos_z2);  // bug?  z2 - z2 
+    side1_dz = (double)(grid_pos_z1 - grid_pos_z2);  //       z1 - z2 yes
+    //Log::Warning(L"%S %S %u\n", __FILE__, __FUNCTION__, __LINE__);
+    /*       |\
+       side1 |  \
+             |____\
+             side 2      */
+  }
+  else
+  {
+    side1_dy = (double)(x2z2_y - x2z1_y);
+    side2_dy = (double)(x1z1_y - x2z1_y);
+    side2_dx = (double)(grid_pos_x1 - grid_pos_x2);
+    side1_dx = (double)(grid_pos_x2 - grid_pos_x1);
+    side2_dz = 0.0;//(double)(grid_pos_z1 - grid_pos_z1); 
+    side1_dz = (double)(grid_pos_z2 - grid_pos_z1);
+
+    /*   side 2
+         _____
+         \    |
+           \  | side 1
+             \|       */
+  }
+  
+  float nx = side1_dy * side2_dz - side1_dz * side2_dy;
+  float ny = side1_dx * side2_dy - side1_dy * side2_dx;
+  float nz = side1_dz * side2_dx - side1_dx * side2_dz;
+
+  float mag = sqrt(nx * nx + ny * ny + nz * nz);
+  if (fabsf(mag) < 1e-6f)
+  {
+    out->y = 0;
+    out->x = 0;
+    out->z = 65536;
+  }
+  else
+  {
+    float invmag = 1.0 / mag;
+    out->x = invmag * nx * 65536.0;
+    out->y = invmag * ny * 65536.0;
+    out->z = invmag * nz * 65536.0;
+  }
+}
+//----- (004014E6) --------------------------------------------------------
+void MakeActorAIList_ODM()
+{
+  int v1; // eax@4
+  int v2; // ebx@4
+  unsigned int v3; // ecx@4
+  int v4; // edx@5
+  int v5; // edx@7
+  unsigned int v6; // edx@9
+  unsigned int v7; // ST20_4@10
+  int v9; // edi@10
+  int v10; // ebx@14
+  int v21; // [sp+Ch] [bp-14h]@4
+  int v22; // [sp+10h] [bp-10h]@4
+
+  pParty->uFlags &= 0xFFFFFFCFu;
+
+  ai_arrays_size = 0;
+  for (uint i = 0; i < uNumActors; ++i)
+  {
+    auto actor = &pActors[i];
+
+    actor->uAttributes &= 0xFFFFFBFF;
+    if (!actor->CanAct())
+    {
+      actor->uAttributes &= 0xFFFFBFFF;
+      continue;
+    }
+
+    v22 = abs(pParty->vPosition.z - actor->vPosition.z);
+    v21 = abs(pParty->vPosition.y - actor->vPosition.y);
+    v1 = abs(pParty->vPosition.x - actor->vPosition.x);
+      v2 = v21;
+      v3 = v22;
+      if ( v1 < v21 )
+      {
+        v4 = v1;
+        v1 = v21;
+        v2 = v4;
+      }
+      if ( v1 < v22 )
+      {
+        v5 = v1;
+        v1 = v22;
+        v3 = v5;
+      }
+      if ( v2 < (signed int)v3 )
+      {
+        v6 = v3;
+        v3 = v2;
+        v2 = v6;
+      }
+      v7 = ((unsigned int)(11 * v2) >> 5) + (v3 >> 2) + v1;
+	  //v8 = actor->uActorRadius;
+      v9 = v7 - actor->uActorRadius;
+      //v23 = v7 - v8;
+      if ( v9 < 0 )
+      {
+        v9 = 0;
+        //v23 = 0;
+      }
+
+      if (v9 < 5632)
+      {
+        v10 = actor->uAttributes & 0xFEFFFFFF;
+        actor->uAttributes = v10;
+        if ( v10 & 0x80000 || actor->GetActorsRelation(0) )
+        {
+          //v11 = (pParty->uFlags & 0x10) == 0;
+          actor->uAttributes = v10 | 0x1000000;
+          if (v9 < 5120 )
+            pParty->SetYellowAlert();
+          if (v9 < 307)
+            pParty->SetRedAlert();
+        }
+		actor->uAttributes |= 0x00004000;
+        ai_near_actors_distances[ai_arrays_size] = v9;
+        ai_near_actors_ids[ai_arrays_size++] = i;
+      }
+      else
+		  actor->uAttributes &= 0xFFFFBFFF;
+  }
+
+  /*
+  result = v27;
+  if ( v27 > 0 )
+  {
+    v14 = 0;
+    v15 = 1;
+    v26 = 1;
+    do
+    {
+      while ( 1 )
+      {
+        v24 = v15;
+        if ( v15 >= result )
+          break;
+        v16 = ai_near_actors_distances[v14];
+        if ( v16 > ai_near_actors_distances[v15] )
+        {
+          v17 = &ai_near_actors_ids[v15];
+          v18 = ai_near_actors_ids[v14];
+          ai_near_actors_ids[v14] = *v17;
+          *v17 = v18;
+          v15 = v24;
+          ai_near_actors_distances[v14] = ai_near_actors_distances[v24];
+          ai_near_actors_distances[v24] = v16;
+        }
+        result = v27;
+        ++v15;
+      }
+      ++v14;
+      v15 = v26 + 1;
+      v26 = v15;
+    }
+    while ( v15 - 1 < result );
+  }*/
+
+  for (uint i = 0; i < ai_arrays_size; ++i)
+    for (uint j = 0; j < i; ++j)
+      if (ai_near_actors_distances[j] > ai_near_actors_distances[i])
+      {
+        int tmp = ai_near_actors_distances[j];
+        ai_near_actors_distances[j] = ai_near_actors_distances[i];
+        ai_near_actors_distances[i] = tmp;
+
+        tmp = ai_near_actors_ids[j];
+        ai_near_actors_ids[j] = ai_near_actors_ids[i];
+        ai_near_actors_ids[i] = tmp;
+      }
+
+
+  if (ai_arrays_size > 30)
+    ai_arrays_size = 30;
+
+  for (uint i = 0; i < ai_arrays_size; ++i)
+    pActors[ai_near_actors_ids[i]].uAttributes |= 0x0400;
+}
 //----- (0046BE0A) --------------------------------------------------------
 void __cdecl ODM_UpdateUserInputAndOther()
 {
@@ -3206,4 +3583,15 @@
   }
   UpdateActors_ODM();
   check_event_triggers();
+}
+//----- (0041F54A) --------------------------------------------------------
+void __cdecl LoadActualSkyFrame()
+{
+  if ( pTexture_RestUI_CurrentSkyFrame )
+    pTexture_RestUI_CurrentSkyFrame->Release();
+  if ( pTexture_RestUI_CurrentHourglassFrame )
+    pTexture_RestUI_CurrentHourglassFrame->Release();
+  pIcons_LOD->SyncLoadedFilesCount();
+  sprintf(pTmpBuf.data(), "TERRA%03d", pParty->uCurrentMinute / 6 + 10 * pParty->uCurrentHour);
+  pTexture_RestUI_CurrentSkyFrame = pIcons_LOD->LoadTexturePtr(pTmpBuf.data(), TEXTURE_16BIT_PALETTE);
 }
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OutdoorCamera.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -0,0 +1,124 @@
+#include "OutdoorCamera.h"
+#include "IndoorCamera.h"
+#include "Outdoor_stuff.h"
+#include "Game.h"
+#include "LightmapBuilder.h"
+#include "Viewport.h"
+#include "Math.h"
+#include "mm7_data.h"
+#include "Allocator.h"
+
+//----- (00487355) --------------------------------------------------------
+bool OutdoorCamera::_487355()
+{
+  int v0; // esi@1
+  stru148 *v1; // edi@2
+  bool result; // eax@3
+
+  v0 = 0;
+  if ( pOutdoorCamera->numStru148s > 0 )
+  {
+    v1 = array_77EC08.data();
+    do
+    {
+      result = pGame->pLightmapBuilder->_45D3C7(v1);
+      ++v0;
+      ++v1;
+    }
+    while ( v0 < pOutdoorCamera->numStru148s );
+  }
+  return result;
+}
+//----- (00481E55) --------------------------------------------------------
+void OutdoorCamera::Project(unsigned int uNumVertices)
+{
+  double v1; // st7@2
+  double v2; // st6@2
+  double v3; // st5@2
+  int v4; // eax@2
+  unsigned int v5; // edx@2
+  double v6; // st4@3
+  double v7; // st3@3
+
+  if ( (signed int)uNumVertices > 0 )
+  {
+    v1 = (double)pOutdoorCamera->int_fov_rad;
+    v2 = (double)pViewport->uScreenCenterX;
+    v3 = (double)pViewport->uScreenCenterY;
+    v4 = 0;
+    v5 = uNumVertices;
+    do
+    {
+      v6 = v1 * array_507D30[v4]._rhw;
+      v7 = v6 * array_507D30[v4].vWorldViewPosition.y;
+      memcpy(&array_50AC10[v4], &array_507D30[v4], sizeof(array_50AC10[v4]));
+      array_50AC10[v4].vWorldViewProjX = v2 - v7;
+      array_50AC10[v4].vWorldViewProjY = v3 - v6 * array_507D30[v4].vWorldViewPosition.z;
+      ++v4;
+      --v5;
+    }
+    while ( v5 );
+  }
+}
+//----- (00485F64) --------------------------------------------------------
+void OutdoorCamera::_485F64()
+{
+  int v1; // eax@1
+  int v2; // eax@2
+  signed __int64 v3; // qtt@4
+  int v4; // eax@4
+
+  this->uCameraFovInDegrees = 75;
+  v1 = stru_5C6E00->uPiMask & 0xD5;
+  if ( v1 >= (signed int)stru_5C6E00->uIntegerHalfPi )
+    v2 = -stru_5C6E00->pTanTable[stru_5C6E00->uIntegerPi - v1];
+  else
+    v2 = stru_5C6E00->pTanTable[v1];
+  LODWORD(v3) = (viewparams->uSomeZ - viewparams->uSomeX) << 31;
+  HIDWORD(v3) = (viewparams->uSomeZ - viewparams->uSomeX) << 15 >> 16;
+  v4 = (signed int)(v3 / v2) >> 16;
+  this->int_fov_rad = v4;
+  this->field_4C = 360000;
+  this->int_fov_rad_inv = 65536 / v4;
+  this->field_50 = 115;
+  unnamed_6BE060[1] = 1;
+  RotationToInts();
+}
+
+//----- (0048600E) --------------------------------------------------------
+void OutdoorCamera::RotationToInts()
+{
+  camera_rotation_y_int_sine   = stru_5C6E00->Sin(pIndoorCamera->sRotationY);
+  camera_rotation_y_int_cosine = stru_5C6E00->Cos(pIndoorCamera->sRotationY);
+  camera_rotation_x_int_sine   = stru_5C6E00->Sin(pIndoorCamera->sRotationX);
+  camera_rotation_x_int_cosine = stru_5C6E00->Cos(pIndoorCamera->sRotationX);
+}
+//----- (00486A28) --------------------------------------------------------
+void OutdoorCamera::AllocSoftwareDrawBuffers()
+{
+  if ( !this || !pSpans )
+  {
+    ReleaseSoftwareDrawBuffers();
+    pSpans = (Span *)pAllocator->AllocNamedChunk(pSpans, 0x493E0u, "SPANS");
+    pEdges = (Edge *)pAllocator->AllocNamedChunk(pEdges, 0x4C2C0u, "EDGES");
+    pSurfs = (Surf *)pAllocator->AllocNamedChunk(pSurfs, 0x11940u, "SURFS");
+    pNewEdges = (Edge *)pAllocator->AllocNamedChunk(pNewEdges, 0x6180u, "NEWEDGES");
+    memset(pSpans, 0, 0x493E0u);
+    memset(pEdges, 0, 0x4C2C0u);
+    memset(pSurfs, 0, 0x11940u);
+    memset(pNewEdges, 0, 0x6180u);
+  }
+}
+
+//----- (00486AFC) --------------------------------------------------------
+void OutdoorCamera::ReleaseSoftwareDrawBuffers()
+{
+  pAllocator->FreeChunk(pSpans);
+  pAllocator->FreeChunk(pEdges);
+  pAllocator->FreeChunk(pSurfs);
+  pAllocator->FreeChunk(pNewEdges);
+  pSpans = 0;
+  pEdges = 0;
+  pSurfs = 0;
+  pNewEdges = 0;
+}
\ No newline at end of file
--- a/Party.cpp	Sun Jun 23 14:27:32 2013 +0600
+++ b/Party.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -19,12 +19,13 @@
 
 #include "mm7_data.h"
 #include "MM7.h"
-
-
-
-
-
-
+#include "Outdoor.h"
+#include "Indoor.h"
+#include "Texture.h"
+#include "LOD.h"
+#include "Sprites.h"
+#include "SpriteObject.h"
+#include "ObjectList.h"
 
 Party *pParty; // idb
 
@@ -1151,4 +1152,365 @@
     UpdatePlayersAndHirelingsEmotions();
   }
   pParty->days_played_without_rest = 0;
+}
+//----- (004938D1) --------------------------------------------------------
+void __fastcall Rest(unsigned int uHoursToSleep)
+{
+  unsigned int v1; // esi@1
+  double v2; // st7@3
+  Player **v3; // esi@3
+
+  v1 = uHoursToSleep;
+  if ( uHoursToSleep > 240 )
+    InitializeActors();
+  v2 = (double)(7680 * v1) * 0.033333335;
+  pParty->uTimePlayed += (signed __int64)v2;
+  v3 = &pPlayers[1];
+  do
+  {
+    (*v3)->Recover((signed __int64)v2);
+    ++v3;
+  }
+  while ( (signed int)v3 <= (signed int)&pPlayers[4] );
+  _494035_timed_effects__water_walking_damage__etc();
+}
+//----- (004B1BDB) --------------------------------------------------------
+void __stdcall RestAndHeal(__int64 uNumMinutes)
+{
+  signed __int64 v1; // ST2C_8@1
+  signed __int64 v2; // qax@1
+  signed __int64 v3; // ST1C_8@1
+  unsigned __int64 v4; // qax@1
+  unsigned int v5; // ebx@1
+  Player *v6; // ebx@1
+
+  pParty->pHirelings[0].bHasUsedTheAbility = 0;
+  pParty->pHirelings[1].bHasUsedTheAbility = 0;
+  pParty->uTimePlayed += (signed __int64)((double)(7680 * uNumMinutes) * 0.033333335);
+  v1 = (signed __int64)((double)(signed __int64)pParty->uTimePlayed * 0.234375);
+  v2 = v1 / 60 / 60;
+  v3 = v2;
+  v4 = (unsigned int)v2 / 0x18;
+  v5 = (unsigned int)(v4 / 7) >> 2;
+  pParty->uCurrentTimeSecond = v1 % 60;
+  pParty->uCurrentMinute = v1 / 60 % 60;
+  pParty->uCurrentHour = v3 % 24;
+  pParty->uCurrentMonthWeek = v4 / 7 & 3;
+  pParty->uDaysPlayed = (unsigned int)v4 % 0x1C;
+  pParty->uCurrentMonth = v5 % 0xC;
+  pParty->uCurrentYear = v5 / 0xC + game_starting_year;
+  pParty->RestAndHeal();
+  dword_507B94 = 1;
+  v6 = pParty->pPlayers;//[0].uNumDivineInterventionCastsThisDay;
+  do
+  {
+	v6->uTimeToRecovery = 0;
+	memset(&v6->uTimeToRecovery, 0, 4u);
+    ++v6;
+  }
+  while ( v6 <= &pParty->pPlayers[3] );
+  pParty->UpdatePlayersAndHirelingsEmotions();
+}
+//----- (0041F5BE) --------------------------------------------------------
+void __cdecl Sleep6Hours()
+{
+  if ( _506F18_num_hours_to_sleep < 6 )
+  {
+    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);
+      _506F18_num_hours_to_sleep = 0;
+      LoadActualSkyFrame();
+    }
+    if ( dword_506F14 == 2 )
+    {
+      pGUIWindow_CurrentMenu->Release();
+      pEventTimer->Resume();
+      if ( pTexture_RestUI_CurrentSkyFrame )
+        pTexture_RestUI_CurrentSkyFrame->Release();
+      if ( pTexture_RestUI_CurrentHourglassFrame )
+        pTexture_RestUI_CurrentHourglassFrame->Release();
+      pTexture_RestUI_CurrentHourglassFrame = 0;
+      pTexture_RestUI_CurrentSkyFrame = 0;
+      pIcons_LOD->_4114F2();
+      pIcons_LOD->SyncLoadedFilesCount();
+      pCurrentScreen = SCREEN_GAME;
+      viewparams->bRedrawGameUI = 1;
+      if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor)
+      {
+        pOutdoor->UpdateSunlightVectors();
+        pOutdoor->UpdateFog();
+      }
+    }
+    dword_506F14 = 0;
+  }
+  else
+  {
+    Rest(6u);
+    _506F18_num_hours_to_sleep -= 6;
+    LoadActualSkyFrame();
+  }
+  viewparams->bRedrawGameUI = 1;
+}
+
+//----- (0047752B) --------------------------------------------------------
+int __cdecl GetPartyReputation()
+{
+  DDM_DLV_Header *v0; // ebx@1
+  signed int v1; // esi@3
+
+  v0 = &pOutdoor->ddm;
+  if ( uCurrentlyLoadedLevelType != LEVEL_Outdoor )
+    v0 = &pIndoor->dlv;
+  v1 = 0;
+  if ( CheckHiredNPCSpeciality(Pirate) )
+    v1 += 5;
+  if ( CheckHiredNPCSpeciality(Burglar) )
+    v1 += 5;
+  if ( CheckHiredNPCSpeciality(Gypsy) )
+    v1 += 5;
+  if ( CheckHiredNPCSpeciality(Duper) )
+    v1 += 5;
+  if ( CheckHiredNPCSpeciality(FallenWizard) )
+    v1 += 5;
+  return v1 + v0->uReputation;
+}
+//----- (004269A2) --------------------------------------------------------
+void __fastcall GivePartyExp(unsigned int pEXPNum)
+{
+  signed int pActivePlayerCount; // ecx@1
+  int pLearningPercent; // eax@13
+
+  pActivePlayerCount = 0;
+  for ( uint i = 0; i < 4; ++i )
+  {
+    if ( !pParty->pPlayers[i].pConditions[13] && !pParty->pPlayers[i].pConditions[14] && !pParty->pPlayers[i].pConditions[15] && !pParty->pPlayers[i].pConditions[16] )
+      pActivePlayerCount ++;
+  }
+  if ( pActivePlayerCount )
+  {
+    pEXPNum = pEXPNum / pActivePlayerCount;
+    for ( uint i = 0; i < 4; ++i )
+    {
+      if ( !pParty->pPlayers[i].pConditions[13] && !pParty->pPlayers[i].pConditions[14] && !pParty->pPlayers[i].pConditions[15] && !pParty->pPlayers[i].pConditions[16] )
+      {
+        if ( pEXPNum )
+        {
+          pLearningPercent = pParty->pPlayers[i].GetLearningPercent();
+          pEXPNum = pEXPNum + pEXPNum * pLearningPercent / 100;
+          pParty->pPlayers[i].uExperience += pEXPNum;
+          if ( pParty->pPlayers[i].uExperience > 4000000000i64 )
+          {
+            pParty->pPlayers[i].uExperience = 0;
+          }
+        }
+      }
+    }
+  }
+}
+//----- (00420C05) --------------------------------------------------------
+void __fastcall party_finds_gold(unsigned int uNumGold, int _1_dont_share_with_followers___2_the_same_but_without_a_message__else_normal)
+{
+  unsigned int v2; // edi@1
+  int v3; // ebp@1
+  unsigned int v4; // esi@1
+  int v5; // ecx@6
+  NPCData *v6; // eax@6
+  signed int v7; // edx@8
+  signed int v8; // ebx@10
+  char *v9; // edi@11
+  signed int v10; // ecx@17
+  int v11; // eax@21
+  NPCData *v12; // ecx@21
+  unsigned int v13; // ecx@23
+  signed int v14; // [sp+Ch] [bp-4h]@6
+
+  v2 = 0;
+  v3 = 0;
+  v4 = uNumGold;
+  if ( _1_dont_share_with_followers___2_the_same_but_without_a_message__else_normal )
+  {
+    if ( _1_dont_share_with_followers___2_the_same_but_without_a_message__else_normal == 1 )
+    {
+      sprintf(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[467], uNumGold);// You found %lu gold!
+    }
+    else
+    {
+      if ( _1_dont_share_with_followers___2_the_same_but_without_a_message__else_normal == 2 )
+        pTmpBuf2[0] = 0;
+    }
+  }
+  else
+  {
+    v14 = 0;
+    v5 = 0;
+    v6 = pParty->pHirelings;
+    do
+    {
+      if ( v6->pName )
+      {
+        v7 = v14++;
+        pTmpBuf[v7] = v5;
+      }
+      ++v6;
+      ++v5;
+    }
+    while ( (signed int)v6 < (signed int)&pParty->pPickedItem );
+    v8 = 0;
+    if ( (signed int)pNPCStats->uNumNewNPCs > 0 )
+    {
+      v9 = (char *)pNPCStats->pNewNPCData;
+      do
+      {
+        if ( v9[8] & 0x80
+          && (!pParty->pHirelings[0].pName || strcmp(*(const char **)v9, pParty->pHirelings[0].pName))
+          && (!pParty->pHirelings[1].pName || strcmp(*(const char **)v9, pParty->pHirelings[1].pName)) )
+        {
+          v10 = v14++;
+          pTmpBuf[v10] = v8 + 2;
+        }
+        ++v8;
+        v9 += 76;
+      }
+      while ( v8 < (signed int)pNPCStats->uNumNewNPCs );
+      v2 = 0;
+    }
+    if ( v14 > 0 )
+    {
+      do
+      {
+        v11 = (unsigned __int8)pTmpBuf[v2];
+        v12 = &pNPCStats->pNPCData[v11 + 499];
+        if ( (unsigned __int8)pTmpBuf[v2] < 2 )
+          v12 = &pParty->pHirelings[v11];
+        v13 = v12->uProfession;
+        if ( v13 )
+          v3 += pNPCStats->pProfessions[v13].uHirePrice;//*(&pNPCStats->field_13A58 + 5 * v13);
+        ++v2;
+      }
+      while ( (signed int)v2 < v14 );
+    }
+    if ( CheckHiredNPCSpeciality(Factor) )
+      v4 += (signed int)(10 * v4) / 100;
+    if ( CheckHiredNPCSpeciality(Banker) )
+      v4 += (signed int)(20 * v4) / 100;
+    if ( CheckHiredNPCSpeciality(Pirate) )
+      v4 += (signed int)(10 * v4) / 100;
+    if ( v3 )
+    {
+      v3 = (signed int)(v4 * v3 / 100) / 100;
+      if ( v3 < 1 )
+        v3 = 1;
+      sprintf(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[466], v4, v3);// You found %lu gold (followers take %lu)!
+    }
+    else
+    {
+      sprintf(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[467], v4);// You found %lu gold!
+    }
+    v2 = 0;
+  }
+  pParty->uNumGold += v4 - v3;
+  pUIAnim_Gold->uAnimTime = v2;
+  pUIAnim_Gold->uAnimLength = 8 * pIconsFrameTable->pIcons[(signed __int16)pUIAnim_Gold->uIconID].uAnimLength;
+  if ( pTmpBuf2[0] )
+    ShowStatusBarString(pTmpBuf2.data(), 2u);
+  pAudioPlayer->PlaySound(SOUND_GoldReceived, v2, v2, -1, v2, v2, v2, v2);
+}
+//----- (00421B2C) --------------------------------------------------------
+bool __cdecl sub_421B2C_PlaceInInventory_or_DropPickedItem()
+{
+  unsigned int v0; // eax@2
+  Texture *v1; // ebx@2
+  int v2; // eax@3
+  Player *v3; // esi@5
+  int v4; // eax@6
+  unsigned __int16 v5; // dx@11
+  signed int v6; // eax@11
+  char *v7; // edi@12
+  __int16 v8; // ax@16
+  SpriteObject a1; // [sp+4h] [bp-78h]@11
+  int v11; // [sp+74h] [bp-8h]@2
+  int v12; // [sp+78h] [bp-4h]@5
+
+  if ( !pParty->pPickedItem.uItemID )
+    return 1;
+  v0 = pIcons_LOD->LoadTexture(
+         pItemsTable->pItems[pParty->pPickedItem.uItemID].pIconName,
+         TEXTURE_16BIT_PALETTE);
+  v1 = pIcons_LOD->GetTexture(v0);
+  v11 = areWeLoadingTexture;
+  if ( uActiveCharacter
+    && (v2 = pPlayers[uActiveCharacter]->AddItem(-1, pParty->pPickedItem.uItemID)) != 0 )
+  {
+    memcpy(&pPlayers[uActiveCharacter]->pInventoryItems[v2-1], &pParty->pPickedItem, 0x24u);
+	pMouse->RemoveHoldingItem();
+  }
+  else
+  {
+    v12 = 0;
+    v3 = pParty->pPlayers;
+	while ( v3 <= &pParty->pPlayers[3] )
+    {
+      v4 = v3->AddItem(-1, pParty->pPickedItem.uItemID);
+      if ( v4 )
+	  {
+		memcpy(&pParty->pPlayers[v12].pInventoryItems[v4], &pParty->pPickedItem, 0x24u);
+		pMouse->RemoveHoldingItem();
+		break;
+	  }
+	  ++v12;
+      ++v3;
+    }
+    if ( v12 == 4 )
+	{
+		v5 = pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID;
+		v6 = 0;
+		a1.uType = pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID;
+		if ( (signed int)pObjectList->uNumObjects <= 0 )
+		{
+		  LOWORD(v6) = 0;
+		}
+		else
+		{
+		  v7 = (char *)&pObjectList->pObjects->uObjectID;
+		  while ( v5 != *(short *)v7 )
+		  {
+			++v6;
+			v7 += 56;
+			if ( v6 >= (signed int)pObjectList->uNumObjects )
+			{
+				LOWORD(v6) = 0;
+				break;
+			}
+		  }
+		}
+		a1.spell_caster_pid = OBJECT_Player;
+		a1.uObjectDescID = v6;
+		a1.vPosition.y = pParty->vPosition.y;
+		a1.vPosition.x = pParty->vPosition.x;
+		a1.vPosition.z = pParty->sEyelevel + pParty->vPosition.z;
+		a1.uSoundID = 0;
+		a1.uFacing = 0;
+		a1.uAttributes = 8;
+		v8 = pIndoor->GetSector(
+			   pParty->vPosition.x,
+			   pParty->vPosition.y,
+			   pParty->sEyelevel + pParty->vPosition.z);
+		a1.uSpriteFrameID = 0;
+		a1.uSectorID = v8;
+		memcpy(&a1.stru_24, &pParty->pPickedItem, sizeof(a1.stru_24));
+		a1.Create(pParty->sRotationY, 184, 200, 0);
+		pMouse->RemoveHoldingItem();
+	}
+  }
+  if ( !v11 )
+  {
+    v1->Release();
+    pIcons_LOD->SyncLoadedFilesCount();
+  }
+  return 1;
 }
\ No newline at end of file
--- a/Player.cpp	Sun Jun 23 14:27:32 2013 +0600
+++ b/Player.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -29,7 +29,8 @@
 
 #include "mm7_data.h"
 #include "MM7.h"
-
+#include "SpriteObject.h"
+#include "DecalBuilder.h"
 
 
 
@@ -9521,4 +9522,807 @@
       pMouse->RemoveHoldingItem();
     }
   }
+}
+//----- (0049387A) --------------------------------------------------------
+int CycleCharacter(unsigned int _this)
+{
+  signed int result; // eax@1
+  signed int v2; // ecx@2
+  signed int v3; // ecx@8
+
+  result = uActiveCharacter;
+  if ( _this )
+  {
+    v2 = 0;
+    while ( 1 )
+    {
+      --result;
+      if ( result < 1 )
+        result = 4;
+      if ( !pPlayers[result]->uTimeToRecovery )
+        break;
+      ++v2;
+      if ( v2 >= 4 )
+        return uActiveCharacter;
+    }
+  }
+  else
+  {
+    v3 = 0;
+    while ( 1 )
+    {
+      ++result;
+      if ( result > 4 )
+        result = 1;
+      if ( !pPlayers[result]->uTimeToRecovery )
+        break;
+      ++v3;
+      if ( v3 >= 4 )
+        return uActiveCharacter;
+    }
+  }
+  return result;
+}
+//----- (0043EE77) --------------------------------------------------------
+bool __fastcall sub_43EE77_ProbablyIfUnderwaterSuitIsEquipped(signed int a1)
+{
+  bool result; // eax@0
+  Player *v2; // edx@3
+  int v3; // ecx@3
+  Player **pPlayers; // esi@8
+  unsigned int v5; // ecx@8
+  Player *v6; // edx@9
+
+  if ( a1 < 1 || a1 > 4 )
+  {
+    if ( !a1 )
+    {
+      pPlayers = &::pPlayers[1];
+      v5 = 604;
+      while ( 1 )
+      {
+        result = Player_has_item(v5, *pPlayers, 0);
+        if ( !result )
+          break;
+        result = v6->pEquipment.uArmor;
+        if ( !result )
+          break;
+        result *= 9;
+        if ( *(int *)&v6->spellbook.pDarkSpellbook.bIsSpellAvailable[4 * result + 5] != v5 )
+          break;
+        ++pPlayers;
+        if ( (signed int)pPlayers >= (signed int)&qword_A750D8 )
+          goto LABEL_13;
+      }
+    }
+    goto LABEL_6;
+  }
+  result = Player_has_item(604u, ::pPlayers[a1], 0);
+  if ( !result
+    || (result = v2->pEquipment.uArmor) == 0
+    || (result *= 9, *(int *)&v2->spellbook.pDarkSpellbook.bIsSpellAvailable[4 * result + 5] != v3) )
+  {
+LABEL_6:
+    LOBYTE(result) = 0;
+    return result;
+  }
+LABEL_13:
+  LOBYTE(result) = 1;
+  return result;
+}
+//----- (0043EE15) --------------------------------------------------------
+bool __fastcall Player_has_item(unsigned int uItemID, Player *pPlayer, char a3)
+{
+  if ( !a3 || pParty->pPickedItem.uItemID != uItemID )
+  {
+    for ( uint i = 0; i < 126; ++i )
+    {
+      if ( pPlayer->pInventoryIndices[i] > 0 )
+      {
+        if ( (unsigned int)pPlayer->pInventoryItems[pPlayer->pInventoryIndices[i] - 1].uItemID == uItemID )
+          return true;
+      }
+    }
+    for ( uint i = 0; i < 16; ++i )
+    {
+      if ( pPlayer->pEquipment.pIndices[i] )
+      {
+        if ( (unsigned int)pPlayer->pInventoryItems[pPlayer->pEquipment.pIndices[i] - 1].uItemID == uItemID )
+          return true;
+      }
+    }
+  }
+  return false;
+}
+//----- (0043EDB9) --------------------------------------------------------
+bool __thiscall sub_43EDB9_get_some_race_sex_relation_2(unsigned int a1)
+{
+  unsigned int pNum; // ebp@1
+  Player **pPlayer; // ebx@1
+  Player *pPlayer2; // esi@2
+  enum CHARACTER_RACE pRace; // edi@2
+  bool pSex; // eax@2
+  char v6; // zf@7
+
+//pPlayer = &pPlayers[1];
+  /*pNum = a1;
+  
+  while ( 1 )
+  {
+    pPlayer2 = *pPlayer;
+    pRace = pPlayer2->GetRace();
+    pSex = pPlayer2->GetSexByVoice();
+    if ( !pRace )
+      break;
+    if ( pRace == 1 || pRace == 2 )
+      break;
+    if ( !pSex && pNum == 2 )//
+      //goto LABEL_15;
+    {
+      pSex = 1;
+      return pSex;
+    }
+    v6 = pNum == 3;//
+LABEL_11:
+    if ( v6 )
+      //goto LABEL_15;
+    {
+      pSex = 1;
+      return pSex;
+    }
+    ++pPlayer;
+    if ( (signed int)pPlayer >= (signed int)&qword_A750D8 )//
+    {
+      pSex = 0;
+      return pSex;
+    }
+  }
+  if ( pSex || pNum )
+  {
+    v6 = pNum == 1;
+    goto LABEL_11;
+  }
+//LABEL_15:
+  pSex = 1;
+  return pSex;*/
+  for (uint i = 1; i <= 4; ++i)
+    {
+      pRace = pPlayers[i]->GetRace();
+      pSex = pPlayers[i]->GetSexByVoice();
+      if (pRace == 0 || pRace == 1 || pRace == 2 || pSex == 0 )
+        return 1;
+    }
+ return 0;
+}
+//----- (0043ED6F) --------------------------------------------------------
+bool _43ED6F_check_party_races(bool a1)
+{
+  bool v6; // zf@5
+
+  for (uint i = 0; i < 4; ++i)
+  {
+    auto player = pParty->pPlayers + i;
+    auto race = player->GetRace();
+
+    if (race != CHARACTER_RACE_HUMAN &&
+        race != CHARACTER_RACE_ELF &&
+        race != CHARACTER_RACE_GOBLIN)
+      v6 = a1 == 1;
+    else
+      v6 = !a1;
+
+    if (v6)
+      return true;
+  }
+  return false;
+}
+//----- (00439FCB) --------------------------------------------------------
+void __fastcall DamagePlayerFromMonster(unsigned int uObjID, int a2, Vec3_int_ *pPos, unsigned int a4)
+{
+  signed int v4; // esi@1
+  unsigned int v5; // ecx@1
+  Player *v6; // ebx@3
+  Actor *v7; // esi@3
+  unsigned int v8; // eax@4
+  char *v9; // eax@5
+  signed int v10; // eax@6
+  int v11; // edx@8
+  int v12; // edx@9
+  int v13; // edx@10
+  int v14; // edx@16
+  int v15; // edx@17
+  int v16; // edx@18
+  enum SoundID v17; // eax@24
+  int v18; // eax@26
+  unsigned __int8 v19; // zf@26
+  unsigned __int8 v20; // sf@26
+  unsigned __int16 v21; // ax@29
+  signed int v22; // edi@36
+  int v23; // eax@38
+  signed int v24; // eax@44
+  unsigned __int16 v25; // cx@47
+  signed int v26; // eax@49
+  int v27; // eax@54
+  float v28; // ST18_4@58
+  double v29; // st7@58
+  float v30; // ST08_4@58
+  double v31; // st7@58
+  float v32; // ST04_4@58
+  float v33; // ST00_4@58
+  int v34; // edi@61
+  int v35; // eax@70
+  double v36; // st7@70
+  SpriteObject *v37; // ebx@77
+  int v38; // edi@77
+  int v39; // esi@77
+  int v40; // eax@77
+  int v41; // eax@77
+  int v42; // eax@78
+  Player *v43; // eax@81
+  Actor *v44; // esi@82
+  Player *v45; // edi@84
+  unsigned __int16 v46; // ax@84
+  int v47; // ebx@105
+  int v48; // eax@107
+  unsigned __int16 v49; // ax@116
+  int v50; // ebx@123
+  unsigned __int16 v51; // ax@124
+  char v52; // bl@124
+  int v53; // eax@128
+  signed int v54; // eax@134
+  unsigned __int16 v55; // cx@137
+  signed int v56; // eax@139
+  int v57; // eax@144
+  float v58; // ST18_4@148
+  double v59; // st7@148
+  float v60; // ST08_4@148
+  double v61; // st7@148
+  float v62; // ST04_4@148
+  float v63; // ST00_4@148
+  int v64; // ebx@151
+  int v65; // eax@161
+  double v66; // st7@161
+  signed int v67; // ecx@164
+  signed int v68; // eax@170
+  int v69; // ecx@170
+  int v70; // eax@171
+  enum SoundID v71; // [sp+20h] [bp-34h]@12
+  int v72; // [sp+30h] [bp-24h]@164
+  double v73; // [sp+40h] [bp-14h]@72
+  signed int v74; // [sp+44h] [bp-10h]@1
+  unsigned int v75; // [sp+48h] [bp-Ch]@3
+  unsigned int uActorID; // [sp+4Ch] [bp-8h]@1
+  int v77; // [sp+50h] [bp-4h]@26
+  signed int a4a; // [sp+60h] [bp+Ch]@162
+  Player *a4b; // [sp+60h] [bp+Ch]@168
+
+  v4 = PID_ID(uObjID);
+  v5 = PID_TYPE(uObjID) - 2;
+  v74 = a2;
+  uActorID = v4;
+  if ( v5 )
+  {
+    if ( v5 != 1
+      || (v6 = &pParty->pPlayers[a4], v7 = &pActors[v4],
+                                     v75 = v6->sHealth,
+                                     !stru_50C198.ActorHitOrMiss(v7, v6)) )
+      return;
+    v8 = v6->pEquipment.uArmor;
+    if ( !v8
+      || (v9 = (char *)v6 + 36 * v8, v9[516] & 2)
+      || (v10 = pItemsTable->pItems[*((int *)v9 + 124)].uSkillType, v10 < 10)
+      || v10 > 11 )
+    {
+      v14 = rand() % 4;
+      if ( !v14 )
+      {
+        v71 = (SoundID)108;
+        goto LABEL_24;
+      }
+      v15 = v14 - 1;
+      if ( !v15 )
+      {
+        v71 = (SoundID)109;
+        goto LABEL_24;
+      }
+      v16 = v15 - 1;
+      if ( !v16 )
+      {
+        v71 = (SoundID)110;
+        goto LABEL_24;
+      }
+      if ( v16 == 1 )
+      {
+        v71 = (SoundID)44;
+        goto LABEL_24;
+      }
+    }
+    else
+    {
+      v11 = rand() % 4;
+      if ( !v11 )
+      {
+        v71 = (SoundID)105;
+        goto LABEL_24;
+      }
+      v12 = v11 - 1;
+      if ( !v12 )
+      {
+        v71 = (SoundID)106;
+        goto LABEL_24;
+      }
+      v13 = v12 - 1;
+      if ( !v13 )
+      {
+        v71 = (SoundID)107;
+        goto LABEL_24;
+      }
+      if ( v13 == 1 )
+      {
+        v71 = (SoundID)45;
+LABEL_24:
+        v17 = v71;
+        goto LABEL_26;
+      }
+    }
+    v17 = (SoundID)a4;
+LABEL_26:
+    pAudioPlayer->PlaySound(v17, PID(OBJECT_Player,a4 + 80), 0, -1, 0, 0, 0, 0);
+    v18 = Actor::_43B3E0_CalcDamage(v7, v74);
+    v19 = HIDWORD(v7->pActorBuffs[3].uExpireTime) == 0;
+    v20 = SHIDWORD(v7->pActorBuffs[3].uExpireTime) < 0;
+    v77 = v18;
+    if ( !v20 && (!(v20 | v19) || LODWORD(v7->pActorBuffs[3].uExpireTime) > 0) )
+    {
+      v21 = v7->pActorBuffs[3].uPower;
+      if ( v21 )
+        v77 /= (signed int)v21;
+    }
+    if ( v74 )
+    {
+      if ( v74 == 1 )
+      {
+        v22 = v7->pMonsterInfo.uAttack2Type;
+      }
+      else
+      {
+        if ( v74 == 2 )
+        {
+          v23 = v7->pMonsterInfo.uSpell1ID;
+        }
+        else
+        {
+          if ( v74 != 3 )
+          {
+            if ( v74 == 4 )
+              v22 = v7->pMonsterInfo.field_3C_some_special_attack;
+            else
+              v22 = 4;
+            goto LABEL_43;
+          }
+          v23 = v7->pMonsterInfo.uSpell2ID;
+        }
+        v22 = LOBYTE(pSpellStats->pInfos[v23].uSchool);
+      }
+    }
+    else
+    {
+      v22 = v7->pMonsterInfo.uAttack1Type;
+    }
+LABEL_43:
+    if ( !(dword_6BE368_debug_settings_2 & 0x10) )
+    {
+      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)) )
+      {
+        v25 = v7->uAIState;
+        if ( v25 != 5 )
+        {
+          if ( v25 != 4 )
+          {
+            v26 = stru_50C198.CalcMagicalDamageToActor(v7, v22, v24);
+            v7->sCurrentHP -= v26;
+            if ( v26 )
+            {
+              if ( v7->sCurrentHP >= 1 )
+              {
+                Actor::AI_Stun(uActorID, PID(OBJECT_Player,a4), 0);
+                Actor::AggroSurroundingPeasants(uActorID, 1);
+              }
+              else
+              {
+                if ( pMonsterStats->pInfos[v7->pMonsterInfo.uID].bQuestMonster & 1 )
+                {
+                  v27 = byte_4D864C && BYTE2(pGame->uFlags) & 8 ? 10 * v7->uActorRadius : v7->uActorRadius;
+                  v74 = v27;
+                  if ( pRenderer->pRenderD3D )
+                  {
+                    if ( pGame->uFlags2 & GAME_FLAGS_2_DRAW_BLOODSPLATS )
+                    {
+                      v28 = (double)v74;
+                      v74 = v7->vPosition.z;
+                      v29 = (double)v74;
+                      v74 = v7->vPosition.y;
+                      v30 = v29;
+                      v31 = (double)v74;
+                      v74 = v7->vPosition.x;
+                      v32 = v31;
+                      v33 = (double)v74;
+                      pDecalBuilder->AddBloodsplat(v33, v32, v30, 1.0, 0.0, 0.0, v28, 0, 0);
+                    }
+                  }
+                }
+                Actor::Die(uActorID);
+                Actor::ApplyFineForKillingPeasant(uActorID);
+                Actor::AggroSurroundingPeasants(uActorID, 1);
+                if ( v7->pMonsterInfo.uExp )
+                  GivePartyExp(pMonsterStats->pInfos[v7->pMonsterInfo.uID].uExp);
+                v34 = SPEECH_51;
+                if ( rand() % 100 < 20 )
+                  v34 = ((signed int)v7->pMonsterInfo.uHP >= 100) + 1;
+                v6->PlaySound((PlayerSpeech)v34, 0);
+              }
+            }
+          }
+        }
+      }
+      if ( !(dword_6BE368_debug_settings_2 & 0x10)
+        && v7->pMonsterInfo.uSpecialAttack
+        && rand() % 100 < v7->pMonsterInfo.uLevel * v7->pMonsterInfo.uSpecialAttackType )
+        v6->_48DCF6(v7->pMonsterInfo.uSpecialAttack, v7);
+    }
+    if ( !pParty->bTurnBasedModeOn )
+    {
+      v35 = v6->GetActualEndurance();
+      v36 = (double)(20 - v6->GetParameterBonus(v35)) * flt_6BE3A4_debug_recmod1 * 2.133333333333333;
+      v6->SetRecoveryTime((signed __int64)v36);
+    }
+    if ( v77 )
+    {
+      v73 = (double)(signed int)v75;
+      if ( (double)v6->GetMaxHealth() * 0.25 < v73 )
+      {
+        if ( v6->sHealth > 0 )
+        {
+          if ( (double)v6->GetMaxHealth() * 0.25 >= (double)v6->sHealth )
+            v6->PlaySound(SPEECH_48, 0);
+        }
+      }
+    }
+    viewparams->bRedrawGameUI = 1;
+    return;
+  }
+  v37 = &pSpriteObjects[uActorID];
+  v38 = PID_TYPE(v37->spell_caster_pid);
+  v39 = PID_ID(v37->spell_caster_pid);
+  v40 = PID_TYPE(v37->spell_caster_pid);
+  uActorID = PID_ID(v37->spell_caster_pid);
+  v41 = v40 - 2;
+  if ( !v41 )
+    goto LABEL_80;
+  v42 = v41 - 1;
+  if ( !v42 )
+  {
+    v44 = &pActors[v39];
+    if ( a4 == -1 )
+      a4 = stru_50C198.which_player_would_attack(v44);
+    v45 = &pParty->pPlayers[a4];
+    v77 = Actor::_43B3E0_CalcDamage(v44, v74);
+    v46 = v37->uType;
+    if ( v37->uType == 545 )
+    {
+      LOBYTE(v51) = v45->GetActualSkillLevel(PLAYER_SKILL_UNARMED);
+      v52 = v51;
+      if ( (signed int)SkillToMastery(v51) >= 4 && rand() % 100 < (v52 & 0x3F) )
+      {
+		  sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[637], v45->pName);
+        ShowStatusBarString(pTmpBuf.data(), 2u);
+        v45->PlaySound(SPEECH_6, 0);
+        return;
+      }
+    }
+    else
+    {
+      if ( v46 != 555
+        && v46 != 510
+        && v46 != 500
+        && v46 != 515
+        && v46 != 505
+        && v46 != 530
+        && v46 != 525
+        && v46 != 520
+        && v46 != 535
+        && v46 != 540 )
+        goto LABEL_115;
+    }
+    if ( !stru_50C198.ActorHitOrMiss(v44, v45) )
+      return;
+    if ( (signed __int64)v45->pPlayerBuffs[13].uExpireTime > 0 )
+      v77 >>= 1;
+    if ( v45->HasEnchantedItemEquipped(36) )
+      v77 >>= 1;
+    if ( v45->HasEnchantedItemEquipped(69) )
+      v77 >>= 1;
+    if ( v45->HasItemEquipped(EQUIP_ARMOUR)
+		&& *(_DWORD *)&v45->pInventoryItems[v45->pEquipment.uArmor-1] == 504 )
+      v77 >>= 1;
+    v75 = 0;
+	v47 = (int)&v45->pEquipment;
+    do
+    {
+      if ( v45->HasItemEquipped((ITEM_EQUIP_TYPE)v75) )
+      {
+        v48 = *(int *)&v45[36 * *(int *)v47 + 496];
+        if ( v48 == 520 )
+          v77 >>= 1;
+        if ( v48 == 531 )
+          v77 >>= 1;
+        if ( v45->GetEquippedItemEquipType((ITEM_EQUIP_TYPE)v75) == EQUIP_SHIELD && SkillToMastery(v45->pActiveSkills[PLAYER_SKILL_SHIELD]) == 4 )
+          v77 >>= 1;
+      }
+      ++v75;
+      v47 += 4;
+    }
+    while ( (signed int)v75 <= 1 );
+LABEL_115:
+    if ( (signed __int64)v44->pActorBuffs[3].uExpireTime > 0 )
+    {
+      v49 = v44->pActorBuffs[3].uPower;
+      if ( v49 )
+        v77 /= (signed int)v49;
+    }
+    if ( !v74 )
+    {
+      v50 = v44->pMonsterInfo.uAttack1Type;
+      goto LABEL_133;
+    }
+    if ( v74 == 1 )
+    {
+      v50 = v44->pMonsterInfo.uAttack2Type;
+      goto LABEL_133;
+    }
+    if ( v74 == 2 )
+    {
+      v53 = v44->pMonsterInfo.uSpell1ID;
+    }
+    else
+    {
+      if ( v74 != 3 )
+      {
+        if ( v74 == 4 )
+          v50 = v44->pMonsterInfo.field_3C_some_special_attack;
+        else
+          v50 = 4;
+LABEL_133:
+        if ( !(dword_6BE368_debug_settings_2 & 0x10) )
+        {
+          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) )
+            {
+              v55 = v44->uAIState;
+              if ( v55 != 5 )
+              {
+                if ( v55 != 4 )
+                {
+                  v56 = stru_50C198.CalcMagicalDamageToActor(v44, v50, v54);
+                  v44->sCurrentHP -= v56;
+                  if ( v56 )
+                  {
+                    if ( v44->sCurrentHP >= 1 )
+                    {
+                      Actor::AI_Stun(uActorID, PID(OBJECT_Player,a4), 0);
+                      Actor::AggroSurroundingPeasants(uActorID, 1);
+                    }
+                    else
+                    {
+                      if ( pMonsterStats->pInfos[v44->pMonsterInfo.uID].bQuestMonster & 1 )
+                      {
+                        v57 = byte_4D864C && BYTE2(pGame->uFlags) & 8 ? 10 * v44->uActorRadius : v44->uActorRadius;
+                        v75 = v57;
+                        if ( pRenderer->pRenderD3D )
+                        {
+                          if ( pGame->uFlags2 & GAME_FLAGS_2_DRAW_BLOODSPLATS )
+                          {
+                            v58 = (double)(signed int)v75;
+                            v75 = v44->vPosition.z;
+                            v59 = (double)(signed int)v75;
+                            v75 = v44->vPosition.y;
+                            v60 = v59;
+                            v61 = (double)(signed int)v75;
+                            v75 = v44->vPosition.x;
+                            v62 = v61;
+                            v63 = (double)(signed int)v75;
+                            pDecalBuilder->AddBloodsplat(v63, v62, v60, 1.0, 0.0, 0.0, v58, 0, 0);
+                          }
+                        }
+                      }
+                      Actor::Die(uActorID);
+                      Actor::ApplyFineForKillingPeasant(uActorID);
+                      Actor::AggroSurroundingPeasants(uActorID, 1);
+                      if ( v44->pMonsterInfo.uExp )
+                        GivePartyExp(pMonsterStats->pInfos[v44->pMonsterInfo.uID].uExp);
+                      v64 = SPEECH_51;
+                      if ( rand() % 100 < 20 )
+                        v64 = ((signed int)v44->pMonsterInfo.uHP >= 100) + 1;
+                      v45->PlaySound((PlayerSpeech)v64, 0);
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+        if ( !v74
+          && !(dword_6BE368_debug_settings_2 & 0x10)
+          && v44->pMonsterInfo.uSpecialAttack
+          && rand() % 100 < v44->pMonsterInfo.uLevel * v44->pMonsterInfo.uSpecialAttackType )
+          v45->_48DCF6(v44->pMonsterInfo.uSpecialAttack, v44);
+        if ( !pParty->bTurnBasedModeOn )
+        {
+          v65 = v45->GetActualEndurance();
+          v66 = (double)(20 - v45->GetParameterBonus(v65))
+              * flt_6BE3A4_debug_recmod1
+              * 2.133333333333333;
+          v45->SetRecoveryTime((signed __int64)v66);
+        }
+        return;
+      }
+      v53 = v44->pMonsterInfo.uSpell2ID;
+    }
+    v50 = LOBYTE(pSpellStats->pInfos[v53].uSchool);
+    goto LABEL_133;
+  }
+  if ( v42 != 1 )
+    return;
+LABEL_80:
+  if ( a4 != -1 )
+  {
+    v43 = &pParty->pPlayers[a4];
+LABEL_168:
+    a4b = v43;
+    if ( v38 != OBJECT_Player || v37->spell_id != SPELL_BOW_ARROW)
+    {
+      v70 = v43->GetMaxHealth();
+      v68 = _43AFE3_calc_spell_damage(v37->spell_id, v37->spell_level, v37->spell_skill, v70);
+      v69 = LOBYTE(pSpellStats->pInfos[v37->spell_id].uSchool);
+    }
+    else
+    {
+      v68 = pParty->pPlayers[uActorID].CalculateRangedDamageTo(0);
+      v69 = 0;
+    }
+    a4b->ReceiveDamage(v68, (DAMAGE_TYPE)v69);
+    if ( v38 == OBJECT_Player && !qword_A750D8 )
+    {
+      qword_A750D8 = 256i64;
+      word_A750E0 = 44;
+      word_A750E2 = uActorID + 1;
+    }
+    return;
+  }
+  v74 = 0;
+  a4a = 1;
+  do
+  {
+    if ( pPlayers[a4a]->CanAct() )
+    {
+      v67 = v74++;
+      *(&v72 + v67) = a4a;
+    }
+    ++a4a;
+  }
+  while ( a4a <= 4 );
+  if ( v74 )
+  {
+    v43 = &pParty->pPlayers[*(&v72+rand()%v74)-1];//&stru_AA1058[3].pSounds[6972 * *(&v72 + rand() % v74) + 40552];
+    goto LABEL_168;
+  }
+}
+//----- (00421EA6) --------------------------------------------------------
+void __cdecl OnInventoryLeftClick()
+{
+  Player *v0; // ebx@1
+  signed int v1; // eax@2
+  signed int v2; // ecx@2
+  int v3; // eax@2
+  char v4; // sf@2
+  int v5; // eax@2
+  unsigned int v6; // eax@7
+  unsigned int v7; // esi@12
+  unsigned int v8; // eax@12
+  unsigned int v9; // eax@16
+  unsigned int v10; // eax@18
+  ItemGen this_; // [sp+Ch] [bp-3Ch]@1
+  POINT a2; // [sp+30h] [bp-18h]@4
+  unsigned int v13; // [sp+38h] [bp-10h]@13
+  unsigned int pY; // [sp+3Ch] [bp-Ch]@2
+  unsigned int pX; // [sp+40h] [bp-8h]@2
+  int a4; // [sp+44h] [bp-4h]@2
+
+  v0 = pPlayers[uActiveCharacter];
+  if ( pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] == 103 )
+  {
+    pMouse->GetClickPos(&pX, &pY);
+    pY = pY - 17;
+    v2 =pX - 14;
+    pX = v2;
+    v3 = 14 * (pY >> 5);
+    v2 >>= 5;
+    v4 = v2 + v3 < 0;
+    v5 = v2 + v3;
+    a4 = v5;
+    if ( !v4 )
+    {
+      if ( v5 <= 126 && pMouse->GetCursorPos(&a2)->x < 462
+            && pMouse->GetCursorPos(&a2)->x >= 14 )
+      {
+        if ( unk_50C9A0 )
+        {
+          v6 = v0->GetItemIDAtInventoryIndex(&a4);
+          if ( v6 )
+          {
+            *((char *)pGUIWindow_Settings->ptr_1C + 8) &= 0x7Fu;
+            *((short *)pGUIWindow_Settings->ptr_1C + 2) = uActiveCharacter - 1;
+            *((int *)pGUIWindow_Settings->ptr_1C + 3) = v6 - 1;
+            *((short *)pGUIWindow_Settings->ptr_1C + 3) = a4;
+            ptr_50C9A4 = (ItemGen *)&v0->pInventoryItems[v6-1];
+            unk_50C9A0 = 0;
+            if ( pMessageQueue_50CBD0->uNumMessages )
+              pMessageQueue_50CBD0->uNumMessages = pMessageQueue_50CBD0->pMessages[0].field_8 != 0;
+            pMouse->SetCursorBitmap("MICON1");
+            dword_50C9D0 = 113;
+            dword_50C9D4 = 0;
+            dword_50C9D8 = 256;
+          }
+          return;
+        }
+        if ( ptr_50C9A4 )
+          return;
+        v7 = pParty->pPickedItem.uItemID;
+        v8 = v0->GetItemIDAtInventoryIndex(&a4);
+        if ( !v7 )
+        {
+          if ( !v8 )
+            return;
+          memcpy(&pParty->pPickedItem, &v0->pInventoryItems[v8-1], sizeof(pParty->pPickedItem));
+          v0->RemoveItemAtInventoryIndex(a4);
+          v9 = pParty->pPickedItem.uItemID;
+          pMouse->SetCursorBitmap(pItemsTable->pItems[v9].pIconName);
+          return;
+        }
+        v13 = v8;
+        if ( v8 )
+        {
+          a2.y = (LONG)&v0->pInventoryItems[v8-1];
+          memcpy(&this_, (const void *)a2.y, sizeof(this_));
+          v0->RemoveItemAtInventoryIndex(a4);
+          pX = v0->AddItem2(a4, &pParty->pPickedItem);
+          if ( !pX )
+          {
+            pX = v0->AddItem2(0xFFFFFFFFu, &pParty->pPickedItem);
+            if ( !pX )
+            {
+              v0->PutItemArInventoryIndex(&this_, v13 - 1, a4);
+              memcpy((void *)a2.y, &this_, sizeof(ItemGen));
+              return;
+            }
+          }
+          v9 = this_.uItemID;
+          memcpy(&pParty->pPickedItem, &this_, sizeof(pParty->pPickedItem));
+          pMouse->SetCursorBitmap(pItemsTable->pItems[v9].pIconName);
+          return;
+        }
+        v10 = v0->AddItem(a4, v7);
+        pX = v10;
+        if ( v10 || (v10 = v0->AddItem(-1, pParty->pPickedItem.uItemID), (pX = v10) != 0) )
+        {
+          memcpy(&v0->pInventoryItems[v10-1], &pParty->pPickedItem, 0x24u);
+          pMouse->RemoveHoldingItem();
+        }
+      }
+    }
+  }
 }
\ No newline at end of file
--- a/Render.cpp	Sun Jun 23 14:27:32 2013 +0600
+++ b/Render.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -11016,4 +11016,8 @@
     break;
   }
 }
-
+//----- (0040DF3D) --------------------------------------------------------
+void __cdecl CallRenderPresent()
+{
+  pRenderer->Present();
+}
--- a/SaveLoad.cpp	Sun Jun 23 14:27:32 2013 +0600
+++ b/SaveLoad.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -23,8 +23,8 @@
 #include "stru123.h"
 #include "texts.h"
 #include "Log.h"
+#include "Allocator.h"
 #include "VideoPlayer.h"
-#include "Allocator.h"
 
 #include "mm7_data.h"
 
@@ -613,7 +613,6 @@
   }
   _chdir("..");
 }
-
 //----- (0046086A) --------------------------------------------------------
 void SaveNewGame()
 {
@@ -673,7 +672,178 @@
   }
   pAllocator->FreeChunk(pSave);
 }
+//----- (0045E03A) --------------------------------------------------------
+unsigned short * MakeScreenshot( signed int width, signed int height )
+{
+  //signed int v2; // edi@1
+  unsigned __int16 *v3; // ebx@1
+  int v4; // edx@7
+  unsigned __int8 v5; // cf@9
+  unsigned int v6; // ecx@9
+  unsigned __int16 *v7; // edi@9
+  int j; // ecx@9
+  //unsigned __int16 *v9; // edi@15
+  //int v10; // ecx@15
+  //LONG v11; // esi@15
+  //signed __int64 v12; // qax@18
+  //unsigned int v13; // ST10_4@21
+  HRESULT v14; // eax@21
+  int v15; // edi@29
+  signed __int64 v16; // qax@30
+  signed int v17; // edx@34
+  unsigned __int16 *v18; // edi@36
+  int k; // ecx@36
+  DDSURFACEDESC2 Dst; // [sp+4h] [bp-A0h]@6
+  unsigned __int16 *pPixels; // [sp+80h] [bp-24h]@1
+  float v23; // [sp+84h] [bp-20h]@1
+  unsigned __int16 *_this; // [sp+88h] [bp-1Ch]@21
+  float v25; // [sp+8Ch] [bp-18h]@1
+  unsigned int v26; // [sp+90h] [bp-14h]@17
+  //int v27; // [sp+94h] [bp-10h]@1
+  int v28; // [sp+98h] [bp-Ch]@16
+  int v29; // [sp+9Ch] [bp-8h]@15
+  //int v30; // [sp+A0h] [bp-4h]@1
 
+  //v30 = width;
+  //v2 = height;
+  //v27 = height;
+  v23 = game_viewport_width / (double)width;
+  v25 = game_viewport_height / (double)height;
+
+  pPixels = (unsigned __int16 *)malloc(2 * height * width);
+  memset(pPixels, 0 , 2 * height * width);
+
+  v3 = pPixels;
+  if ( pRenderer->pRenderD3D )
+  {
+    pRenderer->BeginSceneD3D();
+
+    if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
+      pIndoor->Draw();
+    else if (uCurrentlyLoadedLevelType == LEVEL_Outdoor)
+      pOutdoor->Draw();
+
+    pRenderer->DrawBillboards_And_MaybeRenderSpecialEffects_And_EndScene();
+    memset(&Dst, 0, 0x7Cu);
+    Dst.dwSize = sizeof(Dst);
+
+    if ( pRenderer->LockSurface_DDraw4(pRenderer->pBackBuffer4, &Dst, DDLOCK_WAIT) )
+    {
+      auto src = (unsigned __int16 *)Dst.lpSurface;
+      auto src_width = (Dst.lPitch / sizeof(short));
+      auto src_height = Dst.dwHeight;
+      auto dst = pPixels;
+      for (uint y = 0; y < height; ++y)
+      {
+        //uint src_y = (game_viewport_y + y * v25) * (Dst.lPitch / sizeof(short));
+        uint src_y = game_viewport_y + y * v25;
+        assert(game_viewport_y + y * v25 < src_height);
+        assert(y < height);
+
+        for (uint x = 0; x < width; ++x)
+        {
+          //uint src_x = game_viewport_x + x * v23;
+          uint src_x = game_viewport_x + x * v23;
+          assert(src_x < src_width);
+          assert(x < width);
+
+          dst[y * width + x] = (((63*y)/117) << 5) | 31*x/155;//31*y/117;//src[src_y * src_width + src_x];
+        }
+      }
+      ErrD3D(pRenderer->pBackBuffer4->Unlock(0));
+    }
+    else
+    {
+      __debugbreak(); // unrefactored
+      v4 = height;
+      if ( height > 0 )
+      {
+        do
+        {
+          if ( width > 0 )
+          {
+            v5 = width & 1;
+            v6 = (unsigned int)width >> 1;
+            memset(v3, 0, 4 * ((unsigned int)width >> 1));
+            v7 = &v3[2 * v6];
+            for ( j = v5; j; --j )
+            {
+              *v7 = 0;
+              ++v7;
+            }
+            v3 += width;
+          }
+          --v4;
+        }
+        while ( v4 );
+      }
+    }
+  }
+  else
+  {
+    pRenderer->BeginScene();
+    if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
+    {
+      pIndoor->Draw();
+    }
+    else
+    {
+      if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor )
+        pOutdoor->Draw();
+    }
+    _this = pRenderer->pTargetSurface;
+    v26 = pRenderer->uTargetSurfacePitch;
+    if ( pRenderer->pTargetSurface )
+    {
+      v29 = 0;
+      if ( height > 0 )
+      {
+        do
+        {
+          v28 = 0;
+          if ( width > 0 )
+          {
+            v15 = v26 * (unsigned __int64)(signed __int64)((double)v29 * v25 + 8.0);
+            do
+            {
+              v16 = (signed __int64)((double)v28++ * v23 + 8.0);
+              *v3 = _this[v15 + (int)v16];
+              ++v3;
+            }
+            while ( v28 < width );
+          }
+          ++v29;
+        }
+        while ( v29 < height );
+      }
+    }
+    else
+    {
+      if ( height > 0 )
+      {
+        v17 = height;
+        do
+        {
+          if ( width > 0 )
+          {
+            memset(v3, 0, 4 * ((unsigned int)width >> 1));
+            v18 = &v3[2 * ((unsigned int)width >> 1)];
+            for ( k = width & 1; k; --k )
+            {
+              *v18 = 0;
+              ++v18;
+            }
+            v3 += width;
+          }
+          --v17;
+        }
+        while ( v17 );
+      }
+    }
+    pRenderer->EndScene();
+  }
+  return pPixels;
+}
 //----- (0045E26C) --------------------------------------------------------
 void __thiscall SaveScreenshot(const char *pFilename)
 {
@@ -684,38 +854,4 @@
   v2 = MakeScreenshot(92, 68);
   pRenderer->SavePCXImage(v1, (char *)v2, 92, 68);
   free(v2);
-}
-
-//----- (00460706) --------------------------------------------------------
-void TryLoadLevelFromLOD()
-{
-  FILE *v0; // eax@1
-  FILE *v1; // esi@1
-  __int32 v2; // edi@2
-  char Ext[256]; // [sp+4h] [bp-40Ch]@1
-  char Dir[256]; // [sp+104h] [bp-30Ch]@1
-  char Filename[256]; // [sp+204h] [bp-20Ch]@1
-  char a1[260]; // [sp+304h] [bp-10Ch]@1
-  char Drive[4]; // [sp+408h] [bp-8h]@1
-  int DstBuf; // [sp+40Ch] [bp-4h]@2
-
-  strcpy(a1, pCurrentMapName.data());
-  _splitpath(a1, Drive, Dir, Filename, Ext);
-  sprintf(a1, "levels\\%s%s", Filename, ".lod");
-  v0 = fopen(a1, "rb");
-  v1 = v0;
-  if ( v0 )
-  {
-    fseek(v0, 0, 2);
-    v2 = ftell(v1);
-    rewind(v1);
-    ptr_6A0D08 = pAllocator->AllocNamedChunk(ptr_6A0D08, v2, "LevelLod");
-    fread(ptr_6A0D08, v2, 1u, v1);
-    fseek(v1, v2 - 6, 0);
-    DstBuf = 0;
-    fread(&DstBuf, 4u, 1u, v1);
-    fread(&_6A0D10_txt_lod_loading__unused, 2u, 1u, v1);
-    _6A0D0C_txt_lod_loading = (int)((char *)ptr_6A0D08 + DstBuf);
-    fclose(v1);
-  }
 }
\ No newline at end of file
--- a/Spells.cpp	Sun Jun 23 14:27:32 2013 +0600
+++ b/Spells.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -11,8 +11,15 @@
 #include "texts.h"
 
 #include "mm7_data.h"
-
-
+#include "Party.h"
+#include "Math.h"
+#include "SpriteObject.h"
+#include "ObjectList.h"
+#include "Indoor.h"
+#include "AudioPlayer.h"
+#include "Actor.h"
+#include "Game.h"
+#include "stru6.h"
 
 
 std::array<TownPortalData, 6> TownPortalList = //4ECBB8
@@ -433,118 +440,779 @@
 		}
 
 	}
-//----- (0045828B) --------------------------------------------------------
-unsigned int __fastcall GetSpellColor(signed int a1)
+//----- (00448DF8) --------------------------------------------------------
+void __fastcall EventCastSpell(int spellnum, int uSkillLevel, int uSkill, int fromx, int fromy, int fromz, int tox, int toy, int toz)//sub_448DF8
 {
-  unsigned __int16 v1; // dx@3
-  unsigned __int16 v2; // cx@6
-  unsigned __int16 v4; // [sp-4h] [bp-4h]@3
+  int v9; // esi@1
+  double v10; // st7@4
+  double v11; // st6@4
+  double v12; // st5@4
+  double v13; // st7@6
+  int v14; // ST44_4@7
+  signed int v15; // ebx@9
+  signed int v16; // edx@15
+  char *v17; // ecx@16
+  unsigned __int16 v18; // ax@20
+  char *v19; // ecx@31
+  int v20; // edx@35
+  signed int v21; // edx@37
+  char *v22; // ecx@38
+  unsigned __int16 v23; // ax@41
+  int i; // esi@42
+  signed int v25; // edx@55
+  char *v26; // ecx@56
+  unsigned __int16 v27; // ax@59
+  int j; // esi@60
+  signed int v29; // edx@66
+  char *v30; // ecx@67
+  unsigned __int16 v31; // ax@70
+  //Player *v32; // eax@80
+  //unsigned __int16 v33; // si@85
+  int v34; // eax@96
+  int v35; // eax@97
+  unsigned __int64 v36; // qax@99
+  SpellBuff *v37; // ecx@99
+  int v38; // esi@103
+  signed __int64 v39; // qax@105
+  int v40; // ebx@108
+  int v41; // ebx@109
+  int v42; // esi@111
+  int v43; // ebx@111
+  int v44; // eax@117
+  //unsigned __int16 v45; // si@137
+  unsigned __int16 v46; // [sp-8h] [bp-BCh]@99
+  int v47; // [sp-4h] [bp-B8h]@35
+  unsigned __int16 v48; // [sp-4h] [bp-B8h]@99
+  int v49; // [sp+0h] [bp-B4h]@35
+  int v50; // [sp+0h] [bp-B4h]@99
+  int v51; // [sp+4h] [bp-B0h]@35
+  unsigned __int8 v52; // [sp+4h] [bp-B0h]@99
+  float v53; // [sp+14h] [bp-A0h]@4
+  float v54; // [sp+18h] [bp-9Ch]@4
+  int v55; // [sp+28h] [bp-8Ch]@7
+  unsigned int yaw; // [sp+30h] [bp-84h]@7
+  int pitch; // [sp+34h] [bp-80h]@7
+  //SpriteObject a1; // [sp+38h] [bp-7Ch]@12
+  int v59; // [sp+A8h] [bp-Ch]@1
+  int v60; // [sp+ACh] [bp-8h]@1
+  //int spellnum_; // [sp+B0h] [bp-4h]@1
+  //signed int levela; // [sp+BCh] [bp+8h]@80
+  int a6_4; // [sp+C8h] [bp+14h]@117
+  float a7a; // [sp+CCh] [bp+18h]@6
+  signed int a7b; // [sp+CCh] [bp+18h]@12
+  int a7c; // [sp+CCh] [bp+18h]@29
+  int a7d; // [sp+CCh] [bp+18h]@55
+  float a8a; // [sp+D0h] [bp+1Ch]@6
+  int a8b; // [sp+D0h] [bp+1Ch]@37
+  int a8c; // [sp+D0h] [bp+1Ch]@55
+  float toza; // [sp+D4h] [bp+20h]@6
 
-  if ( a1 < 1 )
+  v9 = 0;
+  v59 = uSkillLevel + 1;
+  //spellnum_ = spellnum;
+  v60 = 0;
+  if ( tox || toy || toz )
   {
-    if ( a1 < 12 )
-    {
-      if ( a1 < 23 )
-      {
-        if ( a1 < 34 )
-        {
-          if ( a1 < 45 )
-          {
-            if ( a1 < 56 )
-            {
-              if ( a1 < 67 )
-              {
-                if ( a1 < 78 )
-                {
-                  if ( a1 < 89 )
-                    goto LABEL_31;
-                  goto LABEL_28;
-                }
-LABEL_25:
-                if ( a1 < 89 )
-                {
-                  v4 = 155;
-                  v2 = 255;
-                  goto LABEL_30;
-                }
-LABEL_28:
-                if ( a1 < 100 )
-                {
-                  v4 = 240;
-                  v2 = 192;
-                  goto LABEL_30;
-                }
-LABEL_31:
-                v4 = 0;
-                v1 = 0;
-                goto LABEL_32;
-              }
-LABEL_21:
-              if ( a1 < 78 )
-              {
-                v4 = 0;
-                v1 = 128;
-                goto LABEL_23;
-              }
-              goto LABEL_25;
-            }
-LABEL_18:
-            if ( a1 < 67 )
-            {
-              v4 = 255;
-              v1 = 15;
-              v2 = 235;
-              return TargetColor(v2, v1, v4);
-            }
-            goto LABEL_21;
-          }
-LABEL_15:
-          if ( a1 < 56 )
-          {
-            v2 = 225;
-            goto LABEL_13;
-          }
-          goto LABEL_18;
-        }
-LABEL_11:
-        if ( a1 < 45 )
-        {
-          v2 = 128;
-LABEL_13:
-          v4 = v2;
-LABEL_30:
-          v1 = v2;
-          return TargetColor(v2, v1, v4);
-        }
-        goto LABEL_15;
-      }
-LABEL_8:
-      if ( a1 < 34 )
-      {
-        v4 = 255;
-        v1 = 128;
-LABEL_32:
-        v2 = 0;
-        return TargetColor(v2, v1, v4);
-      }
-      goto LABEL_11;
-    }
+    v10 = (double)tox - (double)fromx;
+    v53 = v10;
+    v11 = (double)toy - (double)fromy;
+    v54 = v11;
+    v12 = (double)toz;
+  }
+  else
+  {
+    v10 = (double)pParty->vPosition.x - (double)fromx;
+    v53 = v10;
+    v11 = (double)pParty->vPosition.y - (double)fromy;
+    v54 = v11;
+    v12 = (double)(pParty->vPosition.z + pParty->sEyelevel);
+  }
+  a7a = v12 - (double)fromz;
+  toza = v11 * v11;
+  a8a = v10 * v10;
+  v13 = sqrt(a7a * a7a + a8a + toza);
+  if ( v13 <= 1.0 )
+  {
+    LOBYTE(v55) = 1;
+    yaw = 0;
+    pitch = 0;
   }
   else
   {
-    if ( a1 < 12 )
+    v55 = (signed __int64)v13;
+    v14 = (signed __int64)sqrt(a8a + toza);
+    yaw = stru_5C6E00->Atan2((signed __int64)v53, (signed __int64)v54);
+    pitch = stru_5C6E00->Atan2(v14, (signed __int64)a7a);
+  }
+  v15 = v59;
+  if ( v59 <= 0 || v59 > 4 )
+    v15 = 1;
+  a7b = v15;
+
+  SpriteObject a1; // [sp+38h] [bp-7Ch]@12
+  //SpriteObject::SpriteObject(&a1);
+
+  a1.uType = stru_4E3ACC[spellnum].uType;
+  if ( spellnum > 58 )
+  {
+    if ( spellnum == 69 )
+      goto LABEL_117;
+    if ( spellnum != 83 )
+      return;
+    v40 = v15 - 2;
+    if ( v40 )
     {
-      v4 = 0;
-      v1 = 85;
-LABEL_23:
-      v2 = 255;
-      return TargetColor(v2, v1, v4);
+      v41 = v40 - 1;
+      if ( !v41 )
+      {
+        v42 = 14400 * uSkill;
+        v43 = 4 * uSkill + 10;
+        pGame->pStru6Instance->SetPlayerBuffAnim(0x53u, 0);
+        pGame->pStru6Instance->SetPlayerBuffAnim(0x53u, 1u);
+        pGame->pStru6Instance->SetPlayerBuffAnim(0x53u, 2u);
+        pGame->pStru6Instance->SetPlayerBuffAnim(0x53u, 3u);
+        v39 = (signed __int64)((double)(v42 << 7) * 0.033333335);
+        v37 = &pParty->pPartyBuffs[PARTY_BUFF_DAY_OF_GODS];
+        v36 = pParty->uTimePlayed + v39;
+        v37->Apply(v36, a7b, v43, 0, 0);
+        goto LABEL_139;
+      }
+      if ( v41 == 1 )
+      {
+        v42 = 18000 * uSkill;
+        v43 = 5 * uSkill + 10;
+       pGame->pStru6Instance->SetPlayerBuffAnim(0x53u, 0);
+       pGame->pStru6Instance->SetPlayerBuffAnim(0x53u, 1u);
+       pGame->pStru6Instance->SetPlayerBuffAnim(0x53u, 2u);
+       pGame->pStru6Instance->SetPlayerBuffAnim(0x53u, 3u);
+       v39 = (signed __int64)((double)(v42 << 7) * 0.033333335);
+       v37 = &pParty->pPartyBuffs[PARTY_BUFF_DAY_OF_GODS];
+       v36 = pParty->uTimePlayed + v39;
+       v37->Apply(v36, a7b, v43, 0, 0);
+       goto LABEL_139;
+      }
     }
+    v42 = 10800 * uSkill;
+    v43 = 3 * uSkill + 10;
+    pGame->pStru6Instance->SetPlayerBuffAnim(0x53u, 0);
+    pGame->pStru6Instance->SetPlayerBuffAnim(0x53u, 1u);
+    pGame->pStru6Instance->SetPlayerBuffAnim(0x53u, 2u);
+    pGame->pStru6Instance->SetPlayerBuffAnim(0x53u, 3u);
+    v39 = (signed __int64)((double)(v42 << 7) * 0.033333335);
+    v37 = &pParty->pPartyBuffs[PARTY_BUFF_DAY_OF_GODS];
+    v36 = pParty->uTimePlayed + v39;
+    v37->Apply(v36, a7b, v43, 0, 0);
+    goto LABEL_139;
   }
-  if ( a1 >= 23 )
-    goto LABEL_8;
-  v4 = 255;
-  v1 = 212;
-  v2 = 150;
-  return TargetColor(v2, v1, v4);
+  if ( spellnum != 58 )
+  {
+    switch ( spellnum )
+    {
+      case 2:
+      case 6:
+      case 18:
+      case 26:
+      case 29:
+      case 32:
+      case 39:
+      case 41:
+        a1.stru_24.Reset();
+        v16 = 0;
+        a1.spell_id = spellnum;
+        a1.spell_level = uSkill;
+        a1.spell_skill = v15;
+        if ( (signed int)pObjectList->uNumObjects <= 0 )
+        {
+          v18 = 0;
+          a1.uObjectDescID = v18;
+          *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
+          a1.vPosition.x = fromx;
+          a1.uAttributes = 16;
+          a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
+          a1.field_60_distance_related_prolly_lod = v55;
+          v20 = yaw;
+          a1.uSpriteFrameID = 0;
+          a1.spell_caster_pid = 8000 | OBJECT_Item;
+          a1.spell_target_pid = 0;
+          a1.uFacing = yaw;
+          a1.uSoundID = 0;
+          v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
+          a1.Create(v20, pitch, v49, 0);
+          goto LABEL_139;
+        }
+        v17 = (char *)&pObjectList->pObjects->uObjectID;
+        while ( (short)a1.uType != *(short *)v17 )
+        {
+          ++v16;
+          v17 += 56;
+          if ( v16 >= (signed int)pObjectList->uNumObjects )
+          {
+            v18 = 0;
+            a1.uObjectDescID = v18;
+            *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
+            a1.vPosition.x = fromx;
+            a1.uAttributes = 16;
+            a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
+            a1.field_60_distance_related_prolly_lod = v55;
+            v20 = yaw;
+            a1.uSpriteFrameID = 0;
+            a1.spell_caster_pid = 8000 | OBJECT_Item;
+            a1.spell_target_pid = 0;
+            a1.uFacing = yaw;
+            a1.uSoundID = 0;
+            v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
+            a1.Create(v20, pitch, v49, 0);
+            goto LABEL_139;
+          }
+        }
+        v18 = v16;
+        a1.uObjectDescID = v18;
+        *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
+        a1.vPosition.x = fromx;
+        a1.uAttributes = 16;
+        a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
+        a1.field_60_distance_related_prolly_lod = v55;
+        v20 = yaw;
+        a1.uSpriteFrameID = 0;
+        a1.spell_caster_pid = 8000 | OBJECT_Item;
+        a1.spell_target_pid = 0;
+        a1.uFacing = yaw;
+        a1.uSoundID = 0;
+        v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
+        a1.Create(v20, pitch, v49, 0);
+        goto LABEL_139;
+      case 24:
+        switch ( v15 )
+        {
+          case 1:
+            v60 = 1;
+            break;
+          case 2:
+            v60 = 3;
+            break;
+          case 3:
+            v60 = 5;
+            break;
+          case 4:
+            v60 = 7;
+            break;
+        }
+        a7c = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360;
+        if ( v60 != 1 )
+        {
+          a8b = a7c / (v60 - 1);
+          a1.stru_24.Reset();
+          v21 = 0;
+          a1.spell_id = spellnum;
+          a1.spell_level = uSkill;
+          a1.spell_skill = v15;
+          if ( (signed int)pObjectList->uNumObjects <= 0 )
+          {
+            v23 = 0;
+          }
+          else
+          {
+            v22 = (char *)&pObjectList->pObjects->uObjectID;
+            while ( (short)a1.uType != *(short *)v22 )
+            {
+              ++v21;
+              v22 += 56;
+              if ( v21 >= (signed int)pObjectList->uNumObjects )
+              {
+                v23 = 0;
+                a1.uObjectDescID = v23;
+                *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
+                a1.vPosition.x = fromx;
+                a1.uAttributes = 16;
+                a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
+                a1.field_60_distance_related_prolly_lod = v55;
+                a1.uSpriteFrameID = 0;
+                a1.spell_caster_pid = 8000 | OBJECT_Item;
+                a1.spell_target_pid = 4;
+                a1.uSoundID = 0;
+                for ( i = a7c / -2; i <= a7c / 2; i += a8b )
+                {
+                  a1.uFacing = i + yaw;
+                  a1.Create((signed __int16)(i + (short)yaw), pitch, pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed, 0);
+                }
+                goto LABEL_139;
+              }
+            }
+            v23 = v21;
+          }
+          a1.uObjectDescID = v23;
+          *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
+          a1.vPosition.x = fromx;
+          a1.uAttributes = 16;
+          a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
+          a1.field_60_distance_related_prolly_lod = v55;
+          a1.uSpriteFrameID = 0;
+          a1.spell_caster_pid = 8000 | OBJECT_Item;
+          a1.spell_target_pid = 4;
+          a1.uSoundID = 0;
+          for ( i = a7c / -2; i <= a7c / 2; i += a8b )
+          {
+            a1.uFacing = i + yaw;
+            a1.Create((signed __int16)(i + (short)yaw), pitch, pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed, 0);
+          }
+          goto LABEL_139;
+        }
+        a1.stru_24.Reset();
+        v16 = 0;
+        a1.spell_id = spellnum;
+        a1.spell_level = uSkill;
+        a1.spell_skill = v15;
+        if ( (signed int)pObjectList->uNumObjects <= 0 )
+       {
+         v18 = 0;
+         a1.uObjectDescID = v18;
+         *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
+         a1.vPosition.x = fromx;
+         a1.uAttributes = 16;
+         a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
+         a1.field_60_distance_related_prolly_lod = v55;
+         v20 = yaw;
+         a1.uSpriteFrameID = 0;
+         a1.spell_caster_pid = 8000 | OBJECT_Item;
+         a1.spell_target_pid = 0;
+         a1.uFacing = yaw;
+         a1.uSoundID = 0;
+         v51 = 0;
+         v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
+         v47 = pitch;
+         a1.Create(v20, v47, v49, v51);
+         goto LABEL_139;
+       }
+        v19 = (char *)&pObjectList->pObjects->uObjectID;
+        do
+        {
+          if ( (short)a1.uType == *(short *)v19 )
+          {
+            v18 = v16;
+            a1.uObjectDescID = v18;
+            *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
+            a1.vPosition.x = fromx;
+            a1.uAttributes = 16;
+            a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
+            a1.field_60_distance_related_prolly_lod = v55;
+            v20 = yaw;
+            a1.uSpriteFrameID = 0;
+            a1.spell_caster_pid = 8000 | OBJECT_Item;
+            a1.spell_target_pid = 0;
+            a1.uFacing = yaw;
+            a1.uSoundID = 0;
+            v51 = 0;
+            v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
+            v47 = pitch;
+            a1.Create(v20, v47, v49, v51);
+            goto LABEL_139;
+          }
+          ++v16;
+          v19 += 56;
+        }
+        while ( v16 < (signed int)pObjectList->uNumObjects );
+        v18 = 0;
+        a1.uObjectDescID = v18;
+        *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
+        a1.vPosition.x = fromx;
+        a1.uAttributes = 16;
+        a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
+        a1.field_60_distance_related_prolly_lod = v55;
+        v20 = yaw;
+        a1.uSpriteFrameID = 0;
+        a1.spell_caster_pid = 8000 | OBJECT_Item;
+        a1.spell_target_pid = 0;
+        a1.uFacing = yaw;
+        a1.uSoundID = 0;
+        v51 = 0;
+        v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
+        v47 = pitch;
+        a1.Create(v20, v47, v49, v51);
+        goto LABEL_139;
+      case 15:
+        switch ( v15 )
+        {
+          case 1:
+            v60 = 3;
+            break;
+          case 2:
+            v60 = 5;
+            break;
+          case 3:
+            v60 = 7;
+            break;
+          case 4:
+            v60 = 9;
+            break;
+        }
+        a7d = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360;
+        a8c = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360 / (v60 - 1);
+        a1.stru_24.Reset();
+        v25 = 0;
+        a1.spell_id = spellnum;
+        a1.spell_level = uSkill;
+        a1.spell_skill = v15;
+        if ( (signed int)pObjectList->uNumObjects <= 0 )
+        {
+          v27 = 0;
+          a1.uObjectDescID = v27;
+          *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
+          a1.vPosition.x = fromx;
+          a1.uAttributes = 16;
+          a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
+          a1.field_60_distance_related_prolly_lod = v55;
+          a1.uSpriteFrameID = 0;
+          a1.spell_caster_pid = 8000 | OBJECT_Item;
+          a1.spell_target_pid = 4;
+          a1.uSoundID = 0;
+          for ( j = a7d / -2; j <= a7d / 2; j += a8c )
+          {
+            a1.uFacing = j + yaw;
+            a1.Create((signed __int16)(j + (short)yaw), pitch, pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed, 0);
+          }
+          goto LABEL_139;
+        }
+        v26 = (char *)&pObjectList->pObjects->uObjectID;
+        while ( (short)a1.uType != *(short *)v26 )
+        {
+          ++v25;
+          v26 += 56;
+          if ( v25 >= (signed int)pObjectList->uNumObjects )
+          {
+            v27 = 0;
+            a1.uObjectDescID = v27;
+            *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
+            a1.vPosition.x = fromx;
+            a1.uAttributes = 16;
+            a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
+            a1.field_60_distance_related_prolly_lod = v55;
+            a1.uSpriteFrameID = 0;
+            a1.spell_caster_pid = 8000 | OBJECT_Item;
+            a1.spell_target_pid = 4;
+            a1.uSoundID = 0;
+            for ( j = a7d / -2; j <= a7d / 2; j += a8c )
+            {
+              a1.uFacing = j + yaw;
+              a1.Create((signed __int16)(j + (short)yaw), pitch, pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed, 0);
+            }
+            goto LABEL_139;
+          }
+        }
+        v27 = v25;
+        a1.uObjectDescID = v27;
+        *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
+        a1.vPosition.x = fromx;
+        a1.uAttributes = 16;
+        a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
+        a1.field_60_distance_related_prolly_lod = v55;
+        a1.uSpriteFrameID = 0;
+        a1.spell_caster_pid = 8000 | OBJECT_Item;
+        a1.spell_target_pid = 4;
+        a1.uSoundID = 0;
+        for ( j = a7d / -2; j <= a7d / 2; j += a8c )
+        {
+          a1.uFacing = j + yaw;
+          a1.Create(
+            (signed __int16)(j + (short)yaw),
+            pitch,
+            pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed,
+            0);
+        }
+        goto LABEL_139;
+      case 43:
+        if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
+          return;
+        a1.stru_24.Reset();
+        v29 = 0;
+        a1.spell_id = spellnum;
+        a1.spell_level = uSkill;
+        a1.spell_skill = v15;
+        if ( (signed int)pObjectList->uNumObjects <= 0 )
+        {
+          v31 = 0;
+          a1.uObjectDescID = v31;
+          *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
+          a1.vPosition.x = fromx;
+          a1.uAttributes = 16;
+          a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
+          a1.field_60_distance_related_prolly_lod = v55;
+          a1.uSpriteFrameID = 0;
+          a1.spell_caster_pid = 8000 | OBJECT_Item;
+          a1.spell_target_pid = 4;
+          a1.uSoundID = 0;
+          v51 = 0;
+          v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
+          v20 = yaw;
+          v47 = (signed int)stru_5C6E00->uIntegerHalfPi / 2;
+          a1.Create(v20, v47, v49, v51);
+          goto LABEL_139;
+        }
+        v30 = (char *)&pObjectList->pObjects->uObjectID;
+        break;
+
+      case SPELL_FIRE_HASTE:
+        if ( v15 > 0 )
+        {
+          if ( v15 <= 2 )
+          {
+            v9 = 60 * (uSkill + 60);
+          }
+          else
+          {
+            if ( v15 == 3 )
+            {
+              v9 = 180 * (uSkill + 20);
+            }
+            else
+            {
+              if ( v15 == 4 )
+                v9 = 240 * (uSkill + 15);
+            }
+          }
+        }
+        //levela = 1;
+        //v32 = pParty->pPlayers;//[0].pConditions[1];
+        //do
+        for (uint i = 0; i < 4; ++i)
+          if (pParty->pPlayers[i].pConditions[Player::Condition_Weak])
+            return;
+		//while ( v32 <= &pParty->pPlayers[3] );
+        //if ( !levela )
+        //  return;
+        pParty->pPartyBuffs[PARTY_BUFF_HASTE].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(v9 * 128) * 0.033333335),
+          v15,
+          0,
+          0,
+          0);
+        //v33 = spellnum_;
+        pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 0);
+        pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 1);
+        pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 2);
+        pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 3);
+        goto LABEL_138;
+      case 17:
+      case 38:
+      case 51:
+        switch ( v15 )
+        {
+          case 1:
+          case 2:
+            v9 = 300 * (uSkill + 12);
+            break;
+          case 3:
+            v9 = 900 * (uSkill + 4);
+            break;
+          case 4:
+            v9 = 3600 * (uSkill + 1);
+            break;
+        }
+        switch ( spellnum )
+        {
+          case 17:
+            v60 = 0;
+            uSkill = 14;
+            break;
+          case 38:
+            v35 = uSkill + 5;
+            uSkill = 15;
+            v60 = v35;
+            break;
+          case 51:
+            v34 = uSkill + 5;
+            uSkill = 9;
+            v60 = v34;
+            break;
+        }
+        pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 0);
+        pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 1);
+        pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 2);
+        pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 3);
+        v52 = 0;
+        v50 = 0;
+        v48 = v60;
+        v46 = v15;
+        v36 = pParty->uTimePlayed + (signed int)(signed __int64)((double)(v9 << 7) * 0.033333335);
+        v37 = &pParty->pPartyBuffs[uSkill];
+        v37->Apply(v36, v46, v48, v50, v52);
+        goto LABEL_139;;
+      case 8:
+        if ( v15 == 2 || v15 == 3 || v15 != 4 )
+          v38 = 60 * uSkill;
+        else
+          v38 = 600 * uSkill;
+        pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 0);
+        pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 1);
+        pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 2);
+        pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 3);
+        v52 = 0;
+        v50 = 0;
+        v48 = uSkill;
+        v46 = v15;
+        v39 = (signed __int64)((double)(v38 << 7) * 0.033333335);
+        v37 = &pParty->pPartyBuffs[PARTY_BUFF_IMMOLATION];
+        v36 = pParty->uTimePlayed + v39;
+        v37->Apply(v36, v46, v48, v50, v52);
+        goto LABEL_139;
+      case 3:
+      case 14:
+      case 25:
+      case 36:
+        goto LABEL_117;
+      default:
+        return;
+    }
+    while ( (short)a1.uType != *(short *)v30 )
+    {
+      ++v29;
+      v30 += 56;
+      if ( v29 >= (signed int)pObjectList->uNumObjects )
+      {
+        v31 = 0;
+        a1.uObjectDescID = v31;
+        *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
+        a1.vPosition.x = fromx;
+        a1.uAttributes = 16;
+        a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
+        a1.field_60_distance_related_prolly_lod = v55;
+        a1.uSpriteFrameID = 0;
+        a1.spell_caster_pid = 8000 | OBJECT_Item;
+        a1.spell_target_pid = 4;
+        a1.uSoundID = 0;
+        v51 = 0;
+        v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
+        v20 = yaw;
+        v47 = (signed int)stru_5C6E00->uIntegerHalfPi / 2;
+        a1.Create(v20, v47, v49, v51);
+        goto LABEL_139;
+      }
+    }
+    v31 = v29;
+    a1.uObjectDescID = v31;
+    *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
+    a1.vPosition.x = fromx;
+    a1.uAttributes = 16;
+    a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
+    a1.field_60_distance_related_prolly_lod = v55;
+    a1.uSpriteFrameID = 0;
+    a1.spell_caster_pid = 8000 | OBJECT_Item;
+    a1.spell_target_pid = 4;
+    a1.uSoundID = 0;
+    v51 = 0;
+    v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
+    v20 = yaw;
+    v47 = (signed int)stru_5C6E00->uIntegerHalfPi / 2;
+    a1.Create(v20, v47, v49, v51);
+    goto LABEL_139;
+  }
+LABEL_117:
+  v44 = uSkill;
+  a6_4 = 3600 * uSkill;
+  if ( v15 == 1 )
+  {
+    v60 = v44;
+    goto LABEL_125;
+  }
+  if ( v15 == 2 )
+  {
+    v44 = 2 * uSkill;
+    v60 = v44;
+    goto LABEL_125;
+  }
+  if ( v15 == 3 )
+  {
+    v44 = 3 * uSkill;
+    v60 = v44;
+    goto LABEL_125;
+  }
+  if ( v15 == 4 )
+  {
+    v44 = 4 * uSkill;
+    v60 = v44;
+    goto LABEL_125;
+  }
+LABEL_125:
+  switch ( spellnum )
+  {
+    case 3:
+      uSkill = 6;
+      break;
+    case 14:
+      uSkill = 0;
+      break;
+    case 25:
+      uSkill = 17;
+      break;
+    case 36:
+      uSkill = 4;
+      break;
+    case 58:
+      uSkill = 12;
+      break;
+    case 69:
+      uSkill = 1;
+      break;
+  }
+  //v45 = spellnum_;
+  pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 0);
+  pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 1);
+  pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 2);
+  pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 3);
+  pParty->pPartyBuffs[uSkill].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)a6_4 * 4.2666669), v15, v60, 0, 0);
+  //levela = 1;
+LABEL_138:
+  //if ( levela )
+LABEL_139:
+    pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[spellnum], 0, 0, fromx, fromy, 0, 0, 0);
+}
+//----- (00427769) --------------------------------------------------------
+bool __fastcall sub_427769_spell(unsigned int uSpellID)
+{
+  bool result; // eax@2
+
+  __debugbreak(); // refactor
+  if ( *(&pSpellDatas[0].field_12 + 20 * uSpellID) & 0xC )
+    result = 1;
+  else
+    result = 0;
+  return result;
+}
+//----- (0043AFE3) --------------------------------------------------------
+int __fastcall _43AFE3_calc_spell_damage(int a1, int a2, signed int a3, int a4)
+{
+  int result; // eax@1
+  unsigned int v5; // [sp-4h] [bp-8h]@9
+
+  result = 0;
+  if ( a1 == 7 )
+  {
+    if ( a3 <= 0 )
+      return result;
+    if ( a3 <= 2 )
+    {
+      v5 = 6;
+    }
+    else
+    {
+      if ( a3 == 3 )
+      {
+        v5 = 8;
+      }
+      else
+      {
+        if ( a3 != 4 )
+          return result;
+        v5 = 10;
+      }
+    }
+    result = GetDiceResult(a2, v5);
+  }
+  else
+  {
+    if ( a1 == 44 )
+      result = a4 * (LOBYTE(pSpellDatas[40].field_10) + 2 * a2) / 100;
+    else
+      result = *((char *)&pSpellDatas[0].field_10 + 20 * a1)
+             + GetDiceResult(a2, *((char *)&pSpellDatas[0].field_10 + 20 * a1 + 1));
+  }
+  return result;
 }
\ No newline at end of file
--- a/SpriteObject.cpp	Sun Jun 23 14:27:32 2013 +0600
+++ b/SpriteObject.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -1088,7 +1088,21 @@
         }
     uNumSpriteObjects = new_obj_pos;
     }
+//----- (00408896) --------------------------------------------------------
+void InitializeSpriteObjects()
+{
+  for (uint i = 0; i < uNumSpriteObjects; ++i)
+  {
+    auto item = &pSpriteObjects[i];
 
+    if (item->uType &&
+        (item->uSoundID & 8 || pObjectList->pObjects[item->uType].uFlags & 0x10))
+      SpriteObject::OnInteraction(i);
+  }
+
+  for (uint i = 0; i < 100; ++i)
+    array_5118E8.pElements[i].field_C_time_left = 0;
+}
 //----- (0046BEF1) --------------------------------------------------------
 void SpriteObject::_46BEF1_apply_spells_aoe()
 {
--- a/Sprites.cpp	Sun Jun 23 14:27:32 2013 +0600
+++ b/Sprites.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -12,6 +12,10 @@
 #include "FrameTableInc.h"
 
 #include "mm7_data.h"
+#include "Outdoor.h"
+#include "DecorationList.h"
+#include "MM7.h"
+#include "Actor.h"
 
 
 
@@ -659,4 +663,120 @@
     result = 0;
   }
   return result;
-}
\ No newline at end of file
+}
+//----- (0046E26D) --------------------------------------------------------
+void __fastcall _46E26D_collide_against_sprites(signed int a1, signed int a2)
+{
+  int v2; // edx@5
+  unsigned __int16 *v3; // eax@5
+  unsigned __int16 v4; // ax@6
+  LevelDecoration *v5; // edi@7
+  DecorationDesc *v6; // esi@8
+  int v7; // edx@9
+  int v8; // eax@9
+  int v9; // ecx@11
+  int v10; // ebx@13
+  int v11; // esi@13
+  int v12; // ebp@15
+  int v13; // ebx@15
+  int v14; // esi@16
+  int v15; // edi@17
+  int v16; // eax@17
+  int v17; // esi@19
+  char v18; // zf@23
+  int v19; // [sp+0h] [bp-10h]@15
+  unsigned __int16 *v20; // [sp+4h] [bp-Ch]@5
+  int v21; // [sp+8h] [bp-8h]@15
+  int v22; // [sp+Ch] [bp-4h]@13
+
+  if ( a1 >= 0 )
+  {
+    if ( a1 <= 127 )
+    {
+      if ( a2 >= 0 )
+      {
+        if ( a2 <= 127 )
+        {
+          v2 = a1 + (a2 << 7);
+          v3 = &pOutdoor->pFaceIDLIST[pOutdoor->pOMAP[v2]];
+          v20 = &pOutdoor->pFaceIDLIST[pOutdoor->pOMAP[v2]];
+          if ( v3 )
+          {
+            do
+            {
+              v4 = *v3;
+              if ( PID_TYPE(v4) == OBJECT_Decoration)
+              {
+                v5 = &pLevelDecorations[(signed __int16)v4 >> 3];
+                if ( !(v5->field_2 & 0x20) )
+                {
+                  v6 = &pDecorationList->pDecorations[v5->uDecorationDescID];
+                  if (!v6->CanMoveThrough())
+                  {
+                    v7 = v6->uRadius;
+                    v8 = v5->vPosition.x;
+                    if ( stru_721530.sMaxX <= v8 + v7 )
+                    {
+                      if ( stru_721530.sMinX >= v8 - v7 )
+                      {
+                        v9 = v5->vPosition.y;
+                        if ( stru_721530.sMaxY <= v9 + v7 )
+                        {
+                          if ( stru_721530.sMinY >= v9 - v7 )
+                          {
+                            v10 = v6->uDecorationHeight;
+                            v11 = v5->vPosition.z;
+                            v22 = v10;
+                            if ( stru_721530.sMaxZ <= v11 + v10 )
+                            {
+                              if ( stru_721530.sMinZ >= v11 )
+                              {
+                                v12 = v8 - stru_721530.normal.x;
+                                v19 = v9 - stru_721530.normal.y;
+                                v13 = stru_721530.prolly_normal_d + v7;
+                                v21 = ((v8 - stru_721530.normal.x) * stru_721530.field_58.y
+                                     - (v9 - stru_721530.normal.y) * stru_721530.field_58.x) >> 16;
+                                if ( abs(v21) <= stru_721530.prolly_normal_d + v7 )
+                                {
+                                  v14 = (v12 * stru_721530.field_58.x + v19 * stru_721530.field_58.y) >> 16;
+                                  if ( v14 > 0 )
+                                  {
+                                    v15 = v5->vPosition.z;
+                                    v16 = stru_721530.normal.z
+                                        + ((unsigned __int64)(stru_721530.field_58.z * (signed __int64)v14) >> 16);
+                                    if ( v16 >= v15 )
+                                    {
+                                      if ( v16 <= v22 + v15 )
+                                      {
+                                        v17 = v14 - integer_sqrt(v13 * v13 - v21 * v21);
+                                        if ( v17 < 0 )
+                                          v17 = 0;
+                                        if ( v17 < stru_721530.field_7C )
+                                        {
+                                          stru_721530.field_7C = v17;
+                                          stru_721530.uFaceID = (signed __int16)*v20;
+                                        }
+                                      }
+                                    }
+                                  }
+                                }
+                              }
+                            }
+                          }
+                        }
+                      }
+                    }
+                  }
+                }
+              }
+              v3 = v20 + 1;
+              v18 = *v20 == 0;
+              ++v20;
+            }
+            while ( !v18 );
+          }
+        }
+      }
+    }
+  }
+}
--- a/Texture.cpp	Sun Jun 23 14:27:32 2013 +0600
+++ b/Texture.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -1753,4 +1753,4 @@
     ++j;
   }
   return 1;
-}
\ No newline at end of file
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/UI/UIBooks.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -0,0 +1,1770 @@
+#ifdef _MSC_VER
+#define _CRT_SECURE_NO_WARNINGS
+#endif
+
+#include <assert.h>
+
+#include "..\MM7.h"
+
+#include "..\Mouse.h"
+
+#include "..\MapInfo.h"
+#include "..\GUIWindow.h"
+#include "..\GUIFont.h"
+#include "..\Party.h"
+#include "..\AudioPlayer.h"
+#include "..\Outdoor.h"
+#include "..\LOD.h"
+#include "..\Allocator.h"
+#include "..\Viewport.h"
+#include "..\Math.h"
+#include "..\Awards.h"
+#include "..\Autonotes.h"
+#include "..\StorylineTextTable.h"
+#include "..\texts.h"
+
+#include "..\mm7_data.h"
+
+
+
+
+
+
+
+//----- (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)
+{
+  pRenderer->DrawTextureIndexed(471, 445, pIcons_LOD->GetTexture(uExitCancelTextureId));
+  switch (book)
+  {
+    case WINDOW_QuestBook:     BookUI_Questbook_Draw();  break;
+    case WINDOW_AutonotesBook: BookUI_Autonotes_Draw();  break;
+    case WINDOW_MapsBook:      BookUI_Map_Draw();        break;
+    case WINDOW_CalendarBook:  BookUI_Calendar_Draw();   break;
+    case WINDOW_JournalBook:   BookUI_Journal_Draw();    break;
+
+    case WINDOW_LloydsBeacon:  DrawLloydBeaconsScreen(); break;
+    case WINDOW_TownPortal:    BookUI_DrawTownPortalMap();   break;
+  }
+}
+
+
+
+//----- (00413D3C) --------------------------------------------------------
+static const char *GetDayPart()
+{
+  if (pParty->uCurrentHour <= 4)
+    return pGlobalTXT_LocalizationStrings[567]; // "Night"
+  else if (pParty->uCurrentHour == 5)
+    return pGlobalTXT_LocalizationStrings[55]; // "Dawn"
+  else if (pParty->uCurrentHour == 20)
+    return pGlobalTXT_LocalizationStrings[566]; // "Dusk"
+  else
+    return pGlobalTXT_LocalizationStrings[56]; // "Day"
+}
+
+
+
+//----- (00413D6F) --------------------------------------------------------
+void BookUI_Calendar_Draw()
+{
+  unsigned int v0; // esi@1
+  //char *v1; // eax@5
+  int v2; // ecx@5
+  char *v3; // eax@6
+  GUIWindow a1; // [sp+Ch] [bp-60h]@5
+  unsigned int v6; // [sp+60h] [bp-Ch]@1
+  //int v7; // [sp+64h] [bp-8h]@1
+  //int a5; // [sp+68h] [bp-4h]@1
+
+  
+  static unsigned int pDayMoonPhase[28] = // 4E1B18
+  {
+    0, 0, 0,
+    1, 1, 1, 1,
+    2, 2, 2,
+    3, 3, 3, 3,
+    4, 4, 4,
+    3, 3, 3, 3,
+    2, 2, 2,
+    1, 1, 1, 1
+  };
+
+
+  v0 = pParty->uCurrentHour;
+  pRenderer->DrawTextureIndexed(pViewport->uViewportTL_X, pViewport->uViewportTL_Y, pSpellBookPagesTextr_13);
+  if ( (signed int)v0 <= 12 )
+  {
+    if ( !v0 )
+      v0 = 12;
+  }
+  else
+  {
+    v0 -= 12;
+  }
+  a1.uFrameX = game_viewport_x;
+  a1.uFrameY = game_viewport_y;
+  a1.uFrameWidth = game_viewport_width;
+  a1.uFrameHeight = game_viewport_height;
+  a1.uFrameZ = game_viewport_z;
+  a1.uFrameW = game_viewport_w;
+  a1.DrawTitleText(pBook2Font, 0, 0x16u, ui_book_calendar_title_color, pGlobalTXT_LocalizationStrings[186], 3); // "Time in Erathia"
+
+  v2 = 0;
+  if ( pParty->uCurrentHour >= 12 )
+  {
+    if ( pParty->uCurrentHour >= 24 )
+		v2=0;
+	else
+		v2=1;
+  }
+
+  sprintf(pTmpBuf.data(), "%s\t100:\t110%d:%02d %s - %s",
+          pGlobalTXT_LocalizationStrings[526], // "Time"
+          v0,
+          pParty->uCurrentMinute,
+          aAMPMNames[v2],
+          GetDayPart());
+  a1.DrawText(pBookFont, 70, 55, ui_book_calendar_time_color, pTmpBuf.data(), 0, 0, 0);
+
+  sprintf(pTmpBuf.data(), "%s\t100:\t110%d - %s",
+          pGlobalTXT_LocalizationStrings[56], // "Day"
+          pParty->uDaysPlayed + 1,
+          aDayNames[pParty->uDaysPlayed % 7]);
+  a1.DrawText(pBookFont, 70, 2 * LOBYTE(pBookFont->uFontHeight) + 49, ui_book_calendar_day_color, pTmpBuf.data(), 0, 0, 0);
+
+  sprintf(pTmpBuf.data(), "%s\t100:\t110%d - %s",
+          pGlobalTXT_LocalizationStrings[146], // "Month"
+          pParty->uCurrentMonth + 1,
+          aMonthNames[pParty->uCurrentMonth]);
+  a1.DrawText(pBookFont, 70, 4 * LOBYTE(pBookFont->uFontHeight) + 43, ui_book_calendar_month_color, pTmpBuf.data(), 0, 0, 0);
+
+  sprintf(pTmpBuf.data(), "%s\t100:\t110%d", pGlobalTXT_LocalizationStrings[245], pParty->uCurrentYear); // "Year"
+  a1.DrawText(pBookFont, 70, 6 * LOBYTE(pBookFont->uFontHeight) + 37, ui_book_calendar_year_color, pTmpBuf.data(), 0, 0, 0);
+
+  sprintf(pTmpBuf.data(), "%s\t100:\t110%s", pGlobalTXT_LocalizationStrings[530], aMoonPhaseNames[pDayMoonPhase[pParty->uDaysPlayed]]); // "Moon"
+  a1.DrawText(pBookFont, 70, 8 * LOBYTE(pBookFont->uFontHeight) + 31, ui_book_calendar_moon_color, pTmpBuf.data(), 0, 0, 0);
+  
+  v6 = pMapStats->GetMapInfo(pCurrentMapName.data());
+  if ( v6 )
+    v3 = pMapStats->pInfos[v6].pName;
+  else
+    v3 = "Unknown";
+  sprintf(pTmpBuf.data(), "%s\t100:\t110%s", pGlobalTXT_LocalizationStrings[531], v3); // "Location"
+  a1.DrawText(pBookFont, 70, 10 * LOBYTE(pBookFont->uFontHeight) + 25, ui_book_calendar_location_color, pTmpBuf.data(), 0, 0, 0);
+}
+
+
+
+//----- (0041192C) --------------------------------------------------------
+void InitializeBookTextures()
+{
+  //signed int v0; // ebp@3
+  //Texture **v1; // ebx@3
+
+  pAudioPlayer->StopChannels(-1, -1);
+
+  ++pIcons_LOD->uTexturePacksCount;
+  if ( !pIcons_LOD->uNumPrevLoadedFiles )
+    pIcons_LOD->uNumPrevLoadedFiles = pIcons_LOD->uNumLoadedFiles;
+
+  pAudioPlayer->PlaySound(SOUND_OpenBook, 0, 0, -1, 0, 0, 0, 0);
+  pSpellBookPagesTextr_9 = pIcons_LOD->LoadTexturePtr("book", TEXTURE_16BIT_PALETTE);
+  pTexture_pagemask = pIcons_LOD->LoadTexturePtr("pagemask", TEXTURE_16BIT_PALETTE);
+  pTexture_506448   = pIcons_LOD->LoadTexturePtr("ib-m5-u", TEXTURE_16BIT_PALETTE);
+  ptr_506440        = pIcons_LOD->LoadTexturePtr("ib-m5-d", TEXTURE_16BIT_PALETTE);
+  pTexture_50643C   = pIcons_LOD->LoadTexturePtr("ib-m6-u",TEXTURE_16BIT_PALETTE);
+  //v0 = 1;
+
+  static const char *texNames[9] = // 004E24EC
+  {
+    "SBFB00", "SBAB00", "SBWB00", "SBEB00",
+    "SBSB00", "SBMB00", "SBBB00", "SBLB00", "SBDB00"
+  };
+
+  pTexture_506444 = pIcons_LOD->LoadTexturePtr("ib-m6-d",TEXTURE_16BIT_PALETTE);
+  for (uint i = 0; i < 9; ++i)
+  {
+    pSpellBookPagesTextr[i] = pIcons_LOD->LoadTexturePtr(texNames[i], TEXTURE_16BIT_PALETTE);
+
+    sprintf(pTmpBuf.data(), "tab%da", i+1);
+    pTextures_tabs[i][0] = pIcons_LOD->LoadTexturePtr(pTmpBuf.data(), TEXTURE_16BIT_PALETTE);
+    sprintf(pTmpBuf.data(), "tab%db", i+1);
+    pTextures_tabs[i][1] = pIcons_LOD->LoadTexturePtr(pTmpBuf.data(), TEXTURE_16BIT_PALETTE);
+  }
+}
+
+
+
+//----- (00411AAA) --------------------------------------------------------
+void InitializeBookFonts()
+{
+  pAudioPlayer->StopChannels(-1, -1);
+
+  ++pIcons_LOD->uTexturePacksCount;
+  if ( !pIcons_LOD->uNumPrevLoadedFiles )
+    pIcons_LOD->uNumPrevLoadedFiles = pIcons_LOD->uNumLoadedFiles;
+
+  pAudioPlayer->PlaySound(SOUND_OpenBook, 0, 0, -1, 0, 0, 0, 0);
+  pTexture_mapbordr = pIcons_LOD->LoadTexturePtr("mapbordr", TEXTURE_16BIT_PALETTE);
+  pBookFont = LoadFont("book.fnt", "FONTPAL", NULL);
+  pBook2Font = LoadFont("book2.fnt", "FONTPAL", NULL);
+  pAutonoteFont = LoadFont("autonote.fnt", "FONTPAL", NULL);
+  pSpellFont = LoadFont("spell.fnt", "FONTPAL", NULL);
+}
+
+
+
+//----- (00411300) --------------------------------------------------------
+void LoadSpellbook(unsigned int spell_school)
+{
+  //unsigned int v1; // esi@1
+  Player *pPlayer; // ecx@1
+  char v3; // al@1
+  //int v4; // edi@5
+  //Texture *result; // eax@6
+  //unsigned char *v6; // edi@7
+  //unsigned int v7; // eax@7
+  //unsigned __int8 v8; // sf@8
+  //unsigned __int8 v9; // of@8
+  char pContainer[20]; // [sp+Ch] [bp-1Ch]@7
+  //Texture *v11; // [sp+20h] [bp-8h]@5
+  //int v12; // [sp+24h] [bp-4h]@5
+
+  byte_506550 = 0;
+  //v1 = uID;
+  pPlayer = pPlayers[uActiveCharacter];
+  v3 = pPlayer->uQuickSpell;
+  if ( v3 && (unsigned __int8)v3 / 11 == spell_school )
+    quick_spell_at_page = (unsigned __int8)v3 - 11 * spell_school;
+  else
+    quick_spell_at_page = 0;
+
+  for (uint i = 1; i < 12; ++i)
+  {
+    if (pPlayer->spellbook.pChapters[spell_school].bIsSpellAvailable[i - 1])
+    {
+      sprintf(pContainer, "SB%sS%02d", spellbook_texture_filename_suffices[spell_school], pSpellbookSpellIndices[spell_school][i]);
+      dword_506408[i] = pIcons_LOD->LoadTexturePtr(pContainer, TEXTURE_16BIT_PALETTE);
+
+      sprintf(pContainer, "SB%sC%02d", spellbook_texture_filename_suffices[spell_school], pSpellbookSpellIndices[spell_school][i]);
+      dword_5063D8[i] = pIcons_LOD->LoadTexturePtr(pContainer, TEXTURE_16BIT_PALETTE);
+    }
+  }
+}
+
+//----- (0041140B) --------------------------------------------------------
+void sub_41140B()
+{
+  signed int v0; // esi@1
+  GUIButton *v1; // eax@3
+  GUIButton *v2; // esi@4
+
+  v0 = 0;
+  do
+  {
+	dword_5063D8[11+v0]->Release();
+	dword_506408[11+v0]->Release();
+    --v0;
+  }
+  while ( v0 >= -11 );
+  pIcons_LOD->SyncLoadedFilesCount();
+  v1 = pGUIWindow_CurrentMenu->pControlsHead;
+  if ( v1 )
+  {
+    do
+    {
+      v2 = v1->pNext;
+      pAllocator->FreeChunk(v1);
+      v1 = v2;
+    }
+    while ( v2 );
+  }
+  pGUIWindow_CurrentMenu->pControlsHead = 0;
+  pGUIWindow_CurrentMenu->pControlsTail = 0;
+  pGUIWindow_CurrentMenu->uNumControls = 0;
+}
+
+//----- (00411473) --------------------------------------------------------
+void sub_411473()
+{
+  pTexture_pagemask->Release();
+  pTexture_506448->Release();
+  pTexture_50643C->Release();
+  for (uint i = 0; i < 9; ++i)
+      {
+      pSpellBookPagesTextr[i]->Release();
+      pTextures_tabs[i][0]->Release();
+      pTextures_tabs[i][1]->Release();
+      }
+  pAudioPlayer->PlaySound(SOUND_CloseBook, 0, 0, -1, 0, 0, 0, 0);
+  pIcons_LOD->_4114F2();
+}
+
+
+//----- (00411597) --------------------------------------------------------
+void OnCloseSpellBook()
+{
+  pAllocator->FreeChunk(pSpellFont);
+  pSpellFont = nullptr;
+  pAllocator->FreeChunk(pBookFont);
+  pBookFont = nullptr;
+  pAllocator->FreeChunk(pBook2Font);
+  pBook2Font = nullptr;
+  pAllocator->FreeChunk(pAutonoteFont);
+  pAutonoteFont = nullptr;
+  pTexture_mapbordr->Release();
+  pAudioPlayer->PlaySound(SOUND_CloseBook, 0, 0, -1, 0, 0, 0, 0);
+  pIcons_LOD->_4114F2();
+  dword_506364 = 0;
+}
+
+
+
+
+
+
+
+//----- (00412E85) --------------------------------------------------------
+void BookUI_Journal_Draw()
+{
+  unsigned int v0; // eax@3
+  unsigned int v1; // eax@7
+  int v2; // eax@10
+  const char *v3; // eax@10
+  signed int v4; // ecx@12
+  int v5; // ecx@14
+  int v6; // eax@21
+  int v7; // esi@21
+  char *v8; // eax@21
+  char* v9; // eax@22
+  unsigned int v11; // [sp-8h] [bp-64h]@3
+  unsigned int v12; // [sp-8h] [bp-64h]@7
+  Texture *v13; // [sp-4h] [bp-60h]@3
+  Texture *v14; // [sp-4h] [bp-60h]@7
+  GUIWindow a1; // [sp+8h] [bp-54h]@10
+
+  pRenderer->DrawTextureIndexed(pViewport->uViewportTL_X, pViewport->uViewportTL_Y, pSpellBookPagesTextr_11);
+  if ( BtnUp_flag || !dword_506528 )
+  {
+    v13 = pTex_tab_an_6a__zoom_off;
+    v11 = pViewport->uViewportTL_Y + 2;
+    v0 = pViewport->uViewportTL_X + 407;
+  }
+  else
+  {
+    v13 = pTex_tab_an_6b__zoom_on;
+    v11 = pViewport->uViewportTL_Y + 1;
+    v0 = pViewport->uViewportTL_X + 398;
+  }
+  pRenderer->DrawTextureTransparent(v0, v11, v13);
+
+  if ( BtnDown_flag || dword_506528 + num_achieved_awards >= num_achieved_awards_2 )
+  {
+    v14 = pTex_tab_an_7a__zoot_off;
+    v12 = pViewport->uViewportTL_Y + 38;
+    v1 = pViewport->uViewportTL_X + 407;
+  }
+  else
+  {
+    v14 = pTex_tab_an_7b__zoot_on;
+    v12 = pViewport->uViewportTL_Y + 38;
+    v1 = pViewport->uViewportTL_X + 398;
+  }
+  pRenderer->DrawTextureTransparent(v1, v12, v14);
+
+  if ( !byte_5C6D50[dword_506528] )
+  {
+    v2 = achieved_awards[dword_506528];
+    a1.uFrameWidth = game_viewport_width;
+    a1.uFrameX = game_viewport_x;
+    a1.uFrameY = game_viewport_y;
+    a1.uFrameHeight = game_viewport_height;
+    v3 = (const char *)pStorylineText->StoreLine[v2].pPageTitle;//field_4[];
+    a1.uFrameZ = game_viewport_z;
+    a1.uFrameW = game_viewport_w;
+    if ( v3 )
+      a1.DrawTitleText(pBook2Font, 0, 22, ui_book_journal_title_color, v3, 3);
+  }
+
+  a1.uFrameX = 48;
+  a1.uFrameY = 70;
+  a1.uFrameWidth = 360;
+  a1.uFrameHeight = 264;
+  v4 = LOBYTE(pAutonoteFont->uFontHeight) - 3;
+  a1.uFrameZ = 407;
+  a1.uFrameHeight = v4 * 264 / v4;
+  a1.uFrameW = a1.uFrameHeight + 69;
+  if ( BtnDown_flag && dword_506528 + num_achieved_awards < num_achieved_awards_2 )
+  {
+    pAudioPlayer->PlaySound(SOUND_OpenBook, 0, 0, -1, 0, 0, 0, 0);
+    v5 = dword_50651C++;
+    dword_506528 += num_achieved_awards;
+    byte_506130[v5] = num_achieved_awards;
+  }
+  if ( BtnUp_flag && dword_50651C )
+  {
+    pAudioPlayer->PlaySound(SOUND_OpenBook, 0, 0, -1, 0, 0, 0, 0);
+    --dword_50651C;
+    dword_506528 -= (unsigned __int8)byte_506130[dword_50651C];
+  }
+  if ( !num_achieved_awards || dword_506528 < 1 )
+  {
+    dword_506528 = 0;
+    dword_50651C = 0;
+  }
+  BtnDown_flag = 0;
+  v6 = achieved_awards[dword_506528];
+  BtnUp_flag = 0;
+  num_achieved_awards = 0;
+  //v7 = *pStorylineText->StoreLine[v6].pText;//*(&pStorylineText->field_0 + 3 * v6);
+  v7 = (int)pStorylineText->StoreLine[v6].pText;//*(&pStorylineText->field_0 + 3 * v6);
+  v8 = BuilDialogueString(
+         pStorylineText->StoreLine[v6].pText,
+         uActiveCharacter - 1,
+         0,
+         0,
+         0,
+         (__int64 *)&pParty->field_3C._s_times[ v6 + 21]);
+  if ( v7 )
+  {
+    v9 = pAutonoteFont->_44C6C2(v8, &a1, 1u, (unsigned __int8)byte_5C6D50[dword_506528]);
+    a1.DrawText(pAutonoteFont, 1, 0, ui_book_journal_text_color, (const char *)v9, 0, a1.uFrameY + a1.uFrameHeight, ui_book_journal_text_shadow);
+    ++num_achieved_awards;
+  }
+}
+
+
+//----- (00413126) --------------------------------------------------------
+void BookUI_Questbook_Draw()
+{
+  unsigned int v0; // eax@3
+  unsigned int v1; // eax@7
+  int v2; // ecx@11
+  int v3; // ebx@16
+  int v4; // eax@19
+  const char *v5; // edi@19
+  int v6; // eax@19
+  unsigned int v7; // edi@19
+  unsigned int v8; // [sp-8h] [bp-68h]@3
+  unsigned int v9; // [sp-8h] [bp-68h]@7
+  Texture *v10; // [sp-4h] [bp-64h]@3
+  Texture *v11; // [sp-4h] [bp-64h]@7
+  GUIWindow a1; // [sp+Ch] [bp-54h]@9
+
+  pRenderer->DrawTextureIndexed(pViewport->uViewportTL_X, pViewport->uViewportTL_Y, pTexture_CurrentBook);
+  if ( BtnUp_flag || !dword_506528 )
+  {
+    v10 = pTex_tab_an_6a__zoom_off;
+    v8 = pViewport->uViewportTL_Y + 2;
+    v0 = pViewport->uViewportTL_X + 407;
+  }
+  else
+  {
+    v10 = pTex_tab_an_6b__zoom_on;
+    v8 = pViewport->uViewportTL_Y + 1;
+    v0 = pViewport->uViewportTL_X + 398;
+  }
+  pRenderer->DrawTextureTransparent(v0, v8, v10);
+  if ( BtnDown_flag || dword_506528 + num_achieved_awards >= num_achieved_awards_2 )
+  {
+    v11 = pTex_tab_an_7a__zoot_off;
+    v9 = pViewport->uViewportTL_Y + 38;
+    v1 = pViewport->uViewportTL_X + 407;
+  }
+  else
+  {
+    v11 = pTex_tab_an_7b__zoot_on;
+    v9 = pViewport->uViewportTL_Y + 38;
+    v1 = pViewport->uViewportTL_X + 398;
+  }
+  pRenderer->DrawTextureTransparent(v1, v9, v11);
+  a1.uFrameWidth = game_viewport_width;
+  a1.uFrameHeight = game_viewport_height;
+  a1.uFrameX = game_viewport_x;
+  a1.uFrameY = game_viewport_y;
+  a1.uFrameZ = game_viewport_z;
+  a1.uFrameW = game_viewport_w;
+  a1.DrawTitleText(pBook2Font, 0, 22, ui_book_quests_title_color, pGlobalTXT_LocalizationStrings[174], 3); //"Current Quests"
+
+  a1.uFrameX = 48;
+  a1.uFrameY = 70;
+  a1.uFrameWidth = 360;
+  a1.uFrameHeight = 264;
+  a1.uFrameZ = 407;
+  a1.uFrameW = 333;
+  if ( BtnDown_flag && dword_506528 + num_achieved_awards < num_achieved_awards_2 )
+  {
+    pAudioPlayer->PlaySound(SOUND_OpenBook, 0, 0, -1, 0, 0, 0, 0);
+    v2 = dword_50651C++;
+    dword_506528 += num_achieved_awards;
+    byte_506130[v2] = num_achieved_awards;
+  }
+  if ( BtnUp_flag && dword_50651C )
+  {
+    pAudioPlayer->PlaySound(SOUND_OpenBook, 0, 0, -1, 0, 0, 0, 0);
+    --dword_50651C;
+    dword_506528 -= (unsigned __int8)byte_506130[dword_50651C];
+  }
+  if ( !num_achieved_awards || (v3 = dword_506528, dword_506528 < 1) )
+  {
+    v3 = 0;
+    dword_50651C = 0;
+    dword_506528 = 0;
+  }
+  BtnDown_flag = 0;
+  BtnUp_flag = 0;
+  num_achieved_awards = 0;
+  while ( v3 < num_achieved_awards_2 )
+  {
+    v4 = achieved_awards[v3];
+    ++num_achieved_awards;
+    v5 = pQuestTable[v4-1];//(&dword_722F10)[4 * v4];
+    a1.DrawText(pAutonoteFont, 1, 0, ui_book_quests_text_color, pQuestTable[v4-1], 0, 0, 0);//(&dword_722F10)[4 * v4], 0, 0, 0);
+    v6 = pAutonoteFont->CalcTextHeight(v5, &a1, 1, 0);
+    v7 = a1.uFrameY + v6;
+    if ( (signed int)(a1.uFrameY + v6) > (signed int)a1.uFrameHeight )
+      break;
+    pRenderer->DrawTextureTransparent(100, v7 + 12, pSpellBookPagesTextr_10);
+    ++v3;
+    a1.uFrameY = v7 + 24;
+  }
+}
+
+
+//----- (0041338E) --------------------------------------------------------
+void BookUI_Autonotes_Draw()
+{
+  unsigned int v0; // eax@3
+  unsigned int v1; // eax@7
+  signed int v2; // ebp@11
+  unsigned int v3; // eax@18
+  unsigned int v4; // eax@24
+  unsigned int v5; // eax@30
+  unsigned int v6; // eax@36
+  unsigned int v7; // eax@42
+  signed int v8; // ebp@47
+  int v9; // eax@52
+  int v10; // eax@56
+  int v11; // edx@57
+  int v12; // ebp@64
+  int v13; // eax@65
+  const char *v14; // edi@65
+  int v15; // eax@65
+  unsigned int v16; // edi@65
+  unsigned int v17; // [sp-8h] [bp-70h]@3
+  unsigned int v18; // [sp-8h] [bp-70h]@7
+  unsigned int v19; // [sp-8h] [bp-70h]@18
+  unsigned int v20; // [sp-8h] [bp-70h]@24
+  unsigned int v21; // [sp-8h] [bp-70h]@30
+  unsigned int v22; // [sp-8h] [bp-70h]@36
+  unsigned int v23; // [sp-8h] [bp-70h]@42
+  Texture *v24; // [sp-4h] [bp-6Ch]@3
+  Texture *v25; // [sp-4h] [bp-6Ch]@7
+  Texture *v26; // [sp-4h] [bp-6Ch]@18
+  Texture *v27; // [sp-4h] [bp-6Ch]@24
+  Texture *v28; // [sp-4h] [bp-6Ch]@30
+  Texture *v29; // [sp-4h] [bp-6Ch]@36
+  Texture *v30; // [sp-4h] [bp-6Ch]@42
+  signed __int16 v31; // [sp+10h] [bp-58h]@1
+  char *v32; // [sp+10h] [bp-58h]@49
+  GUIWindow a1; // [sp+14h] [bp-54h]@46
+
+  v31 = 0;
+  pRenderer->DrawTextureIndexed(pViewport->uViewportTL_X, pViewport->uViewportTL_Y, pTexture_AutonotesBook);
+  if ( BtnUp_flag || !dword_506528 )
+  {
+    v24 = pTex_tab_an_6a__zoom_off;
+    v17 = pViewport->uViewportTL_Y + 2;
+    v0 = pViewport->uViewportTL_X + 407;
+  }
+  else
+  {
+    v24 = pTex_tab_an_6b__zoom_on;
+    v17 = pViewport->uViewportTL_Y + 1;
+    v0 = pViewport->uViewportTL_X + 398;
+  }
+  pRenderer->DrawTextureTransparent(v0, v17, v24);
+  if ( BtnDown_flag || dword_506528 + num_achieved_awards >= num_achieved_awards_2 )
+  {
+    v25 = pTex_tab_an_7a__zoot_off;
+    v18 = pViewport->uViewportTL_Y + 38;
+    v1 = pViewport->uViewportTL_X + 407;
+  }
+  else
+  {
+    v25 = pTex_tab_an_7b__zoot_on;
+    v18 = pViewport->uViewportTL_Y + 38;
+    v1 = pViewport->uViewportTL_X + 398;
+  }
+  pRenderer->DrawTextureTransparent(v1, v18, v25);
+  if ( !Book_PageBtn3_flag )//Potions_page_flag
+  {
+    if (_506568_autonote_type != AUTONOTE_POTION_RECEPIE)
+    {
+      pRenderer->DrawTextureTransparent(
+        pViewport->uViewportTL_X + 408,
+        pViewport->uViewportTL_Y + 113,
+        pTexture_506390);
+      v2 = 1;
+      goto LABEL_16;
+    }
+    goto LABEL_14;
+  }
+  if (_506568_autonote_type == AUTONOTE_POTION_RECEPIE)
+  {
+LABEL_14:
+    v2 = 1;
+    goto LABEL_15;
+  }
+  v2 = 1;
+  v31 = 1;
+  pAudioPlayer->PlaySound(SOUND_Button2, 0, 0, -1, 0, 0, 0, 0);
+LABEL_15:
+  _506568_autonote_type = AUTONOTE_POTION_RECEPIE;
+  pRenderer->DrawTextureTransparent(pViewport->uViewportTL_X + 398, pViewport->uViewportTL_Y + 113, pTexture_506394);
+LABEL_16:
+  if ( Book_PageBtn4_flag )//Fontains_page_flag
+  {
+    if ( _506568_autonote_type != v2 )
+    {
+      v31 = v2;
+      pAudioPlayer->PlaySound(SOUND_Button2, 0, 0, -1, 0, 0, 0, 0);
+    }
+  }
+  else
+  {
+    if ( _506568_autonote_type != v2 )
+    {
+      v26 = pTexture_506388;
+      v19 = pViewport->uViewportTL_Y + 150;
+      v3 = pViewport->uViewportTL_X + 408;
+      goto LABEL_22;
+    }
+  }
+  v26 = pTexture_50638C;
+  _506568_autonote_type = v2;
+  v19 = pViewport->uViewportTL_Y + 150;
+  v3 = pViewport->uViewportTL_X + 399;
+LABEL_22:
+  pRenderer->DrawTextureTransparent(v3, v19, v26);
+  if ( Book_PageBtn5_flag )//Autonotes_Obelisks_page_flag
+  {
+    if ( _506568_autonote_type != AUTONOTE_OBELISK)
+    {
+      v31 = v2;
+      pAudioPlayer->PlaySound(SOUND_Button2, 0, 0, -1, 0, 0, 0, 0);
+    }
+  }
+  else
+  {
+    if ( _506568_autonote_type != AUTONOTE_OBELISK)
+    {
+      v27 = pTexture_506380;
+      v20 = pViewport->uViewportTL_Y + 188;
+      v4 = pViewport->uViewportTL_X + 408;
+      goto LABEL_28;
+    }
+  }
+  v27 = pTexture_506384;
+  _506568_autonote_type = AUTONOTE_OBELISK;
+  v20 = pViewport->uViewportTL_Y + 188;
+  v4 = pViewport->uViewportTL_X + 397;
+LABEL_28:
+  pRenderer->DrawTextureTransparent(v4, v20, v27);
+  if ( Book_PageBtn6_flag )//Autonotes_Seer_page_flag
+  {
+    if ( _506568_autonote_type != AUTONOTE_SEER)
+    {
+      v31 = v2;
+      pAudioPlayer->PlaySound(SOUND_Button2, 0, 0, -1, 0, 0, 0, 0);
+    }
+  }
+  else
+  {
+    if ( _506568_autonote_type != AUTONOTE_SEER)
+    {
+      v28 = pTexture_506378;
+      v21 = pViewport->uViewportTL_Y + 226;
+      v5 = pViewport->uViewportTL_X + 408;
+      goto LABEL_34;
+    }
+  }
+  v28 = pTexture_50637C;
+  _506568_autonote_type = AUTONOTE_SEER;
+  v21 = pViewport->uViewportTL_Y + 226;
+  v5 = pViewport->uViewportTL_X + 397;
+LABEL_34:
+  pRenderer->DrawTextureTransparent(v5, v21, v28);
+  if ( Autonotes_Misc_page_flag )
+  {
+    if ( _506568_autonote_type != AUTONOTE_MISC)
+    {
+      v31 = v2;
+      pAudioPlayer->PlaySound(SOUND_Button2, 0, 0, -1, 0, 0, 0, 0);
+    }
+  }
+  else
+  {
+    if ( _506568_autonote_type != AUTONOTE_MISC)
+    {
+      v29 = pTexture_506370;
+      v22 = pViewport->uViewportTL_Y + 263;
+      v6 = pViewport->uViewportTL_X + 408;
+      goto LABEL_40;
+    }
+  }
+  v29 = pTexture_506374;
+  _506568_autonote_type = AUTONOTE_MISC;
+  v22 = pViewport->uViewportTL_Y + 264;
+  v6 = pViewport->uViewportTL_X + 397;
+LABEL_40:
+  pRenderer->DrawTextureTransparent(v6, v22, v29);
+  if ( Autonotes_Instructors_page_flag )
+  {
+    if ( _506568_autonote_type != AUTONOTE_TEACHER)
+    {
+      v31 = v2;
+      pAudioPlayer->PlaySound(SOUND_Button2, 0, 0, -1, 0, 0, 0, 0);
+    }
+  }
+  else
+  {
+    if ( _506568_autonote_type != AUTONOTE_TEACHER)
+    {
+      v30 = pTexture_506368;
+      v23 = pViewport->uViewportTL_Y + 302;
+      v7 = pViewport->uViewportTL_X + 408;
+      goto LABEL_46;
+    }
+  }
+  v30 = pTexture_50636C;
+  _506568_autonote_type = AUTONOTE_TEACHER;
+  v23 = pViewport->uViewportTL_Y + 302;
+  v7 = pViewport->uViewportTL_X + 397;
+LABEL_46:
+  pRenderer->DrawTextureTransparent(v7, v23, v30);
+  a1.uFrameWidth = game_viewport_width;
+  a1.uFrameHeight = game_viewport_height;
+  a1.uFrameX = game_viewport_x;
+  a1.uFrameY = game_viewport_y;
+  a1.uFrameZ = game_viewport_z;
+  a1.uFrameW = game_viewport_w;
+  a1.DrawTitleText(pBook2Font, 0, 22, ui_book_autonotes_title_color, pGlobalTXT_LocalizationStrings[154], 3); // "Auto notes"
+
+  a1.uFrameX = 48;
+  a1.uFrameY = 70;
+  a1.uFrameWidth = 360;
+  a1.uFrameHeight = 264;
+  a1.uFrameZ = 407;
+  a1.uFrameW = 333;
+  if ( v31 )
+  {
+    num_achieved_awards_2 = 0;
+    dword_506528 = 0;
+    dword_50651C = 0;
+    num_achieved_awards = 0;
+    v8 = 0;
+    do
+    {
+      //if ( dword_72371C[2 * v8] == dword_506568 )
+	  if ( pAutonoteTxt[v8-1].eType == _506568_autonote_type )
+      {
+        //v32 = (&dword_723718_autonote_related)[8 * (signed __int16)v8];
+		v32 = (char *)pAutonoteTxt[v8-1].pText;
+        if ( (short)v8 )
+        {
+          if ( (unsigned __int16)_449B57_test_bit(pParty->_autonote_bits, v8) && v32 )
+          {
+            v9 = num_achieved_awards++;
+            achieved_awards[v9] = (AwardType)v8;
+          }
+        }
+      }
+      ++v8;
+    }
+    while ( v8 < 196 );
+    num_achieved_awards_2 = num_achieved_awards;
+  }
+  else
+  {
+    if ( BtnDown_flag )
+    {
+      v10 = num_achieved_awards + dword_506528;
+      if ( num_achieved_awards + dword_506528 < num_achieved_awards_2 )
+      {
+        v11 = dword_50651C++;
+        byte_506130[v11] = num_achieved_awards;
+        dword_506528 = v10;
+        pAudioPlayer->PlaySound(SOUND_OpenBook, 0, 0, -1, 0, 0, 0, 0);
+      }
+    }
+    if ( BtnUp_flag && dword_50651C )
+    {
+      --dword_50651C;
+      dword_506528 -= (unsigned __int8)byte_506130[dword_50651C];
+      pAudioPlayer->PlaySound(SOUND_OpenBook, 0, 0, -1, 0, 0, 0, 0);
+    }
+    if ( !num_achieved_awards || dword_506528 < 1 )
+    {
+      dword_506528 = 0;
+      dword_50651C = 0;
+    }
+  }
+  v12 = dword_506528;
+  Autonotes_Instructors_page_flag = 0;
+  BtnDown_flag = 0;
+  BtnUp_flag = 0;
+  num_achieved_awards = 0;
+  Autonotes_Misc_page_flag = 0;
+  Book_PageBtn6_flag = 0;//Autonotes_Seer_page_flag
+  Book_PageBtn5_flag = 0;//Autonotes_Obelisks_page_flag
+  Book_PageBtn4_flag = 0;//Fontains_page_flag
+  Book_PageBtn3_flag = 0;//Potions_page_flag
+  while ( v12 < num_achieved_awards_2 )
+  {
+    v13 = achieved_awards[v12];
+    ++num_achieved_awards;
+    //v14 = (&dword_723718_autonote_related)[8 * v13];
+	v14 = pAutonoteTxt[v13-1].pText;
+    //a1.DrawText(pAutonoteFont, 1, 0, 0, (&dword_723718_autonote_related)[8 * v13], 0, 0, 0);
+	a1.DrawText(pAutonoteFont, 1, 0, ui_book_autonotes_text_color, pAutonoteTxt[v13-1].pText, 0, 0, 0);
+    v15 = pAutonoteFont->CalcTextHeight(v14, &a1, 1, 0);
+    v16 = a1.uFrameY + v15;
+    if ( (signed int)(a1.uFrameY + v15) > (signed int)a1.uFrameHeight )
+      break;
+    pRenderer->DrawTextureTransparent(0x64u, v16 + 12, pSpellBookPagesTextr_10);
+    ++v12;
+    a1.uFrameY = v16 + 24;
+  }
+}
+
+
+//----- (00413980) --------------------------------------------------------
+void BookUI_Map_Draw()
+{ 
+  int v6; // eax@31
+  unsigned int map_id; // eax@35
+  Texture *buttnTxtr; // [sp-4h] [bp-DCh]@3
+  char party_coord[120]; // [sp+Ch] [bp-CCh]@37
+  GUIWindow map_window; // [sp+84h] [bp-54h]@35
+  unsigned int textrX, textrY;
+
+  pRenderer->DrawTextureIndexed(pViewport->uViewportTL_X, pViewport->uViewportTL_Y, pSpellBookPagesTextr_12);
+  if ( BtnUp_flag || viewparams->field_2C / 128 >= 12 )
+  {
+    buttnTxtr = pTex_tab_an_6a__zoom_off;
+    textrY = pViewport->uViewportTL_Y + 2;
+    textrX = pViewport->uViewportTL_X + 408;
+  }
+  else
+  {
+    buttnTxtr = pTex_tab_an_6b__zoom_on;
+    textrY = pViewport->uViewportTL_Y + 1;
+    textrX = pViewport->uViewportTL_X + 398;
+  }
+  pRenderer->DrawTextureTransparent(textrX, textrY, buttnTxtr);
+  if ( BtnDown_flag || viewparams->field_2C / 128 <= 3 )
+  {
+    buttnTxtr = pTex_tab_an_7a__zoot_off;
+    textrY = pViewport->uViewportTL_Y + 38;
+    textrX = pViewport->uViewportTL_X + 408;
+  }
+  else
+  {
+    buttnTxtr = pTex_tab_an_7b__zoot_on;
+    textrY = pViewport->uViewportTL_Y + 38;
+    textrX = pViewport->uViewportTL_X + 398;
+  }
+  pRenderer->DrawTextureTransparent(textrX, textrY, buttnTxtr);
+  if ( Book_PageBtn3_flag )
+  {
+    buttnTxtr = pTexture_506390;
+    textrY = pViewport->uViewportTL_Y + 113;
+    textrX = pViewport->uViewportTL_X + 408;
+  }
+  else
+  {
+    buttnTxtr = pTexture_506394;
+    textrY = pViewport->uViewportTL_Y + 113;
+    textrX = pViewport->uViewportTL_X + 398;
+  }
+  pRenderer->DrawTextureTransparent(textrX, textrY, buttnTxtr);
+  if ( Book_PageBtn4_flag )
+  {
+    buttnTxtr = pTexture_506388;
+    textrY = pViewport->uViewportTL_X + 150;
+    textrX = pViewport->uViewportTL_Y + 408;
+  }
+  else
+  {
+    buttnTxtr = pTexture_50638C;
+    textrY = pViewport->uViewportTL_X + 150;
+    textrX = pViewport->uViewportTL_Y + 399;
+  }
+  pRenderer->DrawTextureTransparent(textrX, textrY, buttnTxtr);
+  if ( Book_PageBtn5_flag )
+  {
+    buttnTxtr = pTexture_506380;
+    textrY = pViewport->uViewportTL_Y + 188;
+    textrX = pViewport->uViewportTL_X + 408;
+  }
+  else
+  {
+    buttnTxtr = pTexture_506384;
+    textrY = pViewport->uViewportTL_Y + 188;
+    textrX = pViewport->uViewportTL_X + 397;
+  }
+  pRenderer->DrawTextureTransparent(textrX, textrY, buttnTxtr);
+  if ( Book_PageBtn6_flag )
+  {
+    buttnTxtr = pTexture_506378;
+    textrY = pViewport->uViewportTL_Y + 226;
+    textrX = pViewport->uViewportTL_X + 408;
+  }
+  else
+  {
+    buttnTxtr = pTexture_50637C;
+    textrY = pViewport->uViewportTL_Y + 226;
+    textrX = pViewport->uViewportTL_X + 397;
+  }
+  pRenderer->DrawTextureTransparent(textrX, textrY, buttnTxtr);
+  if ( BtnDown_flag )
+    viewparams->CenterOnParty2();
+  if ( BtnUp_flag )
+    viewparams->CenterOnParty();
+  if ( Book_PageBtn3_flag )
+    viewparams->_443219();
+  if ( Book_PageBtn4_flag )
+    viewparams->_443231();
+  if ( Book_PageBtn5_flag )
+    viewparams->_44323D();
+  if ( Book_PageBtn6_flag )
+    viewparams->_443225();
+
+  if ( BtnUp_flag | BtnDown_flag | Book_PageBtn3_flag | Book_PageBtn4_flag | Book_PageBtn5_flag | Book_PageBtn6_flag )
+    pAudioPlayer->PlaySound(SOUND_Button2, 0, 0, -1, 0, 0, 0, 0);
+  BtnUp_flag = 0;
+  BtnDown_flag = 0;
+  Book_PageBtn6_flag = 0;
+  Book_PageBtn5_flag = 0;
+  Book_PageBtn4_flag = 0;
+  Book_PageBtn3_flag = 0;
+  DrawBook_Map_sub(97, 49, 361, 313, 0);
+  pRenderer->DrawTextureTransparent(75, 22, pTexture_mapbordr);
+  map_window.uFrameWidth = game_viewport_width;
+  map_window.uFrameHeight = game_viewport_height;
+  map_window.uFrameX = game_viewport_x;
+  map_window.uFrameY = game_viewport_y;
+  map_window.uFrameZ = game_viewport_z;
+  map_window.uFrameW = game_viewport_w;
+  map_id = pMapStats->GetMapInfo(pCurrentMapName.data());
+  if ( map_id )
+    map_window.DrawTitleText(pBook2Font, -14, 12, ui_book_map_title_color, pMapStats->pInfos[map_id].pName, 3);
+
+  map_window.uFrameX = 0;
+  sprintf(party_coord, pGlobalTXT_LocalizationStrings[659], pParty->vPosition.x, pParty->vPosition.y); //"x: %d  y: %d"
+  map_window.DrawTitleText(pFontComic, 0, 320, ui_book_map_coordinates_color, party_coord, 0);
+}
+
+//----- (00442955) --------------------------------------------------------
+void DrawBook_Map_sub( unsigned int tl_x, unsigned int tl_y, unsigned int br_x, int br_y, int _48074 )
+    {
+    int v5; // ebx@1
+    int v6; // edi@1
+    BLVMapOutlines *v7; // eax@8
+    unsigned __int8 v8; // zf@8
+    unsigned __int8 v9; // sf@8
+    int v10; // esi@10
+    unsigned int v11; // edx@11
+    __int16 v12; // cx@12
+    signed int v13; // eax@15
+    int v14; // eax@16
+    Vec3_short_ *v15; // ecx@16
+    int v16; // edx@16
+    int v17; // ecx@16
+    Vec3_short_ *v18; // eax@16
+    int v19; // ecx@16
+    int v20; // eax@16
+    signed int v21; // esi@18
+    int v22; // ecx@21
+    BLVMapOutline *v23; // ecx@21
+    Vec3_short_ *v24; // edx@21
+    Vec3_short_ *v25; // eax@21
+    int v26; // ecx@21
+    unsigned __int16 *v27; // edi@21
+    int v28; // edx@21
+    int v29; // eax@21
+    double v30; // st7@23
+    signed __int64 v31; // qax@23
+    unsigned short *v32; // edx@23
+    int textr_width; // esi@23
+    signed int v34; // eax@23
+    signed int v35; // ecx@23
+    int v36; // esi@27
+    int v37; // ecx@27
+    int v38; // edx@31
+    unsigned int v39; // eax@33
+    short *v40; // esi@33
+    short *v41; // edi@33
+    unsigned __int8 v42; // cf@33
+    unsigned int v43; // ecx@33
+    short *v44; // edi@33
+    short *v45; // esi@33
+    int v46; // ecx@33
+    signed int v47; // esi@38
+    signed int v48; // ecx@38
+    int v49; // eax@38
+    signed int v50; // edx@55
+    unsigned int v51; // ecx@55
+    int result; // eax@72
+    int v53; // eax@75
+    int v54; // esi@75
+    int v55; // eax@75
+    __int16 v56; // si@85
+    double v57; // st7@85
+    int v58; // ebx@85
+    signed __int64 v59; // qax@85
+    signed int v60; // edi@85
+    signed __int64 v61; // qax@85
+    signed int v62; // ebx@85
+    signed int v63; // esi@85
+    int v64; // eax@87
+    unsigned int v65; // ebx@95
+    unsigned short *v66; // edx@95
+    unsigned __int16 *v67; // esi@96
+    int v68; // edi@98
+    unsigned __int16 v69; // cx@99
+    unsigned int v70; // [sp-10h] [bp-48074h]@80
+    unsigned int v71; // [sp-Ch] [bp-48070h]@80
+    unsigned int v72; // [sp-8h] [bp-4806Ch]@80
+    signed int v73; // [sp-4h] [bp-48068h]@59
+    unsigned __int16 v74; // [sp-4h] [bp-48068h]@79
+    unsigned short map_texture_16[147456]; // [sp+Ch] [bp-48058h]@23
+    int v76; // [sp+4800Ch] [bp-58h]@23
+    unsigned __int16 *v77; // [sp+48010h] [bp-54h]@27
+    unsigned __int16 *pPalette_16; // [sp+48014h] [bp-50h]@23
+    unsigned int surfPitch; // [sp+48018h] [bp-4Ch]@1
+
+    int v81; // [sp+48020h] [bp-44h]@23
+    unsigned __int16* render16_data;
+    unsigned char* texture8_data;
+    unsigned char* curr_line;
+    int scale_increment;
+    int scaled_posX;
+    int scaled_posY;
+    int stepX_r;
+    int stepY_r;
+
+
+    unsigned int teal; // [sp+48028h] [bp-3Ch]@8
+    int v84; // [sp+4802Ch] [bp-38h]@1
+    int screenCenter_X; // [sp+48030h] [bp-34h]@1
+    int v86; // [sp+48034h] [bp-30h]@1
+    int v87; // [sp+48038h] [bp-2Ch]@16
+    unsigned int v88; // [sp+4803Ch] [bp-28h]@16
+    int black; // [sp+48040h] [bp-24h]@8
+    int screenCenterY; // [sp+48044h] [bp-20h]@1
+    unsigned int i; // [sp+48048h] [bp-1Ch]@9
+    unsigned int screenHeight; // [sp+4804Ch] [bp-18h]@16
+    unsigned __int16 *v93; // [sp+48050h] [bp-14h]@16
+    signed int screenWidth; // [sp+48054h] [bp-10h]@8
+    unsigned int v95; // [sp+48058h] [bp-Ch]@16
+    int v96; // [sp+4805Ch] [bp-8h]@10
+    const void *v97; // [sp+48060h] [bp-4h]@16
+    unsigned short *a4a; // [sp+4806Ch] [bp+8h]@85
+    int a5a; // [sp+48070h] [bp+Ch]@86
+
+    tl_x = tl_x;
+    tl_y = tl_y;
+    screenCenter_X = (signed int)(tl_x + br_x) >> 1;
+    screenCenterY = (signed int)(tl_y + br_y) >> 1;
+    surfPitch = pRenderer->uTargetSurfacePitch;
+    pRenderer->SetRasterClipRect(tl_x, tl_y, br_x, br_y);
+    v5 = viewparams->field_2C;
+    v6 = viewparams->sViewCenterX;
+    v86 = viewparams->sViewCenterX;
+    v84 = viewparams->sViewCenterY;
+    if ( viewparams->field_2C != 384 )
+        {
+        if ( viewparams->field_2C == 768 )
+            {
+            if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
+                v5 = 680;
+            }
+        }
+    else
+        {
+        v6 = viewparams->indoor_center_x;
+        v86 = viewparams->indoor_center_x;
+        v84 = viewparams->indoor_center_y;
+        if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
+            v5 = viewparams->field_2C - 34;
+        }
+    if ( uCurrentlyLoadedLevelType != LEVEL_Indoor)
+        {
+        screenWidth = br_x - tl_x + 1;
+        screenHeight = br_y - tl_y + 1;
+        render16_data = &pRenderer->pTargetSurface[tl_x + tl_y * surfPitch];
+        texture8_data = pIcons_LOD->pTextures[viewparams->uTextureID_LocationMap].pLevelOfDetail0_prolly_alpha_mask;
+        pPalette_16 = pIcons_LOD->pTextures[viewparams->uTextureID_LocationMap].pPalette16;
+        scale_increment = (1 << (pIcons_LOD->pTextures[viewparams->uTextureID_LocationMap].uWidthLn2 + 16)) / v5;
+
+        v30 = (double)(1 << (16 - pIcons_LOD->pTextures[viewparams->uTextureID_LocationMap].uWidthLn2));
+
+
+        teal =               (unsigned int)(signed __int64)((double)(v6 - 22528 / (v5 / 384) + 32768) / v30) << 16;
+        v97 = (const void *)((unsigned int)(signed __int64)((double)(v6 - 22528 / (v5 / 384) + 32768) / v30) << 16);
+
+        v32 = map_texture_16;
+        textr_width = pIcons_LOD->pTextures[viewparams->uTextureID_LocationMap].uTextureWidth;
+        stepY_r =            (int)(signed __int64)((double)(- v84 - 22528 / (v5 / 384)+ 32768) / v30) << 16;
+        v81 =   (signed __int16)(signed __int64)((double)(v6 - 22528 / (v5 / 384) + 32768) / v30);
+        black = (signed __int16)(signed __int64)((double)(v6 - 22528 / (v5 / 384) + 32768) / v30);
+
+        v76 = textr_width;
+        scaled_posY = stepY_r >> 16;
+        //nearest neiborhood scaling
+        if ( texture8_data)  
+            {
+            for(uint i=0; i<screenHeight;++i)
+                {
+                curr_line=&texture8_data[scaled_posY*textr_width];
+                stepX_r=teal;
+                for(uint j=0; j<screenWidth;++j)
+                    {
+                    scaled_posX=stepX_r>>16;
+                    map_texture_16[i*screenWidth+j]=pPalette_16[*(curr_line+scaled_posX)];
+                    stepX_r+=scale_increment;      
+                    }
+                stepY_r+=scale_increment;
+                scaled_posY=stepY_r>>16;
+                }
+            }
+        //move visible square to render
+        for(uint i=0; i<screenHeight;++i)
+            {
+            if ( screenWidth > 0 )
+                {
+                memcpy((void*)&render16_data[surfPitch*i],(void*)&map_texture_16[i*screenWidth], screenWidth*2);
+                }
+            }
+        }
+    else
+        {
+        black = TargetColor(0, 0, 0);
+        teal = TargetColor(0, 0xFFu, 0xFFu);
+        v7 = pIndoor->pMapOutlines;
+        uNumBlueFacesInBLVMinimap = 0;
+        v8 = pIndoor->pMapOutlines->uNumOutlines == 0;
+        v9 = pIndoor->pMapOutlines->uNumOutlines < 0;
+        screenWidth = 0;
+        if ( !(v9 | v8) )
+            {
+            i = 0;
+            do
+                {
+                v10 = (int)((char *)v7 + i + 4);
+                v96 = pIndoor->pFaces[*(short *)((char *)v7 + i + 8)].uAttributes;
+                if ( !(BYTE1(v96) & 0x20 || (v11 = pIndoor->pFaces[*(short *)((char *)v7 + i + 10)].uAttributes, BYTE1(v11) & 0x20) ))
+                    {
+                    v12 = *(short *)((char *)v7 + i + 14);
+                    if ( !(v12 & 1) )
+                        {
+                        if ( !(!(v96 & 0x80) && (v11 & 0x80u) == 0 ))
+                            {
+                            v96 = (signed int)screenWidth >> 3;
+                            v13 = screenWidth;
+                            *(short *)(v10 + 10) = v12 | 1;
+                            pIndoor->_visible_outlines[v96] |= 1 << (7 - v13 % 8);
+                            }
+                        }
+                    if ( (!(v12 & 1) && !(!(v96 & 0x80) && (v11 & 0x80u) == 0 )) || v12 & 1)
+                        {
+                        v14 = *(short *)v10;
+                        v88 = v5;
+                        v15 = &pIndoor->pVertices[v14];
+                        v16 = v15->x;
+                        v17 = v15->y - v84;
+                        v93 = (unsigned __int16 *)(v16 - v6);
+                        screenHeight = v17;
+                        v18 = &pIndoor->pVertices[*(short *)(v10 + 2)];
+                        v19 = v18->x;
+                        v20 = v18->y - v84;
+                        v95 = v19 - v6;
+                        v97 = (const void *)v20;
+                        v88 = (unsigned __int64)((v16 - v6) * (signed __int64)v5) >> 16;
+                        v87 = (unsigned __int64)((signed int)screenHeight * (signed __int64)v5) >> 16;
+                        v93 = (unsigned __int16 *)((unsigned __int64)((v19 - v6) * (signed __int64)v5) >> 16);
+                        screenHeight = (unsigned __int64)(v20 * (signed __int64)v5) >> 16;
+                        pRenderer->RasterLine2D(
+                            screenCenter_X + v88,
+                            screenCenterY - v87,
+                            screenCenter_X + ((unsigned __int64)((v19 - v6) * (signed __int64)v5) >> 16),
+                            screenCenterY - screenHeight,
+                            black);
+                        v7 = pIndoor->pMapOutlines;
+                        }
+                    }
+                ++screenWidth;
+                i += 12;
+                }
+                while ( screenWidth < (signed int)v7->uNumOutlines );
+            }
+        v21 = 0;
+        if ( (signed int)uNumBlueFacesInBLVMinimap > 0 )
+            {
+            while ( 1 )
+                {
+                v22 = pBlueFacesInBLVMinimapIDs[v21];
+                v87 = v5;
+                v23 = &v7->pOutlines[v22];
+                v24 = &pIndoor->pVertices[v23->uVertex1ID];
+                v25 = &pIndoor->pVertices[v23->uVertex2ID];
+                v26 = v25->x;
+                v27 = (unsigned __int16 *)(v24->x - v86);
+                v28 = v24->y - v84;
+                v29 = v25->y - v84;
+                v93 = v27;
+                screenHeight = v28;
+                v97 = (const void *)v29;
+                v87 = (unsigned __int64)((signed int)v27 * (signed __int64)v5) >> 16;
+                v88 = (unsigned __int64)(v28 * (signed __int64)v5) >> 16;
+                i = (unsigned __int64)((v26 - v86) * (signed __int64)v5) >> 16;
+                v95 = (unsigned __int64)(v29 * (signed __int64)v5) >> 16;
+                pRenderer->RasterLine2D(
+                    screenCenter_X + ((unsigned __int64)((signed int)v27 * (signed __int64)v5) >> 16),
+                    screenCenterY - v88,
+                    screenCenter_X + ((unsigned __int64)((v26 - v86) * (signed __int64)v5) >> 16),
+                    screenCenterY - v95,
+                    teal);
+                ++v21;
+                if ( v21 >= (signed int)uNumBlueFacesInBLVMinimap )
+                    break;
+                v7 = pIndoor->pMapOutlines;
+                }
+            v6 = v86;
+            }
+        }
+    v47 = ((unsigned __int64)((pParty->vPosition.x - v6) * (signed __int64)v5) >> 16) + screenCenter_X - 3;
+    v81 = pParty->vPosition.y - v84;
+    v97 = (const void *)((unsigned __int64)((pParty->vPosition.y - v84) * (signed __int64)v5) >> 16);
+    v48 = 1;
+    v49 = screenCenterY - (int)v97 - 3;
+    if ( v47 >= (signed int)tl_x )
+        {
+        if ( v47 > (signed int)br_x )
+            {
+            if ( (signed int)(((unsigned __int64)((pParty->vPosition.x - v6) * (signed __int64)v5) >> 16) + screenCenter_X - 6) > (signed int)br_x )
+                v48 = 0;
+            v47 = br_x;
+            }
+        }
+    else
+        {
+        if ( (signed int)(((unsigned __int64)((pParty->vPosition.x - v6) * (signed __int64)v5) >> 16) + screenCenter_X) < (signed int)tl_x )
+            v48 = 0;
+        v47 = tl_x;
+        }
+    if ( v49 >= (signed int)tl_y )
+        {
+        if ( v49 > br_y )
+            {
+            if ( screenCenterY - (signed int)v97 - 6 > br_y )
+                v48 = 0;
+            v49 = br_y;
+            }
+        }
+    else
+        {
+        if ( screenCenterY - (signed int)v97 < (signed int)tl_y )
+            v48 = 0;
+        v49 = tl_y;
+        }
+    if ( v48 == 1 )
+        {
+        v50 = 0;
+        v51 = pParty->sRotationY & stru_5C6E00->uDoublePiMask;
+        if ( (signed int)(pParty->sRotationY & stru_5C6E00->uDoublePiMask) >= 128 )
+            {
+            if ( (signed int)v51 > 384 )
+                {
+                if ( (signed int)v51 >= 640 )
+                    {
+                    if ( (signed int)v51 > 896 )
+                        {
+                        if ( (signed int)v51 >= 1152 )
+                            {
+                            if ( (signed int)v51 > 1408 )
+                                {
+                                if ( (signed int)v51 >= 1664 )
+                                    {
+                                    if ( (signed int)v51 <= 1920 )
+                                        v73 = 7;
+                                    }
+                                else
+                                    {
+                                    v73 = 6;
+                                    }
+                                }
+                            else
+                                {
+                                v73 = 5;
+                                }
+                            }
+                        else
+                            {
+                            v73 = 4;
+                            }
+                        }
+                    else
+                        {
+                        v73 = 3;
+                        }
+                    }
+                else
+                    {
+                    v73 = 2;
+                    }
+                if( (signed int)v51 <=1920)
+                    v50 = v73;
+                }
+            else
+                v50 = 1;
+            }
+        pRenderer->DrawTransparentRedShade(v47, v49, pIcons_LOD->GetTexture(pTextureIDs_pMapDirs[v50]));
+        }
+    result = TargetColor(0xFFu, 0xFFu, 0xFFu);
+    v95 = 0;
+    v86 = result;
+    if ( (signed int)uNumLevelDecorations > 0 )
+        {
+        screenWidth = (unsigned int)&pLevelDecorations[0].vPosition;
+        do
+            {
+            if ( *(char *)(screenWidth - 2) & 8 )
+                {
+                v53 = *(int *)(screenWidth + 4) - v84;
+                v93 = (unsigned __int16 *)(*(int *)screenWidth - v6);
+                screenHeight = v53;
+                v54 = ((unsigned __int64)((signed int)v93 * (signed __int64)v5) >> 16) + screenCenter_X;
+                v97 = (const void *)((unsigned __int64)(v53 * (signed __int64)v5) >> 16);
+                v55 = screenCenterY - (int)v97;
+                if ( v54 >= pRenderer->raster_clip_x )
+                    {
+                    if ( v54 <= pRenderer->raster_clip_z && v55 >= pRenderer->raster_clip_y && v55 <= pRenderer->raster_clip_w )
+                        {
+                        v74 = v86;
+                        if ( v5 > 512 )
+                            {
+                            v96 = v55 + 1;
+                            black = v55 - 1;
+                            pRenderer->RasterLine2D(v54 - 1, v55 - 1, v54 - 1, v55 + 1, v86);
+                            pRenderer->RasterLine2D(v54, black, v54, v96, v86);
+                            ++v54;
+                            v74 = v86;
+                            v72 = v96;
+                            v71 = v54;
+                            v70 = black;
+                            }
+                        else
+                            {
+                            v72 = screenCenterY - (int)v97;
+                            v71 = ((unsigned __int64)((signed int)v93 * (signed __int64)v5) >> 16) + screenCenter_X;
+                            v70 = screenCenterY - (int)v97;
+                            }
+                        pRenderer->RasterLine2D(v54, v70, v71, v72, v74);
+                        }
+                    }
+                }
+            ++v95;
+            result = v95;
+            screenWidth += 32;
+            }
+            while ( (signed int)v95 < (signed int)uNumLevelDecorations );
+        }
+    if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor)
+        {
+        screenCenterY = br_x - tl_x + 1;
+        v95 = br_y - tl_y + 1;
+        v77 = &pRenderer->pTargetSurface[tl_x + tl_y * surfPitch];
+        v56 = pIcons_LOD->pTextures[viewparams->uTextureID_LocationMap].uWidthLn2;
+        black = (1 << (v56 + 16)) / v5;
+        v57 = (double)(1 << (16 - v56));
+        v58 = 22528 / (v5 / 384);
+        v59 = (signed __int64)((double)(v6 - v58 + 32768) / v57);
+        v60 = (int)v59 << 16;
+        v97 = (const void *)((int)v59 << 16);
+        v61 = (signed __int64)((double)(32768 - v58 - v84) / v57);
+        pPalette_16 = (unsigned __int16 *)(v60 >> 16);
+        v62 = (int)v61 << 16;
+        teal = v60 >> 16;
+        v63 = (signed __int16)v61;
+        a4a = map_texture_16;
+        result = TargetColor(0xCu, 0xCu, 0xCu);
+        screenCenter_X = 0;
+        for ( i = result; screenCenter_X < (signed int)v95; result = screenCenter_X )
+            {
+            a5a = 0;
+            if ( screenCenterY > 0 )
+                {
+                v96 = (v63 - 80) / 4;
+                v64 = teal;
+                do
+                    {
+                    v81 = (v64 - 80) / 4;
+                    if ( !pOutdoor->_47F04C(v81, v96) )
+                        {
+                        if ( pOutdoor->_47F097(v81, v96) )
+                            {
+                            if ( !((a5a + screenCenter_X) % 2) )
+                                *a4a = i;
+                            }
+                        else
+                            {
+                            *a4a = 0;
+                            }
+                        }
+                    ++a4a;
+                    v97 = (char *)v97 + black;
+                    v64 = (signed int)v97 >> 16;
+                    ++a5a;
+                    }
+                    while ( a5a < screenCenterY );
+                }
+            v62 += black;
+            v97 = (const void *)v60;
+            a4a += screenCenterY - a5a;
+            v63 = v62 >> 16;
+            ++screenCenter_X;
+            teal = (unsigned int)pPalette_16;
+            }
+        v65 = v95;
+        v66 = map_texture_16;
+        if ( (signed int)v95 > 0 )
+            {
+            v67 = v77;
+            result = 2 * (surfPitch - screenCenterY);
+            do
+                {
+                if ( screenCenterY > 0 )
+                    {
+                    v68 = screenCenterY;
+                    do
+                        {
+                        v69 = *(short *)v66;
+                        if ( !*(short *)v66 || v69 == (short)i )
+                            *v67 = v69;
+                        ++v66;
+                        ++v67;
+                        --v68;
+                        }
+                        while ( v68 );
+                    }
+                v67 = (unsigned __int16 *)((char *)v67 + result);
+                --v65;
+                }
+                while ( v65 );
+            }
+        }
+    }
+
+
+
+
+
+//----- (00412AF9) --------------------------------------------------------
+static void BookUI_Spellbook_DrawCurrentSchoolBackground()
+{
+  int v0; // ecx@1
+
+  v0 = 0;
+  if ( uActiveCharacter )
+	  v0 = pParty->pPlayers[uActiveCharacter - 1].lastOpenedSpellbookPage;//*((char *)&pParty->pPartyBuffs[5].uExpireTime + 6972 * uActiveCharacter + 2);
+  pRenderer->DrawTextureIndexed(8, 8, pSpellBookPagesTextr[v0]);
+  pRenderer->DrawTextureIndexed(0x1DCu, 0x1C2u, pTexture_50643C);
+  pRenderer->DrawTextureIndexed(0x231u, 0x1C2u, pTexture_506448);
+}
+
+
+
+
+
+//----- (00412B58) --------------------------------------------------------
+void DrawSpellBookContent(Player *player)
+{
+  //Player *v0; // ebx@1
+  int v1; // ebp@1
+  //unsigned int v2; // eax@1
+  Texture *v3; // edi@1
+  int v4; // esi@1
+  Texture *v5; // eax@3
+  Texture *v6; // edx@5
+  int v7; // eax@8
+  int v8; // eax@11
+  POINT *v9; // esi@13
+  int v10; // eax@13
+  Texture *v11; // edx@14
+  int v12; // eax@15
+  signed int v13; // ecx@18
+  unsigned int v14; // esi@18
+  unsigned int v15; // edi@18
+  Texture *pPageTexture; // eax@21
+  unsigned int v17; // [sp-Ch] [bp-2Ch]@8
+  unsigned int v18; // [sp-Ch] [bp-2Ch]@15
+  unsigned int v19; // [sp-8h] [bp-28h]@8
+  unsigned int v20; // [sp-8h] [bp-28h]@15
+  Texture *v21; // [sp-4h] [bp-24h]@15
+  signed int v22; // [sp-4h] [bp-24h]@22
+  Texture *v23; // [sp+10h] [bp-10h]@5
+  POINT a2; // [sp+18h] [bp-8h]@13
+  POINT v24;
+  int v25;
+
+  static unsigned int texture_tab_coord1[9][2]=
+      {{406, 9}, {406, 46}, {406, 84}, {406,121}, {407,158}, {405, 196}, {405, 234}, {405, 272}, {405,309} };
+
+  static unsigned int texture_tab_coord0[9][2]=
+      {{415, 10}, {415, 46}, {415, 83}, {415,121}, {415,158}, {416, 196}, {416, 234}, {416, 271}, {416,307} };
+
+  BookUI_Spellbook_DrawCurrentSchoolBackground();
+
+  //v0 = pPlayers[uActiveCharacter];
+  v1 = 11 * player->lastOpenedSpellbookPage;
+  //v2 = pIcons_LOD->FindTextureByName("Pending");
+  v3 = pIcons_LOD->GetTexture(pIcons_LOD->FindTextureByName("Pending"));
+  pRenderer->ClearZBuffer(0, 479);
+  v4 = 1;
+  if ( __OFSUB__(v1, v1 + 11) ^ 1 )
+  {
+    do
+    {
+      if ( *(&player->_guilds_member_bits[v1 + 63] + v4) )
+      {
+        v5 = (Texture *)dword_506408[v4];
+        if ( v5 != v3 )
+        {
+          if ( quick_spell_at_page == v4 )
+          {
+            v6 = dword_5063D8[v4];
+            v23 = dword_5063D8[v4];
+          }
+          else
+          {
+            v23 = dword_506408[v4];
+            v6 = v5;
+          }
+          if ( v6->pLevelOfDetail0_prolly_alpha_mask )
+          {
+			v7 = player->lastOpenedSpellbookPage;
+           // v7 =  (12 * v0->lastOpenedSpellbookPage + pSpellbookSpellIndices[v0->lastOpenedSpellbookPage][v4]);
+            v19 = pViewport->uViewportTL_Y +  pIconPos[v7][pSpellbookSpellIndices[v7][v4]].Ypos;
+            v17 = pViewport->uViewportTL_X +  pIconPos[v7][pSpellbookSpellIndices[v7][v4]].Xpos;
+            if ( BYTE1(v6->pBits) & 2 )
+              pRenderer->DrawTextureTransparent(v17, v19, v6);
+            else
+              pRenderer->DrawTextureIndexed(v17, v19, v6);
+            pRenderer->DrawMaskToZBuffer(pIconPos[v7][pSpellbookSpellIndices[v7][v4]].Xpos,
+				               pIconPos[v7][pSpellbookSpellIndices[v7][v4]].Ypos, v23, v4);
+          }
+        }
+      }
+      ++v4;
+    }
+    while ( v4 - 1 < 11 );
+  }
+
+
+  v9 = pMouse->GetCursorPos(&a2);
+  v10 = pRenderer->pActiveZBuffer[v9->x + pSRZBufferLineOffsets[pMouse->GetCursorPos(&v24)->y]] & 0xFFFF;
+  if ( v10 )
+  {
+    v11 = dword_5063D8[v10];
+    if ( v11->pLevelOfDetail0_prolly_alpha_mask )
+    {
+      v21 = dword_5063D8[v10];
+	  v12 = player->lastOpenedSpellbookPage;
+    //  v12 = (12 * v0->lastOpenedSpellbookPage + pSpellbookSpellIndices[v0->lastOpenedSpellbookPage][v10]);
+      v20 = pViewport->uViewportTL_Y +  pIconPos[v12][pSpellbookSpellIndices[v12][v10]].Ypos;
+      v18 = pViewport->uViewportTL_X +  pIconPos[v12][pSpellbookSpellIndices[v12][v10]].Xpos;
+      if ( BYTE1(v11->pBits) & 2 )
+        pRenderer->DrawTextureTransparent(v18, v20, v21);
+      else
+        pRenderer->DrawTextureIndexed(v18, v20, v21);
+    }
+  }
+  v13 = 0;
+  a2.x = (LONG)&player->pActiveSkills[12];
+  v14 = (unsigned int)&player->pActiveSkills[12];
+  v15 = (unsigned int)&player->pActiveSkills[12];
+  v25 = 0;
+  do
+  {
+    if ( *(short *)a2.x )
+    {
+      if ( player->lastOpenedSpellbookPage == v13 )
+      {
+        pPageTexture = pTextures_tabs[v13][1];
+       v14=texture_tab_coord1[v13][0];
+       v15=texture_tab_coord1[v13][1];
+      }
+      else
+      {
+        pPageTexture = pTextures_tabs[v13][0];
+        v14=texture_tab_coord0[v13][0];
+        v15=texture_tab_coord0[v13][1];
+      }
+      pRenderer->DrawTextureTransparent(v14, v15, pPageTexture);
+      v13 = v25;
+    }
+    a2.x += 2;
+    ++v13;
+    v25 = v13;
+  }
+  while ( v13 < 9 );
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/UI/UICharacter.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -0,0 +1,3125 @@
+#ifdef _MSC_VER
+#define _CRT_SECURE_NO_WARNINGS
+#endif
+
+#include <assert.h>
+
+#include <algorithm> 
+
+#include "..\MM7.h"
+
+#include "..\MapInfo.h"
+#include "..\Game.h"
+#include "..\GUIWindow.h"
+#include "..\GUIFont.h"
+#include "..\GUIProgressBar.h"
+#include "..\Party.h"
+#include "..\AudioPlayer.h"
+#include "..\Render.h"
+#include "..\IndoorCamera.h"
+#include "..\LOD.h"
+#include "..\Viewport.h"
+#include "..\Time.h"
+#include "..\Awards.h"
+#include "..\CastSpellInfo.h"
+#include "..\texts.h"
+
+#include "..\mm7_data.h"
+#include "..\Mouse.h"
+#include "..\Allocator.h"
+
+
+int bRingsShownInCharScreen; // 5118E0
+
+
+unsigned int ui_mainmenu_copyright_color;
+
+unsigned int ui_character_default_text_color;
+unsigned int ui_character_skill_highlight_color;
+unsigned int ui_character_header_text_color;
+unsigned int ui_character_bonus_text_color;
+unsigned int ui_character_bonus_text_color_neg;
+unsigned int ui_character_skill_upgradeable_color;
+unsigned int ui_character_skill_default_color;
+std::array<unsigned int, 6> ui_character_award_color;
+
+unsigned int ui_game_minimap_outline_color;
+unsigned int ui_game_minimap_actor_friendly_color;
+unsigned int ui_game_minimap_actor_hostile_color;
+unsigned int ui_game_minimap_actor_corpse_color;
+unsigned int ui_game_minimap_decoration_color_1;
+unsigned int ui_game_minimap_projectile_color;
+unsigned int ui_game_minimap_treasure_color;
+std::array<unsigned int, 24> ui_game_character_record_playerbuff_colors;
+
+unsigned int ui_gamemenu_video_gamma_title_color;
+unsigned int ui_gamemenu_keys_action_name_color;
+unsigned int ui_gamemenu_keys_key_selection_blink_color_1;
+unsigned int ui_gamemenu_keys_key_selection_blink_color_2;
+unsigned int ui_gamemenu_keys_key_default_color;
+
+unsigned int ui_book_quests_title_color;
+unsigned int ui_book_quests_text_color;
+unsigned int ui_book_autonotes_title_color;
+unsigned int ui_book_autonotes_text_color;
+unsigned int ui_book_map_title_color;
+unsigned int ui_book_map_coordinates_color;
+
+unsigned int ui_book_calendar_title_color;
+unsigned int ui_book_calendar_time_color;
+unsigned int ui_book_calendar_day_color;
+unsigned int ui_book_calendar_month_color;
+unsigned int ui_book_calendar_year_color;
+unsigned int ui_book_calendar_moon_color;
+unsigned int ui_book_calendar_location_color;
+
+unsigned int ui_book_journal_title_color;
+unsigned int ui_book_journal_text_color;
+unsigned int ui_book_journal_text_shadow;
+
+std::array<unsigned int, 16> papredoll_dbrds;
+unsigned int papredoll_drhs[4];
+unsigned int papredoll_dlhus[4];
+unsigned int papredoll_dlhs[4];
+unsigned int papredoll_dbods[5];
+int paperdoll_armor_texture[4][17][3];
+//int paperdoll_array_51132C[165];
+unsigned int papredoll_dlaus[5];
+unsigned int papredoll_dlads[4];
+int papredoll_flying_feet[777]; // idb
+int paperdoll_boots_texture[4][6];//0x511638
+int paperdoll_cloak_collar_texture[4][10]; // weak
+int paperdoll_cloak_texture[4][10];
+int paperdoll_helm_texture[2][16]; //511698
+int paperdoll_belt_texture[4][7];  //511718
+
+
+const int paperdoll_Weapon[4][16][2] = {//4E4C30
+    {{128, 205},  {30, 144},  {88,  85},  {0, 0},  {0, 0},  {0, 0},  {17, 104},  {0, 0},  {0, 0},  {0, 0},  {0, 0},  {0, 0},  {0, 0},  {0, 0},  {0, 0},  {0, 0}},
+    {{131, 201},  {38, 158},  {98,  87},  {0, 0},  {0, 0},  {0, 0},  {21, 100},  {0, 0},  {0, 0},  {0, 0},  {0, 0},  {0, 0},  {0, 0},  {0, 0},  {0, 0},  {0, 0}},
+    {{131, 216},  {29, 186},  {88, 119},  {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}},
+    {{123, 216},  {35, 184},  {98, 119},  {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}},
+    };
+
+
+
+const int paperdoll_Boot[4][7][2] = //4E5490
+    {
+    0xE, 0x11D,    0xD, 0x11D,    0xC, 0x10A,    0xA, 0xFF,    0xD, 0xF9,    0xD, 0x137,   0xC, 0x10E,
+    0x14, 0x125,   0x13, 0x122,   0x15, 0x120,   0x15, 0x114,  0x13, 0x10A,  0x11, 0x13E,  0x11, 0x116,
+    0x1D, 0x121,   0x1C, 0x11F,   0x1B, 0x11B,   0x1C, 0x117,  0x16, 0x116,  0x1B, 0x137,  0x1B, 0x11B,
+    0x1F, 0x127,   0x1F, 0x122,   0x1B, 0x11B,   0x1D, 0x117,  0x1D, 0x116,  0x1D, 0x137,  0x1B, 0x11F,
+    };
+const int paperdoll_Cloak[4][10][2] = //4E5570
+    {
+    0x11, 0x68,  0xF, 0x68,  0x14, 0x71,  0x19, 0x6B,  0x21, 0x6F,  0x5, 0x68,  0x5, 0x68,  0x14, 0x71,  0x3, 0x6B,  0xF, 0x6F,
+    0x15, 0x64,  0xB, 0x6B,  0xE, 0x67,   0x15, 0x6B,  0x1B, 0x6F,  0x3, 0x6B,  0, 0x6B,    0xE, 0x67,   0, 0x6B,    0x3, 0x6F,
+    0x10, 0x8A,  0x9, 0x8B,  0x18, 0x98,  0x25, 0x91,  0x29, 0x90,  0x8, 0x8A,  0x9, 0x8B,  0x18, 0x98,  0x3, 0x91,  0x3, 0x90,
+    0x14, 0x92,  0x10, 0x92, 0x15, 0x98,  0x1F, 0x91,  0x22, 0x90,  0x8, 0x92,  0xC, 0x92,  0x15, 0x98,  0x3, 0x91,  0x3, 0x90,
+    };
+const int paperdoll_CloakCollar[4][10][2] = //4E56B0
+    {
+    0x11, 0x68,  0x34, 0x64,  0x21, 0x69,  0x1D, 0x67,  0x20, 0x67,  0x21, 0x68,  0x34, 0x64,  0x21, 0x69,  0x1D, 0x67,  0x1F, 0x67,
+    0x13, 0x64,  0x35, 0x66,  0x29, 0x68,  0x1F, 0x68,  0x1F, 0x6A,  0x21, 0x6A,  0x2B, 0x66,  0x26, 0x68,  0x1F, 0x68,  0x1F, 0x6A,
+    0, 0,        0x30, 0x87,  0x1E, 0x86,  0x1B, 0x86,  0x1C, 0x8A,  0x21, 0x87,  0x30, 0x87,  0x1E, 0x86,  0x1B, 0x86,  0x1C, 0x8A,
+    0, 0,        0x38, 0x8A,  0x24, 0x8B,  0x1D, 0x8B,  0x21, 0x8C,  0x27, 0x8A,  0x34, 0x8A,  0x24, 0x8B,  0x25, 0x8B,  0x21, 0x8C,
+    };
+//int dword_4E56B4; // weak
+const int paperdoll_Belt[4][7][2] = //4E57F0
+    {
+    0x3A, 0xB6,  0x37, 0xB2,  0x34, 0xB9,  0x3A, 0xB9,  0x37, 0xB7,  0x38, 0xAC,  0x37, 0xB7,
+    0x3E, 0xAD,  0x3A, 0xAC,  0x37, 0xB0,  0x3A, 0xB1,  0x39, 0xB0,  0x3C, 0xA5,  0x39, 0xB0,
+    0x3B, 0xD5,  0x37, 0xD2,  0x31, 0xD5,  0x39, 0xD6,  0x37, 0xD8,  0x37, 0xD1,  0x37, 0xD8,
+    0x42, 0xD2,  0x3F, 0xD0,  0x3B, 0xD7,  0x3C, 0xD5,  0x3B, 0xD6,  0x3E, 0xCF,  0x36, 0xD6,
+    };
+const int paperdoll_Helm[4][16][2] = //4E58D0
+    {
+    0x3E, 0x1F,  0x41, 0x2C,  0x37, 0x2F,  0x31, 0x32,  0x37, 0x2A,  0x39, 0x28,  0x36, 0x34,  0x41, 0x38,  0x40, 0x31,  0x40, 0x21,  0x40, 0x31,  0x3C, 0x33,  0x3D, 0x24,  0x3A, 0x1A,  0x37, 0x2A,  0x41, 0x48,
+    0x41, 0x1E,  0x42, 0x2B,  0x37, 0x2F,  0x34, 0x30,  0x39, 0x29,  0x3A, 0x26,  0x36, 0x34,  0x41, 0x37,  0x42, 0x32,  0x40, 0x21,  0x40, 0x31,  0x40, 0x2F,  0x3E, 0x22,  0x3B, 0x1A,  0x39, 0x29,  0x42, 0x47,
+    0x3F, 0x47,  0x41, 0x56,  0x37, 0x59,  0x32, 0x5E,  0x37, 0x58,  0x39, 0x54,  0x34, 0x61,  0x40, 0x61,  0x41, 0x5D,  0x3E, 0x4F,  0x3E, 0x5B,  0x3D, 0x5B,  0x3F, 0x4C,  0x3B, 0x45,  0x37, 0x58,  0x41, 0x74,
+    0x45, 0x45,  0x46, 0x54,  0x3A, 0x55,  0x38, 0x58,  0x3C, 0x54,  0x3F, 0x52,  0x39, 0x5B,  0x45, 0x5C,  0x47, 0x5C,  0x44, 0x4B,  0x44, 0x57,  0x43, 0x55,  0x44, 0x4A,  0x3E, 0x45,  0x3C, 0x54,  0x47, 0x70,
+    };
+const int pPaperdoll_Beards[4] = //4E5AD0
+    {
+    52, 130, 56, 136,
+    };
+const int pPaperdoll_LeftHand[4][2] = //4E5AE0
+    {
+    0x67, 0x6A,
+    0x65, 0x6C,
+    0x74, 0x8D,
+    0x74, 0x93,
+    };
+const int pPaperdoll_SecondLeftHand[4][2] = //4E5B00
+    {
+    0x1A, 0x6B,
+    0x28, 0x6D,
+    0x19, 0x8D,
+    0x20, 0x92,
+    };
+const int pPaperdoll_RightHand[4][2] = //4E5B20
+    {
+    0x1E, 0x90,
+    0x22, 0x9E,
+    0x19, 0xBA,
+    0x1F, 0xB8,
+    };
+const int pPaperdollLeftEmptyHand[4][2] = //4E5B40
+    {
+    0x80, 0xCD,
+    0x83, 0xC9,
+    0x83, 0xD8,
+    0x7B, 0xD8,
+    };
+
+int pPaperdoll_BodyX = 481; // 004E4C28
+int pPaperdoll_BodyY = 0;   // 004E4C2C
+const int paperdoll_Armor[4][17][2] = //4E4E30
+    {
+    // X     Y
+    0x2C, 0x67,  0x30, 0x69,  0x2D, 0x67,  0x2C, 0x64,  0x14, 0x66,  0x22, 0x67,  0x20, 0x66,  0x25, 0x66,  0x12, 0x66,//Human
+    0x0A, 0x66,  0x13, 0x64,  0x0E, 0x64,  0x0A, 0x63,  0x14, 0x66,  0x0A, 0x63,  0x0A, 0x66,  0x25, 0x66,
+
+    0x32, 0x68,  0x32, 0x69,  0x35, 0x69,  0x33, 0x68,  0x24, 0x67,  0x30, 0x69,  0x33, 0x68,  0x31, 0x69,  0x19, 0x69,
+    0x19, 0x6A,  0x16, 0x66,  0x16, 0x65,  0x0F, 0x6B,  0x24, 0x67,  0x0F, 0x6B,  0x19, 0x6A,  0x31, 0x69,
+
+    0x2A, 0x8C,  0x29, 0x8C,  0x2A, 0x89,  0x29, 0x86,  0x12, 0x87,  0x2D, 0x89,  0x2A, 0x88,  0x25, 0x87,  0x12, 0x8B,
+    0x12, 0x8B,  0x11, 0x8A,  0x15, 0x87,  0x09, 0x89,  0x12, 0x87,  0x09, 0x89,  0x12, 0x8B,  0x25, 0x87,
+
+    0x33, 0x90,  0x32, 0x90,  0x34, 0x91,  0x32, 0x8E,  0x21, 0x8B,  0x31, 0x8B,  0x33, 0x8E,  0x2F, 0x8F,  0x16, 0x8D,
+    0x18, 0x8C,  0x19, 0x8C,  0x1B, 0x8E,  0x0C, 0x8C,  0x21, 0x8B,  0x0C, 0x8C,  0x18, 0x8C,  0x2F, 0x8F,
+    };
+const int paperdoll_shoulder[4][17][2] = //4E5050
+    {
+    0x64, 0x67,  0x61, 0x67,  0x65, 0x68,  0x6E, 0x74,  0x6C, 0x68,  0x61, 0x67,  0x66, 0x68,  0x6C, 0x6A,  0x6E, 0x6D,
+    0x67, 0x69,  0x70, 0x67,  0x6E, 0x6D,  0x6C, 0x6F,  0x6C, 0x68,  0x6C, 0x6F,  0x67, 0x69,  0x6C, 0x6A,
+
+    0x60, 0x6B,  0x60, 0x6C,  0x60, 0x6B,  0x61, 0x6A,  0x60, 0x69,  0x60, 0x6A,  0x60, 0x6A,  0x61, 0x69,  0x63, 0x6A,
+    0x64, 0x6A,  0x61, 0x66,  0x66, 0x67,  0x64, 0x6C,  0x60, 0x69,  0x64, 0x6C,  0x64, 0x6A,  0x61, 0x69,
+
+    0x6D, 0x8C,  0x75, 0x8C,  0, 0,        0x72, 0x8D,  0x6A, 0x89,  0, 0,        0x73, 0x8C,  0x69, 0x8C,  0x6E, 0x8D,
+    0x71, 0x8D,  0x70, 0x8D,  0x72, 0x8D,  0x74, 0x8E,  0x6A, 0x89,  0x74, 0x8E,  0x71, 0x8D,  0x69, 0x8C,
+
+    0x72, 0x91,  0x72, 0x91,  0, 0,        0x6E, 0x92,  0x6F, 0x91,  0, 0,        0, 0,        0x6E, 0x91,  0x71, 0x90,
+    0x72, 0x8D,  0x72, 0x90,  0x73, 0x93,  0x73, 0x90,  0x6F, 0x91,  0x73, 0x90,  0x72, 0x8D,  0x6E, 0x91,
+    };
+const int dword_4E5270[4][2] = 
+    {
+    0, 0,
+    0x61, 0x67,
+    0, 0,
+    0x64, 0x69,
+    };
+
+const char *dlad_texnames_by_face[25] =
+    {
+    "pc01lad", "pc02lad", "pc03lad", "pc04lad", "pc05lad", "pc06lad",
+    "pc07lad", "pc08lad", "pc09lad", "pc10lad", "pc11lad", "pc12lad",
+    "pc13lad", "pc14lad", "pc15lad", "pc16lad", "pc17lad", "pc18lad",
+    "pc19lad", "pc20lad", "pc21lad", "pc22lad", "pc23lad", "pc24lad",
+    "pc25lad"
+    };
+const char *dlau_texnames_by_face[25] =
+    {
+    "pc01lau", "pc02lau", "pc03lau", "pc04lau", "pc05lau", "pc06lau",
+    "pc07lau", "pc08lau", "pc09lau", "pc10lau", "pc11lau", "pc12lau",
+    "pc13lau", "pc14lau", "pc15lau", "pc16lau", "pc17lau", "pc18lau",
+    "pc19lau", "pc20lau", "pc21lau", "pc22lau", "pc23lau", "pc24lau",
+    "pc25lau"
+    };
+const char *dbod_texnames_by_face[25] =
+    {
+    "pc01bod", "pc02bod", "pc03bod", "pc04bod", "pc05bod", "pc06bod",
+    "pc07bod", "pc08bod", "pc09bod", "pc10bod", "pc11bod", "pc12bod",
+    "pc13bod", "pc14bod", "pc15bod", "pc16bod", "pc17bod", "pc18bod",
+    "pc19bod", "pc20bod", "pc21bod", "pc22bod", "pc23bod", "pc24bod",
+    "pc25bod"
+    };
+const char *drh_texnames_by_face[25] =
+    {
+
+    "pc01rh", "pc02rh", "pc03rh", "pc04rh", "pc05rh", "pc06rh",
+    "pc07rh", "pc08rh", "pc09rh", "pc10rh", "pc11rh", "pc12rh",
+    "pc13rh", "pc14rh", "pc15rh", "pc16rh", "pc17rh", "pc18rh",
+    "pc19rh", "pc20rh", "pc21rh", "pc22rh", "pc23rh", "pc24rh",
+    "pc25rh"
+    };
+const char *dlh_texnames_by_face[25] =
+    {
+    "pc01lh", "pc02lh", "pc03lh", "pc04lh", "pc05lh", "pc06lh",
+    "pc07lh", "pc08lh", "pc09lh", "pc10lh", "pc11lh", "pc12lh",
+    "pc13lh", "pc14lh", "pc15lh", "pc16lh", "pc17lh", "pc18lh",
+    "pc19lh", "pc20lh", "pc21lh", "pc22lh", "pc23lh", "pc24lh",
+    "pc25lh"
+    };
+const char *dlhu_texnames_by_face[25] =
+    {
+    "pc01lhu", "pc02lhu", "pc03lhu", "pc04lhu", "pc05lhu", "pc06lhu",
+    "pc07lhu", "pc08lhu", "pc09lhu", "pc10lhu", "pc11lhu", "pc12lhu",
+    "pc13lhu", "pc14lhu", "pc15lhu", "pc16lhu", "pc17lhu", "pc18lhu",
+    "pc19lhu", "pc20lhu", "pc21lhu", "pc22lhu", "pc23lhu", "pc24lhu",
+    "pc25lhu"
+    };
+
+const  int pArmorSkills[5]  = {PLAYER_SKILL_LEATHER, PLAYER_SKILL_CHAIN,      PLAYER_SKILL_PLATE,        PLAYER_SKILL_SHIELD,  PLAYER_SKILL_DODGE};
+const int pWeaponSkills[9] = {PLAYER_SKILL_AXE,     PLAYER_SKILL_BOW,        PLAYER_SKILL_DAGGER,       PLAYER_SKILL_MACE,    PLAYER_SKILL_SPEAR,      
+    PLAYER_SKILL_STAFF,    PLAYER_SKILL_SWORD,       PLAYER_SKILL_UNARMED,    PLAYER_SKILL_BLASTER};
+const  int pMiscSkills[12]  = {PLAYER_SKILL_ALCHEMY, PLAYER_SKILL_ARMSMASTER, PLAYER_SKILL_BODYBUILDING, PLAYER_SKILL_ITEM_ID, PLAYER_SKILL_MONSTER_ID, 
+    PLAYER_SKILL_LEARNING, PLAYER_SKILL_TRAP_DISARM, PLAYER_SKILL_MEDITATION, PLAYER_SKILL_MERCHANT, PLAYER_SKILL_PERCEPTION,
+    PLAYER_SKILL_REPAIR, PLAYER_SKILL_STEALING};
+const  int pMagicSkills[9]  = {PLAYER_SKILL_FIRE,    PLAYER_SKILL_AIR,        PLAYER_SKILL_WATER,        PLAYER_SKILL_EARTH,   PLAYER_SKILL_SPIRIT,    
+    PLAYER_SKILL_MIND,     PLAYER_SKILL_BODY,        PLAYER_SKILL_LIGHT,      PLAYER_SKILL_DARK};
+
+
+
+
+void set_default_ui_skin()
+{
+  ui_mainmenu_copyright_color = TargetColor(255, 255, 255);
+
+  ui_character_default_text_color = TargetColor(255, 255, 255);
+  ui_character_header_text_color = TargetColor(255, 255, 155);
+  ui_character_bonus_text_color = TargetColor(0, 255, 0);
+  ui_character_bonus_text_color_neg = TargetColor(255, 0, 0);
+
+  ui_character_skill_upgradeable_color = TargetColor(0, 175, 255);
+  ui_character_skill_default_color = TargetColor(255, 0, 0);
+  ui_character_skill_highlight_color = TargetColor(255, 0, 0);  
+
+  ui_character_award_color[0] = TargetColor(248, 108, 160);
+  ui_character_award_color[1] = TargetColor(112, 220, 248);
+  ui_character_award_color[2] = TargetColor(192, 192, 240);
+  ui_character_award_color[3] = TargetColor( 64, 244,  96);
+  ui_character_award_color[4] = TargetColor(232, 244,  96);
+  ui_character_award_color[5] = TargetColor(240, 252, 192);
+  
+  ui_game_minimap_outline_color = TargetColor(0, 0, 255);
+  ui_game_minimap_actor_friendly_color = TargetColor(0, 255, 0);
+  ui_game_minimap_actor_hostile_color = TargetColor(255, 0, 0);
+  ui_game_minimap_actor_corpse_color = TargetColor(255, 255, 0);
+  ui_game_minimap_decoration_color_1 = TargetColor(255, 255, 255);
+  ui_game_minimap_projectile_color = TargetColor(255, 0, 0);
+  ui_game_minimap_treasure_color = TargetColor(0, 0, 255);
+  ui_game_character_record_playerbuff_colors[0] = TargetColor(150, 212, 255);
+  ui_game_character_record_playerbuff_colors[1] = TargetColor(225, 225, 225);
+  ui_game_character_record_playerbuff_colors[2] = TargetColor(255, 128, 0);
+  ui_game_character_record_playerbuff_colors[3] = TargetColor(128, 128, 128);
+  ui_game_character_record_playerbuff_colors[4] = TargetColor(225, 225, 225);
+  ui_game_character_record_playerbuff_colors[5] = TargetColor(255, 85, 0);
+  ui_game_character_record_playerbuff_colors[6] = TargetColor(255, 128, 0);
+  ui_game_character_record_playerbuff_colors[7] = TargetColor(255, 85, 0);
+  ui_game_character_record_playerbuff_colors[8] = TargetColor(225, 225, 225);
+  ui_game_character_record_playerbuff_colors[9] = TargetColor(235, 15, 255);
+  ui_game_character_record_playerbuff_colors[10] = TargetColor(192, 192, 240);
+  ui_game_character_record_playerbuff_colors[11] = TargetColor(225, 225, 225);
+  ui_game_character_record_playerbuff_colors[12] = TargetColor(255, 128, 0);
+  ui_game_character_record_playerbuff_colors[13] = TargetColor(150, 212, 255);
+  ui_game_character_record_playerbuff_colors[14] = TargetColor(128, 128, 128);
+  ui_game_character_record_playerbuff_colors[15] = TargetColor(255, 255, 155);
+  ui_game_character_record_playerbuff_colors[16] = TargetColor(255, 255, 155);
+  ui_game_character_record_playerbuff_colors[17] = TargetColor(255, 255, 155);
+  ui_game_character_record_playerbuff_colors[18] = TargetColor(255, 255, 155);
+  ui_game_character_record_playerbuff_colors[19] = TargetColor(255, 255, 155);
+  ui_game_character_record_playerbuff_colors[20] = TargetColor(255, 255, 155);
+  ui_game_character_record_playerbuff_colors[21] = TargetColor(255, 255, 155);
+  ui_game_character_record_playerbuff_colors[22] = TargetColor(0, 128, 255);
+  ui_game_character_record_playerbuff_colors[23] = TargetColor(0, 128, 255);
+
+  ui_gamemenu_video_gamma_title_color = TargetColor(255, 255, 155);
+  ui_gamemenu_keys_action_name_color = TargetColor(255, 255, 255);
+  ui_gamemenu_keys_key_selection_blink_color_1 = TargetColor(50, 0, 0);
+  ui_gamemenu_keys_key_selection_blink_color_2 = TargetColor(225, 205, 35);
+  ui_gamemenu_keys_key_default_color = TargetColor(255, 255, 255);
+
+  ui_book_quests_title_color = TargetColor(255, 255, 255);
+  ui_book_quests_text_color = TargetColor(255, 255, 255);
+  ui_book_autonotes_title_color = TargetColor(255, 255, 255);
+  ui_book_autonotes_text_color = TargetColor(255, 255, 255);
+  ui_book_map_title_color = TargetColor(255, 255, 255);
+  ui_book_map_coordinates_color = TargetColor(255, 255, 255);
+
+  ui_book_calendar_title_color = TargetColor(255, 255, 255);
+  ui_book_calendar_time_color = TargetColor(75, 75, 75);
+  ui_book_calendar_day_color = TargetColor(75, 75, 75);
+  ui_book_calendar_month_color = TargetColor(75, 75, 75);
+  ui_book_calendar_year_color = TargetColor(75, 75, 75);
+  ui_book_calendar_moon_color = TargetColor(75, 75, 75);
+  ui_book_calendar_location_color = TargetColor(75, 75, 75);
+
+  ui_book_journal_title_color = TargetColor(255, 255, 255);
+  ui_book_journal_text_color = TargetColor(255, 255, 255);
+  ui_book_journal_text_shadow = TargetColor(0, 0, 0);
+}
+
+
+
+
+//----- (00421626) --------------------------------------------------------
+GUIWindow *CharacterUI_Initialize(unsigned int _this)
+{
+  GUIWindow *pWindow; // edi@3
+
+  ++pIcons_LOD->uTexturePacksCount;
+  if ( !pIcons_LOD->uNumPrevLoadedFiles )
+    pIcons_LOD->uNumPrevLoadedFiles = pIcons_LOD->uNumLoadedFiles;
+
+  pEventTimer->Pause();
+  pAudioPlayer->StopChannels(-1, -1);
+  bRingsShownInCharScreen = false;
+  CharacterUI_LoadPaperdollTextures();
+  pCurrentScreen = _this;
+
+  pWindow = GUIWindow::Create(0, 0, 640, 480, WINDOW_CharacterRecord, uActiveCharacter, 0);
+  pCharacterScreen_StatsBtn = pWindow->CreateButton(pViewport->uViewportTL_X + 12, pViewport->uViewportTL_Y + 308,
+                                pIcons_LOD->GetTexture(papredoll_dbrds[9])->uTextureWidth,
+                                pIcons_LOD->GetTexture(papredoll_dbrds[9])->uTextureHeight,
+                                1, 0, UIMSG_ClickStatsBtn, 0, 'S', pGlobalTXT_LocalizationStrings[216],// Stats
+                                pIcons_LOD->GetTexture(papredoll_dbrds[10]),
+                                pIcons_LOD->GetTexture(papredoll_dbrds[9]), 0);
+  pCharacterScreen_SkillsBtn = pWindow->CreateButton(pViewport->uViewportTL_X + 102, pViewport->uViewportTL_Y + 308,
+                                 pIcons_LOD->GetTexture(papredoll_dbrds[7])->uTextureWidth,
+                                 pIcons_LOD->GetTexture(papredoll_dbrds[7])->uTextureHeight,
+                                 1, 0, UIMSG_ClickSkillsBtn, 0, 'K', pGlobalTXT_LocalizationStrings[205],//Skills
+                                 pIcons_LOD->GetTexture(papredoll_dbrds[8]),
+                                 pIcons_LOD->GetTexture(papredoll_dbrds[7]), 0);
+  pCharacterScreen_InventoryBtn = pWindow->CreateButton(pViewport->uViewportTL_X + 192, pViewport->uViewportTL_Y + 308,
+                                    pIcons_LOD->GetTexture(papredoll_dbrds[5])->uTextureWidth,
+                                    pIcons_LOD->GetTexture(papredoll_dbrds[5])->uTextureHeight,
+                                    1, 0, UIMSG_ClickInventoryBtn, 0, 'I', pGlobalTXT_LocalizationStrings[120], //Inventory
+                                    pIcons_LOD->GetTexture(papredoll_dbrds[6]),
+                                    pIcons_LOD->GetTexture(papredoll_dbrds[5]), 0);
+  pCharacterScreen_AwardsBtn = pWindow->CreateButton(pViewport->uViewportTL_X + 282, pViewport->uViewportTL_Y + 308,
+                                 pIcons_LOD->GetTexture(papredoll_dbrds[3])->uTextureWidth,
+                                 pIcons_LOD->GetTexture(papredoll_dbrds[3])->uTextureHeight,
+                                 1, 0, UIMSG_ClickAwardsBtn, 0, 'A', pGlobalTXT_LocalizationStrings[22], //Awards
+                                 pIcons_LOD->GetTexture(papredoll_dbrds[4]),
+                                 pIcons_LOD->GetTexture(papredoll_dbrds[3]), 0);
+  pCharacterScreen_ExitBtn = pWindow->CreateButton(pViewport->uViewportTL_X + 371, pViewport->uViewportTL_Y + 308,
+                 pIcons_LOD->GetTexture(papredoll_dbrds[1])->uTextureWidth,
+                 pIcons_LOD->GetTexture(papredoll_dbrds[1])->uTextureHeight,
+                 1, 0, UIMSG_ClickExitCharacterWindowBtn, 0, 0, pGlobalTXT_LocalizationStrings[79],//Exit
+                 pIcons_LOD->GetTexture(papredoll_dbrds[2]),
+                 pIcons_LOD->GetTexture(papredoll_dbrds[1]), 0);
+  pWindow->CreateButton(0, 0, 0x1DCu, 0x159u, 1, 122, UIMSG_InventoryLeftClick, 0, 0, "", 0);
+  pCharacterScreen_DetalizBtn = pWindow->CreateButton(0x258u, 0x12Cu, 30, 30, 1, 0, UIMSG_ChangeDetaliz, 0, 0, pGlobalTXT_LocalizationStrings[64], 0);
+  pCharacterScreen_DollBtn = pWindow->CreateButton(0x1DCu, 0, 0xA4u, 0x159u, 1, 0, UIMSG_ClickPaperdoll, 0, 0, "", 0);
+
+  pWindow->CreateButton( 61, 424, 31, 0, 2, 94, UIMSG_SelectCharacter, 1, '1', "", 0);
+  pWindow->CreateButton(177, 424, 31, 0, 2, 94, UIMSG_SelectCharacter, 2, '2', "", 0);
+  pWindow->CreateButton(292, 424, 31, 0, 2, 94, UIMSG_SelectCharacter, 3, '3', "", 0);
+  pWindow->CreateButton(407, 424, 31, 0, 2, 94, UIMSG_SelectCharacter, 4, '4', "", 0);
+
+  pWindow->CreateButton(0, 0, 0, 0, 1, 0, UIMSG_CycleCharacters, 0, '\t', "", 0);
+  FillAwardsData();
+  return pWindow;
+}
+
+//----- (004219BE) --------------------------------------------------------
+GUIWindow *CastSpellInfo::sub_4219BE()
+{
+  GUIWindow *v2; // ebx@1
+
+  pEventTimer->Pause();
+  pAudioPlayer->StopChannels(-1, -1);
+  bRingsShownInCharScreen = 0;
+  CharacterUI_LoadPaperdollTextures();
+  pCurrentScreen = SCREEN_CASTING;
+  v2 = GUIWindow::Create(0, 0, 640, 480, WINDOW_CastSpell_InInventory, (int)this, 0);
+  pCharacterScreen_ExitBtn = v2->CreateButton(394, 318, 75, 33, 1, 0, UIMSG_ClickExitCharacterWindowBtn, 0, 0,
+                 pGlobalTXT_LocalizationStrings[79], // Close
+                 pIcons_LOD->GetTexture(papredoll_dbrds[2]),
+                 pIcons_LOD->GetTexture(papredoll_dbrds[1]), 0);
+  v2->CreateButton(0, 0, 0x1DCu, 0x159u, 1, 122, UIMSG_InventoryLeftClick, 0, 0, "", 0);
+  pCharacterScreen_DollBtn = v2->CreateButton(0x1DCu, 0, 0xA4u, 0x159u, 1, 0, UIMSG_ClickPaperdoll, 0, 0, "", 0);
+
+  v2->CreateButton( 61, 424, 31, 0, 2, 94, UIMSG_SelectCharacter, 1, '1', "", 0);
+  v2->CreateButton(177, 424, 31, 0, 2, 94, UIMSG_SelectCharacter, 2, '2', "", 0);
+  v2->CreateButton(292, 424, 31, 0, 2, 94, UIMSG_SelectCharacter, 3, '3', "", 0);
+  v2->CreateButton(407, 424, 31, 0, 2, 94, UIMSG_SelectCharacter, 4, '4', "", 0);
+
+  return v2;
+}
+
+
+
+
+
+
+static int CharacterUI_SkillsTab_Draw__DrawSkillTable(Player *player, int x, int y, const int *skill_list, int skill_list_size, int right_margin, const char *skill_group_name)
+{
+  int y_offset = y;
+  
+  sprintf(pTmpBuf.data(), "%s\r%03d%s", skill_group_name, right_margin, pGlobalTXT_LocalizationStrings[131]); //"Level"
+  pGUIWindow_CurrentMenu->DrawText(pFontArrus, x, y, ui_character_header_text_color, pTmpBuf.data(), 0, 0, 0);
+
+  int num_skills_drawn = 0;
+  for (uint i = 0; i < skill_list_size; ++i)
+  {
+    auto skill = (PLAYER_SKILL_TYPE)skill_list[i];
+    for (uint j = 0; j < pGUIWindow_CurrentMenu->uNumControls; ++j)
+    {
+      auto v8 = pGUIWindow_CurrentMenu->pControlsHead;
+
+      for (int v7 = j; v7 > 0; --v7)
+        v8 = v8->pNext;
+
+      auto v9 = v8->field_1C;
+      if ((short)(v8->field_1C) >= 0)
+        continue;
+      if ( (v9 & 0x7FFF) != skill )
+        continue;
+
+      ++num_skills_drawn;
+      y_offset = v8->uY;
+
+      auto skill_value = player->pActiveSkills[skill];
+      auto skill_level = skill_value & 0x3F;
+
+      uint skill_color = 0;
+      uint skill_mastery_color = 0;
+      if (player->uSkillPoints > skill_level)
+        skill_color = ui_character_skill_upgradeable_color;
+
+      if (pGUIWindow_CurrentMenu->pCurrentPosActiveItem == j)
+      {
+        if (player->uSkillPoints > skill_level)
+          skill_mastery_color = ui_character_bonus_text_color;
+        else
+          skill_mastery_color = ui_character_skill_default_color;
+        skill_color = skill_mastery_color;
+      }
+
+      if (SkillToMastery(skill_value) == 1)
+      {
+        sprintfex(pTmpBuf.data(), "%s\r%03d%2d", pSkillNames[skill], right_margin, skill_level);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, x, v8->uY, skill_color, pTmpBuf.data(), 0, 0, 0);
+      }
+      else
+      {
+        const char *skill_level_str = nullptr;
+
+        switch (SkillToMastery(skill_value))
+        {
+          case 4: skill_level_str = pGlobalTXT_LocalizationStrings[96];  break; // "Grand"
+          case 3: skill_level_str = pGlobalTXT_LocalizationStrings[432]; break; // Master
+          case 2: skill_level_str = pGlobalTXT_LocalizationStrings[433]; break; // Expert
+        }
+
+        if (!skill_mastery_color)
+          skill_mastery_color = ui_character_header_text_color;
+
+        sprintfex(pTmpBuf.data(), "%s \f%05d%s\f%05d\r%03d%2d", pSkillNames[skill], skill_mastery_color, skill_level_str, skill_color, right_margin, skill_level);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, x, v8->uY, skill_color, pTmpBuf.data(), 0, 0, 0);
+      }
+    }
+  }
+
+  if (!num_skills_drawn)
+  {
+    y_offset += LOBYTE(pFontLucida->uFontHeight) - 3;
+    pGUIWindow_CurrentMenu->DrawText(pFontLucida, x, y_offset, 0, pGlobalTXT_LocalizationStrings[153], 0, 0, 0); //"None"
+  }
+
+  return y_offset;
+}
+
+
+
+//----- (00419719) --------------------------------------------------------
+void CharacterUI_SkillsTab_Draw(Player *player)
+{
+  pRenderer->DrawTextureIndexed(8, 8, pIcons_LOD->LoadTexturePtr("fr_skill", TEXTURE_16BIT_PALETTE));
+
+  sprintfex(pTmpBuf.data(), "%s \f%05d^Pv[%s]\f00000\r177%s: \f%05d%d\f00000",
+            pGlobalTXT_LocalizationStrings[206],        // Skills for
+            ui_character_header_text_color,
+            player->pName,
+            pGlobalTXT_LocalizationStrings[207],        // Skill Points
+            player->uSkillPoints ? ui_character_bonus_text_color : ui_character_default_text_color,
+            player->uSkillPoints);
+  pGUIWindow_CurrentMenu->DrawText(pFontArrus, 24, 18, 0, pTmpBuf.data(), 0, 0, 0);
+
+  int y = 2 * LOBYTE(pFontLucida->uFontHeight) + 13;
+  y = CharacterUI_SkillsTab_Draw__DrawSkillTable(player, 24, y, pWeaponSkills, 9, 400, pGlobalTXT_LocalizationStrings[242]); // "Weapons"
+
+  y += 2 * LOBYTE(pFontLucida->uFontHeight) - 10;
+  CharacterUI_SkillsTab_Draw__DrawSkillTable(player, 24, y, pMagicSkills, 9, 400, pGlobalTXT_LocalizationStrings[138]); // "Magic"
+
+  y = 2 * LOBYTE(pFontLucida->uFontHeight) + 13;
+  y = CharacterUI_SkillsTab_Draw__DrawSkillTable(player, 248, y, pArmorSkills, 5, 177, pGlobalTXT_LocalizationStrings[11]); // "Armor"
+ 
+  y += 2 * LOBYTE(pFontLucida->uFontHeight) - 10;
+  y = CharacterUI_SkillsTab_Draw__DrawSkillTable(player, 248, y, pMiscSkills, 12, 177, pGlobalTXT_LocalizationStrings[143]); //"Misc"
+}
+
+
+
+
+
+
+
+
+
+
+//----- (0041A000) --------------------------------------------------------
+void CharacterUI_AwardsTab_Draw(Player *player)
+{
+    //unsigned int v1; // esi@1
+    //unsigned int v2; // ebx@1
+    //unsigned int award_texture_id; // eax@1
+    unsigned int result; // eax@1
+    int v5; // eax@15
+    char *v6; // ebx@15
+    int v7; // eax@23
+    int v8; // eax@24
+    int v9; // eax@25
+    //int v10; // eax@27
+    int v11; // eax@32
+    int v12; // eax@33
+    int v13; // eax@34
+    //signed int v14; // eax@43
+    //unsigned int v15; // eax@43
+    //int v16; // eax@43
+    //int v17; // [sp-4h] [bp-D4h]@16
+    char Source[100]; // [sp+Ch] [bp-C4h]@1
+    GUIWindow a1; // [sp+70h] [bp-60h]@1
+    //unsigned int v20; // [sp+C4h] [bp-Ch]@15
+    //int v21; // [sp+C8h] [bp-8h]@14
+    //int v22; // [sp+CCh] [bp-4h]@40
+
+  pRenderer->DrawTextureIndexed(8, 8, pIcons_LOD->LoadTexturePtr("fr_award", TEXTURE_16BIT_PALETTE));
+  sprintfex(pTmpBuf.data(), "%s \f%05d", pGlobalTXT_LocalizationStrings[LOCSTR_AVARDS_FOR], ui_character_header_text_color);
+  sprintfex(Source, pGlobalTXT_LocalizationStrings[LOCSTR_S_THE_S], player->pName, pClassNames[player->classType]);
+  strcat(pTmpBuf.data(), Source);
+  strcat(pTmpBuf.data(), "\f00000");
+
+  pGUIWindow_CurrentMenu->DrawText(pFontArrus, 24, 18, 0, pTmpBuf.data(), 0, 0, 0);
+  result = dword_506528;
+  a1.uFrameX = 12;
+  a1.uFrameY = 48;
+  a1.uFrameWidth = 424;
+  a1.uFrameHeight = 290;
+  a1.uFrameZ = 435;
+  a1.uFrameW = 337;
+  if (BtnDown_flag && num_achieved_awards + dword_506528 < num_achieved_awards_2)
+    result = dword_506528++ + 1;
+  if (BtnUp_flag && result)
+  {
+    --result;
+    dword_506528 = result;
+  }
+
+    if ( dword_50651C < 0 )
+        {
+        result += num_achieved_awards;
+        dword_506528 = result;
+        if ( (signed int)(num_achieved_awards + result) > num_achieved_awards_2 )
+            {
+            result = num_achieved_awards_2 - num_achieved_awards;
+            dword_506528 = result;
+            }
+        }
+    else if ( dword_50651C > 0 )
+        {
+        result -= num_achieved_awards;
+        dword_506528 = result;
+        if ( (result & 0x80000000u) != 0 )
+            {
+            result = 0;
+            dword_506528 = result;
+            }
+        }
+    //LABEL_14:
+    BtnDown_flag = 0;
+    BtnUp_flag = 0;
+    num_achieved_awards = 0;
+    dword_50651C = 0;
+
+
+    for (uint i = result; i < num_achieved_awards_2; ++i)
+    {
+      v5 = achieved_awards[i];
+      v6 = (char *)pAwards[v5].pText;//(char *)dword_723E80_award_related[v20 / 4];
+
+            pTmpBuf[0] = 0;
+            switch (v5)
+            {
+              case Award_Arena_PageWins:    sprintf(pTmpBuf.data(), v6, pParty->uNumArenaPageWins);     break;
+              case Award_Arena_SquireWins:  sprintf(pTmpBuf.data(), v6, pParty->uNumArenaSquireWins);   break;
+              case Award_Arena_KnightWins:  sprintf(pTmpBuf.data(), v6, pParty->uNumArenaKnightWins);   break;
+              case Award_Arena_LordWins:    sprintf(pTmpBuf.data(), v6, pParty->uNumArenaLordWins);     break;
+              case Award_ArcomageWins:      sprintf(pTmpBuf.data(), v6, pParty->uNumArcomageWins);      break;
+              case Award_ArcomageLoses:     sprintf(pTmpBuf.data(), v6, pParty->uNumArcomageLoses);     break;
+              case Award_Deaths:            sprintf(pTmpBuf.data(), v6, pParty->uNumDeaths);            break;
+              case Award_BountiesCollected: sprintf(pTmpBuf.data(), v6, pParty->uNumBountiesCollected); break;
+              case Award_Fine:              sprintf(pTmpBuf.data(), v6, pParty->uFine);                 break;
+              case Award_PrisonTerms:       sprintf(pTmpBuf.data(), v6, pParty->uNumPrisonTerms);       break;
+            }
+
+            if (*pTmpBuf.data())
+              v6 = pTmpBuf.data();
+
+
+            a1.DrawText(pFontArrus, 0, 0, ui_character_award_color[pAwards[v5].uPriority % 6], v6, 0, 0, 0);
+            a1.uFrameY = pFontArrus->CalcTextHeight(v6, &a1, 0, 0) + a1.uFrameY + 4;
+            if (a1.uFrameY > a1.uFrameHeight)
+              break;
+
+            ++num_achieved_awards;
+        }
+ }
+
+
+
+
+
+
+//----- (0041A2C1) --------------------------------------------------------
+unsigned int __fastcall GetSizeInInventorySlots(unsigned int uNumPixels)
+{
+  if ( (signed int)uNumPixels < 14 )
+    uNumPixels = 14;
+  return ((signed int)(uNumPixels - 14) >> 5) + 1;
+}
+
+
+
+//----- (0041A556) --------------------------------------------------------
+void draw_leather()
+{
+  pRenderer->DrawTextureIndexed(8, 8, pIcons_LOD->GetTexture(uTextureID_Leather));
+}
+
+
+//----- (0041ABFD) --------------------------------------------------------
+void CharacterUI_CharacterScreen_Draw(Player *player)
+{
+  pRenderer->ClearZBuffer(0, 479);
+  switch (pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0])
+  {
+    case WINDOW_CharacterWindow_Stats:                                // stats
+      CharacterUI_ReleaseButtons();
+      sub_419379();
+      CharacterUI_StatsTab_Draw(player);
+      pRenderer->DrawTextureIndexed(pCharacterScreen_StatsBtn->uX,
+                                    pCharacterScreen_StatsBtn->uY,
+                                    pIcons_LOD->LoadTexturePtr("ib-cd1-d", TEXTURE_16BIT_PALETTE));
+    break;
+
+    case WINDOW_CharacterWindow_Skills:                                // skills
+      if (dword_507CC0_activ_ch != uActiveCharacter)
+      {
+        CharacterUI_ReleaseButtons();
+        CharacterUI_SkillsTab_CreateButtons();
+      }
+      sub_419379();
+      CharacterUI_SkillsTab_Draw(player);
+      pRenderer->DrawTextureIndexed(pCharacterScreen_SkillsBtn->uX,
+                                    pCharacterScreen_SkillsBtn->uY,
+                                    pIcons_LOD->LoadTexturePtr("ib-cd2-d", TEXTURE_16BIT_PALETTE));
+    break;
+
+    case WINDOW_CharacterWindow_Awards:                                // awards
+      CharacterUI_ReleaseButtons();
+      sub_419379();
+      sub_419220();
+      CharacterUI_AwardsTab_Draw(player);
+      pRenderer->DrawTextureIndexed(pCharacterScreen_AwardsBtn->uX,
+                                    pCharacterScreen_AwardsBtn->uY,
+                                    pIcons_LOD->LoadTexturePtr("ib-cd4-d", TEXTURE_16BIT_PALETTE));
+    break;
+
+    case WINDOW_CharacterWindow_Inventory:                             // inventory and other
+      CharacterUI_ReleaseButtons();
+      sub_419379();
+      CharacterUI_InventoryTab_Draw(player, false);
+      pRenderer->DrawTextureIndexed(pCharacterScreen_InventoryBtn->uX,
+                                    pCharacterScreen_InventoryBtn->uY,
+                                    pIcons_LOD->LoadTexturePtr("ib-cd3-d", TEXTURE_16BIT_PALETTE));
+    break;
+
+    default: break;
+  }
+
+  if (bRingsShownInCharScreen)
+    CharacterUI_DrawPaperdollWithRingOverlay(player);
+  else
+    CharacterUI_DrawPaperdoll(player);
+}
+
+//----- (0043CC7C) --------------------------------------------------------
+void CharacterUI_DrawPaperdoll(Player *player)
+{
+  //signed int pSex; // eax@1
+  unsigned int v6; // ecx@9
+  int v7; // ecx@10
+  unsigned int pMainHandNum4; // eax@14
+  ItemGen *item_MainHand4; // eax@15
+  int v10; // edx@15
+  unsigned int pX_MainHand4; // edi@15
+  unsigned int v14; // ebx@18
+  Texture *v16; // ebp@27
+  double v17; // st7@29
+  int v18; // edi@30
+  char *v19; // eax@30
+  unsigned int pBowNum; // eax@37
+  ItemGen *itemBow; // edi@38
+  int pX_Bow; // ebx@38
+  double v28; // st7@51
+  char *v30; // eax@54
+  unsigned int pCloakNum; // eax@59
+  ItemGen *item_Cloak; // edx@60
+  int v33; // eax@65
+  int v34; // eax@74
+  int v35; // ebx@74
+  LODFile_IconsBitmaps *v38; // ecx@78
+  Texture *v39; // edi@85
+  double v40; // st7@87
+  int v41; // edi@88
+  unsigned int pArmorNum; // eax@93
+  ItemGen *item_Armor; // edx@94
+  int v45; // eax@98
+  int v48; // ebx@106
+  LODFile_IconsBitmaps *v50; // ecx@110
+  Texture *v51; // edi@117
+  double v52; // st7@119
+  int v53; // edi@120
+  char *v55; // eax@122
+  unsigned int pBootNum; // eax@127
+  ItemGen *item_Boot; // edi@128
+  int v59; // ebx@129
+  int v60; // ecx@132
+  Texture *v63; // edi@145
+  double v64; // st7@147
+  int v65; // edi@148
+  char *v66; // eax@148
+  unsigned int pMainHandNum; // edx@155
+  int v70; // edx@156
+  unsigned int pBeltNum; // eax@160
+  ItemGen *item_Belt; // edi@161
+  int v73; // edx@163
+  unsigned int v75; // ebx@170
+  Texture *v77; // edi@181
+  double v78; // st7@183
+  int v79; // edi@184
+  char *v80; // eax@184
+  unsigned int pMainHandNum2; // eax@192
+  int v83; // eax@193
+  int pArmorShoulderNum; // eax@197
+  int v87; // eax@197
+  int v88; // eax@198
+  int v89; // eax@199
+  int v94; // ebx@214
+  int v95; // eax@214
+  char *v96; // edi@226
+  double v97; // st7@228
+  int v98; // edi@229
+  char *v99; // eax@229
+  int pX_ArmorShoulder; // eax@237
+  int pY_ArmorShoulder; // ecx@237
+  int v106; // edx@238
+  int v107; // edx@239
+  int v108; // edx@240papredoll_flying_feet
+  int v109; // edi@250
+  char *v110; // edx@250
+  unsigned int pCloakCollarNum; // eax@259
+  ItemGen *item_CloakCollar; // eax@260
+  int v114; // eax@265
+  int v116; // ebx@274
+        double v118; // st7@286
+        int v119; // edi@287
+        char *v120; // eax@287
+        unsigned int v122; // edi@295
+        int pHelmNum; // ebx@297
+        ItemGen *item_Helm; // edi@298
+        int v125; // ecx@303
+        unsigned int v127; // ebx@314
+        Texture *v129; // edi@325
+        double v130; // st7@327
+        int v131; // edi@328
+        char *v132; // eax@328
+        unsigned int pMainHandNum3; // eax@335
+        ItemGen *item_MainHand3; // eax@336
+        unsigned int v138; // ebx@339
+        Texture *v140; // edi@348
+        double v141; // st7@350
+        int v142; // edi@351
+        char *v143; // eax@351
+        unsigned int pShieldNum; // eax@358
+        ItemGen *item_Shield; // eax@359
+        int v149; // edx@359
+        int pX_Shield; // ebx@362
+        int v151; // ecx@363
+        int v152; // ecx@364
+        unsigned int v153; // eax@370
+        Texture *v157; // ebp@381
+        double v158; // st7@383
+        char *v160; // eax@386
+        unsigned int pMainHandNum5; // eax@393
+        ItemGen *item_MainHand5; // eax@394
+        char *v166; // [sp-8h] [bp-54h]@16
+        const char *v167; // [sp-8h] [bp-54h]@23
+        const char *v168; // [sp-8h] [bp-54h]@43
+        const char *v169; // [sp-8h] [bp-54h]@79
+        const char *v170; // [sp-8h] [bp-54h]@111
+        const char *v171; // [sp-8h] [bp-54h]@141
+        const char *v172; // [sp-8h] [bp-54h]@177
+        const char *v173; // [sp-8h] [bp-54h]@222
+        const char *v178; // [sp-8h] [bp-54h]@242
+        const char *v179; // [sp-8h] [bp-54h]@280
+        const char *v180; // [sp-8h] [bp-54h]@321
+        char *v181; // [sp-8h] [bp-54h]@337
+        const char *v182; // [sp-8h] [bp-54h]@344
+        const char *v183; // [sp-8h] [bp-54h]@375
+        signed int v186; // [sp-4h] [bp-50h]@202
+        signed int v191; // [sp-4h] [bp-50h]@266
+        signed int v192; // [sp-4h] [bp-50h]@304
+        int pY_MainHand4; // [sp+10h] [bp-3Ch]@15
+        int pY_Bow; // [sp+10h] [bp-3Ch]@38
+        unsigned int pY_Cloak; // [sp+10h] [bp-3Ch]@74
+        unsigned int pY_Armor; // [sp+10h] [bp-3Ch]@106
+        int pY_Boot; // [sp+10h] [bp-3Ch]@129
+        int pY_Belt; // [sp+10h] [bp-3Ch]@168
+        unsigned int pY_shoulder; // [sp+10h] [bp-3Ch]@216
+        unsigned int pY_CloakCollar; // [sp+10h] [bp-3Ch]@274
+        int pY_Helm; // [sp+10h] [bp-3Ch]@312
+        int pY_MainHand3; // [sp+10h] [bp-3Ch]@336
+        int pY_Shield; // [sp+10h] [bp-3Ch]@362
+        Texture *a2b; // [sp+14h] [bp-38h]@49
+        int pX_Cloak; // [sp+14h] [bp-38h]@74
+        int pX_Armor; // [sp+14h] [bp-38h]@106
+        int pX_Boot; // [sp+14h] [bp-38h]@129
+        int pX_Belt; // [sp+14h] [bp-38h]@168
+        int pX_shoulder; // [sp+14h] [bp-38h]@214
+        int pX_CloakCollar; // [sp+14h] [bp-38h]@274
+        Texture *a2i; // [sp+14h] [bp-38h]@284
+        int pX_Helm; // [sp+14h] [bp-38h]@312
+        int pX_MainHand3; // [sp+14h] [bp-38h]@336
+        int pBodyComplection; // [sp+24h] [bp-28h]@6
+        unsigned int pBowTextureNum; // [sp+2Ch] [bp-20h]@38
+        signed int v245; // [sp+34h] [bp-18h]@361
+        signed int IsDwarf; // [sp+40h] [bp-Ch]@4
+
+  pIcons_LOD->LoadTexture("sptext01", TEXTURE_16BIT_PALETTE);
+  if (player->GetRace() == CHARACTER_RACE_DWARF)
+  {
+    IsDwarf = 1;
+    pBodyComplection = player->GetSexByVoice() == SEX_MALE ? 2 : 3;
+  }
+  else
+  {
+    IsDwarf = 0;
+    pBodyComplection = player->GetSexByVoice() == SEX_MALE ? 0 : 1;
+  }
+
+  int uPlayerID = 0;
+  for (uint i = 0; i < 4; ++i)
+    if (pPlayers[i + 1] == player)
+    {
+      uPlayerID = i + 1;
+      break;
+    }
+
+  pRenderer->ResetTextureClipRect();
+  pRenderer->DrawTextureIndexed(467, 0, pIcons_LOD->GetTexture(uTextureID_BACKDOLL));//
+  if ( IsPlayerWearingWatersuit[uPlayerID] )//
+  {
+    pRenderer->DrawTextureTransparent(pPaperdoll_BodyX, pPaperdoll_BodyY, pIcons_LOD->GetTexture(papredoll_dbods[uPlayerID - 1]));
+    if ( !bRingsShownInCharScreen )
+      pRenderer->DrawMaskToZBuffer(pPaperdoll_BodyX, pPaperdoll_BodyY, pIcons_LOD->GetTexture(papredoll_dbods[uPlayerID - 1]), player->pEquipment.uArmor);
+    v6 = player->pEquipment.uMainHand;
+    if ( !v6 || (v7 = *(int *)&pPlayers[uPlayerID]->pInventoryItems[v6-1], pItemsTable->pItems[v7].uEquipType != 1)
+         && (pItemsTable->pItems[v7].uSkillType != 4 || pPlayers[uPlayerID]->pEquipment.uShield) )
+         pRenderer->DrawTextureTransparent(pPaperdoll_BodyX + pPaperdoll_LeftHand[pBodyComplection][0], pPaperdoll_BodyY + pPaperdoll_LeftHand[pBodyComplection][1],
+         pIcons_LOD->GetTexture(papredoll_dlads[uPlayerID - 1]));
+    pMainHandNum4 = pPlayers[uPlayerID]->pEquipment.uMainHand;
+    if ( pMainHandNum4 )
+    {
+      item_MainHand4 = &pPlayers[uPlayerID]->pInventoryItems[pMainHandNum4 - 1];
+      pX_MainHand4 = pPaperdoll_BodyX + paperdoll_Weapon[pBodyComplection][1][0] - pItemsTable->pItems[item_MainHand4->uItemID].uEquipX;
+      pY_MainHand4 = pPaperdoll_BodyY + paperdoll_Weapon[pBodyComplection][1][1] - pItemsTable->pItems[item_MainHand4->uItemID].uEquipY;
+      if ( item_MainHand4->uItemID == 64 )  //blaster
+        v166 = "item64v1";
+      else
+        v166 = pItemsTable->pItems[item_MainHand4->uItemID].pIconName;
+      v14 = pIcons_LOD->LoadTexture(v166, TEXTURE_16BIT_PALETTE);
+      if ( !( item_MainHand4->uAttributes & 0xF0 ) )
+      {
+        v18 = v14 + 1;
+        v19 = (char *)pIcons_LOD->GetTexture(v14);
+        if ( item_MainHand4->uAttributes & 2 )
+          pRenderer->DrawTransparentRedShade(pX_MainHand4, pY_MainHand4, (Texture *)v19);
+        else
+        {
+          if ( item_MainHand4->uAttributes & 1 )
+            pRenderer->DrawTextureTransparent(pX_MainHand4, pY_MainHand4, (Texture *)v19);
+          else
+            pRenderer->DrawTransparentGreenShade(pX_MainHand4, pY_MainHand4, (Texture *)v19);
+        }
+      }
+      if ( item_MainHand4->uAttributes & 0xF0 )
+      {
+        if ( ( item_MainHand4->uAttributes & 0xF0) == 16 )
+          v167 = "sptext01";
+        if ( ( item_MainHand4->uAttributes & 0xF0) == 32 )
+          v167 = "sp28a";
+        if ( (item_MainHand4->uAttributes & 0xF0) == 64 )
+          v167 = "sp30a";
+        if ( (item_MainHand4->uAttributes & 0xF0) == 128 )
+          v167 = "sp91a";
+        v16 = pIcons_LOD->LoadTexturePtr(v167, TEXTURE_16BIT_PALETTE);
+        _50C9A8_item_enchantment_timer -= pEventTimer->uTimeElapsed;
+        if ( _50C9A8_item_enchantment_timer <= 0 )
+        {
+          _50C9A8_item_enchantment_timer = 0;
+          item_MainHand4->uAttributes &= 0xFFFFFF0Fu;
+          ptr_50C9A4 = 0;
+        }
+        v17 = (double)GetTickCount() * 0.1;
+        pRenderer->_4A63E6(pX_MainHand4, pY_MainHand4, pIcons_LOD->GetTexture(v14), v16, (signed __int64)v17, 0, 255);
+      }
+      if ( !bRingsShownInCharScreen )
+        pRenderer->DrawMaskToZBuffer(pX_MainHand4, pY_MainHand4, (Texture *)v19, pMainHandNum4);
+    }
+  }
+  else//  
+  {
+    pBowNum = pPlayers[uPlayerID]->pEquipment.uBow; //  
+    if ( pBowNum )
+    {
+      itemBow = &pPlayers[uPlayerID]->pInventoryItems[pBowNum - 1];
+      pX_Bow = pPaperdoll_BodyX + paperdoll_Weapon[pBodyComplection][2][0] - pItemsTable->pItems[itemBow->uItemID].uEquipX;
+      pY_Bow = pPaperdoll_BodyY + paperdoll_Weapon[pBodyComplection][2][1] - pItemsTable->pItems[itemBow->uItemID].uEquipY;
+      pBowTextureNum = pIcons_LOD->LoadTexture(pItemsTable->pItems[itemBow->uItemID].pIconName, TEXTURE_16BIT_PALETTE);
+      if ( !(itemBow->uAttributes & 0xF0) )//    
+      {
+        if ( itemBow->uAttributes & 2 )
+          pRenderer->DrawTransparentRedShade(pX_Bow, pY_Bow, pIcons_LOD->GetTexture(pBowTextureNum));
+        else
+        {
+          v30 = (char *)pIcons_LOD->GetTexture(pBowTextureNum);
+          if ( !(itemBow->uAttributes & 1) )//   
+            pRenderer->DrawTransparentGreenShade(pX_Bow, pY_Bow, (Texture *)v30);
+          else //  
+            pRenderer->DrawTextureTransparent(pX_Bow, pY_Bow, (Texture *)v30);
+        }
+      }
+      else
+      {
+        if ( (itemBow->uAttributes & 0xF0) == 16 )
+          v168 = "sptext01";
+        if ( (itemBow->uAttributes & 0xF0) == 32 )
+          v168 = "sp28a";
+        if ( (itemBow->uAttributes & 0xF0) == 64 )
+          v168 = "sp30a";
+        if ( (itemBow->uAttributes & 0xF0) == 128 )
+          v168 = "sp91a";
+        a2b = pIcons_LOD->LoadTexturePtr(v168, TEXTURE_16BIT_PALETTE);
+        _50C9A8_item_enchantment_timer -= pEventTimer->uTimeElapsed;
+        if ( _50C9A8_item_enchantment_timer <= 0 )
+        {
+          _50C9A8_item_enchantment_timer = 0;
+          itemBow->uAttributes &= 0xFFFFFF0Fu;
+          ptr_50C9A4 = 0;
+        }
+        v28 = (double)GetTickCount() * 0.1;
+        pRenderer->_4A63E6(pX_Bow, pY_Bow, pIcons_LOD->GetTexture(pBowTextureNum), a2b, (signed __int64)v28, 0, 255);
+      }
+      if ( !bRingsShownInCharScreen )
+        pRenderer->DrawMaskToZBuffer(pX_Bow, pY_Bow, pIcons_LOD->GetTexture(pBowTextureNum), pBowNum);
+    }
+    pCloakNum = pPlayers[uPlayerID]->pEquipment.uCloak;//  
+    if ( pCloakNum )
+    {
+      item_Cloak = &pPlayers[uPlayerID]->pInventoryItems[pCloakNum - 1];
+      switch ( item_Cloak->uItemID )
+      {
+        case ITEM_RELIC_TWILIGHT:
+          v33 = 5;
+          break;
+        case ITEM_ARTIFACT_CLOAK_OF_THE_SHEEP:
+          v33 = 6;
+          break;
+        case ITEM_RARE_SUN_CLOAK:
+          v33 = 7;
+          break;
+        case ITEM_RARE_MOON_CLOAK:
+          v33 = 8;
+          break;
+        case ITEM_RARE_VAMPIRES_CAPE:
+          v33 = 9;
+          break;
+        default:
+          v33 = item_Cloak->uItemID - 105;
+          break;
+      }
+      if ( v33 >= 0 && v33 < 10 )
+      {
+        v35 = paperdoll_cloak_texture[pBodyComplection][v33];//Texture_Cloak
+        pX_Cloak = pPaperdoll_BodyX + paperdoll_Cloak[pBodyComplection][v33][0];
+        pY_Cloak = pPaperdoll_BodyY + paperdoll_Cloak[pBodyComplection][v33][1];
+        if ( !(item_Cloak->uAttributes & 0xF0) )
+        {
+          v41 = v35 + 1;
+          if ( item_Cloak->uAttributes & 2 )
+            pRenderer->DrawTransparentRedShade(pX_Cloak, pY_Cloak, pIcons_LOD->GetTexture(v35));
+          else
+            pRenderer->DrawTextureTransparent(pX_Cloak, pY_Cloak, pIcons_LOD->GetTexture(v35));
+        }
+        else
+        {
+          if ( (item_Cloak->uAttributes & 0xF0) == 16 )
+            v169 = "sptext01";
+          if ( (item_Cloak->uAttributes & 0xF0) == 32 )
+            v169 = "sp28a";
+          if ( (item_Cloak->uAttributes & 0xF0) != 64 )
+            v169 = "sp30a";
+          if ( (item_Cloak->uAttributes & 0xF0) == 128 )
+            v169 = "sp91a";
+          v39 = pIcons_LOD->LoadTexturePtr(v169, TEXTURE_16BIT_PALETTE);
+          _50C9A8_item_enchantment_timer -= pEventTimer->uTimeElapsed;
+          if ( _50C9A8_item_enchantment_timer <= 0 )
+          {
+            _50C9A8_item_enchantment_timer = 0;
+            item_Cloak->uAttributes &= 0xFFFFFF0Fu;
+            ptr_50C9A4 = 0;
+          }
+          v40 = (double)GetTickCount() * 0.1;
+          pRenderer->_4A63E6(pX_Cloak, pY_Cloak, pIcons_LOD->GetTexture(v35), v39, (signed __int64)v40, 0, 255);
+        }
+        if ( !bRingsShownInCharScreen )
+          pRenderer->DrawMaskToZBuffer(pX_Cloak, pY_Cloak, pIcons_LOD->GetTexture(v35), pCloakNum);
+      }
+    }
+    pRenderer->DrawTextureTransparent(pPaperdoll_BodyX, pPaperdoll_BodyY,// 
+            pIcons_LOD->GetTexture(papredoll_dbods[uPlayerID - 1]));
+    pArmorNum = pPlayers[uPlayerID]->pEquipment.uArmor;//  
+    if ( pArmorNum )
+    {
+      item_Armor = &pPlayers[uPlayerID]->pInventoryItems[pArmorNum - 1];
+      switch ( item_Armor->uItemID )
+      {
+        case 504:
+          v45 = 15;
+          break;
+        case ITEM_ARTIFACT_YORUBA:
+          v45 = 14;
+          break;
+        case ITEM_RELIC_HARECS_LEATHER:
+          v45 = 13;
+          break;
+        case ITEM_ELVEN_CHAINMAIL:
+          v45 = 16;
+          break;
+        default:
+          v45 = item_Armor->uItemID - 66;
+          break;
+      }
+      if ( v45 >= 0 && v45 < 17 )
+      {
+        pX_Armor = pPaperdoll_BodyX + paperdoll_Armor[pBodyComplection][v45][0];
+        pY_Armor = pPaperdoll_BodyY + paperdoll_Armor[pBodyComplection][v45][1];
+        v48 = paperdoll_armor_texture[pBodyComplection][v45][0];
+        if ( !(item_Armor->uAttributes & 0xF0) )
+        {
+          v53 = v48 + 1;
+          if ( item_Armor->uAttributes & 2 )
+            pRenderer->DrawTransparentRedShade(pX_Armor, pY_Armor, pIcons_LOD->GetTexture(v48));
+          else
+          {
+            v55 = (char *)&pIcons_LOD->pTextures[v48];
+            if ( !(item_Armor->uAttributes & 1) )
+              pRenderer->DrawTransparentGreenShade(pX_Armor, pY_Armor, (Texture *)v55);
+            else
+              pRenderer->DrawTextureTransparent(pX_Armor, pY_Armor, (Texture *)v55);
+          }
+        }
+        else
+        {
+          if ( (item_Armor->uAttributes & 0xF0) == 16 )
+            v170 = "sptext01";
+          if ( (item_Armor->uAttributes & 0xF0) == 32 )
+            v170 = "sp28a";
+          if ( (item_Armor->uAttributes & 0xF0) == 64 )
+            v170 = "sp30a";
+          if ( (item_Armor->uAttributes & 0xF0) == 128 )
+            v170 = "sp91a";
+          v51 = pIcons_LOD->LoadTexturePtr(v170, TEXTURE_16BIT_PALETTE);
+          _50C9A8_item_enchantment_timer -= pEventTimer->uTimeElapsed;
+          if ( _50C9A8_item_enchantment_timer <= 0 )
+          {
+            _50C9A8_item_enchantment_timer = 0;
+            item_Armor->uAttributes &= 0xFFFFFF0Fu;
+            ptr_50C9A4 = 0;
+          }
+          v52 = (double)GetTickCount() * 0.1;
+          pRenderer->_4A63E6(pX_Armor, pY_Armor, pIcons_LOD->GetTexture(v48), v51, (signed __int64)v52, 0, 255);
+        }
+        if ( pPlayers[uPlayerID]->pEquipment.uMainHand //  
+          && (pPlayers[uPlayerID]->GetEquippedItemEquipType(EQUIP_MAIN_HAND) == EQUIP_MAIN_HAND ||
+           pPlayers[uPlayerID]->GetEquippedItemSkillType(EQUIP_MAIN_HAND) == EQUIP_SHIELD &&
+          !pPlayers[uPlayerID]->pEquipment.uShield) )
+        {
+          v94 = paperdoll_armor_texture[pBodyComplection][v45][2];
+          if ( v94 == pIcons_LOD->FindTextureByName("pending") )
+          {
+            v94 = paperdoll_armor_texture[pBodyComplection][v45][1];
+            pX_shoulder = pPaperdoll_BodyX + paperdoll_shoulder[pBodyComplection][v45][0];
+            pY_shoulder = pPaperdoll_BodyY + paperdoll_shoulder[pBodyComplection][v45][1];
+          }
+          else
+          {
+            pX_shoulder = pPaperdoll_BodyX + dword_4E5270[v45][0];
+            pY_shoulder = pPaperdoll_BodyY + dword_4E5270[v45][1];
+          }
+          if ( !(item_Armor->uAttributes & 0xF0) )
+          {
+            v98 = v94 + 1;
+            v99 = (char *)pIcons_LOD->GetTexture(v94);
+            if ( item_Armor->uAttributes & 2 )
+              pRenderer->DrawTransparentRedShade(pX_shoulder, pY_shoulder, (Texture *)v99);
+            else
+            {
+              if ( item_Armor->uAttributes & 1 )
+                pRenderer->DrawTextureTransparent(pX_shoulder, pY_shoulder, (Texture *)v99);
+              else
+                pRenderer->DrawTransparentGreenShade(pX_shoulder, pY_shoulder, (Texture *)v99);
+            }
+          }
+          else
+          {
+            if ( v94 != pIcons_LOD->FindTextureByName("pending") )
+            {
+              if ( item_Armor->uAttributes & 0xF0 )
+              {
+                if ( (item_Armor->uAttributes & 0xF0) == ITEM_AURA_EFFECT_RED )
+                  v173 = "sptext01";
+                if ( (item_Armor->uAttributes & 0xF0) == ITEM_AURA_EFFECT_BLUE )
+                  v173 = "sp28a";
+                if ( ( item_Armor->uAttributes & 0xF0) == ITEM_AURA_EFFECT_GREEN )
+                  v173 = "sp30a";
+                if ( (item_Armor->uAttributes & 0xF0) == ITEM_AURA_EFFECT_PURPLE )
+                  v173 = "sp91a";
+                v96 = (char *)pIcons_LOD->LoadTexturePtr(v173, TEXTURE_16BIT_PALETTE);
+                _50C9A8_item_enchantment_timer -= pEventTimer->uTimeElapsed;
+                if ( _50C9A8_item_enchantment_timer <= 0 )
+                {
+                  _50C9A8_item_enchantment_timer = 0;
+                  item_Armor->uAttributes &= 0xFFFFFF0Fu;
+                  ptr_50C9A4 = 0;
+                }
+                v97 = (double)GetTickCount();
+                pRenderer->_4A63E6(pX_shoulder, pY_shoulder, pIcons_LOD->GetTexture(v94), (Texture *)v96, (signed __int64)(v97 * 0.1), 0, 255);
+              }
+            }
+          }
+        }
+        else
+        {
+          v94 = paperdoll_armor_texture[pBodyComplection][v45][1];
+          if ( v94 != pIcons_LOD->FindTextureByName("pending") )
+          {
+            pX_ArmorShoulder = pPaperdoll_BodyX + paperdoll_shoulder[pBodyComplection][v45][0];
+            pY_ArmorShoulder = pPaperdoll_BodyY + paperdoll_shoulder[pBodyComplection][v45][1];
+            if ( !(item_Armor->uAttributes & 0xF0) )
+            {
+              v109 = v94 + 1;
+              v110 = (char *)pIcons_LOD->GetTexture(v94);
+              if ( item_Armor->uAttributes & 2 )
+                pRenderer->DrawTransparentRedShade(pX_ArmorShoulder, pY_ArmorShoulder, (Texture *)v110);
+              else
+              {
+                if ( item_Armor->uAttributes & 1 )
+                  pRenderer->DrawTextureTransparent(pX_ArmorShoulder, pY_ArmorShoulder, (Texture *)v110);
+                else
+                  pRenderer->DrawTransparentGreenShade(pX_ArmorShoulder, pY_ArmorShoulder, (Texture *)v110);
+              }
+            }
+            else
+            {
+              if ( (item_Armor->uAttributes & 0xF0) == 16 )
+                v178 = "sptext01";
+              if ( (item_Armor->uAttributes & 0xF0) == 32 )
+                v178 = "sp28a";
+              if ( (item_Armor->uAttributes & 0xF0) == 64 )
+                v178 = "sp30a";
+              if ( (item_Armor->uAttributes & 0xF0) == 128 )
+                v178 = "sp91a";
+              v96 = (char *)pIcons_LOD->LoadTexturePtr(v178, TEXTURE_16BIT_PALETTE);
+              _50C9A8_item_enchantment_timer -= pEventTimer->uTimeElapsed;
+              if ( _50C9A8_item_enchantment_timer <= 0 )
+              {
+                _50C9A8_item_enchantment_timer = 0;
+                item_Armor->uAttributes &= 0xFFFFFF0Fu;
+                ptr_50C9A4 = 0;
+              }
+              v97 = (double)GetTickCount();
+              pRenderer->_4A63E6(pX_ArmorShoulder, pY_ArmorShoulder, pIcons_LOD->GetTexture(v94), (Texture *)v96, (signed __int64)(v97 * 0.1), 0, 255);
+            }
+          }
+        }
+        if ( !bRingsShownInCharScreen )
+          pRenderer->DrawMaskToZBuffer(pX_Armor, pY_Armor, (Texture *)v55, pArmorNum);
+      }
+    }
+    pBootNum = pPlayers[uPlayerID]->pEquipment.uBoot;// 
+    if ( pBootNum )
+    {
+      item_Boot = &pPlayers[uPlayerID]->pInventoryItems[pBootNum - 1];
+      switch ( item_Boot->uItemID )
+      {
+        case 529:
+          v60 = 5;
+          v59 = papredoll_flying_feet[pPlayers[uPlayerID]->uCurrentFace];
+          break;
+        case 512:
+          v60 = 6;
+          v59 = paperdoll_boots_texture[pBodyComplection][5];
+          break;
+        default:
+          v60 = item_Boot->uItemID - 115;
+          v59 = paperdoll_boots_texture[pBodyComplection][v60];
+          break;
+      }
+      if ( v60 >= 0 && v60 < 7 )
+      {
+        pX_Boot = pPaperdoll_BodyX + paperdoll_Boot[pBodyComplection][v60][0];
+        pY_Boot = pPaperdoll_BodyY + paperdoll_Boot[pBodyComplection][v60][1];
+        if ( !(item_Boot->uAttributes & 0xF0) )
+        {
+          v65 = v59 + 1;
+          v66 = (char *)pIcons_LOD->GetTexture(v59);
+          if ( item_Boot->uAttributes & 2 )
+            pRenderer->DrawTransparentRedShade(pX_Boot, pY_Boot, (Texture *)v66);
+          else
+          {
+            if ( item_Boot->uAttributes & 1 )
+              pRenderer->DrawTextureTransparent(pX_Boot, pY_Boot, (Texture *)v66);
+            else
+              pRenderer->DrawTransparentGreenShade(pX_Boot, pY_Boot, (Texture *)v66);
+          }
+        }
+        else
+        {
+          if ( (item_Boot->uAttributes & 0xF0) == 16 )
+            v171 = "sptext01";
+          if ( (item_Boot->uAttributes & 0xF0) == 32 )
+            v171 = "sp28a";
+          if ( (item_Boot->uAttributes & 0xF0) == 64 )
+            v171 = "sp30a";
+          if ( (item_Boot->uAttributes & 0xF0) == 128 )
+            v171 = "sp91a";
+          v63 = pIcons_LOD->LoadTexturePtr(v171, TEXTURE_16BIT_PALETTE);
+          _50C9A8_item_enchantment_timer -= pEventTimer->uTimeElapsed;
+          if ( _50C9A8_item_enchantment_timer <= 0 )
+          {
+            _50C9A8_item_enchantment_timer = 0;
+            item_Boot->uAttributes &= 0xFFFFFF0Fu;
+            ptr_50C9A4 = 0;
+          }
+          v64 = (double)GetTickCount() * 0.1;
+          pRenderer->_4A63E6(pX_Boot, pY_Boot, pIcons_LOD->GetTexture(v59), v63, (signed __int64)v64, 0, 255);
+        }
+        if ( !bRingsShownInCharScreen )
+          pRenderer->DrawMaskToZBuffer(pX_Boot, pY_Boot, (Texture *)v66, pBootNum);
+      }
+    }
+    pMainHandNum = pPlayers[uPlayerID]->pEquipment.uMainHand;
+    if ( !pMainHandNum || (v70 = *(int *)&pPlayers[uPlayerID]->pInventoryItems[pMainHandNum -1], pItemsTable->pItems[v70].uEquipType != 1)
+        && (pItemsTable->pItems[v70].uSkillType != 4 || pPlayers[uPlayerID]->pEquipment.uShield) )
+                pRenderer->DrawTextureTransparent(pPaperdoll_BodyX + pPaperdoll_LeftHand[pBodyComplection][0],
+                                                  pPaperdoll_BodyY + pPaperdoll_LeftHand[pBodyComplection][1],
+                                                   pIcons_LOD->GetTexture(papredoll_dlads[uPlayerID - 1]));
+        pBeltNum = pPlayers[uPlayerID]->pEquipment.uBelt;//  
+        if ( pBeltNum )
+        {
+          item_Belt = &pPlayers[uPlayerID]->pInventoryItems[pBeltNum - 1];
+        switch ( item_Belt->uItemID )
+        {
+          case ITEM_RILIC_TITANS_BELT:
+            v73 = 5;
+            break;
+          case ITEM_ARTIFACT_HEROS_BELT:
+            v73 = 6;
+            break;
+          default:
+            v73 = item_Belt->uItemID - 100;
+            break;
+        }
+        if ( v73 >= 0 && v73 < 7 )
+        {
+          pX_Belt = pPaperdoll_BodyX + paperdoll_Belt[pBodyComplection][v73][0];
+          pY_Belt = pPaperdoll_BodyY + paperdoll_Belt[pBodyComplection][v73][1];
+          if ( IsDwarf != 1 || v73 == 5 )
+            v75 = paperdoll_belt_texture[pBodyComplection][v73];
+          else
+           v75 = paperdoll_belt_texture[pBodyComplection - 2][v73];
+          if ( !(item_Belt->uAttributes & 0xF0) )
+          {
+            v79 = v75 + 1;
+            v80 = (char *)pIcons_LOD->GetTexture(v75);
+            if ( item_Belt->uAttributes & 2 )
+              pRenderer->DrawTransparentRedShade(pX_Belt, pY_Belt, (Texture *)v80);
+            else
+            {
+              if ( item_Belt->uAttributes & 1 )
+                pRenderer->DrawTextureTransparent(pX_Belt, pY_Belt, (Texture *)v80);
+              else
+                pRenderer->DrawTransparentGreenShade(pX_Belt, pY_Belt, (Texture *)v80);
+            }
+            if ( !bRingsShownInCharScreen )
+              pRenderer->DrawMaskToZBuffer(pX_Belt, pY_Belt, (Texture *)v80, pBeltNum);
+          }
+          else
+          {
+            if ( (item_Belt->uAttributes & 0xF0) == 16 )
+              v172 = "sptext01";
+            if ( (item_Belt->uAttributes & 0xF0) == 32 )
+              v172 = "sp28a";
+            if ( (item_Belt->uAttributes & 0xF0) == 64 )
+              v172 = "sp30a";
+            if ( (item_Belt->uAttributes & 0xF0) == 128 )
+              v172 = "sp91a";
+            v77 = pIcons_LOD->LoadTexturePtr(v172, TEXTURE_16BIT_PALETTE);
+            _50C9A8_item_enchantment_timer -= pEventTimer->uTimeElapsed;
+            if ( _50C9A8_item_enchantment_timer <= 0 )
+            {
+              _50C9A8_item_enchantment_timer = 0;
+              item_Belt->uAttributes &= 0xFFFFFF0Fu;
+              ptr_50C9A4 = 0;
+            }
+            v78 = (double)GetTickCount() * 0.1;
+            pRenderer->_4A63E6(pX_Belt, pY_Belt, pIcons_LOD->GetTexture(v75), v77, (signed __int64)v78, 0, 255);
+          }
+        }
+      }
+      pMainHandNum2 = pPlayers[uPlayerID]->pEquipment.uMainHand;
+      if ( pMainHandNum2 )
+      {
+        v83 = pPlayers[uPlayerID]->pInventoryItems[pMainHandNum2 - 1].uItemID;
+        if ( pItemsTable->pItems[v83].uEquipType == 1
+             || pItemsTable->pItems[v83].uSkillType == PLAYER_SKILL_SPEAR && !pPlayers[uPlayerID]->pEquipment.uShield )
+          pRenderer->DrawTextureTransparent(pPaperdoll_BodyX + pPaperdoll_SecondLeftHand[pBodyComplection][0],
+                                            pPaperdoll_BodyY + pPaperdoll_SecondLeftHand[pBodyComplection][1],
+                                            pIcons_LOD->GetTexture(papredoll_dlaus[uPlayerID - 1]));
+      }
+      pCloakCollarNum = pPlayers[uPlayerID]->pEquipment.uCloak;//  
+      if ( pCloakCollarNum )
+      {
+        item_CloakCollar = &pPlayers[uPlayerID]->pInventoryItems[pCloakCollarNum - 1];
+        switch ( item_CloakCollar->uItemID )
+        {
+          case 525:
+            v114 = 5;
+            break;
+          case 530:
+            v114 = 6;
+            break;
+          case 547:
+            v114 = 7;
+            break;
+          case 548:
+            v114 = 8;
+            break;
+          case 550:
+            v114 = 9;
+            break;
+          default:
+            v114 = item_CloakCollar->uItemID - 105;
+        }
+        if ( v114 >= 0 && v114 < 10 )
+        {
+          v116 = paperdoll_cloak_collar_texture[pBodyComplection][v114];
+          pX_CloakCollar = pPaperdoll_BodyX + paperdoll_CloakCollar[pBodyComplection][v114][0];
+          pY_CloakCollar = pPaperdoll_BodyY + paperdoll_CloakCollar[pBodyComplection][v114][1];
+          if ( v116 != pIcons_LOD->FindTextureByName("pending") )
+          {
+            if ( !(item_CloakCollar->uAttributes & 0xF0) )
+            {
+              v119 = v116 + 1;
+              v120 = (char *)pIcons_LOD->GetTexture(v116);
+              if ( item_CloakCollar->uAttributes & 2 )
+                pRenderer->DrawTransparentRedShade(pX_CloakCollar, pY_CloakCollar, (Texture *)v120);
+              else
+                pRenderer->DrawTextureTransparent(pX_CloakCollar, pY_CloakCollar, (Texture *)v120);
+              if ( !bRingsShownInCharScreen )
+                pRenderer->DrawMaskToZBuffer(pX_CloakCollar, pY_CloakCollar, (Texture *)v120, pCloakCollarNum);
+            }
+            else
+            {
+              if ( (item_CloakCollar->uAttributes & 0xF0) == 16 )
+                v179 = "sptext01";
+              if ( (item_CloakCollar->uAttributes & 0xF0) == 32 )
+                v179 = "sp28a";
+              if ( (item_CloakCollar->uAttributes & 0xF0) == 64 )
+                v179 = "sp30a";
+              if ( (item_CloakCollar->uAttributes & 0xF0) == 128 )
+                v179 = "sp91a";
+              a2i = pIcons_LOD->LoadTexturePtr(v179, TEXTURE_16BIT_PALETTE);
+              _50C9A8_item_enchantment_timer -= pEventTimer->uTimeElapsed;
+              if ( _50C9A8_item_enchantment_timer <= 0 )
+              {
+                _50C9A8_item_enchantment_timer = 0;
+                item_CloakCollar->uAttributes &= 0xFFFFFF0Fu;
+                ptr_50C9A4 = 0;
+              }
+              v118 = (double)GetTickCount() * 0.1;
+              pRenderer->_4A63E6(pX_CloakCollar, pY_CloakCollar, pIcons_LOD->GetTexture(v116), a2i, (signed __int64)v118, 0, 255);
+            }
+          }
+        }
+      }
+      if ( pPlayers[uPlayerID]->uCurrentFace == 12 || pPlayers[uPlayerID]->uCurrentFace == 13 )
+      {
+        v122 = papredoll_dbrds[pPlayers[uPlayerID]->uCurrentFace];
+        if ( v122 != pIcons_LOD->FindTextureByName("Pending") )
+          pRenderer->DrawTextureTransparent(pPaperdoll_BodyX + pPaperdoll_Beards[2 * pPlayers[uPlayerID]->uCurrentFace - 24],
+                     pPaperdoll_BodyY + pPaperdoll_Beards[2 * pPlayers[uPlayerID]->uCurrentFace - 23],
+                     pIcons_LOD->GetTexture(v122));
+      }
+    pHelmNum = pPlayers[uPlayerID]->pEquipment.uHelm;// 
+    if ( pHelmNum )
+    {
+      item_Helm = &pPlayers[uPlayerID]->pInventoryItems[pHelmNum-1];
+      switch ( item_Helm->uItemID )
+      {
+        case 521:
+          v125 = 11;
+          break;
+        case 522:
+          v125 = 12;
+          break;
+        case 523:
+          v125 = 13;
+          break;
+        case 532:
+          v125 = 14;
+          break;
+        case 544:
+          v125 = 15;
+          break;
+        default:
+          v125 = item_Helm->uItemID - 89;
+      }
+      if ( v125 >= 0 && v125 < 16 )
+      {
+        pX_Helm = pPaperdoll_BodyX + paperdoll_Helm[pBodyComplection][v125][0];
+        pY_Helm = pPaperdoll_BodyY + paperdoll_Helm[pBodyComplection][v125][1];
+        if ( IsDwarf != 1 || item_Helm->uItemID != 92 )
+          v127 = paperdoll_helm_texture[player->GetSexByVoice()][v125];
+        else
+          v127 = papredoll_dbrds[11];
+        if ( item_Helm->uAttributes & 0xF0 )
+        {
+          if ( (item_Helm->uAttributes & 0xF0) == 16 )
+            v180 = "sptext01";
+          if ( (item_Helm->uAttributes & 0xF0) == 32 )
+            v180 = "sp28a";
+          if ( (item_Helm->uAttributes & 0xF0) == 64 )
+            v180 = "sp30a";
+          if ( (item_Helm->uAttributes & 0xF0) == 128 )
+            v180 = "sp91a";
+          v129 = pIcons_LOD->LoadTexturePtr(v180, TEXTURE_16BIT_PALETTE);
+          _50C9A8_item_enchantment_timer -= pEventTimer->uTimeElapsed;
+          if ( _50C9A8_item_enchantment_timer <= 0 )
+          {
+            _50C9A8_item_enchantment_timer = 0;
+            item_Helm->uAttributes &= 0xFFFFFF0Fu;
+            ptr_50C9A4 = 0;
+          }
+          v130 = (double)GetTickCount() * 0.1;
+          pRenderer->_4A63E6(pX_Helm, pY_Helm, pIcons_LOD->GetTexture(v127), v129, (signed __int64)v130, 0, 255);
+        }
+        else
+        {
+          v131 = v127 + 1;
+          v132 = (char *)pIcons_LOD->GetTexture(v127);
+          if ( item_Helm->uAttributes & 2 )
+            pRenderer->DrawTransparentRedShade(pX_Helm, pY_Helm, (Texture *)v132);
+          else
+          {
+            if ( item_Helm->uAttributes & 1 )
+              pRenderer->DrawTextureTransparent(pX_Helm, pY_Helm, (Texture *)v132);
+            else
+              pRenderer->DrawTransparentGreenShade(pX_Helm, pY_Helm, (Texture *)v132);
+          }
+        }
+        if ( !bRingsShownInCharScreen )
+          pRenderer->DrawMaskToZBuffer(pX_Helm, pY_Helm, (Texture *)v132, pHelmNum);
+      }
+    }
+    pMainHandNum3 = pPlayers[uPlayerID]->pEquipment.uMainHand;//weapon in right hand
+    if ( pMainHandNum3 )
+    {
+      item_MainHand3 = &pPlayers[uPlayerID]->pInventoryItems[pMainHandNum3 - 1];
+      pX_MainHand3 = pPaperdoll_BodyX + paperdoll_Weapon[pBodyComplection][1][0] - pItemsTable->pItems[item_MainHand3->uItemID].uEquipX;
+      pY_MainHand3 = pPaperdoll_BodyY + paperdoll_Weapon[pBodyComplection][1][1] - pItemsTable->pItems[item_MainHand3->uItemID].uEquipY;
+      if ( item_MainHand3->uItemID == 64 )
+        v181 = "item64v1";
+      else
+        v181 = pItemsTable->pItems[item_MainHand3->uItemID].pIconName;
+      v138 = pIcons_LOD->LoadTexture(v181, TEXTURE_16BIT_PALETTE);
+      if ( !(item_MainHand3->uAttributes & 0xF0) )
+      {
+        v142 = v138 + 1;
+        v143 = (char *)pIcons_LOD->GetTexture(v138);
+        if ( item_MainHand3->uAttributes & 2 )
+          pRenderer->DrawTransparentRedShade(pX_MainHand3, pY_MainHand3, (Texture *)v143);
+        else
+        {
+          if ( item_MainHand3->uAttributes & 1 )
+            pRenderer->DrawTextureTransparent(pX_MainHand3, pY_MainHand3, (Texture *)v143);
+          else
+            pRenderer->DrawTransparentGreenShade(pX_MainHand3, pY_MainHand3, (Texture *)v143);
+        }
+      }
+      else
+      {
+        if ( (item_MainHand3->uAttributes & 0xF0) == 16 )
+          v182 = "sptext01";
+        if ( (item_MainHand3->uAttributes & 0xF0) == 32 )
+          v182 = "sp28a";
+        if ( (item_MainHand3->uAttributes & 0xF0) == 64 )
+           v182 = "sp30a";
+        if ( (item_MainHand3->uAttributes & 0xF0) == 128 )
+          v182 = "sp91a";
+        v140 = pIcons_LOD->LoadTexturePtr(v182, TEXTURE_16BIT_PALETTE);
+        _50C9A8_item_enchantment_timer -= pEventTimer->uTimeElapsed;
+        if ( _50C9A8_item_enchantment_timer <= 0 )
+        {
+          _50C9A8_item_enchantment_timer = 0;
+          item_MainHand3->uAttributes &= 0xFFFFFF0Fu;
+          ptr_50C9A4 = 0;
+        }
+        v141 = (double)GetTickCount() * 0.1;
+        pRenderer->_4A63E6(pX_MainHand3, pY_MainHand3, pIcons_LOD->GetTexture(v138), v140, (signed __int64)v141, 0, 255);
+      }
+      if ( !bRingsShownInCharScreen )
+        pRenderer->DrawMaskToZBuffer(pX_MainHand3, pY_MainHand3, (Texture *)v143, pMainHandNum3);
+    }
+    pShieldNum = pPlayers[uPlayerID]->pEquipment.uShield;//  
+    if ( pShieldNum )
+    {
+      item_Shield = &pPlayers[uPlayerID]->pInventoryItems[pShieldNum - 1];
+      v149 = pItemsTable->pItems[item_Shield->uItemID].uSkillType;
+      if ( v149 == 2 || v149 == 1 )
+      {
+        v151 = item_Shield->uItemID - 400;
+        pX_Shield = 596;
+        v245 = 1;
+        switch ( item_Shield->uItemID )
+        {
+          case 400:
+            pY_Shield = 86;
+            break;
+          case 403:
+            pY_Shield = 28;
+            break;
+          case 415:
+            pX_Shield = 595;
+            pY_Shield = 33;
+            break;
+          default:
+            pX_Shield = pPaperdoll_BodyX + paperdoll_Weapon[pBodyComplection][0][0] - pItemsTable->pItems[item_Shield->uItemID].uEquipX;
+            pY_Shield = pPaperdoll_BodyY + paperdoll_Weapon[pBodyComplection][0][1] - pItemsTable->pItems[item_Shield->uItemID].uEquipY;
+            break;
+        }
+      }
+      else
+      {
+        v245 = 0;
+        pX_Shield = pPaperdoll_BodyX + paperdoll_Weapon[pBodyComplection][0][0] - pItemsTable->pItems[item_Shield->uItemID].uEquipX;
+        pY_Shield = pPaperdoll_BodyY + paperdoll_Weapon[pBodyComplection][0][1] - pItemsTable->pItems[item_Shield->uItemID].uEquipY;
+      }
+      v153 = pIcons_LOD->LoadTexture(pItemsTable->pItems[item_Shield->uItemID].pIconName, TEXTURE_16BIT_PALETTE);
+      if ( !(item_Shield->uAttributes & 0xF0) )
+      {
+        if ( item_Shield->uAttributes & 2 )
+          pRenderer->DrawTransparentRedShade(pX_Shield, pY_Shield, pIcons_LOD->GetTexture(v153));
+        else
+        {
+          v160 = (char *)pIcons_LOD->GetTexture(v153);
+          if ( !(item_Shield->uAttributes & 1) )
+          pRenderer->DrawTransparentGreenShade(pX_Shield, pY_Shield, (Texture *)v160);
+          else
+            pRenderer->DrawTextureTransparent(pX_Shield, pY_Shield, (Texture *)v160);
+        }
+      }
+      else
+      {
+        if ( (item_Shield->uAttributes & 0xF0) == 16 )
+          v183 = "sptext01";
+        if ( (item_Shield->uAttributes & 0xF0) == 32 )
+          v183 = "sp28a";
+        if ( (item_Shield->uAttributes & 0xF0) == 64 )
+          v183 = "sp30a";
+        if ( (item_Shield->uAttributes & 0xF0) == 128 )
+          v183 = "sp91a";
+        v157 = pIcons_LOD->LoadTexturePtr(v183, TEXTURE_16BIT_PALETTE);
+        _50C9A8_item_enchantment_timer -= pEventTimer->uTimeElapsed;
+        if ( _50C9A8_item_enchantment_timer <= 0 )
+        {
+          _50C9A8_item_enchantment_timer = 0;
+          item_Shield->uAttributes &= 0xFFFFFF0Fu;
+          ptr_50C9A4 = 0;
+        }
+        v158 = (double)GetTickCount() * 0.1;
+        pRenderer->_4A63E6(pX_Shield, pY_Shield, pIcons_LOD->GetTexture(v153), v157, (signed __int64)v158, 0, 255);
+        if ( v245 )
+          pRenderer->DrawTextureTransparent(pPaperdoll_BodyX + pPaperdollLeftEmptyHand[pBodyComplection][0],
+                 pPaperdoll_BodyY + pPaperdollLeftEmptyHand[pBodyComplection][1], pIcons_LOD->GetTexture(papredoll_dlhs[uPlayerID - 1]));
+      }
+      if ( !bRingsShownInCharScreen )
+        pRenderer->DrawMaskToZBuffer(pX_Shield, pY_Shield, pIcons_LOD->GetTexture(v153), pShieldNum);
+    }
+  }
+  pRenderer->DrawTextureTransparent(pPaperdoll_BodyX + pPaperdoll_RightHand[pBodyComplection][0], pPaperdoll_BodyY + pPaperdoll_RightHand[pBodyComplection][1], pIcons_LOD->GetTexture(papredoll_drhs[uPlayerID - 1]));
+  pMainHandNum5 = pPlayers[uPlayerID]->pEquipment.uMainHand;
+  if ( pMainHandNum5 )
+  {
+    item_MainHand5 = &pPlayers[uPlayerID]->pInventoryItems[pMainHandNum5 - 1];
+    if ( pItemsTable->pItems[item_MainHand5->uItemID].uEquipType == 1 || 
+        pItemsTable->pItems[item_MainHand5->uItemID].uSkillType == PLAYER_SKILL_SPEAR && 
+         !pPlayers[uPlayerID]->pEquipment.uShield )
+      pRenderer->DrawTextureTransparent(pPaperdoll_BodyX + pPaperdoll_SecondLeftHand[pBodyComplection][0], 
+                                        pPaperdoll_BodyY + pPaperdoll_SecondLeftHand[pBodyComplection][1], 
+                                        pIcons_LOD->GetTexture(papredoll_dlhus[uPlayerID - 1]));
+  }
+  if ( !bRingsShownInCharScreen )// 
+    pRenderer->DrawTextureTransparent(603, 299, pIcons_LOD->GetTexture(uTextureID_MAGNIF_B));
+  pRenderer->DrawTextureTransparent(468, 0, pIcons_LOD->GetTexture(uTextureID_right_panel_loop));//
+}
+
+
+
+
+
+
+
+//----- (0041A2D1) --------------------------------------------------------
+void CharacterUI_InventoryTab_Draw(Player *player, bool a2)
+{
+        Texture *v7; // esi@6
+        signed int v11; // edx@6
+        int v13; // eax@13
+        signed int v14; // edx@13
+        int v15; // eax@13
+        unsigned int v17; // edi@15
+        Texture *pTexture; // ebx@24
+        unsigned int uCellX; // [sp+30h] [bp-8h]@5
+        unsigned int uCellY; // [sp+34h] [bp-4h]@5
+
+  pRenderer->DrawTextureIndexed(8, 8, pIcons_LOD->GetTexture(uTextureID_CharacterUI_InventoryBackground));
+  if (a2)
+    pRenderer->DrawTextureIndexed(8, 305, pIcons_LOD->LoadTexturePtr("fr_strip", TEXTURE_16BIT_PALETTE));
+
+  int i = 0;
+  for (uint i = 0; i < 126; ++i)
+  {
+    int v26 = (int)(player->pInventoryIndices + i);
+
+    if (player->pInventoryIndices[i] <= 0)
+      continue;
+
+    int item_idx = player->pInventoryIndices[i];
+    auto item = &player->pInventoryItems[item_idx - 1];
+    if (!item->uItemID)
+      continue;
+
+    uCellY = 32 * (i / 14) + 17;
+    uCellX = 32 * (i % 14) + 14;
+    uint item_texture_id = pIcons_LOD->LoadTexture(pItemsTable->pItems[item->uItemID].pIconName, TEXTURE_16BIT_PALETTE);
+    v7 = pIcons_LOD->GetTexture(item_texture_id);
+
+                    v11 = v7->uTextureWidth;
+                    if (v11 < 14)
+                        v11 = 14;
+
+                    if ( (v11 - 14) / 32 == 0 && v7->uTextureWidth < 32)
+                        uCellX += (32 - v7->uTextureWidth) / 2;
+                    v13 = v11 - 14;
+                    LOBYTE(v13) = v13 & 0xE0;
+                    v15 = v13 + 32;
+                    v14 = v7->uTextureHeight;
+                    if (v14 < 14 )
+                        v14 = 14;
+                    v17 = uCellX + ((v15 - v7->uTextureWidth) >> 1) + pSRZBufferLineOffsets[uCellY + (( (int)((v14 - 14) & 0xFFFFFFE0) - v7->uTextureHeight + 32) >> 1)];   //added typecast. without it the value in the brackets got cat to unsigned which messed stuff up
+
+    if (item->uAttributes & 0xF0)
+    {
+      switch (item->uAttributes & 0xF0)
+      {
+        case ITEM_AURA_EFFECT_RED:    pTexture = pIcons_LOD->LoadTexturePtr("sptext01", TEXTURE_16BIT_PALETTE); break;
+        case ITEM_AURA_EFFECT_BLUE:   pTexture = pIcons_LOD->LoadTexturePtr("sp28a", TEXTURE_16BIT_PALETTE);    break;
+        case ITEM_AURA_EFFECT_GREEN:  pTexture = pIcons_LOD->LoadTexturePtr("sp30a", TEXTURE_16BIT_PALETTE);    break;
+        case ITEM_AURA_EFFECT_PURPLE: pTexture = pIcons_LOD->LoadTexturePtr("sp91a", TEXTURE_16BIT_PALETTE);    break;
+      }
+
+      _50C9A8_item_enchantment_timer -= pEventTimer->uTimeElapsed;
+      if (_50C9A8_item_enchantment_timer <= 0)
+      {
+        _50C9A8_item_enchantment_timer = 0;
+        LOBYTE(item->uAttributes) &= 0xF;
+        ptr_50C9A4 = 0;
+      }
+
+      pRenderer->_4A63E6(uCellX, uCellY, v7, pTexture, GetTickCount() * 0.1, 0, 255);
+      ZBuffer_Fill(&pRenderer->pActiveZBuffer[v17], item_texture_id, item_idx);
+    }
+    else
+    {
+      if (item->Identified() || pCurrentScreen != SCREEN_HOUSE)
+      {
+        if (item->Broken())
+          pRenderer->DrawTransparentRedShade(uCellX, uCellY, v7);
+        else
+          pRenderer->DrawTextureTransparent(uCellX, uCellY, v7);
+      }
+      else
+        pRenderer->DrawTransparentGreenShade(uCellX, uCellY, v7);
+
+      ZBuffer_Fill(&pRenderer->pActiveZBuffer[v17], item_texture_id, item_idx);
+      continue;
+    }
+  }
+}
+
+
+
+static void CharacterUI_DrawItem(int x, int y, ItemGen *item, int id)
+{
+  auto item_texture = pIcons_LOD->LoadTexturePtr(pItemsTable->pItems[item->uItemID].pIconName, TEXTURE_16BIT_PALETTE);
+
+  if (item->uAttributes & 0xF0) // enchant animation
+  {
+    Texture *enchantment_texture = nullptr;
+    switch (item->uAttributes & 0xF0)
+    {
+      case ITEM_AURA_EFFECT_RED:    enchantment_texture = pIcons_LOD->LoadTexturePtr("sptext01", TEXTURE_16BIT_PALETTE); break;
+      case ITEM_AURA_EFFECT_BLUE:   enchantment_texture = pIcons_LOD->LoadTexturePtr("sp28a", TEXTURE_16BIT_PALETTE);    break;
+      case ITEM_AURA_EFFECT_GREEN:  enchantment_texture = pIcons_LOD->LoadTexturePtr("sp30a", TEXTURE_16BIT_PALETTE);    break;
+      case ITEM_AURA_EFFECT_PURPLE: enchantment_texture = pIcons_LOD->LoadTexturePtr("sp91a", TEXTURE_16BIT_PALETTE);    break;
+    }
+
+    _50C9A8_item_enchantment_timer -= pEventTimer->uTimeElapsed;
+    if (_50C9A8_item_enchantment_timer <= 0)
+    {
+      _50C9A8_item_enchantment_timer = 0;
+      item->uAttributes &= 0xFFFFFF0F;
+      ptr_50C9A4 = 0;
+    }
+    pRenderer->_4A63E6(x, y, item_texture, enchantment_texture, GetTickCount() * 0.1, 0, 255);
+  }
+  else
+  {
+    if (item->Broken())
+      pRenderer->DrawTransparentRedShade(x, y, item_texture);
+    else if (!item->Identified())
+      pRenderer->DrawTransparentGreenShade(x, y, item_texture);
+    else
+      pRenderer->DrawTextureTransparent(x, y, item_texture);
+
+    pRenderer->ZBuffer_Fill_2(x, y, item_texture, id);
+  }
+}
+
+
+//----- (0043E825) --------------------------------------------------------
+void CharacterUI_DrawPaperdollWithRingOverlay(Player *player)
+{
+  CharacterUI_DrawPaperdoll(player);
+
+  pRenderer->DrawTextureTransparent(0x1D9u, 0, pIcons_LOD->GetTexture(uTextureID_BACKHAND));
+  pRenderer->DrawTextureTransparent(0x1D4u, 0, pIcons_LOD->GetTexture(uTextureID_right_panel_loop));
+  pRenderer->DrawTextureIndexed(pCharacterScreen_DetalizBtn->uX,
+                                pCharacterScreen_DetalizBtn->uY,
+                                pIcons_LOD->GetTexture(uTextureID_detaliz_close_button));
+
+  for (uint i = 0; i < 6; ++i)
+  {
+    if (!player->pEquipment.uRings[i])
+      continue;
+    
+    static int pPaperdollRingsX[6] = {0x1EA, 0x21A, 0x248, 0x1EA, 0x21A, 0x248};
+    static int pPaperdollRingsY[6] = {0x0CA, 0x0CA, 0x0CA, 0x0FA, 0x0FA, 0x0FA};
+
+    CharacterUI_DrawItem(pPaperdollRingsX[i],
+                         pPaperdollRingsY[i],
+                         &player->pInventoryItems[player->pEquipment.uRings[i] - 1],
+                         player->pEquipment.uRings[i]);
+  }
+
+
+  if (player->pEquipment.uAmulet)
+  {
+    CharacterUI_DrawItem(493, 91,
+                         &player->pInventoryItems[player->pEquipment.uAmulet - 1],
+                         player->pEquipment.uAmulet);
+  }
+
+  if (player->pEquipment.uGlove)
+  {
+    CharacterUI_DrawItem(586, 88,
+                         &player->pInventoryItems[player->pEquipment.uGlove - 1],
+                         player->pEquipment.uGlove);
+  }
+}
+
+//----- (0043BCA7) --------------------------------------------------------
+void CharacterUI_LoadPaperdollTextures()
+{
+  int v0; // edi@7
+  enum CHARACTER_RACE pRace; // ebx@7
+  signed int pSex; // eax@7
+  int v3; // ebx@10
+  Player *pPlayer; // edi@12
+  unsigned __int8 v5; // cl@12
+  int v6; // edi@16
+  unsigned int v7; // eax@16
+  Player *pPlayer2; // ebx@16
+  char *v9; // ebx@16
+  char v10; // al@16
+  signed int v11; // edi@21
+  unsigned int v22; // eax@76
+  int v23; // ecx@76
+  unsigned int v24; // eax@78
+  int v25; // ecx@78
+  int v26; // ebx@79
+  unsigned int v27; // eax@80
+  int v28; // ecx@80
+  int v30; // [sp+10h] [bp-28h]@5
+  signed int v32; // [sp+10h] [bp-28h]@75
+  signed int v33; // [sp+10h] [bp-28h]@77
+  int v34; // [sp+10h] [bp-28h]@79
+  int pItemTXTNum; // [sp+14h] [bp-24h]@75
+  int v37; // [sp+14h] [bp-24h]@77
+  signed int v38; // [sp+14h] [bp-24h]@79
+  int v42; // [sp+20h] [bp-18h]@6
+  int v43; // [sp+20h] [bp-18h]@73
+  char pContainer[128]; // [sp+24h] [bp-14h]@12
+
+  uTextureID_MAGNIF_B = pIcons_LOD->LoadTexture("MAGNIF-B", TEXTURE_16BIT_PALETTE);
+  //if ( !pParty->uAlignment || pParty->uAlignment == 1 || pParty->uAlignment == 2 )
+  uTextureID_BACKDOLL = pIcons_LOD->LoadTexture("BACKDOLL", TEXTURE_16BIT_PALETTE);
+  uTextureID_right_panel_loop = uTextureID_right_panel;
+  v30 = 0;
+  uTextureID_BACKHAND = pIcons_LOD->LoadTexture("BACKHAND", TEXTURE_16BIT_PALETTE);
+  uTextureID_detaliz_close_button = uExitCancelTextureId;
+  do
+  {
+    v42 = v30 + 1;
+    if ( sub_43EE77_ProbablyIfUnderwaterSuitIsEquipped(v30 + 1) )
+    {
+      v0 = v30;
+      pRace = pPlayers[v30 + 1]->GetRace();
+      pSex = pPlayers[v30 + 1]->GetSexByVoice();
+      if ( pRace && pRace != 1 && pRace != 2 )//race == 3
+        v3 = (pSex != 0) + 3;
+      else
+        v3 = (pSex != 0) + 1;
+      wsprintfA(pContainer, "pc23v%dBod", v3);
+      papredoll_dbods[v0] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);//Body texture
+      wsprintfA(pContainer, "pc23v%dlad", v3);
+      papredoll_dlads[v0] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);// Left Hand
+      wsprintfA(pContainer, "pc23v%dlau", v3);
+      papredoll_dlaus[v0] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);// Left Hand2
+      wsprintfA(pContainer, "pc23v%drh", v3);
+      papredoll_drhs[v0] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);// Right Hand
+      wsprintfA(pContainer, "pc23v%dlh", v3);
+      papredoll_dlhs[v0] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);// Left Fist
+      wsprintfA(pContainer, "pc23v%dlhu", v3);
+      papredoll_dlhus[v0] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE); // Left Fist 2
+      pPlayer = pPlayers[v0 + 1];
+      v5 = pPlayer->uCurrentFace;
+      if ( v5 == 12 || v5 == 13 )
+        papredoll_dbrds[(char)v5] = 0;
+      papredoll_flying_feet[pPlayer->uCurrentFace] = 0;
+      IsPlayerWearingWatersuit[v30 + 1] = 1;
+    }
+    else
+    {
+      papredoll_dbods[v30] = pIcons_LOD->LoadTexture(dbod_texnames_by_face[pPlayers[v30 + 1]->uCurrentFace], TEXTURE_16BIT_PALETTE);
+      papredoll_dlads[v30] = pIcons_LOD->LoadTexture(dlad_texnames_by_face[pPlayers[v30 + 1]->uCurrentFace], TEXTURE_16BIT_PALETTE);
+      papredoll_dlaus[v30] = pIcons_LOD->LoadTexture(dlau_texnames_by_face[pPlayers[v30 + 1]->uCurrentFace], TEXTURE_16BIT_PALETTE);
+      papredoll_drhs[v30] = pIcons_LOD->LoadTexture(drh_texnames_by_face[pPlayers[v30 + 1]->uCurrentFace], TEXTURE_16BIT_PALETTE);
+      papredoll_dlhs[v30] = pIcons_LOD->LoadTexture(dlh_texnames_by_face[pPlayers[v30 + 1]->uCurrentFace], TEXTURE_16BIT_PALETTE);
+      papredoll_dlhus[v30] = pIcons_LOD->LoadTexture(dlhu_texnames_by_face[pPlayers[v30 + 1]->uCurrentFace], TEXTURE_16BIT_PALETTE);
+      v10 = pPlayers[v30 + 1]->uCurrentFace;
+      if ( v10 == 12 || v10 == 13 )
+      {
+        wsprintfA(pContainer, "pc%02dbrd", v10 + 1);
+        papredoll_dbrds[v10] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+      }
+      wsprintfA(pContainer, "item281pc%02d", v10 + 1);
+      papredoll_flying_feet[pPlayers[v30 + 1]->uCurrentFace] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+      IsPlayerWearingWatersuit[v30 + 1] = 0;
+    }
+    ++v30;
+  }
+  while ( v42 < 4 );
+  uTextureID_ar_up_up = pIcons_LOD->LoadTexture("ar_up_up", TEXTURE_16BIT_PALETTE);
+  uTextureID_ar_up_dn = pIcons_LOD->LoadTexture("ar_up_dn", TEXTURE_16BIT_PALETTE);
+  uTextureID_ar_dn_up = pIcons_LOD->LoadTexture("ar_dn_up", TEXTURE_16BIT_PALETTE);
+  uTextureID_ar_dn_dn = pIcons_LOD->LoadTexture("ar_dn_dn", TEXTURE_16BIT_PALETTE);
+  papredoll_dbrds[9] = pIcons_LOD->LoadTexture("ib-cd1-d", TEXTURE_16BIT_PALETTE);
+  papredoll_dbrds[7] = pIcons_LOD->LoadTexture("ib-cd2-d", TEXTURE_16BIT_PALETTE);
+  papredoll_dbrds[5] = pIcons_LOD->LoadTexture("ib-cd3-d", TEXTURE_16BIT_PALETTE);
+  papredoll_dbrds[3] = pIcons_LOD->LoadTexture("ib-cd4-d", TEXTURE_16BIT_PALETTE);
+  papredoll_dbrds[1] = pIcons_LOD->LoadTexture("ib-cd5-d", TEXTURE_16BIT_PALETTE);
+  for ( v11 = 0; v11 < 54; ++v11 )// test equipment
+  {
+    party_has_equipment[v11] = 0;
+    if ( pParty->pPickedItem.uItemID != v11 + 66 )
+    {
+      for ( uint i = 0; i < 4; ++i)
+      {
+        if ( Player_has_item(v11 + 66, &pParty->pPlayers[i], 0) )
+          party_has_equipment[v11] = 1;
+      }
+    }
+  }
+  memset(byte_5111F6.data(), 0, 16);
+  for (uint i = 0; i < 4; ++i)
+  {
+    auto player = pParty->pPlayers + i;
+
+    if (Player_has_item(ITEM_ARTICACT_GOVERNONS_ARMOR, player, 1))    byte_5111F6[0] = 1;
+    if (Player_has_item(ITEM_ARTIFACT_YORUBA, player, 1))             byte_5111F6[1] = 1;
+    if (Player_has_item(ITEM_RELIC_HARECS_LEATHER, player, 1))        byte_5111F6[2] = 1;
+    if (Player_has_item(ITEM_ARTIFACT_LEAGUE_BOOTS, player, 1))       byte_5111F6[3] = 1;
+    if (Player_has_item(ITEM_RELIC_TALEDONS_HELM, player, 1))         byte_5111F6[4] = 1;
+    if (Player_has_item(ITEM_RELIC_SCHOLARS_CAP, player, 1))          byte_5111F6[5] = 1;
+    if (Player_has_item(ITEM_RELIC_PHYNAXIAN_CROWN, player, 1))       byte_5111F6[6] = 1;
+    if (Player_has_item(ITEM_ARTIFACT_MINDS_EYE, player, 1))          byte_5111F6[7] = 1;
+    if (Player_has_item(ITEM_RARE_SHADOWS_MASK, player, 1))           byte_5111F6[8] = 1;
+    if (Player_has_item(ITEM_RILIC_TITANS_BELT, player, 1))           byte_5111F6[9] = 1;
+    if (Player_has_item(ITEM_ARTIFACT_HEROS_BELT, player, 1))         byte_5111F6[10] = 1;
+    if (Player_has_item(ITEM_RELIC_TWILIGHT, player, 1))              byte_5111F6[11] = 1;
+    if (Player_has_item(ITEM_ARTIFACT_CLOAK_OF_THE_SHEEP, player, 1)) byte_5111F6[12] = 1;
+    if (Player_has_item(ITEM_RARE_SUN_CLOAK, player, 1))              byte_5111F6[13] = 1;
+    if (Player_has_item(ITEM_RARE_MOON_CLOAK, player, 1))             byte_5111F6[14] = 1;
+    if (Player_has_item(ITEM_RARE_VAMPIRES_CAPE, player, 1))          byte_5111F6[15] = 1;
+    if (Player_has_item(ITEM_ELVEN_CHAINMAIL, player, 1))             byte_5111F6[16] = 1;
+  }
+
+
+  for (uint i = 0; i < 2; ++i)
+  {
+    for ( uint j = 0; j < 5; ++j )//Belt
+    {
+      GetItemTextureFilename(pContainer, j + 100, i + 1, 0);
+      paperdoll_belt_texture[i][j] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+    }
+    GetItemTextureFilename(pContainer, 535, i + 1, 0);
+    paperdoll_belt_texture[i][6] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+    for ( uint j = 0; j < 11; ++j )//Helm
+    {
+      GetItemTextureFilename(pContainer, j + 89, i + 1, 0);
+      paperdoll_helm_texture[i][j] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+    }
+    GetItemTextureFilename(pContainer, 521, i + 1, 0);
+    paperdoll_helm_texture[i][11] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+    GetItemTextureFilename(pContainer, 522, i + 1, 0);
+    paperdoll_helm_texture[i][12] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+    GetItemTextureFilename(pContainer, 523, i + 1, 0);
+    paperdoll_helm_texture[i][13] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+    GetItemTextureFilename(pContainer, 532, i + 1, 0);
+    paperdoll_helm_texture[i][14] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+    GetItemTextureFilename(pContainer, 544, i + 1, 0);
+    paperdoll_helm_texture[i][15] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+    if ( _43ED6F_check_party_races(true) )
+      papredoll_dbrds[11] = pIcons_LOD->LoadTexture("item092v3", TEXTURE_16BIT_PALETTE);
+  }
+  v43 = 0;
+  for (uint i = 0; i < 4; ++i)
+  {
+    if ( sub_43EDB9_get_some_race_sex_relation_2(i) )
+    {
+      GetItemTextureFilename(pContainer, 524, i + 1, 0);
+      paperdoll_belt_texture[i][5] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);//Titans belt
+      pItemTXTNum = 66;
+      for ( v32 = 0; v32 < 13; ++v32 )//simple armor
+      {
+        GetItemTextureFilename(pContainer, pItemTXTNum, i + 1, 0);
+        paperdoll_armor_texture[i][v32][0] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+        GetItemTextureFilename(pContainer, pItemTXTNum, i + 1, 1);
+        paperdoll_armor_texture[i][v32][1] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+        GetItemTextureFilename(pContainer, pItemTXTNum, i + 1, 2);
+        paperdoll_armor_texture[i][v32][2] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+        pItemTXTNum++;
+      }
+      GetItemTextureFilename(pContainer, 516, i + 1, 0);//artefacts
+      paperdoll_armor_texture[i][v32][0] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+      GetItemTextureFilename(pContainer, 516, i + 1, 1);
+      paperdoll_armor_texture[i][v32][1] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+      GetItemTextureFilename(pContainer, 516, i + 1, 2);
+      paperdoll_armor_texture[i][v32][2] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+      GetItemTextureFilename(pContainer, 505, i + 1, 0);
+      paperdoll_armor_texture[i][v32 + 1][0] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+      GetItemTextureFilename(pContainer, 505, i + 1, 1);
+      paperdoll_armor_texture[i][v32 + 1][1] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+      GetItemTextureFilename(pContainer, 505, i + 1, 2);
+      paperdoll_armor_texture[i][v32 + 1][2] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+      GetItemTextureFilename(pContainer, 504, i + 1, 0);
+      paperdoll_armor_texture[i][v32 + 2][0] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+      GetItemTextureFilename(pContainer, 504, i + 1, 1);
+      paperdoll_armor_texture[i][v32 + 2][1] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+      GetItemTextureFilename(pContainer, 504, i + 1, 2);
+      paperdoll_armor_texture[i][v32 + 2][2] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+      GetItemTextureFilename(pContainer, 533, i + 1, 0);
+      paperdoll_armor_texture[i][v32 + 3][0] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+      GetItemTextureFilename(pContainer, 533, i + 1, 1);
+      paperdoll_armor_texture[i][v32 + 3][1] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+      GetItemTextureFilename(pContainer, 533, i + 1, 2);
+      paperdoll_armor_texture[i][v32 + 3][2] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+      for ( v33 = 0; v33 < 5; ++v33 )//boots
+      {
+        GetItemTextureFilename(pContainer, v33 + 115, i + 1, 0);
+        paperdoll_boots_texture[i][v33] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+      }
+      GetItemTextureFilename(pContainer, 512, i + 1, 0);
+      paperdoll_boots_texture[i][v33] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+      for ( v38 = 0; v38 < 5; ++v38 )//Cloak
+      {
+        GetItemTextureFilename(pContainer, v38 + 105, i + 1, 0);
+        paperdoll_cloak_texture[i][v38] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+        GetItemTextureFilename(pContainer, v38 + 105, i + 1, 1);
+        paperdoll_cloak_collar_texture[i][v38] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+      }
+      GetItemTextureFilename(pContainer, 525, i + 1, 0);
+      paperdoll_cloak_texture[i][5] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+      GetItemTextureFilename(pContainer, 530, i + 1, 0);
+      paperdoll_cloak_texture[i][6] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+      GetItemTextureFilename(pContainer, 547, i + 1, 0);
+      paperdoll_cloak_texture[i][7] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+      GetItemTextureFilename(pContainer, 548, i + 1, 0);
+      paperdoll_cloak_texture[i][8] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+      GetItemTextureFilename(pContainer, 550, i + 1, 0);
+      paperdoll_cloak_texture[i][9] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+      GetItemTextureFilename(pContainer, 525, i + 1, 1);
+      paperdoll_cloak_collar_texture[i][5] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+      GetItemTextureFilename(pContainer, 530, i + 1, 1);
+      paperdoll_cloak_collar_texture[i][6] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+      GetItemTextureFilename(pContainer, 547, i + 1, 1);
+      paperdoll_cloak_collar_texture[i][7] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+      GetItemTextureFilename(pContainer, 548, i + 1, 1);
+      paperdoll_cloak_collar_texture[i][8] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+      GetItemTextureFilename(pContainer, 550, i + 1, 1);
+      paperdoll_cloak_collar_texture[i][9] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+    }
+    else
+    {
+      v26 = v43;
+    }
+    v43 = v26 + 40;
+  }
+}
+
+//----- (00419401) --------------------------------------------------------
+void CharacterUI_SkillsTab_CreateButtons()
+    {
+    // unsigned int v0; // ecx@3
+    GUIButton *pButton; // eax@3
+    unsigned int current_Y; // esi@8
+    int buttons_count; // [sp+10h] [bp-14h]@1
+    int first_rows; // [sp+14h] [bp-10h]@19
+    int skill_id; // [sp+18h] [bp-Ch]@8
+    Player *curr_player; // [sp+1Ch] [bp-8h]@8
+    int i;
+    int uCurrFontHeght;
+
+    buttons_count = 0;
+    if ( dword_507CC0_activ_ch )
+        CharacterUI_ReleaseButtons();
+    dword_507CC0_activ_ch = uActiveCharacter;
+    for ( pButton = pGUIWindow_CurrentMenu->pControlsHead; pButton; pButton = pButton->pNext )
+        {
+        if ( pButton->msg == UIMSG_InventoryLeftClick )
+            {
+            dword_50698C_uX = pButton->uX;
+            dword_506988_uY = pButton->uY;
+            dword_506984_uZ = pButton->uZ;
+            dword_506980_uW = pButton->uW;
+            pButton->uW = 0;
+            pButton->uZ = 0;
+            pButton->uY = 0;
+            pButton->uX = 0;
+            }
+        }
+    first_rows = 0;
+    //  a5 = pGUIWindow_CurrentMenu->uNumControls;
+    curr_player = &pParty->pPlayers[uActiveCharacter-1];
+
+    uCurrFontHeght=pFontLucida->uFontHeight;
+    current_Y = 2 *uCurrFontHeght  + 13;
+    for(i=0; i<9;++i)
+        {
+        skill_id = pWeaponSkills[i];
+        if ( curr_player->pActiveSkills[skill_id] & 0x3F )
+            {
+            current_Y += uCurrFontHeght - 3;
+            ++buttons_count;
+            ++first_rows;
+            pGUIWindow_CurrentMenu->CreateButton(24, current_Y, 204, uCurrFontHeght - 3, 3, skill_id | 0x8000, UIMSG_SkillUp, skill_id, 0, "", 0, 0);
+            }
+        }
+    if ( !first_rows )
+        current_Y += uCurrFontHeght - 3;        
+    current_Y += 2 * uCurrFontHeght - 6;
+    for(i=0; i<9;++i)       
+        {
+        skill_id = pMagicSkills[i];
+        if ( curr_player->pActiveSkills[skill_id] & 0x3F && buttons_count < 15 )
+            {
+            current_Y += uCurrFontHeght - 3;
+            ++buttons_count;
+            pGUIWindow_CurrentMenu->CreateButton(24, current_Y, 204, uCurrFontHeght - 3, 3, skill_id | 0x8000, UIMSG_SkillUp, skill_id, 0, "", 0, 0);
+            }
+        }
+    first_rows = 0;      
+    current_Y = 2 * uCurrFontHeght + 13;
+    for(i=0; i<5;++i) 
+        {
+        skill_id = pArmorSkills[i];
+        if ( curr_player->pActiveSkills[skill_id] & 0x3F )
+            {
+            current_Y+= uCurrFontHeght - 3;
+            ++buttons_count;
+            ++first_rows;
+            pGUIWindow_CurrentMenu->CreateButton(246, current_Y, 204, uCurrFontHeght - 3, 3, skill_id | 0x8000, UIMSG_SkillUp, skill_id, 0, "", 0, 0);
+            }
+        }
+    if ( !first_rows )
+        current_Y += uCurrFontHeght - 3;           
+    current_Y += 2 * uCurrFontHeght - 6;
+    for(i=0; i<12; ++i)
+        {
+        skill_id = pMiscSkills[i];
+        if ( curr_player->pActiveSkills[skill_id] & 0x3F )
+            {
+            current_Y += uCurrFontHeght - 3;
+            ++buttons_count;
+            pGUIWindow_CurrentMenu->CreateButton(246, current_Y, 204, uCurrFontHeght - 3, 3, skill_id | 0x8000, UIMSG_SkillUp, skill_id, 0, "", 0, 0);
+            }
+        }
+
+    if ( buttons_count )
+        pGUIWindow_CurrentMenu->_41D08F_set_keyboard_control_group(buttons_count, 1, 0, pGUIWindow_CurrentMenu->uNumControls);
+    }
+
+
+
+//----- (00418511) --------------------------------------------------------
+    void CharacterUI_StatsTab_Draw( Player *player )
+        {
+        //Player *pPlayer; // edi@1
+        //unsigned int v4; // eax@2
+        int v7; // ebp@4
+        int v8; // eax@4
+        unsigned int v9; // eax@4
+        int v10; // ST34_4@4
+        int v13; // ebp@4
+        int v14; // eax@4
+        unsigned int v15; // eax@4
+        int v19; // ebp@4
+        int v20; // eax@4
+        unsigned int v21; // eax@4
+        int v25; // ebp@4
+        int v26; // eax@4
+        unsigned int v27; // eax@4
+        int v31; // ebp@4
+        int v32; // eax@4
+        unsigned int v33; // eax@4
+        int v37; // ebp@4
+        int v38; // eax@4
+        unsigned int v39; // eax@4
+        int v43; // ebp@4
+        int v44; // eax@4
+        unsigned int v45; // eax@4
+        signed int v49; // eax@6
+        unsigned int v50; // eax@6
+        int v53; // eax@8
+        unsigned int v54; // eax@8
+        int v58; // ebp@8
+        int v59; // eax@8
+        unsigned int v60; // eax@8
+        unsigned int v62; // eax@8
+        signed int v64; // eax@8
+        //unsigned __int8 v66; // al@8
+        char *v67; // eax@9
+        signed int v70; // ebp@11
+        signed int v71; // eax@11
+        unsigned int v72; // eax@11
+        int v75; // ebp@13
+        int v76; // eax@13
+        unsigned int v77; // eax@13
+        char *v78; // ecx@14
+        unsigned int v81; // eax@16
+        int v83; // eax@16
+        char *v85; // eax@16
+        int v87; // eax@16
+        char *v89; // eax@16
+        int v90; // eax@16
+        unsigned int v92; // eax@19
+        int v93; // eax@19
+        unsigned int v95; // eax@22
+        int v96; // eax@22
+        unsigned int v98; // eax@25
+        int v99; // eax@25
+        unsigned int v101; // eax@27
+        int v102; // eax@27
+        unsigned int v104; // eax@30
+        unsigned int v106; // eax@32
+        int v107; // eax@33
+        unsigned int v109; // eax@36
+        unsigned int v111; // eax@38
+        const char *a2; // [sp+14h] [bp-Ch]@4
+        const char *a2a; // [sp+14h] [bp-Ch]@6
+        const char *a2b; // [sp+14h] [bp-Ch]@11
+        const char *a2c; // [sp+14h] [bp-Ch]@16
+        const char *a2d; // [sp+14h] [bp-Ch]@19
+        const char *a2e; // [sp+14h] [bp-Ch]@22
+        const char *a2f; // [sp+14h] [bp-Ch]@25
+        const char *a2g; // [sp+14h] [bp-Ch]@27
+        const char *a2h; // [sp+14h] [bp-Ch]@33
+        int v131; // [sp+18h] [bp-8h]@16
+        int v132; // [sp+18h] [bp-8h]@19
+        int v133; // [sp+18h] [bp-8h]@22
+        int v134; // [sp+18h] [bp-8h]@25
+        int v135; // [sp+18h] [bp-8h]@27
+        int v136; // [sp+18h] [bp-8h]@33
+
+        //pPlayer = &pParty->pPlayers[uPlayerID-1];
+        //pPlayer = player;
+  pRenderer->DrawTextureIndexed(8, 8, pIcons_LOD->LoadTexturePtr("fr_stats", TEXTURE_16BIT_PALETTE));
+  sprintf(pTmpBuf.data(), "\f%05d", ui_character_header_text_color);
+  sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[429], player->pName, pClassNames[player->classType]);//"^Pi[%s] %s" / "%s the %s"
+  strcat(pTmpBuf.data(), pTmpBuf2.data());
+  sprintfex(pTmpBuf2.data(),  "\f00000\r180%s: \f%05d%d\f00000\n\n\n",
+            pGlobalTXT_LocalizationStrings[207], // "Skill points"
+            player->uSkillPoints ? ui_character_bonus_text_color : ui_character_default_text_color,
+            player->uSkillPoints);
+  strcat(pTmpBuf.data(), pTmpBuf2.data());
+  pGUIWindow_CurrentMenu->DrawText(pFontArrus, 26, 18, 0, pTmpBuf.data(), 0, 0, 0);
+
+  v10 = 53;
+  v7 = player->GetBaseStrength();
+  v8 = player->GetActualMight();
+  v9 = UI_GetHealthManaStringColor(v8, v7);
+  sprintf(pTmpBuf.data(), "%s\f%05u\r424%d\f00000 /\t185%d\n", pGlobalTXT_LocalizationStrings[144], v9, v8, v7);//Might
+  pGUIWindow_CurrentMenu->DrawText(pFontArrus, 26, v10, 0, pTmpBuf.data(), 0, 0, 0);
+
+  v10 += LOBYTE(pFontArrus->uFontHeight) - 2;
+  v13 = player->GetBaseIntelligence();
+  v14 = player->GetActualIntelligence();
+  v15 = UI_GetHealthManaStringColor(v14, v13);
+  sprintf(pTmpBuf.data(), "%s\f%05u\r424%d\f00000 /\t185%d\n", pGlobalTXT_LocalizationStrings[116], v15, v14, v13);//Intellect
+  pGUIWindow_CurrentMenu->DrawText(pFontArrus, 26, v10, 0, pTmpBuf.data(), 0, 0, 0);
+
+  v10 += LOBYTE(pFontArrus->uFontHeight) - 2;
+  v19 = player->GetBaseWillpower();
+  v20 = player->GetActualWillpower();
+  v21 = UI_GetHealthManaStringColor(v20, v19);
+  sprintf(pTmpBuf.data(), "%s\f%05u\r424%d\f00000 /\t185%d\n", pGlobalTXT_LocalizationStrings[163], v21, v20, v19);//
+  pGUIWindow_CurrentMenu->DrawText(pFontArrus, 26, v10, 0, pTmpBuf.data(), 0, 0, 0);
+
+  v10 += LOBYTE(pFontArrus->uFontHeight) - 2;
+  v25 = player->GetBaseEndurance();
+  v26 = player->GetActualEndurance();
+  v27 = UI_GetHealthManaStringColor(v26, v25);
+  sprintf(pTmpBuf.data(), "%s\f%05u\r424%d\f00000 /\t185%d\n", pGlobalTXT_LocalizationStrings[75], v27, v26, v25);//
+  pGUIWindow_CurrentMenu->DrawText(pFontArrus, 26, v10, 0, pTmpBuf.data(), 0, 0, 0);
+
+  v10 += LOBYTE(pFontArrus->uFontHeight) - 2;
+  v31 = player->GetBaseAccuracy();
+  v32 = player->GetActualAccuracy();
+  v33 = UI_GetHealthManaStringColor(v32, v31);
+  sprintf(pTmpBuf.data(), "%s\f%05u\r424%d\f00000 /\t185%d\n", pGlobalTXT_LocalizationStrings[1], v33, v32, v31);
+  pGUIWindow_CurrentMenu->DrawText(pFontArrus, 26, v10, 0, pTmpBuf.data(), 0, 0, 0);
+
+        v10 += LOBYTE(pFontArrus->uFontHeight) - 2;
+        v37 = player->GetBaseSpeed();
+        v38 = player->GetActualSpeed();
+        v39 = UI_GetHealthManaStringColor(v38, v37);
+        sprintf(pTmpBuf.data(), "%s\f%05u\r424%d\f00000 /\t185%d\n", pGlobalTXT_LocalizationStrings[211], v39, v38, v37);
+        pGUIWindow_CurrentMenu->DrawText(pFontArrus, 26, v10, 0, pTmpBuf.data(), 0, 0, 0);
+
+        v10 += LOBYTE(pFontArrus->uFontHeight) - 2;
+        v43 = player->GetBaseLuck();
+        v44 = player->GetActualLuck();
+        v45 = UI_GetHealthManaStringColor(v44, v43);
+        sprintf(pTmpBuf.data(), "%s\f%05u\r424%d\f00000 /\t185%d\n\n", pGlobalTXT_LocalizationStrings[136], v45, v44, v43);
+        pGUIWindow_CurrentMenu->DrawText(pFontArrus, 26, v10, 0, pTmpBuf.data(), 0, 0, 0);
+
+        a2 = "%s\f%05u\r424%d\f00000 /\t185%d\n";
+        v10 += 2 * LOBYTE(pFontArrus->uFontHeight) + 5;
+        if ( player->GetMaxHealth() >= 1000 )
+            a2 = "%s\f%05u\r388%d\f00000 / %d\n";
+        v49 = player->GetMaxHealth();
+        v50 = UI_GetHealthManaStringColor(player->sHealth, v49);
+        sprintf(pTmpBuf.data(), a2, pGlobalTXT_LocalizationStrings[108], v50, player->sHealth, v49);
+        pGUIWindow_CurrentMenu->DrawText(pFontArrus, 26, v10, 0, pTmpBuf.data(), 0, 0, 0);
+
+        a2a = "%s\f%05u\r424%d\f00000 /\t185%d\n";
+        v10 += LOBYTE(pFontArrus->uFontHeight) - 2;
+        if ( player->GetMaxMana() >= 1000 )
+            a2a = "%s\f%05u\r388%d\f00000 / %d\n";
+        v53 = player->GetMaxMana();
+        v54 = UI_GetHealthManaStringColor(player->sMana, v53);
+        sprintf(pTmpBuf.data(), a2a, pGlobalTXT_LocalizationStrings[212], v54, player->sMana, v53);
+        pGUIWindow_CurrentMenu->DrawText(pFontArrus, 26, v10, 0, pTmpBuf.data(), 0, 0, 0);
+
+        v10 += LOBYTE(pFontArrus->uFontHeight) - 2;
+        v58 = player->GetBaseAC();
+        v59 = player->GetActualAC();
+        v60 = UI_GetHealthManaStringColor(v59, v58);
+        sprintf(pTmpBuf.data(), "%s\f%05u\r424%d\f00000 /\t185%d\n\n", pGlobalTXT_LocalizationStrings[12], v60, v59, v58);
+        pGUIWindow_CurrentMenu->DrawText(pFontArrus, 26, v10, 0, pTmpBuf.data(), 0, 0, 0);
+
+        v10 += 2 * LOBYTE(pFontArrus->uFontHeight) - 2;
+        v62 = player->GetMajorConditionIdx();
+        v64 = GetConditionDrawColor(v62);
+        sprintf(pTmpBuf.data(), "%s: \f%05d%s\n", pGlobalTXT_LocalizationStrings[47], v64, aCharacterConditionNames[v62]);
+        pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 0x1Au, v10, 0, pTmpBuf.data(), 226, 0);
+
+        v10 += LOBYTE(pFontArrus->uFontHeight) + - 1;
+        if (player->uQuickSpell)
+            v67 = pSpellStats->pInfos[player->uQuickSpell].pShortName;
+        else
+            v67 = pGlobalTXT_LocalizationStrings[153];
+        sprintf(pTmpBuf.data(), "%s: %s", pGlobalTXT_LocalizationStrings[172], v67);
+        pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 0x1Au, v10, 0, pTmpBuf.data(), 226, 0);
+
+        v10 = 50;
+        v70 = player->GetBaseAge();
+        v71 = player->GetActualAge();
+        v72 = UI_GetHealthManaStringColor(v71, v70);
+        sprintf(pTmpBuf.data(), "%s\f%05u\t100%d\f00000 / %d\n", pGlobalTXT_LocalizationStrings[5], v72, v71, v70);
+        pGUIWindow_CurrentMenu->DrawText(pFontArrus, 266, v10, 0, pTmpBuf.data(), 0, 0, 0);
+
+        a2b = "%s\f%05u\t100%d\f00000 / %d\n";
+        v10 += LOBYTE(pFontArrus->uFontHeight) - 2;
+        if ( player->GetBaseLevel() > 99 )
+            a2b = "%s\f%05u\t180%d\f00000 / %d\n";
+        v75 = player->GetBaseLevel();
+        v76 = player->GetActualLevel();
+        v77 = UI_GetHealthManaStringColor(v76, v75);
+        sprintf(pTmpBuf.data(), a2b, pGlobalTXT_LocalizationStrings[131], v77, v76, v75);
+        pGUIWindow_CurrentMenu->DrawText(pFontArrus, 266, v10, 0, pTmpBuf.data(), 0, 0, 0);
+
+        v10 += LOBYTE(pFontArrus->uFontHeight) - 2;
+        if (player->uExperience <= 9999999)
+            v78 = pGlobalTXT_LocalizationStrings[83]; // "Experience"
+        else
+            v78 = pGlobalTXT_LocalizationStrings[17]; // "Exp."
+        v81 = player->GetExperienceDisplayColor();
+        sprintf(pTmpBuf.data(), "%s\r180\f%05d%lu\f00000\n\n", v78, v81, LODWORD(player->uExperience));
+        pGUIWindow_CurrentMenu->DrawText(pFontArrus, 266, v10, 0, pTmpBuf.data(), 0, 0, 0);
+
+        v10 += 2 * LOBYTE(pFontArrus->uFontHeight);
+        v83 = player->GetActualAttack(0);
+        sprintf(pTmpBuf.data(), "%s\t100%+d\n", pGlobalTXT_LocalizationStrings[18], v83);
+        pGUIWindow_CurrentMenu->DrawText(pFontArrus, 266, v10, 0, pTmpBuf.data(), 0, 0, 0);
+
+        v10 += LOBYTE(pFontArrus->uFontHeight) - 2;
+        v85 = player->GetMeleeDamageString();
+        sprintf(pTmpBuf.data(), "%s\t100 %s\n", pGlobalTXT_LocalizationStrings[53], v85);
+        pGUIWindow_CurrentMenu->DrawText(pFontArrus, 266, v10, 0, pTmpBuf.data(), 0, 0, 0);
+
+        v10 += LOBYTE(pFontArrus->uFontHeight) - 2;
+        v87 = player->GetRangedAttack();
+        sprintf(pTmpBuf.data(), "%s\t100%+d\n", pGlobalTXT_LocalizationStrings[203], v87);
+        pGUIWindow_CurrentMenu->DrawText(pFontArrus, 266, v10, 0, pTmpBuf.data(), 0, 0, 0);
+
+        v10 += LOBYTE(pFontArrus->uFontHeight) - 2;
+        v89 = player->GetRangedDamageString();
+        sprintf(pTmpBuf.data(), "%s\t100 %s\n\n", pGlobalTXT_LocalizationStrings[53], v89);
+        pGUIWindow_CurrentMenu->DrawText(pFontArrus, 266, v10, 0, pTmpBuf.data(), 0, 0, 0);
+
+        a2c = format_4E2E10;
+        v10 += 2 * LOBYTE(pFontArrus->uFontHeight) - 4;
+        v131 = player->GetActualResistance(CHARACTER_ATTRIBUTE_RESIST_FIRE);
+        v90 = player->GetBaseResistance(CHARACTER_ATTRIBUTE_RESIST_FIRE);
+        if ( v131 > 99 || v90 > 99 )
+            a2c = "%s\f%05u\t180%d\f00000 / %d\n";
+        v92 = UI_GetHealthManaStringColor(v131, v90);
+        sprintf(pTmpBuf.data(), a2c, pGlobalTXT_LocalizationStrings[87], v92, v131, v90);
+        pGUIWindow_CurrentMenu->DrawText(pFontArrus, 266, v10, 0, pTmpBuf.data(), 0, 0, 0);
+
+        a2d = format_4E2E10;
+        v10 += LOBYTE(pFontArrus->uFontHeight) - 2;
+        v132 = player->GetActualResistance(CHARACTER_ATTRIBUTE_RESIST_AIR);
+        v93 = player->GetBaseResistance(CHARACTER_ATTRIBUTE_RESIST_AIR);
+        if ( v132 > 99 || v93 > 99 )
+            a2d = "%s\f%05u\t180%d\f00000 / %d\n";
+        v95 = UI_GetHealthManaStringColor(v132, v93);
+        sprintf(pTmpBuf.data(), a2d, pGlobalTXT_LocalizationStrings[6], v95, v132, v93);
+        pGUIWindow_CurrentMenu->DrawText(pFontArrus, 266, v10, 0, pTmpBuf.data(), 0, 0, 0);
+
+        a2e = format_4E2E10;
+        v10 += LOBYTE(pFontArrus->uFontHeight) - 2;
+        v133 = player->GetActualResistance(CHARACTER_ATTRIBUTE_RESIST_WATER);
+        v96 = player->GetBaseResistance(CHARACTER_ATTRIBUTE_RESIST_WATER);
+        if ( v133 > 99 || v96 > 99 )
+            a2e = "%s\f%05u\t180%d\f00000 / %d\n";
+        v98 = UI_GetHealthManaStringColor(v133, v96);
+        sprintf(pTmpBuf.data(), a2e, pGlobalTXT_LocalizationStrings[240], v98, v133, v96);
+        pGUIWindow_CurrentMenu->DrawText(pFontArrus, 266, v10, 0, pTmpBuf.data(), 0, 0, 0);
+
+        a2f = format_4E2E10;
+        v10 += LOBYTE(pFontArrus->uFontHeight) - 2;
+        v134 = player->GetActualResistance(CHARACTER_ATTRIBUTE_RESIST_EARTH);
+        v99 = player->GetBaseResistance(CHARACTER_ATTRIBUTE_RESIST_EARTH);
+        if ( v134 > 99 )
+            a2f = "%s\f%05u\t180%d\f00000 / %d\n";
+        v101 = UI_GetHealthManaStringColor(v134, v99);
+        sprintf(pTmpBuf.data(), a2f, pGlobalTXT_LocalizationStrings[70], v101, v134, v99);
+        pGUIWindow_CurrentMenu->DrawText(pFontArrus, 266, v10, 0, pTmpBuf.data(), 0, 0, 0);
+
+        a2g = format_4E2E10;
+        v10 += LOBYTE(pFontArrus->uFontHeight) - 2;
+        v135 = player->GetActualResistance(CHARACTER_ATTRIBUTE_RESIST_MIND);
+        v102 = player->GetBaseResistance(CHARACTER_ATTRIBUTE_RESIST_MIND);
+        if ( v135 > 99 || v102 > 99 )
+            a2g = "%s\f%05u\t180%d\f00000 / %d\n";
+        v104 = UI_GetHealthManaStringColor(v135, v102);
+        sprintf(pTmpBuf.data(), a2g, pGlobalTXT_LocalizationStrings[142], v104, v135, v102);
+        if ( player->classType == PLAYER_CLASS_LICH && v102 == 200 )
+        {
+            v106 = UI_GetHealthManaStringColor(v135, 200);
+            sprintf(pTmpBuf.data(), format_4E2E00, pGlobalTXT_LocalizationStrings[142], v106, pGlobalTXT_LocalizationStrings[625]);
+        }
+        pGUIWindow_CurrentMenu->DrawText(pFontArrus, 266, v10, 0, pTmpBuf.data(), 0, 0, 0);
+
+        a2h = format_4E2E10;
+        v10 += LOBYTE(pFontArrus->uFontHeight) - 2;
+        v136 = player->GetActualResistance(CHARACTER_ATTRIBUTE_RESIST_BODY);
+        v107 = player->GetBaseResistance(CHARACTER_ATTRIBUTE_RESIST_BODY);
+        if ( v136 > 99 || v107 > 99 )
+            a2h = "%s\f%05u\t180%d\f00000 / %d\n";
+        v109 = UI_GetHealthManaStringColor(v136, v107);
+        sprintf(pTmpBuf.data(), a2h, pGlobalTXT_LocalizationStrings[29], v109, v136, v107);
+        if ( player->classType == PLAYER_CLASS_LICH && v107 == 200 )
+        {
+            v111 = UI_GetHealthManaStringColor(v136, 200);
+            sprintf(pTmpBuf.data(), format_4E2E00, pGlobalTXT_LocalizationStrings[29], v111, pGlobalTXT_LocalizationStrings[625]);
+        }
+        pGUIWindow_CurrentMenu->DrawText(pFontArrus, 266, v10, 0, pTmpBuf.data(), 0, 0, 0);
+}
+
+bool awardSort (int i,int j) { 
+    if (pAwards[i].uPriority == 0)  //none
+    {
+        return false;
+    }
+    else if (pAwards[j].uPriority == 0)
+    {
+        return true;
+    }
+    else if(pAwards[i].uPriority == 1)  //fines,arena stuff,etc
+    {
+        return false;
+    }
+    else if(pAwards[j].uPriority == 1)
+    {
+        return true;
+    }
+    else if(pAwards[i].uPriority == 5) //joined guilds
+    {
+        return false;
+    }
+    else if(pAwards[j].uPriority == 5)
+    {
+        return true;
+    }
+    else
+    {
+        return (pAwards[i].uPriority<pAwards[j].uPriority);
+    }
+}
+
+//----- (00419100) --------------------------------------------------------
+void FillAwardsData()
+{
+        auto pPlayer = pPlayers[uActiveCharacter];
+
+        memset(achieved_awards.data(), 0, 4000);
+        num_achieved_awards = 0;
+
+        memset(pTmpBuf2.data(), 0, 0x7D0u);
+        BtnDown_flag = 0;
+        BtnUp_flag = 0;
+        dword_50651C = 0;
+        dword_506528 = 0;
+        for (int i = 0; i < 105; ++i)
+        {
+            if ( _449B57_test_bit(pPlayer->_guilds_member_bits, i) && pAwards[i].pText )
+            {
+                achieved_awards[num_achieved_awards++] = (AwardType)i;
+            }
+        }
+        num_achieved_awards_2 = num_achieved_awards;
+        num_achieved_awards = 0;
+
+        //sort awards index 
+        if (num_achieved_awards_2 > 0)
+        {
+            std::stable_sort(achieved_awards.begin(), achieved_awards.end(), awardSort);
+        }
+    }
+
+
+//----- (0043EF2B) --------------------------------------------------------
+void WetsuitOn( unsigned int uPlayerID )
+    { 
+    CHARACTER_RACE player_race; // edi@2
+    signed int player_sex; // eax@2
+    int texture_num; // ecx@5
+    char pContainer[20]; // [sp+4h] [bp-1Ch]@7
+ 
+    if ( uPlayerID> 0 )
+        {
+        player_race = pPlayers[uPlayerID]->GetRace();
+        player_sex = pPlayers[uPlayerID]->GetSexByVoice();
+        if ( player_race == CHARACTER_RACE_DWARF  )
+            texture_num = (player_sex != 0) + 3;
+        else 
+            texture_num = (player_sex != 0) + 1;
+        wsprintfA(pContainer, "pc23v%dBod", texture_num);
+        papredoll_dbods[uPlayerID - 1] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+        wsprintfA(pContainer, "pc23v%dlad", texture_num);
+        papredoll_dlads[uPlayerID - 1] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+        wsprintfA(pContainer, "pc23v%dlau", texture_num);
+        papredoll_dlaus[uPlayerID - 1] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+        wsprintfA(pContainer, "pc23v%drh", texture_num);
+        papredoll_drhs[uPlayerID - 1] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+        wsprintfA(pContainer, "pc23v%dlh", texture_num);
+        papredoll_dlhs[uPlayerID - 1] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+        wsprintfA(pContainer, "pc23v%dlhu", texture_num);
+        papredoll_dlhus[uPlayerID - 1] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+
+        if ( pPlayers[uPlayerID]->uCurrentFace == 12 || pPlayers[uPlayerID]->uCurrentFace == 13 )
+            papredoll_dbrds[pPlayers[uPlayerID]->uCurrentFace] = 0;
+
+        papredoll_flying_feet[pPlayers[uPlayerID]->uCurrentFace] = 0;
+        IsPlayerWearingWatersuit[uPlayerID] = 1;
+        }
+    }
+
+//----- (0043F0BD) --------------------------------------------------------
+void WetsuitOff( unsigned int uPlayerID )
+    {
+    char pContainer[20]; // [sp+0h] [bp-18h]@4
+
+    if (uPlayerID > 0 )
+        {
+        papredoll_dbods[uPlayerID - 1] = pIcons_LOD->LoadTexture(dbod_texnames_by_face[pPlayers[uPlayerID]->uCurrentFace], TEXTURE_16BIT_PALETTE);
+        papredoll_dlads[uPlayerID - 1] = pIcons_LOD->LoadTexture(dlad_texnames_by_face[pPlayers[uPlayerID]->uCurrentFace], TEXTURE_16BIT_PALETTE);
+        papredoll_dlaus[uPlayerID - 1] = pIcons_LOD->LoadTexture(dlau_texnames_by_face[pPlayers[uPlayerID]->uCurrentFace], TEXTURE_16BIT_PALETTE);
+        papredoll_drhs [uPlayerID - 1] = pIcons_LOD->LoadTexture(drh_texnames_by_face [pPlayers[uPlayerID]->uCurrentFace], TEXTURE_16BIT_PALETTE);
+        papredoll_dlhs [uPlayerID - 1] = pIcons_LOD->LoadTexture(dlh_texnames_by_face [pPlayers[uPlayerID]->uCurrentFace], TEXTURE_16BIT_PALETTE);
+        papredoll_dlhus[uPlayerID - 1] = pIcons_LOD->LoadTexture(dlhu_texnames_by_face[pPlayers[uPlayerID]->uCurrentFace], TEXTURE_16BIT_PALETTE);
+
+        if ( pPlayers[uPlayerID]->uCurrentFace == 12 || pPlayers[uPlayerID]->uCurrentFace == 13 )
+            {
+            wsprintfA(pContainer, "pc%02dbrd", pPlayers[uPlayerID]->uCurrentFace + 1);
+            papredoll_dbrds[pPlayers[uPlayerID]->uCurrentFace] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+            }
+        wsprintfA(pContainer, "item281pc%02d", pPlayers[uPlayerID]->uCurrentFace + 1);
+        papredoll_flying_feet[pPlayers[uPlayerID]->uCurrentFace] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+        IsPlayerWearingWatersuit[uPlayerID] = 0;
+        }
+    }
+//----- (00468F8A) --------------------------------------------------------
+void __cdecl OnPaperdollLeftClick()
+{
+  int v1; // ecx@1
+  unsigned int v2; // edi@1
+  unsigned int v3; // edx@4
+  unsigned int pSkillType; // esi@5
+  unsigned __int16 v5; // ax@7
+  unsigned int v6; // edi@19
+  int v7; // esi@27
+  unsigned int v8; // eax@29
+  int v9; // edx@32
+  int v10; // esi@34
+  int v11; // eax@34
+  int v12; // esi@38
+  int v13; // eax@38
+  char v14; // zf@38
+  int v15; // esi@42
+  int v16; // eax@42
+  int v17; // eax@44
+  unsigned int v18; // ecx@55
+  unsigned int v19; // eax@55
+  int v20; // esi@60
+  int v21; // eax@60
+  unsigned int v22; // eax@61
+  unsigned int v23; // eax@62
+  int v24; // esi@65
+  int v25; // eax@65
+  unsigned int v26; // eax@69
+  int v27; // esi@81
+  int v28; // eax@81
+  int v29; // esi@84
+  int v30; // eax@84
+  int v31; // eax@85
+  unsigned int v32; // ecx@88
+  unsigned int v33; // eax@88
+  int v34; // esi@90
+  unsigned int v35; // eax@91
+  int v36; // esi@93
+  int v37; // edi@93
+  ItemGen *v38; // edi@93
+  __int16 v39; // dx@99
+  ItemGen _this; // [sp+Ch] [bp-40h]@1
+  unsigned int v48; // [sp+30h] [bp-1Ch]@88
+  unsigned int v49; // [sp+34h] [bp-18h]@57
+  unsigned int v50; // [sp+38h] [bp-14h]@50
+  int v51; // [sp+3Ch] [bp-10h]@1
+  unsigned int v52; // [sp+40h] [bp-Ch]@5
+  //int v53; // [sp+44h] [bp-8h]@1
+  //unsigned int v54; // [sp+48h] [bp-4h]@1
+
+  v51 = 0;
+  _this.Reset();
+  //v0 = pPlayers[uActiveCharacter];
+  v1 = pPlayers[uActiveCharacter]->pEquipment.uMainHand;
+  v2 = pPlayers[uActiveCharacter]->pEquipment.uShield;
+  //v54 = pPlayers[uActiveCharacter]->pEquipment.uShield;
+  //v53 = v1;
+  if ( v1 && pItemsTable->pItems[*(int *)&pPlayers[uActiveCharacter]->pInventoryItems[v1 - 1]].uEquipType == 1 )
+    v51 = v1;
+  v3 = pParty->pPickedItem.uItemID;
+  if ( pParty->pPickedItem.uItemID )
+  {
+    v52 = pItemsTable->pItems[pParty->pPickedItem.uItemID].uEquipType;
+    pSkillType = pItemsTable->pItems[pParty->pPickedItem.uItemID].uSkillType;
+    if ( pSkillType == 4 )
+    {
+      if ( v2 )
+      {
+        LOBYTE(v5) = pPlayers[uActiveCharacter]->GetActualSkillLevel(PLAYER_SKILL_SPEAR);
+        if ( (signed int)SkillToMastery(v5) < 3 )
+        {
+          pPlayers[uActiveCharacter]->PlaySound(SPEECH_39, 0);
+          return;
+        }
+        v3 = pParty->pPickedItem.uItemID;
+      }
+    }
+    else
+    {
+      if ( (pSkillType == 8 || pSkillType == 1 || pSkillType == 2)
+        && v1
+        && pItemsTable->pItems[*(int *)&pPlayers[uActiveCharacter]->pInventoryItems[v1-1]].uSkillType == 4 )
+	  {
+        LOBYTE(v5) = pPlayers[uActiveCharacter]->GetActualSkillLevel(PLAYER_SKILL_SPEAR);
+        if ( (signed int)SkillToMastery(v5) < 3 )
+        {
+          pPlayers[uActiveCharacter]->PlaySound(SPEECH_39, 0);
+          return;
+        }
+	  }
+    }
+    if ( !pPlayers[uActiveCharacter]->CanEquip_RaceAndAlignmentCheck(v3) )
+    {
+
+        pPlayers[uActiveCharacter]->PlaySound(SPEECH_39, 0);
+        return;
+    }
+    if ( pParty->pPickedItem.uItemID == 604 )
+    {
+      pPlayers[uActiveCharacter]->EquipBody((ITEM_EQUIP_TYPE)3);
+      WetsuitOn(uActiveCharacter);
+      return;
+    }
+    v6 = v52;
+    switch ( v52 )
+    {
+      case 2u:
+      case 3u:
+      case 5u:
+      case 6u:
+      case 7u:
+      case 8u:
+      case 9u:
+      case 0xBu:
+        if ( !pPlayers[uActiveCharacter]->HasSkill(pSkillType) )
+        {
+          pPlayers[uActiveCharacter]->PlaySound(SPEECH_39, 0);
+          return;
+        }
+        if ( sub_43EE77_ProbablyIfUnderwaterSuitIsEquipped(uActiveCharacter) && (v6 != 3 || bUnderwater) )
+		{
+			pAudioPlayer->PlaySound(SOUND_27, 0, 0, -1, 0, 0, 0, 0);
+			return;
+		}
+        pPlayers[uActiveCharacter]->EquipBody((ITEM_EQUIP_TYPE)v6);
+        if ( pParty->pPickedItem.uItemID == 604 )
+          WetsuitOff(uActiveCharacter);
+        return;
+      case 0xAu:
+        if ( sub_43EE77_ProbablyIfUnderwaterSuitIsEquipped(uActiveCharacter) )
+		{
+			pAudioPlayer->PlaySound(SOUND_27, 0, 0, -1, 0, 0, 0, 0);
+			return;
+		}
+        v52 = 10;
+        v7 = (int)&pPlayers[uActiveCharacter]->pEquipment.uRings;
+        while ( 1 )
+        {
+          if ( !*(int *)v7 )
+          {
+            v8 = pPlayers[uActiveCharacter]->FindFreeInventorySlot();
+            if ( (v8 & 0x80000000u) == 0 )
+			{
+			  v9 = v52;
+			  pParty->pPickedItem.uBodyAnchor = v52 + 1;
+			  memcpy(&pPlayers[uActiveCharacter]->pInventoryItems[v8], &pParty->pPickedItem, sizeof(pPlayers[uActiveCharacter]->pInventoryItems[v8]));
+			  *(&pPlayers[uActiveCharacter]->pEquipment.uShield + v9) = v8 + 1;
+			  pMouse->RemoveHoldingItem();
+              break;
+			}
+          }
+          ++v52;
+          v7 += 4;
+          if ( (signed int)v52 > 15 )
+            break;
+        }
+        if ( v52 == 16 )
+        {
+          v52 = pPlayers[uActiveCharacter]->pEquipment.uRings[6] - 1;
+          memcpy(&_this, &pParty->pPickedItem, sizeof(_this));
+          v10 = (int)((char *)pPlayers[uActiveCharacter] + 36 * v52);
+          *(char *)(v10 + 556) = 0;
+          pParty->pPickedItem.Reset();
+          pParty->SetHoldingItem((ItemGen *)(v10 + 532));
+          _this.uBodyAnchor = 16;
+          v11 = v52 + 1;
+          memcpy((void *)(v10 + 532), &_this, 0x24u);
+          pPlayers[uActiveCharacter]->pEquipment.uRings[6] = v11;
+        }
+        return;
+      case 4u:
+        if ( sub_43EE77_ProbablyIfUnderwaterSuitIsEquipped(uActiveCharacter) )
+		{
+			pAudioPlayer->PlaySound(SOUND_27, 0, 0, -1, 0, 0, 0, 0);
+			return;
+		}
+        if ( !pPlayers[uActiveCharacter]->HasSkill(pSkillType) )
+        {
+          pPlayers[uActiveCharacter]->PlaySound(SPEECH_39, 0);
+          return;
+        }
+        if ( v2 )
+        {
+          --v2;
+          memcpy(&_this, &pParty->pPickedItem, sizeof(_this));
+          v12 = (int)((char *)pPlayers[uActiveCharacter] + 36 * v2);
+          *(char *)(v12 + 556) = 0;
+          pParty->pPickedItem.Reset();
+          pParty->SetHoldingItem((ItemGen *)(v12 + 532));
+          _this.uBodyAnchor = 1;
+          v13 = v2 + 1;
+          v14 = v51 == 0;
+          memcpy((void *)(v12 + 532), &_this, 0x24u);
+          pPlayers[uActiveCharacter]->pEquipment.uShield = v13;
+          if ( v14 )
+            return;
+        }
+        else
+        {
+          v52 = pPlayers[uActiveCharacter]->FindFreeInventorySlot();
+          if ( (v52 & 0x80000000u) != 0 )
+            return;
+          if ( !v51 )
+          {
+            pParty->pPickedItem.uBodyAnchor = 1;
+            v17 = v52 + 1;
+            memcpy(&pPlayers[uActiveCharacter]->pInventoryItems[v52], &pParty->pPickedItem, sizeof(pPlayers[uActiveCharacter]->pInventoryItems[v52]));
+            pPlayers[uActiveCharacter]->pEquipment.uShield = v17;
+            pMouse->RemoveHoldingItem();
+	        return;
+          }
+          memcpy(&_this, &pParty->pPickedItem, sizeof(_this));
+          v15 = (int)((char *)pPlayers[uActiveCharacter] + 36 * (v1 - 1));
+          *(char *)(v15 + 556) = 0;
+          pParty->pPickedItem.Reset();
+          pParty->SetHoldingItem((ItemGen *)(v15 + 532));
+          _this.uBodyAnchor = 1;
+          v16 = v52 + 1;
+          memcpy(&pPlayers[uActiveCharacter]->pInventoryItems[v52], &_this, sizeof(pPlayers[uActiveCharacter]->pInventoryItems[v52]));
+          pPlayers[uActiveCharacter]->pEquipment.uShield = v16;
+        }
+        pPlayers[uActiveCharacter]->pEquipment.uMainHand = 0;
+        return;
+      case 0u:
+      case 0xCu:
+        if ( sub_43EE77_ProbablyIfUnderwaterSuitIsEquipped(uActiveCharacter)
+          && pParty->pPickedItem.uItemID != 64
+          && pParty->pPickedItem.uItemID != 65 )
+		{
+			pAudioPlayer->PlaySound(SOUND_27, 0, 0, -1, 0, 0, 0, 0);
+			return;
+		}
+        if ( !pPlayers[uActiveCharacter]->HasSkill(pSkillType) )
+        {
+          pPlayers[uActiveCharacter]->PlaySound(SPEECH_39, 0);
+          return;
+        }
+        v50 = 0;
+        if ( pSkillType == 2 && (unsigned __int16)(pPlayers[uActiveCharacter]->pActiveSkills[2] & 0xFFC0)
+          || pSkillType == 1 && (signed int)SkillToMastery(pPlayers[uActiveCharacter]->pActiveSkills[1]) >= 3 )
+        {
+
+            v18 = pMouse->uMouseClickX;
+            v19 = pMouse->uMouseClickY;
+
+          v49 = v19;
+          if ( (signed int)v18 >= 560 )
+          {
+            if ( !v51 )
+            {
+              if ( v2 )
+              {
+                --v2;
+                memcpy(&_this, &pParty->pPickedItem, sizeof(_this));
+                v20 = (int)((char *)pPlayers[uActiveCharacter] + 36 * v2);
+                *(char *)(v20 + 556) = 0;
+                pParty->pPickedItem.Reset();
+                pParty->SetHoldingItem((ItemGen *)(v20 + 532));
+                _this.uBodyAnchor = 1;
+                v21 = v2 + 1;
+                v14 = v52 == 12;
+                memcpy((void *)(v20 + 532), &_this, 0x24u);
+                pPlayers[uActiveCharacter]->pEquipment.uShield = v21;
+                if ( !v14 )
+                  return;
+                v22 = _this.uItemID;
+                v50 = v22;
+				if ( v50 )
+                {
+                __debugbreak();  // looks like offset in player's inventory and wand_lut much like case in 0042ECB5
+				  stru_A750F8[uActiveCharacter - 1]._494836(*((int *)&pSpellDatas[66].uNormalLevelRecovery + v50), uActiveCharacter - 1 + 9);
+                }
+				break;
+              }
+              v23 = pPlayers[uActiveCharacter]->FindFreeInventorySlot();
+              if ( (v23 & 0x80000000u) != 0 )
+                return;
+              pParty->pPickedItem.uBodyAnchor = 1;
+              v50 = (unsigned int)&pPlayers[uActiveCharacter]->pInventoryItems[v23];
+              memcpy(&pPlayers[uActiveCharacter]->pInventoryItems[v23], &pParty->pPickedItem, sizeof(pPlayers[uActiveCharacter]->pInventoryItems[v23]));
+              pPlayers[uActiveCharacter]->pEquipment.uShield = v23 + 1;
+              pMouse->RemoveHoldingItem();
+              if ( v52 != 12 )
+                return;
+              v22 = *(int *)v50;
+			  v50 = v22;
+			  if ( v50 )
+              {
+                __debugbreak();  // looks like offset in player's inventory and wand_lut much like case in 0042ECB5
+				stru_A750F8[uActiveCharacter - 1]._494836(*((int *)&pSpellDatas[66].uNormalLevelRecovery + v50), uActiveCharacter - 1 + 9);
+              }
+			  break;
+            }
+          }
+        }
+        if ( !v1 )
+        {
+          v26 = pPlayers[uActiveCharacter]->FindFreeInventorySlot();
+          if ( (v26 & 0x80000000u) != 0 )
+            return;
+          pParty->pPickedItem.uBodyAnchor = 2;
+          v50 = (unsigned int)&pPlayers[uActiveCharacter]->pInventoryItems[v26];
+          memcpy(&pPlayers[uActiveCharacter]->pInventoryItems[v26], &pParty->pPickedItem, sizeof(pPlayers[uActiveCharacter]->pInventoryItems[v26]));
+          pPlayers[uActiveCharacter]->pEquipment.uMainHand = v26 + 1;
+              pMouse->RemoveHoldingItem();
+              if ( v52 != 12 )
+                return;
+              v22 = *(int *)v50;
+			  v50 = v22;
+			  if ( v50 )
+              {
+                __debugbreak();  // looks like offset in player's inventory and wand_lut much like case in 0042ECB5
+				stru_A750F8[uActiveCharacter - 1]._494836(*((int *)&pSpellDatas[66].uNormalLevelRecovery + v50), uActiveCharacter - 1 + 9);
+              }
+			  break;
+        }
+        --v1;
+        memcpy(&_this, &pParty->pPickedItem, sizeof(_this));
+        v24 = (int)((char *)pPlayers[uActiveCharacter] + 36 * v1);
+        *(char *)(v24 + 556) = 0;
+        pParty->pPickedItem.Reset();
+        pParty->SetHoldingItem((ItemGen *)(v24 + 532));
+        _this.uBodyAnchor = 2;
+        v25 = v1 + 1;
+        v14 = v52 == 12;
+        memcpy((void *)(v24 + 532), &_this, 0x24u);
+        pPlayers[uActiveCharacter]->pEquipment.uMainHand = v25;
+        if ( v14 )
+          v50 = _this.uItemID;
+        if ( v51 )
+          pPlayers[uActiveCharacter]->pEquipment.uShield = 0;
+        if ( v50 )
+        {
+                __debugbreak();  // looks like offset in player's inventory and wand_lut much like case in 0042ECB5
+          stru_A750F8[uActiveCharacter - 1]._494836( *((int *)&pSpellDatas[66].uNormalLevelRecovery + v50), uActiveCharacter - 1 + 9);
+        }
+        break;
+      case 1u:
+        if ( sub_43EE77_ProbablyIfUnderwaterSuitIsEquipped(uActiveCharacter) )
+		{
+			pAudioPlayer->PlaySound(SOUND_27, 0, 0, -1, 0, 0, 0, 0);
+			return;
+		}
+        if ( !pPlayers[uActiveCharacter]->HasSkill(pSkillType) )
+        {
+          pPlayers[uActiveCharacter]->PlaySound(SPEECH_39, 0);
+          return;
+        }
+        if ( v1 )
+        {
+          if ( v2 )
+          {
+			pAudioPlayer->PlaySound(SOUND_27, 0, 0, -1, 0, 0, 0, 0);
+			return;
+          }
+          --v1;
+          memcpy(&_this, &pParty->pPickedItem, sizeof(_this));
+          v27 = (int)((char *)pPlayers[uActiveCharacter] + 36 * v1);
+          *(char *)(v27 + 556) = 0;
+          pParty->pPickedItem.Reset();
+          pParty->SetHoldingItem((ItemGen *)(v27 + 532));
+          _this.uBodyAnchor = 2;
+          v28 = v1 + 1;
+          memcpy((void *)(v27 + 532), &_this, 0x24u);
+          pPlayers[uActiveCharacter]->pEquipment.uMainHand = v28;
+        }
+        else
+        {
+          v52 = pPlayers[uActiveCharacter]->FindFreeInventorySlot();
+          if ( (v52 & 0x80000000u) == 0 )
+          {
+            if ( v2 )
+            {
+              memcpy(&_this, &pParty->pPickedItem, sizeof(_this));
+              v29 = (int)((char *)pPlayers[uActiveCharacter] + 36 * (v2 - 1));
+              *(char *)(v29 + 556) = 0;
+              pParty->pPickedItem.Reset();
+              pParty->SetHoldingItem((ItemGen *)(v29 + 532));
+              _this.uBodyAnchor = 2;
+              v30 = v52 + 1;
+              memcpy(&pPlayers[uActiveCharacter]->pInventoryItems[v52], &_this, sizeof(pPlayers[uActiveCharacter]->pInventoryItems[v52]));
+              pPlayers[uActiveCharacter]->pEquipment.uShield = 0;
+              pPlayers[uActiveCharacter]->pEquipment.uMainHand = v30;
+            }
+            else
+            {
+              pParty->pPickedItem.uBodyAnchor = 2;
+              v31 = v52 + 1;
+              memcpy(&pPlayers[uActiveCharacter]->pInventoryItems[v52], &pParty->pPickedItem, sizeof(pPlayers[uActiveCharacter]->pInventoryItems[v52]));
+              pPlayers[uActiveCharacter]->pEquipment.uMainHand = v31;
+              pMouse->RemoveHoldingItem();
+            }
+          }
+        }
+        return;
+      default:
+        pPlayers[uActiveCharacter]->UseItem_DrinkPotion_etc(uActiveCharacter, 0);
+        return;
+    }
+    return;
+  }
+
+    v32 = pMouse->uMouseClickX;
+    v33 = pMouse->uMouseClickY;
+
+  v34 = pRenderer->pActiveZBuffer[v32 + pSRZBufferLineOffsets[v33]] & 0xFFFF;
+  if ( v34 )
+  {
+    v36 = v34 - 1;
+    v37 = (int)((char *)pPlayers[uActiveCharacter] + 36 * v36);
+    v50 = v37;
+    v38 = (ItemGen *)(v37 + 532);
+    v14 = v38->uItemID == 604;
+    v52 = pItemsTable->pItems[v38->uItemID].uEquipType;
+    if ( v14 )
+    {
+      if ( bUnderwater )
+      {
+        pAudioPlayer->PlaySound(SOUND_27, 0, 0, -1, 0, 0, 0, 0);
+        return;
+      }
+      WetsuitOff(uActiveCharacter);
+    }
+    if ( unk_50C9A0 )
+    {
+      *((char *)pGUIWindow_Settings->ptr_1C + 8) &= 0x7Fu;
+      *((short *)pGUIWindow_Settings->ptr_1C + 2) = uActiveCharacter - 1;
+      v39 = v52;
+      *((int *)pGUIWindow_Settings->ptr_1C + 3) = v36;
+      *((short *)pGUIWindow_Settings->ptr_1C + 3) = v39;
+      ptr_50C9A4 = v38;
+      unk_50C9A0 = 0;
+      if ( pMessageQueue_50CBD0->uNumMessages )
+        pMessageQueue_50CBD0->uNumMessages = pMessageQueue_50CBD0->pMessages[0].field_8 != 0;
+      pMouse->SetCursorBitmap("MICON1");
+      dword_50C9D4 = 0;
+      dword_50C9D0 = 113;
+      dword_50C9D8 = 256;
+    }
+    else
+    {
+      if ( !ptr_50C9A4 )
+      {
+        pParty->SetHoldingItem(v38);
+        *(&pPlayers[uActiveCharacter]->uBirthYear + *(char *)(v50 + 556)) = 0;
+        v38->Reset();
+      }
+    }
+  }
+  else
+  {
+    v35 = pPlayers[uActiveCharacter]->pEquipment.uBow;
+    if ( v35 )
+    {
+      auto _a = (ItemGen *)&pPlayers[uActiveCharacter]->pInventoryItems[v35 - 1];
+      pParty->SetHoldingItem(_a);
+      _a->Reset();
+      pPlayers[uActiveCharacter]->pEquipment.uBow = 0;
+    }
+  }
+}
+//----- (004196A0) --------------------------------------------------------
+void CharacterUI_ReleaseButtons()
+{
+  GUIButton *i; // esi@2
+  GUIButton *j; // esi@7
+
+  if ( dword_507CC0_activ_ch )
+  {
+    dword_507CC0_activ_ch = 0;
+    for ( i = pGUIWindow_CurrentMenu->pControlsHead; i; i = j )
+    {
+	  j=i->pNext;
+	  if ( BYTE1(i->field_1C) & 0x80 )
+	  {
+        i->Release();
+		pAllocator->FreeChunk(i);
+	  }
+    }
+    for ( j = pGUIWindow_CurrentMenu->pControlsHead; j; j = j->pNext )
+    {
+      if ( j->msg == UIMSG_InventoryLeftClick)
+      {
+        j->uX = dword_50698C_uX;
+        j->uY = dword_506988_uY;
+        j->uZ = dword_506984_uZ;
+        j->uW = dword_506980_uW;
+        pGUIWindow_CurrentMenu->_41D08F_set_keyboard_control_group(1, 0, 0, 0);
+      }
+    }
+  }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/UI/UIGuilds.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -0,0 +1,347 @@
+#include "..\Items.h"
+#include "..\GUIWindow.h"
+#include "..\mm7_data.h"
+#include "..\texts.h"
+#include "UIHouses.h"
+#include "..\GUIFont.h"
+#include "..\Render.h"
+#include "..\Party.h"
+#include "..\Texture.h"
+#include "..\Mouse.h"
+#include "..\Events2D.h"
+#include "..\AudioPlayer.h"
+#include "..\LOD.h"
+
+//----- (004B5D7C) --------------------------------------------------------
+void GuildDialog()
+{
+  signed int base_teach_price; // ebx@1
+  int v3; // edi@6
+  int result; // eax@11
+  int v6; // esi@13
+  signed int v7; // esi@17
+  int v8; // esi@22
+  signed int v9; // ecx@22
+  char *v10; // eax@22
+  const char *statusbar_string; // ecx@26
+  POINT *v12; // esi@30
+  int v13; // ecx@30
+  void *v14; // ST1C_4@31
+  ItemGen *v15; // ST18_4@31
+  int v16; // ST10_4@31
+  int v17; // eax@31
+  char *v18; // edx@31
+  int v19; // eax@32
+  int pActiveItem; // esi@35
+  int v22; // eax@35
+  unsigned int v23; // eax@36
+  int v24; // eax@39
+  int v25; // eax@40
+  int v26; // ecx@47
+  GUIButton *pButton; // eax@49
+  unsigned int v29; // eax@49
+  char *pText; // eax@52
+  int pTextHeight; // eax@55
+  unsigned int v32; // ecx@55
+  int v33; // eax@55
+  unsigned __int16 pTextColor; // ax@55
+  int v35; // eax@58
+  const char *v36; // ST20_4@61
+  unsigned __int16 v37; // ST1C_2@61
+  int v38; // eax@61
+  int v40; // [sp-14h] [bp-300h]@31
+  int v41; // [sp-10h] [bp-2FCh]@31
+  unsigned __int16 v42; // [sp-Ch] [bp-2F8h]@31
+  char *v43; // [sp-8h] [bp-2F4h]@31
+  unsigned int v44; // [sp-4h] [bp-2F0h]@31
+  char Dest[100]; // [sp+Ch] [bp-2E0h]@3
+  char v46[100]; // [sp+70h] [bp-27Ch]@3
+  char v47[100]; // [sp+D4h] [bp-218h]@3
+  char v48[100]; // [sp+138h] [bp-1B4h]@3
+  char v49[100]; // [sp+19Ch] [bp-150h]@3
+  POINT v50; // [sp+264h] [bp-88h]@30
+  POINT v51; // [sp+26Ch] [bp-80h]@30
+  GUIWindow working_window; // [sp+274h] [bp-78h]@1
+  signed int v53; // [sp+27Ch] [bp-70h]@1
+  signed int v54; // [sp+284h] [bp-68h]@1
+  int pColorWhite; // [sp+2CCh] [bp-20h]@1
+  int pColorYellow; // [sp+2D0h] [bp-1Ch]@1
+  int v58; // [sp+2D4h] [bp-18h]@1
+  unsigned __int8 uPlayerID; // [sp+2DBh] [bp-11h]@31
+  bool pSkillFlag; // [sp+2DCh] [bp-10h]@35
+  int v61; // [sp+2E0h] [bp-Ch]@35
+  int pItemNum;
+  unsigned int v62; // [sp+2E4h] [bp-8h]@13
+  int v63; // [sp+2E8h] [bp-4h]@1
+  int pNumActivItem;
+  int all_text_height;
+
+  memcpy(&working_window, window_SpeakInHouse, sizeof(GUIWindow));
+  working_window.uFrameX = 483;
+  working_window.uFrameWidth = 148;
+  working_window.uFrameZ = 334;
+  pColorWhite = TargetColor(0xFFu, 0xFFu, 0xFFu);
+  pColorYellow = TargetColor(0xFFu, 0xFFu, 0x9Bu);
+  base_teach_price = (signed __int64)(p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].fPriceMultiplier * 500.0);
+  v63 = base_teach_price * (100 - pPlayers[uActiveCharacter]->GetMerchant()) / 100;
+  if ( v63 < base_teach_price / 3 )
+    v63 = base_teach_price / 3;
+  strcpy(Dest, "");
+  strcpy(v46, "");
+  strcpy(v47, "");
+  strcpy(v48, "");
+  strcpy(v49, "");
+  if ( dialog_menu_id != HOUSE_DIALOGUE_MAIN )
+  {
+    if ( dialog_menu_id != HOUSE_DIALOGUE_GUILD_BUY_BOOKS ) //buy skill
+    {
+      if ( sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
+      {
+        if ( pPlayers[uActiveCharacter]->pActiveSkills[dialog_menu_id-36] )
+        {
+          sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[403], pClassNames[dialog_menu_id - 16]); //"You already know the %s skill"
+          ShowStatusBarString(pTmpBuf.data(), 2);
+          pAudioPlayer->PlaySound(SOUND_27, 0, 0, -1, 0, 0, 0, 0);
+        }
+        else
+        {
+          if ( pParty->uNumGold < v63 )
+          {
+            ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2u); //"You don't have enough gold"
+            PlayHouseSound((unsigned int)window_SpeakInHouse->ptr_1C, HouseSound_NotEnoughMoney_TrainingSuccessful);
+          }
+          else
+          {
+            Party::TakeGold(v63);
+            pPlayers[uActiveCharacter]->pActiveSkills[dialog_menu_id-36] = 1;
+          }
+        }
+      }
+      pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
+      return;
+    }
+    pRenderer->DrawTextureIndexed(8, 8, ShopTexture);
+    v6 = 0;
+    v62 = 0;
+    v63 = 32;
+    do
+    {
+      if (pParty->SpellBooksInGuilds[window_SpeakInHouse->par1C-139][v6].uItemID)
+      {
+        pRenderer->DrawTextureTransparent(v63, 0x5Au, ItemsInShopTexture[v6]);
+        ZBuffer_DoFill((int *)((char *)pRenderer->pActiveZBuffer + v62 + 230528), ItemsInShopTexture[v6], v6 + 1);
+      }
+      v63 += 70;
+      v62 += 280;
+      ++v6;
+    }
+    while ( v63 < 452 );
+    v62 = 1680;
+    v7 = 6;
+    v63 = 32;
+    do
+    {
+      if (pParty->SpellBooksInGuilds[window_SpeakInHouse->par1C-139][v7].uItemID)
+      {
+        pRenderer->DrawTextureTransparent(v63, 0xFAu, ItemsInShopTexture[v7]);
+        ZBuffer_DoFill((int *)((char *)pRenderer->pActiveZBuffer + v62 + 638448), ItemsInShopTexture[v7], v7 + 1);
+      }
+      v63 += 70;
+      v62 += 280;
+      ++v7;
+    }
+    while ( v63 < 452 );
+    if ( sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
+    {
+      v8 = 0;
+      v9 = 12;
+      do
+      {
+        if (pParty->SpellBooksInGuilds[window_SpeakInHouse->par1C-139][v9].uItemID )
+          ++v8;
+        --v9;
+      }
+      while ( v9 );
+      GetAsyncKeyState(17);
+      statusbar_string = pGlobalTXT_LocalizationStrings[195]; //"Select the Item to Buy"
+      if ( dialog_menu_id != HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
+        statusbar_string = pGlobalTXT_LocalizationStrings[196]; //"Select the Special Item to Buy"	
+      DrawTextAtStatusBar(statusbar_string, 0);
+      if ( !v8 )
+      {
+        working_window.DrawCurrentTime(__PAIR__( *(int *)&stru_AA1058[3].pSounds[8 * (unsigned int)window_SpeakInHouse->ptr_1C + 44472],
+                       *(int *)&stru_AA1058[3].pSounds[8 * (unsigned int)window_SpeakInHouse->ptr_1C + 44468]) - pParty->uTimePlayed);
+        return;
+      }
+      v12 = pMouse->GetCursorPos(&v51);
+      result = v12->x + pSRZBufferLineOffsets[pMouse->GetCursorPos(&v50)->y];
+      v13 = pRenderer->pActiveZBuffer[result] & 0xFFFF;
+      if ( pRenderer->pActiveZBuffer[result] & 0xFFFF )
+      {
+        v14 = window_SpeakInHouse->ptr_1C;
+        v15 = (ItemGen *)(&pParty->pPlayers[1].uExpressionTimeLength + 18 * (v13 + 12 * (int)v14));
+        v16 = (int)window_SpeakInHouse->ptr_1C;
+        uPlayerID = uActiveCharacter - 1;
+        v17 = pPlayers[uActiveCharacter]->SelectPhrasesTransaction( (ItemGen *)&pParty->pPlayers[1].uExpressionTimeLength + v13 + 12 * (int)v14, BildingType_MagicShop, v16,  2);
+        v18 = BuilDialogueString((char *)pMerchantsBuyPhrases[v17], uPlayerID, v15, (char *)v14, 2, 0);     
+        v19 = pFontArrus->CalcTextHeight(v18, &working_window, 0, 0);
+        working_window.DrawTitleText(pFontArrus, 0, (174 - v19) / 2 + 138,  pColorWhite, v18, 3);
+        return;
+      }
+    }
+    return;
+  }
+  if ( !(unsigned __int16)_449B57_test_bit((unsigned __int8 *)pPlayers[uActiveCharacter]->_guilds_member_bits,
+            guild_mambership_flags[(unsigned int)window_SpeakInHouse->ptr_1C-139]) )
+  { //you must me member
+    v38 = pFontArrus->CalcTextHeight(pNPCTopics[121].pText, &working_window, 0, 0);
+    working_window.DrawTitleText(pFontArrus, 0, (212 - v38) / 2 + 101, pColorYellow, pNPCTopics[121].pText, 3u);
+    pDialogueWindow->pNumPresenceButton = 0;
+    return;
+  }
+  if ( !sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
+    return;
+  v61 = 0;
+  pSkillFlag = false;
+  pActiveItem = pDialogueWindow->pStartingPosActiveItem;
+  v22 = pActiveItem + pDialogueWindow->pNumPresenceButton;
+  pItemNum = 0;
+  if ( pDialogueWindow->pStartingPosActiveItem >= pDialogueWindow->pStartingPosActiveItem + pDialogueWindow->pNumPresenceButton )
+  {
+    sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[544], pPlayers[uActiveCharacter]->pName, pClassNames[pPlayers[uActiveCharacter]->classType]); // "Seek knowledge elsewhere %s the %s"	
+    strcat(pTmpBuf.data(), "\n \n");
+    strcat(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[528]); //"I can offer you nothing further."
+    v19 = pFontArrus->CalcTextHeight(pTmpBuf.data(), &working_window, 0, 0);
+    working_window.DrawTitleText(pFontArrus, 0, (174 - v19) / 2 + 138, pColorYellow, pTmpBuf.data(), 3);
+    return;
+  }
+  all_text_height = 0;
+  do
+  {
+    v23 = pDialogueWindow->GetControl(pActiveItem)->msg_param;
+    if ( v23 == 18 )
+    {
+      all_text_height += pFontArrus->CalcTextHeight(pGlobalTXT_LocalizationStrings[400], &working_window, 0, 0); //"Buy Spells"
+      v61++;
+    }
+    else
+    {
+      if( byte_4ED970_skill_learn_ability_by_class_table[pPlayers[uActiveCharacter]->classType][v23 - 36] 
+          && !pPlayers[uActiveCharacter]->pActiveSkills[v23 - 36] )
+      {
+        all_text_height += pFontArrus->CalcTextHeight(pSkillNames[v23 - 36], &working_window, 0, 0);
+        v61++;
+        pSkillFlag = true;
+      }
+    }
+    ++pActiveItem;
+  }
+  while ( pActiveItem < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem );
+  if ( !v61 )
+  {
+    sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[544], pPlayers[uActiveCharacter]->pName, pClassNames[pPlayers[uActiveCharacter]->classType]); // "Seek knowledge elsewhere %s the %s"	
+    strcat(pTmpBuf.data(), "\n \n");
+    strcat(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[528]); //"I can offer you nothing further."
+    v19 = pFontArrus->CalcTextHeight(pTmpBuf.data(), &working_window, 0, 0);
+    working_window.DrawTitleText(pFontArrus, 0, (174 - v19) / 2 + 138, pColorYellow, pTmpBuf.data(), 3);
+    return;
+  }
+  if ( pSkillFlag )
+  {
+    sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[401], v63); //"Skill Cost: %lu"
+    working_window.DrawTitleText(pFontArrus, 0, 0x92u, 0, pTmpBuf.data(), 3);
+  }
+  v58 = (149 - all_text_height) / v61;
+  if ( v58 > 32 )
+    v58 = 32;
+  v26 = (149 - v61 * v58 - all_text_height) / 2 - v58 / 2 + 162;
+  pNumActivItem = pDialogueWindow->pStartingPosActiveItem;
+  if (pDialogueWindow->pStartingPosActiveItem < pDialogueWindow->pStartingPosActiveItem + pDialogueWindow->pNumPresenceButton )
+  {
+    pItemNum = 2;
+    do
+    {
+      pButton = pDialogueWindow->GetControl(pItemNum);
+      v29 = pButton->msg_param;
+      if ( v29 == 18 )
+      {
+        pText = pGlobalTXT_LocalizationStrings[400]; //"Buy Spells"
+        pButton->uY = v58 + v26;
+        pTextHeight = pFontArrus->CalcTextHeight(pText, &working_window, 0, 0);
+        v32 = pButton->uY;
+        pButton->uHeight = pTextHeight;
+        v33 = v32 + pTextHeight - 1;
+        pButton->uW = v33;
+        v26 = v33;
+        pTextColor = pColorYellow;
+        if ( pDialogueWindow->pCurrentPosActiveItem != pItemNum )
+          pTextColor = pColorWhite;
+        working_window.DrawTitleText(pFontArrus, 0, v32, pTextColor, pText, 3);
+      }
+      else
+      {
+        if ( byte_4ED970_skill_learn_ability_by_class_table[pPlayers[uActiveCharacter]->classType][v29 - 36] 
+             && !pPlayers[uActiveCharacter]->pActiveSkills[v29 - 36] )
+        {
+          pButton->uY = v58 + v26;
+          pTextHeight = pFontArrus->CalcTextHeight(pSkillNames[v29 - 36], &working_window, 0, 0);
+          v32 = pButton->uY;
+          pButton->uHeight = pTextHeight;
+          v33 = v32 + pTextHeight - 1;
+          pButton->uW = v33;
+          v26 = v33;
+          pTextColor = pColorYellow;
+          if ( pDialogueWindow->pCurrentPosActiveItem != pItemNum )
+            pTextColor = pColorWhite;
+          working_window.DrawTitleText(pFontArrus, 0, v32, pTextColor, pSkillNames[v29 - 36], 3);
+        }
+        else
+        {
+          pButton->uW = 0;
+          pButton->uHeight = 0;
+          pButton->uY = 0;
+        }
+      }
+      ++pItemNum;
+    }
+    while ( pItemNum < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem );
+  }
+  return;
+}
+//----- (004BC8D5) --------------------------------------------------------
+void SpellBookGenerator()//for GuildDialogs
+{
+  int pItemNum; // esi@1
+  int v4; // esi@7
+
+  for( int i = 0; i < 12; ++i )
+  {
+    if ( p2DEvents[window_SpeakInHouse->par1C - 1].uType >= 5 )
+    {
+      if ( p2DEvents[window_SpeakInHouse->par1C - 1].uType <= 13 )
+        pItemNum = rand() % word_4F0F30[(signed int)window_SpeakInHouse->par1C - 139] + 11 * p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].uType + 345;
+      else
+      {
+        if ( p2DEvents[window_SpeakInHouse->par1C - 1].uType == 14 )
+          v4 = rand() % 4;
+        else if ( p2DEvents[window_SpeakInHouse->par1C - 1].uType == 15 )
+          v4 = rand() % 3 + 4;
+        else if ( p2DEvents[window_SpeakInHouse->par1C - 1].uType == 16 )
+          v4 = rand() % 2 + 7;
+        if( p2DEvents[window_SpeakInHouse->par1C - 1].uType <= 16 )
+          pItemNum = rand() % word_4F0F30[(signed int)window_SpeakInHouse->par1C - 139] + 11 * v4 + 400;
+      }
+    }
+    if ( pItemNum == 487 )
+    {
+      if ( !(unsigned __int16)_449B57_test_bit(pParty->_quest_bits, 239) )
+        pItemNum = 486;
+    }
+    ItemGen * item_spellbook = &pParty->SpellBooksInGuilds[window_SpeakInHouse->par1C-139][i];
+    item_spellbook->Reset();
+    pParty->SpellBooksInGuilds[window_SpeakInHouse->par1C-139][i].uItemID = pItemNum;
+    pParty->SpellBooksInGuilds[window_SpeakInHouse->par1C-139][i].Identified();
+    ItemsInShopTexture[i] = pIcons_LOD->LoadTexturePtr(pItemsTable->pItems[pItemNum].pIconName, TEXTURE_16BIT_PALETTE);
+  }
+  return;
+}
\ No newline at end of file
--- a/UI/UIHouses.cpp	Sun Jun 23 14:27:32 2013 +0600
+++ b/UI/UIHouses.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -2,31 +2,31 @@
 #define _CRT_SECURE_NO_WARNINGS
 #endif
 
-#include "Texture.h"
-#include "mm7_data.h"
+#include "..\Texture.h"
+#include "..\mm7_data.h"
 #include "UIHouses.h"
-#include "Party.h"
-#include "texts.h"
-#include "Events.h"
-#include "Arcomage.h"
-#include "LOD.h"
-#include "Mouse.h"
-#include "GUIWindow.h"
-#include "GUIFont.h"
-#include "Events2D.h"
-#include "Overlays.h"
-#include "Outdoor.h"
-#include "AudioPlayer.h"
-#include "VideoPlayer.h"
-#include "Monsters.h"
-#include "Viewport.h"
-#include "Keyboard.h"
-#include "IndoorCamera.h"
-#include "MapInfo.h"
-#include "Log.h"
-#include "Game.h"
+#include "..\Party.h"
+#include "..\texts.h"
+#include "..\Events.h"
+#include "..\Arcomage.h"
+#include "..\LOD.h"
+#include "..\Mouse.h"
+#include "..\GUIWindow.h"
+#include "..\GUIFont.h"
+#include "..\Events2D.h"
+#include "..\Overlays.h"
+#include "..\Outdoor.h"
+#include "..\AudioPlayer.h"
+#include "..\VideoPlayer.h"
+#include "..\Monsters.h"
+#include "..\Viewport.h"
+#include "..\Keyboard.h"
+#include "..\IndoorCamera.h"
+#include "..\MapInfo.h"
+#include "..\Log.h"
+#include "..\Game.h"
 
-#include "stru159.h"
+#include "..\stru159.h"
 int uHouse_ExitPic; // weak
 
 int dword_591080; // weak
@@ -314,92 +314,6 @@
         {"Player Castle Bad",           0x24, 0, 25, 0, 0}
 }};
 
-
-
-//----- (0044606A) --------------------------------------------------------
-void PrepareHouse(HOUSE_ID house)
-{
-  //unsigned int v1; // ebx@1
-  //signed int v2; // esi@1
-  //int uExitPic; // edi@1
-  __int16 uExitMapID; // ax@2
-  //int result; // eax@5
-  //unsigned int *v6; // ecx@8
-  int v7; // ebx@11
-  //int v8; // esi@16
-  //unsigned int v9; // eax@16
-  //unsigned int v10; // eax@19
-  //int v11; // ecx@19
-  //char pContainer[36]; // [sp+Ch] [bp-54h]@16
-  int v13; // [sp+30h] [bp-30h]@11
-  int npc_id_arr[6]; // [sp+34h] [bp-2Ch]@1
-  //unsigned int v15; // [sp+4Ch] [bp-14h]@1
-  int uAnimationID; // [sp+50h] [bp-10h]@1
-  //unsigned int *v17; // [sp+54h] [bp-Ch]@3
-  //unsigned int v18; // [sp+58h] [bp-8h]@1
-  //int v19; // [sp+5Ch] [bp-4h]@7
-
-
-  uAnimationID = p2DEvents[house - 1].uAnimationID;
-  memset(npc_id_arr, 0, sizeof(npc_id_arr));
-  uNumDialogueNPCPortraits = 0;
-  uHouse_ExitPic = p2DEvents[house - 1].uExitPicID;
-  if ( uHouse_ExitPic )
-  {
-    uExitMapID = p2DEvents[house - 1]._quest_related;
-    if ( uExitMapID > 0 )
-    {
-	  if(_449B57_test_bit(pParty->_quest_bits,uExitMapID))
-      {
-        uHouse_ExitPic = 0;
-      }
-    }
-  }
-
-  dword_591080 = pAnimatedRooms[uAnimationID].house_npc_id;
-  HouseNPCData[0]=0;
-  uNumDialogueNPCPortraits = 0;
-  if ( dword_591080 )
-  {
-
-    npc_id_arr[0] = dword_591080;
-    uNumDialogueNPCPortraits = 1;
-  }
-
-  for (uint i = 1; i < pNPCStats->uNumNewNPCs; ++i)
-  {
-    if (pNPCStats->pNewNPCData[i].Location2D == house )
-    {
-      if (!(pNPCStats->pNewNPCData[i].uFlags & 0x80))
-      {
-        
-        HouseNPCData[uNumDialogueNPCPortraits+1- (dword_591080 != 0) ? 1 : 0] = &pNPCStats->pNewNPCData[i];     
-        npc_id_arr[uNumDialogueNPCPortraits] = pNPCStats->pNewNPCData[i].uPortraitID;
-         ++uNumDialogueNPCPortraits;
-        if ((pNPCStats->pNewNPCData[i].uFlags & 3) != 2)
-          ++pNPCStats->pNewNPCData[i].uFlags;
-      }
-    }
-
-  }
-
-  for (uint i = 0; i < uNumDialogueNPCPortraits; ++i)
-  {
-   
-    char icon_name[128];
-    sprintfex(icon_name, "npc%03u", npc_id_arr[i]);
-    pDialogueNPCPortraits[i] = pIcons_LOD->LoadTexturePtr(icon_name, TEXTURE_16BIT_PALETTE);
-  }
-
-  if (uHouse_ExitPic)
-  {
-    pDialogueNPCPortraits[uNumDialogueNPCPortraits] = pIcons_LOD->LoadTexturePtr(pHouse_ExitPictures[uHouse_ExitPic], TEXTURE_16BIT_PALETTE);
-    ++uNumDialogueNPCPortraits;
-    uHouse_ExitPic = p2DEvents[house - 1].uExitMapID;
-  }
-}
-
-
 //----- (0044622E) --------------------------------------------------------
 bool EnterHouse(enum HOUSE_ID uHouseID)
 {
@@ -557,6 +471,88 @@
 		}
 	}
 
+//----- (0044606A) --------------------------------------------------------
+void PrepareHouse(HOUSE_ID house)
+{
+  //unsigned int v1; // ebx@1
+  //signed int v2; // esi@1
+  //int uExitPic; // edi@1
+  __int16 uExitMapID; // ax@2
+  //int result; // eax@5
+  //unsigned int *v6; // ecx@8
+  int v7; // ebx@11
+  //int v8; // esi@16
+  //unsigned int v9; // eax@16
+  //unsigned int v10; // eax@19
+  //int v11; // ecx@19
+  //char pContainer[36]; // [sp+Ch] [bp-54h]@16
+  int v13; // [sp+30h] [bp-30h]@11
+  int npc_id_arr[6]; // [sp+34h] [bp-2Ch]@1
+  //unsigned int v15; // [sp+4Ch] [bp-14h]@1
+  int uAnimationID; // [sp+50h] [bp-10h]@1
+  //unsigned int *v17; // [sp+54h] [bp-Ch]@3
+  //unsigned int v18; // [sp+58h] [bp-8h]@1
+  //int v19; // [sp+5Ch] [bp-4h]@7
+
+
+  uAnimationID = p2DEvents[house - 1].uAnimationID;
+  memset(npc_id_arr, 0, sizeof(npc_id_arr));
+  uNumDialogueNPCPortraits = 0;
+  uHouse_ExitPic = p2DEvents[house - 1].uExitPicID;
+  if ( uHouse_ExitPic )
+  {
+    uExitMapID = p2DEvents[house - 1]._quest_related;
+    if ( uExitMapID > 0 )
+    {
+	  if(_449B57_test_bit(pParty->_quest_bits,uExitMapID))
+      {
+        uHouse_ExitPic = 0;
+      }
+    }
+  }
+
+  dword_591080 = pAnimatedRooms[uAnimationID].house_npc_id;
+  HouseNPCData[0]=0;
+  uNumDialogueNPCPortraits = 0;
+  if ( dword_591080 )
+  {
+
+    npc_id_arr[0] = dword_591080;
+    uNumDialogueNPCPortraits = 1;
+  }
+
+  for (uint i = 1; i < pNPCStats->uNumNewNPCs; ++i)
+  {
+    if (pNPCStats->pNewNPCData[i].Location2D == house )
+    {
+      if (!(pNPCStats->pNewNPCData[i].uFlags & 0x80))
+      {
+        
+        HouseNPCData[uNumDialogueNPCPortraits+1- (dword_591080 != 0) ? 1 : 0] = &pNPCStats->pNewNPCData[i];     
+        npc_id_arr[uNumDialogueNPCPortraits] = pNPCStats->pNewNPCData[i].uPortraitID;
+         ++uNumDialogueNPCPortraits;
+        if ((pNPCStats->pNewNPCData[i].uFlags & 3) != 2)
+          ++pNPCStats->pNewNPCData[i].uFlags;
+      }
+    }
+
+  }
+
+  for (uint i = 0; i < uNumDialogueNPCPortraits; ++i)
+  {
+   
+    char icon_name[128];
+    sprintfex(icon_name, "npc%03u", npc_id_arr[i]);
+    pDialogueNPCPortraits[i] = pIcons_LOD->LoadTexturePtr(icon_name, TEXTURE_16BIT_PALETTE);
+  }
+
+  if (uHouse_ExitPic)
+  {
+    pDialogueNPCPortraits[uNumDialogueNPCPortraits] = pIcons_LOD->LoadTexturePtr(pHouse_ExitPictures[uHouse_ExitPic], TEXTURE_16BIT_PALETTE);
+    ++uNumDialogueNPCPortraits;
+    uHouse_ExitPic = p2DEvents[house - 1].uExitMapID;
+  }
+}
 //----- (004B1E92) --------------------------------------------------------
 void PlayHouseSound(unsigned int uHouseID, HouseSoundID sound)
 {
@@ -568,29 +564,6 @@
         806, 0, -1, 0, 0, 0, 0);
 }
 
-//----- (004B4F4F) --------------------------------------------------------
-void JailDialog()
-{
-  const char *v0; // esi@1
-  const char *v1; // ST10_4@1
-  unsigned __int16 v2; // ST0C_2@1
-  int v3; // eax@1
-  GUIWindow v5; // [sp+8h] [bp-54h]@1
-
-  memcpy(&v5, window_SpeakInHouse, sizeof(v5));
-  v0 = pGlobalTXT_LocalizationStrings[672];
-  v1 = pGlobalTXT_LocalizationStrings[672];
-  v5.uFrameX = 483;
-  v5.uFrameWidth = 148;
-  v5.uFrameZ = 334;
-  v2 = TargetColor(0xFFu, 0xFFu, 0x9Bu);
-  v3 = pFontArrus->CalcTextHeight(v0, &v5, 0, 0);
-  v5.DrawTitleText(pFontArrus, 0, (310 - v3) / 2 + 18, v2, v1, 3u);
-}
-
-
-
-
 //----- (004BCACC) --------------------------------------------------------
 void __fastcall OnSelectShopDialogueOption(signed int uMessageParam)
 {
@@ -1613,9 +1586,6 @@
   }
 */
 }
-
-
-
 //----- (004B6943) --------------------------------------------------------
 void __cdecl TravelByTransport()
 {
@@ -1929,12 +1899,6 @@
     }
   }
 }
-
-
-
-
-
-
 //----- (004B68EA) --------------------------------------------------------
 bool __fastcall IsTravelAvailable(int a1)
 {
@@ -2130,8 +2094,6 @@
   return;
 }
 
-
-
 //----- (004B7D7E) --------------------------------------------------------
 void __cdecl BankDialog()
 {
@@ -2715,1961 +2677,6 @@
   }
 }
 
-
-//----- (004B910F) --------------------------------------------------------
-void __cdecl WeaponShopDialog()
-{
-  int v0; // ebx@1
-  int pNumActiveItem; // eax@6
-  signed int v2; // esi@8
-  ItemGen *v4; // eax@11
-  char *v5; // ecx@12
-  unsigned __int8 v6; // dl@13
-  char *v7; // edx@14
-  int v9; // ST08_4@16
-  int v10; // eax@16
-  signed int v11; // esi@18
-  int v12; // ST08_4@21
-  int v13; // eax@21
-  int v14; // edi@23
-  char **v15; // esi@23
-  int v16; // eax@24
-  //int v18; // edx@25
-  int v19; // edi@25
-  unsigned __int8 v20; // sf@25
-  GUIButton *pButton; // esi@27
-  int pNewItem; // eax@27
-  unsigned int v24; // ecx@27
-  int v25; // edx@27
-  unsigned int pColorText; // ax@27
-  signed int v27; // esi@32
-  int v28; // ST08_4@36
-  int v29; // eax@36
-  signed int v32; // esi@41
-  unsigned int v33; // esi@43
-  int v34; // eax@43
-  unsigned int v35; // eax@44
-  int v36; // eax@46
-  __int32 v37; // ecx@51
-  int v40; // eax@53
-  char *v41; // eax@55
-  unsigned int v43; // ecx@55
-  const char **v44; // edx@55
-  int v45; // eax@55
-  int v47; // eax@59
-  const char **v48; // eax@63
-  unsigned int v49; // esi@65
-  Texture *v50; // eax@65
-  int v51; // edi@65
-  int v52; // esi@70
-  Texture *v53; // ST1C_4@70
-  int v54; // edi@70
-  signed int v55; // ecx@73
-  SHORT v56; // di@82
-  bool v57; // eax@82
-  const char *v58; // ecx@84
-  POINT *v59; // esi@89
-  LONG v60; // ecx@90
-  int v61; // eax@90
-  int v62; // ecx@90
-  ItemGen *pItemInShop; // esi@90
-  int v64; // eax@95
-  int all_text_height; // esi@96
-  char **v66; // edi@96
-  int v67; // eax@97
-  int v69; // edx@98
-  int v70; // edi@98
-  int v71;
-  const char **v72; // eax@100
-  int pTextHeight; // eax@100
-  unsigned int v74; // ecx@100
-  int v78; // [sp-14h] [bp-10Ch]@14
-  ItemGen *v79; // [sp-10h] [bp-108h]@12
-  int v80; // [sp-10h] [bp-108h]@14
-  void *v81; // [sp-Ch] [bp-104h]@12
-  unsigned __int16 v82; // [sp-Ch] [bp-104h]@14
-  int v83; // [sp-8h] [bp-100h]@11
-  char *v84; // [sp-8h] [bp-100h]@14
-  __int64 *v85; // [sp-4h] [bp-FCh]@11
-  unsigned int v86; // [sp-4h] [bp-FCh]@14
-  POINT v87; // [sp+Ch] [bp-ECh]@8
-  POINT v88; // [sp+14h] [bp-E4h]@18
-  POINT v89; // [sp+1Ch] [bp-DCh]@89
-  POINT v90; // [sp+24h] [bp-D4h]@19
-  POINT v91; // [sp+2Ch] [bp-CCh]@89
-  POINT v92; // [sp+34h] [bp-C4h]@9
-  POINT v93; // [sp+3Ch] [bp-BCh]@33
-  POINT v94; // [sp+44h] [bp-B4h]@18
-  POINT v95; // [sp+4Ch] [bp-ACh]@32
-  POINT v96; // [sp+54h] [bp-A4h]@18
-  POINT v97; // [sp+5Ch] [bp-9Ch]@32
-  POINT a2; // [sp+64h] [bp-94h]@8
-  POINT v99; // [sp+6Ch] [bp-8Ch]@32
-  POINT v100; // [sp+74h] [bp-84h]@8
-  GUIWindow dialog_window; // [sp+7Ch] [bp-7Ch]@1
-  char *Str; // [sp+D0h] [bp-28h]@55
-  __int32 v103; // [sp+D4h] [bp-24h]@25
-  int pColorYellow; // [sp+D8h] [bp-20h]@1
-  int pColorWhite; // [sp+DCh] [bp-1Ch]@1
-  POINT v106; // [sp+E0h] [bp-18h]@8
-  Player *pPlayer; // [sp+E8h] [bp-10h]@1
-  int pItemNum; // [sp+ECh] [bp-Ch]@26
-  const char **v109; // [sp+F0h] [bp-8h]@26
-  unsigned __int8 v110; // [sp+F7h] [bp-1h]@16
-  int pNumString;
-
-  pPlayer = pPlayers[uActiveCharacter];
-  memcpy(&dialog_window, window_SpeakInHouse, sizeof(dialog_window));
-  dialog_window.uFrameX = 483;
-  dialog_window.uFrameWidth = 148;
-  dialog_window.uFrameZ = 334;
-  pColorWhite = TargetColor(0xFFu, 0xFFu, 0xFFu);
-  pColorYellow = TargetColor(0xE1u, 0xCDu, 0x23u);
-
-  switch(dialog_menu_id)
-  {
-    case HOUSE_DIALOGUE_MAIN:
-    {
-      pNumActiveItem = sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win();
-      if ( pNumActiveItem )
-      {
-        pShopOptions[0] = pGlobalTXT_LocalizationStrings[134];
-        pShopOptions[1] = pGlobalTXT_LocalizationStrings[152];
-        pShopOptions[2] = pGlobalTXT_LocalizationStrings[159];
-        pShopOptions[3] = pGlobalTXT_LocalizationStrings[160];
-        all_text_height = 0;
-        for (int i = 0; i < 4; ++i)//while ( (signed int)v15 < (signed int)&unk_F8B1C8 );
-          all_text_height += pFontArrus->CalcTextHeight(pShopOptions[i], &dialog_window, 0, 0);
-        v103 = (174 - all_text_height) / 4;
-        pNumActiveItem = pDialogueWindow->pStartingPosActiveItem;
-        v19 = (174 - 4 * (174 - all_text_height) / 4 - all_text_height) / 2 - (174 - all_text_height) / 4 / 2 + 138;
-        v20 = -pDialogueWindow->pNumPresenceButton < 0;
-        if ( v20 ^ (pNumActiveItem > pNumActiveItem + pDialogueWindow->pNumPresenceButton ))
-        {
-          pItemNum = 2;
-          pNumString = 0;
-          do
-          {
-            pButton = pDialogueWindow->GetControl(pItemNum);
-            pButton->uY = v103 + v19;
-            pTextHeight = pFontArrus->CalcTextHeight((const char *)pShopOptions[pNumString], &dialog_window, 0, 0);
-            pButton->uHeight = pTextHeight;
-            v19 = pButton->uY + pTextHeight - 1;
-            pButton->uW = v19;
-            pColorText = pColorYellow;
-            if ( pDialogueWindow->pCurrentPosActiveItem != pItemNum )
-              pColorText = pColorWhite;
-            dialog_window.DrawTitleText(pFontArrus, 0, pButton->uY, pColorText, (const char *)pShopOptions[pNumString], 3);
-            ++pItemNum;
-            ++pNumString;
-            pNumActiveItem = pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem;
-          }
-          while ( pItemNum < pNumActiveItem );
-        }
-      }
-      break;
-    }
-
-    case HOUSE_DIALOGUE_SHOP_BUY_STANDARD:
-    {
-      pRenderer->DrawTextureIndexed(8, 8, ShopTexture);
-      v48 = 0;
-      pItemNum = 0;
-      v109 = 0;
-      do
-      {
-        //  if ( pParty->field_777C[9 * (int)&v48[3 * (unsigned int)window_SpeakInHouse->ptr_1C]] )
-        if ( pParty->StandartItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][(int)v48].uItemID)
-        {
-          v49 = word_F8B158[(signed int)v48];
-          v50 = ItemsInShopTexture[(signed int)v48];
-          v49 += 30;
-          v51 = 60 - ((signed int)v50->uTextureWidth >> 1);
-          pRenderer->DrawTextureTransparent(v51 + pItemNum, v49, v50);
-          sub_40F92A(&pRenderer->pActiveZBuffer[v51 + pItemNum + 640 * v49], ItemsInShopTexture[(signed int)v109], (int)((char *)v109 + 1));
-          v48 = v109;
-        }
-        pItemNum += 70;
-        v48 = (const char **)((char *)v48 + 1);
-        v109 = v48;
-      }
-      while ( (signed int)v48 < 6 );
-      pNumActiveItem = sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win();
-      if ( pNumActiveItem )
-      {
-        v55 = 0;
-        v106.x = 0;
-        v106.x = 0;
-        do
-        {
-          if ( pParty->StandartItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][v55].uItemID)//9 * (v55 + 12 * (unsigned int)window_SpeakInHouse->ptr_1C)] )
-            ++v106.x;
-          ++v55;
-        }
-        while ( v55 < 6 );
-        v56 = GetAsyncKeyState(17);
-        v57 = pPlayer->CanSteal();
-        Str = (char *)v57;
-        if ( v56 && v57 )
-        {
-          v58 = pGlobalTXT_LocalizationStrings[185];
-        }
-        else
-        {
-          v58 = pGlobalTXT_LocalizationStrings[195];
-          if ( dialog_menu_id != HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
-            v58 = pGlobalTXT_LocalizationStrings[196];
-        }
-        DrawTextAtStatusBar(v58, 0);
-        if ( v106.x )
-        {
-          v59 = pMouse->GetCursorPos(&v91);
-          pNumActiveItem = v59->x + pSRZBufferLineOffsets[pMouse->GetCursorPos(&v89)->y];
-          if ( pRenderer->pActiveZBuffer[pNumActiveItem] & 0xFFFF )
-          {
-            v60 = (pRenderer->pActiveZBuffer[pNumActiveItem] & 0xFFFF) - 1;
-            v106.x = v60;
-            v61 = (int)window_SpeakInHouse->ptr_1C;//maybe ptr_1C - BuildID_2Events
-            //  v62 = 9 * (v60 + 12 * v61);
-            pItemInShop = (ItemGen *)&pParty->StandartItemsInShops[(int)v61][v60];
-            if ( dialog_menu_id != HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
-              pItemInShop = &pParty->SpecialItemsInShops[(int)v61][v60];
-            if ( !v56 || !Str )
-            {
-              v64 = pPlayer->SelectPhrasesTransaction(pItemInShop, BildingType_WeaponShop, v61, 2);
-              v7 = BuilDialogueString((char *)pMerchantsBuyPhrases[v64], uActiveCharacter - 1, pItemInShop, (char *)window_SpeakInHouse->ptr_1C, 2, 0);
-              pTextHeight = pFontArrus->CalcTextHeight(v7, &dialog_window, 0, 0);
-              dialog_window.DrawTitleText(pFontArrus, 0, (174 - pTextHeight) / 2 + 138, pColorWhite, v7, 3);
-            }
-            else
-            {
-              v7 = BuilDialogueString(pGlobalTXT_LocalizationStrings[181], uActiveCharacter - 1, pItemInShop, (char *)window_SpeakInHouse->ptr_1C, 2, 0);
-              pTextHeight = pFontArrus->CalcTextHeight(v7, &dialog_window, 0, 0);
-              dialog_window.DrawTitleText(pFontArrus, 0, (174 - pTextHeight) / 2 + 138, pColorWhite, v7, 3);
-            }
-          }
-        }
-        else
-        {
-          dialog_window.DrawCurrentTime( pParty->field_3C.field_50[(unsigned int)window_SpeakInHouse->ptr_1C]  - pParty->uTimePlayed);
-          pNumActiveItem = 0; //added
-        }
-      }
-      break;
-    }
-
-    case HOUSE_DIALOGUE_SHOP_SELL:
-    {
-      draw_leather();
-      CharacterUI_InventoryTab_Draw(pPlayers[uActiveCharacter], true);
-      DrawTextAtStatusBar(pGlobalTXT_LocalizationStrings[199], 0);
-      if ( !sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
-        return;
-      if((v11 = pMouse->GetCursorPos(&v96)->x - 14, v106.x = (v11 >> 5) + 14 * ((pMouse->GetCursorPos(&v88)->y - 17) >> 5),
-        pMouse->GetCursorPos(&v94)->x <= 13) || pMouse->GetCursorPos(&v90)->x >= 462 
-        || (pNumActiveItem = pPlayer->GetItemIDAtInventoryIndex((int *)&v106.x), !pNumActiveItem) )
-        return;
-      v79 = (ItemGen *)&pPlayer->pInventoryItems[pNumActiveItem - 1];
-      v13 = pPlayer->SelectPhrasesTransaction(v79, BildingType_WeaponShop, (int)window_SpeakInHouse->ptr_1C, 3);
-      v7 = BuilDialogueString((char *)pMerchantsSellPhrases[v13], uActiveCharacter - 1, v79, (char *)window_SpeakInHouse->ptr_1C, 3, 0);
-      pTextHeight = pFontArrus->CalcTextHeight(v7, &dialog_window, 0, 0);
-      dialog_window.DrawTitleText(pFontArrus, 0, (174 - pTextHeight) / 2 + 138, pColorWhite, v7, 3);
-      break;
-    }
-
-    case HOUSE_DIALOGUE_SHOP_IDENTIFY:
-    {
-      draw_leather();
-      CharacterUI_InventoryTab_Draw(pPlayers[uActiveCharacter], true);
-      DrawTextAtStatusBar(pGlobalTXT_LocalizationStrings[197], 0);
-      if ( !sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
-        return;
-      if((v2 = pMouse->GetCursorPos(&a2)->x - 14, v106.x = (v2 >> 5) + 14 * ((pMouse->GetCursorPos(&v87)->y - 17) >> 5),
-        pMouse->GetCursorPos(&v100)->x <= 13) || pMouse->GetCursorPos(&v92)->x >= 462 
-        || (pNumActiveItem = pPlayer->GetItemIDAtInventoryIndex((int *)&v106.x), !pNumActiveItem) )
-        return;
-      v4 = (ItemGen *)&pPlayer->pInventoryItems[pNumActiveItem - 1];
-      if (!v4->Identified())
-      {
-        v10 = pPlayer->SelectPhrasesTransaction(v4, BildingType_WeaponShop, (int)window_SpeakInHouse->ptr_1C, 4);
-        v7 = BuilDialogueString((char *)pMerchantsIdentifyPhrases[v10], uActiveCharacter - 1, v4, (char *)window_SpeakInHouse->ptr_1C, 4, 0);
-        pTextHeight = pFontArrus->CalcTextHeight(v7, &dialog_window, 0, 0);
-        dialog_window.DrawTitleText(pFontArrus, 0, (174 - pTextHeight) / 2 + 138, pColorWhite, v7, 3);
-      }
-      else
-      {
-        v7 = BuilDialogueString("%24", uActiveCharacter - 1, v4, (char *)window_SpeakInHouse->ptr_1C, 4, 0);
-        pTextHeight = pFontArrus->CalcTextHeight(v7, &dialog_window, 0, 0);
-        dialog_window.DrawTitleText(pFontArrus, 0, (174 - pTextHeight) / 2 + 138, pColorWhite, v7, 3);
-      }
-      break;
-    }
-
-    case HOUSE_DIALOGUE_SHOP_REPAIR:
-    {
-      draw_leather();
-      CharacterUI_InventoryTab_Draw(pPlayers[uActiveCharacter], true);
-      DrawTextAtStatusBar(pGlobalTXT_LocalizationStrings[198], 0);
-      if ( !sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win())
-            return;
-      if( (v2 = pMouse->GetCursorPos(&a2)->x - 14, v106.x = (v2 >> 5) + 14 * ((pMouse->GetCursorPos(&v87)->y - 17) >> 5),
-          pMouse->GetCursorPos(&v100)->x <= 13) || pMouse->GetCursorPos(&v92)->x >= 462
-            || (pNumActiveItem = pPlayer->GetItemIDAtInventoryIndex((int *)&v106.x), !pNumActiveItem)
-            || (!(pPlayer->pOwnItems[pNumActiveItem-1].uAttributes& 2)) )
-            return;
-      v4 = (ItemGen *)&pPlayer->pInventoryItems[pNumActiveItem - 1];
-      v10 = pPlayer->SelectPhrasesTransaction(v4, BildingType_ArmorShop, (int)window_SpeakInHouse->ptr_1C, 5);
-      v7 = BuilDialogueString((char *)pMerchantsRepairPhrases[v10], uActiveCharacter - 1, v4, (char *)window_SpeakInHouse->ptr_1C, 5, 0);
-      pTextHeight = (174 - pFontArrus->CalcTextHeight(v7, &dialog_window, 0, 0)) / 2 + 138;
-      dialog_window.DrawTitleText(pFontArrus, 0, pTextHeight, pColorWhite, v7, 3);
-      return;
-    }
-    break;
-
-    case HOUSE_DIALOGUE_SHOP_DISPLAY_EQUIPMENT:
-    {
-      draw_leather();
-      CharacterUI_InventoryTab_Draw(pPlayers[uActiveCharacter], true);
-      pShopOptions[0] = pGlobalTXT_LocalizationStrings[200];//sell
-      pShopOptions[1] = pGlobalTXT_LocalizationStrings[113];//identify
-      pShopOptions[2] = pGlobalTXT_LocalizationStrings[179];//repair
-      all_text_height = 0;
-      for ( int i = 0; i < 3; ++i )
-        all_text_height += pFontArrus->CalcTextHeight(pShopOptions[i], &dialog_window, 0, 0);
-      v103 = (174 - all_text_height) / 3;
-      pNumActiveItem = pDialogueWindow->pStartingPosActiveItem;
-      v70 = (3 * (58 - (signed int)v103) - all_text_height) / 2 - ((174 - all_text_height) / 3) / 2 + 138;
-      v20 = -pDialogueWindow->pNumPresenceButton < 0;
-      if ( v20 ^ (pNumActiveItem > pNumActiveItem + pDialogueWindow->pNumPresenceButton ))
-      {
-        pItemNum = 2;
-        pNumString = 0;
-        do
-        {
-          pButton = pDialogueWindow->GetControl(pItemNum);
-          pButton->uY = v103 + v70;
-          pTextHeight = pFontArrus->CalcTextHeight((const char *)pShopOptions[pNumString], &dialog_window, 0, 0);
-          pButton->uHeight = pTextHeight;
-          v70 = pButton->uY + pTextHeight - 1;
-          pButton->uW = v70;
-          pColorText = pColorYellow;
-          if ( pDialogueWindow->pCurrentPosActiveItem != pItemNum )
-            pColorText = pColorWhite;
-          dialog_window.DrawTitleText(pFontArrus, 0, pButton->uY, pColorText, (const char *)pShopOptions[pNumString], 3);
-          ++pItemNum;
-          ++pNumString;
-          pNumActiveItem = pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem;
-        }
-        while ( pItemNum < pNumActiveItem );
-      }
-      break;
-    }
-
-    case HOUSE_DIALOGUE_SHOP_BUY_SPECIAL:
-    {
-      pRenderer->DrawTextureIndexed(8, 8, ShopTexture);
-      v109 = 0;
-      pItemNum = 0;
-      do
-      {
-        //   if ( pParty->field_C59C[9 * (int)&v109[3 * (unsigned int)window_SpeakInHouse->ptr_1C] + 724] )
-        if (pParty->SpecialItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][(signed int)v109].uItemID)
-        {
-          v52 = word_F8B158[(signed int)v109] + 30;
-          v53 = ItemsInShopTexture[(signed int)v109];
-          v54 = 60 - ((signed int)v53->uTextureWidth >> 1);
-          pRenderer->DrawTextureTransparent(v54 + pItemNum, word_F8B158[(signed int)v109] + 30, v53);
-          sub_40F92A(&pRenderer->pActiveZBuffer[v54 + pItemNum + 640 * v52], ItemsInShopTexture[(signed int)v109], (int)((char *)v109 + 1));
-        }
-        v109 = (const char **)((char *)v109 + 1);
-        pItemNum += 70;
-      }
-      while ( (signed int)v109 < 6 );
-      pNumActiveItem = sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win();
-      if ( pNumActiveItem )
-      {
-        v55 = 0;
-        v106.x = 0;
-        do
-        {
-          // if ( pParty->field_C59C[9 * (v55 + 12 * (unsigned int)window_SpeakInHouse->ptr_1C) + 724] )
-          if (pParty->SpecialItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][v55].uItemID)
-            ++v106.x;
-          ++v55;
-        }
-        while ( v55 < 6 );
-        v56 = GetAsyncKeyState(17);
-        v57 = pPlayer->CanSteal();
-        Str = (char *)v57;
-        if ( v56 && v57 )
-        {
-          v58 = pGlobalTXT_LocalizationStrings[185];
-        }
-        else
-        {
-          v58 = pGlobalTXT_LocalizationStrings[195];
-          if ( dialog_menu_id != HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
-            v58 = pGlobalTXT_LocalizationStrings[196];
-        }
-        DrawTextAtStatusBar(v58, 0);
-        if ( v106.x )
-        {
-          v59 = pMouse->GetCursorPos(&v91);
-          pNumActiveItem = v59->x + pSRZBufferLineOffsets[pMouse->GetCursorPos(&v89)->y];
-          if ( pRenderer->pActiveZBuffer[pNumActiveItem] & 0xFFFF )
-          {
-            v60 = (pRenderer->pActiveZBuffer[pNumActiveItem] & 0xFFFF) - 1;
-            v106.x = v60;
-            v61 = (int)window_SpeakInHouse->ptr_1C;
-            //  v62 = 9 * (v60 + 12 * v61);
-            pItemInShop = (ItemGen *)&pParty->StandartItemsInShops[(int)v61][v60];
-            if ( dialog_menu_id != HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
-              pItemInShop = &pParty->SpecialItemsInShops[(int)v61][v60];//v63 = (ItemGen *)&pParty->field_C59C[v62 + 724];
-            if ( !v56 || !Str )
-            {
-              v64 = pPlayer->SelectPhrasesTransaction(pItemInShop, BildingType_WeaponShop, v61, 2);
-              v7 = BuilDialogueString((char *)pMerchantsBuyPhrases[v64], uActiveCharacter - 1, pItemInShop, (char *)window_SpeakInHouse->ptr_1C, 2, 0);
-              pTextHeight = pFontArrus->CalcTextHeight(v7, &dialog_window, 0, 0);
-              dialog_window.DrawTitleText(pFontArrus, 0, (174 - pTextHeight) / 2 + 138, pColorWhite, v7, 3);
-            }
-            else
-            {
-              v7 = BuilDialogueString(pGlobalTXT_LocalizationStrings[181], uActiveCharacter - 1, pItemInShop, (char *)window_SpeakInHouse->ptr_1C, 2, 0);
-              pTextHeight = pFontArrus->CalcTextHeight(v7, &dialog_window, 0, 0);
-              dialog_window.DrawTitleText(pFontArrus, 0, (174 - pTextHeight) / 2 + 138, pColorWhite, v7, 3);
-            }
-          }
-        }
-        else
-        {
-          dialog_window.DrawCurrentTime( pParty->field_3C.field_50[(unsigned int)window_SpeakInHouse->ptr_1C]  - pParty->uTimePlayed);
-          pNumActiveItem = 0; //added
-        }
-      }
-      break;
-    }
-
-    case HOUSE_DIALOGUE_LEARN_SKILLS:
-    {
-      if (!sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win())
-        return;
-      v0 = 0;
-      all_text_height = 0;
-      //v32 = (signed __int64)(*(float *)&p2DEvents_minus1__24[13 * (signed int)v31] * 500.0);
-      v32 = (signed __int64)(p2DEvents[(signed int)window_SpeakInHouse->ptr_1C - 1].flt_24 * 500.0);
-      pItemNum = v32 * (100 - pPlayer->GetMerchant()) / 100;
-      if ( pItemNum < v32 / 3 )
-        pItemNum = v32 / 3;
-      pNumActiveItem = pDialogueWindow->pStartingPosActiveItem;
-      if ( pNumActiveItem >= pNumActiveItem + pDialogueWindow->pNumPresenceButton )
-      {
-        sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[544], pPlayer->pName, pClassNames[pPlayer->classType]);
-        strcat(pTmpBuf.data(), "\n \n");
-        strcat(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[528]);
-        pTextHeight = pFontArrus->CalcTextHeight(pTmpBuf.data(), &dialog_window, 0, 0);
-        dialog_window.DrawTitleText(pFontArrus, 0, (174 - pTextHeight) / 2 + 138, pColorYellow, pTmpBuf.data(), 3);
-        return;
-      }
-      do
-      {
-        v35 = pDialogueWindow->GetControl(pNumActiveItem)->msg_param - 36;
-        if ( byte_4ED970_skill_learn_ability_by_class_table[pPlayer->classType][v35] && !pPlayer->pActiveSkills[v35] )
-        {
-          all_text_height += pFontArrus->CalcTextHeight(pSkillNames[v35], &dialog_window, 0, 0);
-          v0++;
-        }
-        ++pNumActiveItem;
-      }
-      while ( pNumActiveItem < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem );
-      if ( !v0 )
-      {
-        sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[544], pPlayer->pName, pClassNames[pPlayer->classType]);
-        strcat(pTmpBuf.data(), "\n \n");
-        strcat(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[528]);
-        pTextHeight = pFontArrus->CalcTextHeight(pTmpBuf.data(), &dialog_window, 0, 0);
-        dialog_window.DrawTitleText(pFontArrus, 0, (174 - pTextHeight) / 2 + 138, pColorYellow, pTmpBuf.data(), 3);
-        return;
-      }
-      sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[401], pItemNum);
-      dialog_window.DrawTitleText(pFontArrus, 0, 0x92u, 0, pTmpBuf.data(), 3);
-      v103 = (149 - all_text_height) / v0;
-      if ( (149 - all_text_height) / v0 > 32 )
-        v103 = 32;
-      pNumActiveItem = pDialogueWindow->pStartingPosActiveItem;
-      v37 = (149 - v0 * v103 - all_text_height) / 2 - v103 / 2 + 162;
-      if ( pNumActiveItem < pNumActiveItem + pDialogueWindow->pNumPresenceButton )
-      {
-        pItemNum = 2;
-        do
-        {
-          pButton = pDialogueWindow->GetControl(pItemNum);
-          v40 = pButton->msg_param - 36;
-          if ( !byte_4ED970_skill_learn_ability_by_class_table[pPlayer->classType][v40] || pPlayer->pActiveSkills[v40] )
-          {
-            pButton->uW = 0;
-            pButton->uHeight = 0;
-            pButton->uY = 0;
-          }
-          else
-          {
-            pButton->uY = v103 + v37;
-            pTextHeight = pFontArrus->CalcTextHeight(pSkillNames[v40], &dialog_window, 0, 0);
-            pButton->uHeight = pTextHeight;
-            v37 = pButton->uY + pTextHeight - 1;
-            pButton->uW = v37;
-            pColorText = pColorYellow;
-            if ( pDialogueWindow->pCurrentPosActiveItem != pItemNum )
-              pColorText = pColorWhite;
-            dialog_window.DrawTitleText(pFontArrus, 0, pButton->uY, pColorText, pSkillNames[v40], 3);
-          }
-          pNumActiveItem = pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem;
-          pItemNum++;
-        }
-        while ( pItemNum < pNumActiveItem );
-      }
-      break;
-    }
-    default:
-    {
-      if( dialog_menu_id > HOUSE_DIALOGUE_SHOP_REPAIR)
-        pNumActiveItem = dialog_menu_id - 96;
-      else
-        pNumActiveItem = dialog_menu_id - 4;
-      break;
-    }
-  }
-}
-
-
-
-//----- (004B9CC6) --------------------------------------------------------
-void __cdecl AlchemistDialog()
-{
-  int v0;
-  int pNumActiveItem; // eax@7
-  signed int v5; // esi@9
-  unsigned int v6; // esi@11
-  int v7; // eax@11
-  unsigned int v8; // eax@12
-  int v9; // eax@14
-  int v10; // ecx@19
-  int v13; // eax@21
-  char *v14; // eax@23
-  int v15; // eax@23
-  unsigned int v16; // ecx@23
-  int v17; // edx@23
-  int v18; // eax@23
-  int v20; // eax@27
-  char *v21; // edx@29
-  int v22; // esi@30
-  char **v23; // edi@30
-  int v24; // eax@31
-  int v26; // edx@32
-  int v27; // edi@32
-  unsigned __int8 v28; // sf@32
-  const char **v30; // eax@34
-  int v31; // eax@34
-  unsigned int v32; // ecx@34
-  int v34; // eax@34
-  signed int v36; // esi@39
-  ItemGen *v37; // eax@42
-  char *v38; // ecx@43
-  unsigned __int8 v39; // dl@44
-  int v40; // eax@46
-  int v41; // ST08_4@47
-  int v42; // eax@47
-  signed int v43; // esi@49
-  int v44; // ST08_4@52
-  int v45; // eax@52
-  Texture *v46; // ecx@55
-  unsigned int v47; // edi@55
-  unsigned int v48; // esi@57
-  int v49; // edx@61
-  Texture *v50; // ecx@67
-  unsigned int v51; // edi@67
-  unsigned int v52; // esi@69
-  int v53; // edx@73
-  Texture *v54; // ecx@79
-  unsigned int v55; // edi@79
-  unsigned int v56; // esi@81
-  int v57; // edx@85
-  Texture *v58; // ecx@91
-  unsigned int v59; // edi@91
-  unsigned int v60; // esi@93
-  int v61; // edx@97
-  signed int v62; // ecx@102
-  SHORT v63; // di@110
-  bool v64; // eax@110
-  const char *v65; // ecx@112
-  POINT *v66; // esi@117
-  int v67; // ecx@118
-  int v68; // eax@118
-  int v69; // ecx@118
-  ItemGen *v70; // esi@118
-  int v71; // eax@123
-  int all_text_height; // edi@125
-  char **v73; // esi@125
-  int v74; // eax@126
-  int pItemNum;
-  int v76; // edx@127
-  int v77; // edi@127
-  GUIButton *pButton; // esi@129
-  const char **v79; // eax@129
-  int pTextHeight; // eax@129
-  unsigned int v81; // ecx@129
-  unsigned int pColorText; // ax@129
-  int v85; // [sp-14h] [bp-ECh]@29
-  int v86; // [sp-10h] [bp-E8h]@29
-  ItemGen *v87; // [sp-10h] [bp-E8h]@43
-  unsigned __int16 v88; // [sp-Ch] [bp-E4h]@29
-  void *v89; // [sp-Ch] [bp-E4h]@43
-  char *v90; // [sp-8h] [bp-E0h]@29
-  int v91; // [sp-8h] [bp-E0h]@42
-  unsigned int v92; // [sp-4h] [bp-DCh]@29
-  __int64 *v93; // [sp-4h] [bp-DCh]@42
-  POINT v94; // [sp+Ch] [bp-CCh]@39
-  POINT v95; // [sp+14h] [bp-C4h]@49
-  POINT v96; // [sp+1Ch] [bp-BCh]@117
-  POINT v97; // [sp+24h] [bp-B4h]@40
-  POINT v98; // [sp+2Ch] [bp-ACh]@117
-  POINT v99; // [sp+34h] [bp-A4h]@49
-  POINT v100; // [sp+3Ch] [bp-9Ch]@50
-  POINT v101; // [sp+44h] [bp-94h]@39
-  POINT v102; // [sp+4Ch] [bp-8Ch]@49
-  POINT a2; // [sp+54h] [bp-84h]@39
-  GUIWindow dialog_window; // [sp+5Ch] [bp-7Ch]@1
-  int v105; // [sp+B0h] [bp-28h]@19
-  int pColorYellow; // [sp+B4h] [bp-24h]@1
-  int Str; // [sp+B8h] [bp-20h]@23
-  int pColorWhite; // [sp+BCh] [bp-1Ch]@1
-  __int32 v109; // [sp+C0h] [bp-18h]@39
-  Player *pPlayer; // [sp+C4h] [bp-14h]@1
-  int pNumString; // [sp+C8h] [bp-10h]@9
-  unsigned int v112; // [sp+CCh] [bp-Ch]@9
-  unsigned __int8 v113; // [sp+D3h] [bp-5h]@47
-  int v114; // [sp+D4h] [bp-4h]@11
-
-  pPlayer = pPlayers[uActiveCharacter];
-  memcpy(&dialog_window, window_SpeakInHouse, sizeof(dialog_window));
-  dialog_window.uFrameX = 483;
-  dialog_window.uFrameWidth = 148;
-  dialog_window.uFrameZ = 334;
-  pColorWhite = TargetColor(0xFFu, 0xFFu, 0xFFu);
-  pColorYellow = TargetColor(0xE1u, 0xCDu, 0x23u);
-  switch(dialog_menu_id)
-  {
-    case HOUSE_DIALOGUE_MAIN:
-    {
-      if ( sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
-      {
-        pShopOptions[0] = pGlobalTXT_LocalizationStrings[134];
-        pShopOptions[1] = pGlobalTXT_LocalizationStrings[152];
-        pShopOptions[2] = pGlobalTXT_LocalizationStrings[159];
-        pShopOptions[3] = pGlobalTXT_LocalizationStrings[160];
-        all_text_height = 0;
-        for (int i = 0; i < 4; ++i)//while ( (signed int)v15 < (signed int)&unk_F8B1C8 );
-          all_text_height += pFontArrus->CalcTextHeight(pShopOptions[i], &dialog_window, 0, 0);
-        Str = (174 - all_text_height) / 4;
-        pNumActiveItem = pDialogueWindow->pStartingPosActiveItem;
-        v76 = pNumActiveItem + pDialogueWindow->pNumPresenceButton;
-        v77 = (174 - 4 * (174 - all_text_height) / 4 - all_text_height) / 2 - (174 - all_text_height) / 4 / 2 + 138;
-        v28 = -pDialogueWindow->pNumPresenceButton < 0;
-        if ( v28 ^ (pNumActiveItem > v76) )
-        {
-          pItemNum = 2;
-          pNumString = 0;
-          do
-          {
-            pButton = pDialogueWindow->GetControl(pItemNum);
-            pButton->uY = Str + v77;
-            pTextHeight = pFontArrus->CalcTextHeight((const char *)pShopOptions[pNumString], &dialog_window, 0, 0);
-            pButton->uHeight = pTextHeight;
-            v77 = pButton->uY + pTextHeight - 1;
-            pButton->uW = v77;
-            pColorText = pColorYellow;
-            if ( pDialogueWindow->pCurrentPosActiveItem != pItemNum )
-              pColorText = pColorWhite;
-            dialog_window.DrawTitleText(pFontArrus, 0, pButton->uY, pColorText, (const char *)pShopOptions[pNumString], 3);
-            ++pItemNum;
-            ++pNumString;
-            pNumActiveItem = pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem;
-          }
-          while ( pItemNum < pNumActiveItem );
-        }
-      }
-      return;
-    }
-    case HOUSE_DIALOGUE_SHOP_BUY_STANDARD:
-    {
-      pRenderer->DrawTextureIndexed(8, 8, ShopTexture);
-      v114 = 0;
-      do
-      {
-        if ( pParty->StandartItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][v114].uItemID)
-        {
-          v46 = ItemsInShopTexture[v114];
-          v47 = 152 - v46->uTextureHeight;
-          if ( (signed int)v47 < 1 )
-            v47 = 0;
-          v48 = 75 * v114 - v46->uTextureWidth / 2 + 40;
-          if ( v114 )
-          {
-            if ( v114 == 5 )
-            {
-              v49 = ItemsInShopTexture[5]->uTextureWidth;
-              if ( (signed int)v48 > 457 - v49 )
-                v48 = 457 - v49;
-            }
-          }
-          else if ( (signed int)v48 < 18 )
-            v48 = 18;
-          pRenderer->DrawTextureTransparent(v48, v47, v46);
-          sub_40F92A(&pRenderer->pActiveZBuffer[v48 + 640 * v47], ItemsInShopTexture[v114], v114 + 1);
-        }
-        ++v114;
-      }
-      while ( v114 < 6 );
-      v114 = 0;
-      do
-      {
-        if ( pParty->StandartItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][v114 + 6].uItemID)
-        {
-          v50 = ItemsInShopTexture[v114 + 6];
-          v51 = 308 - v50->uTextureHeight;
-          if ( (signed int)v51 < 1 )
-            v51 = 0;
-          v52 = 75 * v114 - v50->uTextureWidth / 2 + 40;
-          if ( v114 )
-          {
-            if ( v114 == 5 )
-            {
-              v53 = ItemsInShopTexture[11]->uTextureWidth;
-              if ( (signed int)v52 > 457 - v53 )
-                v52 = 457 - v53;
-            }
-          }
-          else
-          {
-            if ( (signed int)v52 < 18 )
-              v52 = 18;
-          }
-          pRenderer->DrawTextureTransparent(v52, v51, v50);
-          sub_40F92A(&pRenderer->pActiveZBuffer[v52 + 640 * v51], ItemsInShopTexture[v114 + 6], v114 + 7);
-        }
-        ++v114;
-      }
-      while ( v114 < 6 );
-      if ( sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
-      {
-        v62 = 0;
-        v109 = 0;
-        do
-        {
-          if ( pParty->StandartItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][v62].uItemID)
-            ++v109;
-          ++v62;
-        }
-        while ( v62 < 12 );
-        v63 = GetAsyncKeyState(17);
-        v64 = pPlayer->CanSteal();
-        Str = v64;
-        if ( v63 && v64 )
-        {
-          v65 = pGlobalTXT_LocalizationStrings[185];
-        }
-        else if ( dialog_menu_id == HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
-        {
-          v65 = pGlobalTXT_LocalizationStrings[195];
-        }
-        else
-        {
-          v65 = pGlobalTXT_LocalizationStrings[196];
-        }
-        DrawTextAtStatusBar(v65, 0);
-        if ( !v109 )
-        {
-          dialog_window.DrawCurrentTime( pParty->field_3C.field_50[ (unsigned int)window_SpeakInHouse->ptr_1C] - pParty->uTimePlayed);
-          return;
-        }
-        v66 = pMouse->GetCursorPos(&v98);
-        pNumActiveItem = v66->x + pSRZBufferLineOffsets[pMouse->GetCursorPos(&v96)->y];
-        if ( pRenderer->pActiveZBuffer[pNumActiveItem] & 0xFFFF )
-        {
-          v67 = (pRenderer->pActiveZBuffer[pNumActiveItem] & 0xFFFF) - 1;
-          v70 = (ItemGen *)&pParty->StandartItemsInShops[(int)window_SpeakInHouse->ptr_1C][v67];
-          if ( dialog_menu_id != HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
-            v70 = &pParty->SpecialItemsInShops[(int)window_SpeakInHouse->ptr_1C][v67];//v70 = (ItemGen *)&pParty->field_C59C[v69 + 724];
-          if ( !v63 || !Str )
-          {
-            v71 = pPlayer->SelectPhrasesTransaction(v70, BildingType_AlchemistShop, (int)window_SpeakInHouse->ptr_1C, 2);
-            v38 = (char *)pMerchantsBuyPhrases[v71];
-          }
-          else
-          {
-            v38 = pGlobalTXT_LocalizationStrings[181];
-          }
-          v21 = BuilDialogueString(v38, uActiveCharacter - 1, v70, (char *)window_SpeakInHouse->ptr_1C, 2, 0);
-          v40 = pFontArrus->CalcTextHeight(v21, &dialog_window, 0, 0);
-          dialog_window.DrawTitleText(pFontArrus, 0, (174 - v40) / 2 + 138, pColorWhite, v21, 3);
-          return ;
-        }
-      }
-      return;
-    }
-    case HOUSE_DIALOGUE_SHOP_SELL:
-    {
-      draw_leather();
-      CharacterUI_InventoryTab_Draw(pPlayers[uActiveCharacter], true);
-      DrawTextAtStatusBar(pGlobalTXT_LocalizationStrings[199], 0);
-      if ( !sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
-        return;
-      if ((v43 = pMouse->GetCursorPos(&v99)->x - 14, v109 = (v43 >> 5) + 14 * ((pMouse->GetCursorPos(&v95)->y - 17) >> 5),
-           pMouse->GetCursorPos(&v102)->x <= 13) || pMouse->GetCursorPos(&v100)->x >= 462 
-          || (pNumActiveItem = pPlayer->GetItemIDAtInventoryIndex((int *)&v109), !pNumActiveItem) )
-          return;
-      v87 = (ItemGen *)&pPlayer->pInventoryItems[pNumActiveItem - 1];
-      v45 = pPlayer->SelectPhrasesTransaction(v87, BildingType_AlchemistShop, (int)window_SpeakInHouse->ptr_1C, 3);
-      v21 = BuilDialogueString((char *)pMerchantsSellPhrases[v45], uActiveCharacter - 1, v87, (char *)window_SpeakInHouse->ptr_1C, 3, 0);
-      pTextHeight = pFontArrus->CalcTextHeight(v21, &dialog_window, 0, 0);
-      dialog_window.DrawTitleText(pFontArrus, 0, (174 - pTextHeight) / 2 + 138, pColorWhite, v21, 3);
-      return; 
-    }
-    case HOUSE_DIALOGUE_SHOP_IDENTIFY:
-    {
-      draw_leather();
-      CharacterUI_InventoryTab_Draw(pPlayers[uActiveCharacter], true);
-      DrawTextAtStatusBar(pGlobalTXT_LocalizationStrings[197], 0);
-      if ( sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
-        return;
-      if ((v36 = pMouse->GetCursorPos(&a2)->x - 14, v109 = (v36 >> 5) + 14 * ((pMouse->GetCursorPos(&v94)->y - 17) >> 5),
-          pMouse->GetCursorPos(&v101)->x <= 13) || pMouse->GetCursorPos(&v97)->x >= 462
-         || (pNumActiveItem = pPlayer->GetItemIDAtInventoryIndex((int *)&v109), !pNumActiveItem) )
-        return;
-      v37 = (ItemGen *)&pPlayer->pInventoryItems[pNumActiveItem - 1];
-      if (!v37->Identified())
-      {
-        v42 = pPlayer->SelectPhrasesTransaction(v37, BildingType_AlchemistShop, (int)window_SpeakInHouse->ptr_1C, 4);
-        v38 = (char *)pMerchantsIdentifyPhrases[v42];
-      }
-      else
-      {
-        v38 = "%24";
-      }
-      v21 = BuilDialogueString(v38, uActiveCharacter - 1, v37, (char *)window_SpeakInHouse->ptr_1C, 4, 0);
-      v40 = pFontArrus->CalcTextHeight(v21, &dialog_window, 0, 0);
-      dialog_window.DrawTitleText(pFontArrus, 0, (174 - v40) / 2 + 138, pColorWhite, v21, 3);
-      return;
-    }
-    case HOUSE_DIALOGUE_SHOP_DISPLAY_EQUIPMENT:
-    {
-      draw_leather();
-      CharacterUI_InventoryTab_Draw(pPlayers[uActiveCharacter], true);
-      pShopOptions[0] = pGlobalTXT_LocalizationStrings[200];
-      pShopOptions[1] = pGlobalTXT_LocalizationStrings[113];
-      all_text_height = 0;
-      for ( int i = 0; i < 2; ++i )
-        all_text_height += pFontArrus->CalcTextHeight(pShopOptions[i], &dialog_window, 0, 0);
-      Str = (174 - all_text_height) / 2;
-      pNumActiveItem = pDialogueWindow->pStartingPosActiveItem;
-      v26 = pNumActiveItem + pDialogueWindow->pNumPresenceButton;
-      v27 = (2 * (87 - (174 - all_text_height) / 2) - all_text_height) / 2 - (174 - all_text_height) / 2 / 2 + 138;
-      v28 = -pDialogueWindow->pNumPresenceButton < 0;
-      if ( v28 ^ (pNumActiveItem > v26) )
-      {
-        pItemNum = 2;
-        pNumString = 0;
-        do
-        {
-          pButton = pDialogueWindow->GetControl(pItemNum);
-          pButton->uY = Str + v27;
-          pTextHeight = pFontArrus->CalcTextHeight((const char *)pShopOptions[pNumString], &dialog_window, 0, 0);
-          pButton->uHeight = pTextHeight;
-          v27 = pButton->uY + pTextHeight - 1;
-          pButton->uW = v27;
-          pColorText = pColorYellow;
-          if ( pDialogueWindow->pCurrentPosActiveItem != pItemNum )
-            pColorText = pColorWhite;
-          dialog_window.DrawTitleText(pFontArrus, 0, pButton->uY, pColorText, (const char *)pShopOptions[pNumString], 3);
-          ++pItemNum;
-          ++pNumString;
-          pNumActiveItem = pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem;
-        }
-        while ( pItemNum < pNumActiveItem );
-      }
-      return;
-    }
-    case HOUSE_DIALOGUE_SHOP_BUY_SPECIAL:
-    {
-      pRenderer->DrawTextureIndexed(8, 8, ShopTexture);
-      v114 = 0;
-      do
-      {
-        if (pParty->SpecialItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][v114].uItemID)
-        {
-          v54 = ItemsInShopTexture[v114];
-          v55 = 152 - v54->uTextureHeight;
-          if ( (signed int)v55 < 1 )
-            v55 = 0;
-          v56 = 75 * v114 - v54->uTextureWidth / 2 + 40;
-          if ( v114 )
-          {
-            if ( v114 == 5 )
-            {
-              v57 = ItemsInShopTexture[5]->uTextureWidth;
-              if ( (signed int)v56 > 457 - v57 )
-                v56 = 457 - v57;
-            }
-          }
-          else
-          {
-            if ( (signed int)v56 < 18 )
-              v56 = 18;
-          }
-          pRenderer->DrawTextureTransparent(v56, v55, v54);
-          sub_40F92A(&pRenderer->pActiveZBuffer[v56 + 640 * v55], ItemsInShopTexture[v114], v114 + 1);
-        }
-        ++v114;
-      }
-      while ( v114 < 6 );
-      v114 = 0;
-      do
-      {
-        if (pParty->SpecialItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][(signed int)v114 + 6].uItemID) //not itemid
-        {
-          v58 = ItemsInShopTexture[v114 + 6];
-          v59 = 308 - v58->uTextureHeight;
-          if ( (signed int)v59 < 1 )
-            v59 = 0;
-          v60 = 75 * v114 - v58->uTextureWidth / 2 + 40;
-          if ( v114 )
-          {
-            if ( v114 == 5 )
-            {
-              v61 = ItemsInShopTexture[11]->uTextureWidth;
-              if ( (signed int)v60 > 457 - v61 )
-                v60 = 457 - v61;
-            }
-          }
-          else
-          {
-            if ( (signed int)v60 < 18 )
-              v60 = 18;
-          }
-          pRenderer->DrawTextureTransparent(v60, v59, v58);
-          sub_40F92A(&pRenderer->pActiveZBuffer[v60 + 640 * v59], ItemsInShopTexture[v114 + 6], v114 + 7);
-        }
-        ++v114;
-      }
-      while ( v114 < 6 );
-      if ( sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
-      {
-        v62 = 0;
-        v109 = 0;
-        do
-        {
-          if (pParty->SpecialItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][v62].uItemID)
-            ++v109;
-          ++v62;
-        }
-        while ( v62 < 12 );
-        v63 = GetAsyncKeyState(17);
-        v64 = pPlayer->CanSteal();
-        Str = v64;
-        if ( v63 && v64 )
-        {
-          v65 = pGlobalTXT_LocalizationStrings[185];
-        }
-        else
-        {
-          v65 = pGlobalTXT_LocalizationStrings[195];
-          if ( dialog_menu_id != HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
-            v65 = pGlobalTXT_LocalizationStrings[196];
-        }
-        DrawTextAtStatusBar(v65, 0);
-        if ( !v109 )
-        {
-          dialog_window.DrawCurrentTime( pParty->field_3C.field_50[ (unsigned int)window_SpeakInHouse->ptr_1C] - pParty->uTimePlayed);
-          return;
-        }
-        v66 = pMouse->GetCursorPos(&v98);
-        pNumActiveItem = v66->x + pSRZBufferLineOffsets[pMouse->GetCursorPos(&v96)->y];
-        if ( pRenderer->pActiveZBuffer[pNumActiveItem] & 0xFFFF )
-        {
-          v67 = (pRenderer->pActiveZBuffer[pNumActiveItem] & 0xFFFF) - 1;
-          v109 = v67;
-          v68 = (int)window_SpeakInHouse->ptr_1C;
-          //  v69 = 9 * (v67 + 12 * v68);
-          v70 = (ItemGen *)&pParty->StandartItemsInShops[v68][v67];
-          if ( dialog_menu_id != HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
-            v70 = &pParty->SpecialItemsInShops[(int)v68][v67];//v70 = (ItemGen *)&pParty->field_C59C[v69 + 724];
-          if ( !v63 || !Str )
-          {
-            v71 = pPlayer->SelectPhrasesTransaction(v70, BildingType_AlchemistShop, v68, 2);
-            v38 = (char *)pMerchantsBuyPhrases[v71];
-          }
-          else
-          {
-            v38 = pGlobalTXT_LocalizationStrings[181];
-          }
-          v21 = BuilDialogueString(v38, uActiveCharacter - 1, v70, (char *)window_SpeakInHouse->ptr_1C, 2, 0);
-          v40 = pFontArrus->CalcTextHeight(v21, &dialog_window, 0, 0);
-          dialog_window.DrawTitleText(pFontArrus, 0, (174 - v40) / 2 + 138, pColorWhite, v21, 3);
-          return;
-        }
-      }
-      return;
-    }
-    case HOUSE_DIALOGUE_LEARN_SKILLS:
-    {
-      if (!sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win())
-        return;
-      all_text_height = 0;
-      v5 = (signed __int64)(p2DEvents[(signed int)window_SpeakInHouse->ptr_1C - 1].flt_24 * 500.0);
-      pItemNum = v5 * (100 - pPlayer->GetMerchant()) / 100;
-      if ( pItemNum < v5 / 3 )
-        pItemNum = v5 / 3;
-      pNumActiveItem = pDialogueWindow->pStartingPosActiveItem;
-      v114 = 0;
-      if ( pNumActiveItem >= pNumActiveItem + pDialogueWindow->pNumPresenceButton )
-      {
-        sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[544], pPlayer->pName, pClassNames[pPlayer->classType]);
-        strcat(pTmpBuf.data(), "\n \n");
-        strcat(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[528]);
-        v40 = pFontArrus->CalcTextHeight(pTmpBuf.data(), &dialog_window, 0, 0);
-        dialog_window.DrawTitleText(pFontArrus, 0, (174 - v40) / 2 + 138, pColorYellow, pTmpBuf.data(), 3);
-        return;
-      }
-      do
-      {
-        v8 = pDialogueWindow->GetControl(pNumActiveItem)->msg_param - 36;
-        if ( byte_4ED970_skill_learn_ability_by_class_table[pPlayer->classType][v8] && !pPlayer->pActiveSkills[v8] )
-        {
-          all_text_height = pFontArrus->CalcTextHeight(pSkillNames[v8], &dialog_window, 0, 0);
-          ++v114;
-        }
-        ++pNumActiveItem;
-      }
-      while ( pNumActiveItem < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem );
-      if ( !v114 )
-      {
-        sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[544], pPlayer->pName, pClassNames[pPlayer->classType]);
-        strcat(pTmpBuf.data(), "\n \n");
-        strcat(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[528]);
-        v40 = pFontArrus->CalcTextHeight(pTmpBuf.data(), &dialog_window, 0, 0);
-        dialog_window.DrawTitleText(pFontArrus, 0, (174 - v40) / 2 + 138, pColorYellow, pTmpBuf.data(), 3);
-        return;
-      }
-      if ( v114 )
-      {
-        sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[401], pItemNum);
-        dialog_window.DrawTitleText(pFontArrus, 0, 0x92u, 0, pTmpBuf.data(), 3);
-        v18 = (149 - all_text_height) / v114;
-        if ( (149 - all_text_height) / v114 > 32 )
-          v18 = 32;
-        pNumActiveItem = pDialogueWindow->pStartingPosActiveItem;
-        v105 = (149 - v114 * v18 - all_text_height) / 2 - v18 / 2 + 162;
-        if ( pNumActiveItem < pNumActiveItem + pDialogueWindow->pNumPresenceButton )
-        {
-          pItemNum = 2;
-          do
-          {
-            pButton = pDialogueWindow->GetControl(pItemNum);
-            v13 = pButton->msg_param - 36;
-            if ( !byte_4ED970_skill_learn_ability_by_class_table[pPlayer->classType][v13] || pPlayer->pActiveSkills[v13] )
-            {
-              pButton->uW = 0;
-              pButton->uHeight = 0;
-              pButton->uY = 0;
-            }
-            else
-            {
-              pButton->uY = v18 + v105;
-              pTextHeight = pFontArrus->CalcTextHeight(pSkillNames[v13], &dialog_window, 0, 0);
-              pButton->uHeight = pTextHeight;
-              v105 = pButton->uY + pTextHeight - 1;
-              pButton->uW = v105;
-              pColorText = pColorYellow;
-              if ( pDialogueWindow->pCurrentPosActiveItem != pItemNum )
-                pColorText = pColorWhite;
-              dialog_window.DrawTitleText(pFontArrus, 0, pButton->uY, pColorText, pSkillNames[v13], 3);
-            }
-            pNumActiveItem = pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem;
-            pItemNum++;
-          }
-          while ( pItemNum < pNumActiveItem );
-        }
-        return;
-      }
-    }
-    default:
-    {
-      return;// (POINT *)dialog_menu_id - 96;
-    }
-  }
-}
-
-//----- (004BA928) --------------------------------------------------------
-void __cdecl ArmorShopDialog()
-{
-  signed int v1; // esi@8
-  unsigned int v2; // eax@10
-  ItemGen *v3; // eax@11
-  char *v5; // ecx@12
-  char *v6; // eax@13
-  int v8; // eax@15
-  signed int v9; // esi@17
-  unsigned int v10; // eax@19
-  char *v11; // edi@19
-  int v12; // ST08_4@20
-  int v13; // eax@20
-  char *v15; // ecx@20
-  char **v16; // edi@22
-  int all_text_height; // ebx@22
-  char **v18; // esi@22
-  int v19; // eax@23
-  GUIWindow *v20; // ecx@24
-  int v21; // eax@24
-  int v22; // edx@24
-  int v23; // ebx@24
-  unsigned __int8 v24; // sf@24
-  GUIButton *pButton; // eax@26
-  unsigned int v28; // ecx@26
-  int v29; // edx@26
-  signed int v31; // esi@31
-  unsigned int v32; // eax@33
-  int v33; // eax@34
-  int v35; // eax@35
-  char *v36; // edx@36
-  signed int v38; // esi@42
-  unsigned int v39; // esi@44
-  int v40; // eax@44
-  unsigned int v41; // eax@45
-  int v42; // eax@47
-  int v43; // ecx@52
-  int v46; // eax@54
-  unsigned int v49; // ecx@56
-  int v51; // eax@56
-  int v53; // eax@60
-  int textureH; // eax@60
-  signed int textureW; // ebx@65
-  Texture *v56; // eax@67
-  unsigned int pY_item; // edi@68
-  Texture *v58; // ST1C_4@68
-  int v59; // eax@68
-  int v60; // edi@69
-  signed int v61; // ebx@73
-  Texture *v62; // eax@75
-  int v63; // edi@76
-  Texture *v64; // ST1C_4@76
-  unsigned int v65; // ST18_4@76
-  int v66; // eax@76
-  int v67; // edi@77
-  signed int v68; // ecx@81
-  const char *pStatusText; // ecx@91
-  void *v72; // eax@95
-  POINT *v73; // esi@97
-  int v74; // ecx@97
-  int v75; // eax@98
-  int v76; // ecx@98
-  ItemGen *selected_item; // ecx@99
-  unsigned __int8 v78; // bl@104
-  int v80; // ebx@105
-  char **v81; // esi@105
-  int v82; // eax@106
-  int v86; // ebx@107
-  int pTextHeight; // eax@109
-  unsigned int v90; // ecx@109
-  int pNumString; // edx@109
-  unsigned __int16 pTextColor; // ax@109
-  signed int v93; // edx@114
-  POINT *v94; // edi@120
-  __int32 v95; // ecx@120
-  void *v96; // ST14_4@122
-  unsigned __int8 v97; // bl@122
-  ItemGen *v98; // ST10_4@122
-  int v99; // eax@122
-  char *v100; // eax@122
-  const char *v101; // ST18_4@122
-  unsigned __int16 v102; // ST14_2@122
-  int v103; // eax@122
-  signed int v104; // edi@123
-  Texture *v105; // eax@125
-  int v106; // ebx@126
-  unsigned int v108; // ST18_4@126
-  int v109; // eax@126
-  int v110; // ebx@127
-  GUIWindow *v111; // [sp-18h] [bp-11Ch]@36
-  unsigned int v112; // [sp-14h] [bp-118h]@13
-  int v113; // [sp-14h] [bp-118h]@36
-  unsigned int v115; // [sp-10h] [bp-114h]@13
-  ItemGen *v116; // [sp-10h] [bp-114h]@20
-  int v117; // [sp-10h] [bp-114h]@36
-  unsigned __int16 v119; // [sp-Ch] [bp-110h]@13
-  char *v121; // [sp-8h] [bp-10Ch]@13
-  int v122; // [sp-8h] [bp-10Ch]@20
-  unsigned int v123; // [sp-4h] [bp-108h]@13
-  __int64 *v124; // [sp-4h] [bp-108h]@20
-  int v125; // [sp-4h] [bp-108h]@68
-  int v126; // [sp-4h] [bp-108h]@76
-  int v127; // [sp-4h] [bp-108h]@126
-  POINT v128; // [sp+Ch] [bp-F8h]@8
-  POINT v129; // [sp+14h] [bp-F0h]@18
-  char v130; // [sp+1Ch] [bp-E8h]@120
-  POINT a2; // [sp+24h] [bp-E0h]@8
-  POINT v132; // [sp+2Ch] [bp-D8h]@120
-  POINT v133; // [sp+34h] [bp-D0h]@17
-  POINT v134; // [sp+3Ch] [bp-C8h]@97
-  POINT v135; // [sp+44h] [bp-C0h]@31
-  POINT v136; // [sp+4Ch] [bp-B8h]@97
-  POINT v137; // [sp+54h] [bp-B0h]@17
-  POINT v138; // [sp+5Ch] [bp-A8h]@32
-  POINT v139; // [sp+64h] [bp-A0h]@17
-  POINT v140; // [sp+6Ch] [bp-98h]@31
-  POINT v141; // [sp+74h] [bp-90h]@8
-  POINT v142; // [sp+7Ch] [bp-88h]@31
-  POINT v143; // [sp+84h] [bp-80h]@9
-  GUIWindow dialog_window; // [sp+8Ch] [bp-78h]@1
-  int v146; // [sp+E4h] [bp-20h]@24
-  int pYellowColor; // [sp+E8h] [bp-1Ch]@1
-  int pWhiteColor; // [sp+ECh] [bp-18h]@1
-  __int32 pItemCount; // [sp+F0h] [bp-14h]@8
-  int v152; // [sp+FCh] [bp-8h]@24
-  int v153; // [sp+100h] [bp-4h]@44
-  int th;
-  short text_color;
-  int pActiveButton;
-
-  memcpy(&dialog_window, window_SpeakInHouse, sizeof(dialog_window));
-  dialog_window.uFrameX = 483;
-  dialog_window.uFrameWidth = 148;
-  dialog_window.uFrameZ = 334;
-  pWhiteColor = TargetColor(0xFFu, 0xFFu, 0xFFu);
-  pYellowColor = TargetColor(0xE1u, 0xCDu, 0x23u);
-  switch (dialog_menu_id)
-  {
-    case HOUSE_DIALOGUE_MAIN:
-    {
-      if ( !sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
-        return;
-      pShopOptions[0] = pGlobalTXT_LocalizationStrings[134]; //"Buy Standard"
-      pShopOptions[1] = pGlobalTXT_LocalizationStrings[152]; //"Buy Special"
-      pShopOptions[2] = pGlobalTXT_LocalizationStrings[159]; //"Display Inventory"
-      pShopOptions[3] = pGlobalTXT_LocalizationStrings[160];
-      all_text_height = 0;
-      for( int i = 0; i < 4; ++i )
-        all_text_height += pFontArrus->CalcTextHeight(pShopOptions[i], &dialog_window, 0, 0);
-      v146 = ( 174 - all_text_height ) / 4;
-      v23 = ( 174 - 4 * ( 174 - all_text_height ) / 4 - all_text_height ) / 2 - ( 174 - all_text_height ) / 4 / 2 + 138;
-      pNumString = 0;
-      if ( pDialogueWindow->pNumPresenceButton>=0 )
-      {
-        for (pActiveButton = pDialogueWindow->pStartingPosActiveItem; pActiveButton < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem;  ++pActiveButton)
-        {
-          pButton = pDialogueWindow->GetControl(pActiveButton);
-          pButton->uY = v146 + v23;
-          pTextHeight = pFontArrus->CalcTextHeight(pShopOptions[pNumString], &dialog_window, 0, 0);
-          pButton->uHeight = pTextHeight;
-          v23 = pButton->uY + pButton->uHeight - 1;
-          pButton->uW = v23;
-          pTextColor = pYellowColor;
-          if ( pDialogueWindow->pCurrentPosActiveItem != pActiveButton )
-            pTextColor = pWhiteColor;
-          dialog_window.DrawTitleText(pFontArrus, 0, pButton->uY, pTextColor, pShopOptions[pNumString], 3);
-          ++pNumString;
-        }
-      }
-    }
-    break;
-    case HOUSE_DIALOGUE_SHOP_BUY_STANDARD:
-    {
-      pRenderer->DrawTextureIndexed(8, 8, ShopTexture);// 
-      textureW = 0;
-      v153 = 0;
-      for ( int i = 0; i < 8; ++i )//  
-      {
-        if ( pParty->StandartItemsInShops[window_SpeakInHouse->par1C][i].uItemID)
-        {
-          textureW = ItemsInShopTexture[i]->uTextureWidth;
-          textureH = ItemsInShopTexture[i]->uTextureHeight;
-          if ( i >= 4 )  //low row
-          {
-            v60 = 90 - (textureW/2);
-            pRenderer->DrawTextureTransparent(v60 + v153 - 420, 126, ItemsInShopTexture[i]);
-            v59 = v60 + v153 + 80220;
-          }
-          else
-          {
-            pY_item = 98 -  textureH;
-            v152 = 86 - (textureW/2);
-            pRenderer->DrawTextureTransparent(v152 + v153, pY_item, ItemsInShopTexture[i]);
-            v59 = v153 + v152 + 640 * pY_item;
-          }
-          ZBuffer_DoFill(&pRenderer->pActiveZBuffer[v59], ItemsInShopTexture[i], i + 1);
-        }
-        v153 += 105;
-      }
-      if ( !sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
-        return;
-      pItemCount = 0;
-      for ( int i = 0; i < 8; ++i )
-      {
-        if ( pParty->StandartItemsInShops[window_SpeakInHouse->par1C][i].uItemID )
-          ++pItemCount;
-      }
-      if ( GetAsyncKeyState(17) == 0 || pPlayers[uActiveCharacter]->CanSteal() == 0 )
-        pStatusText = pGlobalTXT_LocalizationStrings[195]; //"Select the Item to Buy"
-      else
-        pStatusText = pGlobalTXT_LocalizationStrings[185];//"Steal item"
-      DrawTextAtStatusBar(pStatusText, 0);
-      if ( pItemCount != 0 )
-      {
-        v73 = pMouse->GetCursorPos(&v136);
-        v74 = pRenderer->pActiveZBuffer[v73->x + pSRZBufferLineOffsets[pMouse->GetCursorPos(&v134)->y]] & 0xFFFF;
-        if ( !v74 )
-          return;
-        pItemCount = v74 - 1;
-        selected_item = &pParty->StandartItemsInShops[window_SpeakInHouse->par1C][v74-1];
-        if ( GetAsyncKeyState(17) == 0 || pPlayers[uActiveCharacter]->CanSteal() == 0)
-          v15 = (char *)pMerchantsBuyPhrases[pPlayers[uActiveCharacter]->SelectPhrasesTransaction(selected_item, BildingType_ArmorShop, window_SpeakInHouse->par1C, 2)];
-        else
-          v15 = pGlobalTXT_LocalizationStrings[181]; //"Steal %24"
-        v36 = BuilDialogueString(v15, uActiveCharacter - 1, selected_item, (char *)window_SpeakInHouse->ptr_1C, 2, 0);
-        v115 = (174 - pFontArrus->CalcTextHeight(v36, &dialog_window, 0, 0)) / 2 + 138;
-        dialog_window.DrawTitleText(pFontArrus, 0, v115, pWhiteColor, v36, 3);
-        return;
-      }
-      dialog_window.DrawCurrentTime( pParty->field_3C.field_50[window_SpeakInHouse->par1C]- pParty->uTimePlayed);
-      return;
-    }
-    break;
-    case HOUSE_DIALOGUE_SHOP_BUY_SPECIAL:
-    {
-      pRenderer->DrawTextureIndexed(8, 8, ShopTexture);
-      v11 = 0;
-      v61 = 0;
-      v153 = 0;
-      do
-      {
-        if (pParty->SpecialItemsInShops[window_SpeakInHouse->par1C][v61].uItemID)
-        {
-          v62 = ItemsInShopTexture[v61];
-          if ( v61 >= 4 )
-          {
-            v67 = 90 - ((signed int)v62->uTextureWidth >> 1);
-            pRenderer->DrawTextureTransparent(v153 + v67 - 420, 0x7Eu, ItemsInShopTexture[v61]);
-            v66 = v153 + v67 + 80220;
-          }
-          else
-          {
-            v63 = 98 - v62->uTextureHeight;
-            v64 = ItemsInShopTexture[v61];
-            v65 = 98 - v62->uTextureHeight;
-            v152 = 86 - ((signed int)v62->uTextureWidth >> 1);
-            pRenderer->DrawTextureTransparent(v152 + v153, v65, v64);
-            v66 = v152 + v153 + 640 * v63;
-          }
-          ZBuffer_DoFill(&pRenderer->pActiveZBuffer[v66], ItemsInShopTexture[v61], v61 + 1);
-        }
-        v153 += 105;
-        ++v61;
-      }
-      while ( v61 < 8 );
-      if ( !sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
-        return;
-      v68 = 0;
-      pItemCount = 0;
-      do
-      {
-        if (pParty->SpecialItemsInShops[window_SpeakInHouse->par1C][(signed int)v68].uItemID)
-        ++pItemCount;
-        ++v68;
-      }
-      while ( v68 < 6 );
-      if ( GetAsyncKeyState(17) == 0 || pPlayers[uActiveCharacter]->CanSteal() == 0 )
-        pStatusText = pGlobalTXT_LocalizationStrings[196]; //Select the Special Item to Buy"
-      else
-        pStatusText = pGlobalTXT_LocalizationStrings[185];
-      DrawTextAtStatusBar(pStatusText, 0);
-      if ( (char *)pItemCount != 0 )
-      {
-        v73 = pMouse->GetCursorPos(&v136);
-        v74 = pRenderer->pActiveZBuffer[v73->x + pSRZBufferLineOffsets[pMouse->GetCursorPos((POINT *)&v134)->y]] & 0xFFFF;
-        if ( !v74 )
-          return;
-        pItemCount = v74 - 1;
-        if ( dialog_menu_id == 2 )
-          selected_item = &pParty->StandartItemsInShops[window_SpeakInHouse->par1C][v74 - 1];
-        else
-          selected_item = &pParty->SpecialItemsInShops[window_SpeakInHouse->par1C][v74 - 1];
-        if ( GetAsyncKeyState(17) == 0 || pPlayers[uActiveCharacter]->CanSteal() == 0 )
-          v15 = (char *)pMerchantsBuyPhrases[pPlayers[uActiveCharacter]->SelectPhrasesTransaction(selected_item, BildingType_ArmorShop, window_SpeakInHouse->par1C, 2)];
-        else
-          v15 = pGlobalTXT_LocalizationStrings[181]; //"Steal %24"
-        v36 = BuilDialogueString(v15, uActiveCharacter - 1, selected_item, (char *)window_SpeakInHouse->ptr_1C, 2, 0);
-        v115 = (174 - pFontArrus->CalcTextHeight(v36, &dialog_window, 0, 0)) / 2 + 138;
-        dialog_window.DrawTitleText(pFontArrus, 0, v115, pWhiteColor, v36, 3);
-        return;
-      }
-      dialog_window.DrawCurrentTime( pParty->field_3C.field_50[window_SpeakInHouse->par1C]- pParty->uTimePlayed);
-      return;
-    }
-    break;
-    case HOUSE_DIALOGUE_SHOP_DISPLAY_EQUIPMENT:
-    {
-      draw_leather();
-      CharacterUI_InventoryTab_Draw(pPlayers[uActiveCharacter], true);
-      pShopOptions[0] = pGlobalTXT_LocalizationStrings[200]; //"Sell"
-      pShopOptions[1] = pGlobalTXT_LocalizationStrings[113]; //"Identify"
-      pShopOptions[2] = pGlobalTXT_LocalizationStrings[179]; //"Repair"
-      all_text_height = 0;
-      for ( int i = 0; i < 3; ++i )
-        all_text_height += pFontArrus->CalcTextHeight(pShopOptions[i], &dialog_window, 0, 0);
-      v152 = (174 - all_text_height) / 3;
-      v86 = (3 * (58 - v152) - all_text_height) / 2 - v152 / 2 + 138;
-      v24 = -pDialogueWindow->pNumPresenceButton < 0;
-      pActiveButton = pDialogueWindow->pStartingPosActiveItem;
-      if ( v24 ^ (pDialogueWindow->pStartingPosActiveItem > pDialogueWindow->pStartingPosActiveItem + pDialogueWindow->pNumPresenceButton) )
-      {
-        pNumString = 0;
-        do
-        {
-          pButton = pDialogueWindow->GetControl((unsigned int)pActiveButton);
-          pButton->uY = v152 + v86;
-          pTextHeight = pFontArrus->CalcTextHeight(pShopOptions[pNumString], &dialog_window, 0, 0);
-          v90 = pButton->uY;
-          pButton->uHeight = pTextHeight;
-          v86 = v90 + pTextHeight - 1;
-          pButton->uW = v86;
-          pTextColor = pYellowColor;
-          if ( pDialogueWindow->pCurrentPosActiveItem != pActiveButton )
-            pTextColor = pWhiteColor;
-          dialog_window.DrawTitleText(pFontArrus, 0, v90, pTextColor, pShopOptions[pNumString], 3);
-          ++pNumString;
-          ++pActiveButton;
-        }
-        while ( (signed int)pActiveButton < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem );
-      }
-      return;
-    }
-    break;
-    case HOUSE_DIALOGUE_SHOP_SELL:
-    {
-      draw_leather();
-      CharacterUI_InventoryTab_Draw(pPlayers[uActiveCharacter], true);
-      DrawTextAtStatusBar(pGlobalTXT_LocalizationStrings[199], 0);//"Select the Item to Sell"
-      if ( !sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win())
-        return;
-      if((v9 = pMouse->GetCursorPos(&v139)->x - 14, pItemCount = (v9 >> 5) + 14 * ((pMouse->GetCursorPos(&v133)->y - 17) >> 5),
-         pMouse->GetCursorPos(&v137)->x <= 13) || pMouse->GetCursorPos(&v129)->x >= 462 
-         || (v10 = pPlayers[uActiveCharacter]->GetItemIDAtInventoryIndex((int *)&pItemCount), v11 = 0, !v10) )
-           return;
-      v116 = (ItemGen *)&pPlayers[uActiveCharacter]->pInventoryItems[v10 - 1];
-      v13 = pPlayers[uActiveCharacter]->SelectPhrasesTransaction(v116, BildingType_ArmorShop, window_SpeakInHouse->par1C, 3);
-      v15 = (char *)pMerchantsSellPhrases[pPlayers[uActiveCharacter]->SelectPhrasesTransaction(v116, BildingType_ArmorShop, window_SpeakInHouse->par1C, 3)];
-      v36 = BuilDialogueString(v15, uActiveCharacter - 1, v116, (char *) window_SpeakInHouse->par1C, 3, 0);
-      v115 = (174 - pFontArrus->CalcTextHeight(v36, &dialog_window, 0, 0)) / 2 + 138;
-      dialog_window.DrawTitleText(pFontArrus, 0, v115, pWhiteColor, v36, 3);
-      return;
-    }
-    break;
-    case HOUSE_DIALOGUE_SHOP_IDENTIFY:
-    {
-      draw_leather();
-      CharacterUI_InventoryTab_Draw(pPlayers[uActiveCharacter], true);
-      DrawTextAtStatusBar(pGlobalTXT_LocalizationStrings[197], 0); //"Select the Item to Identify"	
-      if ( sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
-      {
-        v1 = pMouse->GetCursorPos(&a2)->x - 14;
-        pItemCount = (v1 >> 5) + 14 * ((pMouse->GetCursorPos(&v128)->y - 17) >> 5);
-        if ( pMouse->GetCursorPos(&v141)->x > 13 )
-        {
-          if ( pMouse->GetCursorPos(&v143)->x < 462 )
-          {
-            v2 = pPlayers[uActiveCharacter]->GetItemIDAtInventoryIndex((int *)&pItemCount);
-            if ( v2 )
-            {
-              v3 = (ItemGen *)&pPlayers[uActiveCharacter]->pInventoryItems[v2-1];
-              if (v3->Identified())
-                v5 = "%24";
-              else
-              {
-                v8 = pPlayers[uActiveCharacter]->SelectPhrasesTransaction(v3, BildingType_ArmorShop, (int)window_SpeakInHouse->ptr_1C, 4);
-                v5 = (char *)pMerchantsIdentifyPhrases[v8];
-              }
-              v6 = BuilDialogueString(v5, uActiveCharacter - 1, v3, (char *)window_SpeakInHouse->ptr_1C, 4, 0);
-              v115 = (174 - pFontArrus->CalcTextHeight(v6, &dialog_window, 0, 0)) / 2 + 138;
-              dialog_window.DrawTitleText(pFontArrus, 0, v115, pWhiteColor, v6, 3);
-              return;
-            }
-          }
-        }
-      }
-    }
-    break;
-    case HOUSE_DIALOGUE_SHOP_REPAIR:
-    {
-      draw_leather();
-      CharacterUI_InventoryTab_Draw(pPlayers[uActiveCharacter], true);
-      DrawTextAtStatusBar(pGlobalTXT_LocalizationStrings[198], 0);
-      if ( !sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win())
-        return;
-      if( (v31 = pMouse->GetCursorPos(&v135)->x - 14,
-          pItemCount = (v31 >> 5) + 14 * ((pMouse->GetCursorPos(&v142)->y - 17) >> 5),
-            pMouse->GetCursorPos(&v140)->x <= 13)
-            || pMouse->GetCursorPos(&v138)->x >= 462
-            || (v32 = pPlayers[uActiveCharacter]->GetItemIDAtInventoryIndex((int *)&pItemCount), v11 = 0, !v32)
-            || (!(pPlayers[uActiveCharacter]->pOwnItems[v32-1].uAttributes& 2)) )
-        return;
-      v116 = &pPlayers[uActiveCharacter]->pInventoryItems[v33 - 1];
-      v35 = pPlayers[uActiveCharacter]->SelectPhrasesTransaction(&pPlayers[uActiveCharacter]->pInventoryItems[v32 - 1], BildingType_ArmorShop, window_SpeakInHouse->par1C, 5);
-      v15 = (char *)pMerchantsRepairPhrases[v35];
-      v36 = BuilDialogueString(v15, uActiveCharacter - 1, v116, (char *)window_SpeakInHouse->ptr_1C, 5, 0);
-      v115 = (174 - pFontArrus->CalcTextHeight(v36, &dialog_window, 0, 0)) / 2 + 138;
-      dialog_window.DrawTitleText(pFontArrus, 0, v115, pWhiteColor, v36, 3);
-      return;
-    }
-    break;
-    case HOUSE_DIALOGUE_SHOP_6: //buy standart ???
-    {
-      pRenderer->DrawTextureIndexed(8u, 8u, ShopTexture);
-      DrawTextAtStatusBar(pGlobalTXT_LocalizationStrings[195], 0); //"Select the Item to Buy"
-      if ( !sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
-        return;
-      pItemCount = 0;
-      for( int i = 0; i < 6 ; ++i )
-        if (pParty->SpecialItemsInShops[window_SpeakInHouse->par1C][i].uItemID)
-          ++pItemCount;
-      if ( pItemCount )
-      {
-        v94 = pMouse->GetCursorPos(&v132);
-        pItemCount = pRenderer->pActiveZBuffer[v94->x + pSRZBufferLineOffsets[pMouse->GetCursorPos((POINT *)&v130)->y]];
-        v95 = pItemCount;
-        if ( pItemCount && pItemCount != -65536 )
-        {
-          --pItemCount;
-          v97 = uActiveCharacter - 1;
-          v99 = pPlayers[uActiveCharacter]->SelectPhrasesTransaction(&pParty->SpecialItemsInShops[window_SpeakInHouse->par1C][v95-1], BildingType_ArmorShop,	window_SpeakInHouse->par1C,	2);
-          v100 = BuilDialogueString((char *)pMerchantsBuyPhrases[v99], uActiveCharacter - 1, v98, (char *)window_SpeakInHouse->par1C, 2, 0);
-          v103 = pFontArrus->CalcTextHeight(v100, &dialog_window, 0, 0);
-          dialog_window.DrawTitleText(pFontArrus, 0, (174 - v103) / 2 + 138, pWhiteColor, v100, 3);
-        }
-        v104 = 0;
-        v153 = 0;
-        do
-        {
-          //if ( pParty->field_C59C[9 * (v104 + 12 * (unsigned int)window_SpeakInHouse->ptr_1C) + 724] )
-          if (pParty->SpecialItemsInShops[window_SpeakInHouse->par1C][v104].uItemID)
-          {
-            v105 = ItemsInShopTexture[v104];
-            if ( v104 >= 4 )
-            {
-              v110 = 90 - ((signed int)v105->uTextureWidth >> 1);
-              pRenderer->DrawTextureTransparent(v153 + v110 - 420, 0x7Eu, ItemsInShopTexture[v104]);
-              v127 = v104 + 1;
-              v109 = v153 + v110 + 80220;
-            }
-            else
-            {
-              v106 = 98 - v105->uTextureHeight;
-              v108 = 98 - v105->uTextureHeight;
-              v152 = 86 - ((signed int)v105->uTextureWidth >> 1);
-              pRenderer->DrawTextureTransparent(v152 + v153, v108, ItemsInShopTexture[v104]);
-              v127 = v104 + 1;
-              v109 = v152 + v153 + 640 * v106;
-            }
-            ZBuffer_DoFill(&pRenderer->pActiveZBuffer[v109], ItemsInShopTexture[v104], v127);
-          }
-          v153 += 105;
-          ++v104;
-        }
-        while ( v104 < 8 );
-        return;
-      }
-      dialog_window.DrawCurrentTime(pParty->field_3C.field_50[window_SpeakInHouse->par1C]-  pParty->uTimePlayed);
-      return;
-    }
-    break;
-    case HOUSE_DIALOGUE_LEARN_SKILLS:
-    {
-      if (!sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
-        return;
-      v152 = 0;
-      v38 = (signed __int64)(p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].flt_24 * 500.0);
-      pActiveButton = v38 * (100 - pPlayers[uActiveCharacter]->GetMerchant()) / 100;
-      if ( (signed int)pActiveButton < v38 / 3 )
-        pActiveButton = v38 / 3;
-      v39 = pDialogueWindow->pStartingPosActiveItem;
-      v40 = pDialogueWindow->pNumPresenceButton;
-      v153 = 0;
-      if ( (signed int)v39 < (signed int)(v39 + v40) )
-      {
-        do
-        {
-          v41 = pDialogueWindow->GetControl(v39)->msg_param - 36;
-          if ( byte_4ED970_skill_learn_ability_by_class_table[pPlayers[uActiveCharacter]->classType][v41] && !pPlayers[uActiveCharacter]->pActiveSkills[v41] )
-          {
-            v42 = pFontArrus->CalcTextHeight(pSkillNames[v41], &dialog_window, 0, 0);
-            v152 += v42;
-            ++v153;
-          }
-          ++v39;
-        }
-        while ( (signed int)v39 < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem );
-        if ( v153 )
-        {
-          sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[401], pActiveButton);
-          dialog_window.DrawTitleText(pFontArrus, 0, 0x92u, 0, pTmpBuf.data(), 3);
-          pActiveButton = (149 - v152) / v153;
-          if ( (149 - v152) / v153 > 32 )
-            pActiveButton = 32;
-          v43 = (149 - v153 * (signed int)pActiveButton - v152) / 2 - (signed int)pActiveButton / 2 + 162;
-          v152 = pDialogueWindow->pStartingPosActiveItem;
-          v146 = v43;
-          if ( v152 < v152 + pDialogueWindow->pNumPresenceButton )
-          {
-            v153 = 2;
-            do
-            {
-              pButton = pDialogueWindow->GetControl(v152);
-              v46 = pButton->msg_param - 36;
-              if ( !byte_4ED970_skill_learn_ability_by_class_table[pPlayers[uActiveCharacter]->classType][v46] || pPlayers[uActiveCharacter]->pActiveSkills[v46] )
-              {
-                pButton->uW = 0;
-                pButton->uHeight = 0;
-                pButton->uY = 0;
-              }
-              else
-              {
-                pButton->uY = (unsigned int)((char *)pActiveButton + v146);
-                pTextHeight = pFontArrus->CalcTextHeight(pSkillNames[v46], &dialog_window, 0, 0);
-                v49 = pButton->uY;
-                pButton->uHeight = pTextHeight;
-                v51 = v49 + pTextHeight - 1;
-                pButton->uW = v51;
-                v146 = v51;
-                pTextColor = pYellowColor;
-                if ( pDialogueWindow->pCurrentPosActiveItem != v153 )
-                  pTextColor = pWhiteColor;
-                dialog_window.DrawTitleText(pFontArrus, 0, v49, pTextColor, pSkillNames[v46], 3);
-              }
-              v53 = pDialogueWindow->pStartingPosActiveItem;
-              ++v152;
-              textureH = pDialogueWindow->pNumPresenceButton + v53;
-              ++v153;
-            }
-            while ( v152 < textureH );
-          }
-          return;
-        }
-      }
-      sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[544], pPlayers[uActiveCharacter]->pName, pClassNames[pPlayers[uActiveCharacter]->classType]); //"Seek knowledge elsewhere %s the %s"
-      strcat(pTmpBuf.data(), "\n \n");
-      strcat(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[528]); //"I can offer you nothing further."
-      v115 = (174 - pFontArrus->CalcTextHeight(pTmpBuf.data(), &dialog_window, 0, 0)) / 2 + 138;
-      dialog_window.DrawTitleText(pFontArrus, 0, v115, pYellowColor, pTmpBuf.data(), 3);
-      return;
-    }
-    break;
-  }
-}
-
-//----- (004B5D7C) --------------------------------------------------------
-void GuildDialog()
-{
-  signed int base_teach_price; // ebx@1
-  int v3; // edi@6
-  int result; // eax@11
-  int v6; // esi@13
-  signed int v7; // esi@17
-  int v8; // esi@22
-  signed int v9; // ecx@22
-  char *v10; // eax@22
-  const char *statusbar_string; // ecx@26
-  POINT *v12; // esi@30
-  int v13; // ecx@30
-  void *v14; // ST1C_4@31
-  ItemGen *v15; // ST18_4@31
-  int v16; // ST10_4@31
-  int v17; // eax@31
-  char *v18; // edx@31
-  int v19; // eax@32
-  int pActiveItem; // esi@35
-  int v22; // eax@35
-  unsigned int v23; // eax@36
-  int v24; // eax@39
-  int v25; // eax@40
-  int v26; // ecx@47
-  GUIButton *pButton; // eax@49
-  unsigned int v29; // eax@49
-  char *pText; // eax@52
-  int pTextHeight; // eax@55
-  unsigned int v32; // ecx@55
-  int v33; // eax@55
-  unsigned __int16 pTextColor; // ax@55
-  int v35; // eax@58
-  const char *v36; // ST20_4@61
-  unsigned __int16 v37; // ST1C_2@61
-  int v38; // eax@61
-  int v40; // [sp-14h] [bp-300h]@31
-  int v41; // [sp-10h] [bp-2FCh]@31
-  unsigned __int16 v42; // [sp-Ch] [bp-2F8h]@31
-  char *v43; // [sp-8h] [bp-2F4h]@31
-  unsigned int v44; // [sp-4h] [bp-2F0h]@31
-  char Dest[100]; // [sp+Ch] [bp-2E0h]@3
-  char v46[100]; // [sp+70h] [bp-27Ch]@3
-  char v47[100]; // [sp+D4h] [bp-218h]@3
-  char v48[100]; // [sp+138h] [bp-1B4h]@3
-  char v49[100]; // [sp+19Ch] [bp-150h]@3
-  POINT v50; // [sp+264h] [bp-88h]@30
-  POINT v51; // [sp+26Ch] [bp-80h]@30
-  GUIWindow working_window; // [sp+274h] [bp-78h]@1
-  signed int v53; // [sp+27Ch] [bp-70h]@1
-  signed int v54; // [sp+284h] [bp-68h]@1
-  int pColorWhite; // [sp+2CCh] [bp-20h]@1
-  int pColorYellow; // [sp+2D0h] [bp-1Ch]@1
-  int v58; // [sp+2D4h] [bp-18h]@1
-  unsigned __int8 uPlayerID; // [sp+2DBh] [bp-11h]@31
-  bool pSkillFlag; // [sp+2DCh] [bp-10h]@35
-  int v61; // [sp+2E0h] [bp-Ch]@35
-  int pItemNum;
-  unsigned int v62; // [sp+2E4h] [bp-8h]@13
-  int v63; // [sp+2E8h] [bp-4h]@1
-  int pNumActivItem;
-  int all_text_height;
-
-  memcpy(&working_window, window_SpeakInHouse, sizeof(GUIWindow));
-  working_window.uFrameX = 483;
-  working_window.uFrameWidth = 148;
-  working_window.uFrameZ = 334;
-  pColorWhite = TargetColor(0xFFu, 0xFFu, 0xFFu);
-  pColorYellow = TargetColor(0xFFu, 0xFFu, 0x9Bu);
-  base_teach_price = (signed __int64)(p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].fPriceMultiplier * 500.0);
-  v63 = base_teach_price * (100 - pPlayers[uActiveCharacter]->GetMerchant()) / 100;
-  if ( v63 < base_teach_price / 3 )
-    v63 = base_teach_price / 3;
-  strcpy(Dest, "");
-  strcpy(v46, "");
-  strcpy(v47, "");
-  strcpy(v48, "");
-  strcpy(v49, "");
-  if ( dialog_menu_id != HOUSE_DIALOGUE_MAIN )
-  {
-    if ( dialog_menu_id != HOUSE_DIALOGUE_GUILD_BUY_BOOKS ) //buy skill
-    {
-      if ( sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
-      {
-        if ( pPlayers[uActiveCharacter]->pActiveSkills[dialog_menu_id-36] )
-        {
-          sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[403], pClassNames[dialog_menu_id - 16]); //"You already know the %s skill"
-          ShowStatusBarString(pTmpBuf.data(), 2);
-          pAudioPlayer->PlaySound(SOUND_27, 0, 0, -1, 0, 0, 0, 0);
-        }
-        else
-        {
-          if ( pParty->uNumGold < v63 )
-          {
-            ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2u); //"You don't have enough gold"
-            PlayHouseSound((unsigned int)window_SpeakInHouse->ptr_1C, HouseSound_NotEnoughMoney_TrainingSuccessful);
-          }
-          else
-          {
-            Party::TakeGold(v63);
-            pPlayers[uActiveCharacter]->pActiveSkills[dialog_menu_id-36] = 1;
-          }
-        }
-      }
-      pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
-      return;
-    }
-    pRenderer->DrawTextureIndexed(8, 8, ShopTexture);
-    v6 = 0;
-    v62 = 0;
-    v63 = 32;
-    do
-    {
-      if (pParty->SpellBooksInGuilds[window_SpeakInHouse->par1C-139][v6].uItemID)
-      {
-        pRenderer->DrawTextureTransparent(v63, 0x5Au, ItemsInShopTexture[v6]);
-        ZBuffer_DoFill((int *)((char *)pRenderer->pActiveZBuffer + v62 + 230528), ItemsInShopTexture[v6], v6 + 1);
-      }
-      v63 += 70;
-      v62 += 280;
-      ++v6;
-    }
-    while ( v63 < 452 );
-    v62 = 1680;
-    v7 = 6;
-    v63 = 32;
-    do
-    {
-      if (pParty->SpellBooksInGuilds[window_SpeakInHouse->par1C-139][v7].uItemID)
-      {
-        pRenderer->DrawTextureTransparent(v63, 0xFAu, ItemsInShopTexture[v7]);
-        ZBuffer_DoFill((int *)((char *)pRenderer->pActiveZBuffer + v62 + 638448), ItemsInShopTexture[v7], v7 + 1);
-      }
-      v63 += 70;
-      v62 += 280;
-      ++v7;
-    }
-    while ( v63 < 452 );
-    if ( sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
-    {
-      v8 = 0;
-      v9 = 12;
-      do
-      {
-        if (pParty->SpellBooksInGuilds[window_SpeakInHouse->par1C-139][v9].uItemID )
-          ++v8;
-        --v9;
-      }
-      while ( v9 );
-      GetAsyncKeyState(17);
-      statusbar_string = pGlobalTXT_LocalizationStrings[195]; //"Select the Item to Buy"
-      if ( dialog_menu_id != HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
-        statusbar_string = pGlobalTXT_LocalizationStrings[196]; //"Select the Special Item to Buy"	
-      DrawTextAtStatusBar(statusbar_string, 0);
-      if ( !v8 )
-      {
-        working_window.DrawCurrentTime(__PAIR__( *(int *)&stru_AA1058[3].pSounds[8 * (unsigned int)window_SpeakInHouse->ptr_1C + 44472],
-                       *(int *)&stru_AA1058[3].pSounds[8 * (unsigned int)window_SpeakInHouse->ptr_1C + 44468]) - pParty->uTimePlayed);
-        return;
-      }
-      v12 = pMouse->GetCursorPos(&v51);
-      result = v12->x + pSRZBufferLineOffsets[pMouse->GetCursorPos(&v50)->y];
-      v13 = pRenderer->pActiveZBuffer[result] & 0xFFFF;
-      if ( pRenderer->pActiveZBuffer[result] & 0xFFFF )
-      {
-        v14 = window_SpeakInHouse->ptr_1C;
-        v15 = (ItemGen *)(&pParty->pPlayers[1].uExpressionTimeLength + 18 * (v13 + 12 * (int)v14));
-        v16 = (int)window_SpeakInHouse->ptr_1C;
-        uPlayerID = uActiveCharacter - 1;
-        v17 = pPlayers[uActiveCharacter]->SelectPhrasesTransaction( (ItemGen *)&pParty->pPlayers[1].uExpressionTimeLength + v13 + 12 * (int)v14, BildingType_MagicShop, v16,  2);
-        v18 = BuilDialogueString((char *)pMerchantsBuyPhrases[v17], uPlayerID, v15, (char *)v14, 2, 0);     
-        v19 = pFontArrus->CalcTextHeight(v18, &working_window, 0, 0);
-        working_window.DrawTitleText(pFontArrus, 0, (174 - v19) / 2 + 138,  pColorWhite, v18, 3);
-        return;
-      }
-    }
-    return;
-  }
-  if ( !(unsigned __int16)_449B57_test_bit((unsigned __int8 *)pPlayers[uActiveCharacter]->_guilds_member_bits,
-            guild_mambership_flags[(unsigned int)window_SpeakInHouse->ptr_1C-139]) )
-  { //you must me member
-    v38 = pFontArrus->CalcTextHeight(pNPCTopics[121].pText, &working_window, 0, 0);
-    working_window.DrawTitleText(pFontArrus, 0, (212 - v38) / 2 + 101, pColorYellow, pNPCTopics[121].pText, 3u);
-    pDialogueWindow->pNumPresenceButton = 0;
-    return;
-  }
-  if ( !sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
-    return;
-  v61 = 0;
-  pSkillFlag = false;
-  pActiveItem = pDialogueWindow->pStartingPosActiveItem;
-  v22 = pActiveItem + pDialogueWindow->pNumPresenceButton;
-  pItemNum = 0;
-  if ( pDialogueWindow->pStartingPosActiveItem >= pDialogueWindow->pStartingPosActiveItem + pDialogueWindow->pNumPresenceButton )
-  {
-    sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[544], pPlayers[uActiveCharacter]->pName, pClassNames[pPlayers[uActiveCharacter]->classType]); // "Seek knowledge elsewhere %s the %s"	
-    strcat(pTmpBuf.data(), "\n \n");
-    strcat(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[528]); //"I can offer you nothing further."
-    v19 = pFontArrus->CalcTextHeight(pTmpBuf.data(), &working_window, 0, 0);
-    working_window.DrawTitleText(pFontArrus, 0, (174 - v19) / 2 + 138, pColorYellow, pTmpBuf.data(), 3);
-    return;
-  }
-  all_text_height = 0;
-  do
-  {
-    v23 = pDialogueWindow->GetControl(pActiveItem)->msg_param;
-    if ( v23 == 18 )
-    {
-      all_text_height += pFontArrus->CalcTextHeight(pGlobalTXT_LocalizationStrings[400], &working_window, 0, 0); //"Buy Spells"
-      v61++;
-    }
-    else
-    {
-      if( byte_4ED970_skill_learn_ability_by_class_table[pPlayers[uActiveCharacter]->classType][v23 - 36] 
-          && !pPlayers[uActiveCharacter]->pActiveSkills[v23 - 36] )
-      {
-        all_text_height += pFontArrus->CalcTextHeight(pSkillNames[v23 - 36], &working_window, 0, 0);
-        v61++;
-        pSkillFlag = true;
-      }
-    }
-    ++pActiveItem;
-  }
-  while ( pActiveItem < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem );
-  if ( !v61 )
-  {
-    sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[544], pPlayers[uActiveCharacter]->pName, pClassNames[pPlayers[uActiveCharacter]->classType]); // "Seek knowledge elsewhere %s the %s"	
-    strcat(pTmpBuf.data(), "\n \n");
-    strcat(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[528]); //"I can offer you nothing further."
-    v19 = pFontArrus->CalcTextHeight(pTmpBuf.data(), &working_window, 0, 0);
-    working_window.DrawTitleText(pFontArrus, 0, (174 - v19) / 2 + 138, pColorYellow, pTmpBuf.data(), 3);
-    return;
-  }
-  if ( pSkillFlag )
-  {
-    sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[401], v63); //"Skill Cost: %lu"
-    working_window.DrawTitleText(pFontArrus, 0, 0x92u, 0, pTmpBuf.data(), 3);
-  }
-  v58 = (149 - all_text_height) / v61;
-  if ( v58 > 32 )
-    v58 = 32;
-  v26 = (149 - v61 * v58 - all_text_height) / 2 - v58 / 2 + 162;
-  pNumActivItem = pDialogueWindow->pStartingPosActiveItem;
-  if (pDialogueWindow->pStartingPosActiveItem < pDialogueWindow->pStartingPosActiveItem + pDialogueWindow->pNumPresenceButton )
-  {
-    pItemNum = 2;
-    do
-    {
-      pButton = pDialogueWindow->GetControl(pItemNum);
-      v29 = pButton->msg_param;
-      if ( v29 == 18 )
-      {
-        pText = pGlobalTXT_LocalizationStrings[400]; //"Buy Spells"
-        pButton->uY = v58 + v26;
-        pTextHeight = pFontArrus->CalcTextHeight(pText, &working_window, 0, 0);
-        v32 = pButton->uY;
-        pButton->uHeight = pTextHeight;
-        v33 = v32 + pTextHeight - 1;
-        pButton->uW = v33;
-        v26 = v33;
-        pTextColor = pColorYellow;
-        if ( pDialogueWindow->pCurrentPosActiveItem != pItemNum )
-          pTextColor = pColorWhite;
-        working_window.DrawTitleText(pFontArrus, 0, v32, pTextColor, pText, 3);
-      }
-      else
-      {
-        if ( byte_4ED970_skill_learn_ability_by_class_table[pPlayers[uActiveCharacter]->classType][v29 - 36] 
-             && !pPlayers[uActiveCharacter]->pActiveSkills[v29 - 36] )
-        {
-          pButton->uY = v58 + v26;
-          pTextHeight = pFontArrus->CalcTextHeight(pSkillNames[v29 - 36], &working_window, 0, 0);
-          v32 = pButton->uY;
-          pButton->uHeight = pTextHeight;
-          v33 = v32 + pTextHeight - 1;
-          pButton->uW = v33;
-          v26 = v33;
-          pTextColor = pColorYellow;
-          if ( pDialogueWindow->pCurrentPosActiveItem != pItemNum )
-            pTextColor = pColorWhite;
-          working_window.DrawTitleText(pFontArrus, 0, v32, pTextColor, pSkillNames[v29 - 36], 3);
-        }
-        else
-        {
-          pButton->uW = 0;
-          pButton->uHeight = 0;
-          pButton->uY = 0;
-        }
-      }
-      ++pItemNum;
-    }
-    while ( pItemNum < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem );
-  }
-  return;
-}
-
 //----- (004B705E) --------------------------------------------------------
 void TempleDialog()
     {
@@ -5425,630 +3432,6 @@
   }
 }
 
-//----- (004B4FCF) --------------------------------------------------------
-void MagicShopDialog()
-{
-  int result; // eax@6
-  signed int v2; // esi@8
-  unsigned int v3; // ebx@10
-  char *v4; // eax@11
-  char *v5; // eax@12
-  unsigned int v6; // eax@12
-  int v7; // ST08_4@14
-  int v8; // eax@14
-  unsigned __int8 v9; // dl@14
-  char *v10; // ecx@14
-  signed int v11; // esi@16
-  int v12; // ST08_4@19
-  int v13; // eax@19
-  int all_text_height; // edi@21
-  char **v15; // esi@21
-  int v16; // eax@22
-  int v18; // edx@23
-  int v19; // edi@23
-  unsigned __int8 v20; // sf@23
-  GUIButton *control_button; // esi@25
-  const char **v22; // eax@25
-  int v23; // eax@25
-  unsigned int v24; // ecx@25
-  const char **v25; // edx@25
-  unsigned __int16 text_color; // ax@25
-  signed int pTextHeight; // esi@30
-  int v28; // ST08_4@34
-  int v29; // eax@34
-  char *v30; // edx@35
-  void *v32; // eax@40
-  signed int v33; // esi@40
-  unsigned int v34; // esi@42
-  int v35; // eax@42
-  unsigned int v36; // eax@43
-  int v37; // eax@45
-  int v38; // ecx@50
-  int v41; // eax@52
-  char *v42; // eax@54
-  int v43; // eax@54
-  unsigned int v44; // ecx@54
-  int v45; // edx@54
-  int v46; // eax@54
-  unsigned __int16 v47; // ax@54
-  int v48; // eax@58
-  signed int v49; // esi@62
-  Texture *v50; // ecx@64
-  unsigned int v51; // edi@64
-  unsigned int v52; // esi@66
-  int v53; // edx@70
-  Texture *v54; // ecx@76
-  unsigned int v55; // edi@76
-  unsigned int v56; // esi@76
-  int v57; // edx@80
-  unsigned int v59; // edi@86
-  unsigned int v60; // esi@88
-  int v61; // edx@92
-  unsigned int v63; // edi@98
-  unsigned int v64; // esi@100
-  int v65; // edx@104
-  signed int v66; // ecx@109
-  SHORT v67; // di@117
-  bool v68; // eax@117
-  const char *v69; // ecx@119
-  POINT *v70; // esi@124
-  int v71; // ecx@125
-  int v73; // ecx@125
-  int v75; // eax@130
-  int v78; // eax@132
-  int v80; // edx@133
-  int v81; // edi@133
-  const char **v83; // eax@135
-  int v84; // eax@135
-  unsigned int v85; // ecx@135
-  int v86; // edx@135
-  int v89; // [sp-14h] [bp-10Ch]@35
-  int v91; // [sp-10h] [bp-108h]@35
-  unsigned __int16 v92; // [sp-Ch] [bp-104h]@12
-  void *v93; // [sp-Ch] [bp-104h]@14
-  int v94; // [sp-8h] [bp-100h]@11
-  char *v95; // [sp-8h] [bp-100h]@12
-  __int64 *v96; // [sp-4h] [bp-FCh]@11
-  unsigned int v97; // [sp-4h] [bp-FCh]@12
-  POINT v98; // [sp+Ch] [bp-ECh]@8
-  POINT v99; // [sp+14h] [bp-E4h]@16
-  POINT v100; // [sp+1Ch] [bp-DCh]@124
-  POINT v101; // [sp+24h] [bp-D4h]@17
-  POINT v102; // [sp+2Ch] [bp-CCh]@124
-  POINT v103; // [sp+34h] [bp-C4h]@9
-  POINT v104; // [sp+3Ch] [bp-BCh]@31
-  POINT v105; // [sp+44h] [bp-B4h]@16
-  POINT v106; // [sp+4Ch] [bp-ACh]@30
-  POINT v107; // [sp+54h] [bp-A4h]@16
-  POINT v108; // [sp+5Ch] [bp-9Ch]@30
-  POINT a2; // [sp+64h] [bp-94h]@8
-  POINT v110; // [sp+6Ch] [bp-8Ch]@30
-  POINT v111; // [sp+74h] [bp-84h]@8
-  GUIWindow dialog_window; // [sp+7Ch] [bp-7Ch]@1
-  char *Str; // [sp+D0h] [bp-28h]@54
-  int v146; // [sp+D4h] [bp-24h]@23
-  unsigned int pYellowColor; // [sp+D8h] [bp-20h]@1
-  unsigned int pWhiteColor; // [sp+DCh] [bp-1Ch]@1
-  __int32 v117; // [sp+E0h] [bp-18h]@8
-  int v118; // [sp+E4h] [bp-14h]@40
-  const char **v119; // [sp+E8h] [bp-10h]@24
-  int _this; // [sp+ECh] [bp-Ch]@1
-  unsigned __int8 uPlayerID; // [sp+F3h] [bp-5h]@14
-  int v152; // [sp+F4h] [bp-4h]@23
-  int v122;
-  int v114;
-  int pSrtingNum;
-  int pActiveItemNum;
-  ItemGen *item;
-
-  memcpy(&dialog_window, window_SpeakInHouse, sizeof(dialog_window));
-  dialog_window.uFrameX = 483;
-  dialog_window.uFrameWidth = 148;
-  dialog_window.uFrameZ = 334;
-  pWhiteColor = TargetColor(255, 255, 255);
-  pYellowColor = TargetColor(225, 205, 35);
-  if ( dialog_menu_id == HOUSE_DIALOGUE_MAIN)
-  {
-    if ( !sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
-        return;
-    pShopOptions[0] = pGlobalTXT_LocalizationStrings[134]; //"Buy Standard"
-    pShopOptions[1] = pGlobalTXT_LocalizationStrings[152]; //"Buy Special"
-    pShopOptions[2] = pGlobalTXT_LocalizationStrings[159]; //"Display Inventory"
-    pShopOptions[3] = pGlobalTXT_LocalizationStrings[160];
-    all_text_height = 0;
-    for ( int i = 0; i < 4; ++i )
-      all_text_height += pFontArrus->CalcTextHeight(pShopOptions[i], &dialog_window, 0, 0);
-    v146 = (174 - all_text_height) / 4;
-    v23 = (174 - 4 * (174 - all_text_height) / 4 - all_text_height) / 2 - (174 - all_text_height) / 4 / 2 + 138;
-    int j = 0;
-    if ( pDialogueWindow->pNumPresenceButton>=0 )
-    {
-      int th = 2;
-      for (v152 = pDialogueWindow->pStartingPosActiveItem; v152 < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem;  ++v152)
-      {
-        control_button = pDialogueWindow->GetControl(v152);
-        control_button->uY = v146 + v23;
-        pTextHeight = pFontArrus->CalcTextHeight(pShopOptions[j], &dialog_window, 0, 0);
-        control_button->uHeight = pTextHeight;
-        v23 = control_button->uY + control_button->uHeight - 1;
-        control_button->uW = v23;
-        text_color = pYellowColor;
-        if ( pDialogueWindow->pCurrentPosActiveItem != th )
-          text_color = pWhiteColor;
-        dialog_window.DrawTitleText(pFontArrus, 0, control_button->uY, text_color, pShopOptions[j], 3);
-        ++th;               
-        ++j;
-      }
-    }
-    return;
-  }
-  if ( dialog_menu_id == HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
-  {
-    pRenderer->DrawTextureIndexed(8, 8, ShopTexture);
-    v3 = 0;
-    v49 = 0;
-    v122 = 0;
-    do
-    {
-      if ( pParty->StandartItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][v49].uItemID)
-      {
-        v50 = ItemsInShopTexture[v49];
-        v51 = 152 - v50->uTextureHeight;
-        if ( (signed int)v51 < 1 )
-          v51 = 0;
-        v52 = 75 * v49 - v50->uTextureWidth / 2 + 40;
-        if ( v122 )
-        {
-          if ( v122 == 5 )
-          {
-            v53 = ItemsInShopTexture[5]->uTextureWidth;
-            if ( (signed int)v52 > 457 - v53 )
-              v52 = 457 - v53;
-          }
-        }
-        else
-        {
-          if ( (signed int)v52 < 18 )
-            v52 = 18;
-        }
-        pRenderer->DrawTextureTransparent(v52, v51, v50);
-        sub_40F92A(&pRenderer->pActiveZBuffer[v52 + 640 * v51], ItemsInShopTexture[v122], v122 + 1);
-        v49 = v122;
-      }
-      ++v49;
-      v122 = v49;
-    }
-    while ( v49 < 6 );
-    v122 = 0;
-    do
-    {
-      if ( pParty->StandartItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][v122 + 6].uItemID)
-      {
-        v54 = ItemsInShopTexture[v122 + 6];
-        v55 = 306 - v54->uTextureHeight;
-        v56 = 75 * v122 - v54->uTextureWidth / 2 + 40;
-        if ( v122 )
-        {
-          if ( v122 == 5 )
-          {
-            v57 = ItemsInShopTexture[11]->uTextureWidth;
-            if ( (signed int)v56 > 457 - v57 )
-              v56 = 457 - v57;
-          }
-        }
-        else
-        {
-          if ( (signed int)v56 < 18 )
-            v56 = 18;
-        }
-        pRenderer->DrawTextureTransparent(v56, v55, v54);
-        sub_40F92A(&pRenderer->pActiveZBuffer[v56 + 640 * v55], ItemsInShopTexture[v122 + 6], v122 + 7);
-      }
-      ++v122;
-    }
-    while ( v122 < 6 );
-    if ( sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
-    {
-      v66 = 0;
-      v117 = 0;
-      if ( dialog_menu_id == HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
-      {
-        do
-        {
-          if ( pParty->StandartItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][v66].uItemID) //9 * (v66 + 12 * (unsigned int)window_SpeakInHouse->ptr_1C)] )
-            ++v117;
-          ++v66;
-        }
-        while ( v66 < 12 );
-      }
-      else
-      {
-        do
-        {
-          if (pParty->SpecialItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][v66].uItemID)
-            ++v117;
-          ++v66;
-        }
-        while ( v66 < 12 );
-      }
-      v67 = GetAsyncKeyState(VK_CONTROL);
-      v68 = pPlayers[uActiveCharacter]->CanSteal();
-      Str = (char *)v68;
-      if ( v67 && v68 )
-      {
-        v69 = pGlobalTXT_LocalizationStrings[185];// "Steal item"
-      }
-      else
-      {
-        v69 = pGlobalTXT_LocalizationStrings[195];// "Select the Item to Buy"
-        if ( dialog_menu_id != HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
-          v69 = pGlobalTXT_LocalizationStrings[196];// "Select the Special Item to Buy"
-      }
-      DrawTextAtStatusBar(v69, 0);
-      if ( !v117 )
-      {
-        dialog_window.DrawCurrentTime( pParty->field_3C.field_50[(unsigned int)window_SpeakInHouse->ptr_1C] - pParty->uTimePlayed);
-        return;
-      }
-      v70 = pMouse->GetCursorPos(&v102);
-      result = v70->x + pSRZBufferLineOffsets[pMouse->GetCursorPos(&v100)->y];
-      if ( pRenderer->pActiveZBuffer[result] & 0xFFFF )
-      {
-        v71 = (pRenderer->pActiveZBuffer[result] & 0xFFFF) - 1;
-        item = &pParty->StandartItemsInShops[(int)window_SpeakInHouse->ptr_1C][v71];
-        if ( dialog_menu_id != HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
-          item = &pParty->SpecialItemsInShops[(int)window_SpeakInHouse->ptr_1C][v71];
-        if ( v67 && Str )
-          v10 = pGlobalTXT_LocalizationStrings[181];// "Steal %24"
-        else
-        {
-          v75 = pPlayers[uActiveCharacter]->SelectPhrasesTransaction(item, BildingType_MagicShop, (int)window_SpeakInHouse->ptr_1C, 2);
-          v10 = (char *)pMerchantsBuyPhrases[v75];
-        }
-        v30 = BuilDialogueString(v10, uActiveCharacter - 1, item, (char *)window_SpeakInHouse->ptr_1C, 2, 0);
-        v6 = (174 - pFontArrus->CalcTextHeight(v30, &dialog_window, v3, v3)) / 2 + 138;
-        dialog_window.DrawTitleText(pFontArrus, v3, v6, pWhiteColor, v30, 3);
-        return;
-      }
-    }
-    return;
-  }
-  if ( dialog_menu_id == HOUSE_DIALOGUE_SHOP_BUY_SPECIAL)
-  {
-    pRenderer->DrawTextureIndexed(8, 8, ShopTexture);
-    v3 = 0;
-    v49 = 0;
-    v122 = 0;
-    do
-    {
-      if (pParty->SpecialItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][v49].uItemID)
-      {
-        v59 = 152 - ItemsInShopTexture[v49]->uTextureHeight;
-        if ( (signed int)v59 < 1 )
-          v59 = 0;
-        v60 = 75 * v49 - ItemsInShopTexture[v49]->uTextureWidth / 2 + 40;
-        if ( v122 )
-        {
-          if ( v122 == 5 )
-          {
-            v61 = ItemsInShopTexture[5]->uTextureWidth;
-            if ( (signed int)v60 > 457 - v61 )
-              v60 = 457 - v61;
-          }
-        }
-        else
-        {
-          if ( (signed int)v60 < 18 )
-            v60 = 18;
-        }
-        pRenderer->DrawTextureTransparent(v60, v59, ItemsInShopTexture[v49]);
-        sub_40F92A(&pRenderer->pActiveZBuffer[v60 + 640 * v59], ItemsInShopTexture[v122], v122 + 1);
-        v49 = v122;
-      }
-      ++v49;
-      v122 = v49;
-    }
-    while ( v49 < 6 );
-    v122 = 0;
-    do
-    {
-      if (pParty->SpecialItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][v122 + 6].uItemID)
-      {
-        v63 = 306 - ItemsInShopTexture[v122 + 6]->uTextureHeight;
-        if ( (signed int)v63 < 1 )
-          v63 = 0;
-        v64 = 75 * v122 - ItemsInShopTexture[v122 + 6]->uTextureWidth / 2 + 40;
-        if ( v122 )
-        {
-          if ( v122 == 5 )
-          {
-            v65 = ItemsInShopTexture[11]->uTextureWidth;
-            if ( (signed int)v64 > 457 - v65 )
-              v64 = 457 - v65;
-          }
-        }
-        else
-        {
-          if ( (signed int)v64 < 18 )
-            v64 = 18;
-        }
-        pRenderer->DrawTextureTransparent(v64, v63, ItemsInShopTexture[v122 + 6]);
-        sub_40F92A(&pRenderer->pActiveZBuffer[v64 + 640 * v63], ItemsInShopTexture[v122 + 6], v122 + 7);
-      }
-      ++v122;
-    }
-    while ( v122 < 6 );
-    if ( sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
-    {
-      v66 = 0;
-      v117 = 0;
-      if ( dialog_menu_id == HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
-      {
-        do
-        {
-          if ( pParty->StandartItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][v66].uItemID) //9 * (v66 + 12 * (unsigned int)window_SpeakInHouse->ptr_1C)] )
-            ++v117;
-          ++v66;
-        }
-        while ( v66 < 12 );
-      }
-      else
-      {
-        do
-        {
-          if (pParty->SpecialItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][v66].uItemID)
-            ++v117;
-          ++v66;
-        }
-        while ( v66 < 12 );
-      }
-      v67 = GetAsyncKeyState(VK_CONTROL);
-      v68 = pPlayers[uActiveCharacter]->CanSteal();
-      Str = (char *)v68;
-      if ( v67 && v68 )
-      {
-        v69 = pGlobalTXT_LocalizationStrings[185];// "Steal item"
-      }
-      else
-      {
-        v69 = pGlobalTXT_LocalizationStrings[195];// "Select the Item to Buy"
-        if ( dialog_menu_id != HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
-          v69 = pGlobalTXT_LocalizationStrings[196];// "Select the Special Item to Buy"
-      }
-      DrawTextAtStatusBar(v69, 0);
-      if ( !v117 )
-      {
-        dialog_window.DrawCurrentTime( pParty->field_3C.field_50[(unsigned int)window_SpeakInHouse->ptr_1C] - pParty->uTimePlayed);
-        return;
-      }
-      v70 = pMouse->GetCursorPos(&v102);
-      result = v70->x + pSRZBufferLineOffsets[pMouse->GetCursorPos(&v100)->y];
-      if ( pRenderer->pActiveZBuffer[result] & 0xFFFF )
-      {
-        v71 = (pRenderer->pActiveZBuffer[result] & 0xFFFF) - 1;
-        item = &pParty->StandartItemsInShops[(int)window_SpeakInHouse->ptr_1C][v71];
-        if ( dialog_menu_id != HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
-          item = &pParty->SpecialItemsInShops[(int)window_SpeakInHouse->ptr_1C][v71];
-        if ( v67 && Str )
-          v10 = pGlobalTXT_LocalizationStrings[181];// "Steal %24"
-        else
-        {
-          v75 = pPlayers[uActiveCharacter]->SelectPhrasesTransaction(item, BildingType_MagicShop, (int)window_SpeakInHouse->ptr_1C, 2);
-          v10 = (char *)pMerchantsBuyPhrases[v75];
-        }
-        v30 = BuilDialogueString(v10, uActiveCharacter - 1, item, (char *)window_SpeakInHouse->ptr_1C, 2, 0);
-        v6 = (174 - pFontArrus->CalcTextHeight(v30, &dialog_window, v3, v3)) / 2 + 138;
-        dialog_window.DrawTitleText(pFontArrus, v3, v6, pWhiteColor, v30, 3);
-        return;
-      }
-    }
-    return;
-  }
-  if ( dialog_menu_id == HOUSE_DIALOGUE_SHOP_DISPLAY_EQUIPMENT )
-  {
-    draw_leather();
-    CharacterUI_InventoryTab_Draw(pPlayers[uActiveCharacter], true);
-    pShopOptions[0] = pGlobalTXT_LocalizationStrings[200];// "Sell"
-    pShopOptions[1] = pGlobalTXT_LocalizationStrings[113];// "Identify"
-    pShopOptions[2] = pGlobalTXT_LocalizationStrings[179];// "Repair"
-    all_text_height = 0;
-    for ( uint i = 0; i < 3; ++i )
-      all_text_height += pFontArrus->CalcTextHeight(pShopOptions[i], &dialog_window, 0, 0);
-    _this = ((174 - all_text_height) / 3);
-    v81 = (3 * (58 - (signed int)_this) - all_text_height) / 2 - (174 - all_text_height) / 3 / 2 + 138;
-    v20 = -pDialogueWindow->pNumPresenceButton < 0;
-    v118 = pDialogueWindow->pStartingPosActiveItem;
-    if ( v20 ^ (pDialogueWindow->pStartingPosActiveItem > pDialogueWindow->pStartingPosActiveItem + pDialogueWindow->pNumPresenceButton) )
-    {
-      v122 = 2;
-      pSrtingNum = 0;
-      do
-      {
-        control_button = pDialogueWindow->GetControl(v118);
-        control_button->uY = (unsigned int)((char *)_this + v81);
-        pTextHeight = pFontArrus->CalcTextHeight(pShopOptions[pSrtingNum], &dialog_window, 0, 0);
-        v85 = control_button->uY;
-        control_button->uHeight = pTextHeight;
-        v81 = pTextHeight + v85 - 1;
-        control_button->uW = v81;
-        text_color = pYellowColor;
-        if ( pDialogueWindow->pCurrentPosActiveItem != v122 )
-          text_color = pWhiteColor;
-        dialog_window.DrawTitleText(pFontArrus, 0, v85, text_color, pShopOptions[pSrtingNum], 3);
-        ++v122;
-        ++pSrtingNum;
-        ++v118;
-      }
-      while ( v118 < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem );
-    }
-    return;
-  }
-  if ( dialog_menu_id == HOUSE_DIALOGUE_SHOP_SELL)
-  {
-    draw_leather();
-    CharacterUI_InventoryTab_Draw(pPlayers[uActiveCharacter], true);
-    DrawTextAtStatusBar(pGlobalTXT_LocalizationStrings[199], 0);// "Select the Item to Sell"
-    if ( !sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win()
-      || (v11 = pMouse->GetCursorPos(&v107)->x - 14,
-          v117 = (v11 >> 5) + 14 * ((pMouse->GetCursorPos(&v99)->y - 17) >> 5),
-          result = (int)pMouse->GetCursorPos(&v105),
-          *(int *)result <= 13)
-      || (result = (int)pMouse->GetCursorPos(&v101), *(int *)result >= 462)
-      || (result = pPlayers[uActiveCharacter]->GetItemIDAtInventoryIndex((int *)&v117), v3 = 0, !result) )
-      return;
-    item = &pPlayers[uActiveCharacter]->pInventoryItems[result - 1];
-    v13 = pPlayers[uActiveCharacter]->SelectPhrasesTransaction(item, BildingType_MagicShop, (int)window_SpeakInHouse->ptr_1C, 3);
-    v30 = BuilDialogueString((char *)pMerchantsSellPhrases[v13], uActiveCharacter - 1, item, (char *)window_SpeakInHouse->ptr_1C, 3, 0);
-    v6 = (174 - pFontArrus->CalcTextHeight(v30, &dialog_window, v3, v3)) / 2 + 138;
-    dialog_window.DrawTitleText(pFontArrus, v3, v6, pWhiteColor, v30, 3);
-    return;
-  }
-  if ( dialog_menu_id == HOUSE_DIALOGUE_SHOP_IDENTIFY)
-  {
-    draw_leather();
-    CharacterUI_InventoryTab_Draw(pPlayers[uActiveCharacter], true);
-    DrawTextAtStatusBar(pGlobalTXT_LocalizationStrings[197], 0);// "Select the Item to Identify"
-    if ( sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
-    {
-      v2 = pMouse->GetCursorPos(&a2)->x - 14;
-      v117 = (v2 >> 5) + 14 * ((pMouse->GetCursorPos(&v98)->y - 17) >> 5);
-      result = (int)pMouse->GetCursorPos(&v111);
-      if ( *(int *)result > 13 )
-      {
-        result = (int)pMouse->GetCursorPos(&v103);
-        if ( *(int *)result < 462 )
-        {
-          result = pPlayers[uActiveCharacter]->GetItemIDAtInventoryIndex((int *)&v117);
-          if ( result )
-          {
-            item = &pPlayers[uActiveCharacter]->pInventoryItems[result-1];
-            if ( item->uAttributes & 1 )
-            {
-              v5 = BuilDialogueString("%24", uActiveCharacter - 1, item, (char *)window_SpeakInHouse->ptr_1C, 4, 0);
-              v6 = (212 - pFontArrus->CalcTextHeight(v5, &dialog_window, 0, 0)) / 2 + 101;
-              dialog_window.DrawTitleText(pFontArrus, 0, v6, pWhiteColor, v5, 3); 
-              return;
-            }
-            v8 = pPlayers[uActiveCharacter]->SelectPhrasesTransaction(item, BildingType_MagicShop, (int)window_SpeakInHouse->ptr_1C, 4);
-            v30 = BuilDialogueString((char *)pMerchantsIdentifyPhrases[v8], uActiveCharacter - 1, item, (char *)window_SpeakInHouse->ptr_1C, 4, 0);
-            v6 = (174 - pFontArrus->CalcTextHeight(v30, &dialog_window, 0, 0)) / 2 + 138;
-            dialog_window.DrawTitleText(pFontArrus, 0, v6, pWhiteColor, v30, 3);
-            return;
-          }
-        }
-      }
-    }
-    return;
-  }
-  if ( dialog_menu_id == HOUSE_DIALOGUE_SHOP_REPAIR)
-  {
-    draw_leather();
-    CharacterUI_InventoryTab_Draw(pPlayers[uActiveCharacter], true);
-    DrawTextAtStatusBar(pGlobalTXT_LocalizationStrings[198], 0);// "Select the Item to Repair"
-    if ( !sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win()
-      || (pTextHeight = pMouse->GetCursorPos(&v110)->x - 14,
-          v117 = (pTextHeight >> 5) + 14 * ((pMouse->GetCursorPos(&v108)->y - 17) >> 5),
-          result = (int)pMouse->GetCursorPos(&v106),
-          *(int *)result <= 13)
-      || (result = (int)pMouse->GetCursorPos(&v104), *(int *)result >= 462)
-      || (result = pPlayers[uActiveCharacter]->GetItemIDAtInventoryIndex((int *)&v117), v3 = 0, !result)
-     // || (result *= 9, !(pPlayers[uActiveCharacter]->field_1F5[4 * result + 15] & 2)) )
-        || (!(pPlayers[uActiveCharacter]->pOwnItems[result-1].uAttributes& 2)) )
-      return;
-    item = &pPlayers[uActiveCharacter]->pInventoryItems[result - 1];
-    v29 = pPlayers[uActiveCharacter]->SelectPhrasesTransaction(&pPlayers[uActiveCharacter]->pInventoryItems[result - 1], BildingType_MagicShop, (int)window_SpeakInHouse->ptr_1C, 5);
-    v30 = BuilDialogueString((char *)pMerchantsRepairPhrases[v29], uActiveCharacter - 1, item, (char *)window_SpeakInHouse->ptr_1C, 5, 0);
-    v6 = (174 - pFontArrus->CalcTextHeight(v30, &dialog_window, v3, v3)) / 2 + 138;
-    dialog_window.DrawTitleText(pFontArrus, v3, v6, pWhiteColor, v30, 3);
-    return;
-  }
-  if ( dialog_menu_id == HOUSE_DIALOGUE_LEARN_SKILLS )
-  {
-    if ( sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
-    {
-      v3 = 0;
-      all_text_height = 0;
-      v33 = (signed __int64)(p2DEvents[(signed int)window_SpeakInHouse->ptr_1C - 1].flt_24 * 500.0);
-      v119 = (const char **)(v33 * (100 - pPlayers[uActiveCharacter]->GetMerchant()) / 100);
-      if ( (signed int)v119 < v33 / 3 )
-        v119 = (const char **)(v33 / 3);
-      pActiveItemNum = pDialogueWindow->pStartingPosActiveItem;
-      v122 = 0;
-      if ( (signed int)pDialogueWindow->pStartingPosActiveItem >= pDialogueWindow->pStartingPosActiveItem + pDialogueWindow->pNumPresenceButton )
-      {
-        sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[544], pPlayers[uActiveCharacter]->pName, pClassNames[pPlayers[uActiveCharacter]->classType]);// 
-                                            // "Seek knowledge elsewhere %s the %s"
-        strcat(pTmpBuf.data(), "\n \n");
-        strcat(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[528]);// "I can offer you nothing further."
-        v6 = (174 - pFontArrus->CalcTextHeight(pTmpBuf.data(), &dialog_window, 0, 0)) / 2 + 138;
-        dialog_window.DrawTitleText(pFontArrus, v3, v6, pYellowColor, pTmpBuf.data(), 3);
-        return;
-      }
-      do
-      {
-        v36 = pDialogueWindow->GetControl(pActiveItemNum)->msg_param - 36;
-        if ( byte_4ED970_skill_learn_ability_by_class_table[pPlayers[uActiveCharacter]->classType][v36] && !pPlayers[uActiveCharacter]->pActiveSkills[v36] )
-        {
-          all_text_height += pFontArrus->CalcTextHeight(pSkillNames[v36], &dialog_window, 0, 0);
-          ++v122;
-        }
-        ++pActiveItemNum;
-      }
-      while ( pActiveItemNum < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem );
-      if ( !v122 )
-      {
-        sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[544], pPlayers[uActiveCharacter]->pName, pClassNames[pPlayers[uActiveCharacter]->classType]);// 
-                                            // "Seek knowledge elsewhere %s the %s"
-        strcat(pTmpBuf.data(), "\n \n");
-        strcat(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[528]);// "I can offer you nothing further."
-        v6 = (174 - pFontArrus->CalcTextHeight(pTmpBuf.data(), &dialog_window, 0, 0)) / 2 + 138;
-        dialog_window.DrawTitleText(pFontArrus, v3, v6, pYellowColor, pTmpBuf.data(), 3);
-        return;
-      }
-      sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[401], v119);// "Skill Cost: %lu"
-      dialog_window.DrawTitleText(pFontArrus, 0, 0x92u, 0, pTmpBuf.data(), 3u);
-      v119 = (const char **)((149 - all_text_height) / v122);
-      if ( (149 - all_text_height) / v122 > 32 )
-        v119 = (const char **)32;
-      v38 = (149 - v122 * (signed int)v119 - all_text_height) / 2 - (signed int)v119 / 2 + 162;
-      v118 = 2;
-      if ( pDialogueWindow->pStartingPosActiveItem < pDialogueWindow->pStartingPosActiveItem + pDialogueWindow->pNumPresenceButton )
-      {
-        v122 = 2;
-        do
-        {
-          control_button = pDialogueWindow->GetControl(v122);
-          v41 = control_button->msg_param - 36;
-          if ( !byte_4ED970_skill_learn_ability_by_class_table[pPlayers[uActiveCharacter]->classType][v41] || pPlayers[uActiveCharacter]->pActiveSkills[v41] )
-          {
-            control_button->uW = 0;
-            control_button->uHeight = 0;
-            control_button->uY = 0;
-          }
-          else
-          {
-            control_button->uY = (unsigned int)((char *)v119 + v38);
-            pTextHeight = pFontArrus->CalcTextHeight(pSkillNames[v41], &dialog_window, 0, 0);
-            v44 = control_button->uY;
-            control_button->uHeight = pTextHeight;
-            v38 = v44 + pTextHeight - 1;
-            control_button->uW = v38;
-            text_color = pYellowColor;
-            if ( pDialogueWindow->pCurrentPosActiveItem != v122 )
-              text_color = pWhiteColor;
-            dialog_window.DrawTitleText(pFontArrus, 0, v44, text_color, pSkillNames[v41], 3);
-          }
-          ++v122;
-        }
-        while ( v122 < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem );
-      }
-    }
-    return;
-  }
-  return;
-}
-
-
 //----- (004B6478) --------------------------------------------------------
 void sub_4B6478()
     {
@@ -6256,329 +3639,344 @@
   }
   return;
 }
-//----- (004BC8D5) --------------------------------------------------------
-void SpellBookGenerator()//for GuildDialogs
+
+//----- (004B2A74) --------------------------------------------------------
+void SimpleHouseAndBoatsDialog()
 {
-  int pItemNum; // esi@1
-  int v4; // esi@7
+  char *v0; // esi@3
+  char *v1; // ST1C_4@3
+  char *v2; // eax@3
+  const char *v3; // ST1C_4@5
+  int v4; // eax@5
+  unsigned int i; // eax@5
+  NPCData *v6; // esi@6
+  unsigned __int16 v7; // bx@6
+  unsigned int v8; // eax@6
+  int v9; // eax@11
+  unsigned int v10; // ecx@12
+  int v11; // eax@12
+  int v12; // esi@12
+  char *v13; // eax@12
+  GUIWindow *v14; // ebx@13
+  char *v15; // esi@14
+  GUIButton *v16; // eax@15
+  unsigned int v17; // ecx@15
+  int v18; // ecx@17
+  int v19; // ecx@18
+  int v20; // ecx@19
+  int v21; // ecx@20
+  int v22; // ecx@21
+  unsigned int v23; // ecx@23
+  int v24; // ecx@35
+  int v25; // ecx@36
+  int v26; // ecx@37
+  int v27; // ecx@38
+  int v28; // ecx@39
+  char *v29; // esi@42
+  unsigned int v30; // ST20_4@42
+  int v31; // ST1C_4@42
+  unsigned int v32; // eax@42
+  char *v33; // eax@43
+  int v34; // esi@51
+  int v35; // eax@51
+  unsigned int v36; // edi@51
+  GUIButton *v37; // eax@52
+  int v38; // eax@52
+  signed int v39; // ecx@54
+  int v40; // edi@57
+  GUIButton *v41; // eax@60
+  GUIButton *v42; // esi@60
+  const char *v43; // ebx@60
+  int v44; // eax@60
+  unsigned int v45; // ecx@60
+  unsigned __int16 v46; // ax@60
+  GUIFont *v47; // ebx@64
+  int v48; // esi@64
+  char *v49; // eax@66
+  GUIWindow w; // [sp+Ch] [bp-110h]@64
+  GUIWindow v52; // [sp+60h] [bp-BCh]@13
+  GUIWindow a1; // [sp+B4h] [bp-68h]@1
+  unsigned int v54; // [sp+108h] [bp-14h]@14
+  int v55; // [sp+10Ch] [bp-10h]@6
+  int v56; // [sp+110h] [bp-Ch]@13
+  char *pInString; // [sp+114h] [bp-8h]@12
+  NPCData *v58; // [sp+118h] [bp-4h]@6
 
-  for( int i = 0; i < 12; ++i )
+  memcpy(&a1, pDialogueWindow, sizeof(a1));
+  if ( pDialogueNPCCount == uNumDialogueNPCPortraits && uHouse_ExitPic )
   {
-    if ( p2DEvents[window_SpeakInHouse->par1C - 1].uType >= 5 )
+    v0 = pMapStats->pInfos[uHouse_ExitPic].pName;
+    v1 = pMapStats->pInfos[uHouse_ExitPic].pName;
+    a1.uFrameX = 493;
+    a1.uFrameWidth = 126;
+    a1.uFrameZ = 366;
+    a1.DrawTitleText(pFontCreate, 0, 2u, 0, v1, 3u);
+    a1.uFrameX = 483;
+    a1.uFrameWidth = 148;
+    a1.uFrameZ = 334;
+    v2 = pTransitionStrings[uHouse_ExitPic];
+    if ( !v2 )
     {
-      if ( p2DEvents[window_SpeakInHouse->par1C - 1].uType <= 13 )
-        pItemNum = rand() % word_4F0F30[(signed int)window_SpeakInHouse->par1C - 139] + 11 * p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].uType + 345;
-      else
-      {
-        if ( p2DEvents[window_SpeakInHouse->par1C - 1].uType == 14 )
-          v4 = rand() % 4;
-        else if ( p2DEvents[window_SpeakInHouse->par1C - 1].uType == 15 )
-          v4 = rand() % 3 + 4;
-        else if ( p2DEvents[window_SpeakInHouse->par1C - 1].uType == 16 )
-          v4 = rand() % 2 + 7;
-        if( p2DEvents[window_SpeakInHouse->par1C - 1].uType <= 16 )
-          pItemNum = rand() % word_4F0F30[(signed int)window_SpeakInHouse->par1C - 139] + 11 * v4 + 400;
-      }
-    }
-    if ( pItemNum == 487 )
-    {
-      if ( !(unsigned __int16)_449B57_test_bit(pParty->_quest_bits, 239) )
-        pItemNum = 486;
+      sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[411], v0);
+      v2 = pTmpBuf.data();
     }
-    ItemGen * item_spellbook = &pParty->SpellBooksInGuilds[window_SpeakInHouse->par1C-139][i];
-    item_spellbook->Reset();
-    pParty->SpellBooksInGuilds[window_SpeakInHouse->par1C-139][i].uItemID = pItemNum;
-    pParty->SpellBooksInGuilds[window_SpeakInHouse->par1C-139][i].Identified();
-    ItemsInShopTexture[i] = pIcons_LOD->LoadTexturePtr(pItemsTable->pItems[pItemNum].pIconName, TEXTURE_16BIT_PALETTE);
-  }
-  return;
-}
-//----- (004BDB56) --------------------------------------------------------
-void __cdecl UIShop_Buy_Identify_Repair()
-{
-  int v8; // eax@15
-  unsigned int pItemID; // esi@20
-  ItemGen *item; // esi@21
-  unsigned int v15; // eax@33
-  POINT *pCursorPos; // esi@37
-  int v18; // ecx@37
-  float pPriceMultiplier; // ST1C_4@38
-  int taken_item; // eax@40
-  ItemGen *bought_item; // esi@51
-  int party_reputation; // eax@55
-  int v39; // eax@63
-  int v42; // esi@74
-  signed int v43; // ebx@74
-  unsigned __int16 *pSkill; // esi@77
-  int v55; // [sp+0h] [bp-B4h]@26
-  POINT cursor; // [sp+40h] [bp-74h]@37
-  int a6; // [sp+98h] [bp-1Ch]@57
-  int a3; // [sp+9Ch] [bp-18h]@53
-  unsigned int uNumSeconds; // [sp+A4h] [bp-10h]@53
-  unsigned int v79; // [sp+A8h] [bp-Ch]@9
-  int uPriceItemService; // [sp+ACh] [bp-8h]@12
-
-  if ( pCurrentScreen == SCREEN_E )
-  {
-    OnInventoryLeftClick();
-    return;
-  }
-  if ( !sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
-  {
-    pAudioPlayer->PlaySound(SOUND_27, 0, 0, -1, 0, 0, 0, 0);
+    v3 = v2;
+    v4 = pFontCreate->CalcTextHeight(v2, &a1, 0, 0);
+    a1.DrawTitleText(pFontCreate, 0, (212 - v4) / 2 + 101, 0, v3, 3u);
     return;
   }
-
-  switch(dialog_menu_id)
+  a1.uFrameWidth -= 10;
+  a1.uFrameZ -= 10;
+  v58 = HouseNPCData[(unsigned int)((char *)pDialogueNPCCount + -(dword_591080 != 0) )];//- 1
+  v6 = v58;
+  v55 = TargetColor(0xE1u, 0xCDu, 0x23u);
+  v7 = TargetColor(0x15u, 0x99u, 0xE9u);
+  v8 = v6->uProfession;
+  if ( v8 )
+    sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[429], v6->pName, aNPCProfessionNames[v8]);
+  else
+    strcpy(pTmpBuf.data(), v6->pName);
+  a1.DrawTitleText(pFontCreate, 0x1E3u, 0x71u, v7, pTmpBuf.data(), 3u);
+  if ( !dword_591080 )
   {
-    case HOUSE_DIALOGUE_SHOP_DISPLAY_EQUIPMENT:
-    {
-      pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] = 103;
-      OnInventoryLeftClick();
-      break;
-    }
-    case HOUSE_DIALOGUE_GUILD_BUY_BOOKS:
-    {
-      pCursorPos = pMouse->GetCursorPos(&cursor);
-      v18 = pRenderer->pActiveZBuffer[pCursorPos->x + pSRZBufferLineOffsets[pMouse->GetCursorPos(&cursor)->y]] & 0xFFFF;
-      if ( !v18 )
-        return;
-      bought_item = (ItemGen *)(&pParty->pPlayers[1].uExpressionTimeLength + 18 * (v18 + 12 * (int)window_SpeakInHouse->ptr_1C));
-      pPriceMultiplier = p2DEvents[(signed int)window_SpeakInHouse->ptr_1C - 1].fPriceMultiplier;
-      uPriceItemService = pPlayers[uActiveCharacter]->GetBuyingPrice(bought_item->GetValue(), pPriceMultiplier);
-      GetAsyncKeyState(VK_CONTROL);
-      if ( pParty->uNumGold < uPriceItemService )
-      {
-        PlayHouseSound((unsigned int)window_SpeakInHouse->ptr_1C, (HouseSoundID)2);
-        ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2);
-        return;
-      }
-      taken_item = pPlayers[uActiveCharacter]->AddItem(-1, bought_item->uItemID);
-      if ( taken_item )
-      {
-        bought_item->SetIdentified();
-        memcpy(&pPlayers[uActiveCharacter]->pInventoryItems[taken_item - 1], bought_item, 0x24u);
-        dword_F8B1E4 = 1;
-        Party::TakeGold(uPriceItemService);
-        viewparams->bRedrawGameUI = 1;
-        bought_item->Reset();
-        pRenderer->ClearZBuffer(0, 479);
-        pPlayers[uActiveCharacter]->PlaySound((PlayerSpeech)SPEECH_75, 0);
-        return;
-      }
-      pPlayers[uActiveCharacter]->PlaySound(SPEECH_NoRoom, 0);
-      ShowStatusBarString(pGlobalTXT_LocalizationStrings[563], 5);  // "Pack is Full!"
-      break;
-    }
-    case HOUSE_DIALOGUE_SHOP_SELL:
+    if ( !uDialogueType )
     {
-      v79 = ((pMouse->GetCursorPos(&cursor)->x - 14) >> 5) + 14 * ((pMouse->GetCursorPos(&cursor)->y - 17) >> 5);
-      if ( pMouse->GetCursorPos(&cursor)->x <= 13
-        || pMouse->GetCursorPos(&cursor)->x >= 462
-        || (v15 = pPlayers[uActiveCharacter]->GetItemIDAtInventoryIndex((int *)&v79), !v15) )
-          return;
-      if ( MerchandiseTest(&pPlayers[uActiveCharacter]->pInventoryItems[v15 - 1], (int)window_SpeakInHouse->ptr_1C) )
-      {
-        dword_F8B1E4 = 1;
-        pPlayers[uActiveCharacter]->SalesProcess(v79, v15 - 1, (int)window_SpeakInHouse->ptr_1C);
-        viewparams->bRedrawGameUI = 1;
-        pRenderer->ClearZBuffer(0, 479);
-        pPlayers[uActiveCharacter]->PlaySound((PlayerSpeech)77, 0);
-        return;
-      }
-      pPlayers[uActiveCharacter]->PlaySound(SPEECH_79, 0);
-      pAudioPlayer->PlaySound(SOUND_27, 0, 0, -1, 0, 0, 0, 0);
-      break;
-    }
-    case HOUSE_DIALOGUE_SHOP_IDENTIFY:
-    {
-      pMouse->GetCursorPos(&cursor);
-      v79 = ((cursor.x - 14) >> 5) + 14 * ((cursor.y - 17) >> 5);
-      if (cursor.x > 13  && cursor.x < 462)
-      {
-        pItemID = pPlayers[uActiveCharacter]->GetItemIDAtInventoryIndex((int *)&v79);
-        if ( pItemID )
-        {
-          uPriceItemService = pPlayers[uActiveCharacter]->GetPriceIdentification(p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].fPriceMultiplier);
-          item = &pPlayers[uActiveCharacter]->pInventoryItems[pItemID - 1];
-          if ( !(item->uAttributes & 1) )
-          {
-            if ( MerchandiseTest(item, (int)window_SpeakInHouse->ptr_1C) )
-            {
-              if ( pParty->uNumGold >= uPriceItemService )
-              {
-                dword_F8B1E4 = 1;
-                Party::TakeGold(uPriceItemService);
-                item->uAttributes |= 1;
-                pPlayers[uActiveCharacter]->PlaySound(SPEECH_73, 0);
-                ShowStatusBarString(pGlobalTXT_LocalizationStrings[569], 2);
-                return;
-              }
-              PlayHouseSound((unsigned int)window_SpeakInHouse->ptr_1C, (HouseSoundID)2);
-              return;
-            }
-            pAudioPlayer->PlaySound(SOUND_27, 0, 0, -1, 0, 0, 0, 0);
-            pPlayers[uActiveCharacter]->PlaySound((PlayerSpeech)79, 0);
-            return;
-          }
-          pPlayers[uActiveCharacter]->PlaySound((PlayerSpeech)76, 0);
-          return;
-        }
-      }
-      break;
-    }
-    case HOUSE_DIALOGUE_SHOP_REPAIR:
-    {
-      v79 = ((pMouse->GetCursorPos(&cursor)->x - 14) >> 5) + 14 * ((pMouse->GetCursorPos(&cursor)->y - 17) >> 5);
-      if ( pMouse->GetCursorPos(&cursor)->x > 13 )
+      v9 = v6->greet;
+      if ( v9 )
       {
-        if ( pMouse->GetCursorPos(&cursor)->x < 462 )
-        {
-          pItemID = pPlayers[uActiveCharacter]->GetItemIDAtInventoryIndex((int *)&v79);
-          if ( pItemID )
-          {
-            item = &pPlayers[uActiveCharacter]->pInventoryItems[pItemID - 1];
-            pPriceMultiplier = p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].fPriceMultiplier;
-            auto _v = (ItemGen *)&pPlayers[uActiveCharacter]->pInventoryItems[pItemID - 1];
-            uPriceItemService = pPlayers[uActiveCharacter]->GetPriceRepair(_v->GetValue(), pPriceMultiplier);
-            if ( item->uAttributes & 2 )
-            {
-              if ( MerchandiseTest(item, (int)window_SpeakInHouse->ptr_1C) )
-              {
-                if ( pParty->uNumGold >= uPriceItemService )
-                {
-                  dword_F8B1E4 = 1;
-                  Party::TakeGold(uPriceItemService);
-                  v8 = item->uAttributes;
-                  LOBYTE(v8) = v8 & 0xFD;
-                  item->uAttributes = v8 | 1;
-                  pPlayers[uActiveCharacter]->PlaySound(SPEECH_74, 0);
-                  ShowStatusBarString(pGlobalTXT_LocalizationStrings[570], 2);
-                  return;
-                }
-                PlayHouseSound((unsigned int)window_SpeakInHouse->ptr_1C, (HouseSoundID)2);
-                return;
-              }
-              pAudioPlayer->PlaySound(SOUND_27, 0, 0, -1, 0, 0, 0, 0);
-              pPlayers[uActiveCharacter]->PlaySound((PlayerSpeech)79, 0);
-              return;
-            }
-            pPlayers[uActiveCharacter]->PlaySound((PlayerSpeech)76, 0);
-            return;
-          }
-        }
-      }
-      break;
-    }
-    case HOUSE_DIALOGUE_SHOP_BUY_STANDARD:
-    case HOUSE_DIALOGUE_SHOP_BUY_SPECIAL:
-    {
-      pCursorPos = pMouse->GetCursorPos(&cursor);
-      v18 = pRenderer->pActiveZBuffer[pCursorPos->x + pSRZBufferLineOffsets[pCursorPos->y]] & 0xFFFF;
-      if ( !v18 )
-        return;
-      if ( dialog_menu_id == HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
-        bought_item = (ItemGen *)&pParty->StandartItemsInShops[(int)window_SpeakInHouse->ptr_1C][v18 - 1];
-      else
-        bought_item = &pParty->SpecialItemsInShops[(int)window_SpeakInHouse->ptr_1C][v18 - 1];//(ItemGen *)&pParty->field_C59C[v31 + 724];
-      uPriceItemService = pPlayers[uActiveCharacter]->GetBuyingPrice(bought_item->GetValue(), p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].fPriceMultiplier);
-      uNumSeconds = 0;
-      a3 = 0;
-      if ( pMapStats->GetMapInfo(pCurrentMapName.data()) )
-        a3 = pMapStats->pInfos[pMapStats->GetMapInfo(pCurrentMapName.data())]._steal_perm;
-      party_reputation = GetPartyReputation();
-      if (pPlayers[uActiveCharacter]->CanSteal())
-      {
-        if ( GetAsyncKeyState(VK_CONTROL) )
-        {
-          uNumSeconds = pPlayers[uActiveCharacter]->StealFromShop(bought_item, a3, party_reputation, 0, &a6);
-          if ( !uNumSeconds )
-          {
-            sub_4B1447_party_fine((int)window_SpeakInHouse->ptr_1C, 0, a6);
-            return;
-          }
-        }
+        v10 = v6->uFlags;
+        a1.uFrameWidth = game_viewport_width;
+        a1.uFrameZ = 452;
+        pInString = (char *)*(&pNPCStats->field_17884 + ((v10 & 3) == 2) + 2 * v9);
+        v11 = pFontArrus->CalcTextHeight(pInString, &a1, 13, 0);
+        v12 = v11 + 7;
+        pRenderer->_4A6A68(8, 352 - (v11 + 7),
+          pIcons_LOD->GetTexture(uTextureID_Leather),
+          pIcons_LOD->GetTexture(uTextureID_Leather)->uTextureHeight - (v11 + 7));
+        pRenderer->DrawTextureIndexed(8u, 347 - v12, pTexture_591428);
+        v13 = FitTextInAWindow(pInString, pFontArrus, &a1, 0xDu, 0);
+        pDialogueWindow->DrawText(pFontArrus, 13, 354 - v12, 0, v13, 0, 0, 0);
       }
-      if ( pParty->uNumGold < uPriceItemService )
-      {
-        if ( uNumSeconds != 2 )
-        {
-          if ( uNumSeconds != 1 )
-          {
-            PlayHouseSound((unsigned int)window_SpeakInHouse->ptr_1C, (HouseSoundID)2);
-            ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2);// "You don't have enough gold"
-            return;
-          }
-        }
-      }
-      v39 = pPlayers[uActiveCharacter]->AddItem(-1, bought_item->uItemID);
-      if ( v39 )
-      {
-        bought_item->SetIdentified();
-        memcpy(&pPlayers[uActiveCharacter]->pInventoryItems[v39 - 1], bought_item, sizeof(ItemGen));
-        if ( pPlayers[uActiveCharacter]->CanSteal() )
-        {
-          if ( GetAsyncKeyState(VK_CONTROL) )
-          {
-            if ( uNumSeconds == 1 || uNumSeconds == 2 )
-            {
-              pPlayers[uActiveCharacter]->pInventoryItems[v39 - 1].SetStolen();
-              sub_4B1447_party_fine((int)window_SpeakInHouse->ptr_1C, uNumSeconds, a6);
-              viewparams->bRedrawGameUI = 1;
-              bought_item->Reset();
-              pRenderer->ClearZBuffer(0, 479);
-              pPlayers[uActiveCharacter]->PlaySound((PlayerSpeech)SPEECH_75, 0);
-              return;
-            }
-          }
-        }
-        dword_F8B1E4 = 1;
-        Party::TakeGold(uPriceItemService);
-        viewparams->bRedrawGameUI = 1;
-        bought_item->Reset();
-        pRenderer->ClearZBuffer(0, 479);
-        pPlayers[uActiveCharacter]->PlaySound((PlayerSpeech)SPEECH_75, 0);
-        return;
-      }
-      pPlayers[uActiveCharacter]->PlaySound(SPEECH_NoRoom, 0);
-      ShowStatusBarString(pGlobalTXT_LocalizationStrings[563], 2); // "Pack is Full!"
-      break;
-    }
-    default:// if click video screen in shop
-    {
-      __debugbreak(); // please do record these dialogue ids to the HOUSE_DIALOGUE_MENU  enum
-      if( dialog_menu_id >= 36 && dialog_menu_id <= 72 )
-      {
-        v42 = dialog_menu_id - 36;
-        //v43 = (signed __int64)(*(float *)&p2DEvents_minus1__24[13 * (unsigned int)ptr_507BC0->ptr_1C] * 500.0);
-        v43 = (signed __int64)(p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].flt_24 * 500.0);
-        uPriceItemService = v43 * (100 - pPlayers[uActiveCharacter]->GetMerchant()) / 100;
-        if ( uPriceItemService < v43 / 3 )
-          uPriceItemService = v43 / 3;
-        if ( byte_4ED970_skill_learn_ability_by_class_table[pPlayers[uActiveCharacter]->classType][v42] )
-        {
-          pSkill = &pPlayers[uActiveCharacter]->pActiveSkills[v42];
-          if ( !*pSkill )
-          {
-            if ( pParty->uNumGold < uPriceItemService )
-            {
-              ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2);// "You don't have enough gold"
-              if ( in_current_building_type == BildingType_Training )
-                v55 = 4;
-              else
-                v55 = 2;
-              PlayHouseSound((unsigned int)window_SpeakInHouse->ptr_1C, (HouseSoundID)v55);
-              return;
-            }
-            Party::TakeGold(uPriceItemService);
-            dword_F8B1E4 = 1;
-           *pSkill = 1;
-            pPlayers[uActiveCharacter]->PlaySound((PlayerSpeech)78, 0);
-            return;
-          }
-        }
-      }
-      break;
     }
   }
+  v14 = pDialogueWindow;
+  memcpy(&v52, pDialogueWindow, sizeof(v52));
+  v52.uFrameX = 483;
+  v52.uFrameWidth = 148;
+  v52.uFrameZ = 334;
+  v56 = v52.pStartingPosActiveItem;
+  if ( v52.pStartingPosActiveItem < v52.pStartingPosActiveItem + v52.pNumPresenceButton )
+  {
+    v15 = "";//(char *)v54;
+    while ( 1 )
+    {
+      v16 = v52.GetControl(v56);
+      v17 = v16->msg_param;
+      pInString = (char *)v16;
+      if ( (signed int)v17 > 24 )
+      {
+        v24 = v17 - 76;
+        if ( !v24 )
+        {
+          v15 = pGlobalTXT_LocalizationStrings[406];
+          goto LABEL_49;
+        }
+        v25 = v24 - 1;
+        if ( !v25 )
+        {
+          v15 = pGlobalTXT_LocalizationStrings[407];
+          goto LABEL_49;
+        }
+        v26 = v25 - 2;
+        if ( !v26 )
+        {
+          v33 = _4B254D_SkillMasteryTeacher((int)v52.ptr_1C);
+LABEL_44:
+          v15 = v33;
+LABEL_45:
+          v16 = (GUIButton *)pInString;
+          goto LABEL_49;
+        }
+        v27 = v26 - 3;
+        if ( !v27 )
+        {
+          v33 = (char *)ContractSelectText((int)v52.ptr_1C);
+          goto LABEL_44;
+        }
+        v28 = v27 - 1;
+        if ( !v28 )
+        {
+          v29 = (char *)&pMonsterStats + 88 * word_F8B1A0;
+          v30 = TargetColor(0xFFu, 0xFFu, 0xFFu);
+          v31 = *(int *)v29;
+          v32 = TargetColor(0xFFu, 0xFFu, 0x9Bu);
+          sprintfex(pTmpBuf.data(), "\f%05d%s\f%05d", v32, v31, v30);
+          sprintfex(pTmpBuf2.data(), dword_F8B1A4, pTmpBuf.data(), 100 * (unsigned __int8)v29[8]);
+          current_npc_text = pTmpBuf2.data();
+          v15 = "";
+          goto LABEL_45;
+        }
+        if ( v28 != 10 )
+          goto LABEL_41;
+      }
+      else
+      {
+        if ( v17 == 24 )
+        {
+          v23 = v58->evt_F;
+LABEL_33:
+          v15 = (char *)pNPCTopics[v23-1].pTopic;//(&dword_721660)[8 * v23];
+          if ( !v15 )
+          {
+            v16->msg_param = 0;
+            v15 = "";
+          }
+          goto LABEL_49;
+        }
+        v18 = v17 - 13;
+        if ( v18 )
+        {
+          v19 = v18 - 6;
+          if ( !v19 )
+          {
+            v23 = v58->evt_A;
+            goto LABEL_33;
+          }
+          v20 = v19 - 1;
+          if ( !v20 )
+          {
+            v15 = (char *)pNPCTopics[v58->evt_B-1].pTopic;//(&dword_721660)[8 * v58->evtb];
+            if ( !v15 )
+            {
+              v16->msg_param = 0;
+              v15 = "";
+            }
+            if ( uDialogueType != 84 )
+              goto LABEL_49;
+            sprintf(pTmpBuf.data(), format_4E2D80, v55, pItemsTable->pItems[contract_approved].pUnidentifiedName);
+            sprintf(pTmpBuf2.data(), current_npc_text, pTmpBuf.data());
+            current_npc_text = pTmpBuf2.data();
+            goto LABEL_45;
+          }
+          v21 = v20 - 1;
+          if ( !v21 )
+          {
+            v23 = v58->evt_C;
+            goto LABEL_33;
+          }
+          v22 = v21 - 1;
+          if ( !v22 )
+          {
+            v23 = v58->evt_D;
+            goto LABEL_33;
+          }
+          if ( v22 == 1 )
+          {
+            v23 = v58->evt_E;
+            goto LABEL_33;
+          }
+LABEL_41:
+          v15 = "";
+          goto LABEL_49;
+        }
+        v15 = pGlobalTXT_LocalizationStrings[122];
+      }
+LABEL_49:
+      strcpy(v16->pButtonName, v15);
+      ++v56;
+      if ( v56 >= v52.pStartingPosActiveItem + v52.pNumPresenceButton )
+      {
+        v14 = pDialogueWindow;
+        break;
+      }
+    }
+  }
+  v34 = 0;
+  v54 = TargetColor(0xFFu, 0xFFu, 0xFFu);
+  v35 = TargetColor(0xE1u, 0xCDu, 0x23u);
+  v36 = v14->pStartingPosActiveItem;
+  v55 = v35;
+  for ( i = v36 + v14->pNumPresenceButton; (signed int)v36 < (signed int)i; i = pDialogueWindow->pNumPresenceButton
+                                                                    + pDialogueWindow->pStartingPosActiveItem )
+  {
+    v37 = v14->GetControl(v36);
+    v38 = pFontArrus->CalcTextHeight(v37->pButtonName, &v52, 0, 0);
+    v14 = pDialogueWindow;
+    v34 += v38;
+    ++v36;
+  }
+  v39 = v14->pNumPresenceButton;
+  if ( v39 )
+  {
+    v58 = (NPCData *)((174 - v34) / v39);
+    if ( (signed int)v58 > 32 )
+      v58 = (NPCData *)32;
+    pInString = (char *)2;
+    v40 = (174 - (signed int)v58 * v39 - v34) / 2 - (signed int)v58 / 2 + 138;
+    v56 = v14->pStartingPosActiveItem;
+    i = v56;
+    if ( (signed int)i < (signed int)(i + v39) )
+    {
+      while ( 1 )
+      {
+        v41 = v14->GetControl(i);
+        v42 = v41;
+        v43 = v41->pButtonName;
+        v41->uY = (unsigned int)((char *)v58 + v40);
+        v44 = pFontArrus->CalcTextHeight(v41->pButtonName, &v52, 0, 0);
+        v45 = v42->uY;
+        v42->uHeight = v44;
+        v40 = v45 + v44 - 1;
+        v42->uW = v40;
+        v46 = v55;
+        if ( (char *)pDialogueWindow->pCurrentPosActiveItem != pInString )
+          v46 = v54;
+        v52.DrawTitleText(pFontArrus, 0, v45, v46, v43, 3u);
+        v14 = pDialogueWindow;
+        ++pInString;
+        ++v56;
+        i = pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem;
+        if ( v56 >= (signed int)i )
+          break;
+        i = v56;
+      }
+    }
+  }
+  if ( current_npc_text )
+  {
+    w.uFrameWidth = 458;
+    w.uFrameZ = 457;
+    v47 = pFontArrus;
+    v48 = pFontArrus->CalcTextHeight(current_npc_text, &w, 13, 0) + 7;
+    if ( 352 - v48 < 8 )
+    {
+      v47 = pFontCreate;
+      v48 = pFontCreate->CalcTextHeight(current_npc_text, &w, 13, 0) + 7;
+    }
+    pRenderer->_4A6A68(8, 352 - v48,
+      pIcons_LOD->GetTexture(uTextureID_Leather),
+      pIcons_LOD->GetTexture(uTextureID_Leather)->uTextureHeight - v48);
+    pRenderer->DrawTextureIndexed(8u, 347 - v48, pTexture_591428);
+    v49 = FitTextInAWindow(current_npc_text, v47, &w, 0xDu, 0);
+    a1.DrawText(v47, 13, 354 - v48, 0, v49, 0, 0, 0);
+  }
+}
+//----- (004B4F4F) --------------------------------------------------------
+void JailDialog()
+{
+  const char *v0; // esi@1
+  const char *v1; // ST10_4@1
+  unsigned __int16 v2; // ST0C_2@1
+  int v3; // eax@1
+  GUIWindow v5; // [sp+8h] [bp-54h]@1
+
+  memcpy(&v5, window_SpeakInHouse, sizeof(v5));
+  v0 = pGlobalTXT_LocalizationStrings[672];
+  v1 = pGlobalTXT_LocalizationStrings[672];
+  v5.uFrameX = 483;
+  v5.uFrameWidth = 148;
+  v5.uFrameZ = 334;
+  v2 = TargetColor(0xFFu, 0xFFu, 0x9Bu);
+  v3 = pFontArrus->CalcTextHeight(v0, &v5, 0, 0);
+  v5.DrawTitleText(pFontArrus, 0, (310 - v3) / 2 + 18, v2, v1, 3u);
 }
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/UI/UIHouses.h	Sun Jun 23 14:27:57 2013 +0600
@@ -0,0 +1,138 @@
+#pragma once
+
+enum HOUSE_DIALOGUE_MENU: __int32
+{
+  HOUSE_DIALOGUE_NULL = 0,
+  HOUSE_DIALOGUE_MAIN = 1,
+  HOUSE_DIALOGUE_SHOP_BUY_STANDARD = 2,
+  HOUSE_DIALOGUE_SHOP_SELL = 3,
+  HOUSE_DIALOGUE_SHOP_IDENTIFY = 4,
+  HOUSE_DIALOGUE_SHOP_REPAIR = 5,
+  HOUSE_DIALOGUE_SHOP_6 = 6,
+  HOUSE_DIALOGUE_BANK_7 = 7,
+  HOUSE_DIALOGUE_BANK_8 = 8,
+  HOUSE_DIALOGUE_9 = 9,
+  HOUSE_DIALOGUE_TEMPLE_HEAL = 10,
+  HOUSE_DIALOGUE_TEMPLE_DONATE = 11,
+  HOUSE_DIALOGUE_12 = 12,
+  HOUSE_DIALOGUE_13 = 13,
+  HOUSE_DIALOGUE_14 = 14,
+  HOUSE_DIALOGUE_TAVERN_REST = 15,
+  HOUSE_DIALOGUE_TAVERN_BUY_FOOD = 16,
+  HOUSE_DIALOGUE_TRAININGHALL_TRAIN = 17,
+  HOUSE_DIALOGUE_GUILD_BUY_BOOKS = 18,
+  //...
+  HOUSE_DIALOGUE_36 = 36,
+  //..
+  HOUSE_DIALOGUE_GUILD_LEARN_SKILL = 72,
+  //...
+  HOUSE_DIALOGUE_SHOP_DISPLAY_EQUIPMENT = 94,
+  HOUSE_DIALOGUE_SHOP_BUY_SPECIAL = 95,
+  HOUSE_DIALOGUE_LEARN_SKILLS = 96,
+  HOUSE_DIALOGUE_97 = 97,
+  HOUSE_DIALOGUE_98 = 98,
+  HOUSE_DIALOGUE_TOWNHALL_99 = 99,
+  HOUSE_DIALOGUE_TOWNHALL_100 = 100,
+  HOUSE_DIALOGUE_TAVERN_ARCOMAGE_MAIN = 101,
+  HOUSE_DIALOGUE_TAVERN_ARCOMAGE_RULES = 102,
+  HOUSE_DIALOGUE_TAVERN_ARCOMAGE_VICTORY_CONDITIONS = 103,
+  HOUSE_DIALOGUE_TAVERN_ARCOMAGE_RESULT = 104,
+  HOUSE_DIALOGUE_TRANSPORT_SCHEDULE_1 = 105,
+  HOUSE_DIALOGUE_TRANSPORT_SCHEDULE_2 = 106,
+  HOUSE_DIALOGUE_TRANSPORT_SCHEDULE_3 = 107,
+  HOUSE_DIALOGUE_TRANSPORT_SCHEDULE_4 = 108,
+  HOUSE_DIALOGUE_OTHER = -1
+};
+
+/*  349 */
+enum HOUSE_ID
+{
+  HOUSE_SMITH_EMERALD_ISLE = 1,
+  HOUSE_ARMOURER_EMERALD_ISLE = 15,
+  HOUSE_MAGE_EMERALD_ISLE = 29,
+  HOUSE_MAGE_HARMONDALE = 30,
+  HOUSE_ALCHEMIST_EMERALD_ISLE = 42,
+  HOUSE_ALCHEMIST_HARMONDALE = 43,
+  HOUSE_STABLES_HARMONDALE = 54,
+  HOUSE_STABLES_STEADWICK = 55,
+  HOUSE_STABLES_56 = 56,
+  HOUSE_STABLES_57 = 57,
+  HOUSE_STABLES_58 = 58,
+  HOUSE_STABLES_59 = 59,
+  HOUSE_STABLES_60 = 60,
+  HOUSE_STABLES_61 = 61,
+  HOUSE_STABLES_62 = 62,
+  HOUSE_BOATS_63 = 63,
+  HOUSE_BOATS_64 = 64,
+  HOUSE_BOATS_65 = 65,
+  HOUSE_BOATS_66 = 66,
+  HOUSE_BOATS_67 = 67,
+  HOUSE_BOATS_68 = 68,
+  HOUSE_BOATS_69 = 69,
+  HOUSE_BOATS_70 = 70,
+  HOUSE_BOATS_71 = 71,
+  HOUSE_BOATS_72 = 72,
+  HOUSE_BOATS_73 = 73,
+  HOUSE_TEMPLE_EMERALD_ISLE = 74,
+  HOUSE_TEMPLE_HARMONDALE = 75,
+  HOUSE_TRAINING_HALL_EMERALD_ISLE = 89,
+  HOUSE_TRAINING_HALL_HARMONDALE = 90,
+  HOUSE_TRAINING_HALL_91 = 91,
+  HOUSE_TRAINING_HALL_92 = 92,
+  HOUSE_TRAINING_HALL_93 = 93,
+  HOUSE_TRAINING_HALL_94 = 94,
+  HOUSE_TRAINING_HALL_95 = 95,
+
+  HOUSE_TOWNHALL_HARMONDALE = 102,
+  HOUSE_TAVERN_EMERALD_ISLE = 107,
+  HOUSE_BANK_HARMONDALE = 128,
+  HOUSE_FIRE_GUILD_INITIATE_EMERALD_ISLE = 139,
+  HOUSE_AIR_GUILD_INITIATE_EMERALD_ISLE = 143,
+  HOUSE_SPIRIT_GUILD_INITIATE_EMERALD_ISLE = 155,
+  HOUSE_BODY_GUILD_INITIATE_EMERALD_ISLE = 163,
+  HOUSE_BODY_GUILD_ERATHIA = 165,
+  HOUSE_DARK_GUILD_PIT = 170,
+  HOUSE_LORD_AND_JUDGE_EMERALD_ISLE = 186,
+  HOUSE_JAIL = 187,
+  HOUSE_JUDGE_HARMONDALE = 190,
+  HOUSE_224_EMERALD_ISLE = 224,
+  HOUSE_225_EMERALD_ISLE = 225,
+  HOUSE_238_EMERALD_ISLE = 238,
+  HOUSE_466_HARMONDALE = 466,
+  HOUSE_467_HARMONDALE = 467,
+  HOUSE_468_HARMONDALE = 468,
+  HOUSE_472_HARMONDALE = 472,
+  HOUSE_488_HARMONDALE = 488,
+  HOUSE_489_HARMONDALE = 489,
+  HOUSE_600 = 600,//???
+  HOUSE_601 = 601//???
+};
+
+enum HouseSoundID: unsigned __int32
+{
+  HouseSound_Greeting = 1,        // General greeting
+  HouseSound_NotEnoughMoney_TrainingSuccessful = 2,
+  HouseSound_Greeting_2 = 3,      // Polite Greeting when you're guild member
+  HouseSound_Goodbye = 4          // farewells when bought something
+};
+
+void TrainingDialog();
+void JailDialog();
+void  MagicShopDialog();
+void  GuildDialog();
+void  sub_4B6478();
+bool __fastcall IsTravelAvailable(int a1);
+void __cdecl TravelByTransport();
+void TempleDialog();
+void __cdecl TownHallDialog();
+void __cdecl BankDialog();
+void __cdecl TavernDialog();
+void PlayHouseSound(unsigned int uHouseID, HouseSoundID sound); // idb
+void __cdecl WeaponShopDialog();
+void __cdecl AlchemistDialog();
+void __cdecl ArmorShopDialog();
+
+extern int uHouse_ExitPic; // weak
+extern int dword_591080; // weak
+extern int in_current_building_type; // 00F8B198
+extern HOUSE_DIALOGUE_MENU dialog_menu_id; // 00F8B19C
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/UI/UIMainMenu.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -0,0 +1,359 @@
+#ifdef _MSC_VER
+#define _CRT_SECURE_NO_WARNINGS
+#endif
+
+#include <assert.h>
+
+
+#include "..\Mouse.h"
+#include "..\Keyboard.h"
+
+#include "..\GUIWindow.h"
+#include "..\GUIFont.h"
+#include "..\AudioPlayer.h"
+#include "..\Render.h"
+#include "..\LOD.h"
+#include "..\Allocator.h"
+#include "..\PaletteManager.h"
+#include "..\IconFrameTable.h"
+#include "..\texts.h"
+
+#include "..\mm7_data.h"
+
+
+
+//----- (0041B578) --------------------------------------------------------
+void MainMenuUI_LoadFontsAndSomeStuff()
+{
+  pIcons_LOD->SetupPalettes(pRenderer->uTargetRBits,
+                            pRenderer->uTargetGBits,
+                            pRenderer->uTargetBBits);
+  pPaletteManager->SetColorChannelInfo(pRenderer->uTargetRBits,
+                                       pRenderer->uTargetGBits,
+                                       pRenderer->uTargetBBits);
+  pPaletteManager->RecalculateAll();
+
+  for (uint i = 0; i < 480; ++i)
+    pSRZBufferLineOffsets[i] = 640 * i;
+
+  pRenderer->ResetTextureClipRect();
+
+  uTextureID_FONTPAL = pIcons_LOD->LoadTexture("FONTPAL", TEXTURE_16BIT_PALETTE);
+
+  pFontArrus = LoadFont("arrus.fnt", "FONTPAL", nullptr);
+  pFontArrus->field_3 = 0;
+
+  pFontLucida = LoadFont("lucida.fnt", "FONTPAL", nullptr);
+  pFontLucida->field_3 = 0;
+
+  pFontCreate = LoadFont("create.fnt", "FONTPAL", nullptr);
+  pFontCreate->field_3 = 0;
+
+  pFontSmallnum = LoadFont("smallnum.fnt", "FONTPAL", nullptr);
+  pFontComic = LoadFont("comic.fnt", "FONTPAL", nullptr);
+
+  for (uint i = 0; i < 20; ++i)
+    pWindowList[i].eWindowType = WINDOW_null;
+
+  uNumVisibleWindows = -1;
+  memset(pVisibleWindowsIdxs.data(), 0, sizeof(pVisibleWindowsIdxs));
+}
+
+//----- (004415C5) --------------------------------------------------------
+static void LoadPartyBuffIcons()
+{
+  for (uint i = 0; i < 14; ++i)
+  {
+    char filename[200];
+    sprintf(filename, "isn-%02d", i + 1);
+    pTextureIDs_PartyBuffIcons[i] = pIcons_LOD->LoadTexture(filename, TEXTURE_16BIT_PALETTE);
+  }
+
+  uIconIdx_FlySpell = pIconsFrameTable->FindIcon("spell21");
+  uIconIdx_WaterWalk = pIconsFrameTable->FindIcon("spell27");
+}
+
+//----- (0041B690) --------------------------------------------------------
+void MainMenuUI_Create()
+{
+    //unsigned int v0; // eax@1
+    //unsigned int v1; // eax@1
+    //unsigned int v2; // eax@1
+    //unsigned int v3; // eax@1
+    //unsigned int v4; // eax@1
+    //unsigned int v5; // eax@1
+    Texture *v6; // ST78_4@1
+    //const char *v7; // ST5C_4@1
+    unsigned __int8 v8; // al@1
+    //Texture *v9; // ST60_4@1
+    Texture *v10; // ST78_4@1
+    //const char *v11; // ST5C_4@1
+    unsigned __int8 v12; // al@1
+    //Texture *v13; // ST60_4@1
+    unsigned int v14; // eax@1
+    Texture *v15; // ST78_4@1
+    //const char *v16; // ST5C_4@1
+    unsigned __int8 v17; // al@1
+    //Texture *v18; // ST60_4@1
+    unsigned int uTextureID_ib_td4_A; // eax@1
+    Texture *v20; // ST78_4@1
+    unsigned __int8 v22; // al@1
+    //Texture *v23; // ST60_4@1
+    Texture *v24; // eax@1
+    //Texture *v25; // esi@1
+    //Texture *v26; // ST60_4@1
+    //const char *v27; // ST5C_4@1
+    unsigned __int8 v28; // al@1
+    Texture *v29; // eax@1
+    //Texture *v30; // esi@1
+    //Texture *v31; // ST60_4@1
+    //const char *v32; // ST5C_4@1
+    unsigned __int8 v33; // al@1
+
+    pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("wizeyeC"));
+    pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("wizeyeB"));
+    pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("wizeyeA"));
+    pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("torchC"));
+    pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("torchB"));
+    pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("torchA"));
+
+    pTextureIDs_pMapDirs[0] = pIcons_LOD->LoadTexture("MAPDIR8", TEXTURE_16BIT_PALETTE);
+    pTextureIDs_pMapDirs[1] = pIcons_LOD->LoadTexture("MAPDIR1", TEXTURE_16BIT_PALETTE);
+    pTextureIDs_pMapDirs[2] = pIcons_LOD->LoadTexture("MAPDIR2", TEXTURE_16BIT_PALETTE);
+    pTextureIDs_pMapDirs[3] = pIcons_LOD->LoadTexture("MAPDIR3", TEXTURE_16BIT_PALETTE);
+    pTextureIDs_pMapDirs[4] = pIcons_LOD->LoadTexture("MAPDIR4", TEXTURE_16BIT_PALETTE);
+    pTextureIDs_pMapDirs[5] = pIcons_LOD->LoadTexture("MAPDIR5", TEXTURE_16BIT_PALETTE);
+    pTextureIDs_pMapDirs[6] = pIcons_LOD->LoadTexture("MAPDIR6", TEXTURE_16BIT_PALETTE);
+    pTextureIDs_pMapDirs[7] = pIcons_LOD->LoadTexture("MAPDIR7", TEXTURE_16BIT_PALETTE);
+
+    uTextureID_BarBlue = pIcons_LOD->LoadTexture("ib-statB", TEXTURE_16BIT_PALETTE);
+    uTextureID_BarGreen = pIcons_LOD->LoadTexture("ib-statG", TEXTURE_16BIT_PALETTE);
+    uTextureID_BarYellow = pIcons_LOD->LoadTexture("ib-statY", TEXTURE_16BIT_PALETTE);
+    uTextureID_BarRed = pIcons_LOD->LoadTexture("ib-statR", TEXTURE_16BIT_PALETTE);
+    uTextureID_mhp_bd = pIcons_LOD->LoadTexture("mhp_bg", TEXTURE_16BIT_PALETTE);
+    uTextureID_mhp_capl = pIcons_LOD->LoadTexture("mhp_capl", TEXTURE_16BIT_PALETTE);
+    uTextureID_mhp_capr = pIcons_LOD->LoadTexture("mhp_capr", TEXTURE_16BIT_PALETTE);
+    uTextureID_mhp_grn = pIcons_LOD->LoadTexture("mhp_grn", TEXTURE_16BIT_PALETTE);
+    uTextureID_mhp_red = pIcons_LOD->LoadTexture("mhp_red", TEXTURE_16BIT_PALETTE);
+    uTextureID_mhp_yel = pIcons_LOD->LoadTexture("mhp_yel", TEXTURE_16BIT_PALETTE);
+    uTextureID_Leather = pIcons_LOD->LoadTexture("LEATHER", TEXTURE_16BIT_PALETTE);
+    pTexture_Leather = pIcons_LOD->LoadTexturePtr("ibground", TEXTURE_16BIT_PALETTE);
+    uTextureID_x_x_u = pIcons_LOD->LoadTexture("x_x_u", TEXTURE_16BIT_PALETTE);
+    uTextureID_BUTTDESC2 = pIcons_LOD->LoadTexture("BUTTESC2", TEXTURE_16BIT_PALETTE);
+    uTextureID_x_ok_u = pIcons_LOD->LoadTexture("x_ok_u", TEXTURE_16BIT_PALETTE);
+    uTextureID_BUTTYES2 = pIcons_LOD->LoadTexture("BUTTYES2", TEXTURE_16BIT_PALETTE);
+    uTextureID_BUTTMAKE = pIcons_LOD->LoadTexture("BUTTMAKE", TEXTURE_16BIT_PALETTE);
+    uTextureID_BUTTMAKE2 = pIcons_LOD->LoadTexture("BUTTMAKE2", TEXTURE_16BIT_PALETTE);
+
+    pPrimaryWindow = GUIWindow::Create(0, 0, 640, 480, WINDOW_MainMenu, 0, 0);
+    pPrimaryWindow->CreateButton(7u, 8u, 0x1CCu, 0x157u, 1, 0, UIMSG_MouseLeftClickInGame, 0, 0, "", 0);
+    pPrimaryWindow->CreateButton(0x3Du, 0x1A8u, 0x1Fu, 0x28u, 2, 94, UIMSG_SelectCharacter, 1, '1', "", 0);
+    pPrimaryWindow->CreateButton(0xB1u, 0x1A8u, 0x1Fu, 0x28u, 2, 94, UIMSG_SelectCharacter, 2, '2', "", 0);
+    pPrimaryWindow->CreateButton(0x124u, 0x1A8u, 0x1Fu, 0x28u, 2, 94, UIMSG_SelectCharacter, 3, '3', "", 0);
+    pPrimaryWindow->CreateButton(0x197u, 0x1A8u, 0x1Fu, 0x28u, 2, 94, UIMSG_SelectCharacter, 4, '4', "", 0);
+    pPrimaryWindow->CreateButton(0x18u, 0x194u, 5u, 0x31u, 1, 93, UIMSG_0, 1, 0, "", 0);
+    pPrimaryWindow->CreateButton(0x8Bu, 0x194u, 5u, 0x31u, 1, 93, UIMSG_0, 2, 0, "", 0);
+    pPrimaryWindow->CreateButton(0xFFu, 0x194u, 5u, 0x31u, 1, 93, UIMSG_0, 3, 0, "", 0);
+    pPrimaryWindow->CreateButton(0x172u, 0x194u, 5u, 0x31u, 1, 93, UIMSG_0, 4, 0, "", 0);
+    pPrimaryWindow->CreateButton(0x61u, 0x194u, 5u, 0x31u, 1, 93, UIMSG_0, 1, 0, "", 0);
+    pPrimaryWindow->CreateButton(0xD4u, 0x194u, 5u, 0x31u, 1, 93, UIMSG_0, 2, 0, "", 0);
+    pPrimaryWindow->CreateButton(0x148u, 0x194u, 5u, 0x31u, 1, 93, UIMSG_0, 3, 0, "", 0);
+    pPrimaryWindow->CreateButton(0x1BBu, 0x194u, 5u, 0x31u, 1, 93, UIMSG_0, 4, 0, "", 0);
+
+    uTextureID_ib_td1_A = pIcons_LOD->LoadTexture("ib-td1-A", TEXTURE_16BIT_PALETTE);
+    v6 = pIcons_LOD->GetTexture(uTextureID_ib_td1_A);
+    v8 = pKeyActionMap->GetActionVKey(INPUT_Quest);
+    pBtn_Quests = pPrimaryWindow->CreateButton(0x1EBu, 0x161u, v6->uTextureWidth, v6->uTextureHeight, 1, 0, UIMSG_OpenQuestBook, 0, v8, pGlobalTXT_LocalizationStrings[174], v6, 0); //Quests
+
+    uTextureID_ib_td2_A = pIcons_LOD->LoadTexture("ib-td2-A", TEXTURE_16BIT_PALETTE);
+    v10 = pIcons_LOD->GetTexture(uTextureID_ib_td2_A);
+    v12 = pKeyActionMap->GetActionVKey(INPUT_Autonotes);
+    pBtn_Autonotes = pPrimaryWindow->CreateButton(0x20Fu, 0x161u, v10->uTextureWidth, v10->uTextureHeight, 1, 0, UIMSG_OpenAutonotes, 0, v12, pGlobalTXT_LocalizationStrings[154], v10, 0);//Autonotes
+
+    v14 = pIcons_LOD->LoadTexture("ib-td3-A", TEXTURE_16BIT_PALETTE);
+    v15 = pIcons_LOD->GetTexture(v14);
+    v17 = pKeyActionMap->GetActionVKey(INPUT_Mapbook);
+    pBtn_Maps = pPrimaryWindow->CreateButton(0x222u, 0x161u, v15->uTextureWidth, v15->uTextureHeight, 1, 0, UIMSG_OpenMapBook, 0, v17, pGlobalTXT_LocalizationStrings[139], v15, 0); //Maps
+
+    uTextureID_ib_td4_A = pIcons_LOD->LoadTexture("ib-td4-A", TEXTURE_16BIT_PALETTE);
+    v20 = pIcons_LOD->GetTexture(uTextureID_ib_td4_A);
+    v22 = pKeyActionMap->GetActionVKey(INPUT_TimeCal);
+    pBtn_Calendar = pPrimaryWindow->CreateButton(0x23Au, 0x161u, v20->uTextureWidth, v20->uTextureHeight, 1, 0, UIMSG_OpenCalendar, 0, v22,
+        pGlobalTXT_LocalizationStrings[78],//Calendar
+        v20, 0);
+
+    uTextureID_ib_td5_A = pIcons_LOD->LoadTexture("ib-td5-A", TEXTURE_16BIT_PALETTE);
+    pBtn_History = pPrimaryWindow->CreateButton(0x258u, 0x169u,
+        pIcons_LOD->GetTexture(uTextureID_ib_td5_A)->uTextureWidth,
+        pIcons_LOD->GetTexture(uTextureID_ib_td5_A)->uTextureHeight,
+        1, 0, UIMSG_OpenHistoryBook, 0, 0x48u, pGlobalTXT_LocalizationStrings[602],//History
+        pIcons_LOD->GetTexture(uTextureID_ib_td5_A), 0);
+
+    bFlashAutonotesBook = 0;
+    bFlashQuestBook = 0;
+    bFlashHistoryBook = 0;
+
+    v24 = &pIcons_LOD->pTextures[uTextureID_Btn_ZoomIn];
+    v28 = pKeyActionMap->GetActionVKey(INPUT_ZoomIn);
+    pBtn_ZoomIn = pPrimaryWindow->CreateButton(574, 136, v24->uTextureWidth, v24->uTextureHeight, 2, 0, UIMSG_ClickZoomInBtn, 0, v28, pGlobalTXT_LocalizationStrings[252], // Zoom In
+        v24, 0);
+    v29 = &pIcons_LOD->pTextures[uTextureID_Btn_ZoomOut];
+    v33 = pKeyActionMap->GetActionVKey(INPUT_ZoomOut);
+    pBtn_ZoomOut = pPrimaryWindow->CreateButton(519, 136, v29->uTextureWidth, v29->uTextureHeight, 2, 0, UIMSG_ClickZoomOutBtn, 0, v33, pGlobalTXT_LocalizationStrings[251], // Zoom Out
+        v29, 0);
+    pPrimaryWindow->CreateButton(0x1E1u, 0, 0x99u, 0x43u, 1, 92, UIMSG_0, 0, 0, "", 0);
+    pPrimaryWindow->CreateButton(0x1EBu, 0x95u, 0x40u, 0x4Au, 1, 0, UIMSG_StartHireling1Dialogue, 0, '5', "", 0);
+    pPrimaryWindow->CreateButton(0x231u, 0x95u, 0x40u, 0x4Au, 1, 0, UIMSG_StartHireling2Dialogue, 0, '6', "", 0);
+    pPrimaryWindow->CreateButton(0x1DCu, 0x142u, 0x4Du, 0x11u, 1, 100, UIMSG_0, 0, 0, "", 0);
+    pPrimaryWindow->CreateButton(0x22Bu, 0x142u, 0x4Du, 0x11u, 1, 101, UIMSG_0, 0, 0, "", 0);
+    pBtn_CastSpell = pPrimaryWindow->CreateButton(0x1DCu, 0x1C2u,
+        pIcons_LOD->GetTexture(uTextureID_Btn_CastSpell)->uTextureWidth,
+        pIcons_LOD->GetTexture(uTextureID_Btn_CastSpell)->uTextureHeight,
+        1, 0, UIMSG_SpellBookWindow, 0, 0x43u, pGlobalTXT_LocalizationStrings[38], pIcons_LOD->GetTexture(uTextureID_Btn_CastSpell),
+        0);
+    pBtn_Rest = pPrimaryWindow->CreateButton(0x206u, 0x1C2u,
+        pIcons_LOD->GetTexture(uTextureID_Btn_Rest)->uTextureWidth,
+        pIcons_LOD->GetTexture(uTextureID_Btn_Rest)->uTextureHeight,
+        1, 0, UIMSG_RestWindow, 0, 0x52u, pGlobalTXT_LocalizationStrings[182], pIcons_LOD->GetTexture(uTextureID_Btn_Rest), 0);
+    pBtn_QuickReference = pPrimaryWindow->CreateButton(0x230u, 0x1C2u,
+        pIcons_LOD->GetTexture(uTextureID_Btn_QuickReference)->uTextureWidth,
+        pIcons_LOD->GetTexture(uTextureID_Btn_QuickReference)->uTextureHeight,
+        1, 0, UIMSG_QuickReference, 0, 0x5Au, pGlobalTXT_LocalizationStrings[173], pIcons_LOD->GetTexture(uTextureID_Btn_QuickReference), 0);
+    pBtn_GameSettings = pPrimaryWindow->CreateButton(0x25Au, 0x1C2u,
+        pIcons_LOD->GetTexture(uTextureID_Btn_GameSettings)->uTextureWidth,
+        pIcons_LOD->GetTexture(uTextureID_Btn_GameSettings)->uTextureHeight,
+        1, 0, UIMSG_GameMenuButton, 0, 0, pGlobalTXT_LocalizationStrings[93], pIcons_LOD->GetTexture(uTextureID_Btn_GameSettings), 0);
+    pBtn_NPCLeft = pPrimaryWindow->CreateButton(0x1D5u, 0xB2u,
+        pIcons_LOD->GetTexture(uTextureID_Btn_NPCLeft)->uTextureWidth,
+        pIcons_LOD->GetTexture(uTextureID_Btn_NPCLeft)->uTextureHeight,
+        1, 0, UIMSG_ScrollNPCPanel, 0, 0, "", pIcons_LOD->GetTexture(uTextureID_Btn_NPCLeft), 0);
+    pBtn_NPCRight = pPrimaryWindow->CreateButton(0x272u, 0xB2u,
+        pIcons_LOD->GetTexture(uTextureID_Btn_NPCRight)->uTextureWidth,
+        pIcons_LOD->GetTexture(uTextureID_Btn_NPCRight)->uTextureHeight,
+        1, 0, UIMSG_ScrollNPCPanel, 1u, 0, "", pIcons_LOD->GetTexture(uTextureID_Btn_NPCRight), 0);
+    LoadPartyBuffIcons();
+}
+
+//----- (004979D2) --------------------------------------------------------
+MENU_STATE MainMenuUI_Credits_Loop()
+{
+        char *v0; // eax@5
+        char *v1; // edi@5
+        FILE *pFile; // eax@5
+        unsigned int pSize; // esi@7
+        GUIFont *pFont; // edx@9
+        GUIFont *pFont2; // ecx@9
+        __int16 pHeight; // ax@9
+        void *v7; // eax@9
+        unsigned int pNumPixels; // ST2C_4@9
+        unsigned int teal; // eax@9
+        unsigned int v10; // ST2C_4@19
+        MSG Msg; // [sp+84h] [bp-B8h]@10
+        int v17; // [sp+A0h] [bp-9Ch]@9
+        GUIWindow a2;
+        int pColor2; // [sp+F8h] [bp-44h]@9
+        int pColor1; // [sp+FCh] [bp-40h]@9
+        int a5; // [sp+128h] [bp-14h]@1
+        char *pString; // [sp+12Ch] [bp-10h]@9
+        char *ptr; // [sp+130h] [bp-Ch]@5
+        GUIFont *pFontQuick; // [sp+134h] [bp-8h]@1
+        GUIFont *pFontCChar; // [sp+138h] [bp-4h]@1
+        RGBTexture pTexture; // [sp+54h] [bp-E8h]@1
+        RGBTexture pTexture2; // [sp+100h] [bp-3Ch]@1
+        Texture pTexture3; // [sp+Ch] [bp-130h]@5
+
+        a5 = 0;
+        pFontQuick = LoadFont("quick.fnt", "FONTPAL", NULL);
+        pFontCChar = LoadFont("cchar.fnt", "FONTPAL", NULL);
+        if ( pMessageQueue_50CBD0->uNumMessages )
+            pMessageQueue_50CBD0->uNumMessages = pMessageQueue_50CBD0->pMessages[0].field_8 != 0;
+        ++pIcons_LOD->uTexturePacksCount;
+        if ( !pIcons_LOD->uNumPrevLoadedFiles )
+            pIcons_LOD->uNumPrevLoadedFiles = pIcons_LOD->uNumLoadedFiles;
+        dword_A74C88 = 0;
+        pAudioPlayer->PlayMusicTrack(MUSIC_Credits);
+        pTexture.Load("mm6title.pcx", 0);
+        v0 = (char *)pEvents_LOD->LoadRaw("credits.txt", 0);
+        v1 = v0;
+        ptr = v0;
+        pFile = pEvents_LOD->FindContainer("credits.txt", 0);
+        if ( !pFile )
+            Abortf(pGlobalTXT_LocalizationStrings[63]); // "Might and Magic VII is having trouble loading files. 
+        // Please re-install to fix this problem. Note: Re-installing will not destroy your save games."
+        fread(&pTexture3, 1, 0x30, pFile);
+        pSize = pTexture3.uDecompressedSize;
+        if ( !pTexture3.uDecompressedSize )
+            pSize = pTexture3.uTextureSize;
+        memset(&pTexture3, 0, 0x48);
+        pFont = pFontCChar;
+        pFont2 = pFontQuick;
+        v1[pSize] = 0;
+        
+        a2.uFrameWidth = 250;
+        a2.uFrameHeight = 440;
+        a2.uFrameX = 389;
+        a2.uFrameY = 19;
+
+        pTexture2.uWidth = 250;
+        pHeight = pFont2->GetStringHeight2(pFont, v1, &a2, 0, 1);
+        pTexture2.uHeight = pHeight + 2 * a2.uFrameHeight;
+        pTexture2.uNumPixels = (signed __int16)pTexture2.uWidth * (signed __int16)pTexture2.uHeight;
+        v7 = pAllocator->AllocNamedChunk(pTexture2.pPixels, 2 * pTexture2.uNumPixels, "scrollermap");
+        pNumPixels = pTexture2.uNumPixels;
+        pTexture2.pPixels = (unsigned __int16 *)v7;
+        teal = TargetColor(0, 0xFFu, 0xFFu);
+        fill_pixels_fast(teal, pTexture2.pPixels, pNumPixels);
+        pTexture2.field_20 = 0;
+        pTexture2.field_22 = 0;
+        pColor1 = TargetColor(0x70u, 0x8Fu, 0xFEu);
+        pColor2 = TargetColor(0xECu, 0xE6u, 0x9Cu);
+        pString = (char *)operator new(2 * pSize);
+        strncpy(pString, ptr, pSize);
+        pString[pSize]=0;
+        pFontQuick->_44D2FD_prolly_draw_credits_entry(pFontCChar, 0, a2.uFrameHeight, (signed __int16)pTexture2.uWidth, (signed __int16)pTexture2.uHeight, pColor1, 
+            pColor2, pString, pTexture2.pPixels, (signed __int16)pTexture2.uWidth);
+        free(pString);
+        pWindow_MainMenu = GUIWindow::Create(0, 0, 640, 480, WINDOW_MainMenu, 0, ptr);
+        pWindow_MainMenu->CreateButton(0, 0, 0, 0, 1, 0, UIMSG_Escape, 0, 0x1Bu, "", 0);
+        pCurrentScreen = SCREEN_CREATORS;
+        SetCurrentMenuID(MENU_CREDITSPROC);
+        do
+            {
+            while ( PeekMessageA(&Msg, 0, 0, 0, 1) )
+                {
+                if ( Msg.message == 18 )
+                    Game_DeinitializeAndTerminate(0);
+                TranslateMessage(&Msg);
+                DispatchMessageA(&Msg);
+                }
+            if ( BYTE1(dword_6BE364_game_settings_1) & 1 )
+                {
+                WaitMessage();
+                }
+            else
+                {
+                pRenderer->BeginScene();
+                pRenderer->DrawTextureRGB(0, 0, &pTexture);
+                pRenderer->SetTextureClipRect(a2.uFrameX, a2.uFrameY, a2.uFrameX + a2.uFrameWidth, a2.uFrameY + a2.uFrameHeight);
+                pRenderer->_4A5D33(a2.uFrameX, a2.uFrameY, 0, a5, &pTexture2);
+                pRenderer->ResetTextureClipRect();
+                pRenderer->EndScene();
+                ++a5;
+                if ( a5 >= (signed __int16)pTexture2.uHeight )
+                    SetCurrentMenuID(MENU_MAIN);
+                pRenderer->Present();
+                pCurrentScreen = SCREEN_GAME;//Ritor1: temporarily, must be corrected GUI_MainMenuMessageProc()
+                GUI_MainMenuMessageProc();
+                }
+            }
+            while ( GetCurrentMenuID() == MENU_CREDITSPROC );
+            pAudioPlayer->_4AA258(1);
+            pAllocator->FreeChunk(ptr);
+            pAllocator->FreeChunk(pFontQuick);
+            pAllocator->FreeChunk(pFontCChar);
+            pWindow_MainMenu->Release();
+            pIcons_LOD->_4114F2();
+            pTexture.Release();
+            pTexture2.Release();
+            return MENU_MAIN;     // return MENU_Main
+        }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/UI/UIOptions.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -0,0 +1,269 @@
+#include <assert.h>
+
+#include "..\MM7.h"
+
+#include "..\Keyboard.h"
+#include "..\IndoorCameraD3D.h"
+#include "..\CShow.h"
+#include "..\GammaControl.h"
+#include "..\Render.h"
+
+#include "..\Game.h"
+#include "..\GUIWindow.h"
+#include "..\GUIFont.h"
+#include "..\AudioPlayer.h"
+#include "..\LOD.h"
+#include "..\texts.h"
+
+#include "..\mm7_data.h"
+
+
+
+
+OptionsMenuSkin options_menu_skin; // 507C60
+
+
+std::array<bool, 28> GameMenuUI_InvaligKeyBindingsFlags; // 506E6C
+//----- (00414D24) --------------------------------------------------------
+static unsigned int GameMenuUI_GetKeyBindingColor(int key_index)
+{
+  if (uGameMenuUI_CurentlySelectedKeyIdx == key_index)
+  {
+    if (GetTickCount() % 1000 < 500)
+      return ui_gamemenu_keys_key_selection_blink_color_1;
+    else
+      return ui_gamemenu_keys_key_selection_blink_color_2;
+  }
+  else if (GameMenuUI_InvaligKeyBindingsFlags[key_index])
+  {
+    int intensity;
+
+    int time = GetTickCount() % 800;
+    if (time < 400)
+      intensity = - 70 + 70 * time / 400;
+    else
+      intensity = + 70 - 70 * time / 800;
+
+    return TargetColor(185 + intensity, 40 + intensity / 4, 40 + intensity / 4);
+  }
+
+  return ui_gamemenu_keys_key_default_color;
+}
+
+//----- (004142D3) --------------------------------------------------------
+void GameMenuUI_DrawKeyBindings()
+{
+    signed int v4; // ecx@7
+    signed int v5; // eax@8
+    
+    if ( pGUIWindow_CurrentMenu->receives_keyboard_input_2 == WINDOW_INPUT_CONFIRMED)
+        {
+        pPrevVirtualCidesMapping[uGameMenuUI_CurentlySelectedKeyIdx] = pKeyActionMap->pPressedKeysBuffer[0];
+        memset(GameMenuUI_InvaligKeyBindingsFlags.data(), 0, sizeof(GameMenuUI_InvaligKeyBindingsFlags));
+        v4 = 0;
+        do
+            {
+            v5 = 0;
+            do
+                {
+                if ( v4 != v5 && pPrevVirtualCidesMapping[v4] == pPrevVirtualCidesMapping[v5] )
+                    {
+                    GameMenuUI_InvaligKeyBindingsFlags[v4] = true;
+                    GameMenuUI_InvaligKeyBindingsFlags[v5] = true;
+                    }
+                ++v5;
+                }
+                while ( v5 < 28 );
+                ++v4;
+            }
+            while ( v4 < 28 );
+            uGameMenuUI_CurentlySelectedKeyIdx = -1;
+            pGUIWindow_CurrentMenu->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
+        }
+    pRenderer->DrawTextureIndexed(8, 8, pIcons_LOD->GetTexture(uTextureID_Optkb[0]));
+    if ( KeyboardPageNum == 1 )
+    {
+        pRenderer->DrawTextureIndexed(0x13, 0x12E, pIcons_LOD->GetTexture(uTextureID_Optkb[3]));
+
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 23, 142, ui_gamemenu_keys_action_name_color, "Ш", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 142, GameMenuUI_GetKeyBindingColor(0), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[0]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 23, 163, ui_gamemenu_keys_action_name_color, "", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 163, GameMenuUI_GetKeyBindingColor(1), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[1]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 23, 184, ui_gamemenu_keys_action_name_color, "", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 184, GameMenuUI_GetKeyBindingColor(2), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[2]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 23, 205, ui_gamemenu_keys_action_name_color, "", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 205, GameMenuUI_GetKeyBindingColor(3), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[3]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 23, 226, ui_gamemenu_keys_action_name_color, "", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 226, GameMenuUI_GetKeyBindingColor(4), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[4]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 23, 247, ui_gamemenu_keys_action_name_color, "", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 247, GameMenuUI_GetKeyBindingColor(5), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[5]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 23, 268, ui_gamemenu_keys_action_name_color, ".", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 268, GameMenuUI_GetKeyBindingColor(6), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[6]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 142, ui_gamemenu_keys_action_name_color, ". .", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 350, 142, GameMenuUI_GetKeyBindingColor(7), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[7]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 163, ui_gamemenu_keys_action_name_color, "", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 350, 163, GameMenuUI_GetKeyBindingColor(8), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[8]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 184, ui_gamemenu_keys_action_name_color, ".", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 350, 184, GameMenuUI_GetKeyBindingColor(9), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[9]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 205, ui_gamemenu_keys_action_name_color, ".", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 350, 205, GameMenuUI_GetKeyBindingColor(10), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[10]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 226, ui_gamemenu_keys_action_name_color, "", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 350, 226, GameMenuUI_GetKeyBindingColor(11), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[11]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 247, ui_gamemenu_keys_action_name_color, ". ", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 350, 247, GameMenuUI_GetKeyBindingColor(12), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[12]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 268, ui_gamemenu_keys_action_name_color, "", 0, 0, 0);
+     pGUIWindow_CurrentMenu->DrawText(pFontLucida, 350, 268, GameMenuUI_GetKeyBindingColor(13), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[13]), 0, 0, 0);
+    }
+    else
+    {
+        pRenderer->DrawTextureIndexed(0x7F, 0x12E, pIcons_LOD->GetTexture(uTextureID_Optkb[4]));
+
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 23, 142, ui_gamemenu_keys_action_name_color, ". ", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 142, GameMenuUI_GetKeyBindingColor(14), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[14]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 23, 163, ui_gamemenu_keys_action_name_color, "", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 163, GameMenuUI_GetKeyBindingColor(15), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[15]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 23, 184, ui_gamemenu_keys_action_name_color, ". ", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 184, GameMenuUI_GetKeyBindingColor(16), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[16]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 23, 205, ui_gamemenu_keys_action_name_color, "", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 205, GameMenuUI_GetKeyBindingColor(17), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[17]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 23, 226, ui_gamemenu_keys_action_name_color, "", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 226, GameMenuUI_GetKeyBindingColor(18), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[18]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 23, 247, ui_gamemenu_keys_action_name_color, "", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 247, GameMenuUI_GetKeyBindingColor(19), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[19]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 23, 268, ui_gamemenu_keys_action_name_color, ". ", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 127, 268, GameMenuUI_GetKeyBindingColor(20), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[20]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 142, ui_gamemenu_keys_action_name_color, ". ", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 350, 142, GameMenuUI_GetKeyBindingColor(21), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[21]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 163, ui_gamemenu_keys_action_name_color, ". Ш", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 350, 163, GameMenuUI_GetKeyBindingColor(22), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[22]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 184, ui_gamemenu_keys_action_name_color, "", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 350, 184, GameMenuUI_GetKeyBindingColor(23), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[23]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 205, ui_gamemenu_keys_action_name_color, "", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 350, 205, GameMenuUI_GetKeyBindingColor(24), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[24]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 226, ui_gamemenu_keys_action_name_color, ". ", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 350, 226, GameMenuUI_GetKeyBindingColor(25), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[25]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 247, ui_gamemenu_keys_action_name_color, ". ", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 350, 247, GameMenuUI_GetKeyBindingColor(26), pKeyActionMap->GetVKeyDisplayName(pPrevVirtualCidesMapping[26]), 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 247, 268, ui_gamemenu_keys_action_name_color, "", 0, 0, 0);
+        pGUIWindow_CurrentMenu->DrawText(pFontLucida, 350, 268, GameMenuUI_GetKeyBindingColor(27), pKeyActionMap->GetVKeyDisplayName(pWindowList_at_506F50_minus1_indexing[0]), 0, 0, 0);
+    }
+}
+
+
+
+
+//----- (00414D9A) --------------------------------------------------------
+void GameMenuUI_DrawVideoOptions()
+{
+    const char *v0; // ST0C_4@3
+    //unsigned __int16 v1; // ax@3
+    //int v2; // eax@10
+    GUIWindow v3; // [sp+8h] [bp-54h]@3
+
+    pRenderer->DrawTextureIndexed(8, 8, pIcons_LOD->GetTexture(uTextureID_507C10));
+    if ( !pRenderer->bWindowMode && GammaController::IsGammaSupported() )
+        {
+        pRenderer->DrawTextureIndexed(
+            17 * uGammaPos + 42,
+            162,
+            pIcons_LOD->GetTexture(pTextureIDs_GammaPositions[uGammaPos]));
+        pRenderer->DrawTextureRGB(0x112u, 0xA9u, &stru_506E40);
+        v3.uFrameX = 22;
+        v0 = pGlobalTXT_LocalizationStrings[226]; // "Gamma controls the relative ""brightness"" of the game.  May vary depending on your monitor."
+        v3.uFrameY = 190;
+        v3.uFrameWidth = 211;
+        v3.uFrameHeight = 79;
+        v3.uFrameZ = 232;
+        v3.uFrameW = 268;
+        //v1 = TargetColor(0xFFu, 0xFFu, 0x9Bu);
+        v3.DrawTitleText(pFontSmallnum, 0, 0, ui_gamemenu_video_gamma_title_color, v0, 3u);
+        }
+
+    if (!pRenderer->pRenderD3D)
+    {
+      pRenderer->DrawTextureIndexed(20, 281, pIcons_LOD->GetTexture(uTextureID_507C50));
+      pRenderer->DrawTextureIndexed(20, 303, pIcons_LOD->GetTexture(uTextureID_507C54));
+      pRenderer->DrawTextureIndexed(20, 325, pIcons_LOD->GetTexture(uTextureID_507C58));
+    }
+    else
+    {
+      if (pGame->uFlags2 & GAME_FLAGS_2_DRAW_BLOODSPLATS)
+        pRenderer->DrawTextureIndexed(20, 281, pIcons_LOD->GetTexture(uTextureID_507C14));
+      if (pRenderer->bUseColoredLights)
+        pRenderer->DrawTextureIndexed(20, 303, pIcons_LOD->GetTexture(uTextureID_507C18));
+      if (pRenderer->bTinting)
+        pRenderer->DrawTextureIndexed(20, 325, pIcons_LOD->GetTexture(uTextureID_507C1C));
+    }
+}
+
+
+
+//----- (00414F82) --------------------------------------------------------
+void GameMenuUI_Options_Draw()
+{
+  pRenderer->DrawTextureIndexed(8,   8, pIcons_LOD->GetTexture(uTextureID_Options));
+  pRenderer->DrawTextureIndexed(8, 132, pIcons_LOD->GetTexture(options_menu_skin.uTextureID_Background));
+
+  switch (uTurnSpeed)
+  {
+    case 64:   pRenderer->DrawTextureIndexed(BtnTurnCoord[1], 270, pIcons_LOD->GetTexture(options_menu_skin.uTextureID_TurnSpeed[1])); break;
+    case 128:  pRenderer->DrawTextureIndexed(BtnTurnCoord[2], 270, pIcons_LOD->GetTexture(options_menu_skin.uTextureID_TurnSpeed[2])); break;
+    default:   pRenderer->DrawTextureIndexed(BtnTurnCoord[0], 270, pIcons_LOD->GetTexture(options_menu_skin.uTextureID_TurnSpeed[0])); break;
+  }
+
+  if (bWalkSound)  pRenderer->DrawTextureIndexed( 20, 303, pIcons_LOD->GetTexture(options_menu_skin.uTextureID_WalkSound));
+  if (bShowDamage) pRenderer->DrawTextureIndexed(128, 303, pIcons_LOD->GetTexture(options_menu_skin.uTextureID_ShowDamage));
+  if (bFlipOnExit) pRenderer->DrawTextureIndexed(128, 325, pIcons_LOD->GetTexture(options_menu_skin.uTextureID_FlipOnExit));
+  if (bAlwaysRun)  pRenderer->DrawTextureIndexed( 20, 325, pIcons_LOD->GetTexture(options_menu_skin.uTextureID_AlwaysRun));
+
+  pRenderer->DrawTextureIndexed(265 + 17 * uSoundVolumeMultiplier,  162, pIcons_LOD->GetTexture(options_menu_skin.uTextureID_SoundLevels[uSoundVolumeMultiplier]));
+  pRenderer->DrawTextureIndexed(265 + 17 * uMusicVolimeMultiplier,  216, pIcons_LOD->GetTexture(options_menu_skin.uTextureID_SoundLevels[uMusicVolimeMultiplier]));
+  pRenderer->DrawTextureIndexed(265 + 17 * uVoicesVolumeMultiplier, 270, pIcons_LOD->GetTexture(options_menu_skin.uTextureID_SoundLevels[uVoicesVolumeMultiplier]));
+}
+
+
+
+
+
+
+
+
+
+
+OptionsMenuSkin::OptionsMenuSkin():
+  uTextureID_Background(0),
+  uTextureID_ArrowLeft(0),
+  uTextureID_ArrowRight(0),
+  uTextureID_unused_0(0), uTextureID_unused_1(0), uTextureID_unused_2(0),
+  uTextureID_FlipOnExit(0),
+  uTextureID_AlwaysRun(0),
+  uTextureID_WalkSound(0),
+  uTextureID_ShowDamage(0)
+{
+    for (uint i = 0; i < 3; ++i)  uTextureID_TurnSpeed[i] = 0;
+    for (uint i = 0; i < 10; ++i) uTextureID_SoundLevels[i] = 0;
+} 
+
+void OptionsMenuSkin::Relaease()
+{
+  #define RELEASE(id) \
+  {\
+    if (id)\
+      pIcons_LOD->GetTexture(id)->Release();\
+    id = 0;\
+  }
+
+  RELEASE(uTextureID_Background);
+  for (uint i = 0; i < 3; ++i)
+    RELEASE(uTextureID_TurnSpeed[i]);
+  RELEASE(uTextureID_ArrowLeft);
+  RELEASE(uTextureID_ArrowRight);
+  RELEASE(uTextureID_FlipOnExit);
+  for (uint i = 0; i < 10; ++i)
+    RELEASE(uTextureID_SoundLevels[i]);
+  RELEASE(uTextureID_AlwaysRun);
+  RELEASE(uTextureID_WalkSound);
+  RELEASE(uTextureID_ShowDamage);
+
+  #undef RELEASE
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/UI/UIPartyCreation.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -0,0 +1,877 @@
+#ifdef _MSC_VER
+#define _CRT_SECURE_NO_WARNINGS
+#endif
+
+#include <assert.h>
+
+
+#include "..\Mouse.h"
+#include "..\Keyboard.h"
+
+#include "..\Game.h"
+#include "..\GUIWindow.h"
+#include "..\GUIFont.h"
+#include "..\Party.h"
+#include "..\AudioPlayer.h"
+#include "..\Render.h"
+#include "..\LOD.h"
+#include "..\Allocator.h"
+#include "..\Time.h"
+#include "..\IconFrameTable.h"
+#include "..\texts.h"
+
+#include "..\mm7_data.h"
+
+
+
+//----- (004908DE) --------------------------------------------------------
+signed int __cdecl PlayerCreation_Chose4Skills()
+    {
+    Player *v0; // esi@1
+    signed int v1; // edx@2
+    unsigned short *v2; // eax@2
+    signed int v3; // ecx@2
+
+    v0 = pParty->pPlayers;//[0].pActiveSkills;
+    while ( 1 )
+        {
+        v1 = 0;
+        v2 = v0->pActiveSkills;
+        v3 = 37;
+        do
+            {
+            if ( *v2 )
+                ++v1;
+            ++v2;
+            --v3;
+            }
+            while ( v3 );
+            if ( v1 < 4 )
+                break;
+            ++v0;
+            if ( v0 > &pParty->pPlayers[3] )
+                return 1;
+        }
+    return 0;
+    }
+
+
+
+
+//----- (00491CB5) --------------------------------------------------------
+void __cdecl LoadPlayerPortraintsAndVoices()
+    {
+    //Texture **v0; // ebx@1
+    //int v1; // eax@2
+    //int v2; // edi@3
+    char *v3; // esi@5
+    char *v4; // [sp+10h] [bp-4h]@1
+
+    pIcons_LOD->pFacesLock = pIcons_LOD->uNumLoadedFiles;
+
+    for (uint i = 0; i < 4; ++i)
+        for (uint j = 0; j < 56; ++j)
+            {
+            sprintf(pTmpBuf.data(), "%s%02d", pPlayerPortraitsNames[pParty->pPlayers[i].uCurrentFace], j + 1);
+            pTextures_PlayerFaces[i][j] = pIcons_LOD->LoadTexturePtr(pTmpBuf.data(), TEXTURE_16BIT_PALETTE);
+            }
+
+        pTexture_PlayerFaceEradicated = pIcons_LOD->LoadTexturePtr("ERADCATE", TEXTURE_16BIT_PALETTE);
+        pTexture_PlayerFaceDead = pIcons_LOD->LoadTexturePtr("DEAD", TEXTURE_16BIT_PALETTE);
+        pTexture_PlayerFaceMask = pIcons_LOD->LoadTexturePtr("FACEMASK", TEXTURE_16BIT_PALETTE);
+
+        if (SoundSetAction[24][0])
+            for (uint i = 0; i < 4; ++i)
+                {
+                pSoundList->LoadSound(2 * (SoundSetAction[24][0] + 50 * pParty->pPlayers[i].uVoiceID) + 4998, 0);
+                pSoundList->LoadSound(2 * (SoundSetAction[24][0] + 50 * pParty->pPlayers[i].uVoiceID) + 4999, 0);
+                }
+    }
+
+//----- (00491DE7) --------------------------------------------------------
+int __fastcall ReloadPlayerPortraits(int a1, int a2)
+    {
+    int result; // eax@1
+    const char **v3; // ebp@1
+    Texture **v4; // ebx@1
+    int v5; // esi@2
+
+    result = 0;
+    v3 = &pPlayerPortraitsNames[a2];
+    v4 = pTextures_PlayerFaces[a1].data();
+    do
+        {
+        v5 = result + 1;
+        sprintf(pTmpBuf.data(), "%s%02d", *v3, result + 1);
+        pIcons_LOD->ReloadTexture(*v4, pTmpBuf.data(), 2);
+        result = v5;
+        ++v4;
+        }
+        while ( v5 < 56 );
+        return result;
+    }
+//----- (00495B39) --------------------------------------------------------
+void PlayerCreationUI_Draw()
+{
+  int pTextCenter; // eax@3
+  IconFrame *pFrame; // eax@3
+  int pX; // ecx@7
+  GUIButton *uPosActiveItem; // edi@12
+  int uNumLet; // eax@14
+  char v8; // al@17
+  int v9; // ecx@17
+  char v10; // sf@17
+  size_t v16; // eax@28
+  int v17; // eax@33
+  int uStatLevel; // eax@44
+  unsigned int pStatColor; // eax@44
+  PLAYER_SKILL_TYPE pSkillsType; // eax@44
+  int v51; // eax@49
+  char *v52; // edi@52
+  char v53; // al@52
+  PLAYER_CLASS_TYPE uClassType; // edi@53
+  int pColorText; // eax@53
+  PLAYER_SKILL_TYPE pSkillId; // edi@72
+  size_t pLenText; // eax@72
+  signed int v104; // ecx@72
+  int pTextY; // ST08_4@81
+  signed int pBonusNum; // edi@82
+  const char *uRaceName; // [sp+0h] [bp-170h]@39
+  char pText[200]; // [sp+10h] [bp-160h]@14
+  GUIWindow pWindow; // [sp+D8h] [bp-98h]@83
+  size_t v120; // [sp+130h] [bp-40h]@25
+  int uColor1; // [sp+144h] [bp-2Ch]@1
+  int v126; // [sp+148h] [bp-28h]@25
+  int uColorGreen; // [sp+14Ch] [bp-24h]@1
+  int pIntervalY; // [sp+150h] [bp-20h]@14
+  int pX_Numbers; // [sp+154h] [bp-1Ch]@18
+  int uColorTeal; // [sp+158h] [bp-18h]@1
+  int uColorWhite; // [sp+15Ch] [bp-14h]@1
+  int uX; // [sp+160h] [bp-10h]@18
+  unsigned int v133; // [sp+164h] [bp-Ch]@25
+  int pOrder; // [sp+168h] [bp-8h]@14
+  int pIntervalX;
+  int pCorrective;
+  const char *pSkillName;
+
+  uColor1 = TargetColor(0xD1, 0xBB, 0x61);
+  uColorTeal = TargetColor(0, 0xF7, 0xF7);
+  uColorGreen = TargetColor(0, 0xFF, 0);
+  uColorWhite = TargetColor(0xFF, 0xFF, 0xFF);
+  pRenderer->BeginScene();
+  pRenderer->DrawTextureRGB(0, 0, &pTexture_PCX);
+  uPlayerCreationUI_SkySliderPos = (GetTickCount() % 12800) / 20;
+  pRenderer->DrawTextureIndexed(uPlayerCreationUI_SkySliderPos, 2, pTexture_MAKESKY);
+  pRenderer->DrawTextureIndexed(uPlayerCreationUI_SkySliderPos - 640, 2, pTexture_MAKESKY);
+  pRenderer->DrawTextureTransparent(0, 0, pTexture_MAKETOP);
+
+  uPlayerCreationUI_SelectedCharacter = (pGUIWindow_CurrentMenu->pCurrentPosActiveItem - pGUIWindow_CurrentMenu->pStartingPosActiveItem) / 7;
+  switch (uPlayerCreationUI_SelectedCharacter)
+  {
+    case 0: pX = 12;  break;
+    case 1: pX = 171; break;
+    case 2: pX = 329; break;
+    case 3: pX = 488; break;
+    default:
+      assert(false && "Invalid selected character");
+  }
+
+  pTextCenter = pFontCChar->AlignText_Center(640, pGlobalTXT_LocalizationStrings[51]);
+  pGUIWindow_CurrentMenu->DrawText(pFontCChar, pTextCenter + 1, 0, 0, pGlobalTXT_LocalizationStrings[51], 0, 0, 0);
+  pRenderer->DrawTextureTransparent(17, 35, pPlayerPortraits[pParty->pPlayers[0].uCurrentFace]);
+  pRenderer->DrawTextureTransparent(176, 35, pPlayerPortraits[pParty->pPlayers[1].uCurrentFace]);
+  pRenderer->DrawTextureTransparent(335, 35, pPlayerPortraits[pParty->pPlayers[2].uCurrentFace]);
+  pRenderer->DrawTextureTransparent(494, 35, pPlayerPortraits[pParty->pPlayers[3].uCurrentFace]);
+  pFrame = pIconsFrameTable->GetFrame(uIconID_CharacterFrame, pEventTimer->uStartTime);
+
+
+  pRenderer->DrawTextureTransparent(pX, 29, &pIcons_LOD->pTextures[pFrame->uTextureID]);
+  uPosActiveItem = pGUIWindow_CurrentMenu->GetControl(pGUIWindow_CurrentMenu->pCurrentPosActiveItem);
+  uPlayerCreationUI_ArrowAnim = 19 - (GetTickCount() % 500) / 25;
+  pRenderer->DrawTextureTransparent(uPosActiveItem->uZ - 4, uPosActiveItem->uY, pTextures_arrowl[uPlayerCreationUI_ArrowAnim]);
+  pRenderer->DrawTextureTransparent(uPosActiveItem->uX - 12, uPosActiveItem->uY, pTextures_arrowr[uPlayerCreationUI_ArrowAnim]);
+
+  memset(pText, 0, 200);
+  strcpy(pText, pGlobalTXT_LocalizationStrings[205]);// "Skills"
+  uNumLet = strlen(pText) - 1;
+  pOrder = uNumLet;
+  if ( uNumLet >= 0 )
+  {
+    while ( 1 )
+    {
+      v8 = toupper((unsigned __int8)pText[uNumLet]);
+      v9 = pOrder;
+      v10 = pOrder-- - 1 < 0;
+      pText[v9] = v8;
+      if ( v10 )
+        break;
+      uNumLet = pOrder;
+    }
+  }
+
+  pIntervalX = 18;
+  pIntervalY = pFontCreate->uFontHeight - 2;
+  //v124 = 0;
+  uX = 32;
+  pX_Numbers = 493;
+
+  for (int i = 0; i < 4; ++i)
+  {
+    auto player = pParty->pPlayers + i;
+
+    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->receives_keyboard_input_2 != WINDOW_INPUT_NONE && pGUIWindow_CurrentMenu->ptr_1C == (void *)i )
+    {
+      switch ( pGUIWindow_CurrentMenu->receives_keyboard_input_2 )
+      {
+        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 WINDOW_INPUT_CONFIRMED: // press enter
+          pGUIWindow_CurrentMenu->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
+          v120 = strlen((const char *)pKeyActionMap->pPressedKeysBuffer);
+          v126 = 0;
+          v133 = 0;
+          if ( strlen((const char *)pKeyActionMap->pPressedKeysBuffer) )//edit name
+          {
+            do
+            {
+              if ( pKeyActionMap->pPressedKeysBuffer[v133] == ' ' )
+                ++v126;
+              ++v133;
+              v16 = strlen((const char *)pKeyActionMap->pPressedKeysBuffer);
+            }
+            while ( v133 < v16 );
+          }
+          if ( v120 && v126 != v120 )
+            strcpy(player->pName, (const char *)pKeyActionMap->pPressedKeysBuffer);
+          pGUIWindow_CurrentMenu->DrawTextInRect(pFontCreate, pIntervalX, 124, 0, player->pName, 130, 0);
+          *(short *)&player->field_1988[27] = 1;
+          break;
+        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;
+      }
+    }
+    else
+    {
+      pGUIWindow_CurrentMenu->DrawTextInRect(pFontCreate, pIntervalX, 124, 0, player->pName, 130, 0);
+    }
+
+    switch (player->GetRace())
+    {
+      case 0:  uRaceName = pGlobalTXT_LocalizationStrings[99]; break; // "Human"
+      case 1:  uRaceName = pGlobalTXT_LocalizationStrings[103]; break; // "Dwarf"
+      case 2:  uRaceName = pGlobalTXT_LocalizationStrings[106]; break; // "Goblin"
+      case 3:  uRaceName = pGlobalTXT_LocalizationStrings[101]; break; // "Elf"
+    }; 
+    strcpy(pTmpBuf.data(), uRaceName);
+    pGUIWindow_CurrentMenu->DrawTextInRect(pFontCreate, pIntervalX + 72, pIntervalY + 12, 0, pTmpBuf.data(), 130, 0);//Race Name
+
+    pTextCenter = pFontCreate->AlignText_Center(150, pText);
+    pGUIWindow_CurrentMenu->DrawText(pFontCreate, pTextCenter + uX - 24, 291, uColor1, pText, 0, 0, 0); // Skills
+
+    uStatLevel = player->GetActualMight();
+    sprintf(pTmpBuf.data(), "%s\r%03d%d", pGlobalTXT_LocalizationStrings[144], pX_Numbers, uStatLevel);// "Might"
+    pStatColor = player->GetStatColor(0);
+    pGUIWindow_CurrentMenu->DrawText(pFontCreate, uX, 169, pStatColor, pTmpBuf.data(), 0, 0, 0);
+
+    uStatLevel = player->GetActualIntelligence();
+    sprintf(pTmpBuf.data(), "%s\r%03d%d", pGlobalTXT_LocalizationStrings[116], pX_Numbers, uStatLevel);// "Intellect"
+    pStatColor = player->GetStatColor(1);
+    pGUIWindow_CurrentMenu->DrawText(pFontCreate, uX, pIntervalY + 169, pStatColor, pTmpBuf.data(), 0, 0, 0);
+
+    uStatLevel = player->GetActualWillpower();
+    sprintf(pTmpBuf.data(), "%s\r%03d%d", pGlobalTXT_LocalizationStrings[163], pX_Numbers, uStatLevel);// "Personality"
+    pStatColor = player->GetStatColor(2);
+    pGUIWindow_CurrentMenu->DrawText(pFontCreate, uX, 2 * pIntervalY + 169, pStatColor, pTmpBuf.data(), 0, 0, 0);
+
+    uStatLevel = player->GetActualEndurance();
+    sprintf(pTmpBuf.data(), "%s\r%03d%d", pGlobalTXT_LocalizationStrings[75], pX_Numbers, uStatLevel);// "Endurance"
+    pStatColor = player->GetStatColor(3);
+    pGUIWindow_CurrentMenu->DrawText(pFontCreate, uX, 3 * pIntervalY + 169, pStatColor, pTmpBuf.data(), 0, 0, 0);
+
+    uStatLevel = player->GetActualAccuracy();
+    sprintf(pTmpBuf.data(), "%s\r%03d%d", pGlobalTXT_LocalizationStrings[1], pX_Numbers, uStatLevel);// "Accuracy"
+    pStatColor = player->GetStatColor(4);
+    pGUIWindow_CurrentMenu->DrawText(pFontCreate, uX, 4 * pIntervalY + 169, pStatColor, pTmpBuf.data(), 0, 0, 0);
+
+    uStatLevel = player->GetActualSpeed();
+    sprintf(pTmpBuf.data(), "%s\r%03d%d", pGlobalTXT_LocalizationStrings[211], pX_Numbers, uStatLevel);// "Speed"
+    pStatColor = player->GetStatColor(5);
+    pGUIWindow_CurrentMenu->DrawText(pFontCreate, uX, 5 * pIntervalY + 169, pStatColor, pTmpBuf.data(), 0, 0, 0);
+
+    uStatLevel = player->GetActualLuck();
+    sprintf(pTmpBuf.data(), "%s\r%03d%d", pGlobalTXT_LocalizationStrings[136], pX_Numbers, uStatLevel);// "Luck"
+    pStatColor = player->GetStatColor(6);
+    pGUIWindow_CurrentMenu->DrawText(pFontCreate, uX, 6 * pIntervalY + 169, pStatColor, pTmpBuf.data(), 0, 0, 0);
+
+
+    pSkillsType = player->GetSkillIdxByOrder(0);
+    pTextCenter = pFontCreate->AlignText_Center(150, pSkillNames[pSkillsType]);
+    sprintf(pTmpBuf.data(), "\t%03u%s", pTextCenter, pSkillNames[pSkillsType]);
+    pGUIWindow_CurrentMenu->DrawText(pFontCreate, uX - 24, 311, uColorWhite, pTmpBuf.data(), 0, 0, 0);
+
+    pSkillsType = player->GetSkillIdxByOrder(1);
+    pTextCenter = pFontCreate->AlignText_Center(150, pSkillNames[pSkillsType]);
+    sprintf(pTmpBuf.data(), "\t%03u%s", pTextCenter, pSkillNames[pSkillsType]);
+    pGUIWindow_CurrentMenu->DrawText(pFontCreate, uX - 24, pIntervalY + 311, uColorWhite, pTmpBuf.data(), 0, 0, 0);
+
+    pSkillsType = player->GetSkillIdxByOrder(2);
+    pTextCenter = pFontCreate->AlignText_Center(150, pSkillNames[pSkillsType]);
+    sprintf(pTmpBuf.data(), "\t%03u%s", pTextCenter, pSkillNames[pSkillsType]);
+    pColorText = uColorGreen;
+    if ( (signed int)pSkillsType >= 37 )
+      pColorText = uColorTeal;
+    pGUIWindow_CurrentMenu->DrawText(pFontCreate, uX - 24, 2 * pIntervalY + 311, pColorText, pTmpBuf.data(), 0, 0, 0);
+
+    pSkillsType = player->GetSkillIdxByOrder(3);
+    pTextCenter = pFontCreate->AlignText_Center(150, pSkillNames[pSkillsType]);
+    sprintf(pTmpBuf.data(), "\t%03u%s", pTextCenter, pSkillNames[pSkillsType]);
+    pColorText = uColorGreen;
+    if ( (signed int)pSkillsType >= 37 )
+      pColorText = uColorTeal;
+    pGUIWindow_CurrentMenu->DrawText(pFontCreate, uX - 24, 3 * pIntervalY + 311, pColorText, pTmpBuf.data(), 0, 0, 0);
+
+    //v124 = (char *)v124 + 1;
+    pIntervalX += 159;
+    pX_Numbers -= 158;
+    uX += 158;
+  }
+
+  strcpy(pText, pGlobalTXT_LocalizationStrings[41]);// "Class"
+  v51 = strlen(pText) - 1;
+  pOrder = v51;
+  if ( v51 >= 0 )
+  {
+    while ( 1 )
+    {
+      v52 = &pText[v51];
+      v53 = toupper((unsigned __int8)pText[v51]);
+      v10 = pOrder-- - 1 < 0;
+      *v52 = v53;
+      if ( v10 )
+        break;
+      v51 = pOrder;
+    }
+  }
+  uClassType = pParty->pPlayers[uPlayerCreationUI_SelectedCharacter].classType;
+  pTextCenter = pFontCreate->AlignText_Center(193, pText);
+  pGUIWindow_CurrentMenu->DrawText(pFontCreate, pTextCenter + 324, 395, uColor1, pText, 0, 0, 0);//Classes
+
+  pColorText = uColorTeal;
+  if ( uClassType )
+    pColorText = uColorWhite;
+  pTextCenter = pFontCreate->AlignText_Center(65, pClassNames[0]);
+  pGUIWindow_CurrentMenu->DrawText(pFontCreate, pTextCenter + 323, 417, pColorText, pClassNames[0], 0, 0, 0);
+
+  pColorText = uColorTeal;
+  if ( uClassType != PLAYER_CLASS_PALADIN )
+    pColorText = uColorWhite;
+  pTextCenter = pFontCreate->AlignText_Center(65, pClassNames[12]);
+  pGUIWindow_CurrentMenu->DrawText(pFontCreate, pTextCenter + 323, pIntervalY + 417, pColorText, pClassNames[12], 0, 0, 0);
+
+  pColorText = uColorTeal;
+  if ( uClassType != PLAYER_CLASS_DRUID )
+    pColorText = uColorWhite;
+  pTextCenter = pFontCreate->AlignText_Center(65, pClassNames[20]);
+  pGUIWindow_CurrentMenu->DrawText(pFontCreate, pTextCenter + 323, 2 * pIntervalY + 417, pColorText, pClassNames[20], 0, 0, 0);
+
+  pColorText = uColorTeal;
+  if ( uClassType != PLAYER_CLASS_CLERIC )
+    pColorText = uColorWhite;
+  pTextCenter = pFontCreate->AlignText_Center(65, pClassNames[24]);
+  pGUIWindow_CurrentMenu->DrawText(pFontCreate, pTextCenter + 388, 417, pColorText, pClassNames[24], 0, 0, 0);
+
+  pColorText = uColorTeal;
+  if ( uClassType != PLAYER_CLASS_DRUID)
+    pColorText = uColorWhite;
+  pTextCenter = pFontCreate->AlignText_Center(65, pClassNames[28]);
+  pGUIWindow_CurrentMenu->DrawText(pFontCreate, pTextCenter + 388, pIntervalY + 417, pColorText, pClassNames[28], 0, 0, 0);
+
+  pColorText = uColorTeal;
+  if ( uClassType != PLAYER_CLASS_SORCERER )
+    pColorText = uColorWhite;
+  pTextCenter = pFontCreate->AlignText_Center(65, pClassNames[32]);
+  pGUIWindow_CurrentMenu->DrawText(pFontCreate, pTextCenter + 388, 2 * pIntervalY + 417, pColorText, pClassNames[32], 0, 0, 0);
+
+  pColorText = uColorTeal;
+  if ( uClassType != PLAYER_CLASS_ARCHER )
+    pColorText = uColorWhite;
+  pTextCenter = pFontCreate->AlignText_Center(65, pClassNames[16]);
+  pGUIWindow_CurrentMenu->DrawText(pFontCreate, pTextCenter + 453, 417, pColorText, pClassNames[16], 0, 0, 0);
+
+  pColorText = uColorTeal;
+  if ( uClassType != PLAYER_CLASS_MONK )
+    pColorText = uColorWhite;
+  pTextCenter = pFontCreate->AlignText_Center(65, pClassNames[8]);
+  pGUIWindow_CurrentMenu->DrawText(pFontCreate, pTextCenter + 453, pIntervalY + 417, pColorText, pClassNames[8], 0, 0, 0);
+
+  pColorText = uColorTeal;
+  if ( uClassType != PLAYER_CLASS_THEIF )
+    pColorText = uColorWhite;
+  pTextCenter = pFontCreate->AlignText_Center(65, pClassNames[4]);
+  pGUIWindow_CurrentMenu->DrawText(pFontCreate, pTextCenter + 453, 2 * pIntervalY + 417, pColorText, pClassNames[4], 0, 0, 0);
+
+  pTextCenter = pFontCreate->AlignText_Center(236, pGlobalTXT_LocalizationStrings[20]); // "Available Skills"
+  pGUIWindow_CurrentMenu->DrawText(pFontCreate, pTextCenter + 37, 395, uColor1, pGlobalTXT_LocalizationStrings[20], 0, 0, 0);
+  for (uint i = 0; i < 9; ++i)
+  {
+    pSkillId = pParty->pPlayers[uPlayerCreationUI_SelectedCharacter].GetSkillIdxByOrder(i + 4);
+    strcpy(pText, pSkillNames[pSkillId]);
+    pLenText = strlen(pText);
+    v104 = 0;
+    if ( (signed int)pLenText > 0 )
+    {
+      if ( pText[v104] == 32 )
+      {
+        pText[v104] = 0;
+      }
+      else
+      {
+        while ( pText[v104] != 32 )
+        {
+          ++v104;
+          if ( v104 >= (signed int)pLenText )
+          break;
+        }
+      }
+    }
+    pCorrective = -10;//-5
+    if ( (signed int)pLenText < 8 )//if ( (signed int)v124 > 2 )
+      pCorrective = 0;
+    pColorText = uColorTeal;
+    if ( !pParty->pPlayers[uPlayerCreationUI_SelectedCharacter].pActiveSkills[pSkillId] )
+      pColorText = uColorWhite;
+    pTextCenter = pFontCreate->AlignText_Center(100, pText);
+    pGUIWindow_CurrentMenu->DrawText(pFontCreate, 100 * (i / 3) + pTextCenter + pCorrective + 17, pIntervalY * (i % 3) + 417, pColorText, pText, 0, 0, 0);
+  }
+
+  pTextCenter = pFontCreate->AlignText_Center(0x5C, pGlobalTXT_LocalizationStrings[30]);// "Bonus"
+  pGUIWindow_CurrentMenu->DrawText(pFontCreate, pTextCenter + 533, 394, uColor1, pGlobalTXT_LocalizationStrings[30], 0, 0, 0);
+  pBonusNum = PlayerCreation_GetUnspentAttributePointCount();
+  sprintf(pTmpBuf.data(), "%d", pBonusNum);
+  pTextCenter = pFontCreate->AlignText_Center(84, pTmpBuf.data());
+  pGUIWindow_CurrentMenu->DrawText(pFontCreate, pTextCenter + 530, 410, uColorWhite, pTmpBuf.data(), 0, 0, 0);
+  if ( GameUI_Footer_TimeLeft > GetTickCount() )
+  {
+    pWindow.Hint = pGlobalTXT_LocalizationStrings[412];// "Create Party cannot be completed unless you have assigned all characters 2 extra skills and have spent all of your bonus points."
+    if ( pBonusNum < 0 )
+      pWindow.Hint = pGlobalTXT_LocalizationStrings[413];// "You can't spend more than 50 points."
+    pWindow.uFrameWidth = 300;
+    pWindow.uFrameHeight = 100;
+    pWindow.uFrameX = 170;
+    pWindow.uFrameY = 140;
+    pWindow.uFrameZ = 469;
+    pWindow.uFrameW = 239;
+    pWindow.DrawMessageBox(0);
+  }
+  pRenderer->EndScene();
+}
+
+//----- (0049695A) --------------------------------------------------------
+void __cdecl PlayerCreationUI_Initialize()
+{
+  unsigned int v0; // ebx@5
+  unsigned int v1; // eax@6
+  int v2; // ecx@6
+  //unsigned int v3; // eax@8
+  //signed int v4; // ecx@8
+  signed int uControlParam; // [sp+10h] [bp-Ch]@7
+  unsigned int uControlParama; // [sp+10h] [bp-Ch]@9
+  unsigned int uControlParamb; // [sp+10h] [bp-Ch]@11
+  unsigned int uControlParamc; // [sp+10h] [bp-Ch]@13
+  signed int uControlParamd; // [sp+10h] [bp-Ch]@15
+  signed int uX; // [sp+14h] [bp-8h]@5
+  unsigned int uXa; // [sp+14h] [bp-8h]@9
+  unsigned int uXb; // [sp+14h] [bp-8h]@11
+  unsigned int uXc; // [sp+14h] [bp-8h]@13
+  signed int uXd; // [sp+14h] [bp-8h]@16
+
+  pMessageQueue_50CBD0->Flush();
+
+  pAudioPlayer->SetMusicVolume(pSoundVolumeLevels[uMusicVolimeMultiplier] * 64.0f);
+  ++pIcons_LOD->uTexturePacksCount;
+  if ( !pIcons_LOD->uNumPrevLoadedFiles )
+    pIcons_LOD->uNumPrevLoadedFiles = pIcons_LOD->uNumLoadedFiles;
+  pCurrentScreen = SCREEN_PARTY_CREATION;
+  uPlayerCreationUI_ArrowAnim = 0;
+  uPlayerCreationUI_SkySliderPos = 0;
+  uPlayerCreationUI_SelectedCharacter = 0;
+  v0 = LOBYTE(pFontCreate->uFontHeight) - 2;
+  pTexture_IC_KNIGHT[0] = pIcons_LOD->LoadTexturePtr("IC_KNIGHT", TEXTURE_16BIT_PALETTE);
+  pTexture_IC_KNIGHT[1] = pIcons_LOD->LoadTexturePtr("IC_THIEF", TEXTURE_16BIT_PALETTE);
+  pTexture_IC_KNIGHT[2] = pIcons_LOD->LoadTexturePtr("IC_MONK", TEXTURE_16BIT_PALETTE);
+  pTexture_IC_KNIGHT[3] = pIcons_LOD->LoadTexturePtr("IC_PALAD", TEXTURE_16BIT_PALETTE);
+  pTexture_IC_KNIGHT[4] = pIcons_LOD->LoadTexturePtr("IC_ARCH", TEXTURE_16BIT_PALETTE);
+  pTexture_IC_KNIGHT[5] = pIcons_LOD->LoadTexturePtr("IC_RANGER", TEXTURE_16BIT_PALETTE);
+  pTexture_IC_KNIGHT[6] = pIcons_LOD->LoadTexturePtr("IC_CLER", TEXTURE_16BIT_PALETTE);
+  pTexture_IC_KNIGHT[7] = pIcons_LOD->LoadTexturePtr("IC_DRUID", TEXTURE_16BIT_PALETTE);
+  pTexture_IC_KNIGHT[8] = pIcons_LOD->LoadTexturePtr("IC_SORC", TEXTURE_16BIT_PALETTE);
+  pTexture_MAKETOP = pIcons_LOD->LoadTexturePtr("MAKETOP", TEXTURE_16BIT_PALETTE);
+  pTexture_MAKESKY = pIcons_LOD->LoadTexturePtr("MAKESKY", TEXTURE_16BIT_PALETTE);
+  for(uX=0;uX < 22;++uX ) // load PlayerPortraits texture
+  {
+    sprintf(pTmpBuf.data(), "%s01", pPlayerPortraitsNames[uX]);
+    v1 = pIcons_LOD->LoadTexture(pTmpBuf.data(), TEXTURE_16BIT_PALETTE);
+    pPlayerPortraits[uX] = &pIcons_LOD->pTextures[v1];
+
+  }
+  pTexture_PlayerFaceMask = pIcons_LOD->LoadTexturePtr("FACEMASK", TEXTURE_16BIT_PALETTE);
+  pTexture_buttminu  = pIcons_LOD->LoadTexturePtr("buttminu", TEXTURE_16BIT_PALETTE);
+  pTexture_buttplus  = pIcons_LOD->LoadTexturePtr("buttplus", TEXTURE_16BIT_PALETTE);
+  pTexture_pressrigh = pIcons_LOD->LoadTexturePtr("presrigh", TEXTURE_16BIT_PALETTE);
+  pTexture_presleft  = pIcons_LOD->LoadTexturePtr("presleft", TEXTURE_16BIT_PALETTE);
+  uControlParam = 1;
+  do
+  {
+    sprintf(pTmpBuf.data(), "arrowl%d", uControlParam);
+    pTextures_arrowl[uControlParam] = pIcons_LOD->LoadTexturePtr(pTmpBuf.data(), TEXTURE_16BIT_PALETTE);
+
+    sprintf(pTmpBuf.data(), "arrowr%d", uControlParam);
+    pTextures_arrowr[uControlParam] = pIcons_LOD->LoadTexturePtr(pTmpBuf.data(), TEXTURE_16BIT_PALETTE);
+  }
+  while ( ++uControlParam < 20 );
+  pGUIWindow_CurrentMenu = GUIWindow::Create(0, 0, 640, 480, WINDOW_MainMenu, 0, 0);
+  uControlParama = 0;
+  uXa = 8;
+  do
+  {
+    pGUIWindow_CurrentMenu->CreateButton(uXa, 120, 145, 25, 1, 0, UIMSG_PlayerCreationChangeName, uControlParama, 0, "", 0);
+    uXa += 158;
+    ++uControlParama;
+  }
+  while ( (signed int)uXa < 640 );
+
+  pCreationUI_BtnPressLeft[0]   = pGUIWindow_CurrentMenu->CreateButton( 10,  32, 11, 13, 1, 0, UIMSG_PlayerCreation_FacePrev,  0, 0, "", pTexture_presleft, 0);
+  pCreationUI_BtnPressLeft[1]   = pGUIWindow_CurrentMenu->CreateButton(169,  32, 11, 13, 1, 0, UIMSG_PlayerCreation_FacePrev,  1, 0, "", pTexture_presleft, 0);
+  pCreationUI_BtnPressLeft[2]   = pGUIWindow_CurrentMenu->CreateButton(327,  32, 11, 13, 1, 0, UIMSG_PlayerCreation_FacePrev,  2, 0, "", pTexture_presleft, 0);
+  pCreationUI_BtnPressLeft[3]   = pGUIWindow_CurrentMenu->CreateButton(486,  32, 11, 13, 1, 0, UIMSG_PlayerCreation_FacePrev,  3, 0, "", pTexture_presleft, 0);
+  pCreationUI_BtnPressRight[0]  = pGUIWindow_CurrentMenu->CreateButton( 74,  32, 11, 13, 1, 0, UIMSG_PlayerCreation_FaceNext,  0, 0, "", pTexture_pressrigh, 0);
+  pCreationUI_BtnPressRight[1]  = pGUIWindow_CurrentMenu->CreateButton(233,  32, 11, 13, 1, 0, UIMSG_PlayerCreation_FaceNext,  1, 0, "", pTexture_pressrigh, 0);
+  pCreationUI_BtnPressRight[2]  = pGUIWindow_CurrentMenu->CreateButton(391,  32, 11, 13, 1, 0, UIMSG_PlayerCreation_FaceNext,  2, 0, "", pTexture_pressrigh, 0);
+  pCreationUI_BtnPressRight[3]  = pGUIWindow_CurrentMenu->CreateButton(549,  32, 11, 13, 1, 0, UIMSG_PlayerCreation_FaceNext,  3, 0, "", pTexture_pressrigh, 0);
+  pCreationUI_BtnPressLeft2[0]  = pGUIWindow_CurrentMenu->CreateButton( 10, 103, 11, 13, 1, 0, UIMSG_PlayerCreation_VoicePrev, 0, 0, "", pTexture_presleft, 0);
+  pCreationUI_BtnPressLeft2[1]  = pGUIWindow_CurrentMenu->CreateButton(169, 103, 11, 13, 1, 0, UIMSG_PlayerCreation_VoicePrev, 1, 0, "", pTexture_presleft, 0);
+  pCreationUI_BtnPressLeft2[2]  = pGUIWindow_CurrentMenu->CreateButton(327, 103, 11, 13, 1, 0, UIMSG_PlayerCreation_VoicePrev, 2, 0, "", pTexture_presleft, 0);
+  pCreationUI_BtnPressLeft2[3]  = pGUIWindow_CurrentMenu->CreateButton(486, 103, 11, 13, 1, 0, UIMSG_PlayerCreation_VoicePrev, 3, 0, "", pTexture_presleft, 0);
+  pCreationUI_BtnPressRight2[0] = pGUIWindow_CurrentMenu->CreateButton( 74, 103, 11, 13, 1, 0, UIMSG_PlayerCreation_VoiceNext, 0, 0, "", pTexture_pressrigh, 0);
+  pCreationUI_BtnPressRight2[1] = pGUIWindow_CurrentMenu->CreateButton(233, 103, 11, 13, 1, 0, UIMSG_PlayerCreation_VoiceNext, 1, 0, "", pTexture_pressrigh, 0);
+  pCreationUI_BtnPressRight2[2] = pGUIWindow_CurrentMenu->CreateButton(391, 103, 11, 13, 1, 0, UIMSG_PlayerCreation_VoiceNext, 2, 0, "", pTexture_pressrigh, 0);
+  pCreationUI_BtnPressRight2[3] = pGUIWindow_CurrentMenu->CreateButton(549, 103, 11, 13, 1, 0, UIMSG_PlayerCreation_VoiceNext, 3, 0, "", pTexture_pressrigh, 0);
+
+  uControlParamb = 0;
+  uXb = 8;
+  do
+  {
+    pGUIWindow_CurrentMenu->CreateButton(uXb, 308,          150, v0, 1, 0, UIMSG_48,                            uControlParamb, 0, "", 0);
+    pGUIWindow_CurrentMenu->CreateButton(uXb, v0 + 308,     150, v0, 1, 0, UIMSG_49,                            uControlParamb, 0, "", 0);
+    pGUIWindow_CurrentMenu->CreateButton(uXb, 2 * v0 + 308, 150, v0, 1, 0, UIMSG_PlayerCreationRemoveUpSkill,   uControlParamb, 0, "", 0);
+    pGUIWindow_CurrentMenu->CreateButton(uXb, 3 * v0 + 308, 150, v0, 1, 0, UIMSG_PlayerCreationRemoveDownSkill, uControlParamb, 0, "", 0);
+    uXb += 158;
+    ++uControlParamb;
+  }
+  while ( (signed int)uXb < 640 );
+
+  pGUIWindow_CurrentMenu->CreateButton(  5, 21, 153, 365, 1, 0, UIMSG_PlayerCreation_SelectAttribute, 0, '1', "", 0);
+  pGUIWindow_CurrentMenu->CreateButton(163, 21, 153, 365, 1, 0, UIMSG_PlayerCreation_SelectAttribute, 1, '2', "", 0);
+  pGUIWindow_CurrentMenu->CreateButton(321, 21, 153, 365, 1, 0, UIMSG_PlayerCreation_SelectAttribute, 2, '3', "", 0);
+  pGUIWindow_CurrentMenu->CreateButton(479, 21, 153, 365, 1, 0, UIMSG_PlayerCreation_SelectAttribute, 3, '4', "", 0);
+
+  uXc = 23;
+  uControlParamc = 2;
+  do
+  {
+    pGUIWindow_CurrentMenu->CreateButton(uXc, 169,          120, 20, 1, 0, UIMSG_0, uControlParamc - 2, 0, "", 0);
+    pGUIWindow_CurrentMenu->CreateButton(uXc, v0 + 169,     120, 20, 1, 0, UIMSG_0, uControlParamc - 1, 0, "", 0);
+    pGUIWindow_CurrentMenu->CreateButton(uXc, 2 * v0 + 169, 120, 20, 1, 0, UIMSG_0, uControlParamc, 0, "", 0);
+    pGUIWindow_CurrentMenu->CreateButton(uXc, 3 * v0 + 169, 120, 20, 1, 0, UIMSG_0, uControlParamc + 1, 0, "", 0);
+    pGUIWindow_CurrentMenu->CreateButton(uXc, 4 * v0 + 169, 120, 20, 1, 0, UIMSG_0, uControlParamc + 2, 0, "", 0);
+    pGUIWindow_CurrentMenu->CreateButton(uXc, 5 * v0 + 169, 120, 20, 1, 0, UIMSG_0, uControlParamc + 3, 0, "", 0);
+    pGUIWindow_CurrentMenu->CreateButton(uXc, 6 * v0 + 169, 120, 20, 1, 0, UIMSG_0, uControlParamc + 4, 0, "", 0);
+    uControlParamc += 7;
+    uXc += 158;
+  }
+  while ( (signed int)uControlParamc < 30 );
+  pGUIWindow_CurrentMenu->_41D08F_set_keyboard_control_group(28, 0, 7, 40);
+
+  pGUIWindow_CurrentMenu->CreateButton(323, 417,          65, v0, 1, 0, UIMSG_PlayerCreationSelectClass, 0,    0, "", 0);
+  pGUIWindow_CurrentMenu->CreateButton(323, v0 + 417,     65, v0, 1, 0, UIMSG_PlayerCreationSelectClass, 0xC,  0, "", 0);
+  pGUIWindow_CurrentMenu->CreateButton(323, 2 * v0 + 417, 65, v0, 1, 0, UIMSG_PlayerCreationSelectClass, 0x14, 0, "", 0);
+  pGUIWindow_CurrentMenu->CreateButton(388, 417,          65, v0, 1, 0, UIMSG_PlayerCreationSelectClass, 0x18, 0, "", 0);
+  pGUIWindow_CurrentMenu->CreateButton(388, v0 + 417,     65, v0, 1, 0, UIMSG_PlayerCreationSelectClass, 0x1C, 0, "", 0);
+  pGUIWindow_CurrentMenu->CreateButton(388, 2 * v0 + 417, 65, v0, 1, 0, UIMSG_PlayerCreationSelectClass, 0x20, 0, "", 0);
+  pGUIWindow_CurrentMenu->CreateButton(453, 417,          65, v0, 1, 0, UIMSG_PlayerCreationSelectClass, 0x10, 0, "", 0);
+  pGUIWindow_CurrentMenu->CreateButton(453, v0 + 417,     65, v0, 1, 0, UIMSG_PlayerCreationSelectClass, 8,    0, "", 0);
+  pGUIWindow_CurrentMenu->CreateButton(453, 2 * v0 + 417, 65, v0, 1, 0, UIMSG_PlayerCreationSelectClass, 4,    0, "", 0);
+
+  uControlParamd = 0;
+  do
+  {
+    uXd = -5;
+    if ( uControlParamd <= 3 )
+      uXd = 0;
+    pGUIWindow_CurrentMenu->CreateButton(100 * (uControlParamd / 3) + uXd + 17, v0 * (uControlParamd % 3) + 417, 100, v0, 1, 0, UIMSG_PlayerCreationSelectActiveSkill,
+      uControlParamd, 0, "", 0);
+    ++uControlParamd;
+  }
+  while ( uControlParamd < 9 );
+
+  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);
+}
+// 4E28F8: using guessed type int pCurrentScreen;
+
+//----- (0049750E) --------------------------------------------------------
+void DeleteCCharFont()
+{
+  pAllocator->FreeChunk(pFontCChar);
+  pFontCChar = 0;
+}
+//----- (00497526) --------------------------------------------------------
+bool PlayerCreationUI_Loop()
+{
+  //RGBTexture *pTexture; // ebx@1
+  //UINT v1; // esi@1
+  unsigned int v2; // ecx@3
+  LONG uMouseX; // edi@6
+  LONG uMouseY; // eax@6
+  GUIButton *pControlsHead; // edx@6
+  //unsigned int pNumMessage; // ecx@7
+  int pControlParam; // esi@12
+  signed int v8; // edi@30
+  int v9; // edx@31
+  char *v10; // ebx@37
+  Player *v11; // esi@38
+  //signed int uSpellBookPageCount; // ecx@40
+  int v13; // eax@40
+  //signed int uSkillIdx; // eax@45
+  int v15; // eax@70
+  signed int v16; // ecx@70
+  //unsigned int v18; // [sp-4h] [bp-84h]@48
+  ItemGen item; // [sp+Ch] [bp-74h]@37
+  char v20[32]; // [sp+30h] [bp-50h]@29
+  //char v21; // [sp+31h] [bp-4Fh]@29
+  //__int16 v22; // [sp+4Dh] [bp-33h]@29
+  char v23; // [sp+4Fh] [bp-31h]@29
+  MSG Msg; // [sp+50h] [bp-30h]@17
+  POINT v25; // [sp+6Ch] [bp-14h]@6
+  bool v26; // [sp+74h] [bp-Ch]@1
+  //POINT v24; // [sp+78h] [bp-8h]@6
+  //Player *pPlayer;
+
+  //pTexture = &pTexture_PCX;
+  v26 = 0;
+  pTexture_PCX.Release();
+  pTexture_PCX.Load("makeme.pcx", 0);
+
+  v2 = 6;
+  pGUIWindow_CurrentMenu->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
+//LABEL_27:
+  SetCurrentMenuID((MENU_STATE)v2);
+  while ( GetCurrentMenuID() == MENU_CREATEPARTY )
+  {
+    uMouseX = pMouse->GetCursorPos(&v25)->x;
+    uMouseY = pMouse->GetCursorPos(&v25)->y;
+    pControlsHead = pGUIWindow_CurrentMenu->pControlsHead;
+
+    //does nothing actually
+    /*if ( pControlsHead != (GUIButton *)v1 )
+    {
+      pNumMessage = pMessageQueue_50CBD0->uNumMessages;
+      do
+      {
+        if ( uMouseX >= (signed int)pControlsHead->uX && uMouseX <= (signed int)pControlsHead->uZ 
+            && uMouseY >= (signed int)pControlsHead->uY && uMouseY <= (signed int)pControlsHead->uW )//mouse movement
+        {
+          pControlParam = pControlsHead->uControlParam;
+          pMessageQueue_50CBD0->AddMessage((UIMessageType)pControlsHead->field_1C, pControlParam, 0);
+          v1 = 0;
+        }
+        pControlsHead = pControlsHead->pNext;
+      }
+      while ( pControlsHead != (GUIButton *)v1 );
+    }*/
+
+    while ( PeekMessageA(&Msg, 0, 0, 0, PM_REMOVE) )
+    {
+      if ( Msg.message == WM_QUIT )
+        Game_DeinitializeAndTerminate(0);
+      TranslateMessage(&Msg);
+      DispatchMessageA(&Msg);
+    }
+    if ( BYTE1(dword_6BE364_game_settings_1) & 1 )
+    {
+      WaitMessage();
+    }
+    else
+    {
+      PlayerCreationUI_Draw();
+      GUI_MainMenuMessageProc();
+      pRenderer->BeginScene();
+      GUI_UpdateWindows();
+      pRenderer->EndScene();
+      pRenderer->Present();
+      if ( uGameState == GAME_FINISHED )//if click Esc in PlayerCreation Window
+      {
+        v26 = 1;
+        //v2 = 0;
+        //goto LABEL_27;
+        SetCurrentMenuID(MENU_MAIN);
+        continue;
+      }
+      if ( uGameState == GAME_STATE_STARTING_NEW_GAME )//if click OK in PlayerCreation Window
+      {
+        uGameState = GAME_STATE_PLAYING;
+        //v2 = 1;
+        //goto LABEL_27;
+        SetCurrentMenuID(MENU_NEWGAME);
+        continue;
+      }
+    }
+  }
+  pTexture_PCX.Release();
+  pGUIWindow_CurrentMenu->Release();
+  pIcons_LOD->_4114F2();
+
+  int v1 = 0;
+  memset(v20, 0, 32);
+  do
+  {
+    v8 = 0;
+    do
+    {
+      v9 = rand() % 32;
+      if ( !v20[v9] )
+        break;
+      ++v8;
+    }
+    while ( v8 < 10 );
+    if ( v8 == 10 )
+    {
+      v9 = 0;
+      if ( v20[0] )
+      {
+        do
+          ++v9;
+        while ( v20[v9] );
+      }
+    }
+    pParty->field_854[v1++] = v9;
+    v20[v9] = 1;
+  }
+  while ( (signed int)v1 < 32 );
+  //v10 = (char *)&pParty->pPlayers[0].sResMagicBase;
+  
+  item.Reset();
+  //for ( pPlayer = &pParty->pPlayers[0];  pPlayer < &pParty->pPlayers[4]; pPlayer++)
+  for (uint i = 0; i < 4; ++i)
+  {
+    auto player = &pParty->pPlayers[i];
+    //v11 = pPlayer;
+    if (player->classType == PLAYER_CLASS_KNIGHT)
+      player->sResMagicBase = 10;
+    //*((short *)v10 + 400) = 0;
+    player->pPlayerBuffs[22].uExpireTime = 0;
+    for (uint j = 0; j < 9; j++)
+    {
+      if (player->pActiveSkills[PLAYER_SKILL_FIRE + j])
+      {
+        player->lastOpenedSpellbookPage = j;
+        break;
+      }
+    }
+    pItemsTable->GenerateItem(2, 40, &item);
+    player->AddItem2(-1, &item);
+    //uSkillIdx = 0;
+    //v24.y = 0;
+
+    player->sHealth = player->GetMaxHealth();
+    player->sMana = player->GetMaxMana();
+    for (uint j = 0; j < 37; ++j)
+    {
+      if (!player->pActiveSkills[j])
+        continue;
+
+      switch (j)
+      {
+        case PLAYER_SKILL_STAFF:   player->AddItem(-1, 61); break;
+        case PLAYER_SKILL_SWORD:   player->AddItem(-1, 1); break;
+        case PLAYER_SKILL_DAGGER:  player->AddItem(-1, 15); break;
+        case PLAYER_SKILL_AXE:     player->AddItem(-1, 23); break;
+        case PLAYER_SKILL_SPEAR:   player->AddItem(-1, 31); break;
+        case PLAYER_SKILL_BOW:     player->AddItem(-1, 47); break;
+        case PLAYER_SKILL_MACE:    player->AddItem(-1, 50); break;
+        case PLAYER_SKILL_BLASTER: assert(false); break;
+        case PLAYER_SKILL_SHIELD:  player->AddItem(-1, 84); break;
+        case PLAYER_SKILL_LEATHER: player->AddItem(-1, 66); break;
+        case PLAYER_SKILL_CHAIN:   player->AddItem(-1, 71); break;
+        case PLAYER_SKILL_PLATE:   player->AddItem(-1, 76); break;
+        case PLAYER_SKILL_FIRE:
+          player->AddItem(-1, 0x191);
+          player->spellbook.pFireSpellbook.bIsSpellAvailable[0] = true;
+        break;
+        case PLAYER_SKILL_AIR:
+          player->AddItem(-1, 0x19C);
+          player->spellbook.pAirSpellbook.bIsSpellAvailable[0] = true;
+        break;
+        case PLAYER_SKILL_WATER:
+          player->AddItem(-1, 0x1A7);
+		  player->spellbook.pWaterSpellbook.bIsSpellAvailable[0] = true;
+        break;
+        case PLAYER_SKILL_EARTH:
+          player->AddItem(-1, 0x1B2);
+		  player->spellbook.pEarthSpellbook.bIsSpellAvailable[0] = true;
+        break;
+        case PLAYER_SKILL_SPIRIT:
+          player->AddItem(-1, 0x1BD);
+		  player->spellbook.pSpiritSpellbook.bIsSpellAvailable[0] = true;
+        break;
+        case PLAYER_SKILL_MIND:
+          player->AddItem(-1, 0x1C8);
+		  player->spellbook.pMindSpellbook.bIsSpellAvailable[0] = true;
+        break;
+        case PLAYER_SKILL_BODY:
+          player->AddItem(-1, 0x1D3);
+		  player->spellbook.pBodySpellbook.bIsSpellAvailable[0] = true;
+        break;
+        case PLAYER_SKILL_LIGHT:
+        case PLAYER_SKILL_DARK:
+        case PLAYER_SKILL_DIPLOMACY:
+          assert(false);
+        break;
+        case PLAYER_SKILL_ITEM_ID:
+        case PLAYER_SKILL_REPAIR:
+        case PLAYER_SKILL_MEDITATION:
+        case PLAYER_SKILL_PERCEPTION:
+        case PLAYER_SKILL_TRAP_DISARM:
+        case PLAYER_SKILL_LEARNING:
+          player->AddItem(-1, 0xDC);
+		  player->AddItem(-1, 5 * (rand() % 3 + 40));
+        break;
+        case PLAYER_SKILL_DODGE:   player->AddItem(-1, 115); break;
+        case PLAYER_SKILL_UNARMED: player->AddItem(-1, 110); break;
+        default:
+          break;
+      }
+
+      for (uint k = 0; k < 138; k++)
+      {
+        if (player->pOwnItems[k].uItemID)
+          player->pOwnItems[k].SetIdentified();
+      }
+    }
+  }
+
+  pAudioPlayer->StopChannels(-1, -1);
+  return v26;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/UI/UIPopup.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -0,0 +1,2193 @@
+#ifdef _MSC_VER
+#define _CRT_SECURE_NO_WARNINGS
+#endif
+
+#include <assert.h>
+
+#include "..\MM7.h"
+
+#include "..\Mouse.h"
+
+#include "..\Sprites.h"
+#include "..\Vis.h"
+#include "..\Game.h"
+#include "..\GUIWindow.h"
+#include "..\GUIFont.h"
+#include "..\Party.h"
+#include "..\AudioPlayer.h"
+#include "..\LOD.h"
+#include "..\Actor.h"
+#include "..\Viewport.h"
+#include "..\SpriteObject.h"
+#include "..\ObjectList.h"
+#include "..\Chest.h"
+#include "..\PaletteManager.h"
+#include "..\Time.h"
+#include "..\texts.h"
+
+#include "..\mm7_data.h"
+
+static char static_sub_417BB5_out_string[1200]; // static to a file, not sub actually
+
+//----- (004151D9) --------------------------------------------------------
+void __fastcall DrawPopupWindow(unsigned int uX, unsigned int uY, unsigned int uWidth, unsigned int uHeight)
+    {
+    unsigned int v4; // ebx@1
+    Texture *v5; // edi@1
+    signed int uTileWidth; // ecx@1
+    int v7; // eax@5
+    int v8; // ecx@10
+    unsigned int v9; // ebx@14
+    int v10; // [sp+10h] [bp-28h]@5
+    signed int uTileHeight; // [sp+18h] [bp-20h]@1
+    int v12; // [sp+1Ch] [bp-1Ch]@7
+    int v13; // [sp+20h] [bp-18h]@1
+    int a5; // [sp+24h] [bp-14h]@5
+    unsigned int a5a; // [sp+24h] [bp-14h]@11
+    unsigned int a4; // [sp+28h] [bp-10h]@1
+    int uNumXTiles; // [sp+2Ch] [bp-Ch]@3
+    unsigned int uNumXTilesa; // [sp+2Ch] [bp-Ch]@6
+    unsigned int uNumXTilesb; // [sp+2Ch] [bp-Ch]@11
+    unsigned int a2a; // [sp+30h] [bp-8h]@1
+    unsigned int v21; // [sp+34h] [bp-4h]@5
+    unsigned int v22; // [sp+34h] [bp-4h]@11
+
+    v4 = uY;
+    a2a = uX;
+    a4 = uX + uWidth;
+    pRenderer->SetTextureClipRect(uX, v4, uX + uWidth, v4 + uHeight);
+    v5 = pIcons_LOD->GetTexture(uTextureID_Parchment);
+    uTileWidth = v5->uTextureWidth;
+    v13 = v5->uTextureWidth;
+    uTileHeight = v5->uTextureHeight;
+    if ( v5->uTextureWidth && v5->uTextureHeight)
+    {
+        uNumXTiles = (signed int)uWidth / uTileWidth;
+        if ( (signed int)uWidth % uTileWidth )
+            ++uNumXTiles;
+        a5 = 0;
+        v21 = v4;
+        v7 = uNumXTiles + 1;
+        v10 = uNumXTiles + 1;
+        do
+            {
+            uNumXTilesa = a2a - v13;
+            if ( v7 > 0 )
+                {
+                v12 = v7;
+                do
+                    {
+                    uNumXTilesa += v13;
+                    pRenderer->DrawTextureIndexed(uNumXTilesa, v21, v5);
+                    --v12;
+                    }
+                    while ( v12 );
+                    v7 = v10;
+                }
+            v21 += uTileHeight;
+            v8 = a5++;
+            }
+            while ( v8 < (signed int)uHeight / uTileHeight );
+            a5a = v4 + uHeight - 32;
+            pRenderer->DrawTextureTransparent(a2a, v4, pIcons_LOD->GetTexture(uTextureID_5076AC));
+            pRenderer->DrawTextureTransparent(a2a, a5a, pIcons_LOD->GetTexture(uTextureID_5076B4));
+            pRenderer->DrawTextureTransparent(a4 - 32, v4, pIcons_LOD->GetTexture(uTextureID_5076A8));
+            pRenderer->DrawTextureTransparent(a4 - 32, a5a, pIcons_LOD->GetTexture(uTextureID_5076B0));
+            uNumXTilesb = a2a + 32;
+            v22 = v4 + uHeight - 10;
+            if ( (signed int)uWidth > 64 )
+                {
+                pRenderer->SetTextureClipRect(a2a + 32, v4, a4 - 32, v4 + uHeight);
+                pRenderer->DrawTextureTransparent(uNumXTilesb, v4, pIcons_LOD->GetTexture(uTextureID_507698));
+                pRenderer->DrawTextureTransparent(uNumXTilesb, v22, pIcons_LOD->GetTexture(uTextureID_5076A4));
+                if ( (signed int)uWidth > 512 )
+                    {
+                    pRenderer->DrawTextureTransparent(a2a + 544, v4, pIcons_LOD->GetTexture(uTextureID_507698));
+                    pRenderer->DrawTextureTransparent(a2a + 544, v22, pIcons_LOD->GetTexture(uTextureID_5076A4));
+                    }
+                }
+            v9 = v4 + 32;
+            if ( (signed int)uHeight > 64 )
+                {
+                pRenderer->SetTextureClipRect(a2a, v9, a4, a5a);
+                pRenderer->DrawTextureTransparent(a2a, v9, pIcons_LOD->GetTexture(uTextureID_5076A0));
+                pRenderer->DrawTextureTransparent(a4 - 10, v9, pIcons_LOD->GetTexture(uTextureID_50769C));
+                }
+            pRenderer->ResetTextureClipRect();
+        }
+    }
+
+
+
+//----- (0041D895) --------------------------------------------------------
+void GameUI_DrawItemInfo( struct ItemGen* inspect_item )
+    {
+    ItemGen *v1; // esi@1
+    unsigned int v2; // eax@3
+    //char *v3; // edi@5
+    //unsigned int v4; // eax@5
+    //unsigned int v5; // esi@5
+    signed int v6; // eax@5
+    int v7; // edx@5
+    //unsigned int v9; // eax@12
+    char v10; // zf@16
+    ItemGen *v11; // eax@16
+    ItemGen *v12; // eax@25
+    //unsigned int v13; // ecx@32
+    //unsigned int v14; // eax@32
+    //Render *v15; // edi@33
+    const char *v16; // eax@34
+    int v17; // eax@36
+    int v18; // esi@37
+    unsigned __int16 v19; // ax@37
+    //char v20; // al@40
+    char v21; // al@44
+    //char v22; // al@48
+    //char v23; // al@51
+    int v24; // eax@52
+    int v25; // eax@57
+    int v26; // eax@60
+    int v27; // eax@67
+    const char *v28; // edi@69
+    int v29; // eax@70
+    char v30; // edi@78
+    const char *v31; // eax@78
+    int v32; // ecx@81
+    unsigned int v33; // eax@81
+    int v34; // esi@81
+    const char *v35; // eax@85
+    const char *v36; // eax@87
+    unsigned int v37; // eax@109
+    unsigned int v38; // eax@109
+    int v39; // eax@113
+    GUIFont *v40; // edx@113
+    signed int v41; // [sp-20h] [bp-298h]@113
+    int v42; // [sp-1Ch] [bp-294h]@113
+    //char *v43; // [sp-18h] [bp-290h]@46
+    unsigned int v44; // [sp-18h] [bp-290h]@113
+    //int v45; // [sp-14h] [bp-28Ch]@46
+    const char *v46; // [sp-14h] [bp-28Ch]@58
+    char *v47; // [sp-14h] [bp-28Ch]@110
+    //char *v48; // [sp-10h] [bp-288h]@46
+    const char *v49; // [sp-10h] [bp-288h]@56
+    char *v50; // [sp-10h] [bp-288h]@58
+    int v51; // [sp-10h] [bp-288h]@110
+    const char *v52; // [sp-Ch] [bp-284h]@36
+    //int v53; // [sp-Ch] [bp-284h]@46
+    char *v54; // [sp-Ch] [bp-284h]@56
+    int v55; // [sp-Ch] [bp-284h]@58
+    int v56; // [sp-Ch] [bp-284h]@110
+    unsigned int v57; // [sp-8h] [bp-280h]@36
+    //int v58; // [sp-8h] [bp-280h]@46
+    int v59; // [sp-8h] [bp-280h]@56
+    int v60; // [sp-8h] [bp-280h]@58
+    unsigned int v61; // [sp-8h] [bp-280h]@110
+    char out_text[300]; // [sp+8h] [bp-270h]@40
+    //char Dest[100]; // [sp+6Ch] [bp-20Ch]@40
+    //char v64[100]; // [sp+D0h] [bp-1A8h]@40
+    char v65[120]; // [sp+134h] [bp-144h]@92
+    char Source[40]; // [sp+1ACh] [bp-CCh]@49
+    stru351_summoned_item v67;
+    //int v67; // [sp+1D4h] [bp-A4h]@91
+    //int v68; // [sp+1D8h] [bp-A0h]@106
+    //int v69; // [sp+1DCh] [bp-9Ch]@101
+    //int v70; // [sp+1E0h] [bp-98h]@97
+    //int v71; // [sp+1E8h] [bp-90h]@93
+    //int v72; // [sp+1ECh] [bp-8Ch]@91
+    int var88; // [sp+1F0h] [bp-88h]@1
+    Texture *v73; // [sp+1F4h] [bp-84h]@5
+    //unsigned int v75; // [sp+1F8h] [bp-80h]@5
+    //char *v76; // [sp+1FCh] [bp-7Ch]@5
+    int v77; // [sp+200h] [bp-78h]@12
+    int v78; // [sp+204h] [bp-74h]@5
+    GUIWindow wHintWindow; // [sp+208h] [bp-70h]@2
+    POINT a2; // [sp+25Ch] [bp-1Ch]@2
+    int v81; // [sp+264h] [bp-14h]@5
+    // GUIFont *pFontComic; // [sp+268h] [bp-10h]@1
+    PlayerSpeech v83; // [sp+26Ch] [bp-Ch]@18
+    char* v84;
+    int v85;
+    char *Str; // [sp+270h] [bp-8h]@65
+
+    v1 = inspect_item;
+    var88 = TargetColor(0xFFu, 0xFFu, 0x9Bu);
+    if (!inspect_item->uItemID)
+        return;
+
+    wHintWindow.Hint = 0;
+    wHintWindow.uFrameWidth = 384;
+    wHintWindow.uFrameHeight = 180;
+    wHintWindow.uFrameY = 40;
+    if ( pMouse->GetCursorPos(&a2)->x <= 320 )
+        v2 = pMouse->GetCursorPos(&a2)->x + 30;
+    else
+        v2 = pMouse->GetCursorPos(&a2)->x - wHintWindow.uFrameWidth - 30;
+    wHintWindow.uFrameX = v2;
+    auto item_desc = &pItemsTable->pItems[inspect_item->uItemID];
+    //v3 = (char *)&pItemsTable->pItems[_this->uItemID].pIconName;
+    //v76 = v3;
+    //v4 = pIcons_LOD->LoadTexture(pItemsTable->pItems[_this->uItemID].pIconName, TEXTURE_16BIT_PALETTE);
+    //v5 = v4;
+    //v4 *= 72;
+    //v75 = v4;
+    //v73 = &pIcons_LOD->pTextures[v4];
+    v73 = pIcons_LOD->LoadTexturePtr(item_desc->pIconName, TEXTURE_16BIT_PALETTE);
+    v6 = 100 - v73->uTextureWidth;
+    v7 = v73->uTextureHeight;
+    v78 = v6;
+    v81 = 144 - v7;
+    if ( v6 > 0 )
+        v78 = v6 >> 1;
+    if ( v81 <= 0 )
+        v81 = 0;
+    else
+        v81 >>= 1;
+    if ( !item_desc->uItemID_Rep_St )
+        inspect_item->SetIdentified();
+    //v9 = v8->uAttributes;
+    v77 = 0;
+    //a2.y = v8->uAttributes & 2;
+    if (pItemsTable->pItems[inspect_item->uItemID].uEquipType == EQUIP_GOLD)
+        v77 = inspect_item->uSpecEnchantmentType;
+    if ( uActiveCharacter )
+        {
+        //try to identify
+        if (!inspect_item->Identified())
+            {
+
+            v11 = inspect_item;
+            if ( pPlayers[uActiveCharacter]->CanIdentify(inspect_item) == 1 )
+                inspect_item->SetIdentified();
+            v83 = SPEECH_9;
+            if ( !inspect_item->Identified() )
+                {
+                ShowStatusBarString(pGlobalTXT_LocalizationStrings[446], 2u);//"Identify Failed"
+                }
+            else
+                {
+                v83 = SPEECH_8;
+                if ( inspect_item->GetValue() < 100 * (pPlayers[uActiveCharacter]->uLevel + 5) )
+                    v83 = SPEECH_7;
+                }
+            if ( dword_4E455C )
+                {
+                pPlayers[uActiveCharacter]->PlaySound((PlayerSpeech)(int)v83, 0);
+                dword_4E455C = 0;
+                }
+            }
+        inspect_item->UpdateTempBonus(pParty->uTimePlayed);
+        if (inspect_item->Broken())
+            {
+            if ( pPlayers[uActiveCharacter]->CanRepair(inspect_item) == 1 )
+                inspect_item->uAttributes = inspect_item->uAttributes & 0xFFFFFFFD | 1;
+            v83 = SPEECH_11;
+            if ( !inspect_item->Broken() )
+                v83 = SPEECH_10;
+            else
+                ShowStatusBarString(pGlobalTXT_LocalizationStrings[448], 2u);//"Repair Failed"
+            if ( dword_4E455C )
+                {
+                pPlayers[uActiveCharacter]->PlaySound(v83, 0);
+                dword_4E455C = 0;
+                }
+            }
+        }
+    //v13 = _this->uAttributes;
+    //v14 = _this->Identified();
+    //a2.y = inspect_item->Identified();
+    if (inspect_item->Broken())
+        {
+        wHintWindow.DrawMessageBox(0);
+        //v15 = &;
+        pRenderer->SetTextureClipRect(wHintWindow.uFrameX + 12, wHintWindow.uFrameY + 12,
+            wHintWindow.uFrameX + wHintWindow.uFrameWidth - 12, 
+            wHintWindow.uFrameY + wHintWindow.uFrameHeight - 12);
+        wHintWindow.uFrameWidth -= 24;
+        wHintWindow.uFrameHeight -= 12;
+        wHintWindow.uFrameZ = wHintWindow.uFrameX + wHintWindow.uFrameWidth - 1;
+        wHintWindow.uFrameW = wHintWindow.uFrameY + wHintWindow.uFrameHeight - 1;
+        pRenderer->DrawTransparentRedShade(wHintWindow.uFrameX + v78, v81 + wHintWindow.uFrameY + 30, v73);
+        if ( inspect_item->Identified())
+            v16 = inspect_item->GetIdentifiedName();
+        else
+            v16 = item_desc->pUnidentifiedName;
+        wHintWindow.DrawTitleText(pFontArrus, 0, 0xCu, var88, v16, 3u);
+        v17 = pFontArrus->CalcTextHeight(pGlobalTXT_LocalizationStrings[32], &wHintWindow, 0, 0); //"Broken Item"
+        v18 = v17 >> 1;
+        v19 = TargetColor(0xFFu, 0x19u, 0x19u);
+        wHintWindow.DrawTitleText(pFontArrus, 0x64u, ((signed int)wHintWindow.uFrameHeight >> 1) - v18, v19, pGlobalTXT_LocalizationStrings[32], 3); //"Broken Item"
+        pRenderer->ResetTextureClipRect();
+        if ( !areWeLoadingTexture )
+            {
+            v73->Release();
+            pIcons_LOD->SyncLoadedFilesCount();
+            }
+        return;
+        }
+    if (!inspect_item->Identified())
+        {
+        wHintWindow.DrawMessageBox(0);
+        pRenderer->SetTextureClipRect(wHintWindow.uFrameX + 12,  wHintWindow.uFrameY + 12,
+            wHintWindow.uFrameX + wHintWindow.uFrameWidth - 12, 
+            wHintWindow.uFrameY + wHintWindow.uFrameHeight - 12);
+        wHintWindow.uFrameWidth -= 24;
+        wHintWindow.uFrameHeight -= 12;
+        wHintWindow.uFrameZ = wHintWindow.uFrameX + wHintWindow.uFrameWidth - 1;
+        wHintWindow.uFrameW = wHintWindow.uFrameY + wHintWindow.uFrameHeight - 1;
+        pRenderer->DrawTextureTransparent(wHintWindow.uFrameX + v78, v81 + wHintWindow.uFrameY + 30, v73);
+        wHintWindow.DrawTitleText(pFontArrus, 0, 0xCu, var88, item_desc->pUnidentifiedName, 3u);
+        v17 = pFontArrus->CalcTextHeight(pGlobalTXT_LocalizationStrings[232], &wHintWindow, 0, 0); ///"Not Identified"
+        v18 = v17 >> 1;
+        v19 = TargetColor(0xFFu, 0x19u, 0x19u);
+        wHintWindow.DrawTitleText(pFontArrus, 0x64u, ((signed int)wHintWindow.uFrameHeight >> 1) - v18, v19, pGlobalTXT_LocalizationStrings[232], 3);
+        pRenderer->ResetTextureClipRect();
+        if ( !areWeLoadingTexture )
+            {
+            v73->Release();
+            pIcons_LOD->SyncLoadedFilesCount();
+            }
+        return;
+        }
+
+    sprintfex(out_text, pGlobalTXT_LocalizationStrings[463], item_desc->pUnidentifiedName); //"Type: %s"
+    out_text[100] = 0;
+    out_text[200] = 0;
+    //v20 = item_desc->uEquipType;
+    switch (item_desc->uEquipType)
+        {
+    case EQUIP_OFF_HAND:
+    case EQUIP_MAIN_HAND:
+        sprintfex(out_text + 100, "%s: +%d   %s: %dd%d", pGlobalTXT_LocalizationStrings[LOCSTR_ATTACK],
+            (int)item_desc->uDamageMod, pGlobalTXT_LocalizationStrings[53], (int)item_desc->uDamageDice, (int)item_desc->uDamageRoll); //"Damage"
+        if (item_desc->uDamageMod)
+            {
+            char mod[16];
+            sprintf(mod, "+%d", (int)item_desc->uDamageMod);
+            strcat(out_text + 100, mod);
+            }
+        break;
+
+    case EQUIP_BOW:
+        sprintfex(out_text + 100, "%s: +%d   %s: %dd%d", pGlobalTXT_LocalizationStrings[203], //"Shoot"
+            (int)item_desc->uDamageMod, pGlobalTXT_LocalizationStrings[53], //"Damage"
+            (int)item_desc->uDamageDice, (int)item_desc->uDamageRoll);
+        if (item_desc->uDamageMod)
+            {
+            char mod[16];
+            sprintf(mod, "+%d", (int)item_desc->uDamageMod);
+            strcat(out_text + 100, mod);
+            }
+        break;
+
+    case EQUIP_ARMOUR:
+    case EQUIP_SHIELD:
+    case EQUIP_HELMET:
+    case EQUIP_BELT:
+    case EQUIP_CLOAK:
+    case EQUIP_GAUNTLETS:
+    case EQUIP_BOOTS:
+    case EQUIP_RING:
+    case EQUIP_AMULET:
+        if (item_desc->uDamageDice) //"Armor"	
+            sprintfex(out_text + 100, "%s: +%d", pGlobalTXT_LocalizationStrings[11], item_desc->uDamageDice + item_desc->uDamageMod);
+        break;
+
+        }
+
+    if ( !v77 )
+        {
+        if (item_desc->uEquipType ==EQUIP_POTION)  //this is CORRECT! do not move to switch!
+            {
+            if ( inspect_item->uEnchantmentType )
+                sprintf(out_text + 200,  "%s: %d",pGlobalTXT_LocalizationStrings[449] , inspect_item->uEnchantmentType); //"Power"
+            }
+        else if (item_desc->uEquipType == EQUIP_REAGENT)
+            {
+            sprintf(out_text + 200, "%s: %d", pGlobalTXT_LocalizationStrings[449], pItemsTable->pItems[inspect_item->uItemID].uDamageDice); //"Power"
+            }
+
+        else if ( inspect_item->uEnchantmentType )
+            {
+            sprintf(out_text + 200, "%s: %s +%d", pGlobalTXT_LocalizationStrings[210],
+                pItemsTable->pEnchantments[inspect_item->uEnchantmentType-1].pBonusStat, inspect_item->_bonus_strength); //"Special"
+            }
+        else  if ( inspect_item->uSpecEnchantmentType )
+            {      
+            sprintf(out_text + 200, "%s: %s", pGlobalTXT_LocalizationStrings[210], 
+                pItemsTable->pSpecialEnchantments[inspect_item->uSpecEnchantmentType-1].pBonusStatement, inspect_item->_bonus_strength);
+            }
+
+        else if ( inspect_item->uNumCharges )
+            {
+            sprintf(out_text + 200, "%s: %lu", pGlobalTXT_LocalizationStrings[464], inspect_item->uNumCharges); //"Charges"
+
+            }
+        }
+    wHintWindow.uFrameWidth -= 12;
+    v85 = 3;
+    wHintWindow.uFrameZ = wHintWindow.uFrameX + wHintWindow.uFrameWidth - 1;
+    wHintWindow.uFrameW = wHintWindow.uFrameY + wHintWindow.uFrameHeight - 1;
+    Str = (char *)(3 * (LOBYTE(pFontArrus->uFontHeight) + 8));
+    v84 = &out_text[0];
+    do
+        {
+        if ( *v84 )
+            {
+            v27 = pFontComic->CalcTextHeight(v84, &wHintWindow, 100, 0);
+            Str += v27 + 3;
+            }
+        v84 += 100;
+        --v85;
+        }
+        while ( v85 );
+        v28 = item_desc->pDescription;
+        if ( *v28 )
+            {
+            v29 = pFontSmallnum->CalcTextHeight(v28, &wHintWindow, 100, 0);
+            Str += v29;
+            }
+        wHintWindow.uFrameHeight = v73->uTextureHeight + v81 + 54;
+        if ( (signed int)Str > (signed int)wHintWindow.uFrameHeight )
+            wHintWindow.uFrameHeight = (unsigned int)Str;
+        if ( inspect_item->uAttributes & 8 && (inspect_item->uSpecEnchantmentType || inspect_item->uEnchantmentType) )
+            wHintWindow.uFrameHeight += LOBYTE(pFontComic->uFontHeight);
+        v85 = 0;
+        if ( pFontArrus->uFontHeight )
+            {
+            wHintWindow.uFrameWidth -= 24;
+            v30 = pFontArrus->uFontHeight;
+            v31 = inspect_item->GetIdentifiedName();
+            if ( pFontArrus->CalcTextHeight(v31, &wHintWindow, 0, 0) / (signed int)v30 )
+                v85 = v30;
+            wHintWindow.uFrameWidth += 24;
+            }
+        wHintWindow.uFrameWidth += 12;
+        wHintWindow.uFrameHeight += (unsigned int)v85;
+        wHintWindow.uFrameW = wHintWindow.uFrameY + wHintWindow.uFrameHeight - 1;
+        wHintWindow.uFrameZ = wHintWindow.uFrameX + wHintWindow.uFrameWidth - 1;
+        wHintWindow.DrawMessageBox(0);
+        //v15 = pRenderer;
+        pRenderer->SetTextureClipRect(wHintWindow.uFrameX + 12, wHintWindow.uFrameY + 12,
+            wHintWindow.uFrameX + wHintWindow.uFrameWidth - 12, wHintWindow.uFrameY + wHintWindow.uFrameHeight - 12);
+        wHintWindow.uFrameWidth -= 12;
+        v32 = v73->uTextureHeight;
+        v33 = wHintWindow.uFrameHeight;
+        wHintWindow.uFrameHeight -= 12;
+        wHintWindow.uFrameZ = wHintWindow.uFrameX + wHintWindow.uFrameWidth - 1;
+        wHintWindow.uFrameW = wHintWindow.uFrameY + wHintWindow.uFrameHeight - 1;
+        pRenderer->DrawTextureTransparent(
+            wHintWindow.uFrameX + v78,
+            wHintWindow.uFrameY + (signed int)(v33 - v32) / 2,
+            v73);
+
+        v34 = (int)(v85 + 35);
+        v85 = 3;
+        Str = out_text;
+        do
+            {
+            if ( *Str )
+                {
+                wHintWindow.DrawText(pFontComic, 100, v34, 0, Str, 0, 0, 0);
+                v34 += pFontComic->CalcTextHeight(Str, &wHintWindow, 100, 0) + 3;
+                }
+            Str += 100;
+            --v85;
+            }
+            while (v85 );
+            v35 = item_desc->pDescription;
+            if ( *v35 )
+                wHintWindow.DrawText(pFontSmallnum, 100, v34, 0, v35, 0, 0, 0);
+            wHintWindow.uFrameX += 12;
+            wHintWindow.uFrameWidth -= 24;
+            v36 = inspect_item->GetIdentifiedName();
+            wHintWindow.DrawTitleText(pFontArrus, 0, 0xCu, var88, v36, 3u);
+            wHintWindow.uFrameWidth += 24;
+            wHintWindow.uFrameX -= 12;
+            if ( v77 )
+                {
+                sprintf(pTmpBuf.data(), "%s: %lu", pGlobalTXT_LocalizationStrings[465], v77);//"Value"
+                v40 = pFontComic;
+                v61 = 0;
+                v56 = 0;
+                v51 = 0;
+                v47 = pTmpBuf.data();
+                v44 = 0;
+                v42 = wHintWindow.uFrameHeight - LOBYTE(pFontComic->uFontHeight);
+                v41 = 100;
+                }
+            else
+                {
+                if ( (inspect_item->uAttributes & 8) && (inspect_item->uSpecEnchantmentType || inspect_item->uEnchantmentType) )
+                    {
+                    sub_493F79(&v67, inspect_item->uExpireTime - pParty->uTimePlayed);
+                    strcpy(pTmpBuf.data(), "Duration:");
+                    Str = (char *)(v67.field_18_expire_year - game_starting_year);
+                    if (v67.field_18_expire_year != 1168 )
+                        {
+                        sprintf(v65, " %d:yr", v67.field_18_expire_year - game_starting_year);
+                        strcat(pTmpBuf.data(), v65);
+                        }
+                    if ( (((v67.field_14_exprie_month || Str) && 
+                        ((sprintf(v65, " %d:mo", v67.field_14_exprie_month), strcat(pTmpBuf.data(), v65), v67.field_14_exprie_month) || Str) 
+                        || v67.field_C_expire_day)
+                        && ((sprintf(v65, " %d:dy", v67.field_C_expire_day), strcat(pTmpBuf.data(), v65), v67.field_14_exprie_month) || Str || 
+                        v67.field_C_expire_day)
+                        || v67.field_8_expire_hour)
+                        && ((sprintf(v65, " %d:hr", v67.field_8_expire_hour), strcat(pTmpBuf.data(), v65), v67.field_14_exprie_month) || Str || 
+                        v67.field_C_expire_day || v67.field_8_expire_hour)
+                        || v67.field_4_expire_minute )
+                        {
+                        sprintf(v65, " %d:mn", v67.field_4_expire_minute);
+                        strcat(pTmpBuf.data(), v65);
+                        }
+                    wHintWindow.DrawText(pFontComic, 100, wHintWindow.uFrameHeight - 2 * LOBYTE(pFontComic->uFontHeight), 0, pTmpBuf.data(), 0, 0, 0);
+                    }
+                v37 = inspect_item->GetValue();
+                sprintf(pTmpBuf.data(), "%s: %lu", pGlobalTXT_LocalizationStrings[465], v37);
+                wHintWindow.DrawText(pFontComic, 100, wHintWindow.uFrameHeight - LOBYTE(pFontComic->uFontHeight), 0, pTmpBuf.data(), 0, 0, 0);
+                v38 = inspect_item->uAttributes;
+                if ( BYTE1(v38) & 1 )
+                    {
+                    v61 = 0;
+                    v56 = 0;
+                    v51 = 0;
+                    v47 = pGlobalTXT_LocalizationStrings[187]; //"Stolen"
+                    }
+                else
+                    {
+                    if ( !(BYTE1(v38) & 2) )
+                        {
+                        pRenderer->ResetTextureClipRect();
+                        if ( !areWeLoadingTexture )
+                            {
+                            v73->Release();
+                            pIcons_LOD->SyncLoadedFilesCount();
+                            }
+                        return;
+                        }
+                    v61 = 0;
+                    v56 = 0;
+                    v51 = 0;
+                    v47 = pGlobalTXT_LocalizationStrings[651]; //"Hardened"
+                    }
+                LOWORD(v38) = LOWORD(pRenderer->uTargetRMask);
+                v44 = v38;
+                v42 = wHintWindow.uFrameHeight - LOBYTE(pFontComic->uFontHeight);
+                v39 = pFontComic->GetLineWidth(pTmpBuf.data());
+                v40 = pFontComic;
+                v41 = v39 + 132;
+                }
+            wHintWindow.DrawText(v40, v41, v42, v44, v47, v51, v56, v61);
+            pRenderer->ResetTextureClipRect();
+            if ( !areWeLoadingTexture )
+                {
+                v73->Release();
+                pIcons_LOD->SyncLoadedFilesCount();
+                }
+            return;
+    }
+// 4E455C: using guessed type int dword_4E455C;
+// 506128: using guessed type int areWeLoadingTexture;
+
+
+
+//----- (0041E360) --------------------------------------------------------
+void MonsterPopup_Draw(unsigned int uActorID, GUIWindow *edx0)
+{
+  unsigned int v2; // esi@1
+  Actor *v3; // esi@3
+  int v4; // eax@3
+  //unsigned int v5; // ecx@3
+  NPCData *v6; // eax@3
+  unsigned __int16 v7; // cx@3
+  int v8; // eax@4
+  unsigned __int16 v9; // dx@4
+  SpriteFrame *v10; // edi@17
+  LODSprite *v11; // esi@17
+  unsigned int v12; // ecx@17
+  Sprite *v13; // edi@18
+  //int v14; // ecx@18
+  //int v15; // edx@18
+  //int v16; // edx@18
+  //int v17; // eax@18
+  unsigned int v18; // ecx@19
+  unsigned int v19; // eax@21
+  char *v20; // esi@28
+  int v21; // edx@29
+  unsigned __int16 *v22; // ecx@29
+  int v23; // eax@29
+  int v24; // eax@32
+  int v25; // esi@32
+  char *v26; // edx@34
+  unsigned __int8 v27; // sf@36
+  unsigned __int8 v28; // of@36
+  //int v29; // esi@40
+  //unsigned __int16 *v30; // ecx@40
+  //int v31; // eax@40
+  //int v32; // esi@43
+  //unsigned __int16 v33; // ax@45
+  //int v34; // edx@45
+  //int v35; // eax@45
+  int v36; // eax@49
+  //char *v37; // eax@52
+  int v38; // eax@55
+  unsigned __int16 v39; // ax@59
+  SpellBuff *v40; // eax@60
+  int v41; // edi@61
+  unsigned int v42; // eax@61
+  int v43; // eax@62
+  int v44; // eax@63
+  signed int v45; // edi@65
+  unsigned __int16 v46; // ax@73
+  Player *v47; // ecx@77
+  //unsigned int v48; // eax@85
+  GUIFont *v49; // edi@90
+  int v50; // edi@90
+  SpellBuff *v51; // eax@91
+  char *v52; // ecx@98
+  char *v53; // ecx@101
+  char *v54; // ST0C_4@118
+  unsigned int v55; // eax@118
+  GUIFont *v56; // edi@124
+  unsigned __int8 v57; // al@128
+  int v58; // eax@132
+  Actor *v59; // ecx@133
+  unsigned __int8 v60; // dl@138
+  char *v62; // eax@147
+  int v63; // eax@152
+  //char *result; // eax@152
+  int v65; // eax@155
+  const char *v66; // [sp-10h] [bp-1FCh]@121
+  const char *v67; // [sp-10h] [bp-1FCh]@125
+  const char *v68; // [sp-10h] [bp-1FCh]@142
+  int v69; // [sp-Ch] [bp-1F8h]@121
+  char *v70; // [sp-Ch] [bp-1F8h]@125
+  char *v71; // [sp-Ch] [bp-1F8h]@142
+  char *v72; // [sp-8h] [bp-1F4h]@54
+  int v73; // [sp-8h] [bp-1F4h]@79
+  int v74; // [sp-8h] [bp-1F4h]@121
+  int v75; // [sp-8h] [bp-1F4h]@125
+  int v76; // [sp-8h] [bp-1F4h]@142
+  size_t v77; // [sp-4h] [bp-1F0h]@54
+  unsigned int v78; // [sp-4h] [bp-1F0h]@121
+  unsigned int v79; // [sp-4h] [bp-1F0h]@125
+  char *v80; // [sp-4h] [bp-1F0h]@142
+  char *v81; // [sp-4h] [bp-1F0h]@148
+  DDBLTFX Dst; // [sp+Ch] [bp-1E0h]@18
+  DDSURFACEDESC2 pDesc; // [sp+70h] [bp-17Ch]@18
+  RECT v84; // [sp+ECh] [bp-100h]@26
+  char *v85[10]; // [sp+FCh] [bp-F0h]@145
+  char *v95[11]; // [sp+124h] [bp-C8h]@127
+  RenderBillboardTransform_local0 v106; // [sp+150h] [bp-9Ch]@3
+  unsigned int v107; // [sp+1A0h] [bp-4Ch]@18
+  unsigned __int16 *v108; // [sp+1A4h] [bp-48h]@34
+  unsigned int v109; // [sp+1A8h] [bp-44h]@32
+  LPVOID v110; // [sp+1ACh] [bp-40h]@28
+  unsigned int v111; // [sp+1B0h] [bp-3Ch]@29
+  int v112; // [sp+1B4h] [bp-38h]@3
+  int v222; // [sp+1B8h] [bp-34h]@18
+  unsigned __int8 v114; // [sp+1BFh] [bp-2Dh]@133
+  int v115; // [sp+1C0h] [bp-2Ch]@3
+  unsigned int v116; // [sp+1C4h] [bp-28h]@18
+  int i; // [sp+1C8h] [bp-24h]@18
+  int a2; // [sp+1CCh] [bp-20h]@28
+  int v119; // [sp+1D0h] [bp-1Ch]@18
+  SpellBuff *v120; // [sp+1D4h] [bp-18h]@18
+  Actor *v121; // [sp+1D8h] [bp-14h]@3
+  int a5; // [sp+1DCh] [bp-10h]@3
+  GUIWindow *a1; // [sp+1E0h] [bp-Ch]@1
+  int v124; // [sp+1E4h] [bp-8h]@18
+  int a4; // [sp+1E8h] [bp-4h]@18
+
+  a1 = edx0;
+  v2 = uActorID;
+
+  static Actor pMonsterInfoUI_Doll;
+  /*if ( !(bMonsterInfoUI_bDollInitialized & 1) )
+  {
+    bMonsterInfoUI_bDollInitialized |= 1u;
+    Actor::Actor(&pMonsterInfoUI_Doll);
+    atexit(nullsub_3);
+  }*/
+  v106.uParentBillboardID = -1;
+  v3 = &pActors[v2];
+  v121 = v3;
+  v4 = TargetColor(0xE1u, 255, 0x9Bu);
+  //v5 = v3->sNPC_ID;
+  a5 = v4;
+  v6 = GetNPCData(v3->sNPC_ID);
+  v7 = v3->pMonsterInfo.uID;
+  //v112 = (char **)v6;
+  v115 = monster_popup_y_offsets[((signed __int16)v7 - 1) / 3] - 40;
+  if ( v7 == pMonsterInfoUI_Doll.pMonsterInfo.uID )
+  {
+    v9 = pMonsterInfoUI_Doll.uCurrentActionLength;
+  }
+  else
+  {
+    memcpy(&pMonsterInfoUI_Doll, v3, sizeof(pMonsterInfoUI_Doll));
+    pMonsterInfoUI_Doll.uCurrentActionAnimation = ANIM_Bored;
+    pMonsterInfoUI_Doll.uCurrentActionTime = 0;
+    v8 = rand();
+    v3 = v121;
+    v9 = v8 % 256 + 128;
+    pMonsterInfoUI_Doll.uCurrentActionLength = v8 % 256 + 128;
+  }
+
+  if ( (signed int)pMonsterInfoUI_Doll.uCurrentActionTime > (signed __int16)v9 )
+  {
+    pMonsterInfoUI_Doll.uCurrentActionTime = 0;
+    if ( pMonsterInfoUI_Doll.uCurrentActionAnimation == ANIM_Bored || pMonsterInfoUI_Doll.uCurrentActionAnimation == ANIM_AtkMelee)
+    {
+      pMonsterInfoUI_Doll.uCurrentActionAnimation = ANIM_Standing;
+      pMonsterInfoUI_Doll.uCurrentActionLength = rand() % 128 + 128;
+    }
+    else
+    {
+      //rand();
+      pMonsterInfoUI_Doll.uCurrentActionAnimation = ANIM_Bored;
+      if ( (pMonsterInfoUI_Doll.pMonsterInfo.uID < 115 || pMonsterInfoUI_Doll.pMonsterInfo.uID > 186) &&
+           (pMonsterInfoUI_Doll.pMonsterInfo.uID < 232 || pMonsterInfoUI_Doll.pMonsterInfo.uID > 249) && rand() % 30 < 100 )
+        pMonsterInfoUI_Doll.uCurrentActionAnimation = ANIM_AtkMelee;
+      pMonsterInfoUI_Doll.uCurrentActionLength = 8 * pSpriteFrameTable->pSpriteSFrames[v3->pSpriteIDs[(signed __int16)pMonsterInfoUI_Doll.uCurrentActionAnimation]].uAnimLength;
+    }
+  }
+  v10 = pSpriteFrameTable->GetFrame( v3->pSpriteIDs[pMonsterInfoUI_Doll.uCurrentActionAnimation], pMonsterInfoUI_Doll.uCurrentActionTime);
+  v11 = &pSprites_LOD->pSpriteHeaders[v10->pHwSpriteIDs[0]];//40 * v10->pHwSpriteIDs[0] + 7218180;
+  v106.pTarget = pRenderer->pTargetSurface;
+  v106.pTargetZ = pRenderer->pActiveZBuffer;
+  v106.uTargetPitch = pRenderer->uTargetSurfacePitch;
+  v12 = a1->uFrameY + 52;
+  v106.uViewportX = a1->uFrameX + 13;
+  v106.uViewportY = v12;
+  v106.uViewportW = v12 + 128;
+  v106.uViewportZ = v106.uViewportX + 128;
+  v106.uScreenSpaceX = (signed int)(v106.uViewportX + 128 + v106.uViewportX) / 2;
+  v106._screenspace_x_scaler_packedfloat = 65536;
+  v106._screenspace_y_scaler_packedfloat = 65536;
+  v106.uScreenSpaceY = v115 + v12 + v11->uHeight;
+  v106.pPalette = PaletteManager::Get_Dark_or_Red_LUT(v10->uPaletteIndex, 0, 1);
+  v106.sZValue = 0;
+  v106.uFlags = 0;
+  pRenderer->SetRasterClipRect(0, 0, 0x27Fu, 0x1DFu);
+  pRenderer->RasterLine2D(v106.uViewportX - 1, v106.uViewportY - 1, v106.uViewportX + 129, v106.uViewportY - 1, a5);
+  pRenderer->RasterLine2D( v106.uViewportX + 129,  v106.uViewportY - 1,  v106.uViewportX + 129,    v106.uViewportW + 1,    a5);
+  pRenderer->RasterLine2D(v106.uViewportX + 129, v106.uViewportW + 1, v106.uViewportX - 1, v106.uViewportW + 1, a5);
+  pRenderer->RasterLine2D(v106.uViewportX - 1, v106.uViewportW + 1, v106.uViewportX - 1, v106.uViewportY - 1, a5);
+  if ( pRenderer->pRenderD3D )
+  {
+    v13 = &pSprites_LOD->pHardwareSprites[v10->pHwSpriteIDs[0]];
+    v106.uScreenSpaceY = v115 + v106.uViewportY + v13->uBufferHeight;
+    //v222 = (IDirectDrawSurface *)v13->pTextureSurface;
+    memset(&Dst, 0, 0x64u);
+    Dst.dwSize = 100;
+    Dst.dwFillColor = 0;
+    memset(&pDesc, 0, 0x7Cu);
+    pDesc.dwSize = 124;
+    v13->pTextureSurface->GetSurfaceDesc(&pDesc);
+    //v14 = v13->uBufferHeight;
+    //v120 = (SpellBuff *)v13->uBufferWidth;
+    v107 = 0;
+    //v15 = v13->uAreaX;
+    //v119 = v13->uBufferWidth / 2;
+    i = 0;
+    //a4 = v106.uScreenSpaceX + v15 - v13->uBufferWidth / 2;
+    int dst_x = v106.uScreenSpaceX + v13->uAreaX - v13->uBufferWidth / 2;
+    //v115 = v13->uAreaY;
+    //v16 = v13->uAreaWidth + v13->uBufferWidth / 2 + v13->uAreaX - v13->uBufferWidth;
+    //v124 = v106.uScreenSpaceY + v115 - v14;
+    int dst_y = v106.uScreenSpaceY + v13->uAreaY - v13->uBufferHeight;
+    //v17 = v13->uAreaHeight + v13->uAreaY - v14;
+    //v116 = v106.uScreenSpaceX + v16;
+    uint dst_z = v106.uScreenSpaceX + v13->uAreaX + v13->uAreaWidth + v13->uBufferWidth / 2 - v13->uBufferWidth;
+    //v119 = v106.uScreenSpaceY + v17;
+    uint dst_w = v106.uScreenSpaceY + v13->uAreaY + v13->uAreaHeight - v13->uBufferHeight;
+    if (dst_x < v106.uViewportX)
+    {
+      v18 = v106.uViewportX - dst_x;
+      dst_x = v106.uViewportX;
+      v107 = v18;
+    }
+    if (dst_y < v106.uViewportY)
+    {
+      v19 = v106.uViewportY - dst_y;
+      dst_y = v106.uViewportY;
+      i = v19;
+    }
+    if (dst_z > v106.uViewportZ)
+      dst_z = v106.uViewportZ;
+    if (dst_w > v106.uViewportW)
+      dst_w = v106.uViewportW;
+    pRenderer->FillRectFast(v106.uViewportX, v106.uViewportY, v106.uViewportZ - v106.uViewportX, v106.uViewportW - v106.uViewportY, pRenderer->uTargetBMask | pRenderer->uTargetGMask);
+    pRenderer->FillRectFast(v106.uViewportX, v106.uViewportY, v106.uViewportZ - v106.uViewportX, v106.uViewportW - v106.uViewportY, pRenderer->uTargetBMask | pRenderer->uTargetGMask);
+    v84.left = v106.uViewportX;
+    v84.top = v106.uViewportY;
+    v84.right = v106.uViewportZ;
+    v84.bottom = v106.uViewportW;
+    ErrD3D(pRenderer->pBackBuffer4->Blt(&v84, 0, 0, 16778240u, &Dst));
+    if ( pRenderer->uTargetGBits == 5 )
+    {
+      __debugbreak(); // no monster popup for r5g5b5 yet
+      memset(&pDesc, 0, 0x7Cu);
+      pDesc.dwSize = 124;
+      if ( pRenderer->LockSurface_DDraw4(v13->pTextureSurface, &pDesc, DDLOCK_WAIT))
+	  {
+		  v20 = (char *)dst_y;
+		  v110 = pDesc.lpSurface;
+		  a2 = dst_y;
+		  if (dst_y < dst_w)
+		  {
+			//v111 = 2 * pRenderer->uTargetSurfacePitch;
+			v21 = dst_x;
+			v22 = &pRenderer->pTargetSurface[dst_y * pRenderer->uTargetSurfacePitch + dst_x];
+            auto _v22_2 = v22;
+			v23 = i - dst_y;
+			//v120 = (SpellBuff *)&pRenderer->pTargetSurface[(int)&a4[v124 * pRenderer->uTargetSurfacePitch]];
+			v115 = i - dst_y;
+			while ( 1 )
+			{
+			  dst_y = v21;
+			  if ( v21 < dst_z )
+			  {
+				v24 = (int)&v20[v23];
+				v25 = v107 - v21;
+				v109 = v24;
+				for ( i = v107 - v21; ; v25 = i )
+				{
+				  v108 = (unsigned __int16 *)((pDesc.lPitch >> 1) * pDesc.dwHeight * v109 / v13->uAreaHeight);
+				  v26 = (char *)v108 + pDesc.dwWidth * (v25 + dst_y++) / v13->uAreaWidth;
+				  *v22 = *((short *)v110 + (int)v26);
+				  ++v22;
+				  if ( dst_y >= dst_z )
+					break;
+				}
+				v23 = v115;
+			  }
+			  v22 = (unsigned __int16 *)((char *)_v22_2 + 2 * pRenderer->uTargetSurfacePitch);
+              _v22_2 = v22;
+			  v20 = (char *)(a2 + 1);
+			  v28 = __OFSUB__(a2 + 1, dst_w);
+			  v27 = (signed int)(a2++ + 1 - dst_w) < 0;
+			  //a2 = (Player *)((char *)a2 + 1);
+			  //v120 = (SpellBuff *)((char *)v120 + v111);
+			  if ( !(v27 ^ v28) )
+				break;
+			  v21 = dst_x;
+			}
+		  }
+		  v13->pTextureSurface->Unlock(0);
+	  }
+    }
+	else
+	{
+		memset(&pDesc, 0, 0x7Cu);
+		pDesc.dwSize = 124;
+		if ( pRenderer->LockSurface_DDraw4(v13->pTextureSurface, &pDesc, DDLOCK_WAIT) )
+		{
+          auto src = (unsigned __int16 *)pDesc.lpSurface;
+
+          uint num_top_scanlines_above_frame_y = i - dst_y;
+          for (uint y = dst_y; y < dst_w; ++y)
+		  {
+            auto dst = &pRenderer->pTargetSurface[y * pRenderer->uTargetSurfacePitch + dst_x];
+
+            uint src_y = num_top_scanlines_above_frame_y + y;
+            for (uint x = dst_x; x < dst_z; ++x)
+            {
+              uint src_x  = v107 - dst_x + x; // num scanlines left to frame_x  + current x
+
+              uint idx = pDesc.dwHeight * src_y / v13->uAreaHeight * (pDesc.lPitch / sizeof(short)) +
+                         pDesc.dwWidth  * src_x / v13->uAreaWidth;
+              uint b = src[idx] & 0x1F;
+              *dst++ = b | 2 * (src[idx] & 0xFFE0);
+            }
+		  }
+		  v13->pTextureSurface->Unlock(0);
+		}
+	}
+  }
+  else
+  {
+    pRenderer->FillRectFast(v106.uViewportX, v106.uViewportY, v106.uViewportZ - v106.uViewportX, v106.uViewportW - v106.uViewportY, 0);
+    v36 = v10->pHwSpriteIDs[0];
+    if ( v36 >= 0 )
+      pSprites_LOD->pSpriteHeaders[v36].DrawSprite_sw(&v106, 0);
+  }
+
+  if ( v121->sNPC_ID )
+  {
+    //v37 = v6->uProfession;
+    if (v6->uProfession)
+    {
+      sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[429], v6->pName, aNPCProfessionNames[v6->uProfession]); // "%s the %s"   /   ^Pi[%s] %s
+    }
+	else
+	{
+	  v77 = 2000;
+      v72 = v6->pName;
+	}
+  }
+  else
+  {
+    v38 = v121->dword_000334_unique_name;
+    v77 = 2000;
+    if ( v38 )
+      v72 = pMonsterStats->pPlaceStrings[v38];
+    else
+      v72 = pMonsterStats->pInfos[v121->pMonsterInfo.uID].pName;
+  }
+  if(!v121->sNPC_ID || (v121->sNPC_ID && !v6->uProfession))
+    strncpy(pTmpBuf.data(), v72, v77);
+  v39 = TargetColor(0xFFu, 0xFFu, 0x9Bu);
+  a1->DrawTitleText(pFontComic, 0, 0xCu, v39, pTmpBuf.data(), 3u);
+  Actor::DrawHealthBar(v121, a1);
+  v119 = 0;
+  pMonsterInfoUI_Doll.uCurrentActionTime += pMiscTimer->uTimeElapsed;
+  v115 = 0;
+  v116 = 0;
+  i = 0;
+  v112 = 0;
+  if ( !uActiveCharacter )
+  {
+    v45 = 1;
+  }
+  else
+  {
+	  LOBYTE(v40) = pPlayers[uActiveCharacter]->GetActualSkillLevel(PLAYER_SKILL_MONSTER_ID);
+	  v120 = v40;
+	  if ( !v40 )
+		v45 = 1;
+	  else
+	  {
+		  v41 = (unsigned __int8)v40 & 0x3F;
+		  v42 = SkillToMastery((unsigned __int16)v40) - 1;
+		  if ( !v42 )
+		  {
+			if ( v41 + 10 >= v121->pMonsterInfo.uLevel )
+			{
+			  v45 = 1;
+			  v119 = 1;
+			}
+			else
+				v45 = 1;
+		  }
+		  else
+		  {
+			  v43 = v42 - 1;
+			  if ( !v43 )
+			  {
+				if ( 2 * v41 + 10 >= v121->pMonsterInfo.uLevel )
+				{
+				  v45 = 1;
+				  v119 = 1;
+				  v116 = 1;
+				}
+				else
+						v45 = 1;
+			  }
+			  else
+			  {
+				  v44 = v43 - 1;
+				  if ( !v44 )
+				  {
+					if ( 3 * v41 + 10 >= v121->pMonsterInfo.uLevel )
+					{
+					  v45 = 1;
+					  v119 = 1;
+					  v116 = 1;
+					  i = 1;
+					}
+					else
+					{
+						v45 = 1;
+					}
+				  }
+				  else
+				  {
+					  if ( v44 != 1 )
+						v45 = 1;
+					  else
+					  {
+						  v45 = 1;
+						  v119 = 1;
+						  v116 = 1;
+						  i = 1;
+						  v112 = 1;
+					  }
+				  }
+			  }
+		  }
+	  }
+	  //	LABEL_73:
+	  v46 = v121->uAIState;
+	  if ( v46 != 5 && v46 != 4 && !dword_507BF0_is_there_popup_onscreen && v120 )
+	  {
+		v47 = pPlayers[uActiveCharacter];
+		if ( v119 | v116 | i | (unsigned int)v112 )
+		{
+		  if ( v121->pMonsterInfo.uLevel >= v47->uLevel - 5 )
+			v73 = SPEECH_105;
+		  else
+			v73 = SPEECH_104;
+		}
+		else
+		{
+		  v73 = SPEECH_106;
+		}
+		v47->PlaySound((PlayerSpeech)v73, 0);
+	  }
+  }
+
+  for (uint _it = 0; _it < 4; ++_it)
+  {
+    auto player = pParty->pPlayers + _it;
+
+    //LOBYTE(v48) = player->GetActualSkillLevel(PLAYER_SKILL_MONSTER_ID);
+    //v111 = v48;
+    v111 = player->GetActualSkillLevel(PLAYER_SKILL_MONSTER_ID);
+    v120 = (SpellBuff *)138;
+    do
+    {
+      if ( (signed int)SkillToMastery(v111) >= 3 )
+        v115 = v45;
+      v120 = (SpellBuff *)((char *)v120 - 1);
+    }
+    while ( v120 );
+    //++a2;
+  }
+  //while ( (signed int)a2 < (signed int)pParty->pHirelings );
+
+  v49 = pFontSmallnum;
+  a2 = (int)pFontSmallnum;
+  a1->DrawText(pFontSmallnum, 12, 196, a5, pGlobalTXT_LocalizationStrings[631], 0, 0, 0);
+  v50 = LOBYTE(v49->uFontHeight) + 193;
+  if ( !v115 )
+  {
+    v78 = 0;
+    v74 = 0;
+    v69 = 0;
+    v66 = pGlobalTXT_LocalizationStrings[630];
+    a1->DrawText((GUIFont *)a2, 28, v50, a5, v66, v69, v74, v78);
+  }
+  else
+  {
+	  a4 = 0;
+	  v51 = &v121->pActorBuffs[1];
+	  v222 = 0;
+	  v120 = &v121->pActorBuffs[1];
+	  do
+	  {
+		if ( (signed __int64)v51->uExpireTime > 0 )
+		{
+		  switch ( (int)v51 )
+		  {
+			case 0u:
+			  v124 = 60;
+			  a4 = (int)pGlobalTXT_LocalizationStrings[591];
+			  break;
+			case 1u:
+			  v124 = 82;
+			  a4 = (int)pGlobalTXT_LocalizationStrings[649];
+			  break;
+			case 2u:
+			  v124 = 92;
+			  a4 = (int)pGlobalTXT_LocalizationStrings[592];
+			  break;
+			case 3u:
+			  v124 = 63;
+			  a4 = (int)pGlobalTXT_LocalizationStrings[4];
+			  break;
+			case 4u:
+			  v52 = pGlobalTXT_LocalizationStrings[220];
+			  a4 = (int)v52;
+			  v124 = 81;
+			  break;
+			case 5u:
+			  v52 = pGlobalTXT_LocalizationStrings[162];
+			  a4 = (int)v52;
+			  v124 = 81;
+			  break;
+			case 6u:
+			  v53 = pGlobalTXT_LocalizationStrings[593];
+			  v124 = 35;
+			  a4 = (int)v53;
+			  break;
+			case 8u:
+			  v53 = pGlobalTXT_LocalizationStrings[608];
+			  v124 = 62;
+			  a4 = (int)v53;
+			  break;
+			case 7u:
+			case 9u:
+			  a4 = 0;
+			  v124 = 0;
+			  ++v51;
+			  v222 = v222 + 1;
+			  v120 = v51;
+			  __debugbreak(); // fix condition
+			  continue;
+			case 0xAu:
+			  v124 = 47;
+			  a4 = (int)pGlobalTXT_LocalizationStrings[221];
+			  break;
+			case 0xBu:
+			  v124 = 66;
+			  a4 = (int)pGlobalTXT_LocalizationStrings[607];
+			  break;
+			case 0xCu:
+			  v124 = 85;
+			  a4 = (int)pGlobalTXT_LocalizationStrings[610];
+			  break;
+			case 0xDu:
+			  v124 = 86;
+			  a4 = (int)pGlobalTXT_LocalizationStrings[609];
+			  break;
+			case 0xEu:
+			  v124 = 17;
+			  a4 = (int)pGlobalTXT_LocalizationStrings[279];
+			  break;
+			case 0xFu:
+			  v124 = 38;
+			  a4 = (int)pGlobalTXT_LocalizationStrings[442];
+			  break;
+			case 0x10u:
+			  v124 = 46;
+			  a4 = (int)pGlobalTXT_LocalizationStrings[443];
+			  break;
+			case 0x11u:
+			  v124 = 51;
+			  a4 = (int)pGlobalTXT_LocalizationStrings[440];
+			  break;
+			case 0x12u:
+			  v124 = 5;
+			  a4 = (int)pGlobalTXT_LocalizationStrings[441];
+			  break;
+			case 0x13u:
+			  v124 = 95;
+			  a4 = (int)pGlobalTXT_LocalizationStrings[229];
+			  break;
+			case 0x14u:
+			  v124 = 73;
+			  a4 = (int)pGlobalTXT_LocalizationStrings[228];
+			  break;
+			default:
+			  a4 = 0;
+			  break;
+		  }
+		  if ( a4 )
+		  {
+			v54 = (char *)a4;
+			v55 = GetSpellColor(v124);
+			a1->DrawText((GUIFont *)a2, 28, v50, v55, v54, 0, 0, 0);
+			v50 = v50 + *(char *)(a2 + 5) - 3;
+			v51 = v120;
+		  }
+		}
+
+		++v51;
+		v222 = v222 + 1;
+		v120 = v51;
+
+		__debugbreak(); // fix condition
+	  }
+	  //while ( (signed int)((char *)&v222->lpVtbl + 1) < 22 );
+	  while (true);
+
+	  if ( !a4 )
+	  {
+		v78 = 0;
+		v74 = 0;
+		v69 = 0;
+		v66 = pGlobalTXT_LocalizationStrings[153];
+		a1->DrawText((GUIFont *)a2, 28, v50, a5, v66, v69, v74, v78);
+	  }
+  }
+  v56 = pFontSmallnum;
+  a4 = v106.uViewportY;
+  if ( v119 )
+  {
+    sprintf(pTmpBuf.data(), "%s\f%05u\t100%d\n", pGlobalTXT_LocalizationStrings[108], 0, v121->pMonsterInfo.uHP);
+    a1->DrawText(v56, 150, (int)a4, a5, pTmpBuf.data(), 0, 0, 0);
+    a4 = a4 + LOBYTE(v56->uFontHeight) - 3;
+    v79 = v121->pMonsterInfo.uAC;
+    v75 = 0;
+    v70 = pGlobalTXT_LocalizationStrings[12];
+    v67 = "%s\f%05u\t100%d\n";
+  }
+  else
+  {
+    sprintf(pTmpBuf.data(), "%s\f%05u\t100%s\n", pGlobalTXT_LocalizationStrings[108], 0, pGlobalTXT_LocalizationStrings[630]);
+    a1->DrawText(v56, 150, (int)a4, a5, pTmpBuf.data(), 0, 0, 0);
+    v79 = (unsigned int)pGlobalTXT_LocalizationStrings[630];
+    v75 = 0;
+    v70 = pGlobalTXT_LocalizationStrings[12];
+    a4 = a4 + LOBYTE(v56->uFontHeight) - 3;
+    v67 = "%s\f%05u\t100%s\n";
+  }
+  sprintf(pTmpBuf.data(), v67, v70, v75, v79);
+  a1->DrawText(v56, 150, a4, a5, pTmpBuf.data(), 0, 0, 0);
+  a4 = a4 + LOBYTE(v56->uFontHeight) - 6 + LOBYTE(v56->uFontHeight);
+  v95[0] = pGlobalTXT_LocalizationStrings[87];
+  v95[1] = pGlobalTXT_LocalizationStrings[6];
+  v95[2] = pGlobalTXT_LocalizationStrings[240];
+  v95[3] = pGlobalTXT_LocalizationStrings[70];
+  v95[4] = pGlobalTXT_LocalizationStrings[624];
+  v95[5] = pGlobalTXT_LocalizationStrings[138];
+  v95[6] = pGlobalTXT_LocalizationStrings[214];
+  v95[7] = pGlobalTXT_LocalizationStrings[142];
+  v95[8] = pGlobalTXT_LocalizationStrings[29];
+  v95[9] = pGlobalTXT_LocalizationStrings[133];
+  v95[10] = pGlobalTXT_LocalizationStrings[54];
+  if ( v116 )
+  {
+    sprintf(pTmpBuf.data(), "%s\f%05u\t080%s\n", pGlobalTXT_LocalizationStrings[18], 0, v95[v121->pMonsterInfo.uAttack1Type]);
+    a1->DrawText(v56, 150, (int)a4, a5, pTmpBuf.data(), 0, 0, 0);
+    a4 = a4 + LOBYTE(v56->uFontHeight) - 3;
+    v57 = v121->pMonsterInfo.uAttack1DamageBonus;
+    if ( v57 )
+      sprintf(pTmpBuf.data(), "%s\f%05u\t080%dd%d+%d\n", pGlobalTXT_LocalizationStrings[53],
+        0, v121->pMonsterInfo.uAttack1DamageDiceRolls, v121->pMonsterInfo.uAttack1DamageDiceSides, v57);
+    else
+      sprintf(pTmpBuf.data(), "%s\f%05u\t080%dd%d\n", pGlobalTXT_LocalizationStrings[53],
+        0, v121->pMonsterInfo.uAttack1DamageDiceRolls, v121->pMonsterInfo.uAttack1DamageDiceSides);
+  }
+  else
+  {
+    sprintf(pTmpBuf.data(), "%s\f%05u\t080%s\n", pGlobalTXT_LocalizationStrings[18], 0, pGlobalTXT_LocalizationStrings[630]);
+    a1->DrawText(v56, 150, (int)a4, a5, pTmpBuf.data(), 0, 0, 0);
+    a4 = a4 + LOBYTE(v56->uFontHeight) - 3;
+    sprintf(pTmpBuf.data(), "%s\f%05u\t080%s\n", pGlobalTXT_LocalizationStrings[53], 0, pGlobalTXT_LocalizationStrings[630]);
+  }
+  a1->DrawText(v56, 150, a4, a5, pTmpBuf.data(), 0, 0, 0);
+  v58 = LOBYTE(v56->uFontHeight);
+  a4 = a4 + v58 - 6 + v58;
+  if ( !i )
+  {
+    v80 = pGlobalTXT_LocalizationStrings[630];
+    v76 = 0;
+    v71 = pGlobalTXT_LocalizationStrings[628];
+    v68 = "%s\f%05u\t080%s\n";
+    sprintf(pTmpBuf.data(), v68, v71, v76, v80);
+    a1->DrawText(v56, 150, (int)a4, a5, pTmpBuf.data(), 0, 0, 0);
+    v58 = LOBYTE(v56->uFontHeight);
+    a4 = a4 + v58 - 3;
+  }
+  else
+  {
+	  v120 = (SpellBuff *)pGlobalTXT_LocalizationStrings[628];
+	  v59 = v121;
+	  v114 = v121->pMonsterInfo.uSpell1ID;
+	  if ( v114 && v121->pMonsterInfo.uSpell2ID )
+		v120 = (SpellBuff *)pGlobalTXT_LocalizationStrings[629];
+	  if ( v114 )
+	  {
+		sprintf(pTmpBuf.data(), "%s\f%05u\t060%s\n", v120, 0, pSpellStats->pInfos[v114].pShortName);
+		a1->DrawText(v56, 150, (int)a4, a5, pTmpBuf.data(), 0, 0, 0);
+		v58 = LOBYTE(v56->uFontHeight);
+		a4 = a4 + v58 - 3;
+		v59 = v121;
+	  }
+	  v60 = v59->pMonsterInfo.uSpell2ID;
+	  if ( v60 )
+	  {
+		sprintf(pTmpBuf.data(), "\f%05u\t060%s\n", 0, pSpellStats->pInfos[v60].pShortName);
+		a1->DrawText(v56, 150, (int)a4, a5, pTmpBuf.data(), 0, 0, 0);
+		v58 = LOBYTE(v56->uFontHeight);
+		a4 = a4 + v58 - 3;
+		v59 = v121;
+	  }
+	  if ( !v59->pMonsterInfo.uSpell1ID && !v59->pMonsterInfo.uSpell2ID )
+	  {
+		v80 = pGlobalTXT_LocalizationStrings[153];
+		v76 = 0;
+		v71 = pGlobalTXT_LocalizationStrings[628];
+		v68 = "%s\f%05u\t060%s\n";
+		sprintf(pTmpBuf.data(), v68, v71, v76, v80);
+		a1->DrawText(v56, 150, (int)a4, a5, pTmpBuf.data(), 0, 0, 0);
+		v58 = LOBYTE(v56->uFontHeight);
+		a4 = a4 + v58 - 3;
+	  }
+  }
+  a4 = a4 + v58 - 3;
+  a1->DrawText(v56, 150, a4, a5, pGlobalTXT_LocalizationStrings[626], 0, 0, 0);
+  a4 = a4 + LOBYTE(v56->uFontHeight) - 3;
+  v85[0] = pGlobalTXT_LocalizationStrings[87];
+  v85[1] = pGlobalTXT_LocalizationStrings[6];
+  v85[2] = pGlobalTXT_LocalizationStrings[240];
+  v85[3] = pGlobalTXT_LocalizationStrings[70];
+  v85[4] = pGlobalTXT_LocalizationStrings[142];
+  v85[5] = pGlobalTXT_LocalizationStrings[214];
+  v85[6] = pGlobalTXT_LocalizationStrings[29];
+  v85[7] = pGlobalTXT_LocalizationStrings[133];
+  v85[8] = pGlobalTXT_LocalizationStrings[54];
+  v85[9] = pGlobalTXT_LocalizationStrings[624];
+  v95[1] = (char *)v121->pMonsterInfo.uResFire;
+  v95[2] = (char *)v121->pMonsterInfo.uResAir;
+  v95[3] = (char *)v121->pMonsterInfo.uResWater;
+  v95[4] = (char *)v121->pMonsterInfo.uResEarth;
+  v95[5] = (char *)v121->pMonsterInfo.uResMind;
+  v95[6] = (char *)v121->pMonsterInfo.uResSpirit;
+  v95[7] = (char *)v121->pMonsterInfo.uResBody;
+  v95[8] = (char *)v121->pMonsterInfo.uResLight;
+  v95[9] = (char *)v121->pMonsterInfo.uResPhysical;
+  v95[10] = (char *)v121->pMonsterInfo.uResDark;
+  if ( v112 )
+  {
+    v124 = 0;
+    do
+    {
+      v62 = v95[v124+1];
+      if ( v62 == (char *)200 )
+      {
+        v81 = pGlobalTXT_LocalizationStrings[625];
+      }
+      else
+      {
+        if ( v62 )
+          v81 = pGlobalTXT_LocalizationStrings[627];
+        else
+          v81 = pGlobalTXT_LocalizationStrings[153];
+      }
+      sprintf(pTmpBuf.data(), "%s\f%05u\t070%s\n", v85[v124], 0, v81);
+      a1->DrawText(v56, 170, a4, a5, pTmpBuf.data(), 0, 0, 0);
+      v63 = LOBYTE(v56->uFontHeight);
+      v124 += 4;
+      a4 = a4 + v63 - 3;
+    }
+    while ( v124 < 40 );
+  }
+  else
+  {
+    i = 0;
+    do
+    {
+      sprintf(pTmpBuf.data(), "%s\f%05u\t070%s\n", v85[i], 0, pGlobalTXT_LocalizationStrings[630]); // "?"
+      a1->DrawText(v56, 170, a4, a5, pTmpBuf.data(), 0, 0, 0);
+      v65 = LOBYTE(v56->uFontHeight);
+      ++i;
+      a4 = a4 + v65 - 3;
+    }
+    while ( i < 10 );
+  }
+  if ( (signed __int64)pParty->pPartyBuffs[PARTY_BUFF_DETECT_LIFE].uExpireTime > 0 )
+  {
+    sprintf(pTmpBuf.data(), "%s: %d", pGlobalTXT_LocalizationStrings[650], v121->sCurrentHP);
+    pFontSmallnum->GetLineWidth(pTmpBuf.data());
+    a1->DrawTitleText(pFontSmallnum, 0, a1->uFrameHeight - LOBYTE(pFontSmallnum->uFontHeight) - 12, 0, pTmpBuf.data(), 3);
+  }
+}
+
+
+//----- (00417BB5) --------------------------------------------------------
+const char *CharacterUI_GetSkillDescText(unsigned int uPlayerID, PLAYER_SKILL_TYPE uPlayerSkillType)
+{
+    //enum PLAYER_SKILL_TYPE v2; // esi@1
+    //unsigned int v3; // ebx@1
+    int v4; // edi@1
+    int v5; // eax@1
+    Player *pPlayer; // ebx@7
+    char v7; // al@7
+    char v8; // cl@7
+    unsigned int v9; // eax@8
+    unsigned int v10; // eax@8
+    unsigned int v11; // eax@8
+    PLAYER_SKILL_TYPE v12; // edi@8
+    unsigned int v13; // eax@8
+    unsigned int v14; // eax@8
+    PLAYER_SKILL_TYPE v15; // esi@8
+    int v16; // edi@8
+    char v17; // al@8
+    int v18; // ST5C_4@8
+    int v19; // ST4C_4@8
+    int v20; // ST3C_4@8
+    int v21; // ST2C_4@8
+    int v22; // ST1C_4@8
+    char *v23; // esi@8
+    unsigned int v24; // eax@9
+    unsigned int v25; // eax@9
+    unsigned int v26; // eax@9
+    unsigned int v27; // ecx@9
+    PLAYER_SKILL_TYPE v28; // ebx@9
+    unsigned int v29; // eax@9
+    char a2[1200]; // [sp+Ch] [bp-538h]@7
+    char Source[120]; // [sp+4BCh] [bp-88h]@7
+    unsigned __int16 *v33; // [sp+534h] [bp-10h]@1
+    int v34; // [sp+538h] [bp-Ch]@1
+    unsigned __int16 *v35; // [sp+53Ch] [bp-8h]@1
+    //enum PLAYER_SKILL_TYPE v36; // [sp+540h] [bp-4h]@1
+
+    //v2 = uPlayerSkillType;
+    //v3 = uPlayerID;
+    //v36 = uPlayerSkillType;
+    v4 = pFontSmallnum->GetLineWidth(pGlobalTXT_LocalizationStrings[431]);// Normal
+    v34 = pFontSmallnum->GetLineWidth(pGlobalTXT_LocalizationStrings[433]);// Expert
+    v33 = (unsigned __int16 *)pFontSmallnum->GetLineWidth(pGlobalTXT_LocalizationStrings[432]);// Master
+    v5 = pFontSmallnum->GetLineWidth(pGlobalTXT_LocalizationStrings[96]);// Grand
+    v35 = (unsigned __int16 *)v4;
+    if ( v34 > v4 )
+        v35 = (unsigned __int16 *)v34;
+    if ( (signed int)v33 > (signed int)v35 )
+        v35 = v33;
+    if ( v5 > (signed int)v35 )
+        v35 = (unsigned __int16 *)v5;
+    pPlayer = &pParty->pPlayers[uPlayerID];
+    //v33 = &pPlayer->pActiveSkills[uPlayerSkillType];
+    v7 = pPlayer->GetActualSkillLevel(uPlayerSkillType);
+    v8 = pPlayer->pActiveSkills[uPlayerSkillType];
+    a2[0] = 0;
+    Source[0] = 0;
+    if ( (v8 & 0x3F) == (v7 & 0x3F) )
+        {
+        strcpy(a2, "%s\n\n");
+        v24 = GetSkillColor(pPlayer->classType, uPlayerSkillType, 1);
+        sprintf(Source, "\f%05d", v24);
+        strcat(a2, Source);
+        strcat(a2, "%s\t%03d:\t%03d%s\t000\n");
+        v25 = GetSkillColor(pPlayer->classType, uPlayerSkillType, 2);
+        sprintf(Source, "\f%05d", v25);
+        strcat(a2, Source);
+        strcat(a2, "%s\t%03d:\t%03d%s\t000\n");
+        v26 = GetSkillColor(pPlayer->classType, uPlayerSkillType, 3);
+        sprintf(Source, "\f%05d", v26);
+        strcat(a2, Source);
+        strcat(a2, "%s\t%03d:\t%03d%s\t000\n");
+        v27 = pPlayer->classType;
+        v28 = uPlayerSkillType;
+        v29 = GetSkillColor(v27, uPlayerSkillType, 4);
+        sprintf(Source, "\f%05d", v29);
+        strcat(a2, Source);
+        strcat(a2, "%s\t%03d:\t%03d%s\t000\n");
+
+        v23 = static_sub_417BB5_out_string;
+        sprintf(static_sub_417BB5_out_string, a2, pSkillDesc[v28], pGlobalTXT_LocalizationStrings[431],      // Normal
+            (char *)v35 + 3, v35 + 5, pNormalSkillDesc[v28], pGlobalTXT_LocalizationStrings[433],      // Expert
+            (char *)v35 + 3, v35 + 5, pExpertSkillDesc[v28], pGlobalTXT_LocalizationStrings[432],      // Master
+            (char *)v35 + 3, v35 + 5, pMasterSkillDesc[v28], pGlobalTXT_LocalizationStrings[96],       // Grand
+            (char *)v35 + 3, v35 + 5, pGrandSkillDesc[v28]);
+        }
+    else
+        {
+        strcpy(a2, "%s\n\n");
+        v9 = GetSkillColor(pPlayer->classType, uPlayerSkillType, 1);
+        sprintf(Source, "\f%05d", v9);
+        strcat(a2, Source);
+        strcat(a2, "%s\t%03d:\t%03d%s\t000\n");
+        v10 = GetSkillColor(pPlayer->classType, uPlayerSkillType, 2);
+        sprintf(Source, "\f%05d", v10);
+        strcat(a2, Source);
+        strcat(a2, "%s\t%03d:\t%03d%s\t000\n");
+        v11 = GetSkillColor(pPlayer->classType, uPlayerSkillType, 3);
+        sprintf(Source, "\f%05d", v11);
+        strcat(a2, Source);
+        strcat(a2, "%s\t%03d:\t%03d%s\t000\n");
+        v12 = uPlayerSkillType;
+        v13 = GetSkillColor(pPlayer->classType, uPlayerSkillType, 4);
+        sprintf(Source, "\f%05d", v13);
+        strcat(a2, Source);
+        strcat(a2, "%s\t%03d:\t%03d%s\t000\n\n");
+        v14 = TargetColor(0xFFu, 0xFFu, 0xFFu);
+        sprintf(Source, "\f%05d", v14);
+        strcat(a2, Source);
+        strcat(a2, "%s: +%d");
+        v15 = v12;
+        v16 = (int)(v35 + 5);
+        v15 = (PLAYER_SKILL_TYPE)((int)v15 * 4);
+        v34 = (int)((char *)v35 + 3);
+        v17 = pPlayer->GetActualSkillLevel(uPlayerSkillType);
+        v18 = *(int *)(pGrandSkillDesc[v15]);
+        v19 = *(int *)(pMasterSkillDesc[v15]);
+        v20 = *(int *)(pExpertSkillDesc[v15]);
+        v21 = *(int *)(pNormalSkillDesc[v15]);
+        v22 = *(int *)(pSkillDesc[v15]);
+        v23 = static_sub_417BB5_out_string;
+        sprintf(
+            static_sub_417BB5_out_string,
+            a2,
+            v22,
+            pGlobalTXT_LocalizationStrings[431],
+            v34,
+            v16,
+            v21,
+            pGlobalTXT_LocalizationStrings[433],
+            v34,
+            v16,
+            v20,
+            pGlobalTXT_LocalizationStrings[432],
+            v34,
+            v16,
+            v19,
+            pGlobalTXT_LocalizationStrings[96],
+            v34,
+            v16,
+            v18,
+            pGlobalTXT_LocalizationStrings[623],
+            (v17 & 0x3F) - (*(char *)v33 & 0x3F));
+        }
+    return v23;
+    }
+
+//----- (00417FE5) --------------------------------------------------------
+    void CharacterUI_SkillsTab_ShowHint()
+        {
+    unsigned int v0; // ecx@1
+    unsigned int v1; // eax@1
+    GUIButton *i; // esi@6
+    const char *v3; // eax@12
+    unsigned int pX; // [sp+4h] [bp-8h]@1
+    unsigned int pY; // [sp+8h] [bp-4h]@1
+
+    pMouse->GetClickPos(&pX, &pY);
+    v0 = pX;
+    v1 = pY;
+    if ( (signed int)pX < 24 || (signed int)pX > 455 || (signed int)pY < 18 || (signed int)pY > 36 )
+        {
+        for ( i = pGUIWindow_CurrentMenu->pControlsHead; i; i = i->pNext )
+            {
+            if ( i->msg == UIMSG_SkillUp
+                && (signed int)v0 >= (signed int)i->uX
+                && (signed int)v0 <= (signed int)i->uZ
+                && (signed int)v1 >= (signed int)i->uY
+                && (signed int)v1 <= (signed int)i->uW )
+                {
+                v3 = CharacterUI_GetSkillDescText(uActiveCharacter - 1, (PLAYER_SKILL_TYPE)i->msg_param);
+                sub_4179BC_draw_tooltip(pSkillNames[i->msg_param], v3);
+                v1 = pY;
+                v0 = pX;
+                }
+            }
+        }
+    else
+        {
+        sub_4179BC_draw_tooltip(pGlobalTXT_LocalizationStrings[207], pSkillPointsAttributeDescription);
+        }
+    
+    }
+
+//----- (00418083) --------------------------------------------------------
+void __cdecl CharacterUI_StatsTab_ShowHint()
+  {
+  LONG _x; // esi@1
+  LONG _y; // eax@1
+  int pStringNum; // edi@1
+  signed int pTextColor; // eax@15
+  char *pHourWord; // ecx@17
+  char *pDayWord; // eax@20
+  int v15; // ebx@28
+  int v16; // eax@33
+  POINT a2; // [sp+Ch] [bp-24h]@1
+  int pHour; // [sp+14h] [bp-1Ch]@15
+  unsigned int pDay; // [sp+24h] [bp-Ch]@15
+
+  _x = pMouse->GetCursorPos(&a2)->x;
+  _y = pMouse->GetCursorPos(&a2)->y;
+  for ( pStringNum = 0; pStringNum < (signed int)&off_4E2A12; ++pStringNum )
+  {
+    if ( _x >= stat_string_coord[pStringNum].x  && _x <= stat_string_coord[pStringNum].x + stat_string_coord[pStringNum].width )
+    {
+      if ( _y >= stat_string_coord[pStringNum].y && _y <= stat_string_coord[pStringNum].y + stat_string_coord[pStringNum].height )
+        break;
+    }
+  }
+  switch ( pStringNum )
+  {
+    case 0:// Attributes
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+    case 6:
+      if ( aAttributeNames[pStringNum] && pAttributeDescriptions[pStringNum] )
+        sub_4179BC_draw_tooltip(aAttributeNames[pStringNum], pAttributeDescriptions[pStringNum]);
+      break;
+    case 7:// Health Points
+      if ( pGlobalTXT_LocalizationStrings[108] && pHealthPointsAttributeDescription )
+        sub_4179BC_draw_tooltip(pGlobalTXT_LocalizationStrings[108], pHealthPointsAttributeDescription);
+      break;
+    case 8:// Spell Points
+      if ( pGlobalTXT_LocalizationStrings[212] && pSpellPointsAttributeDescription )
+        sub_4179BC_draw_tooltip(pGlobalTXT_LocalizationStrings[212], pSpellPointsAttributeDescription);
+      break;
+    case 9:// Armor Class
+      if ( pGlobalTXT_LocalizationStrings[12] && pArmourClassAttributeDescription )
+        sub_4179BC_draw_tooltip(pGlobalTXT_LocalizationStrings[12], pArmourClassAttributeDescription);
+      break;
+    case 10:// Player Condition
+      strcpy(pTmpBuf2.data(), pPlayerConditionAttributeDescription);
+      strcat(pTmpBuf2.data(), "\n");
+      extern std::array<unsigned int, 18> pConditionImportancyTable;
+      for ( uint i = 0; i < 18; ++i )
+      {
+        if ( pPlayers[uActiveCharacter]->pConditions[pConditionImportancyTable[i]] )
+        {
+          strcat(pTmpBuf2.data(), " \n");
+          pHour = pParty->uTimePlayed - pPlayers[uActiveCharacter]->pConditions[pConditionImportancyTable[i]];
+          pHour = (unsigned int)((pHour * 0.234375) / 60 / 60);
+          pDay = (unsigned int)pHour / 24;
+          pHour %= 24i64;
+          pTextColor = GetConditionDrawColor(pConditionImportancyTable[i]);
+          sprintfex(pTmpBuf.data(), format_4E2DE8, pTextColor, aCharacterConditionNames[pConditionImportancyTable[i]]);
+          strcat(pTmpBuf2.data(), pTmpBuf.data());
+          if ( pHour && pHour <= 1 )
+            pHourWord = pGlobalTXT_LocalizationStrings[109];
+          else
+            pHourWord = pGlobalTXT_LocalizationStrings[110];
+          if ( !pDay || (pDayWord = pGlobalTXT_LocalizationStrings[56], pDay > 1) )
+            pDayWord = pGlobalTXT_LocalizationStrings[57];
+          sprintfex(pTmpBuf.data(), "%lu %s, %lu %s", pDay, pDayWord, pHour, pHourWord);
+          strcat(pTmpBuf2.data(), pTmpBuf.data());
+        }
+      }
+      if ( pGlobalTXT_LocalizationStrings[47] && pTmpBuf2.data() )
+        sub_4179BC_draw_tooltip(pGlobalTXT_LocalizationStrings[47], pTmpBuf2.data());
+      break;
+    case 11:// Fast Spell
+      if ( pGlobalTXT_LocalizationStrings[172] && pFastSpellAttributeDescription )
+        sub_4179BC_draw_tooltip(pGlobalTXT_LocalizationStrings[172], pFastSpellAttributeDescription);
+      break;
+    case 12:// Player Age
+      if ( pGlobalTXT_LocalizationStrings[5] && pPlayerAgeAttributeDescription )
+        sub_4179BC_draw_tooltip(pGlobalTXT_LocalizationStrings[5], pPlayerAgeAttributeDescription);
+      break;
+    case 13:// Player Level
+      if ( pGlobalTXT_LocalizationStrings[131] && pPlayerLevelAttributeDescription )
+        sub_4179BC_draw_tooltip(pGlobalTXT_LocalizationStrings[131], pPlayerLevelAttributeDescription);
+      break;
+    case 14://Experience
+      v15 = pPlayers[uActiveCharacter]->uLevel;
+      do
+      {
+        if ( (signed __int64)pPlayers[uActiveCharacter]->uExperience < (unsigned int)sub_4B46F8(v15) )
+          break;
+        ++v15;
+      }
+      while ( v15 <= 10000 );
+      pTmpBuf[0] = 0;
+      pTmpBuf2[0] = 0;
+      if ( v15 > pPlayers[uActiveCharacter]->uLevel )
+        sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[147], v15);
+      v16 = sub_4B46F8(v15) - LODWORD(pPlayers[uActiveCharacter]->uExperience);
+      sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[538], v16, v15 + 1);
+      strcat(pTmpBuf.data(), "\n");
+      strcat(pTmpBuf.data(), pTmpBuf2.data());
+      sprintf(pTmpBuf2.data(), "%s\n \n%s", pPlayerExperienceAttributeDescription, pTmpBuf.data());
+      if ( pGlobalTXT_LocalizationStrings[83] && pTmpBuf2.data() )
+        sub_4179BC_draw_tooltip(pGlobalTXT_LocalizationStrings[83], pTmpBuf2.data());
+      break;
+    case 15:// Attack Bonus
+      if ( pGlobalTXT_LocalizationStrings[587] && pAttackBonusAttributeDescription )
+        sub_4179BC_draw_tooltip(pGlobalTXT_LocalizationStrings[587], pAttackBonusAttributeDescription);
+      break;
+    case 16:// Attack Damage
+      if ( pGlobalTXT_LocalizationStrings[588] && pAttackDamageAttributeDescription )
+        sub_4179BC_draw_tooltip(pGlobalTXT_LocalizationStrings[588], pAttackDamageAttributeDescription);
+      break;
+    case 17:// Missle Bonus
+      if ( pGlobalTXT_LocalizationStrings[589] && pMissleBonusAttributeDescription )
+        sub_4179BC_draw_tooltip(pGlobalTXT_LocalizationStrings[589], pMissleBonusAttributeDescription);
+      break;
+    case 18:// Missle Damage
+      if ( pGlobalTXT_LocalizationStrings[590] && pMissleDamageAttributeDescription )
+        sub_4179BC_draw_tooltip(pGlobalTXT_LocalizationStrings[590], pMissleDamageAttributeDescription);
+      break;
+    case 19:// Fire Resistance
+      if ( pGlobalTXT_LocalizationStrings[87] && pFireResistanceAttributeDescription )
+        sub_4179BC_draw_tooltip(pGlobalTXT_LocalizationStrings[87], pFireResistanceAttributeDescription);
+      break;
+    case 20:// Air Resistance
+      if ( pGlobalTXT_LocalizationStrings[6] && pAirResistanceAttributeDescription )
+        sub_4179BC_draw_tooltip(pGlobalTXT_LocalizationStrings[6], pAirResistanceAttributeDescription);
+      break;
+    case 21:// Water Resistance
+      if ( pGlobalTXT_LocalizationStrings[240] && pWaterResistanceAttributeDescription )
+        sub_4179BC_draw_tooltip(pGlobalTXT_LocalizationStrings[240], pWaterResistanceAttributeDescription);
+      break;
+    case 22:// Earth Resistance
+      if ( pGlobalTXT_LocalizationStrings[70] && pEarthResistanceAttributeDescription )
+        sub_4179BC_draw_tooltip(pGlobalTXT_LocalizationStrings[70], pEarthResistanceAttributeDescription);
+      break;
+    case 23:// Mind Resistance
+      if ( pGlobalTXT_LocalizationStrings[142] && pMindResistanceAttributeDescription )
+        sub_4179BC_draw_tooltip(pGlobalTXT_LocalizationStrings[142], pMindResistanceAttributeDescription);
+      break;
+    case 24:// Body Resistance
+      if ( pGlobalTXT_LocalizationStrings[29] && pBodyResistanceAttributeDescription )
+        sub_4179BC_draw_tooltip(pGlobalTXT_LocalizationStrings[29], pBodyResistanceAttributeDescription);
+      break;
+    case 25: // Skill Points
+      if ( pGlobalTXT_LocalizationStrings[207] && pSkillPointsAttributeDescription )
+        sub_4179BC_draw_tooltip(pGlobalTXT_LocalizationStrings[207], pSkillPointsAttributeDescription);
+      break;
+    case 26:
+      __debugbreak();
+      //_y = (Player *)(4 * pPlayers[uActiveCharacter]->classType);
+      //v24 = *(char **)((char *)_y->pConditions + (int)pClassNames);
+      //v7 = *(char **)((char *)_y->pConditions + (int)pClassDescriptions);
+      //if ( v24 && v7 )
+        //sub_4179BC_draw_tooltip(v24, v7);
+      break;
+    default:
+      break;
+  }
+}
+
+    //----- (00410B28) --------------------------------------------------------
+    void __thiscall DrawSpellDescriptionPopup(int spell_index)
+        {
+        Player *v1; // edi@1
+        SpellInfo *v2; // esi@1
+        unsigned int v3; // eax@2
+        int v4; // eax@4
+        LONG v5; // ecx@4
+        int v6; // eax@10
+        char *v7; // ST44_4@12
+        unsigned __int16 v8; // ax@12
+        GUIWindow a1; // [sp+Ch] [bp-68h]@4
+        int v10; // [sp+60h] [bp-14h]@1
+        POINT a2; // [sp+64h] [bp-10h]@1
+        int v12; // [sp+6Ch] [bp-8h]@4
+        int v13; // [sp+70h] [bp-4h]@4
+
+        v1 = pPlayers[uActiveCharacter];
+        v10 = spell_index;
+        v2 = &pSpellStats->pInfos[spell_index + 11 * v1->lastOpenedSpellbookPage + 1];
+        if ( pMouse->GetCursorPos(&a2)->y <= 250 )
+            v3 = pMouse->GetCursorPos(&a2)->y + 30;
+        else
+            v3 = 30;
+        a1.uFrameY = v3;
+        a1.uFrameWidth = 328;
+        a1.uFrameHeight = 68;
+        a1.uFrameX = 90;
+        a1.uFrameZ = 417;
+        a1.uFrameW = v3 + 67;
+        a1.Hint = 0;
+        a2.y = pFontSmallnum->GetLineWidth(pGlobalTXT_LocalizationStrings[LOCSTR_NORMAL]);
+        v13 = pFontSmallnum->GetLineWidth(pGlobalTXT_LocalizationStrings[LOCSTR_MASTER]);
+        v12 = pFontSmallnum->GetLineWidth(pGlobalTXT_LocalizationStrings[LOCSTR_EXPERT]);
+        v4 = pFontSmallnum->GetLineWidth(pGlobalTXT_LocalizationStrings[LOCSTR_GRAND]);
+        v5 = a2.y;
+        if ( v13 > a2.y )
+            v5 = v13;
+        if ( v12 > v5 )
+            v5 = v12;
+        if ( v4 > v5 )
+            v5 = v4;
+        sprintf(  pTmpBuf2.data(),
+            "%s\n\n%s\t%03d:\t%03d%s\t000\n%s\t%03d:\t%03d%s\t000\n%s\t%03d:\t%03d%s\t000\n%s\t%03d:\t%03d%s",
+            v2->pDescription,
+            pGlobalTXT_LocalizationStrings[LOCSTR_NORMAL],
+            v5 + 3, v5 + 10,
+            v2->pBasicSkillDesc,
+            pGlobalTXT_LocalizationStrings[LOCSTR_EXPERT],
+            v5 + 3,  v5 + 10,
+            v2->pExpertSkillDesc,
+            pGlobalTXT_LocalizationStrings[LOCSTR_MASTER],
+            v5 + 3, v5 + 10,
+            v2->pMasterSkillDesc,
+            pGlobalTXT_LocalizationStrings[LOCSTR_GRAND],
+            v5 + 3,  v5 + 10,
+            v2->pGrandmasterSkillDesc);
+        v6 = pFontSmallnum->CalcTextHeight(pTmpBuf2.data(), &a1, 0, 0);
+        a1.uFrameHeight += v6;
+        if ( (signed int)a1.uFrameHeight < 150 )
+            a1.uFrameHeight = 150;
+        a1.uFrameWidth = game_viewport_width;
+        a1.DrawMessageBox(0);
+        a1.uFrameWidth -= 12;
+        a1.uFrameHeight -= 12;
+        v7 = v2->pName;
+        a1.uFrameZ = a1.uFrameX + a1.uFrameWidth - 1;
+        a1.uFrameW = a1.uFrameHeight + a1.uFrameY - 1;
+        v8 = TargetColor(0xFFu, 0xFFu, 0x9Bu);
+        a1.DrawTitleText(pFontArrus, 0x78u, 0xCu, v8, v7, 3u);
+        a1.DrawText(pFontSmallnum, 120, 44, 0, pTmpBuf2.data(), 0, 0, 0);
+        a1.uFrameWidth = 108;
+        a1.uFrameZ = a1.uFrameX + 107;
+        a1.DrawTitleText(pFontComic, 0xCu, 0x4Bu, 0, pSkillNames[v1->lastOpenedSpellbookPage + 12], 3u);
+        sprintf( pTmpBuf.data(),  "%s\n%d",    pGlobalTXT_LocalizationStrings[LOCSTR_SP_COST],
+            pSpellDatas[spell_index + 11 * v1->lastOpenedSpellbookPage + 1].mana_per_skill[v1->pActiveSkills[v1->lastOpenedSpellbookPage + PLAYER_SKILL_FIRE]]);
+        //  *(&[0].field_12 //temp_fix field_14
+        // + ((unsigned int)LOBYTE(v1->pActiveSkills[v1->lastOpenedSpellbookPage + 12]) >> 6)
+        // + 10 * (int)((char *)v10 + 11 * v1->lastOpenedSpellbookPage)));
+        a1.DrawTitleText(pFontComic, 0xCu, a1.uFrameHeight - LOBYTE(pFontComic->uFontHeight) - 16, 0, pTmpBuf.data(), 3u);
+        dword_507B00_spell_info_to_draw_in_popup = 0;
+        }
+    // 507B00: using guessed type int dword_507B00_spell_info_to_draw_in_popup;
+
+
+
+
+
+//----- (00416D62) --------------------------------------------------------
+void sub_416D62_ShowPopupWindow_MonsterRecord_ItemInfo_etcsub_416D62(Vec2_int_ *_this)
+{
+        signed int pPlayerNum; // eax@12
+        char *v2; // eax@32
+        void *v3; // ecx@52
+        unsigned int v4; // eax@59
+        int v5; // esi@62
+        signed int v6; // esi@64
+        signed int v7; // esi@69
+        ItemGen *v8; // ecx@70
+        unsigned int v9; // eax@72
+        unsigned int v10; // eax@76
+        //char v11; // zf@83
+        GUIButton *pButton; // esi@84
+        unsigned int v13; // ecx@85
+        char *pStr; // edi@85
+        //signed int pControlID; // eax@92
+        int v16; // eax@95
+        int v17; // eax@96
+        PLAYER_SKILL_TYPE v18; // eax@98
+        char *pStr2; // eax@99
+        unsigned int v20; // eax@108
+        unsigned int pSkillId; // eax@109
+        const char *pSkillInfo; // eax@111
+        //char *v23; // ebx@112
+        char *pHint; // edx@113
+        unsigned int pColor; // eax@113
+        GUIWindow pWindow; // [sp+4h] [bp-74h]@32
+        double v27; // [sp+58h] [bp-20h]@33
+        struct tagPOINT Point; // [sp+60h] [bp-18h]@6
+        char *v29; // [sp+68h] [bp-10h]@33
+        float v30; // [sp+6Ch] [bp-Ch]@33
+        unsigned int pX; // [sp+70h] [bp-8h]@3
+        unsigned int pY; // [sp+74h] [bp-4h]@3
+
+        if ( pCurrentScreen == SCREEN_VIDEO )
+            return;
+        if ( _this )
+            {
+            pX = _this->x;
+            pY = _this->y;
+            }
+        else
+            {
+            pMouse->GetClickPos(&pX, &pY);
+            }
+        if ( pRenderer->bWindowMode )
+            {
+            GetCursorPos(&Point);
+            ScreenToClient(hWnd, &Point);
+            if ( Point.x < 1 || Point.y < 1 || Point.x > 638 || Point.y > 478 )
+                {
+                back_to_game();
+                return;
+                }
+            }
+
+        if ( pParty->pPickedItem.uItemID )//        
+            {
+            //v1 = 0;
+            //do
+            for ( pPlayerNum = 0; pPlayerNum < 4; ++pPlayerNum)
+                {
+                if ( (signed int)pX > RightClickPortraitXmin[pPlayerNum] && (signed int)pX < RightClickPortraitXmax[pPlayerNum]
+                && (signed int)pY > 375 && (signed int)pY < 466 )
+                    {
+                    pPlayers[uActiveCharacter]->UseItem_DrinkPotion_etc(pPlayerNum + 1, 1);
+                    return;
+                    }
+                //++v1;
+                }
+            //while ( v1 < 4 );
+            }
+
+        pEventTimer->Pause();
+
+        switch(pCurrentScreen)
+            {
+        case SCREEN_CASTING:
+            {
+            identify_item();
+            break;
+            }
+
+        case SCREEN_CHEST:
+            {
+            if ( !pPlayers[uActiveCharacter]->CanAct() )
+                {
+                sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[427],//%s    %s
+                    pPlayers[uActiveCharacter]->pName, pGlobalTXT_LocalizationStrings[541]);// 
+                pWindow.Hint = pTmpBuf.data();
+                pWindow.uFrameWidth = 384;
+                pWindow.uFrameHeight = 180;
+                pWindow.uFrameY = 40;
+                if ( (signed int)pX <= 320 )
+                    v10 = pX + 30;
+                else
+                    v10 = pX - 414;
+                pWindow.uFrameX = v10;
+                pWindow.DrawMessageBox(0);
+                }
+            else
+                {
+                v9 = pX + pSRZBufferLineOffsets[pY];
+                if ( pRenderer->pActiveZBuffer[v9] & 0xFFFF )
+                    {
+
+                    //  __debugbreak(); // invalid indexing will result in invalid object ptr
+                    //	v8 = (ItemGen *)(&pOtherOverlayList->pOverlays[49].field_4 + 2662 * (unsigned int)pChestWindow->ptr_1C + 18* *((short *)&pChests[0].igChestItems[139].uExpireTime
+                    //					+ (pRenderer->pActiveZBuffer[v9] & 0xFFFF) + 2662 * (unsigned int)pChestWindow->ptr_1C + 3));
+                    v10=pChests[pChestWindow->par1C].pInventoryIndices[(pRenderer->pActiveZBuffer[v9] & 0xFFFF)-1];
+                    v8 =&pChests[pChestWindow->par1C].igChestItems[v10-1];
+                    GameUI_DrawItemInfo(v8);
+                    }
+                }
+            break;
+            }
+        case SCREEN_GAME:
+            {
+            if (GetCurrentMenuID() > 0)
+                break;
+
+            if ( (signed int)pY > (signed int)pViewport->uViewportBR_Y )
+                {
+                pWindow.ptr_1C = (void *)((signed int)pX / 118);
+                if ( (signed int)pX / 118 < 4 )
+                    {
+                    pWindow.Hint = 0;
+                    pWindow.uFrameWidth = 400;
+                    pWindow.uFrameHeight = 200;
+                    pWindow.uFrameX = 38;
+                    pWindow.uFrameY = 60;
+                    pAudioPlayer->StopChannels(-1, -1);
+                    GameUI_CharacterQuickRecord_Draw(&pWindow, pPlayers[(int)pWindow.ptr_1C + 1]);
+                    }
+                }
+            else if ( (signed int)pX > (signed int)pViewport->uViewportBR_X )
+                {
+                if ( (signed int)pY >= 130 )
+                    {
+                    if ( (signed int)pX >= 476 && (signed int)pX <= 636 && (signed int)pY >= 240 && (signed int)pY <= 300 )
+                        {
+                        pWindow.Hint = 0;
+                        pWindow.uFrameWidth = 400;
+                        pWindow.uFrameHeight = 200;
+                        pWindow.uFrameX = 38;
+                        pWindow.uFrameY = 60;
+                        pAudioPlayer->StopChannels(-1, -1);
+                        pWindow._41D73D_draw_buff_tooltip();
+                        }
+                    else if ( (signed int)pX < 485 || (signed int)pX > 548 || (signed int)pY < 156 || (signed int)pY > 229 )
+                        {
+                        if (!( (signed int)pX < 566 || (signed int)pX > 629 || (signed int)pY < 156 || (signed int)pY > 229 ))
+                            {
+                            pAudioPlayer->StopChannels(-1, -1);
+                            v3 = (void *)1;
+                            GameUI_DrawNPCPopup(v3);
+                            }
+                        }
+                    else
+                        {
+                        pAudioPlayer->StopChannels(-1, -1);
+                        v3 = 0;
+                        GameUI_DrawNPCPopup(v3);
+                        }
+                    }
+                else
+                    {
+                    pWindow.Hint = (char *)GameUI_GetMinimapHintText();
+                    pWindow.uFrameWidth = 256;
+                    pWindow.uFrameX = 130;
+                    pWindow.uFrameY = 140;
+                    pWindow.uFrameHeight = 64;
+                    pAudioPlayer->StopChannels(-1, -1);
+                    pWindow.DrawMessageBox(0);
+                    }
+                }
+            else
+                {
+                pWindow.Hint = 0;
+                pWindow.uFrameWidth = 320;
+                pWindow.uFrameHeight = 320;
+                v4 = pX - 350;
+                if ( (signed int)pX <= 320 )
+                    v4 = pX + 30;
+                pWindow.uFrameX = v4;
+                pWindow.uFrameY = 40;
+                if ( pRenderer->pRenderD3D )
+                    LOWORD(v5) = pGame->pVisInstance->get_picked_object_zbuf_val();
+                else
+                    v5 = pRenderer->pActiveZBuffer[pX + pSRZBufferLineOffsets[pY]];
+                v6 = (unsigned __int16)v5;
+                if (PID_TYPE(v6) != OBJECT_Item)
+                    {
+                    if (PID_TYPE(v6) == OBJECT_Actor)
+                        {
+                        if ( pRenderer->uNumSceneBegins )
+                            {
+                            pWindow.DrawMessageBox(1);
+                            MonsterPopup_Draw(PID_ID(v6), &pWindow);
+                            }
+                        else
+                            {
+                            pRenderer->BeginScene();
+                            pWindow.DrawMessageBox(1);
+                            MonsterPopup_Draw(PID_ID(v6), &pWindow);
+                            pRenderer->EndScene();
+                            }
+                        }
+                    }
+                else
+                    {
+                    v7 = PID_ID(v6);
+                    if ( ! (pObjectList->pObjects[pSpriteObjects[v7].uObjectDescID].uFlags & 0x10 ) )
+                        {
+                        v8 = &pSpriteObjects[v7].stru_24;
+                        GameUI_DrawItemInfo(v8);
+                        }
+                    }
+                }
+            break;
+            }
+        case SCREEN_BOOKS:
+            {
+            if ( !dword_506364
+                || (signed int)pX < (signed int)pViewport->uViewportTL_X
+                || (signed int)pX > (signed int)pViewport->uViewportBR_X
+                || (signed int)pY < (signed int)pViewport->uViewportTL_Y
+                || (signed int)pY > (signed int)pViewport->uViewportBR_Y
+                || (v2 = (char *)sub_444564(), (pWindow.Hint = v2) == 0) )
+                break;
+            v30 = (double)(pFontArrus->GetLineWidth(v2) + 32);
+            v27 = v30 + 6.7553994e15;
+            v29 = (char *)LODWORD(v27);
+            pWindow.uFrameWidth = LODWORD(v27);
+            pWindow.uFrameX = pX + 5;
+            pWindow.uFrameY = pY + 5;
+            pWindow.uFrameHeight = 64;
+            pAudioPlayer->StopChannels(-1, -1);
+            pWindow.DrawMessageBox(0);
+            break;
+            }
+        case SCREEN_CHARACTERS:
+        case SCREEN_E:
+        case SCREEN_CHEST_INVENTORY:
+            {
+            if ( (signed int)pX > 467 && pCurrentScreen != SCREEN_E )
+                {
+                identify_item();
+                }
+            else if ( (signed int)pY >= 345 )
+                break;
+            else if ( pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] == 100 )//2DEvent - CharacerScreenStats
+                {
+                CharacterUI_StatsTab_ShowHint();
+                }
+            else if ( pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] == 101 )//2DEvent - CharacerScreenSkills
+                {
+                CharacterUI_SkillsTab_ShowHint();
+                }
+            else
+              {
+                if ( pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] == 103 )//2DEvent - CharacerScreenInventory
+                  identify_item();
+              }
+            break;
+            }
+        case SCREEN_SPELL_BOOK:
+            {
+            if ( dword_507B00_spell_info_to_draw_in_popup )
+                DrawSpellDescriptionPopup(dword_507B00_spell_info_to_draw_in_popup - 1);
+            break;
+            }
+        case SCREEN_HOUSE:
+        {
+          if ( (signed int)pY < 345 && (signed int)pX < 469 )
+            ShowPopupShopItem();
+          break;
+        }
+        case SCREEN_PARTY_CREATION:
+            {
+            pWindow.Hint = 0;
+            pStr = 0;
+            for ( pButton = pGUIWindow_CurrentMenu->pControlsHead; pButton; pButton = pButton->pNext)
+                {
+                if ( pButton->uButtonType == 1 && pButton->uButtonType != 3 && (signed int)pX > (signed int)pButton->uX && (signed int)pX < (signed int)pButton->uZ
+                    && (signed int)pY > (signed int)pButton->uY && (signed int)pY < (signed int)pButton->uW )
+                    {
+                    switch ( pButton->msg )
+                    {
+                    case UIMSG_0: //stats info
+                        pWindow.Hint = pAttributeDescriptions[(signed int)pButton->msg_param % 7];
+                        pStr = aAttributeNames[(signed int)pButton->msg_param % 7];
+                        break;
+                    case UIMSG_PlayerCreationClickPlus: //Plus button info 
+                        pStr = pGlobalTXT_LocalizationStrings[670];//
+                        pWindow.Hint = pGlobalTXT_LocalizationStrings[671];//"    ,     "
+                        break;
+                    case UIMSG_PlayerCreationClickMinus: //Minus button info
+                        pStr = pGlobalTXT_LocalizationStrings[668];//
+                        pWindow.Hint = pGlobalTXT_LocalizationStrings[669];//"    ,     "
+                        break;
+                    case UIMSG_PlayerCreationSelectActiveSkill: //Available skill button info
+                        v18 = pParty->pPlayers[uPlayerCreationUI_SelectedCharacter].GetSkillIdxByOrder(pButton->msg_param + 4);
+                        pStr = pSkillNames[v18];
+                        pWindow.Hint = pSkillDesc[v18];
+                        break;
+                    case UIMSG_PlayerCreationSelectClass: //Available Class Info
+                        pWindow.Hint = pClassDescriptions[pButton->msg_param];
+                        pStr = pClassNames[pButton->msg_param];
+                        break;
+                    case UIMSG_PlayerCreationClickOK: //OK Info
+                        pWindow.Hint = pGlobalTXT_LocalizationStrings[664];//        .
+                        pStr = pGlobalTXT_LocalizationStrings[665];// 
+                        break;
+                    case UIMSG_PlayerCreationClickReset: //Clear info
+                        pWindow.Hint = pGlobalTXT_LocalizationStrings[666];//     .
+                        pStr = pGlobalTXT_LocalizationStrings[667];// 
+                        break;
+                    case UIMSG_PlayerCreation_SelectAttribute: // Character info
+                        pStr = pParty->pPlayers[pButton->msg_param].pName;
+                        pWindow.Hint = pClassDescriptions[pParty->pPlayers[pButton->msg_param].classType];
+                        break;
+                        }
+                    if ( pButton->msg > UIMSG_44 && pButton->msg <= UIMSG_PlayerCreationRemoveDownSkill ) //Sellected skills info
+                        {
+                        pSkillId = pParty->pPlayers[pButton->msg_param].GetSkillIdxByOrder(pButton->msg - UIMSG_48);
+                        pY = 0;
+                        if ( (signed int)pSkillId < 37 )
+                            {
+                            pSkillInfo = CharacterUI_GetSkillDescText(pButton->msg_param, (PLAYER_SKILL_TYPE)pSkillId);
+                            strcpy(pTmpBuf2.data(), pSkillInfo);
+                            pWindow.Hint = pTmpBuf2.data();
+                            pStr = pSkillNames[pSkillId];
+                            }
+                        }
+                    }
+                }
+            if ( pWindow.Hint )
+                {
+                pHint = (char*)pWindow.Hint;
+                pWindow.Hint = 0;
+                pWindow.uFrameWidth = 384;
+                pWindow.uFrameHeight = 256;
+                pWindow.uFrameX = 128;
+                pWindow.uFrameY = 40;
+                pWindow.uFrameHeight = pFontSmallnum->CalcTextHeight(pHint, &pWindow, 24, 0) + 2 * LOBYTE(pFontLucida->uFontHeight) + 24;
+                pWindow.uFrameZ = pWindow.uFrameX + pWindow.uFrameWidth - 1;
+                pWindow.uFrameW = pWindow.uFrameY + pWindow.uFrameHeight - 1;
+                pWindow.DrawMessageBox(0);
+                pWindow.uFrameX += 12;
+                pWindow.uFrameWidth -= 24;
+                pWindow.uFrameY += 12;
+                pWindow.uFrameHeight -= 12;
+                pWindow.uFrameZ = pWindow.uFrameX + pWindow.uFrameWidth - 1;
+                pWindow.uFrameW = pWindow.uFrameY + pWindow.uFrameHeight - 1;
+                pColor = TargetColor(0xFF, 0xFF, 0x9B);
+                sprintf(pTmpBuf.data(), format_4E2D80, pColor, pStr);//"\f%05d%s\f00000\n"
+                pWindow.DrawTitleText(pFontCreate, 0, 0, 0, pTmpBuf.data(), 3);
+                pWindow.DrawText(pFontSmallnum, 1, pFontLucida->uFontHeight, 0, pHint, 0, 0, 0);
+                }
+            break;
+            }
+        default:
+            {
+            break;
+            }
+            }
+        dword_507BF0_is_there_popup_onscreen = 1;
+        viewparams->bRedrawGameUI = 1;
+        }
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/UI/UIRest.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -0,0 +1,197 @@
+#ifdef _MSC_VER
+#define _CRT_SECURE_NO_WARNINGS
+#endif
+
+#include <assert.h>
+
+
+#include "..\GUIWindow.h"
+#include "..\GUIFont.h"
+#include "..\Party.h"
+#include "..\AudioPlayer.h"
+#include "..\Outdoor.h"
+#include "..\LOD.h"
+#include "..\Viewport.h"
+#include "..\Time.h"
+#include "..\texts.h"
+
+#include "..\mm7_data.h"
+
+
+
+//----- (0041F6C1) --------------------------------------------------------
+void RestUI_Load()
+{
+    Player *v0; // eax@10
+
+    if ( !dword_506F14 )
+        pAudioPlayer->StopChannels(-1, -1);
+    if ( pCurrentScreen != SCREEN_GAME)
+    {
+        pGUIWindow_CurrentMenu->Release();
+        pCurrentScreen = SCREEN_GAME;
+        viewparams->bRedrawGameUI = true;
+    }
+    pEventTimer->Pause();
+    if ( dword_506F14 != 2 )
+        GUIWindow::Create(518, 450, 0, 0, WINDOW_PressedButton2, (int)pBtn_Rest, 0);
+    _506F18_num_hours_to_sleep = 0;
+    dword_506F14 = 0;
+    uRestUI_FoodRequiredToRest = 2;
+    if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor)
+        uRestUI_FoodRequiredToRest = pOutdoor->GetNumFoodRequiredToRestInCurrentPos(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z);
+    if ( PartyHasDragon() )
+        {
+        v0 = pParty->pPlayers;//[0].uClass;
+        while ( v0 <= &pParty->pPlayers[3] )
+            {
+            ++v0;
+            if ( v0 > &pParty->pPlayers[3] )
+                break;
+            }
+        if(v0->classType == PLAYER_CLASS_WARLOCK)
+            ++uRestUI_FoodRequiredToRest;
+        }
+    if ( CheckHiredNPCSpeciality(Porter) )
+        --uRestUI_FoodRequiredToRest;
+    if ( CheckHiredNPCSpeciality(QuarterMaster) )
+        uRestUI_FoodRequiredToRest -= 2;
+    if ( CheckHiredNPCSpeciality(Gypsy) )
+        --uRestUI_FoodRequiredToRest;
+    if ( uRestUI_FoodRequiredToRest < 1 )
+        uRestUI_FoodRequiredToRest = 1;
+    if ( !_stricmp(pCurrentMapName.data(), "d29.blv") && _449B57_test_bit(pParty->_quest_bits, 98) )
+        uRestUI_FoodRequiredToRest = 0;
+
+    ++pIcons_LOD->uTexturePacksCount;
+    if ( !pIcons_LOD->uNumPrevLoadedFiles )
+        pIcons_LOD->uNumPrevLoadedFiles = pIcons_LOD->uNumLoadedFiles;
+
+    pCurrentScreen = SCREEN_REST;
+    _507CD4_RestUI_hourglass_anim_controller = 0;
+    uTextureID_RestUI_restmain = pIcons_LOD->LoadTexture("restmain", TEXTURE_16BIT_PALETTE);
+    uTextureID_RestUI_restb1 = pIcons_LOD->LoadTexture("restb1", TEXTURE_16BIT_PALETTE);
+    uTextureID_RestUI_restb2 = pIcons_LOD->LoadTexture("restb2", TEXTURE_16BIT_PALETTE);
+    uTextureID_RestUI_restb3 = pIcons_LOD->LoadTexture("restb3", TEXTURE_16BIT_PALETTE);
+    uTextureID_RestUI_restb4 = pIcons_LOD->LoadTexture("restb4", TEXTURE_16BIT_PALETTE);
+    uTextureID_RestUI_restexit = pIcons_LOD->LoadTexture("restexit", TEXTURE_16BIT_PALETTE);
+
+    LoadActualSkyFrame();
+
+    pGUIWindow_CurrentMenu = GUIWindow::Create(0, 0, 640u, 480u, WINDOW_Rest, 0, 0);
+    pButton_RestUI_Exit          = pGUIWindow_CurrentMenu->CreateButton(280, 297, 154, 37, 1, 0, UIMSG_ExitRest,       0,   0, "", pIcons_LOD->GetTexture(uTextureID_RestUI_restexit), 0);
+    pButton_RestUI_Main          = pGUIWindow_CurrentMenu->CreateButton( 24, 154, 225, 37, 1, 0, UIMSG_Rest8Hour,      0, 'R', "", pIcons_LOD->GetTexture(uTextureID_RestUI_restb4), 0);
+    pButton_RestUI_WaitUntilDawn = pGUIWindow_CurrentMenu->CreateButton( 61, 232, 154, 33, 1, 0, UIMSG_AlreadyResting, 0, 'D', "", pIcons_LOD->GetTexture(uTextureID_RestUI_restb1), 0);
+    pButton_RestUI_Wait1Hour     = pGUIWindow_CurrentMenu->CreateButton( 61, 264, 154, 33, 1, 0, UIMSG_Wait1Hour,      0, 'H', "", pIcons_LOD->GetTexture(uTextureID_RestUI_restb2), 0);
+    pButton_RestUI_Wait5Minutes  = pGUIWindow_CurrentMenu->CreateButton( 61, 296, 154, 33, 1, 0, UIMSG_Wait5Minutes,   0, 'M', "", pIcons_LOD->GetTexture(uTextureID_RestUI_restb3), 0);
+}
+
+//----- (0041FA01) --------------------------------------------------------
+void RestUI_Draw()
+{
+    int live_characters; // esi@1
+    unsigned int v3; // eax@15
+    //char v4; // al@17
+    bool v5; // eax@21
+    GUIButton tmp_button; // [sp+8h] [bp-DCh]@19
+    //double v7; // [sp+C4h] [bp-20h]@17
+    float v8; // [sp+CCh] [bp-18h]@17
+    __int64 v9; // [sp+D0h] [bp-14h]@17
+    unsigned int am_pm_hours; // [sp+D8h] [bp-Ch]@9
+    __int16 shadow_color; // [sp+DCh] [bp-8h]@1
+    int text_color; // [sp+E0h] [bp-4h]@1
+
+    live_characters = 0;
+    text_color =   TargetColor(10, 0, 0);
+    shadow_color = TargetColor(230, 214, 193);
+    for(int i=1; i<5; ++i)
+        if ( !pPlayers[i]->pConditions[Player::Condition_Dead] && !pPlayers[i]->pConditions[Player::Condition_Eradicated] && pPlayers[i]->sHealth > 0 )
+            ++live_characters;
+
+    if ( live_characters )
+        {
+        pRenderer->DrawTextureIndexed(8, 8, pIcons_LOD->GetTexture(uTextureID_RestUI_restmain));
+        am_pm_hours = pParty->uCurrentHour;
+        dword_506F1C = pGUIWindow_CurrentMenu->pCurrentPosActiveItem;
+        if ( (signed int)pParty->uCurrentHour <= 12 )
+            {
+            if ( !am_pm_hours )
+                am_pm_hours = 12;
+            }
+        else
+            {
+            am_pm_hours -= 12;
+            }
+        pRenderer->DrawTextureIndexed(16u, 26u, pTexture_RestUI_CurrentSkyFrame);
+        if ( pTexture_RestUI_CurrentHourglassFrame )
+            {
+            pTexture_RestUI_CurrentHourglassFrame->Release();
+            pIcons_LOD->SyncLoadedFilesCount();
+            }
+        v3 = pEventTimer->uTimeElapsed + _507CD4_RestUI_hourglass_anim_controller;
+        _507CD4_RestUI_hourglass_anim_controller += pEventTimer->uTimeElapsed;
+        if ( (unsigned int)_507CD4_RestUI_hourglass_anim_controller >= 512 )
+            {
+            v3 = 0;
+            _507CD4_RestUI_hourglass_anim_controller = 0;
+            }
+        v9 = v3;
+        v8 = (double)v3 / 512.0 * 120.0;
+        //v7 = v8 + 6.7553994e15;
+        HIDWORD(v9) = floorf(v8 + 0.5f);//LODWORD(v7);
+        hourglass_icon_idx = (int)floorf(v8 + 0.5f) % 256 + 1;//LOBYTE(v7) + 1;
+        //hourglass_icon_idx = v4;
+        if (hourglass_icon_idx >= 120 )
+            hourglass_icon_idx = 1;
+
+        sprintf(pTmpBuf.data(), "hglas%03d", hourglass_icon_idx);
+        pTexture_RestUI_CurrentHourglassFrame = pIcons_LOD->LoadTexturePtr(pTmpBuf.data(), TEXTURE_16BIT_PALETTE);
+        pRenderer->DrawTextureIndexed(267, 159, pTexture_RestUI_CurrentHourglassFrame);
+        memset(&tmp_button, 0, sizeof(GUIButton));
+        tmp_button.uX = 24;
+        tmp_button.uY = 154;
+
+        tmp_button.uZ = 194;
+        tmp_button.uW = 190;
+
+        tmp_button.uWidth = 171;
+        tmp_button.uHeight = 37;
+
+        tmp_button.pParent = pButton_RestUI_WaitUntilDawn->pParent;
+        tmp_button.DrawLabel(pGlobalTXT_LocalizationStrings[183], pFontCreate, text_color, shadow_color);
+        tmp_button.pParent = 0;
+        sprintf(pTmpBuf.data(), "\r408%d", uRestUI_FoodRequiredToRest);
+        pGUIWindow_CurrentMenu->DrawText(pFontCreate, 0, 164, text_color, pTmpBuf.data(), 0, 0, shadow_color);
+        pButton_RestUI_WaitUntilDawn->DrawLabel(pGlobalTXT_LocalizationStrings[237], pFontCreate, text_color, shadow_color);
+        pButton_RestUI_Wait1Hour->DrawLabel(pGlobalTXT_LocalizationStrings[239], pFontCreate, text_color, shadow_color);
+        pButton_RestUI_Wait5Minutes->DrawLabel(pGlobalTXT_LocalizationStrings[238], pFontCreate, text_color, shadow_color);
+        pButton_RestUI_Exit->DrawLabel(pGlobalTXT_LocalizationStrings[81], pFontCreate, text_color, shadow_color);
+        memset(&tmp_button, 0, sizeof(GUIButton));
+        tmp_button.uX = 45;
+        tmp_button.uY = 199;
+
+        tmp_button.uZ = 229;
+        tmp_button.uW = 228;
+
+        tmp_button.uWidth = 185;
+        tmp_button.uHeight = 30;
+
+        tmp_button.pParent = pButton_RestUI_WaitUntilDawn->pParent;
+        tmp_button.DrawLabel(pGlobalTXT_LocalizationStrings[236], pFontCreate, text_color, shadow_color);
+        tmp_button.pParent = 0;
+        v5 = (pParty->uCurrentHour >= 12 && pParty->uCurrentHour < 24)? 1:0;
+        sprintf(pTmpBuf.data(), "%d:%02d %s", am_pm_hours, pParty->uCurrentMinute, aAMPMNames[v5]);
+        pGUIWindow_CurrentMenu->DrawText(pFontCreate, 368, 168, text_color, pTmpBuf.data(), 0, 0, shadow_color);
+        sprintf(pTmpBuf.data(), "%s\r190%d", pGlobalTXT_LocalizationStrings[56], pParty->uDaysPlayed + 1);
+        pGUIWindow_CurrentMenu->DrawText(pFontCreate, 350, 190, text_color, pTmpBuf.data(), 0, 0, shadow_color);
+        sprintf(pTmpBuf.data(), "%s\r190%d", pGlobalTXT_LocalizationStrings[146], pParty->uCurrentMonth + 1);
+        pGUIWindow_CurrentMenu->DrawText(pFontCreate, 350, 222, text_color, pTmpBuf.data(), 0, 0, shadow_color);
+        sprintf(pTmpBuf.data(), "%s\r190%d", pGlobalTXT_LocalizationStrings[245], pParty->uCurrentYear);
+        pGUIWindow_CurrentMenu->DrawText(pFontCreate, 350, 254, text_color, pTmpBuf.data(), 0, 0, shadow_color);
+        if ( dword_506F14 )
+            Sleep6Hours();
+        }
+    else
+      GUIWindow::Create(pButton_RestUI_Exit->uX, pButton_RestUI_Exit->uY, 0, 0, WINDOW_CloseRestWindowBtn, 
+      (int)pButton_RestUI_Exit, pGlobalTXT_LocalizationStrings[81]); // "Exit Rest"
+    }
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/UI/UISaveLoad.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -0,0 +1,441 @@
+#ifdef _MSC_VER
+#define _CRT_SECURE_NO_WARNINGS
+#endif
+
+#include <assert.h>
+#include <io.h>
+#include "..\MM7.h"
+
+#include "..\Keyboard.h"
+
+#include "..\MapInfo.h"
+#include "..\GUIWindow.h"
+#include "..\GUIFont.h"
+#include "..\Render.h"
+#include "..\IndoorCamera.h"
+#include "..\LOD.h"
+#include "..\Allocator.h"
+#include "..\SaveLoad.h"
+#include "..\texts.h"
+
+#include "..\mm7_data.h"
+
+
+//----- (004601B7) --------------------------------------------------------
+static void UI_DrawSaveLoad(bool save)
+{
+  unsigned __int16 v1; // bx@1
+  unsigned int v2; // edi@4
+  unsigned int v3; // eax@4
+  unsigned int v4; // eax@8
+  int v5; // edi@8
+  unsigned int v6; // eax@8
+  unsigned int pMapID; // eax@10
+  signed __int64 v8; // qax@10
+  unsigned int v9; // ebx@10
+  unsigned __int64 v10; // qax@10
+  __int64 v11; // qax@10
+  char v12; // di@10
+  unsigned __int64 v13; // qtt@10
+  unsigned int v14; // ecx@10
+  __int64 pOurHour; // qax@10
+  int v16; // edi@10
+  signed int pHour; // ebx@22
+  //const char *v18; // ST14_4@32
+  int v19; // eax@32
+  const char *v20; // ST18_4@32
+  int v21; // eax@32
+  //const char *v22; // ST14_4@32
+  int v23; // eax@32
+  const char *pSlotName; // edi@36
+  int v25; // eax@43
+  GUIWindow pWindow; // [sp+Ch] [bp-78h]@8
+  /*unsigned int Dst; // [sp+Ch] [bp-78h]@8
+  unsigned int v27; // [sp+10h] [bp-74h]@8
+  int v28; // [sp+14h] [bp-70h]@8
+  int v29; // [sp+18h] [bp-6Ch]@8
+  unsigned int v30; // [sp+1Ch] [bp-68h]@8
+  unsigned int v31; // [sp+20h] [bp-64h]@8*/
+  int pMinutes; // [sp+60h] [bp-24h]@10
+  int pMonthNum; // [sp+68h] [bp-1Ch]@10
+  unsigned int pSaveFiles; // [sp+70h] [bp-14h]@10
+  __int64 pAMPM2; // [sp+74h] [bp-10h]@10
+  int pYear; // [sp+7Ch] [bp-8h]@10
+  //int a4; // [sp+80h] [bp-4h]@1
+  int pFilesID;
+
+  v1 = 255;
+  TargetColor(0xFF, 0xFF, 0xFF);
+  TargetColor(0xFF, 0xFF, 0x9B);
+  pRenderer->BeginScene();
+  if ( GetCurrentMenuID() != MENU_SAVELOAD && GetCurrentMenuID() != MENU_LoadingProcInMainMenu )
+  {
+    pRenderer->DrawTextureIndexed(8, 8, pIcons_LOD->GetTexture(uTextureID_loadsave));
+    if (save)
+    {
+      v2 = uTextureID_save_up;
+      v3 = uTextureID_LS_saveU;
+    }
+    else
+    {
+      v2 = uTextureID_load_up;
+      v3 = uTextureID_LS_loadU;
+    }
+    pRenderer->DrawTextureIndexed(241, 302, pIcons_LOD->GetTexture(v3));
+    pRenderer->DrawTextureIndexed (18, 139, pIcons_LOD->GetTexture(v2));
+    pRenderer->DrawTextureIndexed(351, 302, pIcons_LOD->GetTexture(uTextureID_x_u));
+    v1 = 255;
+  }
+  if ( pSavegameUsedSlots[uLoadGameUI_SelectedSlot] )
+  {
+    memset(&pWindow, 0, 0x54);
+    pWindow.uFrameX = pGUIWindow_CurrentMenu->uFrameX + 240;
+    v4 = pGUIWindow_CurrentMenu->uFrameY - pFontSmallnum->uFontHeight;
+    pWindow.uFrameWidth = 220;
+    v4 += 157;
+    pWindow.uFrameY = v4;
+    v5 = pFontSmallnum->uFontHeight;
+    pWindow.uFrameZ = pWindow.uFrameX + 219;
+    pWindow.uFrameHeight = v5;
+    pWindow.uFrameW = v5 + v4 - 1;
+    v6 = uLoadGameUI_SelectedSlot;
+    if (pSavegameThumbnails[uLoadGameUI_SelectedSlot].pPixels)
+    {
+      pRenderer->DrawTextureRGB(pGUIWindow_CurrentMenu->uFrameX + 276, pGUIWindow_CurrentMenu->uFrameY + 171, &pSavegameThumbnails[uLoadGameUI_SelectedSlot]);
+      v6 = uLoadGameUI_SelectedSlot;
+    }
+    pMapID = pMapStats->GetMapInfo(pSavegameHeader[v6].pLocationName);
+    pWindow.DrawTitleText(pFontSmallnum, 0, 0, 0, pMapStats->pInfos[pMapID].pName, 3);
+    v8 = (signed __int64)(pSavegameHeader[uLoadGameUI_SelectedSlot].uWordTime * 0.234375) / 60;
+    pMinutes = (int)(((signed __int64)(pSavegameHeader[uLoadGameUI_SelectedSlot].uWordTime * 0.234375) / 60) >> 32);
+    v9 = v8;
+    v8 /= 60i64;
+    pAMPM2 = v8;
+    v10 = (unsigned int)v8 / 24;
+    pSaveFiles = v10;
+    v11 = (unsigned int)(v10 / 7);
+    v12 = v11;
+    LODWORD(v13) = (unsigned int)v11 >> 2;
+    HIDWORD(v13) = HIDWORD(v11);
+    pMonthNum = v13 % 12;
+    pYear = v13 / 12;
+    pMinutes = (int)__PAIR__(pMinutes, v9) % 60;
+    pOurHour = pAMPM2 % 24;
+    v14 = (unsigned __int64)(pAMPM2 % 24) >> 32;
+    LODWORD(pAMPM2) = pAMPM2 % 24;
+    HIDWORD(pOurHour) = pSaveFiles % 28;
+    pYear += game_starting_year;
+    v16 = v12 & 3;
+    pWindow.uFrameY = pGUIWindow_CurrentMenu->uFrameY + 261;
+    HIDWORD(pAMPM2) = v14 == 0 && ((signed int)v14 > 0 || (unsigned int)pOurHour >= 12)
+                && (signed int)v14 <= 0 && (v14 != 0 || (unsigned int)pOurHour < 24);
+    if ( v14  != 0 || ((signed int)v14 <= 0) && (unsigned int)pOurHour <= 12 )
+    {
+      if ( !(v14 | (unsigned int)pOurHour) )
+      {
+        pSaveFiles = 0;
+        pHour = 12;
+        goto LABEL_23;
+      }
+    }
+    else
+    {
+      v14 = (__PAIR__(v14, (unsigned int)pOurHour) - 12) >> 32;
+      LODWORD(pOurHour) = pOurHour - 12;
+    }
+    pHour = pOurHour;
+    pSaveFiles = v14;
+LABEL_23:
+    auto day = aDayNames[HIDWORD(pOurHour) % 7];
+    auto ampm = aAMPMNames[HIDWORD(pAMPM2)];
+    auto month = aMonthNames[pMonthNum];
+    //sprintf(pTmpBuf.data(), "%s %d:%02d%s\n%d %s %d", _d, v17, (int)32, _a, 3, _m, pFilesID);
+    sprintf(pTmpBuf.data(), "%s %d:%02d%s\n%d %s %d", day, pHour, pMinutes, ampm, 7 * v16 + HIDWORD(pOurHour) % 7 + 1, month, pYear);
+    pWindow.DrawTitleText(pFontSmallnum, 0, 0, 0, pTmpBuf.data(), 3u);
+    v1 = 255;
+  }
+  if ( pGUIWindow_CurrentMenu->receives_keyboard_input_2 == WINDOW_INPUT_CONFIRMED)
+  {
+    pGUIWindow_CurrentMenu->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
+    strcpy((char *)&pSavegameHeader + 100 * uLoadGameUI_SelectedSlot, (const char *)pKeyActionMap->pPressedKeysBuffer);
+    pMessageQueue_50CBD0->AddMessage(UIMSG_SaveGame, 0, 0);
+  }
+  else
+  {
+    if ( pGUIWindow_CurrentMenu->receives_keyboard_input_2 == WINDOW_INPUT_CANCELLED)
+      pGUIWindow_CurrentMenu->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
+  }
+  if (GetCurrentMenuID() == MENU_LoadingProcInMainMenu)
+  {
+    //v18 = pGlobalTXT_LocalizationStrings[135];
+    v19 = pFontSmallnum->AlignText_Center(0xBA, pGlobalTXT_LocalizationStrings[135]);//""
+    pGUIWindow_CurrentMenu->DrawText(pFontSmallnum, v19 + 25, 220, 0, pGlobalTXT_LocalizationStrings[135], 0, 0, 0);
+    v20 = (const char *)(&pSavegameHeader[uLoadGameUI_SelectedSlot]);
+    v21 = pFontSmallnum->AlignText_Center(0xBA, (const char *)pSavegameHeader.data() + 100 * uLoadGameUI_SelectedSlot);
+    pGUIWindow_CurrentMenu->DrawTextInRect(pFontSmallnum, v21 + 25, 0x106, 0, v20, 185, 0);
+    //v22 = pGlobalTXT_LocalizationStrings[165];
+    v23 = pFontSmallnum->AlignText_Center(0xBA, pGlobalTXT_LocalizationStrings[165]);//", "
+    pGUIWindow_CurrentMenu->DrawText(pFontSmallnum, v23 + 25, 304, 0, pGlobalTXT_LocalizationStrings[165], 0, 0, 0);
+  }
+  else
+  {
+    if ( save )
+      pSaveFiles = 40;
+    else
+      pSaveFiles = uNumSavegameFiles;
+    int a4 = 199;
+    pFilesID = pSaveListPosition;
+    pSlotName = (const char *)(&pSavegameHeader[pSaveListPosition]);//draw name for save slot
+    do
+    {
+      if ( pFilesID >= (signed int)pSaveFiles )
+        break;
+      short clr;
+      HIDWORD(pAMPM2) = clr = (pFilesID == uLoadGameUI_SelectedSlot ? TargetColor(v1, v1, 0x64) : 0);
+      if ( pGUIWindow_CurrentMenu->receives_keyboard_input_2 != WINDOW_INPUT_IN_PROGRESS || pFilesID != uLoadGameUI_SelectedSlot )
+      {
+        pGUIWindow_CurrentMenu->DrawTextInRect(pFontSmallnum, 0x1B, a4, clr, pSlotName, 185, 0);
+      }
+      else
+      {
+        v25 = pGUIWindow_CurrentMenu->DrawTextInRect(pFontSmallnum, 0x1B, a4, clr, (const char *)pKeyActionMap->pPressedKeysBuffer, 175, 1);
+        pGUIWindow_CurrentMenu->DrawFlashingInputCursor(v25 + 27, a4, pFontSmallnum);
+      }
+      a4 += 21;
+      ++pFilesID;
+      pSlotName += 100;
+    }
+    while ( a4 < 346 );
+  }
+  pRenderer->EndScene();
+}
+// 6A0C9C: using guessed type int dword_6A0C9C;
+
+//----- (004606F7) --------------------------------------------------------
+void LoadUI_Draw()
+{
+  UI_DrawSaveLoad(false);
+}
+
+//----- (004606FE) --------------------------------------------------------
+void SaveUI_Draw()
+{
+  UI_DrawSaveLoad(true);
+}
+
+
+//----- (0045E361) --------------------------------------------------------
+void LoadUI_Load(unsigned int uDialogueType)
+{
+    unsigned int v1; // ebp@5
+    unsigned int v2; // eax@5
+    //signed int v3; // ebp@11
+    FILE *v4; // eax@14
+    FILE *v5; // eax@18
+    unsigned int v6; // eax@25
+    GUIButton *v7; // eax@27
+    const char *v8; // [sp-8h] [bp-26Ch]@25
+    //char *v9; // [sp-4h] [bp-268h]@19
+    enum TEXTURE_TYPE v10; // [sp-4h] [bp-268h]@25
+    unsigned int uDialogueType_; // [sp+10h] [bp-254h]@1
+    //RGBTexture *pTex; // [sp+10h] [bp-254h]@12
+    //SavegameHeader *Dest; // [sp+14h] [bp-250h]@12
+    //const char *Str1; // [sp+18h] [bp-24Ch]@12
+    LODWriteableFile pLODFile; // [sp+1Ch] [bp-248h]@1
+    int v16; // [sp+260h] [bp-4h]@1
+
+    uDialogueType_ = uDialogueType;
+    dword_6BE138 = -1;
+    pIcons_LOD->_inlined_sub2();
+
+    memset(pSavegameUsedSlots.data(), 0, sizeof(pSavegameUsedSlots));
+    memset(pSavegameThumbnails.data(), 0, 45 * sizeof(RGBTexture));
+    uTextureID_loadsave = pIcons_LOD->LoadTexture("loadsave", TEXTURE_16BIT_PALETTE);
+    uTextureID_load_up = pIcons_LOD->LoadTexture("load_up", TEXTURE_16BIT_PALETTE);
+    uTextureID_save_up = pIcons_LOD->LoadTexture("save_up", TEXTURE_16BIT_PALETTE);
+    uTextureID_LS_loadU = pIcons_LOD->LoadTexture("LS_loadU", TEXTURE_16BIT_PALETTE);
+    uTextureID_LS_saveU = pIcons_LOD->LoadTexture("LS_saveU", TEXTURE_16BIT_PALETTE);
+    uTextureID_x_u = pIcons_LOD->LoadTexture("x_u", TEXTURE_16BIT_PALETTE);
+    if ( uDialogueType_ )
+        {
+        pRenderer->DrawTextureIndexed(8, 8, pIcons_LOD->GetTexture(uTextureID_loadsave));
+        if ( pCurrentScreen == SCREEN_SAVEGAME )
+            {
+            v1 = uTextureID_save_up;
+            v2 = uTextureID_LS_saveU;
+            }
+        else
+            {
+            v1 = uTextureID_load_up;
+            v2 = uTextureID_LS_loadU;
+            }
+        pRenderer->DrawTextureIndexed(241, 302, pIcons_LOD->GetTexture(v2));
+        pRenderer->DrawTextureIndexed( 18, 141, pIcons_LOD->GetTexture(v1));
+        pRenderer->DrawTextureIndexed(351, 302, pIcons_LOD->GetTexture(uTextureID_x_u));
+        }
+    else
+        {
+        pRenderer->DrawTextureRGB(0, 0, &pTexture_PCX);
+        }
+    pGUIWindow_CurrentMenu = GUIWindow::Create(saveload_dlg_xs[uDialogueType_], saveload_dlg_ys[uDialogueType_], saveload_dlg_zs[uDialogueType_],
+        saveload_dlg_ws[uDialogueType_], WINDOW_MainMenu_Load, 0, 0);
+    pGUIWindow_CurrentMenu->DrawText(pFontSmallnum, 25, 199, 0, pGlobalTXT_LocalizationStrings[505], 0, 0, 0);// "Reading..."
+    pRenderer->Present();
+    pSavegameList->Initialize(0);
+    if ( pSaveListPosition > (signed int)uNumSavegameFiles )
+        {
+        pSaveListPosition = 0;
+        uLoadGameUI_SelectedSlot = 0;
+        }
+    pLODFile.AllocSubIndicesAndIO(0x12C, 0);
+    assert(sizeof(SavegameHeader) == 0x64);
+    //v3 = 0;
+    for (uint i = 0; i < uNumSavegameFiles; ++i)
+        {
+
+        sprintf(pTmpBuf.data(), "saves\\%s", pSavegameList->pFileList[i].pSaveFileName);
+        if (_access(pTmpBuf.data(), 6))
+            {
+            pSavegameUsedSlots[i] = 0;
+            strcpy(pSavegameHeader[i].pName, pGlobalTXT_LocalizationStrings[72]); // "Empty"
+            continue;
+            }
+        pLODFile.LoadFile(pTmpBuf.data(), 1);
+        v4 = pLODFile.FindContainer("header.bin", true);
+        if ( v4 )
+            fread(&pSavegameHeader[i], 0x64, 1, v4);
+        if ( !_stricmp(pSavegameList->pFileList[i].pSaveFileName, pGlobalTXT_LocalizationStrings[613]) )// "AutoSave.MM7"
+            strcpy(pSavegameHeader[i].pName, pGlobalTXT_LocalizationStrings[16]);// "Autosave"
+        v5 = pLODFile.FindContainer("image.pcx", true);
+        if ( !v5 )
+            {
+            pSavegameUsedSlots[i] = 0;
+            strcpy(pSavegameList->pFileList[i].pSaveFileName, "");
+            }
+        else
+            {
+            pSavegameThumbnails[i].LoadFromFILE(v5, 0, true);
+            pLODFile.CloseWriteFile();
+            pSavegameUsedSlots[i] = 1;
+            }
+        }
+
+    //LABEL_24:
+    pLODFile.FreeSubIndexAndIO();
+    if ( pCurrentScreen == SCREEN_SAVEGAME )
+        {
+        uTextureID_x_d = pIcons_LOD->LoadTexture("x_d", TEXTURE_16BIT_PALETTE);
+        uTextureID_LS_ = pIcons_LOD->LoadTexture("LS_saveD",TEXTURE_16BIT_PALETTE);
+        }
+    else
+        {
+        uTextureID_x_d = pIcons_LOD->LoadTexture("x_d", TEXTURE_16BIT_PALETTE);
+        uTextureID_LS_ = pIcons_LOD->LoadTexture("LS_loadD",TEXTURE_16BIT_PALETTE);
+        }
+    uTextureID_AR_UP_DN = pIcons_LOD->LoadTexture("AR_UP_DN", TEXTURE_16BIT_PALETTE);
+    uTextureID_AR_DN_DN = pIcons_LOD->LoadTexture("AR_DN_DN", TEXTURE_16BIT_PALETTE);
+    pGUIWindow_CurrentMenu->CreateButton(21, 198, 191, 18, 1, 0, UIMSG_SelectLoadSlot, 0, 0, "", 0);
+    pGUIWindow_CurrentMenu->CreateButton(21, 219, 191, 18, 1, 0, UIMSG_SelectLoadSlot, 1, 0, "", 0);
+    pGUIWindow_CurrentMenu->CreateButton(21, 240, 191, 18, 1, 0, UIMSG_SelectLoadSlot, 2, 0, "", 0);
+    pGUIWindow_CurrentMenu->CreateButton(21, 261, 191, 18, 1, 0, UIMSG_SelectLoadSlot, 3, 0, "", 0);
+    pGUIWindow_CurrentMenu->CreateButton(21, 282, 191, 18, 1, 0, UIMSG_SelectLoadSlot, 4, 0, "", 0);
+    pGUIWindow_CurrentMenu->CreateButton(21, 303, 191, 18, 1, 0, UIMSG_SelectLoadSlot, 5, 0, "", 0);
+    pGUIWindow_CurrentMenu->CreateButton(21, 324, 191, 18, 1, 0, UIMSG_SelectLoadSlot, 6, 0, "", 0);
+    pBtnLoadSlot  = pGUIWindow_CurrentMenu->CreateButton(241, 302, 105, 40, 1, 0, UIMSG_SaveLoadBtn, 0, 0, "", pIcons_LOD->GetTexture(uTextureID_LS_), 0);
+    pBtnCancel    = pGUIWindow_CurrentMenu->CreateButton(350, 302, 105, 40, 1, 0, UIMSG_Cancel, 0, 0, "", pIcons_LOD->GetTexture(uTextureID_x_d), 0);
+    pBtnArrowUp   = pGUIWindow_CurrentMenu->CreateButton(215, 199,  17, 17, 1, 0, UIMSG_ArrowUp, 0, 0, "", pIcons_LOD->GetTexture(uTextureID_AR_UP_DN), 0);
+    pBtnDownArrow = pGUIWindow_CurrentMenu->CreateButton(215, 323,  17, 17, 1, 0, UIMSG_DownArrow, uNumSavegameFiles, 0, "", pIcons_LOD->GetTexture(uTextureID_AR_DN_DN), 0);
+}
+
+//----- (0045E93E) --------------------------------------------------------
+void SaveUI_Load()
+{
+    unsigned int v0; // ebp@4
+    unsigned int v1; // eax@4
+    char *v3; // eax@7
+    FILE *v4; // eax@11
+    FILE *v5; // eax@11
+    LODWriteableFile v11; // [sp+1Ch] [bp-248h]@1
+
+    ++pIcons_LOD->uTexturePacksCount;
+    if ( !pIcons_LOD->uNumPrevLoadedFiles )
+        pIcons_LOD->uNumPrevLoadedFiles = pIcons_LOD->uNumLoadedFiles;
+    memset(pSavegameUsedSlots.data(), 0, 0xB4u);
+    memset(&pSavegameThumbnails, 0, 0x708u);
+    uTextureID_loadsave = pIcons_LOD->LoadTexture("loadsave", TEXTURE_16BIT_PALETTE);
+    uTextureID_load_up = pIcons_LOD->LoadTexture("load_up", TEXTURE_16BIT_PALETTE);
+    uTextureID_save_up = pIcons_LOD->LoadTexture("save_up", TEXTURE_16BIT_PALETTE);
+    uTextureID_LS_loadU = pIcons_LOD->LoadTexture("LS_loadU", TEXTURE_16BIT_PALETTE);
+    uTextureID_LS_saveU = pIcons_LOD->LoadTexture("LS_saveU", TEXTURE_16BIT_PALETTE);
+    uTextureID_x_u = pIcons_LOD->LoadTexture("x_u", TEXTURE_16BIT_PALETTE);
+    pRenderer->DrawTextureIndexed(8, 8, pIcons_LOD->GetTexture(uTextureID_loadsave));
+    if ( pCurrentScreen == SCREEN_SAVEGAME )
+    {
+        v0 = uTextureID_save_up;
+        v1 = uTextureID_LS_saveU;
+        }
+    else
+    {
+        v0 = uTextureID_load_up;
+        v1 = uTextureID_LS_loadU;
+        }
+    pRenderer->DrawTextureIndexed(0xF1u, 0x12Eu, pIcons_LOD->GetTexture(v1));
+    pRenderer->DrawTextureIndexed(0x15Fu, 0x12Eu, pIcons_LOD->GetTexture(uTextureID_x_u));
+    pRenderer->DrawTextureIndexed(0x12u, 0x8Du, pIcons_LOD->GetTexture(v0));
+    pGUIWindow_CurrentMenu->DrawText(pFontSmallnum, 25, 199, 0, pGlobalTXT_LocalizationStrings[505], 0, 0, 0);
+    pRenderer->Present();
+    pSavegameList->Initialize(1u);
+    v11.AllocSubIndicesAndIO(0x12Cu, 0);
+    //v2 = pSavegameUsedSlots;
+    // Dest = pSavegameHeader;
+    // this_ = pSavegameThumbnails;
+    // v8 = (char *)pSavegameList->pSavesNames;
+    for (uint i = 0; i < 40; ++i)
+        {
+        v3 = pSavegameList->pFileList[i].pSaveFileName;
+        if ( !*pSavegameList->pFileList[i].pSaveFileName )
+            v3 = "1.mm7";
+        sprintf(pTmpBuf.data(), "saves\\%s", v3);
+        if ( _access(pTmpBuf.data(), 0) || _access(pTmpBuf.data(), 6) )
+            {
+            pSavegameUsedSlots[i] = 0;
+            strcpy(pSavegameHeader[i].pName, pGlobalTXT_LocalizationStrings[LOCSTR_EMPTY]);
+            }
+        else
+            {
+            v11.LoadFile(pTmpBuf.data(), 1);
+            v4 = v11.FindContainer("header.bin", 1);
+            fread(&pSavegameHeader[i], 100, 1u, v4);
+            v5 = v11.FindContainer("image.pcx", 1);
+            if ( v5 )
+                {
+                pSavegameThumbnails[i].LoadFromFILE(v5, 0, 1u);
+                v11.CloseWriteFile();
+                pSavegameUsedSlots[i] = 1;
+                }
+            else
+                {
+                pSavegameUsedSlots[i] = 0;
+                }
+            }
+
+        }
+
+    v11.FreeSubIndexAndIO();
+    uTextureID_x_d = pIcons_LOD->LoadTexture("x_d", TEXTURE_16BIT_PALETTE);
+    uTextureID_LS_ = pIcons_LOD->LoadTexture("LS_saveD", TEXTURE_16BIT_PALETTE);
+    uTextureID_AR_UP_DN = pIcons_LOD->LoadTexture("AR_UP_DN", TEXTURE_16BIT_PALETTE);
+    uTextureID_AR_DN_DN = pIcons_LOD->LoadTexture("AR_DN_DN", TEXTURE_16BIT_PALETTE);
+    pGUIWindow_CurrentMenu = GUIWindow::Create(0, 0, 640, 480, WINDOW_SaveLoadButtons, 0, 0);
+    pGUIWindow_CurrentMenu->CreateButton(21, 198, 191, 18, 1, 0, UIMSG_SelectLoadSlot, 0, 0, "", 0);
+    pGUIWindow_CurrentMenu->CreateButton(21, 218, 191, 18, 1, 0, UIMSG_SelectLoadSlot, 1, 0, "", 0);
+    pGUIWindow_CurrentMenu->CreateButton(21, 238, 191, 18, 1, 0, UIMSG_SelectLoadSlot, 2, 0, "", 0);
+    pGUIWindow_CurrentMenu->CreateButton(21, 258, 191, 18, 1, 0, UIMSG_SelectLoadSlot, 3, 0, "", 0);
+    pGUIWindow_CurrentMenu->CreateButton(21, 278, 191, 18, 1, 0, UIMSG_SelectLoadSlot, 4, 0, "", 0);
+    pGUIWindow_CurrentMenu->CreateButton(21, 298, 191, 18, 1, 0, UIMSG_SelectLoadSlot, 5, 0, "", 0);
+    pGUIWindow_CurrentMenu->CreateButton(21, 318, 191, 18, 1, 0, UIMSG_SelectLoadSlot, 6, 0, "", 0);
+    pBtnLoadSlot  = pGUIWindow_CurrentMenu->CreateButton(241, 302, 105, 40, 1, 0, UIMSG_SaveLoadBtn, 0, 0, "", pIcons_LOD->GetTexture(uTextureID_LS_), 0);
+    pBtnCancel    = pGUIWindow_CurrentMenu->CreateButton(350, 302, 105, 40, 1, 0, UIMSG_Cancel, 0, 0, "", pIcons_LOD->GetTexture(uTextureID_x_d), 0);
+    pBtnArrowUp   = pGUIWindow_CurrentMenu->CreateButton(215, 199,  17, 17, 1, 0, UIMSG_ArrowUp, 0, 0, "", pIcons_LOD->GetTexture(uTextureID_AR_UP_DN), 0);
+    pBtnDownArrow = pGUIWindow_CurrentMenu->CreateButton(215, 323,  17, 17, 1, 0, UIMSG_DownArrow, 34, 0, "", pIcons_LOD->GetTexture(uTextureID_AR_DN_DN), 0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/UI/UIShops.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -0,0 +1,2732 @@
+#include "..\Items.h"
+#include "..\GUIWindow.h"
+#include "..\mm7_data.h"
+#include "..\texts.h"
+#include "UIHouses.h"
+#include "..\GUIFont.h"
+#include "..\Render.h"
+#include "..\Party.h"
+#include "..\Texture.h"
+#include "..\Mouse.h"
+#include "..\Events2D.h"
+#include "..\AudioPlayer.h"
+#include "..\MapInfo.h"
+#include "..\Viewport.h"
+
+//----- (004B910F) --------------------------------------------------------
+void __cdecl WeaponShopDialog()
+{
+  int v0; // ebx@1
+  int pNumActiveItem; // eax@6
+  signed int v2; // esi@8
+  ItemGen *v4; // eax@11
+  char *v5; // ecx@12
+  unsigned __int8 v6; // dl@13
+  char *v7; // edx@14
+  int v9; // ST08_4@16
+  int v10; // eax@16
+  signed int v11; // esi@18
+  int v12; // ST08_4@21
+  int v13; // eax@21
+  int v14; // edi@23
+  char **v15; // esi@23
+  int v16; // eax@24
+  //int v18; // edx@25
+  int v19; // edi@25
+  unsigned __int8 v20; // sf@25
+  GUIButton *pButton; // esi@27
+  int pNewItem; // eax@27
+  unsigned int v24; // ecx@27
+  int v25; // edx@27
+  unsigned int pColorText; // ax@27
+  signed int v27; // esi@32
+  int v28; // ST08_4@36
+  int v29; // eax@36
+  signed int v32; // esi@41
+  unsigned int v33; // esi@43
+  int v34; // eax@43
+  unsigned int v35; // eax@44
+  int v36; // eax@46
+  __int32 v37; // ecx@51
+  int v40; // eax@53
+  char *v41; // eax@55
+  unsigned int v43; // ecx@55
+  const char **v44; // edx@55
+  int v45; // eax@55
+  int v47; // eax@59
+  const char **v48; // eax@63
+  unsigned int v49; // esi@65
+  Texture *v50; // eax@65
+  int v51; // edi@65
+  int v52; // esi@70
+  Texture *v53; // ST1C_4@70
+  int v54; // edi@70
+  signed int v55; // ecx@73
+  SHORT v56; // di@82
+  bool v57; // eax@82
+  const char *v58; // ecx@84
+  POINT *v59; // esi@89
+  LONG v60; // ecx@90
+  int v61; // eax@90
+  int v62; // ecx@90
+  ItemGen *pItemInShop; // esi@90
+  int v64; // eax@95
+  int all_text_height; // esi@96
+  char **v66; // edi@96
+  int v67; // eax@97
+  int v69; // edx@98
+  int v70; // edi@98
+  int v71;
+  const char **v72; // eax@100
+  int pTextHeight; // eax@100
+  unsigned int v74; // ecx@100
+  int v78; // [sp-14h] [bp-10Ch]@14
+  ItemGen *v79; // [sp-10h] [bp-108h]@12
+  int v80; // [sp-10h] [bp-108h]@14
+  void *v81; // [sp-Ch] [bp-104h]@12
+  unsigned __int16 v82; // [sp-Ch] [bp-104h]@14
+  int v83; // [sp-8h] [bp-100h]@11
+  char *v84; // [sp-8h] [bp-100h]@14
+  __int64 *v85; // [sp-4h] [bp-FCh]@11
+  unsigned int v86; // [sp-4h] [bp-FCh]@14
+  POINT v87; // [sp+Ch] [bp-ECh]@8
+  POINT v88; // [sp+14h] [bp-E4h]@18
+  POINT v89; // [sp+1Ch] [bp-DCh]@89
+  POINT v90; // [sp+24h] [bp-D4h]@19
+  POINT v91; // [sp+2Ch] [bp-CCh]@89
+  POINT v92; // [sp+34h] [bp-C4h]@9
+  POINT v93; // [sp+3Ch] [bp-BCh]@33
+  POINT v94; // [sp+44h] [bp-B4h]@18
+  POINT v95; // [sp+4Ch] [bp-ACh]@32
+  POINT v96; // [sp+54h] [bp-A4h]@18
+  POINT v97; // [sp+5Ch] [bp-9Ch]@32
+  POINT a2; // [sp+64h] [bp-94h]@8
+  POINT v99; // [sp+6Ch] [bp-8Ch]@32
+  POINT v100; // [sp+74h] [bp-84h]@8
+  GUIWindow dialog_window; // [sp+7Ch] [bp-7Ch]@1
+  char *Str; // [sp+D0h] [bp-28h]@55
+  __int32 v103; // [sp+D4h] [bp-24h]@25
+  int pColorYellow; // [sp+D8h] [bp-20h]@1
+  int pColorWhite; // [sp+DCh] [bp-1Ch]@1
+  POINT v106; // [sp+E0h] [bp-18h]@8
+  Player *pPlayer; // [sp+E8h] [bp-10h]@1
+  int pItemNum; // [sp+ECh] [bp-Ch]@26
+  const char **v109; // [sp+F0h] [bp-8h]@26
+  unsigned __int8 v110; // [sp+F7h] [bp-1h]@16
+  int pNumString;
+
+  pPlayer = pPlayers[uActiveCharacter];
+  memcpy(&dialog_window, window_SpeakInHouse, sizeof(dialog_window));
+  dialog_window.uFrameX = 483;
+  dialog_window.uFrameWidth = 148;
+  dialog_window.uFrameZ = 334;
+  pColorWhite = TargetColor(0xFFu, 0xFFu, 0xFFu);
+  pColorYellow = TargetColor(0xE1u, 0xCDu, 0x23u);
+
+  switch(dialog_menu_id)
+  {
+    case HOUSE_DIALOGUE_MAIN:
+    {
+      pNumActiveItem = sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win();
+      if ( pNumActiveItem )
+      {
+        pShopOptions[0] = pGlobalTXT_LocalizationStrings[134];
+        pShopOptions[1] = pGlobalTXT_LocalizationStrings[152];
+        pShopOptions[2] = pGlobalTXT_LocalizationStrings[159];
+        pShopOptions[3] = pGlobalTXT_LocalizationStrings[160];
+        all_text_height = 0;
+        for (int i = 0; i < 4; ++i)//while ( (signed int)v15 < (signed int)&unk_F8B1C8 );
+          all_text_height += pFontArrus->CalcTextHeight(pShopOptions[i], &dialog_window, 0, 0);
+        v103 = (174 - all_text_height) / 4;
+        pNumActiveItem = pDialogueWindow->pStartingPosActiveItem;
+        v19 = (174 - 4 * (174 - all_text_height) / 4 - all_text_height) / 2 - (174 - all_text_height) / 4 / 2 + 138;
+        v20 = -pDialogueWindow->pNumPresenceButton < 0;
+        if ( v20 ^ (pNumActiveItem > pNumActiveItem + pDialogueWindow->pNumPresenceButton ))
+        {
+          pItemNum = 2;
+          pNumString = 0;
+          do
+          {
+            pButton = pDialogueWindow->GetControl(pItemNum);
+            pButton->uY = v103 + v19;
+            pTextHeight = pFontArrus->CalcTextHeight((const char *)pShopOptions[pNumString], &dialog_window, 0, 0);
+            pButton->uHeight = pTextHeight;
+            v19 = pButton->uY + pTextHeight - 1;
+            pButton->uW = v19;
+            pColorText = pColorYellow;
+            if ( pDialogueWindow->pCurrentPosActiveItem != pItemNum )
+              pColorText = pColorWhite;
+            dialog_window.DrawTitleText(pFontArrus, 0, pButton->uY, pColorText, (const char *)pShopOptions[pNumString], 3);
+            ++pItemNum;
+            ++pNumString;
+            pNumActiveItem = pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem;
+          }
+          while ( pItemNum < pNumActiveItem );
+        }
+      }
+      break;
+    }
+
+    case HOUSE_DIALOGUE_SHOP_BUY_STANDARD:
+    {
+      pRenderer->DrawTextureIndexed(8, 8, ShopTexture);
+      v48 = 0;
+      pItemNum = 0;
+      v109 = 0;
+      do
+      {
+        //  if ( pParty->field_777C[9 * (int)&v48[3 * (unsigned int)window_SpeakInHouse->ptr_1C]] )
+        if ( pParty->StandartItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][(int)v48].uItemID)
+        {
+          v49 = word_F8B158[(signed int)v48];
+          v50 = ItemsInShopTexture[(signed int)v48];
+          v49 += 30;
+          v51 = 60 - ((signed int)v50->uTextureWidth >> 1);
+          pRenderer->DrawTextureTransparent(v51 + pItemNum, v49, v50);
+          sub_40F92A(&pRenderer->pActiveZBuffer[v51 + pItemNum + 640 * v49], ItemsInShopTexture[(signed int)v109], (int)((char *)v109 + 1));
+          v48 = v109;
+        }
+        pItemNum += 70;
+        v48 = (const char **)((char *)v48 + 1);
+        v109 = v48;
+      }
+      while ( (signed int)v48 < 6 );
+      pNumActiveItem = sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win();
+      if ( pNumActiveItem )
+      {
+        v55 = 0;
+        v106.x = 0;
+        v106.x = 0;
+        do
+        {
+          if ( pParty->StandartItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][v55].uItemID)//9 * (v55 + 12 * (unsigned int)window_SpeakInHouse->ptr_1C)] )
+            ++v106.x;
+          ++v55;
+        }
+        while ( v55 < 6 );
+        v56 = GetAsyncKeyState(17);
+        v57 = pPlayer->CanSteal();
+        Str = (char *)v57;
+        if ( v56 && v57 )
+        {
+          v58 = pGlobalTXT_LocalizationStrings[185];
+        }
+        else
+        {
+          v58 = pGlobalTXT_LocalizationStrings[195];
+          if ( dialog_menu_id != HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
+            v58 = pGlobalTXT_LocalizationStrings[196];
+        }
+        DrawTextAtStatusBar(v58, 0);
+        if ( v106.x )
+        {
+          v59 = pMouse->GetCursorPos(&v91);
+          pNumActiveItem = v59->x + pSRZBufferLineOffsets[pMouse->GetCursorPos(&v89)->y];
+          if ( pRenderer->pActiveZBuffer[pNumActiveItem] & 0xFFFF )
+          {
+            v60 = (pRenderer->pActiveZBuffer[pNumActiveItem] & 0xFFFF) - 1;
+            v106.x = v60;
+            v61 = (int)window_SpeakInHouse->ptr_1C;//maybe ptr_1C - BuildID_2Events
+            //  v62 = 9 * (v60 + 12 * v61);
+            pItemInShop = (ItemGen *)&pParty->StandartItemsInShops[(int)v61][v60];
+            if ( dialog_menu_id != HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
+              pItemInShop = &pParty->SpecialItemsInShops[(int)v61][v60];
+            if ( !v56 || !Str )
+            {
+              v64 = pPlayer->SelectPhrasesTransaction(pItemInShop, BildingType_WeaponShop, v61, 2);
+              v7 = BuilDialogueString((char *)pMerchantsBuyPhrases[v64], uActiveCharacter - 1, pItemInShop, (char *)window_SpeakInHouse->ptr_1C, 2, 0);
+              pTextHeight = pFontArrus->CalcTextHeight(v7, &dialog_window, 0, 0);
+              dialog_window.DrawTitleText(pFontArrus, 0, (174 - pTextHeight) / 2 + 138, pColorWhite, v7, 3);
+            }
+            else
+            {
+              v7 = BuilDialogueString(pGlobalTXT_LocalizationStrings[181], uActiveCharacter - 1, pItemInShop, (char *)window_SpeakInHouse->ptr_1C, 2, 0);
+              pTextHeight = pFontArrus->CalcTextHeight(v7, &dialog_window, 0, 0);
+              dialog_window.DrawTitleText(pFontArrus, 0, (174 - pTextHeight) / 2 + 138, pColorWhite, v7, 3);
+            }
+          }
+        }
+        else
+        {
+          dialog_window.DrawCurrentTime( pParty->field_3C.field_50[(unsigned int)window_SpeakInHouse->ptr_1C]  - pParty->uTimePlayed);
+          pNumActiveItem = 0; //added
+        }
+      }
+      break;
+    }
+
+    case HOUSE_DIALOGUE_SHOP_SELL:
+    {
+      draw_leather();
+      CharacterUI_InventoryTab_Draw(pPlayers[uActiveCharacter], true);
+      DrawTextAtStatusBar(pGlobalTXT_LocalizationStrings[199], 0);
+      if ( !sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
+        return;
+      if((v11 = pMouse->GetCursorPos(&v96)->x - 14, v106.x = (v11 >> 5) + 14 * ((pMouse->GetCursorPos(&v88)->y - 17) >> 5),
+        pMouse->GetCursorPos(&v94)->x <= 13) || pMouse->GetCursorPos(&v90)->x >= 462 
+        || (pNumActiveItem = pPlayer->GetItemIDAtInventoryIndex((int *)&v106.x), !pNumActiveItem) )
+        return;
+      v79 = (ItemGen *)&pPlayer->pInventoryItems[pNumActiveItem - 1];
+      v13 = pPlayer->SelectPhrasesTransaction(v79, BildingType_WeaponShop, (int)window_SpeakInHouse->ptr_1C, 3);
+      v7 = BuilDialogueString((char *)pMerchantsSellPhrases[v13], uActiveCharacter - 1, v79, (char *)window_SpeakInHouse->ptr_1C, 3, 0);
+      pTextHeight = pFontArrus->CalcTextHeight(v7, &dialog_window, 0, 0);
+      dialog_window.DrawTitleText(pFontArrus, 0, (174 - pTextHeight) / 2 + 138, pColorWhite, v7, 3);
+      break;
+    }
+
+    case HOUSE_DIALOGUE_SHOP_IDENTIFY:
+    {
+      draw_leather();
+      CharacterUI_InventoryTab_Draw(pPlayers[uActiveCharacter], true);
+      DrawTextAtStatusBar(pGlobalTXT_LocalizationStrings[197], 0);
+      if ( !sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
+        return;
+      if((v2 = pMouse->GetCursorPos(&a2)->x - 14, v106.x = (v2 >> 5) + 14 * ((pMouse->GetCursorPos(&v87)->y - 17) >> 5),
+        pMouse->GetCursorPos(&v100)->x <= 13) || pMouse->GetCursorPos(&v92)->x >= 462 
+        || (pNumActiveItem = pPlayer->GetItemIDAtInventoryIndex((int *)&v106.x), !pNumActiveItem) )
+        return;
+      v4 = (ItemGen *)&pPlayer->pInventoryItems[pNumActiveItem - 1];
+      if (!v4->Identified())
+      {
+        v10 = pPlayer->SelectPhrasesTransaction(v4, BildingType_WeaponShop, (int)window_SpeakInHouse->ptr_1C, 4);
+        v7 = BuilDialogueString((char *)pMerchantsIdentifyPhrases[v10], uActiveCharacter - 1, v4, (char *)window_SpeakInHouse->ptr_1C, 4, 0);
+        pTextHeight = pFontArrus->CalcTextHeight(v7, &dialog_window, 0, 0);
+        dialog_window.DrawTitleText(pFontArrus, 0, (174 - pTextHeight) / 2 + 138, pColorWhite, v7, 3);
+      }
+      else
+      {
+        v7 = BuilDialogueString("%24", uActiveCharacter - 1, v4, (char *)window_SpeakInHouse->ptr_1C, 4, 0);
+        pTextHeight = pFontArrus->CalcTextHeight(v7, &dialog_window, 0, 0);
+        dialog_window.DrawTitleText(pFontArrus, 0, (174 - pTextHeight) / 2 + 138, pColorWhite, v7, 3);
+      }
+      break;
+    }
+
+    case HOUSE_DIALOGUE_SHOP_REPAIR:
+    {
+      draw_leather();
+      CharacterUI_InventoryTab_Draw(pPlayers[uActiveCharacter], true);
+      DrawTextAtStatusBar(pGlobalTXT_LocalizationStrings[198], 0);
+      if ( !sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win())
+            return;
+      if( (v2 = pMouse->GetCursorPos(&a2)->x - 14, v106.x = (v2 >> 5) + 14 * ((pMouse->GetCursorPos(&v87)->y - 17) >> 5),
+          pMouse->GetCursorPos(&v100)->x <= 13) || pMouse->GetCursorPos(&v92)->x >= 462
+            || (pNumActiveItem = pPlayer->GetItemIDAtInventoryIndex((int *)&v106.x), !pNumActiveItem)
+            || (!(pPlayer->pOwnItems[pNumActiveItem-1].uAttributes& 2)) )
+            return;
+      v4 = (ItemGen *)&pPlayer->pInventoryItems[pNumActiveItem - 1];
+      v10 = pPlayer->SelectPhrasesTransaction(v4, BildingType_ArmorShop, (int)window_SpeakInHouse->ptr_1C, 5);
+      v7 = BuilDialogueString((char *)pMerchantsRepairPhrases[v10], uActiveCharacter - 1, v4, (char *)window_SpeakInHouse->ptr_1C, 5, 0);
+      pTextHeight = (174 - pFontArrus->CalcTextHeight(v7, &dialog_window, 0, 0)) / 2 + 138;
+      dialog_window.DrawTitleText(pFontArrus, 0, pTextHeight, pColorWhite, v7, 3);
+      return;
+    }
+    break;
+
+    case HOUSE_DIALOGUE_SHOP_DISPLAY_EQUIPMENT:
+    {
+      draw_leather();
+      CharacterUI_InventoryTab_Draw(pPlayers[uActiveCharacter], true);
+      pShopOptions[0] = pGlobalTXT_LocalizationStrings[200];//sell
+      pShopOptions[1] = pGlobalTXT_LocalizationStrings[113];//identify
+      pShopOptions[2] = pGlobalTXT_LocalizationStrings[179];//repair
+      all_text_height = 0;
+      for ( int i = 0; i < 3; ++i )
+        all_text_height += pFontArrus->CalcTextHeight(pShopOptions[i], &dialog_window, 0, 0);
+      v103 = (174 - all_text_height) / 3;
+      pNumActiveItem = pDialogueWindow->pStartingPosActiveItem;
+      v70 = (3 * (58 - (signed int)v103) - all_text_height) / 2 - ((174 - all_text_height) / 3) / 2 + 138;
+      v20 = -pDialogueWindow->pNumPresenceButton < 0;
+      if ( v20 ^ (pNumActiveItem > pNumActiveItem + pDialogueWindow->pNumPresenceButton ))
+      {
+        pItemNum = 2;
+        pNumString = 0;
+        do
+        {
+          pButton = pDialogueWindow->GetControl(pItemNum);
+          pButton->uY = v103 + v70;
+          pTextHeight = pFontArrus->CalcTextHeight((const char *)pShopOptions[pNumString], &dialog_window, 0, 0);
+          pButton->uHeight = pTextHeight;
+          v70 = pButton->uY + pTextHeight - 1;
+          pButton->uW = v70;
+          pColorText = pColorYellow;
+          if ( pDialogueWindow->pCurrentPosActiveItem != pItemNum )
+            pColorText = pColorWhite;
+          dialog_window.DrawTitleText(pFontArrus, 0, pButton->uY, pColorText, (const char *)pShopOptions[pNumString], 3);
+          ++pItemNum;
+          ++pNumString;
+          pNumActiveItem = pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem;
+        }
+        while ( pItemNum < pNumActiveItem );
+      }
+      break;
+    }
+
+    case HOUSE_DIALOGUE_SHOP_BUY_SPECIAL:
+    {
+      pRenderer->DrawTextureIndexed(8, 8, ShopTexture);
+      v109 = 0;
+      pItemNum = 0;
+      do
+      {
+        //   if ( pParty->field_C59C[9 * (int)&v109[3 * (unsigned int)window_SpeakInHouse->ptr_1C] + 724] )
+        if (pParty->SpecialItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][(signed int)v109].uItemID)
+        {
+          v52 = word_F8B158[(signed int)v109] + 30;
+          v53 = ItemsInShopTexture[(signed int)v109];
+          v54 = 60 - ((signed int)v53->uTextureWidth >> 1);
+          pRenderer->DrawTextureTransparent(v54 + pItemNum, word_F8B158[(signed int)v109] + 30, v53);
+          sub_40F92A(&pRenderer->pActiveZBuffer[v54 + pItemNum + 640 * v52], ItemsInShopTexture[(signed int)v109], (int)((char *)v109 + 1));
+        }
+        v109 = (const char **)((char *)v109 + 1);
+        pItemNum += 70;
+      }
+      while ( (signed int)v109 < 6 );
+      pNumActiveItem = sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win();
+      if ( pNumActiveItem )
+      {
+        v55 = 0;
+        v106.x = 0;
+        do
+        {
+          // if ( pParty->field_C59C[9 * (v55 + 12 * (unsigned int)window_SpeakInHouse->ptr_1C) + 724] )
+          if (pParty->SpecialItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][v55].uItemID)
+            ++v106.x;
+          ++v55;
+        }
+        while ( v55 < 6 );
+        v56 = GetAsyncKeyState(17);
+        v57 = pPlayer->CanSteal();
+        Str = (char *)v57;
+        if ( v56 && v57 )
+        {
+          v58 = pGlobalTXT_LocalizationStrings[185];
+        }
+        else
+        {
+          v58 = pGlobalTXT_LocalizationStrings[195];
+          if ( dialog_menu_id != HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
+            v58 = pGlobalTXT_LocalizationStrings[196];
+        }
+        DrawTextAtStatusBar(v58, 0);
+        if ( v106.x )
+        {
+          v59 = pMouse->GetCursorPos(&v91);
+          pNumActiveItem = v59->x + pSRZBufferLineOffsets[pMouse->GetCursorPos(&v89)->y];
+          if ( pRenderer->pActiveZBuffer[pNumActiveItem] & 0xFFFF )
+          {
+            v60 = (pRenderer->pActiveZBuffer[pNumActiveItem] & 0xFFFF) - 1;
+            v106.x = v60;
+            v61 = (int)window_SpeakInHouse->ptr_1C;
+            //  v62 = 9 * (v60 + 12 * v61);
+            pItemInShop = (ItemGen *)&pParty->StandartItemsInShops[(int)v61][v60];
+            if ( dialog_menu_id != HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
+              pItemInShop = &pParty->SpecialItemsInShops[(int)v61][v60];//v63 = (ItemGen *)&pParty->field_C59C[v62 + 724];
+            if ( !v56 || !Str )
+            {
+              v64 = pPlayer->SelectPhrasesTransaction(pItemInShop, BildingType_WeaponShop, v61, 2);
+              v7 = BuilDialogueString((char *)pMerchantsBuyPhrases[v64], uActiveCharacter - 1, pItemInShop, (char *)window_SpeakInHouse->ptr_1C, 2, 0);
+              pTextHeight = pFontArrus->CalcTextHeight(v7, &dialog_window, 0, 0);
+              dialog_window.DrawTitleText(pFontArrus, 0, (174 - pTextHeight) / 2 + 138, pColorWhite, v7, 3);
+            }
+            else
+            {
+              v7 = BuilDialogueString(pGlobalTXT_LocalizationStrings[181], uActiveCharacter - 1, pItemInShop, (char *)window_SpeakInHouse->ptr_1C, 2, 0);
+              pTextHeight = pFontArrus->CalcTextHeight(v7, &dialog_window, 0, 0);
+              dialog_window.DrawTitleText(pFontArrus, 0, (174 - pTextHeight) / 2 + 138, pColorWhite, v7, 3);
+            }
+          }
+        }
+        else
+        {
+          dialog_window.DrawCurrentTime( pParty->field_3C.field_50[(unsigned int)window_SpeakInHouse->ptr_1C]  - pParty->uTimePlayed);
+          pNumActiveItem = 0; //added
+        }
+      }
+      break;
+    }
+
+    case HOUSE_DIALOGUE_LEARN_SKILLS:
+    {
+      if (!sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win())
+        return;
+      v0 = 0;
+      all_text_height = 0;
+      //v32 = (signed __int64)(*(float *)&p2DEvents_minus1__24[13 * (signed int)v31] * 500.0);
+      v32 = (signed __int64)(p2DEvents[(signed int)window_SpeakInHouse->ptr_1C - 1].flt_24 * 500.0);
+      pItemNum = v32 * (100 - pPlayer->GetMerchant()) / 100;
+      if ( pItemNum < v32 / 3 )
+        pItemNum = v32 / 3;
+      pNumActiveItem = pDialogueWindow->pStartingPosActiveItem;
+      if ( pNumActiveItem >= pNumActiveItem + pDialogueWindow->pNumPresenceButton )
+      {
+        sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[544], pPlayer->pName, pClassNames[pPlayer->classType]);
+        strcat(pTmpBuf.data(), "\n \n");
+        strcat(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[528]);
+        pTextHeight = pFontArrus->CalcTextHeight(pTmpBuf.data(), &dialog_window, 0, 0);
+        dialog_window.DrawTitleText(pFontArrus, 0, (174 - pTextHeight) / 2 + 138, pColorYellow, pTmpBuf.data(), 3);
+        return;
+      }
+      do
+      {
+        v35 = pDialogueWindow->GetControl(pNumActiveItem)->msg_param - 36;
+        if ( byte_4ED970_skill_learn_ability_by_class_table[pPlayer->classType][v35] && !pPlayer->pActiveSkills[v35] )
+        {
+          all_text_height += pFontArrus->CalcTextHeight(pSkillNames[v35], &dialog_window, 0, 0);
+          v0++;
+        }
+        ++pNumActiveItem;
+      }
+      while ( pNumActiveItem < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem );
+      if ( !v0 )
+      {
+        sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[544], pPlayer->pName, pClassNames[pPlayer->classType]);
+        strcat(pTmpBuf.data(), "\n \n");
+        strcat(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[528]);
+        pTextHeight = pFontArrus->CalcTextHeight(pTmpBuf.data(), &dialog_window, 0, 0);
+        dialog_window.DrawTitleText(pFontArrus, 0, (174 - pTextHeight) / 2 + 138, pColorYellow, pTmpBuf.data(), 3);
+        return;
+      }
+      sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[401], pItemNum);
+      dialog_window.DrawTitleText(pFontArrus, 0, 0x92u, 0, pTmpBuf.data(), 3);
+      v103 = (149 - all_text_height) / v0;
+      if ( (149 - all_text_height) / v0 > 32 )
+        v103 = 32;
+      pNumActiveItem = pDialogueWindow->pStartingPosActiveItem;
+      v37 = (149 - v0 * v103 - all_text_height) / 2 - v103 / 2 + 162;
+      if ( pNumActiveItem < pNumActiveItem + pDialogueWindow->pNumPresenceButton )
+      {
+        pItemNum = 2;
+        do
+        {
+          pButton = pDialogueWindow->GetControl(pItemNum);
+          v40 = pButton->msg_param - 36;
+          if ( !byte_4ED970_skill_learn_ability_by_class_table[pPlayer->classType][v40] || pPlayer->pActiveSkills[v40] )
+          {
+            pButton->uW = 0;
+            pButton->uHeight = 0;
+            pButton->uY = 0;
+          }
+          else
+          {
+            pButton->uY = v103 + v37;
+            pTextHeight = pFontArrus->CalcTextHeight(pSkillNames[v40], &dialog_window, 0, 0);
+            pButton->uHeight = pTextHeight;
+            v37 = pButton->uY + pTextHeight - 1;
+            pButton->uW = v37;
+            pColorText = pColorYellow;
+            if ( pDialogueWindow->pCurrentPosActiveItem != pItemNum )
+              pColorText = pColorWhite;
+            dialog_window.DrawTitleText(pFontArrus, 0, pButton->uY, pColorText, pSkillNames[v40], 3);
+          }
+          pNumActiveItem = pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem;
+          pItemNum++;
+        }
+        while ( pItemNum < pNumActiveItem );
+      }
+      break;
+    }
+    default:
+    {
+      if( dialog_menu_id > HOUSE_DIALOGUE_SHOP_REPAIR)
+        pNumActiveItem = dialog_menu_id - 96;
+      else
+        pNumActiveItem = dialog_menu_id - 4;
+      break;
+    }
+  }
+}
+
+//----- (004BA928) --------------------------------------------------------
+void __cdecl ArmorShopDialog()
+{
+  signed int v1; // esi@8
+  unsigned int v2; // eax@10
+  ItemGen *v3; // eax@11
+  char *v5; // ecx@12
+  char *v6; // eax@13
+  int v8; // eax@15
+  signed int v9; // esi@17
+  unsigned int v10; // eax@19
+  char *v11; // edi@19
+  int v12; // ST08_4@20
+  int v13; // eax@20
+  char *v15; // ecx@20
+  char **v16; // edi@22
+  int all_text_height; // ebx@22
+  char **v18; // esi@22
+  int v19; // eax@23
+  GUIWindow *v20; // ecx@24
+  int v21; // eax@24
+  int v22; // edx@24
+  int v23; // ebx@24
+  unsigned __int8 v24; // sf@24
+  GUIButton *pButton; // eax@26
+  unsigned int v28; // ecx@26
+  int v29; // edx@26
+  signed int v31; // esi@31
+  unsigned int v32; // eax@33
+  int v33; // eax@34
+  int v35; // eax@35
+  char *v36; // edx@36
+  signed int v38; // esi@42
+  unsigned int v39; // esi@44
+  int v40; // eax@44
+  unsigned int v41; // eax@45
+  int v42; // eax@47
+  int v43; // ecx@52
+  int v46; // eax@54
+  unsigned int v49; // ecx@56
+  int v51; // eax@56
+  int v53; // eax@60
+  int textureH; // eax@60
+  signed int textureW; // ebx@65
+  Texture *v56; // eax@67
+  unsigned int pY_item; // edi@68
+  Texture *v58; // ST1C_4@68
+  int v59; // eax@68
+  int v60; // edi@69
+  signed int v61; // ebx@73
+  Texture *v62; // eax@75
+  int v63; // edi@76
+  Texture *v64; // ST1C_4@76
+  unsigned int v65; // ST18_4@76
+  int v66; // eax@76
+  int v67; // edi@77
+  signed int v68; // ecx@81
+  const char *pStatusText; // ecx@91
+  void *v72; // eax@95
+  POINT *v73; // esi@97
+  int v74; // ecx@97
+  int v75; // eax@98
+  int v76; // ecx@98
+  ItemGen *selected_item; // ecx@99
+  unsigned __int8 v78; // bl@104
+  int v80; // ebx@105
+  char **v81; // esi@105
+  int v82; // eax@106
+  int v86; // ebx@107
+  int pTextHeight; // eax@109
+  unsigned int v90; // ecx@109
+  int pNumString; // edx@109
+  unsigned __int16 pTextColor; // ax@109
+  signed int v93; // edx@114
+  POINT *v94; // edi@120
+  __int32 v95; // ecx@120
+  void *v96; // ST14_4@122
+  unsigned __int8 v97; // bl@122
+  ItemGen *v98; // ST10_4@122
+  int v99; // eax@122
+  char *v100; // eax@122
+  const char *v101; // ST18_4@122
+  unsigned __int16 v102; // ST14_2@122
+  int v103; // eax@122
+  signed int v104; // edi@123
+  Texture *v105; // eax@125
+  int v106; // ebx@126
+  unsigned int v108; // ST18_4@126
+  int v109; // eax@126
+  int v110; // ebx@127
+  GUIWindow *v111; // [sp-18h] [bp-11Ch]@36
+  unsigned int v112; // [sp-14h] [bp-118h]@13
+  int v113; // [sp-14h] [bp-118h]@36
+  unsigned int v115; // [sp-10h] [bp-114h]@13
+  ItemGen *v116; // [sp-10h] [bp-114h]@20
+  int v117; // [sp-10h] [bp-114h]@36
+  unsigned __int16 v119; // [sp-Ch] [bp-110h]@13
+  char *v121; // [sp-8h] [bp-10Ch]@13
+  int v122; // [sp-8h] [bp-10Ch]@20
+  unsigned int v123; // [sp-4h] [bp-108h]@13
+  __int64 *v124; // [sp-4h] [bp-108h]@20
+  int v125; // [sp-4h] [bp-108h]@68
+  int v126; // [sp-4h] [bp-108h]@76
+  int v127; // [sp-4h] [bp-108h]@126
+  POINT v128; // [sp+Ch] [bp-F8h]@8
+  POINT v129; // [sp+14h] [bp-F0h]@18
+  char v130; // [sp+1Ch] [bp-E8h]@120
+  POINT a2; // [sp+24h] [bp-E0h]@8
+  POINT v132; // [sp+2Ch] [bp-D8h]@120
+  POINT v133; // [sp+34h] [bp-D0h]@17
+  POINT v134; // [sp+3Ch] [bp-C8h]@97
+  POINT v135; // [sp+44h] [bp-C0h]@31
+  POINT v136; // [sp+4Ch] [bp-B8h]@97
+  POINT v137; // [sp+54h] [bp-B0h]@17
+  POINT v138; // [sp+5Ch] [bp-A8h]@32
+  POINT v139; // [sp+64h] [bp-A0h]@17
+  POINT v140; // [sp+6Ch] [bp-98h]@31
+  POINT v141; // [sp+74h] [bp-90h]@8
+  POINT v142; // [sp+7Ch] [bp-88h]@31
+  POINT v143; // [sp+84h] [bp-80h]@9
+  GUIWindow dialog_window; // [sp+8Ch] [bp-78h]@1
+  int v146; // [sp+E4h] [bp-20h]@24
+  int pYellowColor; // [sp+E8h] [bp-1Ch]@1
+  int pWhiteColor; // [sp+ECh] [bp-18h]@1
+  __int32 pItemCount; // [sp+F0h] [bp-14h]@8
+  int v152; // [sp+FCh] [bp-8h]@24
+  int v153; // [sp+100h] [bp-4h]@44
+  int th;
+  short text_color;
+  int pActiveButton;
+
+  memcpy(&dialog_window, window_SpeakInHouse, sizeof(dialog_window));
+  dialog_window.uFrameX = 483;
+  dialog_window.uFrameWidth = 148;
+  dialog_window.uFrameZ = 334;
+  pWhiteColor = TargetColor(0xFFu, 0xFFu, 0xFFu);
+  pYellowColor = TargetColor(0xE1u, 0xCDu, 0x23u);
+  switch (dialog_menu_id)
+  {
+    case HOUSE_DIALOGUE_MAIN:
+    {
+      if ( !sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
+        return;
+      pShopOptions[0] = pGlobalTXT_LocalizationStrings[134]; //"Buy Standard"
+      pShopOptions[1] = pGlobalTXT_LocalizationStrings[152]; //"Buy Special"
+      pShopOptions[2] = pGlobalTXT_LocalizationStrings[159]; //"Display Inventory"
+      pShopOptions[3] = pGlobalTXT_LocalizationStrings[160];
+      all_text_height = 0;
+      for( int i = 0; i < 4; ++i )
+        all_text_height += pFontArrus->CalcTextHeight(pShopOptions[i], &dialog_window, 0, 0);
+      v146 = ( 174 - all_text_height ) / 4;
+      v23 = ( 174 - 4 * ( 174 - all_text_height ) / 4 - all_text_height ) / 2 - ( 174 - all_text_height ) / 4 / 2 + 138;
+      pNumString = 0;
+      if ( pDialogueWindow->pNumPresenceButton>=0 )
+      {
+        for (pActiveButton = pDialogueWindow->pStartingPosActiveItem; pActiveButton < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem;  ++pActiveButton)
+        {
+          pButton = pDialogueWindow->GetControl(pActiveButton);
+          pButton->uY = v146 + v23;
+          pTextHeight = pFontArrus->CalcTextHeight(pShopOptions[pNumString], &dialog_window, 0, 0);
+          pButton->uHeight = pTextHeight;
+          v23 = pButton->uY + pButton->uHeight - 1;
+          pButton->uW = v23;
+          pTextColor = pYellowColor;
+          if ( pDialogueWindow->pCurrentPosActiveItem != pActiveButton )
+            pTextColor = pWhiteColor;
+          dialog_window.DrawTitleText(pFontArrus, 0, pButton->uY, pTextColor, pShopOptions[pNumString], 3);
+          ++pNumString;
+        }
+      }
+    }
+    break;
+    case HOUSE_DIALOGUE_SHOP_BUY_STANDARD:
+    {
+      pRenderer->DrawTextureIndexed(8, 8, ShopTexture);// 
+      textureW = 0;
+      v153 = 0;
+      for ( int i = 0; i < 8; ++i )//  
+      {
+        if ( pParty->StandartItemsInShops[window_SpeakInHouse->par1C][i].uItemID)
+        {
+          textureW = ItemsInShopTexture[i]->uTextureWidth;
+          textureH = ItemsInShopTexture[i]->uTextureHeight;
+          if ( i >= 4 )  //low row
+          {
+            v60 = 90 - (textureW/2);
+            pRenderer->DrawTextureTransparent(v60 + v153 - 420, 126, ItemsInShopTexture[i]);
+            v59 = v60 + v153 + 80220;
+          }
+          else
+          {
+            pY_item = 98 -  textureH;
+            v152 = 86 - (textureW/2);
+            pRenderer->DrawTextureTransparent(v152 + v153, pY_item, ItemsInShopTexture[i]);
+            v59 = v153 + v152 + 640 * pY_item;
+          }
+          ZBuffer_DoFill(&pRenderer->pActiveZBuffer[v59], ItemsInShopTexture[i], i + 1);
+        }
+        v153 += 105;
+      }
+      if ( !sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
+        return;
+      pItemCount = 0;
+      for ( int i = 0; i < 8; ++i )
+      {
+        if ( pParty->StandartItemsInShops[window_SpeakInHouse->par1C][i].uItemID )
+          ++pItemCount;
+      }
+      if ( GetAsyncKeyState(17) == 0 || pPlayers[uActiveCharacter]->CanSteal() == 0 )
+        pStatusText = pGlobalTXT_LocalizationStrings[195]; //"Select the Item to Buy"
+      else
+        pStatusText = pGlobalTXT_LocalizationStrings[185];//"Steal item"
+      DrawTextAtStatusBar(pStatusText, 0);
+      if ( pItemCount != 0 )
+      {
+        v73 = pMouse->GetCursorPos(&v136);
+        v74 = pRenderer->pActiveZBuffer[v73->x + pSRZBufferLineOffsets[pMouse->GetCursorPos(&v134)->y]] & 0xFFFF;
+        if ( !v74 )
+          return;
+        pItemCount = v74 - 1;
+        selected_item = &pParty->StandartItemsInShops[window_SpeakInHouse->par1C][v74-1];
+        if ( GetAsyncKeyState(17) == 0 || pPlayers[uActiveCharacter]->CanSteal() == 0)
+          v15 = (char *)pMerchantsBuyPhrases[pPlayers[uActiveCharacter]->SelectPhrasesTransaction(selected_item, BildingType_ArmorShop, window_SpeakInHouse->par1C, 2)];
+        else
+          v15 = pGlobalTXT_LocalizationStrings[181]; //"Steal %24"
+        v36 = BuilDialogueString(v15, uActiveCharacter - 1, selected_item, (char *)window_SpeakInHouse->ptr_1C, 2, 0);
+        v115 = (174 - pFontArrus->CalcTextHeight(v36, &dialog_window, 0, 0)) / 2 + 138;
+        dialog_window.DrawTitleText(pFontArrus, 0, v115, pWhiteColor, v36, 3);
+        return;
+      }
+      dialog_window.DrawCurrentTime( pParty->field_3C.field_50[window_SpeakInHouse->par1C]- pParty->uTimePlayed);
+      return;
+    }
+    break;
+    case HOUSE_DIALOGUE_SHOP_BUY_SPECIAL:
+    {
+      pRenderer->DrawTextureIndexed(8, 8, ShopTexture);
+      v11 = 0;
+      v61 = 0;
+      v153 = 0;
+      do
+      {
+        if (pParty->SpecialItemsInShops[window_SpeakInHouse->par1C][v61].uItemID)
+        {
+          v62 = ItemsInShopTexture[v61];
+          if ( v61 >= 4 )
+          {
+            v67 = 90 - ((signed int)v62->uTextureWidth >> 1);
+            pRenderer->DrawTextureTransparent(v153 + v67 - 420, 0x7Eu, ItemsInShopTexture[v61]);
+            v66 = v153 + v67 + 80220;
+          }
+          else
+          {
+            v63 = 98 - v62->uTextureHeight;
+            v64 = ItemsInShopTexture[v61];
+            v65 = 98 - v62->uTextureHeight;
+            v152 = 86 - ((signed int)v62->uTextureWidth >> 1);
+            pRenderer->DrawTextureTransparent(v152 + v153, v65, v64);
+            v66 = v152 + v153 + 640 * v63;
+          }
+          ZBuffer_DoFill(&pRenderer->pActiveZBuffer[v66], ItemsInShopTexture[v61], v61 + 1);
+        }
+        v153 += 105;
+        ++v61;
+      }
+      while ( v61 < 8 );
+      if ( !sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
+        return;
+      v68 = 0;
+      pItemCount = 0;
+      do
+      {
+        if (pParty->SpecialItemsInShops[window_SpeakInHouse->par1C][(signed int)v68].uItemID)
+        ++pItemCount;
+        ++v68;
+      }
+      while ( v68 < 6 );
+      if ( GetAsyncKeyState(17) == 0 || pPlayers[uActiveCharacter]->CanSteal() == 0 )
+        pStatusText = pGlobalTXT_LocalizationStrings[196]; //Select the Special Item to Buy"
+      else
+        pStatusText = pGlobalTXT_LocalizationStrings[185];
+      DrawTextAtStatusBar(pStatusText, 0);
+      if ( (char *)pItemCount != 0 )
+      {
+        v73 = pMouse->GetCursorPos(&v136);
+        v74 = pRenderer->pActiveZBuffer[v73->x + pSRZBufferLineOffsets[pMouse->GetCursorPos((POINT *)&v134)->y]] & 0xFFFF;
+        if ( !v74 )
+          return;
+        pItemCount = v74 - 1;
+        if ( dialog_menu_id == 2 )
+          selected_item = &pParty->StandartItemsInShops[window_SpeakInHouse->par1C][v74 - 1];
+        else
+          selected_item = &pParty->SpecialItemsInShops[window_SpeakInHouse->par1C][v74 - 1];
+        if ( GetAsyncKeyState(17) == 0 || pPlayers[uActiveCharacter]->CanSteal() == 0 )
+          v15 = (char *)pMerchantsBuyPhrases[pPlayers[uActiveCharacter]->SelectPhrasesTransaction(selected_item, BildingType_ArmorShop, window_SpeakInHouse->par1C, 2)];
+        else
+          v15 = pGlobalTXT_LocalizationStrings[181]; //"Steal %24"
+        v36 = BuilDialogueString(v15, uActiveCharacter - 1, selected_item, (char *)window_SpeakInHouse->ptr_1C, 2, 0);
+        v115 = (174 - pFontArrus->CalcTextHeight(v36, &dialog_window, 0, 0)) / 2 + 138;
+        dialog_window.DrawTitleText(pFontArrus, 0, v115, pWhiteColor, v36, 3);
+        return;
+      }
+      dialog_window.DrawCurrentTime( pParty->field_3C.field_50[window_SpeakInHouse->par1C]- pParty->uTimePlayed);
+      return;
+    }
+    break;
+    case HOUSE_DIALOGUE_SHOP_DISPLAY_EQUIPMENT:
+    {
+      draw_leather();
+      CharacterUI_InventoryTab_Draw(pPlayers[uActiveCharacter], true);
+      pShopOptions[0] = pGlobalTXT_LocalizationStrings[200]; //"Sell"
+      pShopOptions[1] = pGlobalTXT_LocalizationStrings[113]; //"Identify"
+      pShopOptions[2] = pGlobalTXT_LocalizationStrings[179]; //"Repair"
+      all_text_height = 0;
+      for ( int i = 0; i < 3; ++i )
+        all_text_height += pFontArrus->CalcTextHeight(pShopOptions[i], &dialog_window, 0, 0);
+      v152 = (174 - all_text_height) / 3;
+      v86 = (3 * (58 - v152) - all_text_height) / 2 - v152 / 2 + 138;
+      v24 = -pDialogueWindow->pNumPresenceButton < 0;
+      pActiveButton = pDialogueWindow->pStartingPosActiveItem;
+      if ( v24 ^ (pDialogueWindow->pStartingPosActiveItem > pDialogueWindow->pStartingPosActiveItem + pDialogueWindow->pNumPresenceButton) )
+      {
+        pNumString = 0;
+        do
+        {
+          pButton = pDialogueWindow->GetControl((unsigned int)pActiveButton);
+          pButton->uY = v152 + v86;
+          pTextHeight = pFontArrus->CalcTextHeight(pShopOptions[pNumString], &dialog_window, 0, 0);
+          v90 = pButton->uY;
+          pButton->uHeight = pTextHeight;
+          v86 = v90 + pTextHeight - 1;
+          pButton->uW = v86;
+          pTextColor = pYellowColor;
+          if ( pDialogueWindow->pCurrentPosActiveItem != pActiveButton )
+            pTextColor = pWhiteColor;
+          dialog_window.DrawTitleText(pFontArrus, 0, v90, pTextColor, pShopOptions[pNumString], 3);
+          ++pNumString;
+          ++pActiveButton;
+        }
+        while ( (signed int)pActiveButton < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem );
+      }
+      return;
+    }
+    break;
+    case HOUSE_DIALOGUE_SHOP_SELL:
+    {
+      draw_leather();
+      CharacterUI_InventoryTab_Draw(pPlayers[uActiveCharacter], true);
+      DrawTextAtStatusBar(pGlobalTXT_LocalizationStrings[199], 0);//"Select the Item to Sell"
+      if ( !sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win())
+        return;
+      if((v9 = pMouse->GetCursorPos(&v139)->x - 14, pItemCount = (v9 >> 5) + 14 * ((pMouse->GetCursorPos(&v133)->y - 17) >> 5),
+         pMouse->GetCursorPos(&v137)->x <= 13) || pMouse->GetCursorPos(&v129)->x >= 462 
+         || (v10 = pPlayers[uActiveCharacter]->GetItemIDAtInventoryIndex((int *)&pItemCount), v11 = 0, !v10) )
+           return;
+      v116 = (ItemGen *)&pPlayers[uActiveCharacter]->pInventoryItems[v10 - 1];
+      v13 = pPlayers[uActiveCharacter]->SelectPhrasesTransaction(v116, BildingType_ArmorShop, window_SpeakInHouse->par1C, 3);
+      v15 = (char *)pMerchantsSellPhrases[pPlayers[uActiveCharacter]->SelectPhrasesTransaction(v116, BildingType_ArmorShop, window_SpeakInHouse->par1C, 3)];
+      v36 = BuilDialogueString(v15, uActiveCharacter - 1, v116, (char *) window_SpeakInHouse->par1C, 3, 0);
+      v115 = (174 - pFontArrus->CalcTextHeight(v36, &dialog_window, 0, 0)) / 2 + 138;
+      dialog_window.DrawTitleText(pFontArrus, 0, v115, pWhiteColor, v36, 3);
+      return;
+    }
+    break;
+    case HOUSE_DIALOGUE_SHOP_IDENTIFY:
+    {
+      draw_leather();
+      CharacterUI_InventoryTab_Draw(pPlayers[uActiveCharacter], true);
+      DrawTextAtStatusBar(pGlobalTXT_LocalizationStrings[197], 0); //"Select the Item to Identify"	
+      if ( sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
+      {
+        v1 = pMouse->GetCursorPos(&a2)->x - 14;
+        pItemCount = (v1 >> 5) + 14 * ((pMouse->GetCursorPos(&v128)->y - 17) >> 5);
+        if ( pMouse->GetCursorPos(&v141)->x > 13 )
+        {
+          if ( pMouse->GetCursorPos(&v143)->x < 462 )
+          {
+            v2 = pPlayers[uActiveCharacter]->GetItemIDAtInventoryIndex((int *)&pItemCount);
+            if ( v2 )
+            {
+              v3 = (ItemGen *)&pPlayers[uActiveCharacter]->pInventoryItems[v2-1];
+              if (v3->Identified())
+                v5 = "%24";
+              else
+              {
+                v8 = pPlayers[uActiveCharacter]->SelectPhrasesTransaction(v3, BildingType_ArmorShop, (int)window_SpeakInHouse->ptr_1C, 4);
+                v5 = (char *)pMerchantsIdentifyPhrases[v8];
+              }
+              v6 = BuilDialogueString(v5, uActiveCharacter - 1, v3, (char *)window_SpeakInHouse->ptr_1C, 4, 0);
+              v115 = (174 - pFontArrus->CalcTextHeight(v6, &dialog_window, 0, 0)) / 2 + 138;
+              dialog_window.DrawTitleText(pFontArrus, 0, v115, pWhiteColor, v6, 3);
+              return;
+            }
+          }
+        }
+      }
+    }
+    break;
+    case HOUSE_DIALOGUE_SHOP_REPAIR:
+    {
+      draw_leather();
+      CharacterUI_InventoryTab_Draw(pPlayers[uActiveCharacter], true);
+      DrawTextAtStatusBar(pGlobalTXT_LocalizationStrings[198], 0);
+      if ( !sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win())
+        return;
+      if( (v31 = pMouse->GetCursorPos(&v135)->x - 14,
+          pItemCount = (v31 >> 5) + 14 * ((pMouse->GetCursorPos(&v142)->y - 17) >> 5),
+            pMouse->GetCursorPos(&v140)->x <= 13)
+            || pMouse->GetCursorPos(&v138)->x >= 462
+            || (v32 = pPlayers[uActiveCharacter]->GetItemIDAtInventoryIndex((int *)&pItemCount), v11 = 0, !v32)
+            || (!(pPlayers[uActiveCharacter]->pOwnItems[v32-1].uAttributes& 2)) )
+        return;
+      v116 = &pPlayers[uActiveCharacter]->pInventoryItems[v33 - 1];
+      v35 = pPlayers[uActiveCharacter]->SelectPhrasesTransaction(&pPlayers[uActiveCharacter]->pInventoryItems[v32 - 1], BildingType_ArmorShop, window_SpeakInHouse->par1C, 5);
+      v15 = (char *)pMerchantsRepairPhrases[v35];
+      v36 = BuilDialogueString(v15, uActiveCharacter - 1, v116, (char *)window_SpeakInHouse->ptr_1C, 5, 0);
+      v115 = (174 - pFontArrus->CalcTextHeight(v36, &dialog_window, 0, 0)) / 2 + 138;
+      dialog_window.DrawTitleText(pFontArrus, 0, v115, pWhiteColor, v36, 3);
+      return;
+    }
+    break;
+    case HOUSE_DIALOGUE_SHOP_6: //buy standart ???
+    {
+      pRenderer->DrawTextureIndexed(8u, 8u, ShopTexture);
+      DrawTextAtStatusBar(pGlobalTXT_LocalizationStrings[195], 0); //"Select the Item to Buy"
+      if ( !sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
+        return;
+      pItemCount = 0;
+      for( int i = 0; i < 6 ; ++i )
+        if (pParty->SpecialItemsInShops[window_SpeakInHouse->par1C][i].uItemID)
+          ++pItemCount;
+      if ( pItemCount )
+      {
+        v94 = pMouse->GetCursorPos(&v132);
+        pItemCount = pRenderer->pActiveZBuffer[v94->x + pSRZBufferLineOffsets[pMouse->GetCursorPos((POINT *)&v130)->y]];
+        v95 = pItemCount;
+        if ( pItemCount && pItemCount != -65536 )
+        {
+          --pItemCount;
+          v97 = uActiveCharacter - 1;
+          v99 = pPlayers[uActiveCharacter]->SelectPhrasesTransaction(&pParty->SpecialItemsInShops[window_SpeakInHouse->par1C][v95-1], BildingType_ArmorShop,	window_SpeakInHouse->par1C,	2);
+          v100 = BuilDialogueString((char *)pMerchantsBuyPhrases[v99], uActiveCharacter - 1, v98, (char *)window_SpeakInHouse->par1C, 2, 0);
+          v103 = pFontArrus->CalcTextHeight(v100, &dialog_window, 0, 0);
+          dialog_window.DrawTitleText(pFontArrus, 0, (174 - v103) / 2 + 138, pWhiteColor, v100, 3);
+        }
+        v104 = 0;
+        v153 = 0;
+        do
+        {
+          //if ( pParty->field_C59C[9 * (v104 + 12 * (unsigned int)window_SpeakInHouse->ptr_1C) + 724] )
+          if (pParty->SpecialItemsInShops[window_SpeakInHouse->par1C][v104].uItemID)
+          {
+            v105 = ItemsInShopTexture[v104];
+            if ( v104 >= 4 )
+            {
+              v110 = 90 - ((signed int)v105->uTextureWidth >> 1);
+              pRenderer->DrawTextureTransparent(v153 + v110 - 420, 0x7Eu, ItemsInShopTexture[v104]);
+              v127 = v104 + 1;
+              v109 = v153 + v110 + 80220;
+            }
+            else
+            {
+              v106 = 98 - v105->uTextureHeight;
+              v108 = 98 - v105->uTextureHeight;
+              v152 = 86 - ((signed int)v105->uTextureWidth >> 1);
+              pRenderer->DrawTextureTransparent(v152 + v153, v108, ItemsInShopTexture[v104]);
+              v127 = v104 + 1;
+              v109 = v152 + v153 + 640 * v106;
+            }
+            ZBuffer_DoFill(&pRenderer->pActiveZBuffer[v109], ItemsInShopTexture[v104], v127);
+          }
+          v153 += 105;
+          ++v104;
+        }
+        while ( v104 < 8 );
+        return;
+      }
+      dialog_window.DrawCurrentTime(pParty->field_3C.field_50[window_SpeakInHouse->par1C]-  pParty->uTimePlayed);
+      return;
+    }
+    break;
+    case HOUSE_DIALOGUE_LEARN_SKILLS:
+    {
+      if (!sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
+        return;
+      v152 = 0;
+      v38 = (signed __int64)(p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].flt_24 * 500.0);
+      pActiveButton = v38 * (100 - pPlayers[uActiveCharacter]->GetMerchant()) / 100;
+      if ( (signed int)pActiveButton < v38 / 3 )
+        pActiveButton = v38 / 3;
+      v39 = pDialogueWindow->pStartingPosActiveItem;
+      v40 = pDialogueWindow->pNumPresenceButton;
+      v153 = 0;
+      if ( (signed int)v39 < (signed int)(v39 + v40) )
+      {
+        do
+        {
+          v41 = pDialogueWindow->GetControl(v39)->msg_param - 36;
+          if ( byte_4ED970_skill_learn_ability_by_class_table[pPlayers[uActiveCharacter]->classType][v41] && !pPlayers[uActiveCharacter]->pActiveSkills[v41] )
+          {
+            v42 = pFontArrus->CalcTextHeight(pSkillNames[v41], &dialog_window, 0, 0);
+            v152 += v42;
+            ++v153;
+          }
+          ++v39;
+        }
+        while ( (signed int)v39 < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem );
+        if ( v153 )
+        {
+          sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[401], pActiveButton);
+          dialog_window.DrawTitleText(pFontArrus, 0, 0x92u, 0, pTmpBuf.data(), 3);
+          pActiveButton = (149 - v152) / v153;
+          if ( (149 - v152) / v153 > 32 )
+            pActiveButton = 32;
+          v43 = (149 - v153 * (signed int)pActiveButton - v152) / 2 - (signed int)pActiveButton / 2 + 162;
+          v152 = pDialogueWindow->pStartingPosActiveItem;
+          v146 = v43;
+          if ( v152 < v152 + pDialogueWindow->pNumPresenceButton )
+          {
+            v153 = 2;
+            do
+            {
+              pButton = pDialogueWindow->GetControl(v152);
+              v46 = pButton->msg_param - 36;
+              if ( !byte_4ED970_skill_learn_ability_by_class_table[pPlayers[uActiveCharacter]->classType][v46] || pPlayers[uActiveCharacter]->pActiveSkills[v46] )
+              {
+                pButton->uW = 0;
+                pButton->uHeight = 0;
+                pButton->uY = 0;
+              }
+              else
+              {
+                pButton->uY = (unsigned int)((char *)pActiveButton + v146);
+                pTextHeight = pFontArrus->CalcTextHeight(pSkillNames[v46], &dialog_window, 0, 0);
+                v49 = pButton->uY;
+                pButton->uHeight = pTextHeight;
+                v51 = v49 + pTextHeight - 1;
+                pButton->uW = v51;
+                v146 = v51;
+                pTextColor = pYellowColor;
+                if ( pDialogueWindow->pCurrentPosActiveItem != v153 )
+                  pTextColor = pWhiteColor;
+                dialog_window.DrawTitleText(pFontArrus, 0, v49, pTextColor, pSkillNames[v46], 3);
+              }
+              v53 = pDialogueWindow->pStartingPosActiveItem;
+              ++v152;
+              textureH = pDialogueWindow->pNumPresenceButton + v53;
+              ++v153;
+            }
+            while ( v152 < textureH );
+          }
+          return;
+        }
+      }
+      sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[544], pPlayers[uActiveCharacter]->pName, pClassNames[pPlayers[uActiveCharacter]->classType]); //"Seek knowledge elsewhere %s the %s"
+      strcat(pTmpBuf.data(), "\n \n");
+      strcat(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[528]); //"I can offer you nothing further."
+      v115 = (174 - pFontArrus->CalcTextHeight(pTmpBuf.data(), &dialog_window, 0, 0)) / 2 + 138;
+      dialog_window.DrawTitleText(pFontArrus, 0, v115, pYellowColor, pTmpBuf.data(), 3);
+      return;
+    }
+    break;
+  }
+}
+//----- (004B9CC6) --------------------------------------------------------
+void __cdecl AlchemistDialog()
+{
+  int v0;
+  int pNumActiveItem; // eax@7
+  signed int v5; // esi@9
+  unsigned int v6; // esi@11
+  int v7; // eax@11
+  unsigned int v8; // eax@12
+  int v9; // eax@14
+  int v10; // ecx@19
+  int v13; // eax@21
+  char *v14; // eax@23
+  int v15; // eax@23
+  unsigned int v16; // ecx@23
+  int v17; // edx@23
+  int v18; // eax@23
+  int v20; // eax@27
+  char *v21; // edx@29
+  int v22; // esi@30
+  char **v23; // edi@30
+  int v24; // eax@31
+  int v26; // edx@32
+  int v27; // edi@32
+  unsigned __int8 v28; // sf@32
+  const char **v30; // eax@34
+  int v31; // eax@34
+  unsigned int v32; // ecx@34
+  int v34; // eax@34
+  signed int v36; // esi@39
+  ItemGen *v37; // eax@42
+  char *v38; // ecx@43
+  unsigned __int8 v39; // dl@44
+  int v40; // eax@46
+  int v41; // ST08_4@47
+  int v42; // eax@47
+  signed int v43; // esi@49
+  int v44; // ST08_4@52
+  int v45; // eax@52
+  Texture *v46; // ecx@55
+  unsigned int v47; // edi@55
+  unsigned int v48; // esi@57
+  int v49; // edx@61
+  Texture *v50; // ecx@67
+  unsigned int v51; // edi@67
+  unsigned int v52; // esi@69
+  int v53; // edx@73
+  Texture *v54; // ecx@79
+  unsigned int v55; // edi@79
+  unsigned int v56; // esi@81
+  int v57; // edx@85
+  Texture *v58; // ecx@91
+  unsigned int v59; // edi@91
+  unsigned int v60; // esi@93
+  int v61; // edx@97
+  signed int v62; // ecx@102
+  SHORT v63; // di@110
+  bool v64; // eax@110
+  const char *v65; // ecx@112
+  POINT *v66; // esi@117
+  int v67; // ecx@118
+  int v68; // eax@118
+  int v69; // ecx@118
+  ItemGen *v70; // esi@118
+  int v71; // eax@123
+  int all_text_height; // edi@125
+  char **v73; // esi@125
+  int v74; // eax@126
+  int pItemNum;
+  int v76; // edx@127
+  int v77; // edi@127
+  GUIButton *pButton; // esi@129
+  const char **v79; // eax@129
+  int pTextHeight; // eax@129
+  unsigned int v81; // ecx@129
+  unsigned int pColorText; // ax@129
+  int v85; // [sp-14h] [bp-ECh]@29
+  int v86; // [sp-10h] [bp-E8h]@29
+  ItemGen *v87; // [sp-10h] [bp-E8h]@43
+  unsigned __int16 v88; // [sp-Ch] [bp-E4h]@29
+  void *v89; // [sp-Ch] [bp-E4h]@43
+  char *v90; // [sp-8h] [bp-E0h]@29
+  int v91; // [sp-8h] [bp-E0h]@42
+  unsigned int v92; // [sp-4h] [bp-DCh]@29
+  __int64 *v93; // [sp-4h] [bp-DCh]@42
+  POINT v94; // [sp+Ch] [bp-CCh]@39
+  POINT v95; // [sp+14h] [bp-C4h]@49
+  POINT v96; // [sp+1Ch] [bp-BCh]@117
+  POINT v97; // [sp+24h] [bp-B4h]@40
+  POINT v98; // [sp+2Ch] [bp-ACh]@117
+  POINT v99; // [sp+34h] [bp-A4h]@49
+  POINT v100; // [sp+3Ch] [bp-9Ch]@50
+  POINT v101; // [sp+44h] [bp-94h]@39
+  POINT v102; // [sp+4Ch] [bp-8Ch]@49
+  POINT a2; // [sp+54h] [bp-84h]@39
+  GUIWindow dialog_window; // [sp+5Ch] [bp-7Ch]@1
+  int v105; // [sp+B0h] [bp-28h]@19
+  int pColorYellow; // [sp+B4h] [bp-24h]@1
+  int Str; // [sp+B8h] [bp-20h]@23
+  int pColorWhite; // [sp+BCh] [bp-1Ch]@1
+  __int32 v109; // [sp+C0h] [bp-18h]@39
+  Player *pPlayer; // [sp+C4h] [bp-14h]@1
+  int pNumString; // [sp+C8h] [bp-10h]@9
+  unsigned int v112; // [sp+CCh] [bp-Ch]@9
+  unsigned __int8 v113; // [sp+D3h] [bp-5h]@47
+  int v114; // [sp+D4h] [bp-4h]@11
+
+  pPlayer = pPlayers[uActiveCharacter];
+  memcpy(&dialog_window, window_SpeakInHouse, sizeof(dialog_window));
+  dialog_window.uFrameX = 483;
+  dialog_window.uFrameWidth = 148;
+  dialog_window.uFrameZ = 334;
+  pColorWhite = TargetColor(0xFFu, 0xFFu, 0xFFu);
+  pColorYellow = TargetColor(0xE1u, 0xCDu, 0x23u);
+  switch(dialog_menu_id)
+  {
+    case HOUSE_DIALOGUE_MAIN:
+    {
+      if ( sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
+      {
+        pShopOptions[0] = pGlobalTXT_LocalizationStrings[134];
+        pShopOptions[1] = pGlobalTXT_LocalizationStrings[152];
+        pShopOptions[2] = pGlobalTXT_LocalizationStrings[159];
+        pShopOptions[3] = pGlobalTXT_LocalizationStrings[160];
+        all_text_height = 0;
+        for (int i = 0; i < 4; ++i)//while ( (signed int)v15 < (signed int)&unk_F8B1C8 );
+          all_text_height += pFontArrus->CalcTextHeight(pShopOptions[i], &dialog_window, 0, 0);
+        Str = (174 - all_text_height) / 4;
+        pNumActiveItem = pDialogueWindow->pStartingPosActiveItem;
+        v76 = pNumActiveItem + pDialogueWindow->pNumPresenceButton;
+        v77 = (174 - 4 * (174 - all_text_height) / 4 - all_text_height) / 2 - (174 - all_text_height) / 4 / 2 + 138;
+        v28 = -pDialogueWindow->pNumPresenceButton < 0;
+        if ( v28 ^ (pNumActiveItem > v76) )
+        {
+          pItemNum = 2;
+          pNumString = 0;
+          do
+          {
+            pButton = pDialogueWindow->GetControl(pItemNum);
+            pButton->uY = Str + v77;
+            pTextHeight = pFontArrus->CalcTextHeight((const char *)pShopOptions[pNumString], &dialog_window, 0, 0);
+            pButton->uHeight = pTextHeight;
+            v77 = pButton->uY + pTextHeight - 1;
+            pButton->uW = v77;
+            pColorText = pColorYellow;
+            if ( pDialogueWindow->pCurrentPosActiveItem != pItemNum )
+              pColorText = pColorWhite;
+            dialog_window.DrawTitleText(pFontArrus, 0, pButton->uY, pColorText, (const char *)pShopOptions[pNumString], 3);
+            ++pItemNum;
+            ++pNumString;
+            pNumActiveItem = pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem;
+          }
+          while ( pItemNum < pNumActiveItem );
+        }
+      }
+      return;
+    }
+    case HOUSE_DIALOGUE_SHOP_BUY_STANDARD:
+    {
+      pRenderer->DrawTextureIndexed(8, 8, ShopTexture);
+      v114 = 0;
+      do
+      {
+        if ( pParty->StandartItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][v114].uItemID)
+        {
+          v46 = ItemsInShopTexture[v114];
+          v47 = 152 - v46->uTextureHeight;
+          if ( (signed int)v47 < 1 )
+            v47 = 0;
+          v48 = 75 * v114 - v46->uTextureWidth / 2 + 40;
+          if ( v114 )
+          {
+            if ( v114 == 5 )
+            {
+              v49 = ItemsInShopTexture[5]->uTextureWidth;
+              if ( (signed int)v48 > 457 - v49 )
+                v48 = 457 - v49;
+            }
+          }
+          else if ( (signed int)v48 < 18 )
+            v48 = 18;
+          pRenderer->DrawTextureTransparent(v48, v47, v46);
+          sub_40F92A(&pRenderer->pActiveZBuffer[v48 + 640 * v47], ItemsInShopTexture[v114], v114 + 1);
+        }
+        ++v114;
+      }
+      while ( v114 < 6 );
+      v114 = 0;
+      do
+      {
+        if ( pParty->StandartItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][v114 + 6].uItemID)
+        {
+          v50 = ItemsInShopTexture[v114 + 6];
+          v51 = 308 - v50->uTextureHeight;
+          if ( (signed int)v51 < 1 )
+            v51 = 0;
+          v52 = 75 * v114 - v50->uTextureWidth / 2 + 40;
+          if ( v114 )
+          {
+            if ( v114 == 5 )
+            {
+              v53 = ItemsInShopTexture[11]->uTextureWidth;
+              if ( (signed int)v52 > 457 - v53 )
+                v52 = 457 - v53;
+            }
+          }
+          else
+          {
+            if ( (signed int)v52 < 18 )
+              v52 = 18;
+          }
+          pRenderer->DrawTextureTransparent(v52, v51, v50);
+          sub_40F92A(&pRenderer->pActiveZBuffer[v52 + 640 * v51], ItemsInShopTexture[v114 + 6], v114 + 7);
+        }
+        ++v114;
+      }
+      while ( v114 < 6 );
+      if ( sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
+      {
+        v62 = 0;
+        v109 = 0;
+        do
+        {
+          if ( pParty->StandartItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][v62].uItemID)
+            ++v109;
+          ++v62;
+        }
+        while ( v62 < 12 );
+        v63 = GetAsyncKeyState(17);
+        v64 = pPlayer->CanSteal();
+        Str = v64;
+        if ( v63 && v64 )
+        {
+          v65 = pGlobalTXT_LocalizationStrings[185];
+        }
+        else if ( dialog_menu_id == HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
+        {
+          v65 = pGlobalTXT_LocalizationStrings[195];
+        }
+        else
+        {
+          v65 = pGlobalTXT_LocalizationStrings[196];
+        }
+        DrawTextAtStatusBar(v65, 0);
+        if ( !v109 )
+        {
+          dialog_window.DrawCurrentTime( pParty->field_3C.field_50[ (unsigned int)window_SpeakInHouse->ptr_1C] - pParty->uTimePlayed);
+          return;
+        }
+        v66 = pMouse->GetCursorPos(&v98);
+        pNumActiveItem = v66->x + pSRZBufferLineOffsets[pMouse->GetCursorPos(&v96)->y];
+        if ( pRenderer->pActiveZBuffer[pNumActiveItem] & 0xFFFF )
+        {
+          v67 = (pRenderer->pActiveZBuffer[pNumActiveItem] & 0xFFFF) - 1;
+          v70 = (ItemGen *)&pParty->StandartItemsInShops[(int)window_SpeakInHouse->ptr_1C][v67];
+          if ( dialog_menu_id != HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
+            v70 = &pParty->SpecialItemsInShops[(int)window_SpeakInHouse->ptr_1C][v67];//v70 = (ItemGen *)&pParty->field_C59C[v69 + 724];
+          if ( !v63 || !Str )
+          {
+            v71 = pPlayer->SelectPhrasesTransaction(v70, BildingType_AlchemistShop, (int)window_SpeakInHouse->ptr_1C, 2);
+            v38 = (char *)pMerchantsBuyPhrases[v71];
+          }
+          else
+          {
+            v38 = pGlobalTXT_LocalizationStrings[181];
+          }
+          v21 = BuilDialogueString(v38, uActiveCharacter - 1, v70, (char *)window_SpeakInHouse->ptr_1C, 2, 0);
+          v40 = pFontArrus->CalcTextHeight(v21, &dialog_window, 0, 0);
+          dialog_window.DrawTitleText(pFontArrus, 0, (174 - v40) / 2 + 138, pColorWhite, v21, 3);
+          return ;
+        }
+      }
+      return;
+    }
+    case HOUSE_DIALOGUE_SHOP_SELL:
+    {
+      draw_leather();
+      CharacterUI_InventoryTab_Draw(pPlayers[uActiveCharacter], true);
+      DrawTextAtStatusBar(pGlobalTXT_LocalizationStrings[199], 0);
+      if ( !sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
+        return;
+      if ((v43 = pMouse->GetCursorPos(&v99)->x - 14, v109 = (v43 >> 5) + 14 * ((pMouse->GetCursorPos(&v95)->y - 17) >> 5),
+           pMouse->GetCursorPos(&v102)->x <= 13) || pMouse->GetCursorPos(&v100)->x >= 462 
+          || (pNumActiveItem = pPlayer->GetItemIDAtInventoryIndex((int *)&v109), !pNumActiveItem) )
+          return;
+      v87 = (ItemGen *)&pPlayer->pInventoryItems[pNumActiveItem - 1];
+      v45 = pPlayer->SelectPhrasesTransaction(v87, BildingType_AlchemistShop, (int)window_SpeakInHouse->ptr_1C, 3);
+      v21 = BuilDialogueString((char *)pMerchantsSellPhrases[v45], uActiveCharacter - 1, v87, (char *)window_SpeakInHouse->ptr_1C, 3, 0);
+      pTextHeight = pFontArrus->CalcTextHeight(v21, &dialog_window, 0, 0);
+      dialog_window.DrawTitleText(pFontArrus, 0, (174 - pTextHeight) / 2 + 138, pColorWhite, v21, 3);
+      return; 
+    }
+    case HOUSE_DIALOGUE_SHOP_IDENTIFY:
+    {
+      draw_leather();
+      CharacterUI_InventoryTab_Draw(pPlayers[uActiveCharacter], true);
+      DrawTextAtStatusBar(pGlobalTXT_LocalizationStrings[197], 0);
+      if ( sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
+        return;
+      if ((v36 = pMouse->GetCursorPos(&a2)->x - 14, v109 = (v36 >> 5) + 14 * ((pMouse->GetCursorPos(&v94)->y - 17) >> 5),
+          pMouse->GetCursorPos(&v101)->x <= 13) || pMouse->GetCursorPos(&v97)->x >= 462
+         || (pNumActiveItem = pPlayer->GetItemIDAtInventoryIndex((int *)&v109), !pNumActiveItem) )
+        return;
+      v37 = (ItemGen *)&pPlayer->pInventoryItems[pNumActiveItem - 1];
+      if (!v37->Identified())
+      {
+        v42 = pPlayer->SelectPhrasesTransaction(v37, BildingType_AlchemistShop, (int)window_SpeakInHouse->ptr_1C, 4);
+        v38 = (char *)pMerchantsIdentifyPhrases[v42];
+      }
+      else
+      {
+        v38 = "%24";
+      }
+      v21 = BuilDialogueString(v38, uActiveCharacter - 1, v37, (char *)window_SpeakInHouse->ptr_1C, 4, 0);
+      v40 = pFontArrus->CalcTextHeight(v21, &dialog_window, 0, 0);
+      dialog_window.DrawTitleText(pFontArrus, 0, (174 - v40) / 2 + 138, pColorWhite, v21, 3);
+      return;
+    }
+    case HOUSE_DIALOGUE_SHOP_DISPLAY_EQUIPMENT:
+    {
+      draw_leather();
+      CharacterUI_InventoryTab_Draw(pPlayers[uActiveCharacter], true);
+      pShopOptions[0] = pGlobalTXT_LocalizationStrings[200];
+      pShopOptions[1] = pGlobalTXT_LocalizationStrings[113];
+      all_text_height = 0;
+      for ( int i = 0; i < 2; ++i )
+        all_text_height += pFontArrus->CalcTextHeight(pShopOptions[i], &dialog_window, 0, 0);
+      Str = (174 - all_text_height) / 2;
+      pNumActiveItem = pDialogueWindow->pStartingPosActiveItem;
+      v26 = pNumActiveItem + pDialogueWindow->pNumPresenceButton;
+      v27 = (2 * (87 - (174 - all_text_height) / 2) - all_text_height) / 2 - (174 - all_text_height) / 2 / 2 + 138;
+      v28 = -pDialogueWindow->pNumPresenceButton < 0;
+      if ( v28 ^ (pNumActiveItem > v26) )
+      {
+        pItemNum = 2;
+        pNumString = 0;
+        do
+        {
+          pButton = pDialogueWindow->GetControl(pItemNum);
+          pButton->uY = Str + v27;
+          pTextHeight = pFontArrus->CalcTextHeight((const char *)pShopOptions[pNumString], &dialog_window, 0, 0);
+          pButton->uHeight = pTextHeight;
+          v27 = pButton->uY + pTextHeight - 1;
+          pButton->uW = v27;
+          pColorText = pColorYellow;
+          if ( pDialogueWindow->pCurrentPosActiveItem != pItemNum )
+            pColorText = pColorWhite;
+          dialog_window.DrawTitleText(pFontArrus, 0, pButton->uY, pColorText, (const char *)pShopOptions[pNumString], 3);
+          ++pItemNum;
+          ++pNumString;
+          pNumActiveItem = pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem;
+        }
+        while ( pItemNum < pNumActiveItem );
+      }
+      return;
+    }
+    case HOUSE_DIALOGUE_SHOP_BUY_SPECIAL:
+    {
+      pRenderer->DrawTextureIndexed(8, 8, ShopTexture);
+      v114 = 0;
+      do
+      {
+        if (pParty->SpecialItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][v114].uItemID)
+        {
+          v54 = ItemsInShopTexture[v114];
+          v55 = 152 - v54->uTextureHeight;
+          if ( (signed int)v55 < 1 )
+            v55 = 0;
+          v56 = 75 * v114 - v54->uTextureWidth / 2 + 40;
+          if ( v114 )
+          {
+            if ( v114 == 5 )
+            {
+              v57 = ItemsInShopTexture[5]->uTextureWidth;
+              if ( (signed int)v56 > 457 - v57 )
+                v56 = 457 - v57;
+            }
+          }
+          else
+          {
+            if ( (signed int)v56 < 18 )
+              v56 = 18;
+          }
+          pRenderer->DrawTextureTransparent(v56, v55, v54);
+          sub_40F92A(&pRenderer->pActiveZBuffer[v56 + 640 * v55], ItemsInShopTexture[v114], v114 + 1);
+        }
+        ++v114;
+      }
+      while ( v114 < 6 );
+      v114 = 0;
+      do
+      {
+        if (pParty->SpecialItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][(signed int)v114 + 6].uItemID) //not itemid
+        {
+          v58 = ItemsInShopTexture[v114 + 6];
+          v59 = 308 - v58->uTextureHeight;
+          if ( (signed int)v59 < 1 )
+            v59 = 0;
+          v60 = 75 * v114 - v58->uTextureWidth / 2 + 40;
+          if ( v114 )
+          {
+            if ( v114 == 5 )
+            {
+              v61 = ItemsInShopTexture[11]->uTextureWidth;
+              if ( (signed int)v60 > 457 - v61 )
+                v60 = 457 - v61;
+            }
+          }
+          else
+          {
+            if ( (signed int)v60 < 18 )
+              v60 = 18;
+          }
+          pRenderer->DrawTextureTransparent(v60, v59, v58);
+          sub_40F92A(&pRenderer->pActiveZBuffer[v60 + 640 * v59], ItemsInShopTexture[v114 + 6], v114 + 7);
+        }
+        ++v114;
+      }
+      while ( v114 < 6 );
+      if ( sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
+      {
+        v62 = 0;
+        v109 = 0;
+        do
+        {
+          if (pParty->SpecialItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][v62].uItemID)
+            ++v109;
+          ++v62;
+        }
+        while ( v62 < 12 );
+        v63 = GetAsyncKeyState(17);
+        v64 = pPlayer->CanSteal();
+        Str = v64;
+        if ( v63 && v64 )
+        {
+          v65 = pGlobalTXT_LocalizationStrings[185];
+        }
+        else
+        {
+          v65 = pGlobalTXT_LocalizationStrings[195];
+          if ( dialog_menu_id != HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
+            v65 = pGlobalTXT_LocalizationStrings[196];
+        }
+        DrawTextAtStatusBar(v65, 0);
+        if ( !v109 )
+        {
+          dialog_window.DrawCurrentTime( pParty->field_3C.field_50[ (unsigned int)window_SpeakInHouse->ptr_1C] - pParty->uTimePlayed);
+          return;
+        }
+        v66 = pMouse->GetCursorPos(&v98);
+        pNumActiveItem = v66->x + pSRZBufferLineOffsets[pMouse->GetCursorPos(&v96)->y];
+        if ( pRenderer->pActiveZBuffer[pNumActiveItem] & 0xFFFF )
+        {
+          v67 = (pRenderer->pActiveZBuffer[pNumActiveItem] & 0xFFFF) - 1;
+          v109 = v67;
+          v68 = (int)window_SpeakInHouse->ptr_1C;
+          //  v69 = 9 * (v67 + 12 * v68);
+          v70 = (ItemGen *)&pParty->StandartItemsInShops[v68][v67];
+          if ( dialog_menu_id != HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
+            v70 = &pParty->SpecialItemsInShops[(int)v68][v67];//v70 = (ItemGen *)&pParty->field_C59C[v69 + 724];
+          if ( !v63 || !Str )
+          {
+            v71 = pPlayer->SelectPhrasesTransaction(v70, BildingType_AlchemistShop, v68, 2);
+            v38 = (char *)pMerchantsBuyPhrases[v71];
+          }
+          else
+          {
+            v38 = pGlobalTXT_LocalizationStrings[181];
+          }
+          v21 = BuilDialogueString(v38, uActiveCharacter - 1, v70, (char *)window_SpeakInHouse->ptr_1C, 2, 0);
+          v40 = pFontArrus->CalcTextHeight(v21, &dialog_window, 0, 0);
+          dialog_window.DrawTitleText(pFontArrus, 0, (174 - v40) / 2 + 138, pColorWhite, v21, 3);
+          return;
+        }
+      }
+      return;
+    }
+    case HOUSE_DIALOGUE_LEARN_SKILLS:
+    {
+      if (!sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win())
+        return;
+      all_text_height = 0;
+      v5 = (signed __int64)(p2DEvents[(signed int)window_SpeakInHouse->ptr_1C - 1].flt_24 * 500.0);
+      pItemNum = v5 * (100 - pPlayer->GetMerchant()) / 100;
+      if ( pItemNum < v5 / 3 )
+        pItemNum = v5 / 3;
+      pNumActiveItem = pDialogueWindow->pStartingPosActiveItem;
+      v114 = 0;
+      if ( pNumActiveItem >= pNumActiveItem + pDialogueWindow->pNumPresenceButton )
+      {
+        sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[544], pPlayer->pName, pClassNames[pPlayer->classType]);
+        strcat(pTmpBuf.data(), "\n \n");
+        strcat(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[528]);
+        v40 = pFontArrus->CalcTextHeight(pTmpBuf.data(), &dialog_window, 0, 0);
+        dialog_window.DrawTitleText(pFontArrus, 0, (174 - v40) / 2 + 138, pColorYellow, pTmpBuf.data(), 3);
+        return;
+      }
+      do
+      {
+        v8 = pDialogueWindow->GetControl(pNumActiveItem)->msg_param - 36;
+        if ( byte_4ED970_skill_learn_ability_by_class_table[pPlayer->classType][v8] && !pPlayer->pActiveSkills[v8] )
+        {
+          all_text_height = pFontArrus->CalcTextHeight(pSkillNames[v8], &dialog_window, 0, 0);
+          ++v114;
+        }
+        ++pNumActiveItem;
+      }
+      while ( pNumActiveItem < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem );
+      if ( !v114 )
+      {
+        sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[544], pPlayer->pName, pClassNames[pPlayer->classType]);
+        strcat(pTmpBuf.data(), "\n \n");
+        strcat(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[528]);
+        v40 = pFontArrus->CalcTextHeight(pTmpBuf.data(), &dialog_window, 0, 0);
+        dialog_window.DrawTitleText(pFontArrus, 0, (174 - v40) / 2 + 138, pColorYellow, pTmpBuf.data(), 3);
+        return;
+      }
+      if ( v114 )
+      {
+        sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[401], pItemNum);
+        dialog_window.DrawTitleText(pFontArrus, 0, 0x92u, 0, pTmpBuf.data(), 3);
+        v18 = (149 - all_text_height) / v114;
+        if ( (149 - all_text_height) / v114 > 32 )
+          v18 = 32;
+        pNumActiveItem = pDialogueWindow->pStartingPosActiveItem;
+        v105 = (149 - v114 * v18 - all_text_height) / 2 - v18 / 2 + 162;
+        if ( pNumActiveItem < pNumActiveItem + pDialogueWindow->pNumPresenceButton )
+        {
+          pItemNum = 2;
+          do
+          {
+            pButton = pDialogueWindow->GetControl(pItemNum);
+            v13 = pButton->msg_param - 36;
+            if ( !byte_4ED970_skill_learn_ability_by_class_table[pPlayer->classType][v13] || pPlayer->pActiveSkills[v13] )
+            {
+              pButton->uW = 0;
+              pButton->uHeight = 0;
+              pButton->uY = 0;
+            }
+            else
+            {
+              pButton->uY = v18 + v105;
+              pTextHeight = pFontArrus->CalcTextHeight(pSkillNames[v13], &dialog_window, 0, 0);
+              pButton->uHeight = pTextHeight;
+              v105 = pButton->uY + pTextHeight - 1;
+              pButton->uW = v105;
+              pColorText = pColorYellow;
+              if ( pDialogueWindow->pCurrentPosActiveItem != pItemNum )
+                pColorText = pColorWhite;
+              dialog_window.DrawTitleText(pFontArrus, 0, pButton->uY, pColorText, pSkillNames[v13], 3);
+            }
+            pNumActiveItem = pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem;
+            pItemNum++;
+          }
+          while ( pItemNum < pNumActiveItem );
+        }
+        return;
+      }
+    }
+    default:
+    {
+      return;// (POINT *)dialog_menu_id - 96;
+    }
+  }
+}
+//----- (004B4FCF) --------------------------------------------------------
+void MagicShopDialog()
+{
+  int result; // eax@6
+  signed int v2; // esi@8
+  unsigned int v3; // ebx@10
+  char *v4; // eax@11
+  char *v5; // eax@12
+  unsigned int v6; // eax@12
+  int v7; // ST08_4@14
+  int v8; // eax@14
+  unsigned __int8 v9; // dl@14
+  char *v10; // ecx@14
+  signed int v11; // esi@16
+  int v12; // ST08_4@19
+  int v13; // eax@19
+  int all_text_height; // edi@21
+  char **v15; // esi@21
+  int v16; // eax@22
+  int v18; // edx@23
+  int v19; // edi@23
+  unsigned __int8 v20; // sf@23
+  GUIButton *control_button; // esi@25
+  const char **v22; // eax@25
+  int v23; // eax@25
+  unsigned int v24; // ecx@25
+  const char **v25; // edx@25
+  unsigned __int16 text_color; // ax@25
+  signed int pTextHeight; // esi@30
+  int v28; // ST08_4@34
+  int v29; // eax@34
+  char *v30; // edx@35
+  void *v32; // eax@40
+  signed int v33; // esi@40
+  unsigned int v34; // esi@42
+  int v35; // eax@42
+  unsigned int v36; // eax@43
+  int v37; // eax@45
+  int v38; // ecx@50
+  int v41; // eax@52
+  char *v42; // eax@54
+  int v43; // eax@54
+  unsigned int v44; // ecx@54
+  int v45; // edx@54
+  int v46; // eax@54
+  unsigned __int16 v47; // ax@54
+  int v48; // eax@58
+  signed int v49; // esi@62
+  Texture *v50; // ecx@64
+  unsigned int v51; // edi@64
+  unsigned int v52; // esi@66
+  int v53; // edx@70
+  Texture *v54; // ecx@76
+  unsigned int v55; // edi@76
+  unsigned int v56; // esi@76
+  int v57; // edx@80
+  unsigned int v59; // edi@86
+  unsigned int v60; // esi@88
+  int v61; // edx@92
+  unsigned int v63; // edi@98
+  unsigned int v64; // esi@100
+  int v65; // edx@104
+  signed int v66; // ecx@109
+  SHORT v67; // di@117
+  bool v68; // eax@117
+  const char *v69; // ecx@119
+  POINT *v70; // esi@124
+  int v71; // ecx@125
+  int v73; // ecx@125
+  int v75; // eax@130
+  int v78; // eax@132
+  int v80; // edx@133
+  int v81; // edi@133
+  const char **v83; // eax@135
+  int v84; // eax@135
+  unsigned int v85; // ecx@135
+  int v86; // edx@135
+  int v89; // [sp-14h] [bp-10Ch]@35
+  int v91; // [sp-10h] [bp-108h]@35
+  unsigned __int16 v92; // [sp-Ch] [bp-104h]@12
+  void *v93; // [sp-Ch] [bp-104h]@14
+  int v94; // [sp-8h] [bp-100h]@11
+  char *v95; // [sp-8h] [bp-100h]@12
+  __int64 *v96; // [sp-4h] [bp-FCh]@11
+  unsigned int v97; // [sp-4h] [bp-FCh]@12
+  POINT v98; // [sp+Ch] [bp-ECh]@8
+  POINT v99; // [sp+14h] [bp-E4h]@16
+  POINT v100; // [sp+1Ch] [bp-DCh]@124
+  POINT v101; // [sp+24h] [bp-D4h]@17
+  POINT v102; // [sp+2Ch] [bp-CCh]@124
+  POINT v103; // [sp+34h] [bp-C4h]@9
+  POINT v104; // [sp+3Ch] [bp-BCh]@31
+  POINT v105; // [sp+44h] [bp-B4h]@16
+  POINT v106; // [sp+4Ch] [bp-ACh]@30
+  POINT v107; // [sp+54h] [bp-A4h]@16
+  POINT v108; // [sp+5Ch] [bp-9Ch]@30
+  POINT a2; // [sp+64h] [bp-94h]@8
+  POINT v110; // [sp+6Ch] [bp-8Ch]@30
+  POINT v111; // [sp+74h] [bp-84h]@8
+  GUIWindow dialog_window; // [sp+7Ch] [bp-7Ch]@1
+  char *Str; // [sp+D0h] [bp-28h]@54
+  int v146; // [sp+D4h] [bp-24h]@23
+  unsigned int pYellowColor; // [sp+D8h] [bp-20h]@1
+  unsigned int pWhiteColor; // [sp+DCh] [bp-1Ch]@1
+  __int32 v117; // [sp+E0h] [bp-18h]@8
+  int v118; // [sp+E4h] [bp-14h]@40
+  const char **v119; // [sp+E8h] [bp-10h]@24
+  int _this; // [sp+ECh] [bp-Ch]@1
+  unsigned __int8 uPlayerID; // [sp+F3h] [bp-5h]@14
+  int v152; // [sp+F4h] [bp-4h]@23
+  int v122;
+  int v114;
+  int pSrtingNum;
+  int pActiveItemNum;
+  ItemGen *item;
+
+  memcpy(&dialog_window, window_SpeakInHouse, sizeof(dialog_window));
+  dialog_window.uFrameX = 483;
+  dialog_window.uFrameWidth = 148;
+  dialog_window.uFrameZ = 334;
+  pWhiteColor = TargetColor(255, 255, 255);
+  pYellowColor = TargetColor(225, 205, 35);
+  if ( dialog_menu_id == HOUSE_DIALOGUE_MAIN)
+  {
+    if ( !sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
+        return;
+    pShopOptions[0] = pGlobalTXT_LocalizationStrings[134]; //"Buy Standard"
+    pShopOptions[1] = pGlobalTXT_LocalizationStrings[152]; //"Buy Special"
+    pShopOptions[2] = pGlobalTXT_LocalizationStrings[159]; //"Display Inventory"
+    pShopOptions[3] = pGlobalTXT_LocalizationStrings[160];
+    all_text_height = 0;
+    for ( int i = 0; i < 4; ++i )
+      all_text_height += pFontArrus->CalcTextHeight(pShopOptions[i], &dialog_window, 0, 0);
+    v146 = (174 - all_text_height) / 4;
+    v23 = (174 - 4 * (174 - all_text_height) / 4 - all_text_height) / 2 - (174 - all_text_height) / 4 / 2 + 138;
+    int j = 0;
+    if ( pDialogueWindow->pNumPresenceButton>=0 )
+    {
+      int th = 2;
+      for (v152 = pDialogueWindow->pStartingPosActiveItem; v152 < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem;  ++v152)
+      {
+        control_button = pDialogueWindow->GetControl(v152);
+        control_button->uY = v146 + v23;
+        pTextHeight = pFontArrus->CalcTextHeight(pShopOptions[j], &dialog_window, 0, 0);
+        control_button->uHeight = pTextHeight;
+        v23 = control_button->uY + control_button->uHeight - 1;
+        control_button->uW = v23;
+        text_color = pYellowColor;
+        if ( pDialogueWindow->pCurrentPosActiveItem != th )
+          text_color = pWhiteColor;
+        dialog_window.DrawTitleText(pFontArrus, 0, control_button->uY, text_color, pShopOptions[j], 3);
+        ++th;               
+        ++j;
+      }
+    }
+    return;
+  }
+  if ( dialog_menu_id == HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
+  {
+    pRenderer->DrawTextureIndexed(8, 8, ShopTexture);
+    v3 = 0;
+    v49 = 0;
+    v122 = 0;
+    do
+    {
+      if ( pParty->StandartItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][v49].uItemID)
+      {
+        v50 = ItemsInShopTexture[v49];
+        v51 = 152 - v50->uTextureHeight;
+        if ( (signed int)v51 < 1 )
+          v51 = 0;
+        v52 = 75 * v49 - v50->uTextureWidth / 2 + 40;
+        if ( v122 )
+        {
+          if ( v122 == 5 )
+          {
+            v53 = ItemsInShopTexture[5]->uTextureWidth;
+            if ( (signed int)v52 > 457 - v53 )
+              v52 = 457 - v53;
+          }
+        }
+        else
+        {
+          if ( (signed int)v52 < 18 )
+            v52 = 18;
+        }
+        pRenderer->DrawTextureTransparent(v52, v51, v50);
+        sub_40F92A(&pRenderer->pActiveZBuffer[v52 + 640 * v51], ItemsInShopTexture[v122], v122 + 1);
+        v49 = v122;
+      }
+      ++v49;
+      v122 = v49;
+    }
+    while ( v49 < 6 );
+    v122 = 0;
+    do
+    {
+      if ( pParty->StandartItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][v122 + 6].uItemID)
+      {
+        v54 = ItemsInShopTexture[v122 + 6];
+        v55 = 306 - v54->uTextureHeight;
+        v56 = 75 * v122 - v54->uTextureWidth / 2 + 40;
+        if ( v122 )
+        {
+          if ( v122 == 5 )
+          {
+            v57 = ItemsInShopTexture[11]->uTextureWidth;
+            if ( (signed int)v56 > 457 - v57 )
+              v56 = 457 - v57;
+          }
+        }
+        else
+        {
+          if ( (signed int)v56 < 18 )
+            v56 = 18;
+        }
+        pRenderer->DrawTextureTransparent(v56, v55, v54);
+        sub_40F92A(&pRenderer->pActiveZBuffer[v56 + 640 * v55], ItemsInShopTexture[v122 + 6], v122 + 7);
+      }
+      ++v122;
+    }
+    while ( v122 < 6 );
+    if ( sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
+    {
+      v66 = 0;
+      v117 = 0;
+      if ( dialog_menu_id == HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
+      {
+        do
+        {
+          if ( pParty->StandartItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][v66].uItemID) //9 * (v66 + 12 * (unsigned int)window_SpeakInHouse->ptr_1C)] )
+            ++v117;
+          ++v66;
+        }
+        while ( v66 < 12 );
+      }
+      else
+      {
+        do
+        {
+          if (pParty->SpecialItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][v66].uItemID)
+            ++v117;
+          ++v66;
+        }
+        while ( v66 < 12 );
+      }
+      v67 = GetAsyncKeyState(VK_CONTROL);
+      v68 = pPlayers[uActiveCharacter]->CanSteal();
+      Str = (char *)v68;
+      if ( v67 && v68 )
+      {
+        v69 = pGlobalTXT_LocalizationStrings[185];// "Steal item"
+      }
+      else
+      {
+        v69 = pGlobalTXT_LocalizationStrings[195];// "Select the Item to Buy"
+        if ( dialog_menu_id != HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
+          v69 = pGlobalTXT_LocalizationStrings[196];// "Select the Special Item to Buy"
+      }
+      DrawTextAtStatusBar(v69, 0);
+      if ( !v117 )
+      {
+        dialog_window.DrawCurrentTime( pParty->field_3C.field_50[(unsigned int)window_SpeakInHouse->ptr_1C] - pParty->uTimePlayed);
+        return;
+      }
+      v70 = pMouse->GetCursorPos(&v102);
+      result = v70->x + pSRZBufferLineOffsets[pMouse->GetCursorPos(&v100)->y];
+      if ( pRenderer->pActiveZBuffer[result] & 0xFFFF )
+      {
+        v71 = (pRenderer->pActiveZBuffer[result] & 0xFFFF) - 1;
+        item = &pParty->StandartItemsInShops[(int)window_SpeakInHouse->ptr_1C][v71];
+        if ( dialog_menu_id != HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
+          item = &pParty->SpecialItemsInShops[(int)window_SpeakInHouse->ptr_1C][v71];
+        if ( v67 && Str )
+          v10 = pGlobalTXT_LocalizationStrings[181];// "Steal %24"
+        else
+        {
+          v75 = pPlayers[uActiveCharacter]->SelectPhrasesTransaction(item, BildingType_MagicShop, (int)window_SpeakInHouse->ptr_1C, 2);
+          v10 = (char *)pMerchantsBuyPhrases[v75];
+        }
+        v30 = BuilDialogueString(v10, uActiveCharacter - 1, item, (char *)window_SpeakInHouse->ptr_1C, 2, 0);
+        v6 = (174 - pFontArrus->CalcTextHeight(v30, &dialog_window, v3, v3)) / 2 + 138;
+        dialog_window.DrawTitleText(pFontArrus, v3, v6, pWhiteColor, v30, 3);
+        return;
+      }
+    }
+    return;
+  }
+  if ( dialog_menu_id == HOUSE_DIALOGUE_SHOP_BUY_SPECIAL)
+  {
+    pRenderer->DrawTextureIndexed(8, 8, ShopTexture);
+    v3 = 0;
+    v49 = 0;
+    v122 = 0;
+    do
+    {
+      if (pParty->SpecialItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][v49].uItemID)
+      {
+        v59 = 152 - ItemsInShopTexture[v49]->uTextureHeight;
+        if ( (signed int)v59 < 1 )
+          v59 = 0;
+        v60 = 75 * v49 - ItemsInShopTexture[v49]->uTextureWidth / 2 + 40;
+        if ( v122 )
+        {
+          if ( v122 == 5 )
+          {
+            v61 = ItemsInShopTexture[5]->uTextureWidth;
+            if ( (signed int)v60 > 457 - v61 )
+              v60 = 457 - v61;
+          }
+        }
+        else
+        {
+          if ( (signed int)v60 < 18 )
+            v60 = 18;
+        }
+        pRenderer->DrawTextureTransparent(v60, v59, ItemsInShopTexture[v49]);
+        sub_40F92A(&pRenderer->pActiveZBuffer[v60 + 640 * v59], ItemsInShopTexture[v122], v122 + 1);
+        v49 = v122;
+      }
+      ++v49;
+      v122 = v49;
+    }
+    while ( v49 < 6 );
+    v122 = 0;
+    do
+    {
+      if (pParty->SpecialItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][v122 + 6].uItemID)
+      {
+        v63 = 306 - ItemsInShopTexture[v122 + 6]->uTextureHeight;
+        if ( (signed int)v63 < 1 )
+          v63 = 0;
+        v64 = 75 * v122 - ItemsInShopTexture[v122 + 6]->uTextureWidth / 2 + 40;
+        if ( v122 )
+        {
+          if ( v122 == 5 )
+          {
+            v65 = ItemsInShopTexture[11]->uTextureWidth;
+            if ( (signed int)v64 > 457 - v65 )
+              v64 = 457 - v65;
+          }
+        }
+        else
+        {
+          if ( (signed int)v64 < 18 )
+            v64 = 18;
+        }
+        pRenderer->DrawTextureTransparent(v64, v63, ItemsInShopTexture[v122 + 6]);
+        sub_40F92A(&pRenderer->pActiveZBuffer[v64 + 640 * v63], ItemsInShopTexture[v122 + 6], v122 + 7);
+      }
+      ++v122;
+    }
+    while ( v122 < 6 );
+    if ( sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
+    {
+      v66 = 0;
+      v117 = 0;
+      if ( dialog_menu_id == HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
+      {
+        do
+        {
+          if ( pParty->StandartItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][v66].uItemID) //9 * (v66 + 12 * (unsigned int)window_SpeakInHouse->ptr_1C)] )
+            ++v117;
+          ++v66;
+        }
+        while ( v66 < 12 );
+      }
+      else
+      {
+        do
+        {
+          if (pParty->SpecialItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][v66].uItemID)
+            ++v117;
+          ++v66;
+        }
+        while ( v66 < 12 );
+      }
+      v67 = GetAsyncKeyState(VK_CONTROL);
+      v68 = pPlayers[uActiveCharacter]->CanSteal();
+      Str = (char *)v68;
+      if ( v67 && v68 )
+      {
+        v69 = pGlobalTXT_LocalizationStrings[185];// "Steal item"
+      }
+      else
+      {
+        v69 = pGlobalTXT_LocalizationStrings[195];// "Select the Item to Buy"
+        if ( dialog_menu_id != HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
+          v69 = pGlobalTXT_LocalizationStrings[196];// "Select the Special Item to Buy"
+      }
+      DrawTextAtStatusBar(v69, 0);
+      if ( !v117 )
+      {
+        dialog_window.DrawCurrentTime( pParty->field_3C.field_50[(unsigned int)window_SpeakInHouse->ptr_1C] - pParty->uTimePlayed);
+        return;
+      }
+      v70 = pMouse->GetCursorPos(&v102);
+      result = v70->x + pSRZBufferLineOffsets[pMouse->GetCursorPos(&v100)->y];
+      if ( pRenderer->pActiveZBuffer[result] & 0xFFFF )
+      {
+        v71 = (pRenderer->pActiveZBuffer[result] & 0xFFFF) - 1;
+        item = &pParty->StandartItemsInShops[(int)window_SpeakInHouse->ptr_1C][v71];
+        if ( dialog_menu_id != HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
+          item = &pParty->SpecialItemsInShops[(int)window_SpeakInHouse->ptr_1C][v71];
+        if ( v67 && Str )
+          v10 = pGlobalTXT_LocalizationStrings[181];// "Steal %24"
+        else
+        {
+          v75 = pPlayers[uActiveCharacter]->SelectPhrasesTransaction(item, BildingType_MagicShop, (int)window_SpeakInHouse->ptr_1C, 2);
+          v10 = (char *)pMerchantsBuyPhrases[v75];
+        }
+        v30 = BuilDialogueString(v10, uActiveCharacter - 1, item, (char *)window_SpeakInHouse->ptr_1C, 2, 0);
+        v6 = (174 - pFontArrus->CalcTextHeight(v30, &dialog_window, v3, v3)) / 2 + 138;
+        dialog_window.DrawTitleText(pFontArrus, v3, v6, pWhiteColor, v30, 3);
+        return;
+      }
+    }
+    return;
+  }
+  if ( dialog_menu_id == HOUSE_DIALOGUE_SHOP_DISPLAY_EQUIPMENT )
+  {
+    draw_leather();
+    CharacterUI_InventoryTab_Draw(pPlayers[uActiveCharacter], true);
+    pShopOptions[0] = pGlobalTXT_LocalizationStrings[200];// "Sell"
+    pShopOptions[1] = pGlobalTXT_LocalizationStrings[113];// "Identify"
+    pShopOptions[2] = pGlobalTXT_LocalizationStrings[179];// "Repair"
+    all_text_height = 0;
+    for ( uint i = 0; i < 3; ++i )
+      all_text_height += pFontArrus->CalcTextHeight(pShopOptions[i], &dialog_window, 0, 0);
+    _this = ((174 - all_text_height) / 3);
+    v81 = (3 * (58 - (signed int)_this) - all_text_height) / 2 - (174 - all_text_height) / 3 / 2 + 138;
+    v20 = -pDialogueWindow->pNumPresenceButton < 0;
+    v118 = pDialogueWindow->pStartingPosActiveItem;
+    if ( v20 ^ (pDialogueWindow->pStartingPosActiveItem > pDialogueWindow->pStartingPosActiveItem + pDialogueWindow->pNumPresenceButton) )
+    {
+      v122 = 2;
+      pSrtingNum = 0;
+      do
+      {
+        control_button = pDialogueWindow->GetControl(v118);
+        control_button->uY = (unsigned int)((char *)_this + v81);
+        pTextHeight = pFontArrus->CalcTextHeight(pShopOptions[pSrtingNum], &dialog_window, 0, 0);
+        v85 = control_button->uY;
+        control_button->uHeight = pTextHeight;
+        v81 = pTextHeight + v85 - 1;
+        control_button->uW = v81;
+        text_color = pYellowColor;
+        if ( pDialogueWindow->pCurrentPosActiveItem != v122 )
+          text_color = pWhiteColor;
+        dialog_window.DrawTitleText(pFontArrus, 0, v85, text_color, pShopOptions[pSrtingNum], 3);
+        ++v122;
+        ++pSrtingNum;
+        ++v118;
+      }
+      while ( v118 < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem );
+    }
+    return;
+  }
+  if ( dialog_menu_id == HOUSE_DIALOGUE_SHOP_SELL)
+  {
+    draw_leather();
+    CharacterUI_InventoryTab_Draw(pPlayers[uActiveCharacter], true);
+    DrawTextAtStatusBar(pGlobalTXT_LocalizationStrings[199], 0);// "Select the Item to Sell"
+    if ( !sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win()
+      || (v11 = pMouse->GetCursorPos(&v107)->x - 14,
+          v117 = (v11 >> 5) + 14 * ((pMouse->GetCursorPos(&v99)->y - 17) >> 5),
+          result = (int)pMouse->GetCursorPos(&v105),
+          *(int *)result <= 13)
+      || (result = (int)pMouse->GetCursorPos(&v101), *(int *)result >= 462)
+      || (result = pPlayers[uActiveCharacter]->GetItemIDAtInventoryIndex((int *)&v117), v3 = 0, !result) )
+      return;
+    item = &pPlayers[uActiveCharacter]->pInventoryItems[result - 1];
+    v13 = pPlayers[uActiveCharacter]->SelectPhrasesTransaction(item, BildingType_MagicShop, (int)window_SpeakInHouse->ptr_1C, 3);
+    v30 = BuilDialogueString((char *)pMerchantsSellPhrases[v13], uActiveCharacter - 1, item, (char *)window_SpeakInHouse->ptr_1C, 3, 0);
+    v6 = (174 - pFontArrus->CalcTextHeight(v30, &dialog_window, v3, v3)) / 2 + 138;
+    dialog_window.DrawTitleText(pFontArrus, v3, v6, pWhiteColor, v30, 3);
+    return;
+  }
+  if ( dialog_menu_id == HOUSE_DIALOGUE_SHOP_IDENTIFY)
+  {
+    draw_leather();
+    CharacterUI_InventoryTab_Draw(pPlayers[uActiveCharacter], true);
+    DrawTextAtStatusBar(pGlobalTXT_LocalizationStrings[197], 0);// "Select the Item to Identify"
+    if ( sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
+    {
+      v2 = pMouse->GetCursorPos(&a2)->x - 14;
+      v117 = (v2 >> 5) + 14 * ((pMouse->GetCursorPos(&v98)->y - 17) >> 5);
+      result = (int)pMouse->GetCursorPos(&v111);
+      if ( *(int *)result > 13 )
+      {
+        result = (int)pMouse->GetCursorPos(&v103);
+        if ( *(int *)result < 462 )
+        {
+          result = pPlayers[uActiveCharacter]->GetItemIDAtInventoryIndex((int *)&v117);
+          if ( result )
+          {
+            item = &pPlayers[uActiveCharacter]->pInventoryItems[result-1];
+            if ( item->uAttributes & 1 )
+            {
+              v5 = BuilDialogueString("%24", uActiveCharacter - 1, item, (char *)window_SpeakInHouse->ptr_1C, 4, 0);
+              v6 = (212 - pFontArrus->CalcTextHeight(v5, &dialog_window, 0, 0)) / 2 + 101;
+              dialog_window.DrawTitleText(pFontArrus, 0, v6, pWhiteColor, v5, 3); 
+              return;
+            }
+            v8 = pPlayers[uActiveCharacter]->SelectPhrasesTransaction(item, BildingType_MagicShop, (int)window_SpeakInHouse->ptr_1C, 4);
+            v30 = BuilDialogueString((char *)pMerchantsIdentifyPhrases[v8], uActiveCharacter - 1, item, (char *)window_SpeakInHouse->ptr_1C, 4, 0);
+            v6 = (174 - pFontArrus->CalcTextHeight(v30, &dialog_window, 0, 0)) / 2 + 138;
+            dialog_window.DrawTitleText(pFontArrus, 0, v6, pWhiteColor, v30, 3);
+            return;
+          }
+        }
+      }
+    }
+    return;
+  }
+  if ( dialog_menu_id == HOUSE_DIALOGUE_SHOP_REPAIR)
+  {
+    draw_leather();
+    CharacterUI_InventoryTab_Draw(pPlayers[uActiveCharacter], true);
+    DrawTextAtStatusBar(pGlobalTXT_LocalizationStrings[198], 0);// "Select the Item to Repair"
+    if ( !sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win()
+      || (pTextHeight = pMouse->GetCursorPos(&v110)->x - 14,
+          v117 = (pTextHeight >> 5) + 14 * ((pMouse->GetCursorPos(&v108)->y - 17) >> 5),
+          result = (int)pMouse->GetCursorPos(&v106),
+          *(int *)result <= 13)
+      || (result = (int)pMouse->GetCursorPos(&v104), *(int *)result >= 462)
+      || (result = pPlayers[uActiveCharacter]->GetItemIDAtInventoryIndex((int *)&v117), v3 = 0, !result)
+     // || (result *= 9, !(pPlayers[uActiveCharacter]->field_1F5[4 * result + 15] & 2)) )
+        || (!(pPlayers[uActiveCharacter]->pOwnItems[result-1].uAttributes& 2)) )
+      return;
+    item = &pPlayers[uActiveCharacter]->pInventoryItems[result - 1];
+    v29 = pPlayers[uActiveCharacter]->SelectPhrasesTransaction(&pPlayers[uActiveCharacter]->pInventoryItems[result - 1], BildingType_MagicShop, (int)window_SpeakInHouse->ptr_1C, 5);
+    v30 = BuilDialogueString((char *)pMerchantsRepairPhrases[v29], uActiveCharacter - 1, item, (char *)window_SpeakInHouse->ptr_1C, 5, 0);
+    v6 = (174 - pFontArrus->CalcTextHeight(v30, &dialog_window, v3, v3)) / 2 + 138;
+    dialog_window.DrawTitleText(pFontArrus, v3, v6, pWhiteColor, v30, 3);
+    return;
+  }
+  if ( dialog_menu_id == HOUSE_DIALOGUE_LEARN_SKILLS )
+  {
+    if ( sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
+    {
+      v3 = 0;
+      all_text_height = 0;
+      v33 = (signed __int64)(p2DEvents[(signed int)window_SpeakInHouse->ptr_1C - 1].flt_24 * 500.0);
+      v119 = (const char **)(v33 * (100 - pPlayers[uActiveCharacter]->GetMerchant()) / 100);
+      if ( (signed int)v119 < v33 / 3 )
+        v119 = (const char **)(v33 / 3);
+      pActiveItemNum = pDialogueWindow->pStartingPosActiveItem;
+      v122 = 0;
+      if ( (signed int)pDialogueWindow->pStartingPosActiveItem >= pDialogueWindow->pStartingPosActiveItem + pDialogueWindow->pNumPresenceButton )
+      {
+        sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[544], pPlayers[uActiveCharacter]->pName, pClassNames[pPlayers[uActiveCharacter]->classType]);// 
+                                            // "Seek knowledge elsewhere %s the %s"
+        strcat(pTmpBuf.data(), "\n \n");
+        strcat(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[528]);// "I can offer you nothing further."
+        v6 = (174 - pFontArrus->CalcTextHeight(pTmpBuf.data(), &dialog_window, 0, 0)) / 2 + 138;
+        dialog_window.DrawTitleText(pFontArrus, v3, v6, pYellowColor, pTmpBuf.data(), 3);
+        return;
+      }
+      do
+      {
+        v36 = pDialogueWindow->GetControl(pActiveItemNum)->msg_param - 36;
+        if ( byte_4ED970_skill_learn_ability_by_class_table[pPlayers[uActiveCharacter]->classType][v36] && !pPlayers[uActiveCharacter]->pActiveSkills[v36] )
+        {
+          all_text_height += pFontArrus->CalcTextHeight(pSkillNames[v36], &dialog_window, 0, 0);
+          ++v122;
+        }
+        ++pActiveItemNum;
+      }
+      while ( pActiveItemNum < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem );
+      if ( !v122 )
+      {
+        sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[544], pPlayers[uActiveCharacter]->pName, pClassNames[pPlayers[uActiveCharacter]->classType]);// 
+                                            // "Seek knowledge elsewhere %s the %s"
+        strcat(pTmpBuf.data(), "\n \n");
+        strcat(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[528]);// "I can offer you nothing further."
+        v6 = (174 - pFontArrus->CalcTextHeight(pTmpBuf.data(), &dialog_window, 0, 0)) / 2 + 138;
+        dialog_window.DrawTitleText(pFontArrus, v3, v6, pYellowColor, pTmpBuf.data(), 3);
+        return;
+      }
+      sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[401], v119);// "Skill Cost: %lu"
+      dialog_window.DrawTitleText(pFontArrus, 0, 0x92u, 0, pTmpBuf.data(), 3u);
+      v119 = (const char **)((149 - all_text_height) / v122);
+      if ( (149 - all_text_height) / v122 > 32 )
+        v119 = (const char **)32;
+      v38 = (149 - v122 * (signed int)v119 - all_text_height) / 2 - (signed int)v119 / 2 + 162;
+      v118 = 2;
+      if ( pDialogueWindow->pStartingPosActiveItem < pDialogueWindow->pStartingPosActiveItem + pDialogueWindow->pNumPresenceButton )
+      {
+        v122 = 2;
+        do
+        {
+          control_button = pDialogueWindow->GetControl(v122);
+          v41 = control_button->msg_param - 36;
+          if ( !byte_4ED970_skill_learn_ability_by_class_table[pPlayers[uActiveCharacter]->classType][v41] || pPlayers[uActiveCharacter]->pActiveSkills[v41] )
+          {
+            control_button->uW = 0;
+            control_button->uHeight = 0;
+            control_button->uY = 0;
+          }
+          else
+          {
+            control_button->uY = (unsigned int)((char *)v119 + v38);
+            pTextHeight = pFontArrus->CalcTextHeight(pSkillNames[v41], &dialog_window, 0, 0);
+            v44 = control_button->uY;
+            control_button->uHeight = pTextHeight;
+            v38 = v44 + pTextHeight - 1;
+            control_button->uW = v38;
+            text_color = pYellowColor;
+            if ( pDialogueWindow->pCurrentPosActiveItem != v122 )
+              text_color = pWhiteColor;
+            dialog_window.DrawTitleText(pFontArrus, 0, v44, text_color, pSkillNames[v41], 3);
+          }
+          ++v122;
+        }
+        while ( v122 < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem );
+      }
+    }
+    return;
+  }
+  return;
+}
+//----- (004BDB56) --------------------------------------------------------
+void __cdecl UIShop_Buy_Identify_Repair()
+{
+  int v8; // eax@15
+  unsigned int pItemID; // esi@20
+  ItemGen *item; // esi@21
+  unsigned int v15; // eax@33
+  POINT *pCursorPos; // esi@37
+  int v18; // ecx@37
+  float pPriceMultiplier; // ST1C_4@38
+  int taken_item; // eax@40
+  ItemGen *bought_item; // esi@51
+  int party_reputation; // eax@55
+  int v39; // eax@63
+  int v42; // esi@74
+  signed int v43; // ebx@74
+  unsigned __int16 *pSkill; // esi@77
+  int v55; // [sp+0h] [bp-B4h]@26
+  POINT cursor; // [sp+40h] [bp-74h]@37
+  int a6; // [sp+98h] [bp-1Ch]@57
+  int a3; // [sp+9Ch] [bp-18h]@53
+  unsigned int uNumSeconds; // [sp+A4h] [bp-10h]@53
+  unsigned int v79; // [sp+A8h] [bp-Ch]@9
+  int uPriceItemService; // [sp+ACh] [bp-8h]@12
+
+  if ( pCurrentScreen == SCREEN_E )
+  {
+    OnInventoryLeftClick();
+    return;
+  }
+  if ( !sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
+  {
+    pAudioPlayer->PlaySound(SOUND_27, 0, 0, -1, 0, 0, 0, 0);
+    return;
+  }
+
+  switch(dialog_menu_id)
+  {
+    case HOUSE_DIALOGUE_SHOP_DISPLAY_EQUIPMENT:
+    {
+      pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] = 103;
+      OnInventoryLeftClick();
+      break;
+    }
+    case HOUSE_DIALOGUE_GUILD_BUY_BOOKS:
+    {
+      pCursorPos = pMouse->GetCursorPos(&cursor);
+      v18 = pRenderer->pActiveZBuffer[pCursorPos->x + pSRZBufferLineOffsets[pMouse->GetCursorPos(&cursor)->y]] & 0xFFFF;
+      if ( !v18 )
+        return;
+      bought_item = (ItemGen *)(&pParty->pPlayers[1].uExpressionTimeLength + 18 * (v18 + 12 * (int)window_SpeakInHouse->ptr_1C));
+      pPriceMultiplier = p2DEvents[(signed int)window_SpeakInHouse->ptr_1C - 1].fPriceMultiplier;
+      uPriceItemService = pPlayers[uActiveCharacter]->GetBuyingPrice(bought_item->GetValue(), pPriceMultiplier);
+      GetAsyncKeyState(VK_CONTROL);
+      if ( pParty->uNumGold < uPriceItemService )
+      {
+        PlayHouseSound((unsigned int)window_SpeakInHouse->ptr_1C, (HouseSoundID)2);
+        ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2);
+        return;
+      }
+      taken_item = pPlayers[uActiveCharacter]->AddItem(-1, bought_item->uItemID);
+      if ( taken_item )
+      {
+        bought_item->SetIdentified();
+        memcpy(&pPlayers[uActiveCharacter]->pInventoryItems[taken_item - 1], bought_item, 0x24u);
+        dword_F8B1E4 = 1;
+        Party::TakeGold(uPriceItemService);
+        viewparams->bRedrawGameUI = 1;
+        bought_item->Reset();
+        pRenderer->ClearZBuffer(0, 479);
+        pPlayers[uActiveCharacter]->PlaySound((PlayerSpeech)SPEECH_75, 0);
+        return;
+      }
+      pPlayers[uActiveCharacter]->PlaySound(SPEECH_NoRoom, 0);
+      ShowStatusBarString(pGlobalTXT_LocalizationStrings[563], 5);  // "Pack is Full!"
+      break;
+    }
+    case HOUSE_DIALOGUE_SHOP_SELL:
+    {
+      v79 = ((pMouse->GetCursorPos(&cursor)->x - 14) >> 5) + 14 * ((pMouse->GetCursorPos(&cursor)->y - 17) >> 5);
+      if ( pMouse->GetCursorPos(&cursor)->x <= 13
+        || pMouse->GetCursorPos(&cursor)->x >= 462
+        || (v15 = pPlayers[uActiveCharacter]->GetItemIDAtInventoryIndex((int *)&v79), !v15) )
+          return;
+      if ( MerchandiseTest(&pPlayers[uActiveCharacter]->pInventoryItems[v15 - 1], (int)window_SpeakInHouse->ptr_1C) )
+      {
+        dword_F8B1E4 = 1;
+        pPlayers[uActiveCharacter]->SalesProcess(v79, v15 - 1, (int)window_SpeakInHouse->ptr_1C);
+        viewparams->bRedrawGameUI = 1;
+        pRenderer->ClearZBuffer(0, 479);
+        pPlayers[uActiveCharacter]->PlaySound((PlayerSpeech)77, 0);
+        return;
+      }
+      pPlayers[uActiveCharacter]->PlaySound(SPEECH_79, 0);
+      pAudioPlayer->PlaySound(SOUND_27, 0, 0, -1, 0, 0, 0, 0);
+      break;
+    }
+    case HOUSE_DIALOGUE_SHOP_IDENTIFY:
+    {
+      pMouse->GetCursorPos(&cursor);
+      v79 = ((cursor.x - 14) >> 5) + 14 * ((cursor.y - 17) >> 5);
+      if (cursor.x > 13  && cursor.x < 462)
+      {
+        pItemID = pPlayers[uActiveCharacter]->GetItemIDAtInventoryIndex((int *)&v79);
+        if ( pItemID )
+        {
+          uPriceItemService = pPlayers[uActiveCharacter]->GetPriceIdentification(p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].fPriceMultiplier);
+          item = &pPlayers[uActiveCharacter]->pInventoryItems[pItemID - 1];
+          if ( !(item->uAttributes & 1) )
+          {
+            if ( MerchandiseTest(item, (int)window_SpeakInHouse->ptr_1C) )
+            {
+              if ( pParty->uNumGold >= uPriceItemService )
+              {
+                dword_F8B1E4 = 1;
+                Party::TakeGold(uPriceItemService);
+                item->uAttributes |= 1;
+                pPlayers[uActiveCharacter]->PlaySound(SPEECH_73, 0);
+                ShowStatusBarString(pGlobalTXT_LocalizationStrings[569], 2);
+                return;
+              }
+              PlayHouseSound((unsigned int)window_SpeakInHouse->ptr_1C, (HouseSoundID)2);
+              return;
+            }
+            pAudioPlayer->PlaySound(SOUND_27, 0, 0, -1, 0, 0, 0, 0);
+            pPlayers[uActiveCharacter]->PlaySound((PlayerSpeech)79, 0);
+            return;
+          }
+          pPlayers[uActiveCharacter]->PlaySound((PlayerSpeech)76, 0);
+          return;
+        }
+      }
+      break;
+    }
+    case HOUSE_DIALOGUE_SHOP_REPAIR:
+    {
+      v79 = ((pMouse->GetCursorPos(&cursor)->x - 14) >> 5) + 14 * ((pMouse->GetCursorPos(&cursor)->y - 17) >> 5);
+      if ( pMouse->GetCursorPos(&cursor)->x > 13 )
+      {
+        if ( pMouse->GetCursorPos(&cursor)->x < 462 )
+        {
+          pItemID = pPlayers[uActiveCharacter]->GetItemIDAtInventoryIndex((int *)&v79);
+          if ( pItemID )
+          {
+            item = &pPlayers[uActiveCharacter]->pInventoryItems[pItemID - 1];
+            pPriceMultiplier = p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].fPriceMultiplier;
+            auto _v = (ItemGen *)&pPlayers[uActiveCharacter]->pInventoryItems[pItemID - 1];
+            uPriceItemService = pPlayers[uActiveCharacter]->GetPriceRepair(_v->GetValue(), pPriceMultiplier);
+            if ( item->uAttributes & 2 )
+            {
+              if ( MerchandiseTest(item, (int)window_SpeakInHouse->ptr_1C) )
+              {
+                if ( pParty->uNumGold >= uPriceItemService )
+                {
+                  dword_F8B1E4 = 1;
+                  Party::TakeGold(uPriceItemService);
+                  v8 = item->uAttributes;
+                  LOBYTE(v8) = v8 & 0xFD;
+                  item->uAttributes = v8 | 1;
+                  pPlayers[uActiveCharacter]->PlaySound(SPEECH_74, 0);
+                  ShowStatusBarString(pGlobalTXT_LocalizationStrings[570], 2);
+                  return;
+                }
+                PlayHouseSound((unsigned int)window_SpeakInHouse->ptr_1C, (HouseSoundID)2);
+                return;
+              }
+              pAudioPlayer->PlaySound(SOUND_27, 0, 0, -1, 0, 0, 0, 0);
+              pPlayers[uActiveCharacter]->PlaySound((PlayerSpeech)79, 0);
+              return;
+            }
+            pPlayers[uActiveCharacter]->PlaySound((PlayerSpeech)76, 0);
+            return;
+          }
+        }
+      }
+      break;
+    }
+    case HOUSE_DIALOGUE_SHOP_BUY_STANDARD:
+    case HOUSE_DIALOGUE_SHOP_BUY_SPECIAL:
+    {
+      pCursorPos = pMouse->GetCursorPos(&cursor);
+      v18 = pRenderer->pActiveZBuffer[pCursorPos->x + pSRZBufferLineOffsets[pCursorPos->y]] & 0xFFFF;
+      if ( !v18 )
+        return;
+      if ( dialog_menu_id == HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
+        bought_item = (ItemGen *)&pParty->StandartItemsInShops[(int)window_SpeakInHouse->ptr_1C][v18 - 1];
+      else
+        bought_item = &pParty->SpecialItemsInShops[(int)window_SpeakInHouse->ptr_1C][v18 - 1];//(ItemGen *)&pParty->field_C59C[v31 + 724];
+      uPriceItemService = pPlayers[uActiveCharacter]->GetBuyingPrice(bought_item->GetValue(), p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].fPriceMultiplier);
+      uNumSeconds = 0;
+      a3 = 0;
+      if ( pMapStats->GetMapInfo(pCurrentMapName.data()) )
+        a3 = pMapStats->pInfos[pMapStats->GetMapInfo(pCurrentMapName.data())]._steal_perm;
+      party_reputation = GetPartyReputation();
+      if (pPlayers[uActiveCharacter]->CanSteal())
+      {
+        if ( GetAsyncKeyState(VK_CONTROL) )
+        {
+          uNumSeconds = pPlayers[uActiveCharacter]->StealFromShop(bought_item, a3, party_reputation, 0, &a6);
+          if ( !uNumSeconds )
+          {
+            sub_4B1447_party_fine((int)window_SpeakInHouse->ptr_1C, 0, a6);
+            return;
+          }
+        }
+      }
+      if ( pParty->uNumGold < uPriceItemService )
+      {
+        if ( uNumSeconds != 2 )
+        {
+          if ( uNumSeconds != 1 )
+          {
+            PlayHouseSound((unsigned int)window_SpeakInHouse->ptr_1C, (HouseSoundID)2);
+            ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2);// "You don't have enough gold"
+            return;
+          }
+        }
+      }
+      v39 = pPlayers[uActiveCharacter]->AddItem(-1, bought_item->uItemID);
+      if ( v39 )
+      {
+        bought_item->SetIdentified();
+        memcpy(&pPlayers[uActiveCharacter]->pInventoryItems[v39 - 1], bought_item, sizeof(ItemGen));
+        if ( pPlayers[uActiveCharacter]->CanSteal() )
+        {
+          if ( GetAsyncKeyState(VK_CONTROL) )
+          {
+            if ( uNumSeconds == 1 || uNumSeconds == 2 )
+            {
+              pPlayers[uActiveCharacter]->pInventoryItems[v39 - 1].SetStolen();
+              sub_4B1447_party_fine((int)window_SpeakInHouse->ptr_1C, uNumSeconds, a6);
+              viewparams->bRedrawGameUI = 1;
+              bought_item->Reset();
+              pRenderer->ClearZBuffer(0, 479);
+              pPlayers[uActiveCharacter]->PlaySound((PlayerSpeech)SPEECH_75, 0);
+              return;
+            }
+          }
+        }
+        dword_F8B1E4 = 1;
+        Party::TakeGold(uPriceItemService);
+        viewparams->bRedrawGameUI = 1;
+        bought_item->Reset();
+        pRenderer->ClearZBuffer(0, 479);
+        pPlayers[uActiveCharacter]->PlaySound((PlayerSpeech)SPEECH_75, 0);
+        return;
+      }
+      pPlayers[uActiveCharacter]->PlaySound(SPEECH_NoRoom, 0);
+      ShowStatusBarString(pGlobalTXT_LocalizationStrings[563], 2); // "Pack is Full!"
+      break;
+    }
+    default:// if click video screen in shop
+    {
+      __debugbreak(); // please do record these dialogue ids to the HOUSE_DIALOGUE_MENU  enum
+      if( dialog_menu_id >= 36 && dialog_menu_id <= 72 )
+      {
+        v42 = dialog_menu_id - 36;
+        //v43 = (signed __int64)(*(float *)&p2DEvents_minus1__24[13 * (unsigned int)ptr_507BC0->ptr_1C] * 500.0);
+        v43 = (signed __int64)(p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].flt_24 * 500.0);
+        uPriceItemService = v43 * (100 - pPlayers[uActiveCharacter]->GetMerchant()) / 100;
+        if ( uPriceItemService < v43 / 3 )
+          uPriceItemService = v43 / 3;
+        if ( byte_4ED970_skill_learn_ability_by_class_table[pPlayers[uActiveCharacter]->classType][v42] )
+        {
+          pSkill = &pPlayers[uActiveCharacter]->pActiveSkills[v42];
+          if ( !*pSkill )
+          {
+            if ( pParty->uNumGold < uPriceItemService )
+            {
+              ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2);// "You don't have enough gold"
+              if ( in_current_building_type == BildingType_Training )
+                v55 = 4;
+              else
+                v55 = 2;
+              PlayHouseSound((unsigned int)window_SpeakInHouse->ptr_1C, (HouseSoundID)v55);
+              return;
+            }
+            Party::TakeGold(uPriceItemService);
+            dword_F8B1E4 = 1;
+           *pSkill = 1;
+            pPlayers[uActiveCharacter]->PlaySound((PlayerSpeech)78, 0);
+            return;
+          }
+        }
+      }
+      break;
+    }
+  }
+}
+//----- (004B1A2D) --------------------------------------------------------
+void __cdecl ShowPopupShopItem()
+{
+  POINT *v1; // esi@5
+  unsigned int v2; // eax@5
+  int v3; // ecx@5
+  POINT *v4; // esi@12
+  int v5; // eax@12
+  unsigned int v6; // eax@13
+  ItemGen *v7; // ecx@13
+  signed int v8; // esi@17
+  unsigned int v9; // eax@19
+  POINT v10; // [sp+8h] [bp-44h]@12
+  POINT v11; // [sp+10h] [bp-3Ch]@12
+  POINT  v12; // [sp+18h] [bp-34h]@18
+  POINT  v13; // [sp+20h] [bp-2Ch]@17
+  POINT v14; // [sp+28h] [bp-24h]@17
+  POINT  v15; // [sp+30h] [bp-1Ch]@17
+  POINT v16; // [sp+38h] [bp-14h]@5
+  POINT a2; // [sp+40h] [bp-Ch]@5
+
+  if ( in_current_building_type <= 0 )
+    return;
+  if ( in_current_building_type <= BildingType_AlchemistShop )
+  {
+    if ( dialog_menu_id != HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
+    {
+      if ( dialog_menu_id <= HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
+        return;
+      if ( dialog_menu_id <= HOUSE_DIALOGUE_SHOP_REPAIR || dialog_menu_id == HOUSE_DIALOGUE_SHOP_DISPLAY_EQUIPMENT )
+      {
+        v8 = pMouse->GetCursorPos(&v15)->x - 14;
+        v5 = (v8 >> 5) + 14 * ((pMouse->GetCursorPos(&v14)->y - 17) >> 5);
+        if ( pMouse->GetCursorPos(&v13)->x <= 13
+          || pMouse->GetCursorPos(&v12)->x >= 462
+          || (v9 = pPlayers[uActiveCharacter]->GetItemIDAtInventoryIndex(&v5)) == 0 )
+          return;
+        GameUI_DrawItemInfo(&pPlayers[uActiveCharacter]->pInventoryItems[v9 - 1]);
+        return;
+      }
+      if ( dialog_menu_id != HOUSE_DIALOGUE_SHOP_BUY_SPECIAL )
+        return;
+    }
+    v4 = pMouse->GetCursorPos(&v11);
+    v5 = pRenderer->pActiveZBuffer[v4->x + pSRZBufferLineOffsets[pMouse->GetCursorPos(&v10)->y]] & 0xFFFF;
+    if ( !v5 )
+      return;
+    v6 = 9 * (v5 + 12 * (unsigned int)window_SpeakInHouse->ptr_1C);
+    v7 = (ItemGen *)((char *)&pParty->pPickedItem + 4 * v6 + 4);
+    if ( dialog_menu_id != HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
+      v7 = &pParty->SpecialItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][v5 - 1];
+    GameUI_DrawItemInfo(v7);
+    return;
+  }
+  if ( in_current_building_type <= BildingType_16 && dialog_menu_id == HOUSE_DIALOGUE_GUILD_BUY_BOOKS )
+  {
+    v1 = pMouse->GetCursorPos(&a2);
+    v2 = v1->x + pSRZBufferLineOffsets[pMouse->GetCursorPos(&v16)->y];
+    v3 = pRenderer->pActiveZBuffer[v2] & 0xFFFF;
+    v5 = pRenderer->pActiveZBuffer[v2] & 0xFFFF;
+    if ( v5 )
+      sub_4B1523((int *)&pParty->pPlayers[1].uExpressionTimeLength + 9 * (v3 + 12 * (unsigned int)window_SpeakInHouse->ptr_1C));
+  }
+}
+//----- (004B1D27) --------------------------------------------------------
+void __cdecl sub_4B1D27()
+{
+  int v0; // edx@2
+  unsigned int v1; // ecx@7
+  signed int v2; // edi@10
+  int v3; // esi@10
+  __int16 v4; // ax@15
+  signed int v5; // edi@20
+  int v6; // esi@20
+  int v7[4]; // [sp+Ch] [bp-10h]@12
+
+  if ( in_current_building_type > 0 )
+  {
+    v0 = 3;
+    if ( in_current_building_type > BildingType_MagicShop )
+    {
+      if ( in_current_building_type == BildingType_Bank )
+      {
+        if ( !dword_F8B1E4 )
+          return;
+      }
+      else
+      {
+        if ( in_current_building_type != BildingType_Temple )
+          return;
+      }
+      v1 = (unsigned int)window_SpeakInHouse->ptr_1C;
+      PlayHouseSound(v1, (HouseSoundID)v0);
+      return;
+    }
+    v1 = (unsigned int)window_SpeakInHouse->ptr_1C;
+    if ( (signed __int64)pParty->field_3C._shop_ban_times[v1 ]<= (signed __int64)pParty->uTimePlayed )
+    {
+      if ( pParty->uNumGold <= 0x2710 )
+      {
+        if ( !dword_F8B1E4 )
+          return;
+        v0 = 4;
+        PlayHouseSound(v1, (HouseSoundID)v0);
+        return;
+      }
+      PlayHouseSound(v1, (HouseSoundID)(dword_F8B1E4 + 3));
+      if ( !dword_F8B1E4 && !qword_A750D8 )
+      {
+        v5 = 0;
+        v6 = 1;
+        do
+        {
+          if ( pPlayers[v6]->CanAct() )
+            v7[v5++] = v6;
+          ++v6;
+        }
+        while ( v6 <= 4 );
+        if ( v5 )
+        {
+          qword_A750D8 = 256i64;
+          word_A750E0 = 80;
+          v4 = LOWORD(v7[rand() % v5]);
+          word_A750E2 = v4;
+          return;
+        }
+      }
+    }
+    else
+    {
+      if ( !qword_A750D8 )
+      {
+        v2 = 0;
+        v3 = 1;
+        do
+        {
+          if ( pPlayers[v3]->CanAct() )
+            v7[v2++] = v3;
+          ++v3;
+        }
+        while ( v3 <= 4 );
+        if ( v2 )
+        {
+          qword_A750D8 = 256i64;
+          word_A750E0 = 80;
+          v4 = LOWORD(v7[rand() % v2]);
+          word_A750E2 = v4;
+          return;
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/UI/UITransition.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -0,0 +1,254 @@
+#ifdef _MSC_VER
+#define _CRT_SECURE_NO_WARNINGS
+#endif
+
+#include <assert.h>
+#include <io.h>
+
+#include "..\mm7_data.h"
+#include "..\VideoPlayer.h"
+#include "..\MapInfo.h"
+#include "..\GUIWindow.h"
+#include "..\GUIFont.h"
+#include "..\GUIProgressBar.h"
+#include "..\Party.h"
+#include "..\AudioPlayer.h"
+#include "..\Outdoor.h"
+#include "..\LOD.h"
+#include "..\Time.h"
+#include "..\stru159.h"
+#include "..\Events2D.h"
+#include "..\texts.h"
+#include "UIHouses.h"
+
+
+
+
+
+//----- (00444839) --------------------------------------------------------
+void TransitionUI_Load(uint anim_id, uint exit_pic_id, int x, int y, int z, int directiony, int directionx, int a8, const char *pLocationName)
+{
+  //unsigned int v9; // ebx@1
+  //int v10; // edi@1
+  //signed int v11; // eax@1
+  unsigned int v12; // eax@6
+  const char *v13; // ST0C_4@6
+  unsigned int v14; // eax@8
+  const char *v15; // eax@14
+  unsigned int v16; // eax@16
+  //unsigned int result; // eax@26
+  const char *v18; // [sp-8h] [bp-40h]@9
+  //const char *v19; // [sp-4h] [bp-3Ch]@2
+  char *v20; // [sp-4h] [bp-3Ch]@9
+  const char *v21; // [sp-4h] [bp-3Ch]@11
+  char pContainer[40]; // [sp+Ch] [bp-2Ch]@1
+  unsigned int v23; // [sp+34h] [bp-4h]@1
+
+  //v9 = a1;
+  //v10 = a2;
+  v23 = IndoorLocation::GetLocationIndex(pLocationName);
+  dword_59117C_teleportx = x;
+  dword_591178_teleporty = y;
+  dword_591174_teleportz = z;
+  dword_591170_teleport_directiony = directiony;
+  dword_59116C_teleport_directionx = directionx;
+  dword_591168_teleport_speedz = a8;
+  dword_591164_teleport_map_name = (char *)pLocationName;
+  uCurrentHouse_Animation = anim_id;
+  pEventTimer->Pause();
+  pAudioPlayer->StopChannels(-1, -1);
+
+  switch (pParty->alignment)
+  {
+    case PartyAlignment_Good:    sprintfex(pContainer, "evt%02d-b", const_2()); break;
+    case PartyAlignment_Neutral: sprintfex(pContainer, "evt%02d", const_2());   break;
+    case PartyAlignment_Evil:    sprintfex(pContainer, "evt%02d-c", const_2()); break;
+    default: assert(false);
+  }
+
+  v12 = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+  v13 = pHouse_ExitPictures[exit_pic_id];
+  pTexture_Dialogue_Background = &pIcons_LOD->pTextures[v12];
+  pTexture_outside = pIcons_LOD->LoadTexturePtr(v13, TEXTURE_16BIT_PALETTE);
+  if (anim_id)
+  {
+    if ( !v23 )
+      //pVideoPlayer->OpenHouseMovie(pAnimatedRooms[p2DEvents_minus1___02[26 * v9]].field_0, 1u);
+      pVideoPlayer->OpenHouseMovie(pAnimatedRooms[p2DEvents[anim_id - 1].uAnimationID].video_name, 1);
+  }
+  else if ( !v23 )
+  {
+      v14 = pMapStats->GetMapInfo(pCurrentMapName.data());
+      if ( v14 )
+      {
+        sprintfex(sHouseName.data(), pGlobalTXT_LocalizationStrings[410], pMapStats->pInfos[v14].pName); // "Leave %s"
+        goto LABEL_20;
+      }
+      v21 = pGlobalTXT_LocalizationStrings[79];
+      goto LABEL_19;
+  }
+  v15 = pLocationName;
+  if ( *pLocationName == 48 )
+    v15 = pCurrentMapName.data();
+  v16 = pMapStats->GetMapInfo(v15);
+  if ( v16 )
+  {
+    sprintfex(sHouseName.data(), pGlobalTXT_LocalizationStrings[411], pMapStats->pInfos[v16].pName);
+    goto LABEL_20;
+  }
+  v21 = pGlobalTXT_LocalizationStrings[73];
+LABEL_19:
+  strcpy(sHouseName.data(), v21);
+LABEL_20:
+  pDialogueWindow = GUIWindow::Create(0, 0, 640, 480, WINDOW_Transition, 0, sHouseName.data());
+  //if ( BYTE1(pAnimatedRooms[p2DEvents_minus1___02[26 * v9]].field_C) )
+  if ( pAnimatedRooms[p2DEvents[anim_id].uAnimationID].uRoomSoundId )
+    PlayHouseSound(anim_id, HouseSound_Greeting);
+  if ( uCurrentlyLoadedLevelType == LEVEL_Indoor && uActiveCharacter && pParty->uFlags & 0x30 )
+    pPlayers[uActiveCharacter]->PlaySound(SPEECH_47, 0);
+  if ( v23 )
+    uCurrentHouse_Animation = v23;
+}
+
+
+
+
+//----- (00444C8F) --------------------------------------------------------
+void TravelUI_Load()
+{
+  //signed int v0; // eax@1
+  unsigned int v1; // eax@6
+  GUIWindow *result; // eax@9
+  //const char *v3; // [sp-4h] [bp-2Ch]@2
+  char pContainer[32]; // [sp+0h] [bp-28h]@1
+
+  pEventTimer->Pause();
+
+  switch (pParty->alignment)
+  {
+    case PartyAlignment_Good:    sprintfex(pContainer, "evt%02d-b", const_2()); break;
+    case PartyAlignment_Neutral: sprintfex(pContainer, "evt%02d", const_2());   break;
+    case PartyAlignment_Evil:    sprintfex(pContainer, "evt%02d-c", const_2()); break;
+    default: assert(false);
+  }
+
+  pTexture_Dialogue_Background = pIcons_LOD->LoadTexturePtr(pContainer, TEXTURE_16BIT_PALETTE);
+  pTexture_outside = pIcons_LOD->LoadTexturePtr("outside", TEXTURE_16BIT_PALETTE);
+  v1 = pMapStats->GetMapInfo(pCurrentMapName.data());
+  if ( v1 )
+    sprintfex(sHouseName.data(), pGlobalTXT_LocalizationStrings[410], pMapStats->pInfos[v1].pName);// "Leave %s"
+  else
+    strcpy(sHouseName.data(), pGlobalTXT_LocalizationStrings[79]);// "Exit"
+  pDialogueWindow = GUIWindow::Create(0, 0, 640, 480, WINDOW_ChangeLocation, 0, sHouseName.data());
+}
+
+
+
+//----- (00444DCA) --------------------------------------------------------
+void TravelUI_Draw()
+{
+  unsigned int v0; // edi@1
+  MapInfo *v1; // edi@2
+  signed int v3; // eax@2
+  int v4; // eax@5
+  const char *v5; // [sp-Ch] [bp-90h]@3
+  signed int v6; // [sp-8h] [bp-8Ch]@3
+  GUIWindow v7; // [sp+Ch] [bp-78h]@1
+  char pDestinationMapName[32]; // [sp+60h] [bp-24h]@1
+  unsigned int v9; // [sp+80h] [bp-4h]@1
+
+  memcpy(&v7, pPrimaryWindow, sizeof(v7));
+  v9 = pMapStats->GetMapInfo(pCurrentMapName.data());
+  pOutdoor->GetTravelDestination(pParty->vPosition.x, pParty->vPosition.y, pDestinationMapName, 20);
+  v0 = pMapStats->GetMapInfo(pDestinationMapName);
+  pRenderer->DrawTextureIndexed(0x1DDu, 0, pTexture_Dialogue_Background);
+  pRenderer->DrawTextureTransparent(0x1D4u, 0, &pIcons_LOD->pTextures[uTextureID_right_panel_loop]);
+  pRenderer->DrawTextureIndexed(pNPCPortraits_x[0][0], pNPCPortraits_y[0][0], pTexture_outside);
+  pRenderer->DrawTextureIndexed(0x22Cu, 0x1C3u, pIcons_LOD->GetTexture(uTextureID_x_x_u));
+  pRenderer->DrawTextureIndexed(0x1DCu, 0x1C3u, pIcons_LOD->GetTexture(uTextureID_x_ok_u));
+  if ( v0 )
+  {
+    v1 = &pMapStats->pInfos[v0];
+    v7.uFrameX = 493;
+    v7.uFrameWidth = 126;
+    v7.uFrameZ = 366;
+    v7.DrawTitleText(pFontCreate, 0, 4u, 0, v1->pName, 3);
+    v7.uFrameX = 483;
+    v7.uFrameWidth = 148;
+    v7.uFrameZ = 334;
+    v3 = GetTravelTime();
+    if ( v3 == 1 )
+    {
+      v6 = 1;
+      v5 = pGlobalTXT_LocalizationStrings[663]; // "It will take %d day to cross to %s."
+    }
+    else
+    {
+      v6 = v3;
+      v5 = pGlobalTXT_LocalizationStrings[128]; // "It will take %d days to travel to %s."
+    }
+    sprintfex(pTmpBuf.data(), v5, v6, v1->pName);
+    strcat(pTmpBuf.data(), "\n \n");
+    sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[126], pMapStats->pInfos[v9].pName);
+    strcat(pTmpBuf.data(), pTmpBuf2.data());
+    v4 = pFontCreate->CalcTextHeight(pTmpBuf.data(), &v7, 0, 0);
+    v7.DrawTitleText(pFontCreate, 0, (212 - v4) / 2 + 101, 0, pTmpBuf.data(), 3);
+    _unused_5B5924_is_travel_ui_drawn = 1;
+  }
+}
+
+
+
+//----- (00444A51) --------------------------------------------------------
+void TransitionUI_Draw()
+{
+  MapInfo *pMapInfo; // esi@5
+  char *v1; // eax@6
+  std::string v3; // [sp-18h] [bp-84h]@11
+  unsigned int v4; // [sp-10h] [bp-7Ch]@12
+  int v5; // [sp-Ch] [bp-78h]@12
+  const char *v6; // [sp-8h] [bp-74h]@11
+  signed int v7; // [sp-4h] [bp-70h]@11
+  GUIWindow v8; // [sp+Ch] [bp-60h]@1
+  unsigned int v9; // [sp+60h] [bp-Ch]@1
+  unsigned int v10; // [sp+64h] [bp-8h]@1
+  int a3; // [sp+6Bh] [bp-1h]@11
+
+  memcpy(&v8, pPrimaryWindow, sizeof(v8));
+  v10 = pMapStats->GetMapInfo(pCurrentMapName.data());
+  v9 = IndoorLocation::GetLocationIndex(dword_591164_teleport_map_name);
+  pRenderer->DrawTextureIndexed(0x1DDu, 0, pTexture_Dialogue_Background);
+  pRenderer->DrawTextureIndexed(pNPCPortraits_x[0][0] - 4, pNPCPortraits_y[0][0] - 4, pIcons_LOD->GetTexture(uTextureID_50795C));
+  pRenderer->DrawTextureIndexed(pNPCPortraits_x[0][0], pNPCPortraits_y[0][0], pTexture_outside);
+  uTextureID_right_panel_loop = uTextureID_right_panel;
+  pRenderer->DrawTextureTransparent(468, 0, pIcons_LOD->GetTexture(uTextureID_right_panel));
+  pRenderer->DrawTextureIndexed(556, 451, pIcons_LOD->GetTexture(uTextureID_x_x_u));
+  pRenderer->DrawTextureIndexed(476, 451, pIcons_LOD->GetTexture(uTextureID_x_ok_u));
+  if ( (pVideoPlayer->AnyMovieLoaded() || v9) && *dword_591164_teleport_map_name != ' ' )
+    v10 = pMapStats->GetMapInfo(dword_591164_teleport_map_name);
+  pMapInfo = &pMapStats->pInfos[v10];
+  v8.uFrameX = 493;
+  v8.uFrameWidth = 126;
+  v8.uFrameZ = 366;
+  v8.DrawTitleText(pFontCreate, 0, 5u, 0, pMapInfo->pName, 3);
+  v8.uFrameX = 483;
+  v8.uFrameWidth = 148;
+  v8.uFrameZ = 334;
+
+  v1 = "";
+  if ( uCurrentHouse_Animation )
+  {
+    v1 = pTransitionStrings[uCurrentHouse_Animation];
+    v4 = (212 - pFontCreate->CalcTextHeight(v1, &v8, 0, 0)) / 2 + 101;
+    v8.DrawTitleText(pFontCreate, 0, v4, 0, v1, 3);
+  }
+  else if ( v10 )
+  {
+    sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[409], pMapInfo->pName);// "Do you wish to leave %s?"
+    v4 = (212 - pFontCreate->CalcTextHeight(pTmpBuf.data(), &v8, 0, 0)) / 2 + 101;
+    v8.DrawTitleText(pFontCreate, 0, v4, 0, pTmpBuf.data(), 3);
+  }
+  else assert(false);
+
+  _unused_5B5924_is_travel_ui_drawn = true;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/UI/UiGame.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -0,0 +1,2977 @@
+#ifdef _MSC_VER
+#define _CRT_SECURE_NO_WARNINGS
+#endif
+
+#include <assert.h>
+
+#include "..\Texture.h"
+#include "..\MM7.h"
+
+#include "..\Mouse.h"
+#include "..\Keyboard.h"
+#include "..\mm7_data.h"
+
+#include "..\Vis.h"
+#include "..\MapInfo.h"
+#include "..\Game.h"
+#include "..\GUIWindow.h"
+#include "..\GUIFont.h"
+#include "..\Party.h"
+#include "..\AudioPlayer.h"
+#include "..\Outdoor.h"
+#include "..\LOD.h"
+#include "..\Actor.h"
+#include "..\Viewport.h"
+#include "..\SpriteObject.h"
+#include "..\ObjectList.h"
+#include "..\DecorationList.h"
+#include "..\PlayerFrameTable.h"
+#include "..\stru123.h"
+#include "..\Time.h"
+#include "..\IconFrameTable.h"
+#include "..\TurnEngine.h"
+#include "..\texts.h"
+#include "UIHouses.h"
+#include "..\BSPModel.h"
+
+
+
+
+
+int uTextureID_GameUI_CharSelectionFrame; // 50C98C
+
+
+
+
+
+//----- (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, &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.data(), "NPC%03d", v6->uPortraitID);
+        v8 = pIcons_LOD->LoadTexture(pTmpBuf2.data(), 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.data();
+          sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[429], v10, aNPCProfessionNames[v9]);
+        }
+        else
+        {
+          v12 = v6->pName;
+          v11 = pTmpBuf.data();
+          strcpy(pTmpBuf.data(), 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)
+{
+  NPCData *pNPCInfo; // ebp@1
+  int v9; // esi@8
+  int pNumberContacts; // eax@11
+  char pContainer[32]; // [sp+14h] [bp-28h]@3
+
+  dword_A74CDC = -1;
+  dword_AE336C = -1;
+  pEventTimer->Pause();
+  pMiscTimer->Pause();
+  pAudioPlayer->StopChannels(-1, -1);
+  uDialogueType = 0;
+  sDialogue_SpeakingActorNPC_ID = actor->sNPC_ID;
+  pDialogue_SpeakingActor = actor;
+  pNPCInfo = GetNPCData(actor->sNPC_ID);
+  if ( (pNPCInfo->uFlags & 3) != 2 )
+    pNPCInfo->uFlags = pNPCInfo->uFlags + 1;
+
+  switch (pParty->alignment)
+  {
+    case PartyAlignment_Good:    sprintfex(pContainer, "evt%02d-b", const_2()); break;
+    case PartyAlignment_Neutral: sprintfex(pContainer, "evt%02d", const_2());   break;
+    case PartyAlignment_Evil:    sprintfex(pContainer, "evt%02d-c", const_2()); break;
+  }
+
+  pDialogueNPCCount = 0;
+  uNumDialogueNPCPortraits = 1;
+  pTexture_Dialogue_Background = pIcons_LOD->LoadTexturePtr(pContainer, TEXTURE_16BIT_PALETTE);
+  sprintfex(pContainer, "npc%03u", pNPCInfo->uPortraitID);
+  v9 = 0;
+  pDialogueNPCPortraits[0] = pIcons_LOD->LoadTexturePtr(pContainer, TEXTURE_16BIT_PALETTE);
+  dword_591084 = areWeLoadingTexture;
+  uTextureID_right_panel_loop = uTextureID_right_panel;
+  if ( !pNPCInfo->Hired() && pNPCInfo->Location2D >= 0 )
+  {
+    if ( (signed int)pParty->GetPartyFame() <= pNPCInfo->fame
+      || (pNumberContacts = pNPCInfo->uFlags & 0xFFFFFF7F, (pNumberContacts & 0x80000000u) != 0) )
+    {
+      v9 = 1;
+    }
+	else
+	{
+		if ( pNumberContacts > 1 )
+		{
+		  if ( pNumberContacts == 2 )
+		  {
+			v9 = 3;
+		  }
+		  else
+		  {
+			  if ( pNumberContacts != 3 )
+			  {
+				if ( pNumberContacts != 4 )
+				  v9 = 1;
+			  }
+			  else
+			  {
+				v9 = 2;
+			  }
+		  }
+		}
+		else if ( pNPCInfo->rep )
+		{
+		  v9 = 2;
+		}
+	}
+  }
+  if (sDialogue_SpeakingActorNPC_ID < 0)
+    v9 = 4;
+  pDialogueWindow = GUIWindow::Create(0, 0, 640, 480, WINDOW_Dialogue, v9, 0);//pNumberContacts = 1, v9 = 0; pNumberContacts = 2, v9 = 3;
+  if (pNPCInfo->Hired())
+  {
+    if ( !pNPCInfo->bHasUsedTheAbility )
+    {
+      if ( pNPCInfo->uProfession >= 10 )
+      {
+        if ( pNPCInfo->uProfession <= 12 || pNPCInfo->uProfession > 32 && (pNPCInfo->uProfession <= 34 
+             || pNPCInfo->uProfession > 38 && (pNPCInfo->uProfession <= 43 || pNPCInfo->uProfession == 52)) )
+        {
+          pDialogueWindow->CreateButton(480, 250, 140, LOBYTE(pFontArrus->uFontHeight) - 3, 1, 0, UIMSG_SelectNPCDialogueOption, 9, 0, "", 0);
+          pDialogueWindow->_41D08F_set_keyboard_control_group(4, 1, 0, 1);
+        }
+      }
+    }
+  }
+
+  pDialogueWindow->CreateButton( 61, 424, 31, 40, 2, 94, UIMSG_SelectCharacter, 1, '1', "", 0);
+  pDialogueWindow->CreateButton(177, 424, 31, 40, 2, 94, UIMSG_SelectCharacter, 2, '2', "", 0);
+  pDialogueWindow->CreateButton(292, 424, 31, 40, 2, 94, UIMSG_SelectCharacter, 3, '3', "", 0);
+  pDialogueWindow->CreateButton(407, 424, 31, 40, 2, 94, UIMSG_SelectCharacter, 4, '4', "", 0);
+
+  if (bPlayerSaysHello && uActiveCharacter && !pNPCInfo->Hired())
+  {
+    if (pParty->uCurrentHour < 5 || pParty->uCurrentHour > 21)
+      pPlayers[uActiveCharacter]->PlaySound(SPEECH_GoodEvening, 0);
+    else
+      pPlayers[uActiveCharacter]->PlaySound(SPEECH_GoodDay, 0);
+  }
+}
+
+//----- (00445350) --------------------------------------------------------
+void GameUI_DrawDialogue()
+{
+  NPCData *pNPC; // ebx@2
+  int pGreetType; // eax@2
+  unsigned __int16 v2; // di@2
+  //unsigned int v3; // eax@2
+  char *v4; // esi@3
+  //int v5; // eax@11
+  //char *v6; // ecx@13
+  //char *v7; // eax@16
+  //unsigned int v8; // edi@19
+  //char *v9; // ecx@27
+  char *v10; // eax@29
+  //int v11; // eax@30
+  int v12; // esi@39
+  char *v13; // eax@41
+  GUIButton *v14; // eax@43
+  //GUIButton *v15; // edi@43
+  signed int v16; // eax@44
+  //unsigned int v23; // eax@53
+  //const char *v24; // eax@59
+  //unsigned __int16 v30; // cx@83
+  int v31; // ecx@86
+  int v32; // ebx@93
+  unsigned int v33; // eax@93
+  GUIWindow *v34; // ecx@93
+  int v35; // esi@93
+  int i; // eax@93
+  GUIButton *v37; // eax@94
+  int v38; // eax@95
+  signed int v39; // esi@99
+  signed int v40; // eax@102
+  unsigned int v41; // ebx@102
+  int v42; // edi@102
+  GUIButton *v43; // esi@103
+  int v44; // eax@104
+  unsigned int v45; // ecx@104
+  unsigned __int16 *v46; // edx@104
+  unsigned __int16 v47; // ax@104
+  GUIWindow pWindow; // [sp+4h] [bp-110h]@39
+  int v49; // [sp+Ch] [bp-108h]@39
+  int v50; // [sp+14h] [bp-100h]@39
+  GUIWindow v51; // [sp+58h] [bp-BCh]@2
+  GUIWindow v52; // [sp+ACh] [bp-68h]@42
+  char *Str; // [sp+100h] [bp-14h]@104
+  //int v54; // [sp+104h] [bp-10h]@2
+  //unsigned __int16 *v55; // [sp+108h] [bp-Ch]@82
+  GUIFont *pOutString; // [sp+10Ch] [bp-8h]@39
+  char *pInString=NULL; // [sp+110h] [bp-4h]@32
+
+  if ( !pDialogueWindow )
+    return;
+
+  memcpy(&v51, pDialogueWindow, sizeof(v51));
+  pNPC = GetNPCData(sDialogue_SpeakingActorNPC_ID);
+  pGreetType = GetGreetType(sDialogue_SpeakingActorNPC_ID);
+  v51.uFrameWidth -= 10;
+  v51.uFrameZ -= 10;
+  //v54 = v1;
+  TargetColor(0xFFu, 0xFFu, 0xFFu);
+  TargetColor(0xE1u, 0xCDu, 0x23u);
+  v2 = TargetColor(0x15u, 0x99u, 0xE9u);
+  pRenderer->DrawTextureIndexed(477, 0, pTexture_Dialogue_Background);
+  pRenderer->DrawTextureTransparent(468, 0, (Texture *)(uTextureID_right_panel_loop != -1 ? &pIcons_LOD->pTextures[uTextureID_right_panel_loop] : 0));
+  pRenderer->DrawTextureIndexed(pNPCPortraits_x[0][0] - 4, pNPCPortraits_y[0][0] - 4, (Texture *)(uTextureID_50795C != -1 ? &pIcons_LOD->pTextures[uTextureID_50795C] : 0));
+  pRenderer->DrawTextureIndexed(pNPCPortraits_x[0][0], pNPCPortraits_y[0][0], pDialogueNPCPortraits[0]);
+
+  if (pNPC->uProfession)
+  {
+    assert(pNPC->uProfession < sizeof(aNPCProfessionNames) / sizeof(*aNPCProfessionNames.data())); // sometimes buffer overflows; errors emerge both here and in dialogue text
+    sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[429], pNPC->pName, aNPCProfessionNames[pNPC->uProfession]);//^Pi[%s] %s
+  }
+  else
+    strcpy(pTmpBuf.data(), pNPC->pName);
+
+  v51.DrawTitleText(pFontArrus, 483, 112, v2, pTmpBuf.data(), 3);
+  pParty->GetPartyFame();
+
+  pInString = nullptr;
+  switch (uDialogueType)
+  {
+    case DIALOGUE_13:
+      pInString = BuilDialogueString(pNPCStats->pProfessions[pNPC->uProfession - 1].pJoinText, uActiveCharacter - 1, 0, 0, 0, 0);
+    break;
+
+    case DIALOGUE_PROFESSION_DETAILS:
+    {
+      auto prof = pNPCStats->pProfessions + pNPC->uProfession - 1;
+
+      if (dialogue_show_profession_details)
+        pInString = BuilDialogueString(prof->pBenefits, uActiveCharacter - 1, 0, 0, 0, 0);
+      else if (pNPC->Hired())
+        pInString = BuilDialogueString(prof->pDismissText, uActiveCharacter - 1, 0, 0, 0, 0);
+      else
+        pInString = BuilDialogueString(prof->pJoinText, uActiveCharacter - 1, 0, 0, 0, 0);
+    }
+    break;
+
+
+    case DIALOGUE_ARENA_WELCOME:
+      pInString = pGlobalTXT_LocalizationStrings[574]; // "Welcome to the Arena of Life and Death.  Remember, you are only allowed one arena combat per visit.  To fight an arena battle, select the option that best describes your abilities and return to me- if you survive:"
+    break;
+
+    case DIALOGUE_ARENA_FIGHT_NOT_OVER_YET:
+      pInString = pGlobalTXT_LocalizationStrings[577]; //"Get back in there you wimps:"
+    break;
+
+    case DIALOGUE_ARENA_REWARD:
+      sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[576], gold_transaction_amount);// "Congratulations on your win: here's your stuff: %u gold."
+      pInString = pTmpBuf.data();
+    break;
+
+    case DIALOGUE_ARENA_ALREADY_WON:
+      pInString = pGlobalTXT_LocalizationStrings[582]; // "You already won this trip to the Arena:"
+    break;
+
+    default:
+      if (uDialogueType > DIALOGUE_18 && uDialogueType < DIALOGUE_23 && !byte_5B0938[0])
+      {
+        pInString = (char *)current_npc_text;
+      }
+      else if (pGreetType == 1)//QuestNPC_greet
+      {
+        if (pNPC->greet)
+        {
+          if ((pNPC->uFlags & 3) == 2)
+            pInString = pNPCStats->pNPCGreetings[pNPC->greet - 1].pGreeting2;
+          else
+            pInString = pNPCStats->pNPCGreetings[pNPC->greet - 1].pGreeting1;
+        }
+      }
+      else if (pGreetType == 2)//HiredNPC_greet
+      {
+        auto prof = pNPCStats->pProfessions + pNPC->uProfession - 1;
+
+        if (pNPC->Hired())
+          pInString = BuilDialogueString(prof->pDismissText, uActiveCharacter - 1, 0, 0, 0, 0);
+        else
+          pInString = BuilDialogueString(prof->pJoinText, uActiveCharacter - 1, 0, 0, 0, 0);
+      }
+    break;
+  }
+
+  if (pInString)
+  {
+    pWindow.uFrameWidth = game_viewport_width;
+    pWindow.uFrameZ = 452;
+    auto font = pFontArrus;
+    v12 = pFontArrus->CalcTextHeight(pInString, &pWindow, 13, 0) + 7;
+    if ( 352 - v12 < 8 )
+    {
+      font = pFontCreate;
+       v12 = pFontCreate->CalcTextHeight(pInString, &pWindow, 13, 0) + 7;
+    }
+    if (uTextureID_Leather != -1)
+      pRenderer->_4A6A68(8, 352 - v12, &pIcons_LOD->pTextures[uTextureID_Leather], pIcons_LOD->pTextures[uTextureID_Leather].uTextureHeight - v12);
+    pRenderer->DrawTextureIndexed(8u, 347 - v12, pTexture_591428);
+    v13 = FitTextInAWindow(pInString, font,  &pWindow, 0xDu, 0);
+    pDialogueWindow->DrawText(font, 13, 354 - v12, 0, v13, 0, 0, 0);
+  }
+
+
+  memcpy(&v52, pDialogueWindow, sizeof(v52));
+  v52.uFrameX = 483;
+  v52.uFrameWidth = 148;
+  v52.uFrameZ = 334;
+  for (int i = v52.pStartingPosActiveItem;
+       i < v52.pStartingPosActiveItem + v52.pNumPresenceButton; ++i)
+  {
+    v14 = v52.GetControl(i);
+    //v15 = v14;
+    if ( !v14 )
+      break;
+    v16 = v14->msg_param;
+
+    if ( v16 > 88 )
+      v14->pButtonName[0] = 0;
+	else if (v16 == 88)
+      strcpy(v14->pButtonName, pGlobalTXT_LocalizationStrings[581]); // Lord
+    else if (v16 == 87)
+      strcpy(v14->pButtonName, pGlobalTXT_LocalizationStrings[580]); // Knight
+    else if (v16 == 86)
+      strcpy(v14->pButtonName, pGlobalTXT_LocalizationStrings[579]); // Squire
+    else if (v16 == 85)
+      strcpy(v14->pButtonName, pGlobalTXT_LocalizationStrings[578]); // Page
+    else if (v16 == 77)
+      strcpy(v14->pButtonName, pGlobalTXT_LocalizationStrings[407]); // Details
+    else if (v16 == 76)
+    {
+      if (pNPC->Hired())
+        sprintf(v14->pButtonName, (const char*)pGlobalTXT_LocalizationStrings[408], pNPC->pName); // Release %s
+      else
+        strcpy(v14->pButtonName, pGlobalTXT_LocalizationStrings[406]); // Hire
+    }
+	else if (v16 == 24)
+    {
+      __debugbreak(); // learn conditions of this event
+      auto topic = pNPCTopics[pNPC->evt_F - 1].pTopic;//(&dword_721660)[8 * v23];
+      if (!topic)
+      {
+        v14->pButtonName[0] = 0;
+        v14->msg_param = 0;
+      }
+      else
+        strcpy(v14->pButtonName, topic);
+    }
+	else if (v16 == 9)
+      strcpy(v14->pButtonName, GetProfessionActionText(pNPC->uProfession));
+	else if (v16 == 19)
+	{
+     // __debugbreak(); // learn conditions of this event Scavenger Hunt
+      auto topic = pNPCTopics[pNPC->evt_A - 1].pTopic;//(&dword_721660)[8 * v23];
+      if (!topic)
+      {
+        v14->pButtonName[0] = 0;
+        v14->msg_param = 0;
+      }
+      else strcpy(v14->pButtonName, topic);
+	}
+	else if (v16 == 20)
+	{
+      //__debugbreak(); // learn conditions of this event instruments
+      auto topic = pNPCTopics[pNPC->evt_B - 1].pTopic;//(&dword_721660)[8 * v23];
+      if (!topic)
+      {
+        v14->pButtonName[0] = 0;
+        v14->msg_param = 0;
+      }
+      else strcpy(v14->pButtonName, topic);
+	}
+	else if (v16 == 21)
+	{
+      //__debugbreak(); // learn conditions of this event
+      auto topic = pNPCTopics[pNPC->evt_C - 1].pTopic;//(&dword_721660)[8 * v23];
+      if (!topic)
+      {
+        v14->pButtonName[0] = 0;
+        v14->msg_param = 0;
+      }
+      else strcpy(v14->pButtonName, topic);
+	}
+	else if (v16 == 22)
+	{
+      //__debugbreak(); // learn conditions of this event
+      auto topic = pNPCTopics[pNPC->evt_D - 1].pTopic;//(&dword_721660)[8 * v23];
+      if (!topic)
+      {
+        v14->pButtonName[0] = 0;
+        v14->msg_param = 0;
+      }
+      else strcpy(v14->pButtonName, topic);
+	}
+	else if (v16 == 23)
+	{
+      //__debugbreak(); // learn conditions of this event
+      auto topic = pNPCTopics[pNPC->evt_E - 1].pTopic;//(&dword_721660)[8 * v23];
+      if (!topic)
+      {
+        v14->pButtonName[0] = 0;
+        v14->msg_param = 0;
+      }
+      else strcpy(v14->pButtonName, topic);
+	}
+	else if (v16 == 13)
+	{
+      if (pNPC->Hired())
+        sprintf(v14->pButtonName, pGlobalTXT_LocalizationStrings[408], pNPC->pName); // Release %s
+      else
+        strcpy(v14->pButtonName, pGlobalTXT_LocalizationStrings[122]); // Join
+	}
+	else
+      v14->pButtonName[0] = 0;
+	
+
+    if (pParty->field_7B5_in_arena_quest && pParty->field_7B5_in_arena_quest != -1)
+    {
+      int num_dead_actors = 0;
+      pInString = 0;
+      for (uint i = 0; i < uNumActors; ++i)
+      {
+        if (pActors[i].uAIState == Dead || pActors[i].uAIState == Removed ||
+            pActors[i].uAIState  == Disabled)
+          ++num_dead_actors;
+        else
+        {
+          int sumonner_type = PID_TYPE(pActors[i].uSummonerID);
+          if (sumonner_type == OBJECT_Player)
+            ++num_dead_actors;
+        }
+      }
+      if (num_dead_actors == uNumActors)
+        strcpy(v14->pButtonName, pGlobalTXT_LocalizationStrings[658]); // Collect Prize
+    }
+  }
+
+
+  v32 = 0;
+  //pInString = (char *)TargetColor(0xFFu, 0xFFu, 0xFFu);
+  v33 = TargetColor(0xE1u, 0xCDu, 0x23u);
+  v34 = pDialogueWindow;
+  //v54 = v33;
+  v35 = pDialogueWindow->pStartingPosActiveItem;
+  for ( i = v35 + pDialogueWindow->pNumPresenceButton; v35 < i; i = pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem )
+  {
+    v37 = v34->GetControl(v35);
+    if ( !v37 )
+    {
+      v34 = pDialogueWindow;
+      break;
+    }
+    v38 = pFontArrus->CalcTextHeight(v37->pButtonName, &v52, 0, 0);
+    v34 = pDialogueWindow;
+    v32 += v38;
+    ++v35;
+  }
+  v39 = v34->pNumPresenceButton;
+  if ( v39 )
+  {
+    pOutString = (GUIFont *)((174 - v32) / v39);
+    if ( (174 - v32) / v39 > 32 )
+      pOutString = (GUIFont *)32;
+    int v55 = 1;
+    v40 = 174 - (int)pOutString * v39 - v32;
+    v41 = v34->pStartingPosActiveItem;
+    v42 = v40 / 2 - (signed int)pOutString / 2 + 138;
+    if ( (signed int)v41 < (signed int)(v41 + v39) )
+    {
+      do
+      {
+        v43 = v34->GetControl(v41);
+        if ( !v43 )
+          break;
+        v43->uY = (unsigned int)((char *)pOutString + v42);
+        Str = v43->pButtonName;
+        v44 = pFontArrus->CalcTextHeight(v43->pButtonName, &v52, 0, 0);
+        v45 = v43->uY;
+        v46 = (unsigned short *)v55;
+        v43->uHeight = v44;
+        v42 = v45 + v44 - 1;
+        v43->uW = v42;
+        v47 = v33;
+        if ( (unsigned __int16 *)pDialogueWindow->pCurrentPosActiveItem != v46 )
+          v47 = TargetColor(0xFFu, 0xFFu, 0xFFu);
+        v52.DrawTitleText(pFontArrus, 0, v45, v47, Str, 3u);
+        v34 = pDialogueWindow;
+        ++v55;
+        ++v41;
+      }
+      while ( (signed int)v41 < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem );
+    }
+  }
+  pRenderer->DrawTextureIndexed(471, 445, pIcons_LOD->GetTexture(uExitCancelTextureId));
+}
+
+
+
+//----- (00444FBE) --------------------------------------------------------
+void GameUI_DrawBranchlessDialogue()
+{
+  //GUIFont *v0; // esi@1
+  int v1; // esi@4
+  char *v2; // eax@6
+  int v3; // edi@12
+  char Str[200]; // [sp+Ch] [bp-120h]@12
+  GUIWindow v5; // [sp+D4h] [bp-58h]@4
+  GUIFont *pFont; // [sp+128h] [bp-4h]@1
+
+  pFont = pFontArrus;
+  if ( current_npc_text && !byte_5B0938[0] )
+    strcpy(byte_5B0938.data(), current_npc_text);
+  v5.uFrameWidth = game_viewport_width;
+  v5.uFrameZ = 452;
+  v1 = pFontArrus->CalcTextHeight(byte_5B0938.data(), &v5, 12, 0) + 7;
+  if ( 352 - v1 < 8 )
+  {
+    pFont = pFontCreate;
+    v1 = pFontCreate->CalcTextHeight(byte_5B0938.data(), &v5, 12, 0) + 7;
+  }
+  pRenderer->_4A6A68(8, 352 - v1,
+    pIcons_LOD->GetTexture(uTextureID_Leather),
+    pIcons_LOD->GetTexture(uTextureID_Leather)->uTextureHeight - v1);
+  pRenderer->DrawTextureIndexed(8, 347 - v1, pTexture_591428);
+  v2 = FitTextInAWindow(byte_5B0938.data(), pFont, &v5, 0xCu, 0);
+  pGUIWindow2->DrawText(pFont, 12, 354 - v1, 0, v2, 0, 0, 0);
+  pRenderer->DrawTextureRGB(0, 0x160u, pTexture_StatusBar);
+  if ( pGUIWindow2->receives_keyboard_input_2 != WINDOW_INPUT_IN_PROGRESS)
+  {
+    if ( pGUIWindow2->receives_keyboard_input_2 == WINDOW_INPUT_CONFIRMED)
+    {
+      pGUIWindow2->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
+      strcpy(GameUI_Footer_TimedString.data(), (const char *)pKeyActionMap->pPressedKeysBuffer);
+LABEL_16:
+      sub_4452BB();
+      return;
+    }
+    if ( pGUIWindow2->receives_keyboard_input_2 != WINDOW_INPUT_CANCELLED)
+      return;
+    pGUIWindow2->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
+LABEL_15:
+    memset(GameUI_Footer_TimedString.data(), 0, 0xC8u);
+    goto LABEL_16;
+  }
+  if ( pGUIWindow2->ptr_1C == (void *)26 )
+  {
+    sprintf(Str, "%s %s", GameUI_Footer_TimedString, pKeyActionMap->pPressedKeysBuffer);
+    v3 = pFontLucida->GetLineWidth(Str);
+    pGUIWindow2->DrawText(pFontLucida, 13, 357, 0, Str, 0, 0, 0);
+    pGUIWindow2->DrawFlashingInputCursor(v3 + 13, 357, pFontLucida);
+    return;
+  }
+  if ( pKeyActionMap->pPressedKeysBuffer[0] )
+  {
+    pKeyActionMap->SetWindowInputStatus(0);
+    goto LABEL_15;
+  }
+}
+
+
+//----- (004443D5) --------------------------------------------------------
+const char *GameUI_GetMinimapHintText()
+{
+  int v0; // ST20_4@1
+  unsigned int v1; // esi@1
+  signed int v2; // ebx@1
+  double v3; // st7@1
+  int v4; // esi@3
+  int v5; // edi@4
+  int v6; // eax@4
+  int v7; // eax@4
+  BSPModel *v8; // ecx@4
+  unsigned __int8 v9; // zf@5
+  char v10; // sf@5
+  unsigned __int8 v11; // of@5
+  ODMFace *v12; // eax@6
+  __int16 v13; // cx@6
+  const char *v14; // eax@8
+  const char *v15; // edi@8
+  char *result; // eax@12
+  unsigned int v17; // eax@14
+  unsigned int v18; // [sp+Ch] [bp-20h]@1
+  int v19; // [sp+10h] [bp-1Ch]@1
+  int v20; // [sp+14h] [bp-18h]@1
+  char *v21; // [sp+18h] [bp-14h]@1
+  unsigned int pY; // [sp+1Ch] [bp-10h]@1
+  int v23; // [sp+20h] [bp-Ch]@1
+  int v24; // [sp+24h] [bp-8h]@1
+  int pX; // [sp+28h] [bp-4h]@1
+
+  v24 = pParty->vPosition.x;
+  v0 = pParty->vPosition.y;
+  v1 = pOutdoor->uNumBModels;
+  *(float *)&v23 = (double)(signed int)viewparams->uMinimapZoom * 0.000015258789;
+  v2 = 0;
+  v18 = pOutdoor->uNumBModels;
+  v21 = 0;
+  pMouse->GetClickPos((unsigned int *)&pX, &pY);
+  v3 = 1.0 / *(float *)&v23;
+  v23 = pX - 557;
+  v19 = (signed __int64)((double)(pX - 557) * v3 + (double)v24);
+  v20 = (signed __int64)((double)v0 - (double)(signed int)(pY - 74) * v3);
+  if ( uCurrentlyLoadedLevelType != LEVEL_Outdoor || (*(float *)&v23 = 0.0, (signed int)v1 <= 0) )
+  {
+LABEL_14:
+    v17 = pMapStats->GetMapInfo(pCurrentMapName.data());
+    if ( v17 == v2 )
+      result = "No Maze Info for this maze on file!";
+    else
+      result = pMapStats->pInfos[v17].pName;
+  }
+  else
+  {
+    v4 = 0;
+    while ( 1 )
+    {
+      pX = pOutdoor->pBModels[v4].vBoundingCenter.x - v19;
+      pY = pOutdoor->pBModels[v4].vBoundingCenter.y - v20;
+      v5 = abs((signed)pY);
+      v6 = abs((signed)pX);
+      v7 = int_get_vector_length(v6, v5, v2);
+      v8 = &pOutdoor->pBModels[0];
+      if ( v7 < 2 * pOutdoor->pBModels[v4].sBoundingRadius )
+      {
+        v11 = __OFSUB__(pOutdoor->pBModels[v4].uNumFaces, v2);
+        v9 = pOutdoor->pBModels[v4].uNumFaces == v2;
+        v10 = ((pOutdoor->pBModels[v4].uNumFaces - v2) & 0x80000000u) != 0;
+        v24 = v2;
+        if ( !((unsigned __int8)(v10 ^ v11) | v9) )
+        {
+          do
+          {
+            v12 = &v8[v4].pFaces[v2 / 0x134u];
+            v13 = v12->sCogTriggeredID;
+            if ( v13 )
+            {
+              if ( !(BYTE2(v12->uAttributes) & 0x10) )
+              {
+                v14 = GetEventHintString(v13);
+                v15 = v14;
+                if ( v14 )
+                {
+                  if ( _stricmp(v14, "") )
+                    v21 = (char *)v15;
+                }
+              }
+            }
+            ++v24;
+            v8 = pOutdoor->pBModels;
+            v2 += 308;
+          }
+          while ( v24 < (signed int)pOutdoor->pBModels[v4].uNumFaces );
+        }
+        result = v21;
+        v2 = 0;
+        if ( v21 )
+          break;
+      }
+      ++v23;
+      ++v4;
+      if ( v23 >= (signed int)v18 )
+        goto LABEL_14;
+    }
+  }
+  return result;
+}
+
+
+
+
+
+//----- (0041D3B7) --------------------------------------------------------
+void GameUI_CharacterQuickRecord_Draw(GUIWindow *window, Player *player)
+{
+  //Player *pPlayer; // esi@1
+  int v6; // eax@5
+  int v7; // ebx@5
+  //unsigned int v8; // ecx@5
+  int v9; // ebx@5
+  //unsigned int v10; // eax@5
+  //int v11; // eax@5
+  //unsigned int v12; // ecx@5
+  Texture *v13; // eax@6
+  unsigned int v14; // eax@12
+  PlayerFrame *v15; // eax@12
+  //unsigned int v16; // eax@15
+  unsigned int v20; // eax@15
+  unsigned int v24; // eax@15
+  unsigned int v25; // eax@15
+  unsigned __int8 v28; // al@15
+  char *v29; // eax@16
+  __int64 v35; // ST38_8@22
+  int v36; // esi@22
+  unsigned int v38; // eax@22
+  char *v39; // eax@24
+  signed int uFramesetID; // [sp+20h] [bp-8h]@9
+  int uFramesetIDa; // [sp+20h] [bp-8h]@18
+
+  uint numActivePlayerBuffs = 0;
+  for (uint i = 0; i < 24; ++i)
+    if (player->pPlayerBuffs[i].uExpireTime > 0)
+      ++numActivePlayerBuffs;
+
+  v6 = pFontArrus->uFontHeight + 162;
+  v7 = (numActivePlayerBuffs - 1) * pFontArrus->uFontHeight;
+  v9 = v6 + v7;
+  window->uFrameHeight = v9;
+  window->uFrameZ = window->uFrameWidth + window->uFrameX - 1;
+  window->uFrameW = v9 + window->uFrameY - 1;
+  window->DrawMessageBox(0);
+
+  if (player->Eradicated())
+    v13 = pTexture_PlayerFaceEradicated;
+  else if (player->Dead())
+    v13 = pTexture_PlayerFaceDead;
+  else
+  {
+      uFramesetID = pPlayerFrameTable->GetFrameIdByExpression(player->expression);
+      if ( !uFramesetID )
+        uFramesetID = 1;
+      if ( player->expression == CHARACTER_EXPRESSION_21)
+      {
+        v15 = pPlayerFrameTable->GetFrameBy_y(&player->_expression21_frameset, &player->_expression21_animtime, pMiscTimer->uTimeElapsed);
+      }
+      else
+      {
+        v14 = pMiscTimer->Time();
+        v15 = pPlayerFrameTable->GetFrameBy_x(uFramesetID, v14);
+      }
+      player->field_1AA2 = v15->uTextureID - 1;
+      v13 = pTextures_PlayerFaces[(unsigned int)window->ptr_1C][v15->uTextureID - 1];
+  }
+
+  pRenderer->DrawTextureTransparent(window->uFrameX + 24, window->uFrameY + 24, v13);
+
+  sprintfex(pTmpBuf.data(), "\f%05d", ui_character_header_text_color);
+  sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[429], player->pName, pClassNames[player->classType]); // "%s the %s"
+  strcat(pTmpBuf.data(), pTmpBuf2.data());
+  strcat(pTmpBuf.data(), "\f00000\n");
+
+  v20 = UI_GetHealthManaStringColor(player->sHealth, player->GetMaxHealth());
+  sprintf(pTmpBuf2.data(), "%s : \f%05u%d\f00000 / %d\n",
+          pGlobalTXT_LocalizationStrings[108], // "Hit Points"
+          v20, player->sHealth, player->GetMaxHealth());
+  strcat(pTmpBuf.data(), pTmpBuf2.data());
+
+  v24 = UI_GetHealthManaStringColor(player->sMana, player->GetMaxMana());
+  sprintf(pTmpBuf2.data(), "%s : \f%05u%d\f00000 / %d\n",
+          pGlobalTXT_LocalizationStrings[212], // "Spell Points"
+          v24, player->sMana, player->GetMaxMana());
+  strcat(pTmpBuf.data(), pTmpBuf2.data());
+
+  v25 = player->GetMajorConditionIdx();
+  sprintf(pTmpBuf2.data(), "%s: \f%05d%s\f00000\n",
+          pGlobalTXT_LocalizationStrings[47], // "Condition
+          GetConditionDrawColor(v25), aCharacterConditionNames[v25]);
+  strcat(pTmpBuf.data(), pTmpBuf2.data());
+
+  v28 = player->uQuickSpell;
+  if ( v28 )
+    v29 = pSpellStats->pInfos[v28].pShortName;
+  else
+    v29 = pGlobalTXT_LocalizationStrings[153];
+  sprintfex(pTmpBuf2.data(), "%s: %s", pGlobalTXT_LocalizationStrings[172], v29); // "Quick Spell"
+  strcat(pTmpBuf.data(), pTmpBuf2.data());
+
+  window->DrawText(pFontArrus, 120, 22, 0, pTmpBuf.data(), 0, 0, 0);
+
+  uFramesetIDa = 0;
+  for (uint i = 0; i < 24; ++i)
+  {
+    auto buff = player->pPlayerBuffs + i;
+    if (buff->uExpireTime > 0)
+    {
+      v35 = buff->uExpireTime - pParty->uTimePlayed;
+      v36 = uFramesetIDa++ * pFontComic->uFontHeight + 134;
+      v38 = ui_game_character_record_playerbuff_colors[i];
+      window->DrawText(pFontComic, 52, v36, v38, aSpellNames[20 + i], 0, 0, 0);
+      sub_41D20D_buff_remaining_time_string(v36, window, v35, pFontComic);
+    }
+  }
+
+  v39 = "";
+  if ( uFramesetIDa == 0 )
+    v39 = pGlobalTXT_LocalizationStrings[153]; // "None"
+  sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[450], v39); // "Active Spells: %s"
+  window->DrawText(pFontArrus, 14, 114, 0, pTmpBuf.data(), 0, 0, 0);
+}
+
+
+
+//----- (0041A57E) --------------------------------------------------------
+void GameUI_QuickRef_Draw()
+{
+        //unsigned int v0; // ebx@1
+        //unsigned int v1; // eax@1
+        //Player *pPlayer; // ebp@2
+        //int v3; // eax@6
+        //int v4; // edi@6
+        unsigned int v5; // eax@7
+        unsigned int v6; // edi@9
+        unsigned int v7; // edi@11
+        //signed int v8; // eax@13
+        unsigned int v9; // eax@13
+        unsigned int v10; // edi@13
+        //int v11; // eax@15
+        unsigned int v12; // eax@15
+        unsigned int v13; // edi@15
+        //int v14; // eax@17
+        //int v15; // ST18_4@17
+        //int v16; // ebx@17
+        //int v17; // eax@17
+        unsigned int v18; // eax@17
+        unsigned int v19; // edi@17
+        //int v20; // eax@19
+        unsigned int v21; // edi@19
+        char *v22; // eax@21
+        unsigned int v23; // edi@21
+        //int v24; // eax@23
+        unsigned int v25; // edi@23
+        char *v26; // eax@25
+        unsigned int v27; // edi@25
+        int v28; // ecx@27
+        char *v29; // eax@27
+        signed int v30; // edx@27
+        unsigned int v31; // edi@31
+        unsigned int v32; // edi@33
+        const char *v33; // ST10_4@35
+        unsigned int v34; // eax@35
+        unsigned int v35; // edi@35
+        //unsigned __int8 v36; // al@37
+        char *v37; // eax@38
+        int v38; // eax@41
+        signed int v39; // edi@42
+        //char *v40; // eax@45
+        //unsigned int v41; // eax@45
+        signed int v43; // [sp+10h] [bp-1Ch]@1
+        unsigned int v44; // [sp+14h] [bp-18h]@2
+        int v45; // [sp+18h] [bp-14h]@1
+        //unsigned int v46; // [sp+1Ch] [bp-10h]@1
+        //unsigned int v47; // [sp+20h] [bp-Ch]@1
+        unsigned int v48; // [sp+24h] [bp-8h]@33
+        //unsigned int v49; // [sp+28h] [bp-4h]@1
+
+        //v0 = 0;
+        //v47 = TargetColor(0xFFu, 0xFFu, 0x9Bu);
+        //v49 = TargetColor(0xFFu, 0, 0);
+        //v46 = TargetColor(0, 0xFFu, 0);
+        //v1 = pIcons_LOD->LoadTexture("quikref", TEXTURE_16BIT_PALETTE);
+  pRenderer->DrawTextureIndexed(8, 8, pIcons_LOD->LoadTexturePtr("quikref", TEXTURE_16BIT_PALETTE));
+        v43 = 0;
+        v45 = LOBYTE(pFontArrus->uFontHeight) + 1;
+        do
+        {
+            auto player = &pParty->pPlayers[v43];
+            v44 = 94 * v43 + 89;
+            if ( v43 == 0 )
+                pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 0x16u, 0x12u, 0, pGlobalTXT_LocalizationStrings[149], 60, 0);//Name
+            pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 94 * v43 + 89, 0x12u, ui_character_header_text_color, player->pName, 84, 0);
+            if ( v43 == 0 )
+                pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 0x16u, 0x2Fu, 0, pGlobalTXT_LocalizationStrings[131], 60, 0); //.
+            sprintf(pTmpBuf.data(), "%lu", player->GetActualLevel());
+            if ( player->GetActualLevel() <= player->GetBaseLevel())
+                v5 = player->GetExperienceDisplayColor();
+            else
+              v5 = ui_character_bonus_text_color;
+            pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, v44, 0x2Fu, v5, pTmpBuf.data(), 84, 0);
+            v6 = v45 + 47;
+            if ( v43 == 0 )
+                pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 0x16u, v45 + 47, 0, pGlobalTXT_LocalizationStrings[41], 60, 0);//
+            pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, v44, v6, 0, pClassNames[player->classType], 84, 0);
+            v7 = v45 + v6;
+            if ( v43 == 0 )
+                pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 0x16u, v7, 0, pGlobalTXT_LocalizationStrings[107], 60, 0);//.
+            sprintf(pTmpBuf.data(), "%d", player->sHealth);
+            v9 = UI_GetHealthManaStringColor(player->sHealth, player->GetMaxHealth());
+            pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, v44, v7, v9, pTmpBuf.data(), 84, 0);
+            v10 = v45 + v7;
+            if ( v43 == 0 )
+                pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 0x16u, v10, 0, pGlobalTXT_LocalizationStrings[209], 60, 0);//
+            sprintf(pTmpBuf.data(), "%d", player->sMana);
+            v12 = UI_GetHealthManaStringColor(player->sMana, player->GetMaxMana());
+            pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, v44, v10, v12, pTmpBuf.data(), 84, 0);
+            v13 = v45 + v10;
+            if ( v43 == 0 )
+                pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 0x16u, v13, 0, pGlobalTXT_LocalizationStrings[0], 60, 0);// 
+            sprintf(pTmpBuf.data(), "%d", player->GetActualAC());
+            v18 = UI_GetHealthManaStringColor(player->GetActualAC(), player->GetBaseAC());
+            pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, v44, v13, v18, pTmpBuf.data(), 84, 0);
+            v19 = v45 + v13;
+            if ( !v43 )
+                pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 0x16u, v19, 0, pGlobalTXT_LocalizationStrings[18], 60, 0);//
+            sprintf(pTmpBuf.data(), "%+d", player->GetActualAttack(0));
+            pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, v44, v19, 0, pTmpBuf.data(), 84, 0);
+            v21 = v45 + v19;
+            if ( !v43 )
+                pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 0x16u, v21, 0, pGlobalTXT_LocalizationStrings[66], 60, 0);//.
+            v22 = player->GetMeleeDamageString();
+            pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, v44, v21, 0, v22, 84, 0);
+            v23 = v45 + v21;
+            if ( !v43 )
+                pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 0x16u, v23, 0, pGlobalTXT_LocalizationStrings[203], 60, 0);// 
+            sprintf(pTmpBuf.data(), "%+d", player->GetRangedAttack());
+            pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, v44, v23, 0, pTmpBuf.data(), 84, 0);
+            v25 = v45 + v23;
+            if ( !v43 )
+                pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 0x16u, v25, 0, pGlobalTXT_LocalizationStrings[66], 60, 0);//.
+            v26 = player->GetRangedDamageString();
+            pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, v44, v25, 0, v26, 84, 0);
+            v27 = v45 + v25;
+            if ( !v43 )
+                pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 0x16u, v27, 0, pGlobalTXT_LocalizationStrings[205], 60, 0);//
+            v28 = 0;
+            v29 = (char *)player->pActiveSkills;
+            v30 = 36;
+            do
+                {
+                if ( *(short *)v29 )
+                    ++v28;
+                v29 += 2;
+                --v30;
+                }
+                while ( v30 );
+                sprintf(pTmpBuf.data(), "%lu", v28);
+                pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, v44, v27, 0, pTmpBuf.data(), 84, 0);
+                v31 = v45 + v27;
+                if ( !v43 )
+                    pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 0x16u, v31, 0, pGlobalTXT_LocalizationStrings[168], 60, 0);//
+                sprintf(pTmpBuf.data(), "%lu", player->uSkillPoints);
+                pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, v44, v31, player->uSkillPoints ? ui_character_bonus_text_color : ui_character_default_text_color, pTmpBuf.data(), 84, 0);
+                v32 = v45 + v31;
+                v48 = player->GetMajorConditionIdx();
+                if ( !v43 )
+                    pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 0x16u, v32, 0, pGlobalTXT_LocalizationStrings[45], 60, 0);//.
+                v33 = aCharacterConditionNames[v48];
+                v34 = GetConditionDrawColor(v48);
+                pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, v44, v32, v34, v33, 84, 0);
+                v35 = v45 + v32;
+                if ( !v43 )
+                    pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 0x16u, v35, 0, pGlobalTXT_LocalizationStrings[170], 60, 0);//..
+                if (player->uQuickSpell)
+                    v37 = pSpellStats->pInfos[player->uQuickSpell].pShortName;
+                else
+                    v37 = pGlobalTXT_LocalizationStrings[153];//
+                pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, v44, v35, 0, v37, 84, 0);
+                ++v43;
+            }
+            while ( v43 < 4 );
+
+            v38 = GetPartyReputation();
+            if ( v38 >= 0 )
+                {
+                if ( v38 <= 5 )
+                  v39 = ui_character_default_text_color;
+                else
+                  v39 = ui_character_bonus_text_color_neg;
+                }
+            else
+              v39 = ui_character_bonus_text_color;
+
+            sprintf(pTmpBuf.data(), "%s: \f%05d%s\f00000", pGlobalTXT_LocalizationStrings[180], v39, GetReputationString(v38));//Reputation
+            pGUIWindow_CurrentMenu->DrawText(pFontArrus, 22, 323, 0, pTmpBuf.data(), 0, 0, 0);
+
+            sprintf(pTmpBuf.data(), "\r261%s: %d", pGlobalTXT_LocalizationStrings[84], pParty->GetPartyFame());// Fame 
+            pGUIWindow_CurrentMenu->DrawText(pFontArrus, 0, 323, 0, pTmpBuf.data(), 0, 0, 0);
+}
+
+
+
+//----- (0041AD6E) --------------------------------------------------------
+void GameUI_DrawRightPanelItems()
+{
+  if (GameUI_RightPanel_BookFlashTimer > pParty->uTimePlayed)
+    GameUI_RightPanel_BookFlashTimer = 0;
+
+  if (pParty->uTimePlayed - GameUI_RightPanel_BookFlashTimer > 128)
+  {
+    GameUI_RightPanel_BookFlashTimer = pParty->uTimePlayed;
+    
+    static bool byte_50697C = false; // 50697C
+    byte_50697C = !byte_50697C;
+    if ( byte_50697C && pCurrentScreen != SCREEN_REST )
+    {
+      if (bFlashQuestBook)     pRenderer->DrawTextureTransparent(493, 355, pIcons_LOD->GetTexture(uTextureID_ib_td1_A));
+      if (bFlashAutonotesBook) pRenderer->DrawTextureTransparent(527, 353, pIcons_LOD->GetTexture(uTextureID_ib_td2_A));
+      if (bFlashHistoryBook)   pRenderer->DrawTextureTransparent(600, 361, pIcons_LOD->GetTexture(uTextureID_ib_td5_A));
+    }
+    else
+    {
+      pRenderer->DrawTextureRGB(468, 0, pTexture_RightFrame);
+      GameUI_DrawHiredNPCs();
+    }
+  }
+}
+
+//----- (0041AEBB) --------------------------------------------------------
+void GameUI_DrawFoodAndGold()
+{
+  int v2; // esi@2
+
+  if ( uGameState != GAME_STATE_FINAL_WINDOW )
+  {
+    v2 = sub_44100D() != 0 ? 381 : 322;
+    sprintf(pTmpBuf.data(), "\r087%lu", pParty->uNumFoodRations);
+    pPrimaryWindow->DrawText(pFontSmallnum, 0, v2, uGameUIFontMain, pTmpBuf.data(), 0, 0, uGameUIFontShadow);
+    sprintf(pTmpBuf.data(), "\r028%lu", pParty->uNumGold);
+    pPrimaryWindow->DrawText(pFontSmallnum, 0, v2, uGameUIFontMain, pTmpBuf.data(), 0, 0, uGameUIFontShadow);
+  }
+}
+
+
+//----- (0041B0C9) --------------------------------------------------------
+void GameUI_DrawLifeManaBars()
+{
+  double v3; // st7@3
+  double v7; // st7@25
+  Texture *v9; // [sp-4h] [bp-30h]@10
+  Texture *v10; // [sp+Ch] [bp-20h]@1
+
+
+  v10 = pIcons_LOD->GetTexture(uTextureID_BarBlue);
+
+  for (uint i = 0; i < 4; ++i)
+  {
+    auto player = pParty->pPlayers + i;
+
+    if (player->sHealth > 0)
+	{
+      int v17 = 0;
+      if (i == 2 || i == 3)
+        v17 = 2;
+
+      v3 = (double)player->sHealth / (double)player->GetMaxHealth();
+      if( v3 > 0.5 )
+      {
+        if ( v3 > 1.0 )
+          v3 = 1.0;
+		v9 = pIcons_LOD->GetTexture(uTextureID_BarGreen);
+      }
+      else if ( v3 > 0.25 )
+        v9 = pIcons_LOD->GetTexture(uTextureID_BarYellow);
+      else if ( v3 > 0.0 )
+        v9 = pIcons_LOD->GetTexture(uTextureID_BarRed);
+
+
+		if( v3 > 0.0 )
+		{
+			pRenderer->SetTextureClipRect(v17 + pHealthBarPos[i],
+                                          (signed __int64)((1.0 - v3) * v9->uTextureHeight) + 402,
+                                          v17 + pHealthBarPos[i] + v9->uTextureWidth,
+                                          v9->uTextureHeight + 402);
+
+		  pRenderer->DrawTextureIndexed(v17 + pHealthBarPos[i], 402, v9);
+		  pRenderer->ResetTextureClipRect();
+		}
+	}
+
+
+    if (player->sMana > 0)
+    {
+      v7 = player->sMana / (double)player->GetMaxMana();
+      if ( v7 > 1.0 )
+        v7 = 1.0;
+
+      int v17 = 0;
+      if (i == 2)
+        v17 = 1;
+
+      pRenderer->SetTextureClipRect(v17 + pManaBarPos[i],
+                                   (signed __int64)((1.0 - v7) * v10->uTextureHeight) + 402,
+                                   v17 + pManaBarPos[i] + v10->uTextureWidth,
+                                   v10->uTextureHeight + 402);
+      pRenderer->DrawTextureIndexed(v17 + pManaBarPos[i], 402, v10);
+      pRenderer->ResetTextureClipRect();
+    }
+  }
+}
+
+//----- (0041B3B6) --------------------------------------------------------
+void GameUI_DrawRightPanel()
+{
+  pRenderer->DrawTextureTransparent(pViewport->uViewportBR_X, 0,
+                                    pIcons_LOD->GetTexture(uTextureID_right_panel));
+}
+
+//----- (0041B3E2) --------------------------------------------------------
+void GameUI_DrawRightPanelFrames()
+{
+  pRenderer->DrawTextureRGB(0,   0,   pTexture_TopFrame);
+  pRenderer->DrawTextureRGB(0,   8,   pTexture_LeftFrame);
+  pRenderer->DrawTextureRGB(468, 0,   pTexture_RightFrame);
+  pRenderer->DrawTextureRGB(0,   352, pTexture_BottomFrame);
+  GameUI_DrawFoodAndGold();
+  GameUI_DrawRightPanelItems();
+}
+
+
+//----- (0041C047) --------------------------------------------------------
+void GameUI_Footer_2()
+{
+    char *v1; // edx@2
+    int v5; // eax@5
+
+  pRenderer->DrawTextureRGB(0, 352, pTexture_StatusBar);
+  if (GameUI_Footer_TimeLeft)
+    v1 = GameUI_Footer_TimedString.data();
+  else
+  {
+    if (!pFooterString[0])
+      return;
+    v1 = pFooterString.data();
+  }
+
+  v5 = pFontLucida->AlignText_Center(450, v1);
+  pPrimaryWindow->DrawText(pFontLucida, v5 + 11, 357, uGameUIFontMain, v1, 0, 0, uGameUIFontShadow);
+}
+
+//----- (0041C0B8) --------------------------------------------------------
+void GameUI_SetFooterString(const char *pStr)
+{
+    const char *v1; // esi@1
+    int i; // eax@7
+    int j; // eax@11
+
+    v1 = pStr;
+    if ( pStr && strcmp(pStr, "test") && !IsBadStringPtrA(v1, 1) && (*v1 || GameUI_Footer_TimeLeft) )
+        {
+        if ( GameUI_Footer_TimeLeft )
+            {
+            for ( i = pFontLucida->GetLineWidth(GameUI_Footer_TimedString.data());
+                i > 450;
+                i = pFontLucida->GetLineWidth(GameUI_Footer_TimedString.data()) )
+                byte_5C3427[strlen(GameUI_Footer_TimedString.data())] = 0;
+            }
+        else
+            {
+            strcpy(pFooterString.data(), v1);
+            for ( j = pFontLucida->GetLineWidth(pFooterString.data());
+                j > 450;
+                j = pFontLucida->GetLineWidth(pFooterString.data()) )
+                GameUI_Footer_TimedString[strlen(pFooterString.data()) + 199] = 0;
+            }
+        }
+    }
+
+//----- (0041C179) --------------------------------------------------------
+void GameUI_Footer()
+{
+    //unsigned int v0; // ebp@1
+    char *v1; // edi@5
+    int v2; // eax@5
+    unsigned int v3; // esi@5
+    size_t v4; // eax@6
+    GUIFont *v5; // ecx@6
+    int v6; // eax@9
+    size_t v7; // eax@10
+    GUIFont *v8; // ecx@10
+    char v9; // zf@12
+    //unsigned int v10; // ST08_4@13
+    int v11; // eax@13
+
+    if ( pFooterString[0] || GameUI_Footer_TimeLeft || bForceDrawFooter )
+        {
+        pRenderer->DrawTextureRGB(0, 352u, pTexture_StatusBar);
+        if ( GameUI_Footer_TimeLeft )
+            {
+            v1 = GameUI_Footer_TimedString.data();
+            v2 = pFontLucida->GetLineWidth(GameUI_Footer_TimedString.data());
+            v3 = 450;
+            while ( v2 > 450 )
+                {
+                v4 = strlen(GameUI_Footer_TimedString.data());
+                v5 = pFontLucida;
+                byte_5C3427[v4] = 0;
+                v2 = pFontLucida->GetLineWidth(GameUI_Footer_TimedString.data());
+                }
+            }
+        else
+            {
+            v1 = pFooterString.data();
+            v6 = pFontLucida->GetLineWidth(pFooterString.data());
+            v3 = 450;
+            while ( v6 > 450 )
+                {
+                v7 = strlen(pFooterString.data());
+                v8 = pFontLucida;
+                GameUI_Footer_TimedString[v7 + 199] = 0;
+                v6 = pFontLucida->GetLineWidth(pFooterString.data());
+                }
+            }
+        v9 = *v1 == 0;
+        bForceDrawFooter = 0;
+        if ( !v9 )
+            {
+            v11 = pFontLucida->AlignText_Center(v3, v1);
+            pPrimaryWindow->DrawText(pFontLucida, v11 + 11, 357, uGameUIFontMain, v1, 0, 0, uGameUIFontShadow);
+            }
+        }
+    }
+// 5C35BC: using guessed type int bForceDrawFooter;
+
+
+//----- (00420EFF) --------------------------------------------------------
+void __cdecl GameUI_WritePointedObjectStatusString()
+{
+  int v1; // ebx@6
+  GUIWindow *pWindow; // edi@7
+  GUIButton *pButton; // ecx@11
+  Player *pPlayer; // eax@19
+  char v5; // cl@19
+  unsigned int v6; // eax@19
+  int v7; // ecx@19
+  __int16 v8; // fps@23
+  unsigned __int8 v9; // c0@23
+  unsigned __int8 v10; // c3@23
+  enum UIMessageType pMessageType1; // esi@24
+  //int v12; // edx@25
+  char *v13; // ecx@28
+  int v14; // eax@41
+  ItemGen *pItemGen; // ecx@44
+  int v16; // ecx@46
+  const char *v17; // eax@49
+  signed int v18; // eax@55
+  signed int v18b;
+  signed int v19; // ecx@63
+  BLVFace *pFace; // eax@69
+  __int16 v21; // ax@70
+  const char *v22; // eax@72
+  LevelDecoration *v23; // ecx@75
+  LevelDecoration *v24; // esi@75
+  __int16 v25; // ax@75
+  const char *v26; // ecx@79
+  Actor *pActor; // ecx@82
+  char *v28; // esi@82
+  int v29; // eax@82
+  signed int v30; // ecx@88
+  const char *v31; // eax@91
+  __int16 v32; // fps@109
+  //unsigned __int8 v33; // c0@109
+  //unsigned __int8 v34; // c3@109
+  enum UIMessageType pMessageType2; // esi@110
+  //int v36; // edx@111
+  enum UIMessageType pMessageType3; // edx@117
+  //int v38; // ecx@118
+  const char *v39; // [sp-8h] [bp-E8h]@20
+  char *v40; // [sp-8h] [bp-E8h]@83
+  int v41; // [sp-4h] [bp-E4h]@20
+  char Str1[200]; // [sp+Ch] [bp-D4h]@129
+  unsigned int pX; // [sp+D4h] [bp-Ch]@1
+  unsigned int pY; // [sp+D8h] [bp-8h]@1
+  unsigned int v45; // [sp+DCh] [bp-4h]@21
+
+  v13 = nullptr;
+
+  pMouse->uPointingObjectID = 0;
+  pMouse->GetClickPos(&pX, &pY);
+  if ( pX < 0 || (signed int)pX > 639 || pY < 0 || (signed int)pY > 479 )//( (pX & 0x80000000u) != 0 || (signed int)pX > 639 || (pY & 0x80000000u) != 0 || (signed int)pY > 479 )
+    return;
+  if (pCurrentScreen == SCREEN_GAME)
+  {
+    if ( (signed int)pX > 467 || (signed int)pY > 351 )
+      goto _click_on_game_ui;
+    if ( pRenderer->pRenderD3D )  // inlined mm8::4C1E01
+    {
+      v18 = pGame->pVisInstance->get_picked_object_zbuf_val();
+      if ( (signed int)pX < (signed int)pViewport->uScreen_TL_X
+        || (signed int)pX > (signed int)pViewport->uScreen_BR_X
+        || (signed int)pY < (signed int)pViewport->uScreen_TL_Y
+        || (signed int)pY > (signed int)pViewport->uScreen_BR_Y )
+        v18 = -1;
+      if ( v18 == -1 )
+        //goto LABEL_61;
+      {
+        pMouse->uPointingObjectID = 0;
+        if ( pMouse->uPointingObjectID == 0 )
+        {
+          if ( uLastPointedObjectID != 0 )
+          {
+            pFooterString[0] = 0;
+            bForceDrawFooter = 1;
+          }
+        }
+        uLastPointedObjectID = pMouse->uPointingObjectID;
+        return;
+      }
+    }
+    else
+    {
+      v18 = pRenderer->pActiveZBuffer[pX + pSRZBufferLineOffsets[pY]];
+    }
+    pMouse->uPointingObjectID = (unsigned __int16)v18;
+    v19 = (signed)PID_ID(v18);
+    if (PID_TYPE(v18) == OBJECT_Item)
+    {
+      v30 = v19;
+      if ( pObjectList->pObjects[pSpriteObjects[v30].uObjectDescID].uFlags & 0x10 )
+        //goto LABEL_73;
+      {
+        pMouse->uPointingObjectID = 0;
+        //goto LABEL_50;
+        uLastPointedObjectID = 1;
+        if ( pMouse->uPointingObjectID == 0 )
+        {
+          if ( uLastPointedObjectID != 0 )
+          {
+            pFooterString[0] = 0;
+            bForceDrawFooter = 1;
+          }
+        }
+        uLastPointedObjectID = pMouse->uPointingObjectID;
+        return;
+      }
+      if ( v18 >= (signed int)0x2000000u || pParty->pPickedItem.uItemID )
+      {
+        v22 = pSpriteObjects[v30].stru_24.GetDisplayName();
+//LABEL_93:
+        v26 = v22;
+        //goto LABEL_87;
+        GameUI_SetFooterString(v26);
+        if ( pMouse->uPointingObjectID == 0 )
+        {
+          if ( uLastPointedObjectID != 0 )
+          {
+            pFooterString[0] = 0;
+            bForceDrawFooter = 1;
+          }
+        }
+        uLastPointedObjectID = pMouse->uPointingObjectID;
+        return;
+      }
+      v31 = pSpriteObjects[v30].stru_24.GetDisplayName();
+      v28 = pTmpBuf.data();
+      sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[470], v31);// "Get %s"
+    }
+    else
+    {
+      if (PID_TYPE(v18) != OBJECT_Actor)
+      {
+        if (PID_TYPE(v18) == OBJECT_Decoration)
+        {
+          v23 = &pLevelDecorations[v19];
+          v24 = v23;
+          v25 = v23->field_16_event_id;
+          if ( !v25 )
+          {
+            if ( v23->IsInteractive() )
+              v26 = pNPCTopics[stru_5E4C90._decor_events[v24->_idx_in_stru123 - 75] + 379].pTopic;
+            else
+              v26 = pDecorationList->pDecorations[v24->uDecorationDescID].field_20;
+            //goto LABEL_87;
+            GameUI_SetFooterString(v26);
+            if ( pMouse->uPointingObjectID == 0 )
+            {
+              if ( uLastPointedObjectID != 0 )
+              {
+                pFooterString[0] = 0;
+                bForceDrawFooter = 1;
+              }
+            }
+            uLastPointedObjectID = pMouse->uPointingObjectID;
+            return;
+          }
+          v22 = GetEventHintString(v25);
+          if ( !v22 )
+            //goto _return;
+          {
+            if ( pMouse->uPointingObjectID == 0 )
+            {
+              if ( uLastPointedObjectID != 0 )
+              {
+                pFooterString[0] = 0;
+                bForceDrawFooter = 1;
+              }
+            }
+            uLastPointedObjectID = pMouse->uPointingObjectID;
+            return;
+          }
+          //goto LABEL_93;
+          v26 = v22;
+          //goto LABEL_87;
+          GameUI_SetFooterString(v26);
+          if ( pMouse->uPointingObjectID == 0 )
+          {
+            if ( uLastPointedObjectID != 0 )
+            {
+              pFooterString[0] = 0;
+              bForceDrawFooter = 1;
+            }
+          }
+          uLastPointedObjectID = pMouse->uPointingObjectID;
+          return;
+        }
+        if (PID_TYPE(v18) == OBJECT_BModel)
+        {
+          if ( HIWORD(v18) < 512)
+          {
+            if ( uCurrentlyLoadedLevelType != LEVEL_Indoor)
+            {
+			  v18b = (signed int)(unsigned __int16)v18 >> 9;
+              v21 = pOutdoor->pBModels[v18b].pFaces[v19 & 0x3F].sCogTriggeredID;
+              //goto LABEL_71;
+              if ( !v21 || (v22 = GetEventHintString(v21)) == 0 )
+                //goto LABEL_73;
+              {
+                pMouse->uPointingObjectID = 0;
+                //goto LABEL_50;
+                uLastPointedObjectID = 1;
+                if ( pMouse->uPointingObjectID == 0 )
+                {
+                  if ( uLastPointedObjectID != 0 )
+                  {
+                    pFooterString[0] = 0;
+                    bForceDrawFooter = 1;
+                  }
+                }
+                uLastPointedObjectID = pMouse->uPointingObjectID;
+                return;
+              }
+              //goto LABEL_93;
+              v26 = v22;
+              //goto LABEL_87;
+              GameUI_SetFooterString(v26);
+              if ( pMouse->uPointingObjectID == 0 )
+              {
+                if ( uLastPointedObjectID != 0 )
+                {
+                  pFooterString[0] = 0;
+                  bForceDrawFooter = 1;
+                }
+              }
+              uLastPointedObjectID = pMouse->uPointingObjectID;
+              return;
+            }
+            pFace = &pIndoor->pFaces[v19];
+            if ( BYTE3(pFace->uAttributes) & 6 )
+            {
+              v21 = pIndoor->pFaceExtras[pFace->uFaceExtraID].uEventID;
+//LABEL_71:
+              if ( !v21 || (v22 = GetEventHintString(v21)) == 0 )
+                //goto LABEL_73;
+              {
+                pMouse->uPointingObjectID = 0;
+                //goto LABEL_50;
+                uLastPointedObjectID = 1;
+                if ( pMouse->uPointingObjectID == 0 )
+                {
+                  if ( uLastPointedObjectID != 0 )
+                  {
+                    pFooterString[0] = 0;
+                    bForceDrawFooter = 1;
+                  }
+                }
+                uLastPointedObjectID = pMouse->uPointingObjectID;
+                return;
+              }
+              //goto LABEL_93;
+              v26 = v22;
+              //goto LABEL_87;
+              GameUI_SetFooterString(v26);
+              if ( pMouse->uPointingObjectID == 0 )
+              {
+                if ( uLastPointedObjectID != 0 )
+                {
+                  pFooterString[0] = 0;
+                  bForceDrawFooter = 1;
+                }
+              }
+              uLastPointedObjectID = pMouse->uPointingObjectID;
+              return;
+            }
+          }
+//LABEL_73:
+          pMouse->uPointingObjectID = 0;
+          //goto LABEL_50;
+          uLastPointedObjectID = 1;
+          if ( pMouse->uPointingObjectID == 0 )
+          {
+            if ( uLastPointedObjectID != 0 )
+            {
+              pFooterString[0] = 0;
+              bForceDrawFooter = 1;
+            }
+          }
+          uLastPointedObjectID = pMouse->uPointingObjectID;
+          return;
+        }
+//LABEL_61:
+        pMouse->uPointingObjectID = 0;
+        //goto _return;
+        if ( pMouse->uPointingObjectID == 0 )
+        {
+          if ( uLastPointedObjectID != 0 )
+          {
+            pFooterString[0] = 0;
+            bForceDrawFooter = 1;
+          }
+        }
+        uLastPointedObjectID = pMouse->uPointingObjectID;
+        return;
+      }
+      if ( v18 >= 335544320 )
+        //goto LABEL_61;
+      {
+        pMouse->uPointingObjectID = 0;
+        if ( pMouse->uPointingObjectID == 0 )
+        {
+          if ( uLastPointedObjectID != 0 )
+          {
+            pFooterString[0] = 0;
+            bForceDrawFooter = 1;
+          }
+        }
+        uLastPointedObjectID = pMouse->uPointingObjectID;
+        return;
+      }
+      pActor = &pActors[v19];
+      v28 = pTmpBuf.data();
+      v29 = pActor->dword_000334_unique_name;
+      if ( v29 )
+        v40 = pMonsterStats->pPlaceStrings[v29];
+      else
+        v40 = pMonsterStats->pInfos[pActor->pMonsterInfo.uID].pName;
+      strncpy(pTmpBuf.data(), v40, 0x7D0u);
+    }
+    v26 = v28;
+//LABEL_87:
+    GameUI_SetFooterString(v26);
+    //goto _return;
+    if ( pMouse->uPointingObjectID == 0 )
+    {
+      if ( uLastPointedObjectID != 0 )
+      {
+        pFooterString[0] = 0;
+        bForceDrawFooter = 1;
+      }
+    }
+    uLastPointedObjectID = pMouse->uPointingObjectID;
+    return;
+  }
+  v1 = uNumVisibleWindows;
+  if ( uNumVisibleWindows > 0 )
+  {
+	  while ( 1 )                                   // some other fullscreen ui
+	  {
+		pWindow = &pWindowList[pVisibleWindowsIdxs[v1] - 1];
+		if ( (signed int)pX >= (signed int)pWindow->uFrameX
+		  && (signed int)pX <= (signed int)pWindow->uFrameZ
+		  && (signed int)pY >= (signed int)pWindow->uFrameY
+		  && (signed int)pY <= (signed int)pWindow->uFrameW )
+		{
+		  for ( pButton = pWindow->pControlsHead; ; pButton = pButton->pNext )
+		  {
+			if ( !pButton )
+			  break;
+			if ( pButton->uButtonType == 1 )
+			{
+			  if ( (signed int)pX >= (signed int)pButton->uX
+				&& (signed int)pX <= (signed int)pButton->uZ
+				&& (signed int)pY >= (signed int)pButton->uY
+				&& (signed int)pY <= (signed int)pButton->uW )
+			  {
+	//LABEL_24:
+				pMessageType1 = (UIMessageType)pButton->field_1C;
+				if ( pMessageType1 )
+				{
+				  pMessageQueue_50CBD0->AddMessage(pMessageType1, pButton->msg_param, 0);
+				}
+	//LABEL_28:
+				v13 = pButton->pButtonName;
+	//_set_status_and_ret:
+				GameUI_SetFooterString(v13);
+	//LABEL_131:
+				uLastPointedObjectID = 1;
+				return;
+			  }
+			}
+			else
+			{
+			  if ( pButton->uButtonType == 2 )
+			  {
+				v45 = pX - pButton->uX;
+				v45 = pY - pButton->uY;
+				if ( (double)(signed int)pButton->uWidth != 0.0 )
+				{
+				  if ( (double)(signed int)pButton->uHeight != 0.0 )
+				  {
+					  pMessageType1 = (UIMessageType)pButton->field_1C;
+					  if ( pMessageType1 )
+					  {
+						pMessageQueue_50CBD0->AddMessage(pMessageType1, pButton->msg_param, 0);
+					  }
+					  v13 = pButton->pButtonName;
+					  GameUI_SetFooterString(v13);
+					  uLastPointedObjectID = 1;
+					  return;
+					//}
+				  }
+				}
+			  }
+			  else                                  // click on skill
+			  {
+				if ( pButton->uButtonType == 3
+				  && (signed int)pX >= (signed int)pButton->uX
+				  && (signed int)pX <= (signed int)pButton->uZ
+				  && (signed int)pY >= (signed int)pButton->uY
+				  && (signed int)pY <= (signed int)pButton->uW )
+				{
+	//LABEL_19:
+				  pPlayer = pPlayers[uActiveCharacter];
+				  v5 = LOBYTE(pPlayer->pActiveSkills[pButton->msg_param]);
+				  v6 = pPlayer->uSkillPoints;
+				  v7 = (v5 & 0x3F) + 1;
+				  if ( v6 < v7 )
+				  {
+					v41 = v7 - v6;
+					v39 = pGlobalTXT_LocalizationStrings[469];// "You need %d more Skill Points to advance here"
+				  }
+				  else
+				  {
+					v41 = v7;
+					v39 = pGlobalTXT_LocalizationStrings[468];// "Clicking here will spend %d Skill Points"
+				  }
+				  sprintf(Str1, v39, v41);
+				  v13 = Str1;
+				  //goto _set_status_and_ret;
+				  GameUI_SetFooterString(v13);
+				  uLastPointedObjectID = 1;
+				  return;
+				}
+			  }
+			}
+		  }
+		}
+		if ( pWindow->uFrameHeight == 480 )
+		  break;
+		--v1;
+		if ( v1 <= 0 )
+		{
+		  break;
+		}
+	  }
+  }
+  if ( uNumVisibleWindows <= 0 || (uNumVisibleWindows > 0 && pWindow->uFrameHeight != 480 && v1 <= 0))
+  {
+    if ( pCurrentScreen == SCREEN_CHEST )
+    {
+      sub_42038D();
+      //goto _return;
+      if ( pMouse->uPointingObjectID == 0 )
+      {
+        if ( uLastPointedObjectID != 0 )
+        {
+          pFooterString[0] = 0;
+          bForceDrawFooter = 1;
+        }
+      }
+      uLastPointedObjectID = pMouse->uPointingObjectID;
+      return;
+    }
+    if ( pCurrentScreen == SCREEN_HOUSE )
+    {
+      if ( dialog_menu_id != HOUSE_DIALOGUE_SHOP_BUY_STANDARD
+        || (v16 = pRenderer->pActiveZBuffer[pX + pSRZBufferLineOffsets[pY]], v16 == 0)
+        || v16 == -65536 )
+        //goto _return;
+      {
+        if ( pMouse->uPointingObjectID == 0 )
+        {
+          if ( uLastPointedObjectID != 0 )
+          {
+            pFooterString[0] = 0;
+            bForceDrawFooter = 1;
+          }
+        }
+        uLastPointedObjectID = pMouse->uPointingObjectID;
+        return;
+       }
+      pItemGen = (ItemGen *)((char *)&pParty->pPickedItem + 36 * (v16 + 12 * (unsigned int)window_SpeakInHouse->ptr_1C) + 4);
+//LABEL_49:
+      v17 = pItemGen->GetDisplayName();
+      GameUI_SetFooterString(v17);
+//LABEL_50:
+      uLastPointedObjectID = 1;
+//_return:
+      if ( pMouse->uPointingObjectID == 0 )
+      {
+        if ( uLastPointedObjectID != 0 )
+        {
+          pFooterString[0] = 0;
+          bForceDrawFooter = 1;
+        }
+      }
+      uLastPointedObjectID = pMouse->uPointingObjectID;
+      return;
+    }
+    if ( (signed int)pY < 350 )
+    {
+      v14 = pRenderer->pActiveZBuffer[pX + pSRZBufferLineOffsets[pY]];
+      if ( v14 == 0 || v14 == -65536 || (unsigned int)v14 >= 0x1388 )
+        //goto _return;
+      {
+        if ( pMouse->uPointingObjectID == 0 )
+        {
+          if ( uLastPointedObjectID != 0 )
+          {
+            pFooterString[0] = 0;
+            bForceDrawFooter = 1;
+          }
+        }
+        uLastPointedObjectID = pMouse->uPointingObjectID;
+        return;
+      }
+      pItemGen = (ItemGen *)&pPlayers[uActiveCharacter]->pInventoryItems[v14-1];
+      //goto LABEL_49;
+      v17 = pItemGen->GetDisplayName();
+      GameUI_SetFooterString(v17);
+      uLastPointedObjectID = 1;
+      if ( pMouse->uPointingObjectID == 0 )
+      {
+        if ( uLastPointedObjectID != 0 )
+        {
+          pFooterString[0] = 0;
+          bForceDrawFooter = 1;
+        }
+      }
+      uLastPointedObjectID = pMouse->uPointingObjectID;
+      return;
+    }
+_click_on_game_ui:
+    if ( (signed int)pX >= (signed int)pWindowList[0].uFrameX
+      && (signed int)pX <= (signed int)pWindowList[0].uFrameZ
+      && (signed int)pY >= (signed int)pWindowList[0].uFrameY
+      && (signed int)pY <= (signed int)pWindowList[0].uFrameW )
+    {
+      for ( pButton = pWindowList[0].pControlsHead; pButton != (GUIButton *)0; pButton = pButton->pNext )
+      {
+        if ( pButton->uButtonType == 1 )
+        {
+          if ( (signed int)pX >= (signed int)pButton->uX
+            && (signed int)pX <= (signed int)pButton->uZ
+            && (signed int)pY >= (signed int)pButton->uY
+            && (signed int)pY <= (signed int)pButton->uW )
+          {
+            pMessageType3 = (UIMessageType)pButton->field_1C;
+            if ( pMessageType3 == 0 ) // For books
+              //goto LABEL_28;
+            {
+              v13 = pButton->pButtonName;
+              GameUI_SetFooterString(v13);
+              uLastPointedObjectID = 1;
+              return;
+            }
+
+            pMessageQueue_50CBD0->AddMessage(pMessageType3, pButton->msg_param, 0);
+            //goto LABEL_131;
+            uLastPointedObjectID = 1;
+            return;
+          }
+        }
+        else
+        {
+          if ( pButton->uButtonType == 2 )
+          {
+            v45 = pX - pButton->uX;
+            v45 = pY - pButton->uY;
+
+            if (pX >= pButton->uX && pX <= pButton->uZ &&
+                pY >= pButton->uY && pY <= pButton->uW)
+            if ( (double)(signed int)pButton->uWidth != 0.0 )
+            {
+              if ( (double)(signed int)pButton->uHeight != 0.0 )
+              {
+                 //UNDEF(v32);
+                //if ( v33 | v34 )
+                //{
+                  pMessageType2 = (UIMessageType)pButton->field_1C;
+                  if ( pMessageType2 != 0 )
+                      pMessageQueue_50CBD0->AddMessage(pMessageType2, pButton->msg_param, 0);
+
+                  //goto LABEL_28;
+                  v13 = pButton->pButtonName;
+                  GameUI_SetFooterString(v13);
+                  uLastPointedObjectID = 1;
+                  return;
+                //}
+              }
+            }
+          }
+          else
+          {
+            if ( pButton->uButtonType == 3
+              && (signed int)pX >= (signed int)pButton->uX
+              && (signed int)pX <= (signed int)pButton->uZ
+              && (signed int)pY >= (signed int)pButton->uY
+              && (signed int)pY <= (signed int)pButton->uW )
+              //goto LABEL_19;
+            {
+              pPlayer = pPlayers[uActiveCharacter];
+              v5 = LOBYTE(pPlayer->pActiveSkills[pButton->msg_param]);
+              v6 = pPlayer->uSkillPoints;
+              v7 = (v5 & 0x3F) + 1;
+              if ( v6 < v7 )
+              {
+                v41 = v7 - v6;
+                v39 = pGlobalTXT_LocalizationStrings[469];// "You need %d more Skill Points to advance here"
+              }
+              else
+              {
+                v41 = v7;
+                v39 = pGlobalTXT_LocalizationStrings[468];// "Clicking here will spend %d Skill Points"
+              }
+              sprintf(Str1, v39, v41);
+              v13 = Str1;
+              //goto _set_status_and_ret;
+              GameUI_SetFooterString(v13);
+              uLastPointedObjectID = 1;
+              return;
+            }
+          }
+        }
+      }
+    }
+    pMouse->uPointingObjectID = sub_46A99B();
+    //goto _return;
+    if ( pMouse->uPointingObjectID == 0 )
+    {
+      if ( uLastPointedObjectID != 0 )
+      {
+        pFooterString[0] = 0;
+        bForceDrawFooter = 1;
+      }
+    }
+    uLastPointedObjectID = pMouse->uPointingObjectID;
+    return;
+  }
+}
+
+
+//----- (0044158F) --------------------------------------------------------
+void GameUI_DrawCharacterSelectionFrame()
+{
+  if ( uActiveCharacter )
+    pRenderer->DrawTextureTransparent(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[uActiveCharacter - 1] - 9, 380,
+                                      pIcons_LOD->GetTexture(uTextureID_GameUI_CharSelectionFrame));
+}
+
+
+
+//----- (0044162D) --------------------------------------------------------
+void GameUI_DrawPartySpells()
+{
+    unsigned int v0; // ebp@1
+    //signed int v1; // edi@1
+    //int v2; // eax@2
+    //int v3; // ecx@5
+    //__int16 *v4; // ebx@25
+    //Player *v5; // edi@26
+    //unsigned int v6; // [sp-4h] [bp-1Ch]@11
+    Texture *v7; // [sp-4h] [bp-1Ch]@12
+    //unsigned int v8; // [sp-4h] [bp-1Ch]@20
+    Texture *v9; // [sp-4h] [bp-1Ch]@21
+    //Player **v10; // [sp+10h] [bp-8h]@25
+
+    v0 = (signed __int64)((double)GetTickCount() * 0.050000001);
+    //v1 = 0;
+    for (uint i = 0; i < 14; ++i)
+        {
+        //v2 =  byte_4E5DD8[v1];
+        if (pParty->pPartyBuffs[byte_4E5DD8[i]].uExpireTime)
+            {
+            auto tex = pIcons_LOD->GetTexture(pTextureIDs_PartyBuffIcons[i]);
+            //v3 = pTextureIDs_PartyBuffIcons[i];
+                pRenderer->_4A65CC(pPartySpellbuffsUI_XYs[i][0],
+                pPartySpellbuffsUI_XYs[i][1], tex, tex,
+                v0 + 20 * pPartySpellbuffsUI_smthns[i], 0, 63);
+            }
+        //++v1;
+        }
+    //while ( v1 < 14 );
+
+    if (pCurrentScreen == SCREEN_GAME || pCurrentScreen == SCREEN_NPC_DIALOGUE)
+        {
+        if (pParty->FlyActive())
+            {
+            if ( pParty->bFlying )
+                v7 = pIcons_LOD->GetTexture(pIconsFrameTable->GetFrame(uIconIdx_FlySpell, v0)->uTextureID);
+            else
+                v7 = pIcons_LOD->GetTexture(pIconsFrameTable->GetFrame(uIconIdx_FlySpell, 0)->uTextureID);
+            if ( pRenderer->pRenderD3D )
+                pRenderer->DrawTextureIndexed(8, 8, v7);
+            else
+                pRenderer->DrawTextureTransparent(8, 8, v7);
+            }
+        if (pParty->WaterWalkActive())
+            {
+            if ( pParty->uFlags & PARTY_FLAGS_1_STANDING_ON_WATER)
+                v9 = pIcons_LOD->GetTexture(pIconsFrameTable->GetFrame(uIconIdx_WaterWalk, v0)->uTextureID);
+            else
+                v9 = pIcons_LOD->GetTexture(pIconsFrameTable->GetFrame(uIconIdx_WaterWalk, 0)->uTextureID);
+            if ( pRenderer->pRenderD3D )
+                pRenderer->DrawTextureIndexed(396u, 8u, v9);
+            else
+                pRenderer->DrawTextureTransparent(396u, 8u, v9);
+            }
+        }
+
+    for (uint i = 0; i < 4; ++i)
+        {
+        auto player = pParty->pPlayers + i;
+
+        if (player->pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].uExpireTime)
+            pRenderer->DrawTextureIndexed(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i] + 72, 427, pIcons_LOD->GetTexture(uTextureID_PlayerBuff_Hammerhands));
+        if (player->pPlayerBuffs[PLAYER_BUFF_BLESS].uExpireTime)
+            pRenderer->DrawTextureIndexed(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i] + 72, 393, pIcons_LOD->GetTexture(uTextureID_PlayerBuff_Bless));
+        if (player->pPlayerBuffs[PLAYER_BUFF_PRESERVATION].uExpireTime)
+            pRenderer->DrawTextureIndexed(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i] + 72, 410, pIcons_LOD->GetTexture(uTextureID_PlayerBuff_Preservation));
+        if (player->pPlayerBuffs[PLAYER_BUFF_PAIN_REFLECTION].uExpireTime)
+            pRenderer->DrawTextureIndexed(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i] + 72, 444, pIcons_LOD->GetTexture(uTextureID_PlayerBuff_PainReflection));
+        }
+    }
+
+
+
+//----- (004921C1) --------------------------------------------------------
+void GameUI_DrawPortraits(unsigned int _this)
+{
+    Texture *pFace; // eax@10
+    unsigned int v7; // eax@17
+    PlayerFrame *pFrame; // eax@21
+    unsigned int v9; // eax@27
+    bool v10; // eax@33
+    bool v11; // edi@40
+    bool v12; // edx@43
+    bool v13; // ecx@46
+    int v16; // eax@57
+    int v19; // eax@62
+    Texture *pPortrait; // [sp-4h] [bp-1Ch]@27
+    unsigned int v22; // [sp+14h] [bp-4h]@1
+
+    v22 = _this;
+    if ( qword_A750D8 )
+        {
+        qword_A750D8 -= (signed int)pMiscTimer->uTimeElapsed;
+        if ( qword_A750D8 <= 0 )
+            {
+            if ( pPlayers[word_A750E2]->CanAct() )
+                pPlayers[word_A750E2]->PlaySound((PlayerSpeech)word_A750E0, 0);
+            qword_A750D8 = 0i64;
+            }
+        }
+
+    for (uint i = 0; i < 4; ++i)
+        {
+        auto pPlayer = pParty->pPlayers + i;
+
+        if (pPlayer->Eradicated())
+            {
+            pFace = pTexture_PlayerFaceEradicated;
+            pPortrait = pFace;
+            v9 = pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i];
+            if ( pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime )
+                pRenderer->_4A6E7E(v9, 0x183u, pPortrait);
+            else
+                pRenderer->DrawTextureTransparent(v9 + 1, 0x184u, pPortrait);
+            auto _v1 = 0;
+            v10 = pPlayer->pPlayerBuffs[14].uExpireTime > 0;
+            if (pPlayer->pPlayerBuffs[1].uExpireTime > 0)
+                _v1 = 1;
+            v11 = pPlayer->pPlayerBuffs[8].uExpireTime > 0;
+            v12 = pPlayer->pPlayerBuffs[7].uExpireTime > 0;
+            v13 = pPlayer->pPlayerBuffs[13].uExpireTime > 0;
+            if ( v13 | v12 | v11 | _v1 | v10 )
+                sub_441A4E(i);
+            continue;
+            }
+        if (pPlayer->Dead())
+            {
+            pFace = pTexture_PlayerFaceDead;
+            pPortrait = pFace;
+            v9 = pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i];
+            if ( pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime )
+                pRenderer->_4A6E7E(v9, 0x183u, pPortrait);
+            else
+                pRenderer->DrawTextureTransparent(v9 + 1, 0x184u, pPortrait);
+            auto _v1 = 0;
+            v10 = pPlayer->pPlayerBuffs[14].uExpireTime > 0;
+            if (pPlayer->pPlayerBuffs[1].uExpireTime > 0)
+                _v1 = 1;
+            v11 = pPlayer->pPlayerBuffs[8].uExpireTime > 0;
+            v12 = pPlayer->pPlayerBuffs[7].uExpireTime > 0;
+            v13 = pPlayer->pPlayerBuffs[13].uExpireTime > 0;
+            if ( v13 | v12 | v11 | _v1 | v10 )
+                sub_441A4E(i);
+            continue;
+            }
+        v7 = 0;
+        for (uint j = 0; j < pPlayerFrameTable->uNumFrames; ++j)
+            if (pPlayerFrameTable->pFrames[j].expression == pPlayer->expression)
+                {
+                v7 = j;
+                break;
+                }
+            if ( v7 == 0 )
+                v7 = 1;
+            if (pPlayer->expression == CHARACTER_EXPRESSION_21)
+                pFrame = pPlayerFrameTable->GetFrameBy_y(&pPlayer->_expression21_frameset, &pPlayer->_expression21_animtime, pMiscTimer->uTimeElapsed);
+            else
+                pFrame = pPlayerFrameTable->GetFrameBy_x(v7, pPlayer->uExpressionTimePassed);
+            if (pPlayer->field_1AA2 != pFrame->uTextureID - 1 || v22 )
+                {
+                pPlayer->field_1AA2 = pFrame->uTextureID - 1;
+                pFace = (Texture *)pTextures_PlayerFaces[i][pPlayer->field_1AA2];//pFace = (Texture *)pTextures_PlayerFaces[i][pFrame->uTextureID];
+                pPortrait = pFace;
+                v9 = pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i];
+                if ( pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime )
+                    pRenderer->_4A6E7E(v9, 0x183u, pPortrait);
+                else
+                    pRenderer->DrawTextureTransparent(v9 + 1, 0x184u, pPortrait);
+                auto _v1 = 0;
+                v10 = pPlayer->pPlayerBuffs[14].uExpireTime > 0;
+                if (pPlayer->pPlayerBuffs[1].uExpireTime > 0)
+                    _v1 = 1;
+                v11 = pPlayer->pPlayerBuffs[8].uExpireTime > 0;
+                v12 = pPlayer->pPlayerBuffs[7].uExpireTime > 0;
+                v13 = pPlayer->pPlayerBuffs[13].uExpireTime > 0;
+                if ( v13 | v12 | v11 | _v1 | v10 )
+                    sub_441A4E(i);
+                continue;
+                }
+        }
+    if ( pParty->bTurnBasedModeOn == 1 )
+        {
+        if ( pTurnEngine->field_4 != 1 )
+            {
+            if (PID_TYPE(pTurnEngine->pQueue[0].uPackedID) == OBJECT_Player)
+                {
+                //v14 = 0;
+                if ( pTurnEngine->uActorQueueSize > 0 )
+                    {
+                    //v15 = (char *)pTurnEngine->pQueue;
+                    for (uint i = 0; i < pTurnEngine->uActorQueueSize; ++i)
+                        {
+                        auto pElem = pTurnEngine->pQueue + i;
+
+                        if (PID_TYPE(pElem->uPackedID) != OBJECT_Player)
+                            break;
+                        v16 = dword_5079D0;
+                        if ( pParty->uFlags & 0x10 )
+                            {
+                            v16 = dword_5079CC;
+                            }
+                        else
+                            {
+                            if ( pParty->uFlags & 0x20 )
+                                v16 = dword_5079C8;
+                            }
+                        pRenderer->DrawTextureTransparent(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[PID_ID(pElem->uPackedID)] - 4, 0x181u, pIcons_LOD->GetTexture(v16));
+                        }
+                    }
+                }
+            }
+        }
+    else
+        {
+        for (uint i = 0; i < 4; ++i)
+            {
+            auto pPlayer = pParty->pPlayers + i;
+            if (pPlayer->CanAct() && !pPlayer->uTimeToRecovery)
+                {
+                v19 = dword_5079D0;
+                if ( pParty->uFlags & 0x10 )
+                    {
+                    v19 = dword_5079CC;
+                    }
+                else
+                    {
+                    if ( pParty->uFlags & 0x20 )
+                        v19 = dword_5079C8;
+                    }
+                pRenderer->DrawTextureTransparent(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i] - 4, 0x181u, pIcons_LOD->GetTexture(v19));
+                }
+            }
+        }
+    }
+
+//----- (00441D38) --------------------------------------------------------
+void GameUI_DrawMinimap(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW, unsigned int uZoom, unsigned int bRedrawOdmMinimap)
+{
+  int uHeight; // ebx@6
+  __int16 v11; // cx@11
+  unsigned int v14; // ebx@23
+  int v15; // eax@23
+  __int16 v17; // di@30
+  double v18; // st7@30
+  float v19; // ST38_4@30
+  double v20; // st7@30
+  double v21; // st6@30
+  double v22; // st5@33
+  signed int v27; // eax@37
+  unsigned __int16 *v28; // ecx@37
+  signed int v29; // edi@40
+  //signed int v33; // ebx@50
+  //unsigned int v34; // eax@50
+  //signed int v35; // ecx@50
+  //unsigned __int16 v36; // di@66
+  int v37; // edi@72
+  int v38; // ebx@72
+  __int16 v39; // ax@87
+  int v40; // edi@91
+  int v41; // ebx@91
+  unsigned int v42; // eax@101
+  unsigned int v43; // ebx@101
+  unsigned int v44; // ST30_4@101
+  char *v45; // ebx@106
+  int v46; // edi@108
+  int v47; // eax@108
+  unsigned int v48; // ebx@114
+  unsigned int v49; // ST64_4@114
+  //unsigned int v51; // [sp-10h] [bp-64h]@79
+  unsigned int v52; // [sp-10h] [bp-64h]@100
+  //unsigned int v53; // [sp-Ch] [bp-60h]@79
+  unsigned int v54; // [sp-Ch] [bp-60h]@100
+  //unsigned int v55; // [sp-8h] [bp-5Ch]@77
+  unsigned int v56; // [sp-8h] [bp-5Ch]@100
+  //signed int v57; // [sp-4h] [bp-58h]@54
+  //unsigned __int16 v58; // [sp-4h] [bp-58h]@77
+  unsigned __int16 v59; // [sp-4h] [bp-58h]@100
+  //unsigned __int16 v60; // [sp+10h] [bp-44h]@66
+  //unsigned int v61; // [sp+10h] [bp-44h]@85
+  //unsigned int v63; // [sp+14h] [bp-40h]@85
+  //unsigned int v65; // [sp+18h] [bp-3Ch]@85
+  unsigned int lPitch; // [sp+20h] [bp-34h]@1
+  unsigned int lPitcha; // [sp+20h] [bp-34h]@23
+  char *lPitchb; // [sp+20h] [bp-34h]@106
+  unsigned int v69; // [sp+24h] [bp-30h]@23
+  signed int v70; // [sp+24h] [bp-30h]@37
+  //unsigned __int16 uBlue; // [sp+28h] [bp-2Ch]@1
+  signed int uBluea; // [sp+28h] [bp-2Ch]@37
+  int v73; // [sp+2Ch] [bp-28h]@30
+  int v76; // [sp+34h] [bp-20h]@91
+  int v77; // [sp+34h] [bp-20h]@108
+  //int v79; // [sp+38h] [bp-1Ch]@72
+  //char *a2c; // [sp+40h] [bp-14h]@68
+  signed int uCenterY; // [sp+48h] [bp-Ch]@1
+  signed int uCenterX; // [sp+4Ch] [bp-8h]@1
+  signed int uWidth; // [sp+5Ch] [bp+8h]@30
+  //signed int uZe; // [sp+5Ch] [bp+8h]@67
+  signed int uZf; // [sp+5Ch] [bp+8h]@85
+  signed int uZg; // [sp+5Ch] [bp+8h]@105
+  unsigned int uWa; // [sp+60h] [bp+Ch]@23
+  float uWb; // [sp+60h] [bp+Ch]@30
+  unsigned int uWd; // [sp+60h] [bp+Ch]@95
+  float uZooma; // [sp+64h] [bp+10h]@117
+  //unsigned int flagsb; // [sp+68h] [bp+14h]@66
+  Actor *flagsc; // [sp+68h] [bp+14h]@86
+  //unsigned int flagsd; // [sp+68h] [bp+14h]@105
+
+  uCenterX = (uX + uZ) / 2;
+  uCenterY = (uY + uW) / 2;
+  lPitch = pRenderer->uTargetSurfacePitch;
+  //TargetColor(0, 0, 0);
+  //uBlue = TargetColor(0, 0, 0xFFu);
+  auto bWizardEyeActive = pParty->WizardEyeActive();
+  auto uWizardEyeSkillLevel = pParty->WizardEyeSkillLevel();
+  if (CheckHiredNPCSpeciality(Cartographer))
+  {
+    bWizardEyeActive = true;
+    uWizardEyeSkillLevel = 2;
+  }
+    bWizardEyeActive = true;
+    uWizardEyeSkillLevel = 3;
+  pRenderer->SetRasterClipRect(uX, uY, uZ - 1, uW - 1);
+  uHeight = uW - uY;
+  uWidth = uZ - uX;
+
+  if ( uCurrentlyLoadedLevelType != LEVEL_Indoor)
+  {
+    v17 = pIcons_LOD->pTextures[viewparams->uTextureID_LocationMap].uWidthLn2;
+    auto pMapLod0 = pIcons_LOD->pTextures[viewparams->uTextureID_LocationMap].pLevelOfDetail0_prolly_alpha_mask;
+    auto pPal = pIcons_LOD->pTextures[viewparams->uTextureID_LocationMap].pPalette16;
+    v73 = (1 << (v17 + 16)) / (signed int)uZoom;
+    v18 = (double)(1 << (16 - v17));
+    v19 = v18;
+    v20 = (double)(pParty->vPosition.x + 32768) / v18;
+    v21 = (double)(32768 - pParty->vPosition.y) / v19;
+    uWb = v21;
+    switch (uZoom)
+    {
+      case 512:
+      {
+        v20 = v20 - (double)(uWidth / 2);
+        v22 = (double)(uHeight / 2);
+        uWb = v21 - v22;
+      }
+      break;
+
+      case 1024:
+      {
+        v20 = v20 - (double)(uWidth / 4);
+        v22 = (double)(uHeight / 4);
+        uWb = v21 - v22;
+      }
+      break;
+
+      case 2048:
+      {
+        v20 = v20 - (double)(uWidth / 8);
+        v22 = (double)(uHeight / 8);
+        uWb = v21 - v22;
+      }
+      break;
+
+      default: assert(false);
+    }
+    assert(sizeof(pOdmMinimap) == 137 * 117 * sizeof(short));
+
+    v70 = floorf(v20 * 65536.0 + 0.5f);//LODWORD(v24);
+    uBluea = floorf(uWb * 65536.0 + 0.5f);//LODWORD(v25);
+    v27 = uBluea >> 16;
+    v28 = &pRenderer->pTargetSurface[uX + uY * lPitch];
+    if (pMapLod0 && bRedrawOdmMinimap)
+    {
+      assert(uWidth == 137 && uHeight == 117);
+      //auto pMinimap = (unsigned __int16 *)pOdmMinimap;
+
+        auto mapWidth = pIcons_LOD->pTextures[viewparams->uTextureID_LocationMap].uTextureWidth;
+
+          v29 = v70 >> 16;
+
+          for (int y = 0; y < uHeight; ++y)
+          {
+              auto pMapLod0Line = &pMapLod0[v27 * mapWidth];
+              for (int x = 0; x < uWidth; ++x)
+              {
+                //*pMinimap++ = pPal[pMapLod0Line[v29]];
+                pOdmMinimap[y][x] = pPal[pMapLod0Line[v29]];
+                v29 = (v70 + x * v73) >> 16;
+              }
+
+            v29 = v70 >> 16;
+            v28 += 137 - uWidth;
+            uBluea += v73;
+            v27 = uBluea >> 16;
+          }
+    }
+
+    for (int y = 0; y < 117; ++y)
+    {
+      for (int x = 0; x < 137; ++x)
+      {
+        *v28++ = pOdmMinimap[y][x];
+      }
+      v28 += lPitch - 137;
+    }
+    uNumBlueFacesInBLVMinimap = 0;
+  }
+  else
+  {
+    pRenderer->FillRectFast(uX, uY, uZ - uX, uHeight, 0xF);
+    uNumBlueFacesInBLVMinimap = 0;
+
+    for (uint i = 0; i < pIndoor->pMapOutlines->uNumOutlines; ++i)
+    {
+      auto pOutline = &pIndoor->pMapOutlines->pOutlines[i];
+
+      auto pFace1 = pIndoor->pFaces + pOutline->uFace1ID;
+      auto pFace2 = pIndoor->pFaces + pOutline->uFace2ID;
+      //v9 = pIndoor->pFaces[pMapVertex->uFace1ID].uAttributes;
+        //v10 = pIndoor->pFaces[pMapVertex->uFace2ID].uAttributes;
+      if (pFace1->Visible() && pFace2->Visible())
+      {
+        v11 = pOutline->uFlags;
+        if ( v11 & 1 )
+          goto LABEL_15;
+        if (pFace1->uAttributes & 0x80 || pFace2->uAttributes & 0x80)
+          goto LABEL_ABC;
+
+      }
+      continue;
+
+LABEL_ABC:
+    pOutline->uFlags = v11 | 1;
+    pIndoor->_visible_outlines[i >> 3] |= 1 << (7 - i % 8);
+
+LABEL_15:
+    //v12 = &pIndoor->pFaces[pOutline->uFace1ID];
+    if (bWizardEyeActive && uWizardEyeSkillLevel >= 3 &&
+        (pFace1->uAttributes & 0x2000 || pFace2->uAttributes & 0x2000) &&
+        (pIndoor->pFaceExtras[pFace1->uFaceExtraID].uEventID || pIndoor->pFaceExtras[pFace2->uFaceExtraID].uEventID))
+    {
+      if (uNumBlueFacesInBLVMinimap < 49)
+        pBlueFacesInBLVMinimapIDs[uNumBlueFacesInBLVMinimap++] = i;
+    }
+    else
+    {
+      auto _a = (uZoom * (signed __int64)pIndoor->pVertices[pOutline->uVertex1ID].x);
+      auto _b = ((unsigned int)((unsigned __int64)_a >> 16) << 16);
+      auto _c = ((signed int)(_b - uZoom * pParty->vPosition.x) >> 16);
+      v69 =     uCenterX + _c;
+      v69 =     uCenterX + ((signed int)(((unsigned int)((unsigned __int64)(uZoom * (signed __int64)pIndoor->pVertices[pOutline->uVertex1ID].x) >> 16) << 16) - uZoom * pParty->vPosition.x) >> 16);
+      lPitcha = uCenterY - ((signed int)(((unsigned int)((unsigned __int64)(uZoom * (signed __int64)pIndoor->pVertices[pOutline->uVertex1ID].y) >> 16) << 16) - uZoom * pParty->vPosition.y) >> 16);
+      uWa =     uCenterX + ((signed int)(((unsigned int)((unsigned __int64)(uZoom * (signed __int64)pIndoor->pVertices[pOutline->uVertex2ID].x) >> 16) << 16) - uZoom * pParty->vPosition.x) >> 16);
+      v14 =     uCenterY - ((signed int)(((unsigned int)((unsigned __int64)(uZoom * (signed __int64)pIndoor->pVertices[pOutline->uVertex2ID].y) >> 16) << 16) - uZoom * pParty->vPosition.y) >> 16);
+      v15 = abs(pOutline->sZ - pParty->vPosition.z) / 8;
+      if ( v15 > 100 )
+        v15 = 100;
+      pRenderer->RasterLine2D(v69, lPitcha, uWa, v14, viewparams->pPalette[-v15 + 200]);
+    }
+  }
+
+
+  for (uint i = 0; i < uNumBlueFacesInBLVMinimap; ++i)
+  {
+    //v16 = (uint *)&pIndoor->pMapOutlines->pOutlines[pBlueFacesInBLVMinimapIDs[uZb]];
+    auto pOutline = &pIndoor->pMapOutlines->pOutlines[pBlueFacesInBLVMinimapIDs[i]];
+    pRenderer->RasterLine2D(uCenterX + ((signed int)(((unsigned int)((unsigned __int64)((signed int)uZoom
+                                                     * (signed __int64)pIndoor->pVertices[pOutline->uVertex1ID].x) >> 16) << 16)
+                  - uZoom * pParty->vPosition.x) >> 16),
+      uCenterY
+    - ((signed int)(((unsigned int)((unsigned __int64)((signed int)uZoom
+                                                     * (signed __int64)pIndoor->pVertices[pOutline->uVertex1ID].y) >> 16) << 16)
+                  - uZoom * pParty->vPosition.y) >> 16),
+      uCenterX
+    + ((signed int)(((unsigned int)((unsigned __int64)((signed int)uZoom
+                                                     * (signed __int64)pIndoor->pVertices[pOutline->uVertex2ID].x) >> 16) << 16)
+                  - uZoom * pParty->vPosition.x) >> 16),
+      uCenterY
+    - ((signed int)(((unsigned int)((unsigned __int64)((signed int)uZoom
+                                                     * (signed __int64)pIndoor->pVertices[pOutline->uVertex2ID].y) >> 16) << 16)
+                  - uZoom * pParty->vPosition.y) >> 16),
+      ui_game_minimap_outline_color);
+  }
+  }
+
+
+  assert(pParty->sRotationY >= 0);
+  float angle = (pParty->sRotationY % 2048) / 2048.0f;
+  const float two_pi = 2.0f * 3.14159f;
+
+  uint arrow_idx = floorf(0.5f + 7 * angle);
+  pRenderer->DrawTextureTransparent(uCenterX - 3, uCenterY - 3, pIcons_LOD->GetTexture(pTextureIDs_pMapDirs[arrow_idx]));
+
+  //flagsb = TargetColor(0, 0, 255);
+  //v60 = TargetColor(255, 0, 0);
+  if (bWizardEyeActive)
+  {
+    //uZe = 0;
+    if (uWizardEyeSkillLevel >= 2)
+      for (uint i = 0; i < uNumSpriteObjects; ++i)
+    //if (uNumSpriteObjects > 0)
+      {
+        auto object = &pSpriteObjects[i];
+
+      //a2c = (char *)&pSpriteObjects[0].uObjectDescID;
+      //while ( 1 )
+      //{
+      if (!object->uType || !object->uObjectDescID)
+        continue;
+      //if (uWizardEyeSkillLevel == 1
+      v37 = uCenterX + ((unsigned __int64)((object->vPosition.x - pParty->vPosition.x) * (signed __int64)uZoom) >> 16);
+      //v79 = (unsigned __int64)((object->vPosition.y - pParty->vPosition.y) * (signed __int64)(signed int)uZoom) >> 16;
+      //v38 = uCenterY - v79;
+      v38 = uCenterY - ((signed __int64)((object->vPosition.y - pParty->vPosition.y) * (signed __int64)uZoom) >> 16);
+      if (v37 < pRenderer->raster_clip_x || v37 > pRenderer->raster_clip_z ||
+          v38 < pRenderer->raster_clip_y || v38 > pRenderer->raster_clip_w)
+        continue;
+
+      assert(uZoom >= 512);
+      if (pObjectList->pObjects[object->uObjectDescID].uFlags & OBJECT_DESC_UNPICKABLE)
+      {
+        pRenderer->RasterLine2D(v37, v38, v37, v38, ui_game_minimap_projectile_color);
+      }
+      else if (uZoom > 512)
+      {
+        pRenderer->RasterLine2D(v37 - 1, v38 - 1, v37 - 1, v38 + 1, ui_game_minimap_treasure_color);
+        pRenderer->RasterLine2D(v37, v38 - 2, v37, v38 + 1, ui_game_minimap_treasure_color);
+        pRenderer->RasterLine2D(v37 + 1, v38 - 1, v37 + 1, v38 + 1, ui_game_minimap_treasure_color);
+        pRenderer->RasterLine2D(v37 - 2, v38, v37 - 2, v38 + 1, ui_game_minimap_treasure_color);
+        pRenderer->RasterLine2D(v37 + 2, v38,
+                                v37 + 2, v38 + 1, ui_game_minimap_treasure_color);
+      }
+      else
+      {
+        pRenderer->RasterLine2D(v37 - 1, v38 - 1,
+                                v37 - 1, v38, ui_game_minimap_treasure_color);
+        pRenderer->RasterLine2D(v37, v38 - 1,
+                                v37, v38, ui_game_minimap_treasure_color);
+      }
+//LABEL_82:
+//LABEL_83:
+        //++uZe;
+        //a2c += 112;
+        //if ( uZe >= (signed int)uNumSpriteObjects )
+        //{
+          //goto LABEL_85;
+        //}
+      //}
+    }
+
+
+LABEL_85:
+    //v63 = TargetColor(255, 0, 0);
+    //v61 = TargetColor(0, 255, 0);
+    //v65 = TargetColor(255, 255, 0);
+    uZf = 0;
+    if ( (signed int)uNumActors > 0 )
+    {
+      flagsc = pActors.data();//[0].uAIState;
+      do
+      {
+		v39 = flagsc->uAIState;
+		if ( flagsc->uAIState != 11 && v39 != 19 && (v39 == 5 || BYTE1(flagsc->uAttributes) & 0x80) )
+        {
+		  v40 = ((unsigned __int64)(( flagsc->vPosition.x - pParty->vPosition.x)
+                                  * (signed __int64)(signed int)uZoom) >> 16)
+              + uCenterX;
+          v76 = (unsigned __int64)(( flagsc->vPosition.y - pParty->vPosition.y)
+                                 * (signed __int64)(signed int)uZoom) >> 16;
+          v41 = uCenterY - v76;
+          if ( v40 >= pRenderer->raster_clip_x )
+          {
+            if ( v40 <= pRenderer->raster_clip_z && v41 >= pRenderer->raster_clip_y && v41 <= pRenderer->raster_clip_w )
+            {
+              uWd = ui_game_minimap_actor_friendly_color;
+			  if ( BYTE3(flagsc->uAttributes) & 1 )
+                uWd = ui_game_minimap_actor_hostile_color;
+              if ( flagsc->uAIState == Dead)
+                uWd = ui_game_minimap_actor_corpse_color;
+              if ( (signed int)uZoom > 1024 )
+              {
+                pRenderer->RasterLine2D(v40 - 1, v41 - 2, v40 - 1, v41 + 2, uWd);
+                pRenderer->RasterLine2D(v40, v41 - 2, v40, v41 + 2, uWd);
+                pRenderer->RasterLine2D(v40 + 1, v41 - 2, v40 + 1, v41 + 2, uWd);
+                v42 = v41 + 1;
+                v43 = v41 - 1;
+                v44 = v42;
+                pRenderer->RasterLine2D(v40 - 2, v43, v40 - 2, v42, uWd);
+                v40 += 2;
+                v59 = uWd;
+                v56 = v44;
+                v54 = v40;
+                v52 = v43;
+              }
+              else
+              {
+                pRenderer->RasterLine2D(v40 - 1, v41 - 1, v40 - 1, uCenterY - v76, uWd);
+                v59 = uWd;
+                v56 = uCenterY - v76;
+                v54 = v40;
+                v52 = v41 - 1;
+              }
+              pRenderer->RasterLine2D(v40, v52, v54, v56, v59);
+            }
+          }
+        }
+        ++uZf;
+        ++flagsc;
+      }
+      while ( uZf < (signed int)uNumActors );
+    }
+  }
+
+
+  //flagsd = TargetColor(255, 255, 255);
+  uZg = 0;
+  if ( (signed int)uNumLevelDecorations > 0 )
+  {
+    v45 = (char *)&pLevelDecorations[0].vPosition;
+    lPitchb = (char *)&pLevelDecorations[0].vPosition;
+    do
+    {
+      if ( *(v45 - 2) & 8 )
+      {
+        v46 = ((unsigned __int64)((*(int *)v45 - pParty->vPosition.x) * (signed __int64)(signed int)uZoom) >> 16)
+            + uCenterX;
+        v77 = (unsigned __int64)((*((int *)v45 + 1) - pParty->vPosition.y) * (signed __int64)(signed int)uZoom) >> 16;
+        v47 = uCenterY - v77;
+        if ( v46 >= pRenderer->raster_clip_x )
+        {
+          if ( v46 <= pRenderer->raster_clip_z && v47 >= pRenderer->raster_clip_y && v47 <= pRenderer->raster_clip_w )
+          {
+            if ( (signed int)uZoom > 512 )
+            {
+              v48 = v47 + 1;
+              v49 = v47 - 1;
+              pRenderer->RasterLine2D(v46 - 1, v47 - 1, v46 - 1, v47 + 1, ui_game_minimap_decoration_color_1);
+              pRenderer->RasterLine2D(v46, v49, v46, v48, ui_game_minimap_decoration_color_1);
+              pRenderer->RasterLine2D(v46 + 1, v49, v46 + 1, v48, ui_game_minimap_decoration_color_1);
+              v45 = lPitchb;
+            }
+            else
+            {
+              pRenderer->RasterLine2D(v46, uCenterY - v77, v46, uCenterY - v77, ui_game_minimap_decoration_color_1);
+            }
+          }
+        }
+      }
+      ++uZg;
+      v45 += 32;
+      lPitchb = v45;
+    }
+    while ( uZg < (signed int)uNumLevelDecorations );
+  }
+  pRenderer->DrawTextureTransparent(0x1D4u, 0, pIcons_LOD->GetTexture(dword_5079D8));
+  uZooma = (double)pParty->sRotationY * 0.1171875;
+  //v50 = uZooma + 6.7553994e15;
+  pRenderer->SetTextureClipRect(541, 0, 567, 480);
+  pRenderer->DrawTextureIndexed(floorf(uZooma + 0.5f) + 285, 136, pIcons_LOD->GetTexture(dword_5079B4));
+  pRenderer->ResetTextureClipRect();
+}
+
+//----- (00441498) --------------------------------------------------------
+void __cdecl GameUI_DrawTorchlightAndWizardEye()
+    {
+    if (pCurrentScreen == SCREEN_GAME
+        || pCurrentScreen == SCREEN_MENU
+        || pCurrentScreen == SCREEN_OPTIONS
+        || pCurrentScreen == SCREEN_REST
+        || pCurrentScreen == SCREEN_SPELL_BOOK
+        || pCurrentScreen == SCREEN_CHEST
+        || pCurrentScreen == SCREEN_SAVEGAME
+        || pCurrentScreen == SCREEN_LOADGAME
+        || pCurrentScreen == SCREEN_CHEST_INVENTORY
+        || pCurrentScreen == SCREEN_BOOKS
+        || pCurrentScreen == SCREEN_BRANCHLESS_NPC_DIALOG )
+        {
+        if (pParty->TorchlightActive())
+            {
+            auto icon = pIconsFrameTable->GetFrame((signed __int16)pUIAnum_Torchlight->uIconID, pEventTimer->Time());
+            pRenderer->DrawTextureTransparent(pUIAnum_Torchlight->x, pUIAnum_Torchlight->y, pIcons_LOD->GetTexture(icon->uTextureID));
+            }
+        if (pParty->WizardEyeActive())
+            {
+            auto icon = pIconsFrameTable->GetFrame((signed __int16)pUIAnim_WizardEye->uIconID, pEventTimer->Time());
+            pRenderer->DrawTextureTransparent(pUIAnim_WizardEye->x, pUIAnim_WizardEye->y, pIcons_LOD->GetTexture(icon->uTextureID));
+            }
+        }
+    }
+// 4E28F8: using guessed type int pCurrentScreen;
+
+
+//----- (00491F87) --------------------------------------------------------
+void GameUI_DrawHiredNPCs()
+{
+  //int v6; // eax@15
+  char v7; // al@17
+  unsigned int v8; // eax@18
+  int v9; // esi@18
+  int v10; // eax@18
+  unsigned int v11; // eax@19
+  unsigned int v12; // esi@19
+  unsigned int v13; // eax@23
+  IconFrame *v14; // eax@24
+  unsigned int v15; // eax@26
+  char pContainer[20]; // [sp+Ch] [bp-30h]@18
+  unsigned int v17; // [sp+20h] [bp-1Ch]@19
+  signed int uFrameID; // [sp+24h] [bp-18h]@19
+  //int i; // [sp+28h] [bp-14h]@15
+  unsigned int v20; // [sp+2Ch] [bp-10h]@20
+  unsigned int v21; // [sp+30h] [bp-Ch]@19
+  int v22; // [sp+34h] [bp-8h]@2
+  unsigned __int8 v23; // [sp+3Bh] [bp-1h]@2
+
+  if ( bNoNPCHiring != 1 )
+  {
+    v23 = 0;
+    v22 = 0;
+    /*for (uint i = 0; i < 2; ++i)
+    { 
+      if (pParty->pHirelings[i].pName)
+        pTmpBuf[v22++] = i;
+    }*/
+    if (pParty->pHirelings[0].pName)
+      pTmpBuf[v22++] = 0;
+    if (pParty->pHirelings[1].pName)
+      pTmpBuf[v22++] = 1;
+
+    for (uint i = 0; i < pNPCStats->uNumNewNPCs; ++i)
+    {
+      if (pNPCStats->pNewNPCData[i].uFlags & 128)
+      {
+        if (!pParty->pHirelings[0].pName || strcmp(pNPCStats->pNewNPCData[i].pName, pParty->pHirelings[0].pName))
+        {
+          if (!pParty->pHirelings[1].pName || strcmp(pNPCStats->pNewNPCData[i].pName, pParty->pHirelings[1].pName))
+            pTmpBuf[v22++] = i + 2;
+        }
+      }
+    }
+
+    //v6 = (unsigned __int8)pParty->field_709;
+	for ( int i = (unsigned __int8)pParty->field_709; i < v22 && v23 < 2; i++ )
+    {
+      v7 = pTmpBuf[i];
+      if ( (unsigned __int8)v7 >= 2 )
+      {
+        sprintf(pContainer, "NPC%03d", pNPCStats->pNPCData[(unsigned __int8)v7 + 499].uPortraitID);
+        v15 = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+        pRenderer->DrawTextureIndexed(pHiredNPCsIconsOffsetsX[v23], pHiredNPCsIconsOffsetsY[v23], pIcons_LOD->GetTexture(v15));
+      }
+      else
+      {
+        sprintf(pContainer, "NPC%03d", pParty->pHirelings[(unsigned __int8)v7].uPortraitID);
+        v8 = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
+        v9 = v23;
+        pRenderer->DrawTextureIndexed(pHiredNPCsIconsOffsetsX[v9], pHiredNPCsIconsOffsetsY[v9], pIcons_LOD->GetTexture(v8));
+        v10 = (unsigned __int8)pTmpBuf[i];
+        if ( pParty->pHirelings[v10].evt_A == 1 )
+        {
+          uFrameID = pParty->pHirelings[v10].evt_B;
+          v11 = pHiredNPCsIconsOffsetsX[v9];
+          v12 = pHiredNPCsIconsOffsetsY[v9];
+          v17 = v11;
+          v21 = 0;
+          if ( (signed int)pIconsFrameTable->uNumIcons <= 0 )
+          {
+LABEL_23:
+            v13 = 0;
+          }
+          else
+          {
+            v20 = 0;
+            while ( _stricmp("spell96", pIconsFrameTable->pIcons[v20 / 0x20].pAnimationName) )
+            {
+              ++v21;
+              v20 += 32;
+              if ( (signed int)v21 >= (signed int)pIconsFrameTable->uNumIcons )
+                goto LABEL_23;
+            }
+            v13 = v21;
+          }
+          v14 = pIconsFrameTable->GetFrame(v13, uFrameID);
+          pRenderer->DrawTextureTransparent(v17, v12, &pIcons_LOD->pTextures[v14->uTextureID]);
+        }
+      }
+      ++v23;
+    }
+  }
+}
+// 6BE3C5: using guessed type char bNoNPCHiring;
+
+//----- (004178FE) --------------------------------------------------------
+unsigned int __fastcall UI_GetHealthManaStringColor(signed int a1, signed int a2)
+{
+  unsigned __int16 v2; // dx@2
+  unsigned __int16 v3; // cx@2
+  int v5; // eax@5
+  unsigned __int16 v6; // [sp-4h] [bp-8h]@2
+
+  if ( a1 <= a2 )
+  {
+    if ( a1 == a2 )
+      return 0;
+    v5 = 100 * a1 / a2;
+    v3 = 255;
+    if ( v5 >= 25 )
+    {
+      v6 = 100;
+      v2 = 255;
+    }
+    else
+    {
+      v6 = 0;
+      v2 = 0;
+    }
+  }
+  else
+  {
+    v6 = 0;
+    v2 = 255;
+    v3 = 0;
+  }
+  return TargetColor(v3, v2, v6);
+}
+
+//----- (00417939) --------------------------------------------------------
+signed int __thiscall GetConditionDrawColor(unsigned int uConditionIdx)
+{
+  unsigned int v1; // ebx@1
+  signed int v2; // edi@1
+  unsigned int v3; // esi@1
+  unsigned int v4; // eax@1
+  unsigned int v6; // [sp+Ch] [bp-4h]@1
+
+  v1 = uConditionIdx;
+  v2 = 65535;
+  v3 = TargetColor(0xE1u, 0xCDu, 0x23u);
+  v6 = TargetColor(0xFFu, 0x23u, 0);
+  v4 = TargetColor(0, 0xFFu, 0);
+  switch ( v1 )
+  {
+    case 0u:
+    case 1u:
+    case 3u:
+    case 4u:
+    case 5u:
+    case 6u:
+    case 7u:
+      v2 = v4;
+      break;
+    case 2u:
+    case 8u:
+    case 9u:
+    case 0xCu:
+    case 0xDu:
+      v2 = v3;
+      break;
+    case 0xAu:
+    case 0xBu:
+    case 0xEu:
+    case 0xFu:
+    case 0x10u:
+      v2 = v6;
+      break;
+    default:
+      return v2;
+  }
+  return v2;
+}
--- a/UICharacter.cpp	Sun Jun 23 14:27:32 2013 +0600
+++ b/UICharacter.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -25,8 +25,8 @@
 #include "texts.h"
 
 #include "mm7_data.h"
-
-
+#include "Mouse.h"
+#include "Allocator.h"
 
 
 int bRingsShownInCharScreen; // 5118E0
@@ -2630,3 +2630,496 @@
         IsPlayerWearingWatersuit[uPlayerID] = 0;
         }
     }
+//----- (00468F8A) --------------------------------------------------------
+void __cdecl OnPaperdollLeftClick()
+{
+  int v1; // ecx@1
+  unsigned int v2; // edi@1
+  unsigned int v3; // edx@4
+  unsigned int pSkillType; // esi@5
+  unsigned __int16 v5; // ax@7
+  unsigned int v6; // edi@19
+  int v7; // esi@27
+  unsigned int v8; // eax@29
+  int v9; // edx@32
+  int v10; // esi@34
+  int v11; // eax@34
+  int v12; // esi@38
+  int v13; // eax@38
+  char v14; // zf@38
+  int v15; // esi@42
+  int v16; // eax@42
+  int v17; // eax@44
+  unsigned int v18; // ecx@55
+  unsigned int v19; // eax@55
+  int v20; // esi@60
+  int v21; // eax@60
+  unsigned int v22; // eax@61
+  unsigned int v23; // eax@62
+  int v24; // esi@65
+  int v25; // eax@65
+  unsigned int v26; // eax@69
+  int v27; // esi@81
+  int v28; // eax@81
+  int v29; // esi@84
+  int v30; // eax@84
+  int v31; // eax@85
+  unsigned int v32; // ecx@88
+  unsigned int v33; // eax@88
+  int v34; // esi@90
+  unsigned int v35; // eax@91
+  int v36; // esi@93
+  int v37; // edi@93
+  ItemGen *v38; // edi@93
+  __int16 v39; // dx@99
+  ItemGen _this; // [sp+Ch] [bp-40h]@1
+  unsigned int v48; // [sp+30h] [bp-1Ch]@88
+  unsigned int v49; // [sp+34h] [bp-18h]@57
+  unsigned int v50; // [sp+38h] [bp-14h]@50
+  int v51; // [sp+3Ch] [bp-10h]@1
+  unsigned int v52; // [sp+40h] [bp-Ch]@5
+  //int v53; // [sp+44h] [bp-8h]@1
+  //unsigned int v54; // [sp+48h] [bp-4h]@1
+
+  v51 = 0;
+  _this.Reset();
+  //v0 = pPlayers[uActiveCharacter];
+  v1 = pPlayers[uActiveCharacter]->pEquipment.uMainHand;
+  v2 = pPlayers[uActiveCharacter]->pEquipment.uShield;
+  //v54 = pPlayers[uActiveCharacter]->pEquipment.uShield;
+  //v53 = v1;
+  if ( v1 && pItemsTable->pItems[*(int *)&pPlayers[uActiveCharacter]->pInventoryItems[v1 - 1]].uEquipType == 1 )
+    v51 = v1;
+  v3 = pParty->pPickedItem.uItemID;
+  if ( pParty->pPickedItem.uItemID )
+  {
+    v52 = pItemsTable->pItems[pParty->pPickedItem.uItemID].uEquipType;
+    pSkillType = pItemsTable->pItems[pParty->pPickedItem.uItemID].uSkillType;
+    if ( pSkillType == 4 )
+    {
+      if ( v2 )
+      {
+        LOBYTE(v5) = pPlayers[uActiveCharacter]->GetActualSkillLevel(PLAYER_SKILL_SPEAR);
+        if ( (signed int)SkillToMastery(v5) < 3 )
+        {
+          pPlayers[uActiveCharacter]->PlaySound(SPEECH_39, 0);
+          return;
+        }
+        v3 = pParty->pPickedItem.uItemID;
+      }
+    }
+    else
+    {
+      if ( (pSkillType == 8 || pSkillType == 1 || pSkillType == 2)
+        && v1
+        && pItemsTable->pItems[*(int *)&pPlayers[uActiveCharacter]->pInventoryItems[v1-1]].uSkillType == 4 )
+	  {
+        LOBYTE(v5) = pPlayers[uActiveCharacter]->GetActualSkillLevel(PLAYER_SKILL_SPEAR);
+        if ( (signed int)SkillToMastery(v5) < 3 )
+        {
+          pPlayers[uActiveCharacter]->PlaySound(SPEECH_39, 0);
+          return;
+        }
+	  }
+    }
+    if ( !pPlayers[uActiveCharacter]->CanEquip_RaceAndAlignmentCheck(v3) )
+    {
+
+        pPlayers[uActiveCharacter]->PlaySound(SPEECH_39, 0);
+        return;
+    }
+    if ( pParty->pPickedItem.uItemID == 604 )
+    {
+      pPlayers[uActiveCharacter]->EquipBody((ITEM_EQUIP_TYPE)3);
+      WetsuitOn(uActiveCharacter);
+      return;
+    }
+    v6 = v52;
+    switch ( v52 )
+    {
+      case 2u:
+      case 3u:
+      case 5u:
+      case 6u:
+      case 7u:
+      case 8u:
+      case 9u:
+      case 0xBu:
+        if ( !pPlayers[uActiveCharacter]->HasSkill(pSkillType) )
+        {
+          pPlayers[uActiveCharacter]->PlaySound(SPEECH_39, 0);
+          return;
+        }
+        if ( sub_43EE77_ProbablyIfUnderwaterSuitIsEquipped(uActiveCharacter) && (v6 != 3 || bUnderwater) )
+		{
+			pAudioPlayer->PlaySound(SOUND_27, 0, 0, -1, 0, 0, 0, 0);
+			return;
+		}
+        pPlayers[uActiveCharacter]->EquipBody((ITEM_EQUIP_TYPE)v6);
+        if ( pParty->pPickedItem.uItemID == 604 )
+          WetsuitOff(uActiveCharacter);
+        return;
+      case 0xAu:
+        if ( sub_43EE77_ProbablyIfUnderwaterSuitIsEquipped(uActiveCharacter) )
+		{
+			pAudioPlayer->PlaySound(SOUND_27, 0, 0, -1, 0, 0, 0, 0);
+			return;
+		}
+        v52 = 10;
+        v7 = (int)&pPlayers[uActiveCharacter]->pEquipment.uRings;
+        while ( 1 )
+        {
+          if ( !*(int *)v7 )
+          {
+            v8 = pPlayers[uActiveCharacter]->FindFreeInventorySlot();
+            if ( (v8 & 0x80000000u) == 0 )
+			{
+			  v9 = v52;
+			  pParty->pPickedItem.uBodyAnchor = v52 + 1;
+			  memcpy(&pPlayers[uActiveCharacter]->pInventoryItems[v8], &pParty->pPickedItem, sizeof(pPlayers[uActiveCharacter]->pInventoryItems[v8]));
+			  *(&pPlayers[uActiveCharacter]->pEquipment.uShield + v9) = v8 + 1;
+			  pMouse->RemoveHoldingItem();
+              break;
+			}
+          }
+          ++v52;
+          v7 += 4;
+          if ( (signed int)v52 > 15 )
+            break;
+        }
+        if ( v52 == 16 )
+        {
+          v52 = pPlayers[uActiveCharacter]->pEquipment.uRings[6] - 1;
+          memcpy(&_this, &pParty->pPickedItem, sizeof(_this));
+          v10 = (int)((char *)pPlayers[uActiveCharacter] + 36 * v52);
+          *(char *)(v10 + 556) = 0;
+          pParty->pPickedItem.Reset();
+          pParty->SetHoldingItem((ItemGen *)(v10 + 532));
+          _this.uBodyAnchor = 16;
+          v11 = v52 + 1;
+          memcpy((void *)(v10 + 532), &_this, 0x24u);
+          pPlayers[uActiveCharacter]->pEquipment.uRings[6] = v11;
+        }
+        return;
+      case 4u:
+        if ( sub_43EE77_ProbablyIfUnderwaterSuitIsEquipped(uActiveCharacter) )
+		{
+			pAudioPlayer->PlaySound(SOUND_27, 0, 0, -1, 0, 0, 0, 0);
+			return;
+		}
+        if ( !pPlayers[uActiveCharacter]->HasSkill(pSkillType) )
+        {
+          pPlayers[uActiveCharacter]->PlaySound(SPEECH_39, 0);
+          return;
+        }
+        if ( v2 )
+        {
+          --v2;
+          memcpy(&_this, &pParty->pPickedItem, sizeof(_this));
+          v12 = (int)((char *)pPlayers[uActiveCharacter] + 36 * v2);
+          *(char *)(v12 + 556) = 0;
+          pParty->pPickedItem.Reset();
+          pParty->SetHoldingItem((ItemGen *)(v12 + 532));
+          _this.uBodyAnchor = 1;
+          v13 = v2 + 1;
+          v14 = v51 == 0;
+          memcpy((void *)(v12 + 532), &_this, 0x24u);
+          pPlayers[uActiveCharacter]->pEquipment.uShield = v13;
+          if ( v14 )
+            return;
+        }
+        else
+        {
+          v52 = pPlayers[uActiveCharacter]->FindFreeInventorySlot();
+          if ( (v52 & 0x80000000u) != 0 )
+            return;
+          if ( !v51 )
+          {
+            pParty->pPickedItem.uBodyAnchor = 1;
+            v17 = v52 + 1;
+            memcpy(&pPlayers[uActiveCharacter]->pInventoryItems[v52], &pParty->pPickedItem, sizeof(pPlayers[uActiveCharacter]->pInventoryItems[v52]));
+            pPlayers[uActiveCharacter]->pEquipment.uShield = v17;
+            pMouse->RemoveHoldingItem();
+	        return;
+          }
+          memcpy(&_this, &pParty->pPickedItem, sizeof(_this));
+          v15 = (int)((char *)pPlayers[uActiveCharacter] + 36 * (v1 - 1));
+          *(char *)(v15 + 556) = 0;
+          pParty->pPickedItem.Reset();
+          pParty->SetHoldingItem((ItemGen *)(v15 + 532));
+          _this.uBodyAnchor = 1;
+          v16 = v52 + 1;
+          memcpy(&pPlayers[uActiveCharacter]->pInventoryItems[v52], &_this, sizeof(pPlayers[uActiveCharacter]->pInventoryItems[v52]));
+          pPlayers[uActiveCharacter]->pEquipment.uShield = v16;
+        }
+        pPlayers[uActiveCharacter]->pEquipment.uMainHand = 0;
+        return;
+      case 0u:
+      case 0xCu:
+        if ( sub_43EE77_ProbablyIfUnderwaterSuitIsEquipped(uActiveCharacter)
+          && pParty->pPickedItem.uItemID != 64
+          && pParty->pPickedItem.uItemID != 65 )
+		{
+			pAudioPlayer->PlaySound(SOUND_27, 0, 0, -1, 0, 0, 0, 0);
+			return;
+		}
+        if ( !pPlayers[uActiveCharacter]->HasSkill(pSkillType) )
+        {
+          pPlayers[uActiveCharacter]->PlaySound(SPEECH_39, 0);
+          return;
+        }
+        v50 = 0;
+        if ( pSkillType == 2 && (unsigned __int16)(pPlayers[uActiveCharacter]->pActiveSkills[2] & 0xFFC0)
+          || pSkillType == 1 && (signed int)SkillToMastery(pPlayers[uActiveCharacter]->pActiveSkills[1]) >= 3 )
+        {
+
+            v18 = pMouse->uMouseClickX;
+            v19 = pMouse->uMouseClickY;
+
+          v49 = v19;
+          if ( (signed int)v18 >= 560 )
+          {
+            if ( !v51 )
+            {
+              if ( v2 )
+              {
+                --v2;
+                memcpy(&_this, &pParty->pPickedItem, sizeof(_this));
+                v20 = (int)((char *)pPlayers[uActiveCharacter] + 36 * v2);
+                *(char *)(v20 + 556) = 0;
+                pParty->pPickedItem.Reset();
+                pParty->SetHoldingItem((ItemGen *)(v20 + 532));
+                _this.uBodyAnchor = 1;
+                v21 = v2 + 1;
+                v14 = v52 == 12;
+                memcpy((void *)(v20 + 532), &_this, 0x24u);
+                pPlayers[uActiveCharacter]->pEquipment.uShield = v21;
+                if ( !v14 )
+                  return;
+                v22 = _this.uItemID;
+                v50 = v22;
+				if ( v50 )
+                {
+                __debugbreak();  // looks like offset in player's inventory and wand_lut much like case in 0042ECB5
+				  stru_A750F8[uActiveCharacter - 1]._494836(*((int *)&pSpellDatas[66].uNormalLevelRecovery + v50), uActiveCharacter - 1 + 9);
+                }
+				break;
+              }
+              v23 = pPlayers[uActiveCharacter]->FindFreeInventorySlot();
+              if ( (v23 & 0x80000000u) != 0 )
+                return;
+              pParty->pPickedItem.uBodyAnchor = 1;
+              v50 = (unsigned int)&pPlayers[uActiveCharacter]->pInventoryItems[v23];
+              memcpy(&pPlayers[uActiveCharacter]->pInventoryItems[v23], &pParty->pPickedItem, sizeof(pPlayers[uActiveCharacter]->pInventoryItems[v23]));
+              pPlayers[uActiveCharacter]->pEquipment.uShield = v23 + 1;
+              pMouse->RemoveHoldingItem();
+              if ( v52 != 12 )
+                return;
+              v22 = *(int *)v50;
+			  v50 = v22;
+			  if ( v50 )
+              {
+                __debugbreak();  // looks like offset in player's inventory and wand_lut much like case in 0042ECB5
+				stru_A750F8[uActiveCharacter - 1]._494836(*((int *)&pSpellDatas[66].uNormalLevelRecovery + v50), uActiveCharacter - 1 + 9);
+              }
+			  break;
+            }
+          }
+        }
+        if ( !v1 )
+        {
+          v26 = pPlayers[uActiveCharacter]->FindFreeInventorySlot();
+          if ( (v26 & 0x80000000u) != 0 )
+            return;
+          pParty->pPickedItem.uBodyAnchor = 2;
+          v50 = (unsigned int)&pPlayers[uActiveCharacter]->pInventoryItems[v26];
+          memcpy(&pPlayers[uActiveCharacter]->pInventoryItems[v26], &pParty->pPickedItem, sizeof(pPlayers[uActiveCharacter]->pInventoryItems[v26]));
+          pPlayers[uActiveCharacter]->pEquipment.uMainHand = v26 + 1;
+              pMouse->RemoveHoldingItem();
+              if ( v52 != 12 )
+                return;
+              v22 = *(int *)v50;
+			  v50 = v22;
+			  if ( v50 )
+              {
+                __debugbreak();  // looks like offset in player's inventory and wand_lut much like case in 0042ECB5
+				stru_A750F8[uActiveCharacter - 1]._494836(*((int *)&pSpellDatas[66].uNormalLevelRecovery + v50), uActiveCharacter - 1 + 9);
+              }
+			  break;
+        }
+        --v1;
+        memcpy(&_this, &pParty->pPickedItem, sizeof(_this));
+        v24 = (int)((char *)pPlayers[uActiveCharacter] + 36 * v1);
+        *(char *)(v24 + 556) = 0;
+        pParty->pPickedItem.Reset();
+        pParty->SetHoldingItem((ItemGen *)(v24 + 532));
+        _this.uBodyAnchor = 2;
+        v25 = v1 + 1;
+        v14 = v52 == 12;
+        memcpy((void *)(v24 + 532), &_this, 0x24u);
+        pPlayers[uActiveCharacter]->pEquipment.uMainHand = v25;
+        if ( v14 )
+          v50 = _this.uItemID;
+        if ( v51 )
+          pPlayers[uActiveCharacter]->pEquipment.uShield = 0;
+        if ( v50 )
+        {
+                __debugbreak();  // looks like offset in player's inventory and wand_lut much like case in 0042ECB5
+          stru_A750F8[uActiveCharacter - 1]._494836( *((int *)&pSpellDatas[66].uNormalLevelRecovery + v50), uActiveCharacter - 1 + 9);
+        }
+        break;
+      case 1u:
+        if ( sub_43EE77_ProbablyIfUnderwaterSuitIsEquipped(uActiveCharacter) )
+		{
+			pAudioPlayer->PlaySound(SOUND_27, 0, 0, -1, 0, 0, 0, 0);
+			return;
+		}
+        if ( !pPlayers[uActiveCharacter]->HasSkill(pSkillType) )
+        {
+          pPlayers[uActiveCharacter]->PlaySound(SPEECH_39, 0);
+          return;
+        }
+        if ( v1 )
+        {
+          if ( v2 )
+          {
+			pAudioPlayer->PlaySound(SOUND_27, 0, 0, -1, 0, 0, 0, 0);
+			return;
+          }
+          --v1;
+          memcpy(&_this, &pParty->pPickedItem, sizeof(_this));
+          v27 = (int)((char *)pPlayers[uActiveCharacter] + 36 * v1);
+          *(char *)(v27 + 556) = 0;
+          pParty->pPickedItem.Reset();
+          pParty->SetHoldingItem((ItemGen *)(v27 + 532));
+          _this.uBodyAnchor = 2;
+          v28 = v1 + 1;
+          memcpy((void *)(v27 + 532), &_this, 0x24u);
+          pPlayers[uActiveCharacter]->pEquipment.uMainHand = v28;
+        }
+        else
+        {
+          v52 = pPlayers[uActiveCharacter]->FindFreeInventorySlot();
+          if ( (v52 & 0x80000000u) == 0 )
+          {
+            if ( v2 )
+            {
+              memcpy(&_this, &pParty->pPickedItem, sizeof(_this));
+              v29 = (int)((char *)pPlayers[uActiveCharacter] + 36 * (v2 - 1));
+              *(char *)(v29 + 556) = 0;
+              pParty->pPickedItem.Reset();
+              pParty->SetHoldingItem((ItemGen *)(v29 + 532));
+              _this.uBodyAnchor = 2;
+              v30 = v52 + 1;
+              memcpy(&pPlayers[uActiveCharacter]->pInventoryItems[v52], &_this, sizeof(pPlayers[uActiveCharacter]->pInventoryItems[v52]));
+              pPlayers[uActiveCharacter]->pEquipment.uShield = 0;
+              pPlayers[uActiveCharacter]->pEquipment.uMainHand = v30;
+            }
+            else
+            {
+              pParty->pPickedItem.uBodyAnchor = 2;
+              v31 = v52 + 1;
+              memcpy(&pPlayers[uActiveCharacter]->pInventoryItems[v52], &pParty->pPickedItem, sizeof(pPlayers[uActiveCharacter]->pInventoryItems[v52]));
+              pPlayers[uActiveCharacter]->pEquipment.uMainHand = v31;
+              pMouse->RemoveHoldingItem();
+            }
+          }
+        }
+        return;
+      default:
+        pPlayers[uActiveCharacter]->UseItem_DrinkPotion_etc(uActiveCharacter, 0);
+        return;
+    }
+    return;
+  }
+
+    v32 = pMouse->uMouseClickX;
+    v33 = pMouse->uMouseClickY;
+
+  v34 = pRenderer->pActiveZBuffer[v32 + pSRZBufferLineOffsets[v33]] & 0xFFFF;
+  if ( v34 )
+  {
+    v36 = v34 - 1;
+    v37 = (int)((char *)pPlayers[uActiveCharacter] + 36 * v36);
+    v50 = v37;
+    v38 = (ItemGen *)(v37 + 532);
+    v14 = v38->uItemID == 604;
+    v52 = pItemsTable->pItems[v38->uItemID].uEquipType;
+    if ( v14 )
+    {
+      if ( bUnderwater )
+      {
+        pAudioPlayer->PlaySound(SOUND_27, 0, 0, -1, 0, 0, 0, 0);
+        return;
+      }
+      WetsuitOff(uActiveCharacter);
+    }
+    if ( unk_50C9A0 )
+    {
+      *((char *)pGUIWindow_Settings->ptr_1C + 8) &= 0x7Fu;
+      *((short *)pGUIWindow_Settings->ptr_1C + 2) = uActiveCharacter - 1;
+      v39 = v52;
+      *((int *)pGUIWindow_Settings->ptr_1C + 3) = v36;
+      *((short *)pGUIWindow_Settings->ptr_1C + 3) = v39;
+      ptr_50C9A4 = v38;
+      unk_50C9A0 = 0;
+      if ( pMessageQueue_50CBD0->uNumMessages )
+        pMessageQueue_50CBD0->uNumMessages = pMessageQueue_50CBD0->pMessages[0].field_8 != 0;
+      pMouse->SetCursorBitmap("MICON1");
+      dword_50C9D4 = 0;
+      dword_50C9D0 = 113;
+      dword_50C9D8 = 256;
+    }
+    else
+    {
+      if ( !ptr_50C9A4 )
+      {
+        pParty->SetHoldingItem(v38);
+        *(&pPlayers[uActiveCharacter]->uBirthYear + *(char *)(v50 + 556)) = 0;
+        v38->Reset();
+      }
+    }
+  }
+  else
+  {
+    v35 = pPlayers[uActiveCharacter]->pEquipment.uBow;
+    if ( v35 )
+    {
+      auto _a = (ItemGen *)&pPlayers[uActiveCharacter]->pInventoryItems[v35 - 1];
+      pParty->SetHoldingItem(_a);
+      _a->Reset();
+      pPlayers[uActiveCharacter]->pEquipment.uBow = 0;
+    }
+  }
+}
+//----- (004196A0) --------------------------------------------------------
+void CharacterUI_ReleaseButtons()
+{
+  GUIButton *i; // esi@2
+  GUIButton *j; // esi@7
+
+  if ( dword_507CC0_activ_ch )
+  {
+    dword_507CC0_activ_ch = 0;
+    for ( i = pGUIWindow_CurrentMenu->pControlsHead; i; i = j )
+    {
+	  j=i->pNext;
+	  if ( BYTE1(i->field_1C) & 0x80 )
+	  {
+        i->Release();
+		pAllocator->FreeChunk(i);
+	  }
+    }
+    for ( j = pGUIWindow_CurrentMenu->pControlsHead; j; j = j->pNext )
+    {
+      if ( j->msg == UIMSG_InventoryLeftClick)
+      {
+        j->uX = dword_50698C_uX;
+        j->uY = dword_506988_uY;
+        j->uZ = dword_506984_uZ;
+        j->uW = dword_506980_uW;
+        pGUIWindow_CurrentMenu->_41D08F_set_keyboard_control_group(1, 0, 0, 0);
+      }
+    }
+  }
+}
\ No newline at end of file
--- a/UIHouses.cpp	Sun Jun 23 14:27:32 2013 +0600
+++ b/UIHouses.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -6256,42 +6256,479 @@
   }
   return;
 }
-//----- (004BC8D5) --------------------------------------------------------
-void SpellBookGenerator()//for GuildDialogs
+//----- (004B1A2D) --------------------------------------------------------
+void __cdecl ShowPopupShopItem()
 {
-  int pItemNum; // esi@1
-  int v4; // esi@7
+  POINT *v1; // esi@5
+  unsigned int v2; // eax@5
+  int v3; // ecx@5
+  POINT *v4; // esi@12
+  int v5; // eax@12
+  unsigned int v6; // eax@13
+  ItemGen *v7; // ecx@13
+  signed int v8; // esi@17
+  unsigned int v9; // eax@19
+  POINT v10; // [sp+8h] [bp-44h]@12
+  POINT v11; // [sp+10h] [bp-3Ch]@12
+  POINT  v12; // [sp+18h] [bp-34h]@18
+  POINT  v13; // [sp+20h] [bp-2Ch]@17
+  POINT v14; // [sp+28h] [bp-24h]@17
+  POINT  v15; // [sp+30h] [bp-1Ch]@17
+  POINT v16; // [sp+38h] [bp-14h]@5
+  POINT a2; // [sp+40h] [bp-Ch]@5
 
-  for( int i = 0; i < 12; ++i )
+  if ( in_current_building_type <= 0 )
+    return;
+  if ( in_current_building_type <= BildingType_AlchemistShop )
   {
-    if ( p2DEvents[window_SpeakInHouse->par1C - 1].uType >= 5 )
+    if ( dialog_menu_id != HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
     {
-      if ( p2DEvents[window_SpeakInHouse->par1C - 1].uType <= 13 )
-        pItemNum = rand() % word_4F0F30[(signed int)window_SpeakInHouse->par1C - 139] + 11 * p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].uType + 345;
+      if ( dialog_menu_id <= HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
+        return;
+      if ( dialog_menu_id <= HOUSE_DIALOGUE_SHOP_REPAIR || dialog_menu_id == HOUSE_DIALOGUE_SHOP_DISPLAY_EQUIPMENT )
+      {
+        v8 = pMouse->GetCursorPos(&v15)->x - 14;
+        v5 = (v8 >> 5) + 14 * ((pMouse->GetCursorPos(&v14)->y - 17) >> 5);
+        if ( pMouse->GetCursorPos(&v13)->x <= 13
+          || pMouse->GetCursorPos(&v12)->x >= 462
+          || (v9 = pPlayers[uActiveCharacter]->GetItemIDAtInventoryIndex(&v5)) == 0 )
+          return;
+        GameUI_DrawItemInfo(&pPlayers[uActiveCharacter]->pInventoryItems[v9 - 1]);
+        return;
+      }
+      if ( dialog_menu_id != HOUSE_DIALOGUE_SHOP_BUY_SPECIAL )
+        return;
+    }
+    v4 = pMouse->GetCursorPos(&v11);
+    v5 = pRenderer->pActiveZBuffer[v4->x + pSRZBufferLineOffsets[pMouse->GetCursorPos(&v10)->y]] & 0xFFFF;
+    if ( !v5 )
+      return;
+    v6 = 9 * (v5 + 12 * (unsigned int)window_SpeakInHouse->ptr_1C);
+    v7 = (ItemGen *)((char *)&pParty->pPickedItem + 4 * v6 + 4);
+    if ( dialog_menu_id != HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
+      v7 = &pParty->SpecialItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][v5 - 1];
+    GameUI_DrawItemInfo(v7);
+    return;
+  }
+  if ( in_current_building_type <= BildingType_16 && dialog_menu_id == HOUSE_DIALOGUE_GUILD_BUY_BOOKS )
+  {
+    v1 = pMouse->GetCursorPos(&a2);
+    v2 = v1->x + pSRZBufferLineOffsets[pMouse->GetCursorPos(&v16)->y];
+    v3 = pRenderer->pActiveZBuffer[v2] & 0xFFFF;
+    v5 = pRenderer->pActiveZBuffer[v2] & 0xFFFF;
+    if ( v5 )
+      sub_4B1523((int *)&pParty->pPlayers[1].uExpressionTimeLength + 9 * (v3 + 12 * (unsigned int)window_SpeakInHouse->ptr_1C));
+  }
+}
+//----- (004B1D27) --------------------------------------------------------
+void __cdecl sub_4B1D27()
+{
+  int v0; // edx@2
+  unsigned int v1; // ecx@7
+  signed int v2; // edi@10
+  int v3; // esi@10
+  __int16 v4; // ax@15
+  signed int v5; // edi@20
+  int v6; // esi@20
+  int v7[4]; // [sp+Ch] [bp-10h]@12
+
+  if ( in_current_building_type > 0 )
+  {
+    v0 = 3;
+    if ( in_current_building_type > BildingType_MagicShop )
+    {
+      if ( in_current_building_type == BildingType_Bank )
+      {
+        if ( !dword_F8B1E4 )
+          return;
+      }
       else
       {
-        if ( p2DEvents[window_SpeakInHouse->par1C - 1].uType == 14 )
-          v4 = rand() % 4;
-        else if ( p2DEvents[window_SpeakInHouse->par1C - 1].uType == 15 )
-          v4 = rand() % 3 + 4;
-        else if ( p2DEvents[window_SpeakInHouse->par1C - 1].uType == 16 )
-          v4 = rand() % 2 + 7;
-        if( p2DEvents[window_SpeakInHouse->par1C - 1].uType <= 16 )
-          pItemNum = rand() % word_4F0F30[(signed int)window_SpeakInHouse->par1C - 139] + 11 * v4 + 400;
+        if ( in_current_building_type != BildingType_Temple )
+          return;
+      }
+      v1 = (unsigned int)window_SpeakInHouse->ptr_1C;
+      PlayHouseSound(v1, (HouseSoundID)v0);
+      return;
+    }
+    v1 = (unsigned int)window_SpeakInHouse->ptr_1C;
+    if ( (signed __int64)pParty->field_3C._shop_ban_times[v1 ]<= (signed __int64)pParty->uTimePlayed )
+    {
+      if ( pParty->uNumGold <= 0x2710 )
+      {
+        if ( !dword_F8B1E4 )
+          return;
+        v0 = 4;
+        PlayHouseSound(v1, (HouseSoundID)v0);
+        return;
+      }
+      PlayHouseSound(v1, (HouseSoundID)(dword_F8B1E4 + 3));
+      if ( !dword_F8B1E4 && !qword_A750D8 )
+      {
+        v5 = 0;
+        v6 = 1;
+        do
+        {
+          if ( pPlayers[v6]->CanAct() )
+            v7[v5++] = v6;
+          ++v6;
+        }
+        while ( v6 <= 4 );
+        if ( v5 )
+        {
+          qword_A750D8 = 256i64;
+          word_A750E0 = 80;
+          v4 = LOWORD(v7[rand() % v5]);
+          word_A750E2 = v4;
+          return;
+        }
+      }
+    }
+    else
+    {
+      if ( !qword_A750D8 )
+      {
+        v2 = 0;
+        v3 = 1;
+        do
+        {
+          if ( pPlayers[v3]->CanAct() )
+            v7[v2++] = v3;
+          ++v3;
+        }
+        while ( v3 <= 4 );
+        if ( v2 )
+        {
+          qword_A750D8 = 256i64;
+          word_A750E0 = 80;
+          v4 = LOWORD(v7[rand() % v2]);
+          word_A750E2 = v4;
+          return;
+        }
+      }
+    }
+  }
+}
+//----- (004B2A74) --------------------------------------------------------
+void SimpleHouseAndBoatsDialog()
+{
+  char *v0; // esi@3
+  char *v1; // ST1C_4@3
+  char *v2; // eax@3
+  const char *v3; // ST1C_4@5
+  int v4; // eax@5
+  unsigned int i; // eax@5
+  NPCData *v6; // esi@6
+  unsigned __int16 v7; // bx@6
+  unsigned int v8; // eax@6
+  int v9; // eax@11
+  unsigned int v10; // ecx@12
+  int v11; // eax@12
+  int v12; // esi@12
+  char *v13; // eax@12
+  GUIWindow *v14; // ebx@13
+  char *v15; // esi@14
+  GUIButton *v16; // eax@15
+  unsigned int v17; // ecx@15
+  int v18; // ecx@17
+  int v19; // ecx@18
+  int v20; // ecx@19
+  int v21; // ecx@20
+  int v22; // ecx@21
+  unsigned int v23; // ecx@23
+  int v24; // ecx@35
+  int v25; // ecx@36
+  int v26; // ecx@37
+  int v27; // ecx@38
+  int v28; // ecx@39
+  char *v29; // esi@42
+  unsigned int v30; // ST20_4@42
+  int v31; // ST1C_4@42
+  unsigned int v32; // eax@42
+  char *v33; // eax@43
+  int v34; // esi@51
+  int v35; // eax@51
+  unsigned int v36; // edi@51
+  GUIButton *v37; // eax@52
+  int v38; // eax@52
+  signed int v39; // ecx@54
+  int v40; // edi@57
+  GUIButton *v41; // eax@60
+  GUIButton *v42; // esi@60
+  const char *v43; // ebx@60
+  int v44; // eax@60
+  unsigned int v45; // ecx@60
+  unsigned __int16 v46; // ax@60
+  GUIFont *v47; // ebx@64
+  int v48; // esi@64
+  char *v49; // eax@66
+  GUIWindow w; // [sp+Ch] [bp-110h]@64
+  GUIWindow v52; // [sp+60h] [bp-BCh]@13
+  GUIWindow a1; // [sp+B4h] [bp-68h]@1
+  unsigned int v54; // [sp+108h] [bp-14h]@14
+  int v55; // [sp+10Ch] [bp-10h]@6
+  int v56; // [sp+110h] [bp-Ch]@13
+  char *pInString; // [sp+114h] [bp-8h]@12
+  NPCData *v58; // [sp+118h] [bp-4h]@6
+
+  memcpy(&a1, pDialogueWindow, sizeof(a1));
+  if ( pDialogueNPCCount == uNumDialogueNPCPortraits && uHouse_ExitPic )
+  {
+    v0 = pMapStats->pInfos[uHouse_ExitPic].pName;
+    v1 = pMapStats->pInfos[uHouse_ExitPic].pName;
+    a1.uFrameX = 493;
+    a1.uFrameWidth = 126;
+    a1.uFrameZ = 366;
+    a1.DrawTitleText(pFontCreate, 0, 2u, 0, v1, 3u);
+    a1.uFrameX = 483;
+    a1.uFrameWidth = 148;
+    a1.uFrameZ = 334;
+    v2 = pTransitionStrings[uHouse_ExitPic];
+    if ( !v2 )
+    {
+      sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[411], v0);
+      v2 = pTmpBuf.data();
+    }
+    v3 = v2;
+    v4 = pFontCreate->CalcTextHeight(v2, &a1, 0, 0);
+    a1.DrawTitleText(pFontCreate, 0, (212 - v4) / 2 + 101, 0, v3, 3u);
+    return;
+  }
+  a1.uFrameWidth -= 10;
+  a1.uFrameZ -= 10;
+  v58 = HouseNPCData[(unsigned int)((char *)pDialogueNPCCount + -(dword_591080 != 0) )];//- 1
+  v6 = v58;
+  v55 = TargetColor(0xE1u, 0xCDu, 0x23u);
+  v7 = TargetColor(0x15u, 0x99u, 0xE9u);
+  v8 = v6->uProfession;
+  if ( v8 )
+    sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[429], v6->pName, aNPCProfessionNames[v8]);
+  else
+    strcpy(pTmpBuf.data(), v6->pName);
+  a1.DrawTitleText(pFontCreate, 0x1E3u, 0x71u, v7, pTmpBuf.data(), 3u);
+  if ( !dword_591080 )
+  {
+    if ( !uDialogueType )
+    {
+      v9 = v6->greet;
+      if ( v9 )
+      {
+        v10 = v6->uFlags;
+        a1.uFrameWidth = game_viewport_width;
+        a1.uFrameZ = 452;
+        pInString = (char *)*(&pNPCStats->field_17884 + ((v10 & 3) == 2) + 2 * v9);
+        v11 = pFontArrus->CalcTextHeight(pInString, &a1, 13, 0);
+        v12 = v11 + 7;
+        pRenderer->_4A6A68(8, 352 - (v11 + 7),
+          pIcons_LOD->GetTexture(uTextureID_Leather),
+          pIcons_LOD->GetTexture(uTextureID_Leather)->uTextureHeight - (v11 + 7));
+        pRenderer->DrawTextureIndexed(8u, 347 - v12, pTexture_591428);
+        v13 = FitTextInAWindow(pInString, pFontArrus, &a1, 0xDu, 0);
+        pDialogueWindow->DrawText(pFontArrus, 13, 354 - v12, 0, v13, 0, 0, 0);
       }
     }
-    if ( pItemNum == 487 )
+  }
+  v14 = pDialogueWindow;
+  memcpy(&v52, pDialogueWindow, sizeof(v52));
+  v52.uFrameX = 483;
+  v52.uFrameWidth = 148;
+  v52.uFrameZ = 334;
+  v56 = v52.pStartingPosActiveItem;
+  if ( v52.pStartingPosActiveItem < v52.pStartingPosActiveItem + v52.pNumPresenceButton )
+  {
+    v15 = "";//(char *)v54;
+    while ( 1 )
     {
-      if ( !(unsigned __int16)_449B57_test_bit(pParty->_quest_bits, 239) )
-        pItemNum = 486;
+      v16 = v52.GetControl(v56);
+      v17 = v16->msg_param;
+      pInString = (char *)v16;
+      if ( (signed int)v17 > 24 )
+      {
+        v24 = v17 - 76;
+        if ( !v24 )
+        {
+          v15 = pGlobalTXT_LocalizationStrings[406];
+          goto LABEL_49;
+        }
+        v25 = v24 - 1;
+        if ( !v25 )
+        {
+          v15 = pGlobalTXT_LocalizationStrings[407];
+          goto LABEL_49;
+        }
+        v26 = v25 - 2;
+        if ( !v26 )
+        {
+          v33 = _4B254D_SkillMasteryTeacher((int)v52.ptr_1C);
+LABEL_44:
+          v15 = v33;
+LABEL_45:
+          v16 = (GUIButton *)pInString;
+          goto LABEL_49;
+        }
+        v27 = v26 - 3;
+        if ( !v27 )
+        {
+          v33 = (char *)ContractSelectText((int)v52.ptr_1C);
+          goto LABEL_44;
+        }
+        v28 = v27 - 1;
+        if ( !v28 )
+        {
+          v29 = (char *)&pMonsterStats + 88 * word_F8B1A0;
+          v30 = TargetColor(0xFFu, 0xFFu, 0xFFu);
+          v31 = *(int *)v29;
+          v32 = TargetColor(0xFFu, 0xFFu, 0x9Bu);
+          sprintfex(pTmpBuf.data(), "\f%05d%s\f%05d", v32, v31, v30);
+          sprintfex(pTmpBuf2.data(), dword_F8B1A4, pTmpBuf.data(), 100 * (unsigned __int8)v29[8]);
+          current_npc_text = pTmpBuf2.data();
+          v15 = "";
+          goto LABEL_45;
+        }
+        if ( v28 != 10 )
+          goto LABEL_41;
+      }
+      else
+      {
+        if ( v17 == 24 )
+        {
+          v23 = v58->evt_F;
+LABEL_33:
+          v15 = (char *)pNPCTopics[v23-1].pTopic;//(&dword_721660)[8 * v23];
+          if ( !v15 )
+          {
+            v16->msg_param = 0;
+            v15 = "";
+          }
+          goto LABEL_49;
+        }
+        v18 = v17 - 13;
+        if ( v18 )
+        {
+          v19 = v18 - 6;
+          if ( !v19 )
+          {
+            v23 = v58->evt_A;
+            goto LABEL_33;
+          }
+          v20 = v19 - 1;
+          if ( !v20 )
+          {
+            v15 = (char *)pNPCTopics[v58->evt_B-1].pTopic;//(&dword_721660)[8 * v58->evtb];
+            if ( !v15 )
+            {
+              v16->msg_param = 0;
+              v15 = "";
+            }
+            if ( uDialogueType != 84 )
+              goto LABEL_49;
+            sprintf(pTmpBuf.data(), format_4E2D80, v55, pItemsTable->pItems[contract_approved].pUnidentifiedName);
+            sprintf(pTmpBuf2.data(), current_npc_text, pTmpBuf.data());
+            current_npc_text = pTmpBuf2.data();
+            goto LABEL_45;
+          }
+          v21 = v20 - 1;
+          if ( !v21 )
+          {
+            v23 = v58->evt_C;
+            goto LABEL_33;
+          }
+          v22 = v21 - 1;
+          if ( !v22 )
+          {
+            v23 = v58->evt_D;
+            goto LABEL_33;
+          }
+          if ( v22 == 1 )
+          {
+            v23 = v58->evt_E;
+            goto LABEL_33;
+          }
+LABEL_41:
+          v15 = "";
+          goto LABEL_49;
+        }
+        v15 = pGlobalTXT_LocalizationStrings[122];
+      }
+LABEL_49:
+      strcpy(v16->pButtonName, v15);
+      ++v56;
+      if ( v56 >= v52.pStartingPosActiveItem + v52.pNumPresenceButton )
+      {
+        v14 = pDialogueWindow;
+        break;
+      }
     }
-    ItemGen * item_spellbook = &pParty->SpellBooksInGuilds[window_SpeakInHouse->par1C-139][i];
-    item_spellbook->Reset();
-    pParty->SpellBooksInGuilds[window_SpeakInHouse->par1C-139][i].uItemID = pItemNum;
-    pParty->SpellBooksInGuilds[window_SpeakInHouse->par1C-139][i].Identified();
-    ItemsInShopTexture[i] = pIcons_LOD->LoadTexturePtr(pItemsTable->pItems[pItemNum].pIconName, TEXTURE_16BIT_PALETTE);
+  }
+  v34 = 0;
+  v54 = TargetColor(0xFFu, 0xFFu, 0xFFu);
+  v35 = TargetColor(0xE1u, 0xCDu, 0x23u);
+  v36 = v14->pStartingPosActiveItem;
+  v55 = v35;
+  for ( i = v36 + v14->pNumPresenceButton; (signed int)v36 < (signed int)i; i = pDialogueWindow->pNumPresenceButton
+                                                                    + pDialogueWindow->pStartingPosActiveItem )
+  {
+    v37 = v14->GetControl(v36);
+    v38 = pFontArrus->CalcTextHeight(v37->pButtonName, &v52, 0, 0);
+    v14 = pDialogueWindow;
+    v34 += v38;
+    ++v36;
   }
-  return;
+  v39 = v14->pNumPresenceButton;
+  if ( v39 )
+  {
+    v58 = (NPCData *)((174 - v34) / v39);
+    if ( (signed int)v58 > 32 )
+      v58 = (NPCData *)32;
+    pInString = (char *)2;
+    v40 = (174 - (signed int)v58 * v39 - v34) / 2 - (signed int)v58 / 2 + 138;
+    v56 = v14->pStartingPosActiveItem;
+    i = v56;
+    if ( (signed int)i < (signed int)(i + v39) )
+    {
+      while ( 1 )
+      {
+        v41 = v14->GetControl(i);
+        v42 = v41;
+        v43 = v41->pButtonName;
+        v41->uY = (unsigned int)((char *)v58 + v40);
+        v44 = pFontArrus->CalcTextHeight(v41->pButtonName, &v52, 0, 0);
+        v45 = v42->uY;
+        v42->uHeight = v44;
+        v40 = v45 + v44 - 1;
+        v42->uW = v40;
+        v46 = v55;
+        if ( (char *)pDialogueWindow->pCurrentPosActiveItem != pInString )
+          v46 = v54;
+        v52.DrawTitleText(pFontArrus, 0, v45, v46, v43, 3u);
+        v14 = pDialogueWindow;
+        ++pInString;
+        ++v56;
+        i = pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem;
+        if ( v56 >= (signed int)i )
+          break;
+        i = v56;
+      }
+    }
+  }
+  if ( current_npc_text )
+  {
+    w.uFrameWidth = 458;
+    w.uFrameZ = 457;
+    v47 = pFontArrus;
+    v48 = pFontArrus->CalcTextHeight(current_npc_text, &w, 13, 0) + 7;
+    if ( 352 - v48 < 8 )
+    {
+      v47 = pFontCreate;
+      v48 = pFontCreate->CalcTextHeight(current_npc_text, &w, 13, 0) + 7;
+    }
+    pRenderer->_4A6A68(8, 352 - v48,
+      pIcons_LOD->GetTexture(uTextureID_Leather),
+      pIcons_LOD->GetTexture(uTextureID_Leather)->uTextureHeight - v48);
+    pRenderer->DrawTextureIndexed(8u, 347 - v48, pTexture_591428);
+    v49 = FitTextInAWindow(current_npc_text, v47, &w, 0xDu, 0);
+    a1.DrawText(v47, 13, 354 - v48, 0, v49, 0, 0, 0);
+  }
 }
 //----- (004BDB56) --------------------------------------------------------
 void __cdecl UIShop_Buy_Identify_Repair()
@@ -6581,4 +7018,41 @@
       break;
     }
   }
+}
+//----- (004BC8D5) --------------------------------------------------------
+void SpellBookGenerator()//for GuildDialogs
+{
+  int pItemNum; // esi@1
+  int v4; // esi@7
+
+  for( int i = 0; i < 12; ++i )
+  {
+    if ( p2DEvents[window_SpeakInHouse->par1C - 1].uType >= 5 )
+    {
+      if ( p2DEvents[window_SpeakInHouse->par1C - 1].uType <= 13 )
+        pItemNum = rand() % word_4F0F30[(signed int)window_SpeakInHouse->par1C - 139] + 11 * p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].uType + 345;
+      else
+      {
+        if ( p2DEvents[window_SpeakInHouse->par1C - 1].uType == 14 )
+          v4 = rand() % 4;
+        else if ( p2DEvents[window_SpeakInHouse->par1C - 1].uType == 15 )
+          v4 = rand() % 3 + 4;
+        else if ( p2DEvents[window_SpeakInHouse->par1C - 1].uType == 16 )
+          v4 = rand() % 2 + 7;
+        if( p2DEvents[window_SpeakInHouse->par1C - 1].uType <= 16 )
+          pItemNum = rand() % word_4F0F30[(signed int)window_SpeakInHouse->par1C - 139] + 11 * v4 + 400;
+      }
+    }
+    if ( pItemNum == 487 )
+    {
+      if ( !(unsigned __int16)_449B57_test_bit(pParty->_quest_bits, 239) )
+        pItemNum = 486;
+    }
+    ItemGen * item_spellbook = &pParty->SpellBooksInGuilds[window_SpeakInHouse->par1C-139][i];
+    item_spellbook->Reset();
+    pParty->SpellBooksInGuilds[window_SpeakInHouse->par1C-139][i].uItemID = pItemNum;
+    pParty->SpellBooksInGuilds[window_SpeakInHouse->par1C-139][i].Identified();
+    ItemsInShopTexture[i] = pIcons_LOD->LoadTexturePtr(pItemsTable->pItems[pItemNum].pIconName, TEXTURE_16BIT_PALETTE);
+  }
+  return;
 }
\ No newline at end of file
--- a/UiGame.cpp	Sun Jun 23 14:27:32 2013 +0600
+++ b/UiGame.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -2897,3 +2897,81 @@
 }
 // 6BE3C5: using guessed type char bNoNPCHiring;
 
+//----- (004178FE) --------------------------------------------------------
+unsigned int __fastcall UI_GetHealthManaStringColor(signed int a1, signed int a2)
+{
+  unsigned __int16 v2; // dx@2
+  unsigned __int16 v3; // cx@2
+  int v5; // eax@5
+  unsigned __int16 v6; // [sp-4h] [bp-8h]@2
+
+  if ( a1 <= a2 )
+  {
+    if ( a1 == a2 )
+      return 0;
+    v5 = 100 * a1 / a2;
+    v3 = 255;
+    if ( v5 >= 25 )
+    {
+      v6 = 100;
+      v2 = 255;
+    }
+    else
+    {
+      v6 = 0;
+      v2 = 0;
+    }
+  }
+  else
+  {
+    v6 = 0;
+    v2 = 255;
+    v3 = 0;
+  }
+  return TargetColor(v3, v2, v6);
+}
+
+//----- (00417939) --------------------------------------------------------
+signed int __thiscall GetConditionDrawColor(unsigned int uConditionIdx)
+{
+  unsigned int v1; // ebx@1
+  signed int v2; // edi@1
+  unsigned int v3; // esi@1
+  unsigned int v4; // eax@1
+  unsigned int v6; // [sp+Ch] [bp-4h]@1
+
+  v1 = uConditionIdx;
+  v2 = 65535;
+  v3 = TargetColor(0xE1u, 0xCDu, 0x23u);
+  v6 = TargetColor(0xFFu, 0x23u, 0);
+  v4 = TargetColor(0, 0xFFu, 0);
+  switch ( v1 )
+  {
+    case 0u:
+    case 1u:
+    case 3u:
+    case 4u:
+    case 5u:
+    case 6u:
+    case 7u:
+      v2 = v4;
+      break;
+    case 2u:
+    case 8u:
+    case 9u:
+    case 0xCu:
+    case 0xDu:
+      v2 = v3;
+      break;
+    case 0xAu:
+    case 0xBu:
+    case 0xEu:
+    case 0xFu:
+    case 0x10u:
+      v2 = v6;
+      break;
+    default:
+      return v2;
+  }
+  return v2;
+}
--- a/VideoPlayer.cpp	Sun Jun 23 14:27:32 2013 +0600
+++ b/VideoPlayer.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -20,7 +20,7 @@
 #include "Time.h"
 #include "Log.h"
 #include "texts.h"
-#include "UIHouses.h"
+#include "UI\UIHouses.h"
 
 
 VideoPlayer *pVideoPlayer = nullptr;
--- a/Viewport.cpp	Sun Jun 23 14:27:32 2013 +0600
+++ b/Viewport.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -4,6 +4,22 @@
 #include "Indoor.h"
 #include "Math.h"
 #include "mm7_data.h"
+#include "Actor.h"
+#include "Outdoor.h"
+#include "Events.h"
+#include "BSPModel.h"
+#include "Mouse.h"
+#include "SpriteObject.h"
+#include "ObjectList.h"
+#include "DecorationList.h"
+#include "texts.h"
+#include "Game.h"
+#include "Vis.h"
+#include "LOD.h"
+#include "GUIWindow.h"
+#include "TurnEngine.h"
+#include "stru123.h"
+#include "MM7.h"
 
 
 //----- (004C0262) --------------------------------------------------------
@@ -233,4 +249,268 @@
     field_28 = dword_576E28;
   }
   field_2C = 384;
-}
\ No newline at end of file
+}
+//----- (0042213C) --------------------------------------------------------
+void OnGameViewportClick()
+{
+  signed int v0; // ebx@2
+  POINT *v1; // esi@3
+  signed int v2; // eax@9
+  BLVFace *v3; // eax@10
+  unsigned int v4; // eax@11
+  unsigned __int16 v5; // dx@14
+  signed int v6; // eax@14
+  char *v7; // esi@15
+  //int *v8; // eax@19
+  int v9; // eax@19
+  unsigned int v10; // eax@19
+  int v11; // ecx@21
+  ODMFace *v12; // eax@22
+  LevelDecoration *v13; // esi@24
+  __int16 v14; // ax@25
+  int v15; // ecx@29
+  signed int v16; // edx@30
+  Actor *v17; // esi@30
+  int v18; // ebx@47
+  unsigned __int16 v19; // ax@50
+  const char *v20; // eax@51
+  signed int v21; // eax@58
+  ItemGen *v22; // esi@62
+  unsigned int v23; // eax@62
+  SpriteObject a1; // [sp+Ch] [bp-80h]@1
+  //POINT v25; // [sp+7Ch] [bp-10h]@3
+  POINT a2; // [sp+84h] [bp-8h]@3
+
+  v1 = pMouse->GetCursorPos(&a2);
+  if ( pRenderer->pRenderD3D )
+    v0 = pGame->pVisInstance->get_picked_object_zbuf_val();
+  else
+  {
+    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
+      && (unsigned int)v0 < 0x2000000 )
+    {
+      v22 = &pSpriteObjects[v21].stru_24;
+      v23 = pSpriteObjects[v21].stru_24.uItemID;
+      if ( pItemsTable->pItems[v23].uEquipType == 18 )
+      {
+        party_finds_gold(v22->uSpecEnchantmentType, 0);
+        viewparams->bRedrawGameUI = 1;
+      }
+      else
+      {
+        sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[471], pItemsTable->pItems[v23].pUnidentifiedName);
+        ShowStatusBarString(pTmpBuf2.data(), 2u);
+        if ( v22->uItemID == 506 )
+          _449B7E_toggle_bit(pParty->_quest_bits, 184, 1u);
+        if ( v22->uItemID == 455 )
+          _449B7E_toggle_bit(pParty->_quest_bits, 185, 1u);
+        if ( !pParty->AddItem(v22) )
+          pParty->SetHoldingItem(v22);
+      }
+      SpriteObject::OnInteraction(a2.y);
+      return;
+    }
+    v4 = pParty->pPickedItem.uItemID;
+    if ( !pParty->pPickedItem.uItemID )
+		return;
+    goto LABEL_14;
+  }
+  if ( PID_TYPE(v0) != OBJECT_Actor)
+  {
+    if ( PID_TYPE(v0) == OBJECT_Decoration)
+    {
+      v13 = &pLevelDecorations[(signed int)(unsigned __int16)v0 >> 3];
+      if ( (signed int)(((unsigned int)v0 >> 16) - pDecorationList->pDecorations[v13->uDecorationDescID].uRadius) >= 512 )
+	  {
+          v4 = pParty->pPickedItem.uItemID;
+          if ( !pParty->pPickedItem.uItemID )
+            return;
+          goto LABEL_14;
+	  }
+      v14 = v13->field_16_event_id;
+      if ( !v14 )
+      {
+        if ( pLevelDecorations[(signed int)(unsigned __int16)v0 >> 3].IsInteractive() )
+        {
+          v15 = stru_5E4C90._decor_events[v13->_idx_in_stru123 - 75] + 380;
+          activeLevelDecoration = &pLevelDecorations[(signed int)(unsigned __int16)v0 >> 3];
+          EventProcessor(v15, 0, 1);
+          activeLevelDecoration = NULL;
+        }
+        return;
+      }
+      v11 = v14;
+    }
+    else
+    {
+      if ( PID_TYPE(v0) != OBJECT_BModel || HIWORD(v0) >= 512 )
+	  {
+          v4 = pParty->pPickedItem.uItemID;
+          if ( !pParty->pPickedItem.uItemID )
+            return;
+          goto LABEL_14;
+	  }
+      v2 = PID_ID(v0);
+      if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
+      {
+        v3 = &pIndoor->pFaces[v2];
+        if ( !(v3->uAttributes & 0x2000000) )
+        {
+LABEL_11:
+			v4 = pParty->pPickedItem.uItemID;
+			if ( !pParty->pPickedItem.uItemID )
+			{
+				ShowNothingHereStatus();
+				v4 = pParty->pPickedItem.uItemID;
+				if ( !pParty->pPickedItem.uItemID )
+					return;
+			}
+LABEL_14:
+			v5 = pItemsTable->pItems[v4].uSpriteID;
+			v6 = 0;
+			a1.uType = v5;
+			if ( (signed int)pObjectList->uNumObjects <= 0 )
+				LOWORD(v6) = 0;
+			else
+			{
+				v7 = (char *)&pObjectList->pObjects->uObjectID;
+				while ( v5 != *(short *)v7 )
+				{
+					++v6;
+					v7 += 56;
+					if ( v6 >= (signed int)pObjectList->uNumObjects )
+					{
+						LOWORD(v6) = 0;
+						break;
+					}
+				}
+			}
+			a1.uObjectDescID = v6;
+			a1.vPosition.y = pParty->vPosition.y;
+			a1.spell_caster_pid = OBJECT_Player;
+			a1.vPosition.x = pParty->vPosition.x;
+			a1.vPosition.z = pParty->sEyelevel + pParty->vPosition.z;
+			a1.uSoundID = 0;
+			a1.uFacing = 0;
+			a1.uAttributes = 8;
+			a1.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->sEyelevel + pParty->vPosition.z);
+			a1.uSpriteFrameID = 0;
+			memcpy(&a1.stru_24, &pParty->pPickedItem, 0x24u);
+
+            extern int UnprojectX(int);
+			v9 = UnprojectX(v1->x);
+			a1.Create(pParty->sRotationY + v9, 184, 200, 0);
+			v10 = pIcons_LOD->LoadTexture(pItemsTable->pItems[pParty->pPickedItem.uItemID].pIconName, TEXTURE_16BIT_PALETTE);
+			if (v10 != -1)
+				pIcons_LOD->pTextures[v10].Release();
+			pMouse->RemoveHoldingItem();
+			pIcons_LOD->SyncLoadedFilesCount();
+			return;
+        }
+        v11 = pIndoor->pFaceExtras[v3->uFaceExtraID].uEventID;
+      }
+      else
+      {
+        v12 = &pOutdoor->pBModels[(signed int)(v0 & 0xFFFF) >> 9].pFaces[v2 & 0x3F];
+        if ( !v12->Clickable())
+          goto LABEL_11;
+        v11 = v12->sCogTriggeredID;
+      }
+    }
+    EventProcessor(v11, (unsigned __int16)v0, 1);
+    return;
+  }
+  v16 = (signed int)(unsigned __int16)v0 >> 3;
+  a2.y = v16;
+  v17 = &pActors[v16];
+  if ( v17->uAIState == 5 )
+  {
+    if ( (unsigned int)v0 < 0x2000000 )
+    {
+      stru_50C198.LootActor(&pActors[v16]);
+      return;
+    }
+    v4 = pParty->pPickedItem.uItemID;
+    if ( !pParty->pPickedItem.uItemID )
+		return;
+    goto LABEL_14;
+  }
+  if ( GetAsyncKeyState(VK_SHIFT) >= 0 )
+  {
+    if ( !v17->GetActorsRelation(0) && !(BYTE2(v17->uAttributes) & 8) )
+    {
+      if ( HIWORD(v0) >= 512)
+	  {
+          v4 = pParty->pPickedItem.uItemID;
+          if ( !pParty->pPickedItem.uItemID )
+            return;
+          goto LABEL_14;
+	  }
+      if ( !v17->CanAct() )
+        return;
+      v18 = a2.y;
+      Actor::AI_FaceObject(a2.y, 4u, 0, 0);
+      if ( !v17->sNPC_ID )
+      {
+        v19 = pNPCStats->pGroups_copy[v17->uGroup];
+        if ( v19 )
+        {
+          v20 = pNPCStats->pCatchPhrases[v19];
+          if ( v20 )
+          {
+            pParty->uFlags |= 2u;
+            strcpy(byte_5B0938.data(), v20);
+            sub_4451A8_press_any_key(0, 0, 0);
+          }
+        }
+        return;
+      }
+      /*if ( (signed int)pMessageQueue_50CBD0->uNumMessages >= 40 )
+        return;
+      pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].eType = UIMSG_StartNPCDialogue;
+      pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = v18;
+LABEL_42:
+      *(&pMessageQueue_50CBD0->uNumMessages + 3 * pMessageQueue_50CBD0->uNumMessages + 3) = 0;
+      ++pMessageQueue_50CBD0->uNumMessages;
+      return;*/
+      pMessageQueue_50CBD0->AddMessage(UIMSG_StartNPCDialogue, v18, 0);
+      return;
+    }
+    if ( pParty->bTurnBasedModeOn == 1 && pTurnEngine->field_4 == 3 )
+    {
+      pTurnEngine->field_18 |= 8u;
+      return;
+    }
+    /*if ( (signed int)pMessageQueue_50CBD0->uNumMessages < 40 )
+    {
+      pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].eType = UIMSG_Attack;
+      goto LABEL_41;
+    }*/
+    pMessageQueue_50CBD0->AddMessage(UIMSG_Attack, 0, 0);
+  }
+  else
+  {
+    if ( pParty->bTurnBasedModeOn == 1 && pTurnEngine->field_4 == 3 )
+    {
+      pParty->uFlags |= PARTY_FLAGS_1_FALLING;
+      return;
+    }
+    if ( uActiveCharacter
+      && sub_427769_spell(pPlayers[uActiveCharacter]->uQuickSpell))
+    {
+      pMessageQueue_50CBD0->AddMessage(UIMSG_CastQuickSpell, 0, 0);
+      /*&& (signed int)pMessageQueue_50CBD0->uNumMessages < 40 )
+      pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].eType = UIMSG_CastQuickSpell;
+LABEL_41:
+      pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = 0;
+      goto LABEL_42;*/
+    }
+  }
+}
--- a/mm7_1.cpp	Sun Jun 23 14:27:32 2013 +0600
+++ b/mm7_1.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -39,7 +39,7 @@
 #include "IconFrameTable.h"
 #include "TurnEngine.h"
 #include "texts.h"
-#include "UIHouses.h"
+#include "UI\UIHouses.h"
 #include "stru367.h"
 
 int __stdcall aWinProc(HWND hWnd, UINT Msg, WPARAM wParam, unsigned int lParam);
@@ -66,294 +66,6 @@
   return ((__int64)a1 * (__int64)a2) >> 16;
 }
 
-//----- (004196A0) --------------------------------------------------------
-void CharacterUI_ReleaseButtons()
-{
-  GUIButton *i; // esi@2
-  GUIButton *j; // esi@7
-
-  if ( dword_507CC0_activ_ch )
-  {
-    dword_507CC0_activ_ch = 0;
-    for ( i = pGUIWindow_CurrentMenu->pControlsHead; i; i = j )
-    {
-	  j=i->pNext;
-	  if ( BYTE1(i->field_1C) & 0x80 )
-	  {
-        i->Release();
-		pAllocator->FreeChunk(i);
-	  }
-    }
-    for ( j = pGUIWindow_CurrentMenu->pControlsHead; j; j = j->pNext )
-    {
-      if ( j->msg == UIMSG_InventoryLeftClick)
-      {
-        j->uX = dword_50698C_uX;
-        j->uY = dword_506988_uY;
-        j->uZ = dword_506984_uZ;
-        j->uW = dword_506980_uW;
-        pGUIWindow_CurrentMenu->_41D08F_set_keyboard_control_group(1, 0, 0, 0);
-      }
-    }
-  }
-}
-
-//----- (0041CD4F) --------------------------------------------------------
-bool UI_OnKeyDown(unsigned int vkKey)
-{
-  //unsigned int v1; // edi@1
-  //unsigned int v2; // eax@2
-  int v3; // esi@3
-  int v4; // ecx@10
-  GUIButton *pButton; // eax@11
-  int v6; // edx@12
-  int v7; // ecx@20
-  char v8; // zf@21
-  //GUIButton *v9; // ecx@24
-  int v10; // esi@24
-  //int v11; // edx@26
-  int v12; // edx@28
-  int v13; // esi@32
-  //GUIButton *v14; // eax@37
-  int v15; // edx@38
-  int v17; // ecx@50
-  int v18; // edx@50
-  //GUIButton *v19; // ecx@54
-  int v20; // esi@54
-  //int v21; // edx@56
-  int v22; // ecx@59
-  int v23; // edx@59
-  int v24; // ecx@60
-  int v25; // esi@63
-  //unsigned int v26; // [sp+Ch] [bp-14h]@1
-  //int v27; // [sp+10h] [bp-10h]@1
-  int v28; // [sp+14h] [bp-Ch]@10
-  int v29; // [sp+14h] [bp-Ch]@36
-  unsigned int uClickX; // [sp+18h] [bp-8h]@10
-  unsigned int uClickY; // [sp+1Ch] [bp-4h]@10
-
-  //v1 = 0;
-  //v27 = uNumVisibleWindows;
-  if ( uNumVisibleWindows < 0 )
-    return false;
-  //v2 = pMessageQueue_50CBD0->uNumMessages;
-  for (int i = uNumVisibleWindows; i >= 0; --i)
-  //while ( 1 )
-  {
-    v3 = pVisibleWindowsIdxs[i] - 1;
-    if (!pWindowList[v3].receives_keyboard_input)
-      continue;
-
-    switch (vkKey)
-    {
-      case VK_LEFT:
-      {
-        v12 = pWindowList[v3].field_34;
-        if ( pWindowList[v3].pCurrentPosActiveItem - pWindowList[v3].pStartingPosActiveItem - v12 >= 0 )
-        {
-          v8 = pCurrentScreen == SCREEN_PARTY_CREATION;
-          pWindowList[v3].pCurrentPosActiveItem -= v12;
-          if ( v8 )
-          {
-            pAudioPlayer->PlaySound(SOUND_Button, 0, 0, -1, 0, 0, 0, 0);
-            //v2 = pMessageQueue_50CBD0->uNumMessages;
-          }
-        }
-        if ( pWindowList[v3].field_30 != 0 )
-        {
-          break;
-        }
-        pButton = pWindowList[v3].pControlsHead;
-        v13 = pWindowList[v3].pCurrentPosActiveItem;
-        if ( v13 > 0)
-        {
-          do
-          {
-            pButton = pButton->pNext;
-            --v13;
-          }
-          while ( v13 );
-        }
-        pMessageQueue_50CBD0->AddMessage(pButton->msg, pButton->msg_param, 0);
-        break;
-      }
-      case VK_RIGHT:
-      {
-        v7 = pWindowList[v3].pCurrentPosActiveItem + pWindowList[v3].field_34;
-        if ( v7 < pWindowList[v3].pNumPresenceButton + pWindowList[v3].pStartingPosActiveItem )
-        {
-          v8 = pCurrentScreen == SCREEN_PARTY_CREATION;
-          pWindowList[v3].pCurrentPosActiveItem = v7;
-          if ( v8 )
-          {
-            pAudioPlayer->PlaySound(SOUND_Button, 0, 0, -1, 0, 0, 0, 0);
-            //v2 = pMessageQueue_50CBD0->uNumMessages;
-          }
-        }
-        if ( pWindowList[v3].field_30 != 0 )
-        {
-          break;
-        }
-        pButton = pWindowList[v3].pControlsHead;
-        v10 = pWindowList[v3].pCurrentPosActiveItem;
-        if ( v10 > 0)
-        {
-          do
-          {
-            pButton = pButton->pNext;
-            --v10;
-          }
-          while ( v10 );
-        }
-        pMessageQueue_50CBD0->AddMessage(pButton->msg, pButton->msg_param, 0);
-        break;
-      }
-      case VK_DOWN:
-      {
-        v17 = pWindowList[v3].pStartingPosActiveItem;
-        v18 = pWindowList[v3].pCurrentPosActiveItem;
-        if ( v18 >= pWindowList[v3].pNumPresenceButton + v17 - 1 )
-          pWindowList[v3].pCurrentPosActiveItem = v17;
-        else
-          pWindowList[v3].pCurrentPosActiveItem = v18 + 1;
-        if ( pWindowList[v3].field_30 != 0 )
-          return true;
-        pButton = pWindowList[v3].pControlsHead;
-        v20 = pWindowList[v3].pCurrentPosActiveItem;
-        if ( v20 > 0)
-        {
-          do
-          {
-            pButton = pButton->pNext;
-            --v20;
-          }
-          while ( v20 );
-        }
-        pMessageQueue_50CBD0->AddMessage(pButton->msg, pButton->msg_param, 0);
-        return true;
-      }
-      case VK_SELECT:
-      {
-        pMouse->GetClickPos(&uClickX, &uClickY);
-        v4 = pWindowList[v3].pStartingPosActiveItem;
-        v28 = v4 + pWindowList[v3].pNumPresenceButton;
-        if ( v4 < v4 + pWindowList[v3].pNumPresenceButton )
-        {
-          while ( 1 )
-          {
-            pButton = pWindowList[v3].pControlsHead;
-            if ( v4 > 0 )
-            {
-              v6 = v4;
-              do
-              {
-                pButton = pButton->pNext;
-                --v6;
-              }
-              while ( v6 );
-            }
-            if ( (signed int)uClickX >= (signed int)pButton->uX//test for StatsTab in PlayerCreation Window
-               && (signed int)uClickX <= (signed int)pButton->uZ
-               && (signed int)uClickY >= (signed int)pButton->uY
-               && (signed int)uClickY <= (signed int)pButton->uW )
-              break;
-            ++v4;
-            if ( v4 >= v28 )
-            {
-              //v1 = 0;
-              //v2 = pMessageQueue_50CBD0->uNumMessages;
-              //--i;
-              //if ( i < 0 )
-                return false;
-              //continue;
-            }
-          }
-          pWindowList[v3].pCurrentPosActiveItem = v4;
-          return true;
-        }
-        //v2 = pMessageQueue_50CBD0->uNumMessages;
-        break;
-      }
-      case VK_UP:
-      {
-        v22 = pWindowList[v3].pCurrentPosActiveItem;
-        v23 = pWindowList[v3].pStartingPosActiveItem;
-        if ( v22 <= v23 )
-          v24 = pWindowList[v3].pNumPresenceButton + v23 - 1;
-        else
-          v24 = v22 - 1;
-        v8 = pWindowList[v3].field_30 == 0;
-        pWindowList[v3].pCurrentPosActiveItem = v24;
-        if ( !v8 )
-          return true;
-        pButton = pWindowList[v3].pControlsHead;
-        v25 = pWindowList[v3].pCurrentPosActiveItem;
-        if ( v25 > 0)
-        {
-          do
-          {
-            pButton = pButton->pNext;
-            --v25;
-          }
-          while ( v25 );
-        }
-        pMessageQueue_50CBD0->AddMessage(pButton->msg, pButton->msg_param, 0);
-        return true;
-      }
-      case VK_NEXT:
-      {  
-        //if ( pWindowList[v3].field_30 != 0 )   //crashed at skill draw
-        //{
-        //  pMouse->GetClickPos(&uClickX, &uClickY);
-        //  v4 = pWindowList[v3].pStartingPosActiveItem;
-        //  v29 = v4 + pWindowList[v3].pNumPresenceButton; //num buttons more than buttons 
-        //  if ( v4 < v29 )
-        //  {
-        //    while ( 1 )
-        //    {
-        //      pButton = pWindowList[v3].pControlsHead;
-        //      if ( v4 > 0 )
-        //      {
-        //        v15 = v4;
-        //        do
-        //        {
-        //          pButton = pButton->pNext;
-        //          --v15;
-        //        }
-        //        while ( v15 );
-        //      }
-        //      if ( (signed int)uClickX >= (signed int)pButton->uX
-        //        && (signed int)uClickX <= (signed int)pButton->uZ
-        //        && (signed int)uClickY >= (signed int)pButton->uY
-        //        && (signed int)uClickY <= (signed int)pButton->uW )
-        //      {
-        //        pWindowList[v3].pCurrentPosActiveItem = v4;
-        //        return true;
-        //      }
-        //      ++v4;
-        //      if ( v4 >= v29 )
-        //      {
-        //        //v1 = 0;
-        //        //v2 = pMessageQueue_50CBD0->uNumMessages;
-        //        break;
-        //      }
-        //    }
-        //  }
-        //  else
-        //  {
-        //    //v2 = pMessageQueue_50CBD0->uNumMessages;
-        //  }
-        //}
-        break;
-      }
-      default:
-      {
-        break;
-      }
-    }
-  }
-}
-
 //----- (0041D20D) --------------------------------------------------------
 void __fastcall sub_41D20D_buff_remaining_time_string( int ecx0, struct GUIWindow *edx0, __int64 a3, struct GUIFont *a2 )
     {
@@ -423,64 +135,6 @@
   a1->DrawText(a2, 32, uY, 0, pTmpBuf.data(), 0, 0, 0);
 }
 
-//----- (0041F54A) --------------------------------------------------------
-void __cdecl LoadActualSkyFrame()
-{
-  if ( pTexture_RestUI_CurrentSkyFrame )
-    pTexture_RestUI_CurrentSkyFrame->Release();
-  if ( pTexture_RestUI_CurrentHourglassFrame )
-    pTexture_RestUI_CurrentHourglassFrame->Release();
-  pIcons_LOD->SyncLoadedFilesCount();
-  sprintf(pTmpBuf.data(), "TERRA%03d", pParty->uCurrentMinute / 6 + 10 * pParty->uCurrentHour);
-  pTexture_RestUI_CurrentSkyFrame = pIcons_LOD->LoadTexturePtr(pTmpBuf.data(), TEXTURE_16BIT_PALETTE);
-}
-
-//----- (0041F5BE) --------------------------------------------------------
-void __cdecl Sleep6Hours()
-{
-  if ( _506F18_num_hours_to_sleep < 6 )
-  {
-    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);
-      _506F18_num_hours_to_sleep = 0;
-      LoadActualSkyFrame();
-    }
-    if ( dword_506F14 == 2 )
-    {
-      pGUIWindow_CurrentMenu->Release();
-      pEventTimer->Resume();
-      if ( pTexture_RestUI_CurrentSkyFrame )
-        pTexture_RestUI_CurrentSkyFrame->Release();
-      if ( pTexture_RestUI_CurrentHourglassFrame )
-        pTexture_RestUI_CurrentHourglassFrame->Release();
-      pTexture_RestUI_CurrentHourglassFrame = 0;
-      pTexture_RestUI_CurrentSkyFrame = 0;
-      pIcons_LOD->_4114F2();
-      pIcons_LOD->SyncLoadedFilesCount();
-      pCurrentScreen = SCREEN_GAME;
-      viewparams->bRedrawGameUI = 1;
-      if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor)
-      {
-        pOutdoor->UpdateSunlightVectors();
-        pOutdoor->UpdateFog();
-      }
-    }
-    dword_506F14 = 0;
-  }
-  else
-  {
-    Rest(6u);
-    _506F18_num_hours_to_sleep -= 6;
-    LoadActualSkyFrame();
-  }
-  viewparams->bRedrawGameUI = 1;
-}
-
 //----- (0042038D) --------------------------------------------------------
 void __cdecl sub_42038D()
 {
@@ -509,631 +163,6 @@
   }
 }
 
-//----- (00420C05) --------------------------------------------------------
-void __fastcall party_finds_gold(unsigned int uNumGold, int _1_dont_share_with_followers___2_the_same_but_without_a_message__else_normal)
-{
-  unsigned int v2; // edi@1
-  int v3; // ebp@1
-  unsigned int v4; // esi@1
-  int v5; // ecx@6
-  NPCData *v6; // eax@6
-  signed int v7; // edx@8
-  signed int v8; // ebx@10
-  char *v9; // edi@11
-  signed int v10; // ecx@17
-  int v11; // eax@21
-  NPCData *v12; // ecx@21
-  unsigned int v13; // ecx@23
-  signed int v14; // [sp+Ch] [bp-4h]@6
-
-  v2 = 0;
-  v3 = 0;
-  v4 = uNumGold;
-  if ( _1_dont_share_with_followers___2_the_same_but_without_a_message__else_normal )
-  {
-    if ( _1_dont_share_with_followers___2_the_same_but_without_a_message__else_normal == 1 )
-    {
-      sprintf(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[467], uNumGold);// You found %lu gold!
-    }
-    else
-    {
-      if ( _1_dont_share_with_followers___2_the_same_but_without_a_message__else_normal == 2 )
-        pTmpBuf2[0] = 0;
-    }
-  }
-  else
-  {
-    v14 = 0;
-    v5 = 0;
-    v6 = pParty->pHirelings;
-    do
-    {
-      if ( v6->pName )
-      {
-        v7 = v14++;
-        pTmpBuf[v7] = v5;
-      }
-      ++v6;
-      ++v5;
-    }
-    while ( (signed int)v6 < (signed int)&pParty->pPickedItem );
-    v8 = 0;
-    if ( (signed int)pNPCStats->uNumNewNPCs > 0 )
-    {
-      v9 = (char *)pNPCStats->pNewNPCData;
-      do
-      {
-        if ( v9[8] & 0x80
-          && (!pParty->pHirelings[0].pName || strcmp(*(const char **)v9, pParty->pHirelings[0].pName))
-          && (!pParty->pHirelings[1].pName || strcmp(*(const char **)v9, pParty->pHirelings[1].pName)) )
-        {
-          v10 = v14++;
-          pTmpBuf[v10] = v8 + 2;
-        }
-        ++v8;
-        v9 += 76;
-      }
-      while ( v8 < (signed int)pNPCStats->uNumNewNPCs );
-      v2 = 0;
-    }
-    if ( v14 > 0 )
-    {
-      do
-      {
-        v11 = (unsigned __int8)pTmpBuf[v2];
-        v12 = &pNPCStats->pNPCData[v11 + 499];
-        if ( (unsigned __int8)pTmpBuf[v2] < 2 )
-          v12 = &pParty->pHirelings[v11];
-        v13 = v12->uProfession;
-        if ( v13 )
-          v3 += pNPCStats->pProfessions[v13].uHirePrice;//*(&pNPCStats->field_13A58 + 5 * v13);
-        ++v2;
-      }
-      while ( (signed int)v2 < v14 );
-    }
-    if ( CheckHiredNPCSpeciality(Factor) )
-      v4 += (signed int)(10 * v4) / 100;
-    if ( CheckHiredNPCSpeciality(Banker) )
-      v4 += (signed int)(20 * v4) / 100;
-    if ( CheckHiredNPCSpeciality(Pirate) )
-      v4 += (signed int)(10 * v4) / 100;
-    if ( v3 )
-    {
-      v3 = (signed int)(v4 * v3 / 100) / 100;
-      if ( v3 < 1 )
-        v3 = 1;
-      sprintf(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[466], v4, v3);// You found %lu gold (followers take %lu)!
-    }
-    else
-    {
-      sprintf(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[467], v4);// You found %lu gold!
-    }
-    v2 = 0;
-  }
-  pParty->uNumGold += v4 - v3;
-  pUIAnim_Gold->uAnimTime = v2;
-  pUIAnim_Gold->uAnimLength = 8 * pIconsFrameTable->pIcons[(signed __int16)pUIAnim_Gold->uIconID].uAnimLength;
-  if ( pTmpBuf2[0] )
-    ShowStatusBarString(pTmpBuf2.data(), 2u);
-  pAudioPlayer->PlaySound(SOUND_GoldReceived, v2, v2, -1, v2, v2, v2, v2);
-}
-
-//----- (00420E01) --------------------------------------------------------
-void __cdecl OnChestLeftClick()
-{
-  int chest_id; // edi@1
-  POINT *v1; // esi@2
-  int v2; // eax@2
-  int v3; // ebx@4
-  int v4; // esi@6
-  int v5; // ecx@6
-  //SpriteObject v6; // [sp+Ch] [bp-80h]@1
-  POINT v7; // [sp+7Ch] [bp-10h]@2
-  POINT a2; // [sp+84h] [bp-8h]@2
-  
-  SpriteObject v6; // [sp+Ch] [bp-80h]@1
-  //SpriteObject::SpriteObject(&v6);
-
-  chest_id = pGUIWindow_CurrentMenu->par1C;
-  if ( pParty->pPickedItem.uItemID )
-  {
-    if ( Chest::PutItemInChest(-1, &pParty->pPickedItem, pGUIWindow_CurrentMenu->par1C) )
-      pMouse->RemoveHoldingItem();
-  }
-  else
-  {
-    v1 = pMouse->GetCursorPos(&a2);
-    v2 = pRenderer->pActiveZBuffer[v1->x + pSRZBufferLineOffsets[pMouse->GetCursorPos((POINT *)&v7)->y]] & 0xFFFF;
-    if ( v2 )
-    {
-      if ( v2 )
-        v3 = v2 - 1;
-      else
-        v3 = -1;
-      v4 = pChests[chest_id].pInventoryIndices[v3] - 1;
-      if ( pItemsTable->pItems[pChests[chest_id].igChestItems[v4].uItemID].uEquipType == EQUIP_GOLD )
-      {
-        party_finds_gold(pChests[chest_id].igChestItems[v4].uSpecEnchantmentType, 0); 
-        viewparams->bRedrawGameUI = 1;
-      }
-      else
-      {
-        pParty->SetHoldingItem(&pChests[chest_id].igChestItems[v4]);
-      }
-      sub_420B13(v4, v3);
-    }
-  }
-}
-
-
-
-//----- (00421B2C) --------------------------------------------------------
-bool __cdecl sub_421B2C_PlaceInInventory_or_DropPickedItem()
-{
-  unsigned int v0; // eax@2
-  Texture *v1; // ebx@2
-  int v2; // eax@3
-  Player *v3; // esi@5
-  int v4; // eax@6
-  unsigned __int16 v5; // dx@11
-  signed int v6; // eax@11
-  char *v7; // edi@12
-  __int16 v8; // ax@16
-  SpriteObject a1; // [sp+4h] [bp-78h]@11
-  int v11; // [sp+74h] [bp-8h]@2
-  int v12; // [sp+78h] [bp-4h]@5
-
-  if ( !pParty->pPickedItem.uItemID )
-    return 1;
-  v0 = pIcons_LOD->LoadTexture(
-         pItemsTable->pItems[pParty->pPickedItem.uItemID].pIconName,
-         TEXTURE_16BIT_PALETTE);
-  v1 = pIcons_LOD->GetTexture(v0);
-  v11 = areWeLoadingTexture;
-  if ( uActiveCharacter
-    && (v2 = pPlayers[uActiveCharacter]->AddItem(-1, pParty->pPickedItem.uItemID)) != 0 )
-  {
-    memcpy(&pPlayers[uActiveCharacter]->pInventoryItems[v2-1], &pParty->pPickedItem, 0x24u);
-	pMouse->RemoveHoldingItem();
-  }
-  else
-  {
-    v12 = 0;
-    v3 = pParty->pPlayers;
-	while ( v3 <= &pParty->pPlayers[3] )
-    {
-      v4 = v3->AddItem(-1, pParty->pPickedItem.uItemID);
-      if ( v4 )
-	  {
-		memcpy(&pParty->pPlayers[v12].pInventoryItems[v4], &pParty->pPickedItem, 0x24u);
-		pMouse->RemoveHoldingItem();
-		break;
-	  }
-	  ++v12;
-      ++v3;
-    }
-    if ( v12 == 4 )
-	{
-		v5 = pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID;
-		v6 = 0;
-		a1.uType = pItemsTable->pItems[pParty->pPickedItem.uItemID].uSpriteID;
-		if ( (signed int)pObjectList->uNumObjects <= 0 )
-		{
-		  LOWORD(v6) = 0;
-		}
-		else
-		{
-		  v7 = (char *)&pObjectList->pObjects->uObjectID;
-		  while ( v5 != *(short *)v7 )
-		  {
-			++v6;
-			v7 += 56;
-			if ( v6 >= (signed int)pObjectList->uNumObjects )
-			{
-				LOWORD(v6) = 0;
-				break;
-			}
-		  }
-		}
-		a1.spell_caster_pid = OBJECT_Player;
-		a1.uObjectDescID = v6;
-		a1.vPosition.y = pParty->vPosition.y;
-		a1.vPosition.x = pParty->vPosition.x;
-		a1.vPosition.z = pParty->sEyelevel + pParty->vPosition.z;
-		a1.uSoundID = 0;
-		a1.uFacing = 0;
-		a1.uAttributes = 8;
-		v8 = pIndoor->GetSector(
-			   pParty->vPosition.x,
-			   pParty->vPosition.y,
-			   pParty->sEyelevel + pParty->vPosition.z);
-		a1.uSpriteFrameID = 0;
-		a1.uSectorID = v8;
-		memcpy(&a1.stru_24, &pParty->pPickedItem, sizeof(a1.stru_24));
-		a1.Create(pParty->sRotationY, 184, 200, 0);
-		pMouse->RemoveHoldingItem();
-	}
-  }
-  if ( !v11 )
-  {
-    v1->Release();
-    pIcons_LOD->SyncLoadedFilesCount();
-  }
-  return 1;
-}
-
-
-//----- (00421EA6) --------------------------------------------------------
-void __cdecl OnInventoryLeftClick()
-{
-  Player *v0; // ebx@1
-  signed int v1; // eax@2
-  signed int v2; // ecx@2
-  int v3; // eax@2
-  char v4; // sf@2
-  int v5; // eax@2
-  unsigned int v6; // eax@7
-  unsigned int v7; // esi@12
-  unsigned int v8; // eax@12
-  unsigned int v9; // eax@16
-  unsigned int v10; // eax@18
-  ItemGen this_; // [sp+Ch] [bp-3Ch]@1
-  POINT a2; // [sp+30h] [bp-18h]@4
-  unsigned int v13; // [sp+38h] [bp-10h]@13
-  unsigned int pY; // [sp+3Ch] [bp-Ch]@2
-  unsigned int pX; // [sp+40h] [bp-8h]@2
-  int a4; // [sp+44h] [bp-4h]@2
-
-  v0 = pPlayers[uActiveCharacter];
-  if ( pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] == 103 )
-  {
-    pMouse->GetClickPos(&pX, &pY);
-    pY = pY - 17;
-    v2 =pX - 14;
-    pX = v2;
-    v3 = 14 * (pY >> 5);
-    v2 >>= 5;
-    v4 = v2 + v3 < 0;
-    v5 = v2 + v3;
-    a4 = v5;
-    if ( !v4 )
-    {
-      if ( v5 <= 126 && pMouse->GetCursorPos(&a2)->x < 462
-            && pMouse->GetCursorPos(&a2)->x >= 14 )
-      {
-        if ( unk_50C9A0 )
-        {
-          v6 = v0->GetItemIDAtInventoryIndex(&a4);
-          if ( v6 )
-          {
-            *((char *)pGUIWindow_Settings->ptr_1C + 8) &= 0x7Fu;
-            *((short *)pGUIWindow_Settings->ptr_1C + 2) = uActiveCharacter - 1;
-            *((int *)pGUIWindow_Settings->ptr_1C + 3) = v6 - 1;
-            *((short *)pGUIWindow_Settings->ptr_1C + 3) = a4;
-            ptr_50C9A4 = (ItemGen *)&v0->pInventoryItems[v6-1];
-            unk_50C9A0 = 0;
-            if ( pMessageQueue_50CBD0->uNumMessages )
-              pMessageQueue_50CBD0->uNumMessages = pMessageQueue_50CBD0->pMessages[0].field_8 != 0;
-            pMouse->SetCursorBitmap("MICON1");
-            dword_50C9D0 = 113;
-            dword_50C9D4 = 0;
-            dword_50C9D8 = 256;
-          }
-          return;
-        }
-        if ( ptr_50C9A4 )
-          return;
-        v7 = pParty->pPickedItem.uItemID;
-        v8 = v0->GetItemIDAtInventoryIndex(&a4);
-        if ( !v7 )
-        {
-          if ( !v8 )
-            return;
-          memcpy(&pParty->pPickedItem, &v0->pInventoryItems[v8-1], sizeof(pParty->pPickedItem));
-          v0->RemoveItemAtInventoryIndex(a4);
-          v9 = pParty->pPickedItem.uItemID;
-          pMouse->SetCursorBitmap(pItemsTable->pItems[v9].pIconName);
-          return;
-        }
-        v13 = v8;
-        if ( v8 )
-        {
-          a2.y = (LONG)&v0->pInventoryItems[v8-1];
-          memcpy(&this_, (const void *)a2.y, sizeof(this_));
-          v0->RemoveItemAtInventoryIndex(a4);
-          pX = v0->AddItem2(a4, &pParty->pPickedItem);
-          if ( !pX )
-          {
-            pX = v0->AddItem2(0xFFFFFFFFu, &pParty->pPickedItem);
-            if ( !pX )
-            {
-              v0->PutItemArInventoryIndex(&this_, v13 - 1, a4);
-              memcpy((void *)a2.y, &this_, sizeof(ItemGen));
-              return;
-            }
-          }
-          v9 = this_.uItemID;
-          memcpy(&pParty->pPickedItem, &this_, sizeof(pParty->pPickedItem));
-          pMouse->SetCursorBitmap(pItemsTable->pItems[v9].pIconName);
-          return;
-        }
-        v10 = v0->AddItem(a4, v7);
-        pX = v10;
-        if ( v10 || (v10 = v0->AddItem(-1, pParty->pPickedItem.uItemID), (pX = v10) != 0) )
-        {
-          memcpy(&v0->pInventoryItems[v10-1], &pParty->pPickedItem, 0x24u);
-          pMouse->RemoveHoldingItem();
-        }
-      }
-    }
-  }
-}
-
-//----- (0042213C) --------------------------------------------------------
-void OnGameViewportClick()
-{
-  signed int v0; // ebx@2
-  POINT *v1; // esi@3
-  signed int v2; // eax@9
-  BLVFace *v3; // eax@10
-  unsigned int v4; // eax@11
-  unsigned __int16 v5; // dx@14
-  signed int v6; // eax@14
-  char *v7; // esi@15
-  //int *v8; // eax@19
-  int v9; // eax@19
-  unsigned int v10; // eax@19
-  int v11; // ecx@21
-  ODMFace *v12; // eax@22
-  LevelDecoration *v13; // esi@24
-  __int16 v14; // ax@25
-  int v15; // ecx@29
-  signed int v16; // edx@30
-  Actor *v17; // esi@30
-  int v18; // ebx@47
-  unsigned __int16 v19; // ax@50
-  const char *v20; // eax@51
-  signed int v21; // eax@58
-  ItemGen *v22; // esi@62
-  unsigned int v23; // eax@62
-  SpriteObject a1; // [sp+Ch] [bp-80h]@1
-  //POINT v25; // [sp+7Ch] [bp-10h]@3
-  POINT a2; // [sp+84h] [bp-8h]@3
-
-  v1 = pMouse->GetCursorPos(&a2);
-  if ( pRenderer->pRenderD3D )
-    v0 = pGame->pVisInstance->get_picked_object_zbuf_val();
-  else
-  {
-    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
-      && (unsigned int)v0 < 0x2000000 )
-    {
-      v22 = &pSpriteObjects[v21].stru_24;
-      v23 = pSpriteObjects[v21].stru_24.uItemID;
-      if ( pItemsTable->pItems[v23].uEquipType == 18 )
-      {
-        party_finds_gold(v22->uSpecEnchantmentType, 0);
-        viewparams->bRedrawGameUI = 1;
-      }
-      else
-      {
-        sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[471], pItemsTable->pItems[v23].pUnidentifiedName);
-        ShowStatusBarString(pTmpBuf2.data(), 2u);
-        if ( v22->uItemID == 506 )
-          _449B7E_toggle_bit(pParty->_quest_bits, 184, 1u);
-        if ( v22->uItemID == 455 )
-          _449B7E_toggle_bit(pParty->_quest_bits, 185, 1u);
-        if ( !pParty->AddItem(v22) )
-          pParty->SetHoldingItem(v22);
-      }
-      SpriteObject::OnInteraction(a2.y);
-      return;
-    }
-    v4 = pParty->pPickedItem.uItemID;
-    if ( !pParty->pPickedItem.uItemID )
-		return;
-    goto LABEL_14;
-  }
-  if ( PID_TYPE(v0) != OBJECT_Actor)
-  {
-    if ( PID_TYPE(v0) == OBJECT_Decoration)
-    {
-      v13 = &pLevelDecorations[(signed int)(unsigned __int16)v0 >> 3];
-      if ( (signed int)(((unsigned int)v0 >> 16) - pDecorationList->pDecorations[v13->uDecorationDescID].uRadius) >= 512 )
-	  {
-          v4 = pParty->pPickedItem.uItemID;
-          if ( !pParty->pPickedItem.uItemID )
-            return;
-          goto LABEL_14;
-	  }
-      v14 = v13->field_16_event_id;
-      if ( !v14 )
-      {
-        if ( pLevelDecorations[(signed int)(unsigned __int16)v0 >> 3].IsInteractive() )
-        {
-          v15 = stru_5E4C90._decor_events[v13->_idx_in_stru123 - 75] + 380;
-          activeLevelDecoration = &pLevelDecorations[(signed int)(unsigned __int16)v0 >> 3];
-          EventProcessor(v15, 0, 1);
-          activeLevelDecoration = NULL;
-        }
-        return;
-      }
-      v11 = v14;
-    }
-    else
-    {
-      if ( PID_TYPE(v0) != OBJECT_BModel || HIWORD(v0) >= 512 )
-	  {
-          v4 = pParty->pPickedItem.uItemID;
-          if ( !pParty->pPickedItem.uItemID )
-            return;
-          goto LABEL_14;
-	  }
-      v2 = PID_ID(v0);
-      if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
-      {
-        v3 = &pIndoor->pFaces[v2];
-        if ( !(v3->uAttributes & 0x2000000) )
-        {
-LABEL_11:
-			v4 = pParty->pPickedItem.uItemID;
-			if ( !pParty->pPickedItem.uItemID )
-			{
-				ShowNothingHereStatus();
-				v4 = pParty->pPickedItem.uItemID;
-				if ( !pParty->pPickedItem.uItemID )
-					return;
-			}
-LABEL_14:
-			v5 = pItemsTable->pItems[v4].uSpriteID;
-			v6 = 0;
-			a1.uType = v5;
-			if ( (signed int)pObjectList->uNumObjects <= 0 )
-				LOWORD(v6) = 0;
-			else
-			{
-				v7 = (char *)&pObjectList->pObjects->uObjectID;
-				while ( v5 != *(short *)v7 )
-				{
-					++v6;
-					v7 += 56;
-					if ( v6 >= (signed int)pObjectList->uNumObjects )
-					{
-						LOWORD(v6) = 0;
-						break;
-					}
-				}
-			}
-			a1.uObjectDescID = v6;
-			a1.vPosition.y = pParty->vPosition.y;
-			a1.spell_caster_pid = OBJECT_Player;
-			a1.vPosition.x = pParty->vPosition.x;
-			a1.vPosition.z = pParty->sEyelevel + pParty->vPosition.z;
-			a1.uSoundID = 0;
-			a1.uFacing = 0;
-			a1.uAttributes = 8;
-			a1.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->sEyelevel + pParty->vPosition.z);
-			a1.uSpriteFrameID = 0;
-			memcpy(&a1.stru_24, &pParty->pPickedItem, 0x24u);
-
-            extern int UnprojectX(int);
-			v9 = UnprojectX(v1->x);
-			a1.Create(pParty->sRotationY + v9, 184, 200, 0);
-			v10 = pIcons_LOD->LoadTexture(pItemsTable->pItems[pParty->pPickedItem.uItemID].pIconName, TEXTURE_16BIT_PALETTE);
-			if (v10 != -1)
-				pIcons_LOD->pTextures[v10].Release();
-			pMouse->RemoveHoldingItem();
-			pIcons_LOD->SyncLoadedFilesCount();
-			return;
-        }
-        v11 = pIndoor->pFaceExtras[v3->uFaceExtraID].uEventID;
-      }
-      else
-      {
-        v12 = &pOutdoor->pBModels[(signed int)(v0 & 0xFFFF) >> 9].pFaces[v2 & 0x3F];
-        if ( !v12->Clickable())
-          goto LABEL_11;
-        v11 = v12->sCogTriggeredID;
-      }
-    }
-    EventProcessor(v11, (unsigned __int16)v0, 1);
-    return;
-  }
-  v16 = (signed int)(unsigned __int16)v0 >> 3;
-  a2.y = v16;
-  v17 = &pActors[v16];
-  if ( v17->uAIState == 5 )
-  {
-    if ( (unsigned int)v0 < 0x2000000 )
-    {
-      stru_50C198.LootActor(&pActors[v16]);
-      return;
-    }
-    v4 = pParty->pPickedItem.uItemID;
-    if ( !pParty->pPickedItem.uItemID )
-		return;
-    goto LABEL_14;
-  }
-  if ( GetAsyncKeyState(VK_SHIFT) >= 0 )
-  {
-    if ( !v17->GetActorsRelation(0) && !(BYTE2(v17->uAttributes) & 8) )
-    {
-      if ( HIWORD(v0) >= 512)
-	  {
-          v4 = pParty->pPickedItem.uItemID;
-          if ( !pParty->pPickedItem.uItemID )
-            return;
-          goto LABEL_14;
-	  }
-      if ( !v17->CanAct() )
-        return;
-      v18 = a2.y;
-      Actor::AI_FaceObject(a2.y, 4u, 0, 0);
-      if ( !v17->sNPC_ID )
-      {
-        v19 = pNPCStats->pGroups_copy[v17->uGroup];
-        if ( v19 )
-        {
-          v20 = pNPCStats->pCatchPhrases[v19];
-          if ( v20 )
-          {
-            pParty->uFlags |= 2u;
-            strcpy(byte_5B0938.data(), v20);
-            sub_4451A8_press_any_key(0, 0, 0);
-          }
-        }
-        return;
-      }
-      /*if ( (signed int)pMessageQueue_50CBD0->uNumMessages >= 40 )
-        return;
-      pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].eType = UIMSG_StartNPCDialogue;
-      pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = v18;
-LABEL_42:
-      *(&pMessageQueue_50CBD0->uNumMessages + 3 * pMessageQueue_50CBD0->uNumMessages + 3) = 0;
-      ++pMessageQueue_50CBD0->uNumMessages;
-      return;*/
-      pMessageQueue_50CBD0->AddMessage(UIMSG_StartNPCDialogue, v18, 0);
-      return;
-    }
-    if ( pParty->bTurnBasedModeOn == 1 && pTurnEngine->field_4 == 3 )
-    {
-      pTurnEngine->field_18 |= 8u;
-      return;
-    }
-    /*if ( (signed int)pMessageQueue_50CBD0->uNumMessages < 40 )
-    {
-      pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].eType = UIMSG_Attack;
-      goto LABEL_41;
-    }*/
-    pMessageQueue_50CBD0->AddMessage(UIMSG_Attack, 0, 0);
-  }
-  else
-  {
-    if ( pParty->bTurnBasedModeOn == 1 && pTurnEngine->field_4 == 3 )
-    {
-      pParty->uFlags |= PARTY_FLAGS_1_FALLING;
-      return;
-    }
-    if ( uActiveCharacter
-      && sub_427769_spell(pPlayers[uActiveCharacter]->uQuickSpell))
-    {
-      pMessageQueue_50CBD0->AddMessage(UIMSG_CastQuickSpell, 0, 0);
-      /*&& (signed int)pMessageQueue_50CBD0->uNumMessages < 40 )
-      pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].eType = UIMSG_CastQuickSpell;
-LABEL_41:
-      pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = 0;
-      goto LABEL_42;*/
-    }
-  }
-}
-
 //----- (004226C2) --------------------------------------------------------
 bool PauseGameDrawing()
 {
@@ -1485,515 +514,6 @@
   while ( v1 );
 }
 
-//----- (00423B5D) --------------------------------------------------------
-int __fastcall sub_423B5D(unsigned int uFaceID)
-{
-  BLVFace *pFace; // ebx@1
-  //Vec3_short_ *v2; // esi@1
-  //int v3; // ST28_4@1
-  //__int16 v4; // ST2C_2@1
-  signed int v5; // esi@1
-  //Vec3_short_ *v6; // eax@4
-  signed int v7; // edi@5
-  signed int v8; // eax@5
-  signed int v9; // ecx@10
-  int v10; // eax@10
-  int v11; // edx@11
-  int v12; // ST28_4@12
-  signed int v13; // edx@12
-  signed __int64 v14; // qtt@12
-  char *v15; // ebx@12
-  int v16; // ST28_4@14
-  signed int v17; // eax@14
-  signed __int64 v18; // qtt@14
-  signed int v19; // edx@15
-  signed int v20; // edx@17
-  signed int v21; // ebx@19
-  signed int v22; // esi@20
-  int v23; // edi@21
-  int v24; // eax@21
-  int v25; // eax@22
-  int v26; // eax@22
-  signed int v27; // ST30_4@24
-  signed __int64 v28; // qtt@24
-  int v29; // ST18_4@25
-  int v30; // eax@26
-  int v31; // eax@27
-  int v32; // eax@27
-  signed int v33; // ST30_4@29
-  signed __int64 v34; // qtt@29
-  int v35; // ST30_4@30
-  signed int v36; // edi@31
-  unsigned int v37; // eax@31
-  bool v38; // edx@31
-  int v39; // ecx@31
-  int v40; // ecx@32
-  int v41; // esi@32
-  int v42; // eax@34
-  signed int v43; // ebx@41
-  unsigned int v44; // eax@41
-  signed int v45; // ecx@42
-  int v46; // esi@42
-  int v47; // eax@44
-  signed int v48; // edi@51
-  unsigned int v49; // eax@51
-  bool v50; // edx@51
-  int v51; // ecx@51
-  int v52; // ecx@52
-  int v53; // esi@52
-  int v54; // eax@54
-  int v55; // ebx@61
-  unsigned int v56; // eax@61
-  signed int v57; // ecx@62
-  int v58; // esi@62
-  int v59; // eax@64
-  char v61; // zf@72
-  signed int v62; // edx@75
-  int v63; // ecx@76
-  int v64; // esi@76
-  int v65; // ecx@83
-  signed int v66; // [sp+14h] [bp-14h]@3
-  int v67; // [sp+14h] [bp-14h]@34
-  int v68; // [sp+14h] [bp-14h]@44
-  int v69; // [sp+14h] [bp-14h]@54
-  int v70; // [sp+14h] [bp-14h]@64
-  signed int v71; // [sp+14h] [bp-14h]@75
-  //IndoorCameraD3D *_this; // [sp+18h] [bp-10h]@1
-  bool thisa; // [sp+18h] [bp-10h]@9
-  int thisb; // [sp+18h] [bp-10h]@12
-  int thisc; // [sp+18h] [bp-10h]@20
-  bool thisd; // [sp+18h] [bp-10h]@41
-  bool thise; // [sp+18h] [bp-10h]@61
-  int thisf; // [sp+18h] [bp-10h]@74
-  signed int v79; // [sp+1Ch] [bp-Ch]@9
-  int v80; // [sp+1Ch] [bp-Ch]@76
-  bool v81; // [sp+20h] [bp-8h]@10
-  bool v82; // [sp+20h] [bp-8h]@32
-  bool v83; // [sp+20h] [bp-8h]@42
-  bool v84; // [sp+20h] [bp-8h]@52
-  bool v85; // [sp+20h] [bp-8h]@62
-  signed int v86; // [sp+24h] [bp-4h]@9
-  signed int v87; // [sp+24h] [bp-4h]@19
-  signed int v88; // [sp+24h] [bp-4h]@31
-  signed int v89; // [sp+24h] [bp-4h]@41
-  signed int v90; // [sp+24h] [bp-4h]@51
-  signed int v91; // [sp+24h] [bp-4h]@61
-
-  pFace = &pIndoor->pFaces[uFaceID];
-  //_this = pGame->pIndoorCameraD3D;
-  //v2 = &pIndoor->pVertices[pFace->pVertexIDs[0]];
-  //v3 = *(_DWORD *)&pIndoor->pVertices[pFace->pVertexIDs[0]].x;
-  //v4 = pIndoor->pVertices[pFace->pVertexIDs[0]].z;
-  v5 = 0;
-  if ( pFace->pFacePlane_old.vNormal.x * (pIndoor->pVertices[pFace->pVertexIDs[0]].x - pBLVRenderParams->vPartyPos.x)
-     + pFace->pFacePlane_old.vNormal.y * (pIndoor->pVertices[pFace->pVertexIDs[0]].y - pBLVRenderParams->vPartyPos.y)
-     + pFace->pFacePlane_old.vNormal.z * (pIndoor->pVertices[pFace->pVertexIDs[0]].z - pBLVRenderParams->vPartyPos.z) < 0 )
-  {
-    stru_50B700.field_0 = 1;
-  }
-  else
-  {
-    stru_50B700.field_0 = 0;
-    if ( !(pFace->uAttributes & 1) )
-      return 0;
-  }
-  v66 = pFace->uNumVertices;
-  if ( (signed int)pFace->uNumVertices > 0 )
-  {
-    do
-    {
-      //v6 = &pIndoor->pVertices[pFace->pVertexIDs[v5]];
-      pGame->pIndoorCameraD3D->ApplyViewTransform_TrueIfStillVisible(pIndoor->pVertices[pFace->pVertexIDs[v5]].x,
-        pIndoor->pVertices[pFace->pVertexIDs[v5]].y, pIndoor->pVertices[pFace->pVertexIDs[v5]].z,
-        &stru_50B700._view_transformed_xs[v5 + 3], &stru_50B700._view_transformed_zs[v5 + 3],
-        &stru_50B700._view_transformed_ys[v5 + 3], 0);
-      ++v5;
-    }
-    while ( v5 < v66 );
-  }
-  v7 = v66;
-  v8 = 0;
-  if ( v66 <= 0 )
-    return 0;
-  do
-  {
-    if ( stru_50B700._view_transformed_xs[v8 + 3] >= 524288 )
-      break;
-    ++v8;
-  }
-  while ( v8 < v66 );
-  if ( v8 >= v66 )
-    return 0;
-  v79 = 0;
-  stru_50B700._view_transformed_xs[v66 + 3] = stru_50B700._view_transformed_xs[3];
-  stru_50B700._view_transformed_zs[v66 + 3] = stru_50B700._view_transformed_zs[3];
-  stru_50B700._view_transformed_ys[v66 + 3] = stru_50B700._view_transformed_ys[3];
-  thisa = stru_50B700._view_transformed_xs[3] >= 524288;
-  v86 = 1;
-  if ( v66 >= 1 )
-  {
-    do
-    {
-      v9 = v86;
-      v10 = stru_50B700._view_transformed_xs[v86 + 3];
-      v81 = v10 >= 524288;
-      if ( thisa ^ v81 )
-      {
-        v11 = stru_50B700._view_transformed_xs[v9 + 2];
-        if ( v10 >= 524288 )
-        {
-          v12 = v10 - v11;
-          v13 = 524288 - v11;
-          LODWORD(v14) = v13 << 16;
-          HIDWORD(v14) = v13 >> 16;
-          v15 = (char *)&stru_50B700._view_transformed_ys[v9 + 2];
-          stru_50B700._view_transformed_zs[v79] = ((unsigned __int64)((stru_50B700._view_transformed_zs[v9 + 3]
-                                                                     - stru_50B700._view_transformed_zs[v9 + 2])
-                                                                    * v14
-                                                                    / v12) >> 16)
-                                                + stru_50B700._view_transformed_zs[v9 + 2];
-          thisb = (unsigned __int64)((stru_50B700._view_transformed_ys[v9 + 3] - stru_50B700._view_transformed_ys[v9 + 2])
-                                   * v14
-                                   / v12) >> 16;
-        }
-        else
-        {
-          v16 = v11 - v10;
-          v17 = 524288 - v10;
-          LODWORD(v18) = v17 << 16;
-          HIDWORD(v18) = v17 >> 16;
-          v15 = (char *)&stru_50B700._view_transformed_ys[v9 + 3];
-          stru_50B700._view_transformed_zs[v79] = ((unsigned __int64)((stru_50B700._view_transformed_zs[v9 + 2]
-                                                                     - stru_50B700._view_transformed_zs[v9 + 3])
-                                                                    * v18
-                                                                    / v16) >> 16)
-                                                + stru_50B700._view_transformed_zs[v9 + 3];
-          thisb = (unsigned __int64)((stru_50B700._view_transformed_ys[v9 + 2] - stru_50B700._view_transformed_ys[v9 + 3])
-                                   * v18
-                                   / v16) >> 16;
-        }
-        v19 = v79++;
-        v7 = v66;
-        stru_50B700._view_transformed_ys[v19] = thisb + *(_DWORD *)v15;
-        stru_50B700._view_transformed_xs[v19] = 524288;
-      }
-      if ( v81 )
-      {
-        v20 = v79++;
-        stru_50B700._view_transformed_xs[v20] = stru_50B700._view_transformed_xs[v9 + 3];
-        stru_50B700._view_transformed_zs[v20] = stru_50B700._view_transformed_zs[v9 + 3];
-        stru_50B700._view_transformed_ys[v20] = stru_50B700._view_transformed_ys[v9 + 3];
-      }
-      ++v86;
-      thisa = v81;
-    }
-    while ( v86 <= v7 );
-  }
-  v87 = 0;
-  v21 = v79;
-  stru_50B700._view_transformed_xs[v79] = stru_50B700._view_transformed_xs[0];
-  stru_50B700._view_transformed_zs[v79] = stru_50B700._view_transformed_zs[0];
-  for ( stru_50B700._view_transformed_ys[v79] = stru_50B700._view_transformed_ys[0];
-        v87 < v79;
-        stru_50B700._screen_space_y[v22 + 12] = pBLVRenderParams->uViewportCenterY - v35 )
-  {
-    v22 = v87;
-    thisc = abs(stru_50B700._view_transformed_xs[v87]);
-    if ( abs(stru_50B700._view_transformed_zs[v87]) >> 13 <= thisc )
-    {
-      v27 = stru_50B700._view_transformed_zs[v22];
-      LODWORD(v28) = v27 << 16;
-      HIDWORD(v28) = v27 >> 16;
-      v26 = v28 / stru_50B700._view_transformed_xs[v22];
-      v23 = 0;
-    }
-    else
-    {
-      v23 = 0;
-      v24 = 0;
-      if ( stru_50B700._view_transformed_zs[v22] >= 0 )
-      {
-        LOBYTE(v24) = stru_50B700._view_transformed_xs[v22] >= 0;
-        v26 = ((v24 - 1) & 0xFF800000) + 4194304;
-      }
-      else
-      {
-        LOBYTE(v24) = stru_50B700._view_transformed_xs[v22] >= 0;
-        v25 = v24 - 1;
-        v26 = (v25 & 0x800000) - 4194304;
-      }
-    }
-    v29 = stru_50B700._view_transformed_ys[v22];
-    stru_50B700._screen_space_x[v22 + 12] = v26;
-    if ( abs(v29) >> 13 <= thisc )
-    {
-      v33 = stru_50B700._view_transformed_ys[v22];
-      LODWORD(v34) = v33 << 16;
-      HIDWORD(v34) = v33 >> 16;
-      v32 = v34 / stru_50B700._view_transformed_xs[v22];
-    }
-    else
-    {
-      v30 = 0;
-      if ( stru_50B700._view_transformed_ys[v22] >= v23 )
-      {
-        LOBYTE(v30) = stru_50B700._view_transformed_xs[v22] >= v23;
-        v32 = ((v30 - 1) & 0xFF800000) + 4194304;
-      }
-      else
-      {
-        LOBYTE(v30) = stru_50B700._view_transformed_xs[v22] >= v23;
-        v31 = v30 - 1;
-        v32 = (v31 & 0x800000) - 4194304;
-      }
-    }
-    stru_50B700._screen_space_y[v22 + 12] = v32;
-    stru_50B700._screen_space_x[v22 + 12] = (unsigned __int64)(SHIWORD(pBLVRenderParams->field_40)
-                                                             * (signed __int64)stru_50B700._screen_space_x[v22 + 12]) >> 16;
-    v35 = (unsigned __int64)(SHIWORD(pBLVRenderParams->field_40) * (signed __int64)stru_50B700._screen_space_y[v22 + 12]) >> 16;
-    stru_50B700._screen_space_x[v22 + 12] = pBLVRenderParams->uViewportCenterX - stru_50B700._screen_space_x[v22 + 12];
-    ++v87;
-  }
-  v36 = 0;
-  stru_50B700._screen_space_x[v21 + 12] = stru_50B700._screen_space_x[12];
-  stru_50B700._screen_space_y[v21 + 12] = stru_50B700._screen_space_y[12];
-  v37 = pBLVRenderParams->uViewportX;
-  v38 = stru_50B700._screen_space_x[12] < (signed int)pBLVRenderParams->uViewportX;
-  LOBYTE(v38) = stru_50B700._screen_space_x[12] >= (signed int)pBLVRenderParams->uViewportX;
-  v39 = 1;
-  v88 = 1;
-  if ( v79 < 1 )
-    return 0;
-  do
-  {
-    v40 = v39;
-    v41 = stru_50B700._screen_space_x[v40 + 12];
-    v82 = v41 >= (signed int)v37;
-    if ( v38 ^ v82 )
-    {
-      if ( v41 >= (signed int)v37 )
-      {
-        v67 = (signed int)(v37 - stru_50B700._screen_space_x[v40 + 11])
-            * (signed __int64)(stru_50B700._screen_space_y[v40 + 12] - stru_50B700._screen_space_y[v40 + 11])
-            / (v41 - stru_50B700._screen_space_x[v40 + 11]);
-        v42 = stru_50B700._screen_space_y[v40 + 11];
-      }
-      else
-      {
-        v67 = (signed int)(v37 - v41)
-            * (signed __int64)(stru_50B700._screen_space_y[v40 + 11] - stru_50B700._screen_space_y[v40 + 12])
-            / (stru_50B700._screen_space_x[v40 + 11] - v41);
-        v42 = stru_50B700._screen_space_y[v40 + 12];
-      }
-      ++v36;
-      stru_50B700._screen_space_y[v36 + 8] = v67 + v42;
-      v37 = pBLVRenderParams->uViewportX;
-      stru_50B700._screen_space_x[v36 + 8] = pBLVRenderParams->uViewportX;
-    }
-    v38 = v82;
-    if ( v82 )
-    {
-      stru_50B700._screen_space_x[v36 + 9] = stru_50B700._screen_space_x[v40 + 12];
-      stru_50B700._screen_space_y[v36++ + 9] = stru_50B700._screen_space_y[v40 + 12];
-    }
-    v39 = v88++ + 1;
-  }
-  while ( v88 <= v79 );
-  if ( !v36
-    || (v43 = 0,
-        stru_50B700._screen_space_x[v36 + 9] = stru_50B700._screen_space_x[9],
-        stru_50B700._screen_space_y[v36 + 9] = stru_50B700._screen_space_y[9],
-        v44 = pBLVRenderParams->uViewportZ,
-        thisd = stru_50B700._screen_space_x[9] <= (signed int)pBLVRenderParams->uViewportZ,
-        v89 = 1,
-        v36 < 1) )
-    return 0;
-  do
-  {
-    v45 = v89;
-    v46 = stru_50B700._screen_space_x[v89 + 9];
-    v83 = v46 <= (signed int)v44;
-    if ( thisd ^ v83 )
-    {
-      if ( v46 <= (signed int)v44 )
-      {
-        v68 = (signed int)(v44 - stru_50B700._screen_space_x[v45 + 8])
-            * (signed __int64)(stru_50B700._screen_space_y[v45 + 9] - stru_50B700._screen_space_y[v45 + 8])
-            / (v46 - stru_50B700._screen_space_x[v45 + 8]);
-        v47 = stru_50B700._screen_space_y[v45 + 8];
-      }
-      else
-      {
-        v68 = (signed int)(v44 - v46)
-            * (signed __int64)(stru_50B700._screen_space_y[v45 + 8] - stru_50B700._screen_space_y[v45 + 9])
-            / (stru_50B700._screen_space_x[v45 + 8] - v46);
-        v47 = stru_50B700._screen_space_y[v45 + 9];
-      }
-      ++v43;
-      stru_50B700._screen_space_y[v43 + 5] = v68 + v47;
-      v44 = pBLVRenderParams->uViewportZ;
-      stru_50B700._screen_space_x[v43 + 5] = pBLVRenderParams->uViewportZ;
-    }
-    if ( v83 )
-    {
-      stru_50B700._screen_space_x[v43 + 6] = stru_50B700._screen_space_x[v45 + 9];
-      stru_50B700._screen_space_y[v43++ + 6] = stru_50B700._screen_space_y[v45 + 9];
-    }
-    ++v89;
-    thisd = v83;
-  }
-  while ( v89 <= v36 );
-  if ( !v43
-    || (v48 = 0,
-        stru_50B700._screen_space_x[v43 + 6] = stru_50B700._screen_space_x[6],
-        stru_50B700._screen_space_y[v43 + 6] = stru_50B700._screen_space_y[6],
-        v49 = pBLVRenderParams->uViewportY,
-        v50 = stru_50B700._screen_space_y[6] < (signed int)pBLVRenderParams->uViewportY,
-        LOBYTE(v50) = stru_50B700._screen_space_y[6] >= (signed int)pBLVRenderParams->uViewportY,
-        v51 = 1,
-        v90 = 1,
-        v43 < 1) )
-    return 0;
-  do
-  {
-    v52 = v51;
-    v53 = stru_50B700._screen_space_y[v52 + 6];
-    v84 = v53 >= (signed int)v49;
-    if ( v50 ^ v84 )
-    {
-      if ( v53 >= (signed int)v49 )
-      {
-        v69 = (signed int)(v49 - stru_50B700._screen_space_y[v52 + 5])
-            * (signed __int64)(stru_50B700._screen_space_x[v52 + 6] - stru_50B700._screen_space_x[v52 + 5])
-            / (v53 - stru_50B700._screen_space_y[v52 + 5]);
-        v54 = stru_50B700._screen_space_x[v52 + 5];
-      }
-      else
-      {
-        v69 = (signed int)(v49 - v53)
-            * (signed __int64)(stru_50B700._screen_space_x[v52 + 5] - stru_50B700._screen_space_x[v52 + 6])
-            / (stru_50B700._screen_space_y[v52 + 5] - v53);
-        v54 = stru_50B700._screen_space_x[v52 + 6];
-      }
-      ++v48;
-      stru_50B700._screen_space_x[v48 + 2] = v69 + v54;
-      v49 = pBLVRenderParams->uViewportY;
-      stru_50B700._screen_space_y[v48 + 2] = pBLVRenderParams->uViewportY;
-    }
-    v50 = v84;
-    if ( v84 )
-    {
-      stru_50B700._screen_space_x[v48 + 3] = stru_50B700._screen_space_x[v52 + 6];
-      stru_50B700._screen_space_y[v48++ + 3] = stru_50B700._screen_space_y[v52 + 6];
-    }
-    v51 = v90++ + 1;
-  }
-  while ( v90 <= v43 );
-  if ( !v48
-    || (v55 = 0,
-        stru_50B700._screen_space_x[v48 + 3] = stru_50B700._screen_space_x[3],
-        stru_50B700._screen_space_y[v48 + 3] = stru_50B700._screen_space_y[3],
-        v56 = pBLVRenderParams->uViewportW,
-        thise = stru_50B700._screen_space_y[3] <= (signed int)pBLVRenderParams->uViewportW,
-        v91 = 1,
-        v48 < 1) )
-    return 0;
-  do
-  {
-    v57 = v91;
-    v58 = stru_50B700._screen_space_y[v91 + 3];
-    v85 = v58 <= (signed int)v56;
-    if ( thise ^ v85 )
-    {
-      if ( v58 <= (signed int)v56 )
-      {
-        v70 = (signed int)(v56 - stru_50B700._screen_space_y[v57 + 2])
-            * (signed __int64)(stru_50B700._screen_space_x[v57 + 3] - stru_50B700._screen_space_x[v57 + 2])
-            / (v58 - stru_50B700._screen_space_y[v57 + 2]);
-        v59 = stru_50B700._screen_space_x[v57 + 2];
-      }
-      else
-      {
-        v70 = (signed int)(v56 - v58)
-            * (signed __int64)(stru_50B700._screen_space_x[v57 + 2] - stru_50B700._screen_space_x[v57 + 3])
-            / (stru_50B700._screen_space_y[v57 + 2] - v58);
-        v59 = stru_50B700._screen_space_x[v57 + 3];
-      }
-      ++v55;
-      //stru_50B700._screen_space_y[v55 + 59] = v70 + v59;
-	  stru_50B700._screen_space_x[v55 - 1] = v70 + v59;
-      v56 = pBLVRenderParams->uViewportW;
-      //stru_50B700._view_transformed_xs[v55 + 47] = pBLVRenderParams->uViewportW;
-	  stru_50B700._screen_space_y[v55 - 1] = pBLVRenderParams->uViewportW;
-    }
-    if ( v85 )
-    {
-      stru_50B700._screen_space_x[v55] = stru_50B700._screen_space_x[v57 + 3];
-      stru_50B700._screen_space_y[v55++] = stru_50B700._screen_space_y[v57 + 3];
-    }
-    ++v91;
-    thise = v85;
-  }
-  while ( v91 <= v48 );
-  if ( !v55 )
-    return 0;
-  v61 = pRenderer->pRenderD3D == 0;
-  stru_50B700._screen_space_x[v55] = stru_50B700._screen_space_x[0];
-  stru_50B700._screen_space_y[v55] = stru_50B700._screen_space_y[0];
-  if ( v61 && v55 > 3 )
-  {
-    stru_50B700._screen_space_x[v55 + 1] = stru_50B700._screen_space_x[1];
-    stru_50B700._screen_space_y[v55 + 1] = stru_50B700._screen_space_y[1];
-    thisf = 2 * (stru_50B700.field_0 != 0) - 1;
-    if ( v55 > 0 )
-    {
-      v62 = 1;
-      v71 = 1;
-      do
-      {
-        v63 = v62 - 1;
-        v64 = v62 + 1;
-        v80 = v62 + 1;
-        if ( v62 - 1 >= v55 )
-          v63 -= v55;
-        if ( v62 >= v55 )
-          v62 -= v55;
-        if ( v64 >= v55 )
-          v64 -= v55;
-        if ( thisf
-           * ((stru_50B700._screen_space_y[v64] - stru_50B700._screen_space_y[v63])
-            * (stru_50B700._screen_space_x[v62] - stru_50B700._screen_space_x[v63])
-            - (stru_50B700._screen_space_y[v62] - stru_50B700._screen_space_y[v63])
-            * (stru_50B700._screen_space_x[v64] - stru_50B700._screen_space_x[v63])) < 0 )
-        {
-          v62 = v80;
-          v71 = v80;
-        }
-        else
-        {
-          v62 = v71;
-          v65 = v71;
-          if ( v71 < v55 || (v65 = v71 - v55, v71 - v55 < v55) )
-          {
-            memcpy(
-              &stru_50B700._screen_space_y[v65],
-              &stru_50B700._screen_space_y[v65 + 1],
-              4 * ((unsigned int)(4 * (v55 - v65)) >> 2));
-            memcpy(
-              &stru_50B700._screen_space_x[v65],
-              &stru_50B700._screen_space_x[v65 + 1],
-              4 * ((unsigned int)(4 * (v55 - v65)) >> 2));
-          }
-          --v55;
-        }
-      }
-      while ( v62 - 1 < v55 );
-    }
-    stru_50B700._screen_space_x[v55] = stru_50B700._screen_space_x[0];
-    stru_50B700._screen_space_y[v55] = stru_50B700._screen_space_y[0];
-  }
-  return v55;
-}
 //----- (00424579) --------------------------------------------------------
 int __fastcall sub_424579(int uFaceID, stru320 *a2)
 {
@@ -2266,339 +786,6 @@
   return result;*/
 }
 
-//----- (00424829) --------------------------------------------------------
-bool sub_424829(int pNumVertices, BspRenderer_stru2 *a2, BspRenderer_stru2 *a3, int uFaceID)
-{
-  //int v4; // edi@1
-  //BspRenderer_stru2 *v5; // ebx@1
-  int v6; // eax@3
-  int min_y; // esi@5
-  int max_y; // edx@5
-  //int v9; // ecx@6
-  int v10; // eax@12
-  //int v11; // edi@13
-  //int v12; // edx@18
-  int v13; // eax@22
-  //int v14; // edi@28
-  int v15; // ecx@29
-  //int v16; // edi@30
-  //int v17; // edx@35
-  int v18; // eax@39
-  int v19; // eax@44
-  int v20; // ecx@44
-  //int v21; // edi@45
-  int v22; // edi@46
-  //__int16 *v23; // ecx@47
-  int v24; // edx@48
-  //int v25; // eax@50
-  int v26; // eax@55
-  signed int v27; // edi@55
-  //int v28; // edx@56
-  int v29; // edx@57
-  //int v30; // eax@59
-  int v31; // eax@64
-  signed int v32; // edi@64
-  //int v33; // edx@65
-  int v34; // eax@66
-  int v35; // dx@66
-  __int16 v36; // dx@67
-  __int16 v37; // di@67
-  __int16 v38; // dx@67
-  //BspRenderer_stru2 *v39; // ecx@69
-  //int v40; // edx@69
-  //int v41; // edi@70
-  //__int16 *v42; // eax@76
-  //__int16 *v43; // eax@81
-  //__int16 *v45; // eax@87
-  int v46; // edx@87
-  //__int16 v47; // cx@88
-  //int v48; // eax@93
-  int v49; // esi@93
-  //__int16 *v50; // ecx@94
-  //int v51; // eax@95
-  //int v52; // eax@97
-  int v53; // [sp+Ch] [bp-34h]@44
-  int v54; // [sp+10h] [bp-30h]@0
-  int v55; // [sp+14h] [bp-2Ch]@12
-  //__int16 *v56; // [sp+14h] [bp-2Ch]@47
-  //__int16 v57; // [sp+14h] [bp-2Ch]@76
-  //__int16 v58; // [sp+14h] [bp-2Ch]@81
-  int v59; // [sp+14h] [bp-2Ch]@87
-  //BspRenderer_stru2 *v60; // [sp+18h] [bp-28h]@1
-  int v61; // [sp+1Ch] [bp-24h]@29
-  int v62; // [sp+20h] [bp-20h]@0
-  signed int v63; // [sp+24h] [bp-1Ch]@3
-  signed int v64; // [sp+28h] [bp-18h]@3
-  int v65; // [sp+2Ch] [bp-14h]@5
-  //int v66; // [sp+2Ch] [bp-14h]@39
-  //int v67; // [sp+30h] [bp-10h]@22
-  int v68; // [sp+34h] [bp-Ch]@12
-  int v69; // [sp+34h] [bp-Ch]@29
-  int v70; // [sp+34h] [bp-Ch]@46
-  int v71; // [sp+34h] [bp-Ch]@75
-  int v72; // [sp+34h] [bp-Ch]@80
-  //int v73; // [sp+38h] [bp-8h]@11
-  //int v74; // [sp+3Ch] [bp-4h]@1
-  //int a3a; // [sp+48h] [bp+8h]@76
-  //int a3b; // [sp+48h] [bp+8h]@87
-
-  //try graphic engine with function returning 1 always, and without
-  //return true;
-  if ( pNumVertices <= 1 )
-    return false;
-  min_y = stru_50B700._screen_space_y[0];
-  v65 = 0;
-  max_y = stru_50B700._screen_space_y[0];
-  if ( !stru_50B700.field_0 )
-  {
-    v63 = 1;
-    v64 = -1;
-  }
-  else 
-  {
-    v63 = -1;
-    v64 = 1;
-  }
-
-  for ( v6 = 1; v6 < pNumVertices; ++v6 )
-  {
-    if ( stru_50B700._screen_space_y[v6] >= min_y )
-    {
-      if ( stru_50B700._screen_space_y[v6] > max_y )
-        max_y = stru_50B700._screen_space_y[v6];
-    }
-    if ( stru_50B700._screen_space_y[v6] < min_y )
-    {
-      v65 = v6;
-      min_y = stru_50B700._screen_space_y[v6];
-    }
-  }
-  if ( max_y == min_y )
-    return false;
-
-  v10 = v65;
-  a2->_viewport_space_y = min_y;
-  a2->_viewport_space_w = max_y;
-  v55 = v65;
-
-  for ( v68 = 0; v68 < pNumVertices; ++v68 )
-  {
-    v10 += v64;
-    if ( v10 < pNumVertices )
-    {
-      if ( v10 < 0 )
-        v10 += pNumVertices;
-    }
-    else
-      v10 -= pNumVertices;
-    if ( stru_50B700._screen_space_y[v10] <= stru_50B700._screen_space_y[v65] )
-    {
-      v55 = v10;
-      v65 = v10;
-    }
-    if ( stru_50B700._screen_space_y[v10] == max_y )
-      break;
-  }
-  v13 = v55 + v64;
-  if ( v13 < pNumVertices )
-  {
-    if ( v13 < 0 )
-      v13 += pNumVertices;
-  }
-  else
-    v13 -= pNumVertices;
-  if ( stru_50B700._screen_space_y[v13] != stru_50B700._screen_space_y[v55] )
-  {
-    v62 = stru_50B700._screen_space_x[v55] << 16;
-    v54 = ((stru_50B700._screen_space_x[v13] - stru_50B700._screen_space_x[v55]) << 16) / (stru_50B700._screen_space_y[v13] - stru_50B700._screen_space_y[v55]);
-    a2->viewport_left_side[min_y] = LOWORD(stru_50B700._screen_space_x[v55]);
-  }
-  v15 = v65;
-  v61 = v65;
-
-  for ( v69 = 0; v69 < pNumVertices; ++v69 )
-  {
-    v15 += v63;
-    if ( v15 < pNumVertices )
-    {
-      if ( v15 < 0 )
-        v15 += pNumVertices;
-    }
-    else
-      v15 -= pNumVertices;
-    if ( stru_50B700._screen_space_y[v15] <= stru_50B700._screen_space_y[v65] )
-    {
-      v61 = v15;
-      v65 = v15;
-    }
-    if ( stru_50B700._screen_space_y[v15] == max_y )
-      break;
-  }
-  v18 = v63 + v61;
-  if ( v18 < pNumVertices )
-  {
-    if ( v18 < 0 )
-      v18 += pNumVertices;
-  }
-  else
-    v18 -= pNumVertices;
-  v19 = v18;
-  v20 = v61;
-  if ( stru_50B700._screen_space_y[v19] != stru_50B700._screen_space_y[v61] )
-  {
-    v61 = stru_50B700._screen_space_x[v20] << 16;
-    v53 = ((stru_50B700._screen_space_x[v19] - stru_50B700._screen_space_x[v20]) << 16) / stru_50B700._screen_space_y[v19] - stru_50B700._screen_space_y[v20];
-    a2->viewport_right_side[max_y] = LOWORD(stru_50B700._screen_space_x[v20]);
-  }
-  v22 = min_y;
-  if ( min_y <= max_y )
-  {
-    //v56 = &a2->array_3D8[v7];
-    //v23 = &a2->array_18[v7];
-    for ( v70 = min_y; v70 <= max_y; ++v70 )
-    {
-      v24 = v13;
-      if ( v22 >= stru_50B700._screen_space_y[v13] && v22 != max_y )
-      {
-        v13 = v64 + v13;
-        if ( v13 < pNumVertices )
-        {
-          if ( v13 < 0 )
-            v13 += pNumVertices;
-        }
-        else
-          v13 -= pNumVertices;
-        v26 = v13;
-        //v27 = stru_50B700._screen_space_y[v26] - stru_50B700._screen_space_y[v24];
-        if ( stru_50B700._screen_space_y[v26] - stru_50B700._screen_space_y[v24] > 0 )
-        {
-          v54 = ((stru_50B700._screen_space_x[v26] - stru_50B700._screen_space_x[v24]) << 16) / stru_50B700._screen_space_y[v26] - stru_50B700._screen_space_y[v24];
-          v62 = stru_50B700._screen_space_x[v24] << 16;
-        }
-      }
-      v29 = v18;
-      if ( v70 >= stru_50B700._screen_space_y[v18] && v70 != max_y )
-      {
-        v18 += v63;
-        if ( v18 < pNumVertices )
-        {
-          if ( v18 < 0 )
-            v18 += pNumVertices;
-        }
-        else
-          v18 -= pNumVertices;
-        v31 = v18;
-        //v32 = stru_50B700._screen_space_y[v31] - stru_50B700._screen_space_y[v29];
-        if ( stru_50B700._screen_space_y[v31] - stru_50B700._screen_space_y[v29] > 0 )
-        {
-          v53 = ((stru_50B700._screen_space_x[v31] - stru_50B700._screen_space_x[v29]) << 16) / stru_50B700._screen_space_y[v31] - stru_50B700._screen_space_y[v29];
-          v61 = stru_50B700._screen_space_x[v29] << 16;
-        }
-      }
-	  //v34 = (char *)a2->array_18 - (char *)a2->array_3D8;
-	  //v35 = *(__int16 *)((char *)&a2->array_3D8[v70] + v34);
-      //v35 = HIWORD(v62);
-      a2->viewport_left_side[v70] = HIWORD(v62);
-      a2->viewport_right_side[v70] = HIWORD(v61);
-      //v34 = &a2->array_3D8[v70];
-      //v35 = a2->array_3D8[v70];
-      if ( a2->viewport_left_side[v70] > a2->viewport_right_side[v70] )
-      {
-        v36 = a2->viewport_left_side[v70] ^ a2->viewport_right_side[v70];
-        v37 = a2->viewport_right_side[v70];
-        a2->viewport_left_side[v70] = v36;
-        v38 = v37 ^ v36;
-        a2->viewport_left_side[v70] ^= v38;
-        a2->viewport_right_side[v70] = v38;
-      }
-      //++v56;
-      v62 += v54;
-      v22 = v70 + 1;
-      v61 += v53;
-      //++v23;
-    }
-  }
-  if ( max_y < a3->_viewport_space_y )
-    return false;
-  if ( min_y > a3->_viewport_space_w )
-    return false;
-  if ( min_y < a3->_viewport_space_y )
-    min_y = a3->_viewport_space_y;
-  if ( max_y > a3->_viewport_space_w )
-    max_y = a3->_viewport_space_w;
-  if ( min_y <= max_y )
-  {
-    //a3a = (char *)a2 - (char *)a3;
-    //v42 = &a3->array_3D8[v7];
-    //v57 = *(__int16 *)((char *)v42 + a3a);
-    for ( v71 = min_y; v71 <= max_y; ++v71 )
-    {
-      if ( a2->viewport_left_side[v71] >= a3->viewport_left_side[v71] && a2->viewport_left_side[v71] <= a3->viewport_right_side[v71] )
-        break;
-      //++v57;
-      ++min_y;
-      //++v42;
-    }
-  }
-  if ( max_y < min_y )
-    return false;
-  //a3a = (char *)a2 - (char *)a3;
-  //v43 = &a3->array_3D8[v8];
-  //v58 = *(__int16 *)((char *)v43 + a3a);
-  for ( v72 = max_y; v72 >= min_y; --v72 )
-  {
-    if ( a2->viewport_right_side[v72] >= a3->viewport_left_side[v72] && a2->viewport_left_side[v72] <= a3->viewport_right_side[v72] )
-      break;
-    //--v58;
-    --max_y;
-    //--v43;
-    //v8 = v8;
-  }
-  if ( min_y >= max_y )
-    return false;
-  //a3b = (char *)a3 - (char *)a2;
-  v59 = min_y;
-  //v45 = &a2->array_18[v7];
-  
-  for ( v46 = max_y - min_y + 1; v46; --v46 )
-  {
-    //v47 = *(__int16 *)((char *)v45 + a3b);
-    if ( a2->viewport_left_side[v59] < a3->viewport_left_side[v59] )
-      a2->viewport_left_side[v59] = a3->viewport_left_side[v59];
-    if ( a2->viewport_right_side[v59] > a3->viewport_right_side[v59] )
-      a2->viewport_right_side[v59] = a3->viewport_right_side[v59];
-    ++v59;
-    //++v45;
-  }
-  a2->_viewport_space_y = min_y;
-  a2->_viewport_space_w = max_y;
-  a2->field_8 = a2->viewport_left_side[min_y];
-  //v48 = a2->viewport_right_side[v7];
-  a2->field_10 = min_y;
-  a2->field_14 = min_y;
-  a2->field_C = a2->viewport_right_side[min_y];
-  v49 = min_y + 1;
-  if ( v49 <= max_y )
-  {
-    //v50 = &a2->array_3D8[v49];
-    for ( v49; v49 <= max_y; ++v49 )
-    {
-      //v51 = a2->array_18[v49];
-      if ( a2->viewport_left_side[v49] < a2->field_8 )
-      {
-        a2->field_8 = a2->viewport_left_side[v49];
-        a2->field_10 = v49;
-      }
-      if ( a2->viewport_right_side[v49] > a2->field_C )
-      {
-        a2->field_C = a2->viewport_right_side[v49];
-        a2->field_14 = v49;
-      }
-      //++v50;
-    }
-  }
-  return true;
-}
 // 50B700: using guessed type int stru_50B700.field_0;
 
 //----- (00424CD7) --------------------------------------------------------
--- a/mm7_2.cpp	Sun Jun 23 14:27:32 2013 +0600
+++ b/mm7_2.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -63,11 +63,10 @@
 #include "stru298.h"
 #include "Events2D.h"
 #include "Log.h"
-#include "UIHouses.h"
+#include "UI\UIHouses.h"
 #include "texts.h"
 #include "MM7.h"
 #include "Lights.h"
-#include "Arcomage.h"
 
 //----- (004BB756) --------------------------------------------------------
 signed int __fastcall sub_4BB756(signed int a1)
@@ -460,7 +459,6 @@
 }
 // F8B1B4: using guessed type int dword_F8B1B4;
 
-
 // 4EE088: using guessed type __int16 word_4EE088_sound_ids[];
 
 //----- (004BC109) --------------------------------------------------------
@@ -674,17 +672,6 @@
   pAudioPlayer->PlaySound((SoundID)14060, 0, 0, -1, 0, 0, 0, 0);
 }
 
-//----- (004BCA33) --------------------------------------------------------
-void UI_CreateEndConversationButton()
-{
-  pDialogueWindow->Release();
-  pDialogueWindow = GUIWindow::Create(0, 0, 640, 345, WINDOW_MainMenu, 0, 0);
-  pBtn_ExitCancel = pDialogueWindow->CreateButton( 471, 445,  169, 35, 1, 0, UIMSG_Escape,  0,  0,
-                 pGlobalTXT_LocalizationStrings[74],  //"End Conversation"
-                 pIcons_LOD->GetTexture(uExitCancelTextureId), 0);
-  pDialogueWindow->CreateButton(8, 8, 450, 320, 1, 0, UIMSG_BuyInShop_Identify_Repair, 0, 0, "", 0);
-}
-
 //----- (004BD8B5) --------------------------------------------------------
 signed int __cdecl sub_4BD8B5()
 {
@@ -783,24 +770,6 @@
   return 0;
 }
 
-//----- (004BE386) --------------------------------------------------------
-void __fastcall log_error(const char *pMessage)
-{
-  const char *v1; // edi@1
-  FILE *f; // eax@1
-  FILE *v3; // esi@1
-
-  v1 = pMessage;
-  f = fopen("errorlog.txt", "a");
-  v3 = f;
-  if ( f )
-  {
-    fprintf(f, "%s\n", v1);
-    fclose(v3);
-    fflush(v3);
-  }
-}
-
 //----- (004BF91E) --------------------------------------------------------
 unsigned int __thiscall GameOverMenu(void *ecx0)
 {
@@ -2804,6 +2773,62 @@
   }
 }
 
+//----- (00450B0A) --------------------------------------------------------
+bool __fastcall SpawnActor(unsigned int uMonsterID)
+{
+  unsigned int v1; // ebx@1
+  bool result; // eax@2
+  MonsterDesc *v3; // esi@5
+  MonsterInfo *v4; // edi@5
+  Vec3_int_ v5; // ST08_12@5
+  unsigned int v6; // ecx@5
+  Actor *v7; // eax@7
+  Actor actor; // [sp+4h] [bp-350h]@5
+  Vec3_int_ pOut; // [sp+348h] [bp-Ch]@5
+
+  v1 = uMonsterID;
+  if ( uNumActors == 499 )
+  {
+    result = 0;
+  }
+  else
+  {
+    if ( (signed int)uMonsterID >= (signed int)pMonsterList->uNumMonsters )
+      v1 = 0;
+    v3 = &pMonsterList->pMonsters[v1];
+    v4 = &pMonsterStats->pInfos[v1 + 1];
+    memset(&actor, 0, 0x344u);
+    strcpy(actor.pActorName, v4->pName);
+    actor.sCurrentHP = LOWORD(v4->uHP);
+    memcpy(&actor.pMonsterInfo, &pMonsterStats->pInfos[v1 + 1], 0x58u);
+    actor.word_000086_some_monster_id = v1 + 1;
+    actor.uActorRadius = v3->uMonsterRadius;
+    actor.uActorHeight = v3->uMonsterHeight;
+    actor.uMovementSpeed = v3->uMovementSpeed;
+    v5 = pParty->vPosition;
+    Vec3_int_::Rotate(200, pParty->sRotationY, 0, v5, &pOut.x, &pOut.z, &pOut.y);
+    actor.vInitialPosition.x = pOut.x;
+    actor.vPosition.x = pOut.x;
+    actor.uTetherDistance = 256;
+    actor.vInitialPosition.y = LOWORD(pOut.z);
+    actor.vPosition.y = LOWORD(pOut.z);
+    actor.vInitialPosition.z = LOWORD(pOut.y);
+    actor.vPosition.z = LOWORD(pOut.y);
+    pSprites_LOD->DeleteSomeSprites();
+    pPaletteManager->ResetNonTestLocked();
+    v6 = uNumActors - 1;
+    if ( dword_5C6DF8 == 1 )
+    {
+      dword_5C6DF8 = 0;
+      v6 = uNumActors++;
+    }
+    v7 = &pActors[v6];
+    memcpy(v7, &actor, 0x344u);
+    v7->PrepareSprites(1);
+    result = 1;
+  }
+  return result;
+}
 // 5C6DF8: using guessed type int dword_5C6DF8;
 
 //----- (00450DA3) --------------------------------------------------------
@@ -3735,213 +3760,120 @@
   }
 }
 
-//----- (004583B0) --------------------------------------------------------
-LevelDecoration::LevelDecoration()
-{
-  this->field_1A = 0;
-  this->field_18 = 0;
-  this->vPosition.z = 0;
-  this->vPosition.y = 0;
-  this->vPosition.x = 0;
-  this->uDecorationDescID = 0;
-  this->field_2 = 0;
-  this->field_16_event_id = 0;
-  this->uCog = 0;
-}
-
-//----- (0045E03A) --------------------------------------------------------
-unsigned short * MakeScreenshot( signed int width, signed int height )
+//----- (0045828B) --------------------------------------------------------
+unsigned int __fastcall GetSpellColor(signed int a1)
 {
-  //signed int v2; // edi@1
-  unsigned __int16 *v3; // ebx@1
-  int v4; // edx@7
-  unsigned __int8 v5; // cf@9
-  unsigned int v6; // ecx@9
-  unsigned __int16 *v7; // edi@9
-  int j; // ecx@9
-  //unsigned __int16 *v9; // edi@15
-  //int v10; // ecx@15
-  //LONG v11; // esi@15
-  //signed __int64 v12; // qax@18
-  //unsigned int v13; // ST10_4@21
-  HRESULT v14; // eax@21
-  int v15; // edi@29
-  signed __int64 v16; // qax@30
-  signed int v17; // edx@34
-  unsigned __int16 *v18; // edi@36
-  int k; // ecx@36
-  DDSURFACEDESC2 Dst; // [sp+4h] [bp-A0h]@6
-  unsigned __int16 *pPixels; // [sp+80h] [bp-24h]@1
-  float v23; // [sp+84h] [bp-20h]@1
-  unsigned __int16 *_this; // [sp+88h] [bp-1Ch]@21
-  float v25; // [sp+8Ch] [bp-18h]@1
-  unsigned int v26; // [sp+90h] [bp-14h]@17
-  //int v27; // [sp+94h] [bp-10h]@1
-  int v28; // [sp+98h] [bp-Ch]@16
-  int v29; // [sp+9Ch] [bp-8h]@15
-  //int v30; // [sp+A0h] [bp-4h]@1
-
-  //v30 = width;
-  //v2 = height;
-  //v27 = height;
-  v23 = game_viewport_width / (double)width;
-  v25 = game_viewport_height / (double)height;
-
-  pPixels = (unsigned __int16 *)malloc(2 * height * width);
-  memset(pPixels, 0 , 2 * height * width);
-
-  v3 = pPixels;
-  if ( pRenderer->pRenderD3D )
-  {
-    pRenderer->BeginSceneD3D();
-
-    if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
-      pIndoor->Draw();
-    else if (uCurrentlyLoadedLevelType == LEVEL_Outdoor)
-      pOutdoor->Draw();
-
-    pRenderer->DrawBillboards_And_MaybeRenderSpecialEffects_And_EndScene();
-    memset(&Dst, 0, 0x7Cu);
-    Dst.dwSize = sizeof(Dst);
-
-    if ( pRenderer->LockSurface_DDraw4(pRenderer->pBackBuffer4, &Dst, DDLOCK_WAIT) )
-    {
-      auto src = (unsigned __int16 *)Dst.lpSurface;
-      auto src_width = (Dst.lPitch / sizeof(short));
-      auto src_height = Dst.dwHeight;
-      auto dst = pPixels;
-      for (uint y = 0; y < height; ++y)
+  unsigned __int16 v1; // dx@3
+  unsigned __int16 v2; // cx@6
+  unsigned __int16 v4; // [sp-4h] [bp-4h]@3
+
+  if ( a1 < 1 )
+  {
+    if ( a1 < 12 )
+    {
+      if ( a1 < 23 )
       {
-        //uint src_y = (game_viewport_y + y * v25) * (Dst.lPitch / sizeof(short));
-        uint src_y = game_viewport_y + y * v25;
-        assert(game_viewport_y + y * v25 < src_height);
-        assert(y < height);
-
-        for (uint x = 0; x < width; ++x)
+        if ( a1 < 34 )
         {
-          //uint src_x = game_viewport_x + x * v23;
-          uint src_x = game_viewport_x + x * v23;
-          assert(src_x < src_width);
-          assert(x < width);
-
-          dst[y * width + x] = (((63*y)/117) << 5) | 31*x/155;//31*y/117;//src[src_y * src_width + src_x];
+          if ( a1 < 45 )
+          {
+            if ( a1 < 56 )
+            {
+              if ( a1 < 67 )
+              {
+                if ( a1 < 78 )
+                {
+                  if ( a1 < 89 )
+                    goto LABEL_31;
+                  goto LABEL_28;
+                }
+LABEL_25:
+                if ( a1 < 89 )
+                {
+                  v4 = 155;
+                  v2 = 255;
+                  goto LABEL_30;
+                }
+LABEL_28:
+                if ( a1 < 100 )
+                {
+                  v4 = 240;
+                  v2 = 192;
+                  goto LABEL_30;
+                }
+LABEL_31:
+                v4 = 0;
+                v1 = 0;
+                goto LABEL_32;
+              }
+LABEL_21:
+              if ( a1 < 78 )
+              {
+                v4 = 0;
+                v1 = 128;
+                goto LABEL_23;
+              }
+              goto LABEL_25;
+            }
+LABEL_18:
+            if ( a1 < 67 )
+            {
+              v4 = 255;
+              v1 = 15;
+              v2 = 235;
+              return TargetColor(v2, v1, v4);
+            }
+            goto LABEL_21;
+          }
+LABEL_15:
+          if ( a1 < 56 )
+          {
+            v2 = 225;
+            goto LABEL_13;
+          }
+          goto LABEL_18;
         }
+LABEL_11:
+        if ( a1 < 45 )
+        {
+          v2 = 128;
+LABEL_13:
+          v4 = v2;
+LABEL_30:
+          v1 = v2;
+          return TargetColor(v2, v1, v4);
+        }
+        goto LABEL_15;
       }
-      ErrD3D(pRenderer->pBackBuffer4->Unlock(0));
-    }
-    else
-    {
-      __debugbreak(); // unrefactored
-      v4 = height;
-      if ( height > 0 )
+LABEL_8:
+      if ( a1 < 34 )
       {
-        do
-        {
-          if ( width > 0 )
-          {
-            v5 = width & 1;
-            v6 = (unsigned int)width >> 1;
-            memset(v3, 0, 4 * ((unsigned int)width >> 1));
-            v7 = &v3[2 * v6];
-            for ( j = v5; j; --j )
-            {
-              *v7 = 0;
-              ++v7;
-            }
-            v3 += width;
-          }
-          --v4;
-        }
-        while ( v4 );
+        v4 = 255;
+        v1 = 128;
+LABEL_32:
+        v2 = 0;
+        return TargetColor(v2, v1, v4);
       }
+      goto LABEL_11;
     }
   }
   else
   {
-    pRenderer->BeginScene();
-    if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
-    {
-      pIndoor->Draw();
-    }
-    else
-    {
-      if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor )
-        pOutdoor->Draw();
-    }
-    _this = pRenderer->pTargetSurface;
-    v26 = pRenderer->uTargetSurfacePitch;
-    if ( pRenderer->pTargetSurface )
-    {
-      v29 = 0;
-      if ( height > 0 )
-      {
-        do
-        {
-          v28 = 0;
-          if ( width > 0 )
-          {
-            v15 = v26 * (unsigned __int64)(signed __int64)((double)v29 * v25 + 8.0);
-            do
-            {
-              v16 = (signed __int64)((double)v28++ * v23 + 8.0);
-              *v3 = _this[v15 + (int)v16];
-              ++v3;
-            }
-            while ( v28 < width );
-          }
-          ++v29;
-        }
-        while ( v29 < height );
-      }
-    }
-    else
-    {
-      if ( height > 0 )
-      {
-        v17 = height;
-        do
-        {
-          if ( width > 0 )
-          {
-            memset(v3, 0, 4 * ((unsigned int)width >> 1));
-            v18 = &v3[2 * ((unsigned int)width >> 1)];
-            for ( k = width & 1; k; --k )
-            {
-              *v18 = 0;
-              ++v18;
-            }
-            v3 += width;
-          }
-          --v17;
-        }
-        while ( v17 );
-      }
-    }
-    pRenderer->EndScene();
-  }
-  return pPixels;
-}
-
-//----- (0046080D) --------------------------------------------------------
-void __cdecl sub_46080D()
-{
-  pAllocator->FreeChunk(ptr_6A0D08);
-  ptr_6A0D08 = 0;
-  _6A0D0C_txt_lod_loading = 0;
-}
-
-//----- (0046082C) --------------------------------------------------------
-bool Initialize_GamesLOD_NewLOD()
-{
-  pGames_LOD = new LODWriteableFile;
-  pGames_LOD->AllocSubIndicesAndIO(300, 0);
-  if (pGames_LOD->LoadFile("data\\games.lod", 1))
-  {
-    pNew_LOD = new LODWriteableFile;
-    pNew_LOD->AllocSubIndicesAndIO(300, 100000);
-    return true;
-  }
-  return false;
+    if ( a1 < 12 )
+    {
+      v4 = 0;
+      v1 = 85;
+LABEL_23:
+      v2 = 255;
+      return TargetColor(v2, v1, v4);
+    }
+  }
+  if ( a1 >= 23 )
+    goto LABEL_8;
+  v4 = 255;
+  v1 = 212;
+  v2 = 150;
+  return TargetColor(v2, v1, v4);
 }
 
 //----- (004610AA) --------------------------------------------------------
@@ -4367,6 +4299,35 @@
   pIcons_LOD->_4114F2();
 }
 
+void set_stru1_field_8_InArcomage(int inValue)
+{
+  switch(inValue)
+  {
+  case 91:LOBYTE(pArcomageGame->stru1.field_8) = 123;break;
+  case 92:LOBYTE(pArcomageGame->stru1.field_8) = 124;break;
+  case 93:LOBYTE(pArcomageGame->stru1.field_8) = 125;break;
+  case 96:LOBYTE(pArcomageGame->stru1.field_8) = 126;break;
+  case 61:LOBYTE(pArcomageGame->stru1.field_8) = 43;break;
+  case 55:LOBYTE(pArcomageGame->stru1.field_8) = 38;break;
+  case 56:LOBYTE(pArcomageGame->stru1.field_8) = 42;break;
+  case 57:LOBYTE(pArcomageGame->stru1.field_8) = 40;break;
+  case 59:LOBYTE(pArcomageGame->stru1.field_8) = 58;break;
+  case 54:LOBYTE(pArcomageGame->stru1.field_8) = 94;break;
+  case 50:LOBYTE(pArcomageGame->stru1.field_8) = 64;break;
+  case 51:LOBYTE(pArcomageGame->stru1.field_8) = 35;break;
+  case 52:LOBYTE(pArcomageGame->stru1.field_8) = 36;break;
+  case 53:LOBYTE(pArcomageGame->stru1.field_8) = 37;break;
+  case 49:LOBYTE(pArcomageGame->stru1.field_8) = 33;break;
+  case 39:LOBYTE(pArcomageGame->stru1.field_8) = 34;break;
+  case 44:LOBYTE(pArcomageGame->stru1.field_8) = 60;break;
+  case 46:LOBYTE(pArcomageGame->stru1.field_8) = 62;break;
+  case 47:LOBYTE(pArcomageGame->stru1.field_8) = 63;break;
+  case 48:LOBYTE(pArcomageGame->stru1.field_8) = 41;break;
+  default:LOBYTE(pArcomageGame->stru1.field_8) = inValue;break;
+  }
+}
+
+
 //----- (004637EB) --------------------------------------------------------
 int __stdcall aWinProc(HWND hWnd, UINT Msg, WPARAM wParam, unsigned int lParam)
 {
@@ -6717,782 +6678,6 @@
 
 // 720980: using guessed type int uTextureID_720980;
 
-//----- (00467F9F) --------------------------------------------------------
-void __cdecl free_book_subwindow()
-{
-  if ( pGUIWindow_ScrollWindow )
-  {
-    pGUIWindow_ScrollWindow->Release();
-    pGUIWindow_ScrollWindow = 0;
-  }
-}
-
-//----- (00468F8A) --------------------------------------------------------
-void __cdecl OnPaperdollLeftClick()
-{
-  int v1; // ecx@1
-  unsigned int v2; // edi@1
-  unsigned int v3; // edx@4
-  unsigned int pSkillType; // esi@5
-  unsigned __int16 v5; // ax@7
-  unsigned int v6; // edi@19
-  int v7; // esi@27
-  unsigned int v8; // eax@29
-  int v9; // edx@32
-  int v10; // esi@34
-  int v11; // eax@34
-  int v12; // esi@38
-  int v13; // eax@38
-  char v14; // zf@38
-  int v15; // esi@42
-  int v16; // eax@42
-  int v17; // eax@44
-  unsigned int v18; // ecx@55
-  unsigned int v19; // eax@55
-  int v20; // esi@60
-  int v21; // eax@60
-  unsigned int v22; // eax@61
-  unsigned int v23; // eax@62
-  int v24; // esi@65
-  int v25; // eax@65
-  unsigned int v26; // eax@69
-  int v27; // esi@81
-  int v28; // eax@81
-  int v29; // esi@84
-  int v30; // eax@84
-  int v31; // eax@85
-  unsigned int v32; // ecx@88
-  unsigned int v33; // eax@88
-  int v34; // esi@90
-  unsigned int v35; // eax@91
-  int v36; // esi@93
-  int v37; // edi@93
-  ItemGen *v38; // edi@93
-  __int16 v39; // dx@99
-  ItemGen _this; // [sp+Ch] [bp-40h]@1
-  unsigned int v48; // [sp+30h] [bp-1Ch]@88
-  unsigned int v49; // [sp+34h] [bp-18h]@57
-  unsigned int v50; // [sp+38h] [bp-14h]@50
-  int v51; // [sp+3Ch] [bp-10h]@1
-  unsigned int v52; // [sp+40h] [bp-Ch]@5
-  //int v53; // [sp+44h] [bp-8h]@1
-  //unsigned int v54; // [sp+48h] [bp-4h]@1
-
-  v51 = 0;
-  _this.Reset();
-  //v0 = pPlayers[uActiveCharacter];
-  v1 = pPlayers[uActiveCharacter]->pEquipment.uMainHand;
-  v2 = pPlayers[uActiveCharacter]->pEquipment.uShield;
-  //v54 = pPlayers[uActiveCharacter]->pEquipment.uShield;
-  //v53 = v1;
-  if ( v1 && pItemsTable->pItems[*(int *)&pPlayers[uActiveCharacter]->pInventoryItems[v1 - 1]].uEquipType == 1 )
-    v51 = v1;
-  v3 = pParty->pPickedItem.uItemID;
-  if ( pParty->pPickedItem.uItemID )
-  {
-    v52 = pItemsTable->pItems[pParty->pPickedItem.uItemID].uEquipType;
-    pSkillType = pItemsTable->pItems[pParty->pPickedItem.uItemID].uSkillType;
-    if ( pSkillType == 4 )
-    {
-      if ( v2 )
-      {
-        LOBYTE(v5) = pPlayers[uActiveCharacter]->GetActualSkillLevel(PLAYER_SKILL_SPEAR);
-        if ( (signed int)SkillToMastery(v5) < 3 )
-        {
-          pPlayers[uActiveCharacter]->PlaySound(SPEECH_39, 0);
-          return;
-        }
-        v3 = pParty->pPickedItem.uItemID;
-      }
-    }
-    else
-    {
-      if ( (pSkillType == 8 || pSkillType == 1 || pSkillType == 2)
-        && v1
-        && pItemsTable->pItems[*(int *)&pPlayers[uActiveCharacter]->pInventoryItems[v1-1]].uSkillType == 4 )
-	  {
-        LOBYTE(v5) = pPlayers[uActiveCharacter]->GetActualSkillLevel(PLAYER_SKILL_SPEAR);
-        if ( (signed int)SkillToMastery(v5) < 3 )
-        {
-          pPlayers[uActiveCharacter]->PlaySound(SPEECH_39, 0);
-          return;
-        }
-	  }
-    }
-    if ( !pPlayers[uActiveCharacter]->CanEquip_RaceAndAlignmentCheck(v3) )
-    {
-
-        pPlayers[uActiveCharacter]->PlaySound(SPEECH_39, 0);
-        return;
-    }
-    if ( pParty->pPickedItem.uItemID == 604 )
-    {
-      pPlayers[uActiveCharacter]->EquipBody((ITEM_EQUIP_TYPE)3);
-      WetsuitOn(uActiveCharacter);
-      return;
-    }
-    v6 = v52;
-    switch ( v52 )
-    {
-      case 2u:
-      case 3u:
-      case 5u:
-      case 6u:
-      case 7u:
-      case 8u:
-      case 9u:
-      case 0xBu:
-        if ( !pPlayers[uActiveCharacter]->HasSkill(pSkillType) )
-        {
-          pPlayers[uActiveCharacter]->PlaySound(SPEECH_39, 0);
-          return;
-        }
-        if ( sub_43EE77_ProbablyIfUnderwaterSuitIsEquipped(uActiveCharacter) && (v6 != 3 || bUnderwater) )
-		{
-			pAudioPlayer->PlaySound(SOUND_27, 0, 0, -1, 0, 0, 0, 0);
-			return;
-		}
-        pPlayers[uActiveCharacter]->EquipBody((ITEM_EQUIP_TYPE)v6);
-        if ( pParty->pPickedItem.uItemID == 604 )
-          WetsuitOff(uActiveCharacter);
-        return;
-      case 0xAu:
-        if ( sub_43EE77_ProbablyIfUnderwaterSuitIsEquipped(uActiveCharacter) )
-		{
-			pAudioPlayer->PlaySound(SOUND_27, 0, 0, -1, 0, 0, 0, 0);
-			return;
-		}
-        v52 = 10;
-        v7 = (int)&pPlayers[uActiveCharacter]->pEquipment.uRings;
-        while ( 1 )
-        {
-          if ( !*(int *)v7 )
-          {
-            v8 = pPlayers[uActiveCharacter]->FindFreeInventorySlot();
-            if ( (v8 & 0x80000000u) == 0 )
-			{
-			  v9 = v52;
-			  pParty->pPickedItem.uBodyAnchor = v52 + 1;
-			  memcpy(&pPlayers[uActiveCharacter]->pInventoryItems[v8], &pParty->pPickedItem, sizeof(pPlayers[uActiveCharacter]->pInventoryItems[v8]));
-			  *(&pPlayers[uActiveCharacter]->pEquipment.uShield + v9) = v8 + 1;
-			  pMouse->RemoveHoldingItem();
-              break;
-			}
-          }
-          ++v52;
-          v7 += 4;
-          if ( (signed int)v52 > 15 )
-            break;
-        }
-        if ( v52 == 16 )
-        {
-          v52 = pPlayers[uActiveCharacter]->pEquipment.uRings[6] - 1;
-          memcpy(&_this, &pParty->pPickedItem, sizeof(_this));
-          v10 = (int)((char *)pPlayers[uActiveCharacter] + 36 * v52);
-          *(char *)(v10 + 556) = 0;
-          pParty->pPickedItem.Reset();
-          pParty->SetHoldingItem((ItemGen *)(v10 + 532));
-          _this.uBodyAnchor = 16;
-          v11 = v52 + 1;
-          memcpy((void *)(v10 + 532), &_this, 0x24u);
-          pPlayers[uActiveCharacter]->pEquipment.uRings[6] = v11;
-        }
-        return;
-      case 4u:
-        if ( sub_43EE77_ProbablyIfUnderwaterSuitIsEquipped(uActiveCharacter) )
-		{
-			pAudioPlayer->PlaySound(SOUND_27, 0, 0, -1, 0, 0, 0, 0);
-			return;
-		}
-        if ( !pPlayers[uActiveCharacter]->HasSkill(pSkillType) )
-        {
-          pPlayers[uActiveCharacter]->PlaySound(SPEECH_39, 0);
-          return;
-        }
-        if ( v2 )
-        {
-          --v2;
-          memcpy(&_this, &pParty->pPickedItem, sizeof(_this));
-          v12 = (int)((char *)pPlayers[uActiveCharacter] + 36 * v2);
-          *(char *)(v12 + 556) = 0;
-          pParty->pPickedItem.Reset();
-          pParty->SetHoldingItem((ItemGen *)(v12 + 532));
-          _this.uBodyAnchor = 1;
-          v13 = v2 + 1;
-          v14 = v51 == 0;
-          memcpy((void *)(v12 + 532), &_this, 0x24u);
-          pPlayers[uActiveCharacter]->pEquipment.uShield = v13;
-          if ( v14 )
-            return;
-        }
-        else
-        {
-          v52 = pPlayers[uActiveCharacter]->FindFreeInventorySlot();
-          if ( (v52 & 0x80000000u) != 0 )
-            return;
-          if ( !v51 )
-          {
-            pParty->pPickedItem.uBodyAnchor = 1;
-            v17 = v52 + 1;
-            memcpy(&pPlayers[uActiveCharacter]->pInventoryItems[v52], &pParty->pPickedItem, sizeof(pPlayers[uActiveCharacter]->pInventoryItems[v52]));
-            pPlayers[uActiveCharacter]->pEquipment.uShield = v17;
-            pMouse->RemoveHoldingItem();
-	        return;
-          }
-          memcpy(&_this, &pParty->pPickedItem, sizeof(_this));
-          v15 = (int)((char *)pPlayers[uActiveCharacter] + 36 * (v1 - 1));
-          *(char *)(v15 + 556) = 0;
-          pParty->pPickedItem.Reset();
-          pParty->SetHoldingItem((ItemGen *)(v15 + 532));
-          _this.uBodyAnchor = 1;
-          v16 = v52 + 1;
-          memcpy(&pPlayers[uActiveCharacter]->pInventoryItems[v52], &_this, sizeof(pPlayers[uActiveCharacter]->pInventoryItems[v52]));
-          pPlayers[uActiveCharacter]->pEquipment.uShield = v16;
-        }
-        pPlayers[uActiveCharacter]->pEquipment.uMainHand = 0;
-        return;
-      case 0u:
-      case 0xCu:
-        if ( sub_43EE77_ProbablyIfUnderwaterSuitIsEquipped(uActiveCharacter)
-          && pParty->pPickedItem.uItemID != 64
-          && pParty->pPickedItem.uItemID != 65 )
-		{
-			pAudioPlayer->PlaySound(SOUND_27, 0, 0, -1, 0, 0, 0, 0);
-			return;
-		}
-        if ( !pPlayers[uActiveCharacter]->HasSkill(pSkillType) )
-        {
-          pPlayers[uActiveCharacter]->PlaySound(SPEECH_39, 0);
-          return;
-        }
-        v50 = 0;
-        if ( pSkillType == 2 && (unsigned __int16)(pPlayers[uActiveCharacter]->pActiveSkills[2] & 0xFFC0)
-          || pSkillType == 1 && (signed int)SkillToMastery(pPlayers[uActiveCharacter]->pActiveSkills[1]) >= 3 )
-        {
-
-            v18 = pMouse->uMouseClickX;
-            v19 = pMouse->uMouseClickY;
-
-          v49 = v19;
-          if ( (signed int)v18 >= 560 )
-          {
-            if ( !v51 )
-            {
-              if ( v2 )
-              {
-                --v2;
-                memcpy(&_this, &pParty->pPickedItem, sizeof(_this));
-                v20 = (int)((char *)pPlayers[uActiveCharacter] + 36 * v2);
-                *(char *)(v20 + 556) = 0;
-                pParty->pPickedItem.Reset();
-                pParty->SetHoldingItem((ItemGen *)(v20 + 532));
-                _this.uBodyAnchor = 1;
-                v21 = v2 + 1;
-                v14 = v52 == 12;
-                memcpy((void *)(v20 + 532), &_this, 0x24u);
-                pPlayers[uActiveCharacter]->pEquipment.uShield = v21;
-                if ( !v14 )
-                  return;
-                v22 = _this.uItemID;
-                v50 = v22;
-				if ( v50 )
-                {
-                __debugbreak();  // looks like offset in player's inventory and wand_lut much like case in 0042ECB5
-				  stru_A750F8[uActiveCharacter - 1]._494836(*((int *)&pSpellDatas[66].uNormalLevelRecovery + v50), uActiveCharacter - 1 + 9);
-                }
-				break;
-              }
-              v23 = pPlayers[uActiveCharacter]->FindFreeInventorySlot();
-              if ( (v23 & 0x80000000u) != 0 )
-                return;
-              pParty->pPickedItem.uBodyAnchor = 1;
-              v50 = (unsigned int)&pPlayers[uActiveCharacter]->pInventoryItems[v23];
-              memcpy(&pPlayers[uActiveCharacter]->pInventoryItems[v23], &pParty->pPickedItem, sizeof(pPlayers[uActiveCharacter]->pInventoryItems[v23]));
-              pPlayers[uActiveCharacter]->pEquipment.uShield = v23 + 1;
-              pMouse->RemoveHoldingItem();
-              if ( v52 != 12 )
-                return;
-              v22 = *(int *)v50;
-			  v50 = v22;
-			  if ( v50 )
-              {
-                __debugbreak();  // looks like offset in player's inventory and wand_lut much like case in 0042ECB5
-				stru_A750F8[uActiveCharacter - 1]._494836(*((int *)&pSpellDatas[66].uNormalLevelRecovery + v50), uActiveCharacter - 1 + 9);
-              }
-			  break;
-            }
-          }
-        }
-        if ( !v1 )
-        {
-          v26 = pPlayers[uActiveCharacter]->FindFreeInventorySlot();
-          if ( (v26 & 0x80000000u) != 0 )
-            return;
-          pParty->pPickedItem.uBodyAnchor = 2;
-          v50 = (unsigned int)&pPlayers[uActiveCharacter]->pInventoryItems[v26];
-          memcpy(&pPlayers[uActiveCharacter]->pInventoryItems[v26], &pParty->pPickedItem, sizeof(pPlayers[uActiveCharacter]->pInventoryItems[v26]));
-          pPlayers[uActiveCharacter]->pEquipment.uMainHand = v26 + 1;
-              pMouse->RemoveHoldingItem();
-              if ( v52 != 12 )
-                return;
-              v22 = *(int *)v50;
-			  v50 = v22;
-			  if ( v50 )
-              {
-                __debugbreak();  // looks like offset in player's inventory and wand_lut much like case in 0042ECB5
-				stru_A750F8[uActiveCharacter - 1]._494836(*((int *)&pSpellDatas[66].uNormalLevelRecovery + v50), uActiveCharacter - 1 + 9);
-              }
-			  break;
-        }
-        --v1;
-        memcpy(&_this, &pParty->pPickedItem, sizeof(_this));
-        v24 = (int)((char *)pPlayers[uActiveCharacter] + 36 * v1);
-        *(char *)(v24 + 556) = 0;
-        pParty->pPickedItem.Reset();
-        pParty->SetHoldingItem((ItemGen *)(v24 + 532));
-        _this.uBodyAnchor = 2;
-        v25 = v1 + 1;
-        v14 = v52 == 12;
-        memcpy((void *)(v24 + 532), &_this, 0x24u);
-        pPlayers[uActiveCharacter]->pEquipment.uMainHand = v25;
-        if ( v14 )
-          v50 = _this.uItemID;
-        if ( v51 )
-          pPlayers[uActiveCharacter]->pEquipment.uShield = 0;
-        if ( v50 )
-        {
-                __debugbreak();  // looks like offset in player's inventory and wand_lut much like case in 0042ECB5
-          stru_A750F8[uActiveCharacter - 1]._494836( *((int *)&pSpellDatas[66].uNormalLevelRecovery + v50), uActiveCharacter - 1 + 9);
-        }
-        break;
-      case 1u:
-        if ( sub_43EE77_ProbablyIfUnderwaterSuitIsEquipped(uActiveCharacter) )
-		{
-			pAudioPlayer->PlaySound(SOUND_27, 0, 0, -1, 0, 0, 0, 0);
-			return;
-		}
-        if ( !pPlayers[uActiveCharacter]->HasSkill(pSkillType) )
-        {
-          pPlayers[uActiveCharacter]->PlaySound(SPEECH_39, 0);
-          return;
-        }
-        if ( v1 )
-        {
-          if ( v2 )
-          {
-			pAudioPlayer->PlaySound(SOUND_27, 0, 0, -1, 0, 0, 0, 0);
-			return;
-          }
-          --v1;
-          memcpy(&_this, &pParty->pPickedItem, sizeof(_this));
-          v27 = (int)((char *)pPlayers[uActiveCharacter] + 36 * v1);
-          *(char *)(v27 + 556) = 0;
-          pParty->pPickedItem.Reset();
-          pParty->SetHoldingItem((ItemGen *)(v27 + 532));
-          _this.uBodyAnchor = 2;
-          v28 = v1 + 1;
-          memcpy((void *)(v27 + 532), &_this, 0x24u);
-          pPlayers[uActiveCharacter]->pEquipment.uMainHand = v28;
-        }
-        else
-        {
-          v52 = pPlayers[uActiveCharacter]->FindFreeInventorySlot();
-          if ( (v52 & 0x80000000u) == 0 )
-          {
-            if ( v2 )
-            {
-              memcpy(&_this, &pParty->pPickedItem, sizeof(_this));
-              v29 = (int)((char *)pPlayers[uActiveCharacter] + 36 * (v2 - 1));
-              *(char *)(v29 + 556) = 0;
-              pParty->pPickedItem.Reset();
-              pParty->SetHoldingItem((ItemGen *)(v29 + 532));
-              _this.uBodyAnchor = 2;
-              v30 = v52 + 1;
-              memcpy(&pPlayers[uActiveCharacter]->pInventoryItems[v52], &_this, sizeof(pPlayers[uActiveCharacter]->pInventoryItems[v52]));
-              pPlayers[uActiveCharacter]->pEquipment.uShield = 0;
-              pPlayers[uActiveCharacter]->pEquipment.uMainHand = v30;
-            }
-            else
-            {
-              pParty->pPickedItem.uBodyAnchor = 2;
-              v31 = v52 + 1;
-              memcpy(&pPlayers[uActiveCharacter]->pInventoryItems[v52], &pParty->pPickedItem, sizeof(pPlayers[uActiveCharacter]->pInventoryItems[v52]));
-              pPlayers[uActiveCharacter]->pEquipment.uMainHand = v31;
-              pMouse->RemoveHoldingItem();
-            }
-          }
-        }
-        return;
-      default:
-        pPlayers[uActiveCharacter]->UseItem_DrinkPotion_etc(uActiveCharacter, 0);
-        return;
-    }
-    return;
-  }
-
-    v32 = pMouse->uMouseClickX;
-    v33 = pMouse->uMouseClickY;
-
-  v34 = pRenderer->pActiveZBuffer[v32 + pSRZBufferLineOffsets[v33]] & 0xFFFF;
-  if ( v34 )
-  {
-    v36 = v34 - 1;
-    v37 = (int)((char *)pPlayers[uActiveCharacter] + 36 * v36);
-    v50 = v37;
-    v38 = (ItemGen *)(v37 + 532);
-    v14 = v38->uItemID == 604;
-    v52 = pItemsTable->pItems[v38->uItemID].uEquipType;
-    if ( v14 )
-    {
-      if ( bUnderwater )
-      {
-        pAudioPlayer->PlaySound(SOUND_27, 0, 0, -1, 0, 0, 0, 0);
-        return;
-      }
-      WetsuitOff(uActiveCharacter);
-    }
-    if ( unk_50C9A0 )
-    {
-      *((char *)pGUIWindow_Settings->ptr_1C + 8) &= 0x7Fu;
-      *((short *)pGUIWindow_Settings->ptr_1C + 2) = uActiveCharacter - 1;
-      v39 = v52;
-      *((int *)pGUIWindow_Settings->ptr_1C + 3) = v36;
-      *((short *)pGUIWindow_Settings->ptr_1C + 3) = v39;
-      ptr_50C9A4 = v38;
-      unk_50C9A0 = 0;
-      if ( pMessageQueue_50CBD0->uNumMessages )
-        pMessageQueue_50CBD0->uNumMessages = pMessageQueue_50CBD0->pMessages[0].field_8 != 0;
-      pMouse->SetCursorBitmap("MICON1");
-      dword_50C9D4 = 0;
-      dword_50C9D0 = 113;
-      dword_50C9D8 = 256;
-    }
-    else
-    {
-      if ( !ptr_50C9A4 )
-      {
-        pParty->SetHoldingItem(v38);
-        *(&pPlayers[uActiveCharacter]->uBirthYear + *(char *)(v50 + 556)) = 0;
-        v38->Reset();
-      }
-    }
-  }
-  else
-  {
-    v35 = pPlayers[uActiveCharacter]->pEquipment.uBow;
-    if ( v35 )
-    {
-      auto _a = (ItemGen *)&pPlayers[uActiveCharacter]->pInventoryItems[v35 - 1];
-      pParty->SetHoldingItem(_a);
-      _a->Reset();
-      pPlayers[uActiveCharacter]->pEquipment.uBow = 0;
-    }
-  }
-}
-
-
-//----- (0046A14B) --------------------------------------------------------
-void OnPressSpace()
-{
-  //SHORT v0; // ax@2
-  int *v1; // eax@2
-  char *v2; // ebx@5
-  unsigned int v3; // esi@5
-  signed int v4; // edi@7
-  unsigned int v5; // edx@7
-  int v6; // ecx@8
-  int v7; // eax@8
-  int v8; // ecx@17
-  int *v9; // esi@22
-  signed int v10; // ebx@22
-  int i; // edi@23
-  int v12; // edx@24
-  int v13; // ecx@24
-  int j; // esi@28
-  int v16; // [sp+4h] [bp-1Ch]@0
-  char *v17; // [sp+8h] [bp-18h]@5
-  unsigned int v18; // [sp+Ch] [bp-14h]@5
-  int v19; // [sp+10h] [bp-10h]@8
-  int *v20; // [sp+14h] [bp-Ch]@5
-  int *v21; // [sp+18h] [bp-8h]@7
-  int v22; // [sp+1Ch] [bp-4h]@4
-
-  if ( pRenderer->pRenderD3D )
-  {
-    pGame->PickKeyboard(GetAsyncKeyState(VK_CONTROL) & 0x8001, &vis_sprite_filter_3, &vis_door_filter);
-    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
-  if ( (signed int)viewparams->uScreen_topL_Y < (signed int)viewparams->uScreen_BttmR_Y )
-  {
-	  v2 = (char *)v1 - 50;
-	  v1 = (int *)((char *)v1 + 50);
-	  v3 = 640 * viewparams->uScreen_topL_Y;
-	  v17 = v2;
-	  v20 = v1;
-	  v18 = ((viewparams->uScreen_BttmR_Y - viewparams->uScreen_topL_Y - 1) >> 1) + 1;
-	  do
-	  {
-		if ( (signed int)v2 < (signed int)v20 )
-		{
-			v1 = &pRenderer->pActiveZBuffer[(int)&v2[v3]];
-			v21 = &pRenderer->pActiveZBuffer[(int)&v2[v3]];
-			v4 = v22;
-			v5 = (((char *)v20 - v2 - 1) >> 1) + 1;
-			do
-			{
-			  v6 = 0;
-			  v7 = *v1 & 0xFFFF;
-			  v19 = 0;
-			  if ( v4 > 0 )
-			  {
-				do
-				{
-				  if ( dword_7207F0[v6] == v7 )
-					break;
-				  ++v6;
-				  v19 = v6;
-				}
-				while ( v6 < v22 );
-			  }
-			  if ( PID_TYPE(v7) == OBJECT_Decoration)
-			  {
-				v16 = (unsigned int)PID_ID(v7);
-				if ( (signed int)(((unsigned int)*v21 >> 16)
-								- pDecorationList->pDecorations[pLevelDecorations[(unsigned int)PID_ID(v7)].uDecorationDescID].uRadius) <= 512 )
-				  if ( v19 == v22 && v4 < 100 )
-				  {
-					++v22;
-					++v4;
-					v8 = *v21;
-					dword_7207F0[v4 - 1] = v7;
-					dword_720660[v4 - 1] = v8;
-				  }
-			  }
-			  else if ( (unsigned int)*v21 <= 0x2000000 )
-			  {
-				  if ( v19 == v22 && v4 < 100 )
-				  {
-					++v22;
-					++v4;
-					v8 = *v21;
-					dword_7207F0[v4 - 1] = v7;
-					dword_720660[v4 - 1] = v8;
-				  }
-			  }
-			  v1 = v21 + 2;
-			  --v5;
-			  v21 += 2;
-			}
-			while ( v5 );
-			v2 = v17;
-		}
-		v3 += 1280;
-		--v18;
-	  }
-	  while ( v18 );
-  }
-  if ( v22 > 0 )
-  {
-    v9 = dword_720660;
-    v10 = 1;
-    do
-    {
-      for ( i = v10; i < v22; ++i )
-      {
-        v12 = *v9;
-        v13 = dword_720660[i];
-        if ( v13 < *v9 )
-        {
-          *v9 = v13;
-          dword_720660[i] = v12;
-        }
-      }
-      ++v10;
-      ++v9;
-      LOBYTE(v1) = v10 - 1;
-    }
-    while ( v10 - 1 < v22 );
-  }
-  for ( j = 0; j < v22; ++j )
-  {
-    LOBYTE(v1) = DoInteractionWithTopmostZObject(dword_720660[j] & 0xFFFF, v16);
-    if ( !(char)v1 )
-      break;
-  }
-}
-
-//----- (0046A334) --------------------------------------------------------
-char __fastcall DoInteractionWithTopmostZObject(int a1, int a2)
-{
-  int v2; // edx@1
-  BLVFace *v4; // eax@9
-  unsigned int v5; // ecx@9
-  unsigned __int16 v6; // ax@11
-  //ODMFace *v7; // eax@16
-  LevelDecoration *v8; // esi@19
-  __int16 v9; // ax@19
-  int v10; // eax@22
-  int v11; // ecx@22
-  int v12; // edi@23
-  Actor *v13; // esi@23
-  unsigned __int16 v14; // ax@23
-  unsigned __int16 v15; // ax@33
-  const char *v16; // eax@34
-  int v17; // edi@36
-  int v18; // eax@36
-  ItemGen *v19; // esi@39
-  unsigned int v20; // eax@39
-  int v21; // ecx@40
-  std::string v22; // [sp-18h] [bp-2Ch]@5
-  const char *v23; // [sp-8h] [bp-1Ch]@5
-  int v24; // [sp-4h] [bp-18h]@5
-  char v25; // [sp+8h] [bp-Ch]@5
-  int v26; // [sp+Ch] [bp-8h]@1
-  int a3; // [sp+13h] [bp-1h]@5
-
-  v26 = a2;
-  v2 = a1;
-  switch ( PID_TYPE(a1) )
-  {
-    case OBJECT_Item: // take the item
-      v17 = PID_ID(a1);
-      v26 = PID_ID(a1);
-      v18 = PID_ID(a1);
-      if ( pObjectList->pObjects[pSpriteObjects[v18].uObjectDescID].uFlags & 0x10
-        || v17 >= 1000
-        || !pSpriteObjects[v18].uObjectDescID )
-        return 1;
-      v19 = &pSpriteObjects[v18].stru_24;
-      v20 = pSpriteObjects[v18].stru_24.uItemID;
-      if ( pItemsTable->pItems[v20].uEquipType == EQUIP_GOLD)
-      {
-        party_finds_gold(v19->uSpecEnchantmentType, 0);
-        viewparams->bRedrawGameUI = 1;
-        v21 = v17;
-      }
-      else
-      {
-        if ( pParty->pPickedItem.uItemID )
-          return 1;
-        v24 = (int)pItemsTable->pItems[v20].pUnidentifiedName;
-        sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[471], v24);
-        ShowStatusBarString(pTmpBuf2.data(), 2u);
-        if ( v19->uItemID == 506 )
-          _449B7E_toggle_bit(pParty->_quest_bits, 184, 1u);
-        if ( v19->uItemID == 455 )
-          _449B7E_toggle_bit(pParty->_quest_bits, 185, 1u);
-        if ( !pParty->AddItem(v19) )
-          pParty->SetHoldingItem(v19);
-        v21 = v26;
-      }
-      SpriteObject::OnInteraction(v21);
-      break;
-
-    case OBJECT_Actor:
-      v12 = PID_ID(a1);
-      v13 = &pActors[PID_ID(a1)];
-      v14 = v13->uAIState;
-      if ( v14 == 4 || v14 == 17 )
-        return 1;
-      if ( v14 == 5 )
-      {
-        stru_50C198.LootActor(&pActors[PID_ID(a1)]);
-      }
-      else
-      {
-        if ( !v13->GetActorsRelation(0) && !(BYTE2(v13->uAttributes) & 8) && v13->CanAct() )
-        {
-          Actor::AI_FaceObject(v12, 4u, 0, 0);
-          if ( v13->sNPC_ID )
-          {
-            pMessageQueue_50CBD0->AddMessage(UIMSG_StartNPCDialogue, v12, 0);
-          }
-          else
-          {
-            v15 = pNPCStats->pGroups_copy[v13->uGroup];
-            if ( v15 )
-            {
-              v16 = pNPCStats->pCatchPhrases[v15];
-              if ( v16 )
-              {
-                pParty->uFlags |= 2u;
-                strcpy(byte_5B0938.data(), v16);
-                sub_4451A8_press_any_key(0, 0, 0);
-              }
-            }
-          }
-        }
-      }
-      break;
-
-    case OBJECT_Decoration:
-      v8 = &pLevelDecorations[PID_ID(a1)];
-      v9 = v8->field_16_event_id;
-      if ( v9 )
-      {
-        EventProcessor(v9, a1, 1);
-        LOBYTE(v8->field_2) |= 8u;
-      }
-      else
-      {
-        if ( !pLevelDecorations[PID_ID(a1)].IsInteractive() )
-          return 1;
-        v10 = v8->_idx_in_stru123;
-        v24 = 1;
-        v11 = stru_5E4C90._decor_events[v10 - 75] + 380;
-        activeLevelDecoration = v8;
-        EventProcessor(v11, 0, 1);
-        activeLevelDecoration = NULL;
-      }
-      break;
-
-    default:
-      MessageBoxW(nullptr, L"Warning: Invalid ID reached!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Mouse.cpp:2020", 0);
-      return 1;
-
-    case OBJECT_BModel:
-      if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor )
-      {
-        int bmodel_id = a1 >> 9,
-            face_id = PID_ID(a1) & 0x3F;
-        if (bmodel_id >= pOutdoor->uNumBModels)
-          return 1;
-        auto face = &pOutdoor->pBModels[bmodel_id].pFaces[face_id];
-        if (face->uAttributes & 0x100000 || face->sCogTriggeredID == 0 )
-          return 1;
-        EventProcessor((signed __int16)face->sCogTriggeredID, v2, 1);
-      }
-      else
-      {
-        v4 = &pIndoor->pFaces[PID_ID(a1)];
-        v5 = v4->uAttributes;
-        if ( !(v5 & 0x2000000) )
-        {
-          ShowNothingHereStatus();
-          return 1;
-        }
-        if ( v5 & 0x100000 || (v6 = pIndoor->pFaceExtras[v4->uFaceExtraID].uEventID) == 0 )
-          return 1;
-        if ( pCurrentScreen != SCREEN_BRANCHLESS_NPC_DIALOG )
-          EventProcessor((signed __int16)v6, v2, 1);
-      }
-      return 0;
-      break;
-  }
-  return 0;
-}
 // 4E28F8: using guessed type int pCurrentScreen;
 
 //----- (0046A6AC) --------------------------------------------------------
--- a/mm7_3.cpp	Sun Jun 23 14:27:32 2013 +0600
+++ b/mm7_3.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -3856,29 +3856,6 @@
 }
 // 47730C: using guessed type int __stdcall const_1(int);
 
-//----- (0047752B) --------------------------------------------------------
-int __cdecl GetPartyReputation()
-{
-  DDM_DLV_Header *v0; // ebx@1
-  signed int v1; // esi@3
-
-  v0 = &pOutdoor->ddm;
-  if ( uCurrentlyLoadedLevelType != LEVEL_Outdoor )
-    v0 = &pIndoor->dlv;
-  v1 = 0;
-  if ( CheckHiredNPCSpeciality(Pirate) )
-    v1 += 5;
-  if ( CheckHiredNPCSpeciality(Burglar) )
-    v1 += 5;
-  if ( CheckHiredNPCSpeciality(Gypsy) )
-    v1 += 5;
-  if ( CheckHiredNPCSpeciality(Duper) )
-    v1 += 5;
-  if ( CheckHiredNPCSpeciality(FallenWizard) )
-    v1 += 5;
-  return v1 + v0->uReputation;
-}
-
 //----- (004775ED) --------------------------------------------------------
 int stru6_stru1_indoor_sw_billboard::_4775ED(float a2)
 {
@@ -7526,38 +7503,6 @@
 // 50B570: using guessed type int dword_50B570[];
 // 50B638: using guessed type int dword_50B638[];
 
-//----- (00481E55) --------------------------------------------------------
-void OutdoorCamera::Project(unsigned int uNumVertices)
-{
-  double v1; // st7@2
-  double v2; // st6@2
-  double v3; // st5@2
-  int v4; // eax@2
-  unsigned int v5; // edx@2
-  double v6; // st4@3
-  double v7; // st3@3
-
-  if ( (signed int)uNumVertices > 0 )
-  {
-    v1 = (double)pOutdoorCamera->int_fov_rad;
-    v2 = (double)pViewport->uScreenCenterX;
-    v3 = (double)pViewport->uScreenCenterY;
-    v4 = 0;
-    v5 = uNumVertices;
-    do
-    {
-      v6 = v1 * array_507D30[v4]._rhw;
-      v7 = v6 * array_507D30[v4].vWorldViewPosition.y;
-      memcpy(&array_50AC10[v4], &array_507D30[v4], sizeof(array_50AC10[v4]));
-      array_50AC10[v4].vWorldViewProjX = v2 - v7;
-      array_50AC10[v4].vWorldViewProjY = v3 - v6 * array_507D30[v4].vWorldViewPosition.z;
-      ++v4;
-      --v5;
-    }
-    while ( v5 );
-  }
-}
-
 //----- (00481EB7) --------------------------------------------------------
 void __cdecl ResetStru148s()
 {
@@ -10426,40 +10371,6 @@
     v->y = 0;
 }
 
-//----- (00485F64) --------------------------------------------------------
-void OutdoorCamera::_485F64()
-{
-  int v1; // eax@1
-  int v2; // eax@2
-  signed __int64 v3; // qtt@4
-  int v4; // eax@4
-
-  this->uCameraFovInDegrees = 75;
-  v1 = stru_5C6E00->uPiMask & 0xD5;
-  if ( v1 >= (signed int)stru_5C6E00->uIntegerHalfPi )
-    v2 = -stru_5C6E00->pTanTable[stru_5C6E00->uIntegerPi - v1];
-  else
-    v2 = stru_5C6E00->pTanTable[v1];
-  LODWORD(v3) = (viewparams->uSomeZ - viewparams->uSomeX) << 31;
-  HIDWORD(v3) = (viewparams->uSomeZ - viewparams->uSomeX) << 15 >> 16;
-  v4 = (signed int)(v3 / v2) >> 16;
-  this->int_fov_rad = v4;
-  this->field_4C = 360000;
-  this->int_fov_rad_inv = 65536 / v4;
-  this->field_50 = 115;
-  unnamed_6BE060[1] = 1;
-  RotationToInts();
-}
-
-//----- (0048600E) --------------------------------------------------------
-void OutdoorCamera::RotationToInts()
-{
-  camera_rotation_y_int_sine   = stru_5C6E00->Sin(pIndoorCamera->sRotationY);
-  camera_rotation_y_int_cosine = stru_5C6E00->Cos(pIndoorCamera->sRotationY);
-  camera_rotation_x_int_sine   = stru_5C6E00->Sin(pIndoorCamera->sRotationX);
-  camera_rotation_x_int_cosine = stru_5C6E00->Cos(pIndoorCamera->sRotationX);
-}
-
 //----- (0048607B) --------------------------------------------------------
 void stru148::_48607B(stru149 *a2)
 {
@@ -10624,116 +10535,6 @@
   return result;
 }
 
-//----- (0048653D) --------------------------------------------------------
-int stru149::_48653D(int a2, int a3, int a4, int a5, int a6, int a7)
-{
-  stru149 *v7; // esi@1
-  int v8; // edi@1
-  int v9; // eax@1
-  //int v10; // edx@1
-  //int v11; // ecx@1
-  int v12; // eax@1
-  int v13; // ebx@2
-  int v14; // ecx@2
-  int v15; // eax@2
-  int v16; // ST14_4@3
-  int v17; // ST10_4@3
-  int v18; // eax@5
-  int v19; // ST10_4@6
-  int v20; // eax@8
-  int v21; // ST10_4@9
-  int v22; // eax@10
-  int v23; // ecx@10
-  int v24; // eax@10
-  int result; // eax@10
-  //int v26; // [sp+14h] [bp-14h]@1
-  int v27; // [sp+18h] [bp-10h]@1
-  int v28; // [sp+1Ch] [bp-Ch]@1
-  int v29; // [sp+24h] [bp-4h]@1
-  int v30; // [sp+30h] [bp+8h]@10
-  int v31; // [sp+3Ch] [bp+14h]@10
-
-  v7 = this;
-  v8 = stru_5C6E00->Cos(pBLVRenderParams->sPartyRotY);
-  v29 = stru_5C6E00->Sin(pBLVRenderParams->sPartyRotY);
-  v28 = stru_5C6E00->Cos(pBLVRenderParams->sPartyRotX);
-  v9 = stru_5C6E00->Sin(pBLVRenderParams->sPartyRotX);
-  //v11 = -pBLVRenderParams->vPartyPos.y;
-  //v26 = -pBLVRenderParams->vPartyPos.x;
-  v27 = v9;
-  v12 = -pBLVRenderParams->vPartyPos.z;
-  if ( pBLVRenderParams->sPartyRotX )
-  {
-    v16 = v8 * -pBLVRenderParams->vPartyPos.x + v29 * -pBLVRenderParams->vPartyPos.y;
-    v13 = v28;
-    v17 = -65536 * pBLVRenderParams->vPartyPos.z;
-    v7->field_0_party_dir_x = ((unsigned __int64)(v16 * (signed __int64)v28) >> 16)
-                + ((unsigned __int64)(-65536 * pBLVRenderParams->vPartyPos.z * (signed __int64)v27) >> 16);
-    v7->field_4_party_dir_y = v8 * -pBLVRenderParams->vPartyPos.y - v29 * -pBLVRenderParams->vPartyPos.x;
-    v14 = v27;
-    v15 = ((unsigned __int64)(v17 * (signed __int64)v28) >> 16) - ((unsigned __int64)(v16 * (signed __int64)v27) >> 16);
-  }
-  else
-  {
-    v7->field_0_party_dir_x = v8 * -pBLVRenderParams->vPartyPos.x + v29 * -pBLVRenderParams->vPartyPos.y;
-    v13 = v28;
-    v7->field_4_party_dir_y = v8 * -pBLVRenderParams->vPartyPos.y - v29 * -pBLVRenderParams->vPartyPos.x;
-    v14 = v27;
-    v15 = v12 << 16;
-  }
-  v7->field_8 = v15;
-  if ( pBLVRenderParams->sPartyRotX )
-  {
-    v19 = ((unsigned __int64)(a2 * (signed __int64)v8) >> 16) + ((unsigned __int64)(a3 * (signed __int64)v29) >> 16);
-    v7->field_C = ((unsigned __int64)(v19 * (signed __int64)v13) >> 16)
-                + ((unsigned __int64)(a4 * (signed __int64)v14) >> 16);
-    v7->field_10 = ((unsigned __int64)(a3 * (signed __int64)v8) >> 16)
-                 - ((unsigned __int64)(a2 * (signed __int64)v29) >> 16);
-    v18 = ((unsigned __int64)(a4 * (signed __int64)v13) >> 16) - ((unsigned __int64)(v19 * (signed __int64)v14) >> 16);
-  }
-  else
-  {
-    v7->field_C = ((unsigned __int64)(a2 * (signed __int64)v8) >> 16)
-                + ((unsigned __int64)(a3 * (signed __int64)v29) >> 16);
-    v7->field_10 = ((unsigned __int64)(a3 * (signed __int64)v8) >> 16)
-                 - ((unsigned __int64)(a2 * (signed __int64)v29) >> 16);
-    v18 = a4;
-  }
-  v7->field_14 = v18;
-  if ( pBLVRenderParams->sPartyRotX )
-  {
-    v21 = ((unsigned __int64)(a5 * (signed __int64)v8) >> 16) + ((unsigned __int64)(a6 * (signed __int64)v29) >> 16);
-    v7->field_18 = ((unsigned __int64)(v21 * (signed __int64)v13) >> 16)
-                 + ((unsigned __int64)(a7 * (signed __int64)v14) >> 16);
-    v7->field_1C = ((unsigned __int64)(a6 * (signed __int64)v8) >> 16)
-                 - ((unsigned __int64)(a5 * (signed __int64)v29) >> 16);
-    v20 = ((unsigned __int64)(a7 * (signed __int64)v13) >> 16) - ((unsigned __int64)(v21 * (signed __int64)v14) >> 16);
-  }
-  else
-  {
-    v7->field_18 = ((unsigned __int64)(a5 * (signed __int64)v8) >> 16)
-                 + ((unsigned __int64)(a6 * (signed __int64)v29) >> 16);
-    v7->field_1C = ((unsigned __int64)(a6 * (signed __int64)v8) >> 16)
-                 - ((unsigned __int64)(a5 * (signed __int64)v29) >> 16);
-    v20 = a7;
-  }
-  v7->field_18 = -v7->field_18;
-  v7->field_1C = -v7->field_1C;
-  v7->field_20 = v20;
-  v22 = v7->field_C;
-  v7->field_20 = -v7->field_20;
-  v23 = ((unsigned __int64)(v22 * (signed __int64)v7->field_0_party_dir_x) >> 16)
-      + ((unsigned __int64)(v7->field_10 * (signed __int64)v7->field_4_party_dir_y) >> 16)
-      + ((unsigned __int64)(v7->field_14 * (signed __int64)v7->field_8) >> 16);
-  v30 = v7->field_18;
-  v24 = v7->field_0_party_dir_x;
-  v7->field_24 = v23;
-  v31 = (unsigned __int64)(v30 * (signed __int64)v24) >> 16;
-  result = (unsigned __int64)(v7->field_1C * (signed __int64)v7->field_4_party_dir_y) >> 16;
-  v7->field_28 = v31 + result + ((unsigned __int64)(v7->field_20 * (signed __int64)v7->field_8) >> 16);
-  return result;
-}
-
 //----- (0048694B) --------------------------------------------------------
 int stru149::_48694B()
 {
@@ -10760,36 +10561,6 @@
   return result;
 }
 
-//----- (00486A28) --------------------------------------------------------
-void OutdoorCamera::AllocSoftwareDrawBuffers()
-{
-  if ( !this || !pSpans )
-  {
-    ReleaseSoftwareDrawBuffers();
-    pSpans = (Span *)pAllocator->AllocNamedChunk(pSpans, 0x493E0u, "SPANS");
-    pEdges = (Edge *)pAllocator->AllocNamedChunk(pEdges, 0x4C2C0u, "EDGES");
-    pSurfs = (Surf *)pAllocator->AllocNamedChunk(pSurfs, 0x11940u, "SURFS");
-    pNewEdges = (Edge *)pAllocator->AllocNamedChunk(pNewEdges, 0x6180u, "NEWEDGES");
-    memset(pSpans, 0, 0x493E0u);
-    memset(pEdges, 0, 0x4C2C0u);
-    memset(pSurfs, 0, 0x11940u);
-    memset(pNewEdges, 0, 0x6180u);
-  }
-}
-
-//----- (00486AFC) --------------------------------------------------------
-void OutdoorCamera::ReleaseSoftwareDrawBuffers()
-{
-  pAllocator->FreeChunk(pSpans);
-  pAllocator->FreeChunk(pEdges);
-  pAllocator->FreeChunk(pSurfs);
-  pAllocator->FreeChunk(pNewEdges);
-  pSpans = 0;
-  pEdges = 0;
-  pSurfs = 0;
-  pNewEdges = 0;
-}
-
 //----- (00486B4E) --------------------------------------------------------
 char __fastcall sr_sub_486B4E_push_outdoor_edges(RenderVertexSoft *a1, int *a2, int *a3, stru148 *a4)//maybe DrawPolygonSW
 {
@@ -11008,459 +10779,6 @@
   return v7;
 }
 
-//----- (0043F953) --------------------------------------------------------
-void PrepareBspRenderList_BLV()
-{
-  pBspRenderer->num_faces = 0;
-
-  if (pBLVRenderParams->uPartySectorID)
-  {
-    pBspRenderer->nodes[0].uSectorID = pBLVRenderParams->uPartySectorID;
-    pBspRenderer->nodes[0].uViewportW = pBLVRenderParams->uViewportW;
-    pBspRenderer->nodes[0].uViewportZ = pBLVRenderParams->uViewportZ;
-    pBspRenderer->nodes[0].uViewportY = pBLVRenderParams->uViewportY;
-    pBspRenderer->nodes[0].uViewportX = pBLVRenderParams->uViewportX;
-    pBspRenderer->nodes[0].field_C._43F9E1(pBLVRenderParams->uViewportX, pBLVRenderParams->uViewportY,
-                                           pBLVRenderParams->uViewportZ, pBLVRenderParams->uViewportW);
-    pBspRenderer->nodes[0].uFaceID = -1;
-    pBspRenderer->nodes[0].viewing_portal_id = -1;
-    pBspRenderer->num_nodes = 1;
-    AddBspNodeToRenderList(0);
-  }
-
-  pBspRenderer->MakeVisibleSectorList();
-}
-
-//----- (0043F9E1) --------------------------------------------------------
-void BspRenderer_stru2::_43F9E1(__int16 x, int y, __int16 z, int w)
-{
-  _viewport_space_y = y;
-  _viewport_space_w = w;
-
-  for (uint i = 0; i < 480; ++i)
-  {
-    if ( i < y || i > w )
-    {
-      viewport_left_side[i] = 640;
-      viewport_right_side[i] = -1;
-    }
-    else
-    {
-      viewport_left_side[i] = x;
-      viewport_right_side[i] = z;
-    } 
-  }
-}
-
-//----- (0043FA33) --------------------------------------------------------
-void __fastcall PrepareDecorationsRenderList_BLV(unsigned int uDecorationID, unsigned int uSectorID)
-{
-  LevelDecoration *v2; // esi@1
-  DecorationDesc *v3; // ebx@2
-  __int16 v4; // ax@2
-  double v5; // st7@3
-  int v6; // eax@5
-  int v7; // edx@5
-  unsigned int v8; // edi@5
-  int v9; // edi@5
-  int v10; // eax@7
-  SpriteFrame *v11; // eax@7
-  SpriteFrame *v12; // esi@7
-  int v13; // eax@7
-  int v14; // ebx@16
-  RenderBillboard *v15; // ecx@17
-  char v16; // zf@18
-  IndoorCameraD3D **v17; // eax@19
-  double v18; // st7@19
-  //float v19; // eax@19
-  signed __int64 v20; // qtt@19
-  signed __int64 v21; // qtt@20
-  //int v22; // edx@21
-  //int v23; // eax@21
-  Particle_sw local_0; // [sp+Ch] [bp-A0h]@3
-  //double v25; // [sp+74h] [bp-38h]@19
-  //unsigned int v26; // [sp+7Ch] [bp-30h]@1
-  int a2; // [sp+80h] [bp-2Ch]@5
-  int a3; // [sp+84h] [bp-28h]@5
-  int a1; // [sp+88h] [bp-24h]@5
-  int v30; // [sp+8Ch] [bp-20h]@7
-  //float v31; // [sp+90h] [bp-1Ch]@1
-  int a5; // [sp+94h] [bp-18h]@17
-  int z; // [sp+98h] [bp-14h]@15
-  int a6; // [sp+9Ch] [bp-10h]@17
-  int y; // [sp+A0h] [bp-Ch]@15
-  int x; // [sp+A4h] [bp-8h]@15
-  int v37; // [sp+A8h] [bp-4h]@5
-
-  //v26 = uDecorationID;
-  //LODWORD(v31) = uSectorID;
-  v2 = &pLevelDecorations[uDecorationID];
-  if (v2->field_2 & 0x20)
-    return;
-
-    v3 = &pDecorationList->pDecorations[v2->uDecorationDescID];
-    v4 = v3->uFlags;
-    if (v3->uFlags & DECORATION_EMITS_FIRE)
-    {
-      memset(&local_0, 0, 0x68u);               // fire,  like at the Pit's tavern
-      v5 = (double)v2->vPosition.x;
-      local_0.type = ParticleType_Bitmap | ParticleType_Rotating | ParticleType_8;
-      local_0.uDiffuse = 0xFF3C1E;
-      local_0.x = v5;
-      local_0.y = (double)v2->vPosition.y;
-      local_0.z = (double)v2->vPosition.z;
-      local_0.flt_10 = 0.0;
-      local_0.flt_14 = 0.0;
-      local_0.flt_18 = 0.0;
-      local_0.flt_28 = 1.0;
-      local_0.timeToLive = (rand() & 0x80) + 128;
-      local_0.uTextureID = pBitmaps_LOD->LoadTexture("effpar01");
-      pGame->pParticleEngine->AddParticle(&local_0);
-      return;
-    }
-
-
-      if (v4 & DECORATION_DONT_DRAW)
-        return;
-
-        v6 = v2->vPosition.x;
-        v7 = v2->vPosition.z;
-        a2 = v2->vPosition.y;
-        a1 = v6;
-        a3 = v7;
-        v8 = v2->field_10_y_rot
-           + ((signed int)stru_5C6E00->uIntegerPi >> 3)
-           - stru_5C6E00->Atan2(v6 - pBLVRenderParams->vPartyPos.x, a2 - pBLVRenderParams->vPartyPos.y);
-        v37 = pBLVRenderParams->field_0_timer_;
-        v9 = ((signed int)(stru_5C6E00->uIntegerPi + v8) >> 8) & 7;
-        if (pParty->bTurnBasedModeOn)
-          v37 = pMiscTimer->uTotalGameTimeElapsed;
-        v10 = abs(v2->vPosition.x + v2->vPosition.y);
-        v11 = pSpriteFrameTable->GetFrame(v3->uSpriteID, v37 + v10);
-        v30 = 0;
-        v12 = v11;
-        v13 = v11->uFlags;
-        if ( v13 & 2 )
-          v30 = 2;
-        if ( v13 & 0x40000 )
-          v30 |= 0x40u;
-        if ( v13 & 0x20000 )
-          LOBYTE(v30) = v30 | 0x80;
-        if ( (256 << v9) & v13 )
-          v30 |= 4u;
-        if ( pGame->pIndoorCameraD3D->ApplyViewTransform_TrueIfStillVisible(a1, a2, a3, &x, &y, &z, 1) )
-        {
-          v14 = abs(x);
-          if ( v14 >= abs(y) )
-          {
-            pGame->pIndoorCameraD3D->Project(x, y, z, &a5, &a6);
-
-            v15 = &pBillboardRenderList[uNumBillboardsToDraw];
-            assert(uNumBillboardsToDraw < 500);
-
-              ++uNumBillboardsToDraw;
-              ++uNumDecorationsDrawnThisFrame;
-              v16 = pRenderer->pRenderD3D == 0;
-              v15->uHwSpriteID = v12->pHwSpriteIDs[v9];
-              v15->uPalette = v12->uPaletteIndex;
-              v15->uIndoorSectorID = uSectorID;
-              if ( v16 )
-              {
-                LODWORD(v21) = pBLVRenderParams->field_40 << 16;
-                HIDWORD(v21) = pBLVRenderParams->field_40 >> 16;
-                v37 = v21 / x;
-                //LODWORD(v31) = v12->scale;
-                v37 = v21 / x;
-                v15->_screenspace_x_scaler_packedfloat = (unsigned __int64)(v12->scale * v21 / x) >> 16;
-                v37 = (unsigned __int64)(v12->scale * (signed __int64)v37) >> 16;
-              }
-              else
-              {
-                v17 = &pGame->pIndoorCameraD3D;
-                v15->fov_x = pGame->pIndoorCameraD3D->fov_x;
-                v18 = (*v17)->fov_y;
-                //v19 = v15->fov_x;
-                v15->fov_y = v18;
-                //v31 = v19;
-                //v25 = v19 + 6.7553994e15;
-                //v25 = floorf(v15->fov_x + 0.5f);
-                LODWORD(v20) = 0;
-                HIDWORD(v20) = floorf(v15->fov_x + 0.5f);
-                v37 = v20 / x;
-                //LODWORD(v31) = v12->scale;
-                v37 = (unsigned __int64)(v12->scale * v20 / x) >> 16;
-                v15->_screenspace_x_scaler_packedfloat = (unsigned __int64)(v12->scale * v20 / x) >> 16;
-                //v31 = v15->fov_y;
-                //v25 = v31 + 6.7553994e15;
-                //v25 = floorf(v15->fov_y + 0.5f);
-                LODWORD(v20) = 0;
-                HIDWORD(v20) = floorf(v15->fov_y + 0.5f);
-                v37 = v20 / x;
-                v37 = (unsigned __int64)(v12->scale * v20 / x) >> 16;
-              }
-              //HIWORD(v22) = HIWORD(x);
-              //LOWORD(v22) = 0;
-              v15->_screenspace_y_scaler_packedfloat = v37;
-              v15->field_1E = v30;
-              v15->world_x = a1;
-              v15->world_y = a2;
-              v15->world_z = a3;
-              v15->uScreenSpaceX = a5;
-              v15->uScreenSpaceY = a6;
-              //v23 = 8 * uDecorationID;
-              //LOBYTE(v23) = PID(OBJECT_Decoration,uDecorationID);
-
-              //v15->sZValue = v22 + v23;
-              v15->actual_z = HIWORD(x);
-              v15->object_pid = PID(OBJECT_Decoration,uDecorationID);
-
-              v15->uTintColor = 0;
-              v15->pSpriteFrame = v12;
-          }
-        }
-}
-
-//----- (0044028F) --------------------------------------------------------
-void PrepareItemsRenderList_BLV()
-{
-  ObjectDesc *v1; // ebx@4
-  __int16 v2; // ax@5
-  RenderBillboard *v3; // esi@12
-  SpriteFrame *v4; // eax@12
-  SpriteFrame *v5; // ebx@12
-  unsigned int v6; // eax@12
-  int v7; // ecx@12
-  int v8; // edx@12
-  int v9; // ecx@12
-  unsigned __int16 v10; // ax@12
-  int *v11; // eax@20
-  //char v12; // zf@26
-  __int64 v18; // ST5C_4@27
-  signed __int64 v19; // qtt@28
-  int v20; // ST5C_4@28
-  //int v21; // edx@29
-  __int16 v22; // ax@29
-  //int v23; // eax@29
-  SpriteFrame *v24; // [sp+1Ch] [bp-40h]@12
-  //__int16 a5; // [sp+28h] [bp-34h]@12
-  int a6; // [sp+2Ch] [bp-30h]@12
-  int a2; // [sp+30h] [bp-2Ch]@12
-  int a1; // [sp+34h] [bp-28h]@12
-  int v30; // [sp+38h] [bp-24h]@12
-  int v31; // [sp+38h] [bp-24h]@27
-  int a3; // [sp+40h] [bp-1Ch]@12
-  signed __int16 v34; // [sp+44h] [bp-18h]@14
-  int v35; // [sp+48h] [bp-14h]@25
-  int v36; // [sp+4Ch] [bp-10h]@25
-  signed int z; // [sp+50h] [bp-Ch]@24
-  signed int y; // [sp+54h] [bp-8h]@24
-  signed int x; // [sp+58h] [bp-4h]@24
-
-  for (uint i = 0; i < uNumSpriteObjects; ++i)
-  {
-    auto p = &pSpriteObjects[i];
-    if (p->uObjectDescID)
-    {
-      v1 = &pObjectList->pObjects[p->uObjectDescID];
-        if ( !(v1->uFlags & 1) )
-         {
-          if ( ((v2 = p->uType, v2 < 1000) || v2 >= 10000)
-            && (v2 < 500 || v2 >= 600)
-            && (v2 < 811 || v2 >= 815)
-            || pGame->pStru6Instance->_4A81CA(p))
-          {
-            //a5 = p->uSectorID;
-            a1 = p->vPosition.x;
-            a2 = p->vPosition.y;
-            a3 = p->vPosition.z;
-            v3 = &pBillboardRenderList[uNumBillboardsToDraw];
-            v4 = pSpriteFrameTable->GetFrame(v1->uSpriteID, p->uSpriteFrameID);
-            v5 = v4;
-            v24 = v4;
-            v30 = v4->uFlags;
-            a6 = v4->uGlowRadius * p->field_22_glow_radius_multiplier;
-            v6 = stru_5C6E00->Atan2(p->vPosition.x - pBLVRenderParams->vPartyPos.x,
-                                    p->vPosition.y - pBLVRenderParams->vPartyPos.y);
-            LOWORD(v7) = p->uFacing;
-            v8 = v30;
-            v9 = ((signed int)(stru_5C6E00->uIntegerPi + ((signed int)stru_5C6E00->uIntegerPi >> 3) + v7 - v6) >> 8) & 7;
-            v10 = v5->pHwSpriteIDs[v9];
-            v3->uHwSpriteID = v10;
-            if ( v30 & 0x20 )
-            {
-              v8 = v30;
-              a3 -= (signed int)((unsigned __int64)(v5->scale * (signed __int64)pSprites_LOD->pSpriteHeaders[(signed __int16)v10].uHeight) >> 16) >> 1;
-            }
-            v34 = 0;
-            if ( v8 & 2 )
-              v34 = 2;
-            if ( v8 & 0x40000 )
-              v34 |= 0x40u;
-            if ( v8 & 0x20000 )
-              LOBYTE(v34) = v34 | 0x80;
-            v11 = (int *)(256 << v9);
-            if ( (256 << v9) & v8 )
-              v34 |= 4u;
-            if ( a6 )
-            {
-              LOBYTE(v11) = byte_4E94D3;
-              pMobileLightsStack->AddLight(
-                a1,
-                a2,
-                a3,
-                p->uSectorID,
-                a6,
-                v1->uParticleTrailColorR,
-                v1->uParticleTrailColorG,
-                v1->uParticleTrailColorB,
-                byte_4E94D3);
-            }
-            if ( pGame->pIndoorCameraD3D->ApplyViewTransform_TrueIfStillVisible(
-                   a1,
-                   a2,
-                   a3,
-                   &x,
-                   &y,
-                   &z,
-                   1) )
-            {
-              pGame->pIndoorCameraD3D->Project(x, y, z, &v36, &v35);
-
-              assert(uNumBillboardsToDraw < 500);
-              //if ( (signed int)uNumBillboardsToDraw >= 500 )
-              //  return;
-              ++uNumBillboardsToDraw;
-              ++uNumSpritesDrawnThisFrame;
-              p->uAttributes |= 1u;
-              //v12 = pRenderer->pRenderD3D == 0;
-              v3->uPalette = v24->uPaletteIndex;
-              v3->uIndoorSectorID = p->uSectorID;
-              if ( pRenderer->pRenderD3D )
-              {
-                v3->fov_x = pGame->pIndoorCameraD3D->fov_x;
-                v3->fov_y = pGame->pIndoorCameraD3D->fov_y;
-                LODWORD(v18) = 0;
-                HIDWORD(v18) = (int)floorf(v3->fov_x + 0.5f);
-                v18 = v18 / x;
-                v3->_screenspace_x_scaler_packedfloat = (unsigned __int64)(v24->scale * v18) >> 16;
-                v31 = (unsigned __int64)(v24->scale * v18) >> 16;
-              }
-              else
-              {
-                LODWORD(v19) = pBLVRenderParams->field_40 << 16;
-                HIDWORD(v19) = pBLVRenderParams->field_40 >> 16;
-                v20 = v19 / x;
-                v3->_screenspace_x_scaler_packedfloat = (unsigned __int64)(v24->scale * v19 / x) >> 16;
-                v31 = (unsigned __int64)(v24->scale * (signed __int64)v20) >> 16;
-              }
-              //HIWORD(v21) = HIWORD(x);
-              //LOWORD(v21) = 0;
-              v3->_screenspace_y_scaler_packedfloat = v31;
-              v3->field_1E = v34;
-              v3->world_x = a1;
-              v3->world_y = a2;
-              v3->world_z = a3;
-              v3->uScreenSpaceX = v36;
-              v22 = v35;
-              v3->uTintColor = 0;
-              v3->uScreenSpaceY = v22;
-              //v23 = 8 * i;
-              //LOBYTE(v23) = PID(OBJECT_Item,i);
-              v3->pSpriteFrame = v24;
-              //v12 = (p->uAttributes & 0x20) == 0;
-              //v3->sZValue = v21 + v23;
-              v3->actual_z = HIWORD(x);
-              v3->object_pid = PID(OBJECT_Item,i);
-              if (p->uAttributes & 0x20)
-              {
-                if ( !pRenderer->pRenderD3D )
-                  v3->sZValue = 0;
-              }
-            }
-          }
-        }
-      }
-  }
-}
-
-//----- (00440639) --------------------------------------------------------
-void AddBspNodeToRenderList(unsigned int node_id)
-{
-  BLVSector *pSector; // esi@1
-
-  pSector = &pIndoor->pSectors[pBspRenderer->nodes[node_id].uSectorID];
-  if ( pRenderer->pRenderD3D )
-  {
-    for (uint i = 0; i < pSector->uNumNonBSPFaces; ++i)
-      //Log::Warning(L"Non-BSP face: %X", v3->pFaceIDs[v2]);
-      pBspRenderer->AddFaceToRenderList_d3d(node_id, pSector->pFaceIDs[i]);
-  }
-  else
-  {
-    for (uint i = 0; i < pSector->uNumNonBSPFaces; ++i)
-      pBspRenderer->AddFaceToRenderList_sw(node_id, pSector->pFaceIDs[i]);
-  }
-  if ( pSector->field_0 & 0x10 )
-    sub_4406BC(node_id, pSector->uFirstBSPNode);
-}
-
-//----- (004406BC) --------------------------------------------------------
-void __fastcall sub_4406BC(unsigned int node_id, unsigned int uFirstNode)
-{
-  BLVSector *pSector; // esi@2
-  BSPNode *pNode; // edi@2
-  BLVFace *pFace; // eax@2
-  int v5; // ecx@2
-  __int16 v6; // ax@6
-  int v7; // ebp@10
-  int v8; // ebx@10
-  __int16 v9; // di@18
-  //int v10; // [sp+10h] [bp-Ch]@1
-  //bool v11; // [sp+14h] [bp-8h]@5
-  BspRenderer_stru0 *node; // [sp+18h] [bp-4h]@1
-
-  //Log::Warning(L"sub_4406BC(%u, %u)", a1, uFirstNode);
-
-  //v10 = a1;
-  node = &pBspRenderer->nodes[node_id];
-  while ( 1 )
-  {
-    pSector = &pIndoor->pSectors[node->uSectorID];
-    pNode = &pIndoor->pNodes[uFirstNode];
-    pFace = &pIndoor->pFaces[pSector->pFaceIDs[pNode->uCoplanarOffset]];
-    v5 = pFace->pFacePlane_old.dist + pBLVRenderParams->vPartyPos.x * pFace->pFacePlane_old.vNormal.x
-       + pBLVRenderParams->vPartyPos.y * pFace->pFacePlane_old.vNormal.y + pBLVRenderParams->vPartyPos.z * pFace->pFacePlane_old.vNormal.z;
-    if (pFace->Portal() && pFace->uSectorID != node->uSectorID )
-      v5 = -v5;
-    //v11 = v5 > 0;
-    if ( v5 <= 0 )
-      v6 = pNode->uFront;
-    else
-      v6 = pNode->uBack;
-    if ( v6 != -1 )
-      sub_4406BC(node_id, v6);
-    v7 = pNode->uCoplanarOffset;
-    v8 = v7 + pNode->uCoplanarSize;
-
-    //Log::Warning(L"Node %u: %X to %X (%hX)", uFirstNode, v7, v8, v2->pFaceIDs[v7]);
-    
-    if ( pRenderer->pRenderD3D )
-    {
-      while ( v7 < v8 )
-        pBspRenderer->AddFaceToRenderList_d3d(node_id, pSector->pFaceIDs[v7++]);
-    }
-    else
-    {
-      while ( v7 < v8 )
-        pBspRenderer->AddFaceToRenderList_sw(node_id, pSector->pFaceIDs[v7++]);
-    }
-    v9 = v5 > 0 ? pNode->uFront : pNode->uBack;
-    if ( v9 == -1 )
-      break;
-    uFirstNode = v9;
-  }
-}
-
 //----- (00440DF5) --------------------------------------------------------
 int stru167_wrap::Push(__int16 a2, __int16 a3, __int16 a4, int a5, __int16 bgr)
 {
@@ -12206,87 +11524,6 @@
   pEventTimer->Resume();
 }
 
-//----- (00445308) --------------------------------------------------------
-const char *GetProfessionActionText(int a1)
-{
-  if ( a1 == 10
-    || a1 == 11
-    || a1 == 12
-    || a1 == 33
-    || a1 == 34
-    || a1 == 39
-    || a1 == 40
-    || a1 == 41
-    || a1 == 42
-    || a1 == 43
-    || a1 == 52 )
-    return pNPCStats->pProfessions[a1 - 1].pActionText;
-  else
-    return pNPCTopics[407].pTopic;
-}
-
-
-//----- (00445C8B) --------------------------------------------------------
-int __fastcall GetGreetType(signed int SpeakingNPC_ID)
-{
-  signed int v1; // ebx@1
-  int v3; // edi@6
-  int v4; // ecx@6
-  int v5; // edx@6
-  NPCData *v6; // eax@6
-  char *v7; // ebp@11
-  NPCData *v8; // esi@11
-
-  v1 = 0;
-  if ( SpeakingNPC_ID >= 0 )
-  {
-    if ( SpeakingNPC_ID < 5000 )
-      return 1;//QuestNPC_greet
-    return 2;//HiredNPC_greet
-  }
-  if ( SpeakingNPC_ID >= 5000 )
-    return 2;
-  v3 = abs((int)sDialogue_SpeakingActorNPC_ID) - 1;
-  v4 = 0;
-  v5 = 0;
-  v6 = pParty->pHirelings;
-  do
-  {
-    if ( v6->pName )
-      pTmpBuf[v4++] = v5;
-    ++v6;
-    ++v5;
-  }
-  while ( (signed int)v6 < (signed int)&pParty->pPickedItem );
-  if ( (signed int)pNPCStats->uNumNewNPCs > 0 )
-  {
-    v7 = &pTmpBuf[v4];
-    v8 = pNPCStats->pNewNPCData;
-    do
-    {
-      if (v8->Hired() && (!pParty->pHirelings[0].pName || strcmp(v8->pName, pParty->pHirelings[0].pName)) )
-      {
-        if ( !pParty->pHirelings[1].pName || strcmp(v8->pName, pParty->pHirelings[1].pName) )
-          *v7++ = v1 + 2;
-      }
-      ++v1;
-      ++v8;
-    }
-    while ( v1 < (signed int)pNPCStats->uNumNewNPCs );
-  }
-  return ((unsigned __int8)pTmpBuf[v3] < 2) + 1;
-}
-
-//----- (0044603D) --------------------------------------------------------
-void __cdecl DialogueEnding()
-{
-  sDialogue_SpeakingActorNPC_ID = 0;
-  pDialogueWindow->Release();
-  pDialogueWindow = 0;
-  pMiscTimer->Resume();
-  pEventTimer->Resume();
-}
-
 //----- (004465DF) --------------------------------------------------------
 int sub_4465DF_check_season(int a1)
 {
@@ -12356,135 +11593,6 @@
   return 0;
 }
 
-//----- (0044665D) --------------------------------------------------------
-// uType:     0 -> any monster
-//            1 -> uParam is GroupID
-//            2 -> uParam is MonsterID
-//            3 -> uParam is ActorID
-// uNumAlive: 0 -> all must be alive
-int __fastcall IsActorAlive(unsigned int uType, unsigned int uParam, unsigned int uNumAlive)
-{
-  unsigned int uAliveActors; // eax@6
-  int v5; // ecx@10
-  unsigned int uTotalActors; // [sp+0h] [bp-4h]@1
-
-  uTotalActors = 0;
-  if ( uType )
-  {
-    if ( uType == 1 )
-    {
-      uAliveActors = SearchActorByGroup(&uTotalActors, uParam);
-    }
-    else
-    {
-      if ( uType == 2 )
-      {
-        uAliveActors = SearchActorByMonsterID(&uTotalActors, uParam);
-      }
-      else
-      {
-        if ( uType != 3 )
-          return 0;
-        uAliveActors = SearchActorByID(&uTotalActors, uParam);
-      }
-    }
-  }
-  else
-  {
-    uAliveActors = SearchAliveActors(&uTotalActors);
-  }
-  v5 = 0;
-  if ( uNumAlive )
-    LOBYTE(v5) = (signed int)uAliveActors >= (signed int)uNumAlive;
-  else
-    LOBYTE(v5) = uTotalActors == uAliveActors;
-  return v5;
-}
-
-//----- (004466C4) --------------------------------------------------------
-int NPC_EventProcessor(int npc_event_id, int entry_line)
-	{
-  signed int event_index; // ebp@1
-  int evt_seq_num; // esi@3
-  bool ready_to_exit; // [sp+Ch] [bp-Ch]@3
-  signed int npc_activity; // [sp+10h] [bp-8h]@3
-  int result;
-
-  event_index = 0;
-  if ( !npc_event_id )
-    return 0;
-  evt_seq_num = entry_line;
-  pSomeOtherEVT = pGlobalEVT.data();
-  uSomeOtherEVT_NumEvents = uGlobalEVT_NumEvents;
-  memcpy(pSomeOtherEVT_Events.data(), pGlobalEVT_Index.data(), sizeof(EventIndex)*4400);
-  npc_activity = 1;
-  ready_to_exit = false;
-  if ( uSomeOtherEVT_NumEvents <= 0 )
-    return 2;
-  do
-  {
-    if ( (pSomeOtherEVT_Events[event_index].uEventID == npc_event_id) && (pSomeOtherEVT_Events[event_index].event_sequence_num == evt_seq_num) )
-    {
-	  _evt_raw *_evt = (_evt_raw *)&pSomeOtherEVT[pSomeOtherEVT_Events[event_index].uEventOffsetInEVT];
-	  switch(_evt->_e_type)
-		  {
-	  case EVENT_Exit:
-		   //exit
-		  if ( ready_to_exit )
-			  result = npc_activity != 0;
-		  else
-			   result = 2;
-		  return result;
-		  break;
-	  case EVENT_OnCanShowDialogItemCmp:
-		  ready_to_exit = true;
-		  //v8 = (unsigned __int8)v7[7] + (((unsigned __int8)v7[8] + (((unsigned __int8)v7[9] + ((unsigned __int8)v7[10] << 8)) << 8)) << 8);
-		  for(int i=0; i<4; ++i)
-			  {  
-			//  if (pParty->pPlayers[i].CompareVariable((enum VariableType)((unsigned __int8)pSomeOtherEVT[v6 + 5] + ((unsigned __int8)pSomeOtherEVT[v6 + 6] << 8)),
-				//  v8))
-			  if (pParty->pPlayers[i].CompareVariable((enum VariableType)EVT_WORD(_evt->v5), EVT_DWORD(_evt->v7)))
-				  {
-				  event_index = -1;
-				  evt_seq_num = EVT_BYTE(_evt->v11)-1;//(unsigned __int8)pSomeOtherEVT[v6 + 11] - 1;
-				  break;
-				  }
-			}
-		  break;
-	  case EVENT_EndCanShowDialogItem :
-		  if ( ready_to_exit )
-			  result = npc_activity != 0;
-		  else
-			  result = 2;
-		  return result;
-		  break;
-	  case EVENT_SetCanShowDialogItem :
-		  ready_to_exit = true;
-		  npc_activity = EVT_BYTE(_evt->v5); //(unsigned __int8)v7[5];
-		  break;
-	  case EVENT_IsActorAssasinated :
-		//  if (IsActorAlive( (unsigned __int8)v7[5], 
-		//	  (unsigned __int8)v7[6] + (((unsigned __int8)v7[7] + (((unsigned __int8)v7[8] + ((unsigned __int8)v7[9] << 8)) << 8)) << 8),
-			//  (unsigned __int8)v7[10]) )
-			if (IsActorAlive( EVT_BYTE(_evt->v5),  EVT_DWORD(_evt->v6), EVT_BYTE(_evt->v10)))
-			  {  // drop linear sequense, going to new seq
-				event_index = -1;
-				evt_seq_num = EVT_BYTE(_evt->v11)-1;//(unsigned __int8)pSomeOtherEVT[v6 + 11] - 1;
-			  }
-		  break;	  
-		  }
-		++evt_seq_num;
-    }
-    ++event_index;
-  }
-  while ( event_index < uSomeOtherEVT_NumEvents );
-  if ( ready_to_exit )
-    result = npc_activity != 0;
-  else
-    result = 2;
-  return result;
-}
-
 //----- (0044861E) --------------------------------------------------------
 void __fastcall sub_44861E_set_texture(unsigned int uFaceCog, const char *pFilename)
 {
@@ -12918,730 +12026,6 @@
   }
 }
 
-//----- (00448DF8) --------------------------------------------------------
-void __fastcall EventCastSpell(int spellnum, int uSkillLevel, int uSkill, int fromx, int fromy, int fromz, int tox, int toy, int toz)//sub_448DF8
-{
-  int v9; // esi@1
-  double v10; // st7@4
-  double v11; // st6@4
-  double v12; // st5@4
-  double v13; // st7@6
-  int v14; // ST44_4@7
-  signed int v15; // ebx@9
-  signed int v16; // edx@15
-  char *v17; // ecx@16
-  unsigned __int16 v18; // ax@20
-  char *v19; // ecx@31
-  int v20; // edx@35
-  signed int v21; // edx@37
-  char *v22; // ecx@38
-  unsigned __int16 v23; // ax@41
-  int i; // esi@42
-  signed int v25; // edx@55
-  char *v26; // ecx@56
-  unsigned __int16 v27; // ax@59
-  int j; // esi@60
-  signed int v29; // edx@66
-  char *v30; // ecx@67
-  unsigned __int16 v31; // ax@70
-  //Player *v32; // eax@80
-  //unsigned __int16 v33; // si@85
-  int v34; // eax@96
-  int v35; // eax@97
-  unsigned __int64 v36; // qax@99
-  SpellBuff *v37; // ecx@99
-  int v38; // esi@103
-  signed __int64 v39; // qax@105
-  int v40; // ebx@108
-  int v41; // ebx@109
-  int v42; // esi@111
-  int v43; // ebx@111
-  int v44; // eax@117
-  //unsigned __int16 v45; // si@137
-  unsigned __int16 v46; // [sp-8h] [bp-BCh]@99
-  int v47; // [sp-4h] [bp-B8h]@35
-  unsigned __int16 v48; // [sp-4h] [bp-B8h]@99
-  int v49; // [sp+0h] [bp-B4h]@35
-  int v50; // [sp+0h] [bp-B4h]@99
-  int v51; // [sp+4h] [bp-B0h]@35
-  unsigned __int8 v52; // [sp+4h] [bp-B0h]@99
-  float v53; // [sp+14h] [bp-A0h]@4
-  float v54; // [sp+18h] [bp-9Ch]@4
-  int v55; // [sp+28h] [bp-8Ch]@7
-  unsigned int yaw; // [sp+30h] [bp-84h]@7
-  int pitch; // [sp+34h] [bp-80h]@7
-  //SpriteObject a1; // [sp+38h] [bp-7Ch]@12
-  int v59; // [sp+A8h] [bp-Ch]@1
-  int v60; // [sp+ACh] [bp-8h]@1
-  //int spellnum_; // [sp+B0h] [bp-4h]@1
-  //signed int levela; // [sp+BCh] [bp+8h]@80
-  int a6_4; // [sp+C8h] [bp+14h]@117
-  float a7a; // [sp+CCh] [bp+18h]@6
-  signed int a7b; // [sp+CCh] [bp+18h]@12
-  int a7c; // [sp+CCh] [bp+18h]@29
-  int a7d; // [sp+CCh] [bp+18h]@55
-  float a8a; // [sp+D0h] [bp+1Ch]@6
-  int a8b; // [sp+D0h] [bp+1Ch]@37
-  int a8c; // [sp+D0h] [bp+1Ch]@55
-  float toza; // [sp+D4h] [bp+20h]@6
-
-  v9 = 0;
-  v59 = uSkillLevel + 1;
-  //spellnum_ = spellnum;
-  v60 = 0;
-  if ( tox || toy || toz )
-  {
-    v10 = (double)tox - (double)fromx;
-    v53 = v10;
-    v11 = (double)toy - (double)fromy;
-    v54 = v11;
-    v12 = (double)toz;
-  }
-  else
-  {
-    v10 = (double)pParty->vPosition.x - (double)fromx;
-    v53 = v10;
-    v11 = (double)pParty->vPosition.y - (double)fromy;
-    v54 = v11;
-    v12 = (double)(pParty->vPosition.z + pParty->sEyelevel);
-  }
-  a7a = v12 - (double)fromz;
-  toza = v11 * v11;
-  a8a = v10 * v10;
-  v13 = sqrt(a7a * a7a + a8a + toza);
-  if ( v13 <= 1.0 )
-  {
-    LOBYTE(v55) = 1;
-    yaw = 0;
-    pitch = 0;
-  }
-  else
-  {
-    v55 = (signed __int64)v13;
-    v14 = (signed __int64)sqrt(a8a + toza);
-    yaw = stru_5C6E00->Atan2((signed __int64)v53, (signed __int64)v54);
-    pitch = stru_5C6E00->Atan2(v14, (signed __int64)a7a);
-  }
-  v15 = v59;
-  if ( v59 <= 0 || v59 > 4 )
-    v15 = 1;
-  a7b = v15;
-
-  SpriteObject a1; // [sp+38h] [bp-7Ch]@12
-  //SpriteObject::SpriteObject(&a1);
-
-  a1.uType = stru_4E3ACC[spellnum].uType;
-  if ( spellnum > 58 )
-  {
-    if ( spellnum == 69 )
-      goto LABEL_117;
-    if ( spellnum != 83 )
-      return;
-    v40 = v15 - 2;
-    if ( v40 )
-    {
-      v41 = v40 - 1;
-      if ( !v41 )
-      {
-        v42 = 14400 * uSkill;
-        v43 = 4 * uSkill + 10;
-        pGame->pStru6Instance->SetPlayerBuffAnim(0x53u, 0);
-        pGame->pStru6Instance->SetPlayerBuffAnim(0x53u, 1u);
-        pGame->pStru6Instance->SetPlayerBuffAnim(0x53u, 2u);
-        pGame->pStru6Instance->SetPlayerBuffAnim(0x53u, 3u);
-        v39 = (signed __int64)((double)(v42 << 7) * 0.033333335);
-        v37 = &pParty->pPartyBuffs[PARTY_BUFF_DAY_OF_GODS];
-        v36 = pParty->uTimePlayed + v39;
-        v37->Apply(v36, a7b, v43, 0, 0);
-        goto LABEL_139;
-      }
-      if ( v41 == 1 )
-      {
-        v42 = 18000 * uSkill;
-        v43 = 5 * uSkill + 10;
-       pGame->pStru6Instance->SetPlayerBuffAnim(0x53u, 0);
-       pGame->pStru6Instance->SetPlayerBuffAnim(0x53u, 1u);
-       pGame->pStru6Instance->SetPlayerBuffAnim(0x53u, 2u);
-       pGame->pStru6Instance->SetPlayerBuffAnim(0x53u, 3u);
-       v39 = (signed __int64)((double)(v42 << 7) * 0.033333335);
-       v37 = &pParty->pPartyBuffs[PARTY_BUFF_DAY_OF_GODS];
-       v36 = pParty->uTimePlayed + v39;
-       v37->Apply(v36, a7b, v43, 0, 0);
-       goto LABEL_139;
-      }
-    }
-    v42 = 10800 * uSkill;
-    v43 = 3 * uSkill + 10;
-    pGame->pStru6Instance->SetPlayerBuffAnim(0x53u, 0);
-    pGame->pStru6Instance->SetPlayerBuffAnim(0x53u, 1u);
-    pGame->pStru6Instance->SetPlayerBuffAnim(0x53u, 2u);
-    pGame->pStru6Instance->SetPlayerBuffAnim(0x53u, 3u);
-    v39 = (signed __int64)((double)(v42 << 7) * 0.033333335);
-    v37 = &pParty->pPartyBuffs[PARTY_BUFF_DAY_OF_GODS];
-    v36 = pParty->uTimePlayed + v39;
-    v37->Apply(v36, a7b, v43, 0, 0);
-    goto LABEL_139;
-  }
-  if ( spellnum != 58 )
-  {
-    switch ( spellnum )
-    {
-      case 2:
-      case 6:
-      case 18:
-      case 26:
-      case 29:
-      case 32:
-      case 39:
-      case 41:
-        a1.stru_24.Reset();
-        v16 = 0;
-        a1.spell_id = spellnum;
-        a1.spell_level = uSkill;
-        a1.spell_skill = v15;
-        if ( (signed int)pObjectList->uNumObjects <= 0 )
-        {
-          v18 = 0;
-          a1.uObjectDescID = v18;
-          *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
-          a1.vPosition.x = fromx;
-          a1.uAttributes = 16;
-          a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
-          a1.field_60_distance_related_prolly_lod = v55;
-          v20 = yaw;
-          a1.uSpriteFrameID = 0;
-          a1.spell_caster_pid = 8000 | OBJECT_Item;
-          a1.spell_target_pid = 0;
-          a1.uFacing = yaw;
-          a1.uSoundID = 0;
-          v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
-          a1.Create(v20, pitch, v49, 0);
-          goto LABEL_139;
-        }
-        v17 = (char *)&pObjectList->pObjects->uObjectID;
-        while ( (short)a1.uType != *(short *)v17 )
-        {
-          ++v16;
-          v17 += 56;
-          if ( v16 >= (signed int)pObjectList->uNumObjects )
-          {
-            v18 = 0;
-            a1.uObjectDescID = v18;
-            *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
-            a1.vPosition.x = fromx;
-            a1.uAttributes = 16;
-            a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
-            a1.field_60_distance_related_prolly_lod = v55;
-            v20 = yaw;
-            a1.uSpriteFrameID = 0;
-            a1.spell_caster_pid = 8000 | OBJECT_Item;
-            a1.spell_target_pid = 0;
-            a1.uFacing = yaw;
-            a1.uSoundID = 0;
-            v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
-            a1.Create(v20, pitch, v49, 0);
-            goto LABEL_139;
-          }
-        }
-        v18 = v16;
-        a1.uObjectDescID = v18;
-        *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
-        a1.vPosition.x = fromx;
-        a1.uAttributes = 16;
-        a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
-        a1.field_60_distance_related_prolly_lod = v55;
-        v20 = yaw;
-        a1.uSpriteFrameID = 0;
-        a1.spell_caster_pid = 8000 | OBJECT_Item;
-        a1.spell_target_pid = 0;
-        a1.uFacing = yaw;
-        a1.uSoundID = 0;
-        v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
-        a1.Create(v20, pitch, v49, 0);
-        goto LABEL_139;
-      case 24:
-        switch ( v15 )
-        {
-          case 1:
-            v60 = 1;
-            break;
-          case 2:
-            v60 = 3;
-            break;
-          case 3:
-            v60 = 5;
-            break;
-          case 4:
-            v60 = 7;
-            break;
-        }
-        a7c = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360;
-        if ( v60 != 1 )
-        {
-          a8b = a7c / (v60 - 1);
-          a1.stru_24.Reset();
-          v21 = 0;
-          a1.spell_id = spellnum;
-          a1.spell_level = uSkill;
-          a1.spell_skill = v15;
-          if ( (signed int)pObjectList->uNumObjects <= 0 )
-          {
-            v23 = 0;
-          }
-          else
-          {
-            v22 = (char *)&pObjectList->pObjects->uObjectID;
-            while ( (short)a1.uType != *(short *)v22 )
-            {
-              ++v21;
-              v22 += 56;
-              if ( v21 >= (signed int)pObjectList->uNumObjects )
-              {
-                v23 = 0;
-                a1.uObjectDescID = v23;
-                *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
-                a1.vPosition.x = fromx;
-                a1.uAttributes = 16;
-                a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
-                a1.field_60_distance_related_prolly_lod = v55;
-                a1.uSpriteFrameID = 0;
-                a1.spell_caster_pid = 8000 | OBJECT_Item;
-                a1.spell_target_pid = 4;
-                a1.uSoundID = 0;
-                for ( i = a7c / -2; i <= a7c / 2; i += a8b )
-                {
-                  a1.uFacing = i + yaw;
-                  a1.Create((signed __int16)(i + (short)yaw), pitch, pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed, 0);
-                }
-                goto LABEL_139;
-              }
-            }
-            v23 = v21;
-          }
-          a1.uObjectDescID = v23;
-          *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
-          a1.vPosition.x = fromx;
-          a1.uAttributes = 16;
-          a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
-          a1.field_60_distance_related_prolly_lod = v55;
-          a1.uSpriteFrameID = 0;
-          a1.spell_caster_pid = 8000 | OBJECT_Item;
-          a1.spell_target_pid = 4;
-          a1.uSoundID = 0;
-          for ( i = a7c / -2; i <= a7c / 2; i += a8b )
-          {
-            a1.uFacing = i + yaw;
-            a1.Create((signed __int16)(i + (short)yaw), pitch, pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed, 0);
-          }
-          goto LABEL_139;
-        }
-        a1.stru_24.Reset();
-        v16 = 0;
-        a1.spell_id = spellnum;
-        a1.spell_level = uSkill;
-        a1.spell_skill = v15;
-        if ( (signed int)pObjectList->uNumObjects <= 0 )
-       {
-         v18 = 0;
-         a1.uObjectDescID = v18;
-         *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
-         a1.vPosition.x = fromx;
-         a1.uAttributes = 16;
-         a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
-         a1.field_60_distance_related_prolly_lod = v55;
-         v20 = yaw;
-         a1.uSpriteFrameID = 0;
-         a1.spell_caster_pid = 8000 | OBJECT_Item;
-         a1.spell_target_pid = 0;
-         a1.uFacing = yaw;
-         a1.uSoundID = 0;
-         v51 = 0;
-         v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
-         v47 = pitch;
-         a1.Create(v20, v47, v49, v51);
-         goto LABEL_139;
-       }
-        v19 = (char *)&pObjectList->pObjects->uObjectID;
-        do
-        {
-          if ( (short)a1.uType == *(short *)v19 )
-          {
-            v18 = v16;
-            a1.uObjectDescID = v18;
-            *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
-            a1.vPosition.x = fromx;
-            a1.uAttributes = 16;
-            a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
-            a1.field_60_distance_related_prolly_lod = v55;
-            v20 = yaw;
-            a1.uSpriteFrameID = 0;
-            a1.spell_caster_pid = 8000 | OBJECT_Item;
-            a1.spell_target_pid = 0;
-            a1.uFacing = yaw;
-            a1.uSoundID = 0;
-            v51 = 0;
-            v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
-            v47 = pitch;
-            a1.Create(v20, v47, v49, v51);
-            goto LABEL_139;
-          }
-          ++v16;
-          v19 += 56;
-        }
-        while ( v16 < (signed int)pObjectList->uNumObjects );
-        v18 = 0;
-        a1.uObjectDescID = v18;
-        *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
-        a1.vPosition.x = fromx;
-        a1.uAttributes = 16;
-        a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
-        a1.field_60_distance_related_prolly_lod = v55;
-        v20 = yaw;
-        a1.uSpriteFrameID = 0;
-        a1.spell_caster_pid = 8000 | OBJECT_Item;
-        a1.spell_target_pid = 0;
-        a1.uFacing = yaw;
-        a1.uSoundID = 0;
-        v51 = 0;
-        v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
-        v47 = pitch;
-        a1.Create(v20, v47, v49, v51);
-        goto LABEL_139;
-      case 15:
-        switch ( v15 )
-        {
-          case 1:
-            v60 = 3;
-            break;
-          case 2:
-            v60 = 5;
-            break;
-          case 3:
-            v60 = 7;
-            break;
-          case 4:
-            v60 = 9;
-            break;
-        }
-        a7d = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360;
-        a8c = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360 / (v60 - 1);
-        a1.stru_24.Reset();
-        v25 = 0;
-        a1.spell_id = spellnum;
-        a1.spell_level = uSkill;
-        a1.spell_skill = v15;
-        if ( (signed int)pObjectList->uNumObjects <= 0 )
-        {
-          v27 = 0;
-          a1.uObjectDescID = v27;
-          *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
-          a1.vPosition.x = fromx;
-          a1.uAttributes = 16;
-          a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
-          a1.field_60_distance_related_prolly_lod = v55;
-          a1.uSpriteFrameID = 0;
-          a1.spell_caster_pid = 8000 | OBJECT_Item;
-          a1.spell_target_pid = 4;
-          a1.uSoundID = 0;
-          for ( j = a7d / -2; j <= a7d / 2; j += a8c )
-          {
-            a1.uFacing = j + yaw;
-            a1.Create((signed __int16)(j + (short)yaw), pitch, pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed, 0);
-          }
-          goto LABEL_139;
-        }
-        v26 = (char *)&pObjectList->pObjects->uObjectID;
-        while ( (short)a1.uType != *(short *)v26 )
-        {
-          ++v25;
-          v26 += 56;
-          if ( v25 >= (signed int)pObjectList->uNumObjects )
-          {
-            v27 = 0;
-            a1.uObjectDescID = v27;
-            *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
-            a1.vPosition.x = fromx;
-            a1.uAttributes = 16;
-            a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
-            a1.field_60_distance_related_prolly_lod = v55;
-            a1.uSpriteFrameID = 0;
-            a1.spell_caster_pid = 8000 | OBJECT_Item;
-            a1.spell_target_pid = 4;
-            a1.uSoundID = 0;
-            for ( j = a7d / -2; j <= a7d / 2; j += a8c )
-            {
-              a1.uFacing = j + yaw;
-              a1.Create((signed __int16)(j + (short)yaw), pitch, pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed, 0);
-            }
-            goto LABEL_139;
-          }
-        }
-        v27 = v25;
-        a1.uObjectDescID = v27;
-        *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
-        a1.vPosition.x = fromx;
-        a1.uAttributes = 16;
-        a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
-        a1.field_60_distance_related_prolly_lod = v55;
-        a1.uSpriteFrameID = 0;
-        a1.spell_caster_pid = 8000 | OBJECT_Item;
-        a1.spell_target_pid = 4;
-        a1.uSoundID = 0;
-        for ( j = a7d / -2; j <= a7d / 2; j += a8c )
-        {
-          a1.uFacing = j + yaw;
-          a1.Create(
-            (signed __int16)(j + (short)yaw),
-            pitch,
-            pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed,
-            0);
-        }
-        goto LABEL_139;
-      case 43:
-        if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
-          return;
-        a1.stru_24.Reset();
-        v29 = 0;
-        a1.spell_id = spellnum;
-        a1.spell_level = uSkill;
-        a1.spell_skill = v15;
-        if ( (signed int)pObjectList->uNumObjects <= 0 )
-        {
-          v31 = 0;
-          a1.uObjectDescID = v31;
-          *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
-          a1.vPosition.x = fromx;
-          a1.uAttributes = 16;
-          a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
-          a1.field_60_distance_related_prolly_lod = v55;
-          a1.uSpriteFrameID = 0;
-          a1.spell_caster_pid = 8000 | OBJECT_Item;
-          a1.spell_target_pid = 4;
-          a1.uSoundID = 0;
-          v51 = 0;
-          v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
-          v20 = yaw;
-          v47 = (signed int)stru_5C6E00->uIntegerHalfPi / 2;
-          a1.Create(v20, v47, v49, v51);
-          goto LABEL_139;
-        }
-        v30 = (char *)&pObjectList->pObjects->uObjectID;
-        break;
-
-      case SPELL_FIRE_HASTE:
-        if ( v15 > 0 )
-        {
-          if ( v15 <= 2 )
-          {
-            v9 = 60 * (uSkill + 60);
-          }
-          else
-          {
-            if ( v15 == 3 )
-            {
-              v9 = 180 * (uSkill + 20);
-            }
-            else
-            {
-              if ( v15 == 4 )
-                v9 = 240 * (uSkill + 15);
-            }
-          }
-        }
-        //levela = 1;
-        //v32 = pParty->pPlayers;//[0].pConditions[1];
-        //do
-        for (uint i = 0; i < 4; ++i)
-          if (pParty->pPlayers[i].pConditions[Player::Condition_Weak])
-            return;
-		//while ( v32 <= &pParty->pPlayers[3] );
-        //if ( !levela )
-        //  return;
-        pParty->pPartyBuffs[PARTY_BUFF_HASTE].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(v9 * 128) * 0.033333335),
-          v15,
-          0,
-          0,
-          0);
-        //v33 = spellnum_;
-        pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 0);
-        pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 1);
-        pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 2);
-        pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 3);
-        goto LABEL_138;
-      case 17:
-      case 38:
-      case 51:
-        switch ( v15 )
-        {
-          case 1:
-          case 2:
-            v9 = 300 * (uSkill + 12);
-            break;
-          case 3:
-            v9 = 900 * (uSkill + 4);
-            break;
-          case 4:
-            v9 = 3600 * (uSkill + 1);
-            break;
-        }
-        switch ( spellnum )
-        {
-          case 17:
-            v60 = 0;
-            uSkill = 14;
-            break;
-          case 38:
-            v35 = uSkill + 5;
-            uSkill = 15;
-            v60 = v35;
-            break;
-          case 51:
-            v34 = uSkill + 5;
-            uSkill = 9;
-            v60 = v34;
-            break;
-        }
-        pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 0);
-        pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 1);
-        pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 2);
-        pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 3);
-        v52 = 0;
-        v50 = 0;
-        v48 = v60;
-        v46 = v15;
-        v36 = pParty->uTimePlayed + (signed int)(signed __int64)((double)(v9 << 7) * 0.033333335);
-        v37 = &pParty->pPartyBuffs[uSkill];
-        v37->Apply(v36, v46, v48, v50, v52);
-        goto LABEL_139;;
-      case 8:
-        if ( v15 == 2 || v15 == 3 || v15 != 4 )
-          v38 = 60 * uSkill;
-        else
-          v38 = 600 * uSkill;
-        pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 0);
-        pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 1);
-        pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 2);
-        pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 3);
-        v52 = 0;
-        v50 = 0;
-        v48 = uSkill;
-        v46 = v15;
-        v39 = (signed __int64)((double)(v38 << 7) * 0.033333335);
-        v37 = &pParty->pPartyBuffs[PARTY_BUFF_IMMOLATION];
-        v36 = pParty->uTimePlayed + v39;
-        v37->Apply(v36, v46, v48, v50, v52);
-        goto LABEL_139;
-      case 3:
-      case 14:
-      case 25:
-      case 36:
-        goto LABEL_117;
-      default:
-        return;
-    }
-    while ( (short)a1.uType != *(short *)v30 )
-    {
-      ++v29;
-      v30 += 56;
-      if ( v29 >= (signed int)pObjectList->uNumObjects )
-      {
-        v31 = 0;
-        a1.uObjectDescID = v31;
-        *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
-        a1.vPosition.x = fromx;
-        a1.uAttributes = 16;
-        a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
-        a1.field_60_distance_related_prolly_lod = v55;
-        a1.uSpriteFrameID = 0;
-        a1.spell_caster_pid = 8000 | OBJECT_Item;
-        a1.spell_target_pid = 4;
-        a1.uSoundID = 0;
-        v51 = 0;
-        v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
-        v20 = yaw;
-        v47 = (signed int)stru_5C6E00->uIntegerHalfPi / 2;
-        a1.Create(v20, v47, v49, v51);
-        goto LABEL_139;
-      }
-    }
-    v31 = v29;
-    a1.uObjectDescID = v31;
-    *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
-    a1.vPosition.x = fromx;
-    a1.uAttributes = 16;
-    a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
-    a1.field_60_distance_related_prolly_lod = v55;
-    a1.uSpriteFrameID = 0;
-    a1.spell_caster_pid = 8000 | OBJECT_Item;
-    a1.spell_target_pid = 4;
-    a1.uSoundID = 0;
-    v51 = 0;
-    v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
-    v20 = yaw;
-    v47 = (signed int)stru_5C6E00->uIntegerHalfPi / 2;
-    a1.Create(v20, v47, v49, v51);
-    goto LABEL_139;
-  }
-LABEL_117:
-  v44 = uSkill;
-  a6_4 = 3600 * uSkill;
-  if ( v15 == 1 )
-  {
-    v60 = v44;
-    goto LABEL_125;
-  }
-  if ( v15 == 2 )
-  {
-    v44 = 2 * uSkill;
-    v60 = v44;
-    goto LABEL_125;
-  }
-  if ( v15 == 3 )
-  {
-    v44 = 3 * uSkill;
-    v60 = v44;
-    goto LABEL_125;
-  }
-  if ( v15 == 4 )
-  {
-    v44 = 4 * uSkill;
-    v60 = v44;
-    goto LABEL_125;
-  }
-LABEL_125:
-  switch ( spellnum )
-  {
-    case 3:
-      uSkill = 6;
-      break;
-    case 14:
-      uSkill = 0;
-      break;
-    case 25:
-      uSkill = 17;
-      break;
-    case 36:
-      uSkill = 4;
-      break;
-    case 58:
-      uSkill = 12;
-      break;
-    case 69:
-      uSkill = 1;
-      break;
-  }
-  //v45 = spellnum_;
-  pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 0);
-  pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 1);
-  pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 2);
-  pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 3);
-  pParty->pPartyBuffs[uSkill].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)a6_4 * 4.2666669), v15, v60, 0, 0);
-  //levela = 1;
-LABEL_138:
-  //if ( levela )
-LABEL_139:
-    pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[spellnum], 0, 0, fromx, fromy, 0, 0, 0);
-}
 // 4EE088: using guessed type __int16 word_4EE088_sound_ids[];
 
 //----- (0044987B) --------------------------------------------------------
@@ -13992,1103 +12376,9 @@
   }
 }
 
-//----- (004014E6) --------------------------------------------------------
-void MakeActorAIList_ODM()
-{
-  int v1; // eax@4
-  int v2; // ebx@4
-  unsigned int v3; // ecx@4
-  int v4; // edx@5
-  int v5; // edx@7
-  unsigned int v6; // edx@9
-  unsigned int v7; // ST20_4@10
-  int v9; // edi@10
-  int v10; // ebx@14
-  int v21; // [sp+Ch] [bp-14h]@4
-  int v22; // [sp+10h] [bp-10h]@4
-
-  pParty->uFlags &= 0xFFFFFFCFu;
-
-  ai_arrays_size = 0;
-  for (uint i = 0; i < uNumActors; ++i)
-  {
-    auto actor = &pActors[i];
-
-    actor->uAttributes &= 0xFFFFFBFF;
-    if (!actor->CanAct())
-    {
-      actor->uAttributes &= 0xFFFFBFFF;
-      continue;
-    }
-
-    v22 = abs(pParty->vPosition.z - actor->vPosition.z);
-    v21 = abs(pParty->vPosition.y - actor->vPosition.y);
-    v1 = abs(pParty->vPosition.x - actor->vPosition.x);
-      v2 = v21;
-      v3 = v22;
-      if ( v1 < v21 )
-      {
-        v4 = v1;
-        v1 = v21;
-        v2 = v4;
-      }
-      if ( v1 < v22 )
-      {
-        v5 = v1;
-        v1 = v22;
-        v3 = v5;
-      }
-      if ( v2 < (signed int)v3 )
-      {
-        v6 = v3;
-        v3 = v2;
-        v2 = v6;
-      }
-      v7 = ((unsigned int)(11 * v2) >> 5) + (v3 >> 2) + v1;
-	  //v8 = actor->uActorRadius;
-      v9 = v7 - actor->uActorRadius;
-      //v23 = v7 - v8;
-      if ( v9 < 0 )
-      {
-        v9 = 0;
-        //v23 = 0;
-      }
-
-      if (v9 < 5632)
-      {
-        v10 = actor->uAttributes & 0xFEFFFFFF;
-        actor->uAttributes = v10;
-        if ( v10 & 0x80000 || actor->GetActorsRelation(0) )
-        {
-          //v11 = (pParty->uFlags & 0x10) == 0;
-          actor->uAttributes = v10 | 0x1000000;
-          if (v9 < 5120 )
-            pParty->SetYellowAlert();
-          if (v9 < 307)
-            pParty->SetRedAlert();
-        }
-		actor->uAttributes |= 0x00004000;
-        ai_near_actors_distances[ai_arrays_size] = v9;
-        ai_near_actors_ids[ai_arrays_size++] = i;
-      }
-      else
-		  actor->uAttributes &= 0xFFFFBFFF;
-  }
-
-  /*
-  result = v27;
-  if ( v27 > 0 )
-  {
-    v14 = 0;
-    v15 = 1;
-    v26 = 1;
-    do
-    {
-      while ( 1 )
-      {
-        v24 = v15;
-        if ( v15 >= result )
-          break;
-        v16 = ai_near_actors_distances[v14];
-        if ( v16 > ai_near_actors_distances[v15] )
-        {
-          v17 = &ai_near_actors_ids[v15];
-          v18 = ai_near_actors_ids[v14];
-          ai_near_actors_ids[v14] = *v17;
-          *v17 = v18;
-          v15 = v24;
-          ai_near_actors_distances[v14] = ai_near_actors_distances[v24];
-          ai_near_actors_distances[v24] = v16;
-        }
-        result = v27;
-        ++v15;
-      }
-      ++v14;
-      v15 = v26 + 1;
-      v26 = v15;
-    }
-    while ( v15 - 1 < result );
-  }*/
-
-  for (uint i = 0; i < ai_arrays_size; ++i)
-    for (uint j = 0; j < i; ++j)
-      if (ai_near_actors_distances[j] > ai_near_actors_distances[i])
-      {
-        int tmp = ai_near_actors_distances[j];
-        ai_near_actors_distances[j] = ai_near_actors_distances[i];
-        ai_near_actors_distances[i] = tmp;
-
-        tmp = ai_near_actors_ids[j];
-        ai_near_actors_ids[j] = ai_near_actors_ids[i];
-        ai_near_actors_ids[i] = tmp;
-      }
-
-
-  if (ai_arrays_size > 30)
-    ai_arrays_size = 30;
-
-  for (uint i = 0; i < ai_arrays_size; ++i)
-    pActors[ai_near_actors_ids[i]].uAttributes |= 0x0400;
-}
-// 4F75D8: using guessed type int ai_arrays_size;
-
-//----- (004016FA) --------------------------------------------------------
-int __cdecl MakeActorAIList_BLV()
-{
-  Actor *v0; // esi@2
-  int v1; // eax@4
-  int v2; // ebx@4
-  unsigned int v3; // ecx@4
-  int v4; // edx@5
-  int v5; // edx@7
-  unsigned int v6; // edx@9
-  unsigned int v7; // ST24_4@10
-  int v8; // eax@10
-  int v9; // edi@10
-  int v10; // ebx@14
-  char v11; // zf@16
-  int v12; // eax@22
-  int v13; // edx@24
-  int v14; // ecx@25
-  int v15; // ebx@26
-  unsigned int *v16; // ecx@27
-  unsigned int v17; // esi@27
-  int v18; // ecx@31
-  signed int v19; // edi@31
-  Actor *v20; // esi@32
-  bool v21; // eax@33
-  int v22; // eax@34
-  signed int v23; // ebx@36
-  Actor *v24; // esi@37
-  signed int v25; // eax@40
-  int v26; // eax@43
-  int v27; // ebx@45
-  int j; // edi@45
-  unsigned int v29; // eax@46
-  int v30; // eax@48
-  int v31; // ecx@51
-  int v32; // eax@51
-  signed int v33; // eax@53
-  __int64 v34; // qax@55
-  char *v35; // ecx@56
-  int v37; // [sp+Ch] [bp-18h]@1
-  int v38; // [sp+10h] [bp-14h]@4
-  int v39; // [sp+14h] [bp-10h]@4
-  int v40; // [sp+18h] [bp-Ch]@10
-  int v41; // [sp+18h] [bp-Ch]@29
-  int i; // [sp+18h] [bp-Ch]@31
-  signed int v43; // [sp+1Ch] [bp-8h]@1
-  signed int v44; // [sp+1Ch] [bp-8h]@25
-  int v45; // [sp+20h] [bp-4h]@1
-
-//  __debugbreak(); // refactor for blv ai
-  pParty->uFlags &= 0xFFFFFFCFu;
-  v37 = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z);
-  v45 = 0;
-  v43 = 0;
-  if ( (signed int)uNumActors > 0 )
-  {
-    v0 = pActors.data();//[0].uAttributes;
-    do
-    {
-      BYTE1(v0->uAttributes) &= 0xFBu;
-      if ( ! v0->CanAct() )
-        goto LABEL_60;
-	  v39 = abs(pParty->vPosition.z - v0->vPosition.z);
-	  v38 = abs(pParty->vPosition.y - v0->vPosition.y);
-	  v1 = abs(pParty->vPosition.x - v0->vPosition.x);
-      v2 = v38;
-      v3 = v39;
-      if ( v1 < v38 )
-      {
-        v4 = v1;
-        v1 = v38;
-        v2 = v4;
-      }
-      if ( v1 < v39 )
-      {
-        v5 = v1;
-        v1 = v39;
-        v3 = v5;
-      }
-      if ( v2 < (signed int)v3 )
-      {
-        v6 = v3;
-        v3 = v2;
-        v2 = v6;
-      }
-      v7 = ((unsigned int)(11 * v2) >> 5) + (v3 >> 2) + v1;
-      v8 = v0->uActorRadius;
-      v9 = v7 - v8;
-      v40 = v7 - v8;
-      if ( v40 < 0 )
-      {
-        v9 = 0;
-        v40 = 0;
-      }
-      if ( v9 < 10240 )
-      {
-        v10 = v0->uAttributes & 0xFEFFFFFF;
-        v0->uAttributes = v10;
-        if ( v10 & 0x80000 || v0->GetActorsRelation(0) )
-        {
-          v11 = (pParty->uFlags & 0x10) == 0;
-          v0->uAttributes = v10 | 0x1000000;
-          if ( v11 && (double)v40 < 307.2 )
-            pParty->uFlags |= 0x10u;
-          if ( !(pParty->uFlags & 0x20) && v9 < 5120 )
-            pParty->uFlags |= 0x20u;
-        }
-        v12 = v45++;
-        ai_near_actors_distances[v12] = v9;
-        ai_near_actors_ids[v12] = v43;
-      }
-      else
-      {
-LABEL_60:
-        BYTE1(v0->uAttributes) &= 0xBFu;
-      }
-      ++v43;
-      ++v0;
-    }
-    while ( v43 < (signed int)uNumActors );
-  }
-  v13 = 0;
-  if ( v45 > 0 )
-  {
-    v14 = 1;
-    v44 = 1;
-    do
-    {
-      while ( 1 )
-      {
-        v41 = v14;
-        if ( v14 >= v45 )
-          break;
-        v15 = ai_near_actors_distances[v13];
-        if ( v15 > ai_near_actors_distances[v14] )
-        {
-          v16 = &ai_near_actors_ids[v14];
-          v17 = ai_near_actors_ids[v13];
-          ai_near_actors_ids[v13] = *v16;
-          *v16 = v17;
-          v14 = v41;
-          ai_near_actors_distances[v13] = ai_near_actors_distances[v41];
-          ai_near_actors_distances[v41] = v15;
-        }
-        ++v14;
-      }
-      ++v13;
-      v14 = v44 + 1;
-      v44 = v14;
-    }
-    while ( v14 - 1 < v45 );
-  }
-  v18 = 0;
-  v19 = 0;
-  for ( i = 0; v18 < v45; i = v18 )
-  {
-    v20 = &pActors[ai_near_actors_ids[v18]];
-    if ( v20->uAttributes & 0x8000
-      || (v21 = sub_4070EF_prolly_collide_objects(PID(OBJECT_Actor,ai_near_actors_ids[v18]), 4u), v18 = i, v21) )
-    {
-      v22 = ai_near_actors_ids[v18];
-      v20->uAttributes |= 0x8000u;
-      ai_array_4F6638_actor_ids[v19] = v22;
-      ai_array_4F5E68[v19++] = ai_near_actors_distances[v18];
-      if ( v19 >= 30 )
-        break;
-    }
-    ++v18;
-  }
-  v23 = 0;
-  ai_arrays_size = v19;
-  if ( (signed int)uNumActors > 0 )
-  {
-    v24 = pActors.data();//[0].uAttributes;
-    do
-    {
-      if ( v24->CanAct() && v24->uSectorID == v37 )
-      {
-        v25 = 0;
-        if ( v19 <= 0 )
-        {
-LABEL_43:
-          v26 = ai_arrays_size;
-          BYTE1(v24->uAttributes) |= 0x40u;
-          ++ai_arrays_size;
-          ai_array_4F6638_actor_ids[v26] = v23;
-        }
-        else
-        {
-          while ( ai_array_4F6638_actor_ids[v25] != v23 )
-          {
-            ++v25;
-            if ( v25 >= v19 )
-              goto LABEL_43;
-          }
-        }
-      }
-      ++v23;
-      ++v24;
-    }
-    while ( v23 < (signed int)uNumActors );
-  }
-  v27 = ai_arrays_size;
-  for ( j = 0; j < v45; ++j )
-  {
-    v29 = ai_near_actors_ids[j];
-    if ( pActors[v29].uAttributes & 0xC000 && pActors[v29].CanAct() )
-    {
-      v30 = 0;
-      if ( v27 <= 0 )
-      {
-LABEL_51:
-        v31 = ai_arrays_size;
-        v32 = ai_near_actors_ids[j];
-        ++ai_arrays_size;
-        ai_array_4F6638_actor_ids[v31] = v32;
-      }
-      else
-      {
-        while ( ai_array_4F6638_actor_ids[v30] != ai_near_actors_ids[j] )
-        {
-          ++v30;
-          if ( v30 >= v27 )
-            goto LABEL_51;
-        }
-      }
-    }
-  }
-  v33 = ai_arrays_size;
-  if ( ai_arrays_size > 30 )
-  {
-    v33 = 30;
-    ai_arrays_size = 30;
-  }
-  memcpy(ai_near_actors_ids.data(), ai_array_4F6638_actor_ids.data(), 4 * v33);
-  memcpy(ai_near_actors_distances.data(), ai_array_4F5E68.data(), 4 * ai_arrays_size);
-  v34 = (unsigned int)ai_arrays_size;
-  if ( ai_arrays_size > 0 )
-  {
-    do
-    {
-      v35 = (char *)&pActors[ai_near_actors_ids[HIDWORD(v34)]].uAttributes;
-      v35[1] |= 4u;
-      ++HIDWORD(v34);
-    }
-    while ( SHIDWORD(v34) < (signed int)v34 );
-  }
-  return v34;
-}
 // 4F75D8: using guessed type int ai_arrays_size;
 
-//----- (00401A91) --------------------------------------------------------
-void __cdecl UpdateActorAI()
-{
-	//unsigned int v0; // esi@4
-	int v1; // eax@7
-	//int v2; // ecx@7
-	//int v3; // eax@7
-	signed int v4; // edi@10
-	Actor *v5; // esi@12
-	signed int sDmg; // eax@14
-	__int16 v7; // cx@14
-	//Player **v8; // esi@20
-	Player *pPlayer; // ecx@21
-	Actor *pActor; // esi@34
-	//__int16 v11; // ax@34
-	//unsigned int v12; // eax@47
-	//signed int v13; // edi@47
-	//SpellBuff *v14; // ebx@47
-	//unsigned int v15; // edi@67
-	//char *v16; // eax@67
-	//unsigned int v17; // edx@67
-	//unsigned int v18; // ecx@67
-	//unsigned __int16 v19; // ax@72
-	//int *v20; // esi@80
-	//Actor *v21; // ebx@80
-	unsigned __int16 v22; // ax@86
-	//signed int v23; // eax@94
-	//unsigned int v24; // eax@102
-	//signed int v25; // edi@102
-	//SpellBuff *v26; // esi@102
-	unsigned int v27; // ecx@123
-	unsigned int v28; // eax@123
-	//unsigned int v29; // eax@127
-	AIDirection *v30; // eax@129
-	unsigned __int16 v31; // ax@132
-	//unsigned int v32; // esi@142
-	int v33; // eax@144
-	int v34; // eax@147
-	char v35; // al@150
-	unsigned int v36; // edi@152
-	signed int v37; // eax@154
-	//unsigned __int8 v38; // sf@158
-	//unsigned __int8 v39; // of@158
-	//signed int v40; // edx@166
-	//unsigned int v41; // ecx@166
-	double v42; // st7@176
-	double v43; // st6@176
-	//bool v44; // eax@189
-	bool v45; // eax@192
-	unsigned __int8 v46; // cl@197
-	double v47; // st7@206
-	//double v48; // st7@207
-	//char v49; // zf@208
-	//char v50; // zf@214
-	//signed int v51; // edx@219
-	//unsigned int v52; // ecx@219
-	__int16 v53; // fps@224
-	//unsigned __int8 v54; // c0@224
-	//unsigned __int8 v55; // c3@224
-	//double v56; // st7@226
-	AIDirection *v57; // eax@246
-	double v58; // st7@246
-	//signed int v59; // [sp-18h] [bp-C8h]@213
-	//int v60; // [sp-14h] [bp-C4h]@144
-	//int v61; // [sp-14h] [bp-C4h]@168
-	//AIDirection *v62; // [sp-14h] [bp-C4h]@213
-	//signed int v63; // [sp-14h] [bp-C4h]@216
-	unsigned int v64; // [sp-14h] [bp-C4h]@219
-	unsigned int v65; // [sp-10h] [bp-C0h]@144
-	char v66; // [sp-10h] [bp-C0h]@147
-	//AIDirection *v67; // [sp-10h] [bp-C0h]@167
-	//int v68; // [sp-10h] [bp-C0h]@168
-	//AIDirection *v69; // [sp-10h] [bp-C0h]@206
-	int v70; // [sp-10h] [bp-C0h]@213
-	//AIDirection *v71; // [sp-10h] [bp-C0h]@216
-	AIDirection v72; // [sp+0h] [bp-B0h]@246
-	AIDirection a3; // [sp+1Ch] [bp-94h]@129
-	AIDirection v74; // [sp+38h] [bp-78h]@246
-	AIDirection v75; // [sp+54h] [bp-5Ch]@129
-	int target_pid_type; // [sp+70h] [bp-40h]@83
-	signed int a1; // [sp+74h] [bp-3Ch]@129
-	int v78; // [sp+78h] [bp-38h]@79
-	AIDirection pDir; // [sp+7Ch] [bp-34h]@129
-	float v80; // [sp+98h] [bp-18h]@33
-	int v81; // [sp+9Ch] [bp-14h]@100
-	//int v82; // [sp+A0h] [bp-10h]@45
-	//unsigned int uActorID; // [sp+A4h] [bp-Ch]@32
-	unsigned int v84; // [sp+A8h] [bp-8h]@11
-	signed int target_pid; // [sp+ACh] [bp-4h]@83
-	AIState uAIState;
-	int v38;
-	
-	if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor)
-		MakeActorAIList_ODM();
-	else
-		MakeActorAIList_BLV();
-	
-	//v0 = 0;
-	if ( uCurrentlyLoadedLevelType != LEVEL_Indoor && pParty->armageddon_timer > 0 )
-	{
-		if ( pParty->armageddon_timer > 417 )
-		{
-			pParty->armageddon_timer = 0;
-		}
-		else
-		{
-			pParty->sRotationY = (stru_5C6E00->uIntegerDoublePi - 1) & (pParty->sRotationY + rand() % 16 - 8);
-			pParty->sRotationX = pParty->sRotationX + rand() % 16 - 8;
-			if ( pParty->sRotationX > 128) 
-				pParty->sRotationX = 128;
-			else if ( pParty->sRotationX < -128 )
-				pParty->sRotationX = -128;
-				
-			pParty->uFlags |= 2u;
-			pParty->armageddon_timer -= pMiscTimer->uTimeElapsed;
-			v4 = pParty->field_16140 + 50;
-			if ( pParty->armageddon_timer <= 0 )
-			{
-				pParty->armageddon_timer = 0;
-				for(int i = 0; i < uNumActors; i++)
-				{
-					pActor=&pActors[i];
-					if ( pActor->CanAct() )
-					{
-						sDmg = stru_50C198.CalcMagicalDamageToActor(pActor, 5, v4);
-						pActor->sCurrentHP -= stru_50C198.CalcMagicalDamageToActor(pActor, 5, v4);
-						if ( sDmg )
-						{
-							if ( pActor->sCurrentHP >= 0 )
-							{
-								Actor::AI_Stun(i, 4, 0);
-							}
-							else
-							{
-								Actor::Die(i);
-								if ( pActor->pMonsterInfo.uExp )
-									GivePartyExp(pMonsterStats->pInfos[pActor->pMonsterInfo.uID].uExp);
-							}
-						}
-					}
-				}
-				for(int i = 1; i <= 4; i++)
-				{
-					pPlayer = pPlayers[i];
-					if ( !pPlayer->pConditions[14] && !pPlayer->pConditions[15] && !pPlayer->pConditions[16] )
-						pPlayer->ReceiveDamage(v4, DMGT_5);
-				}
-			}
-			if (pTurnEngine->field_1C)
-				--pTurnEngine->field_1C;
-		}
-	}
-	
-	if (pParty->bTurnBasedModeOn)
-	{
-		pTurnEngine->_405E14();
-		return;
-	}
-	
-	
-	//uActorID = v0;
-	for (uint i = 0; i < uNumActors; ++i)
-	{
-		pActor = &pActors[i];
-		//LODWORD(v80) = (int)(char *)pActors + 176; // uAIState
-		//do
-		//{
-			//pActor = (Actor *)(LODWORD(v80) - 176);
-			//v11 = *(unsigned int *)LODWORD(v80);
-			//v49 = *(unsigned int *)LODWORD(v80) == 5;
-			ai_near_actors_targets_pid[i] = OBJECT_Player;
-			if (pActor->uAIState == Dead || pActor->uAIState == Removed || pActor->uAIState == Disabled || pActor->uAttributes & 0x0400)
-				continue;
-			
-			if (!pActor->sCurrentHP && pActor->uAIState != Dying)
-				Actor::Die(i);
-			
-			//v84 = *(_QWORD *)(LODWORD(v80) + 84) <= 0i64 ? 0 : 1;
-			//v82 = *(_QWORD *)(LODWORD(v80) + 52) <= 0i64 ? 0 : 1;
-			//v12 = 0;
-			//v13 = 0;
-			//v14 = (SpellBuff *)(LODWORD(v80) + 36);
-			for (uint j = 0; j < 22; ++j)
-			{
-				if (j != 10)
-				pActor->pActorBuffs[j]._4585CA(pParty->uTimePlayed);
-			}
-			/*do
-			{
-				if ( v13 != 10 )
-				{
-					v14->_4585CA(pParty->uTimePlayed);
-					v12 = 0;
-				}
-				++v13;
-				++v14;
-			}
-			while ( v13 < 22 );*/
-			if ( (signed __int64)pActor->pActorBuffs[ACTOR_BUFF_SHRINK].uExpireTime < 0 )
-			//&& SHIDWORD(pActor->pActorBuffs[3].uExpireTime) <= (signed int)v12 && (SHIDWORD(pActor->pActorBuffs[3].uExpireTime) < (signed int)v12
-			// || LODWORD(pActor->pActorBuffs[3].uExpireTime) <= v12) )
-				pActor->uActorHeight = pMonsterList->pMonsters[pActor->pMonsterInfo.uID - 1].uMonsterHeight;
-			if ( (signed __int64)pActor->pActorBuffs[ACTOR_BUFF_CHARM].uExpireTime > 0 )
-				pActor->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly;
-			// not sure
-			else  if ( (signed __int64)pActor->pActorBuffs[ACTOR_BUFF_CHARM].uExpireTime < 0 )
-				pActor->pMonsterInfo.uHostilityType = pMonsterStats->pInfos[pActor->pMonsterInfo.uID].uHostilityType;
-			
-			if ((signed __int64)pActor->pActorBuffs[ACTOR_BUFF_PARALYZED].uExpireTime > 0 
-				|| (signed __int64)pActor->pActorBuffs[ACTOR_BUFF_STONED].uExpireTime > 0)
-				continue;
-			
-			//v15 = pMiscTimer->uTimeElapsed;
-			//v16 = (char *)&pActor->pMonsterInfo.uRecoveryTime;
-			//v17 = pActor->uCurrentActionTime;
-			//v18 = pActor->pMonsterInfo.uRecoveryTime;
-			if (pActor->pMonsterInfo.uRecoveryTime)
-			{
-				if (pActor->pMonsterInfo.uRecoveryTime < pMiscTimer->uTimeElapsed)
-					pActor->pMonsterInfo.uRecoveryTime = 0;
-				else 
-					pActor->pMonsterInfo.uRecoveryTime -= pMiscTimer->uTimeElapsed;
-			}
-			
-			pActor->uCurrentActionTime += pMiscTimer->uTimeElapsed;
-			if (pActor->uCurrentActionTime < pActor->uCurrentActionLength)
-				continue;
-			
-			//v19 = actor->uAIState;
-			if (pActor->uAIState == Dying)
-				pActor->uAIState = Dead;
-			else
-			{
-				if (pActor->uAIState != Summoned)
-				{
-					Actor::AI_StandOrBored(i, OBJECT_Player, 256, nullptr);
-					continue;
-				}
-				pActor->uAIState = Standing;
-			}
-			
-			pActor->uCurrentActionTime = 0;
-			pActor->uCurrentActionLength = 0;
-			pActor->UpdateAnimation();
-			//LABEL_78:
-			//++uActorID;
-			//LODWORD(v80) += 836;
-		//}
-		//while ( (signed int)uActorID < (signed int)uNumActors );
-	}
-	
-	
-	v78 = 0;
-	int actor_id = -1;
-	if ( ai_arrays_size > 0 )
-	{
-		//while ( 1 )
-		for(v78 = 0; v78 < ai_arrays_size; ++v78)
-		{
-			actor_id = ai_near_actors_ids[v78];
-			assert(actor_id < uNumActors);
-			
-			//v20 = &ai_near_actors_targets_pid[actor_id];
-			pActor = &pActors[actor_id];
-			Actor::_SelectTarget(actor_id, &ai_near_actors_targets_pid[actor_id], true);
-			if (pActor->pMonsterInfo.uHostilityType && !ai_near_actors_targets_pid[actor_id])
-				pActor->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly;
-			target_pid = ai_near_actors_targets_pid[actor_id];
-			target_pid_type = PID_TYPE(target_pid);
-			if ( target_pid_type == OBJECT_Actor)
-				v80 = 0.5;
-			else
-				v80 = 1.0;
-			v22 = pActor->uAIState;
-			if ( v22 == Dying || v22 == Dead || v22 == Removed || v22 == Disabled || v22 == Summoned)
-			{
-				continue;
-			}
-			if ( !pActor->sCurrentHP )
-				Actor::Die(actor_id);
-			for(int i=0;i<22;i++)
-			{
-				if ( i != 10 )
-				{
-					pActor->pActorBuffs[i]._4585CA(pParty->uTimePlayed);
-				}
-			}
-			if ( (signed __int64)pActor->pActorBuffs[ACTOR_BUFF_SHRINK].uExpireTime < 0 )
-				pActor->uActorHeight = pMonsterList->pMonsters[pActor->pMonsterInfo.uID - 1].uMonsterHeight;
-			if ( (signed __int64)pActor->pActorBuffs[ACTOR_BUFF_CHARM].uExpireTime > 0 )
-				pActor->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly;
-			// not sure
-			else if ( (signed __int64)pActor->pActorBuffs[ACTOR_BUFF_CHARM].uExpireTime < 0 )
-				pActor->pMonsterInfo.uHostilityType = pMonsterStats->pInfos[pActor->pMonsterInfo.uID].uHostilityType;
-			if ( (signed __int64)pActor->pActorBuffs[2].uExpireTime < 0 )
-			{
-				pActor->uAIState = Removed;
-				continue;
-			}
-			if ( (signed __int64)pActor->pActorBuffs[5].uExpireTime > 0
-				|| (signed __int64)pActor->pActorBuffs[6].uExpireTime > 0)
-			{
-				continue;
-			}
-			v27 = pMiscTimer->uTimeElapsed;
-			v28 = pActor->pMonsterInfo.uRecoveryTime;
-			pActor->uCurrentActionTime += pMiscTimer->uTimeElapsed;
-			if ( (signed int)v28 > 0 )
-				pActor->pMonsterInfo.uRecoveryTime = v28 - v27;
-			if ( pActor->pMonsterInfo.uRecoveryTime < 0 )
-				pActor->pMonsterInfo.uRecoveryTime = 0;
-			if ( !(pActor->uAttributes & 0x8000) )
-				pActor->uAttributes |= 0x8000;
-			a1 = PID(OBJECT_Actor,actor_id);
-			v30 = Actor::GetDirectionInfo(PID(OBJECT_Actor,actor_id), target_pid, &a3, 0);
-			memcpy(&v75, v30, sizeof(v75));
-			memcpy(&pDir, &v75, sizeof(pDir));
-			uAIState = pActor->uAIState; 
-			/*if ( v21->pMonsterInfo.uHostilityType != MonsterInfo::Hostility_Friendly
-				&& (signed int)v21->pMonsterInfo.uRecoveryTime <= 0
-				&& v80 * 307.2 >= (double)(signed int)v75.uDistance
-				&& (uAIState == Pursuing || uAIState == Standing || uAIState == Tethered || uAIState == Fidgeting)
-				|| ( v21->pMonsterInfo.uMissleAttack1Type && uAIState == Stunned ) )
-			{
-				v32 = actor_id;
-			}
-			else
-			*/
-			if ( pActor->pMonsterInfo.uHostilityType == MonsterInfo::Hostility_Friendly
-				|| (signed int)pActor->pMonsterInfo.uRecoveryTime > 0
-				|| v80 * 307.2 < (double)(signed int)v75.uDistance
-				|| uAIState != Pursuing && uAIState != Standing && uAIState != Tethered && uAIState != Fidgeting
-				&&  !pActor->pMonsterInfo.uMissleAttack1Type || uAIState != Stunned )
-			{
-				if ( (signed int)pActor->uCurrentActionTime < pActor->uCurrentActionLength )
-				{
-					continue;
-				}
-				else if ( pActor->uAIState == AttackingMelee )
-				{
-					v35 = stru_50C198.special_ability_use_check(pActor, actor_id);
-					stru_50FE08.Add(
-						a1,
-						5120,
-						pActor->vPosition.x,
-						pActor->vPosition.y,
-						pActor->vPosition.z + ((signed int)pActor->uActorHeight >> 1),
-						v35,
-						1
-					);
-				}
-				else if ( pActor->uAIState == AttackingRanged1 )
-				{
-					v34 = pActor->pMonsterInfo.uMissleAttack1Type;
-					Actor::AI_RangedAttack(actor_id, &pDir, v34, 0);
-				}
-				else if ( pActor->uAIState == AttackingRanged2 )
-				{
-					v34 = pActor->pMonsterInfo.uMissleAttack2Type;
-					Actor::AI_RangedAttack(actor_id, &pDir, v34, 1);
-				}
-				else if ( pActor->uAIState == AttackingRanged3 )
-				{
-					v65 = pActor->pMonsterInfo.uSpellSkillAndMastery1;
-					v33 = pActor->pMonsterInfo.uSpell1ID;
-					Actor::AI_SpellAttack(actor_id, &pDir, v33, 2, v65);
-				}
-				else if ( pActor->uAIState == AttackingRanged4 )
-				{
-					v65 = pActor->pMonsterInfo.uSpellSkillAndMastery2;
-					v33 = pActor->pMonsterInfo.uSpell2ID;
-					Actor::AI_SpellAttack(actor_id, &pDir, v33, 3, v65);
-				}
-			}
-
-			v36 = v75.uDistance;
-			if ( pActor->pMonsterInfo.uHostilityType == MonsterInfo::Hostility_Friendly)
-			{
-				if ( target_pid_type == OBJECT_Actor )
-				{
-					v36 = v75.uDistance;
-					//v37 = (unsigned __int8)*(&byte_5C8D1A[89 * (pActor->pMonsterInfo.uID - 1) / 3]
-					//	+ (pActors[PID_ID(target_pid)].pMonsterInfo.uID - 1) / 3);
-                    v37 =pFactionTable->relations[(pActor->pMonsterInfo.uID-1) / 3 + 1][(pActors[PID_ID(target_pid)].pMonsterInfo.uID - 1) / 3 + 1];
-				}
-				else
-				{
-					v37 = 4;
-				}
-				v38=0;
-				if ( v37 == 2 )
-				{
-					//v39 = __OFSUB__(v36, 1024);
-					//v38 = ((v36 - 1024) & 0x80000000u) != 0;
-					v38 = 1024;
-				}
-				else if ( v37 == 3 )
-				{
-					//v39 = __OFSUB__(v36, 2560);
-					//v38 = ((v36 - 2560) & 0x80000000u) != 0;
-					v38 = 2560;
-				}
-				else if ( v37 == 4 )
-				{
-					//v39 = __OFSUB__(v36, 5120);
-					//v38 = ((v36 - 5120) & 0x80000000u) != 0;
-					v38 = 5120;
-				}
-				if ( v37 >= 1 && v37 <= 4 && v36 < v38  || v37 == 1 )
-					pActor->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Long;
-			}
-
-			if ( (signed __int64)pActor->pActorBuffs[4].uExpireTime > 0 )
-			{
-				if ( (signed int)v36 >= 10240 )
-				{
-					Actor::AI_4032B2(actor_id, target_pid, 1024, 0);
-				}
-				else
-				{
-					//peasents after attacked
-					//guard after attacked
-					Actor::AI_Flee(actor_id, target_pid, 0, &pDir);
-				}
-				continue;
-			}
-
-			if ( pActor->pMonsterInfo.uHostilityType == MonsterInfo::Hostility_Long && target_pid )
-			{
-
-				if ( pActor->pMonsterInfo.uAIType == 1 )
-				{
-					if ( pActor->pMonsterInfo.uMovementType == 5 )
-					{
-						Actor::AI_Stand(actor_id, target_pid, (signed __int64)((double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333),	&pDir);
-					}
-					else
-					{
-						Actor::AI_Flee(actor_id, target_pid, 0, &pDir);
-						continue;
-					}
-						
-				}
-				if ( !(pActor->uAttributes & 0x020000) )
-				{
-					if ( pActor->pMonsterInfo.uAIType == 2 || pActor->pMonsterInfo.uAIType == 3)
-					{
-						if ( pActor->pMonsterInfo.uAIType == 2 )
-							v43 = (double)(signed int)pActor->pMonsterInfo.uHP * 0.2;
-						if ( pActor->pMonsterInfo.uAIType == 3 )
-							v43 = (double)(signed int)pActor->pMonsterInfo.uHP * 0.1;
-						v84 = pActor->sCurrentHP;
-						v42 = (double)(signed int)v84;
-						if ( v43 > v42 && (signed int)v36 < 10240 )
-						{
-							Actor::AI_Flee(actor_id, target_pid, 0, &pDir);
-							continue;
-						}
-					}
-				}
-				
-				v81 = v36 - pActor->uActorRadius;
-				if ( target_pid_type == OBJECT_Actor )
-					v81 -= pActors[PID_ID(target_pid)].uActorRadius;
-				if ( v81 < 0 )
-					v81 = 0;
-				rand();
-				pActor->uAttributes &= 0xFFFBFFFF;
-				if ( v81 < 5120 )
-				{
-					v45 = stru_50C198.special_ability_use_check(pActor, actor_id);
-					if ( v45 == 0 )
-					{
-						if ( pActor->pMonsterInfo.uMissleAttack1Type )
-						{
-							if ( (signed int)pActor->pMonsterInfo.uRecoveryTime <= 0 )
-							{
-								Actor::AI_MissileAttack1(actor_id, target_pid, &pDir);
-							}
-							else if ( pActor->pMonsterInfo.uMovementType == 5 )
-							{
-								v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-								v64 = (signed __int64)v47;
-								Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
-							}
-							else
-							{
-								v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-								if ( v80 * 307.2 > (double)v81 )
-								{
-									v64 = (signed __int64)v47;
-									Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
-								}
-								else
-								{
-									Actor::AI_Pursue1(actor_id, target_pid, actor_id, (signed __int64)v47, &pDir);
-								}
-							}
-						}
-						else
-						{
-							if ( (double)v81 >= v80 * 307.2 )
-							{
-								if ( v81 >= 1024 )
-								{
-									if ( pActor->pMonsterInfo.uMovementType == 5 )
-									{
-										v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-										v64 = (signed __int64)v47;
-										Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
-									}
-									else
-									{
-										//monsters
-										Actor::AI_Pursue3(actor_id, target_pid, 0, &pDir);
-									}
-								}
-								else if ( pActor->pMonsterInfo.uMovementType == 5 )
-								{
-									v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-									v64 = (signed __int64)v47;
-									Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
-								}
-								else
-								{
-									v70 = (signed __int64)v80 * 307.2;
-									//monsters
-									//guard after player runs away
-									// follow player
-									Actor::AI_Pursue2(actor_id, target_pid, 0, &pDir, v70);
-								}
-							}
-							else if ( (signed int)pActor->pMonsterInfo.uRecoveryTime > 0 )
-							{
-								v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-								v64 = (signed __int64)v47;
-								Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
-							}
-							else
-							{
-								//monsters
-								Actor::AI_MeleeAttack(actor_id, target_pid, &pDir);
-							}
-						}
-						continue;
-					}
-					else if ( v45 == 2 || v45 == 3 )
-					{
-						if ( v45 == 2 )
-							v46 = pActor->pMonsterInfo.uSpell1ID;
-						else
-							v46 = pActor->pMonsterInfo.uSpell2ID;
-						if ( v46 )
-						{
-							if ( (signed int)pActor->pMonsterInfo.uRecoveryTime <= 0 )
-							{
-								if ( v45 == 2 )
-									Actor::AI_SpellAttack1(actor_id, target_pid, &pDir);
-								else
-									Actor::AI_SpellAttack2(actor_id, target_pid, &pDir);
-							}
-							else if ( v80 * 307.2 > (double)v81 || pActor->pMonsterInfo.uMovementType == 5 )
-							{
-								v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-								v64 = (signed __int64)v47;
-								Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
-							}
-							else
-							{
-								v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-								Actor::AI_Pursue1(actor_id, target_pid, actor_id, (signed __int64)v47, &pDir);
-							}
-						}
-						else
-						{
-							if ( (double)v81 >= v80 * 307.2 )
-							{
-								if ( v81 >= 1024 )
-								{
-									if ( pActor->pMonsterInfo.uMovementType == 5 )
-									{
-										v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-										v64 = (signed __int64)v47;
-										Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
-									}
-									else
-									{
-										Actor::AI_Pursue3(actor_id, target_pid, 256, &pDir);
-									}
-								}
-								else if ( pActor->pMonsterInfo.uMovementType == 5 )
-								{
-									v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-									v64 = (signed __int64)v47;
-									Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
-								}
-								else
-								{
-									v70 = (signed __int64)v80 * 307.2;
-									Actor::AI_Pursue2(actor_id, target_pid, 0, &pDir, v70);
-								}
-							}
-							else if ( (signed int)pActor->pMonsterInfo.uRecoveryTime > 0 )
-							{
-								v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-								v64 = (signed __int64)v47;
-								Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
-							}
-							else
-							{
-								Actor::AI_MeleeAttack(actor_id, target_pid, &pDir);
-							}
-						}
-						continue;
-					}
-				}
-			}
-			
-			if ( pActor->pMonsterInfo.uHostilityType != MonsterInfo::Hostility_Long || !target_pid || v81 >= 5120 || v45 != 1 )
-			{
-				if ( !pActor->pMonsterInfo.uMovementType )
-				{
-					Actor::AI_4032B2(actor_id, 4, 1024, 0);
-				}
-				else if ( pActor->pMonsterInfo.uMovementType == 1 )
-				{
-					Actor::AI_4032B2(actor_id, 4, 2560, 0);
-				}
-				else if ( pActor->pMonsterInfo.uMovementType == 2 )
-				{
-					Actor::AI_4032B2(actor_id, 4, 5120, 0);
-				}
-				else if ( pActor->pMonsterInfo.uMovementType == 4 )
-				{
-					Actor::AI_4032B2(actor_id, 4, 10240, 0);
-				}
-				else if ( pActor->pMonsterInfo.uMovementType == 5 )
-				{
-					v57 = Actor::GetDirectionInfo(a1, 4u, &v72, 0);
-					v58 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-					memcpy(&v74, v57, sizeof(v74));
-					memcpy(&pDir, &v74, sizeof(pDir));
-					v64 = (signed __int64)v58;
-					Actor::AI_Stand(actor_id, 4, v64, &pDir);
-				}				
-			}
-			else if ( !pActor->pMonsterInfo.uMissleAttack2Type )
-			{
-				if ( (double)v81 >= v80 * 307.2 )
-				{
-					if ( v81 >= 1024 )
-					{
-						if ( pActor->pMonsterInfo.uMovementType == 5 )
-						{
-							v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-							v64 = (signed __int64)v47;
-							Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
-						}
-						else
-						{
-							Actor::AI_Pursue3(actor_id, target_pid, 256, &pDir);
-						}
-					}
-					else if ( pActor->pMonsterInfo.uMovementType == 5 )
-					{
-						v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-						v64 = (signed __int64)v47;
-						Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
-					}
-					else
-					{
-						v70 = (signed __int64)v80 * 307.2;
-						Actor::AI_Pursue2(actor_id, target_pid, 0, &pDir, v70);
-					}
-				}
-				else if ( (signed int)pActor->pMonsterInfo.uRecoveryTime > 0 )
-				{
-					v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-					v64 = (signed __int64)v47;
-					Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
-				}
-				else
-				{
-					Actor::AI_MeleeAttack(actor_id, target_pid, &pDir);
-				}
-			}
-			else if ( (signed int)pActor->pMonsterInfo.uRecoveryTime > 0 )
-			{
-				v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-				if ( v80 * 307.2 > (double)v81 || pActor->pMonsterInfo.uMovementType == 5 )
-				{
-					v64 = (signed __int64)v47;
-					Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
-				}
-				else
-				{
-					Actor::AI_Pursue1(actor_id, target_pid, actor_id, (signed __int64)v47, &pDir);
-				}
-			}
-			else
-			{
-				Actor::AI_MissileAttack2(actor_id, target_pid, &pDir);
-			}		
-		}
-	}
-}
+// 4F75D8: using guessed type int ai_arrays_size;
 
 //----- (0040261D) --------------------------------------------------------
 int stru298::Add(__int16 uID, __int16 a3, __int16 x, __int16 y, __int16 z, char a7, char a8)
--- a/mm7_4.cpp	Sun Jun 23 14:27:32 2013 +0600
+++ b/mm7_4.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -45,7 +45,7 @@
 #include "stru159.h"
 #include "texts.h"
 #include "Log.h"
-#include "UIHouses.h"
+#include "UI\UIHouses.h"
 #include "Lights.h"
 
 //----- (0046CC4B) --------------------------------------------------------
@@ -214,400 +214,6 @@
 }
 // 6836C8: using guessed type int 6836C8_num_decorations_6807E8;
 
-//----- (0046CEC3) --------------------------------------------------------
-int BLV_GetFloorLevel(int x, int y, int z, unsigned int uSectorID, unsigned int *pFaceID)
-{
-  int v13; // ecx@13
-  signed int v14; // ebx@14
-  int v15; // eax@16
-  //int v16; // edx@19
-  //int v17; // ST18_4@19
-  //signed int v18; // edx@19
-  //signed __int64 v19; // qtt@19
-  int v21; // eax@27
-  //int v22; // ecx@29
-  signed int v28; // eax@45
-  int v29; // ebx@47
-  int v30; // edx@49
-  //int v31; // ST10_4@49
-  //signed int v32; // edx@49
-  signed __int64 v33; // qtt@49
-  //signed int v34; // eax@54
-  //signed int v35; // esi@56
-  //int result; // eax@57
-  int v38; // edx@62
-  //int v44; // [sp+20h] [bp-20h]@10
-  bool v47; // [sp+24h] [bp-1Ch]@43
-  bool v48; // [sp+28h] [bp-18h]@10
-  bool v49; // [sp+28h] [bp-18h]@41
-  bool v50; // [sp+2Ch] [bp-14h]@12
-  signed int v53; // [sp+30h] [bp-10h]@10
-  signed int v54; // [sp+30h] [bp-10h]@41
-  signed int v55; // [sp+34h] [bp-Ch]@1
-
-  //LOG_DECOMPILATION_WARNING();
-
-  static int blv_floor_id[50]; // 00721200
-  static int blv_floor_level[50]; // 007212C8
-
-  static __int16 word_721390_ys[104]; // idb
-  static __int16 word_721460_xs[104]; // idb
-
-  auto pSector = &pIndoor->pSectors[uSectorID];
-  v55 = 0;
-  for (uint i = 0; i < pSector->uNumFloors; ++i)
-  {
-    auto pFloor = &pIndoor->pFaces[pSector->pFloors[i]];
-    if (pFloor->Clickable())
-      continue;
-
-    assert(pFloor->uNumVertices);
-    if (x <= pFloor->pBounding.x2 && x >= pFloor->pBounding.x1 &&
-        y <= pFloor->pBounding.y2 && y >= pFloor->pBounding.y1)
-    {
-      for (uint j = 0; j < pFloor->uNumVertices; ++j)
-      {
-        word_721460_xs[2 * j] =     pFloor->pXInterceptDisplacements[j] + pIndoor->pVertices[pFloor->pVertexIDs[j]].x;
-        word_721460_xs[2 * j + 1] = pFloor->pXInterceptDisplacements[j] + pIndoor->pVertices[pFloor->pVertexIDs[j + 1]].x;
-        word_721390_ys[2 * j] =     pFloor->pYInterceptDisplacements[j] + pIndoor->pVertices[pFloor->pVertexIDs[j]].y;
-        word_721390_ys[2 * j + 1] = pFloor->pYInterceptDisplacements[j] + pIndoor->pVertices[pFloor->pVertexIDs[j + 1]].y;
-      }
-      word_721460_xs[2 * pFloor->uNumVertices] = word_721460_xs[0];
-      word_721390_ys[2 * pFloor->uNumVertices] = word_721390_ys[0];
-
-      v50 = word_721390_ys[0] >= y;
-      v53 = 0;
-
-      for (uint j = 0; j < 2 * pFloor->uNumVertices; ++j)
-      {
-        if (v53 >= 2)
-          break;
-
-        v48 = v50;
-        v50 = word_721390_ys[j + 1] >= y;
-
-          v13 = i;
-          if (v48 == v50)
-            continue;
-
-            v14 = word_721460_xs[j + 1] >= x ? 0 : 2;
-            v15 = v14 | (word_721460_xs[j] < x);
-
-          if (v15 == 3)
-            continue;
-          else if (!v15)
-            ++v53;
-          else
-          {
-            auto a_div_b = fixpoint_div(y - word_721390_ys[j], word_721390_ys[j + 1] - word_721390_ys[j]);
-            auto res = fixpoint_sub0((signed int)word_721460_xs[j + 1] - (signed int)word_721460_xs[j], a_div_b);
-
-            if (res + word_721460_xs[j] >= x)
-                ++v53;
-          }
-      }
-
-
-        if ( v53 == 1 )
-        {
-          if ( v55 >= 50 )
-            break;
-          if ( pFloor->uPolygonType == POLYGON_Floor || pFloor->uPolygonType == POLYGON_Ceiling )
-          {
-            v21 = pIndoor->pVertices[pFloor->pVertexIDs[0]].z;
-          }
-          else
-          {
-            v21 = fixpoint_sub0(pFloor->zCalc1, x) + fixpoint_sub0(pFloor->zCalc2, y) + (short)(pFloor->zCalc3 >> 16);
-          }
-          blv_floor_level[v55] = v21;
-          blv_floor_id[v55] = pSector->pFloors[i];
-          v55++;
-        }
-    }
-  }
-
-
-  if ( pSector->field_0 & 8 )
-  {
-    for (uint i = 0; i < pSector->uNumPortals; ++i)
-    {
-      auto portal = &pIndoor->pFaces[pSector->pPortals[i]];
-      if (portal->uPolygonType != POLYGON_Floor)
-        continue;
-
-      if (!portal->uNumVertices)
-        continue;
-
-      if (x <= portal->pBounding.x2 && x >= portal->pBounding.x1 &&
-          y <= portal->pBounding.y2 && y >= portal->pBounding.y1 )
-      {
-        for (uint j = 0; j < portal->uNumVertices; ++j)
-        {
-          word_721460_xs[2 * j] =     portal->pXInterceptDisplacements[j] + pIndoor->pVertices[portal->pVertexIDs[j]].x;
-          word_721460_xs[2 * j + 1] = portal->pXInterceptDisplacements[j + 1] + pIndoor->pVertices[portal->pVertexIDs[j + 1]].x;
-          word_721390_ys[2 * j] =     portal->pYInterceptDisplacements[j] + pIndoor->pVertices[portal->pVertexIDs[j]].y;
-          word_721390_ys[2 * j + 1] = portal->pYInterceptDisplacements[j + 1] + pIndoor->pVertices[portal->pVertexIDs[j + 1]].y;
-        }
-        word_721460_xs[2 * portal->uNumVertices] = word_721460_xs[0];
-        word_721390_ys[2 * portal->uNumVertices] = word_721390_ys[0];
-        v54 = 0;
-        v47 = word_721390_ys[0] >= y;
-
-          for (uint j = 0; j < 2 * portal->uNumVertices; ++j)
-          {
-            v49 = v47;
-            if ( v54 >= 2 )
-              break;
-            v47 = word_721390_ys[j + 1] >= y;
-            if ( v49 != v47 )
-            {
-              v28 = word_721460_xs[j + 1] >= x ? 0 : 2;
-              v29 = v28 | (word_721460_xs[j] < x);
-              if ( v29 != 3 )
-              {
-                if ( !v29 )
-                  ++v54;
-                else
-                {
-                  auto a_div_b = fixpoint_div(y - word_721390_ys[j], word_721390_ys[j + 1] - word_721390_ys[j]);
-                  auto res = fixpoint_sub0(word_721460_xs[j + 1] - word_721460_xs[j], a_div_b);
-                  if (res + word_721460_xs[j] >= x)
-                    ++v54;
-                }
-              }
-            }
-          }
-          if ( v54 == 1 )
-          {
-            if ( v55 >= 50 )
-              break;
-            blv_floor_level[v55] = -29000;
-            blv_floor_id[v55] = pSector->pPortals[i];
-            v55++;
-          }
-      }
-    }
-  }
-  if ( v55 == 1 )
-  {
-    *pFaceID = blv_floor_id[0];
-    return blv_floor_level[0];
-  }
-  if ( !v55 )
-    return -30000;
-  *pFaceID = blv_floor_id[0];
-  //result = blv_floor_level[0];
-
-    /*for ( v35 = 1; v35 < v55; ++v35 )
-    {
-      if ( blv_floor_level[0] <= z + 5 )
-      {
-        if ( blv_floor_level[v35] >= blv_floor_level[0] || blv_floor_level[v35] > z + 5 )
-          continue;
-        blv_floor_level[0] = blv_floor_level[v35];
-        *pFaceID = blv_floor_id[v35];
-        continue;
-      }
-      if ( blv_floor_level[v35] < blv_floor_level[0] )
-      {
-        blv_floor_level[0] = blv_floor_level[v35];
-        *pFaceID = blv_floor_id[v35];
-      }
-    }*/
-
-    
-  int result = blv_floor_level[0];
-  for (uint i = 1; i < v55; ++i)
-  {
-      v38 = blv_floor_level[i];
-      if ( result <= z + 5 )
-      {
-        if ( v38 > result && v38 <= z + 5 )
-        {
-          result = blv_floor_level[i];
-          *pFaceID = blv_floor_id[i];
-        }
-      }
-      else if ( v38 < result )
-      {
-        result = blv_floor_level[i];
-        *pFaceID = blv_floor_id[i];
-      }
-  }
-
-  return result;
-}
-
-//----- (0046D49E) --------------------------------------------------------
-int __fastcall ODM_GetFloorLevel(int X, signed int Y, int Z, int __unused, int *pIsOnWater, int *a6, int bWaterWalk)
-{
-  BSPModel *pBModel; // esi@4
-  ODMFace *pFace; // ecx@11
-  int v14; // edx@20
-  signed int v18; // edx@26
-  int v19; // eax@28
-  int v20; // edx@30
-  int v21; // ST1C_4@30
-  signed int v22; // edx@30
-  signed __int64 v23; // qtt@30
-  int v24; // eax@36
-  signed int v25; // ecx@38
-  int result; // eax@42
-  signed int v27; // ecx@43
-  int v28; // edi@44
-  signed int v29; // edx@44
-  int v30; // esi@45
-  int v31; // eax@45
-  ODMFace *v32; // eax@57
-  int v33; // ecx@59
-  int v36; // [sp+14h] [bp-2Ch]@24
-  int v38; // [sp+1Ch] [bp-24h]@2
-  int v39; // [sp+20h] [bp-20h]@9
-  signed int pBModelNum; // [sp+28h] [bp-18h]@1
-  int pFaceNum; // [sp+2Ch] [bp-14h]@8
-  bool v43; // [sp+30h] [bp-10h]@22
-  bool v44; // [sp+34h] [bp-Ch]@24
-  signed int v46; // [sp+3Ch] [bp-4h]@1
-  signed int v48; // [sp+58h] [bp+18h]@22
-  signed int v49; // [sp+58h] [bp+18h]@43
-
-  v46 = 1;
-  dword_721160[0] = -1;
-  dword_721110[0] = -1;
-  odm_floor_level[0] = GetTerrainHeightsAroundParty2(X, Y, pIsOnWater, bWaterWalk);
-  
-  for ( pBModelNum = 0; pBModelNum < pOutdoor->uNumBModels; ++pBModelNum )
-  {
-    pBModel = &pOutdoor->pBModels[pBModelNum];
-    if ( X <= pBModel->sMaxX && X >= pBModel->sMinX &&
-         Y <= pBModel->sMaxY && Y >= pBModel->sMinY )
-    {
-      if ( pBModel->uNumFaces > 0 )
-      {
-        v39 = 0;
-        for ( pFaceNum = 0; pFaceNum < pBModel->uNumFaces; ++pFaceNum )
-        {
-          pFace = &pBModel->pFaces[pFaceNum];
-          if ( (pFace->uPolygonType == POLYGON_Floor || pFace->uPolygonType == POLYGON_InBetweenFloorAndWall)
-            && !(pFace->uAttributes & 0x20000000)
-            && X <= pFace->pBoundingBox.x2 && X >= pFace->pBoundingBox.x1
-            && Y <= pFace->pBoundingBox.y2 && Y >= pFace->pBoundingBox.y1 )
-          {
-            
-              for ( uint i = 0; i < pFace->uNumVertices; ++i)
-              {
-                word_721040[2 * i] = pFace->pXInterceptDisplacements[i] + pBModel->pVertices.pVertices[pFace->pVertexIDs[i]].x;
-                word_720F70[2 * i] = pFace->pXInterceptDisplacements[i + 1] + pBModel->pVertices.pVertices[pFace->pVertexIDs[i]].y;
-                word_721040[2 * i + 1] = pFace->pXInterceptDisplacements[i] + pBModel->pVertices.pVertices[pFace->pVertexIDs[i + 1]].x;
-                word_720F70[2 * i + 1] = pFace->pXInterceptDisplacements[i + 1] + pBModel->pVertices.pVertices[pFace->pVertexIDs[i + 1]].y;
-              }
-            word_721040[2 * pFace->uNumVertices] = word_721040[0];
-            word_720F70[2 * pFace->uNumVertices] = word_720F70[0];
-            v43 = word_720F70[0] >= Y;
-            v48 = 0;
-            if ( 2 * pFace->uNumVertices > 0 )
-            {
-              for ( int i = 0; i < 2 * pFace->uNumVertices; ++i )
-              {
-                if ( v48 >= 2 )
-                  break;
-                v36 = word_720F70[i + 1];
-                v44 = word_720F70[i + 1] >= Y;
-                if ( v43 != v44 )
-                {
-                  v18 = word_721040[i + 1] >= X ? 0 : 2;
-                  v19 = v18 | (word_721040[i] < X);
-                  if ( v19 != 3 )
-                  {
-                    if ( !v19 )
-                      ++v48;
-                    else
-                    {
-                      LODWORD(v23) = (Y - word_720F70[i]) << 16;
-                      HIDWORD(v23) = (Y - word_720F70[i]) >> 16;
-                      v22 = ((((word_721040[i + 1] - word_721040[i]) * v23 / (v36 - word_720F70[i])) >> 16) + word_721040[i]);
-                      if ( v22 >= X) 
-                        ++v48;
-                    }
-                  }
-                }
-                v43 = v44;
-              }
-              if ( v48 == 1 )
-              {
-                if ( v46 >= 20 )
-                  break;
-                if ( pFace->uPolygonType == POLYGON_Floor )
-                  v24 = pBModel->pVertices.pVertices[pFace->pVertexIDs[0]].z;
-                else
-                  v24 = ((unsigned __int64)(pFace->zCalc1 * (signed __int64)X) >> 16) + ((unsigned __int64)(pFace->zCalc2 * (signed __int64)Y) >> 16)
-                + HIWORD(pFace->zCalc3);
-                v25 = v46++;
-                odm_floor_level[v25] = v24;
-                dword_721160[v25] = pBModelNum;
-                dword_721110[v25] = pFaceNum;
-              }
-            }
-          }
-
-        }
-      }
-    }
-  }
-  if ( v46 == 1 )
-  {
-    *a6 = 0;
-    return odm_floor_level[0];
-  }
-  v27 = 0;
-  if ( v46 <= 1 )
-    *a6 = 0;
-  else
-  {
-    //v29 = 1;
-    for ( v49 = 1; v49 < v46; ++v49 )
-    {
-      if ( odm_floor_level[v49] == odm_floor_level[0] )
-      {
-        v27 = v49;
-        //++v29;
-        break;
-      }
-      if ( odm_floor_level[0] > Z + 5 )
-      {
-        if ( odm_floor_level[v49] >= odm_floor_level[0] )
-        {
-          //++v29;
-          break;
-        }
-        v27 = v49;
-        //++v29;
-        break;
-      }
-      if ( odm_floor_level[v49] > odm_floor_level[0] && odm_floor_level[v49] <= Z + 5 )
-      {
-        v27 = v49;
-        //++v29;
-      }
-    }
-    if ( !v27 )
-      *a6 = 0;
-    else
-      *a6 = dword_721110[v27] | (dword_721160[v27] << 6);
-  }
-  if ( v27 )
-  {
-    v32 = &pOutdoor->pBModels[dword_721160[v27]].pFaces[dword_721110[v27]];
-    *pIsOnWater = false;
-    if ( v32->Fluid())
-      *pIsOnWater = true;
-  }
-  if ( odm_floor_level[v27] >= odm_floor_level[0] )
-    odm_floor_level[0] = odm_floor_level[v27];
-  return odm_floor_level[0];
-}
-
 //----- (0046D8E3) --------------------------------------------------------
 int __fastcall sub_46D8E3(int a1, signed int a2, int a3, int a4)
 {
@@ -820,79 +426,6 @@
   return dword_720F20[v22];
 }
 
-//not sure if right- or left-handed coordinate space assumed, so this could be normal of inverse normal
-// for a right-handed system, that would be an inverse normal
-//----- (0046DCC8) --------------------------------------------------------
-void ODM_GetTerrainNormalAt(int pos_x, int pos_z, Vec3_int_ *out)
-{
-  auto grid_x = WorldPosToGridCellX(pos_x);
-  auto grid_z = WorldPosToGridCellZ(pos_z) - 1;
-
-  auto grid_pos_x1 = GridCellToWorldPosX(grid_x);
-  auto grid_pos_x2 = GridCellToWorldPosX(grid_x + 1);
-  auto grid_pos_z1 = GridCellToWorldPosZ(grid_z);
-  auto grid_pos_z2 = GridCellToWorldPosZ(grid_z + 1);
-
-  auto x1z1_y = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z);
-  auto x2z1_y = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z);
-  auto x2z2_y = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z + 1);
-  auto x1z2_y = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z + 1);
-
-  float side1_dx, side1_dy, side1_dz,
-        side2_dx, side2_dy, side2_dz;
-
-  auto dx = abs(pos_x - grid_pos_x1),
-       dz = abs(grid_pos_z1 - pos_z);
-  if (dz >= dx)
-  {
-    side1_dy = (double)(x1z1_y - x1z2_y);
-    side2_dy = (double)(x2z2_y - x1z2_y);
-    side2_dx = (double)(grid_pos_x2 - grid_pos_x1);
-    side1_dx = (double)(grid_pos_x1 - grid_pos_x2);
-    side2_dz = 0.0;//(double)(grid_pos_z2 - grid_pos_z2);  // bug?  z2 - z2 
-    side1_dz = (double)(grid_pos_z1 - grid_pos_z2);  //       z1 - z2 yes
-    //Log::Warning(L"%S %S %u\n", __FILE__, __FUNCTION__, __LINE__);
-    /*       |\
-       side1 |  \
-             |____\
-             side 2      */
-  }
-  else
-  {
-    side1_dy = (double)(x2z2_y - x2z1_y);
-    side2_dy = (double)(x1z1_y - x2z1_y);
-    side2_dx = (double)(grid_pos_x1 - grid_pos_x2);
-    side1_dx = (double)(grid_pos_x2 - grid_pos_x1);
-    side2_dz = 0.0;//(double)(grid_pos_z1 - grid_pos_z1); 
-    side1_dz = (double)(grid_pos_z2 - grid_pos_z1);
-
-    /*   side 2
-         _____
-         \    |
-           \  | side 1
-             \|       */
-  }
-  
-  float nx = side1_dy * side2_dz - side1_dz * side2_dy;
-  float ny = side1_dx * side2_dy - side1_dy * side2_dx;
-  float nz = side1_dz * side2_dx - side1_dx * side2_dz;
-
-  float mag = sqrt(nx * nx + ny * ny + nz * nz);
-  if (fabsf(mag) < 1e-6f)
-  {
-    out->y = 0;
-    out->x = 0;
-    out->z = 65536;
-  }
-  else
-  {
-    float invmag = 1.0 / mag;
-    out->x = invmag * nx * 65536.0;
-    out->y = invmag * ny * 65536.0;
-    out->z = invmag * nz * 65536.0;
-  }
-}
-
 //----- (0046DEF2) --------------------------------------------------------
 unsigned int __fastcall sub_46DEF2(signed int a2, unsigned int uLayingItemID)
 {
@@ -904,75 +437,6 @@
   return result;
 }
 
-//----- (0046DF1A) --------------------------------------------------------
-signed int __fastcall _46DF1A_collide_against_actor(int a1, int a2)
-{
-  Actor *v2; // edi@1
-  unsigned __int16 v3; // ax@1
-  int v4; // esi@6
-  int v5; // ecx@8
-  int v6; // eax@10
-  int v7; // edx@12
-  int v8; // ecx@14
-  int v9; // eax@14
-  int v10; // ebx@14
-  int v11; // esi@14
-  int v12; // ebx@15
-  int v13; // ebx@17
-  unsigned int v14; // eax@20
-  signed int result; // eax@21
-  int v16; // [sp+Ch] [bp-10h]@1
-  int v17; // [sp+10h] [bp-Ch]@14
-  int v18; // [sp+14h] [bp-8h]@14
-  int v19; // [sp+18h] [bp-4h]@14
-
-  v16 = a1;
-  v2 = &pActors[a1];
-  v3 = v2->uAIState;
-  if ( v3 == 11 || v3 == 4 || v3 == 19 || v3 == 5 || v3 == 17 )
-    goto LABEL_25;
-  v4 = v2->uActorRadius;
-  if ( a2 )
-    v4 = a2;
-  v5 = v2->vPosition.x;
-  if ( stru_721530.sMaxX > v5 + v4
-    || stru_721530.sMinX < v5 - v4
-    || (v6 = v2->vPosition.y, stru_721530.sMaxY > v6 + v4)
-    || stru_721530.sMinY < v6 - v4
-    || (v7 = v2->vPosition.z, stru_721530.sMaxZ > v7 + v2->uActorHeight)
-    || stru_721530.sMinZ < v7
-    || (v8 = v5 - stru_721530.normal.x,
-        v9 = v6 - stru_721530.normal.y,
-        v10 = stru_721530.prolly_normal_d + v4,
-        v17 = stru_721530.prolly_normal_d + v4,
-        v11 = (v8 * stru_721530.field_58.y - v9 * stru_721530.field_58.x) >> 16,
-        v18 = v8,
-        v19 = v9,
-        abs((v8 * stru_721530.field_58.y - v9 * stru_721530.field_58.x) >> 16) > v10)
-    || (v12 = (v18 * stru_721530.field_58.x + v19 * stru_721530.field_58.y) >> 16, v12 <= 0)
-    || (signed int)(((unsigned __int64)(stru_721530.field_58.z * (signed __int64)v12) >> 16) + stru_721530.normal.z) < v2->vPosition.z )
-  {
-LABEL_25:
-    result = 0;
-  }
-  else
-  {
-    v13 = v12 - integer_sqrt(v17 * v17 - v11 * v11);
-    if ( v13 < 0 )
-      v13 = 0;
-    if ( v13 < stru_721530.field_7C )
-    {
-      stru_721530.field_7C = v13;
-      v14 = 8 * v16;
-      LOBYTE(v14) = PID(OBJECT_Actor,v16);
-      stru_721530.uFaceID = v14;
-    }
-    result = 1;
-  }
-  return result;
-}
-// 46DF1A: using guessed type int __fastcall 46DF1A_collide_against_actor(int, int);
-
 //----- (0046E0B2) --------------------------------------------------------
 void __cdecl _46E0B2_collide_against_decorations()
 {
@@ -1065,123 +529,6 @@
   }
 }
 
-//----- (0046E26D) --------------------------------------------------------
-void __fastcall _46E26D_collide_against_sprites(signed int a1, signed int a2)
-{
-  int v2; // edx@5
-  unsigned __int16 *v3; // eax@5
-  unsigned __int16 v4; // ax@6
-  LevelDecoration *v5; // edi@7
-  DecorationDesc *v6; // esi@8
-  int v7; // edx@9
-  int v8; // eax@9
-  int v9; // ecx@11
-  int v10; // ebx@13
-  int v11; // esi@13
-  int v12; // ebp@15
-  int v13; // ebx@15
-  int v14; // esi@16
-  int v15; // edi@17
-  int v16; // eax@17
-  int v17; // esi@19
-  char v18; // zf@23
-  int v19; // [sp+0h] [bp-10h]@15
-  unsigned __int16 *v20; // [sp+4h] [bp-Ch]@5
-  int v21; // [sp+8h] [bp-8h]@15
-  int v22; // [sp+Ch] [bp-4h]@13
-
-  if ( a1 >= 0 )
-  {
-    if ( a1 <= 127 )
-    {
-      if ( a2 >= 0 )
-      {
-        if ( a2 <= 127 )
-        {
-          v2 = a1 + (a2 << 7);
-          v3 = &pOutdoor->pFaceIDLIST[pOutdoor->pOMAP[v2]];
-          v20 = &pOutdoor->pFaceIDLIST[pOutdoor->pOMAP[v2]];
-          if ( v3 )
-          {
-            do
-            {
-              v4 = *v3;
-              if ( PID_TYPE(v4) == OBJECT_Decoration)
-              {
-                v5 = &pLevelDecorations[(signed __int16)v4 >> 3];
-                if ( !(v5->field_2 & 0x20) )
-                {
-                  v6 = &pDecorationList->pDecorations[v5->uDecorationDescID];
-                  if (!v6->CanMoveThrough())
-                  {
-                    v7 = v6->uRadius;
-                    v8 = v5->vPosition.x;
-                    if ( stru_721530.sMaxX <= v8 + v7 )
-                    {
-                      if ( stru_721530.sMinX >= v8 - v7 )
-                      {
-                        v9 = v5->vPosition.y;
-                        if ( stru_721530.sMaxY <= v9 + v7 )
-                        {
-                          if ( stru_721530.sMinY >= v9 - v7 )
-                          {
-                            v10 = v6->uDecorationHeight;
-                            v11 = v5->vPosition.z;
-                            v22 = v10;
-                            if ( stru_721530.sMaxZ <= v11 + v10 )
-                            {
-                              if ( stru_721530.sMinZ >= v11 )
-                              {
-                                v12 = v8 - stru_721530.normal.x;
-                                v19 = v9 - stru_721530.normal.y;
-                                v13 = stru_721530.prolly_normal_d + v7;
-                                v21 = ((v8 - stru_721530.normal.x) * stru_721530.field_58.y
-                                     - (v9 - stru_721530.normal.y) * stru_721530.field_58.x) >> 16;
-                                if ( abs(v21) <= stru_721530.prolly_normal_d + v7 )
-                                {
-                                  v14 = (v12 * stru_721530.field_58.x + v19 * stru_721530.field_58.y) >> 16;
-                                  if ( v14 > 0 )
-                                  {
-                                    v15 = v5->vPosition.z;
-                                    v16 = stru_721530.normal.z
-                                        + ((unsigned __int64)(stru_721530.field_58.z * (signed __int64)v14) >> 16);
-                                    if ( v16 >= v15 )
-                                    {
-                                      if ( v16 <= v22 + v15 )
-                                      {
-                                        v17 = v14 - integer_sqrt(v13 * v13 - v21 * v21);
-                                        if ( v17 < 0 )
-                                          v17 = 0;
-                                        if ( v17 < stru_721530.field_7C )
-                                        {
-                                          stru_721530.field_7C = v17;
-                                          stru_721530.uFaceID = (signed __int16)*v20;
-                                        }
-                                      }
-                                    }
-                                  }
-                                }
-                              }
-                            }
-                          }
-                        }
-                      }
-                    }
-                  }
-                }
-              }
-              v3 = v20 + 1;
-              v18 = *v20 == 0;
-              ++v20;
-            }
-            while ( !v18 );
-          }
-        }
-      }
-    }
-  }
-}
-
 //----- (00486F92) --------------------------------------------------------
 void __cdecl sr_sub_486F92_MessWithEdgesAndSpans()
 {
@@ -1428,28 +775,6 @@
 }
 // 4EC3EC: using guessed type Edge defaultEdge;
 
-//----- (00487355) --------------------------------------------------------
-bool OutdoorCamera::_487355()
-{
-  int v0; // esi@1
-  stru148 *v1; // edi@2
-  bool result; // eax@3
-
-  v0 = 0;
-  if ( pOutdoorCamera->numStru148s > 0 )
-  {
-    v1 = array_77EC08.data();
-    do
-    {
-      result = pGame->pLightmapBuilder->_45D3C7(v1);
-      ++v0;
-      ++v1;
-    }
-    while ( v0 < pOutdoorCamera->numStru148s );
-  }
-  return result;
-}
-
 //----- (00487DA9) --------------------------------------------------------
 void __cdecl sub_487DA9()
 {
@@ -1787,68 +1112,6 @@
 }
 // 4ED498: using guessed type char byte_4ED498;
 
-//----- (0049387A) --------------------------------------------------------
-int CycleCharacter(unsigned int _this)
-{
-  signed int result; // eax@1
-  signed int v2; // ecx@2
-  signed int v3; // ecx@8
-
-  result = uActiveCharacter;
-  if ( _this )
-  {
-    v2 = 0;
-    while ( 1 )
-    {
-      --result;
-      if ( result < 1 )
-        result = 4;
-      if ( !pPlayers[result]->uTimeToRecovery )
-        break;
-      ++v2;
-      if ( v2 >= 4 )
-        return uActiveCharacter;
-    }
-  }
-  else
-  {
-    v3 = 0;
-    while ( 1 )
-    {
-      ++result;
-      if ( result > 4 )
-        result = 1;
-      if ( !pPlayers[result]->uTimeToRecovery )
-        break;
-      ++v3;
-      if ( v3 >= 4 )
-        return uActiveCharacter;
-    }
-  }
-  return result;
-}
-//----- (004938D1) --------------------------------------------------------
-void __fastcall Rest(unsigned int uHoursToSleep)
-{
-  unsigned int v1; // esi@1
-  double v2; // st7@3
-  Player **v3; // esi@3
-
-  v1 = uHoursToSleep;
-  if ( uHoursToSleep > 240 )
-    InitializeActors();
-  v2 = (double)(7680 * v1) * 0.033333335;
-  pParty->uTimePlayed += (signed __int64)v2;
-  v3 = &pPlayers[1];
-  do
-  {
-    (*v3)->Recover((signed __int64)v2);
-    ++v3;
-  }
-  while ( (signed int)v3 <= (signed int)&pPlayers[4] );
-  _494035_timed_effects__water_walking_damage__etc();
-}
-
 //----- (00493938) --------------------------------------------------------
 int __cdecl _493938_regenerate()
 {
@@ -2980,244 +2243,6 @@
   return 1;
 }
 
-//----- (00494F3A) --------------------------------------------------------
-unsigned int IconFrameTable::FindIcon(const char *pIconName)
-{
-  IconFrameTable *v2; // esi@1
-  int v3; // ebx@1
-  unsigned int uID; // edi@1
-  unsigned int result; // eax@4
-
-  v2 = this;
-  v3 = 0;
-  uID = 0;
-  if ( (signed int)this->uNumIcons <= 0 )
-  {
-LABEL_4:
-    result = 0;
-  }
-  else
-  {
-    while ( _stricmp(pIconName, v2->pIcons[v3].pAnimationName) )
-    {
-      ++uID;
-      ++v3;
-      if ( (signed int)uID >= (signed int)v2->uNumIcons )
-        goto LABEL_4;
-    }
-    result = uID;
-  }
-  return result;
-}
-
-//----- (00494F70) --------------------------------------------------------
-IconFrame *IconFrameTable::GetFrame(unsigned int uIconID, unsigned int uFrameID)
-{
-  IconFrame *v3; // edi@1
-  IconFrame *v4; // ecx@1
-  __int16 v5; // dx@2
-  int v6; // edx@3
-  unsigned int v7; // eax@3
-  char *i; // ecx@3
-  int v9; // esi@5
-  IconFrame *result; // eax@6
-
-  v3 = this->pIcons;
-  v4 = &v3[uIconID];
-  if ( v4->uFlags & 1 && (v5 = v4->uAnimLength) != 0 )
-  {
-    v6 = ((signed int)uFrameID >> 3) % (unsigned __int16)v5;
-    v7 = uIconID;
-    for ( i = (char *)&v4->uAnimTime; ; i += 32 )
-    {
-      v9 = *(short *)i;
-      if ( v6 <= v9 )
-        break;
-      v6 -= v9;
-      ++v7;
-    }
-    result = &v3[v7];
-  }
-  else
-  {
-    result = &v3[uIconID];
-  }
-  return result;
-}
-
-//----- (00494FBF) --------------------------------------------------------
-void IconFrameTable::InitializeAnimation(unsigned int uIconID)
-{
-  IconFrameTable *v2; // esi@1
-  unsigned int v3; // edi@3
-  const char *i; // eax@3
-  IconFrame *v5; // eax@5
-
-  v2 = this;
-  if ( (signed int)uIconID <= (signed int)this->uNumIcons && (uIconID & 0x80000000u) == 0 )
-  {
-    v3 = uIconID;
-    for ( i = this->pIcons[uIconID].pTextureName; ; i = v5[v3].pTextureName )
-    {
-      v2->pIcons[v3].uTextureID = pIcons_LOD->LoadTexture(i, TEXTURE_16BIT_PALETTE);
-      v5 = v2->pIcons;
-      if ( !(v5[v3].uFlags & 1) )
-        break;
-      ++v3;
-    }
-  }
-}
-
-//----- (0049500A) --------------------------------------------------------
-void IconFrameTable::ToFile()
-{
-  IconFrameTable *v1; // esi@1
-  FILE *v2; // eax@1
-  FILE *v3; // edi@1
-
-  auto Str = this;
-
-  v1 = Str;
-  v2 = fopen("data\\dift.bin", "wb");
-  v3 = v2;
-  if ( !v2 )
-    Abortf("Unable to save dift.bin!");
-  fwrite(v1, 4u, 1u, v2);
-  fwrite(v1->pIcons, 0x20u, v1->uNumIcons, v3);
-  fclose(v3);
-}
-
-//----- (00495056) --------------------------------------------------------
-void IconFrameTable::FromFile(void *pSerialized)
-{
-  uNumIcons = *(int *)pSerialized;
-  pIcons = (IconFrame *)pAllocator->AllocNamedChunk(pIcons, 32 * uNumIcons, "I Frames");
-  memcpy(pIcons, (char *)pSerialized + 4, 32 * uNumIcons);
-}
-
-//----- (0049509D) --------------------------------------------------------
-int IconFrameTable::FromFileTxt(const char *Args)
-{
-  IconFrameTable *v2; // ebx@1
-  FILE *v3; // eax@1
-  int v4; // esi@3
-  void *v5; // eax@10
-  FILE *v6; // ST0C_4@12
-  char *i; // eax@12
-  const char *v8; // ST00_4@15
-  int v9; // eax@16
-  int v10; // edx@20
-  int v11; // ecx@21
-  int v12; // eax@22
-  signed int j; // edx@25
-  IconFrame *v14; // ecx@26
-  int v15; // esi@26
-  int k; // eax@27
-  signed int result; // eax@11
-  char Buf; // [sp+Ch] [bp-2F8h]@3
-  FrameTableTxtLine v19; // [sp+200h] [bp-104h]@4
-  FrameTableTxtLine v20; // [sp+27Ch] [bp-88h]@4
-  int v21; // [sp+2F8h] [bp-Ch]@3
-  int v22; // [sp+2FCh] [bp-8h]@3
-  FILE *File; // [sp+300h] [bp-4h]@1
-  int Argsa; // [sp+30Ch] [bp+8h]@26
-
-  v2 = this;
-  //TileTable::dtor((TileTable *)this);
-  v3 = fopen(Args, "r");
-  File = v3;
-  if ( !v3 )
-    Abortf("IconFrameTable::load - Unable to open file: %s.", Args);
-  v4 = 0;
-  v21 = 0;
-  v22 = 1;
-  if ( fgets(&Buf, 490, v3) )
-  {
-    do
-    {
-      *strchr(&Buf, 10) = 0;
-      memcpy(&v20, frame_table_txt_parser(&Buf, &v19), sizeof(v20));
-      if ( v20.uPropCount && *v20.pProperties[0] != 47 )
-      {
-        if ( v20.uPropCount < 3 )
-          Abortf("IconFrameTable::loadText, too few arguments, %s line %i.", Args, v22);
-        ++v21;
-      }
-      ++v22;
-    }
-    while ( fgets(&Buf, 490, File) );
-    v4 = v21;
-  }
-  v2->uNumIcons = v4;
-  v5 = pAllocator->AllocNamedChunk(v2->pIcons, 32 * v4, "I Frames");
-  v2->pIcons = (IconFrame *)v5;
-  if ( v5 )
-  {
-    v6 = File;
-    v2->uNumIcons = 0;
-    fseek(v6, 0, 0);
-    for ( i = fgets(&Buf, 490, File); i; i = fgets(&Buf, 490, File) )
-    {
-      *strchr(&Buf, 10) = 0;
-      memcpy(&v20, frame_table_txt_parser(&Buf, &v19), sizeof(v20));
-      if ( v20.uPropCount && *v20.pProperties[0] != 47 )
-      {
-        strcpy(v2->pIcons[v2->uNumIcons].pAnimationName, v20.pProperties[0]);
-        strcpy(v2->pIcons[v2->uNumIcons].pTextureName, v20.pProperties[1]);
-        v8 = v20.pProperties[2];
-        v2->pIcons[v2->uNumIcons].uFlags = 0;
-        if ( !_stricmp(v8, "new") )
-        {
-          v9 = (int)&v2->pIcons[v2->uNumIcons].uFlags;
-          *(char *)v9 |= 4u;
-        }
-        v2->pIcons[v2->uNumIcons].uAnimTime = atoi(v20.pProperties[3]);
-        v2->pIcons[v2->uNumIcons].uAnimLength = 0;
-        v2->pIcons[v2->uNumIcons++].uTextureID = 0;
-      }
-    }
-    fclose(File);
-    v10 = 0;
-    if ( (signed int)(v2->uNumIcons - 1) > 0 )
-    {
-      v11 = 0;
-      do
-      {
-        v12 = (int)&v2->pIcons[v11];
-        if ( !(*(char *)(v12 + 60) & 4) )
-          *(char *)(v12 + 28) |= 1u;
-        ++v10;
-        ++v11;
-      }
-      while ( v10 < (signed int)(v2->uNumIcons - 1) );
-    }
-    for ( j = 0; j < (signed int)v2->uNumIcons; *(short *)(Argsa + 26) = v15 )
-    {
-      v14 = v2->pIcons;
-      Argsa = (int)&v14[j];
-      v15 = *(short *)(Argsa + 24);
-      if ( *(char *)(Argsa + 28) & 1 )
-      {
-        ++j;
-        for ( k = (int)&v14[j]; *(char *)(k + 28) & 1; k += 32 )
-        {
-          v15 += *(short *)(k + 24);
-          ++j;
-        }
-        LOWORD(v15) = v14[j].uAnimTime + v15;
-      }
-      ++j;
-    }
-    result = 1;
-  }
-  else
-  {
-    fclose(File);
-    result = 0;
-  }
-  return result;
-}
-
 //----- (00495366) --------------------------------------------------------
 char *__fastcall sub_495366(unsigned __int8 a1, unsigned __int8 a2)
 {
@@ -6138,202 +5163,12 @@
 }
 // F8B1E0: using guessed type int dword_F8B1E0;
 
-//----- (004B1A2D) --------------------------------------------------------
-void __cdecl ShowPopupShopItem()
-{
-  POINT *v1; // esi@5
-  unsigned int v2; // eax@5
-  int v3; // ecx@5
-  POINT *v4; // esi@12
-  int v5; // eax@12
-  unsigned int v6; // eax@13
-  ItemGen *v7; // ecx@13
-  signed int v8; // esi@17
-  unsigned int v9; // eax@19
-  POINT v10; // [sp+8h] [bp-44h]@12
-  POINT v11; // [sp+10h] [bp-3Ch]@12
-  POINT  v12; // [sp+18h] [bp-34h]@18
-  POINT  v13; // [sp+20h] [bp-2Ch]@17
-  POINT v14; // [sp+28h] [bp-24h]@17
-  POINT  v15; // [sp+30h] [bp-1Ch]@17
-  POINT v16; // [sp+38h] [bp-14h]@5
-  POINT a2; // [sp+40h] [bp-Ch]@5
-
-  if ( in_current_building_type <= 0 )
-    return;
-  if ( in_current_building_type <= BildingType_AlchemistShop )
-  {
-    if ( dialog_menu_id != HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
-    {
-      if ( dialog_menu_id <= HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
-        return;
-      if ( dialog_menu_id <= HOUSE_DIALOGUE_SHOP_REPAIR || dialog_menu_id == HOUSE_DIALOGUE_SHOP_DISPLAY_EQUIPMENT )
-      {
-        v8 = pMouse->GetCursorPos(&v15)->x - 14;
-        v5 = (v8 >> 5) + 14 * ((pMouse->GetCursorPos(&v14)->y - 17) >> 5);
-        if ( pMouse->GetCursorPos(&v13)->x <= 13
-          || pMouse->GetCursorPos(&v12)->x >= 462
-          || (v9 = pPlayers[uActiveCharacter]->GetItemIDAtInventoryIndex(&v5)) == 0 )
-          return;
-        GameUI_DrawItemInfo(&pPlayers[uActiveCharacter]->pInventoryItems[v9 - 1]);
-        return;
-      }
-      if ( dialog_menu_id != HOUSE_DIALOGUE_SHOP_BUY_SPECIAL )
-        return;
-    }
-    v4 = pMouse->GetCursorPos(&v11);
-    v5 = pRenderer->pActiveZBuffer[v4->x + pSRZBufferLineOffsets[pMouse->GetCursorPos(&v10)->y]] & 0xFFFF;
-    if ( !v5 )
-      return;
-    v6 = 9 * (v5 + 12 * (unsigned int)window_SpeakInHouse->ptr_1C);
-    v7 = (ItemGen *)((char *)&pParty->pPickedItem + 4 * v6 + 4);
-    if ( dialog_menu_id != HOUSE_DIALOGUE_SHOP_BUY_STANDARD)
-      v7 = &pParty->SpecialItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][v5 - 1];
-    GameUI_DrawItemInfo(v7);
-    return;
-  }
-  if ( in_current_building_type <= BildingType_16 && dialog_menu_id == HOUSE_DIALOGUE_GUILD_BUY_BOOKS )
-  {
-    v1 = pMouse->GetCursorPos(&a2);
-    v2 = v1->x + pSRZBufferLineOffsets[pMouse->GetCursorPos(&v16)->y];
-    v3 = pRenderer->pActiveZBuffer[v2] & 0xFFFF;
-    v5 = pRenderer->pActiveZBuffer[v2] & 0xFFFF;
-    if ( v5 )
-      sub_4B1523((int *)&pParty->pPlayers[1].uExpressionTimeLength + 9 * (v3 + 12 * (unsigned int)window_SpeakInHouse->ptr_1C));
-  }
-}
 // F8B198: using guessed type int dword_F8B198;
 // F8B19C: using guessed type int dword_F8B19C;
 
-//----- (004B1BDB) --------------------------------------------------------
-void __stdcall RestAndHeal(__int64 uNumMinutes)
-{
-  signed __int64 v1; // ST2C_8@1
-  signed __int64 v2; // qax@1
-  signed __int64 v3; // ST1C_8@1
-  unsigned __int64 v4; // qax@1
-  unsigned int v5; // ebx@1
-  Player *v6; // ebx@1
-
-  pParty->pHirelings[0].bHasUsedTheAbility = 0;
-  pParty->pHirelings[1].bHasUsedTheAbility = 0;
-  pParty->uTimePlayed += (signed __int64)((double)(7680 * uNumMinutes) * 0.033333335);
-  v1 = (signed __int64)((double)(signed __int64)pParty->uTimePlayed * 0.234375);
-  v2 = v1 / 60 / 60;
-  v3 = v2;
-  v4 = (unsigned int)v2 / 0x18;
-  v5 = (unsigned int)(v4 / 7) >> 2;
-  pParty->uCurrentTimeSecond = v1 % 60;
-  pParty->uCurrentMinute = v1 / 60 % 60;
-  pParty->uCurrentHour = v3 % 24;
-  pParty->uCurrentMonthWeek = v4 / 7 & 3;
-  pParty->uDaysPlayed = (unsigned int)v4 % 0x1C;
-  pParty->uCurrentMonth = v5 % 0xC;
-  pParty->uCurrentYear = v5 / 0xC + game_starting_year;
-  pParty->RestAndHeal();
-  dword_507B94 = 1;
-  v6 = pParty->pPlayers;//[0].uNumDivineInterventionCastsThisDay;
-  do
-  {
-	v6->uTimeToRecovery = 0;
-	memset(&v6->uTimeToRecovery, 0, 4u);
-    ++v6;
-  }
-  while ( v6 <= &pParty->pPlayers[3] );
-  pParty->UpdatePlayersAndHirelingsEmotions();
-}
+
 // 507B94: using guessed type int dword_507B94;
 
-//----- (004B1D27) --------------------------------------------------------
-void __cdecl sub_4B1D27()
-{
-  int v0; // edx@2
-  unsigned int v1; // ecx@7
-  signed int v2; // edi@10
-  int v3; // esi@10
-  __int16 v4; // ax@15
-  signed int v5; // edi@20
-  int v6; // esi@20
-  int v7[4]; // [sp+Ch] [bp-10h]@12
-
-  if ( in_current_building_type > 0 )
-  {
-    v0 = 3;
-    if ( in_current_building_type > BildingType_MagicShop )
-    {
-      if ( in_current_building_type == BildingType_Bank )
-      {
-        if ( !dword_F8B1E4 )
-          return;
-      }
-      else
-      {
-        if ( in_current_building_type != BildingType_Temple )
-          return;
-      }
-      v1 = (unsigned int)window_SpeakInHouse->ptr_1C;
-      PlayHouseSound(v1, (HouseSoundID)v0);
-      return;
-    }
-    v1 = (unsigned int)window_SpeakInHouse->ptr_1C;
-    if ( (signed __int64)pParty->field_3C._shop_ban_times[v1 ]<= (signed __int64)pParty->uTimePlayed )
-    {
-      if ( pParty->uNumGold <= 0x2710 )
-      {
-        if ( !dword_F8B1E4 )
-          return;
-        v0 = 4;
-        PlayHouseSound(v1, (HouseSoundID)v0);
-        return;
-      }
-      PlayHouseSound(v1, (HouseSoundID)(dword_F8B1E4 + 3));
-      if ( !dword_F8B1E4 && !qword_A750D8 )
-      {
-        v5 = 0;
-        v6 = 1;
-        do
-        {
-          if ( pPlayers[v6]->CanAct() )
-            v7[v5++] = v6;
-          ++v6;
-        }
-        while ( v6 <= 4 );
-        if ( v5 )
-        {
-          qword_A750D8 = 256i64;
-          word_A750E0 = 80;
-          v4 = LOWORD(v7[rand() % v5]);
-          word_A750E2 = v4;
-          return;
-        }
-      }
-    }
-    else
-    {
-      if ( !qword_A750D8 )
-      {
-        v2 = 0;
-        v3 = 1;
-        do
-        {
-          if ( pPlayers[v3]->CanAct() )
-            v7[v2++] = v3;
-          ++v3;
-        }
-        while ( v3 <= 4 );
-        if ( v2 )
-        {
-          qword_A750D8 = 256i64;
-          word_A750E0 = 80;
-          v4 = LOWORD(v7[rand() % v2]);
-          word_A750E2 = v4;
-          return;
-        }
-      }
-    }
-  }
-}
-
 //----- (004B1ECE) --------------------------------------------------------
 void __cdecl sub_4B1ECE()
 {
@@ -6434,285 +5269,6 @@
 // 722B44: using guessed type int dword_722B44;
 // F8B1A8: using guessed type int dword_F8B1A8;
 
-//----- (004B2001) --------------------------------------------------------
-void __fastcall ClickNPCTopic(signed int uMessageParam)
-{
-  //signed int v1; // eax@1
-  NPCData *pCurrentNPCInfo; // ebp@1
-  int pEventNumber; // ecx@8
-  Player *v4; // esi@20
-  //int v5; // eax@28
-  //int v6; // eax@31
-  //int v7; // eax@34
-  //int v8; // eax@37
-  //int v9; // eax@40
-  //unsigned int v10; // eax@43
-  char *v12; // eax@53
-  char *v13; // eax@56
-  char *v14; // eax@57
-  char *v15; // eax@58
-  //unsigned int v16; // ebp@62
-  char *v17; // ecx@63
-  char *v18; // eax@65
-  const char *v19; // ecx@68
-  //unsigned int v20; // eax@69
-  signed int pPrice; // ecx@70
-  char *v22; // [sp-Ch] [bp-18h]@73
-  //int v23; // [sp-8h] [bp-14h]@49
-  char *v24; // [sp-8h] [bp-14h]@73
-  //int v25; // [sp-4h] [bp-10h]@49
-
-  uDialogueType = uMessageParam + 1;
-  pCurrentNPCInfo = HouseNPCData[(unsigned int)((char *)pDialogueNPCCount + -(dword_591080 != 0) )];//- 1
-  if ( uMessageParam <= 24 )
-  {
-  switch ( uMessageParam )
-  {
-    case 13:
-      current_npc_text = pNPCStats->pProfessions[pCurrentNPCInfo->uProfession].pJoinText;//(char *)*(&pNPCStats->field_13A64 + 5 * v2->uProfession);
-      current_npc_text = BuilDialogueString((char *)current_npc_text, uActiveCharacter - 1, 0, 0, 0, 0);
-      NPCHireableDialogPrepare();
-      dialogue_show_profession_details = false;
-      goto _return;
-    case 19:
-      pEventNumber = pCurrentNPCInfo->evt_A;
-      break;
-    case 20:
-      pEventNumber = pCurrentNPCInfo->evt_B;
-      break;
-    case 21:
-      pEventNumber = pCurrentNPCInfo->evt_C;
-      break;
-    case 22:
-      pEventNumber = pCurrentNPCInfo->evt_D;
-      break;
-    case 23:
-      pEventNumber = pCurrentNPCInfo->evt_E;
-      break;
-    case 24:
-      pEventNumber = pCurrentNPCInfo->evt_F;
-      break;
-    default:
-      goto _return;
-  }
-  /*switch ( pEventNumber )
-  {
-    case 139:
-      sub_4B1ECE();
-      goto _return;
-    case 311:
-      sub_4BBA85_bounties();
-    goto _return;
-  }*/
-  if ( pEventNumber < 200 || pEventNumber > 310 )
-    {
-      if ( pEventNumber < 400 || pEventNumber > 410 )
-      {
-        if ( pEventNumber == 139 )
-        {
-          sub_4B1ECE();
-        }
-        else
-        {
-          if ( pEventNumber == 311 )
-          {
-            sub_4BBA85_bounties();
-          }
-          else
-          {
-            current_npc_text = 0;
-            activeLevelDecoration = (LevelDecoration*)1;
-            EventProcessor(pEventNumber, 0, 1);
-            activeLevelDecoration = NULL;
-          }
-        }
-      }
-      else
-      {
-        dword_F8B1D8 = uMessageParam;
-        DrawJoinGuildWindow(pEventNumber - 400);
-      }
-    }
-    else
-    {
-      sub_4B3FE5(pEventNumber);
-    }
-    goto _return;
-  }
-  if ( uMessageParam != 76 )
-  {
-    if ( uMessageParam == 77 )
-    {
-      //v16 = pCurrentNPCInfo->uProfession;
-      if (dialogue_show_profession_details)
-        v17 = pNPCStats->pProfessions[pCurrentNPCInfo->uProfession - 1].pJoinText;
-      else
-        v17 = pNPCStats->pProfessions[pCurrentNPCInfo->uProfession - 1].pBenefits;
-      current_npc_text = v17;
-      v18 = BuilDialogueString(v17, uActiveCharacter - 1, 0, 0, 0, 0);
-      dialogue_show_profession_details = ~dialogue_show_profession_details;
-      current_npc_text = v18;
-    }
-    else
-    {
-      if ( uMessageParam == 79 )
-      {
-        if ( contract_approved )
-        {
-          Party::TakeGold(gold_transaction_amount);
-          if ( uActiveCharacter )
-          {
-            v12 = (char *)&pPlayers[uActiveCharacter]->pActiveSkills[dword_F8B1AC_award_bit_number];
-            *(short *)v12 &= 0x3Fu;
-            switch ( dword_F8B1B0 )
-            {
-              case 2:
-                v15 = (char *)&pPlayers[uActiveCharacter]->pActiveSkills[dword_F8B1AC_award_bit_number];
-                *v15 |= 0x40u;
-                break;
-              case 3:
-                v14 = (char *)&pPlayers[uActiveCharacter]->pActiveSkills[dword_F8B1AC_award_bit_number];
-                *v14 |= 0x80u;
-                break;
-              case 4:
-                v13 = (char *)&pPlayers[uActiveCharacter]->pActiveSkills[dword_F8B1AC_award_bit_number];
-                v13[1] |= 1u;
-                break;
-            }
-            pPlayers[uActiveCharacter]->PlaySound(SPEECH_85, 0);
-          }
-          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;
-          }*/
-        }
-      }
-      else
-      {
-        if ( uMessageParam == 82 && contract_approved ) //join guild
-        {
-          Party::TakeGold(gold_transaction_amount);
-          v4 = pParty->pPlayers;
-          do
-          {
-            v4->SetVariable(VAR_Award, dword_F8B1AC_award_bit_number);
-            ++v4;
-          }
-          while ( (signed int)v4 < (signed int)pParty->pHirelings );
-          switch ( dword_F8B1D8 )
-          {
-            case 19:
-              pEventNumber = pCurrentNPCInfo->evt_A;
-              if ( pEventNumber >= 400 && pEventNumber <= 416 )
-                pCurrentNPCInfo->evt_A = 0;
-              break;
-            case 20:
-              pEventNumber = pCurrentNPCInfo->evt_B;
-              if ( pEventNumber >= 400 && pEventNumber <= 416 )
-                pCurrentNPCInfo->evt_B = 0;
-              break;
-            case 21:
-              pEventNumber = pCurrentNPCInfo->evt_C;
-              if ( pEventNumber >= 400 && pEventNumber <= 416 )
-                pCurrentNPCInfo->evt_C = 0;
-              break;
-            case 22:
-              pEventNumber = pCurrentNPCInfo->evt_D;
-              if ( pEventNumber >= 400 && pEventNumber <= 416 )
-                pCurrentNPCInfo->evt_D = 0;
-              break;
-            case 23:
-              pEventNumber = pCurrentNPCInfo->evt_E;
-              if ( pEventNumber >= 400 && pEventNumber <= 416 )
-                pCurrentNPCInfo->evt_E = 0;
-              break;
-            case 24:
-              pEventNumber = pCurrentNPCInfo->evt_F;
-              if ( pEventNumber >= 400 && pEventNumber <= 416)
-                pCurrentNPCInfo->evt_F = 0;
-              break;
-          }
-          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;
-          }*/
-          //v11 = uActiveCharacter;
-          if ( uActiveCharacter )
-          {
-            pPlayers[uActiveCharacter]->PlaySound((PlayerSpeech)SPEECH_86, 0);
-            goto _return;
-          }
-        }
-      }
-    }
-    goto _return;
-  }
-  if ( pParty->pHirelings[0].pName && pParty->pHirelings[1].pName )
-  {
-    ShowStatusBarString(pGlobalTXT_LocalizationStrings[533], 2);// ""I cannot join you, you're party is full""
-    goto _return;
-  }
-  if ( pCurrentNPCInfo->uProfession != 51 )
-  {
-    pPrice = pNPCStats->pProfessions[pCurrentNPCInfo->uProfession - 1].uHirePrice;
-    if ( pParty->uNumGold < pPrice )
-    {
-      ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2);
-      dialogue_show_profession_details = false;
-      uDialogueType = 13;
-      current_npc_text = pNPCStats->pProfessions[pCurrentNPCInfo->uProfession - 1].pJoinText;
-      current_npc_text = BuilDialogueString((char *)current_npc_text, uActiveCharacter - 1, 0, 0, 0, 0);
-      if ( uActiveCharacter )
-        pPlayers[uActiveCharacter]->PlaySound(SPEECH_NotEnoughGold, 0);
-      ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2);
-      goto _return;
-    }
-    Party::TakeGold(pPrice);
-  }
-  //LOBYTE(v2->uFlags) |= 0x80u;
-  pCurrentNPCInfo->uFlags |= 128;
-  pParty->field_709 = 0;
-  pParty->CountHirelings();
-  if ( pParty->pHirelings[0].pName )
-  {
-    memcpy(&pParty->pHirelings[1], pCurrentNPCInfo, sizeof(pParty->pHirelings[1]));
-    v24 = pCurrentNPCInfo->pName;
-    v22 = pParty->pHireling2Name;
-  }
-  else
-  {
-    memcpy(pParty->pHirelings, pCurrentNPCInfo, 0x4Cu);
-    v24 = pCurrentNPCInfo->pName;
-    v22 = pParty->pHireling1Name;
-  }
-  strcpy(v22, v24);
-  pParty->field_709 = 0;
-  pParty->CountHirelings();
-  PrepareHouse((HOUSE_ID)(int)window_SpeakInHouse->ptr_1C);
-  dialog_menu_id = HOUSE_DIALOGUE_MAIN;
-
-  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;
-  }*/
-  if ( uActiveCharacter )
-    pPlayers[uActiveCharacter]->PlaySound((PlayerSpeech)61, 0);
-_return:
-  pVideoPlayer->_4BF5B2();//HouseVideo
-}
-
 //----- (004B254D) --------------------------------------------------------
 char *__thiscall _4B254D_SkillMasteryTeacher(int _this)
 {
@@ -7086,366 +5642,6 @@
   return pTmpBuf2.data();
 }
 
-//----- (004B29F2) --------------------------------------------------------
-const char * ContractSelectText( int pEventCode )
-	{
-static const int dialogue_base=110;
-  contract_approved = 0;
-  dword_F8B1AC_award_bit_number = pEventCode + 50;
-  gold_transaction_amount = price_for_membership[pEventCode];
-  if ( pPlayers[uActiveCharacter]->CanAct() )
-  {
-    if ( (unsigned __int16)_449B57_test_bit((unsigned __int8 *)pPlayers[uActiveCharacter]->_guilds_member_bits, dword_F8B1AC_award_bit_number) )
-    {
-      return pNPCTopics[dialogue_base+13].pText;
-    }
-    else
-    {
-      if ( gold_transaction_amount <= pParty->uNumGold )
-      {
-        contract_approved = 1;
-        return pNPCTopics[pEventCode + dialogue_base].pText;
-      }
-      else
-      {
-        return pNPCTopics[dialogue_base+14].pText; 
-      }
-    }
-  }
-  else
-  {
-    return pNPCTopics[dialogue_base+12].pText; 
-  }
-}
-
-//----- (004B2A74) --------------------------------------------------------
-void SimpleHouseAndBoatsDialog()
-{
-  char *v0; // esi@3
-  char *v1; // ST1C_4@3
-  char *v2; // eax@3
-  const char *v3; // ST1C_4@5
-  int v4; // eax@5
-  unsigned int i; // eax@5
-  NPCData *v6; // esi@6
-  unsigned __int16 v7; // bx@6
-  unsigned int v8; // eax@6
-  int v9; // eax@11
-  unsigned int v10; // ecx@12
-  int v11; // eax@12
-  int v12; // esi@12
-  char *v13; // eax@12
-  GUIWindow *v14; // ebx@13
-  char *v15; // esi@14
-  GUIButton *v16; // eax@15
-  unsigned int v17; // ecx@15
-  int v18; // ecx@17
-  int v19; // ecx@18
-  int v20; // ecx@19
-  int v21; // ecx@20
-  int v22; // ecx@21
-  unsigned int v23; // ecx@23
-  int v24; // ecx@35
-  int v25; // ecx@36
-  int v26; // ecx@37
-  int v27; // ecx@38
-  int v28; // ecx@39
-  char *v29; // esi@42
-  unsigned int v30; // ST20_4@42
-  int v31; // ST1C_4@42
-  unsigned int v32; // eax@42
-  char *v33; // eax@43
-  int v34; // esi@51
-  int v35; // eax@51
-  unsigned int v36; // edi@51
-  GUIButton *v37; // eax@52
-  int v38; // eax@52
-  signed int v39; // ecx@54
-  int v40; // edi@57
-  GUIButton *v41; // eax@60
-  GUIButton *v42; // esi@60
-  const char *v43; // ebx@60
-  int v44; // eax@60
-  unsigned int v45; // ecx@60
-  unsigned __int16 v46; // ax@60
-  GUIFont *v47; // ebx@64
-  int v48; // esi@64
-  char *v49; // eax@66
-  GUIWindow w; // [sp+Ch] [bp-110h]@64
-  GUIWindow v52; // [sp+60h] [bp-BCh]@13
-  GUIWindow a1; // [sp+B4h] [bp-68h]@1
-  unsigned int v54; // [sp+108h] [bp-14h]@14
-  int v55; // [sp+10Ch] [bp-10h]@6
-  int v56; // [sp+110h] [bp-Ch]@13
-  char *pInString; // [sp+114h] [bp-8h]@12
-  NPCData *v58; // [sp+118h] [bp-4h]@6
-
-  memcpy(&a1, pDialogueWindow, sizeof(a1));
-  if ( pDialogueNPCCount == uNumDialogueNPCPortraits && uHouse_ExitPic )
-  {
-    v0 = pMapStats->pInfos[uHouse_ExitPic].pName;
-    v1 = pMapStats->pInfos[uHouse_ExitPic].pName;
-    a1.uFrameX = 493;
-    a1.uFrameWidth = 126;
-    a1.uFrameZ = 366;
-    a1.DrawTitleText(pFontCreate, 0, 2u, 0, v1, 3u);
-    a1.uFrameX = 483;
-    a1.uFrameWidth = 148;
-    a1.uFrameZ = 334;
-    v2 = pTransitionStrings[uHouse_ExitPic];
-    if ( !v2 )
-    {
-      sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[411], v0);
-      v2 = pTmpBuf.data();
-    }
-    v3 = v2;
-    v4 = pFontCreate->CalcTextHeight(v2, &a1, 0, 0);
-    a1.DrawTitleText(pFontCreate, 0, (212 - v4) / 2 + 101, 0, v3, 3u);
-    return;
-  }
-  a1.uFrameWidth -= 10;
-  a1.uFrameZ -= 10;
-  v58 = HouseNPCData[(unsigned int)((char *)pDialogueNPCCount + -(dword_591080 != 0) )];//- 1
-  v6 = v58;
-  v55 = TargetColor(0xE1u, 0xCDu, 0x23u);
-  v7 = TargetColor(0x15u, 0x99u, 0xE9u);
-  v8 = v6->uProfession;
-  if ( v8 )
-    sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[429], v6->pName, aNPCProfessionNames[v8]);
-  else
-    strcpy(pTmpBuf.data(), v6->pName);
-  a1.DrawTitleText(pFontCreate, 0x1E3u, 0x71u, v7, pTmpBuf.data(), 3u);
-  if ( !dword_591080 )
-  {
-    if ( !uDialogueType )
-    {
-      v9 = v6->greet;
-      if ( v9 )
-      {
-        v10 = v6->uFlags;
-        a1.uFrameWidth = game_viewport_width;
-        a1.uFrameZ = 452;
-        pInString = (char *)*(&pNPCStats->field_17884 + ((v10 & 3) == 2) + 2 * v9);
-        v11 = pFontArrus->CalcTextHeight(pInString, &a1, 13, 0);
-        v12 = v11 + 7;
-        pRenderer->_4A6A68(8, 352 - (v11 + 7),
-          pIcons_LOD->GetTexture(uTextureID_Leather),
-          pIcons_LOD->GetTexture(uTextureID_Leather)->uTextureHeight - (v11 + 7));
-        pRenderer->DrawTextureIndexed(8u, 347 - v12, pTexture_591428);
-        v13 = FitTextInAWindow(pInString, pFontArrus, &a1, 0xDu, 0);
-        pDialogueWindow->DrawText(pFontArrus, 13, 354 - v12, 0, v13, 0, 0, 0);
-      }
-    }
-  }
-  v14 = pDialogueWindow;
-  memcpy(&v52, pDialogueWindow, sizeof(v52));
-  v52.uFrameX = 483;
-  v52.uFrameWidth = 148;
-  v52.uFrameZ = 334;
-  v56 = v52.pStartingPosActiveItem;
-  if ( v52.pStartingPosActiveItem < v52.pStartingPosActiveItem + v52.pNumPresenceButton )
-  {
-    v15 = "";//(char *)v54;
-    while ( 1 )
-    {
-      v16 = v52.GetControl(v56);
-      v17 = v16->msg_param;
-      pInString = (char *)v16;
-      if ( (signed int)v17 > 24 )
-      {
-        v24 = v17 - 76;
-        if ( !v24 )
-        {
-          v15 = pGlobalTXT_LocalizationStrings[406];
-          goto LABEL_49;
-        }
-        v25 = v24 - 1;
-        if ( !v25 )
-        {
-          v15 = pGlobalTXT_LocalizationStrings[407];
-          goto LABEL_49;
-        }
-        v26 = v25 - 2;
-        if ( !v26 )
-        {
-          v33 = _4B254D_SkillMasteryTeacher((int)v52.ptr_1C);
-LABEL_44:
-          v15 = v33;
-LABEL_45:
-          v16 = (GUIButton *)pInString;
-          goto LABEL_49;
-        }
-        v27 = v26 - 3;
-        if ( !v27 )
-        {
-          v33 = (char *)ContractSelectText((int)v52.ptr_1C);
-          goto LABEL_44;
-        }
-        v28 = v27 - 1;
-        if ( !v28 )
-        {
-          v29 = (char *)&pMonsterStats + 88 * word_F8B1A0;
-          v30 = TargetColor(0xFFu, 0xFFu, 0xFFu);
-          v31 = *(int *)v29;
-          v32 = TargetColor(0xFFu, 0xFFu, 0x9Bu);
-          sprintfex(pTmpBuf.data(), "\f%05d%s\f%05d", v32, v31, v30);
-          sprintfex(pTmpBuf2.data(), dword_F8B1A4, pTmpBuf.data(), 100 * (unsigned __int8)v29[8]);
-          current_npc_text = pTmpBuf2.data();
-          v15 = "";
-          goto LABEL_45;
-        }
-        if ( v28 != 10 )
-          goto LABEL_41;
-      }
-      else
-      {
-        if ( v17 == 24 )
-        {
-          v23 = v58->evt_F;
-LABEL_33:
-          v15 = (char *)pNPCTopics[v23-1].pTopic;//(&dword_721660)[8 * v23];
-          if ( !v15 )
-          {
-            v16->msg_param = 0;
-            v15 = "";
-          }
-          goto LABEL_49;
-        }
-        v18 = v17 - 13;
-        if ( v18 )
-        {
-          v19 = v18 - 6;
-          if ( !v19 )
-          {
-            v23 = v58->evt_A;
-            goto LABEL_33;
-          }
-          v20 = v19 - 1;
-          if ( !v20 )
-          {
-            v15 = (char *)pNPCTopics[v58->evt_B-1].pTopic;//(&dword_721660)[8 * v58->evtb];
-            if ( !v15 )
-            {
-              v16->msg_param = 0;
-              v15 = "";
-            }
-            if ( uDialogueType != 84 )
-              goto LABEL_49;
-            sprintf(pTmpBuf.data(), format_4E2D80, v55, pItemsTable->pItems[contract_approved].pUnidentifiedName);
-            sprintf(pTmpBuf2.data(), current_npc_text, pTmpBuf.data());
-            current_npc_text = pTmpBuf2.data();
-            goto LABEL_45;
-          }
-          v21 = v20 - 1;
-          if ( !v21 )
-          {
-            v23 = v58->evt_C;
-            goto LABEL_33;
-          }
-          v22 = v21 - 1;
-          if ( !v22 )
-          {
-            v23 = v58->evt_D;
-            goto LABEL_33;
-          }
-          if ( v22 == 1 )
-          {
-            v23 = v58->evt_E;
-            goto LABEL_33;
-          }
-LABEL_41:
-          v15 = "";
-          goto LABEL_49;
-        }
-        v15 = pGlobalTXT_LocalizationStrings[122];
-      }
-LABEL_49:
-      strcpy(v16->pButtonName, v15);
-      ++v56;
-      if ( v56 >= v52.pStartingPosActiveItem + v52.pNumPresenceButton )
-      {
-        v14 = pDialogueWindow;
-        break;
-      }
-    }
-  }
-  v34 = 0;
-  v54 = TargetColor(0xFFu, 0xFFu, 0xFFu);
-  v35 = TargetColor(0xE1u, 0xCDu, 0x23u);
-  v36 = v14->pStartingPosActiveItem;
-  v55 = v35;
-  for ( i = v36 + v14->pNumPresenceButton; (signed int)v36 < (signed int)i; i = pDialogueWindow->pNumPresenceButton
-                                                                    + pDialogueWindow->pStartingPosActiveItem )
-  {
-    v37 = v14->GetControl(v36);
-    v38 = pFontArrus->CalcTextHeight(v37->pButtonName, &v52, 0, 0);
-    v14 = pDialogueWindow;
-    v34 += v38;
-    ++v36;
-  }
-  v39 = v14->pNumPresenceButton;
-  if ( v39 )
-  {
-    v58 = (NPCData *)((174 - v34) / v39);
-    if ( (signed int)v58 > 32 )
-      v58 = (NPCData *)32;
-    pInString = (char *)2;
-    v40 = (174 - (signed int)v58 * v39 - v34) / 2 - (signed int)v58 / 2 + 138;
-    v56 = v14->pStartingPosActiveItem;
-    i = v56;
-    if ( (signed int)i < (signed int)(i + v39) )
-    {
-      while ( 1 )
-      {
-        v41 = v14->GetControl(i);
-        v42 = v41;
-        v43 = v41->pButtonName;
-        v41->uY = (unsigned int)((char *)v58 + v40);
-        v44 = pFontArrus->CalcTextHeight(v41->pButtonName, &v52, 0, 0);
-        v45 = v42->uY;
-        v42->uHeight = v44;
-        v40 = v45 + v44 - 1;
-        v42->uW = v40;
-        v46 = v55;
-        if ( (char *)pDialogueWindow->pCurrentPosActiveItem != pInString )
-          v46 = v54;
-        v52.DrawTitleText(pFontArrus, 0, v45, v46, v43, 3u);
-        v14 = pDialogueWindow;
-        ++pInString;
-        ++v56;
-        i = pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem;
-        if ( v56 >= (signed int)i )
-          break;
-        i = v56;
-      }
-    }
-  }
-  if ( current_npc_text )
-  {
-    w.uFrameWidth = 458;
-    w.uFrameZ = 457;
-    v47 = pFontArrus;
-    v48 = pFontArrus->CalcTextHeight(current_npc_text, &w, 13, 0) + 7;
-    if ( 352 - v48 < 8 )
-    {
-      v47 = pFontCreate;
-      v48 = pFontCreate->CalcTextHeight(current_npc_text, &w, 13, 0) + 7;
-    }
-    pRenderer->_4A6A68(8, 352 - v48,
-      pIcons_LOD->GetTexture(uTextureID_Leather),
-      pIcons_LOD->GetTexture(uTextureID_Leather)->uTextureHeight - v48);
-    pRenderer->DrawTextureIndexed(8u, 347 - v48, pTexture_591428);
-    v49 = FitTextInAWindow(current_npc_text, v47, &w, 0xDu, 0);
-    a1.DrawText(v47, 13, 354 - v48, 0, v49, 0, 0, 0);
-  }
-}
-
-//----- (004B36CC) --------------------------------------------------------
-void CreateButtonInColumn( int column_pos, unsigned int control_id )
-{
-     pDialogueWindow->CreateButton( 480, 30 * column_pos + 146, 140, 30,  1,  0, UIMSG_SelectShopDialogueOption,  control_id,  0,   "",   0);
-}
-
 //----- (004B3A72) --------------------------------------------------------
 void sub_4B3A72( int a1 )
 	{
@@ -7711,20 +5907,6 @@
   pDialogueWindow->_41D08F_set_keyboard_control_group(v1 + 1, 1, 0, 1);
 }
 
-//----- (004B3EF0) --------------------------------------------------------
-void DrawJoinGuildWindow( int pEventCode )
-{
-  uDialogueType = 81;//enum JoinGuildDialog
-  current_npc_text = (char *)pNPCTopics[pEventCode + 99].pText;
-  ContractSelectText(pEventCode);
-  pDialogueWindow->Release();
-  pDialogueWindow = GUIWindow::Create(0, 0, 640, 0x15E, WINDOW_MainMenu, pEventCode, 0);
-  pBtn_ExitCancel = pDialogueWindow->CreateButton(471, 445, 169, 35, 1, 0, UIMSG_Escape,                    0, 0, pGlobalTXT_LocalizationStrings[34], pIcons_LOD->GetTexture(uExitCancelTextureId), 0); // Cancel
-                    pDialogueWindow->CreateButton(  0,   0,   0,  0, 1, 0, UIMSG_BuyInShop_Identify_Repair, 0, 0, "", 0);
-                    pDialogueWindow->CreateButton(480, 160, 140, 30, 1, 0, UIMSG_ClickNPCTopic,             0x52u, 0, pGlobalTXT_LocalizationStrings[122], 0);
-  pDialogueWindow->_41D08F_set_keyboard_control_group(1, 1, 0, 2);
-  dialog_menu_id = HOUSE_DIALOGUE_OTHER;
-}
 // F8B19C: using guessed type int dword_F8B19C;
 
 //----- (004B3FE5) --------------------------------------------------------
@@ -7752,150 +5934,6 @@
 // F8B19C: using guessed type int dword_F8B19C;
 // F8B1A8: using guessed type int dword_F8B1A8;
 
-//----- (004B40E6) --------------------------------------------------------
-void NPCHireableDialogPrepare()
-    {
-  signed int v0; // ebx@1
-  NPCData *v1; // edi@1
-
-  v0 = 0;
-  v1 = HouseNPCData[(unsigned int)((char *)pDialogueNPCCount + -(dword_591080 != 0) )];//- 1
-  pDialogueWindow->Release();
-  pDialogueWindow = GUIWindow::Create(0, 0, 640, 0x15Eu, WINDOW_MainMenu, 0, 0);
-  pBtn_ExitCancel = pDialogueWindow->CreateButton( 0x1D7u, 0x1BDu,  0xA9u,   0x23u,  1,  0,  UIMSG_Escape,  0,   0,
-                 pGlobalTXT_LocalizationStrings[34], //"Cancel"
-                 pIcons_LOD->GetTexture(uExitCancelTextureId),
-                 0);
-  pDialogueWindow->CreateButton(0, 0, 0, 0, 1, 0, UIMSG_BuyInShop_Identify_Repair, 0, 0, "", 0);
-  if ( pNPCStats->pProfessions[v1->uProfession].pBenefits)//*(&pNPCStats->field_13A5C + 5 * v1->uProfession) )
-  {
-    pDialogueWindow->CreateButton( 0x1E0u,  0xA0u,  0x8Cu,  0x1Eu,   1,  0,  UIMSG_ClickNPCTopic,  0x4Du,   0,
-      pGlobalTXT_LocalizationStrings[407], 0);//"More Information"   
-    v0 = 1;
-  }
-  pDialogueWindow->CreateButton(  0x1E0u,  30 * v0 + 160,  0x8Cu,  0x1Eu,  1,  0,  UIMSG_ClickNPCTopic,  0x4Cu,  0,
-    pGlobalTXT_LocalizationStrings[406],  0); //"Hire"
-  pDialogueWindow->_41D08F_set_keyboard_control_group(v0 + 1, 1, 0, 2);
-  dialog_menu_id = HOUSE_DIALOGUE_OTHER;
-}
-
-//----- (004B4224) --------------------------------------------------------
-void _4B4224_UpdateNPCTopics( int _this )
-	{
-  int num_menu_buttons; // ebx@1
-  int i; // ebp@5
- // signed int v4; // ebp@9
-  int v6; // eax@16
-  int v8; // eax@21
-  int v10; // eax@26
-  int v12; // eax@31
-  int v14; // eax@36
-  int v16; // eax@41
-  NPCData *v17; // [sp+10h] [bp-4h]@4
-
-  num_menu_buttons = 0;
-  pDialogueNPCCount = (_this + 1);
-  if ( _this + 1 == uNumDialogueNPCPortraits && uHouse_ExitPic )
-  {
-    pDialogueWindow->Release();
-    pDialogueWindow = GUIWindow::Create(0, 0, 640, 480, WINDOW_MainMenu, 0, 0);
-    sprintfex(sHouseName.data(), pGlobalTXT_LocalizationStrings[LOCSTR_ENTER_S], pMapStats->pInfos[uHouse_ExitPic].pName);
-    pBtn_ExitCancel = pDialogueWindow->CreateButton(566, 445, 75, 33, 1, 0, UIMSG_Escape, 0, 'N', pGlobalTXT_LocalizationStrings[34], pIcons_LOD->GetTexture(uTextureID_BUTTDESC2), 0);// "Cancel"
-    pBtn_YES        = pDialogueWindow->CreateButton(486, 445, 75, 33, 1, 0, UIMSG_BF,     1, 'Y', sHouseName.data(), pIcons_LOD->GetTexture(uTextureID_BUTTYES2), 0);
-    pDialogueWindow->CreateButton( pNPCPortraits_x[0][0], pNPCPortraits_y[0][0], 63u, 73u, 1, 0,  UIMSG_BF, 1u, 0x20u,  sHouseName.data(), 0);
-    pDialogueWindow->CreateButton(8, 8, 460, 344, 1, 0, UIMSG_BF, 1, 0x59u, sHouseName.data(), 0);
-  }
-  else
-  {
-    v17 = HouseNPCData[_this + 1 - ((dword_591080 != 0) )];//+ 1
-    if ( dialog_menu_id == HOUSE_DIALOGUE_OTHER )
-    {
-      pDialogueWindow->Release();
-    }
-    else
-    {
-      for ( i = 0; i < uNumDialogueNPCPortraits; ++i )
-        dword_5913F4[i]->Release();
-    }
-    pDialogueWindow = GUIWindow::Create(0, 0, 640, 0x159u, WINDOW_MainMenu, 0, 0);
-    pBtn_ExitCancel = pDialogueWindow->CreateButton(  471u,  445u,  169u, 35u,  1,   0, UIMSG_Escape,  0,  0,
-                   pGlobalTXT_LocalizationStrings[74],// "End Conversation"
-                   pIcons_LOD->GetTexture(uExitCancelTextureId),   0);
-    pDialogueWindow->CreateButton(8u, 8u, 0x1C2u, 0x140u, 1, 0, UIMSG_BuyInShop_Identify_Repair, 0, 0, "", 0);
-    if ( pDialogueNPCCount == 1 && dword_591080 )
-    {
-      sub_4B3B42(in_current_building_type);
-    }
-    else
-    {
-      if ( v17->joins )
-      {
-        num_menu_buttons = 1;
-        pDialogueWindow->CreateButton(480u, 160u, 140u, 30, 1, 0, UIMSG_ClickNPCTopic, 0xDu, 0, "", 0);
-      }
-      if ( v17->evt_A)
-      {
-        if ( num_menu_buttons < 4 )
-        {
-          v6 = NPC_EventProcessor(v17->evt_A);
-          if ( v6 == 1 || v6 == 2 )
-            pDialogueWindow->CreateButton(  480u, 30 * num_menu_buttons++ + 160,  140u, 30u, 1, 0, UIMSG_ClickNPCTopic, 0x13u,  0, "",  0);
-        }
-      }
-      if ( v17->evt_B )
-      {
-        if ( num_menu_buttons < 4 )
-        {
-          v8 = NPC_EventProcessor(v17->evt_B);
-          if ( v8 == 1 || v8 == 2 )
-            pDialogueWindow->CreateButton( 480u,  30 * num_menu_buttons++ + 160,  140u, 30u,  1, 0,  UIMSG_ClickNPCTopic,  0x14u,  0, "",  0);
-        }
-      }
-      if ( v17->evt_C )
-      {
-        if ( num_menu_buttons < 4 )
-        {
-          v10 = NPC_EventProcessor(v17->evt_C);
-          if ( v10 == 1 || v10 == 2 )
-            pDialogueWindow->CreateButton(  480u,  30 * num_menu_buttons++ + 160,  140u, 30u,  1,  0, UIMSG_ClickNPCTopic, 0x15u, 0, "",  0);
-        }
-      }
- 
-      if ( v17->evt_D )
-      {
-        if ( num_menu_buttons < 4 )
-        {
-          v12 = NPC_EventProcessor(v17->evt_D);
-          if ( v12 == 1 || v12 == 2 )
-            pDialogueWindow->CreateButton( 0x1E0u, 30 * num_menu_buttons++ + 160,  0x8Cu, 0x1Eu, 1, 0, UIMSG_ClickNPCTopic, 0x16u,  0, "",  0);
-        }
-      }
-      if ( v17->evt_E )
-      {
-        if ( num_menu_buttons < 4 )
-        {
-          v14 = NPC_EventProcessor(v17->evt_E);
-          if ( v14 == 1 || v14 == 2 )
-            pDialogueWindow->CreateButton( 0x1E0u, 30 * num_menu_buttons++ + 160,  0x8Cu,  0x1Eu,  1,  0,  UIMSG_ClickNPCTopic, 0x17u,  0, "",  0);
-        }
-      }
-      if ( v17->evt_F )
-      {
-        if ( num_menu_buttons < 4 )
-        {
-          v16 = NPC_EventProcessor(v17->evt_F);
-          if ( v16 == 1 || v16 == 2 )
-            pDialogueWindow->CreateButton( 0x1E0u, 30 * num_menu_buttons++ + 160,  0x8Cu,  0x1Eu, 1, 0, UIMSG_ClickNPCTopic, 0x18u, 0, "",  0);
-        }
-      }
-      pDialogueWindow->_41D08F_set_keyboard_control_group(num_menu_buttons, 1, 0, 2);
-      dword_F8B1E0 = pDialogueWindow->pNumPresenceButton;
-    }
-    dialog_menu_id = HOUSE_DIALOGUE_MAIN;
-  }
- 
-}
-
 //----- (004B46A5) --------------------------------------------------------
 void __fastcall DrawTextAtStatusBar( const char *Str, int a5 )
     {
@@ -8484,273 +6522,4 @@
       v1->_406FA8();
     }
   }
-}
-
-//----- (0043FDED) --------------------------------------------------------
-void PrepareActorRenderList_BLV()
-{
-  RenderBillboard *v0; // esi@0
-  unsigned __int16 v3; // ax@3
-  unsigned int v4; // eax@5
-  unsigned __int16 v5; // cx@5
-  int v6; // esi@5
-  unsigned int v7; // eax@7
-  int v8; // eax@10
-  SpriteFrame *v9; // eax@16
-  SpriteFrame *v10; // ebx@18
-  //int *v11; // eax@18
-  int v12; // ecx@28
-  //IndoorCameraD3D **v14; // eax@36
-  double v15; // st7@36
-  float v16; // eax@36
-  //double v17; // ST30_8@36
-  signed __int64 v18; // qtt@36
-  int v19; // ST5C_4@36
-  signed __int64 v20; // qtt@37
-  int v21; // ST5C_4@37
-  signed __int16 v22; // cx@39
-  int v23; // ST50_4@40
-  signed int v24; // ecx@40
-  int v25; // edx@44
-  __int16 v26; // ax@44
-  //MonsterDesc *v27; // edx@44
-  //int v28; // ecx@44
-  unsigned __int8 v29; // zf@44
-  unsigned __int8 v30; // sf@44
-  unsigned int v31; // [sp-8h] [bp-5Ch]@15
-  int v32; // [sp+1Ch] [bp-38h]@5
-  int a3; // [sp+20h] [bp-34h]@5
-  int a2; // [sp+24h] [bp-30h]@5
-  int a1a; // [sp+28h] [bp-2Ch]@5
-  __int16 a5; // [sp+2Ch] [bp-28h]@5
-  int a5a; // [sp+2Ch] [bp-28h]@36
-  int a5b; // [sp+2Ch] [bp-28h]@40
-  __int16 v41; // [sp+3Ch] [bp-18h]@18
-  int a6; // [sp+40h] [bp-14h]@34
-  int v43; // [sp+44h] [bp-10h]@34
-  int z; // [sp+48h] [bp-Ch]@32
-  signed int y; // [sp+4Ch] [bp-8h]@32
-  int x; // [sp+50h] [bp-4h]@32
-
-  for (uint i = 0; i < uNumActors; ++i)
-  {
-    auto p = &pActors[i];
-
-    if (p->uAIState == Removed ||
-        p->uAIState == Disabled)
-      continue;
-
-    a5 = p->uSectorID;
-    a2 = p->vPosition.y;
-    a1a = p->vPosition.x;
-    a3 = p->vPosition.z;
-    v4 = stru_5C6E00->Atan2(a1a - pBLVRenderParams->vPartyPos.x, a2 - pBLVRenderParams->vPartyPos.y);
-    LOWORD(v0) = p->uYawAngle;
-    v5 = p->uCurrentActionAnimation;
-    v6 = ((signed int)((char *)v0 + ((signed int)stru_5C6E00->uIntegerPi >> 3) - v4 + stru_5C6E00->uIntegerPi) >> 8) & 7;
-    v32 = v6;
-    if ( pParty->bTurnBasedModeOn )
-    {
-      if ( v5 == 1 )
-      {
-        v7 = pMiscTimer->uTotalGameTimeElapsed;
-        goto LABEL_10;
-      }
-    }
-    else
-    {
-      if ( v5 == 1 )
-      {
-        v7 = pBLVRenderParams->field_0_timer_;
-LABEL_10:
-        v8 = i * 32 + v7;
-        goto LABEL_12;
-      }
-    }
-    v8 = p->uCurrentActionTime;
-LABEL_12:
-    if (p->pActorBuffs[5].uExpireTime > 0i64 || p->pActorBuffs[6].uExpireTime > 0i64 )
-      v8 = 0;
-    v31 = p->pSpriteIDs[v5];
-    if (p->uAIState == Resurrected)
-      v9 = pSpriteFrameTable->GetFrameBy_x(v31, v8);
-    else
-      v9 = pSpriteFrameTable->GetFrame(v31, v8);
-    v41 = 0;
-    v10 = v9;
-    //v11 = (int *)v9->uFlags;
-    if (v9->uFlags & 2)
-      v41 = 2;
-    if (v9->uFlags & 0x40000)
-      v41 |= 0x40u;
-    if (v9->uFlags & 0x20000)
-      LOBYTE(v41) = v41 | 0x80;
-    v0 = (RenderBillboard *)(256 << v6);
-    if ( (unsigned int)v0 & v9->uFlags)
-      v41 |= 4u;
-    if ( v10->uGlowRadius )
-    {
-      //LOBYTE(v11) = byte_4E94D3;
-      pMobileLightsStack->AddLight(
-        a1a,
-        a2,
-        a3,
-        a5,
-        v10->uGlowRadius,
-        0xFFu,
-        0xFFu,
-        0xFFu,
-        byte_4E94D3);
-    }
-    v12 = 0;
-    if ( pBspRenderer->uNumVisibleNotEmptySectors <= 0 )
-      continue;
-    while (pBspRenderer->pVisibleSectorIDs_toDrawDecorsActorsEtcFrom[v12] != p->uSectorID)
-    {
-      ++v12;
-      if ( v12 >= pBspRenderer->uNumVisibleNotEmptySectors )
-        goto _continue;
-    }
-    if ( !pGame->pIndoorCameraD3D->ApplyViewTransform_TrueIfStillVisible(a1a, a2, a3, &x, &y, &z, 1)
-      || (v0 = (RenderBillboard *)abs(x), (signed int)v0 < abs(y)) )
-      continue;
-    pGame->pIndoorCameraD3D->Project(x, y, z, &v43, &a6);
-    v0 = &pBillboardRenderList[uNumBillboardsToDraw];
-    if (uNumBillboardsToDraw >= 500)
-      break;
-    ++uNumBillboardsToDraw;
-    ++uNumSpritesDrawnThisFrame;
-    p->uAttributes |= 8u;
-    v29 = pRenderer->pRenderD3D == 0;
-    v0->uHwSpriteID = v10->pHwSpriteIDs[v32];
-    v0->uPalette = v10->uPaletteIndex;
-    v0->uIndoorSectorID = a5;
-    if ( v29 )
-    {
-      LODWORD(v20) = pBLVRenderParams->field_40 << 16;
-      HIDWORD(v20) = pBLVRenderParams->field_40 >> 16;
-      v21 = v20 / x;
-      v0->_screenspace_x_scaler_packedfloat = (unsigned __int64)(v10->scale * v20 / x) >> 16;
-      a5a = (unsigned __int64)(v10->scale * (signed __int64)v21) >> 16;
-    }
-    else
-    {
-      //v14 = &pGame->pIndoorCameraD3D;
-      v0->fov_x = pGame->pIndoorCameraD3D->fov_x;
-      v15 = pGame->pIndoorCameraD3D->fov_y;
-      v16 = v0->fov_x;
-      v0->fov_y = v15;
-      //v17 = v16 + 6.7553994e15;
-      LODWORD(v18) = 0;
-      HIDWORD(v18) = floorf(v16 + 0.5f);
-      v19 = v18 / x;
-      v0->_screenspace_x_scaler_packedfloat = (unsigned __int64)(v10->scale * v18 / x) >> 16;
-      a5a = (unsigned __int64)(v10->scale * (signed __int64)v19) >> 16;
-    }
-    v0->_screenspace_y_scaler_packedfloat = a5a;
-    if ( (signed __int64)p->pActorBuffs[3].uExpireTime <= 0 )
-    {
-      if ( (signed __int64)p->pActorBuffs[10].uExpireTime > 0 )
-      {
-        a5b = (unsigned __int64)(pGame->pStru6Instance->_4A806F(p) * (signed __int64)v0->_screenspace_y_scaler_packedfloat) >> 16;
-        goto LABEL_43;
-      }
-    }
-    else
-    {
-      v22 = p->pActorBuffs[3].uPower;
-      if ( v22 )
-      {
-        v23 = (unsigned __int64)(65536 / (unsigned __int16)v22 * (signed __int64)v0->_screenspace_x_scaler_packedfloat) >> 16;
-        v24 = p->pActorBuffs[3].uPower;
-        v0->_screenspace_x_scaler_packedfloat = v23;
-        a5b = (unsigned __int64)(65536 / v24 * (signed __int64)v0->_screenspace_y_scaler_packedfloat) >> 16;
-LABEL_43:
-        v0->_screenspace_y_scaler_packedfloat = a5b;
-        goto LABEL_44;
-      }
-    }
-LABEL_44:
-    HIWORD(v25) = HIWORD(x);
-    v0->world_x = a1a;
-    v0->world_y = a2;
-    v0->world_z = a3;
-    v0->uScreenSpaceX = v43;
-    v0->uScreenSpaceY = a6;
-    LOWORD(v25) = 0;
-    LOBYTE(v26) = v41;
-
-    //v0->sZValue = v25 + (PID(OBJECT_Actor,i));
-    v0->actual_z = HIWORD(x);
-    v0->object_pid = PID(OBJECT_Actor,i);
-
-    v29 = HIDWORD(p->pActorBuffs[5].uExpireTime) == 0;
-    v30 = HIDWORD(p->pActorBuffs[5].uExpireTime) < 0;
-    v0->field_1E = v41;
-    v0->pSpriteFrame = v10;
-    v0->uTintColor = pMonsterList->pMonsters[p->pMonsterInfo.uID - 1].uTintColor;
-    if ( !v30 && (!(v30 | v29) || LODWORD(p->pActorBuffs[5].uExpireTime)) )
-    {
-      HIBYTE(v26) = HIBYTE(v41) | 1;
-      v0->field_1E = v26;
-    }
-    
-_continue:
-    ;
-  }
-}
-
-//----- (00444732) --------------------------------------------------------
-char *GetEventHintString(unsigned int uEventID)
-{
-  signed int event_index; // edx@1
-  int event_pos; // esi@4
-  char *result; // eax@6
-  unsigned int str_index; // eax@9
-  int i; // esi@11
- _evt_raw*  test_evt;
- _evt_raw*  last_evt;
-
-  event_index = 0;
-  if ( uLevelEVT_NumEvents <= 0 )
-    return NULL;
- 
-    //v2 = (char *)&pLevelEVT_Index[0].uEventOffsetInEVT;
-    while ( 1 )
-    {
-      if ( pLevelEVT_Index[event_index].uEventID == uEventID )
-      {
-		test_evt=(_evt_raw*)&pLevelEVT[pLevelEVT_Index[event_index].uEventOffsetInEVT];
-		last_evt=test_evt;
-        event_pos = pLevelEVT_Index[event_index+1].uEventOffsetInEVT;
-        if ( test_evt->_e_type == EVENT_MouseOver )
-          break;
-      }
-      ++event_index;
-      if ( event_index >= uLevelEVT_NumEvents )
-       return NULL;
-    }
-	test_evt=(_evt_raw*)&pLevelEVT[event_pos];
-    if ( test_evt->_e_type== EVENT_SpeakInHouse )
-    {
-      str_index = EVT_DWORD(test_evt->v5);
-      result = (char *)p2DEvents[str_index - 1].pName;
-    }
-    else
-    {
-      for ( i = event_index+1; pLevelEVT_Index[i].uEventID  == uEventID; ++i )
-      {
-        event_pos = pLevelEVT_Index[i].uEventOffsetInEVT;
-		test_evt=(_evt_raw*)&pLevelEVT[event_pos];
-        if ( test_evt->_e_type == EVENT_SpeakInHouse )
-        {
-          str_index = EVT_DWORD(test_evt->v5);
-          if ( str_index < 600 )
-            return (char *)p2DEvents[str_index - 1].pName;
-        }
-      }
-      result = &pLevelStr[pLevelStrOffsets[EVT_BYTE(last_evt->v5)]];
-    }
- 
-  return result;
-}
+}
\ No newline at end of file
--- a/mm7_5.cpp	Sun Jun 23 14:27:32 2013 +0600
+++ b/mm7_5.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -47,7 +47,7 @@
 #include "Events2D.h"
 #include "texts.h"
 #include "Log.h"
-#include "UIHouses.h"
+#include "UI\UIHouses.h"
 #include "Lights.h"
 #include "Lights.h"
 
@@ -4065,89 +4065,6 @@
   memcpy((char *)&v17->cpuid_80000002_registers2[0] + 1, v18, 0x30u);*/
 }
 
-//----- (00438BDF) --------------------------------------------------------
-bool MonsterStats::BelongsToSupertype(unsigned int uMonsterInfoID, enum MONSTER_SUPERTYPE eSupertype)
-{
-  unsigned __int8 v2; // zf@15
-  char v3; // sf@15
-  unsigned __int8 v4; // of@15
-  bool result; // eax@33
-
-  switch ( eSupertype )
-  {
-    case MONSTER_SUPERTYPE_UNDEAD:
-      if ( (signed int)uMonsterInfoID >= MONSTER_GHOST_1 && (signed int)uMonsterInfoID <= MONSTER_GHOST_3
-        || (signed int)uMonsterInfoID >= MONSTER_LICH_1 && (signed int)uMonsterInfoID <= MONSTER_LICH_3
-        || (signed int)uMonsterInfoID >= MONSTER_SKELETON_1 && (signed int)uMonsterInfoID <= MONSTER_SKELETON_3
-        || (signed int)uMonsterInfoID >= MONSTER_VAMPIRE_1 && (signed int)uMonsterInfoID <= MONSTER_VAMPIRE_3
-        || (signed int)uMonsterInfoID >= MONSTER_WIGHT_1 && (signed int)uMonsterInfoID <= MONSTER_WIGHT_3
-        || (signed int)uMonsterInfoID >= MONSTER_ZOMBIE_1 && (signed int)uMonsterInfoID <= MONSTER_ZOMBIE_3 )
-        goto ret_true;
-      if ( (signed int)uMonsterInfoID < MONSTER_GHOUL_1 )
-        goto ret_false;
-      v4 = __OFSUB__(uMonsterInfoID, (int)MONSTER_GHOUL_3);
-      v2 = uMonsterInfoID == MONSTER_GHOUL_3;
-      v3 = ((uMonsterInfoID - MONSTER_GHOUL_3) & 0x80000000u) != 0;
-      goto false_if_outside;
-    case MONSTER_SUPERTYPE_KREEGAN:
-      if ( (signed int)uMonsterInfoID < MONSTER_DEVIL_1 )
-        goto ret_false;
-      v4 = __OFSUB__(uMonsterInfoID, (int)MONSTER_DEVIL_3);
-      v2 = uMonsterInfoID == MONSTER_DEVIL_3;
-      v3 = ((uMonsterInfoID - MONSTER_DEVIL_3) & 0x80000000u) != 0;
-      goto false_if_outside;
-    case MONSTER_SUPERTYPE_ELF:
-      if ( (signed int)uMonsterInfoID >= MONSTER_PEASANT_ELF_FEMALE_1_1
-        && (signed int)uMonsterInfoID <= MONSTER_PEASANT_ELF_MALE_3_3
-        || (signed int)uMonsterInfoID >= MONSTER_ELF_ARCHER_1 && (signed int)uMonsterInfoID <= MONSTER_ELF_ARCHER_3 )
-        goto ret_true;
-      if ( (signed int)uMonsterInfoID < MONSTER_ELF_SPEARMAN_1 )
-        goto ret_false;
-      v4 = __OFSUB__(uMonsterInfoID, (int)MONSTER_ELF_SPEARMAN_3);
-      v2 = uMonsterInfoID == MONSTER_ELF_SPEARMAN_3;
-      v3 = ((uMonsterInfoID - MONSTER_ELF_SPEARMAN_3) & 0x80000000u) != 0;
-      goto false_if_outside;
-    case MONSTER_SUPERTYPE_DRAGON:
-      if ( (signed int)uMonsterInfoID < MONSTER_DRAGON_1 )
-        goto ret_false;
-      v4 = __OFSUB__(uMonsterInfoID, (int)MONSTER_DRAGON_3);
-      v2 = uMonsterInfoID == MONSTER_DRAGON_3;
-      v3 = ((uMonsterInfoID - MONSTER_DRAGON_3) & 0x80000000u) != 0;
-      goto false_if_outside;
-    case MONSTER_SUPERTYPE_WATER_ELEMENTAL:
-      if ( (signed int)uMonsterInfoID < MONSTER_ELEMENTAL_WATER_1 )
-        goto ret_false;
-      v4 = __OFSUB__(uMonsterInfoID, (int)MONSTER_ELEMENTAL_WATER_3);
-      v2 = uMonsterInfoID == MONSTER_ELEMENTAL_WATER_3;
-      v3 = ((uMonsterInfoID - MONSTER_ELEMENTAL_WATER_3) & 0x80000000u) != 0;
-      goto false_if_outside;
-    case MONSTER_SUPERTYPE_TREANT:
-      if ( (signed int)uMonsterInfoID < MONSTER_TREANT_1 )
-        goto ret_false;
-      v4 = __OFSUB__(uMonsterInfoID, (int)MONSTER_TREANT_3);
-      v2 = uMonsterInfoID == MONSTER_TREANT_3;
-      v3 = ((uMonsterInfoID - MONSTER_TREANT_3) & 0x80000000u) != 0;
-      goto false_if_outside;
-    case MONSTER_SUPERTYPE_TITAN:
-      if ( (signed int)uMonsterInfoID < MONSTER_TITAN_1 )
-        goto ret_false;
-      v4 = __OFSUB__(uMonsterInfoID, (int)MONSTER_TITAN_3);
-      v2 = uMonsterInfoID == MONSTER_TITAN_3;
-      v3 = ((uMonsterInfoID - MONSTER_TITAN_3) & 0x80000000u) != 0;
-false_if_outside:
-      if ( !((unsigned __int8)(v3 ^ v4) | v2) )
-        goto ret_false;
-ret_true:
-      result = 1;
-      break;
-    default:
-ret_false:
-      result = 0;
-      break;
-  }
-  return result;
-}
-
 //----- (00438F8F) --------------------------------------------------------
 void __cdecl area_of_effect__damage_evaluate()
 {
@@ -4376,983 +4293,8 @@
 }
 // 50FE08: using guessed type stru298 stru_50FE08;
 
-//----- (00439474) --------------------------------------------------------
-void DamageMonsterFromParty(signed int a1, unsigned int uActorID_Monster, Vec3_int_ *pVelocity)
-{
-  //signed int v3; // eax@1
-  SpriteObject *v4; // ebx@1
-  //int v5; // edx@3
-  //bool uPlayerID; // eax@3
-  //Player *pPlayer; // edi@4
-  Actor *pMonster; // esi@7
-  //SpriteObject *v9; // ebx@12
-  int v10; // eax@12
-  int v11; // ebx@12
-  unsigned int v12; // ecx@12
-  int v13; // edx@15
-  int v14; // edx@17
-  int v15; // eax@24
-  unsigned __int16 v16; // cx@25
-  int v17; // eax@29
-  int v18; // eax@38
-  unsigned __int8 v19; // zf@38
-  unsigned __int8 v20; // sf@38
-  int v21; // edx@44
-  int v22; // eax@44
-  unsigned __int8 v23; // zf@44
-  unsigned __int8 v24; // sf@44
-  int v25; // edx@51
-  int v26; // ecx@51
-  //signed int v27; // eax@51
-  //int v28; // eax@53
-  signed int v29; // eax@76
-  signed int v30; // eax@84
-  signed int v31; // eax@92
-  int v32; // eax@94
-  int v33; // eax@100
-  int v34; // eax@104
-  signed int v35; // eax@104
-  double v36; // st7@104
-  float v37; // ST08_4@104
-  float v38; // ST04_4@104
-  float v39; // ST00_4@104
-  int v40; // ebx@107
-  unsigned int v41; // ebx@109
-  signed __int64 v42; // qax@125
-  unsigned __int16 v43; // ax@132
-  char v44; // bl@132
-  unsigned __int16 v45; // ax@132
-  unsigned __int64 v46; // [sp+Ch] [bp-60h]@6
-  const char *v47; // [sp+14h] [bp-58h]@104
-  char *pPlayerName; // [sp+18h] [bp-54h]@12
-  char *pMonsterName; // [sp+1Ch] [bp-50h]@6
-  int v50; // [sp+20h] [bp-4Ch]@6
-  //unsigned __int64 *v51; // [sp+30h] [bp-3Ch]@6
-  int v52; // [sp+34h] [bp-38h]@12
-  //int v53; // [sp+38h] [bp-34h]@10
-  //int v54; // [sp+3Ch] [bp-30h]@1
-  //int v55; // [sp+40h] [bp-2Ch]@12
-  signed int a4; // [sp+44h] [bp-28h]@1
-  PlayerEquipment *v57; // [sp+48h] [bp-24h]@10
-  //int v58; // [sp+4Ch] [bp-20h]@10
-  int v59; // [sp+50h] [bp-1Ch]@1
-  unsigned int uActorID_Monster_; // [sp+54h] [bp-18h]@1
-  int v61; // [sp+58h] [bp-14h]@1
-  bool v62; // [sp+5Ch] [bp-10h]@1
-  int uDamageAmount; // [sp+60h] [bp-Ch]@1
-  int a2; // [sp+64h] [bp-8h]@27
-  int a3; // [sp+6Bh] [bp-1h]@6
-
-  //v3 = a1;
-  v4 = 0;
-  uActorID_Monster_ = uActorID_Monster;
-  //v54 = a1;
-  uDamageAmount = 0;
-  a4 = 0;
-  v61 = 0;
-  v59 = 0;
-  v62 = 0;
-  if ( PID_TYPE(a1) == OBJECT_Item)
-  {
-    v4 = &pSpriteObjects[PID_ID(a1)];
-    //uDamageAmount = (int)v4;
-    v61 = v4->field_60_distance_related_prolly_lod;
-    a1 = v4->spell_caster_pid;
-    //v54 = v4->field_58_pid;
-  }
-  //v5 = a1 & 7;
-  //uPlayerID = a1 >> 3;
-  if (PID_TYPE(a1) != OBJECT_Player)
-    return;
-
-  assert(PID_ID(abs(a1)) < 4);
-  auto player = &pParty->pPlayers[PID_ID(a1)];
-  pMonster = &pActors[uActorID_Monster_];
-  //uPlayerID = pMonster->IsAlive();
-  if (pMonster->IsNotAlive())
-    return;
-
-  BYTE1(pMonster->uAttributes) |= 0xC0u;
-  if ( pMonster->uAIState == Fleeing )
-    pMonster->uAttributes |= 0x20000u;
-  //v57 = 0;
-  //v53 = 0;
-  //v58 = 0;
-  bool hit_will_stun = false,
-       hit_will_paralyze = false;
-  if ( !v4 )
-  {
-    //v51 = (unsigned __int64 *)player->pEquipment.uMainHand;
-    int main_hand_idx = player->pEquipment.uMainHand;
-    v59 = 1;
-    if ( player->HasItemEquipped(EQUIP_MAIN_HAND) )
-    {
-      auto main_hand_skill = pItemsTable->pItems[player->pInventoryItems[main_hand_idx - 1].uItemID].uSkillType;
-      //v55 = pItemsTable->pItems[player->pInventoryItems[main_hand_idx - 1].uItemID].uSkillType;
-      //v28 = SkillToMastery(player->pActiveSkills[v55]);
-      auto main_hand_mastery = SkillToMastery(player->pActiveSkills[main_hand_skill]);
-      //uDamageAmount = v28;
-      switch (main_hand_skill)
-      {
-        case PLAYER_SKILL_STAFF:
-          if (main_hand_mastery >= 3)
-          {
-            if (rand() % 100 < (player->GetActualSkillLevel(PLAYER_SKILL_STAFF) & 0x3F))  // stun chance when mastery >= 3
-              hit_will_stun = true;
-          }
-        break;
-
-        case PLAYER_SKILL_MACE:
-          if (main_hand_mastery >= 3)
-          {
-            if (rand() % 100 < (player->GetActualSkillLevel(PLAYER_SKILL_MACE) & 0x3F))
-              hit_will_stun = true;
-          }
-          if (main_hand_mastery >= 4)
-          {
-            if (rand() % 100 < (player->GetActualSkillLevel(PLAYER_SKILL_MACE) & 0x3F))
-              hit_will_paralyze = true;
-          }
-        break;
-      }
-    }
-    v50 = pMonster->pMonsterInfo.uID;
-    a2 = 4;
-    //v27 = player->CalculateMeleeDamageTo(0, 0, v50);
-    uDamageAmount = player->CalculateMeleeDamageTo(0, 0, v50);
-    //if ( !v57 )
-      goto LABEL_67;
-    //goto LABEL_69;
-  }
-
-
-  v19 = v4->spell_id == SPELL_DARK_SOULDRINKER;
-  v61 = v4->field_60_distance_related_prolly_lod;
-  if ( !v19 )
-  {
-    //v9 = (SpriteObject *)uDamageAmount;
-	v50 = pParty->vPosition.x - v4->vPosition.x;
-    //v55 = abs(v50);
-    pMonsterName = (char *)(pParty->vPosition.y - v4->vPosition.y);
-    //v51 = (unsigned __int64 *)abs((int)pMonsterName);
-    pPlayerName = (char *)(pParty->vPosition.z - v4->vPosition.z);
-    v52 = abs((int)pPlayerName);
-    v61 = abs(v50);
-    v10 = abs(v50);
-    v11 = (int)abs((int)pMonsterName);
-    v12 = v52;
-    if ( v10 < v11)
-    {
-      v10 = (int)v11;
-      v11 = v10;
-    }
-    if ( v10 < v52 )
-    {
-      v13 = v10;
-      v10 = v52;
-      v12 = v13;
-    }
-    if ( v11 < (signed int)v12 )
-    {
-      v14 = v12;
-      v12 = v11;
-      v11 = v14;
-    }
-    //uPlayerID = ((unsigned int)(11 * v11) >> 5) + (v12 >> 2) + v10;
-    v61 = ((unsigned int)(11 * v11) >> 5) + (v12 >> 2) + v10;
-    if ( v61 >= 2560 )
-    {
-      if ( v61 >= 5120 && !(BYTE1(pMonster->uAttributes) & 4) )
-        return;
-      v61 = 2;
-    }
-    else
-    {
-      v61 = 1;
-    }
-    //v4 = (SpriteObject *)uDamageAmount;
-  }
-
-  v15 = v4->spell_id;
-  if ( v15 == SPELL_LASER_PROJECTILE )
-  {
-    v16 = player->pActiveSkills[7];
-    v61 = 1;
-    if ( (signed int)SkillToMastery(v16) >= 3 )
-      a4 = player->pActiveSkills[7] & 0x3F;
-    a2 = 4;
-    uDamageAmount = player->CalculateMeleeDamageTo(1, 1, 0);
-    goto LABEL_67;
-  }
-  if ( v15 != SPELL_BOW_ARROW )
-  {
-    if ( v15 == SPELL_101 )
-    {
-      a2 = 0;
-      v18 = player->CalculateRangedDamageTo(0);
-      v19 = HIDWORD(pMonster->pActorBuffs[15].uExpireTime) == 0;
-      v20 = SHIDWORD(pMonster->pActorBuffs[15].uExpireTime) < 0;
-      uDamageAmount = v18;
-      if ( !v20 && (!(v20 | v19) || LODWORD(pMonster->pActorBuffs[15].uExpireTime)) )
-        uDamageAmount >>= 1;
-      v59 = 1;
-      goto LABEL_67;
-    }
-    if ( v15 == SPELL_EARTH_BLADES )
-    {
-      a4 = 5 * v4->spell_level;
-      a2 = player->GetSpellSchool(0x27u);
-      v21 = v4->spell_level;
-      v50 = pMonster->sCurrentHP;
-      pMonsterName = (char *)v4->spell_skill;
-      v22 = _43AFE3_calc_spell_damage(39, v21, v4->spell_skill, v50);
-      v23 = HIDWORD(pMonster->pActorBuffs[15].uExpireTime) == 0;
-      v24 = SHIDWORD(pMonster->pActorBuffs[15].uExpireTime) < 0;
-      uDamageAmount = v22;
-      if ( !v24 && (!(v24 | v23) || LODWORD(pMonster->pActorBuffs[15].uExpireTime)) )
-        uDamageAmount >>= 1;
-      v59 = 0;
-LABEL_67:
-      if ( !stru_50C198.PlayerHitOrMiss(player, pMonster, v61, a4) )
-      {
-//LABEL_68:
-        player->PlaySound(SPEECH_52, 0);
-        return;
-      }
-      goto LABEL_69;
-    }
-    if ( v15 == SPELL_EARTH_STUN )
-    {
-      uDamageAmount = 0;
-      a2 = 4;
-      hit_will_stun = 1;
-      goto LABEL_67;
-    }
-    a2 = player->GetSpellSchool(v4->spell_id);
-    v25 = v4->spell_level;
-    v26 = v4->spell_id;
-    v50 = pMonster->sCurrentHP;
-    pMonsterName = (char *)v4->spell_skill;
-    //v27 = _43AFE3_calc_spell_damage(v26, v25, (signed int)pMonsterName, v50);
-    v59 = 0;
-    //v57 = (PlayerEquipment *)1;
-//LABEL_65:
-    uDamageAmount = _43AFE3_calc_spell_damage(v26, v25, v4->spell_skill, v50);
-    //if ( !v57 )
-    //  goto LABEL_67;
-    goto LABEL_69;
-  }
-  v50 = pMonster->word_000086_some_monster_id;
-  a2 = 4;
-  v17 = player->CalculateRangedDamageTo(v50);
-  v19 = v4->stru_24.uItemID == 0;
-  uDamageAmount = v17;
-  v57 = 0;
-  if ( !v19 && v4->stru_24.uSpecEnchantmentType == 3 )
-  {
-    a2 = 0;
-    v57 = (PlayerEquipment *)1;
-  }
-  if ( SHIDWORD(pMonster->pActorBuffs[15].uExpireTime) >= 0
-    && (SHIDWORD(pMonster->pActorBuffs[15].uExpireTime) > 0 || LODWORD(pMonster->pActorBuffs[15].uExpireTime)) )
-    uDamageAmount >>= 1;
-  v59 = 1;
-//LABEL_66:
-  if ( !v57 )
-    goto LABEL_67;
-LABEL_69:
-  if (player->Weak())
-    uDamageAmount /= 1;
-  if ( (signed __int64)pMonster->pActorBuffs[5].uExpireTime > 0 )
-    uDamageAmount = 0;
-  v61 = stru_50C198.CalcMagicalDamageToActor(pMonster, a2, uDamageAmount);
-  if ( !v4 && player->IsUnarmed() && (signed __int64)player->pPlayerBuffs[6].uExpireTime > 0 )
-  {
-    v50 = player->pPlayerBuffs[6].uPower;
-    v29 = stru_50C198.CalcMagicalDamageToActor(pMonster, 8, v50);
-    v61 += v29;
-  }
-  uDamageAmount = v61;
-  if ( v59 )
-  {
-    if ( v4 )
-    {
-      a4 = v4->stru_24._439DF3_get_additional_damage(&a2, &v62);
-      if ( v62 && pMonster->sCurrentHP > 0 )
-      {
-        player->sHealth += v61 / 5;
-        if ( player->sHealth > player->GetMaxHealth() )
-          player->sHealth = player->GetMaxHealth();
-        v62 = 0;
-      }
-      v30 = stru_50C198.CalcMagicalDamageToActor(pMonster, a2, a4);
-      uDamageAmount = v61 + v30;
-    }
-    else
-    {
-      v59 = 0;
-      v57 = &player->pEquipment;
-      do
-      {
-        if ( player->HasItemEquipped((ITEM_EQUIP_TYPE)v59) )
-        {
-          auto _s = (ItemGen *)&player->pInventoryItems[v57->uShield - 1];
-          a4 = _s->_439DF3_get_additional_damage(&a2, &v62);
-          if ( v62 && pMonster->sCurrentHP > 0 )
-          {
-            player->sHealth += v61 / 5;
-            if ( player->sHealth > player->GetMaxHealth() )
-              player->sHealth = player->GetMaxHealth();
-            v62 = 0;
-          }
-          v31 = stru_50C198.CalcMagicalDamageToActor(pMonster, a2, a4);
-          uDamageAmount += v31;
-        }
-        ++v59;
-        v57 = (PlayerEquipment *)((char *)v57 + 4);
-      }
-      while ( v59 <= 1 );
-    }
-  }
-  v32 = uDamageAmount;
-  pMonster->sCurrentHP -= uDamageAmount;
-  if ( !v32 && !hit_will_stun )
-  {
-    player->PlaySound(SPEECH_52, 0);
-    return;
-  }
-  if ( pMonster->sCurrentHP > 0 )
-  {
-    Actor::AI_Stun(uActorID_Monster_, a1, 0);
-    Actor::AggroSurroundingPeasants(uActorID_Monster_, 1);
-    if ( bShowDamage )
-    {
-      v50 = uDamageAmount;
-      pMonsterName = (char *)pMonster;
-      pPlayerName = player->pName;
-      if ( v4 )
-        v47 = pGlobalTXT_LocalizationStrings[189];// "%s shoots %s for %lu points"
-      else
-        v47 = pGlobalTXT_LocalizationStrings[164];// "%s hits %s for %lu damage"
-      sprintfex(pTmpBuf.data(), v47, pPlayerName, pMonsterName, v50);
-      ShowStatusBarString(pTmpBuf.data(), 2u);
-    }
-    v41 = 0;
-  }
-  else
-  {
-    if ( pMonsterStats->pInfos[pMonster->pMonsterInfo.uID].bQuestMonster & 1 )
-    {
-      v33 = byte_4D864C && BYTE2(pGame->uFlags) & 8 ? 10 * pMonster->uActorRadius : pMonster->uActorRadius;
-      //v55 = v33;
-      if ( pRenderer->pRenderD3D )
-      {
-        if ( pGame->uFlags2 & GAME_FLAGS_2_DRAW_BLOODSPLATS )
-        {
-          v50 = 0;
-          pMonsterName = 0;
-          v34 = pMonster->vPosition.z;
-          *(float *)&pPlayerName = (double)v33;
-          //v51 = (unsigned __int64 *)v34;
-          *(float *)&v47 = 0.0;
-          v35 = pMonster->vPosition.y;
-          *((float *)&v46 + 1) = 0.0;
-          *(float *)&v46 = 1.0;
-          v36 = (double)(signed int)pMonster->vPosition.z;
-          //v51 = (unsigned __int64 *)v35;
-          v37 = v36;
-          //v51 = (unsigned __int64 *)pMonster->vPosition.x;
-          v38 = (double)v35;
-          v39 = (double)(signed int)pMonster->vPosition.x;
-          pDecalBuilder->AddBloodsplat(v39, v38, v37, 1.0, 0.0, 0.0, *(float *)&pPlayerName, 0, 0);
-        }
-      }
-    }
-    Actor::Die(uActorID_Monster_);
-    Actor::ApplyFineForKillingPeasant(uActorID_Monster_);
-    Actor::AggroSurroundingPeasants(uActorID_Monster_, 1);
-    if ( pMonster->pMonsterInfo.uExp )
-      GivePartyExp(pMonsterStats->pInfos[pMonster->pMonsterInfo.uID].uExp);
-    v40 = SPEECH_51;
-    if ( rand() % 100 < 20 )
-      v40 = ((signed int)pMonster->pMonsterInfo.uHP >= 100) + 1;
-    player->PlaySound((PlayerSpeech)v40, 0);
-    v41 = 0;
-    if ( bShowDamage )
-    {
-      v50 = (int)pMonster;
-      pMonsterName = (char *)uDamageAmount;
-      pPlayerName = player->pName;             // "%s inflicts %lu points killing %s"
-      sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[175], player->pName, uDamageAmount, pMonster);
-      ShowStatusBarString(pTmpBuf.data(), 2u);
-    }
-  }
-  if ( SHIDWORD(pMonster->pActorBuffs[20].uExpireTime) >= (signed int)v41
-    && (SHIDWORD(pMonster->pActorBuffs[20].uExpireTime) > (signed int)v41
-     || LODWORD(pMonster->pActorBuffs[20].uExpireTime) > v41)
-    && uDamageAmount != v41 )
-    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)
-    && stru_50C198.GetMagicalResistance(pMonster, 3u) )
-  {
-    LODWORD(v42) = 20;
-    v59 = 10;
-    if ( pParty->bTurnBasedModeOn == v41 )
-      v42 = (signed __int64)(flt_6BE3A8_debug_recmod2 * 42.66666666666666);
-    pMonster->pMonsterInfo.uRecoveryTime += v42;
-    if ( bShowDamage != v41 )
-    {
-      v50 = (int)pMonster;
-      pMonsterName = player->pName;            // "%s stuns %s"
-      sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[635], player->pName, pMonster);
-      ShowStatusBarString(pTmpBuf.data(), 2u);
-    }
-  }
-  if ( hit_will_paralyze != v41 )
-  {
-    if ( pMonster->CanAct() )
-    {
-      if ( stru_50C198.GetMagicalResistance(pMonster, 3) )
-      {
-        LOBYTE(v43) = player->GetActualSkillLevel(PLAYER_SKILL_MACE);
-        v44 = v43;
-        v45 = SkillToMastery(v43);
-        //v51 = (unsigned __int64 *)(7680 * (v44 & 0x3F));
-        v46 = pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)(7680 * (v44 & 0x3F)) * 0.033333335);
-        pMonster->pActorBuffs[6].Apply(v46, v45, 0, 0, 0);
-        if ( bShowDamage )
-        {
-          v50 = (int)pMonster;
-          pMonsterName = player->pName;        // "%s paralyzes %s"
-          sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[636], player->pName, pMonster);
-          ShowStatusBarString(pTmpBuf.data(), 2u);
-        }
-      }
-    }
-  }
-  if ( v59 > 10 )
-    v59 = 10;
-  if ( !MonsterStats::BelongsToSupertype(pMonster->pMonsterInfo.uID, MONSTER_SUPERTYPE_TREANT) )
-  {
-    pVelocity->x = (unsigned __int64)(v59 * (signed __int64)pVelocity->x) >> 16;
-    pVelocity->y = (unsigned __int64)(v59 * (signed __int64)pVelocity->y) >> 16;
-    pVelocity->z = (unsigned __int64)(v59 * (signed __int64)pVelocity->z) >> 16;
-    pMonster->vVelocity.x = 50 * LOWORD(pVelocity->x);
-    pMonster->vVelocity.y = 50 * LOWORD(pVelocity->y);
-    pMonster->vVelocity.z = 50 * LOWORD(pVelocity->z);
-  }
-  Actor::AddBloodsplatOnDamageOverlay(uActorID_Monster_, 1, v61);
-}
 // 4D864C: using guessed type char byte_4D864C;
 
-//----- (00439FCB) --------------------------------------------------------
-void __fastcall DamagePlayerFromMonster(unsigned int uObjID, int a2, Vec3_int_ *pPos, unsigned int a4)
-{
-  signed int v4; // esi@1
-  unsigned int v5; // ecx@1
-  Player *v6; // ebx@3
-  Actor *v7; // esi@3
-  unsigned int v8; // eax@4
-  char *v9; // eax@5
-  signed int v10; // eax@6
-  int v11; // edx@8
-  int v12; // edx@9
-  int v13; // edx@10
-  int v14; // edx@16
-  int v15; // edx@17
-  int v16; // edx@18
-  enum SoundID v17; // eax@24
-  int v18; // eax@26
-  unsigned __int8 v19; // zf@26
-  unsigned __int8 v20; // sf@26
-  unsigned __int16 v21; // ax@29
-  signed int v22; // edi@36
-  int v23; // eax@38
-  signed int v24; // eax@44
-  unsigned __int16 v25; // cx@47
-  signed int v26; // eax@49
-  int v27; // eax@54
-  float v28; // ST18_4@58
-  double v29; // st7@58
-  float v30; // ST08_4@58
-  double v31; // st7@58
-  float v32; // ST04_4@58
-  float v33; // ST00_4@58
-  int v34; // edi@61
-  int v35; // eax@70
-  double v36; // st7@70
-  SpriteObject *v37; // ebx@77
-  int v38; // edi@77
-  int v39; // esi@77
-  int v40; // eax@77
-  int v41; // eax@77
-  int v42; // eax@78
-  Player *v43; // eax@81
-  Actor *v44; // esi@82
-  Player *v45; // edi@84
-  unsigned __int16 v46; // ax@84
-  int v47; // ebx@105
-  int v48; // eax@107
-  unsigned __int16 v49; // ax@116
-  int v50; // ebx@123
-  unsigned __int16 v51; // ax@124
-  char v52; // bl@124
-  int v53; // eax@128
-  signed int v54; // eax@134
-  unsigned __int16 v55; // cx@137
-  signed int v56; // eax@139
-  int v57; // eax@144
-  float v58; // ST18_4@148
-  double v59; // st7@148
-  float v60; // ST08_4@148
-  double v61; // st7@148
-  float v62; // ST04_4@148
-  float v63; // ST00_4@148
-  int v64; // ebx@151
-  int v65; // eax@161
-  double v66; // st7@161
-  signed int v67; // ecx@164
-  signed int v68; // eax@170
-  int v69; // ecx@170
-  int v70; // eax@171
-  enum SoundID v71; // [sp+20h] [bp-34h]@12
-  int v72; // [sp+30h] [bp-24h]@164
-  double v73; // [sp+40h] [bp-14h]@72
-  signed int v74; // [sp+44h] [bp-10h]@1
-  unsigned int v75; // [sp+48h] [bp-Ch]@3
-  unsigned int uActorID; // [sp+4Ch] [bp-8h]@1
-  int v77; // [sp+50h] [bp-4h]@26
-  signed int a4a; // [sp+60h] [bp+Ch]@162
-  Player *a4b; // [sp+60h] [bp+Ch]@168
-
-  v4 = PID_ID(uObjID);
-  v5 = PID_TYPE(uObjID) - 2;
-  v74 = a2;
-  uActorID = v4;
-  if ( v5 )
-  {
-    if ( v5 != 1
-      || (v6 = &pParty->pPlayers[a4], v7 = &pActors[v4],
-                                     v75 = v6->sHealth,
-                                     !stru_50C198.ActorHitOrMiss(v7, v6)) )
-      return;
-    v8 = v6->pEquipment.uArmor;
-    if ( !v8
-      || (v9 = (char *)v6 + 36 * v8, v9[516] & 2)
-      || (v10 = pItemsTable->pItems[*((int *)v9 + 124)].uSkillType, v10 < 10)
-      || v10 > 11 )
-    {
-      v14 = rand() % 4;
-      if ( !v14 )
-      {
-        v71 = (SoundID)108;
-        goto LABEL_24;
-      }
-      v15 = v14 - 1;
-      if ( !v15 )
-      {
-        v71 = (SoundID)109;
-        goto LABEL_24;
-      }
-      v16 = v15 - 1;
-      if ( !v16 )
-      {
-        v71 = (SoundID)110;
-        goto LABEL_24;
-      }
-      if ( v16 == 1 )
-      {
-        v71 = (SoundID)44;
-        goto LABEL_24;
-      }
-    }
-    else
-    {
-      v11 = rand() % 4;
-      if ( !v11 )
-      {
-        v71 = (SoundID)105;
-        goto LABEL_24;
-      }
-      v12 = v11 - 1;
-      if ( !v12 )
-      {
-        v71 = (SoundID)106;
-        goto LABEL_24;
-      }
-      v13 = v12 - 1;
-      if ( !v13 )
-      {
-        v71 = (SoundID)107;
-        goto LABEL_24;
-      }
-      if ( v13 == 1 )
-      {
-        v71 = (SoundID)45;
-LABEL_24:
-        v17 = v71;
-        goto LABEL_26;
-      }
-    }
-    v17 = (SoundID)a4;
-LABEL_26:
-    pAudioPlayer->PlaySound(v17, PID(OBJECT_Player,a4 + 80), 0, -1, 0, 0, 0, 0);
-    v18 = Actor::_43B3E0_CalcDamage(v7, v74);
-    v19 = HIDWORD(v7->pActorBuffs[3].uExpireTime) == 0;
-    v20 = SHIDWORD(v7->pActorBuffs[3].uExpireTime) < 0;
-    v77 = v18;
-    if ( !v20 && (!(v20 | v19) || LODWORD(v7->pActorBuffs[3].uExpireTime) > 0) )
-    {
-      v21 = v7->pActorBuffs[3].uPower;
-      if ( v21 )
-        v77 /= (signed int)v21;
-    }
-    if ( v74 )
-    {
-      if ( v74 == 1 )
-      {
-        v22 = v7->pMonsterInfo.uAttack2Type;
-      }
-      else
-      {
-        if ( v74 == 2 )
-        {
-          v23 = v7->pMonsterInfo.uSpell1ID;
-        }
-        else
-        {
-          if ( v74 != 3 )
-          {
-            if ( v74 == 4 )
-              v22 = v7->pMonsterInfo.field_3C_some_special_attack;
-            else
-              v22 = 4;
-            goto LABEL_43;
-          }
-          v23 = v7->pMonsterInfo.uSpell2ID;
-        }
-        v22 = LOBYTE(pSpellStats->pInfos[v23].uSchool);
-      }
-    }
-    else
-    {
-      v22 = v7->pMonsterInfo.uAttack1Type;
-    }
-LABEL_43:
-    if ( !(dword_6BE368_debug_settings_2 & 0x10) )
-    {
-      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)) )
-      {
-        v25 = v7->uAIState;
-        if ( v25 != 5 )
-        {
-          if ( v25 != 4 )
-          {
-            v26 = stru_50C198.CalcMagicalDamageToActor(v7, v22, v24);
-            v7->sCurrentHP -= v26;
-            if ( v26 )
-            {
-              if ( v7->sCurrentHP >= 1 )
-              {
-                Actor::AI_Stun(uActorID, PID(OBJECT_Player,a4), 0);
-                Actor::AggroSurroundingPeasants(uActorID, 1);
-              }
-              else
-              {
-                if ( pMonsterStats->pInfos[v7->pMonsterInfo.uID].bQuestMonster & 1 )
-                {
-                  v27 = byte_4D864C && BYTE2(pGame->uFlags) & 8 ? 10 * v7->uActorRadius : v7->uActorRadius;
-                  v74 = v27;
-                  if ( pRenderer->pRenderD3D )
-                  {
-                    if ( pGame->uFlags2 & GAME_FLAGS_2_DRAW_BLOODSPLATS )
-                    {
-                      v28 = (double)v74;
-                      v74 = v7->vPosition.z;
-                      v29 = (double)v74;
-                      v74 = v7->vPosition.y;
-                      v30 = v29;
-                      v31 = (double)v74;
-                      v74 = v7->vPosition.x;
-                      v32 = v31;
-                      v33 = (double)v74;
-                      pDecalBuilder->AddBloodsplat(v33, v32, v30, 1.0, 0.0, 0.0, v28, 0, 0);
-                    }
-                  }
-                }
-                Actor::Die(uActorID);
-                Actor::ApplyFineForKillingPeasant(uActorID);
-                Actor::AggroSurroundingPeasants(uActorID, 1);
-                if ( v7->pMonsterInfo.uExp )
-                  GivePartyExp(pMonsterStats->pInfos[v7->pMonsterInfo.uID].uExp);
-                v34 = SPEECH_51;
-                if ( rand() % 100 < 20 )
-                  v34 = ((signed int)v7->pMonsterInfo.uHP >= 100) + 1;
-                v6->PlaySound((PlayerSpeech)v34, 0);
-              }
-            }
-          }
-        }
-      }
-      if ( !(dword_6BE368_debug_settings_2 & 0x10)
-        && v7->pMonsterInfo.uSpecialAttack
-        && rand() % 100 < v7->pMonsterInfo.uLevel * v7->pMonsterInfo.uSpecialAttackType )
-        v6->_48DCF6(v7->pMonsterInfo.uSpecialAttack, v7);
-    }
-    if ( !pParty->bTurnBasedModeOn )
-    {
-      v35 = v6->GetActualEndurance();
-      v36 = (double)(20 - v6->GetParameterBonus(v35)) * flt_6BE3A4_debug_recmod1 * 2.133333333333333;
-      v6->SetRecoveryTime((signed __int64)v36);
-    }
-    if ( v77 )
-    {
-      v73 = (double)(signed int)v75;
-      if ( (double)v6->GetMaxHealth() * 0.25 < v73 )
-      {
-        if ( v6->sHealth > 0 )
-        {
-          if ( (double)v6->GetMaxHealth() * 0.25 >= (double)v6->sHealth )
-            v6->PlaySound(SPEECH_48, 0);
-        }
-      }
-    }
-    viewparams->bRedrawGameUI = 1;
-    return;
-  }
-  v37 = &pSpriteObjects[uActorID];
-  v38 = PID_TYPE(v37->spell_caster_pid);
-  v39 = PID_ID(v37->spell_caster_pid);
-  v40 = PID_TYPE(v37->spell_caster_pid);
-  uActorID = PID_ID(v37->spell_caster_pid);
-  v41 = v40 - 2;
-  if ( !v41 )
-    goto LABEL_80;
-  v42 = v41 - 1;
-  if ( !v42 )
-  {
-    v44 = &pActors[v39];
-    if ( a4 == -1 )
-      a4 = stru_50C198.which_player_would_attack(v44);
-    v45 = &pParty->pPlayers[a4];
-    v77 = Actor::_43B3E0_CalcDamage(v44, v74);
-    v46 = v37->uType;
-    if ( v37->uType == 545 )
-    {
-      LOBYTE(v51) = v45->GetActualSkillLevel(PLAYER_SKILL_UNARMED);
-      v52 = v51;
-      if ( (signed int)SkillToMastery(v51) >= 4 && rand() % 100 < (v52 & 0x3F) )
-      {
-		  sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[637], v45->pName);
-        ShowStatusBarString(pTmpBuf.data(), 2u);
-        v45->PlaySound(SPEECH_6, 0);
-        return;
-      }
-    }
-    else
-    {
-      if ( v46 != 555
-        && v46 != 510
-        && v46 != 500
-        && v46 != 515
-        && v46 != 505
-        && v46 != 530
-        && v46 != 525
-        && v46 != 520
-        && v46 != 535
-        && v46 != 540 )
-        goto LABEL_115;
-    }
-    if ( !stru_50C198.ActorHitOrMiss(v44, v45) )
-      return;
-    if ( (signed __int64)v45->pPlayerBuffs[13].uExpireTime > 0 )
-      v77 >>= 1;
-    if ( v45->HasEnchantedItemEquipped(36) )
-      v77 >>= 1;
-    if ( v45->HasEnchantedItemEquipped(69) )
-      v77 >>= 1;
-    if ( v45->HasItemEquipped(EQUIP_ARMOUR)
-		&& *(_DWORD *)&v45->pInventoryItems[v45->pEquipment.uArmor-1] == 504 )
-      v77 >>= 1;
-    v75 = 0;
-	v47 = (int)&v45->pEquipment;
-    do
-    {
-      if ( v45->HasItemEquipped((ITEM_EQUIP_TYPE)v75) )
-      {
-        v48 = *(int *)&v45[36 * *(int *)v47 + 496];
-        if ( v48 == 520 )
-          v77 >>= 1;
-        if ( v48 == 531 )
-          v77 >>= 1;
-        if ( v45->GetEquippedItemEquipType((ITEM_EQUIP_TYPE)v75) == EQUIP_SHIELD && SkillToMastery(v45->pActiveSkills[PLAYER_SKILL_SHIELD]) == 4 )
-          v77 >>= 1;
-      }
-      ++v75;
-      v47 += 4;
-    }
-    while ( (signed int)v75 <= 1 );
-LABEL_115:
-    if ( (signed __int64)v44->pActorBuffs[3].uExpireTime > 0 )
-    {
-      v49 = v44->pActorBuffs[3].uPower;
-      if ( v49 )
-        v77 /= (signed int)v49;
-    }
-    if ( !v74 )
-    {
-      v50 = v44->pMonsterInfo.uAttack1Type;
-      goto LABEL_133;
-    }
-    if ( v74 == 1 )
-    {
-      v50 = v44->pMonsterInfo.uAttack2Type;
-      goto LABEL_133;
-    }
-    if ( v74 == 2 )
-    {
-      v53 = v44->pMonsterInfo.uSpell1ID;
-    }
-    else
-    {
-      if ( v74 != 3 )
-      {
-        if ( v74 == 4 )
-          v50 = v44->pMonsterInfo.field_3C_some_special_attack;
-        else
-          v50 = 4;
-LABEL_133:
-        if ( !(dword_6BE368_debug_settings_2 & 0x10) )
-        {
-          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) )
-            {
-              v55 = v44->uAIState;
-              if ( v55 != 5 )
-              {
-                if ( v55 != 4 )
-                {
-                  v56 = stru_50C198.CalcMagicalDamageToActor(v44, v50, v54);
-                  v44->sCurrentHP -= v56;
-                  if ( v56 )
-                  {
-                    if ( v44->sCurrentHP >= 1 )
-                    {
-                      Actor::AI_Stun(uActorID, PID(OBJECT_Player,a4), 0);
-                      Actor::AggroSurroundingPeasants(uActorID, 1);
-                    }
-                    else
-                    {
-                      if ( pMonsterStats->pInfos[v44->pMonsterInfo.uID].bQuestMonster & 1 )
-                      {
-                        v57 = byte_4D864C && BYTE2(pGame->uFlags) & 8 ? 10 * v44->uActorRadius : v44->uActorRadius;
-                        v75 = v57;
-                        if ( pRenderer->pRenderD3D )
-                        {
-                          if ( pGame->uFlags2 & GAME_FLAGS_2_DRAW_BLOODSPLATS )
-                          {
-                            v58 = (double)(signed int)v75;
-                            v75 = v44->vPosition.z;
-                            v59 = (double)(signed int)v75;
-                            v75 = v44->vPosition.y;
-                            v60 = v59;
-                            v61 = (double)(signed int)v75;
-                            v75 = v44->vPosition.x;
-                            v62 = v61;
-                            v63 = (double)(signed int)v75;
-                            pDecalBuilder->AddBloodsplat(v63, v62, v60, 1.0, 0.0, 0.0, v58, 0, 0);
-                          }
-                        }
-                      }
-                      Actor::Die(uActorID);
-                      Actor::ApplyFineForKillingPeasant(uActorID);
-                      Actor::AggroSurroundingPeasants(uActorID, 1);
-                      if ( v44->pMonsterInfo.uExp )
-                        GivePartyExp(pMonsterStats->pInfos[v44->pMonsterInfo.uID].uExp);
-                      v64 = SPEECH_51;
-                      if ( rand() % 100 < 20 )
-                        v64 = ((signed int)v44->pMonsterInfo.uHP >= 100) + 1;
-                      v45->PlaySound((PlayerSpeech)v64, 0);
-                    }
-                  }
-                }
-              }
-            }
-          }
-        }
-        if ( !v74
-          && !(dword_6BE368_debug_settings_2 & 0x10)
-          && v44->pMonsterInfo.uSpecialAttack
-          && rand() % 100 < v44->pMonsterInfo.uLevel * v44->pMonsterInfo.uSpecialAttackType )
-          v45->_48DCF6(v44->pMonsterInfo.uSpecialAttack, v44);
-        if ( !pParty->bTurnBasedModeOn )
-        {
-          v65 = v45->GetActualEndurance();
-          v66 = (double)(20 - v45->GetParameterBonus(v65))
-              * flt_6BE3A4_debug_recmod1
-              * 2.133333333333333;
-          v45->SetRecoveryTime((signed __int64)v66);
-        }
-        return;
-      }
-      v53 = v44->pMonsterInfo.uSpell2ID;
-    }
-    v50 = LOBYTE(pSpellStats->pInfos[v53].uSchool);
-    goto LABEL_133;
-  }
-  if ( v42 != 1 )
-    return;
-LABEL_80:
-  if ( a4 != -1 )
-  {
-    v43 = &pParty->pPlayers[a4];
-LABEL_168:
-    a4b = v43;
-    if ( v38 != OBJECT_Player || v37->spell_id != SPELL_BOW_ARROW)
-    {
-      v70 = v43->GetMaxHealth();
-      v68 = _43AFE3_calc_spell_damage(v37->spell_id, v37->spell_level, v37->spell_skill, v70);
-      v69 = LOBYTE(pSpellStats->pInfos[v37->spell_id].uSchool);
-    }
-    else
-    {
-      v68 = pParty->pPlayers[uActorID].CalculateRangedDamageTo(0);
-      v69 = 0;
-    }
-    a4b->ReceiveDamage(v68, (DAMAGE_TYPE)v69);
-    if ( v38 == OBJECT_Player && !qword_A750D8 )
-    {
-      qword_A750D8 = 256i64;
-      word_A750E0 = 44;
-      word_A750E2 = uActorID + 1;
-    }
-    return;
-  }
-  v74 = 0;
-  a4a = 1;
-  do
-  {
-    if ( pPlayers[a4a]->CanAct() )
-    {
-      v67 = v74++;
-      *(&v72 + v67) = a4a;
-    }
-    ++a4a;
-  }
-  while ( a4a <= 4 );
-  if ( v74 )
-  {
-    v43 = &pParty->pPlayers[*(&v72+rand()%v74)-1];//&stru_AA1058[3].pSounds[6972 * *(&v72 + rand() % v74) + 40552];
-    goto LABEL_168;
-  }
-}
-
 //----- (0043A97E) --------------------------------------------------------
 void __fastcall sub_43A97E(unsigned int uLayingItemID, signed int a2)
 {
@@ -5440,47 +4382,6 @@
   return result;
 }
 
-//----- (0043AFE3) --------------------------------------------------------
-int __fastcall _43AFE3_calc_spell_damage(int a1, int a2, signed int a3, int a4)
-{
-  int result; // eax@1
-  unsigned int v5; // [sp-4h] [bp-8h]@9
-
-  result = 0;
-  if ( a1 == 7 )
-  {
-    if ( a3 <= 0 )
-      return result;
-    if ( a3 <= 2 )
-    {
-      v5 = 6;
-    }
-    else
-    {
-      if ( a3 == 3 )
-      {
-        v5 = 8;
-      }
-      else
-      {
-        if ( a3 != 4 )
-          return result;
-        v5 = 10;
-      }
-    }
-    result = GetDiceResult(a2, v5);
-  }
-  else
-  {
-    if ( a1 == 44 )
-      result = a4 * (LOBYTE(pSpellDatas[40].field_10) + 2 * a2) / 100;
-    else
-      result = *((char *)&pSpellDatas[0].field_10 + 20 * a1)
-             + GetDiceResult(a2, *((char *)&pSpellDatas[0].field_10 + 20 * a1 + 1));
-  }
-  return result;
-}
-
 //----- (0043B057) --------------------------------------------------------
 void __fastcall sub_43B057(unsigned int uObjID, unsigned int uActorID, Vec3_int_ *pVelocity)
 {
@@ -5654,369 +4555,14 @@
   }
 }
 
-//----- (0043C91D) --------------------------------------------------------
-int __fastcall GetItemTextureFilename(char *pOut, signed int item_id, int index, int shoulder)
-{
-  int result; // eax@2
-  char v5; // zf@3
-  const char *v6; // [sp-Ch] [bp-18h]@88
-  signed int v7; // [sp-8h] [bp-14h]@61
-  int v8; // [sp-4h] [bp-10h]@61
-  signed int v9; // [sp-4h] [bp-10h]@69
-
-  result = 0; //BUG   fn is void
-  if ( item_id <= 500 )
-  {
-    //v5 = *((char *)&pBloodsplatContainer->std__vector_pBloodsplats[62].field_20 + a2 + 2) == 0;
-    v5 = party_has_equipment[(item_id - 100) + 32 + 2] == 0;
-    switch ( item_id )
-    {
-      case 516:
-        v5 = byte_5111F6[2] == 0;
-        break;
-      case 505:
-        v5 = byte_5111F6[1] == 0;
-        break;
-      case 504:
-        v5 = byte_5111F6[0] == 0;
-        break;
-      case 533:
-        v5 = byte_5111F6[16] == 0;
-        break;
-      case 512:
-        v5 = byte_5111F6[3] == 0;
-        break;
-      case 521:
-        v5 = byte_5111F6[4] == 0;
-        break;
-      case 522:
-        v5 = byte_5111F6[5] == 0;
-        break;
-      case 523:
-        v5 = byte_5111F6[6] == 0;
-        break;
-      case 532:
-        v5 = byte_5111F6[7] == 0;
-        break;
-      case 544:
-        v5 = byte_5111F6[8] == 0;
-        break;
-      case 524:
-        v5 = byte_5111F6[9] == 0;
-        break;
-      case 535:
-        v5 = byte_5111F6[10] == 0;
-        break;
-      case 525:
-        v5 = byte_5111F6[11] == 0;
-        break;
-      case 530:
-        v5 = byte_5111F6[12] == 0;
-        break;
-      case 547:
-        v5 = byte_5111F6[13] == 0;
-        break;
-      case 548:
-        v5 = byte_5111F6[14] == 0;
-        break;
-      case 550:
-        v5 = byte_5111F6[15] == 0;
-        break;
-      default:
-        break;
-    }
-    if ( v5 )
-      return result;
-    result = 516;
-    if ( item_id < 66 || item_id > 78 )
-    {
-      if ( item_id == 516 )
-      {
-        if ( !shoulder )
-          return sprintf(pOut, "item%3.3dv%d", 234, index);
-        if ( shoulder == 1 )
-          return sprintf(pOut, "item%3.3dv%da1", 234, index);
-        if ( shoulder == 2 )
-          return sprintf(pOut, "item%3.3dv%da2", 234, index);
-      }
-      if ( item_id != 504 && item_id != 505 && item_id != 533 )
-      {
-        if ( (item_id < 100 || item_id > 104) && item_id != 524 && item_id != 535 )
-        {
-          if ( item_id >= 115 && item_id <= 119 || item_id == 512 )
-          {
-            if ( item_id == 512 )
-              item_id = 312;
-            return sprintf(pOut, "item%3.3dv%d", item_id, index);
-          }
-          if ( (item_id < 89 || item_id > 99) && item_id != 521 && item_id != 522 && item_id != 523 && item_id != 532 && item_id != 544 )
-          {
-            result = 525;
-            if ( (item_id < 105 || item_id > 109) && item_id != 525 && item_id != 530 && item_id != 547 && item_id != 548 && item_id != 550 )
-              return result;
-            switch ( item_id )
-            {
-              case 525:
-                item_id = 325;
-                break;
-              case 530:
-                item_id = 330;
-                break;
-              case 547:
-                item_id = 347;
-                break;
-              case 548:
-                item_id = 348;
-                break;
-              case 550:
-                item_id = 350;
-                break;
-            }
-            if ( !shoulder )
-              return sprintf(pOut, "item%3.3dv%d", item_id, index);
-            return sprintf(pOut, "item%3.3dv%da1", item_id, index);
-          }
-          if ( item_id == 521 )
-            return sprintf(pOut, "item%3.3dv%d", 239, index);
-          if ( item_id == 522 )
-            return sprintf(pOut, "item%3.3dv%d", 240, index);
-          if ( item_id == 523 )
-            return sprintf(pOut, "item%3.3dv%d", 241, index);
-          if ( item_id != 532 )
-          {
-            if ( item_id == 544 )
-              item_id = 344;
-            return sprintf(pOut, "item%3.3dv%d", item_id, index);
-          }
-          return sprintf(pOut, "item%3.3dv%d", 93, index);
-        }
-        if ( item_id == 524 )
-          return sprintf(pOut, "item%3.3dv%d", 324, index);
-        if ( item_id == 535 )
-          item_id = 104;
-        return sprintf(pOut, "item%3.3dv%d", item_id, index);
-      }
-    }
-    if ( item_id != 516 )
-    {
-      switch ( item_id )
-      {
-        case 504:
-          item_id = 235;
-          break;
-        case 505:
-          item_id = 236;
-          break;
-        case 533:
-          item_id = 73;
-          break;
-      }
-      if ( !shoulder )
-        return sprintf(pOut, "item%3.3dv%d", item_id, index);
-      if ( shoulder == 1 )
-        return sprintf(pOut, "item%3.3dv%da1", item_id, index);
-      if ( shoulder == 2 )
-        return sprintf(pOut, "item%3.3dv%da2", item_id, index);
-    }
-    if ( !shoulder )
-      return sprintf(pOut, "item%3.3dv%d", 234, index);
-    if ( shoulder == 1 )
-      return sprintf(pOut, "item%3.3dv%da1", 234, index);
-    if ( shoulder == 2 )
-      return sprintf(pOut, "item%3.3dv%da2", 234, index);
-  }
-  result = item_id - 504;
-  return result;
-}
-
-//----- (0043ED6F) --------------------------------------------------------
-bool _43ED6F_check_party_races(bool a1)
-{
-  bool v6; // zf@5
-
-  for (uint i = 0; i < 4; ++i)
-  {
-    auto player = pParty->pPlayers + i;
-    auto race = player->GetRace();
-
-    if (race != CHARACTER_RACE_HUMAN &&
-        race != CHARACTER_RACE_ELF &&
-        race != CHARACTER_RACE_GOBLIN)
-      v6 = a1 == 1;
-    else
-      v6 = !a1;
-
-    if (v6)
-      return true;
-  }
-  return false;
-}
+// A750D8: using guessed type __int64 qword_A750D8;
+
+
 // A750D8: using guessed type __int64 qword_A750D8;
 
-//----- (0043EDB9) --------------------------------------------------------
-bool __thiscall sub_43EDB9_get_some_race_sex_relation_2(unsigned int a1)
-{
-  unsigned int pNum; // ebp@1
-  Player **pPlayer; // ebx@1
-  Player *pPlayer2; // esi@2
-  enum CHARACTER_RACE pRace; // edi@2
-  bool pSex; // eax@2
-  char v6; // zf@7
-
-//pPlayer = &pPlayers[1];
-  /*pNum = a1;
-  
-  while ( 1 )
-  {
-    pPlayer2 = *pPlayer;
-    pRace = pPlayer2->GetRace();
-    pSex = pPlayer2->GetSexByVoice();
-    if ( !pRace )
-      break;
-    if ( pRace == 1 || pRace == 2 )
-      break;
-    if ( !pSex && pNum == 2 )//
-      //goto LABEL_15;
-    {
-      pSex = 1;
-      return pSex;
-    }
-    v6 = pNum == 3;//
-LABEL_11:
-    if ( v6 )
-      //goto LABEL_15;
-    {
-      pSex = 1;
-      return pSex;
-    }
-    ++pPlayer;
-    if ( (signed int)pPlayer >= (signed int)&qword_A750D8 )//
-    {
-      pSex = 0;
-      return pSex;
-    }
-  }
-  if ( pSex || pNum )
-  {
-    v6 = pNum == 1;
-    goto LABEL_11;
-  }
-//LABEL_15:
-  pSex = 1;
-  return pSex;*/
-  for (uint i = 1; i <= 4; ++i)
-    {
-      pRace = pPlayers[i]->GetRace();
-      pSex = pPlayers[i]->GetSexByVoice();
-      if (pRace == 0 || pRace == 1 || pRace == 2 || pSex == 0 )
-        return 1;
-    }
- return 0;
-}
+
 // A750D8: using guessed type __int64 qword_A750D8;
 
-//----- (0043EE15) --------------------------------------------------------
-bool __fastcall Player_has_item(unsigned int uItemID, Player *pPlayer, char a3)
-{
-  if ( !a3 || pParty->pPickedItem.uItemID != uItemID )
-  {
-    for ( uint i = 0; i < 126; ++i )
-    {
-      if ( pPlayer->pInventoryIndices[i] > 0 )
-      {
-        if ( (unsigned int)pPlayer->pInventoryItems[pPlayer->pInventoryIndices[i] - 1].uItemID == uItemID )
-          return true;
-      }
-    }
-    for ( uint i = 0; i < 16; ++i )
-    {
-      if ( pPlayer->pEquipment.pIndices[i] )
-      {
-        if ( (unsigned int)pPlayer->pInventoryItems[pPlayer->pEquipment.pIndices[i] - 1].uItemID == uItemID )
-          return true;
-      }
-    }
-  }
-  return false;
-}
-
-//----- (0043EE77) --------------------------------------------------------
-bool __fastcall sub_43EE77_ProbablyIfUnderwaterSuitIsEquipped(signed int a1)
-{
-  bool result; // eax@0
-  Player *v2; // edx@3
-  int v3; // ecx@3
-  Player **pPlayers; // esi@8
-  unsigned int v5; // ecx@8
-  Player *v6; // edx@9
-
-  if ( a1 < 1 || a1 > 4 )
-  {
-    if ( !a1 )
-    {
-      pPlayers = &::pPlayers[1];
-      v5 = 604;
-      while ( 1 )
-      {
-        result = Player_has_item(v5, *pPlayers, 0);
-        if ( !result )
-          break;
-        result = v6->pEquipment.uArmor;
-        if ( !result )
-          break;
-        result *= 9;
-        if ( *(int *)&v6->spellbook.pDarkSpellbook.bIsSpellAvailable[4 * result + 5] != v5 )
-          break;
-        ++pPlayers;
-        if ( (signed int)pPlayers >= (signed int)&qword_A750D8 )
-          goto LABEL_13;
-      }
-    }
-    goto LABEL_6;
-  }
-  result = Player_has_item(604u, ::pPlayers[a1], 0);
-  if ( !result
-    || (result = v2->pEquipment.uArmor) == 0
-    || (result *= 9, *(int *)&v2->spellbook.pDarkSpellbook.bIsSpellAvailable[4 * result + 5] != v3) )
-  {
-LABEL_6:
-    LOBYTE(result) = 0;
-    return result;
-  }
-LABEL_13:
-  LOBYTE(result) = 1;
-  return result;
-}
-// A750D8: using guessed type __int64 qword_A750D8;
-
-
-//----- (0043F333) --------------------------------------------------------
-void BspRenderer::MakeVisibleSectorList()
-{
-  int v6; // ebx@3
-
-  uNumVisibleNotEmptySectors = 0;
-  for (uint i = 0; i < num_nodes; ++i)
-  {
-      if (!uNumVisibleNotEmptySectors)
-      {
-        pVisibleSectorIDs_toDrawDecorsActorsEtcFrom[uNumVisibleNotEmptySectors++] = nodes[i].uSectorID;
-        continue;
-      }
-      
-      v6 = 0;
-        while (pVisibleSectorIDs_toDrawDecorsActorsEtcFrom[v6] != nodes[i].uSectorID )
-        {
-          ++v6;
-          if ( v6 >= uNumVisibleNotEmptySectors)
-          {
-            pVisibleSectorIDs_toDrawDecorsActorsEtcFrom[uNumVisibleNotEmptySectors++] = nodes[i].uSectorID;
-          }
-        }
-
-  }
-}
-
 //----- (0043F515) --------------------------------------------------------
 void FindBillboardsLightLevels_BLV()
 {
@@ -8061,835 +6607,6 @@
   return result;
 }
 
-//----- (00407A1C) --------------------------------------------------------
-bool __fastcall sub_407A1C(int x, int z, int y, Vec3_int_ v)
-{
-  unsigned int v4; // esi@1
-  Vec3_int_ v5; // ST08_12@2
-  int v6; // edi@2
-  int v7; // ebx@2
-  int v8; // esi@2
-  signed int v9; // ecx@2
-  int v10; // eax@2
-  int v11; // ecx@4
-  int v12; // eax@4
-  int v13; // ebx@4
-  int v14; // edx@6
-  char *v15; // edi@16
-  ODMFace *v16; // esi@19
-  int v17; // ST34_4@25
-  int v18; // ST38_4@25
-  int v19; // eax@25
-  char v20; // zf@25
-  int v21; // ebx@25
-  int v22; // eax@26
-  signed int v23; // edi@26
-  int v24; // ST34_4@30
-  signed __int64 v25; // qtt@31
-  int v26; // eax@31
-  Vec3_int_ v27; // ST08_12@37
-  Vec3_int_ v28; // ST08_12@37
-  int v29; // edi@37
-  int v30; // ebx@37
-  int v31; // esi@37
-  signed int v32; // ecx@37
-  int v33; // eax@37
-  int v34; // ecx@39
-  int v35; // eax@39
-  int v36; // ebx@39
-  int v37; // edx@41
-  char *v38; // edi@51
-  ODMFace *v39; // esi@54
-  int v40; // ebx@60
-  int v41; // eax@61
-  signed int v42; // edi@61
-  signed __int64 v43; // qtt@66
-  int v44; // eax@66
-  Vec3_int_ v45; // ST08_12@73
-  int v46; // edi@73
-  int v47; // ebx@73
-  int v48; // esi@73
-  signed int v49; // ecx@73
-  int v50; // eax@73
-  int v51; // edx@75
-  int v52; // ecx@75
-  int v53; // eax@75
-  int v54; // ebx@75
-  int v55; // edi@77
-  int v56; // ecx@77
-  int v57; // eax@81
-  int v58; // esi@81
-  int v59; // eax@90
-  BLVSector *v60; // edx@90
-  int v61; // ecx@90
-  BLVFace *v62; // esi@91
-  int v63; // ST34_4@98
-  int v64; // ST30_4@98
-  int v65; // eax@98
-  int v66; // ebx@98
-  int v67; // eax@99
-  signed int v68; // edi@99
-  int v69; // ST2C_4@103
-  signed __int64 v70; // qtt@104
-  int v71; // eax@104
-  Vec3_int_ v72; // ST08_12@111
-  Vec3_int_ v73; // ST08_12@111
-  int v74; // edi@111
-  int v75; // ebx@111
-  int v76; // esi@111
-  signed int v77; // ecx@111
-  int v78; // eax@111
-  int v79; // edx@113
-  int v80; // ecx@113
-  int v81; // eax@113
-  int v82; // ebx@113
-  int v83; // edi@115
-  int v84; // ecx@115
-  int v85; // eax@119
-  int v86; // esi@119
-  int v87; // ecx@128
-  BLVSector *v88; // eax@128
-  int v89; // ecx@128
-  BLVFace *v90; // esi@129
-  int v91; // ebx@136
-  int v92; // eax@137
-  signed int v93; // edi@137
-  signed __int64 v94; // qtt@142
-  int v95; // eax@142
-  Vec3_int_ v97; // [sp-18h] [bp-94h]@1
-  int v98; // [sp-Ch] [bp-88h]@88
-  int v99; // [sp-Ch] [bp-88h]@126
-  int v100; // [sp-8h] [bp-84h]@88
-  int v101; // [sp-8h] [bp-84h]@126
-  int v102; // [sp-4h] [bp-80h]@88
-  int v103; // [sp-4h] [bp-80h]@126
-  int v104; // [sp+Ch] [bp-70h]@13
-  int v105; // [sp+Ch] [bp-70h]@48
-  int v106; // [sp+10h] [bp-6Ch]@18
-  int v107; // [sp+10h] [bp-6Ch]@98
-  int v108; // [sp+10h] [bp-6Ch]@104
-  int v109; // [sp+18h] [bp-64h]@25
-  int v110; // [sp+18h] [bp-64h]@31
-  int i; // [sp+18h] [bp-64h]@90
-  int v112; // [sp+18h] [bp-64h]@128
-  signed int v113; // [sp+20h] [bp-5Ch]@1
-  signed int v114; // [sp+24h] [bp-58h]@1
-  unsigned __int64 a4; // [sp+28h] [bp-54h]@1
-  unsigned int a4_8; // [sp+30h] [bp-4Ch]@1
-  int v117; // [sp+34h] [bp-48h]@4
-  int v118; // [sp+34h] [bp-48h]@39
-  int v119; // [sp+34h] [bp-48h]@75
-  int v120; // [sp+34h] [bp-48h]@113
-  int v121; // [sp+38h] [bp-44h]@4
-  int v122; // [sp+38h] [bp-44h]@39
-  int v123; // [sp+38h] [bp-44h]@76
-  int v124; // [sp+38h] [bp-44h]@114
-  int v125; // [sp+3Ch] [bp-40h]@4
-  int v126; // [sp+3Ch] [bp-40h]@39
-  int v127; // [sp+3Ch] [bp-40h]@77
-  int v128; // [sp+3Ch] [bp-40h]@115
-  int v129; // [sp+40h] [bp-3Ch]@11
-  int v130; // [sp+40h] [bp-3Ch]@46
-  int v131; // [sp+40h] [bp-3Ch]@78
-  int v132; // [sp+40h] [bp-3Ch]@116
-  int v133; // [sp+44h] [bp-38h]@10
-  int v134; // [sp+44h] [bp-38h]@45
-  int v135; // [sp+44h] [bp-38h]@81
-  int v136; // [sp+44h] [bp-38h]@119
-  int v137; // [sp+48h] [bp-34h]@7
-  int v138; // [sp+48h] [bp-34h]@42
-  int v139; // [sp+48h] [bp-34h]@82
-  int v140; // [sp+48h] [bp-34h]@120
-  int v141; // [sp+4Ch] [bp-30h]@6
-  int v142; // [sp+4Ch] [bp-30h]@41
-  int v143; // [sp+4Ch] [bp-30h]@75
-  int v144; // [sp+4Ch] [bp-30h]@113
-  int v145; // [sp+50h] [bp-2Ch]@5
-  int v146; // [sp+50h] [bp-2Ch]@40
-  int v147; // [sp+50h] [bp-2Ch]@75
-  int v148; // [sp+50h] [bp-2Ch]@113
-  int v149; // [sp+54h] [bp-28h]@4
-  int v150; // [sp+54h] [bp-28h]@39
-  int v151; // [sp+54h] [bp-28h]@75
-  int v152; // [sp+54h] [bp-28h]@113
-  int sDepth; // [sp+58h] [bp-24h]@17
-  int sDeptha; // [sp+58h] [bp-24h]@52
-  int sDepthb; // [sp+58h] [bp-24h]@90
-  char *a5; // [sp+5Ch] [bp-20h]@16
-  char *a5a; // [sp+5Ch] [bp-20h]@51
-  signed int a5b; // [sp+5Ch] [bp-20h]@83
-  signed int a5c; // [sp+5Ch] [bp-20h]@121
-  signed int v160; // [sp+60h] [bp-1Ch]@12
-  signed int v161; // [sp+60h] [bp-1Ch]@47
-  int v162; // [sp+60h] [bp-1Ch]@128
-  int v163; // [sp+64h] [bp-18h]@2
-  int outx; // [sp+68h] [bp-14h]@2
-  int outy; // [sp+6Ch] [bp-10h]@2
-  int outz; // [sp+70h] [bp-Ch]@2
-  Vec3_int_ pOut; // [sp+74h] [bp-8h]@2
-  int ya; // [sp+84h] [bp+8h]@60
-  int yb; // [sp+84h] [bp+8h]@136
-  int ve; // [sp+88h] [bp+Ch]@60
-  int va; // [sp+88h] [bp+Ch]@60
-  int vb; // [sp+88h] [bp+Ch]@66
-  int vf; // [sp+88h] [bp+Ch]@136
-  int vc; // [sp+88h] [bp+Ch]@136
-  int vd; // [sp+88h] [bp+Ch]@142
-  int v_4; // [sp+8Ch] [bp+10h]@60
-  int v_4a; // [sp+8Ch] [bp+10h]@65
-  int v_4b; // [sp+8Ch] [bp+10h]@136
-  int v_4c; // [sp+8Ch] [bp+10h]@141
-  int v_8; // [sp+90h] [bp+14h]@53
-
-  a4 = __PAIR__(z, x);
-  v4 = stru_5C6E00->Atan2(v.x - x, v.y - z);
-  v114 = 0;
-  v97.z = y;
-  v113 = 0;
-  a4_8 = v4;
-  *(_QWORD *)&v97.x = a4;
-  if ( uCurrentlyLoadedLevelType != LEVEL_Outdoor)
-  {
-    Vec3_int_::Rotate(32, stru_5C6E00->uIntegerHalfPi + v4, 0, v97, &pOut.x, &pOut.y, &outz);
-    v45.z = v.z;
-    *(_QWORD *)&v45.x = *(_QWORD *)&v;
-    Vec3_int_::Rotate(32, stru_5C6E00->uIntegerHalfPi + v4, 0, v45, &outx, &outy, &v163);
-    v46 = outy - pOut.y;
-    v47 = v163 - outz;
-    v48 = outx - pOut.x;
-    v49 = integer_sqrt(v48 * v48 + v46 * v46 + v47 * v47);
-    v50 = 65536;
-    if ( v49 )
-      v50 = 65536 / v49;
-    v51 = outx;
-    v143 = v48 * v50;
-    v52 = v46 * v50;
-    v53 = v47 * v50;
-    v54 = pOut.x;
-    v147 = v52;
-    v151 = v53;
-    v119 = pOut.x;
-    if ( pOut.x < outx )
-    {
-      v123 = outx;
-    }
-    else
-    {
-      v119 = outx;
-      v123 = pOut.x;
-    }
-    v55 = pOut.y;
-    v56 = outy;
-    v127 = pOut.y;
-    if ( pOut.y < outy )
-    {
-      v131 = outy;
-    }
-    else
-    {
-      v127 = outy;
-      v131 = pOut.y;
-    }
-    v57 = v163;
-    v58 = outz;
-    v135 = outz;
-    if ( outz < v163 )
-    {
-      v139 = v163;
-    }
-    else
-    {
-      v135 = v163;
-      v139 = outz;
-    }
-    a5b = 0;
-    while ( !v114 )
-    {
-      if ( a5b )
-      {
-        v102 = v58;
-        v100 = v55;
-        v98 = v54;
-      }
-      else
-      {
-        v102 = v57;
-        v100 = v56;
-        v98 = v51;
-      }
-      v59 = pIndoor->GetSector(v98, v100, v102);
-      v60 = pIndoor->pSectors;
-      v61 = 116 * v59;
-      sDepthb = 0;
-      for ( i = 116 * v59;
-            sDepthb < *(__int16 *)((char *)&pIndoor->pSectors->uNumWalls + v61)
-                    + 2 * *(__int16 *)((char *)&pIndoor->pSectors->uNumFloors + v61);
-            ++sDepthb )
-      {
-        v62 = &pIndoor->pFaces[(*(unsigned __int16 **)((char *)&v60->pWalls + v61))[sDepthb]];
-        if ( v62->Portal()
-          || v119 > v62->pBounding.x2
-          || v123 < v62->pBounding.x1
-          || v127 > v62->pBounding.y2
-          || v131 < v62->pBounding.y1
-          || v135 > v62->pBounding.z2
-          || v139 < v62->pBounding.z1
-          || (v63 = (unsigned __int64)(v143 * (signed __int64)v62->pFacePlane_old.vNormal.x) >> 16,
-              v64 = (unsigned __int64)(v151 * (signed __int64)v62->pFacePlane_old.vNormal.z) >> 16,
-              v65 = (unsigned __int64)(v147 * (signed __int64)v62->pFacePlane_old.vNormal.y) >> 16,
-              v20 = v63 + v64 + v65 == 0,
-              v66 = v63 + v64 + v65,
-              v107 = v63 + v64 + v65,
-              v20) )
-          goto LABEL_107;
-        v67 = outz * v62->pFacePlane_old.vNormal.z;
-        v68 = -(v62->pFacePlane_old.dist
-              + v67
-              + pOut.y * v62->pFacePlane_old.vNormal.y
-              + pOut.x * v62->pFacePlane_old.vNormal.x);
-        if ( v66 <= 0 )
-        {
-          if ( v62->pFacePlane_old.dist
-             + v67
-             + pOut.y * v62->pFacePlane_old.vNormal.y
-             + pOut.x * v62->pFacePlane_old.vNormal.x < 0 )
-            goto LABEL_107;
-        }
-        else
-        {
-          if ( v62->pFacePlane_old.dist
-             + v67
-             + pOut.y * v62->pFacePlane_old.vNormal.y
-             + pOut.x * v62->pFacePlane_old.vNormal.x > 0 )
-            goto LABEL_107;
-        }
-        v69 = abs(-(v62->pFacePlane_old.dist
-                  + v67
-                  + pOut.y * v62->pFacePlane_old.vNormal.y
-                  + pOut.x * v62->pFacePlane_old.vNormal.x)) >> 14;
-        if ( v69 <= abs(v66) )
-        {
-          LODWORD(v70) = v68 << 16;
-          HIDWORD(v70) = v68 >> 16;
-          v71 = v70 / v107;
-          v108 = v70 / v107;
-          if ( v71 >= 0 )
-          {
-            if ( sub_4075DB(
-                   pOut.x + ((signed int)(((unsigned __int64)(v108 * (signed __int64)v143) >> 16) + 32768) >> 16),
-                   pOut.y + ((signed int)(((unsigned __int64)(v108 * (signed __int64)v147) >> 16) + 32768) >> 16),
-                   outz + ((signed int)(((unsigned __int64)(v108 * (signed __int64)v151) >> 16) + 32768) >> 16),
-                   v62) )
-            {
-              v114 = 1;
-              break;
-            }
-          }
-        }
-        v61 = i;
-LABEL_107:
-        v60 = pIndoor->pSectors;
-      }
-      ++a5b;
-      if ( a5b >= 2 )
-        break;
-      v57 = v163;
-      v56 = outy;
-      v51 = outx;
-      v58 = outz;
-      v55 = pOut.y;
-      v54 = pOut.x;
-    }
-    v72.z = y;
-    *(_QWORD *)&v72.x = a4;
-    Vec3_int_::Rotate(32, a4_8 - stru_5C6E00->uIntegerHalfPi, 0, v72, &pOut.x, &pOut.y, &outz);
-    v73.z = v.z;
-    *(_QWORD *)&v73.x = *(_QWORD *)&v;
-    Vec3_int_::Rotate(32, a4_8 - stru_5C6E00->uIntegerHalfPi, 0, v73, &outx, &outy, &v163);
-    v74 = outy - pOut.y;
-    v75 = v163 - outz;
-    v76 = outx - pOut.x;
-    v77 = integer_sqrt(v76 * v76 + v74 * v74 + v75 * v75);
-    v78 = 65536;
-    if ( v77 )
-      v78 = 65536 / v77;
-    v79 = outx;
-    v144 = v76 * v78;
-    v80 = v74 * v78;
-    v81 = v75 * v78;
-    v82 = pOut.x;
-    v148 = v80;
-    v152 = v81;
-    v120 = pOut.x;
-    if ( pOut.x < outx )
-    {
-      v124 = outx;
-    }
-    else
-    {
-      v120 = outx;
-      v124 = pOut.x;
-    }
-    v83 = pOut.y;
-    v84 = outy;
-    v128 = pOut.y;
-    if ( pOut.y < outy )
-    {
-      v132 = outy;
-    }
-    else
-    {
-      v128 = outy;
-      v132 = pOut.y;
-    }
-    v85 = v163;
-    v86 = outz;
-    v136 = outz;
-    if ( outz < v163 )
-    {
-      v140 = v163;
-    }
-    else
-    {
-      v136 = v163;
-      v140 = outz;
-    }
-    a5c = 0;
-    while ( 1 )
-    {
-      if ( v113 )
-        return !v114 || !v113;
-      if ( a5c )
-      {
-        v103 = v86;
-        v101 = v83;
-        v99 = v82;
-      }
-      else
-      {
-        v103 = v85;
-        v101 = v84;
-        v99 = v79;
-      }
-      v87 = pIndoor->GetSector(v99, v101, v103);
-      v88 = pIndoor->pSectors;
-      v89 = 116 * v87;
-      v162 = 0;
-      v112 = v89;
-      if ( *(__int16 *)((char *)&pIndoor->pSectors->uNumWalls + v89)
-         + 2 * *(__int16 *)((char *)&pIndoor->pSectors->uNumFloors + v89) > 0 )
-        break;
-LABEL_148:
-      ++a5c;
-      if ( a5c >= 2 )
-        return !v114 || !v113;
-      v85 = v163;
-      v84 = outy;
-      v79 = outx;
-      v86 = outz;
-      v83 = pOut.y;
-      v82 = pOut.x;
-    }
-    while ( 1 )
-    {
-      v90 = &pIndoor->pFaces[(*(unsigned __int16 **)((char *)&v88->pWalls + v89))[v162]];
-      if ( v90->Portal()
-        || v120 > v90->pBounding.x2
-        || v124 < v90->pBounding.x1
-        || v128 > v90->pBounding.y2
-        || v132 < v90->pBounding.y1
-        || v136 > v90->pBounding.z2
-        || v140 < v90->pBounding.z1
-        || (yb = (unsigned __int64)(v144 * (signed __int64)v90->pFacePlane_old.vNormal.x) >> 16,
-            v_4b = (unsigned __int64)(v148 * (signed __int64)v90->pFacePlane_old.vNormal.y) >> 16,
-            vf = (unsigned __int64)(v152 * (signed __int64)v90->pFacePlane_old.vNormal.z) >> 16,
-            v20 = yb + vf + v_4b == 0,
-            v91 = yb + vf + v_4b,
-            vc = yb + vf + v_4b,
-            v20) )
-        goto LABEL_145;
-      v92 = outz * v90->pFacePlane_old.vNormal.z;
-      v93 = -(v90->pFacePlane_old.dist
-            + v92
-            + pOut.y * v90->pFacePlane_old.vNormal.y
-            + pOut.x * v90->pFacePlane_old.vNormal.x);
-      if ( v91 <= 0 )
-      {
-        if ( v90->pFacePlane_old.dist
-           + v92
-           + pOut.y * v90->pFacePlane_old.vNormal.y
-           + pOut.x * v90->pFacePlane_old.vNormal.x < 0 )
-          goto LABEL_145;
-      }
-      else
-      {
-        if ( v90->pFacePlane_old.dist
-           + v92
-           + pOut.y * v90->pFacePlane_old.vNormal.y
-           + pOut.x * v90->pFacePlane_old.vNormal.x > 0 )
-          goto LABEL_145;
-      }
-      v_4c = abs(-(v90->pFacePlane_old.dist
-                 + v92
-                 + pOut.y * v90->pFacePlane_old.vNormal.y
-                 + pOut.x * v90->pFacePlane_old.vNormal.x)) >> 14;
-      if ( v_4c <= abs(v91) )
-      {
-        LODWORD(v94) = v93 << 16;
-        HIDWORD(v94) = v93 >> 16;
-        v95 = v94 / vc;
-        vd = v94 / vc;
-        if ( v95 >= 0 )
-        {
-          if ( sub_4075DB(
-                 pOut.x + ((signed int)(((unsigned __int64)(vd * (signed __int64)v144) >> 16) + 32768) >> 16),
-                 pOut.y + ((signed int)(((unsigned __int64)(vd * (signed __int64)v148) >> 16) + 32768) >> 16),
-                 outz + ((signed int)(((unsigned __int64)(vd * (signed __int64)v152) >> 16) + 32768) >> 16),
-                 v90) )
-          {
-            v113 = 1;
-            goto LABEL_148;
-          }
-        }
-      }
-      v89 = v112;
-LABEL_145:
-      v88 = pIndoor->pSectors;
-      ++v162;
-      if ( v162 >= *(__int16 *)((char *)&pIndoor->pSectors->uNumWalls + v89)
-                 + 2 * *(__int16 *)((char *)&pIndoor->pSectors->uNumFloors + v89) )
-        goto LABEL_148;
-    }
-  }
-  Vec3_int_::Rotate(32, stru_5C6E00->uIntegerHalfPi + v4, 0, v97, &pOut.x, &pOut.y, &outz);
-  v5.z = v.z;
-  *(_QWORD *)&v5.x = *(_QWORD *)&v;
-  Vec3_int_::Rotate(32, stru_5C6E00->uIntegerHalfPi + v4, 0, v5, &outx, &outy, &v163);
-  v6 = outy - pOut.y;
-  v7 = v163 - outz;
-  v8 = outx - pOut.x;
-  v9 = integer_sqrt(v8 * v8 + v6 * v6 + v7 * v7);
-  v10 = 65536;
-  if ( v9 )
-    v10 = 65536 / v9;
-  v125 = v8 * v10;
-  v11 = v10;
-  v12 = v7 * v10;
-  v13 = pOut.x;
-  v117 = v12;
-  v121 = v6 * v11;
-  v149 = pOut.x;
-  if ( pOut.x < outx )
-  {
-    v145 = outx;
-  }
-  else
-  {
-    v149 = outx;
-    v145 = pOut.x;
-  }
-  v14 = outy;
-  v141 = pOut.y;
-  if ( pOut.y < outy )
-  {
-    v137 = outy;
-  }
-  else
-  {
-    v141 = outy;
-    v137 = pOut.y;
-  }
-  v133 = outz;
-  if ( outz < v163 )
-  {
-    v129 = v163;
-  }
-  else
-  {
-    v133 = v163;
-    v129 = outz;
-  }
-  v160 = 0;
-  if ( (signed int)pOutdoor->uNumBModels > 0 )
-  {
-    v104 = 0;
-    while ( 1 )
-    {
-      v15 = (char *)&pOutdoor->pBModels[v104].pVertices;
-      a5 = (char *)&pOutdoor->pBModels[v104].pVertices;
-      if ( sub_4088E9(v13, pOut.y, outx, v14, pOutdoor->pBModels[v104].vPosition.x, pOutdoor->pBModels[v104].vPosition.y) <= pOutdoor->pBModels[v104].sBoundingRadius + 128 )
-      {
-        sDepth = 0;
-        if ( *((int *)v15 + 2) > 0 )
-          break;
-      }
-LABEL_36:
-      ++v160;
-      ++v104;
-      if ( v160 >= (signed int)pOutdoor->uNumBModels )
-        goto LABEL_37;
-      v14 = outy;
-      v13 = pOut.x;
-    }
-    v106 = 0;
-    while ( 1 )
-    {
-      v16 = (ODMFace *)(v106 + *((int *)a5 + 4));
-      if ( v149 > v16->pBoundingBox.x2
-        || v145 < v16->pBoundingBox.x1
-        || v141 > v16->pBoundingBox.y2
-        || v137 < v16->pBoundingBox.y1
-        || v133 > v16->pBoundingBox.z2
-        || v129 < v16->pBoundingBox.z1
-        || (v17 = (unsigned __int64)(v125 * (signed __int64)v16->pFacePlane.vNormal.x) >> 16,
-            v18 = (unsigned __int64)(v121 * (signed __int64)v16->pFacePlane.vNormal.y) >> 16,
-            v19 = (unsigned __int64)(v117 * (signed __int64)v16->pFacePlane.vNormal.z) >> 16,
-            v20 = v17 + v18 + v19 == 0,
-            v21 = v17 + v18 + v19,
-            v109 = v17 + v18 + v19,
-            v20) )
-        goto LABEL_33;
-      v22 = pOut.y * v16->pFacePlane.vNormal.y;
-      v23 = -(v16->pFacePlane.dist + v22 + outz * v16->pFacePlane.vNormal.z + pOut.x * v16->pFacePlane.vNormal.x);
-      if ( v21 <= 0 )
-      {
-        if ( v16->pFacePlane.dist + v22 + outz * v16->pFacePlane.vNormal.z + pOut.x * v16->pFacePlane.vNormal.x < 0 )
-          goto LABEL_33;
-      }
-      else
-      {
-        if ( v16->pFacePlane.dist + v22 + outz * v16->pFacePlane.vNormal.z + pOut.x * v16->pFacePlane.vNormal.x > 0 )
-          goto LABEL_33;
-      }
-      v24 = abs(-(v16->pFacePlane.dist + v22 + outz * v16->pFacePlane.vNormal.z + pOut.x * v16->pFacePlane.vNormal.x)) >> 14;
-      if ( v24 <= abs(v21) )
-      {
-        LODWORD(v25) = v23 << 16;
-        HIDWORD(v25) = v23 >> 16;
-        v26 = v25 / v109;
-        v110 = v25 / v109;
-        if ( v26 >= 0 )
-        {
-          if ( sub_4077F1(
-                 pOut.x + ((signed int)(((unsigned __int64)(v110 * (signed __int64)v125) >> 16) + 32768) >> 16),
-                 pOut.y + ((signed int)(((unsigned __int64)(v110 * (signed __int64)v121) >> 16) + 32768) >> 16),
-                 outz + ((signed int)(((unsigned __int64)(v110 * (signed __int64)v117) >> 16) + 32768) >> 16),
-                 v16,
-                 (BSPVertexBuffer *)a5) )
-          {
-            v114 = 1;
-            goto LABEL_36;
-          }
-        }
-      }
-LABEL_33:
-      ++sDepth;
-      v106 += 308;
-      if ( sDepth >= *((int *)a5 + 2) )
-        goto LABEL_36;
-    }
-  }
-LABEL_37:
-  v27.z = y;
-  *(_QWORD *)&v27.x = a4;
-  Vec3_int_::Rotate(32, a4_8 - stru_5C6E00->uIntegerHalfPi, 0, v27, &pOut.x, &pOut.y, &outz);
-  v28.z = v.z;
-  *(_QWORD *)&v28.x = *(_QWORD *)&v;
-  Vec3_int_::Rotate(32, a4_8 - stru_5C6E00->uIntegerHalfPi, 0, v28, &outx, &outy, &v163);
-  v29 = outy - pOut.y;
-  v30 = v163 - outz;
-  v31 = outx - pOut.x;
-  v32 = integer_sqrt(v31 * v31 + v29 * v29 + v30 * v30);
-  v33 = 65536;
-  if ( v32 )
-    v33 = 65536 / v32;
-  v126 = v31 * v33;
-  v34 = v33;
-  v35 = v30 * v33;
-  v36 = pOut.x;
-  v118 = v35;
-  v122 = v29 * v34;
-  v150 = pOut.x;
-  if ( pOut.x < outx )
-  {
-    v146 = outx;
-  }
-  else
-  {
-    v150 = outx;
-    v146 = pOut.x;
-  }
-  v37 = outy;
-  v142 = pOut.y;
-  if ( pOut.y < outy )
-  {
-    v138 = outy;
-  }
-  else
-  {
-    v142 = outy;
-    v138 = pOut.y;
-  }
-  v134 = outz;
-  if ( outz < v163 )
-  {
-    v130 = v163;
-  }
-  else
-  {
-    v134 = v163;
-    v130 = outz;
-  }
-  v161 = 0;
-  if ( (signed int)pOutdoor->uNumBModels > 0 )
-  {
-    v105 = 0;
-    while ( 1 )
-    {
-      v38 = (char *)&pOutdoor->pBModels[v105].pVertices;
-      a5a = (char *)&pOutdoor->pBModels[v105].pVertices;
-      if ( sub_4088E9(v36, pOut.y, outx, v37, pOutdoor->pBModels[v105].vPosition.x, pOutdoor->pBModels[v105].vPosition.y) <= pOutdoor->pBModels[v105].sBoundingRadius + 128 )
-      {
-        sDeptha = 0;
-        if ( *((int *)v38 + 2) > 0 )
-          break;
-      }
-LABEL_71:
-      ++v161;
-      ++v105;
-      if ( v161 >= (signed int)pOutdoor->uNumBModels )
-        return !v114 || !v113;
-      v37 = outy;
-      v36 = pOut.x;
-    }
-    v_8 = 0;
-    while ( 1 )
-    {
-      v39 = (ODMFace *)(v_8 + *((int *)a5a + 4));
-      if ( v150 > v39->pBoundingBox.x2
-        || v146 < v39->pBoundingBox.x1
-        || v142 > v39->pBoundingBox.y2
-        || v138 < v39->pBoundingBox.y1
-        || v134 > v39->pBoundingBox.z2
-        || v130 < v39->pBoundingBox.z1
-        || (ya = (unsigned __int64)(v126 * (signed __int64)v39->pFacePlane.vNormal.x) >> 16,
-            ve = (unsigned __int64)(v122 * (signed __int64)v39->pFacePlane.vNormal.y) >> 16,
-            v_4 = (unsigned __int64)(v118 * (signed __int64)v39->pFacePlane.vNormal.z) >> 16,
-            v20 = ya + ve + v_4 == 0,
-            v40 = ya + ve + v_4,
-            va = ya + ve + v_4,
-            v20) )
-        goto LABEL_68;
-      v41 = pOut.y * v39->pFacePlane.vNormal.y;
-      v42 = -(v39->pFacePlane.dist + v41 + outz * v39->pFacePlane.vNormal.z + pOut.x * v39->pFacePlane.vNormal.x);
-      if ( v40 <= 0 )
-      {
-        if ( v39->pFacePlane.dist + v41 + outz * v39->pFacePlane.vNormal.z + pOut.x * v39->pFacePlane.vNormal.x < 0 )
-          goto LABEL_68;
-      }
-      else
-      {
-        if ( v39->pFacePlane.dist + v41 + outz * v39->pFacePlane.vNormal.z + pOut.x * v39->pFacePlane.vNormal.x > 0 )
-          goto LABEL_68;
-      }
-      v_4a = abs(-(v39->pFacePlane.dist + v41 + outz * v39->pFacePlane.vNormal.z + pOut.x * v39->pFacePlane.vNormal.x)) >> 14;
-      if ( v_4a <= abs(v40) )
-      {
-        LODWORD(v43) = v42 << 16;
-        HIDWORD(v43) = v42 >> 16;
-        v44 = v43 / va;
-        vb = v43 / va;
-        if ( v44 >= 0 )
-        {
-          if ( sub_4077F1(
-                 pOut.x + ((signed int)(((unsigned __int64)(vb * (signed __int64)v126) >> 16) + 32768) >> 16),
-                 pOut.y + ((signed int)(((unsigned __int64)(vb * (signed __int64)v122) >> 16) + 32768) >> 16),
-                 outz + ((signed int)(((unsigned __int64)(vb * (signed __int64)v118) >> 16) + 32768) >> 16),
-                 v39,
-                 (BSPVertexBuffer *)a5a) )
-          {
-            v113 = 1;
-            goto LABEL_71;
-          }
-        }
-      }
-LABEL_68:
-      ++sDeptha;
-      v_8 += 308;
-      if ( sDeptha >= *((int *)a5a + 2) )
-        goto LABEL_71;
-    }
-  }
-  return !v114 || !v113;
-}
-
-//----- (00408768) --------------------------------------------------------
-void InitializeActors()
-{
-  signed int v5; // [sp+Ch] [bp-10h]@1
-  signed int v6; // [sp+10h] [bp-Ch]@1
-  signed int v7; // [sp+14h] [bp-8h]@1
-  signed int v8; // [sp+18h] [bp-4h]@1
-
-  v8 = 0;
-  v6 = 0;
-  v7 = 0;
-  v5 = 0;
-  if ( !_stricmp(pCurrentMapName.data(), "d25.blv") )
-    v8 = 1;
-  if ( !_stricmp(pCurrentMapName.data(), "d26.blv") )
-    v6 = 1;
-  if (_449B57_test_bit(pParty->_quest_bits, 99))
-    v7 = 1;
-  if (_449B57_test_bit(pParty->_quest_bits, 100))
-    v5 = 1;
-
-  Log::Warning(L"%S %S %u", __FILE__, __FUNCTION__, __LINE__); // ai_near_actors_targets_pid[i] for AI_Stand seems always 0;  original code behaviour is identical
-  for (uint i = 0; i < uNumActors; ++i)
-  {
-    auto actor = &pActors[i];
-
-    if (actor->CanAct() || actor->uAIState == Disabled)
-    {
-      actor->vPosition.x = actor->vInitialPosition.x;
-      actor->vPosition.y = actor->vInitialPosition.y;
-      actor->vPosition.z = actor->vInitialPosition.z;
-      actor->sCurrentHP = actor->pMonsterInfo.uHP;
-      if (actor->uAIState != Disabled)
-      {
-        Actor::AI_Stand(i, ai_near_actors_targets_pid[i], actor->pMonsterInfo.uRecoveryTime, 0);
-      }
-    }
-
-    actor->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly;
-
-    if (!v8 || v7)
-      if (!v6 || v5)
-        if (actor->IsPeasant())
-          BYTE2(actor->uAttributes) &= 0xF7u;
-
-    BYTE2(actor->uAttributes) &= 0x7Fu;
-    if (BYTE2(actor->uAttributes) & 0x40)
-        Actor::_4031C1_update_job(i, pParty->uCurrentHour, 1);
-  }
-}
-
-//----- (00408896) --------------------------------------------------------
-void InitializeSpriteObjects()
-{
-  for (uint i = 0; i < uNumSpriteObjects; ++i)
-  {
-    auto item = &pSpriteObjects[i];
-
-    if (item->uType &&
-        (item->uSoundID & 8 || pObjectList->pObjects[item->uType].uFlags & 0x10))
-      SpriteObject::OnInteraction(i);
-  }
-
-  for (uint i = 0; i < 100; ++i)
-    array_5118E8.pElements[i].field_C_time_left = 0;
-}
-
 //----- (004088E9) --------------------------------------------------------
 signed int __fastcall sub_4088E9(int a1, int a2, int a3, int a4, int a5, int a6)
 {
@@ -8911,151 +6628,6 @@
   return result;
 }
 
-//----- (00408A27) --------------------------------------------------------
-unsigned int __thiscall SearchAliveActors(unsigned int *pTotalActors)
-{
-  unsigned int *v1; // esi@1
-  int v2; // eax@1
-  unsigned int v3; // ebp@1
-  signed int v4; // ebx@1
-  Actor *v5; // edi@2
-  unsigned int v6; // eax@3
-  int v8; // [sp+Ch] [bp-4h]@1
-
-  v1 = pTotalActors;
-  v2 = GetAlertStatus();
-  v3 = 0;
-  v4 = 0;
-  *v1 = 0;
-  v8 = v2;
-  if ( (signed int)uNumActors > 0 )
-  {
-    v5 = pActors.data();
-    do
-    {
-      v6 = v5->uAttributes;
-      if ( (v6 & 0x100000) == v8 )
-      {
-        ++*v1;
-        if ( v5->IsNotAlive() == 1 )
-          ++v3;
-      }
-      ++v4;
-      ++v5;
-    }
-    while ( v4 < (signed int)uNumActors );
-  }
-  return v3;
-}
-
-//----- (00408A7E) --------------------------------------------------------
-unsigned int __fastcall SearchActorByMonsterID(unsigned int *pTotalActors, int uMonsterID)
-{
-  unsigned int *v2; // esi@1
-  signed int v3; // ebx@1
-  Actor *v4; // edi@2
-  int v5; // eax@3
-  int v7; // [sp+8h] [bp-Ch]@1
-  int v8; // [sp+Ch] [bp-8h]@1
-  unsigned int v9; // [sp+10h] [bp-4h]@1
-
-  v7 = uMonsterID;
-  v2 = pTotalActors;
-  v3 = 0;
-  v8 = GetAlertStatus();
-  *v2 = 0;
-  v9 = 0;
-  if ( (signed int)uNumActors > 0 )
-  {
-    v4 = pActors.data();//[0].pMonsterInfo.uID;
-    do
-    {
-	  v5 = v4->uAttributes;                // actor::attributes
-      if ( (v5 & 0x100000) == v8 )
-      {
-		if ( v4->pMonsterInfo.field_33 == v7 )
-        {
-          ++*v2;
-          if ( v4->IsNotAlive() == 1 )
-            ++v9;
-        }
-      }
-      ++v3;
-      ++v4;
-    }
-    while ( v3 < (signed int)uNumActors );
-  }
-  return v9;
-}
-
-//----- (00408AE7) --------------------------------------------------------
-unsigned int __fastcall SearchActorByGroup(unsigned int *pTotalActors, unsigned int uGroup)
-{
-  unsigned int *v2; // esi@1
-  signed int v3; // ebx@1
-  Actor *v4; // edi@2
-  int v5; // eax@3
-  unsigned int v7; // [sp+8h] [bp-Ch]@1
-  int v8; // [sp+Ch] [bp-8h]@1
-  unsigned int v9; // [sp+10h] [bp-4h]@1
-
-  v7 = uGroup;
-  v2 = pTotalActors;
-  v3 = 0;
-  v8 = GetAlertStatus();
-  *v2 = 0;
-  v9 = 0;
-  if ( (signed int)uNumActors > 0 )
-  {
-    v4 = pActors.data();//[0].uGroup;
-    do
-    {
-	  v5 = v4->uAttributes;
-      if ( (v5 & 0x100000) == v8 )
-      {
-		if ( v4->uGroup == v7 )
-        {
-          ++*v2;
-          if ( v4->IsNotAlive() == 1 )
-            ++v9;
-        }
-      }
-      ++v3;
-      ++v4;
-    }
-    while ( v3 < (signed int)uNumActors );
-  }
-  return v9;
-}
-
-//----- (00408B54) --------------------------------------------------------
-unsigned int __fastcall SearchActorByID(unsigned int *pTotalActors, unsigned int a2)
-{
-  unsigned int v2; // edi@1
-  unsigned int *v3; // esi@1
-  int v4; // eax@1
-  unsigned int v5; // ebx@1
-  unsigned int v6; // edx@1
-
-  v2 = a2;
-  v3 = pTotalActors;
-  v4 = GetAlertStatus();
-  v5 = 0;
-  *v3 = 0;
-  v6 = pActors[v2].uAttributes;
-  if ( (v6 & 0x100000) == v4 )
-  {
-    *v3 = 1;
-    if ( pActors[v2].IsNotAlive() == 1 )
-      v5 = 1;
-  }
-  return v5;
-}
-
-
-
-
-
 //----- (0040DEDB) --------------------------------------------------------
 unsigned int __stdcall R8G8B8_to_TargetFormat(int uColor)
 {
@@ -9070,12 +6642,6 @@
                            LOBYTE(pRenderer->uTargetRBits) + LOBYTE(pRenderer->uTargetBBits) - 8));
 }
 
-//----- (0040DF3D) --------------------------------------------------------
-void __cdecl CallRenderPresent()
-{
-  pRenderer->Present();
-}
-
 //----- (0040DFA7) --------------------------------------------------------
 int __stdcall retzero_sub_40DFA7(int a1)
 {
@@ -9185,30 +6751,6 @@
   }
 }
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-//----- (00410AF5) --------------------------------------------------------
-void __cdecl SetMoonPhaseNames()
-{
-  aMoonPhaseNames[0] = pGlobalTXT_LocalizationStrings[150];
-  aMoonPhaseNames[1] = pGlobalTXT_LocalizationStrings[171];
-  aMoonPhaseNames[2] = pGlobalTXT_LocalizationStrings[102];
-  aMoonPhaseNames[3] = pGlobalTXT_LocalizationStrings[169];
-  aMoonPhaseNames[4] = pGlobalTXT_LocalizationStrings[92];
-}
-
-
 //----- (00410D99) --------------------------------------------------------
 signed int __fastcall sub_410D99_get_map_index(int a1)
 {
@@ -9236,720 +6778,14 @@
   return v2;
 }
 
-//----- (00410DEC) --------------------------------------------------------
-unsigned int __cdecl DrawLloydBeaconsScreen()
-{
-  Player *pPlayer; // esi@1
-  char *v1; // eax@1
-  unsigned __int16 v2; // ax@6
-  unsigned int result; // eax@11
-  unsigned int v4; // esi@13
-  unsigned int v5; // ecx@13
-  char v6; // zf@13
-  LloydBeacon *v7; // esi@14
-  int v8; // eax@14
-  unsigned __int64 v9; // kr08_8@14
-  unsigned int v10; // esi@14
-  unsigned int v11; // eax@14
-  char *v12; // eax@19
-  char *v13; // ecx@22
-  int v14; // eax@27
-  Texture *v19; // [sp-4h] [bp-8Ch]@4
-  GUIWindow pWindow; // [sp+Ch] [bp-7Ch]@1
-  unsigned int v23; // [sp+64h] [bp-24h]@14
-  __int64 v24; // [sp+68h] [bp-20h]@14
-  unsigned int v25; // [sp+70h] [bp-18h]@13
-  char *Str; // [sp+74h] [bp-14h]@14
-  int v27; // [sp+78h] [bp-10h]@11
-  LloydBeacon *v28; // [sp+7Ch] [bp-Ch]@12
-  RGBTexture *v29; // [sp+80h] [bp-8h]@12
-  int uNumMaxBeacons; // [sp+84h] [bp-4h]@6
-
-  pPlayer = &pParty->pPlayers[_506348_current_lloyd_playerid];
-  pRenderer->DrawTextureIndexed(8u, 8u, pTexture_LloydBeacons[(unsigned __int8)bRecallingBeacon]);
-  v1 = pGlobalTXT_LocalizationStrings[523];     // Recall Beacon
-  pWindow.uFrameX = game_viewport_x;
-  pWindow.uFrameY = game_viewport_y;
-  pWindow.uFrameWidth = 428;
-  pWindow.uFrameHeight = game_viewport_height;
-  pWindow.uFrameZ = 435;
-  pWindow.uFrameW = game_viewport_w;
-  if ( !bRecallingBeacon )
-    v1 = pGlobalTXT_LocalizationStrings[375];   // Set Beacon
-  sprintf(pTmpBuf.data(), "%s", v1);
-  pWindow.DrawTitleText(pBook2Font, 0, 22u, 0, pTmpBuf.data(), 3u);
-  if ( bRecallingBeacon )
-  {
-    pRenderer->DrawTextureTransparent(pBtn_Book_1->uX, pBtn_Book_1->uY, pTex_tab_an_6b__zoom_on);
-    v19 = pTex_tab_an_6a__zoom_off;
-  }
-  else
-  {
-    pRenderer->DrawTextureTransparent(pBtn_Book_1->uX, pBtn_Book_1->uY, pTex_tab_an_6a__zoom_off);
-    v19 = pTex_tab_an_6b__zoom_on;
-  }
-  pRenderer->DrawTextureTransparent(pBtn_Book_2->uX, pBtn_Book_2->uY, v19);
-  v2 = pPlayer->pActiveSkills[14];
-  uNumMaxBeacons = 1;
-  if ( HIBYTE(v2) & 1 || (v2 & 0x80u) != 0 )
-  {
-    uNumMaxBeacons = 5;
-  }
-  else
-  {
-    if ( v2 & 0x40 )
-      uNumMaxBeacons = 3;
-  }
-  result = 0;
-  v27 = 0;
-  if ( uNumMaxBeacons > 0 )
-  {
-    v29 = pSavegameThumbnails.data();
-    v28 = pPlayer->pInstalledBeacons;
-    while ( 1 )
-    {
-      pWindow.uFrameWidth = 92;
-      v4 = result;
-      pWindow.uFrameHeight = 68;
-      v5 = pLloydsBeaconsPreviewXs[result];
-      pWindow.uFrameY = pLloydsBeaconsPreviewYs[result];
-      v25 = pWindow.uFrameY;
-      pWindow.uFrameX = v5;
-      pWindow.uFrameW = pWindow.uFrameY + 67;
-      v6 = v29->pPixels == 0;
-      pWindow.uFrameZ = v5 + 91;
-      if ( !v6 )
-        break;
-      if ( !bRecallingBeacon )
-      {
-        pRenderer->DrawTextureTransparent(pLloydsBeacons_SomeXs[v4], pLloydsBeacons_SomeYs[v4], pTexture_CurrentBook);
-        v14 = pSpellFont->CalcTextHeight(pGlobalTXT_LocalizationStrings[19], &pWindow, 0, 0);
-        pWindow.DrawTitleText(pSpellFont, 0, (signed int)pWindow.uFrameHeight / 2 - v14 / 2, 1, pGlobalTXT_LocalizationStrings[19], 3);
-      }
-LABEL_29:
-      ++v29;
-      ++v28;
-      result = v27++ + 1;
-      if ( v27 >= uNumMaxBeacons )
-        goto LABEL_30;
-    }
-    pRenderer->DrawTextureTransparent(pLloydsBeacons_SomeXs[v4], pLloydsBeacons_SomeYs[v4], pTexture_CurrentBook);
-    pRenderer->DrawTextureRGB(pLloydsBeaconsPreviewXs[v4], pLloydsBeaconsPreviewYs[v4], v29);
-    v7 = v28;
-    Str = pMapStats->pInfos[sub_410D99_get_map_index(HIWORD(v28->field_18))].pName;
-    v8 = pSpellFont->CalcTextHeight(Str, &pWindow, 0, 0);
-    pWindow.uFrameY += -6 - v8;
-    pWindow.DrawTitleText(pSpellFont, 0, 0, 1u, Str, 3u);
-    v9 = v7->uBeaconTime - pParty->uTimePlayed;
-    LODWORD(v24) = LODWORD(v7->uBeaconTime) - LODWORD(pParty->uTimePlayed);
-    HIDWORD(v24) = HIDWORD(v9);
-    v23 = (unsigned __int64)((signed __int64)((double)v24 * 0.234375) / 60 / 60) >> 32;
-    v10 = (signed __int64)((double)v24 * 0.234375) / 60 / 60;
-    v11 = v10 / 0x18;
-    if ( (unsigned int)((signed __int64)((double)v24 * 0.234375) / 60 / 60) / 0x18 )
-    {
-      v13 = pGlobalTXT_LocalizationStrings[57]; // Days
-      if ( v11 > 1 )
-      {
-        sprintf(pTmpBuf.data(), "%lu %s", v11 + 1, v13);
-        pWindow.uFrameY = v25 + pWindow.uFrameHeight + 4;
-        pWindow.DrawTitleText(pSpellFont, 0, 0, 1, pTmpBuf.data(), 3);
-        goto LABEL_29;
-      }
-    }
-    else
-    {
-      if ( (signed __int64)(__PAIR__(v23, v10) + 1) <= 23 )
-      {
-        if ( (v23 & 0x80000000u) != 0 || (signed int)v23 <= 0 && v10 <= 1 )
-          v12 = pGlobalTXT_LocalizationStrings[109];// Hour
-        else
-          v12 = pGlobalTXT_LocalizationStrings[110];// Hours
-        sprintf(pTmpBuf.data(), "%lu %s", v10 + 1, v12);
-        pWindow.uFrameY = v25 + pWindow.uFrameHeight + 4;
-        pWindow.DrawTitleText(pSpellFont, 0, 0, 1, pTmpBuf.data(), 3);
-        goto LABEL_29;
-      }
-    }
-    v13 = pGlobalTXT_LocalizationStrings[56];   // Day
-    sprintf(pTmpBuf.data(), "%lu %s", v11 + 1, v13);
-    pWindow.uFrameY = v25 + pWindow.uFrameHeight + 4;
-    pWindow.DrawTitleText(pSpellFont, 0, 0, 1, pTmpBuf.data(), 3);
-    goto LABEL_29;
-  }
-LABEL_30:
-  if ( byte_506360 )
-  {
-    /*result = pMessageQueue_50CBD0->uNumMessages;
-    if ( (signed int)pMessageQueue_50CBD0->uNumMessages < 40 )
-    {
-      pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].eType = UIMSG_CloseAfterInstallBeacon;
-      pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = 0;
-      result = 3 * pMessageQueue_50CBD0->uNumMessages + 3;
-      *(&pMessageQueue_50CBD0->uNumMessages + result) = 0;
-      ++pMessageQueue_50CBD0->uNumMessages;
-    }*/
-    pMessageQueue_50CBD0->AddMessage(UIMSG_CloseAfterInstallBeacon, 0, 0);
-  }
-  return result;
-}
-
-
-//----- (00413FF1) --------------------------------------------------------
-void SetMonthNames()
-{
-  aMonthNames[0] = pGlobalTXT_LocalizationStrings[415];
-  aMonthNames[1] = pGlobalTXT_LocalizationStrings[416];
-  aMonthNames[2] = pGlobalTXT_LocalizationStrings[417];
-  aMonthNames[3] = pGlobalTXT_LocalizationStrings[418];
-  aMonthNames[4] = pGlobalTXT_LocalizationStrings[419];
-  aMonthNames[5] = pGlobalTXT_LocalizationStrings[420];
-  aMonthNames[6] = pGlobalTXT_LocalizationStrings[421];
-  aMonthNames[7] = pGlobalTXT_LocalizationStrings[422];
-  aMonthNames[8] = pGlobalTXT_LocalizationStrings[423];
-  aMonthNames[9] = pGlobalTXT_LocalizationStrings[424];
-  aMonthNames[10] = pGlobalTXT_LocalizationStrings[425];
-  aMonthNames[11] = pGlobalTXT_LocalizationStrings[426];
-}
-
-//----- (0041406F) --------------------------------------------------------
-void SetDayNames()
-{
-  aDayNames[0] = pGlobalTXT_LocalizationStrings[145];
-  aDayNames[1] = pGlobalTXT_LocalizationStrings[230];
-  aDayNames[2] = pGlobalTXT_LocalizationStrings[243];
-  aDayNames[3] = pGlobalTXT_LocalizationStrings[227];
-  aDayNames[4] = pGlobalTXT_LocalizationStrings[91];
-  aDayNames[5] = pGlobalTXT_LocalizationStrings[188];
-  aDayNames[6] = pGlobalTXT_LocalizationStrings[222];
-}
-
-//----- (004140BB) --------------------------------------------------------
-void SetSpellSchoolNames()
-{
-  aSpellSchoolNames[0] = pGlobalTXT_LocalizationStrings[87];
-  aSpellSchoolNames[1] = pGlobalTXT_LocalizationStrings[6];
-  aSpellSchoolNames[2] = pGlobalTXT_LocalizationStrings[240];
-  aSpellSchoolNames[3] = pGlobalTXT_LocalizationStrings[70];
-  aSpellSchoolNames[4] = pGlobalTXT_LocalizationStrings[214];
-  aSpellSchoolNames[5] = pGlobalTXT_LocalizationStrings[142];
-  aSpellSchoolNames[6] = pGlobalTXT_LocalizationStrings[29];
-  aSpellSchoolNames[7] = pGlobalTXT_LocalizationStrings[133];
-  aSpellSchoolNames[8] = pGlobalTXT_LocalizationStrings[54];
-}
-
-//----- (0041411B) --------------------------------------------------------
-void SetAttributeNames()
-{
-  aAttributeNames[0] = pGlobalTXT_LocalizationStrings[144];
-  aAttributeNames[1] = pGlobalTXT_LocalizationStrings[116];
-  aAttributeNames[2] = pGlobalTXT_LocalizationStrings[163];
-  aAttributeNames[3] = pGlobalTXT_LocalizationStrings[75];
-  aAttributeNames[4] = pGlobalTXT_LocalizationStrings[1];
-  aAttributeNames[5] = pGlobalTXT_LocalizationStrings[211];
-  aAttributeNames[6] = pGlobalTXT_LocalizationStrings[136];
-}
-
-//----- (00414162) --------------------------------------------------------
-void uGameUIFontMain_initialize()
-{
-  uGameUIFontMain = TargetColor(0xAu, 0, 0);
-}
-
-//----- (00414174) --------------------------------------------------------
-void uGameUIFontShadow_initialize()
-{
-  uGameUIFontShadow = TargetColor(0xE6u, 214u, 193u);
-}
-
-
-
-
-//----- (0041420D) --------------------------------------------------------
-void __cdecl sub_41420D_press_esc()
-{
-  GUIWindow v0; // [sp+4h] [bp-54h]@1
-
-  sprintf(pTmpBuf2.data(), "%s\n \n%s", ptr_507BDC->Hint, pGlobalTXT_LocalizationStrings[61]);// Press Escape
-  v0.Hint = pTmpBuf2.data();
-  v0.uFrameWidth = 400;
-  v0.uFrameHeight = 100;
-  v0.uFrameX = 120;
-  v0.uFrameY = 140;
-  v0.uFrameZ = 519;
-  v0.uFrameW = 239;
-  v0.DrawMessageBox(0);
-}
-
-//----- (0041426F) --------------------------------------------------------
-void __cdecl sub_41426F()
-{
-  GUIWindow *v0; // ecx@1
-
-  v0 = ptr_507BDC;
-  pMessageQueue_50CBD0->AddMessage((UIMessageType)(int)ptr_507BDC->ptr_1C, 0, 0);
-
-  v0->Release();
-  ptr_507BDC = 0;
-  pCurrentScreen = dword_506F0C[0];
-  pEventTimer->Resume();
-}
 // 4E28F8: using guessed type int pCurrentScreen;
 
-
-
 void LoadFonts_and_DrawCopyrightWindow()
 {
   MainMenuUI_LoadFontsAndSomeStuff();
   DrawCopyrightWindow();
 }
 
-//----- (00415485) --------------------------------------------------------
-void DrawCopyrightWindow()
-{
-  GUIWindow Dst; // [sp+8h] [bp-54h]@1
-
-  memset(&Dst, 0, 0x54u);
-  Dst.uFrameWidth = 624;
-  Dst.uFrameHeight = 256;
-  Dst.uFrameX = 8;
-  Dst.uFrameY = 30;                             // c 1999 The 3DO Company.
-  Dst.uFrameHeight = pFontSmallnum->CalcTextHeight(pGlobalTXT_LocalizationStrings[157], &Dst, 24, 0)
-                   + 2 * LOBYTE(pFontSmallnum->uFontHeight)
-                   + 24;
-  Dst.uFrameY = 470 - Dst.uFrameHeight;
-  Dst.uFrameZ = Dst.uFrameX + Dst.uFrameWidth - 1;
-  Dst.uFrameW = 469;
-  //Dst.Hint = "abcagfdsgsg ljsrengvlkjesnfkjwnef";
-  Dst.DrawMessageBox(0);
-
-  Dst.uFrameWidth -= 24;
-  Dst.uFrameX += 12;
-  Dst.uFrameY += 12;
-  Dst.uFrameHeight -= 12;
-  Dst.uFrameZ = Dst.uFrameX + Dst.uFrameWidth - 1;
-  Dst.uFrameW = Dst.uFrameY + Dst.uFrameHeight - 1;
-  Dst.DrawTitleText(pFontSmallnum, 0, 0xCu, ui_mainmenu_copyright_color, pGlobalTXT_LocalizationStrings[157], 3);
-}
-
-
-
-//----- (004156F0) --------------------------------------------------------
-void GUI_UpdateWindows() 
-{
-  GUIWindow *pWindow; // esi@4
-  //unsigned int pWindowType; // eax@4
-  const char *pHint; // edx@66
-  GUIButton *pButtonPtr_1C; // ebp@79
-  char *pHint1; // edx@80
-  int v26; // eax@98
-  unsigned int v27; // ebp@106
-  GUIWindow *pGUIWindow2; // ecx@109
-  GUIFont *pGUIFont; // ST1C_4@115
-  int v31; // eax@115
-  GUIButton *pButton; // ebp@118
-  int v39; // eax@129
-  unsigned int pNumMessages; // eax@142
-  GUIButton *pGUIButton; // ebp@146
-  //unsigned int pX; // [sp-1Ch] [bp-124h]@17
-  //unsigned int pY; // [sp-18h] [bp-120h]@17
-  //Texture *pTexture; // [sp-14h] [bp-11Ch]@17
-  //Texture *pTexture2; // [sp-14h] [bp-11Ch]@86
-  int i; // [sp+0h] [bp-108h]@3
-  ItemGen pItemGen; // [sp+4h] [bp-104h]@98
-  GUIButton GUIButton2; // [sp+28h] [bp-E0h]@133
-  ItemGen ItemGen2; // [sp+E4h] [bp-24h]@129
-
-  if (GetCurrentMenuID() != MENU_CREATEPARTY)
-    UI_OnKeyDown(VK_NEXT);
-
-  for ( i = 1; i <= uNumVisibleWindows; ++i )
-  {
-    pWindow = &pWindowList[pVisibleWindowsIdxs[i] - 1];
-    switch (pWindow->eWindowType)
-    {
-      case WINDOW_OptionsButtons:
-      {
-        pRenderer->DrawTextureIndexed(pViewport->uViewportTL_Y,
-                                      pViewport->uViewportTL_X, pIcons_LOD->GetTexture(uTextureID_Options));
-        viewparams->bRedrawGameUI = 1;
-        continue;
-      }
-      case WINDOW_CharacterRecord:
-      {
-        CharacterUI_CharacterScreen_Draw(pPlayers[uActiveCharacter]);
-        continue;
-      }
-      case WINDOW_Options:
-      {
-        GameMenuUI_Options_Draw();
-        continue;
-      }
-      case WINDOW_Book:
-      {
-        BookUI_Draw((WindowType)(int)pWindow->ptr_1C);
-        continue;
-      }
-      case WINDOW_Dialogue:
-      {
-        GameUI_DrawDialogue();
-        continue;
-      }
-      case WINDOW_QuickReference:
-      {
-        GameUI_QuickRef_Draw();
-        continue;
-      }
-      case WINDOW_Rest:
-      {
-        RestUI_Draw();
-        continue;
-      }
-      case WINDOW_ChangeLocation:
-      {
-        TravelUI_Draw();
-        continue;
-      }
-      case WINDOW_SpellBook:
-      {
-        DrawSpellBookContent(pPlayers[uActiveCharacter]);
-        continue;
-      }
-      case WINDOW_GreetingNPC:
-      {
-        GameUI_DrawBranchlessDialogue();
-        continue;
-      }
-      case WINDOW_Chest:
-      {
-        if ( pCurrentScreen == SCREEN_CHEST )
-        {
-          Chest::DrawChestUI((unsigned int)pWindow->ptr_1C);
-        }
-        else if ( pCurrentScreen == SCREEN_CHEST_INVENTORY )
-        {
-          pRenderer->ClearZBuffer(0, 479);
-          draw_leather();
-          CharacterUI_InventoryTab_Draw(pPlayers[uActiveCharacter], true);
-          pRenderer->DrawTextureIndexed(pBtn_ExitCancel->uX, pBtn_ExitCancel->uY, pIcons_LOD->GetTexture(uExitCancelTextureId));
-        }
-        continue;
-      }
-      case WINDOW_SaveLoadButtons:
-      {
-        SaveUI_Draw();
-        continue;
-      }
-      case WINDOW_MainMenu_Load:
-      {
-        LoadUI_Draw();
-        continue;
-      }
-      case WINDOW_HouseInterior:
-      {
-        pWindowList[pVisibleWindowsIdxs[i] - 1].HouseDialogManager();
-        if ( !window_SpeakInHouse )
-          continue;
-        if ( (signed int)window_SpeakInHouse->ptr_1C >= 53 )
-          continue;
-        if ( pParty->field_3C._shop_ban_times[(signed int)window_SpeakInHouse->ptr_1C] <=pParty->uTimePlayed )
-        {
-          if ( (signed int)window_SpeakInHouse->ptr_1C < 53 )
-          {
-            pParty->field_3C._shop_ban_times[(signed int)window_SpeakInHouse->ptr_1C] = 0;
-          }
-          continue;
-        }
-        pNumMessages = pMessageQueue_50CBD0->uNumMessages;
-        pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 0, 0);
-        continue;
-      }
-      case WINDOW_Transition:
-      {
-        TransitionUI_Draw();
-        continue;
-      }
-      case WINDOW_Scroll:
-      {
-        CreateScrollWindow();
-        continue;
-      }
-      case WINDOW_CastSpell_InInventory:
-      {
-        pRenderer->ClearZBuffer(0, 479);
-        draw_leather();
-        CharacterUI_InventoryTab_Draw(pPlayers[uActiveCharacter], true);
-        CharacterUI_DrawPaperdoll(pPlayers[uActiveCharacter]);
-        pRenderer->DrawTextureTransparent(pBtn_ExitCancel->uX, pBtn_ExitCancel->uY, pIcons_LOD->GetTexture(uTextureID_x_x_u));
-        continue;
-      }
-      case WINDOW_FinalWindow:
-      {
-        sub_41420D_press_esc();
-        continue;
-      }
-      case WINDOW_50:
-      {
-        v27 = TargetColor(255, 255, 255);
-        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);
-          v31 = pFontCreate->GetLineWidth((const char *)pKeyActionMap->pPressedKeysBuffer);
-          ptr_507BD0->DrawFlashingInputCursor(v31 + 30, 40, pFontCreate);
-          continue;
-        }
-        if ( ptr_507BD0->receives_keyboard_input_2 == WINDOW_INPUT_CONFIRMED)
-        {
-          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 = SCREEN_GAME;
-          viewparams->bRedrawGameUI = true;
-          continue;
-        }
-        if ( ptr_507BD0->receives_keyboard_input_2 == WINDOW_INPUT_CANCELLED)
-        {
-          pWindow->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
-          pEventTimer->Resume();
-          ptr_507BD0->Release();
-          continue;
-        }
-      }
-      case WINDOW_59:
-      {
-        pWindow->DrawMessageBox(0);
-        pWindow->DrawText(pFontLucida, 10, 20, 0, "Making item number", 0, 0, 0);
-        pWindow->DrawText(pFontLucida, 10, 40, 0, (const char *)pKeyActionMap->pPressedKeysBuffer, 0, 0, 0);
-        if ( !pKeyActionMap->field_204 )
-        {
-          ItemGen2.Reset();
-          pWindow->Release();
-          pEventTimer->Resume();
-          pCurrentScreen = 0;
-          viewparams->bRedrawGameUI = true;
-          v26 = atoi((const char *)pKeyActionMap->pPressedKeysBuffer);
-          if ( v26 > 0 )
-          {
-            if ( v26 < 800 )
-            {
-              ItemGen2.uAttributes |= 1u;
-              ItemGen2.uItemID = v26;
-              if ( pItemsTable->pItems[v26].uEquipType == 12 )
-              {
-                ItemGen2.uNumCharges = rand() % 6 + pItemsTable->pItems[ItemGen2.uItemID].uDamageMod + 1;
-                ItemGen2.uMaxCharges = LOBYTE(ItemGen2.uNumCharges);
-              }
-              else
-              {
-                if ( v26 >= 221 && v26 < 271 )
-                  ItemGen2.uEnchantmentType = rand() % 10 + 1;
-              }
-              pItemsTable->SetSpecialBonus(&ItemGen2);
-              pParty->SetHoldingItem(&ItemGen2);
-            }
-          }
-        }
-        continue;
-      }
-      case WINDOW_PressedButton2:
-      {
-        if ( pWindow->Hint != (char *)1 )
-          pAudioPlayer->PlaySound((SoundID)75, 0, 0, -1, 0, 0, 0, 0);
-        pButton = (GUIButton *)pWindow->ptr_1C;
-        if ( pButton->uX >= 0 && pButton->uX <= 640 )
-        {
-          if ( pButton->uY >= 0 && pButton->uY <= 480 )
-          {
-            pRenderer->DrawTextureIndexed(pWindow->uFrameX, pWindow->uFrameY, pButton->pTextures[0]);
-            viewparams->bRedrawGameUI = 1;
-            if ( pWindow->Hint )
-            {
-              if ( pWindow->Hint != (char *)1 )
-                pButton->DrawLabel(pWindow->Hint, pFontCreate, 0, 0);
-            }
-            pWindow->Release();
-            continue;
-          }
-        }
-        viewparams->bRedrawGameUI = 1;
-        if ( pWindow->Hint )
-        {
-          if ( pWindow->Hint != (char *)1 )
-            pButton->DrawLabel(pWindow->Hint, pFontCreate, 0, 0);
-        }
-        pWindow->Release();
-        continue;
-      }
-      case WINDOW_CharactersPressedButton:
-      {
-        if ( pWindow->Hint != (char *)1 )
-          pAudioPlayer->PlaySound((SoundID)75, 0, 0, -1, 0, 0, 0, 0);
-        pButton = (GUIButton *)pWindow->ptr_1C;
-        pRenderer->DrawTextureIndexed(pWindow->uFrameX, pWindow->uFrameY, pButton->pTextures[1]);
-        viewparams->bRedrawGameUI = 1;
-        if ( pWindow->Hint )
-        {
-          if ( pWindow->Hint != (char *)1 )
-            pButton->DrawLabel(pWindow->Hint, pFontCreate, 0, 0);
-        }
-        pWindow->Release();
-        continue;
-      }
-      case WINDOW_PressedButton:
-      {
-        if ( pWindow->Hint != (char *)1 )
-          pAudioPlayer->PlaySound((SoundID)75, 0, 0, -1, 0, 0, 0, 0);
-        pButton = (GUIButton *)pWindow->ptr_1C;
-        pRenderer->DrawTextureTransparent(pWindow->uFrameX, pWindow->uFrameY, pButton->pTextures[0]);
-        viewparams->bRedrawGameUI = 1;
-        if ( pWindow->Hint )
-        {
-          if ( pWindow->Hint != (char *)1 )
-            pButton->DrawLabel(pWindow->Hint, pFontCreate, 0, 0);
-        }
-        pWindow->Release();
-        continue;
-      }
-      case WINDOW_5D:
-      {
-        if ( pWindow->Hint != (char *)1 )
-          pAudioPlayer->PlaySound((SoundID)75, 0, 0, -1, 0, 0, 0, 0);
-        pButton = (GUIButton *)pWindow->ptr_1C;
-        pRenderer->DrawTextureTransparent(pWindow->uFrameX, pWindow->uFrameY, pButton->pTextures[1]);
-        viewparams->bRedrawGameUI = 1;
-        pWindow->Release();
-        continue;
-      }
-      case WINDOW_SaveLoadBtn:
-      {
-        if (pWindow->Hint != (char *)1)
-          pAudioPlayer->PlaySound(SOUND_Button2, 0, 0, -1, 0, 0, 0, 0);
-        pButton = (GUIButton *)pWindow->ptr_1C;
-        pRenderer->DrawTextureIndexed(pWindow->uFrameX, pWindow->uFrameY, pButton->pTextures[0]);
-        pHint = pWindow->Hint;
-        viewparams->bRedrawGameUI = 1;
-        if ( pHint && pHint != (char *)1 )
-          pButton->DrawLabel(pHint, pFontCreate, 0, 0);
-        pWindow->Release();
-        if (pCurrentScreen == SCREEN_SAVEGAME)
-          pMessageQueue_50CBD0->AddMessage(UIMSG_SaveGame, 0, 0);
-        else
-          pMessageQueue_50CBD0->AddMessage(UIMSG_LoadGame, 0, 0);
-        continue;
-      }
-      case WINDOW_LoadGame_CancelBtn:
-      {
-        if ( pWindow->Hint != (char *)1 )
-          pAudioPlayer->PlaySound((SoundID)75, 0, 0, -1, 0, 0, 0, 0);
-        pButton = (GUIButton *)pWindow->ptr_1C;
-        pRenderer->DrawTextureTransparent(pWindow->uFrameX, pWindow->uFrameY, pButton->pTextures[0]);
-        viewparams->bRedrawGameUI = 1;
-        if ( pWindow->Hint && pWindow->Hint != (char *)1 )
-          pButton->DrawLabel(pWindow->Hint, pFontCreate, 0, 0);
-        pWindow->Release();
-        pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 0, 0);
-        continue;
-      }
-      case WINDOW_CloseRestWindowBtn:
-      {
-        if ( pWindow->Hint != (char *)1 )
-          pAudioPlayer->PlaySound(SOUND_Button2, 0, 0, -1, 0, 0, 0, 0);
-        pGUIButton = (GUIButton *)pWindow->ptr_1C;
-        pRenderer->DrawTextureIndexed(pWindow->uFrameX, pWindow->uFrameY, pGUIButton->pTextures[0]);
-        pHint = pWindow->Hint;
-        viewparams->bRedrawGameUI = 1;
-        if ( pHint && pHint != (char *)1 )
-          pGUIButton->DrawLabel(pHint, pFontCreate, 0, 0);
-        pWindow->Release();
-        pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 0, 0);
-        continue;
-      }
-      case WINDOW_ExitCharacterWindow:
-      {
-        if ( pWindow->Hint != (char *)1 )
-          pAudioPlayer->PlaySound(SOUND_Button2, 0, 0, -1, 0, 0, 0, 0);
-        pButton = (GUIButton *)pWindow->ptr_1C;
-        pRenderer->DrawTextureIndexed(pWindow->uFrameX, pWindow->uFrameY, pButton->pTextures[1]);
-        pHint = pWindow->Hint;
-        viewparams->bRedrawGameUI = 1;
-        if ( pHint && pHint != (char *)1 )
-          pButton->DrawLabel(pHint, pFontCreate, 0, 0);
-        pWindow->Release();
-        pNumMessages = pMessageQueue_50CBD0->uNumMessages;
-        pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 0, 0);
-        continue;
-      }
-      case WINDOW_RestWindow:
-      {
-        memset(&GUIButton2, 0, 0xBCu);
-        GUIButton2.uZ = 197;
-        GUIButton2.uW = 197;
-        GUIButton2.uX = 27;
-        GUIButton2.uY = 161;
-        GUIButton2.uWidth = 171;
-        GUIButton2.uHeight = 37;
-        GUIButton2.pParent = pButton_RestUI_WaitUntilDawn->pParent;
-        pAudioPlayer->PlaySound(SOUND_Button2, 0, 0, -1, 0, 0, 0, 0);
-        pRenderer->DrawTextureIndexed(pWindow->uFrameX, pWindow->uFrameY, *((Texture **)pWindow->ptr_1C + 15));
-        viewparams->bRedrawGameUI = 1;
-        GUIButton2.DrawLabel(pGlobalTXT_LocalizationStrings[183], pFontCreate, 0, 0);//   8 
-        GUIButton2.pParent = 0;
-        pGUIWindow2 = pWindow;
-        pGUIWindow2->Release();
-        continue;
-      }
-      case WINDOW_BooksWindow:
-      {
-        pButton = (GUIButton *)pWindow->ptr_1C;
-        pRenderer->DrawTextureIndexed(pWindow->uFrameY,
-                                      pWindow->uFrameX, pButton->pTextures[0]);
-        viewparams->bRedrawGameUI = true;
-        continue;
-      }
-      case WINDOW_CharacterWindow_Inventory:
-      {
-        pWindow->DrawMessageBox(0);
-        pWindow->DrawText(pFontLucida, 10, 20, 0, "Making item number", 0, 0, 0);
-        pWindow->DrawText(pFontLucida, 10, 40, 0, (const char *)pKeyActionMap->pPressedKeysBuffer, 0, 0, 0);
-        if ( !pKeyActionMap->field_204 )
-        {
-          ItemGen2.Reset();
-          pWindow->Release();
-          pEventTimer->Resume();
-          pCurrentScreen = SCREEN_GAME;
-          viewparams->bRedrawGameUI = 1;
-          v39 = atoi((const char *)pKeyActionMap->pPressedKeysBuffer);
-          if ( v39 > 0 )
-          {
-            if ( v39 < 800 )
-              SpawnActor(v39);
-          }
-        }
-        continue;
-      }
-      case WINDOW_KeyMappingOptions:
-      {
-        GameMenuUI_DrawKeyBindings();
-        continue;
-      }
-      case WINDOW_VideoOptions:
-      {
-        GameMenuUI_DrawVideoOptions();
-        continue;
-      }
-      default:
-      {
-        continue;
-      }
-    }
-  }
-  if ( GetCurrentMenuID() == -1 )
-    GameUI_DrawFoodAndGold();
-  if ( sub_4637E0_is_there_popup_onscreen() )
-    sub_416D62_ShowPopupWindow_MonsterRecord_ItemInfo_etcsub_416D62(0);
-}
 
 //----- (00416196) --------------------------------------------------------
 void identify_item()
@@ -10377,245 +7213,6 @@
   }
 }
 
-
-
-
-
-//----- (004175C0) --------------------------------------------------------
-void UI_OnMouseLeftClick(int *pXY)
-{
-  int *pXY_; // esi@1
-  signed int y; // eax@7
-  signed int x; // ecx@7
-  unsigned int v4; // eax@11
-  signed int v5; // eax@17
-  signed int v6; // esi@19
-  int v7; // esi@30
-  GUIWindow *v8; // edx@31
-  GUIButton *i; // esi@37
-  signed int v10; // eax@50
-  int v11; // ecx@52
-  unsigned int pX; // [sp+14h] [bp-8h]@7
-  unsigned int pY; // [sp+18h] [bp-4h]@7
-
-  pXY_ = pXY;
-  if ( pCurrentScreen == SCREEN_VIDEO
-    || sub_4637E0_is_there_popup_onscreen() )
-    return;
-  if ( pGUIWindow2 && pGUIWindow2->ptr_1C == (void *)33 )
-  {
-    sub_4452BB();
-    return;
-  }
-  if ( pXY_ )
-  {
-    x = *pXY_;
-    y = pXY_[1];
-    pX = *pXY_;
-    pY = y;
-  }
-  else
-  {
-    pMouse->GetClickPos(&pX, &pY);
-    y = pY;
-    x = pX;
-  }
-  if ( pCurrentScreen != SCREEN_GAME || !dword_507B98_ctrl_pressed )
-    goto LABEL_30;
-  v4 = GetCurrentMenuID();
-  x = pX;
-  if ( (v4 & 0x80000000u) == 0
-    || (signed int)pX < (signed int)pViewport->uViewportTL_X
-    || (signed int)pX > (signed int)pViewport->uViewportBR_X )
-  {
-    y = pY;
-LABEL_30:
-    v7 = uNumVisibleWindows;
-    if ( uNumVisibleWindows < 0 )
-      return;
-    while ( 1 )
-    {
-      //v8 = (GUIWindow *)&pWindowList_at_506F50_minus1_indexing[21 * pVisibleWindowsIdxs[v7]];
-      v8 = &pWindowList[pVisibleWindowsIdxs[v7] - 1];
-      if ( x >= (signed int)v8->uFrameX )
-      {
-        if ( x <= (signed int)v8->uFrameZ && y >= (signed int)v8->uFrameY && y <= (signed int)v8->uFrameW )
-          break;
-      }
-      --v7;
-      if ( v7 < 0 )
-        return;
-    }
-    for ( i = v8->pControlsHead; ; i = i->pNext )
-    {
-      if ( !i )
-        return;
-      if ( i->uButtonType == 1 )
-        goto LABEL_41;
-      if ( i->uButtonType != 2 )
-        break;
-      if ( (signed int)(signed __int64)sqrt((double)((x - i->uX) * (x - i->uX) + (y - i->uY) * (y - i->uY))) < (signed int)i->uWidth )
-        goto LABEL_50;
-      y = pY;
-      x = pX;
-LABEL_45:
-      ;
-    }
-    if ( i->uButtonType != 3 )
-      goto LABEL_45;
-LABEL_41:
-    if ( x >= (signed int)i->uX && x <= (signed int)i->uZ && y >= (signed int)i->uY && y <= (signed int)i->uW )
-    {
-LABEL_50:
-      i->field_2C_is_pushed = 1;
-      v10 = pMessageQueue_50CBD0->uNumMessages;
-      if ( pMessageQueue_50CBD0->uNumMessages )
-      {
-        v10 = pMessageQueue_50CBD0->pMessages[0].field_8 != 0;
-        pMessageQueue_50CBD0->uNumMessages = pMessageQueue_50CBD0->pMessages[0].field_8 != 0;
-      }
-      //v11 = i->uControlParam;
-      pMessageQueue_50CBD0->AddMessage(i->msg, i->msg_param, 0);
-      return;
-    }
-    goto LABEL_45;
-  }
-  y = pY;
-  if ( (signed int)pY < (signed int)pViewport->uViewportTL_Y || (signed int)pY > (signed int)pViewport->uViewportBR_Y )
-    goto LABEL_30;
-  if ( pRenderer->pRenderD3D )
-    v5 = pGame->pVisInstance->get_picked_object_zbuf_val();
-  else
-    v5 = pRenderer->pActiveZBuffer[pX + pSRZBufferLineOffsets[pY]];
-  v6 = (unsigned __int16)v5;
-  if (PID_TYPE(v5) == OBJECT_Actor
-    && uActiveCharacter
-    && v5 < 0x2000000
-    && pPlayers[uActiveCharacter]->CanAct()
-    && pPlayers[uActiveCharacter]->CanSteal() )
-  {
-    /*if ( (signed int)pMessageQueue_50CBD0->uNumMessages < 40 )
-    {
-      pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].eType = UIMSG_1B;
-      pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = v6 >> 3;
-      *(&pMessageQueue_50CBD0->uNumMessages + 3 * pMessageQueue_50CBD0->uNumMessages + 3) = 0;
-      ++pMessageQueue_50CBD0->uNumMessages;
-    }*/
-    pMessageQueue_50CBD0->AddMessage(UIMSG_1B, PID_ID(v6), 0);
-
-    if ( pParty->bTurnBasedModeOn == 1 )
-    {
-      if ( pTurnEngine->field_4 == 3 )
-        pTurnEngine->field_18 |= 8u;
-    }
-  }
-}
-
-
-
-//----- (00417871) --------------------------------------------------------
-void __thiscall sub_417871(int *pXY)
-{
-  POINT v1; // [sp+0h] [bp-18h]@5
-  POINT a2; // [sp+8h] [bp-10h]@5
-  unsigned int pY; // [sp+10h] [bp-8h]@3
-  unsigned int pX; // [sp+14h] [bp-4h]@3
-
-  if ( !pRenderer->pRenderD3D )
-  {
-    if ( pXY )
-    {
-      pX = *pXY;
-      pY = pXY[1];
-    }
-    else
-    {
-      pMouse->GetClickPos(&pX, &pY);
-    }
-    pMouse->GetCursorPos(&a2);
-    pMouse->GetCursorPos(&v1);
-  }
-}
-
-//----- (004178FE) --------------------------------------------------------
-unsigned int __fastcall UI_GetHealthManaStringColor(signed int a1, signed int a2)
-{
-  unsigned __int16 v2; // dx@2
-  unsigned __int16 v3; // cx@2
-  int v5; // eax@5
-  unsigned __int16 v6; // [sp-4h] [bp-8h]@2
-
-  if ( a1 <= a2 )
-  {
-    if ( a1 == a2 )
-      return 0;
-    v5 = 100 * a1 / a2;
-    v3 = 255;
-    if ( v5 >= 25 )
-    {
-      v6 = 100;
-      v2 = 255;
-    }
-    else
-    {
-      v6 = 0;
-      v2 = 0;
-    }
-  }
-  else
-  {
-    v6 = 0;
-    v2 = 255;
-    v3 = 0;
-  }
-  return TargetColor(v3, v2, v6);
-}
-
-//----- (00417939) --------------------------------------------------------
-signed int __thiscall GetConditionDrawColor(unsigned int uConditionIdx)
-{
-  unsigned int v1; // ebx@1
-  signed int v2; // edi@1
-  unsigned int v3; // esi@1
-  unsigned int v4; // eax@1
-  unsigned int v6; // [sp+Ch] [bp-4h]@1
-
-  v1 = uConditionIdx;
-  v2 = 65535;
-  v3 = TargetColor(0xE1u, 0xCDu, 0x23u);
-  v6 = TargetColor(0xFFu, 0x23u, 0);
-  v4 = TargetColor(0, 0xFFu, 0);
-  switch ( v1 )
-  {
-    case 0u:
-    case 1u:
-    case 3u:
-    case 4u:
-    case 5u:
-    case 6u:
-    case 7u:
-      v2 = v4;
-      break;
-    case 2u:
-    case 8u:
-    case 9u:
-    case 0xCu:
-    case 0xDu:
-      v2 = v3;
-      break;
-    case 0xAu:
-    case 0xBu:
-    case 0xEu:
-    case 0xFu:
-    case 0x10u:
-      v2 = v6;
-      break;
-    default:
-      return v2;
-  }
-  return v2;
-}
-
 //----- (004179BC) --------------------------------------------------------
 void __fastcall sub_4179BC_draw_tooltip( const char *a1, const char *a2 )
     {
@@ -10691,74 +7288,4 @@
       return red;
   }
   return white;
-}
-
-
-//----- (00419220) --------------------------------------------------------
-void __cdecl sub_419220()
-{
-  GUIButton *i; // eax@2
-
-  if ( !dword_507CBC )
-  {
-    dword_507CBC = 1;
-    for ( i = pGUIWindow_CurrentMenu->pControlsHead; i; i = i->pNext )
-    {
-      if ( i->msg == UIMSG_InventoryLeftClick )
-      {
-        dword_50698C_uX = i->uX;
-        dword_506988_uY = i->uY;
-        dword_506984_uZ = i->uZ;
-        dword_506980_uW = i->uW;
-        i->uW = 0;
-        i->uZ = 0;
-        i->uY = 0;
-        i->uX = 0;
-      }
-    }
-    pBtn_Up = pGUIWindow_CurrentMenu->CreateButton(438, 46,
-                   pIcons_LOD->GetTexture(uTextureID_ar_up_up)->uTextureWidth,
-                   pIcons_LOD->GetTexture(uTextureID_ar_up_up)->uTextureHeight,
-                   1, 0, UIMSG_ClickAwardsUpBtn, 0, 0, "",
-                   pIcons_LOD->GetTexture(uTextureID_ar_up_up),
-                   pIcons_LOD->GetTexture(uTextureID_ar_up_dn), 0);
-    pBtn_Down = pGUIWindow_CurrentMenu->CreateButton(438, 292,
-                   pIcons_LOD->GetTexture(uTextureID_ar_dn_up)->uTextureWidth,
-                   pIcons_LOD->GetTexture(uTextureID_ar_dn_up)->uTextureHeight,
-                   1, 0, UIMSG_ClickAwardsDownBtn, 0, 0, "",
-                   pIcons_LOD->GetTexture(uTextureID_ar_dn_up),
-                   pIcons_LOD->GetTexture(uTextureID_ar_dn_dn), 0);
-    ptr_507BA4 = pGUIWindow_CurrentMenu->CreateButton(440, 62, 16, 232, 1, 0, UIMSG_ClickAwardScrollBar, 0, 0, "", 0);
-  }
-}
-
-
-
-//----- (00419379) --------------------------------------------------------
-void __cdecl sub_419379()
-{
-  GUIButton *pButton; // esi@2
-
-  if ( dword_507CBC )
-  {
-    dword_507CBC = 0;
-	ptr_507BA4->Release();
-    pBtn_Up->Release();
-    pBtn_Down->Release();
-    pBtn_Down = 0;
-    pBtn_Up = 0;
-    for ( pButton = pGUIWindow_CurrentMenu->pControlsHead; pButton; pButton = pButton->pNext )
-    {
-      if ( pButton->msg == UIMSG_InventoryLeftClick )
-      {
-        pButton->uX = dword_50698C_uX;
-        pButton->uY = dword_506988_uY;
-        pButton->uZ = dword_506984_uZ;
-        pButton->uW = dword_506980_uW;
-        pGUIWindow_CurrentMenu->_41D08F_set_keyboard_control_group(1, 0, 0, 0);
-      }
-    }
-  }
-}
-
-
+}
\ No newline at end of file
--- a/mm7_6.cpp	Sun Jun 23 14:27:32 2013 +0600
+++ b/mm7_6.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -1194,40 +1194,6 @@
 // 50C994: using guessed type int dword_50C994;
 // 50C998: using guessed type int dword_50C998_turnbased_icon_1A;
 
-//----- (004269A2) --------------------------------------------------------
-void __fastcall GivePartyExp(unsigned int pEXPNum)
-{
-  signed int pActivePlayerCount; // ecx@1
-  int pLearningPercent; // eax@13
-
-  pActivePlayerCount = 0;
-  for ( uint i = 0; i < 4; ++i )
-  {
-    if ( !pParty->pPlayers[i].pConditions[13] && !pParty->pPlayers[i].pConditions[14] && !pParty->pPlayers[i].pConditions[15] && !pParty->pPlayers[i].pConditions[16] )
-      pActivePlayerCount ++;
-  }
-  if ( pActivePlayerCount )
-  {
-    pEXPNum = pEXPNum / pActivePlayerCount;
-    for ( uint i = 0; i < 4; ++i )
-    {
-      if ( !pParty->pPlayers[i].pConditions[13] && !pParty->pPlayers[i].pConditions[14] && !pParty->pPlayers[i].pConditions[15] && !pParty->pPlayers[i].pConditions[16] )
-      {
-        if ( pEXPNum )
-        {
-          pLearningPercent = pParty->pPlayers[i].GetLearningPercent();
-          pEXPNum = pEXPNum + pEXPNum * pLearningPercent / 100;
-          pParty->pPlayers[i].uExperience += pEXPNum;
-          if ( pParty->pPlayers[i].uExperience > 4000000000i64 )
-          {
-            pParty->pPlayers[i].uExperience = 0;
-          }
-        }
-      }
-    }
-  }
-}
-
 //----- (00426A5A) --------------------------------------------------------
 void stru319::LootActor(Actor *pActor)
 {
@@ -2024,4563 +1990,6 @@
   return result;
 }
 
-//----- (00427769) --------------------------------------------------------
-bool __fastcall sub_427769_spell(unsigned int uSpellID)
-{
-  bool result; // eax@2
-
-  __debugbreak(); // refactor
-  if ( *(&pSpellDatas[0].field_12 + 20 * uSpellID) & 0xC )
-    result = 1;
-  else
-    result = 0;
-  return result;
-}
-
-//----- (0042777D) --------------------------------------------------------
-void _42777D_CastSpell_UseWand_ShootArrow(int a1, unsigned int uPlayerID, unsigned int a4, __int16 a5, int a6)
-{
-  //bool result; // eax@2
-  //__int16 v6; // bx@4
-  //Player *v7; // eax@4
-  //char v8; // zf@12
-  unsigned __int16 v9; // cx@16
-  unsigned int v10; // eax@18
-  unsigned __int8 v11; // sf@18
-  unsigned __int8 v12; // of@18
-  unsigned __int16 v13; // cx@21
-  unsigned int v14; // eax@23
-  //stru277 *v15; // esi@27
-  //stru277 *v16; // eax@28
-  //GUIWindow *v17; // eax@43
-  //GUIWindow *v18; // [sp-30h] [bp-48h]@44
-  //unsigned int v19; // [sp-2Ch] [bp-44h]@44
-  //unsigned int v20; // [sp-28h] [bp-40h]@44
-  //unsigned int v21; // [sp-24h] [bp-3Ch]@44
-  //unsigned int v22; // [sp-20h] [bp-38h]@44
-  //int v23; // [sp-1Ch] [bp-34h]@44
-  //int v24; // [sp-18h] [bp-30h]@44
-  //unsigned int v25; // [sp-14h] [bp-2Ch]@43
-  //unsigned int v26; // [sp-10h] [bp-28h]@43
-  //unsigned __int8 v27; // [sp-Ch] [bp-24h]@43
-  //char *v28; // [sp-8h] [bp-20h]@43
-  //Texture *v29; // [sp-4h] [bp-1Ch]@43
-  //__int16 a3a; // [sp+10h] [bp-8h]@1
-  //__int16 a2a; // [sp+14h] [bp-4h]@1
-
-  //a3a = uPlayerID;
-  //a2a = a1;
-  
-  //if ( pParty->bTurnBasedModeOn != 1
-  //  || (result = pTurnEngine->field_4, pTurnEngine->field_4 != 1) && pTurnEngine->field_4 != 3 )
-  if (pParty->bTurnBasedModeOn)
-  {
-    if (pTurnEngine->field_4 == 1 || pTurnEngine->field_4 == 3)
-      return;
-  }
-
-
-    //v6 = a5;
-    //v7 = &pParty->pPlayers[uPlayerID];
-  assert(uPlayerID < 4);
-  auto player = &pParty->pPlayers[uPlayerID];
-    if ( !(a5 & 0x10) )
-    {
-      switch ( a1 )
-      {
-        case SPELL_SPIRIT_FATE:
-        case SPELL_BODY_FIRST_AID:
-        case SPELL_DARK_REANIMATE:
-          //HIBYTE(v6) = HIBYTE(a5) | 1;
-          a5 |= 0x0100;
-          break;
-
-        case SPELL_FIRE_FIRE_AURA:
-        case SPELL_WATER_RECHARGE_ITEM:
-        case SPELL_WATER_ENCHANT_ITEM:
-        case SPELL_DARK_VAMPIRIC_WEAPON:
-          //LOBYTE(v6) = a5 | 0x80;
-          a5 |= 0x0080;
-          break;
-
-        case SPELL_FIRE_FIRE_BOLT:
-        case SPELL_FIRE_FIREBALL:
-        case SPELL_FIRE_INCINERATE:
-        case SPELL_AIR_LIGHNING_BOLT:
-        case SPELL_AIR_IMPLOSION:
-        case SPELL_WATER_POISON_SPRAY:
-        case SPELL_WATER_ICE_BOLT:
-        case SPELL_WATER_ACID_BURST:
-        case SPELL_WATER_ICE_BLAST:
-        case SPELL_EARTH_STUN:
-        case SPELL_EARTH_SLOW:
-        case SPELL_EARTH_DEADLY_SWARM:
-        case SPELL_EARTH_BLADES:
-        case SPELL_EARTH_MASS_DISTORTION:
-        case SPELL_SPIRIT_SPIRIT_LASH:
-        case SPELL_MIND_MIND_BLAST:
-        case SPELL_MIND_CHARM:
-        case SPELL_MIND_PSYCHIC_SHOCK:
-        case SPELL_BODY_HARM:
-        case SPELL_BODY_FLYING_FIST:
-        case SPELL_LIGHT_LIGHT_BOLT:
-        case SPELL_LIGHT_DESTROY_UNDEAD:
-        case SPELL_LIGHT_SUNRAY:
-        case SPELL_DARK_TOXIC_CLOUD:
-        case SPELL_DARK_SHRINKING_RAY:
-        case SPELL_DARK_SHARPMETAL:
-        case SPELL_DARK_DRAGON_BREATH:
-          if ( !a6 )
-            a5 |= 0x0008;
-          break;
-        case SPELL_MIND_TELEPATHY:
-        case SPELL_MIND_BERSERK:
-        case SPELL_MIND_ENSLAVE:
-        case SPELL_LIGHT_PARALYZE:
-        case SPELL_DARK_CONTROL_UNDEAD:
-//LABEL_9:
-          //v6 = a5 | 8;
-          a5 |= 0x0008;
-          break;
-
-        case SPELL_EARTH_TELEKINESIS:
-          a5 |= 0x0040;
-          break;
-
-        case SPELL_SPIRIT_BLESS:
-          if (a4 && ~a4 & 0x01C0)
-            //goto LABEL_25;
-          {
-            a5 |= 0x0002;
-            break;
-          }
-          else if ((player->pActiveSkills[PLAYER_SKILL_SPIRIT] & 0x1C0) == 0)
-            //goto LABEL_25;
-          {
-            a5 |= 0x0002;
-            break;
-          }
-          break;
-
-        case SPELL_SPIRIT_PRESERVATION:
-          v9 = a4;
-          if ( !a4 )
-            v9 = player->pActiveSkills[PLAYER_SKILL_SPIRIT];
-          //goto LABEL_18;
-          v10 = SkillToMastery(v9);
-          v12 = __OFSUB__(v10, 3);
-          v11 = ((v10 - 3) & 0x80000000u) != 0;
-          //goto LABEL_24;
-          if ( v11 ^ v12 )
-          {
-            a5 |= 0x0002;
-            break;
-          }
-          break;
-
-        case SPELL_DARK_PAIN_REFLECTION:
-          v9 = a4;
-          if ( !a4 )
-            v9 = player->pActiveSkills[PLAYER_SKILL_DARK];
-//LABEL_18:
-          v10 = SkillToMastery(v9);
-          v12 = __OFSUB__(v10, 3);
-          v11 = ((v10 - 3) & 0x80000000u) != 0;
-          //goto LABEL_24;
-          if ( v11 ^ v12 )
-          {
-            a5 |= 0x0002;
-            break;
-          }
-          break;
-
-        case SPELL_BODY_HAMMERHANDS:
-          v13 = a4;
-          if ( !a4 )
-            v13 = player->pActiveSkills[PLAYER_SKILL_BODY];
-          v14 = SkillToMastery(v13);
-          v12 = __OFSUB__(v14, 4);
-          v11 = ((v14 - 4) & 0x80000000u) != 0;
-//LABEL_24:
-          if ( v11 ^ v12 )
-            //goto LABEL_25;
-          {
-            a5 |= 0x0002;
-            break;
-          }
-          break;
-
-        case SPELL_EARTH_STONE_TO_FLESH:
-        case SPELL_SPIRIT_REMOVE_CURSE:
-        case SPELL_SPIRIT_RAISE_DEAD:
-        case SPELL_SPIRIT_RESSURECTION:
-        case SPELL_MIND_REMOVE_FEAR:
-        case SPELL_MIND_CURE_PARALYSIS:
-        case SPELL_MIND_CURE_INSANITY:
-        case SPELL_BODY_CURE_WEAKNESS:
-        case SPELL_BODY_REGENERATION:
-        case SPELL_BODY_CURE_POISON:
-        case SPELL_BODY_CURE_DISEASE:
-//LABEL_25:
-          //v6 = a5 | 2;
-          a5 |= 0x0002;
-          break;
-
-        case SPELL_DARK_SACRIFICE:
-          //HIBYTE(v6) = HIBYTE(a5) | 2;
-          a5 |= 0x0200;
-          break;
-        default:
-          break;
-      }
-    }
-
-
-    if (a5 & 0x3CA)
-    {
-      assert(sizeof(pCastSpellInfo) / sizeof(*pCastSpellInfo.data()) == 10);
-      for (uint i = 0; i < 10; ++i)
-        if (pCastSpellInfo[i].field_8 & 0x3CA)
-        {
-          pCastSpellInfo[i].spellnum = 0;
-          break;
-        }
-    }
-      
-    assert(sizeof(pCastSpellInfo) / sizeof(*pCastSpellInfo.data()) == 10);
-    for (uint i = 0; i < 10; ++i)
-    {
-      auto spell = &pCastSpellInfo[i];
-      if (!spell->spellnum)
-        continue;
-
-      spell->spellnum = 0;
-      if (spell->field_8 & 0x3CA)
-      {
-        pGUIWindow_Settings->Release();
-        pGUIWindow_Settings = nullptr;
-        pMouse->SetCursorBitmap("MICON1");
-        GameUI_Footer_TimeLeft = 0;
-        unk_50C9A0 = 0;
-        back_to_game();
-      }
-    }
-
-    int result = pCastSpellInfo.data()->PushCastSpellInfo(a1, uPlayerID, a4, a5, a6);
-    if ( result != -1 )
-    {
-      if ( a5 & 2 )
-      {
-        if ( pGUIWindow_Settings )
-          return;
-        pGUIWindow_Settings = GUIWindow::Create(0, 0, 640, 480, WINDOW_CastSpell, (int)&pCastSpellInfo[result], 0);
-        pGUIWindow_Settings->CreateButton(52, 422, 35, 0, 2, 0, UIMSG_CastSpell_Character_Big_Improvement, 0, 49, "", 0);
-        pGUIWindow_Settings->CreateButton(165, 422, 35, 0, 2, 0, UIMSG_CastSpell_Character_Big_Improvement, 1, 50, "", 0);
-        pGUIWindow_Settings->CreateButton(280, 422, 35, 0, 2, 0, UIMSG_CastSpell_Character_Big_Improvement, 2, 51, "", 0);
-        pGUIWindow_Settings->CreateButton(390, 422, 35, 0, 2, 0, UIMSG_CastSpell_Character_Big_Improvement, 3, 52, "", 0);
-        sub_421B2C_PlaceInInventory_or_DropPickedItem();
-        return;
-      }
-      if ( a5 & 8 )
-      {
-        if ( pGUIWindow_Settings )
-          return;
-
-        pGUIWindow_Settings = GUIWindow::Create(0, 0, 640, 480, WINDOW_CastSpell, (int)&pCastSpellInfo[result], 0);
-        pGUIWindow_Settings->CreateButton(game_viewport_x, game_viewport_y, game_viewport_width, game_viewport_height, 1, 0, UIMSG_CastSpell_Shoot_Monster, 0, 0, "", 0);
-        sub_421B2C_PlaceInInventory_or_DropPickedItem();
-        return;
-      }
-      if ( a5 & 0x40 )
-      {
-        if ( pGUIWindow_Settings )
-          return;
-
-        pGUIWindow_Settings = GUIWindow::Create(0, 0, 640, 480, WINDOW_CastSpell, (int)&pCastSpellInfo[result], 0);
-        pGUIWindow_Settings->CreateButton(game_viewport_x, game_viewport_y, game_viewport_width, game_viewport_height, 1, 0, UIMSG_CastSpell_BE, 0, 0, "", 0);
-        sub_421B2C_PlaceInInventory_or_DropPickedItem();
-        return;
-      }
-      if ( (char)a5 < 0 )
-      {
-        if ( pGUIWindow_Settings )
-          return;
-        ++pIcons_LOD->uTexturePacksCount;
-        if ( !pIcons_LOD->uNumPrevLoadedFiles )
-          pIcons_LOD->uNumPrevLoadedFiles = pIcons_LOD->uNumLoadedFiles;
-        pGUIWindow_Settings = pCastSpellInfo[result].sub_4219BE();
-        unk_50C9A0 = 1;
-        some_active_character = uActiveCharacter;
-        sub_421B2C_PlaceInInventory_or_DropPickedItem();
-        return;
-      }
-      if ( HIBYTE(a5) & 1 )
-      {
-        if ( pGUIWindow_Settings )
-          return;
-        pGUIWindow_Settings = GUIWindow::Create(0, 0, 640, 480, WINDOW_CastSpell, (int)&pCastSpellInfo[result], 0);
-        pGUIWindow_Settings->CreateButton(0x34u, 0x1A6u, 0x23u, 0, 2, 0, UIMSG_CastSpell_Character_Small_Improvement, 0, 0x31u, "", 0);
-        pGUIWindow_Settings->CreateButton(0xA5u, 0x1A6u, 0x23u, 0, 2, 0, UIMSG_CastSpell_Character_Small_Improvement, 1, 0x32u, "", 0);
-        pGUIWindow_Settings->CreateButton(0x118u, 0x1A6u, 0x23u, 0, 2, 0, UIMSG_CastSpell_Character_Small_Improvement, 2, 0x33u, "", 0);
-        pGUIWindow_Settings->CreateButton(0x186u, 0x1A6u, 0x23u, 0, 2, 0, UIMSG_CastSpell_Character_Small_Improvement, 3, 0x34u, "", 0);
-        pGUIWindow_Settings->CreateButton(8, 8, game_viewport_width, game_viewport_height, 1, 0, UIMSG_CastSpell_Monster_Improvement, 0, 0, "", NULL);
-        sub_421B2C_PlaceInInventory_or_DropPickedItem();
-      }
-      if ( HIBYTE(a5) & 2 && !pGUIWindow_Settings )
-      {
-        pGUIWindow_Settings = GUIWindow::Create(0, 0, 640, 480, WINDOW_CastSpell, (int)&pCastSpellInfo[result], 0);
-        pBtn_NPCLeft = pGUIWindow_Settings->CreateButton(469, 178,
-                       pIcons_LOD->GetTexture(uTextureID_Btn_NPCLeft)->uTextureWidth,
-                       pIcons_LOD->GetTexture(uTextureID_Btn_NPCLeft)->uTextureHeight,
-                       1, 0, UIMSG_ScrollNPCPanel, 0, 0, "",
-                       pIcons_LOD->GetTexture(uTextureID_Btn_NPCLeft), 0);
-        pBtn_NPCRight = pGUIWindow_Settings->CreateButton(626, 178,
-                       pIcons_LOD->GetTexture(uTextureID_Btn_NPCRight)->uTextureWidth,
-                       pIcons_LOD->GetTexture(uTextureID_Btn_NPCRight)->uTextureHeight,
-                       1, 0, UIMSG_ScrollNPCPanel, 1, 0, "",
-                       pIcons_LOD->GetTexture(uTextureID_Btn_NPCRight), 0);
-        pGUIWindow_Settings->CreateButton(491, 149, 64, 74, 1, 0, UIMSG_HiredNPC_CastSpell, 4, 0x35u, "", 0);
-        pGUIWindow_Settings->CreateButton(561, 149, 64, 74, 1, 0, UIMSG_HiredNPC_CastSpell, 5, 0x36u, "", 0);
-      }
-    }
-}
-
-//----- (00427D48) --------------------------------------------------------
-void CastSpellInfo::_427D48(unsigned int uPlayerID)
-{
-  CastSpellInfo *v2; // esi@1
-  signed int v3; // ebx@1
-
-  v2 = this;
-  v3 = 10;
-  do
-  {
-    if ( v2->spellnum )
-    {
-      if ( v2->field_8 & 0x3CA )
-      {
-        v2->spellnum = 0;
-        pGUIWindow_Settings->Release();
-        pGUIWindow_Settings = 0;
-        pMouse->SetCursorBitmap("MICON1");
-        GameUI_Footer_TimeLeft = 0;
-        unk_50C9A0 = 0;
-        back_to_game();
-      }
-    }
-    ++v2;
-    --v3;
-  }
-  while ( v3 );
-}
-
-//----- (00427DA0) --------------------------------------------------------
-unsigned int CastSpellInfo::PushCastSpellInfo(__int16 a2, __int16 uPlayerID, __int16 skill_level, __int16 a5, int spell_sound_id)
-{
-  unsigned int result; // eax@1
-  CastSpellInfo *v7; // edx@1
-  CastSpellInfo *v8; // ecx@5
-
-  result = 0;
-  v7 = this;
-  while ( v7->spellnum )
-  {
-    ++result;
-    ++v7;
-    if ( (signed int)result >= 10 )
-      goto LABEL_8;
-  }
-  v8 = &this[result];
-  v8->spellnum = a2;
-  v8->uPlayerID = uPlayerID;
-  if ( a5 & 0x10 )
-    v8->uPlayerID_2 = uPlayerID;
-  v8->field_6 = 0;
-  v8->spell_target_pid = 0;
-  v8->field_8 = a5;
-  v8->forced_spell_skill_level = skill_level;
-  v8->sound_id = spell_sound_id;
-LABEL_8:
-  if ( result == 10 )
-    result = -1;
-  return result;
-}
-
-//----- (00427E01) --------------------------------------------------------
-void CastSpellInfo::_427E01_cast_spell()
-{
-  int v2; // edi@1
-  CastSpellInfo *pCastSpell; // ebx@2
-  signed int v6; // eax@14
-  unsigned __int16 v11; // cx@45
-  unsigned __int8 v14; // zf@53
-  signed int i; // esi@76
-  __int16 v23; // ax@88
-  int v51; // eax@146
-  __int16 v52; // ax@153
-  signed __int64 v54; // qax@164
-  Actor *v55; // edi@164
-  signed __int64 v58; // qax@177
-  Actor *pActor; // edi@177
-  unsigned __int16 v60; // ax@184
-  int v61; // ecx@184
-  ItemGen *v69; // esi@211
-  double v90; // st7@245
-  Player *v92; // eax@255
-  int v105; // edi@271
-  __int16 v108; // ST1C_2@274
-  __int16 v109; // ST18_2@274
-  stru6 *v110; // eax@274
-  int v111; // eax@274
-  Actor *v112; // esi@278
-  int v113; // eax@278
-  int v114; // ebx@278
-  unsigned int v115; // ecx@278
-  int v116; // edx@279
-  int v117; // edx@281
-  int v118; // edx@283
-  signed int v122; // eax@286
-  int v127; // eax@296
-  int v153; // ecx@322
-  int v154; // eax@322
-  int v155; // eax@323
-  int v156; // eax@323
-  int v162; // edi@340
-  signed int v164; // eax@340
-  signed int v165; // edi@340
-  signed int v168; // edi@343
-  int v169; // eax@344
-  signed int v174; // edi@355
-  int v188; // esi@369
-  int v189; // edi@369
-  signed int v191; // edi@379
-  signed int v205; // edi@405
-  int v206; // eax@407
-  __int16 v207; // cx@407
-  int v208; // eax@411
-  signed int v209; // ecx@412
-  int v210; // edx@412
-  signed int v211; // ecx@412
-  int v212; // eax@413
-  int v213; // eax@413
-  int v214; // eax@413
-  int v215; // eax@415
-  double v216; // st7@415
-  double v217; // st6@415
-  signed __int64 v218; // qtt@423
-  char v223; // al@438
-
-  int v227; // esi@453
-  unsigned int v228; // edi@454
-  int v229; // edi@466
-
-  ItemGen *v240; // ecx@472
-  double v241; // st7@478
-  ItemGen *v245; // edi@492
-  int v254; // eax@513
-  int v255; // esi@513
-  int v256; // ecx@513
-  int v257; // edx@514
-  int v258; // ecx@514
-  char v259; // al@516
-  int v260; // eax@518
-  int v261; // esi@519
-  int v262; // edx@521
-  int *v263; // ecx@521
-  int v264; // esi@521
-  int v265; // edx@521
-  int *ii; // eax@522
-  int v267; // eax@524
-  int v268; // eax@524
-  char v271; // al@531
-  int v277; // edx@548
-  int v278; // ecx@548
-  char v279; // al@550
-  int v280; // eax@552
-  int *v281; // esi@553
-  int v282; // edx@555
-  int *v283; // ecx@555
-  int v284; // esi@555
-  int v285; // edx@555
-  int *l; // eax@556
-  ItemGen *v294; // esi@575
-  int v295; // edx@575
-  int kk; // edi@575
-  char v313; // al@606pGame->GetStru6()
-  const char *v317; // ecx@617
-  Player *v318; // ecx@619
-  unsigned int v319; // edi@627
-  int v323; // edi@635
-  char *v324; // eax@635
-  Player *v325; // ecx@640
-  int v328; // ecx@651
-  int v329; // ecx@652
-  int v330; // edi@654
-  signed int v342; // edi@668
-  signed int v343; // edi@670
-  unsigned __int64 v344; // ST08_8@670
-  Player *v351; // edi@680
-  Player *v357; // edi@694
-  Actor *v369; // edi@705
-  int v373; // eax@715
-  int v374; // eax@717
-  int v376; // eax@717
-  Player *v377; // ecx@719
-  int v381; // edi@727
-  int v382; // ecx@727
-  Player *v383; // eax@728
-  int v384; // eax@733
-  int v388; // edi@740
-  int v396; // eax@752
-  int v397; // eax@757
-  int v398; // eax@757
-  int v399; // eax@757
-  Actor *v417; // eax@787
-  int v418; // ecx@789
-  __int16 v419; // ax@791
-  signed int v420; // eax@793
-  ItemGen *v421; // edx@793
-  const char *v422; // eax@801
-  signed int v426; // eax@815
-  Actor *v433; // edi@832
-  int v435; // ecx@837
-  int v440; // eax@843
-  int v441; // eax@847
-  signed int v445; // edi@857
-  int v446; // ecx@862
-  LevelDecoration *v447; // edi@864
-  __int16 v448; // ax@864
-  char *v449; // esi@870
-  int v450; // eax@870
-  signed int v460; // eax@895
-  Actor *v461; // eax@897
-  unsigned __int16 v462; // cx@897
-  signed int v463; // edx@897
-  int v470; // edi@913
-  int v471; // eax@917
-  int v472; // eax@917
-  int v498; // edi@931
-  int v499; // eax@935
-  int v500; // eax@935
-  Player *v501; // edi@939
-  int v505; // eax@943
-  int v507; // edi@944
-  signed int v509; // eax@944
-  //signed int v510; // edi@944
-  Actor *v518; // edx@957
-  __int16 v519; // cx@958
-  int v531; // eax@982
-  int v533; // edi@983
-  signed int v535; // eax@983
-  signed int v536; // edi@983
-  stru6 *v537; // eax@984
-  double v549; // st7@991
-  unsigned __int16 v550; // di@991
-  Player *v553; // edi@1001
-  unsigned __int16 v562; // di@1005
-  signed int v563; // eax@1010
-  unsigned int v564; // ecx@1011
-  signed int v565; // eax@1012
-  Player **v566; // ecx@1012
-  int v567; // eax@1012
-  Player *v571; // eax@1013
-  char *v572; // ecx@1013
-  signed int v576; // eax@1025
-  Player *v577; // eax@1026
-  int v578; // eax@1028
-  __int16 v579; // ax@1029
-  int v581; // edi@1031
-  char *v585; // esi@1034
-  signed int v587; // eax@1035
-  char v591; // al@1048
-  ItemGen *v592; // esi@1052
-  int v596; // esi@1066
-  unsigned int v597; // edi@1067
-  int v600; // edi@1086
-  int v601; // edx@1086
-  int v602; // eax@1086
-  int v603; // ecx@1086
-  NPCData *pNPCData; // eax@1089
-  int v606; // edx@1091
-  AwardType *v607; // ecx@1100
-  __int16 v608; // ax@1102
-  signed int v609; // eax@1104
-  int v610; // edi@1106
-  unsigned int v611; // eax@1106
-  Player *v612; // edi@1106
-  DDM_DLV_Header *v613; // eax@1108
-  int v615; // edi@1119
-  Player *v619; // edi@1123
-  signed __int64 v623; // qax@1127
-  int v625; // edi@1129
-  signed int v627; // eax@1129
-  signed int v628; // edi@1129
-  int v629; // ecx@1130
-  Player *v630; // eax@1131
-  int v631; // eax@1137
-  int v635; // edi@1142
-  int v642; // edi@1156
-  int v643; // eax@1156
-  int v644; // eax@1156
-  signed int v645; // eax@1158
-  unsigned int v656; // [sp-4h] [bp-E88h]@639
-  int v657; // [sp-4h] [bp-E88h]@807
-  int v659; // [sp+0h] [bp-E84h]@123
-  int v660; // [sp+0h] [bp-E84h]@146
-  Actor *v661; // [sp+0h] [bp-E84h]@164
-  unsigned __int64 v663; // [sp+0h] [bp-E84h]@639
-  const char *v664; // [sp+0h] [bp-E84h]@802
-  int v665; // [sp+0h] [bp-E84h]@807
-  int v666; // [sp+4h] [bp-E80h]@12
-  PLAYER_SKILL_TYPE v667; // [sp+4h] [bp-E80h]@25
-  int v671; // [sp+4h] [bp-E80h]@146
-  int v675; // [sp+4h] [bp-E80h]@800
-  int v676; // [sp+4h] [bp-E80h]@807
-  int v677; // [sp+4h] [bp-E80h]@861
-  int v679[800]; // [sp+14h] [bp-E70h]@515
-  AIDirection a3; // [sp+C94h] [bp-1F0h]@21
-  int v681[4]; // [sp+CB0h] [bp-1D4h]@1137
-  int v682[4]; // [sp+CC0h] [bp-1C4h]@731
-  ItemGen v683; // [sp+CD0h] [bp-1B4h]@791
-  int v684; // [sp+D04h] [bp-180h]@416
-  unsigned __int64 v685; // [sp+D08h] [bp-17Ch]@416
-  unsigned __int64 v687; // [sp+D24h] [bp-160h]@327
-  Vec3_int_ v688; // [sp+D2Ch] [bp-158h]@943
-  Vec3_int_ v691; // [sp+D38h] [bp-14Ch]@137
-  Vec3_int_ v694; // [sp+D44h] [bp-140h]@982
-  Vec3_int_ v697; // [sp+D50h] [bp-134h]@129
-  Vec3_int_ v700; // [sp+D5Ch] [bp-128h]@339
-  Vec3_int_ v701; // [sp+D68h] [bp-11Ch]@286
-  Vec3_int_ v704; // [sp+D74h] [bp-110h]@132
-  Vec3_int_ v707; // [sp+D80h] [bp-104h]@1127
-  int v710; // [sp+D8Ch] [bp-F8h]@1156
-  __int64 v712; // [sp+D94h] [bp-F0h]@991
-  int v713; // [sp+D9Ch] [bp-E8h]@324
-  int n; // [sp+DA0h] [bp-E4h]@1
-  AIDirection v715; // [sp+DA4h] [bp-E0h]@21
-  int v716; // [sp+DC0h] [bp-C4h]@272
-  __int64 v717; // [sp+DC4h] [bp-C0h]@271
-  float v718; // [sp+DCCh] [bp-B8h]@176
-  signed int sRecoveryTime; // [sp+DD0h] [bp-B4h]@53
-  char *y; // [sp+DD4h] [bp-B0h]@325
-  int v721; // [sp+DD8h] [bp-ACh]@163
-  int v723; // [sp+E4Ch] [bp-38h]@1
-  ItemGen *_this; // [sp+E50h] [bp-34h]@23
-  float v725; // [sp+E54h] [bp-30h]@23
-  Player *v726; // [sp+E58h] [bp-2Ch]@131
-  float v727; // [sp+E5Ch] [bp-28h]@1
-  unsigned int uRequiredMana; // [sp+E60h] [bp-24h]@53
-  Player *pPlayer; // [sp+E64h] [bp-20h]@8
-  int v730; // [sp+E68h] [bp-1Ch]@53
-  Player *v730b;
-  ItemGen *v730c;
-  int v731; // [sp+E6Ch] [bp-18h]@48
-  signed int v732; // [sp+E70h] [bp-14h]@325
-  unsigned __int64 v733; // [sp+E74h] [bp-10h]@1
-  signed int a2; // [sp+E7Ch] [bp-8h]@14
-  int amount; // [sp+E80h] [bp-4h]@1
-
-  SpriteObject pSpellSprite; // [sp+DDCh] [bp-A8h]@1
-
-  v2 = 0;
-  amount = 0;
-  LODWORD(v733) = 0;
-  v723 = 0;
-  v727 = 0.0;
-  for(n = 0; n < 10; ++n)
-  {
-    pCastSpell = &this[n];
-    HIDWORD(v733) = (int)pCastSpell;
-    if ( pCastSpell->spellnum == 0 )
-      continue;
-
-    if (pParty->Invisible())
-      pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].Reset();
-
-    if ( pCastSpell->field_8 & 0x3CA )
-    {
-      if ( !pParty->pPlayers[pCastSpell->uPlayerID].CanAct() )
-        this->_427D48(1);
-      continue;
-    }
-    pPlayer = &pParty->pPlayers[pCastSpell->uPlayerID];
-
-    a2 = pCastSpell->spell_target_pid;
-    if (!pCastSpell->spell_target_pid)
-    {
-      if (pCastSpell->spellnum == SPELL_LIGHT_DESTROY_UNDEAD ||
-          pCastSpell->spellnum == SPELL_SPIRIT_TURN_UNDEAD ||
-          pCastSpell->spellnum == SPELL_DARK_CONTROL_UNDEAD )
-        v666 = 1;
-      else
-        v666 = 0;
-
-      a2 = stru_50C198.FindClosestActor(5120, 1, v666);
-      v6 = pMouse->uPointingObjectID;
-      if ( pMouse->uPointingObjectID && PID_TYPE(v6) == OBJECT_Actor && pActors[PID_ID(v6)].CanAct() )
-        a2 = pMouse->uPointingObjectID;
-    }
-
-
-    pSpellSprite.uType = stru_4E3ACC[pCastSpell->spellnum].uType;
-    if (pSpellSprite.uType)
-    {
-      if (PID_TYPE(a2) == OBJECT_Actor)
-      {
-        memcpy(&v715, Actor::GetDirectionInfo(PID(OBJECT_Player, pCastSpell->uPlayerID + 1), a2, &a3, 0), sizeof(v715));
-        v2 = v723;
-      }
-      else
-      {
-        v715.uYawAngle = pParty->sRotationY;
-        v715.uPitchAngle = pParty->sRotationX;
-      }
-    }
-
-    LODWORD(v725) = 0;
-    _this = 0;
-    if (pCastSpell->forced_spell_skill_level)
-    {
-      v11 = pCastSpell->forced_spell_skill_level;
-      v723 = v11 & 0x3F; // 6 bytes
-      v2 = v723;
-    }
-    else
-    {
-      //v667 = PLAYER_SKILL_STAFF;
-      if (pCastSpell->spellnum < SPELL_AIR_WIZARD_EYE)
-        v667 = PLAYER_SKILL_FIRE;
-      else if (pCastSpell->spellnum < SPELL_WATER_AWAKEN)
-        v667 = PLAYER_SKILL_AIR;
-      else if (pCastSpell->spellnum < SPELL_EARTH_STUN)
-        v667 = PLAYER_SKILL_WATER;
-      else if (pCastSpell->spellnum < SPELL_SPIRIT_DETECT_LIFE)
-        v667 = PLAYER_SKILL_EARTH;
-      else if (pCastSpell->spellnum < SPELL_MIND_REMOVE_FEAR)
-        v667 = PLAYER_SKILL_SPIRIT;
-      else if (pCastSpell->spellnum < SPELL_BODY_CURE_WEAKNESS)
-        v667 = PLAYER_SKILL_MIND;
-      else if (pCastSpell->spellnum < SPELL_LIGHT_LIGHT_BOLT)
-        v667 = PLAYER_SKILL_BODY;
-      else if (pCastSpell->spellnum < SPELL_DARK_REANIMATE)
-        v667 = PLAYER_SKILL_LIGHT;
-      else if (pCastSpell->spellnum < SPELL_BOW_ARROW)
-        v667 = PLAYER_SKILL_DARK;
-      else if (pCastSpell->spellnum == SPELL_BOW_ARROW)
-        v667 = PLAYER_SKILL_BOW;
-      else assert(false && "Unknown spell");
-
-      LODWORD(v725) = v667;
-      v723 = pPlayer->GetActualSkillLevel(v667) & 0x3F;
-      v2 = v723;
-      v11 = pPlayer->pActiveSkills[LODWORD(v725)];
-    }
-
-	v731 = SkillToMastery(v11);
-
-    if (pCastSpell->forced_spell_skill_level)
-      uRequiredMana = 0;
-    else 
-      uRequiredMana = pSpellDatas[pCastSpell->spellnum - 1].mana_per_skill[v731 - 1];
-    sRecoveryTime = pSpellDatas[pCastSpell->spellnum - 1].recovery_per_skill[v731 - 1];
-
-    if (LODWORD(v725) == PLAYER_SKILL_DARK && pParty->uCurrentHour == 0 && pParty->uCurrentMinute == 0 ||
-        LODWORD(v725) == PLAYER_SKILL_LIGHT && pParty->uCurrentHour == 12 && pParty->uCurrentMinute == 0)
-      uRequiredMana = 0;
-
-    if (pCastSpell->spellnum < SPELL_BOW_ARROW && pPlayer->sMana < uRequiredMana)
-    {
-      ShowStatusBarString(pGlobalTXT_LocalizationStrings[586], 2u); // "Not enough spell points"
-      pCastSpell->spellnum = 0;
-      continue;
-    }
-    v730 = pCastSpell->spellnum;
-    if (pPlayer->Cursed() && pCastSpell->spellnum < SPELL_BOW_ARROW && rand() % 100 < 50)
-    {
-      if (!pParty->bTurnBasedModeOn)
-      {
-        //v646 = pPlayer;
-        pPlayer->SetRecoveryTime((signed __int64)(flt_6BE3A4_debug_recmod1 * 213.3333333333333));
-        //v647 = n;
-      }
-      else
-      {
-        //v647 = n;
-        //v646 = pPlayer;
-        //v648 = sRecoveryTime;
-        //v649 = pPlayer;
-        pParty->pTurnBasedPlayerRecoveryTimes[this[n].uPlayerID] = 100;
-        pPlayer->SetRecoveryTime(sRecoveryTime);
-        pTurnEngine->_40471C();
-      }
-      ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2u); // "Spell failed"
-      pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-      this[n].spellnum = 0;
-      pPlayer->sMana -= uRequiredMana;
-      return;
-    }
-
-    switch ( pCastSpell->spellnum )
-    {
-		case SPELL_101:
-			assert(false && "Unknown spell effect #101 (prolly flaming bow arrow");
-		case SPELL_BOW_ARROW:
-		{
-			amount = 1;
-			if ( SkillToMastery(pPlayer->pActiveSkills[PLAYER_SKILL_BOW]) >= 3 )
-				amount = 2;
-			sRecoveryTime = pPlayer->GetAttackRecoveryTime(true);
-			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_id = pCastSpell->spellnum;
-			pSpellSprite.spell_skill = v731;
-			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-			if ( pPlayer->WearsItem(ITEM_ARTEFACT_ULLYSES, EQUIP_BOW) )
-				pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(0xBD6u);
-			pSpellSprite.vPosition.x = pParty->vPosition.x;
-			pSpellSprite.vPosition.y = pParty->vPosition.y;
-			pSpellSprite.uAttributes = 0;
-			pSpellSprite.uSpriteFrameID = 0;
-			pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
-			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-			pSpellSprite.spell_target_pid = a2;
-			pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
-			pSpellSprite.uFacing = LOWORD(v715.uYawAngle);
-			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-			pPlayer = &pParty->pPlayers[pCastSpell->uPlayerID];
-			memcpy(&pSpellSprite.stru_24, &pPlayer->pInventoryItems[pPlayer->pEquipment.uBow-1], sizeof(pSpellSprite.stru_24));
-			pSpellSprite.uAttributes = 256;
-			if ( pParty->bTurnBasedModeOn == 1 )
-				pSpellSprite.uAttributes = 260;
-			for ( i = 0; i < amount; ++i )
-			{
-				if ( i )
-					pSpellSprite.vPosition.z += 32;
-				pSpellSprite.uSectorID = pIndoor->GetSector(pSpellSprite.vPosition.x, pSpellSprite.vPosition.y, pSpellSprite.vPosition.z);
-				if ( pSpellSprite.Create(v715.uYawAngle, v715.uPitchAngle, pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed,
-					pCastSpell->uPlayerID + 1) != -1 && pParty->bTurnBasedModeOn == 1 )
-				++pTurnEngine->field_1C;
-			}
-			break;
-		}
-		case SPELL_LASER_PROJECTILE:
-		{
-			sRecoveryTime = pPlayer->GetAttackRecoveryTime(0);
-			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
-			pSpellSprite.spell_level = v723;
-			pSpellSprite.spell_skill = v731;
-			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-			pSpellSprite.vPosition.x = pParty->vPosition.x;
-			pSpellSprite.vPosition.y = pParty->vPosition.y;
-			pSpellSprite.uAttributes = 0;
-			pSpellSprite.uSpriteFrameID = 0;
-			pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 2;
-			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-			pSpellSprite.spell_target_pid = a2;
-			pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
-			pSpellSprite.uFacing = LOWORD(v715.uYawAngle);
-			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-			pPlayer = &pParty->pPlayers[pCastSpell->uPlayerID];
-			memcpy(&pSpellSprite.stru_24, &pPlayer->pInventoryItems[pPlayer->pEquipment.uMainHand-1],sizeof(pSpellSprite.stru_24));
-			//	&pParty->pPlayers[pCastSpell->uPlayerID].spellbook.pDarkSpellbook.bIsSpellAvailable[36
-			//		* pParty->pPlayers[pCastSpell->uPlayerID].pEquipment.uMainHand + 5], );
-			v23 = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pSpellSprite.vPosition.z);
-			HIBYTE(pSpellSprite.uAttributes) |= 1u;
-			pSpellSprite.uSectorID = v23;
-			if ( pParty->bTurnBasedModeOn == 1 )
-				LOBYTE(pSpellSprite.uAttributes) |= 4u;
-			if ( pSpellSprite.Create(v715.uYawAngle, v715.uPitchAngle, pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed,
-					pCastSpell->uPlayerID + 1) != -1 && pParty->bTurnBasedModeOn == 1 )
-				++pTurnEngine->field_1C;
-			break;
-		}
-		case SPELL_FIRE_TORCH_LIGHT:
-		{
-			switch (v731)
-			{
-				case 1: amount = 2; break;
-				case 2: amount = 3; break;
-				case 3:
-				case 4: amount = 4; break;
-				default:
-				assert(false);
-			}
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			pParty->pPartyBuffs[PARTY_BUFF_TORCHLIGHT].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)3600 * v2 * 4.2666669), v731, amount, 0, 0);
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_FIRE_FIRE_SPIKE:
-		{
-			switch (v731)
-			{
-				case 1: amount = 3; break;
-				case 2: amount = 5; break;
-				case 3: amount = 7; break;
-				case 4: amount = 9; break;
-				default:
-				assert(false);
-			}
-
-			//v31 = v3->uPlayerID;
-			//v32 = 8 * v31;
-			//LOBYTE(v32) = v32 | OBJECT_Player;
-
-			//if ( (signed int)uNumSpriteObjects > 0 )
-			int _v733 = 0;
-			for (uint i = 0; i < uNumSpriteObjects; ++i)
-			{
-				auto object = &pSpriteObjects[i];
-				if (object->uType && object->spell_id == SPELL_FIRE_FIRE_SPIKE && object->spell_caster_pid == PID(OBJECT_Player, pCastSpell->uPlayerID))
-				++_v733;
-				/*v33 = (char *)&pSpriteObjects[0].field_48;
-				v730 = uNumSpriteObjects;
-				do
-				{
-				if ( *((short *)v33 - 36) && *(int *)v33 == 7 && *((int *)v33 + 4) == v32 )
-					++HIDWORD(v733);
-				v33 += 112;
-				--v730;
-				}
-				while ( v730 );*/
-			}
-			if (_v733 > amount)
-			{
-				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
-				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
-				continue;
-			}
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
-			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-			pSpellSprite.vPosition.y = pParty->vPosition.y;
-			pSpellSprite.vPosition.x = pParty->vPosition.x;
-			pSpellSprite.uAttributes = 0;
-			pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
-			pSpellSprite.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3);
-			pSpellSprite.uSpriteFrameID = 0;
-			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-			pSpellSprite.spell_target_pid = a2;
-			pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
-			pSpellSprite.uFacing = LOWORD(v715.uYawAngle);
-			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-			if ( pParty->bTurnBasedModeOn == 1 )
-				LOBYTE(pSpellSprite.uAttributes) |= 4u;
-			v659 = pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed;
-			if ( pSpellSprite.Create(pParty->sRotationY, pParty->sRotationX + 10, v659, pCastSpell->uPlayerID + 1) != -1 && pParty->bTurnBasedModeOn == 1 )
-				++pTurnEngine->field_1C;
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_AIR_IMPLOSION:
-		{
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			if (!a2)
-			{
-				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
-				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
-				continue;
-			}
-			if (PID_TYPE(a2) != OBJECT_Actor)
-			{
-				LODWORD(v727) = 1;
-				break;
-			}
-			v697.x = 0;
-			v697.y = 0;
-			v697.z = 0;
-			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
-			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-			pSpellSprite.uAttributes = 0;
-			pSpellSprite.uSectorID = 0;
-			pSpellSprite.uSpriteFrameID = 0;
-			pSpellSprite.field_60_distance_related_prolly_lod = 0;
-			pSpellSprite.uFacing = 0;
-			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-			pSpellSprite.vPosition.x = pActors[PID_ID(a2)].vPosition.x;
-			pSpellSprite.vPosition.z = pActors[PID_ID(a2)].vPosition.z;
-			pSpellSprite.vPosition.y = pActors[PID_ID(a2)].vPosition.y;
-			pSpellSprite.spell_target_pid = PID(OBJECT_Actor, PID_ID(a2));
-			auto obj_id = pSpellSprite.Create(0, 0, 0, 0);
-			DamageMonsterFromParty(PID(OBJECT_Item, obj_id), PID_ID(a2), &v697);
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_EARTH_MASS_DISTORTION:
-		{
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			if ( !stru_50C198.GetMagicalResistance(&pActors[PID_ID(a2)], 3u) )
-			{
-				LODWORD(v727) = 1;
-				break;
-			}
-			pActors[PID_ID(a2)].pActorBuffs[10].Apply(pMiscTimer->uTotalGameTimeElapsed + 128, 0, 0, 0, 0);
-			v704.x = 0;
-			v704.y = 0;
-			v704.z = 0;
-			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
-			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-			pSpellSprite.uAttributes = 0;
-			pSpellSprite.uSectorID = 0;
-			pSpellSprite.uSpriteFrameID = 0;
-			pSpellSprite.field_60_distance_related_prolly_lod = 0;
-			pSpellSprite.uFacing = 0;
-			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-			pSpellSprite.vPosition.x = pActors[PID_ID(a2)].vPosition.x;
-			pSpellSprite.vPosition.y = pActors[PID_ID(a2)].vPosition.y;
-			pSpellSprite.vPosition.z = pActors[PID_ID(a2)].vPosition.z;
-			pSpellSprite.spell_target_pid = PID(OBJECT_Actor, PID_ID(a2));
-			auto obj_id = pSpellSprite.Create(0, 0, 0, 0);
-			DamageMonsterFromParty(PID(OBJECT_Item, obj_id), PID_ID(a2), &v704);
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_LIGHT_DESTROY_UNDEAD:
-		{
-			if ( !pPlayer->CanCastSpell(uRequiredMana) || !a2 || PID_TYPE(a2) != OBJECT_Actor)
-				break;
-			//v730 = a2 >> 3;
-			//HIDWORD(v733) = (int)&pActors[PID_ID(a2)];
-			v691.x = 0;
-			v691.y = 0;
-			v691.z = 0;
-			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
-			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-			pSpellSprite.vPosition.x = pActors[PID_ID(a2)].vPosition.x;
-			pSpellSprite.vPosition.y = pActors[PID_ID(a2)].vPosition.y;
-			pSpellSprite.vPosition.z = pActors[PID_ID(a2)].vPosition.z;
-			pSpellSprite.uAttributes = 0;
-			pSpellSprite.uSectorID = pIndoor->GetSector(pSpellSprite.vPosition.x, pSpellSprite.vPosition.y, pSpellSprite.vPosition.z);
-			pSpellSprite.uSpriteFrameID = 0;
-			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-			pSpellSprite.spell_target_pid = a2;
-			pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
-			pSpellSprite.uFacing = LOWORD(v715.uYawAngle);
-			pSpellSprite.uAttributes |= 0x80u;
-			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-			auto obj_id = pSpellSprite.Create(0, 0, 0, 0);
-			if ( !MonsterStats::BelongsToSupertype(pActor->pMonsterInfo.uID, MONSTER_SUPERTYPE_UNDEAD) )
-			{
-				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
-				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
-				continue;
-			}
-			DamageMonsterFromParty(PID(OBJECT_Item, obj_id), PID_ID(a2), &v691);
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_FIRE_FIRE_BOLT:
-		case SPELL_FIRE_FIREBALL:
-		case SPELL_FIRE_INCINERATE:
-		case SPELL_AIR_LIGHNING_BOLT:
-		case SPELL_WATER_ICE_BOLT:
-		case SPELL_WATER_ICE_BLAST:
-		case SPELL_EARTH_STUN:
-		case SPELL_EARTH_DEADLY_SWARM:
-		case SPELL_MIND_MIND_BLAST:
-		case SPELL_MIND_PSYCHIC_SHOCK:
-		case SPELL_BODY_HARM:
-		case SPELL_LIGHT_LIGHT_BOLT:
-		case SPELL_DARK_DRAGON_BREATH:
-		{
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
-			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-			pSpellSprite.vPosition.y = pParty->vPosition.y;
-			pSpellSprite.vPosition.x = pParty->vPosition.x;
-			pSpellSprite.uAttributes = 0;
-			pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
-			if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
-				pSpellSprite.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3);
-			else
-				pSpellSprite.uSectorID = 0;
-			pSpellSprite.uSpriteFrameID = 0;
-			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-			pSpellSprite.spell_target_pid = a2;
-			pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
-			pSpellSprite.uFacing = LOWORD(v715.uYawAngle);
-			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-			if ( pParty->bTurnBasedModeOn == 1 )
-				LOBYTE(pSpellSprite.uAttributes) |= 4u;
-			if ( pCastSpell->spellnum == SPELL_AIR_LIGHNING_BOLT )
-				LOBYTE(pSpellSprite.uAttributes) |= 0x40u;
-			v659 = pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed;
-			if ( pSpellSprite.Create(v715.uYawAngle, v715.uPitchAngle, v659, pCastSpell->uPlayerID + 1) != -1 && pParty->bTurnBasedModeOn == 1 )
-				++pTurnEngine->field_1C;
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_WATER_ACID_BURST:
-		case SPELL_EARTH_BLADES:
-		case SPELL_BODY_FLYING_FIST:
-		case SPELL_DARK_TOXIC_CLOUD:
-		{
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
-			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-			v51 = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 2;
-			pSpellSprite.vPosition.y = pParty->vPosition.y;
-			v671 = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 2;
-			v660 = pParty->vPosition.y;
-			pSpellSprite.uAttributes = 0;
-			pSpellSprite.vPosition.x = pParty->vPosition.x;
-			pSpellSprite.vPosition.z = v51;
-			v52 = pIndoor->GetSector(pParty->vPosition.x, v660, v671);
-			pSpellSprite.uSpriteFrameID = 0;
-			pSpellSprite.uSectorID = v52;
-			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-			pSpellSprite.spell_target_pid = a2;
-			pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
-			pSpellSprite.uFacing = LOWORD(v715.uYawAngle);
-			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-			if ( pParty->bTurnBasedModeOn == 1 )
-				LOBYTE(pSpellSprite.uAttributes) |= 4u;
-			v659 = pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed;
-			if ( pSpellSprite.Create(v715.uYawAngle, v715.uPitchAngle, v659, pCastSpell->uPlayerID + 1) != -1 && pParty->bTurnBasedModeOn == 1 )
-				++pTurnEngine->field_1C;
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_LIGHT_SUNRAY:
-		{
-			if ( uCurrentlyLoadedLevelType == LEVEL_Indoor
-				|| uCurrentlyLoadedLevelType == LEVEL_Outdoor && (pParty->uCurrentHour < 5 || pParty->uCurrentHour >= 21) )
-			{
-				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
-				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
-				continue;
-			}
-			if ( pPlayer->CanCastSpell(uRequiredMana) )
-			{
-				pSpellSprite.stru_24.Reset();
-				pSpellSprite.spell_id = pCastSpell->spellnum;
-				pSpellSprite.spell_skill = v731;
-				pSpellSprite.spell_level = v2;
-				pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-				pSpellSprite.vPosition.y = pParty->vPosition.y;
-				v51 = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
-				v671 = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
-				v660 = pParty->vPosition.y;
-				pSpellSprite.uAttributes = 0;
-				pSpellSprite.vPosition.x = pParty->vPosition.x;
-				pSpellSprite.vPosition.z = v51;
-				v52 = pIndoor->GetSector(pParty->vPosition.x, v660, v671);
-				pSpellSprite.uSpriteFrameID = 0;
-				pSpellSprite.uSectorID = v52;
-				pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-				pSpellSprite.spell_target_pid = a2;
-				pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
-				pSpellSprite.uFacing = LOWORD(v715.uYawAngle);
-				pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-				if ( pParty->bTurnBasedModeOn == 1 )
-					LOBYTE(pSpellSprite.uAttributes) |= 4u;
-				v659 = pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed;
-				if ( pSpellSprite.Create(v715.uYawAngle, v715.uPitchAngle, v659, pCastSpell->uPlayerID + 1) != -1 && pParty->bTurnBasedModeOn == 1 )
-					++pTurnEngine->field_1C;
-				LODWORD(v727) = 1;
-			}
-			break;
-		}
-		case SPELL_LIGHT_PARALYZE:
-		{
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			if (PID_TYPE(a2) != OBJECT_Actor || (v730 = PID_ID(a2), v721 = (int)&pActors[PID_ID(a2)],
-					!stru_50C198.GetMagicalResistance(&pActors[PID_ID(a2)], 9)) )
-			{
-				LODWORD(v727) = 1;
-				break;
-			}
-			Actor::AI_Stand(PID_ID(a2), 4u, 0x80u, 0);
-			v54 = (signed __int64)((double)(23040 * v2) * 0.033333335);
-			v55 = &pActors[PID_ID(a2)];
-			v55->pActorBuffs[6].Apply(pParty->uTimePlayed + (signed int)v54, v731, 0, 0, 0);
-			BYTE2(v55->uAttributes) |= 8u;
-			v55->vVelocity.x = 0;
-			//v672 = 0;
-			v55->vVelocity.y = 0;
-			v661 = v55;
-			pGame->GetStru6()->_4A7E89_sparkles_on_actor_after_it_casts_buff(v661, 0);
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_EARTH_SLOW:
-		{
-			switch (v731)
-			{
-				case 1: LODWORD(v733) = 180 * v2; amount = 2; break;
-				case 2: LODWORD(v733) = 300 * v2; amount = 2; break;
-				case 3: LODWORD(v733) = 300 * v2; amount = 4; break;
-				case 4: LODWORD(v733) = 300 * v2; amount = 8; break;
-				default:
-				assert(false);
-			}
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			if (PID_TYPE(a2) != OBJECT_Actor
-				|| (v721 = 836 * PID_ID(a2),
-					LODWORD(v718) = (int)&pActors[PID_ID(a2)],
-					!stru_50C198.GetMagicalResistance(&pActors[PID_ID(a2)], 3u)) )
-			{
-				LODWORD(v727) = 1;
-				break;
-			}
-			v58 = (signed __int64)((double)(23040 * v2) * 0.033333335);
-			//v59 = v721;
-			pActor = &pActors[PID_ID(a2)];
-			//((SpellBuff *)((char *)&pActors[0].pActorBuffs[7] + v721))->Apply(
-			pActor->pActorBuffs[7].Apply(pParty->uTimePlayed + (signed int)v58,	v731, amount, 0, 0);
-			//*((char *)&pActors[0].uAttributes + v59 + 2) |= 8u;
-			BYTE2(pActor->uAttributes) |= 8u;
-			//v672 = 0;
-			v661 = (Actor *)LODWORD(v718);
-			pGame->GetStru6()->_4A7E89_sparkles_on_actor_after_it_casts_buff(v661, 0);
-			LODWORD(v727) = 1;
-			break;
-      }
-		case SPELL_MIND_CHARM:
-		{
-		if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			break;
-
-		if ( !stru_50C198.GetMagicalResistance(&pActors[PID_ID(a2)], 7u) )
-		{
-			LODWORD(v727) = 1;
-			break;
-		}
-
-		uint power = 300 * v2;
-		if ( v731 == 2 )
-		{
-			power = 600 * v2;
-		}
-		else if ( v731 == 3 )
-			power  = 29030400;
-
-		//((SpellBuff *)((char *)&pActors[0].pActorBuffs[9] + v730))->Reset();
-		pActors[PID_ID(a2)].pActorBuffs[9].Reset();
-		//((SpellBuff *)((char *)&pActors[0].pActorBuffs[12] + v730))->Reset();
-		pActors[PID_ID(a2)].pActorBuffs[12].Reset();
-		//((SpellBuff *)((char *)&pActors[0].pActorBuffs[1] + v730))->Apply(
-		pActors[PID_ID(a2)].pActorBuffs[1].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)(power << 7) * 0.033333335),
-			v731, 0, 0, 0);
-		pSpellSprite.stru_24.Reset();
-		pSpellSprite.spell_id = pCastSpell->spellnum;
-		pSpellSprite.spell_level = v2;
-		pSpellSprite.spell_skill = v731;
-		v60 = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-		v61 = PID_ID(a2);
-			v600 = pActors[v61].vPosition.y;
-			v601 = pActors[v61].vPosition.x;
-			pSpellSprite.uObjectDescID = v60;
-			pSpellSprite.vPosition.x = v601;
-			v602 = pActors[v61].uActorHeight;
-			v603 = pActors[v61].vPosition.z;
-			pSpellSprite.vPosition.y = v600;
-			v676 = v603 + v602;
-			v665 = v600;
-			pSpellSprite.vPosition.z = v603 + v602;
-			v657 = v601;
-			pSpellSprite.uAttributes = 0;
-			pSpellSprite.uSectorID = pIndoor->GetSector(v657, v665, v676);
-			pSpellSprite.uSpriteFrameID = 0;
-			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-			pSpellSprite.spell_target_pid = a2;
-			pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
-			pSpellSprite.uFacing = LOWORD(v715.uYawAngle);
-			LOBYTE(pSpellSprite.uAttributes) |= 0x80u;
-			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-			pSpellSprite.Create(0, 0, 0, pCastSpell->uPlayerID + 1);
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_DARK_SHRINKING_RAY:
-		{
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			pSpellSprite.stru_24.Reset();
-			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-			pSpellSprite.vPosition.x = pParty->vPosition.x;
-			pSpellSprite.vPosition.y = pParty->vPosition.y;
-			pSpellSprite.uAttributes = 0;
-			pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
-			pSpellSprite.uSectorID = pIndoor->GetSector(
-								pParty->vPosition.x,
-								pParty->vPosition.y,
-								pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3);
-			pSpellSprite.uSpriteFrameID = 0;
-			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-			pSpellSprite.spell_target_pid = a2;
-			pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
-			pSpellSprite.uFacing = LOWORD(v715.uYawAngle);
-			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-			pSpellSprite.spell_skill = v731;
-			pSpellSprite.spell_id = SPELL_FIRE_PROTECTION_FROM_FIRE;
-			pSpellSprite.spell_level = 300 * v2;
-				if ( pParty->bTurnBasedModeOn == 1 )
-				LOBYTE(pSpellSprite.uAttributes) |= 4u;
-
-				v659 = pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed;
-
-				if ( pSpellSprite.Create(v715.uYawAngle, v715.uPitchAngle, v659, pCastSpell->uPlayerID + 1) != -1 && pParty->bTurnBasedModeOn == 1 )
-				++pTurnEngine->field_1C;
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_FIRE_FIRE_AURA:
-		{
-			switch (v731)
-			{
-				case 1: LODWORD(v733) = 3600 * v2; amount = 10; break;
-				case 2: LODWORD(v733) = 3600 * v2; amount = 11; break;
-				case 3: LODWORD(v733) = 3600 * v2; amount = 12; break;
-				case 4: LODWORD(v733) = 0; amount = 12; break;
-				default:
-				assert(false);
-			}
-			
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			v730c = &pParty->pPlayers[pCastSpell->uPlayerID_2].pInventoryItems[a2];
-			auto _itm = &pItemsTable->pItems[v730c->uItemID];
-			v730c->UpdateTempBonus(pParty->uTimePlayed);
-			if ( v730c->uItemID < 64 || v730c->uItemID > 65 
-				&& !v730c->Broken()
-				&& !v730c->uSpecEnchantmentType
-				&& !v730c->uEnchantmentType
-				&& ( _itm->uEquipType == 0 || _itm->uEquipType == 1 || _itm->uEquipType == 2)
-				&& !pItemsTable->IsMaterialNonCommon(v730c) )
-			{
-				v69 = v730c;
-				v14 = v731 == 4;
-				v730c->uSpecEnchantmentType = amount;
-				if ( !v14 )
-				{
-					v69->uExpireTime = pParty->uTimePlayed
-										+ (signed int)(signed __int64)((double)(signed int)((int)v733 << 7)
-																		* 0.033333335);
-					v69->uAttributes |= 8u;
-				}
-				v69->uAttributes |= 0x10u;
-				_50C9A8_item_enchantment_timer = 256;
-				LODWORD(v727) = 1;
-				break;
-			}
-
-			dword_50C9D0 = 113;
-			dword_50C9D4 = 0;
-			dword_50C9D8 = 1;
-
-			ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
-			pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-			pCastSpell->spellnum = 0;
-			continue;
-		}
-		case SPELL_BODY_REGENERATION:
-		{
-			switch (v731)
-			{
-				case 1: LODWORD(v733) = 3600 * v2; amount = 1; break;
-				case 2: LODWORD(v733) = 3600 * v2; amount = 1; break;
-				case 3: LODWORD(v733) = 3600 * v2; amount = 3; break;
-				case 4: LODWORD(v733) = 3600 * v2; amount = 10; break;
-				default:
-				assert(false);
-			}
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
-
-			pParty->pPlayers[pCastSpell->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_REGENERATION].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)v733 * 4.2666669), v731, amount, 0, 0);
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_FIRE_PROTECTION_FROM_FIRE:
-		case SPELL_AIR_PROTECTION_FROM_AIR:
-		case SPELL_WATER_PROTECTION_FROM_WATER:
-		case SPELL_EARTH_PROTECTION_FROM_EARTH:
-		case SPELL_MIND_PROTECTION_FROM_MIND:
-		case SPELL_BODY_PROTECTION_FROM_BODY:
-		{
-			switch (v731)
-			{
-				case 1: 
-				case 2: 
-				case 3: 
-				case 4: LODWORD(v733) = 3600 * v2; amount = v731 * v2; break;
-				default:
-				assert(false);
-			}
-
-			switch (pCastSpell->spellnum)
-			{
-			  case SPELL_FIRE_PROTECTION_FROM_FIRE:
-				LODWORD(v725) = PARTY_BUFF_RESIST_FIRE;
-				break;
-			  case SPELL_AIR_PROTECTION_FROM_AIR:
-				LODWORD(v725) = PARTY_BUFF_RESIST_AIR;
-				break;
-			  case SPELL_WATER_PROTECTION_FROM_WATER:
-				LODWORD(v725) = PARTY_BUFF_RESIST_WATER;
-				break;
-			  case SPELL_EARTH_PROTECTION_FROM_EARTH:
-				LODWORD(v725) = PARTY_BUFF_RESIST_EARTH;
-				break;
-			  case SPELL_MIND_PROTECTION_FROM_MIND:
-				LODWORD(v725) = PARTY_BUFF_RESIST_MIND;
-				break;
-			  case SPELL_BODY_PROTECTION_FROM_BODY:
-				LODWORD(v725) = PARTY_BUFF_RESIST_BODY;
-				break;
-			  default:
-				assert(false);
-				continue;
-			}
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-			  break;
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
-			v90 = (double)(signed int)v733 * 4.2666669;
-			pParty->pPartyBuffs[LODWORD(v725)].Apply(pParty->uTimePlayed + (signed int)(signed __int64)v90, v731, amount, 0, 0);
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_FIRE_HASTE:
-		{
-			switch (v731)
-			{
-				case 1: LODWORD(v733) = 60 * (v2 + 60); break;
-				case 2: LODWORD(v733) = 60 * (v2 + 60); break;
-				case 3: LODWORD(v733) = 180 * (v2 + 20); break;
-				case 4: LODWORD(v733) = 240 * (v2 + 15); break;
-				default:
-				assert(false);
-			}
-			if ( pPlayer->CanCastSpell(uRequiredMana) )
-			{
-				v92 = pParty->pPlayers;//[0].pConditions[1];
-				LODWORD(v727) = 1;
-				do
-				{
-					if ( v92->pConditions[1] )
-						LODWORD(v727) = 0;
-					++v92;
-				}
-				while ( v92 <= &pParty->pPlayers[3] );
-				if (LODWORD(v727))
-				{
-					pParty->pPartyBuffs[PARTY_BUFF_HASTE].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, 0, 0, 0);
-
-					pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
-					pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
-					pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
-					pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
-				}
-			}
-			break;
-		}
-		case SPELL_SPIRIT_BLESS:
-		{
-			switch (v731)
-			{
-				case 1: LODWORD(v733) = 300 * (v2 + 12); break;
-				case 2: LODWORD(v733) = 300 * (v2 + 12); break;
-				case 3: LODWORD(v733) = 900 * (v2 + 4); break;
-				case 4: LODWORD(v733) = 3600 * (v2 + 1); break;
-				default:
-				assert(false);
-			}
-			amount = v2 + 5;
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			if ( v731 == 1 )
-			{
-				v108 = pCastSpell->uPlayerID_2;
-				v109 = pCastSpell->spellnum;
-				v110 = pGame->GetStru6();
-				pGame->GetStru6()->SetPlayerBuffAnim(v109, v108);
-				v111 = pOtherOverlayList->_4418B1(10000, pCastSpell->uPlayerID_2 + 310, 0, 65536);
-				//v668 = 0;
-				v716 = v111;
-				//v658 = v111;
-				//v653 = amount;
-				//v651 = 1;
-				//v28 = pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
-				//v27 = (char *)&pParty->pPlayers[v3->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_BLESS];
-		//LABEL_103:
-				//HIDWORD(v650) = HIDWORD(v28);
-		//LABEL_104:
-				//LODWORD(v650) = v28;
-				pParty->pPlayers[pCastSpell->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_BLESS].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), 1, amount, v111, 0);
-				LODWORD(v727) = 1;
-				break;
-			}
-			v105 = 0;
-			v717 = (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
-			v730b = pParty->pPlayers;//[0].pPlayerBuffs[1];
-			do
-			{
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, v105);
-				v716 = pOtherOverlayList->_4418B1(10000, v105 + 310, 0, 65536);
-				v730b->pPlayerBuffs[1].Apply(pParty->uTimePlayed + v717, v731, amount, v716, 0);
-				++v730b;
-				++v105;
-			}
-			while ( v730b <= &pParty->pPlayers[3] );
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_SPIRIT_SPIRIT_LASH:
-		{
-			if ( pPlayer->CanCastSpell(uRequiredMana) && a2 && PID_TYPE(a2) == OBJECT_Actor)
-			{
-				//v730 = a2 >> 3;
-				v112 = &pActors[PID_ID(a2)];
-				//v726 = (Player *)abs(v112->vPosition.z - pParty->vPosition.z);
-				v721 = abs(v112->vPosition.y - pParty->vPosition.y);
-				v113 = abs(v112->vPosition.x - pParty->vPosition.x);
-				_this = (ItemGen *)v113;
-				v114 = v721;
-				v115 = (unsigned int)abs(v112->vPosition.z - pParty->vPosition.z);
-				if ( v113 < v721 )
-				{
-					v116 = v113;
-					v113 = v721;
-					v114 = v116;
-				}
-				if ( v113 < (signed int)v115 )
-				{
-					v117 = v113;
-					v113 = (int)v115;
-					v115 = v117;
-				}
-				if ( v114 < (signed int)v115 )
-				{
-					v118 = v115;
-					v115 = v114;
-					v114 = v118;
-				}
-				_this = (ItemGen *)(((unsigned int)(11 * v114) >> 5) + (v115 >> 2) + v113);
-				if ( (double)(signed int)this <= 307.2 )
-				{
-					v701.x = 0;
-					v701.y = 0;
-					v701.z = 0;
-					pSpellSprite.stru_24.Reset();
-					pSpellSprite.spell_id = pCastSpell->spellnum;
-					pSpellSprite.spell_level = v723;
-					pSpellSprite.spell_skill = v731;
-					pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-					pSpellSprite.uAttributes = 0;
-					pSpellSprite.uSectorID = 0;
-					pSpellSprite.uSpriteFrameID = 0;
-					pSpellSprite.field_60_distance_related_prolly_lod = 0;
-					pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-					pSpellSprite.uFacing = 0;
-					pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-					pSpellSprite.vPosition.x = v112->vPosition.x;
-					pSpellSprite.vPosition.y = v112->vPosition.y;
-					pSpellSprite.vPosition.z = v112->vPosition.z - (unsigned int)(signed __int64)((double)(signed int)v112->uActorHeight * unk_4D8548);
-					pSpellSprite.spell_target_pid = PID(OBJECT_Actor, a2);
-					v122 = pSpellSprite.Create(0, 0, 0, 0);
-					DamageMonsterFromParty(PID(OBJECT_Item, v122), PID_ID(a2), &v701);
-					LODWORD(v727) = 1;
-				}
-				else
-				{
-					ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2u);
-					pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-					pCastSpell->spellnum = 0;
-				}
-				//pCastSpell = (CastSpellInfo *)HIDWORD(v733);
-			}
-			break;
-		}
-		case SPELL_AIR_SHIELD:
-		case SPELL_EARTH_STONESKIN:
-		case SPELL_SPIRIT_HEROISM:
-		{
-			switch (v731)
-			{
-				case 1: LODWORD(v733) = 300 * (v2 + 12); break;
-				case 2: LODWORD(v733) = 300 * (v2 + 12); break;
-				case 3: LODWORD(v733) = 900 * (v2 + 4); break;
-				case 4: LODWORD(v733) = 3600 * (v2 + 1); break;
-				default:
-				assert(false);
-			}
-			v127 = pCastSpell->spellnum;
-			if ( v127 == 17 )
-			{
-				amount = 0;
-				LODWORD(v725) = 14;
-			}
-			else
-			{
-				if ( v127 == 38 )
-				{
-					LODWORD(v725) = 15;
-					amount = v2 + 5;
-				}
-				else
-				{
-					if ( v127 != 51 )
-						continue;
-					LODWORD(v725) = 9;
-					amount = v2 + 5;
-				}
-			}
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
-			v90 = (double)(signed int)((int)v733 << 7) * 0.033333335;
-	//LABEL_304:
-			pParty->pPartyBuffs[LODWORD(v725)].Apply(pParty->uTimePlayed + (signed int)(signed __int64)v90, v731, amount, 0, 0);
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_FIRE_IMMOLATION:
-		{
-			if ( v731 == 4 )
-				LODWORD(v733) = 600 * v2;
-			else
-				LODWORD(v733) = 60 * v2;
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
-
-			pParty->pPartyBuffs[PARTY_BUFF_IMMOLATION].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, v2, 0, 0);
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_FIRE_METEOR_SHOWER:
-		{
-			//v149 = v731 - 1;
-			//if ( v149 && (v150 = v149 - 1) != 0 && (v151 = v150 - 1) != 0 )
-			int i;
-			if ( v731 == 4 )
-			{
-				i = 20;
-			}
-			else
-			{
-				i = 16;
-			}
-			if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
-			{
-				ShowStatusBarString(pGlobalTXT_LocalizationStrings[491], 2);  // Can't cast Meteor Shower indoors!
-				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
-				continue;
-			}
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			LODWORD(v725) = PID_TYPE(a2);
-			if (PID_TYPE(a2) == OBJECT_Actor)
-			{
-				uRequiredMana = pActors[PID_ID(a2)].vPosition.x;
-				v153 = pActors[PID_ID(a2)].vPosition.y;
-				v154 = pActors[PID_ID(a2)].vPosition.z;
-				LODWORD(v727) = v153;
-			}
-			else
-			{
-				v155 = stru_5C6E00->Cos(pParty->sRotationY);
-				uRequiredMana = pParty->vPosition.x + sub_42EBBE(2048, v155);
-				v156 = stru_5C6E00->Sin(pParty->sRotationY);
-				LODWORD(v727) = pParty->vPosition.y + sub_42EBBE(2048, v156);
-				v154 = pParty->vPosition.z;
-			}
-			unsigned __int64 k = 0;
-			int j = 0;
-			if ( (signed int)i > 0 )
-			{
-				v730 = LODWORD(v725) == 3 ? a2 : 0;
-				do
-				{
-					a2 = rand() % 1000;
-					if ( sqrt((double)(rand() % 1000) - 2500 * 
-								(double)(rand() % 1000) - 2500 + 
-								j * j + k * k) <= 1.0 )
-					{
-						LODWORD(v687) = 0;
-						HIDWORD(v687) = 0;
-					}
-					else
-					{
-						v687 = __PAIR__(
-								stru_5C6E00->Atan2((signed __int64)sqrt((float)(j * j + k * k)), 
-													(double)(rand() % 1000) - 2500),
-													stru_5C6E00->Atan2(j, k));
-					}
-					pSpellSprite.stru_24.Reset();
-					pSpellSprite.spell_id = pCastSpell->spellnum;
-					pSpellSprite.spell_level = v2;
-					pSpellSprite.spell_skill = v731;
-					pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-					pSpellSprite.uAttributes = 0;
-					pSpellSprite.vPosition.x = uRequiredMana;
-					pSpellSprite.vPosition.y = LODWORD(v727);
-					pSpellSprite.uSectorID = 0;
-					pSpellSprite.vPosition.z = a2 + v154;
-					pSpellSprite.uSpriteFrameID = 0;
-					pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-					pSpellSprite.spell_target_pid = v730;
-					pSpellSprite.field_60_distance_related_prolly_lod = stru_50C198._427546(a2 + 2500);
-					pSpellSprite.uFacing = v687;
-					pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-					if ( pParty->bTurnBasedModeOn == 1 )
-						pSpellSprite.uAttributes = 4;
-					if ( pSpellSprite.Create(v687, SHIDWORD(v687), pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed, 0) != -1
-						&& pParty->bTurnBasedModeOn == 1 )
-						++pTurnEngine->field_1C;
-					j = rand() % 1024 - 512;
-					k = rand() % 1024 - 512;
-				}
-				while ( i-- != 1 );
-			}
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_FIRE_INFERNO:
-		{
-			//v67 = 2;
-			if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor)
-			{
-				ShowStatusBarString(pGlobalTXT_LocalizationStrings[492], 2); // Can't cast Inferno outdoors!
-				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
-				continue;
-			}
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			auto _v726 = sub_46A6AC((int)dword_50BF30.data(), 100, 4096);
-			v700.z = 0;
-			v700.y = 0;
-			v700.x = 0;
-			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
-			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-			pSpellSprite.uAttributes = 0;
-			pSpellSprite.uSectorID = 0;
-			pSpellSprite.uSpriteFrameID = 0;
-			pSpellSprite.field_60_distance_related_prolly_lod = 0;
-			pSpellSprite.uFacing = 0;
-			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-			a2 = 0;
-			if ( (signed int)_v726 > 0 )
-			{
-				do
-				{
-					v162 = dword_50BF30[a2];
-					pSpellSprite.vPosition.x = pActors[v162].vPosition.x;
-					pSpellSprite.vPosition.y = pActors[v162].vPosition.y;
-					pSpellSprite.vPosition.z = pActors[v162].vPosition.z - (unsigned int)(signed __int64)((double)pActors[v162].uActorHeight * unk_4D8548);
-					pSpellSprite.spell_target_pid = PID(OBJECT_Actor, dword_50BF30[a2]);
-					v164 = pSpellSprite.Create(0, 0, 0, 0);
-					v165 = a2;
-					DamageMonsterFromParty(PID(OBJECT_Item, v164), dword_50BF30[a2], &v700);
-					pGame->GetStru6()->_4A81CA(&pSpellSprite);
-					pGame->GetStru6()->FadeScreen__like_Turn_Undead_and_mb_Armageddon(0xFF3C1Eu, 0x40u);
-					a2 = v165 + 1;
-				}
-				while ( v165 + 1 < (signed int)_v726 );
-			}
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_AIR_WIZARD_EYE:
-		{
-			LODWORD(v733) = 3600 * v2;
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			v168 = 0;
-			do
-			{
-				v169 = pOtherOverlayList->_4418B1(2000, v168++ + 100, 0, 65536);
-				v716 = v169;
-			}
-			while ( v168 < 4 );
-
-			pParty->pPartyBuffs[PARTY_BUFF_WIZARD_EYE].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, 0, 0, 0);
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_AIR_FEATHER_FALL:
-		{
-			switch (v731)
-			{
-				case 1: LODWORD(v733) = 300 * v2; break;
-				case 2: LODWORD(v733) = 600 * v2; break;
-				case 3: LODWORD(v733) = 3600 * v2; break;
-				case 4: LODWORD(v733) = 3600 * v2; break;
-				default:
-				assert(false);
-			}
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			v174 = 0;
-			do
-				pOtherOverlayList->_4418B1(2010, v174++ + 100, 0, 65536);
-			while ( v174 < 4 );
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
-
-			pParty->pPartyBuffs[PARTY_BUFF_FEATHER_FALL].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, 0, 0, 0);
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_AIR_SPARKS:
-		{
-			switch (v731)
-			{
-				case 1: amount = 3; break;
-				case 2: amount = 5; break;
-				case 3: amount = 7; break;
-				case 4: amount = 9; break;
-				default:
-				assert(false);
-			}
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			auto _v726 = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360;
-			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
-			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-			pSpellSprite.vPosition.y = pParty->vPosition.y;
-			pSpellSprite.vPosition.x = pParty->vPosition.x;
-			pSpellSprite.uAttributes = 0;
-			pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
-			pSpellSprite.uSectorID = pIndoor->GetSector(
-								pParty->vPosition.x,
-								pParty->vPosition.y,
-								pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3);
-			pSpellSprite.uSpriteFrameID = 0;
-			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-			pSpellSprite.spell_target_pid = a2;
-			pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
-			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-			if ( pParty->bTurnBasedModeOn == 1 )
-				LOBYTE(pSpellSprite.uAttributes) |= 4u;
-			v188 = (signed int)_v726 / -2;
-			v189 = (signed int)_v726 / 2;
-			while ( v188 <= v189 )
-			{
-				pSpellSprite.uFacing = v188 + LOWORD(v715.uYawAngle);
-				if ( pSpellSprite.Create(
-						(signed __int16)(v188 + LOWORD(v715.uYawAngle)),
-						v715.uPitchAngle,
-						pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed,
-						pCastSpell->uPlayerID + 1) != -1
-						&& pParty->bTurnBasedModeOn == 1 )
-				    ++pTurnEngine->field_1C;
-				v188 += _v726 / (amount - 1);
-			}
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_AIR_JUMP:
-		{
-			if ( pParty->uFlags & PARTY_FLAGS_1_FALLING)
-			{
-				ShowStatusBarString(pGlobalTXT_LocalizationStrings[493], 2);  // Can't cast Jump while airborne!
-				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				break;
-			}
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			v191 = 0;
-			do
-				pOtherOverlayList->_4418B1(2040, v191++ + 100, 0, 65536);
-			while ( v191 < 4 );
-			BYTE1(pParty->uFlags) |= 1u;
-			pParty->uFallSpeed = 1000;
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_AIR_INVISIBILITY:
-		{
-			switch (v731)
-			{
-				case 1: LODWORD(v733) = 600 * v2; amount = v2; break;
-				case 2: LODWORD(v733) = 600 * v2; amount = 2 * v2; break;
-				case 3: LODWORD(v733) = 600 * v2; amount = 3 * v2; break;
-				case 4: LODWORD(v733) = 3600 * v2; amount = 4 * v2; break;
-				default:
-				assert(false);
-			}
-			if (pParty->uFlags & (PARTY_FLAGS_1_ALERT_RED | PARTY_FLAGS_1_ALERT_YELLOW))
-			{
-				ShowStatusBarString(pGlobalTXT_LocalizationStrings[638], 2);  // There are hostile creatures nearby!
-				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
-				continue;
-			}
-			if ( pPlayer->CanCastSpell(uRequiredMana) )
-			{
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
-
-				pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, amount, 0, 0);
-				LODWORD(v727) = 1;
-			}
-			break;
-		}
-		case SPELL_AIR_FLY:
-		{
-			if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
-			{
-				ShowStatusBarString(pGlobalTXT_LocalizationStrings[494], 2);  // Can not cast Fly indoors!
-				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				break;
-			}
-			if ( !pPlayers[pCastSpell->uPlayerID + 1]->GetMaxMana() )
-			{
-				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2);  // Spell failed
-				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				break;
-			}
-			LODWORD(v733) = 3600 * v2;
-			if ( v731 == 1 || v731 == 2 || v731 == 3 )
-				amount = 1;
-			else
-				amount = 0;
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			v205 = 0;
-			do
-				pOtherOverlayList->_4418B1(2090, v205++ + 100, 0, 65536);
-			while ( v205 < 4 );
-			v206 = pOtherOverlayList->_4418B1(10008, 203, 0, 65536);
-			v207 = pCastSpell->uPlayerID + 1;
-			v716 = v206;
-
-			pParty->pPartyBuffs[PARTY_BUFF_FLY].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, amount, v206, v207);
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_AIR_STARBURST:
-		{
-			//v67 = 2;
-			if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
-			{
-				ShowStatusBarString(pGlobalTXT_LocalizationStrings[495], 2);  // Can't cast Starburst indoors!
-				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
-				continue;
-			}
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			v208 = PID_TYPE(a2);
-			LODWORD(v725) = PID_TYPE(a2);
-			if ( v208 == 3 )
-			{
-				v209 = PID_ID(a2);
-				LODWORD(v718) = pActors[v209].vPosition.x;
-				v210 = pActors[v209].vPosition.y;
-				v211 = pActors[v209].vPosition.z;
-				v713 = v210;
-			}
-			else
-			{
-				v212 = stru_5C6E00->Cos(pParty->sRotationY);
-				LODWORD(v718) = pParty->vPosition.x + sub_42EBBE(2048, v212);
-				v213 = stru_5C6E00->Sin(pParty->sRotationY);
-				v214 = sub_42EBBE(2048, v213);
-				v211 = pParty->vPosition.z;
-				v713 = pParty->vPosition.y + v214;
-				v208 = LODWORD(v725);
-			}
-			signed int _v733 = 0;
-			*(float *)&v732 = (double)v211;
-			LODWORD(v725) = v211 + 2500;
-			v721 = 0;
-			*(float *)&y = (double)(v211 + 2500);
-			v730 = v208 == 3 ? a2 : 0;
-			a2 = 20;
-			do
-			{
-				v215 = rand();
-				v216 = (double)v721;
-				v217 = (double)_v733;
-				*(float *)&uRequiredMana = v217;
-				_this = (ItemGen *)(v215 % 1000);
-				*((float *)&v733 + 1) = (double)(v215 % 1000) + *(float *)&v732 - *(float *)&y;
-				*(float *)&v721 = v217 * v217;
-				//*(float *)&v726 = v216 * v216;
-				if ( sqrt(*((float *)&v733 + 1) * *((float *)&v733 + 1) + v216 * v216 + *(float *)&v721) <= 1.0 )
-				{
-					LODWORD(v685) = 0;
-					HIDWORD(v685) = 0;
-				}
-				else
-				{
-					v684 = (signed __int64)sqrt(v216 * v216 + *(float *)&v721);
-					v685 = __PAIR__(
-								stru_5C6E00->Atan2(v684, (signed __int64)*((float *)&v733 + 1)),
-								stru_5C6E00->Atan2((signed __int64)v216, (signed __int64)*(float *)&uRequiredMana));
-				}
-				pSpellSprite.stru_24.Reset();
-				pSpellSprite.spell_id = pCastSpell->spellnum;
-				pSpellSprite.spell_level = v2;
-				pSpellSprite.spell_skill = v731;
-				pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-				pSpellSprite.uAttributes = 0;
-				pSpellSprite.vPosition.x = LODWORD(v718);
-				pSpellSprite.vPosition.y = v713;
-				pSpellSprite.uSectorID = 0;
-				pSpellSprite.vPosition.z = (int)((char *)_this + LODWORD(v725));
-				pSpellSprite.uSpriteFrameID = 0;
-				pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-				pSpellSprite.spell_target_pid = v730;
-				//__debugbreak();//
-				pSpellSprite.field_60_distance_related_prolly_lod = stru_50C198._427546((int)&_this[69].uNumCharges);
-				pSpellSprite.uFacing = v685;
-				pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-				if ( pParty->bTurnBasedModeOn == 1 )
-				pSpellSprite.uAttributes = 4;
-				if ( pSpellSprite.Create(v685, SHIDWORD(v685), pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed, 0) != -1
-					   && pParty->bTurnBasedModeOn == 1 )
-				  ++pTurnEngine->field_1C;
-				v721 = rand() % 1024 - 512;
-				v218 = rand();
-				v14 = a2-- == 1;
-				_v733 = (unsigned __int64)(v218 % 1024) - 512;
-			}
-			while ( !v14 );
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_WATER_AWAKEN:
-		{
-			switch (v731)
-			{
-				case 1: amount = 180 * v2; break;
-				case 2: amount = 3600 * v2; break;
-				case 3: amount = 86400 * v2; break;
-				case 4: amount = 0; break;
-				default:
-				assert(false);
-			}
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			for( int i=0; i < 4; i++ )
-			{
-				pPlayer = &pParty->pPlayers[i];
-				if ( v731 == 4 )
-				{
-					if ( pPlayer->pConditions[2] )
-					{
-						//*((int *)v222 + 4) = 0;
-						//*((int *)v222 + 5) = 0;
-						pPlayer->pConditions[2] = 0;
-						pPlayer->PlaySound(SPEECH_103, 0);
-					}
-				}
-				else
-				{
-					v223 = pPlayer->DiscardConditionIfLastsLongerThan(
-								2u,
-								pParty->uTimePlayed - (signed int)(signed __int64)((double)(amount << 7) * 0.033333335));
-					if ( v223 )
-						pPlayer->PlaySound(SPEECH_103, 0);
-				}
-			}
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_WATER_POISON_SPRAY:
-		{
-			switch (v731)
-			{
-				case 1: amount = 1; break;
-				case 2: amount = 3; break;
-				case 3: amount = 5; break;
-				case 4: amount = 7; break;
-				default:
-				assert(false);
-			}
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			signed int _v733 = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360;
-			if ( amount == 1 )
-			{
-				pSpellSprite.stru_24.Reset();
-				pSpellSprite.spell_id = pCastSpell->spellnum;
-				pSpellSprite.spell_skill = v731;
-				pSpellSprite.spell_level = v2;
-				pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-				pSpellSprite.vPosition.y = pParty->vPosition.y;
-				v51 = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
-				v671 = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
-				v660 = pParty->vPosition.y;
-//	LABEL_153:
-				pSpellSprite.uAttributes = 0;
-				pSpellSprite.vPosition.x = pParty->vPosition.x;
-				pSpellSprite.vPosition.z = v51;
-				v52 = pIndoor->GetSector(pParty->vPosition.x, v660, v671);
-				pSpellSprite.uSpriteFrameID = 0;
-				pSpellSprite.uSectorID = v52;
-				pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-				pSpellSprite.spell_target_pid = a2;
-				pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
-				pSpellSprite.uFacing = LOWORD(v715.uYawAngle);
-				pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-				if ( pParty->bTurnBasedModeOn == 1 )
-					LOBYTE(pSpellSprite.uAttributes) |= 4u;
-				v659 = pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed;
-				if ( pSpellSprite.Create(v715.uYawAngle, v715.uPitchAngle, v659, pCastSpell->uPlayerID + 1) != -1 && pParty->bTurnBasedModeOn == 1 )
-					++pTurnEngine->field_1C;
-			}
-			else
-			{
-				pSpellSprite.stru_24.Reset();
-				pSpellSprite.spell_id = pCastSpell->spellnum;
-				pSpellSprite.spell_level = v2;
-				pSpellSprite.spell_skill = v731;
-				pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-				pSpellSprite.vPosition.y = pParty->vPosition.y;
-				pSpellSprite.vPosition.x = pParty->vPosition.x;
-				pSpellSprite.uAttributes = 0;
-				pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
-				pSpellSprite.uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3);
-				pSpellSprite.uSpriteFrameID = 0;
-				pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-				pSpellSprite.spell_target_pid = a2;
-				pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
-				pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-				if ( pParty->bTurnBasedModeOn == 1 )
-					LOBYTE(pSpellSprite.uAttributes) |= 4u;
-				v227 = _v733 / -2;
-				signed int _y = _v733 / 2;
-				if ( _v733 / -2 <= _v733 / 2 )
-				{
-					v228 = v715.uYawAngle;
-					do
-					{
-						pSpellSprite.uFacing = v227 + v228;
-						if ( pSpellSprite.Create(
-								v227 + v228,
-								v715.uPitchAngle,
-								pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed,
-								pCastSpell->uPlayerID + 1) != -1
-								&& pParty->bTurnBasedModeOn == 1 )
-							++pTurnEngine->field_1C;
-						v227 += _v733 / (amount - 1);
-					}
-					while ( v227 <= _y );
-				}
-			}
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_WATER_WATER_WALK:
-		{
-			if ( !pPlayers[pCastSpell->uPlayerID + 1]->GetMaxMana() )
-			{
-				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2);  // Spell failed
-				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				break;
-			}
-			if ( v731 == 2 || v731 != 3 && v731 != 4 )
-				v229 = 600 * v2;
-			else
-				v229 = 3600 * v2;
-			LODWORD(v733) = v229;
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			v716 = pOtherOverlayList->_4418B1(10005, 201, 0, 65536);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
-
-			pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].Apply(
-				pParty->uTimePlayed + (signed int)(signed __int64)((double)(v229 << 7) * 0.033333335),
-				v731,
-				amount,
-				v716,
-				pCastSpell->uPlayerID + 1);
-			if ( v731 == 4 )
-				pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].uFlags = 1;
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_WATER_RECHARGE_ITEM:
-		{
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			v240 = &pParty->pPlayers[pCastSpell->uPlayerID_2].pInventoryItems[a2];
-			
-			if ( pItemsTable->pItems[v240->uItemID].uEquipType != 12 || v240->uAttributes & 2 )
-			{
-				dword_50C9D0 = 113;
-				dword_50C9D4 = 0;
-				dword_50C9D8 = 1;
-
-				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2);  // Spell failed
-				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
-				continue;
-			}
-			if ( v731 == 1 || v731 == 2 )
-			{
-				v241 = (double)v723 * 0.0099999998 + 0.5;
-			}
-			else if ( v731 == 3 )
-			{
-				v241 = (double)v723 * 0.0099999998 + 0.69999999;
-			}
-			else if ( v731 == 4 )
-			{
-				v241 = (double)v723 * 0.0099999998 + 0.80000001;
-			}
-			else
-			{
-				v241 = 0.0;
-			}
-			if ( v241 > 1.0 )
-				v241 = 1.0;
-			int uNewCharges = v240->uMaxCharges * v241;
-			v240->uMaxCharges = uNewCharges;
-			v240->uNumCharges = uNewCharges;
-			if ( uNewCharges <= 0 )
-			{
-				v240 = 0;
-				dword_50C9D0 = 113;
-				dword_50C9D4 = 0;
-				dword_50C9D8 = 1;
-				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2u);
-				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
-				v2 = v723;
-				continue;
-			}
-			v240->uAttributes |= 0x40u;
-			_50C9A8_item_enchantment_timer = 256;
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_WATER_ENCHANT_ITEM:
-		{
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			uRequiredMana = 0;
-			amount = 10 * v2;
-			v730 = 1;
-			pPlayer = &pParty->pPlayers[pCastSpell->uPlayerID_2];
-			v245 = &pPlayer->pInventoryItems[a2];
-			ItemDesc *_v725 = &pItemsTable->pItems[v245->uItemID];
-			if ( 
-				v731 == 1 || v731 == 2 && _v725->uEquipType > 2 ||
-				v731 == 3 || v731 == 4 && 
-				v245->uItemID <= 134 &&
-				v245->uSpecEnchantmentType == 0 &&
-				v245->uEnchantmentType == 0 &&
-				v245->_bonus_strength== 0 &&
-				!v245->Broken() )
-			{
-				if ( v245->GetValue() < 450 || 
-					(v245->GetValue() < 250 && (v731 == 3 || v731 == 4) && _v725->uEquipType >= 0 && _v725->uEquipType <= 2)
-					)
-				{
-					v730 = 0;
-				}
-				if ( rand() % 100 < 10 * v2 || 
-					(rand() % 100 < 80 && (v731 == 3 || v731 == 4 )) ||
-					v245->GetValue() < 450 || 
-					(v245->GetValue() < 250 && (v731 == 3 || v731 == 4) && v271 >= 0 && v271 <= 2)
-					)
-				{
-					v313 = _v725->uEquipType;
-					if ( _v725->uEquipType >= 3 && _v725->uEquipType <= 11 )
-					{
-						v295 = rand() % 10;// pItemsTable->field_116D8[pItemsTable->pItems[_this->uItemID].uEquipType];
-						v245->uEnchantmentType = 0;
-						for ( kk = pItemsTable->pEnchantments[0].to_item[pItemsTable->pItems[v245->uItemID].uEquipType + 1];
-							;
-							kk += pItemsTable->pEnchantments[v294->uEnchantmentType].to_item[pItemsTable->pItems[v245->uItemID].uEquipType + 1] )
-						{
-							++v245->uEnchantmentType;
-							if ( kk >= v295 )
-								break;
-						}
-						v255 = 10;//pItemsTable->field_116D8[17];
-						v256 = 10;//pItemsTable->field_116D8[16];
-						v245->_bonus_strength = v256 + rand() % (v255 - v256 + 1);
-						v245->uAttributes |= 0x20u;
-						_50C9A8_item_enchantment_timer = 256;
-						LODWORD(v727) = 1;
-						break;
-					}
-					else if ( v731 == 3 || v731 == 4)
-					{
-					v257 = pItemsTable->pSpecialEnchantments_count;
-					v258 = 0;
-					v725 = 0.0;
-					int _v733 = 0;
-					if ( pItemsTable->pSpecialEnchantments_count > 0 )
-					{
-						v730 = (int)&v679;
-						do
-						{
-							v259 = LOBYTE(pItemsTable->pSpecialEnchantments[v258 + 1].pBonusStatement);
-							if ( !v259 || v259 == 1 )
-							{
-								v260 = *(&pItemsTable->pSpecialEnchantments[0].to_item_apply[pItemsTable->pItems[*(int *)v245].uEquipType
-																					+ 4]
-										+ v258 * 28);
-								LODWORD(v725) += v260;
-								if ( v260 )
-								{
-									v261 = v730;
-									v730 += 4;
-									*(int *)v261 = _v733;
-								}
-							}
-							++_v733;
-							++v258;
-						}
-						while ( _v733 < v257 );
-					}
-					v262 = rand() % SLODWORD(v725);
-					v263 = v679;
-					v245->uSpecEnchantmentType = v679[0];
-					v264 = pItemsTable->pSpecialEnchantments[*v263].to_item_apply[pItemsTable->pItems[*(int *)v245].uEquipType + 4];
-					v265 = v262 + 1;
-					if ( v264 < v265 )
-					{
-						for ( ii = v679; ; ii = (int *)v732 )
-						{
-							v267 = (int)(ii + 1);
-							v732 = v267;
-							v268 = *(int *)v267;
-							*(int *)(v245 + 12) = v268;
-							v264 += pItemsTable->pSpecialEnchantments[v268].to_item_apply[pItemsTable->pItems[*(int *)v245].uEquipType
-																				+ 4];
-							if ( v264 >= v265 )
-								break;
-						}
-					}
-
-						v277 = pItemsTable->pSpecialEnchantments_count;
-						v278 = 0;
-						v725 = 0.0;
-						_v733 = 0;
-						if ( pItemsTable->pSpecialEnchantments_count > 0 )
-						{
-							int *_v730 = v679;
-							do
-							{
-								v279 = LOBYTE(pItemsTable->pSpecialEnchantments[v278].pBonusStatement);
-								if ( !v279 || v279 == 1 )
-								{
-									v280 = *(&pItemsTable->pSpecialEnchantments[v278].to_item_apply[pItemsTable->pItems[v245->uItemID].uEquipType]);
-									_v733 += v280;
-									if ( v280 )
-									{
-										v281 = _v730;
-										++_v730;
-										*v281 = _v733;
-									}
-								}
-								++_v733;
-								++v278;
-							}
-							while ( _v733 < v277 );
-						}
-						v282 = rand() % _v733;
-						v283 = v679;
-						v245->uSpecEnchantmentType = v679[0];
-						v284 = pItemsTable->pSpecialEnchantments[*v283].to_item_apply[pItemsTable->pItems[v245->uItemID].uEquipType ];
-						v285 = v282 + 1;
-						for ( l = v679; v284 < v285; ++l )
-						{
-							v245->uSpecEnchantmentType = *(l+1);
-							v284 += pItemsTable->pSpecialEnchantments[*(l+1)].to_item_apply[pItemsTable->pItems[v245->uItemID].uEquipType];
-						}
-						++v245->uSpecEnchantmentType;
-						v245->uAttributes |= 0x20u;
-						_50C9A8_item_enchantment_timer = 256;
-						LODWORD(v727) = 1;
-						break;
-					}
-				}
-				else
-				{
-					if ( !(BYTE1(v245->uAttributes) & 2) )
-					{
-						v245->uAttributes |= 2;
-					}
-				}
-						
-			}
-
-			if ( LODWORD(v727) == 0 )
-			{
-				v317 = pGlobalTXT_LocalizationStrings[428];
-				if ( v730 == 0 )
-					v317 = pGlobalTXT_LocalizationStrings[585];
-				ShowStatusBarString(v317, 2u);
-				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				v318 =  &pParty->pPlayers[pCastSpell->uPlayerID_2];
-				pCastSpell->spellnum = 0;
-				v318->PlaySound(SPEECH_43, 0);
-			}
-
-			break;
-		}
-		case SPELL_WATER_TOWN_PORTAL:
-		{
-			amount = 10 * v2;
-			if ( pPlayer->sMana < (signed int)uRequiredMana )
-				break;
-			if ( pParty->uFlags & (PARTY_FLAGS_1_ALERT_RED | PARTY_FLAGS_1_ALERT_YELLOW) && v731 != 4 || rand() % 100 >= amount && v731 != 4 )
-			{
-				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
-				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
-				continue;
-			}
-			town_portal_caster_id = LOBYTE(pCastSpell->uPlayerID);
-			pMessageQueue_50CBD0->AddMessage(UIMSG_OnCastTownPortal, 0, 0);
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_WATER_LLOYDS_BEACON:
-		{
-			LODWORD(v733) = 604800 * v2;
-			if ( !_stricmp(pCurrentMapName.data(), "d05.blv") )
-			{
-				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
-				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
-				continue;
-			}
-			v319 = uRequiredMana;
-			if ( pPlayer->sMana >= (signed int)uRequiredMana )
-			{
-				pEventTimer->Pause();
-				pMessageQueue_50CBD0->AddMessage(UIMSG_OnCastLloydsBeacon, 0, 0);
-				qword_506350 = (signed int)v733;
-				_506348_current_lloyd_playerid = pCastSpell->uPlayerID;
-				::uRequiredMana = v319;
-				::sRecoveryTime = sRecoveryTime;
-				dword_50633C = pCastSpell->sound_id;
-				dword_506338 = pCastSpell->spellnum;
-				LOBYTE(pCastSpell->field_8) |= 0x20u;
-			}
-			break;
-		}
-		case SPELL_EARTH_STONE_TO_FLESH:
-		{
-			__debugbreak(); // missing GM ?
-			switch (v731)
-			{
-				case 1: amount = 3600 * v2; break;
-				case 2: amount = 3600 * v2; break;
-				case 3: amount = 86400 * v2; break;
-				case 4: break;
-				default:
-				assert(false);
-			}
-	//LABEL_634:
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			v323 = pCastSpell->uPlayerID_2;
-			v324 = (char *)&pParty->pPlayers[v323].pConditions[15];
-			if ( !pParty->pPlayers[v323].pConditions[15] )
-			{
-				LODWORD(v727) = 1;
-				break;
-			}
-			if ( v731 == 4 )
-			{
-				*(int *)v324 = 0;
-				*((int *)v324 + 1) = 0;
-				LODWORD(v727) = 1;
-				break;
-			}
-			v732 = amount << 7;
-			v663 = (signed __int64)((double)(signed __int64)pParty->uTimePlayed - (double)(amount << 7) * 0.033333335);
-			v656 = 15;
-			v325 = &pParty->pPlayers[v323];
-			v325->DiscardConditionIfLastsLongerThan(v656, v663);
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_EARTH_ROCK_BLAST:
-		{
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
-			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-			pSpellSprite.vPosition.y = pParty->vPosition.y;
-			pSpellSprite.vPosition.x = pParty->vPosition.x;
-			pSpellSprite.uAttributes = 0;
-			pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
-			pSpellSprite.uSectorID = pIndoor->GetSector(
-								pParty->vPosition.x,
-								pParty->vPosition.y,
-								pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3);
-			pSpellSprite.uSpriteFrameID = 0;
-			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-			pSpellSprite.spell_target_pid = a2;
-			pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
-			pSpellSprite.uFacing = LOWORD(pParty->sRotationY);
-			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-			if ( pParty->bTurnBasedModeOn == 1 )
-				LOBYTE(pSpellSprite.uAttributes) |= 4u;
-
-			v659 = pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed;
-			if ( pSpellSprite.Create(pParty->sRotationY, pParty->sRotationX, v659, pCastSpell->uPlayerID + 1) != -1 && pParty->bTurnBasedModeOn == 1 )
-				++pTurnEngine->field_1C;
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_EARTH_DEATH_BLOSSOM:
-		{
-			if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
-			{
-				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
-				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
-				continue;
-			}
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			pSpellSprite.uType = 4090;
-			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
-			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-			pSpellSprite.vPosition.x = pParty->vPosition.x;
-			pSpellSprite.vPosition.y = pParty->vPosition.y;
-			pSpellSprite.uAttributes = 0;
-			pSpellSprite.uSectorID = 0;
-			pSpellSprite.uSpriteFrameID = 0;
-			pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
-			pSpellSprite.field_60_distance_related_prolly_lod = 0;
-			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-			pSpellSprite.spell_target_pid = a2;
-			pSpellSprite.uFacing = LOWORD(pParty->sRotationY);
-			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-			if ( pParty->bTurnBasedModeOn == 1 )
-				pSpellSprite.uAttributes = 4;
-
-			v659 = pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed;
-			if ( pSpellSprite.Create(pParty->sRotationY, stru_5C6E00->uIntegerHalfPi / 2, v659, 0) != -1 && pParty->bTurnBasedModeOn == 1 )
-				++pTurnEngine->field_1C;
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_SPIRIT_DETECT_LIFE:
-		{
-			v328 = v731 - 2;
-			if ( v328 )
-			{
-				v329 = v328 - 1;
-				if ( v329 && v329 != 1 )
-					v330 = 600 * v2;
-				else
-					v330 = 3600 * v2;
-			}
-			else
-			{
-				v330 = 1800 * v2;
-			}
-			LODWORD(v733) = v330;
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
-
-			pParty->pPartyBuffs[PARTY_BUFF_DETECT_LIFE].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, 0, 0, 0);
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_SPIRIT_FATE:
-		{
-			switch (v731)
-			{
-				case 1: amount = 1 * v2; break;
-				case 2: amount = 2 * v2; break;
-				case 3: amount = 4 * v2; break;
-				case 4: amount = 6 * v2; break;
-				default:
-				assert(false);
-			}
-			LODWORD(v733) = 300;
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			v342 = pCastSpell->spell_target_pid;
-			if ( v342 == 0 )
-			{
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
-
-				pParty->pPlayers[pCastSpell->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_FATE].Apply(pParty->uTimePlayed + 1280, v731, amount, 0, 0);
-				LODWORD(v727) = 1;
-				break;
-			}
-			if (PID_TYPE(v342) == OBJECT_Actor)
-			{
-				v343 = PID_ID(v342);
-				HIDWORD(v344) = 0 + ((pParty->uTimePlayed + 1280) >> 32);
-				LODWORD(v344) = LODWORD(pParty->uTimePlayed) + 1280;
-				pActors[v343].pActorBuffs[11].Apply(v344, v731, amount, 0, 0);
-				BYTE2(pActors[v343].uAttributes) |= 8u;
-				//v672 = 0;
-				v661 = &pActors[v343];
-				pGame->GetStru6()->_4A7E89_sparkles_on_actor_after_it_casts_buff(v661, 0);
-			}
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_SPIRIT_REMOVE_CURSE:
-		{
-			switch (v731)
-			{
-				case 1: amount = 3600 * v2; break;
-				case 2: amount = 3600 * v2; break;
-				case 3: amount = 86400 * v2; break;
-				case 4: amount = 0; break;
-				default:
-				assert(false);
-			}
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			v351 = &pParty->pPlayers[pCastSpell->uPlayerID_2];
-			if ( !v351->pConditions[0] )
-			{
-				LODWORD(v727) = 1;
-				break;
-			}
-			if ( v731 == 4 )
-			{
-				LODWORD(v351->pConditions[0]) = 0;
-				HIDWORD(v351->pConditions[0]) = 0;
-			}
-			else
-			{
-				v732 = amount << 7;
-				v351->DiscardConditionIfLastsLongerThan(0, (signed __int64)((double)(signed __int64)pParty->uTimePlayed - (double)(amount << 7) * 0.033333335));
-				if ( HIDWORD(pParty->pPlayers[pCastSpell->uPlayerID_2].pConditions[0]) | LODWORD(pParty->pPlayers[pCastSpell->uPlayerID_2].pConditions[0]) )
-				{
-					LODWORD(v727) = 1;
-					break;
-				}
-			}
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_SPIRIT_PRESERVATION:
-		{
-			if ( v731 == 4 )
-				LODWORD(v733) = 900 * (v2 + 4);
-			else
-				LODWORD(v733) = 300 * (v2 + 12);
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			if ( v731 == 1 || v731 == 2 )
-			{
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
-				pParty->pPlayers[pCastSpell->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_PRESERVATION].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, 0, 0, 0);
-				LODWORD(v727) = 1;
-				break;
-			}
-			a2 = 0;
-			v717 = (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
-			v357 = pParty->pPlayers;//[0].pPlayerBuffs[11];
-			do
-			{
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, a2);
-				v357->pPlayerBuffs[PLAYER_BUFF_PRESERVATION].Apply(pParty->uTimePlayed + v717, v731, 0, 0, 0);
-				++a2;
-				++v357;// = (SpellBuff *)((char *)v357 + 6972);
-			}
-			while ( v357 <= &pParty->pPlayers[3] );
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_SPIRIT_TURN_UNDEAD:
-		{
-			if ( v731 == 1 || v731 == 2)
-				LODWORD(v733) = 60 * (v2 + 3);
-			else
-				LODWORD(v733) = 300 * v2 + 180;
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			auto _v726 = sub_46A6AC((int)dword_50BF30.data(), 100, 4096);
-			pGame->GetStru6()->FadeScreen__like_Turn_Undead_and_mb_Armageddon(0xFFFFFFu, 0xC0u);
-			++pSpellSprite.uType;
-			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
-			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-			pSpellSprite.uAttributes = 0;
-			pSpellSprite.uSectorID = 0;
-			pSpellSprite.uSpriteFrameID = 0;
-			pSpellSprite.field_60_distance_related_prolly_lod = 0;
-			pSpellSprite.uFacing = 0;
-			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-			for ( a2 = 0; a2 < (signed int)_v726; ++a2 )
-			{
-				v369 = &pActors[dword_50BF30[a2]];
-				if ( MonsterStats::BelongsToSupertype(v369->pMonsterInfo.uID, MONSTER_SUPERTYPE_UNDEAD) )
-				{
-					pSpellSprite.vPosition.x = v369->vPosition.x;
-					pSpellSprite.vPosition.y = v369->vPosition.y;
-					pSpellSprite.vPosition.z = v369->vPosition.z - (unsigned int)(signed __int64)((double)v369->uActorHeight * unk_4D8548);
-
-					pSpellSprite.spell_target_pid = PID(OBJECT_Actor, dword_50BF30[a2]);
-					pSpellSprite.Create(0, 0, 0, 0);
-					v369->pActorBuffs[4].Apply(
-						pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335),
-						v731, 0, 0, 0);
-				}
-			}
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_SPIRIT_RAISE_DEAD:
-		{
-			if ( v731 == 4 )
-				amount = 0;
-			else
-				amount = 86400 * v2;
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			pOtherOverlayList->_4418B1(5080, pCastSpell->uPlayerID_2 + 100, 0, 65536);
-			v373 = pCastSpell->uPlayerID_2;
-			if ( !(HIDWORD(pParty->pPlayers[v373].pConditions[14]) | LODWORD(pParty->pPlayers[v373].pConditions[14])) )
-			{
-				LODWORD(v727) = 1;
-				break;
-			}
-			v14 = v731 == 4;
-			pParty->pPlayers[v373].sHealth = 1;
-			if ( v14 )
-			{
-				v374 = pCastSpell->uPlayerID_2;
-				LODWORD(pParty->pPlayers[v374].pConditions[14]) = 0;
-				HIDWORD(pParty->pPlayers[v374].pConditions[14]) = 0;
-				v376 = pCastSpell->uPlayerID_2;
-				LODWORD(pParty->pPlayers[v376].pConditions[13]) = 0;
-				HIDWORD(pParty->pPlayers[v376].pConditions[13]) = 0;
-			}
-			else
-			{
-				*(float *)&a2 = (double)(amount << 7) * 0.033333335;
-				pParty->pPlayers[pCastSpell->uPlayerID_2].DiscardConditionIfLastsLongerThan(
-				0xEu,
-				(signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2));
-				pParty->pPlayers[pCastSpell->uPlayerID_2].DiscardConditionIfLastsLongerThan(
-				0xDu,
-				(signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2));
-			}
-			v377 = &pParty->pPlayers[pCastSpell->uPlayerID_2];
-			v377->SetCondition(1, 0);
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_SPIRIT_SHARED_LIFE:
-		{
-			if ( v731 == 4 )
-				amount = 4 * v2;
-			else
-				amount = 3 * v2;
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			v381 = 0;
-			signed int _v733 = amount;
-			v730 = 0;
-			v382 = 1;
-			do
-			{
-				v383 = pPlayers[v382];
-				if ( !v383->pConditions[14] && !v383->pConditions[15] && !v383->pConditions[16] )
-				v682[v381++] = v382;
-				++v382;
-			}
-			while ( v382 <= 4 );
-			v384 = 0;
-			v730 = v381;
-			if ( v381 > 0 )
-			{
-				do
-					_v733 += pPlayers[v682[v384++]]->sHealth;
-				while ( v384 < v381 );
-			}
-			v732 = (signed __int64)((double)_v733 / (double)v730);
-			_v733 = 0;
-			if ( v381 > 0 )
-			{
-				do
-				{
-					//v385 = (ItemGen **)&pPlayers[v682[HIDWORD(v733)]];
-					v726 = pPlayers[v682[_v733]];
-					v726->sHealth = v732;
-					//v386 = v726->GetMaxHealth();
-					if ( v726->sHealth > v726->GetMaxHealth())
-						v726->sHealth = v726->GetMaxHealth();
-					if ( v726->sHealth > 0 )
-					{
-						v726->pConditions[Player::Condition_Unconcious] = 0;
-					}
-					v388 = _v733;
-
-					pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, LOWORD(v682[_v733]) - 1);
-					_v733 = v388 + 1;
-				}
-				while ( v388 + 1 < v730 );
-			}
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_SPIRIT_RESSURECTION:
-		{
-			switch (v731)
-			{
-				case 1: amount = 180 * v2; break;
-				case 2: amount = 10800 * v2; break;
-				case 3: amount = 259200 * v2; break;
-				case 4: amount = 0; break;
-				default:
-				assert(false);
-			}
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			v396 = pCastSpell->uPlayerID_2;
-			if ( HIDWORD(pParty->pPlayers[v396].pConditions[16]) | LODWORD(pParty->pPlayers[v396].pConditions[16])
-				|| HIDWORD(pParty->pPlayers[v396].pConditions[14]) | LODWORD(pParty->pPlayers[v396].pConditions[14]) )
-			{
-				if ( !(HIDWORD(pParty->pPlayers[v396].pConditions[1]) | LODWORD(pParty->pPlayers[v396].pConditions[1])) )
-					pParty->pPlayers[v396].PlaySound(SPEECH_25, 0);
-				if ( v731 == 4 )
-				{
-					v397 = pCastSpell->uPlayerID_2;
-					LODWORD(pParty->pPlayers[v397].pConditions[16]) = 0;
-					HIDWORD(pParty->pPlayers[v397].pConditions[16]) = 0;
-					v398 = pCastSpell->uPlayerID_2;
-					LODWORD(pParty->pPlayers[v398].pConditions[14]) = 0;
-					HIDWORD(pParty->pPlayers[v398].pConditions[14]) = 0;
-					v399 = pCastSpell->uPlayerID_2;
-					LODWORD(pParty->pPlayers[v399].pConditions[13]) = 0;
-					HIDWORD(pParty->pPlayers[v399].pConditions[13]) = 0;
-				}
-				else
-				{
-					*(float *)&a2 = (double)(amount << 7) * 0.033333335;
-					pParty->pPlayers[pCastSpell->uPlayerID_2].DiscardConditionIfLastsLongerThan( 0x10u,
-						(signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2));
-					pParty->pPlayers[pCastSpell->uPlayerID_2].DiscardConditionIfLastsLongerThan( 0xEu,
-						(signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2));
-					pParty->pPlayers[pCastSpell->uPlayerID_2].DiscardConditionIfLastsLongerThan( 0xDu,
-						(signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2));
-				}
-				pParty->pPlayers[pCastSpell->uPlayerID_2].SetCondition(1u, 1);
-				pParty->pPlayers[pCastSpell->uPlayerID_2].sHealth = 1;
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
-			}
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_MIND_CURE_PARALYSIS:
-		{
-			switch (v731)
-			{
-				case 1: amount = 3600 * v2; break;
-				case 2: amount = 3600 * v2; break;
-				case 3: amount = 86400 * v2; break;
-				case 4: amount = 0; break;
-				default:
-				assert(false);
-			}
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
-			v323 = pCastSpell->uPlayerID_2;
-			v324 = (char *)&pParty->pPlayers[v323].pConditions[12];
-			if ( !pParty->pPlayers[v323].pConditions[12] )
-			{
-				LODWORD(v727) = 1;
-				break;
-			}
-			if ( v731 == 4 )
-			{
-				*(int *)v324 = 0;
-				*((int *)v324 + 1) = 0;
-				LODWORD(v727) = 1;
-				break;
-			}
-			v663 = (signed __int64)((double)(signed __int64)pParty->uTimePlayed - (double)(amount << 7) * 0.033333335);
-			v656 = 12;
-			v325 = &pParty->pPlayers[v323];
-			v325->DiscardConditionIfLastsLongerThan(v656, v663);
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_MIND_REMOVE_FEAR:
-		{
-			switch (v731)
-			{
-				case 1: amount = 180 * v2; break;
-				case 2: amount = 3600 * v2; break;
-				case 3: amount = 86400 * v2; break;
-				case 4: amount = 0; break;
-				default:
-				assert(false);
-			}
-
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
-			v323 = pCastSpell->uPlayerID_2;
-			v324 = (char *)&pParty->pPlayers[v323].pConditions[3];
-			if ( !pParty->pPlayers[v323].pConditions[3] )
-			{
-				LODWORD(v727) = 1;
-				break;
-			}
-			if ( v731 == 4 )
-			{
-				*(int *)v324 = 0;
-				*((int *)v324 + 1) = 0;
-				LODWORD(v727) = 1;
-				break;
-			}
-			v663 = (signed __int64)((double)(signed __int64)pParty->uTimePlayed - (double)(amount << 7) * 0.033333335);
-			v656 = 3;
-			v325 = &pParty->pPlayers[v323];
-			v325->DiscardConditionIfLastsLongerThan(v656, v663);
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_MIND_TELEPATHY:
-		{
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			if (PID_TYPE(a2) != OBJECT_Actor)
-			{
-				LODWORD(v727) = 1;
-				break;
-			}
-			v417 = &pActors[PID_ID(a2)];
-			Actor * _v730 = v417;
-			if ( !(BYTE2(v417->uAttributes) & 0x80) )
-			{
-				v417->SetRandomGoldIfTheresNoItem();
-				v417 = _v730;
-			}
-			v418 = v417->array_000234[3].uItemID;
-			signed int _v733 = 0;
-			if ( pItemsTable->pItems[v418].uEquipType == 18 )
-				_v733 = v417->array_000234[3].uSpecEnchantmentType;
-
-			//ItemGen::ItemGen(&v683);
-			v683.Reset();
-
-			v419 = _v730->uCarriedItemID;
-			if (v419)
-			{
-				v683.uItemID = v419;
-				//goto LABEL_799;
-			}
-			else
-			{
-				v420 = 0;
-				v421 = _v730->array_000234;
-				while ( !v421->uItemID || pItemsTable->pItems[v421->uItemID].uEquipType == 18 )
-				{
-					++v420;
-					++v421;
-					if ( v420 >= 4 )
-						break;
-				}
-				if ( v420 < 4 )
-				{
-					memcpy(&v683, &_v730->array_000234[v420], sizeof(v683));
-					v2 = v723;
-					//v1 = 0;
-				}
-			}
-//	LABEL_799:
-			if ( _v733 != 0 )
-			{
-				v675 = _v733;
-				if (v683.uItemID)
-				{
-					v422 = v683.GetDisplayName();
-					sprintf(pTmpBuf2.data(), "(%s), and %d gold", v422, v675);
-
-				}
-				else
-				{
-					v664 = "%d gold";
-					sprintf(pTmpBuf2.data(), v664, v675);
-				}
-			}
-			else
-			{
-				if (v683.uItemID)
-				{
-					const char *_v675 = v683.GetDisplayName();
-					v664 = "(%s)";
-					sprintf(pTmpBuf2.data(), v664, _v675);
-				}
-				else
-				{
-					strcpy(pTmpBuf2.data(), "nothing");
-					ShowStatusBarString(pTmpBuf2.data(), 2u);
-				}
-			}
-			ShowStatusBarString(pTmpBuf2.data(), 2u);
-			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
-			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-			pSpellSprite.vPosition.x = _v730->vPosition.x;
-			pSpellSprite.vPosition.y = _v730->vPosition.y;
-			v676 = _v730->uActorHeight;
-			v665 = pSpellSprite.vPosition.y;
-			pSpellSprite.vPosition.z = _v730->uActorHeight;
-			v657 = pSpellSprite.vPosition.x;
-			pSpellSprite.uAttributes = 0;
-			pSpellSprite.uSectorID = pIndoor->GetSector(v657, v665, v676);
-			pSpellSprite.uSpriteFrameID = 0;
-			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-			pSpellSprite.spell_target_pid = a2;
-			pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
-			pSpellSprite.uFacing = LOWORD(v715.uYawAngle);
-			LOBYTE(pSpellSprite.uAttributes) |= 0x80u;
-			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-			pSpellSprite.Create(0, 0, 0, pCastSpell->uPlayerID + 1);
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_MIND_BERSERK:
-		{
-			switch (v731)
-			{
-				case 1: amount = 300 * v2; break;
-				case 2: amount = 300 * v2; break;
-				case 3: amount = 600 * v2; break;
-				case 4: amount = 3600; break;
-				default:
-				assert(false);
-			}
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			v426 = PID_ID(a2);
-			if (PID_TYPE(a2) != OBJECT_Actor)
-			{
-				LODWORD(v727) = 1;
-				break;
-			}
-			v730 = 836 * v426;
-			if ( stru_50C198.GetMagicalResistance(&pActors[v426], 7u) )
-			{
-				pActors[v426].pActorBuffs[1].Reset();
-				pActors[v426].pActorBuffs[12].Reset();
-				pActors[v426].pActorBuffs[9].Apply(
-				pParty->uTimePlayed + (signed __int64)((double)(amount << 7) * 0.033333335),
-				v731, 0, 0, 0);
-				pActors[v426].pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Long;
-			}
-			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
-			v60 = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-			v61 = v426;
-			v600 = pActors[v61].vPosition.y;
-			v601 = pActors[v61].vPosition.x;
-			pSpellSprite.uObjectDescID = v60;
-			pSpellSprite.vPosition.x = v601;
-			v602 = pActors[v61].uActorHeight;
-			v603 = pActors[v61].vPosition.z;
-			pSpellSprite.vPosition.y = v600;
-			v676 = v603 + v602;
-			v665 = v600;
-			pSpellSprite.vPosition.z = v603 + v602;
-			v657 = v601;
-			pSpellSprite.uAttributes = 0;
-			pSpellSprite.uSectorID = pIndoor->GetSector(v657, v665, v676);
-			pSpellSprite.uSpriteFrameID = 0;
-			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-			pSpellSprite.spell_target_pid = a2;
-			pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
-			pSpellSprite.uFacing = LOWORD(v715.uYawAngle);
-			LOBYTE(pSpellSprite.uAttributes) |= 0x80u;
-			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-			pSpellSprite.Create(0, 0, 0, pCastSpell->uPlayerID + 1);
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_MIND_ENSLAVE:
-		{
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			amount = 600 * v2;
-			if (PID_TYPE(a2) != OBJECT_Actor)
-			{
-				LODWORD(v727) = 1;
-				break;
-			}
-			v730 = 836 * PID_ID(a2);
-			if ( MonsterStats::BelongsToSupertype(pActors[PID_ID(a2)].pMonsterInfo.uID, MONSTER_SUPERTYPE_UNDEAD) )
-				break;
-			if ( stru_50C198.GetMagicalResistance(&pActors[PID_ID(a2)], 7u) )
-			{
-				pActors[PID_ID(a2)].pActorBuffs[9].Reset();
-				pActors[PID_ID(a2)].pActorBuffs[1].Reset();
-				pActors[PID_ID(a2)].pActorBuffs[12].Apply(pParty->uTimePlayed + (signed __int64)((double)(amount << 7) * 0.033333335),
-				v731, 0, 0, 0);
-			}
-			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
-			v60 = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-			v61 = PID_ID(a2);
-			v600 = pActors[v61].vPosition.y;
-			v601 = pActors[v61].vPosition.x;
-			pSpellSprite.uObjectDescID = v60;
-			pSpellSprite.vPosition.x = v601;
-			v602 = pActors[v61].uActorHeight;
-			v603 = pActors[v61].vPosition.z;
-			pSpellSprite.vPosition.y = v600;
-			v676 = v603 + v602;
-			v665 = v600;
-			pSpellSprite.vPosition.z = v603 + v602;
-			v657 = v601;
-			pSpellSprite.uAttributes = 0;
-			pSpellSprite.uSectorID = pIndoor->GetSector(v657, v665, v676);
-			pSpellSprite.uSpriteFrameID = 0;
-			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-			pSpellSprite.spell_target_pid = a2;
-			pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
-			pSpellSprite.uFacing = LOWORD(v715.uYawAngle);
-			LOBYTE(pSpellSprite.uAttributes) |= 0x80u;
-			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-			pSpellSprite.Create(0, 0, 0, pCastSpell->uPlayerID + 1);
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_MIND_MASS_FEAR:
-		{
-			if ( v731 == 4 )
-				amount = 300 * v2;
-			else
-				amount = 180 * v2;
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			auto _v726 = sub_46A6AC((int)dword_50BF30.data(), 100, 4096);
-			pGame->GetStru6()->FadeScreen__like_Turn_Undead_and_mb_Armageddon(0xA0A0Au, 0xC0u);
-			++pSpellSprite.uType;
-			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
-			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-			pSpellSprite.uAttributes = 0;
-			pSpellSprite.uSectorID = 0;
-			pSpellSprite.uSpriteFrameID = 0;
-			pSpellSprite.field_60_distance_related_prolly_lod = 0;
-			pSpellSprite.uFacing = 0;
-			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-			for ( a2 = 0; a2 < (signed int)_v726; ++a2 )
-			{
-				v433 = &pActors[dword_50BF30[a2]];
-				if ( MonsterStats::BelongsToSupertype(v433->pMonsterInfo.uID, MONSTER_SUPERTYPE_UNDEAD) )
-					break;
-				pSpellSprite.vPosition.x = v433->vPosition.x;
-				pSpellSprite.vPosition.y = v433->vPosition.y;
-				pSpellSprite.vPosition.z = v433->vPosition.z - (unsigned int)(signed __int64)((double)v433->uActorHeight * unk_4D8548);
-
-				pSpellSprite.spell_target_pid = PID(OBJECT_Actor, dword_50BF30[a2]);
-				pSpellSprite.Create(0, 0, 0, 0);
-				if ( stru_50C198.GetMagicalResistance(v433, 7u) )
-				{
-					v433->pActorBuffs[4].Apply(pParty->uTimePlayed + (signed __int64)((double)(amount << 7) * 0.033333335),
-						v731, 0, 0, 0);
-				}
-			}
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_MIND_CURE_INSANITY:
-		{
-			v435 = v731 - 2;
-			if ( v731 == 4 )
-				amount = 0;
-			else
-				amount = 86400 * v2;
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
-			v440 = pCastSpell->uPlayerID_2;
-			if ( HIDWORD(pParty->pPlayers[v440].pConditions[5]) | LODWORD(pParty->pPlayers[v440].pConditions[5]) )
-			{
-				if ( !(HIDWORD(pParty->pPlayers[v440].pConditions[1]) | LODWORD(pParty->pPlayers[v440].pConditions[1])) )
-					pParty->pPlayers[v440].PlaySound(SPEECH_25, 0);
-				if ( v731 == 4 )
-				{
-					v441 = pCastSpell->uPlayerID_2;
-					LODWORD(pParty->pPlayers[v441].pConditions[5]) = 0;
-					HIDWORD(pParty->pPlayers[v441].pConditions[5]) = 0;
-				}
-				else
-				{
-					pParty->pPlayers[pCastSpell->uPlayerID_2].DiscardConditionIfLastsLongerThan(5u,
-						(signed __int64)((double)(signed __int64)pParty->uTimePlayed - (double)(amount << 7) * 0.033333335));
-				}
-				v377 = &pParty->pPlayers[pCastSpell->uPlayerID_2];
-				v377->SetCondition(1, 0);
-			}
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_EARTH_TELEKINESIS:
-		{
-			switch (v731)
-			{
-				case 1: amount = 2 * v2; break;
-				case 2: amount = 2 * v2; break;
-				case 3: amount = 3 * v2; break;
-				case 4: amount = 4 * v2; break;
-				default:
-				assert(false);
-			}
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			v445 = PID_ID(a2);
-			if (PID_TYPE(a2) == OBJECT_Item)
-			{
-				v449 = (char *)&pSpriteObjects[v445].stru_24;
-				v450 = *(int *)v449;
-				if ( pItemsTable->pItems[v450].uEquipType == 18 )
-				{
-					party_finds_gold(*((int *)v449 + 3), 0);
-					viewparams->bRedrawGameUI = 1;
-				}
-				else
-				{
-					sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[471], pItemsTable->pItems[v450].pUnidentifiedName);
-					ShowStatusBarString(pTmpBuf2.data(), 2u);
-					if ( !pParty->AddItem(&pSpriteObjects[v445].stru_24) )
-						pParty->SetHoldingItem(&pSpriteObjects[v445].stru_24);
-				}
-				SpriteObject::OnInteraction(v445);
-			}
-			else
-			{
-				if (PID_TYPE(a2) == OBJECT_Actor)
-				{
-					stru_50C198.LootActor(&pActors[v445]);
-				}
-				else
-				{
-					if (PID_TYPE(a2) != OBJECT_Decoration)
-					{
-						if (PID_TYPE(a2) != OBJECT_BModel)
-						{
-							LODWORD(v727) = 1;
-							break;
-						}
-						dword_507CD8 = 1;
-						v677 = 1;
-						if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
-							v446 = pIndoor->pFaceExtras[pIndoor->pFaces[v445].uFaceExtraID].uEventID;
-						else
-							v446 = pOutdoor->pBModels[a2 >> 9].pFaces[v445 & 0x3F].sCogTriggeredID;
-						EventProcessor(v446, a2, v677);
-						LODWORD(v727) = 1;
-						break;
-					}
-					v447 = &pLevelDecorations[v445];
-					dword_507CD8 = 1;
-					v448 = v447->field_16_event_id;
-					if (v448)
-					{
-						v677 = 1;
-						v446 = v448;
-						EventProcessor(v446, a2, v677);
-						LODWORD(v727) = 1;
-						break;
-					}
-					if ( v447->IsInteractive() )
-					{
-						activeLevelDecoration = v447;
-						EventProcessor(stru_5E4C90._decor_events[v447->_idx_in_stru123 - 75] + 380, 0, 1);
-						activeLevelDecoration = NULL;
-					}
-				}
-			}
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_BODY_CURE_WEAKNESS:
-		{
-			switch (v731)
-			{
-				case 1: amount = 180 * v2; break;
-				case 2: amount = 3600 * v2; break;
-				case 3: amount = 86400 * v2; break;
-				case 4: amount = 0; break;
-				default:
-				assert(false);
-			}
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
-			v323 = pCastSpell->uPlayerID_2;
-			v324 = (char *)&pParty->pPlayers[v323].pConditions[1];
-			if ( !pParty->pPlayers[v323].pConditions[1] )
-			{
-				LODWORD(v727) = 1;
-				break;
-			}
-			if ( v731 == 4 )
-			{
-				*(int *)v324 = 0;
-				*((int *)v324 + 1) = 0;
-				LODWORD(v727) = 1;
-				break;
-			}
-			v663 = (signed __int64)((double)(signed __int64)pParty->uTimePlayed - (double)(amount << 7) * 0.033333335);
-			v656 = 1;
-			v325 = &pParty->pPlayers[v323];
-			v325->DiscardConditionIfLastsLongerThan(v656, v663);
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_BODY_FIRST_AID:
-		{
-			switch (v731)
-			{
-				case 1: amount = 2 * v2 + 5; break;
-				case 2: amount = 3 * v2 + 5; break;
-				case 3: amount = 4 * v2 + 5; break;
-				case 4: amount = 5 * v2 + 5; break;
-				default:
-				assert(false);
-			}
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			v460 = pCastSpell->spell_target_pid;
-			if (!v460)
-			{
-				pParty->pPlayers[pCastSpell->uPlayerID_2].Heal(amount);
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
-			}
-			else
-			{
-				if (PID_TYPE(v460) == OBJECT_Actor)
-				{
-					v461 = &pActors[PID_ID(v460)];
-					v462 = v461->uAIState;
-					v463 = v461->pMonsterInfo.uHP;
-					if ( v462 != 5 )
-					{
-						if ( v462 != 4 )
-						{
-							if ( v462 != 19 )
-							{
-								if ( v462 != 11 )
-								{
-									v461->sCurrentHP += amount;
-									if ( v461->sCurrentHP > v463 )
-										v461->sCurrentHP = v463;
-								}
-							}
-						}
-					}
-				}
-			}
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_BODY_CURE_POISON:
-		{
-			switch (v731)
-			{
-				case 1: amount = 3600 * v2; break;
-				case 2: amount = 3600 * v2; break;
-				case 3: amount = 86400 * v2; break;
-				case 4: amount = 0; break;
-				default:
-				assert(false);
-			}
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
-			v470 = pCastSpell->uPlayerID_2;
-			if ( !(HIDWORD(pParty->pPlayers[v470].pConditions[6]) | LODWORD(pParty->pPlayers[v470].pConditions[6]))
-				&& !(HIDWORD(pParty->pPlayers[v470].pConditions[8]) | LODWORD(pParty->pPlayers[v470].pConditions[8]))
-				&& !(HIDWORD(pParty->pPlayers[v470].pConditions[10]) | LODWORD(pParty->pPlayers[v470].pConditions[10])) )
-			{
-				LODWORD(v727) = 1;
-				break;
-			}
-			if ( v731 == 4 )
-			{
-				LODWORD(pParty->pPlayers[v470].pConditions[6]) = 0;
-				HIDWORD(pParty->pPlayers[v470].pConditions[6]) = 0;
-				v471 = pCastSpell->uPlayerID_2;
-				LODWORD(pParty->pPlayers[v471].pConditions[8]) = 0;
-				HIDWORD(pParty->pPlayers[v471].pConditions[8]) = 0;
-				v472 = pCastSpell->uPlayerID_2;
-				LODWORD(pParty->pPlayers[v472].pConditions[10]) = 0;
-				HIDWORD(pParty->pPlayers[v472].pConditions[10]) = 0;
-				LODWORD(v727) = 1;
-				break;
-			}
-			*(float *)&a2 = (double)(amount << 7) * 0.033333335;
-			pParty->pPlayers[v470].DiscardConditionIfLastsLongerThan(
-				6u,
-				(signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2));
-			pParty->pPlayers[pCastSpell->uPlayerID_2].DiscardConditionIfLastsLongerThan(
-				8u,
-				(signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2));
-			v663 = (signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2);
-			v656 = 10;
-			v325 = &pParty->pPlayers[pCastSpell->uPlayerID_2];
-			v325->DiscardConditionIfLastsLongerThan(v656, v663);
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_BODY_PROTECTION_FROM_MAGIC:
-		{
-			amount = v2;
-			LODWORD(v733) = 3600 * v2;
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
-
-			pParty->pPartyBuffs[PARTY_BUFF_PROTECTION_FROM_MAGIC].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, v2, 0, 0);
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_BODY_HAMMERHANDS:
-		{
-			LODWORD(v733) = 3600 * v2;
-			amount = v2;
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			if ( v731 == 4 )
-			{
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
-				v732 = (int)v733 << 7;
-				v717 = (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
-				pParty->pPlayers[0].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].Apply(pParty->uTimePlayed + v717, 4u, v2, v2, 0);
-				pParty->pPlayers[1].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].Apply(pParty->uTimePlayed + v717, 4u, v2, v2, 0);
-				pParty->pPlayers[2].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].Apply(pParty->uTimePlayed + v717, 4u, v2, v2, 0);
-
-				pParty->pPlayers[3].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].Apply(pParty->uTimePlayed + v717, 4, v2, v2, 0);
-				LODWORD(v727) = 1;
-				break;
-			}
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
-
-			pParty->pPlayers[pCastSpell->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, v2, v2, 0);
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_BODY_CURE_DISEASE:
-		{
-			if ( v731 == 4 )
-				amount = 0;
-			else
-				amount = 86400 * v2;
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
-			v498 = pCastSpell->uPlayerID_2;
-			if ( !(HIDWORD(pParty->pPlayers[v498].pConditions[7]) | LODWORD(pParty->pPlayers[v498].pConditions[7]))
-				&& !(HIDWORD(pParty->pPlayers[v498].pConditions[9]) | LODWORD(pParty->pPlayers[v498].pConditions[9]))
-				&& !(HIDWORD(pParty->pPlayers[v498].pConditions[11]) | LODWORD(pParty->pPlayers[v498].pConditions[11])) )
-			{
-				LODWORD(v727) = 1;
-				break;
-			}
-			if ( v731 == 4 )
-			{
-				LODWORD(pParty->pPlayers[v498].pConditions[7]) = 0;
-				HIDWORD(pParty->pPlayers[v498].pConditions[7]) = 0;
-				v499 = pCastSpell->uPlayerID_2;
-				LODWORD(pParty->pPlayers[v499].pConditions[9]) = 0;
-				HIDWORD(pParty->pPlayers[v499].pConditions[9]) = 0;
-				v500 = pCastSpell->uPlayerID_2;
-				LODWORD(pParty->pPlayers[v500].pConditions[11]) = 0;
-				HIDWORD(pParty->pPlayers[v500].pConditions[11]) = 0;
-			}
-			else
-			{
-				*(float *)&a2 = (double)(amount << 7) * 0.033333335;
-				pParty->pPlayers[v498].DiscardConditionIfLastsLongerThan(
-				7u,
-				(signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2));
-				pParty->pPlayers[pCastSpell->uPlayerID_2].DiscardConditionIfLastsLongerThan(
-				9u,
-				(signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2));
-				v663 = (signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2);
-				v656 = 11;
-				v325 = &pParty->pPlayers[pCastSpell->uPlayerID_2];
-				v325->DiscardConditionIfLastsLongerThan(v656, v663);
-			}
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_BODY_POWER_CURE:
-		{
-			amount = 5 * v2 + 10;
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			v501 = pParty->pPlayers;
-			int v1 = 0;
-			do
-			{
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, v1);
-				v501->Heal(amount);
-				++v501;
-				++v1;
-			}
-			while ( (signed int)v501 < (signed int)pParty->pHirelings );
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_LIGHT_DISPEL_MAGIC:
-		{
-			sRecoveryTime -= v2;
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-
-			pGame->GetStru6()->FadeScreen__like_Turn_Undead_and_mb_Armageddon(0xAFF0Au, 0xC0u);
-			v505 = sub_46A6AC((int)dword_50BF30.data(), 100, 4096);
-			++pSpellSprite.uType;
-			//signed int _v733 = v505;
-			v688.x = 0;
-			v688.y = 0;
-			v688.z = 0;
-			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
-			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-			pSpellSprite.uAttributes = 0;
-			pSpellSprite.uSectorID = 0;
-			pSpellSprite.uSpriteFrameID = 0;
-			pSpellSprite.field_60_distance_related_prolly_lod = 0;
-			pSpellSprite.uFacing = 0;
-			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-			a2 = 0;
-			for ( a2 = 0; a2 < v505; ++a2 )
-			{
-				v507 = dword_50BF30[a2];
-				pSpellSprite.vPosition.x = pActors[v507].vPosition.x;
-				pSpellSprite.vPosition.y = pActors[v507].vPosition.y;
-				pSpellSprite.vPosition.z = pActors[v507].vPosition.z - (unsigned int)(signed __int64)((double)pActors[v507].uActorHeight * unk_4D8548);
-				pSpellSprite.spell_target_pid = PID(OBJECT_Actor, dword_50BF30[a2]);
-				v509 = pSpellSprite.Create(0, 0, 0, 0);
-				DamageMonsterFromParty(PID(OBJECT_Item, v509), dword_50BF30[a2], &v688);
-			}
-			for ( a2 = 0; a2 < v505; ++a2 )
-			{
-				pActor = &pActors[dword_50BF30[a2]];
-				pSpellSprite.vPosition.x = pActor->vPosition.x;
-				pSpellSprite.vPosition.y = pActor->vPosition.y;
-				pSpellSprite.vPosition.z = pActor->vPosition.z - (unsigned int)(signed __int64)((double)pActor->uActorHeight * unk_4D8548);
-				pSpellSprite.spell_target_pid = PID(OBJECT_Actor, dword_50BF30[a2]);
-				pSpellSprite.Create(0, 0, 0, 0);
-				for (int i = 0; i < 22; ++i)
-				{
-					pActor->pActorBuffs[i].Reset();
-				}
-			}
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_LIGHT_SUMMON_ELEMENTAL:
-		{
-			switch (v731)
-			{
-				case 1: v733 = 300 * v2; amount = 1; break;
-				case 2: v733 = 300 * v2; amount = 1; break;
-				case 3: v733 = 900 * v2; amount = 3; break;
-				case 4: v733 = 900 * v2; amount = 5; break;
-				default:
-				assert(false);
-			}
-			//v733 = __PAIR__(0, v516);
-			signed int _v733 = 0;
-			if ( (signed int)uNumActors > 0 )
-			{
-				v518 = pActors.data();//[0].uAIState;
-				auto _v726 = uNumActors;
-				do
-				{
-					v519 = v518->uAIState;
-					if ( v518->uAIState != 5 && v519 != 11 && v519 != 19 && PID(OBJECT_Player, pCastSpell->uPlayerID) == v518->uSummonerID )
-						++_v733;
-					++v518;
-					--_v726;
-				}
-				while ( _v726 != 0 );
-			}
-			if ( _v733 >= amount )
-			{
-				ShowStatusBarString(pGlobalTXT_LocalizationStrings[648], 2);  // This character can't summon any more monsters!
-				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
-				continue;
-			}
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			sub_44FA4C_spawn_light_elemental(pCastSpell->uPlayerID, v731, v733);
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_LIGHT_DAY_OF_THE_GODS:
-		{
-			switch (v731)
-			{
-				case 1: LODWORD(v733) = 10800 * v2; amount = 3 * v2 + 10; break;
-				case 2: LODWORD(v733) = 10800 * v2; amount = 3 * v2 + 10; break;
-				case 3: LODWORD(v733) = 14400 * v2; amount = 4 * v2 + 10; break;
-				case 4: LODWORD(v733) = 18000 * v2; amount = 5 * v2 + 10; break;
-				default:
-				assert(false);
-			}
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
-
-			pParty->pPartyBuffs[PARTY_BUFF_DAY_OF_GODS].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, amount, 0, 0);
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_LIGHT_PRISMATIC_LIGHT:
-		{
-			//v67 = 2;
-			if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor)
-			{
-				ShowStatusBarString(pGlobalTXT_LocalizationStrings[497], 2);  // Can't cast Prismatic Light outdoors!
-				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
-				continue;
-			}
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			v531 = sub_46A6AC((int)dword_50BF30.data(), 100, 4096);
-			++pSpellSprite.uType;
-			v694.x = 0;
-			v694.y = 0;
-			v694.z = 0;
-			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
-			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-			pSpellSprite.uAttributes = 0;
-			pSpellSprite.uSectorID = 0;
-			pSpellSprite.uSpriteFrameID = 0;
-			pSpellSprite.field_60_distance_related_prolly_lod = 0;
-			pSpellSprite.uFacing = 0;
-			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-			a2 = 0;
-			if ( (signed int)v531 > 0 )
-			{
-				do
-				{
-					v533 = dword_50BF30[a2];
-					pSpellSprite.vPosition.x = pActors[v533].vPosition.x;
-					pSpellSprite.vPosition.y = pActors[v533].vPosition.y;
-					pSpellSprite.vPosition.z = pActors[v533].vPosition.z - (unsigned int)(signed __int64)((double)pActors[v533].uActorHeight * unk_4D8548);
-					pSpellSprite.spell_target_pid = PID(OBJECT_Actor, dword_50BF30[a2]);
-					v535 = pSpellSprite.Create(0, 0, 0, 0);
-					v536 = a2;
-					DamageMonsterFromParty(PID(OBJECT_Item, v535), dword_50BF30[a2], &v694);
-					a2 = v536 + 1;
-				}
-				while ( v536 + 1 < (signed int)v531 );
-			}
-			v537 = pGame->GetStru6();
-			pGame->GetStru6()->_4A8BFC();
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_LIGHT_DAY_OF_PROTECTION:
-		{
-			switch (v731)
-			{
-				case 1: LODWORD(v733) = 14400 * v2; amount = 4 * v2; break;
-				case 2: LODWORD(v733) = 14400 * v2; amount = 4 * v2; break;
-				case 3: LODWORD(v733) = 14400 * v2; amount = 4 * v2; break;
-				case 4: LODWORD(v733) = 18000 * v2; amount = 5 * v2; break;
-				default:
-				assert(false);
-			}
-			v730 = LODWORD(v733);
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
-
-			v732 = v730 << 7;
-			v549 = (double)(v730 << 7) * 0.033333335;
-			*((float *)&v733 + 1) = v549;
-			v712 = (signed __int64)v549;
-			pParty->pPartyBuffs[PARTY_BUFF_RESIST_BODY].Apply(pParty->uTimePlayed + (signed __int64)v549, v731, amount, 0, 0);
-			pParty->pPartyBuffs[PARTY_BUFF_RESIST_MIND].Apply(pParty->uTimePlayed + v712, v731, amount, 0, 0);
-			pParty->pPartyBuffs[PARTY_BUFF_RESIST_FIRE].Apply(pParty->uTimePlayed + v712, v731, amount, 0, 0);
-			pParty->pPartyBuffs[PARTY_BUFF_RESIST_WATER].Apply(pParty->uTimePlayed + v712, v731, amount, 0, 0);
-			pParty->pPartyBuffs[PARTY_BUFF_RESIST_AIR].Apply(pParty->uTimePlayed + v712, v731, amount, 0, 0);
-			pParty->pPartyBuffs[PARTY_BUFF_RESIST_EARTH].Apply(pParty->uTimePlayed + v712, v731, amount, 0, 0);
-			v550 = v2 + 5;
-			pParty->pPartyBuffs[PARTY_BUFF_FEATHER_FALL].Apply(
-				(signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733 + 1)),
-				v731,
-				v550, 0, 0);
-
-			pParty->pPartyBuffs[PARTY_BUFF_WIZARD_EYE].Apply((signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733 + 1)), v731, v550, 0, 0);
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_LIGHT_HOUR_OF_POWER:
-		{
-			switch (v731)
-			{
-				case 1: LODWORD(v733) = 4; amount = 4; break;
-				case 2: LODWORD(v733) = 4; amount = 4; break;
-				case 3: LODWORD(v733) = 12; amount = 12; break;
-				case 4: LODWORD(v733) = 20; amount = 15; break;
-				default:
-				assert(false);
-			}
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			y = (char *)(60 * (v2 * LODWORD(v733) + 60));
-			v732 = (300 * amount * v2 + 60) << 7;
-			v730 = v2 + 5;
-			int _v726 = 0;
-			v553 = pParty->pPlayers;//[0].pConditions[1];
-			*((float *)&v733) = (double)v732 * 0.033333335;
-			do
-			{
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
-
-				//((SpellBuff *)(v553 + 6056))->Apply(
-				v553->pPlayerBuffs[4].Apply((signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733)), v731, v730, 0, 0);
-				if ( *(_QWORD *)v553 )
-					_v726 = 1;
-				++v553;
-			}
-			while ( v553 <= &pParty->pPlayers[3] );
-			v562 = v731;
-			pParty->pPartyBuffs[PARTY_BUFF_HEROISM].Apply((signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733)), v731, v730, 0, 0);
-			pParty->pPartyBuffs[PARTY_BUFF_SHIELD].Apply((signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733)), v562, 0, 0, 0);
-			pParty->pPartyBuffs[PARTY_BUFF_STONE_SKIN].Apply((signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733)), v562, v730, 0, 0);
-			if (!_v726)
-			{
-				pParty->pPartyBuffs[PARTY_BUFF_HASTE].Apply((signed __int64)((double)(signed int)((int)y << 7) * 0.033333335 + (double)(signed __int64)pParty->uTimePlayed), v562, v730, 0, 0);
-			}
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_LIGHT_DIVINE_INTERVENTION:
-		{
-			amount = 3;
-			if ( pPlayer->uNumDivineInterventionCastsThisDay >= 3u )
-			{
-				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
-				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
-				continue;
-			}
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			a2 = 0;
-			_this = (ItemGen *)&pPlayers[1];
-			do
-			{
-				v563 = 0;
-				do
-				{
-					v564 = _this->uItemID;
-					*(int *)(v563 + _this->uItemID) = 0;
-					v563 += 8;
-					*(int *)(v563 + v564 - 4) = 0;
-				}
-				while ( v563 <= 128 );
-				v565 = ((Player *)_this->uItemID)->GetMaxHealth();
-				v566 = (Player **)_this;
-				*(int *)(_this->uItemID + 6460) = v565;
-				v567 = (*v566)->GetMaxMana();
-				*(int *)(_this->uItemID + 6464) = v567;
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, a2);
-				++a2;
-				_this = (ItemGen *)((char *)_this + 4);
-			}
-			while ( (signed int)this < (signed int)&qword_A750D8 );
-			v571 = pPlayer;
-			v572 = (char *)&pPlayer->sAgeModifier;
-			if ( pPlayer->sAgeModifier + 10 >= 120 )
-				*(short *)v572 = 120;
-			else
-				*(short *)v572 = pPlayer->sAgeModifier + 10;
-			sRecoveryTime += -5 * v2;
-			++v571->uNumDivineInterventionCastsThisDay;
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_DARK_REANIMATE:
-		{
-			switch (v731)
-			{
-				case 1: amount = 2 * v2; break;
-				case 2: amount = 3 * v2; break;
-				case 3: amount = 4 * v2; break;
-				case 4: amount = 5 * v2; break;
-				default:
-				assert(false);
-			}
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			v576 = pCastSpell->spell_target_pid;
-			if (!v576)
-			{
-				v585 = (char *)&pParty->pPlayers[pCastSpell->uPlayerID_2];
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
-				if ( *((_QWORD *)v585 + 14) )
-				{
-				((Player *)v585)->SetCondition(0x11u, 1);
-				v587 = ((Player *)v585)->GetSexByVoice();
-				ReloadPlayerPortraits(pCastSpell->uPlayerID_2, (v587 != 0) + 23);
-				*((_QWORD *)v585 + 17) = pParty->uTimePlayed;
-				}
-				break;
-			}
-			v577 = (Player *)(PID_ID(v576));
-			//v726 = v577;
-			if ( v577 == (Player *)-1 )
-			{
-				ShowStatusBarString(pGlobalTXT_LocalizationStrings[496], 2);  // No valid target exists!
-				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
-				continue;
-			}
-			v578 = (int)&pActors[(int)v577];
-			v721 = v578;
-			if ( *(short *)(v578 + 40) > 0 || (v579 = *(short *)(v578 + 176), v579 != 5) && v579 != 4 )
-			{
-				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
-				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
-				continue;
-			}
-			++pSpellSprite.uType;
-			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
-			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-			pSpellSprite.uAttributes = 0;
-			pSpellSprite.uSectorID = 0;
-			pSpellSprite.uSpriteFrameID = 0;
-			pSpellSprite.field_60_distance_related_prolly_lod = 0;
-			v581 = v721;
-			pSpellSprite.uFacing = 0;
-			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-			pSpellSprite.vPosition.x = *(short *)(v721 + 142);
-			pSpellSprite.vPosition.y = *(short *)(v721 + 144);
-			v732 = *(short *)(v721 + 138);
-			pSpellSprite.vPosition.z = *(short *)(v721 + 146) - (unsigned int)(signed __int64)((double)v732 * unk_4D8548);
-			pSpellSprite.spell_target_pid = PID(OBJECT_Actor, (int)v577);
-			pSpellSprite.Create(0, 0, 0, 0);
-			if ( *(char *)(v581 + 52) > amount )
-				break;
-			Actor::Resurrect((unsigned int)v577);
-			*(char *)(v581 + 61) = 0;
-			*(char *)(v581 + 53) = 0;
-			*(char *)(v581 + 54) = 0;
-			*(char *)(v581 + 55) = 0;
-			*(char *)(v581 + 56) = 0;
-			*(char *)(v581 + 57) = 0;
-			*(int *)(v581 + 712) = 9999;
-			*(char *)(v581 + 38) &= 0xF7u;
-			*(int *)(v581 + 708) = 0;
-			((SpellBuff *)(v581 + 356))->Reset();
-			((SpellBuff *)(v581 + 228))->Reset();
-			((SpellBuff *)(v581 + 404))->Reset();
-			if ( *(short *)(v581 + 40) > 10 * amount )
-				*(short *)(v581 + 40) = 10 * amount;
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_DARK_VAMPIRIC_WEAPON:
-		{
-			amount = 16;
-			if ( v731 == 4 )
-			{
-				LODWORD(v733) = 0;
-			}
-			else
-			{
-				LODWORD(v733) = 3600 * v2;
-			}
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			__debugbreak();
-			//HIDWORD(v733) = (int)(char *)&pParty + 6972 * pCastSpell->uPlayerID_2 + 36 * a2 + 3040;
-			ItemGen *_v733 = &pParty->pPlayers[pCastSpell->uPlayerID_2].pInventoryItems[a2];
-			ItemDesc *_v732 = &pItemsTable->pItems[_v733->uItemID];
-			_v733->UpdateTempBonus(pParty->uTimePlayed);
-			if ( _v733->uItemID >= 64 && _v733->uItemID <= 65
-				|| LOBYTE(_v733->uAttributes) & 2
-				|| _v733->uSpecEnchantmentType != 0
-				|| _v733->uEnchantmentType != 0
-				|| (v591 = _v732->uEquipType) != 0 && v591 != 1 && v591 != 2
-				|| pItemsTable->IsMaterialNonCommon(_v733) )
-			{
-				dword_50C9D0 = 113;
-				dword_50C9D4 = 0;
-				dword_50C9D8 = 1;
-
-				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
-				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
-				continue;
-			}
-			v592 = _v733;
-			v14 = v731 == 4;
-			_v733->uSpecEnchantmentType = 16;
-			if ( !v14 )
-			{
-				v732 = (int)v733 << 7;
-				v592->uExpireTime = pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
-				v592->uAttributes |= 8u;
-			}
-			LOBYTE(v592->uAttributes) |= 0x80u;
-			_50C9A8_item_enchantment_timer = 256;
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_DARK_SHARPMETAL:
-		{
-			switch (v731)
-			{
-				case 1: amount = 5; break;
-				case 2: amount = 5; break;
-				case 3: amount = 7; break;
-				case 4: amount = 9; break;
-				default:
-				assert(false);
-			}
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			auto _v726 = ((signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360);
-			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
-			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-			pSpellSprite.vPosition.x = pParty->vPosition.x;
-			pSpellSprite.vPosition.y = pParty->vPosition.y;
-			pSpellSprite.uAttributes = 0;
-			pSpellSprite.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 2;
-			pSpellSprite.uSectorID = pIndoor->GetSector(
-								pParty->vPosition.x,
-								pParty->vPosition.y,
-								pParty->vPosition.z + (signed int)pParty->uPartyHeight / 2);
-			pSpellSprite.uSpriteFrameID = 0;
-			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-			pSpellSprite.spell_target_pid = a2;
-			pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
-			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-			if ( pParty->bTurnBasedModeOn == 1 )
-				LOBYTE(pSpellSprite.uAttributes) |= 4u;
-			v596 = (signed int)_v726 / -2;
-			y = (char *)((signed int)_v726 / 2);
-			if ( (signed int)_v726 / -2 <= (signed int)_v726 / 2 )
-			{
-				v597 = v715.uYawAngle;
-				do
-				{
-					pSpellSprite.uFacing = v596 + v597;
-					if ( pSpellSprite.Create(
-							v596 + v597,
-							v715.uPitchAngle,
-							pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed,
-							pCastSpell->uPlayerID + 1) != -1
-							&& pParty->bTurnBasedModeOn == 1 )
-						++pTurnEngine->field_1C;
-					v596 += _v726 / (amount - 1);
-				}
-				while ( v596 <= (signed int)y );
-			}
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_DARK_CONTROL_UNDEAD:
-		{
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			switch (v731)
-			{
-				case 1: LODWORD(v733) = 180 * v2; break;
-				case 2: LODWORD(v733) = 180 * v2; break;
-				case 3: LODWORD(v733) = 300 * v2; break;
-				case 4: LODWORD(v733) = 29030400; break;
-				default:
-				assert(false);
-			}
-			if (PID_TYPE(a2) != OBJECT_Actor)
-			{
-				LODWORD(v727) = 1;
-				break;
-			}
-			pActor = &pActors[PID_ID(a2)];
-			if ( !MonsterStats::BelongsToSupertype(pActor->pMonsterInfo.uID, MONSTER_SUPERTYPE_UNDEAD) )
-				break;
-			if ( !stru_50C198.GetMagicalResistance(pActor, 0xAu) )
-			{
-				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
-				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
-				continue;
-			}
-			pActor->pActorBuffs[9].Reset();
-			pActor->pActorBuffs[1].Reset();
-			pActor->pActorBuffs[12].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335),
-				v731, 0, 0, 0);
-			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
-			v60 = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-			
-			v600 = pActor->vPosition.y;
-			v601 = pActor->vPosition.x;
-			pSpellSprite.uObjectDescID = v60;
-			pSpellSprite.vPosition.x = v601;
-			v602 = pActor->uActorHeight;
-			v603 = pActor->vPosition.z;
-			pSpellSprite.vPosition.y = v600;
-			v676 = v603 + v602;
-			v665 = v600;
-			pSpellSprite.vPosition.z = v603 + v602;
-			v657 = v601;
-			pSpellSprite.uAttributes = 0;
-			pSpellSprite.uSectorID = pIndoor->GetSector(v657, v665, v676);
-			pSpellSprite.uSpriteFrameID = 0;
-			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-			pSpellSprite.spell_target_pid = a2;
-			pSpellSprite.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
-			pSpellSprite.uFacing = LOWORD(v715.uYawAngle);
-			LOBYTE(pSpellSprite.uAttributes) |= 0x80u;
-			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-			pSpellSprite.Create(0, 0, 0, pCastSpell->uPlayerID + 1);
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_DARK_SACRIFICE:
-		{
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			int _v733 = 0;
-			memset(&achieved_awards, 0, 4000);
-			int i = 0;
-			pNPCData = pParty->pHirelings;
-			do
-			{
-				if ( pNPCData->pName != 0)
-				{
-					v606 = _v733++;
-					achieved_awards[v606] = (AwardType)(i + 1);
-				}
-				++i;
-				++pNPCData;
-			}
-			while ( pNPCData <= &pParty->pHirelings[1] );
-			i = 0;
-			if ( (signed int)pNPCStats->uNumNewNPCs > 0)
-			{
-				pNPCData = pNPCStats->pNewNPCData;
-				//__debugbreak(); // data offset
-				AwardType *_v734 = &achieved_awards[_v733];
-				do
-				{
-					if ( pNPCData->uFlags & 0x80
-						&& (!pParty->pHirelings[0].pName || strcmp(pNPCData->pName, pParty->pHirelings[0].pName))
-						&& (!pParty->pHirelings[1].pName || strcmp(pNPCData->pName, pParty->pHirelings[1].pName)) )
-					{
-						v607 = _v734;
-						++_v734;
-						*v607 = (AwardType)(i + 3);
-					}
-					++i;
-					++pNPCData;
-				}
-				while ( (signed int)i < (signed int)pNPCStats->uNumNewNPCs );
-			}
-			v608 = pCastSpell->uPlayerID_2;
-			if ( v608 != 4 && v608 != 5
-				|| (v609 = (signed int)*(&pFontCChar + v608 + (unsigned __int8)pParty->field_709), v609 <= 0)
-				|| v609 >= 3 )
-			{
-				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
-				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
-				continue;
-			}
-			v610 = 76 * v609;
-			//*((int *)&pParty->pPlayers[3].pInstalledBeacons[4].uBeaconTime + 19 * v609) = 0;
-			pParty->pHirelings[v609-1].evt_B = 0;
-			v611 = pIconsFrameTable->FindIcon("spell96");
-			//*(int *)((char *)&pParty->pPlayers[3].pInstalledBeacons[4].uBeaconTime + v610 + 4) = pIconsFrameTable->GetIconAnimLength(v611);
-			pParty->pHirelings[v609-1].evt_C = pIconsFrameTable->GetIconAnimLength(v611);
-			//*(int *)((char *)&pParty->pPlayers[3].pInstalledBeacons[3].field_18 + v610) = 1;
-			pParty->pHirelings[v609-1].evt_A = 1;
-
-			v612 = pParty->pPlayers;
-			do
-			{
-				v612->sHealth = v612->GetMaxHealth();
-				v612->sMana = v612->GetMaxMana();
-				++v612;
-			}
-			while ( v612 <= &pParty->pPlayers[3] );
-			v613 = &pOutdoor->ddm;
-			if ( uCurrentlyLoadedLevelType != LEVEL_Outdoor)
-				v613 = &pIndoor->dlv;
-			v613->uReputation += 15;
-			if ( v613->uReputation > 10000 )
-				v613->uReputation = 10000;
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_DARK_PAIN_REFLECTION:
-		{
-			switch (v731)
-			{
-				case 1: LODWORD(v733) = 300 * (v2 + 12); break;
-				case 2: LODWORD(v733) = 300 * (v2 + 12); break;
-				case 3: LODWORD(v733) = 300 * (v2 + 12); break;
-				case 4: LODWORD(v733) = 900 * (v2 + 4); break;
-				default:
-				assert(false);
-			}
-			amount = v2 + 5;
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			if ( v731 != 3 && v731 != 4 )
-			{
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
-				pParty->pPlayers[pCastSpell->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_PAIN_REFLECTION].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, amount, v716, 0);
-				LODWORD(v727) = 1;
-				break;
-			}
-			a2 = 0;
-			v717 = (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
-			v619 = pParty->pPlayers;//[0].pPlayerBuffs[10];
-			do
-			{
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, a2);
-				v619->pPlayerBuffs[PLAYER_BUFF_PAIN_REFLECTION].Apply(pParty->uTimePlayed + v717, v731, amount, v716, 0);
-				++a2;
-				++v619;
-			}
-			while ( v619 <= &pParty->pPlayers[3] );
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_DARK_SOULDRINKER:
-		{
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			pGame->GetIndoorCamera();
-			v623 = (signed __int64)pGame->pIndoorCameraD3D->GetPickDepth();
-			signed int _v733 = sub_46A6AC((int)dword_50BF30.data(), 100, v623);
-			v707.x = 0;
-			v707.y = 0;
-			v707.z = 0;
-			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
-			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_skill = v731;
-			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
-			pSpellSprite.uAttributes = 0;
-			pSpellSprite.uSectorID = 0;
-			pSpellSprite.uSpriteFrameID = 0;
-			pSpellSprite.field_60_distance_related_prolly_lod = 0;
-			pSpellSprite.uFacing = 0;
-			pSpellSprite.spell_caster_pid = PID(OBJECT_Player, pCastSpell->uPlayerID);
-			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
-			a2 = 0;
-			int _v726 = 0;
-			if ( _v733 > 0 )
-			{
-				_v726 = (_v733 * (7 * v2 + 25));
-				do
-				{
-					v625 = dword_50BF30[a2];
-					pSpellSprite.vPosition.x = pActors[v625].vPosition.x;
-					pSpellSprite.vPosition.y = pActors[v625].vPosition.y;
-					//v732 = pActors[v625].uActorHeight;
-					pSpellSprite.vPosition.z = pActors[v625].vPosition.z - (unsigned int)(signed __int64)((double)pActors[v625].uActorHeight * unk_4D8548);
-					pSpellSprite.spell_target_pid = PID(OBJECT_Actor, dword_50BF30[a2]);
-					v627 = pSpellSprite.Create(0, 0, 0, 0);
-					v628 = a2;
-					DamageMonsterFromParty(PID(OBJECT_Item, v627), dword_50BF30[a2], &v707);
-					a2 = v628 + 1;
-				}
-				while ( v628 + 1 < _v733 );
-			}
-			v730 = 0;
-			v629 = 1;
-			do
-			{
-				v630 = pPlayers[v629];
-				if ( !v630->pConditions[2]
-				&& !v630->pConditions[12]
-				&& !v630->pConditions[13]
-				&& !v630->pConditions[14]
-				&& !v630->pConditions[15]
-								&& !v630->pConditions[16] )
-				{
-					v631 = v730++;
-					v681[v631] = v629;
-				}
-				++v629;
-			}
-			while ( v629 <= 4 );
-			v732 = (signed __int64)((double)(signed int)_v726 / (double)v730);
-			_v733 = 0;
-			if ( v730 > 0 )
-			{
-				do
-				{
-					//v632 = 4 * v681[HIDWORD(v733)] + 10965188;
-					v726 = pPlayers[v681[_v733]];
-					//v633 = pPlayers[v681[HIDWORD(v733)]];
-					v726->sHealth += v732;
-					//v726 = *(Player **)v632;
-					//v634 = v726->GetMaxHealth();
-					if ( v726->sHealth > v726->GetMaxHealth())
-						v726->sHealth = v726->GetMaxHealth();
-					v635 = _v733;
-
-					pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, WORD2(v733));
-					_v733 = v635 + 1;
-				}
-				while ( v635 + 1 < v730 );
-			}
-			pGame->GetStru6()->FadeScreen__like_Turn_Undead_and_mb_Armageddon(0, 0x40u);
-			LODWORD(v727) = 1;
-			break;
-		}
-		case SPELL_DARK_ARMAGEDDON:
-		{
-			if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
-			{
-				ShowStatusBarString(pGlobalTXT_LocalizationStrings[499], 2);  // Can't cast Armageddon indoors!
-				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
-				continue;
-			}
-			if ( v731 == 4)
-				amount = 4;
-			else
-				amount = 3;
-			if ( pPlayer->uNumArmageddonCasts >= amount || pParty->armageddon_timer > 0 )
-			{
-				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
-				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
-				continue;
-			}
-			if ( !pPlayer->CanCastSpell(uRequiredMana) )
-				break;
-			pParty->armageddon_timer = 256;
-			pParty->field_16140 = v2;
-			++pPlayer->uNumArmageddonCasts;
-			if ( pParty->bTurnBasedModeOn == 1 )
-				++pTurnEngine->field_1C;
-			auto _v726 = 50;
-			do
-			{
-				v642 = rand() % 4096 - 2048;
-				v643 = rand();
-				v721 = v642 + pParty->vPosition.x;
-				y = (char *)(pParty->vPosition.y + v643 % 4096 - 2048);
-				v732 = GetTerrainHeightsAroundParty2(v642 + pParty->vPosition.x, (int)y, &v710, 0);
-				v644 = rand();
-				sub_42F7EB_DropItemAt(0xFE6u, v721, (int)y, v732 + 16, v644 % 500 + 500, 1, 0, 0, 0);
-				--_v726;
-			}
-			while ( _v726 != 0 );
-			LODWORD(v727) = 1;
-			break;
-		}
-
-		default:
-			break;
-	}
-	if ( pCastSpell->field_8 & 0x20 )
-	{
-		if ( v727 != 0.0 )
-			pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[pCastSpell->spellnum], 0, 0, -1, 0, pCastSpell->sound_id, 0, 0);
-	}
-	else
-	{
-		if ( sRecoveryTime < 0 )
-			sRecoveryTime = 0;
-		if ( pParty->bTurnBasedModeOn )
-		{
-			v645 = sRecoveryTime;
-			pParty->pTurnBasedPlayerRecoveryTimes[pCastSpell->uPlayerID] = sRecoveryTime;
-			pPlayer->SetRecoveryTime(v645);
-			if ( !some_active_character )
-				pTurnEngine->_40471C();
-		}
-		else
-		{
-			pPlayer->SetRecoveryTime(
-				(signed __int64)(flt_6BE3A4_debug_recmod1 * (double)sRecoveryTime * 2.133333333333333));
-		}
-		if ( v727 != 0.0 )
-		{
-			pPlayer->PlaySound(SPEECH_49, 0);
-			if ( v727 != 0.0 )
-				pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[pCastSpell->spellnum], 0, 0, -1, 0, pCastSpell->sound_id, 0,	0);
-		}
-	}
-	pCastSpell->spellnum = 0;
-	v2 = v723;
-	continue;
-  }
-  
-}
-//----- (0042EB42) --------------------------------------------------------
-__int16 ObjectList::ObjectIDByItemID(unsigned __int16 uItemID)
-{
-  unsigned int v2; // edx@1
-  signed int v3; // eax@1
-  char *v4; // ecx@2
-
-  v2 = this->uNumObjects;
-  v3 = 0;
-  if ( (signed int)this->uNumObjects <= 0 )
-  {
-LABEL_5:
-    LOWORD(v3) = 0;
-  }
-  else
-  {
-    v4 = (char *)&this->pObjects->uObjectID;
-    while ( uItemID != *(short *)v4 )
-    {
-      ++v3;
-      v4 += 56;
-      if ( v3 >= (signed int)v2 )
-        goto LABEL_5;
-    }
-  }
-  return v3;
-}
-
-//----- (0042EB78) --------------------------------------------------------
-int IconFrameTable::GetIconAnimLength(unsigned int uIconID)
-{
-  return 8 * this->pIcons[uIconID].uAnimLength;
-}
-
-const wchar_t *UIMessage2String(UIMessageType msg)
-{
-  #define CASE(xxx) case xxx: swprintf(b, wcslen(L"%03X/%s"), L"%03X/%s", msg, L#xxx); return b;
-  static wchar_t b[256]; // bad for threads
-  switch (msg)
-  {
-    CASE(UIMSG_SelectSpell)
-    CASE(UIMSG_ChangeGameState)
-    CASE(UIMSG_Attack)
-    CASE(UIMSG_PlayArcomage)
-    CASE(UIMSG_MainMenu_ShowPartyCreationWnd)
-    CASE(UIMSG_MainMenu_ShowLoadWindow)
-    CASE(UIMSG_ShowCredits)
-    CASE(UIMSG_ExitToWindows)
-    CASE(UIMSG_PlayerCreationChangeName)
-    CASE(UIMSG_PlayerCreationClickPlus)
-    CASE(UIMSG_PlayerCreationClickMinus)
-    CASE(UIMSG_PlayerCreationSelectActiveSkill)
-    CASE(UIMSG_PlayerCreationSelectClass)
-    CASE(UIMSG_PlayerCreationClickOK)
-    CASE(UIMSG_PlayerCreationClickReset)
-    CASE(UIMSG_ClickBooksBtn)
-    CASE(UIMSG_PlayerCreationRemoveUpSkill)
-    CASE(UIMSG_PlayerCreationRemoveDownSkill)
-    CASE(UIMSG_SPellbook_ShowHightlightedSpellInfo)
-    CASE(UIMSG_LoadGame)
-    CASE(UIMSG_SaveGame)
-    CASE(UIMSG_ShowStatus_DateTime)
-    CASE(UIMSG_ShowStatus_ManaHP)
-    CASE(UIMSG_ShowStatus_Player)
-    CASE(UIMSG_Wait5Minutes)
-    CASE(UIMSG_Wait1Hour)
-    CASE(UIMSG_ShowStatus_Food)
-    CASE(UIMSG_ShowStatus_Funds)
-    CASE(UIMSG_QuickReference)
-    CASE(UIMSG_GameMenuButton)
-    CASE(UIMSG_AlreadyResting)
-    CASE(UIMSG_SelectCharacter)
-    CASE(UIMSG_ChangeSoundVolume)
-    CASE(UIMSG_ChangeMusicVolume)
-    CASE(UIMSG_Escape)
-    CASE(UIMSG_PlayerCreation_SelectAttribute)
-    CASE(UIMSG_InventoryLeftClick)
-    CASE(UIMSG_SkillUp)
-    CASE(UIMSG_GameMenu_ReturnToGame)
-    CASE(UIMSG_StartNewGame)
-    CASE(UIMSG_Game_OpenLoadGameDialog)
-    CASE(UIMSG_Game_OpenSaveGameDialog)
-    CASE(UIMSG_Game_OpenOptionsDialog)
-    CASE(UIMSG_SetGraphicsMode)
-    CASE(UIMSG_Quit)
-    CASE(UIMSG_StartHireling1Dialogue)
-    CASE(UIMSG_StartHireling2Dialogue)
-    CASE(UIMSG_SelectNPCDialogueOption)
-    CASE(UIMSG_CastSpellFromBook)
-    CASE(UIMSG_PlayerCreation_VoicePrev)
-    CASE(UIMSG_PlayerCreation_VoiceNext)
-    CASE(UIMSG_StartNPCDialogue)
-    CASE(UIMSG_ArrowUp)
-    CASE(UIMSG_DownArrow)
-    CASE(UIMSG_SaveLoadBtn)
-    CASE(UIMSG_SelectLoadSlot)
-    CASE(UIMSG_Cancel)
-    CASE(UIMSG_ExitRest)
-    CASE(UIMSG_PlayerCreation_FacePrev)
-    CASE(UIMSG_PlayerCreation_FaceNext)
-    CASE(UIMSG_CycleCharacters)
-    CASE(UIMSG_SetTurnSpeed)
-    CASE(UIMSG_ToggleWalkSound)
-    CASE(UIMSG_ChangeVoiceVolume)
-    CASE(UIMSG_ToggleShowDamage)
-    CASE(UIMSG_ScrollNPCPanel)
-    CASE(UIMSG_ShowFinalWindow)
-    CASE(UIMSG_OpenQuestBook)
-    CASE(UIMSG_OpenAutonotes)
-    CASE(UIMSG_OpenMapBook)
-    CASE(UIMSG_OpenCalendar)
-    CASE(UIMSG_OpenHistoryBook)
-    CASE(UIMSG_ToggleAlwaysRun)
-    CASE(UIMSG_ToggleFlipOnExit)
-    CASE(UIMSG_Game_Action)
-    CASE(UIMSG_RentRoom)
-    CASE(UIMSG_TransitionUI_Confirm)
-    CASE(UIMSG_OpenKeyMappingOptions)
-    CASE(UIMSG_SelectKeyPage1)
-    CASE(UIMSG_SelectKeyPage2)
-    CASE(UIMSG_ResetKeyMapping)
-    CASE(UIMSG_ChangeKeyButton)
-    CASE(UIMSG_OpenVideoOptions)
-    CASE(UIMSG_ToggleBloodsplats)
-    CASE(UIMSG_ToggleColoredLights)
-    CASE(UIMSG_ToggleTint)
-    default:
-      swprintf(b, wcslen(L"UIMSG_%03X") , L"UIMSG_%03X", msg); return b;
-  };
-  #undef CASE
-}
-
 //----- (0042EB8D) --------------------------------------------------------
 void GUIMessageQueue::AddMessageImpl(UIMessageType msg, int param, unsigned int a4, const char *file, int line)
 {
--- a/stru9.cpp	Sun Jun 23 14:27:32 2013 +0600
+++ b/stru9.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -110,7 +110,7 @@
           v19 = &pVertices2[i];
         }
         //v20 = v12;
-        if ( AreVectorsCollinear(&pVertices2[i], pPortalBounding, &static_AE3FA4) )//
+        if ( AreVectorsCollinear(&pVertices2[i], pPortalBounding, &static_AE3FA4) )
           AddVertex(&static_AE33A0, &pVertices2[i]);
         //pOutNumVertices = pOutNumVertices;
         //a3a++;
--- a/texts.cpp	Sun Jun 23 14:27:32 2013 +0600
+++ b/texts.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -387,6 +387,68 @@
 	aSpellNames[42] = pGlobalTXT_LocalizationStrings[194];
 	aSpellNames[43] = pGlobalTXT_LocalizationStrings[657];
 	}
+//----- (00413FF1) --------------------------------------------------------
+void SetMonthNames()
+{
+  aMonthNames[0] = pGlobalTXT_LocalizationStrings[415];
+  aMonthNames[1] = pGlobalTXT_LocalizationStrings[416];
+  aMonthNames[2] = pGlobalTXT_LocalizationStrings[417];
+  aMonthNames[3] = pGlobalTXT_LocalizationStrings[418];
+  aMonthNames[4] = pGlobalTXT_LocalizationStrings[419];
+  aMonthNames[5] = pGlobalTXT_LocalizationStrings[420];
+  aMonthNames[6] = pGlobalTXT_LocalizationStrings[421];
+  aMonthNames[7] = pGlobalTXT_LocalizationStrings[422];
+  aMonthNames[8] = pGlobalTXT_LocalizationStrings[423];
+  aMonthNames[9] = pGlobalTXT_LocalizationStrings[424];
+  aMonthNames[10] = pGlobalTXT_LocalizationStrings[425];
+  aMonthNames[11] = pGlobalTXT_LocalizationStrings[426];
+}
+
+//----- (0041406F) --------------------------------------------------------
+void SetDayNames()
+{
+  aDayNames[0] = pGlobalTXT_LocalizationStrings[145];
+  aDayNames[1] = pGlobalTXT_LocalizationStrings[230];
+  aDayNames[2] = pGlobalTXT_LocalizationStrings[243];
+  aDayNames[3] = pGlobalTXT_LocalizationStrings[227];
+  aDayNames[4] = pGlobalTXT_LocalizationStrings[91];
+  aDayNames[5] = pGlobalTXT_LocalizationStrings[188];
+  aDayNames[6] = pGlobalTXT_LocalizationStrings[222];
+}
+
+//----- (004140BB) --------------------------------------------------------
+void SetSpellSchoolNames()
+{
+  aSpellSchoolNames[0] = pGlobalTXT_LocalizationStrings[87];
+  aSpellSchoolNames[1] = pGlobalTXT_LocalizationStrings[6];
+  aSpellSchoolNames[2] = pGlobalTXT_LocalizationStrings[240];
+  aSpellSchoolNames[3] = pGlobalTXT_LocalizationStrings[70];
+  aSpellSchoolNames[4] = pGlobalTXT_LocalizationStrings[214];
+  aSpellSchoolNames[5] = pGlobalTXT_LocalizationStrings[142];
+  aSpellSchoolNames[6] = pGlobalTXT_LocalizationStrings[29];
+  aSpellSchoolNames[7] = pGlobalTXT_LocalizationStrings[133];
+  aSpellSchoolNames[8] = pGlobalTXT_LocalizationStrings[54];
+}
+
+//----- (0041411B) --------------------------------------------------------
+void SetAttributeNames()
+{
+  aAttributeNames[0] = pGlobalTXT_LocalizationStrings[144];
+  aAttributeNames[1] = pGlobalTXT_LocalizationStrings[116];
+  aAttributeNames[2] = pGlobalTXT_LocalizationStrings[163];
+  aAttributeNames[3] = pGlobalTXT_LocalizationStrings[75];
+  aAttributeNames[4] = pGlobalTXT_LocalizationStrings[1];
+  aAttributeNames[5] = pGlobalTXT_LocalizationStrings[211];
+  aAttributeNames[6] = pGlobalTXT_LocalizationStrings[136];
+}
+//----- (00410AF5) --------------------------------------------------------
+void __cdecl SetMoonPhaseNames()
+{
+  aMoonPhaseNames[0] = pGlobalTXT_LocalizationStrings[150];
+  aMoonPhaseNames[1] = pGlobalTXT_LocalizationStrings[171];
+  aMoonPhaseNames[2] = pGlobalTXT_LocalizationStrings[102];
+  aMoonPhaseNames[3] = pGlobalTXT_LocalizationStrings[169];
+  aMoonPhaseNames[4] = pGlobalTXT_LocalizationStrings[92];
+}
 
 
-