changeset 1572:19f1735fca80

Слияние
author Ritor1
date Sun, 08 Sep 2013 17:07:58 +0600
parents ef20d4608b1a (current diff) addae48bc203 (diff)
children 6d759814a817
files UI/UIGuilds.cpp UI/UIMainMenu.cpp
diffstat 91 files changed, 3440 insertions(+), 4916 deletions(-) [+]
line wrap: on
line diff
--- a/Actor.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/Actor.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -2,9 +2,6 @@
 #define _CRT_SECURE_NO_WARNINGS
 #endif
 
-#include <assert.h>
-
-
 #include "mm7_data.h"
 #include "DecalBuilder.h"
 
@@ -294,7 +291,7 @@
 }
 
 //----- (00404AC7) --------------------------------------------------------
-void __fastcall Actor::AI_SpellAttack(unsigned int uActorID, AIDirection *pDir, int spellnum, int a4, unsigned int uSkillLevel)
+void __fastcall Actor::AI_SpellAttack(unsigned int uActorID, AIDirection *pDir, int uSpellID, int a4, unsigned int uSkillLevel)
 {
   Actor *v5; // esi@1
   unsigned int v6; // edi@1
@@ -426,25 +423,25 @@
   v117 = pDir;
   v6 = uSkillLevel & 0x3F;
   v7 = SkillToMastery(uSkillLevel);
-  if ( spellnum <= 47 )
+  if ( uSpellID <= 47 )
   {
-    if ( spellnum != 47 )
+    if ( uSpellID != 47 )
     {
-      if ( spellnum <= 18 )
+      if ( uSpellID <= 18 )
       {
-        if ( spellnum == 18 || spellnum == 2 )
+        if ( uSpellID == 18 || uSpellID == 2 )
           goto LABEL_159;
-        if ( spellnum != 5 )
+        if ( uSpellID != 5 )
         {
-          if ( spellnum == 6 )
+          if ( uSpellID == 6 )
             goto LABEL_159;
-          if ( spellnum != 9 )
+          if ( uSpellID != 9 )
           {
-            if ( spellnum != 11 )
+            if ( uSpellID != 11 )
             {
-              if ( spellnum != 15 )
+              if ( uSpellID != 15 )
               {
-                if ( spellnum != 17 )
+                if ( uSpellID != 17 )
                   return;
                 if ( (signed int)v7 <= 0 )
                   goto LABEL_20;
@@ -577,7 +574,7 @@
               return;
             }
 LABEL_159:
-            a1.uType = stru_4E3ACC[spellnum].uType;
+            a1.uType = stru_4E3ACC[uSpellID].uType;
             v119 = 0.0;
             if ( (signed int)pObjectList->uNumObjects <= 0 )
             {
@@ -598,7 +595,7 @@
             }
             a1.uObjectDescID = v82;
             a1.stru_24.Reset();
-            a1.spell_id = spellnum;
+            a1.spell_id = uSpellID;
             v83 = v5->vPosition.x;
             v84 = v5->vPosition.y;
             a1.spell_level = uSkillLevel;
@@ -660,7 +657,7 @@
               LOBYTE(v92) = v92 | 2;
               v100 = 0;
               v99 = v92;
-              v22 = (SoundID)word_4EE088_sound_ids[spellnum];
+              v22 = (SoundID)word_4EE088_sound_ids[uSpellID];
               goto LABEL_202;
             }
             return;
@@ -844,13 +841,13 @@
         v39 = 0;
         goto LABEL_79;
       }
-      if ( spellnum == 26 || spellnum == 29 )
+      if ( uSpellID == 26 || uSpellID == 29 )
         goto LABEL_159;
-      if ( spellnum != 38 )
+      if ( uSpellID != 38 )
       {
-        if ( spellnum == 39 || spellnum == 41 )
+        if ( uSpellID == 39 || uSpellID == 41 )
           goto LABEL_159;
-        if ( spellnum != 46 )
+        if ( uSpellID != 46 )
           return;
         if ( (signed int)v7 > 0 )
         {
@@ -971,9 +968,9 @@
     LOWORD(v48) = 0;
     goto LABEL_114;
   }
-  if ( spellnum <= 80 )
+  if ( uSpellID <= 80 )
   {
-    if ( spellnum == 80 )
+    if ( uSpellID == 80 )
     {
       v56 = pParty->pPartyBuffs;
       do
@@ -1019,11 +1016,11 @@
       v22 = (SoundID)word_4EE088_sound_ids[80];
       goto LABEL_202;
     }
-    if ( spellnum != 51 )
+    if ( uSpellID != 51 )
     {
-      if ( spellnum == 57 || spellnum == 65 || spellnum == 70 )
+      if ( uSpellID == 57 || uSpellID == 65 || uSpellID == 70 )
         goto LABEL_159;
-      if ( spellnum == 73 )
+      if ( uSpellID == 73 )
       {
         if ( (signed int)v7 <= 0 || (signed int)v7 > 4 )
           v51 = 0;
@@ -1048,7 +1045,7 @@
         v98 = (SoundID)16060;
         goto LABEL_222;
       }
-      if ( spellnum == 77 )
+      if ( uSpellID == 77 )
       {
         v5->sCurrentHP += 5 * v6 + 10;
         if ( v5->sCurrentHP >= (signed int)v5->pMonsterInfo.uHP )
@@ -1057,7 +1054,7 @@
         v47 = 0;
         goto LABEL_127;
       }
-      v49 = spellnum == 78;
+      v49 = uSpellID == 78;
 LABEL_158:
       if ( !v49 )
         return;
@@ -1104,7 +1101,7 @@
     v54 = 0;
     goto LABEL_142;
   }
-  if ( spellnum == 85 )
+  if ( uSpellID == 85 )
   {
     if ( (signed int)v7 > 0 )
     {
@@ -1148,7 +1145,7 @@
     v96 = 0;
     goto LABEL_221;
   }
-  if ( spellnum == 86 )
+  if ( uSpellID == 86 )
   {
     if ( (signed int)v7 > 0 )
     {
@@ -1191,13 +1188,13 @@
     v94 = 0;
     goto LABEL_212;
   }
-  if ( spellnum == 90 )
+  if ( uSpellID == 90 )
     goto LABEL_159;
-  if ( spellnum != 93 )
+  if ( uSpellID != 93 )
   {
-    if ( spellnum != 95 )
+    if ( uSpellID != 95 )
     {
-      v49 = spellnum == 97;
+      v49 = uSpellID == 97;
       goto LABEL_158;
     }
     if ( (signed int)v7 > 0 )
@@ -1826,7 +1823,7 @@
     v41.vDirection.y = (signed __int64)(1.0 / v33 * v43 * 65536.0);
     v41.vDirection.z = (signed __int64)(1.0 / v33 * a4a * 65536.0);
     v41.uDistance = (signed __int64)v33;
-    v41.uDistanceXZ = (signed __int64)sqrt(outy2 + outx2);
+    v41.uDistanceXZ = sqrt(outy2 + outx2);
     v41.uYawAngle = stru_5C6E00->Atan2((signed __int64)v42, (signed __int64)v43);
     v41.uPitchAngle = stru_5C6E00->Atan2(v41.uDistanceXZ, (signed __int64)a4a);
   }
@@ -2308,7 +2305,7 @@
   result = pPlayer->CanAct();
   if ( result )
   {
-    pCastSpellInfo.data()->_427D48(v1);
+    CastSpellInfoHelpers::_427D48();
     v4 = 0;
     v5 = pMapStats->GetMapInfo(pCurrentMapName);
     if ( v5 )
@@ -2985,8 +2982,8 @@
   actor->UpdateAnimation();
 
   for (uint i = 0; i < 5; ++i)
-    if (pParty->field_750[i] == actor->pMonsterInfo.uID)
-      pParty->field_75A[i] = true;
+    if (pParty->monster_id_for_hunting[i] == actor->pMonsterInfo.uID)
+      pParty->monster_for_hunting_killed[i] = true;
 
   for (uint i = 0; i < 22; ++i)
     actor->pActorBuffs[i].Reset();
@@ -3970,12 +3967,12 @@
         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,
+        v11 = (v8 * stru_721530.direction.y - v9 * stru_721530.direction.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 )
+        abs((v8 * stru_721530.direction.y - v9 * stru_721530.direction.x) >> 16) > v10)
+    || (v12 = (v18 * stru_721530.direction.x + v19 * stru_721530.direction.y) >> 16, v12 <= 0)
+    || (signed int)(((unsigned __int64)(stru_721530.direction.z * (signed __int64)v12) >> 16) + stru_721530.normal.z) < v2->vPosition.z )
   {
 LABEL_25:
     result = 0;
@@ -4063,7 +4060,7 @@
 	//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 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
@@ -4194,19 +4191,19 @@
 				++v14;
 			}
 			while ( v13 < 22 );*/
-			if ( (signed __int64)pActor->pActorBuffs[ACTOR_BUFF_SHRINK].uExpireTime < 0 )
+			if (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 )
+			if (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 )
+			else if (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;
+			if (pActor->pActorBuffs[ACTOR_BUFF_PARALYZED].uExpireTime > 0 ||
+				pActor->pActorBuffs[ACTOR_BUFF_STONED].uExpireTime > 0)
+		      continue;
 			
 			//v15 = pMiscTimer->uTimeElapsed;
 			//v16 = (char *)&pActor->pMonsterInfo.uRecoveryTime;
@@ -4408,7 +4405,7 @@
 					pActor->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Long;
 			}
 
-			if ( (signed __int64)pActor->pActorBuffs[4].uExpireTime > 0 )
+			if (pActor->pActorBuffs[4].uExpireTime > 0)
 			{
 				if ( (signed int)v36 >= 10240 )
 				{
@@ -4430,7 +4427,7 @@
 				{
 					if ( pActor->pMonsterInfo.uMovementType == MONSTER_MOVEMENT_TYPE_STAIONARY )
 					{
-						Actor::AI_Stand(actor_id, target_pid, (signed __int64)((double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333),	&pDir);
+						Actor::AI_Stand(actor_id, target_pid, pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333,	&pDir);
 					}
 					else
 					{
@@ -4477,21 +4474,19 @@
 							}
 							else if ( pActor->pMonsterInfo.uMovementType == MONSTER_MOVEMENT_TYPE_STAIONARY )
 							{
-								v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-								v64 = (signed __int64)v47;
-								Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
+								v47 = pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+								Actor::AI_Stand(actor_id, target_pid, v47, &pDir);
 							}
 							else
 							{
-								v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+								v47 = pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
 								if ( v80 * 307.2 > (double)v81 )
 								{
-									v64 = (signed __int64)v47;
-									Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
+									Actor::AI_Stand(actor_id, target_pid, v47, &pDir);
 								}
 								else
 								{
-									Actor::AI_Pursue1(actor_id, target_pid, actor_id, (signed __int64)v47, &pDir);
+									Actor::AI_Pursue1(actor_id, target_pid, actor_id, v47, &pDir);
 								}
 							}
 						}
@@ -4503,9 +4498,8 @@
 								{
 									if ( pActor->pMonsterInfo.uMovementType == MONSTER_MOVEMENT_TYPE_STAIONARY )
 									{
-										v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-										v64 = (signed __int64)v47;
-										Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
+										v47 = pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+										Actor::AI_Stand(actor_id, target_pid, v47, &pDir);
 									}
 									else
 									{
@@ -4515,9 +4509,8 @@
 								}
 								else if ( pActor->pMonsterInfo.uMovementType == MONSTER_MOVEMENT_TYPE_STAIONARY )
 								{
-									v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-									v64 = (signed __int64)v47;
-									Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
+									v47 = pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+									Actor::AI_Stand(actor_id, target_pid, v47, &pDir);
 								}
 								else
 								{
@@ -4530,9 +4523,8 @@
 							}
 							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);
+								v47 = pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+								Actor::AI_Stand(actor_id, target_pid, v47, &pDir);
 							}
 							else
 							{
@@ -4559,14 +4551,13 @@
 							}
 							else if ( v80 * 307.2 > (double)v81 || pActor->pMonsterInfo.uMovementType == MONSTER_MOVEMENT_TYPE_STAIONARY )
 							{
-								v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-								v64 = (signed __int64)v47;
-								Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
+								v47 = pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+								Actor::AI_Stand(actor_id, target_pid, v47, &pDir);
 							}
 							else
 							{
-								v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-								Actor::AI_Pursue1(actor_id, target_pid, actor_id, (signed __int64)v47, &pDir);
+								v47 = pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+								Actor::AI_Pursue1(actor_id, target_pid, actor_id, v47, &pDir);
 							}
 						}
 						else
@@ -4577,9 +4568,8 @@
 								{
 									if ( pActor->pMonsterInfo.uMovementType == MONSTER_MOVEMENT_TYPE_STAIONARY )
 									{
-										v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-										v64 = (signed __int64)v47;
-										Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
+										v47 = pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+										Actor::AI_Stand(actor_id, target_pid, v47, &pDir);
 									}
 									else
 									{
@@ -4588,9 +4578,8 @@
 								}
 								else if ( pActor->pMonsterInfo.uMovementType == MONSTER_MOVEMENT_TYPE_STAIONARY )
 								{
-									v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-									v64 = (signed __int64)v47;
-									Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
+									v47 = pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+									Actor::AI_Stand(actor_id, target_pid, v47, &pDir);
 								}
 								else
 								{
@@ -4600,9 +4589,8 @@
 							}
 							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);
+								v47 = pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+								Actor::AI_Stand(actor_id, target_pid, v47, &pDir);
 							}
 							else
 							{
@@ -4638,8 +4626,7 @@
 					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);
+					Actor::AI_Stand(actor_id, 4, v58, &pDir);
 				}				
 			}
 			else if ( !pActor->pMonsterInfo.uMissleAttack2Type )
@@ -4650,9 +4637,8 @@
 					{
 						if ( pActor->pMonsterInfo.uMovementType == MONSTER_MOVEMENT_TYPE_STAIONARY )
 						{
-							v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-							v64 = (signed __int64)v47;
-							Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
+							v47 = pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+							Actor::AI_Stand(actor_id, target_pid, v47, &pDir);
 						}
 						else
 						{
@@ -4661,9 +4647,8 @@
 					}
 					else if ( pActor->pMonsterInfo.uMovementType == MONSTER_MOVEMENT_TYPE_STAIONARY )
 					{
-						v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-						v64 = (signed __int64)v47;
-						Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
+						v47 = pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+						Actor::AI_Stand(actor_id, target_pid, v47, &pDir);
 					}
 					else
 					{
@@ -4673,9 +4658,8 @@
 				}
 				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);
+					v47 = pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+					Actor::AI_Stand(actor_id, target_pid, v47, &pDir);
 				}
 				else
 				{
@@ -4686,14 +4670,9 @@
 			{
 				v47 = (double)(signed int)pActor->pMonsterInfo.uRecoveryTime * 2.133333333333333;
 				if ( v80 * 307.2 > (double)v81 || pActor->pMonsterInfo.uMovementType == MONSTER_MOVEMENT_TYPE_STAIONARY )
-				{
-					v64 = (signed __int64)v47;
-					Actor::AI_Stand(actor_id, target_pid, v64, &pDir);
-				}
+					Actor::AI_Stand(actor_id, target_pid, v47, &pDir);
 				else
-				{
-					Actor::AI_Pursue1(actor_id, target_pid, actor_id, (signed __int64)v47, &pDir);
-				}
+					Actor::AI_Pursue1(actor_id, target_pid, actor_id, v47, &pDir);
 			}
 			else
 			{
@@ -4711,7 +4690,6 @@
 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;
@@ -4739,12 +4717,11 @@
   {
     uAliveActors = SearchAliveActors(&uTotalActors);
   }
-  v5 = 0;
-  if ( uNumAlive )
-    LOBYTE(v5) = (signed int)uAliveActors >= (signed int)uNumAlive;
+
+  if (uNumAlive)
+    return uAliveActors >= uNumAlive;
   else
-    LOBYTE(v5) = uTotalActors == uAliveActors;
-  return v5;
+    return uTotalActors == uAliveActors;
 }
 //----- (00408B54) --------------------------------------------------------
 unsigned int SearchActorByID(unsigned int *pTotalActors, unsigned int a2)
@@ -5029,7 +5006,7 @@
   if (pMonster->IsNotAlive())
     return;
 
-  BYTE1(pMonster->uAttributes) |= 0xC0u;
+  pMonster->uAttributes |= 0xC000;
   if ( pMonster->uAIState == Fleeing )
     pMonster->uAttributes |= 0x20000u;
   //v57 = 0;
@@ -5076,7 +5053,7 @@
     v50 = pMonster->pMonsterInfo.uID;
     a2 = 4;
     //v27 = player->CalculateMeleeDamageTo(0, 0, v50);
-    uDamageAmount = player->CalculateMeleeDamageTo(0, 0, v50);
+    uDamageAmount = player->CalculateMeleeDamageTo(false, false, v50);
     //if ( !v57 )
       goto LABEL_67;
     //goto LABEL_69;
@@ -5138,7 +5115,7 @@
     if ( (signed int)SkillToMastery(v16) >= 3 )
       a4 = player->pActiveSkills[7] & 0x3F;
     a2 = 4;
-    uDamageAmount = player->CalculateMeleeDamageTo(1, 1, 0);
+    uDamageAmount = player->CalculateMeleeDamageTo(true, true, 0);
     goto LABEL_67;
   }
   if ( v15 != SPELL_BOW_ARROW )
@@ -5424,7 +5401,7 @@
   monster_id = a1;
   x_ = x;
   v15 = a1;
-  if ( (signed int)uNumActors < 500
+  if (uNumActors < 500
     && ((signed int)pAllocator->uBigBufferSizeAligned >> 10) - ((signed int)pAllocator->uNextFreeOffsetInBigBuffer >> 10) >= 2000 )
   {
     v16 = 0;
--- a/Actor.h	Sun Sep 08 17:07:47 2013 +0600
+++ b/Actor.h	Sun Sep 08 17:07:58 2013 +0600
@@ -214,7 +214,7 @@
   static struct AIDirection *__fastcall GetDirectionInfo(unsigned int uObj1ID, unsigned int uObj2ID, struct AIDirection *pOut, int a4);
   static signed int __fastcall Explode(unsigned int uActorID);
   static char __fastcall AI_RangedAttack(unsigned int uActorID, struct AIDirection *a2, int type, char a4);
-  static void __fastcall AI_SpellAttack(unsigned int uActorID, struct AIDirection *pDir, int spellnum, int a4, unsigned int uSkillLevel);
+  static void __fastcall AI_SpellAttack(unsigned int uActorID, struct AIDirection *pDir, int uSpellID, int a4, unsigned int uSkillLevel);
   static void AggroSurroundingPeasants(unsigned int uActorID, int a2);
   static bool ArePeasantsOfSameFaction(Actor *a1, Actor *a2);
   static bool StealFrom(unsigned int uActorID);
--- a/Allocator.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/Allocator.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -6,6 +6,7 @@
 #include <stdio.h>
 
 #include "Allocator.h"
+#include "ErrorHandling.h"
 
 #include "mm7_data.h"
 
@@ -13,6 +14,7 @@
 
 Allocator *pAllocator; // idb
 
+int aborting_app = false; // weak
 
 
 
@@ -24,9 +26,8 @@
 //----- (00426755) --------------------------------------------------------
 void *Allocator::AllocNamedChunk(const void *pPrevPtrValue, unsigned int uSize, const char *pName)
 {
+  Assert(!pPrevPtrValue, "PrevPtrValue != 0");
 
-  if ( pPrevPtrValue && !aborting_app )
-	  AbortWithError();
   if (!uSize)
 	  return 0;
   return malloc(uSize);
--- a/Arcomage.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/Arcomage.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -3,7 +3,6 @@
 #endif
 
 #include <string>
-#include <assert.h>
 
 #include "Render.h"
 #include "Arcomage.h"
@@ -447,10 +446,10 @@
 }
 
 //----- (0040DFC1) --------------------------------------------------------
-void ArcomageGame::OnMouseMove(POINT *pXY)
+void ArcomageGame::OnMouseMove(int x, int y)
 {
-  pArcomageGame->mouse_x = pXY->x;
-  pArcomageGame->mouse_y = pXY->y;
+  pArcomageGame->mouse_x = x;
+  pArcomageGame->mouse_y = y;
 }
 
 
--- a/Arcomage.h	Sun Sep 08 17:07:47 2013 +0600
+++ b/Arcomage.h	Sun Sep 08 17:07:58 2013 +0600
@@ -141,7 +141,7 @@
   static bool MsgLoop(int a1, ArcomageGame_stru1 *a2);
   static void PlaySound(unsigned int event_id);
   static void OnMouseClick(char right_left, bool bDown);
-  static void OnMouseMove(POINT *pXY);
+  static void OnMouseMove(int x, int y);
   static void GetCardRect(unsigned int uCardID, RECT *pCardRect);
 
   static void Loop();
--- a/AudioPlayer.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/AudioPlayer.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -3,7 +3,6 @@
 #endif
 
 #include <string>
-#include <assert.h>
 
 #include "mm7_data.h"
 #include "VideoPlayer.h"
@@ -22,6 +21,7 @@
 #include "MapInfo.h"
 #include "GUIWindow.h"
 #include "Log.h"
+#include "ErrorHandling.h"
 
 #include "Bink_Smacker.h"
 
@@ -264,7 +264,8 @@
     a2 = v14->uDecompressedSize;
     v16 = a2;
     if ( (signed int)a2 > uBufferSizeLeft )
-      Abortf("Sound %s is size %i bytes, sound buffer size is %i bytes", Args, a2, uBufferSizeLeft);
+      Error("Sound %s is size %i bytes, sound buffer size is %i bytes", Args, a2, uBufferSizeLeft);
+
     SetFilePointer(pAudioPlayer->hAudioSnd, v14->uFileOffset, 0, 0);
     v17 = v14->uCompressedSize;
     if ( (signed int)v17 >= (signed int)*v15 )
@@ -380,7 +381,8 @@
   v2 = fopen("data\\dsounds.bin", "wb");
   v3 = v2;
   if ( !v2 )
-    Abortf("Unable to save dsounds.bin!");
+    Error("Unable to save dsounds.bin!");
+
   fwrite(v1, 4u, 1u, v2);
   fwrite(v1->pSounds, 0x78u, v1->sNumSounds, v3);
   fclose(v3);
@@ -441,7 +443,8 @@
   v4 = fopen(Args, "r");
   File = v4;
   if ( !v4 )
-    Abortf("SoundListClass::load - Unable to open file: %s.");
+    Error("SoundListClass::load - Unable to open file: %s.");
+
   v5 = 0;
   Argsa = 0;
   if ( fgets(&Buf, 490, v4) )
@@ -461,7 +464,8 @@
   v6 = pAllocator->AllocNamedChunk(v2->pSounds, 120 * v5, "Snd Des.");
   v2->pSounds = (SoundDesc *)v6;
   if ( v6 == (void *)v3 )
-    Abortf("SoundListClass::load - Out of Memory!");
+    Error("SoundListClass::load - Out of Memory!");
+
   memset(v6, v3, 120 * v2->sNumSounds);
   v7 = File;
   v2->sNumSounds = v3;
--- a/CShow.h	Sun Sep 08 17:07:47 2013 +0600
+++ b/CShow.h	Sun Sep 08 17:07:58 2013 +0600
@@ -1,5 +1,6 @@
 #pragma once
 #include "VideoPlayer.h"
+#include "ErrorHandling.h"
 
 
 /*  302 */
@@ -31,7 +32,7 @@
     case MOVIE_Outro:   VideoPlayer::MovieLoop("end_seq1", 20, 1, 1);      break;
 
     default:
-      assert(false && "Invalid movie requested in " __FUNCTION__);
+      Error("Invalid movie requested: %u", movie);
       break;
   }
 }
--- a/CastSpellInfo.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/CastSpellInfo.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -25,8 +25,11 @@
 #include "texts.h"
 #include "LOD.h"
 
+const size_t CastSpellInfoCount = 10;
+std::array<CastSpellInfo, CastSpellInfoCount> pCastSpellInfo;
+
 //----- (00427E01) --------------------------------------------------------
-void CastSpellInfo::_427E01_cast_spell()
+void CastSpellInfoHelpers::_427E01_cast_spell()
 {
   int v2; // edi@1
   CastSpellInfo *pCastSpell; // ebx@2
@@ -306,20 +309,20 @@
   LODWORD(v733) = 0;
   v723 = 0;
   v727 = 0.0;
-  for(n = 0; n < 10; ++n)
+  for(n = 0; n < CastSpellInfoCount; ++n)
   {
-    pCastSpell = &this[n];
+    pCastSpell = &pCastSpellInfo[n];
     HIDWORD(v733) = (int)pCastSpell;
-    if ( pCastSpell->spellnum == 0 )
+    if ( pCastSpell->uSpellID == 0 )
       continue;
 
     if (pParty->Invisible())
       pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].Reset();
 
-    if ( pCastSpell->field_8 & 0x3CA )
+    if ( pCastSpell->uFlags & 0x3CA )
     {
       if ( !pParty->pPlayers[pCastSpell->uPlayerID].CanAct() )
-        this->_427D48(1);
+        _427D48();
       continue;
     }
     pPlayer = &pParty->pPlayers[pCastSpell->uPlayerID];
@@ -327,9 +330,9 @@
     a2 = pCastSpell->spell_target_pid;
     if (!pCastSpell->spell_target_pid)
     {
-      if (pCastSpell->spellnum == SPELL_LIGHT_DESTROY_UNDEAD ||
-          pCastSpell->spellnum == SPELL_SPIRIT_TURN_UNDEAD ||
-          pCastSpell->spellnum == SPELL_DARK_CONTROL_UNDEAD )
+      if (pCastSpell->uSpellID == SPELL_LIGHT_DESTROY_UNDEAD ||
+          pCastSpell->uSpellID == SPELL_SPIRIT_TURN_UNDEAD ||
+          pCastSpell->uSpellID == SPELL_DARK_CONTROL_UNDEAD )
         v666 = 1;
       else
         v666 = 0;
@@ -341,7 +344,7 @@
     }
 
 
-    pSpellSprite.uType = stru_4E3ACC[pCastSpell->spellnum].uType;
+    pSpellSprite.uType = stru_4E3ACC[pCastSpell->uSpellID].uType;
     if (pSpellSprite.uType)
     {
       if (PID_TYPE(a2) == OBJECT_Actor)
@@ -367,25 +370,25 @@
     else
     {
       //v667 = PLAYER_SKILL_STAFF;
-      if (pCastSpell->spellnum < SPELL_AIR_WIZARD_EYE)
+      if (pCastSpell->uSpellID < SPELL_AIR_WIZARD_EYE)
         v667 = PLAYER_SKILL_FIRE;
-      else if (pCastSpell->spellnum < SPELL_WATER_AWAKEN)
+      else if (pCastSpell->uSpellID < SPELL_WATER_AWAKEN)
         v667 = PLAYER_SKILL_AIR;
-      else if (pCastSpell->spellnum < SPELL_EARTH_STUN)
+      else if (pCastSpell->uSpellID < SPELL_EARTH_STUN)
         v667 = PLAYER_SKILL_WATER;
-      else if (pCastSpell->spellnum < SPELL_SPIRIT_DETECT_LIFE)
+      else if (pCastSpell->uSpellID < SPELL_SPIRIT_DETECT_LIFE)
         v667 = PLAYER_SKILL_EARTH;
-      else if (pCastSpell->spellnum < SPELL_MIND_REMOVE_FEAR)
+      else if (pCastSpell->uSpellID < SPELL_MIND_REMOVE_FEAR)
         v667 = PLAYER_SKILL_SPIRIT;
-      else if (pCastSpell->spellnum < SPELL_BODY_CURE_WEAKNESS)
+      else if (pCastSpell->uSpellID < SPELL_BODY_CURE_WEAKNESS)
         v667 = PLAYER_SKILL_MIND;
-      else if (pCastSpell->spellnum < SPELL_LIGHT_LIGHT_BOLT)
+      else if (pCastSpell->uSpellID < SPELL_LIGHT_LIGHT_BOLT)
         v667 = PLAYER_SKILL_BODY;
-      else if (pCastSpell->spellnum < SPELL_DARK_REANIMATE)
+      else if (pCastSpell->uSpellID < SPELL_DARK_REANIMATE)
         v667 = PLAYER_SKILL_LIGHT;
-      else if (pCastSpell->spellnum < SPELL_BOW_ARROW)
+      else if (pCastSpell->uSpellID < SPELL_BOW_ARROW)
         v667 = PLAYER_SKILL_DARK;
-      else if (pCastSpell->spellnum == SPELL_BOW_ARROW)
+      else if (pCastSpell->uSpellID == SPELL_BOW_ARROW)
         v667 = PLAYER_SKILL_BOW;
       else assert(false && "Unknown spell");
 
@@ -400,21 +403,21 @@
     if (pCastSpell->forced_spell_skill_level)
       uRequiredMana = 0;
     else 
-      uRequiredMana = pSpellDatas[pCastSpell->spellnum - 1].mana_per_skill[v731 - 1];
-    sRecoveryTime = pSpellDatas[pCastSpell->spellnum - 1].recovery_per_skill[v731 - 1];
+      uRequiredMana = pSpellDatas[pCastSpell->uSpellID - 1].mana_per_skill[v731 - 1];
+    sRecoveryTime = pSpellDatas[pCastSpell->uSpellID - 1].recovery_per_skill[v731 - 1];
 
     if (LODWORD(v725) == PLAYER_SKILL_DARK && pParty->uCurrentHour == 0 && pParty->uCurrentMinute == 0 ||
         LODWORD(v725) == PLAYER_SKILL_LIGHT && pParty->uCurrentHour == 12 && pParty->uCurrentMinute == 0)
       uRequiredMana = 0;
 
-    if (pCastSpell->spellnum < SPELL_BOW_ARROW && pPlayer->sMana < uRequiredMana)
+    if (pCastSpell->uSpellID < SPELL_BOW_ARROW && pPlayer->sMana < uRequiredMana)
     {
       ShowStatusBarString(pGlobalTXT_LocalizationStrings[586], 2u); // "Not enough spell points"
-      pCastSpell->spellnum = 0;
+      pCastSpell->uSpellID = 0;
       continue;
     }
-    v730 = pCastSpell->spellnum;
-    if (pPlayer->IsCursed() && pCastSpell->spellnum < SPELL_BOW_ARROW && rand() % 100 < 50)
+    v730 = pCastSpell->uSpellID;
+    if (pPlayer->IsCursed() && pCastSpell->uSpellID < SPELL_BOW_ARROW && rand() % 100 < 50)
     {
       if (!pParty->bTurnBasedModeOn)
       {
@@ -428,18 +431,18 @@
         //v646 = pPlayer;
         //v648 = sRecoveryTime;
         //v649 = pPlayer;
-        pParty->pTurnBasedPlayerRecoveryTimes[this[n].uPlayerID] = 100;
+        pParty->pTurnBasedPlayerRecoveryTimes[pCastSpellInfo[n].uPlayerID] = 100;
         pPlayer->SetRecoveryTime(sRecoveryTime);
         pTurnEngine->ApplyPlayerAction();
       }
       ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2u); // "Spell failed"
       pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-      this[n].spellnum = 0;
+      pCastSpellInfo[n].uSpellID = 0;
       pPlayer->sMana -= uRequiredMana;
       return;
     }
 
-    switch ( pCastSpell->spellnum )
+    switch ( pCastSpell->uSpellID )
     {
 		case SPELL_101:
 			assert(false && "Unknown spell effect #101 (prolly flaming bow arrow");
@@ -451,7 +454,7 @@
 			sRecoveryTime = pPlayer->GetAttackRecoveryTime(true);
 			pSpellSprite.stru_24.Reset();
 			pSpellSprite.spell_level = v2;
-			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_id = pCastSpell->uSpellID;
 			pSpellSprite.spell_skill = v731;
 			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
 			if ( pPlayer->WearsItem(ITEM_ARTEFACT_ULLYSES, EQUIP_BOW) )
@@ -486,7 +489,7 @@
 		{
 			sRecoveryTime = pPlayer->GetAttackRecoveryTime(0);
 			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_id = pCastSpell->uSpellID;
 			pSpellSprite.spell_level = v723;
 			pSpellSprite.spell_skill = v731;
 			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
@@ -569,13 +572,13 @@
 			{
 				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
 				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
+				pCastSpell->uSpellID = 0;
 				continue;
 			}
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
 			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_id = pCastSpell->uSpellID;
 			pSpellSprite.spell_level = v2;
 			pSpellSprite.spell_skill = v731;
 			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
@@ -606,7 +609,7 @@
 			{
 				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
 				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
+				pCastSpell->uSpellID = 0;
 				continue;
 			}
 			if (PID_TYPE(a2) != OBJECT_Actor)
@@ -618,7 +621,7 @@
 			v697.y = 0;
 			v697.z = 0;
 			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_id = pCastSpell->uSpellID;
 			pSpellSprite.spell_level = v2;
 			pSpellSprite.spell_skill = v731;
 			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
@@ -652,7 +655,7 @@
 			v704.y = 0;
 			v704.z = 0;
 			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_id = pCastSpell->uSpellID;
 			pSpellSprite.spell_level = v2;
 			pSpellSprite.spell_skill = v731;
 			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
@@ -682,7 +685,7 @@
 			v691.y = 0;
 			v691.z = 0;
 			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_id = pCastSpell->uSpellID;
 			pSpellSprite.spell_level = v2;
 			pSpellSprite.spell_skill = v731;
 			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
@@ -703,7 +706,7 @@
 			{
 				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
 				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
+				pCastSpell->uSpellID = 0;
 				continue;
 			}
 			DamageMonsterFromParty(PID(OBJECT_Item, obj_id), PID_ID(a2), &v691);
@@ -727,7 +730,7 @@
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
 			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_id = pCastSpell->uSpellID;
 			pSpellSprite.spell_level = v2;
 			pSpellSprite.spell_skill = v731;
 			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
@@ -747,7 +750,7 @@
 			pSpellSprite.uSoundID = LOWORD(pCastSpell->sound_id);
 			if ( pParty->bTurnBasedModeOn == 1 )
 				LOBYTE(pSpellSprite.uAttributes) |= 4u;
-			if ( pCastSpell->spellnum == SPELL_AIR_LIGHNING_BOLT )
+			if ( pCastSpell->uSpellID == SPELL_AIR_LIGHNING_BOLT )
 				LOBYTE(pSpellSprite.uAttributes) |= 0x40u;
 			v659 = pObjectList->pObjects[(signed __int16)pSpellSprite.uObjectDescID].uSpeed;
 			if ( pSpellSprite.Create(v715.uYawAngle, v715.uPitchAngle, v659, pCastSpell->uPlayerID + 1) != -1 && pParty->bTurnBasedModeOn == 1 )
@@ -763,7 +766,7 @@
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
 			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_id = pCastSpell->uSpellID;
 			pSpellSprite.spell_level = v2;
 			pSpellSprite.spell_skill = v731;
 			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
@@ -797,13 +800,13 @@
 			{
 				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
 				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
+				pCastSpell->uSpellID = 0;
 				continue;
 			}
 			if ( pPlayer->CanCastSpell(uRequiredMana) )
 			{
 				pSpellSprite.stru_24.Reset();
-				pSpellSprite.spell_id = pCastSpell->spellnum;
+				pSpellSprite.spell_id = pCastSpell->uSpellID;
 				pSpellSprite.spell_skill = v731;
 				pSpellSprite.spell_level = v2;
 				pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
@@ -915,7 +918,7 @@
 		pActors[PID_ID(a2)].pActorBuffs[1].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)(power << 7) * 0.033333335),
 			v731, 0, 0, 0);
 		pSpellSprite.stru_24.Reset();
-		pSpellSprite.spell_id = pCastSpell->spellnum;
+		pSpellSprite.spell_id = pCastSpell->uSpellID;
 		pSpellSprite.spell_level = v2;
 		pSpellSprite.spell_skill = v731;
 		v60 = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
@@ -995,7 +998,7 @@
 			auto _itm = &pItemsTable->pItems[v730c->uItemID];
 			v730c->UpdateTempBonus(pParty->uTimePlayed);
 			if ( v730c->uItemID < 64 || v730c->uItemID > 65 
-				&& !v730c->Broken()
+				&& !v730c->IsBroken()
 				&& !v730c->uSpecEnchantmentType
 				&& !v730c->uEnchantmentType
 				&& ( _itm->uEquipType == 0 || _itm->uEquipType == 1 || _itm->uEquipType == 2)
@@ -1023,7 +1026,7 @@
 
 			ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
 			pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-			pCastSpell->spellnum = 0;
+			pCastSpell->uSpellID = 0;
 			continue;
 		}
 		case SPELL_BODY_REGENERATION:
@@ -1040,7 +1043,7 @@
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
 
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, pCastSpell->uPlayerID_2);
 
 			pParty->pPlayers[pCastSpell->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_REGENERATION].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)v733 * 4.2666669), v731, amount, 0, 0);
 			LODWORD(v727) = 1;
@@ -1063,7 +1066,7 @@
 				assert(false);
 			}
 
-			switch (pCastSpell->spellnum)
+			switch (pCastSpell->uSpellID)
 			{
 			  case SPELL_FIRE_PROTECTION_FROM_FIRE:
 				LODWORD(v725) = PARTY_BUFF_RESIST_FIRE;
@@ -1089,10 +1092,10 @@
 			}
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 			  break;
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 0);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 1);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 2);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 3);
 			v90 = (double)(signed int)v733 * 4.2666669;
 			pParty->pPartyBuffs[LODWORD(v725)].Apply(pParty->uTimePlayed + (signed int)(signed __int64)v90, v731, amount, 0, 0);
 			LODWORD(v727) = 1;
@@ -1124,10 +1127,10 @@
 				{
 					pParty->pPartyBuffs[PARTY_BUFF_HASTE].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, 0, 0, 0);
 
-					pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
-					pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
-					pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
-					pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
+					pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 0);
+					pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 1);
+					pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 2);
+					pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 3);
 				}
 			}
 			break;
@@ -1149,7 +1152,7 @@
 			if ( v731 == 1 )
 			{
 				v108 = pCastSpell->uPlayerID_2;
-				v109 = pCastSpell->spellnum;
+				v109 = pCastSpell->uSpellID;
 				v110 = pGame->GetStru6();
 				pGame->GetStru6()->SetPlayerBuffAnim(v109, v108);
 				v111 = pOtherOverlayList->_4418B1(10000, pCastSpell->uPlayerID_2 + 310, 0, 65536);
@@ -1173,7 +1176,7 @@
 			v730b = pParty->pPlayers;//[0].pPlayerBuffs[1];
 			do
 			{
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, v105);
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, v105);
 				v716 = pOtherOverlayList->_4418B1(10000, v105 + 310, 0, 65536);
 				v730b->pPlayerBuffs[1].Apply(pParty->uTimePlayed + v717, v731, amount, v716, 0);
 				++v730b;
@@ -1214,13 +1217,13 @@
 					v114 = v118;
 				}
 				_this = (ItemGen *)(((unsigned int)(11 * v114) >> 5) + (v115 >> 2) + v113);
-				if ( (double)(signed int)this <= 307.2 )
+				if ( (double)(signed int)_this <= 307.2 )
 				{
 					v701.x = 0;
 					v701.y = 0;
 					v701.z = 0;
 					pSpellSprite.stru_24.Reset();
-					pSpellSprite.spell_id = pCastSpell->spellnum;
+					pSpellSprite.spell_id = pCastSpell->uSpellID;
 					pSpellSprite.spell_level = v723;
 					pSpellSprite.spell_skill = v731;
 					pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
@@ -1243,7 +1246,7 @@
 				{
 					ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2u);
 					pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-					pCastSpell->spellnum = 0;
+					pCastSpell->uSpellID = 0;
 				}
 				//pCastSpell = (CastSpellInfo *)HIDWORD(v733);
 			}
@@ -1262,7 +1265,7 @@
 				default:
 				assert(false);
 			}
-			v127 = pCastSpell->spellnum;
+			v127 = pCastSpell->uSpellID;
 			if ( v127 == 17 )
 			{
 				amount = 0;
@@ -1285,10 +1288,10 @@
 			}
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 0);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 1);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 2);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 3);
 			v90 = (double)(signed int)((int)v733 << 7) * 0.033333335;
 	//LABEL_304:
 			pParty->pPartyBuffs[LODWORD(v725)].Apply(pParty->uTimePlayed + (signed int)(signed __int64)v90, v731, amount, 0, 0);
@@ -1304,10 +1307,10 @@
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
 
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 0);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 1);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 2);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 3);
 
 			pParty->pPartyBuffs[PARTY_BUFF_IMMOLATION].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, v2, 0, 0);
 			LODWORD(v727) = 1;
@@ -1330,7 +1333,7 @@
 			{
 				ShowStatusBarString(pGlobalTXT_LocalizationStrings[491], 2);  // Can't cast Meteor Shower indoors!
 				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
+				pCastSpell->uSpellID = 0;
 				continue;
 			}
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
@@ -1374,7 +1377,7 @@
 													stru_5C6E00->Atan2(j, k));
 					}
 					pSpellSprite.stru_24.Reset();
-					pSpellSprite.spell_id = pCastSpell->spellnum;
+					pSpellSprite.spell_id = pCastSpell->uSpellID;
 					pSpellSprite.spell_level = v2;
 					pSpellSprite.spell_skill = v731;
 					pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
@@ -1409,7 +1412,7 @@
 			{
 				ShowStatusBarString(pGlobalTXT_LocalizationStrings[492], 2); // Can't cast Inferno outdoors!
 				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
+				pCastSpell->uSpellID = 0;
 				continue;
 			}
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
@@ -1419,7 +1422,7 @@
 			v700.y = 0;
 			v700.x = 0;
 			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_id = pCastSpell->uSpellID;
 			pSpellSprite.spell_level = v2;
 			pSpellSprite.spell_skill = v731;
 			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
@@ -1486,10 +1489,10 @@
 			do
 				pOtherOverlayList->_4418B1(2010, v174++ + 100, 0, 65536);
 			while ( v174 < 4 );
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 0);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 1);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 2);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 3);
 
 			pParty->pPartyBuffs[PARTY_BUFF_FEATHER_FALL].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, 0, 0, 0);
 			LODWORD(v727) = 1;
@@ -1510,7 +1513,7 @@
 				break;
 			auto _v726 = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360;
 			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_id = pCastSpell->uSpellID;
 			pSpellSprite.spell_level = v2;
 			pSpellSprite.spell_skill = v731;
 			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
@@ -1580,15 +1583,15 @@
 			{
 				ShowStatusBarString(pGlobalTXT_LocalizationStrings[638], 2);  // There are hostile creatures nearby!
 				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
+				pCastSpell->uSpellID = 0;
 				continue;
 			}
 			if ( pPlayer->CanCastSpell(uRequiredMana) )
 			{
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 0);
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 1);
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 2);
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 3);
 
 				pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, amount, 0, 0);
 				LODWORD(v727) = 1;
@@ -1635,7 +1638,7 @@
 			{
 				ShowStatusBarString(pGlobalTXT_LocalizationStrings[495], 2);  // Can't cast Starburst indoors!
 				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
+				pCastSpell->uSpellID = 0;
 				continue;
 			}
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
@@ -1690,7 +1693,7 @@
 								stru_5C6E00->Atan2((signed __int64)v216, (signed __int64)*(float *)&uRequiredMana));
 				}
 				pSpellSprite.stru_24.Reset();
-				pSpellSprite.spell_id = pCastSpell->spellnum;
+				pSpellSprite.spell_id = pCastSpell->uSpellID;
 				pSpellSprite.spell_level = v2;
 				pSpellSprite.spell_skill = v731;
 				pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
@@ -1775,7 +1778,7 @@
 			if ( amount == 1 )
 			{
 				pSpellSprite.stru_24.Reset();
-				pSpellSprite.spell_id = pCastSpell->spellnum;
+				pSpellSprite.spell_id = pCastSpell->uSpellID;
 				pSpellSprite.spell_skill = v731;
 				pSpellSprite.spell_level = v2;
 				pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
@@ -1804,7 +1807,7 @@
 			else
 			{
 				pSpellSprite.stru_24.Reset();
-				pSpellSprite.spell_id = pCastSpell->spellnum;
+				pSpellSprite.spell_id = pCastSpell->uSpellID;
 				pSpellSprite.spell_level = v2;
 				pSpellSprite.spell_skill = v731;
 				pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
@@ -1859,10 +1862,10 @@
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
 			v716 = pOtherOverlayList->_4418B1(10005, 201, 0, 65536);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 0);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 1);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 2);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 3);
 
 			pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].Apply(
 				pParty->uTimePlayed + (signed int)(signed __int64)((double)(v229 << 7) * 0.033333335),
@@ -1889,7 +1892,7 @@
 
 				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2);  // Spell failed
 				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
+				pCastSpell->uSpellID = 0;
 				continue;
 			}
 			if ( v731 == 1 || v731 == 2 )
@@ -1921,7 +1924,7 @@
 				dword_50C9D8 = 1;
 				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2u);
 				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
+				pCastSpell->uSpellID = 0;
 				v2 = v723;
 				continue;
 			}
@@ -1947,7 +1950,7 @@
 				v245->uSpecEnchantmentType == 0 &&
 				v245->uEnchantmentType == 0 &&
 				v245->_bonus_strength== 0 &&
-				!v245->Broken() )
+				!v245->IsBroken() )
 			{
 				if ( v245->GetValue() < 450 || 
 					(v245->GetValue() < 250 && (v731 == 3 || v731 == 4) && _v725->uEquipType >= 0 && _v725->uEquipType <= 2)
@@ -2096,7 +2099,7 @@
 				ShowStatusBarString(v317, 2u);
 				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
 				v318 =  &pParty->pPlayers[pCastSpell->uPlayerID_2];
-				pCastSpell->spellnum = 0;
+				pCastSpell->uSpellID = 0;
 				v318->PlaySound(SPEECH_43, 0);
 			}
 
@@ -2111,7 +2114,7 @@
 			{
 				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
 				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
+				pCastSpell->uSpellID = 0;
 				continue;
 			}
 			town_portal_caster_id = LOBYTE(pCastSpell->uPlayerID);
@@ -2126,7 +2129,7 @@
 			{
 				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
 				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
+				pCastSpell->uSpellID = 0;
 				continue;
 			}
 			v319 = uRequiredMana;
@@ -2139,8 +2142,8 @@
 				::uRequiredMana = v319;
 				::sRecoveryTime = sRecoveryTime;
 				dword_50633C = pCastSpell->sound_id;
-				dword_506338 = pCastSpell->spellnum;
-				LOBYTE(pCastSpell->field_8) |= 0x20u;
+				dword_506338 = pCastSpell->uSpellID;
+				pCastSpell->uFlags |= 0x20u;
 			}
 			break;
 		}
@@ -2186,7 +2189,7 @@
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
 			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_id = pCastSpell->uSpellID;
 			pSpellSprite.spell_level = v2;
 			pSpellSprite.spell_skill = v731;
 			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
@@ -2219,14 +2222,14 @@
 			{
 				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
 				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
+				pCastSpell->uSpellID = 0;
 				continue;
 			}
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
 			pSpellSprite.uType = 4090;
 			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_id = pCastSpell->uSpellID;
 			pSpellSprite.spell_level = v2;
 			pSpellSprite.spell_skill = v731;
 			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
@@ -2268,10 +2271,10 @@
 			LODWORD(v733) = v330;
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 0);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 1);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 2);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 3);
 
 			pParty->pPartyBuffs[PARTY_BUFF_DETECT_LIFE].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, 0, 0, 0);
 			LODWORD(v727) = 1;
@@ -2294,7 +2297,7 @@
 			v342 = pCastSpell->spell_target_pid;
 			if ( v342 == 0 )
 			{
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, pCastSpell->uPlayerID_2);
 
 				pParty->pPlayers[pCastSpell->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_FATE].Apply(pParty->uTimePlayed + 1280, v731, amount, 0, 0);
 				LODWORD(v727) = 1;
@@ -2348,7 +2351,7 @@
 					break;
 				}
 			}
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, pCastSpell->uPlayerID_2);
 			LODWORD(v727) = 1;
 			break;
 		}
@@ -2362,7 +2365,7 @@
 				break;
 			if ( v731 == 1 || v731 == 2 )
 			{
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, pCastSpell->uPlayerID_2);
 				pParty->pPlayers[pCastSpell->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_PRESERVATION].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, 0, 0, 0);
 				LODWORD(v727) = 1;
 				break;
@@ -2372,7 +2375,7 @@
 			v357 = pParty->pPlayers;//[0].pPlayerBuffs[11];
 			do
 			{
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, a2);
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, a2);
 				v357->pPlayerBuffs[PLAYER_BUFF_PRESERVATION].Apply(pParty->uTimePlayed + v717, v731, 0, 0, 0);
 				++a2;
 				++v357;// = (SpellBuff *)((char *)v357 + 6972);
@@ -2393,7 +2396,7 @@
 			pGame->GetStru6()->FadeScreen__like_Turn_Undead_and_mb_Armageddon(0xFFFFFFu, 0xC0u);
 			++pSpellSprite.uType;
 			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_id = pCastSpell->uSpellID;
 			pSpellSprite.spell_level = v2;
 			pSpellSprite.spell_skill = v731;
 			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
@@ -2510,7 +2513,7 @@
 					}
 					v388 = _v733;
 
-					pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, LOWORD(v682[_v733]) - 1);
+					pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, LOWORD(v682[_v733]) - 1);
 					_v733 = v388 + 1;
 				}
 				while ( v388 + 1 < v730 );
@@ -2561,7 +2564,7 @@
 				}
 				pParty->pPlayers[pCastSpell->uPlayerID_2].SetCondition(1u, 1);
 				pParty->pPlayers[pCastSpell->uPlayerID_2].sHealth = 1;
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, pCastSpell->uPlayerID_2);
 			}
 			LODWORD(v727) = 1;
 			break;
@@ -2580,7 +2583,7 @@
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
 
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, pCastSpell->uPlayerID_2);
 			v323 = pCastSpell->uPlayerID_2;
 			v324 = (char *)&pParty->pPlayers[v323].pConditions[12];
 			if ( !pParty->pPlayers[v323].pConditions[12] )
@@ -2617,7 +2620,7 @@
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
 
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, pCastSpell->uPlayerID_2);
 			v323 = pCastSpell->uPlayerID_2;
 			v324 = (char *)&pParty->pPlayers[v323].pConditions[3];
 			if ( !pParty->pPlayers[v323].pConditions[3] )
@@ -2719,7 +2722,7 @@
 			}
 			ShowStatusBarString(pTmpBuf2.data(), 2u);
 			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_id = pCastSpell->uSpellID;
 			pSpellSprite.spell_level = v2;
 			pSpellSprite.spell_skill = v731;
 			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
@@ -2772,7 +2775,7 @@
 				pActors[v426].pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Long;
 			}
 			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_id = pCastSpell->uSpellID;
 			pSpellSprite.spell_level = v2;
 			pSpellSprite.spell_skill = v731;
 			v60 = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
@@ -2822,7 +2825,7 @@
 				v731, 0, 0, 0);
 			}
 			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_id = pCastSpell->uSpellID;
 			pSpellSprite.spell_level = v2;
 			pSpellSprite.spell_skill = v731;
 			v60 = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
@@ -2863,7 +2866,7 @@
 			pGame->GetStru6()->FadeScreen__like_Turn_Undead_and_mb_Armageddon(0xA0A0Au, 0xC0u);
 			++pSpellSprite.uType;
 			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_id = pCastSpell->uSpellID;
 			pSpellSprite.spell_level = v2;
 			pSpellSprite.spell_skill = v731;
 			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
@@ -2904,7 +2907,7 @@
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
 
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, pCastSpell->uPlayerID_2);
 			v440 = pCastSpell->uPlayerID_2;
 			if ( HIDWORD(pParty->pPlayers[v440].pConditions[5]) | LODWORD(pParty->pPlayers[v440].pConditions[5]) )
 			{
@@ -2954,7 +2957,7 @@
 				{
 					sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[471], pItemsTable->pItems[v450].pUnidentifiedName);
 					ShowStatusBarString(pTmpBuf2.data(), 2u);
-					if ( !pParty->AddItem(&pSpriteObjects[v445].stru_24) )
+					if ( !pParty->AddItemToParty(&pSpriteObjects[v445].stru_24) )
 						pParty->SetHoldingItem(&pSpriteObjects[v445].stru_24);
 				}
 				SpriteObject::OnInteraction(v445);
@@ -2984,7 +2987,7 @@
 						break;
 					}
 					OpenedTelekinesis = true;
-					if ( pLevelDecorations[v445].field_16_event_id )
+					if ( pLevelDecorations[v445].uEventID )
 					{
 						EventProcessor(v448, a2, 1);
 						LODWORD(v727) = 1;
@@ -3015,7 +3018,7 @@
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
 
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, pCastSpell->uPlayerID_2);
 			v323 = pCastSpell->uPlayerID_2;
 			v324 = (char *)&pParty->pPlayers[v323].pConditions[1];
 			if ( !pParty->pPlayers[v323].pConditions[1] )
@@ -3054,7 +3057,7 @@
 			if (!v460)
 			{
 				pParty->pPlayers[pCastSpell->uPlayerID_2].Heal(amount);
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, pCastSpell->uPlayerID_2);
 			}
 			else
 			{
@@ -3097,7 +3100,7 @@
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
 
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, pCastSpell->uPlayerID_2);
 			v470 = pCastSpell->uPlayerID_2;
 			if ( !(HIDWORD(pParty->pPlayers[v470].pConditions[6]) | LODWORD(pParty->pPlayers[v470].pConditions[6]))
 				&& !(HIDWORD(pParty->pPlayers[v470].pConditions[8]) | LODWORD(pParty->pPlayers[v470].pConditions[8]))
@@ -3140,10 +3143,10 @@
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
 
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 0);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 1);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 2);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 3);
 
 			pParty->pPartyBuffs[PARTY_BUFF_PROTECTION_FROM_MAGIC].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, v2, 0, 0);
 			LODWORD(v727) = 1;
@@ -3157,10 +3160,10 @@
 				break;
 			if ( v731 == 4 )
 			{
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 0);
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 1);
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 2);
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 3);
 				v732 = (int)v733 << 7;
 				v717 = (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
 				pParty->pPlayers[0].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].Apply(pParty->uTimePlayed + v717, 4u, v2, v2, 0);
@@ -3171,7 +3174,7 @@
 				LODWORD(v727) = 1;
 				break;
 			}
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, pCastSpell->uPlayerID_2);
 
 			pParty->pPlayers[pCastSpell->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, v2, v2, 0);
 			LODWORD(v727) = 1;
@@ -3186,7 +3189,7 @@
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
 
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, pCastSpell->uPlayerID_2);
 			v498 = pCastSpell->uPlayerID_2;
 			if ( !(HIDWORD(pParty->pPlayers[v498].pConditions[7]) | LODWORD(pParty->pPlayers[v498].pConditions[7]))
 				&& !(HIDWORD(pParty->pPlayers[v498].pConditions[9]) | LODWORD(pParty->pPlayers[v498].pConditions[9]))
@@ -3232,7 +3235,7 @@
 			int v1 = 0;
 			do
 			{
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, v1);
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, v1);
 				v501->Heal(amount);
 				++v501;
 				++v1;
@@ -3255,7 +3258,7 @@
 			v688.y = 0;
 			v688.z = 0;
 			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_id = pCastSpell->uSpellID;
 			pSpellSprite.spell_level = v2;
 			pSpellSprite.spell_skill = v731;
 			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
@@ -3324,7 +3327,7 @@
 			{
 				ShowStatusBarString(pGlobalTXT_LocalizationStrings[648], 2);  // This character can't summon any more monsters!
 				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
+				pCastSpell->uSpellID = 0;
 				continue;
 			}
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
@@ -3347,10 +3350,10 @@
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
 
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 0);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 1);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 2);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 3);
 
 			pParty->pPartyBuffs[PARTY_BUFF_DAY_OF_GODS].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, amount, 0, 0);
 			LODWORD(v727) = 1;
@@ -3363,7 +3366,7 @@
 			{
 				ShowStatusBarString(pGlobalTXT_LocalizationStrings[497], 2);  // Can't cast Prismatic Light outdoors!
 				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
+				pCastSpell->uSpellID = 0;
 				continue;
 			}
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
@@ -3374,7 +3377,7 @@
 			v694.y = 0;
 			v694.z = 0;
 			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_id = pCastSpell->uSpellID;
 			pSpellSprite.spell_level = v2;
 			pSpellSprite.spell_skill = v731;
 			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
@@ -3422,10 +3425,10 @@
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
 
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
-			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 0);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 1);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 2);
+			pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 3);
 
 			v732 = v730 << 7;
 			v549 = (double)(v730 << 7) * 0.033333335;
@@ -3468,10 +3471,10 @@
 			*((float *)&v733) = (double)v732 * 0.033333335;
 			do
 			{
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 0);
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 1);
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 2);
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, 3);
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 0);
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 1);
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 2);
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, 3);
 
 				//((SpellBuff *)(v553 + 6056))->Apply(
 				v553->pPlayerBuffs[4].Apply((signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733)), v731, v730, 0, 0);
@@ -3498,7 +3501,7 @@
 			{
 				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
 				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
+				pCastSpell->uSpellID = 0;
 				continue;
 			}
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
@@ -3521,11 +3524,11 @@
 				*(int *)(_this->uItemID + 6460) = v565;
 				v567 = (*v566)->GetMaxMana();
 				*(int *)(_this->uItemID + 6464) = v567;
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, a2);
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, a2);
 				++a2;
 				_this = (ItemGen *)((char *)_this + 4);
 			}
-			while ( (signed int)this < (signed int)&qword_A750D8 );
+			while ( (signed int)_this < (signed int)&qword_A750D8 );
 			v571 = pPlayer;
 			v572 = (char *)&pPlayer->sAgeModifier;
 			if ( pPlayer->sAgeModifier + 10 >= 120 )
@@ -3554,7 +3557,7 @@
 			if (!v576)
 			{
 				v585 = (char *)&pParty->pPlayers[pCastSpell->uPlayerID_2];
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, pCastSpell->uPlayerID_2);
 				if ( *((_QWORD *)v585 + 14) )
 				{
 				((Player *)v585)->SetCondition(0x11u, 1);
@@ -3570,7 +3573,7 @@
 			{
 				ShowStatusBarString(pGlobalTXT_LocalizationStrings[496], 2);  // No valid target exists!
 				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
+				pCastSpell->uSpellID = 0;
 				continue;
 			}
 			v578 = (int)&pActors[(int)v577];
@@ -3579,12 +3582,12 @@
 			{
 				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
 				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
+				pCastSpell->uSpellID = 0;
 				continue;
 			}
 			++pSpellSprite.uType;
 			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_id = pCastSpell->uSpellID;
 			pSpellSprite.spell_level = v2;
 			pSpellSprite.spell_skill = v731;
 			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
@@ -3653,7 +3656,7 @@
 
 				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
 				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
+				pCastSpell->uSpellID = 0;
 				continue;
 			}
 			v592 = _v733;
@@ -3685,7 +3688,7 @@
 				break;
 			auto _v726 = ((signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360);
 			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_id = pCastSpell->uSpellID;
 			pSpellSprite.spell_level = v2;
 			pSpellSprite.spell_skill = v731;
 			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
@@ -3751,7 +3754,7 @@
 			{
 				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
 				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
+				pCastSpell->uSpellID = 0;
 				continue;
 			}
 			pActor->pActorBuffs[9].Reset();
@@ -3759,7 +3762,7 @@
 			pActor->pActorBuffs[12].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335),
 				v731, 0, 0, 0);
 			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_id = pCastSpell->uSpellID;
 			pSpellSprite.spell_level = v2;
 			pSpellSprite.spell_skill = v731;
 			v60 = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
@@ -3835,7 +3838,7 @@
 			{
 				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
 				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
+				pCastSpell->uSpellID = 0;
 				continue;
 			}
 			v610 = 76 * v609;
@@ -3880,7 +3883,7 @@
 				break;
 			if ( v731 != 3 && v731 != 4 )
 			{
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, pCastSpell->uPlayerID_2);
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, pCastSpell->uPlayerID_2);
 				pParty->pPlayers[pCastSpell->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_PAIN_REFLECTION].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, amount, v716, 0);
 				LODWORD(v727) = 1;
 				break;
@@ -3890,7 +3893,7 @@
 			v619 = pParty->pPlayers;//[0].pPlayerBuffs[10];
 			do
 			{
-				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, a2);
+				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, a2);
 				v619->pPlayerBuffs[PLAYER_BUFF_PAIN_REFLECTION].Apply(pParty->uTimePlayed + v717, v731, amount, v716, 0);
 				++a2;
 				++v619;
@@ -3910,7 +3913,7 @@
 			v707.y = 0;
 			v707.z = 0;
 			pSpellSprite.stru_24.Reset();
-			pSpellSprite.spell_id = pCastSpell->spellnum;
+			pSpellSprite.spell_id = pCastSpell->uSpellID;
 			pSpellSprite.spell_level = v2;
 			pSpellSprite.spell_skill = v731;
 			pSpellSprite.uObjectDescID = pObjectList->ObjectIDByItemID(pSpellSprite.uType);
@@ -3975,7 +3978,7 @@
 						v726->sHealth = v726->GetMaxHealth();
 					v635 = _v733;
 
-					pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->spellnum, WORD2(v733));
+					pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, WORD2(v733));
 					_v733 = v635 + 1;
 				}
 				while ( v635 + 1 < v730 );
@@ -3990,7 +3993,7 @@
 			{
 				ShowStatusBarString(pGlobalTXT_LocalizationStrings[499], 2);  // Can't cast Armageddon indoors!
 				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
+				pCastSpell->uSpellID = 0;
 				continue;
 			}
 			if ( v731 == 4)
@@ -4001,7 +4004,7 @@
 			{
 				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
 				pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-				pCastSpell->spellnum = 0;
+				pCastSpell->uSpellID = 0;
 				continue;
 			}
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
@@ -4031,10 +4034,10 @@
 		default:
 			break;
 	}
-	if ( pCastSpell->field_8 & 0x20 )
+	if ( pCastSpell->uFlags & 0x20 )
 	{
 		if ( v727 != 0.0 )
-			pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[pCastSpell->spellnum], 0, 0, -1, 0, pCastSpell->sound_id, 0, 0);
+			pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[pCastSpell->uSpellID], 0, 0, -1, 0, pCastSpell->sound_id, 0, 0);
 	}
 	else
 	{
@@ -4057,63 +4060,52 @@
 		{
 			pPlayer->PlaySound(SPEECH_49, 0);
 			if ( v727 != 0.0 )
-				pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[pCastSpell->spellnum], 0, 0, -1, 0, pCastSpell->sound_id, 0,	0);
+				pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[pCastSpell->uSpellID], 0, 0, -1, 0, pCastSpell->sound_id, 0,	0);
 		}
 	}
-	pCastSpell->spellnum = 0;
+	pCastSpell->uSpellID = 0;
 	v2 = v723;
 	continue;
   }
   
 }
 //----- (00427DA0) --------------------------------------------------------
-unsigned int CastSpellInfo::PushCastSpellInfo(__int16 a2, __int16 uPlayerID, __int16 skill_level, __int16 a5, int spell_sound_id)
+size_t PushCastSpellInfo(uint16_t uSpellID, uint16_t uPlayerID, __int16 skill_level, uint16_t uFlags, int spell_sound_id)
 {
-  for ( uint i = 0; i < 10; i++ )
+  for (size_t i = 0; i < CastSpellInfoCount; i++)
   {
-    if ( !this[i].spellnum )
+    if (!pCastSpellInfo[i].uSpellID)
     {
-      this[i].spellnum = a2;
-      this[i].uPlayerID = uPlayerID;
-      if ( a5 & 0x10 )
-        this[i].uPlayerID_2 = uPlayerID;
-      this[i].field_6 = 0;
-      this[i].spell_target_pid = 0;
-      this[i].field_8 = a5;
-      this[i].forced_spell_skill_level = skill_level;
-      this[i].sound_id = spell_sound_id;
+      pCastSpellInfo[i].uSpellID = uSpellID;
+      pCastSpellInfo[i].uPlayerID = uPlayerID;
+      if (uFlags & 0x10)
+        pCastSpellInfo[i].uPlayerID_2 = uPlayerID;
+      pCastSpellInfo[i].field_6 = 0;
+      pCastSpellInfo[i].spell_target_pid = 0;
+      pCastSpellInfo[i].uFlags = uFlags;
+      pCastSpellInfo[i].forced_spell_skill_level = skill_level;
+      pCastSpellInfo[i].sound_id = spell_sound_id;
       return i;
     }
   }
   return -1;
 }
 //----- (00427D48) --------------------------------------------------------
-void CastSpellInfo::_427D48(unsigned int uPlayerID)//Press S
+void CastSpellInfoHelpers::_427D48()
 {
-  CastSpellInfo *v2; // esi@1
-  signed int v3; // ebx@1
-
-  v2 = this;
-  v3 = 10;
-  do
+  for (size_t i = 0; i < CastSpellInfoCount; i++)
   {
-    if ( v2->spellnum )
+    if (pCastSpellInfo[i].uSpellID && pCastSpellInfo[i].uFlags & 0x3CA)
     {
-      if ( v2->field_8 & 0x3CA )
-      {
-        v2->spellnum = 0;
-        pGUIWindow_Settings->Release();
-        pGUIWindow_Settings = 0;
-        pMouse->SetCursorBitmap("MICON1");
-        GameUI_Footer_TimeLeft = 0;
-        unk_50C9A0 = 0;
-        back_to_game();
-      }
+      pCastSpellInfo[i].uSpellID = 0;
+      pGUIWindow_Settings->Release();
+      pGUIWindow_Settings = 0;
+      pMouse->SetCursorBitmap("MICON1");
+      GameUI_Footer_TimeLeft = 0;
+      unk_50C9A0 = 0;
+      back_to_game();
     }
-    ++v2;
-    --v3;
   }
-  while ( v3 );
 }
 //----- (0042777D) --------------------------------------------------------
 void _42777D_CastSpell_UseWand_ShootArrow(int a1, unsigned int uPlayerID, unsigned int a4, __int16 a5, int a6)
@@ -4316,24 +4308,22 @@
 
     if (a5 & 0x3CA)
     {
-      assert(sizeof(pCastSpellInfo) / sizeof(*pCastSpellInfo.data()) == 10);
-      for (uint i = 0; i < 10; ++i)
-        if (pCastSpellInfo[i].field_8 & 0x3CA)
+      for (uint i = 0; i < CastSpellInfoCount; ++i)
+        if (pCastSpellInfo[i].uFlags & 0x3CA)
         {
-          pCastSpellInfo[i].spellnum = 0;
+          pCastSpellInfo[i].uSpellID = 0;
           break;
         }
     }
       
-    assert(sizeof(pCastSpellInfo) / sizeof(*pCastSpellInfo.data()) == 10);
-    for (uint i = 0; i < 10; ++i)
+    for (uint i = 0; i < CastSpellInfoCount; ++i)
     {
       auto spell = &pCastSpellInfo[i];
-      if (!spell->spellnum)
+      if (!spell->uSpellID)
         continue;
 
-      spell->spellnum = 0;
-      if (spell->field_8 & 0x3CA)
+      spell->uSpellID = 0;
+      if (spell->uFlags & 0x3CA)
       {
         pGUIWindow_Settings->Release();
         pGUIWindow_Settings = nullptr;
@@ -4344,7 +4334,7 @@
       }
     }
 
-    int result = pCastSpellInfo.data()->PushCastSpellInfo(a1, uPlayerID, a4, a5, a6);
+    int result = PushCastSpellInfo(a1, uPlayerID, a4, a5, a6);
     if ( result != -1 )
     {
       if ( a5 & 2 )
@@ -4422,101 +4412,3 @@
       }
     }
 }
-
-const wchar_t *UIMessage2String(UIMessageType msg)
-{
-  #define CASE(xxx) case xxx: swprintf(b, wcslen(L"%03X/%s"), L"%03X/%s", msg, L#xxx); return b;
-  static wchar_t b[256]; // bad for threads
-  switch (msg)
-  {
-    CASE(UIMSG_SelectSpell)
-    CASE(UIMSG_ChangeGameState)
-    CASE(UIMSG_Attack)
-    CASE(UIMSG_PlayArcomage)
-    CASE(UIMSG_MainMenu_ShowPartyCreationWnd)
-    CASE(UIMSG_MainMenu_ShowLoadWindow)
-    CASE(UIMSG_ShowCredits)
-    CASE(UIMSG_ExitToWindows)
-    CASE(UIMSG_PlayerCreationChangeName)
-    CASE(UIMSG_PlayerCreationClickPlus)
-    CASE(UIMSG_PlayerCreationClickMinus)
-    CASE(UIMSG_PlayerCreationSelectActiveSkill)
-    CASE(UIMSG_PlayerCreationSelectClass)
-    CASE(UIMSG_PlayerCreationClickOK)
-    CASE(UIMSG_PlayerCreationClickReset)
-    CASE(UIMSG_ClickBooksBtn)
-    CASE(UIMSG_PlayerCreationRemoveUpSkill)
-    CASE(UIMSG_PlayerCreationRemoveDownSkill)
-    CASE(UIMSG_SPellbook_ShowHightlightedSpellInfo)
-    CASE(UIMSG_LoadGame)
-    CASE(UIMSG_SaveGame)
-    CASE(UIMSG_ShowStatus_DateTime)
-    CASE(UIMSG_ShowStatus_ManaHP)
-    CASE(UIMSG_ShowStatus_Player)
-    CASE(UIMSG_Wait5Minutes)
-    CASE(UIMSG_Wait1Hour)
-    CASE(UIMSG_ShowStatus_Food)
-    CASE(UIMSG_ShowStatus_Funds)
-    CASE(UIMSG_QuickReference)
-    CASE(UIMSG_GameMenuButton)
-    CASE(UIMSG_AlreadyResting)
-    CASE(UIMSG_SelectCharacter)
-    CASE(UIMSG_ChangeSoundVolume)
-    CASE(UIMSG_ChangeMusicVolume)
-    CASE(UIMSG_Escape)
-    CASE(UIMSG_PlayerCreation_SelectAttribute)
-    CASE(UIMSG_InventoryLeftClick)
-    CASE(UIMSG_SkillUp)
-    CASE(UIMSG_GameMenu_ReturnToGame)
-    CASE(UIMSG_StartNewGame)
-    CASE(UIMSG_Game_OpenLoadGameDialog)
-    CASE(UIMSG_Game_OpenSaveGameDialog)
-    CASE(UIMSG_Game_OpenOptionsDialog)
-    CASE(UIMSG_SetGraphicsMode)
-    CASE(UIMSG_Quit)
-    CASE(UIMSG_StartHireling1Dialogue)
-    CASE(UIMSG_StartHireling2Dialogue)
-    CASE(UIMSG_SelectNPCDialogueOption)
-    CASE(UIMSG_CastSpellFromBook)
-    CASE(UIMSG_PlayerCreation_VoicePrev)
-    CASE(UIMSG_PlayerCreation_VoiceNext)
-    CASE(UIMSG_StartNPCDialogue)
-    CASE(UIMSG_ArrowUp)
-    CASE(UIMSG_DownArrow)
-    CASE(UIMSG_SaveLoadBtn)
-    CASE(UIMSG_SelectLoadSlot)
-    CASE(UIMSG_Cancel)
-    CASE(UIMSG_ExitRest)
-    CASE(UIMSG_PlayerCreation_FacePrev)
-    CASE(UIMSG_PlayerCreation_FaceNext)
-    CASE(UIMSG_CycleCharacters)
-    CASE(UIMSG_SetTurnSpeed)
-    CASE(UIMSG_ToggleWalkSound)
-    CASE(UIMSG_ChangeVoiceVolume)
-    CASE(UIMSG_ToggleShowDamage)
-    CASE(UIMSG_ScrollNPCPanel)
-    CASE(UIMSG_ShowFinalWindow)
-    CASE(UIMSG_OpenQuestBook)
-    CASE(UIMSG_OpenAutonotes)
-    CASE(UIMSG_OpenMapBook)
-    CASE(UIMSG_OpenCalendar)
-    CASE(UIMSG_OpenHistoryBook)
-    CASE(UIMSG_ToggleAlwaysRun)
-    CASE(UIMSG_ToggleFlipOnExit)
-    CASE(UIMSG_Game_Action)
-    CASE(UIMSG_RentRoom)
-    CASE(UIMSG_TransitionUI_Confirm)
-    CASE(UIMSG_OpenKeyMappingOptions)
-    CASE(UIMSG_SelectKeyPage1)
-    CASE(UIMSG_SelectKeyPage2)
-    CASE(UIMSG_ResetKeyMapping)
-    CASE(UIMSG_ChangeKeyButton)
-    CASE(UIMSG_OpenVideoOptions)
-    CASE(UIMSG_ToggleBloodsplats)
-    CASE(UIMSG_ToggleColoredLights)
-    CASE(UIMSG_ToggleTint)
-    default:
-      swprintf(b, wcslen(L"UIMSG_%03X") , L"UIMSG_%03X", msg); return b;
-  };
-  #undef CASE
-}
\ No newline at end of file
--- a/CastSpellInfo.h	Sun Sep 08 17:07:47 2013 +0600
+++ b/CastSpellInfo.h	Sun Sep 08 17:07:58 2013 +0600
@@ -1,6 +1,14 @@
 #pragma once
+
+#include <cstdint>
+
 #include <array>
 
+namespace CastSpellInfoHelpers
+{
+  void _427D48();
+  void _427E01_cast_spell();
+};
 
 /*  271 */
 #pragma pack(push, 1)
@@ -9,30 +17,18 @@
   //----- (00426987) --------------------------------------------------------
   inline CastSpellInfo()
   {
-    field_8 = 0;
-    spellnum = 0;
-    field_6 = 0;
-    uPlayerID_2 = 0;
-    uPlayerID = 0;
-    sound_id = 0;
+    memset(this, 0, sizeof(this));
   }
 
-  void _427D48(unsigned int uPlayerID);
-  unsigned int PushCastSpellInfo(__int16 a2, __int16 uPlayerID, __int16 skill_level, __int16 a5, int sound_id);
   struct GUIWindow *GetCastSpellInInventoryWindow();
-  void _427E01_cast_spell();
 
-  __int16 spellnum;
-  unsigned __int16 uPlayerID;
-  __int16 uPlayerID_2;
+  uint16_t uSpellID;
+  uint16_t uPlayerID;
+  uint16_t uPlayerID_2;
   __int16 field_6;
-  __int16 field_8;
+  uint16_t uFlags;
   __int16 forced_spell_skill_level;
   int spell_target_pid;
   int sound_id;
 };
 #pragma pack(pop)
-
-
-extern std::array<CastSpellInfo, 10> pCastSpellInfo;
-extern CastSpellInfo stru_50CDB4; // idb
--- a/Chest.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/Chest.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -3,7 +3,6 @@
 #endif
 
 #include <stdio.h>
-#include <assert.h>
 
 #include "BSPModel.h"
 #include "Items.h"
@@ -617,7 +616,8 @@
   v2 = fopen("data\\dchest.bin", "wb");
   v3 = v2;
   if ( !v2 )
-    Abortf("Unable to save dchest.bin!");
+    Error("Unable to save dchest.bin!");
+
   fwrite(v1, 4u, 1u, v2);
   fwrite(v1->pChests, 0x24u, v1->uNumChests, v3);
   fclose(v3);
@@ -671,7 +671,8 @@
   v4 = fopen(Args, "r");
   File = v4;
   if ( !v4 )
-    Abortf("ChestDescriptionList::load - Unable to open file: %s.");
+    Error("ChestDescriptionList::load - Unable to open file: %s.");
+
   v5 = 0;
   Argsa = 0;
   if ( fgets(&Buf, 490, v4) )
@@ -692,7 +693,8 @@
   v7 = pAllocator->AllocNamedChunk(v6, 36 * v5, "Chest Descrip");
   v2->pChests = (ChestDesc *)v7;
   if ( v7 == (void *)v3 )
-    Abortf("ChestDescriptionList::load - Out of Memory!");
+    Error("ChestDescriptionList::load - Out of Memory!");
+
   memset(v7, v3, 36 * v2->uNumChests);
   v8 = File;
   v2->uNumChests = v3;
--- a/Conditions.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/Conditions.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -54,9 +54,19 @@
     }
     ITEM_TYPE itemId = thisProc->m_equipmentPairs[i * 2].m_ItemId;
     ITEM_EQUIP_TYPE slot = thisProc->m_equipmentPairs[i * 2 + 1].m_EquipSlot;
-    if (inPlayer->WearsItem(itemId, slot))
+    if (slot == EQIUP_ANY)
     {
-      return false;
+      if (inPlayer->WearsItemAnyWhere(itemId))
+      {
+        return false;
+      }
+    }
+    else
+    {
+      if (inPlayer->WearsItem(itemId, slot))
+      {
+        return false;
+      }
     }
   }
   return true;
--- a/DecalBuilder.h	Sun Sep 08 17:07:47 2013 +0600
+++ b/DecalBuilder.h	Sun Sep 08 17:07:58 2013 +0600
@@ -1,4 +1,7 @@
 #pragma once
+
+#include <cstdint>
+
 #include "Render.h"
 
 /*  158 */
@@ -120,7 +123,7 @@
   __int16 field_C0A;
   __int16 field_C0C;
   __int16 field_C0E;
-  uint uColorMultiplier;
+  uint32_t uColorMultiplier;
   int field_C14;
   DecalBuilder_stru0 *field_C18;
   int field_C1C;
--- a/DecorationList.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/DecorationList.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -5,6 +5,7 @@
 #include "FrameTableInc.h"
 #include "mm7_data.h"
 #include "Indoor.h"
+#include "ErrorHandling.h"
 
 //----- (0045864C) --------------------------------------------------------
 void DecorationList::FromFile(void *data_mm6, void *data_mm7, void *data_mm8)
@@ -14,8 +15,8 @@
        num_mm8_decs = data_mm8 ? *(int *)data_mm8 : 0;
 
   uNumDecorations = num_mm6_decs + num_mm7_decs + num_mm8_decs;
-  assert(uNumDecorations);
-  assert(!num_mm8_decs);
+  Assert(uNumDecorations);
+  Assert(!num_mm8_decs);
 
   pDecorations = (DecorationDesc *)pAllocator->AllocNamedChunk(pDecorations, uNumDecorations * sizeof(DecorationDesc), "Dec Descrip");
   memcpy(pDecorations, (char *)data_mm7 + 4, num_mm7_decs * sizeof(DecorationDesc));
@@ -86,7 +87,8 @@
   v3 = fopen(Args, "r");
   File = v3;
   if ( !v3 )
-    Abortf("DecorationDescriptionList::load - Unable to open file: %s.");
+    Error("DecorationDescriptionList::load - Unable to open file: %s.");
+
   v4 = 0;
   Argsa = 0;
   if ( fgets(&Buf, 490, v3) )
@@ -105,7 +107,8 @@
   v5 = pAllocator->AllocNamedChunk(v2->pDecorations, 84 * v4, "Dec Descrip");
   v2->pDecorations = (DecorationDesc *)v5;
   if ( !v5 )
-    Abortf("DecorationDescriptionList::load - Out of Memory!");
+    Error("DecorationDescriptionList::load - Out of Memory!");
+
   v6 = File;
   v2->uNumDecorations = 0;
   fseek(v6, 0, 0);
@@ -244,7 +247,8 @@
   v2 = fopen("data\\ddeclist.bin", "wb");
   v3 = v2;
   if ( !v2 )
-    Abortf("Unable to save ddeclist.bin!");
+    Error("Unable to save ddeclist.bin!");
+
   fwrite(v1, 4u, 1u, v2);
   fwrite(v1->pDecorations, 0x54u, v1->uNumDecorations, v3);
   fclose(v3);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ErrorHandling.h	Sun Sep 08 17:07:58 2013 +0600
@@ -0,0 +1,60 @@
+#pragma once
+
+#define Error(format, ...)             Error_impl_(__FILE__, __FUNCTION__, __LINE__, format, __VA_ARGS__)
+#define Assert(condition, ...) Assert_impl_(__FILE__, __FUNCTION__, __LINE__, condition, #condition,  __VA_ARGS__)
+
+
+
+#include <stdarg.h>
+inline __declspec(noreturn) void Error_impl_(const char *filename, const char *functionname, int line,
+                                             const char *format, ...)
+{
+  va_list va;
+  va_start(va, format);
+  {
+    char header[4096];
+    sprintf(header, "Error in %s: %u\n\t%s\n\n", filename, line, functionname);
+
+    char msg_body[8192];
+    vsprintf(msg_body, format, va);
+
+    wchar_t msg[sizeof(header) + sizeof(msg_body)];
+    swprintf(msg, L"%S %S", header, msg_body);
+
+    extern void MsgBox(const wchar_t *, const wchar_t *);
+    MsgBox(msg, L"Error");
+  }
+  va_end(va);
+
+  __debugbreak();
+}
+
+
+inline void Assert_impl_(const char *filename, const char *functionname, int line,
+                         bool condition, const char *condition_string, const char *format = nullptr, ...)
+{
+  if (condition)
+    return;
+
+  va_list va;
+  va_start(va, format);
+  {
+    char header[4096];
+    sprintf(header, "Assertion in %s: %u\n\t%s:\n%s\n\n", filename, line, functionname, condition_string);
+
+    char msg_body[8192];
+    vsprintf(msg_body, format, va);
+    
+    wchar_t msg[sizeof(header) + sizeof(msg_body)];
+    if (format)
+      swprintf(msg, L"%S %S", header, msg_body);
+    else
+      swprintf(msg, L"%S", header);
+
+    extern void MsgBox(const wchar_t *, const wchar_t *);
+    MsgBox(msg, L"Assertion");
+  }
+  va_end(va);
+
+  __debugbreak();
+}
\ No newline at end of file
--- a/Events.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/Events.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -2,7 +2,6 @@
 #define _CRT_SECURE_NO_WARNINGS
 #endif
 
-#include <assert.h>
 #include <stdlib.h>
 
 #include "Weather.h"
@@ -67,24 +66,23 @@
 {
   FILE *pLodFile; // eax@1
   unsigned int uTextureSize; // esi@3
-  char Args[60]; // [sp+8h] [bp-B4h]@6
+  //char Args[60]; // [sp+8h] [bp-B4h]@6
   void *ptr; // [sp+B8h] [bp-4h]@1
   Texture DstBuf; // [sp+6Ch] [bp-50h]@1
 
   ptr = pEvents_LOD->LoadRaw(pContainerName, 0);
   pLodFile = pEvents_LOD->FindContainer(pContainerName, 0);
   if ( !pLodFile )
-    Abortf("Unable to load %s", pContainerName);
+    Error("Unable to load %s", pContainerName);
+
   fread(&DstBuf, 1, 48, pLodFile);
   uTextureSize = DstBuf.uDecompressedSize;
   if ( !DstBuf.uDecompressedSize )
     uTextureSize = DstBuf.uTextureSize;
   memset(&DstBuf, 0, 72);
   if ( uTextureSize >= (signed int)uBufferSize )
-    {
-    sprintf(Args, "File %s Size %lu - Buffer size %lu", pContainerName, uTextureSize, uBufferSize);
-    Abortf(Args);
-    }
+    Error("File %s Size %lu - Buffer size %lu", pContainerName, uTextureSize, uBufferSize);
+
   memcpy(pBuffer, ptr, uTextureSize);
   pAllocator->FreeChunk(ptr);
   return uTextureSize;
--- a/GUIFont.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/GUIFont.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -3,7 +3,6 @@
 #endif
 
 #include <string>
-#include <assert.h>
 
 #include "LOD.h"
 #include "GUIFont.h"
@@ -49,10 +48,8 @@
         {
         pallete_index =pIcons_LOD->LoadTexture(pFontPalette, TEXTURE_16BIT_PALETTE);
         if (pallete_index == -1)
-            {
-            wsprintfA(pTmpBuf.data(), "Unable to open %s", pFontPalette);
-            Abortf(pTmpBuf.data());
-            }	
+            Error("Unable to open %s", pFontPalette);
+
         pFont->pFontPalettes[palletes_count] = pIcons_LOD->pTextures[pallete_index].pPalette16;
         ++palletes_count;
         }
@@ -285,7 +282,7 @@
       }
   currentFont=pFontMain; // esi@3
   uInStrLen = strlen(pString);
-  assert(uInStrLen < sizeof(pTmpBuf3));
+  Assert(uInStrLen < sizeof(pTmpBuf3));
   strcpy(pTmpBuf3.data(), pString);
   if (uInStrLen==0)
       return pTmpBuf3.data();
--- a/GUIProgressBar.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/GUIProgressBar.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -2,8 +2,6 @@
 #define _CRT_SECURE_NO_WARNINGS
 #endif
 
-#include <assert.h>
-
 #include "GUIProgressBar.h"
 #include "LOD.h"
 #include "Mouse.h"
@@ -43,7 +41,7 @@
       break;
 
     default:
-      assert(false && "Invalid GUIProgressBar type");
+      Error("Invalid GUIProgressBar type: %u", type);
   }
 
   //v2 = this;
@@ -110,7 +108,7 @@
     case PartyAlignment_Good:    pIcons_LOD->_410522(&pBardata, "bardata-b", 2); break;
     case PartyAlignment_Neutral: pIcons_LOD->_410522(&pBardata, "bardata", 2); break;
     case PartyAlignment_Evil:    pIcons_LOD->_410522(&pBardata, "bardata-c", 2); break;
-    default: assert(false);
+    default: Error("Invalid alignment type: %u", pParty->alignment);
   }
 
   uProgressCurrent = 0;
--- a/GUIWindow.h	Sun Sep 08 17:07:47 2013 +0600
+++ b/GUIWindow.h	Sun Sep 08 17:07:58 2013 +0600
@@ -1,10 +1,9 @@
 #pragma once
-#include "Player.h"
+
+#include <cstdint>
 #include <array>
 
-
-
-
+#include "Player.h"
 
 enum UIMessageType: unsigned __int32
 {
@@ -566,7 +565,7 @@
 
 
 // transition & travel ui
-void TransitionUI_Load(uint anim_id, uint exit_pic_id, int x, int y, int z, int directiony, int directionx, int a8, const char *pLocationName);
+void TransitionUI_Load(uint32_t anim_id, uint32_t exit_pic_id, int x, int y, int z, int directiony, int directionx, int a8, const char *pLocationName);
 void TransitionUI_Draw();
 
 void TravelUI_Load();
--- a/Game.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/Game.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -2,8 +2,6 @@
 #define _CRT_SECURE_NO_WARNINGS
 #endif
 
-#include <assert.h>
-
 #include "Vis.h"
 
 #include "LightmapBuilder.h"
@@ -73,7 +71,7 @@
   int v4; // edi@26
   //int v5; // eax@35
 
-  uFlags2 &= 0xFFFFFFFDu;
+  uFlags2 &= ~0x02;
   if ( pParty->_497FC5_check_party_perception_against_level() )
     uFlags2 |= 2u;
   pIndoorCamera->sRotationX = pParty->sRotationX;
@@ -127,7 +125,7 @@
         pIndoor->Draw();
       else if (uCurrentlyLoadedLevelType == LEVEL_Outdoor)
         pOutdoor->Draw();
-      else assert(false);
+      else Error("Invalid level type: %u", uCurrentlyLoadedLevelType);
 
       if (pRenderer->pRenderD3D)
       {
@@ -543,7 +541,7 @@
       if (num_conscious_players)
       {
         int idx = conscious_players_ids[rand() % num_conscious_players];
-        assert(idx >= 0);
+        Assert(idx >= 0);
         pPlayers[idx + 1]->PlaySound(SPEECH_99, 0);
       }
 
@@ -1178,7 +1176,7 @@
           else
             face->uAttributes |= FACE_OUTLINED;
         }
-        else assert(false);
+        else Error("Invalid level type", uCurrentlyLoadedLevelType);
       }
       break;
 
--- a/IconFrameTable.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/IconFrameTable.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -105,7 +105,7 @@
   v2 = fopen("data\\dift.bin", "wb");
   v3 = v2;
   if ( !v2 )
-    Abortf("Unable to save dift.bin!");
+    Error("Unable to save dift.bin!");
   fwrite(v1, 4u, 1u, v2);
   fwrite(v1->pIcons, 0x20u, v1->uNumIcons, v3);
   fclose(v3);
@@ -119,8 +119,8 @@
        num_mm8_frames = data_mm8 ? *(int *)data_mm8 : 0;
 
   uNumIcons = num_mm6_frames + num_mm7_frames + num_mm8_frames;
-  assert(uNumIcons);
-  assert(!num_mm8_frames);
+  Assert(uNumIcons);
+  Assert(!num_mm8_frames);
 
   pIcons = (IconFrame *)pAllocator->AllocNamedChunk(pIcons, uNumIcons * sizeof(IconFrame), "I Frames");
   memcpy(pIcons,                                   (char *)data_mm7 + 4, num_mm7_frames * sizeof(IconFrame));
@@ -160,7 +160,7 @@
   v3 = fopen(Args, "r");
   File = v3;
   if ( !v3 )
-    Abortf("IconFrameTable::load - Unable to open file: %s.", Args);
+    Error("IconFrameTable::load - Unable to open file: %s.", Args);
   v4 = 0;
   v21 = 0;
   v22 = 1;
@@ -173,7 +173,7 @@
       if ( v20.uPropCount && *v20.pProperties[0] != 47 )
       {
         if ( v20.uPropCount < 3 )
-          Abortf("IconFrameTable::loadText, too few arguments, %s line %i.", Args, v22);
+          Error("IconFrameTable::loadText, too few arguments, %s line %i.", Args, v22);
         ++v21;
       }
       ++v22;
--- a/Indoor.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/Indoor.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -2,8 +2,6 @@
 #define _CRT_SECURE_NO_WARNINGS
 #endif
 
-#include <assert.h>
-
 #include "LightmapBuilder.h"
 #include "DecalBuilder.h"
 #include "stru9.h"
@@ -64,7 +62,7 @@
 stru337 stru_F81018;
 BspRenderer_PortalViewportData stru_F8A590;
 BspRenderer *pBspRenderer = new BspRenderer; // idb
-stru141 stru_721530;
+stru141_actor_collision_object stru_721530;
 std::array<stru352, 480> stru_F83B80;
 
 
@@ -1749,7 +1747,7 @@
   }
 
   if ( !pGames_LOD->DoesContainerExist(pFilename) )
-    Abortf("Unable to find %s in Games.LOD", pFilename);
+    Error("Unable to find %s in Games.LOD", pFilename);
 
   //v238 = pFilename - 4;
   //v81 = strlen(pFilename);
@@ -2971,7 +2969,7 @@
             v25 = abs(v15->pFacePlane_old.vNormal.z);
             //v26 = v87;
             if ( v24 > v25 )
-              Abortf("Door Error\ndoor id: %i\nfacet no: %i\n\nOverflow dividing facet->d [%i] by facet->nz [%i]",
+              Error("Door Error\ndoor id: %i\nfacet no: %i\n\nOverflow dividing facet->d [%i] by facet->nz [%i]",
                 door->uDoorID,
                 door->pFaceIDs[v88],
                 v15->pFacePlane_old.dist,
@@ -3185,7 +3183,7 @@
   int v18; // ecx@33
   BLVFace *v19; // eax@34
   int v20; // ecx@46
-  int v21; // eax@46
+  //int v21; // eax@46
   int v22; // edi@46
   int v23; // eax@48
   unsigned int v24; // eax@51
@@ -3210,9 +3208,9 @@
   __int16 v43; // dx@96
   int v44; // ecx@96
   int v45; // edi@101
-  int v46; // edi@101
-  int v47; // eax@101
-  unsigned __int64 v48; // qax@101
+  //int v46; // edi@101
+  //int v47; // eax@101
+  //unsigned __int64 v48; // qax@101
   unsigned __int8 v49; // zf@103
   unsigned __int8 v50; // sf@103
   unsigned __int8 v51; // of@103
@@ -3361,29 +3359,28 @@
         return;
     }
     v20 = v0->uActorRadius;
-    v21 = v0->uActorHeight;
     stru_721530.field_84 = -1;
     stru_721530.field_70 = 0;
     uSectorID = 0;
     stru_721530.field_0 = 1;
-    stru_721530.field_8 = v20;
+    stru_721530.field_8_radius = v20;
     stru_721530.prolly_normal_d = v20;
-    stru_721530.field_C = v21;
+    stru_721530.height = v0->uActorHeight;
     v22 = 0;
     while ( 1 )
     {
-      stru_721530.field_34.x = v0->vPosition.x;
-      stru_721530.normal.x = stru_721530.field_34.x;
-      stru_721530.field_34.y = v0->vPosition.y;
-      stru_721530.normal.y = stru_721530.field_34.y;
+      stru_721530.position.x = v0->vPosition.x;
+      stru_721530.normal.x = stru_721530.position.x;
+      stru_721530.position.y = v0->vPosition.y;
+      stru_721530.normal.y = stru_721530.position.y;
       v23 = v0->vPosition.z;
       stru_721530.normal.z = v23 + v20 + 1;
-      stru_721530.field_34.z = v23 - v20 + stru_721530.field_C - 1;
-      if ( stru_721530.field_34.z < stru_721530.normal.z )
-        stru_721530.field_34.z = v23 + v20 + 1;
-      stru_721530.field_1C = v0->vVelocity.x;
-      stru_721530.field_20 = v0->vVelocity.y;
-      stru_721530.field_24 = v0->vVelocity.z;
+      stru_721530.position.z = v23 - v20 + stru_721530.height - 1;
+      if ( stru_721530.position.z < stru_721530.normal.z )
+        stru_721530.position.z = v23 + v20 + 1;
+      stru_721530.velocity.x = v0->vVelocity.x;
+      stru_721530.velocity.y = v0->vVelocity.y;
+      stru_721530.velocity.z = v0->vVelocity.z;
       stru_721530.uSectorID = v0->uSectorID;
       if ( !stru_721530._47050A(v22) )
       {
@@ -3434,12 +3431,9 @@
         }
         else
         {
-          v58 = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.x) >> 16;
-          v30 = v58 + v0->vPosition.x;
-          v58 = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.y) >> 16;
-          v31 = v58 + v0->vPosition.y;
-          v58 = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.z) >> 16;
-          v32 = v58 + v0->vPosition.z;
+          v30 = v0->vPosition.x + fixpoint_sub0(stru_721530.field_7C, stru_721530.direction.x);
+          v31 = v0->vPosition.y + fixpoint_sub0(stru_721530.field_7C, stru_721530.direction.y);
+          v32 = v0->vPosition.z + fixpoint_sub0(stru_721530.field_7C, stru_721530.direction.z);
         }
         v33 = collide_against_floor(v30, v31, v32, &stru_721530.uSectorID, &uFaceID);
         v34 = pIndoor->pFaces[uFaceID].uAttributes;
@@ -3463,13 +3457,13 @@
               v0->uSectorID = LOWORD(stru_721530.uSectorID);
               goto LABEL_123;
             }
-            v58 = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.x) >> 16;
-            v0->vPosition.x += (unsigned int)(stru_721530.field_7C * stru_721530.field_58.x) >> 16;
-            v58 = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.y) >> 16;
-            v0->vPosition.y += (unsigned int)(stru_721530.field_7C * stru_721530.field_58.y) >> 16;
-            v58 = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.z) >> 16;
+            //v58 = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.direction.x) >> 16;
+            v0->vPosition.x += fixpoint_sub0(stru_721530.field_7C, stru_721530.direction.x);
+            //v58 = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.direction.y) >> 16;
+            v0->vPosition.y += fixpoint_sub0(stru_721530.field_7C, stru_721530.direction.y);
+            //v58 = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.direction.z) >> 16;
             v36 = stru_721530.uFaceID;
-            v0->vPosition.z += (unsigned int)(stru_721530.field_7C * stru_721530.field_58.z) >> 16;
+            v0->vPosition.z += fixpoint_sub0(stru_721530.field_7C, stru_721530.direction.z);
             v0->uSectorID = LOWORD(stru_721530.uSectorID);
             stru_721530.field_70 += stru_721530.field_7C;
             v37 = PID_ID(v36);
@@ -3483,15 +3477,8 @@
                   v45 = stru_5C6E00->Atan2(
                           v0->vPosition.x - pLevelDecorations[v37].vPosition.x,
                           v0->vPosition.y - pLevelDecorations[v37].vPosition.y);
-                  v54 = stru_5C6E00->Cos(v45);
-                  v56 = (unsigned __int64)(v54 * (signed __int64)(signed int)_this) >> 16;
-                  v46 = v45 - stru_5C6E00->uIntegerHalfPi;
-                  v0->vVelocity.x = v54 * _this >> 16;
-                  v47 = stru_5C6E00->Sin(v45);
-                  v54 = v47;
-                  v48 = v47 * (signed __int64)(signed int)_this;
-                  v56 = v48 >> 16;
-                  v0->vVelocity.y = WORD1(v48);
+                  v0->vVelocity.x = fixpoint_sub0(stru_5C6E00->Cos(v45), _this);
+                  v0->vVelocity.y = fixpoint_sub0(stru_5C6E00->Sin(v45), _this);
                   goto LABEL_119;
                 }
                 if ( PID_TYPE(v36) == OBJECT_BModel)
@@ -3517,17 +3504,12 @@
                                                                               * v0->vVelocity.y
                                                                               + v38->pFacePlane_old.vNormal.z
                                                                               * v0->vVelocity.z) >> 16;
-                    if ( stru_721530.field_64 >> 3 > v61 )
-                      v61 = stru_721530.field_64 >> 3;
-                    v58 = v38->pFacePlane_old.vNormal.x;
-                    v58 = (unsigned __int64)(v61 * (signed __int64)v58) >> 16;
-                    _this = v38->pFacePlane_old.vNormal.y;
-                    _this = (unsigned __int64)(v61 * (signed __int64)(signed int)_this) >> 16;
-                    v56 = v38->pFacePlane_old.vNormal.z;
-                    v56 = (unsigned __int64)(v61 * (signed __int64)v56) >> 16;
-                    v0->vVelocity.x += v58;
-                    v0->vVelocity.y += _this;
-                    v0->vVelocity.z += v56;
+                    if ( (stru_721530.speed >> 3) > v61 )
+                      v61 = stru_721530.speed >> 3;
+
+                    v0->vVelocity.x += fixpoint_sub0(v61, v38->pFacePlane_old.vNormal.x);
+                    v0->vVelocity.y += fixpoint_sub0(v61, v38->pFacePlane_old.vNormal.y);
+                    v0->vVelocity.z += fixpoint_sub0(v61, v38->pFacePlane_old.vNormal.z);
                     v41 = v38->uPolygonType;
                     if ( v41 != 4 && v41 != 3 )
                     {
@@ -3551,18 +3533,10 @@
                     EventProcessor(pIndoor->pFaceExtras[v38->uFaceExtraID].uEventID, 0, 1);
                 }
 LABEL_119:
-                v56 = v0->vVelocity.x;
-                v54 = 58500;
-                v56 = (unsigned __int64)(58500i64 * v56) >> 16;
-                v0->vVelocity.x = v56;
-                v56 = v0->vVelocity.y;
-                v56 = (unsigned __int64)(v54 * (signed __int64)v56) >> 16;
-                v54 = 58500;
-                v0->vVelocity.y = v56;
-                v56 = v0->vVelocity.z;
-                v56 = (unsigned __int64)(v54 * (signed __int64)v56) >> 16;
+                v0->vVelocity.x = fixpoint_sub0(58500, v0->vVelocity.x);
+                v0->vVelocity.y = fixpoint_sub0(58500, v0->vVelocity.y);
+                v0->vVelocity.z = fixpoint_sub0(58500, v0->vVelocity.z);
                 v22 = 0;
-                v0->vVelocity.z = v56;
                 goto LABEL_120;
               }
               if ( v0->GetActorsRelation(0) )
@@ -3670,7 +3644,7 @@
   __int16 v29; // ax@85
   signed int v30; // edi@94
   int v31; // esi@94
-  char Args; // [sp+350h] [bp-C4h]@16
+  //char Args; // [sp+350h] [bp-C4h]@16
   int v34[4]; // [sp+3E8h] [bp-2Ch]@96
   int v35; // [sp+3F8h] [bp-1Ch]@1
   //char b[4]; // [sp+3FCh] [bp-18h]@58
@@ -3727,21 +3701,17 @@
          (char *)&pDest)
      - 1;
   if ( !v4 )
-  {
-    sprintf(&Args, "Unable to open %s", pCurrentMapName);
-    Abortf(&Args);
-  }
+    Error("Unable to open %s", pCurrentMapName);
+
   v5 = v4 - 1;
   if ( !v5 )
-  {
-    sprintf(&Args, "File %s is not a BLV File", pCurrentMapName);
-    Abortf(&Args);
-  }
+    Error("File %s is not a BLV File", pCurrentMapName);
+
   v6 = v5 - 1;
   if ( !v6 )
-    Abortf("Attempt to open new level before clearing old");
+    Error("Attempt to open new level before clearing old");
   if ( v6 == 1 )
-    Abortf("Out of memory loading indoor level");
+    Error("Out of memory loading indoor level");
   if ( !(dword_6BE364_game_settings_1 & 0x2000) )
   {
     InitializeActors();
@@ -3836,21 +3806,6 @@
     if (!pFace->uBitmapID != -1)
       pBitmaps_LOD->pTextures[pFace->uBitmapID].palette_id2 = pPaletteManager->LoadPalette(pBitmaps_LOD->pTextures[pFace->uBitmapID].palette_id1);
  }
-
-  /*i = 0;
-  if ( (signed int)pIndoor->uNumFaces > 0 )
-  {
-    v12 = 0;
-    do
-    {
-      if ( pIndoor->pFaces[v12].uBitmapID != -1 )
-        pBitmaps_LOD->pTextures[pIndoor->pFaces[v12].uBitmapID].palette_id2 = pPaletteManager->LoadPalette(pBitmaps_LOD->pTextures[pIndoor->pFaces[v12].uBitmapID].palette_id1);
-      ++i;
-      ++v12;
-    }
-    while ( i < (signed int)pIndoor->uNumFaces );
-  }*/
-
   
   pGameLoadingUI_ProgressBar->Progress();
   
@@ -3897,7 +3852,7 @@
         }
       }
 
-      if (!pDecortaion->field_16_event_id)
+      if (!pDecortaion->uEventID)
       {
         if (pDecortaion->IsInteractive())
         {
@@ -4828,11 +4783,12 @@
               }
               else
               {
-                LODWORD(v19) = pBLVRenderParams->field_40 << 16;
+                __debugbreak(); // sw rendering
+                /*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;
+                v31 = (unsigned __int64)(v24->scale * (signed __int64)v20) >> 16;*/
               }
               //HIWORD(v21) = HIWORD(x);
               //LOWORD(v21) = 0;
@@ -4942,7 +4898,7 @@
   }
 }
 //----- (0043FA33) --------------------------------------------------------
-void __fastcall PrepareDecorationsRenderList_BLV(unsigned int uDecorationID, unsigned int uSectorID)
+void PrepareDecorationsRenderList_BLV(unsigned int uDecorationID, unsigned int uSectorID)
 {
   LevelDecoration *v2; // esi@1
   DecorationDesc *v3; // ebx@2
@@ -5152,113 +5108,97 @@
   }
 }
 //----- (0048653D) --------------------------------------------------------
-int stru149::_48653D(int a2, int a3, int a4, int a5, int a6, int a7)//portal frustum culling
+void stru149::_48653D_frustum_blv(int a2, int a3, int a4, int a5, int a6, int a7)//portal frustum culling
 {
-  stru149 *v7; // esi@1
+  //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 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 v18; // eax@5
   int v19; // ST10_4@6
-  int v20; // eax@8
+  //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 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 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;
+  //int v30; // [sp+30h] [bp+8h]@10
+  //int v31; // [sp+3Ch] [bp+14h]@10
+
   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;
+  //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);
+    this->field_0_party_dir_x = fixpoint_sub0(v16, v28) + fixpoint_sub0((-pBLVRenderParams->vPartyPos.z) << 16, v9);
+    this->field_4_party_dir_y = v8 * -pBLVRenderParams->vPartyPos.y - v29 * -pBLVRenderParams->vPartyPos.x;
+    this->field_8_party_dir_z = fixpoint_sub0(v17, v28) - fixpoint_sub0(v16, v9);
   }
   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;
+    this->field_0_party_dir_x = v8 * -pBLVRenderParams->vPartyPos.x + v29 * -pBLVRenderParams->vPartyPos.y;
+    this->field_4_party_dir_y = v8 * -pBLVRenderParams->vPartyPos.y - v29 * -pBLVRenderParams->vPartyPos.x;
+    this->field_8_party_dir_z = (-pBLVRenderParams->vPartyPos.z) << 16;
   }
-  v7->field_8 = v15;
-  if ( pBLVRenderParams->sPartyRotX )
+
+  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);
+    v19 = fixpoint_sub0(a2, v8) + fixpoint_sub0(a3, v29);
+
+    this->field_C = fixpoint_sub0(v19, v28) + fixpoint_sub0(a4, v9);
+    this->field_10 = fixpoint_sub0(a3, v8) - fixpoint_sub0(a2, v29);
+    this->field_14 = fixpoint_sub0(a4, v28) - fixpoint_sub0(v19, v9);
   }
   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;
+    this->field_C = fixpoint_sub0(a2, v8) + fixpoint_sub0(a3, v29);
+    this->field_10 = fixpoint_sub0(a3, v8) - fixpoint_sub0(a2, v29);
+    this->field_14 = a4;
   }
-  v7->field_14 = v18;
-  if ( pBLVRenderParams->sPartyRotX )
+
+  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);
+    v21 = fixpoint_sub0(a5, v8) + fixpoint_sub0(a6, v29);
+
+    this->field_18 = fixpoint_sub0(v21, v28) + fixpoint_sub0(a7, v9);
+    this->field_1C = fixpoint_sub0(a6, v8) - fixpoint_sub0(a5, v29);
+    this->field_20 = fixpoint_sub0(a7, v28) - fixpoint_sub0(v21, v9);
   }
   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;
+    this->field_18 = fixpoint_sub0(a5, v8) + fixpoint_sub0(a6, v29);
+    this->field_1C = fixpoint_sub0(a6, v8) - fixpoint_sub0(a5, v29);
+    this->field_20 = 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;
+
+  this->field_18 = -this->field_18;
+  this->field_1C = -this->field_1C;
+  this->field_20 = -this->field_20;
+
+  this->field_24 = fixpoint_dot(this->field_C,  this->field_0_party_dir_x,
+                                this->field_10, this->field_4_party_dir_y,
+                                this->field_14, this->field_8_party_dir_z);
+  this->field_28 = fixpoint_dot(this->field_18, this->field_0_party_dir_x,
+                                this->field_1C, this->field_4_party_dir_y,
+                                this->field_20, this->field_8_party_dir_z);
 }
 //----- (00407A1C) --------------------------------------------------------
 bool __fastcall sub_407A1C(int x, int z, int y, Vec3_int_ v)
@@ -5284,8 +5224,8 @@
   int v22; // eax@26
   signed int v23; // edi@26
   int v24; // ST34_4@30
-  signed __int64 v25; // qtt@31
-  int v26; // eax@31
+  //signed __int64 v25; // qtt@31
+  //int v26; // eax@31
   Vec3_int_ v27; // ST08_12@37
   Vec3_int_ v28; // ST08_12@37
   int v29; // edi@37
@@ -5302,8 +5242,8 @@
   int v40; // ebx@60
   int v41; // eax@61
   signed int v42; // edi@61
-  signed __int64 v43; // qtt@66
-  int v44; // eax@66
+  //signed __int64 v43; // qtt@66
+  //int v44; // eax@66
   Vec3_int_ v45; // ST08_12@73
   int v46; // edi@73
   int v47; // ebx@73
@@ -5329,8 +5269,8 @@
   int v67; // eax@99
   signed int v68; // edi@99
   int v69; // ST2C_4@103
-  signed __int64 v70; // qtt@104
-  int v71; // eax@104
+  //signed __int64 v70; // qtt@104
+  //int v71; // eax@104
   Vec3_int_ v72; // ST08_12@111
   Vec3_int_ v73; // ST08_12@111
   int v74; // edi@111
@@ -5353,8 +5293,8 @@
   int v91; // ebx@136
   int v92; // eax@137
   signed int v93; // edi@137
-  signed __int64 v94; // qtt@142
-  int v95; // eax@142
+  //signed __int64 v94; // qtt@142
+  //int v95; // eax@142
   Vec3_int_ v97; // [sp-18h] [bp-94h]@1
   int v98; // [sp-Ch] [bp-88h]@88
   int v99; // [sp-Ch] [bp-88h]@126
@@ -5373,7 +5313,7 @@
   int v112; // [sp+18h] [bp-64h]@128
   signed int v113; // [sp+20h] [bp-5Ch]@1
   signed int v114; // [sp+24h] [bp-58h]@1
-  unsigned __int64 a4; // [sp+28h] [bp-54h]@1
+  //unsigned __int64 a4; // [sp+28h] [bp-54h]@1
   unsigned int a4_8; // [sp+30h] [bp-4Ch]@1
   int v117; // [sp+34h] [bp-48h]@4
   int v118; // [sp+34h] [bp-48h]@39
@@ -5442,18 +5382,19 @@
 
   __debugbreak();
 
-  a4 = __PAIR__(z, x);
   v4 = stru_5C6E00->Atan2(v.x - x, v.y - z);
   v114 = 0;
   v97.z = y;
+  v97.x = x;
+  v97.y = z;
   v113 = 0;
   a4_8 = v4;
-  *(_QWORD *)&v97.x = a4;
   if ( uCurrentlyLoadedLevelType != LEVEL_Outdoor)
   {
     Vec3_int_::Rotate(32, stru_5C6E00->uIntegerHalfPi + v4, 0, v97, &pOut.x, &pOut.y, &outz);
     v45.z = v.z;
-    *(_QWORD *)&v45.x = *(_QWORD *)&v;
+    v45.x = v.x;
+    v45.y = v.y;
     Vec3_int_::Rotate(32, stru_5C6E00->uIntegerHalfPi + v4, 0, v45, &outx, &outy, &v163);
     v46 = outy - pOut.y;
     v47 = v163 - outz;
@@ -5570,16 +5511,17 @@
                   + pOut.x * v62->pFacePlane_old.vNormal.x)) >> 14;
         if ( v69 <= abs(v66) )
         {
-          LODWORD(v70) = v68 << 16;
-          HIDWORD(v70) = v68 >> 16;
-          v71 = v70 / v107;
-          v108 = v70 / v107;
-          if ( v71 >= 0 )
+          //LODWORD(v70) = v68 << 16;
+          //HIDWORD(v70) = v68 >> 16;
+          //v71 = v70 / v107;
+          //v108 = v70 / v107;
+          v108 = fixpoint_div(v68, v107);
+          if ( v108 >= 0 )
           {
             if ( sub_4075DB(
-                   pOut.x + ((signed int)(((unsigned __int64)(v108 * (signed __int64)v143) >> 16) + 32768) >> 16),
-                   pOut.y + ((signed int)(((unsigned __int64)(v108 * (signed __int64)v147) >> 16) + 32768) >> 16),
-                   outz + ((signed int)(((unsigned __int64)(v108 * (signed __int64)v151) >> 16) + 32768) >> 16),
+                   pOut.x + ((signed int)(fixpoint_sub0(v108, v143) + 32768) >> 16),
+                   pOut.y + ((signed int)(fixpoint_sub0(v108, v147) + 32768) >> 16),
+                   outz + ((signed int)(fixpoint_sub0(v108, v151) + 32768) >> 16),
                    v62) )
             {
               v114 = 1;
@@ -5602,10 +5544,12 @@
       v54 = pOut.x;
     }
     v72.z = y;
-    *(_QWORD *)&v72.x = a4;
+    v72.x = x;
+    v72.y = z;
     Vec3_int_::Rotate(32, a4_8 - stru_5C6E00->uIntegerHalfPi, 0, v72, &pOut.x, &pOut.y, &outz);
     v73.z = v.z;
-    *(_QWORD *)&v73.x = *(_QWORD *)&v;
+    v73.x = v.x;
+    v73.y = v.y;
     Vec3_int_::Rotate(32, a4_8 - stru_5C6E00->uIntegerHalfPi, 0, v73, &outx, &outy, &v163);
     v74 = outy - pOut.y;
     v75 = v163 - outz;
@@ -5701,9 +5645,9 @@
         || v132 < v90->pBounding.y1
         || v136 > v90->pBounding.z2
         || v140 < v90->pBounding.z1
-        || (yb = (unsigned __int64)(v144 * (signed __int64)v90->pFacePlane_old.vNormal.x) >> 16,
-            v_4b = (unsigned __int64)(v148 * (signed __int64)v90->pFacePlane_old.vNormal.y) >> 16,
-            vf = (unsigned __int64)(v152 * (signed __int64)v90->pFacePlane_old.vNormal.z) >> 16,
+        || (yb = fixpoint_sub0(v144, v90->pFacePlane_old.vNormal.x),
+            v_4b = fixpoint_sub0(v148, v90->pFacePlane_old.vNormal.y),
+            vf = fixpoint_sub0(v152, v90->pFacePlane_old.vNormal.z),
             v20 = yb + vf + v_4b == 0,
             v91 = yb + vf + v_4b,
             vc = yb + vf + v_4b,
@@ -5736,16 +5680,17 @@
                  + pOut.x * v90->pFacePlane_old.vNormal.x)) >> 14;
       if ( v_4c <= abs(v91) )
       {
-        LODWORD(v94) = v93 << 16;
-        HIDWORD(v94) = v93 >> 16;
-        v95 = v94 / vc;
-        vd = v94 / vc;
-        if ( v95 >= 0 )
+        //LODWORD(v94) = v93 << 16;
+        //HIDWORD(v94) = v93 >> 16;
+        //v95 = v94 / vc;
+        //vd = v94 / vc;
+        vd = fixpoint_div(v93, vc);
+        if ( vd >= 0 )
         {
           if ( sub_4075DB(
-                 pOut.x + ((signed int)(((unsigned __int64)(vd * (signed __int64)v144) >> 16) + 32768) >> 16),
-                 pOut.y + ((signed int)(((unsigned __int64)(vd * (signed __int64)v148) >> 16) + 32768) >> 16),
-                 outz + ((signed int)(((unsigned __int64)(vd * (signed __int64)v152) >> 16) + 32768) >> 16),
+                 pOut.x + ((signed int)(fixpoint_sub0(vd, v144) + 32768) >> 16),
+                 pOut.y + ((signed int)(fixpoint_sub0(vd, v148) + 32768) >> 16),
+                 outz + ((signed int)(fixpoint_sub0(vd, v152) + 32768) >> 16),
                  v90) )
           {
             v113 = 1;
@@ -5764,7 +5709,8 @@
   }
   Vec3_int_::Rotate(32, stru_5C6E00->uIntegerHalfPi + v4, 0, v97, &pOut.x, &pOut.y, &outz);
   v5.z = v.z;
-  *(_QWORD *)&v5.x = *(_QWORD *)&v;
+  v5.x = v.x;
+  v5.y = v.y;
   Vec3_int_::Rotate(32, stru_5C6E00->uIntegerHalfPi + v4, 0, v5, &outx, &outy, &v163);
   v6 = outy - pOut.y;
   v7 = v163 - outz;
@@ -5842,9 +5788,9 @@
         || v137 < v16->pBoundingBox.y1
         || v133 > v16->pBoundingBox.z2
         || v129 < v16->pBoundingBox.z1
-        || (v17 = (unsigned __int64)(v125 * (signed __int64)v16->pFacePlane.vNormal.x) >> 16,
-            v18 = (unsigned __int64)(v121 * (signed __int64)v16->pFacePlane.vNormal.y) >> 16,
-            v19 = (unsigned __int64)(v117 * (signed __int64)v16->pFacePlane.vNormal.z) >> 16,
+        || (v17 = fixpoint_sub0(v125, v16->pFacePlane.vNormal.x),
+            v18 = fixpoint_sub0(v121, v16->pFacePlane.vNormal.y),
+            v19 = fixpoint_sub0(v117, v16->pFacePlane.vNormal.z),
             v20 = v17 + v18 + v19 == 0,
             v21 = v17 + v18 + v19,
             v109 = v17 + v18 + v19,
@@ -5865,16 +5811,17 @@
       v24 = abs(-(v16->pFacePlane.dist + v22 + outz * v16->pFacePlane.vNormal.z + pOut.x * v16->pFacePlane.vNormal.x)) >> 14;
       if ( v24 <= abs(v21) )
       {
-        LODWORD(v25) = v23 << 16;
-        HIDWORD(v25) = v23 >> 16;
-        v26 = v25 / v109;
-        v110 = v25 / v109;
-        if ( v26 >= 0 )
+        //LODWORD(v25) = v23 << 16;
+        //HIDWORD(v25) = v23 >> 16;
+        //v26 = v25 / v109;
+        //v110 = v25 / v109;
+        v110 = fixpoint_div(v23, v109);
+        if ( v110 >= 0 )
         {
           if ( sub_4077F1(
-                 pOut.x + ((signed int)(((unsigned __int64)(v110 * (signed __int64)v125) >> 16) + 32768) >> 16),
-                 pOut.y + ((signed int)(((unsigned __int64)(v110 * (signed __int64)v121) >> 16) + 32768) >> 16),
-                 outz + ((signed int)(((unsigned __int64)(v110 * (signed __int64)v117) >> 16) + 32768) >> 16),
+                 pOut.x + ((signed int)(fixpoint_sub0(v110, v125) + 32768) >> 16),
+                 pOut.y + ((signed int)(fixpoint_sub0(v110, v121) + 32768) >> 16),
+                 outz + ((signed int)(fixpoint_sub0(v110, v117) + 32768) >> 16),
                  v16,
                  (BSPVertexBuffer *)a5) )
           {
@@ -5892,10 +5839,12 @@
   }
 LABEL_37:
   v27.z = y;
-  *(_QWORD *)&v27.x = a4;
+  v27.x = x;
+  v27.y = z;
   Vec3_int_::Rotate(32, a4_8 - stru_5C6E00->uIntegerHalfPi, 0, v27, &pOut.x, &pOut.y, &outz);
   v28.z = v.z;
-  *(_QWORD *)&v28.x = *(_QWORD *)&v;
+  v28.x = v.x;
+  v28.y = v.y;
   Vec3_int_::Rotate(32, a4_8 - stru_5C6E00->uIntegerHalfPi, 0, v28, &outx, &outy, &v163);
   v29 = outy - pOut.y;
   v30 = v163 - outz;
@@ -5973,9 +5922,9 @@
         || v138 < v39->pBoundingBox.y1
         || v134 > v39->pBoundingBox.z2
         || v130 < v39->pBoundingBox.z1
-        || (ya = (unsigned __int64)(v126 * (signed __int64)v39->pFacePlane.vNormal.x) >> 16,
-            ve = (unsigned __int64)(v122 * (signed __int64)v39->pFacePlane.vNormal.y) >> 16,
-            v_4 = (unsigned __int64)(v118 * (signed __int64)v39->pFacePlane.vNormal.z) >> 16,
+        || (ya = fixpoint_sub0(v126, v39->pFacePlane.vNormal.x),
+            ve = fixpoint_sub0(v122, v39->pFacePlane.vNormal.y),
+            v_4 = fixpoint_sub0(v118, v39->pFacePlane.vNormal.z),
             v20 = ya + ve + v_4 == 0,
             v40 = ya + ve + v_4,
             va = ya + ve + v_4,
@@ -5996,16 +5945,16 @@
       v_4a = abs(-(v39->pFacePlane.dist + v41 + outz * v39->pFacePlane.vNormal.z + pOut.x * v39->pFacePlane.vNormal.x)) >> 14;
       if ( v_4a <= abs(v40) )
       {
-        LODWORD(v43) = v42 << 16;
-        HIDWORD(v43) = v42 >> 16;
-        v44 = v43 / va;
-        vb = v43 / va;
-        if ( v44 >= 0 )
+        //LODWORD(v43) = v42 << 16;
+        //HIDWORD(v43) = v42 >> 16;
+        //vb = v43 / va;
+        vb = fixpoint_div(v42, va);
+        if ( vb >= 0 )
         {
           if ( sub_4077F1(
-                 pOut.x + ((signed int)(((unsigned __int64)(vb * (signed __int64)v126) >> 16) + 32768) >> 16),
-                 pOut.y + ((signed int)(((unsigned __int64)(vb * (signed __int64)v122) >> 16) + 32768) >> 16),
-                 outz + ((signed int)(((unsigned __int64)(vb * (signed __int64)v118) >> 16) + 32768) >> 16),
+                 pOut.x + ((signed int)(fixpoint_sub0(vb, v126) + 32768) >> 16),
+                 pOut.y + ((signed int)(fixpoint_sub0(vb, v122) + 32768) >> 16),
+                 outz + ((signed int)(fixpoint_sub0(vb, v118) + 32768) >> 16),
                  v39,
                  (BSPVertexBuffer *)a5a) )
           {
@@ -6109,7 +6058,7 @@
           _449B7E_toggle_bit(pParty->_quest_bits, 184, 1u);
         if ( v19->uItemID == 455 )
           _449B7E_toggle_bit(pParty->_quest_bits, 185, 1u);
-        if ( !pParty->AddItem(v19) )
+        if ( !pParty->AddItemToParty(v19) )
           pParty->SetHoldingItem(v19);
         v21 = v26;
       }
@@ -6155,7 +6104,7 @@
 
     case OBJECT_Decoration:
       v8 = &pLevelDecorations[PID_ID(a1)];
-      v9 = v8->field_16_event_id;
+      v9 = v8->uEventID;
       if ( v9 )
       {
         EventProcessor(v9, a1, 1);
--- a/Indoor.h	Sun Sep 08 17:07:47 2013 +0600
+++ b/Indoor.h	Sun Sep 08 17:07:58 2013 +0600
@@ -1,4 +1,5 @@
 #pragma once
+
 #include "Level/Decoration.h"
 #include "Indoor_stuff.h"
 
--- a/IndoorCameraD3D.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/IndoorCameraD3D.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -710,7 +710,7 @@
 
 void IndoorCameraD3D::DebugDrawPortal(BLVFace *pFace)
 {
-  assert(pFace->uNumVertices <= 32);
+  Assert(pFace->uNumVertices <= 32);
 
   RenderVertexSoft sw[32];
   for (uint i = 0; i < pFace->uNumVertices; ++i)
--- a/Indoor_stuff.h	Sun Sep 08 17:07:47 2013 +0600
+++ b/Indoor_stuff.h	Sun Sep 08 17:07:58 2013 +0600
@@ -1,4 +1,7 @@
 #pragma once
+
+#include <array>
+
 #include "Render.h"
 #include "IndoorCameraD3D.h"
 
@@ -244,29 +247,27 @@
 
 /*  134 */
 #pragma pack(push, 1)
-struct stru141
+struct stru141_actor_collision_object
 {
   int _47050A(int a2);
 
   int field_0;
   int prolly_normal_d;
-  int field_8;
-  int field_C;
+  int field_8_radius;
+  int height;
   int field_10;
   int field_14;
   int field_18;
-  int field_1C;
-  int field_20;
-  int field_24;
+  Vec3_int_ velocity;
   Vec3_int_ normal;
-  Vec3_int_ field_34;
+  Vec3_int_ position;
   Vec3_int_ normal2;
   int field_4C;
   int field_50;
   int field_54;
-  Vec3_int_ field_58;
-  int field_64;
-  int field_68;
+  Vec3_int_ direction; // velocity's unit vector
+  int speed;
+  int inv_speed;
   int field_6C;
   int field_70;
   unsigned int uSectorID;
@@ -284,7 +285,7 @@
   int field_A4;
 };
 #pragma pack(pop)
-extern stru141 stru_721530;
+extern stru141_actor_collision_object stru_721530;
 
 
 
--- a/Items.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/Items.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -3,7 +3,6 @@
 #endif
 
 #include <stdlib.h>
-#include <assert.h>
 
 #include "Items.h"
 #include "MapInfo.h"
@@ -1460,7 +1459,7 @@
 //----- (00456499) --------------------------------------------------------
 const char *ItemGen::GetDisplayName()
 {
-  if (Identified())
+  if (IsIdentified())
     return GetIdentifiedName();
   else
     return pItemsTable->pItems[uItemID].pUnidentifiedName;
--- a/Items.h	Sun Sep 08 17:07:47 2013 +0600
+++ b/Items.h	Sun Sep 08 17:07:58 2013 +0600
@@ -6,7 +6,7 @@
     DMGT_FIRE   = 0,
     DMGT_ELECTR = 1,
     DMGT_COLD   = 2,
-    DMGT_3      = 3,
+    DMGT_EARTH      = 3,
     DMGT_PHISYCAL= 4,
     DMGT_5      = 5,
     DMGT_SPIRIT = 6,
@@ -81,21 +81,32 @@
   ITEM_SPELLBOOK_LIGHT_SUN_BURST = 0x1E6,
   ITEM_SPELLBOOK_LIGHT_DIVINE_INTERVENTION = 0x1E7,
   ITEM_ARTIFACT_PUCK = 500,//0x1F4,
+  ITEM_ARTIFACT_IRON_FEATHER = 501,
+  ITEM_ARTIFACT_WALLACE = 502,
+  ITEM_ARTIFACT_CORSAIR = 503,
   ITEM_ARTICACT_GOVERNONS_ARMOR = 504,//1F8
   ITEM_ARTIFACT_YORUBA = 505,//1F9
   ITEM_ARTIFACT_SPLITTER = 506,//1FA
   ITEM_ARTIFACT_GHOULSBANE = 507,//1FA
+  ITEM_ARTIFACT_GIBBET = 508,//1FA
+  ITEM_ARTIFACT_CHARELE = 509,//1FA
   ITEM_ARTEFACT_ULLYSES =510, 
+  ITEM_ARTEFACT_HANDS_OF_THE_MASTER =511, 
   ITEM_ARTIFACT_LEAGUE_BOOTS = 512,//200
+  ITEM_ARTIFACT_RULERS_RING = 513,
+  ITEM_RELIC_MASH = 514,
   ITEM_RELIC_ETHRICS_STAFF = 515,//204
   ITEM_RELIC_HARECS_LEATHER = 516,//204
-  ITEM_RELIC_OLD_NICK = 517,//204
+  ITEM_RELIC_OLD_NICK = 517,
+  ITEM_RELIC_AMUCK = 518,
+  ITEM_RELIC_GLORY_SHIELD = 519,
   ITEM_RELIC_KELEBRIM = 520,//208
   ITEM_RELIC_TALEDONS_HELM = 521,//209
   ITEM_RELIC_SCHOLARS_CAP = 522,//20A
   ITEM_RELIC_PHYNAXIAN_CROWN = 523,//20B
   ITEM_RILIC_TITANS_BELT = 524,//20C
   ITEM_RELIC_TWILIGHT = 525,//20D
+  ITEM_RELIC_ANIA_SELVING = 526,
   ITEM_RELIC_JUSTICE = 527,
   ITEM_RELIC_MEKORIGS_HAMMER = 528,
   ITEM_ARTIFACT_HERMES_SANDALS = 529,
@@ -156,10 +167,11 @@
  //   Reset();
  // }
 
-  inline bool Broken()        {return (uAttributes & ITEM_BROKEN) != 0;}
-  inline bool Identified()    {return (uAttributes & ITEM_IDENTIFIED) != 0;}
+  inline bool IsBroken()        {return (uAttributes & ITEM_BROKEN) != 0;}
+  inline void SetBroken()     {uAttributes |= ITEM_BROKEN;}
+  inline bool IsIdentified()    {return (uAttributes & ITEM_IDENTIFIED) != 0;}
   inline void SetIdentified() {uAttributes |= ITEM_IDENTIFIED;}
-  inline bool Stolen()        {return (uAttributes & ITEM_STOLEN) != 0;}
+  inline bool IsStolen()        {return (uAttributes & ITEM_STOLEN) != 0;}
   inline void SetStolen()     {uAttributes |= ITEM_STOLEN;}
 
   bool GenerateArtifact();
@@ -177,6 +189,7 @@
   int _bonus_strength;  //8
   int uSpecEnchantmentType; // 25  +5 levels //0c
                             // 16  Drain Hit Points from target.
+                            // 35  Increases chance of disarming.
                             // 39  Double damage vs Demons.
                             // 40  Double damage vs Dragons
                             // 45  +5 Speed and Accuracy
--- a/LOD.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/LOD.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -21,12 +21,15 @@
 
 LODFile_IconsBitmaps *pIcons_LOD = nullptr;
 LODFile_IconsBitmaps *pIcons_LOD_mm6 = nullptr;
+LODFile_IconsBitmaps *pIcons_LOD_mm8 = nullptr;
 
 LODFile_IconsBitmaps *pBitmaps_LOD = nullptr;
 LODFile_IconsBitmaps *pBitmaps_LOD_mm6 = nullptr;
+LODFile_IconsBitmaps *pBitmaps_LOD_mm8 = nullptr;
 
 LODFile_Sprites *pSprites_LOD = nullptr;
 LODFile_Sprites *pSprites_LOD_mm6 = nullptr;
+LODFile_Sprites *pSprites_LOD_mm8 = nullptr;
 
 LODWriteableFile *pNew_LOD = nullptr;
 LODWriteableFile *pGames_LOD = nullptr;
@@ -1453,7 +1456,7 @@
 //----- (00461F71) --------------------------------------------------------
 bool LOD::File::AppendDirectory(LOD::Directory *pDir, const void *pData)
 {
-  assert(uNumSubDirs < 299);
+  Assert(uNumSubDirs < 299);
 
   memcpy(&pSubIndices[uNumSubDirs++], pDir, sizeof(LOD::Directory));
   fwrite(pData, 1, pDir->uDataSize, pOutputFileHandle);
@@ -1677,7 +1680,7 @@
   uCurrentIndexDir = 0;
   uLODDataSize = lod_indx.uDataSize;
   uNumSubDirs = lod_indx.uNumSubIndices;
-  assert(uNumSubDirs <= 300);
+  Assert(uNumSubDirs <= 300);
 
   uOffsetToSubIndex = lod_indx.uOfsetFromSubindicesStart;
   fseek(pFile, uOffsetToSubIndex, SEEK_SET);
@@ -2079,7 +2082,8 @@
   v5 = v4;
   File = v4;
   if ( !v4 )
-    Abortf("Unable to load %s", pContainer);
+    Error("Unable to load %s", pContainer);
+
   fread(&DstBuf, 1u, 0x30u, v4);
   Argsa = DstBuf.uTextureSize;
   if ( DstBuf.uDecompressedSize )
@@ -2131,7 +2135,7 @@
   int v20; // edx@15
   signed int v21; // ecx@18
   signed int v22; // ecx@23
-  char Args[100]; // [sp+4h] [bp-68h]@3
+  //char Args[100]; // [sp+4h] [bp-68h]@3
   FILE *File; // [sp+68h] [bp-4h]@1
 
   v4 = this;
@@ -2140,10 +2144,8 @@
   {
     File = FindContainer("pending", 0);
     if ( !File )
-    {
-      sprintf(Args, "Can't find %s!", pContainer);
-      Abortf(Args);
-    }
+      Error("Can't find %s!", pContainer);
+
   }
   v5 = pDst;
   fread(pDst, 1u, 0x30u, File);
@@ -2832,7 +2834,7 @@
 {
   uint id = LoadTexture(pContainer, uTextureType);
 
-  assert(id != -1 && L"Texture not found");
+  Assert(id != -1 && L"Texture not found");
 
   return &pTextures[id];
 }
@@ -2857,7 +2859,7 @@
 //  if (!uNumLoadedFiles)
 //  {
 //LABEL_5:
-    assert(uNumLoadedFiles < 1000);
+    Assert(uNumLoadedFiles < 1000);
     /*if (uNumLoadedFiles >= 1000)
     {
       Log::Warning(L"Maximum texture number exceeded");
--- a/LOD.h	Sun Sep 08 17:07:47 2013 +0600
+++ b/LOD.h	Sun Sep 08 17:07:58 2013 +0600
@@ -1,9 +1,9 @@
 #pragma once
 #include <stdio.h>
 #include <memory.h>
-#include <assert.h>
 
 #include "Texture.h"
+#include "ErrorHandling.h"
 
 class Sprite;
 
@@ -166,7 +166,7 @@
 
   inline struct Texture *GetTexture(int idx)
   {
-    assert(idx < 1000);
+    Assert(idx < 1000, "Texture index out of bounds (%u)", idx);
     if (idx == -1) 
       return nullptr; // we need to return dummy texture here
     return &pTextures[idx];
@@ -302,14 +302,18 @@
 
 
 extern LODFile_IconsBitmaps *pEvents_LOD;
+
 extern LODFile_IconsBitmaps *pIcons_LOD;
 extern LODFile_IconsBitmaps *pIcons_LOD_mm6;
+extern LODFile_IconsBitmaps *pIcons_LOD_mm8;
 
 extern LODFile_IconsBitmaps *pBitmaps_LOD;
 extern LODFile_IconsBitmaps *pBitmaps_LOD_mm6;
+extern LODFile_IconsBitmaps *pBitmaps_LOD_mm8;
 
 extern LODFile_Sprites *pSprites_LOD;
 extern LODFile_Sprites *pSprites_LOD_mm6;
+extern LODFile_Sprites *pSprites_LOD_mm8;
 
 extern LODWriteableFile *pNew_LOD;
 extern LODWriteableFile *pGames_LOD;
--- a/Level/Decoration.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/Level/Decoration.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -1,5 +1,6 @@
 #include "Decoration.h"
 #include "../Party.h"
+#include "../ErrorHandling.h"
 
 //----- (004583B0) --------------------------------------------------------
 LevelDecoration::LevelDecoration()
@@ -106,7 +107,7 @@
     case 225: case 226: case 227:
       return 0;
 
-    default: assert(false && "Invalid Decoration");
+    default: Error("Invalid DecorationDescID: %u", uDecorationDescID);
   }
 }
 
--- a/Level/Decoration.h	Sun Sep 08 17:07:47 2013 +0600
+++ b/Level/Decoration.h	Sun Sep 08 17:07:58 2013 +0600
@@ -1,8 +1,10 @@
 #pragma once
 
-#include "../mm7_data.h"
+#include <cstdint>
 
-enum LEVEL_DECORATION_FLAGS: uint16
+#include "../VectorTypes.h"
+
+enum LEVEL_DECORATION_FLAGS: uint16_t
 {
   LEVEL_DECORATION_TRIGGERED_BY_TOUCH = 0x01,
   LEVEL_DECORATION_TRIGGERED_BY_MONSTER = 0x02,
@@ -22,15 +24,15 @@
   bool IsInteractive();
   bool IsObeliskChestActive();
 
-  uint16 uDecorationDescID;
-  uint16 uFlags;
+  uint16_t uDecorationDescID;
+  uint16_t uFlags;
   Vec3_int_ vPosition;
-  int32 field_10_y_rot;
-  uint16 uCog;
-  int16 field_16_event_id;
-  int16 field_18;
-  int16 field_1A;
-  int16 _idx_in_stru123;
-  int16 field_1E;
+  int32_t field_10_y_rot;
+  uint16_t uCog;
+  uint16_t uEventID;
+  uint16_t uTriggerRange;
+  int16_t field_1A;
+  int16_t _idx_in_stru123;
+  int16_t field_1E;
 };
 #pragma pack(pop)
--- a/LightmapBuilder.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/LightmapBuilder.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -1,11 +1,10 @@
-#include <assert.h>
-
 #include "LightmapBuilder.h"
 #include "Game.h"
 #include "stru314.h"
 #include "Outdoor.h"
 #include "Outdoor_stuff.h"
 #include "Log.h"
+#include "ErrorHandling.h"
 
 #include "OutdoorCamera.h"
 #include "Lights.h"
@@ -1655,7 +1654,7 @@
         {
           v28 = &std__vector_000004[*i];
           if ( !DrawLightmap(v28, &arg4, 0.0) )
-            assert(false && "Invalid lightmap detected!");
+            Error("Invalid lightmap detected! (%u)", *i);
         }
       }
       else
--- a/Log.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/Log.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -19,14 +19,16 @@
     return;
 
   va_list args;
+  wchar_t pMsg[8192];
 
   va_start(args, pFormat);
-  vwprintf_s(pFormat, args);
+  vswprintf_s(pMsg, 8192, pFormat, args);
   va_end(args);
-  puts("\r\n");
 
+  DWORD w;
+  WriteConsole(hStdOut, pMsg, lstrlenW(pMsg), &w, nullptr);
+  WriteConsole(hStdOut, L"\r\n", 2, &w, nullptr);
 }
-
 //----- (004BE386) --------------------------------------------------------
 void __fastcall log_error(const char *pMessage)
 {
--- a/MM7.h	Sun Sep 08 17:07:47 2013 +0600
+++ b/MM7.h	Sun Sep 08 17:07:58 2013 +0600
@@ -12,19 +12,7 @@
 typedef unsigned __int64 _QWORD;
 
 
-/*  288 */
-/*#pragma pack(push, 1)
-struct CheckHRESULT_stru0
-{
-  void CheckHRESULT(HRESULT a2, const char *Str, int a4, unsigned int uType);
-  void *_466D09_xcpt_string(std::string a2, const char *Str, int a4);
-  void ShowMessageBox(std::string *a0, std::string lpCaption, UINT uType, std::string lpText, int line);
-  char ddraw_error(HRESULT hr, char *Str, size_t a3);
-  char dinput_error(int a1, const char *Str, int a3);
 
-  void ( ***vdestructor_ptr)(CheckHRESULT_stru0 *, bool);
-};
-#pragma pack(pop)*/
 
 
 
--- a/Math.h	Sun Sep 08 17:07:47 2013 +0600
+++ b/Math.h	Sun Sep 08 17:07:58 2013 +0600
@@ -1,11 +1,7 @@
 #pragma once
+
 #include <cassert>
 #include <limits>
-#include <float.h>
-#include <cmath>
-#include <cstdlib>
-#include <ciso646>
-
 
 /*  186 */
 #pragma pack(push, 1)
@@ -28,26 +24,21 @@
 };
 #pragma pack(pop)
 
-
-int fixpoint_sub0(int, int);
-int fixpoint_div(int, int);
-int fixpoint_mul(int, int);
+__int64 fixpoint_sub0(int, int);
+__int64 fixpoint_dot(int x1, int x2, int y1, int y2, int z1, int z2);
+__int64 fixpoint_div(int, int);
+__int64 fixpoint_mul(int, int);
 int fixpoint_from_float(float value);
 
-#ifndef ROUNDING_EPSILON
-#define ROUNDING_EPSILON 0.0000001
-#endif
-
-
 template <typename FloatType>
-int bankersRounding(
+inline int bankersRounding(
   const FloatType& value
   ) {
     assert("Method unsupported for this type" && false);
     return value;
 }
 
-template<> static int bankersRounding<float>(const float& inValue)
+template<> inline int bankersRounding<float>(const float& inValue)
 {
   union Cast
   {
@@ -61,8 +52,7 @@
 
 #pragma push_macro("max")
 #undef max
-
-template<> static int bankersRounding<double>(const double& inValue)
+template<> inline int bankersRounding<double>(const double& inValue)
 {
   double maxValue = std::numeric_limits<int>::max();
   assert(maxValue - 6755399441055744.0 >= inValue);
@@ -75,8 +65,6 @@
   c.d = inValue + 6755399441055744.0;
   return c.l;
 }
-
-
 #pragma pop_macro("max")
 
-extern struct stru193_math *stru_5C6E00;
\ No newline at end of file
+extern struct stru193_math *stru_5C6E00;
--- a/Monsters.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/Monsters.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -368,7 +368,8 @@
   v3 = fopen(Args, "r");
   File = v3;
   if ( !v3 )
-    Abortf("MonsterRaceListStruct::load - Unable to open file: %s.");
+    Error("MonsterRaceListStruct::load - Unable to open file: %s.");
+
   v4 = 0;
   Argsa = 0;
   if ( fgets(&Buf, 490, v3) )
@@ -387,7 +388,8 @@
   v5 = pAllocator->AllocNamedChunk(v2->pMonsters, 152 * v4, "Mon Race");
   v2->pMonsters = (MonsterDesc *)v5;
   if ( !v5 )
-    Abortf("MonsterRaceListStruct::load - Out of Memory!");
+    Error("MonsterRaceListStruct::load - Out of Memory!");
+
   v6 = File;
   v2->uNumMonsters = 0;
   fseek(v6, 0, 0);
@@ -463,8 +465,8 @@
        num_mm8_monsters = data_mm8 ? *(int *)data_mm8 : 0;
 
   uNumMonsters = num_mm6_monsters + num_mm7_monsters + num_mm8_monsters;
-  assert(uNumMonsters);
-  assert(!num_mm8_monsters);
+  Assert(uNumMonsters);
+  Assert(!num_mm8_monsters);
 
   pMonsters = (MonsterDesc *)pAllocator->AllocNamedChunk(pMonsters, sizeof(MonsterDesc) * uNumMonsters, "Mon Race");
   memcpy(pMonsters, (char *)data_mm7 + 4, num_mm7_monsters * sizeof(MonsterDesc));
@@ -496,7 +498,7 @@
   v2 = fopen("data\\dmonlist.bin", "wb");
   v3 = v2;
   if ( !v2 )
-    Abortf("Unable to save dmonlist.bin!");
+    Error("Unable to save dmonlist.bin!");
   fwrite(v1, 4u, 1u, v2);
   fwrite(v1->pMonsters, 0x98u, v1->uNumMonsters, v3);
   fclose(v3);
@@ -1193,7 +1195,7 @@
         if( (!_stricmp(pMonsters[i].pMonsterName, pMonsterName)))
             return i;
     }
-    assert(false && "Monster not found!");
+    Error("Monster not found: %s", pMonsterName);
 }
 //----- (00438BDF) --------------------------------------------------------
 bool MonsterStats::BelongsToSupertype(unsigned int uMonsterInfoID, enum MONSTER_SUPERTYPE eSupertype)
--- a/Mouse.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/Mouse.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -453,9 +453,9 @@
         while ( v8 < this->field_4C );
         v6 = v15;
       }
-      if (pParty->pPickedItem.Broken())
+      if (pParty->pPickedItem.IsBroken())
         pRenderer->DrawTransparentRedShade(a2, v6, pTexture);
-      else if (!pParty->pPickedItem.Identified())
+      else if (!pParty->pPickedItem.IsIdentified())
         pRenderer->DrawTransparentGreenShade(a2, v6, pTexture);
       else
         pRenderer->DrawTextureTransparent(a2, v6, pTexture);
--- a/NPC.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/NPC.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -1343,7 +1343,7 @@
       OracleDialogue();
       goto _return;
     case 311:
-      sub_4BBA85_bounties();
+      CheckBountyRespawnAndAward();
     goto _return;
   }*/
   if ( pEventNumber < 200 || pEventNumber > 310 )
@@ -1358,7 +1358,7 @@
         { 
           if ( pEventNumber == 311 )
           {
-            sub_4BBA85_bounties();
+            CheckBountyRespawnAndAward();
           }
           else
           {
--- a/OSAPI.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/OSAPI.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -39,3 +39,11 @@
   //__debugbreak();
   return 0;
 }
+
+
+
+
+void MsgBox(const wchar_t *msg, const wchar_t *title)
+{
+  MessageBoxW(nullptr, msg, title, 0);
+}
\ No newline at end of file
--- a/OSAPI.h	Sun Sep 08 17:07:47 2013 +0600
+++ b/OSAPI.h	Sun Sep 08 17:07:58 2013 +0600
@@ -1,5 +1,4 @@
 #define WIN32_LEAN_AND_MEAN
-#include <assert.h>
 #include <windows.h>
 
 #include <MMSystem.h>
--- a/ObjectList.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/ObjectList.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -3,6 +3,7 @@
 #include "Sprites.h"
 #include "FrameTableInc.h"
 #include "Allocator.h"
+#include "ErrorHandling.h"
 
 //----- (0042EB42) --------------------------------------------------------
 __int16 ObjectList::ObjectIDByItemID(unsigned __int16 uItemID)
@@ -49,7 +50,7 @@
   v2 = fopen("data\\dobjlist.bin", "wb");
   v3 = v2;
   if ( !v2 )
-    Abortf("Unable to save dobjlist.bin!");
+    Error("Unable to save dobjlist.bin!");
   fwrite(v1, 4u, 1u, v2);
   fwrite(v1->pObjects, 0x38u, v1->uNumObjects, v3);
   fclose(v3);
@@ -63,8 +64,8 @@
        num_mm8_objs = data_mm8 ? *(int *)data_mm8 : 0;
 
   uNumObjects = num_mm6_objs + num_mm7_objs + num_mm8_objs;
-  assert(uNumObjects);
-  assert(!num_mm8_objs);
+  Assert(uNumObjects);
+  Assert(!num_mm8_objs);
 
   pObjects = (ObjectDesc *)pAllocator->AllocNamedChunk(pObjects, uNumObjects * sizeof(ObjectDesc), "Obj Descrip");
   memcpy(pObjects, (char *)data_mm7 + 4, num_mm7_objs * sizeof(ObjectDesc));
@@ -148,7 +149,8 @@
   v4 = fopen(Args, "r");
   File = v4;
   if ( !v4 )
-    Abortf("ObjectDescriptionList::load - Unable to open file: %s.");
+    Error("ObjectDescriptionList::load - Unable to open file: %s.");
+
   v5 = 0;
   Argsa = 0;
   if ( fgets(&Buf, 490, v4) )
@@ -168,7 +170,8 @@
   v6 = pAllocator->AllocNamedChunk(v2->pObjects, 56 * v5, "Obj Descrip");
   v2->pObjects = (ObjectDesc *)v6;
   if ( v6 == (void *)v3 )
-    Abortf("ObjectDescriptionList::load - Out of Memory!");
+    Error("ObjectDescriptionList::load - Out of Memory!");
+
   memset(v6, v3, 56 * v2->uNumObjects);
   v7 = File;
   v2->uNumObjects = v3;
--- a/Outdoor.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/Outdoor.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -2,8 +2,6 @@
 #define _CRT_SECURE_NO_WARNINGS
 #endif
 
-#include <assert.h>
-
 #include "stru6.h"
 #include "Weather.h"
 #include "Sprites.h"
@@ -108,7 +106,6 @@
   pIndoorCamera->pos.z = pParty->vPosition.z + pParty->sEyelevel;
   if (bRedraw || pRenderer->pRenderD3D)
   {
-    ResetPolygons();
     pOutdoorCamera->RotationToInts();
     sub_481ED9_MessWithOutdoorCamera();
   }
@@ -1158,7 +1155,7 @@
   void *v5; // ST14_4@1
   void *v6; // eax@1
   unsigned int v7; // eax@1
-  char v8; // zf@1
+  //char v8; // zf@1
 
   v1 = this;
   strcpy(this->pLevelFilename, "blank");
@@ -1199,12 +1196,13 @@
   v1->uSky_TextureID = pBitmaps_LOD->LoadTexture(v1->pSkyTextureName);
   strcpy(v1->pGroundTileset, byte_6BE124_cfg_textures_DefaultGroundTexture.data());
   v7 = pBitmaps_LOD->LoadTexture(v1->pGroundTileset);
-  v8 = v1->uSky_TextureID == -1;
   v1->uMainTile_BitmapID = v7;
-  if ( v8 )
-    Abortf("Invalid Sky Tex Handle");
+
+  if ( v1->uSky_TextureID == -1 )
+    Error("Invalid Sky Tex Handle");
+
   if ( v1->uMainTile_BitmapID == -1 )
-    Abortf("Invalid Ground Tex Handle");
+    Error("Invalid Ground Tex Handle");
 }
 
 
@@ -1714,7 +1712,7 @@
   assert(sizeof(BSPModel) == 188);
 
   if (!pGames_LOD->DoesContainerExist(pFilename))
-    Abortf("Unable to find %s in Games.LOD", pFilename);
+    Error("Unable to find %s in Games.LOD", pFilename);
 
 
   char pMinimapTextureFilename[1024];
@@ -2718,7 +2716,7 @@
       }
       if ( v8 && decor->uCog == 20 )
         decor->uFlags |= LEVEL_DECORATION_OBELISK_CHEST;
-      if ( !decor->field_16_event_id )
+      if ( !decor->uEventID )
       {
         if ( decor->IsInteractive() )
         {
--- a/Outdoor_stuff.h	Sun Sep 08 17:07:47 2013 +0600
+++ b/Outdoor_stuff.h	Sun Sep 08 17:07:58 2013 +0600
@@ -68,13 +68,13 @@
 #pragma pack(push, 1)
 struct stru149
 {
-  int _48616B(int a2, int a3, int a4, int a5, int a6, int a7);
-  int _48653D(int a2, int a3, int a4, int a5, int a6, int a7);
-  void Inverse_sky_48694B();
+  void _48616B_frustum_odm(int a2, int a3, int a4, int a5, int a6, int a7);
+  void _48653D_frustum_blv(int a2, int a3, int a4, int a5, int a6, int a7);
+  void _48694B_frustum_sky();
 
   int field_0_party_dir_x;
   int field_4_party_dir_y;
-  int field_8;
+  int field_8_party_dir_z;
   int field_C;
   int field_10;
   int field_14;
--- a/Overlays.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/Overlays.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -176,7 +176,7 @@
   v2 = fopen("data\\doverlay.bin", "wb");
   v3 = v2;
   if ( !v2 )
-    Abortf("Unable to save doverlay.bin!");
+    Error("Unable to save doverlay.bin!");
   fwrite(v1, 4u, 1u, v2);
   fwrite(v1->pOverlays, 8u, v1->uNumOverlays, v3);
   fclose(v3);
@@ -190,8 +190,8 @@
        num_mm8_overlays = data_mm8 ? *(int *)data_mm8 : 0;
 
   uNumOverlays = num_mm6_overlays + num_mm7_overlays + num_mm8_overlays;
-  assert(uNumOverlays);
-  assert(!num_mm8_overlays);
+  Assert(uNumOverlays);
+  Assert(!num_mm8_overlays);
 
   pOverlays = (OverlayDesc *)pAllocator->AllocNamedChunk(pOverlays, uNumOverlays * sizeof(OverlayDesc), "Ovl Des.");
   memcpy(pOverlays,                                       (char *)data_mm7 + 4, num_mm7_overlays * sizeof(OverlayDesc));
@@ -230,7 +230,8 @@
   v4 = fopen(Args, "r");
   File = v4;
   if ( !v4 )
-    Abortf("ObjectDescriptionList::load - Unable to open file: %s.");
+    Error("ObjectDescriptionList::load - Unable to open file: %s.");
+
   v5 = 0;
   Argsa = 0;
   if ( fgets(&Buf, 490, v4) )
@@ -251,7 +252,8 @@
   v7 = pAllocator->AllocNamedChunk(v6, 8 * v5, "Ovl Des.");
   v2->pOverlays = (OverlayDesc *)v7;
   if ( v7 == (void *)v3 )
-    Abortf("OverlayDescriptionList::load - Out of Memory!");
+    Error("OverlayDescriptionList::load - Out of Memory!");
+
   memset(v7, v3, 8 * v2->uNumOverlays);
   v8 = File;
   v2->uNumOverlays = v3;
--- a/PaletteManager.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/PaletteManager.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -2,8 +2,6 @@
 #define _CRT_SECURE_NO_WARNINGS
 #endif
 
-#include <assert.h>
-
 #include "PaletteManager.h"
 #include "Texture.h"
 #include "Game.h"
@@ -423,7 +421,7 @@
       }
       else if (v23 == 0)
         Log::Warning(L"Calling palette manager with num_target_bits == 0");
-      else assert(false);
+      else Error("(%u)", v23);
       //v24 = (unsigned __int32)a3 | ((unsigned __int32)a2a << v2->uNumTargetBBits) | ((unsigned __int32)a1 << (v2->uNumTargetBBits + v2->uNumTargetGBits));
       //v25 = v73;
       //v73 += 2;
@@ -472,7 +470,7 @@
       }
       else if (v23 == 0)
         Log::Warning(L"Calling palette manager with num_target_bits == 0");
-      else assert(false);
+      else Error("(%u)", v23);
 
       //v29 = (unsigned __int64)(signed __int64)a3 | ((unsigned __int16)(signed __int64)a2a << v2->uNumTargetBBits) | (unsigned __int16)((unsigned __int16)(signed __int64)a1 << (v2->uNumTargetBBits + v28));
       //v30 = (__int16 *)v73;
@@ -517,7 +515,7 @@
     }
       else if (v23 == 0)
         Log::Warning(L"Calling palette manager with num_target_bits == 0");
-    else assert(false);
+    else Error("(%u)", v23);
 
     v36 = (signed __int64)((a1 + a2a + a3) * 0.3333333333333333 * 8.0);
     v37 = (signed int)v36 >> (8 - v2->uNumTargetRBits);
@@ -593,7 +591,7 @@
       }
       else if (v23 == 0)
         Log::Warning(L"Calling palette manager with num_target_bits == 0");
-      else assert(false);
+      else Error("(%u)", v23);
 
       if (pPalette_mistColor[0] || pPalette_mistColor[1] || pPalette_mistColor[2])
       {
--- a/Party.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/Party.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -2,8 +2,6 @@
 #define _CRT_SECURE_NO_WARNINGS
 #endif
 
-#include <assert.h>
-
 #include "Party.h"
 #include "MapInfo.h"
 #include "Time.h"
@@ -82,7 +80,7 @@
     uFallSpeed = 0;
     field_28 = 0;
     uDefaultPartyHeight = 120;
-    field_14 = 37;
+    field_14_radius = 37;
     y_rotation_granularity = 25;
     y_rotation_speed = 90;
 
@@ -895,7 +893,7 @@
   this->uFallSpeed = 0;
   this->field_28 = 0;
   this->uDefaultPartyHeight = 120;
-  this->field_14 = 37;
+  this->field_14_radius = 37;
   this->y_rotation_granularity = 25;
   this->uWalkSpeed = 384;
   this->y_rotation_speed = 90;
@@ -1022,7 +1020,7 @@
         case Condition_Paralyzed:   player->expression = CHARACTER_EXPRESSION_PARALYZED; break;
         case Condition_Unconcious:  player->expression = CHARACTER_EXPRESSION_UNCONCIOUS; break;
         default:
-          assert(false);
+          Error("Invalid condition: %u", condition);
       }
     }
   }
@@ -1041,7 +1039,7 @@
       hireling->evt_B = 0;
       hireling->evt_C = 0;
 
-      assert(sizeof(NPCData) == 0x4C);
+      Assert(sizeof(NPCData) == 0x4C);
       memset(hireling, 0, sizeof(*hireling));
 
       pParty->field_709 = 0;
@@ -1222,10 +1220,6 @@
 {
   if ( _506F18_num_minutes_to_sleep < 6 )
   {
-    pParty->pPlayers[3].SetAsleep(false);
-    pParty->pPlayers[2].SetAsleep(false);
-    pParty->pPlayers[1].SetAsleep(false);
-    pParty->pPlayers[0].SetAsleep(false);
     if ( _506F18_num_minutes_to_sleep )
     {
       Rest(_506F18_num_minutes_to_sleep);
@@ -1234,25 +1228,8 @@
     }
     if ( dword_506F14 == 2 )
     {
-      pGUIWindow_CurrentMenu->Release();
-      pEventTimer->Resume();
-      if ( pTexture_RestUI_CurrentSkyFrame )
-        pTexture_RestUI_CurrentSkyFrame->Release();
-      if ( pTexture_RestUI_CurrentHourglassFrame )
-        pTexture_RestUI_CurrentHourglassFrame->Release();
-      pTexture_RestUI_CurrentHourglassFrame = 0;
-      pTexture_RestUI_CurrentSkyFrame = 0;
-      pIcons_LOD->RemoveTexturesPackFromTextureList();
-      pIcons_LOD->SyncLoadedFilesCount();
-      pCurrentScreen = SCREEN_GAME;
-      viewparams->bRedrawGameUI = 1;
-      if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor)
-      {
-        pOutdoor->UpdateSunlightVectors();
-        pOutdoor->UpdateFog();
-      }
+      pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 0, 0);
     }
-    dword_506F14 = 0;
   }
   else
   {
--- a/Party.h	Sun Sep 08 17:07:47 2013 +0600
+++ b/Party.h	Sun Sep 08 17:07:58 2013 +0600
@@ -150,9 +150,10 @@
 #pragma pack(push, 1)
 struct Party_stru0
 {
-  int field_0[20];
+  //__int64 field_0[10];
+  __int64 bountyHunting_next_generation_time[10];
  // int field_50[170];
-  __int64 field_50[85];
+  __int64 Shops_next_generation_time[85];//field_50
   __int64 _shop_ban_times[53];
   int field_4A0[20];
   int field_4F0[38];
@@ -185,7 +186,7 @@
   void SetHoldingItem(ItemGen *pItem);
   int GetNextActiveCharacter();
   bool _497FC5_check_party_perception_against_level();
-  bool AddItem(ItemGen *pItem);
+  bool AddItemToParty(ItemGen *pItem);
   void Yell();
   void CountHirelings();
   
@@ -218,7 +219,7 @@
   unsigned int uDefaultPartyHeight;
   int sEyelevel;
   unsigned int uDefaultEyelevel;
-  int field_14;
+  int field_14_radius;
   int y_rotation_granularity;
   unsigned int uWalkSpeed;
   int y_rotation_speed;  // deg/s
@@ -265,8 +266,8 @@
   int uNumPrisonTerms;
   unsigned int uNumBountiesCollected;
   int field_74C;
-  __int16 field_750[5];
-  __int16 field_75A[5];
+  __int16 monster_id_for_hunting[5];
+  __int16 monster_for_hunting_killed[5];
   unsigned char   days_played_without_rest;
   unsigned __int8 _quest_bits[64];
   unsigned __int8 pArcomageWins[16];
--- a/Player.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/Player.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -2,11 +2,8 @@
 #define _CRT_SECURE_NO_WARNINGS
 #endif
 
-#include <assert.h>
-
 #include "stru6.h"
 
-
 #include "Player.h"
 #include "PlayerFrameTable.h"
 #include "AudioPlayer.h"
@@ -245,7 +242,7 @@
   item_value =pOwnItems[item_index].GetValue();
   v6 = p2DEvents[ _2devent_idx - 1].fPriceMultiplier;
   sell_price = GetPriceSell(item_value, v6);
-  if ( pOwnItems[item_index].Broken() )
+  if ( pOwnItems[item_index].IsBroken() )
     sell_price = 1;
   if ( sell_price < 1 )
     sell_price = 1;
@@ -266,7 +263,7 @@
     if (item_idx)
     {
       item_id = pOwnItems[item_idx - 1].uItemID;
-      if ( item_id != 64 && item_id != 65 ) //blaster& blaster rifle
+      if ( item_id != ITEM_BLASTER && item_id != ITEM_LASER_RIFLE ) //blaster& blaster rifle
           return false;
     }
   }
@@ -343,7 +340,6 @@
 int Player::GetBuyingPrice(unsigned int uRealValue, float price_multiplier)
 {
   uint price = (uint)(((100 - GetMerchant()) * (uRealValue * price_multiplier)) / 100);
-  assert (price > 0);
 
   if (price < uRealValue)
     price = uRealValue;
@@ -650,7 +646,7 @@
         return(_449B57_test_bit((unsigned __int8 *)this->_achieved_awards_bits, 79));
         break;
       default:
-        assert("Should not be able to get here" && false);
+        Error("Should not be able to get here (%u)", uClass);
         break;
     }
     return false;
@@ -813,27 +809,19 @@
     texture->Release();
     pIcons_LOD->SyncLoadedFilesCount();
   }
-  if ( slotHeight == 0 || slotWidth == 0)
-  {
-    assert("Items should have nonzero dimensions");
-    return 1;
-  }
+  Assert(slotHeight > 0 && slotWidth > 0, "Items should have nonzero dimensions");
   if ( (slotWidth + uSlot % INVETORYSLOTSWIDTH) <= INVETORYSLOTSWIDTH && (slotHeight + uSlot / INVETORYSLOTSWIDTH) <= INVETORYSLOTSHEIGHT )
   {
-    int startOfInnerLoop = uSlot;
-    for (unsigned int y = 0; y < slotHeight; y++)
-    {
-      int innerLoopPos = startOfInnerLoop;
       for (unsigned int x = 0; x < slotWidth; x++)
       {
-        if (pInventoryMatrix[innerLoopPos] != 0)
+        for (unsigned int y = 0; y < slotHeight; y++)
         {
-          return false;
+          if (pInventoryMatrix[y * INVETORYSLOTSWIDTH + x + uSlot] != 0)
+          {
+            return false;
+          }
         }
-        innerLoopPos++;
       }
-      startOfInnerLoop += INVETORYSLOTSWIDTH;
-    }
     return true;
   }
   return false;
@@ -911,23 +899,19 @@
 int Player::AddItem(int index, unsigned int uItemID)
 {
   int xStartValue = 0;
-  int startOfInnerLoop = 0;
 
   if ( index == -1 )
   {
-    for (int ycoord = 0; ycoord < INVETORYSLOTSHEIGHT; ycoord++)
-    {
-      int innerLoopPos = startOfInnerLoop;
       for (int xcoord = 0; xcoord < INVETORYSLOTSWIDTH; xcoord++)
       {
-        if ( CanFitItem(innerLoopPos, uItemID) )
+        for (int ycoord = 0; ycoord < INVETORYSLOTSHEIGHT; ycoord++)
         {
-          return CreateItemInInventory(innerLoopPos, uItemID);
+          if ( CanFitItem(ycoord * INVETORYSLOTSWIDTH + xcoord, uItemID) )
+          {
+            return CreateItemInInventory(ycoord * INVETORYSLOTSWIDTH + xcoord, uItemID);
+          }
         }
-        innerLoopPos++;
       }
-      startOfInnerLoop += INVETORYSLOTSWIDTH;
-    }
     return 0;
   }
   if ( !CanFitItem(index, uItemID) )
@@ -941,24 +925,19 @@
 //----- (00492826) --------------------------------------------------------
 int Player::AddItem2(int index, ItemGen *Src)
 {
-  int xStartValue = 0;
   pItemsTable->SetSpecialBonus(Src);
-  int startOfInnerLoop = 0;
 
   if ( index == -1 )
   {
-    for (int ycoord = 0; ycoord < INVETORYSLOTSHEIGHT; ycoord++)      //TODO: change pInventoryMatrix to 2 dimensional array.
-    {
-      int innerLoopPos = startOfInnerLoop;
-      for (int xcoord = 0; xcoord < INVETORYSLOTSWIDTH; xcoord++)
+    for (int xcoord = 0; xcoord < INVETORYSLOTSWIDTH; xcoord++)
+    {
+      for (int ycoord = 0; ycoord < INVETORYSLOTSHEIGHT; ycoord++)      //TODO: change pInventoryMatrix to 2 dimensional array.
       {
-        if ( CanFitItem(innerLoopPos, Src->uItemID) )
+        if ( CanFitItem(ycoord * INVETORYSLOTSWIDTH + xcoord, Src->uItemID) )
         {
-          return CreateItemInInventory2(innerLoopPos, Src);
+          return CreateItemInInventory2(ycoord * INVETORYSLOTSWIDTH + xcoord, Src);
         }
-        innerLoopPos++;
       }
-      startOfInnerLoop += INVETORYSLOTSWIDTH;
     }
     return 0;
   }
@@ -1091,10 +1070,10 @@
         return 4;
     break;
     default:
-      assert(false);
+      Error("(%u)", building_type);
     break;
   }
-  if (pItem->Stolen())
+  if (pItem->IsStolen())
     return 6;
 
   multiplier = p2DEvents[BuildID_2Events - 1].fPriceMultiplier;
@@ -1104,7 +1083,7 @@
       price = GetBuyingPrice(itemValue, multiplier);
     break;
     case 3:
-      if (pItem->Broken())
+      if (pItem->IsBroken())
         price = 1;
       else
         price = this->GetPriceSell(itemValue, multiplier);
@@ -1116,7 +1095,7 @@
       price = this->GetPriceRepair(itemValue, multiplier);
       break;
     default:
-      assert(false);
+      Error("(%u)", ShopMenuType);
     break;
   }
   if ( merchantLevel )
@@ -1140,296 +1119,122 @@
 int Player::GetBodybuilding()
 {
   int v1; // al@1
-  int v2; // ecx@1
-  int v4; // eax@3
-  signed int v6; // [sp-4h] [bp-4h]@2
 
   v1 = GetActualSkillLevel(PLAYER_SKILL_BODYBUILDING);
-  v2 = v1 & 0x3F;
-  if ( v1 & 0x100 )
-  {
-    v6 = 5;
-  }
-  else
-  {
-    if ( (v1&0xFF) >= 0 )
-    {
-      v4 = ((v1 & 0x40) != 0) + 1;
-      return v2 * v4;
-    }
-    v6 = 3;
-  }
-  v4 = v6;
-  return v2 * v4;
+  int multiplier = GetMultiplierForSkillLevel(v1, 1, 2, 3, 5);
+  return multiplier * (v1 & 0x3F);
 }
 
 //----- (004910A8) --------------------------------------------------------
 int Player::GetMeditation()
 {
   int v1; // al@1
-  int base_level; // ecx@1
-  int v4; // eax@3
-  signed int v6; // [sp-4h] [bp-4h]@2
 
   v1 = GetActualSkillLevel(PLAYER_SKILL_MEDITATION);
-  base_level = v1 & 0x3F;
-  if ( v1 & 0x100 )
-  {
-    v6 = 5;
-  }
-  else
-  {
-    if ( (v1&0xFF) >= 0 )
-    {
-      v4 = ((v1 & 0x40) != 0) + 1;
-      return base_level * v4;
-    }
-    v6 = 3;
-  }
-  v4 = v6;
-  return base_level * v4;
+  int multiplier = GetMultiplierForSkillLevel(v1, 1, 2, 3, 5);
+  return multiplier * (v1 & 0x3F);
 }
 
 //----- (004910D3) --------------------------------------------------------
-int Player::CanIdentify(ItemGen *pItem)
+bool Player::CanIdentify( ItemGen *pItem )
 {
   unsigned __int16 v2; // ax@1
-  unsigned __int16 v3; // bx@1
-  int uSkillMult; // eax@3
   int v5; // edi@7
-  signed int v6; // ebp@7
-  char *v7; // esi@7
-  signed int uSkillMultiplier; // [sp-4h] [bp-14h]@2
 
   if (CheckHiredNPCSpeciality(Scholar))
     return true;
 
-  v2 = pPlayers[uActiveCharacter]->GetActualSkillLevel(PLAYER_SKILL_ITEM_ID);
-  v3 = v2;
-  if ( v2 & 1 )
-  {
-    uSkillMultiplier = 5;
-  }
-  else
-  {
-    if ( (v2 & 0x80u) == 0 )
-    {
-      uSkillMult = ((v2 & 0x40) != 0) + 1;
-      v5 = uSkillMult * (v3 & 0x3F);
-      v6 = 0;
-      v7 = (char *)&pItemsTable->pItems[pItem->uItemID].pIconName;
-
-      if ( (signed int)SkillToMastery(v3) >= 4 )
-        v6 = 1;
-      if ( v5 >= (unsigned __int8)v7[46] )
-        v6 = 1;
-      return v6;
-    }
-    uSkillMultiplier = 3;
-  }
-  uSkillMult = uSkillMultiplier;
-  v5 = uSkillMult * (v3 & 0x3F);
-  v6 = 0;
-  v7 = (char *)&pItemsTable->pItems[pItem->uItemID].pIconName;
-
-  if ( (signed int)SkillToMastery(v3) >= 4 )
-    v6 = 1;
-  if ( v5 >= (unsigned __int8)v7[46] )
-    v6 = 1;
-  return v6;
+  v2 = GetActualSkillLevel(PLAYER_SKILL_ITEM_ID);
+  if ( (signed int)SkillToMastery(v2) >= 4 )
+    return true;
+
+  int multiplier = GetMultiplierForSkillLevel(v2, 1, 2, 3, 5);
+  v5 = multiplier * (v2 & 0x3F);
+  return v5 >= pItemsTable->pItems[pItem->uItemID].uItemID_Rep_St;
 }
 
 //----- (00491151) --------------------------------------------------------
-int Player::CanRepair(ItemGen *a2)
+bool Player::CanRepair( ItemGen *pItem )
 {
   unsigned __int16 v2; // ax@1
-  unsigned __int16 v3; // bx@1
-  int v4; // eax@3
   int v5; // edi@7
-  signed int v6; // ebp@7
-  signed int v10; // [sp-4h] [bp-14h]@2
-
-  
-  auto v7 = &pItemsTable->pItems[a2->uItemID];
+
+  ItemDesc* v7 = &pItemsTable->pItems[pItem->uItemID];
   if (CheckHiredNPCSpeciality(Smith) && v7->uEquipType <= 2 ||
       CheckHiredNPCSpeciality(Armorer) && v7->uEquipType >= 3 && v7->uEquipType <= 9 ||
       CheckHiredNPCSpeciality(Alchemist) && v7->uEquipType >= 9 )
     return true;
 
   v2 = GetActualSkillLevel(PLAYER_SKILL_REPAIR);
-  v3 = v2;
-  if (v2 & 0x100 )
-  {
-    v10 = 5;
-  }
-  else
-  {
-    if ( (v2 & 0x80u) == 0 )
-    {
-      v4 = ((v2 & 0x40) != 0) + 1;
-      goto LABEL_7;
-    }
-    v10 = 3;
-  }
-  v4 = v10;
-LABEL_7:
-  v5 = v4 * (v3 & 0x3F);
-  v6 = 0;
-  if ( (signed int)SkillToMastery(v3) >= 4 )
+  if ( (signed int)SkillToMastery(v2) >= 4 )
     return true;
-  if ( v5 >= *((char *)(v7 + 1) + 2) )
-  {
-    __debugbreak(); // really odd
-    return true;
-  }
-  return false;
+
+  int multiplier = GetMultiplierForSkillLevel(v2, 1, 2, 3, 5);
+  v5 = multiplier * (v2 & 0x3F);
+  return v5 >= v7->uItemID_Rep_St;
 }
 
 //----- (004911F3) --------------------------------------------------------
 int Player::GetMerchant()
 {
-  Player *v1; // edi@1
   unsigned __int16 v2; // ax@1
-  unsigned __int16 v3; // bx@1
-  int v4; // esi@1
   int v5; // edi@1
   int v7; // eax@3
-  int v8; // ecx@7
-  signed int v9; // [sp-4h] [bp-10h]@6
-
-  v1 = this;
+
   v2 = GetActualSkillLevel(PLAYER_SKILL_MERCHANT);
-  v3 = v1->pActiveSkills[PLAYER_SKILL_MERCHANT];
-  v4 = v2 & 0x003F;
-  v5 = v1->pActiveSkills[PLAYER_SKILL_MERCHANT] & 0x3F;
-  if ( (signed int)SkillToMastery(v2) >= 4 )
+  if ( SkillToMastery(v2) >= 4 )
     return 10000;
+
   v7 = GetPartyReputation();
-  if ( !v4 )
+  int multiplier = GetMultiplierForSkillLevel(v2, 1, 2, 3, 5);
+  v5 = multiplier * (v2 & 0x3F);
+  if (v5 == 0)
+  {
     return -v7;
-  if ( v3 & 0x100 )
-  {
-    v9 = 5;
-  }
-  else
-  {
-    if ( (v3 & 0x80u) == 0 )
-    {
-      v8 = ((v3 & 0x40) != 0) + 1;
-      return v5 * (v8 - 1) - v7 + v4 + 7;
-    }
-    v9 = 3;
-  }
-  v8 = v9;
-  return v5 * (v8 - 1) - v7 + v4 + 7;
+  }
+  return v5 - v7 + 7;
 }
 
 //----- (0049125A) --------------------------------------------------------
 int Player::GetPerception()
 {
-  Player *v1; // edi@1
   unsigned __int16 v2; // ax@1
-  unsigned __int16 v3; // bx@1
-  int v4; // esi@1
   int v5; // edi@1
-  int v7; // eax@5
-  signed int v8; // [sp-4h] [bp-10h]@4
-
-  v1 = this;
+
   v2 = GetActualSkillLevel(PLAYER_SKILL_PERCEPTION);
-  v3 = v1->pActiveSkills[PLAYER_SKILL_PERCEPTION];
-  v4 = v2 & 0x3F;
-  v5 = v1->pActiveSkills[PLAYER_SKILL_PERCEPTION] & 0x3F;
-  if ( (signed int)SkillToMastery(v2) >= 4 )
+  if ( SkillToMastery(v2) >= 4 )
     return 10000;
-  if ( v3 & 0x100 )
-  {
-    v8 = 5;
-  }
-  else
-  {
-    if ( (v3 & 0x80u) == 0 )
-    {
-      v7 = ((v3 & 0x40) != 0) + 1;
-      return v4 + v5 * (v7 - 1);
-    }
-    v8 = 3;
-  }
-  v7 = v8;
-  return v4 + v5 * (v7 - 1);
+
+  int multiplier = GetMultiplierForSkillLevel(v2, 1, 2, 3, 5);
+  v5 = multiplier * (v2 & 0x3F);
+  return v5;
 }
 
 //----- (004912B0) --------------------------------------------------------
 int Player::GetDisarmTrap()
 {
-  Player *v1; // ebp@1
   unsigned __int16 v2; // ax@1
-  unsigned __int16 v3; // bx@1
-  int v4; // esi@1
   int v5; // edi@1
-  int v7; // eax@7
-  signed int v8; // [sp-4h] [bp-14h]@6
-
-  v1 = this;
+
   v2 = GetActualSkillLevel(PLAYER_SKILL_TRAP_DISARM);
-  v3 = v1->pActiveSkills[29];
-  v4 = v2 & 0x3F;
-  v5 = v1->pActiveSkills[29] & 0x3F;
   if ( (signed int)SkillToMastery(v2) >= 4 )
     return 10000;
-  if ( HasEnchantedItemEquipped(35) )
-    v4 *= 2;
-  if ( v3 & 0x100 )
-  {
-    v8 = 5;
-  }
-  else
-  {
-    if ( (v3 & 0x80u) == 0 )
-    {
-      v7 = ((v3 & 0x40) != 0) + 1;
-      return v4 + v5 * (v7 - 1);
-    }
-    v8 = 3;
-  }
-  v7 = v8;
-  return v4 + v5 * (v7 - 1);
+
+  int multiplier = GetMultiplierForSkillLevel(v2, 1, 2, 3, 5);
+  if ( HasEnchantedItemEquipped(35) )  //only the real skill level is supposed to be added again, not the multiplied value
+    multiplier++;
+  v5 = multiplier * (v2 & 0x3F);
+  return v5;
 }
 
 //----- (00491317) --------------------------------------------------------
 char Player::GetLearningPercent()
 {
-  Player *v1; // esi@1
   int v2; // eax@1
-  unsigned __int16 v3; // bx@1
-  int v4; // ecx@1
-  int v5; // eax@4
-  signed int v7; // [sp-4h] [bp-Ch]@3
-
-  v1 = this;
+
   v2 = GetActualSkillLevel(PLAYER_SKILL_LEARNING);
-  v3 = v1->pActiveSkills[36];
-  v4 = v2 & 0x3F;
-  if ( v2 )
-  {
-    if (v3 & 0x100 )
-    {
-      v7 = 5;
-    }
-    else
-    {
-      if ( (v3 & 0x80u) == 0 )
-      {
-        v5 = ((v3 & 0x40) != 0) + 1;
-        goto LABEL_8;
-      }
-      v7 = 3;
-    }
-    v5 = v7;
-LABEL_8:
-    v2 = (v1->pActiveSkills[36] & 0x3F) * (v5 - 1) + v4 + 9;
-  }
-  return v2;
+  int multiplier = GetMultiplierForSkillLevel(v2, 1, 2, 3, 5);
+  return multiplier * v2 + 9;
 }
 
 //----- (0048C6AF) --------------------------------------------------------
@@ -1544,93 +1349,57 @@
 }
 
 //----- (0048C6F6) --------------------------------------------------------
-bool Party::AddItem(ItemGen *pItem)
+bool Party::AddItemToParty(ItemGen *pItem)      //TODO move to party.cpp
 {
   unsigned int v2; // eax@1
-  unsigned int v3; // ecx@4
-  signed int v4; // edx@4
   char *v5; // eax@8
-  //unsigned int v6; // eax@10
   Texture *v7; // ebx@10
   signed int v8; // esi@10
   Player *v9; // edi@11
   int v10; // eax@11
-  bool result; // eax@15
-  std::string v12; // [sp-18h] [bp-40h]@9
-
-
-  int v15[4] = {0, 1, 2, 3}; // [sp+Ch] [bp-1Ch]@3
-  //int v16; // [sp+10h] [bp-18h]@3
-  //int v17; // [sp+14h] [bp-14h]@3
-  //int v18; // [sp+18h] [bp-10h]@3
-  Player *v19; // [sp+1Ch] [bp-Ch]@9
-  Party *v20; // [sp+20h] [bp-8h]@1
   int v21; // [sp+24h] [bp-4h]@10
 
-  auto thos = this;
-
-  v20 = thos;
   v2 = pItem->uItemID;
   if ( !pItemsTable->pItems[v2].uItemID_Rep_St )
     pItem->SetIdentified();
-  ///v15 = 0;
-  //v16 = 1;
-  //v18 = 3;
-  //v17 = 2;
-  if ( uActiveCharacter )
-  {
-    v3 = uActiveCharacter - 1;
-    v4 = 0;
-    do
-    {
-      v15[v4++] = v3++;
-      if ( (signed int)v3 >= 4 )
-        v3 = 0;
-    }
-    while ( v4 < 4 );
-  }
+
   v5 = pItemsTable->pItems[v2].pIconName;
   if ( v5 )
   {
     v7 = pIcons_LOD->LoadTexturePtr(v5, TEXTURE_16BIT_PALETTE);
     v21 = areWeLoadingTexture;
     v8 = 0;
-    while ( 1 )
-    {
-      v9 = &v20->pPlayers[v15[v8]];
-      v19 = &v20->pPlayers[v15[v8]];
-      v10 = v19->AddItem(-1, pItem->uItemID);
+    int startId = uActiveCharacter >= 0 ? uActiveCharacter - 1 : 0;
+    for (int i = 0; i < 4; i++)
+    {
+      v9 = &pPlayers[(startId + i) % 4];  //start with current active player, then cycle right if item won't fit
+      v10 = v9->AddItem(-1, pItem->uItemID);
       if ( v10 )
-        break;
-      ++v8;
-      if ( v8 >= 4 )
       {
+        memcpy(&v9->pInventoryItemList[v10-1], pItem, 0x24u);
+        pItem->Reset();
+        pAudioPlayer->PlaySound(SOUND_GoldReceived, 0, 0, -1, 0, 0, 0, 0);
+        v9->PlaySound(SPEECH_60, 0);
         if ( !v21 )
         {
           v7->Release();
           pIcons_LOD->SyncLoadedFilesCount();
         }
-        goto LABEL_15;
+        return true;
       }
     }
-    memcpy(&v9->pInventoryItemList[v10-1], pItem, 0x24u);
-    pItem->Reset();
-    pAudioPlayer->PlaySound(SOUND_GoldReceived, 0, 0, -1, 0, 0, 0, 0);
-    v19->PlaySound(SPEECH_60, 0);
     if ( !v21 )
     {
       v7->Release();
       pIcons_LOD->SyncLoadedFilesCount();
     }
-    result = 1;
+    return false;
   }
   else
   {
     MessageBoxW(nullptr, L"Invalid picture_name detected ::addItem()", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Party.cpp:795", 0);
-LABEL_15:
-    result = 0;
-  }
-  return result;
+    return false;
+  }
 }
 // 506128: using guessed type int areWeLoadingTexture;
 
@@ -1693,37 +1462,37 @@
 //----- (0048C93C) --------------------------------------------------------
 int Player::GetActualMight()
 {
-  return GetActualAttribute(CHARACTER_ATTRIBUTE_STRENGTH);
+  return GetActualAttribute(CHARACTER_ATTRIBUTE_STRENGTH, &Player::uMight, &Player::uMightBonus);
 }
 
 //----- (0048C9C2) --------------------------------------------------------
 int Player::GetActualIntelligence()
 {
-  return GetActualAttribute(CHARACTER_ATTRIBUTE_INTELLIGENCE);
+  return GetActualAttribute(CHARACTER_ATTRIBUTE_INTELLIGENCE, &Player::uIntelligence, &Player::uIntelligenceBonus);
 }
 
 //----- (0048CA3F) --------------------------------------------------------
 int Player::GetActualWillpower()
 {
-  return GetActualAttribute(CHARACTER_ATTRIBUTE_WILLPOWER);
+  return GetActualAttribute(CHARACTER_ATTRIBUTE_WILLPOWER, &Player::uWillpower, &Player::uWillpowerBonus);
 }
 
 //----- (0048CABC) --------------------------------------------------------
 int Player::GetActualEndurance()
 {
-  return GetActualAttribute(CHARACTER_ATTRIBUTE_ENDURANCE);
+  return GetActualAttribute(CHARACTER_ATTRIBUTE_ENDURANCE, &Player::uEndurance, &Player::uEnduranceBonus);
 }
 
 //----- (0048CB39) --------------------------------------------------------
 int Player::GetActualAccuracy()
 {
-  return GetActualAttribute(CHARACTER_ATTRIBUTE_ACCURACY);
+  return GetActualAttribute(CHARACTER_ATTRIBUTE_ACCURACY, &Player::uAccuracy, &Player::uAccuracyBonus);
 }
 
 //----- (0048CBB6) --------------------------------------------------------
 int Player::GetActualSpeed()
 {
-  return GetActualAttribute(CHARACTER_ATTRIBUTE_SPEED);
+  return GetActualAttribute(CHARACTER_ATTRIBUTE_SPEED, &Player::uSpeed, &Player::uSpeedBonus);
 }
 
 //----- (0048CC33) --------------------------------------------------------
@@ -1739,49 +1508,13 @@
   if ( CheckHiredNPCSpeciality(Psychic) )
     npc_luck_bonus += 10;
 
-  return GetActualAttribute(CHARACTER_ATTRIBUTE_LUCK)
+  return GetActualAttribute(CHARACTER_ATTRIBUTE_LUCK, &Player::uLuck, &Player::uLuckBonus)
        + npc_luck_bonus;
 }
 
 //----- (new function) --------------------------------------------------------
-int Player::GetActualAttribute( CHARACTER_ATTRIBUTE_TYPE attrId )
-{
-  unsigned __int16 attrValue = 0;
-  unsigned __int16 attrBonus = 0;
-  switch (attrId)
-  {
-  case CHARACTER_ATTRIBUTE_STRENGTH:
-    attrValue = uMight;
-    attrBonus = uMightBonus;
-    break;
-  case CHARACTER_ATTRIBUTE_INTELLIGENCE:
-    attrValue = uIntelligence;
-    attrBonus = uIntelligenceBonus;
-    break;
-  case CHARACTER_ATTRIBUTE_WILLPOWER:
-    attrValue = uWillpower;
-    attrBonus = uWillpowerBonus;
-    break;
-  case CHARACTER_ATTRIBUTE_ENDURANCE:
-    attrValue = uEndurance;
-    attrBonus = uEnduranceBonus;
-    break;
-  case CHARACTER_ATTRIBUTE_ACCURACY:
-    attrValue = uAccuracy;
-    attrBonus = uAccuracyBonus;
-    break;
-  case CHARACTER_ATTRIBUTE_SPEED:
-    attrValue = uSpeed;
-    attrBonus = uSpeedBonus;
-    break;
-  case CHARACTER_ATTRIBUTE_LUCK:
-    attrValue = uLuck;
-    attrBonus = uLuckBonus;
-    break;
-  default:
-    return 0;
-  }
-
+int Player::GetActualAttribute( CHARACTER_ATTRIBUTE_TYPE attrId, unsigned short Player::* attrValue, unsigned short Player::* attrBonus )
+{
   uint uActualAge = this->sAgeModifier + GetBaseAge();
   uint uAgeingMultiplier = 100;
   for (uint i = 0; i < 4; ++i)
@@ -1795,40 +1528,35 @@
   auto uConditionMult = pConditionAttributeModifier[attrId][GetMajorConditionIdx()];
   int magicBonus = GetMagicalBonus(attrId);
   int itemBonus = GetItemsBonus(attrId, 0);
-  return uConditionMult * uAgeingMultiplier * attrValue / 100 / 100
+  return uConditionMult * uAgeingMultiplier * this->*attrValue / 100 / 100
     + magicBonus
-    + magicBonus
-    + attrBonus;
+    + itemBonus
+    + this->*attrBonus;
 }
 
 //----- (0048CCF5) --------------------------------------------------------
 int Player::GetActualAttack(int a2)
 {
-  Player *v2; // esi@1
   int v3; // eax@1
   int v4; // edi@1
   int v5; // ebx@1
   int v6; // ebp@1
 
-  v2 = this;
   v3 = GetActualAccuracy();
   v4 = GetParameterBonus(v3);
   v5 = GetSkillBonus(CHARACTER_ATTRIBUTE_ATTACK);
   v6 = GetItemsBonus(CHARACTER_ATTRIBUTE_ATTACK, a2);
-  return v4 + v5 + v6 + GetMagicalBonus(CHARACTER_ATTRIBUTE_ATTACK) + v2->_some_attack_bonus;
+  return v4 + v5 + v6 + GetMagicalBonus(CHARACTER_ATTRIBUTE_ATTACK) + this->_some_attack_bonus;
 }
 
 //----- (0048CD45) --------------------------------------------------------
 int Player::GetMeleeDamageMinimal()
 {
-  Player *v1; // edi@1
   int v2; // eax@1
   int v3; // esi@1
   int v4; // esi@1
   int v5; // esi@1
-  int v6; // esi@1
   signed int result; // eax@1
-
  
   v2 = GetActualMight();
   v3 = GetParameterBonus(v2);
@@ -1843,7 +1571,6 @@
 //----- (0048CD90) --------------------------------------------------------
 int Player::GetMeleeDamageMaximal()
 {
-  Player *v1; // edi@1
   int v2; // eax@1
   int v3; // esi@1
   int v4; // esi@1
@@ -1851,12 +1578,11 @@
   int v6; // esi@1
   signed int result; // eax@1
 
-  v1 = this;
   v2 = GetActualMight();
   v3 = GetParameterBonus(v2);
   v4 = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MAX, 0) + v3;
   v5 = GetSkillBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS) + v4;
-  v6 = v1->_melee_dmg_bonus + GetMagicalBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS) + v5;
+  v6 = this->_melee_dmg_bonus + GetMagicalBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS) + v5;
   result = 1;
   if ( v6 >= 1 )
     result = v6;
@@ -1864,212 +1590,104 @@
 }
 
 //----- (0048CDDB) --------------------------------------------------------
-int Player::CalculateMeleeDamageTo(int a2, int a3, unsigned int uTargetActorID)
-{
-  int v4; // esi@1
-  Player *v5; // edi@1
-  ItemGen *v6; // ebx@4
-  unsigned int v7; // ebp@4
-  unsigned int v8; // esi@4
-  int v9; // eax@4
-  int v10; // eax@9
-  char v11; // zf@9
-  int v12; // esi@10
-  int v13; // eax@11
-  enum MONSTER_SUPERTYPE v14; // edx@24
-  ItemGen *v15; // ebx@35
-  unsigned int v16; // ebp@35
-  unsigned int v17; // esi@35
-  int v18; // edx@38
-  int v19; // eax@40
-  enum MONSTER_SUPERTYPE v20; // edx@53
-  int v21; // esi@62
-  int v22; // eax@63
-  int v23; // ebx@63
-  int v24; // ebx@63
+int Player::CalculateMeleeDamageTo( bool ignoreSkillBonus, bool ignoreOffhand, unsigned int uTargetActorID )
+{
+  int dmgSum; // esi@62
   signed int result; // eax@64
-  MONSTER_SUPERTYPE v26; // [sp-4h] [bp-24h]@20
-  MONSTER_SUPERTYPE v27; // [sp-4h] [bp-24h]@49
-  int v28; // [sp+10h] [bp-10h]@1
-  int v29; // [sp+10h] [bp-10h]@33
-  signed int v30; // [sp+14h] [bp-Ch]@7
-  signed int v31; // [sp+14h] [bp-Ch]@36
-  int v32; // [sp+18h] [bp-8h]@1
-  int v33; // [sp+18h] [bp-8h]@8
-  int v34; // [sp+1Ch] [bp-4h]@1
-  int v35; // [sp+28h] [bp+8h]@37
-
-  v4 = 0;
-  v5 = this;
-  v34 = 0;
-  v32 = 0;
-  v28 = 0;
-  if ( IsUnarmed() == 1 )
-  {
-    v32 = rand() % 3 + 1;
-LABEL_61:
-    v34 = v4;
-    goto LABEL_62;
-  }
-  if ( HasItemEquipped(EQUIP_MAIN_HAND) )
-  {
-    v6 = (ItemGen *)&v5->pInventoryItemList[v5->pEquipment.uMainHand-1];
-    v7 = v6->uItemID;
-    v8 = v6->uItemID;
-    v9 = pItemsTable->pItems[v8].uDamageDice;
-    if ( pItemsTable->pItems[v8].uSkillType == PLAYER_SKILL_SPEAR && !v5->pEquipment.uShield )
-      ++v9;
-    v30 = pItemsTable->pItems[v8].uDamageRoll;
-    if ( v9 > 0 )
-    {
-      v33 = v9;
-      do
+  int mainWpnDmg; // [sp+18h] [bp-8h]@1
+  int offHndWpnDmg; // [sp+1Ch] [bp-4h]@1
+
+  offHndWpnDmg = 0;
+  mainWpnDmg = 0;
+  if ( IsUnarmed() )
+  {
+    mainWpnDmg = rand() % 3 + 1;
+  }
+  else
+  {
+    if ( HasItemEquipped(EQUIP_MAIN_HAND) )
+    {
+      ItemGen *mainHandItemGen = &this->pInventoryItemList[this->pEquipment.uMainHand-1];
+      int itemId = mainHandItemGen->uItemID;
+      bool addOneDice = false;
+      if ( pItemsTable->pItems[itemId].uSkillType == PLAYER_SKILL_SPEAR && !this->pEquipment.uShield )
+        addOneDice = true;
+      mainWpnDmg = CalculateMeleeDmgToEnemyWithWeapon(mainHandItemGen, uTargetActorID, addOneDice);
+    }
+    if ( !ignoreOffhand )
+    {
+      if ( this->HasItemEquipped(EQUIP_OFF_HAND) )
       {
-        v10 = rand();
-        v11 = v33-- == 1;
-        v28 += v10 % v30 + 1;
-      }
-      while ( !v11 );
-    }
-    v12 = pItemsTable->pItems[v8].uDamageMod + v28;
-    if ( !uTargetActorID )
-      goto LABEL_28;
-    v13 = v6->uSpecEnchantmentType;
-    if ( v13 == 64 || v7 == 507 || v7 == 508 || v7 == 527 )
-    {
-      v14 = (MONSTER_SUPERTYPE)1;
-    }
-    else
-    {
-      if ( v13 == 39 )
-      {
-        v26 = MONSTER_SUPERTYPE_KREEGAN;
-      }
-      else
-      {
-        if ( v13 == 40 )
+        ItemGen *offHandItemGen = (ItemGen *)&this->pInventoryItemList[this->pEquipment.uShield - 1];
+        int itemId = offHandItemGen->uItemID;
+        if ( pItemsTable->pItems[itemId].uEquipType != EQUIP_SHIELD )
         {
-          v26 = MONSTER_SUPERTYPE_DRAGON;
-        }
-        else
-        {
-          if ( v13 == 63 || v7 == 517 )
-          {
-            v26 = MONSTER_SUPERTYPE_ELF;
-          }
-          else
-          {
-            if ( v13 != 65 )
-            {
-LABEL_28:
-              if ( (signed int)SkillToMastery(v5->pActiveSkills[2]) >= 3
-                && pItemsTable->pItems[v6->uItemID].uSkillType == 2
-                && rand() % 100 < 10 )
-                v12 *= 3;
-              v32 = v12;
-              goto LABEL_33;
-            }
-            v26 = MONSTER_SUPERTYPE_TITAN;
-          }
+          offHndWpnDmg = CalculateMeleeDmgToEnemyWithWeapon(offHandItemGen, uTargetActorID, false);
         }
       }
-      v14 = v26;
-    }
-    if ( MonsterStats::BelongsToSupertype(uTargetActorID, v14) )
-      v12 *= 2;
-    goto LABEL_28;
-  }
-LABEL_33:
-  v29 = 0;
-  if ( !a3 )
-  {
-    if ( v5->HasItemEquipped((ITEM_EQUIP_TYPE)0) )
-    {
-      v15 = (ItemGen *)&v5->pInventoryItemList[v5->pEquipment.uShield - 1];
-      v16 = v15->uItemID;
-      v17 = v15->uItemID;
-      if ( pItemsTable->pItems[v17].uEquipType != 4 )
-      {
-        v31 = pItemsTable->pItems[v17].uDamageRoll;
-        if ( (signed int)pItemsTable->pItems[v17].uDamageDice > 0 )
-        {
-          v35 = pItemsTable->pItems[v17].uDamageDice;
-          do
-          {
-            v18 = rand() % v31;
-            v11 = v35-- == 1;
-            v29 += v18 + 1;
-          }
-          while ( !v11 );
-        }
-        v4 = pItemsTable->pItems[v17].uDamageMod + v29;
-        if ( !uTargetActorID )
-          goto LABEL_57;
-        v19 = v15->uSpecEnchantmentType;
-        if ( v19 == 64 || v16 == 507 || v16 == 508 || v16 == 527 )
-        {
-          v20 = (MONSTER_SUPERTYPE)1;
-        }
-        else
-        {
-          if ( v19 == 39 )
-          {
-            v27 = MONSTER_SUPERTYPE_KREEGAN;
-          }
-          else
-          {
-            if ( v19 == 40 )
-            {
-              v27 = MONSTER_SUPERTYPE_DRAGON;
-            }
-            else
-            {
-              if ( v19 == 63 || v16 == 517 )
-              {
-                v27 = MONSTER_SUPERTYPE_ELF;
-              }
-              else
-              {
-                if ( v19 != 65 )
-                {
-LABEL_57:
-                  if ( pItemsTable->pItems[v15->uItemID].uSkillType == PLAYER_SKILL_DAGGER
-                    && SkillToMastery(v5->pActiveSkills[2] >= 3u)
-                    && rand() % 100 < 10 )
-                    v4 *= 3;
-                  goto LABEL_61;
-                }
-                v27 = MONSTER_SUPERTYPE_TITAN;
-              }
-            }
-          }
-          v20 = v27;
-        }
-        if ( MonsterStats::BelongsToSupertype(uTargetActorID, v20) )
-          v4 *= 2;
-        goto LABEL_57;
-      }
-    }
-  }
-LABEL_62:
-  v21 = v32 + v34;
-  if ( !a2 )
-  {
-    v22 = GetActualMight();
-    v23 = GetParameterBonus(v22);
-    v24 = GetSkillBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS) + v23;
-    v21 += v5->_melee_dmg_bonus + GetMagicalBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS) + v24;
+    }
+  }
+  dmgSum = mainWpnDmg + offHndWpnDmg;
+  if ( !ignoreSkillBonus )
+  {
+    int might = GetActualMight();
+    int mightBonus = GetParameterBonus(might);
+    int mightAndSkillbonus = GetSkillBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS) + mightBonus;
+    dmgSum += this->_melee_dmg_bonus + GetMagicalBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS) + mightAndSkillbonus;
   }
   result = 1;
-  if ( v21 >= 1 )
-    result = v21;
+  if ( dmgSum >= 1 )
+    result = dmgSum;
   return result;
 }
 
+
+int Player::CalculateMeleeDmgToEnemyWithWeapon( ItemGen * weapon, unsigned int uTargetActorID , bool addOneDice )
+{
+  int itemId = weapon->uItemID;
+  int diceCount = pItemsTable->pItems[itemId].uDamageDice;
+  if (addOneDice)
+  {
+    diceCount++;
+  }
+  int diceSides = pItemsTable->pItems[itemId].uDamageRoll;
+  int diceResult = 0;
+  for (int i = 0; i < diceCount; i++)
+  {
+    diceResult += rand() % diceSides + 1;
+  }
+  int totalDmg = pItemsTable->pItems[itemId].uDamageMod + diceResult;
+  if ( uTargetActorID > 0)
+  {
+    int enchType = weapon->uSpecEnchantmentType;
+    if ( MonsterStats::BelongsToSupertype(uTargetActorID, MONSTER_SUPERTYPE_UNDEAD) && (enchType == 64 || itemId == ITEM_ARTIFACT_GHOULSBANE || itemId == ITEM_ARTIFACT_GIBBET || itemId == ITEM_RELIC_JUSTICE) )
+    {
+      totalDmg *= 2;
+    }
+    else if (MonsterStats::BelongsToSupertype(uTargetActorID, MONSTER_SUPERTYPE_KREEGAN) && ( enchType == 39 || itemId == ITEM_ARTIFACT_GIBBET))
+    {
+      totalDmg *= 2;
+    }
+    else if (MonsterStats::BelongsToSupertype(uTargetActorID, MONSTER_SUPERTYPE_DRAGON) && ( enchType == 40 || itemId == ITEM_ARTIFACT_GIBBET))
+    {
+      totalDmg *= 2;
+    }
+    else if (MonsterStats::BelongsToSupertype(uTargetActorID, MONSTER_SUPERTYPE_TITAN) && ( enchType == 65 ))
+    {
+      totalDmg *= 2;
+    }
+  }
+  if ( (signed int)SkillToMastery(this->pActiveSkills[2]) >= 3
+    && pItemsTable->pItems[itemId].uSkillType == 2
+    && rand() % 100 < 10 )
+    totalDmg *= 3;
+  return totalDmg;
+}
+
+
 //----- (0048D0B9) --------------------------------------------------------
 int Player::GetRangedAttack()
 {
-  Player *v1; // esi@1
   int v2; // eax@1
   int v3; // edi@3
   int v4; // eax@4
@@ -2077,15 +1695,14 @@
   int v6; // edi@4
   int v7; // edi@4
 
-  v1 = this;
   v2 = *(int *)&this->pInventoryItemList[this->pEquipment.uMainHand-1];
-  if ( v2 < 64 || v2 > 65 )
+  if ( v2 < ITEM_BLASTER || v2 > ITEM_LASER_RIFLE )
   {
     v4 = GetActualAccuracy();
     v5 = GetParameterBonus(v4);
     v6 = GetItemsBonus(CHARACTER_ATTRIBUTE_RANGED_ATTACK, 0) + v5;
     v7 = GetSkillBonus(CHARACTER_ATTRIBUTE_RANGED_ATTACK) + v6;
-    v3 = v1->_ranged_atk_bonus + GetMagicalBonus(CHARACTER_ATTRIBUTE_RANGED_ATTACK) + v7;
+    v3 = this->_ranged_atk_bonus + GetMagicalBonus(CHARACTER_ATTRIBUTE_RANGED_ATTACK) + v7;
   }
   else
   {
@@ -2097,20 +1714,14 @@
 //----- (0048D124) --------------------------------------------------------
 int Player::GetRangedDamageMin()
 {
-  Player *v1; // esi@1
   int v2; // edi@1
   int v3; // edi@1
   int v4; // edi@1
-  unsigned __int16 v5; // ax@1
   int result; // eax@6
 
-  v1 = this;
   v2 = GetItemsBonus(CHARACTER_ATTRIBUTE_RANGED_DMG_MIN, 0);
   v3 = GetSkillBonus(CHARACTER_ATTRIBUTE_RANGED_DMG_BONUS) + v2;
-  v4 = v1->_ranged_dmg_bonus + GetMagicalBonus(CHARACTER_ATTRIBUTE_RANGED_DMG_BONUS) + v3;
-  v5 = v1->pActiveSkills[5];
-  if ( v5 && (signed int)SkillToMastery(v5) >= 4 && HasItemEquipped(EQUIP_BOW) )
-    v4 += v1->pActiveSkills[5] & 0x3F;
+  v4 = this->_ranged_dmg_bonus + GetMagicalBonus(CHARACTER_ATTRIBUTE_RANGED_DMG_BONUS) + v3;
   if ( v4 >= 1 )
     result = v4;
   else
@@ -2121,20 +1732,14 @@
 //----- (0048D191) --------------------------------------------------------
 int Player::GetRangedDamageMax()
 {
-  Player *v1; // esi@1
   int v2; // edi@1
   int v3; // edi@1
   int v4; // edi@1
-  unsigned __int16 v5; // ax@1
   int result; // eax@6
 
-  v1 = this;
   v2 = GetItemsBonus(CHARACTER_ATTRIBUTE_RANGED_DMG_MAX, 0);
   v3 = GetSkillBonus(CHARACTER_ATTRIBUTE_RANGED_DMG_BONUS) + v2;
-  v4 = v1->_ranged_dmg_bonus + GetMagicalBonus(CHARACTER_ATTRIBUTE_RANGED_DMG_BONUS) + v3;
-  v5 = v1->pActiveSkills[5];
-  if ( v5 && (signed int)SkillToMastery(v5) >= 4 && HasItemEquipped(EQUIP_BOW) )
-    v4 += v1->pActiveSkills[5] & 0x3F;
+  v4 = this->_ranged_dmg_bonus + GetMagicalBonus(CHARACTER_ATTRIBUTE_RANGED_DMG_BONUS) + v3;
   if ( v4 >= 1 )
     result = v4;
   else
@@ -2143,276 +1748,209 @@
 }
 
 //----- (0048D1FE) --------------------------------------------------------
-bool Player::CalculateRangedDamageTo(int a2)
-{
-  Player *v2; // ebx@1
-  bool result; // eax@1
+int Player::CalculateRangedDamageTo( int a2 )
+{
   ItemGen *v4; // ebx@2
   unsigned int v5; // edi@2
-  unsigned int v6; // esi@2
-  int v7; // edx@4
-  char v8; // zf@4
   int v9; // esi@5
   int v10; // ebx@6
-  enum MONSTER_SUPERTYPE v11; // edx@7
-  unsigned __int16 v12; // ax@19
-  MONSTER_SUPERTYPE v13; // [sp-Ch] [bp-20h]@13
-  Player *v14; // [sp+4h] [bp-10h]@1
   signed int v15; // [sp+8h] [bp-Ch]@2
-  int v16; // [sp+Ch] [bp-8h]@3
   int v17; // [sp+10h] [bp-4h]@1
 
   v17 = 0;
-  v2 = this;
-  v14 = this;
-  result = HasItemEquipped(EQUIP_BOW);
-  if ( !result )
-    return result;
-  v4 = (ItemGen *)&v2->pInventoryItemList[v2->pEquipment.uBow-1];
+  if ( !HasItemEquipped(EQUIP_BOW) )
+    return 0;
+  v4 = (ItemGen *)&this->pInventoryItemList[this->pEquipment.uBow-1];
   v5 = v4->uItemID;
-  v6 = v4->uItemID;
-  v15 = pItemsTable->pItems[v6].uDamageRoll;
-  if ( (signed int)pItemsTable->pItems[v6].uDamageDice > 0 )
-  {
-    v16 = pItemsTable->pItems[v6].uDamageDice;
-    do
-    {
-      v7 = rand() % v15;
-      v8 = v16-- == 1;
-      v17 += v7 + 1;
-    }
-    while ( !v8 );
-  }
-  v9 = pItemsTable->pItems[v6].uDamageMod + v17;
+  v15 = pItemsTable->pItems[v5].uDamageRoll;
+  for( int i = 0; i < pItemsTable->pItems[v5].uDamageDice; i++ )
+  {
+    int v7 = rand() % v15;
+    v17 += v7 + 1;
+  }
+  v9 = pItemsTable->pItems[v5].uDamageMod + v17;
   if ( a2 )
   {
     v10 = v4->uSpecEnchantmentType;
-    if ( v10 == 64 )
-    {
-      v11 = (MONSTER_SUPERTYPE)1;
-      goto LABEL_17;
-    }
-    if ( v10 == 39 || v5 == 508 )
-    {
-      v13 = MONSTER_SUPERTYPE_KREEGAN;
-      goto LABEL_16;
-    }
-    if ( v10 == 40 )
-    {
-      v13 = MONSTER_SUPERTYPE_DRAGON;
-      goto LABEL_16;
-    }
-    if ( v10 == 63 || v5 == 517 )
-    {
-      v13 = MONSTER_SUPERTYPE_ELF;
-LABEL_16:
-      v11 = v13;
-LABEL_17:
-      if ( MonsterStats::BelongsToSupertype(a2, v11) )
-        v9 *= 2;
-      goto LABEL_19;
-    }
-  }
-LABEL_19:
-  v12 = v14->pActiveSkills[5];
-  if ( v12 )
-  {
-    if ( (signed int)SkillToMastery(v12) >= 4 )
-      v9 += v14->pActiveSkills[5] & 0x3F;
-  }
-  return v9;
+    if ( v10 == 64 && MonsterStats::BelongsToSupertype(a2, MONSTER_SUPERTYPE_UNDEAD))
+    {
+      v9 *= 2;
+    }
+    else if ( v10 == 39 && MonsterStats::BelongsToSupertype(a2, MONSTER_SUPERTYPE_KREEGAN))
+    {
+      v9 *= 2;
+    }
+    else if ( v10 == 40 && MonsterStats::BelongsToSupertype(a2, MONSTER_SUPERTYPE_DRAGON))
+    {
+      v9 *= 2;
+    }
+    else if ( v10 == 63 && MonsterStats::BelongsToSupertype(a2, MONSTER_SUPERTYPE_ELF))
+    {
+      v9 *= 2;
+    }
+  }
+  return v9 + this->GetSkillBonus(CHARACTER_ATTRIBUTE_RANGED_DMG_BONUS);
 }
 
 //----- (0048D2EA) --------------------------------------------------------
 char *Player::GetMeleeDamageString()
 {
-signed int itemid; // eax@1
-int min_damage; // edi@3
-int max_damage; // eax@3
+  signed int itemid; // eax@1
+  int min_damage; // edi@3
+  int max_damage; // eax@3
 
   static char player__getmeleedamagestring_static_buff[40]; // idb
 
-  if ( pEquipment.uMainHand)
-      {
-      itemid= pOwnItems[this->pEquipment.uMainHand-1].uItemID;
-      if ( itemid < 64 || itemid > 65 ) //blasters
-          {
-          min_damage = GetMeleeDamageMinimal();
-          max_damage = GetMeleeDamageMaximal();
-          }
-      else
-          {  //for blasters
-          min_damage = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MIN, 0);
-          max_damage = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MAX, 0);
-          }
-      if ( max_damage )
-          {
-          if ( min_damage == max_damage )
-              {
-              sprintf(player__getmeleedamagestring_static_buff, "%d", min_damage);
-              }
-          else
-              {
-              sprintf(player__getmeleedamagestring_static_buff, "%d - %d", min_damage, max_damage);
-              }
-          }
-      else
-          {
-          strcpy(player__getmeleedamagestring_static_buff, "N/A");
-          }
-
-      if (( itemid >= 135 )&&( itemid <= 159 )) //wands
-          {
-          strcpy(player__getmeleedamagestring_static_buff, pGlobalTXT_LocalizationStrings[595]); //"Wand"
-          }
-      }
+  if (pEquipment.uMainHand >= 0)
+  {
+    itemid = pOwnItems[this->pEquipment.uMainHand-1].uItemID;
+  }
+
+  if (pEquipment.uMainHand >= 0 && ( itemid >= 135 ) && ( itemid <= 159 ))
+  {
+    strcpy(player__getmeleedamagestring_static_buff, pGlobalTXT_LocalizationStrings[595]); //"Wand"
+    return player__getmeleedamagestring_static_buff;
+  }
+  else if (pEquipment.uMainHand >= 0 && (itemid == ITEM_BLASTER || itemid == ITEM_LASER_RIFLE))
+  {
+    min_damage = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MIN, 1);
+    max_damage = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MAX, 1);
+  }
   else
-      strcpy(player__getmeleedamagestring_static_buff, "N/A");
+  {
+    min_damage = GetMeleeDamageMinimal();
+    max_damage = GetMeleeDamageMaximal();
+  }
+  if ( min_damage == max_damage )
+  {
+    sprintf(player__getmeleedamagestring_static_buff, "%d", min_damage);
+  }
+  else
+  {
+    sprintf(player__getmeleedamagestring_static_buff, "%d - %d", min_damage, max_damage);
+  }
   return player__getmeleedamagestring_static_buff;
 }
 
 //----- (0048D396) --------------------------------------------------------
 char *Player::GetRangedDamageString()
-    {
+{
     signed int itemid; // eax@1
     int min_damage; // edi@3
     int max_damage; // eax@3
 
     static char player__getrangeddamagestring_static_buff[40]; // idb
-    if ( pEquipment.uMainHand)
-        {
-        itemid= pOwnItems[this->pEquipment.uMainHand-1].uItemID;
-        if ( itemid < 64 || itemid > 65 ) //blasters
-            {
-            min_damage = GetRangedDamageMin();
-            max_damage = GetRangedDamageMax();
-            }
-        else
-            {  //for blasters
-            min_damage = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MIN, 1);
-            max_damage = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MAX, 1);
-            }
-        if ( max_damage )
-            {
-            if ( min_damage == max_damage )
-                {
-                sprintf(player__getrangeddamagestring_static_buff, "%d", min_damage);
-                }
-            else
-                {
-                sprintf(player__getrangeddamagestring_static_buff, "%d - %d", min_damage, max_damage);
-                }
-            }
-        else
-            {
-            strcpy(player__getrangeddamagestring_static_buff, "N/A");
-            }
-
-        if (( itemid >= 135 )&&( itemid <= 159 )) //wands
-            {
-            strcpy(player__getrangeddamagestring_static_buff, pGlobalTXT_LocalizationStrings[595]); //"Wand"
-            }
-        }
+
+    if (pEquipment.uMainHand >= 0)
+    {
+      itemid = pOwnItems[this->pEquipment.uMainHand-1].uItemID;
+    }
+
+    if (pEquipment.uMainHand >= 0 && ( itemid >= 135 ) && ( itemid <= 159 ))
+    {
+      strcpy(player__getrangeddamagestring_static_buff, pGlobalTXT_LocalizationStrings[595]); //"Wand"
+      return player__getrangeddamagestring_static_buff;
+    }
+    else if (pEquipment.uMainHand >= 0 && (itemid == ITEM_BLASTER || itemid == ITEM_LASER_RIFLE))
+    {
+      min_damage = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MIN, 1);
+      max_damage = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MAX, 1);
+    }
     else
-        strcpy(player__getrangeddamagestring_static_buff, "N/A");
+    {
+      min_damage = GetRangedDamageMin();
+      max_damage = GetRangedDamageMax();
+    }
+    if ( max_damage > 0)
+    {
+      if ( min_damage == max_damage )
+      {
+        sprintf(player__getrangeddamagestring_static_buff, "%d", min_damage);
+      }
+      else
+      {
+        sprintf(player__getrangeddamagestring_static_buff, "%d - %d", min_damage, max_damage);
+      }
+    }
+    else
+    {
+      strcpy(player__getrangeddamagestring_static_buff, "N/A");
+    }
     return player__getrangeddamagestring_static_buff;
-    }
+}
 
 //----- (0048D45A) --------------------------------------------------------
 bool Player::CanTrainToNextLevel()
 {
-  int v1; // edx@1
-  int v2; // eax@1
-  int i; // esi@1
-
-  v1 = this->uLevel;
-  v2 = 0;
-  for ( i = 0; i < v1; ++i )
-    v2 += i + 1;
-  return (signed __int64)this->uExperience >= 1000 * v2;
+  int lvl = this->uLevel + 1;
+  int neededExp = ((lvl * (lvl - 1)) / 2 * 1000);
+  return this->uExperience >= neededExp;
 }
 
 //----- (0048D498) --------------------------------------------------------
 unsigned int Player::GetExperienceDisplayColor()
 {
-  unsigned int result; // eax@2
-
   if ( CanTrainToNextLevel() )
-    result = ui_character_bonus_text_color;
+    return ui_character_bonus_text_color;
   else
-    result = ui_character_default_text_color;
-  return result;
+    return ui_character_default_text_color;
 }
 
 //----- (0048D4B3) --------------------------------------------------------
-int Player::CalculateIncommingDamage( DAMAGE_TYPE dmg_type, int amount )
-    {
-
+int Player::CalculateIncommingDamage( DAMAGE_TYPE dmg_type, int dmg )
+{
   int resist_value; // edi@8
   int player_luck; // eax@21
   signed int res_rand_divider; // ebx@2
   int armor_skill; // eax@29
-  enum CHARACTER_ATTRIBUTE_TYPE player_resist; // [sp-4h] [bp-10h]@9
-  signed int result_amount_dmg; // [sp+8h] [bp-4h]@17
-
-  player_resist=CHARACTER_ATTRIBUTE_STRENGTH;
+
+  if ( classType == PLAYER_CLASS_LICH && (dmg_type == CHARACTER_ATTRIBUTE_RESIST_MIND || dmg_type == CHARACTER_ATTRIBUTE_RESIST_BODY || dmg_type == CHARACTER_ATTRIBUTE_RESIST_SPIRIT )) //TODO: determine if spirit resistance should be handled by body res. modifier
+    return 0;
+
+  resist_value = 0;
   switch(dmg_type)
       {
-      case DMGT_FIRE:   player_resist=CHARACTER_ATTRIBUTE_RESIST_FIRE; break;
-      case DMGT_ELECTR: player_resist=CHARACTER_ATTRIBUTE_RESIST_AIR;  break;
-      case DMGT_COLD:   player_resist=CHARACTER_ATTRIBUTE_RESIST_WATER; break;
-      case DMGT_3: player_resist=CHARACTER_ATTRIBUTE_RESIST_EARTH; break;
+      case DMGT_FIRE:   resist_value = GetActualResistance(CHARACTER_ATTRIBUTE_RESIST_FIRE); break;
+      case DMGT_ELECTR: resist_value = GetActualResistance(CHARACTER_ATTRIBUTE_RESIST_AIR);  break;
+      case DMGT_COLD:   resist_value = GetActualResistance(CHARACTER_ATTRIBUTE_RESIST_WATER); break;
+      case DMGT_EARTH:  resist_value = GetActualResistance(CHARACTER_ATTRIBUTE_RESIST_EARTH); break;
       
-      case DMGT_SPIRIT: player_resist=CHARACTER_ATTRIBUTE_RESIST_SPIRIT;break;
-      case DMGT_MIND: player_resist=CHARACTER_ATTRIBUTE_RESIST_MIND; break;
-      case DMGT_BODY: player_resist=CHARACTER_ATTRIBUTE_RESIST_BODY; break;
+      case DMGT_SPIRIT: resist_value = GetActualResistance(CHARACTER_ATTRIBUTE_RESIST_SPIRIT);break;
+      case DMGT_MIND:   resist_value = GetActualResistance(CHARACTER_ATTRIBUTE_RESIST_MIND); break;
+      case DMGT_BODY:   resist_value = GetActualResistance(CHARACTER_ATTRIBUTE_RESIST_BODY); break;
       }
-  if (player_resist)
-    resist_value = GetActualResistance(player_resist);
-  else
-    resist_value = 0;
-
-  result_amount_dmg = amount;
-  if ( classType == PLAYER_CLASS_LICH && resist_value >= 200 )
-    return 0;
+
   player_luck = GetActualLuck();
   res_rand_divider = GetParameterBonus(player_luck) + resist_value + 30;
 
-  if ( resist_value )
+  if ( GetParameterBonus(player_luck) + resist_value > 0 )
   { 
-    if ( rand() % res_rand_divider >= 30 )
-    {
-      result_amount_dmg = amount >> 1;
+    for (int i = 0; i < 4; i++)
+    {
       if ( rand() % res_rand_divider >= 30 )
-      {
-        result_amount_dmg = amount >> 2;
-        if ( rand() % res_rand_divider >= 30 )
-        {
-          result_amount_dmg = amount >> 3;
-          if ( rand() % res_rand_divider >= 30 )
-            result_amount_dmg = amount >> 4;
-        }
-      }
-    }
-  }
-  if (( dmg_type == DMGT_PHISYCAL )&&( pEquipment.uArmor ))
-  {
-      if (!pOwnItems[pEquipment.uArmor-1].Broken()) 
+        dmg >>= 1;
+      else
+        break;
+    }
+  }
+  if (( dmg_type == DMGT_PHISYCAL ) && ( pEquipment.uArmor ))
+  {
+      if (!pOwnItems[pEquipment.uArmor - 1].IsBroken()) 
       {
         armor_skill = GetEquippedItemSkillType(EQUIP_ARMOUR);
         if ( armor_skill==PLAYER_SKILL_PLATE )
         {
           if ( SkillToMastery(pActiveSkills[PLAYER_SKILL_PLATE]) >= 3 )
-              return (int)(double)result_amount_dmg * 0.5;
+              return dmg / 2;
         }
         if (armor_skill==PLAYER_SKILL_CHAIN )
         {
           if (SkillToMastery(pActiveSkills[PLAYER_SKILL_CHAIN]) == 4) 
-             return (int)(double)result_amount_dmg * 0.66670001;
+             return dmg * 2 / 3;
         }
       }
   }
-  return result_amount_dmg;
+  return dmg;
 }
 
 //----- (0048D62C) --------------------------------------------------------
@@ -2430,8 +1968,8 @@
 //----- (0048D676) --------------------------------------------------------
 bool Player::IsUnarmed()
 {
-  return HasItemEquipped(EQUIP_MAIN_HAND) != 0 &&
-        !(HasItemEquipped(EQUIP_OFF_HAND) == 0 && GetEquippedItemEquipType(EQUIP_OFF_HAND) != EQUIP_SHIELD);
+  return !HasItemEquipped(EQUIP_MAIN_HAND) &&
+        (!HasItemEquipped(EQUIP_OFF_HAND) || GetEquippedItemEquipType(EQUIP_OFF_HAND) == EQUIP_SHIELD);
 }
 
 //----- (0048D6AA) --------------------------------------------------------
@@ -2439,7 +1977,7 @@
 {
   auto i = pEquipment.pIndices[uEquipIndex];
   if (i)
-    return ~(pOwnItems[i - 1].uAttributes & ITEM_BROKEN);
+    return (~(pOwnItems[i - 1].uAttributes & ITEM_BROKEN)) != 0;
   else 
     return false;
 }
@@ -2451,7 +1989,6 @@
   {
     if (HasItemEquipped((ITEM_EQUIP_TYPE)i) &&
       pOwnItems[pEquipment.pIndices[i]-1].uSpecEnchantmentType == uEnchantment)
-      //  *(int *)&this->field_1F6[36 * pEquipment[i] + 6] != uEnchantment)
       return true;
   }
   return false;
@@ -2459,39 +1996,34 @@
 
 //----- (0048D709) --------------------------------------------------------
 bool Player::WearsItem( int item_id, ITEM_EQUIP_TYPE equip_type )
-    {
-
-  int v6; // esi@5
-
-  if ( equip_type >= 16 )
-  {
-    v6 = 0;
-    while ( !HasItemEquipped((ITEM_EQUIP_TYPE)v6)
-         || pInventoryItemList[pEquipment.pIndices[v6] - 1].uItemID != item_id )
-    {
-      ++v6;
-      if ( (signed int)v6 >= 16 )
-        return 0;
-    }
-    return 1;
-  }
-  if ( HasItemEquipped(equip_type) && pInventoryItemList[pEquipment.pIndices[equip_type - 1]].uItemID == item_id )
-    return 1;
-  return 0;
+{
+  return ( HasItemEquipped(equip_type) && pInventoryItemList[pEquipment.pIndices[equip_type - 1]].uItemID == item_id );
+}
+
+bool Player::WearsItemAnyWhere(int item_id)
+{
+  for (int i = 0; i < 16; i++)
+  {
+    if (WearsItem(item_id, (ITEM_EQUIP_TYPE) i))
+    {
+      return true;
+    }
+  }
+  return false;
 }
 
 //----- (0048D76C) --------------------------------------------------------
-bool Player::StealFromShop(ItemGen *a2, int a3, int a4, int a5, int *a6)
+bool Player::StealFromShop(ItemGen *itemToSteal, int a3, int reputation, int a5, int *a6)   //check stealing in IDA pro once I get home. The whole thing looks odd, dword_4EDEB4 and dword_4EDEA0 are never filled, might be a bug, might me on purpose
 {
   unsigned __int16 v6; // cx@8
   int v7; // edi@8
   unsigned int v8; // ebx@8
-  unsigned int v9; // esi@8
+  unsigned int itemvalue; // esi@8
   int v10; // eax@8
   int v11; // edi@12
   bool result; // eax@13
 
-  if ( !a2
+  if ( !itemToSteal
     || this->pConditions[16]
     || this->pConditions[14]
     || this->pConditions[15]
@@ -2506,12 +2038,12 @@
     v6 = this->pActiveSkills[34];
     v7 = v6 & 0x3F;
     v8 = SkillToMastery(v6);
-    v9 = a2->GetValue();
-    v10 = pItemsTable->pItems[a2->uItemID].uEquipType;
-    if ( !pItemsTable->pItems[a2->uItemID].uEquipType || v10 == 1 || v10 == 2 )
-      v9 *= 3;
+    itemvalue = itemToSteal->GetValue();
+    v10 = pItemsTable->pItems[itemToSteal->uItemID].uEquipType;
+    if ( !pItemsTable->pItems[itemToSteal->uItemID].uEquipType || v10 == 1 || v10 == 2 )
+      itemvalue *= 3;
     v11 = dword_4EDEB4[rand() % 100 / 20] + v7 * dword_4EDEA0[v8];
-    *a6 = 100 * (a4 + a3) + v9 + (a5 != 0 ? 0x1F4 : 0);
+    *a6 = 100 * (reputation + a3) + itemvalue + (a5 != 0 ? 0x1F4 : 0);
     if ( rand() % 100 >= 5 )
     {
       if ( *a6 > v11 )
@@ -2698,19 +2230,19 @@
 {
   signed int max_health; // eax@3
 
-  if ( !pConditions[Condition_Eradicated] && !pConditions[Condition_Dead] )
+  if ( !IsEradicated() && !IsDead() )
   {
     max_health = GetMaxHealth();
-    if ( pConditions[Condition_Zombie] )
+    if ( IsZombie() )
       max_health /= 2;
     sHealth += amount;
     if ( sHealth > max_health )
         sHealth = max_health;
-    if ( pConditions[Condition_Unconcious] )
+    if ( IsUnconcious() )
     {
       if ( sHealth > 0 )
       {
-        pConditions[Condition_Unconcious] = 0i64;
+        SetUnconcious(false);
       }
     }
   }
@@ -2723,21 +2255,20 @@
   unsigned int armor_indx; // eax@8
   bool broke_armor;
  
-  pConditions[Condition_Sleep] = 0i64;
+  SetAsleep(false);
   recieved_dmg = CalculateIncommingDamage(dmg_type, amount);
   sHealth -= recieved_dmg;
   broke_armor = sHealth <= -10;
   if ( sHealth < 1 ) //
   {
     if ( (sHealth + uEndurance + GetItemsBonus(CHARACTER_ATTRIBUTE_ENDURANCE, 0) >= 1)
-      || pPlayerBuffs[PLAYER_BUFF_PRESERVATION].uExpireTime > 0i64 )
-    {
-      SetCondition(Condition_Unconcious, 0);
+      || pPlayerBuffs[PLAYER_BUFF_PRESERVATION].uExpireTime > 0 )
+    {
+      SetCondUnconsciousWithBlockCheck(false);
     }
     else
     {
-      SetCondition(Condition_Dead, 0);
-      //v6 = LODWORD(pParty->uTimePlayed); ???? if equals 0 do not broke armor?
+      SetCondDeadWithBlockCheck(false);
       if ( sHealth > 0 )
         sHealth = 0;
     }
@@ -2746,9 +2277,9 @@
       armor_indx = pEquipment.uArmor;
       if ( armor_indx )
       {
-        if ( !pOwnItems[armor_indx-1].uAttributes & ITEM_ENCHANTED)
+        if ( !(pOwnItems[armor_indx-1].uAttributes & ITEM_ENCHANTED))
         {
-          pOwnItems[armor_indx-1].uAttributes|=ITEM_BROKEN;
+          pOwnItems[armor_indx-1].SetBroken();
         }
       }
     }
@@ -2759,7 +2290,7 @@
 }
 
 //----- (0048DCF6) --------------------------------------------------------
-int Player::_48DCF6(int a2, Actor *pActor)
+int Player::_48DCF6(int a2, Actor *pActor)  //TODO check this with IDA to see what the uninitialized vars are supposed to contain
 {
   signed int v3; // edi@1
   signed int v4; // ebx@1
@@ -2855,7 +2386,7 @@
       v13 = this->pInventoryItemList;
       do
       {
-        if ( (signed int)v13->uItemID > 0 && (signed int)v13->uItemID <= 134 && !v13->Broken())
+        if ( (signed int)v13->uItemID > 0 && (signed int)v13->uItemID <= 134 && !v13->IsBroken())
           v46[v4++] = v12;
         ++v12;
         ++v13;
@@ -3205,7 +2736,7 @@
     }
     else
     {
-      assert(false && "Unknown armour type"); // what kind of armour is that?
+      Error("Unknown armour type"); // what kind of armour is that?
       armour_recovery_multipliers[0] = 1.0f;
       armour_recovery_multipliers[1] = 1.0f;
       armour_recovery_multipliers[2] = 1.0f;
@@ -3599,7 +3130,7 @@
 //----- (0048E96A) --------------------------------------------------------
 void Player::SetRecoveryTime(signed int rec)
 {
-  assert(rec >= 0);
+  Assert(rec >= 0);
 
   if (rec > uTimeToRecovery)
     uTimeToRecovery = rec;
@@ -4803,455 +4334,252 @@
   return result;
 }
 
+
 //----- (0048FC00) --------------------------------------------------------
-int Player::GetSkillBonus(enum CHARACTER_ATTRIBUTE_TYPE a2)
-{
- 
-
-
-  Player *v2; // esi@1
-  int armmaster_skill; // eax@1
-  char v4; // di@1
-  signed int v5; // ebx@1
-  unsigned int armaster_mastery; // eax@2
-  unsigned __int8 v7; // sf@5
-  unsigned __int8 v8; // of@5
-  PlayerEquipment *v9; // ebx@19
-  Player *v10; // ecx@20
-  PLAYER_SKILL_TYPE v11; // edi@21
-  int v12; // eax@21
-  int v13; // edi@21
-  char v14; // di@25
-  signed int v15; // esi@25
-  char v16; // al@32
-  int v18; // eax@36
-  unsigned int v19; // eax@37
-  ITEM_EQUIP_TYPE v20; // edi@40
-  int v21; // edx@41
-  int v22; // eax@42
-  PLAYER_SKILL_TYPE v23; // edi@45
-  unsigned __int16 v24; // ax@45
-  unsigned __int16 v25; // bx@45
-  unsigned int v26; // eax@45
-  unsigned __int8 v27; // sf@50
-  unsigned __int8 v28; // of@50
-  unsigned int v29; // eax@52
-  int v30; // eax@55
-  int v31; // eax@58
-  unsigned int v32; // eax@59
-  int v33; // eax@65
-  char v34; // si@65
-  ITEM_EQUIP_TYPE v35; // edi@69
-  int v36; // edx@70
-  int v37; // eax@71
-  PLAYER_SKILL_TYPE v38; // edi@74
-  int v39; // eax@74
-  int v40; // eax@89
-  char v41; // si@89
-  int v42; // eax@96
-  PLAYER_SKILL_TYPE v43; // edx@97
-  int v44; // eax@97
-  int v45; // eax@98
-  int v46; // eax@99
-  int v47; // eax@100
-  int v48; // eax@101
-  int v49; // eax@102
-  unsigned __int16 v50; // ax@113
-  char v51; // di@113
-  unsigned int v52; // eax@113
-  int v53; // edi@113
-  signed int i; // ecx@113
-  unsigned __int16 v55; // ax@118
-  char v56; // si@118
-  unsigned int v57; // eax@118
-  int v58; // esi@121
-  signed int j; // ecx@121
-  int base_value; // edi@126
-  int attrib_modif; // eax@126
-  signed int v62; // [sp-4h] [bp-30h]@26
-  signed int v63; // [sp-4h] [bp-30h]@80
-  int v64; // [sp+Ch] [bp-20h]@104
-  int v65; // [sp+10h] [bp-1Ch]@104
-  int v66; // [sp+14h] [bp-18h]@104
-  int v67; // [sp+18h] [bp-14h]@104
-  int v68; // [sp+1Ch] [bp-10h]@69
-  PlayerEquipment *v69; // [sp+20h] [bp-Ch]@1
-  int skill_bonus; // [sp+24h] [bp-8h]@1
-  ITEM_EQUIP_TYPE v71; // [sp+28h] [bp-4h]@1
-  int a1; // [sp+34h] [bp+8h]@21
-  int a1a; // [sp+34h] [bp+8h]@74
-  signed int a1b; // [sp+34h] [bp+8h]@94
-  int multiplier;
-  int arm_bonus;
-  int lvl_avl[4];
-
-  v2 = this;
-  skill_bonus = 0;
-  v69 = 0;
-  multiplier =0;
-  arm_bonus =0;
-  v71 = (ITEM_EQUIP_TYPE)0;
-  armmaster_skill = GetActualSkillLevel(PLAYER_SKILL_ARMSMASTER);
-  v4 = armmaster_skill;
-  v5 = 1;
-  if ( armmaster_skill )
-  {
-    armaster_mastery = SkillToMastery(armmaster_skill);
-    if ( a2 == CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS )
-    {
-      if ( armaster_mastery == 4 )
-          multiplier =2;
-      else if ( armaster_mastery == 3 )
-          multiplier =1;
-    }
-    else if ( a2 == CHARACTER_ATTRIBUTE_ATTACK )
-    {
-    if ( armaster_mastery == 4 )
-        multiplier =2;
-    else if ( armaster_mastery >= 2 )
-        multiplier =1;
+int Player::GetSkillBonus(enum CHARACTER_ATTRIBUTE_TYPE inSkill)    //TODO: move the individual implementations to attribute classes once possible
+{
+  int armsMasterBonus;
+
+  armsMasterBonus = 0;
+  int armmaster_skill = GetActualSkillLevel(PLAYER_SKILL_ARMSMASTER);
+  if ( armmaster_skill > 0 )
+  {
+    int multiplier = 0;
+    if ( inSkill == CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS )
+    {
+      multiplier = GetMultiplierForSkillLevel(armmaster_skill, 0, 0, 1, 2);
+    }
+    else if ( inSkill == CHARACTER_ATTRIBUTE_ATTACK )
+    {
+      multiplier = GetMultiplierForSkillLevel(armmaster_skill, 0, 1, 1, 2);
     } 
-    arm_bonus=(armmaster_skill&0x3F)*multiplier;
-  }
- 
-  
-  if ( a2 == CHARACTER_ATTRIBUTE_HEALTH )
-  {
-    base_value = pBaseHealthPerLevelByClass[classType];
-    attrib_modif = GetBodybuilding();
-    return base_value * attrib_modif;
-  }
-  if ( a2 == CHARACTER_ATTRIBUTE_MANA )
-  {
-    base_value = pBaseManaPerLevelByClass[classType];
-    attrib_modif = GetMeditation();
-    return base_value * attrib_modif;
-  }
-  if ( a2 == CHARACTER_ATTRIBUTE_AC_BONUS )
+    armsMasterBonus = multiplier * (armmaster_skill & 0x3F);
+  }
+
+  switch(inSkill)
+  {
+  case CHARACTER_ATTRIBUTE_RANGED_DMG_BONUS:
+    if (HasItemEquipped(EQUIP_BOW))
+    {
+      int bowSkillLevel = GetActualSkillLevel(PLAYER_SKILL_DODGE);
+      int multiplier = GetMultiplierForSkillLevel(bowSkillLevel, 0, 0, 0, 1);
+      return multiplier * (bowSkillLevel & 0x3F);
+    }
+    return 0;
+    break;
+  case CHARACTER_ATTRIBUTE_HEALTH:
+    {
+      int base_value = pBaseHealthPerLevelByClass[classType];
+      int attrib_modif = GetBodybuilding();
+      return base_value * attrib_modif;
+    }
+    break;
+  case CHARACTER_ATTRIBUTE_MANA:
+    {
+      int base_value = pBaseManaPerLevelByClass[classType];
+      int attrib_modif = GetMeditation();
+      return base_value * attrib_modif;
+    }
+    break;
+  case CHARACTER_ATTRIBUTE_AC_BONUS:
+    {
+      bool wearingArmor = false;
+      bool wearingLeather = false;
+      unsigned int ACSum = 0;
+
+      for (int j = 0; j < 16; ++j) 
       {
-      a1b = 0;
-      v71 = (ITEM_EQUIP_TYPE)0;
-     
-      for (j=0; j<16; ++j) 
+        if (pEquipment.pIndices[j] && (!pOwnItems[pEquipment.pIndices[j]].IsBroken()))
+        {
+          int curr_item = pOwnItems[pEquipment.pIndices[j] - 1].uItemID;
+          PLAYER_SKILL_TYPE itemSkillType = (PLAYER_SKILL_TYPE)pItemsTable->pItems[curr_item].uSkillType;
+          int currArmorSkillLevel = GetActualSkillLevel(itemSkillType);
+          int multiplier = 0;
+          switch (itemSkillType)
           {
-           if (pEquipment.pIndices[j]&&(!pOwnItems[ pEquipment.pIndices[j]].Broken()))
-               {
-               int curr_item =pOwnItems[pEquipment.pIndices[j]].uItemID;
-               v44=pItemsTable->pItems[curr_item].uSkillType;
-               switch (v44)
-                   {
-
-               case PLAYER_SKILL_STAFF:
-                   
-                   lvl_avl[0]=0;
-                   lvl_avl[1]=1;
-                   lvl_avl[2]=0;
-                   lvl_avl[3]=0;
-                   break;
-               case PLAYER_SKILL_SWORD:
-               case PLAYER_SKILL_SPEAR:
-                   lvl_avl[0]=0;
-                   lvl_avl[1]=0;
-                   lvl_avl[2]=0;
-                   lvl_avl[3]=1;
-                   break;
-               case PLAYER_SKILL_SHIELD:
-                    a1b = 1;
-                   lvl_avl[0]=1;
-                   lvl_avl[1]=0;
-                   lvl_avl[2]=1;
-                   lvl_avl[3]=0;
-                   break;
-               case PLAYER_SKILL_LEATHER:
-                   v71 = (ITEM_EQUIP_TYPE)1;
-                   lvl_avl[0]=1;
-                   lvl_avl[1]=0;
-                   lvl_avl[2]=1;
-                   lvl_avl[3]=0;
-
-                   break;
-               case PLAYER_SKILL_CHAIN:
-                    a1b = 1;
-                   lvl_avl[0]=1;
-                   lvl_avl[1]=0;
-                   lvl_avl[2]=0;
-                   lvl_avl[3]=0;
-                   break;
-               case PLAYER_SKILL_PLATE:
-                     a1b = 1; 
-                   lvl_avl[0]=1;
-                   lvl_avl[1]=0;
-                   lvl_avl[2]=0;
-                   lvl_avl[3]=0;
-                   break;
-               default:
-                   continue;
-                   }
-
-               v50= GetActualSkillLevel((PLAYER_SKILL_TYPE)v44);
-               v51 = v50;
-               v52 = SkillToMastery(v50);
-               v53 = v51 & 0x3F;
-               for ( i = 0; i < (signed int)v52; ++i )
-                   {
-                   if ( lvl_avl[i] )
-                       skill_bonus += v53;
-                   }
-
-               }
+          case PLAYER_SKILL_STAFF:
+            multiplier = GetMultiplierForSkillLevel(currArmorSkillLevel, 0, 1, 1, 1);
+            break;
+          case PLAYER_SKILL_SWORD:
+          case PLAYER_SKILL_SPEAR:
+            multiplier = GetMultiplierForSkillLevel(currArmorSkillLevel, 0, 0, 0, 1);
+            break;
+          case PLAYER_SKILL_SHIELD:
+            wearingArmor = true;
+            multiplier = GetMultiplierForSkillLevel(currArmorSkillLevel, 1, 1, 2, 2);
+            break;
+          case PLAYER_SKILL_LEATHER:
+            wearingLeather = true;
+            multiplier = GetMultiplierForSkillLevel(currArmorSkillLevel, 1, 1, 2, 2);
+            break;
+          case PLAYER_SKILL_CHAIN:
+            wearingArmor = true;
+            multiplier = GetMultiplierForSkillLevel(currArmorSkillLevel, 1, 1, 1, 1);
+            break;
+          case PLAYER_SKILL_PLATE:
+            wearingArmor = true; 
+            multiplier = GetMultiplierForSkillLevel(currArmorSkillLevel, 1, 1, 1, 1);
+            break;
           }
-
-      lvl_avl[0]=1;
-      lvl_avl[1]=1;
-      lvl_avl[2]=1;
-      lvl_avl[3]=0;
-
-      v55 = GetActualSkillLevel(PLAYER_SKILL_DODGE);
-      v56 = v55;
-      v57 = SkillToMastery(v55);
-      if ( !a1b && (!v71 || v57 == 4) )
-          {
-          v58 = v56 & 0x3F;
-          for ( j = 0; j < (signed int)v57; ++j )
-              {
-              if ( lvl_avl[j] )
-                  skill_bonus += v58;
-              }
-          }
-      return skill_bonus;
-
-    
+          ACSum += multiplier * (currArmorSkillLevel & 0x3F);
+        }
+      }
+
+      int dodgeSkillLevel = GetActualSkillLevel(PLAYER_SKILL_DODGE);
+      int dodgeMastery = SkillToMastery(dodgeSkillLevel);
+      int multiplier = GetMultiplierForSkillLevel(dodgeSkillLevel, 1, 2, 3, 3);
+      if ( !wearingArmor && (!wearingLeather || dodgeMastery == 4) )
+      {
+        ACSum += multiplier * (dodgeSkillLevel & 0x3F);
       }
-
-  if (a2 == CHARACTER_ATTRIBUTE_ATTACK)
-  {
-
-  if ( v2->IsUnarmed() == 1 )
+      return ACSum;
+    }
+    break;
+  case CHARACTER_ATTRIBUTE_ATTACK:
+    if ( this->IsUnarmed() )
+    {
+      int unarmedSkill = this->GetActualSkillLevel(PLAYER_SKILL_UNARMED);
+      if (!unarmedSkill)
       {
-      v33 = v2->GetActualSkillLevel(PLAYER_SKILL_UNARMED);
-      v34 = v33;
-      if ( !v33 )
-          return skill_bonus;
-      if ( SkillToMastery(v33) >= 3 )
-          multiplier = 2;
-      else 
-          multiplier=1;
-      v30 = multiplier * (v34 & 0x3F);
-      return arm_bonus + v30;
+        return 0;
       }
-  v35 = (ITEM_EQUIP_TYPE)0;
-  v68 = 0;
-  for (i=0; i<16 ; ++i)
+      int multiplier = GetMultiplierForSkillLevel(unarmedSkill, 0, 1, 2, 2);
+      return armsMasterBonus + multiplier * (unarmedSkill & 0x3F);
+    }
+    for (int i = 0; i < 16; ++i)
+    {
+      if ( this->HasItemEquipped((ITEM_EQUIP_TYPE)i) )
       {
-      if ( v2->HasItemEquipped((ITEM_EQUIP_TYPE)i) )
+        ItemDesc currItem = pItemsTable->pItems[this->pInventoryItemList[this->pEquipment.pIndices[i] - 1].uItemID];
+        if ( currItem.uEquipType <= EQUIP_MAIN_HAND)
+        {
+          PLAYER_SKILL_TYPE currItemSkillType = (PLAYER_SKILL_TYPE)currItem.uSkillType;
+          int currentItemSkillLevel = this->GetActualSkillLevel(currItemSkillType);
+          if (currItemSkillType == PLAYER_SKILL_BLASTER)
           {
-          v37 = v2->pEquipment.pIndices[i]-1;
-          if ( pItemsTable->pItems[v37].uEquipType <= EQUIP_MAIN_HAND)
-              break;
+            int multiplier = GetMultiplierForSkillLevel(currentItemSkillLevel, 1, 2, 3, 5);
+            return multiplier * (currentItemSkillLevel & 0x3F);
           }
-      }
-  if ( i >= 16 )
-      return skill_bonus;
-  
-  v38 = (PLAYER_SKILL_TYPE)pItemsTable->pItems[v37].uSkillType;
-  a1a = v2->GetActualSkillLevel(v38);
-  v39=  SkillToMastery(a1a);
-  v71 = (ITEM_EQUIP_TYPE)0;
-  switch (v38)
-      {
-  case PLAYER_SKILL_STAFF:
-      v71 = (ITEM_EQUIP_TYPE)1;
-      if ( v39 == 4 )
+          else if (currItemSkillType == PLAYER_SKILL_STAFF && this->GetActualSkillLevel(PLAYER_SKILL_UNARMED) > 0)
           {
-          v40 = v2->GetActualSkillLevel(PLAYER_SKILL_UNARMED);
-          v41 = v40;
-
-          if ( v40 )
-              {
-              if ( SkillToMastery(v40) >= 3 )
-                  multiplier = 2;
-              else 
-                  multiplier=1;
-              v68 = multiplier * (v41 & 0x3F);
-              }
+            int unarmedSkillLevel = this->GetActualSkillLevel(PLAYER_SKILL_UNARMED);
+            int multiplier = GetMultiplierForSkillLevel(currentItemSkillLevel, 1, 1, 2, 2);
+            return multiplier * (unarmedSkillLevel & 0x3F) + armsMasterBonus + (currentItemSkillLevel & 0x3F);
           }
-      break;
-  case PLAYER_SKILL_SWORD:
-  case PLAYER_SKILL_DAGGER:
-  case PLAYER_SKILL_AXE:
-  case PLAYER_SKILL_SPEAR:
-  case PLAYER_SKILL_MACE:
-            v71 = (ITEM_EQUIP_TYPE)1;
-        break;
-  case PLAYER_SKILL_BLASTER:
-
-      switch (v39)
+          else
           {
-      case 0: multiplier=1; break;
-      case 1: multiplier=3; break;
-      case 3: multiplier=3; break;
-      case 4: multiplier=5; break;
+            return armsMasterBonus + (currentItemSkillLevel & 0x3F);
           }
-      v5 = multiplier;
-      return v5 * (a1a & 0x3F);
-      break;
+        }
       }
-
-
-  
-  v30 = v68 + v71 * (a1a & 0x3F);
-  return (int)((char *)v69 + v30);
-
-  }
-
-
-  if ( a2 != 9 )
-  {
-   
-      if ( a2 <= CHARACTER_ATTRIBUTE_ATTACK )
-        return skill_bonus;
-      if ( a2 > CHARACTER_ATTRIBUTE_MELEE_DMG_MAX )
+    }
+    return 0;
+    break;
+
+  case CHARACTER_ATTRIBUTE_RANGED_ATTACK:
+    for (int i = 0; i < 16; i++)
+    {
+      if ( this->HasItemEquipped((ITEM_EQUIP_TYPE)i) )
       {
-        if ( a2 != CHARACTER_ATTRIBUTE_RANGED_ATTACK )
-          return skill_bonus;
-        v71 = (ITEM_EQUIP_TYPE)0;
-        v9 = &v2->pEquipment;
-        while ( 1 )
+        PLAYER_SKILL_TYPE currentItemSkillType = (PLAYER_SKILL_TYPE)pItemsTable->pItems[this->pInventoryItemList[this->pEquipment.pIndices[i] - 1].uItemID].uSkillType;
+        int currentItemSkillLevel = this->GetActualSkillLevel(currentItemSkillType);
+        if ( currentItemSkillType == PLAYER_SKILL_BOW )
         {
-          if ( v2->HasItemEquipped(v71) )
-          {
-            v11 = (PLAYER_SKILL_TYPE)pItemsTable->pItems[v2->pInventoryItemList[*(_DWORD *)v9].uItemID].uEquipType;
-            LOBYTE(v12) = this->GetActualSkillLevel(v11);
-            a1 = v12;
-            SkillToMastery(v12);
-            v13 = v11 - 5;
-            if ( !v13 )
-              return a1 & 0x3F;
-            if ( v13 == 2 )
-              break;
-          }
-          v71 = (ITEM_EQUIP_TYPE)((int)v71 + 1);
-          v9 = (PlayerEquipment *)((char *)v9 + 4);
-          if ( (signed int)v71 >= 16 )
-            return skill_bonus;
+          int multiplier = GetMultiplierForSkillLevel(currentItemSkillLevel, 1, 1, 1, 1);
+          return multiplier * (currentItemSkillLevel & 0x3F);
         }
-        v14 = a1;
-        v15 = 1;
-        if ( (signed int)SkillToMastery(a1) >= 4 )
-        {
-          v62 = 5;
-          goto LABEL_31;
+        else if ( currentItemSkillType == PLAYER_SKILL_BLASTER )
+        {      
+          int multiplier = GetMultiplierForSkillLevel(currentItemSkillLevel, 1, 2, 3, 5);
+          return multiplier * (currentItemSkillLevel & 0x3F);
         }
-        if ( (signed int)SkillToMastery(a1) >= 3 )
-        {
-          v62 = 3;
-          goto LABEL_31;
-        }
-        if ( (signed int)SkillToMastery(a1) < 2 )
-          goto LABEL_32;
-        goto LABEL_30;
       }
-      if ( v2->IsUnarmed() )
+    }
+    return 0;
+    break;
+
+  case CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS:
+    if ( this->IsUnarmed() )
+    {
+      int unarmedSkillLevel = this->GetActualSkillLevel(PLAYER_SKILL_UNARMED);
+      if ( !unarmedSkillLevel )
       {
-        LOBYTE(v18) = v2->GetActualSkillLevel(PLAYER_SKILL_UNARMED);
-        v14 = v18;
-        if ( !v18 )
-          return skill_bonus;
-        v15 = 0;
-        v19 = SkillToMastery(v18);
-        if ( (signed int)v19 < 3 )
-        {
-          if ( (signed int)v19 >= 2 )
-            v15 = 1;
-LABEL_32:
-          v16 = v14;
-          return v15 * (v16 & 0x3F);
-        }
-LABEL_30:
-        v62 = 2;
-LABEL_31:
-        v15 = v62;
-        goto LABEL_32;
+        return 0;
       }
-      v20 = (ITEM_EQUIP_TYPE)0;
-      while ( 1 )
+      int multiplier = GetMultiplierForSkillLevel(unarmedSkillLevel, 0, 1, 2, 2);
+      return multiplier * (unarmedSkillLevel & 0x3F);
+    }
+    for (int i = 0; i < 16; i++)
+    {
+      if ( this->HasItemEquipped((ITEM_EQUIP_TYPE)i) )
       {
-        if ( v2->HasItemEquipped(v20) )
+        int currItemId = this->pInventoryItemList[this->pEquipment.pIndices[i]].uItemID;
+        if ( pItemsTable->pItems[currItemId].uEquipType == EQUIP_MAIN_HAND || pItemsTable->pItems[currItemId].uEquipType == EQUIP_OFF_HAND )
         {
-          v22 = this->pInventoryItemList[this->pEquipment.pIndices[v20]].uItemID;
-          if ( pItemsTable->pItems[v22].uEquipType <= 1u )
-            break;
-        }
-        v20 = (ITEM_EQUIP_TYPE)((int)v20 + 1);
-        if ( (signed int)v20 >= 16 )
-          return skill_bonus;
-      }
-      v71 = (ITEM_EQUIP_TYPE)0;
-      v23 = (PLAYER_SKILL_TYPE)pItemsTable->pItems[v22].uSkillType;
-      LOBYTE(v24) = v2->GetActualSkillLevel(v23);
-      v25 = v24;
-      v26 = SkillToMastery(v24);
-      if ( !v23 )
-      {
-        if ( (signed int)SkillToMastery(v25) >= 4 )
-        {
-          LOBYTE(v31) = v2->GetActualSkillLevel(PLAYER_SKILL_UNARMED);
-          LOBYTE(v25) = v31;
-          if ( v31 )
+          PLAYER_SKILL_TYPE currItemSkillType = (PLAYER_SKILL_TYPE)pItemsTable->pItems[currItemId].uSkillType;
+          int currItemSkillLevel = this->GetActualSkillLevel(currItemSkillType);
+          int baseSkillBonus;
+          int multiplier;
+          switch (currItemSkillType)
           {
-            v15 = 0;
-            v32 = SkillToMastery(v31);
-            if ( (signed int)v32 < 3 )
+          case PLAYER_SKILL_STAFF:
+            if ( SkillToMastery(currItemSkillLevel) >= 4 && this->GetActualSkillLevel(PLAYER_SKILL_UNARMED) > 0)
             {
-              if ( (signed int)v32 >= 2 )
-                v15 = 1;
+              int unarmedSkillLevel = this->GetActualSkillLevel(PLAYER_SKILL_UNARMED);
+              int multiplier = GetMultiplierForSkillLevel(unarmedSkillLevel, 0, 1, 2, 2);
+              return multiplier * (unarmedSkillLevel & 0x3F);
             }
             else
             {
-              v15 = 2;
+              return armsMasterBonus;
             }
-            v16 = v25;
-            return v15 * (v16 & 0x3F);
+            break;
+
+          case PLAYER_SKILL_DAGGER:
+            multiplier = GetMultiplierForSkillLevel(currItemSkillLevel, 0, 0, 0, 1);
+            baseSkillBonus = multiplier * (currItemSkillLevel & 0x3F);
+            return armsMasterBonus + baseSkillBonus;
+            break;
+          case PLAYER_SKILL_SWORD:
+            multiplier = GetMultiplierForSkillLevel(currItemSkillLevel, 0, 0, 0, 0);
+            baseSkillBonus = multiplier * (currItemSkillLevel & 0x3F);
+            return armsMasterBonus + baseSkillBonus;
+            break;
+          case PLAYER_SKILL_MACE:
+          case PLAYER_SKILL_SPEAR:
+            multiplier = GetMultiplierForSkillLevel(currItemSkillLevel, 0, 1, 1, 1);
+            baseSkillBonus = multiplier * (currItemSkillLevel & 0x3F);
+            return armsMasterBonus + baseSkillBonus;
+            break;
+          case PLAYER_SKILL_AXE:
+            multiplier = GetMultiplierForSkillLevel(currItemSkillLevel, 0, 0, 1, 1);
+            baseSkillBonus = multiplier * (currItemSkillLevel & 0x3F);
+            return armsMasterBonus + baseSkillBonus;
+            break;
           }
         }
-        goto LABEL_55;
       }
-      if ( v23 == PLAYER_SKILL_DAGGER )
-      {
-        v29 = SkillToMastery(v25);
-        v28 = __OFSUB__(v29, 4);
-        v27 = ((v29 - 4) & 0x80000000u) != 0;
-      }
-      else
-      {
-        if ( v23 <= PLAYER_SKILL_DAGGER )
-          goto LABEL_55;
-        if ( v23 > PLAYER_SKILL_SPEAR )
-        {
-          if ( v23 == PLAYER_SKILL_MACE )
-          {
-            v28 = __OFSUB__(v26, 2);
-            v27 = v26 - 2 < 0;
-            goto LABEL_53;
-          }
-LABEL_55:
-          v30 = v71 * (v25 & 0x3F);
-          return (int)((char *)v69 + v30);
-        }
-        v28 = __OFSUB__(v26, 3);
-        v27 = v26 - 3 < 0;
-      }
-LABEL_53:
-      if ( !(v27 ^ v28) )
-        v71 = (ITEM_EQUIP_TYPE)1;
-      goto LABEL_55;
-    }
-    
-  
-    assert(false && "Unknown attribute!");
+    }
+    return 0;
+    break;
+  default:
     return 0;
-}
-
+  }
+}
+
+unsigned int Player::GetMultiplierForSkillLevel(unsigned int skillValue, int mult1, int mult2, int mult3, int mult4)
+{
+  int masteryLvl = SkillToMastery(skillValue);
+  switch (masteryLvl)
+  {
+    case 1: return mult1;
+    case 2: return mult2;
+    case 3: return mult3;
+    case 4: return mult4;
+  }
+  Error("(%u)", masteryLvl);
+  return 0;
+}
 //----- (00490109) --------------------------------------------------------
 // faces are:  0  1  2  3   human males
 //             4  5  6  7   human females
@@ -5332,7 +4660,7 @@
     case 0x18u:
       return SEX_FEMALE;
   }
-  assert(false);
+  Error("(%u)", this->uVoiceID);
   return SEX_MALE;
 }
 
@@ -5582,7 +4910,7 @@
     }
   }
 
-  assert(false);
+  return (PLAYER_SKILL_TYPE)37;
 }
 
 
@@ -5676,9 +5004,7 @@
   case 6:
     statToChange = &this->uLuck;
   default:
-    assert(false);
-    return;
-    break;
+    Error("(%u)", eAttribute);
   }
   if ( *statToChange < baseValue )
   {
@@ -6986,7 +6312,8 @@
       break;
     }
   }
-  assert(currPlayerId != -1);
+
+  Assert(currPlayerId != -1);
   if ( var_type > VAR_AutoNotes )
   {
     if ( var_type <= VAR_GoldInBank )
@@ -7437,14 +6764,14 @@
         this->sResDarkBonus = (unsigned __int8)var_value;
         break;
       case VAR_PhysicalResistanceBonus:
-        assert("VAR_PhysicalResistanceBonus variable unsupported" && false);
+        Assert("VAR_PhysicalResistanceBonus variable unsupported" && false);
         return;
         break;
       case VAR_MagicResistanceBonus:
         this->sResMagicBonus = (unsigned __int8)var_value;
         break;
       default:
-          assert("Unexpected var_type" && false);
+          Error("Unexpected var_type: %u", var_type);
           return;
         break;
     }
@@ -8191,7 +7518,7 @@
         pParty->uNumArenaLordWins -= (char)pValue;
         break;
     }
-    assert(false && "Function not returning any value!");
+    Error("Function not returning any value! (%u)", VarNum);
   }
   else
   {
@@ -8773,7 +8100,7 @@
       //pPlayers = &::pPlayers[1];
       //v5 = 604;
       //while ( 1 )
-  assert ( a1 > 0 && a1 < 5 );
+  Assert ( a1 > 0 && a1 < 5 );
       for ( uint i = 1; i < 5; ++i )
       {
         //item_flag = Player_has_item(604, *pPlayers, 0);
@@ -9660,3 +8987,8 @@
 {
   SetCondition(Condition_Dead, blockable);
 }
+
+void Player::SetCondUnconsciousWithBlockCheck( int blockable )
+{
+  SetCondition(Condition_Dead, blockable);
+}
\ No newline at end of file
--- a/Player.h	Sun Sep 08 17:07:47 2013 +0600
+++ b/Player.h	Sun Sep 08 17:07:58 2013 +0600
@@ -10,9 +10,12 @@
 #define PLAYER_BUFF_FATE             4
 #define PLAYER_BUFF_HAMMERHANDS      6
 #define PLAYER_BUFF_7                7
+#define PLAYER_BUFF_8                8
 #define PLAYER_BUFF_PAIN_REFLECTION 10
 #define PLAYER_BUFF_PRESERVATION    11
 #define PLAYER_BUFF_REGENERATION    12
+#define PLAYER_BUFF_13              13
+#define PLAYER_BUFF_14              14
 
 
 #define PLAYER_GUILD_BITS__SPIRIT_MEMBERSHIP 58
@@ -460,7 +463,7 @@
   bool CompareVariable(enum VariableType VarNum, signed int pValue);
   void UseItem_DrinkPotion_etc(signed int a2, int a3);
   bool AddItem(struct ItemGen *pItem);
-  int GetActualAttribute(CHARACTER_ATTRIBUTE_TYPE attrId);
+  int GetActualAttribute(CHARACTER_ATTRIBUTE_TYPE attrId, unsigned short Player::* attrValue, unsigned short Player::* attrBonus);
   int GetBaseStrength();
   int GetBaseIntelligence();
   int GetBaseWillpower();
@@ -480,11 +483,11 @@
   int GetActualAttack(int a2);
   int GetMeleeDamageMinimal();
   int GetMeleeDamageMaximal();
-  int CalculateMeleeDamageTo(int a2, int a3, unsigned int uTargetActorID);
+  int CalculateMeleeDamageTo(bool ignoreSkillBonus, bool ignoreOffhand, unsigned int uTargetActorID);
   int GetRangedAttack();
   int GetRangedDamageMin();
   int GetRangedDamageMax();
-  bool CalculateRangedDamageTo(int a2);
+  int CalculateRangedDamageTo(int a2);
   char *GetMeleeDamageString();
   char *GetRangedDamageString();
   bool CanTrainToNextLevel();
@@ -534,8 +537,8 @@
   int SelectPhrasesTransaction(ItemGen *pItem, int building_type, int BuildID_2Events, int a5);
   int GetBodybuilding();
   int GetMeditation();
-  int CanIdentify(ItemGen *pItem);
-  int CanRepair(ItemGen *);
+  bool CanIdentify(ItemGen *pItem);
+  bool CanRepair(ItemGen *pItem);
   int GetMerchant();
   int GetPerception();
   int GetDisarmTrap();
@@ -578,6 +581,10 @@
   void DrawPlayerBuffAnimBasedOnCondition(int currPlayerId);
   void EquipBody(ITEM_EQUIP_TYPE uEquipType);
 
+  unsigned int GetMultiplierForSkillLevel(unsigned int skillValue, int mult1, int mult2, int mult3, int mult4);
+  int CalculateMeleeDmgToEnemyWithWeapon( ItemGen * weapon, unsigned int uTargetActorID , bool addOneDice);
+  bool WearsItemAnyWhere(int item_id);
+
   bool IsWeak();
   bool IsDead();
   bool IsEradicated();
@@ -610,6 +617,7 @@
   void SetCondWeakWithBlockCheck (int blockable);
   void SetCondInsaneWithBlockCheck (int blockable);
   void SetCondDeadWithBlockCheck (int blockable);
+  void SetCondUnconsciousWithBlockCheck( int blockable );
 
   inline bool IsRaceHuman() {return GetRace() == CHARACTER_RACE_HUMAN;}
   inline bool IsRaceDwarf() {return GetRace() == CHARACTER_RACE_DWARF;}
--- a/Render.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/Render.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -2,8 +2,6 @@
 #define _CRT_SECURE_NO_WARNINGS
 #endif
 
-#include <assert.h>
-
 #include "Outdoor_stuff.h"
 #include "VideoPlayer.h"
 #include "Sprites.h"
@@ -2103,7 +2101,7 @@
   hd_water_current_frame = 0;
 }
 
-bool Render::Initialize(bool bWindowed, uint uDefaultDevice, bool bColoredLights, uint uDetailLevel, uint bTinting)
+bool Render::Initialize(bool bWindowed, uint32_t uDefaultDevice, bool bColoredLights, uint32_t uDetailLevel, bool bTinting)
 {
   bUserDirect3D = true;//ReadWindowsRegistryInt("Use D3D", 0);
   bStartInWindow = bWindowed;
@@ -3185,13 +3183,15 @@
       else
       {
         if ( !v7->bIsDeviceCompatible )
-          Abortf("There aren't any D3D devices to create.");
+          Error("There aren't any D3D devices to create.");
+
         v8 = pRenderD3D->CreateDevice(0, 0, hWnd);
         uAcquiredDirect3DDevice = 0;
       }
     }
     if ( !v8 )
-      Abortf("D3Drend->Init failed.");
+      Error("D3Drend->Init failed.");
+
     v9 = pRenderD3D;
     pBackBuffer4 = v9->pBackBuffer;
     pFrontBuffer4 = v9->pFrontBuffer;
@@ -3208,7 +3208,7 @@
       pBackBuffer4 = 0;
       pFrontBuffer4 = 0;
       pDirectDraw4 = 0;
-      Abortf("Direct3D renderer:  The device failed to return capabilities.");
+      Error("Direct3D renderer:  The device failed to return capabilities.");
     }
     if ( v10 & 0x3E )
     {
@@ -3222,7 +3222,7 @@
       pBackBuffer4 = 0;
       pFrontBuffer4 = 0;
       pDirectDraw4 = 0;
-      Abortf("Direct3D renderer:  The device doesn't support the necessary alpha blending modes.");
+      Error("Direct3D renderer:  The device doesn't support the necessary alpha blending modes.");
     }
     if ( (v10 & 0x80u) != 0 )
     {
@@ -3235,7 +3235,7 @@
       pBackBuffer4 = 0;
       pFrontBuffer4 = 0;
       pDirectDraw4 = 0;
-      Abortf("Direct3D renderer:  The device doesn't support non-square textures.");
+      Error("Direct3D renderer:  The device doesn't support non-square textures.");
     }
     LOBYTE(field_10365C) = ~(unsigned __int8)(v10 >> 6) & 1;
     bRequiredTextureStagesAvailable = CheckTextureStages();
@@ -3407,12 +3407,13 @@
     else
     {
       if ( !pRenderD3D->pAvailableDevices[0].bIsDeviceCompatible )
-        Abortf("There aren't any D3D devices to init.");
+        Error("There aren't any D3D devices to init.");
+
       v7 = pRenderD3D->CreateDevice(0, 1, hWnd);
       uAcquiredDirect3DDevice = 0;
     }
     if ( !v7 )
-      Abortf("D3Drend->Init failed.");
+      Error("D3Drend->Init failed.");
 
     //v8 = pRenderD3D;
     pColorKeySurface4 = 0;
@@ -3431,7 +3432,7 @@
       pBackBuffer4 = 0;
       pFrontBuffer4 = 0;
       pDirectDraw4 = 0;
-      Abortf("Direct3D renderer:  The device failed to return capabilities.");
+      Error("Direct3D renderer:  The device failed to return capabilities.");
     }
     if ( v9 & 0x3E )
     {
@@ -3445,7 +3446,7 @@
       pBackBuffer4 = 0;
       pFrontBuffer4 = 0;
       pDirectDraw4 = 0;
-      Abortf("Direct3D renderer:  The device doesn't support the necessary alpha blending modes.");
+      Error("Direct3D renderer:  The device doesn't support the necessary alpha blending modes.");
     }
     if ( (v9 & 0x80u) != 0 )
     {
@@ -3458,7 +3459,7 @@
       pBackBuffer4 = 0;
       pFrontBuffer4 = 0;
       pDirectDraw4 = 0;
-      Abortf("Direct3D renderer:  The device doesn't support non-square textures.");
+      Error("Direct3D renderer:  The device doesn't support non-square textures.");
     }
     LOBYTE(field_10365C) = ~(unsigned __int8)(v9 >> 6) & 1;
     bRequiredTextureStagesAvailable = CheckTextureStages();
@@ -5145,7 +5146,7 @@
   v7 = pFace->uPolygonType;
   if ( v7 == 4 || v7 == 3 )
     v70 = v6;
-  stru_8019C8._48653D(65536, 0, 0, 0, 65536, 0);
+  stru_8019C8._48653D_frustum_blv(65536, 0, 0, 0, 65536, 0);
   v62.Create_48607B(&stru_8019C8);
   v62.uTileBitmapID = pFace->uBitmapID;
   v62.pTexture = (Texture *)((signed __int16)v62.uTileBitmapID != -1 ? &pBitmaps_LOD->pTextures[(signed __int16)v62.uTileBitmapID] : 0);
@@ -6449,7 +6450,7 @@
             true,
             bMipMaps,
             uMinDeviceTextureDim) )
-      Abortf("HiScreen16::LoadTexture - D3Drend->CreateTexture() failed: %x", 0);
+      Error("HiScreen16::LoadTexture - D3Drend->CreateTexture() failed: %x", 0);
     //v10 = *pOutSurface;
     //v11 = 0;
     if ( bMipMaps )
@@ -6550,7 +6551,7 @@
     //v6 = v3->uMinDeviceTextureDim;
     //v7 = v3->pRenderD3D;
     if (!pRenderD3D->CreateTexture(sprite_texture->uWidth, sprite_texture->uHeight, &pSprite->pTextureSurface, &pSprite->pTexture, 1u, 0, uMinDeviceTextureDim))
-      Abortf("HiScreen16::LoadTexture - D3Drend->CreateTexture() failed: %x", 0);
+      Error("HiScreen16::LoadTexture - D3Drend->CreateTexture() failed: %x", 0);
     //pSprite = v2->pTextureSurface;
     //pSprite = (Sprite *)pSprite->pName;
     //v8 = pSprite;
@@ -8411,7 +8412,6 @@
       ClipCursor(0);
       pRenderer->SwitchToWindow(hWnd);
       SetWindowLongA(hWnd, -16, uWindowStyle);
-      SetMenu(hWnd, hOSMenu);
     }
     if ( pRenderer->pRenderD3D )
     {
--- a/Render.h	Sun Sep 08 17:07:47 2013 +0600
+++ b/Render.h	Sun Sep 08 17:07:58 2013 +0600
@@ -1,5 +1,7 @@
 #pragma once
-#include <stdio.h>
+
+#include <cstdint>
+#include <cstdio>
 
 #include "lib\legacy_dx\d3d.h"
 #include "OSAPI.h"
@@ -169,7 +171,7 @@
   HWLTexture *LoadTexture(const char *pName, int bMipMaps);
 
   FILE *pFile;
-  uint  uSignature;
+  uint32_t uSignature;
   unsigned int uDataOffset;
   unsigned int uNumItems;
   char *pSpriteNames[50000];
@@ -267,8 +269,8 @@
 
   static Render *Create() {return new Render;}
 
-  bool Initialize(bool bWindowed, uint uDefaultDevice,
-                  bool bColoredLights, uint uDetailLevel, uint bTinting);
+  bool Initialize(bool bWindowed, uint32_t uDefaultDevice,
+                  bool bColoredLights, uint32_t uDetailLevel, bool bTinting);
 
 
   bool IsColorKeySupported(IDirectDraw4 *);
@@ -435,7 +437,7 @@
   unsigned int uMinDeviceTextureDim;
   int field_10365C;
   unsigned int bUsingSpecular;
-  uint uFogColor;
+  uint32_t uFogColor;
   int field_103668;
   unsigned int pHDWaterBitmapIDs[7];
   char field_103688[32];
@@ -447,7 +449,7 @@
   int _gpu_memory_used;
   void ( *pBeforePresentFunction)();
   int field_1036C4;
-  uint bFogEnabled;
+  uint32_t bFogEnabled;
   int field_1036CC;
   RenderBillboardD3D pBillboardRenderListD3D[1000];
   unsigned int uNumBillboardsToDraw;
--- a/SaveLoad.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/SaveLoad.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -4,7 +4,6 @@
 
 #include <io.h>
 #include <direct.h>
-#include <assert.h>
 
 #include "SaveLoad.h"
 #include "BSPModel.h"
@@ -105,7 +104,7 @@
     Log::Warning(L"%S", Str);
     MessageBoxA(nullptr, Str, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\LoadSave.cpp:549", 0);
   }
-  assert(sizeof(SavegameHeader) == 100);
+  Assert(sizeof(SavegameHeader) == 100);
   fread(&header, sizeof(SavegameHeader), 1, f);
 
   f = pNew_LOD->FindContainer("party.bin", 1);
@@ -211,10 +210,7 @@
   sprintf(pTmpBuf.data(), "levels\\%s", header.pLocationName);
   v26 = _access(pTmpBuf.data(), 4) != -1;
   if ( !v25 && !v26 )
-  {
-    sprintf(pTmpBuf.data(), "Unable to find: %s!", header.pLocationName);
-    Abortf(pTmpBuf.data());
-  }
+    Error("Unable to find: %s!", header.pLocationName);
 
   strcpy(pCurrentMapName, header.pLocationName);
   dword_6BE364_game_settings_1 |= 0x2001;
@@ -308,7 +304,7 @@
     MessageBoxA(nullptr, work_string, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\LoadSave.cpp:773", 0);
   }
 
-  assert(sizeof(SavegameHeader) == 100);
+  Assert(sizeof(SavegameHeader) == 100);
   memset(save_header.pName, 0, 20);
   memset(save_header.pLocationName, 0, 20);
   memset(save_header.field_30, 0, 52);
@@ -344,7 +340,7 @@
   }
   strcpy(pLodDirectory.pFilename, "npcdata.bin");
   pLodDirectory.uDataSize = 501 * sizeof(NPCData);
-  assert(pLodDirectory.uDataSize == 38076);
+  Assert(pLodDirectory.uDataSize == 38076);
   if ( pNew_LOD->Write(&pLodDirectory, pNPCStats->pNewNPCData, 0) )
   {
     sprintf(work_string, pGlobalTXT_LocalizationStrings[612], 205);
@@ -737,15 +733,15 @@
       {
         //uint src_y = (game_viewport_y + y * v25) * (Dst.lPitch / sizeof(short));
         uint src_y = game_viewport_y + y * v25;
-        assert(game_viewport_y + y * v25 < src_height);
-        assert(y < height);
+        Assert(game_viewport_y + y * v25 < src_height);
+        Assert(y < height);
 
         for (uint x = 0; x < width; ++x)
         {
           //uint src_x = game_viewport_x + x * v23;
           uint src_x = game_viewport_x + x * v23;
-          assert(src_x < src_width);
-          assert(x < width);
+          Assert(src_x < src_width);
+          Assert(x < width);
 
           dst[y * width + x] = (((63*y)/117) << 5) | 31*x/155;//31*y/117;//src[src_y * src_width + src_x];
         }
--- a/Spells.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/Spells.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -441,7 +441,7 @@
 
 	}
 //----- (00448DF8) --------------------------------------------------------
-void __fastcall EventCastSpell(int spellnum, int uSkillLevel, int uSkill, int fromx, int fromy, int fromz, int tox, int toy, int toz)//sub_448DF8
+void __fastcall EventCastSpell(int uSpellID, 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
@@ -509,7 +509,7 @@
 
   v9 = 0;
   v59 = uSkillLevel + 1;
-  //spellnum_ = spellnum;
+  //spellnum_ = uSpellID;
   v60 = 0;
   if ( tox || toy || toz )
   {
@@ -552,12 +552,12 @@
   SpriteObject a1; // [sp+38h] [bp-7Ch]@12
   //SpriteObject::SpriteObject(&a1);
 
-  a1.uType = stru_4E3ACC[spellnum].uType;
-  if ( spellnum > 58 )
+  a1.uType = stru_4E3ACC[uSpellID].uType;
+  if ( uSpellID > 58 )
   {
-    if ( spellnum == 69 )
+    if ( uSpellID == 69 )
       goto LABEL_117;
-    if ( spellnum != 83 )
+    if ( uSpellID != 83 )
       return;
     v40 = v15 - 2;
     if ( v40 )
@@ -604,9 +604,9 @@
     v37->Apply(v36, a7b, v43, 0, 0);
     goto LABEL_139;
   }
-  if ( spellnum != 58 )
+  if ( uSpellID != 58 )
   {
-    switch ( spellnum )
+    switch ( uSpellID )
     {
       case 2:
       case 6:
@@ -618,7 +618,7 @@
       case 41:
         a1.stru_24.Reset();
         v16 = 0;
-        a1.spell_id = spellnum;
+        a1.spell_id = uSpellID;
         a1.spell_level = uSkill;
         a1.spell_skill = v15;
         if ( (signed int)pObjectList->uNumObjects <= 0 )
@@ -703,7 +703,7 @@
           a8b = a7c / (v60 - 1);
           a1.stru_24.Reset();
           v21 = 0;
-          a1.spell_id = spellnum;
+          a1.spell_id = uSpellID;
           a1.spell_level = uSkill;
           a1.spell_skill = v15;
           if ( (signed int)pObjectList->uNumObjects <= 0 )
@@ -759,7 +759,7 @@
         }
         a1.stru_24.Reset();
         v16 = 0;
-        a1.spell_id = spellnum;
+        a1.spell_id = uSpellID;
         a1.spell_level = uSkill;
         a1.spell_skill = v15;
         if ( (signed int)pObjectList->uNumObjects <= 0 )
@@ -849,7 +849,7 @@
         a8c = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360 / (v60 - 1);
         a1.stru_24.Reset();
         v25 = 0;
-        a1.spell_id = spellnum;
+        a1.spell_id = uSpellID;
         a1.spell_level = uSkill;
         a1.spell_skill = v15;
         if ( (signed int)pObjectList->uNumObjects <= 0 )
@@ -924,7 +924,7 @@
           return;
         a1.stru_24.Reset();
         v29 = 0;
-        a1.spell_id = spellnum;
+        a1.spell_id = uSpellID;
         a1.spell_level = uSkill;
         a1.spell_skill = v15;
         if ( (signed int)pObjectList->uNumObjects <= 0 )
@@ -985,10 +985,10 @@
           0,
           0);
         //v33 = spellnum_;
-        pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 0);
-        pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 1);
-        pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 2);
-        pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 3);
+        pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 0);
+        pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 1);
+        pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 2);
+        pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 3);
         goto LABEL_138;
       case 17:
       case 38:
@@ -1006,7 +1006,7 @@
             v9 = 3600 * (uSkill + 1);
             break;
         }
-        switch ( spellnum )
+        switch ( uSpellID )
         {
           case 17:
             v60 = 0;
@@ -1023,10 +1023,10 @@
             v60 = v34;
             break;
         }
-        pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 0);
-        pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 1);
-        pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 2);
-        pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 3);
+        pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 0);
+        pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 1);
+        pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 2);
+        pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 3);
         v52 = 0;
         v50 = 0;
         v48 = v60;
@@ -1040,10 +1040,10 @@
           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);
+        pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 0);
+        pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 1);
+        pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 2);
+        pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 3);
         v52 = 0;
         v50 = 0;
         v48 = uSkill;
@@ -1131,7 +1131,7 @@
     goto LABEL_125;
   }
 LABEL_125:
-  switch ( spellnum )
+  switch ( uSpellID )
   {
     case 3:
       uSkill = 6;
@@ -1153,16 +1153,16 @@
       break;
   }
   //v45 = spellnum_;
-  pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 0);
-  pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 1);
-  pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 2);
-  pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 3);
+  pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 0);
+  pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 1);
+  pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 2);
+  pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 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);
+    pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0);
 }
 //----- (00427769) --------------------------------------------------------
 bool __fastcall sub_427769_spell(unsigned int uSpellID)
--- a/SpriteObject.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/SpriteObject.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -1,5 +1,3 @@
-#include <assert.h>
-
 #include "BSPModel.h"
 #include "SpriteObject.h"
 #include "Party.h"
@@ -312,12 +310,12 @@
       ODM_GetTerrainNormalAt(v12, v11, &v51);
       v1->vVelocity.z -= LOWORD(pEventTimer->uTimeElapsed) * GetGravityStrength();
       v56 = abs(v51.y * v1->vVelocity.y + v51.z * v1->vVelocity.z + v51.x * v1->vVelocity.x) >> 16;
-      v60 = ((unsigned __int64)(v56 * (signed __int64)v51.x) >> 16);
-      v1->vVelocity.x += (unsigned int)(v56 * v51.x) >> 16;
-      v60 = ((unsigned __int64)(v56 * (signed __int64)v51.y) >> 16);
-      v1->vVelocity.y += (unsigned int)(v56 * v51.y) >> 16;
-      v60 = ((unsigned __int64)(v56 * (signed __int64)v51.z) >> 16);
-      v1->vVelocity.z += (unsigned int)(v56 * v51.z) >> 16;
+      //v60 = ((unsigned __int64)(v56 * (signed __int64)v51.x) >> 16);
+      v1->vVelocity.x += fixpoint_sub0(v56, v51.x);
+      //v60 = ((unsigned __int64)(v56 * (signed __int64)v51.y) >> 16);
+      v1->vVelocity.y += fixpoint_sub0(v56, v51.y);
+      //v60 = ((unsigned __int64)(v56 * (signed __int64)v51.z) >> 16);
+      v1->vVelocity.z += fixpoint_sub0(v56, v51.z);
 LABEL_12:
       v7 = v54;
       goto LABEL_13;
@@ -397,22 +395,22 @@
     stru_721530.field_0 = 0;
     v55 = 0;
     stru_721530.prolly_normal_d = v2->uRadius;
-    stru_721530.field_C = v2->uHeight;
-    stru_721530.field_8 = 0;
+    stru_721530.height = v2->uHeight;
+    stru_721530.field_8_radius = 0;
     stru_721530.field_70 = 0;
     while ( 1 )
     {
-      stru_721530.field_34.x = v1->vPosition.x;
-      stru_721530.normal.x = stru_721530.field_34.x;
+      stru_721530.position.x = v1->vPosition.x;
+      stru_721530.normal.x = stru_721530.position.x;
       v15 = v1->vPosition.y;
       stru_721530.uSectorID = 0;
-      stru_721530.field_34.y = v15;
+      stru_721530.position.y = v15;
       stru_721530.normal.y = v15;
-      stru_721530.field_34.z = v1->vPosition.z + stru_721530.prolly_normal_d + 1;
-      stru_721530.normal.z = stru_721530.field_34.z;
-      stru_721530.field_1C = v1->vVelocity.x;
-      stru_721530.field_20 = v1->vVelocity.y;
-      stru_721530.field_24 = v1->vVelocity.z;
+      stru_721530.position.z = v1->vPosition.z + stru_721530.prolly_normal_d + 1;
+      stru_721530.normal.z = stru_721530.position.z;
+      stru_721530.velocity.x = v1->vVelocity.x;
+      stru_721530.velocity.y = v1->vVelocity.y;
+      stru_721530.velocity.z = v1->vVelocity.z;
       if ( stru_721530._47050A(0) )
         return;
       _46E889_collide_against_bmodels(0);
@@ -504,13 +502,13 @@
             }
         return;
       }
-      v60 = ((unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.x) >> 16);
-      v1->vPosition.x += (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.x) >> 16;
-      v60 = ((unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.y) >> 16);
-      v1->vPosition.y += (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.y) >> 16;
-      v60 = ((unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.z) >> 16);
+      //v60 = ((unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.direction.x) >> 16);
+      v1->vPosition.x += fixpoint_sub0(stru_721530.field_7C, stru_721530.direction.x);
+      //v60 = ((unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.direction.y) >> 16);
+      v1->vPosition.y += fixpoint_sub0(stru_721530.field_7C, stru_721530.direction.y);
+      //v60 = ((unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.direction.z) >> 16);
       v28 = LOWORD(stru_721530.uSectorID);
-      v1->vPosition.z += (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.z) >> 16;
+      v1->vPosition.z += fixpoint_sub0(stru_721530.field_7C, stru_721530.direction.z);
       v29 = v1->vPosition.z;
       v1->uSectorID = v28;
       stru_721530.field_70 += stru_721530.field_7C;
@@ -532,14 +530,13 @@
         {
           v56 = abs(v32->pFacePlane.vNormal.z * v1->vVelocity.z + v32->pFacePlane.vNormal.y * v1->vVelocity.y
                                                                 + v32->pFacePlane.vNormal.x * v1->vVelocity.x) >> 16;
-          if ( stru_721530.field_64 >> 3 > v56 )
-            v56 = stru_721530.field_64 >> 3;
+          if ( (stru_721530.speed >> 3) > v56 )
+            v56 = stru_721530.speed >> 3;
           v57 = v32->pFacePlane.vNormal.x;
           v57 = (unsigned __int64)(v56 * (signed __int64)v57) >> 16;
           v58 = v32->pFacePlane.vNormal.y;
           v58 = (unsigned __int64)(v56 * (signed __int64)v58) >> 16;
-          v60 = v32->pFacePlane.vNormal.z;
-          v60 = ((unsigned __int64)(v56 * (signed __int64)(signed int)v60) >> 16);
+          v60 = ((unsigned __int64)(v56 * (signed __int64)v32->pFacePlane.vNormal.z) >> 16);
           v1->vVelocity.x += 2 * v57;
           v1->vVelocity.y += 2 * v58;
           if ( v32->pFacePlane.vNormal.z <= 32000 )
@@ -614,7 +611,7 @@
   int v9; // ecx@16
   __int16 v10; // di@18
   char v11; // al@19
-  int v12; // eax@25
+  //int v12; // eax@25
   int v13; // eax@31
   int v14; // ebx@34
   signed int v15; // ebx@46
@@ -673,22 +670,22 @@
     stru_721530.field_0 = v8;
     uFaceID = v8;
     stru_721530.prolly_normal_d = pObject->uRadius;
-    v12 = pObject->uHeight;
+
     stru_721530.field_84 = -1;
-    stru_721530.field_C = v12;
-    stru_721530.field_8 = v8;
+    stru_721530.height = pObject->uHeight;
+    stru_721530.field_8_radius = v8;
     stru_721530.field_70 = v8;
     while ( 1 )
     {
-      stru_721530.field_34.x = pSpriteObject->vPosition.x;
-      stru_721530.normal.x = stru_721530.field_34.x;
-      stru_721530.field_34.y = pSpriteObject->vPosition.y;
-      stru_721530.normal.y = stru_721530.field_34.y;
-      stru_721530.field_34.z = stru_721530.prolly_normal_d + pSpriteObject->vPosition.z + 1;
-      stru_721530.normal.z = stru_721530.field_34.z;
-      stru_721530.field_1C = pSpriteObject->vVelocity.x;
-      stru_721530.field_20 = pSpriteObject->vVelocity.y;
-      stru_721530.field_24 = pSpriteObject->vVelocity.z;
+      stru_721530.position.x = pSpriteObject->vPosition.x;
+      stru_721530.normal.x = stru_721530.position.x;
+      stru_721530.position.y = pSpriteObject->vPosition.y;
+      stru_721530.normal.y = stru_721530.position.y;
+      stru_721530.position.z = stru_721530.prolly_normal_d + pSpriteObject->vPosition.z + 1;
+      stru_721530.normal.z = stru_721530.position.z;
+      stru_721530.velocity.x = pSpriteObject->vVelocity.x;
+      stru_721530.velocity.y = pSpriteObject->vVelocity.y;
+      stru_721530.velocity.z = pSpriteObject->vVelocity.z;
       stru_721530.uSectorID = pSpriteObject->uSectorID;
       if ( stru_721530._47050A(v8) )
         return;
@@ -788,12 +785,12 @@
         pGame->pParticleEngine->AddParticle(&Dst);
         return;
       }
-      v40 = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.x) >> 16;
-      pSpriteObject->vPosition.x += (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.x) >> 16;
-      v40 = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.y) >> 16;
-      pSpriteObject->vPosition.y += (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.y) >> 16;
-      v40 = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.z) >> 16;
-      pSpriteObject->vPosition.z += (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.z) >> 16;
+      //v40 = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.direction.x) >> 16;
+      pSpriteObject->vPosition.x += fixpoint_sub0(stru_721530.field_7C, stru_721530.direction.x);
+      //v40 = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.direction.y) >> 16;
+      pSpriteObject->vPosition.y += fixpoint_sub0(stru_721530.field_7C, stru_721530.direction.y);
+      //v40 = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.direction.z) >> 16;
+      pSpriteObject->vPosition.z += fixpoint_sub0(stru_721530.field_7C, stru_721530.direction.z);
       pSpriteObject->uSectorID = LOWORD(stru_721530.uSectorID);
       stru_721530.field_70 += stru_721530.field_7C;
       if ( pObject->uFlags & 0x40 && !_46BFFA_check_object_intercept(uLayingItemID, stru_721530.uFaceID) )
@@ -824,8 +821,8 @@
         {
           v42 = abs(v16->pFacePlane_old.vNormal.x * pSpriteObject->vVelocity.x + v16->pFacePlane_old.vNormal.z * pSpriteObject->vVelocity.z
                                                                     + v16->pFacePlane_old.vNormal.y * pSpriteObject->vVelocity.y) >> 16;
-          if ( stru_721530.field_64 >> 3 > v42 )
-            v42 = stru_721530.field_64 >> 3;
+          if ( (stru_721530.speed >> 3) > v42 )
+            v42 = stru_721530.speed >> 3;
           v40 = v16->pFacePlane_old.vNormal.x;
           v40 = (unsigned __int64)(v42 * (signed __int64)v40) >> 16;
           v41 = v16->pFacePlane_old.vNormal.y;
--- a/SpriteObject.h	Sun Sep 08 17:07:47 2013 +0600
+++ b/SpriteObject.h	Sun Sep 08 17:07:58 2013 +0600
@@ -3,7 +3,8 @@
 
 enum
 {
-  OBJECT_ATTACHED_TO_ACTOR = 0x80,
+    OBJECT_40 = 0x40
+  , OBJECT_ATTACHED_TO_ACTOR = 0x80
 };
 
 #define MAX_SPRITE_OBJECTS 1000
--- a/Sprites.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/Sprites.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -351,7 +351,7 @@
   v2 = fopen("data\\dsft.bin", "wb");
   v3 = v2;
   if ( !v2 )
-    Abortf("Unable to save dsft.bin!");
+    Error("Unable to save dsft.bin!");
   fwrite(v1, 4u, 1u, v2);
   fwrite(&v1->uNumEFrames, 4u, 1u, v3);
   fwrite(v1->pSpriteSFrames, 0x3Cu, v1->uNumSpriteFrames, v3);
@@ -405,8 +405,7 @@
     pSpriteSFrames[num_mm7_frames + i].uAnimLength = 0;
   }
   memcpy(pSpriteEFrames + num_mm7_frames, (char *)data_mm6 + 8 + mm6_frames_size, 2 * num_mm6_eframes);
-  
-  if (data_mm8) __debugbreak();
+
   auto mm8_frames_size = num_mm8_frames * sizeof(SpriteFrame);
   memcpy(pSpriteSFrames + num_mm6_frames + num_mm7_frames, (char *)data_mm8 + 8, mm8_frames_size);
   memcpy(pSpriteEFrames + num_mm6_frames + num_mm7_frames, (char *)data_mm8 + 8 + mm8_frames_size, 2 * num_mm8_eframes);
@@ -479,7 +478,8 @@
   v3 = fopen(Args, "r");
   File = v3;
   if ( !v3 )
-    Abortf("CSpriteFrameTable::load - Unable to open file: %s.", Args);
+    Error("CSpriteFrameTable::load - Unable to open file: %s.", Args);
+
   v4 = 0;
   Argsa = 0;
   if ( fgets(Buf, 490, v3) )
@@ -779,16 +779,16 @@
                                 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;
+                                v21 = ((v8 - stru_721530.normal.x) * stru_721530.direction.y
+                                     - (v9 - stru_721530.normal.y) * stru_721530.direction.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;
+                                  v14 = (v12 * stru_721530.direction.x + v19 * stru_721530.direction.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);
+                                        + ((unsigned __int64)(stru_721530.direction.z * (signed __int64)v14) >> 16);
                                     if ( v16 >= v15 )
                                     {
                                       if ( v16 <= v22 + v15 )
--- a/Texture.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/Texture.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -257,7 +257,7 @@
   v2 = fopen("data\\dtft.bin", "wb");
   v3 = v2;
   if ( !v2 )
-    Abortf("Unable to save dtft.bin!");
+    Error("Unable to save dtft.bin!");
   fwrite(v1, 4u, 1u, v2);
   fwrite(v1->pTextures, 0x14u, v1->sNumTextures, v3);
   fclose(v3);
@@ -271,8 +271,8 @@
        num_mm8_frames = data_mm8 ? *(int *)data_mm8 : 0;
 
   sNumTextures = num_mm6_frames + num_mm7_frames + num_mm8_frames;
-  assert(sNumTextures);
-  assert(!num_mm8_frames);
+  Assert(sNumTextures);
+  Assert(!num_mm8_frames);
 
   pTextures = (TextureFrame *)pAllocator->AllocNamedChunk(pTextures, sNumTextures * sizeof(TextureFrame), "Txt Frames");
 
@@ -453,10 +453,8 @@
   v4 = v3;
   File = v3;
   if ( !v3 )
-  {
-    sprintf(pTmpBuf.data(), "Unable to load %s", pContainer);
-    Abortf(pTmpBuf.data());
-  }
+    Error("Unable to load %s", pContainer);
+
   fread(&DstBuf, 1u, 0x30u, v3);
   Count = DstBuf.uTextureSize;
   if ( DstBuf.uDecompressedSize )
@@ -543,10 +541,8 @@
   v5 = v4;
   File = v4;
   if ( !v4 )
-  {
-    sprintf(pTmpBuf.data(), "Unable to load %s", pContainer);
-    Abortf(pTmpBuf.data());
-  }
+    Error("Unable to load %s", pContainer);
+
   fread(&DstBuf, 1u, 0x30u, v4);
   Count = DstBuf.uTextureSize;
   if ( DstBuf.uDecompressedSize )
@@ -1508,7 +1504,8 @@
     fseek(File, 128, 0);
     ftell(File);
 	if ( pcx_header2.planes == 1 )
-      Abortf("24bit PCX Only!");
+      Error("24bit PCX Only!");
+
     if ( pcx_header2.planes == 3 )
     {
       v37 = 0;
@@ -1680,7 +1677,8 @@
   v3 = fopen(Args, "r");
   File = v3;
   if ( !v3 )
-    Abortf("CTextureFrameTable::load - Unable to open file: %s.", Args);
+    Error("CTextureFrameTable::load - Unable to open file: %s.", Args);
+
   v4 = 0;
   v24 = 0;
   v25 = 1;
@@ -1694,7 +1692,7 @@
       if ( v21 && *Str1 != 47 )
       {
         if ( v21 < 2 )
-          Abortf("CTextureFrameTable::load, too few arguments, %s line %i.", Args, v25);
+          Error("CTextureFrameTable::load, too few arguments, %s line %i.", Args, v25);
         ++v24;
       }
       ++v25;
@@ -1707,7 +1705,7 @@
   v6 = pAllocator->AllocNamedChunk(v5, 20 * v4, "Txt Frames");
   v2->pTextures = (TextureFrame *)v6;
   if ( !v6 )
-    Abortf("CTextureFrameTable::load - Out of Memory!");
+    Error("CTextureFrameTable::load - Out of Memory!");
   v7 = File;
   v2->sNumTextures = 0;
   fseek(v7, 0, 0);
--- a/TileTable.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/TileTable.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -2,7 +2,6 @@
 #define _CRT_SECURE_NO_WARNINGS
 #endif
 
-#include  <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -30,15 +29,7 @@
 //----- (00487E3B) --------------------------------------------------------
 TileDesc *TileTable::GetTileById(unsigned int uTileID)
 {
-  /*TileDesc *result; // eax@3
-
-  if ( (uTileID & 0x80000000u) != 0 || (signed int)uTileID > (signed int)(this->uNumTiles - 1) )
-    result = this->pTiles;
-  else
-    result = &this->pTiles[uTileID];
-  return result;*/
-
-  assert(uTileID < sNumTiles);
+  Assert(uTileID < sNumTiles);
   return &pTiles[uTileID];
 }
 
@@ -112,7 +103,7 @@
   v2 = fopen("data\\dtile.bin", "wb");
   v3 = v2;
   if ( !v2 )
-    Abortf("Unable to save dtile.bin!");
+    Error("Unable to save dtile.bin!");
   fwrite(v1, 4u, 1u, v2);
   fwrite(v1->pTiles, 0x1Au, v1->sNumTiles, v3);
   fclose(v3);
@@ -125,8 +116,8 @@
        num_mm7_tiles = data_mm7 ? *(int *)data_mm7 : 0,
        num_mm8_tiles = data_mm8 ? *(int *)data_mm8 : 0;
   sNumTiles = num_mm6_tiles + num_mm7_tiles + num_mm8_tiles;
-  assert(sNumTiles);
-  assert(!num_mm8_tiles);
+  Assert(sNumTiles);
+  Assert(!num_mm8_tiles);
 
   pTiles = (TileDesc *)pAllocator->AllocNamedChunk(pTiles, sNumTiles * sizeof(TileDesc), "Tile Descrip");
   memcpy(pTiles,                                 (char *)data_mm7 + 4, num_mm7_tiles * sizeof(TileDesc));
@@ -226,7 +217,7 @@
   v3 = fopen(pFilename, "r");
   File = v3;
   if ( !v3 )
-    Abortf("TileTable::load - Unable to open file: %s.");
+    Error("TileTable::load - Unable to open file: %s.");
   v4 = 0;
   for ( i = v3; fgets(&Buf, 490, i); i = File )
   {
@@ -239,7 +230,7 @@
   v5 = pAllocator->AllocNamedChunk(v2->pTiles, 26 * v4, "Tile Descrip");
   v2->pTiles = (TileDesc *)v5;
   if ( !v5 )
-    Abortf("TileTable::Load - Out of Memory!");
+    Error("TileTable::Load - Out of Memory!");
   memset(v5, 0, 26 * v2->sNumTiles);
   v2->sNumTiles = 0;
   fseek(File, 0, 0);
--- a/TurnEngine.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/TurnEngine.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -697,7 +697,7 @@
 
 //----- (00406648) --------------------------------------------------------
 void stru262_TurnBased::AIAttacks( unsigned int queue_index )
-    {
+{
     TurnBased_QueueElem *v1; // ecx@1
     int v3; // eax@1
     unsigned int v4; // ebx@2
--- a/UI/Books/UIMapBook.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/UI/Books/UIMapBook.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -2,8 +2,6 @@
 #define _CRT_SECURE_NO_WARNINGS
 #endif
 
-#include <assert.h>
-
 #include "..\..\MM7.h"
 #include "..\..\Render.h"
 #include "..\..\Mouse.h"
@@ -528,21 +526,21 @@
   {
     v51 = pParty->sRotationY & stru_5C6E00->uDoublePiMask;
     if ( (signed int)v51 <= 1920 )
-      v50 = 7;
+      v50 = 6;
     if ( (signed int)v51 < 1664 )
-      v50 = 6;
+      v50 = 5;
     if ( (signed int)v51 <= 1408 )
-      v50 = 5;
+      v50 = 4;
     if ( (signed int)v51 < 1152 )
-      v50 = 4;
+      v50 = 3;
     if ( (signed int)v51 <= 896 )
-      v50 = 3;
+      v50 = 2;
     if ( (signed int)v51 < 640 )
-      v50 = 2;
+      v50 = 1;
     if ( (signed int)v51 <= 384 )
-      v50 = 1;
-    if ( (signed int)v51 < 128 )
       v50 = 0;
+    if ( (signed int)v51 < 128 || (signed int)v51 > 1920 )
+      v50 = 7;
     pRenderer->DrawTransparentRedShade(v47, v49, pIcons_LOD->GetTexture(pTextureIDs_pMapDirs[v50]));
   }
   result = TargetColor(0xFFu, 0xFFu, 0xFFu);
--- a/UI/Books/UINotesBooks.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/UI/Books/UINotesBooks.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -1,9 +1,7 @@
-
 #ifdef _MSC_VER
 #define _CRT_SECURE_NO_WARNINGS
 #endif
 
-#include <assert.h>
 #include "..\..\MM7.h"
 #include "..\..\Render.h"
 #include "..\..\Mouse.h"
--- a/UI/Books/UISpellBook.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/UI/Books/UISpellBook.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -2,7 +2,6 @@
 #define _CRT_SECURE_NO_WARNINGS
 #endif
 
-#include <assert.h>
 #include "..\..\MM7.h"
 #include "..\..\Render.h"
 #include "..\..\Mouse.h"
--- a/UI/UIBooks.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/UI/UIBooks.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -2,7 +2,6 @@
 #define _CRT_SECURE_NO_WARNINGS
 #endif
 
-#include <assert.h>
 #include "..\MM7.h"
 #include "UIBooks.h"
 #include "..\Render.h"
--- a/UI/UICharacter.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/UI/UICharacter.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -2,7 +2,6 @@
 #define _CRT_SECURE_NO_WARNINGS
 #endif
 
-#include <assert.h>
 #include <algorithm> 
 #include "..\MM7.h"
 #include "..\MapInfo.h"
@@ -1594,9 +1593,9 @@
     }
     else
     {
-      if (player->pInventoryItemList[player->pInventoryMatrix[i] - 1].Identified() || pCurrentScreen != SCREEN_HOUSE)
+      if (player->pInventoryItemList[player->pInventoryMatrix[i] - 1].IsIdentified() || pCurrentScreen != SCREEN_HOUSE)
       {
-        if (player->pInventoryItemList[player->pInventoryMatrix[i] - 1].Broken())
+        if (player->pInventoryItemList[player->pInventoryMatrix[i] - 1].IsBroken())
           pRenderer->DrawTransparentRedShade(uCellX, uCellY, pTexture);
         else
           pRenderer->DrawTextureTransparent(uCellX, uCellY, pTexture);
@@ -1635,9 +1634,9 @@
   }
   else
   {
-    if (item->Broken())
+    if (item->IsBroken())
       pRenderer->DrawTransparentRedShade(x, y, item_texture);
-    else if (!item->Identified())
+    else if (!item->IsIdentified())
       pRenderer->DrawTransparentGreenShade(x, y, item_texture);
     else
       pRenderer->DrawTextureTransparent(x, y, item_texture);
@@ -1764,7 +1763,7 @@
       }
     }
   }
-  memset(byte_5111F6.data(), 0, 16);
+  memset(byte_5111F6.data(), 0, sizeof(byte_5111F6));
   for (uint i = 0; i < 4; ++i)
   {
     auto player = pParty->pPlayers + i;
--- a/UI/UIGuilds.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/UI/UIGuilds.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -40,7 +40,6 @@
   int v26; // ecx@47
   GUIButton *pButton; // eax@49
   unsigned int v29; // eax@49
-  char *pText; // eax@52
   int pTextHeight; // eax@55
   unsigned int v32; // ecx@55
   int v33; // eax@55
@@ -72,9 +71,10 @@
   int v61; // [sp+2E0h] [bp-Ch]@35
   int pItemNum;
   unsigned int v62; // [sp+2E4h] [bp-8h]@13
-  int v63; // [sp+2E8h] [bp-4h]@1
+  int pPrice; // [sp+2E8h] [bp-4h]@1
   int pNumActivItem;
   int all_text_height;
+  int pX;
 
   memcpy(&working_window, window_SpeakInHouse, sizeof(GUIWindow));
   working_window.uFrameX = 483;
@@ -83,9 +83,9 @@
   pColorWhite = TargetColor(0xFFu, 0xFFu, 0xFFu);
   pColorYellow = TargetColor(0xFFu, 0xFFu, 0x9Bu);
   base_teach_price = (signed __int64)(p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].fPriceMultiplier * 500.0);
-  v63 = base_teach_price * (100 - pPlayers[uActiveCharacter]->GetMerchant()) / 100;
-  if ( v63 < base_teach_price / 3 )
-    v63 = base_teach_price / 3;
+  pPrice = base_teach_price * (100 - pPlayers[uActiveCharacter]->GetMerchant()) / 100;
+  if ( pPrice < base_teach_price / 3 )
+    pPrice = base_teach_price / 3;
   strcpy(Dest, "");
   strcpy(v46, "");
   strcpy(v47, "");
@@ -105,14 +105,14 @@
         }
         else
         {
-          if ( pParty->uNumGold < v63 )
+          if ( pParty->uNumGold < pPrice )
           {
-            ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2u); //"You don't have enough gold"
+            ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2); //"You don't have enough gold"
             PlayHouseSound((unsigned int)window_SpeakInHouse->ptr_1C, HouseSound_NotEnoughMoney_TrainingSuccessful);
           }
           else
           {
-            Party::TakeGold(v63);
+            Party::TakeGold(pPrice);
             pPlayers[uActiveCharacter]->pActiveSkills[dialog_menu_id-36] = 1;
           }
         }
@@ -123,40 +123,34 @@
     pRenderer->DrawTextureIndexed(8, 8, ShopTexture);
     v6 = 0;
     v62 = 0;
-    v63 = 32;
-    do
+    for ( pX = 32; pX < 452; pX += 70 )//   
     {
-      if (pParty->SpellBooksInGuilds[window_SpeakInHouse->par1C-139][v6].uItemID)
+      if ( pParty->SpellBooksInGuilds[window_SpeakInHouse->par1C-139][v6].uItemID )
       {
-        pRenderer->DrawTextureTransparent(v63, 0x5Au, ItemsInShopTexture[v6]);
+        pRenderer->DrawTextureTransparent(pX, 90, ItemsInShopTexture[v6]);
         ZBuffer_DoFill((int *)((char *)pRenderer->pActiveZBuffer + v62 + 230528), ItemsInShopTexture[v6], v6 + 1);
       }
-      v63 += 70;
       v62 += 280;
       ++v6;
     }
-    while ( v63 < 452 );
     v62 = 1680;
     v7 = 6;
-    v63 = 32;
-    do
+    for ( pX = 32; pX < 452; pX += 70 )//   
     {
       if (pParty->SpellBooksInGuilds[window_SpeakInHouse->par1C-139][v7].uItemID)
       {
-        pRenderer->DrawTextureTransparent(v63, 0xFAu, ItemsInShopTexture[v7]);
+        pRenderer->DrawTextureTransparent(pX, 250, ItemsInShopTexture[v7]);
         ZBuffer_DoFill((int *)((char *)pRenderer->pActiveZBuffer + v62 + 638448), ItemsInShopTexture[v7], v7 + 1);
       }
-      v63 += 70;
       v62 += 280;
       ++v7;
     }
-    while ( v63 < 452 );
     if ( HouseUI_CheckIfPlayerCanInteract() )
     {
       v8 = 0;
       for ( v9 = 12; v9; --v9 )
       {
-        if (pParty->SpellBooksInGuilds[window_SpeakInHouse->par1C-139][v9].uItemID )
+        if ( pParty->SpellBooksInGuilds[window_SpeakInHouse->par1C-139][v9].uItemID > 0 )
           ++v8;
       }
       GetAsyncKeyState(17);
@@ -166,8 +160,7 @@
       DrawTextAtStatusBar(statusbar_string, 0);
       if ( !v8 )
       {
-        working_window.DrawCurrentTime(__PAIR__( *(int *)&stru_AA1058[3].pSounds[8 * (unsigned int)window_SpeakInHouse->ptr_1C + 44472],
-                       *(int *)&stru_AA1058[3].pSounds[8 * (unsigned int)window_SpeakInHouse->ptr_1C + 44468]) - pParty->uTimePlayed);
+        working_window.DrawCurrentTime(pParty->field_3C.Shops_next_generation_time[window_SpeakInHouse->par1C] - pParty->uTimePlayed);//"  14 "
         return;
       }
       v12 = pMouse->GetCursorPos(&v51);
@@ -180,7 +173,7 @@
         v16 = (int)window_SpeakInHouse->ptr_1C;
         uPlayerID = uActiveCharacter - 1;
         v17 = pPlayers[uActiveCharacter]->SelectPhrasesTransaction( (ItemGen *)&pParty->pPlayers[1].uExpressionTimeLength + v13 + 12 * (int)v14, BuildingType_MagicShop, v16,  2);
-        v18 = BuildDialogueString((char *)pMerchantsBuyPhrases[v17], uPlayerID, v15, (char *)v14, 2, 0);     
+        v18 = BuildDialogueString((char *)pMerchantsBuyPhrases[v17], uPlayerID, v15, (char *)v14, 2, 0);
         v19 = pFontArrus->CalcTextHeight(v18, &working_window, 0, 0);
         working_window.DrawTitleText(pFontArrus, 0, (174 - v19) / 2 + 138,  pColorWhite, v18, 3);
         return;
@@ -192,7 +185,7 @@
             guild_mambership_flags[(unsigned int)window_SpeakInHouse->ptr_1C-139]) )
   { //you must me member
     v38 = pFontArrus->CalcTextHeight(pNPCTopics[121].pText, &working_window, 0, 0);
-    working_window.DrawTitleText(pFontArrus, 0, (212 - v38) / 2 + 101, pColorYellow, pNPCTopics[121].pText, 3u);
+    working_window.DrawTitleText(pFontArrus, 0, (212 - v38) / 2 + 101, pColorYellow, pNPCTopics[121].pText, 3);
     pDialogueWindow->pNumPresenceButton = 0;
     return;
   }
@@ -245,7 +238,7 @@
   }
   if ( pSkillFlag )
   {
-    sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[401], v63); //"Skill Cost: %lu"
+    sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[401], pPrice); //"Skill Cost: %lu"
     working_window.DrawTitleText(pFontArrus, 0, 0x92u, 0, pTmpBuf.data(), 3);
   }
   v58 = (149 - all_text_height) / v61;
@@ -262,9 +255,8 @@
       v29 = pButton->msg_param;
       if ( v29 == 18 )
       {
-        pText = pGlobalTXT_LocalizationStrings[400]; //"Buy Spells"
         pButton->uY = v58 + v26;
-        pTextHeight = pFontArrus->CalcTextHeight(pText, &working_window, 0, 0);
+        pTextHeight = pFontArrus->CalcTextHeight(pGlobalTXT_LocalizationStrings[400], &working_window, 0, 0);
         v32 = pButton->uY;
         pButton->uHeight = pTextHeight;
         v33 = v32 + pTextHeight - 1;
@@ -273,7 +265,7 @@
         pTextColor = pColorYellow;
         if ( pDialogueWindow->pCurrentPosActiveItem != pItemNum )
           pTextColor = pColorWhite;
-        working_window.DrawTitleText(pFontArrus, 0, v32, pTextColor, pText, 3);
+        working_window.DrawTitleText(pFontArrus, 0, v32, pTextColor, pGlobalTXT_LocalizationStrings[400], 3);//"Buy Spells"
       }
       else
       {
@@ -337,7 +329,7 @@
     ItemGen * item_spellbook = &pParty->SpellBooksInGuilds[window_SpeakInHouse->par1C-139][i];
     item_spellbook->Reset();
     pParty->SpellBooksInGuilds[window_SpeakInHouse->par1C-139][i].uItemID = pItemNum;
-    pParty->SpellBooksInGuilds[window_SpeakInHouse->par1C-139][i].Identified();
+    pParty->SpellBooksInGuilds[window_SpeakInHouse->par1C-139][i].IsIdentified();
     ItemsInShopTexture[i] = pIcons_LOD->LoadTexturePtr(pItemsTable->pItems[pItemNum].pIconName, TEXTURE_16BIT_PALETTE);
   }
   return;
--- a/UI/UIHouses.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/UI/UIHouses.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -109,10 +109,6 @@
   {255, 255, 255, 255}   // HOUSE_BOATS_73
 };
 
-
-
-
-
 std::array<const stru159, 196> pAnimatedRooms = //0x4E5F70
 {{
         {"",                            0x4, 0x1F4, 0, 0, 0},
@@ -326,7 +322,7 @@
     num_buttons = 2;
     CreateButtonInColumn(0, 102);
     CreateButtonInColumn(1, 103);
-	if ( pParty->HasItem(651) ) //Arcomage Deck
+    if ( pParty->HasItem(651) ) //Arcomage Deck
     {
       num_buttons = 3;
       CreateButtonInColumn(2, 104);
@@ -369,24 +365,6 @@
 //----- (004B3B42) --------------------------------------------------------
 void InitializaDialogueOptions(BuildingType type)
 {
-  /*int v1; // ecx@18
-  int v2; // ecx@19
-  int v3; // ecx@20
-  signed int v4; // esi@22
-  signed int v5; // eax@22
-  unsigned int v6; // edx@24
-  int v7; // ecx@24
-  int result; // eax@43
-  int v9; // [sp-10h] [bp-14h]@28
-  int v10; // [sp-Ch] [bp-10h]@28
-  int v11; // [sp-8h] [bp-Ch]@28
-  unsigned int v12; // [sp-4h] [bp-8h]@4
-  unsigned int v13; // [sp-4h] [bp-8h]@5
-  unsigned int v14; // [sp-4h] [bp-8h]@9
-  unsigned int v15; // [sp-4h] [bp-8h]@10
-  unsigned int v16; // [sp-4h] [bp-8h]@14
-  int v17; // [sp-4h] [bp-8h]@28*/
-
   switch (type)
   {
     case BuildingType_WeaponShop:
@@ -580,7 +558,7 @@
       break;
 
     default:
-      assert(false && "Invalid enumeration value");
+      Error("Invalid enumeration value: %u", type);
   }
 
 /*  if ( a1 > 13 )
@@ -764,39 +742,30 @@
 //----- (004B1784) --------------------------------------------------------
 bool  HouseUI_CheckIfPlayerCanInteract()
 {
-  Player *pPlayer; // ebx@1
-  bool result; // eax@2
-  int v3; // eax@3
-  GUIWindow v4; // [sp+4h] [bp-54h]@3
+  GUIWindow window; // [sp+4h] [bp-54h]@3
 
-  pPlayer = pPlayers[uActiveCharacter];
-  if ( pPlayer->CanAct() )
+  if ( pPlayers[uActiveCharacter]->CanAct() )
   {
     pDialogueWindow->pNumPresenceButton = dword_F8B1E0;
-    result = 1;
+    return true;
   }
   else
   {
     pDialogueWindow->pNumPresenceButton = 0;
-    memcpy(&v4, pPrimaryWindow, sizeof(v4));
-    v4.uFrameX = 483;
-    v4.uFrameWidth = 148;
-    v4.uFrameZ = 334;
-    sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[427], pPlayer->pName, pGlobalTXT_LocalizationStrings[562]);// 
-                                                // "%s is in no condition to %s"
-                                                // "do anything"
-    v3 = pFontArrus->CalcTextHeight(pTmpBuf.data(), &v4, 0, 0);
-    v4.DrawTitleText(pFontArrus, 0, (212 - v3) / 2 + 101, ui_house_player_cant_interact_color, pTmpBuf.data(), 3u);
-    result = 0;
+    memcpy(&window, pPrimaryWindow, sizeof(window));
+    window.uFrameX = 483;
+    window.uFrameWidth = 148;
+    window.uFrameZ = 334;
+    sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[427], pPlayers[uActiveCharacter]->pName,
+              pGlobalTXT_LocalizationStrings[562]); // "%s is in no condition to %s""do anything"
+    window.DrawTitleText(pFontArrus, 0, (212 - pFontArrus->CalcTextHeight(pTmpBuf.data(), &window, 0, 0)) / 2 + 101, ui_house_player_cant_interact_color, pTmpBuf.data(), 3);
+    return false;
   }
-  return result;
 }
 
 //----- (0044622E) --------------------------------------------------------
 bool EnterHouse(enum HOUSE_ID uHouseID)
 {
-	//enum HOUSE_ID v1; // edi@1
-	//int v2; // edi@5
 	signed int uOpenTime; // eax@5
 	signed int uCloseTime; // esi@5
 	unsigned int v5; // esi@5
@@ -804,27 +773,18 @@
 	signed int am_pm_flag_open; // ecx@10
 	signed int am_pm_flag_close; // eax@10
 	int v9; // esi@10
-	//unsigned int v10; // esi@16
 	int v11; // ecx@17
 	unsigned int v12; // kr00_4@25
-	//Player *v13; // esi@25
 	int v14; // eax@25
-	//Player *v15; // esi@27
-	//signed int v16; // eax@32
 	unsigned int v17; // eax@37
 	signed int v18; // edi@37
 	signed int v19; // edi@41
-	//unsigned int v20; // ecx@41
-	//const char *v22; // [sp-4h] [bp-40h]@33
 	char pContainer[40]; // [sp+Ch] [bp-30h]@32
 	unsigned int v24; // [sp+34h] [bp-8h]@5
-	//enum HOUSE_ID v25; // [sp+38h] [bp-4h]@1
 
-	//v1 = uHouseID;
-	//v25 = uHouseID;
 	GameUI_Footer_TimedString[0] = 0;
 	pFooterString[0] = 0;
-	ShowStatusBarString("", 2u);
+	ShowStatusBarString("", 2);
 	if ( pMessageQueue_50CBD0->uNumMessages )
 		pMessageQueue_50CBD0->uNumMessages = pMessageQueue_50CBD0->pMessages[0].field_8 != 0;
 	viewparams->bRedrawGameUI = 1;
@@ -907,12 +867,12 @@
 		if ( !pIcons_LOD->uNumPrevLoadedFiles )
 			pIcons_LOD->uNumPrevLoadedFiles = pIcons_LOD->uNumLoadedFiles;
 		switch (pParty->alignment)
-			{
+        {
 		case PartyAlignment_Good:    sprintf(pContainer, "evt%02d-b", const_2()); break;
 		case PartyAlignment_Neutral: sprintf(pContainer, "evt%02d", const_2()); break;
 		case PartyAlignment_Evil:    sprintf(pContainer, "evt%02d-c", const_2()); break;
-		default: assert(false);
-			}
+        default: Error("Invalid alignment type: %u", pParty->alignment);
+        }
 
 		v17 = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
 		pDialogueNPCCount = 0;
@@ -952,25 +912,11 @@
 //----- (0044606A) --------------------------------------------------------
 void PrepareHouse(HOUSE_ID house)
 {
-  //unsigned int v1; // ebx@1
-  //signed int v2; // esi@1
-  //int uExitPic; // edi@1
   __int16 uExitMapID; // ax@2
-  //int result; // eax@5
-  //unsigned int *v6; // ecx@8
   int v7; // ebx@11
-  //int v8; // esi@16
-  //unsigned int v9; // eax@16
-  //unsigned int v10; // eax@19
-  //int v11; // ecx@19
-  //char pContainer[36]; // [sp+Ch] [bp-54h]@16
   int v13; // [sp+30h] [bp-30h]@11
   int npc_id_arr[6]; // [sp+34h] [bp-2Ch]@1
-  //unsigned int v15; // [sp+4Ch] [bp-14h]@1
   int uAnimationID; // [sp+50h] [bp-10h]@1
-  //unsigned int *v17; // [sp+54h] [bp-Ch]@3
-  //unsigned int v18; // [sp+58h] [bp-8h]@1
-  //int v19; // [sp+5Ch] [bp-4h]@7
 
 
   uAnimationID = p2DEvents[house - 1].uAnimationID;
@@ -1041,21 +987,9 @@
 //----- (004BCACC) --------------------------------------------------------
 void __fastcall OnSelectShopDialogueOption(signed int uMessageParam)
 {
-  //unsigned int v1; // edi@1
-  //signed int v2; // ebx@1
-  //signed int v3; // ecx@2
-  int v4; // eax@5
-  signed int v5; // esi@5
-  //Player *v6; // ecx@5
-  //signed int v7; // edx@5
+  int experience_for_next_level; // eax@5
   GUIWindow *v8; // esi@10
-  unsigned int v9; // eax@12
-  int v10; // esi@31
-  int v11; // edi@31
-  int v12; // esi@32
-  __int16 v13; // bp@32
-  int v14; // edx@32
-  GUIWindow *v15; // eax@32
+  //int v11; // edi@31
   int v16; // eax@32
   int v17; // eax@33
   int v18; // eax@34
@@ -1065,24 +999,13 @@
   __int16 v22; // ax@107
   __int16 v23; // ax@132
   __int16 v24; // ax@163
-  int v25; // esi@190
-  __int16 v26; // ax@190
-  char v27; // zf@190
-  Player *v28; // edi@192
-  int v29; // eax@204
-  void *v30; // esi@208
-  unsigned __int64 v31; // qax@208
-  signed int v32; // edi@209
-  int v33; // eax@210
   unsigned int v34; // eax@211
-  //Player *v35; // edi@227
   signed int v36; // esi@227
   int v37; // ecx@227
   int v38; // esi@230
   int v39; // edx@235
   int v40; // edi@243
   unsigned __int64 v41; // qax@243
-  //void *v42; // eax@244
   signed int v43; // edi@244
   int v44; // edx@244
   int v45; // eax@246
@@ -1095,83 +1018,62 @@
   void *v52; // eax@260
   signed int v53; // edi@260
   int v54; // eax@262
-  //signed int v55; // [sp+10h] [bp-10h]@1
-  int v56; // [sp+14h] [bp-Ch]@31
 
-  //v1 = 0;
-  //v2 = a1;
-  //v55 = a1;
   if ( !pDialogueWindow->pNumPresenceButton )
     return;
   pRenderer->ClearZBuffer(0, 479);
-  //v3 = dword_F8B198;
   if ( dialog_menu_id != HOUSE_DIALOGUE_MAIN)
     v8 = window_SpeakInHouse;
-  //else
   if (dialog_menu_id == HOUSE_DIALOGUE_MAIN)
   {
-	  if ( in_current_building_type == BuildingType_Training )
-	  {
-		if ( uMessageParam == HOUSE_DIALOGUE_TRAININGHALL_TRAIN )
-		{
-		  v4 = 0;
-		  v5 = 0;
-		  //v6 = pPlayers[uActiveCharacter];
-		  //v7 = pPlayers[uActiveCharacter]->uLevel;
-		  if ( pPlayers[uActiveCharacter]->uLevel > 0 )
-		  {
-			do
-			  v4 += v5++ + 1;
-			while ( v5 < pPlayers[uActiveCharacter]->uLevel );
-		  }
-		  if (pPlayers[uActiveCharacter]->uLevel < pMaxLevelPerTrainingHallType[(unsigned int)window_SpeakInHouse->ptr_1C - 89] &&
-			  (signed __int64)pPlayers[uActiveCharacter]->uExperience < 1000 * v4)
-			return;
-		}
-		pDialogueWindow->Release();
-		pDialogueWindow = GUIWindow::Create(0, 0, 640, 0x159u, WINDOW_MainMenu, 0, 0);
-		pBtn_ExitCancel = pDialogueWindow->CreateButton(526, 445, 75, 33, 1, 0, UIMSG_Escape, 0, 0, pGlobalTXT_LocalizationStrings[74],// "End Conversation"
-					                                    pIcons_LOD->GetTexture(uTextureID_BUTTDESC2), 0);
-		pDialogueWindow->CreateButton(8, 8, 0x1C2, 0x140, 1, 0, UIMSG_BuyInShop_Identify_Repair, 0, 0, "", nullptr);
-//	LABEL_10:
-		//v3 = dword_F8B198;
-		v8 = window_SpeakInHouse;
-	  }
-	  //else
-	  if ( in_current_building_type != BuildingType_Training )
-	  {
-		  v8 = window_SpeakInHouse;
-		  if ((in_current_building_type == BuildingType_Stables || in_current_building_type == BuildingType_Boats) &&
-			  transport_schedule[transport_routes[(unsigned int)window_SpeakInHouse->ptr_1C - HOUSE_STABLES_HARMONDALE][uMessageParam - HOUSE_DIALOGUE_TRANSPORT_SCHEDULE_1]].pSchedule[pParty->uDaysPlayed % 7]
-			|| in_current_building_type != BuildingType_Temple || uMessageParam != BuildingType_MindGuild )
-		  {
-		//LABEL_9:
-			pDialogueWindow->Release();
-			pDialogueWindow = GUIWindow::Create(0, 0, 640, 0x159u, WINDOW_MainMenu, 0, 0);
-			pBtn_ExitCancel = pDialogueWindow->CreateButton(526, 445, 75, 33, 1, 0, UIMSG_Escape, 0, 0, pGlobalTXT_LocalizationStrings[74],// "End Conversation"
-						                                    pIcons_LOD->GetTexture(uTextureID_BUTTDESC2), 0);
-			pDialogueWindow->CreateButton(8u, 8u, 0x1C2u, 0x140u, 1, 0, UIMSG_BuyInShop_Identify_Repair, 0, 0, "", nullptr);
-	//	LABEL_10:
-			//v3 = dword_F8B198;
-			v8 = window_SpeakInHouse;
-		  }
-		  else if (uActiveCharacter)
-		  {
-			if ( !pPlayers[uActiveCharacter]->IsPlayerHealableByTemple() )
-			  return;
-			v8 = window_SpeakInHouse;
-		  }
-	  }
-	//LABEL_11:
-	  dialog_menu_id = (HOUSE_DIALOGUE_MENU)uMessageParam;
-	  if ( in_current_building_type < BuildingType_19 )
-	  {
-		v9 = pIcons_LOD->LoadTexture(off_4F03B8[(int)in_current_building_type], TEXTURE_16BIT_PALETTE);
-		//v3 = dword_F8B198;
-		ShopTexture = &pIcons_LOD->pTextures[v9];
-	//LABEL_13:
-		v8 = window_SpeakInHouse;
-	  }
+    if ( in_current_building_type == BuildingType_Training )
+    {
+      if ( uMessageParam == HOUSE_DIALOGUE_TRAININGHALL_TRAIN )
+      {
+        experience_for_next_level = 0;
+        if ( pPlayers[uActiveCharacter]->uLevel > 0 )
+        {
+          for( uint i = 0; i < pPlayers[uActiveCharacter]->uLevel; i++ )
+            experience_for_next_level += i + 1;
+        }
+        if (pPlayers[uActiveCharacter]->uLevel < pMaxLevelPerTrainingHallType[(unsigned int)window_SpeakInHouse->ptr_1C - 89] &&
+          (signed __int64)pPlayers[uActiveCharacter]->uExperience < 1000 * experience_for_next_level)//test experience
+        return;
+      }
+      pDialogueWindow->Release();
+      pDialogueWindow = GUIWindow::Create(0, 0, 640, 345, WINDOW_MainMenu, 0, 0);
+      pBtn_ExitCancel = pDialogueWindow->CreateButton(526, 445, 75, 33, 1, 0, UIMSG_Escape, 0, 0, pGlobalTXT_LocalizationStrings[74],// "End Conversation"
+                                                       pIcons_LOD->GetTexture(uTextureID_BUTTDESC2), 0);
+      pDialogueWindow->CreateButton(8, 8, 450, 320, 1, 0, UIMSG_BuyInShop_Identify_Repair, 0, 0, "", nullptr);
+      v8 = window_SpeakInHouse;
+    }
+    if ( in_current_building_type != BuildingType_Training )
+    {
+      v8 = window_SpeakInHouse;
+      if ((in_current_building_type == BuildingType_Stables || in_current_building_type == BuildingType_Boats) &&
+           transport_schedule[transport_routes[(unsigned int)window_SpeakInHouse->ptr_1C - HOUSE_STABLES_HARMONDALE][uMessageParam - HOUSE_DIALOGUE_TRANSPORT_SCHEDULE_1]].pSchedule[pParty->uDaysPlayed % 7]
+          || in_current_building_type != BuildingType_Temple || uMessageParam != BuildingType_MindGuild )
+      {
+        pDialogueWindow->Release();
+        pDialogueWindow = GUIWindow::Create(0, 0, 640, 345, WINDOW_MainMenu, 0, 0);
+        pBtn_ExitCancel = pDialogueWindow->CreateButton(526, 445, 75, 33, 1, 0, UIMSG_Escape, 0, 0, pGlobalTXT_LocalizationStrings[74],// "End Conversation"
+                                                         pIcons_LOD->GetTexture(uTextureID_BUTTDESC2), 0);
+        pDialogueWindow->CreateButton(8, 8, 450, 320, 1, 0, UIMSG_BuyInShop_Identify_Repair, 0, 0, "", nullptr);
+        v8 = window_SpeakInHouse;
+      }
+      else if (uActiveCharacter)
+      {
+        if ( !pPlayers[uActiveCharacter]->IsPlayerHealableByTemple() )
+          return;
+        v8 = window_SpeakInHouse;
+      }
+    }
+    dialog_menu_id = (HOUSE_DIALOGUE_MENU)uMessageParam;
+    if ( in_current_building_type < BuildingType_19 )
+    {
+      ShopTexture = &pIcons_LOD->pTextures[pIcons_LOD->LoadTexture(off_4F03B8[(int)in_current_building_type], TEXTURE_16BIT_PALETTE)];
+      v8 = window_SpeakInHouse;
+    }
   }
   
   //NEW
@@ -1190,243 +1092,190 @@
     case BuildingType_15:
     case BuildingType_16:
     {
-      if ( *(int *)&stru_AA1058[3].pSounds[8 * (unsigned int)v8->ptr_1C + 44472] >= (signed __int64)pParty->uTimePlayed &&
-          *(int *)&stru_AA1058[3].pSounds[8 * (unsigned int)v8->ptr_1C + 44468] >= (signed __int64)pParty->uTimePlayed )
+      if ( pParty->field_3C.Shops_next_generation_time[window_SpeakInHouse->par1C] >= (signed __int64)pParty->uTimePlayed )
       {
-        v32 = 0;
-        do
+        for ( uint i = 0; i < 12; ++i )
         {
-          //v33 = *(&pParty->pPlayers[1].pInstalledBeacons[0].field_18 + 9 * (v32 + 12 * (unsigned int)v8->ptr_1C));
-          v33 = pParty->SpellBooksInGuilds[v8->par1C-139][v32].uItemID;
-          if ( v33 )
+          if ( pParty->SpellBooksInGuilds[v8->par1C-139][i].uItemID )
           {
-            v34 = pIcons_LOD->LoadTexture(pItemsTable->pItems[v33].pIconName, TEXTURE_16BIT_PALETTE);
+            v34 = pIcons_LOD->LoadTexture(pItemsTable->pItems[pParty->SpellBooksInGuilds[v8->par1C-139][i].uItemID].pIconName, TEXTURE_16BIT_PALETTE);
             v8 = window_SpeakInHouse;
-            ItemsInShopTexture[v32] = &pIcons_LOD->pTextures[v34];
+            ItemsInShopTexture[i] = &pIcons_LOD->pTextures[v34];
           }
-          ++v32;
         }
-        while ( v32 < 12 );
       }
-      else
+      else//generation new books
       {
         SpellBookGenerator();
-        v30 = window_SpeakInHouse->ptr_1C;
-        v31 = pParty->uTimePlayed + (signed __int64)((double)(0xA8C000
-                                   //* (signed int)p2DEvents_minus1[26 * (unsigned int)ptr_507BC0->ptr_1C])
+        pParty->field_3C.Shops_next_generation_time[window_SpeakInHouse->par1C] = pParty->uTimePlayed + (signed __int64)((double)(0xA8C000
                                   * (signed int)p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].field_1C) * 0.033333335);
-        *(int *)&stru_AA1058[3].pSounds[8 * (int)v30 + 44468] = v31;
-        *(int *)&stru_AA1058[3].pSounds[8 * (int)v30 + 44472] = HIDWORD(v31);
       }
-      //return;
       break;
     }
     case BuildingType_TownHall:
     {
-      if ( uMessageParam == 99 )
+      if ( uMessageParam == HOUSE_DIALOGUE_TOWNHALL_MESSAGE )
       {
-        v10 = (int)((char *)v8->ptr_1C - 102);
-        v56 = v10;
-        v11 = 8 * v10 + 11325428;
-        if ( pParty->field_3C.field_0[2 * v10 + 1] >= (signed __int64)pParty->uTimePlayed
-             && pParty->field_3C.field_0[2 * v10] >= (signed __int64)pParty->uTimePlayed )
+        if ( pParty->field_3C.bountyHunting_next_generation_time[(int)((char *)v8->ptr_1C - 102)] < (signed __int64)pParty->uTimePlayed )//new generation
         {
-          v13 = 0;
+          pParty->monster_for_hunting_killed[(int)((char *)v8->ptr_1C - 102)] = false;
+          pParty->field_3C.bountyHunting_next_generation_time[(int)((char *)v8->ptr_1C - 102)] = (signed __int64)((double)(309657600 * (pParty->uCurrentMonth + 12i64 * pParty->uCurrentYear - 14015)) * 0.033333335);
+          pParty->monster_id_for_hunting[(int)((char *)v8->ptr_1C - 102)] = rand() % 258 + 1;
+          v16 = (int)((char *)window_SpeakInHouse->ptr_1C - 102);
+          if ( !v16 )
+          {
+            while ( 1 )
+            {
+              v24 = pParty->monster_id_for_hunting[(int)((char *)v8->ptr_1C - 102)];
+              if ( (unsigned __int16)v24 < 115 || (unsigned __int16)v24 > 132 )
+              {
+                if ( ((unsigned __int16)v24 < 235 || (unsigned __int16)v24 > 252)
+                  && ((unsigned __int16)v24 < 133 || (unsigned __int16)v24 > 150)
+                  && ((unsigned __int16)v24 < 0x97u || (unsigned __int16)v24 > 0xBAu)
+                  && ((unsigned __int16)v24 < 0xBEu || (unsigned __int16)v24 > 0xC0u)
+                  && ((unsigned __int16)v24 < 0xC4u || (unsigned __int16)v24 > 0xC6u)
+                  && ((unsigned __int16)v24 < 0x2Bu || (unsigned __int16)v24 > 0x2Du)
+                  && ((unsigned __int16)v24 < 0xCDu || (unsigned __int16)v24 > 0xCFu)
+                  && ((unsigned __int16)v24 < 0x5Eu || (unsigned __int16)v24 > 0x60u)
+                  && ((unsigned __int16)v24 < 0xFDu || (unsigned __int16)v24 > 0xFFu)
+                  && ((unsigned __int16)v24 < 0x6Du || (unsigned __int16)v24 > 0x6Fu)
+                  && ((unsigned __int16)v24 < 0x61u || (unsigned __int16)v24 > 0x63u) )
+                  break;
+              }
+              pParty->monster_id_for_hunting[(int)((char *)v8->ptr_1C - 102)] = rand() % 258 + 1;
+            }
+          }
+          if ( v16 == 1 )
+          {
+            while ( 1 )
+            {
+              v23 = pParty->monster_id_for_hunting[(int)((char *)v8->ptr_1C - 102)];
+              if ( (unsigned __int16)v23 < 115 || (unsigned __int16)v23 > 132 )
+              {
+                if ( ((unsigned __int16)v23 < 0xE8u || (unsigned __int16)v23 > 0xF9u)
+                  && ((unsigned __int16)v23 < 0x85u || (unsigned __int16)v23 > 0x96u)
+                  && ((unsigned __int16)v23 < 0x97u || (unsigned __int16)v23 > 0xBAu)
+                  && ((unsigned __int16)v23 < 0xBEu || (unsigned __int16)v23 > 0xC0u)
+                  && ((unsigned __int16)v23 < 0xC4u || (unsigned __int16)v23 > 0xC6u)
+                  && ((unsigned __int16)v23 < 0x2Bu || (unsigned __int16)v23 > 0x2Du)
+                  && ((unsigned __int16)v23 < 0x52u || (unsigned __int16)v23 > 0x54u)
+                  && ((unsigned __int16)v23 < 4 || (unsigned __int16)v23 > 6)
+                  && ((unsigned __int16)v23 < 0x37u || (unsigned __int16)v23 > 0x39u)
+                  && ((unsigned __int16)v23 < 0x3Au || (unsigned __int16)v23 > 0x3Cu)
+                  && ((unsigned __int16)v23 < 0x3Du || (unsigned __int16)v23 > 0x3Fu)
+                  && ((unsigned __int16)v23 < 0xFDu || (unsigned __int16)v23 > 0xFFu)
+                  && ((unsigned __int16)v23 < 0x61u || (unsigned __int16)v23 > 0x63u)
+                  && ((unsigned __int16)v23 < 0xCDu || (unsigned __int16)v23 > 0xCFu) )
+                  break;
+              }
+              pParty->monster_id_for_hunting[(int)((char *)v8->ptr_1C - 102)] = rand() % 258 + 1;
+            }
+          }
+          if ( v16 == 2 )
+          {
+            while ( 1 )
+            {
+              v22 = pParty->monster_id_for_hunting[(int)((char *)v8->ptr_1C - 102)];
+              if ( (unsigned __int16)v22 < 0x73u || (unsigned __int16)v22 > 0x84u )
+              {
+                if ( ((unsigned __int16)v22 < 0xE8u || (unsigned __int16)v22 > 0xF9u)
+                  && ((unsigned __int16)v22 < 0x85u || (unsigned __int16)v22 > 0x96u)
+                  && ((unsigned __int16)v22 < 0x97u || (unsigned __int16)v22 > 0xBAu)
+                  && ((unsigned __int16)v22 < 0xBEu || (unsigned __int16)v22 > 0xC0u)
+                  && ((unsigned __int16)v22 < 0xC4u || (unsigned __int16)v22 > 0xC6u)
+                  && ((unsigned __int16)v22 < 0x2Bu || (unsigned __int16)v22 > 0x2Du)
+                  && ((unsigned __int16)v22 < 0x31u || (unsigned __int16)v22 > 0x33u)
+                  && ((unsigned __int16)v22 < 0x34u || (unsigned __int16)v22 > 0x36u)
+                  && ((unsigned __int16)v22 < 0xFDu || (unsigned __int16)v22 > 0xFFu)
+                  && ((unsigned __int16)v22 < 0x61u || (unsigned __int16)v22 > 0x63u)
+                  && ((unsigned __int16)v22 < 0x1Cu || (unsigned __int16)v22 > 0x1Eu) )
+                  break;
+              }
+              pParty->monster_id_for_hunting[(int)((char *)v8->ptr_1C - 102)] = rand() % 258 + 1;
+            }
+          }
+          if ( v16 == 3 )
+          {
+            while ( 1 )
+            {
+              v21 = pParty->monster_id_for_hunting[(int)((char *)v8->ptr_1C - 102)];
+              if ( (unsigned __int16)v21 < 0x73u || (unsigned __int16)v21 > 0x84u )
+              {
+                if ( ((unsigned __int16)v21 < 0xE8u || (unsigned __int16)v21 > 0xF9u)
+                  && ((unsigned __int16)v21 < 0x85u || (unsigned __int16)v21 > 0x96u)
+                  && ((unsigned __int16)v21 < 0x97u || (unsigned __int16)v21 > 0xBAu)
+                  && ((unsigned __int16)v21 < 0xBEu || (unsigned __int16)v21 > 0xC0u)
+                  && ((unsigned __int16)v21 < 0xC4u || (unsigned __int16)v21 > 0xC6u)
+                  && ((unsigned __int16)v21 < 0x2Bu || (unsigned __int16)v21 > 0x2Du)
+                  && ((unsigned __int16)v21 < 0x5Eu || (unsigned __int16)v21 > 0x60u)
+                  && ((unsigned __int16)v21 < 0x43u || (unsigned __int16)v21 > 0x45u)
+                  && ((unsigned __int16)v21 < 0x4Fu || (unsigned __int16)v21 > 0x51u)
+                  && ((unsigned __int16)v21 < 0xC1u || (unsigned __int16)v21 > 0xC3u)
+                  && ((unsigned __int16)v21 < 0x13u || (unsigned __int16)v21 > 0x15u)
+                  && ((unsigned __int16)v21 < 0xFDu || (unsigned __int16)v21 > 0xFFu)
+                  && ((unsigned __int16)v21 < 0x61u || (unsigned __int16)v21 > 0x63u)
+                  && ((unsigned __int16)v21 < 0x6Au || (unsigned __int16)v21 > 0x6Cu) )
+                  break;
+              }
+              pParty->monster_id_for_hunting[(int)((char *)v8->ptr_1C - 102)] = rand() % 258 + 1;
+            }
+          }
+          if ( v16 == 4 )
+          {
+            while ( 1 )
+            {
+              v20 = pParty->monster_id_for_hunting[(int)((char *)v8->ptr_1C - 102)];
+              if ( (unsigned __int16)v20 < 0x73u || (unsigned __int16)v20 > 0x84u )
+              {
+                if ( ((unsigned __int16)v20 < 0xE8u || (unsigned __int16)v20 > 0xF9u)
+                  && ((unsigned __int16)v20 < 0x85u || (unsigned __int16)v20 > 0x96u)
+                  && ((unsigned __int16)v20 < 0x97u || (unsigned __int16)v20 > 0xBAu)
+                  && ((unsigned __int16)v20 < 0xBEu || (unsigned __int16)v20 > 0xC0u)
+                  && ((unsigned __int16)v20 < 0xC4u || (unsigned __int16)v20 > 0xC6u)
+                  && ((unsigned __int16)v20 < 0x2Bu || (unsigned __int16)v20 > 0x2Du)
+                  && ((unsigned __int16)v20 < 0x6Du || (unsigned __int16)v20 > 0x6Fu)
+                  && ((unsigned __int16)v20 < 0x46u || (unsigned __int16)v20 > 0x48u)
+                  && ((unsigned __int16)v20 < 0x100u || (unsigned __int16)v20 > 0x102u)
+                  && ((unsigned __int16)v20 < 0xD9u || (unsigned __int16)v20 > 0xDBu)
+                  && ((unsigned __int16)v20 < 0xC7u || (unsigned __int16)v20 > 0xC9u)
+                  && ((unsigned __int16)v20 < 0xE5u || (unsigned __int16)v20 > 0xE7u)
+                  && ((unsigned __int16)v20 < 0xDFu || (unsigned __int16)v20 > 0xE1u)
+                  && ((unsigned __int16)v20 < 0x5Bu || (unsigned __int16)v20 > 0x5Du)
+                  && ((unsigned __int16)v20 < 0x49u || (unsigned __int16)v20 > 0x4Bu)
+                  && ((unsigned __int16)v20 < 0xFDu || (unsigned __int16)v20 > 0xFFu)
+                  && ((unsigned __int16)v20 < 0x61u || (unsigned __int16)v20 > 0x63u)
+                  && ((unsigned __int16)v20 < 0x10u || (unsigned __int16)v20 > 0x12u) )
+                  break;
+              }
+              pParty->monster_id_for_hunting[(int)((char *)v8->ptr_1C - 102)] = rand() % 258 + 1;
+            }
+          }
+        }
+        bountyHunting_monster_id_for_hunting = pParty->monster_id_for_hunting[(int)((char *)v8->ptr_1C - 102)];
+        if ( !pParty->monster_for_hunting_killed[(int)((char *)v8->ptr_1C - 102)] )
+        {
+          bountyHunting_text = pNPCTopics[351].pText;//"       %s..."
+          if ( !pParty->monster_id_for_hunting[(int)((char *)v8->ptr_1C - 102)] )
+            bountyHunting_text = pNPCTopics[353].pText;//"        "
         }
         else
         {
-          v12 = v10;
-          v13 = 0;
-          pParty->field_75A[v12] = 0;
-          *(_QWORD *)v11 = (signed __int64)((double)(309657600 * (pParty->uCurrentMonth + 12i64 * pParty->uCurrentYear - 14015)) * 0.033333335);
-          v14 = rand() % 258;
-          v15 = window_SpeakInHouse;
-          pParty->field_750[v12] = v14 + 1;
-          v16 = (int)((char *)v15->ptr_1C - 102);
-          if ( v16 )
+          if ( pParty->monster_id_for_hunting[(int)((char *)v8->ptr_1C - 102)] > 0 )//get prize
           {
-            v17 = v16 - 1;
-            if ( v17 )
-            {
-              v18 = v17 - 1;
-              if ( v18 )
-					{
-						v19 = v18 - 1;
-						if ( v19 )
-						{
-							if ( v19 == 1 )
-							{
-								while ( 1 )
-								{
-									v20 = pParty->field_750[v12];
-									if ( (unsigned __int16)v20 < 0x73u || (unsigned __int16)v20 > 0x84u )
-									{
-										if ( ((unsigned __int16)v20 < 0xE8u || (unsigned __int16)v20 > 0xF9u)
-										&& ((unsigned __int16)v20 < 0x85u || (unsigned __int16)v20 > 0x96u)
-										&& ((unsigned __int16)v20 < 0x97u || (unsigned __int16)v20 > 0xBAu)
-										&& ((unsigned __int16)v20 < 0xBEu || (unsigned __int16)v20 > 0xC0u)
-										&& ((unsigned __int16)v20 < 0xC4u || (unsigned __int16)v20 > 0xC6u)
-										&& ((unsigned __int16)v20 < 0x2Bu || (unsigned __int16)v20 > 0x2Du)
-										&& ((unsigned __int16)v20 < 0x6Du || (unsigned __int16)v20 > 0x6Fu)
-										&& ((unsigned __int16)v20 < 0x46u || (unsigned __int16)v20 > 0x48u)
-										&& ((unsigned __int16)v20 < 0x100u || (unsigned __int16)v20 > 0x102u)
-										&& ((unsigned __int16)v20 < 0xD9u || (unsigned __int16)v20 > 0xDBu)
-										&& ((unsigned __int16)v20 < 0xC7u || (unsigned __int16)v20 > 0xC9u)
-										&& ((unsigned __int16)v20 < 0xE5u || (unsigned __int16)v20 > 0xE7u)
-										&& ((unsigned __int16)v20 < 0xDFu || (unsigned __int16)v20 > 0xE1u)
-										&& ((unsigned __int16)v20 < 0x5Bu || (unsigned __int16)v20 > 0x5Du)
-										&& ((unsigned __int16)v20 < 0x49u || (unsigned __int16)v20 > 0x4Bu)
-										&& ((unsigned __int16)v20 < 0xFDu || (unsigned __int16)v20 > 0xFFu)
-										&& ((unsigned __int16)v20 < 0x61u || (unsigned __int16)v20 > 0x63u)
-										&& ((unsigned __int16)v20 < 0x10u || (unsigned __int16)v20 > 0x12u) )
-											break;
-									}
-									pParty->field_750[v12] = rand() % 258 + 1;
-								}
-							}
-						}
-						else
-						{
-							while ( 1 )
-							{
-								v21 = pParty->field_750[v12];
-								if ( (unsigned __int16)v21 < 0x73u || (unsigned __int16)v21 > 0x84u )
-								{
-								if ( ((unsigned __int16)v21 < 0xE8u || (unsigned __int16)v21 > 0xF9u)
-									&& ((unsigned __int16)v21 < 0x85u || (unsigned __int16)v21 > 0x96u)
-									&& ((unsigned __int16)v21 < 0x97u || (unsigned __int16)v21 > 0xBAu)
-									&& ((unsigned __int16)v21 < 0xBEu || (unsigned __int16)v21 > 0xC0u)
-									&& ((unsigned __int16)v21 < 0xC4u || (unsigned __int16)v21 > 0xC6u)
-									&& ((unsigned __int16)v21 < 0x2Bu || (unsigned __int16)v21 > 0x2Du)
-									&& ((unsigned __int16)v21 < 0x5Eu || (unsigned __int16)v21 > 0x60u)
-									&& ((unsigned __int16)v21 < 0x43u || (unsigned __int16)v21 > 0x45u)
-									&& ((unsigned __int16)v21 < 0x4Fu || (unsigned __int16)v21 > 0x51u)
-									&& ((unsigned __int16)v21 < 0xC1u || (unsigned __int16)v21 > 0xC3u)
-									&& ((unsigned __int16)v21 < 0x13u || (unsigned __int16)v21 > 0x15u)
-									&& ((unsigned __int16)v21 < 0xFDu || (unsigned __int16)v21 > 0xFFu)
-									&& ((unsigned __int16)v21 < 0x61u || (unsigned __int16)v21 > 0x63u)
-									&& ((unsigned __int16)v21 < 0x6Au || (unsigned __int16)v21 > 0x6Cu) )
-										break;
-								}
-								pParty->field_750[v12] = rand() % 258 + 1;
-							}
-						}
-					}
-					else
-					{
-						while ( 1 )
-						{
-							v22 = pParty->field_750[v12];
-							if ( (unsigned __int16)v22 < 0x73u || (unsigned __int16)v22 > 0x84u )
-							{
-								if ( ((unsigned __int16)v22 < 0xE8u || (unsigned __int16)v22 > 0xF9u)
-								&& ((unsigned __int16)v22 < 0x85u || (unsigned __int16)v22 > 0x96u)
-								&& ((unsigned __int16)v22 < 0x97u || (unsigned __int16)v22 > 0xBAu)
-								&& ((unsigned __int16)v22 < 0xBEu || (unsigned __int16)v22 > 0xC0u)
-								&& ((unsigned __int16)v22 < 0xC4u || (unsigned __int16)v22 > 0xC6u)
-								&& ((unsigned __int16)v22 < 0x2Bu || (unsigned __int16)v22 > 0x2Du)
-								&& ((unsigned __int16)v22 < 0x31u || (unsigned __int16)v22 > 0x33u)
-								&& ((unsigned __int16)v22 < 0x34u || (unsigned __int16)v22 > 0x36u)
-								&& ((unsigned __int16)v22 < 0xFDu || (unsigned __int16)v22 > 0xFFu)
-								&& ((unsigned __int16)v22 < 0x61u || (unsigned __int16)v22 > 0x63u)
-								&& ((unsigned __int16)v22 < 0x1Cu || (unsigned __int16)v22 > 0x1Eu) )
-								break;
-							}
-							pParty->field_750[v12] = rand() % 258 + 1;
-						}
-					}
-				}
-				else
-				{
-					while ( 1 )
-					{
-						v23 = pParty->field_750[v12];
-						if ( (unsigned __int16)v23 < 0x73u || (unsigned __int16)v23 > 0x84u )
-						{
-						if ( ((unsigned __int16)v23 < 0xE8u || (unsigned __int16)v23 > 0xF9u)
-							&& ((unsigned __int16)v23 < 0x85u || (unsigned __int16)v23 > 0x96u)
-							&& ((unsigned __int16)v23 < 0x97u || (unsigned __int16)v23 > 0xBAu)
-							&& ((unsigned __int16)v23 < 0xBEu || (unsigned __int16)v23 > 0xC0u)
-							&& ((unsigned __int16)v23 < 0xC4u || (unsigned __int16)v23 > 0xC6u)
-							&& ((unsigned __int16)v23 < 0x2Bu || (unsigned __int16)v23 > 0x2Du)
-							&& ((unsigned __int16)v23 < 0x52u || (unsigned __int16)v23 > 0x54u)
-							&& ((unsigned __int16)v23 < 4u || (unsigned __int16)v23 > 6u)
-							&& ((unsigned __int16)v23 < 0x37u || (unsigned __int16)v23 > 0x39u)
-							&& ((unsigned __int16)v23 < 0x3Au || (unsigned __int16)v23 > 0x3Cu)
-							&& ((unsigned __int16)v23 < 0x3Du || (unsigned __int16)v23 > 0x3Fu)
-							&& ((unsigned __int16)v23 < 0xFDu || (unsigned __int16)v23 > 0xFFu)
-							&& ((unsigned __int16)v23 < 0x61u || (unsigned __int16)v23 > 0x63u)
-							&& ((unsigned __int16)v23 < 0xCDu || (unsigned __int16)v23 > 0xCFu) )
-								break;
-						}
-						pParty->field_750[v12] = rand() % 258 + 1;
-					}
-				}
-			}
-			else
-			{
-				while ( 1 )
-				{
-					v24 = pParty->field_750[v12];
-					if ( (unsigned __int16)v24 < 0x73u || (unsigned __int16)v24 > 0x84u )
-					{
-						if ( ((unsigned __int16)v24 < 0xEBu || (unsigned __int16)v24 > 0xFCu)
-						&& ((unsigned __int16)v24 < 0x85u || (unsigned __int16)v24 > 0x96u)
-						&& ((unsigned __int16)v24 < 0x97u || (unsigned __int16)v24 > 0xBAu)
-						&& ((unsigned __int16)v24 < 0xBEu || (unsigned __int16)v24 > 0xC0u)
-						&& ((unsigned __int16)v24 < 0xC4u || (unsigned __int16)v24 > 0xC6u)
-						&& ((unsigned __int16)v24 < 0x2Bu || (unsigned __int16)v24 > 0x2Du)
-						&& ((unsigned __int16)v24 < 0xCDu || (unsigned __int16)v24 > 0xCFu)
-						&& ((unsigned __int16)v24 < 0x5Eu || (unsigned __int16)v24 > 0x60u)
-						&& ((unsigned __int16)v24 < 0xFDu || (unsigned __int16)v24 > 0xFFu)
-						&& ((unsigned __int16)v24 < 0x6Du || (unsigned __int16)v24 > 0x6Fu)
-						&& ((unsigned __int16)v24 < 0x61u || (unsigned __int16)v24 > 0x63u) )
-							break;
-					}
-					pParty->field_750[v12] = rand() % 258 + 1;
-				}
-			}
-			v10 = v56;
-		}
-		v25 = v10;
-		v26 = pParty->field_750[v25];
-		v27 = pParty->field_75A[v25] == v13;
-		word_F8B1A0 = pParty->field_750[v25];
-		if ( v27 )
-		{
-			//v1 = 0;
-			v27 = v26 == v13;
-			v29 = (int)pNPCTopics[351].pText;
-			if ( v27 )
-				v29 = (int)pNPCTopics[353].pText;
-			dword_F8B1A4 = (char *)v29;
-		}
-		else
-		{
-			if ( v26 != v13 )
-			{
-				party_finds_gold(100 * pMonsterStats->pInfos[(unsigned __int16)v26].uLevel, 0);
-				v28 = pParty->pPlayers;
-				do
-				{
-					v28->SetVariable(VAR_Award, 86);
-					++v28;
-				}
-				while ( (signed int)v28 < (signed int)pParty->pHirelings );
-				pParty->uNumBountiesCollected += 100 * pMonsterStats->pInfos[pParty->field_750[v25]].uLevel;
-				pParty->field_750[v25] = v13;
-				pParty->field_75A[v25] = v13;
-			}
-			//v1 = 0;
-			dword_F8B1A4 = pNPCTopics[352].pText;
-		}
-	}
-	else if ( uMessageParam == HOUSE_DIALOGUE_TOWNHALL_100 )
-	{
-		pKeyActionMap->EnterText(1, 10, v8);
-	}
-	break;
-	}
+            party_finds_gold(100 * pMonsterStats->pInfos[(unsigned __int16)pParty->monster_id_for_hunting[(int)((char *)v8->ptr_1C - 102)]].uLevel, 0);
+            for ( uint i = 0; i < 4; ++i )
+              pParty->pPlayers[i].SetVariable(VAR_Award, 86);
+            pParty->uNumBountiesCollected += 100 * pMonsterStats->pInfos[pParty->monster_id_for_hunting[(int)((char *)v8->ptr_1C - 102)]].uLevel;
+            pParty->monster_id_for_hunting[(int)((char *)v8->ptr_1C - 102)] = 0;
+            pParty->monster_for_hunting_killed[(int)((char *)v8->ptr_1C - 102)] = false;
+          }
+          bountyHunting_text = pNPCTopics[352].pText;//"!  ..."
+        }
+      }
+      else if ( uMessageParam == HOUSE_DIALOGUE_TOWNHALL_PAY_FINE )
+        pKeyActionMap->EnterText(1, 10, v8);
+      break;
+    }
     case BuildingType_Bank:
     {
       if ( dialog_menu_id >= 7 && dialog_menu_id <= 8 )
@@ -1676,7 +1525,7 @@
 			  v25 = v10;
 			  v26 = pParty->field_750[v25];
 			  v27 = pParty->field_75A[v25] == v13;
-			  word_F8B1A0 = pParty->field_750[v25];
+			  bountyHunting_monster_id_for_hunting = pParty->field_750[v25];
 			  if ( v27 )
 			  {
 				//v1 = 0;
@@ -1684,7 +1533,7 @@
 				v29 = (int)pNPCTopics[351].pText;
 				if ( v27 )
 				  v29 = (int)pNPCTopics[353].pText;
-				dword_F8B1A4 = (char *)v29;
+				bountyHunting_text = (char *)v29;
 			  }
 			  else
 			  {
@@ -1703,7 +1552,7 @@
 				  pParty->field_75A[v25] = v13;
 				}
 				//v1 = 0;
-				dword_F8B1A4 = pNPCTopics[352].pText;
+				bountyHunting_text = pNPCTopics[352].pText;
 			  }
 			}
 			else if ( uMessageParam == 100 )
@@ -1755,11 +1604,11 @@
     case HOUSE_DIALOGUE_SHOP_BUY_STANDARD:
     case HOUSE_DIALOGUE_SHOP_BUY_SPECIAL:
     {
-      if ( pParty->field_3C.field_50[(unsigned int)v8->ptr_1C] < (signed __int64)pParty->uTimePlayed )
+      if ( pParty->field_3C.Shops_next_generation_time[(unsigned int)v8->ptr_1C] < (signed __int64)pParty->uTimePlayed )
       {
         GenerateStandartShopItems();
         GenerateSpecialShopItems();
-        pParty->field_3C.field_50[window_SpeakInHouse->par1C] = pParty->uTimePlayed + (signed __int64)((double)(11059200 * (signed int)p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].field_1C) * 0.033333335);
+        pParty->field_3C.Shops_next_generation_time[window_SpeakInHouse->par1C] = pParty->uTimePlayed + (signed __int64)((double)(11059200 * (signed int)p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].field_1C) * 0.033333335);
       }
       if ( uMessageParam == HOUSE_DIALOGUE_SHOP_BUY_STANDARD )
       {
@@ -1838,8 +1687,6 @@
     {
       if( uMessageParam >= HOUSE_DIALOGUE_36 && uMessageParam <= HOUSE_DIALOGUE_GUILD_LEARN_SKILL )
       {
-        //v35 = pPlayers[uActiveCharacter];
-        //v36 = (signed __int64)(*(float *)&p2DEvents_minus1__24[13 * (unsigned int)v8->ptr_1C] * 500.0);
         v36 = (signed __int64)(p2DEvents[(unsigned int)v8->ptr_1C - 1].flt_24 * 500.0);
         v37 = v36 * (100 - pPlayers[uActiveCharacter]->GetMerchant()) / 100;
         if ( v37 < v36 / 3 )
@@ -1951,7 +1798,7 @@
     sub_421B2C_PlaceInInventory_or_DropPickedItem();
     return;
   }
-  if ( pParty->field_3C.field_50[(unsigned int)v8->ptr_1C] < (signed __int64)pParty->uTimePlayed )
+  if ( pParty->field_3C.Shops_next_generation_time[(unsigned int)v8->ptr_1C] < (signed __int64)pParty->uTimePlayed )
   {
     GenerateStandartShopItems();
     GenerateSpecialShopItems();
@@ -1962,7 +1809,7 @@
         //+ (signed __int64)((double)(11059200 * (signed int)p2DEvents_minus1[26 * (unsigned int)ptr_507BC0->ptr_1C])
         + (signed __int64)((double)(11059200 * (signed int)p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].field_1C)
                          * 0.033333335);
-    pParty->field_3C.field_50[v40] = v41;
+    pParty->field_3C.Shops_next_generation_time[v40] = v41;
    
   }
   v42 = v8->ptr_1C;
@@ -2069,11 +1916,6 @@
   unsigned int v3; // eax@1
   signed int v4; // ebx@1
   stru365_travel_info *v5; // esi@7
-  //int v6; // eax@9
-  //int v7; // eax@9
-  //int v8; // eax@12
-  //int v9; // edi@12
-  //int v10; // edx@12
   int v11; // ecx@12
   signed int v12; // esi@13
   signed int v13; // edi@14
@@ -2393,177 +2235,131 @@
 //----- (004B7911) --------------------------------------------------------
 void  TownHallDialog()
 {
-  GUIWindow *v0; // eax@4
   int v1; // eax@10
   int v2; // esi@10
-  GUIFont *v3; // ST20_4@20
-  int v4; // eax@20
-  MonsterInfo *v5; // edi@21
-  unsigned int v6; // ST20_4@21
-  char *v7; // ST1C_4@21
-  unsigned int v8; // eax@21
-  int v9; // esi@21
-  char *v10; // eax@23
-  signed int v11; // ebx@24
-  signed int i; // esi@26
-  int v13; // eax@27
-  GUIWindow *v14; // ecx@28
-  __int64 v15; // qax@28
+  signed int pStringSum; // ebx@24
   signed int v16; // ebx@28
   int v17; // ebx@28
-  unsigned __int8 v18; // sf@28
-  char **v19; // edi@29
-  GUIButton *v20; // eax@30
-  GUIButton *v21; // esi@30
-  int v22; // eax@30
+  GUIButton *pButton; // eax@30
+  int pTextHeight; // eax@30
   unsigned int v23; // ecx@30
-  unsigned __int16 v24; // ax@30
-  GUIWindow a1; // [sp+Ch] [bp-110h]@21
-  GUIWindow w; // [sp+60h] [bp-BCh]@21
-  GUIWindow _this; // [sp+B4h] [bp-68h]@1
-  int v28; // [sp+108h] [bp-14h]@1
+  unsigned __int16 pTextColor; // ax@30
+  GUIWindow window; // [sp+60h] [bp-BCh]@21
+  GUIWindow townHall_window; // [sp+B4h] [bp-68h]@1
   int v29; // [sp+10Ch] [bp-10h]@28
-  int v30; // [sp+110h] [bp-Ch]@1
   int v31; // [sp+114h] [bp-8h]@29
   GUIFont *pOutString; // [sp+118h] [bp-4h]@21
 
-  memcpy(&_this, window_SpeakInHouse, sizeof(_this));
-  _this.uFrameX = 483;
-  _this.uFrameWidth = 148;
-  _this.uFrameZ = 334;
-  v28 = TargetColor(0xFFu, 0xFFu, 0xFFu);
-  v30 = TargetColor(0xFFu, 0xFFu, 0x9Bu);
-  sprintf(pTmpBuf.data(), "%s: %d", pGlobalTXT_LocalizationStrings[605], pParty->uFine);
-  _this.DrawTitleText(pFontArrus, 0, 0x104u, v30, pTmpBuf.data(), 3u);
+  memcpy(&townHall_window, window_SpeakInHouse, sizeof(townHall_window));
+  townHall_window.uFrameX = 483;
+  townHall_window.uFrameWidth = 148;
+  townHall_window.uFrameZ = 334;
+  sprintf(pTmpBuf.data(), "%s: %d", pGlobalTXT_LocalizationStrings[605], pParty->uFine);// 
+  townHall_window.DrawTitleText(pFontArrus, 0, 260, TargetColor(0xFFu, 0xFFu, 0x9Bu), pTmpBuf.data(), 3);
   switch(dialog_menu_id)
   {
-	case HOUSE_DIALOGUE_MAIN:
-		{
-		v11 = 1;
-		pOutString = 0;
-		pShopOptions[0] = pGlobalTXT_LocalizationStrings[604];
-		if ( pParty->uFine )
-		{
-			pShopOptions[1] = pGlobalTXT_LocalizationStrings[603];
-			v11 = 2;
-		}
-		for ( i = 0; i < v11; ++i )
-		{
-			v13 = pFontArrus->CalcTextHeight(pShopOptions[i], &_this, 0, 0);
-			pOutString = (GUIFont *)((char *)pOutString + v13);
-		}
-		v29 = (100 - (signed int)pOutString) / v11;
-		v14 = pDialogueWindow;
-		v15 = 80 - v11 * (100 - (signed int)pOutString) / v11 - (signed int)pOutString;
-		v16 = v15 - HIDWORD(v15);
-		LODWORD(v15) = pDialogueWindow->pStartingPosActiveItem;
-		HIDWORD(v15) = v15 + pDialogueWindow->pNumPresenceButton;
-		v17 = (v16 >> 1) - v29 / 2 + 158;
-		v18 = -pDialogueWindow->pNumPresenceButton < 0;
-		pOutString = (GUIFont *)pDialogueWindow->pStartingPosActiveItem;
-		if ( v18 ^ __OFSUB__((int)v15, HIDWORD(v15)) )
-		{
-			v31 = 2;
-			v19 = pShopOptions.data();
-			do
-			{
-				v20 = v14->GetControl((unsigned int)pOutString);
-				v21 = v20;
-				v20->uY = v29 + v17;
-				v22 = pFontArrus->CalcTextHeight(*v19, &_this, 0, 0);
-				v23 = v21->uY;
-				v21->uHeight = v22;
-				v17 = v23 + v22 - 1;
-				v21->uW = v17;
-				v24 = v30;
-				if ( pDialogueWindow->pCurrentPosActiveItem != v31 )
-					v24 = v28;
-				_this.DrawTitleText(pFontArrus, 0, v23, v24, *v19, 3u);
-				v14 = pDialogueWindow;
-				++v31;
-				++v19;
-				pOutString = (GUIFont *)((char *)pOutString + 1);
-			}
-			while ( (signed int)pOutString < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem );
-		}
-		break;
-		}
-
-	case HOUSE_DIALOGUE_TOWNHALL_99:
-		{
-		v5 = &pMonsterStats->pInfos[word_F8B1A0];
-		v6 = TargetColor(0xFFu, 0xFFu, 0xFFu);
-		v7 = v5->pName;
-		v8 = TargetColor(0xFFu, 0xFFu, 0x9Bu);
-		sprintf(pTmpBuf.data(), "\f%05d%s\f%05d", v8, v7, v6);
-		sprintf(pTmpBuf2.data(), dword_F8B1A4, pTmpBuf.data(), 100 * v5->uLevel);
-		current_npc_text = pTmpBuf2.data();
-		memcpy(&a1, pDialogueWindow, sizeof(a1));
-		w.uFrameWidth = 458;
-		w.uFrameZ = 457;
-		pOutString = pFontArrus;
-		v9 = pFontArrus->CalcTextHeight(pTmpBuf2.data(), &w, 13, 0) + 7;
-		if ( 352 - v9 < 8 )
-		{
-			pOutString = pFontCreate;
-			v9 = pFontCreate->CalcTextHeight(current_npc_text, &w, 13, 0) + 7;
-		}
-
-		auto pTex = pIcons_LOD->GetTexture(uTextureID_Leather);
-		pRenderer->GetLeather(8, 352 - v9, pTex, pTex->uTextureHeight - v9);
-		pRenderer->DrawTextureIndexed(8, 347 - v9, pTexture_591428);
-		v10 = FitTextInAWindow(current_npc_text, pOutString, &w, 13, 0);
-		a1.DrawText(pOutString, 13, 354 - v9, 0, v10, 0, 0, 0);
-		break;
-		}
-	case HOUSE_DIALOGUE_TOWNHALL_100:
-		{
-		v0 = window_SpeakInHouse;
-		if ( window_SpeakInHouse->receives_keyboard_input_2 == WINDOW_INPUT_IN_PROGRESS)
-		{
-			sprintfex(pTmpBuf.data(), "%s\n%s", pGlobalTXT_LocalizationStrings[606], pGlobalTXT_LocalizationStrings[112]); // "Pay"   "How Much?"
-			_this.DrawTitleText(pFontArrus, 0, 0x92u, v30, pTmpBuf.data(), 3u);
-			_this.DrawTitleText(pFontArrus, 0, 0xBAu, v28, (const char *)pKeyActionMap->pPressedKeysBuffer, 3);
-			v3 = pFontArrus;
-			v4 = pFontArrus->GetLineWidth((const char *)pKeyActionMap->pPressedKeysBuffer);
-			_this.DrawFlashingInputCursor(v4 / 2 + 80, 185, v3);
-			return;
-		}
-		if ( window_SpeakInHouse->receives_keyboard_input_2 == WINDOW_INPUT_CONFIRMED)
-		{
-			v1 = atoi((const char *)pKeyActionMap->pPressedKeysBuffer);
-			v2 = v1;
-			if ( v1 <= 0 )
-			{
-				pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
-				return;
-			}
-			if ( v1 > pParty->uNumGold )
-			{
-				PlayHouseSound((unsigned int)window_SpeakInHouse->ptr_1C, HouseSound_NotEnoughMoney_TrainingSuccessful);
-				v2 = pParty->uNumGold;
-			}
-			if ( v2 > pParty->uFine )
-				v2 = pParty->uFine;
-			Party::TakeGold(v2);
-			pParty->uFine -= v2;
-			if ( pParty->uFine < 0 )
-				pParty->uFine = 0;
-			if ( uActiveCharacter )
-				pPlayers[uActiveCharacter]->PlaySound(SPEECH_81, 0);
-			v0 = window_SpeakInHouse;
-		}
-		if ( window_SpeakInHouse->receives_keyboard_input_2 == WINDOW_INPUT_CANCELLED)
-		{
-			v0->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
-			pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
-		}
-		break;
-		}
-	default:
-		{
-		break;
-		}
+    case HOUSE_DIALOGUE_MAIN:
+    {
+      pStringSum = 1;
+      pTextHeight = 0;
+      pShopOptions[0] = pGlobalTXT_LocalizationStrings[604];//  
+      if ( pParty->uFine > 0 )
+      {
+        pShopOptions[1] = pGlobalTXT_LocalizationStrings[603];// 
+        pStringSum = 2;
+      }
+      for ( uint i = 0; i < pStringSum; ++i )
+        pTextHeight += pFontArrus->CalcTextHeight(pShopOptions[i], &townHall_window, 0, 0);
+      v29 = (100 - pTextHeight) / pStringSum;
+      v16 = 80 - pStringSum * ((100 - pTextHeight) / pStringSum);
+      v17 = (v16 / 2) - v29 / 2 + 158;
+      if ( pDialogueWindow->pNumPresenceButton > 0 )
+      {
+        v31 = 2;
+        uint j = 0;
+        for ( uint i = pDialogueWindow->pStartingPosActiveItem;
+              i < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem; ++i )
+        {
+          pButton = pDialogueWindow->GetControl(i);
+          pButton->uY = v29 + v17;
+          pTextHeight = pFontArrus->CalcTextHeight(pShopOptions[j], &townHall_window, 0, 0);
+          v23 = pButton->uY;
+          pButton->uHeight = pTextHeight;
+          v17 = v23 + pTextHeight - 1;
+          pButton->uW = v17;
+          pTextColor = TargetColor(0xFFu, 0xFFu, 0x9Bu);
+          if ( pDialogueWindow->pCurrentPosActiveItem != v31 )
+            pTextColor = TargetColor(0xFFu, 0xFFu, 0xFFu);
+          townHall_window.DrawTitleText(pFontArrus, 0, v23, pTextColor, pShopOptions[j], 3);
+          ++v31;
+          ++j;
+        }
+      }
+      break;
+    }
+    case HOUSE_DIALOGUE_TOWNHALL_MESSAGE:
+    {
+      sprintf(pTmpBuf.data(), "\f%05d%s\f%05d", TargetColor(0xFFu, 0xFFu, 0x9Bu),
+      pMonsterStats->pInfos[bountyHunting_monster_id_for_hunting].pName, TargetColor(0xFFu, 0xFFu, 0xFFu));
+      sprintf(pTmpBuf2.data(), bountyHunting_text, pTmpBuf.data(), 100 * pMonsterStats->pInfos[bountyHunting_monster_id_for_hunting].uLevel);
+      current_npc_text = pTmpBuf2.data();
+      memcpy(&window, pDialogueWindow, sizeof(window));
+      window.uFrameWidth = 458;
+      window.uFrameZ = 457;
+      pOutString = pFontArrus;
+      pTextHeight = pFontArrus->CalcTextHeight(pTmpBuf2.data(), &window, 13, 0) + 7;
+      if ( 352 - pTextHeight < 8 )
+      {
+        pOutString = pFontCreate;
+        pTextHeight = pFontCreate->CalcTextHeight(current_npc_text, &window, 13, 0) + 7;
+      }
+      pRenderer->GetLeather(8, 352 - pTextHeight, pIcons_LOD->GetTexture(uTextureID_Leather), pIcons_LOD->GetTexture(uTextureID_Leather)->uTextureHeight - pTextHeight);
+      pRenderer->DrawTextureIndexed(8, 347 - pTextHeight, pTexture_591428);
+      window.DrawText(pOutString, 13, 354 - pTextHeight, 0, FitTextInAWindow(current_npc_text, pOutString, &window, 13, 0), 0, 0, 0);
+      break;
+    }
+    case HOUSE_DIALOGUE_TOWNHALL_PAY_FINE:
+    {
+      if ( window_SpeakInHouse->receives_keyboard_input_2 == WINDOW_INPUT_IN_PROGRESS)
+      {
+        sprintfex(pTmpBuf.data(), "%s\n%s", pGlobalTXT_LocalizationStrings[606], pGlobalTXT_LocalizationStrings[112]); // "Pay"   "How Much?"
+        townHall_window.DrawTitleText(pFontArrus, 0, 146, TargetColor(0xFFu, 0xFFu, 0x9Bu), pTmpBuf.data(), 3);
+        townHall_window.DrawTitleText(pFontArrus, 0, 186, TargetColor(0xFFu, 0xFFu, 0xFFu), (const char *)pKeyActionMap->pPressedKeysBuffer, 3);
+        townHall_window.DrawFlashingInputCursor(pFontArrus->GetLineWidth((const char *)pKeyActionMap->pPressedKeysBuffer) / 2 + 80, 185, pFontArrus);
+        return;
+      }
+      if ( window_SpeakInHouse->receives_keyboard_input_2 == WINDOW_INPUT_CONFIRMED)
+      {
+        v1 = atoi((const char *)pKeyActionMap->pPressedKeysBuffer);
+        v2 = atoi((const char *)pKeyActionMap->pPressedKeysBuffer);
+        if ( v1 <= 0 )
+        {
+          pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
+          return;
+        }
+        if ( v1 > pParty->uNumGold )
+        {
+          PlayHouseSound((unsigned int)window_SpeakInHouse->ptr_1C, HouseSound_NotEnoughMoney_TrainingSuccessful);
+          v2 = pParty->uNumGold;
+        }
+        if ( v2 > pParty->uFine )
+          v2 = pParty->uFine;
+        Party::TakeGold(v2);
+        pParty->uFine -= v2;
+        if ( pParty->uFine < 0 )
+          pParty->uFine = 0;
+        if ( uActiveCharacter )
+          pPlayers[uActiveCharacter]->PlaySound(SPEECH_81, 0);
+      }
+      if ( window_SpeakInHouse->receives_keyboard_input_2 == WINDOW_INPUT_CANCELLED)
+      {
+        window_SpeakInHouse->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
+        pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
+      }
+      break;
+    }
+    default:
+      break;
   }
   return;
 }
@@ -4267,7 +4063,6 @@
           v33 = _4B254D_SkillMasteryTeacher((int)v52.ptr_1C);
 LABEL_44:
           v15 = v33;
-LABEL_45:
           v16 = (GUIButton *)pInString;
           goto LABEL_49;
         }
@@ -4280,15 +4075,16 @@
         v28 = v27 - 1;
         if ( !v28 )
         {
-          v29 = (char *)&pMonsterStats + 88 * word_F8B1A0;
+          v29 = pMonsterStats->pInfos[bountyHunting_monster_id_for_hunting].pName;
           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]);
+          sprintfex(pTmpBuf2.data(), bountyHunting_text, pTmpBuf.data(), 100 * (unsigned __int8)v29[8]);
           current_npc_text = pTmpBuf2.data();
           v15 = "";
-          goto LABEL_45;
+          v16 = (GUIButton *)pInString;
+          goto LABEL_49;
         }
         if ( v28 != 10 )
           goto LABEL_41;
@@ -4330,7 +4126,8 @@
             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;
+            v16 = (GUIButton *)pInString;
+            goto LABEL_49;
           }
           v21 = v20 - 1;
           if ( !v21 )
--- a/UI/UIHouses.h	Sun Sep 08 17:07:47 2013 +0600
+++ b/UI/UIHouses.h	Sun Sep 08 17:07:58 2013 +0600
@@ -32,8 +32,8 @@
   HOUSE_DIALOGUE_LEARN_SKILLS = 96,
   HOUSE_DIALOGUE_97 = 97,
   HOUSE_DIALOGUE_98 = 98,
-  HOUSE_DIALOGUE_TOWNHALL_99 = 99,
-  HOUSE_DIALOGUE_TOWNHALL_100 = 100,
+  HOUSE_DIALOGUE_TOWNHALL_MESSAGE = 99,
+  HOUSE_DIALOGUE_TOWNHALL_PAY_FINE = 100,
   HOUSE_DIALOGUE_TAVERN_ARCOMAGE_MAIN = 101,
   HOUSE_DIALOGUE_TAVERN_ARCOMAGE_RULES = 102,
   HOUSE_DIALOGUE_TAVERN_ARCOMAGE_VICTORY_CONDITIONS = 103,
--- a/UI/UIMainMenu.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/UI/UIMainMenu.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -2,9 +2,6 @@
 #define _CRT_SECURE_NO_WARNINGS
 #endif
 
-#include <assert.h>
-
-
 #include "..\Mouse.h"
 #include "..\Keyboard.h"
 
@@ -111,14 +108,14 @@
     pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("torchB"));
     pIconsFrameTable->InitializeAnimation(pIconsFrameTable->FindIcon("torchA"));
 
-    pTextureIDs_pMapDirs[0] = pIcons_LOD->LoadTexture("MAPDIR8", TEXTURE_16BIT_PALETTE);
-    pTextureIDs_pMapDirs[1] = pIcons_LOD->LoadTexture("MAPDIR1", TEXTURE_16BIT_PALETTE);
-    pTextureIDs_pMapDirs[2] = pIcons_LOD->LoadTexture("MAPDIR2", TEXTURE_16BIT_PALETTE);
-    pTextureIDs_pMapDirs[3] = pIcons_LOD->LoadTexture("MAPDIR3", TEXTURE_16BIT_PALETTE);
-    pTextureIDs_pMapDirs[4] = pIcons_LOD->LoadTexture("MAPDIR4", TEXTURE_16BIT_PALETTE);
-    pTextureIDs_pMapDirs[5] = pIcons_LOD->LoadTexture("MAPDIR5", TEXTURE_16BIT_PALETTE);
-    pTextureIDs_pMapDirs[6] = pIcons_LOD->LoadTexture("MAPDIR6", TEXTURE_16BIT_PALETTE);
-    pTextureIDs_pMapDirs[7] = pIcons_LOD->LoadTexture("MAPDIR7", TEXTURE_16BIT_PALETTE);
+    pTextureIDs_pMapDirs[0] = pIcons_LOD->LoadTexture("MAPDIR1", TEXTURE_16BIT_PALETTE);
+    pTextureIDs_pMapDirs[1] = pIcons_LOD->LoadTexture("MAPDIR2", TEXTURE_16BIT_PALETTE);
+    pTextureIDs_pMapDirs[2] = pIcons_LOD->LoadTexture("MAPDIR3", TEXTURE_16BIT_PALETTE);
+    pTextureIDs_pMapDirs[3] = pIcons_LOD->LoadTexture("MAPDIR4", TEXTURE_16BIT_PALETTE);
+    pTextureIDs_pMapDirs[4] = pIcons_LOD->LoadTexture("MAPDIR5", TEXTURE_16BIT_PALETTE);
+    pTextureIDs_pMapDirs[5] = pIcons_LOD->LoadTexture("MAPDIR6", TEXTURE_16BIT_PALETTE);
+    pTextureIDs_pMapDirs[6] = pIcons_LOD->LoadTexture("MAPDIR7", TEXTURE_16BIT_PALETTE);
+    pTextureIDs_pMapDirs[7] = pIcons_LOD->LoadTexture("MAPDIR8", TEXTURE_16BIT_PALETTE);
 
     uTextureID_BarBlue = pIcons_LOD->LoadTexture("ib-statB", TEXTURE_16BIT_PALETTE);
     uTextureID_BarGreen = pIcons_LOD->LoadTexture("ib-statG", TEXTURE_16BIT_PALETTE);
@@ -272,7 +269,8 @@
         ptr = v0;
         pFile = pEvents_LOD->FindContainer("credits.txt", 0);
         if ( !pFile )
-            Abortf(pGlobalTXT_LocalizationStrings[63]); // "Might and Magic VII is having trouble loading files. 
+            Error(pGlobalTXT_LocalizationStrings[63]); // "Might and Magic VII is having trouble loading files. 
+
         // Please re-install to fix this problem. Note: Re-installing will not destroy your save games."
         fread(&pTexture3, 1, 0x30, pFile);
         pSize = pTexture3.uDecompressedSize;
--- a/UI/UIOptions.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/UI/UIOptions.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -1,5 +1,3 @@
-#include <assert.h>
-
 #include "..\MM7.h"
 
 #include "..\Keyboard.h"
--- a/UI/UIPartyCreation.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/UI/UIPartyCreation.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -2,9 +2,6 @@
 #define _CRT_SECURE_NO_WARNINGS
 #endif
 
-#include <assert.h>
-
-
 #include "..\Mouse.h"
 #include "..\Keyboard.h"
 
@@ -173,7 +170,7 @@
     case 2: pX = 329; break;
     case 3: pX = 488; break;
     default:
-      assert(false && "Invalid selected character");
+      Error("Invalid selected character");
   }
 
   pTextCenter = pFontCChar->AlignText_Center(640, pGlobalTXT_LocalizationStrings[51]);
@@ -811,7 +808,7 @@
         case PLAYER_SKILL_SPEAR:   player->AddItem(-1, 31); break;
         case PLAYER_SKILL_BOW:     player->AddItem(-1, 47); break;
         case PLAYER_SKILL_MACE:    player->AddItem(-1, 50); break;
-        case PLAYER_SKILL_BLASTER: assert(false); break;
+        case PLAYER_SKILL_BLASTER: Error("No blasters at startup :p");
         case PLAYER_SKILL_SHIELD:  player->AddItem(-1, 84); break;
         case PLAYER_SKILL_LEATHER: player->AddItem(-1, 66); break;
         case PLAYER_SKILL_CHAIN:   player->AddItem(-1, 71); break;
@@ -847,7 +844,7 @@
         case PLAYER_SKILL_LIGHT:
         case PLAYER_SKILL_DARK:
         case PLAYER_SKILL_DIPLOMACY:
-          assert(false);
+          Error("No dimoplacy in mm7 (yet)");
         break;
         case PLAYER_SKILL_ITEM_ID:
         case PLAYER_SKILL_REPAIR:
--- a/UI/UIPopup.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/UI/UIPopup.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -2,8 +2,6 @@
 #define _CRT_SECURE_NO_WARNINGS
 #endif
 
-#include <assert.h>
-
 #include "..\MM7.h"
 
 #include "..\Mouse.h"
@@ -284,14 +282,14 @@
     if ( uActiveCharacter )
         {
         //try to identify
-        if (!inspect_item->Identified())
+        if (!inspect_item->IsIdentified())
             {
 
             v11 = inspect_item;
             if ( pPlayers[uActiveCharacter]->CanIdentify(inspect_item) == 1 )
                 inspect_item->SetIdentified();
             v83 = SPEECH_9;
-            if ( !inspect_item->Identified() )
+            if ( !inspect_item->IsIdentified() )
                 {
                 ShowStatusBarString(pGlobalTXT_LocalizationStrings[446], 2u);//"Identify Failed"
                 }
@@ -308,12 +306,12 @@
                 }
             }
         inspect_item->UpdateTempBonus(pParty->uTimePlayed);
-        if (inspect_item->Broken())
+        if (inspect_item->IsBroken())
             {
             if ( pPlayers[uActiveCharacter]->CanRepair(inspect_item) == 1 )
                 inspect_item->uAttributes = inspect_item->uAttributes & 0xFFFFFFFD | 1;
             v83 = SPEECH_11;
-            if ( !inspect_item->Broken() )
+            if ( !inspect_item->IsBroken() )
                 v83 = SPEECH_10;
             else
                 ShowStatusBarString(pGlobalTXT_LocalizationStrings[448], 2u);//"Repair Failed"
@@ -327,7 +325,7 @@
     //v13 = _this->uAttributes;
     //v14 = _this->Identified();
     //a2.y = inspect_item->Identified();
-    if (inspect_item->Broken())
+    if (inspect_item->IsBroken())
         {
         wHintWindow.DrawMessageBox(0);
         //v15 = &;
@@ -339,7 +337,7 @@
         wHintWindow.uFrameZ = wHintWindow.uFrameX + wHintWindow.uFrameWidth - 1;
         wHintWindow.uFrameW = wHintWindow.uFrameY + wHintWindow.uFrameHeight - 1;
         pRenderer->DrawTransparentRedShade(wHintWindow.uFrameX + v78, v81 + wHintWindow.uFrameY + 30, v73);
-        if ( inspect_item->Identified())
+        if ( inspect_item->IsIdentified())
             v16 = inspect_item->GetIdentifiedName();
         else
             v16 = item_desc->pUnidentifiedName;
@@ -356,7 +354,7 @@
             }
         return;
         }
-    if (!inspect_item->Identified())
+    if (!inspect_item->IsIdentified())
         {
         wHintWindow.DrawMessageBox(0);
         pRenderer->SetTextureClipRect(wHintWindow.uFrameX + 12,  wHintWindow.uFrameY + 12,
--- a/UI/UIRest.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/UI/UIRest.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -2,9 +2,6 @@
 #define _CRT_SECURE_NO_WARNINGS
 #endif
 
-#include <assert.h>
-
-
 #include "..\GUIWindow.h"
 #include "..\GUIFont.h"
 #include "..\Party.h"
--- a/UI/UISaveLoad.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/UI/UISaveLoad.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -2,7 +2,6 @@
 #define _CRT_SECURE_NO_WARNINGS
 #endif
 
-#include <assert.h>
 #include <io.h>
 #include "..\MM7.h"
 
@@ -288,7 +287,7 @@
         uLoadGameUI_SelectedSlot = 0;
         }
     pLODFile.AllocSubIndicesAndIO(0x12C, 0);
-    assert(sizeof(SavegameHeader) == 0x64);
+    Assert(sizeof(SavegameHeader) == 0x64);
     //v3 = 0;
     for (uint i = 0; i < uNumSavegameFiles; ++i)
         {
--- a/UI/UIShops.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/UI/UIShops.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -70,7 +70,7 @@
   int v61; // eax@90
   int v62; // ecx@90
   ItemGen *pItemInShop; // esi@90
-  int v64; // eax@95
+  //int v64; // eax@95
   int all_text_height; // esi@96
   char **v66; // edi@96
   int v67; // eax@97
@@ -233,8 +233,8 @@
               pItemInShop = &pParty->SpecialItemsInShops[(int)v61][v60];
             if ( !v56 || !Str )
             {
-              v64 = pPlayer->SelectPhrasesTransaction(pItemInShop, BuildingType_WeaponShop, v61, 2);
-              v7 = BuildDialogueString((char *)pMerchantsBuyPhrases[v64], uActiveCharacter - 1, pItemInShop, (char *)window_SpeakInHouse->ptr_1C, 2, 0);
+              v7 = BuildDialogueString((char *)pMerchantsBuyPhrases[pPlayer->SelectPhrasesTransaction(pItemInShop, BuildingType_WeaponShop, v61, 2)],
+                                       uActiveCharacter - 1, pItemInShop, (char *)window_SpeakInHouse->ptr_1C, 2, 0);
               pTextHeight = pFontArrus->CalcTextHeight(v7, &dialog_window, 0, 0);
               dialog_window.DrawTitleText(pFontArrus, 0, (174 - pTextHeight) / 2 + 138, pColorWhite, v7, 3);
             }
@@ -248,7 +248,7 @@
         }
         else
         {
-          dialog_window.DrawCurrentTime( pParty->field_3C.field_50[(unsigned int)window_SpeakInHouse->ptr_1C]  - pParty->uTimePlayed);
+          dialog_window.DrawCurrentTime( pParty->field_3C.Shops_next_generation_time[(unsigned int)window_SpeakInHouse->ptr_1C] - pParty->uTimePlayed);//  7 
           pNumActiveItem = 0; //added
         }
       }
@@ -286,7 +286,7 @@
         || (pNumActiveItem = pPlayer->GetItemIDAtInventoryIndex((int *)&v106.x), !pNumActiveItem) )
         return;
       v4 = (ItemGen *)&pPlayer->pInventoryItemList[pNumActiveItem - 1];
-      if (!v4->Identified())
+      if (!v4->IsIdentified())
       {
         v10 = pPlayer->SelectPhrasesTransaction(v4, BuildingType_WeaponShop, (int)window_SpeakInHouse->ptr_1C, 4);
         v7 = BuildDialogueString((char *)pMerchantsIdentifyPhrases[v10], uActiveCharacter - 1, v4, (char *)window_SpeakInHouse->ptr_1C, 4, 0);
@@ -424,22 +424,20 @@
               pItemInShop = &pParty->SpecialItemsInShops[(int)v61][v60];//v63 = (ItemGen *)&pParty->field_C59C[v62 + 724];
             if ( !v56 || !Str )
             {
-              v64 = pPlayer->SelectPhrasesTransaction(pItemInShop, BuildingType_WeaponShop, v61, 2);
-              v7 = BuildDialogueString((char *)pMerchantsBuyPhrases[v64], uActiveCharacter - 1, pItemInShop, (char *)window_SpeakInHouse->ptr_1C, 2, 0);
-              pTextHeight = pFontArrus->CalcTextHeight(v7, &dialog_window, 0, 0);
-              dialog_window.DrawTitleText(pFontArrus, 0, (174 - pTextHeight) / 2 + 138, pColorWhite, v7, 3);
+              v7 = BuildDialogueString((char *)pMerchantsBuyPhrases[pPlayer->SelectPhrasesTransaction(pItemInShop, BuildingType_WeaponShop, v61, 2)],
+                                       uActiveCharacter - 1, pItemInShop, (char *)window_SpeakInHouse->ptr_1C, 2, 0);
+              dialog_window.DrawTitleText(pFontArrus, 0, (174 - pFontArrus->CalcTextHeight(v7, &dialog_window, 0, 0)) / 2 + 138, pColorWhite, v7, 3);
             }
             else
             {
               v7 = BuildDialogueString(pGlobalTXT_LocalizationStrings[181], uActiveCharacter - 1, pItemInShop, (char *)window_SpeakInHouse->ptr_1C, 2, 0);
-              pTextHeight = pFontArrus->CalcTextHeight(v7, &dialog_window, 0, 0);
-              dialog_window.DrawTitleText(pFontArrus, 0, (174 - pTextHeight) / 2 + 138, pColorWhite, v7, 3);
+              dialog_window.DrawTitleText(pFontArrus, 0, (174 - pFontArrus->CalcTextHeight(v7, &dialog_window, 0, 0)) / 2 + 138, pColorWhite, v7, 3);
             }
           }
         }
         else
         {
-          dialog_window.DrawCurrentTime( pParty->field_3C.field_50[(unsigned int)window_SpeakInHouse->ptr_1C]  - pParty->uTimePlayed);
+          dialog_window.DrawCurrentTime( pParty->field_3C.Shops_next_generation_time[(unsigned int)window_SpeakInHouse->ptr_1C]  - pParty->uTimePlayed);
           pNumActiveItem = 0; //added
         }
       }
@@ -769,7 +767,7 @@
         dialog_window.DrawTitleText(pFontArrus, 0, v115, pWhiteColor, v36, 3);
         return;
       }
-      dialog_window.DrawCurrentTime( pParty->field_3C.field_50[window_SpeakInHouse->par1C]- pParty->uTimePlayed);
+      dialog_window.DrawCurrentTime( pParty->field_3C.Shops_next_generation_time[window_SpeakInHouse->par1C]- pParty->uTimePlayed);
       return;
     }
     break;
@@ -841,7 +839,7 @@
         dialog_window.DrawTitleText(pFontArrus, 0, v115, pWhiteColor, v36, 3);
         return;
       }
-      dialog_window.DrawCurrentTime( pParty->field_3C.field_50[window_SpeakInHouse->par1C]- pParty->uTimePlayed);
+      dialog_window.DrawCurrentTime( pParty->field_3C.Shops_next_generation_time[window_SpeakInHouse->par1C]- pParty->uTimePlayed);
       return;
     }
     break;
@@ -920,7 +918,7 @@
             if ( v2 )
             {
               v3 = (ItemGen *)&pPlayers[uActiveCharacter]->pInventoryItemList[v2-1];
-              if (v3->Identified())
+              if (v3->IsIdentified())
                 v5 = "%24";
               else
               {
@@ -1018,7 +1016,7 @@
         while ( v104 < 8 );
         return;
       }
-      dialog_window.DrawCurrentTime(pParty->field_3C.field_50[window_SpeakInHouse->par1C]-  pParty->uTimePlayed);
+      dialog_window.DrawCurrentTime(pParty->field_3C.Shops_next_generation_time[window_SpeakInHouse->par1C]-  pParty->uTimePlayed);
       return;
     }
     break;
@@ -1351,7 +1349,7 @@
         DrawTextAtStatusBar(v65, 0);
         if ( !v109 )
         {
-          dialog_window.DrawCurrentTime( pParty->field_3C.field_50[ (unsigned int)window_SpeakInHouse->ptr_1C] - pParty->uTimePlayed);
+          dialog_window.DrawCurrentTime( pParty->field_3C.Shops_next_generation_time[ (unsigned int)window_SpeakInHouse->ptr_1C] - pParty->uTimePlayed);
           return;
         }
         v66 = pMouse->GetCursorPos(&v98);
@@ -1409,7 +1407,7 @@
          || (pNumActiveItem = pPlayer->GetItemIDAtInventoryIndex((int *)&v109), !pNumActiveItem) )
         return;
       v37 = (ItemGen *)&pPlayer->pInventoryItemList[pNumActiveItem - 1];
-      if (!v37->Identified())
+      if (!v37->IsIdentified())
       {
         v42 = pPlayer->SelectPhrasesTransaction(v37, BuildingType_AlchemistShop, (int)window_SpeakInHouse->ptr_1C, 4);
         v38 = (char *)pMerchantsIdentifyPhrases[v42];
@@ -1551,7 +1549,7 @@
         DrawTextAtStatusBar(v65, 0);
         if ( !v109 )
         {
-          dialog_window.DrawCurrentTime( pParty->field_3C.field_50[ (unsigned int)window_SpeakInHouse->ptr_1C] - pParty->uTimePlayed);
+          dialog_window.DrawCurrentTime( pParty->field_3C.Shops_next_generation_time[ (unsigned int)window_SpeakInHouse->ptr_1C] - pParty->uTimePlayed);
           return;
         }
         v66 = pMouse->GetCursorPos(&v98);
@@ -1932,7 +1930,7 @@
       DrawTextAtStatusBar(v69, 0);
       if ( !v117 )
       {
-        dialog_window.DrawCurrentTime( pParty->field_3C.field_50[(unsigned int)window_SpeakInHouse->ptr_1C] - pParty->uTimePlayed);
+        dialog_window.DrawCurrentTime( pParty->field_3C.Shops_next_generation_time[(unsigned int)window_SpeakInHouse->ptr_1C] - pParty->uTimePlayed);
         return;
       }
       v70 = pMouse->GetCursorPos(&v102);
@@ -2063,7 +2061,7 @@
       DrawTextAtStatusBar(v69, 0);
       if ( !v117 )
       {
-        dialog_window.DrawCurrentTime( pParty->field_3C.field_50[(unsigned int)window_SpeakInHouse->ptr_1C] - pParty->uTimePlayed);
+        dialog_window.DrawCurrentTime( pParty->field_3C.Shops_next_generation_time[(unsigned int)window_SpeakInHouse->ptr_1C] - pParty->uTimePlayed);
         return;
       }
       v70 = pMouse->GetCursorPos(&v102);
--- a/UI/UITransition.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/UI/UITransition.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -2,7 +2,6 @@
 #define _CRT_SECURE_NO_WARNINGS
 #endif
 
-#include <assert.h>
 #include <io.h>
 
 #include "..\mm7_data.h"
@@ -63,7 +62,7 @@
     case PartyAlignment_Good:    sprintfex(pContainer, "evt%02d-b", const_2()); break;
     case PartyAlignment_Neutral: sprintfex(pContainer, "evt%02d", const_2());   break;
     case PartyAlignment_Evil:    sprintfex(pContainer, "evt%02d-c", const_2()); break;
-    default: assert(false);
+    default: Error("Invalid alignment: %u", pParty->alignment);
   }
 
   v12 = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
@@ -129,7 +128,7 @@
     case PartyAlignment_Good:    sprintfex(pContainer, "evt%02d-b", const_2()); break;
     case PartyAlignment_Neutral: sprintfex(pContainer, "evt%02d", const_2());   break;
     case PartyAlignment_Evil:    sprintfex(pContainer, "evt%02d-c", const_2()); break;
-    default: assert(false);
+    default: Error("Invalid alignment: %u", pParty->alignment);
   }
 
   pTexture_Dialogue_Background = pIcons_LOD->LoadTexturePtr(pContainer, TEXTURE_16BIT_PALETTE);
@@ -248,7 +247,7 @@
     v4 = (212 - pFontCreate->CalcTextHeight(pTmpBuf.data(), &v8, 0, 0)) / 2 + 101;
     v8.DrawTitleText(pFontCreate, 0, v4, 0, pTmpBuf.data(), 3);
   }
-  else assert(false);
+  else Error("Troubles in da house");
 
   _unused_5B5924_is_travel_ui_drawn = true;
 }
--- a/UI/UiGame.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/UI/UiGame.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -2,8 +2,6 @@
 #define _CRT_SECURE_NO_WARNINGS
 #endif
 
-#include <assert.h>
-
 #include "..\Texture.h"
 #include "..\MM7.h"
 
@@ -33,6 +31,7 @@
 #include "..\texts.h"
 #include "UIHouses.h"
 #include "..\BSPModel.h"
+#include "..\Math.h"
 
 
 int uTextureID_GameUI_CharSelectionFrame; // 50C98C
@@ -176,7 +175,7 @@
         ++v4;
       }
       while ( (signed int)lpsz < (signed int)pNPCStats->uNumNewNPCs );*/
-      for (int i = 0; i < pNPCStats->uNumNewNPCs; ++i)
+      for ( uint i = 0; i < pNPCStats->uNumNewNPCs; ++i )
       {
         if (pNPCStats->pNewNPCData[i].Hired())
         {
@@ -349,7 +348,7 @@
   int pTextHeight; // esi@39
   GUIButton *pButton; // eax@43
   int v32; // ebx@93
-  int v35; // esi@93
+  uint v35; // esi@93
   int v38; // eax@95
   signed int v39; // esi@99
   signed int v40; // eax@102
@@ -600,7 +599,7 @@
 
   // Install Buttons( )-------- 
   v32 = 0;
-  v35 = pDialogueWindow->pStartingPosActiveItem;
+  v35 = (uint)pDialogueWindow->pStartingPosActiveItem;
   for ( uint i = v35 + pDialogueWindow->pNumPresenceButton; v35 < i; i = pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem )
   {
     pButton = pDialogueWindow->GetControl(v35);
@@ -731,7 +730,7 @@
   }
   else
   {
-    for ( uint j = 0; j < (signed int)pOutdoor->uNumBModels; ++j )
+    for ( uint j = 0; j < (uint)pOutdoor->uNumBModels; ++j )
     {
       v7 = int_get_vector_length(abs((signed)pOutdoor->pBModels[j].vBoundingCenter.x - v19),
                                  abs((signed)pOutdoor->pBModels[j].vBoundingCenter.y - v20), 0);
@@ -739,7 +738,7 @@
       {
         if ( pOutdoor->pBModels[j].uNumFaces )
         {
-          for ( uint i = 0; i < (signed int)pOutdoor->pBModels[j].uNumFaces; ++i )
+          for ( uint i = 0; i < (uint)pOutdoor->pBModels[j].uNumFaces; ++i )
           {
             pFace = &pOutdoor->pBModels[j].pFaces[i];
             if ( pFace->sCogTriggeredID )
@@ -975,10 +974,10 @@
 //----- (0041AD6E) --------------------------------------------------------
 void GameUI_DrawRightPanelItems()
 {
-  if (GameUI_RightPanel_BookFlashTimer > pParty->uTimePlayed)
+  if ( (unsigned long long)GameUI_RightPanel_BookFlashTimer > pParty->uTimePlayed )
     GameUI_RightPanel_BookFlashTimer = 0;
 
-  if (pParty->uTimePlayed - GameUI_RightPanel_BookFlashTimer > 128)
+  if ( pParty->uTimePlayed - GameUI_RightPanel_BookFlashTimer > 128 )
   {
     GameUI_RightPanel_BookFlashTimer = pParty->uTimePlayed;
     
@@ -1167,61 +1166,39 @@
   int v1; // ebx@6
   GUIWindow *pWindow; // edi@7
   GUIButton *pButton; // ecx@11
-  Player *pPlayer; // eax@19
-  char v5; // cl@19
-  unsigned int v6; // eax@19
   int v7; // ecx@19
-  __int16 v8; // fps@23
-  unsigned __int8 v9; // c0@23
-  unsigned __int8 v10; // c3@23
   enum UIMessageType pMessageType1; // esi@24
-  char *v13; // ecx@28
   int v14; // eax@41
   ItemGen *pItemGen; // ecx@44
   int v16; // ecx@46
-  const char *v17; // eax@49
   signed int v18; // eax@55
   signed int v18b;
   signed int v19; // ecx@63
   BLVFace *pFace; // eax@69
-  __int16 v21; // ax@70
-  const char *v22; // eax@72
-  LevelDecoration *v23; // ecx@75
-  LevelDecoration *v24; // esi@75
-  __int16 v25; // ax@75
-  const char *v26; // ecx@79
-  Actor *pActor; // ecx@82
+  const char *pText; // ecx@79
   char *v28; // esi@82
-  int v29; // eax@82
-  signed int v30; // ecx@88
-  const char *v31; // eax@91
-  __int16 v32; // fps@109
   enum UIMessageType pMessageType2; // esi@110
   enum UIMessageType pMessageType3; // edx@117
-  const char *v39; // [sp-8h] [bp-E8h]@20
-  char *v40; // [sp-8h] [bp-E8h]@83
-  int v41; // [sp-4h] [bp-E4h]@20
   char Str1[200]; // [sp+Ch] [bp-D4h]@129
   unsigned int pX; // [sp+D4h] [bp-Ch]@1
   unsigned int pY; // [sp+D8h] [bp-8h]@1
   unsigned int v45; // [sp+DCh] [bp-4h]@21
 
-  v13 = nullptr;
+  int interaction_distance_limit = 512;
+
   pMouse->uPointingObjectID = 0;
   pMouse->GetClickPos(&pX, &pY);
-  if ( pX < 0 || (signed int)pX > 639 || pY < 0 || (signed int)pY > 479 )//( (pX & 0x80000000u) != 0 || (signed int)pX > 639 || (pY & 0x80000000u) != 0 || (signed int)pY > 479 )
+  if ( pX < 0 || pX > 639 || pY < 0 || pY > 479 )
     return;
   if (pCurrentScreen == SCREEN_GAME)
   {
-    if ( (signed int)pX > 467 || (signed int)pY > 351 )
+    if ( pX > 467 || pY > 351 )
       goto _click_on_game_ui;
     if ( pRenderer->pRenderD3D )  // inlined mm8::4C1E01
     {
       v18 = pGame->pVisInstance->get_picked_object_zbuf_val();
-      if ( (signed int)pX < (signed int)pViewport->uScreen_TL_X
-        || (signed int)pX > (signed int)pViewport->uScreen_BR_X
-        || (signed int)pY < (signed int)pViewport->uScreen_TL_Y
-        || (signed int)pY > (signed int)pViewport->uScreen_BR_Y )
+      if ( pX < (unsigned int)pViewport->uScreen_TL_X || pX > (unsigned int)pViewport->uScreen_BR_X
+        || pY < (unsigned int)pViewport->uScreen_TL_Y || pY > (unsigned int)pViewport->uScreen_BR_Y )
         v18 = -1;
       if ( v18 == -1 )
       {
@@ -1242,13 +1219,20 @@
       v18 = pRenderer->pActiveZBuffer[pX + pSRZBufferLineOffsets[pY]];
     pMouse->uPointingObjectID = (unsigned __int16)v18;
     v19 = (signed)PID_ID(v18);
+  //For Items------------------------------------
     if (PID_TYPE(v18) == OBJECT_Item)
     {
-      v30 = v19;
-      if ( pObjectList->pObjects[pSpriteObjects[v30].uObjectDescID].uFlags & 0x10 )
+      if ( pObjectList->pObjects[pSpriteObjects[v19].uObjectDescID].uFlags & 0x10 )
       {
         pMouse->uPointingObjectID = 0;
-        uLastPointedObjectID = 1;
+        pFooterString[0] = 0;
+        bForceDrawFooter = 1;
+        uLastPointedObjectID = 0;
+        return;
+      }
+      if ( v18 >= (signed int)0x2000000u || pParty->pPickedItem.uItemID )
+      {
+        GameUI_SetFooterString(pSpriteObjects[v19].stru_24.GetDisplayName());
         if ( pMouse->uPointingObjectID == 0 )
         {
           if ( uLastPointedObjectID != 0 )
@@ -1260,10 +1244,32 @@
         uLastPointedObjectID = pMouse->uPointingObjectID;
         return;
       }
-      if ( v18 >= (signed int)0x2000000u || pParty->pPickedItem.uItemID )
+      v28 = pTmpBuf.data();
+      sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[470], pSpriteObjects[v19].stru_24.GetDisplayName());// "Get %s"
+    }
+//For Decorations----------------------------------
+    if (PID_TYPE(v18) == OBJECT_Decoration)
+    {
+      if ( !pLevelDecorations[v19].uEventID )
       {
-        v22 = pSpriteObjects[v30].stru_24.GetDisplayName();
-        GameUI_SetFooterString(v22);
+        if ( pLevelDecorations[v19].IsInteractive() )
+          pText = pNPCTopics[stru_5E4C90._decor_events[pLevelDecorations[v19]._idx_in_stru123 - 75] + 379].pTopic;
+        else
+          pText = pDecorationList->pDecorations[pLevelDecorations[v19].uDecorationDescID].field_20;
+        GameUI_SetFooterString(pText);
+        if ( pMouse->uPointingObjectID == 0 )
+        {
+          if ( uLastPointedObjectID != 0 )
+          {
+            pFooterString[0] = 0;
+            bForceDrawFooter = 1;
+          }
+        }
+        uLastPointedObjectID = pMouse->uPointingObjectID;
+        return;
+      }
+      if ( !GetEventHintString(pLevelDecorations[v19].uEventID) )
+      {
         if ( pMouse->uPointingObjectID == 0 )
         {
           if ( uLastPointedObjectID != 0 )
@@ -1275,52 +1281,36 @@
         uLastPointedObjectID = pMouse->uPointingObjectID;
         return;
       }
-      v31 = pSpriteObjects[v30].stru_24.GetDisplayName();
-      v28 = pTmpBuf.data();
-      sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[470], v31);// "Get %s"
+      GameUI_SetFooterString(GetEventHintString(pLevelDecorations[v19].uEventID));
+      if ( pMouse->uPointingObjectID == 0 )
+      {
+        if ( uLastPointedObjectID != 0 )
+        {
+          pFooterString[0] = 0;
+          bForceDrawFooter = 1;
+        }
+      }
+      uLastPointedObjectID = pMouse->uPointingObjectID;
+      return;
     }
-    else
+  //For 3D Model-------------------------------------
+    if (PID_TYPE(v18) == OBJECT_BModel)
     {
-      if (PID_TYPE(v18) != OBJECT_Actor)
+      if ( HIWORD(v18) < interaction_distance_limit )
       {
-        if (PID_TYPE(v18) == OBJECT_Decoration)
+        if ( uCurrentlyLoadedLevelType != LEVEL_Indoor)
         {
-          v23 = &pLevelDecorations[v19];
-          v24 = v23;
-          v25 = v23->field_16_event_id;
-          if ( !v25 )
+          v18b = (signed int)(unsigned __int16)v18 >> 9;
+          if ( !pOutdoor->pBModels[v18b].pFaces[v19 & 0x3F].sCogTriggeredID
+            || !GetEventHintString(pOutdoor->pBModels[v18b].pFaces[v19 & 0x3F].sCogTriggeredID) )
           {
-            if ( v23->IsInteractive() )
-              v26 = pNPCTopics[stru_5E4C90._decor_events[v24->_idx_in_stru123 - 75] + 379].pTopic;
-            else
-              v26 = pDecorationList->pDecorations[v24->uDecorationDescID].field_20;
-            GameUI_SetFooterString(v26);
-            if ( pMouse->uPointingObjectID == 0 )
-            {
-              if ( uLastPointedObjectID != 0 )
-              {
-                pFooterString[0] = 0;
-                bForceDrawFooter = 1;
-              }
-            }
-            uLastPointedObjectID = pMouse->uPointingObjectID;
+            pMouse->uPointingObjectID = 0;
+            pFooterString[0] = 0;
+            bForceDrawFooter = 1;
+            uLastPointedObjectID = 0;
             return;
           }
-          v22 = GetEventHintString(v25);
-          if ( !v22 )
-          {
-            if ( pMouse->uPointingObjectID == 0 )
-            {
-              if ( uLastPointedObjectID != 0 )
-              {
-                pFooterString[0] = 0;
-                bForceDrawFooter = 1;
-              }
-            }
-            uLastPointedObjectID = pMouse->uPointingObjectID;
-            return;
-          }
-          GameUI_SetFooterString(v22);
+          GameUI_SetFooterString(GetEventHintString(pOutdoor->pBModels[v18b].pFaces[v19 & 0x3F].sCogTriggeredID));
           if ( pMouse->uPointingObjectID == 0 )
           {
             if ( uLastPointedObjectID != 0 )
@@ -1332,75 +1322,19 @@
           uLastPointedObjectID = pMouse->uPointingObjectID;
           return;
         }
-        if (PID_TYPE(v18) == OBJECT_BModel)
+        pFace = &pIndoor->pFaces[v19];
+        if ( BYTE3(pFace->uAttributes) & 6 )
         {
-          if ( HIWORD(v18) < 512)
+          if ( !pIndoor->pFaceExtras[pFace->uFaceExtraID].uEventID
+            || !GetEventHintString(pIndoor->pFaceExtras[pFace->uFaceExtraID].uEventID) )
           {
-            if ( uCurrentlyLoadedLevelType != LEVEL_Indoor)
-            {
-              v18b = (signed int)(unsigned __int16)v18 >> 9;
-              v21 = pOutdoor->pBModels[v18b].pFaces[v19 & 0x3F].sCogTriggeredID;
-              if ( !v21 || (v22 = GetEventHintString(v21)) == 0 )
-              {
-                pMouse->uPointingObjectID = 0;
-                uLastPointedObjectID = 1;
-                if ( pMouse->uPointingObjectID == 0 )
-                {
-                  if ( uLastPointedObjectID != 0 )
-                  {
-                    pFooterString[0] = 0;
-                    bForceDrawFooter = 1;
-                  }
-                }
-                uLastPointedObjectID = pMouse->uPointingObjectID;
-                return;
-              }
-              GameUI_SetFooterString(v22);
-              if ( pMouse->uPointingObjectID == 0 )
-              {
-                if ( uLastPointedObjectID != 0 )
-                {
-                  pFooterString[0] = 0;
-                  bForceDrawFooter = 1;
-                }
-              }
-              uLastPointedObjectID = pMouse->uPointingObjectID;
-              return;
-            }
-            pFace = &pIndoor->pFaces[v19];
-            if ( BYTE3(pFace->uAttributes) & 6 )
-            {
-              v21 = pIndoor->pFaceExtras[pFace->uFaceExtraID].uEventID;
-              if ( !v21 || (v22 = GetEventHintString(v21)) == 0 )
-              {
-                pMouse->uPointingObjectID = 0;
-                uLastPointedObjectID = 1;
-                if ( pMouse->uPointingObjectID == 0 )
-                {
-                  if ( uLastPointedObjectID != 0 )
-                  {
-                    pFooterString[0] = 0;
-                    bForceDrawFooter = 1;
-                  }
-                }
-                uLastPointedObjectID = pMouse->uPointingObjectID;
-                return;
-              }
-              GameUI_SetFooterString(v22);
-              if ( pMouse->uPointingObjectID == 0 )
-              {
-                if ( uLastPointedObjectID != 0 )
-                {
-                  pFooterString[0] = 0;
-                  bForceDrawFooter = 1;
-                }
-              }
-              uLastPointedObjectID = pMouse->uPointingObjectID;
-              return;
-            }
+            pMouse->uPointingObjectID = 0;
+            pFooterString[0] = 0;
+            bForceDrawFooter = 1;
+            uLastPointedObjectID = 0;
+            return;
           }
-          pMouse->uPointingObjectID = 0;
-          uLastPointedObjectID = 1;
+          GameUI_SetFooterString(GetEventHintString(pIndoor->pFaceExtras[pFace->uFaceExtraID].uEventID));
           if ( pMouse->uPointingObjectID == 0 )
           {
             if ( uLastPointedObjectID != 0 )
@@ -1412,14 +1346,22 @@
           uLastPointedObjectID = pMouse->uPointingObjectID;
           return;
         }
+      }
+      pMouse->uPointingObjectID = 0;
+      pFooterString[0] = 0;
+      bForceDrawFooter = 1;
+      uLastPointedObjectID = 0;
+      return;
+    }
+    else
+    {
+      if (PID_TYPE(v18) != OBJECT_Actor)
+      {
         pMouse->uPointingObjectID = 0;
-        if ( pMouse->uPointingObjectID == 0 )
+        if ( uLastPointedObjectID != 0 )
         {
-          if ( uLastPointedObjectID != 0 )
-          {
-            pFooterString[0] = 0;
-            bForceDrawFooter = 1;
-          }
+          pFooterString[0] = 0;
+          bForceDrawFooter = 1;
         }
         uLastPointedObjectID = pMouse->uPointingObjectID;
         return;
@@ -1438,17 +1380,14 @@
         uLastPointedObjectID = pMouse->uPointingObjectID;
         return;
       }
-      pActor = &pActors[v19];
       v28 = pTmpBuf.data();
-      v29 = pActor->dword_000334_unique_name;
-      if ( v29 )
-        v40 = pMonsterStats->pPlaceStrings[v29];
+      if ( pActors[v19].dword_000334_unique_name )
+        pText = pMonsterStats->pPlaceStrings[pActors[v19].dword_000334_unique_name];
       else
-        v40 = pMonsterStats->pInfos[pActor->pMonsterInfo.uID].pName;
-      strncpy(pTmpBuf.data(), v40, 0x7D0u);
+        pText = pMonsterStats->pInfos[pActors[v19].pMonsterInfo.uID].pName;
+      strncpy(pTmpBuf.data(), pText, 0x7D0u);
     }
-    v26 = v28;
-    GameUI_SetFooterString(v26);
+    GameUI_SetFooterString(v28);
     if ( pMouse->uPointingObjectID == 0 )
     {
       if ( uLastPointedObjectID != 0 )
@@ -1487,8 +1426,7 @@
 				{
 				  pMessageQueue_50CBD0->AddMessage(pMessageType1, pButton->msg_param, 0);
 				}
-				v13 = pButton->pButtonName;
-				GameUI_SetFooterString(v13);
+				GameUI_SetFooterString(pButton->pButtonName);
 				uLastPointedObjectID = 1;
 				return;
 			  }
@@ -1508,8 +1446,7 @@
 					  {
 						pMessageQueue_50CBD0->AddMessage(pMessageType1, pButton->msg_param, 0);
 					  }
-					  v13 = pButton->pButtonName;
-					  GameUI_SetFooterString(v13);
+					  GameUI_SetFooterString(pButton->pButtonName);
 					  uLastPointedObjectID = 1;
 					  return;
 					//}
@@ -1518,31 +1455,16 @@
 			  }
 			  else                                  // click on skill
 			  {
-				if ( pButton->uButtonType == 3
-				  && (signed int)pX >= (signed int)pButton->uX
-				  && (signed int)pX <= (signed int)pButton->uZ
-				  && (signed int)pY >= (signed int)pButton->uY
-				  && (signed int)pY <= (signed int)pButton->uW )
-				{
-				  pPlayer = pPlayers[uActiveCharacter];
-				  v5 = LOBYTE(pPlayer->pActiveSkills[pButton->msg_param]);
-				  v6 = pPlayer->uSkillPoints;
-				  v7 = (v5 & 0x3F) + 1;
-				  if ( v6 < v7 )
-				  {
-					v41 = v7 - v6;
-					v39 = pGlobalTXT_LocalizationStrings[469];// "You need %d more Skill Points to advance here"
-				  }
-				  else
-				  {
-					v41 = v7;
-					v39 = pGlobalTXT_LocalizationStrings[468];// "Clicking here will spend %d Skill Points"
-				  }
-				  sprintf(Str1, v39, v41);
-				  v13 = Str1;
-				  GameUI_SetFooterString(v13);
-				  uLastPointedObjectID = 1;
-				  return;
+              if ( pButton->uButtonType == 3 && pX >= pButton->uX && pX <= pButton->uZ && pY >= pButton->uY && pY <= pButton->uW )
+              {
+                v7 = (LOBYTE(pPlayers[uActiveCharacter]->pActiveSkills[pButton->msg_param]) & 0x3F) + 1;
+                if ( pPlayers[uActiveCharacter]->uSkillPoints < v7 )
+                  sprintf(Str1, pGlobalTXT_LocalizationStrings[469], v7 - pPlayers[uActiveCharacter]->uSkillPoints);// "You need %d more Skill Points to advance here"
+                else
+                  sprintf(Str1, pGlobalTXT_LocalizationStrings[468], v7);// "Clicking here will spend %d Skill Points"
+                GameUI_SetFooterString(Str1);
+                uLastPointedObjectID = 1;
+                return;
 				}
 			  }
 			}
@@ -1591,8 +1513,7 @@
         return;
        }
       pItemGen = (ItemGen *)((char *)&pParty->pPickedItem + 36 * (v16 + 12 * (unsigned int)window_SpeakInHouse->ptr_1C) + 4);
-      v17 = pItemGen->GetDisplayName();
-      GameUI_SetFooterString(v17);
+      GameUI_SetFooterString(pItemGen->GetDisplayName());
       uLastPointedObjectID = 1;
       if ( pMouse->uPointingObjectID == 0 )
       {
@@ -1622,8 +1543,7 @@
         return;
       }
       pItemGen = (ItemGen *)&pPlayers[uActiveCharacter]->pInventoryItemList[v14-1];
-      v17 = pItemGen->GetDisplayName();
-      GameUI_SetFooterString(v17);
+      GameUI_SetFooterString(pItemGen->GetDisplayName());
       uLastPointedObjectID = 1;
       if ( pMouse->uPointingObjectID == 0 )
       {
@@ -1654,8 +1574,7 @@
             pMessageType3 = (UIMessageType)pButton->field_1C;
             if ( pMessageType3 == 0 ) // For books
             {
-              v13 = pButton->pButtonName;
-              GameUI_SetFooterString(v13);
+              GameUI_SetFooterString(pButton->pButtonName);
               uLastPointedObjectID = 1;
               return;
             }
@@ -1685,8 +1604,7 @@
                   if ( pMessageType2 != 0 )
                       pMessageQueue_50CBD0->AddMessage(pMessageType2, pButton->msg_param, 0);
 
-                  v13 = pButton->pButtonName;
-                  GameUI_SetFooterString(v13);
+                  GameUI_SetFooterString(pButton->pButtonName);
                   uLastPointedObjectID = 1;
                   return;
                 //}
@@ -1696,28 +1614,15 @@
           else
           {
             if ( pButton->uButtonType == 3
-              && (signed int)pX >= (signed int)pButton->uX
-              && (signed int)pX <= (signed int)pButton->uZ
-              && (signed int)pY >= (signed int)pButton->uY
-              && (signed int)pY <= (signed int)pButton->uW )
+              && pX >= pButton->uX && pX <= pButton->uZ
+              && pY >= pButton->uY && pY <= pButton->uW )
             {
-              pPlayer = pPlayers[uActiveCharacter];
-              v5 = LOBYTE(pPlayer->pActiveSkills[pButton->msg_param]);
-              v6 = pPlayer->uSkillPoints;
-              v7 = (v5 & 0x3F) + 1;
-              if ( v6 < v7 )
-              {
-                v41 = v7 - v6;
-                v39 = pGlobalTXT_LocalizationStrings[469];// "You need %d more Skill Points to advance here"
-              }
+              v7 = (LOBYTE(pPlayers[uActiveCharacter]->pActiveSkills[pButton->msg_param]) & 0x3F) + 1;
+              if ( pPlayers[uActiveCharacter]->uSkillPoints < v7 )
+                sprintf(Str1, pGlobalTXT_LocalizationStrings[469], v7 - pPlayers[uActiveCharacter]->uSkillPoints);// "You need %d more Skill Points to advance here"
               else
-              {
-                v41 = v7;
-                v39 = pGlobalTXT_LocalizationStrings[468];// "Clicking here will spend %d Skill Points"
-              }
-              sprintf(Str1, v39, v41);
-              v13 = Str1;
-              GameUI_SetFooterString(v13);
+                sprintf(Str1, pGlobalTXT_LocalizationStrings[468], v7);// "Clicking here will spend %d Skill Points"
+              GameUI_SetFooterString(Str1);
               uLastPointedObjectID = 1;
               return;
             }
@@ -1750,259 +1655,209 @@
 //----- (0044162D) --------------------------------------------------------
 void GameUI_DrawPartySpells()
 {
-    unsigned int v0; // ebp@1
-    Texture *v7; // [sp-4h] [bp-1Ch]@12
-    Texture *v9; // [sp-4h] [bp-1Ch]@21
-
-    v0 = (signed __int64)((double)GetTickCount() * 0.050000001);
-    //v1 = 0;
-    for (uint i = 0; i < 14; ++i)
-        {
-        //v2 =  byte_4E5DD8[v1];
-        if (pParty->pPartyBuffs[byte_4E5DD8[i]].uExpireTime)
-            {
-            auto tex = pIcons_LOD->GetTexture(pTextureIDs_PartyBuffIcons[i]);
-            //v3 = pTextureIDs_PartyBuffIcons[i];
-                pRenderer->_4A65CC(pPartySpellbuffsUI_XYs[i][0],
-                pPartySpellbuffsUI_XYs[i][1], tex, tex,
-                v0 + 20 * pPartySpellbuffsUI_smthns[i], 0, 63);
-            }
-        //++v1;
-        }
-    //while ( v1 < 14 );
+  unsigned int v0; // ebp@1
+  Texture *v7; // [sp-4h] [bp-1Ch]@12
+  Texture *v9; // [sp-4h] [bp-1Ch]@21
 
-    if (pCurrentScreen == SCREEN_GAME || pCurrentScreen == SCREEN_NPC_DIALOGUE)
-        {
-        if (pParty->FlyActive())
-            {
-            if ( pParty->bFlying )
-                v7 = pIcons_LOD->GetTexture(pIconsFrameTable->GetFrame(uIconIdx_FlySpell, v0)->uTextureID);
-            else
-                v7 = pIcons_LOD->GetTexture(pIconsFrameTable->GetFrame(uIconIdx_FlySpell, 0)->uTextureID);
-            if ( pRenderer->pRenderD3D )
-                pRenderer->DrawTextureIndexed(8, 8, v7);
-            else
-                pRenderer->DrawTextureTransparent(8, 8, v7);
-            }
-        if (pParty->WaterWalkActive())
-            {
-            if ( pParty->uFlags & PARTY_FLAGS_1_STANDING_ON_WATER)
-                v9 = pIcons_LOD->GetTexture(pIconsFrameTable->GetFrame(uIconIdx_WaterWalk, v0)->uTextureID);
-            else
-                v9 = pIcons_LOD->GetTexture(pIconsFrameTable->GetFrame(uIconIdx_WaterWalk, 0)->uTextureID);
-            if ( pRenderer->pRenderD3D )
-                pRenderer->DrawTextureIndexed(396u, 8u, v9);
-            else
-                pRenderer->DrawTextureTransparent(396u, 8u, v9);
-            }
-        }
-
-    for (uint i = 0; i < 4; ++i)
-        {
-        auto player = pParty->pPlayers + i;
-
-        if (player->pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].uExpireTime)
-            pRenderer->DrawTextureIndexed(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i] + 72, 427, pIcons_LOD->GetTexture(uTextureID_PlayerBuff_Hammerhands));
-        if (player->pPlayerBuffs[PLAYER_BUFF_BLESS].uExpireTime)
-            pRenderer->DrawTextureIndexed(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i] + 72, 393, pIcons_LOD->GetTexture(uTextureID_PlayerBuff_Bless));
-        if (player->pPlayerBuffs[PLAYER_BUFF_PRESERVATION].uExpireTime)
-            pRenderer->DrawTextureIndexed(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i] + 72, 410, pIcons_LOD->GetTexture(uTextureID_PlayerBuff_Preservation));
-        if (player->pPlayerBuffs[PLAYER_BUFF_PAIN_REFLECTION].uExpireTime)
-            pRenderer->DrawTextureIndexed(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i] + 72, 444, pIcons_LOD->GetTexture(uTextureID_PlayerBuff_PainReflection));
-        }
+  v0 = (signed __int64)((double)GetTickCount() * 0.050000001);
+  //v1 = 0;
+  for (uint i = 0; i < 14; ++i)
+  {
+    //v2 =  byte_4E5DD8[v1];
+    if (pParty->pPartyBuffs[byte_4E5DD8[i]].uExpireTime)
+    {
+      auto tex = pIcons_LOD->GetTexture(pTextureIDs_PartyBuffIcons[i]);
+      //v3 = pTextureIDs_PartyBuffIcons[i];
+      pRenderer->_4A65CC(pPartySpellbuffsUI_XYs[i][0],
+      pPartySpellbuffsUI_XYs[i][1], tex, tex,
+      v0 + 20 * pPartySpellbuffsUI_smthns[i], 0, 63);
     }
+    //++v1;
+  }
+  //while ( v1 < 14 );
+  if (pCurrentScreen == SCREEN_GAME || pCurrentScreen == SCREEN_NPC_DIALOGUE)
+  {
+    if (pParty->FlyActive())
+    {
+      if ( pParty->bFlying )
+        v7 = pIcons_LOD->GetTexture(pIconsFrameTable->GetFrame(uIconIdx_FlySpell, v0)->uTextureID);
+      else
+        v7 = pIcons_LOD->GetTexture(pIconsFrameTable->GetFrame(uIconIdx_FlySpell, 0)->uTextureID);
+      if ( pRenderer->pRenderD3D )
+        pRenderer->DrawTextureIndexed(8, 8, v7);
+      else
+        pRenderer->DrawTextureTransparent(8, 8, v7);
+    }
+    if ( pParty->WaterWalkActive() )
+    {
+      if ( pParty->uFlags & PARTY_FLAGS_1_STANDING_ON_WATER )
+        v9 = pIcons_LOD->GetTexture(pIconsFrameTable->GetFrame(uIconIdx_WaterWalk, v0)->uTextureID);
+      else
+        v9 = pIcons_LOD->GetTexture(pIconsFrameTable->GetFrame(uIconIdx_WaterWalk, 0)->uTextureID);
+      if ( pRenderer->pRenderD3D )
+        pRenderer->DrawTextureIndexed(396, 8, v9);
+      else
+        pRenderer->DrawTextureTransparent(396, 8, v9);
+    }
+  }
+  for (uint i = 0; i < 4; ++i)
+  {
+    if ( pParty->pPlayers[i].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].uExpireTime )
+      pRenderer->DrawTextureIndexed(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i] + 72, 427, pIcons_LOD->GetTexture(uTextureID_PlayerBuff_Hammerhands));
+    if ( pParty->pPlayers[i].pPlayerBuffs[PLAYER_BUFF_BLESS].uExpireTime )
+      pRenderer->DrawTextureIndexed(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i] + 72, 393, pIcons_LOD->GetTexture(uTextureID_PlayerBuff_Bless));
+    if ( pParty->pPlayers[i].pPlayerBuffs[PLAYER_BUFF_PRESERVATION].uExpireTime )
+      pRenderer->DrawTextureIndexed(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i] + 72, 410, pIcons_LOD->GetTexture(uTextureID_PlayerBuff_Preservation));
+    if ( pParty->pPlayers[i].pPlayerBuffs[PLAYER_BUFF_PAIN_REFLECTION].uExpireTime )
+      pRenderer->DrawTextureIndexed(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i] + 72, 444, pIcons_LOD->GetTexture(uTextureID_PlayerBuff_PainReflection));
+  }
+}
 
 //----- (004921C1) --------------------------------------------------------
 void GameUI_DrawPortraits(unsigned int _this)
 {
-    Texture *pFace; // eax@10
-    unsigned int v7; // eax@17
+    unsigned int face_expression_ID; // eax@17
     PlayerFrame *pFrame; // eax@21
-    unsigned int v9; // eax@27
-    bool v10; // eax@33
-    bool v11; // edi@40
-    bool v12; // edx@43
-    bool v13; // ecx@46
-    int v16; // eax@57
-    int v19; // eax@62
+    int pTextureID; // eax@57
     Texture *pPortrait; // [sp-4h] [bp-1Ch]@27
-    //unsigned int v22; // [sp+14h] [bp-4h]@1
+
+  if ( qword_A750D8 )
+  {
+    qword_A750D8 -= (signed int)pMiscTimer->uTimeElapsed;
+    if ( qword_A750D8 <= 0 )
+    {
+      if ( pPlayers[uSpeakingCharacter]->CanAct() )
+        pPlayers[uSpeakingCharacter]->PlaySound(PlayerSpeechID, 0);
+      qword_A750D8 = 0i64;
+    }
+  }
 
-    //v22 = _this;
-    if ( qword_A750D8 )
+  for (uint i = 0; i < 4; ++i)
+  {
+    Player* pPlayer = &pParty->pPlayers[i];
+    if ( pPlayer->IsEradicated() )
+    {
+      pPortrait = pTexture_PlayerFaceEradicated;
+      if ( pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime )
+        pRenderer->_4A6E7E(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i], 388, pPortrait);
+      else
+        pRenderer->DrawTextureTransparent(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i] + 1, 388, pPortrait);
+      if ( pPlayer->pPlayerBuffs[PLAYER_BUFF_BLESS].uExpireTime | pPlayer->pPlayerBuffs[PLAYER_BUFF_7].uExpireTime
+         | pPlayer->pPlayerBuffs[PLAYER_BUFF_8].uExpireTime | pPlayer->pPlayerBuffs[PLAYER_BUFF_13].uExpireTime
+         | pPlayer->pPlayerBuffs[PLAYER_BUFF_14].uExpireTime )
+        sub_441A4E(i);
+      continue;
+    }
+    if (pPlayer->IsDead())
+    {
+      pPortrait = pTexture_PlayerFaceDead;
+      if ( pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime )
+        pRenderer->_4A6E7E(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i], 388, pPortrait);
+      else
+        pRenderer->DrawTextureTransparent(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i] + 1, 388, pPortrait);
+      if ( pPlayer->pPlayerBuffs[PLAYER_BUFF_BLESS].uExpireTime | pPlayer->pPlayerBuffs[PLAYER_BUFF_7].uExpireTime
+         | pPlayer->pPlayerBuffs[PLAYER_BUFF_8].uExpireTime | pPlayer->pPlayerBuffs[PLAYER_BUFF_13].uExpireTime
+         | pPlayer->pPlayerBuffs[PLAYER_BUFF_14].uExpireTime )
+        sub_441A4E(i);
+      continue;
+    }
+    face_expression_ID = 0;
+    for ( uint j = 0; j < pPlayerFrameTable->uNumFrames; ++j )
+      if ( pPlayerFrameTable->pFrames[j].expression == pPlayer->expression )
+      {
+        face_expression_ID = j;
+        break;
+      }
+    if ( face_expression_ID == 0 )
+      face_expression_ID = 1;
+    if (pPlayer->expression == CHARACTER_EXPRESSION_21)
+      pFrame = pPlayerFrameTable->GetFrameBy_y(&pPlayer->_expression21_frameset, &pPlayer->_expression21_animtime, pMiscTimer->uTimeElapsed);
+    else
+      pFrame = pPlayerFrameTable->GetFrameBy_x(face_expression_ID, pPlayer->uExpressionTimePassed);
+    if (pPlayer->field_1AA2 != pFrame->uTextureID - 1 || _this )
+    {
+      pPlayer->field_1AA2 = pFrame->uTextureID - 1;
+      pPortrait = (Texture *)pTextures_PlayerFaces[i][pPlayer->field_1AA2];//pFace = (Texture *)pTextures_PlayerFaces[i][pFrame->uTextureID];
+      if ( pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime )
+        pRenderer->_4A6E7E(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i], 388, pPortrait);
+      else
+        pRenderer->DrawTextureTransparent(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i] + 1, 388, pPortrait);
+      if ( pPlayer->pPlayerBuffs[PLAYER_BUFF_BLESS].uExpireTime | pPlayer->pPlayerBuffs[PLAYER_BUFF_7].uExpireTime
+         | pPlayer->pPlayerBuffs[PLAYER_BUFF_8].uExpireTime | pPlayer->pPlayerBuffs[PLAYER_BUFF_13].uExpireTime
+         | pPlayer->pPlayerBuffs[PLAYER_BUFF_14].uExpireTime )
+        sub_441A4E(i);
+      continue;
+    }
+  }
+  if ( pParty->bTurnBasedModeOn == 1 )
+  {
+    if ( pTurnEngine->turn_stage != 1 )
+    {
+      if (PID_TYPE(pTurnEngine->pQueue[0].uPackedID) == OBJECT_Player)
+      {
+        if ( pTurnEngine->uActorQueueSize > 0 )
         {
-        qword_A750D8 -= (signed int)pMiscTimer->uTimeElapsed;
-        if ( qword_A750D8 <= 0 )
-            {
-            if ( pPlayers[uSpeakingCharacter]->CanAct() )
-                pPlayers[uSpeakingCharacter]->PlaySound(PlayerSpeechID, 0);
-            qword_A750D8 = 0i64;
-            }
-        }
-
-    for (uint i = 0; i < 4; ++i)
-        {
-        Player* pPlayer = &pParty->pPlayers[i];
-
-        if (pPlayer->IsEradicated())
+          for (uint i = 0; i < (uint)pTurnEngine->uActorQueueSize; ++i)
+          {
+            if (PID_TYPE(pTurnEngine->pQueue[i].uPackedID) != OBJECT_Player)
+              break;
+            pTextureID = dword_5079D0;
+            if ( pParty->uFlags & 0x10 )
+              pTextureID = dword_5079CC;
+            else
             {
-            pFace = pTexture_PlayerFaceEradicated;
-            pPortrait = pFace;
-            v9 = pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i];
-            if ( pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime )
-                pRenderer->_4A6E7E(v9, 0x183u, pPortrait);
-            else
-                pRenderer->DrawTextureTransparent(v9 + 1, 0x184u, pPortrait);
-            auto _v1 = 0;
-            v10 = pPlayer->pPlayerBuffs[14].uExpireTime > 0;
-            if (pPlayer->pPlayerBuffs[1].uExpireTime > 0)
-                _v1 = 1;
-            v11 = pPlayer->pPlayerBuffs[8].uExpireTime > 0;
-            v12 = pPlayer->pPlayerBuffs[7].uExpireTime > 0;
-            v13 = pPlayer->pPlayerBuffs[13].uExpireTime > 0;
-            if ( v13 | v12 | v11 | _v1 | v10 )
-                sub_441A4E(i);
-            continue;
-            }
-        if (pPlayer->IsDead())
-            {
-            pFace = pTexture_PlayerFaceDead;
-            pPortrait = pFace;
-            v9 = pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i];
-            if ( pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime )
-                pRenderer->_4A6E7E(v9, 0x183u, pPortrait);
-            else
-                pRenderer->DrawTextureTransparent(v9 + 1, 0x184u, pPortrait);
-            auto _v1 = 0;
-            v10 = pPlayer->pPlayerBuffs[14].uExpireTime > 0;
-            if (pPlayer->pPlayerBuffs[1].uExpireTime > 0)
-                _v1 = 1;
-            v11 = pPlayer->pPlayerBuffs[8].uExpireTime > 0;
-            v12 = pPlayer->pPlayerBuffs[7].uExpireTime > 0;
-            v13 = pPlayer->pPlayerBuffs[13].uExpireTime > 0;
-            if ( v13 | v12 | v11 | _v1 | v10 )
-                sub_441A4E(i);
-            continue;
+              if ( pParty->uFlags & 0x20 )
+                pTextureID = dword_5079C8;
             }
-        v7 = 0;
-        for (uint j = 0; j < pPlayerFrameTable->uNumFrames; ++j)
-            if (pPlayerFrameTable->pFrames[j].expression == pPlayer->expression)
-                {
-                v7 = j;
-                break;
-                }
-            if ( v7 == 0 )
-                v7 = 1;
-            if (pPlayer->expression == CHARACTER_EXPRESSION_21)
-                pFrame = pPlayerFrameTable->GetFrameBy_y(&pPlayer->_expression21_frameset, &pPlayer->_expression21_animtime, pMiscTimer->uTimeElapsed);
-            else
-                pFrame = pPlayerFrameTable->GetFrameBy_x(v7, pPlayer->uExpressionTimePassed);
-            if (pPlayer->field_1AA2 != pFrame->uTextureID - 1 || _this )
-                {
-                pPlayer->field_1AA2 = pFrame->uTextureID - 1;
-                pFace = (Texture *)pTextures_PlayerFaces[i][pPlayer->field_1AA2];//pFace = (Texture *)pTextures_PlayerFaces[i][pFrame->uTextureID];
-                pPortrait = pFace;
-                v9 = pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i];
-                if ( pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime )
-                    pRenderer->_4A6E7E(v9, 0x183u, pPortrait);
-                else
-                    pRenderer->DrawTextureTransparent(v9 + 1, 0x184u, pPortrait);
-                auto _v1 = 0;
-                v10 = pPlayer->pPlayerBuffs[14].uExpireTime > 0;
-                if (pPlayer->pPlayerBuffs[1].uExpireTime > 0)
-                    _v1 = 1;
-                v11 = pPlayer->pPlayerBuffs[8].uExpireTime > 0;
-                v12 = pPlayer->pPlayerBuffs[7].uExpireTime > 0;
-                v13 = pPlayer->pPlayerBuffs[13].uExpireTime > 0;
-                if ( v13 | v12 | v11 | _v1 | v10 )
-                    sub_441A4E(i);
-                continue;
-                }
+            pRenderer->DrawTextureTransparent(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[PID_ID(pTurnEngine->pQueue[i].uPackedID)] - 4, 385, pIcons_LOD->GetTexture(pTextureID));
+          }
         }
-    if ( pParty->bTurnBasedModeOn == 1 )
+      }
+    }
+  }
+  else
+  {
+    for (uint i = 0; i < 4; ++i)
+    {
+      if (pParty->pPlayers[i].CanAct() && !pParty->pPlayers[i].uTimeToRecovery)
+      {
+        pTextureID = dword_5079D0;
+        if ( pParty->uFlags & 0x10 )
+          pTextureID = dword_5079CC;
+        else
         {
-        if ( pTurnEngine->turn_stage != 1 )
-            {
-            if (PID_TYPE(pTurnEngine->pQueue[0].uPackedID) == OBJECT_Player)
-                {
-                //v14 = 0;
-                if ( pTurnEngine->uActorQueueSize > 0 )
-                    {
-                    //v15 = (char *)pTurnEngine->pQueue;
-                    for (uint i = 0; i < pTurnEngine->uActorQueueSize; ++i)
-                        {
-                        auto pElem = pTurnEngine->pQueue + i;
-
-                        if (PID_TYPE(pElem->uPackedID) != OBJECT_Player)
-                            break;
-                        v16 = dword_5079D0;
-                        if ( pParty->uFlags & 0x10 )
-                            {
-                            v16 = dword_5079CC;
-                            }
-                        else
-                            {
-                            if ( pParty->uFlags & 0x20 )
-                                v16 = dword_5079C8;
-                            }
-                        pRenderer->DrawTextureTransparent(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[PID_ID(pElem->uPackedID)] - 4, 0x181u, pIcons_LOD->GetTexture(v16));
-                        }
-                    }
-                }
-            }
+          if ( pParty->uFlags & 0x20 )
+            pTextureID = dword_5079C8;
         }
-    else
-        {
-        for (uint i = 0; i < 4; ++i)
-            {
-            auto pPlayer = pParty->pPlayers + i;
-            if (pPlayer->CanAct() && !pPlayer->uTimeToRecovery)
-                {
-                v19 = dword_5079D0;
-                if ( pParty->uFlags & 0x10 )
-                    {
-                    v19 = dword_5079CC;
-                    }
-                else
-                    {
-                    if ( pParty->uFlags & 0x20 )
-                        v19 = dword_5079C8;
-                    }
-                pRenderer->DrawTextureTransparent(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i] - 4, 0x181u, pIcons_LOD->GetTexture(v19));
-                }
-            }
-        }
+        pRenderer->DrawTextureTransparent(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i] - 4, 385, pIcons_LOD->GetTexture(pTextureID));
+      }
     }
+  }
+}
 
 //----- (00441D38) --------------------------------------------------------
 void GameUI_DrawMinimap(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW, unsigned int uZoom, unsigned int bRedrawOdmMinimap)
 {
   int uHeight; // ebx@6
-  unsigned int v14; // ebx@23
+  unsigned int pW; // ebx@23
   int v15; // eax@23
-  __int16 v17; // di@30
   double v20; // st7@30
   signed int v27; // eax@37
   unsigned __int16 *v28; // ecx@37
   signed int v29; // edi@40
-  int pObject_X; // edi@72
-  int pObject_Y; // ebx@72
-  int pActor_X; // edi@91
-  int pActor_Y; // ebx@91
-  int pDecoration_X; // edi@108
-  int pDecoration_Y; // eax@108
+  int pPoint_X; // edi@72
+  int pPoint_Y; // ebx@72
   unsigned int lPitch; // [sp+20h] [bp-34h]@1
-  unsigned int lPitcha; // [sp+20h] [bp-34h]@23
-  unsigned int v69; // [sp+24h] [bp-30h]@23
+  unsigned int pY; // [sp+20h] [bp-34h]@23
+  unsigned int pX; // [sp+24h] [bp-30h]@23
   signed int v70; // [sp+24h] [bp-30h]@37
   signed int uBluea; // [sp+28h] [bp-2Ch]@37
   int v73; // [sp+2Ch] [bp-28h]@30
   signed int uCenterY; // [sp+48h] [bp-Ch]@1
   signed int uCenterX; // [sp+4Ch] [bp-8h]@1
   signed int uWidth; // [sp+5Ch] [bp+8h]@30
-  unsigned int uWa; // [sp+60h] [bp+Ch]@23
+  unsigned int pZ; // [sp+60h] [bp+Ch]@23
   float uWb; // [sp+60h] [bp+Ch]@30
-  unsigned int uWd; // [sp+60h] [bp+Ch]@95
   unsigned int pColor;
 
   uCenterX = (uX + uZ) / 2;
@@ -2027,12 +1882,11 @@
 
   if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor)
   {
-    v17 = pIcons_LOD->pTextures[viewparams->uTextureID_LocationMap].uWidthLn2;
     auto pMapLod0 = pIcons_LOD->pTextures[viewparams->uTextureID_LocationMap].pLevelOfDetail0_prolly_alpha_mask;
     auto pPal = pIcons_LOD->pTextures[viewparams->uTextureID_LocationMap].pPalette16;
-    v73 = (1 << (v17 + 16)) / (signed int)uZoom;
-    v20 = (double)(pParty->vPosition.x + 32768) / (double)(1 << (16 - v17));
-    uWb = (double)(32768 - pParty->vPosition.y) / (double)(1 << (16 - v17));
+    v73 = (1 << (pIcons_LOD->pTextures[viewparams->uTextureID_LocationMap].uWidthLn2 + 16)) / (signed int)uZoom;
+    v20 = (double)(pParty->vPosition.x + 32768) / (double)(1 << (16 - pIcons_LOD->pTextures[viewparams->uTextureID_LocationMap].uWidthLn2));
+    uWb = (double)(32768 - pParty->vPosition.y) / (double)(1 << (16 - pIcons_LOD->pTextures[viewparams->uTextureID_LocationMap].uWidthLn2));
     switch (uZoom)
     {
       case 512:
@@ -2100,7 +1954,7 @@
     pRenderer->FillRectFast(uX, uY, uZ - uX, uHeight, 0xF);
     uNumBlueFacesInBLVMinimap = 0;
 
-    for (uint i = 0; i < pIndoor->pMapOutlines->uNumOutlines; ++i)
+    for (uint i = 0; i < (uint)pIndoor->pMapOutlines->uNumOutlines; ++i)
     {
       auto pOutline = &pIndoor->pMapOutlines->pOutlines[i];
       auto pFace1 = pIndoor->pFaces + pOutline->uFace1ID;
@@ -2109,7 +1963,6 @@
         //v10 = pIndoor->pFaces[pMapVertex->uFace2ID].uAttributes;
       if (pFace1->Visible() && pFace2->Visible())
       {
-        //v11 = pOutline->uFlags;
         if ( pOutline->uFlags & 1 )
           goto LABEL_15;
         if (pFace1->uAttributes & 0x80 || pFace2->uAttributes & 0x80)
@@ -2135,36 +1988,50 @@
         auto _a = (uZoom * (signed __int64)pIndoor->pVertices[pOutline->uVertex1ID].x);
         auto _b = ((unsigned int)((unsigned __int64)_a >> 16) << 16);
         auto _c = ((signed int)(_b - uZoom * pParty->vPosition.x) >> 16);
-        //v69 =     uCenterX + _c;
-        v69 =     uCenterX + ((signed int)(((unsigned int)((unsigned __int64)(uZoom * (signed __int64)pIndoor->pVertices[pOutline->uVertex1ID].x) >> 16) << 16) - uZoom * pParty->vPosition.x) >> 16);
-        lPitcha = uCenterY - ((signed int)(((unsigned int)((unsigned __int64)(uZoom * (signed __int64)pIndoor->pVertices[pOutline->uVertex1ID].y) >> 16) << 16) - uZoom * pParty->vPosition.y) >> 16);
-        uWa =     uCenterX + ((signed int)(((unsigned int)((unsigned __int64)(uZoom * (signed __int64)pIndoor->pVertices[pOutline->uVertex2ID].x) >> 16) << 16) - uZoom * pParty->vPosition.x) >> 16);
-        v14 =     uCenterY - ((signed int)(((unsigned int)((unsigned __int64)(uZoom * (signed __int64)pIndoor->pVertices[pOutline->uVertex2ID].y) >> 16) << 16) - uZoom * pParty->vPosition.y) >> 16);
+        pX = uCenterX + ((signed int)(((unsigned int)((unsigned __int64)(uZoom * (signed __int64)pIndoor->pVertices[pOutline->uVertex1ID].x) >> 16) << 16) - uZoom * pParty->vPosition.x) >> 16);
+        pY = uCenterY - ((signed int)(((unsigned int)((unsigned __int64)(uZoom * (signed __int64)pIndoor->pVertices[pOutline->uVertex1ID].y) >> 16) << 16) - uZoom * pParty->vPosition.y) >> 16);
+        pZ = uCenterX + ((signed int)(((unsigned int)((unsigned __int64)(uZoom * (signed __int64)pIndoor->pVertices[pOutline->uVertex2ID].x) >> 16) << 16) - uZoom * pParty->vPosition.x) >> 16);
+        pW = uCenterY - ((signed int)(((unsigned int)((unsigned __int64)(uZoom * (signed __int64)pIndoor->pVertices[pOutline->uVertex2ID].y) >> 16) << 16) - uZoom * pParty->vPosition.y) >> 16);
         v15 = abs(pOutline->sZ - pParty->vPosition.z) / 8;
         if ( v15 > 100 )
           v15 = 100;
-        pRenderer->RasterLine2D(v69, lPitcha, uWa, v14, viewparams->pPalette[-v15 + 200]);
+        pRenderer->RasterLine2D(pX, pY, pZ, pW, viewparams->pPalette[-v15 + 200]);
       }
     }
 
     for (uint i = 0; i < uNumBlueFacesInBLVMinimap; ++i)
     {
       auto pOutline = &pIndoor->pMapOutlines->pOutlines[pBlueFacesInBLVMinimapIDs[i]];
-      pRenderer->RasterLine2D(uCenterX + ((signed int)(((unsigned int)((unsigned __int64)((signed int)uZoom * (signed __int64)pIndoor->pVertices[pOutline->uVertex1ID].x) >> 16) << 16) - uZoom * pParty->vPosition.x) >> 16),
-                 uCenterY - ((signed int)(((unsigned int)((unsigned __int64)((signed int)uZoom * (signed __int64)pIndoor->pVertices[pOutline->uVertex1ID].y) >> 16) << 16) - uZoom * pParty->vPosition.y) >> 16),
-                 uCenterX + ((signed int)(((unsigned int)((unsigned __int64)((signed int)uZoom * (signed __int64)pIndoor->pVertices[pOutline->uVertex2ID].x) >> 16) << 16) - uZoom * pParty->vPosition.x) >> 16),
-                 uCenterY - ((signed int)(((unsigned int)((unsigned __int64)((signed int)uZoom * (signed __int64)pIndoor->pVertices[pOutline->uVertex2ID].y) >> 16) << 16) - uZoom * pParty->vPosition.y) >> 16),
-                 ui_game_minimap_outline_color);
+      pX = uCenterX + ((signed int)(((unsigned int)((unsigned __int64)((signed int)uZoom * (signed __int64)pIndoor->pVertices[pOutline->uVertex1ID].x) >> 16) << 16) - uZoom * pParty->vPosition.x) >> 16);
+      pY = uCenterY - ((signed int)(((unsigned int)((unsigned __int64)((signed int)uZoom * (signed __int64)pIndoor->pVertices[pOutline->uVertex1ID].y) >> 16) << 16) - uZoom * pParty->vPosition.y) >> 16);
+      pZ = uCenterX + ((signed int)(((unsigned int)((unsigned __int64)((signed int)uZoom * (signed __int64)pIndoor->pVertices[pOutline->uVertex2ID].x) >> 16) << 16) - uZoom * pParty->vPosition.x) >> 16);
+      pW = uCenterY - ((signed int)(((unsigned int)((unsigned __int64)((signed int)uZoom * (signed __int64)pIndoor->pVertices[pOutline->uVertex2ID].y) >> 16) << 16) - uZoom * pParty->vPosition.y) >> 16);
+      pRenderer->RasterLine2D(pX, pY, pZ, pW, ui_game_minimap_outline_color);
     }
   }
 
-  assert(pParty->sRotationY >= 0);
-  float angle = (pParty->sRotationY % 2048) / 2048.0f;
-  const float two_pi = 2.0f * 3.14159f;
+  //draw arrow on the minimap(include. Ritor1)
+  uint arrow_idx;
+  unsigned int rotate = pParty->sRotationY & stru_5C6E00->uDoublePiMask;
+  if ( (signed int)rotate <= 1920 )
+    arrow_idx = 6;
+  if ( (signed int)rotate < 1664 )
+    arrow_idx = 5;
+  if ( (signed int)rotate <= 1408 )
+    arrow_idx = 4;
+  if ( (signed int)rotate < 1152 )
+    arrow_idx = 3;
+  if ( (signed int)rotate <= 896 )
+    arrow_idx = 2;
+  if ( (signed int)rotate < 640 )
+    arrow_idx = 1;
+  if ( (signed int)rotate <= 384 )
+    arrow_idx = 0;
+  if ( (signed int)rotate < 128 || (signed int)rotate > 1920 )
+    arrow_idx = 7;
+  pRenderer->DrawTextureTransparent(uCenterX - 3, uCenterY - 3, pIcons_LOD->GetTexture(pTextureIDs_pMapDirs[arrow_idx]));//
 
-  uint arrow_idx = floorf(0.5f + 7 * angle);
-  pRenderer->DrawTextureTransparent(uCenterX - 3, uCenterY - 3, pIcons_LOD->GetTexture(pTextureIDs_pMapDirs[arrow_idx]));
-
+  //draw objects on the minimap
   if ( bWizardEyeActive )
   {
     if ( uWizardEyeSkillLevel >= 2 )
@@ -2174,27 +2041,27 @@
         if ( !pSpriteObjects[i].uType || !pSpriteObjects[i].uObjectDescID )
           continue;
         //if (uWizardEyeSkillLevel == 1
-        pObject_X = uCenterX + ((unsigned __int64)((pSpriteObjects[i].vPosition.x - pParty->vPosition.x) * (signed __int64)uZoom) >> 16);
-        pObject_Y = uCenterY - ((signed __int64)((pSpriteObjects[i].vPosition.y - pParty->vPosition.y) * (signed __int64)uZoom) >> 16);
-        if ( pObject_X >= pRenderer->raster_clip_x && pObject_X <= pRenderer->raster_clip_z &&
-             pObject_Y >= pRenderer->raster_clip_y && pObject_Y <= pRenderer->raster_clip_w)
+        pPoint_X = uCenterX + ((unsigned __int64)((pSpriteObjects[i].vPosition.x - pParty->vPosition.x) * (signed __int64)uZoom) >> 16);
+        pPoint_Y = uCenterY - ((signed __int64)((pSpriteObjects[i].vPosition.y - pParty->vPosition.y) * (signed __int64)uZoom) >> 16);
+        if ( pPoint_X >= pRenderer->raster_clip_x && pPoint_X <= pRenderer->raster_clip_z &&
+             pPoint_Y >= pRenderer->raster_clip_y && pPoint_Y <= pRenderer->raster_clip_w)
         {
           if (pObjectList->pObjects[pSpriteObjects[i].uObjectDescID].uFlags & OBJECT_DESC_UNPICKABLE)
           {
-            pRenderer->RasterLine2D(pObject_X, pObject_Y, pObject_X, pObject_Y, ui_game_minimap_projectile_color);
+            pRenderer->RasterLine2D(pPoint_X, pPoint_Y, pPoint_X, pPoint_Y, ui_game_minimap_projectile_color);
           }
           else if ( uZoom > 512 )
           {
-            pRenderer->RasterLine2D(pObject_X - 2, pObject_Y,     pObject_X - 2, pObject_Y + 1, ui_game_minimap_treasure_color);
-            pRenderer->RasterLine2D(pObject_X - 1, pObject_Y - 1, pObject_X - 1, pObject_Y + 1, ui_game_minimap_treasure_color);
-            pRenderer->RasterLine2D(pObject_X,     pObject_Y - 2, pObject_X,     pObject_Y + 1, ui_game_minimap_treasure_color);
-            pRenderer->RasterLine2D(pObject_X + 1, pObject_Y - 1, pObject_X + 1, pObject_Y + 1, ui_game_minimap_treasure_color);
-            pRenderer->RasterLine2D(pObject_X + 2, pObject_Y,     pObject_X + 2, pObject_Y + 1, ui_game_minimap_treasure_color);
+            pRenderer->RasterLine2D(pPoint_X - 2, pPoint_Y,     pPoint_X - 2, pPoint_Y + 1, ui_game_minimap_treasure_color);
+            pRenderer->RasterLine2D(pPoint_X - 1, pPoint_Y - 1, pPoint_X - 1, pPoint_Y + 1, ui_game_minimap_treasure_color);
+            pRenderer->RasterLine2D(pPoint_X,     pPoint_Y - 2, pPoint_X,     pPoint_Y + 1, ui_game_minimap_treasure_color);
+            pRenderer->RasterLine2D(pPoint_X + 1, pPoint_Y - 1, pPoint_X + 1, pPoint_Y + 1, ui_game_minimap_treasure_color);
+            pRenderer->RasterLine2D(pPoint_X + 2, pPoint_Y,     pPoint_X + 2, pPoint_Y + 1, ui_game_minimap_treasure_color);
           }
           else
           {
-            pRenderer->RasterLine2D(pObject_X - 1, pObject_Y - 1, pObject_X - 1, pObject_Y, ui_game_minimap_treasure_color);
-            pRenderer->RasterLine2D(pObject_X,     pObject_Y - 1, pObject_X,     pObject_Y, ui_game_minimap_treasure_color);
+            pRenderer->RasterLine2D(pPoint_X - 1, pPoint_Y - 1, pPoint_X - 1, pPoint_Y, ui_game_minimap_treasure_color);
+            pRenderer->RasterLine2D(pPoint_X,     pPoint_Y - 1, pPoint_X,     pPoint_Y, ui_game_minimap_treasure_color);
           }
         }
       }
@@ -2204,10 +2071,10 @@
       if ( pActors[i].uAIState != Removed && pActors[i].uAIState != Disabled
        && (pActors[i].uAIState == Dead || BYTE1(pActors[i].uAttributes) & 0x80) )
       {
-        pActor_X = uCenterX + ((unsigned __int64)(( pActors[i].vPosition.x - pParty->vPosition.x) * (signed __int64)(signed int)uZoom) >> 16);
-        pActor_Y = uCenterY - ((unsigned __int64)(( pActors[i].vPosition.y - pParty->vPosition.y) * (signed __int64)(signed int)uZoom) >> 16);
-        if ( pActor_X >= pRenderer->raster_clip_x && pActor_X <= pRenderer->raster_clip_z
-          && pActor_Y >= pRenderer->raster_clip_y && pActor_Y <= pRenderer->raster_clip_w )
+        pPoint_X = uCenterX + ((unsigned __int64)(( pActors[i].vPosition.x - pParty->vPosition.x) * (signed __int64)(signed int)uZoom) >> 16);
+        pPoint_Y = uCenterY - ((unsigned __int64)(( pActors[i].vPosition.y - pParty->vPosition.y) * (signed __int64)(signed int)uZoom) >> 16);
+        if ( pPoint_X >= pRenderer->raster_clip_x && pPoint_X <= pRenderer->raster_clip_z
+          && pPoint_Y >= pRenderer->raster_clip_y && pPoint_Y <= pRenderer->raster_clip_w )
         {
           pColor = ui_game_minimap_actor_friendly_color;
           if ( BYTE3(pActors[i].uAttributes) & 1 )
@@ -2216,16 +2083,16 @@
             pColor = ui_game_minimap_actor_corpse_color;
           if ( uZoom > 1024 )
           {
-            pRenderer->RasterLine2D(pActor_X - 2, pActor_Y - 1, pActor_X - 2, pActor_Y + 1, pColor);
-            pRenderer->RasterLine2D(pActor_X - 1, pActor_Y - 2, pActor_X - 1, pActor_Y + 2, pColor);
-            pRenderer->RasterLine2D(pActor_X,     pActor_Y - 2, pActor_X,     pActor_Y + 2, pColor);
-            pRenderer->RasterLine2D(pActor_X + 1, pActor_Y - 2, pActor_X + 1, pActor_Y + 2, pColor);
-            pRenderer->RasterLine2D(pActor_X + 2, pActor_Y - 1, pActor_X + 2, pActor_Y + 1, pColor);
+            pRenderer->RasterLine2D(pPoint_X - 2, pPoint_Y - 1, pPoint_X - 2, pPoint_Y + 1, pColor);
+            pRenderer->RasterLine2D(pPoint_X - 1, pPoint_Y - 2, pPoint_X - 1, pPoint_Y + 2, pColor);
+            pRenderer->RasterLine2D(pPoint_X,     pPoint_Y - 2, pPoint_X,     pPoint_Y + 2, pColor);
+            pRenderer->RasterLine2D(pPoint_X + 1, pPoint_Y - 2, pPoint_X + 1, pPoint_Y + 2, pColor);
+            pRenderer->RasterLine2D(pPoint_X + 2, pPoint_Y - 1, pPoint_X + 2, pPoint_Y + 1, pColor);
           }
           else
           {
-            pRenderer->RasterLine2D(pActor_X - 1, pActor_Y - 1, pActor_X - 1, pActor_Y, pColor);
-            pRenderer->RasterLine2D(pActor_X,     pActor_Y - 1, pActor_X,     pActor_Y, pColor);
+            pRenderer->RasterLine2D(pPoint_X - 1, pPoint_Y - 1, pPoint_X - 1, pPoint_Y, pColor);
+            pRenderer->RasterLine2D(pPoint_X,     pPoint_Y - 1, pPoint_X,     pPoint_Y, pColor);
           }
         }
       }
@@ -2234,19 +2101,19 @@
     {
       if ( pLevelDecorations[i].uFlags & 8 )
       {
-        pDecoration_X = uCenterX + ((unsigned __int64)((pLevelDecorations[i].vPosition.x - pParty->vPosition.x) * (signed __int64)(signed int)uZoom) >> 16);
-        pDecoration_Y = uCenterY - ((unsigned __int64)((pLevelDecorations[i].vPosition.y - pParty->vPosition.y) * (signed __int64)(signed int)uZoom) >> 16);
-        if ( pDecoration_X >= pRenderer->raster_clip_x && pDecoration_X <= pRenderer->raster_clip_z
-          && pDecoration_Y >= pRenderer->raster_clip_y && pDecoration_Y <= pRenderer->raster_clip_w )
+        pPoint_X = uCenterX + ((unsigned __int64)((pLevelDecorations[i].vPosition.x - pParty->vPosition.x) * (signed __int64)(signed int)uZoom) >> 16);
+        pPoint_Y = uCenterY - ((unsigned __int64)((pLevelDecorations[i].vPosition.y - pParty->vPosition.y) * (signed __int64)(signed int)uZoom) >> 16);
+        if ( pPoint_X >= pRenderer->raster_clip_x && pPoint_X <= pRenderer->raster_clip_z
+          && pPoint_Y >= pRenderer->raster_clip_y && pPoint_Y <= pRenderer->raster_clip_w )
         {
           if ( (signed int)uZoom > 512 )
           {
-            pRenderer->RasterLine2D(pDecoration_X - 1, pDecoration_Y - 1, pDecoration_X - 1, pDecoration_Y + 1, ui_game_minimap_decoration_color_1);
-            pRenderer->RasterLine2D(pDecoration_X,     pDecoration_Y - 1, pDecoration_X,     pDecoration_Y + 1, ui_game_minimap_decoration_color_1);
-            pRenderer->RasterLine2D(pDecoration_X + 1, pDecoration_Y - 1, pDecoration_X + 1, pDecoration_Y + 1, ui_game_minimap_decoration_color_1);
+            pRenderer->RasterLine2D(pPoint_X - 1, pPoint_Y - 1, pPoint_X - 1, pPoint_Y + 1, ui_game_minimap_decoration_color_1);
+            pRenderer->RasterLine2D(pPoint_X,     pPoint_Y - 1, pPoint_X,     pPoint_Y + 1, ui_game_minimap_decoration_color_1);
+            pRenderer->RasterLine2D(pPoint_X + 1, pPoint_Y - 1, pPoint_X + 1, pPoint_Y + 1, ui_game_minimap_decoration_color_1);
           }
           else
-            pRenderer->RasterLine2D(pDecoration_X, pDecoration_Y, pDecoration_X, pDecoration_Y, ui_game_minimap_decoration_color_1);
+            pRenderer->RasterLine2D(pPoint_X, pPoint_Y, pPoint_X, pPoint_Y, ui_game_minimap_decoration_color_1);
         }
       }
     }
--- a/VectorTypes.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/VectorTypes.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -1,45 +1,44 @@
+#include <utility>
+
 #include "mm7_data.h"
+#include "Math.h"
+
+//----- (004621DA) --------------------------------------------------------
+uint32_t int_get_vector_length(int32_t x, int32_t y, int32_t z)
+{
+  if (x < y)
+  {
+    std::swap(x, y);
+  }
+  if (x < z)
+  {
+    std::swap(x, z);
+  }
+  if (y < z)
+  {
+    std::swap(y, z);
+  }
+
+  return x + (11 * y >> 5) + (z >> 2);
+}
 
 //----- (0044C362) --------------------------------------------------------
-void Vec3_int_::Normalize_float()
+template <class T>
+void Vec3<T>::Normalize_float()
 {
-  //Vec3_int_ *v1; // esi@1
-  double v2; // st6@1
-  float v3; // ST20_4@1
-  double v4; // st5@1
-  float v5; // ST18_4@1
-  double v6; // st4@1
-  float v7; // ST14_4@1
-  float v8; // ST24_4@1
-  float v9; // ST20_4@1
-  double v10; // ST0C_8@1
-  float v11; // ST18_4@1
-  double v12; // ST0C_8@1
-  float v13; // ST14_4@1
-  double v14; // ST0C_8@1
+  double x = this->x;
+  double y = this->y;
+  double z = this->z;
+  double s = sqrt(x * x + y * y + z * z);
 
-  assert(false);
-  //v1 = this;
-  v2 = (double)this->x * 0.000015258789;
-  v3 = v2;
-  v4 = (double)this->y * 0.000015258789;
-  v5 = v4;
-  v6 = (double)this->z * 0.000015258789;
-  v7 = v6;
-  v8 = 1.0 / sqrt(v6 * v6 + v4 * v4 + v2 * v2);
-  v9 = v8 * v3 * 65536.0;
-  v10 = v9 + 6.7553994e15;
-  this->x = LODWORD(v10);
-  v11 = v8 * v5 * 65536.0;
-  v12 = v11 + 6.7553994e15;
-  this->y = LODWORD(v12);
-  v13 = v8 * v7 * 65536.0;
-  v14 = v13 + 6.7553994e15;
-  this->z = LODWORD(v14);
+  this->x = bankersRounding(x / s);
+  this->y = bankersRounding(y / s);
+  this->z = bankersRounding(z / s);
 }
 
 //----- (0043AA99) --------------------------------------------------------
-void __fastcall Vec3_int_::Rotate(int sDepth, int sRotY, int sRotX, Vec3_int_ v, int *outx, int *outy, int *outz)
+template <class T>
+void __fastcall Vec3<T>::Rotate(T sDepth, T sRotY, T sRotX, Vec3<T> v, T *outx, T *outy, T *outz)
 {
  float cosf_x = cosf(3.14159265f * sRotX / 1024.0f),
        sinf_x = sinf(3.14159265f * sRotX / 1024.0f),
@@ -52,9 +51,12 @@
 }
 
 //----- (0043AB61) --------------------------------------------------------
-void Vec3_int_::Normalize(int *x, int *y, int *z)
+template <class T>
+void Vec3<T>::Normalize(T *x, T *y, T *z)
 {
   *x *= 65536 / (integer_sqrt(*y * *y + *z * *z + *x * *x) | 1);
   *y *= 65536 / (integer_sqrt(*y * *y + *z * *z + *x * *x) | 1);
   *z *= 65536 / (integer_sqrt(*y * *y + *z * *z + *x * *x) | 1);
 }
+
+template Vec3<int32_t>;
--- a/VectorTypes.h	Sun Sep 08 17:07:47 2013 +0600
+++ b/VectorTypes.h	Sun Sep 08 17:07:58 2013 +0600
@@ -1,29 +1,67 @@
 #pragma once
 
-typedef unsigned __int32 uint;
+#include <cstdint>
+
+uint32_t int_get_vector_length(int32_t x, int32_t y, int32_t z);
+
+#pragma pack(push, 1)
+template <class T>
+struct Vec2
+{
+  T x;
+  T y;
+
+  inline Vec2(T a = 0, T b = 0):
+    x(a), y(b)
+  {}
+};
+#pragma pack(pop)
+
+#define Vec2_int_ Vec2<int32_t>
+#define Vec2_float_ Vec2<float>
 
 #pragma pack(push, 1)
-struct Vec2_short_
+template <class T>
+struct Vec3: public Vec2<T>
 {
-  __int16 x;
-  __int16 y;
+  T z;
+
+  inline Vec3(T a = 0, T b = 0, T c = 0):
+    Vec2(a, b), z(c)
+  {}
+
+  void Normalize_float();
+  template <class U>
+  inline uint32_t GetDistanceTo(Vec3<U> &o)
+  {
+    return int_get_vector_length(
+      abs(this->x - o.x),
+      abs(this->y - o.y),
+      abs(this->z - o.z)
+    );
+  }
+
+  static void __fastcall Rotate(T sDepth, T sRotY, T sRotX, Vec3<T> v, T *outx, T *outy, T *outz);
+  static void Normalize(T *x, T *y, T *z);
 };
 #pragma pack(pop)
 
+#define Vec3_short_ Vec3<int16_t>
+#define Vec3_int_ Vec3<int32_t>
+
 #pragma pack(push, 1)
 struct Vec3_float_
 {
   void Normalize();
-
   
-//----- (0049B32D) --------------------------------------------------------
-static Vec3_float_ *Vec3_float_::Cross(Vec3_float_ *v1, Vec3_float_ *pOut, float x, float y, float z)
-{
-  pOut->x = z * v1->y - y * v1->z;
-  pOut->y = x * v1->z - z * v1->x;
-  pOut->z = y * v1->x - x * v1->y;
-  return pOut;
-}
+  //----- (0049B32D) --------------------------------------------------------
+  static Vec3_float_ *Vec3_float_::Cross(Vec3_float_ *v1, Vec3_float_ *pOut, float x, float y, float z)
+  {
+    pOut->x = z * v1->y - y * v1->z;
+    pOut->y = x * v1->z - z * v1->x;
+    pOut->z = y * v1->x - x * v1->y;
+    return pOut;
+  }
 
   //----- (0049B02E) --------------------------------------------------------
   inline static float NegDot(Vec3_float_ *a1, Vec3_float_ *a2, float *a3)
@@ -37,54 +75,6 @@
 };
 #pragma pack(pop)
 
-
-#pragma pack(push, 1)
-struct Vec2_int_
-{
-  int x;
-  int y;
-};
-#pragma pack(pop)
-
-#pragma pack(push, 1)
-struct Vec2_float_
-{
-  float x;
-  float y;
-};
-#pragma pack(pop)
-
-
-#pragma pack(push, 1)
-struct Vec3_short_
-{
-  __int16 x;
-  __int16 y;
-  __int16 z;
-};
-#pragma pack(pop)
-
-#pragma pack(push, 1)
-struct Vec3_int_
-{
-  inline Vec3_int_():
-    x(0), y(0), z(0)
-  {}
-  inline Vec3_int_(int a, int b = 0, int c = 0):
-    x(a), y(b), z(c)
-  {}
-
-  void Normalize_float();
-
-  static void __fastcall Rotate(int sDepth, int sRotY, int sRotX, Vec3_int_ v, int *outx, int *outy, int *outz);
-  static void Normalize(int *x, int *y, int *z);
-
-  int x;
-  int y;
-  int z;
-};
-#pragma pack(pop)
-
 #pragma pack(push, 1)
 struct Vec4_int_
 {
@@ -95,11 +85,6 @@
 };
 #pragma pack(pop)
 
-
-
-
-
-
 /*   82 */
 #pragma pack(push, 1)
 struct Plane_int_
@@ -109,7 +94,6 @@
 };
 #pragma pack(pop)
 
-
 #pragma pack(push, 1)
 struct BBox_short_
 {
@@ -142,9 +126,6 @@
 };
 #pragma pack(pop)
 
-
-
-
 /*  196 */
 #pragma pack(push, 1)
 struct Matrix3x3_float_
@@ -161,4 +142,3 @@
   };
 };
 #pragma pack(pop)
-
--- a/Viewport.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/Viewport.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -95,67 +95,72 @@
 
 //----- (00443219) --------------------------------------------------------
  void ViewingParams::_443219()
-    {
-    this->sViewCenterY += 512;
-    AdjustPosition();
-    }
+ {
+   this->sViewCenterY += 512;
+   
+   AdjustPosition();
+ }
 
 //----- (00443225) --------------------------------------------------------
 void ViewingParams::_443225()
-    {
-    this->sViewCenterX -= 512;
-    AdjustPosition();
-    }
+{
+  this->sViewCenterX -= 512;
+  
+  AdjustPosition();
+}
 
 //----- (00443231) --------------------------------------------------------
 void ViewingParams::_443231()
-    {
-    this->sViewCenterY -= 512;
-    AdjustPosition();
-    }
+{
+  this->sViewCenterY -= 512;
+
+  AdjustPosition();
+}
 
 //----- (0044323D) --------------------------------------------------------
 void ViewingParams::_44323D()
-    {
-    this->sViewCenterX += 512;
-    AdjustPosition();
-    }
+{
+  this->sViewCenterX += 512;
+
+  AdjustPosition();
+}
 
 //----- (00443249) --------------------------------------------------------
 void ViewingParams::CenterOnParty()
-    {
-    int v1; // edx@1
+{
+  this->field_2C = (32768 * (__int64)this->field_2C) >> 16;
+  if (this->field_2C < 384)
+    this->field_2C = 384;
 
-    v1 = (unsigned __int64)((signed __int64)this->field_2C << 15) >> 16;
-    this->field_2C = v1;
-    if ( v1 < 384 )
-        this->field_2C = 384;
-    this->sViewCenterX = pParty->vPosition.x;
-    this->sViewCenterY = pParty->vPosition.y;
-    AdjustPosition();
-    }
+  this->sViewCenterX = pParty->vPosition.x;
+  this->sViewCenterY = pParty->vPosition.y;
+
+  AdjustPosition();
+}
 
 //----- (00443291) --------------------------------------------------------
 void ViewingParams::CenterOnParty2()
-    {
-    int v1; // edx@1
+{
     int v2; // eax@1
 
-    v1 = 2 * this->field_2C;
-    v2 = 1536;
-    this->field_2C = v1;
-    if ( uCurrentlyLoadedLevelType != LEVEL_Outdoor )
-        v2 = 3072;
-    if ( v1 > v2 )
+    if (uCurrentlyLoadedLevelType == LEVEL_Outdoor)
+      v2 = 1536;
+    else if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
+      v2 = 3072;
+    else assert(false);
+    
+    this->field_2C *= 2;
+    if (this->field_2C > v2 )
         this->field_2C = v2;
+
     this->sViewCenterX = pParty->vPosition.x;
     this->sViewCenterY = pParty->vPosition.y;
     AdjustPosition();
-    }
+}
 
 //----- (004432E7) --------------------------------------------------------
 void ViewingParams::AdjustPosition()
-    {
+{
     ViewingParams *v1; // esi@1
     int v2; // ebx@1
     signed int v3; // edx@1
@@ -167,7 +172,7 @@
 
     v1 = this;
     v2 = this->indoor_center_y;
-    v3 = 88 >> this->field_2C / 384;
+    v3 = 88 >> (this->field_2C / 384);
     v4 = (44 - v3) << 9;
     if ( v1->sViewCenterY > v2 + v4 )
         v1->sViewCenterY = v2 + v4;
@@ -295,7 +300,7 @@
           _449B7E_toggle_bit(pParty->_quest_bits, 184, 1);
         if ( pSpriteObjects[v21].stru_24.uItemID == 455 )
           _449B7E_toggle_bit(pParty->_quest_bits, 185, 1);
-        if ( !pParty->AddItem(&pSpriteObjects[v21].stru_24) )
+        if ( !pParty->AddItemToParty(&pSpriteObjects[v21].stru_24) )
           pParty->SetHoldingItem(&pSpriteObjects[v21].stru_24);
       }
       SpriteObject::OnInteraction(a2.y);
@@ -533,7 +538,7 @@
       pIcons_LOD->SyncLoadedFilesCount();
       return;
     }
-    if ( !pLevelDecorations[(signed int)(unsigned __int16)v0 >> 3].field_16_event_id )
+    if ( !pLevelDecorations[(signed int)(unsigned __int16)v0 >> 3].uEventID )
     {
       if ( pLevelDecorations[(signed int)(unsigned __int16)v0 >> 3].IsInteractive() )
       {
@@ -544,7 +549,7 @@
       }
       return;
     }
-    pEventID = pLevelDecorations[(signed int)(unsigned __int16)v0 >> 3].field_16_event_id;
+    pEventID = pLevelDecorations[(signed int)(unsigned __int16)v0 >> 3].uEventID;
   }
   if ( PID_TYPE(v0) == OBJECT_BModel && HIWORD(v0) < clickable_distance)
   {
--- a/Vis.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/Vis.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -1,5 +1,3 @@
-#include <assert.h>
-
 #include "Vis.h"
 #include "Outdoor.h"
 #include "BSPModel.h"
@@ -592,9 +590,9 @@
   Intersection->vWorldPosition.y = pRayStart->vWorldPosition.y + t * ray_dir_x;
   Intersection->vWorldPosition.z = pRayStart->vWorldPosition.z + t * ray_dir_z;
 
-  IntersectPoint.x = (signed __int64)Intersection->vWorldPosition.x;
-  IntersectPoint.y = (signed __int64)Intersection->vWorldPosition.y;
-  IntersectPoint.z = (signed __int64)Intersection->vWorldPosition.z;
+  IntersectPoint.x = Intersection->vWorldPosition.x;
+  IntersectPoint.y = Intersection->vWorldPosition.y;
+  IntersectPoint.z = Intersection->vWorldPosition.z;
 
   if ( !CheckIntersectBModel(pFace, IntersectPoint, pBModelID) )
     return false;
@@ -883,11 +881,11 @@
   int outz; // [sp+94h] [bp-Ch]@1
   int outy; // [sp+98h] [bp-8h]@1
 
-  pRotY = pIndoorCamera->sRotationY + UnprojectX((signed __int64)fMouseX);
+  pRotY = pIndoorCamera->sRotationY + UnprojectX(fMouseX);
   pStartR.z = pIndoorCamera->pos.z;
   pStartR.x = pIndoorCamera->pos.x;
   pStartR.y = pIndoorCamera->pos.y;
-  pRotX = pIndoorCamera->sRotationX + UnprojectY((signed __int64)fMouseY);
+  pRotX = pIndoorCamera->sRotationX + UnprojectY(fMouseY);
   pDepth = fixpoint_from_float(fPickDepth);
   Vec3_int_::Rotate(pDepth, pRotY, pRotX, pStartR, &outx, &outy, &outz);
 
@@ -1433,7 +1431,7 @@
           MessageBoxA(nullptr, "Unsupported \"exclusion if no event\" type in CVis::is_part_of_selection", "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Vis.cpp:207", 0);
           return true;
         }
-        if (pLevelDecorations[object_idx].uCog || pLevelDecorations[object_idx].field_16_event_id)
+        if (pLevelDecorations[object_idx].uCog || pLevelDecorations[object_idx].uEventID)
           return true;
         return pLevelDecorations[object_idx].IsInteractive();
       }
--- a/_deleted.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/_deleted.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -2120,7 +2120,7 @@
     return;
 
   array_77EC08[1999].Create_48607B(&stru_8019C8);
-  array_77EC08[1999].ptr_38->Inverse_sky_48694B();
+  array_77EC08[1999].ptr_38->_48694B_frustum_sky();
 
   if (pOutdoor->uMainTile_BitmapID == -1)
   {
@@ -2143,7 +2143,7 @@
   cos((double)pIndoorCamera->sRotationX * 0.0030664064);
   sin((double)pIndoorCamera->sRotationX * 0.0030664064);
   array_77EC08[1999].Create_48607B(&stru_8019C8);
-  array_77EC08[1999].ptr_38->Inverse_sky_48694B();
+  array_77EC08[1999].ptr_38->_48694B_frustum_sky();
 
   if (pOutdoor->uSky_TextureID == -1)
   {
@@ -12276,4 +12276,170 @@
     while ( v16 != 1 );
   }
 }
+//----- (00481EB7) --------------------------------------------------------
+void ResetPolygons()
+{
+  for (auto i = 0; i < pOutdoorCamera->uNumPolygons; ++i)
+  {
+    array_77EC08[i].prolly_head = nullptr;
+    array_77EC08[i].prolly_tail = nullptr;
+
+    array_77EC08[i].flags = 0;
+    array_77EC08[i].field_32 = 0;
+  }
+}
+//----- (00466BE5) --------------------------------------------------------
+void Abortf(const char *Format, ...)
+{
+  va_list va; // [sp+8h] [bp+8h]@1
+
+  va_start(va, Format);
+  if ( !pRenderer->bWindowMode )
+    pRenderer->ChangeBetweenWinFullscreenModes();
+  vsprintf(pTmpBuf.data(), Format, va);
+  if ( pMouse )
+    pMouse->Activate(0);
+  ClipCursor(0);
+  MessageBoxA(0, pTmpBuf.data(), "Error", 0x30u);
+  Game_DeinitializeAndTerminate(1);
+}
+//----- (00466B8C) --------------------------------------------------------
+int  AbortWithError()
+{
+  if ( !aborting_app )
+  {
+    ClipCursor(0);
+    aborting_app = 1;
+    if ( !pRenderer->bWindowMode )
+      pRenderer->ChangeBetweenWinFullscreenModes();
+    if ( MessageBoxA(0, pGlobalTXT_LocalizationStrings[176], pGlobalTXT_LocalizationStrings[59], 0x34u) == 6 )
+      SaveGame(1, 0);                           // "Internal Error"
+                                                // "Might and Magic VII has detected an internal error and will be forced to close.  Would you like us to autosave your game before closing?"
+    Game_DeinitializeAndTerminate(1);
+  }
+  return 0;
+}
+
+//----- (0046271C) --------------------------------------------------------
+void CreateDefaultBLVLevel()
+{
+  ofn.lStructSize = 0x4Cu;
+  ofn.hwndOwner = hWnd;
+  ofn.hInstance = 0;
+  ofn.lpstrFilter = "Indoor  BLV Files (*.blv)";
+  ofn.lpstrCustomFilter = 0;
+  ofn.nMaxCustFilter = 0;
+  ofn.nFilterIndex = 0;
+  ofn.lpstrFile = 0;
+  ofn.nMaxFile = 260;
+  ofn.nMaxFileTitle = 512;
+  ofn.lpstrInitialDir = "levels";
+  ofn.lpstrTitle = "Might and Magic VII - Load Which Level?";
+  ofn.Flags = 4;
+  ofn.nFileOffset = 0;
+  ofn.nFileExtension = 0;
+  ofn.lpstrDefExt = "blv";
+  ofn.lCustData = 0;
+  ofn.lpfnHook = 0;
+  ofn.lpTemplateName = 0;
+  ofn.lpstrFileTitle = pTmpBuf.data();
+}
+
+const wchar_t *UIMessage2String(UIMessageType msg)
+{
+  #define CASE(xxx) case xxx: swprintf(b, wcslen(L"%03X/%s"), L"%03X/%s", msg, L#xxx); return b;
+  static wchar_t b[256]; // bad for threads
+  switch (msg)
+  {
+    CASE(UIMSG_SelectSpell)
+    CASE(UIMSG_ChangeGameState)
+    CASE(UIMSG_Attack)
+    CASE(UIMSG_PlayArcomage)
+    CASE(UIMSG_MainMenu_ShowPartyCreationWnd)
+    CASE(UIMSG_MainMenu_ShowLoadWindow)
+    CASE(UIMSG_ShowCredits)
+    CASE(UIMSG_ExitToWindows)
+    CASE(UIMSG_PlayerCreationChangeName)
+    CASE(UIMSG_PlayerCreationClickPlus)
+    CASE(UIMSG_PlayerCreationClickMinus)
+    CASE(UIMSG_PlayerCreationSelectActiveSkill)
+    CASE(UIMSG_PlayerCreationSelectClass)
+    CASE(UIMSG_PlayerCreationClickOK)
+    CASE(UIMSG_PlayerCreationClickReset)
+    CASE(UIMSG_ClickBooksBtn)
+    CASE(UIMSG_PlayerCreationRemoveUpSkill)
+    CASE(UIMSG_PlayerCreationRemoveDownSkill)
+    CASE(UIMSG_SPellbook_ShowHightlightedSpellInfo)
+    CASE(UIMSG_LoadGame)
+    CASE(UIMSG_SaveGame)
+    CASE(UIMSG_ShowStatus_DateTime)
+    CASE(UIMSG_ShowStatus_ManaHP)
+    CASE(UIMSG_ShowStatus_Player)
+    CASE(UIMSG_Wait5Minutes)
+    CASE(UIMSG_Wait1Hour)
+    CASE(UIMSG_ShowStatus_Food)
+    CASE(UIMSG_ShowStatus_Funds)
+    CASE(UIMSG_QuickReference)
+    CASE(UIMSG_GameMenuButton)
+    CASE(UIMSG_AlreadyResting)
+    CASE(UIMSG_SelectCharacter)
+    CASE(UIMSG_ChangeSoundVolume)
+    CASE(UIMSG_ChangeMusicVolume)
+    CASE(UIMSG_Escape)
+    CASE(UIMSG_PlayerCreation_SelectAttribute)
+    CASE(UIMSG_InventoryLeftClick)
+    CASE(UIMSG_SkillUp)
+    CASE(UIMSG_GameMenu_ReturnToGame)
+    CASE(UIMSG_StartNewGame)
+    CASE(UIMSG_Game_OpenLoadGameDialog)
+    CASE(UIMSG_Game_OpenSaveGameDialog)
+    CASE(UIMSG_Game_OpenOptionsDialog)
+    CASE(UIMSG_SetGraphicsMode)
+    CASE(UIMSG_Quit)
+    CASE(UIMSG_StartHireling1Dialogue)
+    CASE(UIMSG_StartHireling2Dialogue)
+    CASE(UIMSG_SelectNPCDialogueOption)
+    CASE(UIMSG_CastSpellFromBook)
+    CASE(UIMSG_PlayerCreation_VoicePrev)
+    CASE(UIMSG_PlayerCreation_VoiceNext)
+    CASE(UIMSG_StartNPCDialogue)
+    CASE(UIMSG_ArrowUp)
+    CASE(UIMSG_DownArrow)
+    CASE(UIMSG_SaveLoadBtn)
+    CASE(UIMSG_SelectLoadSlot)
+    CASE(UIMSG_Cancel)
+    CASE(UIMSG_ExitRest)
+    CASE(UIMSG_PlayerCreation_FacePrev)
+    CASE(UIMSG_PlayerCreation_FaceNext)
+    CASE(UIMSG_CycleCharacters)
+    CASE(UIMSG_SetTurnSpeed)
+    CASE(UIMSG_ToggleWalkSound)
+    CASE(UIMSG_ChangeVoiceVolume)
+    CASE(UIMSG_ToggleShowDamage)
+    CASE(UIMSG_ScrollNPCPanel)
+    CASE(UIMSG_ShowFinalWindow)
+    CASE(UIMSG_OpenQuestBook)
+    CASE(UIMSG_OpenAutonotes)
+    CASE(UIMSG_OpenMapBook)
+    CASE(UIMSG_OpenCalendar)
+    CASE(UIMSG_OpenHistoryBook)
+    CASE(UIMSG_ToggleAlwaysRun)
+    CASE(UIMSG_ToggleFlipOnExit)
+    CASE(UIMSG_Game_Action)
+    CASE(UIMSG_RentRoom)
+    CASE(UIMSG_TransitionUI_Confirm)
+    CASE(UIMSG_OpenKeyMappingOptions)
+    CASE(UIMSG_SelectKeyPage1)
+    CASE(UIMSG_SelectKeyPage2)
+    CASE(UIMSG_ResetKeyMapping)
+    CASE(UIMSG_ChangeKeyButton)
+    CASE(UIMSG_OpenVideoOptions)
+    CASE(UIMSG_ToggleBloodsplats)
+    CASE(UIMSG_ToggleColoredLights)
+    CASE(UIMSG_ToggleTint)
+    default:
+      swprintf(b, wcslen(L"UIMSG_%03X") , L"UIMSG_%03X", msg); return b;
+  };
+  #undef CASE
+}
 */
\ No newline at end of file
--- a/mm7_1.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/mm7_1.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -9,7 +9,6 @@
 */
 
 //#include <defs.h>
-#include <assert.h>
 
 #include "Texture.h"
 #include "mm7_data.h"
@@ -49,12 +48,12 @@
 
 
 //----- (004A1780) mm6_chinese---------------------------------------------
-int fixpoint_div(int a1, int a2)
+__int64 fixpoint_div(int a1, int a2)
 {
   return ((__int64)a1 << 16) / a2;
 }
 
-int fixpoint_mul(int a1, int a2)
+__int64 fixpoint_mul(int a1, int a2)
 {
   return (((__int64)a1 << 16) * a2) >> 16;
 }
@@ -63,11 +62,18 @@
 //----- (0042EBBE) --------------------------------------------------------
 //----- (004453C0) mm6-----------------------------------------------------
 //----- (004A1760) mm6_chinese---------------------------------------------
-int fixpoint_sub0(int a1, int a2)
+__int64 fixpoint_sub0(int a1, int a2)
 {
   return ((__int64)a1 * (__int64)a2) >> 16;
 }
 
+__int64 fixpoint_dot(int x1, int x2, int y1, int y2, int z1, int z2)
+{
+  return fixpoint_sub0(x1, x2) +
+         fixpoint_sub0(y1, y2) +
+         fixpoint_sub0(z1, z2);
+}
+
 //----- (0041D20D) --------------------------------------------------------
 void __fastcall sub_41D20D_buff_remaining_time_string( int ecx0, struct GUIWindow *edx0, __int64 a3, struct GUIFont *a2 )
     {
@@ -400,7 +406,7 @@
     v4 = 225;
     v6 = 255;
   }
-  else assert(false);
+  else Error("Invalid alignment type: %u", align);
 
   uGameUIFontMain = v3;
   uGameUIFontShadow = TargetColor(v5, v4, v6);
--- a/mm7_2.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/mm7_2.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -4,9 +4,8 @@
 
 #include <io.h>
 #include <direct.h>
-#include <assert.h>
-#include <windows.h>
-
+
+#include "OSAPI.h"
 
 #include "Texture.h"
 #include "mm7_data.h"
@@ -218,81 +217,59 @@
 }
 
 //----- (004BBA85) --------------------------------------------------------
-const char *sub_4BBA85_bounties()
+void CheckBountyRespawnAndAward()
 {
-  int v0; // edi@1
-  signed __int64 v1; // qax@2
   int i; // eax@2
-  int v3; // edx@3
-  int v4; // edi@14
-  __int16 v5; // ax@14
-  char v6; // zf@14
-  Player *v7; // ebx@16
-  const char *result; // eax@19
+  int rand_monster_id; // edx@3
 
   uDialogueType = 83;
   pDialogueWindow->Release();
   pDialogueWindow = GUIWindow::Create(0, 0, 640, 350, WINDOW_MainMenu, 0, 0);
-  pBtn_ExitCancel = pDialogueWindow->CreateButton(471u, 445u, 169u, 35u, 1, 0, UIMSG_Escape, 0, 0, pGlobalTXT_LocalizationStrings[34],// "Cancel"
+  pBtn_ExitCancel = pDialogueWindow->CreateButton(471, 445, 169, 35, 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);
-  pDialogueWindow->CreateButton(480u, 160u, 140u, 30u, 1, 0, UIMSG_0, 0x53u, 0, "", 0);
+  pDialogueWindow->CreateButton(480, 160, 140, 30, 1, 0, UIMSG_0, 83, 0, "", 0);
   pDialogueWindow->_41D08F_set_keyboard_control_group(1, 1, 0, 2);
   dialog_menu_id = HOUSE_DIALOGUE_OTHER;
-  v0 = (int)((char *)window_SpeakInHouse->ptr_1C - 102);
-  if ( (signed __int64)__PAIR__(pParty->field_3C.field_0[2 * v0 + 1], pParty->field_3C.field_0[2 * v0]) < (signed __int64)pParty->uTimePlayed )
-  {
-    pParty->field_75A[v0] = 0;
-    __debugbreak(); // starting year-related constant here;
-    v1 = (signed __int64)((double)(0x12750000 * (pParty->uCurrentMonth + 12i64 * pParty->uCurrentYear - 14015))
-                        * 0.033333335);
-    pParty->field_3C.field_0[2 * v0] = v1;
-    pParty->field_3C.field_0[2 * v0 + 1] = HIDWORD(v1);
+  //get new monster for hunting
+  if ( pParty->field_3C.bountyHunting_next_generation_time[(int)((char *)window_SpeakInHouse->ptr_1C - 102)] < (signed __int64)pParty->uTimePlayed )
+  {
+    pParty->monster_for_hunting_killed[(int)((char *)window_SpeakInHouse->ptr_1C - 102)] = false;
+    pParty->field_3C.bountyHunting_next_generation_time[(int)((char *)window_SpeakInHouse->ptr_1C - 102)] = (signed __int64)((double)(0x12750000 * (pParty->uCurrentMonth + 12i64 * pParty->uCurrentYear - 14015)) * 0.033333335);
     for ( i = rand(); ; i = rand() )
     {
-      v3 = i % 258 + 1;
-      pParty->field_750[v0] = v3;
-      if ( (unsigned __int16)v3 < 0x73u || (unsigned __int16)v3 > 0x84u )
+      rand_monster_id = i % 258 + 1;
+      pParty->monster_id_for_hunting[(int)((char *)window_SpeakInHouse->ptr_1C - 102)] = rand_monster_id;
+      if ( (unsigned __int16)rand_monster_id < 0x73u || (unsigned __int16)rand_monster_id > 0x84u )
       {
-        if ( ((unsigned __int16)v3 < 0xEBu || (unsigned __int16)v3 > 0xFCu)
-          && ((unsigned __int16)v3 < 0x85u || (unsigned __int16)v3 > 0x96u)
-          && ((unsigned __int16)v3 < 0x97u || (unsigned __int16)v3 > 0xBAu)
-          && ((unsigned __int16)v3 < 0xC4u || (unsigned __int16)v3 > 0xC6u) )
+        if ( ((unsigned __int16)rand_monster_id < 0xEBu || (unsigned __int16)rand_monster_id > 0xFCu)
+          && ((unsigned __int16)rand_monster_id < 0x85u || (unsigned __int16)rand_monster_id > 0x96u)
+          && ((unsigned __int16)rand_monster_id < 0x97u || (unsigned __int16)rand_monster_id > 0xBAu)
+          && ((unsigned __int16)rand_monster_id < 0xC4u || (unsigned __int16)rand_monster_id > 0xC6u) )
           break;
       }
     }
   }
-  v4 = v0;
-  v5 = pParty->field_750[v4];
-  v6 = pParty->field_75A[v4] == 0;
-  word_F8B1A0 = pParty->field_750[v4];
-  if ( v6 )
-  {
-    v6 = v5 == 0;
-    result = pNPCTopics[351].pText;
-    if ( v6 )
-      result = pNPCTopics[353].pText;
-  }
-  else
-  {
-    if ( v5 )
+  bountyHunting_monster_id_for_hunting = pParty->monster_id_for_hunting[(int)((char *)window_SpeakInHouse->ptr_1C - 102)];
+  if ( !pParty->monster_for_hunting_killed[(int)((char *)window_SpeakInHouse->ptr_1C - 102)] )
+  {
+    bountyHunting_text = pNPCTopics[351].pText;
+    if ( !pParty->monster_id_for_hunting[(int)((char *)window_SpeakInHouse->ptr_1C - 102)] )
+      bountyHunting_text = pNPCTopics[353].pText;
+  }
+  else//get prize
+  {
+    if ( pParty->monster_id_for_hunting[(int)((char *)window_SpeakInHouse->ptr_1C - 102)] )
     {
-      party_finds_gold(100 * pMonsterStats->pInfos[(unsigned __int16)v5].uLevel, 0);
-      v7 = pParty->pPlayers;
-      do
-      {
-        v7->SetVariable(VAR_Award, 86);
-        ++v7;
-      }
-      while ( (signed int)v7 < (signed int)pParty->pHirelings );
-      pParty->uNumBountiesCollected += 100 * pMonsterStats->pInfos[pParty->field_750[v4]].uLevel;
-      pParty->field_750[v4] = 0;
-      pParty->field_75A[v4] = 0;
+      party_finds_gold(100 * pMonsterStats->pInfos[(unsigned __int16)pParty->monster_id_for_hunting[(int)((char *)window_SpeakInHouse->ptr_1C - 102)]].uLevel, 0);
+      for ( uint i = 0; i < 4; ++i )
+        pParty->pPlayers[i].SetVariable(VAR_Award, 86);
+      pParty->uNumBountiesCollected += 100 * pMonsterStats->pInfos[pParty->monster_id_for_hunting[(int)((char *)window_SpeakInHouse->ptr_1C - 102)]].uLevel;
+      pParty->monster_id_for_hunting[(int)((char *)window_SpeakInHouse->ptr_1C - 102)] = 0;
+      pParty->monster_for_hunting_killed[(int)((char *)window_SpeakInHouse->ptr_1C - 102)] = false;
     }
-    result = pNPCTopics[352].pText;
-  }
-  dword_F8B1A4 = (char *)result;
-  return result;
+    bountyHunting_text = pNPCTopics[352].pText;
+  }
 }
 
 //----- (004BBCDD) --------------------------------------------------------
@@ -334,7 +311,7 @@
       {
         uDialogueType = 91;
         v4 = pParty->pPlayers;
-        ++*((char *)&pParty->field_75A[3] + (unsigned __int8)pParty->field_7B5_in_arena_quest + 1);
+        ++*((char *)&pParty->monster_for_hunting_killed[3] + (unsigned __int8)pParty->field_7B5_in_arena_quest + 1);
         do
         {
           v4->SetVariable(VAR_Award, (unsigned __int8)pParty->field_7B5_in_arena_quest + 3);
@@ -707,7 +684,7 @@
   char *v9; // eax@14
   unsigned int v10; // eax@25
   GUIWindow pWindow; // [sp+34h] [bp-9Ch]@1
-  MSG Msg; // [sp+88h] [bp-48h]@22
+  //MSG Msg; // [sp+88h] [bp-48h]@22
   unsigned int v14; // [sp+A4h] [bp-2Ch]@5
   void *v15; // [sp+A8h] [bp-28h]@1
   char *pInString; // [sp+ACh] [bp-24h]@5
@@ -827,15 +804,12 @@
     LODWORD(v23) = GetTickCount() + 5000;
     while ( (unsigned int)v23 > GetTickCount() )
       ;
-    while ( 1 )
+    for (MSG msg; PeekMessage(&msg, 0, 0, 0, PM_REMOVE);)
     {
-      v10 = PeekMessageA(&Msg, 0, 0, 0, 1u);
-      if ( !v10 )
-        break;
-      if ( Msg.message == 18 )
+      if (msg.message == WM_QUIT)
         Game_DeinitializeAndTerminate(0);
-      TranslateMessage(&Msg);
-      DispatchMessageA(&Msg);
+      TranslateMessage(&msg);
+      DispatchMessage(&msg);
     }
     if ( pMessageQueue_50CBD0->uNumMessages )
     {
@@ -846,12 +820,12 @@
     pKeyActionMap->uLastKeyPressed = 0;
     do
     {
-      while ( PeekMessageA(&Msg, 0, 0, 0, 1u) )
+      for (MSG msg; PeekMessage(&msg, 0, 0, 0, PM_REMOVE);)
       {
-        if ( Msg.message == 18 )
+        if (msg.message == WM_QUIT)
           Game_DeinitializeAndTerminate(0);
-        TranslateMessage(&Msg);
-        DispatchMessageA(&Msg);
+        TranslateMessage(&msg);
+        DispatchMessage(&msg);
       }
     }
     while ( !pKeyActionMap->uLastKeyPressed );
@@ -1786,7 +1760,7 @@
   {
     auto decor = &pLevelDecorations[i];
 
-    if (!decor->field_16_event_id)
+    if (!decor->uEventID)
     {
       if (decor->IsInteractive())
       {
@@ -3113,58 +3087,6 @@
       event_triggers[num_event_triggers++] = i;
 }
 
-//----- (004621DA) --------------------------------------------------------
-int int_get_vector_length(signed int x, signed int y, signed int z)
-{
-  signed int v3; // eax@2
-
-  if ( x < y )
-  {
-    v3 = x;
-    x = y;
-    y = v3;
-  }
-  if ( x < z )
-  {
-    v3 = x;
-    x = z;
-    z = v3;
-  }
-  if ( y < z )
-  {
-    v3 = y;
-    y = z;
-    z = v3;
-  }
-  return (11 * y >> 5) + x + (z >> 2);
-}
-
-OPENFILENAMEA ofn;
-//----- (0046271C) --------------------------------------------------------
-void CreateDefaultBLVLevel()
-{
-  ofn.lStructSize = 0x4Cu;
-  ofn.hwndOwner = hWnd;
-  ofn.hInstance = 0;
-  ofn.lpstrFilter = "Indoor  BLV Files (*.blv)";
-  ofn.lpstrCustomFilter = 0;
-  ofn.nMaxCustFilter = 0;
-  ofn.nFilterIndex = 0;
-  ofn.lpstrFile = 0;
-  ofn.nMaxFile = 260;
-  ofn.nMaxFileTitle = 512;
-  ofn.lpstrInitialDir = "levels";
-  ofn.lpstrTitle = "Might and Magic VII - Load Which Level?";
-  ofn.Flags = 4;
-  ofn.nFileOffset = 0;
-  ofn.nFileExtension = 0;
-  ofn.lpstrDefExt = "blv";
-  ofn.lCustData = 0;
-  ofn.lpfnHook = 0;
-  ofn.lpTemplateName = 0;
-  ofn.lpstrFileTitle = pTmpBuf.data();
-}
-
 //----- (004627B7) --------------------------------------------------------
 void MainMenu_Loop()
 {
@@ -3219,13 +3141,12 @@
       pWindow = pGUIWindow_CurrentMenu;
     }
 
-    MSG msg;
-    while ( PeekMessageA(&msg, 0, 0, 0, PM_REMOVE) )
+    for (MSG msg; PeekMessage(&msg, 0, 0, 0, PM_REMOVE);)
     {
       if (msg.message == WM_QUIT)
         Game_DeinitializeAndTerminate(0);
       TranslateMessage(&msg);
-      DispatchMessageA(&msg);
+      DispatchMessage(&msg);
     }
     if (dword_6BE364_game_settings_1 & 0x0100)
     {
@@ -3306,33 +3227,40 @@
 }
 
 //----- (004637EB) --------------------------------------------------------
-int __stdcall aWinProc(HWND hWnd, UINT Msg, WPARAM wParam, unsigned int lParam)
+int __stdcall aWinProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 {
-  HANDLE v6; // eax@32
-  HDC v10; // edi@50
-  int v11; // esi@50
-  signed int v13; // eax@135
-  char v29; // dl@209
-  bool v31; // ebx@211
-  float v33; // ST04_4@246
-  float v34; // ST04_4@254
-  struct tagPAINTSTRUCT Paint; // [sp+24h] [bp-48h]@13
-  int pXY[2]; // [sp+64h] [bp-8h]@261
-  int a2; // [sp+7Ch] [bp+10h]@50
-
-  switch (Msg)
-  {
-    case WM_SIZING:  return 1;
+  //HANDLE v6; // eax@32
+  //HDC v10; // edi@50
+  //int v11; // esi@50
+  //signed int v13; // eax@135
+  //char v29; // dl@209
+  //bool v31; // ebx@211
+  //float v33; // ST04_4@246
+  //float v34; // ST04_4@254
+  //struct tagPAINTSTRUCT Paint; // [sp+24h] [bp-48h]@13
+  //int pXY[2]; // [sp+64h] [bp-8h]@261
+  //int a2; // [sp+7Ch] [bp+10h]@50
+
+  switch (uMsg)
+  {
+    case WM_SIZING: return 1;
+    
+    case WM_CREATE:  case WM_NCCREATE:
+    case WM_GETTEXT: case WM_SETTEXT:
     case WM_SHOWWINDOW:
-    case WM_GETTEXT:
-    case WM_SETTEXT: return DefWindowProcW(hWnd, Msg, wParam, lParam);
+      return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+
+    case WM_DESTROY:
+      SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
+      PostQuitMessage(0);
+      return 0;
 
     case WM_WINDOWPOSCHANGED:
     {
       if (pVideoPlayer && pVideoPlayer->AnyMovieLoaded() && pVideoPlayer->pBinkBuffer)
         BinkBufferSetOffset(pVideoPlayer->pBinkBuffer, 0, 0);
 
-      return DefWindowProcW(hWnd, Msg, wParam, lParam);
+      return DefWindowProcW(hWnd, uMsg, wParam, lParam);
     }
 
     case WM_CHAR:
@@ -3340,13 +3268,13 @@
       if (!pKeyActionMap->_459F10(wParam) && !viewparams->field_4C)
         GUI_HandleHotkey(wParam);
     }
-    return DefWindowProcA(hWnd, Msg, wParam, lParam);
+    return DefWindowProcW(hWnd, uMsg, wParam, lParam);
 
 
     case WM_DEVICECHANGE:
     {
       if (wParam == 0x8000)          // CD or some device has been inserted - notify InsertCD dialog
-        PostMessageA(hInsertCDWindow, WM_USER + 1, 0, 0);
+        PostMessageW(hInsertCDWindow, WM_USER + 1, 0, 0);
       return 0;
     }
 
@@ -3358,7 +3286,7 @@
 
         case 101:  // Quit game
         case 40001:
-          SendMessageA(::hWnd, WM_DESTROY, 0, 0);
+          SendMessageW(hWnd, WM_DESTROY, 0, 0);
         return 0;
 
 
@@ -3527,355 +3455,296 @@
 
       }
     }
-    return DefWindowProcA(hWnd, Msg, wParam, lParam);
-  };
-
-  if ( Msg > WM_SYSCOMMAND )
-  {
-    switch ( Msg )
-    {
-      case WM_LBUTTONDOWN:
-        if ( pArcomageGame->bGameInProgress )
-        {
-          pArcomageGame->stru1.field_0 = 7;
-          ArcomageGame::OnMouseClick(0, 1);
-          return DefWindowProcA(hWnd, Msg, wParam, lParam);
-        }
-        goto __handle_mouse_click;
-
-      case WM_RBUTTONDOWN:
-        v31 = 0;
-        if ( !pArcomageGame->bGameInProgress )
-          //goto LABEL_240;
-        {
-          if ( pVideoPlayer->pVideoFrame.pPixels != (unsigned __int16 *)v31 )
-            pVideoPlayer->bStopBeforeSchedule = 1;
-
-          pMouse->SetMouseClick((unsigned __int16)lParam, lParam >> 16);
-          if (pGame)
-          {
-            v33 = pGame->pIndoorCameraD3D->GetPickDepth();
-            pGame->PickMouse(v33, (unsigned __int16)lParam, lParam >> 16, v31, &vis_sprite_filter_2, &vis_door_filter);
-          }
-
-            sub_416D62_ShowPopupWindow_MonsterRecord_ItemInfo_etcsub_416D62(0);
-            return DefWindowProcA(hWnd, Msg, wParam, lParam);
-
-        }
-
+    return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+
+    case WM_LBUTTONDOWN:
+      if (pArcomageGame->bGameInProgress)
+      {
+        pArcomageGame->stru1.field_0 = 7;
+        ArcomageGame::OnMouseClick(0, true);
+        return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+      }
+
+      goto __handle_mouse_click;
+
+    case WM_RBUTTONDOWN:
+      if (pArcomageGame->bGameInProgress)
+      {
         pArcomageGame->stru1.field_0 = 8;
-        ArcomageGame::OnMouseClick(1, 1);
-        return DefWindowProcA(hWnd, Msg, wParam, lParam);
-      case WM_LBUTTONUP:
-        if ( !pArcomageGame->bGameInProgress )
-          //goto LABEL_218;
-        {
-          back_to_game();
-          return DefWindowProcA(hWnd, Msg, wParam, lParam);
-        }
-        pArcomageGame->stru1.field_0 = 3;
-        ArcomageGame::OnMouseClick(0, 0);
-        return DefWindowProcA(hWnd, Msg, wParam, lParam);
-      case WM_RBUTTONUP:
-        if ( !pArcomageGame->bGameInProgress )
-        {
-//LABEL_218:
-
-          back_to_game();
-          return DefWindowProcA(hWnd, Msg, wParam, lParam);
-        }
-        pArcomageGame->stru1.field_0 = 4;
-        ArcomageGame::OnMouseClick(1, false);
-        return DefWindowProcA(hWnd, Msg, wParam, lParam);
-
-      case WM_LBUTTONDBLCLK:
-        if ( pArcomageGame->bGameInProgress )
-        {
-          pArcomageGame->stru1.field_0 = 7;
-          return DefWindowProcA(hWnd, Msg, wParam, lParam);
-        }
+        ArcomageGame::OnMouseClick(1, true);
+        return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+      }
+
+      if (pVideoPlayer->pVideoFrame.pPixels)
+        pVideoPlayer->bStopBeforeSchedule = 1;
+
+      pMouse->SetMouseClick(LOWORD(lParam), HIWORD(lParam));
+
+      if (pGame)
+      {
+        pGame->PickMouse(pGame->pIndoorCameraD3D->GetPickDepth(), LOWORD(lParam), HIWORD(lParam), 0, &vis_sprite_filter_2, &vis_door_filter);
+      }
+
+      sub_416D62_ShowPopupWindow_MonsterRecord_ItemInfo_etcsub_416D62(0);
+      return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+
+
+    case WM_LBUTTONUP:
+      if ( !pArcomageGame->bGameInProgress )
+      {
+        back_to_game();
+        return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+      }
+      pArcomageGame->stru1.field_0 = 3;
+      ArcomageGame::OnMouseClick(0, 0);
+      return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+    case WM_RBUTTONUP:
+      if ( !pArcomageGame->bGameInProgress )
+      {
+        back_to_game();
+        return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+      }
+      pArcomageGame->stru1.field_0 = 4;
+      ArcomageGame::OnMouseClick(1, false);
+      return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+
+    case WM_LBUTTONDBLCLK:
+      if ( pArcomageGame->bGameInProgress )
+      {
+        pArcomageGame->stru1.field_0 = 7;
+        return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+      }
         
 __handle_mouse_click:
-        if ( pVideoPlayer->pVideoFrame.pPixels )
+      if (pVideoPlayer->pVideoFrame.pPixels)
+        pVideoPlayer->bStopBeforeSchedule = 1;
+
+      pMouse->SetMouseClick(LOWORD(lParam), HIWORD(lParam));
+
+      if (GetCurrentMenuID() == MENU_CREATEPARTY)
+      {
+        UI_OnKeyDown(VK_SELECT);
+      }
+
+      if (pGame)
+        pGame->PickMouse(512.0, LOWORD(lParam), HIWORD(lParam), false, &vis_sprite_filter_3, &vis_door_filter);
+
+      UI_OnMouseLeftClick(0);
+
+      return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+
+    case WM_RBUTTONDBLCLK:
+      if ( !pArcomageGame->bGameInProgress )
+      {
+        if (pVideoPlayer->pVideoFrame.pPixels)
           pVideoPlayer->bStopBeforeSchedule = 1;
 
-          pMouse->SetMouseClick((unsigned __int16)lParam, lParam >> 16);
-
-        if (GetCurrentMenuID() != MENU_CREATEPARTY)
-          pMouse->SetMouseClick((unsigned __int16)lParam, lParam >> 16);
-        else
+        pMouse->SetMouseClick(LOWORD(lParam), HIWORD(lParam));
+
+        if (pGame)
         {
-          UI_OnKeyDown(VK_SELECT);
-          pMouse->SetMouseClick((unsigned __int16)lParam, lParam >> 16);
-        }
-
-
-          if (pGame)
-            pGame->PickMouse(512.0, (unsigned __int16)lParam, lParam >> 16, false, &vis_sprite_filter_3, &vis_door_filter);
-
-          UI_OnMouseLeftClick(0);
-
-        return DefWindowProcA(hWnd, Msg, wParam, lParam);
-
-      case WM_RBUTTONDBLCLK:
-        v31 = 0;
-        if ( !pArcomageGame->bGameInProgress )
-        {
-//LABEL_240:
-          if ( pVideoPlayer->pVideoFrame.pPixels != (unsigned __int16 *)v31 )
-            pVideoPlayer->bStopBeforeSchedule = 1;
-
-            pMouse->SetMouseClick((unsigned __int16)lParam, lParam >> 16);
-          if (pGame)
-          {
-            v33 = pGame->pIndoorCameraD3D->GetPickDepth();
-            pGame->PickMouse(v33, (unsigned __int16)lParam, lParam >> 16, v31, &vis_sprite_filter_2, &vis_door_filter);
-          }
-
-            sub_416D62_ShowPopupWindow_MonsterRecord_ItemInfo_etcsub_416D62(0);
-            return DefWindowProcA(hWnd, Msg, wParam, lParam);
-
+          pGame->PickMouse(pGame->pIndoorCameraD3D->GetPickDepth(), LOWORD(lParam), HIWORD(lParam), false, &vis_sprite_filter_2, &vis_door_filter);
         }
-        pArcomageGame->stru1.field_0 = 8;
-        return DefWindowProcA(hWnd, Msg, wParam, lParam);
-      case WM_MBUTTONDOWN:
-        if ( pRenderer->pRenderD3D )
-        {
-          if ( pGame )
-          {
-            v34 = pGame->pIndoorCameraD3D->GetPickDepth();
-            pGame->PickMouse(v34, (unsigned __int16)lParam, lParam >> 16, 1, &vis_sprite_filter_3, &vis_face_filter);
-            return DefWindowProcA(hWnd, Msg, wParam, lParam);
-          }
-        }
-        if ( !pGame )
-          //goto _def_wnd_proc;
-          return DefWindowProcA(hWnd, Msg, wParam, lParam);
-        return DefWindowProcA(hWnd, Msg, wParam, lParam);
-      case WM_MOUSEMOVE:
-        if ( pArcomageGame->bGameInProgress )
-        {
-          pXY[0] = (unsigned __int16)lParam;
-          pXY[1] = lParam >> 16;
-          ArcomageGame::OnMouseMove((POINT *)pXY);
-          ArcomageGame::OnMouseClick(0, wParam & 1);
-          v29 = (wParam >> 1) & 1;
-          ArcomageGame::OnMouseClick(1, v29 != 0);
-        }
-        else
-        {
-          pMouse->SetMouseClick((unsigned __int16)lParam, lParam >> 16);
-        }
-        return DefWindowProcA(hWnd, Msg, wParam, lParam);
-      default:
-        //goto _def_wnd_proc;
-        return DefWindowProcA(hWnd, Msg, wParam, lParam);
-    }
-  }
-  if ( Msg == WM_SYSCOMMAND )
-  {
-    if ( wParam == SC_SCREENSAVE || wParam == SC_MONITORPOWER )
-      return 0;
-    //goto _def_wnd_proc;
-    return DefWindowProcA(hWnd, Msg, wParam, lParam);
-  }
-  if ( Msg > WM_ACTIVATEAPP )
-  {
-    if ( Msg != WM_KEYFIRST && Msg != WM_WINDOWPOSCHANGED)
-    {
-      if ( Msg == WM_KEYUP && wParam == VK_CONTROL )
+
+        sub_416D62_ShowPopupWindow_MonsterRecord_ItemInfo_etcsub_416D62(0);
+        return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+      }
+
+      pArcomageGame->stru1.field_0 = 8;
+
+      return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+
+    case WM_MBUTTONDOWN:
+      if (pRenderer->pRenderD3D && pGame)
+      {
+        pGame->PickMouse(pGame->pIndoorCameraD3D->GetPickDepth(), LOWORD(lParam), HIWORD(lParam), 1, &vis_sprite_filter_3, &vis_face_filter);
+      }
+
+      return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+
+    case WM_MOUSEMOVE:
+      if ( pArcomageGame->bGameInProgress )
+      {
+        ArcomageGame::OnMouseMove(LOWORD(lParam), HIWORD(lParam));
+        ArcomageGame::OnMouseClick(0, wParam == MK_LBUTTON);
+        ArcomageGame::OnMouseClick(1, wParam == MK_RBUTTON);
+      }
+      else
+      {
+        pMouse->SetMouseClick(LOWORD(lParam), HIWORD(lParam));
+      }
+
+      return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+
+    case WM_SYSCOMMAND:
+      if ( wParam == SC_SCREENSAVE || wParam == SC_MONITORPOWER )
+        return 0;
+
+      return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+
+    case WM_KEYUP:
+      if (wParam == VK_CONTROL)
       {
         dword_507B98_ctrl_pressed = 0;
       }
-      return DefWindowProcA(hWnd, Msg, wParam, lParam);
-    }
-    if ( uGameMenuUI_CurentlySelectedKeyIdx != -1 )
-    {
-      pKeyActionMap->_459F10(wParam);
-      return DefWindowProcA(hWnd, Msg, wParam, lParam);
-    }
-    if ( !pArcomageGame->bGameInProgress )
-    {
-      if ( pVideoPlayer->pVideoFrame.pPixels )
-        pVideoPlayer->bStopBeforeSchedule = 1;
-      if ( wParam == VK_RETURN )
-      {
-        if ( !viewparams->field_4C )
-          UI_OnKeyDown(wParam);
-        return 0;
-      }
-      if ( wParam == VK_CONTROL )
+
+      return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+
+    case WM_KEYDOWN:
+      if ( uGameMenuUI_CurentlySelectedKeyIdx != -1 )
       {
-        dword_507B98_ctrl_pressed = 1;
-        return 0;
-      }
-      if ( wParam == VK_ESCAPE )
-      {
-        pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, window_SpeakInHouse != 0, 0);
-        return 0;
+        pKeyActionMap->_459F10(wParam);
+        return DefWindowProcW(hWnd, uMsg, wParam, lParam);
       }
-      if ( wParam <= VK_HOME )
-        return 0;
-      if ( wParam > VK_DOWN )
+      if ( !pArcomageGame->bGameInProgress )
       {
-        if ( wParam != VK_F4 || pVideoPlayer->AnyMovieLoaded() )
-          return 0;
-        SendMessageA(hWnd, WM_COMMAND, 104, 0);
-        return 0;
-      }
-      if ( wParam >= VK_LEFT && wParam <= VK_DOWN )
-      {
-        if ( pCurrentScreen != SCREEN_GAME && pCurrentScreen != SCREEN_MODAL_WINDOW )
+        if ( pVideoPlayer->pVideoFrame.pPixels )
+          pVideoPlayer->bStopBeforeSchedule = 1;
+        if ( wParam == VK_RETURN )
         {
           if ( !viewparams->field_4C )
             UI_OnKeyDown(wParam);
           return 0;
         }
-      }
-      if ( pCurrentScreen != SCREEN_GAME && pCurrentScreen != SCREEN_MODAL_WINDOW )
-        return 0;
-    }
-
-    pArcomageGame->stru1.field_0 = 1;
-
-    v13 = (unsigned __int16)MapVirtualKeyA((unsigned __int16)wParam, 2u);
-    set_stru1_field_8_InArcomage(v13);
-    if ( wParam == 27 )
-    {
-      pArcomageGame->GameOver = 1;
-      pArcomageGame->field_F4 = 1;
-      pArcomageGame->uGameResult = 2;
-      pArcomageGame->field_B0 = -2;
-      return DefWindowProcA(hWnd, Msg, wParam, lParam);
-    }
-    if ( wParam != 114 )
-    {
-      if ( wParam == 115 && !pVideoPlayer->AnyMovieLoaded() )
-        SendMessageA(hWnd, 0x111u, 0x68u, 0);
-      return DefWindowProcA(hWnd, Msg, wParam, lParam);
-    }
-    SendMessageA(hWnd, WM_COMMAND, 103, 0);
-    return 0;
-  }
-  if ( Msg == WM_ACTIVATEAPP )
-  {
-    if ( wParam && (GetForegroundWindow() == hWnd || GetForegroundWindow() == hInsertCDWindow) )
-    {
-      if ( BYTE1(dword_6BE364_game_settings_1) & 1 )
-      {
-        dword_4E98BC_bApplicationActive = 1;
-        if ( pRenderer->bWindowMode )
+        if ( wParam == VK_CONTROL )
+        {
+          dword_507B98_ctrl_pressed = 1;
+          return 0;
+        }
+        if ( wParam == VK_ESCAPE )
         {
-          v10 = GetDC(0);
-          a2 = GetDeviceCaps(v10, BITSPIXEL);
-          v11 = GetDeviceCaps(v10, PLANES);
-          ReleaseDC(0, v10);
-          if ( a2 != 16 || v11 != 1 )
-            Abortf(pGlobalTXT_LocalizationStrings[62]);
+          pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, window_SpeakInHouse != 0, 0);
+          return 0;
         }
-        BYTE1(dword_6BE364_game_settings_1) &= 0xFEu;
-
-        if ( pArcomageGame->bGameInProgress )
-        {
-          pArcomageGame->field_F9 = 1;
-        }
-        else
+        if ( wParam <= VK_HOME )
+          return 0;
+        if ( wParam > VK_DOWN )
         {
-          if ( BYTE1(dword_6BE364_game_settings_1) & 2 )
-            BYTE1(dword_6BE364_game_settings_1) &= 0xFDu;
-          else
-            pEventTimer->Resume();
-          if ( BYTE1(dword_6BE364_game_settings_1) & 4 )
-            BYTE1(dword_6BE364_game_settings_1) &= 0xFBu;
-          else
-            pMiscTimer->Resume();
-
-          viewparams->bRedrawGameUI = true;
-          if ( pVideoPlayer->pSmackerMovie )
+          if ( wParam != VK_F4 || pVideoPlayer->AnyMovieLoaded() )
+            return 0;
+          SendMessageW(hWnd, WM_COMMAND, 104, 0);
+          return 0;
+        }
+        if ( wParam >= VK_LEFT && wParam <= VK_DOWN )
+        {
+          if ( pCurrentScreen != SCREEN_GAME && pCurrentScreen != SCREEN_MODAL_WINDOW )
           {
-            pRenderer->RestoreFrontBuffer();
-            pRenderer->_4A184C();
-            pVideoPlayer->_4BF5B2();
+            if ( !viewparams->field_4C )
+              UI_OnKeyDown(wParam);
+            return 0;
           }
         }
-        if ( pAudioPlayer->hAILRedbook && !bGameoverLoop && !pVideoPlayer->pSmackerMovie )
-          AIL_redbook_resume(pAudioPlayer->hAILRedbook);
+        if ( pCurrentScreen != SCREEN_GAME && pCurrentScreen != SCREEN_MODAL_WINDOW )
+          return 0;
       }
-    }
-    else
-    {
-      if ( !(dword_6BE364_game_settings_1 & 0x100) )
+
+      pArcomageGame->stru1.field_0 = 1;
+
+      set_stru1_field_8_InArcomage(MapVirtualKey(wParam, MAPVK_VK_TO_CHAR));
+      if ( wParam == 27 )
       {
-        while(initing); //ADDED spinlock to allow int players ets! Gloval
-          dword_4E98BC_bApplicationActive = 0;
-        if ( (pVideoPlayer->pSmackerMovie || pVideoPlayer->pBinkMovie) && pVideoPlayer->bPlayingMovie )
-          pVideoPlayer->bStopBeforeSchedule = 1;
-
-        if ( pRenderer->bUserDirect3D && pRenderer->uAcquiredDirect3DDevice == 1 )
-          SetWindowPos(::hWnd, (HWND)0xFFFFFFFE, 0, 0, 0, 0, 0x18u);
-        ClipCursor(0);
-        dword_6BE364_game_settings_1 |= 0x100u;
-        if ( pEventTimer->bPaused )
-          BYTE1(dword_6BE364_game_settings_1) |= 2u;
-        else
-          pEventTimer->Pause();
-        if ( pMiscTimer->bPaused )
-          BYTE1(dword_6BE364_game_settings_1) |= 4u;
-        else
-          pMiscTimer->Pause();
-
-        pAudioPlayer->StopChannels(-1, -1);
-        if ( pAudioPlayer->hAILRedbook )
-          AIL_redbook_pause(pAudioPlayer->hAILRedbook);
+        pArcomageGame->GameOver = 1;
+        pArcomageGame->field_F4 = 1;
+        pArcomageGame->uGameResult = 2;
+        pArcomageGame->field_B0 = -2;
+        return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+      }
+      if ( wParam != 114 )
+      {
+        if ( wParam == 115 && !pVideoPlayer->AnyMovieLoaded() )
+          SendMessage(hWnd, WM_COMMAND, 0x68u, 0);
+        return DefWindowProcW(hWnd, uMsg, wParam, lParam);
       }
-    }
-    return 0;
-  }
-  if (Msg == WM_CREATE)
-  {
-    auto hDC = GetDC(hWnd);
-    {
-      if (GetDeviceCaps(hDC, BITSPIXEL) < 8)
+      SendMessageW(hWnd, WM_COMMAND, 103, 0);
+      return 0;
+
+    case WM_ACTIVATEAPP:
+      if ( wParam && (GetForegroundWindow() == hWnd || GetForegroundWindow() == hInsertCDWindow) )
       {
-        ReleaseDC(hWnd, hDC);
-        Log::Warning(L"You must be running in 256 color mode or higher.");
-        Abortf("You must be running in 256 color mode or higher. You can change the screen depth with the control panel display icon.");
+        if ( BYTE1(dword_6BE364_game_settings_1) & 1 )
+        {
+          dword_4E98BC_bApplicationActive = 1;
+          if ( pRenderer->bWindowMode )
+          {
+            HDC hDC = GetDC(hWnd);
+            int bitsPerPixel = GetDeviceCaps(hDC, BITSPIXEL);
+            int planes = GetDeviceCaps(hDC, PLANES);
+            ReleaseDC(hWnd, hDC);
+            if (bitsPerPixel != 16 || planes != 1)
+              Error(pGlobalTXT_LocalizationStrings[62]);
+          }
+          BYTE1(dword_6BE364_game_settings_1) &= 0xFEu;
+
+          if ( pArcomageGame->bGameInProgress )
+          {
+            pArcomageGame->field_F9 = 1;
+          }
+          else
+          {
+            if ( BYTE1(dword_6BE364_game_settings_1) & 2 )
+              BYTE1(dword_6BE364_game_settings_1) &= 0xFDu;
+            else
+              pEventTimer->Resume();
+            if ( BYTE1(dword_6BE364_game_settings_1) & 4 )
+              BYTE1(dword_6BE364_game_settings_1) &= 0xFBu;
+            else
+              pMiscTimer->Resume();
+
+            viewparams->bRedrawGameUI = true;
+            if ( pVideoPlayer->pSmackerMovie )
+            {
+              pRenderer->RestoreFrontBuffer();
+              pRenderer->_4A184C();
+              pVideoPlayer->_4BF5B2();
+            }
+          }
+          if ( pAudioPlayer->hAILRedbook && !bGameoverLoop && !pVideoPlayer->pSmackerMovie )
+            AIL_redbook_resume(pAudioPlayer->hAILRedbook);
+        }
       }
-    }
-    ReleaseDC(hWnd, hDC);
-    return 0;
-  }
-  if ( Msg == WM_DESTROY )
-  {
-    v6 = GetCurrentProcess();
-    SetPriorityClass(v6, 0x20u);
-    if ( pGame )
-    {
-
-    }
-
-    PostQuitMessage(0);
-    return 0;
-  }
-  if ( Msg == WM_SETFOCUS )
-  {
-    if ( ::hWnd == (HWND)wParam )
-    {
+      else
+      {
+        if (!(dword_6BE364_game_settings_1 & 0x100))
+        {
+          dword_4E98BC_bApplicationActive = 0;
+          if ( (pVideoPlayer->pSmackerMovie || pVideoPlayer->pBinkMovie) && pVideoPlayer->bPlayingMovie )
+            pVideoPlayer->bStopBeforeSchedule = 1;
+
+          if ( pRenderer->bUserDirect3D && pRenderer->uAcquiredDirect3DDevice == 1 )
+            SetWindowPos(hWnd, (HWND)0xFFFFFFFE, 0, 0, 0, 0, 0x18u);
+          ClipCursor(0);
+          dword_6BE364_game_settings_1 |= 0x100u;
+          if ( pEventTimer->bPaused )
+            BYTE1(dword_6BE364_game_settings_1) |= 2u;
+          else
+            pEventTimer->Pause();
+          if ( pMiscTimer->bPaused )
+            BYTE1(dword_6BE364_game_settings_1) |= 4u;
+          else
+            pMiscTimer->Pause();
+
+          pAudioPlayer->StopChannels(-1, -1);
+          if ( pAudioPlayer->hAILRedbook )
+            AIL_redbook_pause(pAudioPlayer->hAILRedbook);
+        }
+      }
+      return 0;
+
+    case WM_SETFOCUS:
       dword_4E98BC_bApplicationActive = 0;
       if ( pRenderer->bUserDirect3D && pRenderer->uAcquiredDirect3DDevice == 1 )
-        SetWindowPos(::hWnd, (HWND)0xFFFFFFFE, 0, 0, 0, 0, 0x18u);
+        SetWindowPos(hWnd, (HWND)0xFFFFFFFE, 0, 0, 0, 0, 0x18u);
       ClipCursor(0);
-
-    }
-//_def_wnd_proc:
-    return DefWindowProcA(hWnd, Msg, wParam, lParam);
-  }
-  if ( Msg != WM_KILLFOCUS )
-  {
-    if ( Msg == WM_PAINT )
-    {
+      return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+
+    case WM_KILLFOCUS:
+      dword_4E98BC_bApplicationActive = 1;
+      return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+
+    case WM_PAINT:
       if ( !GetUpdateRect(hWnd, 0, 0) || !dword_4E98BC_bApplicationActive && !pRenderer->bWindowMode )
         return 0;
+      PAINTSTRUCT Paint;
       BeginPaint(hWnd, &Paint);
       if ( pArcomageGame->bGameInProgress )
       {
@@ -3892,13 +3761,10 @@
       pRenderer->Present();
       EndPaint(hWnd, &Paint);
       return 0;
-    }
-    //goto _def_wnd_proc;
-    return DefWindowProcA(hWnd, Msg, wParam, lParam);
-  }
-  if ( ::hWnd != (HWND)wParam || (dword_4E98BC_bApplicationActive = 1, pRenderer->bWindowMode) || true )
-    return DefWindowProcA(hWnd, Msg, wParam, lParam);
-
+
+    default:
+      return DefWindowProcA(hWnd, uMsg, wParam, lParam);
+  }
 }
 
 //----- (00464479) --------------------------------------------------------
@@ -3942,7 +3808,7 @@
   pEventTimer->Pause();
   pMiscTimer->Pause();
   pParty->uFlags = 2;
-  pCastSpellInfo.data()->_427D48(1);
+  CastSpellInfoHelpers::_427D48();
   ResetCursor_Palettes_LODs_Level_Audio_SFT_Windows();
   DoPrepareWorld(0, (_0_box_loading_1_fullscreen == 0) + 1);
   pMiscTimer->Resume();
@@ -4028,12 +3894,12 @@
     pSpriteObjects[i].uObjectDescID = 0;
 
   v5 = pMapStats->GetMapInfo(pCurrentMapName);
-  bUnderwater = 0;
+  bUnderwater = false;
   uLevelMapStatsID = v5;
   pGame->uFlags2 &= 0xFFFFFFF7u;
   if ( !_stricmp(pCurrentMapName, "out15.odm") )
   {
-    bUnderwater = 1;
+    bUnderwater = true;
     pGame->uFlags2 |= 8u;
   }
   pParty->floor_face_pid = 0;
@@ -4432,7 +4298,6 @@
 //----- (004651F4) --------------------------------------------------------
 bool MM7_Initialize()
 {
-initing=true; //ADDED Gloval
   wchar_t pCurrentDir[1024];
   _wgetcwd(pCurrentDir, 1024);
 
@@ -4474,11 +4339,6 @@
   auto hDesktopDC = GetDC(nullptr);
   uint uDesktopWidth = GetDeviceCaps(hDesktopDC, HORZRES);
   uint uDesktopHeight = GetDeviceCaps(hDesktopDC, VERTRES);
-
-  if (GetDeviceCaps(hDesktopDC, BITSPIXEL) != 16 ||
-      GetDeviceCaps(hDesktopDC, PLANES) != 1 )
-    dword_6BE364_game_settings_1 |= 2;
-
   ReleaseDC(nullptr, hDesktopDC);
 
   uint uTotalWinWidth = 2 * GetSystemMetrics(SM_CXFRAME) + 640;
@@ -4500,10 +4360,9 @@
                          uWindowX, uWindowY,
                          640, 480,
                          nullptr,
-                         hOSMenu = nullptr,
+                         nullptr,
                          wcxw.hInstance,
                          nullptr);
-  SetWindowTextW(hWnd, L"Might and Magic VII");
 
   HMENU menu = CreateMenu();
   {
@@ -4712,7 +4571,6 @@
   MoveWindow(hWnd, uWindowX, uWindowY,
     rcClient.left - rcClient.right - rcWindow.left + rcWindow.right + 640,
     rcClient.top - rcClient.bottom - rcWindow.top + rcWindow.bottom + 480, 0);
-  ShowWindow(hWnd, SW_SHOWNORMAL);
 
   pIcons_LOD = new LODFile_IconsBitmaps;
   if (!pIcons_LOD->Load("data\\icons.lod", "icons"))
@@ -4765,7 +4623,7 @@
   }
 
 
-
+#if 0
   if (_access("../MM_VI/data/icons.lod", 0) == 0)
   {
     pIcons_LOD_mm6 = new LODFile_IconsBitmaps;
@@ -4808,54 +4666,48 @@
     Log::Warning(L"Unable to find mm6:sprites.lod");
 
 
-
-  if (bDebugResouces)
-  {
-    pSpriteFrameTable = new SpriteFrameTable;
-    if (!pSpriteFrameTable->FromFileTxt("data\\sft.txt"))
-      Abortf("Unable to open sft.txt");
-
-    pDecorationList = new DecorationList;
-    if (!pDecorationList->FromFileTxt("data\\declist.txt"))
-      Abortf("Unable to open declist.txt");
-
-    pObjectList = new ObjectList;
-    if (!pObjectList->FromFileTxt("data\\objlist.txt"))
-      Abortf("Unable to open objlist.txt");
-
-    pMonsterList = new MonsterList;
-    if (!pMonsterList->FromFileTxt("data\\monlist.txt"))
-      Abortf("Unable to open monlist.txt");
-
-    pIconsFrameTable = new IconFrameTable;
-    if (!pIconsFrameTable->FromFileTxt("data\\ift.txt"))
-      Abortf("Unable to open ift.txt");
-
-    pTextureFrameTable = new TextureFrameTable;
-    if (!pTextureFrameTable->FromFileTxt("data\\tft.def"))
-      Abortf("Unable to open tft.def");
-
-    pTileTable = new TileTable;
-    if (!pTileTable->FromFileTxt("data\\tile.def"))
-      Abortf("Unable to open tile.def");
-
-    pPlayerFrameTable = new PlayerFrameTable;
-    if (!pPlayerFrameTable->FromFileTxt("data\\pft.def"))
-      Abortf("Unable to open pft.def");
-
-    pChestList = new ChestList;
-    if (!pChestList->FromFileTxt("data\\chest.def"))
-      Abortf("Unable to open chest.def");
-
-    pOverlayList = new OverlayList;
-    if (!pOverlayList->FromFileTxt("data\\overlay.def"))
-      Abortf("Unable to open overlay.def");
-
-    pSoundList = new SoundList;
-    if (!pSoundList->FromFileTxt("data\\sounds.def"))
-      Abortf("Unable to open sounds.def");
+  if (_access("../mm8/data/icons.lod", 0) == 0)
+  {
+    pIcons_LOD_mm8 = new LODFile_IconsBitmaps;
+    if (!pIcons_LOD_mm8->Load("../mm8/data/icons.lod", "icons"))
+    {
+      delete pIcons_LOD_mm8;
+      pIcons_LOD_mm8 = nullptr;
+      Log::Warning(L"Unable to load mm8:icons.lod");
+    }
   }
   else
+    Log::Warning(L"Unable to find mm8:icons.lod");
+
+
+  if (_access("../mm8/data/bitmaps.lod", 0) == 0)
+  {
+    pBitmaps_LOD_mm8 = new LODFile_IconsBitmaps;
+    if (!pBitmaps_LOD_mm8->Load("../mm8/data/bitmaps.lod", "bitmaps"))
+    {
+      delete pBitmaps_LOD_mm8;
+      pBitmaps_LOD_mm8 = nullptr;
+      Log::Warning(L"Unable to load mm8:bitmaps.lod");
+    }
+  }
+  else
+    Log::Warning(L"Unable to find mm8:bitmaps.lod");
+  
+
+  if (_access("../mm8/data/sprites.lod", 0) == 0)
+  {
+    pSprites_LOD_mm8 = new LODFile_Sprites;
+    if (!pSprites_LOD_mm8->LoadSprites("../mm8/data/sprites.lod"))
+    {
+      delete pSprites_LOD_mm8;
+      pSprites_LOD_mm8 = nullptr;
+      Log::Warning(L"Unable to load mm8:sprites.lod");
+    }
+  }
+  else
+    Log::Warning(L"Unable to find mm8:sprites.lod");
+#endif
+
   {
     void *sft_mm6 = pIcons_LOD_mm6 ? pIcons_LOD_mm6->LoadRaw("dsft.bin", 1) : nullptr,
          *sft_mm8 = nullptr;
@@ -4958,20 +4810,6 @@
   }
 
 
-  if (bDebugResouces)
-  {
-    pSpriteFrameTable->ToFile();
-    pDecorationList->ToFile();
-    pObjectList->ToFile();
-    pMonsterList->ToFile();
-    pIconsFrameTable->ToFile();
-    pTextureFrameTable->ToFile();
-    pTileTable->ToFile();
-    pPlayerFrameTable->ToFile();
-    pChestList->ToFile();
-    pOverlayList->ToFile();
-    pSoundList->ToFile();
-  }
 
   
   if (dword_6BE364_game_settings_1 & 2 || !(dword_6BE368_debug_settings_2 & 1))// 
@@ -5047,7 +4885,7 @@
       break;
     }
 
-  initing = false; //ADDED Gloval
+  ShowWindow(hWnd, SW_SHOWNORMAL);
   return true;
 }
 
@@ -5230,7 +5068,7 @@
   assert(sizeof(MobileLight) == 0x12);
   assert(sizeof(LightsStack_MobileLight_) == 0x1C28);
   assert(sizeof(Game) == 0xE78);
-  assert(sizeof(stru141) == 0xA8);
+  assert(sizeof(stru141_actor_collision_object) == 0xA8);
   assert(sizeof(ActionQueue) == 0x7C);
   assert(sizeof(NPCData) == 0x4C);
   assert(sizeof(NPCStats) == 0x17FFC);
@@ -5296,19 +5134,6 @@
 //----- (00462C94) --------------------------------------------------------
 bool MM_Main(const wchar_t *pCmdLine)
 {
-  HWND hPrevWnd; // eax@1
-  HWND hPrevWnd_; // esi@1
-  HWND v6; // eax@4
-  int v8; // eax@15
-  //bool v9; // edx@16
-  //OtherOverlay *v10; // esi@44
-  //signed int v11; // edi@44
-  //unsigned int v12; // ecx@56
-  HANDLE v13; // eax@68
-  unsigned int startms; // [sp+8h] [bp-24h]@55
-  RECT Rect; // [sp+Ch] [bp-20h]@15
-  int a2[4]; // [sp+1Ch] [bp-10h]@15
-  
   IntegrityTest();
   char test[1024];
   sprintfex(test, "^Pi[%s]: ^R[;;]", "");
@@ -5360,7 +5185,6 @@
     pGame->Deinitialize();
     return 1;
   }
-  Log::Warning(L"MM init: ok");
 
     pEventTimer->Pause();
 
@@ -5370,7 +5194,7 @@
     dword_6BE364_game_settings_1 |= 0x4000;
     pGame->InitializeGammaController();
     SecondaryInitialization();
-    pRenderer->SetRasterClipRect(0, 0, 639u, 479u);
+    pRenderer->SetRasterClipRect(0, 0, 639, 479);
     FinalInitialization();
 
     Log::Warning(L"MM: entering main loop");
@@ -5443,18 +5267,19 @@
 
 			  pParty->Reset();
 			  pParty->CreateDefaultParty(1);
-
-              extern void CreateDefaultBLVLevel();
+              
+              __debugbreak();
+              /*extern void CreateDefaultBLVLevel();
 			  CreateDefaultBLVLevel();
 
-			  extern OPENFILENAMEA ofn;
+			  OPENFILENAMEA ofn;
 			  if ( !GetOpenFileNameA((LPOPENFILENAMEA)&ofn) )
 			  {
 				pMouse->Activate(1);
 				break;
 			  }
 			  _chdir("..\\");
-			  strcpy(pCurrentMapName, ofn.lpstrFileTitle);
+			  strcpy(pCurrentMapName, ofn.lpstrFileTitle);*/
 			  pMouse->Activate(1);
 			  pGame->Loop();
 		  }
@@ -5482,7 +5307,7 @@
       {
         pAudioPlayer->SetMusicVolume(pSoundVolumeLevels[uMusicVolimeMultiplier] * 64.0f);
         AIL_redbook_stop(pAudioPlayer->hAILRedbook);
-        unsigned int end_ms;
+        unsigned int startms, end_ms;
         AIL_redbook_track_info(pAudioPlayer->hAILRedbook, 0xE, &startms, &end_ms);
         AIL_redbook_play(pAudioPlayer->hAILRedbook, startms + 1, end_ms);
       }
@@ -5688,40 +5513,6 @@
     pOutdoorCamera->_485F64();
 }
 
-//----- (00466B8C) --------------------------------------------------------
-int  AbortWithError()
-{
-  if ( !aborting_app )
-  {
-    ClipCursor(0);
-    aborting_app = 1;
-    if ( !pRenderer->bWindowMode )
-      pRenderer->ChangeBetweenWinFullscreenModes();
-    if ( MessageBoxA(0, pGlobalTXT_LocalizationStrings[176], pGlobalTXT_LocalizationStrings[59], 0x34u) == 6 )
-      SaveGame(1, 0);                           // "Internal Error"
-                                                // "Might and Magic VII has detected an internal error and will be forced to close.  Would you like us to autosave your game before closing?"
-    Game_DeinitializeAndTerminate(1);
-  }
-  return 0;
-}
-// 720018: using guessed type int aborting_app;
-
-//----- (00466BE5) --------------------------------------------------------
-void Abortf(const char *Format, ...)
-{
-  va_list va; // [sp+8h] [bp+8h]@1
-
-  va_start(va, Format);
-  if ( !pRenderer->bWindowMode )
-    pRenderer->ChangeBetweenWinFullscreenModes();
-  vsprintf(pTmpBuf.data(), Format, va);
-  if ( pMouse )
-    pMouse->Activate(0);
-  ClipCursor(0);
-  MessageBoxA(0, pTmpBuf.data(), "Error", 0x30u);
-  Game_DeinitializeAndTerminate(1);
-}
-
 //----- (00466C40) --------------------------------------------------------
 const wchar_t *MENU_STATE_to_string(MENU_STATE m)
 {
@@ -6182,7 +5973,7 @@
   }
   v25 = &pLevelDecorations[v20];
   v26 = v25;
-  v27 = v25->field_16_event_id;
+  v27 = v25->uEventID;
   if ( v27 )
   {
     v23 = GetEventHintString(v27);
--- a/mm7_3.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/mm7_3.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -2,8 +2,6 @@
 #define _CRT_SECURE_NO_WARNINGS
 #endif
 
-#include <assert.h>
-
 #include "Weather.h"
 #include "Texture.h"
 #include "mm7_data.h"
@@ -160,14 +158,14 @@
           {
             a3 = stru_721530.field_6C;
             if ( sub_47531C(stru_721530.prolly_normal_d, &a3, stru_721530.normal.x, stru_721530.normal.y, stru_721530.normal.z,
-                   stru_721530.field_58.x, stru_721530.field_58.y, stru_721530.field_58.z, pFace, a10) )
+                   stru_721530.direction.x, stru_721530.direction.y, stru_721530.direction.z, pFace, a10) )
             {
               v17 = a3;
             }
             else
             {
               a3 = stru_721530.field_6C + stru_721530.prolly_normal_d;
-              if ( !sub_475D85(&stru_721530.normal, &stru_721530.field_58, &a3, pFace) )
+              if ( !sub_475D85(&stru_721530.normal, &stru_721530.direction, &a3, pFace) )
                 goto LABEL_34;
               v17 = a3 - stru_721530.prolly_normal_d;
               a3 -= stru_721530.prolly_normal_d;
@@ -187,8 +185,8 @@
         || (v19 = pFace->pFacePlane_old.vNormal.x,
             v20 = pFace->pFacePlane_old.vNormal.y,
             v30 = v19,
-            v21 = (stru_721530.field_34.x * v19 + pFace->pFacePlane_old.dist + stru_721530.field_34.y * v20
-                 + stru_721530.field_34.z * pFace->pFacePlane_old.vNormal.z) >> 16,
+            v21 = (stru_721530.position.x * v19 + pFace->pFacePlane_old.dist + stru_721530.position.y * v20
+                 + stru_721530.position.z * pFace->pFacePlane_old.vNormal.z) >> 16,
             v21 <= 0)
         || (v22 = (stru_721530.field_4C * v30 + pFace->pFacePlane_old.dist + stru_721530.field_50 * v20
                  + stru_721530.field_54 * pFace->pFacePlane_old.vNormal.z) >> 16,
@@ -197,14 +195,14 @@
         || v22 > v21 )
         goto LABEL_45;
       a3 = stru_721530.field_6C;
-      if ( sub_47531C(stru_721530.field_8, &a3, stru_721530.field_34.x, stru_721530.field_34.y, stru_721530.field_34.z,
-             stru_721530.field_58.x, stru_721530.field_58.y, stru_721530.field_58.z, pFace, a10) )
+      if ( sub_47531C(stru_721530.field_8_radius, &a3, stru_721530.position.x, stru_721530.position.y, stru_721530.position.z,
+             stru_721530.direction.x, stru_721530.direction.y, stru_721530.direction.z, pFace, a10) )
       {
         v23 = a3;
         goto LABEL_43;
       }
-      a3 = stru_721530.field_6C + stru_721530.field_8;
-      if ( sub_475D85(&stru_721530.field_34, &stru_721530.field_58, &a3, pFace) )
+      a3 = stru_721530.field_6C + stru_721530.field_8_radius;
+      if ( sub_475D85(&stru_721530.position, &stru_721530.direction, &a3, pFace) )
       {
         v23 = a3 - stru_721530.prolly_normal_d;
         a3 -= stru_721530.prolly_normal_d;
@@ -373,9 +371,9 @@
                  stru_721530.normal.x,
                  stru_721530.normal.y,
                  stru_721530.normal.z,
-                 stru_721530.field_58.x,
-                 stru_721530.field_58.y,
-                 stru_721530.field_58.z,
+                 stru_721530.direction.x,
+                 stru_721530.direction.y,
+                 stru_721530.direction.z,
                  &f,
                  a10,
                  a11) )
@@ -384,8 +382,8 @@
           }
           else
           {
-            v11 = stru_721530.field_58.y;
-            v12 = stru_721530.field_58.z;
+            v11 = stru_721530.direction.y;
+            v12 = stru_721530.direction.z;
             v13 = stru_721530.normal.y;
             a2 = stru_721530.prolly_normal_d + stru_721530.field_6C;
             if ( !sub_475F30(
@@ -394,7 +392,7 @@
                     stru_721530.normal.x,
                     v13,
                     stru_721530.normal.z,
-                    stru_721530.field_58.x,
+                    stru_721530.direction.x,
                     v11,
                     v12,
                     a10) )
@@ -415,10 +413,10 @@
 LABEL_29:
     if ( stru_721530.field_0 & 1 )
     {
-      v15 = (f.pFacePlane_old.vNormal.z * stru_721530.field_34.z
+      v15 = (f.pFacePlane_old.vNormal.z * stru_721530.position.z
            + f.pFacePlane_old.dist
-           + f.pFacePlane_old.vNormal.y * stru_721530.field_34.y
-           + f.pFacePlane_old.vNormal.x * stru_721530.field_34.x) >> 16;
+           + f.pFacePlane_old.vNormal.y * stru_721530.position.y
+           + f.pFacePlane_old.vNormal.x * stru_721530.position.x) >> 16;
       if ( v15 > 0 )
       {
         v16 = (f.pFacePlane_old.vNormal.z * stru_721530.field_54
@@ -430,15 +428,14 @@
           if ( v16 <= v15 )
           {
             a2 = stru_721530.field_6C;
-            if ( sub_4754BF(
-                   stru_721530.field_8,
+            if ( sub_4754BF(stru_721530.field_8_radius,
                    &a2,
-                   stru_721530.field_34.x,
-                   stru_721530.field_34.y,
-                   stru_721530.field_34.z,
-                   stru_721530.field_58.x,
-                   stru_721530.field_58.y,
-                   stru_721530.field_58.z,
+                   stru_721530.position.x,
+                   stru_721530.position.y,
+                   stru_721530.position.z,
+                   stru_721530.direction.x,
+                   stru_721530.direction.y,
+                   stru_721530.direction.z,
                    &f,
                    a10,
                    a11) )
@@ -453,17 +450,16 @@
             }
             else
             {
-              v18 = stru_721530.field_58.y;
-              v19 = stru_721530.field_58.z;
-              v20 = stru_721530.field_34.y;
-              a2 = stru_721530.field_6C + stru_721530.field_8;
-              if ( sub_475F30(
-                     &a2,
+              v18 = stru_721530.direction.y;
+              v19 = stru_721530.direction.z;
+              v20 = stru_721530.position.y;
+              a2 = stru_721530.field_6C + stru_721530.field_8_radius;
+              if ( sub_475F30(&a2,
                      &f,
-                     stru_721530.field_34.x,
+                     stru_721530.position.x,
                      v20,
-                     stru_721530.field_34.z,
-                     stru_721530.field_58.x,
+                     stru_721530.position.z,
+                     stru_721530.direction.x,
                      v18,
                      v19,
                      a10) )
@@ -564,15 +560,15 @@
                     {
                       v8 = v4 - stru_721530.normal.x;
                       v9 = v5 - stru_721530.normal.y;
-                      if ( abs(((v4 - stru_721530.normal.x) * stru_721530.field_58.y
-                              - (v5 - stru_721530.normal.y) * stru_721530.field_58.x) >> 16) <= v3
+                      if ( abs(((v4 - stru_721530.normal.x) * stru_721530.direction.y
+                              - (v5 - stru_721530.normal.y) * stru_721530.direction.x) >> 16) <= v3
                                                                                               + stru_721530.prolly_normal_d )
                       {
-                        v10 = (v8 * stru_721530.field_58.x + v9 * stru_721530.field_58.y) >> 16;
+                        v10 = (v8 * stru_721530.direction.x + v9 * stru_721530.direction.y) >> 16;
                         if ( v10 > 0 )
                         {
                           v11 = stru_721530.normal.z
-                              + ((unsigned __int64)(stru_721530.field_58.z * (signed __int64)v10) >> 16);
+                              + ((unsigned __int64)(stru_721530.direction.z * (signed __int64)v10) >> 16);
                           if ( v11 >= *(int *)(v14 + 10) - stru_721530.prolly_normal_d )
                           {
                             if ( v11 <= v13 + stru_721530.prolly_normal_d + *(int *)(v14 + 10) )
@@ -600,7 +596,7 @@
 }
 
 //----- (0046EF01) --------------------------------------------------------
-int  _46EF01_collision_chech_player(int a1)
+int _46EF01_collision_chech_player(int a1)
 {
   int v1; // edx@1
   int result; // eax@1
@@ -615,10 +611,10 @@
   int v11; // [sp+18h] [bp-4h]@7
 
   v8 = a1;
-  v1 = 2 * pParty->field_14;
+  v1 = 2 * pParty->field_14_radius;
   result = pParty->vPosition.x;
   v9 = pParty->uPartyHeight;
-  if ( stru_721530.sMaxX <= pParty->vPosition.x + 2 * pParty->field_14 )
+  if ( stru_721530.sMaxX <= pParty->vPosition.x + 2 * pParty->field_14_radius )
   {
     if ( stru_721530.sMinX >= pParty->vPosition.x - v1 )
     {
@@ -632,18 +628,18 @@
             {
               v3 = stru_721530.prolly_normal_d + v1;
               v11 = pParty->vPosition.x - stru_721530.normal.x;
-              v4 = ((pParty->vPosition.x - stru_721530.normal.x) * stru_721530.field_58.y
-                  - (pParty->vPosition.y - stru_721530.normal.y) * stru_721530.field_58.x) >> 16;
+              v4 = ((pParty->vPosition.x - stru_721530.normal.x) * stru_721530.direction.y
+                  - (pParty->vPosition.y - stru_721530.normal.y) * stru_721530.direction.x) >> 16;
               v10 = pParty->vPosition.y - stru_721530.normal.y;
-              result = abs(((pParty->vPosition.x - stru_721530.normal.x) * stru_721530.field_58.y
-                          - (pParty->vPosition.y - stru_721530.normal.y) * stru_721530.field_58.x) >> 16);
+              result = abs(((pParty->vPosition.x - stru_721530.normal.x) * stru_721530.direction.y
+                          - (pParty->vPosition.y - stru_721530.normal.y) * stru_721530.direction.x) >> 16);
               if ( result <= v3 )
               {
-                result = v10 * stru_721530.field_58.y;
-                v5 = (v10 * stru_721530.field_58.y + v11 * stru_721530.field_58.x) >> 16;
+                result = v10 * stru_721530.direction.y;
+                v5 = (v10 * stru_721530.direction.y + v11 * stru_721530.direction.x) >> 16;
                 if ( v5 > 0 )
                 {
-                  v6 = ((unsigned __int64)(stru_721530.field_58.z * (signed __int64)v5) >> 16) + stru_721530.normal.z;
+                  v6 = ((unsigned __int64)(stru_721530.direction.z * (signed __int64)v5) >> 16) + stru_721530.normal.z;
                   result = pParty->vPosition.z;
                   if ( v6 >= pParty->vPosition.z )
                   {
@@ -710,17 +706,15 @@
             && stru_721530.sMaxZ <= v3->pBounding.z2
             && stru_721530.sMinZ >= v3->pBounding.z1 )
           {
-            v4 = (stru_721530.normal.x * v3->pFacePlane_old.vNormal.x
-                + v3->pFacePlane_old.dist
+            v4 = (stru_721530.normal.x * v3->pFacePlane_old.vNormal.x + v3->pFacePlane_old.dist
                 + stru_721530.normal.y * v3->pFacePlane_old.vNormal.y
                 + stru_721530.normal.z * v3->pFacePlane_old.vNormal.z) >> 16;
-            v5 = (stru_721530.normal2.z * v3->pFacePlane_old.vNormal.z
-                + v3->pFacePlane_old.dist
+            v5 = (stru_721530.normal2.z * v3->pFacePlane_old.vNormal.z + v3->pFacePlane_old.dist
                 + stru_721530.normal2.x * v3->pFacePlane_old.vNormal.x
                 + stru_721530.normal2.y * v3->pFacePlane_old.vNormal.y) >> 16;
             if ( (v4 < stru_721530.prolly_normal_d || v5 < stru_721530.prolly_normal_d)
               && (v4 > -stru_721530.prolly_normal_d || v5 > -stru_721530.prolly_normal_d)
-              && (a3 = stru_721530.field_6C, sub_475D85(&stru_721530.normal, &stru_721530.field_58, &a3, v3))
+              && (a3 = stru_721530.field_6C, sub_475D85(&stru_721530.normal, &stru_721530.direction, &a3, v3))
               && a3 < (signed int)v10 )
             {
               v0 = v9;
@@ -758,13 +752,13 @@
 }
 
 //----- (0047050A) --------------------------------------------------------
-int stru141::_47050A(int a2)
+int stru141_actor_collision_object::_47050A(int dt)
 {
-  stru141 *v2; // esi@1
-  signed int v3; // eax@1
-  int v4; // ecx@1
-  int v5; // edx@1
-  int v6; // edx@1
+  stru141_actor_collision_object *v2; // esi@1
+  //signed int v3; // eax@1
+  //int v4; // ecx@1
+  //int v5; // edx@1
+  //int v6; // edx@1
   int v7; // eax@1
   int v8; // eax@3
   signed int result; // eax@4
@@ -789,34 +783,36 @@
   int v28; // [sp+14h] [bp+8h]@5
 
   v2 = this;
-  v3 = integer_sqrt(this->field_24 * this->field_24 + this->field_20 * this->field_20 + this->field_1C * this->field_1C);
-  v4 = v3 | 1;
-  v5 = v2->field_1C;
-  v2->field_64 = v3 | 1;
-  v2->field_58.x = 65536 / (v3 | 1) * v5;
-  v2->field_58.y = 65536 / (v3 | 1) * v2->field_20;
-  v6 = 65536 / (v3 | 1) * v2->field_24;
-  v2->field_68 = 65536 / (v3 | 1);
-  v7 = a2;
-  v2->field_58.z = v6;
-  if ( !a2 )
+  int speed = 1 | integer_sqrt(this->velocity.z * this->velocity.z + this->velocity.y * this->velocity.y + this->velocity.x * this->velocity.x);
+
+  v2->direction.x = 65536 / speed * v2->velocity.x;
+  v2->direction.y = 65536 / speed * v2->velocity.y;
+  v2->direction.z = 65536 / speed * v2->velocity.z;
+
+  v2->speed = speed;
+  v2->inv_speed = 65536 / speed;
+
+  if (dt)
+    v7 = dt;
+  else
     v7 = pEventTimer->dt_in_some_format;
-  v8 = ((unsigned __int64)(v7 * (signed __int64)v4) >> 16) - v2->field_70;
+
+  v8 = fixpoint_sub0(v7, speed) - v2->field_70; // speed * dt - something
   v2->field_6C = v8;
   if ( v8 > 0 )
   {
-    v10 = ((unsigned __int64)(v8 * (signed __int64)v2->field_58.x) >> 16) + v2->normal.x;
+    v10 = fixpoint_sub0(v8, v2->direction.x) + v2->normal.x;
     v2->field_4C = v10;
     v2->normal2.x = v10;
-    v11 = ((unsigned __int64)(v2->field_6C * (signed __int64)v2->field_58.y) >> 16) + v2->normal.y;
+    v11 = fixpoint_sub0(v2->field_6C, v2->direction.y) + v2->normal.y;
     v2->field_50 = v11;
     v2->normal2.y = v11;
-    v2->normal2.z = ((unsigned __int64)(v2->field_6C * (signed __int64)v2->field_58.z) >> 16) + v2->normal.z;
-    v12 = v2->field_34.z;
+    v2->normal2.z = fixpoint_sub0(v2->field_6C, v2->direction.z) + v2->normal.z;
+    v12 = v2->position.z;
     v13 = v2->normal.x;
     v14 = v2->normal2.x;
     v15 = v2->prolly_normal_d;
-    v16 = v12 + ((unsigned __int64)(v2->field_6C * (signed __int64)v2->field_58.z) >> 16);
+    v16 = v12 + fixpoint_sub0(v2->field_6C, v2->direction.z);
     v28 = v16;
     v2->field_54 = v16;
     v17 = v13;
@@ -844,7 +840,7 @@
     else
       v25 = v24 - v15;
     v2->sMaxZ = v25;
-    v26 = v2->field_8;
+    v26 = v2->field_8_radius;
     if ( v12 <= v28 )
       v27 = v28 + v26;
     else
@@ -864,7 +860,7 @@
 }
 
 //----- (004706C6) --------------------------------------------------------
-void  UpdateActors_ODM()
+void UpdateActors_ODM()
 {
   Actor *v0; // esi@2
   AIState uAIState; // ax@2
@@ -878,22 +874,22 @@
   //unsigned __int8 v9; // zf@17
   unsigned __int8 v10; // sf@17
   unsigned __int16 v11; // ax@21
-  int v12; // eax@29
-  unsigned __int64 v13; // qax@29
-  int v14; // eax@30
-  unsigned __int64 v15; // qax@30
+  //int v12; // eax@29
+  //unsigned __int64 v13; // qax@29
+  //int v14; // eax@30
+  //unsigned __int64 v15; // qax@30
   int v16; // eax@33
   //int v17; // edi@34
-  int v18; // edx@42
-  int v19; // ecx@42
+  //int v18; // edx@42
+  //int v19; // ecx@42
   __int16 v20; // ax@42
-  int v21; // ebx@42
-  int v22; // edi@42
-  int v23; // ecx@42
-  __int16 v24; // ax@42
+  //int v21; // ebx@42
+  //int v22; // edi@42
+  //int v23; // ecx@42
+  //__int16 v24; // ax@42
   int v25; // eax@45
   signed int v26; // ecx@50
-  int v27; // eax@52
+  //int v27; // eax@52
   int v28; // eax@54
   signed int v29; // ebx@57
   signed int v30; // eax@57
@@ -916,8 +912,8 @@
   signed int v47; // ebx@85
   int v48; // edi@85
   int v49; // edi@85
-  int v50; // eax@85
-  unsigned __int64 v51; // qax@85
+  //int v50; // eax@85
+  //unsigned __int64 v51; // qax@85
   //unsigned __int8 v52; // zf@87
   //unsigned __int8 v53; // sf@87
  // unsigned __int8 v54; // of@104
@@ -940,12 +936,12 @@
   int v71; // [sp+38h] [bp-18h]@62
   int uIsAboveFloor; // [sp+3Ch] [bp-14h]@10
   int v72b;
-  int v73; // [sp+40h] [bp-10h]@17
+  //int v73; // [sp+40h] [bp-10h]@17
   int uIsFlying; // [sp+44h] [bp-Ch]@8
   unsigned int v75; // [sp+48h] [bp-8h]@1
   int uIsOnWater; // [sp+4Ch] [bp-4h]@10
 
-  for(v75=0;(signed int)v75 < (signed int)uNumActors;++v75)
+  for (v75 = 0; v75 < uNumActors; ++v75)
   {
     v0 = &pActors[v75];
     v66 = v0->vPosition.x;
@@ -985,53 +981,34 @@
     if ( v0->uCurrentActionAnimation == ANIM_Walking )
     {
       v8 = v0->uMovementSpeed;
-      v73 = v0->uMovementSpeed;
       if ( (signed __int64)v0->pActorBuffs[7].uExpireTime > 0 )
       {
-        v8 = (signed __int64)((double)v73 * 0.5);
-        v73 = (signed __int64)((double)v73 * 0.5);
+        v8 = (signed __int64)((double)v8 * 0.5);
       }
       if ( uAIState == Fleeing || uAIState == Pursuing )
       {
         v8 *= 2;
-        v73 = v8;
       }
       if ( pParty->bTurnBasedModeOn == 1 && pTurnEngine->turn_stage == 1 )
-        v8 = (signed __int64)((double)v73 * flt_6BE3AC_debug_recmod1_x_1_6);
+        v8 *= flt_6BE3AC_debug_recmod1_x_1_6;
       if ( v8 > 1000 )
         v8 = 1000;
-      v12 = stru_5C6E00->Cos(v0->uYawAngle);
-      v13 = v12 * (signed __int64)v8;
-      v73 = v13 >> 16;
-      v0->vVelocity.x = WORD1(v13);
-      v69 = stru_5C6E00->Sin(v0->uYawAngle);
-      v73 = (unsigned __int64)((signed int)v69 * (signed __int64)v8) >> 16;
-      v0->vVelocity.y = v69 * v8 >> 16;
+
+      v0->vVelocity.x = fixpoint_sub0(stru_5C6E00->Cos(v0->uYawAngle), v8);
+      v0->vVelocity.y = fixpoint_sub0(stru_5C6E00->Sin(v0->uYawAngle), v8);
       if ( uIsFlying )
       {
-        v14 = stru_5C6E00->Sin(v0->uPitchAngle);
-        v69 = v14;
-        v15 = v14 * (signed __int64)v8;
-        v73 = v15 >> 16;
-        v0->vVelocity.z = WORD1(v15);
+        v0->vVelocity.z = fixpoint_sub0(stru_5C6E00->Sin(v0->uPitchAngle), v8);
       }
       //v7 = v68;
     }
     else
     {
-      v73 = v0->vVelocity.x;
-      v69 = 55000;
-      v73 = (unsigned __int64)(55000i64 * v73) >> 16;
-      v0->vVelocity.x = v73;
-      v73 = v0->vVelocity.y;
-      v73 = (unsigned __int64)((signed int)v69 * (signed __int64)v73) >> 16;
-      v0->vVelocity.y = v73;
+      v0->vVelocity.x = fixpoint_sub0(55000, v0->vVelocity.x);
+      v0->vVelocity.y = fixpoint_sub0(55000, v0->vVelocity.y);
       if ( uIsFlying )
       {
-        v69 = 55000;
-        v73 = v0->vVelocity.z;
-        v73 = (unsigned __int64)(55000i64 * v73) >> 16;
-        v0->vVelocity.z = v73;
+        v0->vVelocity.z = fixpoint_sub0(55000, v0->vVelocity.z);
       }
     }
     if ( v0->vPosition.z < v5 )
@@ -1045,24 +1022,18 @@
     {
       if ( v70 && !uIsAboveFloor && v67 )
       {
-        v18 = v0->vPosition.y;
-        v19 = v0->vPosition.x;
         v0->vPosition.z = v5;
-        ODM_GetTerrainNormalAt(v19, v18, &v62);
+        ODM_GetTerrainNormalAt(v0->vPosition.x, v0->vPosition.y, &v62);
         v20 = GetGravityStrength();
-        v21 = v62.y;
-        v22 = v62.z;
-        v23 = v62.y * v0->vVelocity.y;
+        //v21 = v62.y;
+        //v22 = v62.z;
+        //v23 = v62.y * v0->vVelocity.y;
         v0->vVelocity.z += -8 * LOWORD(pEventTimer->uTimeElapsed) * v20;
-        v73 = abs(v62.x * v0->vVelocity.x + v22 * v0->vVelocity.z + v23) >> 16;
-        v72b = v21;
-        v0->vVelocity.x += (unsigned int)(v73 * v62.x) >> 16;
-        v72b = (unsigned __int64)(v73 * (signed __int64)v72b) >> 16;
-        v24 = v72b;
-        v72b = v22;
-        v0->vVelocity.y += v24;
-        v72b = (unsigned __int64)(v73 * (signed __int64)v72b) >> 16;
-        v0->vVelocity.z += v72b;
+        int v73 = abs(v62.x * v0->vVelocity.x + v62.z * v0->vVelocity.z + v62.y * v0->vVelocity.y) >> 16;
+        //v72b = v21;
+        v0->vVelocity.x += fixpoint_sub0(v73, v62.x);
+        v0->vVelocity.y += fixpoint_sub0(v73, v62.y);
+        v0->vVelocity.z += fixpoint_sub0(v73, v62.z);
         //v17 = 0;
       }
     }
@@ -1090,28 +1061,28 @@
       v26 = 40;
     else
       v26 = v0->uActorRadius;
-    v27 = v0->uActorHeight;
+
     stru_721530.field_84 = -1;
-    stru_721530.field_8 = v26;
+    stru_721530.field_8_radius = v26;
     stru_721530.prolly_normal_d = v26;
-    stru_721530.field_C = v27;
+    stru_721530.height = v0->uActorHeight;
     stru_721530.field_70 = 0;
     v69 = 0;
     while ( 1 )
     {
-      stru_721530.field_34.x = v0->vPosition.x;
-      stru_721530.normal.x = stru_721530.field_34.x;
-      stru_721530.field_34.y = v0->vPosition.y;
-      stru_721530.normal.y = stru_721530.field_34.y;
+      stru_721530.position.x = v0->vPosition.x;
+      stru_721530.normal.x = stru_721530.position.x;
+      stru_721530.position.y = v0->vPosition.y;
+      stru_721530.normal.y = stru_721530.position.y;
       v28 = v0->vPosition.z;
       stru_721530.normal.z = v28 + v26 + 1;
-      stru_721530.field_34.z = v28 - v26 + stru_721530.field_C - 1;
-      if ( stru_721530.field_34.z < stru_721530.normal.z )
-        stru_721530.field_34.z = v28 + v26 + 1;
-      stru_721530.field_1C = v0->vVelocity.x;
+      stru_721530.position.z = v28 - v26 + stru_721530.height - 1;
+      if ( stru_721530.position.z < stru_721530.normal.z )
+        stru_721530.position.z = v28 + v26 + 1;
+      stru_721530.velocity.x = v0->vVelocity.x;
       stru_721530.uSectorID = 0;
-      stru_721530.field_20 = v0->vVelocity.y;
-      stru_721530.field_24 = v0->vVelocity.z;
+      stru_721530.velocity.y = v0->vVelocity.y;
+      stru_721530.velocity.z = v0->vVelocity.z;
       if ( stru_721530._47050A(0) )
         break;
       _46E889_collide_against_bmodels(1u);
@@ -1129,11 +1100,10 @@
       }
       v71 = i > 1;
       if ( stru_721530.field_7C < stru_721530.field_6C )
-        v70 = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.z) >> 16;
+        v70 = fixpoint_sub0(stru_721530.field_7C, stru_721530.direction.z);
       //v34 = 0;
       v35 = stru_721530.normal2.z - stru_721530.prolly_normal_d - 1;
-      v36 = ODM_GetFloorLevel(
-              stru_721530.normal2.x,
+      v36 = ODM_GetFloorLevel(stru_721530.normal2.x,
               stru_721530.normal2.y,
               stru_721530.normal2.z - stru_721530.prolly_normal_d - 1,
               v0->uActorHeight,
@@ -1163,13 +1133,13 @@
         v0->vPosition.z = LOWORD(stru_721530.normal2.z) - LOWORD(stru_721530.prolly_normal_d) - 1;
         break;
       }
-      v72b = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.x) >> 16;
-      v0->vPosition.x += (unsigned int)(stru_721530.field_7C * stru_721530.field_58.x) >> 16;
-      v72b = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.y) >> 16;
-      v0->vPosition.y += (unsigned int)(stru_721530.field_7C * stru_721530.field_58.y) >> 16;
-      v72b = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.z) >> 16;
+      //v72b = fixpoint_sub0(stru_721530.field_7C, stru_721530.field_58.x);
+      v0->vPosition.x += fixpoint_sub0(stru_721530.field_7C, stru_721530.direction.x);
+      //v72b = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.y) >> 16;
+      v0->vPosition.y += fixpoint_sub0(stru_721530.field_7C, stru_721530.direction.y);
+      //v72b = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.z) >> 16;
+      v0->vPosition.z += fixpoint_sub0(stru_721530.field_7C, stru_721530.direction.z);
       v38 = stru_721530.uFaceID;
-      v0->vPosition.z += (unsigned int)(stru_721530.field_7C * stru_721530.field_58.z) >> 16;
       stru_721530.field_70 += stru_721530.field_7C;
 	  v39 = PID_ID(v38);
       switch ( PID_TYPE(v38) )
@@ -1190,7 +1160,7 @@
 				  Actor::AI_StandOrBored(v75, 4, 0, (AIDirection *)0);
 			  }
             }
-            else if ( v71 != 0 )
+            else if ( v71 )
 			{
               Actor::AI_StandOrBored(v75, 4, 0, (AIDirection *)0);
 			}
@@ -1225,20 +1195,14 @@
           v48 = stru_5C6E00->Atan2(
                   v0->vPosition.x - pLevelDecorations[v39].vPosition.x,
                   v0->vPosition.y - pLevelDecorations[v39].vPosition.y);
-          v71 = stru_5C6E00->Cos(v48);
-          v70 = (unsigned __int64)(v71 * (signed __int64)v47) >> 16;
           v49 = v48;
-          v0->vVelocity.x = (unsigned int)(v71 * v47) >> 16;
-          v50 = stru_5C6E00->Sin(v48);
-          v71 = v50;
-          v51 = v50 * (signed __int64)v47;
-          v70 = v51 >> 16;
-          v0->vVelocity.y = WORD1(v51);
+          v0->vVelocity.x = fixpoint_sub0(stru_5C6E00->Cos(v48), v47);
+          v0->vVelocity.y = fixpoint_sub0(stru_5C6E00->Sin(v48), v47);
           break;
         case OBJECT_BModel:
           v40 = &pOutdoor->pBModels[v38 >> 9];
           v41 = &v40->pFaces[v39 & 0x3F];
-          if ( !(BYTE3(v41->uAttributes) & 0x20) )
+          if ( !(v41->uAttributes & 0x20000000) )
           {
             v42 = v41->uPolygonType;
             if ( v42 == 3 )
@@ -1257,17 +1221,12 @@
             {
               v72b = abs(v41->pFacePlane.vNormal.y * v0->vVelocity.y + v41->pFacePlane.vNormal.z * v0->vVelocity.z
                                                                     + v41->pFacePlane.vNormal.x * v0->vVelocity.x) >> 16;
-              if ( stru_721530.field_64 >> 3 > v72b )
-                v72b = stru_721530.field_64 >> 3;
-              v73 = v41->pFacePlane.vNormal.x;
-              v73 = (unsigned __int64)(v72b * (signed __int64)v73) >> 16;
-              v71 = v41->pFacePlane.vNormal.y;
-              v71 = (unsigned __int64)(v72b * (signed __int64)v71) >> 16;
-              v70 = v41->pFacePlane.vNormal.z;
-              v70 = (unsigned __int64)(v72b * (signed __int64)(signed int)v70) >> 16;
-              v0->vVelocity.x += v73;
-              v0->vVelocity.y += v71;
-              v0->vVelocity.z += v70;
+              if ( (stru_721530.speed >> 3) > v72b )
+                v72b = stru_721530.speed >> 3;
+
+              v0->vVelocity.x += fixpoint_sub0(v72b, v41->pFacePlane.vNormal.x);
+              v0->vVelocity.y += fixpoint_sub0(v72b, v41->pFacePlane.vNormal.y);
+              v0->vVelocity.z += fixpoint_sub0(v72b, v41->pFacePlane.vNormal.z);
               if ( v42 != 4 )
               {
                 v45 = v0->vPosition.z;
@@ -1288,20 +1247,12 @@
           }
           break;
       }
-      v70 = v0->vVelocity.x;
-      v71 = 58500;
-      v70 = (unsigned __int64)(58500i64 * (signed int)v70) >> 16;
-      v0->vVelocity.x = v70;
-      v70 = v0->vVelocity.y;
-      v70 = (unsigned __int64)(v71 * (signed __int64)(signed int)v70) >> 16;
-      v71 = 58500;
-      v0->vVelocity.y = v70;
-      v70 = v0->vVelocity.z;
-      v70 = (unsigned __int64)(v71 * (signed __int64)(signed int)v70) >> 16;
+
+      v0->vVelocity.x = fixpoint_sub0(58500, v0->vVelocity.x);
+      v0->vVelocity.y = fixpoint_sub0(58500, v0->vVelocity.y);
+      v0->vVelocity.z = fixpoint_sub0(58500, v0->vVelocity.z);
+
       ++v69;
-      //v54 = v69 < 100;
-      //v10 = (v69 - 100) < 0;
-      v0->vVelocity.z = v70;
       if ( v69 >= 100 )
         break;
       v26 = stru_721530.prolly_normal_d;
@@ -1368,8 +1319,8 @@
     //do
     //{
       //LOWORD(v0) = item->uAttributes;
-    if (item->uAttributes & 0x40)
-      item->uAttributes &= 0xFFBF;
+    if (item->uAttributes & OBJECT_40)
+      item->uAttributes &= ~OBJECT_40;
     else
     {
               //v3 = item->uObjectDescID;
@@ -1639,10 +1590,10 @@
   if (!pParty->FeatherFallActive())
   {
     bFeatherFall = false;
-    if (!pParty->pPlayers[0].WearsItem(ITEM_ARTIFACT_LADYS_ESCORT, EQIUP_ANY) &&  // grants feather fall
-        !pParty->pPlayers[1].WearsItem(ITEM_ARTIFACT_LADYS_ESCORT, EQIUP_ANY) &&
-        !pParty->pPlayers[2].WearsItem(ITEM_ARTIFACT_LADYS_ESCORT, EQIUP_ANY) &&
-        !pParty->pPlayers[3].WearsItem(ITEM_ARTIFACT_LADYS_ESCORT, EQIUP_ANY))
+    if (!pParty->pPlayers[0].WearsItemAnyWhere(ITEM_ARTIFACT_LADYS_ESCORT) &&  // grants feather fall
+        !pParty->pPlayers[1].WearsItemAnyWhere(ITEM_ARTIFACT_LADYS_ESCORT) &&
+        !pParty->pPlayers[2].WearsItemAnyWhere(ITEM_ARTIFACT_LADYS_ESCORT) &&
+        !pParty->pPlayers[3].WearsItemAnyWhere(ITEM_ARTIFACT_LADYS_ESCORT))
     {
       fall_start = pParty->uFallStartY;
     }
@@ -1748,37 +1699,37 @@
         break;
 
       case PARTY_StrafeLeft:
-        v2 -= (unsigned __int64)(stru_5C6E00->Sin(angle) * (signed __int64)((signed int)(signed __int64)((double)v81 * fWalkSpeedMultiplier) >> 1)) >> 16;
-        v1 += (unsigned __int64)(stru_5C6E00->Cos(angle) * (signed __int64)((signed int)(signed __int64)((double)v81 * fWalkSpeedMultiplier) >> 1)) >> 16;
+        v2 -= fixpoint_sub0(stru_5C6E00->Sin(angle), v81 * fWalkSpeedMultiplier / 2);
+        v1 += fixpoint_sub0(stru_5C6E00->Cos(angle), v81 * fWalkSpeedMultiplier / 2);
         v78 = 1;
         break;
       case PARTY_StrafeRight:
-        v2 += (unsigned __int64)(stru_5C6E00->Sin(angle) * (signed __int64)((signed int)(signed __int64)((double)v81 * fWalkSpeedMultiplier) >> 1)) >> 16;
-        v1 -= (unsigned __int64)(stru_5C6E00->Cos(angle) * (signed __int64)((signed int)(signed __int64)((double)v81 * fWalkSpeedMultiplier) >> 1)) >> 16;
+        v2 += fixpoint_sub0(stru_5C6E00->Sin(angle), v81 * fWalkSpeedMultiplier / 2);
+        v1 -= fixpoint_sub0(stru_5C6E00->Cos(angle), v81 * fWalkSpeedMultiplier / 2);
         v78 = 1;
         break;
       case PARTY_WalkForward:
-        v2 += (unsigned __int64)(stru_5C6E00->Cos(angle) * (signed __int64)(signed int)(signed __int64)(5 * (double)v81 * fWalkSpeedMultiplier)) >> 16;
-        v1 += (unsigned __int64)(stru_5C6E00->Sin(angle) * (signed __int64)(signed int)(signed __int64)(5 * (double)v81 * fWalkSpeedMultiplier)) >> 16;
+        v2 += fixpoint_sub0(stru_5C6E00->Cos(angle), 5 * v81 * fWalkSpeedMultiplier);
+        v1 += fixpoint_sub0(stru_5C6E00->Sin(angle), 5 * v81 * fWalkSpeedMultiplier);
         v78 = 1;
         break;
       case PARTY_WalkBackward:
-        v2 -= (unsigned __int64)(stru_5C6E00->Cos(angle) * (signed __int64)(signed int)(signed __int64)((double)v81 * fBackwardWalkSpeedMultiplier)) >> 16;
-        v1 -= (unsigned __int64)(stru_5C6E00->Sin(angle) * (signed __int64)(signed int)(signed __int64)((double)v81 * fBackwardWalkSpeedMultiplier)) >> 16;
+        v2 -= fixpoint_sub0(stru_5C6E00->Cos(angle), v81 * fBackwardWalkSpeedMultiplier);
+        v1 -= fixpoint_sub0(stru_5C6E00->Sin(angle), v81 * fBackwardWalkSpeedMultiplier);
         v78 = 1;
         break;
       case PARTY_RunForward:
-        v2 += (unsigned __int64)(stru_5C6E00->Cos(angle) * (signed __int64)(signed int)(2 * (unsigned __int64)(signed __int64)((double)v81 * fWalkSpeedMultiplier))) >> 16;
-        v1 += (unsigned __int64)(stru_5C6E00->Sin(angle) * (signed __int64)(signed int)(2 * (unsigned __int64)(signed __int64)((double)v81 * fWalkSpeedMultiplier))) >> 16;
+        v2 += fixpoint_sub0(stru_5C6E00->Cos(angle), 2 * v81 * fWalkSpeedMultiplier);
+        v1 += fixpoint_sub0(stru_5C6E00->Sin(angle), 2 * v81 * fWalkSpeedMultiplier);
         v72 = 1;
         break;
       case PARTY_RunBackward:
         //v32 = stru_5C6E00->SinCos(angle);
         //v33 = (double)v81;
         //v88 = (double)v81;
-        v2 -= (unsigned __int64)(stru_5C6E00->Cos(angle) * (signed __int64)(signed int)(signed __int64)((double)v81 * fBackwardWalkSpeedMultiplier)) >> 16;
+        v2 -= fixpoint_sub0(stru_5C6E00->Cos(angle), v81 * fBackwardWalkSpeedMultiplier);
         //v34 = stru_5C6E00->SinCos(angle - stru_5C6E00->uIntegerHalfPi);
-        v1 -= (unsigned __int64)(stru_5C6E00->Sin(angle) * (signed __int64)(signed int)(signed __int64)((double)v81 * fBackwardWalkSpeedMultiplier)) >> 16;
+        v1 -= fixpoint_sub0(stru_5C6E00->Sin(angle), v81 * fBackwardWalkSpeedMultiplier);
         v72 = 1;
         break;
       case PARTY_LookUp:
@@ -1855,23 +1806,23 @@
   }
   stru_721530.field_84 = -1;
   stru_721530.field_70 = 0;
-  stru_721530.prolly_normal_d = pParty->field_14;
-  stru_721530.field_8 = pParty->field_14 >> 1;
+  stru_721530.prolly_normal_d = pParty->field_14_radius;
+  stru_721530.field_8_radius = pParty->field_14_radius / 2;
   auto v83 = 0;
   stru_721530.field_0 = 1;
-  stru_721530.field_C = pParty->uPartyHeight - 32;
+  stru_721530.height = pParty->uPartyHeight - 32;
   while ( 1 )
   {
     new_party_z = party_z;
-    stru_721530.field_34.x = new_party_x;
+    stru_721530.position.x = new_party_x;
     stru_721530.normal.x = new_party_x;
-    stru_721530.field_1C = v2;
-    stru_721530.field_34.y = new_party_y;
+    stru_721530.velocity.x = v2;
+    stru_721530.position.y = new_party_y;
     stru_721530.normal.y = new_party_y;
-    stru_721530.field_20 = v1;
+    stru_721530.velocity.y = v1;
     stru_721530.normal.z = stru_721530.prolly_normal_d + party_z + 1;
-    stru_721530.field_34.z = stru_721530.field_C + party_z + 1;
-    stru_721530.field_24 = pParty->uFallSpeed;
+    stru_721530.position.z = stru_721530.height + party_z + 1;
+    stru_721530.velocity.z = pParty->uFallSpeed;
     stru_721530.uSectorID = uSectorID;
     v38 = 0;
     if ( pParty->bTurnBasedModeOn == 1 && pTurnEngine->turn_stage == 3 )
@@ -1898,9 +1849,9 @@
     }
     else
     {
-      v39 = ((unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.x) >> 16) + new_party_x;
-      uSectorID = new_party_y + ((unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.y) >> 16);
-      v40 = new_party_z + ((unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.z) >> 16);
+      v39 = ((unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.direction.x) >> 16) + new_party_x;
+      uSectorID = new_party_y + ((unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.direction.y) >> 16);
+      v40 = new_party_z + ((unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.direction.z) >> 16);
     }
     v42 = collide_against_floor(v39, uSectorID, v40 + 40, &stru_721530.uSectorID, &uFaceID);
     if ( v42 == -30000 || v42 - new_party_z > 128 )
@@ -1912,12 +1863,12 @@
       new_party_z = stru_721530.normal2.z - stru_721530.prolly_normal_d - 1;
       break;
     }
-    new_party_x += (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.x) >> 16;
-    new_party_y += (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.y) >> 16;
+    new_party_x += (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.direction.x) >> 16;
+    new_party_y += (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.direction.y) >> 16;
     v43 = stru_721530.uFaceID;
     uSectorID = stru_721530.uSectorID;
     stru_721530.field_70 += stru_721530.field_7C;
-    auto v87 = ((unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.z) >> 16) + new_party_z;
+    auto v87 = ((unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.direction.z) >> 16) + new_party_z;
     if ( PID_TYPE(stru_721530.uFaceID) == OBJECT_Actor)
     {
       if ( SHIDWORD(pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime) >= 0
@@ -1964,8 +1915,8 @@
 			if ( !v47 )
 			{
 			  v80 = abs(v1 * v44->pFacePlane_old.vNormal.y + v46 + v2 * v48) >> 16;
-			  if ( stru_721530.field_64 >> 3 > v80 )
-				v80 = stru_721530.field_64 >> 3;
+			  if ((stru_721530.speed >> 3) > v80 )
+				v80 = stru_721530.speed >> 3;
 			  v50 = (unsigned __int64)(v80 * (signed __int64)v44->pFacePlane_old.vNormal.x) >> 16;
 			  v81 = v44->pFacePlane_old.vNormal.y;
 			  v81 = (unsigned __int64)(v80 * (signed __int64)v81) >> 16;
@@ -1992,8 +1943,8 @@
 			else
 			{
 				v80 = abs(v1 * v44->pFacePlane_old.vNormal.y + v46 + v2 * v48) >> 16;
-				if ( stru_721530.field_64 >> 3 > v80 )
-				  v80 = stru_721530.field_64 >> 3;
+				if ((stru_721530.speed >> 3) > v80 )
+				  v80 = stru_721530.speed >> 3;
 				v49 = (unsigned __int64)(v80 * (signed __int64)v44->pFacePlane_old.vNormal.x) >> 16;
 				v81 = v44->pFacePlane_old.vNormal.y;
 				v81 = (unsigned __int64)(v80 * (signed __int64)v81) >> 16;
@@ -2217,7 +2168,7 @@
   {
     bFeatherFall = 0;
     for (int i = 0; i < 4; ++i)
-      if (pParty->pPlayers[i].WearsItem(ITEM_ARTIFACT_LADYS_ESCORT, EQIUP_ANY))  // seems like flying boots
+      if (pParty->pPlayers[i].WearsItemAnyWhere(ITEM_ARTIFACT_LADYS_ESCORT))  // seems like flying boots
       {
         bFeatherFall = 1;
         break;
@@ -2708,22 +2659,22 @@
   }
   stru_721530.field_84 = -1;
   stru_721530.field_70 = 0;
-  stru_721530.prolly_normal_d = pParty->field_14;
-  stru_721530.field_8 = pParty->field_14 >> 1;
+  stru_721530.prolly_normal_d = pParty->field_14_radius;
+  stru_721530.field_8_radius = pParty->field_14_radius >> 1;
   v126 = 0;
   stru_721530.field_0 = 1;
-  stru_721530.field_C = pParty->uPartyHeight - 32;
+  stru_721530.height = pParty->uPartyHeight - 32;
   do
   {
-    stru_721530.field_34.x = pX;
+    stru_721530.position.x = pX;
     stru_721530.normal.x = pX;
-    stru_721530.field_1C = v2;
-    stru_721530.field_34.y = pY;
+    stru_721530.velocity.x = v2;
+    stru_721530.position.y = pY;
     stru_721530.normal.y = pY;
     stru_721530.normal.z = stru_721530.prolly_normal_d + pZ + 1;
-    stru_721530.field_34.z = stru_721530.field_C + pZ + 1;
-    stru_721530.field_20 = v128;
-    stru_721530.field_24 = pParty->uFallSpeed;
+    stru_721530.position.z = stru_721530.height + pZ + 1;
+    stru_721530.velocity.y = v128;
+    stru_721530.velocity.z = pParty->uFallSpeed;
     v36 = 0;
     stru_721530.uSectorID = 0;
     if ( pParty->bTurnBasedModeOn == 1 && pTurnEngine->turn_stage == 3 )
@@ -2745,10 +2696,10 @@
     }
     else
     {
-      _angle_x = pX + ((unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.x) >> 16);
-      _angle_y = pY + ((unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.y) >> 16);
-      pModel = (BSPModel *)((unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.z) >> 16);
-      v40 = ((unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.z) >> 16) + pZ;
+      _angle_x = pX + fixpoint_sub0(stru_721530.field_7C, stru_721530.direction.x);
+      _angle_y = pY + fixpoint_sub0(stru_721530.field_7C, stru_721530.direction.y);
+      pModel = (BSPModel *)fixpoint_sub0(stru_721530.field_7C, stru_721530.direction.z);
+      v40 = fixpoint_sub0(stru_721530.field_7C, stru_721530.direction.z) + pZ;
     }
     v122 = v40;
     ODM_GetFloorLevel(_angle_x, _angle_y, v40, pParty->uPartyHeight, &is_on_water, &bmodel_standing_on_pid, 0);
@@ -2884,8 +2835,8 @@
         if ( !v129 && (pODMFace->uPolygonType != POLYGON_InBetweenFloorAndWall || v119) )//   
         {
           v118 = abs(v128 * pODMFace->pFacePlane.vNormal.y + pParty->uFallSpeed * v52 + v2 * pODMFace->pFacePlane.vNormal.x) >> 16;
-          if ( stru_721530.field_64 >> 3 > v118 )
-            v118 = stru_721530.field_64 >> 3;
+          if ((stru_721530.speed >> 3) > v118 )
+            v118 = stru_721530.speed >> 3;
           v129 = (unsigned __int64)(v118 * (signed __int64)pODMFace->pFacePlane.vNormal.x) >> 16;
           _walk_speed = (unsigned __int64)(v118 * (signed __int64)pODMFace->pFacePlane.vNormal.y) >> 16;
           v54 = 0;
@@ -2926,8 +2877,8 @@
 			continue;
         }
         v118 = abs(v128 * pODMFace->pFacePlane.vNormal.y + pParty->uFallSpeed * v52 + v2 * pODMFace->pFacePlane.vNormal.x) >> 16;
-        if ( stru_721530.field_64 >> 3 > v118 )
-          v118 = stru_721530.field_64 >> 3;
+        if ((stru_721530.speed >> 3) > v118 )
+          v118 = stru_721530.speed >> 3;
         v122 = pODMFace->pFacePlane.vNormal.x;
         v122 = (unsigned __int64)(v118 * (signed __int64)(signed int)v122) >> 16;
         pModel = (BSPModel *)pODMFace->pFacePlane.vNormal.y;
@@ -4856,7 +4807,7 @@
   v7 = v3;
   v8 = ptr_38;
   sTextureDeltaV = v2->sTextureDeltaV;
-  v8->_48616B(v4, v7, 0, 0, v5, v6);
+  v8->_48616B_frustum_odm(v4, v7, 0, 0, v5, v6);
   return 1;
 }
 
@@ -5377,7 +5328,7 @@
        (pOutdoorCamera->shading_dist_mist * -sin(pIndoorCamera->sRotationX * 0.003066406352445483) - pIndoorCamera->pos.z);//61 / 184 / 310    
 
   pSkyPolygon.Create_48607B(&stru_8019C8);
-  pSkyPolygon.ptr_38->Inverse_sky_48694B();//maybe creating skydome(   )
+  pSkyPolygon.ptr_38->_48694B_frustum_sky();//maybe creating skydome(   )
   pSkyPolygon.uTileBitmapID = pOutdoor->uSky_TextureID;// 
   pSkyPolygon.pTexture = (Texture *)(pOutdoor->uSky_TextureID != -1 ? &pBitmaps_LOD->pTextures[pOutdoor->uSky_TextureID] : 0);// 
   if (pOutdoor->uSky_TextureID == -1)
@@ -5940,23 +5891,10 @@
 }
 
 
-//----- (00481EB7) --------------------------------------------------------
-void ResetPolygons()
-{
-  for (auto i = 0; i < pOutdoorCamera->uNumPolygons; ++i)
-  {
-    array_77EC08[i].prolly_head = nullptr;
-    array_77EC08[i].prolly_tail = nullptr;
-
-    array_77EC08[i].flags = 0;
-    array_77EC08[i].field_32 = 0;
-  }
-}
-
 //----- (00481ED9) --------------------------------------------------------
 void  sub_481ED9_MessWithOutdoorCamera()
 {
-  stru_8019C8._48616B(65536, 0, 0, 0, 65536, 0);
+  stru_8019C8._48616B_frustum_odm(65536, 0, 0, 0, 65536, 0);
   pOutdoorCamera->uNumPolygons = 0;
   pOutdoorCamera->uNumEdges = 0;
   pOutdoorCamera->uNumSpans = 0;
@@ -6027,7 +5965,7 @@
 
   int y_min = min(y1, min(y2, y3)),
       y_max = max(y1, max(y2, y3));
-  return y_max - y_min > 512;
+  return (y_max - y_min) > 512;
 
   /*if ( y1 >= y2 )
   {
@@ -6179,126 +6117,109 @@
 }
 
 //----- (0048616B) --------------------------------------------------------
-int stru149::_48616B(int a2, int a3, int a4, int a5, int a6, int a7)
+void stru149::_48616B_frustum_odm(int a2, int a3, int a4, int a5, int a6, int a7)
 {
   int v7; // ebx@1
-  int v8; // esi@1
+  //int v8; // esi@1
   int v9; // edi@1
-  int v10; // eax@1
+  //int v10; // eax@1
   int v11; // edx@1
-  int v12; // esi@2
-  int v13; // eax@2
-  int v14; // ST10_4@3
-  int v15; // esi@3
-  int v16; // eax@5
+  //int v12; // esi@2
+  //int v13; // eax@2
+  //int v14; // ST10_4@3
+  //int v15; // esi@3
+  //int v16; // eax@5
   int v17; // ST0C_4@6
-  int v18; // eax@8
+  //int v18; // eax@8
   int v19; // ST0C_4@9
-  int v20; // eax@10
-  int v21; // edx@10
-  int v22; // eax@10
-  int result; // eax@10
+  //int v20; // eax@10
+  //int v21; // edx@10
+  //int v22; // eax@10
+  //int result; // eax@10
   int v24; // [sp+14h] [bp-14h]@1
   int v25; // [sp+18h] [bp-10h]@1
-  int v26; // [sp+1Ch] [bp-Ch]@1
+  //int v26; // [sp+1Ch] [bp-Ch]@1
   int v27; // [sp+24h] [bp-4h]@1
-  int v28; // [sp+30h] [bp+8h]@10
-  int v29; // [sp+3Ch] [bp+14h]@10
+  //int v28; // [sp+30h] [bp+8h]@10
+  //int v29; // [sp+3Ch] [bp+14h]@10
 
   v25 = pOutdoorCamera->camera_rotation_x_int_cosine;
   v7 = pOutdoorCamera->camera_rotation_y_int_sine;
   v27 = pOutdoorCamera->camera_rotation_x_int_sine;
-  v8 = -pIndoorCamera->pos.y;
+  //v8 = -pIndoorCamera->pos.y;
   v9 = pOutdoorCamera->camera_rotation_y_int_cosine;
-  v26 = -pIndoorCamera->pos.z;
-  v24 = -pIndoorCamera->pos.x;
-  v10 = pOutdoorCamera->camera_rotation_y_int_cosine * -pIndoorCamera->pos.x;
-  v11 = v10 + pOutdoorCamera->camera_rotation_y_int_sine * -pIndoorCamera->pos.y;
+  //v26 = -pIndoorCamera->pos.z;
+  v11 = pOutdoorCamera->camera_rotation_y_int_cosine * -pIndoorCamera->pos.x + pOutdoorCamera->camera_rotation_y_int_sine * -pIndoorCamera->pos.y;
+  v24 = pOutdoorCamera->camera_rotation_y_int_cosine * -pIndoorCamera->pos.y - pOutdoorCamera->camera_rotation_y_int_sine * -pIndoorCamera->pos.x;
   if ( pIndoorCamera->sRotationX )
   {
-    v14 = v10 + pOutdoorCamera->camera_rotation_y_int_sine * -pIndoorCamera->pos.y;
-    v15 = pOutdoorCamera->camera_rotation_y_int_cosine * v8 - pOutdoorCamera->camera_rotation_y_int_sine * v24;
-    this->field_0_party_dir_x = ((unsigned __int64)(v11 * (signed __int64)pOutdoorCamera->camera_rotation_x_int_cosine) >> 16)
-                  + ((unsigned __int64)(-65536
-                                      * pIndoorCamera->pos.z
-                                      * (signed __int64)pOutdoorCamera->camera_rotation_x_int_sine) >> 16);
-    this->field_4_party_dir_y = v15;
-    v12 = v25;
-    v13 = ((unsigned __int64)((v26 << 16) * (signed __int64)v25) >> 16)
-        - ((unsigned __int64)(v14 * (signed __int64)v27) >> 16);
+    this->field_0_party_dir_x = fixpoint_sub0(v11, pOutdoorCamera->camera_rotation_x_int_cosine) +
+                                fixpoint_sub0((-pIndoorCamera->pos.z) << 16, pOutdoorCamera->camera_rotation_x_int_sine);
+    this->field_4_party_dir_y = v24;
+    this->field_8_party_dir_z = fixpoint_sub0((-pIndoorCamera->pos.z) << 16, v25) - fixpoint_sub0(v11, v27);
   }
   else
   {
-    this->field_4_party_dir_y = pOutdoorCamera->camera_rotation_y_int_cosine * v8 - pOutdoorCamera->camera_rotation_y_int_sine * v24;
-    v12 = v25;
     this->field_0_party_dir_x = v11;
-    v13 = v26 << 16;
-  }
-  this->field_8 = v13;
-  if ( pIndoorCamera->sRotationX )
-  {
-    v17 = ((unsigned __int64)(a2 * (signed __int64)v9) >> 16) + ((unsigned __int64)(a3 * (signed __int64)v7) >> 16);
-    this->field_C = ((unsigned __int64)(v17 * (signed __int64)v12) >> 16)
-                  + ((unsigned __int64)(a4 * (signed __int64)v27) >> 16);
-    this->field_10 = ((unsigned __int64)(a3 * (signed __int64)v9) >> 16)
-                   - ((unsigned __int64)(a2 * (signed __int64)v7) >> 16);
-    v16 = ((unsigned __int64)(a4 * (signed __int64)v12) >> 16) - ((unsigned __int64)(v17 * (signed __int64)v27) >> 16);
+    this->field_4_party_dir_y = v24;
+    this->field_8_party_dir_z = (-pIndoorCamera->pos.z) << 16;
+  }
+
+  if (pIndoorCamera->sRotationX)
+  {
+    v17 = fixpoint_sub0(a2, v9) + fixpoint_sub0(a3, v7);
+
+    this->field_C = fixpoint_sub0(v17, v25) + fixpoint_sub0(a4, v27);
+    this->field_10 = fixpoint_sub0(a3, v9) - fixpoint_sub0(a2, v7);
+    this->field_14 = fixpoint_sub0(a4, v25) - fixpoint_sub0(v17, v27);
   }
   else
   {
-    this->field_C = ((unsigned __int64)(a2 * (signed __int64)v9) >> 16)
-                  + ((unsigned __int64)(a3 * (signed __int64)v7) >> 16);
-    this->field_10 = ((unsigned __int64)(a3 * (signed __int64)v9) >> 16)
-                   - ((unsigned __int64)(a2 * (signed __int64)v7) >> 16);
-    v16 = a4;
-  }
-  this->field_14 = v16;
-  if ( pIndoorCamera->sRotationX )
-  {
-    v19 = ((unsigned __int64)(a5 * (signed __int64)v9) >> 16) + ((unsigned __int64)(a6 * (signed __int64)v7) >> 16);
-    this->field_18 = ((unsigned __int64)(v19 * (signed __int64)v12) >> 16)
-                   + ((unsigned __int64)(a7 * (signed __int64)v27) >> 16);
-    this->field_1C = ((unsigned __int64)(a6 * (signed __int64)v9) >> 16)
-                   - ((unsigned __int64)(a5 * (signed __int64)v7) >> 16);
-    v18 = ((unsigned __int64)(a7 * (signed __int64)v12) >> 16) - ((unsigned __int64)(v19 * (signed __int64)v27) >> 16);
+    this->field_C = fixpoint_sub0(a2, v9) + fixpoint_sub0(a3, v7);
+    this->field_10 = fixpoint_sub0(a3, v9) - fixpoint_sub0(a2, v7);
+    this->field_14 = a4;
+  }
+
+  if (pIndoorCamera->sRotationX)
+  {
+    v19 = fixpoint_sub0(a5, v9) + fixpoint_sub0(a6, v7);
+
+    this->field_18 = fixpoint_sub0(v19, v25) + fixpoint_sub0(a7, v27);
+    this->field_1C = fixpoint_sub0(a6, v9) - fixpoint_sub0(a5, v7);
+    this->field_20 = fixpoint_sub0(a7, v25) - fixpoint_sub0(v19, v27);
   }
   else
   {
-    this->field_18 = ((unsigned __int64)(a5 * (signed __int64)v9) >> 16)
-                   + ((unsigned __int64)(a6 * (signed __int64)v7) >> 16);
-    this->field_1C = ((unsigned __int64)(a6 * (signed __int64)v9) >> 16)
-                   - ((unsigned __int64)(a5 * (signed __int64)v7) >> 16);
-    v18 = a7;
-  }
+    this->field_18 = fixpoint_sub0(a5, v9) + fixpoint_sub0(a6, v7);
+    this->field_1C = fixpoint_sub0(a6, v9) - fixpoint_sub0(a5, v7);
+    this->field_20 = a7;
+  }
+
   this->field_18 = -this->field_18;
   this->field_1C = -this->field_1C;
-  this->field_20 = v18;
-  v20 = this->field_C;
   this->field_20 = -this->field_20;
-  v21 = ((unsigned __int64)(v20 * (signed __int64)this->field_0_party_dir_x) >> 16)
-      + ((unsigned __int64)(this->field_10 * (signed __int64)this->field_4_party_dir_y) >> 16)
-      + ((unsigned __int64)(this->field_14 * (signed __int64)this->field_8) >> 16);
-  v28 = this->field_18;
-  v22 = this->field_0_party_dir_x;
-  this->field_24 = v21;
-  v29 = (unsigned __int64)(v28 * (signed __int64)v22) >> 16;
-  result = (unsigned __int64)(this->field_1C * (signed __int64)this->field_4_party_dir_y) >> 16;
-  this->field_28 = v29 + result + ((unsigned __int64)(this->field_20 * (signed __int64)this->field_8) >> 16);
-  return result;
+
+  this->field_24 = fixpoint_dot(this->field_C,  this->field_0_party_dir_x,
+                                this->field_10, this->field_4_party_dir_y,
+                                this->field_14, this->field_8_party_dir_z);
+  this->field_28 = fixpoint_dot(this->field_18, this->field_0_party_dir_x,
+                                this->field_1C, this->field_4_party_dir_y,
+                                this->field_20, this->field_8_party_dir_z);
 }
 
 //----- (0048694B) --------------------------------------------------------
-void stru149::Inverse_sky_48694B()
+void stru149::_48694B_frustum_sky()
 {
   this->field_18 = -this->field_18;
   this->field_1C = -this->field_1C;
   this->field_20 = -this->field_20;
-  this->field_24 = ((unsigned __int64)(this->field_C * (signed __int64)this->field_0_party_dir_x) >> 16)
-                 + ((unsigned __int64)(this->field_10 * (signed __int64)this->field_4_party_dir_y) >> 16)
-                 + ((unsigned __int64)(this->field_14 * (signed __int64)this->field_8) >> 16);
-  this->field_28 = ((unsigned __int64)(this->field_18 * (signed __int64)this->field_0_party_dir_x) >> 16)
-                 + ((unsigned __int64)(this->field_1C * (signed __int64)this->field_4_party_dir_y) >> 16)
-                 + ((unsigned __int64)(this->field_20 * (signed __int64)this->field_8) >> 16);
+
+  this->field_24 = fixpoint_dot(this->field_C,  this->field_0_party_dir_x,
+                                this->field_10, this->field_4_party_dir_y,
+                                this->field_14, this->field_8_party_dir_z);
+  this->field_28 = fixpoint_dot(this->field_18, this->field_0_party_dir_x,
+                                this->field_1C, this->field_4_party_dir_y,
+                                this->field_20, this->field_8_party_dir_z);
 }
 
 //----- (0044100D) --------------------------------------------------------
@@ -6318,8 +6239,8 @@
   char *v3; // esi@1
   int v4; // edi@4
   bool v5; // ecx@4
-  SpriteFrame *v6; // eax@6
-  SpriteFrame *v7; // edi@6
+  SpriteFrame *pFrame; // eax@6
+  //SpriteFrame *v7; // edi@6
   int v8; // eax@6
   unsigned __int16 v9; // ax@6
   RenderBillboardTransform_local0 v10; // [sp+Ch] [bp-5Ch]@1
@@ -6357,24 +6278,24 @@
         {
           if ( !pOtherOverlayList->pOverlays[i].field_0 )
           {
-            v6 = pSpriteFrameTable->GetFrame(pOverlayList->pOverlays[pOtherOverlayList->pOverlays[i].field_2].uSpriteFramesetID,
+            pFrame = pSpriteFrameTable->GetFrame(pOverlayList->pOverlays[pOtherOverlayList->pOverlays[i].field_2].uSpriteFramesetID,
                    pOtherOverlayList->pOverlays[i].field_4);
-            v7 = v6;
+            //v7 = v6;
             v11 = pOtherOverlayList->pOverlays[i].field_E;
-            v13 = v6->scale;
-            v13 = (unsigned __int64)(v11 * (signed __int64)v13) >> 16;
+            //v13 = pFrame->scale;
+            v13 = (unsigned __int64)(v11 * (signed __int64)pFrame->scale) >> 16;
             v10.uScreenSpaceX = pOtherOverlayList->pOverlays[i].field_8;
             v10.uScreenSpaceY = pOtherOverlayList->pOverlays[i].field_A;
             v10._screenspace_x_scaler_packedfloat = v13;
             v10._screenspace_y_scaler_packedfloat = v13;
-            v10.pPalette = PaletteManager::Get_Dark_or_Red_LUT(v6->uPaletteIndex, 0, 1);
+            v10.pPalette = PaletteManager::Get_Dark_or_Red_LUT(pFrame->uPaletteIndex, 0, 1);
             v8 = pOtherOverlayList->pOverlays[i].field_2;
             v10.sZValue = 0;
             v10.uFlags = 0;
             v9 = pOverlayList->pOverlays[v8].uOverlayType;
             if ( !v9 || v9 == 2 )
-              v10.uScreenSpaceY += pSprites_LOD->pSpriteHeaders[v7->pHwSpriteIDs[0]].uHeight >> 1;
-            result = pSprites_LOD->pSpriteHeaders[v7->pHwSpriteIDs[0]]._4AD2D1(&v10, 0);
+              v10.uScreenSpaceY += pSprites_LOD->pSpriteHeaders[pFrame->pHwSpriteIDs[0]].uHeight >> 1;
+            result = pSprites_LOD->pSpriteHeaders[pFrame->pHwSpriteIDs[0]]._4AD2D1(&v10, 0);
             ++v12;
             if ( v12 == 5 )
               break;
@@ -6648,10 +6569,7 @@
 
   uLevelStrNumStrings = string_num - 1;
   if ( max_string_length > 800 )
-  {
-    sprintf(Args, "MAX_EVENT_TEXT_LENGTH needs to be increased to %lu", max_string_length+1);
-    Abortf(Args);
-  }
+    Error("MAX_EVENT_TEXT_LENGTH needs to be increased to %lu", max_string_length+1);
 
   if ( uLevelStrNumStrings > 0 )
   {
@@ -6846,10 +6764,10 @@
   char pContainerName[120]; // [sp+8h] [bp-98h]@1
 
   sprintf(pContainerName, "%s.evt", pLevelName);
-  uLevelEVT_Size = LoadEventsToBuffer(pContainerName, pLevelEVT.data(), 0x2400u);
+  uLevelEVT_Size = LoadEventsToBuffer(pContainerName, pLevelEVT.data(), 9216);
 
   sprintf(pContainerName, "%s.str", pLevelName);
-  uLevelStrFileSize = LoadEventsToBuffer(pContainerName, pLevelStr.data(), 0x2400u);
+  uLevelStrFileSize = LoadEventsToBuffer(pContainerName, pLevelStr.data(), 9216);
   if (uLevelStrFileSize)
     LoadLevel_InitializeLevelStr();
 }
@@ -6918,7 +6836,7 @@
             v12 = v11->sCogTriggeredID;
             if ( v12 )
             {
-              if ( !(BYTE2(v11->uAttributes) & 0x10) )
+              if ( !(v11->uAttributes & 0x100000) )
               {
                 v13 = GetEventHintString(v12);
                 v14 = v13;
@@ -6985,7 +6903,7 @@
 }
 
 //----- (004452BB) --------------------------------------------------------
-void  sub_4452BB()
+void sub_4452BB()
 {
   pGUIWindow2->Release();
   pGUIWindow2 = 0;
@@ -7190,40 +7108,25 @@
 }
 
 //----- (0044882F) --------------------------------------------------------
-void __fastcall SetDecorationSprite(unsigned int uCog, int a2, const char *pFileName)
+void __fastcall SetDecorationSprite(uint16_t uCog, bool bHide, const char *pFileName)
 {
-  signed int v3; // ebp@1
-  char *v4; // esi@2
-  unsigned __int16 v5; // ax@6
-  unsigned int v6; // [sp+4h] [bp-8h]@1
-  int v7; // [sp+8h] [bp-4h]@1
-
-  v3 = 0;
-  v7 = a2;
-  v6 = uCog;
-  if ( (signed int)uNumLevelDecorations > 0 )
-  {
-    v4 = (char *)&pLevelDecorations[0].uFlags;
-    do
+  for (size_t i = 0; i < uNumLevelDecorations; i++)
+  {
+    if (pLevelDecorations[i].uCog == uCog)
     {
-      if ( *((_WORD *)v4 + 9) == v6 )
+      if (pFileName && strcmp(pFileName, "0"))
       {
-        if ( pFileName && _stricmp(pFileName, "0") )
-        {
-          v5 = pDecorationList->GetDecorIdByName(pFileName);
-          *((_WORD *)v4 - 1) = v5;
-          pDecorationList->InitializeDecorationSprite((signed __int16)v5);
-        }
-        if ( v7 )
-          *v4 &= 0xDFu;
-        else
-          *v4 |= 0x20u;
-        pParty->uFlags |= 2u;
+        pLevelDecorations[i].uDecorationDescID = pDecorationList->GetDecorIdByName(pFileName);
+        pDecorationList->InitializeDecorationSprite(pLevelDecorations[i].uDecorationDescID);
       }
-      ++v3;
-      v4 += 32;
+
+      if (bHide)
+        pLevelDecorations[i].uFlags &= ~LEVEL_DECORATION_INVISIBLE;
+      else
+        pLevelDecorations[i].uFlags |= LEVEL_DECORATION_INVISIBLE;
+
+      pParty->uFlags |= 2u;
     }
-    while ( v3 < (signed int)uNumLevelDecorations );
   }
 }
 
@@ -7481,7 +7384,7 @@
   if ( v10 )
   {
     v11 = uNumActors;
-    SpawnEncounter((MapInfo *)&pMapStats->pInfos[v10], &v16, 0, count, 0);
+    SpawnEncounter(&pMapStats->pInfos[v10], &v16, 0, count, 0);
     memcpy(&v15, Actor::GetDirectionInfo(PID(OBJECT_Actor, v11), 4u, &a3, 1), sizeof(v15));
     v12 = v11;
     if ( (signed int)v11 < (signed int)uNumActors )
@@ -7497,7 +7400,6 @@
   }
 }
 
-// 4EE088: using guessed type __int16 word_4EE088_sound_ids[];
 
 //----- (0044987B) --------------------------------------------------------
 void sub_44987B(const char *pMapName, MapStartPoint start_point)
@@ -7538,6 +7440,8 @@
     case MapStartPoint_South: v10 = "South Start"; break;
     case MapStartPoint_East: v10 = "East Start";  break;
     case MapStartPoint_West: v10 = "West Start";  break;
+    default:
+      Error("Invalid enum value: %u", point);
   }
 
   strcpy(pName, v10);
@@ -7580,7 +7484,7 @@
         pParty->vPosition.z = _5B65B0_npcdata_rep_or_other;
         pParty->uFallStartY = _5B65B0_npcdata_rep_or_other;
       }
-      if ( _5B65B4_npcdata_loword_house_or_other )
+      if ( _5B65B4_npcdata_loword_house_or_other != -1 )
         pParty->sRotationY = _5B65B4_npcdata_loword_house_or_other;
       if ( _5B65B8_npcdata_hiword_house_or_other )
         pParty->sRotationX = _5B65B8_npcdata_hiword_house_or_other;
@@ -7610,7 +7514,7 @@
   unsigned int v7; // edx@18
   signed int v8; // esi@19
   int v9; // eax@19
-  char Args; // [sp+Ch] [bp-78h]@6
+  //char Args; // [sp+Ch] [bp-78h]@6
 
   LOWORD(v2) = LOWORD(pIndoor->pDoors);
   v3 = a2;
@@ -7628,8 +7532,7 @@
   while ( v4 < 200 );
   if ( v4 >= 200 )
   {
-    sprintf(&Args, "Unable to find Door ID: %i!", uDoorID);
-    Abortf(&Args);
+    Error("Unable to find Door ID: %i!", uDoorID);
   }
   v6 = &pIndoor->pDoors[v4];
   if ( v3 == 2 )
@@ -7714,14 +7617,11 @@
 
 //----- (0044C175) --------------------------------------------------------
 void ShowStatusBarString( const char *pString, unsigned int uNumSeconds )
-    {
-  unsigned int v2; // esi@1
-  int i; // eax@1
-
-  v2 = uNumSeconds;
+{
   strcpy(GameUI_Footer_TimedString.data(), pString);
-  GameUI_Footer_TimeLeft = 1000 * v2 + GetTickCount();
-  for ( i = pFontLucida->GetLineWidth(GameUI_Footer_TimedString.data());
+  GameUI_Footer_TimeLeft = 1000 * uNumSeconds + GetTickCount();
+
+  for (int i = pFontLucida->GetLineWidth(GameUI_Footer_TimedString.data());
         i > 450;
         i = pFontLucida->GetLineWidth(GameUI_Footer_TimedString.data()) )
     GameUI_Footer_TimedString[strlen(GameUI_Footer_TimedString.data()) - 1] = 0;
@@ -7731,7 +7631,7 @@
 void ShowNothingHereStatus()
 {
   if ( !GameUI_Footer_TimeLeft )
-    ShowStatusBarString(pGlobalTXT_LocalizationStrings[521], 2u);// Nothing here
+    ShowStatusBarString(pGlobalTXT_LocalizationStrings[521], 2);// Nothing here
 }
 
 //----- (0044C28B) --------------------------------------------------------
@@ -7781,23 +7681,18 @@
 }
 
 //----- (0040261D) --------------------------------------------------------
-int stru298::Add(__int16 uID, __int16 a3, __int16 x, __int16 y, __int16 z, char a7, char a8)
+void stru298::Add(__int16 uID, __int16 a3, __int16 x, __int16 y, __int16 z, char a7, char a8)
 {
-  int result; // eax@1
-
-  result = this->count;
-  if ( this->count < 100 )
-  {
-    this->pIDs[result] = uID;
-    this->pXs[this->count] = x;
-    this->pYs[this->count] = y;
-    this->pZs[this->count] = z;
-    this->field_324[this->count] = a3;
-    this->field_3EC[this->count] = a8;
-    result = this->count;
-    this->field_450[this->count++] = a7;
-  }
-  return result;
+  if (count < 100)
+  {
+    pIDs[count] = uID;
+    pXs[count] = x;
+    pYs[count] = y;
+    pZs[count] = z;
+    field_324[count] = a3;
+    field_3EC[count] = a8;
+    field_450[count++] = a7;
+  }
 }
 
 //----- (00402CAE) --------------------------------------------------------
--- a/mm7_4.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/mm7_4.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -2,8 +2,6 @@
 #define _CRT_SECURE_NO_WARNINGS
 #endif
 
-#include <assert.h>
-
 #include "Texture.h"
 #include "mm7_data.h"
 #include "VideoPlayer.h"
@@ -49,165 +47,33 @@
 //----- (0046CC4B) --------------------------------------------------------
 void check_event_triggers()
 {
-  int v0; // eax@1
   LevelDecoration *v1; // esi@2
-  signed int v2; // edi@2
-  int v3; // ebx@2
-  int v4; // eax@3
-  int v5; // ebx@3
-  unsigned int v6; // ecx@3
-  unsigned int v7; // edx@6
-  unsigned int v8; // edx@8
-  Actor *v9; // edi@13
-  int v10; // ebx@14
-  int v11; // eax@14
-  int v12; // ebx@14
-  unsigned int v13; // ecx@14
-  int v14; // edx@15
-  unsigned int v15; // edx@17
-  unsigned int v16; // edx@19
-  char *v17; // edi@25
-  int v18; // ebx@26
-  int v19; // eax@26
-  int v20; // ebx@26
-  unsigned int v21; // ecx@26
-  int v22; // edx@27
-  unsigned int v23; // edx@29
-  unsigned int v24; // edx@31
-  int v25; // [sp+0h] [bp-24h]@3
-  int v26; // [sp+0h] [bp-24h]@14
-  int v27; // [sp+0h] [bp-24h]@26
-  int v28; // [sp+4h] [bp-20h]@3
-  int v29; // [sp+4h] [bp-20h]@14
-  int v30; // [sp+4h] [bp-20h]@26
-  signed int v31; // [sp+8h] [bp-1Ch]@2
-  int v32; // [sp+Ch] [bp-18h]@2
-  int v33; // [sp+10h] [bp-14h]@2
-  int i; // [sp+14h] [bp-10h]@1
-  int v35; // [sp+18h] [bp-Ch]@2
-  int v36; // [sp+1Ch] [bp-8h]@3
-  signed int v37; // [sp+1Ch] [bp-8h]@12
-  signed int v38; // [sp+20h] [bp-4h]@24
 
-  v0 = 0;
-  for ( i = 0; i < num_event_triggers; ++i )
+  for (size_t i = 0; i < num_event_triggers; i++)
   {
-    v1 = &pLevelDecorations[event_triggers[v0]];
-    v2 = v1->field_18;
-    v3 = v1->vPosition.y;
-    v33 = v1->vPosition.x;
-    v32 = v1->vPosition.y;
-    v35 = v1->vPosition.z;
-    v31 = v1->field_18;
-    if (v1->uFlags & LEVEL_DECORATION_TRIGGERED_BY_TOUCH)
+    v1 = &pLevelDecorations[event_triggers[i]];
+
+    if (v1->uFlags & LEVEL_DECORATION_TRIGGERED_BY_TOUCH
+        && v1->vPosition.GetDistanceTo(pParty->vPosition) < v1->uTriggerRange)
     {
-      v36 = abs(v1->vPosition.x - pParty->vPosition.x);
-      v25 = abs(v3 - pParty->vPosition.y);
-      v28 = abs(v35 - pParty->vPosition.z);
-      v4 = v36;
-      v5 = v25;
-      v6 = v28;
-      if ( v36 < v25 )
-      {
-        v4 = v25;
-        v5 = v36;
-      }
-      if ( v4 < v28 )
-      {
-        v7 = v4;
-        v4 = v28;
-        v6 = v7;
-      }
-      if ( v5 < (signed int)v6 )
-      {
-        v8 = v6;
-        v6 = v5;
-        v5 = v8;
-      }
-      if ( (signed int)(((unsigned int)(11 * v5) >> 5) + (v6 >> 2) + v4) < v2 )
-        EventProcessor(v1->field_16_event_id, PID(OBJECT_Decoration,i), 1);
+      EventProcessor(v1->uEventID, PID(OBJECT_Decoration,i), 1);
     }
-    if (v1->uFlags & LEVEL_DECORATION_TRIGGERED_BY_MONSTER)
+    else if (v1->uFlags & LEVEL_DECORATION_TRIGGERED_BY_MONSTER)
     {
-      v37 = 0;
-      if ( (signed int)uNumActors > 0 )
+      for (size_t j = 0; j < uNumActors; j++)
       {
-        v9 = pActors.data();//[0].vPosition.y;
-        do
-        {
-		  v10 = abs(v33 - v9->vPosition.x);
-          v29 = abs(v32 - v9->vPosition.y);
-          v26 = abs(v35 - v9->vPosition.z);
-          v11 = v10;
-          v12 = v29;
-          v13 = v26;
-          if ( v11 < v29 )
-          {
-            v14 = v11;
-            v11 = v29;
-            v12 = v14;
-          }
-          if ( v11 < v26 )
-          {
-            v15 = v11;
-            v11 = v26;
-            v13 = v15;
-          }
-          if ( v12 < (signed int)v13 )
-          {
-            v16 = v13;
-            v13 = v12;
-            v12 = v16;
-          }
-          if ( (signed int)(((unsigned int)(11 * v12) >> 5) + (v13 >> 2) + v11) < v31 )
-            EventProcessor(v1->field_16_event_id, 0, 1);
-          ++v37;
-          ++v9;
-        }
-        while ( v37 < (signed int)uNumActors );
+        if (v1->vPosition.GetDistanceTo(pActors[j].vPosition) < v1->uTriggerRange)
+          EventProcessor(v1->uEventID, 0, 1);
       }
     }
-    if (v1->uFlags & LEVEL_DECORATION_TRIGGERED_BY_OBJECT)
+    else if (v1->uFlags & LEVEL_DECORATION_TRIGGERED_BY_OBJECT)
     {
-      v38 = 0;
-      if ( (signed int)uNumSpriteObjects > 0 )
+      for (size_t j = 0; j < uNumSpriteObjects; j++)
       {
-        v17 = (char *)&pSpriteObjects[0].vPosition.y;
-        do
-        {
-          v18 = abs(v33 - *((int *)v17 - 1));
-          v30 = abs(v32 - *(int *)v17);
-          v27 = abs(v35 - *((int *)v17 + 1));
-          v19 = v18;
-          v20 = v30;
-          v21 = v27;
-          if ( v19 < v30 )
-          {
-            v22 = v19;
-            v19 = v30;
-            v20 = v22;
-          }
-          if ( v19 < v27 )
-          {
-            v23 = v19;
-            v19 = v27;
-            v21 = v23;
-          }
-          if ( v20 < (signed int)v21 )
-          {
-            v24 = v21;
-            v21 = v20;
-            v20 = v24;
-          }
-          if ( (signed int)(((unsigned int)(11 * v20) >> 5) + (v21 >> 2) + v19) < v31 )
-            EventProcessor(v1->field_16_event_id, 0, 1);
-          ++v38;
-          v17 += 112;
-        }
-        while ( v38 < (signed int)uNumSpriteObjects );
+        if (v1->vPosition.GetDistanceTo(pSpriteObjects[j].vPosition) < v1->uTriggerRange)
+          EventProcessor(v1->uEventID, 0, 1);
       }
     }
-    v0 = i + 1;
   }
 }
 // 6836C8: using guessed type int 6836C8_num_decorations_6807E8;
@@ -492,16 +358,15 @@
                     v16 = v4 - stru_721530.normal.x;
                     v15 = v5 - stru_721530.normal.y;
                     v8 = stru_721530.prolly_normal_d + v3;
-                    v17 = ((v4 - stru_721530.normal.x) * stru_721530.field_58.y
-                         - (v5 - stru_721530.normal.y) * stru_721530.field_58.x) >> 16;
+                    v17 = ((v4 - stru_721530.normal.x) * stru_721530.direction.y
+                         - (v5 - stru_721530.normal.y) * stru_721530.direction.x) >> 16;
                     if ( abs(v17) <= stru_721530.prolly_normal_d + v3 )
                     {
-                      v9 = (v16 * stru_721530.field_58.x + v15 * stru_721530.field_58.y) >> 16;
+                      v9 = (v16 * stru_721530.direction.x + v15 * stru_721530.direction.y) >> 16;
                       if ( v9 > 0 )
                       {
                         v10 = v1->vPosition.z;
-                        v11 = stru_721530.normal.z
-                            + ((unsigned __int64)(stru_721530.field_58.z * (signed __int64)v9) >> 16);
+                        v11 = stru_721530.normal.z + fixpoint_sub0(stru_721530.direction.z, v9);
                         if ( v11 >= v10 )
                         {
                           if ( v11 <= v18 + v10 )
@@ -1690,7 +1555,7 @@
   v2 = fopen("data\\dpft.bin", "wb");
   v3 = v2;
   if ( !v2 )
-    Abortf("Unable to save dpft.bin!");
+    Error("Unable to save dpft.bin");
   fwrite(v1, 4u, 1u, v2);
   fwrite(v1->pFrames, 0xAu, v1->uNumFrames, v3);
   fclose(v3);
@@ -1747,7 +1612,7 @@
   v3 = fopen(Args, "r");
   File = v3;
   if ( !v3 )
-    Abortf("PlayerFrameTable::load - Unable to open file: %s.", Args);
+    Error("PlayerFrameTable::load - Unable to open file: %s.", Args);
   v4 = 0;
   v25 = 0;
   v26 = 1;
@@ -1760,7 +1625,7 @@
       if ( v24.uPropCount && *v24.pProperties[0] != 47 )
       {
         if ( v24.uPropCount < 3 )
-          Abortf("PlayerFrameTable::load, too few arguments, %s line %i.", Args, v26);
+          Error("PlayerFrameTable::load, too few arguments, %s line %i.", Args, v26);
         ++v25;
       }
       ++v26;
@@ -1772,7 +1637,7 @@
   v5 = pAllocator->AllocNamedChunk(v2->pFrames, 10 * v4, "P Frames");
   v2->pFrames = (PlayerFrame *)v5;
   if ( !v5 )
-    Abortf("PlayerFrameTable::load - Out of Memory!");
+    Error("PlayerFrameTable::load - Out of Memory!");
   v6 = File;
   v2->uNumFrames = 0;
   fseek(v6, 0, 0);
@@ -2190,7 +2055,7 @@
             if ( a5 == 3 )
             {
               v29 = pPlayer->GetPriceSell(a3->GetValue(), p2DEvents[(signed int)a4 - 1].fPriceMultiplier);
-              if (a3->Broken())
+              if (a3->IsBroken())
                 v29 = 1;
               sprintfex(a1, "%lu", v29);
               strcat(pTmpBuf2.data(), a1);
@@ -2207,7 +2072,7 @@
                 if ( a5 == 6 )
                 {
                   v29 = pPlayer->GetPriceSell(a3->GetValue(), p2DEvents[(signed int)a4 - 1].fPriceMultiplier) / 2;
-                  if (a3->Broken())
+                  if (a3->IsBroken())
                     v29 = 1;
                   if (!v29)
                     v29 = 1;
@@ -3761,7 +3626,7 @@
 					OracleDialogue();
 					break;
 				case 311:
-					sub_4BBA85_bounties();
+					CheckBountyRespawnAndAward();
 					break;
 				case 399:
                   __debugbreak(); // what kind of dialogue is that?
@@ -3793,7 +3658,7 @@
   bool test;
 
   if ( (p2DEvents[_2da_idx - 1].uType != 4 || (signed int)item->uItemID < 740 || (signed int)item->uItemID > 771)
-    && ((signed int)item->uItemID >= 600 || (signed int)item->uItemID >= 529 && (signed int)item->uItemID <= 599) || item->Stolen())
+    && ((signed int)item->uItemID >= 600 || (signed int)item->uItemID >= 529 && (signed int)item->uItemID <= 599) || item->IsStolen())
     return 0;
   switch( p2DEvents[_2da_idx - 1].uType )
   {
--- a/mm7_5.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/mm7_5.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -2,8 +2,6 @@
 #define _CRT_SECURE_NO_WARNINGS
 #endif
 
-#include <assert.h>
-
 #include "Texture.h"
 #include "mm7_data.h"
 #include "VideoPlayer.h"
@@ -1246,10 +1244,10 @@
                       if ( dword_506F14 )
                       {
                         Rest(_506F18_num_minutes_to_sleep);
-                        pParty->pPlayers[3].pConditions[2] = 0i64;
-                        pParty->pPlayers[2].pConditions[2] = 0i64;
-                        pParty->pPlayers[1].pConditions[2] = 0i64;
-                        pParty->pPlayers[0].pConditions[2] = 0i64;
+                        pParty->pPlayers[3].SetAsleep(false);
+                        pParty->pPlayers[2].SetAsleep(false);
+                        pParty->pPlayers[1].SetAsleep(false);
+                        pParty->pPlayers[0].SetAsleep(false);
                       }
                       pTexture_RestUI_CurrentSkyFrame->Release();
                       pTexture_RestUI_CurrentHourglassFrame->Release();
@@ -1257,6 +1255,11 @@
                       pTexture_RestUI_CurrentSkyFrame = 0;
                       pIcons_LOD->SyncLoadedFilesCount();
                       pIcons_LOD->RemoveTexturesPackFromTextureList();
+                      if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor)
+                      {
+                        pOutdoor->UpdateSunlightVectors();
+                        pOutdoor->UpdateFog();
+                      }
                       _506F18_num_minutes_to_sleep = 0;
                       dword_506F14 = 0;
                       dword_507B94 = 1;
@@ -1275,18 +1278,18 @@
                           unk_50C9A0 = 0;
                           back_to_game();
                          }
-                       }
-                       if ( (signed int)uActiveCharacter < 1 || (signed int)uActiveCharacter > 4 )
+                      }
+                      if ( (signed int)uActiveCharacter < 1 || (signed int)uActiveCharacter > 4 )
                         uActiveCharacter = pParty->GetNextActiveCharacter();
-                       pGUIWindow_CurrentMenu->Release();
-                       if ( pGUIWindow_CurrentMenu == window_SpeakInHouse )
-                       window_SpeakInHouse = 0;
-                       pGUIWindow_CurrentMenu = 0;
-                       pEventTimer->Resume();
-                       pCurrentScreen = SCREEN_GAME;
-                       viewparams->bRedrawGameUI = 1;
-                       pIcons_LOD->RemoveTexturesFromTextureList();
-                       continue;
+                      pGUIWindow_CurrentMenu->Release();
+                      if ( pGUIWindow_CurrentMenu == window_SpeakInHouse )
+                        window_SpeakInHouse = 0;
+                      pGUIWindow_CurrentMenu = 0;
+                      pEventTimer->Resume();
+                      pCurrentScreen = SCREEN_GAME;
+                      viewparams->bRedrawGameUI = 1;
+                      pIcons_LOD->RemoveTexturesFromTextureList();
+                      continue;
                     case SCREEN_E:
 						__debugbreak();
                       pGUIWindow_CurrentMenu->Release();
@@ -1688,7 +1691,7 @@
           {
             pParty->field_6E4 = 0;
             pParty->field_6E0 = 0;
-            pCastSpellInfo.data()->_427D48(1);
+            CastSpellInfoHelpers::_427D48();
             DialogueEnding();
             pEventTimer->Pause();
             pGameLoadingUI_ProgressBar->Initialize(GUIProgressBar::TYPE_Box);
@@ -1792,7 +1795,7 @@
             if ( !v47 )
               continue;
             pSpellInfo = (CastSpellInfo *)pGUIWindow_Settings->ptr_1C;
-            LOBYTE(pSpellInfo->field_8) &= 0xBFu;
+            pSpellInfo->uFlags &= ~0x40u;
             pSpellInfo->uPlayerID_2 = uMessageParam;
             pSpellInfo->spell_target_pid = v44;
             pParty->pPlayers[pSpellInfo->uPlayerID].SetRecoveryTime(300);
@@ -1810,7 +1813,7 @@
             if ( !v47 )
               continue;
             pSpellInfo = (CastSpellInfo *)pGUIWindow_Settings->ptr_1C;
-            LOBYTE(pSpellInfo->field_8) &= 0xBFu;
+            pSpellInfo->uFlags &= ~0x40u;
             pSpellInfo->uPlayerID_2 = uMessageParam;
             pSpellInfo->spell_target_pid = v44;
             pParty->pPlayers[pSpellInfo->uPlayerID].SetRecoveryTime(300);
@@ -1824,7 +1827,7 @@
           }
           if ( v45 == 5 )
           {
-            v48 = pLevelDecorations[v46].field_16_event_id == 0;
+            v48 = pLevelDecorations[v46].uEventID == 0;
           }
           else
           {
@@ -1837,7 +1840,7 @@
                 continue;
               v44 = uNumSeconds;
               pSpellInfo = (CastSpellInfo *)pGUIWindow_Settings->ptr_1C;
-              LOBYTE(pSpellInfo->field_8) &= 0xBFu;
+              pSpellInfo->uFlags &= ~0x40u;
               pSpellInfo->uPlayerID_2 = uMessageParam;
               pSpellInfo->spell_target_pid = v44;
               pParty->pPlayers[pSpellInfo->uPlayerID].SetRecoveryTime(300);
@@ -1857,7 +1860,7 @@
           if ( v48 )
             continue;
           pSpellInfo = (CastSpellInfo *)pGUIWindow_Settings->ptr_1C;
-          LOBYTE(pSpellInfo->field_8) &= 0xBFu;
+          pSpellInfo->uFlags &= ~0x40u;
           pSpellInfo->uPlayerID_2 = uMessageParam;
           pSpellInfo->spell_target_pid = v44;
           pParty->pPlayers[pSpellInfo->uPlayerID].SetRecoveryTime(300);
@@ -1886,13 +1889,13 @@
               switch ( uMessage )
               {
                 case UIMSG_CastSpell_Character_Big_Improvement:
-                  LOBYTE(pSpellInfo->field_8) &= 0xFDu;
+                  pSpellInfo->uFlags &= ~0x02u;
                   break;
                 case UIMSG_CastSpell_Character_Small_Improvement:
-                  HIBYTE(pSpellInfo->field_8) &= 0xFEu;
+                  pSpellInfo->uFlags &= ~0x0100u;
                   break;
                 case UIMSG_HiredNPC_CastSpell:
-                  HIBYTE(pSpellInfo->field_8) &= 0xFDu;
+                  pSpellInfo->uFlags &= ~0x0200u;
                   break;
               }
               pSpellInfo->uPlayerID_2 = uMessageParam;
@@ -2370,14 +2373,14 @@
           pSpellInfo = (CastSpellInfo *)pGUIWindow_Settings->ptr_1C;
           if ( uMessage == UIMSG_CastSpell_Shoot_Monster )
           {
-            LOBYTE(pSpellInfo->field_8) &= 0xF7;
+            pSpellInfo->uFlags &= ~0x08;
           }
           else
           {
             if ( uMessage == UIMSG_CastSpell_Monster_Improvement )
-              HIBYTE(pSpellInfo->field_8) &= 0xFEu;
+              pSpellInfo->uFlags &= ~0x0100u;
             else
-              HIBYTE(pSpellInfo->field_8) &= 0xFDu;
+              pSpellInfo->uFlags &= ~0x0200u;
           }
           pSpellInfo->uPlayerID_2 = uMessageParam;
           pSpellInfo->spell_target_pid = v44;
@@ -3235,7 +3238,7 @@
       }
     }
   }
-  pCastSpellInfo.data()->_427E01_cast_spell();
+  CastSpellInfoHelpers::_427E01_cast_spell();
 }
 
 //----- (004356FF) --------------------------------------------------------
@@ -3832,9 +3835,7 @@
   }
   stru_50FE08.count = 0;
 }
-// 50FE08: using guessed type stru298 stru_50FE08;
 
-// 4D864C: using guessed type char byte_4D864C;
 
 //----- (0043A97E) --------------------------------------------------------
 void __fastcall sub_43A97E(unsigned int uLayingItemID, signed int a2)
@@ -4669,8 +4670,8 @@
   int v21; // edi@20
   signed int v22; // eax@22
   signed __int64 v23; // qtt@22
-  bool result; // eax@25
-  int v25; // [sp+14h] [bp-8h]@14
+  //bool result; // eax@25
+  //int v25; // [sp+14h] [bp-8h]@14
   int a4a; // [sp+28h] [bp+Ch]@2
   signed int a5a; // [sp+2Ch] [bp+10h]@14
 
@@ -4720,23 +4721,24 @@
     {
 	  if( dword_4F5BF4_xs[i + 2] >= a4a || dword_4F5BF4_xs[i] >= a4a)
       {
-		  if ( (dword_4F5BF4_xs[i + 2] >= a4a && dword_4F5BF4_xs[i + 1] >= a4a)
-          || (v25 = dword_4F5BF4_xs[i + 2] - dword_4F5BF4_xs[i + 1],
-              LODWORD(v23) = v25 << 16,
-              HIDWORD(v23) = v25 >> 16,
-              dword_4F5BF4_xs[i + 1]
-            + ((signed int)(((unsigned __int64)(v23
-                                              / (dword_4F5B24_ys[i + 2] - dword_4F5B24_ys[i + 1])
-                                              * ((a3 - dword_4F5B24_ys[i + 1]) << 16)) >> 16)
-                          + 32768) >> 16) >= a4a) )
-          ++a5a;
+		  if (dword_4F5BF4_xs[i + 2] >= a4a && dword_4F5BF4_xs[i + 1] >= a4a)
+            ++a5a;
+          else
+          {
+              v23 = (__int64)(dword_4F5BF4_xs[i + 2] - dword_4F5BF4_xs[i + 1]) << 16;
+              __int64 _a = dword_4F5B24_ys[i + 2] - dword_4F5B24_ys[i + 1];
+              __int64 _b = (__int64)(a3 - dword_4F5B24_ys[i + 1]) << 16;
+
+              if (dword_4F5BF4_xs[i + 1] + ((((v23 / _a * _b) >> 16) + 32768) >> 16) >= a4a)
+                ++a5a;
+          }
 	  }
     }
   }
-  result = 1;
+
   if ( a5a != 1 )
-    result = 0;
-  return result;
+    return false;
+  return true;
 
 }
 
--- a/mm7_6.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/mm7_6.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -295,6 +295,7 @@
 		}
 	}
   }
+  pActor->uCarriedItemID = 1;
   if ( pActor->uCarriedItemID )
   {
     Dst.Reset();
@@ -318,12 +319,12 @@
     if ( pItemsTable->pItems[v5].uEquipType == 14 && v4 != 220 )
       Dst.uEnchantmentType = 2 * rand() % 4 + 2;
     pItemsTable->SetSpecialBonus(&Dst);
-    if ( !pParty->AddItem(&Dst) )
+    if ( !pParty->AddItemToParty(&Dst) )
       pParty->SetHoldingItem(&Dst);
     pActor->uCarriedItemID = 0;
     if ( pActor->array_000234[0].uItemID )
     {
-      if ( !pParty->AddItem(pActor->array_000234) )
+      if ( !pParty->AddItemToParty(pActor->array_000234) )
       {
         sub_421B2C_PlaceInInventory_or_DropPickedItem();
         pParty->SetHoldingItem(pActor->array_000234);
@@ -332,7 +333,7 @@
     }
     if ( pActor->array_000234[1].uItemID )
     {
-      if ( !pParty->AddItem(&pActor->array_000234[1]) )
+      if ( !pParty->AddItemToParty(&pActor->array_000234[1]) )
       {
         sub_421B2C_PlaceInInventory_or_DropPickedItem();
         pParty->SetHoldingItem(&pActor->array_000234[1]);
@@ -354,7 +355,7 @@
       else
         sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[471], v11);
       ShowStatusBarString(pTmpBuf2.data(), 2u);
-      if ( !pParty->AddItem(&Dst) )
+      if ( !pParty->AddItemToParty(&Dst) )
         pParty->SetHoldingItem(&Dst);
       v13 = 1;
     }
@@ -374,13 +375,13 @@
     sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[471], v10);
   ShowStatusBarString(pTmpBuf2.data(), 2u);
   v8 = pParty;
-  if ( !pParty->AddItem(&Dst) )
+  if ( !pParty->AddItemToParty(&Dst) )
     pParty->SetHoldingItem(&Dst);
   v13 = 1;
 LABEL_45:
   if ( pActor->array_000234[0].uItemID )
   {
-    if ( !v8->AddItem(pActor->array_000234) )
+    if ( !v8->AddItemToParty(pActor->array_000234) )
     {
       sub_421B2C_PlaceInInventory_or_DropPickedItem();
       v8->SetHoldingItem(pActor->array_000234);
@@ -390,7 +391,7 @@
   }
   if ( pActor->array_000234[1].uItemID )
   {
-    if ( !v8->AddItem(&pActor->array_000234[1]) )
+    if ( !v8->AddItemToParty(&pActor->array_000234[1]) )
     {
       sub_421B2C_PlaceInInventory_or_DropPickedItem();
       v8->SetHoldingItem(&pActor->array_000234[1]);
@@ -1110,14 +1111,14 @@
   if (!player->CanAct())
     return;
 
-  pCastSpellInfo.data()->_427D48(uActiveCharacter);
+  CastSpellInfoHelpers::_427D48();
     //v3 = 0;
   if (pParty->Invisible())
     pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].Reset();
 
     //v31 = player->pEquipment.uBow;
   int bow_idx = player->pEquipment.uBow;
-  if (bow_idx && player->pInventoryItemList[bow_idx - 1].Broken())
+  if (bow_idx && player->pInventoryItemList[bow_idx - 1].IsBroken())
     bow_idx = 0;
 
     //v32 = 0;
@@ -1131,7 +1132,7 @@
   {
     auto item = &player->pInventoryItemList[main_hand_idx - 1];
       //v5 = (char *)v1 + 36 * v4;
-    if (!item->Broken())
+    if (!item->IsBroken())
     {
 		//v28b = &v1->pInventoryItems[v4].uItemID;
         //v6 = v1->pInventoryItems[v4].uItemID;//*((int *)v5 + 124);
@@ -1675,14 +1676,14 @@
 
 
 //----- (0042FA66) --------------------------------------------------------
-int __fastcall _42FA66_do_explosive_impact(int a1, int a2, int a3, int a4, __int16 a5, signed int a6)
+void _42FA66_do_explosive_impact(int a1, int a2, int a3, int a4, __int16 a5, signed int a6)
 {
   int v6; // edi@1
   int v7; // esi@1
   char *v8; // ecx@2
   unsigned __int16 v9; // ax@5
   //int v10; // eax@10
-  signed int result; // eax@11
+  //signed int result; // eax@11
   //__int16 v12; // ax@12
   //SpriteObject a1a; // [sp+Ch] [bp-74h]@1
   int v14; // [sp+7Ch] [bp-4h]@1
@@ -1734,18 +1735,16 @@
   {
     a1a.spell_caster_pid = 0;
   }
-  result = a1a.Create(0, 0, 0, 0);
-  if ( result != -1 )
-  {
-    result = stru_50FE08.Add(PID(OBJECT_Item, result),
+
+  int id = a1a.Create(0, 0, 0, 0);
+  if (id != -1)
+    stru_50FE08.Add(PID(OBJECT_Item, id),
                a5,
                SLOWORD(a1a.vPosition.x),
                SLOWORD(a1a.vPosition.y),
                SLOWORD(a1a.vPosition.z),
                0,
                0);
-  }
-  return result;
 }
 
 //----- (0042FB5C) --------------------------------------------------------
@@ -2062,7 +2061,7 @@
                 v24 = pPlayers[uActiveCharacter]->GetAttackRecoveryTime(false);
                 if ( !pParty->bTurnBasedModeOn )
                   pPlayers[uActiveCharacter]->SetRecoveryTime((signed __int64)(flt_6BE3A4_debug_recmod1 * (double)v24 * 2.133333333333333));
-                pCastSpellInfo.data()->_427D48(uActiveCharacter);
+                CastSpellInfoHelpers::_427D48();
                 pTurnEngine->ApplyPlayerAction();
               }
             }
--- a/mm7_data.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/mm7_data.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -33,12 +33,6 @@
 #include "MapInfo.h"
 struct MapStats *pMapStats;
 
-
-
-#include "CastSpellInfo.h"
-std::array<CastSpellInfo, 10> pCastSpellInfo;
-CastSpellInfo stru_50CDB4; // idb
-
 #include "Viewport.h"
 struct Viewport *pViewport = new Viewport;
 struct ViewingParams *viewparams = new ViewingParams;
@@ -1018,7 +1012,7 @@
 char pStartingMapName[32]; // idb
 std::array<unsigned __int8, 5> IsPlayerWearingWatersuit;
 std::array<char, 54> party_has_equipment;
-std::array<char, 16> byte_5111F6;
+std::array<char, 17> byte_5111F6;
 
 int _unused000; // weak
 
@@ -1212,7 +1206,6 @@
 int uWindowX; // idb
 int uWindowY; // idb
 LONG uWindowStyle; // idb
-HMENU hOSMenu; // idb
 int dword_6BE340; // weak
 char pCurrentMapName[32]; // idb
 unsigned int uLevelMapStatsID;
@@ -1243,7 +1236,6 @@
 bool bNoLogo = false;
 bool bNoCD = false;
 bool bNoSound = false;
-int aborting_app; // weak
 std::array<int, 100> dword_720020_zvalues;
 std::array<int, 299> dword_7201B0_zvalues;
 int uTextureID_720980; // weak
@@ -1355,8 +1347,8 @@
 std::array<__int16, 777> word_F8B158; // weak
 struct Texture *ShopTexture; // idb
 std::array<struct Texture *, 12> ItemsInShopTexture;
-__int16 word_F8B1A0; // weak
-const char *dword_F8B1A4; // idb
+__int16 bountyHunting_monster_id_for_hunting; // word_F8B1A0
+const char *bountyHunting_text; // word_F8B1A4
 int contract_approved; // weak
 int dword_F8B1AC_award_bit_number; // idb
 int dword_F8B1B0; // weak
@@ -1382,5 +1374,3 @@
 std::array<__int16, 104> intersect_face_vertex_coords_list_b; // word_F8BD18
 int dword_F93F20; // weak
 int dword_F93F70; // weak
-
-volatile bool initing;
\ No newline at end of file
--- a/mm7_data.h	Sun Sep 08 17:07:47 2013 +0600
+++ b/mm7_data.h	Sun Sep 08 17:07:58 2013 +0600
@@ -660,7 +660,7 @@
 extern char pStartingMapName[32]; // idb
 extern std::array<unsigned __int8, 5> IsPlayerWearingWatersuit;
 extern std::array<char, 54> party_has_equipment;
-extern std::array<char, 16> byte_5111F6;
+extern std::array<char, 17> byte_5111F6;
 extern std::array<unsigned int, 16> papredoll_dbrds;
 
 extern int bRingsShownInCharScreen; // weak
@@ -858,7 +858,6 @@
 extern int uWindowX; // idb
 extern int uWindowY; // idb
 extern LONG uWindowStyle; // idb
-extern HMENU hOSMenu; // idb
 extern int dword_6BE340; // weak
 extern char pCurrentMapName[32]; // idb
 extern unsigned int uLevelMapStatsID;
@@ -889,7 +888,6 @@
 extern bool bNoLogo;
 extern bool bNoCD;
 extern bool bNoSound;
-extern int aborting_app; // weak
 extern std::array<int, 100> dword_720020_zvalues;
 extern std::array<int, 299> dword_7201B0_zvalues;
 extern int dword_7207F0[]; // idb
@@ -1009,8 +1007,8 @@
 extern std::array<__int16, 777> word_F8B158; // weak
 extern struct Texture *ShopTexture; // idb
 extern std::array<struct Texture *, 12> ItemsInShopTexture;
-extern __int16 word_F8B1A0; // weak
-extern const char *dword_F8B1A4; // idb
+extern __int16 bountyHunting_monster_id_for_hunting; // weak
+extern const char *bountyHunting_text; // idb
 extern int contract_approved; // weak
 extern int dword_F8B1AC_award_bit_number; // idb
 extern int dword_F8B1B0; // weak
@@ -1040,7 +1038,6 @@
 extern int dword_F93F20; // weak
 extern int dword_F93F70; // weak
 
-extern volatile bool initing; //ADDED
 
 
 
@@ -1136,7 +1133,7 @@
 bool __fastcall sub_42F7EB_DropItemAt(unsigned int uSpriteID, int x, int y, int z, int a4, int count, int a7, unsigned __int16 attributes, ItemGen *a9);
 void __fastcall sub_42F960_create_object(int x, int y, int z); // idb
 void CompactLayingItemsList();
-int __fastcall _42FA66_do_explosive_impact(int a1, int a2, int a3, int a4, __int16 a5, signed int a6);
+void _42FA66_do_explosive_impact(int a1, int a2, int a3, int a4, __int16 a5, signed int a6);
 bool _42FB5C_check_spell(signed int a1);
 void sub_42FBDD();
 void CloseWindowBackground();
@@ -1167,7 +1164,7 @@
 int __fastcall _43F55F_get_billboard_light_level(struct RenderBillboard *a1, int uBaseLightLevel);
 int __fastcall _43F5C8_get_point_light_level_with_respect_to_lights(unsigned int uBaseLightLevel, int uSectorID, float x, float y, float z);
 void PrepareBspRenderList_BLV();
-void __fastcall PrepareDecorationsRenderList_BLV(unsigned int uDecorationID, unsigned int uSectorID);
+void PrepareDecorationsRenderList_BLV(unsigned int uDecorationID, unsigned int uSectorID);
 void PrepareActorRenderList_BLV();
 void PrepareItemsRenderList_BLV();
 void AddBspNodeToRenderList(unsigned int node_id);
@@ -1199,7 +1196,6 @@
 void PrepareToLoadBLV(unsigned int bLoading);
 void __fastcall PrepareToLoadODM(unsigned int bLoading, struct OutdoorCamera *a2);
 void _461103_load_level_sub();
-int int_get_vector_length(signed int x, signed int y, signed int z);
 void MainMenu_Loop();
 char sub_4637E0_is_there_popup_onscreen();
 void ResetCursor_Palettes_LODs_Level_Audio_SFT_Windows();
@@ -1219,8 +1215,6 @@
 void CreateAsyncKeyboard();
 void MM6_Initialize(const wchar_t *pIniFilename);
 void MM7Initialization();
-int AbortWithError();
-void Abortf(const char *Format, ...);
 void SetCurrentMenuID(enum MENU_STATE); // idb
 enum MENU_STATE GetCurrentMenuID();
 void CreateMsgScrollWindow(signed int mscroll_id);
@@ -1244,7 +1238,7 @@
 void _4B4224_UpdateNPCTopics(int _this);
 void __fastcall DrawTextAtStatusBar(const char *Str, int a5);
 __int64 GetExperienceRequiredForLevel(int a1);
-const char *sub_4BBA85_bounties();
+void CheckBountyRespawnAndAward();
 void sub_4BBCDD();
 void __fastcall _4BBF61_summon_actor(int a1, __int16 x, int y, int z); // idb
 void ArenaFight();
@@ -1263,7 +1257,6 @@
 unsigned int WorldPosToGridCellZ(int); // weak
 int GridCellToWorldPosX(int); // weak
 int GridCellToWorldPosZ(int); // weak
-void ResetPolygons();
 void sub_481ED9_MessWithOutdoorCamera();
 bool IsTerrainSlopeTooHigh(int pos_x, int pos_y);
 int __fastcall GetTerrainHeightsAroundParty2(int a1, int a2, int *a3, int a4);
@@ -1361,13 +1354,13 @@
 int NPC_EventProcessor(int npc_event_id, int entry_line = 0);
 void __fastcall sub_448518_npc_set_item(int npc, unsigned int item, int a3);
 void __fastcall sub_44861E_set_texture(unsigned int uFaceCog, const char *pFilename);
-void __fastcall SetDecorationSprite(unsigned int uCog, int a2, const char *pFileName); // idb
+void __fastcall SetDecorationSprite(uint16_t uCog, bool bHide, const char *pFileName); // idb
 void __fastcall sub_44892E_set_faces_bit(int sCogNumber, int bit, int on);
 void __fastcall ToggleActorGroupFlag(unsigned int uGroupID, unsigned int uFlag, unsigned int bToggle);
 void  GameUI_StatusBar_UpdateTimedString(unsigned int bForceHide); // idb
 void OnTimer(int);
 void __fastcall sub_448CF4_spawn_monsters(__int16 typeindex, __int16 level, int count, int x, int y, int z, int group, unsigned int uUniqueName);
-void __fastcall EventCastSpell(int spellnum, int uSkillLevel, int uSkill, int fromx, int fromy, int fromz, int tox, int toy, int toz);//sub_448DF8
+void __fastcall EventCastSpell(int uSpellID, int uSkillLevel, int uSkill, int fromx, int fromy, int fromz, int tox, int toy, int toz);//sub_448DF8
 __int16 __fastcall sub_449A49_door_switch_animation(unsigned int uDoorID, int a2); // idb
 bool _449B57_test_bit(unsigned __int8 *a1, __int16 a2);
 void _449B7E_toggle_bit(unsigned char *pArray, __int16 a2, unsigned __int16 bToggle); // idb
--- a/mm7text_ru.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/mm7text_ru.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -5,9 +5,9 @@
 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
-#include <assert.h>
 
 #include "Log.h"
+#include "ErrorHandling.h"
 
 
 struct GenderTableEntry
@@ -1161,14 +1161,14 @@
   return nullptr;
 }
 
-int  sprintfex_internal(char *str)
+int sprintfex_internal(char *str)
 {
   auto p = strstr(str, "^");
   if (!p)
     return strlen(str);
 
   char buf[8192];
-  assert(strlen(str) < sizeof(buf));
+  Assert(strlen(str) < sizeof(buf));
 
   int next_integer_token = 0;
   bool integer_tokens_defined[10] = {false, false, false, false, false, false, false, false, false, false};
@@ -1190,7 +1190,7 @@
           goto _invalid_token;
         src += 3;  // ^I[
         
-        assert(next_integer_token < 10);
+        Assert(next_integer_token < 10);
         if (sscanf(src, "%d", &integer_tokens[next_integer_token]))
           integer_tokens_defined[next_integer_token++] = true;
 
@@ -1217,7 +1217,7 @@
         else if (src[2] != '[')
           goto _invalid_token;
 
-        assert(integer_tokens_defined[integer_token_idx]);
+        Assert(integer_tokens_defined[integer_token_idx]);
         src += 3; // ^L[
 
         auto ending1 = src;
@@ -1256,7 +1256,7 @@
       {
         if (src[2] != '[')
           goto _invalid_token;
-        assert(gender_token_defined);
+        Assert(gender_token_defined);
 
         src += 3; // ^R[
 
@@ -1285,7 +1285,7 @@
           actual_ending = ending3;
           actual_ending_len = src - ending3 - 1;
         }
-        else assert(false);
+        else Error("Invalid gender token");
 
         strncpy(dst, actual_ending, actual_ending_len);
         dst += actual_ending_len;
@@ -1367,8 +1367,7 @@
         strncpy(token, token_begin, token_len);
         token[token_len] = 0;
 
-        Log::Warning(L"Invalid format token: %S", token);
-        assert(false);
+        Error("Invalid format token: %s", token);
       }
       break;
     }
--- a/stru10.cpp	Sun Sep 08 17:07:47 2013 +0600
+++ b/stru10.cpp	Sun Sep 08 17:07:58 2013 +0600
@@ -1,10 +1,9 @@
-#include <assert.h>
-
 #include "stru10.h"
 #include "Render.h"
 #include "Indoor.h"
 #include "Game.h"
 #include "Party.h"
+#include "ErrorHandling.h"
 
 #include "mm7_data.h"
 
@@ -81,7 +80,7 @@
 //----- (0049CE9E) --------------------------------------------------------
 void stru10::_49CE9E(BLVFace *pFace, RenderVertexSoft *pVertices, unsigned int uNumVertices, RenderVertexSoft *pOutLimits)
 {
-  assert(sizeof(RenderVertexSoft) == 0x30);
+  Assert(sizeof(RenderVertexSoft) == 0x30);
   
   RenderVertexSoft pLimits[64];
   stru10::CalcPolygonLimits(pFace, pLimits);
@@ -273,7 +272,7 @@
     break;
 
     default:
-      assert(false);
+      Error("Invalid polygon type (%u)", pFace->uPolygonType);
   }
 
 
--- a/stru298.h	Sun Sep 08 17:07:47 2013 +0600
+++ b/stru298.h	Sun Sep 08 17:07:58 2013 +0600
@@ -4,7 +4,7 @@
 #pragma pack(push, 1)
 struct stru298
 {
-  int Add(__int16 uID, __int16 a3, __int16 x, __int16 y, __int16 z, char a7, char a8);
+  void Add(__int16 uID, __int16 a3, __int16 x, __int16 y, __int16 z, char a7, char a8);
 
   int count;
   __int16 pIDs[100];