changeset 661:2535151505da

Слияние
author Ritor1
date Tue, 12 Mar 2013 09:43:50 +0600
parents 94fab082f146 (current diff) 1ff57450f090 (diff)
children 8c595c7a3218
files UIHouses.cpp
diffstat 32 files changed, 1098 insertions(+), 1215 deletions(-) [+]
line wrap: on
line diff
--- a/Actor.cpp	Tue Mar 12 09:43:40 2013 +0600
+++ b/Actor.cpp	Tue Mar 12 09:43:50 2013 +0600
@@ -3883,6 +3883,7 @@
     break;
 
     case Removed:
+    case Disabled:
       return;
 
     default:
--- a/DecalBuilder.cpp	Tue Mar 12 09:43:40 2013 +0600
+++ b/DecalBuilder.cpp	Tue Mar 12 09:43:50 2013 +0600
@@ -107,7 +107,7 @@
 }
 
 //----- (0049B540) --------------------------------------------------------
-char DecalBuilder::ApplyDecals(int a2, char a3, stru154 *a4, int a5, RenderVertexSoft *a6, IndoorCameraD3D_Vec4 *a7, char a8, unsigned int uSectorID)
+char DecalBuilder::ApplyDecals(int light_level, char a3, stru154 *a4, int a5, RenderVertexSoft *a6, IndoorCameraD3D_Vec4 *a7, char a8, unsigned int uSectorID)
 {
   char *v9; // eax@3
   signed int v10; // ecx@3
@@ -148,6 +148,7 @@
 
   __debugbreak();
 
+  auto a2 = light_level;
   auto a9 = uSectorID;
 
   thisa = this;
--- a/DecalBuilder.h	Tue Mar 12 09:43:40 2013 +0600
+++ b/DecalBuilder.h	Tue Mar 12 09:43:50 2013 +0600
@@ -91,7 +91,7 @@
 
   bool AddBloodsplat(float x, float y, float z, float r, float g, float b, float radius, int a8, int a9);
   void Reset(unsigned int bPreserveBloodsplats);
-  char ApplyDecals(int a2, char a3, struct stru154 *a4, int a5, struct RenderVertexSoft *a6, struct IndoorCameraD3D_Vec4 *a7, char a8, unsigned int uSectorID);
+  char ApplyDecals(int light_level, char a3, struct stru154 *a4, int a5, struct RenderVertexSoft *a6, struct IndoorCameraD3D_Vec4 *a7, char a8, unsigned int uSectorID);
   char _49B790_build_decal_geometry(int a2, char a3, int a4, int a5, int a6, unsigned int uColorMultiplier, struct RenderVertexSoft *a8, struct stru314 *a9, signed int a10, struct RenderVertexSoft *a11, char uClipFlags);
   bool ApplyBloodsplatDecals_IndoorFace(unsigned int uFaceID);
   char ApplyDecals_OutdoorFace(ODMFace *pFace);
--- a/Events2D.h	Tue Mar 12 09:43:40 2013 +0600
+++ b/Events2D.h	Tue Mar 12 09:43:50 2013 +0600
@@ -1,39 +1,40 @@
 #pragma once
 
 /*  296 */
-enum BildingType : unsigned short
-	{
-	BildingType_WeaponShop = 0x1,
-	BildingType_ArmorShop = 0x2,
-	BildingType_MagicShop = 0x3,
-	BildingType_AlchemistShop = 0x4,
-	BildingType_FireGuild = 0x5,
-	BildingType_AirGuild = 0x6,
-	BildingType_WaterGuild = 0x7,
-	BildingType_EarthGuild = 0x8,
-	BildingType_SpiritGuild = 0x9,
-	BildingType_MindGuild = 0xA,
-	BildingType_BodyGuild = 0xB,
-	BildingType_LightGuild = 0xC,
-	BildingType_DarkGuild = 0xD,
-	BildingType_14 = 0xE,
-	BildingType_15 = 0xF,
-	BildingType_16 = 0x10,
-	BildingType_TownHall = 0x11,
-	BildingType_18 = 0x12,
-	BildingType_19 = 0x13,
-	BildingType_Throne_Room = 0x14,
-	BildingType_Tavern = 0x15,
-	BildingType_Bank = 0x16,
-	BildingType_Temple = 0x17,
-	BildingType_Unic = 0x19,
-	BildingType_1A = 0x1A,
-	BildingType_Stables = 0x1B,
-	BildingType_Boats = 0x1C,
-	BildingType_House = 0x1D,
-	BildingType_Training = 0x1E,
-	BildingType_Jail = 0x1F,
-	};
+enum BildingType: unsigned short
+{
+  BildingType_WeaponShop = 1,
+  BildingType_ArmorShop = 2,
+  BildingType_MagicShop = 3,
+  BildingType_AlchemistShop = 4,
+  BildingType_FireGuild = 5,
+  BildingType_AirGuild = 6,
+  BildingType_WaterGuild = 7,
+  BildingType_EarthGuild = 8,
+  BildingType_SpiritGuild = 9,
+  BildingType_MindGuild = 10,
+  BildingType_BodyGuild = 11,
+  BildingType_LightGuild = 12,
+  BildingType_DarkGuild = 13,
+  BildingType_14 = 14,
+  BildingType_15 = 15,
+  BildingType_16 = 16,
+  BildingType_TownHall = 17,
+  BildingType_18 = 18,
+  BildingType_19 = 19,
+  BildingType_Throne_Room = 20,
+  BildingType_Tavern = 21,
+  BildingType_Bank = 22,
+  BildingType_Temple = 23,
+  BuildingType_24 = 24,
+  BildingType_Unic = 25,
+  BildingType_1A = 26,
+  BildingType_Stables = 27,
+  BildingType_Boats = 28,
+  BildingType_House = 29,
+  BildingType_Training = 30,
+  BildingType_Jail = 31
+};
 
 /*  168 */
 #pragma pack(push, 1)
--- a/GUIWindow.h	Tue Mar 12 09:43:40 2013 +0600
+++ b/GUIWindow.h	Tue Mar 12 09:43:50 2013 +0600
@@ -240,7 +240,7 @@
   UIMSG_85 = 0x85,
   UIMSG_StartHireling1Dialogue = 0x86,
   UIMSG_StartHireling2Dialogue = 0x87,
-  UIMSG_SelectDialogueOption = 0x88,
+  UIMSG_SelectNPCDialogueOption = 0x88,
   UIMSG_8C = 0x8C,
   UIMSG_8D = 0x8D,
   UIMSG_CastSpellFromBook = 0x8E,
@@ -309,7 +309,7 @@
   UIMSG_16F = 0x16F,
   UIMSG_170 = 0x170,
   UIMSG_Game_Action = 0x194,
-  UIMSG_ClickLearnSkillDialog = 0x195,
+  UIMSG_SelectShopDialogueOption = 0x195,
   UIMSG_OpenRestUI = 0x199,
   UIMSG_19A = 0x19A,
   UIMSG_TransitionUI_Confirm = 0x19B,
@@ -402,7 +402,7 @@
 
 
 
-void OnSelectDialogueOption(DIALOGUE_TYPE newDialogueType);
+void OnSelectNPCDialogueOption(DIALOGUE_TYPE newDialogueType);
 
 
 
--- a/Game.cpp	Tue Mar 12 09:43:40 2013 +0600
+++ b/Game.cpp	Tue Mar 12 09:43:50 2013 +0600
@@ -659,9 +659,10 @@
 
 
 //----- (0044EDE4) --------------------------------------------------------
-bool Game::AlterGamma(BLVFace *pFace, unsigned int *pColor)
+bool Game::AlterGamma_BLV(BLVFace *pFace, unsigned int *pColor)
 {
-  if (pGame->uFlags2 & 2 && pFace->uAttributes & 2)
+  if (uFlags2 & GAME_FLAGS_2_SATURATE_LIGHTMAPS &&
+      pFace->uAttributes & FACE_CAN_SATURATE_COLOR)
   {
     *pColor = ReplaceHSV(*pColor, 1.0, fSaturation, -1.0);
     return true;
@@ -671,11 +672,12 @@
 }
 
 //----- (0044EE30) --------------------------------------------------------
-bool Game::_44EE30(ODMFace *a2, int a3)
+bool Game::AlterGamma_ODM(ODMFace *pFace, unsigned int *pColor)
 {
-  if (uFlags2 & 0x2 && a2->uAttributes & 0x02)
+  if (uFlags2 & GAME_FLAGS_2_SATURATE_LIGHTMAPS &&
+      pFace->uAttributes & FACE_CAN_SATURATE_COLOR)
   {
-    *(int *)a3 = ReplaceHSV(*(int *)a3, 1.0, fSaturation, -1.0);
+    *pColor = ReplaceHSV(*pColor, 1.0, fSaturation, -1.0);
     return true;
   }
   else
--- a/Game.h	Tue Mar 12 09:43:40 2013 +0600
+++ b/Game.h	Tue Mar 12 09:43:50 2013 +0600
@@ -97,8 +97,8 @@
   void OutlineSelection();
   signed int _44EC23(struct stru148 *a2, int *a3, signed int a4);
   signed int _44ED0A(struct BLVFace *a2, int *a3, signed int a4);
-  bool AlterGamma(struct BLVFace *pFace, unsigned int *pColor);
-  bool _44EE30(struct ODMFace *a2, int a3);
+  bool AlterGamma_BLV(struct BLVFace *pFace, unsigned int *pColor);
+  bool AlterGamma_ODM(struct ODMFace *pFace, unsigned int *pColor);
   bool draw_debug_outlines();
   bool _44EEA7();
   bool _44F07B();
--- a/Indoor.h	Tue Mar 12 09:43:40 2013 +0600
+++ b/Indoor.h	Tue Mar 12 09:43:50 2013 +0600
@@ -250,17 +250,17 @@
 #pragma pack(pop)
 
 
-#define FACE_TWO_SIDED        0x00000001 // portal/two-sided
-// 0x02  color is saturated against lights
-#define FACE_TEXTURE_ANIMATED 0x00000010 // like wavy water
-#define FACE_INVISIBLE        0x00002000
-#define FACE_TEXTURE_FRAME    0x00004000 // Texture ID is a frameset from TextureFrameTable, otherwise BitmapID
-#define FACE_OUTLINED         0x00010000 // outline face edges
-#define FACE_TEXTURE_FLOW     0x00040000 // The texture moves slowly. For horizontal facets only.
-#define FACE_DO_NOT_LIGHT     0x00400000
-#define FACE_CLICKABLE        0x02000000 // Event can be triggered by clicking on the facet.
-#define FACE_PRESSURE_PLATE   0x04000000 // Event can be triggered by stepping on the facet.
-#define FACE_ETHEREAL         0x20000000 // Untouchable. You can pass through it.
+#define FACE_TWO_SIDED          0x00000001 // portal/two-sided
+#define FACE_CAN_SATURATE_COLOR 0x00000002
+#define FACE_TEXTURE_ANIMATED   0x00000010 // like wavy water
+#define FACE_INVISIBLE          0x00002000
+#define FACE_TEXTURE_FRAME      0x00004000 // Texture ID is a frameset from TextureFrameTable, otherwise BitmapID
+#define FACE_OUTLINED           0x00010000 // outline face edges
+#define FACE_TEXTURE_FLOW       0x00040000 // The texture moves slowly. For horizontal facets only.
+#define FACE_DO_NOT_LIGHT       0x00400000
+#define FACE_CLICKABLE          0x02000000 // Event can be triggered by clicking on the facet.
+#define FACE_PRESSURE_PLATE     0x04000000 // Event can be triggered by stepping on the facet.
+#define FACE_ETHEREAL           0x20000000 // Untouchable. You can pass through it.
 
 /*   93 */
 #pragma pack(push, 1)
--- a/LOD.cpp	Tue Mar 12 09:43:40 2013 +0600
+++ b/LOD.cpp	Tue Mar 12 09:43:50 2013 +0600
@@ -3094,6 +3094,7 @@
   uint id = LoadTexture(pContainer, uTextureType);
   if (id == -1)
   {
+    assert(false);
     Log::Warning(L"LOD error\\no container: \"%S\"", pContainer);
     return nullptr;
   }
@@ -3120,11 +3121,12 @@
 //  if (!uNumLoadedFiles)
 //  {
 //LABEL_5:
-    if (uNumLoadedFiles >= 1000)
+    assert(uNumLoadedFiles < 1000);
+    /*if (uNumLoadedFiles >= 1000)
     {
       Log::Warning(L"Maximum texture number exceeded");
       AbortWithError();
-    }
+    }*/
     if (LoadTextureFromLOD(&pTextures[uNumLoadedFiles], pContainer, uTextureType) == -1)
     {
       v6 = 0;
--- a/LightmapBuilder.cpp	Tue Mar 12 09:43:40 2013 +0600
+++ b/LightmapBuilder.cpp	Tue Mar 12 09:43:50 2013 +0600
@@ -1075,7 +1075,7 @@
  int i;
 
   v10 = 0;
-  stru_F8AD28.uCurrentAmbientLightLevel = pOutdoor->field_CBC_terrain_triangles_shade_type;
+  stru_F8AD28.uCurrentAmbientLightLevel = pOutdoor->max_terrain_dimming_level;
   for (i = 0; i < pMobileLightsStack->uNumLightsActive; ++i)
   {
       if ( v10 >= 20 )
--- a/NPC.cpp	Tue Mar 12 09:43:40 2013 +0600
+++ b/NPC.cpp	Tue Mar 12 09:43:50 2013 +0600
@@ -456,6 +456,9 @@
 			decode_step=0;
 			do 
 				{
+                while (*test_string == '\t')  // some steps are separated by multiple \t's
+                  ++test_string;
+                
 				c = *(unsigned char*)test_string;
 				temp_str_len = 0;
 				while((c!='\t')&&(c>0))
--- a/NPC.h	Tue Mar 12 09:43:40 2013 +0600
+++ b/NPC.h	Tue Mar 12 09:43:50 2013 +0600
@@ -1,71 +1,68 @@
 #pragma once
 
-/*
-enum NPCProffession
-	{
-	Smith	1
-	Armorer	2
-	Alchemist	3
-	Scholar	4
-	Guide	5
-	Tracker	6
-	Pathfinder	7
-	Sailor	8
-	Navigator	9
-	Healer	10
-	Expert Healer	11
-	Master Healer	12
-	Teacher	13
-	Instructor	14
-	Arms Master	15
-	Weapons Master	16
-	Apprentice	17
-	Mystic	18
-	Spell Master	19
-	Trader	20
-	Merchant	21
-	Scout	22
-	Herbalist	23
-	Apothecary	24
-	Tinker	25
-	Locksmith	26
-	Fool	27
-	Chimney Sweep	28
-	Porter	29
-	Quarter Master	30
-	Factor	31
-	Banker	32
-	Cook	33
-	Chef	34
-	Horseman	35
-	Bard	36
-	Enchanter	37
-	Cartographer	38
-	Wind Master	39
-	Water Master	40
-	Gate Master	41
-	Acolyte	42
-	Piper	43
-	Explorer	44
-	Pirate	45
-	Squire	46
-	Psychic	47
-	Gypsy	48
-	Diplomat	49
-	Duper	50
-	Burglar	51
-	Fallen Wizard	52
-	Acolyte	53
-	Initiate	54
-	Prelate	55
-	Monk	56
-	Sage	57
-	Hunter	58
+enum NPCProf
+{
+  Smith	= 1,           // GM Weapon Repair;
+  Armorer = 2,         // GM Armor Repair;
+  Alchemist = 3,       // GM Potion Repair;
+  Scholar = 4,         // GM Item ID;               Learning: +5
+  Guide = 5,           // Travel by foot: -1 day;
+  Tracker = 6,         // Travel by foot: -2 days;
+  Pathfinder = 7,      // Travel by foot: -3 days;
+  Sailor = 8,          // Travel by sea: -2 days;
+  Navigator = 9,       // Travel by sea: -3 days;
+  Healer = 10,
+  ExpertHealer = 11,
+  MasterHealer = 12,
+  Teacher = 13,        // Learning: +10;
+  Instructor = 14,     // Learning: +15;
+  Armsmaster = 15,     // Armsmaster: +2;
+  Weaponsmaster = 16,  // Armsmaster: +3;
+  Apprentice = 17,     // Fire: +2;         Air: +2;    Water: +2;   Earth: +2;
+  Mystic = 18,         // Fire: +3;         Air: +3;    Water: +3;   Earth: +3;
+  Spellmaster = 19,    // Fire: +4;         Air: +4;    Water: +4;   Earth: +4;
+  Trader = 20,         // Merchant: +4;
+  Merchant = 21,       // Merchant: +6;
+  Scout = 22,          // Perception: +6;
+  Herbalist = 23,      // Alchemy: +4;
+  Apothecary = 24,     // Alchemy: +8;
+  Tinker = 25,         // Traps: +4;
+  Locksmith = 26,      // Traps: +6;
+  Fool = 27,           // Luck: +5;
+  ChimneySweep = 28,   // Luck: +20;
+  Porter = 29,         // Food for rest: -1;
+  QuarterMaster = 30,  // Food for rest: -2;
+  Factor = 31,         // Gold finds: +10%;
+  Banker = 32,         // Gold finds: +20%;
+  Cook = 33,
+  Chef = 34,
+  Horseman = 35,       // Travel by foot: -2 days;
+  Bard = 36,
+  Enchanter = 37,      // Resist All: +20;
+  Cartographer = 38,   // Wizard Eye level 2;
+  WindMaster = 39,
+  WaterMaster = 40,
+  GateMaster = 41,
+  Acolyte = 42,
+  Piper = 43,
+  Explorer = 44,       // Travel by foot -1 day;     Travel by sea: -1 day;
+  Pirate = 45,         // Travel by sea: -2 days;    Gold finds: +10%;      Reputation: +5;
+  Squire = 46,
+  Psychic = 47,        // Perception: +5;            Luck: +10;
+  Gypsy = 48,          // Food for rest: -1;         Merchant: +3;          Reputation: +5;
+  Diplomat = 49,
+  Duper = 50,          // Merchant: +8;              Reputation: +5;
+  Burglar = 51,        // Traps: +8;                 Stealing: +8;          Reputation: +5;
+  FallenWizard = 52,   // Reputation: +5;
+  Acolyte2 = 53,       // Spirit: +2;                Mind: +2;              Body: +2;
+  Initiate = 54,       // Spirit: +3;                Mind: +3;              Body: +3;
+  Prelate = 55,        // Spirit: +4;                Mind: +4;              Body: +4;
+  Monk = 56,           // Unarmed: +2;               Dodge: +2;
+  Sage = 57,           // Monster ID: +6
+  Hunter = 58          // Monster ID: +6
+};
 
 
-	};
-	*/
-
 
 struct NPCTopic
 {
@@ -88,100 +85,7 @@
   int fame;  //c
   int rep;  //10
   unsigned int Location2D;  //14
-  unsigned int uProfession; //18      CheckHiredNPCSpeciality(uProfession)
-                                  /*   
-
-      v0 = uDefaultTravelTime_ByFoot;
-  if ( CheckHiredNPCSpeciality(5u) )
-    --v0;
-  if ( CheckHiredNPCSpeciality(6u) )
-    v0 -= 2;
-  if ( CheckHiredNPCSpeciality(7u) )
-    v0 -= 3;
-  if ( CheckHiredNPCSpeciality(0x2Cu) )
-    --v0;
-
-
-      case PLAYER_SKILL_MONSTER_ID:
-      if ( CheckHiredNPCSpeciality(58) )
-        skill += 6;
-      if ( CheckHiredNPCSpeciality(57) )
-        skill += 6;
-
-    case PLAYER_SKILL_ARMSMASTER:
-        if ( CheckHiredNPCSpeciality(15) )
-          skill += 2;
-        if ( CheckHiredNPCSpeciality(16) )
-          skill += 3;
-
-    case PLAYER_SKILL_STEALING:
-      if (CheckHiredNPCSpeciality(51))
-        skill +=
-
-    case PLAYER_SKILL_ALCHEMY:
-        if ( CheckHiredNPCSpeciality(23) )
-          skill += 4;
-        if ( CheckHiredNPCSpeciality(24) )
-	  skill += 8
-
-    case PLAYER_SKILL_LEARNING:
-        if ( CheckHiredNPCSpeciality(13) )
-          skill += 10;
-        if ( CheckHiredNPCSpeciality(14) )
-          skill += 15;
-        if ( CheckHiredNPCSpeciality(4) )
-          skill += 5;
-
-    case PLAYER_SKILL_UNARMED:	
-      if (CheckHiredNPCSpeciality(56) )
-       skill +
-
-    case PLAYER_SKILL_DODGE:
-      if ( CheckHiredNPCSpeciality(56) )
-       skill+
-
-    case PLAYER_SKILL_MERCHANT:
-        if ( CheckHiredNPCSpeciality(20) )
-          skill += 4;
-        if ( CheckHiredNPCSpeciality(21) )
-          skill += 6;
-        if ( CheckHiredNPCSpeciality(48) )
-          skill += 3;
-        if ( CheckHiredNPCSpeciality(50) )
-          skill += 8;
-
-    case PLAYER_SKILL_PERCEPTION:
-      if ( CheckHiredNPCSpeciality(22) )
-        v2 = 6;
-      if ( CheckHiredNPCSpeciality(47) )
-        v2 += 5;
-
-    case PLAYER_SKILL_TRAP_DISARM:
-      if ( CheckHiredNPCSpeciality(25) )
-        v2 = 4;
-      if ( CheckHiredNPCSpeciality(26) )
-        v2 += 6;
-      if ( CheckHiredNPCSpeciality(51) )
-        v2 += 8;
-
-      FIRE WATER EARTH AIR
-          if ( CheckHiredNPCSpeciality(17) )
-            v2 = 2;
-          if ( CheckHiredNPCSpeciality(18) )
-            v2 += 3;
-          if ( CheckHiredNPCSpeciality(19) )
-            v2 += 4;
-          if ( classType == PLAYER_CLASS_WARLOCK && PartyHasDragon() )
-            v2 += 3;
-
-      SPIRIT MIND BODY
-          if ( CheckHiredNPCSpeciality(53) )
-            v2 = 2;
-          if ( CheckHiredNPCSpeciality(54) )
-            v2 += 3;
-          if ( CheckHiredNPCSpeciality(55) )
-            v2 += 4;
-  */
+  unsigned int uProfession; //18
   int greet;  //1c
   int joins;  //20
   int field_24;
--- a/Outdoor.cpp	Tue Mar 12 09:43:40 2013 +0600
+++ b/Outdoor.cpp	Tue Mar 12 09:43:50 2013 +0600
@@ -459,32 +459,32 @@
   unsigned int result; // eax@1
   OutdoorLocation *v2; // esi@1
   unsigned int v3; // edi@3
-  int v4; // ebx@3
+  //int v4; // ebx@3
   int v5; // eax@3
-  int v6; // eax@3
-  int v7; // ecx@3
+  //int v6; // eax@3
+  //int v7; // ecx@3
   double v8; // st7@4
 
   result = pParty->uCurrentHour;
   v2 = this;
-  if ( pParty->uCurrentHour >= 5 && pParty->uCurrentHour < 0x15 )
+  if ( pParty->uCurrentHour >= 5 && pParty->uCurrentHour < 21 )
   {
     v3 = pParty->uCurrentMinute + 60 * (pParty->uCurrentHour - 5);
-    v4 = (signed int)(v3 * stru_5C6E00->uIntegerPi) / 960;
+    //v4 = (signed int)(v3 * stru_5C6E00->uIntegerPi) / 960;
     v5 = stru_5C6E00->Cos((signed int)(v3 * stru_5C6E00->uIntegerPi) / 960);
-    v2->field_D1C = 0;
-    v2->field_D18 = v5;
-    v6 = stru_5C6E00->Sin(v4);
-    v7 = v2->field_D18;
-    v2->field_D20 = v6;
-    v2->vSunlight.x = -v7;
-    v2->vSunlight.y = -v2->field_D1C;
-    v2->vSunlight.z = -v6;
+    v2->inv_sunlight_y = 0;
+    v2->inv_sunlight_x = v5;
+    //v6 = stru_5C6E00->Sin(v4);
+    //v7 = v2->field_D18;
+    v2->inv_sunlight_z = stru_5C6E00->Sin((signed int)(v3 * stru_5C6E00->uIntegerPi) / 960);
+    v2->vSunlight.x = -v2->inv_sunlight_x;
+    v2->vSunlight.y = -v2->inv_sunlight_y;
+    v2->vSunlight.z = -v2->inv_sunlight_z;
     if ( (signed int)v3 >= 480 )
       v8 = (double)(signed int)(960 - v3);
     else
       v8 = (double)(signed int)v3;
-    v2->field_CBC_terrain_triangles_shade_type = (signed __int64)(20.0 - v8 * 0.002083333333333333 * 20.0);
+    v2->max_terrain_dimming_level = (signed __int64)(20.0 - v8 / 480.0 * 20.0);
     result = pParty->uCurrentMinute;
     v2->uLastSunlightUpdateMinute = pParty->uCurrentMinute;
   }
@@ -2417,40 +2417,40 @@
  else
    v3 = v3 + this->pTileTypes[3].uTileID - 198;
 
- static int f = 0;
- if (f)
-   pParty->uCurrentMonth = 2;
-
-  switch (pParty->uCurrentMonth)
-  {
-    case 11: case 0: case 1: // winter
-      if (v3 >= 90) // Tileset_Grass begins at TileID = 90
-      {
-        if (v3 <= 95) // some grastyl entries
-          v3 = 348;
-        else if (v3 <= 113)  // rest of grastyl & all grdrt*
-          v3 = 348 + (v3 - 96);
-      }
+  #pragma region "New: seasons change"
+  extern bool change_seasons;
+  if (change_seasons)
+    switch (pParty->uCurrentMonth)
+    {
+      case 11: case 0: case 1: // winter
+        if (v3 >= 90) // Tileset_Grass begins at TileID = 90
+        {
+          if (v3 <= 95) // some grastyl entries
+            v3 = 348;
+          else if (v3 <= 113)  // rest of grastyl & all grdrt*
+            v3 = 348 + (v3 - 96);
+        }
       /*switch (v3)
       {
         case 102: v3 = 354; break;  // grdrtNE -> SNdrtne
         case 104: v3 = 356; break;  // grdrtNW -> SNdrtnw
         case 108: v3 = 360; break;  // grdrtN  -> SNdrtn
       }*/
-    break;
+      break;
+
+      case 2: case 3: case 4: // spring
+      case 8: case 9: case 10: // autumn
+        if (v3 >= 90 && v3 <= 113) // just convert all Tileset_Grass to dirt
+          v3 = 1;
+      break;
 
-    case 2: case 3: case 4: // spring
-    case 8: case 9: case 10: // autumn
-      if (v3 >= 90 && v3 <= 113) // just convert all Tileset_Grass to dirt
-        v3 = 1;
-    break;
+      case 5: case 6: case 7: // summer
+        //all tiles are green grass by default
+      break;
 
-    case 5: case 6: case 7: // summer
-      //all tiles are green grass by default
-    break;
-
-    default: assert(pParty->uCurrentMonth >= 0 && pParty->uCurrentMonth < 12);
-  }
+      default: assert(pParty->uCurrentMonth >= 0 && pParty->uCurrentMonth < 12);
+    }
+  #pragma endregion
 
  return pTileTable->pTiles[v3].uBitmapID;
 }
--- a/Outdoor.h	Tue Mar 12 09:43:40 2013 +0600
+++ b/Outdoor.h	Tue Mar 12 09:43:50 2013 +0600
@@ -209,7 +209,7 @@
   char array_528[968];
   char array_8F0[968];
   int field_CB8;
-  int field_CBC_terrain_triangles_shade_type;
+  int max_terrain_dimming_level;
   int field_CC0;
   unsigned int pSpriteIDs_LUN[8];
   unsigned int uSpriteID_LUNFULL;
@@ -226,9 +226,9 @@
   int field_D0C;
   int field_D10;
   int field_D14;
-  int field_D18;
-  int field_D1C;
-  int field_D20;
+  int inv_sunlight_x;
+  int inv_sunlight_y;
+  int inv_sunlight_z;
   int field_D24;
   int field_D28;
   int field_D2C;
--- a/Outdoor_stuff.h	Tue Mar 12 09:43:40 2013 +0600
+++ b/Outdoor_stuff.h	Tue Mar 12 09:43:50 2013 +0600
@@ -41,12 +41,12 @@
   __int16 field_50;
   __int16 field_52;
   ODMFace *pODMFace;
-  char field_58;
+  char dimming_level;
   char field_59;
   char field_5A;
   char field_5B;
-  char field_5C;
-  char field_5D;
+  char terrain_grid_z;
+  char terrain_grid_x;
   unsigned __int8 uBModelID;
   unsigned __int8 uBModelFaceID;
   struct Edge *pEdgeList1[20];
--- a/Player.cpp	Tue Mar 12 09:43:40 2013 +0600
+++ b/Player.cpp	Tue Mar 12 09:43:50 2013 +0600
@@ -1965,6 +1965,9 @@
   signed int v6; // ebp@7
   char *v7; // esi@7
   signed int uSkillMultiplier; // [sp-4h] [bp-14h]@2
+  
+  if (CheckHiredNPCSpeciality(Scholar))
+    return true;
 
   v2 = pPlayers[uActiveCharacter]->GetActualSkillLevel(PLAYER_SKILL_ITEM_ID);
   v3 = v2;
@@ -1980,11 +1983,7 @@
       v5 = uSkillMult * (v3 & 0x3F);
       v6 = 0;
       v7 = (char *)&pItemsTable->pItems[pItem->uItemID].pIconName;
-      if ( CheckHiredNPCSpeciality(4) )
-      {
-        v6 = 1;
-        return v6;
-      }
+
       if ( (signed int)SkillToMastery(v3) >= 4 )
         v6 = 1;
       if ( v5 >= (unsigned __int8)v7[46] )
@@ -1997,11 +1996,7 @@
   v5 = uSkillMult * (v3 & 0x3F);
   v6 = 0;
   v7 = (char *)&pItemsTable->pItems[pItem->uItemID].pIconName;
-  if ( CheckHiredNPCSpeciality(4) )
-  {
-    v6 = 1;
-    return v6;
-  }
+
   if ( (signed int)SkillToMastery(v3) >= 4 )
     v6 = 1;
   if ( v5 >= (unsigned __int8)v7[46] )
@@ -2020,6 +2015,13 @@
   char v8; // al@10
   signed int v10; // [sp-4h] [bp-14h]@2
 
+  
+  auto v7 = &pItemsTable->pItems[a2->uItemID];
+  if (CheckHiredNPCSpeciality(Smith) && v7->uEquipType <= 2 ||
+      CheckHiredNPCSpeciality(Armorer) && v7->uEquipType >= 3 && v7->uEquipType <= 9 ||
+      CheckHiredNPCSpeciality(Alchemist) && v7->uEquipType >= 9 )
+    return true;
+
   LOBYTE(v2) = GetActualSkillLevel(PLAYER_SKILL_REPAIR);
   v3 = v2;
   if ( HIBYTE(v2) & 1 )
@@ -2039,11 +2041,6 @@
 LABEL_7:
   v5 = v4 * (v3 & 0x3F);
   v6 = 0;
-  auto v7 = &pItemsTable->pItems[a2->uItemID];
-  if (CheckHiredNPCSpeciality(1) && v7->uEquipType <= 2 ||
-      CheckHiredNPCSpeciality(2) && v7->uEquipType >= 3 && v7->uEquipType <= 9 ||
-      CheckHiredNPCSpeciality(3) && v7->uEquipType >= 9 )
-    return true;
   if ( (signed int)SkillToMastery(v3) >= 4 )
     return true;
   if ( v5 >= *((char *)(v7 + 1) + 2) )
@@ -2629,11 +2626,11 @@
 
   v8 = 0;
   v1 = this;
-  if ( CheckHiredNPCSpeciality(0x1Bu) )
+  if ( CheckHiredNPCSpeciality(Fool) )
     v8 = 5;
-  if ( CheckHiredNPCSpeciality(0x1Cu) )
+  if ( CheckHiredNPCSpeciality(ChimneySweep) )
     v8 += 20;
-  if ( CheckHiredNPCSpeciality(0x2Fu) )
+  if ( CheckHiredNPCSpeciality(Psychic) )
     v8 += 10;
   v2 = v1->sAgeModifier + GetBaseAge();
   v3 = 0;
@@ -4499,7 +4496,7 @@
   v10 = 0;
   v9 = 0;
   v4 = GetRace();
-  if ( CheckHiredNPCSpeciality(0x25u) )
+  if ( CheckHiredNPCSpeciality(Enchanter) )
     v10 = 20;
   if ( (a2 == CHARACTER_ATTRIBUTE_RESIST_FIRE
      || a2 == CHARACTER_ATTRIBUTE_RESIST_AIR
@@ -5653,9 +5650,9 @@
   {
     case PLAYER_SKILL_MONSTER_ID:
     {
-      if ( CheckHiredNPCSpeciality(58) )
+      if ( CheckHiredNPCSpeciality(Hunter) )
         v2 = 6;
-      if ( CheckHiredNPCSpeciality(57) )
+      if ( CheckHiredNPCSpeciality(Sage) )
         v2 += 6;
       v8 = (CHARACTER_ATTRIBUTE_TYPE)20;
       v2 += GetItemsBonus(v8, 0);
@@ -5664,9 +5661,9 @@
 
     case PLAYER_SKILL_ARMSMASTER:
     {
-        if ( CheckHiredNPCSpeciality(15) )
+        if ( CheckHiredNPCSpeciality(Armsmaster) )
           v2 = 2;
-        if ( CheckHiredNPCSpeciality(16) )
+        if ( CheckHiredNPCSpeciality(Weaponsmaster) )
           v2 += 3;
         v8 = (CHARACTER_ATTRIBUTE_TYPE)21;
       v2 += GetItemsBonus(v8, 0);
@@ -5675,7 +5672,7 @@
 
     case PLAYER_SKILL_STEALING:
     {
-      if (CheckHiredNPCSpeciality(51))
+      if (CheckHiredNPCSpeciality(Burglar))
           v2 = 8;
       v8 = (CHARACTER_ATTRIBUTE_TYPE)17;
       v2 += GetItemsBonus(v8, 0);
@@ -5685,9 +5682,9 @@
 
     case PLAYER_SKILL_ALCHEMY:
     {
-        if ( CheckHiredNPCSpeciality(23) )
+        if ( CheckHiredNPCSpeciality(Herbalist) )
           v2 = 4;
-        if ( CheckHiredNPCSpeciality(24) )
+        if ( CheckHiredNPCSpeciality(Apothecary) )
           v2 += 8;
         v8 = (CHARACTER_ATTRIBUTE_TYPE)16;
       v2 += GetItemsBonus(v8, 0);
@@ -5696,11 +5693,11 @@
 
     case PLAYER_SKILL_LEARNING:
     {
-        if ( CheckHiredNPCSpeciality(13) )
+        if ( CheckHiredNPCSpeciality(Teacher) )
           v2 = 10;
-        if ( CheckHiredNPCSpeciality(14) )
+        if ( CheckHiredNPCSpeciality(Instructor) )
           v2 += 15;
-        if ( CheckHiredNPCSpeciality(4) )
+        if ( CheckHiredNPCSpeciality(Scholar) )
           v2 += 5;
         v8 = (CHARACTER_ATTRIBUTE_TYPE)46;
       v2 += GetItemsBonus(v8, 0);
@@ -5709,7 +5706,7 @@
 
     case PLAYER_SKILL_UNARMED:
     {
-      if (CheckHiredNPCSpeciality(56) )
+      if (CheckHiredNPCSpeciality(Monk) )
         v2 = 2;
       v8 = (CHARACTER_ATTRIBUTE_TYPE)23;
       v2 += GetItemsBonus(v8, 0);
@@ -5718,7 +5715,7 @@
 
     case PLAYER_SKILL_DODGE:
     {
-      if ( CheckHiredNPCSpeciality(56) )
+      if ( CheckHiredNPCSpeciality(Monk) )
         v2 = 2;
       v8 = (CHARACTER_ATTRIBUTE_TYPE)22;
       v2 += GetItemsBonus(v8, 0);
@@ -5735,11 +5732,11 @@
     break;
 
     case PLAYER_SKILL_EARTH:
-      if ( CheckHiredNPCSpeciality(17) )
+      if ( CheckHiredNPCSpeciality(Apprentice) )
             v2 = 2;
-          if ( CheckHiredNPCSpeciality(18) )
+          if ( CheckHiredNPCSpeciality(Mystic) )
             v2 += 3;
-          if ( CheckHiredNPCSpeciality(19) )
+          if ( CheckHiredNPCSpeciality(Spellmaster) )
             v2 += 4;
           if ( classType == PLAYER_CLASS_WARLOCK && PartyHasDragon() )
             v2 += 3;
@@ -5747,11 +5744,11 @@
       v2 += GetItemsBonus(v8, 0);
     break;
     case PLAYER_SKILL_FIRE:
-      if ( CheckHiredNPCSpeciality(17) )
+      if ( CheckHiredNPCSpeciality(Apprentice) )
             v2 = 2;
-          if ( CheckHiredNPCSpeciality(18) )
+          if ( CheckHiredNPCSpeciality(Mystic) )
             v2 += 3;
-          if ( CheckHiredNPCSpeciality(19) )
+          if ( CheckHiredNPCSpeciality(Spellmaster) )
             v2 += 4;
           if ( classType == PLAYER_CLASS_WARLOCK && PartyHasDragon() )
             v2 += 3;
@@ -5759,11 +5756,11 @@
       v2 += GetItemsBonus(v8, 0);
     break;
     case PLAYER_SKILL_AIR:
-      if ( CheckHiredNPCSpeciality(17) )
+      if ( CheckHiredNPCSpeciality(Apprentice) )
             v2 = 2;
-          if ( CheckHiredNPCSpeciality(18) )
+          if ( CheckHiredNPCSpeciality(Mystic) )
             v2 += 3;
-          if ( CheckHiredNPCSpeciality(19) )
+          if ( CheckHiredNPCSpeciality(Spellmaster) )
             v2 += 4;
           if ( classType == PLAYER_CLASS_WARLOCK && PartyHasDragon() )
             v2 += 3;
@@ -5771,11 +5768,11 @@
       v2 += GetItemsBonus(v8, 0);
     break;
     case PLAYER_SKILL_WATER:
-      if ( CheckHiredNPCSpeciality(17) )
+      if ( CheckHiredNPCSpeciality(Apprentice) )
             v2 = 2;
-          if ( CheckHiredNPCSpeciality(18) )
+          if ( CheckHiredNPCSpeciality(Mystic) )
             v2 += 3;
-          if ( CheckHiredNPCSpeciality(19) )
+          if ( CheckHiredNPCSpeciality(Spellmaster) )
             v2 += 4;
           if ( classType == PLAYER_CLASS_WARLOCK && PartyHasDragon() )
             v2 += 3;
@@ -5783,31 +5780,31 @@
       v2 += GetItemsBonus(v8, 0);
     break;
     case PLAYER_SKILL_SPIRIT:
-          if ( CheckHiredNPCSpeciality(53) )
+          if ( CheckHiredNPCSpeciality(Acolyte2) )
             v2 = 2;
-          if ( CheckHiredNPCSpeciality(54) )
+          if ( CheckHiredNPCSpeciality(Initiate) )
             v2 += 3;
-          if ( CheckHiredNPCSpeciality(55) )
+          if ( CheckHiredNPCSpeciality(Prelate) )
             v2 += 4;
       v8 = (CHARACTER_ATTRIBUTE_TYPE)38;
       v2 += GetItemsBonus(v8, 0);
     break;
     case PLAYER_SKILL_MIND:
-          if ( CheckHiredNPCSpeciality(53) )
+          if ( CheckHiredNPCSpeciality(Acolyte2) )
             v2 = 2;
-          if ( CheckHiredNPCSpeciality(54) )
+          if ( CheckHiredNPCSpeciality(Initiate) )
             v2 += 3;
-          if ( CheckHiredNPCSpeciality(55) )
+          if ( CheckHiredNPCSpeciality(Prelate) )
             v2 += 4;
       v8 = (CHARACTER_ATTRIBUTE_TYPE)39;
       v2 += GetItemsBonus(v8, 0);
     break;
     case PLAYER_SKILL_BODY:
-          if ( CheckHiredNPCSpeciality(53) )
+          if ( CheckHiredNPCSpeciality(Acolyte2) )
             v2 = 2;
-          if ( CheckHiredNPCSpeciality(54) )
+          if ( CheckHiredNPCSpeciality(Initiate) )
             v2 += 3;
-          if ( CheckHiredNPCSpeciality(55) )
+          if ( CheckHiredNPCSpeciality(Prelate) )
             v2 += 4;
       v8 = (CHARACTER_ATTRIBUTE_TYPE)40;
       v2 += GetItemsBonus(v8, 0);
@@ -5825,22 +5822,22 @@
 
     case PLAYER_SKILL_MERCHANT:
     {
-        if ( CheckHiredNPCSpeciality(20) )
+        if ( CheckHiredNPCSpeciality(Trader) )
           v2 = 4;
-        if ( CheckHiredNPCSpeciality(21) )
+        if ( CheckHiredNPCSpeciality(Merchant) )
           v2 += 6;
-        if ( CheckHiredNPCSpeciality(48) )
+        if ( CheckHiredNPCSpeciality(Gypsy) )
           v2 += 3;
-        if ( CheckHiredNPCSpeciality(50) )
+        if ( CheckHiredNPCSpeciality(Duper) )
           v2 += 8;
     }
     break;
 
     case PLAYER_SKILL_PERCEPTION:
     {
-      if ( CheckHiredNPCSpeciality(22) )
+      if ( CheckHiredNPCSpeciality(Scout) )
         v2 = 6;
-      if ( CheckHiredNPCSpeciality(47) )
+      if ( CheckHiredNPCSpeciality(Psychic) )
         v2 += 5;
     }
     break;
@@ -5855,11 +5852,11 @@
     break;
     case PLAYER_SKILL_TRAP_DISARM:
     {
-      if ( CheckHiredNPCSpeciality(25) )
+      if ( CheckHiredNPCSpeciality(Tinker) )
         v2 = 4;
-      if ( CheckHiredNPCSpeciality(26) )
+      if ( CheckHiredNPCSpeciality(Locksmith) )
         v2 += 6;
-      if ( CheckHiredNPCSpeciality(51) )
+      if ( CheckHiredNPCSpeciality(Burglar) )
         v2 += 8;
       v8 = (CHARACTER_ATTRIBUTE_TYPE)18;
       v2 += GetItemsBonus(v8, 0);
--- a/Player.h	Tue Mar 12 09:43:40 2013 +0600
+++ b/Player.h	Tue Mar 12 09:43:50 2013 +0600
@@ -85,8 +85,8 @@
   SPEECH_68 = 68,
   SPEECH_69 = 69,
   SPEECH_70 = 70,
-  SPEECH_71 = 71,
-  SPEECH_72 = 72,
+  SPEECH_CarriageReady = 71, // travelling by carriage
+  SPEECH_SetSail = 72,       // travelling by sea
   SPEECH_73 = 73,
   SPEECH_74 = 74,
   SPEECH_75 = 75,
--- a/Render.cpp	Tue Mar 12 09:43:40 2013 +0600
+++ b/Render.cpp	Tue Mar 12 09:43:50 2013 +0600
@@ -338,13 +338,13 @@
               v14 = *(int *)&v4->flags;
               if ( v14 & 0x10 && v4->field_59 != 5 )
               {
-                dword_80AA20 = (v4->field_5C - 64) << 25;
+                dword_80AA20 = (v4->terrain_grid_z - 64) << 25;
                 dword_80AA1C = dword_80AA20 + 0x1FF0000;
-                dword_80AA14 = (v4->field_5D << 25) + 0x7FFF0000;
+                dword_80AA14 = (v4->terrain_grid_x << 25) + 0x7FFF0000;
                 dword_80AA18 = dword_80AA14 - 0x1FF0000;
                 byte_80AA10 = ((unsigned int)pOutdoor->ActuallyGetSomeOtherTileInfo(
-                                               v4->field_5C,
-                                               v4->field_5D - 1) >> 9) & 1;
+                                               v4->terrain_grid_z,
+                                               v4->terrain_grid_x - 1) >> 9) & 1;
                 if ( *(int *)&v4->flags & 2 || (v15 = *(int *)&v4->flags, BYTE1(v15) & 1) )
                 {
                   if ( *(int *)&v4->flags & 2 )
@@ -372,15 +372,15 @@
                         sr_sub_48408A_prolly_odm_water_no_waves(v3);
                       else
                         sr_sub_485407_prolly_odm_water_wavy(v3);
-                      v18 = v4->field_5C - 64;
+                      v18 = v4->terrain_grid_z - 64;
                       v4->pTexture = v16;
                       dword_80AA20 = v18 << 25;
                       dword_80AA1C = (v18 << 25) + 0x1FF0000;
-                      dword_80AA14 = (v4->field_5D << 25) + 0x7FFF0000;
+                      dword_80AA14 = (v4->terrain_grid_x << 25) + 0x7FFF0000;
                       dword_80AA18 = dword_80AA14 - 0x1FF0000;
                       byte_80AA10 = ((unsigned int)pOutdoor->ActuallyGetSomeOtherTileInfo(
-                                                     v4->field_5C,
-                                                     v4->field_5D - 1) >> 9) & 1;
+                                                     v4->terrain_grid_z,
+                                                     v4->terrain_grid_x - 1) >> 9) & 1;
                       sr_sub_484442(v3);
                       v3->field_E = LOWORD(unnamed_6BE060[1]);
                       if ( v4->prolly_tail == v3 )
@@ -427,13 +427,13 @@
                   {
                     if ( v19 == 1 )
                     {
-                      dword_80AA20 = (v4->field_5C - 64) << 25;
+                      dword_80AA20 = (v4->terrain_grid_z - 64) << 25;
                       dword_80AA1C = dword_80AA20 + 33488896;
-                      dword_80AA14 = (v4->field_5D << 25) + 0x7FFF0000;
+                      dword_80AA14 = (v4->terrain_grid_x << 25) + 0x7FFF0000;
                       dword_80AA18 = dword_80AA14 - 33488896;
                       byte_80AA10 = ((unsigned int)pOutdoor->ActuallyGetSomeOtherTileInfo(
-                                                     v4->field_5C,
-                                                     v4->field_5D - 1) >> 9) & 1;
+                                                     v4->terrain_grid_z,
+                                                     v4->terrain_grid_x - 1) >> 9) & 1;
                       while ( 1 )
                       {
                         if ( !sr_sub_4847EB(v3) )
@@ -606,9 +606,9 @@
         v2 = (stru148 *)&pBitmaps_LOD->pTextures[pOutdoor->uMainTile_BitmapID],
         (array_77EC08[1999].pTexture = (Texture *)(pOutdoor->uMainTile_BitmapID != -1 ? (int)v2 : 0)) == 0) )
     return (signed __int16)v2;
-  array_77EC08[1999].field_58 = 23 - (-20 * pOutdoor->vSunlight.z >> 16);
-  if ( array_77EC08[1999].field_58 > 20 )
-    array_77EC08[1999].field_58 = 20;
+  array_77EC08[1999].dimming_level = 23 - (-20 * pOutdoor->vSunlight.z >> 16);
+  if ( array_77EC08[1999].dimming_level > 20 )
+    array_77EC08[1999].dimming_level = 20;
   v10 = stru_5C6E00->Sin(pIndoorCamera->sRotationX);
   array_77EC08[1999].v_18.y = 0;
   array_77EC08[1999].v_18.x = v10;
@@ -625,7 +625,7 @@
   array_77EC08[1999].pTexture = (Texture *)(pOutdoor->uSky_TextureID != -1 ? (int)v2 : 0);
   if ( !(pOutdoor->uSky_TextureID != -1 ? (int)v2 : 0) )
     return (signed __int16)v2;
-  array_77EC08[1999].field_58 = 0;
+  array_77EC08[1999].dimming_level = 0;
   v11 = stru_5C6E00->Sin(pIndoorCamera->sRotationX + 16);
   array_77EC08[1999].v_18.y = 0;
   array_77EC08[1999].v_18.x = -v11;
@@ -1822,7 +1822,17 @@
       v8->pODMFace = nullptr;
       v8->uNumVertices = 4;
       v8->field_59 = 5;
-      v8->field_58 = 0;
+
+
+      uint norm_idx = pTerrainNormalIndices[2 * (x + 128 * z) + 1];
+      assert(norm_idx < uNumTerrainNormals);
+
+      auto norm = pTerrainNormals + norm_idx;
+      float _f = (norm->x * (float)pOutdoor->vSunlight.x / 65536.0 -
+                  norm->y * (float)pOutdoor->vSunlight.y / 65536.0 -
+                  norm->z * (float)pOutdoor->vSunlight.z / 65536.0);
+      v8->dimming_level = 20.0 - floorf(20.0 * _f + 0.5f);
+
       ++pOutdoorCamera->numStru148s;
       ++pOutdoorCamera->field_44;
       assert(pOutdoorCamera->numStru148s < 20000);
@@ -2000,7 +2010,7 @@
   v4 = 0;
   v88 = 0;
   v84 = v3 - 1;
-  v90 = (float)pOutdoor->vSunlight.x / 65536,0;
+  v90 = (float)pOutdoor->vSunlight.x / 65536.0;
   v91 = (float)pOutdoor->vSunlight.y / 65536.0;
   v92 = (float)pOutdoor->vSunlight.z / 65536.0;
   if ( v3 - 1 > 0 )
@@ -2067,22 +2077,22 @@
           v16->field_32 = 0;
           v20 = v93;
           v16->field_59 = 1;
-          v16->field_5D = (char)v19;
+          v16->terrain_grid_x = (char)v19;
           v16->field_34 = *(_WORD *)(v20 + 2);
           v21 = v89;
-          v16->field_5C = v89;
+          v16->terrain_grid_z = v89;
           v22 = pTerrainNormalIndices[2 * (v19 + 128 * v21) + 1];
           if ( v22 < 0 || v22 > uNumTerrainNormals - 1 )
             v23 = 0;
           else
             v23 = &pTerrainNormals[v22];
-          v24 = v92 * v23->y;
+          v24 = v92 * v23->z;
           //v99 = v23;
-          thisf = 20.0 - (-v24 - v91 * v23->z - v90 * v23->x) * 20.0;
+          thisf = 20.0 - (-v24 - v91 * v23->y - v90 * v23->x) * 20.0;
           //v25 = thisf + 6.7553994e15;
           //v27 = pOutdoorCamera->numStru148s > 1999;
           //v26 = pOutdoorCamera->numStru148s - 1999 < 0;
-          v16->field_58 = floorf(thisf + 0.5f);
+          v16->dimming_level = floorf(thisf + 0.5f);
           if ( pOutdoorCamera->numStru148s >= 1999 )
             return;
           ++pOutdoorCamera->numStru148s;
@@ -2142,7 +2152,7 @@
               v33 = v108 != 0 ? 5 : 0;
             static_sub_0048034E_stru_154._49B0C9(v23, v95);
             if ( pDecalBuilder->uNumDecals > 0 )
-              pDecalBuilder->ApplyDecals(31 - v16->field_58, 4, &static_sub_0048034E_stru_154, a5, array_50AC10, 0, *(float *)&v33, -1);
+              pDecalBuilder->ApplyDecals(31 - v16->dimming_level, 4, &static_sub_0048034E_stru_154, a5, array_50AC10, 0, *(float *)&v33, -1);
           }
           if ( stru_F8AD28.uNumLightsApplied > 0 )
             pGame->pLightmapBuilder->ApplyLights(&stru_F8AD28, &static_sub_0048034E_stru_154, a5, array_50AC10, 0, v33);
@@ -2205,10 +2215,10 @@
       *(int *)&v40->flags = v42;
       v44 = v93;
       v40->field_59 = 1;
-      v40->field_5D = (char)v43;
+      v40->terrain_grid_x = (char)v43;
       v40->field_34 = *(_WORD *)(v44 + 2);
       v45 = v89;
-      v40->field_5C = v89;
+      v40->terrain_grid_z = v89;
       v46 = 4 * ((char)v43 + (v45 << 7));
       v85 = v46;
       v47 = *(unsigned __int16 *)((char *)pTerrainNormalIndices + v46 + 2);//    v47 = pTerrainNormalIndices[v46 + 1];
@@ -2220,9 +2230,9 @@
       //v99 = v48;
       thisg = 20.0 - (-v49 - v91 * v48->z - v90 * v48->x) * 20.0;
       v50 = thisg + 6.755399441055744e15;
-      v40->field_58 = LOBYTE(v50);
+      v40->dimming_level = LOBYTE(v50);
       if ( LOBYTE(v50) < 0 )
-        v40->field_58 = 0;
+        v40->dimming_level = 0;
       if ( pOutdoorCamera->numStru148s >= 1999 )
         return;
       ++pOutdoorCamera->numStru148s;
@@ -2287,7 +2297,7 @@
         //a8 = (RenderVertexSoft *)(this_3a ? 3 : v108 != 0 ? 5 : 0);
         static_sub_0048034E_stru_76D590._49B0C9(v48, *(float *)&a4);
         if ( pDecalBuilder->uNumDecals > 0 )
-          pDecalBuilder->ApplyDecals(31 - v40->field_58, 4, &static_sub_0048034E_stru_76D590, uNumVertices, array_50AC10, 0, (char)pVertices, -1);
+          pDecalBuilder->ApplyDecals(31 - v40->dimming_level, 4, &static_sub_0048034E_stru_76D590, uNumVertices, array_50AC10, 0, (char)pVertices, -1);
       }
       if ( stru_F8AD28.uNumLightsApplied > 0 )
         v96->ApplyLights(&stru_F8AD28, &static_sub_0048034E_stru_76D590, uNumVertices, array_50AC10, 0, (char)pVertices);
@@ -2339,8 +2349,8 @@
       v61 = v93;
       v59->field_59 = 1;
       v59->field_34 = *(_WORD *)(v61 + 2);
-      v59->field_5C = v89;
-      v59->field_5D = v97;
+      v59->terrain_grid_z = v89;
+      v59->terrain_grid_x = v97;
       v62 = *(unsigned __int16 *)((char *)pTerrainNormalIndices + v85);
       if ( v62 > (signed int)(uNumTerrainNormals - 1) )
         v63 = 0;
@@ -2349,9 +2359,9 @@
       v64 = v92 * v63->y;
       //v99 = v63;
       thish = 20.0 - (-v64 - v91 * v63->y - v90 * v63->x) * 20.0;
-      v59->field_58 = floorf(thish + 0.5f);
-      if ( v59->field_58 < 0 )
-        v59->field_58 = 0;
+      v59->dimming_level = floorf(thish + 0.5f);
+      if ( v59->dimming_level < 0 )
+        v59->dimming_level = 0;
       if ( pOutdoorCamera->numStru148s >= 1999 )
         return;
       ++pOutdoorCamera->numStru148s;
@@ -2410,7 +2420,7 @@
           v70 = v108 != 0 ? 5 : 0;
         static_sub_0048034E_stru_76D578._49B0C9(v63, v87);
         if ( pDecalBuilder->uNumDecals > 0 )
-          pDecalBuilder->ApplyDecals(31 - v40->field_58, 4, &static_sub_0048034E_stru_76D578, v100, array_50AC10, 0, v70, -1);
+          pDecalBuilder->ApplyDecals(31 - v40->dimming_level, 4, &static_sub_0048034E_stru_76D578, v100, array_50AC10, 0, v70, -1);
       }
       if ( stru_F8AD28.uNumLightsApplied > 0 )
         v96->ApplyLights(&stru_F8AD28, &static_sub_0048034E_stru_76D578, v100, array_50AC10, 0, v70);
@@ -2588,9 +2598,9 @@
   v6 = 0;
   v90 = 0;
   v81 = v3 - 1;
-  v95 = (double)pOutdoor->vSunlight.x * 0.000015258789;
-  v96 = (double)pOutdoor->vSunlight.y * 0.000015258789;
-  v97 = (double)pOutdoor->vSunlight.z * 0.000015258789;
+  v95 = (double)pOutdoor->vSunlight.x / 65536.0;
+  v96 = (double)pOutdoor->vSunlight.y / 65536.0;
+  v97 = (double)pOutdoor->vSunlight.z / 65536.0;
   if ( v3 - 1 > 0 )
   {
     while ( 1 )
@@ -2643,10 +2653,10 @@
         *(int *)&v17->flags = v19;
         v21 = v92;
         v17->field_59 = 1;
-        v17->field_5D = LOBYTE(v20);
+        v17->terrain_grid_x = LOBYTE(v20);
         v17->field_34 = v21->distance;
         v22 = v94;
-        v17->field_5C = v94;
+        v17->terrain_grid_z = v94;
         v23 = pTerrainNormalIndices[2 * (LODWORD(v20) + (v22 << 7)) + 1];
         if ( v23 < 0 || v23 > (signed int)(uNumTerrainNormals - 1) )
           v24 = 0;
@@ -2661,11 +2671,11 @@
           v99 = v25 * 31.0;
           v76 = v99 + 6.7553994e15;
           v84 = LODWORD(v76);
-          v17->field_58 = 31 - LOBYTE(v76);
+          v17->dimming_level = 31 - LOBYTE(v76);
         }
         else
         {
-          v17->field_58 = 0;
+          v17->dimming_level = 0;
         }
         if ( pOutdoorCamera->numStru148s >= 1999 )
           return;
@@ -2760,10 +2770,10 @@
     *(int *)&v38->flags = v40;
     v42 = v92;
     v38->field_59 = 1;
-    v38->field_5D = LOBYTE(v41);
+    v38->terrain_grid_x = LOBYTE(v41);
     v38->field_34 = v42->distance;
     v43 = v94;
-    v38->field_5C = v94;
+    v38->terrain_grid_z = v94;
     v44 = 2 * (LODWORD(v41) + (v43 << 7));
     LODWORD(v93) = v44 * 2;
     v45 = pTerrainNormalIndices[v44 + 1];
@@ -2780,14 +2790,14 @@
       v88 = v47 * 31.0;
       v74 = v88 + 6.7553994e15;
       v87 = LODWORD(v74);
-      v38->field_58 = 31 - LOBYTE(v74);
+      v38->dimming_level = 31 - LOBYTE(v74);
     }
     else
     {
-      v38->field_58 = 0;
-    }
-    if ( v38->field_58 < 0 )
-      v38->field_58 = 0;
+      v38->dimming_level = 0;
+    }
+    if ( v38->dimming_level < 0 )
+      v38->dimming_level = 0;
     if ( pOutdoorCamera->numStru148s >= 1999 )
       return;
     ++pOutdoorCamera->numStru148s;
@@ -2849,8 +2859,8 @@
           v58 = v92;
           v17->field_59 = 1;
           v17->field_34 = v58->distance;
-          v17->field_5C = v94;
-          v17->field_5D = LOBYTE(v99);
+          v17->terrain_grid_z = v94;
+          v17->terrain_grid_x = LOBYTE(v99);
           v59 = *(unsigned __int16 *)((char *)pTerrainNormalIndices + LODWORD(v93));
           if ( v59 > (signed int)(uNumTerrainNormals - 1) )
           {
@@ -2870,14 +2880,14 @@
             v93 = v61 * 31.0;
             v72 = v93 + 6.7553994e15;
             v83 = LODWORD(v72);
-            v17->field_58 = 31 - LOBYTE(v72);
+            v17->dimming_level = 31 - LOBYTE(v72);
           }
           else
           {
-            v17->field_58 = 0;
+            v17->dimming_level = 0;
           }
-          if ( v17->field_58 < 0 )
-            v17->field_58 = 0;
+          if ( v17->dimming_level < 0 )
+            v17->dimming_level = 0;
           if ( pOutdoorCamera->numStru148s >= 1999 )
             return;
           ++pOutdoorCamera->numStru148s;
@@ -3475,15 +3485,15 @@
 void Render::PrepareDecorationsRenderList_ODM()
 {
   //char *v0; // esi@2
-  DecorationDesc *v1; // ebx@6
+  //DecorationDesc *v1; // ebx@6
   __int16 v2; // ax@6
   double v3; // st7@7
-  int v4; // eax@9
-  int v5; // edx@9
+  //int v4; // eax@9
+  //int v5; // edx@9
   unsigned int v6; // edi@9
   int v7; // eax@9
   SpriteFrame *v8; // eax@9
-  SpriteFrame *v9; // edi@9
+  //SpriteFrame *v9; // edi@9
   unsigned __int16 *v10; // eax@9
   int v11; // ecx@9
   int v12; // eax@9
@@ -3507,10 +3517,10 @@
   int v30; // ecx@37
   int v31; // ebx@37
   Particle_sw local_0; // [sp+Ch] [bp-98h]@7
-  int x; // [sp+74h] [bp-30h]@9
-  int y; // [sp+78h] [bp-2Ch]@9
+  //int x; // [sp+74h] [bp-30h]@9
+  //int y; // [sp+78h] [bp-2Ch]@9
   //int v35; // [sp+7Ch] [bp-28h]@1
-  int v36; // [sp+80h] [bp-24h]@9
+  //int v36; // [sp+80h] [bp-24h]@9
   unsigned __int16 *v37; // [sp+84h] [bp-20h]@9
   int v38; // [sp+88h] [bp-1Ch]@9
   int v39; // [sp+8Ch] [bp-18h]@24
@@ -3527,30 +3537,99 @@
     //do
   for (int i = 0; i < uNumLevelDecorations; ++i)
   {
+    auto decor = pLevelDecorations + i;
     auto v0 = (char *)&pLevelDecorations[i].vPosition.y;
 
-      if ( (!(*(v0 - 6) & 0x40) || ((LevelDecoration *)(v0 - 8))->_47A825()) && !(*(v0 - 6) & 0x20) )
-      {
-        v1 = &pDecorationList->pDecorations[*((short *)v0 - 4)];
-        v2 = v1->uFlags;
+      if ( (!(decor->field_2 & 0x40) || decor->_47A825()) && !(decor->field_2 & 0x20) )
+      {
+        //v1 = &pDecorationList->pDecorations[decor->uDecorationDescID];
+        auto decor_desc = pDecorationList->pDecorations + decor->uDecorationDescID;
+        v2 = decor_desc->uFlags;
         if ( (char)v2 >= 0 )
         {
           if ( !(v2 & 0x22) )
           {
-            v4 = *((int *)v0 - 1);
-            v5 = *((int *)v0 + 1);
+            //v4 = decor->vPosition.x;
+            //v5 = decor->vPosition.z;
             v6 = pMiscTimer->uTotalGameTimeElapsed;
-            y = *(int *)v0;
-            x = v4;
-            v36 = v5;
-            v7 = abs(v4 + y);
-            v8 = pSpriteFrameTable->GetFrame(v1->uSpriteID, v6 + v7);
-            v9 = v8;
+            //y = decor->vPosition.y;
+            //x = decor->vPosition.x;
+            //v36 = decor->vPosition.z;
+            v7 = abs(decor->vPosition.x + decor->vPosition.y);
+
+
+            #pragma region "New: seasons change"
+            extern bool change_seasons;
+            if (change_seasons)
+              switch (pParty->uCurrentMonth)
+              {
+                // case 531 (tree60), 536 (tree65), 537 (tree66) have no autumn/winter sprites
+                case 11: case 0: case 1: // winter
+                  switch (decor_desc->uSpriteID)
+                  {
+                    //case 468: //bush02    grows on swamps, which are evergreeen actually
+                    case 548:             // flower10
+                    case 547:             // flower09
+                    case 541:             // flower03
+                    case 539: continue;   // flower01
+
+                    case 483:             // tree01
+                    case 486:             // tree04
+                    case 492:             // tree10
+                      pSpriteFrameTable->InitializeSprite(decor_desc->uSpriteID + 2);
+                      v8 = pSpriteFrameTable->GetFrame(decor_desc->uSpriteID + 2, v6 + v7);
+                    break;
+
+                    default:
+                      v8 = pSpriteFrameTable->GetFrame(decor_desc->uSpriteID, v6 + v7);
+                  }
+                break;
+
+                case 2: case 3: case 4: // spring
+                  switch (decor_desc->uSpriteID)
+                  {
+                  }
+                  v8 = pSpriteFrameTable->GetFrame(decor_desc->uSpriteID, v6 + v7);
+                break;
+
+                case 8: case 9: case 10: // autumn
+                  switch (decor_desc->uSpriteID)
+                  {
+                    //case 468: //bush02    grows on swamps, which are evergreeen actually
+                    case 548:             // flower10
+                    case 547:             // flower09
+                    case 541:             // flower03
+                    case 539: continue;   // flower01
+                    
+                    case 483:             // tree01
+                    case 486:             // tree04
+                    case 492:             // tree10
+                      pSpriteFrameTable->InitializeSprite(decor_desc->uSpriteID + 1);
+                      v8 = pSpriteFrameTable->GetFrame(decor_desc->uSpriteID + 1, v6 + v7);
+                    break;
+
+                    default:
+                      v8 = pSpriteFrameTable->GetFrame(decor_desc->uSpriteID, v6 + v7);
+                  }
+                break;
+
+                case 5: case 6: case 7: // summer
+                  //all green by default
+                  v8 = pSpriteFrameTable->GetFrame(decor_desc->uSpriteID, v6 + v7);
+                break;
+
+                default: assert(pParty->uCurrentMonth >= 0 && pParty->uCurrentMonth < 12);
+              }
+            else
+              v8 = pSpriteFrameTable->GetFrame(decor_desc->uSpriteID, v6 + v7);
+            #pragma endregion
+            //v8 = pSpriteFrameTable->GetFrame(decor_desc->uSpriteID, v6 + v7);
+
+            //v9 = v8;
             v42 = v8->uFlags;
             a5 = v8->uGlowRadius;
-            v10 = (unsigned __int16 *)stru_5C6E00->Atan2(
-                                        *((int *)v0 - 1) - pIndoorCamera->pos.x,
-                                        *(int *)v0 - pIndoorCamera->pos.y);
+            v10 = (unsigned __int16 *)stru_5C6E00->Atan2(decor->vPosition.x - pIndoorCamera->pos.x,
+                                                         decor->vPosition.y - pIndoorCamera->pos.y);
             v11 = *((int *)v0 + 2);
             v37 = v10;
             v12 = v42;
@@ -3572,9 +3651,9 @@
             {
               if ( pRenderer->pRenderD3D && pRenderer->bUseColoredLights )
               {
-                v14 = v1->uColoredLightRed;
-                v15 = v1->uColoredLightGreen;
-                v16 = v1->uColoredLightBlue;
+                v14 = decor_desc->uColoredLightRed;
+                v15 = decor_desc->uColoredLightGreen;
+                v16 = decor_desc->uColoredLightBlue;
               }
               else
               {
@@ -3584,25 +3663,25 @@
               }
               b = v16;
               pStationaryLightsStack->AddLight(
-                x,
-                y,
-                v36 + v1->uDecorationHeight / 2,
+                decor->vPosition.x,
+                decor->vPosition.y,
+                decor->vPosition.z + decor_desc->uDecorationHeight / 2,
                 a5,
                 v14,
                 v15,
                 v16,
                 byte_4E94D0);
             }
-            v17 = (x - pIndoorCamera->pos.x) << 16;
+            v17 = (decor->vPosition.x - pIndoorCamera->pos.x) << 16;
             if ( pIndoorCamera->sRotationX )
             {
-              v40 = (y - pIndoorCamera->pos.y) << 16;
+              v40 = (decor->vPosition.y - pIndoorCamera->pos.y) << 16;
               v18 = ((unsigned __int64)(v17 * (signed __int64)pOutdoorCamera->camera_rotation_y_int_cosine) >> 16)
                   + ((unsigned __int64)(v40 * (signed __int64)pOutdoorCamera->camera_rotation_y_int_sine) >> 16);
               v42 = v18;
               b = (unsigned __int64)(v17 * (signed __int64)pOutdoorCamera->camera_rotation_y_int_sine) >> 16;
               a5 = (unsigned __int64)(v40 * (signed __int64)pOutdoorCamera->camera_rotation_y_int_cosine) >> 16;
-              v40 = (v36 - pIndoorCamera->pos.z) << 16;
+              v40 = (decor->vPosition.z - pIndoorCamera->pos.z) << 16;
               v41 = (unsigned __int64)(v40 * (signed __int64)pOutdoorCamera->camera_rotation_x_int_sine) >> 16;
               v19 = (unsigned __int64)(v18 * (signed __int64)pOutdoorCamera->camera_rotation_x_int_cosine) >> 16;
               v20 = v19 + ((unsigned __int64)(v40 * (signed __int64)pOutdoorCamera->camera_rotation_x_int_sine) >> 16);
@@ -3629,9 +3708,9 @@
                   v41 = v24 / v39;
                   v40 = pViewport->uScreenCenterY
                       - ((signed int)(((unsigned __int64)(a5 * (signed __int64)v42) >> 16) + 32768) >> 16);
-                  v42 = v9->scale;
+                  v42 = v8->scale;
                   v41 = (unsigned __int64)(v42 * v24 / v39) >> 16;
-                  v37 = (unsigned __int16 *)&v9->pHwSpriteIDs[(int)v37];
+                  v37 = (unsigned __int16 *)&v8->pHwSpriteIDs[(int)v37];
                   if ( pRenderer->pRenderD3D )
                   {
                     v26 = v41;
@@ -3651,7 +3730,7 @@
                     v27 = &pBillboardRenderList[::uNumBillboardsToDraw++];
                     ++uNumDecorationsDrawnThisFrame;
                     v27->uHwSpriteID = *v37;
-                    v28 = v9->uPaletteIndex;
+                    v28 = v8->uPaletteIndex;
                     v27->_screenspace_x_scaler_packedfloat = v26;
                     v27->_screenspace_y_scaler_packedfloat = v26;
                     v29 = v38;
@@ -3659,9 +3738,9 @@
                     HIBYTE(v29) |= 2u;
                     v27->uPalette = v28;
                     v27->field_1E = v29;
-                    v27->world_x = x;
-                    v27->world_y = y;
-                    v27->world_z = v36;
+                    v27->world_x = decor->vPosition.x;
+                    v27->world_y = decor->vPosition.y;
+                    v27->world_z = decor->vPosition.z;
                     v27->uScreenSpaceY = v40;
                     HIWORD(v30) = HIWORD(v39);
                     v31 = 8 * i | OBJECT_Decoration;
@@ -3669,7 +3748,7 @@
                     v27->uIndoorSectorID = 0;
                     v27->sZValue = v30 + v31;
                     v27->uPaletteSubindex = 0;
-                    v27->pSpriteFrame = v9;
+                    v27->pSpriteFrame = v8;
                     v27->uTintColor = 0;
                   }
                 }
@@ -3678,8 +3757,8 @@
             }
             else
             {
-              v42 = (x - pIndoorCamera->pos.x) << 16;
-              v40 = (y - pIndoorCamera->pos.y) << 16;
+              v42 = (decor->vPosition.x - pIndoorCamera->pos.x) << 16;
+              v40 = (decor->vPosition.y - pIndoorCamera->pos.y) << 16;
               b = (unsigned __int64)(v17 * (signed __int64)pOutdoorCamera->camera_rotation_y_int_cosine) >> 16;
               a5 = (unsigned __int64)(v40 * (signed __int64)pOutdoorCamera->camera_rotation_y_int_sine) >> 16;
               v20 = b + ((unsigned __int64)(v40 * (signed __int64)pOutdoorCamera->camera_rotation_y_int_sine) >> 16);
@@ -3690,7 +3769,7 @@
                 b = (unsigned __int64)(v40 * (signed __int64)pOutdoorCamera->camera_rotation_y_int_cosine) >> 16;
                 v21 = ((unsigned __int64)(v40 * (signed __int64)pOutdoorCamera->camera_rotation_y_int_cosine) >> 16) - a5;
                 v41 = ((unsigned __int64)(v40 * (signed __int64)pOutdoorCamera->camera_rotation_y_int_cosine) >> 16) - a5;
-                v22 = (v36 - pIndoorCamera->pos.z) << 16;
+                v22 = (decor->vPosition.z - pIndoorCamera->pos.z) << 16;
                 goto LABEL_30;
               }
             }
@@ -4409,7 +4488,7 @@
   unsigned int v55; // [sp+5Ch] [bp-Ch]@34
   unsigned int v56; // [sp+60h] [bp-8h]@12
   int v57; // [sp+60h] [bp-8h]@34
-  HRESULT a2; // [sp+64h] [bp-4h]@4
+  unsigned int a2; // [sp+64h] [bp-4h]@4
 
   v5 = this;
   v6 = 0;
@@ -4419,11 +4498,11 @@
     v53 = v7;
     v54 = v7->std__vector_000004_size;
     if ( v7->std__vector_000004_size)
-      a2 = -1;
-    pGame->_44EE30(a4, (int)&a2);
+      a2 = 0xFFFFFFFF;
+    pGame->AlterGamma_ODM(a4, &a2);
     if ( byte_4D864C && pGame->uFlags & 1 )
     {
-      v8 = GetActorTintColor(a3->field_58, 0, array_50AC10[0].vWorldViewPosition.x, 0, 0);
+      v8 = ::GetActorTintColor(a3->dimming_level, 0, array_50AC10[0].vWorldViewPosition.x, 0, 0);
       v7->_45D74F_MessWithLight(v8, 0);
     }
     else
@@ -4445,8 +4524,8 @@
           v55 = uNumVertices;
           do
           {
-            a2 = GetActorTintColor(a3->field_58, 0, *(float *)v45, 0, 0);
-            pGame->_44EE30(a4, (int)&a2);
+            a2 = ::GetActorTintColor(a3->dimming_level, 0, *(float *)v45, 0, 0);
+            pGame->AlterGamma_ODM(a4, &a2);
             v46 = v57;
             v47 = *(float *)v45 * 1000.0 / (double)pOutdoorCamera->shading_dist_mist;
             *(int *)(v57 - 4) = *((int *)v45 + 3);
@@ -4507,7 +4586,7 @@
             v9->pFacePlane.vNormal.x = *((int *)v10 + 4);
             *(float *)&v9->pFacePlane.vNormal.y = 1.0 - 1.0 / v12;
             *(float *)&v9->pFacePlane.vNormal.z = 1.0 / (*(float *)v10 + 0.0000001);
-            v13 = GetActorTintColor(a3->field_58, 0, *(float *)v10, 0, 0);
+            v13 = GetActorTintColor(a3->dimming_level, 0, *(float *)v10, 0, 0);
             v14 = a4;
             v15 = *(float *)v10;
             a4->pFacePlane.dist = v13;
@@ -7236,6 +7315,7 @@
 //----- (004A2031) --------------------------------------------------------
 unsigned int Render::GetActorTintColor(float a2, int tint, int a4, int a5, RenderBillboard *a6)
 {
+  __debugbreak(); // should not fire outside decal builder
   return ::GetActorTintColor(tint, a4, a2, a5, a6);
 }
 
@@ -7434,7 +7514,7 @@
     v10 = v9->std__vector_000004_size;*/
     if ( byte_4D864C && pGame->uFlags & 1 )
     {
-      v11 = GetActorTintColor(a4->field_58, 0, array_50AC10[0].vWorldViewPosition.x, 0, 0);
+      v11 = ::GetActorTintColor(a4->dimming_level, 0, array_50AC10[0].vWorldViewPosition.x, 0, 0);
       pGame->pLightmapBuilder->_45D74F_MessWithLight(v11, 0);
     }
     else
@@ -7477,7 +7557,7 @@
             *(int *)v51 = *((int *)v52 + 4);
             *(float *)(v51 + 4) = 1.0 - 1.0 / v54;
             *(float *)(v51 + 8) = 1.0 / (*(float *)v52 + 0.0000001);
-            v55 = GetActorTintColor(a4->field_58, 0, *(float *)v52, 0, 0);
+            v55 = ::GetActorTintColor(a4->dimming_level, 0, *(float *)v52, 0, 0);
             v56 = a7;
             v57 = *(float *)v52;
             *(int *)(a7 + 12) = v55;
@@ -7527,7 +7607,7 @@
             *(int *)v12 = *((int *)v13 + 4);
             *(float *)(v12 + 4) = 1.0 - 1.0 / v15;
             *(float *)(v12 + 8) = 1.0 / (*(float *)v13 + 0.0000001);
-            v16 = GetActorTintColor(a4->field_58, 0, *(float *)v13, 0, 0);
+            v16 = GetActorTintColor(a4->dimming_level, 0, *(float *)v13, 0, 0);
             v17 = a7;
             v18 = *(float *)v13;
             *(int *)(a7 + 12) = v16;
@@ -7669,7 +7749,7 @@
    pVertices[i].pos.z = 0.99989998;
    pVertices[i].rhw = array_50AC10[i]._rhw;
 
-   pVertices[i].diffuse = GetActorTintColor(31, 0, array_50AC10[i].vWorldViewPosition.x, 1, 0);
+   pVertices[i].diffuse = ::GetActorTintColor(31, 0, array_50AC10[i].vWorldViewPosition.x, true, false);
    v7 = 0;
    if (this->bUsingSpecular)
    {
@@ -7747,9 +7827,9 @@
     if ( a2 >= 3 )
     {
       ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP));
-      v5 = 31 - (a3->field_58 & 0x1F);
-      if ( v5 < pOutdoor->field_CBC_terrain_triangles_shade_type )
-        v5 = pOutdoor->field_CBC_terrain_triangles_shade_type;
+      v5 = 31 - (a3->dimming_level & 0x1F);
+      if ( v5 < pOutdoor->max_terrain_dimming_level )
+        v5 = pOutdoor->max_terrain_dimming_level;
       v6 = 8 * v5 | ((8 * v5 | (v5 << 11)) << 8);
       if ( a2 > 0 )
       {
@@ -7834,7 +7914,7 @@
   auto uCorrectedColor = uColor;
   if (pGame->pLightmapBuilder->std__vector_000004_size)
     uCorrectedColor = 0xFFFFFFFF;
-  pGame->AlterGamma(pFace, &uCorrectedColor);
+  pGame->AlterGamma_BLV(pFace, &uCorrectedColor);
 
   if (byte_4D864C && pGame->uFlags & 1)
   {
@@ -8501,7 +8581,7 @@
   v30 = (a2->_screenspace_x_scaler_packedfloat & 0xFFFF) / 65530.0 + HIWORD(a2->_screenspace_x_scaler_packedfloat);
   v29 = (a2->_screenspace_y_scaler_packedfloat & 0xFFFF) / 65530.0 + HIWORD(a2->_screenspace_y_scaler_packedfloat);
 
-  unsigned int diffuse = GetActorTintColor(paletteSubindex, 0, a2->zbuffer_depth, 0, pBillboard);
+  unsigned int diffuse = ::GetActorTintColor(paletteSubindex, 0, a2->zbuffer_depth, 0, pBillboard);
   if (a2->uTintColor & 0x00FFFFFF && bTinting)
   {
     diffuse = sub_4A19D8(a2->uTintColor, diffuse);
--- a/Sprites.cpp	Tue Mar 12 09:43:40 2013 +0600
+++ b/Sprites.cpp	Tue Mar 12 09:43:50 2013 +0600
@@ -326,23 +326,29 @@
 }
 
 //----- (0044D8D0) --------------------------------------------------------
-SpriteFrame *SpriteFrameTable::GetFrame(unsigned int uSpriteID, unsigned int uFrameID)
+SpriteFrame *SpriteFrameTable::GetFrame(unsigned int uSpriteID, unsigned int uTime)
 {
-  SpriteFrame *v3; // edi@1
+  //SpriteFrame *v3; // edi@1
   SpriteFrame *v4; // ecx@1
-  __int16 v5; // dx@2
-  int v6; // edx@3
-  unsigned int v7; // eax@3
-  char *i; // ecx@3
-  int v9; // esi@5
-  SpriteFrame *result; // eax@6
+  //__int16 v5; // dx@2
+  //int v6; // edx@3
+  //unsigned int v7; // eax@3
+  //char *i; // ecx@3
+  //int v9; // esi@5
+  //SpriteFrame *result; // eax@6
 
-  v3 = this->pSpriteSFrames;
-  v4 = &v3[uSpriteID];
-  if ( v4->uFlags & 1 && (v5 = v4->uAnimLength) != 0 )
-  {
-    v6 = ((signed int)uFrameID >> 3) % v5;
-    v7 = uSpriteID;
+  v4 = &pSpriteSFrames[uSpriteID];
+  if (~v4->uFlags & 1 || !v4->uAnimLength)
+    return pSpriteSFrames + uSpriteID;
+
+  for (uint t = (uTime / 8) % v4->uAnimLength; t > v4->uAnimTime; ++v4)
+    t -= v4->uAnimTime;
+  return v4;
+
+  /*for (v4; v4->uAnimTime <= t; ++v4)
+
+    v6 = (uTime / 8) % v4->uAnimLength;
+    //v7 = uSpriteID;
     for ( i = (char *)&v4->uAnimTime; ; i += 60 )
     {
       v9 = *(short *)i;
@@ -351,13 +357,8 @@
       v6 -= v9;
       ++v7;
     }
-    result = &v3[v7];
-  }
-  else
-  {
-    result = &v3[uSpriteID];
-  }
-  return result;
+    return &pSpriteSFrames[v7];*/
+
 }
 
 //----- (0044D91F) --------------------------------------------------------
--- a/Sprites.h	Tue Mar 12 09:43:40 2013 +0600
+++ b/Sprites.h	Tue Mar 12 09:43:50 2013 +0600
@@ -59,7 +59,7 @@
   void InitializeSprite(unsigned int uSpriteID);
   unsigned int FastFindSprite(char *pSpriteName);
   void BinarySearch(int a2, int a3, const char *pSpriteName);
-  SpriteFrame *GetFrame(unsigned int uSpriteID, unsigned int uFrameID);
+  SpriteFrame *GetFrame(unsigned int uSpriteID, unsigned int uTime);
   SpriteFrame *GetFrameBy_x(unsigned int uSpriteID, signed int a3);
 
   unsigned int uNumSpriteFrames;
--- a/UIHouses.cpp	Tue Mar 12 09:43:40 2013 +0600
+++ b/UIHouses.cpp	Tue Mar 12 09:43:50 2013 +0600
@@ -914,23 +914,23 @@
 //----- (004B8285) --------------------------------------------------------
 void __cdecl TavernDialog()
 {
-  GUIWindow *v0; // ebx@1
-  Player *v1; // edi@1
+  int v0;
+  int pItemNum;
   double v2; // st7@1
   signed int v3; // ebx@1
   int v4; // ecx@1
   int v5; // esi@3
   signed int v6; // edi@5
   int v7; // ecx@5
-  GUIWindow *v8; // edi@16
+  int pNumString; // edi@16
   signed int v9; // esi@16
-  unsigned int v10; // esi@18
+  unsigned int pNumActiveItem; // esi@18
   int v11; // eax@18
   unsigned int v12; // eax@19
   int v13; // eax@21
   int v14; // ecx@26
-  GUIButton *v15; // eax@28
-  GUIButton *v16; // esi@28
+  //GUIButton *v15; // eax@28
+  //GUIButton *v16; // esi@28
   int v17; // eax@28
   char *v18; // eax@30
   int v19; // eax@30
@@ -942,17 +942,14 @@
   int v25; // eax@34
   char *v26; // esi@36
   int v27; // edi@46
-  unsigned int v28; // eax@53
-  unsigned int v29; // eax@55
-  unsigned int v30; // eax@57
+  unsigned int pColorText; // eax@57
   signed int v31; // eax@59
-  unsigned int v32; // eax@61
-  GUIWindow *v33; // edi@64
+  //GUIWindow *v33; // edi@64
   int v34; // eax@64
   int v35; // ecx@64
   int v36; // esi@64
   char v37; // sf@64
-  GUIButton *v38; // eax@65
+  GUIButton *pButton; // eax@65
   int v39; // edx@69
   int v40; // ecx@69
   int v41; // ecx@69
@@ -965,18 +962,17 @@
   signed int v48; // edi@77
   signed int i; // esi@79
   int v50; // eax@80
-  GUIWindow *v51; // ecx@81
+  //GUIWindow *v51; // ecx@81
   _QWORD v52; // qax@81
   signed int v53; // edi@81
   int v54; // edi@81
-  GUIButton *v55; // esi@83
+  //GUIButton *v55; // esi@83
   const char **v56; // eax@83
   int v57; // eax@83
   unsigned int v58; // ecx@83
-  Player *v59; // edx@83
+  //Player *v59; // edx@83
   unsigned __int16 v60; // ax@83
   int v61; // eax@99
-  int v62; // edi@99
   char *v63; // eax@99
   GUIFont *v64; // edx@99
   GUIFont *v65; // edi@100
@@ -992,36 +988,34 @@
   char v75[100]; // [sp+70h] [bp-204h]@59
   char a1[100]; // [sp+D4h] [bp-1A0h]@57
   char v77[100]; // [sp+138h] [bp-13Ch]@59
-  GUIWindow v78; // [sp+19Ch] [bp-D8h]@99
-  GUIWindow v79; // [sp+1F0h] [bp-84h]@1
+  //GUIWindow v78; // [sp+19Ch] [bp-D8h]@99
+  GUIWindow dialog_window; // [sp+1F0h] [bp-84h]@1
   char *Str[2]; // [sp+244h] [bp-30h]@30
-  unsigned int v81; // [sp+24Ch] [bp-28h]@1
+  unsigned int pColorWhite; // [sp+24Ch] [bp-28h]@1
   unsigned __int8 v82; // [sp+253h] [bp-21h]@59
   int v83; // [sp+254h] [bp-20h]@1
-  __int16 v84[2]; // [sp+258h] [bp-1Ch]@1
-  Player *v85; // [sp+25Ch] [bp-18h]@1
-  int v86; // [sp+260h] [bp-14h]@18
+  int pColorYellow; // [sp+258h] [bp-1Ch]@1
+  Player *pPlayer; // [sp+25Ch] [bp-18h]@1
+  int all_text_height; // [sp+260h] [bp-14h]@18
   unsigned __int8 v87; // [sp+266h] [bp-Eh]@59
   unsigned __int8 v88; // [sp+267h] [bp-Dh]@57
   int v89; // [sp+268h] [bp-Ch]@1
-  unsigned __int8 v90; // [sp+26Fh] [bp-5h]@55
-  GUIFont *pOutString; // [sp+270h] [bp-4h]@3
+  unsigned int pTextHeight; // [sp+26Fh] [bp-5h]@55
+  int v91; // [sp+270h] [bp-4h]@3
+  GUIFont *pOutString;
 
-  v0 = window_SpeakInHouse;
-  memcpy(&v79, window_SpeakInHouse, sizeof(v79));
-  v85 = pPlayers[uActiveCharacter];
-  v1 = v85;
-  v79.uFrameX = 483;
-  v79.uFrameWidth = 148;
-  v79.uFrameZ = 334;
-  v81 = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0xFFu, 0xFFu, 0xFFu);
-  *(int *)v84 = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0xFFu, 0xFFu, 0x9Bu);
-  //v2 = p2DEvents_minus1__20[13 * (unsigned int)v0->ptr_1C];
-  v2 = p2DEvents[(unsigned int)v0->ptr_1C - 1].fPriceMultiplier;
+  pPlayer = pPlayers[uActiveCharacter];
+  memcpy(&dialog_window, window_SpeakInHouse, sizeof(dialog_window));
+  dialog_window.uFrameX = 483;
+  dialog_window.uFrameWidth = 148;
+  dialog_window.uFrameZ = 334;
+  pColorWhite = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0xFFu, 0xFFu, 0xFFu);
+  pColorYellow = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0xFFu, 0xFFu, 0x9Bu);
+  v2 = p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].fPriceMultiplier;
   *(float *)&v83 = v2;
   *(float *)&v89 = v2 * v2;
   v3 = (signed __int64)(*(float *)&v89 * 0.1);
-  v4 = v3 * (100 - v1->GetMerchant()) / 100;
+  v4 = v3 * (100 - pPlayer->GetMerchant()) / 100;
   if ( v4 < v3 / 3 )
     v4 = v3 / 3;
   v5 = 1;
@@ -1029,7 +1023,7 @@
   if ( v4 <= 0 )
     pOutString = (GUIFont *)1;
   v6 = (signed __int64)(*(float *)&v89 * *(float *)&v83 * 0.0099999998);
-  v7 = v6 * (100 - v85->GetMerchant()) / 100;
+  v7 = v6 * (100 - pPlayer->GetMerchant()) / 100;
   if ( v7 < v6 / 3 )
     v7 = v6 / 3;
   v83 = v7;
@@ -1040,405 +1034,324 @@
   }
   switch(dialog_menu_id)
   {
-	case 102:
-		{
-		v65 = pFontArrus;
-		pOutString = pFontArrus;
-		strcpy(pTmpBuf, pNPCTopics[354].pText);
-		v78.uFrameWidth = 460;
-		v78.uFrameZ = 452;
-		v62 = v65->CalcTextHeight(pTmpBuf, &v78, 12, 0) + 7;
-		if ( 352 - v62 < 8 )
-		{
-			pOutString = pFontCreate;
-			v62 = pFontCreate->CalcTextHeight(pTmpBuf, &v78, 12, 0) + 7;
-		}
-
-		auto pTex = (uTextureID_Leather != -1 ? &pIcons_LOD->pTextures[uTextureID_Leather] : 0);
-		pRenderer->_4A6A68(8u, 352 - v62, pTex, (pTex ? pTex->uTextureHeight : 26) - v62);
+    case DIALOG_SHOP_MAIN:
+    {
+      if ( !sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
+          return;
 
-		pRenderer->DrawTextureIndexed(8u, 347 - v62, pTexture_591428);
-		v73 = 0;
-		v70 = 0;
-		v68 = 0;
-		v63 = FitTextInAWindow(pTmpBuf, pOutString, &v78, 0xCu, 0);
-		v64 = pOutString;
-		window_SpeakInHouse->DrawText(v64, 12, 354 - v62, 0, v63, v68, v70, v73);
-		break;
-		}
-	case 103:
-		{
-		strcpy(pTmpBuf, pNPCTopics[(uint)window_SpeakInHouse->ptr_1C + 247].pText);
-		v78.uFrameWidth = 460;
-		v78.uFrameZ = 452;
-		v61 = pFontArrus->CalcTextHeight(pTmpBuf, &v78, 12, 0);
-		v62 = v61 + 7;
+      sprintf(Dest, "\xC" "%05d", pDialogueWindow->pCurrentPosActiveItem == 2 ? pColorYellow : pColorWhite);
+      sprintfex(pTmpBuf2, pGlobalTXT_LocalizationStrings[178], pOutString); // Rent room for %d gold
+      strcat(Dest, pTmpBuf2);
+      pTextHeight = pFontArrus->CalcTextHeight(Dest, &dialog_window, 0, 0);
+      strcat(Dest, "\n \n");
 
-		auto pTex = (uTextureID_Leather != -1 ? &pIcons_LOD->pTextures[uTextureID_Leather] : nullptr);
-		pRenderer->_4A6A68(8u, 352 - (v61 + 7), pTex, (pTex ? pTex->uTextureHeight : 26) - (v61 + 7));
+      sprintf(a1, "\xC" "%05d", pDialogueWindow->pCurrentPosActiveItem == 3 ? pColorYellow : pColorWhite);
+      sprintfex(pTmpBuf2, pGlobalTXT_LocalizationStrings[86], // Buy food for %d days for %d gold
+        (unsigned int)p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].fPriceMultiplier,
+         v83);
+      strcat(a1, pTmpBuf2);
+      v88 = pFontArrus->CalcTextHeight(a1, &dialog_window, 0, 0);
+      strcat(a1, "\n \n");
 
-		pRenderer->DrawTextureIndexed(8u, 347 - v62, pTexture_591428);
-		v73 = 0;
-		v70 = 0;
-		v68 = 0;
-		v63 = FitTextInAWindow(pTmpBuf, pFontArrus, &v78, 0xCu, 0);
-		v64 = pFontArrus;
-		window_SpeakInHouse->DrawText(v64, 12, 354 - v62, 0, v63, v68, v70, v73);
-		break;
-		}
-	case 104:
-		{
-		if ( pArcomageGame->bGameInProgress == 1 )
-          return;
-        v26 = pTmpBuf;
-        if ( pArcomageGame->uGameResult )
+      sprintf(v77, "\xC" "%05d", pDialogueWindow->pCurrentPosActiveItem == 4 ? pColorYellow : pColorWhite);
+      strcat(v77, pGlobalTXT_LocalizationStrings[160]); // Learn Skills
+      v82 = pFontArrus->CalcTextHeight(v77, &dialog_window, 0, 0);
+      strcat(v77, "\n \n");
+      v75[0] = 0;
+      pTextHeight = 0;
+      v31 = (signed int)window_SpeakInHouse->ptr_1C;
+      if ( v31 >= 108 && v31 <= 120 )
+      {
+        sprintf(v75, "\xC" "%05d", pDialogueWindow->pCurrentPosActiveItem == 5 ? pColorYellow : pColorWhite);
+        strcat(v75, pGlobalTXT_LocalizationStrings[611]); // Play Arcomage
+        pTextHeight = pFontArrus->CalcTextHeight(v75, &dialog_window, 0, 0);
+      }
+      v34 = pDialogueWindow->pStartingPosActiveItem;
+      v35 = v34 + pDialogueWindow->pNumPresenceButton;
+      v36 = LOBYTE(pFontArrus->uFontHeight) - 3;
+      v37 = -pDialogueWindow->pNumPresenceButton < 0;
+      pOutString = (GUIFont *)pDialogueWindow->pStartingPosActiveItem;
+      if ( !(v37 ^ v34 < v35) )
+      {
+        sprintf(pTmpBuf, "%s%s%s%s", Dest, a1, v77, v75);
+        dialog_window.DrawTitleText(pFontArrus, 0, 146, 0, pTmpBuf, 3);
+        return;
+      }
+      while ( 1 )
+      {
+        pButton = pDialogueWindow->GetControl((unsigned int)pOutString);
+        if ( pButton->uControlParam == 15 )
         {
-          if ( pArcomageGame->uGameResult == 1 )
-            v72 = pGlobalTXT_LocalizationStrings[640];// You won!
-          else
-            v72 = pGlobalTXT_LocalizationStrings[641];// You lost!
-        }
-        else
-        {
-          v72 = pGlobalTXT_LocalizationStrings[639];// A tie!
+          v46 = pTextHeight;
+          pButton->uHeight = pTextHeight;
+          pButton->uY = 146;
+          v41 = v46 + 145;
+          pButton->uW = v41;
         }
-        strcpy(pTmpBuf, v72);
-//LABEL_97:
-        v71 = 3;
-        v69 = v26;
-        v67 = v84[0];
-        v66 = (174 - pFontArrus->CalcTextHeight(v26, &v79, 0, 0)) / 2 + 138;
-        v79.DrawTitleText(pFontArrus, 0, v66, v67, v69, v71);
-		break;
-		}
-	case 15:
-		{
-        if ( pParty->uNumGold >= (unsigned int)pOutString )
+        else if ( pButton->uControlParam == 16 )
+        {
+          v44 = v88;
+          v45 = pTextHeight + v36 + 146;
+          pButton->uHeight = v88;
+          pButton->uY = v45;
+          v41 = v45 + v44 - 1;
+          pButton->uW = v41;
+        }
+        else if ( pButton->uControlParam == 96 )
         {
-          Party::TakeGold((unsigned int)pOutString);
-          v27 = (int)window_SpeakInHouse->ptr_1C;
-          HousePlaySomeSound((unsigned int)window_SpeakInHouse->ptr_1C, 2);
-          dialog_menu_id = 0;
-          while ( sub_4BD8B5() )
-            ;
-          sub_4B1D27();
-          pVideoPlayer->Unload();
-          window_SpeakInHouse->Release();
-          window_SpeakInHouse = 0;
-
-          if ( pMessageQueue_50CBD0->uNumMessages )
-            pMessageQueue_50CBD0->uNumMessages = pMessageQueue_50CBD0->pMessages[0].field_8 != 0;
-          pMessageQueue_50CBD0->pMessages[0].eType = UIMSG_OpenRestUI;
-          pMessageQueue_50CBD0->pMessages[0].param = v27;
-          pMessageQueue_50CBD0->pMessages[0].field_8 = 1;
-//LABEL_51:
-          ++pMessageQueue_50CBD0->uNumMessages;
+          v42 = pTextHeight + v88 + 2 * v36 + 146;
+          v43 = v82;
+          pButton->uY = v42;
+          pButton->uHeight = v43;
+          v41 = v43 + v42 - 1;
+          pButton->uW = v41;
+        }
+        else if ( pButton->uControlParam == 101 )
+        {
+          v39 = pTextHeight + 3 * v36 + pTextHeight + v88 + 146;
+          v40 = v87;
+          pButton->uHeight = pTextHeight;
+          pButton->uY = v39;
+          v41 = v39 + v40 - 1;
+          pButton->uW = v41;
+        }
+        pOutString = (GUIFont *)((char *)pOutString + 1);
+        if ( (signed int)pOutString >= pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem )
+        {
+          sprintf(pTmpBuf, "%s%s%s%s", &Dest, &a1, &v77, &v75);
+          dialog_window.DrawTitleText(pFontArrus, 0, 146, 0, pTmpBuf, 3);
           return;
         }
-		ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2u);
-        HousePlaySomeSound((unsigned int)window_SpeakInHouse->ptr_1C, 4);
-        pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, v5, 0);
-		break;
-		}
-	case 96:
-		{
-		if ( !sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
-			return;
-		v8 = pDialogueWindow;
-		*(float *)&v89 = 0.0;
-
-		//v9 = (signed __int64)(*(float *)&p2DEvents_minus1__24[13 * (unsigned int)ptr_507BC0->ptr_1C] * 500.0);
-		v9 = (signed __int64)(p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].flt_24 * 500.0);
-
-		pOutString = (GUIFont *)(v9 * (100 - v85->GetMerchant()) / 100);
-		if ( (signed int)pOutString < v9 / 3 )
-			pOutString = (GUIFont *)(v9 / 3);
-		v10 = v8->pStartingPosActiveItem;
-		v11 = v10 + v8->pNumPresenceButton;
-		v86 = 0;
-		if ( (signed int)v10 < v11 )
-		{
-			do
-			{
-				v12 = v8->GetControl(v10)->uControlParam - 36;
-				if ( byte_4ED970_skill_learn_ability_by_class_table[v85->classType][v12] && !v85->pActiveSkills[v12] )
-				{
-					v13 = pFontArrus->CalcTextHeight(pSkillNames[v12], &v79, 0, 0);
-					v89 += v13;
-					++v86;
-				}
-				++v10;
-			}
-			while ( (signed int)v10 < v8->pStartingPosActiveItem + v8->pNumPresenceButton );
-			if ( v86 )
-			{
-				sprintf(pTmpBuf, pGlobalTXT_LocalizationStrings[401], pOutString);
-				v79.DrawTitleText(pFontArrus, 0, 0x92u, 0, pTmpBuf, 3u);
-				pOutString = (GUIFont *)((149 - v89) / v86);
-				if ( (149 - v89) / v86 > 32 )
-					pOutString = (GUIFont *)32;
-				v14 = (149 - v86 * (signed int)pOutString - v89) / 2 - (signed int)pOutString / 2 + 162;
-				v89 = v8->pStartingPosActiveItem;
-				v83 = v14;
-				if ( v89 < v89 + v8->pNumPresenceButton )
-				{
-					v86 = 2;
-					do
-					{
-						v15 = v8->GetControl(v89);
-						v16 = v15;
-						v17 = v15->uControlParam - 36;
-						if ( !byte_4ED970_skill_learn_ability_by_class_table[v85->classType][v17] || v85->pActiveSkills[v17] )
-						{
-							v16->uW = 0;
-							v16->uHeight = 0;
-							v16->uY = 0;
-						}
-						else
-						{
-							v18 = pSkillNames[v17];
-							v16->uY = (unsigned int)((char *)pOutString + v83);
-							Str[1] = v18;
-							v19 = pFontArrus->CalcTextHeight(v18, &v79, 0, 0);
-							v20 = v16->uY;
-							v21 = v86;
-							v16->uHeight = v19;
-							v22 = v19 + v20 - 1;
-							v16->uW = v22;
-							v83 = v22;
-							v23 = v84[0];
-							if ( pDialogueWindow->pCurrentPosActiveItem != v21 )
-								v23 = v81;
-							v79.DrawTitleText(pFontArrus, 0, v20, v23, Str[1], 3u);
-						}
-						v24 = v8->pNumPresenceButton;
-						++v89;
-						v25 = v8->pStartingPosActiveItem + v24;
-						++v86;
-					}
-					while ( v89 < v25 );
-				}
-				return;
-			}
-		}
-		v26 = pTmpBuf;
-		sprintf(pTmpBuf, pGlobalTXT_LocalizationStrings[544], v85->pName, pClassNames[v85->classType]);
-		strcat(pTmpBuf, "\n \n");
-		strcat(pTmpBuf, pGlobalTXT_LocalizationStrings[528]);
-		v71 = 3;
-		v69 = v26;
-		v67 = v84[0];
-		v66 = (174 - pFontArrus->CalcTextHeight(v26, &v79, 0, 0)) / 2 + 138;
-		v79.DrawTitleText(pFontArrus, 0, v66, v67, v69, v71);
-		return;
-		break;
-		}
-	case 16:
-		{
-        *(_QWORD *)Str = pParty->uNumFoodRations;
-        //if ( (double)pParty->uNumFoodRations >= p2DEvents_minus1__20[13 * (unsigned int)ptr_507BC0->ptr_1C] )
-        if ( (double)pParty->uNumFoodRations >= p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].fPriceMultiplier )
+      }
+      break;
+    }
+    case DIALOG_SHOP_ARCOMAGE_102:
+    {
+      __debugbreak;
+      pOutString = pFontArrus;
+      strcpy(pTmpBuf, pNPCTopics[354].pText);
+      dialog_window.uFrameWidth = 460;
+      dialog_window.uFrameZ = 452;
+      pTextHeight = pFontArrus->CalcTextHeight(pTmpBuf, &dialog_window, 12, 0) + 7;
+      if ( 352 - pTextHeight < 8 )
+      {
+        pOutString = pFontCreate;
+        pTextHeight = pFontCreate->CalcTextHeight(pTmpBuf, &dialog_window, 12, 0) + 7;
+      }
+      auto pTex = (uTextureID_Leather != -1 ? &pIcons_LOD->pTextures[uTextureID_Leather] : 0);
+      pRenderer->_4A6A68(8, 352 - pTextHeight, pTex, (pTex ? pTex->uTextureHeight : 26) - pTextHeight);
+      pRenderer->DrawTextureIndexed(8, 347 - pTextHeight, pTexture_591428);
+      v63 = FitTextInAWindow(pTmpBuf, pOutString, &dialog_window, 0xCu, 0);
+      window_SpeakInHouse->DrawText(pOutString, 12, 354 - pTextHeight, 0, v63, 0, 0, 0);
+      break;
+    }
+    case DIALOG_SHOP_ARCOMAGE_103:
+    {
+      __debugbreak;
+      strcpy(pTmpBuf, pNPCTopics[(uint)window_SpeakInHouse->ptr_1C + 247].pText);
+      dialog_window.uFrameWidth = 460;
+      dialog_window.uFrameZ = 452;
+      v61 = pFontArrus->CalcTextHeight(pTmpBuf, &dialog_window, 12, 0);
+      pTextHeight = v61 + 7;
+      auto pTex = (uTextureID_Leather != -1 ? &pIcons_LOD->pTextures[uTextureID_Leather] : nullptr);
+      pRenderer->_4A6A68(8, 352 - (v61 + 7), pTex, (pTex ? pTex->uTextureHeight : 26) - (v61 + 7));
+      pRenderer->DrawTextureIndexed(8, 347 - pTextHeight, pTexture_591428);
+      v63 = FitTextInAWindow(pTmpBuf, pFontArrus, &dialog_window, 0xCu, 0);
+      window_SpeakInHouse->DrawText(pFontArrus, 12, 354 - pTextHeight, 0, v63, 0, 0, 0);
+      break;
+    }
+    case DIALOG_SHOP_ARCOMAGE_RESULT:
+    {
+      if ( pArcomageGame->bGameInProgress == 1 )
+        return;
+      if ( pArcomageGame->uGameResult )
+      {
+        if ( pArcomageGame->uGameResult == 1 )
+          v72 = pGlobalTXT_LocalizationStrings[640];// You won!
+        else
+          v72 = pGlobalTXT_LocalizationStrings[641];// You lost!
+      }
+      else
+      {
+        v72 = pGlobalTXT_LocalizationStrings[639];// A tie!
+      }
+      strcpy(pTmpBuf, v72);
+      v66 = (174 - pFontArrus->CalcTextHeight(pTmpBuf, &dialog_window, 0, 0)) / 2 + 138;
+      dialog_window.DrawTitleText(pFontArrus, 0, v66, pColorYellow, pTmpBuf, 3);
+      break;
+    }
+    case DIALOG_SHOP_REST:
+    {
+      if ( pParty->uNumGold >= (unsigned int)pOutString )
+      {
+        Party::TakeGold((unsigned int)pOutString);
+        v27 = (int)window_SpeakInHouse->ptr_1C;
+        HousePlaySomeSound((unsigned int)window_SpeakInHouse->ptr_1C, 2);
+        dialog_menu_id = 0;
+        sub_4BD8B5();
+        sub_4B1D27();
+        pVideoPlayer->Unload();
+        window_SpeakInHouse->Release();
+        window_SpeakInHouse = 0;
+        if ( pMessageQueue_50CBD0->uNumMessages )
+          pMessageQueue_50CBD0->uNumMessages = pMessageQueue_50CBD0->pMessages[0].field_8 != 0;
+        pMessageQueue_50CBD0->pMessages[0].eType = UIMSG_OpenRestUI;
+        pMessageQueue_50CBD0->pMessages[0].param = v27;
+        pMessageQueue_50CBD0->pMessages[0].field_8 = 1;
+        ++pMessageQueue_50CBD0->uNumMessages;
+        return;
+      }
+      ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2);
+      HousePlaySomeSound((unsigned int)window_SpeakInHouse->ptr_1C, 4);
+      pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, v5, 0);
+      break;
+    }
+    case DIALOG_SHOP_SKILLS:
+    {
+      if ( !sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
+        return;
+      v0 = 0;
+      v9 = (signed __int64)(p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].flt_24 * 500.0);
+      pItemNum = v9 * (100 - pPlayer->GetMerchant()) / 100;
+      if ( pItemNum < v9 / 3 )
+        pItemNum = v9 / 3;
+      pNumActiveItem = pDialogueWindow->pStartingPosActiveItem;
+      all_text_height = 0;
+      if ( pNumActiveItem < pNumActiveItem + pDialogueWindow->pNumPresenceButton )
+      {
+        do
         {
-          ShowStatusBarString(pGlobalTXT_LocalizationStrings[140], 2u);
-          if ( uActiveCharacter )
-            pPlayers[uActiveCharacter]->PlaySound(SPEECH_67, 0);
-          pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, v5, 0);
+          v12 = pDialogueWindow->GetControl(pNumActiveItem)->uControlParam - 36;
+          if ( byte_4ED970_skill_learn_ability_by_class_table[pPlayer->classType][v12] && !pPlayer->pActiveSkills[v12] )
+          {
+            all_text_height = pFontArrus->CalcTextHeight(pSkillNames[v12], &dialog_window, 0, 0);
+            v0++;
+          }
+          ++pNumActiveItem;
+        }
+        while ( pNumActiveItem < pDialogueWindow->pStartingPosActiveItem + pDialogueWindow->pNumPresenceButton );
+        if ( v0 )
+        {
+          sprintf(pTmpBuf, pGlobalTXT_LocalizationStrings[401], pItemNum);
+          dialog_window.DrawTitleText(pFontArrus, 0, 0x92u, 0, pTmpBuf, 3);
+          v91 = (149 - all_text_height) / v0;
+          if ( (149 - all_text_height) / v0 > 32 )
+            v91 = 32;
+          v14 = (149 - v0 * v91 - all_text_height) / 2 - v91 / 2 + 162;
+          pNumActiveItem = pDialogueWindow->pStartingPosActiveItem;
+          if ( pNumActiveItem < pNumActiveItem + pDialogueWindow->pNumPresenceButton )
+          {
+            pItemNum = 2;
+            do
+            {
+              pButton = pDialogueWindow->GetControl(pItemNum);
+              v17 = pButton->uControlParam - 36;
+              if ( !byte_4ED970_skill_learn_ability_by_class_table[pPlayer->classType][v17] || pPlayer->pActiveSkills[v17] )
+              {
+                pButton->uW = 0;
+                pButton->uHeight = 0;
+                pButton->uY = 0;
+              }
+              else
+              {
+                pButton->uY = v91 + v14;
+                pTextHeight = pFontArrus->CalcTextHeight(pSkillNames[v17], &dialog_window, 0, 0);
+                pButton->uHeight = pTextHeight;
+                v14 = pTextHeight + pButton->uY - 1;
+                pButton->uW = v14;
+                pColorText = pColorYellow;
+                if ( pDialogueWindow->pCurrentPosActiveItem != pItemNum )
+                  pColorText = pColorWhite;
+                dialog_window.DrawTitleText(pFontArrus, 0, pButton->uY, pColorText, pSkillNames[v17], 3);
+              }
+              pNumActiveItem = pDialogueWindow->pStartingPosActiveItem + pDialogueWindow->pNumPresenceButton;
+              pItemNum++;
+            }
+            while ( pItemNum < pNumActiveItem );
+          }
           return;
         }
-        if ( pParty->uNumGold >= v7 )
-        {
-          Party::TakeGold(v7);
-          //pParty->uNumFoodRations = (signed __int64)p2DEvents_minus1__20[13 * (unsigned int)ptr_507BC0->ptr_1C];
-          pParty->uNumFoodRations = (signed __int64)p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].fPriceMultiplier;
-          HousePlaySomeSound((unsigned int)window_SpeakInHouse->ptr_1C, 3);
-          v5 = 1;
-//LABEL_43:
-          pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, v5, 0);
-          return;
-          //goto LABEL_51;
-        }
-		ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2u);
-        HousePlaySomeSound((unsigned int)window_SpeakInHouse->ptr_1C, 4);
+      }
+      sprintf(pTmpBuf, pGlobalTXT_LocalizationStrings[544], pPlayer->pName, pClassNames[pPlayer->classType]);
+      strcat(pTmpBuf, "\n \n");
+      strcat(pTmpBuf, pGlobalTXT_LocalizationStrings[528]);
+      pTextHeight = (174 - pFontArrus->CalcTextHeight(pTmpBuf, &dialog_window, 0, 0)) / 2 + 138;
+      dialog_window.DrawTitleText(pFontArrus, 0, pTextHeight, pColorYellow, pTmpBuf, 3);
+      return;
+    }
+    case DIALOG_SHOP_BYE_FOOD:
+    {
+      *(_QWORD *)Str = pParty->uNumFoodRations;
+      //if ( (double)pParty->uNumFoodRations >= p2DEvents_minus1__20[13 * (unsigned int)ptr_507BC0->ptr_1C] )
+      if ( (double)pParty->uNumFoodRations >= p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].fPriceMultiplier )
+      {
+        ShowStatusBarString(pGlobalTXT_LocalizationStrings[140], 2);
+        if ( uActiveCharacter )
+          pPlayers[uActiveCharacter]->PlaySound(SPEECH_67, 0);
         pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, v5, 0);
-		break;
-		}
-	case 1:
-		{
-		if ( !sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
-		  return;
-		v28 = *(int *)v84;
-		if ( pDialogueWindow->pCurrentPosActiveItem != 2 )
-		  v28 = v81;
-		sprintf(Dest, format_4E2DC8, v28);
-		sprintf(pTmpBuf2, pGlobalTXT_LocalizationStrings[178], pOutString);
-		strcat(Dest, pTmpBuf2);
-		v90 = pFontArrus->CalcTextHeight(Dest, &v79, 0, 0);
-		strcat(Dest, "\n \n");
-		v29 = *(int *)v84;
-		if ( pDialogueWindow->pCurrentPosActiveItem != 3 )
-		  v29 = v81;
-		sprintf(a1, format_4E2DC8, v29);
-		sprintf(pTmpBuf2,
-		  pGlobalTXT_LocalizationStrings[86],
-		  //(signed __int64)p2DEvents_minus1__20[13 * (unsigned int)ptr_507BC0->ptr_1C],
-		  (signed __int64)p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].fPriceMultiplier,
-		  v83);
-		strcat(a1, pTmpBuf2);
-		v88 = pFontArrus->CalcTextHeight(a1, &v79, 0, 0);
-		strcat(a1, "\n \n");
-		v30 = *(int *)v84;
-		if ( pDialogueWindow->pCurrentPosActiveItem != 4 )
-		  v30 = v81;
-		sprintf(v77, format_4E2DC8, v30);
-		strcat(v77, pGlobalTXT_LocalizationStrings[160]);
-		v82 = pFontArrus->CalcTextHeight(v77, &v79, 0, 0);
-		strcat(v77, "\n \n");
-		v75[0] = 0;
-		v87 = 0;
-		v31 = (signed int)window_SpeakInHouse->ptr_1C;
-		if ( v31 >= 108 && v31 <= 120 )
-		{
-		  v32 = *(int *)v84;
-		  if ( pDialogueWindow->pCurrentPosActiveItem != 5 )
-			v32 = v81;
-		  sprintf(v75, format_4E2DC8, v32);
-		  strcat(v75, pGlobalTXT_LocalizationStrings[611]);
-		  v87 = pFontArrus->CalcTextHeight(v75, &v79, 0, 0);
-		}
-		v33 = pDialogueWindow;
-		Str[1] = (char *)pDialogueWindow;
-		v34 = pDialogueWindow->pStartingPosActiveItem;
-		v35 = v34 + pDialogueWindow->pNumPresenceButton;
-		v36 = LOBYTE(pFontArrus->uFontHeight) - 3;
-		v37 = -pDialogueWindow->pNumPresenceButton < 0;
-		pOutString = (GUIFont *)pDialogueWindow->pStartingPosActiveItem;
-		if ( !(v37 ^ __OFSUB__(v34, v35)) )
-		{
-	//LABEL_75:
-		  sprintf(pTmpBuf, "%s%s%s%s", &Dest, &a1, &v77, &v75);
-		  v71 = 3;
-		  v69 = pTmpBuf;
-		  v67 = 0;
-		  v66 = 146;
-	//LABEL_98:
-		  v79.DrawTitleText(pFontArrus, 0, v66, v67, v69, v71);
-		  return;
-		}
-		while ( 1 )
-		{
-		  v38 = v33->GetControl((unsigned int)pOutString);
-		  if ( v38->uControlParam == 15 )
-		  {
-			v46 = v90;
-			v38->uHeight = v90;
-			v38->uY = 146;
-			v41 = v46 + 145;
-			v38->uW = v41;
-		  }
-		  else if ( v38->uControlParam == 16 )
-		  {
-			v44 = v88;
-			v45 = v90 + v36 + 146;
-			v38->uHeight = v88;
-			v38->uY = v45;
-			v41 = v45 + v44 - 1;
-			v38->uW = v41;
-		  }
-		  else if ( v38->uControlParam == 96 )
-		  {
-			v42 = v90 + v88 + 2 * v36 + 146;
-			v43 = v82;
-			v38->uY = v42;
-			v38->uHeight = v43;
-			v41 = v43 + v42 - 1;
-			v38->uW = v41;
-		  }
-		  else if ( v38->uControlParam == 101 )
-		  {
-			v39 = v90 + 3 * v36 + v87 + v88 + 146;
-			v33 = (GUIWindow *)Str[1];
-			v40 = v87;
-			v38->uHeight = v87;
-			v38->uY = v39;
-			v41 = v39 + v40 - 1;
-	//LABEL_73:
-			v38->uW = v41;
-		  }
-		  v47 = v33->pStartingPosActiveItem;
-		  pOutString = (GUIFont *)((char *)pOutString + 1);
-		  if ( (signed int)pOutString >= v33->pNumPresenceButton + v47 )
-		  {
-			  sprintf(pTmpBuf, "%s%s%s%s", &Dest, &a1, &v77, &v75);
-			  v71 = 3;
-			  v69 = pTmpBuf;
-			  v67 = 0;
-			  v66 = 146;
-			  v79.DrawTitleText(pFontArrus, 0, v66, v67, v69, v71);
-			  return;
-		  }
-		}
-		break;
-		}
-	case 101:
-		{
-		if ( sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
-		{
-			v48 = 2;
-			pShopOptions[0] = pGlobalTXT_LocalizationStrings[620];
-			pOutString = 0;
-			pShopOptions[1] = pGlobalTXT_LocalizationStrings[622];
-			if ( pParty->HasItem(0x28Bu) )
-			{
-				pShopOptions[2] = pGlobalTXT_LocalizationStrings[621];
-				v48 = 3;
-			}
-			for ( i = 0; i < v48; ++i )
-			{
-				v50 = pFontArrus->CalcTextHeight(pShopOptions[i], &v79, 0, 0);
-				pOutString = (GUIFont *)((char *)pOutString + v50);
-			}
-			v86 = (174 - (signed int)pOutString) / v48;
-			v51 = pDialogueWindow;
-			v52 = 174 - v48 * (174 - (signed int)pOutString) / v48 - (signed int)pOutString;
-			v53 = v52 - HIDWORD(v52);
-			LODWORD(v52) = pDialogueWindow->pStartingPosActiveItem;
-			HIDWORD(v52) = v52 + pDialogueWindow->pNumPresenceButton;
-			v54 = (v53 >> 1) - v86 / 2 + 138;
-			v37 = -pDialogueWindow->pNumPresenceButton < 0;
-			v89 = pDialogueWindow->pStartingPosActiveItem;
-			if ( v37 ^ __OFSUB__((int)v52, HIDWORD(v52)) )
-			{
-				v85 = (Player *)2;
-				pOutString = (GUIFont *)pShopOptions;
-				do
-				{
-					v55 = v51->GetControl(v89);
-					v56 = (const char **)pOutString;
-					v55->uY = v86 + v54;
-					v57 = pFontArrus->CalcTextHeight(*v56, &v79, 0, 0);
-					v58 = v55->uY;
-					v59 = v85;
-					v55->uHeight = v57;
-					v54 = v57 + v58 - 1;
-					v55->uW = v54;
-					v60 = v84[0];
-					if ( (Player *)pDialogueWindow->pCurrentPosActiveItem != v59 )
-						v60 = v81;
-					v79.DrawTitleText(pFontArrus, 0, v58, v60, *(const char **)&pOutString->cFirstChar, 3u);
-					v51 = pDialogueWindow;
-					v85 = (Player *)((char *)v85 + 1);
-					pOutString = (GUIFont *)((char *)pOutString + 4);
-					++v89;
-				}
-				while ( v89 < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem );
-			}
-		}
-		break;
-		}
-	default:
-		{
-		break;
-		}
+        return;
+      }
+      if ( pParty->uNumGold >= v7 )
+      {
+        Party::TakeGold(v7);
+        //pParty->uNumFoodRations = (signed __int64)p2DEvents_minus1__20[13 * (unsigned int)ptr_507BC0->ptr_1C];
+        pParty->uNumFoodRations = (signed __int64)p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].fPriceMultiplier;
+        HousePlaySomeSound((unsigned int)window_SpeakInHouse->ptr_1C, 3);
+        pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
+        return;
+      }
+      ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2);
+      HousePlaySomeSound((unsigned int)window_SpeakInHouse->ptr_1C, 4);
+      pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, v5, 0);
+      break;
+    }
+    case DIALOG_SHOP_ARCOMAGE_MAIN:
+    {
+      if ( sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
+      {
+        v48 = 2;
+        pShopOptions[0] = pGlobalTXT_LocalizationStrings[620];
+        pShopOptions[1] = pGlobalTXT_LocalizationStrings[622];
+        pOutString = 0;
+        if ( pParty->HasItem(0x28Bu) )
+        {
+          pShopOptions[2] = pGlobalTXT_LocalizationStrings[621];
+          v48 = 3;
+        }
+        for ( i = 0; i < v48; ++i )
+          all_text_height = pFontArrus->CalcTextHeight(pShopOptions[i], &dialog_window, 0, 0);
+        all_text_height = (174 - all_text_height) / v48;
+        pNumActiveItem = pDialogueWindow->pStartingPosActiveItem;
+        v54 = (174 - v48 * (174 - all_text_height) / v48 - all_text_height) / 2 - (174 - all_text_height) / v48 / 2 + 138;
+        v37 = -pDialogueWindow->pNumPresenceButton < 0;
+        if ( v37 ^ pNumActiveItem < pNumActiveItem + pDialogueWindow->pNumPresenceButton )
+        {
+          pItemNum = 2;
+          pNumString = 0;
+          do
+          {
+            pButton = pDialogueWindow->GetControl(pItemNum);
+            pButton->uY = all_text_height + v54;
+            pTextHeight = pFontArrus->CalcTextHeight((const char *)pShopOptions[pNumString], &dialog_window, 0, 0);
+            pButton->uHeight = pTextHeight;
+            v54 = pButton->uY + pTextHeight - 1;
+            pButton->uW = v54;
+            pColorText = pColorYellow;
+            if ( pDialogueWindow->pCurrentPosActiveItem != pItemNum )
+              pColorText = pColorWhite;
+            dialog_window.DrawTitleText(pFontArrus, 0, pButton->uY, pColorText, *(const char **)&pOutString->cFirstChar, 3);
+            pItemNum++;
+            pNumActiveItem = pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem;
+          }
+          while ( pItemNum < pNumActiveItem );
+        }
+      }
+      break;
+    }
+    default:
+    {
+      break;
+    }
   }
 }
 
@@ -1449,12 +1362,10 @@
   int v0; // ebx@1
   int pNumActiveItem; // eax@6
   signed int v2; // esi@8
-  //unsigned int v3; // ebx@10
   ItemGen *v4; // eax@11
   char *v5; // ecx@12
   unsigned __int8 v6; // dl@13
   char *v7; // edx@14
-  //int v8; // eax@15
   int v9; // ST08_4@16
   int v10; // eax@16
   signed int v11; // esi@18
@@ -1463,36 +1374,28 @@
   int v14; // edi@23
   char **v15; // esi@23
   int v16; // eax@24
-  GUIWindow *v17; // ecx@25
-  int v18; // edx@25
+  //int v18; // edx@25
   int v19; // edi@25
   unsigned __int8 v20; // sf@25
   GUIButton *pButton; // esi@27
   int pNewItem; // eax@27
-  //int v23; // eax@27
   unsigned int v24; // ecx@27
   int v25; // edx@27
-  unsigned __int16 v26; // ax@27
+  unsigned int pColorText; // ax@27
   signed int v27; // esi@32
   int v28; // ST08_4@36
   int v29; // eax@36
-  GUIWindow *v30; // edi@41
-  //void *v31; // eax@41
   signed int v32; // esi@41
   unsigned int v33; // esi@43
   int v34; // eax@43
   unsigned int v35; // eax@44
   int v36; // eax@46
   __int32 v37; // ecx@51
-  GUIButton *v38; // eax@53
-  GUIButton *v39; // esi@53
   int v40; // eax@53
   char *v41; // eax@55
-  //int v42; // eax@55
   unsigned int v43; // ecx@55
   const char **v44; // edx@55
   int v45; // eax@55
-  unsigned __int16 v46; // ax@55
   int v47; // eax@59
   const char **v48; // eax@63
   unsigned int v49; // esi@65
@@ -1514,16 +1417,12 @@
   int all_text_height; // esi@96
   char **v66; // edi@96
   int v67; // eax@97
-  GUIWindow *v68; // ecx@98
   int v69; // edx@98
   int v70; // edi@98
   int v71;
   const char **v72; // eax@100
   int pTextHeight; // eax@100
   unsigned int v74; // ecx@100
-  Player *v75; // edx@100
-  unsigned __int16 v76; // ax@100
-  GUIWindow *v77; // [sp-18h] [bp-110h]@14
   int v78; // [sp-14h] [bp-10Ch]@14
   ItemGen *v79; // [sp-10h] [bp-108h]@12
   int v80; // [sp-10h] [bp-108h]@14
@@ -1550,7 +1449,7 @@
   GUIWindow dialog_window; // [sp+7Ch] [bp-7Ch]@1
   char *Str; // [sp+D0h] [bp-28h]@55
   __int32 v103; // [sp+D4h] [bp-24h]@25
-  int pColor2; // [sp+D8h] [bp-20h]@1
+  int pColorYellow; // [sp+D8h] [bp-20h]@1
   int pColorWhite; // [sp+DCh] [bp-1Ch]@1
   POINT v106; // [sp+E0h] [bp-18h]@8
   Player *pPlayer; // [sp+E8h] [bp-10h]@1
@@ -1565,7 +1464,7 @@
   dialog_window.uFrameWidth = 148;
   dialog_window.uFrameZ = 334;
   pColorWhite = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0xFFu, 0xFFu, 0xFFu);
-  pColor2 = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0xE1u, 0xCDu, 0x23u);
+  pColorYellow = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0xE1u, 0xCDu, 0x23u);
   switch(dialog_menu_id)
   {
     case DIALOG_SHOP_MAIN:
@@ -1582,10 +1481,9 @@
           all_text_height += pFontArrus->CalcTextHeight(pShopOptions[i], &dialog_window, 0, 0);
         v103 = (174 - all_text_height) / 4;
         pNumActiveItem = pDialogueWindow->pStartingPosActiveItem;
-        v18 = pNumActiveItem + pDialogueWindow->pNumPresenceButton;
         v19 = (174 - 4 * (174 - all_text_height) / 4 - all_text_height) / 2 - (174 - all_text_height) / 4 / 2 + 138;
         v20 = -pDialogueWindow->pNumPresenceButton < 0;
-        if ( v20 ^ pNumActiveItem > v18 )
+        if ( v20 ^ pNumActiveItem > pNumActiveItem + pDialogueWindow->pNumPresenceButton )
         {
           pItemNum = 2;
           pNumString = 0;
@@ -1597,10 +1495,10 @@
             pButton->uHeight = pTextHeight;
             v19 = pButton->uY + pTextHeight - 1;
             pButton->uW = v19;
-            v26 = pColor2;
+            pColorText = pColorYellow;
             if ( pDialogueWindow->pCurrentPosActiveItem != pItemNum )
-              v26 = pColorWhite;
-            dialog_window.DrawTitleText(pFontArrus, 0, pButton->uY, v26, (const char *)pShopOptions[pNumString], 3);
+              pColorText = pColorWhite;
+            dialog_window.DrawTitleText(pFontArrus, 0, pButton->uY, pColorText, (const char *)pShopOptions[pNumString], 3);
             ++pItemNum;
             ++pNumString;
             pNumActiveItem = pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem;
@@ -1774,10 +1672,9 @@
         all_text_height += pFontArrus->CalcTextHeight(pShopOptions[i], &dialog_window, 0, 0);
       v103 = (174 - all_text_height) / 3;
       pNumActiveItem = pDialogueWindow->pStartingPosActiveItem;
-      v18 = pNumActiveItem + pDialogueWindow->pNumPresenceButton;
       v70 = (3 * (58 - (signed int)v103) - all_text_height) / 2 - ((174 - all_text_height) / 3) / 2 + 138;
       v20 = -pDialogueWindow->pNumPresenceButton < 0;
-      if ( v20 ^ pNumActiveItem > v18 )
+      if ( v20 ^ pNumActiveItem > pNumActiveItem + pDialogueWindow->pNumPresenceButton )
       {
         pItemNum = 2;
         pNumString = 0;
@@ -1789,10 +1686,10 @@
           pButton->uHeight = pTextHeight;
           v70 = pButton->uY + pTextHeight - 1;
           pButton->uW = v70;
-          v76 = pColor2;
+          pColorText = pColorYellow;
           if ( pDialogueWindow->pCurrentPosActiveItem != pItemNum )
-            v76 = pColorWhite;
-          dialog_window.DrawTitleText(pFontArrus, 0, pButton->uY, v76, (const char *)pShopOptions[pNumString], 3);
+            pColorText = pColorWhite;
+          dialog_window.DrawTitleText(pFontArrus, 0, pButton->uY, pColorText, (const char *)pShopOptions[pNumString], 3);
           ++pItemNum;
           ++pNumString;
           pNumActiveItem = pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem;
@@ -1902,7 +1799,7 @@
         strcat(pTmpBuf, "\n \n");
         strcat(pTmpBuf, pGlobalTXT_LocalizationStrings[528]);
         pTextHeight = pFontArrus->CalcTextHeight(pTmpBuf, &dialog_window, 0, 0);
-        dialog_window.DrawTitleText(pFontArrus, 0, (174 - pTextHeight) / 2 + 138, pColor2, pTmpBuf, 3);
+        dialog_window.DrawTitleText(pFontArrus, 0, (174 - pTextHeight) / 2 + 138, pColorYellow, pTmpBuf, 3);
         return;
       }
       do
@@ -1922,7 +1819,7 @@
         strcat(pTmpBuf, "\n \n");
         strcat(pTmpBuf, pGlobalTXT_LocalizationStrings[528]);
         pTextHeight = pFontArrus->CalcTextHeight(pTmpBuf, &dialog_window, 0, 0);
-        dialog_window.DrawTitleText(pFontArrus, 0, (174 - pTextHeight) / 2 + 138, pColor2, pTmpBuf, 3);
+        dialog_window.DrawTitleText(pFontArrus, 0, (174 - pTextHeight) / 2 + 138, pColorYellow, pTmpBuf, 3);
         return;
       }
       sprintf(pTmpBuf, pGlobalTXT_LocalizationStrings[401], pItemNum);
@@ -1952,10 +1849,10 @@
             pButton->uHeight = pTextHeight;
             v37 = pButton->uY + pTextHeight - 1;
             pButton->uW = v37;
-            v46 = pColor2;
+            pColorText = pColorYellow;
             if ( pDialogueWindow->pCurrentPosActiveItem != pItemNum )
-              v46 = pColorWhite;
-            dialog_window.DrawTitleText(pFontArrus, 0, pButton->uY, v46, pSkillNames[v40], 3);
+              pColorText = pColorWhite;
+            dialog_window.DrawTitleText(pFontArrus, 0, pButton->uY, pColorText, pSkillNames[v40], 3);
           }
           pNumActiveItem = pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem;
           pItemNum++;
@@ -1982,40 +1879,30 @@
 {
   int v0;
   int pNumActiveItem; // eax@7
-  //GUIWindow *v2; // edi@9
-  //unsigned int v3; // ebx@9
-  //void *v4; // eax@9
   signed int v5; // esi@9
   unsigned int v6; // esi@11
   int v7; // eax@11
   unsigned int v8; // eax@12
   int v9; // eax@14
   int v10; // ecx@19
-  GUIButton *v11; // eax@21
-  GUIButton *v12; // esi@21
   int v13; // eax@21
   char *v14; // eax@23
   int v15; // eax@23
   unsigned int v16; // ecx@23
   int v17; // edx@23
   int v18; // eax@23
-  unsigned __int16 v19; // ax@23
   int v20; // eax@27
   char *v21; // edx@29
   int v22; // esi@30
   char **v23; // edi@30
   int v24; // eax@31
-  GUIWindow *v25; // ecx@32
   int v26; // edx@32
   int v27; // edi@32
   unsigned __int8 v28; // sf@32
-  GUIButton *v29; // esi@34
   const char **v30; // eax@34
   int v31; // eax@34
   unsigned int v32; // ecx@34
-  Player *v33; // edx@34
   int v34; // eax@34
-  unsigned __int16 v35; // ax@34
   signed int v36; // esi@39
   ItemGen *v37; // eax@42
   char *v38; // ecx@43
@@ -2062,9 +1949,7 @@
   const char **v79; // eax@129
   int pTextHeight; // eax@129
   unsigned int v81; // ecx@129
-  Player *v82; // edx@129
-  unsigned __int16 v83; // ax@129
-  GUIWindow *v84; // [sp-18h] [bp-F0h]@29
+  unsigned int pColorText; // ax@129
   int v85; // [sp-14h] [bp-ECh]@29
   int v86; // [sp-10h] [bp-E8h]@29
   ItemGen *v87; // [sp-10h] [bp-E8h]@43
@@ -2086,7 +1971,7 @@
   POINT a2; // [sp+54h] [bp-84h]@39
   GUIWindow dialog_window; // [sp+5Ch] [bp-7Ch]@1
   int v105; // [sp+B0h] [bp-28h]@19
-  int pColor2; // [sp+B4h] [bp-24h]@1
+  int pColorYellow; // [sp+B4h] [bp-24h]@1
   int Str; // [sp+B8h] [bp-20h]@23
   int pColorWhite; // [sp+BCh] [bp-1Ch]@1
   __int32 v109; // [sp+C0h] [bp-18h]@39
@@ -2102,7 +1987,7 @@
   dialog_window.uFrameWidth = 148;
   dialog_window.uFrameZ = 334;
   pColorWhite = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0xFFu, 0xFFu, 0xFFu);
-  pColor2 = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0xE1u, 0xCDu, 0x23u);
+  pColorYellow = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0xE1u, 0xCDu, 0x23u);
   switch(dialog_menu_id)
   {
     case DIALOG_SHOP_MAIN:
@@ -2133,11 +2018,10 @@
             pButton->uHeight = pTextHeight;
             v77 = pButton->uY + pTextHeight - 1;
             pButton->uW = v77;
-            v83 = pColor2;
+            pColorText = pColorYellow;
             if ( pDialogueWindow->pCurrentPosActiveItem != pItemNum )
-              v83 = pColorWhite;
-            dialog_window.DrawTitleText(pFontArrus, 0, pButton->uY, v83, (const char *)pShopOptions[pNumString], 3);
-            pPlayer = (Player *)((char *)pPlayer + 1);
+              pColorText = pColorWhite;
+            dialog_window.DrawTitleText(pFontArrus, 0, pButton->uY, pColorText, (const char *)pShopOptions[pNumString], 3);
             ++pItemNum;
             ++pNumString;
             pNumActiveItem = pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem;
@@ -2153,7 +2037,6 @@
       v114 = 0;
       do
       {
-        // if ( pParty->field_777C[9 * (v114 + 12 * (unsigned int)window_SpeakInHouse->ptr_1C)] )
         if ( pParty->StandartItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][v114].uItemID);
         {
           v46 = ItemsInShopTexture[v114];
@@ -2181,7 +2064,6 @@
       v114 = 0;
       do
       {
-        //  if ( pParty->field_777C[9 * (v114 + 12 * (unsigned int)window_SpeakInHouse->ptr_1C) + 54] )
         if ( pParty->StandartItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][v114+1].uItemID);
         {
           v50 = ItemsInShopTexture[v114 + 6];
@@ -2215,7 +2097,6 @@
         v109 = 0;
         do
         {
-          // if ( pParty->field_777C[9 * (v62 + 12 * (unsigned int)window_SpeakInHouse->ptr_1C)] )
           if ( pParty->StandartItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][v62].uItemID);
             ++v109;
           ++v62;
@@ -2247,7 +2128,6 @@
         if ( pRenderer->pActiveZBuffer[pNumActiveItem] & 0xFFFF )
         {
           v67 = (pRenderer->pActiveZBuffer[pNumActiveItem] & 0xFFFF) - 1;
-          //  v69 = 9 * (v67 + 12 * v68);
           v70 = (ItemGen *)&pParty->StandartItemsInShops[(int)window_SpeakInHouse->ptr_1C][v67];
           if ( dialog_menu_id != 2 )
             v70 = &pParty->SpecialItemsInShops[(int)window_SpeakInHouse->ptr_1C][v67];//v70 = (ItemGen *)&pParty->field_C59C[v69 + 724];
@@ -2338,10 +2218,10 @@
           pButton->uHeight = pTextHeight;
           v27 = pButton->uY + pTextHeight - 1;
           pButton->uW = v27;
-          v35 = pColor2;
+          pColorText = pColorYellow;
           if ( pDialogueWindow->pCurrentPosActiveItem != pItemNum )
-            v35 = pColorWhite;
-          dialog_window.DrawTitleText(pFontArrus, 0, pButton->uY, v35, (const char *)pShopOptions[pNumString], 3);
+            pColorText = pColorWhite;
+          dialog_window.DrawTitleText(pFontArrus, 0, pButton->uY, pColorText, (const char *)pShopOptions[pNumString], 3);
           ++pItemNum;
           ++pNumString;
           pNumActiveItem = pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem;
@@ -2356,7 +2236,6 @@
       v114 = 0;
       do
       {
-        //if ( pParty->field_C59C[9 * (v114 + 12 * (unsigned int)window_SpeakInHouse->ptr_1C) + 724] )
         if (pParty->SpecialItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][v114].uItemID)
         {
           v54 = ItemsInShopTexture[v114];
@@ -2387,7 +2266,6 @@
       v114 = 0;
       do
       {
-        // if ( pParty->field_C59C[9 * (v114 + 12 * (unsigned int)window_SpeakInHouse->ptr_1C) + 778] )   //weak 
         if (pParty->SpecialItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][(signed int)v114].uItemID) //not itemid
         {
           v58 = ItemsInShopTexture[v114 + 6];
@@ -2421,7 +2299,6 @@
         v109 = 0;
         do
         {
-          //if ( pParty->field_C59C[9 * (v62 + 12 * (unsigned int)window_SpeakInHouse->ptr_1C) + 724] )
           if (pParty->SpecialItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][v62].uItemID)
             ++v109;
           ++v62;
@@ -2479,7 +2356,6 @@
       if (!sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win())
         return;
       all_text_height = 0;
-      //v5 = (signed __int64)(*(float *)&p2DEvents_minus1__24[13 * (signed int)v4] * 500.0);
       v5 = (signed __int64)(p2DEvents[(signed int)window_SpeakInHouse->ptr_1C - 1].flt_24 * 500.0);
       pItemNum = v5 * (100 - pPlayer->GetMerchant()) / 100;
       if ( pItemNum < v5 / 3 )
@@ -2492,7 +2368,7 @@
         strcat(pTmpBuf, "\n \n");
         strcat(pTmpBuf, pGlobalTXT_LocalizationStrings[528]);
         v40 = pFontArrus->CalcTextHeight(pTmpBuf, &dialog_window, 0, 0);
-        dialog_window.DrawTitleText(pFontArrus, 0, (174 - v40) / 2 + 138, pColor2, pTmpBuf, 3);
+        dialog_window.DrawTitleText(pFontArrus, 0, (174 - v40) / 2 + 138, pColorYellow, pTmpBuf, 3);
         return;
       }
       do
@@ -2512,7 +2388,7 @@
         strcat(pTmpBuf, "\n \n");
         strcat(pTmpBuf, pGlobalTXT_LocalizationStrings[528]);
         v40 = pFontArrus->CalcTextHeight(pTmpBuf, &dialog_window, 0, 0);
-        dialog_window.DrawTitleText(pFontArrus, 0, (174 - v40) / 2 + 138, pColor2, pTmpBuf, 3);
+        dialog_window.DrawTitleText(pFontArrus, 0, (174 - v40) / 2 + 138, pColorYellow, pTmpBuf, 3);
         return;
       }
       if ( v114 )
@@ -2544,10 +2420,10 @@
               pButton->uHeight = pTextHeight;
               v105 = pButton->uY + pTextHeight - 1;
               pButton->uW = v105;
-              v19 = pColor2;
+              pColorText = pColorYellow;
               if ( pDialogueWindow->pCurrentPosActiveItem != pItemNum )
-                v19 = pColorWhite;
-              dialog_window.DrawTitleText(pFontArrus, 0, pButton->uY, v19, pSkillNames[v13], 3);
+                pColorText = pColorWhite;
+              dialog_window.DrawTitleText(pFontArrus, 0, pButton->uY, pColorText, pSkillNames[v13], 3);
             }
             pNumActiveItem = pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem;
             pItemNum++;
@@ -3953,12 +3829,12 @@
 {
   Player *v0; // ebx@1
   int color2; // eax@1
-  unsigned int v2; // ecx@1
-  int v3; // eax@1
-  signed int v4; // edx@1
-  int v5; // edi@3
-  unsigned int v6; // esi@3
-  void *v7; // ecx@3
+  //unsigned int v2; // ecx@1
+  //int v3; // eax@1
+  //signed int v4; // edx@1
+  unsigned __int64 v5; // edi@3
+  //unsigned int v6; // esi@3
+  //void *v7; // ecx@3
   int v8; // edx@4
   double v9; // st7@6
   signed int v10; // esi@6
@@ -4017,12 +3893,12 @@
   int v63; // [sp-4h] [bp-88h]@52
   char *v64; // [sp-4h] [bp-88h]@63
   GUIWindow v65; // [sp+Ch] [bp-78h]@1
-  __int64 v66; // [sp+60h] [bp-24h]@3
+  //__int64 v66; // [sp+60h] [bp-24h]@3
   unsigned int white; // [sp+68h] [bp-1Ch]@1
   int v68; // [sp+6Ch] [bp-18h]@3
   int v69; // [sp+70h] [bp-14h]@6
-  unsigned int i; // [sp+74h] [bp-10h]@1
-  int v71; // [sp+78h] [bp-Ch]@1
+  //unsigned int i; // [sp+74h] [bp-10h]@1
+  //int v71; // [sp+78h] [bp-Ch]@1
   int v72; // [sp+7Ch] [bp-8h]@16
   int v73; // [sp+80h] [bp-4h]@14
 
@@ -4033,31 +3909,32 @@
   v65.uFrameZ = 334;
   white = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0xFFu, 0xFFu, 0xFFu);
   color2 = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0xE1u, 0xCDu, 0x23u);
-  v2 = v0->uLevel;
-  v71 = color2;
-  v3 = 0;
-  v4 = 0;
-  for ( i = v2; v4 < (signed int)v2; ++v4 )
-    v3 += v4 + 1;
-  v5 = 1000 * v3;
-  v6 = HIDWORD(v0->uExperience);
-  v7 = window_SpeakInHouse->ptr_1C;
-  v68 = (unsigned __int16)word_4F0866[(signed int)v7];
-  v66 = 1000 * v3;
-  if ( (signed __int64)__PAIR__(v6, LODWORD(v0->uExperience)) >= v66 )
+  //v71 = color2;
+  //v2 = v0->uLevel;
+  //v3 = 0;
+  //v4 = 0;
+  //for ( i = v2; v4 < (signed int)v2; ++v4 )
+  //  v3 += v4 + 1;
+  //v5 = 1000 * v3;
+  v5 = 1000ui64 * v0->uLevel * (v0->uLevel + 1) / 2;  // E n = n(n + 1) / 2
+  //v6 = HIDWORD(v0->uExperience);
+  //v7 = window_SpeakInHouse->ptr_1C;
+  v68 = pMaxLevelPerTrainingHallType[(unsigned int)window_SpeakInHouse->ptr_1C - 89];
+  //v66 = 1000 * v3;
+  if (v0->uExperience >= v5)
   {
     v8 = v0->classType % 4 + 1;
     if ( v8 == 4 )
       v8 = 3;
-    v9 = (double)(signed int)i;
-    i = 0;
+    v9 = (double)v0->uLevel;
+    //i = 0;
     v69 = v8;
     //v10 = (signed __int64)(v9 * p2DEvents_minus1__20[13 * (signed int)v7] * (double)v8);
-    v10 = (signed __int64)(v9 * p2DEvents[(signed int)v7 - 1].fPriceMultiplier * (double)v8);
+    v10 = (signed __int64)(v9 * p2DEvents[(signed int)window_SpeakInHouse->ptr_1C - 1].fPriceMultiplier * (double)v8);
     v11 = v10 * (100 - v0->GetMerchant()) / 100;
     if ( v11 < v10 / 3 )
       v11 = v10 / 3;
-    i = v11;
+    //i = v11;
   }
   result = sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win();
   if ( result )
@@ -4072,7 +3949,8 @@
           result = sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win();
           if ( result )
           {
-            i = 0;
+            //i = 0;
+            int _v0 = 0;
             v13 = pDialogueWindow;
             //v14 = (signed __int64)(*(float *)&p2DEvents_minus1__24[13 * (unsigned int)ptr_507BC0->ptr_1C] * 500.0);
             v14 = (signed __int64)(p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].flt_24 * 500.0);
@@ -4090,7 +3968,7 @@
               if ( byte_4ED970_skill_learn_ability_by_class_table[v0->classType][v17] && !v0->pActiveSkills[v17] )
               {
                 v18 = pFontArrus->CalcTextHeight(pSkillNames[v17], &v65, 0, 0);
-                i += v18;
+                _v0 += v18;
                 ++v72;
               }
               ++v15;
@@ -4100,19 +3978,19 @@
             {
               sprintf(pTmpBuf, pGlobalTXT_LocalizationStrings[401], v73);// "Skill Cost: %lu"
               v65.DrawTitleText(pFontArrus, 0, 0x92u, 0, pTmpBuf, 3u);
-              v73 = (signed int)(149 - i) / v72;
+              v73 = (signed int)(149 - _v0) / v72;
               if ( v73 > 32 )
                 v73 = 32;
               result = v13->pStartingPosActiveItem;
-              v19 = (signed int)(149 - v72 * v73 - i) / 2 - v73 / 2 + 162;
-              i = result;
+              v19 = (signed int)(149 - v72 * v73 - _v0) / 2 - v73 / 2 + 162;
+              int _v1 = result;
               v68 = v19;
               if ( result < result + v13->pNumPresenceButton )
               {
                 v72 = 2;
                 do
                 {
-                  v20 = v13->GetControl(i);
+                  v20 = v13->GetControl(_v1);
                   v21 = v20;
                   v22 = v20->uControlParam - 36;
                   if ( !byte_4ED970_skill_learn_ability_by_class_table[v0->classType][v22] || v0->pActiveSkills[v22] )
@@ -4125,24 +4003,24 @@
                   {
                     v23 = pSkillNames[v22];
                     v21->uY = v73 + v68;
-                    HIDWORD(v66) = (int)v23;
+                    //HIDWORD(v66) = (int)v23;
                     v24 = pFontArrus->CalcTextHeight(v23, &v65, 0, 0);
                     v25 = v21->uY;
                     v21->uHeight = v24;
                     v26 = v25 + v24 - 1;
                     v21->uW = v26;
                     v68 = v26;
-                    v27 = v71;
+                    v27 = color2;
                     if ( pDialogueWindow->pCurrentPosActiveItem != v72 )
                       v27 = white;
-                    v65.DrawTitleText(pFontArrus, 0, v25, v27, (char *)HIDWORD(v66), 3u);
+                    v65.DrawTitleText(pFontArrus, 0, v25, v27, v23, 3u);
                   }
                   v28 = v13->pStartingPosActiveItem;
-                  ++i;
+                  ++_v1;
                   result = v13->pNumPresenceButton + v28;
                   ++v72;
                 }
-                while ( (signed int)i < result );
+                while ( (signed int)_v1 < result );
               }
             }
             else
@@ -4152,7 +4030,7 @@
                                                 // "Seek knowledge elsewhere %s the %s"
               strcat(pTmpBuf, "\n \n");
               strcat(pTmpBuf, pGlobalTXT_LocalizationStrings[528]);// "I can offer you nothing further."
-              v29 = v71;
+              v29 = color2;
               v30 = pFontArrus->CalcTextHeight(pTmpBuf, &v65, 0, 0);
               result = (int)v65.DrawTitleText(pFontArrus, 0, (174 - v30) / 2 + 138, v29, pTmpBuf, 3u);
             }
@@ -4163,7 +4041,7 @@
       if ( !sub_4B1784_check_if_player_concious__draw_warning_else_mess_with_dlg_win() )
       {
         v31 = pNPCTopics[122].pText;
-        v32 = v71;
+        v32 = color2;
         v33 = pFontArrus->CalcTextHeight(pNPCTopics[122].pText, &v65, 0, 0);
         v65.DrawTitleText(pFontArrus, 0, (212 - v33) / 2 + 101, v32, v31, 3u);
         result = (int)pDialogueWindow;
@@ -4173,11 +4051,11 @@
       v34 = v0->uLevel;
       if ( v34 < v68 )
       {
-        if ( (signed __int64)v0->uExperience >= v66 )
+        if ( (signed __int64)v0->uExperience >= v5 )
         {
-          if ( pParty->uNumGold >= i )
+          if ( pParty->uNumGold >= v11)
           {
-            Party::TakeGold(i);
+            Party::TakeGold(v11);
             HousePlaySomeSound((unsigned int)window_SpeakInHouse->ptr_1C, 2);
             ++v0->uLevel;
             v0->uSkillPoints += v0->uLevel / 10 + 5;
@@ -4206,7 +4084,7 @@
                 pOutdoor->SetFog();
             }
             v0->PlaySound(SPEECH_87, 0);
-            sprintf(pTmpBuf, pGlobalTXT_LocalizationStrings[430], v0->pName, v0->uLevel, v0->uLevel / 10 + 5);// 
+            sprintfex(pTmpBuf, pGlobalTXT_LocalizationStrings[430], v0->pName, v0->uLevel, v0->uLevel / 10 + 5);// 
                                                 // "%s is now Level %lu and has earned %lu Skill Points!"
             ShowStatusBarString(pTmpBuf, 2u);
             goto LABEL_56;
@@ -4229,12 +4107,12 @@
           pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
           return 1; // void function actually
         }
-        sprintf(pTmpBuf, pGlobalTXT_LocalizationStrings[538], v5 - LODWORD(v0->uExperience), v34 + 1);// 
+        sprintfex(pTmpBuf, pGlobalTXT_LocalizationStrings[538], (unsigned int)(v5 - v0->uExperience), v34 + 1);// 
                                                 // "You need %d more experience to train to level %d"
         v35 = 0;
         v62 = 3;
         v60 = pTmpBuf;
-        v58 = v71;
+        v58 = color2;
         v36 = (212 - pFontArrus->CalcTextHeight(pTmpBuf, &v65, 0, 0)) / 2 + 88;
       }
       else
@@ -4245,7 +4123,7 @@
         v35 = 0;
         v62 = 3;
         v60 = pTmpBuf;
-        v58 = v71;
+        v58 = color2;
         v36 = (212 - pFontArrus->CalcTextHeight(pTmpBuf, &v65, 0, 0)) / 2 + 101;
       }
       v65.DrawTitleText(pFontArrus, v35, v36, v58, v60, v62);
@@ -4271,7 +4149,7 @@
             v46 = v0->uLevel;
             if ( v46 < v68 )
             {
-              if ( (signed __int64)v0->uExperience < v66 )
+              if ( (signed __int64)v0->uExperience < v5 )
               {
                 v64 = (char *)(v46 + 1);
                 v61 = (char *)(v5 - LODWORD(v0->uExperience));
@@ -4279,7 +4157,7 @@
               }
               else
               {
-                v64 = (char *)i;
+                v64 = (char *)v11;
                 v61 = (char *)(v46 + 1);
                 v59 = pGlobalTXT_LocalizationStrings[537];// "Train to level %d for %d gold"
               }
@@ -4290,7 +4168,7 @@
               v61 = pGlobalTXT_LocalizationStrings[536];// ""With your skills, you should be working here as a teacher.""
               v59 = "%s\n \n%s";
             }
-            sprintf(*v45, v59, v61, v64);
+            sprintfex(*v45, v59, v61, v64);
           }
           v47 = pFontArrus->CalcTextHeight(*v45, &v65, 0, 0);
           v43 = pDialogueWindow;
@@ -4300,7 +4178,7 @@
         }
         while ( v73 < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem );
       }
-      HIDWORD(v66) = (174 - v72) / 2;
+      //HIDWORD(v66) = (174 - v72) / 2;
       result = v43->pStartingPosActiveItem;
       v48 = result + v43->pNumPresenceButton;
       v49 = (2 * (87 - (174 - v72) / 2) - v72) / 2 - (174 - v72) / 2 / 2 + 138;
@@ -4308,25 +4186,25 @@
       v73 = v43->pStartingPosActiveItem;
       if ( v50 ^ __OFSUB__(result, v48) )
       {
-        i = 2;
+        int _v3 = 2;
         v51 = pShopOptions;
         do
         {
           v52 = v43->GetControl(v73);
           v53 = v52;
-          v52->uY = HIDWORD(v66) + v49;
+          v52->uY = (174 - v72) / 2 + v49;
           v54 = pFontArrus->CalcTextHeight(*v51, &v65, 0, 0);
           v55 = v53->uY;
           v53->uHeight = v54;
           v56 = v54 + v55 - 1;
           v53->uW = v56;
           v49 = v56;
-          v57 = v71;
-          if ( pDialogueWindow->pCurrentPosActiveItem != i )
+          v57 = color2;
+          if ( pDialogueWindow->pCurrentPosActiveItem != _v3 )
             v57 = white;
           v65.DrawTitleText(pFontArrus, 0, v55, v57, *v51, 3u);
           v43 = pDialogueWindow;
-          ++i;
+          ++_v3;
           ++v51;
           ++v73;
           result = pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem;
--- a/UIHouses.h	Tue Mar 12 09:43:40 2013 +0600
+++ b/UIHouses.h	Tue Mar 12 09:43:50 2013 +0600
@@ -9,9 +9,15 @@
     DIALOG_SHOP_SELL = 3,
     DIALOG_SHOP_IDENTIFY = 4,
     DIALOG_SHOP_REPAIR = 5,
+    DIALOG_SHOP_REST = 15,
+    DIALOG_SHOP_BYE_FOOD = 16,
     DIALOG_SHOP_DISPLAY_EQUIPMENT = 94,
     DIALOG_SHOP_BUY_SPECIAL = 95,
     DIALOG_SHOP_SKILLS = 96,
+    DIALOG_SHOP_ARCOMAGE_MAIN = 101,
+    DIALOG_SHOP_ARCOMAGE_102 = 102,
+    DIALOG_SHOP_ARCOMAGE_103 = 103,
+    DIALOG_SHOP_ARCOMAGE_RESULT = 104,
     };
 
 /*  349 */
--- a/mm7_1.cpp	Tue Mar 12 09:43:40 2013 +0600
+++ b/mm7_1.cpp	Tue Mar 12 09:43:50 2013 +0600
@@ -3601,11 +3601,11 @@
 	if(v0->classType == PLAYER_CLASS_WARLOCK)
 		++uRestUI_FoodRequiredToRest;
   }
-  if ( CheckHiredNPCSpeciality(0x1Du) )
+  if ( CheckHiredNPCSpeciality(Porter) )
     --uRestUI_FoodRequiredToRest;
-  if ( CheckHiredNPCSpeciality(0x1Eu) )
+  if ( CheckHiredNPCSpeciality(QuarterMaster) )
     uRestUI_FoodRequiredToRest -= 2;
-  if ( CheckHiredNPCSpeciality(0x30u) )
+  if ( CheckHiredNPCSpeciality(Gypsy) )
     --uRestUI_FoodRequiredToRest;
   if ( uRestUI_FoodRequiredToRest < 1 )
     uRestUI_FoodRequiredToRest = 1;
@@ -3698,7 +3698,7 @@
   Player **ppPlayers; // ecx@1
   Player *pPlayer; // eax@2
   unsigned int v3; // eax@15
-  char v4; // al@17
+  //char v4; // al@17
   bool v5; // eax@21
   GUIButton Dst; // [sp+8h] [bp-DCh]@19
   //double v7; // [sp+C4h] [bp-20h]@17
@@ -3751,18 +3751,18 @@
       _507CD4_RestUI_hourglass_anim_controller = 0;
     }
     v9 = v3;
-    v8 = (double)v3 * 0.001953125 * 120.0;
+    v8 = (double)v3 / 512.0 * 120.0;
     //v7 = v8 + 6.7553994e15;
     HIDWORD(v9) = floorf(v8 + 0.5f);//LODWORD(v7);
-    v4 = (int)floorf(v8 + 0.5f) % 256 + 1;//LOBYTE(v7) + 1;
-    byte_4E2BC8 = v4;
-    if ( (unsigned __int8)(v4) >= 0x78u )
+    hourglass_icon_idx = (int)floorf(v8 + 0.5f) % 256 + 1;//LOBYTE(v7) + 1;
+    //hourglass_icon_idx = v4;
+    if (hourglass_icon_idx >= 120 )
     {
-      v4 = 1;
-      byte_4E2BC8 = 1;
+      //v4 = 1;
+      hourglass_icon_idx = 1;
     }
-    sprintf(pTmpBuf, "hglas%03d", (unsigned __int8)v4);
-    pTexture_RestUI_CurrentHourglassFrame = &pIcons_LOD->pTextures[pIcons_LOD->LoadTexture(pTmpBuf, TEXTURE_16BIT_PALETTE)];
+    sprintf(pTmpBuf, "hglas%03d", hourglass_icon_idx);
+    pTexture_RestUI_CurrentHourglassFrame = pIcons_LOD->LoadTexturePtr(pTmpBuf, TEXTURE_16BIT_PALETTE);
     pRenderer->DrawTextureIndexed(0x10Bu, 0x9Fu, pTexture_RestUI_CurrentHourglassFrame);
     memset(&Dst, 0, 0xBCu);
     Dst.uX = 24;
@@ -3927,11 +3927,11 @@
       }
       while ( (signed int)v2 < v14 );
     }
-    if ( CheckHiredNPCSpeciality(0x1Fu) )
+    if ( CheckHiredNPCSpeciality(Factor) )
       v4 += (signed int)(10 * v4) / 100;
-    if ( CheckHiredNPCSpeciality(0x20u) )
+    if ( CheckHiredNPCSpeciality(Banker) )
       v4 += (signed int)(20 * v4) / 100;
-    if ( CheckHiredNPCSpeciality(0x2Du) )
+    if ( CheckHiredNPCSpeciality(Pirate) )
       v4 += (signed int)(10 * v4) / 100;
     if ( v3 )
     {
--- a/mm7_2.cpp	Tue Mar 12 09:43:40 2013 +0600
+++ b/mm7_2.cpp	Tue Mar 12 09:43:50 2013 +0600
@@ -824,9 +824,9 @@
 }
 
 //----- (004BCACC) --------------------------------------------------------
-void __fastcall DrawLearnSkillDialog(signed int uMessageParam)
-{
-  unsigned int v1; // edi@1
+void __fastcall OnSelectShopDialogueOption(signed int uMessageParam)
+{
+  //unsigned int v1; // edi@1
   //signed int v2; // ebx@1
   //signed int v3; // ecx@2
   int v4; // eax@5
@@ -883,7 +883,7 @@
   //signed int v55; // [sp+10h] [bp-10h]@1
   int v56; // [sp+14h] [bp-Ch]@31
 
-  v1 = 0;
+  //v1 = 0;
   //v2 = a1;
   //v55 = a1;
   if ( !pDialogueWindow->pNumPresenceButton )
@@ -910,15 +910,15 @@
 			  v4 += v5++ + 1;
 			while ( v5 < pPlayers[uActiveCharacter]->uLevel );
 		  }
-		  if ( pPlayers[uActiveCharacter]->uLevel < (unsigned __int16)word_4F0866[(unsigned int)window_SpeakInHouse->ptr_1C]
-			&& (signed __int64)pPlayers[uActiveCharacter]->uExperience < 1000 * v4 )
+		  if (pPlayers[uActiveCharacter]->uLevel < pMaxLevelPerTrainingHallType[(unsigned int)window_SpeakInHouse->ptr_1C - 89] &&
+			  (signed __int64)pPlayers[uActiveCharacter]->uExperience < 1000 * v4)
 			return;
 		}
 		pDialogueWindow->Release();
-		pDialogueWindow = GUIWindow::Create(0, 0, 640, 0x159u, WINDOW_MainMenu, v1, v1);
-		pBtn_ExitCancel = pDialogueWindow->CreateButton(526, 445, 75, 33, 1, v1, 0x71u, v1, v1, pGlobalTXT_LocalizationStrings[74],// "End Conversation"
-					   (Texture *)(uTextureID_BUTTDESC2 != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_BUTTDESC2] : 0), v1);
-		pDialogueWindow->CreateButton(8u, 8u, 0x1C2u, 0x140u, 1, v1, 0x51u, v1, v1, "", (Texture *)v1);
+		pDialogueWindow = GUIWindow::Create(0, 0, 640, 0x159u, WINDOW_MainMenu, 0, 0);
+		pBtn_ExitCancel = pDialogueWindow->CreateButton(526, 445, 75, 33, 1, 0, 0x71u, 0, 0, pGlobalTXT_LocalizationStrings[74],// "End Conversation"
+					                                    pIcons_LOD->GetTexture(uTextureID_BUTTDESC2), 0);
+		pDialogueWindow->CreateButton(8u, 8u, 0x1C2u, 0x140u, 1, 0, 0x51u, 0, 0, "", nullptr);
 //	LABEL_10:
 		//v3 = dword_F8B198;
 		v8 = window_SpeakInHouse;
@@ -927,20 +927,20 @@
 	  {
 		  v8 = window_SpeakInHouse;
 		  if ( (in_current_building_type == BildingType_Stables || in_current_building_type == BildingType_Boats)
-			&& (v1 = 0, *(&byte_4F09B1[32 * (unsigned __int8)*(&byte_4F0CCF[4 * (unsigned int)window_SpeakInHouse->ptr_1C] + uMessageParam)] + pParty->uDaysPlayed % 7))
+			&& (*(&byte_4F09B1[32 * (unsigned __int8)*(&byte_4F0CCF[4 * (unsigned int)window_SpeakInHouse->ptr_1C] + uMessageParam)] + pParty->uDaysPlayed % 7))
 			|| in_current_building_type != BildingType_Temple || uMessageParam != BildingType_MindGuild )
 		  {
 		//LABEL_9:
 			pDialogueWindow->Release();
-			pDialogueWindow = GUIWindow::Create(0, 0, 640, 0x159u, WINDOW_MainMenu, v1, v1);
-			pBtn_ExitCancel = pDialogueWindow->CreateButton(526, 445, 75, 33, 1, v1, 0x71u, v1, v1, pGlobalTXT_LocalizationStrings[74],// "End Conversation"
-						   (Texture *)(uTextureID_BUTTDESC2 != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_BUTTDESC2] : 0), v1);
-			pDialogueWindow->CreateButton(8u, 8u, 0x1C2u, 0x140u, 1, v1, 0x51u, v1, v1, "", (Texture *)v1);
+			pDialogueWindow = GUIWindow::Create(0, 0, 640, 0x159u, WINDOW_MainMenu, 0, 0);
+			pBtn_ExitCancel = pDialogueWindow->CreateButton(526, 445, 75, 33, 1, 0, 0x71u, 0, 0, pGlobalTXT_LocalizationStrings[74],// "End Conversation"
+						                                    pIcons_LOD->GetTexture(uTextureID_BUTTDESC2), 0);
+			pDialogueWindow->CreateButton(8u, 8u, 0x1C2u, 0x140u, 1, 0, 0x51u, 0, 0, "", nullptr);
 	//	LABEL_10:
 			//v3 = dword_F8B198;
 			v8 = window_SpeakInHouse;
 		  }
-		  else if ( uActiveCharacter != v1 )
+		  else if (uActiveCharacter)
 		  {
 			if ( !pPlayers[uActiveCharacter]->_4B6FF9() )
 			  return;
@@ -973,7 +973,7 @@
   {
     if ( in_current_building_type != BildingType_Tavern )
     {
-      if ( in_current_building_type <= (signed int)v1 )
+      if (in_current_building_type <= 0)
         return;
       if ( in_current_building_type > BildingType_AlchemistShop )
       {
@@ -1184,7 +1184,7 @@
           word_F8B1A0 = pParty->field_750[v25];
           if ( v27 )
           {
-            v1 = 0;
+            //v1 = 0;
             v27 = v26 == v13;
             v29 = (int)pNPCTopics[351].pText;
             if ( v27 )
@@ -1207,7 +1207,7 @@
               pParty->field_750[v25] = v13;
               pParty->field_75A[v25] = v13;
             }
-            v1 = 0;
+            //v1 = 0;
             dword_F8B1A4 = pNPCTopics[352].pText;
           }
         }
@@ -1247,7 +1247,7 @@
           *(&pMessageQueue_50CBD0->uNumMessages + 3 * pMessageQueue_50CBD0->uNumMessages + 3) = v1;
           ++pMessageQueue_50CBD0->uNumMessages;
         }*/
-        pMessageQueue_50CBD0->AddMessage(UIMSG_PlayArcomage, v1, v1);
+        pMessageQueue_50CBD0->AddMessage(UIMSG_PlayArcomage, 0, 0);
         dialog_menu_id = 104;
         break;
     }
@@ -9932,10 +9932,10 @@
   }
   
   pAllocator = Allocator::Create();
-  if (!pAllocator->Initialize(26 * 1024))
+  if (!pAllocator->Initialize(48 * 1024))
   {
     MessageBoxW(nullptr,
-                L"Unable to Allocate 26Mb of RAM",
+                L"Unable to Allocate 48Mb of RAM",
                 L"More RAM Memory Required", MB_ICONEXCLAMATION);
     return false;
   }
@@ -10446,6 +10446,7 @@
 }
 
 bool new_sky = false;
+bool change_seasons = true;
 
 //----- (00462C94) --------------------------------------------------------
 bool MM_Main(const wchar_t *pCmdLine)
--- a/mm7_3.cpp	Tue Mar 12 09:43:40 2013 +0600
+++ b/mm7_3.cpp	Tue Mar 12 09:43:50 2013 +0600
@@ -3917,15 +3917,15 @@
   if ( uCurrentlyLoadedLevelType != LEVEL_Outdoor )
     v0 = &pIndoor->dlv;
   v1 = 0;
-  if ( CheckHiredNPCSpeciality(0x2Du) )
-    v1 = 5;
-  if ( CheckHiredNPCSpeciality(0x33u) )
+  if ( CheckHiredNPCSpeciality(Pirate) )
+    v1 += 5;
+  if ( CheckHiredNPCSpeciality(Burglar) )
     v1 += 5;
-  if ( CheckHiredNPCSpeciality(0x30u) )
+  if ( CheckHiredNPCSpeciality(Gypsy) )
     v1 += 5;
-  if ( CheckHiredNPCSpeciality(0x32u) )
+  if ( CheckHiredNPCSpeciality(Duper) )
     v1 += 5;
-  if ( CheckHiredNPCSpeciality(0x34u) )
+  if ( CheckHiredNPCSpeciality(FallenWizard) )
     v1 += 5;
   return v1 + v0->uReputation;
 }
@@ -4847,11 +4847,11 @@
       pLightmapBuilder = (LightmapBuilder *)(v51 + v53 + v52);
       v51 = 20 * (int)pLightmapBuilder;
       result = 20 - (20 * (signed int)pLightmapBuilder >> 16);
-      v7->field_58 = result;
+      v7->dimming_level = result;
       if ( result < 0 )
-        v7->field_58 = 0;
-      if ( v7->field_58 > 31 )
-        v7->field_58 = 31;
+        v7->dimming_level = 0;
+      if ( v7->dimming_level > 31 )
+        v7->dimming_level = 31;
       if ( pOutdoorCamera->numStru148s >= 1999 + 5000)
         return result;
       ++pOutdoorCamera->numStru148s;
@@ -4912,8 +4912,7 @@
             v38 = 0;
             v37 = array_50AC10;
             v36 = uNumVertices;
-            pDecalBuilder->ApplyDecals(
-              31 - v7->field_58,
+            pDecalBuilder->ApplyDecals(31 - v7->dimming_level,
               2,
               &static_RenderBuildingsD3D_stru_73C834,
               uNumVertices,
@@ -5170,8 +5169,8 @@
         *(float *)&v84 = v13 * 31.0;
         v14 = *(float *)&v84 + 6.7553994e15;
         v71 = LODWORD(v14);
-        v15 = (int)&v12->field_58;
-        v12->field_58 = 31 - LOBYTE(v14);
+        v15 = (int)&v12->dimming_level;
+        v12->dimming_level = 31 - LOBYTE(v14);
         if ( (char)(31 - LOBYTE(v14)) < 0 )
           *(char *)v15 = 0;
         if ( *(char *)v15 > 31 )
@@ -5529,11 +5528,11 @@
   float v15; // [sp+8h] [bp-30h]@1
   float v16; // [sp+Ch] [bp-2Ch]@1
 
-  v14 = (double)pOutdoor->vSunlight.x * 0.000015258789;
+  v14 = (double)pOutdoor->vSunlight.x / 65536.0;
   result = 0;
   v1 = (unsigned int)&array_77EC08[pOutdoorCamera->numStru148s];
-  v15 = (double)pOutdoor->vSunlight.y * 0.000015258789;
-  v16 = (double)pOutdoor->vSunlight.z * 0.000015258789;
+  v15 = (double)pOutdoor->vSunlight.y / 65536.0;
+  v16 = (double)pOutdoor->vSunlight.z / 65536.0;
   if ( v1 > (unsigned int)array_77EC08 )
   {
     v2 = (char *)&array_77EC08[0].pODMFace;
@@ -6136,7 +6135,7 @@
   if (pOutdoor->uSky_TextureID == -1)
     return;
 
-  _this.field_58 = 0;
+  _this.dimming_level = 0;
   _this.uNumVertices = 4;
   _this.v_18.x = -stru_5C6E00->Sin(pIndoorCamera->sRotationX + 16);
   _this.v_18.y = 0;
@@ -6404,7 +6403,7 @@
   if ( !v62.pTexture )
     return;
   v8 = pBLVRenderParams->sPartyRotX;
-  v62.field_58 = 0;
+  v62.dimming_level = 0;
   v62.uNumVertices = v3;
   v9 = stru_5C6E00->Sin(pBLVRenderParams->sPartyRotX + 16);
   v62.v_18.y = 0;
@@ -6904,8 +6903,8 @@
       v10 = 27;
     if ( v10 < a4 )
       v10 = a4;
-    if ( v10 > pOutdoor->field_CBC_terrain_triangles_shade_type )
-      v10 = pOutdoor->field_CBC_terrain_triangles_shade_type;
+    if ( v10 > pOutdoor->max_terrain_dimming_level )
+      v10 = pOutdoor->max_terrain_dimming_level;
     return PaletteManager::Get_Dark_or_Red_LUT(v4, v10, 1);
   }
   v6 = 0;
@@ -7004,7 +7003,7 @@
         *a5 = 31;
         *a6 = -1;
       }
-      v16 = v8->field_58 - terrain_gamma;
+      v16 = v8->dimming_level - terrain_gamma;
       if ( v16 >= 0 )
       {
         if ( v16 > 27 )
@@ -7037,8 +7036,8 @@
         *v14 = v20;
       if ( *v14 < v16 )
         *v14 = v16;
-      if ( *v14 > pOutdoor->field_CBC_terrain_triangles_shade_type )
-        *v14 = pOutdoor->field_CBC_terrain_triangles_shade_type;
+      if ( *v14 > pOutdoor->max_terrain_dimming_level )
+        *v14 = pOutdoor->max_terrain_dimming_level;
       goto LABEL_45;
     }
     if ( v9 >= day_fogrange_1 << 16 )
@@ -7366,7 +7365,7 @@
 
 
 //----- (0047C4FC) --------------------------------------------------------
-signed int __fastcall GetActorTintColor(int tint, int a2, float a3, int a4, RenderBillboard *a5)
+signed int __fastcall GetActorTintColor(int max_dimm, int min_dimm, float distance, int a4, RenderBillboard *a5)
 {
   //int v5; // esi@1
   signed int v6; // edx@1
@@ -7385,11 +7384,11 @@
   //double v19; // ST0C_8@44
   signed int v20; // [sp+10h] [bp-4h]@10
   float a3a; // [sp+1Ch] [bp+8h]@33
-  float a3b; // [sp+1Ch] [bp+8h]@34
+  //float a3b; // [sp+1Ch] [bp+8h]@34
   float a3c; // [sp+1Ch] [bp+8h]@44
   //float a3d; // [sp+1Ch] [bp+8h]@44
   float a4b; // [sp+20h] [bp+Ch]@18
-  int a4a; // [sp+20h] [bp+Ch]@33
+  //int a4a; // [sp+20h] [bp+Ch]@33
   //float a4c; // [sp+20h] [bp+Ch]@44
   //float a4d; // [sp+20h] [bp+Ch]@44
   int a5a; // [sp+24h] [bp+10h]@44
@@ -7398,12 +7397,13 @@
   v6 = 0;
 
   if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
-    return 8 * (31 - tint) | ((8 * (31 - tint) | ((31 - tint) << 11)) << 8);
+    return 8 * (31 - max_dimm) | ((8 * (31 - max_dimm) | ((31 - max_dimm) << 11)) << 8);
+
   if (pParty->armageddon_timer)
     return 0xFFFF0000;
 
   v8 = pWeather->field_FA0;
-  if ( bUnderwater == 1 )
+  if (bUnderwater)
     v8 = 0;
   if ( v8 )
   {
@@ -7416,11 +7416,11 @@
     v9 = (double)v20 * 1024.0;
     if ( a4 )
       goto LABEL_19;
-    if ( a3 <= v9 )
-    {
-      if ( a3 > 0.0 )
-      {
-        a4b = a3 * 216.0 / v9;
+    if ( distance <= v9 )
+    {
+      if ( distance > 0.0 )
+      {
+        a4b = distance * 216.0 / v9;
         v10 = a4b + 6.7553994e15;
         v6 = LODWORD(v10);
         if ( SLODWORD(v10) > 216 )
@@ -7431,7 +7431,7 @@
     {
       v6 = 216;
     }
-    if ( a3 != 0.0 )
+    if ( distance != 0.0 )
     {
 LABEL_20:
       if ( a5 )
@@ -7447,10 +7447,11 @@
 
 
 
-  if ( a3 == 0.0 )
+  if (fabsf(distance) < 1.0e-6f)
     return 0xFFF8F8F8;
 
-  v11 = 8 * (tint - a2);
+  // dim in measured in 8-steps
+  v11 = 8 * (max_dimm - min_dimm);
     //v12 = v11;
     if ( v11 >= 0 )
     {
@@ -7460,27 +7461,32 @@
     else
       v11 = 0;
 
-    if ( a4 )
-    {
-      a3b = pOutdoor->fFogDensity * 216.0;
+    float fog_density_mult = 216.0f;
+    if (a4)
+      fog_density_mult += distance / (double)pOutdoorCamera->shading_dist_shade * 32.0;
+
+    v6 = v11 + floorf(pOutdoor->fFogDensity * fog_density_mult + 0.5f);
+    /*if ( a4 )
+    {
+      //a3b = pOutdoor->fFogDensity * 216.0;
       //v14 = a3b + 6.7553994e15;
-      a4a = floorf(a3b + 0.5f);//LODWORD(v14);
-    }
-    else
-    {
-      a3a = (a3 / (double)pOutdoorCamera->shading_dist_shade * 32.0 + 216.0) * pOutdoor->fFogDensity;
+      //a4a = floorf(a3b + 0.5f);//LODWORD(v14);
+    }
+    else
+    {
+      //a3a = (distance / (double)pOutdoorCamera->shading_dist_shade * 32.0 + 216.0) * pOutdoor->fFogDensity;
       //v13 = a3a + 6.7553994e15;
-      a4a = floorf(a3a + 0.5f);//LODWORD(v13);
-    }
-    v6 = a4a + v11;
+      //a4a = floorf(a3a + 0.5f);//LODWORD(v13);
+    }
+    v6 = a4a + v11;*/
     if ( a5 )
       v6 = 8 * _43F55F_get_billboard_light_level(a5, v6 >> 3);
     if ( v6 > 216 )
       v6 = 216;
     if ( v6 < v11 )
       v6 = v11;
-    if ( v6 > 8 * pOutdoor->field_CBC_terrain_triangles_shade_type )
-      v6 = 8 * pOutdoor->field_CBC_terrain_triangles_shade_type;
+    if ( v6 > 8 * pOutdoor->max_terrain_dimming_level )
+      v6 = 8 * pOutdoor->max_terrain_dimming_level;
     if ( !bUnderwater )
       return (255 - v6) | ((255 - v6) << 16) | ((255 - v6) << 8);
     else
@@ -11940,7 +11946,7 @@
   uBlue = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0, 0, 0xFFu);
   auto bWizardEyeActive = pParty->WizardEyeActive();
   auto uWizardEyeSkillLevel = pParty->WizardEyeSkillLevel();
-  if (CheckHiredNPCSpeciality(0x26u))
+  if (CheckHiredNPCSpeciality(Cartographer))
   {
     bWizardEyeActive = true;
     uWizardEyeSkillLevel = 2;
@@ -13858,13 +13864,13 @@
   signed int v0; // esi@1
 
   v0 = uDefaultTravelTime_ByFoot;
-  if ( CheckHiredNPCSpeciality(5u) )
+  if ( CheckHiredNPCSpeciality(Guide) )
     --v0;
-  if ( CheckHiredNPCSpeciality(6u) )
+  if ( CheckHiredNPCSpeciality(Tracker) )
     v0 -= 2;
-  if ( CheckHiredNPCSpeciality(7u) )
+  if ( CheckHiredNPCSpeciality(Pathfinder) )
     v0 -= 3;
-  if ( CheckHiredNPCSpeciality(0x2Cu) )
+  if ( CheckHiredNPCSpeciality(Explorer) )
     --v0;
   if ( v0 < 1 )
     v0 = 1;
--- a/mm7_4.cpp	Tue Mar 12 09:43:40 2013 +0600
+++ b/mm7_4.cpp	Tue Mar 12 09:43:50 2013 +0600
@@ -9292,7 +9292,7 @@
   }
   if ( v0 <= &_4F0882_evt_VAR_PlayerItemInHands_vals[53] )
   {
-	  ptr_F8B1E8 = (char *)pNPCTopics[666].pText;
+	  ptr_F8B1E8 = (char *)pNPCTopics[666].pText; // Here's %s that you lost. Be careful
 	  v4 = _4F0882_evt_VAR_PlayerItemInHands_vals[2 * v11];
 	  contract_approved = _4F0882_evt_VAR_PlayerItemInHands_vals[2 * v11];
 	  pParty->pPlayers[0].AddVariable(VAR_PlayerItemInHands, v4);
@@ -10811,8 +10811,8 @@
 
 
 //----- (004BC49B) --------------------------------------------------------
-void OnSelectDialogueOption(DIALOGUE_TYPE newDialogueType)
-    {
+void OnSelectNPCDialogueOption(DIALOGUE_TYPE newDialogueType)
+{
     //unsigned int v1; // esi@1
     NPCData *speakingNPC; // ebp@1
     //unsigned int v3; // eax@1
@@ -10830,17 +10830,16 @@
     const char *v15; // [sp-4h] [bp-14h]@60
 
     //v1 = _this;
-    speakingNPC = GetNPCData(sDialogue_SpeakingActorNPC_ID);
+  speakingNPC = GetNPCData(sDialogue_SpeakingActorNPC_ID);
     //v3 = v1;
-    uDialogueType = newDialogueType;
-    if ( !speakingNPC->uFlags )
-        {
-        speakingNPC->uFlags = 1;
+  uDialogueType = newDialogueType;
+  if (!speakingNPC->uFlags)
+  {
+    speakingNPC->uFlags = 1;
         //v3 = uDialogueType;
-        }
-    if ((newDialogueType>DIALOGUE_24)||(newDialogueType<DIALOGUE_19))
-        {
-
+  }
+  if ((newDialogueType > DIALOGUE_24) || (newDialogueType < DIALOGUE_19))
+  {
         if (newDialogueType != DIALOGUE_76)
             {
             if (newDialogueType == DIALOGUE_PROFESSION_DETAILS)
@@ -11350,8 +11349,8 @@
   int v29; // eax@62
   unsigned int v30; // ecx@62
   char *v31; // eax@63
-  char v32; // [sp-3Ch] [bp-2CCh]@62
-  int v33; // [sp-38h] [bp-2C8h]@62
+  MapInfo v32; // [sp-3Ch] [bp-2CCh]@62
+  /*int v33; // [sp-38h] [bp-2C8h]@62
   int v34; // [sp-34h] [bp-2C4h]@62
   int v35; // [sp-30h] [bp-2C0h]@62
   int v36; // [sp-2Ch] [bp-2BCh]@62
@@ -11365,17 +11364,17 @@
   char *v44; // [sp-Ch] [bp-29Ch]@62
   unsigned int v45; // [sp-8h] [bp-298h]@62
   char *v46; // [sp-4h] [bp-294h]@62
-  const char *v47[5]; // [sp+0h] [bp-290h]@7
-  char v48; // [sp+14h] [bp-27Ch]@37
-  char v49; // [sp+78h] [bp-218h]@68
-  char v50; // [sp+DCh] [bp-1B4h]@68
-  char v51; // [sp+140h] [bp-150h]@68
-  char Dest; // [sp+1A4h] [bp-ECh]@36
+  const char *v47[5]; // [sp+0h] [bp-290h]@7*/
+  char v48[100]; // [sp+14h] [bp-27Ch]@37
+  char v49[100]; // [sp+78h] [bp-218h]@68
+  char v50[100]; // [sp+DCh] [bp-1B4h]@68
+  char v51[100]; // [sp+140h] [bp-150h]@68
+  char Dest[100]; // [sp+1A4h] [bp-ECh]@36
   GUIWindow v53; // [sp+208h] [bp-88h]@1
   int v54; // [sp+25Ch] [bp-34h]@36
   int v55; // [sp+260h] [bp-30h]@36
   unsigned int v56; // [sp+264h] [bp-2Ch]@1
-  __int16 v57[2]; // [sp+268h] [bp-28h]@1
+  int v57; // [sp+268h] [bp-28h]@1
   Player *v58; // [sp+26Ch] [bp-24h]@36
   GUIWindow *v59; // [sp+270h] [bp-20h]@1
   unsigned int v60; // [sp+274h] [bp-1Ch]@36
@@ -11394,7 +11393,7 @@
   v53.uFrameX = 483;
   v53.uFrameWidth = 148;
   v53.uFrameZ = 334;
-  *(int *)v57 = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0xFFu, 0xFFu, 0xFFu);
+  v57 = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0xFFu, 0xFFu, 0xFFu);
   v56 = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0xFFu, 0xFFu, 0x9Bu);
   v3 = 52 * (unsigned int)v0->ptr_1C;
   //v59 = (GUIWindow *)((((p2DEvents_minus1___00[v3 / 2] != 27) - 1) & 0xFFFFFFE7) + 50);
@@ -11414,8 +11413,8 @@
       v17 = LOBYTE(pFontArrus->uFontHeight) - 3;
       v59 = pDialogueWindow;
       v54 = v17;
-      strcpy(&Dest, "");
-      sprintf(pTmpBuf2, pGlobalTXT_LocalizationStrings[405], s1);
+      strcpy(Dest, "");
+      sprintfex(pTmpBuf2, pGlobalTXT_LocalizationStrings[405], s1); // Price: %lu gold
       v18 = pFontArrus->CalcTextHeight(pTmpBuf2, &v53, 0, 0);
       v19 = v16->pNumPresenceButton;
       v20 = v18 + v17 + 146;
@@ -11426,13 +11425,13 @@
       if ( v21 >= v21 + v19 )
         goto LABEL_71;
       s1 = 2;
-      a1 = &v48;
+      a1 = v48;
       while ( 1 )
       {
-        v47[1] = (const char *)v60;
+        int v47 = v60;
         v22 = window_SpeakInHouse->ptr_1C;
-        v23 = (Player *)(unsigned __int8)*(&_4F0D38_TravelInfo[4 * (signed int)v22] + v62);
-        v61 = (Player *)(unsigned __int8)*(&_4F0D38_TravelInfo[4 * (signed int)v22] + v62);
+        v23 = (Player *)(unsigned __int8)*(&_4F0D38_TravelInfo[4 * (unsigned int)v22] + v62); // negindex. actual address is around + 0x36
+        v61 = (Player *)(unsigned __int8)*(&_4F0D38_TravelInfo[4 * (unsigned int)v22] + v62); // + 0x3F for sea travels, less for land
         v24 = v16->GetControl(v60);
         if ( v23 != v58
           && ((signed int)s1 >= 6 ? (v25 = 1) : (v25 = (unsigned __int8)*(&byte_4F09B1[32 * (int)v23]
@@ -11444,49 +11443,35 @@
           v58 = v61;
           v27 = (const char *)v56;
           if ( pDialogueWindow->pCurrentPosActiveItem != s1 )
-            v27 = *(const char **)v57;
-          v47[1] = v27;
-          sprintf(a1, format_4E2DC8, v27);
+            v27 = (const char *)v57;
+          //v32.uRedbookTrackID = v27;
+          sprintf(a1, "\xC" "%05d", v27);
           v66 = (unsigned __int8)byte_4F09B8[v26 * 4];
           if ( (signed int)window_SpeakInHouse->ptr_1C >= 63 )
           {
-            if ( CheckHiredNPCSpeciality(8u) )
+            if ( CheckHiredNPCSpeciality(Sailor) )
               v66 -= 2;
-            if ( CheckHiredNPCSpeciality(9u) )
+            if ( CheckHiredNPCSpeciality(Navigator) )
               v66 -= 3;
-            v47[1] = (const char *)45;
+            //v47 = Pirate;
+            if ( CheckHiredNPCSpeciality(Pirate) )
+              v66 -= 2;
           }
           else
           {
-            v47[1] = (const char *)35;
-          }
-          if ( CheckHiredNPCSpeciality((unsigned int)v47[1]) )
-            v66 -= 2;
-          if ( CheckHiredNPCSpeciality(0x2Cu) )
+            //v47 = Horseman;
+            if ( CheckHiredNPCSpeciality(Horseman) )
+              v66 -= 2;
+          }
+          if ( CheckHiredNPCSpeciality(Explorer) )
             --v66;
           if ( v66 < 1 )
             v66 = 1;
           if ( v61 != (Player *)v2 )
           {
-            memcpy(&v32, (char *)&pMapStats + 68 * (unsigned __int8)byte_4F09B0[v26 * 4], 0x44u);
-            sprintf(pTmpBuf, pGlobalTXT_LocalizationStrings[404],
-              v66,
-              *(int *)&v32,
-              v33,
-              v34,
-              v35,
-              v36,
-              v37,
-              v38,
-              v39,
-              v40,
-              v41,
-              v42,
-              v43,
-              v44,
-              v45,
-              v46,
-              *(_QWORD *)v47);
+            memcpy(&v32, &pMapStats->pInfos[(unsigned __int8)byte_4F09B0[v26 * 4]], 0x44u);
+            sprintfex(pTmpBuf, pGlobalTXT_LocalizationStrings[404], // Time - %d days, destination %s
+              v66, v32.pName);
             strcat(a1, pTmpBuf);
             v28 = a1;
             a1 += 100;
@@ -11523,23 +11508,20 @@
       }
       if ( v63 != v55 )
       {
-        v47[1] = &Dest;
+        /*v47[1] = &Dest;
         v47[0] = &v51;
         v46 = &v50;
         v45 = (unsigned int)&v49;
         v44 = &v48;
-        v43 = pTmpBuf2;
-        sprintf(pTmpBuf, "%s\n \n%s%s%s%s%s", pTmpBuf2, &v48, &v49, &v50, &v51, &Dest);
+        v43 = pTmpBuf2;*/
+        sprintf(pTmpBuf, "%s\n \n%s%s%s%s%s", pTmpBuf2, v48, v49, v50, v51, Dest);
         v53.DrawTitleText(pFontArrus, 0, 0x92u, 0, pTmpBuf, 3u);
       }
       else
       {
 LABEL_71:
-        v47[1] = (const char *)3;
-        v47[0] = pGlobalTXT_LocalizationStrings[561];
-        v46 = *(char **)v57;
-        v45 = (174 - pFontArrus->CalcTextHeight(pGlobalTXT_LocalizationStrings[561], &v53, 0, 0)) / 2 + 138;
-        v53.DrawTitleText(pFontArrus, 0, v45, (unsigned __int16)v46, v47[0], (unsigned int)v47[1]);
+        v53.DrawTitleText(pFontArrus, 0, (174 - pFontArrus->CalcTextHeight(pGlobalTXT_LocalizationStrings[561], &v53, 0, 0)) / 2 + 138,
+                          v57, pGlobalTXT_LocalizationStrings[561], 3);
         pAudioPlayer->StopChannels(-1, -1);
       }
     }
@@ -11560,8 +11542,8 @@
         pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
       }
       Party::TakeGold(s1);
-      v47[1] = (const char *)7;
-      v5 = &byte_4F09B0[32 * (unsigned __int8)*(&byte_4F0CCF[4 * (unsigned int)window_SpeakInHouse->ptr_1C] + dialog_menu_id)];
+      //v47[1] = (const char *)7;
+      v5 = &byte_4F09B0[32 * (unsigned __int8)*(&byte_4F0CCF[4 * (unsigned int)window_SpeakInHouse->ptr_1C] + dialog_menu_id)];  // negindex with ptr_1C around +0x36
       if ( v5[pParty->uDaysPlayed % 7 + 1] )
       {
         if ( _strcmpi(pCurrentMapName, pMapStats->pInfos[(unsigned __int8)*v5].pFilename) )
@@ -11597,25 +11579,28 @@
         }
         HousePlaySomeSound((unsigned int)window_SpeakInHouse->ptr_1C, 2);
         v12 = (unsigned __int8)v5[8];
+        int _v47;
         if ( (signed int)window_SpeakInHouse->ptr_1C >= 63 )
         {
-          v63 = SPEECH_72;
+          v63 = SPEECH_SetSail;
           v13 = 2500;
-          if ( CheckHiredNPCSpeciality(8u) )
+          if ( CheckHiredNPCSpeciality(Sailor) )
             v12 -= 2;
-          if ( CheckHiredNPCSpeciality(9u) )
+          if ( CheckHiredNPCSpeciality(Navigator) )
             v12 -= 3;
-          v47[1] = (const char *)45;
+          //_v47 = 45;
+          if ( CheckHiredNPCSpeciality(Pirate) )
+            v12 -= 2;
         }
         else
         {
-          v63 = SPEECH_71;
+          v63 = SPEECH_CarriageReady;
           v13 = 1500;
-          v47[1] = (const char *)35;
-        }
-        if ( CheckHiredNPCSpeciality((unsigned int)v47[1]) )
-          v12 -= 2;
-        if ( CheckHiredNPCSpeciality(0x2Cu) )
+          //_v47 = 35;
+          if ( CheckHiredNPCSpeciality(Horseman) )
+            v12 -= 2;
+        }
+        if ( CheckHiredNPCSpeciality(Explorer) )
           --v12;
         if ( v12 < 1 )
           v12 = 1;
--- a/mm7_5.cpp	Tue Mar 12 09:43:40 2013 +0600
+++ b/mm7_5.cpp	Tue Mar 12 09:43:50 2013 +0600
@@ -396,11 +396,11 @@
         case UIMSG_ClickNPCTopic:
           ClickNPCTopic(uMessageParam);
           continue;
-        case UIMSG_ClickLearnSkillDialog:
-          DrawLearnSkillDialog(uMessageParam);
-          continue;
-        case UIMSG_SelectDialogueOption:
-          OnSelectDialogueOption((DIALOGUE_TYPE)uMessageParam);
+        case UIMSG_SelectShopDialogueOption:
+          OnSelectShopDialogueOption(uMessageParam);
+          continue;
+        case UIMSG_SelectNPCDialogueOption:
+          OnSelectNPCDialogueOption((DIALOGUE_TYPE)uMessageParam);
           continue;
         case UIMSG_19A:
           _4B4224_UpdateNPCTopics(uMessageParam);
@@ -15116,10 +15116,10 @@
 			break;
 			}
 		case WINDOW_Rest:
-			{
+	    {
 			RestUI_Draw();
 			break;
-			}
+		}
 		case WINDOW_Dialogue:
 			{
 			DrawDialogueUI();
@@ -16641,21 +16641,21 @@
   {
     strcpy(a2, "%s\n\n");
     v24 = GetSkillColor(pPlayer->classType, uPlayerSkillType, 1);
-    sprintf(Source, format_4E2DC8, v24);
+    sprintf(Source, "\xC" "%05d", v24);
     strcat(a2, Source);
     strcat(a2, "%s\t%03d:\t%03d%s\t000\n");
     v25 = GetSkillColor(pPlayer->classType, uPlayerSkillType, 2);
-    sprintf(Source, format_4E2DC8, v25);
+    sprintf(Source, "\xC" "%05d", v25);
     strcat(a2, Source);
     strcat(a2, "%s\t%03d:\t%03d%s\t000\n");
     v26 = GetSkillColor(pPlayer->classType, uPlayerSkillType, 3);
-    sprintf(Source, format_4E2DC8, v26);
+    sprintf(Source, "\xC" "%05d", v26);
     strcat(a2, Source);
     strcat(a2, "%s\t%03d:\t%03d%s\t000\n");
     v27 = pPlayer->classType;
     v28 = uPlayerSkillType;
     v29 = GetSkillColor(v27, uPlayerSkillType, 4);
-    sprintf(Source, format_4E2DC8, v29);
+    sprintf(Source, "\xC" "%05d", v29);
     strcat(a2, Source);
     strcat(a2, "%s\t%03d:\t%03d%s\t000\n");
 
@@ -16670,24 +16670,24 @@
   {
     strcpy(a2, "%s\n\n");
     v9 = GetSkillColor(pPlayer->classType, uPlayerSkillType, 1);
-    sprintf(Source, format_4E2DC8, v9);
+    sprintf(Source, "\xC" "%05d", v9);
     strcat(a2, Source);
     strcat(a2, "%s\t%03d:\t%03d%s\t000\n");
     v10 = GetSkillColor(pPlayer->classType, uPlayerSkillType, 2);
-    sprintf(Source, format_4E2DC8, v10);
+    sprintf(Source, "\xC" "%05d", v10);
     strcat(a2, Source);
     strcat(a2, "%s\t%03d:\t%03d%s\t000\n");
     v11 = GetSkillColor(pPlayer->classType, uPlayerSkillType, 3);
-    sprintf(Source, format_4E2DC8, v11);
+    sprintf(Source, "\xC" "%05d", v11);
     strcat(a2, Source);
     strcat(a2, "%s\t%03d:\t%03d%s\t000\n");
     v12 = uPlayerSkillType;
     v13 = GetSkillColor(pPlayer->classType, uPlayerSkillType, 4);
-    sprintf(Source, format_4E2DC8, v13);
+    sprintf(Source, "\xC" "%05d", v13);
     strcat(a2, Source);
     strcat(a2, "%s\t%03d:\t%03d%s\t000\n\n");
     v14 = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0xFFu, 0xFFu, 0xFFu);
-    sprintf(Source, format_4E2DC8, v14);
+    sprintf(Source, "\xC" "%05d", v14);
     strcat(a2, Source);
     strcat(a2, "%s: +%d");
     v15 = v12;
@@ -17139,7 +17139,7 @@
   v2 = pIcons_LOD->LoadTexture("fr_stats", TEXTURE_16BIT_PALETTE);
   pRenderer->DrawTextureIndexed(8, 8, (Texture *)(v2 != -1 ? (int)&pIcons_LOD->pTextures[v2] : 0));
   v3 = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0xFFu, 0xFFu, 0x9Bu);
-  sprintf(pTmpBuf, format_4E2DC8, v3);
+  sprintf(pTmpBuf, "\xC" "%05d", v3);
   sprintf(pTmpBuf2, pGlobalTXT_LocalizationStrings[429], pPlayer->pName, pClassNames[pPlayer->classType]);//^Pi[%s] %s
   strcat(pTmpBuf, pTmpBuf2);
   if ( pPlayer->uSkillPoints )
--- a/mm7_6.cpp	Tue Mar 12 09:43:40 2013 +0600
+++ b/mm7_6.cpp	Tue Mar 12 09:43:50 2013 +0600
@@ -7576,7 +7576,7 @@
     CASE(UIMSG_Quit)
     CASE(UIMSG_StartHireling1Dialogue)
     CASE(UIMSG_StartHireling2Dialogue)
-    CASE(UIMSG_SelectDialogueOption)
+    CASE(UIMSG_SelectNPCDialogueOption)
     CASE(UIMSG_CastSpellFromBook)
     CASE(UIMSG_PlayerCreation_VoicePrev)
     CASE(UIMSG_PlayerCreation_VoiceNext)
--- a/mm7_data.cpp	Tue Mar 12 09:43:40 2013 +0600
+++ b/mm7_data.cpp	Tue Mar 12 09:43:50 2013 +0600
@@ -487,7 +487,7 @@
 char _4E2AD8_ui_colors[72];
 char _4E2B21_buff_spell_tooltip_colors[80];
 char byte_4E2B70[777]; // weak
-char byte_4E2BC8; // weak
+unsigned char hourglass_icon_idx = 12; // weak
 
 char aSS[777]; // idb
 char ascii_4E2C54[6];
@@ -524,7 +524,7 @@
 char format_4E2D90[8];
 char aS03d03dS000_0[777]; // idb
 char aS03d03dS000[777]; // idb
-const char *format_4E2DC8 = "\f%05d";
+//const char *format_4E2DC8 = "\f%05d";
 char aS[777]; // idb
 char aLuSLuS[777]; // idb
 char byte_4E2DE8; // idb
@@ -1476,7 +1476,7 @@
 	   56, 56, 59, 59, 60, 60};
 __int16 word_4F0754[49];
 //__int16 word_4F07B6[88];
-__int16 word_4F0866[14];
+//__int16 _word_4F0866_pMaxLevelPerTrainingHallType_negindexing[14];
 __int16 _4F0882_evt_VAR_PlayerItemInHands_vals[54]=
 {
 	0x0D4, 0x270, 0x0D5, 0x21C, 0x0D6, 0x2BE, 0x0D7, 0x2BD, 0x0D8, 0x289, 
@@ -1485,8 +1485,9 @@
 	0x0E2, 0x1E7, 0x0E3, 0x287, 0x0E4, 0x272, 0x0E5, 0x267, 0x0E6,
 	0x275, 0x0E7, 0x25A, 0x0E8, 0x2A4, 0x0E9, 0x2A5, 0x0EA, 0x2A3,
 	0x0EB, 0x25C, 0x0EC, 0x25D, 0x0ED, 0x259, 0x0F1, 0x21E
-}
-;
+};
+unsigned short pMaxLevelPerTrainingHallType[6] = {5, 15, 25, 25, 200, 200};
+
 int price_for_membership[11]={100, 100, 50, 50, 50, 50, 50, 50, 50, 1000, 1000}; // weak
 char byte_4F09B0[777]; // weak
 char byte_4F09B1[777]; // weak
--- a/mm7_data.h	Tue Mar 12 09:43:40 2013 +0600
+++ b/mm7_data.h	Tue Mar 12 09:43:50 2013 +0600
@@ -473,7 +473,7 @@
 extern char _4E2AD8_ui_colors[72];
 extern char _4E2B21_buff_spell_tooltip_colors[80];
 extern char byte_4E2B70[]; // weak
-extern char byte_4E2BC8; // weak
+extern unsigned char hourglass_icon_idx; // weak
 
 extern char aSS[]; // idb
 extern char ascii_4E2C54[6];
@@ -510,7 +510,7 @@
 extern char format_4E2D90[8];
 extern char aS03d03dS000_0[]; // idb
 extern char aS03d03dS000[]; // idb
-extern const char *format_4E2DC8;
+//extern const char *format_4E2DC8;
 extern char aS[]; // idb
 extern char aLuSLuS[]; // idb
 extern char byte_4E2DE8; // idb
@@ -1008,8 +1008,9 @@
 extern int guild_mambership_flags[32];
 extern __int16 word_4F0754[49];
 //extern __int16 word_4F07B6[88];
-extern __int16 word_4F0866[14];
+//extern __int16 _word_4F0866_pMaxLevelPerTrainingHallType_negindexing[14];
 extern __int16 _4F0882_evt_VAR_PlayerItemInHands_vals[54];
+extern unsigned short pMaxLevelPerTrainingHallType[];
 extern int price_for_membership[]; // weak
 extern char byte_4F09B0[]; // weak
 extern char byte_4F09B1[]; // weak
@@ -2194,7 +2195,7 @@
 char *__fastcall sr_sub_47C28C_get_palette(stru148 *a1, char a2, signed int a3, signed int a4);
 unsigned int __cdecl GetLevelFogColor();
 int __fastcall sub_47C3D7_get_fog_related_stuff(int a1, int a2, float a3);
-signed int __fastcall GetActorTintColor(int a1, int a2, float a3, int a4, struct RenderBillboard *a5);
+signed int __fastcall GetActorTintColor(int max_dim, int min_dim, float distance, int a4, struct RenderBillboard *a5);
 unsigned int __stdcall WorldPosToGridCellX(int); // weak
 unsigned int __stdcall WorldPosToGridCellZ(int); // weak
 int __stdcall GridCellToWorldPosX(int); // weak
@@ -2324,7 +2325,7 @@
 void __cdecl ArenaFight();
 void  SpellBookGenerator();
 struct GUIButton *__cdecl UI_CreateEndConversationButton();
-void __fastcall DrawLearnSkillDialog(signed int uMessageParam);
+void __fastcall OnSelectShopDialogueOption(signed int uMessageParam);
 signed int __cdecl sub_4BD8B5();
 bool __fastcall sub_4BDAAF(ItemGen *a1, int _2da_idx);
 void __cdecl sub_4BDB56_buy_skill____();
--- a/mm7text_ru.cpp	Tue Mar 12 09:43:40 2013 +0600
+++ b/mm7text_ru.cpp	Tue Mar 12 09:43:50 2013 +0600
@@ -874,6 +874,7 @@
   {"", 0},
   {"", 0},
   {"", 0},
+  {"", 0},
   {"", 1},
   {"", 0},
   {"", 0},
@@ -1165,8 +1166,9 @@
   char buf[8192];
   assert(strlen(str) < sizeof(buf));
 
-  bool integer_token_defined = false;
-  int integer_token = 0;
+  int next_integer_token = 0;
+  bool integer_tokens_defined[10] = {false, false, false, false, false, false, false, false, false, false};
+  int integer_tokens[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
 
   bool gender_token_defined = false;
   int gender_token = 0;
@@ -1183,9 +1185,10 @@
         if (src[2] != '[')
           goto _invalid_token;
         src += 3;  // ^I[
-
-        if (sscanf(src, "%d", &integer_token))
-          integer_token_defined = true;
+        
+        assert(next_integer_token < 10);
+        if (sscanf(src, "%d", &integer_tokens[next_integer_token]))
+          integer_tokens_defined[next_integer_token++] = true;
 
         auto int_begin = src;
         while (*src++ != ']');
@@ -1198,9 +1201,19 @@
 
       case 'L':
       {
-        if (src[2] != '[')
+        int integer_token_idx = 0;
+        if (src[2] >= '1' && src[2] <= '9')
+        {
+          if (src[3] != '[')
+            goto _invalid_token;
+          integer_token_idx = src[2] - '1';
+
+          src += 1;
+        }
+        else if (src[2] != '[')
           goto _invalid_token;
-        assert(integer_token_defined);
+
+        assert(integer_tokens_defined[integer_token_idx]);
         src += 3; // ^L[
 
         auto ending1 = src;
@@ -1213,7 +1226,7 @@
         char *actual_ending = nullptr;
         int   actual_ending_len = 0;
 
-        int modulo = abs(integer_token) % 10;
+        int modulo = abs(integer_tokens[integer_token_idx]) % 10;
         if (modulo == 1)
         {
           actual_ending = ending1;
@@ -1328,7 +1341,7 @@
           case 'P': case 'p':
           {
             auto token_begin = src;
-            int token_len = 0;
+            int token_len = 1;
             for (int i = 0; token_begin[i] != ']'; ++i)
               token_len++;
             strncpy(dst, token_begin, token_len);
--- a/texts.cpp	Tue Mar 12 09:43:40 2013 +0600
+++ b/texts.cpp	Tue Mar 12 09:43:50 2013 +0600
@@ -305,7 +305,7 @@
 	aNPCProfessionNames[27] = pGlobalTXT_LocalizationStrings[329];
 	aNPCProfessionNames[28] = pGlobalTXT_LocalizationStrings[330];
 	aNPCProfessionNames[29] = pGlobalTXT_LocalizationStrings[331];
-	aNPCProfessionNames[20] = pGlobalTXT_LocalizationStrings[332];
+	aNPCProfessionNames[30] = pGlobalTXT_LocalizationStrings[332];
 	aNPCProfessionNames[31] = pGlobalTXT_LocalizationStrings[333];
 	aNPCProfessionNames[32] = pGlobalTXT_LocalizationStrings[334];
 	aNPCProfessionNames[33] = pGlobalTXT_LocalizationStrings[335];