changeset 1295:86a83e12d795

moving files
author Ritor1
date Mon, 17 Jun 2013 17:34:01 +0600
parents 6bbd50bda571
children c423f946dc99
files Actor.cpp Events.cpp GUIButton.cpp GUIWindow.cpp IconFrameTable.cpp Indoor.cpp NPC.cpp Outdoor.cpp OutdoorCamera.cpp Party.cpp Player.cpp Spells.cpp Sprites.cpp UIHouses.cpp mm7_1.cpp mm7_3.cpp mm7_4.cpp
diffstat 17 files changed, 4980 insertions(+), 4973 deletions(-) [+]
line wrap: on
line diff
--- a/Actor.cpp	Mon Jun 17 09:09:30 2013 +0600
+++ b/Actor.cpp	Mon Jun 17 17:34:01 2013 +0600
@@ -33,7 +33,7 @@
 
 #include "MM7.h"
 #include "SpriteObject.h"
-
+#include "stru298.h"
 
 
 
@@ -3979,3 +3979,821 @@
   }
   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;
+}
\ No newline at end of file
--- a/Events.cpp	Mon Jun 17 09:09:30 2013 +0600
+++ b/Events.cpp	Mon Jun 17 17:34:01 2013 +0600
@@ -1533,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/GUIButton.cpp	Mon Jun 17 09:09:30 2013 +0600
+++ b/GUIButton.cpp	Mon Jun 17 17:34:01 2013 +0600
@@ -175,3 +175,8 @@
            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);
+}
\ No newline at end of file
--- a/GUIWindow.cpp	Mon Jun 17 09:09:30 2013 +0600
+++ b/GUIWindow.cpp	Mon Jun 17 17:34:01 2013 +0600
@@ -1860,4 +1860,27 @@
     }
   }
   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();
 }
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IconFrameTable.cpp	Mon Jun 17 17:34:01 2013 +0600
@@ -0,0 +1,243 @@
+#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;
+}
\ No newline at end of file
--- a/Indoor.cpp	Mon Jun 17 09:09:30 2013 +0600
+++ b/Indoor.cpp	Mon Jun 17 17:34:01 2013 +0600
@@ -37,8 +37,11 @@
 
 #include "mm7_data.h"
 #include "MM7.h"
-
-
+#include "Sprites.h"
+#include "Game.h"
+#include "stru6.h"
+#include "ParticleEngine.h"
+#include "Outdoor_stuff.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),
@@ -4638,4 +4641,1249 @@
       }
     }
   }
+}
+//----- (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;
 }
\ No newline at end of file
--- a/NPC.cpp	Mon Jun 17 09:09:30 2013 +0600
+++ b/NPC.cpp	Mon Jun 17 17:34:01 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 "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/Outdoor.cpp	Mon Jun 17 09:09:30 2013 +0600
+++ b/Outdoor.cpp	Mon Jun 17 17:34:01 2013 +0600
@@ -3169,4 +3169,382 @@
     return false;
   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;
 }
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OutdoorCamera.cpp	Mon Jun 17 17:34:01 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	Mon Jun 17 09:09:30 2013 +0600
+++ b/Party.cpp	Mon Jun 17 17:34:01 2013 +0600
@@ -19,7 +19,8 @@
 
 #include "mm7_data.h"
 #include "MM7.h"
-
+#include "Outdoor.h"
+#include "Indoor.h"
 
 
 
@@ -1151,4 +1152,84 @@
     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();
+}
+//----- (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;
 }
\ No newline at end of file
--- a/Player.cpp	Mon Jun 17 09:09:30 2013 +0600
+++ b/Player.cpp	Mon Jun 17 17:34:01 2013 +0600
@@ -9521,4 +9521,44 @@
       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;
 }
\ No newline at end of file
--- a/Spells.cpp	Mon Jun 17 09:09:30 2013 +0600
+++ b/Spells.cpp	Mon Jun 17 17:34:01 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
@@ -432,4 +439,728 @@
 				strtok(NULL, "\r");
 		}
 
-	}
\ No newline at end of file
+	}
+//----- (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);
+}
\ No newline at end of file
--- a/Sprites.cpp	Mon Jun 17 09:09:30 2013 +0600
+++ b/Sprites.cpp	Mon Jun 17 17:34:01 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/UIHouses.cpp	Mon Jun 17 09:09:30 2013 +0600
+++ b/UIHouses.cpp	Mon Jun 17 17:34:01 2013 +0600
@@ -6255,4 +6255,478 @@
     while ( v35 <v29->pNumPresenceButton + v29->pStartingPosActiveItem );
   }
   return;
-}
\ No newline at end of file
+}
+//----- (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;
+        }
+      }
+    }
+  }
+}
+//----- (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);
+  }
+}
--- a/mm7_1.cpp	Mon Jun 17 09:09:30 2013 +0600
+++ b/mm7_1.cpp	Mon Jun 17 17:34:01 2013 +0600
@@ -1488,12 +1488,12 @@
 //----- (00423B5D) --------------------------------------------------------
 int __fastcall sub_423B5D(unsigned int uFaceID)
 {
-  BLVFace *v1; // ebx@1
+  BLVFace *pFace; // ebx@1
   Vec3_short_ *v2; // esi@1
-  int v3; // ST28_4@1
-  __int16 v4; // ST2C_2@1
+  //int v3; // ST28_4@1
+  //__int16 v4; // ST2C_2@1
   signed int v5; // esi@1
-  Vec3_short_ *v6; // eax@4
+  //Vec3_short_ *v6; // eax@4
   signed int v7; // edi@5
   signed int v8; // eax@5
   signed int v9; // ecx@10
@@ -1579,34 +1579,34 @@
   signed int v90; // [sp+24h] [bp-4h]@51
   signed int v91; // [sp+24h] [bp-4h]@61
 
-  v1 = &pIndoor->pFaces[uFaceID];
+  pFace = &pIndoor->pFaces[uFaceID];
   _this = pGame->pIndoorCameraD3D;
-  v2 = &pIndoor->pVertices[*v1->pVertexIDs];
-  v3 = *(_DWORD *)&v2->x;
-  v4 = v2->z;
+  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 ( v1->pFacePlane_old.vNormal.x * ((signed __int16)v3 - pBLVRenderParams->vPartyPos.x)
-     + v1->pFacePlane_old.vNormal.y * (SHIWORD(v3) - pBLVRenderParams->vPartyPos.y)
-     + v1->pFacePlane_old.vNormal.z * (v4 - pBLVRenderParams->vPartyPos.z) < 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 ( !(v1->uAttributes & 1) )
+    if ( !(pFace->uAttributes & 1) )
       return 0;
   }
-  v66 = v1->uNumVertices;
-  if ( (signed int)v1->uNumVertices > 0 )
+  v66 = pFace->uNumVertices;
+  if ( (signed int)pFace->uNumVertices > 0 )
   {
     do
     {
-      v6 = &pIndoor->pVertices[v1->pVertexIDs[v5]];
+      //v6 = &pIndoor->pVertices[pFace->pVertexIDs[v5]];
       pGame->pIndoorCameraD3D->ApplyViewTransform_TrueIfStillVisible(
-        v6->x,
-        v6->y,
-        v6->z,
+        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],
--- a/mm7_3.cpp	Mon Jun 17 09:09:30 2013 +0600
+++ b/mm7_3.cpp	Mon Jun 17 17:34:01 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.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;
-    } 
-  }
-}
-
-//----- (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;//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;
-  }
-}
-
 //----- (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)
 {
@@ -12947,730 +12055,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) --------------------------------------------------------
@@ -14021,1103 +12405,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	Mon Jun 17 09:09:30 2013 +0600
+++ b/mm7_4.cpp	Mon Jun 17 17:34:01 2013 +0600
@@ -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