changeset 1588:e6ac4919b22c

Слияние
author Ritor1
date Mon, 09 Sep 2013 09:13:40 +0600
parents b42e6f35e03d (current diff) 6d759814a817 (diff)
children f408fbf3d9cc
files UI/UIHouses.cpp
diffstat 80 files changed, 2138 insertions(+), 3048 deletions(-) [+]
line wrap: on
line diff
--- a/Actor.cpp	Mon Sep 09 09:13:23 2013 +0600
+++ b/Actor.cpp	Mon Sep 09 09:13:40 2013 +0600
@@ -2,9 +2,6 @@
 #define _CRT_SECURE_NO_WARNINGS
 #endif
 
-#include <assert.h>
-
-
 #include "mm7_data.h"
 #include "DecalBuilder.h"
 
@@ -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);
   }
@@ -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/Allocator.cpp	Mon Sep 09 09:13:23 2013 +0600
+++ b/Allocator.cpp	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/Arcomage.cpp	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/Arcomage.h	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/AudioPlayer.cpp	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/CShow.h	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/CastSpellInfo.cpp	Mon Sep 09 09:13:40 2013 +0600
@@ -998,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)
@@ -1950,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)
@@ -2957,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);
--- a/Chest.cpp	Mon Sep 09 09:13:23 2013 +0600
+++ b/Chest.cpp	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/Conditions.cpp	Mon Sep 09 09:13:40 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/DecorationList.cpp	Mon Sep 09 09:13:23 2013 +0600
+++ b/DecorationList.cpp	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/Events.cpp	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/GUIFont.cpp	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/GUIProgressBar.cpp	Mon Sep 09 09:13:40 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/Game.cpp	Mon Sep 09 09:13:23 2013 +0600
+++ b/Game.cpp	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/IconFrameTable.cpp	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/Indoor.cpp	Mon Sep 09 09:13:40 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();
   
@@ -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;
       }
--- a/IndoorCameraD3D.cpp	Mon Sep 09 09:13:23 2013 +0600
+++ b/IndoorCameraD3D.cpp	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/Indoor_stuff.h	Mon Sep 09 09:13:40 2013 +0600
@@ -247,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;
@@ -287,7 +285,7 @@
   int field_A4;
 };
 #pragma pack(pop)
-extern stru141 stru_721530;
+extern stru141_actor_collision_object stru_721530;
 
 
 
--- a/Items.cpp	Mon Sep 09 09:13:23 2013 +0600
+++ b/Items.cpp	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/Items.h	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/LOD.cpp	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/LOD.h	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/Level/Decoration.cpp	Mon Sep 09 09:13:40 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/LightmapBuilder.cpp	Mon Sep 09 09:13:23 2013 +0600
+++ b/LightmapBuilder.cpp	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/Log.cpp	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/MM7.h	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/Math.h	Mon Sep 09 09:13:40 2013 +0600
@@ -24,9 +24,10 @@
 };
 #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);
 
 template <typename FloatType>
--- a/Monsters.cpp	Mon Sep 09 09:13:23 2013 +0600
+++ b/Monsters.cpp	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/Mouse.cpp	Mon Sep 09 09:13:40 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/OSAPI.cpp	Mon Sep 09 09:13:23 2013 +0600
+++ b/OSAPI.cpp	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/OSAPI.h	Mon Sep 09 09:13:40 2013 +0600
@@ -1,5 +1,4 @@
 #define WIN32_LEAN_AND_MEAN
-#include <assert.h>
 #include <windows.h>
 
 #include <MMSystem.h>
--- a/ObjectList.cpp	Mon Sep 09 09:13:23 2013 +0600
+++ b/ObjectList.cpp	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/Outdoor.cpp	Mon Sep 09 09:13:40 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];
--- a/Outdoor_stuff.h	Mon Sep 09 09:13:23 2013 +0600
+++ b/Outdoor_stuff.h	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/Overlays.cpp	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/PaletteManager.cpp	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/Party.cpp	Mon Sep 09 09:13:40 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;
--- a/Party.h	Mon Sep 09 09:13:23 2013 +0600
+++ b/Party.h	Mon Sep 09 09:13:40 2013 +0600
@@ -186,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();
   
@@ -219,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
--- a/Player.cpp	Mon Sep 09 09:13:23 2013 +0600
+++ b/Player.cpp	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/Player.h	Mon Sep 09 09:13:40 2013 +0600
@@ -463,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();
@@ -483,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();
@@ -537,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();
@@ -581,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();
@@ -613,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	Mon Sep 09 09:13:23 2013 +0600
+++ b/Render.cpp	Mon Sep 09 09:13:40 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"
@@ -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/SaveLoad.cpp	Mon Sep 09 09:13:23 2013 +0600
+++ b/SaveLoad.cpp	Mon Sep 09 09:13:40 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/SpriteObject.cpp	Mon Sep 09 09:13:23 2013 +0600
+++ b/SpriteObject.cpp	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/SpriteObject.h	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/Sprites.cpp	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/Texture.cpp	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/TileTable.cpp	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/TurnEngine.cpp	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/UI/Books/UIMapBook.cpp	Mon Sep 09 09:13:40 2013 +0600
@@ -2,8 +2,6 @@
 #define _CRT_SECURE_NO_WARNINGS
 #endif
 
-#include <assert.h>
-
 #include "..\..\MM7.h"
 #include "..\..\Render.h"
 #include "..\..\Mouse.h"
--- a/UI/Books/UINotesBooks.cpp	Mon Sep 09 09:13:23 2013 +0600
+++ b/UI/Books/UINotesBooks.cpp	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/UI/Books/UISpellBook.cpp	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/UI/UIBooks.cpp	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/UI/UICharacter.cpp	Mon Sep 09 09:13:40 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);
--- a/UI/UIGuilds.cpp	Mon Sep 09 09:13:23 2013 +0600
+++ b/UI/UIGuilds.cpp	Mon Sep 09 09:13:40 2013 +0600
@@ -329,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	Mon Sep 09 09:13:23 2013 +0600
+++ b/UI/UIHouses.cpp	Mon Sep 09 09:13:40 2013 +0600
@@ -558,7 +558,7 @@
       break;
 
     default:
-      assert(false && "Invalid enumeration value");
+      Error("Invalid enumeration value: %u", type);
   }
 
 /*  if ( a1 > 13 )
@@ -867,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;
@@ -2321,141 +2321,116 @@
 //----- (004B7D7E) --------------------------------------------------------
 void  BankDialog()
 {
-  GUIWindow *v0; // eax@4
-  //int v1; // ecx@5
-  int v2; // eax@6
-  unsigned int v3; // esi@6
-  GUIFont *v4; // ST10_4@12
-  int v5; // eax@12
-  int v6; // eax@19
-  unsigned int v7; // esi@19
-  unsigned __int16 v8; // ax@27
-  unsigned __int16 v9; // ax@29
-  char *v10; // [sp-8h] [bp-70h]@11
-  char *v11; // [sp-4h] [bp-6Ch]@11
-  GUIWindow _this; // [sp+Ch] [bp-5Ch]@1
-  __int16 v13[2]; // [sp+60h] [bp-8h]@1
-  __int16 v14[2]; // [sp+64h] [bp-4h]@1
+  int entered_sum; // eax@19
+  unsigned int takes_sum; // esi@19
+  unsigned __int16 pColorText; // ax@27
+  GUIWindow bank_window; // [sp+Ch] [bp-5Ch]@1
 
-  memcpy(&_this, window_SpeakInHouse, sizeof(_this));
-  _this.uFrameX = 483;
-  _this.uFrameWidth = 148;
-  _this.uFrameZ = 334;
-  *(int *)v13 = TargetColor(0xFFu, 0xFFu, 0xFFu);
-  *(int *)v14 = TargetColor(0xFFu, 0xFFu, 0x9Bu);
-  sprintf(pTmpBuf.data(), "%s: %d", pGlobalTXT_LocalizationStrings[25], pParty->uNumGoldInBank);
-  _this.DrawTitleText(pFontArrus, 0, 0xDCu, v14[0], pTmpBuf.data(), 3u);
+  memcpy(&bank_window, window_SpeakInHouse, sizeof(bank_window));
+  bank_window.uFrameX = 483;
+  bank_window.uFrameWidth = 148;
+  bank_window.uFrameZ = 334;
+  sprintf(pTmpBuf.data(), "%s: %d", pGlobalTXT_LocalizationStrings[25], pParty->uNumGoldInBank);//
+  bank_window.DrawTitleText(pFontArrus, 0, 220, TargetColor(0xFFu, 0xFFu, 0x9Bu), pTmpBuf.data(), 3);
   switch(dialog_menu_id)
   {
-	case HOUSE_DIALOGUE_MAIN:
-		{
-		v8 = v14[0];
-		if ( pDialogueWindow->pCurrentPosActiveItem != 2 )
-			v8 = v13[0];
-		_this.DrawTitleText(pFontArrus, 0, 0x92u, v8, pGlobalTXT_LocalizationStrings[60], 3u);
-		v9 = v14[0];
-		if ( pDialogueWindow->pCurrentPosActiveItem != 3 )
-			v9 = v13[0];
-		_this.DrawTitleText(pFontArrus, 0, 0xB0u, v9, pGlobalTXT_LocalizationStrings[244], 3u);
-		break;
-		}
-	case HOUSE_DIALOGUE_BANK_7:
-		{
-		v0 = window_SpeakInHouse;
-		if ( window_SpeakInHouse->receives_keyboard_input_2 != WINDOW_INPUT_IN_PROGRESS)
-		{
-			if ( window_SpeakInHouse->receives_keyboard_input_2 == WINDOW_INPUT_CONFIRMED)
-			{
-				v6 = atoi((const char *)pKeyActionMap->pPressedKeysBuffer);
-				v7 = v6;
-				if ( !v6 )
-				{
-					pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
-					return;
-				}
-				if ( v6 > pParty->uNumGold )
-				{
-					PlayHouseSound((unsigned int)window_SpeakInHouse->ptr_1C, HouseSound_NotEnoughMoney_TrainingSuccessful);
-					v7 = pParty->uNumGold;
-				}
-				if ( v7 )
-				{
-					Party::TakeGold(v7);
-					pParty->uNumGoldInBank += v7;
-					if ( uActiveCharacter )
-						pPlayers[uActiveCharacter]->PlaySound(SPEECH_81, 0);
-				}
-				v0 = window_SpeakInHouse;
-				v0->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
-				pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
-				return;
-			}
-			if (window_SpeakInHouse->receives_keyboard_input_2 != WINDOW_INPUT_CANCELLED)
-				return;
-			v0->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
-			pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
-			return;      
-		}
-		v11 = pGlobalTXT_LocalizationStrings[112];
-		v10 = pGlobalTXT_LocalizationStrings[60];
-		sprintf(pTmpBuf.data(), "%s\n%s", v10, v11);
-		_this.DrawTitleText(pFontArrus, 0, 0x92u, v14[0], pTmpBuf.data(), 3u);
-		_this.DrawTitleText(pFontArrus, 0, 0xBAu, v13[0], (const char *)pKeyActionMap->pPressedKeysBuffer, 3u);
-		v4 = pFontArrus;
-		v5 = pFontArrus->GetLineWidth((const char *)pKeyActionMap->pPressedKeysBuffer);
-		_this.DrawFlashingInputCursor(v5 / 2 + 80, 185, v4);
-		break;
-		}
-
-	case HOUSE_DIALOGUE_BANK_8:
-		{
-		v0 = window_SpeakInHouse;
-		if ( window_SpeakInHouse->receives_keyboard_input_2 != WINDOW_INPUT_IN_PROGRESS)
-		{
-			if ( window_SpeakInHouse->receives_keyboard_input_2 == WINDOW_INPUT_CONFIRMED)
-			{
-				window_SpeakInHouse->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
-				v2 = atoi((const char *)pKeyActionMap->pPressedKeysBuffer);
-				v3 = v2;
-				if ( v2 )
-				{
-					if ( v2 > pParty->uNumGoldInBank )
-					{
-						PlayHouseSound((unsigned int)window_SpeakInHouse->ptr_1C, HouseSound_NotEnoughMoney_TrainingSuccessful);
-						v3 = pParty->uNumGoldInBank;
-					}
-					if ( v3 )
-					{
-						Party::SetGold(pParty->uNumGold + v3);
-						pParty->uNumGoldInBank -= v3;
-					}
-				}
-                v0->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
-				pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
-				return;
-			}
-			if ( window_SpeakInHouse->receives_keyboard_input_2 != WINDOW_INPUT_CANCELLED)
-				return;
-			v0->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
-			pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
-			return;  
-		}
-		v11 = pGlobalTXT_LocalizationStrings[112];
-		v10 = pGlobalTXT_LocalizationStrings[244];
-		sprintfex(pTmpBuf.data(), "%s\n%s", v10, v11);
-		_this.DrawTitleText(pFontArrus, 0, 0x92u, v14[0], pTmpBuf.data(), 3u);
-		_this.DrawTitleText(pFontArrus, 0, 0xBAu, v13[0], (const char *)pKeyActionMap->pPressedKeysBuffer, 3u);
-		v4 = pFontArrus;
-		v5 = pFontArrus->GetLineWidth((const char *)pKeyActionMap->pPressedKeysBuffer);
-		_this.DrawFlashingInputCursor(v5 / 2 + 80, 185, v4);
-		return;
-		break;
-		}
-
-	default:
-		{
-		break;
-		}
+    case HOUSE_DIALOGUE_MAIN:
+    {
+      pColorText = TargetColor(0xFFu, 0xFFu, 0x9Bu);
+      if ( pDialogueWindow->pCurrentPosActiveItem != 2 )
+        pColorText = TargetColor(0xFFu, 0xFFu, 0xFFu);
+      bank_window.DrawTitleText(pFontArrus, 0, 146, pColorText, pGlobalTXT_LocalizationStrings[60], 3);
+      pColorText = TargetColor(0xFFu, 0xFFu, 0x9Bu);
+      if ( pDialogueWindow->pCurrentPosActiveItem != 3 )
+        pColorText = TargetColor(0xFFu, 0xFFu, 0xFFu);
+      bank_window.DrawTitleText(pFontArrus, 0, 176, pColorText, pGlobalTXT_LocalizationStrings[244], 3);
+      break;
+    }
+    case HOUSE_DIALOGUE_BANK_PUT_GOLD:
+    {
+      if ( window_SpeakInHouse->receives_keyboard_input_2 == WINDOW_INPUT_IN_PROGRESS)
+      {
+        sprintf(pTmpBuf.data(), "%s\n%s", pGlobalTXT_LocalizationStrings[60], pGlobalTXT_LocalizationStrings[112]);//"" "?"
+        bank_window.DrawTitleText(pFontArrus, 0, 146, TargetColor(0xFFu, 0xFFu, 0x9Bu), pTmpBuf.data(), 3);
+        bank_window.DrawTitleText(pFontArrus, 0, 186, TargetColor(0xFFu, 0xFFu, 0xFFu), (const char *)pKeyActionMap->pPressedKeysBuffer, 3);
+        bank_window.DrawFlashingInputCursor(pFontArrus->GetLineWidth((const char *)pKeyActionMap->pPressedKeysBuffer) / 2 + 80, 185, pFontArrus);
+        return;
+      }
+      if ( window_SpeakInHouse->receives_keyboard_input_2 == WINDOW_INPUT_CONFIRMED)
+      {
+        entered_sum = atoi((const char *)pKeyActionMap->pPressedKeysBuffer);
+        takes_sum = entered_sum;
+        if ( !entered_sum )
+        {
+          pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
+          return;
+        }
+        if ( entered_sum > pParty->uNumGold )
+        {
+          PlayHouseSound((unsigned int)window_SpeakInHouse->ptr_1C, HouseSound_NotEnoughMoney_TrainingSuccessful);
+          takes_sum = pParty->uNumGold;
+        }
+        if ( takes_sum )
+        {
+          Party::TakeGold(takes_sum);
+          pParty->uNumGoldInBank += takes_sum;
+          if ( uActiveCharacter )
+            pPlayers[uActiveCharacter]->PlaySound(SPEECH_81, 0);
+        }
+        window_SpeakInHouse->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
+        pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
+        return;
+      }
+      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);
+      }
+      return;
+    }
+    case HOUSE_DIALOGUE_BANK_GET_GOLD:
+    {
+      if ( window_SpeakInHouse->receives_keyboard_input_2 == WINDOW_INPUT_IN_PROGRESS)
+      {
+        sprintfex(pTmpBuf.data(), "%s\n%s", pGlobalTXT_LocalizationStrings[244], pGlobalTXT_LocalizationStrings[112]);//"" "?"
+        bank_window.DrawTitleText(pFontArrus, 0, 146, TargetColor(0xFFu, 0xFFu, 0x9Bu), pTmpBuf.data(), 3);
+        bank_window.DrawTitleText(pFontArrus, 0, 186, TargetColor(0xFFu, 0xFFu, 0xFFu), (const char *)pKeyActionMap->pPressedKeysBuffer, 3);
+        bank_window.DrawFlashingInputCursor(pFontArrus->GetLineWidth((const char *)pKeyActionMap->pPressedKeysBuffer) / 2 + 80, 185, pFontArrus);
+        return;
+      }
+      if ( window_SpeakInHouse->receives_keyboard_input_2 == WINDOW_INPUT_CONFIRMED)
+      {
+        window_SpeakInHouse->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
+        entered_sum = atoi((const char *)pKeyActionMap->pPressedKeysBuffer);
+        takes_sum = entered_sum;
+        if ( entered_sum )
+        {
+          if ( entered_sum > pParty->uNumGoldInBank )
+          {
+            PlayHouseSound((unsigned int)window_SpeakInHouse->ptr_1C, HouseSound_NotEnoughMoney_TrainingSuccessful);
+            takes_sum = pParty->uNumGoldInBank;
+          }
+          if ( takes_sum )
+          {
+            Party::SetGold(pParty->uNumGold + takes_sum);
+            pParty->uNumGoldInBank -= takes_sum;
+          }
+        }
+        window_SpeakInHouse->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
+        pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
+        return;
+      }
+      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);
+      }
+      return;
+    }
+    default:
+    {
+      break;
+    }
   }
 }
 // F8B19C: using guessed type int dword_F8B19C;
@@ -4041,7 +4016,10 @@
           goto LABEL_49;
         }
         if ( v28 != 10 )
-          goto LABEL_41;
+        {
+          v15 = "";
+          goto LABEL_49;
+        }
       }
       else
       {
--- a/UI/UIHouses.h	Mon Sep 09 09:13:23 2013 +0600
+++ b/UI/UIHouses.h	Mon Sep 09 09:13:40 2013 +0600
@@ -10,8 +10,8 @@
   HOUSE_DIALOGUE_SHOP_IDENTIFY = 4,
   HOUSE_DIALOGUE_SHOP_REPAIR = 5,
   HOUSE_DIALOGUE_SHOP_6 = 6,
-  HOUSE_DIALOGUE_BANK_7 = 7,
-  HOUSE_DIALOGUE_BANK_8 = 8,
+  HOUSE_DIALOGUE_BANK_PUT_GOLD = 7,
+  HOUSE_DIALOGUE_BANK_GET_GOLD = 8,
   HOUSE_DIALOGUE_9 = 9,
   HOUSE_DIALOGUE_TEMPLE_HEAL = 10,
   HOUSE_DIALOGUE_TEMPLE_DONATE = 11,
--- a/UI/UIMainMenu.cpp	Mon Sep 09 09:13:23 2013 +0600
+++ b/UI/UIMainMenu.cpp	Mon Sep 09 09:13:40 2013 +0600
@@ -2,9 +2,6 @@
 #define _CRT_SECURE_NO_WARNINGS
 #endif
 
-#include <assert.h>
-
-
 #include "..\Mouse.h"
 #include "..\Keyboard.h"
 
@@ -76,12 +73,6 @@
 //----- (0041B690) --------------------------------------------------------
 void MainMenuUI_Create()
 {
-    //unsigned int v0; // eax@1
-    //unsigned int v1; // eax@1
-    //unsigned int v2; // eax@1
-    //unsigned int v3; // eax@1
-    //unsigned int v4; // eax@1
-    //unsigned int v5; // eax@1
     Texture *v6; // ST78_4@1
     //const char *v7; // ST5C_4@1
     unsigned __int8 v8; // al@1
@@ -278,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	Mon Sep 09 09:13:23 2013 +0600
+++ b/UI/UIOptions.cpp	Mon Sep 09 09:13:40 2013 +0600
@@ -1,5 +1,3 @@
-#include <assert.h>
-
 #include "..\MM7.h"
 
 #include "..\Keyboard.h"
--- a/UI/UIPartyCreation.cpp	Mon Sep 09 09:13:23 2013 +0600
+++ b/UI/UIPartyCreation.cpp	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/UI/UIPopup.cpp	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/UI/UIRest.cpp	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/UI/UISaveLoad.cpp	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/UI/UIShops.cpp	Mon Sep 09 09:13:40 2013 +0600
@@ -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);
@@ -918,7 +918,7 @@
             if ( v2 )
             {
               v3 = (ItemGen *)&pPlayers[uActiveCharacter]->pInventoryItemList[v2-1];
-              if (v3->Identified())
+              if (v3->IsIdentified())
                 v5 = "%24";
               else
               {
@@ -1407,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];
--- a/UI/UITransition.cpp	Mon Sep 09 09:13:23 2013 +0600
+++ b/UI/UITransition.cpp	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/UI/UiGame.cpp	Mon Sep 09 09:13:40 2013 +0600
@@ -2,8 +2,6 @@
 #define _CRT_SECURE_NO_WARNINGS
 #endif
 
-#include <assert.h>
-
 #include "..\Texture.h"
 #include "..\MM7.h"
 
--- a/Viewport.cpp	Mon Sep 09 09:13:23 2013 +0600
+++ b/Viewport.cpp	Mon Sep 09 09:13:40 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);
--- a/Vis.cpp	Mon Sep 09 09:13:23 2013 +0600
+++ b/Vis.cpp	Mon Sep 09 09:13:40 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);
 
--- a/_deleted.cpp	Mon Sep 09 09:13:23 2013 +0600
+++ b/_deleted.cpp	Mon Sep 09 09:13:40 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,6 +12276,75 @@
     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;
--- a/mm7_1.cpp	Mon Sep 09 09:13:23 2013 +0600
+++ b/mm7_1.cpp	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/mm7_2.cpp	Mon Sep 09 09:13:40 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"
@@ -685,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
@@ -805,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 )
     {
@@ -824,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 );
@@ -3091,32 +3087,6 @@
       event_triggers[num_event_triggers++] = i;
 }
 
-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()
 {
@@ -3171,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)
     {
@@ -3258,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:
@@ -3292,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;
     }
 
@@ -3310,7 +3286,7 @@
 
         case 101:  // Quit game
         case 40001:
-          SendMessageA(::hWnd, WM_DESTROY, 0, 0);
+          SendMessageW(hWnd, WM_DESTROY, 0, 0);
         return 0;
 
 
@@ -3479,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 )
       {
@@ -3844,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) --------------------------------------------------------
@@ -3980,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;
@@ -4384,7 +4298,6 @@
 //----- (004651F4) --------------------------------------------------------
 bool MM7_Initialize()
 {
-initing=true; //ADDED Gloval
   wchar_t pCurrentDir[1024];
   _wgetcwd(pCurrentDir, 1024);
 
@@ -4426,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;
@@ -4452,10 +4360,9 @@
                          uWindowX, uWindowY,
                          640, 480,
                          nullptr,
-                         hOSMenu = nullptr,
+                         nullptr,
                          wcxw.hInstance,
                          nullptr);
-  SetWindowTextW(hWnd, L"Might and Magic VII");
 
   HMENU menu = CreateMenu();
   {
@@ -4664,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"))
@@ -4717,7 +4623,7 @@
   }
 
 
-
+#if 0
   if (_access("../MM_VI/data/icons.lod", 0) == 0)
   {
     pIcons_LOD_mm6 = new LODFile_IconsBitmaps;
@@ -4760,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;
@@ -4910,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))// 
@@ -4999,7 +4885,7 @@
       break;
     }
 
-  initing = false; //ADDED Gloval
+  ShowWindow(hWnd, SW_SHOWNORMAL);
   return true;
 }
 
@@ -5182,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);
@@ -5248,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[;;]", "");
@@ -5312,7 +5185,6 @@
     pGame->Deinitialize();
     return 1;
   }
-  Log::Warning(L"MM init: ok");
 
     pEventTimer->Pause();
 
@@ -5322,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");
@@ -5395,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();
 		  }
@@ -5434,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);
       }
@@ -5640,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)
 {
--- a/mm7_3.cpp	Mon Sep 09 09:13:23 2013 +0600
+++ b/mm7_3.cpp	Mon Sep 09 09:13:40 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) --------------------------------------------------------
@@ -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;
@@ -7466,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 )
@@ -7482,7 +7400,6 @@
   }
 }
 
-// 4EE088: using guessed type __int16 word_4EE088_sound_ids[];
 
 //----- (0044987B) --------------------------------------------------------
 void sub_44987B(const char *pMapName, MapStartPoint start_point)
@@ -7523,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);
@@ -7595,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;
@@ -7613,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 )
@@ -7699,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;
@@ -7716,7 +7631,7 @@
 void ShowNothingHereStatus()
 {
   if ( !GameUI_Footer_TimeLeft )
-    ShowStatusBarString(pGlobalTXT_LocalizationStrings[521], 2u);// Nothing here
+    ShowStatusBarString(pGlobalTXT_LocalizationStrings[521], 2);// Nothing here
 }
 
 //----- (0044C28B) --------------------------------------------------------
@@ -7766,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	Mon Sep 09 09:13:23 2013 +0600
+++ b/mm7_4.cpp	Mon Sep 09 09:13:40 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"
@@ -360,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 )
@@ -1558,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);
@@ -1615,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;
@@ -1628,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;
@@ -1640,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);
@@ -2058,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);
@@ -2075,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;
@@ -3661,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	Mon Sep 09 09:13:23 2013 +0600
+++ b/mm7_5.cpp	Mon Sep 09 09:13:40 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"
@@ -3837,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)
@@ -4674,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
 
@@ -4725,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	Mon Sep 09 09:13:23 2013 +0600
+++ b/mm7_6.cpp	Mon Sep 09 09:13:40 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]);
@@ -1117,7 +1118,7 @@
 
     //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) --------------------------------------------------------
--- a/mm7_data.cpp	Mon Sep 09 09:13:23 2013 +0600
+++ b/mm7_data.cpp	Mon Sep 09 09:13:40 2013 +0600
@@ -1206,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;
@@ -1237,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
@@ -1376,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	Mon Sep 09 09:13:23 2013 +0600
+++ b/mm7_data.h	Mon Sep 09 09:13:40 2013 +0600
@@ -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
@@ -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);
@@ -1218,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);
@@ -1262,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);
--- a/mm7text_ru.cpp	Mon Sep 09 09:13:23 2013 +0600
+++ b/mm7text_ru.cpp	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/stru10.cpp	Mon Sep 09 09:13:40 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	Mon Sep 09 09:13:23 2013 +0600
+++ b/stru298.h	Mon Sep 09 09:13:40 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];