changeset 826:1133e34a7560

Слияние
author Ritor1
date Tue, 26 Mar 2013 23:19:12 +0600
parents 35c31a49d989 (current diff) fe4c8b113548 (diff)
children 085eb19b7ffd
files mm7_3.cpp
diffstat 38 files changed, 2173 insertions(+), 2670 deletions(-) [+]
line wrap: on
line diff
--- a/Actor.cpp	Tue Mar 26 23:18:58 2013 +0600
+++ b/Actor.cpp	Tue Mar 26 23:19:12 2013 +0600
@@ -594,15 +594,15 @@
               }
               a1.uObjectDescID = v11;
               a1.stru_24.Reset();
-              a1.field_48 = 15;
+              a1.spell_id = SPELL_AIR_SPARKS;
               v13 = v5->vPosition.x;
               v14 = v5->vPosition.y;
-              a1.field_4C = uSkillLevel;
+              a1.spell_level = uSkillLevel;
               a1.vPosition.x = v13;
               v15 = v5->vPosition.z + ((signed int)v5->uActorHeight >> 1);
               v16 = v117;
               v17 = LOWORD(v117->uYawAngle);
-              a1.field_50 = 0;
+              a1.spell_skill = 0;
               a1.vPosition.y = v14;
               a1.vPosition.z = v15;
               a1.uFacing = v17;
@@ -611,9 +611,9 @@
               a1.uSectorID = pIndoor->GetSector(v13, v14, v15);
               v18 = 8 * LODWORD(v120);
               LOBYTE(v18) = 8 * LOBYTE(v120) | AI_OBJECT_ACTOR;
-              a1.field_58_pid = v18;
+              a1.spell_caster_pid = v18;
               a1.uSpriteFrameID = 0;
-              a1.field_5C = 0;
+              a1.spell_target_pid = 0;
               a1.field_60_distance_related_prolly_lod = 3;
               v19 = spellnuma / -2;
               a1a = spellnuma / 2;
@@ -675,15 +675,15 @@
             }
             a1.uObjectDescID = v82;
             a1.stru_24.Reset();
-            a1.field_48 = spellnum;
+            a1.spell_id = spellnum;
             v83 = v5->vPosition.x;
             v84 = v5->vPosition.y;
-            a1.field_4C = uSkillLevel;
+            a1.spell_level = uSkillLevel;
             a1.vPosition.x = v83;
             v85 = v5->vPosition.z + ((signed int)v5->uActorHeight >> 1);
             v86 = v117;
             v87 = LOWORD(v117->uYawAngle);
-            a1.field_50 = 0;
+            a1.spell_skill = 0;
             a1.vPosition.y = v84;
             a1.vPosition.z = v85;
             a1.uFacing = v87;
@@ -696,8 +696,8 @@
             v90 = 8 * LODWORD(v120);
             LOBYTE(v90) = 8 * LOBYTE(v120) | OBJECT_Actor;
             a1.uSpriteFrameID = 0;
-            a1.field_58_pid = v90;
-            a1.field_5C = 0;
+            a1.spell_caster_pid = v90;
+            a1.spell_target_pid = 0;
             a1.field_60_distance_related_prolly_lod = 3;
             if ( (double)v89 >= 307.2 )
             {
@@ -822,17 +822,17 @@
                 v34 = spellnumd;
               }
               a1.uObjectDescID = v34;
-              a1.field_4C = uSkillLevel;
+              a1.spell_level = uSkillLevel;
               a1.vPosition.x = v111;
               a1.vPosition.y = v113;
               a1.vPosition.z = v30 + v114;
-              a1.field_48 = 9;
-              a1.field_50 = 0;
+              a1.spell_id = SPELL_FIRE_METEOR_SHOWER;
+              a1.spell_skill = 0;
               a1.uAttributes = 0;
               a1.uSectorID = 0;
               a1.uSpriteFrameID = 0;
-              a1.field_58_pid = v116;
-              a1.field_5C = 0;
+              a1.spell_caster_pid = v116;
+              a1.spell_target_pid = 0;
               a1.field_60_distance_related_prolly_lod = stru_50C198._427546(v30 + 2500);
               a1.uFacing = v32;
               a1.uSoundID = 0;
@@ -1367,15 +1367,15 @@
   }
   a1.uObjectDescID = v71;
   a1.stru_24.Reset();
-  a1.field_48 = 93;
+  a1.spell_id = SPELL_DARK_SHARPMETAL;
   v73 = v5->vPosition.x;
   v74 = v5->vPosition.y;
-  a1.field_4C = uSkillLevel;
+  a1.spell_level = uSkillLevel;
   a1.vPosition.x = v73;
   v75 = v5->vPosition.z + ((signed int)v5->uActorHeight >> 1);
   v76 = v117;
   v77 = LOWORD(v117->uYawAngle);
-  a1.field_50 = 0;
+  a1.spell_skill = 0;
   a1.vPosition.y = v74;
   a1.vPosition.z = v75;
   a1.uFacing = v77;
@@ -1384,9 +1384,9 @@
   a1.uSectorID = pIndoor->GetSector(v73, v74, v75);
   v78 = 8 * LODWORD(v120);
   LOBYTE(v78) = 8 * LOBYTE(v120) | OBJECT_Actor;
-  a1.field_58_pid = v78;
+  a1.spell_caster_pid = v78;
   a1.uSpriteFrameID = 0;
-  a1.field_5C = 0;
+  a1.spell_target_pid = 0;
   a1.field_60_distance_related_prolly_lod = 3;
   a1c = spellnume / -2;
   if ( spellnume / -2 > spellnume / 2 )
@@ -1567,11 +1567,11 @@
   a1.uObjectDescID = v8;
   a1.stru_24.Reset();
   a1.vPosition.x = v5->vPosition.x;
-  a1.field_48 = 0;
+  a1.spell_id = 0;
   a1.vPosition.y = v5->vPosition.y;
-  a1.field_4C = 0;
+  a1.spell_level = 0;
   v17 = v5->uActorHeight;
-  a1.field_50 = 0;
+  a1.spell_skill = 0;
   v9 = LOWORD(v4->uYawAngle);
   a1.vPosition.z = v5->vPosition.z - (unsigned int)(signed __int64)((double)v17 * -0.75);
   a1.uFacing = v9;
@@ -1583,8 +1583,8 @@
   v12 = 8 * v15;
   LOBYTE(v12) = 8 * v15 | AI_OBJECT_ACTOR;
   a1.uSpriteFrameID = 0;
-  a1.field_58_pid = v12;
-  a1.field_5C = 0;
+  a1.spell_caster_pid = v12;
+  a1.spell_target_pid = 0;
   if ( (double)v11 >= 307.2 )
   {
     if ( v11 >= 1024 )
@@ -1674,11 +1674,11 @@
   a1.uObjectDescID = v4;
   a1.stru_24.Reset();
   a1.vPosition.y = v1->vPosition.y;
-  a1.field_48 = 0;
+  a1.spell_id = 0;
   v5 = v1->vPosition.x;
   v11 = v1->uActorHeight;
-  a1.field_4C = 0;
-  a1.field_50 = 0;
+  a1.spell_level = 0;
+  a1.spell_skill = 0;
   a1.vPosition.x = v5;
   v6 = v1->vPosition.z - (unsigned int)(signed __int64)((double)v11 * -0.75);
   a1.uFacing = 0;
@@ -1689,8 +1689,8 @@
   v7 = 8 * v10;
   LOBYTE(v7) = 8 * v10 | OBJECT_Actor;
   a1.uSpriteFrameID = 0;
-  a1.field_58_pid = v7;
-  a1.field_5C = 0;
+  a1.spell_caster_pid = v7;
+  a1.spell_target_pid = 0;
   a1.field_60_distance_related_prolly_lod = 3;
   a1.field_61 = 4;
   return a1.Create(0, 0, 0, 0);
--- a/Chest.cpp	Tue Mar 26 23:18:58 2013 +0600
+++ b/Chest.cpp	Tue Mar 26 23:19:12 2013 +0600
@@ -37,7 +37,7 @@
 
 //----- (0042041E) --------------------------------------------------------
 bool Chest::Open( signed int uChestID )
-    {
+{
   //char *v1; // edi@5
   unsigned int v2; // eax@8
   GUIWindow *v3; // eax@15
@@ -180,9 +180,9 @@
     a1.stru_24.Reset();
     v24 = *(short *)v23;
     v25 = 0;
-    a1.field_50 = 0;
-    a1.field_4C = 0;
-    a1.field_48 = 0;
+    a1.spell_skill = 0;
+    a1.spell_level = 0;
+    a1.spell_id = 0;
     a1.field_54 = 0;
     a1.uType = v24;
     if ( (signed int)pObjectList->uNumObjects <= 0 )
@@ -210,8 +210,8 @@
     a1.uAttributes = 48;
     a1.uSectorID = pIndoor->GetSector(pOut.x, pOut.z, pOut.y);
     a1.uSpriteFrameID = 0;
-    a1.field_58_pid = 0;
-    a1.field_5C = 0;
+    a1.spell_caster_pid = 0;
+    a1.spell_target_pid = 0;
     a1.uFacing = 0;
     a1.Create(0, 0, 0, 0);
     pAudioPlayer->PlaySound(SOUND_8, 0, 0, -1, 0, 0, 0, 0);
--- a/GUIWindow.h	Tue Mar 26 23:18:58 2013 +0600
+++ b/GUIWindow.h	Tue Mar 26 23:19:12 2013 +0600
@@ -1,5 +1,7 @@
 #pragma once
 #include "GUIButton.h"
+#include "Items.h"
+#include "Player.h"
 
 
 
@@ -417,4 +419,20 @@
 
 
 
-void QuickRefDraw();
\ No newline at end of file
+void QuickRefDraw();
+
+
+
+
+
+
+
+
+
+
+//character ui
+unsigned int __fastcall GetSkillColor(unsigned int uPlayerClass, PLAYER_SKILL_TYPE uPlayerSkillType, signed int skill_level);
+const char *__fastcall CharacterUI_GetSkillDescText(unsigned int uPlayerID, PLAYER_SKILL_TYPE uPlayerSkillType);
+char __cdecl CharacterUI_SkillsTab_ShowHint();
+char __cdecl CharacterUI_StatsTab_ShowHint();
+char __fastcall CharacterUI_StatsTab_Draw(unsigned int uPlayerID); // idb
\ No newline at end of file
--- a/Game.cpp	Tue Mar 26 23:18:58 2013 +0600
+++ b/Game.cpp	Tue Mar 26 23:19:12 2013 +0600
@@ -355,8 +355,16 @@
         pMouse->_469EA4();
         pRenderer->EndScene();
       }
+
+      static int gtc_old = GetTickCount();
+      int gtc = GetTickCount();
+      auto evt_old = pEventTimer->uStartTime,
+           msc_old = pMiscTimer->uStartTime;
       pEventTimer->Update();
       pMiscTimer->Update();
+      Log::Warning(L"Evt/Msc/GTC dt: %u/%u/%u", pEventTimer->uTimeElapsed, pMiscTimer->uTimeElapsed, gtc - gtc_old);
+      gtc_old = gtc;
+
       OnTimer(0);
       GameUI_StatusBar_UpdateTimedString(0);
       if ( pMiscTimer->bPaused && !pEventTimer->bPaused )
--- a/Indoor.h	Tue Mar 26 23:18:58 2013 +0600
+++ b/Indoor.h	Tue Mar 26 23:19:12 2013 +0600
@@ -1,7 +1,7 @@
 #pragma once
 #include "VectorTypes.h"
 #include "IndoorCameraD3D.h"
-
+#include "Weather.h"
 
 
 
@@ -402,13 +402,7 @@
 
 
 
-#pragma pack(push, 1)
-struct IndoorLocation_stru1
-{
-  unsigned __int64 uLastVisitDay;
-  char field_2F4[48];
-};
-#pragma pack(pop)
+
 
 
 
@@ -475,7 +469,7 @@
   unsigned int uNumSpawnPoints;
   struct SpawnPointMM7 *pSpawnPoints;
   struct DDM_DLV_Header dlv;
-  IndoorLocation_stru1 stru1;
+  LocationTime_stru1 stru1;
   char _visible_outlines[876];
 };
 #pragma pack(pop)
--- a/Items.cpp	Tue Mar 26 23:18:58 2013 +0600
+++ b/Items.cpp	Tue Mar 26 23:19:12 2013 +0600
@@ -547,17 +547,17 @@
 					{
 					if ( !_strcmpi(test_string, "weapon") )
 						{
-						pItems[item_counter].uEquipType = EQUIP_ONE_OR_TWO_HANDS;
+						pItems[item_counter].uEquipType = EQUIP_OFF_HAND;
 						break;
 						}
 					if ( !_strcmpi(test_string, "weapon2") )
 						{
-						pItems[item_counter].uEquipType = EQUIP_TWO_HANDED;
+						pItems[item_counter].uEquipType = EQUIP_MAIN_HAND;
 						break;
 						}
 					if ( !_strcmpi(test_string, "weapon1or2") )
 						{
-						pItems[item_counter].uEquipType = EQUIP_ONE_OR_TWO_HANDS;
+						pItems[item_counter].uEquipType = EQUIP_OFF_HAND;
 						break;
 						}
 					if ( !(_strcmpi(test_string, "missile")&&_strcmpi(test_string, "bow")))
@@ -1609,7 +1609,7 @@
         PLAYER_SKILL_TYPE requested_skill = PLAYER_SKILL_INVALID;
         switch (uTreasureType)
             {
-        case 20: requested_equip = EQUIP_ONE_OR_TWO_HANDS; break;
+        case 20: requested_equip = EQUIP_OFF_HAND; break;
         case 21: requested_equip = EQUIP_ARMOUR; break;
         case 22: requested_skill = PLAYER_SKILL_MISC; break;
         case 23: requested_skill = PLAYER_SKILL_SWORD; break;
@@ -1760,8 +1760,8 @@
     //try get special enhansment
     switch (pItems[out_item->uItemID].uEquipType)
         {
-    case EQUIP_ONE_OR_TWO_HANDS:
-    case EQUIP_TWO_HANDED :   
+    case EQUIP_OFF_HAND:
+    case EQUIP_MAIN_HAND :   
     case EQUIP_BOW :    
         if ( !uBonusChanceWpSpecial[v6] )
             return;
--- a/Items.h	Tue Mar 26 23:18:58 2013 +0600
+++ b/Items.h	Tue Mar 26 23:19:12 2013 +0600
@@ -4,7 +4,6 @@
 
 
 
-
 /*  338 */
 enum ITEM_FLAGS :unsigned int
 {
@@ -34,8 +33,8 @@
   ITEM_CROSSBOW_1 = 0x2F,
   ITEM_MACE_1 = 0x32,
   ITEM_STAFF_1 = 0x3D,
-  ITEM_BLASTER = 65,
-  ITEM_LASER_RIFLE = 66,
+  ITEM_BLASTER = 64,
+  ITEM_LASER_RIFLE = 65,
   ITEM_LEATHER_1 = 0x42,
   ITEM_CHAINMAIL_1 = 0x47,
   ITEM_PLATE_1 = 0x4C,
@@ -87,29 +86,29 @@
 };
 
 /*  331 */
-enum ITEM_EQUIP_TYPE
+enum ITEM_EQUIP_TYPE: unsigned __int8
 {
-  EQUIP_ONE_OR_TWO_HANDS = 0,
-  EQUIP_TWO_HANDED       = 1,
-  EQUIP_BOW              = 2,
-  EQUIP_ARMOUR           = 3,
-  EQUIP_SHIELD           = 4,
-  EQUIP_HELMET           = 5,
-  EQUIP_BELT             = 6,
-  EQUIP_CLOAK            = 7,
-  EQUIP_GAUNTLETS        = 8,
-  EQUIP_BOOTS            = 9,
-  EQUIP_RING             = 10,
-  EQUIP_AMULET           = 11,
-  EQUIP_WAND             = 12,
-  EQUIP_REAGENT          = 13,
-  EQUIP_POTION           = 14,
-  EQUIP_SPELL_SCROLL     = 15,
-  EQUIP_BOOK             = 16,
-  EQUIP_MESSAGE_SCROLL   = 17,
-  EQUIP_GOLD             = 18,
-  EQUIP_GEM              = 19,
-  EQUIP_NONE             = 20
+  EQUIP_OFF_HAND     = 0,
+  EQUIP_MAIN_HAND     = 1,
+  EQUIP_BOW            = 2,
+  EQUIP_ARMOUR         = 3,
+  EQUIP_SHIELD         = 4,
+  EQUIP_HELMET         = 5,
+  EQUIP_BELT           = 6,
+  EQUIP_CLOAK          = 7,
+  EQUIP_GAUNTLETS      = 8,
+  EQUIP_BOOTS          = 9,
+  EQUIP_RING           = 10,
+  EQUIP_AMULET         = 11,
+  EQUIP_WAND           = 12,
+  EQUIP_REAGENT        = 13,
+  EQUIP_POTION         = 14,
+  EQUIP_SPELL_SCROLL   = 15,
+  EQUIP_BOOK           = 16,
+  EQUIP_MESSAGE_SCROLL = 17,
+  EQUIP_GOLD           = 18,
+  EQUIP_GEM            = 19,
+  EQUIP_NONE           = 20
 };
 
 
@@ -143,7 +142,21 @@
   int uItemID;
   int uEnchantmentType;
   int _bonus_strength;
-  int uSpecEnchantmentType; // 25: +5 levels
+  int uSpecEnchantmentType; // 25  +5 levels
+                            // 16  Drain Hit Points from target.
+                            // 39  Double damage vs Demons.
+                            // 40  Double damage vs Dragons
+                            // 45  +5 Speed and Accuracy
+                            // 56  +5 Might and Endurance.
+                            // 57  +5 Intellect and Personality.
+                            // 58  Increased Value.
+                            // 60  +3 Unarmed and Dodging skills
+                            // 61  +3 Stealing and Disarm skills.
+                            // 59  Increased Weapon speed.
+                            // 63  Double Damage vs. Elves.
+                            // 64  Double Damage vs. Undead.
+                            // 67  Adds 5 points of Body damage and +2 Disarm skill.
+                            // 68  Adds 6-8 points of Cold damage and +5 Armor Class.
   int uNumCharges;
   unsigned int uAttributes;
   unsigned __int8 uBodyAnchor;
@@ -170,7 +183,7 @@
 	__int16 field_1A; //16 
 	signed __int16 uEquipX; //18  1c
 	signed __int16 uEquipY; //1a  1e
-	unsigned __int8 uEquipType; //1c 20
+	ITEM_EQUIP_TYPE uEquipType; //1c 20
 	unsigned __int8 uSkillType; //1d 21
 	unsigned __int8 uDamageDice; //1e 22
 	unsigned __int8 uDamageRoll; //1f 23
--- a/LOD.h	Tue Mar 26 23:18:58 2013 +0600
+++ b/LOD.h	Tue Mar 26 23:19:12 2013 +0600
@@ -14,9 +14,6 @@
   TEXTURE_16BIT_PALETTE = 0x2,
 };
 
-
-
-
 namespace LOD
 {
   #pragma pack(push, 1)
--- a/MM7.h	Tue Mar 26 23:18:58 2013 +0600
+++ b/MM7.h	Tue Mar 26 23:19:12 2013 +0600
@@ -21,6 +21,8 @@
 #define BYTE2(a) (*((unsigned char *)&a + 2))
 #define BYTE3(a) (*((unsigned char *)&a + 3))
 
+#define PID(type, id) (unsigned int)((((8 * (id))) | (type)) & 0xFFFF)  // packed id
+
 
 typedef unsigned __int16 _WORD;
 typedef unsigned __int64 _QWORD;
--- a/Outdoor.cpp	Tue Mar 26 23:18:58 2013 +0600
+++ b/Outdoor.cpp	Tue Mar 26 23:19:12 2013 +0600
@@ -316,9 +316,9 @@
       MessageBoxA(0, "Error!", "Couldn't Load Map!", 0);
       CreateDebugLocation();
     }
-    ::day_attrib = v5->day_attrib;
-    ::day_fogrange_1 = v5->day_fogrange_1;
-    ::day_fogrange_2 = v5->day_fogrange_2;
+    ::day_attrib = v5->loc_time.day_attrib;
+    ::day_fogrange_1 = v5->loc_time.day_fogrange_1;
+    ::day_fogrange_2 = v5->loc_time.day_fogrange_2;
     if ( Is_out15odm_underwater() )
       SetUnderwaterFog();
     _6BE134_odm_main_tile_group = v5->pTileTypes[0].tileset;
@@ -679,9 +679,9 @@
 
   if ( Is_out15odm_underwater() )
     SetUnderwaterFog();
-  pOutdoor->day_fogrange_1 = ::day_fogrange_1;
-  pOutdoor->day_fogrange_2 = ::day_fogrange_2;
-  pOutdoor->day_attrib = ::day_attrib;
+  pOutdoor->loc_time.day_fogrange_1 = ::day_fogrange_1;
+  pOutdoor->loc_time.day_fogrange_2 = ::day_fogrange_2;
+  pOutdoor->loc_time.day_attrib = ::day_attrib;
 }
 
 //----- (00482170) --------------------------------------------------------
@@ -2324,7 +2324,7 @@
   pSrc += 0xC8;
 
   pGameLoadingUI_ProgressBar->Progress();
-  memcpy(&uLastVisitDay, pSrc, 0x38u);
+  memcpy(&loc_time, pSrc, 0x38u);
 
   free(pSrcMem);
 
@@ -2353,23 +2353,23 @@
   //v100 = HIDWORD(uLastVisitDay);
   //LODWORD(v142) = LODWORD(uLastVisitDay);
   //HIDWORD(v142) = v100;
-  if (uLastVisitDay)
+  if (loc_time.uLastVisitDay)
   {
-    if ( (signed int)((signed int)(signed __int64)((double)uLastVisitDay * 0.234375) / 60 / 60 / 24) % 28 != pParty->uDaysPlayed )
+    if ( (signed int)((signed int)(signed __int64)((double)loc_time.uLastVisitDay * 0.234375) / 60 / 60 / 24) % 28 != pParty->uDaysPlayed )
     {
       if ( rand() % 100 >= 20 )
         v108 = dword_4EC268[rand() % dword_4EC2A8];
       else
         v108 = dword_4EC28C[rand() % dword_4EC2AC];
-      sprintf(sky_texture_name, "plansky%d", v108);
+      sprintf(loc_time.sky_texture_name, "plansky%d", v108);
     }
   }
   else
   {
-    strcpy(sky_texture_name, "plansky3");
+    strcpy(loc_time.sky_texture_name, "plansky3");
   }
   //v101 = pBitmaps_LOD->LoadTexture(field_4F8);
-  uSky_TextureID = pBitmaps_LOD->LoadTexture(sky_texture_name);
+  uSky_TextureID = pBitmaps_LOD->LoadTexture(loc_time.sky_texture_name);
   if (uSky_TextureID != -1)
     pBitmaps_LOD->pTextures[uSky_TextureID].palette_id2 = pPaletteManager->LoadPalette(pBitmaps_LOD->pTextures[uSky_TextureID].palette_id1);
 
@@ -2504,41 +2504,29 @@
 //----- (0047ED83) --------------------------------------------------------
 int OutdoorLocation::_47ED83(signed int a2, signed int a3)
 {
-  int result; // eax@5
+  assert(a2 < 128 && a3 < 128);
 
-  if ( a2 < 0 || a2 > 127 || a3 < 0 || a3 > 127 )
-    result = 0;
-  else
-    result = *(&this->pTerrain.pTilemap[128 * a3] + a2);
-  return result;
+  return *(&this->pTerrain.pTilemap[128 * a3] + a2);
 }
 
 //----- (0047EDB3) --------------------------------------------------------
 int OutdoorLocation::ActuallyGetSomeOtherTileInfo(unsigned int uX, unsigned int uY)
 {
+  assert(uX < 128 && uY < 128);
   int v3; // esi@5
 
-  if (uX < 0 || uX > 127 || uY < 0 || uY > 127)
-    return 0;
-  else
-  {
-    v3 = this->pTerrain.pTilemap[uY * 128 + uX];
-    if ( v3 >= 90 )
-      v3 = v3 + this->pTileTypes[(v3 - 90) / 36].uTileID - 36 * ((v3 - 90) / 36) - 90;
+  v3 = this->pTerrain.pTilemap[uY * 128 + uX];
+  if ( v3 >= 90 )
+    v3 = v3 + this->pTileTypes[(v3 - 90) / 36].uTileID - 36 * ((v3 - 90) / 36) - 90;
   return pTileTable->pTiles[v3].uAttributes;
-  }
 }
 
 //----- (0047EE16) --------------------------------------------------------
 int OutdoorLocation::DoGetHeightOnTerrain(unsigned int uX, unsigned int uZ)
 {
-  int result; // eax@5
+  assert(uX < 128 && uZ < 128);
 
-  if ( (signed int)uX < 0 || (signed int)uX > 127 || (signed int)uZ < 0 || (signed int)uZ > 127 )
-    result = 0;
-  else
-    result = 32 * *(&this->pTerrain.pHeightmap[uZ * 128 + uX]);
-  return result;
+  return 32 * pTerrain.pHeightmap[uZ * 128 + uX];
 }
 
 //----- (0047EE49) --------------------------------------------------------
--- a/Outdoor.h	Tue Mar 26 23:18:58 2013 +0600
+++ b/Outdoor.h	Tue Mar 26 23:19:12 2013 +0600
@@ -4,7 +4,7 @@
 #include "Indoor.h"
 #include "TileFrameTable.h"
 #include "MapInfo.h"
-
+#include "Weather.h"
 
 
 #define DAY_ATTRIB_FOG  1
@@ -210,12 +210,13 @@
   unsigned int uNumSpawnPoints;
   struct SpawnPointMM7 *pSpawnPoints;
   struct DDM_DLV_Header ddm;
-  unsigned __int64 uLastVisitDay;
-  char sky_texture_name[12];
-  int day_attrib;
-  int day_fogrange_1;
-  int day_fogrange_2;
-  char field_510[24];
+  LocationTime_stru1 loc_time;
+  //unsigned __int64 uLastVisitDay;
+  //char sky_texture_name[12];
+  //int day_attrib;
+  //int day_fogrange_1;
+  //int day_fogrange_2;
+ // char field_510[24];
   unsigned char uUndiscoveredArea[88][11];//968
   unsigned char uDicovered_area[88][11];//[968]
   int field_CB8;
--- a/Party.h	Tue Mar 26 23:18:58 2013 +0600
+++ b/Party.h	Tue Mar 26 23:19:12 2013 +0600
@@ -30,6 +30,7 @@
   PARTY_FLAGS_1_ALERT_YELLOW = 0x0020,
   PARTY_FLAGS_1_STANDING_ON_WATER = 0x0080,
   PARTY_FLAGS_1_LANDING = 0x0100,
+  PARTY_FLAGS_1_BURNING = 0x200
 };
 enum PARTY_FLAGS_2: __int32
 {
--- a/Player.cpp	Tue Mar 26 23:18:58 2013 +0600
+++ b/Player.cpp	Tue Mar 26 23:19:12 2013 +0600
@@ -7,6 +7,7 @@
 #include "AudioPlayer.h"
 #include "Party.h"
 #include "GUIButton.h"
+#include "Log.h"
 #include "LOD.h"
 #include "Monsters.h" 
 #include "GUIWindow.h"
@@ -22,6 +23,7 @@
 #include "Autonotes.h"
 #include "Awards.h"
 #include "texts.h"
+
 #include "mm7_data.h"
 
 
@@ -111,6 +113,23 @@
 
 
 
+unsigned short base_recovery_times_per_weapon_type[12] =
+{
+  100,  // PLAYER_SKILL_STAFF   && Unarmed withoud skill
+   90,  // PLAYER_SKILL_SWORD   && Unarmed with skill
+   60,  // PLAYER_SKILL_DAGGER
+  100,  // PLAYER_SKILL_AXE
+   80,  // PLAYER_SKILL_SPEAR
+  100,  // PLAYER_SKILL_BOW
+   80,  // PLAYER_SKILL_MACE
+   30,  // PLAYER_SKILL_BLASTER
+   10,  // PLAYER_SKILL_SHIELD
+   10,  // PLAYER_SKILL_LEATHER
+   20,  // PLAYER_SKILL_CHAIN
+   30   // PLAYER_SKILL_PLATE
+};
+
+
 
 //----- (00490913) --------------------------------------------------------
 signed int __cdecl PlayerCreation_ComputeAttributeBonus()
@@ -2763,7 +2782,7 @@
     v34 = v4;
     goto LABEL_62;
   }
-  if ( HasItemEquipped(EQUIP_TWO_HANDED) )
+  if ( HasItemEquipped(EQUIP_MAIN_HAND) )
   {
     v6 = (ItemGen *)&v5->pInventoryItems[v5->pEquipment.uMainHand-1];
     v7 = v6->uItemID;
@@ -3327,23 +3346,22 @@
 }
 
 //----- (0048D62C) --------------------------------------------------------
-int Player::GetEquippedItemEquipType(unsigned int uEquipSlot)
-{
-  return pItemsTable->pItems[pInventoryItems[pEquipment.pIndices[uEquipSlot]-1].uItemID].uEquipType;
+ITEM_EQUIP_TYPE Player::GetEquippedItemEquipType(ITEM_EQUIP_TYPE uEquipSlot)
+{
+  return pItemsTable->pItems[pInventoryItems[pEquipment.pIndices[uEquipSlot] - 1].uItemID].uEquipType;
 }
 
 //----- (0048D651) --------------------------------------------------------
-int Player::GetEquippedItemSkillType(enum ITEM_EQUIP_TYPE uEquipSlot)
-{
-  return pItemsTable->pItems[pInventoryItems[pEquipment.pIndices[uEquipSlot] - 1].uItemID].uSkillType;
+PLAYER_SKILL_TYPE Player::GetEquippedItemSkillType(ITEM_EQUIP_TYPE uEquipSlot)
+{
+  return (PLAYER_SKILL_TYPE)pItemsTable->pItems[pInventoryItems[pEquipment.pIndices[uEquipSlot] - 1].uItemID].uSkillType;
 }
 
 //----- (0048D676) --------------------------------------------------------
 bool Player::IsUnarmed()
 {
-  return HasItemEquipped(EQUIP_TWO_HANDED) != 1
-      && (HasItemEquipped(EQUIP_ONE_OR_TWO_HANDS) != 1
-       || GetEquippedItemEquipType(0) == EQUIP_SHIELD);
+  return HasItemEquipped(EQUIP_MAIN_HAND) != EQUIP_MAIN_HAND &&
+        !(HasItemEquipped(EQUIP_OFF_HAND) == EQUIP_MAIN_HAND && GetEquippedItemEquipType(EQUIP_OFF_HAND) != EQUIP_SHIELD);
 }
 
 //----- (0048D6AA) --------------------------------------------------------
@@ -3797,9 +3815,9 @@
       {
         if ( HasItemEquipped((ITEM_EQUIP_TYPE)v14) )
         {
-          if ( v15 == 3 )
+          if ( v15 == EQUIP_ARMOUR )
             v46[v4++] = LOBYTE(v5->pEquipment.uBody) - 1;
-          if ( (!v15 || v15 == 1) && GetEquippedItemEquipType(v15) == 4 )
+          if ( (!v15 || v15 == 1) && GetEquippedItemEquipType((ITEM_EQUIP_TYPE)v15) == 4 )
             v46[v4++] = *((char *)&v5->pEquipment.uOffHand + 4 * v15) - 1;
         }
         v14 = v15 + 1;
@@ -3815,7 +3833,7 @@
           if ( v17 == 2 )
             v46[v4++] = LOBYTE(v5->pEquipment.uBow) - 1;
           if ( (!v17 || v17 == 1)
-            && (!GetEquippedItemEquipType(v17) || GetEquippedItemEquipType(v17) == 1) )
+            && (!GetEquippedItemEquipType((ITEM_EQUIP_TYPE)v17) || GetEquippedItemEquipType((ITEM_EQUIP_TYPE)v17) == 1) )
             v46[v4++] = *((char *)&v5->pEquipment.uOffHand + 4 * v17) - 1;
         }
         v16 = v17 + 1;
@@ -4052,211 +4070,160 @@
 }
 
 //----- (0048E1B5) --------------------------------------------------------
-int Player::GetAttackRecoveryTime(int a2)
-{
-  unsigned int v2; // ebx@1
-  char *v3; // edi@1
-  Player *v4; // esi@1
-  int v5; // eax@3
-  int v6; // eax@3
-  int v7; // eax@6
-  int v8; // eax@9
-  int v9; // eax@9
-  int v10; // eax@10
-  int v11; // edx@13
-  int v12; // ecx@14
-  int v13; // eax@15
-  int v14; // ebx@18
-  int v15; // eax@18
-  double v16; // st7@21
-  double v17; // st7@22
-  unsigned __int16 v18; // cx@27
-  Player *v19; // ecx@28
-  int v20; // eax@30
-  int v21; // eax@30
-  int v22; // eax@30
-  int v23; // ecx@30
-  unsigned int v24; // eax@30
-  int v25; // eax@31
-  int v26; // ebx@32
-  int v27; // eax@32
-  unsigned __int16 *v28; // ebx@36
-  int v29; // eax@42
-  int v30; // edi@43
-  signed int v31; // eax@49
-  int v32; // ecx@50
-  int result; // eax@54
-  float v34; // [sp+8h] [bp-38h]@27
-  float v35; // [sp+Ch] [bp-34h]@18
-  float v36; // [sp+10h] [bp-30h]@21
-  float v37; // [sp+14h] [bp-2Ch]@21
-  float v38; // [sp+18h] [bp-28h]@27
-  int v39; // [sp+1Ch] [bp-24h]@31
-  int v40; // [sp+20h] [bp-20h]@1
-  int v41; // [sp+24h] [bp-1Ch]@1
-  unsigned int v42; // [sp+28h] [bp-18h]@14
-  int v43; // [sp+2Ch] [bp-14h]@1
-  int v44; // [sp+30h] [bp-10h]@1
-  int v45; // [sp+34h] [bp-Ch]@1
-  int v46; // [sp+38h] [bp-8h]@1
-  int v47; // [sp+3Ch] [bp-4h]@1
-
-  v2 = 0;
-  v3 = 0;
-  v4 = this;
-  v47 = (unsigned __int16)word_4EDED8[0];
-  v43 = 0;
-  v45 = 0;
-  v40 = 0;
-  v41 = 0;
-  v44 = 0;
-  v46 = 0;
-  if ( a2 )
+int Player::GetAttackRecoveryTime(bool bRangedAttack)
+{
+  ItemGen  *weapon = nullptr;
+  ItemDesc *weapon_desc = nullptr;
+  uint      weapon_recovery = base_recovery_times_per_weapon_type[0];
+  if (bRangedAttack)
   {
     if ( !HasItemEquipped(EQUIP_BOW) )
       goto LABEL_17;
-    v5 = (int)&v4->pInventoryItems[v4->pEquipment.uBow-1];
-    v46 = v5;
-    v3 = (char *)&pItemsTable->pItems[*(int *)v5].pIconName;
-    v6 = (unsigned __int16)word_4EDED8[(unsigned __int8)v3[29]];
-    goto LABEL_4;
-  }
-  if ( IsUnarmed() == 1 )
-  {
-    LOBYTE(v7) = GetActualSkillLevel(PLAYER_SKILL_UNARMED);
-    if ( v7 )
-    {
-      v6 = (unsigned __int16)word_4EDED8[1];
-LABEL_4:
-      v47 = v6;
+    weapon = &pInventoryItems[pEquipment.uBow - 1];
+    weapon_desc = &pItemsTable->pItems[weapon->uItemID];
+    weapon_recovery = base_recovery_times_per_weapon_type[weapon_desc->uSkillType];
+    goto LABEL_17;
+  }
+  else if ( IsUnarmed() == 1 )
+  {
+    if (GetActualSkillLevel(PLAYER_SKILL_UNARMED))
+    {
+      weapon_recovery = base_recovery_times_per_weapon_type[1];
       goto LABEL_17;
     }
   }
-  if ( HasItemEquipped(EQUIP_TWO_HANDED) )
-  {
-    v8 = (int)&v4->pInventoryItems[v4->pEquipment.uMainHand-1];
-    v46 = v8;
-    v9 = *(int *)v8;
-    v3 = (char *)&pItemsTable->pItems[v9].pIconName;
-    if ( v3[28] == 12 )
-      v10 = *(&pSpellDatas[0].uExpertLevelRecovery + 10 * *((int *)&pSpellDatas[66].uNormalLevelRecovery + v9));
+
+  if ( HasItemEquipped(EQUIP_MAIN_HAND) )
+  {
+    weapon = &pInventoryItems[pEquipment.uMainHand - 1];
+    weapon_desc = &pItemsTable->pItems[weapon->uItemID];
+    if (weapon_desc->uEquipType == EQUIP_WAND)
+    {
+      __debugbreak();  // looks like offset in player's inventory and wand_lut much like case in 0042ECB5
+      __debugbreak();  // looks like wands were two-handed weapons once, or supposed to be. should not get here now
+      weapon_recovery = pSpellDatas[wand_spell_ids[weapon->uItemID - ITEM_WAND_FIRE]].uExpertLevelRecovery;
+    }
     else
-      v10 = (unsigned __int16)word_4EDED8[(unsigned __int8)v3[29]];
-    v47 = v10;
-  }
-  if ( HasItemEquipped((ITEM_EQUIP_TYPE)0) )
-  {
-    v12 = (int)&v4->pInventoryItems[v4->pEquipment.uOffHand-1];
-    v42 = (unsigned __int16)word_4EDED8[pItemsTable->pItems[*(int *)v12].uSkillType];
-    if ( (signed int)v42 > v47 )
-    {
-      v13 = *(int *)v12;
-      v46 = v12;
-      v3 = (char *)(v11 + 48 * v13);
-      v47 = v42;
-    }
-    v2 = 0;
-  }
+      weapon_recovery = base_recovery_times_per_weapon_type[weapon_desc->uSkillType];
+  }
+  if (HasItemEquipped(EQUIP_OFF_HAND) && GetEquippedItemEquipType(EQUIP_OFF_HAND) != EQUIP_SHIELD) // ADD: shield check because shield recovery is added later and can be accidentally doubled
+  {
+    auto v12 = &pInventoryItems[pEquipment.uOffHand - 1];
+    auto v12_desc = &pItemsTable->pItems[v12->uItemID];
+    if (base_recovery_times_per_weapon_type[v12_desc->uSkillType] > weapon_recovery)
+    {
+      weapon = &pInventoryItems[pEquipment.uOffHand - 1];
+      weapon_desc = &pItemsTable->pItems[weapon->uItemID];
+      weapon_recovery = base_recovery_times_per_weapon_type[pItemsTable->pItems[weapon->uItemID].uSkillType];
+    }
+  }
+
 LABEL_17:
+  uint armour_recovery = 0;
   if ( HasItemEquipped(EQUIP_ARMOUR) )
   {
-    v14 = pItemsTable->pItems[*(int *)&v4->pInventoryItems[v4->pEquipment.uBody-1]].uSkillType;
-    SkillToMastery(v4->pActiveSkills[9]);
-    v15 = (unsigned __int16)word_4EDED8[v14];
-    v35 = 1.0;
-    v43 = v15;
-    if ( v14 == 9 )
-    {
-      v36 = 0.0;
+    auto armour_skill_type = pItemsTable->pItems[pInventoryItems[pEquipment.uBody - 1].uItemID].uSkillType;
+    uint base_armour_recovery = base_recovery_times_per_weapon_type[armour_skill_type];
+
+    float armour_recovery_multipliers[4];
+    if (armour_skill_type == PLAYER_SKILL_LEATHER)
+    {
+      armour_recovery_multipliers[0] = 1.0f;
+      armour_recovery_multipliers[1] = 0;
+      armour_recovery_multipliers[2] = 0;
+      armour_recovery_multipliers[3] = 0;
+    }
+    else if (armour_skill_type == PLAYER_SKILL_CHAIN)
+    {
+      armour_recovery_multipliers[0] = 1.0f;
+      armour_recovery_multipliers[1] = 0.5f;
+      armour_recovery_multipliers[2] = 0;
+      armour_recovery_multipliers[3] = 0;
+    }
+    else if (armour_skill_type == PLAYER_SKILL_PLATE)
+    {
+      armour_recovery_multipliers[0] = 1.0f;
+      armour_recovery_multipliers[1] = 0.5f;
+      armour_recovery_multipliers[2] = 0.5f;
+      armour_recovery_multipliers[3] = 0;
     }
     else
     {
-      if ( v14 != 10 )
-      {
-        if ( v14 != 11 )
-        {
-          v36 = 1.0;
-          v37 = 1.0;
-          v16 = 1.0;
-LABEL_27:
-          v18 = v4->pActiveSkills[v14];
-          v38 = v16;
-          v43 = (signed __int64)((double)v43 * *(&v34 + SkillToMastery(v18)));
-          v2 = 0;
-          goto LABEL_28;
-        }
-        v17 = 0.5;
-        v36 = 0.5;
-LABEL_26:
-        v37 = v17;
-        v16 = 0.0;
-        goto LABEL_27;
-      }
-      v36 = 0.5;
-    }
-    v17 = 0.0;
-    goto LABEL_26;
-  }
-LABEL_28:
-  if ( HasItemEquipped((ITEM_EQUIP_TYPE)v2) && v19->GetEquippedItemEquipType(v2) == 4 )
-  {
-    v20 = 9 * v4->pEquipment.uOffHand;
-    v35 = 1.0;
-    v21 = 3 * *(int *)&v4->spellbook.pDarkSpellbook.bIsSpellAvailable[4 * v20 + 5];
-    v36 = 0.0;
-    v22 = pItemsTable->pItems[16 * v21 / 0x30u].uSkillType;
-    v37 = 0.0;
-    v23 = (unsigned __int16)word_4EDED8[v22];
-    v38 = 0.0;
-    v45 = v23;
-    v24 = SkillToMastery(v4->pActiveSkills[v22]);
-    v45 = (signed __int64)((double)v45 * *(&v34 + v24));
-  }
-  v25 = GetActualSpeed();
-  v39 = _48EA1B_get_static_effect(v25);
-  v42 = v2;
-  if ( v3 != (char *)v2 )
-  {
-    v26 = (unsigned __int8)v3[29];
-    LOBYTE(v27) = GetActualSkillLevel((enum PLAYER_SKILL_TYPE)(unsigned __int8)v3[29]);
-    if ( v27 && (v26 == 1 || v26 == 3 || v26 == 5) )
-    {
-      v28 = &v4->pActiveSkills[v26];
-      if ( (signed int)SkillToMastery(*v28) >= 2 )
-        v40 = *(char *)v28 & 0x3F;
-    }
-    v2 = 0;
-    if ( v3[29] == 7 )
-      v42 = 1;
-  }
-  if ( a2 == v2 )
-  {
-    if ( v42 == v2 )
-    {
-      LOBYTE(v29) = GetActualSkillLevel(PLAYER_SKILL_ARMSMASTER);
-      if ( v29 != v2 )
-      {
-        v30 = v29 & 0x3F;
-        v44 = v29 & 0x3F;
-        if ( (signed int)SkillToMastery(v29) >= 4 )
-          v44 += v30;
-      }
-    }
-  }
-  if ( SHIDWORD(v4->pPlayerBuffs[7].uExpireTime) >= (signed int)v2
-    && (SHIDWORD(v4->pPlayerBuffs[7].uExpireTime) > (signed int)v2 || LODWORD(v4->pPlayerBuffs[7].uExpireTime) > v2) )
+      assert(false && "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;
+      armour_recovery_multipliers[3] = 1.0f;
+    }
+
+    uint skill_mastery = SkillToMastery(pActiveSkills[armour_skill_type]);
+    armour_recovery = base_armour_recovery * armour_recovery_multipliers[skill_mastery - 1];
+  }
+
+  uint shield_recovery = 0;
+  if (HasItemEquipped(EQUIP_OFF_HAND) && GetEquippedItemEquipType(EQUIP_OFF_HAND) == EQUIP_SHIELD)
+  {
+    float shield_recovery_multipliers[4] = {1, 0, 0, 0};
+
+    auto shield = &pInventoryItems[pEquipment.uOffHand - 1];
+    auto skill_type = pItemsTable->pItems[shield->uItemID].uSkillType;
+
+    uint shield_base_recovery = base_recovery_times_per_weapon_type[skill_type];
+    shield_recovery = shield_base_recovery * SkillToMastery(pActiveSkills[skill_type]);
+  }
+
+  uint player_speed_recovery_reduction = _48EA1B_get_static_effect(GetActualSpeed()),
+       sword_axe_bow_recovery_reduction = 0;
+  bool shooting_laser = false;
+  if (weapon_desc)
+  {
+    if (GetActualSkillLevel((PLAYER_SKILL_TYPE)weapon_desc->uSkillType) &&
+        (weapon_desc->uSkillType == PLAYER_SKILL_SWORD || weapon_desc->uSkillType == PLAYER_SKILL_AXE || weapon_desc->uSkillType == PLAYER_SKILL_BOW) )
+    {
+      if (SkillToMastery(pActiveSkills[weapon_desc->uSkillType]) >= 2 )  // Expert   Sword, Axe & Bow   reduce recovery
+        sword_axe_bow_recovery_reduction = pActiveSkills[weapon_desc->uSkillType] & 0x3F;
+    }
+    if (weapon_desc->uSkillType == PLAYER_SKILL_BLASTER)
+      shooting_laser = true;
+  }
+
+  uint armsmaster_recovery_reduction = 0;
+  if (!bRangedAttack && !shooting_laser)
+  {
+    if (uint armsmaster_level = GetActualSkillLevel(PLAYER_SKILL_ARMSMASTER))
+    {
+      armsmaster_recovery_reduction = armsmaster_level & 0x3F;
+      if (SkillToMastery(armsmaster_level) >= 4)
+        armsmaster_recovery_reduction *= 2;
+    }
+  }
+
+  uint v41 = 0;
+  if (pPlayerBuffs[PLAYER_BUFF_7].uExpireTime > 0)
     v41 = 25;
-  v31 = 0;
-  if ( v46 != v2 )
-  {
-    v32 = *(int *)(v46 + 12);
-    if ( v32 == 59 || v32 == 41 || *(int *)v46 == 500 )
-      v31 = 20;
-  }
-  result = v47 + v43 + v45 - v44 - v31 - v41 - v40 - v39;
-  if ( result < 0 )
-    result = 0;
-  return result;
+
+  uint weapon_enchantment_recovery_reduction = 0;
+  if ( weapon  )
+  {
+    if (weapon->uSpecEnchantmentType == 59 ||
+        weapon->uSpecEnchantmentType == 41 ||
+        weapon->uSpecEnchantmentType == 500)
+      weapon_enchantment_recovery_reduction = 20;
+  }
+
+
+  int recovery = weapon_recovery +
+                 armour_recovery +
+                 shield_recovery
+                 - armsmaster_recovery_reduction
+                 - weapon_enchantment_recovery_reduction
+                 - v41
+                 - sword_axe_bow_recovery_reduction
+                 - player_speed_recovery_reduction;
+
+  if (recovery < 0)
+    recovery = 0;
+  return recovery;
 }
 
 //----- (0048E4F8) --------------------------------------------------------
@@ -4553,43 +4520,44 @@
 }
 
 //----- (0048E8F5) --------------------------------------------------------
-bool Player::Recover(signed int a2)
-{
-  Player *v2; // esi@1
+bool Player::Recover(int dt)
+{
+  //Player *v2; // esi@1
   signed __int64 v3; // qax@1
-  bool result; // eax@4
-
-  v2 = this;
-  v3 = (signed __int64)((double)(a2 * _48EA46_calc_special_bonus_by_items(17)) * 0.01 + (double)a2);
-  if ( v2->uTimeToRecovery - (signed int)v3 > 0 )
-  {
-    v2->uTimeToRecovery -= v3;
-    result = 1;
+  //bool result; // eax@4
+
+  //v2 = this;
+  v3 = (signed __int64)((double)(dt * _48EA46_calc_special_bonus_by_items(17)) * 0.01 + (double)dt);
+
+  Log::Warning(L"Recover(dt = %u/%u - %u", dt, (uint)v3, (uint)uTimeToRecovery);
+
+  if (uTimeToRecovery > v3)
+  {
+    uTimeToRecovery -= v3;
+    return true;
   }
   else
   {
-    v2->uTimeToRecovery = 0;
-    viewparams->bRedrawGameUI = 1;
-    if ( !uActiveCharacter )
+    uTimeToRecovery = 0;
+    viewparams->bRedrawGameUI = true;
+    if (!uActiveCharacter)
       uActiveCharacter = pParty->GetNextActiveCharacter();
-    result = 0;
-  }
-  return result;
+    return false;
+  }
 }
 
 //----- (0048E96A) --------------------------------------------------------
-void Player::SetRecoveryTime(signed int sRecoveryTime)
-{
-  signed int v2; // edx@1
-
-  v2 = sRecoveryTime;
-  if ( sRecoveryTime < 0 )
-    v2 = 0;
-  if ( v2 > this->uTimeToRecovery )
-    this->uTimeToRecovery = v2;
-  if ( pPlayers[uActiveCharacter] == this && !some_active_character )
+void Player::SetRecoveryTime(signed int rec)
+{
+  assert(rec > 0);
+
+  if (rec > uTimeToRecovery)
+    uTimeToRecovery = rec;
+
+  if (pPlayers[uActiveCharacter] == this && !some_active_character)
     uActiveCharacter = pParty->GetNextActiveCharacter();
-  viewparams->bRedrawGameUI = 1;
+
+  viewparams->bRedrawGameUI = true;
 }
 // 50C0C4: using guessed type int some_active_character;
 
@@ -4626,33 +4594,31 @@
 //----- (0048EA46) --------------------------------------------------------
 int Player::_48EA46_calc_special_bonus_by_items(int a2)
 {
-  int v2; // edi@1
   int v3; // esi@1
   int v4; // edx@2
   int v5; // eax@3
   char *v6; // eax@4
 
-  v2 = 0;
   v3 = 0;
   while ( 1 )
   {
     if ( !HasItemEquipped((ITEM_EQUIP_TYPE)v3) )
       goto LABEL_11;
-    v5 = pEquipment.uOffHand  - 1;            // BUG
-                                                // v5 = _this->cEquippedItems.uOffHand - 1;
+    v5 = pEquipment.pIndices[v3]  - 1;
     if ( a2 != 17 )
-      break;
+    {
+      if ( a2 != 24 || this->pInventoryItems[v5].uSpecEnchantmentType != 24 )
+        goto LABEL_11;
+      return 5;
+    }
     v6 = (char *)this + 36 * v5;
     if ( *((int *)v6 + 133) == 533 || *((int *)v6 + 136) == 17 )
       return 50;
 LABEL_11:
     ++v3;
     if ( (signed int)v3 >= 16 )
-      return v2;
-  }
-  if ( a2 != 24 || this->pInventoryItems[v5].uSpecEnchantmentType != 24 )
-    goto LABEL_11;
-  return 5;
+      return 0;
+  }
 }
 
 //----- (0048EAAE) --------------------------------------------------------
@@ -4877,7 +4843,7 @@
       v31 = *(&v6->pEquipment.uOffHand + v65) - 1;
       if ( v3 == 9 )
       {
-        v32 = GetEquippedItemEquipType(v65);
+        v32 = GetEquippedItemEquipType((ITEM_EQUIP_TYPE)v65);
         if ( v32 >= 3 )
         {
           if ( v32 <= 11 )
@@ -5438,9 +5404,9 @@
   {
     if ( IsUnarmed() != 1 )
     {
-      if ( v6->HasItemEquipped(EQUIP_TWO_HANDED) )
-      {
-        v22 = this->GetEquippedItemEquipType(1u);
+      if ( v6->HasItemEquipped(EQUIP_MAIN_HAND) )
+      {
+        v22 = this->GetEquippedItemEquipType(EQUIP_MAIN_HAND);
         if ( v22 >= 0 )
         {
           if ( v22 <= 2 )
@@ -5461,7 +5427,7 @@
           }
         }
       }
-      if ( a3 || !v6->HasItemEquipped((ITEM_EQUIP_TYPE)0) || (v28 = v27->GetEquippedItemEquipType(0), v28 < 0) || v28 > 2 )
+      if ( a3 || !v6->HasItemEquipped(EQUIP_OFF_HAND) || (v28 = v27->GetEquippedItemEquipType(EQUIP_OFF_HAND), v28 < 0) || v28 > 2 )
         return v5 + v62 + v61;
       v15 = pItemsTable->pItems[v29].uDamageMod;
       v14 = pItemsTable->pItems[v29].uDamageDice * pItemsTable->pItems[v29].uDamageRoll;
@@ -5485,16 +5451,16 @@
       v5 = 0;
       return v5 + v62 + v61;
     }
-    if ( v6->HasItemEquipped(EQUIP_TWO_HANDED) )
-    {
-      v17 = this->GetEquippedItemEquipType(1u);
+    if ( v6->HasItemEquipped(EQUIP_MAIN_HAND) )
+    {
+      v17 = this->GetEquippedItemEquipType(EQUIP_MAIN_HAND);
       if ( v17 >= 0 )
       {
         if ( v17 <= 2 )
           v5 = pItemsTable->pItems[*(int *)&v6->pInventoryItems[v6->pEquipment.uMainHand-1]].uDamageMod;
       }
     }
-    if ( a3 || !v6->HasItemEquipped((ITEM_EQUIP_TYPE)0) || (v19 = v18->GetEquippedItemEquipType(0), v19 < 0) || v19 > 2 )
+    if ( a3 || !v6->HasItemEquipped(EQUIP_OFF_HAND) || (v19 = v18->GetEquippedItemEquipType(EQUIP_OFF_HAND), v19 < 0) || v19 > 2 )
       return v5 + v62 + v61;
     v20 = *(int *)&v6->pInventoryItems[v6->pEquipment.uOffHand-1];
     goto LABEL_365;
@@ -5506,9 +5472,9 @@
       v5 = 1;
       return v5 + v62 + v61;
     }
-    if ( v6->HasItemEquipped(EQUIP_TWO_HANDED) )
-    {
-      v9 = this->GetEquippedItemEquipType(1u);
+    if ( v6->HasItemEquipped(EQUIP_MAIN_HAND) )
+    {
+      v9 = this->GetEquippedItemEquipType(EQUIP_MAIN_HAND);
       if ( v9 >= 0 )
       {
         if ( v9 <= 2 )
@@ -5522,7 +5488,7 @@
         }
       }
     }
-    if ( a3 || !v6->HasItemEquipped((ITEM_EQUIP_TYPE)0) || (v12 = v11->GetEquippedItemEquipType(0), v12 < 0) || v12 > 2 )
+    if ( a3 || !v6->HasItemEquipped(EQUIP_OFF_HAND) || (v12 = v11->GetEquippedItemEquipType(EQUIP_OFF_HAND), v12 < 0) || v12 > 2 )
       return v5 + v62 + v61;
     v14 = pItemsTable->pItems[this->pInventoryItems[this->pEquipment.uOffHand].uItemID].uDamageMod;
     v15 = pItemsTable->pItems[this->pInventoryItems[this->pEquipment.uOffHand].uItemID].uDamageDice;
@@ -5881,7 +5847,7 @@
   unsigned __int8 v8; // of@5
   PlayerEquipment *v9; // ebx@19
   Player *v10; // ecx@20
-  enum PLAYER_SKILL_TYPE v11; // edi@21
+  PLAYER_SKILL_TYPE v11; // edi@21
   int v12; // eax@21
   int v13; // edi@21
   char v14; // di@25
@@ -5892,7 +5858,7 @@
   ITEM_EQUIP_TYPE v20; // edi@40
   int v21; // edx@41
   int v22; // eax@42
-  enum PLAYER_SKILL_TYPE v23; // edi@45
+  PLAYER_SKILL_TYPE v23; // edi@45
   unsigned __int16 v24; // ax@45
   unsigned __int16 v25; // bx@45
   unsigned int v26; // eax@45
@@ -5907,12 +5873,12 @@
   ITEM_EQUIP_TYPE v35; // edi@69
   int v36; // edx@70
   int v37; // eax@71
-  enum PLAYER_SKILL_TYPE v38; // edi@74
+  PLAYER_SKILL_TYPE v38; // edi@74
   int v39; // eax@74
   int v40; // eax@89
   char v41; // si@89
   int v42; // eax@96
-  enum PLAYER_SKILL_TYPE v43; // edx@97
+  PLAYER_SKILL_TYPE v43; // edx@97
   int v44; // eax@97
   int v45; // eax@98
   int v46; // eax@99
@@ -6549,9 +6515,9 @@
 }
 
 //----- (004903C9) --------------------------------------------------------
-enum PLAYER_SKILL_TYPE Player::GetSkillIdxByOrder(signed int order)
-{
-  enum PLAYER_SKILL_TYPE result; // eax@5
+PLAYER_SKILL_TYPE Player::GetSkillIdxByOrder(signed int order)
+{
+  PLAYER_SKILL_TYPE result; // eax@5
   int v3; // edx@5
   char *v4; // ecx@5
   int v5; // esi@11
--- a/Player.h	Tue Mar 26 23:18:58 2013 +0600
+++ b/Player.h	Tue Mar 26 23:19:12 2013 +0600
@@ -8,6 +8,7 @@
 #define PLAYER_BUFF_BLESS            1
 #define PLAYER_BUFF_FATE             4
 #define PLAYER_BUFF_HAMMERHANDS      6
+#define PLAYER_BUFF_7                7
 #define PLAYER_BUFF_PAIN_REFLECTION 10
 #define PLAYER_BUFF_PRESERVATION    11
 #define PLAYER_BUFF_REGENERATION    12
@@ -184,7 +185,7 @@
 };
 
 /*  328 */
-enum PLAYER_SKILL_TYPE
+enum PLAYER_SKILL_TYPE: unsigned __int8
 {
   PLAYER_SKILL_STAFF = 0,
   PLAYER_SKILL_SWORD = 1,
@@ -484,10 +485,10 @@
   bool CanTrainToNextLevel();
   unsigned int GetExperienceDisplayColor();
   int CalculateIncommingDamage(int resistance, signed int type);
-  int GetEquippedItemEquipType(unsigned int uEquipSlot);
-  int GetEquippedItemSkillType(enum ITEM_EQUIP_TYPE uEquipSlot);
+  ITEM_EQUIP_TYPE   GetEquippedItemEquipType(ITEM_EQUIP_TYPE uEquipSlot);
+  PLAYER_SKILL_TYPE GetEquippedItemSkillType(ITEM_EQUIP_TYPE uEquipSlot);
   bool IsUnarmed();
-  bool HasItemEquipped(enum ITEM_EQUIP_TYPE uEquipIndex);
+  bool HasItemEquipped(ITEM_EQUIP_TYPE uEquipIndex);
   bool HasEnchantedItemEquipped(int uEnchantment);
   bool WearsItem(int a1, signed int a2);
   bool StealFromShop(struct ItemGen *a2, int a3, int a4, int a5, int *a6);
@@ -496,7 +497,7 @@
   int ReceiveDamage(signed int type, int resistance);
   int _48DCF6(int a2, struct Actor *pActor);
   unsigned int GetSpellSchool(unsigned int uSpellID);
-  int GetAttackRecoveryTime(int a2);
+  int GetAttackRecoveryTime(bool bRangedAttack);
   int GetMaxHealth();
   int GetMaxMana();
   int GetBaseAC();
@@ -512,14 +513,14 @@
   int _48EA46_calc_special_bonus_by_items(int a2);
   int GetItemsBonus(enum CHARACTER_ATTRIBUTE_TYPE attr, int a3);
   int GetMagicalBonus(enum CHARACTER_ATTRIBUTE_TYPE a2);
-  char GetActualSkillLevel(enum PLAYER_SKILL_TYPE uSkillType);
+  char GetActualSkillLevel(PLAYER_SKILL_TYPE uSkillType);
   int GetSkillBonus(enum CHARACTER_ATTRIBUTE_TYPE a2);
   enum CHARACTER_RACE GetRace();
   PLAYER_SEX GetSexByVoice();
   void SetInitialStats();
   int SetSexByVoice();
   void Reset(PLAYER_CLASS_TYPE classType);
-  enum PLAYER_SKILL_TYPE GetSkillIdxByOrder(signed int order);
+  PLAYER_SKILL_TYPE GetSkillIdxByOrder(signed int order);
   void DecreaseAttribute(int eAttribute);
   int IncreaseAttribute(int eAttribute);
   void Player::Zero();
--- a/Render.cpp	Tue Mar 26 23:18:58 2013 +0600
+++ b/Render.cpp	Tue Mar 26 23:19:12 2013 +0600
@@ -5204,13 +5204,13 @@
 // 4EFA84: using guessed type int dword_4EFA84;
 
 //----- (0049F5A2) --------------------------------------------------------
-int Render::_49F5A2(int a2, int a3, int a4, void *Dst, int a6, int a7)
-{
+void Render::PackPCXpicture( unsigned short* picture_data, int wight, int heidth, void *data_buff, int max_buff_size,unsigned int* packed_size )
+    {
   Render *v7; // ebx@1
   void *v8; // esi@3
   void *v9; // esi@3
   int v10; // ecx@4
-  int v11; // eax@4
+  unsigned short* v11; // eax@4
   int v12; // eax@6
   int v13; // eax@8
   int v14; // ecx@8
@@ -5220,158 +5220,141 @@
   char v18[58]; // [sp+Ch] [bp-ACh]@3
  // __int16 v19; // [sp+44h] [bp-74h]@3
   char v20[48]; // [sp+48h] [bp-70h]@3
-  char *v21; // [sp+78h] [bp-40h]@7
-  char *v22; // [sp+7Ch] [bp-3Ch]@7
+  char *lineG; // [sp+78h] [bp-40h]@7
+  char *lineB; // [sp+7Ch] [bp-3Ch]@7
   int v23; // [sp+80h] [bp-38h]@4
   int v24; // [sp+84h] [bp-34h]@4
   int v25; // [sp+88h] [bp-30h]@4
   int v26; // [sp+8Ch] [bp-2Ch]@4
-  char Src; // [sp+90h] [bp-28h]@3
-  char v28; // [sp+91h] [bp-27h]@3
-  char v29; // [sp+92h] [bp-26h]@3
-  char v30; // [sp+93h] [bp-25h]@3
-  __int16 v31; // [sp+94h] [bp-24h]@3
-  __int16 v32; // [sp+96h] [bp-22h]@3
-  __int16 v33; // [sp+98h] [bp-20h]@3
-  __int16 v34; // [sp+9Ah] [bp-1Eh]@3
-  __int16 v35; // [sp+9Ch] [bp-1Ch]@3
-  __int16 v36; // [sp+9Eh] [bp-1Ah]@3
-  char v37; // [sp+A0h] [bp-18h]@3
-  char v38; // [sp+A1h] [bp-17h]@3
-  __int16 v39; // [sp+A2h] [bp-16h]@3
-  __int16 v40; // [sp+A4h] [bp-14h]@3
-  void *ptr; // [sp+A8h] [bp-10h]@3
-  int v42; // [sp+ACh] [bp-Ch]@1
+  PCXHeader_1 Src; // [sp+90h] [bp-28h]@3
+  PCXHeader_2 v27; // [sp+A0h] [bp-18h]@3
+  char *lineRGB; // [sp+A8h] [bp-10h]@3
+  int pitch; // [sp+ACh] [bp-Ch]@1
   char v43; // [sp+B3h] [bp-5h]@18
   int i; // [sp+B4h] [bp-4h]@6
+  unsigned short* line_pictute_data;
+  byte test_byte;
+  unsigned char pict_byte;
 
   v7 = this;
-  v42 = a3;
-  if ( a3 & 1 )
-    v42 = a3 + 1;
-  v31 = 0;
-  v32 = 0;
-  v33 = a3 - 1;
-  v34 = a4 - 1;
-  v39 = v42;
+  pitch = wight;
+  if ( wight & 1 )
+      pitch = wight + 1;
+  Src.left = 0;
+  Src.up = 0;
+  Src.right = wight - 1;
+  Src.bottom = heidth - 1;
+  v27.pitch = pitch;
   memset(&v20, 0, 0x30u);
   memset(&v18, 0, 0x38u);
-  v8 = Dst;
-  v37 = 0;
+  v8 = data_buff;
+  v27.reserved = 0;
   *(_WORD *)&v18[56] = 0;
-  Src = 10;
-  v28 = 5;
-  v29 = 1;
-  v30 = 8;
-  v35 = 75;
-  v36 = 75;
-  v38 = 3;
-  v40 = 1;
-  memcpy(Dst, &Src, 1u);
+  Src.manufacturer = 10;
+  Src.version = 5;
+  Src.encoding = 1;
+  Src.bpp = 8;
+  Src.hdpi = 75;
+  Src.vdpi = 75;
+  v27.planes = 3;
+  v27.palette_info = 1;
+  memcpy(data_buff, &Src, 1u);
   v8 = (char *)v8 + 1;
-  memcpy(v8, &v28, 1u);
+  memcpy(v8, &Src.version, 1u);
   v8 = (char *)v8 + 1;
-  memcpy(v8, &v29, 1u);
+  memcpy(v8, &Src.encoding, 1u);
   v8 = (char *)v8 + 1;
-  memcpy(v8, &v30, 1u);
+  memcpy(v8, &Src.bpp, 1u);
   v8 = (char *)v8 + 1;
-  memcpy(v8, &v31, 2u);
+  memcpy(v8, &Src.left, 2u);
   v8 = (char *)v8 + 2;
-  memcpy(v8, &v32, 2u);
+  memcpy(v8, &Src.up, 2u);
   v8 = (char *)v8 + 2;
-  memcpy(v8, &v33, 2u);
+  memcpy(v8, &Src.right, 2u);
   v8 = (char *)v8 + 2;
-  memcpy(v8, &v34, 2u);
+  memcpy(v8, &Src.bottom, 2u);
   v8 = (char *)v8 + 2;
-  memcpy(v8, &v35, 2u);
+  memcpy(v8, &Src.hdpi, 2u);
   v8 = (char *)v8 + 2;
-  memcpy(v8, &v36, 2u);
+  memcpy(v8, &Src.vdpi, 2u);
   v8 = (char *)v8 + 2;
   memcpy(v8, &v20, 0x30u);
   v8 = (char *)v8 + 48;
-  memcpy(v8, &v37, 1u);
+  memcpy(v8, &v27, 1u);
   v8 = (char *)v8 + 1;
-  memcpy(v8, &v38, 1u);
+  memcpy(v8, &v27.planes, 1u);
   v8 = (char *)v8 + 1;
-  memcpy(v8, &v39, 2u);
+  memcpy(v8, &v27.pitch, 2u);
   v8 = (char *)v8 + 2;
-  memcpy(v8, &v40, 2u);
+  memcpy(v8, &v27.palette_info, 2u);
   v8 = (char *)v8 + 2;
   memcpy(v8, &v18, 0x3Au);
   v9 = (char *)v8 + 58;
-  ptr = pAllocator->AllocNamedChunk(0, 3 * a3 + 6, 0);
-  if ( a4 > 0 )
-  {
-    v10 = v42;
-    v25 = a4;
-    v26 = 3 * v42;
-    v23 = 2 * a3;
-    v11 = a2;
-    v24 = a2;
+
+  lineRGB = (char*)pAllocator->AllocNamedChunk(0, 3 * (wight + 2), 0);
+  if ( heidth > 0 )
+  {
+    v10 = pitch;
+    v25 = heidth;
+    v26 = 3 * pitch;
+    v23 = 2 * wight;
+    v11 = picture_data;
+    v24 = (int)picture_data;
     while ( 1 )
     {
-      a4 = v11;
+      line_pictute_data = v11;
       v12 = 0;
       i = 0;
-      if ( a3 > 0 )
-      {
-        v21 = (char *)ptr + v10;
-        v22 = (char *)ptr + 2 * v42;
+      if ( wight > 0 )
+      {
+        lineG = (char *)lineRGB + pitch;
+        lineB = (char *)lineRGB + 2 * pitch;
         do
         {
-          *((char *)ptr + v12) = (signed int)(v7->uTargetRMask & *(short *)a4) >> (LOBYTE(v7->uTargetGBits)
-                                                                                  + LOBYTE(v7->uTargetBBits)
-                                                                                  + v7->uTargetRBits
-                                                                                  - 8);
-          v13 = i;
-          v21[i] = (signed int)(v7->uTargetGMask & *(short *)a4) >> (LOBYTE(v7->uTargetBBits)
-                                                                   + LOBYTE(v7->uTargetGBits)
-                                                                   - 8);
-          v14 = a4;
-          a4 += 2;
-          v22[v13] = (v7->uTargetBMask & *(char *)v14) << (8 - LOBYTE(v7->uTargetBBits));
-          v12 = v13 + 1;
-          i = v12;
-        }
-        while ( v12 < a3 );
+          lineRGB[v12] = (signed int)(v7->uTargetRMask & *line_pictute_data) >> (v7->uTargetGBits  + v7->uTargetBBits  + v7->uTargetRBits  - 8);
+          lineG[v12] = (signed int)(v7->uTargetGMask & *line_pictute_data) >> ( v7->uTargetBBits + v7->uTargetGBits- 8);
+          lineB[v12] = (v7->uTargetBMask & *line_pictute_data) << (8 - v7->uTargetBBits);
+
+          v12++;
+        }
+        while ( v12 < wight );
       }
       for ( i = 0; i < v26; v9 = (char *)v9 + 1 )
       {
-        BYTE3(a4) = 1;
-        BYTE3(a2) = *((char *)ptr + i);
+        test_byte = 1;
+        pict_byte = lineRGB [i];
         do
         {
-          v15 = i + BYTE3(a4);
-          if ( *((char *)ptr + v15) != BYTE3(a2) )
+          v15 = i + test_byte;
+          if ( *((char *)lineRGB + v15) != pict_byte )
             break;
-          if ( !(v15 % v42) )
+          if ( !(v15 % pitch) )
             break;
-          ++BYTE3(a4);
-        }
-        while ( BYTE3(a4) < 0x3Fu );
-        if ( i + BYTE3(a4) > v26 )
-          BYTE3(a4) = 3 * v42 - i;
-        if ( BYTE3(a4) > 1u || BYTE3(a2) >= 0xC0u )
-        {
-          v43 = BYTE3(a4) | 0xC0;
+          ++test_byte;
+        }
+        while ( test_byte < 0x3Fu );
+        if ( i + test_byte > v26 )
+          test_byte = 3 * pitch - i;
+        if ( test_byte > 1u || pict_byte >= 0xC0u )
+        {
+          v43 = test_byte | 0xC0;
           memcpy(v9, &v43, 1u);
           v9 = (char *)v9 + 1;
         }
-        memcpy(v9, (char *)&a2 + 3, 1u);
-        i += BYTE3(a4);
-      }
-      v11 = v23 + v24;
+        memcpy(v9, &pict_byte, 1u);
+        i += test_byte;
+      }
+      v11 +=wight ;
       v16 = v25-- == 1;
-      v24 += v23;
+     
       if ( v16 )
         break;
-      v10 = v42;
-    }
-  }
-  pAllocator->FreeChunk(ptr);
-  result = a7;
-  *(int *)a7 = (char *)v9 - Dst;
-  return result;
+      v10 = pitch;
+    }
+  }
+  pAllocator->FreeChunk(lineRGB);
+  *(int *)packed_size = (char *)v9 - data_buff;
+ 
 }
 
 //----- (0049F8B5) --------------------------------------------------------
--- a/Render.h	Tue Mar 26 23:18:58 2013 +0600
+++ b/Render.h	Tue Mar 26 23:19:12 2013 +0600
@@ -279,7 +279,7 @@
   void PresentBlackScreen();
   void SavePCXScreenshot();
   void _49F1BC(const char *a1);
-  int _49F5A2(int a2, int a3, int a4, void *Dst, int a6, int a7);
+  void PackPCXpicture(unsigned short* picture_data, int wight, int heidth, void *data_buff, int max_buff_size,unsigned int* packed_size);
   FILE *SavePCXImage(const char *Filename, char *a3, int a4, int a5);
   void ClearTarget(unsigned int uColor);
   void Release2();
--- a/SaveLoad.cpp	Tue Mar 26 23:18:58 2013 +0600
+++ b/SaveLoad.cpp	Tue Mar 26 23:19:12 2013 +0600
@@ -182,7 +182,7 @@
         auto uItemID = pParty->pPlayers[i].pInventoryItems[uEquipIdx - 1].uItemID;
         if (pItemsTable->pItems[uItemID].uEquipType == 12)
         {
-          __debugbreak();
+                __debugbreak();  // looks like offset in player's inventory and wand_lut much like case in 0042ECB5
           v31 = *((int *)&pSpellDatas[66].uNormalLevelRecovery + uItemID);
           stru_A750F8[i]._494836(v31, i + 9);
         }
@@ -228,16 +228,16 @@
 
 
 //----- (0045F469) --------------------------------------------------------
-int __fastcall SaveGame(int a1, __int16 *a2)
-{
+void SaveGame( bool IsAutoSAve, bool NotSaveWorld )
+    {
   int result; // eax@1
-  void *pScreenshot; // edi@5
-  int v4; // eax@6
+  unsigned short *pScreenshot; // edi@5
+  int text_pos; // eax@6
   int v5; // eax@6
   int v6; // eax@6
   const char *v7; // edi@8
   FILE *v8; // edi@24
-  int v9; // edi@30
+  char* compressed_buf; // edi@30
   void *v10; // esi@31
   void *v11; // esi@31
   void *v12; // esi@37
@@ -249,7 +249,7 @@
   unsigned int v18; // ecx@38
   unsigned int v19; // esi@39
   BSPModel *v20; // edx@39
-  void *v21; // esi@41
+  char *data_write_pos; // esi@41
   void *v22; // esi@41
   BSPModel *v23; // eax@42
   signed int v24; // edi@42
@@ -283,7 +283,7 @@
   int pPositionX; // [sp+20Ch] [bp-64h]@2
   int v53; // [sp+210h] [bp-60h]@2
   int v54; // [sp+214h] [bp-5Ch]@2
-  int Src; // [sp+218h] [bp-58h]@30
+  ODMHeader Src; // [sp+218h] [bp-58h]@30
   char v56; // [sp+21Ch] [bp-54h]@30
   char v57; // [sp+21Dh] [bp-53h]@30
   char v58; // [sp+21Eh] [bp-52h]@30
@@ -291,12 +291,12 @@
   int v60; // [sp+220h] [bp-50h]@30
   int v61; // [sp+224h] [bp-4Ch]@30
   int v62; // [sp+228h] [bp-48h]@2
-  LOD::Directory pDir; // [sp+22Ch] [bp-44h]@2
+  LOD::Directory pLodDirectory; // [sp+22Ch] [bp-44h]@2
   size_t Size; // [sp+250h] [bp-20h]@26
   __int16 *v66; // [sp+254h] [bp-1Ch]@1
-  void *DstBuf; // [sp+258h] [bp-18h]@2
+  char *uncompressed_buff; // [sp+258h] [bp-18h]@2
   __int16 *v68; // [sp+25Ch] [bp-14h]@32
-  unsigned int v69; // [sp+260h] [bp-10h]@23
+  unsigned int compressed_block_size; // [sp+260h] [bp-10h]@23
   int v70; // [sp+264h] [bp-Ch]@22
   std::string *v71; // [sp+268h] [bp-8h]@8
   int a3; // [sp+26Fh] [bp-1h]@8
@@ -304,10 +304,10 @@
   //v66 = a2;
   strcpy(byte_6BE3B0, pCurrentMapName);
   if (!_strcmpi(pCurrentMapName, "d05.blv")) // arena
-    return false;
+    return;
 
-  DstBuf = malloc(0xF4240);
-  pDir.Reset();
+  uncompressed_buff = (char*)malloc(1000000);
+  pLodDirectory.Reset();
   pPositionX = pParty->vPosition.x;
   v51 = pParty->vPosition.y;
   v62 = pParty->vPosition.z;
@@ -322,25 +322,25 @@
   if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
     pIndoor->stru1.uLastVisitDay = pParty->uTimePlayed;
   else
-    pOutdoor->uLastVisitDay = pParty->uTimePlayed;
+    pOutdoor->loc_time.uLastVisitDay = pParty->uTimePlayed;
   pScreenshot = MakeScreenshot(150, 112);
-  strcpy(pDir.pFilename, "image.pcx");
-  pRenderer->_49F5A2((int)pScreenshot, 150, 112, DstBuf, 1000000, (int)&pDir.uDataSize);
+  strcpy(pLodDirectory.pFilename, "image.pcx");
+  pRenderer->PackPCXpicture(pScreenshot, 150, 112, uncompressed_buff, 1000000, &pLodDirectory.uDataSize);
   free(pScreenshot);
   if (pCurrentScreen == SCREEN_SAVEGAME)
   {
     pRenderer->DrawTextureIndexed(8, 8, pIcons_LOD->GetTexture(uTextureID_loadsave));
     pRenderer->DrawTextureIndexed(18, 141, pIcons_LOD->GetTexture(uTextureID_save_up));
-    v4 = pFontSmallnum->AlignText_Center(0xBA, pGlobalTXT_LocalizationStrings[190]);
-    pGUIWindow_CurrentMenu->DrawText(pFontSmallnum, v4 + 25, 219, 0, pGlobalTXT_LocalizationStrings[190], 0, 0, 0); //
-    v5 = pFontSmallnum->AlignText_Center(0xBA, pSavegameHeader[uLoadGameUI_SelectedSlot].pName);
-    pGUIWindow_CurrentMenu->DrawTextInRect(pFontSmallnum, v5 + 25, 0x103u, 0, pSavegameHeader[uLoadGameUI_SelectedSlot].pName, 185, 0);
-    v6 = pFontSmallnum->AlignText_Center(0xBA, pGlobalTXT_LocalizationStrings[165]);
-    pGUIWindow_CurrentMenu->DrawText(pFontSmallnum, v6 + 25, 299, 0, pGlobalTXT_LocalizationStrings[165], 0, 0, 0); //, 
+    text_pos = pFontSmallnum->AlignText_Center(186, pGlobalTXT_LocalizationStrings[190]);
+    pGUIWindow_CurrentMenu->DrawText(pFontSmallnum, text_pos + 25, 219, 0, pGlobalTXT_LocalizationStrings[190], 0, 0, 0); //
+    text_pos  = pFontSmallnum->AlignText_Center(186, pSavegameHeader[uLoadGameUI_SelectedSlot].pName);
+    pGUIWindow_CurrentMenu->DrawTextInRect(pFontSmallnum, text_pos  + 25, 259, 0, pSavegameHeader[uLoadGameUI_SelectedSlot].pName, 185, 0);
+    text_pos  = pFontSmallnum->AlignText_Center(186, pGlobalTXT_LocalizationStrings[165]);
+    pGUIWindow_CurrentMenu->DrawText(pFontSmallnum, text_pos  + 25, 299, 0, pGlobalTXT_LocalizationStrings[165], 0, 0, 0); //, 
     pRenderer->Present();
   }
 
-  if (pNew_LOD->Write(&pDir, DstBuf, 0))
+  if (pNew_LOD->Write(&pLodDirectory, uncompressed_buff, 0))
   {
     sprintf(Str, pGlobalTXT_LocalizationStrings[612], 200); //  ! Code=%d
     MessageBoxA(nullptr, Str, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\LoadSave.cpp:773", 0);
@@ -352,45 +352,45 @@
   memset(header.field_30, 0, 52);
   strcpy(header.pLocationName, pCurrentMapName);
   header.uWordTime = pParty->uTimePlayed;
-  strcpy(pDir.pFilename, "header.bin");
-  pDir.uDataSize = sizeof(SavegameHeader);
-  if (pNew_LOD->Write(&pDir, &header, 0))
+  strcpy(pLodDirectory.pFilename, "header.bin");
+  pLodDirectory.uDataSize = sizeof(SavegameHeader);
+  if (pNew_LOD->Write(&pLodDirectory, &header, 0))
   {
     sprintf(Str, pGlobalTXT_LocalizationStrings[612], 201);
     MessageBoxA(nullptr, Str, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\LoadSave.cpp:784", 0);
   }
-  strcpy(pDir.pFilename, "party.bin");
-  pDir.uDataSize = 90680;
-  if ( pNew_LOD->Write(&pDir, pParty, 0) )
+  strcpy(pLodDirectory.pFilename, "party.bin");
+  pLodDirectory.uDataSize = sizeof(Party); //90680;
+  if ( pNew_LOD->Write(&pLodDirectory, pParty, 0) )
   {
     sprintf(Str, pGlobalTXT_LocalizationStrings[612], 202);
     MessageBoxA(nullptr, Str, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\LoadSave.cpp:793", 0);
   }
-  strcpy(pDir.pFilename, "clock.bin");
-  pDir.uDataSize = 40;
-  if ( pNew_LOD->Write(&pDir, pEventTimer, 0) )
+  strcpy(pLodDirectory.pFilename, "clock.bin");
+  pLodDirectory.uDataSize =sizeof(Timer);// 40;
+  if ( pNew_LOD->Write(&pLodDirectory, pEventTimer, 0) )
   {
     sprintf(Str, pGlobalTXT_LocalizationStrings[612], 203);
     MessageBoxA(nullptr, Str, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\LoadSave.cpp:802", 0);
   }
-  strcpy(pDir.pFilename, "overlay.bin");
-  pDir.uDataSize = 1008;
-  if ( pNew_LOD->Write(&pDir, pOtherOverlayList, 0) )
+  strcpy(pLodDirectory.pFilename, "overlay.bin");
+  pLodDirectory.uDataSize =sizeof(OtherOverlayList);// 1008;
+  if ( pNew_LOD->Write(&pLodDirectory, pOtherOverlayList, 0) )
   {
     sprintf(Str, pGlobalTXT_LocalizationStrings[612], 204);
     MessageBoxA(nullptr, Str, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\LoadSave.cpp:811", 0);
   }
-  strcpy(pDir.pFilename, "npcdata.bin");
-  pDir.uDataSize = 501 * sizeof(NPCData);
-  assert(pDir.uDataSize == 38076);
-  if ( pNew_LOD->Write(&pDir, pNPCStats->pNewNPCData, 0) )
+  strcpy(pLodDirectory.pFilename, "npcdata.bin");
+  pLodDirectory.uDataSize = 501 * sizeof(NPCData);
+  assert(pLodDirectory.uDataSize == 38076);
+  if ( pNew_LOD->Write(&pLodDirectory, pNPCStats->pNewNPCData, 0) )
   {
     sprintf(Str, pGlobalTXT_LocalizationStrings[612], 205);
     MessageBoxA(nullptr, Str, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\LoadSave.cpp:820", 0);
   }
-  strcpy(pDir.pFilename, "npcgroup.bin");
-  pDir.uDataSize = 102;
-  if ( pNew_LOD->Write(&pDir, pNPCStats->pGroups_copy, 0) )
+  strcpy(pLodDirectory.pFilename, "npcgroup.bin");
+  pLodDirectory.uDataSize = 102;
+  if ( pNew_LOD->Write(&pLodDirectory, pNPCStats->pGroups_copy, 0) )
   {
     sprintf(Str, pGlobalTXT_LocalizationStrings[612], 206);
     MessageBoxA(nullptr, Str, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\LoadSave.cpp:829", 0);
@@ -406,13 +406,13 @@
         __debugbreak();
         sprintf(Str, "lloyd%d%d.pcx", i, j);
         fseek(v8, 0, 2);
-        pDir.uDataSize = ftell(v8);
+        pLodDirectory.uDataSize = ftell(v8);
         rewind(v8);
-        fread(DstBuf, pDir.uDataSize, 1, v8);
-        strcpy((char *)&pDir, Str);
+        fread(uncompressed_buff, pLodDirectory.uDataSize, 1, v8);
+        strcpy((char *)&pLodDirectory, Str);
         fclose(v8);
         remove(Str);
-        if ( pNew_LOD->Write(&pDir, DstBuf, 0) )
+        if ( pNew_LOD->Write(&pLodDirectory, uncompressed_buff, 0) )
         {
           sprintf(Str, pGlobalTXT_LocalizationStrings[612], 207);
           MessageBoxA(nullptr, Str, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\LoadSave.cpp:857", 0);
@@ -421,114 +421,100 @@
       }
 	}
   }
-  if ( !a2 )
+  if ( !NotSaveWorld )
   {
     //__debugbreak();
-    sub_42FA22_mess_with_laying_item_list();
-    v9 = (int)malloc(0xF4240);
-    v71 = (std::string *)v9;
-    Src = 91969;
-    v56 = 109;
-    v57 = 118;
-    v58 = 105;
-    v59 = 105;
-    v60 = 0;
-    v61 = 0;
-    memcpy((void *)v9, &Src, 0x10);
+    CompactLayingItemsList();
+    compressed_buf = (char*)malloc(1000000);
+  //  v71 = (std::string *)compressed_buf;
+    Src.uVersion = 91969;
+    Src.pMagic[0] = 'm';
+    Src.pMagic[1] = 'v';
+    Src.pMagic[2] = 'i';
+    Src.pMagic[3] = 'i';
+    Src.uCompressedSize = 0;
+    Src.uDecompressedSize = 0;
+    data_write_pos = uncompressed_buff;
+    memcpy((void *)compressed_buf, &Src, 0x10);
     if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
     {
       pIndoor->dlv.uNumFacesInBModels = pIndoor->uNumFaces;
       pIndoor->dlv.uNumBModels = 0;
       pIndoor->dlv.uNumDecorations = uNumLevelDecorations;
-      memcpy(DstBuf, &pIndoor->dlv, 0x28);
-      v10 = (char *)DstBuf + 40;
-      memcpy(v10, pIndoor->_visible_outlines, 0x36B);
-      v11 = (char *)v10 + 875;
-      if ( (signed int)pIndoor->uNumFaces > 0 )
-      {
-        v68 = 0;
-        for (int i =  0; i <= (signed int)pIndoor->uNumFaces; ++i)
+      memcpy(data_write_pos, &pIndoor->dlv, 0x28);
+      data_write_pos += 40;
+      memcpy(data_write_pos, pIndoor->_visible_outlines, 0x36B);
+      data_write_pos += 875;
+    
+        for (int i =  0; i <(signed int)pIndoor->uNumFaces; ++i)
         {
-		  v38 = &pIndoor->pFaces[i].uAttributes;//(char *)v68 + (unsigned int)pIndoor->pFaces + 44;
-          memcpy(v11, v38, 4);
-          v68 += 48;
-          v11 = (char *)v11 + 4;
+          memcpy(data_write_pos, &pIndoor->pFaces[i].uAttributes, 4);
+          data_write_pos += 4;
         }
-      }
-      if ( (signed int)uNumLevelDecorations > 0 )
-      {
-        v68 = &pLevelDecorations[0].field_2;
-        for (int i =  0; i <= (signed int)uNumLevelDecorations; ++i)
+
+        for (int i =  0; i <(signed int)uNumLevelDecorations; ++i)
         {
-          memcpy(v11, v68, 2);
-          v68 += 16;
-          v11 = (char *)v11 + 2;
+          memcpy(data_write_pos, &pLevelDecorations[i].field_2, 2);
+     
+          data_write_pos+= 2;
         }
-      }
-      memcpy(v11, &uNumActors, 4);
-      v12 = (char *)v11 + 4;
-      memcpy(v12, pActors, 836 * uNumActors);
-      v13 = (char *)v12 + 836 * uNumActors;
-      memcpy(v13, &uNumSpriteObjects, 4);
-      v13 = (char *)v13 + 4;
-      memcpy(v13, pSpriteObjects, 112 * uNumSpriteObjects);
-      v14 = (char *)v13 + 112 * uNumSpriteObjects;
-      memcpy(v14, &uNumChests, 4);
-      v14 = (char *)v14 + 4;
-      memcpy(v14, pChests, 5324 * uNumChests);
-      v15 = (char *)v14 + 5324 * uNumChests;
-      memcpy(v15, pIndoor->pDoors, 0x3E80);
-      v15 = (char *)v15 + 16000;
-      memcpy(v15, pIndoor->ptr_0002B4_doors_ddata, pIndoor->blv.uDoors_ddata_Size);
-      v16 = (char *)v15 + pIndoor->blv.uDoors_ddata_Size;
-      memcpy(v16, &stru_5E4C90, 0xC8);
-      v17 = (int)((char *)v16 + 200);
-      memcpy((void *)v17, &pIndoor->stru1, 0x38);
+      memcpy(data_write_pos, &uNumActors, 4);
+      data_write_pos += 4;
+      memcpy(data_write_pos, pActors, 836 * uNumActors);
+      data_write_pos += 836 * uNumActors;
+      memcpy(data_write_pos, &uNumSpriteObjects, 4);
+      data_write_pos += 4;
+      memcpy(data_write_pos, pSpriteObjects, 112 * uNumSpriteObjects);
+      data_write_pos += 112 * uNumSpriteObjects;
+      memcpy(data_write_pos, &uNumChests, 4);
+      data_write_pos += 4;
+      memcpy(data_write_pos, pChests, 5324 * uNumChests);
+      data_write_pos += 5324 * uNumChests;
+      memcpy(data_write_pos, pIndoor->pDoors, 0x3E80);
+      data_write_pos += 16000;
+      memcpy(data_write_pos, pIndoor->ptr_0002B4_doors_ddata, pIndoor->blv.uDoors_ddata_Size);
+      data_write_pos += pIndoor->blv.uDoors_ddata_Size;
+      memcpy(data_write_pos, &stru_5E4C90, 0xC8);
+      data_write_pos += 200;
+      memcpy(data_write_pos, &pIndoor->stru1, 0x38);
+      data_write_pos += 56;
+
     }
     else
     {
       v18 = 0;
       pOutdoor->ddm.uNumFacesInBModels = 0;
-      if ( (signed int)pOutdoor->uNumBModels > 0 )
-      {
-        v19 = pOutdoor->uNumBModels;
-		v20 = &pOutdoor->pBModels[0];
-        do
-        {
-		  v18 += v20->uNumFaces;
-          ++v20;
-          --v19;
-          pOutdoor->ddm.uNumFacesInBModels = v18;
-        }
-        while ( v19 );
-      }
-      v21 = DstBuf;
+      for (int i=0; i<pOutdoor->uNumBModels;++i)
+          {
+          v18 +=pOutdoor->pBModels[i].uNumFaces;
+          }
+      pOutdoor->ddm.uNumFacesInBModels = v18;
       pOutdoor->ddm.uNumBModels = pOutdoor->uNumBModels;
       pOutdoor->ddm.uNumDecorations = uNumLevelDecorations;
-      memcpy(DstBuf, &pOutdoor->ddm, 0x28);
-      v21 = (char *)v21 + 40;
-      memcpy(v21, pOutdoor->uUndiscoveredArea, 0x3C8);
-      v21 = (char *)v21 + 968;
-      memcpy(v21, pOutdoor->uDicovered_area, 0x3C8);
-      v22 = (char *)v21 + 968;
+      memcpy(data_write_pos, &pOutdoor->ddm, sizeof(DDM_DLV_Header));//0x28
+      data_write_pos += sizeof(DDM_DLV_Header);
+      memcpy(data_write_pos, pOutdoor->uUndiscoveredArea, 0x3C8);
+      data_write_pos += 968;
+      memcpy(data_write_pos, pOutdoor->uDicovered_area, 0x3C8);
+      data_write_pos += 968;
       if ( (signed int)pOutdoor->uNumBModels > 0 )
       {
         v23 = pOutdoor->pBModels;
         v24 = 76;
 		for (int i =  0; i < (signed int)pOutdoor->uNumBModels ; ++i)
         {
-		  v25 = v23[i].uNumFaces == 0;//*(int *)&v23->pModelName[v24] == 0;
-		  v26 = v23[i].uNumFaces < 0;//*(int *)&v23->pModelName[v24] < 0;
-          if ( !(v26 | v25) )
+		  //v25 = v23[i].uNumFaces == 0;//*(int *)&v23->pModelName[v24] == 0;
+		 // v26 = v23[i].uNumFaces < 0;//*(int *)&v23->pModelName[v24] < 0;
+          if ( pOutdoor->pBModels[i].uNumFaces>0)
           {
             v68 = 0;
 			for (int j =  0; j < pOutdoor->pBModels[i].uNumFaces;++j)//*(int *)&pOutdoor->pBModels->pModelName[v24]; ++j)
             {
 			  v38 = &(v23[i].pFaces[j].uAttributes); //(char *)v68 + *(int *)&v23->pModelName[v24 + 8] + 28;				 
-              memcpy(v22, v38, 4);
+              memcpy(data_write_pos, v38, 4);
               v23 = pOutdoor->pBModels;
               v68 += 154;
-              v22 = (char *)v22 + 4;
+              data_write_pos += 4;
             }
            }
           v24 += 188;
@@ -539,55 +525,56 @@
         v66 = &pLevelDecorations[0].field_2;
         for (int i = 0; i <= (signed int)uNumLevelDecorations; ++i)
         {
-          memcpy(v22, v66, 2);
+          memcpy(data_write_pos, v66, 2);
           v66 += 16;
-          v22 = (char *)v22 + 2;
+          data_write_pos += 2;
         }
       }
-      memcpy(v22, &uNumActors, 4);
-      v28 = (char *)v22 + 4;
-      memcpy(v28, pActors, 836 * uNumActors);
-      v29 = (char *)v28 + 836 * uNumActors;
-      memcpy(v29, &uNumSpriteObjects, 4);
-      v29 = (char *)v29 + 4;
-      memcpy(v29, pSpriteObjects, 112 * uNumSpriteObjects);
-      v30 = (char *)v29 + 112 * uNumSpriteObjects;
-      memcpy(v30, &uNumChests, 4);
-      v30 = (char *)v30 + 4;
-      memcpy(v30, pChests, 5324 * uNumChests);
-      v31 = (char *)v30 + 5324 * uNumChests;
-      memcpy(v31, &stru_5E4C90, 0xC8);
-      v17 = (int)((char *)v31 + 200);
-      memcpy((void *)v17, &pOutdoor->uLastVisitDay, 0x38);
-      v9 = (int)v71;
+      memcpy(data_write_pos, &uNumActors, 4);
+      data_write_pos += 4;
+      memcpy(data_write_pos, pActors, 836 * uNumActors);
+      data_write_pos +=  836 * uNumActors;
+      memcpy(data_write_pos, &uNumSpriteObjects, 4);
+      data_write_pos += 4;
+      memcpy(data_write_pos, pSpriteObjects, 112 * uNumSpriteObjects);
+      data_write_pos += 112 * uNumSpriteObjects;
+      memcpy(data_write_pos, &uNumChests, 4);
+      data_write_pos += 4;
+      memcpy(data_write_pos, pChests, 5324 * uNumChests);
+      data_write_pos += 5324 * uNumChests;
+      memcpy(data_write_pos, &stru_5E4C90, 0xC8);
+      data_write_pos += 200;
+      memcpy(data_write_pos, &pOutdoor->loc_time, 0x38);
+      data_write_pos += 56;
+
+      //compressed_buf = (int)v71;
     }
-    v32 = v17 + 56;
     strcpy(Source, pCurrentMapName);
     _splitpath(Source, Drive, Dir, Filename, Ext);
     v48 = 100;
-    Size = v32 - (int)DstBuf;
-    v69 = 999984;
-    LOBYTE(v33) = zlib::MemZip((char *)v9 + 16, (unsigned int *)&v69, DstBuf, v32 - (int)DstBuf);
-    if ( v33 || (signed int)v69 > (signed int)Size )
+    Size = (int)data_write_pos - (int)uncompressed_buff;
+    compressed_block_size = 999984;
+    LOBYTE(v33) = zlib::MemZip((char *)compressed_buf + 16, (unsigned int *)&compressed_block_size, uncompressed_buff,Size);
+    if ( v33 || (signed int)compressed_block_size > (signed int)Size )
     {
-      memcpy((void *)(v9 + 16), DstBuf, Size);
-      v69 = Size;
+      memcpy((void *)(compressed_buf + 16), uncompressed_buff, Size);
+      compressed_block_size = Size;
     }
-    v69 += 16;
-    memcpy((void *)(v9 + 8), &v69, 4);
-    memcpy((void *)(v9 + 12), &Size, 4);
+    compressed_block_size += 16;
+    memcpy(&((ODMHeader *)compressed_buf)->uCompressedSize, &compressed_block_size, 4);
+    memcpy(&((ODMHeader *)compressed_buf)->uDecompressedSize, &Size, 4);
     sprintf(Source, "%s%s", &Filename, &Ext);
-    strcpy((char *)&pDir, Source);
-    pDir.uDataSize = v69;
-    if ( pNew_LOD->Write(&pDir, (const void *)v9, 0) )
+    strcpy((char *)&pLodDirectory, Source);
+    pLodDirectory.uDataSize = compressed_block_size;
+    if ( pNew_LOD->Write(&pLodDirectory, (const void *)compressed_buf, 0) )
     {
       sprintf(Str, pGlobalTXT_LocalizationStrings[612], 208);
       MessageBoxA(nullptr, Str, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\LoadSave.cpp:1071", 0);
     }
-    free((void *)v9);
+    free((void *)compressed_buf);
   }
-  free(DstBuf);
-  if ( a1 )
+  free(uncompressed_buff);
+  if ( IsAutoSAve )
   {
     if ( !CopyFileA("data\\new.lod", "saves\\autosave.mm7", 0) )
     {
@@ -602,9 +589,7 @@
   pParty->vPosition.z = v62;
   pParty->uFallStartY = v62;
   pParty->sRotationY = v53;
-  result = v54;
   pParty->sRotationX = v54;
-  return result;
 }
 
 
--- a/SpriteObject.cpp	Tue Mar 26 23:18:58 2013 +0600
+++ b/SpriteObject.cpp	Tue Mar 26 23:19:12 2013 +0600
@@ -17,7 +17,7 @@
 #include "mm7_data.h"
 
 size_t uNumSpriteObjects;
-SpriteObject pSpriteObjects[1000];
+SpriteObject pSpriteObjects[MAX_SPRITE_OBJECTS];
 
 //----- (00404828) --------------------------------------------------------
 SpriteObject::SpriteObject()
@@ -34,9 +34,9 @@
   field_60_distance_related_prolly_lod = 0;
   field_20 = 0;
   uSpriteFrameID = 0;
-  field_50 = 0;
-  field_4C = 0;
-  field_48 = 0;
+  spell_skill = 0;
+  spell_level = 0;
+  spell_id = 0;
   field_54 = 0;
 }
 
@@ -83,7 +83,7 @@
     v21 = v6;
   }
   while ( (signed int)v7 < (signed int)((char *)&pObjectList->uNumObjects + 2) );*/
-  for (uint i = 0; i < 1000; ++i)
+  for (uint i = 0; i < MAX_SPRITE_OBJECTS; ++i)
     if (!pSpriteObjects[i].uObjectDescID)
     {
       v6 = i;
@@ -408,11 +408,11 @@
       v58 = v16;
       v18 = WorldPosToGridCellX(v17);
       _46E26D_collide_against_sprites(v18, v58);
-      if ( (v1->field_58_pid & 7) != OBJECT_Player)
+      if ( (v1->spell_caster_pid & 7) != OBJECT_Player)
         _46EF01_collision_chech_player(0);
-      if ( (v1->field_58_pid & 7) == OBJECT_Actor)
+      if ( (v1->spell_caster_pid & 7) == OBJECT_Actor)
       {
-        v19 = v1->field_58_pid >> 3;
+        v19 = v1->spell_caster_pid >> 3;
         if ( v19 >= 0 )
         {
           if ( v19 < (signed int)(uNumActors - 1) )
@@ -698,9 +698,9 @@
       {
         _46E44E_collide_against_faces_and_portals(0);
         _46E0B2_collide_against_decorations();
-        if ( (pSpriteObject->field_58_pid & 7) != OBJECT_Player)
+        if ( (pSpriteObject->spell_caster_pid & 7) != OBJECT_Player)
           _46EF01_collision_chech_player(1);
-        v13 = pSpriteObject->field_58_pid;
+        v13 = pSpriteObject->spell_caster_pid;
         v42 = v8;
         if ( (v13 & 7) == OBJECT_Actor)
         {
@@ -713,7 +713,7 @@
               //v14 = (signed __int64)((double)v41 * 0.3333333333333333);
               //v41 = *(short *)(v39 - 38) - 1;
               //if ( v14 != (unsigned int)(signed __int64)((double)v41 * 0.3333333333333333) )
-				if( pActors[pSpriteObject->field_58_pid >> 3].pMonsterInfo.uID != v39b->pMonsterInfo.uID )
+				if( pActors[pSpriteObject->spell_caster_pid >> 3].pMonsterInfo.uID != v39b->pMonsterInfo.uID )
 					//not sure: pMonsterList->pMonsters[v39b->word_000086_some_monster_id-1].uToHitRadius
 					_46DF1A_collide_against_actor(v42, *((short *)&pMonsterList->pMonsters[v39b->word_000086_some_monster_id] - 73));
               ++v42;
@@ -1100,3 +1100,17 @@
     }
   }
 }
+
+
+//----- (0042FA22) --------------------------------------------------------
+void CompactLayingItemsList()
+    {
+    int new_obj_pos=0;
+
+    for (int i=0; i<MAX_SPRITE_OBJECTS; ++i)
+        {
+        if (pSpriteObjects[i].uObjectDescID)
+            memcpy(&pSpriteObjects[new_obj_pos++], &pSpriteObjects[i],sizeof(SpriteObject));
+        }
+    uNumSpriteObjects = new_obj_pos;
+    }
\ No newline at end of file
--- a/SpriteObject.h	Tue Mar 26 23:18:58 2013 +0600
+++ b/SpriteObject.h	Tue Mar 26 23:19:12 2013 +0600
@@ -7,7 +7,7 @@
   OBJECT_ATTACHED_TO_ACTOR = 0x80,
 };
 
-
+#define MAX_SPRITE_OBJECTS 1000
 /*   72 */
 #pragma pack(push, 1)
 struct SpriteObject
@@ -36,12 +36,12 @@
   __int16 field_20;
   __int16 field_22_glow_radius_multiplier;
   struct ItemGen stru_24;
-  int field_48;
-  int field_4C;
-  int field_50;
+  int spell_id;
+  int spell_level;
+  int spell_skill;
   int field_54;
-  int field_58_pid;
-  int field_5C;
+  int spell_caster_pid;
+  int spell_target_pid;
   char field_60_distance_related_prolly_lod;
   char field_61;
   char field_62[2];
@@ -52,4 +52,4 @@
 
 
 extern size_t uNumSpriteObjects;
-extern SpriteObject pSpriteObjects[1000];
\ No newline at end of file
+extern SpriteObject pSpriteObjects[MAX_SPRITE_OBJECTS];
\ No newline at end of file
--- a/Time.cpp	Tue Mar 26 23:18:58 2013 +0600
+++ b/Time.cpp	Tue Mar 26 23:19:12 2013 +0600
@@ -2,6 +2,7 @@
 
 #include "Time.h"
 #include "Keyboard.h"
+#include "Log.h"
 
 #include "mm7_data.h"
 
@@ -20,7 +21,7 @@
 //----- (00426317) --------------------------------------------------------
 unsigned __int64 Timer::Time()
 {
-  uint v2 = (timeGetTime() << 7) / 0x3E8;
+  uint v2 = (timeGetTime() * 128) / 1000;
   if (v2 < uStartTime)
     uStartTime = 0;
   return v2;
@@ -75,27 +76,25 @@
 //----- (004263B7) --------------------------------------------------------
 void Timer::Update()
 {
-  Timer *v1; // esi@1
-  unsigned int v2; // eax@2
-  signed int v3; // eax@3
-  char v4; // zf@5
+  //Timer *v1; // esi@1
+  //unsigned int v2; // eax@2
+  //signed int v3; // eax@3
+  //char v4; // zf@5
+
+
+  unsigned __int64 new_time = Time();
+  while (new_time <= uStartTime)
+    new_time = Time();
 
-  v1 = this;
-  do
-  {
-    v2 = Time() - v1->uStartTime;
-    v1->uTimeElapsed = v2;
-  }
-  while ( (signed int)v2 <= 0 );
-  v1->uStartTime = Time();
-  v3 = v1->uTimeElapsed;
-  if ( v3 > 32 )
-    v3 = 32;
-  v4 = v1->bPaused == 0;
-  v1->uTimeElapsed = v3;
-  if ( v4 && !v1->bTackGameTime )
-    v1->uTotalGameTimeElapsed += v3;
-  v1->dt_in_some_format = (v3 << 16) / 128;
+  uTimeElapsed = new_time - uStartTime;
+  uStartTime = new_time;
+
+  if (uTimeElapsed > 32)
+    uTimeElapsed = 32;
+
+  if (!bPaused && !bTackGameTime)
+    uTotalGameTimeElapsed += uTimeElapsed;
+  dt_in_some_format = (uTimeElapsed << 16) / 128;
 }
 
 //----- (00426402) --------------------------------------------------------
--- a/Time.h	Tue Mar 26 23:18:58 2013 +0600
+++ b/Time.h	Tue Mar 26 23:19:12 2013 +0600
@@ -1,6 +1,8 @@
 #pragma once
 
 
+
+
 /*   61 */
 #pragma pack(push, 1)
 struct Timer
--- a/UIBooks.cpp	Tue Mar 26 23:18:58 2013 +0600
+++ b/UIBooks.cpp	Tue Mar 26 23:19:12 2013 +0600
@@ -429,13 +429,13 @@
   if ( !byte_5C6D50[dword_506528] )
   {
     v2 = achievedAwardsIndex[dword_506528];
-    a1.uFrameWidth = 460;
-    a1.uFrameX = 8;
-    a1.uFrameY = 8;
-    a1.uFrameHeight = 344;
+    a1.uFrameWidth = game_viewport_width;
+    a1.uFrameX = game_viewport_x;
+    a1.uFrameY = game_viewport_y;
+    a1.uFrameHeight = game_viewport_height;
     v3 = (const char *)pStorylineText->StoreLine[v2].pPageTitle;//field_4[];
-    a1.uFrameZ = 467;
-    a1.uFrameW = 351;
+    a1.uFrameZ = game_viewport_z;
+    a1.uFrameW = game_viewport_w;
     if ( v3 )
       a1.DrawTitleText(pBook2Font, 0, 0x16u, 0, v3, 3u);
   }
@@ -532,12 +532,12 @@
     v1 = pViewport->uViewportTL_X + 398;
   }
   pRenderer->DrawTextureTransparent(v1, v9, v11);
-  a1.uFrameWidth = 460;
-  a1.uFrameHeight = 344;
-  a1.uFrameX = 8;
-  a1.uFrameY = 8;
-  a1.uFrameZ = 467;
-  a1.uFrameW = 351;
+  a1.uFrameWidth = game_viewport_width;
+  a1.uFrameHeight = game_viewport_height;
+  a1.uFrameX = game_viewport_x;
+  a1.uFrameY = game_viewport_y;
+  a1.uFrameZ = game_viewport_z;
+  a1.uFrameW = game_viewport_w;
   a1.DrawTitleText(pBook2Font, 0, 0x16u, 0, pGlobalTXT_LocalizationStrings[174], 3u);
   a1.uFrameX = 48;
   a1.uFrameY = 70;
@@ -796,12 +796,12 @@
   v7 = pViewport->uViewportTL_X + 397;
 LABEL_46:
   pRenderer->DrawTextureTransparent(v7, v23, v30);
-  a1.uFrameWidth = 460;
-  a1.uFrameHeight = 344;
-  a1.uFrameX = 8;
-  a1.uFrameY = 8;
-  a1.uFrameZ = 467;
-  a1.uFrameW = 467;
+  a1.uFrameWidth = game_viewport_width;
+  a1.uFrameHeight = game_viewport_height;
+  a1.uFrameX = game_viewport_x;
+  a1.uFrameY = game_viewport_z;
+  a1.uFrameZ = game_viewport_z;
+  a1.uFrameW = game_viewport_w;
   a1.DrawTitleText(pBook2Font, 0, 0x16u, 0, pGlobalTXT_LocalizationStrings[154], 3u);
   a1.uFrameX = 48;
   a1.uFrameY = 70;
@@ -1004,12 +1004,12 @@
   dword_506540 = 0;
   DrawBook_Map_sub(97, 49, 361, 313, 0);
   pRenderer->DrawTextureTransparent(75, 22, pTexture_mapbordr);
-  map_window.uFrameWidth = 460;
-  map_window.uFrameHeight = 344;
-  map_window.uFrameX = 8;
-  map_window.uFrameY = 8;
-  map_window.uFrameZ = 467;
-  map_window.uFrameW = 467;
+  map_window.uFrameWidth = game_viewport_width;
+  map_window.uFrameHeight = game_viewport_height;
+  map_window.uFrameX = game_viewport_x;
+  map_window.uFrameY = game_viewport_y;
+  map_window.uFrameZ = game_viewport_z;
+  map_window.uFrameW = game_viewport_w;
   map_id = pMapStats->GetMapInfo(pCurrentMapName);
   if ( map_id )
     map_window.DrawTitleText(pBook2Font, -14, 12, 0, pMapStats->pInfos[map_id].pName, 3);
--- a/UICharacter.cpp	Tue Mar 26 23:18:58 2013 +0600
+++ b/UICharacter.cpp	Tue Mar 26 23:19:12 2013 +0600
@@ -2375,9 +2375,9 @@
                                                                             }
 LABEL_209:
                                                                         if ( pPlayer->pEquipment.uMainHand
-                                                                            && (pPlayer->GetEquippedItemEquipType(1u) == 1
-                                                                            || pPlayer->GetEquippedItemSkillType(EQUIP_TWO_HANDED) == 4
-                                                                            && !pPlayer->pEquipment.uOffHand) )
+                                                                            && (pPlayer->GetEquippedItemEquipType(EQUIP_MAIN_HAND) == EQUIP_MAIN_HAND ||
+                                                                                pPlayer->GetEquippedItemSkillType(EQUIP_MAIN_HAND) == EQUIP_SHIELD &&
+                                                                                !pPlayer->pEquipment.uOffHand) )
                                                                             {
                                                                             v91 = 17 * pBodyComplection + v90;
                                                                             v92 = v91;
--- a/UIHouses.cpp	Tue Mar 26 23:18:58 2013 +0600
+++ b/UIHouses.cpp	Tue Mar 26 23:19:12 2013 +0600
@@ -2597,7 +2597,7 @@
       __debugbreak();
       pOutString = pFontArrus;
       strcpy(pTmpBuf, pNPCTopics[354].pText);
-      dialog_window.uFrameWidth = 460;
+      dialog_window.uFrameWidth = game_viewport_width;
       dialog_window.uFrameZ = 452;
       pTextHeight = pFontArrus->CalcTextHeight(pTmpBuf, &dialog_window, 12, 0) + 7;
       if ( 352 - pTextHeight < 8 )
@@ -2616,7 +2616,7 @@
     {
       __debugbreak();
       strcpy(pTmpBuf, pNPCTopics[(uint)window_SpeakInHouse->ptr_1C + 247].pText);
-      dialog_window.uFrameWidth = 460;
+      dialog_window.uFrameWidth = game_viewport_width;
       dialog_window.uFrameZ = 452;
       v61 = pFontArrus->CalcTextHeight(pTmpBuf, &dialog_window, 12, 0);
       pTextHeight = v61 + 7;
--- a/UIHouses.h	Tue Mar 26 23:18:58 2013 +0600
+++ b/UIHouses.h	Tue Mar 26 23:19:12 2013 +0600
@@ -1,5 +1,4 @@
 #pragma once
-
 #include "stru159.h"
 
 enum HOUSE_DIALOGUE_MENU: unsigned __int32
--- a/UIPartyCreation.cpp	Tue Mar 26 23:18:58 2013 +0600
+++ b/UIPartyCreation.cpp	Tue Mar 26 23:19:12 2013 +0600
@@ -172,13 +172,13 @@
   unsigned int v34; // eax@44
   int v35; // eax@44
   unsigned int v36; // eax@44
-  enum PLAYER_SKILL_TYPE v37; // eax@44
-  enum PLAYER_SKILL_TYPE v39; // eax@44
-  enum PLAYER_SKILL_TYPE v41; // eax@44
+  PLAYER_SKILL_TYPE v37; // eax@44
+  PLAYER_SKILL_TYPE v39; // eax@44
+  PLAYER_SKILL_TYPE v41; // eax@44
   const char *v42; // edx@44
   char *v43; // ST1C_4@44
   int v45; // eax@44
-  enum PLAYER_SKILL_TYPE v46; // eax@46
+  PLAYER_SKILL_TYPE v46; // eax@46
   const char *v47; // edx@46
   char *v48; // ST1C_4@46
   int v50; // eax@46
@@ -197,7 +197,7 @@
   int v85; // eax@65
   int v89; // eax@67
   int v94; // eax@69
-  enum PLAYER_SKILL_TYPE pSkillId; // edi@72
+  PLAYER_SKILL_TYPE pSkillId; // edi@72
   size_t pLenText; // eax@72
   signed int v104; // ecx@72
   int pColorText; // ecx@79
--- a/UIPopup.cpp	Tue Mar 26 23:18:58 2013 +0600
+++ b/UIPopup.cpp	Tue Mar 26 23:19:12 2013 +0600
@@ -406,8 +406,8 @@
     //v20 = item_desc->uEquipType;
     switch (item_desc->uEquipType)
         {
-    case EQUIP_ONE_OR_TWO_HANDS:
-    case EQUIP_TWO_HANDED:
+    case EQUIP_OFF_HAND:
+    case EQUIP_MAIN_HAND:
         sprintfex(out_text + 100, "%s: +%d   %s: %dd%d", pGlobalTXT_LocalizationStrings[LOCSTR_ATTACK],
             (int)item_desc->uDamageMod, pGlobalTXT_LocalizationStrings[53], (int)item_desc->uDamageDice, (int)item_desc->uDamageRoll); //"Damage"
         if (item_desc->uDamageMod)
@@ -1430,8 +1430,8 @@
 
 
 //----- (00417BB5) --------------------------------------------------------
-const char *__fastcall CharacterUI_GetSkillDescText(unsigned int uPlayerID, enum PLAYER_SKILL_TYPE uPlayerSkillType)
-    {
+const char *__fastcall CharacterUI_GetSkillDescText(unsigned int uPlayerID, PLAYER_SKILL_TYPE uPlayerSkillType)
+{
     //enum PLAYER_SKILL_TYPE v2; // esi@1
     //unsigned int v3; // ebx@1
     int v4; // edi@1
@@ -1442,10 +1442,10 @@
     unsigned int v9; // eax@8
     unsigned int v10; // eax@8
     unsigned int v11; // eax@8
-    enum PLAYER_SKILL_TYPE v12; // edi@8
+    PLAYER_SKILL_TYPE v12; // edi@8
     unsigned int v13; // eax@8
     unsigned int v14; // eax@8
-    enum PLAYER_SKILL_TYPE v15; // esi@8
+    PLAYER_SKILL_TYPE v15; // esi@8
     int v16; // edi@8
     char v17; // al@8
     int v18; // ST5C_4@8
@@ -1458,7 +1458,7 @@
     unsigned int v25; // eax@9
     unsigned int v26; // eax@9
     unsigned int v27; // ecx@9
-    enum PLAYER_SKILL_TYPE v28; // ebx@9
+    PLAYER_SKILL_TYPE v28; // ebx@9
     unsigned int v29; // eax@9
     char a2[1200]; // [sp+Ch] [bp-538h]@7
     char Source[120]; // [sp+4BCh] [bp-88h]@7
@@ -1600,7 +1600,7 @@
                 && (signed int)v1 >= (signed int)i->uY
                 && (signed int)v1 <= (signed int)i->uW )
                 {
-                v3 = CharacterUI_GetSkillDescText(uActiveCharacter - 1, (enum PLAYER_SKILL_TYPE)i->uControlParam);
+                v3 = CharacterUI_GetSkillDescText(uActiveCharacter - 1, (PLAYER_SKILL_TYPE)i->uControlParam);
                 sub_4179BC_draw_tooltip(pSkillNames[i->uControlParam], v3);
                 v1 = pY;
                 v0 = pX;
@@ -1906,7 +1906,7 @@
         a1.uFrameHeight += v6;
         if ( (signed int)a1.uFrameHeight < 150 )
             a1.uFrameHeight = 150;
-        a1.uFrameWidth = 460;
+        a1.uFrameWidth = game_viewport_width;
         a1.DrawMessageBox(0);
         a1.uFrameWidth -= 12;
         a1.uFrameHeight -= 12;
@@ -1948,7 +1948,7 @@
         signed int pControlID; // eax@92
         int v16; // eax@95
         int v17; // eax@96
-        enum PLAYER_SKILL_TYPE v18; // eax@98
+        PLAYER_SKILL_TYPE v18; // eax@98
         char *pStr2; // eax@99
         unsigned int v20; // eax@108
         unsigned int pSkillId; // eax@109
@@ -2261,7 +2261,7 @@
                         pY = 0;
                         if ( (signed int)pSkillId < 37 )
                             {
-                            pSkillInfo = CharacterUI_GetSkillDescText(pButton->uControlParam, (enum PLAYER_SKILL_TYPE)pSkillId);
+                            pSkillInfo = CharacterUI_GetSkillDescText(pButton->uControlParam, (PLAYER_SKILL_TYPE)pSkillId);
                             strcpy(pTmpBuf2, pSkillInfo);
                             pWindow.Hint = pTmpBuf2;
                             pStr = pSkillNames[pSkillId];
--- a/Weather.h	Tue Mar 26 23:18:58 2013 +0600
+++ b/Weather.h	Tue Mar 26 23:19:12 2013 +0600
@@ -1,7 +1,17 @@
 #pragma once
 
 
-
+#pragma pack(push, 1)
+struct LocationTime_stru1
+    {
+    unsigned __int64 uLastVisitDay;
+    char sky_texture_name[12];
+    int day_attrib;
+    int day_fogrange_1;
+    int day_fogrange_2;
+    char field_2F4[24];
+    };
+#pragma pack(pop)
 
 
 
--- a/mm7_1.cpp	Tue Mar 26 23:18:58 2013 +0600
+++ b/mm7_1.cpp	Tue Mar 26 23:19:12 2013 +0600
@@ -813,7 +813,7 @@
 			}
 		  }
 		}
-		a1.field_58_pid = OBJECT_Player;
+		a1.spell_caster_pid = OBJECT_Player;
 		a1.uObjectDescID = v6;
 		a1.vPosition.y = pParty->vPosition.y;
 		a1.vPosition.x = pParty->vPosition.x;
@@ -1217,7 +1217,7 @@
 			}
 			a1.uObjectDescID = v6;
 			a1.vPosition.y = pParty->vPosition.y;
-			a1.field_58_pid = OBJECT_Player;
+			a1.spell_caster_pid = OBJECT_Player;
 			a1.vPosition.x = pParty->vPosition.x;
 			a1.vPosition.z = pParty->sEyelevel + pParty->vPosition.z;
 			a1.uSoundID = 0;
--- a/mm7_2.cpp	Tue Mar 26 23:18:58 2013 +0600
+++ b/mm7_2.cpp	Tue Mar 26 23:19:12 2013 +0600
@@ -562,7 +562,7 @@
   v26 = 0;
   pParty->field_7B5_in_arena_quest = uDialogueType;
   memcpy(&window, pDialogueWindow, sizeof(window));
-  window.uFrameWidth = 460;
+  window.uFrameWidth = game_viewport_width;
   window.uFrameZ = 452;
   v0 = pFontArrus->CalcTextHeight(pGlobalTXT_LocalizationStrings[575], &window, 13, 0) + 7;
   pRenderer->BeginSceneD3D();
@@ -4303,11 +4303,11 @@
   a1a.uFacing = 0;
   a1a.vPosition.z = a2->vPosition.z;
   a1a.vPosition.x = a2->vPosition.x;
-  a1a.field_50 = 0;
-  a1a.field_4C = 0;
-  a1a.field_48 = 0;
-  a1a.field_5C = 0;
-  a1a.field_58_pid = 0;
+  a1a.spell_skill = 0;
+  a1a.spell_level = 0;
+  a1a.spell_id = 0;
+  a1a.spell_target_pid = 0;
+  a1a.spell_caster_pid = 0;
   a1a.uSpriteFrameID = 0;
   a1a.uSectorID = pIndoor->GetSector(a2->vPosition.x, a2->vPosition.y, a2->vPosition.z);;
   return a1a.Create(0, 0, 0, 0);
@@ -6256,20 +6256,20 @@
 }
 
 //----- (0045E03A) --------------------------------------------------------
-unsigned __int16 *__fastcall MakeScreenshot(signed int width, signed int height)
-{
-  signed int v2; // edi@1
+unsigned short * MakeScreenshot( signed int width, signed int height )
+{
+  //signed int v2; // edi@1
   unsigned __int16 *v3; // ebx@1
   int v4; // edx@7
   unsigned __int8 v5; // cf@9
   unsigned int v6; // ecx@9
   unsigned __int16 *v7; // edi@9
   int j; // ecx@9
-  unsigned __int16 *v9; // edi@15
-  int v10; // ecx@15
-  LONG v11; // esi@15
-  signed __int64 v12; // qax@18
-  unsigned int v13; // ST10_4@21
+  //unsigned __int16 *v9; // edi@15
+  //int v10; // ecx@15
+  //LONG v11; // esi@15
+  //signed __int64 v12; // qax@18
+  //unsigned int v13; // ST10_4@21
   HRESULT v14; // eax@21
   int v15; // edi@29
   signed __int64 v16; // qax@30
@@ -6282,76 +6282,79 @@
   unsigned __int16 *_this; // [sp+88h] [bp-1Ch]@21
   float v25; // [sp+8Ch] [bp-18h]@1
   unsigned int v26; // [sp+90h] [bp-14h]@17
-  int v27; // [sp+94h] [bp-10h]@1
+  //int v27; // [sp+94h] [bp-10h]@1
   int v28; // [sp+98h] [bp-Ch]@16
-  int i; // [sp+9Ch] [bp-8h]@15
-  int v30; // [sp+A0h] [bp-4h]@1
-
-  v30 = width;
-  v2 = height;
-  v27 = height;
-  v23 = 452.0 / (double)width;
-  v25 = 336.0 / (double)height;
+  int v29; // [sp+9Ch] [bp-8h]@15
+  //int v30; // [sp+A0h] [bp-4h]@1
+
+  //v30 = width;
+  //v2 = height;
+  //v27 = height;
+  v23 = game_viewport_width / (double)width;
+  v25 = game_viewport_height / (double)height;
+
   pPixels = (unsigned __int16 *)malloc(2 * height * width);
+  memset(pPixels, 0 , 2 * height * width);
+
   v3 = pPixels;
   if ( pRenderer->pRenderD3D )
   {
     pRenderer->BeginSceneD3D();
-    if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
-    {
+
+    if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
       pIndoor->Draw();
-    }
-    else
-    {
-      if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor )
-        pOutdoor->Draw();
-    }
+    else if (uCurrentlyLoadedLevelType == LEVEL_Outdoor)
+      pOutdoor->Draw();
+
     pRenderer->DrawBillboards_And_MaybeRenderSpecialEffects_And_EndScene();
     memset(&Dst, 0, 0x7Cu);
-    Dst.dwSize = 124;
+    Dst.dwSize = sizeof(Dst);
+
     if ( pRenderer->LockSurface_DDraw4(pRenderer->pBackBuffer4, &Dst, DDLOCK_WAIT) )
     {
-      v9 = (unsigned __int16 *)Dst.lpSurface;
-      v10 = 0;
-      v11 = Dst.lPitch >> 1;
-      for ( i = 0; i < v27; ++i )
-      {
-        v28 = v10;
-        if ( v30 > v10 )
-        {
-          v26 = v11 * (unsigned __int64)(signed __int64)((double)i * v25 + 8.0);
-          do
-          {
-            v12 = (signed __int64)((double)v28++ * v23 + 8.0);
-            *v3 = v9[v26 + (int)v12];
-            ++v3;
-          }
-          while ( v28 < v30 );
-          v10 = 0;
-        }
-      }
-      v13 = v10;
+      auto src = (unsigned __int16 *)Dst.lpSurface;
+      auto src_width = (Dst.lPitch / sizeof(short));
+      auto src_height = Dst.dwHeight;
+      auto dst = pPixels;
+      for (uint y = 0; y < height; ++y)
+      {
+        //uint src_y = (game_viewport_y + y * v25) * (Dst.lPitch / sizeof(short));
+        uint src_y = game_viewport_y + y * v25;
+        assert(game_viewport_y + y * v25 < src_height);
+        assert(y < height);
+
+        for (uint x = 0; x < width; ++x)
+        {
+          //uint src_x = game_viewport_x + x * v23;
+          uint src_x = game_viewport_x + x * v23;
+          assert(src_x < src_width);
+          assert(x < width);
+
+          dst[y * width + x] = (((63*y)/117) << 5) | 31*x/155;//31*y/117;//src[src_y * src_width + src_x];
+        }
+      }
       ErrD3D(pRenderer->pBackBuffer4->Unlock(0));
     }
     else
     {
-      v4 = v27;
-      if ( v27 > 0 )
+      __debugbreak(); // unrefactored
+      v4 = height;
+      if ( height > 0 )
       {
         do
         {
-          if ( v30 > 0 )
-          {
-            v5 = v30 & 1;
-            v6 = (unsigned int)v30 >> 1;
-            memset(v3, 0, 4 * ((unsigned int)v30 >> 1));
+          if ( width > 0 )
+          {
+            v5 = width & 1;
+            v6 = (unsigned int)width >> 1;
+            memset(v3, 0, 4 * ((unsigned int)width >> 1));
             v7 = &v3[2 * v6];
             for ( j = v5; j; --j )
             {
               *v7 = 0;
               ++v7;
             }
-            v3 += v30;
+            v3 += width;
           }
           --v4;
         }
@@ -6375,45 +6378,45 @@
     v26 = pRenderer->uTargetSurfacePitch;
     if ( pRenderer->pTargetSurface )
     {
-      i = 0;
-      if ( v2 > 0 )
+      v29 = 0;
+      if ( height > 0 )
       {
         do
         {
           v28 = 0;
-          if ( v30 > 0 )
-          {
-            v15 = v26 * (unsigned __int64)(signed __int64)((double)i * v25 + 8.0);
+          if ( width > 0 )
+          {
+            v15 = v26 * (unsigned __int64)(signed __int64)((double)v29 * v25 + 8.0);
             do
             {
               v16 = (signed __int64)((double)v28++ * v23 + 8.0);
               *v3 = _this[v15 + (int)v16];
               ++v3;
             }
-            while ( v28 < v30 );
-          }
-          ++i;
-        }
-        while ( i < v27 );
+            while ( v28 < width );
+          }
+          ++v29;
+        }
+        while ( v29 < height );
       }
     }
     else
     {
-      if ( v2 > 0 )
-      {
-        v17 = v2;
+      if ( height > 0 )
+      {
+        v17 = height;
         do
         {
-          if ( v30 > 0 )
-          {
-            memset(v3, 0, 4 * ((unsigned int)v30 >> 1));
-            v18 = &v3[2 * ((unsigned int)v30 >> 1)];
-            for ( k = v30 & 1; k; --k )
+          if ( width > 0 )
+          {
+            memset(v3, 0, 4 * ((unsigned int)width >> 1));
+            v18 = &v3[2 * ((unsigned int)width >> 1)];
+            for ( k = width & 1; k; --k )
             {
               *v18 = 0;
               ++v18;
             }
-            v3 += v30;
+            v3 += width;
           }
           --v17;
         }
@@ -6547,7 +6550,7 @@
     pParty->vPosition.y = 1816;
     pParty->sPrevRotationY = 512;
     pParty->sRotationY = 512;
-    SaveGame(1, (__int16 *)1);
+    SaveGame(1, 1);
   }
   pAllocator->FreeChunk(pSave);
 }
@@ -9199,10 +9202,12 @@
   //_getcwd(v5, 120);
   //sprintfex(pIniFilename, "%s\\mm6.ini", v5);
   viewparams = new ViewingParams;
-  viewparams->uScreen_topL_X = GetPrivateProfileIntW(L"screen", L"vx1", 8, pIniFilename);
-  viewparams->uScreen_topL_Y = GetPrivateProfileIntW(L"screen", L"vy1", 8, pIniFilename);
-  viewparams->uScreen_BttmR_X = GetPrivateProfileIntW(L"screen", L"vx2", 468, pIniFilename);
-  viewparams->uScreen_BttmR_Y = GetPrivateProfileIntW(L"screen", L"vy2", 351, pIniFilename);
+  game_viewport_x = viewparams->uScreen_topL_X = GetPrivateProfileIntW(L"screen", L"vx1", 8, pIniFilename);
+  game_viewport_y = viewparams->uScreen_topL_Y = GetPrivateProfileIntW(L"screen", L"vy1", 8, pIniFilename);
+  game_viewport_z = viewparams->uScreen_BttmR_X = GetPrivateProfileIntW(L"screen", L"vx2", 468, pIniFilename);
+  game_viewport_w = viewparams->uScreen_BttmR_Y = GetPrivateProfileIntW(L"screen", L"vy2", 351, pIniFilename);
+  game_viewport_width = game_viewport_z - game_viewport_x;
+  game_viewport_height = game_viewport_w - game_viewport_y + 1;
 
 
   pAudioPlayer = new AudioPlayer;
@@ -9438,508 +9443,6 @@
   return uCurrentMenuID;
 }
 
-/*
-    v17 = 0;
-    if ( v4 > -2005532222 )
-    {
-      switch ( v4 + 2005532212 )
-      {
-        case 0:
-          v7 = "DDERR_SURFACENOTATTACHED";
-          goto LABEL_173;
-        case 10:
-          v7 = "DDERR_TOOBIGHEIGHT";
-          goto LABEL_173;
-        case 20:
-          v7 = "DDERR_TOOBIGSIZE";
-          goto LABEL_173;
-        case 30:
-          v7 = "DDERR_TOOBIGWIDTH";
-          goto LABEL_173;
-        case 50:
-          v7 = "DDERR_UNSUPPORTEDFORMAT";
-          goto LABEL_173;
-        case 60:
-          v7 = "DDERR_UNSUPPORTEDMASK";
-          goto LABEL_173;
-        case 61:
-          v7 = "DDERR_INVALIDSTREAM";
-          goto LABEL_173;
-        case 77:
-          v7 = "DDERR_VERTICALBLANKINPROGRESS";
-          goto LABEL_173;
-        case 80:
-          v7 = "DDERR_WASSTILLDRAWING";
-          goto LABEL_173;
-        case 100:
-          v7 = "DDERR_XALIGN";
-          goto LABEL_173;
-        case 101:
-          v7 = "DDERR_INVALIDDIRECTDRAWGUID";
-          goto LABEL_173;
-        case 102:
-          v7 = "DDERR_DIRECTDRAWALREADYCREATED";
-          goto LABEL_173;
-        case 103:
-          v7 = "DDERR_NODIRECTDRAWHW";
-          goto LABEL_173;
-        case 104:
-          v7 = "DDERR_PRIMARYSURFACEALREADYEXISTS";
-          goto LABEL_173;
-        case 105:
-          v7 = "DDERR_NOEMULATION";
-          goto LABEL_173;
-        case 106:
-          v7 = "DDERR_REGIONTOOSMALL";
-          goto LABEL_173;
-        case 107:
-          v7 = "DDERR_CLIPPERISUSINGHWND";
-          goto LABEL_173;
-        case 108:
-          v7 = "DDERR_NOCLIPPERATTACHED";
-          goto LABEL_173;
-        case 109:
-          v7 = "DDERR_NOHWND";
-          goto LABEL_173;
-        case 110:
-          v7 = "DDERR_HWNDSUBCLASSED";
-          goto LABEL_173;
-        case 111:
-          v7 = "DDERR_HWNDALREADYSET";
-          goto LABEL_173;
-        case 112:
-          v7 = "DDERR_NOPALETTEATTACHED";
-          goto LABEL_173;
-        case 113:
-          v7 = "DDERR_NOPALETTEHW";
-          goto LABEL_173;
-        case 114:
-          v7 = "DDERR_BLTFASTCANTCLIP";
-          goto LABEL_173;
-        case 115:
-          v7 = "DDERR_NOBLTHW";
-          goto LABEL_173;
-        case 116:
-          v7 = "DDERR_NODDROPSHW";
-          goto LABEL_173;
-        case 117:
-          v7 = "DDERR_OVERLAYNOTVISIBLE";
-          goto LABEL_173;
-        case 118:
-          v7 = "DDERR_NOOVERLAYDEST";
-          goto LABEL_173;
-        case 119:
-          v7 = "DDERR_INVALIDPOSITION";
-          goto LABEL_173;
-        case 120:
-          v7 = "DDERR_NOTAOVERLAYSURFACE";
-          goto LABEL_173;
-        case 121:
-          v7 = "DDERR_EXCLUSIVEMODEALREADYSET";
-          goto LABEL_173;
-        case 122:
-          v7 = "DDERR_NOTFLIPPABLE";
-          goto LABEL_173;
-        case 123:
-          v7 = "DDERR_CANTDUPLICATE";
-          goto LABEL_173;
-        case 125:
-          v7 = "DDERR_CANTCREATEDC";
-          goto LABEL_173;
-        case 126:
-          v7 = "DDERR_NODC";
-          goto LABEL_173;
-        case 127:
-          v7 = "DDERR_WRONGMODE";
-          goto LABEL_173;
-        case 128:
-          v7 = "DDERR_IMPLICITLYCREATED";
-          goto LABEL_173;
-        case 129:
-          v7 = "DDERR_NOTPALETTIZED";
-          goto LABEL_173;
-        case 130:
-          v7 = "DDERR_UNSUPPORTEDMODE";
-          goto LABEL_173;
-        case 131:
-          v7 = "DDERR_NOMIPMAPHW";
-          goto LABEL_173;
-        case 132:
-          v7 = "DDERR_INVALIDSURFACETYPE";
-          goto LABEL_173;
-        case 140:
-          v7 = "DDERR_NOOPTIMIZEHW";
-          goto LABEL_173;
-        case 141:
-          v7 = "DDERR_NOTLOADED";
-          goto LABEL_173;
-        case 142:
-          v7 = "DDERR_NOFOCUSWINDOW";
-          goto LABEL_173;
-        case 160:
-          v7 = "DDERR_DCALREADYCREATED";
-          goto LABEL_173;
-        case 170:
-          v7 = "DDERR_NONONLOCALVIDMEM";
-          goto LABEL_173;
-        case 180:
-          v7 = "DDERR_CANTPAGELOCK";
-          goto LABEL_173;
-        case 200:
-          v7 = "DDERR_CANTPAGEUNLOCK";
-          goto LABEL_173;
-        case 220:
-          v7 = "DDERR_NOTPAGELOCKED";
-          goto LABEL_173;
-        case 230:
-          v7 = "DDERR_MOREDATA";
-          goto LABEL_173;
-        case 231:
-          v7 = "DDERR_EXPIRED";
-          goto LABEL_173;
-        case 235:
-          v7 = "DDERR_VIDEONOTACTIVE";
-          goto LABEL_173;
-        case 239:
-          v7 = "DDERR_DEVICEDOESNTOWNSURFACE";
-          goto LABEL_173;
-        default:
-          goto LABEL_174;
-        case 124:
-          goto LABEL_176;
-      }
-      goto LABEL_176;
-    }
-    if ( v4 != -2005532222 )
-    {
-      if ( v4 > -2005532447 )
-      {
-        if ( v4 <= -2005532337 )
-        {
-          if ( v4 == -2005532337 )
-          {
-            v7 = "DDERR_NOVSYNCHW";
-            goto LABEL_173;
-          }
-          if ( v4 > -2005532392 )
-          {
-            if ( v4 == -2005532382 )
-            {
-              v7 = "DDERR_NOROTATIONHW";
-              goto LABEL_173;
-            }
-            if ( v4 == -2005532362 )
-            {
-              v7 = "DDERR_NOSTRETCHHW";
-              goto LABEL_173;
-            }
-            if ( v4 == -2005532356 )
-            {
-              v7 = "DDERR_NOT4BITCOLOR";
-              goto LABEL_173;
-            }
-            if ( v4 == -2005532355 )
-            {
-              v7 = "DDERR_NOT4BITCOLORINDEX";
-              goto LABEL_173;
-            }
-            if ( v4 == -2005532352 )
-            {
-              v7 = "DDERR_NOT8BITCOLOR";
-              goto LABEL_173;
-            }
-            if ( v4 == -2005532342 )
-            {
-              v7 = "DDERR_NOTEXTUREHW";
-              goto LABEL_173;
-            }
-          }
-          else
-          {
-            if ( v4 == -2005532392 )
-            {
-              v7 = "DDERR_NORASTEROPHW";
-              goto LABEL_173;
-            }
-            if ( v4 == -2005532442 )
-            {
-              v7 = "DDERR_NOFLIPHW";
-              goto LABEL_173;
-            }
-            if ( v4 == -2005532432 )
-            {
-              v7 = "DDERR_NOGDI";
-              goto LABEL_173;
-            }
-            if ( v4 == -2005532422 )
-            {
-              v7 = "DDERR_NOMIRRORHW";
-              goto LABEL_173;
-            }
-            if ( v4 == -2005532417 )
-            {
-              v7 = "DDERR_NOTFOUND";
-              goto LABEL_173;
-            }
-            if ( v4 == -2005532412 )
-            {
-              v7 = "DDERR_NOOVERLAYHW";
-              goto LABEL_173;
-            }
-            if ( v4 == -2005532402 )
-            {
-              v7 = "DDERR_OVERLAPPINGRECTS";
-              goto LABEL_173;
-            }
-          }
-          goto LABEL_174;
-        }
-        if ( v4 <= -2005532285 )
-        {
-          if ( v4 == -2005532285 )
-          {
-            v7 = "DDERR_PALETTEBUSY";
-            goto LABEL_173;
-          }
-          if ( v4 == -2005532332 )
-          {
-            v7 = "DDERR_NOZBUFFERHW";
-            goto LABEL_173;
-          }
-          if ( v4 == -2005532322 )
-          {
-            v7 = "DDERR_NOZOVERLAYHW";
-            goto LABEL_173;
-          }
-          if ( v4 == DDERR_OUTOFCAPS )
-          {
-            v7 = "DDERR_OUTOFCAPS";
-            goto LABEL_173;
-          }
-          if ( v4 == DDERR_OUTOFVIDEOMEMORY )
-          {
-            v7 = "DDERR_OUTOFVIDEOMEMORY";
-            goto LABEL_173;
-          }
-          if ( v4 == DDERR_OVERLAYCANTCLIP )
-          {
-            v7 = "DDERR_OVERLAYCANTCLIP";
-            goto LABEL_173;
-          }
-          if ( v4 == DDERR_OVERLAYCOLORKEYONLYONEACTIVE )
-          {
-            v7 = "DDERR_OVERLAYCOLORKEYONLYONEACTIVE";
-            goto LABEL_173;
-          }
-          goto LABEL_174;
-        }
-        if ( v4 == -2005532272 )
-        {
-          v7 = "DDERR_COLORKEYNOTSET";
-          goto LABEL_173;
-        }
-        if ( v4 == -2005532262 )
-        {
-          v7 = "DDERR_SURFACEALREADYATTACHED";
-          goto LABEL_173;
-        }
-        if ( v4 == -2005532252 )
-        {
-          v7 = "DDERR_SURFACEALREADYDEPENDENT";
-          goto LABEL_173;
-        }
-        if ( v4 != -2005532242 )
-        {
-          if ( v4 == -2005532237 )
-          {
-            v7 = "DDERR_CANTLOCKSURFACE";
-            goto LABEL_173;
-          }
-          if ( v4 == -2005532232 )
-          {
-            v7 = "DDERR_SURFACEISOBSCURED";
-            goto LABEL_173;
-          }
-          goto LABEL_174;
-        }
-      }
-      else
-      {
-        if ( v4 == -2005532447 )
-        {
-          v7 = "DDERR_NOEXCLUSIVEMODE";
-          goto LABEL_173;
-        }
-        if ( v4 <= -2005532562 )
-        {
-          if ( v4 == -2005532562 )
-          {
-            v7 = "DDERR_INVALIDCLIPLIST";
-            goto LABEL_173;
-          }
-          if ( v4 > -2005532662 )
-          {
-            if ( v4 == -2005532652 )
-            {
-              v7 = "DDERR_CANNOTDETACHSURFACE";
-              goto LABEL_173;
-            }
-            if ( v4 == -2005532632 )
-            {
-              v7 = "DDERR_CURRENTLYNOTAVAIL";
-              goto LABEL_173;
-            }
-            if ( v4 == -2005532617 )
-            {
-              v7 = "DDERR_EXCEPTION";
-              goto LABEL_173;
-            }
-            if ( v4 == -2005532582 )
-            {
-              v7 = "DDERR_HEIGHTALIGN";
-              goto LABEL_173;
-            }
-            if ( v4 == -2005532577 )
-            {
-              v7 = "DDERR_INCOMPATIBLEPRIMARY";
-              goto LABEL_173;
-            }
-            if ( v4 == -2005532572 )
-            {
-              v7 = "DDERR_INVALIDCAPS";
-              goto LABEL_173;
-            }
-          }
-          else
-          {
-            if ( v4 == -2005532662 )
-            {
-              v7 = "DDERR_CANNOTATTACHSURFACE";
-              goto LABEL_173;
-            }
-            if ( v4 == -2147467263 )
-            {
-              v7 = "DDERR_UNSUPPORTED";
-              goto LABEL_173;
-            }
-            if ( v4 == -2147467259 )
-            {
-              v7 = "DDERR_GENERIC";
-              goto LABEL_173;
-            }
-            if ( v4 == -2147221008 )
-            {
-              v7 = "DDERR_NOTINITIALIZED";
-              goto LABEL_173;
-            }
-            if ( v4 == -2147024882 )
-            {
-              v7 = "DDERR_OUTOFMEMORY";
-              goto LABEL_173;
-            }
-            if ( v4 == -2147024809 )
-            {
-              v7 = "DDERR_INVALIDPARAMS";
-              goto LABEL_173;
-            }
-            if ( v4 == -2005532667 )
-            {
-              v7 = "DDERR_ALREADYINITIALIZED";
-LABEL_173:
-              v13 = strlen(v7);
-              v12 = (char *)v7;
-LABEL_175:
-              std::stringoperator_assign__const_char_ptr__(&a1, v12, v13);
-              v13 = a3;
-              pRenderer->field_40110 = 0;
-              v15 = &v11;
-              std::string40E2C8(&v11, Str, (int)((char *)&hr + 3));
-              v10 = 48;
-              LOBYTE(v17) = 1;
-              Str = (char *)&v9;
-              std::string40E2C8(&v9, "Direct Draw Error", (int)((char *)&a3 + 3));
-              LOBYTE(v17) = 0;
-              CheckHRESULT_stru0::ShowMessageBox(v6, &a1, v9, v10, v11, v13);
-              v5 = 1;
-              goto LABEL_176;
-            }
-          }
-LABEL_174:
-          sprintfex(&Src, "Unknown DirectDraw/Direct3D error number %X", v4);
-          v13 = strlen(&Src);
-          v12 = &Src;
-          goto LABEL_175;
-        }
-        if ( v4 > -2005532492 )
-        {
-          if ( v4 == -2005532467 )
-          {
-            v7 = "DDERR_NOCLIPLIST";
-            goto LABEL_173;
-          }
-          if ( v4 == -2005532462 )
-          {
-            v7 = "DDERR_NOCOLORCONVHW";
-            goto LABEL_173;
-          }
-          if ( v4 == -2005532460 )
-          {
-            v7 = "DDERR_NOCOOPERATIVELEVELSET";
-            goto LABEL_173;
-          }
-          if ( v4 == -2005532457 )
-          {
-            v7 = "DDERR_NOCOLORKEY";
-            goto LABEL_173;
-          }
-          if ( v4 == -2005532452 )
-          {
-            v7 = "DDERR_NOCOLORKEYHW";
-            goto LABEL_173;
-          }
-          if ( v4 == -2005532450 )
-          {
-            v7 = "DDERR_NODIRECTDRAWSUPPORT";
-            goto LABEL_173;
-          }
-          goto LABEL_174;
-        }
-        if ( v4 == -2005532492 )
-        {
-          v7 = "DDERR_NOALPHAHW";
-          goto LABEL_173;
-        }
-        if ( v4 == -2005532552 )
-        {
-          v7 = "DDERR_INVALIDMODE";
-          goto LABEL_173;
-        }
-        if ( v4 == -2005532542 )
-        {
-          v7 = "DDERR_INVALIDOBJECT";
-          goto LABEL_173;
-        }
-        if ( v4 == -2005532527 )
-        {
-          v7 = "DDERR_INVALIDPIXELFORMAT";
-          goto LABEL_173;
-        }
-        if ( v4 != -2005532522 )
-        {
-          if ( v4 == -2005532512 )
-          {
-            v7 = "DDERR_LOCKEDSURFACES";
-            goto LABEL_173;
-          }
-          if ( v4 == -2005532502 )
-          {
-            v7 = "DDERR_NO3D";
-            goto LABEL_173;
-          }
-          goto LABEL_174;
-        }
-      }*/
-
 //----- (00467D5D) --------------------------------------------------------
 int __thiscall sub_467D5D(int _this)
 {
@@ -10378,9 +9881,12 @@
                 v22 = _this.uItemID;
                 v50 = v22;
 				if ( v50 )
+                {
+                __debugbreak();  // looks like offset in player's inventory and wand_lut much like case in 0042ECB5
 				  stru_A750F8[uActiveCharacter - 1]._494836(
 					*((int *)&pSpellDatas[66].uNormalLevelRecovery + v50),
 					uActiveCharacter - 1 + 9);
+                }
 				break;
               }
               v23 = v0->FindFreeInventorySlot();
@@ -10396,9 +9902,11 @@
               v22 = *(int *)v50;
 			  v50 = v22;
 			  if ( v50 )
+              {
+                __debugbreak();  // looks like offset in player's inventory and wand_lut much like case in 0042ECB5
 				stru_A750F8[uActiveCharacter - 1]._494836(
-				*((int *)&pSpellDatas[66].uNormalLevelRecovery + v50),
-				uActiveCharacter - 1 + 9);
+				*((int *)&pSpellDatas[66].uNormalLevelRecovery + v50), uActiveCharacter - 1 + 9);
+              }
 			  break;
             }
           }
@@ -10418,9 +9926,12 @@
               v22 = *(int *)v50;
 			  v50 = v22;
 			  if ( v50 )
+              {
+                __debugbreak();  // looks like offset in player's inventory and wand_lut much like case in 0042ECB5
 				stru_A750F8[uActiveCharacter - 1]._494836(
 				*((int *)&pSpellDatas[66].uNormalLevelRecovery + v50),
 				uActiveCharacter - 1 + 9);
+              }
 			  break;
         }
         --v53;
@@ -10439,9 +9950,12 @@
         if ( v51 )
           v0->pEquipment.uOffHand = 0;
         if ( v50 )
+        {
+                __debugbreak();  // looks like offset in player's inventory and wand_lut much like case in 0042ECB5
           stru_A750F8[uActiveCharacter - 1]._494836(
             *((int *)&pSpellDatas[66].uNormalLevelRecovery + v50),
             uActiveCharacter - 1 + 9);
+        }
         break;
       case 1u:
         if ( sub_43EE77_ProbablyIfUnderwaterSuitIsEquipped(uActiveCharacter) )
@@ -11477,9 +10991,9 @@
         {
           if ( stru_50C198.GetMagicalResistance(v2, 0xAu) )
           {
-			  v2->pActorBuffs[v1->field_48].Apply(
-              pParty->uTimePlayed + (signed int)(signed __int64)((double)(v1->field_4C << 7) * 0.033333335),
-              v1->field_50,
+			  v2->pActorBuffs[v1->spell_id].Apply(
+              pParty->uTimePlayed + (signed int)(signed __int64)((double)(v1->spell_level << 7) * 0.033333335),
+              v1->spell_skill,
               4u,
               0,
               0);
@@ -11656,12 +11170,12 @@
   v151 = a2 & 7;
   if ( (a2 & 7) == OBJECT_Actor)
   {
-    if ( (v2->field_58_pid & 7) == OBJECT_Actor && !pActors[v2->field_58_pid >> 3].GetActorsRelation(&pActors[a2 >> 3]) )
+    if ( (v2->spell_caster_pid & 7) == OBJECT_Actor && !pActors[v2->spell_caster_pid >> 3].GetActorsRelation(&pActors[a2 >> 3]) )
       return 1;
   }
   else
   {
-    if ( (a2 & 7) == OBJECT_Player && (v2->field_58_pid & 7) == OBJECT_Player)
+    if ( (a2 & 7) == OBJECT_Player && (v2->spell_caster_pid & 7) == OBJECT_Player)
       return 1;
   }
   if ( pParty->bTurnBasedModeOn == 1 )
@@ -11673,8 +11187,8 @@
       v2->uAttributes = v5 & 0xFFFB;
     }
   }
-  if ( v151 == OBJECT_BModel && (v2->field_58_pid & 7) != OBJECT_Player)
-    BYTE2(pActors[v2->field_58_pid >> 3].uAttributes) |= 4u;
+  if ( v151 == OBJECT_BModel && (v2->spell_caster_pid & 7) != OBJECT_Player)
+    BYTE2(pActors[v2->spell_caster_pid >> 3].uAttributes) |= 4u;
   v6 = v2->uType;
   v7 = v2->uType;
   if ( v7 > 3060 )
@@ -11732,7 +11246,7 @@
         v138 = 1;
         if ( v151 != OBJECT_Actor)
         {
-          if ( v6 != 9030 || v2->field_50 != 4 )
+          if ( v6 != 9030 || v2->spell_skill != 4 )
             goto LABEL_246;
           v2->_46BEF1_apply_spells();
 LABEL_233:
@@ -11789,9 +11303,9 @@
         v106 = v145;
         v150 = 0;
         v139 = v106 >> 3;
-        v137 = v2->field_4C;
-        v152 = v2->field_50;
-        v136 = v2->field_48;
+        v137 = v2->spell_level;
+        v152 = v2->spell_skill;
+        v136 = v2->spell_id;
         if ( v6 == 9030 )
         {
           v150 = 2;
@@ -11845,9 +11359,9 @@
               {
                 v2->_46BEF1_apply_spells();
               }
-              v2->field_4C = 0;
-              v2->field_50 = 0;
-              v2->field_48 = 0;
+              v2->spell_level = 0;
+              v2->spell_skill = 0;
+              v2->spell_id = 0;
               goto LABEL_233;
             }
             v135 = 10;
@@ -11955,7 +11469,7 @@
             v127 = v9;
             v126 = v124;
 LABEL_268:
-            v116 = word_4EE088_sound_ids[v2->field_48];
+            v116 = word_4EE088_sound_ids[v2->spell_id];
 LABEL_269:
             v125 = v116 + 1;
             goto LABEL_29;
@@ -11988,7 +11502,7 @@
           if ( !v63 )
             SpriteObject::OnInteraction(v153);
           v64 = v2->uFacing - stru_5C6E00->uIntegerDoublePi;
-          v44 = v2->field_50 == 4;
+          v44 = v2->spell_skill == 4;
           v2->vVelocity.z = 0;
           v2->vVelocity.y = 0;
           v2->vVelocity.x = 0;
--- a/mm7_3.cpp	Tue Mar 26 23:18:58 2013 +0600
+++ b/mm7_3.cpp	Tue Mar 26 23:19:12 2013 +0600
@@ -1390,7 +1390,7 @@
       v4 = &pObjectList->pObjects[item->uObjectDescID];
       if (item->AttachedToActor())
       {
-          v5 = item->field_5C >> 3;
+          v5 = item->spell_target_pid >> 3;
           *(int *)(v2 - 26) = pActors[v5].vPosition.x;
           *(int *)(v2 - 22) = pActors[v5].vPosition.y;
           *(int *)(v2 - 18) = pActors[v5].vPosition.z + pActors[v5].uActorHeight;
@@ -7724,74 +7724,79 @@
 }
 
 //----- (0048257A) --------------------------------------------------------
-int __fastcall GetTerrainHeightsAroundParty2(int a1, int a2, int *pIsOnWater, int a4)
-{
-  unsigned int v4; // ebx@1
-  unsigned int v5; // edi@1
+int __fastcall GetTerrainHeightsAroundParty2(int a1, int a2, int *pIsOnWater, int bFloatAboveWater)
+{
+  //unsigned int v4; // ebx@1
+  //unsigned int v5; // edi@1
   int result; // eax@9
-  int v7; // ebx@10
+  //int v7; // ebx@10
   int v8; // ebx@11
   int v9; // eax@11
   int v10; // ecx@11
-  int v11; // [sp+Ch] [bp-Ch]@1
-  int v12; // [sp+10h] [bp-8h]@1
+  //int v11; // [sp+Ch] [bp-Ch]@1
+  //int v12; // [sp+10h] [bp-8h]@1
   int v13; // [sp+10h] [bp-8h]@11
   signed int v14; // [sp+14h] [bp-4h]@3
   int v15; // [sp+24h] [bp+Ch]@11
 
-  v11 = a1;
-  v12 = a2;
-  v4 = WorldPosToGridCellX(a1);
-  v5 = WorldPosToGridCellZ(v12) - 1;
-  dword_76D538_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(v4);
-  dword_76D53C_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(v4 + 1);
-  dword_76D540_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(v4 + 1);
-  dword_76D544_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(v4);
-  dword_76D528_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(v5);
-  dword_76D52C_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(v5);
-  dword_76D530_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(v5 + 1);
-  dword_76D534_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(v5 + 1);
-  dword_76D518_terrain_cell_world_pos_around_party_y = pOutdoor->DoGetHeightOnTerrain(v4, v5);
-  dword_76D51C_terrain_cell_world_pos_around_party_y = pOutdoor->DoGetHeightOnTerrain(v4 + 1, v5);
-  dword_76D520_terrain_cell_world_pos_around_party_y = pOutdoor->DoGetHeightOnTerrain(v4 + 1, v5 + 1);
-  dword_76D524_terrain_cell_world_pos_around_party_y = pOutdoor->DoGetHeightOnTerrain(v4, v5 + 1);
+  //v11 = a1;
+  //v12 = a2;
+  auto grid_x = WorldPosToGridCellX(a1);
+  auto grid_z = WorldPosToGridCellZ(a2) - 1;
+
+  auto grid_x1 = GridCellToWorldPosX(grid_x),
+       grid_x2 = GridCellToWorldPosX(grid_x + 1);
+  auto grid_z1 = GridCellToWorldPosZ(grid_z),
+       grid_z2 = GridCellToWorldPosZ(grid_z + 1);
+
+  auto y_x1z1 = pOutdoor->DoGetHeightOnTerrain(grid_x,     grid_z),
+       y_x2z1 = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z),
+       y_x2z2 = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z + 1),
+       y_x1z2 = pOutdoor->DoGetHeightOnTerrain(grid_x,     grid_z + 1);
+  //v4 = WorldPosToGridCellX(a1);
+  //v5 = WorldPosToGridCellZ(v12) - 1;
+  //dword_76D538_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(v4);
+  //dword_76D53C_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(v4 + 1);
+  //dword_76D540_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(v4 + 1);
+  //dword_76D544_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(v4);
+  //dword_76D528_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(v5);
+  //dword_76D52C_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(v5);
+  //dword_76D530_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(v5 + 1);
+  //dword_76D534_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(v5 + 1);
+  //dword_76D518_terrain_cell_world_pos_around_party_y = pOutdoor->DoGetHeightOnTerrain(v4, v5);
+  //dword_76D51C_terrain_cell_world_pos_around_party_y = pOutdoor->DoGetHeightOnTerrain(v4 + 1, v5);
+  //dword_76D520_terrain_cell_world_pos_around_party_y = pOutdoor->DoGetHeightOnTerrain(v4 + 1, v5 + 1);
+  //dword_76D524_terrain_cell_world_pos_around_party_y = pOutdoor->DoGetHeightOnTerrain(v4, v5 + 1);
   *pIsOnWater = false;
-  if ( pOutdoor->ActuallyGetSomeOtherTileInfo(v4, v5) & 2 )
+  if ( pOutdoor->ActuallyGetSomeOtherTileInfo(grid_x, grid_z) & 2 )
     *pIsOnWater = true;
   v14 = 0;
-  if ( !a4 && *pIsOnWater )
+  if ( !bFloatAboveWater && *pIsOnWater )
     v14 = -60;
-  if ( dword_76D518_terrain_cell_world_pos_around_party_y != dword_76D51C_terrain_cell_world_pos_around_party_y
-    || dword_76D51C_terrain_cell_world_pos_around_party_y != dword_76D520_terrain_cell_world_pos_around_party_y
-    || dword_76D520_terrain_cell_world_pos_around_party_y != dword_76D524_terrain_cell_world_pos_around_party_y )
-  {
-    v7 = abs(v11 - dword_76D538_terrain_cell_world_pos_around_party_x);
-    if ( abs(dword_76D528_terrain_cell_world_pos_around_party_z - v12) >= v7 )
-    {
-      v8 = dword_76D524_terrain_cell_world_pos_around_party_y;
-      v9 = dword_76D520_terrain_cell_world_pos_around_party_y;
-      v10 = dword_76D518_terrain_cell_world_pos_around_party_y;
-      v15 = v11 - dword_76D544_terrain_cell_world_pos_around_party_x;
-      v13 = v12 - dword_76D534_terrain_cell_world_pos_around_party_z;
+  if ( y_x1z1 != y_x2z1 ||
+       y_x2z1 != y_x2z2 ||
+       y_x2z2 != y_x1z2 )
+  {
+    if ( abs(grid_z1 - a2) >= abs(a1 - grid_x1) )
+    {
+      v8 = y_x1z2;
+      v9 = y_x2z2;
+      v10 = y_x1z1;
+      v15 = a1 - grid_x1;
+      v13 = a2 - grid_z2;
     }
     else
     {
-      v8 = dword_76D51C_terrain_cell_world_pos_around_party_y;
-      v9 = dword_76D518_terrain_cell_world_pos_around_party_y;
-      v10 = dword_76D520_terrain_cell_world_pos_around_party_y;
-      v15 = dword_76D53C_terrain_cell_world_pos_around_party_x - v11;
-      v13 = dword_76D52C_terrain_cell_world_pos_around_party_z - v12;
-    }
-    result = v14
-           + v8
-           + ((unsigned __int64)(v13 * (signed __int64)((v10 - v8) << 7)) >> 16)
-           + ((unsigned __int64)(v15 * (signed __int64)((v9 - v8) << 7)) >> 16);
-  }
-  else
-  {
-    result = v14 + dword_76D518_terrain_cell_world_pos_around_party_y;
-  }
-  return result;
+      v8 = y_x2z1;
+      v9 = y_x1z1;
+      v10 = y_x2z2;
+      v15 = grid_x2 - a1;
+      v13 = grid_z1 - a2;
+    }
+    return v14 + v8 + fixpoint_mul(v13, (v10 - v8) * 128) + fixpoint_mul(v15, (v9 - v8) * 128);
+  }
+  else
+    return y_x1z1;
 }
 
 //----- (0048276F) --------------------------------------------------------
@@ -11923,7 +11928,7 @@
 		else if (_evt->_e_type == EVENT_OnTimer || _evt->_e_type == EVENT_OnLongTimer)
 		{
 			v3 = &array_5B5928_timers[dword_5B65C8_timers_count];
-			v20 = pOutdoor->uLastVisitDay;
+			v20 = pOutdoor->loc_time.uLastVisitDay;
 			if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
 				v20 = pIndoor->stru1.uLastVisitDay;
 
@@ -12423,7 +12428,7 @@
   pFont = pFontArrus;
   if ( ptr_F8B1E8 && !byte_5B0938[0] )
     strcpy(byte_5B0938, ptr_F8B1E8);
-  v5.uFrameWidth = 460;
+  v5.uFrameWidth = game_viewport_width;
   v5.uFrameZ = 452;
   v1 = pFontArrus->CalcTextHeight(byte_5B0938, &v5, 12, 0) + 7;
   if ( 352 - v1 < 8 )
@@ -12676,7 +12681,7 @@
 
   if (pInString)
   {
-    pWindow.uFrameWidth = 460;
+    pWindow.uFrameWidth = game_viewport_width;
     pWindow.uFrameZ = 452;
     auto font = pFontArrus;
     v12 = pFontArrus->CalcTextHeight(pInString, &pWindow, 13, 0) + 7;
@@ -13782,9 +13787,9 @@
       case 41:
         a1.stru_24.Reset();
         v16 = 0;
-        a1.field_48 = spellnum;
-        a1.field_4C = level;
-        a1.field_50 = v15;
+        a1.spell_id = spellnum;
+        a1.spell_level = level;
+        a1.spell_skill = v15;
         if ( (signed int)pObjectList->uNumObjects <= 0 )
           goto LABEL_34;
         v17 = (char *)&pObjectList->pObjects->uObjectID;
@@ -13820,9 +13825,9 @@
           a8b = a7c / (v60 - 1);
           a1.stru_24.Reset();
           v21 = 0;
-          a1.field_48 = spellnum;
-          a1.field_4C = level;
-          a1.field_50 = v15;
+          a1.spell_id = spellnum;
+          a1.spell_level = level;
+          a1.spell_skill = v15;
           if ( (signed int)pObjectList->uNumObjects <= 0 )
           {
 LABEL_41:
@@ -13847,8 +13852,8 @@
           a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
           a1.field_60_distance_related_prolly_lod = v55;
           a1.uSpriteFrameID = 0;
-          a1.field_58_pid = 8000 | OBJECT_Item;
-          a1.field_5C = 4;
+          a1.spell_caster_pid = 8000 | OBJECT_Item;
+          a1.spell_target_pid = 4;
           a1.uSoundID = 0;
           for ( i = a7c / -2; i <= a7c / 2; i += a8b )
           {
@@ -13863,9 +13868,9 @@
         }
         a1.stru_24.Reset();
         v16 = 0;
-        a1.field_48 = spellnum;
-        a1.field_4C = level;
-        a1.field_50 = v15;
+        a1.spell_id = spellnum;
+        a1.spell_level = level;
+        a1.spell_skill = v15;
         if ( (signed int)pObjectList->uNumObjects <= 0 )
           goto LABEL_34;
         v19 = (char *)&pObjectList->pObjects->uObjectID;
@@ -13888,8 +13893,8 @@
         a1.field_60_distance_related_prolly_lod = v55;
         v20 = yaw;
         a1.uSpriteFrameID = 0;
-        a1.field_58_pid = 8000 | OBJECT_Item;
-        a1.field_5C = 0;
+        a1.spell_caster_pid = 8000 | OBJECT_Item;
+        a1.spell_target_pid = 0;
         a1.uFacing = yaw;
         a1.uSoundID = 0;
         v51 = 0;
@@ -13916,9 +13921,9 @@
         a8c = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360 / (v60 - 1);
         a1.stru_24.Reset();
         v25 = 0;
-        a1.field_48 = spellnum;
-        a1.field_4C = level;
-        a1.field_50 = v15;
+        a1.spell_id = spellnum;
+        a1.spell_level = level;
+        a1.spell_skill = v15;
         if ( (signed int)pObjectList->uNumObjects <= 0 )
           goto LABEL_59;
         v26 = (char *)&pObjectList->pObjects->uObjectID;
@@ -13942,8 +13947,8 @@
         a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
         a1.field_60_distance_related_prolly_lod = v55;
         a1.uSpriteFrameID = 0;
-        a1.field_58_pid = 8000 | OBJECT_Item;
-        a1.field_5C = 4;
+        a1.spell_caster_pid = 8000 | OBJECT_Item;
+        a1.spell_target_pid = 4;
         a1.uSoundID = 0;
         for ( j = a7d / -2; j <= a7d / 2; j += a8c )
         {
@@ -13960,9 +13965,9 @@
           return;
         a1.stru_24.Reset();
         v29 = 0;
-        a1.field_48 = spellnum;
-        a1.field_4C = level;
-        a1.field_50 = v15;
+        a1.spell_id = spellnum;
+        a1.spell_level = level;
+        a1.spell_skill = v15;
         if ( (signed int)pObjectList->uNumObjects <= 0 )
           goto LABEL_70;
         v30 = (char *)&pObjectList->pObjects->uObjectID;
@@ -14096,8 +14101,8 @@
     a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
     a1.field_60_distance_related_prolly_lod = v55;
     a1.uSpriteFrameID = 0;
-    a1.field_58_pid = 8000 | OBJECT_Item;
-    a1.field_5C = 4;
+    a1.spell_caster_pid = 8000 | OBJECT_Item;
+    a1.spell_target_pid = 4;
     a1.uSoundID = 0;
     v51 = 0;
     v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
@@ -14926,710 +14931,834 @@
 // 4F75D8: using guessed type int ai_arrays_size;
 
 //----- (00401A91) --------------------------------------------------------
-void __cdecl UpdateActorAI()
-{
-  //unsigned int v0; // esi@4
-  int v1; // eax@7
-  int v2; // ecx@7
-  int v3; // eax@7
-  signed int v4; // edi@10
-  Actor *v5; // esi@12
-  signed int v6; // eax@14
-  __int16 v7; // cx@14
-  Player **v8; // esi@20
-  Player *pPlayer; // ecx@21
-  //Actor *pActor; // esi@34
-  //__int16 v11; // ax@34
-  //unsigned int v12; // eax@47
-  //signed int v13; // edi@47
-  //SpellBuff *v14; // ebx@47
-  //unsigned int v15; // edi@67
-  //char *v16; // eax@67
-  //unsigned int v17; // edx@67
-  //unsigned int v18; // ecx@67
-  //unsigned __int16 v19; // ax@72
-  //int *v20; // esi@80
-  Actor *v21; // ebx@80
-  unsigned __int16 v22; // ax@86
-  signed int v23; // eax@94
-  unsigned int v24; // eax@102
-  signed int v25; // edi@102
-  SpellBuff *v26; // esi@102
-  unsigned int v27; // ecx@123
-  unsigned int v28; // eax@123
-  unsigned int v29; // eax@127
-  AIDirection *v30; // eax@129
-  unsigned __int16 v31; // ax@132
-  unsigned int v32; // esi@142
-  int v33; // eax@144
-  int v34; // eax@147
-  char v35; // al@150
-  unsigned int v36; // edi@152
-  signed int v37; // eax@154
-  unsigned __int8 v38; // sf@158
-  unsigned __int8 v39; // of@158
-  signed int v40; // edx@166
-  unsigned int v41; // ecx@166
-  double v42; // st7@176
-  double v43; // st6@176
-  bool v44; // eax@189
-  bool v45; // eax@192
-  unsigned __int8 v46; // cl@197
-  double v47; // st7@206
-  double v48; // st7@207
-  char v49; // zf@208
-  char v50; // zf@214
-  signed int v51; // edx@219
-  unsigned int v52; // ecx@219
-  __int16 v53; // fps@224
-  unsigned __int8 v54; // c0@224
-  unsigned __int8 v55; // c3@224
-  double v56; // st7@226
-  AIDirection *v57; // eax@246
-  double v58; // st7@246
-  signed int v59; // [sp-18h] [bp-C8h]@213
-  int v60; // [sp-14h] [bp-C4h]@144
-  int v61; // [sp-14h] [bp-C4h]@168
-  AIDirection *v62; // [sp-14h] [bp-C4h]@213
-  signed int v63; // [sp-14h] [bp-C4h]@216
-  unsigned int v64; // [sp-14h] [bp-C4h]@219
-  unsigned int v65; // [sp-10h] [bp-C0h]@144
-  char v66; // [sp-10h] [bp-C0h]@147
-  AIDirection *v67; // [sp-10h] [bp-C0h]@167
-  int v68; // [sp-10h] [bp-C0h]@168
-  AIDirection *v69; // [sp-10h] [bp-C0h]@206
-  int v70; // [sp-10h] [bp-C0h]@213
-  AIDirection *v71; // [sp-10h] [bp-C0h]@216
-  AIDirection v72; // [sp+0h] [bp-B0h]@246
-  AIDirection a3; // [sp+1Ch] [bp-94h]@129
-  AIDirection v74; // [sp+38h] [bp-78h]@246
-  AIDirection v75; // [sp+54h] [bp-5Ch]@129
-  int v76; // [sp+70h] [bp-40h]@83
-  signed int a1; // [sp+74h] [bp-3Ch]@129
-  int v78; // [sp+78h] [bp-38h]@79
-  AIDirection pDir; // [sp+7Ch] [bp-34h]@129
-  float v80; // [sp+98h] [bp-18h]@33
-  int v81; // [sp+9Ch] [bp-14h]@100
-  int v82; // [sp+A0h] [bp-10h]@45
-  //unsigned int uActorID; // [sp+A4h] [bp-Ch]@32
-  unsigned int v84; // [sp+A8h] [bp-8h]@11
-  signed int a2; // [sp+ACh] [bp-4h]@83
-
-  if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor)
-    MakeActorAIList_ODM();
-  else
-    MakeActorAIList_BLV();
-
-  //v0 = 0;
-  if ( uCurrentlyLoadedLevelType != LEVEL_Indoor && pParty->armageddon_timer > 0 )
-  {
-    if ( pParty->armageddon_timer > 417 )
-    {
-      pParty->armageddon_timer = 0;
-    }
-    else
-    {
-      pParty->sRotationY = (stru_5C6E00->uIntegerDoublePi - 1) & (pParty->sRotationY + rand() % 16 - 8);
-      v1 = rand();
-      v2 = 128;
-      v3 = pParty->sRotationX + v1 % 16 - 8;
-      pParty->sRotationX = v3;
-      if ( v3 > 128 || (v2 = -128, v3 < -128) )
-        pParty->sRotationX = v2;
-      pParty->uFlags |= 2u;
-      pParty->armageddon_timer -= pMiscTimer->uTimeElapsed;
-      v4 = pParty->field_16140 + 50;
-      if ( pParty->armageddon_timer <= 0 )
-      {
-        pParty->armageddon_timer = 0;
-        v84 = 0;
-        if ( (signed int)uNumActors > 0 )
-        {
-          v5 = pActors;//[0].sCurrentHP;
-          do
-          {
-            if ( v5->CanAct() )
-            {
-              v6 = stru_50C198.CalcMagicalDamageToActor(v5, 5, v4);
-              v7 = v5->sCurrentHP - v6;
-              v5->sCurrentHP = v7;
-              if ( v6 )
-              {
-                if ( v7 >= 0 )
-                {
-                  Actor::_4030AD(v84, 4, 0);
-                }
-                else
-                {
-                  Actor::Die(v84);
-                  if ( v5->pMonsterInfo.uExp )
-                    GivePartyExp(pMonsterStats->pInfos[v5->pMonsterInfo.uID].uExp);
-                }
-              }
-            }
-            ++v84;
-            ++v5;
-          }
-          while ( (signed int)v84 < (signed int)uNumActors );
-        }
-        v8 = &pPlayers[1];
-        do
-        {
-          pPlayer = *v8;
-          if ( !(*v8)->pConditions[14] && !pPlayer->pConditions[15] && !pPlayer->pConditions[16] )
-            pPlayer->ReceiveDamage(v4, 5);
-          ++v8;
-        }
-        while ( (signed int)v8 <= (signed int)&pPlayers[4] );
-        //v0 = 0;
-      }
-      if (pTurnEngine->field_1C)
-        --pTurnEngine->field_1C;
-    }
-  }
-
-  if (pParty->bTurnBasedModeOn)
-  {
-    pTurnEngine->_405E14();
-    return;
-  }
-
-
-  //uActorID = v0;
-  for (uint i = 0; i < uNumActors; ++i)
-  {
-    auto actor = pActors + i;
-    //LODWORD(v80) = (int)(char *)pActors + 176; // uAIState
-    //do
-    //{
-      //pActor = (Actor *)(LODWORD(v80) - 176);
-      //v11 = *(unsigned int *)LODWORD(v80);
-      //v49 = *(unsigned int *)LODWORD(v80) == 5;
-    ai_near_actors_targets_pid[i] = OBJECT_Player;
-    if (actor->uAIState == Dead || actor->uAIState == Removed || actor->uAIState == Disabled || actor->uAttributes & 0x0400)
-      continue;
-
-    if (!actor->sCurrentHP && actor->uAIState != Dying)
-      Actor::Die(i);
-
-    //v84 = *(_QWORD *)(LODWORD(v80) + 84) <= 0i64 ? 0 : 1;
-    //v82 = *(_QWORD *)(LODWORD(v80) + 52) <= 0i64 ? 0 : 1;
-      //v12 = 0;
-      //v13 = 0;
-      //v14 = (SpellBuff *)(LODWORD(v80) + 36);
-    for (uint j = 0; j < 22; ++j)
-    {
-      if (j != 10)
-        actor->pActorBuffs[j]._4585CA(pParty->uTimePlayed);
-    }
-      /*do
-      {
-        if ( v13 != 10 )
-        {
-          v14->_4585CA(pParty->uTimePlayed);
-          v12 = 0;
-        }
-        ++v13;
-        ++v14;
-      }
-      while ( v13 < 22 );*/
-    if (!actor->pActorBuffs[ACTOR_BUFF_SHRINK].uExpireTime)
-        //&& SHIDWORD(pActor->pActorBuffs[3].uExpireTime) <= (signed int)v12 && (SHIDWORD(pActor->pActorBuffs[3].uExpireTime) < (signed int)v12
-        // || LODWORD(pActor->pActorBuffs[3].uExpireTime) <= v12) )
-      actor->uActorHeight = pMonsterList->pMonsters[actor->pMonsterInfo.uID - 1].uMonsterHeight;
-    if (actor->pActorBuffs[ACTOR_BUFF_CHARM].uExpireTime)
-      actor->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly;
-    else
-      actor->pMonsterInfo.uHostilityType = pMonsterStats->pInfos[actor->pMonsterInfo.uID].uHostilityType;
-
-    if (actor->pActorBuffs[ACTOR_BUFF_PARALYZED].uExpireTime ||
-        actor->pActorBuffs[ACTOR_BUFF_STONED].uExpireTime)
-      continue;
-
-      //v15 = pMiscTimer->uTimeElapsed;
-      //v16 = (char *)&pActor->pMonsterInfo.uRecoveryTime;
-      //v17 = pActor->uCurrentActionTime;
-      //v18 = pActor->pMonsterInfo.uRecoveryTime;
-    if (actor->pMonsterInfo.uRecoveryTime)
-    {
-      if (actor->pMonsterInfo.uRecoveryTime < pMiscTimer->uTimeElapsed)
-        actor->pMonsterInfo.uRecoveryTime = 0;
-      else actor->pMonsterInfo.uRecoveryTime -= pMiscTimer->uTimeElapsed;
-    }
-    
-    actor->uCurrentActionTime += pMiscTimer->uTimeElapsed;
-    if (actor->uCurrentActionTime < actor->uCurrentActionLength)
-      continue;
-
-      //v19 = actor->uAIState;
-    if (actor->uAIState == Dying)
-        actor->uAIState = Dead;
-    else
-    {
-      if (actor->uAIState != Summoned)
-      {
-        Actor::AI_StandOrBored(i, OBJECT_Player, 256, nullptr);
-        continue;
-      }
-      actor->uAIState = Standing;
-    }
-
-    actor->uCurrentActionTime = 0;
-    actor->uCurrentActionLength = 0;
-    actor->UpdateAnimation();
-//LABEL_78:
-      //++uActorID;
-      //LODWORD(v80) += 836;
-    //}
-    //while ( (signed int)uActorID < (signed int)uNumActors );
-  }
-
-
-  v78 = 0;
-  int actor_id = -1;
-  if ( ai_arrays_size > 0 )
-  {
-    while ( 1 )
-    {
-      actor_id = ai_near_actors_ids[v78];
-      assert(actor_id < uNumActors);
-
-      //v20 = &ai_near_actors_targets_pid[actor_id];
-      v21 = &pActors[actor_id];
-      Actor::_SelectTarget(actor_id, &ai_near_actors_targets_pid[actor_id], true);
-      if (v21->pMonsterInfo.uHostilityType && !ai_near_actors_targets_pid[actor_id])
-        v21->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly;
-      a2 = ai_near_actors_targets_pid[actor_id];
-      v76 = a2 & 7;
-      if ( (a2 & 7) == OBJECT_Actor)
-        v80 = 0.5;
-      else
-        v80 = 1.0;
-      v22 = v21->uAIState;
-      if ( v22 == Dying || v22 == Dead || v22 == Removed || v22 == Disabled || v22 == Summoned)
-        goto LABEL_254;
-      if ( !v21->sCurrentHP )
-        Actor::Die(actor_id);
-      if ( (signed __int64)v21->pActorBuffs[3].uExpireTime <= 0 )
-      {
-        v84 = 0;
-        v23 = 1;
-      }
-      else
-      {
-        v23 = 1;
-        v84 = 1;
-      }
-      if ( (signed __int64)v21->pActorBuffs[1].uExpireTime <= 0 )
-        v82 = 0;
-      else
-        v82 = v23;
-      if ( (signed __int64)v21->pActorBuffs[2].uExpireTime <= 0 )
-        v81 = 0;
-      else
-        v81 = v23;
-      v24 = 0;
-      v25 = 0;
-      v26 = v21->pActorBuffs;
-      do
-      {
-        if ( v25 != 10 )
-        {
-          v26->_4585CA(pParty->uTimePlayed);
-          v24 = 0;
-        }
-        ++v25;
-        ++v26;
-      }
-      while ( v25 < 22 );
-      if ( v84 != v24
-        && SHIDWORD(v21->pActorBuffs[3].uExpireTime) <= (signed int)v24
-        && (SHIDWORD(v21->pActorBuffs[3].uExpireTime) < (signed int)v24
-         || LODWORD(v21->pActorBuffs[3].uExpireTime) <= v24) )
-        v21->uActorHeight = pMonsterList->pMonsters[v21->pMonsterInfo.uID - 1].uMonsterHeight;
-      if ( v82 != v24 )
-      {
-        v21->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly;
-        if ( SHIDWORD(v21->pActorBuffs[1].uExpireTime) <= (signed int)v24 )
-        {
-          if ( SHIDWORD(v21->pActorBuffs[1].uExpireTime) < (signed int)v24
-            || LODWORD(v21->pActorBuffs[1].uExpireTime) <= v24 )
-            v21->pMonsterInfo.uHostilityType = pMonsterStats->pInfos[v21->pMonsterInfo.uID].uHostilityType;
-        }
-      }
-      if ( v81 != v24
-        && SHIDWORD(v21->pActorBuffs[2].uExpireTime) <= (signed int)v24
-        && (SHIDWORD(v21->pActorBuffs[2].uExpireTime) < (signed int)v24
-         || LODWORD(v21->pActorBuffs[2].uExpireTime) <= v24) )
-      {
-        v21->uAIState = Removed;
-        goto LABEL_254;
-      }
-      if ( v21->pActorBuffs[5].uExpireTime || v21->pActorBuffs[6].uExpireTime )
-        goto LABEL_254;
-      v27 = pMiscTimer->uTimeElapsed;
-      v28 = v21->pMonsterInfo.uRecoveryTime;
-      v21->uCurrentActionTime += pMiscTimer->uTimeElapsed;
-      if ( (signed int)v28 > 0 )
-        v21->pMonsterInfo.uRecoveryTime = v28 - v27;
-      if ( v21->pMonsterInfo.uRecoveryTime< 0 )
-        v21->pMonsterInfo.uRecoveryTime = 0;
-      v29 = v21->uAttributes;
-      if ( !(v29 & 0x8000) )
-        v21->uAttributes = v29 | 0x8000;
-      a1 = 8 * actor_id | OBJECT_Actor;
-      v30 = Actor::GetDirectionInfo(8 * actor_id | OBJECT_Actor, a2, &a3, 0);
-      v49 = v21->pMonsterInfo.uHostilityType == 0;
-      memcpy(&v75, v30, sizeof(v75));
-      memcpy(&pDir, &v75, sizeof(pDir));
-      if ( !v49 && (signed int)v21->pMonsterInfo.uRecoveryTime <= 0 )
-      {
-        if ( v80 * 307.2 >= (double)(signed int)v75.uDistance
-          && ((v31 = v21->uAIState, v31 == 6) || !v31 || v31 == 1 || v31 == 9)
-          || v21->pMonsterInfo.uMissleAttack1Type && v21->uAIState == 8 )
-        {
-          v32 = actor_id;
-          goto LABEL_152;
-        }
-      }
-      if ( (signed int)v21->uCurrentActionTime < v21->uCurrentActionLength )
-        goto LABEL_254;
-      if ( v21->uAIState == 2 )
-      {
-        v32 = actor_id;
-        v35 = stru_50C198.special_ability_use_check(v21, actor_id);
-        stru_50FE08.Add(
-          a1,
-          5120,
-          v21->vPosition.x,
-          v21->vPosition.y,
-          v21->vPosition.z + ((signed int)v21->uActorHeight >> 1),
-          v35,
-          1);
-        goto LABEL_152;
-      }
-      if ( v21->uAIState == 3 )
-      {
-        v34 = v21->pMonsterInfo.uMissleAttack1Type;
-        v66 = 0;
-        goto LABEL_149;
-      }
-      if ( v21->uAIState == 12 )
-      {
-        v34 = v21->pMonsterInfo.uMissleAttack2Type;
-        v66 = 1;
-LABEL_149:
-        v32 = actor_id;
-        Actor::_404874(actor_id, &pDir, v34, v66);
-        goto LABEL_152;
-      }
-      v32 = actor_id;
-      if ( v21->uAIState == 13 )
-        break;
-      if ( v21->uAIState == 18 )
-      {
-        v65 = v21->pMonsterInfo.uSpellSkillAndMastery2;
-        v60 = 3;
-        v33 = v21->pMonsterInfo.uSpell2ID;
-LABEL_146:
-        Actor::_404AC7(actor_id, &pDir, v33, v60, v65);
-      }
-LABEL_152:
-      v36 = v75.uDistance;
-      if ( v21->pMonsterInfo.uHostilityType )
-        goto LABEL_165;
-      if ( v76 == 3 )
-      {
-        v36 = v75.uDistance;
-        v37 = (unsigned __int8)*(&byte_5C8D1A[89 * (v21->pMonsterInfo.uID - 1) / 3]
-                               + (pActors[a2 >> 3].pMonsterInfo.uID - 1) / 3);
-      }
-      else
-      {
-        v37 = 4;
-      }
-      if ( v37 == 1 )
-        goto LABEL_257;
-      if ( v37 == 2 )
-      {
-        v39 = __OFSUB__(v36, 1024);
-        v38 = ((v36 - 1024) & 0x80000000u) != 0;
-      }
-      else
-      {
-        if ( v37 == 3 )
-        {
-          v39 = __OFSUB__(v36, 2560);
-          v38 = ((v36 - 2560) & 0x80000000u) != 0;
-        }
-        else
-        {
-          if ( v37 != 4 )
-            goto LABEL_165;
-          v39 = __OFSUB__(v36, 5120);
-          v38 = ((v36 - 5120) & 0x80000000u) != 0;
-        }
-      }
-      if ( v38 ^ v39 )
-LABEL_257:
-      v21->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Long;
-LABEL_165:
-      if ( (signed __int64)v21->pActorBuffs[4].uExpireTime > 0 )
-      {
-        v40 = a2;
-        v41 = v32;
-        if ( (signed int)v36 >= 10240 )
-        {
-          v68 = 0;
-          v61 = 1024;
-          goto LABEL_253;
-        }
-        v67 = &pDir;
-        goto LABEL_182;
-      }
-      if ( v21->pMonsterInfo.uHostilityType != 4 || !a2 )
-        goto LABEL_241;
-      if ( !(v21->uAttributes & 0x020000) || v21->pMonsterInfo.uAIType == 1 )
-      {
-        if ( v21->pMonsterInfo.uAIType == 1 )
-        {
-          v67 = &pDir;
-          if ( v21->pMonsterInfo.uMovementType != 5 )
-            goto LABEL_181;
-          Actor::AI_Stand(
-            v32,
-            a2,
-            (signed __int64)((double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333),
-            &pDir);
-        }
-        else
-        {
-          if ( v21->pMonsterInfo.uAIType == 2 )
-          {
-            v84 = v21->sCurrentHP;
-            v42 = (double)(signed int)v84;
-            v43 = (double)(signed int)v21->pMonsterInfo.uHP * 0.2;
-          }
-          else
-          {
-            if ( v21->pMonsterInfo.uAIType != 3 )
-              goto LABEL_185;
-            v84 = v21->sCurrentHP;
-            v42 = (double)(signed int)v84;
-            v43 = (double)(signed int)v21->pMonsterInfo.uHP * 0.1;
-          }
-          if ( v43 > v42 && (signed int)v36 < 10240 )
-          {
-            v67 = &pDir;
-LABEL_181:
-            v40 = a2;
-            v41 = v32;
-LABEL_182:
-            Actor::_402968(v41, v40, 0, v67);
-            goto LABEL_254;
-          }
-        }
-      }
-LABEL_185:
-      v81 = v36 - v21->uActorRadius;
-      if ( v76 == 3 )
-        v81 -= pActors[a2 >> 3].uActorRadius;
-      if ( v81 < 0 )
-        v81 = 0;
-      rand();
-      v44 = (signed int)v21->pMonsterInfo.uRecoveryTime <= 0;
-      v21->uAttributes &= 0xFBFFFF;
-      v82 = 0;
-      v49 = v21->pMonsterInfo.uMovementType == 5;
-      v84 = v44;
-      if ( v49 )
-        v82 = 1;
-      if ( v81 >= 5120 )
-        goto LABEL_241;
-      v45 = stru_50C198.special_ability_use_check(v21, v32);
-      if ( !v45 )
-      {
-        if ( v21->pMonsterInfo.uMissleAttack1Type )
-        {
-          if ( v84 )
-          {
-            Actor::_403476(v32, a2, &pDir);
-            goto LABEL_254;
-          }
-LABEL_223:
-          if ( v82 )
-            goto LABEL_217;
-          v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-          //UNDEF(v53);
-          v69 = &pDir;
-          if ( !(v54 | v55) )
-            goto LABEL_219;
-LABEL_225:
-          Actor::_402AD7(v32, a2, v32, (signed __int64)v47, v69);
-          goto LABEL_254;
-        }
-        v56 = v80 * 307.2;
-        if ( (double)v81 >= v56 )
-        {
-          if ( v81 >= 1024 )
-          {
-            if ( v82 )
-              goto LABEL_217;
-            v71 = &pDir;
-            v63 = 0;
-            goto LABEL_240;
-          }
-          goto LABEL_235;
-        }
-        goto LABEL_227;
-      }
-      if ( v45 != 1 )
-      {
-        if ( v45 > 1 && v45 <= 3 )
-        {
-          if ( v45 == 2 )
-            v46 = v21->pMonsterInfo.uSpell1ID;
-          else
-            v46 = v21->pMonsterInfo.uSpell2ID;
-          if ( v46 )
-          {
-            if ( v84 )
-            {
-              if ( v45 == 2 )
-                Actor::_403854(v32, a2, &pDir);
-              else
-                Actor::_403A60(v32, a2, &pDir);
-              goto LABEL_254;
-            }
-            if ( v80 * 307.2 > (double)v81 || v82 )
-            {
-LABEL_217:
-              v69 = &pDir;
-LABEL_218:
-              v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-LABEL_219:
-              v51 = a2;
-              v64 = (signed __int64)v47;
-              v52 = v32;
-LABEL_247:
-              Actor::AI_Stand(v52, v51, v64, v69);
-              goto LABEL_254;
-            }
-            v69 = &pDir;
-            v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-            goto LABEL_225;
-          }
-          v48 = v80 * 307.2;
-          if ( (double)v81 >= v48 )
-          {
-            if ( v81 >= 1024 )
-            {
-              v50 = v82 == 0;
-LABEL_215:
-              if ( !v50 )
-                goto LABEL_217;
-              v71 = &pDir;
-              v63 = 256;
-LABEL_240:
-              Actor::_402686(v32, a2, v63, v71);
-              goto LABEL_254;
-            }
-            if ( v82 )
-              goto LABEL_217;
-            v70 = (signed __int64)v48;
-            v62 = &pDir;
-            v59 = 0;
-            goto LABEL_237;
-          }
-          v49 = v84 == 0;
-          goto LABEL_209;
-        }
-LABEL_241:
-        if ( !v21->pMonsterInfo.uMovementType )
-        {
-          v68 = 0;
-          v61 = 1024;
-LABEL_252:
-          v41 = v32;
-          v40 = 4;
-LABEL_253:
-          Actor::_4032B2(v41, v40, v61, v68);
-          goto LABEL_254;
-        }
-        if ( v21->pMonsterInfo.uMovementType == 1 )
-        {
-          v68 = 0;
-          v61 = 2560;
-          goto LABEL_252;
-        }
-        if ( v21->pMonsterInfo.uMovementType == 2 )
-        {
-          v68 = 0;
-          v61 = 5120;
-          goto LABEL_252;
-        }
-        if ( v21->pMonsterInfo.uMovementType == 4 )
-        {
-          v68 = 0;
-          v61 = 10240;
-          goto LABEL_252;
-        }
-        if ( v21->pMonsterInfo.uMovementType == 5 )
-        {
-          v57 = Actor::GetDirectionInfo(a1, 4u, &v72, 0);
-          v58 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-          memcpy(&v74, v57, sizeof(v74));
-          memcpy(&pDir, &v74, sizeof(pDir));
-          v69 = &pDir;
-          v52 = actor_id;
-          v64 = (signed __int64)v58;
-          v51 = 4;
-          goto LABEL_247;
-        }
-        goto LABEL_254;
-      }
-      if ( !v21->pMonsterInfo.uMissleAttack2Type )
-      {
-        v56 = v80 * 307.2;
-        if ( (double)v81 >= v56 )
-        {
-          if ( v81 >= 1024 )
-          {
-            v50 = v82 == 0;
-            goto LABEL_215;
-          }
-LABEL_235:
-          if ( v82 )
-            goto LABEL_217;
-          v70 = (signed __int64)v56;
-          v62 = &pDir;
-          v59 = 0;
-LABEL_237:
-          Actor::_40281C(v32, a2, v59, v62, v70);
-          goto LABEL_254;
-        }
-LABEL_227:
-        v49 = v84 == 0;
-LABEL_209:
-        v69 = &pDir;
-        if ( v49 )
-          goto LABEL_218;
-        Actor::_403C6C(v32, a2, &pDir);
-        goto LABEL_254;
-      }
-      if ( !v84 )
-        goto LABEL_223;
-      Actor::_40368B(v32, a2, &pDir);
-LABEL_254:
-      ++v78;
-      if ( v78 >= ai_arrays_size )
-        return;
-    }
-    v65 = v21->pMonsterInfo.uSpellSkillAndMastery1;
-    v60 = 2;
-    v33 = v21->pMonsterInfo.uSpell1ID;
-    goto LABEL_146;
-  }
+void __cdecl UpdateActorAI()
+{
+	//unsigned int v0; // esi@4
+	int v1; // eax@7
+	int v2; // ecx@7
+	int v3; // eax@7
+	signed int v4; // edi@10
+	Actor *v5; // esi@12
+	signed int v6; // eax@14
+	__int16 v7; // cx@14
+	Player **v8; // esi@20
+	Player *pPlayer; // ecx@21
+	//Actor *pActor; // esi@34
+	//__int16 v11; // ax@34
+	//unsigned int v12; // eax@47
+	//signed int v13; // edi@47
+	//SpellBuff *v14; // ebx@47
+	//unsigned int v15; // edi@67
+	//char *v16; // eax@67
+	//unsigned int v17; // edx@67
+	//unsigned int v18; // ecx@67
+	//unsigned __int16 v19; // ax@72
+	//int *v20; // esi@80
+	Actor *v21; // ebx@80
+	unsigned __int16 v22; // ax@86
+	//signed int v23; // eax@94
+	//unsigned int v24; // eax@102
+	signed int v25; // edi@102
+	SpellBuff *v26; // esi@102
+	unsigned int v27; // ecx@123
+	unsigned int v28; // eax@123
+	unsigned int v29; // eax@127
+	AIDirection *v30; // eax@129
+	unsigned __int16 v31; // ax@132
+	unsigned int v32; // esi@142
+	int v33; // eax@144
+	int v34; // eax@147
+	char v35; // al@150
+	unsigned int v36; // edi@152
+	signed int v37; // eax@154
+	unsigned __int8 v38; // sf@158
+	unsigned __int8 v39; // of@158
+	signed int v40; // edx@166
+	unsigned int v41; // ecx@166
+	double v42; // st7@176
+	double v43; // st6@176
+	bool v44; // eax@189
+	bool v45; // eax@192
+	unsigned __int8 v46; // cl@197
+	double v47; // st7@206
+	double v48; // st7@207
+	char v49; // zf@208
+	char v50; // zf@214
+	signed int v51; // edx@219
+	unsigned int v52; // ecx@219
+	__int16 v53; // fps@224
+	unsigned __int8 v54; // c0@224
+	unsigned __int8 v55; // c3@224
+	double v56; // st7@226
+	AIDirection *v57; // eax@246
+	double v58; // st7@246
+	signed int v59; // [sp-18h] [bp-C8h]@213
+	int v60; // [sp-14h] [bp-C4h]@144
+	int v61; // [sp-14h] [bp-C4h]@168
+	AIDirection *v62; // [sp-14h] [bp-C4h]@213
+	signed int v63; // [sp-14h] [bp-C4h]@216
+	unsigned int v64; // [sp-14h] [bp-C4h]@219
+	unsigned int v65; // [sp-10h] [bp-C0h]@144
+	char v66; // [sp-10h] [bp-C0h]@147
+	AIDirection *v67; // [sp-10h] [bp-C0h]@167
+	int v68; // [sp-10h] [bp-C0h]@168
+	AIDirection *v69; // [sp-10h] [bp-C0h]@206
+	int v70; // [sp-10h] [bp-C0h]@213
+	AIDirection *v71; // [sp-10h] [bp-C0h]@216
+	AIDirection v72; // [sp+0h] [bp-B0h]@246
+	AIDirection a3; // [sp+1Ch] [bp-94h]@129
+	AIDirection v74; // [sp+38h] [bp-78h]@246
+	AIDirection v75; // [sp+54h] [bp-5Ch]@129
+	int v76; // [sp+70h] [bp-40h]@83
+	signed int a1; // [sp+74h] [bp-3Ch]@129
+	int v78; // [sp+78h] [bp-38h]@79
+	AIDirection pDir; // [sp+7Ch] [bp-34h]@129
+	float v80; // [sp+98h] [bp-18h]@33
+	int v81; // [sp+9Ch] [bp-14h]@100
+	int v82; // [sp+A0h] [bp-10h]@45
+	//unsigned int uActorID; // [sp+A4h] [bp-Ch]@32
+	unsigned int v84; // [sp+A8h] [bp-8h]@11
+	signed int a2; // [sp+ACh] [bp-4h]@83
+	
+	if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor)
+	MakeActorAIList_ODM();
+	else
+	MakeActorAIList_BLV();
+	
+	//v0 = 0;
+	if ( uCurrentlyLoadedLevelType != LEVEL_Indoor && pParty->armageddon_timer > 0 )
+	{
+		if ( pParty->armageddon_timer > 417 )
+		{
+			pParty->armageddon_timer = 0;
+		}
+		else
+		{
+			pParty->sRotationY = (stru_5C6E00->uIntegerDoublePi - 1) & (pParty->sRotationY + rand() % 16 - 8);
+			v1 = rand();
+			v2 = 128;
+			v3 = pParty->sRotationX + v1 % 16 - 8;
+			pParty->sRotationX = v3;
+			if ( v3 > 128 || (v2 = -128, v3 < -128) )
+			pParty->sRotationX = v2;
+			pParty->uFlags |= 2u;
+			pParty->armageddon_timer -= pMiscTimer->uTimeElapsed;
+			v4 = pParty->field_16140 + 50;
+			if ( pParty->armageddon_timer <= 0 )
+			{
+				pParty->armageddon_timer = 0;
+				v84 = 0;
+				if ( (signed int)uNumActors > 0 )
+				{
+					v5 = pActors;//[0].sCurrentHP;
+					do
+					{
+						if ( v5->CanAct() )
+						{
+							v6 = stru_50C198.CalcMagicalDamageToActor(v5, 5, v4);
+							v7 = v5->sCurrentHP - v6;
+							v5->sCurrentHP = v7;
+							if ( v6 )
+							{
+								if ( v7 >= 0 )
+								{
+									Actor::_4030AD(v84, 4, 0);
+								}
+								else
+								{
+									Actor::Die(v84);
+									if ( v5->pMonsterInfo.uExp )
+									GivePartyExp(pMonsterStats->pInfos[v5->pMonsterInfo.uID].uExp);
+								}
+							}
+						}
+						++v84;
+						++v5;
+					}
+					while ( (signed int)v84 < (signed int)uNumActors );
+				}
+				v8 = &pPlayers[1];
+				do
+				{
+					pPlayer = *v8;
+					if ( !(*v8)->pConditions[14] && !pPlayer->pConditions[15] && !pPlayer->pConditions[16] )
+					pPlayer->ReceiveDamage(v4, 5);
+					++v8;
+				}
+				while ( (signed int)v8 <= (signed int)&pPlayers[4] );
+				//v0 = 0;
+			}
+			if (pTurnEngine->field_1C)
+			--pTurnEngine->field_1C;
+		}
+	}
+	
+	if (pParty->bTurnBasedModeOn)
+	{
+		pTurnEngine->_405E14();
+		return;
+	}
+	
+	
+	//uActorID = v0;
+	for (uint i = 0; i < uNumActors; ++i)
+	{
+		auto actor = pActors + i;
+		//LODWORD(v80) = (int)(char *)pActors + 176; // uAIState
+		//do
+		//{
+			//pActor = (Actor *)(LODWORD(v80) - 176);
+			//v11 = *(unsigned int *)LODWORD(v80);
+			//v49 = *(unsigned int *)LODWORD(v80) == 5;
+			ai_near_actors_targets_pid[i] = OBJECT_Player;
+			if (actor->uAIState == Dead || actor->uAIState == Removed || actor->uAIState == Disabled || actor->uAttributes & 0x0400)
+			continue;
+			
+			if (!actor->sCurrentHP && actor->uAIState != Dying)
+			Actor::Die(i);
+			
+			//v84 = *(_QWORD *)(LODWORD(v80) + 84) <= 0i64 ? 0 : 1;
+			//v82 = *(_QWORD *)(LODWORD(v80) + 52) <= 0i64 ? 0 : 1;
+			//v12 = 0;
+			//v13 = 0;
+			//v14 = (SpellBuff *)(LODWORD(v80) + 36);
+			for (uint j = 0; j < 22; ++j)
+			{
+				if (j != 10)
+				actor->pActorBuffs[j]._4585CA(pParty->uTimePlayed);
+			}
+			/*do
+			{
+				if ( v13 != 10 )
+				{
+					v14->_4585CA(pParty->uTimePlayed);
+					v12 = 0;
+				}
+				++v13;
+				++v14;
+			}
+			while ( v13 < 22 );*/
+			if (!actor->pActorBuffs[ACTOR_BUFF_SHRINK].uExpireTime)
+			//&& SHIDWORD(pActor->pActorBuffs[3].uExpireTime) <= (signed int)v12 && (SHIDWORD(pActor->pActorBuffs[3].uExpireTime) < (signed int)v12
+			// || LODWORD(pActor->pActorBuffs[3].uExpireTime) <= v12) )
+			actor->uActorHeight = pMonsterList->pMonsters[actor->pMonsterInfo.uID - 1].uMonsterHeight;
+			if (actor->pActorBuffs[ACTOR_BUFF_CHARM].uExpireTime)
+			actor->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly;
+			else
+			actor->pMonsterInfo.uHostilityType = pMonsterStats->pInfos[actor->pMonsterInfo.uID].uHostilityType;
+			
+			if (actor->pActorBuffs[ACTOR_BUFF_PARALYZED].uExpireTime ||
+			actor->pActorBuffs[ACTOR_BUFF_STONED].uExpireTime)
+			continue;
+			
+			//v15 = pMiscTimer->uTimeElapsed;
+			//v16 = (char *)&pActor->pMonsterInfo.uRecoveryTime;
+			//v17 = pActor->uCurrentActionTime;
+			//v18 = pActor->pMonsterInfo.uRecoveryTime;
+			if (actor->pMonsterInfo.uRecoveryTime)
+			{
+				if (actor->pMonsterInfo.uRecoveryTime < pMiscTimer->uTimeElapsed)
+				actor->pMonsterInfo.uRecoveryTime = 0;
+				else actor->pMonsterInfo.uRecoveryTime -= pMiscTimer->uTimeElapsed;
+			}
+			
+			actor->uCurrentActionTime += pMiscTimer->uTimeElapsed;
+			if (actor->uCurrentActionTime < actor->uCurrentActionLength)
+			continue;
+			
+			//v19 = actor->uAIState;
+			if (actor->uAIState == Dying)
+			actor->uAIState = Dead;
+			else
+			{
+				if (actor->uAIState != Summoned)
+				{
+					Actor::AI_StandOrBored(i, OBJECT_Player, 256, nullptr);
+					continue;
+				}
+				actor->uAIState = Standing;
+			}
+			
+			actor->uCurrentActionTime = 0;
+			actor->uCurrentActionLength = 0;
+			actor->UpdateAnimation();
+			//LABEL_78:
+			//++uActorID;
+			//LODWORD(v80) += 836;
+		//}
+		//while ( (signed int)uActorID < (signed int)uNumActors );
+	}
+	
+	
+	v78 = 0;
+	int actor_id = -1;
+	if ( ai_arrays_size > 0 )
+	{
+		//while ( 1 )
+		for(v78 = 0; v78 < ai_arrays_size; ++v78)
+		{
+			actor_id = ai_near_actors_ids[v78];
+			assert(actor_id < uNumActors);
+			
+			//v20 = &ai_near_actors_targets_pid[actor_id];
+			v21 = &pActors[actor_id];
+			Actor::_SelectTarget(actor_id, &ai_near_actors_targets_pid[actor_id], true);
+			if (v21->pMonsterInfo.uHostilityType && !ai_near_actors_targets_pid[actor_id])
+			v21->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly;
+			a2 = ai_near_actors_targets_pid[actor_id];
+			v76 = a2 & 7;
+			if ( (a2 & 7) == OBJECT_Actor)
+			v80 = 0.5;
+			else
+			v80 = 1.0;
+			v22 = v21->uAIState;
+			if ( v22 == Dying || v22 == Dead || v22 == Removed || v22 == Disabled || v22 == Summoned)
+			{
+				continue;
+			}
+			else
+			{
+				if ( !v21->sCurrentHP )
+				Actor::Die(actor_id);
+				v25 = 0;
+				v26 = v21->pActorBuffs;
+				do
+				{
+					if ( v25 != 10 )
+					{
+						v26->_4585CA(pParty->uTimePlayed);
+						//v24 = 0;
+					}
+					++v25;
+					++v26;
+				}
+				while ( v25 < 22 );
+				if ( (signed __int64)v21->pActorBuffs[3].uExpireTime > 0
+				&& SHIDWORD(v21->pActorBuffs[3].uExpireTime) <= 0
+				&& (SHIDWORD(v21->pActorBuffs[3].uExpireTime) < 0
+				|| LODWORD(v21->pActorBuffs[3].uExpireTime) <= 0) )
+				v21->uActorHeight = pMonsterList->pMonsters[v21->pMonsterInfo.uID - 1].uMonsterHeight;
+				if ( (signed __int64)v21->pActorBuffs[1].uExpireTime > 0 )
+				{
+					v21->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly;
+					if ( SHIDWORD(v21->pActorBuffs[1].uExpireTime) <= 0 )
+					{
+						if ( SHIDWORD(v21->pActorBuffs[1].uExpireTime) < 0
+						|| LODWORD(v21->pActorBuffs[1].uExpireTime) <= 0 )
+						v21->pMonsterInfo.uHostilityType = pMonsterStats->pInfos[v21->pMonsterInfo.uID].uHostilityType;
+					}
+				}
+				if ( (signed __int64)v21->pActorBuffs[2].uExpireTime > 0
+				&& SHIDWORD(v21->pActorBuffs[2].uExpireTime) <= 0
+				&& (SHIDWORD(v21->pActorBuffs[2].uExpireTime) < 0
+				|| LODWORD(v21->pActorBuffs[2].uExpireTime) <= 0) )
+				{
+					v21->uAIState = Removed;
+					continue;
+				}
+				else if ( v21->pActorBuffs[5].uExpireTime || v21->pActorBuffs[6].uExpireTime )
+				{
+					continue;
+				}
+				else
+				{
+					v27 = pMiscTimer->uTimeElapsed;
+					v28 = v21->pMonsterInfo.uRecoveryTime;
+					v21->uCurrentActionTime += pMiscTimer->uTimeElapsed;
+					if ( (signed int)v28 > 0 )
+					v21->pMonsterInfo.uRecoveryTime = v28 - v27;
+					if ( v21->pMonsterInfo.uRecoveryTime< 0 )
+					v21->pMonsterInfo.uRecoveryTime = 0;
+					v29 = v21->uAttributes;
+					if ( !(v29 & 0x8000) )
+					v21->uAttributes = v29 | 0x8000;
+					a1 = 8 * actor_id | OBJECT_Actor;
+					v30 = Actor::GetDirectionInfo(8 * actor_id | OBJECT_Actor, a2, &a3, 0);
+					v49 = v21->pMonsterInfo.uHostilityType == 0;
+					memcpy(&v75, v30, sizeof(v75));
+					memcpy(&pDir, &v75, sizeof(pDir));
+					if ( !v49
+					&& (signed int)v21->pMonsterInfo.uRecoveryTime <= 0
+					&& v80 * 307.2 >= (double)(signed int)v75.uDistance
+					&& ((v31 = v21->uAIState, v31 == 6) || !v31 || v31 == 1 || v31 == 9)
+					|| v21->pMonsterInfo.uMissleAttack1Type && v21->uAIState == 8 )
+					{
+						v32 = actor_id;
+					}
+					else
+					{
+						if ( (signed int)v21->uCurrentActionTime < v21->uCurrentActionLength )
+						{
+							continue;
+						}
+						else if ( v21->uAIState == 2 )
+						{
+							v32 = actor_id;
+							v35 = stru_50C198.special_ability_use_check(v21, actor_id);
+							stru_50FE08.Add(
+							a1,
+							5120,
+							v21->vPosition.x,
+							v21->vPosition.y,
+							v21->vPosition.z + ((signed int)v21->uActorHeight >> 1),
+							v35,
+							1
+							);
+						}
+						else if ( v21->uAIState == 3 )
+						{
+							v34 = v21->pMonsterInfo.uMissleAttack1Type;
+							v66 = 0;
+							v32 = actor_id;
+							Actor::_404874(actor_id, &pDir, v34, v66);
+						}
+						else if ( v21->uAIState == 12 )
+						{
+							v34 = v21->pMonsterInfo.uMissleAttack2Type;
+							v66 = 1;
+							v32 = actor_id;
+							Actor::_404874(actor_id, &pDir, v34, v66);
+						}
+						else
+						{
+							v32 = actor_id;
+							if ( v21->uAIState == 13 )
+							{
+								v65 = v21->pMonsterInfo.uSpellSkillAndMastery1;
+								v60 = 2;
+								v33 = v21->pMonsterInfo.uSpell1ID;
+								Actor::_404AC7(actor_id, &pDir, v33, v60, v65);
+							}
+							else if ( v21->uAIState == 18 )
+							{
+								v65 = v21->pMonsterInfo.uSpellSkillAndMastery2;
+								v60 = 3;
+								v33 = v21->pMonsterInfo.uSpell2ID;
+								Actor::_404AC7(actor_id, &pDir, v33, v60, v65);
+							}
+						}
+					}
+				}
+			}
+			v36 = v75.uDistance;
+			if ( !v21->pMonsterInfo.uHostilityType )
+			{
+				if ( v76 == 3 )
+				{
+					v36 = v75.uDistance;
+					v37 = (unsigned __int8)*(&byte_5C8D1A[89 * (v21->pMonsterInfo.uID - 1) / 3]
+					+ (pActors[a2 >> 3].pMonsterInfo.uID - 1) / 3);
+				}
+				else
+				{
+					v37 = 4;
+				}
+				if ( v37 == 2 )
+				{
+					v39 = __OFSUB__(v36, 1024);
+					v38 = ((v36 - 1024) & 0x80000000u) != 0;
+				}
+				else if ( v37 == 3 )
+				{
+					v39 = __OFSUB__(v36, 2560);
+					v38 = ((v36 - 2560) & 0x80000000u) != 0;
+				}
+				else if ( v37 == 4 )
+				{
+					v39 = __OFSUB__(v36, 5120);
+					v38 = ((v36 - 5120) & 0x80000000u) != 0;
+				}
+				if ( v37 >= 1 && v37 <= 4 && v38 ^ v39 || v37 == 1 )
+				v21->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Long;
+			}
+			if ( (signed __int64)v21->pActorBuffs[4].uExpireTime > 0 )
+			{
+				v40 = a2;
+				v41 = v32;
+				if ( (signed int)v36 >= 10240 )
+				{
+					v68 = 0;
+					v61 = 1024;
+					Actor::_4032B2(v41, v40, v61, v68);
+					continue;
+				}
+				v67 = &pDir;
+				Actor::_402968(v41, v40, 0, v67);
+				continue;
+			}
+			if ( v21->pMonsterInfo.uHostilityType == 4 && a2 )
+			{
+				if ( !(v21->uAttributes & 0x020000) || v21->pMonsterInfo.uAIType == 1 )
+				{
+					if ( v21->pMonsterInfo.uAIType == 1 )
+					{
+						v67 = &pDir;
+						if ( v21->pMonsterInfo.uMovementType != 5 )
+						{
+							v40 = a2;
+							v41 = v32;
+							Actor::_402968(v41, v40, 0, v67);
+							continue;
+						}
+						Actor::AI_Stand(
+						v32,
+						a2,
+						(signed __int64)((double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333),
+						&pDir);
+					}
+					else
+					{
+						if ( v21->pMonsterInfo.uAIType == 2 )
+						{
+							v84 = v21->sCurrentHP;
+							v42 = (double)(signed int)v84;
+							v43 = (double)(signed int)v21->pMonsterInfo.uHP * 0.2;
+						}
+						else
+						{
+							v84 = v21->sCurrentHP;
+							v42 = (double)(signed int)v84;
+							v43 = (double)(signed int)v21->pMonsterInfo.uHP * 0.1;
+						}
+						if ( v21->pMonsterInfo.uAIType == 2 || v21->pMonsterInfo.uAIType == 3 )
+						if ( v43 > v42 && (signed int)v36 < 10240 )
+						{
+							v67 = &pDir;
+							v40 = a2;
+							v41 = v32;
+							Actor::_402968(v41, v40, 0, v67);
+							continue;
+						}
+					}
+				}
+				v81 = v36 - v21->uActorRadius;
+				if ( v76 == 3 )
+				v81 -= pActors[a2 >> 3].uActorRadius;
+				if ( v81 < 0 )
+				v81 = 0;
+				rand();
+				v44 = (signed int)v21->pMonsterInfo.uRecoveryTime <= 0;
+				v21->uAttributes &= 0xFBFFFF;
+				v82 = 0;
+				v49 = v21->pMonsterInfo.uMovementType == 5;
+				v84 = v44;
+				if ( v49 )
+				v82 = 1;
+				if ( v81 < 5120 )
+				{
+					v45 = stru_50C198.special_ability_use_check(v21, v32);
+					if ( !v45 )
+					{
+						if ( v21->pMonsterInfo.uMissleAttack1Type )
+						{
+							if ( v84 )
+							{
+								Actor::_403476(v32, a2, &pDir);
+								continue;
+								
+							}
+							if ( v82 )
+							{
+								v69 = &pDir;
+								v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+								v51 = a2;
+								v64 = (signed __int64)v47;
+								v52 = v32;
+								Actor::AI_Stand(v52, v51, v64, v69);
+								continue;
+							}
+							v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+							//UNDEF(v53);
+							v69 = &pDir;
+							if ( !(v54 | v55) )
+							{
+								v51 = a2;
+								v64 = (signed __int64)v47;
+								v52 = v32;
+								Actor::AI_Stand(v52, v51, v64, v69);
+								continue;
+							}
+							Actor::_402AD7(v32, a2, v32, (signed __int64)v47, v69);
+							continue;
+						}
+						v56 = v80 * 307.2;
+						if ( (double)v81 >= v56 )
+						{
+							if ( v81 >= 1024 )
+							{
+								if ( v82 )
+								{
+									v69 = &pDir;
+									v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+									v51 = a2;
+									v64 = (signed __int64)v47;
+									v52 = v32;
+									Actor::AI_Stand(v52, v51, v64, v69);
+									continue;
+								}
+								v71 = &pDir;
+								v63 = 0;
+								
+								Actor::_402686(v32, a2, v63, v71);
+								continue;
+							}
+							if ( v82 )
+							{
+								v69 = &pDir;
+								v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+								v51 = a2;
+								v64 = (signed __int64)v47;
+								v52 = v32;
+								Actor::AI_Stand(v52, v51, v64, v69);
+								continue;
+							}
+							v70 = (signed __int64)v56;
+							v62 = &pDir;
+							v59 = 0;
+							Actor::_40281C(v32, a2, v59, v62, v70);
+							continue;
+						}
+						v49 = v84 == 0;
+						v69 = &pDir;
+						if ( v49 )
+						{
+							v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+							v51 = a2;
+							v64 = (signed __int64)v47;
+							v52 = v32;
+							Actor::AI_Stand(v52, v51, v64, v69);
+							continue;
+						}
+						Actor::_403C6C(v32, a2, &pDir);
+						continue;
+					}
+					if ( v45 != 1 )
+					{
+						if ( v45 > 1 && v45 <= 3 )
+						{
+							if ( v45 == 2 )
+							v46 = v21->pMonsterInfo.uSpell1ID;
+							else
+							v46 = v21->pMonsterInfo.uSpell2ID;
+							if ( v46 )
+							{
+								if ( v84 )
+								{
+									if ( v45 == 2 )
+									Actor::_403854(v32, a2, &pDir);
+									else
+									Actor::_403A60(v32, a2, &pDir);
+									continue;
+								}
+								if ( v80 * 307.2 > (double)v81 || v82 )
+								{
+									v69 = &pDir;
+									v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+									v51 = a2;
+									v64 = (signed __int64)v47;
+									v52 = v32;
+									Actor::AI_Stand(v52, v51, v64, v69);
+									continue;
+									
+								}
+								v69 = &pDir;
+								v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+								Actor::_402AD7(v32, a2, v32, (signed __int64)v47, v69);
+								continue;
+							}
+							v48 = v80 * 307.2;
+							if ( (double)v81 >= v48 )
+							{
+								if ( v81 >= 1024 )
+								{
+									v50 = v82 == 0;
+									if ( !v50 )
+									{
+										v69 = &pDir;
+										v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+										v51 = a2;
+										v64 = (signed __int64)v47;
+										v52 = v32;
+										Actor::AI_Stand(v52, v51, v64, v69);
+										continue;
+									}
+									v71 = &pDir;
+									v63 = 256;
+									Actor::_402686(v32, a2, v63, v71);
+									continue;
+									
+								}
+								if ( v82 )
+								{
+									v69 = &pDir;
+									v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+									v51 = a2;
+									v64 = (signed __int64)v47;
+									v52 = v32;
+									Actor::AI_Stand(v52, v51, v64, v69);
+									continue;
+								}
+								v70 = (signed __int64)v48;
+								v62 = &pDir;
+								v59 = 0;
+								Actor::_40281C(v32, a2, v59, v62, v70);
+								continue;
+							}
+							v49 = v84 == 0;
+							v69 = &pDir;
+							if ( v49 )
+							{
+								v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+								v51 = a2;
+								v64 = (signed __int64)v47;
+								v52 = v32;
+								Actor::AI_Stand(v52, v51, v64, v69);
+								continue;
+							}
+							Actor::_403C6C(v32, a2, &pDir);
+							continue;
+						}
+					}
+				}
+			}
+			if ( v21->pMonsterInfo.uHostilityType != 4 || !a2 || v81 >= 5120 || v45 != 1 )
+			{
+				if ( !v21->pMonsterInfo.uMovementType )
+				{
+					v68 = 0;
+					v61 = 1024;
+					v41 = v32;
+					v40 = 4;
+					Actor::_4032B2(v41, v40, v61, v68);
+					continue;
+					
+				}
+				if ( v21->pMonsterInfo.uMovementType == 1 )
+				{
+					v68 = 0;
+					v61 = 2560;
+					v41 = v32;
+					v40 = 4;
+					Actor::_4032B2(v41, v40, v61, v68);
+					continue;
+				}
+				if ( v21->pMonsterInfo.uMovementType == 2 )
+				{
+					v68 = 0;
+					v61 = 5120;
+					v41 = v32;
+					v40 = 4;
+					Actor::_4032B2(v41, v40, v61, v68);
+					continue;
+				}
+				if ( v21->pMonsterInfo.uMovementType == 4 )
+				{
+					v68 = 0;
+					v61 = 10240;
+					v41 = v32;
+					v40 = 4;
+					Actor::_4032B2(v41, v40, v61, v68);
+					continue;
+				}
+				if ( v21->pMonsterInfo.uMovementType == 5 )
+				{
+					v57 = Actor::GetDirectionInfo(a1, 4u, &v72, 0);
+					v58 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+					memcpy(&v74, v57, sizeof(v74));
+					memcpy(&pDir, &v74, sizeof(pDir));
+					v69 = &pDir;
+					v52 = actor_id;
+					v64 = (signed __int64)v58;
+					v51 = 4;
+					Actor::AI_Stand(v52, v51, v64, v69);
+					continue;
+				}
+				continue;
+				
+			}
+			if ( !v21->pMonsterInfo.uMissleAttack2Type )
+			{
+				v56 = v80 * 307.2;
+				if ( (double)v81 >= v56 )
+				{
+					if ( v81 >= 1024 )
+					{
+						v50 = v82 == 0;
+						if ( !v50 )
+						{
+							v69 = &pDir;
+							v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+							v51 = a2;
+							v64 = (signed __int64)v47;
+							v52 = v32;
+							Actor::AI_Stand(v52, v51, v64, v69);
+							continue;
+						}
+						v71 = &pDir;
+						v63 = 256;
+						Actor::_402686(v32, a2, v63, v71);
+						continue;
+					}
+					if ( v82 )
+					{
+						v69 = &pDir;
+						v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+						v51 = a2;
+						v64 = (signed __int64)v47;
+						v52 = v32;
+						Actor::AI_Stand(v52, v51, v64, v69);
+						continue;
+					}
+					v70 = (signed __int64)v56;
+					v62 = &pDir;
+					v59 = 0;
+					Actor::_40281C(v32, a2, v59, v62, v70);
+					continue;
+					
+				}
+				v49 = v84 == 0;
+				v69 = &pDir;
+				if ( v49 )
+				{
+					v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+					v51 = a2;
+					v64 = (signed __int64)v47;
+					v52 = v32;
+					Actor::AI_Stand(v52, v51, v64, v69);
+					continue;
+				}
+				Actor::_403C6C(v32, a2, &pDir);
+				continue;
+			}
+			if ( !v84 )
+			{
+				if ( v82 )
+				{
+					v69 = &pDir;
+					v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+					v51 = a2;
+					v64 = (signed __int64)v47;
+					v52 = v32;
+					Actor::AI_Stand(v52, v51, v64, v69);
+					continue;
+				}
+				v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+				//UNDEF(v53);
+				v69 = &pDir;
+				if ( !(v54 | v55) )
+				{
+					v51 = a2;
+					v64 = (signed __int64)v47;
+					v52 = v32;
+					Actor::AI_Stand(v52, v51, v64, v69);
+					continue;
+				}
+				Actor::_402AD7(v32, a2, v32, (signed __int64)v47, v69);
+				continue;
+			}
+			Actor::_40368B(v32, a2, &pDir);
+		}
+	}
 }
 
 //----- (0040261D) --------------------------------------------------------
@@ -15978,6 +16107,7 @@
   {
     do
     {
+      __debugbreak();
       *(&v31.uDistance + v18) = pParty->pPlayers[*(&v1->field_0 + 4 * (*(&a3.uDistance + v18) + 2)) >> 3].GetAttackRecoveryTime(
                                   v2);
       ++v18;
--- a/mm7_4.cpp	Tue Mar 26 23:18:58 2013 +0600
+++ b/mm7_4.cpp	Tue Mar 26 23:19:12 2013 +0600
@@ -2074,11 +2074,11 @@
       a3.y = 0;
       a3.x = 0;
       a1.stru_24.Reset();
-      a1.field_4C = pParty->pPartyBuffs[10].uPower;
-      a1.field_50 = pParty->ImmolationSkillLevel();
+      a1.spell_level = pParty->pPartyBuffs[PARTY_BUFF_IMMOLATION].uPower;
+      a1.spell_skill = pParty->ImmolationSkillLevel();
       v10 = 0;
       a1.uType = 1070;
-      a1.field_48 = 8;
+      a1.spell_id = SPELL_FIRE_IMMOLATION;
       if ( (signed int)pObjectList->uNumObjects <= 0 )
       {
 LABEL_19:
@@ -2102,7 +2102,7 @@
       a1.uAttributes = 0;
       a1.uSectorID = 0;
       a1.uSpriteFrameID = 0;
-      a1.field_58_pid = v12;
+      a1.spell_caster_pid = v12;
       a1.uFacing = 0;
       a1.uSoundID = 0;
       v13 = sub_46A89E((int)v41, 100, 307);
@@ -2119,7 +2119,7 @@
           v18 = 8 * v15;
           LOBYTE(v18) = 8 * v15 | 3;
           a1.vPosition.y = v17;
-          a1.field_5C = v18;
+          a1.spell_target_pid = v18;
           v19 = a1.Create(0, 0, 0, 0);
           DamageMonsterFromParty(8 * v19 | 2, *v14, &a3);
           ++v9;
@@ -2377,8 +2377,8 @@
   Player **v16; // esi@43
   Player *v17; // edi@44
   double v18; // st7@44
-  float v19; // ST28_4@48
-  double v20; // ST38_8@48
+  //float v19; // ST28_4@48
+  //double v20; // ST38_8@48
   Player *v21; // esi@51
   signed int v22; // edi@53
   int v23; // eax@59
@@ -2418,7 +2418,7 @@
   //int v57; // [sp-4h] [bp-34h]@18
   int v58; // [sp-4h] [bp-34h]@33
   int v59; // [sp-4h] [bp-34h]@55
-  unsigned int v60; // [sp+10h] [bp-20h]@1
+  //unsigned int v60; // [sp+10h] [bp-20h]@1
   unsigned int v61; // [sp+14h] [bp-1Ch]@1
   Player **v62; // [sp+14h] [bp-1Ch]@50
   //unsigned int a2; // [sp+18h] [bp-18h]@1
@@ -2427,7 +2427,7 @@
 
   //a2 = pParty->uCurrentHour;
   v61 = pParty->uDaysPlayed;
-  v60 = pEventTimer->uTimeElapsed;
+  //auto prev_time = pEventTimer->uTimeElapsed;
   pParty->uTimePlayed += pEventTimer->uTimeElapsed;
   v0 = (signed __int64)(pParty->uTimePlayed * 0.234375) / 60;
   v1 = v0;
@@ -2547,13 +2547,13 @@
   }
   _493938_regenerate();
   v65 = 4;
-  a2a = v60;
-  if ( pParty->uFlags2 & 2 )
-  {
-    v19 = (double)(signed int)v60 * 0.5;
-    v20 = v19 + 6.7553994e15;
-    a2a = LODWORD(v20);
-    if ( SLODWORD(v20) <= 0 )
+  a2a = pEventTimer->uTimeElapsed;
+  if ( pParty->uFlags2 & PARTY_FLAGS_2_RUNNING )
+  {
+    //v19 = (double)(signed int)prev_time * 0.5;
+    //v20 = v19 + 6.7553994e15;
+    a2a *= 0.5f;
+    if (a2a < 1)
       a2a = 1;
   }
   v62 = &pPlayers[1];
@@ -2581,7 +2581,7 @@
     v23 = (int)&v21->field_E0;
     if ( v21->field_E0 )
     {
-      v24 = *(int *)v23 - v60;
+      v24 = *(int *)v23 - pEventTimer->uTimeElapsed;
       if ( v24 > 0 )
       {
         *(int *)v23 = v24;
@@ -2595,7 +2595,7 @@
     v25 = (int)&v21->field_E4;
     if ( v21->field_E4 )
     {
-      v26 = *(int *)v25 - v60;
+      v26 = *(int *)v25 - pEventTimer->uTimeElapsed;
       if ( v26 > 0 )
       {
         *(int *)v25 = v26;
@@ -2609,7 +2609,7 @@
     v27 = (int)&v21->field_E8;
     if ( v21->field_E8 )
     {
-      v28 = *(int *)v27 - v60;
+      v28 = *(int *)v27 - pEventTimer->uTimeElapsed;
       if ( v28 > 0 )
       {
         *(int *)v27 = v28;
@@ -2623,7 +2623,7 @@
     v29 = (int)&v21->field_EC;
     if ( v21->field_EC )
     {
-      v30 = *(int *)v29 - v60;
+      v30 = *(int *)v29 - pEventTimer->uTimeElapsed;
       if ( v30 > 0 )
       {
         *(int *)v29 = v30;
@@ -2637,7 +2637,7 @@
     v31 = (int)&v21->field_F0;
     if ( v21->field_F0 )
     {
-      v32 = *(int *)v31 - v60;
+      v32 = *(int *)v31 - pEventTimer->uTimeElapsed;
       if ( v32 > 0 )
       {
         *(int *)v31 = v32;
@@ -2651,7 +2651,7 @@
     v33 = (int)&v21->field_F4;
     if ( v21->field_F4 )
     {
-      v34 = *(int *)v33 - v60;
+      v34 = *(int *)v33 - pEventTimer->uTimeElapsed;
       if ( v34 > 0 )
       {
         *(int *)v33 = v34;
@@ -2665,7 +2665,7 @@
     v35 = (int)&v21->field_F8;
     if ( v21->field_F8 )
     {
-      v36 = *(int *)v35 - v60;
+      v36 = *(int *)v35 - pEventTimer->uTimeElapsed;
       if ( v36 > 0 )
       {
         *(int *)v35 = v36;
@@ -2679,7 +2679,7 @@
     v37 = (int)&v21->field_FC;
     if ( v21->field_FC )
     {
-      v38 = *(int *)v37 - v60;
+      v38 = *(int *)v37 - pEventTimer->uTimeElapsed;
       if ( v38 > 0 )
       {
         *(int *)v37 = v38;
@@ -2693,7 +2693,7 @@
     v39 = (int)&v21->field_100;
     if ( v21->field_100 )
     {
-      v40 = *(int *)v39 - v60;
+      v40 = *(int *)v39 - pEventTimer->uTimeElapsed;
       if ( v40 > 0 )
       {
         *(int *)v39 = v40;
@@ -2707,7 +2707,7 @@
     v41 = (int)&v21->field_104;
     if ( v21->field_104 )
     {
-      v42 = *(int *)v41 - v60;
+      v42 = *(int *)v41 - pEventTimer->uTimeElapsed;
       if ( v42 > 0 )
       {
         *(int *)v41 = v42;
@@ -4298,8 +4298,8 @@
         {
           memcpy(pDst + y * Dst.lPitch / 2,
                  pSrc + y * 640, 8 * sizeof(__int16));
-          memcpy(pDst + 8 + 460/*462*/ + y * Dst.lPitch / 2,
-                 pSrc + 8 + 460/*462*/ + y * 640, 174/*172*/ * sizeof(__int16));
+          memcpy(pDst + 8 + game_viewport_width/*462*/ + y * Dst.lPitch / 2,
+                 pSrc + 8 + game_viewport_width/*462*/ + y * 640, 174/*172*/ * sizeof(__int16));
         }
 
         for (uint y = 352; y < 480; ++y)
@@ -6198,7 +6198,7 @@
   a1.uFrameHeight += v6;
   if ( (signed int)a1.uFrameHeight < 150 )
     a1.uFrameHeight = 150;
-  a1.uFrameWidth = 460;
+  a1.uFrameWidth = game_viewport_width;
   a1.DrawMessageBox(0);
   a1.uFrameWidth -= 12;
   a1.uFrameHeight -= 12;
@@ -7296,7 +7296,7 @@
       if ( v9 )
       {
         v10 = v6->uFlags;
-        a1.uFrameWidth = 460;
+        a1.uFrameWidth = game_viewport_width;
         a1.uFrameZ = 452;
         pInString = (char *)*(&pNPCStats->field_17884 + ((v10 & 3) == 2) + 2 * v9);
         v11 = pFontArrus->CalcTextHeight(pInString, &a1, 13, 0);
--- a/mm7_5.cpp	Tue Mar 26 23:18:58 2013 +0600
+++ b/mm7_5.cpp	Tue Mar 26 23:19:12 2013 +0600
@@ -3485,7 +3485,7 @@
   void *v3; // edi@21
   signed int v4; // eax@29
   int v5; // ecx@29
-  enum PLAYER_SKILL_TYPE v6; // edi@37
+  PLAYER_SKILL_TYPE v6; // edi@37
   GUIWindow *pWindow; // eax@56
   unsigned int v8; // edx@56
   //Player *pCurrentPlayer; // edi@57
@@ -4540,7 +4540,7 @@
       {
         v4 = &pSpriteObjects[v3];
         v36 = v4;
-        v5 = v4->field_58_pid;
+        v5 = v4->spell_caster_pid;
         v2 = v5 & 7;
         v3 = v5 >> 3;
       }
@@ -4781,7 +4781,7 @@
     v4 = &pSpriteObjects[a1 >> 3];
     //uDamageAmount = (int)v4;
     v61 = v4->field_60_distance_related_prolly_lod;
-    a1 = v4->field_58_pid;
+    a1 = v4->spell_caster_pid;
     //v54 = v4->field_58_pid;
   }
   //v5 = a1 & 7;
@@ -4809,7 +4809,7 @@
     //v51 = (unsigned __int64 *)player->pEquipment.uMainHand;
     int main_hand_idx = player->pEquipment.uMainHand;
     v59 = 1;
-    if ( player->HasItemEquipped(EQUIP_TWO_HANDED) )
+    if ( player->HasItemEquipped(EQUIP_MAIN_HAND) )
     {
       auto main_hand_skill = pItemsTable->pItems[player->pInventoryItems[main_hand_idx - 1].uItemID].uSkillType;
       //v55 = pItemsTable->pItems[player->pInventoryItems[main_hand_idx - 1].uItemID].uSkillType;
@@ -4850,7 +4850,7 @@
   }
 
 
-  v19 = v4->field_48 == 99;
+  v19 = v4->spell_id == SPELL_DARK_SOULDRINKER;
   v61 = v4->field_60_distance_related_prolly_lod;
   if ( !v19 )
   {
@@ -4897,8 +4897,8 @@
     v4 = (SpriteObject *)uDamageAmount;
   }
 
-  v15 = v4->field_48;
-  if ( v15 == 102 )
+  v15 = v4->spell_id;
+  if ( v15 == SPELL_LASER_PROJECTILE )
   {
     v16 = player->pActiveSkills[7];
     v61 = 1;
@@ -4908,9 +4908,9 @@
     uDamageAmount = player->CalculateMeleeDamageTo(1, 1, 0);
     goto LABEL_67;
   }
-  if ( v15 != 100 )
-  {
-    if ( v15 == 101 )
+  if ( v15 != SPELL_BOW_ARROW )
+  {
+    if ( v15 == SPELL_101 )
     {
       a2 = 0;
       v18 = player->CalculateRangedDamageTo(0);
@@ -4922,14 +4922,14 @@
       v59 = 1;
       goto LABEL_67;
     }
-    if ( v15 == 39 )
-    {
-      a4 = 5 * v4->field_4C;
+    if ( v15 == SPELL_EARTH_BLADES )
+    {
+      a4 = 5 * v4->spell_level;
       a2 = player->GetSpellSchool(0x27u);
-      v21 = v4->field_4C;
+      v21 = v4->spell_level;
       v50 = pMonster->sCurrentHP;
-      pMonsterName = (char *)v4->field_50;
-      v22 = _43AFE3_calc_spell_damage(39, v21, (signed int)pMonsterName, v50);
+      pMonsterName = (char *)v4->spell_skill;
+      v22 = _43AFE3_calc_spell_damage(39, v21, v4->spell_skill, v50);
       v23 = HIDWORD(pMonster->pActorBuffs[15].uExpireTime) == 0;
       v24 = SHIDWORD(pMonster->pActorBuffs[15].uExpireTime) < 0;
       uDamageAmount = v22;
@@ -4945,24 +4945,23 @@
       }
       goto LABEL_69;
     }
-    if ( v15 == 34 )
+    if ( v15 == SPELL_EARTH_STUN )
     {
       uDamageAmount = 0;
       a2 = 4;
       hit_will_stun = 1;
       goto LABEL_67;
     }
-    v50 = v4->field_48;
-    a2 = player->GetSpellSchool(v50);
-    v25 = v4->field_4C;
-    v26 = v4->field_48;
+    a2 = player->GetSpellSchool(v4->spell_id);
+    v25 = v4->spell_level;
+    v26 = v4->spell_id;
     v50 = pMonster->sCurrentHP;
-    pMonsterName = (char *)v4->field_50;
+    pMonsterName = (char *)v4->spell_skill;
     //v27 = _43AFE3_calc_spell_damage(v26, v25, (signed int)pMonsterName, v50);
     v59 = 0;
     //v57 = (PlayerEquipment *)1;
 //LABEL_65:
-    uDamageAmount = _43AFE3_calc_spell_damage(v26, v25, (signed int)pMonsterName, v50);
+    uDamageAmount = _43AFE3_calc_spell_damage(v26, v25, v4->spell_skill, v50);
     //if ( !v57 )
     //  goto LABEL_67;
     goto LABEL_69;
@@ -5450,10 +5449,10 @@
     return;
   }
   v37 = &pSpriteObjects[uActorID];
-  v38 = v37->field_58_pid & 7;
-  v39 = v37->field_58_pid >> 3;
-  v40 = v37->field_58_pid & 7;
-  uActorID = v37->field_58_pid >> 3;
+  v38 = v37->spell_caster_pid & 7;
+  v39 = v37->spell_caster_pid >> 3;
+  v40 = v37->spell_caster_pid & 7;
+  uActorID = v37->spell_caster_pid >> 3;
   v41 = v40 - 2;
   if ( !v41 )
     goto LABEL_80;
@@ -5514,7 +5513,7 @@
           v77 >>= 1;
         if ( v48 == 531 )
           v77 >>= 1;
-        if ( v45->GetEquippedItemEquipType(v75) == 4 && SkillToMastery(v45->pActiveSkills[8]) == 4 )
+        if ( v45->GetEquippedItemEquipType((ITEM_EQUIP_TYPE)v75) == EQUIP_SHIELD && SkillToMastery(v45->pActiveSkills[PLAYER_SKILL_SHIELD]) == 4 )
           v77 >>= 1;
       }
       ++v75;
@@ -5639,11 +5638,11 @@
     v43 = &pParty->pPlayers[a4];
 LABEL_168:
     a4b = v43;
-    if ( v38 != OBJECT_Player || v37->field_48 != 100 )
+    if ( v38 != OBJECT_Player || v37->spell_id != SPELL_BOW_ARROW)
     {
       v70 = v43->GetMaxHealth();
-      v68 = _43AFE3_calc_spell_damage(v37->field_48, v37->field_4C, v37->field_50, v70);
-      v69 = LOBYTE(pSpellStats->pInfos[v37->field_48].uSchool);
+      v68 = _43AFE3_calc_spell_damage(v37->spell_id, v37->spell_level, v37->spell_skill, v70);
+      v69 = LOBYTE(pSpellStats->pInfos[v37->spell_id].uSchool);
     }
     else
     {
@@ -5690,7 +5689,7 @@
   v6 = uLayingItemID;
   v2 = uLayingItemID;
   v3 = a2 >> 3;
-  v4 = pSpriteObjects[uLayingItemID].field_58_pid & 7;
+  v4 = pSpriteObjects[uLayingItemID].spell_caster_pid & 7;
   v5 = (a2 & 7) - 3;
   if ( v5 )
   {
@@ -5864,10 +5863,10 @@
     if ( (a2 & 7) == OBJECT_Item)
     {
       v4 = &pSpriteObjects[(signed int)a2 >> 3];
-      v5 = v4->field_48;
+      v5 = v4->spell_id;
       if ( v5 )
       {
-        v6 = _43AFE3_calc_spell_damage(v5, v4->field_4C, v4->field_50, pActor->sCurrentHP);
+        v6 = _43AFE3_calc_spell_damage(v5, v4->spell_level, v4->spell_skill, pActor->sCurrentHP);
         v7 = stru_50C198.CalcMagicalDamageToActor(pActor, 0, v6);
         pActor->sCurrentHP -= v7;
         if ( v7 )
@@ -5924,7 +5923,7 @@
   {
     v5 = &pSpriteObjects[a1 >> 3];
     v4 = v5->field_60_distance_related_prolly_lod;
-    v17 = v5->field_58_pid;
+    v17 = v5->spell_caster_pid;
   }
   LOWORD(v6) = v17 & 7;
   if ( v6 == OBJECT_Actor)
@@ -10106,12 +10105,12 @@
   v0 = &pParty->pPlayers[_506348_current_lloyd_playerid];
   pRenderer->DrawTextureIndexed(8u, 8u, pTexture_LloydBeacons[(unsigned __int8)bRecallingBeacon]);
   v1 = pGlobalTXT_LocalizationStrings[523];     // Recall Beacon
-  v22.uFrameX = 8;
-  v22.uFrameY = 8;
+  v22.uFrameX = game_viewport_x;
+  v22.uFrameY = game_viewport_y;
   v22.uFrameWidth = 428;
-  v22.uFrameHeight = 344;
+  v22.uFrameHeight = game_viewport_height;
   v22.uFrameZ = 435;
-  v22.uFrameW = 351;
+  v22.uFrameW = game_viewport_w;
   if ( !bRecallingBeacon )
     v1 = pGlobalTXT_LocalizationStrings[375];   // Set Beacon
   sprintf(pTmpBuf, "%s", v1);
@@ -10264,12 +10263,12 @@
   pRenderer->DrawTextureTransparent(8, 8, pTexture_CurrentBook);
   pRenderer->DrawTextureTransparent(471, 445, pIcons_LOD->GetTexture(uExitCancelTextureId));
 
-  v6.uFrameX = 8;
-  v6.uFrameY = 8;
-  v6.uFrameWidth = 460;
-  v6.uFrameHeight = 344;
-  v6.uFrameZ = 467;
-  v6.uFrameW = 351;
+  v6.uFrameX = game_viewport_x;
+  v6.uFrameY = game_viewport_y;
+  v6.uFrameWidth = game_viewport_width;
+  v6.uFrameHeight = game_viewport_height;
+  v6.uFrameZ = game_viewport_z;
+  v6.uFrameW = game_viewport_w;
   
   const uint fountain_bits_lut[] = {PARTY_QUEST_FOUNTAIN_HARMONDALE,
                                     PARTY_QUEST_FOUNTAIN_PIERPONT,
@@ -10432,12 +10431,12 @@
   {
     v0 -= 12;
   }
-  a1.uFrameX = 8;
-  a1.uFrameY = 8;
-  a1.uFrameWidth = 460;
-  a1.uFrameHeight = 344;
-  a1.uFrameZ = 467;
-  a1.uFrameW = 467;
+  a1.uFrameX = game_viewport_x;
+  a1.uFrameY = game_viewport_y;
+  a1.uFrameWidth = game_viewport_width;
+  a1.uFrameHeight = game_viewport_height;
+  a1.uFrameZ = game_viewport_z;
+  a1.uFrameW = game_viewport_w;
   a1.DrawTitleText(pBook2Font, 0, 0x16u, 0, pGlobalTXT_LocalizationStrings[186], 3u);
   if ( pParty->uCurrentHour >= 12 )
   {
@@ -11802,7 +11801,7 @@
 }
 
 //----- (00417AD4) --------------------------------------------------------
-unsigned int __fastcall GetSkillColor(unsigned int uPlayerClass, enum PLAYER_SKILL_TYPE uPlayerSkillType, signed int skill_level)
+unsigned int __fastcall GetSkillColor(unsigned int uPlayerClass, PLAYER_SKILL_TYPE uPlayerSkillType, signed int skill_level)
 {
   int v8; // eax@10
   int v12; // eax@14
--- a/mm7_6.cpp	Tue Mar 26 23:18:58 2013 +0600
+++ b/mm7_6.cpp	Tue Mar 26 23:19:12 2013 +0600
@@ -2309,7 +2309,7 @@
         v24 = 0;
         v23 = 1;
         v22 = 344;
-        v21 = 460;
+        v21 = game_viewport_width;
         v20 = 8;
         v19 = 8;
         pGUIWindow_Settings = v17;
@@ -2353,7 +2353,7 @@
         pGUIWindow_Settings->CreateButton(0xA5u, 0x1A6u, 0x23u, 0, 2, 0, 0x8Du, 1u, 0x32u, "", 0);
         pGUIWindow_Settings->CreateButton(0x118u, 0x1A6u, 0x23u, 0, 2, 0, 0x8Du, 2u, 0x33u, "", 0);
         pGUIWindow_Settings->CreateButton(0x186u, 0x1A6u, 0x23u, 0, 2, 0, 0x8Du, 3u, 0x34u, "", 0);
-		pGUIWindow_Settings->CreateButton(8, 8, 460, 344, 1, 0, 140, 0, 0, "", NULL);
+		pGUIWindow_Settings->CreateButton(8, 8, game_viewport_width, 344, 1, 0, 140, 0, 0, "", NULL);
 		sub_421B2C_PlaceInInventory_or_DropPickedItem();
       }
       if ( HIBYTE(a5) & 2 && !pGUIWindow_Settings )
@@ -2421,7 +2421,7 @@
 }
 
 //----- (00427DA0) --------------------------------------------------------
-unsigned int stru277::PushStru277(__int16 a2, __int16 uPlayerID, __int16 skill_level, __int16 a5, int a6)
+unsigned int stru277::PushStru277(__int16 a2, __int16 uPlayerID, __int16 skill_level, __int16 a5, int spell_sound_id)
 {
   unsigned int result; // eax@1
   stru277 *v7; // edx@1
@@ -2445,7 +2445,7 @@
   v8->spell_target_pid = 0;
   v8->field_8 = a5;
   v8->forced_spell_skill_level = skill_level;
-  v8->field_10 = a6;
+  v8->sound_id = spell_sound_id;
 LABEL_8:
   if ( result == 10 )
     result = -1;
@@ -2466,17 +2466,17 @@
   //char v9; // al@44
   //int v10; // eax@45
   unsigned __int16 v11; // cx@45
-  signed int v12; // ecx@48
+  //signed int v12; // ecx@48
   //int v13; // eax@53
   unsigned __int8 v14; // zf@53
   //unsigned int v15; // edx@53
   //signed int v16; // eax@53
   Player *v17; // esi@70
-  int v18; // eax@72
-  int v19; // eax@74
+  //int v18; // eax@72
+  //int v19; // eax@74
   char *v20; // eax@74
   signed int i; // esi@76
-  int v22; // eax@88
+  //int v22; // eax@88
   __int16 v23; // ax@88
   //int v24; // ecx@93
   //int v25; // ecx@94
@@ -2488,26 +2488,26 @@
   //int v31; // eax@112
   //int v32; // eax@112
   //char *v33; // edx@113
-  int v34; // eax@121
+  //int v34; // eax@121
   int v35; // eax@123
   int v36; // edx@125
-  int v37; // eax@129
+  //int v37; // eax@129
   signed int v38; // edi@129
   signed int v39; // eax@129
   int v40; // ecx@129
   int v41; // eax@129
   signed int v42; // eax@129
   int *v43; // ecx@129
-  int v44; // eax@132
+  //int v44; // eax@132
   int v45; // ecx@132
   int v46; // eax@132
   unsigned int v47; // edx@133
   int v48; // eax@137
-  int v49; // eax@137
-  int v50; // eax@141
+  //int v49; // eax@137
+  //int v50; // eax@141
   int v51; // eax@146
   __int16 v52; // ax@153
-  int v53; // eax@153
+  //int v53; // eax@153
   signed __int64 v54; // qax@164
   int v55; // edi@164
   //stru6 *v56; // eax@165
@@ -2516,7 +2516,7 @@
   int v59; // edi@177
   unsigned __int16 v60; // ax@184
   int v61; // ecx@184
-  int v62; // eax@186
+  //int v62; // eax@186
   int v63; // ecx@187
   int v64; // ecx@188
   int v65; // ecx@189
@@ -2615,7 +2615,7 @@
   double v158; // st7@326
   double v159; // st6@326
   signed __int64 v160; // qtt@334
-  int v161; // eax@339
+  //int v161; // eax@339
   int v162; // edi@340
   int v163; // eax@340
   signed int v164; // eax@340
@@ -2641,7 +2641,7 @@
   int v184; // ecx@358
   int v185; // ecx@359
   int v186; // ecx@360
-  int v187; // eax@367
+  //int v187; // eax@367
   int v188; // esi@369
   int v189; // edi@369
   //const char *v190; // ecx@377
@@ -2680,7 +2680,7 @@
   char v223; // al@438
   int v224; // ecx@442
   int v225; // ecx@443
-  int v226; // eax@451
+  //int v226; // eax@451
   int v227; // esi@453
   unsigned int v228; // edi@454
   int v229; // edi@466
@@ -2781,7 +2781,7 @@
   char *v324; // eax@635
   Player *v325; // ecx@640
   int v326; // eax@643
-  int v327; // eax@648
+  //int v327; // eax@648
   int v328; // ecx@651
   int v329; // ecx@652
   int v330; // edi@654
@@ -2822,7 +2822,7 @@
   int v365; // ecx@699
   int v366; // eax@701
   //stru6 *v367; // eax@704
-  int v368; // eax@704
+  //int v368; // eax@704
   Actor *v369; // edi@705
   int v370; // eax@706
   int v371; // ecx@709
@@ -2886,7 +2886,7 @@
   int v429; // ecx@826
   int v430; // eax@828
   //stru6 *v431; // eax@831
-  int v432; // eax@831
+  //int v432; // eax@831
   Actor *v433; // edi@832
   int v434; // eax@833
   int v435; // ecx@837
@@ -2960,7 +2960,7 @@
   //stru6 *v503; // eax@940
   //stru6 *v504; // eax@943
   int v505; // eax@943
-  int v506; // eax@943
+  //int v506; // eax@943
   int v507; // edi@944
   int v508; // eax@944
   signed int v509; // eax@944
@@ -2986,7 +2986,7 @@
   //__int16 v529; // ST18_2@975
   //stru6 *v530; // eax@975
   int v531; // eax@982
-  int v532; // eax@982
+  //int v532; // eax@982
   int v533; // edi@983
   int v534; // eax@983
   signed int v535; // eax@983
@@ -3034,7 +3034,7 @@
   Player *v577; // eax@1026
   int v578; // eax@1028
   __int16 v579; // ax@1029
-  int v580; // eax@1031
+  //int v580; // eax@1031
   int v581; // edi@1031
   int v582; // eax@1031
   //__int16 v583; // ST1C_2@1034
@@ -3049,7 +3049,7 @@
   int v592; // esi@1052
   int v593; // ecx@1057
   int v594; // ecx@1058
-  int v595; // eax@1064
+  //int v595; // eax@1064
   int v596; // esi@1066
   unsigned int v597; // edi@1067
   int v598; // eax@1079
@@ -3058,7 +3058,7 @@
   int v601; // edx@1086
   int v602; // eax@1086
   int v603; // ecx@1086
-  int v604; // eax@1087
+  //int v604; // eax@1087
   char *v605; // eax@1089
   int v606; // edx@1091
   int v607; // ecx@1100
@@ -3078,7 +3078,7 @@
   //__int16 v621; // ST18_2@1124
   //stru6 *v622; // eax@1124
   signed __int64 v623; // qax@1127
-  int v624; // eax@1127
+  //int v624; // eax@1127
   int v625; // edi@1129
   int v626; // eax@1129
   signed int v627; // eax@1129
@@ -3121,7 +3121,7 @@
   const char *v664; // [sp+0h] [bp-E84h]@802
   int v665; // [sp+0h] [bp-E84h]@807
   int v666; // [sp+4h] [bp-E80h]@12
-  enum PLAYER_SKILL_TYPE v667; // [sp+4h] [bp-E80h]@25
+  PLAYER_SKILL_TYPE v667; // [sp+4h] [bp-E80h]@25
   //unsigned __int8 v668; // [sp+4h] [bp-E80h]@100
   int v669; // [sp+4h] [bp-E80h]@123
   Vec3_int_ *v670; // [sp+4h] [bp-E80h]@133
@@ -3299,7 +3299,6 @@
 
     if ( HIBYTE(v11) & 1 )
     {
-      v12 = 4;
       v731 = 4;
     }
     else
@@ -3312,15 +3311,14 @@
       {
         v731 = 3;
       }
-      v12 = v731;
     }
 
     v730 = v3->spellnum;
     if (v3->forced_spell_skill_level)
       uRequiredMana = 0;
     else 
-      uRequiredMana = pSpellDatas[v3->spellnum].mana_per_skill[v12 - 1];
-    sRecoveryTime = pSpellDatas[v3->spellnum].recovery_per_skill[v12 - 1];
+      uRequiredMana = pSpellDatas[v3->spellnum].mana_per_skill[v731 - 1];
+    sRecoveryTime = pSpellDatas[v3->spellnum].recovery_per_skill[v731 - 1];
 
     if (LODWORD(v725) == PLAYER_SKILL_DARK && pParty->uCurrentHour == 0 && pParty->uCurrentMinute == 0 ||
         LODWORD(v725) == PLAYER_SKILL_LIGHT && pParty->uCurrentHour == 12 && pParty->uCurrentMinute == 0)
@@ -3374,12 +3372,11 @@
         _this = (ItemGen *)1;
         if ( (signed int)SkillToMastery(pPlayer->pActiveSkills[PLAYER_SKILL_BOW]) >= 3 )
           _this = (ItemGen *)2;
-        sRecoveryTime = v17->GetAttackRecoveryTime(1);
+        sRecoveryTime = v17->GetAttackRecoveryTime(true);
         a1.stru_24.Reset();
-        v18 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_48 = v18;
-        a1.field_50 = v731;
+        a1.spell_level = v2;
+        a1.spell_id = v3->spellnum;
+        a1.spell_skill = v731;
         a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
         if ( v17->WearsItem(510, 2) )
           a1.uObjectDescID = pObjectList->ObjectIDByItemID(0xBD6u);
@@ -3388,13 +3385,11 @@
         a1.uAttributes = 0;
         a1.uSpriteFrameID = 0;
         a1.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
-        v19 = 8 * v3->uPlayerID;
-        LOBYTE(v19) = v19 | OBJECT_Player;
-        a1.field_58_pid = v19;
-        a1.field_5C = a2;
+        a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+        a1.spell_target_pid = a2;
         a1.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
         a1.uFacing = LOWORD(v715.uYawAngle);
-        a1.uSoundID = LOWORD(v3->field_10);
+        a1.uSoundID = LOWORD(v3->sound_id);
         v20 = (char *)&pParty->pPlayers[v3->uPlayerID];
         memcpy(&a1.stru_24, &v20[36 * *((int *)v20 + 1620) + 496], sizeof(a1.stru_24));
         a1.uAttributes = 256;
@@ -3418,22 +3413,20 @@
       case SPELL_LASER_PROJECTILE:
         sRecoveryTime = pPlayer->GetAttackRecoveryTime(0);
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v723;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v723;
+        a1.spell_skill = v731;
         a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
         a1.vPosition.x = pParty->vPosition.x;
         a1.vPosition.y = pParty->vPosition.y;
         a1.uAttributes = 0;
         a1.uSpriteFrameID = 0;
         a1.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 2;
-        v22 = 8 * v3->uPlayerID;
-        LOBYTE(v22) = v22 | OBJECT_Player;
-        a1.field_58_pid = v22;
-        a1.field_5C = a2;
+        a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+        a1.spell_target_pid = a2;
         a1.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
         a1.uFacing = LOWORD(v715.uYawAngle);
-        a1.uSoundID = LOWORD(v3->field_10);
+        a1.uSoundID = LOWORD(v3->sound_id);
         memcpy(
           &a1.stru_24,
           &pParty->pPlayers[v3->uPlayerID].spellbook.pDarkSpellbook.bIsSpellAvailable[36
@@ -3457,7 +3450,7 @@
       case SPELL_FIRE_TORCH_LIGHT:
         LODWORD(v733) = 3600 * v2;
 
-        switch (v12)
+        switch (v731)
         {
           case 1: amount = 2; break;
           case 2: amount = 3; break;
@@ -3474,7 +3467,7 @@
         goto LABEL_1056;
 
       case SPELL_FIRE_FIRE_SPIKE:
-        v29 = v12 - 2;
+        v29 = v731 - 2;
         if ( v29 )
         {
           v30 = v29 - 1;
@@ -3503,7 +3496,7 @@
         for (uint i = 0; i < uNumSpriteObjects; ++i)
         {
           auto object = pSpriteObjects + i;
-          if (object->uType && object->field_48 == 7 && object->field_58_pid == 8 * (int)v3->uPlayerID | OBJECT_Player)
+          if (object->uType && object->spell_id == SPELL_FIRE_FIRE_SPIKE && object->spell_caster_pid == (8 * (int)v3->uPlayerID) | OBJECT_Player)
             ++HIDWORD(v733);
           /*v33 = (char *)&pSpriteObjects[0].field_48;
           v730 = uNumSpriteObjects;
@@ -3526,9 +3519,9 @@
           goto play_sound_and_continue;
 
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
         a1.vPosition.y = pParty->vPosition.y;
         a1.vPosition.x = pParty->vPosition.x;
@@ -3539,13 +3532,11 @@
                          pParty->vPosition.y,
                          pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3);
         a1.uSpriteFrameID = 0;
-        v34 = 8 * v3->uPlayerID;
-        LOBYTE(v34) = v34 | OBJECT_Player;
-        a1.field_58_pid = v34;
-        a1.field_5C = a2;
+        a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+        a1.spell_target_pid = a2;
         a1.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
         a1.uFacing = LOWORD(v715.uYawAngle);
-        a1.uSoundID = LOWORD(v3->field_10);
+        a1.uSoundID = LOWORD(v3->sound_id);
         if ( pParty->bTurnBasedModeOn == 1 )
           LOBYTE(a1.uAttributes) |= 4u;
         v669 = v3->uPlayerID + 1;
@@ -3568,21 +3559,18 @@
         v698 = 0;
         v697 = 0;
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
         a1.uAttributes = 0;
         a1.uSectorID = 0;
         a1.uSpriteFrameID = 0;
-        v37 = v3->uPlayerID;
         a1.field_60_distance_related_prolly_lod = 0;
-        v37 *= 8;
-        LOBYTE(v37) = v37 | OBJECT_Player;
         a1.uFacing = 0;
-        a1.field_58_pid = v37;
+        a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
         v38 = a2 >> 3;
-        a1.uSoundID = LOWORD(v3->field_10);
+        a1.uSoundID = LOWORD(v3->sound_id);
         v39 = a2 >> 3;
         a1.vPosition.x = pActors[v39].vPosition.x;
         v40 = pActors[v39].vPosition.y;
@@ -3590,7 +3578,7 @@
         v41 = 8 * (a2 >> 3);
         a1.vPosition.y = v40;
         LOBYTE(v41) = v41 | OBJECT_Actor;
-        a1.field_5C = v41;
+        a1.spell_target_pid = v41;
         v42 = a1.Create(0, 0, 0, 0);
         v43 = &v697;
         goto LABEL_133;
@@ -3607,28 +3595,23 @@
         v705 = 0;
         v704 = 0;
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
         a1.uAttributes = 0;
         a1.uSectorID = 0;
         a1.uSpriteFrameID = 0;
-        v44 = v3->uPlayerID;
         a1.field_60_distance_related_prolly_lod = 0;
         a1.uFacing = 0;
-        v44 *= 8;
-        LOBYTE(v44) = v44 | OBJECT_Player;
         v38 = (signed int)v726;
-        a1.field_58_pid = v44;
-        a1.uSoundID = LOWORD(v3->field_10);
+        a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+        a1.uSoundID = LOWORD(v3->sound_id);
         a1.vPosition.x = *(__int16 *)((char *)&pActors[0].vPosition.x + HIDWORD(v733));
         v45 = *(__int16 *)((char *)&pActors[0].vPosition.y + HIDWORD(v733));
         a1.vPosition.z = *(__int16 *)((char *)&pActors[0].vPosition.z + HIDWORD(v733));
-        v46 = 8 * (int)v726;
         a1.vPosition.y = v45;
-        LOBYTE(v46) = 8 * (char)v726 | OBJECT_Actor;
-        a1.field_5C = v46;
+        a1.spell_target_pid = PID(OBJECT_Actor, (int)v726);
         v42 = a1.Create(0, 0, 0, 0);
         v43 = &v704;
 LABEL_133:
@@ -3644,9 +3627,9 @@
         v692 = 0;
         v691 = 0;
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
         a1.vPosition.x = *(short *)(HIDWORD(v733) + 142);
         a1.vPosition.y = *(short *)(HIDWORD(v733) + 144);
@@ -3655,15 +3638,12 @@
         a1.uAttributes = 0;
         a1.uSectorID = pIndoor->GetSector(a1.vPosition.x, a1.vPosition.y, v48);
         a1.uSpriteFrameID = 0;
-        v49 = 8 * v3->uPlayerID;
-        LOBYTE(v49) = v49 | OBJECT_Player;
-        a1.field_58_pid = v49;
-        a1.field_5C = a2;
+        a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+        a1.spell_target_pid = a2;
         a1.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
         a1.uFacing = LOWORD(v715.uYawAngle);
-        LOWORD(v49) = LOWORD(v3->field_10);
         LOBYTE(a1.uAttributes) |= 0x80u;
-        a1.uSoundID = v49;
+        a1.uSoundID = LOWORD(v3->sound_id);
         v726 = (Player *)a1.Create(0, 0, 0, 0);
         if ( !MonsterStats::BelongsToSupertype(*(short *)(HIDWORD(v733) + 96), MONSTER_SUPERTYPE_UNDEAD) )
         {
@@ -3677,47 +3657,52 @@
 LABEL_139:
         DamageMonsterFromParty(8 * v42 | 2, v47, v670);
         goto LABEL_1056;
+
+
       case SPELL_FIRE_FIRE_BOLT:
-      case 6:
-      case 11:
-      case 18:
-      case 26:
-      case 32:
-      case 34:
-      case 37:
-      case 57:
-      case 65:
-      case 70:
-      case 78:
-      case 97:
+      case SPELL_FIRE_FIREBALL:
+      case SPELL_FIRE_INCINERATE:
+      case SPELL_AIR_LIGHNING_BOLT:
+      case SPELL_WATER_ICE_BOLT:
+      case SPELL_WATER_ICE_BLAST:
+      case SPELL_EARTH_STUN:
+      case SPELL_EARTH_DEADLY_SWARM:
+      case SPELL_MIND_MIND_BLAST:
+      case SPELL_MIND_PSYCHIC_SHOCK:
+      case SPELL_BODY_HARM:
+      case SPELL_LIGHT_LIGHT_BOLT:
+      case SPELL_DARK_DRAGON_BREATH:
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           goto play_sound_and_continue;
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
         a1.vPosition.y = pParty->vPosition.y;
         a1.vPosition.x = pParty->vPosition.x;
         a1.uAttributes = 0;
         a1.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
-        a1.uSectorID = pIndoor->GetSector(
-                         pParty->vPosition.x,
-                         pParty->vPosition.y,
-                         pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3);
+        if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
+          a1.uSectorID = pIndoor->GetSector(pParty->vPosition.x,
+                                            pParty->vPosition.y,
+                                            pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3);
+        else a1.uSectorID = 0;
+
         a1.uSpriteFrameID = 0;
-        v50 = 8 * v3->uPlayerID;
-        LOBYTE(v50) = v50 | OBJECT_Player;
-        a1.field_58_pid = v50;
-        a1.field_5C = a2;
+        a1.spell_caster_pid = (8 * v3->uPlayerID) | OBJECT_Player;
+        a1.spell_target_pid = a2;
         a1.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
         a1.uFacing = LOWORD(v715.uYawAngle);
-        a1.uSoundID = LOWORD(v3->field_10);
+        a1.uSoundID = LOWORD(v3->sound_id);
         if ( pParty->bTurnBasedModeOn == 1 )
           LOBYTE(a1.uAttributes) |= 4u;
         if ( v3->spellnum == 18 )
           LOBYTE(a1.uAttributes) |= 0x40u;
         goto LABEL_156;
+
+
+
       case 29:
       case 39:
       case 76:
@@ -3725,9 +3710,9 @@
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           goto play_sound_and_continue;
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
         v51 = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 2;
         a1.vPosition.y = pParty->vPosition.y;
@@ -3766,19 +3751,19 @@
         v661 = (Actor *)v55;
         goto LABEL_165;
       case 35:
-        if ( v12 == 2 )
+        if ( v731 == 2 )
         {
           v57 = 300 * v2;
         }
         else
         {
-          if ( v12 == 3 )
+          if ( v731 == 3 )
           {
             amount = 4;
             v57 = 300 * v2;
             goto LABEL_174;
           }
-          if ( v12 == 4 )
+          if ( v731 == 4 )
           {
             v57 = 300 * v2;
             amount = 8;
@@ -3836,9 +3821,9 @@
           pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335),
           v731, 0, 0, 0);
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         v60 = pObjectList->ObjectIDByItemID(a1.uType);
         v61 = a2 >> 3;
         goto LABEL_1086;
@@ -3856,19 +3841,17 @@
                          pParty->vPosition.y,
                          pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3);
         a1.uSpriteFrameID = 0;
-        v62 = 8 * v3->uPlayerID;
-        LOBYTE(v62) = v62 | OBJECT_Player;
-        a1.field_58_pid = v62;
-        a1.field_5C = a2;
+        a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+        a1.spell_target_pid = a2;
         a1.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
         a1.uFacing = LOWORD(v715.uYawAngle);
-        a1.uSoundID = LOWORD(v3->field_10);
-        a1.field_50 = v731;
-        a1.field_48 = 3;
-        a1.field_4C = 300 * v2;
+        a1.uSoundID = LOWORD(v3->sound_id);
+        a1.spell_skill = v731;
+        a1.spell_id = SPELL_FIRE_PROTECTION_FROM_FIRE;
+        a1.spell_level = 300 * v2;
         goto LABEL_154;
       case 4:
-        v63 = v12 - 1;
+        v63 = v731 - 1;
         if ( !v63 )
         {
           amount = 10;
@@ -3939,7 +3922,7 @@
                           0,
                           -1,
                           0,
-                          v3->field_10,
+                          v3->sound_id,
                           0,
                           0);
                     }
@@ -3987,7 +3970,7 @@
         goto LABEL_203;
 
       case SPELL_BODY_REGENERATION:
-        v70 = v12 - 1;
+        v70 = v731 - 1;
         LODWORD(v733) = 3600 * v2;
         if ( v70 && (v71 = v70 - 1) != 0 )
         {
@@ -4020,7 +4003,7 @@
       case SPELL_EARTH_PROTECTION_FROM_EARTH:
       case SPELL_MIND_PROTECTION_FROM_MIND:
       case SPELL_BODY_PROTECTION_FROM_BODY:
-        v76 = v12 - 1;
+        v76 = v731 - 1;
         LODWORD(v733) = 3600 * v2;
         if ( v76 )
         {
@@ -4090,21 +4073,21 @@
         goto play_sound_and_continue;
 
       case SPELL_FIRE_HASTE:
-        if ( v12 <= 0 )
+        if ( v731 <= 0 )
           goto LABEL_254;
-        if ( v12 <= 2 )
+        if ( v731 <= 2 )
         {
           v91 = 60 * (v2 + 60);
         }
         else
         {
-          if ( v12 == 3 )
+          if ( v731 == 3 )
           {
             v91 = 180 * (v2 + 20);
           }
           else
           {
-            if ( v12 != 4 )
+            if ( v731 != 4 )
               goto LABEL_254;
             v91 = 240 * (v2 + 15);
           }
@@ -4136,7 +4119,7 @@
         goto play_sound_and_continue;
 
       case SPELL_SPIRIT_BLESS:
-        v101 = v12 - 1;
+        v101 = v731 - 1;
         if ( v101 && (v102 = v101 - 1) != 0 )
         {
           v103 = v102 - 1;
@@ -4234,9 +4217,9 @@
             v701 = 0;
             a1.stru_24.Reset();
             v119 = HIDWORD(v733);
-            a1.field_48 = *(int *)HIDWORD(v733);
-            a1.field_4C = v723;
-            a1.field_50 = v731;
+            a1.spell_id = *(int *)HIDWORD(v733);
+            a1.spell_level = v723;
+            a1.spell_skill = v731;
             a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
             a1.uAttributes = 0;
             a1.uSectorID = 0;
@@ -4244,7 +4227,7 @@
             v120 = 8 * *(short *)(v119 + 2);
             LOBYTE(v120) = v120 | OBJECT_Player;
             a1.field_60_distance_related_prolly_lod = 0;
-            a1.field_58_pid = v120;
+            a1.spell_caster_pid = v120;
             a1.uFacing = 0;
             a1.uSoundID = *(short *)(v119 + 16);
             a1.vPosition.x = v112->vPosition.x;
@@ -4253,7 +4236,7 @@
             v121 = 8 * a2;
             a1.vPosition.z = v112->vPosition.z - (unsigned int)(signed __int64)((double)(signed int)v726 * unk_4D8548);
             LOBYTE(v121) = 8 * a2 | 3;
-            a1.field_5C = v121;
+            a1.spell_target_pid = v121;
             v122 = a1.Create(0, 0, 0, 0);
             DamageMonsterFromParty(8 * v122 | 2, v730, (Vec3_int_ *)&v701);
             LODWORD(v727) = 1;
@@ -4271,7 +4254,7 @@
       case SPELL_AIR_SHIELD:
       case SPELL_EARTH_STONESKIN:
       case SPELL_SPIRIT_HEROISM:
-        v123 = v12 - 1;
+        v123 = v731 - 1;
         if ( v123 && (v124 = v123 - 1) != 0 )
         {
           v125 = v124 - 1;
@@ -4328,7 +4311,7 @@
         goto play_sound_and_continue;
 
       case SPELL_FIRE_IMMOLATION:
-        v138 = v12 - 2;
+        v138 = v731 - 2;
         if ( v138 && (v139 = v138 - 1) != 0 && v139 == 1 )
           v140 = 600 * v2;
         else
@@ -4348,7 +4331,7 @@
         goto LABEL_1056;
 
       case 9:
-        v149 = v12 - 1;
+        v149 = v731 - 1;
         if ( v149 && (v150 = v149 - 1) != 0 && (v151 = v150 - 1) != 0 )
         {
           if ( v151 == 1 )
@@ -4417,9 +4400,9 @@
                        stru_5C6E00->Atan2((signed __int64)v718, (signed __int64)*(float *)&v721));
             }
             a1.stru_24.Reset();
-            a1.field_48 = v3->spellnum;
-            a1.field_4C = v2;
-            a1.field_50 = v731;
+            a1.spell_id = v3->spellnum;
+            a1.spell_level = v2;
+            a1.spell_skill = v731;
             a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
             a1.uAttributes = 0;
             a1.vPosition.x = uRequiredMana;
@@ -4427,11 +4410,11 @@
             a1.uSectorID = 0;
             a1.vPosition.z = a2 + v713;
             a1.uSpriteFrameID = 0;
-            a1.field_58_pid = 8 * v3->uPlayerID | OBJECT_Player;
-            a1.field_5C = v730;
+            a1.spell_caster_pid = 8 * v3->uPlayerID | OBJECT_Player;
+            a1.spell_target_pid = v730;
             a1.field_60_distance_related_prolly_lod = stru_50C198._427546(a2 + 2500);
             a1.uFacing = v687;
-            a1.uSoundID = LOWORD(v3->field_10);
+            a1.uSoundID = LOWORD(v3->sound_id);
             if ( pParty->bTurnBasedModeOn == 1 )
               a1.uAttributes = 4;
             if ( a1.Create(
@@ -4465,20 +4448,17 @@
         v700.y = 0;
         v700.x = 0;
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
         a1.uAttributes = 0;
         a1.uSectorID = 0;
         a1.uSpriteFrameID = 0;
-        v161 = v3->uPlayerID;
         a1.field_60_distance_related_prolly_lod = 0;
         a1.uFacing = 0;
-        v161 *= 8;
-        LOBYTE(v161) = v161 | OBJECT_Player;
-        a1.field_58_pid = v161;
-        a1.uSoundID = LOWORD(v3->field_10);
+        a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+        a1.uSoundID = LOWORD(v3->sound_id);
         a2 = 0;
         if ( (signed int)v726 > 0 )
         {
@@ -4491,7 +4471,7 @@
             a1.vPosition.z = pActors[v162].vPosition.z - (unsigned int)(signed __int64)((double)v732 * unk_4D8548);
             v163 = 8 * dword_50BF30[a2];
             LOBYTE(v163) = v163 | OBJECT_Actor;
-            a1.field_5C = v163;
+            a1.spell_target_pid = v163;
             v164 = a1.Create(0, 0, 0, 0);
             v165 = a2;
             DamageMonsterFromParty(8 * v164 | AI_OBJECT_LAYING_ITEM, dword_50BF30[a2], &v700);
@@ -4521,7 +4501,7 @@
         goto LABEL_1056;
 
       case SPELL_AIR_FEATHER_FALL:
-        v170 = v12 - 1;
+        v170 = v731 - 1;
         if ( !v170 )
         {
           v173 = 300 * v2;
@@ -4557,7 +4537,7 @@
         goto play_sound_and_continue;
 
       case SPELL_AIR_SPARKS:
-        v184 = v12 - 1;
+        v184 = v731 - 1;
         if ( v184 )
         {
           v185 = v184 - 1;
@@ -4588,9 +4568,9 @@
         v726 = (Player *)((signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360);
         v732 = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360 / (amount - 1);
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
         a1.vPosition.y = pParty->vPosition.y;
         a1.vPosition.x = pParty->vPosition.x;
@@ -4601,12 +4581,10 @@
                          pParty->vPosition.y,
                          pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3);
         a1.uSpriteFrameID = 0;
-        v187 = 8 * v3->uPlayerID;
-        LOBYTE(v187) = v187 | OBJECT_Player;
-        a1.field_58_pid = v187;
-        a1.field_5C = a2;
+        a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+        a1.spell_target_pid = a2;
         a1.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
-        a1.uSoundID = LOWORD(v3->field_10);
+        a1.uSoundID = LOWORD(v3->sound_id);
         if ( pParty->bTurnBasedModeOn == 1 )
           LOBYTE(a1.uAttributes) |= 4u;
         v188 = (signed int)v726 / -2;
@@ -4642,7 +4620,7 @@
         goto LABEL_1056;
 
       case SPELL_AIR_INVISIBILITY:
-        v192 = v12 - 1;
+        v192 = v731 - 1;
         if ( !v192 )
         {
           amount = v2;
@@ -4784,9 +4762,9 @@
                      stru_5C6E00->Atan2((signed __int64)v727, (signed __int64)*(float *)&uRequiredMana));
           }
           a1.stru_24.Reset();
-          a1.field_48 = v3->spellnum;
-          a1.field_4C = v2;
-          a1.field_50 = v731;
+          a1.spell_id = v3->spellnum;
+          a1.spell_level = v2;
+          a1.spell_skill = v731;
           a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
           a1.uAttributes = 0;
           a1.vPosition.x = LODWORD(v718);
@@ -4794,11 +4772,11 @@
           a1.uSectorID = 0;
           a1.vPosition.z = (int)((char *)_this + LODWORD(v725));
           a1.uSpriteFrameID = 0;
-          a1.field_58_pid = 8 * v3->uPlayerID | OBJECT_Player;
-          a1.field_5C = v730;
+          a1.spell_caster_pid = 8 * v3->uPlayerID | OBJECT_Player;
+          a1.spell_target_pid = v730;
           a1.field_60_distance_related_prolly_lod = stru_50C198._427546((int)&_this[69].uNumCharges);
           a1.uFacing = v685;
-          a1.uSoundID = LOWORD(v3->field_10);
+          a1.uSoundID = LOWORD(v3->sound_id);
           if ( pParty->bTurnBasedModeOn == 1 )
             a1.uAttributes = 4;
           if ( a1.Create(
@@ -4816,7 +4794,7 @@
         while ( !v14 );
         goto LABEL_1056;
       case 23:
-        v219 = v12 - 2;
+        v219 = v731 - 2;
         if ( v219 )
         {
           v220 = v219 - 1;
@@ -4846,7 +4824,7 @@
         HIDWORD(v733) = (int)(char *)&pParty + 2508;
         break;
       case 24:
-        v224 = v12 - 2;
+        v224 = v731 - 2;
         if ( v224 )
         {
           v225 = v224 - 1;
@@ -4873,9 +4851,9 @@
         {
 LABEL_152:
           a1.stru_24.Reset();
-          a1.field_48 = v3->spellnum;
-          a1.field_50 = v731;
-          a1.field_4C = v2;
+          a1.spell_id = v3->spellnum;
+          a1.spell_skill = v731;
+          a1.spell_level = v2;
           a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
           a1.vPosition.y = pParty->vPosition.y;
           v51 = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
@@ -4888,13 +4866,11 @@
           v52 = pIndoor->GetSector(pParty->vPosition.x, v660, v671);
           a1.uSpriteFrameID = 0;
           a1.uSectorID = v52;
-          v53 = 8 * v3->uPlayerID;
-          LOBYTE(v53) = v53 | OBJECT_Player;
-          a1.field_58_pid = v53;
-          a1.field_5C = a2;
+          a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+          a1.spell_target_pid = a2;
           a1.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
           a1.uFacing = LOWORD(v715.uYawAngle);
-          a1.uSoundID = LOWORD(v3->field_10);
+          a1.uSoundID = LOWORD(v3->sound_id);
 LABEL_154:
           if ( pParty->bTurnBasedModeOn == 1 )
             LOBYTE(a1.uAttributes) |= 4u;
@@ -4911,9 +4887,9 @@
         {
           v732 = SHIDWORD(v733) / (amount - 1);
           a1.stru_24.Reset();
-          a1.field_48 = v3->spellnum;
-          a1.field_4C = v2;
-          a1.field_50 = v731;
+          a1.spell_id = v3->spellnum;
+          a1.spell_level = v2;
+          a1.spell_skill = v731;
           a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
           a1.vPosition.y = pParty->vPosition.y;
           a1.vPosition.x = pParty->vPosition.x;
@@ -4924,12 +4900,10 @@
                            pParty->vPosition.y,
                            pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3);
           a1.uSpriteFrameID = 0;
-          v226 = 8 * v3->uPlayerID;
-          LOBYTE(v226) = v226 | OBJECT_Player;
-          a1.field_58_pid = v226;
-          a1.field_5C = a2;
+          a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+          a1.spell_target_pid = a2;
           a1.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
-          a1.uSoundID = LOWORD(v3->field_10);
+          a1.uSoundID = LOWORD(v3->sound_id);
           if ( pParty->bTurnBasedModeOn == 1 )
             LOBYTE(a1.uAttributes) |= 4u;
           v227 = SHIDWORD(v733) / -2;
@@ -5459,7 +5433,7 @@
         amount = 10 * v2;
         if ( pPlayer->sMana < (signed int)uRequiredMana )
           goto play_sound_and_continue;
-        if ( pParty->uFlags & (PARTY_FLAGS_1_ALERT_RED | PARTY_FLAGS_1_ALERT_YELLOW) && v12 != 4 || rand() % 100 >= amount && v731 != 4 )
+        if ( pParty->uFlags & (PARTY_FLAGS_1_ALERT_RED | PARTY_FLAGS_1_ALERT_YELLOW) && v731 != 4 || rand() % 100 >= amount && v731 != 4 )
         {
           ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
           pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
@@ -5485,13 +5459,13 @@
           _506348_current_lloyd_playerid = v3->uPlayerID;
           ::uRequiredMana = v319;
           ::sRecoveryTime = sRecoveryTime;
-          dword_50633C = v3->field_10;
+          dword_50633C = v3->sound_id;
           dword_506338 = v3->spellnum;
           LOBYTE(v3->field_8) |= 0x20u;
         }
         goto play_sound_and_continue;
       case 40:
-        v320 = v12 - 2;
+        v320 = v731 - 2;
         if ( !v320 )
           goto LABEL_632;
         v321 = v320 - 1;
@@ -5524,9 +5498,9 @@
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           goto play_sound_and_continue;
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
         a1.vPosition.y = pParty->vPosition.y;
         a1.vPosition.x = pParty->vPosition.x;
@@ -5539,11 +5513,11 @@
         a1.uSpriteFrameID = 0;
         v326 = 8 * v3->uPlayerID;
         LOBYTE(v326) = v326 | OBJECT_Player;
-        a1.field_58_pid = v326;
-        a1.field_5C = a2;
+        a1.spell_caster_pid = v326;
+        a1.spell_target_pid = a2;
         a1.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
         a1.uFacing = LOWORD(pParty->sRotationY);
-        a1.uSoundID = LOWORD(v3->field_10);
+        a1.uSoundID = LOWORD(v3->sound_id);
         if ( pParty->bTurnBasedModeOn == 1 )
           LOBYTE(a1.uAttributes) |= 4u;
         v669 = v3->uPlayerID + 1;
@@ -5561,9 +5535,9 @@
           goto play_sound_and_continue;
         a1.uType = 4090;
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
         a1.vPosition.x = pParty->vPosition.x;
         a1.vPosition.y = pParty->vPosition.y;
@@ -5571,13 +5545,11 @@
         a1.uSectorID = 0;
         a1.uSpriteFrameID = 0;
         a1.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
-        v327 = 8 * v3->uPlayerID;
-        LOBYTE(v327) = v327 | OBJECT_Player;
         a1.field_60_distance_related_prolly_lod = 0;
-        a1.field_58_pid = v327;
-        a1.field_5C = a2;
+        a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+        a1.spell_target_pid = a2;
         a1.uFacing = LOWORD(pParty->sRotationY);
-        a1.uSoundID = LOWORD(v3->field_10);
+        a1.uSoundID = LOWORD(v3->sound_id);
         if ( pParty->bTurnBasedModeOn == 1 )
           a1.uAttributes = 4;
         v669 = 0;
@@ -5590,7 +5562,7 @@
         goto LABEL_157;
 
       case SPELL_SPIRIT_DETECT_LIFE:
-        v328 = v12 - 2;
+        v328 = v731 - 2;
         if ( v328 )
         {
           v329 = v328 - 1;
@@ -5621,7 +5593,7 @@
 
       case SPELL_SPIRIT_FATE:
         LODWORD(v733) = 300;
-        v339 = v12 - 2;
+        v339 = v731 - 2;
         if ( v339 )
         {
           v340 = v339 - 1;
@@ -5670,7 +5642,7 @@
         goto LABEL_1056;
 
       case 49:
-        v348 = v12 - 2;
+        v348 = v731 - 2;
         if ( !v348 )
           goto LABEL_677;
         v349 = v348 - 1;
@@ -5710,7 +5682,7 @@
         v674 = v3->uPlayerID_2;
         goto LABEL_685;
       case SPELL_SPIRIT_PRESERVATION:
-        v354 = v12 - 2;
+        v354 = v731 - 2;
         if ( v354 && (v355 = v354 - 1) != 0 && v355 == 1 )
           v356 = 900 * (v2 + 4);
         else
@@ -5741,7 +5713,7 @@
         while ( v357 <= &pParty->pPlayers[3] );
         goto LABEL_1056;
       case 48:
-        v364 = v12 - 2;
+        v364 = v731 - 2;
         if ( !v364 || (v365 = v364 - 1) != 0 && v365 != 1 )
           v366 = 60 * (v2 + 3);
         else
@@ -5753,20 +5725,17 @@
         pGame->GetStru6()->FadeScreen__like_Turn_Undead_and_mb_Armageddon(0xFFFFFFu, 0xC0u);
         ++a1.uType;
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
         a1.uAttributes = 0;
         a1.uSectorID = 0;
         a1.uSpriteFrameID = 0;
-        v368 = v3->uPlayerID;
         a1.field_60_distance_related_prolly_lod = 0;
         a1.uFacing = 0;
-        v368 *= 8;
-        LOBYTE(v368) = v368 | OBJECT_Player;
-        a1.field_58_pid = v368;
-        a1.uSoundID = LOWORD(v3->field_10);
+        a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+        a1.uSoundID = LOWORD(v3->sound_id);
         for ( a2 = 0; a2 < (signed int)v726; ++a2 )
         {
           v369 = &pActors[dword_50BF30[a2]];
@@ -5778,7 +5747,7 @@
             a1.vPosition.z = v369->vPosition.z - (unsigned int)(signed __int64)((double)v732 * unk_4D8548);
             v370 = 8 * dword_50BF30[a2];
             LOBYTE(v370) = v370 | OBJECT_Actor;
-            a1.field_5C = v370;
+            a1.spell_target_pid = v370;
             a1.Create(0, 0, 0, 0);
             v732 = (int)v733 << 7;
             v369->pActorBuffs[4].Apply(
@@ -5788,7 +5757,7 @@
         }
         goto LABEL_1056;
       case 53:
-        v371 = v12 - 2;
+        v371 = v731 - 2;
         if ( v371 && (v372 = v371 - 1) != 0 && v372 == 1 )
           amount = 0;
         else
@@ -5824,7 +5793,7 @@
         v377 = &pParty->pPlayers[v3->uPlayerID_2];
         goto LABEL_720;
       case 54:
-        v378 = v12 - 2;
+        v378 = v731 - 2;
         if ( v378 && (v379 = v378 - 1) != 0 && v379 == 1 )
           v380 = 4 * v2;
         else
@@ -5880,7 +5849,7 @@
         goto LABEL_1056;
 
       case 55:
-        v392 = v12 - 1;
+        v392 = v731 - 1;
         if ( !v392 )
         {
           v395 = 180 * v2;
@@ -5952,7 +5921,7 @@
         goto play_sound_and_continue;
 
       case 61:
-        v405 = v12 - 2;
+        v405 = v731 - 2;
         if ( !v405 )
           goto LABEL_766;
         v406 = v405 - 1;
@@ -5987,7 +5956,7 @@
         v656 = 12;
         goto LABEL_640;
       case 56:
-        v411 = v12 - 2;
+        v411 = v731 - 2;
         if ( v411 )
         {
           v412 = v411 - 1;
@@ -6088,9 +6057,9 @@
 LABEL_807:
         ShowStatusBarString(pTmpBuf2, 2u);
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
         a1.vPosition.x = *(short *)(v730 + 142);
         a1.vPosition.y = *(short *)(v730 + 144);
@@ -6100,7 +6069,7 @@
         v657 = a1.vPosition.x;
         goto LABEL_1087;
       case 62:
-        v423 = v12 - 2;
+        v423 = v731 - 2;
         if ( !v423 )
           goto LABEL_813;
         v424 = v423 - 1;
@@ -6134,9 +6103,9 @@
           pActors[v426].pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Long;
         }
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         v60 = pObjectList->ObjectIDByItemID(a1.uType);
         v61 = v426;
         goto LABEL_1086;
@@ -6160,14 +6129,14 @@
             v731, 0, 0, 0);
         }
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         v60 = pObjectList->ObjectIDByItemID(a1.uType);
         v61 = v427;
         goto LABEL_1086;
       case 63:
-        v428 = v12 - 2;
+        v428 = v731 - 2;
         if ( v428 && (v429 = v428 - 1) != 0 && v429 == 1 )
           v430 = 300 * v2;
         else
@@ -6179,20 +6148,17 @@
         pGame->GetStru6()->FadeScreen__like_Turn_Undead_and_mb_Armageddon(0xA0A0Au, 0xC0u);
         ++a1.uType;
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
         a1.uAttributes = 0;
         a1.uSectorID = 0;
         a1.uSpriteFrameID = 0;
-        v432 = v3->uPlayerID;
         a1.field_60_distance_related_prolly_lod = 0;
         a1.uFacing = 0;
-        v432 *= 8;
-        LOBYTE(v432) = v432 | OBJECT_Player;
-        a1.field_58_pid = v432;
-        a1.uSoundID = LOWORD(v3->field_10);
+        a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+        a1.uSoundID = LOWORD(v3->sound_id);
         for ( a2 = 0; a2 < (signed int)v726; ++a2 )
         {
           v433 = &pActors[dword_50BF30[a2]];
@@ -6204,7 +6170,7 @@
           a1.vPosition.z = v433->vPosition.z - (unsigned int)(signed __int64)((double)v732 * unk_4D8548);
           v434 = 8 * dword_50BF30[a2];
           LOBYTE(v434) = v434 | OBJECT_Actor;
-          a1.field_5C = v434;
+          a1.spell_target_pid = v434;
           a1.Create(0, 0, 0, 0);
           if ( stru_50C198.GetMagicalResistance(v433, 7u) )
           {
@@ -6216,7 +6182,7 @@
         }
         goto LABEL_1056;
       case 64:
-        v435 = v12 - 2;
+        v435 = v731 - 2;
         if ( v435 && (v436 = v435 - 1) != 0 && v436 == 1 )
           amount = 0;
         else
@@ -6249,7 +6215,7 @@
         }
         goto LABEL_1056;
       case 42:
-        v442 = v12 - 2;
+        v442 = v731 - 2;
         if ( !v442 )
           goto LABEL_855;
         v443 = v442 - 1;
@@ -6328,7 +6294,7 @@
         }
         goto LABEL_1056;
       case 67:
-        v451 = v12 - 2;
+        v451 = v731 - 2;
         if ( v451 )
         {
           v452 = v451 - 1;
@@ -6374,7 +6340,7 @@
         v325 = &pParty->pPlayers[v323];
         goto LABEL_641;
       case 68:
-        v457 = v12 - 2;
+        v457 = v731 - 2;
         if ( v457 )
         {
           v458 = v457 - 1;
@@ -6432,7 +6398,7 @@
         }
         goto LABEL_1056;
       case 72:
-        v464 = v12 - 2;
+        v464 = v731 - 2;
         if ( !v464 )
           goto LABEL_910;
         v465 = v464 - 1;
@@ -6530,7 +6496,7 @@
         pParty->pPlayers[v3->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, v2, v2, 0);
         goto LABEL_1056;
       case 74:
-        v493 = v12 - 2;
+        v493 = v731 - 2;
         if ( v493 && (v494 = v493 - 1) != 0 && v494 == 1 )
           amount = 0;
         else
@@ -6603,20 +6569,17 @@
         v689 = 0;
         v688 = 0;
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
         a1.uAttributes = 0;
         a1.uSectorID = 0;
         a1.uSpriteFrameID = 0;
-        v506 = v3->uPlayerID;
         a1.field_60_distance_related_prolly_lod = 0;
         a1.uFacing = 0;
-        v506 *= 8;
-        LOBYTE(v506) = v506 | OBJECT_Player;
-        a1.field_58_pid = v506;
-        a1.uSoundID = LOWORD(v3->field_10);
+        a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+        a1.uSoundID = LOWORD(v3->sound_id);
         a2 = 0;
         if ( SHIDWORD(v733) > 0 )
         {
@@ -6629,7 +6592,7 @@
             a1.vPosition.z = pActors[v507].vPosition.z - (unsigned int)(signed __int64)((double)v732 * unk_4D8548);
             v508 = 8 * dword_50BF30[a2];
             LOBYTE(v508) = v508 | OBJECT_Actor;
-            a1.field_5C = v508;
+            a1.spell_target_pid = v508;
             v509 = a1.Create(0, 0, 0, 0);
             v510 = a2;
             DamageMonsterFromParty(8 * v509 | OBJECT_Item, dword_50BF30[a2], (Vec3_int_ *)&v688);
@@ -6646,7 +6609,7 @@
           a1.vPosition.z = v511->vPosition.z - (unsigned int)(signed __int64)((double)v732 * unk_4D8548);
           v512 = 8 * dword_50BF30[a2];
           LOBYTE(v512) = v512 | OBJECT_Actor;
-          a1.field_5C = v512;
+          a1.spell_target_pid = v512;
           a1.Create(0, 0, 0, 0);
           v513 = v511->pActorBuffs;
           v726 = (Player *)22;
@@ -6660,7 +6623,7 @@
         }
         goto LABEL_1056;
       case 82:
-        v514 = v12 - 2;
+        v514 = v731 - 2;
         if ( !v514 )
           goto LABEL_955;
         v515 = v514 - 1;
@@ -6711,7 +6674,7 @@
         sub_44FA4C_spawn_light_elemental(v3->uPlayerID, v731, v733);
         goto LABEL_1056;
       case 83:
-        v520 = v12 - 2;
+        v520 = v731 - 2;
         if ( !v520 )
           goto LABEL_973;
         v521 = v520 - 1;
@@ -6768,20 +6731,17 @@
         v695 = 0;
         v694 = 0;
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
         a1.uAttributes = 0;
         a1.uSectorID = 0;
         a1.uSpriteFrameID = 0;
-        v532 = v3->uPlayerID;
         a1.field_60_distance_related_prolly_lod = 0;
         a1.uFacing = 0;
-        v532 *= 8;
-        LOBYTE(v532) = v532 | OBJECT_Player;
-        a1.field_58_pid = v532;
-        a1.uSoundID = LOWORD(v3->field_10);
+        a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+        a1.uSoundID = LOWORD(v3->sound_id);
         a2 = 0;
         if ( (signed int)v726 > 0 )
         {
@@ -6794,7 +6754,7 @@
             a1.vPosition.z = pActors[v533].vPosition.z - (unsigned int)(signed __int64)((double)v732 * unk_4D8548);
             v534 = 8 * dword_50BF30[a2];
             LOBYTE(v534) = v534 | OBJECT_Actor;
-            a1.field_5C = v534;
+            a1.spell_target_pid = v534;
             v535 = a1.Create(0, 0, 0, 0);
             v536 = a2;
             DamageMonsterFromParty(8 * v535 | OBJECT_Item, dword_50BF30[a2], (Vec3_int_ *)&v694);
@@ -6807,7 +6767,7 @@
         goto LABEL_1056;
 
       case SPELL_LIGHT_DAY_OF_PROTECTION:
-        v538 = v12 - 2;
+        v538 = v731 - 2;
         if ( v538 && (v539 = v538 - 1) != 0 && v539 == 1 )
         {
           amount = 5 * v2;
@@ -6847,7 +6807,7 @@
         pParty->pPartyBuffs[PARTY_BUFF_WIZARD_EYE].Apply((signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733 + 1)), v731, v550, 0, 0);
         goto LABEL_1056;
       case 86:
-        v551 = v12 - 2;
+        v551 = v731 - 2;
         if ( !v551 )
           goto LABEL_998;
         v552 = v551 - 1;
@@ -6943,7 +6903,7 @@
         ++v571->uNumDivineInterventionCastsThisDay;
         goto LABEL_1056;
       case 89:
-        v573 = v12 - 2;
+        v573 = v731 - 2;
         if ( v573 )
         {
           v574 = v573 - 1;
@@ -6998,28 +6958,24 @@
         }
         ++a1.uType;
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
         a1.uAttributes = 0;
         a1.uSectorID = 0;
         a1.uSpriteFrameID = 0;
-        v580 = v3->uPlayerID;
         a1.field_60_distance_related_prolly_lod = 0;
         v581 = v721;
-        v580 *= 8;
-        LOBYTE(v580) = v580 | OBJECT_Player;
         a1.uFacing = 0;
-        a1.field_58_pid = v580;
-        a1.uSoundID = LOWORD(v3->field_10);
+        a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+        a1.uSoundID = LOWORD(v3->sound_id);
         a1.vPosition.x = *(short *)(v721 + 142);
         a1.vPosition.y = *(short *)(v721 + 144);
         v732 = *(short *)(v721 + 138);
         v582 = 8 * (int)v726;
         a1.vPosition.z = *(short *)(v721 + 146) - (unsigned int)(signed __int64)((double)v732 * unk_4D8548);
-        LOBYTE(v582) = 8 * (char)v726 | OBJECT_Actor;
-        a1.field_5C = v582;
+        a1.spell_target_pid = PID(OBJECT_Actor, (int)v726);
         a1.Create(0, 0, 0, 0);
         if ( *(char *)(v581 + 52) > amount )
           goto play_sound_and_continue;
@@ -7040,7 +6996,7 @@
           *(short *)(v581 + 40) = 10 * amount;
         goto LABEL_1056;
       case 91:
-        v588 = v12 - 1;
+        v588 = v731 - 1;
         amount = 16;
         if ( v588 && (v589 = v588 - 1) != 0 && (v590 = v589 - 1) != 0 )
         {
@@ -7084,7 +7040,7 @@
         *(char *)(v592 + 20) |= 0x80u;
         goto LABEL_1055;
       case 93:
-        v593 = v12 - 2;
+        v593 = v731 - 2;
         if ( !v593 )
           goto LABEL_1062;
         v594 = v593 - 1;
@@ -7105,9 +7061,9 @@
         v726 = (Player *)((signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360);
         v732 = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360 / (amount - 1);
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
         a1.vPosition.x = pParty->vPosition.x;
         a1.vPosition.y = pParty->vPosition.y;
@@ -7118,12 +7074,10 @@
                          pParty->vPosition.y,
                          pParty->vPosition.z + (signed int)pParty->uPartyHeight / 2);
         a1.uSpriteFrameID = 0;
-        v595 = 8 * v3->uPlayerID;
-        LOBYTE(v595) = v595 | OBJECT_Player;
-        a1.field_58_pid = v595;
-        a1.field_5C = a2;
+        a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+        a1.spell_target_pid = a2;
         a1.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
-        a1.uSoundID = LOWORD(v3->field_10);
+        a1.uSoundID = LOWORD(v3->sound_id);
         if ( pParty->bTurnBasedModeOn == 1 )
           LOBYTE(a1.uAttributes) |= 4u;
         v596 = (signed int)v726 / -2;
@@ -7183,9 +7137,9 @@
           pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335),
           v731, 0, 0, 0);
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         v60 = pObjectList->ObjectIDByItemID(a1.uType);
         v61 = v599;
 LABEL_1086:
@@ -7204,15 +7158,12 @@
         a1.uAttributes = 0;
         a1.uSectorID = pIndoor->GetSector(v657, v665, v676);
         a1.uSpriteFrameID = 0;
-        v604 = 8 * v3->uPlayerID;
-        LOBYTE(v604) = v604 | OBJECT_Player;
-        a1.field_58_pid = v604;
-        a1.field_5C = a2;
+        a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+        a1.spell_target_pid = a2;
         a1.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
         a1.uFacing = LOWORD(v715.uYawAngle);
-        LOWORD(v604) = LOWORD(v3->field_10);
         LOBYTE(a1.uAttributes) |= 0x80u;
-        a1.uSoundID = v604;
+        a1.uSoundID = LOWORD(v3->sound_id);
         a1.Create(0, 0, 0, v3->uPlayerID + 1);
         goto LABEL_1056;
       case 96:
@@ -7284,15 +7235,15 @@
         LODWORD(v727) = 1;
         goto play_sound_and_continue;
       case 95:
-        if ( v12 <= 0 )
+        if ( v731 <= 0 )
           goto LABEL_1119;
-        if ( v12 <= 3 )
+        if ( v731 <= 3 )
         {
           v614 = 300 * (v2 + 12);
         }
         else
         {
-          if ( v12 != 4 )
+          if ( v731 != 4 )
             goto LABEL_1119;
           v614 = 900 * (v2 + 4);
         }
@@ -7335,20 +7286,17 @@
         v708 = 0;
         v707 = 0;
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
         a1.uAttributes = 0;
         a1.uSectorID = 0;
         a1.uSpriteFrameID = 0;
-        v624 = v3->uPlayerID;
         a1.field_60_distance_related_prolly_lod = 0;
         a1.uFacing = 0;
-        v624 *= 8;
-        LOBYTE(v624) = v624 | OBJECT_Player;
-        a1.field_58_pid = v624;
-        a1.uSoundID = LOWORD(v3->field_10);
+        a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+        a1.uSoundID = LOWORD(v3->sound_id);
         a2 = 0;
         if ( SHIDWORD(v733) > 0 )
         {
@@ -7362,7 +7310,7 @@
             a1.vPosition.z = pActors[v625].vPosition.z - (unsigned int)(signed __int64)((double)v732 * unk_4D8548);
             v626 = 8 * dword_50BF30[a2];
             LOBYTE(v626) = v626 | OBJECT_Actor;
-            a1.field_5C = v626;
+            a1.spell_target_pid = v626;
             v627 = a1.Create(0, 0, 0, 0);
             v628 = a2;
             DamageMonsterFromParty(8 * v627 | 2, dword_50BF30[a2], (Vec3_int_ *)&v707);
@@ -7417,7 +7365,7 @@
           pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
           goto LABEL_203;
         }
-        v640 = v12 - 2;
+        v640 = v731 - 2;
         if ( !v640 || (v641 = v640 - 1) == 0 || (amount = 4, v641 != 1) )
           amount = 3;
         if ( pPlayer->uNumArmageddonCasts >= amount || pParty->armageddon_timer > 0 )
@@ -7753,7 +7701,8 @@
 
   bool shooting_bow = false,
        shotting_laser = false,
-       shooting_wand = false;
+       shooting_wand = false,
+       melee_attack = false;
   if (laser_weapon_item_id)
   {
     shotting_laser = true;
@@ -7771,6 +7720,8 @@
   }
   else if (target_type == OBJECT_Actor && actor_distance <= 407.2)
   {
+    melee_attack = true;
+
     Vec3_int_ a3;
     a3.x = actor->vPosition.x - pParty->vPosition.x;
     a3.y = actor->vPosition.y - pParty->vPosition.y;
@@ -7792,15 +7743,16 @@
   }
   else
   {
+    melee_attack = true;
     ; // actor out of range or no actor; no ranged weapon so melee attacking air
   }
 
-  if (!pParty->bTurnBasedModeOn)
+  if (!pParty->bTurnBasedModeOn && melee_attack) // wands, bows & lasers will add recovery while shooting spell effect
   {
-    int recovery = player->GetAttackRecoveryTime(0);
+    int recovery = player->GetAttackRecoveryTime(false);
     if (recovery < 30 )
       recovery = 30;
-    player->SetRecoveryTime((signed __int64)(flt_6BE3A4_debug_recmod1 * (double)recovery * 2.133333333333333));
+    player->SetRecoveryTime(flt_6BE3A4_debug_recmod1 * (double)recovery * 2.133333333333333);
   }
 
   
@@ -7817,7 +7769,7 @@
   else
   {
     int main_hand_idx = player->pEquipment.uMainHand;
-    if (player->HasItemEquipped(EQUIP_TWO_HANDED))
+    if (player->HasItemEquipped(EQUIP_MAIN_HAND))
       v34 = pItemsTable->pItems[*(int *)&player->pInventoryItems[main_hand_idx - 1]].uSkillType;
     pTurnEngine->_40471C();
   }
@@ -8143,9 +8095,9 @@
     v9 = v22;
   }
   v10 = 0;
-  a1a.field_50 = 0;
-  a1a.field_4C = 0;
-  a1a.field_48 = 0;
+  a1a.spell_skill = 0;
+  a1a.spell_level = 0;
+  a1a.spell_id = 0;
   a1a.field_54 = 0;
   a1a.uType = v9;
   if ( (signed int)pObjectList->uNumObjects <= 0 )
@@ -8173,8 +8125,8 @@
   a1a.uAttributes = attributes;
   a1a.uSectorID = pIndoor->GetSector(v21, y, z);
   a1a.uSpriteFrameID = 0;
-  a1a.field_58_pid = 0;
-  a1a.field_5C = 0;
+  a1a.spell_caster_pid = 0;
+  a1a.spell_target_pid = 0;
   if ( !(a1a.uAttributes & 0x10) )
   {
     v13 = 0;
@@ -8249,9 +8201,9 @@
   a1.stru_24.Reset();
 
   v5 = 0;
-  a1.field_50 = 0;
-  a1.field_4C = 0;
-  a1.field_48 = 0;
+  a1.spell_skill = 0;
+  a1.spell_level = 0;
+  a1.spell_id = 0;
   a1.field_54 = 0;
   a1.uType = 800;
   if ( (signed int)pObjectList->uNumObjects <= 0 )
@@ -8279,8 +8231,8 @@
   a1.uAttributes = 0;
   a1.uSectorID = pIndoor->GetSector(v3, v4, z);
   a1.uSpriteFrameID = 0;
-  a1.field_58_pid = 0;
-  a1.field_5C = 0;
+  a1.spell_caster_pid = 0;
+  a1.spell_target_pid = 0;
   v8 = a1.Create(0, 0, 0, 0);
   if ( v8 != -1 )
   {
@@ -8290,39 +8242,7 @@
   }
 }
 
-//----- (0042FA22) --------------------------------------------------------
-SpriteObject *__cdecl sub_42FA22_mess_with_laying_item_list()
-{
-  size_t v0; // edx@1
-  int v1; // ebp@1
-  SpriteObject *result; // eax@1
-  SpriteObject *v3; // ebx@1
-
-  v0 = 0;
-  v1 = 0;
-  //result = (char *)&pSpriteObjects[0].uObjectDescID;
-  result = pSpriteObjects;
-  v3 = pSpriteObjects;
-  do
-  {
-	if ( result->uObjectDescID )
-    {
-      if ( v1 != v0 )
-      {
-        memcpy(v3, result, 0x70u);
-        result->uObjectDescID = 0;
-      }
-      ++v0;
-      ++v3;// = (char *)v3 + 112;
-    }
-    ++result;// += 112;
-    ++v1;
-  }
-  //while ( (signed int)result < (signed int)((char *)&pObjectList->uNumObjects + 2) );
-  while( result <= &pSpriteObjects[999] );
-  uNumSpriteObjects = v0;
-  return result;
-}
+
 
 //----- (0042FA66) --------------------------------------------------------
 int __fastcall _42FA66_do_explosive_impact(int a1, int a2, int a3, int a4, __int16 a5, signed int a6)
@@ -8344,9 +8264,9 @@
   a1a.uType = 600;
   a1a.stru_24.Reset();
 
-  a1a.field_48 = 6;
-  a1a.field_4C = 8;
-  a1a.field_50 = 3;
+  a1a.spell_id = SPELL_FIRE_FIREBALL;
+  a1a.spell_level = 8;
+  a1a.spell_skill = 3;
   v14 = 0;
   if ( (signed int)pObjectList->uNumObjects <= 0 )
   {
@@ -8372,7 +8292,7 @@
   a1a.uAttributes = 0;
   a1a.uSectorID = pIndoor->GetSector(v6, v7, a3);
   a1a.uSpriteFrameID = 0;
-  a1a.field_5C = 0;
+  a1a.spell_target_pid = 0;
   a1a.field_60_distance_related_prolly_lod = 0;
   a1a.uFacing = 0;
   a1a.uSoundID = 0;
@@ -8380,11 +8300,11 @@
   {
     v10 = 8 * a6 - 8;
     LOBYTE(v10) = v10 | OBJECT_Player;
-    a1a.field_58_pid = v10;
+    a1a.spell_caster_pid = v10;
   }
   else
   {
-    a1a.field_58_pid = 0;
+    a1a.spell_caster_pid = 0;
   }
   result = a1a.Create(0, 0, 0, 0);
   if ( result != -1 )
@@ -8727,7 +8647,7 @@
               v6 = pPlayers[uActiveCharacter];
               if ( !v6->uTimeToRecovery )
               {
-                v24 = v6->GetAttackRecoveryTime(0);
+                v24 = v6->GetAttackRecoveryTime(false);
                 if ( !pParty->bTurnBasedModeOn )
                   pPlayers[uActiveCharacter]->SetRecoveryTime(
                     (signed __int64)(flt_6BE3A4_debug_recmod1 * (double)v24 * 2.133333333333333));
--- a/mm7_data.cpp	Tue Mar 26 23:18:58 2013 +0600
+++ b/mm7_data.cpp	Tue Mar 26 23:19:12 2013 +0600
@@ -322,7 +322,19 @@
 // Data declarations
 
 int game_starting_year = 0;
+int game_viewport_width;
+int game_viewport_height;
+int game_viewport_x;
+int game_viewport_y;
+int game_viewport_z;
+int game_viewport_w;
 
+
+
+unsigned int saveload_dlg_xs[2] = {82, 0};
+unsigned int saveload_dlg_ys[2] = {60, 0};
+unsigned int saveload_dlg_zs[2] = {460, 640};
+unsigned int saveload_dlg_ws[2] = {344, 480};
 int pWindowList_at_506F50_minus1_indexing[1];
 int dword_4C9890[10]; // weak
 int dword_4C9920[16]; // weak
@@ -949,10 +961,6 @@
 char byte_4E94D1 = 9; // weak
 char _4E94D2_light_type = 6; // weak
 char byte_4E94D3 = 10; // weak
-unsigned int saveload_dlg_xs[2] = {82, 0};
-unsigned int saveload_dlg_ys[2] = {60, 0};
-unsigned int saveload_dlg_zs[2] = {460, 640};
-unsigned int saveload_dlg_ws[2] = {344, 480};
 int dword_4E98BC_bApplicationActive; // weak
 //char *off_4EB080; // idb
 char *pTransitionStrings[465] = {"", nullptr};  // 004EB080
@@ -1230,7 +1238,6 @@
 int dword_4EDEA0[777]; // weak
 int dword_4EDEB4[777]; // weak
 int dword_4EDEC4[777]; // weak
-__int16 word_4EDED8[16] = {100, 90, 60, 100, 80, 100, 80, 30, 10, 10, 20, 30, 100, 0, 0, 0};
 _UNKNOWN unk_4EDF40; // weak
 unsigned int pHiredNPCsIconsOffsetsX[2] = {489, 559};
 unsigned int pHiredNPCsIconsOffsetsY[2] = {152, 152};
@@ -1911,30 +1918,6 @@
  struct Vec3_float_ *pTerrainNormals;
  unsigned short  pTerrainNormalIndices[128 * 128 * 2];
  unsigned int    pTerrainSomeOtherData[128 * 128 * 2];
-int dword_76D518_terrain_cell_world_pos_around_party_y; // weak
-int dword_76D51C_terrain_cell_world_pos_around_party_y; // weak
-int dword_76D520_terrain_cell_world_pos_around_party_y; // weak
-int dword_76D524_terrain_cell_world_pos_around_party_y; // weak
-int dword_76D528_terrain_cell_world_pos_around_party_z; // weak
-int dword_76D52C_terrain_cell_world_pos_around_party_z; // weak
-int dword_76D530_terrain_cell_world_pos_around_party_z; // weak
-int dword_76D534_terrain_cell_world_pos_around_party_z; // weak
-int dword_76D538_terrain_cell_world_pos_around_party_x; // weak
-int dword_76D53C_terrain_cell_world_pos_around_party_x; // weak
-int dword_76D540_terrain_cell_world_pos_around_party_x; // weak
-int dword_76D544_terrain_cell_world_pos_around_party_x; // weak
-//int dword_76D548_terrain_cell_world_pos_around_party_y; // weak
-//int dword_76D54C_terrain_cell_world_pos_around_party_y; // weak
-//int dword_76D550_terrain_cell_world_pos_around_party_y; // weak
-//int dword_76D554_terrain_cell_world_pos_around_party_y; // weak
-//int dword_76D558_terrain_cell_world_pos_around_party_z; // weak
-//int dword_76D55C_terrain_cell_world_pos_around_party_z; // weak
-//int dword_76D560_terrain_cell_world_pos_around_party_z; // weak
-//int dword_76D564_terrain_cell_world_pos_around_party_z; // weak
-//int dword_76D568_terrain_cell_world_pos_around_party_x; // weak
-//int dword_76D56C_terrain_cell_world_pos_around_party_x; // weak
-//int dword_76D570_terrain_cell_world_pos_around_party_x; // weak
-//int dword_76D574_terrain_cell_world_pos_around_party_x; // weak
 struct unk_F7B60C stru_76D578; // struct @ MM7.exe::0076D578
 struct unk_F7B60C stru_76D590; // struct @ MM7.exe::0076D590
 struct unk_F7B60C stru_76D5A8; // struct @ MM7.exe::0076D5A8
--- a/mm7_data.h	Tue Mar 26 23:18:58 2013 +0600
+++ b/mm7_data.h	Tue Mar 26 23:19:12 2013 +0600
@@ -312,6 +312,12 @@
 // Data declarations
 
 extern int game_starting_year;
+extern int game_viewport_width;
+extern int game_viewport_height;
+extern int game_viewport_x;
+extern int game_viewport_y;
+extern int game_viewport_z;
+extern int game_viewport_w;
 
 extern int pWindowList_at_506F50_minus1_indexing[1];
 extern int dword_4C9890[10]; // weak
@@ -818,7 +824,6 @@
 extern int dword_4EDEA0[]; // weak
 extern int dword_4EDEB4[]; // weak
 extern int dword_4EDEC4[]; // weak
-extern __int16 word_4EDED8[]; // weak
 extern _UNKNOWN unk_4EDF40; // weak
 extern unsigned int pHiredNPCsIconsOffsetsX[2];
 extern unsigned int pHiredNPCsIconsOffsetsY[2];
@@ -1418,30 +1423,6 @@
 extern struct Vec3_float_ *pTerrainNormals;
 extern unsigned short  pTerrainNormalIndices[128 * 128 * 2];
 extern unsigned int    pTerrainSomeOtherData[128 * 128 * 2];
-extern int dword_76D518_terrain_cell_world_pos_around_party_y; // weak
-extern int dword_76D51C_terrain_cell_world_pos_around_party_y; // weak
-extern int dword_76D520_terrain_cell_world_pos_around_party_y; // weak
-extern int dword_76D524_terrain_cell_world_pos_around_party_y; // weak
-extern int dword_76D528_terrain_cell_world_pos_around_party_z; // weak
-extern int dword_76D52C_terrain_cell_world_pos_around_party_z; // weak
-extern int dword_76D530_terrain_cell_world_pos_around_party_z; // weak
-extern int dword_76D534_terrain_cell_world_pos_around_party_z; // weak
-extern int dword_76D538_terrain_cell_world_pos_around_party_x; // weak
-extern int dword_76D53C_terrain_cell_world_pos_around_party_x; // weak
-extern int dword_76D540_terrain_cell_world_pos_around_party_x; // weak
-extern int dword_76D544_terrain_cell_world_pos_around_party_x; // weak
-//extern int dword_76D548_terrain_cell_world_pos_around_party_y; // weak
-//extern int dword_76D54C_terrain_cell_world_pos_around_party_y; // weak
-//extern int dword_76D550_terrain_cell_world_pos_around_party_y; // weak
-//extern int dword_76D554_terrain_cell_world_pos_around_party_y; // weak
-//extern int dword_76D558_terrain_cell_world_pos_around_party_z; // weak
-//extern int dword_76D55C_terrain_cell_world_pos_around_party_z; // weak
-//extern int dword_76D560_terrain_cell_world_pos_around_party_z; // weak
-//extern int dword_76D564_terrain_cell_world_pos_around_party_z; // weak
-//extern int dword_76D568_terrain_cell_world_pos_around_party_x; // weak
-//extern int dword_76D56C_terrain_cell_world_pos_around_party_x; // weak
-//extern int dword_76D570_terrain_cell_world_pos_around_party_x; // weak
-//extern int dword_76D574_terrain_cell_world_pos_around_party_x; // weak
 extern char byte_76D5C0;
 extern struct unk_F7B60C stru_76D578;
 extern struct unk_F7B60C stru_76D590;
@@ -1687,11 +1668,6 @@
 unsigned int __fastcall UI_GetHealthManaStringColor(signed int a1, signed int a2);
 signed int __thiscall GetConditionDrawColor(unsigned int uConditionIdx); // idb
 char __fastcall sub_4179BC_draw_tooltip(const char *a1, const char *a2); // idb
-unsigned int __fastcall GetSkillColor(unsigned int uPlayerClass, enum PLAYER_SKILL_TYPE uPlayerSkillType, signed int skill_level);
-const char *__fastcall CharacterUI_GetSkillDescText(unsigned int uPlayerID, enum PLAYER_SKILL_TYPE uPlayerSkillType);
-char __cdecl CharacterUI_SkillsTab_ShowHint();
-char __cdecl CharacterUI_StatsTab_ShowHint();
-char __fastcall CharacterUI_StatsTab_Draw(unsigned int uPlayerID); // idb
 void FillAwardsData();
 void __cdecl sub_419220();
 void __cdecl sub_419379();
@@ -1761,7 +1737,7 @@
 signed int __cdecl sub_42F4DA();
 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
-SpriteObject *__cdecl sub_42FA22_mess_with_laying_item_list();
+void CompactLayingItemsList();
 signed int __fastcall _42FA66_do_explosive_impact(int a1, int a2, int a3, int a4, __int16 a5, signed int a6);
 bool __fastcall sub_42FB5C(signed int a1);
 // int __cdecl crt_sub_42FBB7();
@@ -1896,12 +1872,12 @@
 unsigned int __fastcall SkillToMastery(unsigned __int16 a1);
 unsigned int __fastcall GetSpellColor(signed int a1);
 void *__thiscall unknown_vdtor_6(void *_this, bool a2);
-unsigned __int16 *__fastcall MakeScreenshot(signed int width, signed int height);
+unsigned short * MakeScreenshot(signed int width, signed int height);
 void __thiscall SaveScreenshot(const char *pFilename);
 void __fastcall GameUI_DrawLoadMenu(unsigned int uDialogueType); // idb
 void __cdecl GameUI_DrawSaveMenu();
 void __fastcall LoadGame(unsigned int uSlot); // idb
-int __fastcall SaveGame(int a1, __int16 *a2);
+void SaveGame(bool IsAutoSAve, bool NotSaveWorld);
 void __fastcall DoSavegame(unsigned int uSlot); // idb
 void GameUI_MainMenu_DoDrawLoad(int a1);
 void GameUI_MainMenu_DrawLoad();
--- a/stru277.h	Tue Mar 26 23:18:58 2013 +0600
+++ b/stru277.h	Tue Mar 26 23:19:12 2013 +0600
@@ -9,16 +9,16 @@
   //----- (00426987) --------------------------------------------------------
   inline stru277()
   {
-  this->field_8 = 0;
-  this->spellnum = 0;
-  this->field_6 = 0;
-  this->uPlayerID_2 = 0;
-  this->uPlayerID = 0;
-  this->field_10 = 0;
+    field_8 = 0;
+    spellnum = 0;
+    field_6 = 0;
+    uPlayerID_2 = 0;
+    uPlayerID = 0;
+    sound_id = 0;
   }
 
   void _427D48(unsigned int uPlayerID);
-  unsigned int PushStru277(__int16 a2, __int16 uPlayerID, __int16 skill_level, __int16 a5, int a6);
+  unsigned int PushStru277(__int16 a2, __int16 uPlayerID, __int16 skill_level, __int16 a5, int sound_id);
   struct GUIWindow *sub_4219BE();
   void _427E01_cast_spell();
 
@@ -29,7 +29,7 @@
   __int16 field_8;
   __int16 forced_spell_skill_level;
   int spell_target_pid;
-  int field_10;
+  int sound_id;
 };
 #pragma pack(pop)
 
--- a/stru6.cpp	Tue Mar 26 23:18:58 2013 +0600
+++ b/stru6.cpp	Tue Mar 26 23:19:12 2013 +0600
@@ -830,9 +830,9 @@
       AddMobileLight(a2, 0xFF3C1E, 256);
       if (pRenderer->pRenderD3D)
       {
-        result = a2->field_58_pid & 7;
-        if ((a2->field_58_pid & 7) != OBJECT_Actor &&
-            (a2->field_58_pid & 7) != OBJECT_Item)
+        result = a2->spell_caster_pid & 7;
+        if ((a2->spell_caster_pid & 7) != OBJECT_Actor &&
+            (a2->spell_caster_pid & 7) != OBJECT_Item)
         {
           if (field_204 != 4)
           {