changeset 1629:2149b14614ad

Слияние
author Ritor1
date Mon, 16 Sep 2013 09:37:30 +0600
parents 7ce831a2a393 (current diff) 2d374de0a364 (diff)
children ee4a65ac9d21
files UI/UIHouses.cpp
diffstat 14 files changed, 2273 insertions(+), 2696 deletions(-) [+]
line wrap: on
line diff
--- a/Items.cpp	Mon Sep 16 09:37:08 2013 +0600
+++ b/Items.cpp	Mon Sep 16 09:37:30 2013 +0600
@@ -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) --------------------------------------------------------
@@ -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	Mon Sep 16 09:37:08 2013 +0600
+++ b/Items.h	Mon Sep 16 09:37:30 2013 +0600
@@ -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;}
--- a/Math.h	Mon Sep 16 09:37:08 2013 +0600
+++ b/Math.h	Mon Sep 16 09:37:30 2013 +0600
@@ -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/Outdoor.cpp	Mon Sep 16 09:37:08 2013 +0600
+++ b/Outdoor.cpp	Mon Sep 16 09:37:30 2013 +0600
@@ -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	Mon Sep 16 09:37:08 2013 +0600
+++ b/Player.cpp	Mon Sep 16 09:37:30 2013 +0600
@@ -156,329 +156,6 @@
    30   // PLAYER_SKILL_PLATE
 };
 
-#include <map>
-#include <list>
-
-typedef struct CEnchantment
-{
-  CEnchantment(int bonus, unsigned __int16 Player::* skillPtr = NULL):
-    statBonus(bonus),
-    statPtr(skillPtr)
-    {
-    }
-  int statBonus;
-  unsigned __int16 Player::* statPtr;
-} CEnchantment;
-
-#define NEWBONUSINTOSPECIALLIST(x,y) AddToMap(specialBonusMap, enchId, x, y);
-#define NEWBONUSINTOSPECIALLIST2(x,y,z) AddToMap(specialBonusMap, enchId, x, y, z);
-
-#define NEWBONUSINTOREGULARLIST(x) AddToMap(regularBonusMap, enchId, x);
-
-#define NEWBONUSINTOARTIFACTLIST(x,y) AddToMap(artifactBonusMap, enchId, x, y);
-#define NEWBONUSINTOARTIFACTLIST2(x,y,z) AddToMap(artifactBonusMap, enchId, x, y, z);
-
-std::map<int, std::map<CHARACTER_ATTRIBUTE_TYPE, CEnchantment*>* > regularBonusMap;
-std::map<int, std::map<CHARACTER_ATTRIBUTE_TYPE, CEnchantment*>* > specialBonusMap;
-std::map<int, std::map<CHARACTER_ATTRIBUTE_TYPE, CEnchantment*>* > artifactBonusMap;
-//-------------------------------------------------------------------------
-
-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)
-{
-  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 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 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 PopulateArtifactBonusMap()
-{
-  int enchId = 1;//of Might
-  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_STRENGTH, 5);
-}
-//-------------------------------------------------------------------------
-
-void Player::GetItemBonusSpecialEnchantment(int enchantmentId, CHARACTER_ATTRIBUTE_TYPE attrToGet, int* additiveBonus, int* halfSkillBonus)
-{
-  auto bonusList = specialBonusMap.find(enchantmentId);
-  if (bonusList == 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 = this->*currBonus->statPtr / 2;
-      }
-      else
-      {
-        if (*additiveBonus < currBonus->statBonus)
-        {
-          *additiveBonus = currBonus->statBonus;
-        }
-      }
-    }
-    else
-    {
-      *additiveBonus += currBonus->statBonus;
-    }
-  }
-}
-
-//-------------------------------------------------------------------------
-bool IsRegularEnchanmentForAttribute(int enchantmentId, CHARACTER_ATTRIBUTE_TYPE attrToGet)
-{
-  auto bonusList = specialBonusMap.find(enchantmentId);
-  if (bonusList == specialBonusMap.end())
-  {
-    return false;
-  }
-  std::map<CHARACTER_ATTRIBUTE_TYPE, CEnchantment*>* currList = bonusList->second;
-  return (currList->find(attrToGet) != currList->end());
-}
-
 //----- (00490913) --------------------------------------------------------
 int PlayerCreation_GetUnspentAttributePointCount()
 {
@@ -1461,7 +1138,7 @@
 {
   unsigned __int16 v2; // ax@1
   int v5; // edi@7
-
+  return true;
   if (CheckHiredNPCSpeciality(Scholar))
     return true;
 
@@ -1561,11 +1238,6 @@
 //----- (0048C6AF) --------------------------------------------------------
 Player::Player()
 {  
-  if (specialBonusMap.empty())
-  {
-    PopulateSpecialBonusMap();
-  }
-
   memset(&pEquipment, 0, sizeof(PlayerEquipment));
   memset(pInventoryMatrix, 0, 126 * sizeof(int));
   for (uint i = 0; i < 126; ++i)
@@ -3092,7 +2764,7 @@
   }
 
   uint hasteRecoveryReduction = 0;
-  if (pPlayerBuffs[PLAYER_BUFF_7].uExpireTime > 0 || pParty->pPartyBuffs[PARTY_BUFF_HASTE].uExpireTime > 0 )
+  if (pPlayerBuffs[PLAYER_BUFF_HASTE].uExpireTime > 0 || pParty->pPartyBuffs[PARTY_BUFF_HASTE].uExpireTime > 0 )
     hasteRecoveryReduction = 25;
 
   uint weapon_enchantment_recovery_reduction = 0;
@@ -3450,72 +3122,30 @@
 //----- (0048EAAE) --------------------------------------------------------
 int Player::GetItemsBonus( enum CHARACTER_ATTRIBUTE_TYPE attr, bool getOnlyMainHandDmg /*= false*/ )
 {
- // signed int v4; // eax@1
   int v5; // edi@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;
 
   v5 = 0;
   v62 = 0;
   v61 = 0;
-
   
   no_skills=false;
   switch (attr)
@@ -3550,558 +3180,295 @@
       return 0;
   }
 
-  if ( (signed int)attr > 28 )
-  {
-    if ( attr == CHARACTER_ATTRIBUTE_RANGED_DMG_BONUS || attr == CHARACTER_ATTRIBUTE_RANGED_ATTACK)
-    {
+  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 + v62 + v61;
-    }
-    if ( attr == CHARACTER_ATTRIBUTE_RANGED_DMG_MIN )
-    {
+      return v5;
+      break;
+
+    case CHARACTER_ATTRIBUTE_RANGED_DMG_MIN:
       if ( !HasItemEquipped(EQUIP_BOW) )
-        return v5 + v62 + v61;
+        return 0;
       v57 = this->pOwnItems[this->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 )
-    {
+      return v5 + v56;
+      break;
+
+    case CHARACTER_ATTRIBUTE_RANGED_DMG_MAX:
       if ( !HasItemEquipped(EQUIP_BOW) )
-        return v5 + v62 + v61;
+        return 0;
       v20 = this->pOwnItems[this->pEquipment.uBow-1].uItemID;
       v5 = pItemsTable->pItems[v20].uDamageDice * pItemsTable->pItems[v20].uDamageRoll;
       v56 = pItemsTable->pItems[v20].uDamageMod;
-      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 = this->pEquipment.pIndices[v65] - 1;
-      if ( attr == CHARACTER_ATTRIBUTE_AC_BONUS )
-      {
-        v32 = GetEquippedItemEquipType((ITEM_EQUIP_TYPE)v65);
-        if ( v32 >= 3 && v32 <= 11 )
-        {
-          v33 = this->pInventoryItemList[v31].uItemID;
-          v5 += pItemsTable->pItems[v33].uDamageDice + pItemsTable->pItems[v33].uDamageMod;
-        }
-      }
-      v63 = (int)((char *)this + 36 * v31);
-      attra = (ItemGen *)(v63 + 532);
-      if ( pItemsTable->IsMaterialNonCommon((ItemGen *)(attra)) == 1
-        && !pItemsTable->IsMaterialSpecial(attra) )
+      return v5 + v56;
+
+    case CHARACTER_ATTRIBUTE_LEVEL: 
+      if ( !Player::HasEnchantedItemEquipped(25) )
+        return 0;
+      return 5;
+      break;
+
+    case CHARACTER_ATTRIBUTE_MELEE_DMG_MAX:
+      if ( IsUnarmed() )
       {
-        v34 = attra->uItemID;
-        switch ( attra->uItemID )
-        {
-          case ITEM_ARTIFACT_PUCK:
-            if ( attr == 5 )
-              v5 += 50;
-            goto LABEL_361;
-          case ITEM_ARTIFACT_IRON_FEATHER:
-            if ( attr == 0 )
-              v5 += 40;
-            goto LABEL_361;
-          case ITEM_ARTIFACT_WALLACE:
-            if ( attr == 21 )
-              v61 += 10;
-            if ( attr == 2 )
-              v5 += 40;
-            goto LABEL_361;
-          case ITEM_ARTIFACT_CORSAIR:
-            if ( attr == 17 )
-              v61 += 5;
-            if ( attr == 18 )
-              v61 += 5;
-            if ( attr == 6 )
-              v5 += 40;
-            goto LABEL_361;
-          case ITEM_ARTICACT_GOVERNONS_ARMOR:            
-            if (attr <= 6)
-              v5 += 10;
-            goto LABEL_361;
-          case ITEM_ARTIFACT_YORUBA:
-            if ( attr == 3 )
-              v5 += 25;
-            goto LABEL_361;
-          case ITEM_ARTIFACT_SPLITTER:
-            if ( attr == 10 )
-              v5 += 50;
-            goto LABEL_361;
-          case ITEM_ARTEFACT_ULLYSES:
-            if ( attr == 4 )
-              v5 += 50;
-            goto LABEL_361;
-          case ITEM_ARTEFACT_HANDS_OF_THE_MASTER:
-            if ( attr == 23 )
-              v61 += 10;
-            if ( attr == 22 )
-              v61 += 10;
-            goto LABEL_361;
-          case ITEM_ARTIFACT_LEAGUE_BOOTS:
-            if ( attr == 36 )
-            {
-              v34 = this->pActiveSkills[PLAYER_SKILL_WATER];
-              v62 = (v32 / 2) & 0x1F;
-            }
-            if ( attr == 5 )
-              v5 += 40;
-            goto LABEL_361;
-          case ITEM_ARTIFACT_RULERS_RING:
-            if ( attr == 39 )
-            {
-              v34 = this->pActiveSkills[PLAYER_SKILL_MIND];
-              v62 = (v34 / 2 ) & 0x1F;
-            }
-            if ( attr == 42 )
-            {
-              v34 = this->pActiveSkills[PLAYER_SKILL_DARK];
-              v62 = (v34 / 2 ) & 0x1F;
-            }
-            goto LABEL_361;
-          case ITEM_RELIC_MASH:
-            if ( attr == 0 )
-              v5 += 150;
-            if ( attr == 1 )
-              v5 -= 40;
-            if ( attr == 2 )
-              v5 -= 40;
-            if ( attr == 5 )
-              v5 -= 40;
-            goto LABEL_361;
-          case ITEM_RELIC_ETHRICS_STAFF:
-            if ( attr == 42 )
-            {
-              v34 = this->pActiveSkills[PLAYER_SKILL_DARK];
-              v62 = (v34 / 2 ) & 0x1F;
-            }
-            if ( attr == 43 )
-              v61 += 15;
-            goto LABEL_361;
-          case ITEM_RELIC_HARECS_LEATHER:
-            if ( attr == 17 )
-              v61 += 5;
-            if ( attr == 18 )
-              v61 += 5;
-            if ( attr == 6 )
-              v5 += 50;
-            if ( attr == 11 || attr == 10 || attr == 12 || attr == 13 || attr == 33 || attr == 14 )
-            {
-                v5 -= 10;
-              goto LABEL_361;
-            }
-            if ( attr == 15 )
-              v5 -= 10;
-            goto LABEL_361;
-          case ITEM_RELIC_OLD_NICK:
-            if ( attr == 18 )
-              v61 += 5;
-            goto LABEL_361;
-          case ITEM_RELIC_AMUCK:
-            if ( attr == 0)
-              v5 += 100;
-            if ( attr == 3 )
-              v5 += 100;
-            if ( attr == 9 )
-              v5 -= 15;
-            goto LABEL_361;
-          case ITEM_RELIC_GLORY_SHIELD:
-            if ( attr == 45 )
-              v61 += 5;
-            if ( attr == 15 )
-              v5 -= 10;
-            if ( attr == 14 )
-              v5 -= 10;
-            goto LABEL_361;
-          case ITEM_RELIC_KELEBRIM:
-            if ( attr == 3 )
-              v5 += 50;
-            goto LABEL_361;
-          case ITEM_RELIC_TALEDONS_HELM:
-            if ( attr == 2 )
-              v5 += 15;
-            if ( !attr )
-              v5 += 15;
-            if ( attr == 6 )
-              v5 -= 40;
-            goto LABEL_361;
-          case ITEM_RELIC_SCHOLARS_CAP:
-            if ( attr == 46 )
-              v61 += 15;
-            if ( attr == 3 )
-              v5 -= 50;
-            goto LABEL_361;
-          case ITEM_RELIC_PHYNAXIAN_CROWN:
-            if ( attr == 34 )
-            {
-              v34 = this->pActiveSkills[PLAYER_SKILL_FIRE];
-              v62 = (v34 / 2 ) & 0x1F;
-            }
-            if ( attr == 12 )
-              v5 += 50;
-            if ( attr == 2 )
-              v5 += 30;
-            if ( attr == 9 )
-              v5 -= 20;
-            goto LABEL_361;
-          case ITEM_RILIC_TITANS_BELT:
-            if ( !attr )
-              v5 += 75;
-            if ( attr == 5 )
-              v5 -= 40;
-            goto LABEL_361;
-          case ITEM_RELIC_TWILIGHT:
-            if ( attr == CHARACTER_ATTRIBUTE_SPEED )
-              v5 += 50;
-            if ( attr == CHARACTER_ATTRIBUTE_LUCK )
-              v5 += 50;
-            if ( attr == CHARACTER_ATTRIBUTE_RESIST_AIR || attr == CHARACTER_ATTRIBUTE_RESIST_FIRE || attr == CHARACTER_ATTRIBUTE_RESIST_WATER || attr == CHARACTER_ATTRIBUTE_RESIST_EARTH || attr == CHARACTER_ATTRIBUTE_RESIST_SPIRIT || attr == CHARACTER_ATTRIBUTE_RESIST_MIND )
-            {
-              v5 -= 15;
-              goto LABEL_361;
-            }
-            if ( attr == 15 )
-              v5 -= 15;
-            goto LABEL_361;
-          case ITEM_RELIC_ANIA_SELVING:
-            if ( attr == CHARACTER_ATTRIBUTE_ACCURACY )
-              v5 += 150;
-            if ( attr == CHARACTER_ATTRIBUTE_SKILL_BOW )
-              v61 += 5;
-            if ( attr == CHARACTER_ATTRIBUTE_AC_BONUS )
-              v5 -= 25;
-            goto LABEL_361;
-          case ITEM_RELIC_JUSTICE:
-            if ( attr == 39 )
-            {
-              v34 = this->pActiveSkills[PLAYER_SKILL_MIND];
-              v62 = (v34 / 2 ) & 0x1F;
-            }
-            if ( attr == 40 )
-            {
-              v34 = this->pActiveSkills[PLAYER_SKILL_BODY];
-              v62 = (v34 / 2 ) & 0x1F;
-            }
-            if ( attr == 5 )
-              v5 -= 40;
-            goto LABEL_361;
-          case ITEM_RELIC_MEKORIGS_HAMMER:
-            if ( attr == 38 )
-            {
-              v34 = this->pActiveSkills[PLAYER_SKILL_SPIRIT];
-              v62 = ( v34 / 2 ) & 0x1F;
-            }
-            if ( attr == 0 )
-              v5 += 75;
-            if ( attr == 11 )
-              v5 -= 50;
-            goto LABEL_361;
-          case ITEM_ARTIFACT_HERMES_SANDALS:
-            if ( attr == 5 )
-              v5 += 100;
-            if ( attr == 4 )
-              v5 += 50;
-            if ( attr == 11 )
-              v5 += 50;
-            goto LABEL_361;
-          case ITEM_ARTIFACT_CLOAK_OF_THE_SHEEP:
-            if ( attr == 1 )
-              v5 -= 20;
-            if ( attr == 2 )
-              v5 -= 20;
-            goto LABEL_361;
-          case ITEM_ARTIFACT_MINDS_EYE:
-            if ( attr == 1 )
-              v5 += 15;
-            if ( attr == 2 )
-              v5 += 15;
-            goto LABEL_361;
-          case ITEM_ELVEN_CHAINMAIL:
-            if ( attr == 5 )
-              v5 += 15;
-            if ( attr == 4 )
-              v5 += 15;
-            goto LABEL_361;
-          case ITEM_FORGE_GAUNTLETS:
-            if ( attr == 10 )
-              v5 += 30;
-            if ( attr == 0 )
-              v5 += 15;
-            if ( attr == 3 )
-              v5 += 15;
-            goto LABEL_361;
-          case ITEM_ARTIFACT_HEROS_BELT:
-            if ( attr == 21 )
-              v61 += 5;
-            if ( attr == 0 )
-              v5 += 15;
-            if (attr >= 10 && attr <= 15)
-              v5 += 10;
-            goto LABEL_361;
-          case ITEM_ARTIFACT_LADYS_ESCORT:
-            if (attr >= 10 && attr <= 15)
-              v5 += 10;
-            goto LABEL_361;
-          default:
-            goto LABEL_361;
-        }
-        goto LABEL_361;
-      }
-      if ( this->pOwnItems[v65].uEnchantmentType == attr + 1 )
-      {
-        if ( attr >= CHARACTER_ATTRIBUTE_STRENGTH )
-        {
-          if ( attr <= CHARACTER_ATTRIBUTE_RESIST_BODY )
-          {
-            v5 += this->pOwnItems[v65].m_enchantmentStrength;
-          }
-          else
-          {
-            if ( attr <= CHARACTER_ATTRIBUTE_SKILL_UNARMED && v5 < this->pOwnItems[v65].m_enchantmentStrength )
-              v5 = this->pOwnItems[v65].m_enchantmentStrength;
-          }
-        }
+        return 3;
       }
       else
       {
-        v34 = this->pOwnItems[v65].uSpecEnchantmentType;
-        GetItemBonusSpecialEnchantment(v34, attr, &v5, &v61);
-      }
-
-LABEL_361:
-      ++v65;
-      if ( (signed int)v65 >= 16 )
-        return v5 + v62 + v61;
-    }
-  }
-  if ( attr == CHARACTER_ATTRIBUTE_MELEE_DMG_MAX )
-  {
-    if ( IsUnarmed() != 1 )
-    {
-      if ( this->HasItemEquipped(EQUIP_MAIN_HAND) )
-      {
-        v22 = this->GetEquippedItemEquipType(EQUIP_MAIN_HAND);
-        if ( v22 >= 0 )
+        if ( this->HasItemEquipped(EQUIP_MAIN_HAND) )
         {
-          if ( v22 <= 2 )
+          v22 = this->GetEquippedItemEquipType(EQUIP_MAIN_HAND);
+          if ( v22 >= 0 && v22 <= 2)
           {
-			  v23 = this->pOwnItems[this->pEquipment.uMainHand].uItemID;
+            v23 = this->pOwnItems[this->pEquipment.uMainHand].uItemID;
+            v26 = pItemsTable->pItems[v23].uDamageRoll;
             if ( this->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;
+              v25 = pItemsTable->pItems[v23].uDamageDice + 1;
             }
             v5 = pItemsTable->pItems[v23].uDamageMod + v25 * v26;
           }
         }
-      }
-      
-      if ( getOnlyMainHandDmg || !this->HasItemEquipped(EQUIP_OFF_HAND) )
-          {
-
-          v28 = this->GetEquippedItemEquipType(EQUIP_OFF_HAND);
-          if ((v28 < 0) || v28 > 2 )
-              return v5 + v62 + v61;
+        if ( getOnlyMainHandDmg || !this->HasItemEquipped(EQUIP_OFF_HAND) ||  (GetEquippedItemEquipType(EQUIP_OFF_HAND) < 0 && GetEquippedItemEquipType(EQUIP_OFF_HAND) > 2))
+        {
+            return v5;
         }
-      v15 = pItemsTable->pItems[v23].uDamageMod;
-      v14 = pItemsTable->pItems[v23].uDamageDice * pItemsTable->pItems[v23].uDamageRoll;
-      v5 += v15 + v14;
-      return v5 + v62 + v61;
-    }
-    v59 = 3;
-    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 )
+        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() )
       {
-      if ( !Player::HasEnchantedItemEquipped(25) )
-          return v5 + v62 + v61;
-      v5 = 5;
-      return v5 + v62 + v61;
+        return 0;
       }
-  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 ( this->HasItemEquipped(EQUIP_MAIN_HAND) )
-    {
-      v17 = this->GetEquippedItemEquipType(EQUIP_MAIN_HAND);
-      if ( v17 >= 0 )
+      if ( this->HasItemEquipped(EQUIP_MAIN_HAND) )
       {
-        if ( v17 <= 2 )
+        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) || (v19 = this->GetEquippedItemEquipType(EQUIP_OFF_HAND), v19 < 0) || v19 > 2 )
-      return v5 + v62 + v61;
-    v20 = this->pOwnItems[this->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 ( this->HasItemEquipped(EQUIP_MAIN_HAND) )
-    {
-      v9 = this->GetEquippedItemEquipType(EQUIP_MAIN_HAND);
-      if ( v9 >= 0 )
+      if ( getOnlyMainHandDmg || !this->HasItemEquipped(EQUIP_OFF_HAND) || (this->GetEquippedItemEquipType(EQUIP_OFF_HAND) < 0) || this->GetEquippedItemEquipType(EQUIP_OFF_HAND) > 2 )
+        return v5;
+      else
       {
-        if ( v9 <= 2 )
+        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)
         {
           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].uDamageMod;
+          if ( !this->pEquipment.uShield && pItemsTable->pItems[this->pOwnItems[this->pEquipment.uMainHand].uItemID].uSkillType == 4)
           {
-            if ( pItemsTable->pItems[this->pOwnItems[this->pEquipment.uMainHand].uItemID].uSkillType == 4 )
-              ++v5;
+            ++v5;
           }
         }
       }
-    }
-    
-    if ( getOnlyMainHandDmg || !this->HasItemEquipped(EQUIP_OFF_HAND))
+
+      if ( getOnlyMainHandDmg || !this->HasItemEquipped(EQUIP_OFF_HAND) || (this->GetEquippedItemEquipType(EQUIP_OFF_HAND) < 0) || this->GetEquippedItemEquipType(EQUIP_OFF_HAND) > 2 )
+      {
+        return v5;
+      }
+      else
+      {
+        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) )
         {
-        v12 = this->GetEquippedItemEquipType(EQUIP_OFF_HAND);
-        if  ((v12 < 0) || v12 > 2 )
-                return v5 + v62 + v61;
+          v31 = this->pEquipment.pIndices[i] - 1;
+          currEquippedItem = &this->pInventoryItemList[v31];
+          if ( attr == CHARACTER_ATTRIBUTE_AC_BONUS )
+          {
+            v32 = GetEquippedItemEquipType((ITEM_EQUIP_TYPE)i);
+            if ( v32 >= 3 && v32 <= 11 )
+            {
+              v33 = currEquippedItem->uItemID;
+              v5 += pItemsTable->pItems[v33].uDamageDice + pItemsTable->pItems[v33].uDamageMod;
+            }
+          }
+          if ( pItemsTable->IsMaterialNonCommon((ItemGen *)(currEquippedItem))
+            && !pItemsTable->IsMaterialSpecial(currEquippedItem) )
+          {
+            currEquippedItem->GetItemBonusArtifact(this, attr, &v62);
+          }
+          else if ( currEquippedItem->uEnchantmentType != 0 )
+          {
+            if (currEquippedItem->IsRegularEnchanmentForAttribute(attr))
+            {
+              if ( attr > CHARACTER_ATTRIBUTE_RESIST_BODY && v5 < currEquippedItem->m_enchantmentStrength )
+                v5 = currEquippedItem->m_enchantmentStrength;
+              else
+                v5 += currEquippedItem->m_enchantmentStrength;
+            }
+          }
+          else
+          {
+            currEquippedItem->GetItemBonusSpecialEnchantment(this, attr, &v5, &v61);
+          }
         }
-    v14 = pItemsTable->pItems[this->pOwnItems[this->pEquipment.uShield].uItemID].uDamageMod;
-    v15 = pItemsTable->pItems[this->pOwnItems[this->pEquipment.uShield].uItemID].uDamageDice;
-    v5 += v15 + v14;
-  }
-  return v5 + v62 + v61;
+      }
+      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
@@ -4574,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:
@@ -4657,7 +4015,7 @@
 
 //----- (004901FC) --------------------------------------------------------
 void Player::SetSexByVoice()
-    {
+{
   switch ( this->uVoiceID)
   {
     case 0:
@@ -4689,6 +4047,7 @@
       this->uSex = SEX_FEMALE;
       break;
     default:
+      Error("(%u)", this->uVoiceID);
       break;
   }
  
@@ -4897,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 )
   {
@@ -5073,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 )
@@ -6305,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);
         }
@@ -6313,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();
@@ -6332,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);
       }
@@ -6354,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;
       }
@@ -7977,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
   {
@@ -8013,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();
     }
@@ -8024,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;
       }
     }
@@ -8123,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)
--- a/Player.h	Mon Sep 16 09:37:08 2013 +0600
+++ b/Player.h	Mon Sep 16 09:37:30 2013 +0600
@@ -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
@@ -580,6 +595,8 @@
   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);
@@ -627,7 +644,6 @@
 
   inline bool IsMale() { return GetSexByVoice() == SEX_MALE;}
   inline bool IsFemale() { return !IsMale();}
-  void GetItemBonusSpecialEnchantment(int enchantmentId, CHARACTER_ATTRIBUTE_TYPE attrToGet, int* additiveBonus, int* halfSkillBonus);
   __int64 pConditions[20];
   unsigned __int64 uExperience;
   char pName[16];
--- a/UI/UICharacter.cpp	Mon Sep 16 09:37:08 2013 +0600
+++ b/UI/UICharacter.cpp	Mon Sep 16 09:37:30 2013 +0600
@@ -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	Mon Sep 16 09:37:08 2013 +0600
+++ b/UI/UIHouses.cpp	Mon Sep 16 09:37:30 2013 +0600
@@ -91,19 +91,19 @@
   {  2,   3,   4,   5},  // HOUSE_STABLES_STEADWICK
   {  6,   7,   8,   8},  // HOUSE_STABLES_TULAREAN_FOREST
   {  9,  10,  10,  10},  // HOUSE_STABLES_DEYJA
-  { 11,  11,  12,  12},  // HOUSE_STABLES_58
-  { 13,  13,  13,  13},  // HOUSE_STABLES_59
-  { 14,  14,  15,  15},  // HOUSE_STABLES_60
+  { 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
@@ -1920,14 +1920,11 @@
   int schedule_id; // esi@39
   GUIButton *pButton; // ebx@39
   signed int v25; // eax@41
-  unsigned int v30; // ecx@62
   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
-  //unsigned int v60; // [sp+274h] [bp-1Ch]@36
   int index; // [sp+27Ch] [bp-14h]@36
-  //char *a1; // [sp+284h] [bp-Ch]@37
   unsigned int pPrice; // [sp+288h] [bp-8h]@1
   int travel_time; // [sp+28Ch] [bp-4h]@48
   enum PlayerSpeech pSpeech;
@@ -1962,8 +1959,8 @@
 
         if (schedule_id != 255)
         {
-          if (schedule_id >= 25)
-            Log::Warning(L"Transport UI: scedule overflow");
+          //if (schedule_id >= 25)
+            //Log::Warning(L"Transport UI: schedule overflow");
           if ( pCurrentButton >= 6 )
             v25 = true;
           else
@@ -1971,9 +1968,9 @@
         }
 
         if (schedule_id != 255 && v25 && (!transport_schedule[schedule_id].uQuestBit
-           || _449B57_test_bit(pParty->_quest_bits, transport_schedule[schedule_id].uQuestBit)) )
+           || _449B57_test_bit(pParty->_quest_bits, transport_schedule[schedule_id].uQuestBit)) )//:      
         {
-//get color for current string(   )------------
+  //get color for current string(   )----------
           if ( pDialogueWindow->pCurrentPosActiveItem == pCurrentButton )
             sprintf(pTopicArray[index], "\f%05d", TargetColor(255, 255, 155));
           else
@@ -2007,9 +2004,8 @@
             strcat(pTopicArray[index], "\n \n");
             pButton->uY = pRealTextHeight;
             pTextHeight = pFontArrus->CalcTextHeight(pTmpBuf.data(), &travel_window, 0, 0);
-            v30 = pButton->uY;
             pButton->uHeight = pTextHeight;
-            pButton->uW = v30 + pTextHeight - 1;
+            pButton->uW = pButton->uY + pTextHeight - 1;
             pRealTextHeight += (LOBYTE(pFontArrus->uFontHeight) - 3) + pTextHeight;
           }
         }
@@ -2151,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
@@ -2192,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;
         }
@@ -2408,8 +2402,6 @@
   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
@@ -2423,11 +2415,9 @@
   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
@@ -2441,15 +2431,12 @@
   signed int v48; // 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
@@ -2467,14 +2454,10 @@
   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
   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
@@ -2485,18 +2468,15 @@
   unsigned __int8 pTopic4Height;
   int pTextHeight;
 
-  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;
+  pItemNum = v3 * (100 - pPlayers[uActiveCharacter]->GetMerchant()) / 100;
   if ( pItemNum < v3 / 3 )
     pItemNum = v3 / 3;
   v5 = 1;
@@ -2504,7 +2484,7 @@
   if ( pItemNum <= 0 )
     pOutString = (GUIFont *)1;
   v6 = (signed __int64)(*(float *)&v89 * *(float *)&v83 * 0.0099999998);
-  v7 = v6 * (100 - pPlayer->GetMerchant()) / 100;
+  v7 = v6 * (100 - pPlayers[uActiveCharacter]->GetMerchant()) / 100;
   if ( v7 < v6 / 3 )
   v7 = v6 / 3;
   v83 = v7;
@@ -2521,36 +2501,36 @@
       if ( !HouseUI_CheckIfPlayerCanInteract() )
           return;
 
-      sprintf(pTopic1, "\f%05d", pDialogueWindow->pCurrentPosActiveItem == 2 ? pColorYellow : pColorWhite);
+      sprintf(pTopic1, "\f%05d", pDialogueWindow->pCurrentPosActiveItem == 2 ? TargetColor(0xFFu, 0xFFu, 0x9Bu) : TargetColor(0xFFu, 0xFFu, 0xFFu));
       sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[178], pOutString); // 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);
       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 ( pNumActiveItem = pDialogueWindow->pStartingPosActiveItem;
+              pNumActiveItem < pDialogueWindow->pStartingPosActiveItem + pDialogueWindow->pNumPresenceButton; ++pNumActiveItem )
         {
           pButton = pDialogueWindow->GetControl(pNumActiveItem);
           if ( pButton->msg_param == 15 )
@@ -2588,14 +2568,9 @@
             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);
-          }
         }
-        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;
     }
@@ -2649,7 +2624,7 @@
       }
       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);
+      dialog_window.DrawTitleText(pFontArrus, 0, v66, TargetColor(0xFFu, 0xFFu, 0x9Bu), pTmpBuf.data(), 3);
       break;
     }
     case HOUSE_DIALOGUE_TAVERN_REST:
@@ -2685,7 +2660,7 @@
         return;
       v0 = 0;
       v9 = (signed __int64)(p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].flt_24 * 500.0);
-      pItemNum = v9 * (100 - pPlayer->GetMerchant()) / 100;
+      pItemNum = v9 * (100 - pPlayers[uActiveCharacter]->GetMerchant()) / 100;
       if ( pItemNum < v9 / 3 )
         pItemNum = v9 / 3;
       pNumActiveItem = pDialogueWindow->pStartingPosActiveItem;
@@ -2695,7 +2670,8 @@
         do
         {
           v12 = pDialogueWindow->GetControl(pNumActiveItem)->msg_param - 36;
-          if ( byte_4ED970_skill_learn_ability_by_class_table[pPlayer->classType][v12] && !pPlayer->pActiveSkills[v12] )
+          if ( byte_4ED970_skill_learn_ability_by_class_table[pPlayers[uActiveCharacter]->classType][v12]
+              && !pPlayers[uActiveCharacter]->pActiveSkills[v12] )
           {
             all_text_height = pFontArrus->CalcTextHeight(pSkillNames[v12], &dialog_window, 0, 0);
             v0++;
@@ -2719,7 +2695,8 @@
             {
               pButton = pDialogueWindow->GetControl(pItemNum);
               v17 = pButton->msg_param - 36;
-              if ( !byte_4ED970_skill_learn_ability_by_class_table[pPlayer->classType][v17] || pPlayer->pActiveSkills[v17] )
+              if ( !byte_4ED970_skill_learn_ability_by_class_table[pPlayers[uActiveCharacter]->classType][v17]
+                 || pPlayers[uActiveCharacter]->pActiveSkills[v17] )
               {
                 pButton->uW = 0;
                 pButton->uHeight = 0;
@@ -2732,9 +2709,9 @@
                 pButton->uHeight = pTextHeight;
                 v14 = pTextHeight + pButton->uY - 1;
                 pButton->uW = v14;
-                pColorText = pColorYellow;
+                pColorText = TargetColor(0xFFu, 0xFFu, 0x9Bu);
                 if ( pDialogueWindow->pCurrentPosActiveItem != pItemNum )
-                  pColorText = pColorWhite;
+                  pColorText = TargetColor(0xFFu, 0xFFu, 0xFFu);
                 dialog_window.DrawTitleText(pFontArrus, 0, pButton->uY, pColorText, pSkillNames[v17], 3);
               }
               pNumActiveItem = pDialogueWindow->pStartingPosActiveItem + pDialogueWindow->pNumPresenceButton;
@@ -2745,11 +2722,12 @@
           return;
         }
       }
-      sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[544], pPlayer->pName, pClassNames[pPlayer->classType]);
+      sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[544], pPlayers[uActiveCharacter]->pName,
+              pClassNames[pPlayers[uActiveCharacter]->classType]);
       strcat(pTmpBuf.data(), "\n \n");
       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;
     }
 
@@ -2798,7 +2776,7 @@
         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;
+        //v37 = -pDialogueWindow->pNumPresenceButton < 0;
         if ( pNumActiveItem < pNumActiveItem + pDialogueWindow->pNumPresenceButton )
         {
           pItemNum = 2;
@@ -2811,9 +2789,9 @@
             pButton->uHeight = pTextHeight;
             v54 = pButton->uY + pTextHeight - 1;
             pButton->uW = v54;
-            pColorText = pColorYellow;
+            pColorText = TargetColor(0xFFu, 0xFFu, 0x9Bu);
             if ( pDialogueWindow->pCurrentPosActiveItem != pItemNum )
-              pColorText = pColorWhite;
+              pColorText = TargetColor(0xFFu, 0xFFu, 0xFFu);
             dialog_window.DrawTitleText(pFontArrus, 0, pButton->uY, pColorText, (const char *)pShopOptions[pNumString], 3);
             pItemNum++;
             ++pNumString;
@@ -2833,407 +2811,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 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[window_SpeakInHouse->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 = pPlayers[uActiveCharacter]->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[pPlayers[uActiveCharacter]->classType][v9] && !pPlayers[uActiveCharacter]->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[pPlayers[uActiveCharacter]->classType][v16] || pPlayers[uActiveCharacter]->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], pPlayers[uActiveCharacter]->pName, pClassNames[pPlayers[uActiveCharacter]->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 )
-        {
-                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];
-                pPlayers[uActiveCharacter]->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;
-        }
-        if ( !pPlayers[uActiveCharacter]->IsPlayerHealableByTemple() )
-            return;
-        v25 = 0;
-        if ( pParty->uNumGold < v2 )
-        {
-          ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2u);
-          PlayHouseSound((unsigned int)window_SpeakInHouse->ptr_1C, HouseSound_NotEnoughMoney_TrainingSuccessful);
-          pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, v25);
-          return;
-        }
-        Party::TakeGold(v2);
-        v35 = LODWORD(pPlayers[uActiveCharacter]->pConditions[17]);
-        v59 = pPlayers[uActiveCharacter]->pConditions[14];
-        v58 = pPlayers[uActiveCharacter]->pConditions[15];
-        v60 = pPlayers[uActiveCharacter]->pConditions[16];
-        v61 = (GUIWindow *)HIDWORD(pPlayers[uActiveCharacter]->pConditions[17]);
-        memset(pPlayers[uActiveCharacter], 0, 0xA0u);
-        pPlayers[uActiveCharacter]->sHealth = pPlayers[uActiveCharacter]->GetMaxHealth();
-        pPlayers[uActiveCharacter]->sMana = pPlayers[uActiveCharacter]->GetMaxMana();
-        v36 = (signed int)window_SpeakInHouse->ptr_1C;
-        if ( v36 != 78 && (v36 <= 80 || v36 > 82) )
-            {
-            if ( (unsigned int)v61 | v35 )
-                {
-                v37 = LOBYTE(pPlayers[uActiveCharacter]->uPrevFace);
-                v38 = pPlayers[uActiveCharacter]->uPrevVoiceID;
-                pPlayers[uActiveCharacter]->uCurrentFace = v37;
-                pPlayers[uActiveCharacter]->uVoiceID = v38;
-                ReloadPlayerPortraits(uActiveCharacter - 1, (char)v37);
-                }
-            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, v25);
-            return;
-            }
-        v39 = v61;
-        if ( (unsigned int)v61 | v35 )
-            {
-            LODWORD(pPlayers[uActiveCharacter]->pConditions[17]) = v35;
-            }
-        else
-            {
-            if ( !v60 && !v58 && !v59 )
-            {
-              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, v25);
-              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;
-            v40 = (pPlayers[uActiveCharacter]->GetSexByVoice() != 0) + 23;
-            pPlayers[uActiveCharacter]->uCurrentFace = v40;
-            ReloadPlayerPortraits(uActiveCharacter - 1, (char)v40);
-            LODWORD(pPlayers[uActiveCharacter]->pConditions[17]) = LODWORD(pParty->uTimePlayed);
-            v39 = (GUIWindow *)HIDWORD(pParty->uTimePlayed);
-            }
-        HIDWORD(pPlayers[uActiveCharacter]->pConditions[17]) = (int)v39;
+        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, v25);
-        return; // void func
-        }
-    v63 = 1;
-    v41 = pDialogueWindow->GetControl(pDialogueWindow->pStartingPosActiveItem);
-    strcpy(a1, "");
-    v41->uHeight = 0;
-    v41->uY = 0;
-    if ( pPlayers[uActiveCharacter]->IsPlayerHealableByTemple() )
+        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 )
         {
-        sprintf(a1, "%s %d %s", pGlobalTXT_LocalizationStrings[104], HIDWORD(v60), pGlobalTXT_LocalizationStrings[97]);
-        v63 = 0;
+          v30 = pParty->uDaysPlayed % 7 + 1;
+          LOBYTE(v30) = v30 | 0x80;
+          _42777D_CastSpell_UseWand_ShootArrow(SPELL_AIR_WIZARD_EYE, uActiveCharacter - 1, v30, 48, 0);
         }
-    strcpy(&a1[100], pGlobalTXT_LocalizationStrings[68]);
-    strcpy(&a1[200], pGlobalTXT_LocalizationStrings[160]);
-    v42 = v63;
-    v43 = pDialogueWindow;
-    v44 = v63;
-    v66 = 0;
-    if ( v63 < pDialogueWindow->pNumPresenceButton )
+        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 )
         {
-        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 );
+          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);
         }
-    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 )
+      }
+      ++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] )
         {
-        v61 = (GUIWindow *)(v42 + 2);
-        v66 = (DDM_DLV_Header *)&a1[100 * v42];
-        do
+          all_text_height += pFontArrus->CalcTextHeight(pSkillNames[pDialogueWindow->GetControl(i)->msg_param - 36], &tample_window, 0, 0);
+          ++pCurrentItem;
+        }
+      }
+      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] )
             {
-            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;
+              pButton->uW = 0;
+              pButton->uHeight = 0;
+              pButton->uY = 0;
+            }
+            else
+            {
+              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);
             }
-            while ( (signed int)v65 < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem );
+            pCurrentItem++;
+          }
         }
-    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
@@ -3243,222 +3096,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;
@@ -3474,115 +3235,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) --------------------------------------------------------
@@ -3810,8 +3568,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
@@ -4024,15 +3780,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);
@@ -4060,19 +3816,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/UiGame.cpp	Mon Sep 16 09:37:08 2013 +0600
+++ b/UI/UiGame.cpp	Mon Sep 16 09:37:30 2013 +0600
@@ -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	Mon Sep 16 09:37:08 2013 +0600
+++ b/mm7_1.cpp	Mon Sep 16 09:37:30 2013 +0600
@@ -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_4.cpp	Mon Sep 16 09:37:08 2013 +0600
+++ b/mm7_4.cpp	Mon Sep 16 09:37:30 2013 +0600
@@ -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;
--- a/mm7_5.cpp	Mon Sep 16 09:37:08 2013 +0600
+++ b/mm7_5.cpp	Mon Sep 16 09:37:30 2013 +0600
@@ -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	Mon Sep 16 09:37:08 2013 +0600
+++ b/mm7_data.cpp	Mon Sep 16 09:37:30 2013 +0600
@@ -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;
--- a/mm7_data.h	Mon Sep 16 09:37:08 2013 +0600
+++ b/mm7_data.h	Mon Sep 16 09:37:30 2013 +0600
@@ -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;
@@ -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);