changeset 1633:384a6b9d1333

Merge
author Nomad
date Tue, 17 Sep 2013 12:40:37 +0200
parents 69ab7593e7af (current diff) ee4a65ac9d21 (diff)
children 04cae215a13c 2c71fa8913d2
files Render.cpp
diffstat 22 files changed, 2794 insertions(+), 3442 deletions(-) [+]
line wrap: on
line diff
--- a/Actor.cpp	Tue Sep 17 12:37:07 2013 +0200
+++ b/Actor.cpp	Tue Sep 17 12:40:37 2013 +0200
@@ -5327,7 +5327,7 @@
     player->ReceiveDamage(uDamageAmount, (DAMAGE_TYPE)a2);
   v50 = 24;
   v59 = 20 * v61 / (signed int)pMonster->pMonsterInfo.uHP;
-  if ( (player->_48EA46_calc_special_bonus_by_items(24) || hit_will_stun != v41)
+  if ( (player->GetSpecialItemBonus(24) || hit_will_stun != v41)
     && stru_50C198.GetMagicalResistance(pMonster, 3u) )
   {
     LODWORD(v42) = 20;
--- a/CastSpellInfo.cpp	Tue Sep 17 12:37:07 2013 +0200
+++ b/CastSpellInfo.cpp	Tue Sep 17 12:40:37 2013 +0200
@@ -1949,7 +1949,7 @@
 				v245->uItemID <= 134 &&
 				v245->uSpecEnchantmentType == 0 &&
 				v245->uEnchantmentType == 0 &&
-				v245->_bonus_strength== 0 &&
+				v245->m_enchantmentStrength== 0 &&
 				!v245->IsBroken() )
 			{
 				if ( v245->GetValue() < 450 || 
@@ -1982,7 +1982,7 @@
 						}
 						v255 = 10;//pItemsTable->field_116D8[17];
 						v256 = 10;//pItemsTable->field_116D8[16];
-						v245->_bonus_strength = v256 + rand() % (v255 - v256 + 1);
+						v245->m_enchantmentStrength = v256 + rand() % (v255 - v256 + 1);
 						v245->uAttributes |= 0x20u;
 						_50C9A8_item_enchantment_timer = 256;
 						LODWORD(v727) = 1;
--- a/GUIWindow.cpp	Tue Sep 17 12:37:07 2013 +0200
+++ b/GUIWindow.cpp	Tue Sep 17 12:40:37 2013 +0200
@@ -1037,6 +1037,7 @@
           TempleDialog();
           break;
         case BuildingType_Stables:
+        case BuildingType_Boats:
           TravelByTransport();
           break;
         case BuildingType_Training:
@@ -1725,31 +1726,29 @@
   if (eWindowType == WINDOW_HouseInterior)
   {
     pCurrentScreen = SCREEN_HOUSE;
-    pBtn_ExitCancel = pWindow->CreateButton(471, 445, 0xA9u, 0x23u, 1, 0, UIMSG_Escape, 0, 0, pGlobalTXT_LocalizationStrings[80],//Выйти из здания
+    pBtn_ExitCancel = pWindow->CreateButton(471, 445, 169, 35, 1, 0, UIMSG_Escape, 0, 0, pGlobalTXT_LocalizationStrings[80],//Выйти из здания
                    pIcons_LOD->GetTexture(uExitCancelTextureId), 0);
-  
-      for ( v26 = 0; v26 < uNumDialogueNPCPortraits; ++v26 )
+    for ( v26 = 0; v26 < uNumDialogueNPCPortraits; ++v26 )
+    {
+      if ( v26 + 1 == uNumDialogueNPCPortraits && uHouse_ExitPic )
       {
-        if ( v26 + 1 == uNumDialogueNPCPortraits && uHouse_ExitPic )
-        {
-          v30 = pMapStats->pInfos[uHouse_ExitPic].pName;
-          v29 = (char*)pGlobalTXT_LocalizationStrings[LOCSTR_ENTER_S];
-        }
+        v30 = pMapStats->pInfos[uHouse_ExitPic].pName;
+        v29 = (char*)pGlobalTXT_LocalizationStrings[LOCSTR_ENTER_S];
+      }
+      else
+      {
+        if ( v26 || !dword_591080 )
+          v27 = HouseNPCData[v26 +1 - ((dword_591080 != 0)? 1:0)]->pName;
         else
-        {
-          if ( v26 || !dword_591080 )
-            v27 = HouseNPCData[v26 +1 - ((dword_591080 != 0)? 1:0)]->pName;
-          else
-            v27 = (char*)p2DEvents[pButton - 1].pProprieterName;
-          v30 = v27;
-          v29 = (char*)pGlobalTXT_LocalizationStrings[435];
-        }
-        sprintfex(byte_591180[v26].data(), v29, v30);
-        dword_5913F4[v26] = pWindow->CreateButton(pNPCPortraits_x[uNumDialogueNPCPortraits - 1][v26],
-                                                                 pNPCPortraits_y[uNumDialogueNPCPortraits - 1][v26],
-                                             0x3Fu, 0x49u, 1, 0, UIMSG_ClickHouseNPCPortrait, v26, 0, byte_591180[v26].data(), 0, 0, 0);
+          v27 = (char*)p2DEvents[pButton - 1].pProprieterName;
+        v30 = v27;
+        v29 = (char*)pGlobalTXT_LocalizationStrings[435];
       }
-  
+      sprintfex(byte_591180[v26].data(), v29, v30);
+      HouseNPCPortraitsButtonsList[v26] = pWindow->CreateButton(pNPCPortraits_x[uNumDialogueNPCPortraits - 1][v26],
+                                                                pNPCPortraits_y[uNumDialogueNPCPortraits - 1][v26],
+                                           63, 73, 1, 0, UIMSG_ClickHouseNPCPortrait, v26, 0, byte_591180[v26].data(), 0, 0, 0);
+    }
     if ( uNumDialogueNPCPortraits == 1 )
     {
       window_SpeakInHouse = &pWindowList[uNextFreeWindowID];
--- a/Items.cpp	Tue Sep 17 12:37:07 2013 +0200
+++ b/Items.cpp	Tue Sep 17 12:40:37 2013 +0200
@@ -255,7 +255,7 @@
   this->uAttributes = 0;
   this->uNumCharges = 0;
   this->uSpecEnchantmentType = 0;
-  this->_bonus_strength = 0;
+  this->m_enchantmentStrength = 0;
   this->uEnchantmentType = 0;
   this->uItemID = 0;
   this->uBodyAnchor = 0;
@@ -792,7 +792,7 @@
 						{
 						for(int ii=0; ii<24; ++ii)
 							{
-							if (_stricmp(test_string,pEnchantments[ii].pBonusStat))
+							if (!_stricmp(test_string,pEnchantments[ii].pOfName))
 								{
 								pItems[item_counter]._bonus_type=ii+1;
 								break;
@@ -802,7 +802,7 @@
 							{
 							for(int ii=0; ii<72; ++ii)
 								{
-								if (_stricmp(test_string,pSpecialEnchantments[ii].pBonusStatement))
+								if (!_stricmp(test_string,pSpecialEnchantments[ii].pNameAdd))
 									{
 									pItems[item_counter]._additional_value=ii+1;
 									}
@@ -1245,6 +1245,13 @@
 			} while ((decode_step<2)&&!break_loop);
 		}
 
+
+  
+  ItemGen::PopulateSpecialBonusMap();
+  ItemGen::PopulateArtifactBonusMap();
+  ItemGen::PopulateRegularBonusMap();
+  
+
 	}
 
 //----- (00456D17) --------------------------------------------------------
@@ -1254,7 +1261,7 @@
   {
     pItem->uEnchantmentType = pItems[pItem->uItemID]._bonus_type;
     pItem->uSpecEnchantmentType = pItems[pItem->uItemID]._additional_value;
-    pItem->_bonus_strength = pItems[pItem->uItemID]._bonus_strength;
+    pItem->m_enchantmentStrength = pItems[pItem->uItemID]._bonus_strength;
   }
 }
 
@@ -1443,7 +1450,7 @@
 	if ( this->uAttributes & ITEM_TEMP_BONUS || pItemsTable->IsMaterialNonCommon(this) )
 		return uBaseValue;
 	if (uEnchantmentType )
-		return uBaseValue + 100 * _bonus_strength;;
+		return uBaseValue + 100 * m_enchantmentStrength;;
 	if (uSpecEnchantmentType )
 		{
 		bonus = pItemsTable->pSpecialEnchantments[uSpecEnchantmentType].iTreasureLevel;
@@ -1797,12 +1804,12 @@
             ++out_item->uEnchantmentType;
 
             v33 = rand() % (bonus_ranges[v6].maxR - bonus_ranges[v6].minR + 1);
-            out_item->_bonus_strength = v33 + bonus_ranges[v6].minR;
+            out_item->m_enchantmentStrength = v33 + bonus_ranges[v6].minR;
             v32 = out_item->uEnchantmentType - 1;
             if ( v32 == 21 || v32 == 22 || v32 == 23 ) //Armsmaster skill, Dodge skill, Unarmed skill 
-                out_item->_bonus_strength = out_item->_bonus_strength/2;
-            if ( out_item->_bonus_strength <= 0 )
-                out_item->_bonus_strength = 1;
+                out_item->m_enchantmentStrength = out_item->m_enchantmentStrength/2;
+            if ( out_item->m_enchantmentStrength <= 0 )
+                out_item->m_enchantmentStrength = 1;
             return;
             
             }
@@ -1915,6 +1922,482 @@
     return false;
 
 }
+
+std::map<int, std::map<CHARACTER_ATTRIBUTE_TYPE, CEnchantment*>* >ItemGen::regularBonusMap;
+std::map<int, std::map<CHARACTER_ATTRIBUTE_TYPE, CEnchantment*>* >ItemGen::specialBonusMap;
+std::map<int, std::map<CHARACTER_ATTRIBUTE_TYPE, CEnchantment*>* >ItemGen::artifactBonusMap;
+
+#define NEWBONUSINTOSPECIALLIST(x,y) AddToMap(ItemGen::specialBonusMap, enchId, x, y);
+#define NEWBONUSINTOSPECIALLIST2(x,y,z) AddToMap(ItemGen::specialBonusMap, enchId, x, y, z);
+
+#define NEWBONUSINTOREGULARLIST(x) AddToMap(ItemGen::regularBonusMap, enchId, x);
+
+#define NEWBONUSINTOARTIFACTLIST(x,y) AddToMap(ItemGen::artifactBonusMap, itemId, x, y);
+#define NEWBONUSINTOARTIFACTLIST2(x,y,z) AddToMap(ItemGen::artifactBonusMap, itemId, x, y, z);
+
+void ItemGen::AddToMap( std::map<int, std::map<CHARACTER_ATTRIBUTE_TYPE, CEnchantment*>* > &maptoadd, int enchId, CHARACTER_ATTRIBUTE_TYPE attrId, int bonusValue /*= 0*/, unsigned __int16 Player::* skillPtr /*= NULL*/ )
+{
+  auto key = maptoadd.find(enchId);
+  std::map<CHARACTER_ATTRIBUTE_TYPE, CEnchantment*>* currMap;
+  if (key == maptoadd.end())
+  {
+    currMap = new std::map<CHARACTER_ATTRIBUTE_TYPE, CEnchantment*>;
+    maptoadd[enchId] = currMap;
+  }
+  else
+  {
+    currMap = key->second;
+  }
+  Assert(currMap->find(attrId) == currMap->end(), "Attribute %d already present for enchantment %d", attrId, enchId);
+  (*currMap)[attrId] = new CEnchantment(bonusValue, skillPtr);
+}
+
+void ItemGen::PopulateSpecialBonusMap()
+{
+  int enchId = 1;// of Protection, +10 to all Resistances
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_RESIST_FIRE, 10);
+  NEWBONUSINTOSPECIALLIST( CHARACTER_ATTRIBUTE_RESIST_AIR, 10);
+  NEWBONUSINTOSPECIALLIST( CHARACTER_ATTRIBUTE_RESIST_WATER, 10);
+  NEWBONUSINTOSPECIALLIST( CHARACTER_ATTRIBUTE_RESIST_EARTH, 10);
+  NEWBONUSINTOSPECIALLIST( CHARACTER_ATTRIBUTE_RESIST_MIND, 10);
+  NEWBONUSINTOSPECIALLIST( CHARACTER_ATTRIBUTE_RESIST_BODY, 10);
+
+  enchId = 2;//of The Gods, +10 to all Seven Statistics
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_STRENGTH, 10);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_INTELLIGENCE, 10);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_WILLPOWER, 10);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_ENDURANCE, 10);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_ACCURACY, 10);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_SPEED, 10);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_LUCK, 10);
+
+  enchId = 26;//of Air Magic
+  NEWBONUSINTOSPECIALLIST2(CHARACTER_ATTRIBUTE_SKILL_AIR,0, &Player::skillAir);
+
+  enchId = 27;//of Body Magic
+  NEWBONUSINTOSPECIALLIST2(CHARACTER_ATTRIBUTE_SKILL_BODY,0, &Player::skillBody);
+
+  enchId = 28;//of Dark Magic
+  NEWBONUSINTOSPECIALLIST2(CHARACTER_ATTRIBUTE_SKILL_DARK,0, &Player::skillDark);
+
+  enchId = 29;//of Earth Magic
+  NEWBONUSINTOSPECIALLIST2(CHARACTER_ATTRIBUTE_SKILL_EARTH,0, &Player::skillEarth);
+
+  enchId = 30;//of Fire Magic
+  NEWBONUSINTOSPECIALLIST2(CHARACTER_ATTRIBUTE_SKILL_FIRE,0, &Player::skillFire);
+
+  enchId = 31;//of Light Magic
+  NEWBONUSINTOSPECIALLIST2(CHARACTER_ATTRIBUTE_SKILL_LIGHT,0, &Player::skillLight);
+
+  enchId = 32;//of Mind Magic
+  NEWBONUSINTOSPECIALLIST2(CHARACTER_ATTRIBUTE_SKILL_MIND,0, &Player::skillMind);
+
+  enchId = 33;//of Spirit Magic
+  NEWBONUSINTOSPECIALLIST2(CHARACTER_ATTRIBUTE_SKILL_SPIRIT,0, &Player::skillSpirit);
+
+  enchId = 34;//of Water Magic
+  NEWBONUSINTOSPECIALLIST2(CHARACTER_ATTRIBUTE_SKILL_WATER,0, &Player::skillWater);
+
+  enchId = 42;//of Doom
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_STRENGTH, 1);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_INTELLIGENCE, 1);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_WILLPOWER, 1);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_ENDURANCE, 1);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_ACCURACY, 1);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_SPEED, 1);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_LUCK, 1);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_HEALTH, 1);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_MANA, 1);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_AC_BONUS, 1);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_RESIST_FIRE, 1);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_RESIST_AIR, 1);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_RESIST_WATER, 1);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_RESIST_EARTH, 1);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_RESIST_MIND, 1);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_RESIST_BODY, 1);
+
+  enchId = 43;//of Earth
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_ENDURANCE, 10);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_AC_BONUS, 10);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_HEALTH, 10);
+
+  enchId = 44;//of Life
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_HEALTH, 10);
+
+  enchId = 45;//Rogues
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_SPEED, 5);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_ACCURACY, 5);
+
+  enchId = 46;//of The Dragon
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_STRENGTH, 25);
+
+  enchId = 47;//of The Eclipse
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_MANA, 10);
+
+  enchId = 48;//of The Golem
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_ENDURANCE, 15);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_AC_BONUS, 5);
+
+  enchId = 49;//of The Moon
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_INTELLIGENCE, 10);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_LUCK, 10);
+
+  enchId = 50;//of The Phoenix
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_RESIST_FIRE, 30);
+
+  enchId = 51;//of The Sky
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_MANA, 10);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_SPEED, 10);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_INTELLIGENCE, 10);
+
+  enchId = 52;//of The Stars
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_ENDURANCE, 10);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_ACCURACY, 10);
+
+  enchId = 53;//of The Sun
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_STRENGTH, 10);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_WILLPOWER, 10);
+
+  enchId = 54;//of The Troll
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_ENDURANCE, 15);
+
+  enchId = 55;//of The Unicorn
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_LUCK, 15);
+
+  enchId = 56;//Warriors
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_STRENGTH, 5);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_ENDURANCE, 5);
+
+  enchId = 57;//Wizards
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_INTELLIGENCE, 5);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_WILLPOWER, 5);
+
+  enchId = 60;//Monks'
+  NEWBONUSINTOSPECIALLIST2(CHARACTER_ATTRIBUTE_SKILL_DODGE, 3, &Player::skillDodge);
+  NEWBONUSINTOSPECIALLIST2(CHARACTER_ATTRIBUTE_SKILL_UNARMED, 3, &Player::skillUnarmed);
+
+  enchId = 61;//Thieves'
+  NEWBONUSINTOSPECIALLIST2(CHARACTER_ATTRIBUTE_SKILL_TRAP_DISARM, 3, &Player::skillStealing);
+  NEWBONUSINTOSPECIALLIST2(CHARACTER_ATTRIBUTE_SKILL_STEALING, 3, &Player::skillDisarmTrap);
+
+  enchId = 62;//of Identifying
+  NEWBONUSINTOSPECIALLIST2(CHARACTER_ATTRIBUTE_SKILL_ITEM_ID, 3, &Player::skillItemId);
+  NEWBONUSINTOSPECIALLIST2(CHARACTER_ATTRIBUTE_SKILL_MONSTER_ID, 3, &Player::skillMonsterId);
+
+  enchId = 67;//Assassins'
+  NEWBONUSINTOSPECIALLIST2(CHARACTER_ATTRIBUTE_SKILL_TRAP_DISARM, 2, &Player::skillDisarmTrap);
+
+  enchId = 68;//Barbarians'
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_AC_BONUS, 5);
+
+  enchId = 69;//of the Storm
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_RESIST_AIR, 20);
+
+  enchId = 70;//of the Ocean
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_RESIST_WATER, 10);
+  NEWBONUSINTOSPECIALLIST2(CHARACTER_ATTRIBUTE_SKILL_ALCHEMY, 2, &Player::skillAlchemy);
+}
+
+void ItemGen::PopulateRegularBonusMap()
+{
+  int enchId = 1;//of Might
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_STRENGTH);
+
+  enchId = 2;//of Thought
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_INTELLIGENCE);
+
+  enchId = 3;//of Charm
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_WILLPOWER);
+
+  enchId = 4;//of Vigor 
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_ENDURANCE);
+
+  enchId = 5;//of Precision 
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_ACCURACY);
+
+  enchId = 6;//of Speed 
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_SPEED);
+
+  enchId = 7;//of Luck 
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_LUCK);
+
+  enchId = 8;//of Health 
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_HEALTH);
+
+  enchId = 9;//of Magic 
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_MANA);
+
+  enchId = 10;//of Defense 
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_AC_BONUS);
+
+  enchId = 11;//of Fire Resistance 
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_RESIST_FIRE);
+
+  enchId = 12;//of Air Resistance 
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_RESIST_AIR);
+
+  enchId = 13;//of Water Resistance 
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_RESIST_WATER);
+
+  enchId = 14;//of Earth Resistance 
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_RESIST_EARTH);
+
+  enchId = 15;//of Mind Resistance 
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_RESIST_MIND);
+
+  enchId = 16;//of Body Resistance 
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_RESIST_BODY);
+
+  enchId = 17;//of Alchemy 
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_SKILL_ALCHEMY);
+
+  enchId = 18;//of Stealing 
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_SKILL_STEALING);
+
+  enchId = 19;//of Disarming 
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_SKILL_TRAP_DISARM);
+
+  enchId = 20;//of Items 
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_SKILL_ITEM_ID);
+
+  enchId = 21;//of Monsters 
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_SKILL_MONSTER_ID);
+
+  enchId = 22;//of Arms 
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_SKILL_ARMSMASTER);
+
+  enchId = 23;//of Dodging 
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_SKILL_DODGE);
+
+  enchId = 24;//of the Fist
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_SKILL_UNARMED);
+}
+
+void ItemGen::PopulateArtifactBonusMap()
+{
+  int itemId;
+  itemId = ITEM_ARTIFACT_PUCK;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_STRENGTH, 40);
+
+  itemId = ITEM_ARTIFACT_IRON_FEATHER;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_STRENGTH, 40);
+
+  itemId = ITEM_ARTIFACT_WALLACE;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_WILLPOWER, 40);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_ARMSMASTER, 10);
+
+  itemId = ITEM_ARTIFACT_CORSAIR;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_LUCK, 40);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_TRAP_DISARM, 5);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_STEALING, 5);
+
+  itemId = ITEM_ARTICACT_GOVERNONS_ARMOR;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_STRENGTH, 10);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_INTELLIGENCE, 10);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_WILLPOWER, 10);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_ENDURANCE, 10);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_ACCURACY, 10);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SPEED, 10);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_LUCK, 10);
+
+  itemId = ITEM_ARTIFACT_YORUBA;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_ENDURANCE, 25);
+
+  itemId = ITEM_ARTIFACT_SPLITTER;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_FIRE, 50);
+
+  itemId = ITEM_ARTEFACT_ULLYSES,
+    NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_ACCURACY, 50);
+
+  itemId = ITEM_ARTEFACT_HANDS_OF_THE_MASTER,
+    NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_DODGE, 10);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_UNARMED, 10);
+
+  itemId = ITEM_ARTIFACT_LEAGUE_BOOTS;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SPEED, 40);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_WATER, 0, &Player::skillWater);
+
+  itemId = ITEM_ARTIFACT_RULERS_RING;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_MIND, 0, &Player::skillMind);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_DARK, 0, &Player::skillDark);
+
+  itemId = ITEM_RELIC_MASH;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_STRENGTH, 150);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_INTELLIGENCE, -40);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_WILLPOWER, -40);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SPEED, -40);
+
+  itemId = ITEM_RELIC_ETHRICS_STAFF;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_DARK, 0, &Player::skillDark);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_MEDITATION, 15);
+
+  itemId = ITEM_RELIC_HARECS_LEATHER;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_TRAP_DISARM, 5);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_STEALING, 5);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_LUCK, 50);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_FIRE, -10);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_WATER, -10);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_AIR, -10);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_EARTH, -10);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_MIND, -10);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_BODY, -10);
+
+  itemId = ITEM_RELIC_OLD_NICK;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_TRAP_DISARM, 5);
+
+  itemId = ITEM_RELIC_AMUCK;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_STRENGTH, 100);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_ENDURANCE, 100);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_AC_BONUS, -15);
+
+  itemId = ITEM_RELIC_GLORY_SHIELD;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_SPIRIT, 0, &Player::skillSpirit);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_SHIELD, 5);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_MIND, -10);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_BODY, -10);
+
+  itemId = ITEM_RELIC_KELEBRIM;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_ENDURANCE, 50);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_EARTH, -30);
+
+  itemId = ITEM_RELIC_TALEDONS_HELM;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_LIGHT, 0, &Player::skillLight);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_WILLPOWER, 15);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_STRENGTH, 15);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_LUCK, -40);
+
+  itemId = ITEM_RELIC_SCHOLARS_CAP;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_LEARNING, +15);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_ENDURANCE, -50);
+
+  itemId = ITEM_RELIC_PHYNAXIAN_CROWN;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_FIRE, 0, &Player::skillFire);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_WATER, +50);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_WILLPOWER, 30);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_AC_BONUS, -20);
+
+  itemId = ITEM_RILIC_TITANS_BELT;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_STRENGTH, 75);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SPEED, -40);
+
+  itemId = ITEM_RELIC_TWILIGHT;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SPEED, 50);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_LUCK, 50);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_FIRE, -15);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_WATER, -15);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_AIR, -15);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_EARTH, -15);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_MIND, -15);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_BODY, -15);
+
+  itemId = ITEM_RELIC_ANIA_SELVING;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_ACCURACY, 150);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_BOW, 5);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_AC_BONUS, -25);
+
+  itemId = ITEM_RELIC_JUSTICE;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_MIND, 0, &Player::skillMind);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_BODY, 0, &Player::skillBody);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SPEED, -40);
+
+  itemId = ITEM_RELIC_MEKORIGS_HAMMER;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_SPIRIT, 0, &Player::skillSpirit);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_STRENGTH, 75);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_AIR, -50);
+
+  itemId = ITEM_ARTIFACT_HERMES_SANDALS;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SPEED, 100);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_ACCURACY, 50);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_AIR, 50);
+
+  itemId = ITEM_ARTIFACT_CLOAK_OF_THE_SHEEP;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_WILLPOWER, -20);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_INTELLIGENCE, -20);
+
+  itemId = ITEM_ARTIFACT_MINDS_EYE;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_WILLPOWER, 15);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_INTELLIGENCE, 15);
+
+  itemId = ITEM_ELVEN_CHAINMAIL;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SPEED, 15);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_ACCURACY, 15);
+
+  itemId = ITEM_FORGE_GAUNTLETS;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_STRENGTH, 15);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_ENDURANCE, 15);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_FIRE, 30);
+
+  itemId = ITEM_ARTIFACT_HEROS_BELT;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_STRENGTH, 15);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_ARMSMASTER, 5);
+}
+
+void ItemGen::GetItemBonusSpecialEnchantment( Player* owner, CHARACTER_ATTRIBUTE_TYPE attrToGet, int* additiveBonus, int* halfSkillBonus )
+{
+  auto bonusList = ItemGen::specialBonusMap.find(this->uSpecEnchantmentType);
+  if (bonusList == ItemGen::specialBonusMap.end())
+  {
+    return;
+  }
+  std::map<CHARACTER_ATTRIBUTE_TYPE, CEnchantment*>* currList = bonusList->second;
+  if (currList->find(attrToGet) != currList->end())
+  {
+    CEnchantment* currBonus = (*currList)[attrToGet];
+    if (currBonus->statPtr != NULL)
+    {
+      if (currBonus->statBonus == 0)
+      {
+        *halfSkillBonus = owner->*currBonus->statPtr / 2;
+      }
+      else
+      {
+        if (*additiveBonus < currBonus->statBonus)
+        {
+          *additiveBonus = currBonus->statBonus;
+        }
+      }
+    }
+    else
+    {
+      *additiveBonus += currBonus->statBonus;
+    }
+  }
+}
+
+void ItemGen::GetItemBonusArtifact( Player* owner, CHARACTER_ATTRIBUTE_TYPE attrToGet, int* bonusSum )
+{
+  auto bonusList = ItemGen::artifactBonusMap.find(this->uItemID);
+  if (bonusList == ItemGen::artifactBonusMap.end())
+  {
+    return;
+  }
+  std::map<CHARACTER_ATTRIBUTE_TYPE, CEnchantment*>* currList = bonusList->second;
+  if (currList->find(attrToGet) != currList->end())
+  {
+    CEnchantment* currBonus = (*currList)[attrToGet];
+    if (currBonus->statPtr != NULL)
+    {
+      *bonusSum = owner->*currBonus->statPtr / 2;
+    }
+    else
+    {
+      *bonusSum += currBonus->statBonus;
+    }
+  }
+}
+
+bool ItemGen::IsRegularEnchanmentForAttribute( CHARACTER_ATTRIBUTE_TYPE attrToGet )
+{
+  auto bonusList = ItemGen::specialBonusMap.find(this->uSpecEnchantmentType);
+  if (bonusList == ItemGen::specialBonusMap.end())
+  {
+    return false;
+  }
+  std::map<CHARACTER_ATTRIBUTE_TYPE, CEnchantment*>* currList = bonusList->second;
+  return (currList->find(attrToGet) != currList->end());
+  return false;
+}
+
 //----- (004B8E3D) --------------------------------------------------------
 void GenerateStandartShopItems()
 	{
--- a/Items.h	Tue Sep 17 12:37:07 2013 +0200
+++ b/Items.h	Tue Sep 17 12:40:37 2013 +0200
@@ -1,5 +1,6 @@
 #pragma once
 #include <array>
+#include <map>
 
 enum DAMAGE_TYPE:unsigned int
     {
@@ -135,10 +136,22 @@
   ITEM_FORGE_GAUNTLETS = 534,
   ITEM_ARTIFACT_HEROS_BELT = 535,//217
   ITEM_ARTIFACT_LADYS_ESCORT = 536,
+  ITEM_RARE_CLANKERS_AMULET = 537,
+  ITEM_RARE_LIETENANTS_CUTLASS = 538,
+  ITEM_RARE_MEDUSAS_MIRROR = 539,
+  ITEM_RARE_LADY_CARMINES_DAGGER = 540,
+  ITEM_RARE_VILLAINS_BLADE = 541,
+  ITEM_RARE_PERFECT_BOW = 542,
+  ITEM_RARE_PERFECT_BOW_FIXED = 543,
   ITEM_RARE_SHADOWS_MASK = 544,//220
+  ITEM_RARE_GHOST_RING = 545,//220
+  ITEM_RARE_FAERIE_RING = 546,//220
   ITEM_RARE_SUN_CLOAK = 547,//223
   ITEM_RARE_MOON_CLOAK = 548,//224
+  ITEM_RARE_ZOKKARS_AXE = 549,//224
   ITEM_RARE_VAMPIRES_CAPE = 550,//226
+  ITEM_RARE_MINOTAURS_AXE = 551,//226
+  ITEM_RARE_GROGNARDS_CUTLASS = 552,//226
   ITEM_LICH_JAR_FULL = 601,
   ITEM_WETSUIT = 604,
   ITEM_LICH_JAR_EMPTY = 615,
@@ -173,7 +186,19 @@
   EQUIP_NONE           = 20
 };
 
+enum CHARACTER_ATTRIBUTE_TYPE; 
+struct Player; 
 
+typedef struct CEnchantment
+{
+  CEnchantment(int bonus, unsigned __int16 Player::* skillPtr = NULL):
+statBonus(bonus),
+  statPtr(skillPtr)
+{
+}
+int statBonus;
+unsigned __int16 Player::* statPtr;
+} CEnchantment;
 
 /*   64 */
 #pragma pack(push, 1)
@@ -184,6 +209,23 @@
  // {
  //   Reset();
  // }
+  static void AddToMap(std::map<int, std::map<CHARACTER_ATTRIBUTE_TYPE, CEnchantment*>* > &maptoadd, 
+    int enchId, 
+    CHARACTER_ATTRIBUTE_TYPE attrId, 
+    int bonusValue = 0, 
+    unsigned __int16 Player::* skillPtr = NULL);
+
+  static std::map<int, std::map<CHARACTER_ATTRIBUTE_TYPE, CEnchantment*>* > regularBonusMap;
+  static std::map<int, std::map<CHARACTER_ATTRIBUTE_TYPE, CEnchantment*>* > specialBonusMap;
+  static std::map<int, std::map<CHARACTER_ATTRIBUTE_TYPE, CEnchantment*>* > artifactBonusMap;
+
+  static void PopulateSpecialBonusMap();
+  static void PopulateRegularBonusMap();
+  static void PopulateArtifactBonusMap();
+
+  void GetItemBonusSpecialEnchantment(Player* owner, CHARACTER_ATTRIBUTE_TYPE attrToGet, int* additiveBonus, int* halfSkillBonus);
+  void GetItemBonusArtifact(Player* owner, CHARACTER_ATTRIBUTE_TYPE attrToGet, int* bonusSum);
+  bool IsRegularEnchanmentForAttribute(CHARACTER_ATTRIBUTE_TYPE attrToGet);
 
   inline bool IsBroken()        {return (uAttributes & ITEM_BROKEN) != 0;}
   inline void SetBroken()     {uAttributes |= ITEM_BROKEN;}
@@ -204,7 +246,7 @@
 
   int uItemID; //0
   int uEnchantmentType; //4
-  int _bonus_strength;  //8
+  int m_enchantmentStrength;  //8
   int uSpecEnchantmentType; // 25  +5 levels //0c
                             // 16  Drain Hit Points from target.
                             // 35  Increases chance of disarming.
--- a/Math.h	Tue Sep 17 12:37:07 2013 +0200
+++ b/Math.h	Tue Sep 17 12:40:37 2013 +0200
@@ -25,6 +25,7 @@
 #pragma pack(pop)
 
 __int64 fixpoint_sub0(int, int);
+__int64 fixpoint_sub2(int, int);
 __int64 fixpoint_dot(int x1, int x2, int y1, int y2, int z1, int z2);
 __int64 fixpoint_div(int, int);
 __int64 fixpoint_mul(int, int);
--- a/NPC.cpp	Tue Sep 17 12:37:07 2013 +0200
+++ b/NPC.cpp	Tue Sep 17 12:40:37 2013 +0200
@@ -1647,7 +1647,7 @@
     else
     {
       for ( i = 0; i < uNumDialogueNPCPortraits; ++i )
-        dword_5913F4[i]->Release();
+        HouseNPCPortraitsButtonsList[i]->Release();
     }
     pDialogueWindow = GUIWindow::Create(0, 0, 640, 0x159u, WINDOW_MainMenu, 0, 0);
     pBtn_ExitCancel = pDialogueWindow->CreateButton(  471u,  445u,  169u, 35u,  1,   0, UIMSG_Escape,  0,  0,
--- a/Outdoor.cpp	Tue Sep 17 12:37:07 2013 +0200
+++ b/Outdoor.cpp	Tue Sep 17 12:40:37 2013 +0200
@@ -447,7 +447,10 @@
   {
     if ( v9 == 4 ) // to & from Shoals
     {
-      if ( sub_43EE77_ProbablyIfUnderwaterSuitIsEquipped(0) )
+      if ( pPlayers[1]->HasUnderwaterSuitEquipped() &&
+           pPlayers[2]->HasUnderwaterSuitEquipped() &&
+           pPlayers[3]->HasUnderwaterSuitEquipped() &&
+           pPlayers[4]->HasUnderwaterSuitEquipped())
       {
         uDefaultTravelTime_ByFoot = 1;
         strcpy(pOut, "out15.odm");
--- a/Player.cpp	Tue Sep 17 12:37:07 2013 +0200
+++ b/Player.cpp	Tue Sep 17 12:40:37 2013 +0200
@@ -156,8 +156,6 @@
    30   // PLAYER_SKILL_PLATE
 };
 
-
-
 //----- (00490913) --------------------------------------------------------
 int PlayerCreation_GetUnspentAttributePointCount()
 {
@@ -1140,7 +1138,7 @@
 {
   unsigned __int16 v2; // ax@1
   int v5; // edi@7
-
+  return true;
   if (CheckHiredNPCSpeciality(Scholar))
     return true;
 
@@ -1406,49 +1404,49 @@
 //----- (0048C855) --------------------------------------------------------
 int Player::GetBaseStrength()
 {
-  return this->uMight + GetItemsBonus(CHARACTER_ATTRIBUTE_STRENGTH, 0);
+  return this->uMight + GetItemsBonus(CHARACTER_ATTRIBUTE_STRENGTH);
 }
 
 //----- (0048C86C) --------------------------------------------------------
 int Player::GetBaseIntelligence()
 {
-  return this->uIntelligence + GetItemsBonus(CHARACTER_ATTRIBUTE_INTELLIGENCE, 0);
+  return this->uIntelligence + GetItemsBonus(CHARACTER_ATTRIBUTE_INTELLIGENCE);
 }
 
 //----- (0048C883) --------------------------------------------------------
 int Player::GetBaseWillpower()
 {
-  return this->uWillpower + GetItemsBonus(CHARACTER_ATTRIBUTE_WILLPOWER, 0);
+  return this->uWillpower + GetItemsBonus(CHARACTER_ATTRIBUTE_WILLPOWER);
 }
 
 //----- (0048C89A) --------------------------------------------------------
 int Player::GetBaseEndurance()
 {
-  return this->uEndurance + GetItemsBonus(CHARACTER_ATTRIBUTE_ENDURANCE, 0);
+  return this->uEndurance + GetItemsBonus(CHARACTER_ATTRIBUTE_ENDURANCE);
 }
 
 //----- (0048C8B1) --------------------------------------------------------
 int Player::GetBaseAccuracy()
 {
-  return this->uAccuracy + GetItemsBonus(CHARACTER_ATTRIBUTE_ACCURACY, 0);
+  return this->uAccuracy + GetItemsBonus(CHARACTER_ATTRIBUTE_ACCURACY);
 }
 
 //----- (0048C8C8) --------------------------------------------------------
 int Player::GetBaseSpeed()
 {
-  return this->uSpeed + GetItemsBonus(CHARACTER_ATTRIBUTE_SPEED, 0);
+  return this->uSpeed + GetItemsBonus(CHARACTER_ATTRIBUTE_SPEED);
 }
 
 //----- (0048C8DF) --------------------------------------------------------
 int Player::GetBaseLuck()
 {
-  return this->uLuck + GetItemsBonus(CHARACTER_ATTRIBUTE_LUCK, 0);
+  return this->uLuck + GetItemsBonus(CHARACTER_ATTRIBUTE_LUCK);
 }
 
 //----- (0048C8F6) --------------------------------------------------------
 int Player::GetBaseLevel()
 {
-  return this->uLevel + GetItemsBonus(CHARACTER_ATTRIBUTE_LEVEL, 0);
+  return this->uLevel + GetItemsBonus(CHARACTER_ATTRIBUTE_LEVEL);
 }
 
 //----- (0048C90D) --------------------------------------------------------
@@ -1456,7 +1454,7 @@
 {
   return uLevel + sLevelModifier +
          GetMagicalBonus(CHARACTER_ATTRIBUTE_LEVEL) +
-         GetItemsBonus(CHARACTER_ATTRIBUTE_LEVEL, 0);
+         GetItemsBonus(CHARACTER_ATTRIBUTE_LEVEL);
 }
 
 //----- (0048C93C) --------------------------------------------------------
@@ -1527,7 +1525,7 @@
 
   auto uConditionMult = pConditionAttributeModifier[attrId][GetMajorConditionIdx()];
   int magicBonus = GetMagicalBonus(attrId);
-  int itemBonus = GetItemsBonus(attrId, 0);
+  int itemBonus = GetItemsBonus(attrId);
   return uConditionMult * uAgeingMultiplier * this->*attrValue / 100 / 100
     + magicBonus
     + itemBonus
@@ -1560,7 +1558,7 @@
  
   v2 = GetActualMight();
   v3 = GetParameterBonus(v2);
-  v4 = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MIN, 0) + v3;
+  v4 = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MIN) + v3;
   v5 = GetSkillBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS) + v4;
   result = _melee_dmg_bonus + GetMagicalBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS) + v5;
   if ( result < 1 )
@@ -1580,7 +1578,7 @@
 
   v2 = GetActualMight();
   v3 = GetParameterBonus(v2);
-  v4 = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MAX, 0) + v3;
+  v4 = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MAX) + v3;
   v5 = GetSkillBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS) + v4;
   v6 = this->_melee_dmg_bonus + GetMagicalBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS) + v5;
   result = 1;
@@ -1700,7 +1698,7 @@
   {
     v4 = GetActualAccuracy();
     v5 = GetParameterBonus(v4);
-    v6 = GetItemsBonus(CHARACTER_ATTRIBUTE_RANGED_ATTACK, 0) + v5;
+    v6 = GetItemsBonus(CHARACTER_ATTRIBUTE_RANGED_ATTACK) + v5;
     v7 = GetSkillBonus(CHARACTER_ATTRIBUTE_RANGED_ATTACK) + v6;
     v3 = this->_ranged_atk_bonus + GetMagicalBonus(CHARACTER_ATTRIBUTE_RANGED_ATTACK) + v7;
   }
@@ -1719,7 +1717,7 @@
   int v4; // edi@1
   int result; // eax@6
 
-  v2 = GetItemsBonus(CHARACTER_ATTRIBUTE_RANGED_DMG_MIN, 0);
+  v2 = GetItemsBonus(CHARACTER_ATTRIBUTE_RANGED_DMG_MIN);
   v3 = GetSkillBonus(CHARACTER_ATTRIBUTE_RANGED_DMG_BONUS) + v2;
   v4 = this->_ranged_dmg_bonus + GetMagicalBonus(CHARACTER_ATTRIBUTE_RANGED_DMG_BONUS) + v3;
   if ( v4 >= 1 )
@@ -1737,7 +1735,7 @@
   int v4; // edi@1
   int result; // eax@6
 
-  v2 = GetItemsBonus(CHARACTER_ATTRIBUTE_RANGED_DMG_MAX, 0);
+  v2 = GetItemsBonus(CHARACTER_ATTRIBUTE_RANGED_DMG_MAX);
   v3 = GetSkillBonus(CHARACTER_ATTRIBUTE_RANGED_DMG_BONUS) + v2;
   v4 = this->_ranged_dmg_bonus + GetMagicalBonus(CHARACTER_ATTRIBUTE_RANGED_DMG_BONUS) + v3;
   if ( v4 >= 1 )
@@ -1813,8 +1811,8 @@
   }
   else if (pEquipment.uMainHand >= 0 && (itemid == ITEM_BLASTER || itemid == ITEM_LASER_RIFLE))
   {
-    min_damage = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MIN, 1);
-    max_damage = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MAX, 1);
+    min_damage = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MIN, true);
+    max_damage = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MAX, true);
   }
   else
   {
@@ -1853,8 +1851,8 @@
     }
     else if (pEquipment.uMainHand >= 0 && (itemid == ITEM_BLASTER || itemid == ITEM_LASER_RIFLE))
     {
-      min_damage = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MIN, 1);
-      max_damage = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MAX, 1);
+      min_damage = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MIN, true);
+      max_damage = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MAX, true);
     }
     else
     {
@@ -2261,7 +2259,7 @@
   broke_armor = sHealth <= -10;
   if ( sHealth < 1 ) //
   {
-    if ( (sHealth + uEndurance + GetItemsBonus(CHARACTER_ATTRIBUTE_ENDURANCE, 0) >= 1)
+    if ( (sHealth + uEndurance + GetItemsBonus(CHARACTER_ATTRIBUTE_ENDURANCE) >= 1)
       || pPlayerBuffs[PLAYER_BUFF_PRESERVATION].uExpireTime > 0 )
     {
       SetCondUnconsciousWithBlockCheck(false);
@@ -2663,23 +2661,18 @@
   uint      weapon_recovery = base_recovery_times_per_weapon_type[0];
   if (bRangedAttack)
   {
-    if ( !HasItemEquipped(EQUIP_BOW) )
-      goto LABEL_17;
-    weapon = &pInventoryItemList[pEquipment.uBow - 1];
-    weapon_desc = &pItemsTable->pItems[weapon->uItemID];
-    weapon_recovery = base_recovery_times_per_weapon_type[weapon_desc->uSkillType];
-    goto LABEL_17;
-  }
-  else if ( IsUnarmed() == 1 )
-  {
-    if (GetActualSkillLevel(PLAYER_SKILL_UNARMED))
-    {
+    if ( HasItemEquipped(EQUIP_BOW) )
+    {
+      weapon = &pInventoryItemList[pEquipment.uBow - 1];
+      weapon_desc = &pItemsTable->pItems[weapon->uItemID];
+      weapon_recovery = base_recovery_times_per_weapon_type[weapon_desc->uSkillType];
+    }
+  }
+  else if ( IsUnarmed() == 1 && GetActualSkillLevel(PLAYER_SKILL_UNARMED) > 0)
+  {
       weapon_recovery = base_recovery_times_per_weapon_type[1];
-      goto LABEL_17;
-    }
-  }
-
-  if ( HasItemEquipped(EQUIP_MAIN_HAND) )
+  }
+  else if ( HasItemEquipped(EQUIP_MAIN_HAND) )
   {
     weapon = &pInventoryItemList[pEquipment.uMainHand - 1];
     weapon_desc = &pItemsTable->pItems[weapon->uItemID];
@@ -2705,58 +2698,43 @@
     }
   }
 
-LABEL_17:
   uint armour_recovery = 0;
   if ( HasItemEquipped(EQUIP_ARMOUR) )
   {
     auto armour_skill_type = pItemsTable->pItems[pInventoryItemList[pEquipment.uArmor - 1].uItemID].uSkillType;
     uint base_armour_recovery = base_recovery_times_per_weapon_type[armour_skill_type];
-
-    float armour_recovery_multipliers[4];
+    float multiplier;
+
     if (armour_skill_type == PLAYER_SKILL_LEATHER)
     {
-      armour_recovery_multipliers[0] = 1.0f;
-      armour_recovery_multipliers[1] = 0;
-      armour_recovery_multipliers[2] = 0;
-      armour_recovery_multipliers[3] = 0;
+      multiplier = GetArmorRecoveryMultiplierFromSkillLevel(armour_skill_type, 1.0f, 0, 0, 0);
     }
     else if (armour_skill_type == PLAYER_SKILL_CHAIN)
     {
-      armour_recovery_multipliers[0] = 1.0f;
-      armour_recovery_multipliers[1] = 0.5f;
-      armour_recovery_multipliers[2] = 0;
-      armour_recovery_multipliers[3] = 0;
+      multiplier = GetArmorRecoveryMultiplierFromSkillLevel(armour_skill_type, 1.0f, 0.5f, 0, 0);
     }
     else if (armour_skill_type == PLAYER_SKILL_PLATE)
     {
-      armour_recovery_multipliers[0] = 1.0f;
-      armour_recovery_multipliers[1] = 0.5f;
-      armour_recovery_multipliers[2] = 0.5f;
-      armour_recovery_multipliers[3] = 0;
+      multiplier = GetArmorRecoveryMultiplierFromSkillLevel(armour_skill_type, 1.0f, 0.5f, 0.5f, 0);
     }
     else
     {
       Error("Unknown armour type"); // what kind of armour is that?
-      armour_recovery_multipliers[0] = 1.0f;
-      armour_recovery_multipliers[1] = 1.0f;
-      armour_recovery_multipliers[2] = 1.0f;
-      armour_recovery_multipliers[3] = 1.0f;
-    }
-
-    uint skill_mastery = SkillToMastery(pActiveSkills[armour_skill_type]);
-    armour_recovery = base_armour_recovery * armour_recovery_multipliers[skill_mastery - 1];
+      multiplier = GetArmorRecoveryMultiplierFromSkillLevel(armour_skill_type, 1.0f, 1.0f, 1.0f, 1.0f);
+    }
+
+    armour_recovery = (uint)(base_armour_recovery * multiplier);
   }
 
   uint shield_recovery = 0;
   if (HasItemEquipped(EQUIP_OFF_HAND) && GetEquippedItemEquipType(EQUIP_OFF_HAND) == EQUIP_SHIELD)
   {
-    float shield_recovery_multipliers[4] = {1, 0, 0, 0};
-
     auto shield = &pInventoryItemList[pEquipment.uShield - 1];
     auto skill_type = pItemsTable->pItems[shield->uItemID].uSkillType;
 
     uint shield_base_recovery = base_recovery_times_per_weapon_type[skill_type];
-    shield_recovery = shield_base_recovery * SkillToMastery(pActiveSkills[skill_type]);
+    float multiplier = GetArmorRecoveryMultiplierFromSkillLevel(skill_type, 1.0f, 0, 0, 0);
+    shield_recovery = (uint)(shield_base_recovery * multiplier);
   }
 
   uint player_speed_recovery_reduction = GetParameterBonus(GetActualSpeed()),
@@ -2785,9 +2763,9 @@
     }
   }
 
-  uint v41 = 0;
-  if (pPlayerBuffs[PLAYER_BUFF_7].uExpireTime > 0)
-    v41 = 25;
+  uint hasteRecoveryReduction = 0;
+  if (pPlayerBuffs[PLAYER_BUFF_HASTE].uExpireTime > 0 || pParty->pPartyBuffs[PARTY_BUFF_HASTE].uExpireTime > 0 )
+    hasteRecoveryReduction = 25;
 
   uint weapon_enchantment_recovery_reduction = 0;
   if ( weapon  )
@@ -2798,13 +2776,12 @@
       weapon_enchantment_recovery_reduction = 20;
   }
 
-
   int recovery = weapon_recovery +
                  armour_recovery +
                  shield_recovery
                  - armsmaster_recovery_reduction
                  - weapon_enchantment_recovery_reduction
-                 - v41
+                 - hasteRecoveryReduction
                  - sword_axe_bow_recovery_reduction
                  - player_speed_recovery_reduction;
 
@@ -2813,6 +2790,22 @@
   return recovery;
 }
 
+
+//----- new --------------------------------------------------------
+float Player::GetArmorRecoveryMultiplierFromSkillLevel( unsigned char armour_skill_type, float mult1, float mult2, float mult3, float mult4 )
+{
+  uint skill_mastery = SkillToMastery(pActiveSkills[armour_skill_type]);
+  switch (skill_mastery)
+  {
+    case 1: return mult1; break;
+    case 2: return mult2; break;
+    case 3: return mult3; break;
+    case 4: return mult4; break;
+  }
+  Error("Unexpected input value: %d", armour_skill_type);
+  return 0;
+}
+
 //----- (0048E4F8) --------------------------------------------------------
 int Player::GetMaxHealth()
 {
@@ -2825,10 +2818,8 @@
   v6 = uFullHealthBonus
      + pBaseHealthByClass[classType / 4]
      + GetSkillBonus(CHARACTER_ATTRIBUTE_HEALTH)
-     + GetItemsBonus(CHARACTER_ATTRIBUTE_HEALTH, 0) + v4;
-  if (v6 <= 0)
-    return 1;
-  return v6;
+     + GetItemsBonus(CHARACTER_ATTRIBUTE_HEALTH) + v4;
+  return max(1, v6);
 }
 
 //----- (0048E565) --------------------------------------------------------
@@ -2842,7 +2833,6 @@
   int v7; // esi@6
   int v8; // esi@6
   int v9; // esi@6
-  int result; // eax@7
   
   switch (classType)
   {
@@ -2891,7 +2881,7 @@
       break;
   }
   v7 = pBaseManaPerLevelByClass[classType] * (GetActualLevel() + v3);
-  v8 = GetItemsBonus(CHARACTER_ATTRIBUTE_MANA, 0) + v7;
+  v8 = GetItemsBonus(CHARACTER_ATTRIBUTE_MANA) + v7;
   v9 = uFullManaBonus
       + pBaseManaByClass[classType / 4]
   + GetSkillBonus(CHARACTER_ATTRIBUTE_MANA)
@@ -2902,53 +2892,39 @@
 //----- (0048E656) --------------------------------------------------------
 int Player::GetBaseAC()
 {
-  Player *v1; // edi@1
   int v2; // eax@1
   int v3; // esi@1
   int v4; // esi@1
   int v5; // esi@1
-  int result; // eax@2
-
-  v1 = this;
+
   v2 = GetActualSpeed();
   v3 = GetParameterBonus(v2);
-  v4 = GetItemsBonus(CHARACTER_ATTRIBUTE_AC_BONUS, 0) + v3;
+  v4 = GetItemsBonus(CHARACTER_ATTRIBUTE_AC_BONUS) + v3;
   v5 = GetSkillBonus(CHARACTER_ATTRIBUTE_AC_BONUS) + v4;
-  if ( v5 >= 1 )
-    result = v5;
-  else
-    result = 0;
-  return result;
+  return max(0, v5);
 }
 
 //----- (0048E68F) --------------------------------------------------------
 int Player::GetActualAC()
 {
-  Player *v1; // edi@1
   int v2; // eax@1
   int v3; // esi@1
   int v4; // esi@1
   int v5; // esi@1
   int v6; // esi@1
-  int result; // eax@2
-
-  v1 = this;
+
   v2 = GetActualSpeed();
   v3 = GetParameterBonus(v2);
-  v4 = GetItemsBonus(CHARACTER_ATTRIBUTE_AC_BONUS, 0) + v3;
+  v4 = GetItemsBonus(CHARACTER_ATTRIBUTE_AC_BONUS) + v3;
   v5 = GetSkillBonus(CHARACTER_ATTRIBUTE_AC_BONUS) + v4;
-  v6 = v1->sACModifier + GetMagicalBonus(CHARACTER_ATTRIBUTE_AC_BONUS) + v5;
-  if ( v6 >= 1 )
-    result = v6;
-  else
-    result = 0;
-  return result;
+  v6 = this->sACModifier + GetMagicalBonus(CHARACTER_ATTRIBUTE_AC_BONUS) + v5;
+  return max(0, v6);
 }
 
 //----- (0048E6DC) --------------------------------------------------------
 unsigned int Player::GetBaseAge()
 {
-  return ((__int64)(pParty->uTimePlayed * 0.234375) / 60 / 60 / 24) / 7 / 4 / 12 - uBirthYear + game_starting_year;
+  return (unsigned int)(((__int64)(pParty->uTimePlayed * 0.234375) / 60 / 60 / 24) / 7 / 4 / 12 - uBirthYear + game_starting_year);
 }
 
 //----- (0048E72C) --------------------------------------------------------
@@ -2960,155 +2936,100 @@
 //----- (0048E73F) --------------------------------------------------------
 int Player::GetBaseResistance(enum CHARACTER_ATTRIBUTE_TYPE a2)
 {
-  Player *v2; // ebx@1
-  signed int v3; // esi@1
-  enum CHARACTER_RACE v4; // eax@1
-  signed int v5; // edi@8
-  char v6; // zf@9
   int v7; // esi@20
-  int result; // eax@21
-  signed int v9; // [sp-4h] [bp-10h]@11
-
-  v2 = this;
-  v3 = 0;
-  v4 = GetRace();
-  if ( a2 == CHARACTER_ATTRIBUTE_RESIST_FIRE )
-  {
-    v5 = 0;
-    goto LABEL_16;
-  }
-  if ( a2 == CHARACTER_ATTRIBUTE_RESIST_AIR )
-  {
-    v5 = 1;
-LABEL_16:
-    v6 = v4 == 2;
-    goto LABEL_17;
-  }
-  if ( a2 == CHARACTER_ATTRIBUTE_RESIST_WATER )
-  {
-    v6 = v4 == 3;
-    v5 = 2;
-    goto LABEL_17;
-  }
-  if ( a2 == CHARACTER_ATTRIBUTE_RESIST_EARTH )
-  {
-    v5 = 3;
-    v6 = v4 == 3;
-    goto LABEL_17;
-  }
-  if ( a2 == CHARACTER_ATTRIBUTE_RESIST_MIND )
-  {
-    v5 = 7;
-    if ( v4 != 1 )
-      goto LABEL_20;
-    v9 = 10;
-LABEL_19:
-    v3 = v9;
-    goto LABEL_20;
-  }
-  if ( a2 == CHARACTER_ATTRIBUTE_RESIST_BODY || a2 == 33 )
-  {
-    v5 = 8;
-    v6 = v4 == 0;
-LABEL_17:
-    if ( !v6 )
-      goto LABEL_20;
-    v9 = 5;
-    goto LABEL_19;
-  }
-  v5 = 0;
-LABEL_20:
-  v7 = GetItemsBonus(a2, 0) + v3;
-  if ( v2->classType != PLAYER_CLASS_LICH || (result = 200, v7 + *(&v2->sResFireBase + v5) <= 200) )
-    result = v7 + *(&v2->sResFireBase + v5);
-  return result;
+  int racialBonus = 0;
+  __int16* resStat;
+
+  switch (a2)
+  {
+    case CHARACTER_ATTRIBUTE_RESIST_FIRE:
+      resStat = &sResFireBase;
+      if (IsRaceGoblin())
+        racialBonus = 5;
+      break;
+    case CHARACTER_ATTRIBUTE_RESIST_AIR:
+      resStat = &sResAirBase;
+      if (IsRaceGoblin())
+        racialBonus = 5;
+      break;
+    case  CHARACTER_ATTRIBUTE_RESIST_WATER:
+      resStat = &sResWaterBase;
+      if (IsRaceDwarf())
+        racialBonus = 5;
+      break;
+    case CHARACTER_ATTRIBUTE_RESIST_EARTH:
+      resStat = &sResEarthBase;
+      if (IsRaceDwarf())
+        racialBonus = 5;
+    break;
+    case CHARACTER_ATTRIBUTE_RESIST_MIND:
+      resStat = &sResMindBase;
+      if (IsRaceElf())
+        racialBonus = 10;
+      break;
+    case CHARACTER_ATTRIBUTE_RESIST_BODY:
+    case CHARACTER_ATTRIBUTE_RESIST_SPIRIT:
+      resStat = &sResBodyBase;
+      if (IsRaceHuman())
+        racialBonus = 5;
+      break;
+  }
+  v7 = GetItemsBonus(a2) + racialBonus;
+  return v7 + *resStat;
 }
 
 //----- (0048E7D0) --------------------------------------------------------
 int Player::GetActualResistance(enum CHARACTER_ATTRIBUTE_TYPE a2)
 {
-  signed int v2; // edi@1
-  Player *v3; // esi@1
-  enum CHARACTER_RACE v4; // ebx@1
-  char v6; // zf@18
-  int v7; // ebx@28
-  int result; // eax@28
-  signed int v9; // [sp+10h] [bp-8h]@1
-  signed int v10; // [sp+14h] [bp-4h]@1
-
-  v2 = 0;
-  v3 = this;
-  v10 = 0;
-  v9 = 0;
-  v4 = GetRace();
+  signed int v10 = 0; // [sp+14h] [bp-4h]@1
+  __int16* resStat;
+  int result;
+  int baseRes;
+
+  int leatherArmorSkillLevel = GetActualSkillLevel(PLAYER_SKILL_LEATHER);
   if ( CheckHiredNPCSpeciality(Enchanter) )
     v10 = 20;
   if ( (a2 == CHARACTER_ATTRIBUTE_RESIST_FIRE
      || a2 == CHARACTER_ATTRIBUTE_RESIST_AIR
      || a2 == CHARACTER_ATTRIBUTE_RESIST_WATER
      || a2 == CHARACTER_ATTRIBUTE_RESIST_EARTH)
-    && SkillToMastery(v3->pActiveSkills[9]) == 4
+    && SkillToMastery(leatherArmorSkillLevel) == 4
     && HasItemEquipped(EQUIP_ARMOUR)
     && GetEquippedItemSkillType(EQUIP_ARMOUR) == PLAYER_SKILL_LEATHER )
-    v10 += v3->pActiveSkills[9] & 0x3F;
-  if ( a2 == CHARACTER_ATTRIBUTE_RESIST_FIRE )
-    goto LABEL_25;
-  if ( a2 == CHARACTER_ATTRIBUTE_RESIST_AIR )
-  {
-    v2 = 1;
-LABEL_25:
-    v6 = v4 == 2;
-LABEL_26:
-    if ( v6 )
-      v9 = 5;
-    goto LABEL_28;
-  }
-  if ( a2 == CHARACTER_ATTRIBUTE_RESIST_WATER )
-  {
-    v6 = v4 == 3;
-    v2 = 2;
-    goto LABEL_26;
-  }
-  if ( a2 == CHARACTER_ATTRIBUTE_RESIST_EARTH )
-  {
-    v2 = 3;
-    if ( v4 == 3 )
-      v10 += 5;
-  }
-  else
-  {
-    if ( a2 != CHARACTER_ATTRIBUTE_RESIST_MIND )
-    {
-      if ( a2 != CHARACTER_ATTRIBUTE_RESIST_BODY && a2 != 33 )
-        goto LABEL_28;
-      v2 = 8;
-      v6 = v4 == 0;
-      goto LABEL_26;
-    }
-    v2 = 7;
-    if ( v4 == 1 )
-      v9 = 10;
-  }
-LABEL_28:
-  v7 = GetItemsBonus(a2, 0);
-  result = v10 + GetMagicalBonus(a2) + v7 + v9 + *(&v3->sResFireBonus + v2) + *(&v3->sResFireBase + v2);
-  if ( v3->classType == PLAYER_CLASS_LICH )
-  {
-    if ( result > 200 )
-      result = 200;
-  }
+    v10 += leatherArmorSkillLevel & 0x3F;
+  switch (a2)
+  {
+  case CHARACTER_ATTRIBUTE_RESIST_FIRE:
+    resStat = &sResFireBonus;
+    break;
+  case CHARACTER_ATTRIBUTE_RESIST_AIR:
+    resStat = &sResAirBonus;
+    break;
+  case  CHARACTER_ATTRIBUTE_RESIST_WATER:
+    resStat = &sResWaterBonus;
+    break;
+  case CHARACTER_ATTRIBUTE_RESIST_EARTH:
+    resStat = &sResEarthBonus;
+    break;
+  case CHARACTER_ATTRIBUTE_RESIST_MIND:
+    resStat = &sResMindBonus;
+    break;
+  case CHARACTER_ATTRIBUTE_RESIST_BODY:
+  case CHARACTER_ATTRIBUTE_RESIST_SPIRIT:
+    resStat = &sResBodyBonus;
+    break;
+  }
+  baseRes = GetBaseResistance(a2);
+  result = v10 + GetMagicalBonus(a2) + baseRes + *(resStat);
   return result;
 }
 
 //----- (0048E8F5) --------------------------------------------------------
 bool Player::Recover(int dt)
 {
-  //Player *v2; // esi@1
-  signed __int64 v3; // qax@1
-  //bool result; // eax@4
-
-  //v2 = this;
-  v3 = (signed __int64)((double)(dt * _48EA46_calc_special_bonus_by_items(17)) * 0.01 + (double)dt);
+  int v3; // qax@1
+
+  v3 = (int)(dt * GetSpecialItemBonus(17) * 0.01 + dt);
 
   Log::Warning(L"Recover(dt = %u/%u - %u", dt, (uint)v3, (uint)uTimeToRecovery);
 
@@ -3161,969 +3082,393 @@
 
 //----- (0048EA1B) --------------------------------------------------------
 int Player::GetParameterBonus( int player_parameter )
-    {
+{
   int i; // eax@1
   i = 0;
   while (param_to_bonus_table[i])
-      { 
-      if (player_parameter >= param_to_bonus_table[i])
-          break;
-      ++i;    
-      }   
+  { 
+    if (player_parameter >= param_to_bonus_table[i])
+      break;
+    ++i;    
+  }   
   return parameter_to_bonus_value[i];
 }
 
 //----- (0048EA46) --------------------------------------------------------
-int Player::_48EA46_calc_special_bonus_by_items(int a2)
+int Player::GetSpecialItemBonus( int enchantmentId )
 {
   int inv_indx; // eax@3
 
-  for (int i=EQUIP_OFF_HAND; i<EQUIP_BOOK; ++i )
-      {
-      if ( !HasItemEquipped((ITEM_EQUIP_TYPE)i) )
-          continue;
+  for (int i = EQUIP_OFF_HAND; i < EQUIP_BOOK; ++i )
+  {
+    if ( HasItemEquipped((ITEM_EQUIP_TYPE)i) )
+    {
       inv_indx = pEquipment.pIndices[i]  - 1;
-      if (a2==17)
-          {
-          if ((pInventoryItemList[inv_indx].uSpecEnchantmentType==17)||(pInventoryItemList[inv_indx].uItemID==533)) //Elven Chainmail+Increases rate of Recovery
-              return 50;
-          }
-      if (a2==24)
-          {
-          if (pInventoryItemList[inv_indx].uSpecEnchantmentType==24) //Increased Knockback.
-              return 5;
-          }
+      if (enchantmentId == 17)
+      {
+        if ((pInventoryItemList[inv_indx].uSpecEnchantmentType == 17) || (pInventoryItemList[inv_indx].uItemID == 533)) //Elven Chainmail+Increases rate of Recovery
+          return 50;
       }
+      if (enchantmentId == 24) 
+      {
+        if (pInventoryItemList[inv_indx].uSpecEnchantmentType == 24) //Increased Knockback.
+          return 5;
+      }
+    }
+  }
   return 0;
 }
 
 //----- (0048EAAE) --------------------------------------------------------
-int Player::GetItemsBonus(CHARACTER_ATTRIBUTE_TYPE attr, int a3)
-{
-  CHARACTER_ATTRIBUTE_TYPE v3; // esi@1
- // signed int v4; // eax@1
+int Player::GetItemsBonus( enum CHARACTER_ATTRIBUTE_TYPE attr, bool getOnlyMainHandDmg /*= false*/ )
+{
   int v5; // edi@1
-  Player *v6; // ebx@1
-  Player *v8; // ecx@48
   int v9; // eax@49
-  int v10; // edx@49
-  Player *v11; // ecx@55
-  int v12; // eax@56
-  int v13; // edx@56
   int v14; // ecx@58
   int v15; // eax@58
-  Player *v16; // ecx@61
   int v17; // eax@62
-  Player *v18; // ecx@66
-  int v19; // eax@67
   int v20; // eax@69
-  Player *v21; // ecx@75
   int v22; // eax@76
   int v23; // edx@76
-  //int v24; // eax@79
   int v25; // ecx@80
   int v26; // edi@80
-  Player *v27; // ecx@84
-  int v28; // eax@85
-  int v29; // edx@85
-  Player *v30; // ecx@96
   int v31; // ebp@97
   int v32; // eax@98
   unsigned int v33; // eax@100
-  int v34; // eax@103
-  char v35; // zf@104
-  char v36; // zf@107
-  unsigned __int8 v37; // zf@119
-  char v38; // sf@119
-  unsigned __int8 v39; // of@119
-  char v40; // zf@122
-  char v41; // zf@145
-  char v42; // zf@164
-  char v43; // zf@173
-  char v44; // zf@189
-  char v45; // zf@198
-  char v46; // zf@239
-  int v47; // eax@268
-  int v48; // eax@269
-  int v49; // eax@291
-  char v50; // zf@295
-  int v51; // eax@306
-  int v52; // eax@307
-  char v53; // zf@312
-  char v54; // zf@336
-  char v55; // zf@348
   int v56; // eax@365
   int v57; // ebx@368
   signed int v58; // [sp-4h] [bp-20h]@10
-  signed int v59; // [sp-4h] [bp-20h]@71
-  signed int v60; // [sp-4h] [bp-20h]@347
   int v61; // [sp+10h] [bp-Ch]@1
   int v62; // [sp+14h] [bp-8h]@1
-  int v63; // [sp+18h] [bp-4h]@101
-  ItemGen *attra; // [sp+20h] [bp+4h]@101
-  unsigned int v65; // [sp+24h] [bp+8h]@95
+  ItemGen *currEquippedItem; // [sp+20h] [bp+4h]@101
   bool no_skills;
 
-  v3 = attr;
   v5 = 0;
-  v6 = this;
   v62 = 0;
   v61 = 0;
-
   
   no_skills=false;
   switch (attr)
+  {
+    case  CHARACTER_ATTRIBUTE_SKILL_ALCHEMY:      v58 = PLAYER_SKILL_ALCHEMY;      break;
+    case  CHARACTER_ATTRIBUTE_SKILL_STEALING:     v58 = PLAYER_SKILL_STEALING;     break;
+    case  CHARACTER_ATTRIBUTE_SKILL_TRAP_DISARM:  v58 = PLAYER_SKILL_TRAP_DISARM;  break;
+    case  CHARACTER_ATTRIBUTE_SKILL_ITEM_ID:      v58 = PLAYER_SKILL_ITEM_ID;      break;
+    case  CHARACTER_ATTRIBUTE_SKILL_MONSTER_ID:   v58 = PLAYER_SKILL_MONSTER_ID;   break;
+    case  CHARACTER_ATTRIBUTE_SKILL_ARMSMASTER:   v58 = PLAYER_SKILL_ARMSMASTER;   break;
+    case  CHARACTER_ATTRIBUTE_SKILL_DODGE:        v58 = PLAYER_SKILL_DODGE;        break;
+    case  CHARACTER_ATTRIBUTE_SKILL_UNARMED:      v58 = PLAYER_SKILL_UNARMED;      break;
+    case  CHARACTER_ATTRIBUTE_SKILL_FIRE:         v58 = PLAYER_SKILL_FIRE;         break;
+    case  CHARACTER_ATTRIBUTE_SKILL_AIR:          v58 = PLAYER_SKILL_AIR;          break;
+    case  CHARACTER_ATTRIBUTE_SKILL_WATER:        v58 = PLAYER_SKILL_WATER;        break;
+    case  CHARACTER_ATTRIBUTE_SKILL_EARTH:        v58 = PLAYER_SKILL_EARTH;        break;
+    case  CHARACTER_ATTRIBUTE_SKILL_SPIRIT:       v58 = PLAYER_SKILL_SPIRIT;       break;
+    case  CHARACTER_ATTRIBUTE_SKILL_MIND:         v58 = PLAYER_SKILL_MIND;         break;
+    case  CHARACTER_ATTRIBUTE_SKILL_BODY:         v58 = PLAYER_SKILL_BODY;         break;
+    case  CHARACTER_ATTRIBUTE_SKILL_LIGHT:        v58 = PLAYER_SKILL_LIGHT;        break;
+    case  CHARACTER_ATTRIBUTE_SKILL_DARK:         v58 = PLAYER_SKILL_DARK;         break;
+    case  CHARACTER_ATTRIBUTE_SKILL_MEDITATION:   v58 = PLAYER_SKILL_MEDITATION;   break;
+    case  CHARACTER_ATTRIBUTE_SKILL_BOW:          v58 = PLAYER_SKILL_BOW;          break;
+    case  CHARACTER_ATTRIBUTE_SKILL_SHIELD:       v58 = PLAYER_SKILL_SHIELD;       break;
+    case  CHARACTER_ATTRIBUTE_SKILL_LEARNING:     v58 = PLAYER_SKILL_LEARNING;     break;
+    default:
+      no_skills=true;
+  }
+  if (!no_skills)
+  {
+    if ( !this->pActiveSkills[v58] )
+      return 0;
+  }
+
+  switch(attr)      //TODO would be nice to move these into separate functions
+  {
+    case CHARACTER_ATTRIBUTE_RANGED_DMG_BONUS:
+    case CHARACTER_ATTRIBUTE_RANGED_ATTACK:
+      if ( HasItemEquipped(EQUIP_BOW) )
+        v5 = pItemsTable->pItems[this->pOwnItems[this->pEquipment.uBow-1].uItemID].uDamageMod;
+      return v5;
+      break;
+
+    case CHARACTER_ATTRIBUTE_RANGED_DMG_MIN:
+      if ( !HasItemEquipped(EQUIP_BOW) )
+        return 0;
+      v57 = this->pOwnItems[this->pEquipment.uBow-1].uItemID;
+      v5 = pItemsTable->pItems[v57].uDamageMod;
+      v56 = pItemsTable->pItems[v57].uDamageDice;
+      return v5 + v56;
+      break;
+
+    case CHARACTER_ATTRIBUTE_RANGED_DMG_MAX:
+      if ( !HasItemEquipped(EQUIP_BOW) )
+        return 0;
+      v20 = this->pOwnItems[this->pEquipment.uBow-1].uItemID;
+      v5 = pItemsTable->pItems[v20].uDamageDice * pItemsTable->pItems[v20].uDamageRoll;
+      v56 = pItemsTable->pItems[v20].uDamageMod;
+      return v5 + v56;
+
+    case CHARACTER_ATTRIBUTE_LEVEL: 
+      if ( !Player::HasEnchantedItemEquipped(25) )
+        return 0;
+      return 5;
+      break;
+
+    case CHARACTER_ATTRIBUTE_MELEE_DMG_MAX:
+      if ( IsUnarmed() )
       {
-  case  CHARACTER_ATTRIBUTE_SKILL_ALCHEMY:      v58 = PLAYER_SKILL_ALCHEMY;      break;
-  case  CHARACTER_ATTRIBUTE_SKILL_STEALING:     v58 = PLAYER_SKILL_STEALING;     break;
-  case  CHARACTER_ATTRIBUTE_SKILL_TRAP_DISARM:  v58 = PLAYER_SKILL_TRAP_DISARM;  break;
-  case  CHARACTER_ATTRIBUTE_SKILL_ITEM_ID:      v58 = PLAYER_SKILL_ITEM_ID;      break;
-  case  CHARACTER_ATTRIBUTE_SKILL_MONSTER_ID:   v58 = PLAYER_SKILL_MONSTER_ID;   break;
-  case  CHARACTER_ATTRIBUTE_SKILL_ARMSMASTER:   v58 = PLAYER_SKILL_ARMSMASTER;   break;
-  case  CHARACTER_ATTRIBUTE_SKILL_DODGE:        v58 = PLAYER_SKILL_DODGE;        break;
-  case  CHARACTER_ATTRIBUTE_SKILL_UNARMED:      v58 = PLAYER_SKILL_UNARMED;      break;
-  case  CHARACTER_ATTRIBUTE_SKILL_FIRE:         v58 = PLAYER_SKILL_FIRE;         break;
-  case  CHARACTER_ATTRIBUTE_SKILL_AIR:          v58 = PLAYER_SKILL_AIR;          break;
-  case  CHARACTER_ATTRIBUTE_SKILL_WATER:        v58 = PLAYER_SKILL_WATER;        break;
-  case  CHARACTER_ATTRIBUTE_SKILL_EARTH:        v58 = PLAYER_SKILL_EARTH;        break;
-  case  CHARACTER_ATTRIBUTE_SKILL_SPIRIT:       v58 = PLAYER_SKILL_SPIRIT;       break;
-  case  CHARACTER_ATTRIBUTE_SKILL_MIND:         v58 = PLAYER_SKILL_MIND;         break;
-  case  CHARACTER_ATTRIBUTE_SKILL_BODY:         v58 = PLAYER_SKILL_BODY;         break;
-  case  CHARACTER_ATTRIBUTE_SKILL_LIGHT:        v58 = PLAYER_SKILL_LIGHT;        break;
-  case  CHARACTER_ATTRIBUTE_SKILL_DARK:         v58 = PLAYER_SKILL_DARK;         break;
-  case  CHARACTER_ATTRIBUTE_SKILL_MEDITATION:   v58 = PLAYER_SKILL_MEDITATION;   break;
-  case  CHARACTER_ATTRIBUTE_SKILL_BOW:          v58 = PLAYER_SKILL_BOW;          break;
-  case  CHARACTER_ATTRIBUTE_SKILL_SHIELD:       v58 = PLAYER_SKILL_SHIELD;       break;
-  case  CHARACTER_ATTRIBUTE_SKILL_LEARNING:     v58 = PLAYER_SKILL_LEARNING;     break;
-  default:
-      no_skills=true;
+        return 3;
       }
-  if (!no_skills)
+      else
       {
-      if ( !this->pActiveSkills[v58] )
+        if ( this->HasItemEquipped(EQUIP_MAIN_HAND) )
+        {
+          v22 = this->GetEquippedItemEquipType(EQUIP_MAIN_HAND);
+          if ( v22 >= 0 && v22 <= 2)
+          {
+            v23 = this->pOwnItems[this->pEquipment.uMainHand].uItemID;
+            v26 = pItemsTable->pItems[v23].uDamageRoll;
+            if ( this->pEquipment.uShield || pItemsTable->pItems[v23].uSkillType != 4 )
+            {
+              v25 = pItemsTable->pItems[v23].uDamageDice;
+            }
+            else
+            {
+              v25 = pItemsTable->pItems[v23].uDamageDice + 1;
+            }
+            v5 = pItemsTable->pItems[v23].uDamageMod + v25 * v26;
+          }
+        }
+        if ( getOnlyMainHandDmg || !this->HasItemEquipped(EQUIP_OFF_HAND) ||  (GetEquippedItemEquipType(EQUIP_OFF_HAND) < 0 && GetEquippedItemEquipType(EQUIP_OFF_HAND) > 2))
+        {
+            return v5;
+        }
+        else
+        {
+          v23 = this->pOwnItems[this->pEquipment.uShield].uItemID;
+          v15 = pItemsTable->pItems[v23].uDamageMod;
+          v14 = pItemsTable->pItems[v23].uDamageDice * pItemsTable->pItems[v23].uDamageRoll;
+          return v5 + v15 + v14;
+        }
+      }
+    break;
+
+    case CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS:
+    case CHARACTER_ATTRIBUTE_ATTACK:
+      if ( IsUnarmed() )
+      {
         return 0;
       }
-
-  if ( (signed int)attr > 28 )
-  {
-    if ( (signed int)attr < 29 )
-      return v5 + v62 + v61;
-    if ( (signed int)attr <= CHARACTER_ATTRIBUTE_RANGED_DMG_BONUS )
-    {
-      if ( HasItemEquipped(EQUIP_BOW) )
-        v5 = pItemsTable->pItems[v6->pOwnItems[v6->pEquipment.uBow-1].uItemID].uDamageMod;
-      return v5 + v62 + v61;
-    }
-    if ( attr == CHARACTER_ATTRIBUTE_RANGED_DMG_MIN )
-    {
-      if ( !HasItemEquipped(EQUIP_BOW) )
-        return v5 + v62 + v61;
-      v57 = v6->pOwnItems[v6->pEquipment.uBow-1].uItemID;
-      v5 = pItemsTable->pItems[v57].uDamageMod;
-      v56 = pItemsTable->pItems[v57].uDamageDice;
-      v5 += v56;
-      return v5 + v62 + v61;
-    }
-    if ( attr == CHARACTER_ATTRIBUTE_RANGED_DMG_MAX )
-    {
-      if ( !HasItemEquipped(EQUIP_BOW) )
-        return v5 + v62 + v61;
-      v20 = v6->pOwnItems[v6->pEquipment.uBow-1].uItemID;
-      v5 = pItemsTable->pItems[v20].uDamageDice * pItemsTable->pItems[v20].uDamageRoll;
-LABEL_365:
-      v56 = pItemsTable->pItems[v20].uDamageMod;
-LABEL_366:
-      v5 += v56;
-      return v5 + v62 + v61;
-    }
-    if ( (signed int)attr <= 33 || (signed int)attr > 46 )
-      return v5 + v62 + v61;
-LABEL_95:
-    v65 = 0;
-    while ( 1 )
-    {
-      if ( !HasItemEquipped((ITEM_EQUIP_TYPE)v65) )
-        goto LABEL_361;
-      v31 = *(&v6->pEquipment.uShield + v65) - 1;
-      if ( v3 == 9 )
+      if ( this->HasItemEquipped(EQUIP_MAIN_HAND) )
+      {
+        v17 = this->GetEquippedItemEquipType(EQUIP_MAIN_HAND);
+        if ( v17 >= 0 && v17 <= 2)
+        {
+          v5 = pItemsTable->pItems[this->pOwnItems[this->pEquipment.uMainHand-1].uItemID].uDamageMod;
+        }
+      }
+      if ( getOnlyMainHandDmg || !this->HasItemEquipped(EQUIP_OFF_HAND) || (this->GetEquippedItemEquipType(EQUIP_OFF_HAND) < 0) || this->GetEquippedItemEquipType(EQUIP_OFF_HAND) > 2 )
+        return v5;
+      else
       {
-        v32 = GetEquippedItemEquipType((ITEM_EQUIP_TYPE)v65);
-        if ( v32 >= 3 )
+        v20 = this->pOwnItems[this->pEquipment.uShield - 1].uItemID;
+        v56 = pItemsTable->pItems[v20].uDamageMod;
+        return v5 + v56;
+      }
+      break;
+
+    case CHARACTER_ATTRIBUTE_MELEE_DMG_MIN:
+      if ( IsUnarmed() )
+      {
+        return 1;
+      }
+      if ( this->HasItemEquipped(EQUIP_MAIN_HAND) )
+      {
+        v9 = this->GetEquippedItemEquipType(EQUIP_MAIN_HAND);
+        if ( v9 >= 0 && v9 <= 2)
         {
-          if ( v32 <= 11 )
+          v5 = pItemsTable->pItems[this->pOwnItems[this->pEquipment.uMainHand].uItemID].uDamageDice +
+            pItemsTable->pItems[this->pOwnItems[this->pEquipment.uMainHand].uItemID].uDamageMod;
+          if ( !this->pEquipment.uShield && pItemsTable->pItems[this->pOwnItems[this->pEquipment.uMainHand].uItemID].uSkillType == 4)
           {
-            v33 = v6->pInventoryItemList[v31].uItemID;
-            v5 += pItemsTable->pItems[v33].uDamageDice + pItemsTable->pItems[v33].uDamageMod;
+            ++v5;
           }
         }
       }
-      v63 = (int)((char *)v6 + 36 * v31);
-      attra = (ItemGen *)(v63 + 532);
-      if ( pItemsTable->IsMaterialNonCommon((ItemGen *)(v63 + 532)) == 1
-        && !pItemsTable->IsMaterialSpecial(attra) )
+
+      if ( getOnlyMainHandDmg || !this->HasItemEquipped(EQUIP_OFF_HAND) || (this->GetEquippedItemEquipType(EQUIP_OFF_HAND) < 0) || this->GetEquippedItemEquipType(EQUIP_OFF_HAND) > 2 )
       {
-        v34 = attra->uItemID;
-        switch ( attra->uItemID )
-        {
-          case 0x1F4u:
-            v35 = v3 == 5;
-            goto LABEL_105;
-          case 0x1F5u:
-            v36 = v3 == 0;
-            goto LABEL_108;
-          case 0x1F6u:
-            if ( v3 == 21 )
-              v61 += 10;
-            v36 = v3 == 2;
-            goto LABEL_108;
-          case 0x1F7u:
-            if ( v3 == 17 )
-              v61 += 5;
-            if ( v3 == 18 )
-              v61 += 5;
-            v36 = v3 == 6;
-            goto LABEL_108;
-          case 0x1F8u:
-            goto LABEL_118;
-          case 0x1F9u:
-            v40 = v3 == 3;
-            goto LABEL_123;
-          case 0x1FAu:
-            v35 = v3 == 10;
-            goto LABEL_105;
-          case 0x1FEu:
-            v35 = v3 == 4;
-            goto LABEL_105;
-          case 0x1FFu:
-            if ( v3 == 23 )
-              v61 += 10;
-            if ( v3 == 22 )
-              v61 += 10;
-            goto LABEL_361;
-          case 0x200u:
-            if ( v3 == 36 )
-            {
-              LOBYTE(v34) = LOBYTE(v6->pActiveSkills[14]);
-              v62 = ((unsigned int)v34 >> 1) & 0x1F;
-            }
-            v36 = v3 == 5;
-LABEL_108:
-            if ( v36 )
-              v5 += 40;
-            goto LABEL_361;
-          case 0x201u:
-            if ( v3 == 39 )
-            {
-              LOBYTE(v34) = LOBYTE(v6->pActiveSkills[17]);
-              v34 = ((unsigned int)v34 >> 1) & 0x1F;
-              v62 = v34;
-            }
-            goto LABEL_136;
-          case 0x202u:
-            if ( !v3 )
-              v5 += 150;
-            if ( v3 == 1 )
-              v5 -= 40;
-            if ( v3 == 2 )
-              v5 -= 40;
-            goto LABEL_145;
-          case 0x203u:
-            if ( v3 == 42 )
-            {
-              LOBYTE(v34) = LOBYTE(v6->pActiveSkills[20]);
-              v62 = ((unsigned int)v34 >> 1) & 0x1F;
-            }
-            if ( v3 == 43 )
-              v61 += 15;
-            goto LABEL_361;
-          case 0x204u:
-            if ( v3 == 17 )
-              v61 += 5;
-            if ( v3 == 18 )
-              v61 += 5;
-            if ( v3 == 6 )
-              v5 += 50;
-            if ( v3 == 11 || v3 == 10 || v3 == 12 || v3 == 13 || v3 == 33 || v3 == 14 )
-              goto LABEL_166;
-            v42 = v3 == 15;
-            goto LABEL_165;
-          case 0x205u:
-            if ( v3 == 18 )
-              v61 += 5;
-            goto LABEL_361;
-          case 0x206u:
-            if ( !v3 )
-              v5 += 100;
-            if ( v3 == 3 )
-              v5 += 100;
-            v43 = v3 == 9;
-            goto LABEL_174;
-          case 0x207u:
-            if ( v3 == 45 )
-              v61 += 5;
-            if ( v3 == 15 )
-              v5 -= 10;
-            v42 = v3 == 14;
-LABEL_165:
-            if ( v42 )
-LABEL_166:
-              v5 -= 10;
-            goto LABEL_361;
-          case 0x208u:
-            v35 = v3 == 3;
-            goto LABEL_105;
-          case 0x209u:
-            if ( v3 == 2 )
-              v5 += 15;
-            if ( !v3 )
-              v5 += 15;
-            v41 = v3 == 6;
-            goto LABEL_146;
-          case 0x20Au:
-            if ( v3 == 46 )
-              v61 += 15;
-            v44 = v3 == 3;
-            goto LABEL_190;
-          case 0x20Bu:
-            if ( v3 == 34 )
-            {
-              LOBYTE(v34) = LOBYTE(v6->pActiveSkills[12]);
-              v62 = ((unsigned int)v34 >> 1) & 0x1F;
-            }
-            if ( v3 == 12 )
-              v5 += 50;
-            if ( v3 == 2 )
-              v5 += 30;
-            v45 = v3 == 9;
-            goto LABEL_199;
-          case 0x20Cu:
-            if ( !v3 )
-              v5 += 75;
-            goto LABEL_145;
-          case 0x20Du:
-            if ( v3 == 5 )
-              v5 += 50;
-            if ( v3 == 6 )
-              v5 += 50;
-            if ( v3 == 11 || v3 == 10 || v3 == 12 || v3 == 13 || v3 == 33 || v3 == 14 )
-              goto LABEL_374;
-            v43 = v3 == 15;
-LABEL_174:
-            if ( v43 )
-LABEL_374:
-              v5 -= 15;
-            goto LABEL_361;
-          case 0x20Eu:
-            if ( v3 == 4 )
-              v5 += 150;
-            if ( v3 == 44 )
-              v61 += 5;
-            if ( v3 == 9 )
-              v5 -= 25;
-            goto LABEL_361;
-          case 0x20Fu:
-            if ( v3 == 39 )
-            {
-              LOBYTE(v34) = LOBYTE(v6->pActiveSkills[17]);
-              v34 = ((unsigned int)v34 >> 1) & 0x1F;
-              v62 = v34;
-            }
-            if ( v3 == 40 )
-            {
-              LOBYTE(v34) = LOBYTE(v6->pActiveSkills[18]);
-              v62 = ((unsigned int)v34 >> 1) & 0x1F;
-            }
-LABEL_145:
-            v41 = v3 == 5;
-LABEL_146:
-            if ( v41 )
-              v5 -= 40;
-            goto LABEL_361;
-          case 0x210u:
-            if ( v3 == 38 )
-            {
-              LOBYTE(v34) = LOBYTE(v6->pActiveSkills[16]);
-              v62 = ((unsigned int)v34 >> 1) & 0x1F;
-            }
-            if ( !v3 )
-              v5 += 75;
-            v44 = v3 == 11;
-LABEL_190:
-            if ( v44 )
-              v5 -= 50;
-            goto LABEL_361;
-          case 0x211u:
-            if ( v3 == 5 )
-              v5 += 100;
-            if ( v3 == 4 )
-              v5 += 50;
-            v35 = v3 == 11;
-LABEL_105:
-            if ( v35 )
-              v5 += 50;
-            goto LABEL_361;
-          case 0x212u:
-            if ( v3 == 1 )
-              v5 -= 20;
-            v45 = v3 == 2;
-LABEL_199:
-            if ( v45 )
-              v5 -= 20;
-            goto LABEL_361;
-          case 0x214u:
-            if ( v3 == 1 )
-              v5 += 15;
-            v46 = v3 == 2;
-            goto LABEL_240;
-          case 0x215u:
-            if ( v3 == 5 )
-              v5 += 15;
-            v46 = v3 == 4;
-            goto LABEL_240;
-          case 0x216u:
-            if ( v3 == 10 )
-              v5 += 30;
-            if ( !v3 )
-              v5 += 15;
-            goto LABEL_315;
-          case 0x217u:
-            if ( v3 == 21 )
-              v61 += 5;
-            if ( !v3 )
-              v5 += 15;
-            goto LABEL_253;
-          case 0x218u:
-            goto LABEL_253;
-          default:
-            goto LABEL_361;
-        }
-        goto LABEL_361;
-      }
-      if ( *(int *)(v63 + 536) == v3 + 1 )
-      {
-        if ( (signed int)v3 >= 0 )
-        {
-          if ( (signed int)v3 <= 15 )
-          {
-            v5 += *((int *)v6->pConditions + 9 * v31 + 135);
-          }
-          else
-          {
-            if ( (signed int)v3 <= 23 && v5 < *((int *)v6->pConditions + 9 * v31 + 135) )
-              v5 = *((int *)v6->pConditions + 9 * v31 + 135);
-          }
-        }
-        goto LABEL_361;
-      }
-      v34 = *(int *)(v63 + 544);
-      if ( v34 > 48 )
-      {
-        switch ( v34 )
-        {
-          case 54:
-            goto LABEL_315;
-          case 49:
-            if ( v3 == 6 )
-              goto LABEL_121;
-            v50 = v3 == 1;
-            goto LABEL_296;
-          case 51:
-            if ( v3 != 5 && v3 != 1 )
-              goto LABEL_309;
-            goto LABEL_121;
-          case 52:
-            if ( v3 == 3 )
-              goto LABEL_121;
-            v50 = v3 == 4;
-            goto LABEL_296;
-          case 53:
-            if ( !v3 )
-              goto LABEL_121;
-            v50 = v3 == 2;
-            goto LABEL_296;
-          case 55:
-            v46 = v3 == 6;
-            goto LABEL_240;
-          case 56:
-            if ( !v3 )
-              goto LABEL_351;
-            v53 = v3 == 3;
-            goto LABEL_350;
-          case 57:
-            if ( v3 == 1 )
-              goto LABEL_351;
-            v53 = v3 == 2;
-            goto LABEL_350;
-          case 50:
-            if ( v3 == 10 )
-              v5 += 30;
-            goto LABEL_361;
-          case 60:
-            if ( v3 != 23 )
-              goto LABEL_336;
-            if ( v5 >= 3 )
-              goto LABEL_361;
-            v5 = 3;
-LABEL_336:
-            v54 = v3 == 22;
-            goto LABEL_345;
-          case 61:
-            if ( v3 != 17 )
-              goto LABEL_340;
-            if ( v5 >= 3 )
-              goto LABEL_361;
-            v5 = 3;
-LABEL_340:
-            v54 = v3 == 18;
-            goto LABEL_345;
-          case 62:
-            if ( v3 != 19 )
-              goto LABEL_344;
-            if ( v5 >= 3 )
-              goto LABEL_361;
-            v5 = 3;
-LABEL_344:
-            v54 = v3 == 20;
-LABEL_345:
-            if ( !v54 )
-              goto LABEL_361;
-            if ( v5 >= 3 )
-              goto LABEL_361;
-            v60 = 3;
-            goto LABEL_360;
-          case 67:
-            v55 = v3 == 18;
-            goto LABEL_357;
-          case 68:
-            v53 = v3 == 9;
-            goto LABEL_350;
-          case 69:
-            if ( v3 == 11 )
-              v5 += 20;
-            break;
-          case 70:
-            if ( v3 == 12 )
-              v5 += 10;
-            v55 = v3 == 16;
-LABEL_357:
-            if ( v55 && v5 < 2 )
-            {
-              v60 = 2;
-LABEL_360:
-              v5 = v60;
-            }
-            break;
-          default:
-            goto LABEL_361;
-        }
-        goto LABEL_361;
-      }
-      if ( v34 == 48 )
-      {
-        if ( v3 == 9 )
-          v5 += 5;
-LABEL_315:
-        v46 = v3 == 3;
-LABEL_240:
-        if ( v46 )
-          v5 += 15;
-        goto LABEL_361;
-      }
-      if ( v34 > 32 )
-      {
-        if ( v34 > 44 )
-        {
-          v51 = v34 - 45;
-          if ( !v51 )
-          {
-            if ( v3 == 5 )
-              goto LABEL_351;
-            v53 = v3 == 4;
-LABEL_350:
-            if ( v53 )
-LABEL_351:
-              v5 += 5;
-            goto LABEL_361;
-          }
-          v52 = v51 - 1;
-          if ( !v52 )
-          {
-            v40 = v3 == 0;
-LABEL_123:
-            if ( v40 )
-              v5 += 25;
-            goto LABEL_361;
-          }
-          if ( v52 == 1 )
-          {
-LABEL_309:
-            v50 = v3 == 8;
-            goto LABEL_296;
-          }
-        }
-        else
-        {
-          if ( v34 == 44 )
-          {
-            v50 = v3 == 7;
-            goto LABEL_296;
-          }
-          v34 -= 33;
-          if ( !v34 )
-          {
-            if ( v3 != 38 )
-              goto LABEL_361;
-            LOBYTE(v34) = LOBYTE(v6->pActiveSkills[16]);
-            goto LABEL_138;
-          }
-          --v34;
-          if ( !v34 )
-          {
-            if ( v3 != 36 )
-              goto LABEL_361;
-            LOBYTE(v34) = LOBYTE(v6->pActiveSkills[14]);
-            goto LABEL_138;
-          }
-          v49 = v34 - 8;
-          if ( !v49 )
-          {
-            if ( (signed int)v3 >= 0 && (signed int)v3 <= 15 )
-              ++v5;
-            goto LABEL_361;
-          }
-          if ( v49 == 1 )
-          {
-            if ( v3 != 3 && v3 != 7 )
-            {
-              v50 = v3 == 9;
-LABEL_296:
-              if ( !v50 )
-                goto LABEL_361;
-            }
-LABEL_121:
-            v5 += 10;
-            goto LABEL_361;
-          }
-        }
+        return v5;
       }
       else
       {
-        if ( v34 == 32 )
+        v14 = pItemsTable->pItems[this->pOwnItems[this->pEquipment.uShield].uItemID].uDamageMod;
+        v15 = pItemsTable->pItems[this->pOwnItems[this->pEquipment.uShield].uItemID].uDamageDice;
+        return v5 + v15 + v14;
+      }
+      break;
+
+    case   CHARACTER_ATTRIBUTE_STRENGTH:
+    case   CHARACTER_ATTRIBUTE_INTELLIGENCE:
+    case   CHARACTER_ATTRIBUTE_WILLPOWER:
+    case   CHARACTER_ATTRIBUTE_ENDURANCE:
+    case   CHARACTER_ATTRIBUTE_ACCURACY:
+    case   CHARACTER_ATTRIBUTE_SPEED:
+    case   CHARACTER_ATTRIBUTE_LUCK:
+    case   CHARACTER_ATTRIBUTE_HEALTH:
+    case   CHARACTER_ATTRIBUTE_MANA:
+    case   CHARACTER_ATTRIBUTE_AC_BONUS:
+
+    case   CHARACTER_ATTRIBUTE_RESIST_FIRE:
+    case   CHARACTER_ATTRIBUTE_RESIST_AIR:
+    case   CHARACTER_ATTRIBUTE_RESIST_WATER:
+    case   CHARACTER_ATTRIBUTE_RESIST_EARTH:
+    case   CHARACTER_ATTRIBUTE_RESIST_MIND:
+    case   CHARACTER_ATTRIBUTE_RESIST_BODY:        
+    case   CHARACTER_ATTRIBUTE_RESIST_SPIRIT:
+
+    case   CHARACTER_ATTRIBUTE_SKILL_ALCHEMY:
+    case   CHARACTER_ATTRIBUTE_SKILL_STEALING:
+    case   CHARACTER_ATTRIBUTE_SKILL_TRAP_DISARM:
+    case   CHARACTER_ATTRIBUTE_SKILL_ITEM_ID:
+    case   CHARACTER_ATTRIBUTE_SKILL_MONSTER_ID:
+    case   CHARACTER_ATTRIBUTE_SKILL_ARMSMASTER:
+    case   CHARACTER_ATTRIBUTE_SKILL_DODGE:
+    case   CHARACTER_ATTRIBUTE_SKILL_UNARMED:
+
+    case   CHARACTER_ATTRIBUTE_SKILL_FIRE:
+    case   CHARACTER_ATTRIBUTE_SKILL_AIR:
+    case   CHARACTER_ATTRIBUTE_SKILL_WATER:
+    case   CHARACTER_ATTRIBUTE_SKILL_EARTH:
+    case   CHARACTER_ATTRIBUTE_SKILL_SPIRIT:
+    case   CHARACTER_ATTRIBUTE_SKILL_MIND:
+    case   CHARACTER_ATTRIBUTE_SKILL_BODY:
+    case   CHARACTER_ATTRIBUTE_SKILL_LIGHT:
+    case   CHARACTER_ATTRIBUTE_SKILL_DARK:
+    case   CHARACTER_ATTRIBUTE_SKILL_MEDITATION:
+    case   CHARACTER_ATTRIBUTE_SKILL_BOW:
+    case   CHARACTER_ATTRIBUTE_SKILL_SHIELD:
+    case   CHARACTER_ATTRIBUTE_SKILL_LEARNING:
+      for (int i = 0; i < 16; i++)
+      {
+        if ( HasItemEquipped((ITEM_EQUIP_TYPE)i) )
         {
-          if ( v3 != 39 )
-            goto LABEL_361;
-          LOBYTE(v34) = LOBYTE(v6->pActiveSkills[17]);
-          goto LABEL_138;
-        }
-        if ( v34 > 28 )
-        {
-          v34 -= 29;
-          if ( v34 )
+          v31 = this->pEquipment.pIndices[i] - 1;
+          currEquippedItem = &this->pInventoryItemList[v31];
+          if ( attr == CHARACTER_ATTRIBUTE_AC_BONUS )
           {
-            --v34;
-            if ( v34 )
+            v32 = GetEquippedItemEquipType((ITEM_EQUIP_TYPE)i);
+            if ( v32 >= 3 && v32 <= 11 )
             {
-              --v34;
-              if ( v34 || v3 != 41 )
-                goto LABEL_361;
-              LOBYTE(v34) = LOBYTE(v6->pActiveSkills[19]);
+              v33 = currEquippedItem->uItemID;
+              v5 += pItemsTable->pItems[v33].uDamageDice + pItemsTable->pItems[v33].uDamageMod;
             }
-            else
+          }
+          if ( pItemsTable->IsMaterialNonCommon((ItemGen *)(currEquippedItem))
+            && !pItemsTable->IsMaterialSpecial(currEquippedItem) )
+          {
+            currEquippedItem->GetItemBonusArtifact(this, attr, &v62);
+          }
+          else if ( currEquippedItem->uEnchantmentType != 0 )
+          {
+            if (currEquippedItem->IsRegularEnchanmentForAttribute(attr))
             {
-              if ( v3 != 34 )
-                goto LABEL_361;
-              LOBYTE(v34) = LOBYTE(v6->pActiveSkills[12]);
+              if ( attr > CHARACTER_ATTRIBUTE_RESIST_BODY && v5 < currEquippedItem->m_enchantmentStrength )
+                v5 = currEquippedItem->m_enchantmentStrength;
+              else
+                v5 += currEquippedItem->m_enchantmentStrength;
             }
           }
           else
           {
-            if ( v3 != 37 )
-              goto LABEL_361;
-            LOBYTE(v34) = LOBYTE(v6->pActiveSkills[15]);
-          }
-          goto LABEL_138;
-        }
-        if ( v34 == 28 )
-        {
-LABEL_136:
-          if ( v3 == 42 )
-          {
-            LOBYTE(v34) = LOBYTE(v6->pActiveSkills[20]);
-LABEL_138:
-            v62 = ((unsigned int)v34 >> 1) & 0x1F;
-            goto LABEL_361;
-          }
-        }
-        else
-        {
-          v47 = v34 - 1;
-          if ( v47 )
-          {
-            v48 = v47 - 1;
-            if ( v48 )
-            {
-              v34 = v48 - 24;
-              if ( v34 )
-              {
-                --v34;
-                if ( v34 || v3 != 40 )
-                  goto LABEL_361;
-                LOBYTE(v34) = LOBYTE(v6->pActiveSkills[18]);
-              }
-              else
-              {
-                if ( v3 != 35 )
-                  goto LABEL_361;
-                LOBYTE(v34) = LOBYTE(v6->pActiveSkills[13]);
-              }
-              goto LABEL_138;
-            }
-LABEL_118:
-            if ( (signed int)v3 < 0 )
-              goto LABEL_361;
-            v39 = __OFSUB__((int)v3, 6);
-            v37 = v3 == 6;
-            v38 = v3 - 6 < 0;
-          }
-          else
-          {
-LABEL_253:
-            if ( (signed int)v3 < 10 )
-              goto LABEL_361;
-            v39 = __OFSUB__((int)v3, 15);
-            v37 = v3 == 15;
-            v38 = v3 - 15 < 0;
-          }
-          if ( (unsigned __int8)(v38 ^ v39) | v37 )
-            goto LABEL_121;
-        }
-      }
-LABEL_361:
-      ++v65;
-      if ( (signed int)v65 >= 16 )
-        return v5 + v62 + v61;
-    }
-  }
-  if ( attr == CHARACTER_ATTRIBUTE_MELEE_DMG_MAX )
-  {
-    if ( IsUnarmed() != 1 )
-    {
-      if ( v6->HasItemEquipped(EQUIP_MAIN_HAND) )
-      {
-        v22 = this->GetEquippedItemEquipType(EQUIP_MAIN_HAND);
-        if ( v22 >= 0 )
-        {
-          if ( v22 <= 2 )
-          {
-			  v23 = this->pOwnItems[this->pEquipment.uMainHand].uItemID;
-            if ( v6->pEquipment.uShield || pItemsTable->pItems[v23].uSkillType != 4 )
-            {
-              v26 = pItemsTable->pItems[v23].uDamageRoll;
-              v25 = pItemsTable->pItems[v23].uDamageDice;
-            }
-            else
-            {
-              v25 = pItemsTable->pItems[v23].uDamageRoll;
-              v26 = pItemsTable->pItems[v23].uDamageDice + 1;
-            }
-            v5 = pItemsTable->pItems[v23].uDamageMod + v25 * v26;
+            currEquippedItem->GetItemBonusSpecialEnchantment(this, attr, &v5, &v61);
           }
         }
       }
-      
-      if ( a3 || !v6->HasItemEquipped(EQUIP_OFF_HAND) )
-          {
-
-          v28 = v6->GetEquippedItemEquipType(EQUIP_OFF_HAND);
-          if ((v28 < 0) || v28 > 2 )
-              return v5 + v62 + v61;
-        }
-      v15 = pItemsTable->pItems[v23].uDamageMod;
-      v14 = pItemsTable->pItems[v23].uDamageDice * pItemsTable->pItems[v23].uDamageRoll;
-      v5 += v15 + v14;
       return v5 + v62 + v61;
-    }
-    v59 = 3;
-LABEL_74:
-    v5 = v59;
-    return v5 + v62 + v61;
-  }
-  if ( (signed int)attr < 0 )
-    return v5 + v62 + v61;
-  if ( (signed int)attr <= CHARACTER_ATTRIBUTE_SKILL_UNARMED )
-    goto LABEL_95;
-  if ( attr == CHARACTER_ATTRIBUTE_LEVEL )
-      {
-      if ( !Player::HasEnchantedItemEquipped(25) )
-          return v5 + v62 + v61;
-      v5 = 5;
-      return v5 + v62 + v61;
-      }
-  if ( (signed int)attr <= CHARACTER_ATTRIBUTE_LEVEL )
-    return v5 + v62 + v61;
-  if ( (signed int)attr <= CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS )
-  {
-    if ( IsUnarmed() == 1 )
-    {
-      v5 = 0;
-      return v5 + v62 + v61;
-    }
-    if ( v6->HasItemEquipped(EQUIP_MAIN_HAND) )
-    {
-      v17 = this->GetEquippedItemEquipType(EQUIP_MAIN_HAND);
-      if ( v17 >= 0 )
-      {
-        if ( v17 <= 2 )
-          v5 = pItemsTable->pItems[v6->pOwnItems[v6->pEquipment.uMainHand-1].uItemID].uDamageMod;
-      }
-    }
-    if ( a3 || !v6->HasItemEquipped(EQUIP_OFF_HAND) || (v19 = v6->GetEquippedItemEquipType(EQUIP_OFF_HAND), v19 < 0) || v19 > 2 )
-      return v5 + v62 + v61;
-    v20 = v6->pOwnItems[v6->pEquipment.uShield - 1].uItemID;
-    v56 = pItemsTable->pItems[v20].uDamageMod;
-    v5 += v56;
-    return v5 + v62 + v61;
-  }
-  if ( attr == CHARACTER_ATTRIBUTE_MELEE_DMG_MIN )
-  {
-    if ( IsUnarmed() == 1 )
-    {
-      v5 = 1;
-      return v5 + v62 + v61;
-    }
-    if ( v6->HasItemEquipped(EQUIP_MAIN_HAND) )
-    {
-      v9 = this->GetEquippedItemEquipType(EQUIP_MAIN_HAND);
-      if ( v9 >= 0 )
-      {
-        if ( v9 <= 2 )
-        {
-          v5 = pItemsTable->pItems[this->pOwnItems[this->pEquipment.uMainHand].uItemID].uDamageDice +
-                 pItemsTable->pItems[this->pOwnItems[this->pEquipment.uMainHand].uItemID].uDamageMod;
-          if ( !v6->pEquipment.uShield )
-          {
-            if ( pItemsTable->pItems[this->pOwnItems[this->pEquipment.uMainHand].uItemID].uSkillType == 4 )
-              ++v5;
-          }
-        }
-      }
-    }
-    
-    if ( a3 || !v6->HasItemEquipped(EQUIP_OFF_HAND))
-        {
-        v12 = v6->GetEquippedItemEquipType(EQUIP_OFF_HAND);
-        if  ((v12 < 0) || v12 > 2 )
-                return v5 + v62 + v61;
-        }
-    v14 = pItemsTable->pItems[this->pOwnItems[this->pEquipment.uShield].uItemID].uDamageMod;
-    v15 = pItemsTable->pItems[this->pOwnItems[this->pEquipment.uShield].uItemID].uDamageDice;
-LABEL_88:
-    v5 += v15 + v14;
-  }
-  return v5 + v62 + v61;
+      break;
+    default:
+      return 0;
+    }
 }
 
 //----- (0048F73C) --------------------------------------------------------
 int Player::GetMagicalBonus(enum CHARACTER_ATTRIBUTE_TYPE a2)
 {
-  int result; // eax@1
-  int v3; // eax@4
-  int v4; // ecx@5
-
-  switch (a2)
-  {
-    case CHARACTER_ATTRIBUTE_LEVEL: return 0;
-  }
-
-  result = 0;
-  if ( (signed int)a2 > 10 )
-  {
-    if ( (signed int)a2 <= 15 )
-    {
-      switch ( a2 )
-      {
-        case CHARACTER_ATTRIBUTE_RESIST_BODY:
-          v3 = this->pPlayerBuffs[2].uPower;
-          v4 = pParty->pPartyBuffs[PARTY_BUFF_RESIST_BODY].uPower;
-          break;
-        case CHARACTER_ATTRIBUTE_RESIST_AIR:
-          v3 = this->pPlayerBuffs[0].uPower;
-          v4 = pParty->pPartyBuffs[PARTY_BUFF_RESIST_AIR].uPower;
-          break;
-        case CHARACTER_ATTRIBUTE_RESIST_WATER:
-          v3 = this->pPlayerBuffs[22].uPower;
-          v4 = pParty->pPartyBuffs[PARTY_BUFF_RESIST_WATER].uPower;
-          break;
-        case CHARACTER_ATTRIBUTE_RESIST_EARTH:
-          v3 = this->pPlayerBuffs[3].uPower;
-          v4 = pParty->pPartyBuffs[PARTY_BUFF_RESIST_EARTH].uPower;
-          break;
-        default:
-          if ( a2 != 14 )
-            return result;
-          v3 = this->pPlayerBuffs[9].uPower;
-          v4 = pParty->pPartyBuffs[PARTY_BUFF_RESIST_MIND].uPower;
-          break;
-      }
-      return v4 + v3;
-    }
-    if ( a2 != CHARACTER_ATTRIBUTE_ATTACK )
-    {
-      if ( a2 == CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS )
-      {
-        v3 = this->pPlayerBuffs[8].uPower;
-        v4 = pParty->pPartyBuffs[PARTY_BUFF_HEROISM].uPower;
-        return v4 + v3;
-      }
-      if ( a2 != CHARACTER_ATTRIBUTE_RANGED_ATTACK )
-        return result;
-    }
-    return this->pPlayerBuffs[1].uPower;
-  }
-  if ( a2 == 10 )
-  {
-    v3 = this->pPlayerBuffs[5].uPower;
-    v4 = pParty->pPartyBuffs[PARTY_BUFF_RESIST_FIRE].uPower;
-    return v4 + v3;
-  }
+  int v3 = 0; // eax@4
+  int v4 = 0; // ecx@5
+
   switch ( a2 )
   {
+    case CHARACTER_ATTRIBUTE_RESIST_FIRE:
+      v3 = this->pPlayerBuffs[PLAYER_BUFF_RESIST_FIRE].uPower;
+      v4 = pParty->pPartyBuffs[PARTY_BUFF_RESIST_FIRE].uPower;
+      break;
+    case CHARACTER_ATTRIBUTE_RESIST_AIR:
+      v3 = this->pPlayerBuffs[PLAYER_BUFF_RESIST_AIR].uPower;
+      v4 = pParty->pPartyBuffs[PARTY_BUFF_RESIST_AIR].uPower;
+      break;
+    case CHARACTER_ATTRIBUTE_RESIST_BODY:
+      v3 = this->pPlayerBuffs[PLAYER_BUFF_RESIST_BODY].uPower;
+      v4 = pParty->pPartyBuffs[PARTY_BUFF_RESIST_BODY].uPower;
+      break;
+    case CHARACTER_ATTRIBUTE_RESIST_WATER:
+      v3 = this->pPlayerBuffs[PLAYER_BUFF_RESIST_WATER].uPower;
+      v4 = pParty->pPartyBuffs[PARTY_BUFF_RESIST_WATER].uPower;
+      break;
+    case CHARACTER_ATTRIBUTE_RESIST_EARTH:
+      v3 = this->pPlayerBuffs[PLAYER_BUFF_RESIST_EARTH].uPower;
+      v4 = pParty->pPartyBuffs[PARTY_BUFF_RESIST_EARTH].uPower;
+      break;
+    case CHARACTER_ATTRIBUTE_RESIST_MIND:
+      v3 = this->pPlayerBuffs[PLAYER_BUFF_RESIST_MIND].uPower;
+      v4 = pParty->pPartyBuffs[PARTY_BUFF_RESIST_MIND].uPower;
+      break;
+    case CHARACTER_ATTRIBUTE_ATTACK:
+    case CHARACTER_ATTRIBUTE_RANGED_ATTACK:
+      v3 = this->pPlayerBuffs[PLAYER_BUFF_BLESS].uPower;  //only player effect spell in both VI and VII
+      break;
+    case CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS:
+      v3 = this->pPlayerBuffs[PLAYER_BUFF_HEROISM].uPower;
+      v4 = pParty->pPartyBuffs[PARTY_BUFF_HEROISM].uPower;
+      break;
     case CHARACTER_ATTRIBUTE_STRENGTH:
-      v3 = pPlayerBuffs[19].uPower;
-      goto LABEL_5;
+      v3 = pPlayerBuffs[PLAYER_BUFF_STRENGTH].uPower;
+      v4 = pParty->pPartyBuffs[PARTY_BUFF_DAY_OF_GODS].uPower;
+      break;
     case CHARACTER_ATTRIBUTE_INTELLIGENCE:
-      v3 = pPlayerBuffs[17].uPower;
-      goto LABEL_5;
+      v3 = pPlayerBuffs[PLAYER_BUFF_INTELLIGENCE].uPower;
+      v4 = pParty->pPartyBuffs[PARTY_BUFF_DAY_OF_GODS].uPower;
+      break;
     case CHARACTER_ATTRIBUTE_WILLPOWER:
-      v3 = pPlayerBuffs[20].uPower;
-      goto LABEL_5;
+      v3 = pPlayerBuffs[PLAYER_BUFF_WILLPOWER].uPower;
+      v4 = pParty->pPartyBuffs[PARTY_BUFF_DAY_OF_GODS].uPower;
+      break;
     case CHARACTER_ATTRIBUTE_ENDURANCE:
-      v3 = pPlayerBuffs[16].uPower;
-      goto LABEL_5;
+      v3 = pPlayerBuffs[PLAYER_BUFF_ENDURANCE].uPower;
+      v4 = pParty->pPartyBuffs[PARTY_BUFF_DAY_OF_GODS].uPower;
+      break;
     case CHARACTER_ATTRIBUTE_ACCURACY:
-      v3 = pPlayerBuffs[15].uPower;
-      goto LABEL_5;
+      v3 = pPlayerBuffs[PLAYER_BUFF_ACCURACY].uPower;
+      v4 = pParty->pPartyBuffs[PARTY_BUFF_DAY_OF_GODS].uPower;
+      break;
     case CHARACTER_ATTRIBUTE_SPEED:
-      v3 = pPlayerBuffs[21].uPower;
-      goto LABEL_5;
+      v3 = pPlayerBuffs[PLAYER_BUFF_SPEED].uPower;
+      v4 = pParty->pPartyBuffs[PARTY_BUFF_DAY_OF_GODS].uPower;
+      break;
     case CHARACTER_ATTRIBUTE_LUCK:
-      v3 = pPlayerBuffs[18].uPower;
-LABEL_5:
+      v3 = pPlayerBuffs[PLAYER_BUFF_LUCK].uPower;
       v4 = pParty->pPartyBuffs[PARTY_BUFF_DAY_OF_GODS].uPower;
-      return v4 + v3;
+      break;
     case CHARACTER_ATTRIBUTE_AC_BONUS:
-      v3 = this->pPlayerBuffs[14].uPower;
+      v3 = this->pPlayerBuffs[PLAYER_BUFF_STONESKIN].uPower;
       v4 = pParty->pPartyBuffs[PARTY_BUFF_STONE_SKIN].uPower;
-      return v4 + v3;
-    default:
-      return result;
-  }
-  return result;
+      break;
+  }
+  return v3 + v4;
 }
 
 //----- (0048F882) --------------------------------------------------------
 int Player::GetActualSkillLevel( PLAYER_SKILL_TYPE uSkillType )
-    {
+{
   signed int bonus_value; // esi@1
   unsigned __int16 skill_value; // ax@126
   int result; // al@127
@@ -4137,7 +3482,7 @@
         bonus_value = 6;
       if ( CheckHiredNPCSpeciality(Sage) )
         bonus_value += 6;
-      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_MONSTER_ID, 0);
+      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_MONSTER_ID);
     }
     break;
 
@@ -4147,7 +3492,7 @@
           bonus_value = 2;
         if ( CheckHiredNPCSpeciality(Weaponsmaster) )
           bonus_value += 3;
-      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_ARMSMASTER, 0);
+      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_ARMSMASTER);
     }
     break;
 
@@ -4155,7 +3500,7 @@
     {
       if (CheckHiredNPCSpeciality(Burglar))
           bonus_value = 8;
-      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_STEALING, 0);
+      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_STEALING);
     }
     break;
 
@@ -4166,7 +3511,7 @@
           bonus_value = 4;
         if ( CheckHiredNPCSpeciality(Apothecary) )
           bonus_value += 8;
-        bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_ALCHEMY, 0);
+        bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_ALCHEMY);
     }
     break;
 
@@ -4178,7 +3523,7 @@
           bonus_value += 15;
         if ( CheckHiredNPCSpeciality(Scholar) )
           bonus_value += 5;
-      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_LEARNING, 0);
+      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_LEARNING);
     }
     break;
 
@@ -4186,7 +3531,7 @@
     {
       if (CheckHiredNPCSpeciality(Monk) )
         bonus_value = 2;
-      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_UNARMED, 0);
+      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_UNARMED);
     }
     break;
 
@@ -4194,15 +3539,15 @@
     {
       if ( CheckHiredNPCSpeciality(Monk) )
         bonus_value = 2;
-      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_DODGE, 0);
+      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_DODGE);
     }
     break;
     
     case PLAYER_SKILL_BOW:
-      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_BOW, 0);
+      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_BOW);
     break;
     case PLAYER_SKILL_SHIELD:
-      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_SHIELD, 0);
+      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_SHIELD);
     break;
 
     case PLAYER_SKILL_EARTH:
@@ -4214,7 +3559,7 @@
             bonus_value += 4;
           if ( classType == PLAYER_CLASS_WARLOCK && PartyHasDragon() )
             bonus_value += 3;
-      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_EARTH, 0);
+      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_EARTH);
     break;
     case PLAYER_SKILL_FIRE:
       if ( CheckHiredNPCSpeciality(Apprentice) )
@@ -4225,7 +3570,7 @@
             bonus_value += 4;
           if ( classType == PLAYER_CLASS_WARLOCK && PartyHasDragon() )
             bonus_value += 3;
-      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_FIRE, 0);
+      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_FIRE);
     break;
     case PLAYER_SKILL_AIR:
       if ( CheckHiredNPCSpeciality(Apprentice) )
@@ -4236,7 +3581,7 @@
             bonus_value += 4;
           if ( classType == PLAYER_CLASS_WARLOCK && PartyHasDragon() )
             bonus_value += 3;
-      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_AIR, 0);
+      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_AIR);
     break;
     case PLAYER_SKILL_WATER:
       if ( CheckHiredNPCSpeciality(Apprentice) )
@@ -4247,7 +3592,7 @@
             bonus_value += 4;
           if ( classType == PLAYER_CLASS_WARLOCK && PartyHasDragon() )
             bonus_value += 3;
-      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_WATER, 0);
+      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_WATER);
     break;
     case PLAYER_SKILL_SPIRIT:
           if ( CheckHiredNPCSpeciality(Acolyte2) )
@@ -4256,7 +3601,7 @@
             bonus_value += 3;
           if ( CheckHiredNPCSpeciality(Prelate) )
             bonus_value += 4;
-      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_SPIRIT, 0);
+      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_SPIRIT);
     break;
     case PLAYER_SKILL_MIND:
           if ( CheckHiredNPCSpeciality(Acolyte2) )
@@ -4265,7 +3610,7 @@
             bonus_value += 3;
           if ( CheckHiredNPCSpeciality(Prelate) )
             bonus_value += 4;
-      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_MIND, 0);
+      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_MIND);
     break;
     case PLAYER_SKILL_BODY:
           if ( CheckHiredNPCSpeciality(Acolyte2) )
@@ -4274,14 +3619,14 @@
             bonus_value += 3;
           if ( CheckHiredNPCSpeciality(Prelate) )
             bonus_value += 4;
-      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_BODY, 0);
+      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_BODY);
     break;
     case PLAYER_SKILL_LIGHT:
-      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_LIGHT, 0);
+      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_LIGHT);
     break;
     case PLAYER_SKILL_DARK:
     {
-      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_DARK, 0);
+      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_DARK);
     }
     break;
 
@@ -4308,10 +3653,10 @@
     break;
 
     case PLAYER_SKILL_ITEM_ID:
-      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_ITEM_ID, 0);
+      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_ITEM_ID);
       break;
     case PLAYER_SKILL_MEDITATION:
-      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_MEDITATION, 0);
+      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_MEDITATION);
     break;
     case PLAYER_SKILL_TRAP_DISARM:
     {
@@ -4321,7 +3666,7 @@
         bonus_value += 6;
       if ( CheckHiredNPCSpeciality(Burglar) )
         bonus_value += 8;
-      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_TRAP_DISARM, 0);
+      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_TRAP_DISARM);
     }
     break;
   }
@@ -4596,40 +3941,31 @@
 //                     24   zombie female
 enum CHARACTER_RACE Player::GetRace()
 {
-  if ( uCurrentFace > 15 )
-  {
-    if ( uCurrentFace >= 16 && uCurrentFace <= 19 )
-      return CHARACTER_RACE_GOBLIN;
+  if ( uCurrentFace <= 7 )
+  {
+    return CHARACTER_RACE_HUMAN;
+  }
+  else if ( uCurrentFace <= 11 )
+  {
+      return CHARACTER_RACE_ELF;
+  }
+  else if ( uCurrentFace <= 15 )
+  {
+    return CHARACTER_RACE_DWARF;
+  }
+  else if ( uCurrentFace <= 19 )
+  {
+    return CHARACTER_RACE_GOBLIN;
   }
   else
   {
-    if ( uCurrentFace >= 12 )
-    {
-      return CHARACTER_RACE_DWARF;
-    }
-    else
-    {
-      
-        if ( uCurrentFace <= 7 )
-        {
-          return CHARACTER_RACE_HUMAN;
-        }
-        else
-        {
-          if ( uCurrentFace <= 11 )
-            return CHARACTER_RACE_ELF;
-        }
-    }
-  }
-  return CHARACTER_RACE_HUMAN;
+    return CHARACTER_RACE_HUMAN;
+  }
 }
 
 //----- (00490141) --------------------------------------------------------
 PLAYER_SEX Player::GetSexByVoice()
 {
-  signed int result; // eax@1
-
-  result = 0;
   switch ( this->uVoiceID )
   {
     case 0u:
@@ -4679,7 +4015,7 @@
 
 //----- (004901FC) --------------------------------------------------------
 void Player::SetSexByVoice()
-    {
+{
   switch ( this->uVoiceID)
   {
     case 0:
@@ -4711,6 +4047,7 @@
       this->uSex = SEX_FEMALE;
       break;
     default:
+      Error("(%u)", this->uVoiceID);
       break;
   }
  
@@ -4919,18 +4256,16 @@
 //unsigned __int16 PartyCreation_BtnMinusClick(Player *_this, int eAttribute)
 void Player::DecreaseAttribute(int eAttribute)
 {
-  int v2; // eax@1
   int pBaseValue; // ecx@1
   int pDroppedStep; // ebx@1
   int pStep; // esi@1
-  unsigned __int16 result; // ax@7
   int uMinValue; // [sp+Ch] [bp-4h]@1
 
-  v2 = eAttribute + 7 * GetRace();
-  pBaseValue = StatTable[0][v2].uBaseValue;
-  pDroppedStep = StatTable[0][v2].uDroppedStep;
+  int raceId = GetRace();
+  pBaseValue = StatTable[raceId][eAttribute].uBaseValue;
+  pDroppedStep = StatTable[raceId][eAttribute].uDroppedStep;
   uMinValue = pBaseValue - 2;
-  pStep = StatTable[0][v2].uBaseStep;
+  pStep = StatTable[raceId][eAttribute].uBaseStep;
   unsigned short* AttrToChange = nullptr;
   switch ( eAttribute )
   {
@@ -5095,680 +4430,670 @@
 
 //----- (004680ED) --------------------------------------------------------
 void Player::UseItem_DrinkPotion_etc(signed int player_num, int a3)
-    {
-    Player *v3; // esi@1
-    signed int v5; // eax@17
-    int v8; // edx@39
-    char *v13; // eax@45
-    signed int v15; // edi@68
-    int v16; // edx@73
-    unsigned __int16 v17; // edi@73
-    unsigned int v18; // eax@73
-    const char *v22; // eax@84
-    int scroll_id; // esi@96
-    int v25; // eax@109
-    int v26; // eax@113
-    int new_mana_val; // edi@114
-    signed __int64 v28; // qax@120
-    __int64 v30; // edi@137
-    __int64 v32; // ST3C_4@137
-    __int64 v34; // ST34_4@137
-    unsigned __int16 v50; // [sp-Ch] [bp-38h]@120
-    const char *v66; // [sp-4h] [bp-30h]@69
-    signed int v67; // [sp-4h] [bp-30h]@77
-    const char *v68; // [sp-4h] [bp-30h]@89
-    char v72; // [sp+20h] [bp-Ch]@68
-    signed int v73; // [sp+24h] [bp-8h]@1
-    char*  v74; // [sp+24h] [bp-8h]@23
-    Player *thisb; // [sp+28h] [bp-4h]@1
-    unsigned int thisa; // [sp+28h] [bp-4h]@22
-
-    thisb = this;
-    v3 = &pParty->pPlayers[player_num-1];
-    v73 = 1;
-    if ( pParty->bTurnBasedModeOn == 1 && (pTurnEngine->turn_stage == 1 || pTurnEngine->turn_stage == 3) )
-        return;
-    if ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uEquipType == EQUIP_REAGENT )
-        {
-        if ( pParty->pPickedItem.uItemID == 160 )
-            { 
-            pParty->pPlayers[player_num-1].SetCondition(Condition_Poison1, 1);
-            }
-        else if ( pParty->pPickedItem.uItemID == 161 )
-            {
-            new_mana_val = v3->sMana;
-            new_mana_val += 2;
-            if ( new_mana_val > v3->GetMaxMana() )
-                new_mana_val = v3->GetMaxMana();
-            v3->PlaySound(SPEECH_36, 0);
-            }
-        else if ( pParty->pPickedItem.uItemID == 162 )
-            {
-            pParty->pPlayers[player_num-1].Heal(2);
-            v3->PlaySound(SPEECH_36, 0);
-            
-            }
-        else
-            {    
-            v68 = pParty->pPickedItem.GetDisplayName();
-            sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[36], v68);//"%s can not be used that way"
-            ShowStatusBarString(pTmpBuf.data(), 2);
-            pAudioPlayer->PlaySound((SoundID)27, 0, 0, -1, 0, 0, 0, 0);
-            return;
-            }
-        pAudioPlayer->PlaySound((SoundID)211, 0, 0, -1, 0, 0, 0, 0);
-
-        if ( pGUIWindow_CurrentMenu && pGUIWindow_CurrentMenu->eWindowType != WINDOW_null)
-            {
-            pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 0, 0);
-            }
-        if ( v73 )
-            {
-            if ( pParty->bTurnBasedModeOn )
-                {
-                pParty->pTurnBasedPlayerRecoveryTimes[player_num-1] = 100;
-                thisb->SetRecoveryTime(100);
-                pTurnEngine->ApplyPlayerAction();
-                }
-            else
-                {
-                thisb->SetRecoveryTime((signed __int64)(flt_6BE3A4_debug_recmod1 * 213.3333333333333));
-                }
-            }
-        pMouse->RemoveHoldingItem();
-        return;
-
-
-        }
-    if ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uEquipType == EQUIP_POTION )
-        {
-        switch ( pParty->pPickedItem.uItemID )
-            {
-        case 221: //Catalyst
-            pParty->pPlayers[player_num-1].SetCondition(Condition_Poison1, 1);
-            break;
-        case 222: //Cure Wounds
-            v25 = pParty->pPickedItem.uEnchantmentType + 10;
-            pParty->pPlayers[player_num-1].Heal(v25);
-            v3->PlaySound(SPEECH_36, 0);
-            break;
-        case 223: //Magic Potion
-            v26 = pParty->pPickedItem.uEnchantmentType + 10;
-            new_mana_val = v3->sMana;
-            new_mana_val += v26;
-            if ( new_mana_val > v3->GetMaxMana() )
-                new_mana_val = v3->GetMaxMana();
-            v3->PlaySound(SPEECH_36, 0);
-            break;
-        case 224: //Cure Weakness
-            v3->pConditions[Condition_Weak] = 0i64;
-            v3->PlaySound(SPEECH_36, 0);
-            break;
-        case 225: //Cure Disease
-            v3->pConditions[Condition_Disease3] = 0i64;      
-            v3->pConditions[Condition_Disease2] = 0i64;
-            v3->pConditions[Condition_Disease1] = 0i64;
-            v3->PlaySound(SPEECH_36, 0);
-            break;
-        case 226: //Cure Poison
-            v3->pConditions[Condition_Poison3] = 0i64;
-            v3->pConditions[Condition_Poison2] = 0i64;
-            v3->pConditions[Condition_Poison1] = 0i64;
-            v3->PlaySound(SPEECH_36, 0);
-            break;
-        case 227: //Awaken
-            v3->pConditions[Condition_Sleep] = 0i64;
-            v3->PlaySound(SPEECH_36, 0);
-            break;
-        case 228: //Haste
-            if ( !v3->pConditions[Condition_Weak] )
-                {
+{
+  Player *playerAffected; // esi@1
+  signed int v5; // eax@17
+  int v8; // edx@39
+  char *v13; // eax@45
+  signed int v15; // edi@68
+  int v16; // edx@73
+  unsigned __int16 v17; // edi@73
+  unsigned int v18; // eax@73
+  const char *v22; // eax@84
+  int scroll_id; // esi@96
+  int v25; // eax@109
+  int v26; // eax@113
+  int new_mana_val; // edi@114
+  signed __int64 v28; // qax@120
+  __int64 v30; // edi@137
+  __int64 v32; // ST3C_4@137
+  __int64 v34; // ST34_4@137
+  unsigned __int16 v50; // [sp-Ch] [bp-38h]@120
+  const char *v66; // [sp-4h] [bp-30h]@69
+  signed int v67; // [sp-4h] [bp-30h]@77
+  const char *v68; // [sp-4h] [bp-30h]@89
+  char v72; // [sp+20h] [bp-Ch]@68
+  signed int v73; // [sp+24h] [bp-8h]@1
+  char*  v74; // [sp+24h] [bp-8h]@23
+  Player *thisb; // [sp+28h] [bp-4h]@1
+  unsigned int thisa; // [sp+28h] [bp-4h]@22
+
+  thisb = this;
+  playerAffected = &pParty->pPlayers[player_num-1];
+  v73 = 1;
+  if ( pParty->bTurnBasedModeOn == 1 && (pTurnEngine->turn_stage == 1 || pTurnEngine->turn_stage == 3) )
+      return;
+  if ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uEquipType == EQUIP_REAGENT )
+  {
+    if ( pParty->pPickedItem.uItemID == 160 )
+    { 
+      playerAffected->SetCondition(Condition_Poison1, 1);
+    }
+    else if ( pParty->pPickedItem.uItemID == 161 )
+    {
+      new_mana_val = playerAffected->sMana;
+      new_mana_val += 2;
+      if ( new_mana_val > playerAffected->GetMaxMana() )
+        new_mana_val = playerAffected->GetMaxMana();
+      playerAffected->PlaySound(SPEECH_36, 0);
+    }
+    else if ( pParty->pPickedItem.uItemID == 162 )
+    {
+      playerAffected->Heal(2);
+      playerAffected->PlaySound(SPEECH_36, 0);
+    }
+    else
+    {    
+      v68 = pParty->pPickedItem.GetDisplayName();
+      sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[36], v68);//"%s can not be used that way"
+      ShowStatusBarString(pTmpBuf.data(), 2);
+      pAudioPlayer->PlaySound((SoundID)27, 0, 0, -1, 0, 0, 0, 0);
+      return;
+    }
+    pAudioPlayer->PlaySound((SoundID)211, 0, 0, -1, 0, 0, 0, 0);
+
+    if ( pGUIWindow_CurrentMenu && pGUIWindow_CurrentMenu->eWindowType != WINDOW_null)
+    {
+      pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 0, 0);
+    }
+    if ( v73 )
+    {
+      if ( pParty->bTurnBasedModeOn )
+      {
+        pParty->pTurnBasedPlayerRecoveryTimes[player_num-1] = 100;
+        thisb->SetRecoveryTime(100);
+        pTurnEngine->ApplyPlayerAction();
+      }
+      else
+      {
+        thisb->SetRecoveryTime(flt_6BE3A4_debug_recmod1 * 213.3333333333333);
+      }
+    }
+    pMouse->RemoveHoldingItem();
+    return;
+  }
+
+  if ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uEquipType == EQUIP_POTION )
+  {
+      switch ( pParty->pPickedItem.uItemID )
+      {
+          case 221: //Catalyst
+              playerAffected->SetCondition(Condition_Poison1, 1);
+              break;
+          case 222: //Cure Wounds
+              v25 = pParty->pPickedItem.uEnchantmentType + 10;
+              playerAffected->Heal(v25);
+              playerAffected->PlaySound(SPEECH_36, 0);
+              break;
+          case 223: //Magic Potion
+              v26 = pParty->pPickedItem.uEnchantmentType + 10;
+              new_mana_val = playerAffected->sMana;
+              new_mana_val += v26;
+              if ( new_mana_val > playerAffected->GetMaxMana() )
+                  new_mana_val = playerAffected->GetMaxMana();
+              playerAffected->PlaySound(SPEECH_36, 0);
+              break;
+          case 224: //Cure Weakness
+              playerAffected->pConditions[Condition_Weak] = 0i64;
+              playerAffected->PlaySound(SPEECH_36, 0);
+              break;
+          case 225: //Cure Disease
+              playerAffected->pConditions[Condition_Disease3] = 0i64;      
+              playerAffected->pConditions[Condition_Disease2] = 0i64;
+              playerAffected->pConditions[Condition_Disease1] = 0i64;
+              playerAffected->PlaySound(SPEECH_36, 0);
+              break;
+          case 226: //Cure Poison
+              playerAffected->pConditions[Condition_Poison3] = 0i64;
+              playerAffected->pConditions[Condition_Poison2] = 0i64;
+              playerAffected->pConditions[Condition_Poison1] = 0i64;
+              playerAffected->PlaySound(SPEECH_36, 0);
+              break;
+          case 227: //Awaken
+              playerAffected->pConditions[Condition_Sleep] = 0i64;
+              playerAffected->PlaySound(SPEECH_36, 0);
+              break;
+          case 228: //Haste
+              if ( !playerAffected->pConditions[Condition_Weak] )
+              {
                 v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
-                v3->pPlayerBuffs[7].Apply(pParty->uTimePlayed + v28, 3, 5, 0, 0);
-                v3->PlaySound(SPEECH_36, 0);
-                }
-            break;
-        case 229: //Heroism
-            v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
-            v3->pPlayerBuffs[8].Apply(pParty->uTimePlayed + v28, 3, 5, 0, 0);
-            v3->PlaySound(SPEECH_36, 0);
-            break;
-        case 230: //Bless
-            v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
-            v3->pPlayerBuffs[1].Apply(pParty->uTimePlayed + v28, 3, 5, 0, 0);
-            v3->PlaySound(SPEECH_36, 0);
-            break;
-        case 231: //Preservation
-            v50 = 3 * pParty->pPickedItem.uEnchantmentType;
-            v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
-            v3->pPlayerBuffs[11].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
-            v3->PlaySound(SPEECH_36, 0);
-            break;
-        case 232: //Shield
-            v50 = 3 * pParty->pPickedItem.uEnchantmentType;
-            v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
-            v3->pPlayerBuffs[13].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
-            v3->PlaySound(SPEECH_36, 0);
-            break;
-        case 234: //Stoneskin
-            v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
-            v3->pPlayerBuffs[14].Apply(pParty->uTimePlayed + v28, 3, 5, 0, 0);
-            v3->PlaySound(SPEECH_36, 0);
-            break;
-        case 235: //Water Breathing
-            v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335),
-            v3->pPlayerBuffs[23].Apply(pParty->uTimePlayed +v28,  3, 5, 0, 0);
-            break;
-        case 237: //Remove Fear
-            v3->pConditions[Condition_Fear] = 0i64;
-            v3->PlaySound(SPEECH_36, 0);
-            break;
-        case 238: //Remove Curse
-            v3->pConditions[Condition_Cursed] = 0i64;
-            v3->PlaySound(SPEECH_36, 0);
-            break;
-        case 239: //Cure Insanity
-            v3->pConditions[Condition_Insane] = 0i64;
-            v3->PlaySound(SPEECH_36, 0);
-            break;
-        case 240: //Might Boost
-            v50 = 3 * pParty->pPickedItem.uEnchantmentType;
-            v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
-            v3->pPlayerBuffs[19].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
-            v3->PlaySound(SPEECH_36, 0);
-            break;
-        case 241: //Intellect Boost
-            v50 = 3 * pParty->pPickedItem.uEnchantmentType;
-            v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
-            v3->pPlayerBuffs[17].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
-            v3->PlaySound(SPEECH_36, 0);
-            break;
-        case 242: //Personality Boost
-            v50 = 3 * pParty->pPickedItem.uEnchantmentType;
-            v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
-            v3->pPlayerBuffs[20].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
-            v3->PlaySound(SPEECH_36, 0);
-            break;
-        case 243://Endurance Boost
-            v50 = 3 * pParty->pPickedItem.uEnchantmentType;
-            v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
-            v3->pPlayerBuffs[16].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
-            v3->PlaySound(SPEECH_36, 0);
-            break;
-        case 244: //Speed Boost
-            v50 = 3 * pParty->pPickedItem.uEnchantmentType;
-            v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
-            v3->pPlayerBuffs[21].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
-            v3->PlaySound(SPEECH_36, 0);
-            break;
-        case 245: //Accuracy Boost
-            v50 = 3 * pParty->pPickedItem.uEnchantmentType;
-            v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
-            v3->pPlayerBuffs[15].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
-            v3->PlaySound(SPEECH_36, 0);
-            break;
-        case 251: //Cure Paralysis
-            v3->pConditions[Condition_Paralyzed] = 0i64;
-            v3->PlaySound(SPEECH_36, 0);
-            break;
-        case 252://Divine Restoration
-            v30 = v3->pConditions[Condition_Dead];
-            v32 = v3->pConditions[Condition_Pertified];
-            v34 = v3->pConditions[Condition_Eradicated];    
-            memset(&pParty->pPlayers[player_num-1].pConditions,0,sizeof(pConditions));
-            v3->pConditions[Condition_Dead] = v30;
-            v3->pConditions[Condition_Pertified] = v32;
-            v3->pConditions[Condition_Eradicated] = v34;
-            v3->PlaySound(SPEECH_36, 0);
-            break;
-        case 253: //Divine Cure
-            v25 = 5 * pParty->pPickedItem.uEnchantmentType;
-            pParty->pPlayers[player_num-1].Heal(v25);
-            v3->PlaySound(SPEECH_36, 0);
-            break;
-        case 254: //Divine Power
-            v26 = 5 * pParty->pPickedItem.uEnchantmentType;
-            new_mana_val = v3->sMana;
-            new_mana_val += v26;
-            if ( new_mana_val > v3->GetMaxMana() )
-                new_mana_val = v3->GetMaxMana();
-            v3->PlaySound(SPEECH_36, 0);
-            break;
-        case 255: //Luck Boost
-            v50 = 3 * pParty->pPickedItem.uEnchantmentType;
-            v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
-            v3->pPlayerBuffs[18].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
-            v3->PlaySound(SPEECH_36, 0);
-            break;
-        case 256: //Fire Resistance
-            v50 = 3 * pParty->pPickedItem.uEnchantmentType;
-            v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
-            v3->pPlayerBuffs[5].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
-            v3->PlaySound(SPEECH_36, 0);
-            break;
-        case 257: //Air Resistance
-            v50 = 3 * pParty->pPickedItem.uEnchantmentType;
-            v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
-            v3->pPlayerBuffs[0].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
-            v3->PlaySound(SPEECH_36, 0);
-            break;
-        case 258: //Water Resistance
-            v50 = 3 * pParty->pPickedItem.uEnchantmentType;
-            v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
-            v3->pPlayerBuffs[22].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
-            v3->PlaySound(SPEECH_36, 0);
-            break;
-        case 259: //Earth Resistance
-            v50 = 3 * pParty->pPickedItem.uEnchantmentType;
-            v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
-            v3->pPlayerBuffs[3].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
-            v3->PlaySound(SPEECH_36, 0);
-            break;
-        case 260: //Mind Resistance
-            v50 = 3 * pParty->pPickedItem.uEnchantmentType;
-            v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
-            v3->pPlayerBuffs[9].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
-            v3->PlaySound(SPEECH_36, 0);
-            break;
-        case 261: //Body Resistance
-            v50 = 3 * pParty->pPickedItem.uEnchantmentType;
-            v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
-            v3->pPlayerBuffs[2].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
-            v3->PlaySound(SPEECH_36, 0);
-           break;
-        case 262: //Stone to Flesh
-            v3->pConditions[Condition_Pertified] = 0i64;
-            v3->PlaySound(SPEECH_36, 0);
-            break;
-        case 264: //Pure Luck
-            if ( !v3->pure_luck_used )
-                {
-                v3->uLuck += 50;
-                v3->pure_luck_used = 1;
-                }
-            v3->PlaySound(SPEECH_36, 0);
-            break;
-        case 265: //Pure Speed
-            if ( !v3->pure_speed_used )
-                {
-                v3->uSpeed += 50;
-                v3->pure_speed_used = 1;
-                }
-            v3->PlaySound(SPEECH_36, 0);
-            break;
-        case 266: //Pure Intellect
-            if ( !v3->pure_intellect_used )
-                {
-                v3->uIntelligence += 50;
-                v3->pure_intellect_used = 1;
-                }
-            v3->PlaySound(SPEECH_36, 0);
-           break;
-        case 267: //Pure Endurance
-            if ( !v3->pure_endurance_used )
-                {
-                v3->uEndurance += 50;
-                v3->pure_endurance_used = 1;
-                }
-            v3->PlaySound(SPEECH_36, 0);
-            break;
-        case 268:  //Pure Personality
-            if ( !v3->pure_willpower_used )
-                {
-                v3->uWillpower += 50;
-                v3->pure_willpower_used = 1;
-                }
-            v3->PlaySound(SPEECH_36, 0);
-            break;
-        case 269: //Pure Accuracy
-            if ( !v3->pure_accuracy_used )
-                {
-                v3->uAccuracy += 50;
-                v3->pure_accuracy_used = 1;
-                }
-            v3->PlaySound(SPEECH_36, 0);
-            break;
-        case 270: //Pure Might
-            if ( !v3->pure_might_used )
-                {
-                v3->uMight += 50;
-                v3->pure_might_used = 1;
-                }
-            v3->PlaySound(SPEECH_36, 0);
-            break;
-        case 271: //Rejuvenation
-            v3->sAgeModifier = 0;
-            v3->PlaySound(SPEECH_36, 0);
-           break;
-
-        default:
-            v68 = pParty->pPickedItem.GetDisplayName();
-            sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[36], v68);//"%s can not be used that way"
-            ShowStatusBarString(pTmpBuf.data(), 2u);
-            pAudioPlayer->PlaySound((SoundID)27, 0, 0, -1, 0, 0, 0, 0);
-            return;
-            }
-        pAudioPlayer->PlaySound((SoundID)210, 0, 0, -1, 0, 0, 0, 0);
-        if ( pGUIWindow_CurrentMenu && pGUIWindow_CurrentMenu->eWindowType != WINDOW_null)
-            {
-            if ( !v73 )
-                {
-                pMouse->RemoveHoldingItem();
-                return;
-                }
-            pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 0, 0);
-            }
-        if ( v73 )
-            {
-            if ( pParty->bTurnBasedModeOn )
-                {
-                pParty->pTurnBasedPlayerRecoveryTimes[player_num-1] = 100;
-                thisb->SetRecoveryTime(100);
-                pTurnEngine->ApplyPlayerAction();
-                }
-            else
-                {
-                thisb->SetRecoveryTime((signed __int64)(flt_6BE3A4_debug_recmod1 * 213.3333333333333));
-                }
-            }
-        pMouse->RemoveHoldingItem();
+                playerAffected->pPlayerBuffs[7].Apply(pParty->uTimePlayed + v28, 3, 5, 0, 0);
+                playerAffected->PlaySound(SPEECH_36, 0);
+              }
+              break;
+          case 229: //Heroism
+              v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
+              playerAffected->pPlayerBuffs[8].Apply(pParty->uTimePlayed + v28, 3, 5, 0, 0);
+              playerAffected->PlaySound(SPEECH_36, 0);
+              break;
+          case 230: //Bless
+              v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
+              playerAffected->pPlayerBuffs[1].Apply(pParty->uTimePlayed + v28, 3, 5, 0, 0);
+              playerAffected->PlaySound(SPEECH_36, 0);
+              break;
+          case 231: //Preservation
+              v50 = 3 * pParty->pPickedItem.uEnchantmentType;
+              v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
+              playerAffected->pPlayerBuffs[11].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
+              playerAffected->PlaySound(SPEECH_36, 0);
+              break;
+          case 232: //Shield
+              v50 = 3 * pParty->pPickedItem.uEnchantmentType;
+              v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
+              playerAffected->pPlayerBuffs[13].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
+              playerAffected->PlaySound(SPEECH_36, 0);
+              break;
+          case 234: //Stoneskin
+              v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
+              playerAffected->pPlayerBuffs[14].Apply(pParty->uTimePlayed + v28, 3, 5, 0, 0);
+              playerAffected->PlaySound(SPEECH_36, 0);
+              break;
+          case 235: //Water Breathing
+              v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335),
+              playerAffected->pPlayerBuffs[23].Apply(pParty->uTimePlayed +v28,  3, 5, 0, 0);
+              break;
+          case 237: //Remove Fear
+              playerAffected->pConditions[Condition_Fear] = 0i64;
+              playerAffected->PlaySound(SPEECH_36, 0);
+              break;
+          case 238: //Remove Curse
+              playerAffected->pConditions[Condition_Cursed] = 0i64;
+              playerAffected->PlaySound(SPEECH_36, 0);
+              break;
+          case 239: //Cure Insanity
+              playerAffected->pConditions[Condition_Insane] = 0i64;
+              playerAffected->PlaySound(SPEECH_36, 0);
+              break;
+          case 240: //Might Boost
+              v50 = 3 * pParty->pPickedItem.uEnchantmentType;
+              v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
+              playerAffected->pPlayerBuffs[19].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
+              playerAffected->PlaySound(SPEECH_36, 0);
+              break;
+          case 241: //Intellect Boost
+              v50 = 3 * pParty->pPickedItem.uEnchantmentType;
+              v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
+              playerAffected->pPlayerBuffs[17].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
+              playerAffected->PlaySound(SPEECH_36, 0);
+              break;
+          case 242: //Personality Boost
+              v50 = 3 * pParty->pPickedItem.uEnchantmentType;
+              v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
+              playerAffected->pPlayerBuffs[20].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
+              playerAffected->PlaySound(SPEECH_36, 0);
+              break;
+          case 243://Endurance Boost
+              v50 = 3 * pParty->pPickedItem.uEnchantmentType;
+              v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
+              playerAffected->pPlayerBuffs[16].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
+              playerAffected->PlaySound(SPEECH_36, 0);
+              break;
+          case 244: //Speed Boost
+              v50 = 3 * pParty->pPickedItem.uEnchantmentType;
+              v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
+              playerAffected->pPlayerBuffs[21].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
+              playerAffected->PlaySound(SPEECH_36, 0);
+              break;
+          case 245: //Accuracy Boost
+              v50 = 3 * pParty->pPickedItem.uEnchantmentType;
+              v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
+              playerAffected->pPlayerBuffs[15].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
+              playerAffected->PlaySound(SPEECH_36, 0);
+              break;
+          case 251: //Cure Paralysis
+              playerAffected->pConditions[Condition_Paralyzed] = 0i64;
+              playerAffected->PlaySound(SPEECH_36, 0);
+              break;
+          case 252://Divine Restoration
+              v30 = playerAffected->pConditions[Condition_Dead];
+              v32 = playerAffected->pConditions[Condition_Pertified];
+              v34 = playerAffected->pConditions[Condition_Eradicated];    
+              memset(&playerAffected->pConditions,0,sizeof(pConditions));
+              playerAffected->pConditions[Condition_Dead] = v30;
+              playerAffected->pConditions[Condition_Pertified] = v32;
+              playerAffected->pConditions[Condition_Eradicated] = v34;
+              playerAffected->PlaySound(SPEECH_36, 0);
+              break;
+          case 253: //Divine Cure
+              v25 = 5 * pParty->pPickedItem.uEnchantmentType;
+              playerAffected->Heal(v25);
+              playerAffected->PlaySound(SPEECH_36, 0);
+              break;
+          case 254: //Divine Power
+              v26 = 5 * pParty->pPickedItem.uEnchantmentType;
+              new_mana_val = playerAffected->sMana;
+              new_mana_val += v26;
+              if ( new_mana_val > playerAffected->GetMaxMana() )
+                  new_mana_val = playerAffected->GetMaxMana();
+              playerAffected->PlaySound(SPEECH_36, 0);
+              break;
+          case 255: //Luck Boost
+              v50 = 3 * pParty->pPickedItem.uEnchantmentType;
+              v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
+              playerAffected->pPlayerBuffs[18].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
+              playerAffected->PlaySound(SPEECH_36, 0);
+              break;
+          case 256: //Fire Resistance
+              v50 = 3 * pParty->pPickedItem.uEnchantmentType;
+              v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
+              playerAffected->pPlayerBuffs[5].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
+              playerAffected->PlaySound(SPEECH_36, 0);
+              break;
+          case 257: //Air Resistance
+              v50 = 3 * pParty->pPickedItem.uEnchantmentType;
+              v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
+              playerAffected->pPlayerBuffs[0].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
+              playerAffected->PlaySound(SPEECH_36, 0);
+              break;
+          case 258: //Water Resistance
+              v50 = 3 * pParty->pPickedItem.uEnchantmentType;
+              v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
+              playerAffected->pPlayerBuffs[22].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
+              playerAffected->PlaySound(SPEECH_36, 0);
+              break;
+          case 259: //Earth Resistance
+              v50 = 3 * pParty->pPickedItem.uEnchantmentType;
+              v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
+              playerAffected->pPlayerBuffs[3].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
+              playerAffected->PlaySound(SPEECH_36, 0);
+              break;
+          case 260: //Mind Resistance
+              v50 = 3 * pParty->pPickedItem.uEnchantmentType;
+              v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
+              playerAffected->pPlayerBuffs[9].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
+              playerAffected->PlaySound(SPEECH_36, 0);
+              break;
+          case 261: //Body Resistance
+              v50 = 3 * pParty->pPickedItem.uEnchantmentType;
+              v28 = (signed __int64)((double)(230400 * pParty->pPickedItem.uEnchantmentType) * 0.033333335);
+              playerAffected->pPlayerBuffs[2].Apply(pParty->uTimePlayed + v28, 0, v50, 0, 0);
+              playerAffected->PlaySound(SPEECH_36, 0);
+              break;
+          case 262: //Stone to Flesh
+              playerAffected->pConditions[Condition_Pertified] = 0i64;
+              playerAffected->PlaySound(SPEECH_36, 0);
+              break;
+          case 264: //Pure Luck
+              if ( !playerAffected->pure_luck_used )
+              {
+                playerAffected->uLuck += 50;
+                playerAffected->pure_luck_used = 1;
+              }
+              playerAffected->PlaySound(SPEECH_36, 0);
+              break;
+          case 265: //Pure Speed
+              if ( !playerAffected->pure_speed_used )
+              {
+                playerAffected->uSpeed += 50;
+                playerAffected->pure_speed_used = 1;
+              }
+              playerAffected->PlaySound(SPEECH_36, 0);
+              break;
+          case 266: //Pure Intellect
+              if ( !playerAffected->pure_intellect_used )
+              {
+                playerAffected->uIntelligence += 50;
+                playerAffected->pure_intellect_used = 1;
+              }
+              playerAffected->PlaySound(SPEECH_36, 0);
+              break;
+          case 267: //Pure Endurance
+              if ( !playerAffected->pure_endurance_used )
+              {
+                playerAffected->uEndurance += 50;
+                playerAffected->pure_endurance_used = 1;
+              }
+              playerAffected->PlaySound(SPEECH_36, 0);
+              break;
+          case 268:  //Pure Personality
+              if ( !playerAffected->pure_willpower_used )
+              {
+                playerAffected->uWillpower += 50;
+                playerAffected->pure_willpower_used = 1;
+              }
+              playerAffected->PlaySound(SPEECH_36, 0);
+              break;
+          case 269: //Pure Accuracy
+              if ( !playerAffected->pure_accuracy_used )
+              {
+                playerAffected->uAccuracy += 50;
+                playerAffected->pure_accuracy_used = 1;
+              }
+              playerAffected->PlaySound(SPEECH_36, 0);
+              break;
+          case 270: //Pure Might
+              if ( !playerAffected->pure_might_used )
+              {
+                playerAffected->uMight += 50;
+                playerAffected->pure_might_used = 1;
+              }
+              playerAffected->PlaySound(SPEECH_36, 0);
+              break;
+          case 271: //Rejuvenation
+              playerAffected->sAgeModifier = 0;
+              playerAffected->PlaySound(SPEECH_36, 0);
+              break;
+
+          default:
+          v68 = pParty->pPickedItem.GetDisplayName();
+          sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[36], v68);//"%s can not be used that way"
+          ShowStatusBarString(pTmpBuf.data(), 2u);
+          pAudioPlayer->PlaySound((SoundID)27, 0, 0, -1, 0, 0, 0, 0);
+          return;
+      }
+      pAudioPlayer->PlaySound((SoundID)210, 0, 0, -1, 0, 0, 0, 0);
+      if ( pGUIWindow_CurrentMenu && pGUIWindow_CurrentMenu->eWindowType != WINDOW_null)
+      {
+//         if ( !v73 )                                            v73 is always 1 at this point
+//         {
+//           pMouse->RemoveHoldingItem();
+//           return;
+//         }
+        pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 0, 0);
+      }
+      if ( v73 )
+      {
+        if ( pParty->bTurnBasedModeOn )
+        {
+          pParty->pTurnBasedPlayerRecoveryTimes[player_num-1] = 100;
+          thisb->SetRecoveryTime(100);
+          pTurnEngine->ApplyPlayerAction();
+        }
+        else
+        {
+          thisb->SetRecoveryTime(flt_6BE3A4_debug_recmod1 * 213.3333333333333);
+        }
+      }
+      pMouse->RemoveHoldingItem();
+      return;
+  }
+
+
+  if ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uEquipType == EQUIP_SPELL_SCROLL )
+  {
+    if ( pCurrentScreen == SCREEN_CASTING )
         return;
-    
-        }
-
-
-    if ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uEquipType == EQUIP_SPELL_SCROLL )
-        {
-
-
-        if ( pCurrentScreen == SCREEN_CASTING )
-            return;
-        if ( !pParty->pPlayers[player_num-1].CanAct() )
-            {
-
-            v68 = aCharacterConditionNames[v3->GetMajorConditionIdx()];
-        sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[382], v68);
+    if ( !playerAffected->CanAct() )
+    {
+
+      v68 = aCharacterConditionNames[playerAffected->GetMajorConditionIdx()];
+      sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[382], v68);
+      ShowStatusBarString(pTmpBuf.data(), 2u);
+      pAudioPlayer->PlaySound((SoundID)27, 0, 0, -1, 0, 0, 0, 0);
+      return;
+    }
+    if ( bUnderwater == 1 )
+    {
+      ShowStatusBarString(pGlobalTXT_LocalizationStrings[652], 2u);//"You can not do that while you are underwater!"
+      pAudioPlayer->PlaySound((SoundID)27, 0, 0, -1, 0, 0, 0, 0);
+      return;
+    }
+    dword_50C9AC = 1;
+    scroll_id = pParty->pPickedItem.uItemID - 299;
+    if ( scroll_id == 30 || scroll_id == 4 || scroll_id == 91 || scroll_id == 28 ) //Enchant Item scroll, Vampiric Weapon scroll ,Recharge Item ,Fire Aura
+    {
+      pMouse->RemoveHoldingItem();
+      pGUIWindow_CurrentMenu->Release();
+      pIcons_LOD->RemoveTexturesPackFromTextureList();
+      pCurrentScreen = SCREEN_GAME;
+      viewparams->bRedrawGameUI = 1;
+      _42777D_CastSpell_UseWand_ShootArrow(scroll_id, player_num - 1, 0x85u, 1, 0);
+    }
+    else
+    {
+      _720984_unused = pParty->pPickedItem.uItemID;
+      pMouse->RemoveHoldingItem();
+      pMessageQueue_50C9E8->AddMessage(UIMSG_SpellScrollUse, scroll_id, player_num - 1);
+      if ( pCurrentScreen && pGUIWindow_CurrentMenu
+        && (pGUIWindow_CurrentMenu->eWindowType != WINDOW_null))
+      {
+        pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 0, 0);
+      }
+    }
+    return;
+  }
+
+  if ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uEquipType == EQUIP_BOOK )
+  {  
+      v15 = pParty->pPickedItem.uItemID - 400;
+      v72 = playerAffected->spellbook.bHaveSpell[pParty->pPickedItem.uItemID-400];//(char *)&v3->pConditions[0] + pParty->pPickedItem.uItemID + 2;
+      if ( v72 )
+      {
+        v66 = pParty->pPickedItem.GetDisplayName();
+        sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[380], v66);//"You already know the %s spell"
         ShowStatusBarString(pTmpBuf.data(), 2u);
         pAudioPlayer->PlaySound((SoundID)27, 0, 0, -1, 0, 0, 0, 0);
         return;
-            }
-        if ( bUnderwater == 1 )
-            {
-            ShowStatusBarString(pGlobalTXT_LocalizationStrings[652], 2u);//"You can not do that while you are underwater!"
-            pAudioPlayer->PlaySound((SoundID)27, 0, 0, -1, 0, 0, 0, 0);
-            return;
-            }
-        dword_50C9AC = 1;
-        scroll_id = pParty->pPickedItem.uItemID - 299;
-        if ( scroll_id == 30 || scroll_id == 4 || scroll_id == 91 || scroll_id == 28 ) //Enchant Item scroll, Vampiric Weapon scroll ,Recharge Item ,Fire Aura
-            {
-            pMouse->RemoveHoldingItem();
-            pGUIWindow_CurrentMenu->Release();
-            pIcons_LOD->RemoveTexturesPackFromTextureList();
-            pCurrentScreen = SCREEN_GAME;
-            viewparams->bRedrawGameUI = 1;
-            _42777D_CastSpell_UseWand_ShootArrow(scroll_id, player_num - 1, 0x85u, 1, 0);
-            }
-        else
-            {
-            _720984_unused = pParty->pPickedItem.uItemID;
-            pMouse->RemoveHoldingItem();
-            pMessageQueue_50C9E8->AddMessage(UIMSG_SpellScrollUse, scroll_id, player_num - 1);
-            if ( pCurrentScreen && pGUIWindow_CurrentMenu
-                && (pGUIWindow_CurrentMenu->eWindowType != WINDOW_null))
-                {
-                pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 0, 0);
-                }
-            }
+      }
+      if ( !playerAffected->CanAct() )
+      {
+        v66 = aCharacterConditionNames[playerAffected->GetMajorConditionIdx()];
+        sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[382], v66);//"That player is %s"
+        ShowStatusBarString(pTmpBuf.data(), 2u);
+        pAudioPlayer->PlaySound((SoundID)27, 0, 0, -1, 0, 0, 0, 0);
         return;
-        }
-
-    if ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uEquipType == EQUIP_BOOK )
-
-        {  
-        v15 = pParty->pPickedItem.uItemID - 400;
-        v72 = v3->spellbook.bHaveSpell[pParty->pPickedItem.uItemID-400];//(char *)&v3->pConditions[0] + pParty->pPickedItem.uItemID + 2;
-        if ( v72 )
-            {
-            v66 = pParty->pPickedItem.GetDisplayName();
-            sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[380], v66);//"You already know the %s spell"
-            ShowStatusBarString(pTmpBuf.data(), 2u);
-            pAudioPlayer->PlaySound((SoundID)27, 0, 0, -1, 0, 0, 0, 0);
-            return;
-            }
-        if ( !pParty->pPlayers[player_num-1].CanAct() )
-            {
-            v66 = aCharacterConditionNames[v3->GetMajorConditionIdx()];
-            sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[382], v66);//"That player is %s"
-            ShowStatusBarString(pTmpBuf.data(), 2u);
-            pAudioPlayer->PlaySound((SoundID)27, 0, 0, -1, 0, 0, 0, 0);
-            return;
-            }
-        v16 = v15 % 11 + 1;
-        v17 = v3->pActiveSkills[v15 / 11 + 12];
-        v18 = SkillToMastery(v17) - 1;
-        switch (v18)
-            {
+      }
+      v16 = v15 % 11 + 1;
+      v17 = playerAffected->pActiveSkills[v15 / 11 + 12];
+      v18 = SkillToMastery(v17) - 1;
+      switch (v18)  
+      {
         case 0: v67 = 4; break;
         case 1: v67 = 7; break;
         case 2: v67 = 10; break;
         case 3: v67 = 11; break;
         default:
-            v67 = player_num;   
-            }
+          v67 = player_num;   
+      }
   
-        if ( v16 > v67 || !v17 )
-            {
-            v22 = pParty->pPickedItem.GetDisplayName();
-            sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[381], v22); //"You don't have the skill to learn %s"
-            ShowStatusBarString(pTmpBuf.data(), 2u);
-            v3->PlaySound((PlayerSpeech)20, 0);
-            return; 
-            }
-     //   v72 = 1;
-        v3->PlaySound(SPEECH_21, 0);
-        v73 = 0;
-
-
-        if ( pGUIWindow_CurrentMenu && pGUIWindow_CurrentMenu->eWindowType != WINDOW_null)
-            {
-            if ( !v73 )
-                {
-                pMouse->RemoveHoldingItem();
-                return;
-                }
-            pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 0, 0);
-            }
-        if ( v73 )
+      if ( v16 > v67 || !v17 )
+      {
+        v22 = pParty->pPickedItem.GetDisplayName();
+        sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[381], v22); //"You don't have the skill to learn %s"
+        ShowStatusBarString(pTmpBuf.data(), 2u);
+        playerAffected->PlaySound((PlayerSpeech)20, 0);
+        return; 
+      }
+    //   v72 = 1;
+      playerAffected->PlaySound(SPEECH_21, 0);
+      v73 = 0;
+
+
+      if ( pGUIWindow_CurrentMenu && pGUIWindow_CurrentMenu->eWindowType != WINDOW_null)
+      {
+        if ( !v73 )
+        {
+          pMouse->RemoveHoldingItem();
+          return;
+        }
+        pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 0, 0);
+      }
+//       if ( v73 )                                                v73 is always 0 at this point
+//       {
+//         if ( pParty->bTurnBasedModeOn )
+//         {
+//           pParty->pTurnBasedPlayerRecoveryTimes[player_num-1] = 100;
+//           thisb->SetRecoveryTime(100);
+//           pTurnEngine->ApplyPlayerAction();
+//         }
+//         else
+//         {
+//           thisb->SetRecoveryTime(flt_6BE3A4_debug_recmod1 * 213.3333333333333);
+//         }
+//       }
+      pMouse->RemoveHoldingItem();
+      return;
+  }
+
+  if ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uEquipType == EQUIP_MESSAGE_SCROLL )
+  {
+      if ( playerAffected->CanAct() )
+      {
+          CreateMsgScrollWindow(pParty->pPickedItem.uItemID);
+          playerAffected->PlaySound(SPEECH_37, 0);
+          return;
+      }
+      v68 = aCharacterConditionNames[playerAffected->GetMajorConditionIdx()];
+      sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[382], v68);
+      ShowStatusBarString(pTmpBuf.data(), 2u);
+      pAudioPlayer->PlaySound((SoundID)27, 0, 0, -1, 0, 0, 0, 0);
+      return;
+  }
+  else
+  {
+    if (pParty->pPickedItem.uItemID == 616) //Genie Lamp
+    {
+      thisa = pParty->uCurrentMonthWeek + 1;
+      if ( pParty->uCurrentMonth >= 7 )
+          v74 = NULL;
+      else
+          v74 = aAttributeNames[pParty->uCurrentMonth];
+      switch ( pParty->uCurrentMonth )
+      {
+        case 0:
+            playerAffected->uMight += thisa;
+            sprintf(pTmpBuf.data(), "+%u %s %s", thisa, v74, pGlobalTXT_LocalizationStrings[121]);//"Permanent"	
+            break;
+        case 1:
+            playerAffected->uIntelligence += thisa;
+            sprintf(pTmpBuf.data(), "+%u %s %s", thisa, v74, pGlobalTXT_LocalizationStrings[121]);//"Permanent"	
+            break;
+        case 2:
+            playerAffected->uWillpower += thisa;
+            sprintf(pTmpBuf.data(), "+%u %s %s", thisa, v74, pGlobalTXT_LocalizationStrings[121]);//"Permanent"	
+            break;
+        case 3:
+            playerAffected->uEndurance += thisa;
+            sprintf(pTmpBuf.data(), "+%u %s %s", thisa, v74, pGlobalTXT_LocalizationStrings[121]);//"Permanent"	
+            break;
+        case 4:
+            playerAffected->uAccuracy += thisa;
+            sprintf(pTmpBuf.data(), "+%u %s %s", thisa, v74, pGlobalTXT_LocalizationStrings[121]);//"Permanent"	
+            break;
+        case 5:
+            playerAffected->uSpeed += thisa;
+            sprintf(pTmpBuf.data(), "+%u %s %s", thisa, v74, pGlobalTXT_LocalizationStrings[121]);//"Permanent"	
+            break;
+        case 6:
+            playerAffected->uLuck += thisa;
+            sprintf(pTmpBuf.data(), "+%u %s %s", thisa, v74, pGlobalTXT_LocalizationStrings[121]);//"Permanent"	
+            break;
+        case 7:
+            party_finds_gold(1000 * thisa, 0);
+            sprintf(pTmpBuf.data(), "+%u %s", 1000 * thisa, pGlobalTXT_LocalizationStrings[97]);//"Gold"
+            break;
+        case 8:
+            Party::GiveFood(5 * thisa); 
+            sprintf(pTmpBuf.data(), "+%u %s",5 * thisa , pGlobalTXT_LocalizationStrings[653]);//"Food"
+            break;
+        case 9u:
+            playerAffected->uSkillPoints += 2 * thisa;
+            sprintf(pTmpBuf.data(), "+%u %s", 2 * thisa, pGlobalTXT_LocalizationStrings[LOCSTR_SKILL_POINTS]);
+            break;
+        case 10:
+            playerAffected->uExperience += 2500 * thisa;
+            sprintf(pTmpBuf.data(), "+%u %s", 2500 * thisa, pGlobalTXT_LocalizationStrings[LOCSTR_EXPIRIENCE]);
+            break;
+        case 11:
+            v8 = rand() % 6;
+            switch (v8)
             {
-            if ( pParty->bTurnBasedModeOn )
-                {
-                pParty->pTurnBasedPlayerRecoveryTimes[player_num-1] = 100;
-                thisb->SetRecoveryTime(100);
-                pTurnEngine->ApplyPlayerAction();
-                }
-            else
-                {
-                thisb->SetRecoveryTime((signed __int64)(flt_6BE3A4_debug_recmod1 * 213.3333333333333));
-                }
+            case 0:
+                playerAffected->sResFireBase += thisa;
+                v13 = pGlobalTXT_LocalizationStrings[87];
+                break;
+            case 1:
+                playerAffected->sResAirBase += thisa;
+                v13 = pGlobalTXT_LocalizationStrings[6];
+                break;
+            case 2:
+                playerAffected->sResWaterBase += thisa;
+                v13 = pGlobalTXT_LocalizationStrings[240];
+                break;
+            case 3:
+                playerAffected->sResEarthBase += thisa;
+                v13 = pGlobalTXT_LocalizationStrings[70];
+                break;
+            case 4:
+                playerAffected->sResMindBase += thisa;
+                v13 = pGlobalTXT_LocalizationStrings[142];
+                break;
+            case 5:
+                playerAffected->sResBodyBase += thisa;
+                v13 = pGlobalTXT_LocalizationStrings[29];
+                break;
             }
-        pMouse->RemoveHoldingItem();
+            sprintf(pTmpBuf.data(), "+%u %s %s", thisa, v13, pGlobalTXT_LocalizationStrings[121]);
+            break;
+
+      }
+      ShowStatusBarString(pTmpBuf.data(), 2u);
+      pMouse->RemoveHoldingItem();
+      pGame->pStru6Instance->SetPlayerBuffAnim(SPELL_QUEST_COMPLETED, player_num - 1);
+      playerAffected->PlaySound(SPEECH_93, 0);
+      pAudioPlayer->PlaySound((SoundID)219, 0, 0, -1, 0, 0, 0, 0);
+      if ( pParty->uDaysPlayed == 6 || pParty->uDaysPlayed == 20 )
+          {
+          playerAffected->SetCondition(Condition_Eradicated, 0);
+          pAudioPlayer->PlaySound((SoundID)215, 0, 0, -1, 0, 0, 0, 0);
+          }
+      else if ( pParty->uDaysPlayed == 12 || pParty->uDaysPlayed == 26 )
+          {
+          playerAffected->SetCondition(Condition_Dead, 0);
+          pAudioPlayer->PlaySound((SoundID)215, 0, 0, -1, 0, 0, 0, 0);
+          }
+      else  if ( pParty->uDaysPlayed == 4 || pParty->uDaysPlayed == 25 )
+      {
+        playerAffected->SetCondition(Condition_Pertified, 0);
+        pAudioPlayer->PlaySound((SoundID)215, 0, 0, -1, 0, 0, 0, 0);                 
+      }
+      return;
+      }
+      else if ( pParty->pPickedItem.uItemID == 630 ) //Red Apple
+      {
+          Party::GiveFood(1u);
+          pAudioPlayer->PlaySound(SOUND_EatApple, 0, 0, -1, 0, 0, 0, 0);
+      }
+      else if ( pParty->pPickedItem.uItemID == 632 ) //Lute
+      {
+        pAudioPlayer->PlaySound(SOUND_PlayLute,  0, 0, -1, 0, 0, 0, 0);
         return;
-
-        }
-
-    if ( pItemsTable->pItems[pParty->pPickedItem.uItemID].uEquipType == EQUIP_MESSAGE_SCROLL )
-
-        {
-        if ( pParty->pPlayers[player_num-1].CanAct() )
-            {
-            CreateMsgScrollWindow(pParty->pPickedItem.uItemID);
-            v3->PlaySound(SPEECH_37, 0);
-            return;
-            }
-        v68 = aCharacterConditionNames[v3->GetMajorConditionIdx()];
-        sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[382], v68);
+      }
+      else if ( pParty->pPickedItem.uItemID == 633 ) //Faerie Pipes
+      {
+        pAudioPlayer->PlaySound(SOUND_PlayFaeriePipes,  0, 0, -1, 0, 0, 0, 0);
+        return;
+      }
+      else if ( pParty->pPickedItem.uItemID == 634 ) //Gryphonheart's Trumpet
+      {
+        pAudioPlayer->PlaySound(SOUND_PlayGryphonheartsTrumpet,  0, 0, -1, 0, 0, 0, 0);
+        return;
+      }
+      else if ( pParty->pPickedItem.uItemID == 646 ) //Horseshoe
+      {
+        pGame->pStru6Instance->SetPlayerBuffAnim(SPELL_QUEST_COMPLETED, player_num - 1);
+        v5 = PID(OBJECT_Player, player_num + 49);
+        pAudioPlayer->PlaySound(SOUND_20001, v5, 0, -1, 0, 0, 0, 0);
+        playerAffected->AddVariable(VAR_NumSkillPoints, 2);
+      }
+      else if ( pParty->pPickedItem.uItemID == 650 ) //Temple in a Bottle
+      {
+        TeleportToNWCDungeon();
+        return;
+      }
+      else
+      {
+        v68 = pParty->pPickedItem.GetDisplayName();
+        sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[36],v68);//"%s can not be used that way"
         ShowStatusBarString(pTmpBuf.data(), 2u);
         pAudioPlayer->PlaySound((SoundID)27, 0, 0, -1, 0, 0, 0, 0);
         return;
-        }
-    else
-    {
-      if (pParty->pPickedItem.uItemID == 616) //Genie Lamp
-      {
-            thisa = pParty->uCurrentMonthWeek + 1;
-            if ( pParty->uCurrentMonth >= 7 )
-                v74 = NULL;
-            else
-                v74 = aAttributeNames[pParty->uCurrentMonth];
-            switch ( pParty->uCurrentMonth )
-                {
-            case 0:
-                v3->uMight += thisa;
-                sprintf(pTmpBuf.data(), "+%u %s %s", thisa, v74, pGlobalTXT_LocalizationStrings[121]);//"Permanent"	
-                break;
-            case 1:
-                v3->uIntelligence += thisa;
-                sprintf(pTmpBuf.data(), "+%u %s %s", thisa, v74, pGlobalTXT_LocalizationStrings[121]);//"Permanent"	
-                break;
-            case 2:
-                v3->uWillpower += thisa;
-                sprintf(pTmpBuf.data(), "+%u %s %s", thisa, v74, pGlobalTXT_LocalizationStrings[121]);//"Permanent"	
-                break;
-            case 3:
-                v3->uEndurance += thisa;
-                sprintf(pTmpBuf.data(), "+%u %s %s", thisa, v74, pGlobalTXT_LocalizationStrings[121]);//"Permanent"	
-                break;
-            case 4:
-                v3->uAccuracy += thisa;
-               sprintf(pTmpBuf.data(), "+%u %s %s", thisa, v74, pGlobalTXT_LocalizationStrings[121]);//"Permanent"	
-                break;
-            case 5:
-                v3->uSpeed += thisa;
-                sprintf(pTmpBuf.data(), "+%u %s %s", thisa, v74, pGlobalTXT_LocalizationStrings[121]);//"Permanent"	
-                break;
-            case 6:
-                v3->uLuck += thisa;
-               sprintf(pTmpBuf.data(), "+%u %s %s", thisa, v74, pGlobalTXT_LocalizationStrings[121]);//"Permanent"	
-                break;
-            case 7:
-                party_finds_gold(1000 * thisa, 0);
-                sprintf(pTmpBuf.data(), "+%u %s", 1000 * thisa, pGlobalTXT_LocalizationStrings[97]);//"Gold"
-                break;
-            case 8:
-                Party::GiveFood(5 * thisa); 
-                sprintf(pTmpBuf.data(), "+%u %s",5 * thisa , pGlobalTXT_LocalizationStrings[653]);//"Food"
-                break;
-            case 9u:
-                v3->uSkillPoints += 2 * thisa;
-                sprintf(pTmpBuf.data(), "+%u %s", 2 * thisa, pGlobalTXT_LocalizationStrings[LOCSTR_SKILL_POINTS]);
-                break;
-            case 10:
-                v3->uExperience += 2500 * thisa;
-                sprintf(pTmpBuf.data(), "+%u %s", 2500 * thisa, pGlobalTXT_LocalizationStrings[LOCSTR_EXPIRIENCE]);
-                break;
-            case 11:
-                v8 = rand() % 6;
-                switch (v8)
-                    {
-                case 0:
-                    v3->sResFireBase += thisa;
-                    v13 = pGlobalTXT_LocalizationStrings[87];
-                    break;
-                case 1:
-                    v3->sResAirBase += thisa;
-                    v13 = pGlobalTXT_LocalizationStrings[6];
-                    break;
-                case 2:
-                    v3->sResWaterBase += thisa;
-                    v13 = pGlobalTXT_LocalizationStrings[240];
-                    break;
-                case 3:
-                    v3->sResEarthBase += thisa;
-                    v13 = pGlobalTXT_LocalizationStrings[70];
-                    break;
-                case 4:
-                    v3->sResMindBase += thisa;
-                    v13 = pGlobalTXT_LocalizationStrings[142];
-                    break;
-                case 5:
-                    v3->sResBodyBase += thisa;
-                    v13 = pGlobalTXT_LocalizationStrings[29];
-                    break;
-                    }
-                sprintf(pTmpBuf.data(), "+%u %s %s", thisa, v13, pGlobalTXT_LocalizationStrings[121]);
-                break;
-
-                }
-            ShowStatusBarString(pTmpBuf.data(), 2u);
-            pMouse->RemoveHoldingItem();
-            pGame->pStru6Instance->SetPlayerBuffAnim(SPELL_QUEST_COMPLETED, player_num - 1);
-            v3->PlaySound(SPEECH_93, 0);
-            pAudioPlayer->PlaySound((SoundID)219, 0, 0, -1, 0, 0, 0, 0);
-            if ( pParty->uDaysPlayed == 6 || pParty->uDaysPlayed == 20 )
-                {
-                v3->SetCondition(Condition_Eradicated, 0);
-                pAudioPlayer->PlaySound((SoundID)215, 0, 0, -1, 0, 0, 0, 0);
-                }
-            else if ( pParty->uDaysPlayed == 12 || pParty->uDaysPlayed == 26 )
-                {
-                v3->SetCondition(Condition_Dead, 0);
-                pAudioPlayer->PlaySound((SoundID)215, 0, 0, -1, 0, 0, 0, 0);
-                }
-            else  if ( pParty->uDaysPlayed == 4 || pParty->uDaysPlayed == 25 )
-                {
-                v3->SetCondition(Condition_Pertified, 0);
-                pAudioPlayer->PlaySound((SoundID)215, 0, 0, -1, 0, 0, 0, 0);                 
-                }
-            return;
-            }
-        else if ( pParty->pPickedItem.uItemID == 630 ) //Red Apple
-        {
-            Party::GiveFood(1u);
-            pAudioPlayer->PlaySound(SOUND_EatApple, 0, 0, -1, 0, 0, 0, 0);
-        }
-        else if ( pParty->pPickedItem.uItemID == 632 ) //Lute
-                {
-                pAudioPlayer->PlaySound(SOUND_PlayLute,  0, 0, -1, 0, 0, 0, 0);
-                return;
-                }
-        else if ( pParty->pPickedItem.uItemID == 633 ) //Faerie Pipes
-                {
-                pAudioPlayer->PlaySound(SOUND_PlayFaeriePipes,  0, 0, -1, 0, 0, 0, 0);
-                return;
-                }
-        else if ( pParty->pPickedItem.uItemID == 634 ) //Gryphonheart's Trumpet
-                {
-                pAudioPlayer->PlaySound(SOUND_PlayGryphonheartsTrumpet,  0, 0, -1, 0, 0, 0, 0);
-                return;
-                }
-        else if ( pParty->pPickedItem.uItemID == 646 ) //Horseshoe
-        {
-                pGame->pStru6Instance->SetPlayerBuffAnim(SPELL_QUEST_COMPLETED, player_num - 1);
-                v5 = PID(OBJECT_Player, player_num + 49);
-                pAudioPlayer->PlaySound(SOUND_20001, v5, 0, -1, 0, 0, 0, 0);
-                v3->AddVariable(VAR_NumSkillPoints, 2);
-                }
-        else if ( pParty->pPickedItem.uItemID == 650 ) //Temple in a Bottle
-                    {
-                    TeleportToNWCDungeon();
-                    return;
-                    }
-        else
-                {
-   
-                v68 = pParty->pPickedItem.GetDisplayName();
-                sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[36],v68);//"%s can not be used that way"
-                ShowStatusBarString(pTmpBuf.data(), 2u);
-                pAudioPlayer->PlaySound((SoundID)27, 0, 0, -1, 0, 0, 0, 0);
-                return;
-                }
-
-        pMouse->RemoveHoldingItem();
-        return;
-        }
-
-    }
+      }
+
+      pMouse->RemoveHoldingItem();
+      return;
+  }
+}
 
 //----- (00449BB4) --------------------------------------------------------
 bool Player::CompareVariable( enum VariableType VarNum, signed int pValue )
@@ -6327,6 +5652,7 @@
       {
         if ( (signed int)var_type >= 0xF5 )
         {
+          __debugbreak(); //how do I get here?
           *(int *)&stru_AA1058[3].pSounds[8 * var_type + 44300] = LODWORD(pParty->uTimePlayed);
           *(int *)&stru_AA1058[3].pSounds[8 * var_type + 44304] = HIDWORD(pParty->uTimePlayed);
         }
@@ -6335,9 +5661,11 @@
           switch ( var_type )
           {
             case VAR_MonthEquals|VAR_CurrentSP:
+              __debugbreak(); //how do I get here?
               _449B7E_toggle_bit((unsigned char *)field_1A50, var_value, 1u);
               break;
             case VAR_NPCs2:
+              __debugbreak(); //how do I get here?
               pParty->field_709 = 0;
               LOBYTE(pNPCStats->pNewNPCData[var_value].uFlags) |= 0x80u;
               pParty->CountHirelings();
@@ -6354,6 +5682,7 @@
         return;
       if ( (signed int)var_type <= 0x112 )
       {
+        __debugbreak(); //how do I get here?
         *(int *)&stru_AA1058[3].pSounds[8 * var_type + 44532] = LODWORD(pParty->uTimePlayed);
         *(int *)&stru_AA1058[3].pSounds[8 * var_type + 44536] = HIDWORD(pParty->uTimePlayed);
       }
@@ -6376,6 +5705,7 @@
               v23 = pStorylineText->StoreLine[v22].pText == 0,//*(&pStorylineText->field_0 + 3 * v22) == 0,
               pParty->field_3C.field_4F0[2 * (var_type - 276) + 1] = HIDWORD(pParty->uTimePlayed),
               v23) )
+              __debugbreak(); //how do I get here?
           return;
         bFlashHistoryBook = 1;
       }
@@ -7999,35 +7329,27 @@
 //----- (00467E7F) --------------------------------------------------------
 void Player::EquipBody(ITEM_EQUIP_TYPE uEquipType)
 {
-  //unsigned int v1; // esi@1
   int v2; // ebx@1
   Player *v3; // eax@1
   int v4; // edx@1
-  int v5; // esi@2
-  //int v6; // eax@2
   int v7; // eax@3
-  ItemGen _this; // [sp+Ch] [bp-30h]@1
-  //Player *v9; // [sp+30h] [bp-Ch]@1
-  int v10; // [sp+34h] [bp-8h]@1
-  int *v11; // [sp+38h] [bp-4h]@1
-
-
-  _this.Reset();
+  ItemGen tempPickedItem; // [sp+Ch] [bp-30h]@1
+  unsigned int *v11; // [sp+38h] [bp-4h]@1
+
+  tempPickedItem.Reset();
   v2 = pEquipTypeToBodyAnchor[uEquipType];
   v3 = pPlayers[uActiveCharacter];
-  v11 = (int *)&v3->pEquipment.pIndices[v2];
+  v11 = &v3->pEquipment.pIndices[v2];
   v4 = *v11;
-  v10 = *v11;
-  if ( v10 )
-  {
-    memcpy(&_this, &pParty->pPickedItem, sizeof(_this));
-    v5 = (int)((char *)v3 + 4 * (9 * v4 - 9));
-    *(char *)(v5 + 556) = 0;
+  if ( v4 )
+  {
+    memcpy(&tempPickedItem, &pParty->pPickedItem, sizeof(tempPickedItem));
+    v3->pInventoryItemList[v4 - 1].uBodyAnchor = 0;
     pParty->pPickedItem.Reset();
-    pParty->SetHoldingItem((ItemGen *)(v5 + 532));
-    _this.uBodyAnchor = v2 + 1;
-    memcpy((void *)(v5 + 532), &_this, 0x24u);
-    *v11 = v10;
+    pParty->SetHoldingItem(&v3->pInventoryItemList[v4 - 1]);
+    tempPickedItem.uBodyAnchor = v2 + 1;
+    memcpy(&v3->pInventoryItemList[v4 - 1], &tempPickedItem, sizeof(ItemGen));
+    *v11 = v4;
   }
   else
   {
@@ -8035,7 +7357,7 @@
     if (v7 >= 0)
     {
       pParty->pPickedItem.uBodyAnchor = v2 + 1;
-      memcpy(&v3->pInventoryItemList[v7], &pParty->pPickedItem, sizeof(v3->pInventoryItemList[v7]));
+      memcpy(&v3->pInventoryItemList[v7], &pParty->pPickedItem, sizeof(ItemGen));
       *v11 = v7 + 1;
       pMouse->RemoveHoldingItem();
     }
@@ -8046,98 +7368,49 @@
 //----- (0049387A) --------------------------------------------------------
 int CycleCharacter(bool backwards)
 {
-  signed int result; // eax@1
-  signed int v2; // ecx@2
-  signed int v3; // ecx@8
-
-  result = uActiveCharacter;
-  if ( backwards )
-  {
-    v2 = 0;
-    while ( 1 )
-    {
-      --result;
-      if ( result < 1 )
-        result = 4;
-      if ( !pPlayers[result]->uTimeToRecovery )
-        break;
-      ++v2;
-      if ( v2 >= 4 )
-        return uActiveCharacter;
-    }
-  }
-  else
-  {
-    v3 = 0;
-    while ( 1 )
-    {
-      ++result;
-      if ( result > 4 )
-        result = 1;
-      if ( !pPlayers[result]->uTimeToRecovery )
-        break;
-      ++v3;
-      if ( v3 >= 4 )
-        return uActiveCharacter;
-    }
-  }
-  return result;
-}
+  const int PARTYSIZE = 4;
+  int valToAdd = backwards ? (PARTYSIZE - 2) : 0;
+  int mult = backwards ? -1 : 1;
+
+  for (int i = 0; i < (PARTYSIZE - 1); i++)
+  {
+    int currCharId = ((uActiveCharacter + mult * i + valToAdd) % PARTYSIZE) + 1;
+    if ( pPlayers[currCharId]->uTimeToRecovery == 0 )
+    {
+      return currCharId;
+    }
+  }
+  return uActiveCharacter;
+}
+
 //----- (0043EE77) --------------------------------------------------------
-bool __fastcall sub_43EE77_ProbablyIfUnderwaterSuitIsEquipped(signed int a1)
-{
-  bool result; // eax@0
-  Player *v2; // edx@3
-  int v3; // ecx@3
-  Player **pPlayers; // esi@8
-  //bool item_flag;
-  Player *v6; // edx@9
-
-  //if ( a1 < 1 || a1 > 4 )
-  //{
-    //if ( !a1 )
-    //{
-      //pPlayers = &::pPlayers[1];
-      //v5 = 604;
-      //while ( 1 )
-  Assert ( a1 > 0 && a1 < 5 );
-      for ( uint i = 1; i < 5; ++i )
-      {
-        //item_flag = Player_has_item(604, *pPlayers, 0);
-        if ( !Player_has_item(604, ::pPlayers[i], 0) )
-          return false;
-        //__debugbreak(); // player.cpp(8748): warning C4700: uninitialized local variable 'v6' used
-        //result = ::pPlayers[i]->pEquipment.uArmor;
-        if ( !::pPlayers[i]->pEquipment.uArmor )
-          return false;
-        //result *= 9;
-        if (::pPlayers[i]->pEquippedItems[::pPlayers[i]->pEquipment.uArmor].uItemID != 604 )
-          return false;
-        //++pPlayers;
-        //if ( (signed int)pPlayers >= (signed int)&qword_A750D8 )
-          //return true;
-      }
-      return true;
-    }
+bool Player::HasUnderwaterSuitEquipped() //the original function took the player number as a parameter. if it was 0, the whole party was checked. calls with the parameter 0 have been changed to calls to this for every player
+{
+  if (this->pEquipment.uArmor == 0 || this->pInventoryItemList[this->pEquipment.uArmor].uItemID != 604)
+  {
+    return false;
+  }
+  return true;
+}
 
 //----- (0043EE15) --------------------------------------------------------
-bool __fastcall Player_has_item(unsigned int uItemID, Player *pPlayer, char a3)
+bool Player::HasItem( unsigned int uItemID, char a3 )
 {
   if ( !a3 || pParty->pPickedItem.uItemID != uItemID )
   {
     for ( uint i = 0; i < 126; ++i )
     {
-      if ( pPlayer->pInventoryMatrix[i] > 0 )
+      if ( this->pInventoryMatrix[i] > 0 )
       {
-        if ( (unsigned int)pPlayer->pInventoryItemList[pPlayer->pInventoryMatrix[i] - 1].uItemID == uItemID )
+        if ( (unsigned int)this->pInventoryItemList[this->pInventoryMatrix[i] - 1].uItemID == uItemID )
           return true;
       }
     }
     for ( uint i = 0; i < 16; ++i )
     {
-      if ( pPlayer->pEquipment.pIndices[i] )
+      if ( this->pEquipment.pIndices[i] )
       {
-        if ( (unsigned int)pPlayer->pInventoryItemList[pPlayer->pEquipment.pIndices[i] - 1].uItemID == uItemID )
+        if ( (unsigned int)this->pInventoryItemList[this->pEquipment.pIndices[i] - 1].uItemID == uItemID )
           return true;
       }
     }
@@ -8145,64 +7418,36 @@
   return false;
 }
 //----- (0043EDB9) --------------------------------------------------------
-bool  sub_43EDB9_get_some_race_sex_relation_2(unsigned int a1)
-{
-  unsigned int pNum; // ebp@1
-  Player **pPlayer; // ebx@1
-  Player *pPlayer2; // esi@2
-  enum CHARACTER_RACE pRace; // edi@2
-  bool pSex; // eax@2
-  char v6; // zf@7
-
-//pPlayer = &pPlayers[1];
-  /*pNum = a1;
-  
-  while ( 1 )
-  {
-    pPlayer2 = *pPlayer;
-    pRace = pPlayer2->GetRace();
-    pSex = pPlayer2->GetSexByVoice();
-    if ( !pRace )
-      break;
-    if ( pRace == 1 || pRace == 2 )
-      break;
-    if ( !pSex && pNum == 2 )//
-      //goto LABEL_15;
-    {
-      pSex = 1;
-      return pSex;
-    }
-    v6 = pNum == 3;//
-LABEL_11:
-    if ( v6 )
-      //goto LABEL_15;
-    {
-      pSex = 1;
-      return pSex;
-    }
-    ++pPlayer;
-    if ( (signed int)pPlayer >= (signed int)&qword_A750D8 )//
-    {
-      pSex = 0;
-      return pSex;
-    }
-  }
-  if ( pSex || pNum )
-  {
-    v6 = pNum == 1;
-    goto LABEL_11;
-  }
-//LABEL_15:
-  pSex = 1;
-  return pSex;*/
-  for (uint i = 1; i <= 4; ++i)
-    {
-      pRace = pPlayers[i]->GetRace();
-      pSex = pPlayers[i]->GetSexByVoice();
-      if (pRace == 0 || pRace == 1 || pRace == 2 || pSex == 0 )
-        return 1;
-    }
- return 0;
+bool ShouldLoadTexturesForRaceAndGender(unsigned int _this)
+{
+  CHARACTER_RACE race; // edi@2
+  PLAYER_SEX sex; // eax@2
+
+  for (int i = 1; i <= 4; i++)
+  {
+    race = pPlayers[i]->GetRace();
+    sex = pPlayers[i]->GetSexByVoice();
+    switch(_this)
+    {
+       case 0:
+         if (( race == CHARACTER_RACE_HUMAN || race == CHARACTER_RACE_ELF || race == CHARACTER_RACE_GOBLIN ) && sex == SEX_MALE )
+           return true;
+         break;
+       case 1:
+         if (( race == CHARACTER_RACE_HUMAN || race == CHARACTER_RACE_ELF || race == CHARACTER_RACE_GOBLIN ) && sex == SEX_FEMALE )
+           return true;
+         break;
+       case 2:
+         if ( race == CHARACTER_RACE_DWARF && sex == SEX_MALE )
+           return true;
+         break;
+       case 3:
+         if ( race == CHARACTER_RACE_DWARF && sex == SEX_FEMALE )
+           return true;
+         break;
+    }
+  }
+  return false;
 }
 //----- (0043ED6F) --------------------------------------------------------
 bool _43ED6F_check_party_races(bool a1)
@@ -8991,4 +8236,4 @@
 void Player::SetCondUnconsciousWithBlockCheck( int blockable )
 {
   SetCondition(Condition_Dead, blockable);
-}
\ No newline at end of file
+}
--- a/Player.h	Tue Sep 17 12:37:07 2013 +0200
+++ b/Player.h	Tue Sep 17 12:40:37 2013 +0200
@@ -5,17 +5,32 @@
 
 
 
-
-#define PLAYER_BUFF_BLESS            1
-#define PLAYER_BUFF_FATE             4
-#define PLAYER_BUFF_HAMMERHANDS      6
-#define PLAYER_BUFF_7                7
-#define PLAYER_BUFF_8                8
-#define PLAYER_BUFF_PAIN_REFLECTION 10
-#define PLAYER_BUFF_PRESERVATION    11
-#define PLAYER_BUFF_REGENERATION    12
-#define PLAYER_BUFF_13              13
-#define PLAYER_BUFF_14              14
+enum PLAYER_BUFFS
+{
+  PLAYER_BUFF_RESIST_AIR       = 0,
+  PLAYER_BUFF_BLESS            = 1,
+  PLAYER_BUFF_RESIST_BODY      = 2,
+  PLAYER_BUFF_RESIST_EARTH     = 3,
+  PLAYER_BUFF_FATE             = 4,
+  PLAYER_BUFF_RESIST_FIRE      = 3,
+  PLAYER_BUFF_HAMMERHANDS      = 6,
+  PLAYER_BUFF_HASTE            = 7,
+  PLAYER_BUFF_HEROISM          = 8,
+  PLAYER_BUFF_RESIST_MIND      = 9,
+  PLAYER_BUFF_PAIN_REFLECTION = 10,
+  PLAYER_BUFF_PRESERVATION    = 11,
+  PLAYER_BUFF_REGENERATION    = 12,
+  PLAYER_BUFF_13              = 13,
+  PLAYER_BUFF_STONESKIN       = 14,
+  PLAYER_BUFF_ACCURACY        = 15,
+  PLAYER_BUFF_ENDURANCE       = 16,
+  PLAYER_BUFF_INTELLIGENCE    = 17,
+  PLAYER_BUFF_LUCK            = 18,
+  PLAYER_BUFF_STRENGTH        = 19,
+  PLAYER_BUFF_WILLPOWER       = 20,
+  PLAYER_BUFF_SPEED           = 21,
+  PLAYER_BUFF_RESIST_WATER    = 22
+};
 
 
 #define PLAYER_GUILD_BITS__SPIRIT_MEMBERSHIP 58
@@ -518,8 +533,8 @@
   void RandomizeName();
   unsigned int GetMajorConditionIdx();
   int GetParameterBonus(int player_parameter);
-  int _48EA46_calc_special_bonus_by_items(int a2);
-  int GetItemsBonus(enum CHARACTER_ATTRIBUTE_TYPE attr, int a3);
+  int GetSpecialItemBonus(int enchantmentId);
+  int GetItemsBonus(enum CHARACTER_ATTRIBUTE_TYPE attr, bool a3 = false);
   int GetMagicalBonus(enum CHARACTER_ATTRIBUTE_TYPE a2);
   int GetActualSkillLevel(PLAYER_SKILL_TYPE uSkillType);
   int GetSkillBonus(enum CHARACTER_ATTRIBUTE_TYPE a2);
@@ -580,10 +595,13 @@
   void PlaySoundBasedOnCondition(int currPlayerId);
   void DrawPlayerBuffAnimBasedOnCondition(int currPlayerId);
   void EquipBody(ITEM_EQUIP_TYPE uEquipType);
+  bool HasUnderwaterSuitEquipped();
+  bool HasItem(unsigned int uItemID, char a3);
 
   unsigned int GetMultiplierForSkillLevel(unsigned int skillValue, int mult1, int mult2, int mult3, int mult4);
   int CalculateMeleeDmgToEnemyWithWeapon( ItemGen * weapon, unsigned int uTargetActorID , bool addOneDice);
   bool WearsItemAnyWhere(int item_id);
+  float GetArmorRecoveryMultiplierFromSkillLevel( unsigned char armour_skill_type, float param2, float param3, float param4, float param5 );
 
   bool IsWeak();
   bool IsDead();
--- a/Render.cpp	Tue Sep 17 12:37:07 2013 +0200
+++ b/Render.cpp	Tue Sep 17 12:40:37 2013 +0200
@@ -8470,7 +8470,7 @@
     {
       InvalidateRect(0, 0, 0);
       MoveWindow(hWnd, uWindowX, uWindowY, uWindowWidth, uWindowHeight, 0);
-      ShowWindow(hWnd, 1);
+      ShowWindow(hWnd, SW_SHOWNORMAL);
     }
     pMouse->bActive = 1;
     if ( pVideoPlayer->AnyMovieLoaded() )
--- a/UI/UICharacter.cpp	Tue Sep 17 12:37:07 2013 +0200
+++ b/UI/UICharacter.cpp	Tue Sep 17 12:40:37 2013 +0200
@@ -1698,7 +1698,7 @@
   uTextureID_detaliz_close_button = uExitCancelTextureId;
   for ( uint i = 0; i < 4; ++i )
   {
-    if ( sub_43EE77_ProbablyIfUnderwaterSuitIsEquipped(i + 1) )
+    if ( pPlayers[i + 1]->HasUnderwaterSuitEquipped() )
     {
       if ( pPlayers[i + 1]->GetRace() == CHARACTER_RACE_DWARF )
         v3 = (pPlayers[i + 1]->GetSexByVoice() != 0) + 3;
@@ -1757,7 +1757,7 @@
     {
       for ( uint j = 0; j < 4; ++j)
       {
-        if ( Player_has_item(i + 66, &pParty->pPlayers[j], 0) )
+        if ( pParty->pPlayers[j].HasItem(i + 66, 0) )
           party_has_equipment[i] = 1;
       }
     }
@@ -1767,23 +1767,23 @@
   {
     auto player = pParty->pPlayers + i;
 
-    if (Player_has_item(ITEM_ARTICACT_GOVERNONS_ARMOR, player, 1))    byte_5111F6[0] = 1;
-    if (Player_has_item(ITEM_ARTIFACT_YORUBA, player, 1))             byte_5111F6[1] = 1;
-    if (Player_has_item(ITEM_RELIC_HARECS_LEATHER, player, 1))        byte_5111F6[2] = 1;
-    if (Player_has_item(ITEM_ARTIFACT_LEAGUE_BOOTS, player, 1))       byte_5111F6[3] = 1;
-    if (Player_has_item(ITEM_RELIC_TALEDONS_HELM, player, 1))         byte_5111F6[4] = 1;
-    if (Player_has_item(ITEM_RELIC_SCHOLARS_CAP, player, 1))          byte_5111F6[5] = 1;
-    if (Player_has_item(ITEM_RELIC_PHYNAXIAN_CROWN, player, 1))       byte_5111F6[6] = 1;
-    if (Player_has_item(ITEM_ARTIFACT_MINDS_EYE, player, 1))          byte_5111F6[7] = 1;
-    if (Player_has_item(ITEM_RARE_SHADOWS_MASK, player, 1))           byte_5111F6[8] = 1;
-    if (Player_has_item(ITEM_RILIC_TITANS_BELT, player, 1))           byte_5111F6[9] = 1;
-    if (Player_has_item(ITEM_ARTIFACT_HEROS_BELT, player, 1))         byte_5111F6[10] = 1;
-    if (Player_has_item(ITEM_RELIC_TWILIGHT, player, 1))              byte_5111F6[11] = 1;
-    if (Player_has_item(ITEM_ARTIFACT_CLOAK_OF_THE_SHEEP, player, 1)) byte_5111F6[12] = 1;
-    if (Player_has_item(ITEM_RARE_SUN_CLOAK, player, 1))              byte_5111F6[13] = 1;
-    if (Player_has_item(ITEM_RARE_MOON_CLOAK, player, 1))             byte_5111F6[14] = 1;
-    if (Player_has_item(ITEM_RARE_VAMPIRES_CAPE, player, 1))          byte_5111F6[15] = 1;
-    if (Player_has_item(ITEM_ELVEN_CHAINMAIL, player, 1))             byte_5111F6[16] = 1;
+    if (player->HasItem(ITEM_ARTICACT_GOVERNONS_ARMOR, 1))    byte_5111F6[0] = 1;
+    if (player->HasItem(ITEM_ARTIFACT_YORUBA, 1))             byte_5111F6[1] = 1;
+    if (player->HasItem(ITEM_RELIC_HARECS_LEATHER, 1))        byte_5111F6[2] = 1;
+    if (player->HasItem(ITEM_ARTIFACT_LEAGUE_BOOTS, 1))       byte_5111F6[3] = 1;
+    if (player->HasItem(ITEM_RELIC_TALEDONS_HELM, 1))         byte_5111F6[4] = 1;
+    if (player->HasItem(ITEM_RELIC_SCHOLARS_CAP, 1))          byte_5111F6[5] = 1;
+    if (player->HasItem(ITEM_RELIC_PHYNAXIAN_CROWN, 1))       byte_5111F6[6] = 1;
+    if (player->HasItem(ITEM_ARTIFACT_MINDS_EYE, 1))          byte_5111F6[7] = 1;
+    if (player->HasItem(ITEM_RARE_SHADOWS_MASK, 1))           byte_5111F6[8] = 1;
+    if (player->HasItem(ITEM_RILIC_TITANS_BELT, 1))           byte_5111F6[9] = 1;
+    if (player->HasItem(ITEM_ARTIFACT_HEROS_BELT, 1))         byte_5111F6[10] = 1;
+    if (player->HasItem(ITEM_RELIC_TWILIGHT, 1))              byte_5111F6[11] = 1;
+    if (player->HasItem(ITEM_ARTIFACT_CLOAK_OF_THE_SHEEP, 1)) byte_5111F6[12] = 1;
+    if (player->HasItem(ITEM_RARE_SUN_CLOAK, 1))              byte_5111F6[13] = 1;
+    if (player->HasItem(ITEM_RARE_MOON_CLOAK, 1))             byte_5111F6[14] = 1;
+    if (player->HasItem(ITEM_RARE_VAMPIRES_CAPE, 1))          byte_5111F6[15] = 1;
+    if (player->HasItem(ITEM_ELVEN_CHAINMAIL, 1))             byte_5111F6[16] = 1;
   }
 
   for (uint i = 0; i < 2; ++i)
@@ -1816,7 +1816,7 @@
   //v43 = 0;
   for (uint i = 0; i < 4; ++i)
   {
-    if ( sub_43EDB9_get_some_race_sex_relation_2(i) )
+    if ( ShouldLoadTexturesForRaceAndGender(i) )
     {
       GetItemTextureFilename(pContainer, 524, i + 1, 0);
       paperdoll_belt_texture[i][5] = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);//Titans belt
@@ -2404,7 +2404,7 @@
           pPlayers[uActiveCharacter]->PlaySound(SPEECH_39, 0);
           return;
         }
-        if ( sub_43EE77_ProbablyIfUnderwaterSuitIsEquipped(uActiveCharacter) && (pEquipType != EQUIP_ARMOUR || bUnderwater) )
+        if ( pPlayers[uActiveCharacter]->HasUnderwaterSuitEquipped() && (pEquipType != EQUIP_ARMOUR || bUnderwater) )
         {
           pAudioPlayer->PlaySound(SOUND_27, 0, 0, -1, 0, 0, 0, 0);
           return;
@@ -2415,7 +2415,7 @@
         return;
 //------------------------dress rings(одевание колец)----------------------------------
       case EQUIP_RING:
-        if ( sub_43EE77_ProbablyIfUnderwaterSuitIsEquipped(uActiveCharacter) )
+        if ( pPlayers[uActiveCharacter]->HasUnderwaterSuitEquipped() )
         {
           pAudioPlayer->PlaySound(SOUND_27, 0, 0, -1, 0, 0, 0, 0);
           return;
@@ -2452,7 +2452,7 @@
         return;
 //------------------dress shield(одеть щит)------------------------------------------------------
       case EQUIP_SHIELD://Щит
-        if ( sub_43EE77_ProbablyIfUnderwaterSuitIsEquipped(uActiveCharacter) )//в акваланге
+        if ( pPlayers[uActiveCharacter]->HasUnderwaterSuitEquipped() )//в акваланге
         {
           pAudioPlayer->PlaySound(SOUND_27, 0, 0, -1, 0, 0, 0, 0);
           return;
@@ -2503,7 +2503,7 @@
 //-------------------------taken in hand(взять в руку)-------------------------------------------
       case EQUIP_OFF_HAND:
       case EQUIP_WAND:
-        if ( sub_43EE77_ProbablyIfUnderwaterSuitIsEquipped(uActiveCharacter)
+        if ( pPlayers[uActiveCharacter]->HasUnderwaterSuitEquipped()
           && pParty->pPickedItem.uItemID != 64
           && pParty->pPickedItem.uItemID != 65 )
         {
@@ -2607,7 +2607,7 @@
         break;
 //---------------------------take two hands(взять двумя руками)---------------------------------
       case EQUIP_MAIN_HAND:
-        if ( sub_43EE77_ProbablyIfUnderwaterSuitIsEquipped(uActiveCharacter) )
+        if ( pPlayers[uActiveCharacter]->HasUnderwaterSuitEquipped() )
         {
           pAudioPlayer->PlaySound(SOUND_27, 0, 0, -1, 0, 0, 0, 0);
           return;
--- a/UI/UIHouses.cpp	Tue Sep 17 12:37:07 2013 +0200
+++ b/UI/UIHouses.cpp	Tue Sep 17 12:40:37 2013 +0200
@@ -89,21 +89,21 @@
 {
   {  0,   1,   1,  34},  // HOUSE_STABLES_HARMONDALE
   {  2,   3,   4,   5},  // HOUSE_STABLES_STEADWICK
-  {  6,   7,   8,   8},  // HOUSE_STABLES_56
-  {  9,  10,  10,  10},  // HOUSE_STABLES_57
-  { 11,  11,  12,  12},  // HOUSE_STABLES_58
-  { 13,  13,  13,  13},  // HOUSE_STABLES_59
-  { 14,  14,  15,  15},  // HOUSE_STABLES_60
+  {  6,   7,   8,   8},  // HOUSE_STABLES_TULAREAN_FOREST
+  {  9,  10,  10,  10},  // HOUSE_STABLES_DEYJA
+  { 11,  11,  12,  12},  // HOUSE_STABLES_BRACADA_DESERT
+  { 13,  13,  13,  13},  // HOUSE_STABLES_TATALIA
+  { 14,  14,  15,  15},  // HOUSE_STABLES_AVLEE
   {255, 255, 255, 255},  // HOUSE_STABLES_61
   {255, 255, 255, 255},  // HOUSE_STABLES_62
-  {255, 255, 255, 255},  // HOUSE_BOATS_63
-  { 16,  17,  18,  19},  // HOUSE_BOATS_64
-  { 18,  20,  21,  21},  // HOUSE_BOATS_65
-  { 22,  23,  24,  25},  // HOUSE_BOATS_66
-  { 22,  22,  23,  23},  // HOUSE_BOATS_67
+  {255, 255, 255, 255},  // HOUSE_BOATS_EMERALD_ISLE
+  { 16,  17,  18,  19},  // HOUSE_BOATS_ERATHIA
+  { 18,  20,  21,  21},  // HOUSE_BOATS_TULAREAN_FOREST
+  { 22,  23,  24,  25},  // HOUSE_BOATS_BRACADA_DESERT
+  { 22,  22,  23,  23},  // HOUSE_BOATS_EVENMORN_ISLAND
   {255, 255, 255, 255},  // HOUSE_BOATS_68
-  { 27,  28,  29,  30},  // HOUSE_BOATS_69
-  { 31,  32,  33,  33},  // HOUSE_BOATS_70
+  { 27,  28,  29,  30},  // HOUSE_BOATS_TATALIA
+  { 31,  32,  33,  33},  // HOUSE_BOATS_AVLEE
   { 24,  24,  24,  24},  // HOUSE_BOATS_71
   {255, 255, 255, 255},  // HOUSE_BOATS_72
   {255, 255, 255, 255}   // HOUSE_BOATS_73
@@ -989,7 +989,6 @@
 {
   int experience_for_next_level; // eax@5
   GUIWindow *v8; // esi@10
-  //int v11; // edi@31
   int v16; // eax@32
   int v17; // eax@33
   int v18; // eax@34
@@ -1910,283 +1909,192 @@
 //----- (004B6943) --------------------------------------------------------
 void  TravelByTransport()
 {
-  GUIWindow *v0; // ebx@1
-  Player *v1; // esi@1
-  signed int v2; // edi@1
-  unsigned int v3; // eax@1
   signed int v4; // ebx@1
-  stru365_travel_info *v5; // esi@7
-  int v11; // ecx@12
+  stru365_travel_info *pTravel; // esi@7
   signed int v12; // esi@13
   signed int v13; // edi@14
   DWORD v14; // eax@26
   DWORD v15; // edi@26
-  GUIWindow *v16; // ebx@36
-  int v17; // esi@36
-  int v18; // eax@36
-  int v19; // ecx@36
-  int v20; // esi@36
-  int v21; // eax@36
-  void *v22; // eax@39
-  int v23; // esi@39
-  GUIButton *v24; // ebx@39
+  int pTextHeight; // eax@36
+  int pRealTextHeight; // esi@36
+  int schedule_id; // esi@39
+  GUIButton *pButton; // ebx@39
   signed int v25; // eax@41
-  //int v26; // esi@44
-  //const char *v27; // eax@46
-  char *v28; // eax@62
-  int v29; // eax@62
-  unsigned int v30; // ecx@62
-  char *v31; // eax@63
-  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
-  int v37; // [sp-28h] [bp-2B8h]@62
-  int v38; // [sp-24h] [bp-2B4h]@62
-  int v39; // [sp-20h] [bp-2B0h]@62
-  int v40; // [sp-1Ch] [bp-2ACh]@62
-  int v41; // [sp-18h] [bp-2A8h]@62
-  int v42; // [sp-14h] [bp-2A4h]@62
-  char *v43; // [sp-10h] [bp-2A0h]@62
-  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[5][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
-  //int v57; // [sp+268h] [bp-28h]@1
-  int v58; // [sp+26Ch] [bp-24h]@36
-  //GUIWindow *v59; // [sp+270h] [bp-20h]@1
-  unsigned int v60; // [sp+274h] [bp-1Ch]@36
-  //Player *v61; // [sp+278h] [bp-18h]@1
-  int v62; // [sp+27Ch] [bp-14h]@36
-  int v63; // [sp+280h] [bp-10h]@14
-  char *a1; // [sp+284h] [bp-Ch]@37
-  unsigned int s1; // [sp+288h] [bp-8h]@1
-  int v66; // [sp+28Ch] [bp-4h]@48
+  MapInfo pMap; // [sp-3Ch] [bp-2CCh]@62
+  char pTopicArray[5][100]; // [sp+14h] [bp-27Ch]@37
+  GUIWindow travel_window; // [sp+208h] [bp-88h]@1
+  int pPrimaryTextHeight; // [sp+260h] [bp-30h]@36
+  int index; // [sp+27Ch] [bp-14h]@36
+  unsigned int pPrice; // [sp+288h] [bp-8h]@1
+  int travel_time; // [sp+28Ch] [bp-4h]@48
+  enum PlayerSpeech pSpeech;
+  unsigned int pCurrentButton;
 
-  v0 = window_SpeakInHouse;
-  memcpy(&v53, window_SpeakInHouse, sizeof(v53));
-  v2 = 255;
-  //v61 = pPlayers[uActiveCharacter];
-  v1 = pPlayers[uActiveCharacter];
-  v53.uFrameX = 483;
-  v53.uFrameWidth = 148;
-  v53.uFrameZ = 334;
-  auto color_default = TargetColor(255, 255, 255);
-  auto color_selected = TargetColor(255, 255, 155);
-  v3 = 52 * (unsigned int)v0->ptr_1C;
-  //v59 = (GUIWindow *)((((p2DEvents_minus1___00[v3 / 2] != 27) - 1) & 0xFFFFFFE7) + 50);
-  //v59 = (GUIWindow *)((((p2DEvents[(unsigned int)v0->ptr_1C - 1].uType != BuildingType_Stables) - 1) & 0xFFFFFFE7) + 50);
-  //v4 = (signed __int64)((double)(signed int)v59 * p2DEvents_minus1__20[v3 / 4]);
+  memcpy(&travel_window, window_SpeakInHouse, sizeof(travel_window));
+  travel_window.uFrameX = 483;
+  travel_window.uFrameWidth = 148;
+  travel_window.uFrameZ = 334;
 
-  v4 = p2DEvents[(unsigned int)v0->ptr_1C - 1].uType == BuildingType_Stables ? 25 : 50;
-  v4 *= p2DEvents[(unsigned int)v0->ptr_1C - 1].fPriceMultiplier;
+  v4 = p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].uType == BuildingType_Stables ? 25 : 50;
+  v4 *= p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].fPriceMultiplier;
 
-  s1 = v4 * (100 - v1->GetMerchant()) / 100;
-  if ( (signed int)s1 < v4 / 3 )
-    s1 = v4 / 3;
+  pPrice = v4 * (100 - pPlayers[uActiveCharacter]->GetMerchant()) / 100;
+  if ( (signed int)pPrice < v4 / 3 )
+    pPrice = v4 / 3;
   if ( dialog_menu_id == HOUSE_DIALOGUE_MAIN)
   {
     if ( HouseUI_CheckIfPlayerCanInteract() )
     {
-      v16 = pDialogueWindow;
-      v58 = 255;
-      v62 = 0;
-      v17 = LOBYTE(pFontArrus->uFontHeight) - 3;
-      //v59 = pDialogueWindow;
-      v54 = v17;
-      strcpy(v48[4], "");
-      sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[405], s1); // Price: %lu gold
-      v18 = pFontArrus->CalcTextHeight(pTmpBuf2.data(), &v53, 0, 0);
-      v19 = v16->pNumPresenceButton;
-      v20 = v18 + v17 + 146;
-      v21 = v16->pStartingPosActiveItem;
-      v63 = v20;
-      v55 = v20;
-      v60 = v21;
-      if ( v21 >= v21 + v19 )
-        goto LABEL_71;
-      s1 = 2;
-      a1 = (char *)v48;
-      while ( 1 )
+      index = 0;
+      strcpy(pTopicArray[4], "");
+      sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[405], pPrice); // Price: %lu gold
+      pTextHeight = pFontArrus->CalcTextHeight(pTmpBuf2.data(), &travel_window, 0, 0);
+      pRealTextHeight = pTextHeight + (LOBYTE(pFontArrus->uFontHeight) - 3) + 146;
+      pPrimaryTextHeight = pRealTextHeight;
+      pCurrentButton = 2;
+      for ( uint i = pDialogueWindow->pStartingPosActiveItem; i < (unsigned int)(pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem); ++i )
       {
-        int v47 = v60;
-        v22 = window_SpeakInHouse->ptr_1C;
-        v23 = transport_routes[(unsigned int)v22 - HOUSE_STABLES_HARMONDALE][v62];
-        //v23 = (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);
+        schedule_id = transport_routes[(unsigned int)window_SpeakInHouse->ptr_1C - HOUSE_STABLES_HARMONDALE][index];
+        pButton = pDialogueWindow->GetControl(i);
 
-        if (v23 != v58)
+        if (schedule_id != 255)
         {
-          if (v23 >= 25)
-            Log::Warning(L"Transport UI: scedule overflow");
-          if (s1 >= 6)
+          //if (schedule_id >= 25)
+            //Log::Warning(L"Transport UI: schedule overflow");
+          if ( pCurrentButton >= 6 )
             v25 = true;
           else
-            v25 = transport_schedule[v23].pSchedule[pParty->uDaysPlayed % 7];
+            v25 = transport_schedule[schedule_id].pSchedule[pParty->uDaysPlayed % 7];
         }
 
-        if (v23 != v58 && v25 && (!transport_schedule[v23].uQuestBit || _449B57_test_bit(pParty->_quest_bits, transport_schedule[v23].uQuestBit)) )
+        if (schedule_id != 255 && v25 && (!transport_schedule[schedule_id].uQuestBit
+           || _449B57_test_bit(pParty->_quest_bits, transport_schedule[schedule_id].uQuestBit)) )//ошибка: рисуется несколько строчек одного направления путешествия
         {
-            v58 = v23;
-            if ( pDialogueWindow->pCurrentPosActiveItem == s1 )
-              sprintf(a1, "\f%05d", color_selected);
-            else
-              sprintf(a1, "\f%05d", color_default);
-
-          //v32.uRedbookTrackID = v27;
-          v66 = transport_schedule[v23].uTravelTime;
-          if ( (unsigned int)window_SpeakInHouse->ptr_1C >= HOUSE_BOATS_63 )
+  //get color for current string(определение цвета текущей строки)----------
+          if ( pDialogueWindow->pCurrentPosActiveItem == pCurrentButton )
+            sprintf(pTopicArray[index], "\f%05d", TargetColor(255, 255, 155));
+          else
+            sprintf(pTopicArray[index], "\f%05d", TargetColor(255, 255, 255));
+  //hired NPC premium(премия наёмного НПС)----------------------------------
+          travel_time = transport_schedule[schedule_id].uTravelTime;
+          if ( (unsigned int)window_SpeakInHouse->ptr_1C >= HOUSE_BOATS_EMERALD_ISLE )
           {
             if ( CheckHiredNPCSpeciality(Sailor) )
-              v66 -= 2;
+              travel_time -= 2;
             if ( CheckHiredNPCSpeciality(Navigator) )
-              v66 -= 3;
+              travel_time -= 3;
             if ( CheckHiredNPCSpeciality(Pirate) )
-              v66 -= 2;
+              travel_time -= 2;
           }
           else
           {
             if ( CheckHiredNPCSpeciality(Horseman) )
-              v66 -= 2;
+              travel_time -= 2;
           }
           if ( CheckHiredNPCSpeciality(Explorer) )
-            --v66;
-          if ( v66 < 1 )
-            v66 = 1;
-          if ( v23 != v2 )
+            --travel_time;
+
+          if ( travel_time < 1 )
+            travel_time = 1;
+          if ( schedule_id != 255 )
           {
-            memcpy(&v32, &pMapStats->pInfos[transport_schedule[v23].uMapInfoID], 0x44u);
-            sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[404], // Time - %d days, destination %s
-                      v66, v32.pName);
-            strcat(a1, pTmpBuf.data());
-            v28 = a1;
-            a1 += 100;
-            ++v62;
-            ++s1;
-            strcat(v28, "\n \n");
-            v24->uY = v63;
-            v29 = pFontArrus->CalcTextHeight(pTmpBuf.data(), &v53, 0, 0);
-            v30 = v24->uY;
-            v24->uHeight = v29;
-            v2 = 255;
-            v24->uW = v30 + v29 - 1;
-            v63 += v54 + v29;
+            memcpy(&pMap, &pMapStats->pInfos[transport_schedule[schedule_id].uMapInfoID], 0x44u);
+            sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[404], travel_time, pMap.pName); // Time - %d days, destination %s
+            strcat(pTopicArray[index], pTmpBuf.data());
+            strcat(pTopicArray[index], "\n \n");
+            pButton->uY = pRealTextHeight;
+            pTextHeight = pFontArrus->CalcTextHeight(pTmpBuf.data(), &travel_window, 0, 0);
+            pButton->uHeight = pTextHeight;
+            pButton->uW = pButton->uY + pTextHeight - 1;
+            pRealTextHeight += (LOBYTE(pFontArrus->uFontHeight) - 3) + pTextHeight;
           }
         }
         else
         {
-          v31 = a1;
-          ++v62;
-          ++s1;
-          a1 += 100;
-          strcpy(v31, "");
-          if ( v24 )
+          strcpy(pTopicArray[index], "");
+          if ( pButton )
           {
-            v24->uW = 0;
-            v24->uHeight = 0;
-            v24->uY = 0;
+            pButton->uW = 0;
+            pButton->uHeight = 0;
+            pButton->uY = 0;
           }
         }
-        ++v60;
-        if ( (signed int)v60 >= v16->pNumPresenceButton + v16->pStartingPosActiveItem )
-          break;
-        //v16 = v59;
+        ++index;
+        ++pCurrentButton;
       }
-      if ( v63 != v55 )
+      if ( pRealTextHeight != pPrimaryTextHeight )
       {
-        /*v47[1] = &Dest;
-        v47[0] = &v51;
-        v46 = &v50;
-        v45 = (unsigned int)&v49;
-        v44 = &v48;
-        v43 = pTmpBuf2.data();*/
-        sprintf(pTmpBuf.data(), "%s\n \n%s%s%s%s%s", pTmpBuf2.data(), v48[0], v48[1], v48[2], v48[3], v48[4]);
-        v53.DrawTitleText(pFontArrus, 0, 0x92u, 0, pTmpBuf.data(), 3u);
+        sprintf(pTmpBuf.data(), "%s\n \n%s%s%s%s%s", pTmpBuf2.data(), pTopicArray[0], pTopicArray[1], pTopicArray[2], pTopicArray[3], pTopicArray[4]);
+        travel_window.DrawTitleText(pFontArrus, 0, 146, 0, pTmpBuf.data(), 3);
       }
       else
       {
-LABEL_71:
-        v53.DrawTitleText(pFontArrus, 0, (174 - pFontArrus->CalcTextHeight(pGlobalTXT_LocalizationStrings[561], &v53, 0, 0)) / 2 + 138,
-                          color_default, pGlobalTXT_LocalizationStrings[561], 3);
+        travel_window.DrawTitleText(pFontArrus, 0, (174 - pFontArrus->CalcTextHeight(pGlobalTXT_LocalizationStrings[561], &travel_window, 0, 0)) / 2 + 138,//"Извините, приходите в другой день"
+                          TargetColor(255, 255, 255), pGlobalTXT_LocalizationStrings[561], 3);
         pAudioPlayer->StopChannels(-1, -1);
       }
     }
   }
-  else
+  else//после нажатия топика
   {
     if ( dialog_menu_id >= HOUSE_DIALOGUE_TRANSPORT_SCHEDULE_1 && dialog_menu_id <= HOUSE_DIALOGUE_TRANSPORT_SCHEDULE_4 )
     {
-      if ( pParty->uNumGold < s1 )
+      if ( pParty->uNumGold < pPrice )
       {
-        ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2u);
+        ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2);//"У вас не хватает золота"
         PlayHouseSound((unsigned int)window_SpeakInHouse->ptr_1C, HouseSound_Greeting_2);
         pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
         return;
       }
 
-      Party::TakeGold(s1);
+      Party::TakeGold(pPrice);
 
-      v5 = &transport_schedule[transport_routes[(unsigned int)window_SpeakInHouse->ptr_1C - HOUSE_STABLES_HARMONDALE][dialog_menu_id - HOUSE_DIALOGUE_TRANSPORT_SCHEDULE_1]];
-      if ( v5->pSchedule[pParty->uDaysPlayed % 7] )
+      pTravel = &transport_schedule[transport_routes[(unsigned int)window_SpeakInHouse->ptr_1C - HOUSE_STABLES_HARMONDALE][dialog_menu_id - HOUSE_DIALOGUE_TRANSPORT_SCHEDULE_1]];
+      if ( pTravel->pSchedule[pParty->uDaysPlayed % 7] )
       {
-        if ( _stricmp(pCurrentMapName, pMapStats->pInfos[v5->uMapInfoID].pFilename) )
+        if ( _stricmp(pCurrentMapName, pMapStats->pInfos[pTravel->uMapInfoID].pFilename) )
         {
           SaveGame(1, 0);
-          strcpy(pCurrentMapName, pMapStats->pInfos[v5->uMapInfoID].pFilename);
+          strcpy(pCurrentMapName, pMapStats->pInfos[pTravel->uMapInfoID].pFilename);
 
           dword_6BE364_game_settings_1 |= 1u;
           _5B65B8_npcdata_hiword_house_or_other = 0;
           dword_5B65BC = 0;
-          _5B65B4_npcdata_loword_house_or_other = v5->arrival_rot_y;
-          v11 = *((int *)v5 + 3);
+          _5B65B4_npcdata_loword_house_or_other = pTravel->arrival_rot_y;
           uGameState = GAME_STATE_2;
-          _5B65A8_npcdata_uflags_or_other = v11;
-          _5B65AC_npcdata_fame_or_other = v5->arrival_y;
-          _5B65B0_npcdata_rep_or_other = v5->arrival_z;
-          dword_5B65C0 = v11 | v5->arrival_y | v5->arrival_z | v5->arrival_rot_y;
+          _5B65A8_npcdata_uflags_or_other = pTravel->arrival_x;
+          _5B65AC_npcdata_fame_or_other = pTravel->arrival_y;
+          _5B65B0_npcdata_rep_or_other = pTravel->arrival_z;
+          dword_5B65C0 = pTravel->arrival_x | pTravel->arrival_y | pTravel->arrival_z | pTravel->arrival_rot_y;
         }
         else
         {
           pIndoorCamera->sRotationY = 0;
           pParty->uFlags |= 2u;
-          pParty->vPosition.x = v5->arrival_x;
-          pParty->vPosition.y = v5->arrival_y;
-          pParty->vPosition.z = v5->arrival_z;
+          pParty->vPosition.x = pTravel->arrival_x;
+          pParty->vPosition.y = pTravel->arrival_y;
+          pParty->vPosition.z = pTravel->arrival_z;
           pParty->uFallStartY = pParty->vPosition.z;
           pParty->sRotationX = 0;
-          pParty->sRotationY = v5->arrival_rot_y;
+          pParty->sRotationY = pTravel->arrival_rot_y;
         }
         PlayHouseSound((unsigned int)window_SpeakInHouse->ptr_1C, HouseSound_NotEnoughMoney_TrainingSuccessful);
-        v12 = v5->uTravelTime;
-        int _v47;
+        v12 = pTravel->uTravelTime;
         if ( (signed int)window_SpeakInHouse->ptr_1C >= 63 )
         {
-          v63 = SPEECH_SetSail;
+          pSpeech = SPEECH_SetSail;
           v13 = 2500;
           if ( CheckHiredNPCSpeciality(Sailor) )
             v12 -= 2;
           if ( CheckHiredNPCSpeciality(Navigator) )
             v12 -= 3;
-          //_v47 = 45;
           if ( CheckHiredNPCSpeciality(Pirate) )
             v12 -= 2;
         }
         else
         {
-          v63 = SPEECH_CarriageReady;
+          pSpeech = SPEECH_CarriageReady;
           v13 = 1500;
-          //_v47 = 35;
           if ( CheckHiredNPCSpeciality(Horseman) )
             v12 -= 2;
         }
@@ -2195,7 +2103,7 @@
         if ( v12 < 1 )
           v12 = 1;
         RestAndHeal(1440 * v12);
-        v1->PlaySound((PlayerSpeech)v63, 0);
+        pPlayers[uActiveCharacter]->PlaySound(pSpeech, 0);
         v14 = GetTickCount();
         v15 = v14 + v13;
         if ( v15 < v14 )
@@ -2218,20 +2126,17 @@
 //----- (004B68EA) --------------------------------------------------------
 bool __fastcall IsTravelAvailable(int a1)
 {
-  for (uint i = 0; i < 4; ++i)
+  for ( uint i = 0; i < 4; ++i )
   {
-    uint route = transport_routes[a1][i];
-    if (transport_schedule[route].pSchedule[pParty->uDaysPlayed % 7])
+    if ( transport_schedule[transport_routes[a1][i]].pSchedule[pParty->uDaysPlayed % 7] )
     {
-      if (!transport_schedule[route].uQuestBit || _449B57_test_bit(pParty->_quest_bits, transport_schedule[route].uQuestBit))
+      if (!transport_schedule[transport_routes[a1][i]].uQuestBit || _449B57_test_bit(pParty->_quest_bits, transport_schedule[transport_routes[a1][i]].uQuestBit))
         return true;
     }
   }
   return false;
 }
 
-
-
 //----- (004B7911) --------------------------------------------------------
 void  TownHallDialog()
 {
@@ -2242,7 +2147,6 @@
   int v17; // ebx@28
   GUIButton *pButton; // eax@30
   int pTextHeight; // eax@30
-  unsigned int v23; // ecx@30
   unsigned __int16 pTextColor; // ax@30
   GUIWindow window; // [sp+60h] [bp-BCh]@21
   GUIWindow townHall_window; // [sp+B4h] [bp-68h]@1
@@ -2283,14 +2187,13 @@
           pButton = pDialogueWindow->GetControl(i);
           pButton->uY = v29 + v17;
           pTextHeight = pFontArrus->CalcTextHeight(pShopOptions[j], &townHall_window, 0, 0);
-          v23 = pButton->uY;
           pButton->uHeight = pTextHeight;
-          v17 = v23 + pTextHeight - 1;
+          v17 = pButton->uY + pTextHeight - 1;
           pButton->uW = v17;
           pTextColor = TargetColor(0xFFu, 0xFFu, 0x9Bu);
           if ( pDialogueWindow->pCurrentPosActiveItem != v31 )
             pTextColor = TargetColor(0xFFu, 0xFFu, 0xFFu);
-          townHall_window.DrawTitleText(pFontArrus, 0, v23, pTextColor, pShopOptions[j], 3);
+          townHall_window.DrawTitleText(pFontArrus, 0, pButton->uY, pTextColor, pShopOptions[j], 3);
           ++v31;
           ++j;
         }
@@ -2484,126 +2387,53 @@
 //----- (004B8285) --------------------------------------------------------
 void  TavernDialog()
 {
-  int v0;
+  int pPriceRoom;
+  int pPriceFood;
+  int pPriceSkill;
   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
   int pNumString; // edi@16
   signed int v9; // esi@16
-  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
-  int v17; // eax@28
-  char *v18; // eax@30
-  int v19; // eax@30
-  unsigned int v20; // ecx@30
-  int v21; // edx@30
-  int v22; // eax@30
-  unsigned __int16 v23; // ax@30
-  int v24; // eax@34
-  int v25; // eax@34
-  char *v26; // esi@36
-  int v27; // edi@46
   unsigned int pColorText; // eax@57
-  signed int v31; // eax@59
-  //GUIWindow *v33; // edi@64
-  int v34; // eax@64
-  int v35; // ecx@64
-  int v36; // esi@64
-  char v37; // sf@64
   GUIButton *pButton; // eax@65
-  int v39; // edx@69
-  int v40; // ecx@69
-  int v41; // ecx@69
-  int v42; // ecx@70
-  unsigned int v43; // edx@70
-  int v44; // edx@71
-  int v45; // ecx@71
-  int v46; // ecx@72
-  int v47; // eax@74
-  signed int v48; // edi@77
+  int pSkillCount;
+  signed int pOptionsCount; // edi@77
   signed int i; // esi@79
-  int v50; // eax@80
-  //GUIWindow *v51; // ecx@81
-  _QWORD v52; // qax@81
   signed int v53; // edi@81
   int v54; // edi@81
-  //GUIButton *v55; // esi@83
-  const char **v56; // eax@83
-  int v57; // eax@83
-  unsigned int v58; // ecx@83
-  //Player *v59; // edx@83
-  unsigned __int16 v60; // ax@83
-  int v61; // eax@99
-  char *v63; // eax@99
-  GUIFont *v64; // edx@99
-  GUIFont *v65; // edi@100
-  unsigned int v66; // [sp-10h] [bp-284h]@75
-  unsigned __int16 v67; // [sp-Ch] [bp-280h]@75
-  int v68; // [sp-Ch] [bp-280h]@99
-  char *v69; // [sp-8h] [bp-27Ch]@75
-  int v70; // [sp-8h] [bp-27Ch]@99
-  unsigned int v71; // [sp-4h] [bp-278h]@75
-  const char *v72; // [sp-4h] [bp-278h]@93
-  unsigned int v73; // [sp-4h] [bp-278h]@99
+  const char *pText; // [sp-4h] [bp-278h]@93
   char pTopic1[100]; // [sp+Ch] [bp-268h]@55
   char pTopic4[100]; // [sp+70h] [bp-204h]@59
   char pTopic2[100]; // [sp+D4h] [bp-1A0h]@57
   char pTopic3[100]; // [sp+138h] [bp-13Ch]@59
-  //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 pColorWhite; // [sp+24Ch] [bp-28h]@1
+  int v91; // [sp+270h] [bp-4h]@3
+  unsigned int pTopic1Height; // [sp+26Fh] [bp-5h]@55
+  unsigned __int8 pTopic2Height; // [sp+267h] [bp-Dh]@57
   unsigned __int8 pTopic3Height; // [sp+253h] [bp-21h]@59
-  int v83; // [sp+254h] [bp-20h]@1
-  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 pTopic2Height; // [sp+267h] [bp-Dh]@57
-  int v89; // [sp+268h] [bp-Ch]@1
-  unsigned int pTopic1Height; // [sp+26Fh] [bp-5h]@55
-  int v91; // [sp+270h] [bp-4h]@3
-  GUIFont *pOutString;
   unsigned __int8 pTopic4Height;
   int pTextHeight;
+  int all_text_height; // [sp+260h] [bp-14h]@18
+  GUIFont *pOutString;
 
-  pPlayer = pPlayers[uActiveCharacter];
   memcpy(&dialog_window, window_SpeakInHouse, sizeof(dialog_window));
   dialog_window.uFrameX = 483;
   dialog_window.uFrameWidth = 148;
   dialog_window.uFrameZ = 334;
-  pColorWhite = TargetColor(0xFFu, 0xFFu, 0xFFu);
-  pColorYellow = TargetColor(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);
-  pItemNum = v3 * (100 - pPlayer->GetMerchant()) / 100;
-  if ( pItemNum < v3 / 3 )
-    pItemNum = v3 / 3;
-  v5 = 1;
-  pOutString = (GUIFont *)pItemNum;
-  if ( pItemNum <= 0 )
-    pOutString = (GUIFont *)1;
-  v6 = (signed __int64)(*(float *)&v89 * *(float *)&v83 * 0.0099999998);
-  v7 = v6 * (100 - pPlayer->GetMerchant()) / 100;
-  if ( v7 < v6 / 3 )
-  v7 = v6 / 3;
-  v83 = v7;
-  if ( v7 <= 0 )
-  {
-    v7 = 1;
-    v83 = 1;
-  }
+
+  pPriceRoom = ((v2 * v2) / 10) * (100 - pPlayers[uActiveCharacter]->GetMerchant()) / 100;
+  if ( pPriceRoom < ((v2 * v2) / 10) / 3 )
+    pPriceRoom = ((v2 * v2) / 10) / 3;
+  if ( pPriceRoom <= 0 )
+    pPriceRoom = 1;
+
+  pPriceFood = ((v2 * v2) * v2 / 100) * (100 - pPlayers[uActiveCharacter]->GetMerchant()) / 100;
+  if ( pPriceFood < ((v2 * v2) * v2 / 100) / 3 )
+    pPriceFood = ((v2 * v2) * v2 / 100) / 3;
+  if ( pPriceFood <= 0 )
+    pPriceFood = 1;
+
 
   switch(dialog_menu_id)
   {
@@ -2612,81 +2442,64 @@
       if ( !HouseUI_CheckIfPlayerCanInteract() )
           return;
 
-      sprintf(pTopic1, "\f%05d", pDialogueWindow->pCurrentPosActiveItem == 2 ? pColorYellow : pColorWhite);
-      sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[178], pOutString); // Rent room for %d gold
+      sprintf(pTopic1, "\f%05d", pDialogueWindow->pCurrentPosActiveItem == 2 ? TargetColor(0xFFu, 0xFFu, 0x9Bu) : TargetColor(0xFFu, 0xFFu, 0xFFu));
+      sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[178], pPriceRoom); // Rent room for %d gold
       strcat(pTopic1, pTmpBuf2.data());
       pTopic1Height = pFontArrus->CalcTextHeight(pTopic1, &dialog_window, 0, 0);
       strcat(pTopic1, "\n \n");
 
-      sprintf(pTopic2, "\f%05d", pDialogueWindow->pCurrentPosActiveItem == 3 ? pColorYellow : pColorWhite);
+      sprintf(pTopic2, "\f%05d", pDialogueWindow->pCurrentPosActiveItem == 3 ? TargetColor(0xFFu, 0xFFu, 0x9Bu) : TargetColor(0xFFu, 0xFFu, 0xFFu));
       sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[86], // Buy food for %d days for %d gold
-        (unsigned int)p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].fPriceMultiplier, v83);
+        (unsigned int)p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].fPriceMultiplier, pPriceFood);
       strcat(pTopic2, pTmpBuf2.data());
       pTopic2Height = pFontArrus->CalcTextHeight(pTopic2, &dialog_window, 0, 0);
       strcat(pTopic2, "\n \n");
 
-      sprintf(pTopic3, "\f%05d", pDialogueWindow->pCurrentPosActiveItem == 4 ? pColorYellow : pColorWhite);
+      sprintf(pTopic3, "\f%05d", pDialogueWindow->pCurrentPosActiveItem == 4 ? TargetColor(0xFFu, 0xFFu, 0x9Bu) : TargetColor(0xFFu, 0xFFu, 0xFFu));
       strcat(pTopic3, pGlobalTXT_LocalizationStrings[160]); // Learn Skills
       pTopic3Height = pFontArrus->CalcTextHeight(pTopic3, &dialog_window, 0, 0);
       strcat(pTopic3, "\n \n");
       pTopic4[0] = 0;
       if ( (signed int)window_SpeakInHouse->par1C >= 108 && (signed int)window_SpeakInHouse->par1C <= 120 )
       {
-        sprintf(pTopic4, "\f%05d", pDialogueWindow->pCurrentPosActiveItem == 5 ? pColorYellow : pColorWhite);
+        sprintf(pTopic4, "\f%05d", pDialogueWindow->pCurrentPosActiveItem == 5 ? TargetColor(0xFFu, 0xFFu, 0x9Bu) : TargetColor(0xFFu, 0xFFu, 0xFFu));
         strcat(pTopic4, pGlobalTXT_LocalizationStrings[611]); // Play Arcomage
         pTopic4Height = pFontArrus->CalcTextHeight(pTopic4, &dialog_window, 0, 0);
       }
-      pNumActiveItem = pDialogueWindow->pStartingPosActiveItem;
-      v36 = LOBYTE(pFontArrus->uFontHeight) - 3;
-      v37 = -pDialogueWindow->pNumPresenceButton < 0;
-      if ( !(v37 ^ (pNumActiveItem < pNumActiveItem + pDialogueWindow->pNumPresenceButton)) )
+
+      if ( pDialogueWindow->pNumPresenceButton )
       {
-        do
+        for ( pItemNum = pDialogueWindow->pStartingPosActiveItem;
+              pItemNum < pDialogueWindow->pStartingPosActiveItem + pDialogueWindow->pNumPresenceButton; ++pItemNum )
         {
-          pButton = pDialogueWindow->GetControl(pNumActiveItem);
+          pButton = pDialogueWindow->GetControl(pItemNum);
           if ( pButton->msg_param == 15 )
           {
-            v46 = pTopic1Height;
             pButton->uHeight = pTopic1Height;
             pButton->uY = 146;
-            v41 = v46 + 145;
-            pButton->uW = v41;
+            pButton->uW = pTopic1Height + 145;
           }
           else if ( pButton->msg_param == 16 )
           {
-            v44 = pTopic2Height;
-            v45 = pTopic1Height + v36 + 146;
             pButton->uHeight = pTopic2Height;
-            pButton->uY = v45;
-            v41 = v45 + v44 - 1;
-            pButton->uW = v41;
+            pButton->uY = pTopic1Height + (LOBYTE(pFontArrus->uFontHeight) - 3) + 146;
+            pButton->uW = (pTopic1Height + (LOBYTE(pFontArrus->uFontHeight) - 3) + 146) + pTopic2Height - 1;
           }
           else if ( pButton->msg_param == 96 )
           {
-            v42 = pTopic1Height + pTopic2Height + 2 * v36 + 146;
-            v43 = pTopic3Height;
-            pButton->uY = v42;
-            pButton->uHeight = v43;
-            v41 = v43 + v42 - 1;
-            pButton->uW = v41;
+            pButton->uY = pTopic1Height + pTopic2Height + 2 * (LOBYTE(pFontArrus->uFontHeight) - 3) + 146;
+            pButton->uHeight = pTopic3Height;
+            pButton->uW = pTopic3Height + (pTopic1Height + pTopic2Height + 2 * (LOBYTE(pFontArrus->uFontHeight) - 3) + 146) - 1;
           }
           else if ( pButton->msg_param == 101 )
           {
-            v39 = pTopic1Height + 3 * v36 + pTopic4Height + pTopic2Height + 146;
-            v40 = pTopic4Height;
             pButton->uHeight = pTopic4Height;
-            pButton->uY = v39;
-            v41 = v39 + v40 - 1;
-            pButton->uW = v41;
-          }
-          pNumActiveItem++;
-          if ( pNumActiveItem >= pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem )
-          {
-            sprintfex(pTmpBuf.data(), "%s%s%s%s", pTopic1, pTopic2, pTopic3, pTopic4);
-            dialog_window.DrawTitleText(pFontArrus, 0, 146, 0, pTmpBuf.data(), 3);
+            pButton->uY = pTopic1Height + 3 * (LOBYTE(pFontArrus->uFontHeight) - 3) + pTopic4Height + pTopic2Height + 146;
+            pButton->uW = (pTopic1Height + 3 * (LOBYTE(pFontArrus->uFontHeight) - 3) + pTopic4Height + pTopic2Height + 146) + pTopic4Height - 1;
           }
         }
-        while ( pNumActiveItem < pDialogueWindow->pStartingPosActiveItem + pDialogueWindow->pNumPresenceButton );
+        sprintfex(pTmpBuf.data(), "%s%s%s%s", pTopic1, pTopic2, pTopic3, pTopic4);
+        dialog_window.DrawTitleText(pFontArrus, 0, 146, 0, pTmpBuf.data(), 3);
       }
       break;
     }
@@ -2702,11 +2515,9 @@
         pOutString = pFontCreate;
         pTextHeight = pFontCreate->CalcTextHeight(pTmpBuf.data(), &dialog_window, 12, 0) + 7;
       }
-      auto pTex = pIcons_LOD->GetTexture(uTextureID_Leather);
-      pRenderer->GetLeather(8, 352 - pTextHeight, pTex, pTex->uTextureHeight - pTextHeight);
+      pRenderer->GetLeather(8, 352 - pTextHeight, pIcons_LOD->GetTexture(uTextureID_Leather), pIcons_LOD->GetTexture(uTextureID_Leather)->uTextureHeight - pTextHeight);
       pRenderer->DrawTextureIndexed(8, 347 - pTextHeight, pTexture_591428);
-      v63 = FitTextInAWindow(pTmpBuf.data(), pOutString, &dialog_window, 0xCu, 0);
-      window_SpeakInHouse->DrawText(pOutString, 12, 354 - pTextHeight, 0, v63, 0, 0, 0);
+      window_SpeakInHouse->DrawText(pOutString, 12, 354 - pTextHeight, 0, FitTextInAWindow(pTmpBuf.data(), pOutString, &dialog_window, 0xCu, 0), 0, 0, 0);
       break;
     }
     case HOUSE_DIALOGUE_TAVERN_ARCOMAGE_VICTORY_CONDITIONS:
@@ -2714,13 +2525,11 @@
       strcpy(pTmpBuf.data(), pNPCTopics[(uint)window_SpeakInHouse->ptr_1C + 247].pText);
       dialog_window.uFrameWidth = game_viewport_width;
       dialog_window.uFrameZ = 452;
-      v61 = pFontArrus->CalcTextHeight(pTmpBuf.data(), &dialog_window, 12, 0);
-      pTextHeight = v61 + 7;
-      auto pTex = pIcons_LOD->GetTexture(uTextureID_Leather);
-      pRenderer->GetLeather(8, 352 - (v61 + 7), pTex, pTex->uTextureHeight - (v61 + 7));
+      pTextHeight = pFontArrus->CalcTextHeight(pTmpBuf.data(), &dialog_window, 12, 0) + 7;
+      pRenderer->GetLeather(8, 352 - pTextHeight, pIcons_LOD->GetTexture(uTextureID_Leather), pIcons_LOD->GetTexture(uTextureID_Leather)->uTextureHeight - pTextHeight);
       pRenderer->DrawTextureIndexed(8, 347 - pTextHeight, pTexture_591428);
-      v63 = FitTextInAWindow(pTmpBuf.data(), pFontArrus, &dialog_window, 0xCu, 0);
-      window_SpeakInHouse->DrawText(pFontArrus, 12, 354 - pTextHeight, 0, v63, 0, 0, 0);
+      window_SpeakInHouse->DrawText(pFontArrus, 12, 354 - pTextHeight, 0,
+                                    FitTextInAWindow(pTmpBuf.data(), pFontArrus, &dialog_window, 0xCu, 0), 0, 0, 0);
       break;
     }
     case HOUSE_DIALOGUE_TAVERN_ARCOMAGE_RESULT:
@@ -2730,43 +2539,42 @@
       if ( pArcomageGame->uGameResult )
       {
         if ( pArcomageGame->uGameResult == 1 )
-          v72 = pGlobalTXT_LocalizationStrings[640];// You won!
+          pText = pGlobalTXT_LocalizationStrings[640];// You won!
         else
-          v72 = pGlobalTXT_LocalizationStrings[641];// You lost!
+          pText = pGlobalTXT_LocalizationStrings[641];// You lost!
       }
       else
       {
-        v72 = pGlobalTXT_LocalizationStrings[639];// A tie!
+        pText = pGlobalTXT_LocalizationStrings[639];// A tie!
       }
-      strcpy(pTmpBuf.data(), v72);
-      v66 = (174 - pFontArrus->CalcTextHeight(pTmpBuf.data(), &dialog_window, 0, 0)) / 2 + 138;
-      dialog_window.DrawTitleText(pFontArrus, 0, v66, pColorYellow, pTmpBuf.data(), 3);
+      strcpy(pTmpBuf.data(), pText);
+      dialog_window.DrawTitleText(pFontArrus, 0, (174 - pFontArrus->CalcTextHeight(pTmpBuf.data(), &dialog_window, 0, 0)) / 2 + 138,
+                                  TargetColor(0xFFu, 0xFFu, 0x9Bu), pTmpBuf.data(), 3);
       break;
     }
     case HOUSE_DIALOGUE_TAVERN_REST:
     {
-      if ( pParty->uNumGold >= (unsigned int)pOutString )
+      if ( pParty->uNumGold >= pPriceRoom )
       {
-        Party::TakeGold((unsigned int)pOutString);
-        v27 = (int)window_SpeakInHouse->ptr_1C;//107
+        Party::TakeGold(pPriceRoom);
         PlayHouseSound((unsigned int)window_SpeakInHouse->ptr_1C, HouseSound_NotEnoughMoney_TrainingSuccessful);
         dialog_menu_id = HOUSE_DIALOGUE_NULL;
         sub_4BD8B5();
         GetHouseGoodbyeSpeech();
         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_RentRoom;
-        pMessageQueue_50CBD0->pMessages[0].param = v27;
+        pMessageQueue_50CBD0->pMessages[0].param = (int)window_SpeakInHouse->ptr_1C;//107
         pMessageQueue_50CBD0->pMessages[0].field_8 = 1;
         ++pMessageQueue_50CBD0->uNumMessages;
+        window_SpeakInHouse->Release();
+        window_SpeakInHouse = 0;
         return;
       }
-      ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2);
+      ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2);//У вас не хватает золота
       PlayHouseSound((unsigned int)window_SpeakInHouse->ptr_1C, HouseSound_Goodbye);
-      pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, v5, 0);
+      pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
       break;
     }
 
@@ -2774,92 +2582,78 @@
     {
       if ( !HouseUI_CheckIfPlayerCanInteract() )
         return;
-      v0 = 0;
+      pSkillCount = 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;
+      pPriceSkill = v9 * (100 - pPlayers[uActiveCharacter]->GetMerchant()) / 100;
+      if ( pPriceSkill < v9 / 3 )
+        pPriceSkill = v9 / 3;
       all_text_height = 0;
-      if ( pNumActiveItem < pNumActiveItem + pDialogueWindow->pNumPresenceButton )
+      for ( pItemNum = pDialogueWindow->pStartingPosActiveItem;
+            pItemNum < pDialogueWindow->pStartingPosActiveItem + pDialogueWindow->pNumPresenceButton; ++pItemNum )
       {
-        do
-        {
-          v12 = pDialogueWindow->GetControl(pNumActiveItem)->msg_param - 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 )
+        if ( byte_4ED970_skill_learn_ability_by_class_table[pPlayers[uActiveCharacter]->classType][pDialogueWindow->GetControl(pItemNum)->msg_param - 36]
+            && !pPlayers[uActiveCharacter]->pActiveSkills[pDialogueWindow->GetControl(pItemNum)->msg_param - 36] )
         {
-          sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[401], pItemNum);
-          dialog_window.DrawTitleText(pFontArrus, 0, 0x92u, 0, pTmpBuf.data(), 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->msg_param - 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;
+          all_text_height = pFontArrus->CalcTextHeight(pSkillNames[pDialogueWindow->GetControl(pItemNum)->msg_param - 36], &dialog_window, 0, 0);
+          pSkillCount++;
         }
       }
-      sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[544], pPlayer->pName, pClassNames[pPlayer->classType]);
+      if ( pSkillCount )
+      {
+        sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[401], pPriceSkill);//Стоимость навыка: %lu
+        dialog_window.DrawTitleText(pFontArrus, 0, 0x92u, 0, pTmpBuf.data(), 3);
+        v91 = (149 - all_text_height) / pSkillCount;
+        if ( (149 - all_text_height) / pSkillCount > 32 )
+          v91 = 32;
+        v54 = (149 - pSkillCount * v91 - all_text_height) / 2 - v91 / 2 + 162;
+        for ( pItemNum = pDialogueWindow->pStartingPosActiveItem;
+              pItemNum < pDialogueWindow->pStartingPosActiveItem + pDialogueWindow->pNumPresenceButton; pItemNum++ )
+        {
+          pButton = pDialogueWindow->GetControl(pItemNum);
+          if ( !byte_4ED970_skill_learn_ability_by_class_table[pPlayers[uActiveCharacter]->classType][pButton->msg_param - 36]
+            || pPlayers[uActiveCharacter]->pActiveSkills[pButton->msg_param - 36] )
+          {
+            pButton->uW = 0;
+            pButton->uHeight = 0;
+            pButton->uY = 0;
+          }
+          else
+          {
+            pButton->uY = v91 + v54;
+            pTextHeight = pFontArrus->CalcTextHeight(pSkillNames[pButton->msg_param - 36], &dialog_window, 0, 0);
+            pButton->uHeight = pTextHeight;
+            v54 = pTextHeight + pButton->uY - 1;
+            pButton->uW = v54;
+            pColorText = TargetColor(0xFFu, 0xFFu, 0x9Bu);
+            if ( pDialogueWindow->pCurrentPosActiveItem != pItemNum )
+              pColorText = TargetColor(0xFFu, 0xFFu, 0xFFu);
+            dialog_window.DrawTitleText(pFontArrus, 0, pButton->uY, pColorText, pSkillNames[pButton->msg_param - 36], 3);
+          }
+        }
+        return;
+      }
+      sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[544], pPlayers[uActiveCharacter]->pName,//Советую вам %s %s поискать знания еще где-нибудь
+              pClassNames[pPlayers[uActiveCharacter]->classType]);
       strcat(pTmpBuf.data(), "\n \n");
-      strcat(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[528]);
+      strcat(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[528]);//Больше ничего не могу предложить.
       pTextHeight = (174 - pFontArrus->CalcTextHeight(pTmpBuf.data(), &dialog_window, 0, 0)) / 2 + 138;
-      dialog_window.DrawTitleText(pFontArrus, 0, pTextHeight, pColorYellow, pTmpBuf.data(), 3);
+      dialog_window.DrawTitleText(pFontArrus, 0, pTextHeight, TargetColor(0xFFu, 0xFFu, 0x9Bu), pTmpBuf.data(), 3);
       return;
     }
 
     case HOUSE_DIALOGUE_TAVERN_BUY_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);
+        ShowStatusBarString(pGlobalTXT_LocalizationStrings[140], 2);//Вы уже купили еду!
         if ( uActiveCharacter )
           pPlayers[uActiveCharacter]->PlaySound(SPEECH_67, 0);
-        pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, v5, 0);
+        pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
         return;
       }
-      if ( pParty->uNumGold >= v7 )
+      if ( pParty->uNumGold >= pPriceFood )
       {
-        Party::TakeGold(v7);
-        //pParty->uNumFoodRations = (signed __int64)p2DEvents_minus1__20[13 * (unsigned int)ptr_507BC0->ptr_1C];
+        Party::TakeGold(pPriceFood);
         pParty->uNumFoodRations = (signed __int64)p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].fPriceMultiplier;
         PlayHouseSound((unsigned int)window_SpeakInHouse->ptr_1C, HouseSound_Greeting_2);
         pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
@@ -2867,7 +2661,7 @@
       }
       ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2);  // "You don't have enough gold"
       PlayHouseSound((unsigned int)window_SpeakInHouse->ptr_1C, HouseSound_Goodbye);
-      pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, v5, 0);
+      pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
       break;
     }
 
@@ -2875,42 +2669,34 @@
     {
       if ( HouseUI_CheckIfPlayerCanInteract() )
       {
-        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 ( pNumActiveItem < pNumActiveItem + pDialogueWindow->pNumPresenceButton )
+        pOptionsCount = 2;
+        pShopOptions[0] = pGlobalTXT_LocalizationStrings[620];//Правила
+        pShopOptions[1] = pGlobalTXT_LocalizationStrings[622];//Условия победы
+        if ( pParty->HasItem(651) )//651 - Колода для игры в АркоМэйдж в Items.txt
         {
-          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 *)pShopOptions[pNumString], 3);
-            pItemNum++;
-            ++pNumString;
-            pNumActiveItem = pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem;
-          }
-          while ( pItemNum < pNumActiveItem );
+          pShopOptions[2] = pGlobalTXT_LocalizationStrings[621];//Играть
+          pOptionsCount = 3;
+        }
+        for ( i = 0; i < pOptionsCount; ++i )
+          all_text_height = pFontArrus->CalcTextHeight(pShopOptions[i], &dialog_window, 0, 0);
+        all_text_height = (174 - all_text_height) / pOptionsCount;
+        
+        v54 = (174 - pOptionsCount * (174 - all_text_height) / pOptionsCount - all_text_height) / 2 - (174 - all_text_height) / pOptionsCount / 2 + 138;
+        pNumString = 0;
+        for ( pItemNum = pDialogueWindow->pStartingPosActiveItem;
+              pItemNum < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem ; pItemNum++ )
+        {
+          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 = TargetColor(0xFFu, 0xFFu, 0x9Bu);
+          if ( pDialogueWindow->pCurrentPosActiveItem != pItemNum )
+            pColorText = TargetColor(0xFFu, 0xFFu, 0xFFu);
+          dialog_window.DrawTitleText(pFontArrus, 0, pButton->uY, pColorText, (const char *)pShopOptions[pNumString], 3);
+          ++pNumString;
         }
       }
       break;
@@ -2924,408 +2710,282 @@
 
 //----- (004B705E) --------------------------------------------------------
 void TempleDialog()
+{
+  int pPrice; // edi@1
+  int pTextHeight; // eax@11
+  unsigned __int16 pTextColor; // ax@21
+  DDM_DLV_Header *v26; // edi@29
+  unsigned int v30; // edx@36
+  int v35; // edi@50
+  GUIButton *pButton; // edi@64
+  int v47; // edi@71
+  GUIWindow tample_window; // [sp+13Ch] [bp-88h]@1
+  unsigned __int8 index; // [sp+1B7h] [bp-Dh]@64
+  int v64; // [sp+1B8h] [bp-Ch]@6
+  unsigned int pCurrentItem; // [sp+1BCh] [bp-8h]@6
+  int all_text_height; // [sp+1C0h] [bp-4h]@6
+
+  memcpy(&tample_window, window_SpeakInHouse, sizeof(tample_window));
+  tample_window.uFrameX = 483;
+  tample_window.uFrameWidth = 148;
+  tample_window.uFrameZ = 334;
+  pPrice = pPlayers[uActiveCharacter]->GetTempleHealCostModifier(p2DEvents[window_SpeakInHouse->par1C - 1].fPriceMultiplier);
+  if ( dialog_menu_id == HOUSE_DIALOGUE_MAIN )
+  {
+    index = 1;
+    pButton = pDialogueWindow->GetControl(pDialogueWindow->pStartingPosActiveItem);
+    pButton->uHeight = 0;
+    pButton->uY = 0;
+    if ( pPlayers[uActiveCharacter]->IsPlayerHealableByTemple() )
     {
-    GUIWindow *v0; // ebx@1
-    Player *v1; // esi@1
-    int v2; // edi@1
-    int result; // eax@4
-    GUIWindow *v4; // edi@6
-    void *v5; // eax@6
-    int v6; // eax@6
-    unsigned int v7; // eax@8
-    int v8; // ecx@8
-    unsigned int v9; // eax@9
-    int v10; // eax@11
-    int v11; // eax@12
-    GUIWindow *v12; // ecx@16
-    int v13; // edx@16
-    GUIButton *v14; // eax@19
-    GUIButton *v15; // edi@19
-    int v16; // eax@19
-    const char *v17; // eax@21
-    int v18; // eax@21
-    unsigned int v19; // ecx@21
-    int v20; // eax@21
-    unsigned __int16 v21; // ax@21
-    unsigned __int16 v22; // ST14_2@27
-    int v23; // eax@27
-    double v24; // st7@28
-    unsigned int v25; // ebx@28
-    DDM_DLV_Header *v26; // edi@29
-    int v27; // eax@31
-    int v28; // eax@32
-    //unsigned int v29; // ecx@34
-    unsigned int v30; // edx@36
-    unsigned int v31; // edx@38
-    unsigned int v32; // edx@40
-    unsigned int v33; // edx@42
-    unsigned int v34; // edx@44
-    int v35; // edi@50
-    signed int v36; // eax@50
-    unsigned __int8 v37; // al@54
-    int v38; // ecx@54
-    GUIWindow *v39; // eax@56
-    unsigned __int8 v40; // al@61
-    GUIButton *v41; // edi@64
-    int v42; // esi@66
-    GUIWindow *v43; // ecx@66
-    int v44; // edi@66
-    int v45; // eax@68
-    signed int v46; // edi@69
-    int v47; // edi@71
-    GUIButton *v48; // eax@73
-    const char *v49; // edx@73
-    GUIButton *v50; // esi@73
-    int v51; // eax@73
-    unsigned int v52; // ecx@73
-    unsigned __int16 v53; // ax@73
-    char a1[300]; // [sp+10h] [bp-1B4h]@64
-    GUIWindow v57; // [sp+13Ch] [bp-88h]@1
-    __int64 v58; // [sp+190h] [bp-34h]@1
-    __int64 v59; // [sp+198h] [bp-2Ch]@1
-    __int64 v60; // [sp+1A0h] [bp-24h]@1
-    GUIWindow *v61; // [sp+1ACh] [bp-18h]@6
-    unsigned int v62; // [sp+1B0h] [bp-14h]@8
-    unsigned __int8 v63; // [sp+1B7h] [bp-Dh]@64
-    int v64; // [sp+1B8h] [bp-Ch]@6
-    unsigned int v65; // [sp+1BCh] [bp-8h]@6
-    DDM_DLV_Header *v66; // [sp+1C0h] [bp-4h]@6
-
-    v0 = window_SpeakInHouse;
-    memcpy(&v57, window_SpeakInHouse, sizeof(v57));
-    v57.uFrameX = 483;
-    v57.uFrameWidth = 148;
-    v57.uFrameZ = 334;
-    HIDWORD(v58) = TargetColor(0xFFu, 0xFFu, 0xFFu);
-    HIDWORD(v59) = TargetColor(0xFFu, 0xFFu, 0x9Bu);
-    v1 = pPlayers[uActiveCharacter];
-    //v2 = pPlayers[uActiveCharacter]->_4B807C(p2DEvents_minus1__20[13 * (unsigned int)v0->ptr_1C]);
-    v2 = pPlayers[uActiveCharacter]->GetTempleHealCostModifier(p2DEvents[v0->par1C - 1].fPriceMultiplier);
-    HIDWORD(v60) = v2;
-    if ( dialog_menu_id != HOUSE_DIALOGUE_MAIN )
+      sprintfex(pTmpBuf.data(), "%s %d %s", pGlobalTXT_LocalizationStrings[104], pPrice, pGlobalTXT_LocalizationStrings[97]);//"Лечить" "Золото"
+      pShopOptions[0] = pTmpBuf.data();
+      index = 0;
+    }
+    pShopOptions[1] = pGlobalTXT_LocalizationStrings[68];//"Пожертвовать"
+    pShopOptions[2] = pGlobalTXT_LocalizationStrings[160];//"Обучиться навыкам"
+    all_text_height = 0;
+    if ( index < pDialogueWindow->pNumPresenceButton )
     {
-      if ( dialog_menu_id != HOUSE_DIALOGUE_TEMPLE_HEAL )
+      uint i = index;
+      for ( uint j = index; j < pDialogueWindow->pNumPresenceButton; ++j )
+      {
+        all_text_height += pFontArrus->CalcTextHeight(pShopOptions[1 * i], &tample_window, 0, 0);
+        i++;
+      }
+    }
+    v64 = (174 - (signed int)all_text_height) / (pDialogueWindow->pNumPresenceButton - index);
+    if ( v64 > 32 )
+      v64 = 32;
+    all_text_height = (174 - v64 * (pDialogueWindow->pNumPresenceButton - index) - (signed int)all_text_height) / 2 - v64 / 2 + 138;
+    if ( index + pDialogueWindow->pStartingPosActiveItem < pDialogueWindow->pStartingPosActiveItem + pDialogueWindow->pNumPresenceButton )
+    {
+      uint i = index;
+      for ( pCurrentItem = index + pDialogueWindow->pStartingPosActiveItem;
+          (signed int)pCurrentItem < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem; ++pCurrentItem )
       {
-        if ( dialog_menu_id != HOUSE_DIALOGUE_TEMPLE_DONATE )
-        {
-          if ( dialog_menu_id == HOUSE_DIALOGUE_LEARN_SKILLS )
-          {
-            if ( HouseUI_CheckIfPlayerCanInteract() )
-            {
-              v4 = pDialogueWindow;
-              v61 = pDialogueWindow;
-              v5 = window_SpeakInHouse->ptr_1C;
-              v66 = 0;
-              //v65 = (signed __int64)(*(float *)&p2DEvents_minus1__24[13 * (signed int)v5] * 500.0);
-              v65 = (signed __int64)(p2DEvents[(signed int)v5 - 1].flt_24 * 500.0);
-              v6 = v1->GetMerchant();
-              v64 = (signed int)(v65 * (100 - v6)) / 100;
-              if ( v64 < (signed int)v65 / 3 )
-                v64 = (signed int)v65 / 3;
-              v7 = v4->pStartingPosActiveItem;
-              v8 = v7 + v4->pNumPresenceButton;
-              v65 = 0;
-              v62 = v7;
-              if ( (signed int)v7 >= v8 )
-                goto LABEL_78;
-              do
-              {
-                v9 = v4->GetControl(v62)->msg_param - 36;
-                if ( byte_4ED970_skill_learn_ability_by_class_table[v1->classType][v9] && !v1->pActiveSkills[v9] )
-                {
-                  v10 = pFontArrus->CalcTextHeight(pSkillNames[v9], &v57, 0, 0);
-                  v66 = (DDM_DLV_Header *)((char *)v66 + v10);
-                  ++v65;
-                }
-                v11 = v4->pStartingPosActiveItem;
-                ++v62;
-              }
-              while ( (signed int)v62 < v4->pNumPresenceButton + v11 );
-              if ( v65 )
-              {
-                sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[401], v64);
-                v57.DrawTitleText(pFontArrus, 0, 0x92u, 0, pTmpBuf.data(), 3u);
-                v64 = (149 - (signed int)v66) / (signed int)v65;
-                if ( v64 > 32 )
-                  v64 = 32;
-                v65 = (signed int)(149 - v65 * v64 - (int)v66) / 2 - v64 / 2 + 162;
-                v12 = v61;
-                result = v61->pStartingPosActiveItem;
-                v13 = result + v61->pNumPresenceButton;
-                v62 = v61->pStartingPosActiveItem;
-                if ( result < v13 )
-                {
-                  v66 = (DDM_DLV_Header *)2;
-                  while ( 1 )
-                  {
-                    v14 = v12->GetControl(v62);
-                    v15 = v14;
-                    v16 = v14->msg_param - 36;
-                    if ( !byte_4ED970_skill_learn_ability_by_class_table[v1->classType][v16] || v1->pActiveSkills[v16] )
-                    {
-                      v15->uW = 0;
-                      v15->uHeight = 0;
-                      v15->uY = 0;
-                    }
-                    else
-                    {
-                      v17 = pSkillNames[v16];
-                      v15->uY = v64 + v65;
-                      HIDWORD(v60) = (uint32)v17;
-                      v18 = pFontArrus->CalcTextHeight(v17, &v57, 0, 0);
-                      v19 = v15->uY;
-                      v15->uHeight = v18;
-                      v20 = v19 + v18 - 1;
-                      v15->uW = v20;
-                      v65 = v20;
-                      v21 = WORD2(v59);
-                      if ( (DDM_DLV_Header *)pDialogueWindow->pCurrentPosActiveItem != v66 )
-                        v21 = WORD2(v58);
-                      v57.DrawTitleText(pFontArrus, 0, v19, v21, (const char *)HIDWORD(v60), 3u);
-                    }
-                    result = (int)v61;
-                    ++v62;
-                    v66 = (DDM_DLV_Header *)((char *)v66 + 1);
-                    if ( (signed int)v62 >= v61->pNumPresenceButton + v61->pStartingPosActiveItem )
-                      break;
-                    v12 = v61;
-                  }
-                }
-              }
-              else
-              {
-LABEL_78:
-                sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[544], v1->pName, pClassNames[v1->classType]);
-                strcat(pTmpBuf.data(), "\n \n");
-                strcat(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[528]);
-                v22 = WORD2(v59);
-                v23 = pFontArrus->CalcTextHeight(pTmpBuf.data(), &v57, 0, 0);
-                v57.DrawTitleText(pFontArrus, 0, (174 - v23) / 2 + 138, v22, pTmpBuf.data(), 3u);
-              }
-            }
-          }
-          return;
-        }
-        // DONATION
-        //v24 = p2DEvents_minus1__20[13 * (unsigned int)ptr_507BC0->ptr_1C];
-        v24 = p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].fPriceMultiplier;
-        v25 = 0;
-        if ( pParty->uNumGold >= (unsigned int)(signed __int64)v24 )
+        pButton = pDialogueWindow->GetControl(pCurrentItem);
+        pButton->uY = v64 + all_text_height;
+        pTextHeight = pFontArrus->CalcTextHeight(pShopOptions[1 * i], &tample_window, 0, 0);
+        pButton->uHeight = pTextHeight;
+        pButton->uW = pButton->uY + pTextHeight - 1;
+        all_text_height = pButton->uW;
+        pTextColor = TargetColor(0xFFu, 0xFFu, 0x9Bu);
+        if ( pDialogueWindow->pCurrentPosActiveItem != index + 2 )
+          pTextColor = TargetColor(0xFFu, 0xFFu, 0xFFu);
+        tample_window.DrawTitleText(pFontArrus, 0, pButton->uY, pTextColor, pShopOptions[1 * i], 3);
+        i++;
+        index++;
+      }
+    }
+    return;
+  }
+  //-------------------------------------------------
+  if ( dialog_menu_id == HOUSE_DIALOGUE_TEMPLE_HEAL )
+  {
+    if ( !pPlayers[uActiveCharacter]->IsPlayerHealableByTemple() )
+      return;
+    if ( pParty->uNumGold < pPrice )
+    {
+      ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2);//"У вас не хватает золота"
+      PlayHouseSound((unsigned int)window_SpeakInHouse->ptr_1C, HouseSound_NotEnoughMoney_TrainingSuccessful);
+      pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
+      return;
+    }
+    Party::TakeGold(pPrice);
+    v35 = LODWORD(pPlayers[uActiveCharacter]->pConditions[17]);
+    memset(pPlayers[uActiveCharacter], 0, 0xA0u);
+    pPlayers[uActiveCharacter]->sHealth = pPlayers[uActiveCharacter]->GetMaxHealth();
+    pPlayers[uActiveCharacter]->sMana = pPlayers[uActiveCharacter]->GetMaxMana();
+    if ( (signed int)window_SpeakInHouse->ptr_1C != 78 && ((signed int)window_SpeakInHouse->ptr_1C <= 80 || (signed int)window_SpeakInHouse->ptr_1C > 82) )
+    {
+      if ( (unsigned int)pPlayers[uActiveCharacter]->pConditions[17] | v35 )
+      {
+        pPlayers[uActiveCharacter]->uCurrentFace = pPlayers[uActiveCharacter]->uPrevFace;
+        pPlayers[uActiveCharacter]->uVoiceID = pPlayers[uActiveCharacter]->uPrevVoiceID;
+        ReloadPlayerPortraits(uActiveCharacter - 1, pPlayers[uActiveCharacter]->uPrevFace);
+      }
+      pAudioPlayer->PlaySound((SoundID)(SOUND_GoldReceived|0x2), -1, 0, -1, 0, 0, 0, 0);
+      pPlayers[uActiveCharacter]->PlaySound(SPEECH_82, 0);
+      pOtherOverlayList->_4418B1(20, uActiveCharacter + 99, 0, 65536);
+      pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
+      return;
+    }
+    if ( (unsigned int)pPlayers[uActiveCharacter]->pConditions[17] | v35 )
+    {
+      LODWORD(pPlayers[uActiveCharacter]->pConditions[17]) = v35;
+    }
+    else
+    {
+      if ( !pPlayers[uActiveCharacter]->pConditions[16]
+        && !pPlayers[uActiveCharacter]->pConditions[15] && !pPlayers[uActiveCharacter]->pConditions[14] )
+      {
+        pAudioPlayer->PlaySound((SoundID)(SOUND_GoldReceived|0x2), -1, 0, -1, 0, 0, 0, 0);
+        pPlayers[uActiveCharacter]->PlaySound(SPEECH_82, 0);
+        pOtherOverlayList->_4418B1(20, uActiveCharacter + 99, 0, 65536);
+        pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
+        return;
+      }
+      pPlayers[uActiveCharacter]->uPrevFace = pPlayers[uActiveCharacter]->uCurrentFace;
+      pPlayers[uActiveCharacter]->uPrevVoiceID = pPlayers[uActiveCharacter]->uVoiceID;
+      pPlayers[uActiveCharacter]->SetCondition(0x11u, 1);
+      pPlayers[uActiveCharacter]->uVoiceID = (pPlayers[uActiveCharacter]->GetSexByVoice() != 0) + 23;
+      pPlayers[uActiveCharacter]->uCurrentFace = (pPlayers[uActiveCharacter]->GetSexByVoice() != 0) + 23;
+      ReloadPlayerPortraits(uActiveCharacter - 1, (pPlayers[uActiveCharacter]->GetSexByVoice() != 0) + 23);
+      LODWORD(pPlayers[uActiveCharacter]->pConditions[17]) = LODWORD(pParty->uTimePlayed);
+      //v39 = (GUIWindow *)HIDWORD(pParty->uTimePlayed);
+    }
+    //HIDWORD(pPlayers[uActiveCharacter]->pConditions[17]) = (int)v39;
+    pPlayers[uActiveCharacter]->pConditions[17] =pParty->uTimePlayed;
+    pAudioPlayer->PlaySound((SoundID)(SOUND_GoldReceived|0x2), -1, 0, -1, 0, 0, 0, 0);
+    pPlayers[uActiveCharacter]->PlaySound(SPEECH_82, 0);
+    pOtherOverlayList->_4418B1(20, uActiveCharacter + 99, 0, 65536);
+    pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
+    return;
+  }
+  //---------------------------------------------------
+  if ( dialog_menu_id == HOUSE_DIALOGUE_TEMPLE_DONATE )
+  {
+    pPrice = p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].fPriceMultiplier;
+    if ( pParty->uNumGold >= (unsigned int)pPrice )
+    {
+      Party::TakeGold((unsigned int)pPrice);
+      v26 = &pOutdoor->ddm;
+      if ( uCurrentlyLoadedLevelType != LEVEL_Outdoor )
+        v26 = &pIndoor->dlv;
+      if ( v26->uReputation > -5 )
+      {
+        v26->uReputation = v26->uReputation - 1;
+        if ( v26->uReputation - 1 < -5 )
+          v26->uReputation = -5;
+      }
+      if ( (unsigned __int8)byte_F8B1EF[uActiveCharacter] == pParty->uDaysPlayed % 7 )
+      {
+        if ( v26->uReputation <= -5 )
         {
-                Party::TakeGold((signed __int64)v24);
-                v26 = &pOutdoor->ddm;
-                if ( uCurrentlyLoadedLevelType != LEVEL_Outdoor )
-                    v26 = &pIndoor->dlv;
-                v27 = v26->uReputation;
-                v66 = v26;
-                if ( v27 > -5 )
-                    {
-                    v28 = v27 - 1;
-                    v26->uReputation = v28;
-                    if ( v28 < -5 )
-                        v26->uReputation = -5;
-                    }
-                if ( (unsigned __int8)byte_F8B1EF[uActiveCharacter] == pParty->uDaysPlayed % 7 )
-                    {
-                    if ( v26->uReputation <= -5 )
-                        {
-                        v30 = pParty->uDaysPlayed % 7 + 1;
-                        LOBYTE(v30) = v30 | 0x80;
-                        _42777D_CastSpell_UseWand_ShootArrow(SPELL_AIR_WIZARD_EYE, uActiveCharacter - 1, v30, 48, 0);
-                        }
-                    if ( v26->uReputation <= -10 )
-                        {
-                        v31 = pParty->uDaysPlayed % 7 + 1;
-                        LOBYTE(v31) = v31 | 0x80;
-                        _42777D_CastSpell_UseWand_ShootArrow(SPELL_SPIRIT_PRESERVATION, uActiveCharacter - 1, v31, 48, 0);
-                        v26 = v66;
-                        }
-                    if ( v26->uReputation <= -15 )
-                        {
-                        v32 = pParty->uDaysPlayed % 7 + 1;
-                        LOBYTE(v32) = v32 | 0x80;
-                        _42777D_CastSpell_UseWand_ShootArrow(SPELL_BODY_PROTECTION_FROM_MAGIC, uActiveCharacter - 1, v32, 48, 0);
-                        v26 = v66;
-                        }
-                    if ( v26->uReputation <= -20 )
-                        {
-                        v33 = pParty->uDaysPlayed % 7 + 1;
-                        LOBYTE(v33) = v33 | 0x80;
-                        _42777D_CastSpell_UseWand_ShootArrow(SPELL_LIGHT_HOUR_OF_POWER, uActiveCharacter - 1, v33, 48, 0);
-                        v26 = v66;
-                        }
-                    if ( v26->uReputation <= -25 )
-                        {
-                        v34 = pParty->uDaysPlayed % 7 + 1;
-                        LOBYTE(v34) = v34 | 0x80;
-                        _42777D_CastSpell_UseWand_ShootArrow(SPELL_LIGHT_DAY_OF_PROTECTION, uActiveCharacter - 1, v34, 48, 0);
-                        }
-                    }
-                ++byte_F8B1EF[uActiveCharacter];
-                v1->PlaySound(SPEECH_83, 0);
-                ShowStatusBarString(pGlobalTXT_LocalizationStrings[527], 2u); // "Thank You!"
-                pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, v25);
-                return;
-          }
-          ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2u);
-          PlayHouseSound((unsigned int)window_SpeakInHouse->ptr_1C, HouseSound_NotEnoughMoney_TrainingSuccessful);
-          pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, v25);
-          return;
+          v30 = pParty->uDaysPlayed % 7 + 1;
+          LOBYTE(v30) = v30 | 0x80;
+          _42777D_CastSpell_UseWand_ShootArrow(SPELL_AIR_WIZARD_EYE, uActiveCharacter - 1, v30, 48, 0);
+        }
+        if ( v26->uReputation <= -10 )
+        {
+          v30 = pParty->uDaysPlayed % 7 + 1;
+          LOBYTE(v30) = v30 | 0x80;
+          _42777D_CastSpell_UseWand_ShootArrow(SPELL_SPIRIT_PRESERVATION, uActiveCharacter - 1, v30, 48, 0);
+        }
+        if ( v26->uReputation <= -15 )
+        {
+          v30 = pParty->uDaysPlayed % 7 + 1;
+          LOBYTE(v30) = v30 | 0x80;
+          _42777D_CastSpell_UseWand_ShootArrow(SPELL_BODY_PROTECTION_FROM_MAGIC, uActiveCharacter - 1, v30, 48, 0);
+        }
+        if ( v26->uReputation <= -20 )
+        {
+          v30 = pParty->uDaysPlayed % 7 + 1;
+          LOBYTE(v30) = v30 | 0x80;
+          _42777D_CastSpell_UseWand_ShootArrow(SPELL_LIGHT_HOUR_OF_POWER, uActiveCharacter - 1, v30, 48, 0);
+        }
+        if ( v26->uReputation <= -25 )
+        {
+          v30 = pParty->uDaysPlayed % 7 + 1;
+          LOBYTE(v30) = v30 | 0x80;
+          _42777D_CastSpell_UseWand_ShootArrow(SPELL_LIGHT_DAY_OF_PROTECTION, uActiveCharacter - 1, v30, 48, 0);
         }
-        if ( !v1->IsPlayerHealableByTemple() )
-            return;
-        v25 = 0;
-        if ( pParty->uNumGold < v2 )
+      }
+      ++byte_F8B1EF[uActiveCharacter];
+      pPlayers[uActiveCharacter]->PlaySound(SPEECH_83, 0);
+      ShowStatusBarString(pGlobalTXT_LocalizationStrings[527], 2); // "Thank You!"
+      pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
+      return;
+    }
+    ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2);//"У вас не хватает золота"
+    PlayHouseSound((unsigned int)window_SpeakInHouse->ptr_1C, HouseSound_NotEnoughMoney_TrainingSuccessful);
+    pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
+    return;
+  }
+  //------------------------------------------------
+  if ( dialog_menu_id == HOUSE_DIALOGUE_LEARN_SKILLS )
+  {
+    if ( HouseUI_CheckIfPlayerCanInteract() )
+    {
+      all_text_height = 0;
+      pCurrentItem = (signed __int64)(p2DEvents[(signed int)window_SpeakInHouse->ptr_1C - 1].flt_24 * 500.0);
+      v64 = (signed int)(pCurrentItem * (100 - pPlayers[uActiveCharacter]->GetMerchant())) / 100;
+      if ( v64 < (signed int)pCurrentItem / 3 )
+        v64 = (signed int)pCurrentItem / 3;
+      pCurrentItem = 0;
+      for ( int i = pDialogueWindow->pStartingPosActiveItem; i < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem; ++i )
+      {
+        if ( byte_4ED970_skill_learn_ability_by_class_table[pPlayers[uActiveCharacter]->classType][pDialogueWindow->GetControl(i)->msg_param - 36]
+         && !pPlayers[uActiveCharacter]->pActiveSkills[pDialogueWindow->GetControl(i)->msg_param - 36] )
         {
-          ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2u);
-          PlayHouseSound((unsigned int)window_SpeakInHouse->ptr_1C, HouseSound_NotEnoughMoney_TrainingSuccessful);
-          pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, v25);
-          return;
+          all_text_height += pFontArrus->CalcTextHeight(pSkillNames[pDialogueWindow->GetControl(i)->msg_param - 36], &tample_window, 0, 0);
+          ++pCurrentItem;
         }
-        Party::TakeGold(v2);
-        v35 = LODWORD(v1->pConditions[17]);
-        v59 = v1->pConditions[14];
-        v58 = v1->pConditions[15];
-        v60 = v1->pConditions[16];
-        v61 = (GUIWindow *)HIDWORD(v1->pConditions[17]);
-        memset(v1, 0, 0xA0u);
-        v1->sHealth = v1->GetMaxHealth();
-        v1->sMana = v1->GetMaxMana();
-        v36 = (signed int)window_SpeakInHouse->ptr_1C;
-        if ( v36 != 78 && (v36 <= 80 || v36 > 82) )
+      }
+      if ( pCurrentItem )
+      {
+        sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[401], v64);
+        tample_window.DrawTitleText(pFontArrus, 0, 0x92u, 0, pTmpBuf.data(), 3);
+        v64 = (149 - (signed int)all_text_height) / (signed int)pCurrentItem;
+        if ( v64 > 32 )
+          v64 = 32;
+        all_text_height = (signed int)(149 - pCurrentItem * v64 - (int)all_text_height) / 2 - v64 / 2 + 162;
+        if ( pDialogueWindow->pStartingPosActiveItem < pDialogueWindow->pStartingPosActiveItem + pDialogueWindow->pNumPresenceButton )
+        {
+          pCurrentItem = 2;
+          for ( int i = pDialogueWindow->pStartingPosActiveItem;
+                    i < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem; ++i )
+          {
+            pButton = pDialogueWindow->GetControl(i);
+            if ( !byte_4ED970_skill_learn_ability_by_class_table[pPlayers[uActiveCharacter]->classType][pButton->msg_param - 36]
+              || pPlayers[uActiveCharacter]->pActiveSkills[pButton->msg_param - 36] )
             {
-            if ( (unsigned int)v61 | v35 )
-                {
-                v37 = LOBYTE(v1->uPrevFace);
-                v38 = v1->uPrevVoiceID;
-                v1->uCurrentFace = v37;
-                v1->uVoiceID = v38;
-                ReloadPlayerPortraits(uActiveCharacter - 1, (char)v37);
-                }
-            pAudioPlayer->PlaySound((SoundID)(SOUND_GoldReceived|0x2), -1, 0, -1, 0, 0, 0, 0);
-            v1->PlaySound(SPEECH_82, 0);
-            pOtherOverlayList->_4418B1(20, uActiveCharacter + 99, 0, 65536);
-            pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, v25);
-            return;
+              pButton->uW = 0;
+              pButton->uHeight = 0;
+              pButton->uY = 0;
             }
-        v39 = v61;
-        if ( (unsigned int)v61 | v35 )
-            {
-            LODWORD(v1->pConditions[17]) = v35;
-            }
-        else
+            else
             {
-            if ( !v60 && !v58 && !v59 )
-            {
-              pAudioPlayer->PlaySound((SoundID)(SOUND_GoldReceived|0x2), -1, 0, -1, 0, 0, 0, 0);
-              v1->PlaySound(SPEECH_82, 0);
-              pOtherOverlayList->_4418B1(20, uActiveCharacter + 99, 0, 65536);
-              pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, v25);
-              return;
+              pButton->uY = v64 + all_text_height;
+              pTextHeight = pFontArrus->CalcTextHeight(pSkillNames[pButton->msg_param - 36], &tample_window, 0, 0);
+              pButton->uHeight = pTextHeight;
+              pButton->uW = pButton->uY + pTextHeight - 1;
+              all_text_height = pButton->uW;
+              pTextColor = TargetColor(0xFFu, 0xFFu, 0x9Bu);
+              if ( pDialogueWindow->pCurrentPosActiveItem != pCurrentItem )
+                pTextColor = TargetColor(0xFFu, 0xFFu, 0xFFu);
+              tample_window.DrawTitleText(pFontArrus, 0, pButton->uY, pTextColor, pSkillNames[pButton->msg_param - 36], 3);
             }
-            v1->uPrevFace = v1->uCurrentFace;
-            v1->uPrevVoiceID = v1->uVoiceID;
-            v1->SetCondition(0x11u, 1);
-            v1->uVoiceID = (v1->GetSexByVoice() != 0) + 23;
-            v40 = (v1->GetSexByVoice() != 0) + 23;
-            v1->uCurrentFace = v40;
-            ReloadPlayerPortraits(uActiveCharacter - 1, (char)v40);
-            LODWORD(v1->pConditions[17]) = LODWORD(pParty->uTimePlayed);
-            v39 = (GUIWindow *)HIDWORD(pParty->uTimePlayed);
-            }
-        HIDWORD(v1->pConditions[17]) = (int)v39;
-        pAudioPlayer->PlaySound((SoundID)(SOUND_GoldReceived|0x2), -1, 0, -1, 0, 0, 0, 0);
-        v1->PlaySound(SPEECH_82, 0);
-        pOtherOverlayList->_4418B1(20, uActiveCharacter + 99, 0, 65536);
-        pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, v25);
-        return; // void func
-        }
-    v63 = 1;
-    v41 = pDialogueWindow->GetControl(pDialogueWindow->pStartingPosActiveItem);
-    strcpy(a1, "");
-    v41->uHeight = 0;
-    v41->uY = 0;
-    if ( v1->IsPlayerHealableByTemple() )
-        {
-        sprintf(a1, "%s %d %s", pGlobalTXT_LocalizationStrings[104], HIDWORD(v60), pGlobalTXT_LocalizationStrings[97]);
-        v63 = 0;
+            pCurrentItem++;
+          }
         }
-    strcpy(&a1[100], pGlobalTXT_LocalizationStrings[68]);
-    strcpy(&a1[200], pGlobalTXT_LocalizationStrings[160]);
-    v42 = v63;
-    v43 = pDialogueWindow;
-    v44 = v63;
-    v66 = 0;
-    if ( v63 < pDialogueWindow->pNumPresenceButton )
-        {
-        v61 = (GUIWindow *)&a1[100 * v63];
-        do
-            {
-            v45 = pFontArrus->CalcTextHeight((const char *)v61, &v57, 0, 0);
-            v66 = (DDM_DLV_Header *)((char *)v66 + v45);
-            v43 = pDialogueWindow;
-            v61 = (GUIWindow *)((char *)v61 + 100);
-            ++v44;
-            }
-            while ( v44 < pDialogueWindow->pNumPresenceButton );
-        }
-    v46 = v43->pNumPresenceButton - v42;
-    v64 = (174 - (signed int)v66) / v46;
-    if ( v64 > 32 )
-        v64 = 32;
-    v47 = (174 - v64 * v46 - (signed int)v66) / 2 - v64 / 2 + 138;
-    v65 = v42 + v43->pStartingPosActiveItem;
-    if ( v42 + v43->pStartingPosActiveItem < v43->pStartingPosActiveItem + v43->pNumPresenceButton )
-        {
-        v61 = (GUIWindow *)(v42 + 2);
-        v66 = (DDM_DLV_Header *)&a1[100 * v42];
-        do
-            {
-            v48 = v43->GetControl(v65);
-            v49 = (const char *)v66;
-            v50 = v48;
-            v48->uY = v64 + v47;
-            v51 = pFontArrus->CalcTextHeight(v49, &v57, 0, 0);
-            v52 = v50->uY;
-            v50->uHeight = v51;
-            v47 = v52 + v51 - 1;
-            v50->uW = v47;
-            v53 = WORD2(v59);
-            if ( (GUIWindow *)pDialogueWindow->pCurrentPosActiveItem != v61 )
-                v53 = WORD2(v58);
-            v57.DrawTitleText(pFontArrus, 0, v52, v53, (const char *)v66, 3u);
-            v43 = pDialogueWindow;
-            v66 = (DDM_DLV_Header *)((char *)v66 + 100);
-            v61 = (GUIWindow *)((char *)v61 + 1);
-            ++v65;
-            }
-            while ( (signed int)v65 < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem );
-        }
-    return;
+      }
+      else
+      {
+        sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[544], pPlayers[uActiveCharacter]->pName, pClassNames[pPlayers[uActiveCharacter]->classType]);//"Советую вам %s %s поискать знания еще где-нибудь"
+        strcat(pTmpBuf.data(), "\n \n");
+        strcat(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[528]);//"Больше ничего не могу предложить."
+        pTextHeight = pFontArrus->CalcTextHeight(pTmpBuf.data(), &tample_window, 0, 0);
+        tample_window.DrawTitleText(pFontArrus, 0, (174 - pTextHeight) / 2 + 138, TargetColor(0xFFu, 0xFFu, 0x9Bu), pTmpBuf.data(), 3);
+      }
     }
+  }
+  return;
+}
 
 //----- (004B4710) --------------------------------------------------------
 void TrainingDialog()
 {
-  //Player *v0; // ebx@1
-  int color2; // eax@1
-  //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
-  int v11; // ecx@6
-  //int result; // eax@9
-  GUIWindow *v13; // edi@14
+  int pPrice; // ecx@6
   signed int v14; // esi@14
   unsigned int v15; // esi@16
   int v16; // eax@16
   unsigned int v17; // eax@17
-  int v18; // eax@19
   int v19; // ecx@24
   GUIButton *v20; // eax@26
   GUIButton *v21; // esi@26
@@ -3335,222 +2995,130 @@
   unsigned int v25; // ecx@28
   int v26; // eax@28
   unsigned __int16 v27; // ax@28
-  //int v28; // eax@32
   unsigned __int16 v29; // ST14_2@34
   int v30; // eax@34
-  //const char *v31; // ST18_4@36
-  //unsigned __int16 v32; // ST14_2@36
   int v33; // eax@36
-  int v34; // eax@37
-  unsigned int v35; // edi@38
   unsigned int v36; // eax@38
-  //int v37; // ecx@41
-  //char *v38; // eax@41
-  //int *v39; // eax@45
-  unsigned int v40; // eax@46
-  //void *v41; // ecx@46
   unsigned int v42; // eax@46
-  GUIWindow *v43; // ecx@59
-  int v44; // edx@59
-  char **v45; // esi@60
-  //int v46; // eax@62
-  int v47; // eax@68
-  //int v48; // edx@69
+  int index;
+  int all_text_height; // eax@68
   int v49; // ebx@69
-  //unsigned __int8 v50; // sf@69
-  char **v51; // edi@70
-  GUIButton *v52; // eax@71
-  GUIButton *v53; // esi@71
-  int v54; // eax@71
-  unsigned int v55; // ecx@71
-  int v56; // eax@71
-  unsigned __int16 v57; // ax@71
-  unsigned __int16 v58; // [sp-Ch] [bp-90h]@38
-  //const char *v59; // [sp-Ch] [bp-90h]@63
-  char *v60; // [sp-8h] [bp-8Ch]@38
-  //char *v61; // [sp-8h] [bp-8Ch]@63
-  unsigned int v62; // [sp-4h] [bp-88h]@38
-  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
-  unsigned int white; // [sp+68h] [bp-1Ch]@1
+  GUIButton *pButton; // eax@71
+  int pTextHeight; // eax@71
+  unsigned __int16 pTextColor; // ax@71
+  GUIWindow training_dialog_window; // [sp+Ch] [bp-78h]@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
-  int v72; // [sp+7Ch] [bp-8h]@16
   int v73; // [sp+80h] [bp-4h]@14
 
-  //v0 = pPlayers[uActiveCharacter];
-  memcpy(&v65, window_SpeakInHouse, sizeof(v65));
-  v65.uFrameX = 483;
-  v65.uFrameWidth = 148;
-  v65.uFrameZ = 334;
-  white = TargetColor(255, 255, 255);
-  color2 = TargetColor(0xE1u, 0xCDu, 0x23u);
-  //v71 = color2;
-  //v2 = v0->uLevel;
-  //v3 = 0;
-  //v4 = 0;
-  //for ( i = v2; v4 < (signed int)v2; ++v4 )
-  //  v3 += v4 + 1;
-  //v5 = 1000 * v3;
+  memcpy(&training_dialog_window, window_SpeakInHouse, sizeof(training_dialog_window));
+  training_dialog_window.uFrameX = 483;
+  training_dialog_window.uFrameWidth = 148;
+  training_dialog_window.uFrameZ = 334;
   v5 = 1000ui64 * pPlayers[uActiveCharacter]->uLevel * (pPlayers[uActiveCharacter]->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 - HOUSE_TRAINING_HALL_EMERALD_ISLE];
-  //v66 = 1000 * v3;
   if (pPlayers[uActiveCharacter]->uExperience >= v5)
   {
     v8 = pPlayers[uActiveCharacter]->classType % 4 + 1;
     if ( v8 == 4 )
       v8 = 3;
     v9 = (double)pPlayers[uActiveCharacter]->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)window_SpeakInHouse->ptr_1C - 1].fPriceMultiplier * (double)v8);
-    v11 = v10 * (100 - pPlayers[uActiveCharacter]->GetMerchant()) / 100;
-    if ( v11 < v10 / 3 )
-      v11 = v10 / 3;
-    //i = v11;
+    pPrice = v10 * (100 - pPlayers[uActiveCharacter]->GetMerchant()) / 100;
+    if ( pPrice < v10 / 3 )
+      pPrice = v10 / 3;
   }
-
+//-------------------------------------------------------
+  all_text_height = 0;
   if (HouseUI_CheckIfPlayerCanInteract())
   {
-    if ( dialog_menu_id != HOUSE_DIALOGUE_MAIN )
+    if ( dialog_menu_id == HOUSE_DIALOGUE_MAIN )
     {
-      if ( dialog_menu_id != HOUSE_DIALOGUE_TRAININGHALL_TRAIN )
+      if (HouseUI_CheckIfPlayerCanInteract())
       {
-        if ( dialog_menu_id == HOUSE_DIALOGUE_LEARN_SKILLS )
+        index = 0;
+        pShopOptions[0] = pTmpBuf.data();
+        pShopOptions[1] = pGlobalTXT_LocalizationStrings[160];// "Learn Skills"
+        if ( pDialogueWindow->pStartingPosActiveItem < pDialogueWindow->pStartingPosActiveItem + pDialogueWindow->pNumPresenceButton )
         {
-          if (HouseUI_CheckIfPlayerCanInteract())
+          for ( int i = pDialogueWindow->pStartingPosActiveItem;
+                i < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem; ++i )
           {
-            //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);
-            v73 = v14 * (100 - pPlayers[uActiveCharacter]->GetMerchant()) / 100;
-            if ( v73 < v14 / 3 )
-              v73 = v14 / 3;
-            v15 = v13->pStartingPosActiveItem;
-            v16 = v13->pNumPresenceButton;
-            v72 = 0;
-            if ( (signed int)v15 >= (signed int)(v15 + v16) )
-              goto LABEL_76;
-            do
-            {
-              v17 = v13->GetControl(v15)->msg_param - 36;
-              if ( byte_4ED970_skill_learn_ability_by_class_table[pPlayers[uActiveCharacter]->classType][v17] && !pPlayers[uActiveCharacter]->pActiveSkills[v17] )
-              {
-                v18 = pFontArrus->CalcTextHeight(pSkillNames[v17], &v65, 0, 0);
-                _v0 += v18;
-                ++v72;
-              }
-              ++v15;
-            }
-            while ( (signed int)v15 < v13->pNumPresenceButton + v13->pStartingPosActiveItem );
-            if ( v72 )
+            if ( pDialogueWindow->GetControl(i)->msg_param == HOUSE_DIALOGUE_TRAININGHALL_TRAIN )
             {
-              sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[401], v73);// "Skill Cost: %lu"
-              v65.DrawTitleText(pFontArrus, 0, 0x92u, 0, pTmpBuf.data(), 3u);
-              v73 = (signed int)(149 - _v0) / v72;
-              if ( v73 > 32 )
-                v73 = 32;
-              //result = v13->pStartingPosActiveItem;
-              v19 = (signed int)(149 - v72 * v73 - _v0) / 2 - v73 / 2 + 162;
-              int _v1 = v13->pStartingPosActiveItem;
-              v68 = v19;
-              if (v13->pStartingPosActiveItem < v13->pStartingPosActiveItem + v13->pNumPresenceButton )
+              if (pPlayers[uActiveCharacter]->uLevel >= v68)
+                sprintfex(pShopOptions[index], "%s\n \n%s", pGlobalTXT_LocalizationStrings[536], pGlobalTXT_LocalizationStrings[529]); //"With your skills, you should be working here as a teacher."    "Sorry, but we are unable to train you."
+              else
               {
-                v72 = 2;
-                do
-                {
-                  v20 = v13->GetControl(_v1);
-                  v21 = v20;
-                  v22 = v20->msg_param - 36;
-                  if ( !byte_4ED970_skill_learn_ability_by_class_table[pPlayers[uActiveCharacter]->classType][v22] || pPlayers[uActiveCharacter]->pActiveSkills[v22] )
-                  {
-                    v21->uW = 0;
-                    v21->uHeight = 0;
-                    v21->uY = 0;
-                  }
-                  else
-                  {
-                    v23 = pSkillNames[v22];
-                    v21->uY = v73 + v68;
-                    //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 = color2;
-                    if ( pDialogueWindow->pCurrentPosActiveItem != v72 )
-                      v27 = white;
-                    v65.DrawTitleText(pFontArrus, 0, v25, v27, v23, 3u);
-                  }
-                  ++_v1;
-                  ++v72;
-                }
-                while ( (signed int)_v1 < v13->pStartingPosActiveItem + v13->pNumPresenceButton );
+                if (pPlayers[uActiveCharacter]->uExperience < v5)
+                  sprintfex(pShopOptions[index], pGlobalTXT_LocalizationStrings[538], (uint)(v5 - pPlayers[uActiveCharacter]->uExperience), pPlayers[uActiveCharacter]->uLevel + 1); // "You need %d more experience to train to level %d"
+                else
+                  sprintfex(pShopOptions[index], pGlobalTXT_LocalizationStrings[537], pPlayers[uActiveCharacter]->uLevel + 1, pPrice); // "Train to level %d for %d gold"
               }
             }
-            else
-            {
-LABEL_76:
-              sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[544], pPlayers[uActiveCharacter]->pName, pClassNames[pPlayers[uActiveCharacter]->classType]);// 
-                                                // "Seek knowledge elsewhere %s the %s"
-              strcat(pTmpBuf.data(), "\n \n");
-              strcat(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[528]);// "I can offer you nothing further."
-              v29 = color2;
-              v30 = pFontArrus->CalcTextHeight(pTmpBuf.data(), &v65, 0, 0);
-              v65.DrawTitleText(pFontArrus, 0, (174 - v30) / 2 + 138, v29, pTmpBuf.data(), 3u);
-            }
+            all_text_height += pFontArrus->CalcTextHeight(pShopOptions[index], &training_dialog_window, 0, 0);
+            ++index;
           }
         }
-        return;
+        v49 = (2 * (87 - (174 - all_text_height) / 2) - all_text_height) / 2 - (174 - all_text_height) / 2 / 2 + 138;
+        if (pDialogueWindow->pStartingPosActiveItem < pDialogueWindow->pStartingPosActiveItem + pDialogueWindow->pNumPresenceButton)
+        {
+          int pCurrentItem = 2;
+          index = 0;
+          for ( int i = pDialogueWindow->pStartingPosActiveItem;
+                i < pDialogueWindow->pStartingPosActiveItem + pDialogueWindow->pNumPresenceButton; ++i )
+          {
+            pButton = pDialogueWindow->GetControl(i);
+            pButton->uY = (174 - all_text_height) / 2 + v49;
+            pTextHeight = pFontArrus->CalcTextHeight(pShopOptions[index], &training_dialog_window, 0, 0);
+            pButton->uHeight = pTextHeight;
+            pButton->uW = pTextHeight + pButton->uY - 1;
+            v49 = pButton->uW;
+            pTextColor = TargetColor(0xE1u, 0xCDu, 0x23u);
+            if ( pDialogueWindow->pCurrentPosActiveItem != pCurrentItem )
+              pTextColor = TargetColor(255, 255, 255);
+            training_dialog_window.DrawTitleText(pFontArrus, 0, pButton->uY, pTextColor, pShopOptions[index], 3);
+            ++pCurrentItem;
+            ++index;
+          }
+        }
       }
+    }
+//------------------------------------------------------------------
+    if ( dialog_menu_id == HOUSE_DIALOGUE_TRAININGHALL_TRAIN )
+    {
       if ( !HouseUI_CheckIfPlayerCanInteract() )
       {
-        //v31 = pNPCTopics[122].pText;
-        //v32 = color2;
-        v33 = pFontArrus->CalcTextHeight(pNPCTopics[122].pText, &v65, 0, 0);
-        v65.DrawTitleText(pFontArrus, 0, (212 - v33) / 2 + 101, color2, pNPCTopics[122].pText, 3);
+        v33 = pFontArrus->CalcTextHeight(pNPCTopics[122].pText, &training_dialog_window, 0, 0);
+        training_dialog_window.DrawTitleText(pFontArrus, 0, (212 - v33) / 2 + 101, TargetColor(0xE1u, 0xCDu, 0x23u), pNPCTopics[122].pText, 3);
         pDialogueWindow->pNumPresenceButton = 0;
         return;
       }
-      v34 = pPlayers[uActiveCharacter]->uLevel;
-      if ( v34 < v68 )
+      //v34 = pPlayers[uActiveCharacter]->uLevel;
+      if ( pPlayers[uActiveCharacter]->uLevel < v68 )
       {
         if ( (signed __int64)pPlayers[uActiveCharacter]->uExperience >= v5 )
         {
-          if ( pParty->uNumGold >= v11)
+          if ( pParty->uNumGold >= pPrice)
           {
-            Party::TakeGold(v11);
+            Party::TakeGold(pPrice);
             PlayHouseSound((unsigned int)window_SpeakInHouse->ptr_1C, HouseSound_NotEnoughMoney_TrainingSuccessful);
             ++pPlayers[uActiveCharacter]->uLevel;
             pPlayers[uActiveCharacter]->uSkillPoints += pPlayers[uActiveCharacter]->uLevel / 10 + 5;
             pPlayers[uActiveCharacter]->sHealth = pPlayers[uActiveCharacter]->GetMaxHealth();
             pPlayers[uActiveCharacter]->sMana = pPlayers[uActiveCharacter]->GetMaxMana();
-
             uint max_level_in_party = player_levels[0];
             for (uint _it = 1; _it < 4; ++_it)
             {
               if (player_levels[_it] > max_level_in_party)
                 max_level_in_party = player_levels[_it];
             }
-
             ++player_levels[uActiveCharacter - 1];
             if (player_levels[uActiveCharacter - 1] > max_level_in_party) // if we reach new maximum party level
                                                                           // feature is broken thou, since this array is always zeroed in EnterHouse
             {
-              v40 = _494820_training_time(pParty->uCurrentHour);
-              //v41 = window_SpeakInHouse->ptr_1C;
-              v42 = 60 * (v40 + 4) - pParty->uCurrentMinute;
+              v42 = 60 * (_494820_training_time(pParty->uCurrentHour) + 4) - pParty->uCurrentMinute;
               if ((unsigned int)window_SpeakInHouse->ptr_1C == HOUSE_TRAINING_HALL_94 ||
                   (unsigned int)window_SpeakInHouse->ptr_1C == HOUSE_TRAINING_HALL_95)
                 v42 += 720;
@@ -3566,115 +3134,112 @@
             return;
           }
           ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2);// "You don't have enough gold"
-          v63 = 4;
-LABEL_55:
-          PlayHouseSound((unsigned int)window_SpeakInHouse->ptr_1C, (HouseSoundID)v63);
-//LABEL_56:
-          /*result = pMessageQueue_50CBD0->uNumMessages;
-          if ( (signed int)pMessageQueue_50CBD0->uNumMessages < 40 )
-          {
-            pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].eType = UIMSG_Escape;
-            pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = 1;
-            result = 3 * pMessageQueue_50CBD0->uNumMessages + 3;
-            *(&pMessageQueue_50CBD0->uNumMessages + result) = 0;
-            ++pMessageQueue_50CBD0->uNumMessages;
-          }
-          return result;*/
+          PlayHouseSound((unsigned int)window_SpeakInHouse->ptr_1C, (HouseSoundID)4);
           pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
           return;
         }
-        sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[538], (unsigned int)(v5 - pPlayers[uActiveCharacter]->uExperience), v34 + 1);// 
+        sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[538], (unsigned int)(v5 - pPlayers[uActiveCharacter]->uExperience), pPlayers[uActiveCharacter]->uLevel + 1);// 
                                                 // "You need %d more experience to train to level %d"
-        v35 = 0;
-        v62 = 3;
-        v60 = pTmpBuf.data();
-        v58 = color2;
-        v36 = (212 - pFontArrus->CalcTextHeight(pTmpBuf.data(), &v65, 0, 0)) / 2 + 88;
+        v36 = (212 - pFontArrus->CalcTextHeight(pTmpBuf.data(), &training_dialog_window, 0, 0)) / 2 + 88;
       }
       else
       {
         sprintf(pTmpBuf.data(), "%s\n \n%s", pGlobalTXT_LocalizationStrings[536], pGlobalTXT_LocalizationStrings[529]);// 
                                                 // ""With your skills, you should be working here as a teacher.""
                                                 // ""Sorry, but we are unable to train you.""
-        v35 = 0;
-        v62 = 3;
-        v60 = pTmpBuf.data();
-        v58 = color2;
-        v36 = (212 - pFontArrus->CalcTextHeight(pTmpBuf.data(), &v65, 0, 0)) / 2 + 101;
+        v36 = (212 - pFontArrus->CalcTextHeight(pTmpBuf.data(), &training_dialog_window, 0, 0)) / 2 + 101;
       }
-      v65.DrawTitleText(pFontArrus, v35, v36, v58, v60, v62);
-      v63 = 3;
-      goto LABEL_55;
+      training_dialog_window.DrawTitleText(pFontArrus, 0, v36, TargetColor(0xE1u, 0xCDu, 0x23u), pTmpBuf.data(), 3);
+      PlayHouseSound((unsigned int)window_SpeakInHouse->ptr_1C, (HouseSoundID)3);
+      pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
+      return;
     }
-
+  }
+//-------------------------------------------------------------
+  if ( dialog_menu_id == HOUSE_DIALOGUE_LEARN_SKILLS )
+  {
     if (HouseUI_CheckIfPlayerCanInteract())
     {
-      v43 = pDialogueWindow;
-      v72 = 0;
-      pShopOptions[0] = pTmpBuf.data();
-      pShopOptions[1] = pGlobalTXT_LocalizationStrings[160];// "Learn Skills"
-      v44 = pDialogueWindow->pNumPresenceButton;
-      v73 = pDialogueWindow->pStartingPosActiveItem;
-      if ( v73 < v73 + v44 )
+      v14 = (signed __int64)(p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].flt_24 * 500.0);
+      v73 = v14 * (100 - pPlayers[uActiveCharacter]->GetMerchant()) / 100;
+      if ( v73 < v14 / 3 )
+        v73 = v14 / 3;
+      v15 = pDialogueWindow->pStartingPosActiveItem;
+      v16 = pDialogueWindow->pNumPresenceButton;
+      index = 0;
+      if ( (signed int)v15 >= (signed int)(v15 + v16) )
+        goto LABEL_76;
+      do
+      {
+        v17 = pDialogueWindow->GetControl(v15)->msg_param - 36;
+        if ( byte_4ED970_skill_learn_ability_by_class_table[pPlayers[uActiveCharacter]->classType][v17] && !pPlayers[uActiveCharacter]->pActiveSkills[v17] )
+        {
+          all_text_height += pFontArrus->CalcTextHeight(pSkillNames[v17], &training_dialog_window, 0, 0);
+          ++index;
+        }
+        ++v15;
+      }
+      while ( (signed int)v15 < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem );
+      if ( index )
       {
-        v45 = pShopOptions.data();
-        do
+        sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[401], v73);// "Skill Cost: %lu"
+        training_dialog_window.DrawTitleText(pFontArrus, 0, 0x92u, 0, pTmpBuf.data(), 3);
+        v73 = (signed int)(149 - all_text_height) / index;
+        if ( v73 > 32 )
+          v73 = 32;
+        v19 = (signed int)(149 - index * v73 - all_text_height) / 2 - v73 / 2 + 162;
+        int _v1 = pDialogueWindow->pStartingPosActiveItem;
+        v68 = v19;
+        if (pDialogueWindow->pStartingPosActiveItem < pDialogueWindow->pStartingPosActiveItem + pDialogueWindow->pNumPresenceButton )
         {
-          if ( v43->GetControl(v73)->msg_param == HOUSE_DIALOGUE_TRAININGHALL_TRAIN )
+          index = 2;
+          do
           {
-            //v46 = pPlayers[uActiveCharacter]->uLevel;
-            if (pPlayers[uActiveCharacter]->uLevel >= v68)
-              sprintfex(*v45, "%s\n \n%s",
-                        pGlobalTXT_LocalizationStrings[536], pGlobalTXT_LocalizationStrings[529]); //"With your skills, you should be working here as a teacher."    "Sorry, but we are unable to train you."
+            v20 = pDialogueWindow->GetControl(_v1);
+            v21 = v20;
+            v22 = v20->msg_param - 36;
+            if ( !byte_4ED970_skill_learn_ability_by_class_table[pPlayers[uActiveCharacter]->classType][v22] || pPlayers[uActiveCharacter]->pActiveSkills[v22] )
+            {
+              v21->uW = 0;
+              v21->uHeight = 0;
+              v21->uY = 0;
+            }
             else
             {
-              if (pPlayers[uActiveCharacter]->uExperience < v5)
-                sprintfex(*v45, pGlobalTXT_LocalizationStrings[538],  // "You need %d more experience to train to level %d"
-                          (uint)(v5 - pPlayers[uActiveCharacter]->uExperience), pPlayers[uActiveCharacter]->uLevel + 1);
-              else
-                sprintfex(*v45, pGlobalTXT_LocalizationStrings[537],  // "Train to level %d for %d gold"
-                          pPlayers[uActiveCharacter]->uLevel + 1, v11);
+              v23 = pSkillNames[v22];
+              v21->uY = v73 + v68;
+              //HIDWORD(v66) = (int)v23;
+              v24 = pFontArrus->CalcTextHeight(v23, &training_dialog_window, 0, 0);
+              v25 = v21->uY;
+              v21->uHeight = v24;
+              v26 = v25 + v24 - 1;
+              v21->uW = v26;
+              v68 = v26;
+              v27 = TargetColor(0xE1u, 0xCDu, 0x23u);
+              if ( pDialogueWindow->pCurrentPosActiveItem != index )
+                v27 = TargetColor(255, 255, 255);
+              training_dialog_window.DrawTitleText(pFontArrus, 0, v25, v27, v23, 3);
             }
+            ++_v1;
+            ++index;
           }
-          v47 = pFontArrus->CalcTextHeight(*v45, &v65, 0, 0);
-          v43 = pDialogueWindow;
-          v72 += v47;
-          ++v45;
-          ++v73;
+          while ( (signed int)_v1 < pDialogueWindow->pStartingPosActiveItem + pDialogueWindow->pNumPresenceButton );
         }
-        while ( v73 < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem );
       }
-
-      v49 = (2 * (87 - (174 - v72) / 2) - v72) / 2 - (174 - v72) / 2 / 2 + 138;
-      v73 = v43->pStartingPosActiveItem;
-      if (v43->pStartingPosActiveItem < v43->pStartingPosActiveItem + v43->pNumPresenceButton)
+      else
       {
-        int _v3 = 2;
-        v51 = pShopOptions.data();
-        do
-        {
-          v52 = v43->GetControl(v73);
-          v53 = v52;
-          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 = color2;
-          if ( pDialogueWindow->pCurrentPosActiveItem != _v3 )
-            v57 = white;
-          v65.DrawTitleText(pFontArrus, 0, v55, v57, *v51, 3u);
-          v43 = pDialogueWindow;
-          ++_v3;
-          ++v51;
-          ++v73;
-        }
-        while ( v73 < pDialogueWindow->pStartingPosActiveItem + pDialogueWindow->pNumPresenceButton);
+LABEL_76:
+        sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[544], pPlayers[uActiveCharacter]->pName, pClassNames[pPlayers[uActiveCharacter]->classType]);// 
+                                              // "Seek knowledge elsewhere %s the %s"
+        strcat(pTmpBuf.data(), "\n \n");
+        strcat(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[528]);// "I can offer you nothing further."
+        v29 = TargetColor(0xE1u, 0xCDu, 0x23u);
+        v30 = pFontArrus->CalcTextHeight(pTmpBuf.data(), &training_dialog_window, 0, 0);
+        training_dialog_window.DrawTitleText(pFontArrus, 0, (174 - v30) / 2 + 138, v29, pTmpBuf.data(), 3);
       }
     }
   }
+  return;
 }
 
 //----- (004B6478) --------------------------------------------------------
@@ -3902,8 +3467,6 @@
   int v38; // eax@52
   signed int v39; // ecx@54
   int v40; // edi@57
-  GUIButton *v41; // eax@60
-  GUIButton *v42; // esi@60
   const char *v43; // ebx@60
   int v44; // eax@60
   unsigned int v45; // ecx@60
@@ -4116,15 +3679,15 @@
     v40 = (174 - (signed int)pNPC * v39 - v34) / 2 - (signed int)pNPC / 2 + 138;
     for ( i = pDialogueWindow->pStartingPosActiveItem; i < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem; ++i )
     {
-      v41 = pDialogueWindow->GetControl(i);
-      v42 = v41;
-      v43 = v41->pButtonName;
-      v41->uY = (unsigned int)((char *)pNPC + v40);
-      v44 = pFontArrus->CalcTextHeight(v41->pButtonName, &v52, 0, 0);
-      v45 = v42->uY;
-      v42->uHeight = v44;
+      pButton = pDialogueWindow->GetControl(i);
+      //v42 = v41;
+      v43 = pButton->pButtonName;
+      pButton->uY = (unsigned int)((char *)pNPC + v40);
+      v44 = pFontArrus->CalcTextHeight(pButton->pButtonName, &v52, 0, 0);
+      v45 = pButton->uY;
+      pButton->uHeight = v44;
       v40 = v45 + v44 - 1;
-      v42->uW = v40;
+      pButton->uW = v40;
       v46 = TargetColor(0xE1u, 0xCDu, 0x23u);
       if ( (char *)pDialogueWindow->pCurrentPosActiveItem != pInString )
         v46 = TargetColor(0xFFu, 0xFFu, 0xFFu);
@@ -4152,19 +3715,12 @@
 //----- (004B4F4F) --------------------------------------------------------
 void JailDialog()
 {
-  const char *v0; // esi@1
-  const char *v1; // ST10_4@1
-  unsigned __int16 v2; // ST0C_2@1
-  int v3; // eax@1
-  GUIWindow v5; // [sp+8h] [bp-54h]@1
+  GUIWindow jail_dialogue_window; // [sp+8h] [bp-54h]@1
 
-  memcpy(&v5, window_SpeakInHouse, sizeof(v5));
-  v0 = pGlobalTXT_LocalizationStrings[672];
-  v1 = pGlobalTXT_LocalizationStrings[672];
-  v5.uFrameX = 483;
-  v5.uFrameWidth = 148;
-  v5.uFrameZ = 334;
-  v2 = TargetColor(0xFFu, 0xFFu, 0x9Bu);
-  v3 = pFontArrus->CalcTextHeight(v0, &v5, 0, 0);
-  v5.DrawTitleText(pFontArrus, 0, (310 - v3) / 2 + 18, v2, v1, 3u);
+  memcpy(&jail_dialogue_window, window_SpeakInHouse, sizeof(jail_dialogue_window));
+  jail_dialogue_window.uFrameX = 483;
+  jail_dialogue_window.uFrameWidth = 148;
+  jail_dialogue_window.uFrameZ = 334;
+  jail_dialogue_window.DrawTitleText(pFontArrus, 0, (310 - pFontArrus->CalcTextHeight(pGlobalTXT_LocalizationStrings[672], &jail_dialogue_window, 0, 0)) / 2 + 18,
+     TargetColor(0xFFu, 0xFFu, 0x9Bu), pGlobalTXT_LocalizationStrings[672], 3);
 }
\ No newline at end of file
--- a/UI/UIHouses.h	Tue Sep 17 12:37:07 2013 +0200
+++ b/UI/UIHouses.h	Tue Sep 17 12:40:37 2013 +0200
@@ -56,21 +56,21 @@
   HOUSE_ALCHEMIST_HARMONDALE = 43,
   HOUSE_STABLES_HARMONDALE = 54,
   HOUSE_STABLES_STEADWICK = 55,
-  HOUSE_STABLES_56 = 56,
-  HOUSE_STABLES_57 = 57,
-  HOUSE_STABLES_58 = 58,
-  HOUSE_STABLES_59 = 59,
-  HOUSE_STABLES_60 = 60,
+  HOUSE_STABLES_TULAREAN_FOREST = 56,
+  HOUSE_STABLES_DEYJA = 57,
+  HOUSE_STABLES_BRACADA_DESERT = 58,
+  HOUSE_STABLES_TATALIA = 59,
+  HOUSE_STABLES_AVLEE = 60,
   HOUSE_STABLES_61 = 61,
   HOUSE_STABLES_62 = 62,
-  HOUSE_BOATS_63 = 63,
-  HOUSE_BOATS_64 = 64,
-  HOUSE_BOATS_65 = 65,
-  HOUSE_BOATS_66 = 66,
-  HOUSE_BOATS_67 = 67,
+  HOUSE_BOATS_EMERALD_ISLE = 63,
+  HOUSE_BOATS_ERATHIA = 64,
+  HOUSE_BOATS_TULAREAN_FOREST = 65,
+  HOUSE_BOATS_BRACADA_DESERT = 66,
+  HOUSE_BOATS_EVENMORN_ISLAND = 67,
   HOUSE_BOATS_68 = 68,
-  HOUSE_BOATS_69 = 69,
-  HOUSE_BOATS_70 = 70,
+  HOUSE_BOATS_TATALIA = 69,
+  HOUSE_BOATS_AVLEE = 70,
   HOUSE_BOATS_71 = 71,
   HOUSE_BOATS_72 = 72,
   HOUSE_BOATS_73 = 73,
--- a/UI/UIPopup.cpp	Tue Sep 17 12:37:07 2013 +0200
+++ b/UI/UIPopup.cpp	Tue Sep 17 12:40:37 2013 +0200
@@ -439,12 +439,12 @@
         else if ( inspect_item->uEnchantmentType )
             {
             sprintf(out_text + 200, "%s: %s +%d", pGlobalTXT_LocalizationStrings[210],
-                pItemsTable->pEnchantments[inspect_item->uEnchantmentType-1].pBonusStat, inspect_item->_bonus_strength); //"Special"
+                pItemsTable->pEnchantments[inspect_item->uEnchantmentType-1].pBonusStat, inspect_item->m_enchantmentStrength); //"Special"
             }
         else  if ( inspect_item->uSpecEnchantmentType )
             {      
             sprintf(out_text + 200, "%s: %s", pGlobalTXT_LocalizationStrings[210], 
-                pItemsTable->pSpecialEnchantments[inspect_item->uSpecEnchantmentType-1].pBonusStatement, inspect_item->_bonus_strength);
+                pItemsTable->pSpecialEnchantments[inspect_item->uSpecEnchantmentType-1].pBonusStatement, inspect_item->m_enchantmentStrength);
             }
 
         else if ( inspect_item->uNumCharges )
--- a/UI/UiGame.cpp	Tue Sep 17 12:37:07 2013 +0200
+++ b/UI/UiGame.cpp	Tue Sep 17 12:40:37 2013 +0200
@@ -348,7 +348,7 @@
   int pTextHeight; // esi@39
   GUIButton *pButton; // eax@43
   int v32; // ebx@93
-  uint v35; // esi@93
+  //uint v35; // esi@93
   int v38; // eax@95
   signed int v39; // esi@99
   signed int v40; // eax@102
@@ -599,15 +599,15 @@
 
   // Install Buttons(Установка кнопок)-------- 
   v32 = 0;
-  v35 = (uint)pDialogueWindow->pStartingPosActiveItem;
-  for ( uint i = v35 + pDialogueWindow->pNumPresenceButton; v35 < i; i = pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem )
+  //v35 = (uint)pDialogueWindow->pStartingPosActiveItem;
+  for ( int i = pDialogueWindow->pStartingPosActiveItem; i < pDialogueWindow->pStartingPosActiveItem + pDialogueWindow->pNumPresenceButton; ++i )
   {
-    pButton = pDialogueWindow->GetControl(v35);
+    pButton = pDialogueWindow->GetControl(i);
     if ( !pButton )
       break;
     v38 = pFontArrus->CalcTextHeight(pButton->pButtonName, &window, 0, 0);
     v32 += v38;
-    ++v35;
+    //++v35;
   }
   v39 = pDialogueWindow->pNumPresenceButton;
   if ( v39 )
@@ -1742,9 +1742,9 @@
         pRenderer->_4A6E7E(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i], 388, pPortrait);
       else
         pRenderer->DrawTextureTransparent(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i] + 1, 388, pPortrait);
-      if ( pPlayer->pPlayerBuffs[PLAYER_BUFF_BLESS].uExpireTime | pPlayer->pPlayerBuffs[PLAYER_BUFF_7].uExpireTime
-         | pPlayer->pPlayerBuffs[PLAYER_BUFF_8].uExpireTime | pPlayer->pPlayerBuffs[PLAYER_BUFF_13].uExpireTime
-         | pPlayer->pPlayerBuffs[PLAYER_BUFF_14].uExpireTime )
+      if ( pPlayer->pPlayerBuffs[PLAYER_BUFF_BLESS].uExpireTime | pPlayer->pPlayerBuffs[PLAYER_BUFF_HASTE].uExpireTime
+         | pPlayer->pPlayerBuffs[PLAYER_BUFF_HEROISM].uExpireTime | pPlayer->pPlayerBuffs[PLAYER_BUFF_13].uExpireTime
+         | pPlayer->pPlayerBuffs[PLAYER_BUFF_STONESKIN].uExpireTime )
         sub_441A4E(i);
       continue;
     }
@@ -1755,9 +1755,9 @@
         pRenderer->_4A6E7E(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i], 388, pPortrait);
       else
         pRenderer->DrawTextureTransparent(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i] + 1, 388, pPortrait);
-      if ( pPlayer->pPlayerBuffs[PLAYER_BUFF_BLESS].uExpireTime | pPlayer->pPlayerBuffs[PLAYER_BUFF_7].uExpireTime
-         | pPlayer->pPlayerBuffs[PLAYER_BUFF_8].uExpireTime | pPlayer->pPlayerBuffs[PLAYER_BUFF_13].uExpireTime
-         | pPlayer->pPlayerBuffs[PLAYER_BUFF_14].uExpireTime )
+      if ( pPlayer->pPlayerBuffs[PLAYER_BUFF_BLESS].uExpireTime | pPlayer->pPlayerBuffs[PLAYER_BUFF_HASTE].uExpireTime
+         | pPlayer->pPlayerBuffs[PLAYER_BUFF_HEROISM].uExpireTime | pPlayer->pPlayerBuffs[PLAYER_BUFF_13].uExpireTime
+         | pPlayer->pPlayerBuffs[PLAYER_BUFF_STONESKIN].uExpireTime )
         sub_441A4E(i);
       continue;
     }
@@ -1782,9 +1782,9 @@
         pRenderer->_4A6E7E(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i], 388, pPortrait);
       else
         pRenderer->DrawTextureTransparent(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i] + 1, 388, pPortrait);
-      if ( pPlayer->pPlayerBuffs[PLAYER_BUFF_BLESS].uExpireTime | pPlayer->pPlayerBuffs[PLAYER_BUFF_7].uExpireTime
-         | pPlayer->pPlayerBuffs[PLAYER_BUFF_8].uExpireTime | pPlayer->pPlayerBuffs[PLAYER_BUFF_13].uExpireTime
-         | pPlayer->pPlayerBuffs[PLAYER_BUFF_14].uExpireTime )
+      if ( pPlayer->pPlayerBuffs[PLAYER_BUFF_BLESS].uExpireTime | pPlayer->pPlayerBuffs[PLAYER_BUFF_HASTE].uExpireTime
+         | pPlayer->pPlayerBuffs[PLAYER_BUFF_HEROISM].uExpireTime | pPlayer->pPlayerBuffs[PLAYER_BUFF_13].uExpireTime
+         | pPlayer->pPlayerBuffs[PLAYER_BUFF_STONESKIN].uExpireTime )
         sub_441A4E(i);
       continue;
     }
--- a/mm7_1.cpp	Tue Sep 17 12:37:07 2013 +0200
+++ b/mm7_1.cpp	Tue Sep 17 12:40:37 2013 +0200
@@ -65,6 +65,14 @@
 {
   return ((__int64)a1 * (__int64)a2) >> 16;
 }
+__int64 fixpoint_sub2(int a1, int a2)
+{
+  signed __int64 v3; // qtt@1
+
+  LODWORD(v3) = a1 << 16;
+  HIDWORD(v3) = a1 >> 16;
+  return v3 / a2;
+}
 
 __int64 fixpoint_dot(int x1, int x2, int y1, int y2, int z1, int z2)
 {
--- a/mm7_2.cpp	Tue Sep 17 12:37:07 2013 +0200
+++ b/mm7_2.cpp	Tue Sep 17 12:40:37 2013 +0200
@@ -577,9 +577,6 @@
 int sub_4BD8B5()
 {
   int v0; // eax@4
-  int v1; // eax@29
-  unsigned int v2; // esi@30
-  //const char *v3; // ebx@31
 
   if ( pMessageQueue_50CBD0->uNumMessages )
     pMessageQueue_50CBD0->uNumMessages = pMessageQueue_50CBD0->pMessages[0].field_8 != 0;
@@ -590,12 +587,9 @@
   if ( pDialogueNPCCount )
   {
     v0 = dialog_menu_id;
-    if ( dialog_menu_id != HOUSE_DIALOGUE_SHOP_BUY_STANDARD
-      && dialog_menu_id != HOUSE_DIALOGUE_SHOP_SELL
-      && dialog_menu_id != HOUSE_DIALOGUE_97
-      && dialog_menu_id != HOUSE_DIALOGUE_SHOP_REPAIR
-      && dialog_menu_id != HOUSE_DIALOGUE_SHOP_IDENTIFY
-      && ShopTexture )
+    if ( dialog_menu_id != HOUSE_DIALOGUE_SHOP_BUY_STANDARD && dialog_menu_id != HOUSE_DIALOGUE_SHOP_SELL
+      && dialog_menu_id != HOUSE_DIALOGUE_97 && dialog_menu_id != HOUSE_DIALOGUE_SHOP_REPAIR
+      && dialog_menu_id != HOUSE_DIALOGUE_SHOP_IDENTIFY && ShopTexture )
     {
       ShopTexture->Release();
       v0 = dialog_menu_id;
@@ -644,23 +638,17 @@
     dialog_menu_id = HOUSE_DIALOGUE_NULL;
     pDialogueWindow = 0;
     pIcons_LOD->SyncLoadedFilesCount();
-    v1 = uNumDialogueNPCPortraits;
     if ( uNumDialogueNPCPortraits != 1 )
     {
-      v2 = 0;
       pBtn_ExitCancel = window_SpeakInHouse->pControlsHead;
       if ( uNumDialogueNPCPortraits > 0 )
       {
-        //v3 = byte_591180;
-        do
+        for ( uint i = 0; i < (unsigned int)uNumDialogueNPCPortraits; ++i )
         {
-          dword_5913F4[v2] = window_SpeakInHouse->CreateButton(pNPCPortraits_x[v1 - 1][v2], pNPCPortraits_y[v1 - 1][v2],
-                                              0x3Fu, 0x49u, 1, 0, UIMSG_ClickHouseNPCPortrait, v2, 0, byte_591180[v2].data(), 0, 0, 0);
-          v1 = uNumDialogueNPCPortraits;
-          ++v2;
-          //v3 += 100;
+          HouseNPCPortraitsButtonsList[i] = window_SpeakInHouse->CreateButton(pNPCPortraits_x[uNumDialogueNPCPortraits - 1][i],
+                                                                              pNPCPortraits_y[uNumDialogueNPCPortraits - 1][i],
+                                              63, 73, 1, 0, UIMSG_ClickHouseNPCPortrait, i, 0, byte_591180[i].data(), 0, 0, 0);
         }
-        while ( (signed int)v2 < uNumDialogueNPCPortraits );
       }
       pVideoPlayer->_4BF5B2();
       return 1;
@@ -922,6 +910,7 @@
   v231 = 0;
   if ( dstHeight <= 0 )
     return result;
+  
   do
   {
     for (int counter = 0; counter < dstWidth; counter++)
@@ -947,11 +936,11 @@
         for(int i = 0; i < ratioDiff; i++)
         {
           if(field0value == 32)
-            v21 = _450FB1((int)v175[i]);
+            v21 = _450FB1(((int*)v175)[i]);
           else if(field0value == 16)
-            v21 = _450FB1((_WORD)v175[i]);
+            v21 = _450FB1(((_WORD*)v175)[i]);
           else
-            v21 = _450FB1((unsigned __int8)v175[i]);
+            v21 = _450FB1(((unsigned __int8*)v175)[i]);
           v240 += ((unsigned int)v21 >> 24);
           a6b += BYTE2(v21);
           v252 += BYTE1(v21);
@@ -3817,7 +3806,7 @@
 //----- (00464761) --------------------------------------------------------
 void Game_DeinitializeAndTerminate(int exitCode)
 {
-  SetPriorityClass(GetCurrentProcess(), 0x20u);
+  SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
   ResetCursor_Palettes_LODs_Level_Audio_SFT_Windows();
   pGame->Deinitialize();
   pRenderer->Release2();
--- a/mm7_4.cpp	Tue Sep 17 12:37:07 2013 +0200
+++ b/mm7_4.cpp	Tue Sep 17 12:40:37 2013 +0200
@@ -850,7 +850,7 @@
             v21->pConditions[13] = pParty->uTimePlayed;
           if ( v35 < 1 )
           {
-            if ( v21->sHealth + v21->uEndurance + v21->GetItemsBonus(CHARACTER_ATTRIBUTE_ENDURANCE, 0) >= 1
+            if ( v21->sHealth + v21->uEndurance + v21->GetItemsBonus(CHARACTER_ATTRIBUTE_ENDURANCE) >= 1
               || (signed __int64)v21->pPlayerBuffs[11].uExpireTime > 0 )
             {
               v21->pConditions[13] = pParty->uTimePlayed;
@@ -1079,7 +1079,7 @@
       else
       {
         //v58 = 0;
-        if ( !sub_43EE77_ProbablyIfUnderwaterSuitIsEquipped(v12) )
+        if ( !pPlayers[v12]->HasUnderwaterSuitEquipped() )
         {
           //v14 = pPlayers[v12];
           //v15 = (double)pPlayers[v12]->GetMaxHealth() * 0.1;
@@ -1139,7 +1139,7 @@
     if ( (*v62)->uTimeToRecovery )
       v21->Recover(a2a);
     v22 = v21->sHealth;
-    if ( v21->GetItemsBonus(CHARACTER_ATTRIBUTE_ENDURANCE, 0) + v22 + v21->uEndurance >= 1
+    if ( v21->GetItemsBonus(CHARACTER_ATTRIBUTE_ENDURANCE) + v22 + v21->uEndurance >= 1
       || (signed __int64)v21->pPlayerBuffs[11].uExpireTime > 0 )
     {
       if ( v22 < 1 )
--- a/mm7_5.cpp	Tue Sep 17 12:37:07 2013 +0200
+++ b/mm7_5.cpp	Tue Sep 17 12:40:37 2013 +0200
@@ -4302,264 +4302,274 @@
 bool __fastcall sub_4070EF_prolly_detect_player(unsigned int uObjID, unsigned int uObj2ID)
 {
   signed int v2; // eax@1
-  //unsigned int v3; // ecx@1
-  //signed int v4; // esi@1
   int v5; // ecx@2
-  signed int v6; // eax@4
-  int object1_sector; // eax@4
+  int obj1_sector; // eax@4
   float v8; // ST24_4@5
   double v9; // ST18_8@5
-  signed int v10; // eax@6
   int v11; // ecx@6
   signed int v12; // eax@7
   int v13; // esi@7
   int v14; // esi@8
   int v15; // esi@9
-  signed int v16; // eax@11
   int obj2_z; // edi@11
   int obj2_x; // esi@11
   int obj2_sector; // eax@13
   float v20; // ST24_4@14
   double v21; // ST18_8@14
-  signed int v22; // eax@15
-  int dist2_x; // ebx@16
-  signed int v24; // ecx@16
+  int dist_x; // ebx@16
+  signed int dist_3d; // ecx@16
   int v25; // eax@18
-  //int v26; // eax@28
-  //BLVSector *v27; // edx@31
-  //int v28; // ecx@31
   BLVFace *v29; // ebx@32
   Vec3_short_ *v30; // esi@32
   int v31; // eax@32
   int v32; // ST50_4@44
   int v33; // ST54_4@44
   int v34; // eax@44
-  char v35; // zf@44
-  int v36; // edi@44
-  int v37; // eax@45
   signed int v38; // esi@45
-  int v39; // ST4C_4@49
   signed __int64 v40; // qtt@50
-  __int16 v42; // bx@58
+  __int16 next_sector; // bx@58
   int v43; // [sp-8h] [bp-70h]@11
   int v44; // [sp-4h] [bp-6Ch]@11
-  //int v45; // [sp+Ch] [bp-5Ch]@32
-  //__int16 v46; // [sp+10h] [bp-58h]@32
   int v47; // [sp+18h] [bp-50h]@20
   int v48; // [sp+1Ch] [bp-4Ch]@20
   int v49; // [sp+20h] [bp-48h]@20
-  int dist2_z; // [sp+24h] [bp-44h]@16
-  signed int v51; // [sp+24h] [bp-44h]@27
-  signed int v52; // [sp+28h] [bp-40h]@26
-  signed int v53; // [sp+2Ch] [bp-3Ch]@23
-  signed int v54; // [sp+30h] [bp-38h]@22
-  signed int v55; // [sp+34h] [bp-34h]@21
-  signed int v56; // [sp+38h] [bp-30h]@20
-  signed int v57; // [sp+3Ch] [bp-2Ch]@28
+  int dist_z; // [sp+24h] [bp-44h]@16
+  signed int higher_z; // [sp+24h] [bp-44h]@27
+  signed int lower_z; // [sp+28h] [bp-40h]@26
+  signed int higher_y; // [sp+2Ch] [bp-3Ch]@23
+  signed int lower_y; // [sp+30h] [bp-38h]@22
+  signed int higher_x; // [sp+34h] [bp-34h]@21
+  signed int lower_x; // [sp+38h] [bp-30h]@20
+  signed int sectors_visited; // [sp+3Ch] [bp-2Ch]@28
   int v58; // [sp+44h] [bp-24h]@50
   int v59; // [sp+48h] [bp-20h]@44
   int obj2_y; // [sp+50h] [bp-18h]@11
-  signed int v61; // [sp+50h] [bp-18h]@31
-  //int v62; // [sp+54h] [bp-14h]@16
-  int obj_x; // [sp+58h] [bp-10h]@4
-  int obj_y; // [sp+5Ch] [bp-Ch]@4
-  int obj_z; // [sp+60h] [bp-8h]@4
-  int v66; // [sp+64h] [bp-4h]@7
+  int obj1_x; // [sp+58h] [bp-10h]@4
+  int obj1_y; // [sp+5Ch] [bp-Ch]@4
+  int obj1_z; // [sp+60h] [bp-8h]@4
+  int current_sector; // [sp+64h] [bp-4h]@7
+  int dist_y;
+  int v70;
 
   v2 = PID_ID(uObjID);
-  if ( PID_TYPE(uObjID) == 5 )
+  switch( PID_TYPE(uObjID) )
   {
-      v6 = v2;
-      obj_x = pLevelDecorations[v6].vPosition.x;
-      obj_y = pLevelDecorations[v6].vPosition.y;
-      obj_z = pLevelDecorations[v6].vPosition.z;
-      object1_sector = pIndoor->GetSector(obj_x, obj_y, obj_z);
-  }
-  else if ( PID_TYPE(uObjID) == 3 )
-  {
-      obj_x = pActors[v2].vPosition.x;
-      obj_y = pActors[v2].vPosition.y;
+	case OBJECT_Decoration:
+      obj1_x = pLevelDecorations[v2].vPosition.x;
+      obj1_y = pLevelDecorations[v2].vPosition.y;
+      obj1_z = pLevelDecorations[v2].vPosition.z;
+      obj1_sector = pIndoor->GetSector(obj1_x, obj1_y, obj1_z);
+	  break;
+	case OBJECT_Actor:
+      obj1_x = pActors[v2].vPosition.x;
+      obj1_y = pActors[v2].vPosition.y;
       v8 = (double)pActors[v2].uActorHeight * 0.69999999;
       //v9 = v8 + 6.7553994e15;
-      //obj_z = LODWORD(v9) + pActors[v2].vPosition.z;
-	  obj_z = (int)v8 + pActors[v2].vPosition.z;
-      object1_sector = pActors[v2].uSectorID;
+      //obj1_z = LODWORD(v9) + pActors[v2].vPosition.z;
+	  obj1_z = (int)v8 + pActors[v2].vPosition.z;
+      obj1_sector = pActors[v2].uSectorID;
+	  break;
+	case OBJECT_Item:
+      obj1_x = pSpriteObjects[v2].vPosition.x;
+      obj1_y = pSpriteObjects[v2].vPosition.y;
+      obj1_z = pSpriteObjects[v2].vPosition.z;
+      obj1_sector = pSpriteObjects[v2].uSectorID;
+	  break;
+	default:
+	  return 0;
   }
-  else if ( PID_TYPE(uObjID) == 2 )
-  {
-    v10 = v2;
-    obj_x = pSpriteObjects[v10].vPosition.x;
-    obj_y = pSpriteObjects[v10].vPosition.y;
-    obj_z = pSpriteObjects[v10].vPosition.z;
-    object1_sector = pSpriteObjects[v10].uSectorID;
-  }
-  else
-	  return 0;
-  v66 = object1_sector;
   v12 = PID_ID(uObj2ID);
-  if ( PID_TYPE(uObj2ID) == 5)
+  switch( PID_TYPE(uObj2ID) )
   {
-	v16 = v12;
-    obj2_z = pLevelDecorations[v16].vPosition.z;
-    obj2_x = pLevelDecorations[v16].vPosition.x;
-    obj2_y = pLevelDecorations[v16].vPosition.y;
-	obj2_sector = pIndoor->GetSector(obj2_x, obj2_y, obj2_z);
-   }
-   else if ( PID_TYPE(uObj2ID) == 4)
-   {
-     obj2_x = pParty->vPosition.x;
-     obj2_z = pParty->sEyelevel + pParty->vPosition.z;
-     obj2_y = pParty->vPosition.y;
-	 obj2_sector = pIndoor->GetSector(obj2_x, obj2_y, obj2_z);
-    }
-  
-  else if( PID_TYPE(uObj2ID) == 3)
-  {
-    obj2_y = pActors[v12].vPosition.y;
-    obj2_x = pActors[v12].vPosition.x;
-    v20 = (double)pActors[v12].uActorHeight * 0.69999999;
-    //v21 = v20 + 6.7553994e15;
-    //obj2_z = LODWORD(v21) + pActors[v12].vPosition.z;
-	obj2_z = (int)v20 + pActors[v12].vPosition.z;
-    obj2_sector = pActors[v12].uSectorID;
+    case OBJECT_Decoration:
+      obj2_z = pLevelDecorations[v12].vPosition.z;
+      obj2_x = pLevelDecorations[v12].vPosition.x;
+      obj2_y = pLevelDecorations[v12].vPosition.y;
+	  obj2_sector = pIndoor->GetSector(obj2_x, obj2_y, obj2_z);
+	  break;
+	case OBJECT_Player:
+      obj2_x = pParty->vPosition.x;
+      obj2_z = pParty->sEyelevel + pParty->vPosition.z;
+      obj2_y = pParty->vPosition.y;
+	  obj2_sector = pIndoor->GetSector(obj2_x, obj2_y, obj2_z);
+      break;
+	case OBJECT_Actor:
+      obj2_y = pActors[v12].vPosition.y;
+      obj2_x = pActors[v12].vPosition.x;
+      v20 = (double)pActors[v12].uActorHeight * 0.69999999;
+      //v21 = v20 + 6.7553994e15;
+      //obj2_z = LODWORD(v21) + pActors[v12].vPosition.z;
+	  obj2_z = (int)v20 + pActors[v12].vPosition.z;
+      obj2_sector = pActors[v12].uSectorID;
+	  break;
+	case OBJECT_Item:
+      obj2_x = pSpriteObjects[v12].vPosition.x;
+      obj2_z = pSpriteObjects[v12].vPosition.z;
+      obj2_y = pSpriteObjects[v12].vPosition.y;
+      obj2_sector = pSpriteObjects[v12].uSectorID;
+	  break;
+	default:
+	  return 0;
   }
-  
-  else if ( PID_TYPE(uObj2ID) == 2)
-  {
-    v22 = v12;
-    obj2_x = pSpriteObjects[v22].vPosition.x;
-    obj2_z = pSpriteObjects[v22].vPosition.z;
-    obj2_y = pSpriteObjects[v22].vPosition.y;
-    obj2_sector = pSpriteObjects[v22].uSectorID;
-  }
-  else
-	  return 0;
-  dist2_x = obj2_x - obj_x;
-  dist2_z = obj2_z - obj_z;
-  v24 = integer_sqrt(dist2_x * dist2_x + (obj2_y - obj_y) * (obj2_y - obj_y) + dist2_z * dist2_z);
-  if ( v24 > 5120 )
+  dist_x = obj2_x - obj1_x;
+  dist_z = obj2_z - obj1_z;
+  dist_y = obj2_y - obj1_y;
+  dist_3d = integer_sqrt(dist_x * dist_x + dist_y * dist_y + dist_z * dist_z);
+  //range check
+  if ( dist_3d > 5120 )
     return 0;
   if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor)
     return 1;
   v25 = 65536;
-  if ( v24 )
-    v25 = 65536 / v24;
-  v49 = dist2_x * v25;
-  v47 = dist2_z * v25;
-  v48 = (obj2_y - obj_y) * v25;
-  if ( obj_x < obj2_x )
+  if ( dist_3d )
+    v25 = 65536 / dist_3d;
+  v49 = dist_x * v25;
+  v47 = dist_z * v25;
+  v48 = dist_y * v25;
+  if ( obj1_x < obj2_x )
   {
-	v56 = obj_x;
-    v55 = obj2_x;
+	lower_x = obj1_x;
+    higher_x = obj2_x;
   }
   else
   {
-    v56 = obj2_x;
-    v55 = obj_x;
+    lower_x = obj2_x;
+    higher_x = obj1_x;
   }
-  if ( obj_y < obj2_y )
+  if ( obj1_y < obj2_y )
   {
-	v54 = obj_y;
-    v53 = obj2_y;
+	lower_y = obj1_y;
+    higher_y = obj2_y;
   }
   else
   {
-    v54 = obj2_y;
-    v53 = obj_y;
+    lower_y = obj2_y;
+    higher_y = obj1_y;
   }
-  if ( obj_z < obj2_z )
+  if ( obj1_z < obj2_z )
   {
-	v52 = obj_z;
-    v51 = obj2_z;
+	lower_z = obj1_z;
+    higher_z = obj2_z;
   }
   else
   {
-    v52 = obj2_z;
-    v51 = obj_z;
+    lower_z = obj2_z;
+    higher_z = obj1_z;
   }
-  v57 = 0;
-  if ( v66 == obj2_sector )
+  sectors_visited = 0;
+  //monster in same sector with player
+  if ( obj1_sector == obj2_sector )
       return 1;
-  //for ( v57 = 0; v57 < 30; v57++ )
-  if ( v57 < 30 && !(v61 = 0, pIndoor->pSectors[v66].uNumPortals <= 0) )
-	for( int v61 = 0; v61 < pIndoor->pSectors[v66].uNumPortals; v61++ )
+  //search starts from monster
+  current_sector = obj1_sector;
+  for( int current_portal = 0; current_portal < pIndoor->pSectors[current_sector].uNumPortals; current_portal++ )
+  {
+	v29 = &pIndoor->pFaces[pIndoor->pSectors[current_sector].pPortals[current_portal]];
+	v30 = &pIndoor->pVertices[*v29->pVertexIDs];
+	v31 = v29->pFacePlane_old.vNormal.z * (v30->z - obj1_z)
+		+ v29->pFacePlane_old.vNormal.y * (v30->y - obj1_y)
+		+ v29->pFacePlane_old.vNormal.x * (v30->x - obj1_x);
+
+	if ( current_sector != v29->uSectorID )
+		v31 = -v31;
+
+	if ( v31 >= 0 && v30->x != obj1_x && v30->y != obj1_y && v30->z != obj1_z)
+		continue;
+
+	if(	lower_x > v29->pBounding.x2
+		|| higher_x < v29->pBounding.x1
+		|| lower_y > v29->pBounding.y2
+		|| higher_y < v29->pBounding.y1
+		|| lower_z > v29->pBounding.z2
+		|| higher_z < v29->pBounding.z1 )
+	{
+		continue;
+	}
+	  
+	v32 = fixpoint_sub0(v29->pFacePlane_old.vNormal.x,v49);
+	v33 = fixpoint_sub0(v29->pFacePlane_old.vNormal.z,v47);
+	v34 = fixpoint_sub0(v29->pFacePlane_old.vNormal.y,v48);
+	v59 = v32 + v33 + v34;
+	if ( v59 )
 	{
-      v29 = &pIndoor->pFaces[pIndoor->pSectors[v66].pPortals[v61]];
-      v30 = &pIndoor->pVertices[*v29->pVertexIDs];
-      //v45 = *(int *)&v30->x;
-      //v46 = v30->z;
-      //v31 = v29->pFacePlane_old.vNormal.z * (v46 - obj_z)
-	  v31 = v29->pFacePlane_old.vNormal.z * (v30->z - obj_z)
-          //+ v29->pFacePlane_old.vNormal.y * (SHIWORD(v45) - obj_y)
-		  + v29->pFacePlane_old.vNormal.y * (v30->y - obj_y)
-          //+ v29->pFacePlane_old.vNormal.x * ((signed __int16)v45 - obj_x);
-		  + v29->pFacePlane_old.vNormal.x * (v30->x - obj_x);
-      if ( v66 != v29->uSectorID )
-        v31 = -v31;
-      //if (!( v31 >= 0 && (signed __int16)v45 != obj_x && SHIWORD(v45) != obj_y && v46 != obj_z
-	  if (!( v31 >= 0 && v30->x != obj_x && v30->y != obj_y && v30->z != obj_z
-        || v56 > v29->pBounding.x2
-        || v55 < v29->pBounding.x1
-        || v54 > v29->pBounding.y2
-        || v53 < v29->pBounding.y1
-        || v52 > v29->pBounding.z2
-        || v51 < v29->pBounding.z1 ) )
-	  {
-		  v32 = (unsigned __int64)(v49 * (signed __int64)v29->pFacePlane_old.vNormal.x) >> 16;
-		  v33 = (unsigned __int64)(v47 * (signed __int64)v29->pFacePlane_old.vNormal.z) >> 16;
-		  v34 = (unsigned __int64)(v48 * (signed __int64)v29->pFacePlane_old.vNormal.y) >> 16;
-		  v35 = v32 + v33 + v34 == 0;
-		  v36 = v32 + v33 + v34;
-		  v59 = v32 + v33 + v34;
-		  if ( !v35 )
-		  {
-			  v37 = obj_z * v29->pFacePlane_old.vNormal.z;
-			  v38 = -(v29->pFacePlane_old.dist + v37 + obj_x * v29->pFacePlane_old.vNormal.x + obj_y * v29->pFacePlane_old.vNormal.y);
-			  if ( v36 <= 0 ^ v29->pFacePlane_old.dist + v37 + obj_x * v29->pFacePlane_old.vNormal.x + obj_y * v29->pFacePlane_old.vNormal.y <= 0)
-			  {
-				v39 = abs(-(v29->pFacePlane_old.dist
-						  + v37
-						  + obj_x * v29->pFacePlane_old.vNormal.x
-						  + obj_y * v29->pFacePlane_old.vNormal.y)) >> 14;
-				if ( v39 > abs(v36)
-				  || (LODWORD(v40) = v38 << 16, HIDWORD(v40) = v38 >> 16, v58 = v40 / v59, (signed int)(v40 / v59) < 0)
-				  || !sub_4075DB(
-						obj_x + ((signed int)(((unsigned __int64)(v58 * (signed __int64)v49) >> 16) + 32768) >> 16),
-						obj_y + ((signed int)(((unsigned __int64)(v58 * (signed __int64)v48) >> 16) + 32768) >> 16),
-						obj_z + ((signed int)(((unsigned __int64)(v58 * (signed __int64)v47) >> 16) + 32768) >> 16),
-						v29) )
-				{
-				  continue;
-				}
-				if ( v29->uSectorID == v66 )
-				  v42 = v29->uBackSectorID;
-				else
-				  v42 = v29->uSectorID;
-				if ( v42 != v66 )
-				{
-				  ++v57;
-				  v66 = v42;
-				  if ( v42 == obj2_sector )
-					return 1;
-				  if ( v57 < 30 && pIndoor->pSectors[v66].uNumPortals > 0)
-				  {
-					  v61=-1;
-					  continue;
-				  }
+		v70 = v29->pFacePlane_old.dist 
+			+ obj1_z * v29->pFacePlane_old.vNormal.z 
+			+ obj1_x * v29->pFacePlane_old.vNormal.x 
+			+ obj1_y * v29->pFacePlane_old.vNormal.y;
+		v38 = -v70;
+
+		// if ( v59 <= 0 ^ v70 <= 0 )
+		
+		/* TEMPORARY
+		if ( v59 <= 0 && v70 <= 0 )
+		{
+			continue;
+		}
+		if ( !(v59 <= 0 && v70 <= 0) )
+		{
+			continue;
+		}
+		*/
+
+		if( abs(v38) >> 14 > abs(v59) )
+			continue;
+
+		v58 = fixpoint_sub2(v38,v59);
+
+		if( v58 < 0 )
+		{
+			continue;
+		}
 
-				}
-				break;
-			  }
-		  }
-	  }
-    }
-  if ( v66 != obj2_sector )
+		if(!sub_4075DB(
+				obj1_x + ((fixpoint_sub0(v49,v58) + 32768) >> 16),
+				obj1_y + ((fixpoint_sub0(v48,v58) + 32768) >> 16),
+				obj1_z + ((fixpoint_sub0(v47,v58) + 32768) >> 16),
+				v29) )
+		{
+			continue;
+		}
+
+		//if there is no next sector turn back
+		if ( v29->uSectorID == current_sector )
+			next_sector = v29->uBackSectorID;
+		else
+			next_sector = v29->uSectorID;
+
+		//no more portals, quit
+		if ( next_sector == current_sector )
+		{
+			break;
+		}
+
+		++sectors_visited;
+		current_sector = next_sector;
+
+		//found player, quit
+		if ( next_sector == obj2_sector )
+			return 1;
+
+		current_sector = next_sector;
+
+		//did we hit limit for portals?
+		//does the next room have portals?
+		if ( sectors_visited < 30 && pIndoor->pSectors[current_sector].uNumPortals > 0)
+		{
+				current_portal=-1;
+				continue;
+		}
+		else
+			break;
+	}
+  }
+  //did we stop in the sector where player is?
+  if ( current_sector != obj2_sector )
     return 0;
   return 1;
 }
 
 //----- (004075DB) --------------------------------------------------------
-bool __fastcall sub_4075DB(int a1, int a2, int a3, BLVFace *a4)
+bool __fastcall sub_4075DB(int x, int y, int z, BLVFace *a4)
 {
   unsigned int v5; // esi@1
   char v7; // zf@2
@@ -4590,57 +4600,57 @@
   v9 = pIndoor->pVertices;
   if ( v5 & FACE_XY_PLANE )
   {
-    a4a = a1;
-    v8 = a2;
+    a4a = x;
+    v8 = y;
     for(int i = 0; i < a4->uNumVertices; i++)
 	{
         dword_4F5D98_xs[i] = v9[a4->pVertexIDs[i]].x;
-        dword_4F5CC4_ys[i+1] = v9[a4->pVertexIDs[i]].y;
+        dword_4F5CC8_ys[i] = v9[a4->pVertexIDs[i]].y;
 	}
   }
   else
   {
-    v8 = a3;
-    if ( v5 & FACE_XY_PLANE )
+    v8 = z;
+    if ( v5 & FACE_XZ_PLANE )
     {
-      a4a = a1;
+      a4a = x;
       for(int i = 0; i < a4->uNumVertices; i++)
 	  {
 		dword_4F5D98_xs[i] = v9[a4->pVertexIDs[i]].x;
-		dword_4F5CC4_ys[i+1] = v9[a4->pVertexIDs[i]].z;
+		dword_4F5CC8_ys[i] = v9[a4->pVertexIDs[i]].z;
 	  }
     }
     else
     {
-      a4a = a2;
+      a4a = y;
       for(int i = 0; i < a4->uNumVertices; i++)
 	  {
 		dword_4F5D98_xs[i] = v9[a4->pVertexIDs[i]].y;
-		dword_4F5CC4_ys[i+1] = v9[a4->pVertexIDs[i]].z;
+		dword_4F5CC8_ys[i] = v9[a4->pVertexIDs[i]].z;
 	  }
     }
   }
   a3a = 0;
   dword_4F5D98_xs[a4->uNumVertices] = dword_4F5D98_xs[0];
-  dword_4F5CC4_ys[a4->uNumVertices + 1] = dword_4F5CC4_ys[1];
-  for(int i = 0; i < a4->uNumVertices; i++)
+  dword_4F5CC8_ys[a4->uNumVertices] = dword_4F5CC8_ys[0];
+  for(int i = 0; i < a4->uNumVertices && a3a < 2; i++)
   {
-    if ( a3a >= 2 )
-      break;
-    if ( dword_4F5CC4_ys[i + 1] >= v8 ^ (dword_4F5CC4_ys[i + 2] >= v8) )
+    if ( dword_4F5CC8_ys[i] >= v8 ^ (dword_4F5CC8_ys[i + 1] >= v8) )
     {
-	  if( dword_4F5D98_xs[i + 1] >= a4a || dword_4F5D98_xs[i] >= a4a)
+	  //if( dword_4F5D98_xs[i + 1] >= a4a || dword_4F5D98_xs[i] >= a4a)
+	  if( !(dword_4F5D98_xs[i + 1] >= a4a && dword_4F5D98_xs[i] < a4a))
       {
-		  if ( (dword_4F5D98_xs[i + 1] >= a4a && dword_4F5D98_xs[i] >= a4a)
-          || (v25 = dword_4F5D98_xs[i + 1] - dword_4F5D98_xs[i],
-              LODWORD(v26) = v25 << 16,
-              HIDWORD(v26) = v25 >> 16,
-              dword_4F5D98_xs[i]
-            + ((signed int)(((unsigned __int64)(v26
-                                              / (dword_4F5CC4_ys[i + 2] - dword_4F5CC4_ys[i + 1])
-                                              * ((v8 - dword_4F5CC4_ys[i + 1]) << 16)) >> 16)
-                          + 32768) >> 16) >= a4a) )
-          ++a3a;
+		  if ( (dword_4F5D98_xs[i + 1] < a4a && dword_4F5D98_xs[i] >= a4a) )
+			  ++a3a;
+		  //|| (v25 = dword_4F5D98_xs[i + 1] - dword_4F5D98_xs[i],LODWORD(v26) = v25 << 16, HIDWORD(v26) = v25 >> 16, 
+		  //dword_4F5D98_xs[i] + ((signed int)(((unsigned __int64)(v26 / (dword_4F5CC4_ys[i + 2] - dword_4F5CC4_ys[i + 1])* ((v8 - dword_4F5CC4_ys[i + 1]) << 16)) >> 16)
+          //                + 32768) >> 16) >= a4a) )
+		  else
+		  {
+			v25 = fixpoint_sub2(dword_4F5D98_xs[i + 1] - dword_4F5D98_xs[i], dword_4F5CC8_ys[i + 1] - dword_4F5CC8_ys[i]);
+			if( dword_4F5D98_xs[i] + (fixpoint_sub0(v25, (v8 - dword_4F5CC8_ys[i]) << 16) + 32768 >> 16) >= a4a)
+				++a3a;
+		  }
       }
     }
   }
@@ -4966,12 +4976,12 @@
   if (no_rightlick_in_inventory)
     return;
 
+  pMouse->GetCursorPos(&a2);
   if (a2.x <= 13 || a2.x >= 462)
     return;
 
   auto player = pPlayers[uActiveCharacter];
 
-  pMouse->GetCursorPos(&a2);
   int item_pid = pRenderer->pActiveZBuffer[a2.x + pSRZBufferLineOffsets[a2.y]] & 0xFFFF;
   //pMouse->GetClickPos(&pX, &pY);
   if (!item_pid)
--- a/mm7_data.cpp	Tue Sep 17 12:37:07 2013 +0200
+++ b/mm7_data.cpp	Tue Sep 17 12:40:37 2013 +0200
@@ -860,10 +860,10 @@
 int dword_4F5428[777]; // weak
 int dword_4F542C[777]; // weak
 _UNKNOWN crtunk_4F54B8; // weak
-std::array<int, 777> dword_4F5B24_ys; // idb
-std::array<int, 777> dword_4F5BF4_xs; // idb
-std::array<int, 777> dword_4F5CC4_ys; // idb
-std::array<int, 777> dword_4F5D98_xs; // idb
+std::array<int, 52> dword_4F5B24_ys; // idb
+std::array<int, 52> dword_4F5BF4_xs; // idb
+std::array<int, 52> dword_4F5CC8_ys; // idb
+std::array<int, 52> dword_4F5D98_xs; // idb
 std::array<int, 500> ai_array_4F5E68;
 std::array<int, 500> ai_array_4F6638_actor_ids;
 std::array<int, 500> ai_near_actors_targets_pid;
@@ -1043,7 +1043,7 @@
 int dword_59117C_teleportx; // weak
 std::array<std::array<char, 100>, 6> byte_591180; // idb
 std::array<struct NPCData *, 7> HouseNPCData;//0 zero element holds standart house npc
-GUIButton* dword_5913F4[6];
+GUIButton* HouseNPCPortraitsButtonsList[6];//dword_5913F4
 struct Texture *pTexture_591428;
 struct Texture *pTexture_outside; // idb
 struct Texture *pTexture_Dialogue_Background;
--- a/mm7_data.h	Tue Sep 17 12:37:07 2013 +0200
+++ b/mm7_data.h	Tue Sep 17 12:40:37 2013 +0200
@@ -509,10 +509,10 @@
 extern int dword_4F5428[]; // weak
 extern int dword_4F542C[]; // weak
 extern _UNKNOWN crtunk_4F54B8; // weak
-extern std::array<int, 777> dword_4F5B24_ys; // idb
-extern std::array<int, 777> dword_4F5BF4_xs; // idb
-extern std::array<int, 777> dword_4F5CC4_ys; // idb
-extern std::array<int, 777> dword_4F5D98_xs; // idb
+extern std::array<int, 52> dword_4F5B24_ys; // idb
+extern std::array<int, 52> dword_4F5BF4_xs; // idb
+extern std::array<int, 52> dword_4F5CC8_ys; // idb
+extern std::array<int, 52> dword_4F5D98_xs; // idb
 extern std::array<int, 500> ai_array_4F5E68;
 extern std::array<int, 500> ai_array_4F6638_actor_ids;
 extern std::array<int, 500> ai_near_actors_targets_pid;
@@ -693,7 +693,7 @@
 extern int dword_59117C_teleportx; // weak
 extern std::array<std::array<char, 100>, 6> byte_591180; // idb
 extern std::array<struct NPCData *, 7> HouseNPCData; //0this array size temporarily increased to 60 from 6 to work aroud house overflow
-extern GUIButton* dword_5913F4[6];
+extern GUIButton* HouseNPCPortraitsButtonsList[6];
 extern struct Texture *pTexture_591428;
 extern struct Texture *pTexture_outside; // idb
 extern struct Texture *pTexture_Dialogue_Background;
@@ -1143,9 +1143,7 @@
 void CharacterUI_LoadPaperdollTextures();
 int __fastcall GetItemTextureFilename(char *pOut, signed int item_id, int index, int shoulder);
 bool _43ED6F_check_party_races(bool b);
-bool  sub_43EDB9_get_some_race_sex_relation_2(unsigned int _this);
-bool __fastcall Player_has_item(unsigned int uItemID, struct Player *pPlayer, char a3);
-bool __fastcall sub_43EE77_ProbablyIfUnderwaterSuitIsEquipped(signed int a1);
+bool  ShouldLoadTexturesForRaceAndGender(unsigned int _this);
 void WetsuitOn(unsigned int uPlayerID); // idb
 void WetsuitOff(unsigned int uPlayerID);
 void __fastcall PrepareDrawLists_BLV(struct IndoorLocation_drawstru *_this);