changeset 2346:37bb43874e59

Слияние
author Ritor1
date Mon, 07 Apr 2014 19:15:31 +0600
parents 182effc4b0ee (current diff) 13e15d77b0f8 (diff)
children d57505d3c70c
files Game.cpp UI/UIHouses.cpp
diffstat 66 files changed, 806 insertions(+), 754 deletions(-) [+]
line wrap: on
line diff
--- a/Actor.cpp	Mon Apr 07 19:15:13 2014 +0600
+++ b/Actor.cpp	Mon Apr 07 19:15:31 2014 +0600
@@ -2827,7 +2827,7 @@
   return true;
 }
 //----- (00401A91) --------------------------------------------------------
-void  UpdateActorAI()
+void  Actor::UpdateActorAI()
 {
 	signed int v4; // edi@10
 	signed int sDmg; // eax@14
@@ -2862,9 +2862,9 @@
 	uint v38;
 	
 	if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor)
-		MakeActorAIList_ODM();
+		Actor::MakeActorAIList_ODM();
 	else
-		MakeActorAIList_BLV();
+		Actor::MakeActorAIList_BLV();
 	
 	if ( uCurrentlyLoadedLevelType != LEVEL_Indoor && pParty->armageddon_timer > 0 )
 	{
@@ -3297,21 +3297,21 @@
   if ( uType )
   {
     if ( uType == 1 )
-      uAliveActors = SearchActorByGroup(&uTotalActors, uParam);
+      uAliveActors = Actor::SearchActorByGroup(&uTotalActors, uParam);
     else
     {
       if ( uType == 2 )
-        uAliveActors = SearchActorByMonsterID(&uTotalActors, uParam);
+        uAliveActors = Actor::SearchActorByMonsterID(&uTotalActors, uParam);
       else
       {
         if ( uType != 3 )
           return 0;
-        uAliveActors = SearchActorByID(&uTotalActors, uParam);
+        uAliveActors = Actor::SearchActorByID(&uTotalActors, uParam);
       }
     }
   }
   else
-    uAliveActors = SearchAliveActors(&uTotalActors);
+    uAliveActors = Actor::SearchAliveActors(&uTotalActors);
 
   if (uNumAlive)
     return uAliveActors >= uNumAlive;
@@ -3319,7 +3319,7 @@
     return uTotalActors == uAliveActors;
 }
 //----- (00408B54) --------------------------------------------------------
-unsigned int SearchActorByID(unsigned int *pTotalActors, unsigned int a2)
+unsigned int Actor::SearchActorByID(unsigned int *pTotalActors, unsigned int a2)
 {
   int v4; // eax@1
   unsigned int v5; // ebx@1
@@ -3335,7 +3335,7 @@
   return v5;
 }
 //----- (00408AE7) --------------------------------------------------------
-unsigned int SearchActorByGroup(unsigned int *pTotalActors, unsigned int uGroup)
+unsigned int Actor::SearchActorByGroup(unsigned int *pTotalActors, unsigned int uGroup)
 {
   int v8; // [sp+Ch] [bp-8h]@1
   unsigned int v9; // [sp+10h] [bp-4h]@1
@@ -3357,7 +3357,7 @@
   return v9;
 }
 //----- (00408A7E) --------------------------------------------------------
-unsigned int SearchActorByMonsterID(unsigned int *pTotalActors, int uMonsterID)
+unsigned int Actor::SearchActorByMonsterID(unsigned int *pTotalActors, int uMonsterID)
 {
   Actor *v4; // edi@2
   int v8; // [sp+Ch] [bp-8h]@1
@@ -3379,7 +3379,7 @@
   return v9;
 }
 //----- (00408A27) --------------------------------------------------------
-unsigned int SearchAliveActors(unsigned int *pTotalActors)
+unsigned int Actor::SearchAliveActors(unsigned int *pTotalActors)
 {
   int v2; // eax@1
   unsigned int v3; // ebp@1
@@ -3401,7 +3401,7 @@
   return v3;
 }
 //----- (00408768) --------------------------------------------------------
-void InitializeActors()
+void Actor::InitializeActors()
 {
   signed int v5; // [sp+Ch] [bp-10h]@1
   signed int v6; // [sp+10h] [bp-Ch]@1
@@ -3451,7 +3451,7 @@
   }
 }
 //----- (00439474) --------------------------------------------------------
-void DamageMonsterFromParty(signed int a1, unsigned int uActorID_Monster, Vec3_int_ *pVelocity)
+void Actor::DamageMonsterFromParty(signed int a1, unsigned int uActorID_Monster, Vec3_int_ *pVelocity)
 {
   SpriteObject *projectileSprite; // ebx@1
   Actor *pMonster; // esi@7
@@ -4416,4 +4416,304 @@
       }
     }
   }
+}
+
+//----- (004014E6) --------------------------------------------------------
+void Actor::MakeActorAIList_ODM()
+{
+  int v1; // eax@4
+//  int v2; // ebx@4
+//  unsigned int v3; // ecx@4
+//  int v4; // edx@5
+//  int v5; // edx@7
+//  unsigned int v6; // edx@9
+  unsigned int v7; // ST20_4@10
+  int v9; // edi@10
+  int v10; // ebx@14
+  int v21; // [sp+Ch] [bp-14h]@4
+  int v22; // [sp+10h] [bp-10h]@4
+
+  pParty->uFlags &= 0xFFFFFFCFu;
+
+  ai_arrays_size = 0;
+  for (uint i = 0; i < uNumActors; ++i)
+  {
+    Actor* actor = &pActors[i];
+
+    actor->uAttributes &= 0xFFFFFBFF;
+    if (!actor->CanAct())
+    {
+      actor->uAttributes &= 0xFFFFBFFF;
+      continue;
+    }
+
+    v22 = abs(pParty->vPosition.z - actor->vPosition.z);
+    v21 = abs(pParty->vPosition.y - actor->vPosition.y);
+    v1 = abs(pParty->vPosition.x - actor->vPosition.x);
+      v7 = int_get_vector_length(v22, v21, v1);
+	  //v8 = actor->uActorRadius;
+      v9 = v7 - actor->uActorRadius;
+      //v23 = v7 - v8;
+      if ( v9 < 0 )
+      {
+        v9 = 0;
+        //v23 = 0;
+      }
+
+      if (v9 < 5632)
+      {
+        v10 = actor->uAttributes & 0xFEFFFFFF;
+        actor->uAttributes = v10;
+        if ( v10 & 0x80000 || actor->GetActorsRelation(0) )
+        {
+          //v11 = (pParty->uFlags & 0x10) == 0;
+          actor->uAttributes = v10 | 0x1000000;
+          if (v9 < 5120 )
+            pParty->SetYellowAlert();
+          if (v9 < 307)
+            pParty->SetRedAlert();
+        }
+		actor->uAttributes |= 0x00004000;
+        ai_near_actors_distances[ai_arrays_size] = v9;
+        ai_near_actors_ids[ai_arrays_size++] = i;
+      }
+      else
+		  actor->uAttributes &= 0xFFFFBFFF;
+  }
+
+  /*
+  result = v27;
+  if ( v27 > 0 )
+  {
+    v14 = 0;
+    v15 = 1;
+    v26 = 1;
+    do
+    {
+      while ( 1 )
+      {
+        v24 = v15;
+        if ( v15 >= result )
+          break;
+        v16 = ai_near_actors_distances[v14];
+        if ( v16 > ai_near_actors_distances[v15] )
+        {
+          v17 = &ai_near_actors_ids[v15];
+          v18 = ai_near_actors_ids[v14];
+          ai_near_actors_ids[v14] = *v17;
+          *v17 = v18;
+          v15 = v24;
+          ai_near_actors_distances[v14] = ai_near_actors_distances[v24];
+          ai_near_actors_distances[v24] = v16;
+        }
+        result = v27;
+        ++v15;
+      }
+      ++v14;
+      v15 = v26 + 1;
+      v26 = v15;
+    }
+    while ( v15 - 1 < result );
+  }*/
+
+  for (uint i = 0; i < ai_arrays_size; ++i)
+    for (uint j = 0; j < i; ++j)
+      if (ai_near_actors_distances[j] > ai_near_actors_distances[i])
+      {
+        int tmp = ai_near_actors_distances[j];
+        ai_near_actors_distances[j] = ai_near_actors_distances[i];
+        ai_near_actors_distances[i] = tmp;
+
+        tmp = ai_near_actors_ids[j];
+        ai_near_actors_ids[j] = ai_near_actors_ids[i];
+        ai_near_actors_ids[i] = tmp;
+      }
+
+
+  if (ai_arrays_size > 30)
+    ai_arrays_size = 30;
+
+  for (uint i = 0; i < ai_arrays_size; ++i)
+    pActors[ai_near_actors_ids[i]].uAttributes |= 0x0400;
+}
+
+//----- (004016FA) --------------------------------------------------------
+int  Actor::MakeActorAIList_BLV()
+{
+  //Actor *v0; // esi@2
+  int v1; // eax@4
+  //  int v2; // ebx@4
+  //  unsigned int v3; // ecx@4
+  //  int v4; // edx@5
+  //  int v5; // edx@7
+  //  unsigned int v6; // edx@9
+  unsigned int v7; // ST24_4@10
+  //  int v8; // eax@10
+  int v9; // edi@10
+  //  int v10; // ebx@14
+  //  char v11; // zf@16
+  int v12; // eax@22
+  int v13; // edx@24
+  //  int v14; // ecx@25
+  int v15; // ebx@26
+  //  unsigned int *v16; // ecx@27
+  unsigned int v17; // esi@27
+  int v18; // ecx@31
+  signed int v19; // edi@31
+  //  Actor *v20; // esi@32
+  //  bool v21; // eax@33
+  //  int v22; // eax@34
+  //  signed int v23; // ebx@36
+  //  Actor *v24; // esi@37
+  signed int v25; // eax@40
+  //  int v26; // eax@43
+  int v27; // ebx@45
+  int j; // edi@45
+  //  unsigned int v29; // eax@46
+  int v30; // eax@48
+  //  int v31; // ecx@51
+  //  int v32; // eax@51
+  //  signed int v33; // eax@53
+  //  __int64 v34; // qax@55
+  //  char *v35; // ecx@56
+  int v37; // [sp+Ch] [bp-18h]@1
+  int v38; // [sp+10h] [bp-14h]@4
+  int v39; // [sp+14h] [bp-10h]@4
+  //int v40; // [sp+18h] [bp-Ch]@10
+  //  int v41; // [sp+18h] [bp-Ch]@29
+  int i; // [sp+18h] [bp-Ch]@31
+  //signed int v43; // [sp+1Ch] [bp-8h]@1
+  //  signed int v44; // [sp+1Ch] [bp-8h]@25
+  int v45; // [sp+20h] [bp-4h]@1
+
+  //  __debugbreak(); // refactor for blv ai
+  pParty->uFlags &= 0xFFFFFFCFu;
+  v37 = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z);
+  v45 = 0;
+  for ( uint i = 0; i < (signed int)uNumActors; ++i )
+  {
+    pActors[i].uAttributes &= 0xFB00;
+    if ( !pActors[i].CanAct() )
+    {
+      pActors[i].uAttributes &= 0xBF00;
+      continue;
+    }
+    v39 = abs(pParty->vPosition.z - pActors[i].vPosition.z);
+    v38 = abs(pParty->vPosition.y - pActors[i].vPosition.y);
+    v1 = abs(pParty->vPosition.x - pActors[i].vPosition.x);
+    v7 = int_get_vector_length(v39, v38, v1);
+    v9 = v7 - pActors[i].uActorRadius;
+    if ( v9 < 0 )
+      v9 = 0;
+    if ( v9 < 10240 )
+    {
+      pActors[i].uAttributes &= 0xFEFFFFFF;
+      if ( pActors[i].uAttributes & 0x80000 || pActors[i].GetActorsRelation(0) )
+      {
+        pActors[i].uAttributes |= 0x1000000;
+        if ( !(pParty->uFlags & 0x10) && (double)v9 < 307.2 )
+          pParty->uFlags |= 0x10;
+        if ( !(pParty->uFlags & 0x20) && v9 < 5120 )
+          pParty->uFlags |= 0x20;
+      }
+      v12 = v45++;
+      ai_near_actors_distances[v12] = v9;
+      ai_near_actors_ids[v12] = i;
+    }
+    else
+      pActors[i].uAttributes &= 0xBF00;
+  }
+  v13 = 0;
+  if ( v45 > 0 )
+  {
+    for ( uint i = 1; i < v45; i++ )
+    {
+      for ( uint j = 1; j < v45; ++j )
+      {
+        v15 = ai_near_actors_distances[v13];
+        if ( ai_near_actors_distances[v13] > ai_near_actors_distances[j] )
+        {
+          v17 = ai_near_actors_ids[v13];
+          ai_near_actors_ids[v13] = ai_near_actors_ids[j];
+          ai_near_actors_ids[j] = v17;
+          ai_near_actors_distances[v13] = ai_near_actors_distances[j];
+          ai_near_actors_distances[j] = v15;
+        }
+      }
+      ++v13;
+    }
+  }
+  v18 = 0;
+  v19 = 0;
+  for ( i = 0; i < v45; i++ )
+  {
+    if ( pActors[ai_near_actors_ids[i]].uAttributes & 0x8000
+      || sub_4070EF_prolly_detect_player(PID(OBJECT_Actor,ai_near_actors_ids[i]), 4) )
+    {
+      pActors[ai_near_actors_ids[i]].uAttributes |= 0x8000;
+      ai_array_4F6638_actor_ids[v19] = ai_near_actors_ids[i];
+      ai_array_4F5E68[v19++] = ai_near_actors_distances[i];
+      if ( v19 >= 30 )
+        break;
+    }
+  }
+  ai_arrays_size = v19;
+  if ( (signed int)uNumActors > 0 )
+  {
+    for ( uint i = 0; i < (signed int)uNumActors; ++i )
+    {
+      if ( pActors[i].CanAct() && pActors[i].uSectorID == v37 )
+      {
+        v25 = 0;
+        if ( v19 <= 0 )
+        {
+          pActors[i].uAttributes |= 0x4000;
+          ai_array_4F6638_actor_ids[ai_arrays_size++] = i;
+        }
+        else
+        {
+          while ( ai_array_4F6638_actor_ids[v25] != i )
+          {
+            ++v25;
+            if ( v25 >= v19 )
+            {
+              pActors[i].uAttributes |= 0x4000;
+              ai_array_4F6638_actor_ids[ai_arrays_size++] = i;
+              break;
+            }
+          }
+        }
+      }
+    }
+  }
+  v27 = ai_arrays_size;
+  for ( j = 0; j < v45; ++j )
+  {
+    //v29 = ai_near_actors_ids[j];
+    if ( pActors[ai_near_actors_ids[j]].uAttributes & 0xC000 && pActors[ai_near_actors_ids[j]].CanAct() )
+    {
+      v30 = 0;
+      if ( v27 <= 0 )
+        ai_array_4F6638_actor_ids[ai_arrays_size++] = ai_near_actors_ids[j];
+      else
+      {
+        while ( ai_array_4F6638_actor_ids[v30] != ai_near_actors_ids[j] )
+        {
+          ++v30;
+          if ( v30 >= v27 )
+          {
+            ai_array_4F6638_actor_ids[ai_arrays_size++] = ai_near_actors_ids[j];
+            break;
+          }
+        }
+      }
+    }
+  }
+  if ( ai_arrays_size > 30 )
+    ai_arrays_size = 30;
+  memcpy(ai_near_actors_ids.data(), ai_array_4F6638_actor_ids.data(), 4 * ai_arrays_size);
+  memcpy(ai_near_actors_distances.data(), ai_array_4F5E68.data(), 4 * ai_arrays_size);
+  for ( uint i = 0; i < ai_arrays_size; i++ )
+    pActors[ai_near_actors_ids[i]].uAttributes |= 0x400;
+  return ai_arrays_size;
 }
\ No newline at end of file
--- a/Actor.h	Mon Apr 07 19:15:13 2014 +0600
+++ b/Actor.h	Mon Apr 07 19:15:31 2014 +0600
@@ -229,6 +229,15 @@
 
   static bool _46DF1A_collide_against_actor(int a1, int a2);
   static void Arena_summon_actor(int monster_id, __int16 x, int y, int z);
+  static void DamageMonsterFromParty(signed int a1, unsigned int uActorID_Monster, struct Vec3_int_ *pVelocity);
+  static void MakeActorAIList_ODM();
+  static int MakeActorAIList_BLV();
+  static void UpdateActorAI();
+  static void InitializeActors();
+  static unsigned int SearchAliveActors(unsigned int *pTotalActors);
+  static unsigned int SearchActorByMonsterID(unsigned int *pTotalActors, int uMonsterID);
+  static unsigned int SearchActorByGroup(unsigned int *pTotalActors, unsigned int uGroup);
+  static unsigned int SearchActorByID(unsigned int *pTotalActors, unsigned int a2);
 
 
   void LootActor();
@@ -290,4 +299,7 @@
 extern std::array<Actor, 500> pActors;
 extern size_t uNumActors;
 
-bool CheckActors_proximity();
\ No newline at end of file
+bool CheckActors_proximity();
+int __fastcall IsActorAlive(unsigned int uType, unsigned int uParam, unsigned int uNumAlive); // idb
+void __fastcall sub_448518_npc_set_item(int npc, unsigned int item, int a3);
+void __fastcall ToggleActorGroupFlag(unsigned int uGroupID, unsigned int uFlag, unsigned int bToggle);
\ No newline at end of file
--- a/Arcomage.cpp	Mon Apr 07 19:15:13 2014 +0600
+++ b/Arcomage.cpp	Mon Apr 07 19:15:31 2014 +0600
@@ -3557,7 +3557,7 @@
 }
 
 //----- (00409C8B) --------------------------------------------------------
-void PrepareArcomage()
+void ArcomageGame::PrepareArcomage()
 {
 //  signed __int64 v1; // qax@4
   int v2; // esi@4
--- a/Arcomage.h	Mon Apr 07 19:15:13 2014 +0600
+++ b/Arcomage.h	Mon Apr 07 19:15:31 2014 +0600
@@ -143,6 +143,8 @@
   static void OnMouseClick(char right_left, bool bDown);
   static void OnMouseMove(int x, int y);
   static void GetCardRect(unsigned int uCardID, RECT *pCardRect);
+  static void PrepareArcomage();
+  static void DoBlt_Copy(unsigned __int16 *pPixels); // idb
 
   static void Loop();
 
--- a/AudioPlayer.cpp	Mon Apr 07 19:15:13 2014 +0600
+++ b/AudioPlayer.cpp	Mon Apr 07 19:15:31 2014 +0600
@@ -20,6 +20,7 @@
 #include "Log.h"
 #include "ErrorHandling.h"
 #include "Level/Decoration.h"
+#include "Registry.h"
 
 #include "Bink_Smacker.h"
 
--- a/AudioPlayer.h	Mon Apr 07 19:15:13 2014 +0600
+++ b/AudioPlayer.h	Mon Apr 07 19:15:31 2014 +0600
@@ -356,3 +356,9 @@
 #pragma pack(pop)
 extern std::array<stru339_spell_sound, 4> stru_A750F8;
 extern std::array<stru339_spell_sound, 4> AA1058_PartyQuickSpellSound;
+
+struct SoundHeader *FindSound_BinSearch(unsigned int uStart, unsigned int uEnd, const char *pName);
+struct SoundData *LoadSound(const char *pSoundName, struct SoundData *pOutBuff, unsigned int uID);
+int __fastcall sub_4AB66C(int, int); // weak
+int GetSoundStrengthByDistanceFromParty(int x, int y, int z);
+void PlayLevelMusic();
--- a/Build/Visual Studio 2012/World of Might and Magic.vcxproj	Mon Apr 07 19:15:13 2014 +0600
+++ b/Build/Visual Studio 2012/World of Might and Magic.vcxproj	Mon Apr 07 19:15:31 2014 +0600
@@ -210,6 +210,7 @@
     <ClCompile Include="..\..\Party.cpp" />
     <ClCompile Include="..\..\Player.cpp" />
     <ClCompile Include="..\..\Random.cpp" />
+    <ClCompile Include="..\..\Registry.cpp" />
     <ClCompile Include="..\..\Render.cpp" />
     <ClCompile Include="..\..\SaveLoad.cpp" />
     <ClCompile Include="..\..\Spells.cpp" />
@@ -453,6 +454,7 @@
     <ClInclude Include="..\..\Player.h" />
     <ClInclude Include="..\..\PlayerFrameTable.h" />
     <ClInclude Include="..\..\Random.h" />
+    <ClInclude Include="..\..\Registry.h" />
     <ClInclude Include="..\..\Render.h" />
     <ClInclude Include="..\..\SaveLoad.h" />
     <ClInclude Include="..\..\Spells.h" />
--- a/Build/Visual Studio 2012/World of Might and Magic.vcxproj.filters	Mon Apr 07 19:15:13 2014 +0600
+++ b/Build/Visual Studio 2012/World of Might and Magic.vcxproj.filters	Mon Apr 07 19:15:31 2014 +0600
@@ -386,6 +386,7 @@
     </ClCompile>
     <ClCompile Include="..\..\MediaPlayer.cpp" />
     <ClCompile Include="..\..\OurMath.cpp" />
+    <ClCompile Include="..\..\Registry.cpp" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\Level\Decoration.h" />
@@ -912,6 +913,7 @@
     <ClInclude Include="..\..\MediaPlayer.h" />
     <ClInclude Include="..\..\OpenALSoundProvider.h" />
     <ClInclude Include="..\..\stuff.h" />
+    <ClInclude Include="..\..\Registry.h" />
   </ItemGroup>
   <ItemGroup>
     <None Include="..\..\Player.swig" />
--- a/CastSpellInfo.cpp	Mon Apr 07 19:15:13 2014 +0600
+++ b/CastSpellInfo.cpp	Mon Apr 07 19:15:31 2014 +0600
@@ -430,7 +430,7 @@
           pSpellSprite.vPosition.z = pActors[mon_id].vPosition.z;
           pSpellSprite.vPosition.y = pActors[mon_id].vPosition.y;
           pSpellSprite.spell_target_pid = PID(OBJECT_Actor, mon_id);
-          DamageMonsterFromParty(PID(OBJECT_Item, pSpellSprite.Create(0, 0, 0, 0)), mon_id, &v697);
+          Actor::DamageMonsterFromParty(PID(OBJECT_Item, pSpellSprite.Create(0, 0, 0, 0)), mon_id, &v697);
         }
         spell_sound_flag = true;
         break;
@@ -462,7 +462,7 @@
           pSpellSprite.vPosition.y = pActors[mon_id].vPosition.y;
           pSpellSprite.vPosition.z = pActors[mon_id].vPosition.z;
           pSpellSprite.spell_target_pid = PID(OBJECT_Actor, mon_id);
-          DamageMonsterFromParty(PID(OBJECT_Item, pSpellSprite.Create(0, 0, 0, 0)), mon_id, &v704);
+          Actor::DamageMonsterFromParty(PID(OBJECT_Item, pSpellSprite.Create(0, 0, 0, 0)), mon_id, &v704);
         }
         spell_sound_flag = true;
         break;
@@ -501,7 +501,7 @@
           pCastSpell->uSpellID = 0;
           continue;
         }
-        DamageMonsterFromParty(PID(OBJECT_Item, obj_id), PID_ID(a2), &v691);
+        Actor::DamageMonsterFromParty(PID(OBJECT_Item, obj_id), PID_ID(a2), &v691);
         spell_sound_flag = true;
         break;
       }
@@ -929,7 +929,7 @@
             pSpellSprite.vPosition.y = pActors[mon_id].vPosition.y;
             pSpellSprite.vPosition.z = pActors[mon_id].vPosition.z - (unsigned int)(signed __int64)((double)pActors[mon_id].uActorHeight * -0.8);
             pSpellSprite.spell_target_pid = PID(OBJECT_Actor, a2);
-            DamageMonsterFromParty(PID(OBJECT_Item, pSpellSprite.Create(0, 0, 0, 0)), mon_id, &v701);
+            Actor::DamageMonsterFromParty(PID(OBJECT_Item, pSpellSprite.Create(0, 0, 0, 0)), mon_id, &v701);
             spell_sound_flag = true;
           }
           else
@@ -1110,7 +1110,7 @@
           pSpellSprite.vPosition.y = pActors[_50BF30_actors_in_viewport_ids[i]].vPosition.y;
           pSpellSprite.vPosition.z = pActors[_50BF30_actors_in_viewport_ids[i]].vPosition.z - (unsigned int)(signed __int64)((double)pActors[_50BF30_actors_in_viewport_ids[i]].uActorHeight * -0.8);
           pSpellSprite.spell_target_pid = PID(OBJECT_Actor, _50BF30_actors_in_viewport_ids[i]);
-          DamageMonsterFromParty(PID(OBJECT_Item, pSpellSprite.Create(0, 0, 0, 0)), _50BF30_actors_in_viewport_ids[i], &v700);
+          Actor::DamageMonsterFromParty(PID(OBJECT_Item, pSpellSprite.Create(0, 0, 0, 0)), _50BF30_actors_in_viewport_ids[i], &v700);
           pGame->GetStru6()->_4A81CA(&pSpellSprite);
           pGame->GetStru6()->FadeScreen__like_Turn_Undead_and_mb_Armageddon(0xFF3C1E, 0x40);
         }
@@ -2608,7 +2608,7 @@
           pSpellSprite.vPosition.z = pActors[_50BF30_actors_in_viewport_ids[a2]].vPosition.z - 
                                    (unsigned int)(signed __int64)((double)pActors[_50BF30_actors_in_viewport_ids[a2]].uActorHeight * -0.8);
           pSpellSprite.spell_target_pid = PID(OBJECT_Actor, _50BF30_actors_in_viewport_ids[a2]);
-          DamageMonsterFromParty(PID(OBJECT_Item, pSpellSprite.Create(0, 0, 0, 0)), _50BF30_actors_in_viewport_ids[a2], &v688);
+          Actor::DamageMonsterFromParty(PID(OBJECT_Item, pSpellSprite.Create(0, 0, 0, 0)), _50BF30_actors_in_viewport_ids[a2], &v688);
         }
         for ( a2 = 0; a2 < mon_num; ++a2 )
         {
@@ -2712,7 +2712,7 @@
           pSpellSprite.vPosition.z = pActors[_50BF30_actors_in_viewport_ids[mon_id]].vPosition.z -
                 (unsigned int)(signed __int64)((double)pActors[_50BF30_actors_in_viewport_ids[mon_id]].uActorHeight * -0.8);
           pSpellSprite.spell_target_pid = PID(OBJECT_Actor, _50BF30_actors_in_viewport_ids[mon_id]);
-          DamageMonsterFromParty(PID(OBJECT_Item, pSpellSprite.Create(0, 0, 0, 0)), _50BF30_actors_in_viewport_ids[mon_id], &v694);
+          Actor::DamageMonsterFromParty(PID(OBJECT_Item, pSpellSprite.Create(0, 0, 0, 0)), _50BF30_actors_in_viewport_ids[mon_id], &v694);
         }
         //v537 = pGame->GetStru6();
         pGame->GetStru6()->_4A8BFC();
@@ -3156,7 +3156,7 @@
             pSpellSprite.vPosition.z = pActors[_50BF30_actors_in_viewport_ids[mon_id]].vPosition.z - 
                        (unsigned int)(signed __int64)((double)pActors[_50BF30_actors_in_viewport_ids[mon_id]].uActorHeight * -0.8);
             pSpellSprite.spell_target_pid = PID(OBJECT_Actor, _50BF30_actors_in_viewport_ids[mon_id]);
-            DamageMonsterFromParty(PID(OBJECT_Item, pSpellSprite.Create(0, 0, 0, 0)), _50BF30_actors_in_viewport_ids[mon_id], &v707);
+            Actor::DamageMonsterFromParty(PID(OBJECT_Item, pSpellSprite.Create(0, 0, 0, 0)), _50BF30_actors_in_viewport_ids[mon_id], &v707);
           }
         }
         int pl_num = 0;
--- a/CastSpellInfo.h	Mon Apr 07 19:15:13 2014 +0600
+++ b/CastSpellInfo.h	Mon Apr 07 19:15:31 2014 +0600
@@ -32,3 +32,5 @@
   int sound_id;
 };
 #pragma pack(pop)
+
+void _42777D_CastSpell_UseWand_ShootArrow(int a1, unsigned int uPlayerID, unsigned int a4, __int16 a5, int a6);
\ No newline at end of file
--- a/Chest.cpp	Mon Apr 07 19:15:13 2014 +0600
+++ b/Chest.cpp	Mon Apr 07 19:15:31 2014 +0600
@@ -195,7 +195,7 @@
 }
 
 //----- (0042038D) --------------------------------------------------------
-void ChestUI_WritePointedObjectStatusString()
+void Chest::ChestUI_WritePointedObjectStatusString()
 {
   int v1; // ecx@2
   POINT cursor; // [sp+8h] [bp-8h]@1
@@ -768,7 +768,7 @@
 }
 // 506128: using guessed type int areWeLoadingTexture;
 //----- (00420E01) --------------------------------------------------------
-void OnChestLeftClick()
+void Chest::OnChestLeftClick()
 {
   int v2; // eax@2
   int v3; // ebx@4
--- a/Chest.h	Mon Apr 07 19:15:13 2014 +0600
+++ b/Chest.h	Mon Apr 07 19:15:31 2014 +0600
@@ -60,6 +60,8 @@
   static bool Open(signed int uChestID);
   static void DrawChestUI(signed int uChestID);
   static void ToggleFlag(signed int uChestID, unsigned __int16 uFlag, unsigned int bToggle);
+  static void ChestUI_WritePointedObjectStatusString();
+  static void OnChestLeftClick();
 
   unsigned __int16 uChestBitmapID; //0
   unsigned __int16 uFlags; //2
--- a/Events.h	Mon Apr 07 19:15:13 2014 +0600
+++ b/Events.h	Mon Apr 07 19:15:31 2014 +0600
@@ -1,5 +1,5 @@
 #pragma once
-
+#include <array>
 
 
 
@@ -334,6 +334,7 @@
 void Initialize_GlobalEVT();
 void LoadLevel_InitializeLevelEvt();
 void EventProcessor(int uEventID, int a2, int a3, int entry_line = 0);
+char *GetEventHintString(unsigned int uEventID); // idb
 
 
 
--- a/GUIFont.h	Mon Apr 07 19:15:13 2014 +0600
+++ b/GUIFont.h	Mon Apr 07 19:15:31 2014 +0600
@@ -32,6 +32,8 @@
                                         unsigned __int16 *pPixels, unsigned int uPixelsWidth);
 
   static char * FitTwoFontStringINWindow(const char *pString, GUIFont *pFontMain, GUIFont *pFontSecond, GUIWindow* pWindow, int startPixlOff, int a6);
+  static void uGameUIFontMain_initialize();
+  static void uGameUIFontShadow_initialize();
 
   unsigned char cFirstChar;  //0
   unsigned char cLastChar;  //1
--- a/GUIWindow.cpp	Mon Apr 07 19:15:13 2014 +0600
+++ b/GUIWindow.cpp	Mon Apr 07 19:15:31 2014 +0600
@@ -1738,7 +1738,7 @@
   ItemGen ItemGen2; // [sp+E4h] [bp-24h]@129
 
   if (GetCurrentMenuID() != MENU_CREATEPARTY)
-    UI_OnKeyDown(VK_NEXT);
+    Mouse::UI_OnKeyDown(VK_NEXT);
 
   for ( i = 1; i <= uNumVisibleWindows; ++i )
   {
--- a/GUIWindow.h	Mon Apr 07 19:15:13 2014 +0600
+++ b/GUIWindow.h	Mon Apr 07 19:15:31 2014 +0600
@@ -599,8 +599,25 @@
 void FillAwardsData();
 void CreateAwardsScrollBar();
 void ReleaseAwardsScrollBar();
+void Inventory_ItemPopupAndAlchemy();
+void __fastcall LoadThumbnailLloydTexture(unsigned int uSlot, unsigned int uPlayer);
+unsigned int UI_GetHealthManaAndOtherQualitiesStringColor(signed int current_pos, signed int base_pos);
+unsigned int __fastcall GetSizeInInventorySlots(unsigned int uNumPixels);
+struct GUIButton *__fastcall GUI_HandleHotkey(unsigned __int8 uHotkey); // idb
+int __fastcall GUI_ReplaceHotkey(unsigned __int8 uOldHotkey, unsigned __int8 uNewHotkey, char bFirstCall);
+void DrawBuff_remaining_time_string(int uY, struct GUIWindow *window, __int64 remaining_time, struct GUIFont *Font);
+void GameUI_DrawItemInfo(struct ItemGen* inspect_item); // idb
+void MonsterPopup_Draw(unsigned int uActorID, struct GUIWindow *window);
+void SetUserInterface(enum PartyAlignment alignment, bool bReplace);
+void CreateMsgScrollWindow(signed int mscroll_id);
+void free_book_subwindow();
+void CreateScrollWindow();
+void OnPaperdollLeftClick();
 
 
+void __fastcall ZBuffer_Fill(int *pZBuffer, int uTextureId, int iZValue);
+void __fastcall ZBuffer_DoFill(int *pZBuffer, struct Texture *pTex, int uZValue);
+void __fastcall ZBuffer_DoFill2(int *pZBuffer, struct Texture *a2, int a3); // idb
 
 
 
--- a/Game.cpp	Mon Apr 07 19:15:13 2014 +0600
+++ b/Game.cpp	Mon Apr 07 19:15:31 2014 +0600
@@ -1,4 +1,5 @@
 #define _CRT_SECURE_NO_WARNINGS
+#include "Arcomage.h"
 #include "mm7_unsorted_subs.h"
 #include "Vis.h"
 #include "Weather.h"
@@ -47,6 +48,8 @@
 #include "SpriteObject.h"
 #include "mm7.h"
 #include "Sprites.h"
+#include "Registry.h"
+#include "Chest.h"
 
 
 
@@ -363,7 +366,7 @@
           dword_6BE364_game_settings_1 &= ~GAME_SETTINGS_0001;
         else
         {
-          UpdateActorAI();
+          Actor::UpdateActorAI();
           UpdateUserInput_and_MapSpecificStuff();
         }
       }
@@ -477,7 +480,7 @@
           dword_5B65C0 = 1;
           PrepareWorld(1);
         }
-        InitializeActors();
+        Actor::InitializeActors();
 
         int num_conscious_players = 0;
         int conscious_players_ids[4] = {-1, -1, -1, -1};
@@ -1344,7 +1347,7 @@
         case UIMSG_PlayArcomage:
           pVideoPlayer->_4BF5B2();
           pArcomageGame->bGameInProgress = 1;
-          PrepareArcomage();
+          ArcomageGame::PrepareArcomage();
           continue;
         case UIMSG_StartNPCDialogue:
           if ( !uActiveCharacter )
@@ -3129,7 +3132,7 @@
                     v66 = TownPortalList[uMessageParam].rot_x;
                     _5B65B4_npcdata_loword_house_or_other = TownPortalList[uMessageParam].rot_y;
                     _5B65B8_npcdata_hiword_house_or_other = v66;
-                    InitializeActors();
+                    Actor::InitializeActors();
                   }
                   v67 = (char*)pGUIWindow_CurrentMenu->Hint;
                   if ( v67 )
@@ -4053,7 +4056,7 @@
             pPlayers[uActiveCharacter]->OnInventoryLeftClick();
             continue;
           }
-          OnChestLeftClick();
+          Chest::OnChestLeftClick();
           continue;
         case UIMSG_InventoryLeftClick:
           pPlayers[uActiveCharacter]->OnInventoryLeftClick();
--- a/Game.h	Mon Apr 07 19:15:13 2014 +0600
+++ b/Game.h	Mon Apr 07 19:15:31 2014 +0600
@@ -176,4 +176,10 @@
 
 
 
-extern Game *pGame;
\ No newline at end of file
+extern Game *pGame;
+
+void sub_42FBDD();
+void CloseWindowBackground();
+void GameUI_MsgProc();
+void back_to_game();
+void GUI_MainMenuMessageProc();
\ No newline at end of file
--- a/GammaControl.h	Mon Apr 07 19:15:13 2014 +0600
+++ b/GammaControl.h	Mon Apr 07 19:15:31 2014 +0600
@@ -1,6 +1,5 @@
 #pragma once
 #include "lib\legacy_dx\d3d.h"
-#include "OSAPI.h"
 
 #pragma pack(push, 1)
 class GammaController
--- a/Indoor.cpp	Mon Apr 07 19:15:13 2014 +0600
+++ b/Indoor.cpp	Mon Apr 07 19:15:31 2014 +0600
@@ -3130,8 +3130,8 @@
     Error("Out of memory loading indoor level");
   if ( !(dword_6BE364_game_settings_1 & GAME_SETTINGS_2000) )
   {
-    InitializeActors();
-    InitializeSpriteObjects();
+    Actor::InitializeActors();
+    SpriteObject::InitializeSpriteObjects();
   }
   dword_6BE364_game_settings_1 &= ~GAME_SETTINGS_2000;
   if ( !map_id )
@@ -3544,186 +3544,6 @@
 
   return result;
 }
-//----- (004016FA) --------------------------------------------------------
-int  MakeActorAIList_BLV()
-{
-  //Actor *v0; // esi@2
-  int v1; // eax@4
-//  int v2; // ebx@4
-//  unsigned int v3; // ecx@4
-//  int v4; // edx@5
-//  int v5; // edx@7
-//  unsigned int v6; // edx@9
-  unsigned int v7; // ST24_4@10
-//  int v8; // eax@10
-  int v9; // edi@10
-//  int v10; // ebx@14
-//  char v11; // zf@16
-  int v12; // eax@22
-  int v13; // edx@24
-//  int v14; // ecx@25
-  int v15; // ebx@26
-//  unsigned int *v16; // ecx@27
-  unsigned int v17; // esi@27
-  int v18; // ecx@31
-  signed int v19; // edi@31
-//  Actor *v20; // esi@32
-//  bool v21; // eax@33
-//  int v22; // eax@34
-//  signed int v23; // ebx@36
-//  Actor *v24; // esi@37
-  signed int v25; // eax@40
-//  int v26; // eax@43
-  int v27; // ebx@45
-  int j; // edi@45
-//  unsigned int v29; // eax@46
-  int v30; // eax@48
-//  int v31; // ecx@51
-//  int v32; // eax@51
-//  signed int v33; // eax@53
-//  __int64 v34; // qax@55
-//  char *v35; // ecx@56
-  int v37; // [sp+Ch] [bp-18h]@1
-  int v38; // [sp+10h] [bp-14h]@4
-  int v39; // [sp+14h] [bp-10h]@4
-  //int v40; // [sp+18h] [bp-Ch]@10
-//  int v41; // [sp+18h] [bp-Ch]@29
-  int i; // [sp+18h] [bp-Ch]@31
-  //signed int v43; // [sp+1Ch] [bp-8h]@1
-//  signed int v44; // [sp+1Ch] [bp-8h]@25
-  int v45; // [sp+20h] [bp-4h]@1
-
-//  __debugbreak(); // refactor for blv ai
-  pParty->uFlags &= 0xFFFFFFCFu;
-  v37 = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z);
-  v45 = 0;
-  for ( uint i = 0; i < (signed int)uNumActors; ++i )
-  {
-    pActors[i].uAttributes &= 0xFB00;
-    if ( !pActors[i].CanAct() )
-    {
-      pActors[i].uAttributes &= 0xBF00;
-      continue;
-    }
-    v39 = abs(pParty->vPosition.z - pActors[i].vPosition.z);
-    v38 = abs(pParty->vPosition.y - pActors[i].vPosition.y);
-    v1 = abs(pParty->vPosition.x - pActors[i].vPosition.x);
-    v7 = int_get_vector_length(v39, v38, v1);
-    v9 = v7 - pActors[i].uActorRadius;
-    if ( v9 < 0 )
-      v9 = 0;
-    if ( v9 < 10240 )
-    {
-      pActors[i].uAttributes &= 0xFEFFFFFF;
-      if ( pActors[i].uAttributes & 0x80000 || pActors[i].GetActorsRelation(0) )
-      {
-        pActors[i].uAttributes |= 0x1000000;
-        if ( !(pParty->uFlags & 0x10) && (double)v9 < 307.2 )
-          pParty->uFlags |= 0x10;
-        if ( !(pParty->uFlags & 0x20) && v9 < 5120 )
-          pParty->uFlags |= 0x20;
-      }
-      v12 = v45++;
-      ai_near_actors_distances[v12] = v9;
-      ai_near_actors_ids[v12] = i;
-    }
-    else
-      pActors[i].uAttributes &= 0xBF00;
-  }
-  v13 = 0;
-  if ( v45 > 0 )
-  {
-    for ( uint i = 1; i < v45; i++ )
-    {
-      for ( uint j = 1; j < v45; ++j )
-      {
-        v15 = ai_near_actors_distances[v13];
-        if ( ai_near_actors_distances[v13] > ai_near_actors_distances[j] )
-        {
-          v17 = ai_near_actors_ids[v13];
-          ai_near_actors_ids[v13] = ai_near_actors_ids[j];
-          ai_near_actors_ids[j] = v17;
-          ai_near_actors_distances[v13] = ai_near_actors_distances[j];
-          ai_near_actors_distances[j] = v15;
-        }
-      }
-      ++v13;
-    }
-  }
-  v18 = 0;
-  v19 = 0;
-  for ( i = 0; i < v45; i++ )
-  {
-    if ( pActors[ai_near_actors_ids[i]].uAttributes & 0x8000
-      || sub_4070EF_prolly_detect_player(PID(OBJECT_Actor,ai_near_actors_ids[i]), 4) )
-    {
-      pActors[ai_near_actors_ids[i]].uAttributes |= 0x8000;
-      ai_array_4F6638_actor_ids[v19] = ai_near_actors_ids[i];
-      ai_array_4F5E68[v19++] = ai_near_actors_distances[i];
-      if ( v19 >= 30 )
-        break;
-    }
-  }
-  ai_arrays_size = v19;
-  if ( (signed int)uNumActors > 0 )
-  {
-    for ( uint i = 0; i < (signed int)uNumActors; ++i )
-    {
-      if ( pActors[i].CanAct() && pActors[i].uSectorID == v37 )
-      {
-        v25 = 0;
-        if ( v19 <= 0 )
-        {
-          pActors[i].uAttributes |= 0x4000;
-          ai_array_4F6638_actor_ids[ai_arrays_size++] = i;
-        }
-        else
-        {
-          while ( ai_array_4F6638_actor_ids[v25] != i )
-          {
-            ++v25;
-            if ( v25 >= v19 )
-            {
-              pActors[i].uAttributes |= 0x4000;
-              ai_array_4F6638_actor_ids[ai_arrays_size++] = i;
-			  break;
-            }
-          }
-        }
-      }
-    }
-  }
-  v27 = ai_arrays_size;
-  for ( j = 0; j < v45; ++j )
-  {
-    //v29 = ai_near_actors_ids[j];
-    if ( pActors[ai_near_actors_ids[j]].uAttributes & 0xC000 && pActors[ai_near_actors_ids[j]].CanAct() )
-    {
-      v30 = 0;
-      if ( v27 <= 0 )
-        ai_array_4F6638_actor_ids[ai_arrays_size++] = ai_near_actors_ids[j];
-      else
-      {
-        while ( ai_array_4F6638_actor_ids[v30] != ai_near_actors_ids[j] )
-        {
-          ++v30;
-          if ( v30 >= v27 )
-		  {
-            ai_array_4F6638_actor_ids[ai_arrays_size++] = ai_near_actors_ids[j];
-			break;
-		  }
-        }
-      }
-    }
-  }
-  if ( ai_arrays_size > 30 )
-    ai_arrays_size = 30;
-  memcpy(ai_near_actors_ids.data(), ai_array_4F6638_actor_ids.data(), 4 * ai_arrays_size);
-  memcpy(ai_near_actors_distances.data(), ai_array_4F5E68.data(), 4 * ai_arrays_size);
-  for ( uint i = 0; i < ai_arrays_size; i++ )
-    pActors[ai_near_actors_ids[i]].uAttributes |= 0x400;
-  return ai_arrays_size;
-}
 //----- (0043FDED) --------------------------------------------------------
 void PrepareActorRenderList_BLV()
 {
--- a/Indoor.h	Mon Apr 07 19:15:13 2014 +0600
+++ b/Indoor.h	Mon Apr 07 19:15:31 2014 +0600
@@ -535,3 +535,21 @@
 
 
 
+
+int __fastcall GetPortalScreenCoord(unsigned int uFaceID);
+bool PortalFrustrum(int pNumVertices, struct BspRenderer_PortalViewportData *a2, struct BspRenderer_PortalViewportData *near_portal, int uFaceID);
+void PrepareBspRenderList_BLV();
+void PrepareDecorationsRenderList_BLV(unsigned int uDecorationID, unsigned int uSectorID);
+void PrepareActorRenderList_BLV();
+void PrepareItemsRenderList_BLV();
+void AddBspNodeToRenderList(unsigned int node_id);
+void __fastcall sub_4406BC(unsigned int node_id, unsigned int uFirstNode); // idb
+char __fastcall DoInteractionWithTopmostZObject(int a1, int a2);
+int __fastcall sub_4AAEA6_transform(struct RenderVertexSoft *a1);
+unsigned int __fastcall sub_4B0E07(unsigned int uFaceID); // idb
+void BLV_UpdateUserInputAndOther();
+int BLV_GetFloorLevel(int x, int y, int z, unsigned int uSectorID, unsigned int *pFaceID);
+void BLV_UpdateDoors();
+void UpdateActors_BLV();
+void BLV_ProcessPartyActions();
+void Door_switch_animation(unsigned int uDoorID, int a2); // idb: sub_449A49
--- a/Items.cpp	Mon Apr 07 19:15:13 2014 +0600
+++ b/Items.cpp	Mon Apr 07 19:15:31 2014 +0600
@@ -16,6 +16,7 @@
 #include "StorylineTextTable.h"
 #include "texts.h"
 #include "mm7_data.h"
+#include "OurMath.h"
 
 
 struct ITEM_VARIATION
--- a/Items.h	Mon Apr 07 19:15:13 2014 +0600
+++ b/Items.h	Mon Apr 07 19:15:31 2014 +0600
@@ -514,4 +514,8 @@
   int field_14_exprie_month;
   int field_18_expire_year;
 };
-#pragma pack(pop)
\ No newline at end of file
+#pragma pack(pop)
+
+
+int GetItemTextureFilename(char *pOut, signed int item_id, int index, int shoulder);
+void FillAviableSkillsToTeach(int _this);
\ No newline at end of file
--- a/Keyboard.cpp	Mon Apr 07 19:15:13 2014 +0600
+++ b/Keyboard.cpp	Mon Apr 07 19:15:31 2014 +0600
@@ -4,7 +4,6 @@
 #include "Game.h"
 
 #include "mm7_data.h"
-#include "mm7_unsorted_subs.h"
 #include "Vis.h"
 #include "MM7.h"
 #include "Actor.h"
@@ -17,6 +16,7 @@
 #include "Indoor.h"
 #include "viewport.h"
 #include "AudioPlayer.h"
+#include "Registry.h"
 #include "Level/Decoration.h"
 
 #include <tuple>
--- a/Keyboard.h	Mon Apr 07 19:15:13 2014 +0600
+++ b/Keyboard.h	Mon Apr 07 19:15:31 2014 +0600
@@ -96,5 +96,6 @@
 
 
 
+void OnPressSpace();
 
 extern struct KeyboardActionMapping *pKeyActionMap;
\ No newline at end of file
--- a/LOD.h	Mon Apr 07 19:15:13 2014 +0600
+++ b/LOD.h	Mon Apr 07 19:15:31 2014 +0600
@@ -2,7 +2,6 @@
 #include <stdio.h>
 #include <memory.h>
 
-#include "Log.h"
 #include "Texture.h"
 
 class Sprite;
--- a/Lights.h	Mon Apr 07 19:15:13 2014 +0600
+++ b/Lights.h	Mon Apr 07 19:15:31 2014 +0600
@@ -1,5 +1,4 @@
 #pragma once
-#include "OSAPI.h" // messagebox
 
 #include "VectorTypes.h"
 
@@ -72,29 +71,7 @@
   }
 
   //----- (004AD3C8) --------------------------------------------------------
-  inline bool AddLight(__int16 x, __int16 y, __int16 z, __int16 a5, unsigned char r, unsigned char g, unsigned char b, char uLightType)
-  {
-    unsigned int v9; // eax@1
-    std::string v11; // [sp-18h] [bp-18h]@3
-
-    v9 = this->uNumLightsActive;
-    if ( (signed int)v9 >= 400 )
-    {
-      MessageBoxW(nullptr, L"Too many stationary lights!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\StationaryLightStack.cpp:45", 0);
-      return false;
-    }
-
-      StationaryLight* pLight = &pLights[uNumLightsActive++];
-      pLight->vPosition.x = x;
-      pLight->vPosition.y = y;
-      pLight->vPosition.z = z;
-      pLight->uRadius = a5;
-      pLight->uLightColorR = (unsigned __int8)r;
-      pLight->uLightColorG = g;
-      pLight->uLightColorB = b;
-      pLight->uLightType = uLightType;
-      return true;
-  }
+  bool AddLight(__int16 x, __int16 y, __int16 z, __int16 a5, unsigned char r, unsigned char g, unsigned char b, char uLightType);
 
 
 
--- a/LightsStack.cpp	Mon Apr 07 19:15:13 2014 +0600
+++ b/LightsStack.cpp	Mon Apr 07 19:15:31 2014 +0600
@@ -1,6 +1,7 @@
 #define _CRT_SECURE_NO_WARNINGS
 #include <string>
 #include "Lights.h"
+#include "OSAPI.h"
 
 
 //----- (00467D88) --------------------------------------------------------
@@ -26,3 +27,27 @@
 
   return true;
 }
+
+bool LightsStack_StationaryLight_::AddLight( __int16 x, __int16 y, __int16 z, __int16 a5, unsigned char r, unsigned char g, unsigned char b, char uLightType )
+{
+  unsigned int v9; // eax@1
+  std::string v11; // [sp-18h] [bp-18h]@3
+
+  v9 = this->uNumLightsActive;
+  if ( (signed int)v9 >= 400 )
+  {
+    MessageBoxW(nullptr, L"Too many stationary lights!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\StationaryLightStack.cpp:45", 0);
+    return false;
+  }
+
+  StationaryLight* pLight = &pLights[uNumLightsActive++];
+  pLight->vPosition.x = x;
+  pLight->vPosition.y = y;
+  pLight->vPosition.z = z;
+  pLight->uRadius = a5;
+  pLight->uLightColorR = (unsigned __int8)r;
+  pLight->uLightColorG = g;
+  pLight->uLightColorB = b;
+  pLight->uLightType = uLightType;
+  return true;
+}
--- a/Monsters.cpp	Mon Apr 07 19:15:13 2014 +0600
+++ b/Monsters.cpp	Mon Apr 07 19:15:31 2014 +0600
@@ -1275,4 +1275,5 @@
       break;
   }
   return result;
-}
\ No newline at end of file
+}
+
--- a/Mouse.cpp	Mon Apr 07 19:15:13 2014 +0600
+++ b/Mouse.cpp	Mon Apr 07 19:15:31 2014 +0600
@@ -430,7 +430,7 @@
   uMouseClickY = y;
 }
 //----- (004175C0) --------------------------------------------------------
-void UI_OnMouseLeftClick(int *pXY)
+void Mouse::UI_OnMouseLeftClick(int *pXY)
 {
   signed int y; // eax@7
   signed int x; // ecx@7
@@ -560,7 +560,7 @@
 
 
 //----- (0041CD4F) --------------------------------------------------------
-bool UI_OnKeyDown(unsigned int vkKey)
+bool Mouse::UI_OnKeyDown(unsigned int vkKey)
 {
   //unsigned int v1; // edi@1
   //unsigned int v2; // eax@2
--- a/Mouse.h	Mon Apr 07 19:15:13 2014 +0600
+++ b/Mouse.h	Mon Apr 07 19:15:31 2014 +0600
@@ -80,6 +80,9 @@
   void ChangeActivation(int a1);
   void SetMouseClick(int x, int y);
 
+  static void UI_OnMouseLeftClick(int *pXY); // idb
+  static bool UI_OnKeyDown(unsigned int vkKey);
+
 
   unsigned int uPointingObjectID;
   unsigned int bActive;
--- a/NPC.cpp	Mon Apr 07 19:15:13 2014 +0600
+++ b/NPC.cpp	Mon Apr 07 19:15:31 2014 +0600
@@ -15,6 +15,7 @@
 #include "Indoor.h"
 #include "MapInfo.h"
 #include "Level/Decoration.h"
+#include "Actor.h"
 
 int pDialogueNPCCount;
 std::array<struct Texture *, 6> pDialogueNPCPortraits;
--- a/NPC.h	Mon Apr 07 19:15:13 2014 +0600
+++ b/NPC.h	Mon Apr 07 19:15:31 2014 +0600
@@ -206,3 +206,12 @@
 bool CheckHiredNPCSpeciality(unsigned int uProfession);
 
 int UseNPCSkill(NPCProf profession);
+void __fastcall ClickNPCTopic(signed int uMessageParam);
+const char *ContractSelectText(int pEventCode);
+void NPCHireableDialogPrepare();
+void _4B4224_UpdateNPCTopics(int _this);
+const char *GetProfessionActionText(int a1);
+struct NPCData *__fastcall GetNPCData(signed int npcid);
+struct NPCData * GetNewNPCData(signed int npcid, int* npc_indx);
+int __fastcall GetGreetType(signed int SpeakingNPC_ID);
+int NPC_EventProcessor(int npc_event_id, int entry_line = 0);
--- a/OSWindow.cpp	Mon Apr 07 19:15:13 2014 +0600
+++ b/OSWindow.cpp	Mon Apr 07 19:15:31 2014 +0600
@@ -22,6 +22,7 @@
 #include "Log.h"
 #include "LOD.h"
 #include "Outdoor_stuff.h"
+#include "Registry.h"
 
 
 bool wizard_eye = false;         //    
@@ -45,12 +46,12 @@
   pMouse->SetMouseClick(x, y);
 
   if (GetCurrentMenuID() == MENU_CREATEPARTY)
-    UI_OnKeyDown(VK_SELECT);
+    Mouse::UI_OnKeyDown(VK_SELECT);
 
   if (pGame)
     pGame->PickMouse(512.0, x, y, false, &vis_sprite_filter_3, &vis_door_filter);
 
-  UI_OnMouseLeftClick(0);
+  Mouse::UI_OnMouseLeftClick(0);
   return true;
 }
 
@@ -225,7 +226,7 @@
         if ( wparam == VK_RETURN )
         {
           if ( !viewparams->field_4C )
-            UI_OnKeyDown(wparam);
+            Mouse::UI_OnKeyDown(wparam);
           return 0;
         }
         if (wparam == VK_CONTROL)
@@ -254,7 +255,7 @@
           if ( pCurrentScreen != SCREEN_GAME && pCurrentScreen != SCREEN_MODAL_WINDOW )
           {
             if ( !viewparams->field_4C )
-              UI_OnKeyDown(wparam);
+              Mouse::UI_OnKeyDown(wparam);
             return 0;
           }
         }
--- a/OurMath.cpp	Mon Apr 07 19:15:13 2014 +0600
+++ b/OurMath.cpp	Mon Apr 07 19:15:31 2014 +0600
@@ -198,4 +198,55 @@
 int fixpoint_from_int(int lhv, int rhv)
 {
   return (lhv << 16) | rhv;
-}
\ No newline at end of file
+}
+
+
+//----- (00452A9E) --------------------------------------------------------
+int integer_sqrt(int val)
+{
+  signed int result; // eax@2
+  unsigned int v2; // edx@3
+  unsigned int v3; // edi@3
+  //signed int v4; // ebx@3
+  int v5; // esi@4
+
+  if (val < 1)
+    return val;
+
+  v2 = 0;
+  v3 = val;
+  result = 0;
+  //v4 = 16;
+  for (uint i = 0; i < 16; ++i)
+  {
+    result *= 2;
+    v2 = (v3 >> 30) | 4 * v2;
+    v5 = 2 * result + 1;
+    v3 *= 4;
+    if ( v2 >= v5 )
+    {
+      ++result;
+      v2 -= v5;
+    }
+    //--v4;
+  }
+  //while ( v4 );
+  if ( val - result * result >= (unsigned int)(result - 1) )
+    ++result;
+  return result;
+}
+
+//----- (00452B2E) --------------------------------------------------------
+int __fastcall GetDiceResult(unsigned int uNumDice, unsigned int uDiceSides)
+{
+  int v3; // esi@1
+
+  v3 = 0;
+  if ( uDiceSides )
+  {
+    for ( uint i = 0; i < uNumDice; ++i)
+      v3 += rand() % uDiceSides + 1;
+    return v3;
+  }
+  return 0;
+}
--- a/OurMath.h	Mon Apr 07 19:15:13 2014 +0600
+++ b/OurMath.h	Mon Apr 07 19:15:31 2014 +0600
@@ -30,6 +30,9 @@
 __int64 fixpoint_sub_unknown(int, int);
 int fixpoint_from_float(float value);
 int fixpoint_from_int(int lhv, int rhv);
+int integer_sqrt(int val);
+int __fastcall GetDiceResult(unsigned int uNumDice, unsigned int uDiceSides); // idb
+inline int round_to_int(float x) { return (int)floor(x + 0.5f); }
 
 template <typename FloatType>
 inline int bankersRounding(const FloatType& value)
--- a/Outdoor.cpp	Mon Apr 07 19:15:13 2014 +0600
+++ b/Outdoor.cpp	Mon Apr 07 19:15:31 2014 +0600
@@ -3111,124 +3111,6 @@
     out->z = invmag * nz * 65536.0;
   }
 }
-//----- (004014E6) --------------------------------------------------------
-void MakeActorAIList_ODM()
-{
-  int v1; // eax@4
-//  int v2; // ebx@4
-//  unsigned int v3; // ecx@4
-//  int v4; // edx@5
-//  int v5; // edx@7
-//  unsigned int v6; // edx@9
-  unsigned int v7; // ST20_4@10
-  int v9; // edi@10
-  int v10; // ebx@14
-  int v21; // [sp+Ch] [bp-14h]@4
-  int v22; // [sp+10h] [bp-10h]@4
-
-  pParty->uFlags &= 0xFFFFFFCFu;
-
-  ai_arrays_size = 0;
-  for (uint i = 0; i < uNumActors; ++i)
-  {
-    Actor* actor = &pActors[i];
-
-    actor->uAttributes &= 0xFFFFFBFF;
-    if (!actor->CanAct())
-    {
-      actor->uAttributes &= 0xFFFFBFFF;
-      continue;
-    }
-
-    v22 = abs(pParty->vPosition.z - actor->vPosition.z);
-    v21 = abs(pParty->vPosition.y - actor->vPosition.y);
-    v1 = abs(pParty->vPosition.x - actor->vPosition.x);
-      v7 = int_get_vector_length(v22, v21, v1);
-	  //v8 = actor->uActorRadius;
-      v9 = v7 - actor->uActorRadius;
-      //v23 = v7 - v8;
-      if ( v9 < 0 )
-      {
-        v9 = 0;
-        //v23 = 0;
-      }
-
-      if (v9 < 5632)
-      {
-        v10 = actor->uAttributes & 0xFEFFFFFF;
-        actor->uAttributes = v10;
-        if ( v10 & 0x80000 || actor->GetActorsRelation(0) )
-        {
-          //v11 = (pParty->uFlags & 0x10) == 0;
-          actor->uAttributes = v10 | 0x1000000;
-          if (v9 < 5120 )
-            pParty->SetYellowAlert();
-          if (v9 < 307)
-            pParty->SetRedAlert();
-        }
-		actor->uAttributes |= 0x00004000;
-        ai_near_actors_distances[ai_arrays_size] = v9;
-        ai_near_actors_ids[ai_arrays_size++] = i;
-      }
-      else
-		  actor->uAttributes &= 0xFFFFBFFF;
-  }
-
-  /*
-  result = v27;
-  if ( v27 > 0 )
-  {
-    v14 = 0;
-    v15 = 1;
-    v26 = 1;
-    do
-    {
-      while ( 1 )
-      {
-        v24 = v15;
-        if ( v15 >= result )
-          break;
-        v16 = ai_near_actors_distances[v14];
-        if ( v16 > ai_near_actors_distances[v15] )
-        {
-          v17 = &ai_near_actors_ids[v15];
-          v18 = ai_near_actors_ids[v14];
-          ai_near_actors_ids[v14] = *v17;
-          *v17 = v18;
-          v15 = v24;
-          ai_near_actors_distances[v14] = ai_near_actors_distances[v24];
-          ai_near_actors_distances[v24] = v16;
-        }
-        result = v27;
-        ++v15;
-      }
-      ++v14;
-      v15 = v26 + 1;
-      v26 = v15;
-    }
-    while ( v15 - 1 < result );
-  }*/
-
-  for (uint i = 0; i < ai_arrays_size; ++i)
-    for (uint j = 0; j < i; ++j)
-      if (ai_near_actors_distances[j] > ai_near_actors_distances[i])
-      {
-        int tmp = ai_near_actors_distances[j];
-        ai_near_actors_distances[j] = ai_near_actors_distances[i];
-        ai_near_actors_distances[i] = tmp;
-
-        tmp = ai_near_actors_ids[j];
-        ai_near_actors_ids[j] = ai_near_actors_ids[i];
-        ai_near_actors_ids[i] = tmp;
-      }
-
-
-  if (ai_arrays_size > 30)
-    ai_arrays_size = 30;
-
-  for (uint i = 0; i < ai_arrays_size; ++i)
-    pActors[ai_near_actors_ids[i]].uAttributes |= 0x0400;
-}
 //----- (0046BE0A) --------------------------------------------------------
 void ODM_UpdateUserInputAndOther()
 {
@@ -3265,7 +3147,7 @@
   check_event_triggers();
 }
 //----- (0041F54A) --------------------------------------------------------
-void LoadActualSkyFrame()
+void OutdoorLocation::LoadActualSkyFrame()
 {
   if ( pTexture_RestUI_CurrentSkyFrame )
     pTexture_RestUI_CurrentSkyFrame->Release();
--- a/Outdoor.h	Mon Apr 07 19:15:13 2014 +0600
+++ b/Outdoor.h	Mon Apr 07 19:15:31 2014 +0600
@@ -168,6 +168,8 @@
   void SetFog();
   void Draw();
 
+  static void LoadActualSkyFrame();
+
 
   char pLevelFilename[32];
   char pLocationFileName[32];
@@ -245,6 +247,12 @@
 
 extern struct OutdoorLocation *pOutdoor;
 
+void ODM_UpdateUserInputAndOther();
+int ODM_GetFloorLevel(int X, signed int Y, int Z, int, int *pOnWater, int *bmodel_pid, int bWaterWalk);
+int GetCeilingHeight(int Party_X, signed int Party_Y, int Party_ZHeight, int pFaceID);
+void ODM_GetTerrainNormalAt(int pos_x, int pos_z, Vec3_int_ *out);
+void UpdateActors_ODM();
+void ODM_ProcessPartyActions();
 
 
 
--- a/PaletteManager.cpp	Mon Apr 07 19:15:13 2014 +0600
+++ b/PaletteManager.cpp	Mon Apr 07 19:15:31 2014 +0600
@@ -5,6 +5,7 @@
 #include "Game.h"
 #include "LOD.h"
 #include "Log.h"
+#include "OurMath.h"
 
 #include "mm7_data.h"
 
@@ -953,4 +954,28 @@
     result = (unsigned __int16 *)pPaletteManager->pPalette1[a1];
   return result;
 }
-// 4D864C: using guessed type char byte_4D864C;
\ No newline at end of file
+// 4D864C: using guessed type char byte_4D864C;
+
+
+//----- (0048A959) --------------------------------------------------------
+signed int ReplaceHSV(unsigned int uColor, float h_replace, float s_replace, float v_replace)
+{
+  float r = ((uColor & 0x00FF0000) >> 16) / 255.0f,
+    g = ((uColor & 0x0000FF00) >> 8) / 255.0f,
+    b = (uColor & 0x000000FF) / 255.0f;
+
+  float h, s, v;
+  RGB2HSV(&h, &s, r, g, b, &v);
+
+  if ( h_replace != -1.0 )
+    h = h_replace;
+  if ( s_replace != -1.0 )
+    s = s_replace;
+  if ( v_replace != -1.0 )
+    v = v_replace;
+  HSV2RGB(&r, &g, &b, h, s, v);
+
+  return (((uint)round_to_int(r * 255.0f) & 0xFF) << 16) |
+    (((uint)round_to_int(g * 255.0f) & 0xFF) << 8) |
+    (((uint)round_to_int(b * 255.0f) & 0xFF));
+}
\ No newline at end of file
--- a/PaletteManager.h	Mon Apr 07 19:15:13 2014 +0600
+++ b/PaletteManager.h	Mon Apr 07 19:15:31 2014 +0600
@@ -47,4 +47,7 @@
 
 
 
+bool __fastcall HSV2RGB(float *a1, float *a2, float *a3, float a4, float a5, float a6);
+void __fastcall RGB2HSV(float *a1, float *a2, float a3, float a4, float a5, float *a6);
+signed int ReplaceHSV(unsigned int uColor, float a2, float gamma, float a4);
 extern PaletteManager *pPaletteManager;
\ No newline at end of file
--- a/Party.cpp	Mon Apr 07 19:15:13 2014 +0600
+++ b/Party.cpp	Mon Apr 07 19:15:31 2014 +0600
@@ -805,7 +805,7 @@
   signed __int64 v2; // st7@3
 
   if ( uHoursToSleep > 240 )
-    InitializeActors();
+    Actor::InitializeActors();
   v2 = (signed __int64)((7680 * uHoursToSleep) * 0.033333335);
   pParty->uTimePlayed += v2;
   for (int i = 1; i <= 4; i++)
@@ -849,7 +849,7 @@
   pParty->UpdatePlayersAndHirelingsEmotions();
 }
 //----- (0041F5BE) --------------------------------------------------------
-void  Sleep6Hours()
+void  Party::Sleep6Hours()
 {
   if ( _506F18_num_minutes_to_sleep < 6 )
   {
@@ -857,7 +857,7 @@
     {
       Rest(_506F18_num_minutes_to_sleep);
       _506F18_num_minutes_to_sleep = 0;
-      LoadActualSkyFrame();
+      OutdoorLocation::LoadActualSkyFrame();
     }
     if ( dword_506F14 == 2 )
     {
@@ -868,7 +868,7 @@
   {
     Rest(6u);
     _506F18_num_minutes_to_sleep -= 6;
-    LoadActualSkyFrame();
+    OutdoorLocation::LoadActualSkyFrame();
   }
   viewparams->bRedrawGameUI = 1;
 }
--- a/Party.h	Mon Apr 07 19:15:13 2014 +0600
+++ b/Party.h	Mon Apr 07 19:15:31 2014 +0600
@@ -202,6 +202,8 @@
   static void TakeFood(unsigned int uNumFood);
   static void GiveFood(unsigned int _this);
 
+  static void Sleep6Hours();
+
   inline bool WizardEyeActive()      {return pPartyBuffs[PARTY_BUFF_WIZARD_EYE].uExpireTime > 0;}
   inline int  WizardEyeSkillLevel()  {return pPartyBuffs[PARTY_BUFF_WIZARD_EYE].uSkill;}
   inline bool TorchlightActive()     {return pPartyBuffs[PARTY_BUFF_TORCHLIGHT].uExpireTime > 0;}
@@ -323,3 +325,5 @@
 extern struct ActionQueue *pPartyActionQueue;
 
 bool TestPartyQuestBit(PARTY_QUEST_BITS bit);
+void __fastcall Rest(unsigned int uHoursToSleep);
+void RestAndHeal(__int64 uNumMinutes); // idb
--- a/Player.cpp	Mon Apr 07 19:15:13 2014 +0600
+++ b/Player.cpp	Mon Apr 07 19:15:31 2014 +0600
@@ -32,6 +32,7 @@
 #include "SpriteObject.h"
 #include "DecalBuilder.h"
 #include "CastSpellInfo.h"
+#include "OurMath.h"
 
 
 
@@ -8072,7 +8073,7 @@
     a3.z = actor->vPosition.z - pParty->vPosition.z;
     Vec3_int_::Normalize(&a3.x, &a3.y, &a3.z);
 
-    DamageMonsterFromParty(PID(OBJECT_Player, uActiveCharacter - 1), target_id, &a3);
+    Actor::DamageMonsterFromParty(PID(OBJECT_Player, uActiveCharacter - 1), target_id, &a3);
     if (player->WearsItem(ITEM_ARTIFACT_SPLITTER, EQUIP_TWO_HANDED) || player->WearsItem(ITEM_ARTIFACT_SPLITTER, EQUIP_SINGLE_HANDED))
           _42FA66_do_explosive_impact(actor->vPosition.x, actor->vPosition.y, actor->vPosition.z + actor->uActorHeight / 2, 0, 512, uActiveCharacter);
   }
--- a/Player.h	Mon Apr 07 19:15:13 2014 +0600
+++ b/Player.h	Mon Apr 07 19:15:31 2014 +0600
@@ -846,4 +846,10 @@
 };
 #pragma pack(pop)
 
+void __fastcall DamagePlayerFromMonster(unsigned int uObjID, int a2, struct Vec3_int_ *pPos, signed int a4);
+bool IsDwarfPresentInParty(bool b);
+bool  ShouldLoadTexturesForRaceAndGender(unsigned int _this);
+int PlayerCreation_GetUnspentAttributePointCount();
+int CycleCharacter(bool backwards);
+
 extern NZIArray<struct Player *, 5> pPlayers;
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Registry.cpp	Mon Apr 07 19:15:31 2014 +0600
@@ -0,0 +1,182 @@
+#define _CRT_SECURE_NO_WARNINGS
+#include <stdio.h>
+#include <array>
+#include <windows.h>
+
+#include "Registry.h"
+
+//----- (004649EF) --------------------------------------------------------
+int __fastcall ReadWindowsRegistryInt(const char *pKey, int uDefValue)
+{
+  int v3; // [sp+4h] [bp-24h]@1
+  DWORD cbData; // [sp+8h] [bp-20h]@1
+  LPCSTR lpValueName; // [sp+Ch] [bp-1Ch]@1
+  DWORD dwDisposition; // [sp+10h] [bp-18h]@2
+  BYTE Data[4]; // [sp+14h] [bp-14h]@5
+  HKEY hKey; // [sp+18h] [bp-10h]@1
+  HKEY phkResult; // [sp+1Ch] [bp-Ch]@1
+  HKEY v10; // [sp+20h] [bp-8h]@1
+  HKEY v11; // [sp+24h] [bp-4h]@1
+
+  v3 = uDefValue;
+  lpValueName = pKey;
+  v11 = 0;
+  v10 = 0;
+  hKey = 0;
+  phkResult = 0;
+  cbData = 4;
+  if ( !RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE", 0, KEY_READ|KEY_WOW64_32KEY, &hKey) )// for 64 bit
+  {
+    if ( !RegCreateKeyExA(hKey, "New World Computing", 0, "", 0, 0xF003Fu, 0, &phkResult, &dwDisposition) )
+    {
+      if ( !RegCreateKeyExA(phkResult, "Might and Magic VII", 0, "", 0, 0xF003Fu, 0, &v10, &dwDisposition) )
+      {
+        if ( !RegCreateKeyExA(v10, "1.0", 0, "", 0, 0xF003Fu, 0, &v11, &dwDisposition) )
+        {
+          if ( RegQueryValueExA(v11, lpValueName, 0, 0, Data, &cbData) )
+          {
+            *(int *)Data = v3;
+            RegSetValueExA(v11, lpValueName, 0, 4u, Data, 4u);
+          }
+          RegCloseKey(v11);
+        }
+        RegCloseKey(v10);
+      }
+      RegCloseKey(phkResult);
+    }
+    RegCloseKey(hKey);
+  }
+  return *(int *)Data;
+}
+
+//----- (00464B02) --------------------------------------------------------
+void __fastcall WriteWindowsRegistryString(const char *pKey, const char *pString)
+{
+  size_t v2; // eax@5
+  const char *lpValueName; // [sp+4h] [bp-1Ch]@1
+  const char *Str; // [sp+8h] [bp-18h]@1
+  DWORD dwDisposition; // [sp+Ch] [bp-14h]@2
+  HKEY hKey; // [sp+10h] [bp-10h]@1
+  HKEY phkResult; // [sp+14h] [bp-Ch]@1
+  HKEY v8; // [sp+18h] [bp-8h]@1
+  HKEY v9; // [sp+1Ch] [bp-4h]@1
+
+  Str = pString;
+  lpValueName = pKey;
+  v9 = 0;
+  v8 = 0;
+  hKey = 0;
+  phkResult = 0;
+  if ( !RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE", 0, 0x2001Fu, &hKey) )
+  {
+    if ( !RegCreateKeyExA(hKey, "New World Computing", 0, "", 0, 0xF003Fu, 0, &phkResult, &dwDisposition) )
+    {
+      if ( !RegCreateKeyExA(phkResult, "Might and Magic VII", 0, "", 0, 0xF003Fu, 0, &v8, &dwDisposition) )
+      {
+        if ( !RegCreateKeyExA(v8, "1.0", 0, "", 0, 0xF003Fu, 0, &v9, &dwDisposition) )
+        {
+          v2 = strlen(Str);
+          RegSetValueExA(v9, lpValueName, 0, 1u, (const BYTE *)Str, v2 + 1);
+          RegCloseKey(v9);
+        }
+        RegCloseKey(v8);
+      }
+      RegCloseKey(phkResult);
+    }
+    RegCloseKey(hKey);
+  }
+}
+
+//----- (00464BEF) --------------------------------------------------------
+void __fastcall ReadWindowsRegistryString(const char *pKeyName, char *pOutString, int uBufLen, const char *pDefaultValue)
+{
+  LSTATUS (__stdcall *v4)(HKEY); // esi@1
+  LSTATUS result; // eax@7
+  DWORD Type; // [sp+Ch] [bp-24h]@5
+  LPCSTR lpValueName; // [sp+10h] [bp-20h]@1
+  DWORD cbData; // [sp+14h] [bp-1Ch]@1
+  LPBYTE Dest; // [sp+18h] [bp-18h]@1
+  DWORD dwDisposition; // [sp+1Ch] [bp-14h]@2
+  HKEY phkResult; // [sp+20h] [bp-10h]@1
+  HKEY hKey; // [sp+24h] [bp-Ch]@1
+  HKEY v13; // [sp+28h] [bp-8h]@1
+  HKEY v14; // [sp+2Ch] [bp-4h]@1
+
+  cbData = uBufLen;
+  Dest = (LPBYTE)pOutString;
+  lpValueName = pKeyName;
+  v14 = 0;
+  v13 = 0;
+  hKey = 0;
+  phkResult = 0;
+  v4 = RegCloseKey;
+  if ( RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE", 0, 0x2001Fu, &hKey)
+    || RegCreateKeyExA(hKey, "New World Computing", 0, "", 0, 0xF003Fu, 0, &phkResult, &dwDisposition)
+    || RegCreateKeyExA(phkResult, "Might and Magic VII", 0, "", 0, 0xF003Fu, 0, &v13, &dwDisposition)
+    || RegCreateKeyExA(v13, "1.0", 0, "", 0, 0xF003Fu, 0, &v14, &dwDisposition) )
+  {
+    result = (LSTATUS)strncpy((char *)Dest, pDefaultValue, uBufLen);
+  }
+  else if ( RegQueryValueExA(v14, lpValueName, 0, &Type, Dest, &cbData) )
+  {
+    RegCloseKey(v14);
+    v14 = 0;
+    result = (LSTATUS)strncpy((char *)Dest, pDefaultValue, uBufLen);
+  }
+  else
+  {
+    v4 = RegCloseKey;
+    RegCloseKey(v14);
+    v14 = 0;
+    RegCloseKey(v13);
+    v13 = 0;
+    RegCloseKey(phkResult);
+    phkResult = 0;
+    result = RegCloseKey(hKey);
+    hKey = 0;
+  }
+  if ( v14 )
+    result = v4(v14);
+  if ( v13 )
+    result = v4(v13);
+  if ( hKey )
+    result = v4(hKey);
+  if ( phkResult )
+    result = v4(phkResult);
+}
+
+//----- (00464D32) --------------------------------------------------------
+void __fastcall WriteWindowsRegistryInt(const char *pKey, int val)
+{
+  const char *lpValueName; // [sp+4h] [bp-1Ch]@1
+  BYTE Data[4]; // [sp+8h] [bp-18h]@1
+  DWORD dwDisposition; // [sp+Ch] [bp-14h]@2
+  HKEY hKey; // [sp+10h] [bp-10h]@1
+  HKEY phkResult; // [sp+14h] [bp-Ch]@1
+  HKEY v7; // [sp+18h] [bp-8h]@1
+  HKEY v8; // [sp+1Ch] [bp-4h]@1
+
+  *(int *)Data = val;
+  lpValueName = pKey;
+  v8 = 0;
+  v7 = 0;
+  hKey = 0;
+  phkResult = 0;
+  if ( !RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE", 0, 0x2001Fu, &hKey) )
+  {
+    if ( !RegCreateKeyExA(hKey, "New World Computing", 0, "", 0, 0xF003Fu, 0, &phkResult, &dwDisposition) )
+    {
+      if ( !RegCreateKeyExA(phkResult, "Might and Magic VII", 0, "", 0, 0xF003Fu, 0, &v7, &dwDisposition) )
+      {
+        if ( !RegCreateKeyExA(v7, "1.0", 0, "", 0, 0xF003Fu, 0, &v8, &dwDisposition) )
+        {
+          RegSetValueExA(v8, lpValueName, 0, 4, Data, 4);
+          RegCloseKey(v8);
+        }
+        RegCloseKey(v7);
+      }
+      RegCloseKey(phkResult);
+    }
+    RegCloseKey(hKey);
+  }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Registry.h	Mon Apr 07 19:15:31 2014 +0600
@@ -0,0 +1,8 @@
+#pragma once
+
+
+
+int __fastcall ReadWindowsRegistryInt(const char *pKey, int uDefValue); // idb
+void __fastcall WriteWindowsRegistryString(const char *pKey, const char *pString);
+void __fastcall ReadWindowsRegistryString(const char *pKeyName, char *pOutString, int uBufLen, const char *pDefaultValue);
+void __fastcall WriteWindowsRegistryInt(const char *pKey, int val);
\ No newline at end of file
--- a/Render.cpp	Mon Apr 07 19:15:13 2014 +0600
+++ b/Render.cpp	Mon Apr 07 19:15:31 2014 +0600
@@ -33,6 +33,7 @@
 #include "Lights.h"
 #include "Level/Decoration.h"
 #include "Vis.h"
+#include "Registry.h"
 
 //#pragma comment(lib, "lib\\legacy_dx\\lib\\ddraw.lib")
 //#pragma comment(lib, "lib\\legacy_dx\\lib\\dxguid.lib")
--- a/Render.h	Mon Apr 07 19:15:13 2014 +0600
+++ b/Render.h	Mon Apr 07 19:15:31 2014 +0600
@@ -514,6 +514,8 @@
 };
 #pragma pack(pop)
 
+bool PauseGameDrawing();
+
 extern struct IDirectDrawClipper *pDDrawClipper;
 extern struct Render *pRenderer; // idb
 extern struct pUnkTerrain *Unks;
@@ -569,4 +571,8 @@
 extern RenderVertexSoft array_50AC10[50];
 extern RenderVertexSoft array_73D150[20];
 
-extern RenderVertexD3D3 d3d_vertex_buffer[50];
\ No newline at end of file
+extern RenderVertexD3D3 d3d_vertex_buffer[50];
+
+
+int ODM_NearClip(unsigned int uVertexID); // idb
+int ODM_FarClip(unsigned int uNumVertices);
\ No newline at end of file
--- a/SaveLoad.h	Mon Apr 07 19:15:13 2014 +0600
+++ b/SaveLoad.h	Mon Apr 07 19:15:31 2014 +0600
@@ -44,6 +44,11 @@
 #pragma pack(pop)
 
 
+void __fastcall LoadGame(unsigned int uSlot); // idb
+void SaveGame(bool IsAutoSAve, bool NotSaveWorld);
+void __fastcall DoSavegame(unsigned int uSlot); // idb
+bool Initialize_GamesLOD_NewLOD();
+void SaveNewGame();
 
 extern unsigned int uNumSavegameFiles;
 extern std::array<unsigned int, 45> pSavegameUsedSlots;
--- a/Spells.cpp	Mon Apr 07 19:15:13 2014 +0600
+++ b/Spells.cpp	Mon Apr 07 19:15:31 2014 +0600
@@ -1,6 +1,5 @@
 #define _CRT_SECURE_NO_WARNINGS
 #include <stdlib.h>
-#include "mm7_unsorted_subs.h"
 #include "ErrorHandling.h"
 
 #include "Spells.h"
--- a/Spells.h	Mon Apr 07 19:15:13 2014 +0600
+++ b/Spells.h	Mon Apr 07 19:15:31 2014 +0600
@@ -286,3 +286,6 @@
 extern std::array<unsigned int, 25> wand_spell_ids;
 
 int _43AFE3_calc_spell_damage(int spellId, int spellLevel, signed int skillMastery, int currentHp);
+
+bool sub_427769_isSpellQuickCastableOnShiftClick(unsigned int uSpellID);
+void __fastcall EventCastSpell(int uSpellID, int uSkillLevel, int uSkill, int fromx, int fromy, int fromz, int tox, int toy, int toz);//sub_448DF8
--- a/SpriteObject.cpp	Mon Apr 07 19:15:13 2014 +0600
+++ b/SpriteObject.cpp	Mon Apr 07 19:15:31 2014 +0600
@@ -931,7 +931,7 @@
   uNumSpriteObjects = new_obj_pos;
 }
 //----- (00408896) --------------------------------------------------------
-void InitializeSpriteObjects()
+void SpriteObject::InitializeSpriteObjects()
 {
   for (uint i = 0; i < uNumSpriteObjects; ++i)
   {
--- a/SpriteObject.h	Mon Apr 07 19:15:13 2014 +0600
+++ b/SpriteObject.h	Mon Apr 07 19:15:31 2014 +0600
@@ -24,6 +24,7 @@
   static void OnInteraction(unsigned int uLayingItemID);
   static bool sub_42F7EB_DropItemAt(unsigned int uSpriteID, int x, int y, int z, int a4, int count, int a7, unsigned __int16 attributes, ItemGen *a9);
   static void sub_42F960_create_object(int x, int y, int z);
+  static void InitializeSpriteObjects();
 
 
   unsigned __int16 uType;
@@ -52,6 +53,7 @@
 #pragma pack(pop)
 
 
+void CompactLayingItemsList();
 
 extern size_t uNumSpriteObjects;
 extern std::array<SpriteObject, MAX_SPRITE_OBJECTS> pSpriteObjects;
\ No newline at end of file
--- a/Sprites.cpp	Mon Apr 07 19:15:13 2014 +0600
+++ b/Sprites.cpp	Mon Apr 07 19:15:31 2014 +0600
@@ -9,7 +9,6 @@
 #include "FrameTableInc.h"
 
 #include "mm7_data.h"
-#include "mm7_unsorted_subs.h"
 #include "Outdoor.h"
 #include "DecorationList.h"
 #include "MM7.h"
--- a/UI/Books/UIMapBook.cpp	Mon Apr 07 19:15:13 2014 +0600
+++ b/UI/Books/UIMapBook.cpp	Mon Apr 07 19:15:31 2014 +0600
@@ -1,4 +1,5 @@
 #define _CRT_SECURE_NO_WARNINGS
+#include "..\..\Events.h"
 #include "..\..\mm7_unsorted_subs.h"
 #include "..\..\MM7.h"
 #include "..\..\Render.h"
--- a/UI/UIHouses.cpp	Mon Apr 07 19:15:13 2014 +0600
+++ b/UI/UIHouses.cpp	Mon Apr 07 19:15:31 2014 +0600
@@ -1,5 +1,6 @@
 #define _CRT_SECURE_NO_WARNINGS
 #include "..\mm7_unsorted_subs.h"
+#include "..\SaveLoad.h"
 #include "..\Texture.h"
 #include "..\mm7_data.h"
 #include "..\ErrorHandling.h"
@@ -23,6 +24,7 @@
 #include "..\MapInfo.h"
 #include "..\Log.h"
 #include "..\Game.h"
+#include "..\CastSpellInfo.h"
 
 #include "..\stru159.h"
 int uHouse_ExitPic; // weak
--- a/UI/UIMainMenu.cpp	Mon Apr 07 19:15:13 2014 +0600
+++ b/UI/UIMainMenu.cpp	Mon Apr 07 19:15:31 2014 +0600
@@ -14,6 +14,7 @@
 
 #include "..\mm7_data.h"
 #include "..\mm7_unsorted_subs.h"
+#include "..\Game.h"
 
 
 //----- (0041B578) --------------------------------------------------------
--- a/UI/UIRest.cpp	Mon Apr 07 19:15:13 2014 +0600
+++ b/UI/UIRest.cpp	Mon Apr 07 19:15:31 2014 +0600
@@ -64,7 +64,7 @@
   uTextureID_RestUI_restb3 = pIcons_LOD->LoadTexture("restb3", TEXTURE_16BIT_PALETTE);
   uTextureID_RestUI_restb4 = pIcons_LOD->LoadTexture("restb4", TEXTURE_16BIT_PALETTE);
   uTextureID_RestUI_restexit = pIcons_LOD->LoadTexture("restexit", TEXTURE_16BIT_PALETTE);
-  LoadActualSkyFrame();
+  OutdoorLocation::LoadActualSkyFrame();
   pGUIWindow_CurrentMenu = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_Rest, 0, 0);
   pButton_RestUI_Exit          = pGUIWindow_CurrentMenu->CreateButton(280, 297, 154, 37, 1, 0, UIMSG_ExitRest,       0,   0, "", pIcons_LOD->GetTexture(uTextureID_RestUI_restexit), 0);
   pButton_RestUI_Main          = pGUIWindow_CurrentMenu->CreateButton( 24, 154, 225, 37, 1, 0, UIMSG_Rest8Hour,      0, 'R', "", pIcons_LOD->GetTexture(uTextureID_RestUI_restb4), 0);
@@ -158,7 +158,7 @@
     sprintf(pTmpBuf.data(), "%s\r190%d", pGlobalTXT_LocalizationStrings[245], pParty->uCurrentYear);//
     pGUIWindow_CurrentMenu->DrawText(pFontCreate, 350, 254, Color16(10, 0, 0), pTmpBuf.data(), 0, 0, Color16(230, 214, 193));
     if ( dword_506F14 )
-      Sleep6Hours();
+      Party::Sleep6Hours();
   }
   else
     GUIWindow::Create(pButton_RestUI_Exit->uX, pButton_RestUI_Exit->uY, 0, 0, WINDOW_CloseRestWindowBtn, 
--- a/UI/UiGame.cpp	Mon Apr 07 19:15:13 2014 +0600
+++ b/UI/UiGame.cpp	Mon Apr 07 19:15:31 2014 +0600
@@ -1,4 +1,5 @@
 #define _CRT_SECURE_NO_WARNINGS
+#include "..\Events.h"
 #include "..\mm7_unsorted_subs.h"
 #include "..\Texture.h"
 #include "..\MM7.h"
@@ -32,6 +33,7 @@
 #include "..\BSPModel.h"
 #include "..\OurMath.h"
 #include "..\Level/Decoration.h"
+#include "..\Chest.h"
 
 
 int uTextureID_GameUI_CharSelectionFrame; // 50C98C
@@ -1342,7 +1344,7 @@
     //() -------------------------------------------
     if ( pCurrentScreen == SCREEN_CHEST )
     {
-      ChestUI_WritePointedObjectStatusString();
+      Chest::ChestUI_WritePointedObjectStatusString();
       if ( pMouse->uPointingObjectID == 0 )
       {
         if ( uLastPointedObjectID != 0 )
--- a/Viewport.h	Mon Apr 07 19:15:13 2014 +0600
+++ b/Viewport.h	Mon Apr 07 19:15:31 2014 +0600
@@ -31,6 +31,7 @@
 };
 #pragma pack(pop)
 
+void OnGameViewportClick();
 
 
 extern struct Viewport *pViewport;
--- a/mm7_2.cpp	Mon Apr 07 19:15:13 2014 +0600
+++ b/mm7_2.cpp	Mon Apr 07 19:15:31 2014 +0600
@@ -28,6 +28,7 @@
 #include "Overlays.h"
 #include "Arcomage.h"
 #include "LOD.h"
+#include "Log.h"
 #include "Actor.h"
 #include "Events.h"
 #include "Viewport.h"
@@ -59,6 +60,7 @@
 #include "Level/Decoration.h"
 #include "LuaVM.h"
 #include "MMT.h"
+#include "Registry.h"
 
 //#include "lib/lua/lua.h"
 
@@ -1876,56 +1878,6 @@
                                                                     + (__PAIR__(v10, (unsigned __int16)a4 >> 2) & 0x1C00));
 }
 
-//----- (00452A9E) --------------------------------------------------------
-int integer_sqrt(int val)
-{
-  signed int result; // eax@2
-  unsigned int v2; // edx@3
-  unsigned int v3; // edi@3
-  //signed int v4; // ebx@3
-  int v5; // esi@4
-
-  if (val < 1)
-    return val;
-
-    v2 = 0;
-    v3 = val;
-    result = 0;
-    //v4 = 16;
-  for (uint i = 0; i < 16; ++i)
-  {
-      result *= 2;
-      v2 = (v3 >> 30) | 4 * v2;
-      v5 = 2 * result + 1;
-      v3 *= 4;
-      if ( v2 >= v5 )
-      {
-        ++result;
-        v2 -= v5;
-      }
-      //--v4;
-  }
-    //while ( v4 );
-    if ( val - result * result >= (unsigned int)(result - 1) )
-      ++result;
-    return result;
-}
-
-//----- (00452B2E) --------------------------------------------------------
-int __fastcall GetDiceResult(unsigned int uNumDice, unsigned int uDiceSides)
-{
-  int v3; // esi@1
-
-  v3 = 0;
-  if ( uDiceSides )
-  {
-    for ( uint i = 0; i < uNumDice; ++i)
-      v3 += rand() % uDiceSides + 1;
-    return v3;
-  }
-  return 0;
-}
-
 
 
 //----- (004547E4) --------------------------------------------------------
@@ -2509,181 +2461,6 @@
   _flushall();
 }
 
-//----- (004649EF) --------------------------------------------------------
-int __fastcall ReadWindowsRegistryInt(const char *pKey, int uDefValue)
-{
-  int v3; // [sp+4h] [bp-24h]@1
-  DWORD cbData; // [sp+8h] [bp-20h]@1
-  LPCSTR lpValueName; // [sp+Ch] [bp-1Ch]@1
-  DWORD dwDisposition; // [sp+10h] [bp-18h]@2
-  BYTE Data[4]; // [sp+14h] [bp-14h]@5
-  HKEY hKey; // [sp+18h] [bp-10h]@1
-  HKEY phkResult; // [sp+1Ch] [bp-Ch]@1
-  HKEY v10; // [sp+20h] [bp-8h]@1
-  HKEY v11; // [sp+24h] [bp-4h]@1
-
-  v3 = uDefValue;
-  lpValueName = pKey;
-  v11 = 0;
-  v10 = 0;
-  hKey = 0;
-  phkResult = 0;
-  cbData = 4;
-  if ( !RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE", 0, KEY_READ|KEY_WOW64_32KEY, &hKey) )// for 64 bit
-  {
-    if ( !RegCreateKeyExA(hKey, "New World Computing", 0, "", 0, 0xF003Fu, 0, &phkResult, &dwDisposition) )
-    {
-      if ( !RegCreateKeyExA(phkResult, "Might and Magic VII", 0, "", 0, 0xF003Fu, 0, &v10, &dwDisposition) )
-      {
-        if ( !RegCreateKeyExA(v10, "1.0", 0, "", 0, 0xF003Fu, 0, &v11, &dwDisposition) )
-        {
-          if ( RegQueryValueExA(v11, lpValueName, 0, 0, Data, &cbData) )
-          {
-            *(int *)Data = v3;
-            RegSetValueExA(v11, lpValueName, 0, 4u, Data, 4u);
-          }
-          RegCloseKey(v11);
-        }
-        RegCloseKey(v10);
-      }
-      RegCloseKey(phkResult);
-    }
-    RegCloseKey(hKey);
-  }
-  return *(int *)Data;
-}
-
-//----- (00464B02) --------------------------------------------------------
-void __fastcall WriteWindowsRegistryString(const char *pKey, const char *pString)
-{
-  size_t v2; // eax@5
-  const char *lpValueName; // [sp+4h] [bp-1Ch]@1
-  const char *Str; // [sp+8h] [bp-18h]@1
-  DWORD dwDisposition; // [sp+Ch] [bp-14h]@2
-  HKEY hKey; // [sp+10h] [bp-10h]@1
-  HKEY phkResult; // [sp+14h] [bp-Ch]@1
-  HKEY v8; // [sp+18h] [bp-8h]@1
-  HKEY v9; // [sp+1Ch] [bp-4h]@1
-
-  Str = pString;
-  lpValueName = pKey;
-  v9 = 0;
-  v8 = 0;
-  hKey = 0;
-  phkResult = 0;
-  if ( !RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE", 0, 0x2001Fu, &hKey) )
-  {
-    if ( !RegCreateKeyExA(hKey, "New World Computing", 0, "", 0, 0xF003Fu, 0, &phkResult, &dwDisposition) )
-    {
-      if ( !RegCreateKeyExA(phkResult, "Might and Magic VII", 0, "", 0, 0xF003Fu, 0, &v8, &dwDisposition) )
-      {
-        if ( !RegCreateKeyExA(v8, "1.0", 0, "", 0, 0xF003Fu, 0, &v9, &dwDisposition) )
-        {
-          v2 = strlen(Str);
-          RegSetValueExA(v9, lpValueName, 0, 1u, (const BYTE *)Str, v2 + 1);
-          RegCloseKey(v9);
-        }
-        RegCloseKey(v8);
-      }
-      RegCloseKey(phkResult);
-    }
-    RegCloseKey(hKey);
-  }
-}
-
-//----- (00464BEF) --------------------------------------------------------
-void __fastcall ReadWindowsRegistryString(const char *pKeyName, char *pOutString, int uBufLen, const char *pDefaultValue)
-{
-  LSTATUS (__stdcall *v4)(HKEY); // esi@1
-  LSTATUS result; // eax@7
-  DWORD Type; // [sp+Ch] [bp-24h]@5
-  LPCSTR lpValueName; // [sp+10h] [bp-20h]@1
-  DWORD cbData; // [sp+14h] [bp-1Ch]@1
-  LPBYTE Dest; // [sp+18h] [bp-18h]@1
-  DWORD dwDisposition; // [sp+1Ch] [bp-14h]@2
-  HKEY phkResult; // [sp+20h] [bp-10h]@1
-  HKEY hKey; // [sp+24h] [bp-Ch]@1
-  HKEY v13; // [sp+28h] [bp-8h]@1
-  HKEY v14; // [sp+2Ch] [bp-4h]@1
-
-  cbData = uBufLen;
-  Dest = (LPBYTE)pOutString;
-  lpValueName = pKeyName;
-  v14 = 0;
-  v13 = 0;
-  hKey = 0;
-  phkResult = 0;
-  v4 = RegCloseKey;
-  if ( RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE", 0, 0x2001Fu, &hKey)
-    || RegCreateKeyExA(hKey, "New World Computing", 0, "", 0, 0xF003Fu, 0, &phkResult, &dwDisposition)
-    || RegCreateKeyExA(phkResult, "Might and Magic VII", 0, "", 0, 0xF003Fu, 0, &v13, &dwDisposition)
-    || RegCreateKeyExA(v13, "1.0", 0, "", 0, 0xF003Fu, 0, &v14, &dwDisposition) )
-  {
-    result = (LSTATUS)strncpy((char *)Dest, pDefaultValue, uBufLen);
-  }
-  else if ( RegQueryValueExA(v14, lpValueName, 0, &Type, Dest, &cbData) )
-  {
-    RegCloseKey(v14);
-    v14 = 0;
-    result = (LSTATUS)strncpy((char *)Dest, pDefaultValue, uBufLen);
-  }
-  else
-  {
-	v4 = RegCloseKey;
-	RegCloseKey(v14);
-	v14 = 0;
-	RegCloseKey(v13);
-	v13 = 0;
-	RegCloseKey(phkResult);
-	phkResult = 0;
-	result = RegCloseKey(hKey);
-	hKey = 0;
-  }
-  if ( v14 )
-    result = v4(v14);
-  if ( v13 )
-    result = v4(v13);
-  if ( hKey )
-    result = v4(hKey);
-  if ( phkResult )
-    result = v4(phkResult);
-}
-
-//----- (00464D32) --------------------------------------------------------
-void __fastcall WriteWindowsRegistryInt(const char *pKey, int val)
-{
-  const char *lpValueName; // [sp+4h] [bp-1Ch]@1
-  BYTE Data[4]; // [sp+8h] [bp-18h]@1
-  DWORD dwDisposition; // [sp+Ch] [bp-14h]@2
-  HKEY hKey; // [sp+10h] [bp-10h]@1
-  HKEY phkResult; // [sp+14h] [bp-Ch]@1
-  HKEY v7; // [sp+18h] [bp-8h]@1
-  HKEY v8; // [sp+1Ch] [bp-4h]@1
-
-  *(int *)Data = val;
-  lpValueName = pKey;
-  v8 = 0;
-  v7 = 0;
-  hKey = 0;
-  phkResult = 0;
-  if ( !RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE", 0, 0x2001Fu, &hKey) )
-  {
-    if ( !RegCreateKeyExA(hKey, "New World Computing", 0, "", 0, 0xF003Fu, 0, &phkResult, &dwDisposition) )
-    {
-      if ( !RegCreateKeyExA(phkResult, "Might and Magic VII", 0, "", 0, 0xF003Fu, 0, &v7, &dwDisposition) )
-      {
-        if ( !RegCreateKeyExA(v7, "1.0", 0, "", 0, 0xF003Fu, 0, &v8, &dwDisposition) )
-        {
-          RegSetValueExA(v8, lpValueName, 0, 4, Data, 4);
-          RegCloseKey(v8);
-        }
-        RegCloseKey(v7);
-      }
-      RegCloseKey(phkResult);
-    }
-    RegCloseKey(hKey);
-  }
-}
 
 //----- (00464E17) --------------------------------------------------------
 bool __fastcall CheckMM7CD(char c)
--- a/mm7_3.cpp	Mon Apr 07 19:15:13 2014 +0600
+++ b/mm7_3.cpp	Mon Apr 07 19:15:31 2014 +0600
@@ -14,6 +14,7 @@
 #include "Outdoor_stuff.h"
 #include "Overlays.h"
 #include "LOD.h"
+#include "Log.h"
 #include "Actor.h"
 #include "Events.h"
 #include "Viewport.h"
@@ -31,6 +32,7 @@
 #include "Level/Decoration.h"
 #include "mm7_unsorted_subs.h"
 #include "mm7_data.h"
+#include "SaveLoad.h"
 
 #include "MM7.h"
 
@@ -2687,8 +2689,8 @@
     (int)&thisa);
   if ( !(dword_6BE364_game_settings_1 & GAME_SETTINGS_2000) )
   {
-    InitializeActors();
-    InitializeSpriteObjects();
+    Actor::InitializeActors();
+    SpriteObject::InitializeSpriteObjects();
   }
   dword_6BE364_game_settings_1 &= ~GAME_SETTINGS_2000;
   //v5 = 0;
--- a/mm7_4.cpp	Mon Apr 07 19:15:13 2014 +0600
+++ b/mm7_4.cpp	Mon Apr 07 19:15:31 2014 +0600
@@ -142,28 +142,6 @@
     array_77EC08[i].field_108 = 0;
 }
 
-//----- (0048A959) --------------------------------------------------------
-signed int ReplaceHSV(unsigned int uColor, float h_replace, float s_replace, float v_replace)
-{
-  float r = ((uColor & 0x00FF0000) >> 16) / 255.0f,
-        g = ((uColor & 0x0000FF00) >> 8) / 255.0f,
-        b = (uColor & 0x000000FF) / 255.0f;
-
-  float h, s, v;
-  RGB2HSV(&h, &s, r, g, b, &v);
-
-  if ( h_replace != -1.0 )
-    h = h_replace;
-  if ( s_replace != -1.0 )
-    s = s_replace;
-  if ( v_replace != -1.0 )
-    v = v_replace;
-  HSV2RGB(&r, &g, &b, h, s, v);
-
-  return (((uint)round_to_int(r * 255.0f) & 0xFF) << 16) |
-         (((uint)round_to_int(g * 255.0f) & 0xFF) << 8) |
-         (((uint)round_to_int(b * 255.0f) & 0xFF));
-}
 
 
 //----- (00491E3A) --------------------------------------------------------
@@ -345,7 +323,7 @@
         a1.vPosition.z = pActors[v14].vPosition.z;
         a1.spell_target_pid = PID(OBJECT_Actor,v14);
         v19 = a1.Create(0, 0, 0, 0);
-        DamageMonsterFromParty(PID(OBJECT_Item,v19), v14, &a3);
+        Actor::DamageMonsterFromParty(PID(OBJECT_Item,v19), v14, &a3);
       }
     }
 
--- a/mm7_5.cpp	Mon Apr 07 19:15:13 2014 +0600
+++ b/mm7_5.cpp	Mon Apr 07 19:15:31 2014 +0600
@@ -182,7 +182,7 @@
                 switch ( attacker_type )
                 {
                   case OBJECT_Player:
-                    DamageMonsterFromParty(AttackerInfo.pIDs[attacker_id], actorID, &AttackerInfo.vec_4B4[attacker_id]);
+                    Actor::DamageMonsterFromParty(AttackerInfo.pIDs[attacker_id], actorID, &AttackerInfo.vec_4B4[attacker_id]);
                     break;
                   case OBJECT_Actor:
                     if ( v36 && pActors[v3].GetActorsRelation(&pActors[actorID]) )
@@ -228,7 +228,7 @@
         Actor::ActorDamageFromMonster(PID(OBJECT_Item, uLayingItemID), PID_ID(a2), &layingitem_vel_50FDFC, pSpriteObjects[uLayingItemID].field_61);
         break;
       case OBJECT_Player:
-        DamageMonsterFromParty(PID(OBJECT_Item, uLayingItemID), PID_ID(a2), &layingitem_vel_50FDFC);
+        Actor::DamageMonsterFromParty(PID(OBJECT_Item, uLayingItemID), PID_ID(a2), &layingitem_vel_50FDFC);
         break;
       case OBJECT_Item:
         ItemDamageFromActor(PID(OBJECT_Item, uLayingItemID), PID_ID(a2), &layingitem_vel_50FDFC);
--- a/mm7_unsorted_subs.h	Mon Apr 07 19:15:13 2014 +0600
+++ b/mm7_unsorted_subs.h	Mon Apr 07 19:15:31 2014 +0600
@@ -13,88 +13,28 @@
 
 //void ShowMM7IntroVideo_and_LoadingScreen();
 unsigned int GameOverMenu(void *ecx0);
-int __fastcall SpawnRandomTreasure(struct MapInfo *a1, struct SpawnPointMM7 *a2);
-void DamageMonsterFromParty(signed int a1, unsigned int uActorID_Monster, struct Vec3_int_ *pVelocity);
 
-void MakeActorAIList_ODM();
-int MakeActorAIList_BLV();
-void UpdateActorAI();
 bool __fastcall sub_4070EF_prolly_detect_player(unsigned int uObjID, unsigned int uObj2ID);
 bool __fastcall sub_4075DB(int a1, int a2, int a3, struct BLVFace *face);
 bool __fastcall sub_4077F1(int a1, int a2, int a3, struct ODMFace *face, struct BSPVertexBuffer *a5);
 bool __fastcall sub_407A1C(int x, int z, int y, struct Vec3_int_ v); // idb
-void InitializeActors();
-void InitializeSpriteObjects();
 int __fastcall sub_4088E9(int a1, int a2, int a3, int a4, int a5, int a6);
-unsigned int SearchAliveActors(unsigned int *pTotalActors);
-unsigned int SearchActorByMonsterID(unsigned int *pTotalActors, int uMonsterID);
-unsigned int SearchActorByGroup(unsigned int *pTotalActors, unsigned int uGroup);
-unsigned int SearchActorByID(unsigned int *pTotalActors, unsigned int a2);
-void PrepareArcomage();
-void DoBlt_Copy(unsigned __int16 *pPixels); // idb
-void __fastcall ZBuffer_Fill(int *pZBuffer, int uTextureId, int iZValue);
-void __fastcall ZBuffer_DoFill(int *pZBuffer, struct Texture *pTex, int uZValue);
-void __fastcall ZBuffer_DoFill2(int *pZBuffer, struct Texture *a2, int a3); // idb
-void SetMoonPhaseNames();
-void __fastcall LoadThumbnailLloydTexture(unsigned int uSlot, unsigned int uPlayer);
-void SetAttributeNames();
-void uGameUIFontMain_initialize();
-void uGameUIFontShadow_initialize();
-void Inventory_ItemPopupAndAlchemy();
-void UI_OnMouseLeftClick(int *pXY); // idb
-unsigned int UI_GetHealthManaAndOtherQualitiesStringColor(signed int current_pos, signed int base_pos);
-unsigned int __fastcall GetSizeInInventorySlots(unsigned int uNumPixels);
-struct GUIButton *__fastcall GUI_HandleHotkey(unsigned __int8 uHotkey); // idb
-int __fastcall GUI_ReplaceHotkey(unsigned __int8 uOldHotkey, unsigned __int8 uNewHotkey, char bFirstCall);
-void DrawBuff_remaining_time_string(int uY, struct GUIWindow *window, __int64 remaining_time, struct GUIFont *Font);
-bool UI_OnKeyDown(unsigned int vkKey);
-void GameUI_DrawItemInfo(struct ItemGen* inspect_item); // idb
-void MonsterPopup_Draw(unsigned int uActorID, struct GUIWindow *window);
-void LoadActualSkyFrame();
-void Sleep6Hours();
-void ChestUI_WritePointedObjectStatusString();
-void OnChestLeftClick();
 void GameUI_WritePointedObjectStatusString();
 void __fastcall GameUI_OnPlayerPortraitLeftClick(unsigned int uPlayerID); // idb
-void OnGameViewportClick();
-bool PauseGameDrawing();
-void SetUserInterface(enum PartyAlignment alignment, bool bReplace);
 void reset_some_strus_flt_2Cs();
-int __fastcall GetPortalScreenCoord(unsigned int uFaceID);
-bool PortalFrustrum(int pNumVertices, struct BspRenderer_PortalViewportData *a2, struct BspRenderer_PortalViewportData *near_portal, int uFaceID);
-int ODM_NearClip(unsigned int uVertexID); // idb
-int ODM_FarClip(unsigned int uNumVertices);
-bool sub_427769_isSpellQuickCastableOnShiftClick(unsigned int uSpellID);
-void _42777D_CastSpell_UseWand_ShootArrow(int a1, unsigned int uPlayerID, unsigned int a4, __int16 a5, int a6);
 void  InitializeTurnBasedAnimations(void *);
-void CompactLayingItemsList();
-void sub_42FBDD();
-void CloseWindowBackground();
-void GameUI_MsgProc();
-void back_to_game();
-void GUI_MainMenuMessageProc();
 double get_shading_dist_mist();
 void area_of_effect__damage_evaluate();
-void __fastcall DamagePlayerFromMonster(unsigned int uObjID, int a2, struct Vec3_int_ *pPos, signed int a4);
 void __fastcall sub_43A97E(unsigned int uLayingItemID, signed int a2); // idb
 double __fastcall sub_43AE12(signed int a1);
 void ItemDamageFromActor(unsigned int uObjID, unsigned int uActorID, struct Vec3_int_ *pVelocity);
 void CharacterUI_LoadPaperdollTextures();
-int GetItemTextureFilename(char *pOut, signed int item_id, int index, int shoulder);
-bool IsDwarfPresentInParty(bool b);
-bool  ShouldLoadTexturesForRaceAndGender(unsigned int _this);
 void WetsuitOn(unsigned int uPlayerID); // idb
 void WetsuitOff(unsigned int uPlayerID);
 void __fastcall PrepareDrawLists_BLV();
 void FindBillboardsLightLevels_BLV();
 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 PrepareDecorationsRenderList_BLV(unsigned int uDecorationID, unsigned int uSectorID);
-void PrepareActorRenderList_BLV();
-void PrepareItemsRenderList_BLV();
-void AddBspNodeToRenderList(unsigned int node_id);
-void __fastcall sub_4406BC(unsigned int node_id, unsigned int uFirstNode); // idb
 bool _44100D_should_alter_right_panel();
 __int16 __fastcall sub_441A4E(int a1);
 void DrawBook_Map_sub(unsigned int tl_x, unsigned int tl_y, unsigned int br_x, int br_y, int _48074); // idb
@@ -104,16 +44,10 @@
 void OnMapLoad();
 void Level_LoadEvtAndStr(const char *pLevelName);
 const char *GetMapBookHintText();//sub_444564
-char *GetEventHintString(unsigned int uEventID); // idb
 int GetTravelTime();
 void __fastcall sub_4451A8_press_any_key(int a1, int a2, int a4);
 unsigned int SkillToMastery(unsigned int skill_value);
 unsigned int __fastcall GetSpellColor(signed int a1);
-void __fastcall LoadGame(unsigned int uSlot); // idb
-void SaveGame(bool IsAutoSAve, bool NotSaveWorld);
-void __fastcall DoSavegame(unsigned int uSlot); // idb
-bool Initialize_GamesLOD_NewLOD();
-void SaveNewGame();
 void PrepareToLoadBLV(unsigned int bLoading);
 void __fastcall PrepareToLoadODM(unsigned int bLoading, struct ODMRenderParams *a2);
 void _461103_load_level_sub();
@@ -126,10 +60,6 @@
 char Is_out15odm_underwater();
 void SetUnderwaterFog();
 void DoPrepareWorld(unsigned int bLoading, int _1_fullscreen_loading_2_box);
-int __fastcall ReadWindowsRegistryInt(const char *pKey, int uDefValue); // idb
-void __fastcall WriteWindowsRegistryString(const char *pKey, const char *pString);
-void __fastcall ReadWindowsRegistryString(const char *pKeyName, char *pOutString, int uBufLen, const char *pDefaultValue);
-void __fastcall WriteWindowsRegistryInt(const char *pKey, int val);
 bool __fastcall CheckMM7CD(char c);
 void SecondaryInitialization();
 void CreateAsyncMouse();
@@ -138,24 +68,13 @@
 void MM7Initialization();
 void SetCurrentMenuID(enum MENU_STATE); // idb
 enum MENU_STATE GetCurrentMenuID();
-void CreateMsgScrollWindow(signed int mscroll_id);
-void free_book_subwindow();
-void CreateScrollWindow();
-void OnPaperdollLeftClick();
-void OnPressSpace();
-char __fastcall DoInteractionWithTopmostZObject(int a1, int a2);
 void OracleDialogue();
-void __fastcall ClickNPCTopic(signed int uMessageParam);
 const char * _4B254D_SkillMasteryTeacher(int trainerInfo);
-const char *ContractSelectText(int pEventCode);
 void SimpleHouseDialog();
 void CreateButtonInColumn(int a1, unsigned int a2);
-void FillAviableSkillsToTeach(int _this);
 void sub_4B3E1E();
 void DrawJoinGuildWindow(int pEventCode);
 void _4B3FE5_training_dialogue(int a4);
-void NPCHireableDialogPrepare();
-void _4B4224_UpdateNPCTopics(int _this);
 void __fastcall DrawTextAtStatusBar(const char *Str, int a5);
 __int64 GetExperienceRequiredForLevel(int a1);
 void CheckBountyRespawnAndAward();
@@ -180,16 +99,10 @@
 int __fastcall GetTerrainHeightsAroundParty2(int a1, int a2, int *a3, int a4);
 void sub_487DA9();
 double GetFogDensityByTime(struct OutdoorLocation *_this);
-bool __fastcall HSV2RGB(float *a1, float *a2, float *a3, float a4, float a5, float a6);
-void __fastcall RGB2HSV(float *a1, float *a2, float a3, float a4, float a5, float *a6);
-signed int ReplaceHSV(unsigned int uColor, float a2, float gamma, float a4);
 bool PlayerCreation_Choose4Skills();
-int PlayerCreation_GetUnspentAttributePointCount();
 void LoadPlayerPortraintsAndVoices();
 void ReloadPlayerPortraits(int player_id, int face_id);
 void sub_491E3A();
-int CycleCharacter(bool backwards);
-void __fastcall Rest(unsigned int uHoursToSleep);
 void _493938_regenerate();
 void init_summoned_item(struct stru351_summoned_item *_this, __int64 duration);
 void _494035_timed_effects__water_walking_damage__etc();
@@ -201,27 +114,13 @@
 void DeleteCCharFont();
 bool PlayerCreationUI_Loop();
 unsigned int __fastcall GetMaxMipLevels(unsigned int uDim);
-struct SoundHeader *FindSound_BinSearch(unsigned int uStart, unsigned int uEnd, const char *pName);
-struct SoundData *LoadSound(const char *pSoundName, struct SoundData *pOutBuff, unsigned int uID);
-int __fastcall sub_4AAEA6_transform(struct RenderVertexSoft *a1);
-int __fastcall sub_4AB66C(int, int); // weak
-int GetSoundStrengthByDistanceFromParty(int x, int y, int z);
-void PlayLevelMusic();
-unsigned int __fastcall sub_4B0E07(unsigned int uFaceID); // idb
 void sub_4B1447_party_fine(int shopId, int stealingResult, int fineToAdd);
 void sub_4B1523_showSpellbookInfo(int spellItemId);
 void ShowPopupShopItem();
-void RestAndHeal(__int64 uNumMinutes); // idb
 void GetHouseGoodbyeSpeech();
 unsigned int GetGravityStrength();
 void UpdateUserInput_and_MapSpecificStuff();
-void BLV_UpdateUserInputAndOther();
-void ODM_UpdateUserInputAndOther();
 bool __fastcall _46BFFA_check_object_intercept(unsigned int uLayingItemID, signed int a2);
-int BLV_GetFloorLevel(int x, int y, int z, unsigned int uSectorID, unsigned int *pFaceID);
-int ODM_GetFloorLevel(int X, signed int Y, int Z, int, int *pOnWater, int *bmodel_pid, int bWaterWalk);
-int GetCeilingHeight(int Party_X, signed int Party_Y, int Party_ZHeight, int pFaceID);
-void ODM_GetTerrainNormalAt(int pos_x, int pos_z, Vec3_int_ *out);
 unsigned int __fastcall sub_46DEF2(signed int a2, unsigned int uLayingItemID);
 void _46E0B2_collide_against_decorations();
 void __fastcall _46E26D_collide_against_sprites(signed int a1, signed int a2);
@@ -231,13 +130,8 @@
 void __fastcall _46ED8A_collide_against_sprite_objects(unsigned int _this);
 int _46EF01_collision_chech_player(int a1); // idb
 int _46F04E_collide_against_portals();
-void BLV_UpdateDoors();
-void UpdateActors_BLV();
-void UpdateActors_ODM();
 void UpdateObjects();
 int collide_against_floor_approximate(int x, int y, int z, unsigned int *pSectorID, unsigned int *pFaceID); // idb
-void BLV_ProcessPartyActions();
-void ODM_ProcessPartyActions();
 bool sub_47531C(int a1, int *a2, int pos_x, int pos_y, int pos_z, int dir_x, int dir_y, int dir_z, struct BLVFace *face, int a10);
 bool sub_4754BF(int a1, int *a2, int X, int Y, int Z, int dir_x, int dir_y, int dir_z, struct BLVFace *face, int a10, int a11);
 int sub_475665(struct BLVFace *face, int a2, __int16 a3);
@@ -245,26 +139,16 @@
 bool __fastcall sub_475D85(Vec3_int_ *a1, Vec3_int_ *a2, int *a3, struct BLVFace *a4);
 bool __fastcall sub_475F30(int *a1, struct BLVFace *a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9);
 void sub_4452BB();
-const char *GetProfessionActionText(int a1);
-struct NPCData *__fastcall GetNPCData(signed int npcid);
-struct NPCData * GetNewNPCData(signed int npcid, int* npc_indx);
-int __fastcall GetGreetType(signed int SpeakingNPC_ID);
 void  DialogueEnding();
 void PrepareHouse(enum HOUSE_ID house); // idb
 bool EnterHouse(enum HOUSE_ID uHouseID);
 bool sub_4465DF_check_season(int a1);
-int __fastcall IsActorAlive(unsigned int uType, unsigned int uParam, unsigned int uNumAlive); // idb
-int NPC_EventProcessor(int npc_event_id, int entry_line = 0);
-void __fastcall sub_448518_npc_set_item(int npc, unsigned int item, int a3);
 void __fastcall sub_44861E_set_texture(unsigned int uFaceCog, const char *pFilename);
 void __fastcall SetDecorationSprite(uint16_t uCog, bool bHide, const char *pFileName); // idb
 void __fastcall sub_44892E_set_faces_bit(int sCogNumber, int bit, int on);
-void __fastcall ToggleActorGroupFlag(unsigned int uGroupID, unsigned int uFlag, unsigned int bToggle);
 void  GameUI_StatusBar_UpdateTimedString(unsigned int bForceHide); // idb
 void OnTimer(int);
 void __fastcall sub_448CF4_spawn_monsters(__int16 typeindex, __int16 level, int count, int x, int y, int z, int group, unsigned int uUniqueName);
-void __fastcall EventCastSpell(int uSpellID, int uSkillLevel, int uSkill, int fromx, int fromy, int fromz, int tox, int toy, int toz);//sub_448DF8
-void Door_switch_animation(unsigned int uDoorID, int a2); // idb: sub_449A49
 bool _449B57_test_bit(unsigned __int8 *a1, __int16 a2);
 void _449B7E_toggle_bit(unsigned char *pArray, __int16 a2, unsigned __int16 bToggle); // idb
 void ShowStatusBarString(const char *pString, unsigned int uNumSeconds);
@@ -278,9 +162,6 @@
 void RespawnGlobalDecorations();
 bool __fastcall SpawnActor(unsigned int uMonsterID);
 int GetAlertStatus();
-int integer_sqrt(int val);
-int __fastcall GetDiceResult(unsigned int uNumDice, unsigned int uDiceSides); // idb
-inline int round_to_int(float x) { return (int)floor(x + 0.5f); }
 inline void __fastcall memset32(void *ptr, unsigned __int32 value, int count)
 {
   unsigned __int32* p = (unsigned __int32 *)ptr;
--- a/texts.h	Mon Apr 07 19:15:13 2014 +0600
+++ b/texts.h	Mon Apr 07 19:15:31 2014 +0600
@@ -9,6 +9,8 @@
 void  SetSomeItemsNames();
 char *RemoveQuotes(char *Str);
 void  InitializeGameText();
+void SetMoonPhaseNames();
+void SetAttributeNames();
 
 struct ci_less : std::binary_function<std::string, std::string, bool>   //case insensitive comparator for dictionaries
 {