changeset 230:b9f4ff2f6c45

Merge
author Gloval
date Sun, 17 Feb 2013 17:18:45 +0400
parents 05a2d2b35ed0 (current diff) 46ae2602aceb (diff)
children a69fc44061d5 0df4136b6aac 3395164886cd
files Items.cpp Items.h
diffstat 11 files changed, 286 insertions(+), 349 deletions(-) [+]
line wrap: on
line diff
--- a/CShow.h	Sun Feb 17 17:07:52 2013 +0400
+++ b/CShow.h	Sun Feb 17 17:18:45 2013 +0400
@@ -36,7 +36,7 @@
   //std::string v5; // [sp-18h] [bp-24h]@4
   //signed int v6; // [sp-Ch] [bp-18h]@10
   int ScreenSizeFlag; // [sp-8h] [bp-14h]@4
-  int v8; // [sp-4h] [bp-10h]@4
+  //int v8; // [sp-4h] [bp-10h]@4
   //char v9; // [sp+0h] [bp-Ch]@14
   //char v10; // [sp+4h] [bp-8h]@4
   //int a3; // [sp+Bh] [bp-1h]@14
@@ -49,53 +49,46 @@
       MessageBoxW(nullptr, L"No movie", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Show.cpp:40", 0);
       break;
     case MOVIE_3DOLogo:
-      v8 = 1;
       ScreenSizeFlag = 0;
       v3 = 0;
       Name = "3dologo";
-      VideoPlayer::MovieLoop(Name, v3, ScreenSizeFlag, v8);
+      VideoPlayer::MovieLoop(Name, v3, ScreenSizeFlag, 1);
       break;
     case MOVIE_NWCLogo:
-      v8 = 1;
       ScreenSizeFlag = 1;
       v3 = 0;
       Name = "new world logo";
-      VideoPlayer::MovieLoop(Name, v3, ScreenSizeFlag, v8);
+      VideoPlayer::MovieLoop(Name, v3, ScreenSizeFlag, 1);
       break;
     case MOVIE_JVC:
-      v8 = 1;
       ScreenSizeFlag = 1;
       v3 = 0;
       Name = "jvc";
-      VideoPlayer::MovieLoop(Name, v3, ScreenSizeFlag, v8);
+      VideoPlayer::MovieLoop(Name, v3, ScreenSizeFlag, 1);
       break;
     case MOVIE_Intro:
-      v8 = 1;
       ScreenSizeFlag = 1;
       v3 = 0;
       Name = "Intro";
-      VideoPlayer::MovieLoop(Name, v3, ScreenSizeFlag, v8);
+      VideoPlayer::MovieLoop(Name, v3, ScreenSizeFlag, 1);
       break;
     case MOVIE_Emerald:
-      v8 = 1;
       ScreenSizeFlag = 1;
       v3 = 0;
       Name = "Intro Post";
-      VideoPlayer::MovieLoop(Name, v3, ScreenSizeFlag, v8);
+      VideoPlayer::MovieLoop(Name, v3, ScreenSizeFlag, 1);
       break;
     case MOVIE_Death:
-      v8 = 1;
       ScreenSizeFlag = 1;
       v3 = 2;
       Name = "losegame";
-      VideoPlayer::MovieLoop(Name, v3, ScreenSizeFlag, v8);
+      VideoPlayer::MovieLoop(Name, v3, ScreenSizeFlag, 1);
       break;
     case MOVIE_Outro:
-      v8 = 1;
       ScreenSizeFlag = 1;
       v3 = 20;
       Name = "end_seq1";
-      VideoPlayer::MovieLoop(Name, v3, ScreenSizeFlag, v8);
+      VideoPlayer::MovieLoop(Name, v3, ScreenSizeFlag, 1);
       break;
     default:
       MessageBoxW(nullptr, L"Invalid movie requested in CShow::Run()", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Show.cpp:72", 0);
--- a/Game.cpp	Sun Feb 17 17:07:52 2013 +0400
+++ b/Game.cpp	Sun Feb 17 17:18:45 2013 +0400
@@ -1024,7 +1024,7 @@
 //----- (0044EA5E) --------------------------------------------------------
 bool Game::PickMouse(float fPickDepth, unsigned int uMouseX, unsigned int uMouseY, bool bOutline, Vis_SelectionFilter *sprite_filter, Vis_SelectionFilter *face_filter)
 {
-  if (pCurrentScreen || !pRenderer->pRenderD3D)
+  if (pCurrentScreen != SCREEN_GAME|| !pRenderer->pRenderD3D)
     return false;
 
   if (!pVisInstance)
--- a/Items.cpp	Sun Feb 17 17:07:52 2013 +0400
+++ b/Items.cpp	Sun Feb 17 17:18:45 2013 +0400
@@ -1,4 +1,5 @@
 #include <stdlib.h>
+#include <assert.h>
 
 #include "Items.h"
 #include "MapInfo.h"
@@ -1504,14 +1505,14 @@
 
 
 //----- (00456620) --------------------------------------------------------
-void ItemsTable::GenerateItem(int a2, int a3, ItemGen *pItem)
+void ItemsTable::GenerateItem(int treasure_level, int a3, ItemGen *out_item)
 {
-  ItemGen *v4; // esi@1
-  ItemsTable *v5; // edi@1
+  //ItemGen *v4; // esi@1
+  //ItemsTable *v5; // edi@1
   int v6; // ebx@3
   int *v7; // ecx@33
-  int v8; // eax@34
-  int v9; // eax@39
+  //int v8; // eax@34
+  //int v9; // eax@39
   int v10; // ebx@43
   int v11; // ecx@47
   unsigned int *v12; // edx@48
@@ -1553,163 +1554,103 @@
   unsigned int v48; // ecx@123
   int v49; // eax@123
   int v50; // eax@123
-  unsigned char Dst[0xC80]; // [sp+Ch] [bp-C88h]@33
+  int Dst[800]; // [sp+Ch] [bp-C88h]@33
   int v52; // [sp+C8Ch] [bp-8h]@33
-  int v53; // [sp+C90h] [bp-4h]@1
-  int v54; // [sp+C9Ch] [bp+8h]@3
-  int v55; // [sp+CA0h] [bp+Ch]@34
+  //int v53; // [sp+C90h] [bp-4h]@1
+  //int v54; // [sp+C9Ch] [bp+8h]@3
+  //int v55; // [sp+CA0h] [bp+Ch]@34
   signed int v56; // [sp+CA0h] [bp+Ch]@55
   int v57; // [sp+CA0h] [bp+Ch]@62
   int *v58; // [sp+CA0h] [bp+Ch]@102
   int v59; // [sp+CA0h] [bp+Ch]@123
-  signed int a2a; // [sp+CA4h] [bp+10h]@33
+  //signed int a2a; // [sp+CA4h] [bp+10h]@33
   int a2b; // [sp+CA4h] [bp+10h]@101
   int a2c; // [sp+CA4h] [bp+10h]@120
 
-  v53 = -1;
-  v4 = pItem;
-  v5 = this;
-  if ( !pItem )
-    v4 = (ItemGen *)pAllocator->AllocNamedChunk(pItem, 0x24u, "newItemGen");
-  memset(v4, 0, 0x24u);
-  v6 = a2 - 1;
-  v54 = a2 - 1;
+  //v53 = -1;
+  //v4 = pItem;
+  //v5 = this;
+  if (!out_item)
+    out_item = (ItemGen *)pAllocator->AllocNamedChunk(out_item, sizeof(*out_item), "newItemGen");
+  memset(out_item, 0, sizeof(*out_item));
+
+  auto v4 = out_item;
+  v6 = treasure_level - 1;
+  //v54 = treasure_level - 1;
   if ( a3 )
   {
-    switch ( a3 )
+    ITEM_EQUIP_TYPE   requested_equip;
+    PLAYER_SKILL_TYPE requested_skill = PLAYER_SKILL_INVALID;
+    switch (a3)
+     {
+      case 20: requested_equip = EQUIP_ONE_OR_TWO_HANDS; break;
+      case 21: requested_equip = EQUIP_ARMOUR; break;
+      case 22: requested_skill = (PLAYER_SKILL_TYPE)38; __debugbreak();/*check this skill*/ break;
+      case 23: requested_skill = PLAYER_SKILL_SWORD; break;
+      case 24: requested_skill = PLAYER_SKILL_DAGGER; break;
+      case 25: requested_skill = PLAYER_SKILL_AXE; break;
+      case 26: requested_skill = PLAYER_SKILL_SPEAR; break;
+      case 27: requested_skill = PLAYER_SKILL_BOW; break;
+      case 28: requested_skill = PLAYER_SKILL_MACE; break;
+      case 29: requested_skill = (PLAYER_SKILL_TYPE)37; __debugbreak();/*check this skill*/break;
+      case 30: requested_skill = PLAYER_SKILL_STAFF; break;
+      case 31: requested_skill = PLAYER_SKILL_LEATHER; break;
+      case 32: requested_skill = PLAYER_SKILL_CHAIN; break;
+      case 33: requested_skill = PLAYER_SKILL_PLATE; break;
+      case 34: requested_equip = EQUIP_SHIELD; break;
+      case 35: requested_equip = EQUIP_HELMET; break;
+      case 36: requested_equip = EQUIP_BELT; break;
+      case 37: requested_equip = EQUIP_CLOAK; break;
+      case 38: requested_equip = EQUIP_GAUNTLETS; break;
+      case 39: requested_equip = EQUIP_BOOTS; break;
+      case 40: requested_equip = EQUIP_RING; break;
+      case 41: requested_equip = EQUIP_AMULET; break;
+      case 42: requested_equip = EQUIP_C; break;
+      case 43: requested_equip = EQUIP_F; break;
+      case 44: requested_equip = EQUIP_POTION; break;
+      case 45: requested_equip = EQUIP_REAGENT; break;
+      case 46: requested_equip = EQUIP_GEM; break;
+      default:
+        __debugbreak(); // check this condition
+        requested_equip = (ITEM_EQUIP_TYPE)(a3 - 1);
+      break;
+    }
+    memset(Dst, 0, sizeof(Dst));
+    v52 = 0;
+    v7 = Dst;
+    //a2a = 1;
+    if (requested_skill == PLAYER_SKILL_INVALID)
     {
-      case 20:
-        a3 = EQUIP_ONE_OR_TWO_HANDS;
-        break;
-      case 21:
-        a3 = 3;
-        break;
-      case 22:
-        v53 = 38;
-        break;
-      case 23:
-        v53 = 1;
-        break;
-      case 24:
-        v53 = 2;
-        break;
-      case 25:
-        v53 = 3;
-        break;
-      case 26:
-        v53 = 4;
-        break;
-      case 27:
-        v53 = 5;
-        break;
-      case 28:
-        v53 = 6;
-        break;
-      case 30:
-        v53 = 0;
-        break;
-      case 31:
-        v53 = 9;
-        break;
-      case 32:
-        v53 = 10;
-        break;
-      case 33:
-        v53 = 0xBu;
-        break;
-      case 34:
-        a3 = 4;
-        break;
-      case 35:
-        a3 = 5;
-        break;
-      case 36:
-        a3 = 6;
-        break;
-      case 37:
-        a3 = 7;
-        break;
-      case 38:
-        a3 = 8;
-        break;
-      case 39:
-        a3 = EQUIP_BOOTS;
-        break;
-      case 40:
-        a3 = EQUIP_RING;
-        break;
-      case 41:
-        a3 = 0xBu;
-        break;
-      case 42:
-        a3 = EQUIP_C;
-        break;
-      case 43:
-        a3 = EQUIP_F;
-        break;
-      case 44:
-        a3 = EQUIP_POTION;
-        break;
-      case 45:
-        a3 = EQUIP_REAGENT;
-        break;
-      case 46:
-        a3 = EQUIP_GEM;
-        break;
-      case 29:
-        v53 = 37;
-        break;
-      default:
-        --a3;
-        break;
-    }
-    memset(&Dst, 0, 0xC80u);
-    v52 = 0;
-    v7 = (int *)&Dst;
-    a2a = 1;
-    if ( v53 == -1 )
-    {
-      v53 = (int)&v5->pItems[1].uEquipType;
-      v9 = (int)(&v5->pItems[1].uChanceByTreasureLvl[0] + v6);
-      do
+      for (uint i = 1; i < 500; ++i)
       {
-        if ( *(unsigned char *)v53 == a3 )
+        if (pItems[i].uEquipType == requested_equip)
         {
-          *v7 = a2a;
-          ++v7;
-          v52 += *(unsigned char *)v9;
+          *v7++ = i;
+          v52 += pItems[i].uChanceByTreasureLvl[v6];
         }
-        ++a2a;
-        v53 += 48;
-        v9 += 48;
       }
-      while ( a2a < 500 );
     }
     else
     {
-      v55 = (int)&v5->pItems[1].uSkillType;
-      v8 = (int)(&v5->pItems[1].uChanceByTreasureLvl[0] + v6);
-      do
+      for (uint i = 1; i < 500; ++i)
       {
-        if ( *(unsigned char *)v55 == v53 )
+        if (pItems[i].uSkillType == requested_skill)
         {
-          *v7 = a2a;
-          ++v7;
-          v52 += *(unsigned char *)v8;
+          *v7++ = i;
+          v52 += pItems[i].uChanceByTreasureLvl[v6];
         }
-        ++a2a;
-        v55 += 48;
-        v8 += 48;
       }
-      while ( a2a < 500 );
     }
+
     v10 = 0;
     if ( v52 )
       v10 = rand() % v52;
-    v4->uItemID = *(uint *)Dst;
-    if ( !Dst )
+
+    v4->uItemID = *Dst;
+    if (!v4->uItemID)
       v4->uItemID = 1;
-    v11 = *(&v5->pItems[v4->uItemID].uChanceByTreasureLvl[0] + v54);
+
+    v11 = pItems[v4->uItemID].uChanceByTreasureLvl[v6];
     if ( v11 < v10 )
     {
       v12 = (uint *)Dst;
@@ -1718,11 +1659,11 @@
         ++v12;
         v13 = *v12;
         v4->uItemID = *v12;
-        v11 += *(&v5->pItems[v13].uChanceByTreasureLvl[0] + v54);
+        v11 += pItems[v13].uChanceByTreasureLvl[v6];
       }
       while ( v11 < v10 );
     }
-    if ( v5->pItems[v4->uItemID].uEquipType == EQUIP_POTION && v4->uItemID != ITEM_POTION_BOTTLE )
+    if (pItems[v4->uItemID].uEquipType == EQUIP_POTION && v4->uItemID != ITEM_POTION_BOTTLE )
     {
       v4->_bonus_type = 0;
       v14 = 2;
@@ -1734,7 +1675,7 @@
       }
       while ( v14 );
 LABEL_72:
-      v4->_bonus_type = v15 * (v54 + 1);
+      v4->_bonus_type = v15 * treasure_level;
       goto LABEL_73;
     }
   }
@@ -1746,12 +1687,12 @@
       v56 += pParty->field_7BA[v16++];
     while ( v16 < 29 );
     v17 = rand() % 29;
-    if ( v54 == 5 && rand() % 100 < 5 && !pParty->field_7BA[v17] && v56 < 13 )
+    if ( v6 == 5 && rand() % 100 < 5 && !pParty->field_7BA[v17] && v56 < 13 )
     {
       pParty->field_7BA[v17] = 1;
       v4->uAttributes = 0;
       v4->uItemID = v17 + 500;
-      v5->SetSpecialBonus(v4);
+      SetSpecialBonus(v4);
       return;
     }
     v57 = 0;
@@ -1760,14 +1701,14 @@
     if ( v18 > 0 )
     {
       do
-        v57 += *(&v5->pItems[v4->uItemID++ + 1].uChanceByTreasureLvl[0] + v54);
+        v57 += pItems[v4->uItemID++ + 1].uChanceByTreasureLvl[v6];
       while ( v57 < v18 );
     }
     if ( !v18 )
       v4->uItemID = 1;
     if ( !v4->uItemID )
       v4->uItemID = 1;
-    if ( v5->pItems[v4->uItemID].uEquipType == EQUIP_POTION && v4->uItemID != ITEM_POTION_BOTTLE )
+    if (pItems[v4->uItemID].uEquipType == EQUIP_POTION && v4->uItemID != ITEM_POTION_BOTTLE)
     {
       v4->_bonus_type = 0;
       v19 = 2;
@@ -1789,12 +1730,12 @@
     v4->uAttributes = 0;
   else
     v4->uAttributes = 1;
-  if ( v5->pItems[v4->uItemID].uEquipType != EQUIP_POTION )
+  if ( pItems[v4->uItemID].uEquipType != EQUIP_POTION )
   {
     v4->uAdditionalValue = 0;
     v4->_bonus_type = 0;
   }
-  v20 = v5->pItems[v4->uItemID].uEquipType;
+  v20 = pItems[v4->uItemID].uEquipType;
   if ( v20 <= EQUIP_BOW )
   {
     v37 = 10;//(int)&v5->field_1169C[4 * v54 + 48];
@@ -1816,7 +1757,7 @@
       }
       return;
     }
-    v22 = (int)&v5->uBonusChanceStandart[v54];
+    v22 = (int)&uBonusChanceStandart[v6];
     if ( !*(unsigned int *)v22 )
       return;
     v23 = rand();
@@ -1824,7 +1765,7 @@
     v25 = v23 % 100;
     if ( v23 % 100 < v24 )
       goto LABEL_127;
-    if ( !v5->uBonusChanceSpecial[v54] )
+    if ( !uBonusChanceSpecial[v6] )
         return;
     if ( v25 < v24 )
     {
@@ -1832,9 +1773,9 @@
       v26 = rand() % 10;//v5->field_116D8[v5->pItems[v4->uItemID].uEquipType];
       v27 = v4->uItemID;
       v4->_bonus_type = 0;
-      for ( i = v5->pEnchantments[0].to_item[v5->pItems[v27].uEquipType + 1];
+      for ( i = pEnchantments[0].to_item[pItems[v27].uEquipType + 1];
             i < v26;
-            i += v5->pEnchantments[v4->_bonus_type].to_item[v5->pItems[v29].uEquipType + 1] )
+            i += pEnchantments[v4->_bonus_type].to_item[pItems[v29].uEquipType + 1] )
       {
         v29 = v4->uItemID;
         ++v4->_bonus_type;
@@ -1860,14 +1801,14 @@
   memset(&Dst, 0, 0xC80u);
   v39 = 0;
   a2b = 0;
-  if ( v5->pSpecialEnchantments_count > 0 )
+  if ( pSpecialEnchantments_count > 0 )
   {
-    v52 = -16 - (uint)v5;
+    v52 = -16 - (uint)this;
     v58 = (int *)&Dst;
-    v40 = (int)&v5->pSpecialEnchantments[1];
+    v40 = (int)&pSpecialEnchantments[1];
     do
     {
-      switch ( v54 )
+      switch ( v6 )
       {
         case 2:
           if ( !*(unsigned char *)v40 )
@@ -1879,8 +1820,8 @@
           if ( !*(unsigned char *)v40 || v43 == 1 )
           {
 LABEL_117:
-            v39 += *((unsigned char *)&v5->uAllItemsCount + v40 + v52 + v5->pItems[v4->uItemID].uEquipType);
-            if ( *((unsigned char *)&v5->uAllItemsCount + v40 + v52 + v5->pItems[v4->uItemID].uEquipType) )
+            v39 += *((unsigned char *)&uAllItemsCount + v40 + v52 + pItems[v4->uItemID].uEquipType);
+            if ( *((unsigned char *)&uAllItemsCount + v40 + v52 + pItems[v4->uItemID].uEquipType) )
             {
               v44 = v58;
               ++v58;
@@ -1897,7 +1838,7 @@
           v41 = v42 == 3;
           break;
         default:
-          if ( v54 != 5 )
+          if ( v6 != 5 )
             goto LABEL_119;
           v41 = *(unsigned char *)v40 == 3;
           break;
@@ -1908,12 +1849,12 @@
       ++a2b;
       v40 += 28;
     }
-    while ( a2b < v5->pSpecialEnchantments_count );
+    while ( a2b < pSpecialEnchantments_count );
   }
   v45 = rand();
   v4->uAdditionalValue = *(uint *)Dst;
   v46 = v45 % v39 + 1;
-  a2c = *((unsigned char *)&v5->uAllItemsCount + 28 * (*(uint *)Dst + 1389) + v5->pItems[v4->uItemID].uEquipType);
+  a2c = *((unsigned char *)&uAllItemsCount + 28 * (*(uint *)Dst + 1389) + pItems[v4->uItemID].uEquipType);
   if ( a2c < v46 )
   {
     for ( j = (int *)&Dst; ; j = (int *)v59 )
@@ -1923,7 +1864,7 @@
       v59 = v49;
       v50 = *(unsigned int *)v49;
       v4->uAdditionalValue = v50;
-      a2c += *((unsigned char *)&v5->uAllItemsCount + 28 * (v50 + 1389) + v5->pItems[v48].uEquipType);
+      a2c += *((unsigned char *)&uAllItemsCount + 28 * (v50 + 1389) + pItems[v48].uEquipType);
       if ( a2c >= v46 )
         break;
     }
--- a/Items.h	Sun Feb 17 17:07:52 2013 +0400
+++ b/Items.h	Sun Feb 17 17:18:45 2013 +0400
@@ -216,7 +216,7 @@
   void Initialize();
   void LoadPotions();
   void LoadPotionNotes();
-  void GenerateItem(int a2, int a3, ItemGen *pItem);
+  void GenerateItem(int treasure_level, int a3, ItemGen *pItem);
   void SetSpecialBonus(ItemGen *pItem);
   bool _456D43_is_material_equals_3(ItemGen *pItem);
   bool _456D5E_is_some_material(ItemGen *pItem);
--- a/Outdoor.h	Sun Feb 17 17:07:52 2013 +0400
+++ b/Outdoor.h	Sun Feb 17 17:18:45 2013 +0400
@@ -124,6 +124,9 @@
   {
     subconstuctor();
     uLastSunlightUpdateMinute = 0;
+
+    uNumBModels = 0;
+    pBModels = nullptr;
   }
   //----- (004626CD) --------------------------------------------------------
   void subconstuctor()
--- a/VideoPlayer.cpp	Sun Feb 17 17:07:52 2013 +0400
+++ b/VideoPlayer.cpp	Sun Feb 17 17:18:45 2013 +0400
@@ -334,7 +334,7 @@
 
 
 //----- (004BE70E) --------------------------------------------------------
-void __fastcall VideoPlayer::MovieLoop(const char *pMovieName, int a2, int ScreenSizeFlag, int uGameState)
+void __fastcall VideoPlayer::MovieLoop(const char *pMovieName, int a2, int ScreenSizeFlag, int a4)
 {
   int v4; // ebp@1
   const char *pName; // edi@1
@@ -418,7 +418,7 @@
         }
       }
     }
-    if ( uGameState == GAME_FINISHED )
+    if (a4 == 1)
       pCurrentScreen = SCREEN_GAME;
     pVideoPlayer->bPlayingMovie = 0;
     ShowCursor(1);
--- a/Vis.cpp	Sun Feb 17 17:07:52 2013 +0400
+++ b/Vis.cpp	Sun Feb 17 17:18:45 2013 +0400
@@ -6,6 +6,7 @@
 #include "Actor.h"
 #include "IndoorCamera.h"
 #include "Viewport.h"
+#include "Log.h"
 
 #include "mm7_data.h"
 //#include "MM7.h"
@@ -1482,8 +1483,13 @@
   PickBillboards_Mouse(fDepth, fMouseX, fMouseY, &default_list, sprite_filter);
   if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
     PickIndoorFaces_Mouse(fDepth, pMouseRay, &default_list, face_filter);
+  else if (uCurrentlyLoadedLevelType == LEVEL_Outdoor)
+    PickOutdoorFaces_Mouse(fDepth, pMouseRay, &default_list, face_filter, false);
   else
-    PickOutdoorFaces_Mouse(fDepth, pMouseRay, &default_list, face_filter, false);
+  {
+    Log::Warning(L"Picking mouse in undefined level"); // picking in main menu is default (buggy) game behavious. should've returned false in Game::PickMouse
+    return false;
+  }
   default_list.create_object_pointers(Vis_SelectionList::All);
   sort_object_pointers(default_list.object_pointers, 0, default_list.uNumPointers - 1);
 
--- a/mm7_3.cpp	Sun Feb 17 17:07:52 2013 +0400
+++ b/mm7_3.cpp	Sun Feb 17 17:18:45 2013 +0400
@@ -5183,24 +5183,24 @@
 {
   char *v4; // eax@4
   char v5; // dl@5
-  char *v6; // ecx@5
-  int v7; // edi@9
+  int v6; // ecx@5
+  char *v7; // edi@9
   char *v9; // eax@21
   char v10; // dl@22
-  char *v11; // ecx@22
-  int v12; // edi@26
+  int v11; // ecx@22
+  char *v12; // edi@26
   char *v14; // eax@39
   char v15; // dl@40
   int v16; // ecx@40
-  int v17; // edi@44
+  char *v17; // edi@44
   char v18; // zf@47
   NPCStats_stru0 *v19; // eax@57
   signed int v20; // edx@57
   signed int v21; // ecx@58
-  char *v22; // [sp+10h] [bp-10h]@4
-  char *v23; // [sp+10h] [bp-10h]@21
-  char *v25; // [sp+14h] [bp-Ch]@4
-  char *v26; // [sp+14h] [bp-Ch]@21
+  int v22; // [sp+10h] [bp-10h]@4
+  int v23; // [sp+10h] [bp-10h]@21
+  int v25; // [sp+14h] [bp-Ch]@4
+  int v26; // [sp+14h] [bp-Ch]@21
   signed int v27; // [sp+14h] [bp-Ch]@39
   //signed int v28; // [sp+18h] [bp-8h]@3
   //signed int v29; // [sp+18h] [bp-8h]@20
@@ -5219,8 +5219,8 @@
   for (uint i = 0; i < 789; ++i)
   {
     v4 = strtok(nullptr, "\r") + 1;
-    v22 = nullptr;
-    v25 = nullptr;
+    v22 = 0;
+    v25 = 0;
     do
     {
       v5 = *v4;
@@ -5232,28 +5232,28 @@
           if ( !v5 )
             break;
           ++v6;
-          v5 = v4[(int)v6];
+          v5 = v4[v6];
         }
         while ( v5 != 9 );
         //v2 = 0;
       }
-      v7 = (int)&v4[(int)v6];
-      if ( !v4[(int)v6] )
-        v25 = (char *)1;
-      *(char *)v7 = 0;
-      if ( v6 == nullptr )
-      {
-        v25 = (char *)1;
-      }
-      else
-      {
-        if ( v22 == (char *)1 )
+      v7 = &v4[v6];
+      if ( !v4[v6] )
+        v25 = 1;
+      *v7 = 0;
+      if ( v6 == 0 )
+      {
+        v25 = 1;
+      }
+      else
+      {
+        if ( v22 == 1 )
           pNPCTopics[i].pText = RemoveQuotes(v4);
       }
       ++v22;
-      v4 = (char *)(v7 + 1);
-    }
-    while ( (signed int)(v22 - 1) <= 1 && v25 == nullptr );
+      v4 = v7 + 1;
+    }
+    while ( (signed int)(v22 - 1) <= 1 && !v25);// == nullptr );
   }
 
   if (pNPCTopicTXT_Raw)
@@ -5266,8 +5266,8 @@
   for (uint i = 0; i < 579; ++i)
   {
     v9 = strtok(nullptr, "\r") + 1;
-    v23 = nullptr;
-    v26 = nullptr;
+    v23 = 0;
+    v26 = 0;
     do
     {
       v10 = *v9;
@@ -5279,28 +5279,28 @@
           if ( !v10 )
             break;
           ++v11;
-          v10 = v9[(int)v11];
+          v10 = v9[v11];
         }
         while ( v10 != 9 );
         //v2 = 0;
       }
-      v12 = (int)&v9[(int)v11];
-      if ( !v9[(int)v11] )
-        v26 = (char *)1;
-      *(char *)v12 = 0;
-      if ( v11 == nullptr )
-      {
-        v26 = (char *)1;
-      }
-      else
-      {
-        if ( v23 == (char *)1 )
+      v12 = &v9[v11];
+      if ( !v9[v11] )
+        v26 = 1;
+      *v12 = 0;
+      if ( v11 == 0 )
+      {
+        v26 = 1;
+      }
+      else
+      {
+        if ( v23 == 1 )
           pNPCTopics[i].pTopic = RemoveQuotes(v9);
       }
       ++v23;
-      v9 = (char *)(v12 + 1);
-    }
-    while ( (signed int)(v23 - 1) <= 1 && v26 == nullptr );
+      v9 = v12 + 1;
+    }
+    while ( (signed int)(v23 - 1) <= 1 && !v26 );
   }
 
   if (pNPCDistTXT_Raw)
@@ -5335,10 +5335,10 @@
         while ( v15 != 9 );
         v2 = v24;
       }
-      v17 = (int)&v14[v16];
+      v17 = &v14[v16];
       if ( !v14[v16] )
         v27 = 1;
-      *(char *)v17 = 0;
+      *v17 = 0;
       if ( !v16 )
       {
         v27 = 1;
@@ -5358,7 +5358,7 @@
         *v31 = 10;
 LABEL_54:
       ++v2;
-      v14 = (char *)(v17 + 1);
+      v14 = v17 + 1;
       v24 = v2;
     }
     while ( (signed int)(v2 - 1) <= 77 && !v27 );
@@ -9665,7 +9665,7 @@
   for (uint i = 0; i < 16384; ++i)
   //do
   {
-    auto v4 = stru_76E5C8 + i;
+    auto v4 = stru_76E5C8[i];
     //band3a = 256;
     //v8 = (double)(signed int)((char *)v4 + 256 - (int)stru_76E5C8);
     for (uint j = 0; j < 128; ++j)                  // band3a: 0 -> 128
@@ -9677,17 +9677,17 @@
       if (v7 >= v10)
       {
         if (v7 >= v9)
-          v4->field_0 = ((v7 >= v3) - 1) & 2;
-        else
-          v4->field_0 = 2;
-      }
-      else
-      {
-        v4->field_0 = 1;
+          v4.field_0 = ((v7 >= v3) - 1) & 2;
+        else
+          v4.field_0 = 2;
+      }
+      else
+      {
+        v4.field_0 = 1;
       }
       //band3a += 512;
-      v4->distance = v7;
-      ++v4;
+      v4.distance = v7;
+      //++v4;
     }
     //while ( band3a < 65792 );
   }
@@ -16453,7 +16453,7 @@
   __int16 v54[2]; // [sp+104h] [bp-10h]@2
   unsigned __int16 *v55; // [sp+108h] [bp-Ch]@82
   GUIFont *pOutString; // [sp+10Ch] [bp-8h]@39
-  char *pInString; // [sp+110h] [bp-4h]@32
+  char *pInString=NULL; // [sp+110h] [bp-4h]@32
 
   if ( !pDialogueWindow )
     return;
@@ -17005,7 +17005,7 @@
       {
         MessageBoxW(nullptr, L"NPC id exceeds MAX_DATA!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Events.cpp:1984", 0);
       }
-      return &pNPCStats->pNewNPCData[v1 - 1];
+      return &pNPCStats->pNewNPCData[v1];// - 1];
     }
     return &pNPCStats->array_13EF4[npcid - 5000];
   }
--- a/mm7_4.cpp	Sun Feb 17 17:07:52 2013 +0400
+++ b/mm7_4.cpp	Sun Feb 17 17:18:45 2013 +0400
@@ -5845,7 +5845,7 @@
 //----- (00497526) --------------------------------------------------------
 bool __cdecl PlayerCreationUI_Loop()
 {
-  RGBTexture *pTexture; // ebx@1
+  //RGBTexture *pTexture; // ebx@1
   UINT v1; // esi@1
   unsigned int v2; // ecx@3
   LONG uMouseX; // edi@6
@@ -5859,7 +5859,7 @@
   Player *v11; // esi@38
   signed int uSpellBookPageCount; // ecx@40
   int v13; // eax@40
-  signed int uSkillIdx; // eax@45
+  //signed int uSkillIdx; // eax@45
   int v15; // eax@70
   signed int v16; // ecx@70
   //unsigned int v18; // [sp-4h] [bp-84h]@48
@@ -5871,10 +5871,10 @@
   MSG Msg; // [sp+50h] [bp-30h]@17
   POINT v25; // [sp+6Ch] [bp-14h]@6
   bool v26; // [sp+74h] [bp-Ch]@1
-  POINT v24; // [sp+78h] [bp-8h]@6
-  Player *pPlayer;
-
-  pTexture = &pTexture_PCX;
+  //POINT v24; // [sp+78h] [bp-8h]@6
+  //Player *pPlayer;
+
+  //pTexture = &pTexture_PCX;
   v1 = 0;
   v26 = 0;
   pTexture_PCX.Release();
@@ -5889,7 +5889,7 @@
   {
     if ( pAsyncMouse != (void *)v1 )
       pAsyncMouse->_46B736_consume_click_lists(1);
-    uMouseX = pMouse->GetCursorPos(&v24)->x;
+    uMouseX = pMouse->GetCursorPos(&v25)->x;
     uMouseY = pMouse->GetCursorPos(&v25)->y;
     pControlsHead = pGUIWindow_CurrentMenu->pControlsHead;
     if ( pControlsHead != (GUIButton *)v1 )
@@ -5904,7 +5904,7 @@
           if ( (signed int)pNumMessage < 40 )
           {
             pMessageQueue_50CBD0->pMessages[pNumMessage].eType = (UIMessageType)pControlsHead->field_1C;
-            pTexture = &pTexture_PCX;
+            //pTexture = &pTexture_PCX;
             pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = pControlParam;
             *(&pMessageQueue_50CBD0->uNumMessages + 3 * pMessageQueue_50CBD0->uNumMessages + 3) = 0;
             pNumMessage = pMessageQueue_50CBD0->uNumMessages + 1;
@@ -5953,13 +5953,11 @@
       }
     }
   }
-  pTexture->Release();
+  pTexture_PCX.Release();
   pGUIWindow_CurrentMenu->Release();
   pIcons_LOD->_4114F2();
-  v20[0] = 0;
-  memset(&v20[1], 0, 0x1Cu);
-  *(_WORD*)&v20[29] = 0;
-  v20[31] = 0;
+
+  memset(v20, 0, 32);
   do
   {
     v8 = 0;
@@ -5985,112 +5983,107 @@
     v20[v9] = 1;
   }
   while ( (signed int)v1 < 32 );
+  //v10 = (char *)&pParty->pPlayers[0].sResMagicBase;
+  
   item.Reset();
-  //v10 = (char *)&pParty->pPlayers[0].sResMagicBase;
-  for ( pPlayer = &pParty->pPlayers[0];  pPlayer < &pParty->pPlayers[4]; pPlayer++)
-  {
+  //for ( pPlayer = &pParty->pPlayers[0];  pPlayer < &pParty->pPlayers[4]; pPlayer++)
+  for (uint i = 0; i < 4; ++i)
+  {
+    auto player = &pParty->pPlayers[i];
     //v11 = pPlayer;
-    if (pPlayer->classType == PLAYER_CLASS_KNIGHT)
-      pPlayer->sResMagicBase = 10;
+    if (player->classType == PLAYER_CLASS_KNIGHT)
+      player->sResMagicBase = 10;
     //*((short *)v10 + 400) = 0;
-    pPlayer->pPlayerBuffs[22].uExpireTime = 0;
+    player->pPlayerBuffs[22].uExpireTime = 0;
     uSpellBookPageCount = 0;
-    for ( int i = 0; i < 9; i++)
-    {
-      if ( pPlayer->pActiveSkills[12+i] )
+    for (uint j = 0; j < 9; j++)
+    {
+      if (player->pActiveSkills[PLAYER_SKILL_FIRE + j])
         ++uSpellBookPageCount;
     }
-    pPlayer->lastOpenedSpellbookPage = uSpellBookPageCount;
+    player->lastOpenedSpellbookPage = uSpellBookPageCount;
     pItemsTable->GenerateItem(2, 40, &item);
-    pPlayer->AddItem2(-1, &item);
-    uSkillIdx = 0;
-    v24.y = 0;
-    do
-    {
-      if ( pPlayer->pActiveSkills[uSkillIdx] )
-      {
-        switch ( uSkillIdx )
-        {
-          case PLAYER_SKILL_STAFF:   pPlayer->AddItem(-1, 61); break;
-          case PLAYER_SKILL_SWORD:   pPlayer->AddItem(-1, 1); break;
-          case PLAYER_SKILL_DAGGER:  pPlayer->AddItem(-1, 15); break;
-          case PLAYER_SKILL_AXE:     pPlayer->AddItem(-1, 23); break;
-          case PLAYER_SKILL_SPEAR:   pPlayer->AddItem(-1, 31); break;
-          case PLAYER_SKILL_BOW:     pPlayer->AddItem(-1, 47); break;
-          case PLAYER_SKILL_MACE:    pPlayer->AddItem(-1, 50); break;
-          case PLAYER_SKILL_BLASTER: assert(false); break;
-          case PLAYER_SKILL_SHIELD:  pPlayer->AddItem(-1, 84); break;
-          case PLAYER_SKILL_LEATHER: pPlayer->AddItem(-1, 66); break;
-          case PLAYER_SKILL_CHAIN:   pPlayer->AddItem(-1, 71); break;
-          case PLAYER_SKILL_PLATE:   pPlayer->AddItem(-1, 76); break;
-          case PLAYER_SKILL_FIRE:
-            pPlayer->AddItem(-1, 0x191);
-            pPlayer->spellbook.pFireSpellbook.bIsSpellAvailable[0] = true;
-          break;
-          case PLAYER_SKILL_AIR:
-            pPlayer->AddItem(-1, 0x19C);
-            pPlayer->spellbook.pAirSpellbook.bIsSpellAvailable[0] = true;
-          break;
-          case PLAYER_SKILL_WATER:
-            pPlayer->AddItem(-1, 0x1A7);
-			pPlayer->spellbook.pWaterSpellbook.bIsSpellAvailable[0] = true;
+    player->AddItem2(-1, &item);
+    //uSkillIdx = 0;
+    //v24.y = 0;
+
+    player->sHealth = player->GetMaxHealth();
+    player->sMana = player->GetMaxMana();
+    for (uint j = 0; j < 37; ++j)
+    {
+      if (!player->pActiveSkills[j])
+        continue;
+
+      switch (j)
+      {
+        case PLAYER_SKILL_STAFF:   player->AddItem(-1, 61); break;
+        case PLAYER_SKILL_SWORD:   player->AddItem(-1, 1); break;
+        case PLAYER_SKILL_DAGGER:  player->AddItem(-1, 15); break;
+        case PLAYER_SKILL_AXE:     player->AddItem(-1, 23); break;
+        case PLAYER_SKILL_SPEAR:   player->AddItem(-1, 31); break;
+        case PLAYER_SKILL_BOW:     player->AddItem(-1, 47); break;
+        case PLAYER_SKILL_MACE:    player->AddItem(-1, 50); break;
+        case PLAYER_SKILL_BLASTER: assert(false); break;
+        case PLAYER_SKILL_SHIELD:  player->AddItem(-1, 84); break;
+        case PLAYER_SKILL_LEATHER: player->AddItem(-1, 66); break;
+        case PLAYER_SKILL_CHAIN:   player->AddItem(-1, 71); break;
+        case PLAYER_SKILL_PLATE:   player->AddItem(-1, 76); break;
+        case PLAYER_SKILL_FIRE:
+          player->AddItem(-1, 0x191);
+          player->spellbook.pFireSpellbook.bIsSpellAvailable[0] = true;
+        break;
+        case PLAYER_SKILL_AIR:
+          player->AddItem(-1, 0x19C);
+          player->spellbook.pAirSpellbook.bIsSpellAvailable[0] = true;
+        break;
+        case PLAYER_SKILL_WATER:
+          player->AddItem(-1, 0x1A7);
+		  player->spellbook.pWaterSpellbook.bIsSpellAvailable[0] = true;
+        break;
+        case PLAYER_SKILL_EARTH:
+          player->AddItem(-1, 0x1B2);
+		  player->spellbook.pEarthSpellbook.bIsSpellAvailable[0] = true;
+        break;
+        case PLAYER_SKILL_SPIRIT:
+          player->AddItem(-1, 0x1BD);
+		  player->spellbook.pSpiritSpellbook.bIsSpellAvailable[0] = true;
+        break;
+        case PLAYER_SKILL_MIND:
+          player->AddItem(-1, 0x1C8);
+		  player->spellbook.pMindSpellbook.bIsSpellAvailable[0] = true;
+        break;
+        case PLAYER_SKILL_BODY:
+          player->AddItem(-1, 0x1D3);
+		  player->spellbook.pBodySpellbook.bIsSpellAvailable[0] = true;
+        break;
+        case PLAYER_SKILL_LIGHT:
+        case PLAYER_SKILL_DARK:
+        case PLAYER_SKILL_DIPLOMACY:
+          assert(false);
+        break;
+        case PLAYER_SKILL_ITEM_ID:
+        case PLAYER_SKILL_REPAIR:
+        case PLAYER_SKILL_MEDITATION:
+        case PLAYER_SKILL_PERCEPTION:
+        case PLAYER_SKILL_TRAP_DISARM:
+        case PLAYER_SKILL_LEARNING:
+          player->AddItem(-1, 0xDC);
+		  player->AddItem(-1, 5 * (rand() % 3 + 40));
+        break;
+        case PLAYER_SKILL_DODGE:   player->AddItem(-1, 115); break;
+        case PLAYER_SKILL_UNARMED: player->AddItem(-1, 110); break;
+        default:
           break;
-          case PLAYER_SKILL_EARTH:
-            pPlayer->AddItem(-1, 0x1B2);
-			pPlayer->spellbook.pEarthSpellbook.bIsSpellAvailable[0] = true;
-          break;
-          case PLAYER_SKILL_SPIRIT:
-            pPlayer->AddItem(-1, 0x1BD);
-			pPlayer->spellbook.pSpiritSpellbook.bIsSpellAvailable[0] = true;
-          break;
-          case PLAYER_SKILL_MIND:
-            pPlayer->AddItem(-1, 0x1C8);
-			pPlayer->spellbook.pMindSpellbook.bIsSpellAvailable[0] = true;
-          break;
-          case PLAYER_SKILL_BODY:
-            pPlayer->AddItem(-1, 0x1D3);
-			pPlayer->spellbook.pBodySpellbook.bIsSpellAvailable[0] = true;
-          break;
-          case PLAYER_SKILL_LIGHT:
-          case PLAYER_SKILL_DARK:
-          case PLAYER_SKILL_DIPLOMACY:
-            assert(false);
-          break;
-          case PLAYER_SKILL_ITEM_ID:
-          case PLAYER_SKILL_REPAIR:
-          case PLAYER_SKILL_MEDITATION:
-          case PLAYER_SKILL_PERCEPTION:
-          case PLAYER_SKILL_TRAP_DISARM:
-          case PLAYER_SKILL_LEARNING:
-            pPlayer->AddItem(-1, 0xDC);
-			pPlayer->AddItem(-1, 5 * (rand() % 3 + 40));
-          break;
-          case PLAYER_SKILL_DODGE:
-			pPlayer->AddItem(-1, 115);
-          break;
-          case PLAYER_SKILL_UNARMED:
-            pPlayer->AddItem(-1, 110);
-          break;
-          default:
-            break;
-        }
-		for ( int i = 0; i < 138; i++)
-        {
-          if ( &pPlayer->pInventoryItems[i] )
-            pPlayer->pInventoryItems[i].uAttributes |= 1;
-         }
-        pPlayer->sHealth = pPlayer->GetMaxHealth();
-        pPlayer->sMana = pPlayer->GetMaxMana();
-        uSkillIdx = v24.y;
-      }
-      ++uSkillIdx;
-      v24.y = uSkillIdx;
-    }
-    while ( uSkillIdx < 37 );
-    //v10 += 6972;
-	//pPlayer++;
-  }
-  //while ( (signed int)v10 < (signed int)((char *)&pParty->field_871C[455] + 2) );
+      }
+
+      for (uint k = 0; k < 138; k++)
+      {
+        if (&player->pInventoryItems[k])
+          player->pInventoryItems[k].uAttributes |= 1;
+      }
+    }
+  }
+
   pAudioPlayer->StopChannels(-1, -1);
   if (pAsyncMouse)
     pAsyncMouse->Suspend();
--- a/mm7_data.cpp	Sun Feb 17 17:07:52 2013 +0400
+++ b/mm7_data.cpp	Sun Feb 17 17:18:45 2013 +0400
@@ -2,6 +2,7 @@
 
 #include "NPC.h"
 #include "Actor.h"
+#include "GUIWindow.h"
 
 
 
@@ -477,7 +478,7 @@
 char aS100110D[777]; // idb
 char aS100110DS[777]; // idb
 char aS100110D02dSS[777]; // idb
-int pCurrentScreen; // weak
+int pCurrentScreen = SCREEN_VIDEO; // 004E28F8
 char byte_4E28FC; // weak
 unsigned int uGammaPos;
 int dword_4E2910[777]; // weak
--- a/mm7_data.h	Sun Feb 17 17:07:52 2013 +0400
+++ b/mm7_data.h	Sun Feb 17 17:18:45 2013 +0400
@@ -456,7 +456,7 @@
 extern char aS100110D[]; // idb
 extern char aS100110DS[]; // idb
 extern char aS100110D02dSS[]; // idb
-extern int pCurrentScreen; // weak
+extern int pCurrentScreen; // 004E28F8
 extern char byte_4E28FC; // weak
 extern unsigned int uGammaPos;
 extern int dword_4E2910[]; // weak