changeset 1611:8e99b4a7176f

Слияние
author Ritor1
date Sat, 14 Sep 2013 10:28:23 +0600
parents fa0e700bcc80 (current diff) 4b79ff62df3a (diff)
children 11f12a34b397
files
diffstat 9 files changed, 955 insertions(+), 1061 deletions(-) [+]
line wrap: on
line diff
--- a/Actor.cpp	Sat Sep 14 10:28:13 2013 +0600
+++ b/Actor.cpp	Sat Sep 14 10:28:23 2013 +0600
@@ -5327,7 +5327,7 @@
     player->ReceiveDamage(uDamageAmount, (DAMAGE_TYPE)a2);
   v50 = 24;
   v59 = 20 * v61 / (signed int)pMonster->pMonsterInfo.uHP;
-  if ( (player->_48EA46_calc_special_bonus_by_items(24) || hit_will_stun != v41)
+  if ( (player->GetSpecialItemBonus(24) || hit_will_stun != v41)
     && stru_50C198.GetMagicalResistance(pMonster, 3u) )
   {
     LODWORD(v42) = 20;
--- a/CastSpellInfo.cpp	Sat Sep 14 10:28:13 2013 +0600
+++ b/CastSpellInfo.cpp	Sat Sep 14 10:28:23 2013 +0600
@@ -1949,7 +1949,7 @@
 				v245->uItemID <= 134 &&
 				v245->uSpecEnchantmentType == 0 &&
 				v245->uEnchantmentType == 0 &&
-				v245->_bonus_strength== 0 &&
+				v245->m_enchantmentStrength== 0 &&
 				!v245->IsBroken() )
 			{
 				if ( v245->GetValue() < 450 || 
@@ -1982,7 +1982,7 @@
 						}
 						v255 = 10;//pItemsTable->field_116D8[17];
 						v256 = 10;//pItemsTable->field_116D8[16];
-						v245->_bonus_strength = v256 + rand() % (v255 - v256 + 1);
+						v245->m_enchantmentStrength = v256 + rand() % (v255 - v256 + 1);
 						v245->uAttributes |= 0x20u;
 						_50C9A8_item_enchantment_timer = 256;
 						LODWORD(v727) = 1;
--- a/Items.cpp	Sat Sep 14 10:28:13 2013 +0600
+++ b/Items.cpp	Sat Sep 14 10:28:23 2013 +0600
@@ -255,7 +255,7 @@
   this->uAttributes = 0;
   this->uNumCharges = 0;
   this->uSpecEnchantmentType = 0;
-  this->_bonus_strength = 0;
+  this->m_enchantmentStrength = 0;
   this->uEnchantmentType = 0;
   this->uItemID = 0;
   this->uBodyAnchor = 0;
@@ -792,7 +792,7 @@
 						{
 						for(int ii=0; ii<24; ++ii)
 							{
-							if (_stricmp(test_string,pEnchantments[ii].pBonusStat))
+							if (!_stricmp(test_string,pEnchantments[ii].pOfName))
 								{
 								pItems[item_counter]._bonus_type=ii+1;
 								break;
@@ -802,7 +802,7 @@
 							{
 							for(int ii=0; ii<72; ++ii)
 								{
-								if (_stricmp(test_string,pSpecialEnchantments[ii].pBonusStatement))
+								if (!_stricmp(test_string,pSpecialEnchantments[ii].pNameAdd))
 									{
 									pItems[item_counter]._additional_value=ii+1;
 									}
@@ -1245,6 +1245,13 @@
 			} while ((decode_step<2)&&!break_loop);
 		}
 
+
+  
+  ItemGen::PopulateSpecialBonusMap();
+  ItemGen::PopulateArtifactBonusMap();
+  ItemGen::PopulateRegularBonusMap();
+  
+
 	}
 
 //----- (00456D17) --------------------------------------------------------
@@ -1254,7 +1261,7 @@
   {
     pItem->uEnchantmentType = pItems[pItem->uItemID]._bonus_type;
     pItem->uSpecEnchantmentType = pItems[pItem->uItemID]._additional_value;
-    pItem->_bonus_strength = pItems[pItem->uItemID]._bonus_strength;
+    pItem->m_enchantmentStrength = pItems[pItem->uItemID]._bonus_strength;
   }
 }
 
@@ -1443,7 +1450,7 @@
 	if ( this->uAttributes & ITEM_TEMP_BONUS || pItemsTable->IsMaterialNonCommon(this) )
 		return uBaseValue;
 	if (uEnchantmentType )
-		return uBaseValue + 100 * _bonus_strength;;
+		return uBaseValue + 100 * m_enchantmentStrength;;
 	if (uSpecEnchantmentType )
 		{
 		bonus = pItemsTable->pSpecialEnchantments[uSpecEnchantmentType].iTreasureLevel;
@@ -1797,12 +1804,12 @@
             ++out_item->uEnchantmentType;
 
             v33 = rand() % (bonus_ranges[v6].maxR - bonus_ranges[v6].minR + 1);
-            out_item->_bonus_strength = v33 + bonus_ranges[v6].minR;
+            out_item->m_enchantmentStrength = v33 + bonus_ranges[v6].minR;
             v32 = out_item->uEnchantmentType - 1;
             if ( v32 == 21 || v32 == 22 || v32 == 23 ) //Armsmaster skill, Dodge skill, Unarmed skill 
-                out_item->_bonus_strength = out_item->_bonus_strength/2;
-            if ( out_item->_bonus_strength <= 0 )
-                out_item->_bonus_strength = 1;
+                out_item->m_enchantmentStrength = out_item->m_enchantmentStrength/2;
+            if ( out_item->m_enchantmentStrength <= 0 )
+                out_item->m_enchantmentStrength = 1;
             return;
             
             }
@@ -1915,6 +1922,482 @@
     return false;
 
 }
+
+std::map<int, std::map<CHARACTER_ATTRIBUTE_TYPE, CEnchantment*>* >ItemGen::regularBonusMap;
+std::map<int, std::map<CHARACTER_ATTRIBUTE_TYPE, CEnchantment*>* >ItemGen::specialBonusMap;
+std::map<int, std::map<CHARACTER_ATTRIBUTE_TYPE, CEnchantment*>* >ItemGen::artifactBonusMap;
+
+#define NEWBONUSINTOSPECIALLIST(x,y) AddToMap(ItemGen::specialBonusMap, enchId, x, y);
+#define NEWBONUSINTOSPECIALLIST2(x,y,z) AddToMap(ItemGen::specialBonusMap, enchId, x, y, z);
+
+#define NEWBONUSINTOREGULARLIST(x) AddToMap(ItemGen::regularBonusMap, enchId, x);
+
+#define NEWBONUSINTOARTIFACTLIST(x,y) AddToMap(ItemGen::artifactBonusMap, itemId, x, y);
+#define NEWBONUSINTOARTIFACTLIST2(x,y,z) AddToMap(ItemGen::artifactBonusMap, itemId, x, y, z);
+
+void ItemGen::AddToMap( std::map<int, std::map<CHARACTER_ATTRIBUTE_TYPE, CEnchantment*>* > &maptoadd, int enchId, CHARACTER_ATTRIBUTE_TYPE attrId, int bonusValue /*= 0*/, unsigned __int16 Player::* skillPtr /*= NULL*/ )
+{
+  auto key = maptoadd.find(enchId);
+  std::map<CHARACTER_ATTRIBUTE_TYPE, CEnchantment*>* currMap;
+  if (key == maptoadd.end())
+  {
+    currMap = new std::map<CHARACTER_ATTRIBUTE_TYPE, CEnchantment*>;
+    maptoadd[enchId] = currMap;
+  }
+  else
+  {
+    currMap = key->second;
+  }
+  Assert(currMap->find(attrId) == currMap->end(), "Attribute %d already present for enchantment %d", attrId, enchId);
+  (*currMap)[attrId] = new CEnchantment(bonusValue, skillPtr);
+}
+
+void ItemGen::PopulateSpecialBonusMap()
+{
+  int enchId = 1;// of Protection, +10 to all Resistances
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_RESIST_FIRE, 10);
+  NEWBONUSINTOSPECIALLIST( CHARACTER_ATTRIBUTE_RESIST_AIR, 10);
+  NEWBONUSINTOSPECIALLIST( CHARACTER_ATTRIBUTE_RESIST_WATER, 10);
+  NEWBONUSINTOSPECIALLIST( CHARACTER_ATTRIBUTE_RESIST_EARTH, 10);
+  NEWBONUSINTOSPECIALLIST( CHARACTER_ATTRIBUTE_RESIST_MIND, 10);
+  NEWBONUSINTOSPECIALLIST( CHARACTER_ATTRIBUTE_RESIST_BODY, 10);
+
+  enchId = 2;//of The Gods, +10 to all Seven Statistics
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_STRENGTH, 10);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_INTELLIGENCE, 10);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_WILLPOWER, 10);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_ENDURANCE, 10);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_ACCURACY, 10);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_SPEED, 10);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_LUCK, 10);
+
+  enchId = 26;//of Air Magic
+  NEWBONUSINTOSPECIALLIST2(CHARACTER_ATTRIBUTE_SKILL_AIR,0, &Player::skillAir);
+
+  enchId = 27;//of Body Magic
+  NEWBONUSINTOSPECIALLIST2(CHARACTER_ATTRIBUTE_SKILL_BODY,0, &Player::skillBody);
+
+  enchId = 28;//of Dark Magic
+  NEWBONUSINTOSPECIALLIST2(CHARACTER_ATTRIBUTE_SKILL_DARK,0, &Player::skillDark);
+
+  enchId = 29;//of Earth Magic
+  NEWBONUSINTOSPECIALLIST2(CHARACTER_ATTRIBUTE_SKILL_EARTH,0, &Player::skillEarth);
+
+  enchId = 30;//of Fire Magic
+  NEWBONUSINTOSPECIALLIST2(CHARACTER_ATTRIBUTE_SKILL_FIRE,0, &Player::skillFire);
+
+  enchId = 31;//of Light Magic
+  NEWBONUSINTOSPECIALLIST2(CHARACTER_ATTRIBUTE_SKILL_LIGHT,0, &Player::skillLight);
+
+  enchId = 32;//of Mind Magic
+  NEWBONUSINTOSPECIALLIST2(CHARACTER_ATTRIBUTE_SKILL_MIND,0, &Player::skillMind);
+
+  enchId = 33;//of Spirit Magic
+  NEWBONUSINTOSPECIALLIST2(CHARACTER_ATTRIBUTE_SKILL_SPIRIT,0, &Player::skillSpirit);
+
+  enchId = 34;//of Water Magic
+  NEWBONUSINTOSPECIALLIST2(CHARACTER_ATTRIBUTE_SKILL_WATER,0, &Player::skillWater);
+
+  enchId = 42;//of Doom
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_STRENGTH, 1);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_INTELLIGENCE, 1);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_WILLPOWER, 1);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_ENDURANCE, 1);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_ACCURACY, 1);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_SPEED, 1);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_LUCK, 1);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_HEALTH, 1);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_MANA, 1);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_AC_BONUS, 1);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_RESIST_FIRE, 1);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_RESIST_AIR, 1);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_RESIST_WATER, 1);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_RESIST_EARTH, 1);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_RESIST_MIND, 1);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_RESIST_BODY, 1);
+
+  enchId = 43;//of Earth
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_ENDURANCE, 10);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_AC_BONUS, 10);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_HEALTH, 10);
+
+  enchId = 44;//of Life
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_HEALTH, 10);
+
+  enchId = 45;//Rogues
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_SPEED, 5);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_ACCURACY, 5);
+
+  enchId = 46;//of The Dragon
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_STRENGTH, 25);
+
+  enchId = 47;//of The Eclipse
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_MANA, 10);
+
+  enchId = 48;//of The Golem
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_ENDURANCE, 15);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_AC_BONUS, 5);
+
+  enchId = 49;//of The Moon
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_INTELLIGENCE, 10);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_LUCK, 10);
+
+  enchId = 50;//of The Phoenix
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_RESIST_FIRE, 30);
+
+  enchId = 51;//of The Sky
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_MANA, 10);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_SPEED, 10);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_INTELLIGENCE, 10);
+
+  enchId = 52;//of The Stars
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_ENDURANCE, 10);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_ACCURACY, 10);
+
+  enchId = 53;//of The Sun
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_STRENGTH, 10);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_WILLPOWER, 10);
+
+  enchId = 54;//of The Troll
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_ENDURANCE, 15);
+
+  enchId = 55;//of The Unicorn
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_LUCK, 15);
+
+  enchId = 56;//Warriors
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_STRENGTH, 5);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_ENDURANCE, 5);
+
+  enchId = 57;//Wizards
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_INTELLIGENCE, 5);
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_WILLPOWER, 5);
+
+  enchId = 60;//Monks'
+  NEWBONUSINTOSPECIALLIST2(CHARACTER_ATTRIBUTE_SKILL_DODGE, 3, &Player::skillDodge);
+  NEWBONUSINTOSPECIALLIST2(CHARACTER_ATTRIBUTE_SKILL_UNARMED, 3, &Player::skillUnarmed);
+
+  enchId = 61;//Thieves'
+  NEWBONUSINTOSPECIALLIST2(CHARACTER_ATTRIBUTE_SKILL_TRAP_DISARM, 3, &Player::skillStealing);
+  NEWBONUSINTOSPECIALLIST2(CHARACTER_ATTRIBUTE_SKILL_STEALING, 3, &Player::skillDisarmTrap);
+
+  enchId = 62;//of Identifying
+  NEWBONUSINTOSPECIALLIST2(CHARACTER_ATTRIBUTE_SKILL_ITEM_ID, 3, &Player::skillItemId);
+  NEWBONUSINTOSPECIALLIST2(CHARACTER_ATTRIBUTE_SKILL_MONSTER_ID, 3, &Player::skillMonsterId);
+
+  enchId = 67;//Assassins'
+  NEWBONUSINTOSPECIALLIST2(CHARACTER_ATTRIBUTE_SKILL_TRAP_DISARM, 2, &Player::skillDisarmTrap);
+
+  enchId = 68;//Barbarians'
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_AC_BONUS, 5);
+
+  enchId = 69;//of the Storm
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_RESIST_AIR, 20);
+
+  enchId = 70;//of the Ocean
+  NEWBONUSINTOSPECIALLIST(CHARACTER_ATTRIBUTE_RESIST_WATER, 10);
+  NEWBONUSINTOSPECIALLIST2(CHARACTER_ATTRIBUTE_SKILL_ALCHEMY, 2, &Player::skillAlchemy);
+}
+
+void ItemGen::PopulateRegularBonusMap()
+{
+  int enchId = 1;//of Might
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_STRENGTH);
+
+  enchId = 2;//of Thought
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_INTELLIGENCE);
+
+  enchId = 3;//of Charm
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_WILLPOWER);
+
+  enchId = 4;//of Vigor 
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_ENDURANCE);
+
+  enchId = 5;//of Precision 
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_ACCURACY);
+
+  enchId = 6;//of Speed 
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_SPEED);
+
+  enchId = 7;//of Luck 
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_LUCK);
+
+  enchId = 8;//of Health 
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_HEALTH);
+
+  enchId = 9;//of Magic 
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_MANA);
+
+  enchId = 10;//of Defense 
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_AC_BONUS);
+
+  enchId = 11;//of Fire Resistance 
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_RESIST_FIRE);
+
+  enchId = 12;//of Air Resistance 
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_RESIST_AIR);
+
+  enchId = 13;//of Water Resistance 
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_RESIST_WATER);
+
+  enchId = 14;//of Earth Resistance 
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_RESIST_EARTH);
+
+  enchId = 15;//of Mind Resistance 
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_RESIST_MIND);
+
+  enchId = 16;//of Body Resistance 
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_RESIST_BODY);
+
+  enchId = 17;//of Alchemy 
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_SKILL_ALCHEMY);
+
+  enchId = 18;//of Stealing 
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_SKILL_STEALING);
+
+  enchId = 19;//of Disarming 
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_SKILL_TRAP_DISARM);
+
+  enchId = 20;//of Items 
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_SKILL_ITEM_ID);
+
+  enchId = 21;//of Monsters 
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_SKILL_MONSTER_ID);
+
+  enchId = 22;//of Arms 
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_SKILL_ARMSMASTER);
+
+  enchId = 23;//of Dodging 
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_SKILL_DODGE);
+
+  enchId = 24;//of the Fist
+  NEWBONUSINTOREGULARLIST(CHARACTER_ATTRIBUTE_SKILL_UNARMED);
+}
+
+void ItemGen::PopulateArtifactBonusMap()
+{
+  int itemId;
+  itemId = ITEM_ARTIFACT_PUCK;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_STRENGTH, 40);
+
+  itemId = ITEM_ARTIFACT_IRON_FEATHER;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_STRENGTH, 40);
+
+  itemId = ITEM_ARTIFACT_WALLACE;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_WILLPOWER, 40);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_ARMSMASTER, 10);
+
+  itemId = ITEM_ARTIFACT_CORSAIR;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_LUCK, 40);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_TRAP_DISARM, 5);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_STEALING, 5);
+
+  itemId = ITEM_ARTICACT_GOVERNONS_ARMOR;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_STRENGTH, 10);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_INTELLIGENCE, 10);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_WILLPOWER, 10);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_ENDURANCE, 10);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_ACCURACY, 10);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SPEED, 10);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_LUCK, 10);
+
+  itemId = ITEM_ARTIFACT_YORUBA;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_ENDURANCE, 25);
+
+  itemId = ITEM_ARTIFACT_SPLITTER;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_FIRE, 50);
+
+  itemId = ITEM_ARTEFACT_ULLYSES,
+    NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_ACCURACY, 50);
+
+  itemId = ITEM_ARTEFACT_HANDS_OF_THE_MASTER,
+    NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_DODGE, 10);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_UNARMED, 10);
+
+  itemId = ITEM_ARTIFACT_LEAGUE_BOOTS;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SPEED, 40);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_WATER, 0, &Player::skillWater);
+
+  itemId = ITEM_ARTIFACT_RULERS_RING;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_MIND, 0, &Player::skillMind);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_DARK, 0, &Player::skillDark);
+
+  itemId = ITEM_RELIC_MASH;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_STRENGTH, 150);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_INTELLIGENCE, -40);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_WILLPOWER, -40);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SPEED, -40);
+
+  itemId = ITEM_RELIC_ETHRICS_STAFF;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_DARK, 0, &Player::skillDark);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_MEDITATION, 15);
+
+  itemId = ITEM_RELIC_HARECS_LEATHER;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_TRAP_DISARM, 5);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_STEALING, 5);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_LUCK, 50);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_FIRE, -10);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_WATER, -10);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_AIR, -10);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_EARTH, -10);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_MIND, -10);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_BODY, -10);
+
+  itemId = ITEM_RELIC_OLD_NICK;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_TRAP_DISARM, 5);
+
+  itemId = ITEM_RELIC_AMUCK;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_STRENGTH, 100);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_ENDURANCE, 100);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_AC_BONUS, -15);
+
+  itemId = ITEM_RELIC_GLORY_SHIELD;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_SPIRIT, 0, &Player::skillSpirit);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_SHIELD, 5);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_MIND, -10);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_BODY, -10);
+
+  itemId = ITEM_RELIC_KELEBRIM;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_ENDURANCE, 50);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_EARTH, -30);
+
+  itemId = ITEM_RELIC_TALEDONS_HELM;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_LIGHT, 0, &Player::skillLight);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_WILLPOWER, 15);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_STRENGTH, 15);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_LUCK, -40);
+
+  itemId = ITEM_RELIC_SCHOLARS_CAP;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_LEARNING, +15);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_ENDURANCE, -50);
+
+  itemId = ITEM_RELIC_PHYNAXIAN_CROWN;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_FIRE, 0, &Player::skillFire);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_WATER, +50);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_WILLPOWER, 30);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_AC_BONUS, -20);
+
+  itemId = ITEM_RILIC_TITANS_BELT;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_STRENGTH, 75);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SPEED, -40);
+
+  itemId = ITEM_RELIC_TWILIGHT;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SPEED, 50);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_LUCK, 50);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_FIRE, -15);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_WATER, -15);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_AIR, -15);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_EARTH, -15);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_MIND, -15);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_BODY, -15);
+
+  itemId = ITEM_RELIC_ANIA_SELVING;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_ACCURACY, 150);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_BOW, 5);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_AC_BONUS, -25);
+
+  itemId = ITEM_RELIC_JUSTICE;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_MIND, 0, &Player::skillMind);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_BODY, 0, &Player::skillBody);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SPEED, -40);
+
+  itemId = ITEM_RELIC_MEKORIGS_HAMMER;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_SPIRIT, 0, &Player::skillSpirit);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_STRENGTH, 75);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_AIR, -50);
+
+  itemId = ITEM_ARTIFACT_HERMES_SANDALS;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SPEED, 100);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_ACCURACY, 50);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_AIR, 50);
+
+  itemId = ITEM_ARTIFACT_CLOAK_OF_THE_SHEEP;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_WILLPOWER, -20);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_INTELLIGENCE, -20);
+
+  itemId = ITEM_ARTIFACT_MINDS_EYE;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_WILLPOWER, 15);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_INTELLIGENCE, 15);
+
+  itemId = ITEM_ELVEN_CHAINMAIL;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SPEED, 15);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_ACCURACY, 15);
+
+  itemId = ITEM_FORGE_GAUNTLETS;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_STRENGTH, 15);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_ENDURANCE, 15);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_RESIST_FIRE, 30);
+
+  itemId = ITEM_ARTIFACT_HEROS_BELT;
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_STRENGTH, 15);
+  NEWBONUSINTOARTIFACTLIST(CHARACTER_ATTRIBUTE_SKILL_ARMSMASTER, 5);
+}
+
+void ItemGen::GetItemBonusSpecialEnchantment( Player* owner, CHARACTER_ATTRIBUTE_TYPE attrToGet, int* additiveBonus, int* halfSkillBonus )
+{
+  auto bonusList = ItemGen::specialBonusMap.find(this->uSpecEnchantmentType);
+  if (bonusList == ItemGen::specialBonusMap.end())
+  {
+    return;
+  }
+  std::map<CHARACTER_ATTRIBUTE_TYPE, CEnchantment*>* currList = bonusList->second;
+  if (currList->find(attrToGet) != currList->end())
+  {
+    CEnchantment* currBonus = (*currList)[attrToGet];
+    if (currBonus->statPtr != NULL)
+    {
+      if (currBonus->statBonus == 0)
+      {
+        *halfSkillBonus = owner->*currBonus->statPtr / 2;
+      }
+      else
+      {
+        if (*additiveBonus < currBonus->statBonus)
+        {
+          *additiveBonus = currBonus->statBonus;
+        }
+      }
+    }
+    else
+    {
+      *additiveBonus += currBonus->statBonus;
+    }
+  }
+}
+
+void ItemGen::GetItemBonusArtifact( Player* owner, CHARACTER_ATTRIBUTE_TYPE attrToGet, int* bonusSum )
+{
+  auto bonusList = ItemGen::artifactBonusMap.find(this->uItemID);
+  if (bonusList == ItemGen::artifactBonusMap.end())
+  {
+    return;
+  }
+  std::map<CHARACTER_ATTRIBUTE_TYPE, CEnchantment*>* currList = bonusList->second;
+  if (currList->find(attrToGet) != currList->end())
+  {
+    CEnchantment* currBonus = (*currList)[attrToGet];
+    if (currBonus->statPtr != NULL)
+    {
+      *bonusSum = owner->*currBonus->statPtr / 2;
+    }
+    else
+    {
+      *bonusSum += currBonus->statBonus;
+    }
+  }
+}
+
+bool ItemGen::IsRegularEnchanmentForAttribute( CHARACTER_ATTRIBUTE_TYPE attrToGet )
+{
+  auto bonusList = ItemGen::specialBonusMap.find(this->uSpecEnchantmentType);
+  if (bonusList == ItemGen::specialBonusMap.end())
+  {
+    return false;
+  }
+  std::map<CHARACTER_ATTRIBUTE_TYPE, CEnchantment*>* currList = bonusList->second;
+  return (currList->find(attrToGet) != currList->end());
+  return false;
+}
+
 //----- (004B8E3D) --------------------------------------------------------
 void GenerateStandartShopItems()
 	{
--- a/Items.h	Sat Sep 14 10:28:13 2013 +0600
+++ b/Items.h	Sat Sep 14 10:28:23 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;}
@@ -204,7 +246,7 @@
 
   int uItemID; //0
   int uEnchantmentType; //4
-  int _bonus_strength;  //8
+  int m_enchantmentStrength;  //8
   int uSpecEnchantmentType; // 25  +5 levels //0c
                             // 16  Drain Hit Points from target.
                             // 35  Increases chance of disarming.
--- a/Player.cpp	Sat Sep 14 10:28:13 2013 +0600
+++ b/Player.cpp	Sat Sep 14 10:28:23 2013 +0600
@@ -156,8 +156,6 @@
    30   // PLAYER_SKILL_PLATE
 };
 
-
-
 //----- (00490913) --------------------------------------------------------
 int PlayerCreation_GetUnspentAttributePointCount()
 {
@@ -1140,7 +1138,7 @@
 {
   unsigned __int16 v2; // ax@1
   int v5; // edi@7
-
+  return true;
   if (CheckHiredNPCSpeciality(Scholar))
     return true;
 
@@ -1406,49 +1404,49 @@
 //----- (0048C855) --------------------------------------------------------
 int Player::GetBaseStrength()
 {
-  return this->uMight + GetItemsBonus(CHARACTER_ATTRIBUTE_STRENGTH, 0);
+  return this->uMight + GetItemsBonus(CHARACTER_ATTRIBUTE_STRENGTH);
 }
 
 //----- (0048C86C) --------------------------------------------------------
 int Player::GetBaseIntelligence()
 {
-  return this->uIntelligence + GetItemsBonus(CHARACTER_ATTRIBUTE_INTELLIGENCE, 0);
+  return this->uIntelligence + GetItemsBonus(CHARACTER_ATTRIBUTE_INTELLIGENCE);
 }
 
 //----- (0048C883) --------------------------------------------------------
 int Player::GetBaseWillpower()
 {
-  return this->uWillpower + GetItemsBonus(CHARACTER_ATTRIBUTE_WILLPOWER, 0);
+  return this->uWillpower + GetItemsBonus(CHARACTER_ATTRIBUTE_WILLPOWER);
 }
 
 //----- (0048C89A) --------------------------------------------------------
 int Player::GetBaseEndurance()
 {
-  return this->uEndurance + GetItemsBonus(CHARACTER_ATTRIBUTE_ENDURANCE, 0);
+  return this->uEndurance + GetItemsBonus(CHARACTER_ATTRIBUTE_ENDURANCE);
 }
 
 //----- (0048C8B1) --------------------------------------------------------
 int Player::GetBaseAccuracy()
 {
-  return this->uAccuracy + GetItemsBonus(CHARACTER_ATTRIBUTE_ACCURACY, 0);
+  return this->uAccuracy + GetItemsBonus(CHARACTER_ATTRIBUTE_ACCURACY);
 }
 
 //----- (0048C8C8) --------------------------------------------------------
 int Player::GetBaseSpeed()
 {
-  return this->uSpeed + GetItemsBonus(CHARACTER_ATTRIBUTE_SPEED, 0);
+  return this->uSpeed + GetItemsBonus(CHARACTER_ATTRIBUTE_SPEED);
 }
 
 //----- (0048C8DF) --------------------------------------------------------
 int Player::GetBaseLuck()
 {
-  return this->uLuck + GetItemsBonus(CHARACTER_ATTRIBUTE_LUCK, 0);
+  return this->uLuck + GetItemsBonus(CHARACTER_ATTRIBUTE_LUCK);
 }
 
 //----- (0048C8F6) --------------------------------------------------------
 int Player::GetBaseLevel()
 {
-  return this->uLevel + GetItemsBonus(CHARACTER_ATTRIBUTE_LEVEL, 0);
+  return this->uLevel + GetItemsBonus(CHARACTER_ATTRIBUTE_LEVEL);
 }
 
 //----- (0048C90D) --------------------------------------------------------
@@ -1456,7 +1454,7 @@
 {
   return uLevel + sLevelModifier +
          GetMagicalBonus(CHARACTER_ATTRIBUTE_LEVEL) +
-         GetItemsBonus(CHARACTER_ATTRIBUTE_LEVEL, 0);
+         GetItemsBonus(CHARACTER_ATTRIBUTE_LEVEL);
 }
 
 //----- (0048C93C) --------------------------------------------------------
@@ -1527,7 +1525,7 @@
 
   auto uConditionMult = pConditionAttributeModifier[attrId][GetMajorConditionIdx()];
   int magicBonus = GetMagicalBonus(attrId);
-  int itemBonus = GetItemsBonus(attrId, 0);
+  int itemBonus = GetItemsBonus(attrId);
   return uConditionMult * uAgeingMultiplier * this->*attrValue / 100 / 100
     + magicBonus
     + itemBonus
@@ -1560,7 +1558,7 @@
  
   v2 = GetActualMight();
   v3 = GetParameterBonus(v2);
-  v4 = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MIN, 0) + v3;
+  v4 = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MIN) + v3;
   v5 = GetSkillBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS) + v4;
   result = _melee_dmg_bonus + GetMagicalBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS) + v5;
   if ( result < 1 )
@@ -1580,7 +1578,7 @@
 
   v2 = GetActualMight();
   v3 = GetParameterBonus(v2);
-  v4 = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MAX, 0) + v3;
+  v4 = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MAX) + v3;
   v5 = GetSkillBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS) + v4;
   v6 = this->_melee_dmg_bonus + GetMagicalBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS) + v5;
   result = 1;
@@ -1700,7 +1698,7 @@
   {
     v4 = GetActualAccuracy();
     v5 = GetParameterBonus(v4);
-    v6 = GetItemsBonus(CHARACTER_ATTRIBUTE_RANGED_ATTACK, 0) + v5;
+    v6 = GetItemsBonus(CHARACTER_ATTRIBUTE_RANGED_ATTACK) + v5;
     v7 = GetSkillBonus(CHARACTER_ATTRIBUTE_RANGED_ATTACK) + v6;
     v3 = this->_ranged_atk_bonus + GetMagicalBonus(CHARACTER_ATTRIBUTE_RANGED_ATTACK) + v7;
   }
@@ -1719,7 +1717,7 @@
   int v4; // edi@1
   int result; // eax@6
 
-  v2 = GetItemsBonus(CHARACTER_ATTRIBUTE_RANGED_DMG_MIN, 0);
+  v2 = GetItemsBonus(CHARACTER_ATTRIBUTE_RANGED_DMG_MIN);
   v3 = GetSkillBonus(CHARACTER_ATTRIBUTE_RANGED_DMG_BONUS) + v2;
   v4 = this->_ranged_dmg_bonus + GetMagicalBonus(CHARACTER_ATTRIBUTE_RANGED_DMG_BONUS) + v3;
   if ( v4 >= 1 )
@@ -1737,7 +1735,7 @@
   int v4; // edi@1
   int result; // eax@6
 
-  v2 = GetItemsBonus(CHARACTER_ATTRIBUTE_RANGED_DMG_MAX, 0);
+  v2 = GetItemsBonus(CHARACTER_ATTRIBUTE_RANGED_DMG_MAX);
   v3 = GetSkillBonus(CHARACTER_ATTRIBUTE_RANGED_DMG_BONUS) + v2;
   v4 = this->_ranged_dmg_bonus + GetMagicalBonus(CHARACTER_ATTRIBUTE_RANGED_DMG_BONUS) + v3;
   if ( v4 >= 1 )
@@ -1813,8 +1811,8 @@
   }
   else if (pEquipment.uMainHand >= 0 && (itemid == ITEM_BLASTER || itemid == ITEM_LASER_RIFLE))
   {
-    min_damage = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MIN, 1);
-    max_damage = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MAX, 1);
+    min_damage = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MIN, true);
+    max_damage = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MAX, true);
   }
   else
   {
@@ -1853,8 +1851,8 @@
     }
     else if (pEquipment.uMainHand >= 0 && (itemid == ITEM_BLASTER || itemid == ITEM_LASER_RIFLE))
     {
-      min_damage = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MIN, 1);
-      max_damage = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MAX, 1);
+      min_damage = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MIN, true);
+      max_damage = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MAX, true);
     }
     else
     {
@@ -2261,7 +2259,7 @@
   broke_armor = sHealth <= -10;
   if ( sHealth < 1 ) //
   {
-    if ( (sHealth + uEndurance + GetItemsBonus(CHARACTER_ATTRIBUTE_ENDURANCE, 0) >= 1)
+    if ( (sHealth + uEndurance + GetItemsBonus(CHARACTER_ATTRIBUTE_ENDURANCE) >= 1)
       || pPlayerBuffs[PLAYER_BUFF_PRESERVATION].uExpireTime > 0 )
     {
       SetCondUnconsciousWithBlockCheck(false);
@@ -2663,23 +2661,18 @@
   uint      weapon_recovery = base_recovery_times_per_weapon_type[0];
   if (bRangedAttack)
   {
-    if ( !HasItemEquipped(EQUIP_BOW) )
-      goto LABEL_17;
-    weapon = &pInventoryItemList[pEquipment.uBow - 1];
-    weapon_desc = &pItemsTable->pItems[weapon->uItemID];
-    weapon_recovery = base_recovery_times_per_weapon_type[weapon_desc->uSkillType];
-    goto LABEL_17;
-  }
-  else if ( IsUnarmed() == 1 )
-  {
-    if (GetActualSkillLevel(PLAYER_SKILL_UNARMED))
-    {
+    if ( HasItemEquipped(EQUIP_BOW) )
+    {
+      weapon = &pInventoryItemList[pEquipment.uBow - 1];
+      weapon_desc = &pItemsTable->pItems[weapon->uItemID];
+      weapon_recovery = base_recovery_times_per_weapon_type[weapon_desc->uSkillType];
+    }
+  }
+  else if ( IsUnarmed() == 1 && GetActualSkillLevel(PLAYER_SKILL_UNARMED) > 0)
+  {
       weapon_recovery = base_recovery_times_per_weapon_type[1];
-      goto LABEL_17;
-    }
-  }
-
-  if ( HasItemEquipped(EQUIP_MAIN_HAND) )
+  }
+  else if ( HasItemEquipped(EQUIP_MAIN_HAND) )
   {
     weapon = &pInventoryItemList[pEquipment.uMainHand - 1];
     weapon_desc = &pItemsTable->pItems[weapon->uItemID];
@@ -2705,58 +2698,43 @@
     }
   }
 
-LABEL_17:
   uint armour_recovery = 0;
   if ( HasItemEquipped(EQUIP_ARMOUR) )
   {
     auto armour_skill_type = pItemsTable->pItems[pInventoryItemList[pEquipment.uArmor - 1].uItemID].uSkillType;
     uint base_armour_recovery = base_recovery_times_per_weapon_type[armour_skill_type];
-
-    float armour_recovery_multipliers[4];
+    float multiplier;
+
     if (armour_skill_type == PLAYER_SKILL_LEATHER)
     {
-      armour_recovery_multipliers[0] = 1.0f;
-      armour_recovery_multipliers[1] = 0;
-      armour_recovery_multipliers[2] = 0;
-      armour_recovery_multipliers[3] = 0;
+      multiplier = GetArmorRecoveryMultiplierFromSkillLevel(armour_skill_type, 1.0f, 0, 0, 0);
     }
     else if (armour_skill_type == PLAYER_SKILL_CHAIN)
     {
-      armour_recovery_multipliers[0] = 1.0f;
-      armour_recovery_multipliers[1] = 0.5f;
-      armour_recovery_multipliers[2] = 0;
-      armour_recovery_multipliers[3] = 0;
+      multiplier = GetArmorRecoveryMultiplierFromSkillLevel(armour_skill_type, 1.0f, 0.5f, 0, 0);
     }
     else if (armour_skill_type == PLAYER_SKILL_PLATE)
     {
-      armour_recovery_multipliers[0] = 1.0f;
-      armour_recovery_multipliers[1] = 0.5f;
-      armour_recovery_multipliers[2] = 0.5f;
-      armour_recovery_multipliers[3] = 0;
+      multiplier = GetArmorRecoveryMultiplierFromSkillLevel(armour_skill_type, 1.0f, 0.5f, 0.5f, 0);
     }
     else
     {
       Error("Unknown armour type"); // what kind of armour is that?
-      armour_recovery_multipliers[0] = 1.0f;
-      armour_recovery_multipliers[1] = 1.0f;
-      armour_recovery_multipliers[2] = 1.0f;
-      armour_recovery_multipliers[3] = 1.0f;
-    }
-
-    uint skill_mastery = SkillToMastery(pActiveSkills[armour_skill_type]);
-    armour_recovery = base_armour_recovery * armour_recovery_multipliers[skill_mastery - 1];
+      multiplier = GetArmorRecoveryMultiplierFromSkillLevel(armour_skill_type, 1.0f, 1.0f, 1.0f, 1.0f);
+    }
+
+    armour_recovery = (uint)(base_armour_recovery * multiplier);
   }
 
   uint shield_recovery = 0;
   if (HasItemEquipped(EQUIP_OFF_HAND) && GetEquippedItemEquipType(EQUIP_OFF_HAND) == EQUIP_SHIELD)
   {
-    float shield_recovery_multipliers[4] = {1, 0, 0, 0};
-
     auto shield = &pInventoryItemList[pEquipment.uShield - 1];
     auto skill_type = pItemsTable->pItems[shield->uItemID].uSkillType;
 
     uint shield_base_recovery = base_recovery_times_per_weapon_type[skill_type];
-    shield_recovery = shield_base_recovery * SkillToMastery(pActiveSkills[skill_type]);
+    float multiplier = GetArmorRecoveryMultiplierFromSkillLevel(skill_type, 1.0f, 0, 0, 0);
+    shield_recovery = (uint)(shield_base_recovery * multiplier);
   }
 
   uint player_speed_recovery_reduction = GetParameterBonus(GetActualSpeed()),
@@ -2785,9 +2763,9 @@
     }
   }
 
-  uint v41 = 0;
-  if (pPlayerBuffs[PLAYER_BUFF_7].uExpireTime > 0)
-    v41 = 25;
+  uint hasteRecoveryReduction = 0;
+  if (pPlayerBuffs[PLAYER_BUFF_7].uExpireTime > 0 || pParty->pPartyBuffs[PARTY_BUFF_HASTE].uExpireTime > 0 )
+    hasteRecoveryReduction = 25;
 
   uint weapon_enchantment_recovery_reduction = 0;
   if ( weapon  )
@@ -2798,13 +2776,12 @@
       weapon_enchantment_recovery_reduction = 20;
   }
 
-
   int recovery = weapon_recovery +
                  armour_recovery +
                  shield_recovery
                  - armsmaster_recovery_reduction
                  - weapon_enchantment_recovery_reduction
-                 - v41
+                 - hasteRecoveryReduction
                  - sword_axe_bow_recovery_reduction
                  - player_speed_recovery_reduction;
 
@@ -2813,6 +2790,22 @@
   return recovery;
 }
 
+
+//----- new --------------------------------------------------------
+float Player::GetArmorRecoveryMultiplierFromSkillLevel( unsigned char armour_skill_type, float mult1, float mult2, float mult3, float mult4 )
+{
+  uint skill_mastery = SkillToMastery(pActiveSkills[armour_skill_type]);
+  switch (skill_mastery)
+  {
+    case 1: return mult1; break;
+    case 2: return mult2; break;
+    case 3: return mult3; break;
+    case 4: return mult4; break;
+  }
+  Error("Unexpected input value: %d", armour_skill_type);
+  return 0;
+}
+
 //----- (0048E4F8) --------------------------------------------------------
 int Player::GetMaxHealth()
 {
@@ -2825,10 +2818,8 @@
   v6 = uFullHealthBonus
      + pBaseHealthByClass[classType / 4]
      + GetSkillBonus(CHARACTER_ATTRIBUTE_HEALTH)
-     + GetItemsBonus(CHARACTER_ATTRIBUTE_HEALTH, 0) + v4;
-  if (v6 <= 0)
-    return 1;
-  return v6;
+     + GetItemsBonus(CHARACTER_ATTRIBUTE_HEALTH) + v4;
+  return max(1, v6);
 }
 
 //----- (0048E565) --------------------------------------------------------
@@ -2842,7 +2833,6 @@
   int v7; // esi@6
   int v8; // esi@6
   int v9; // esi@6
-  int result; // eax@7
   
   switch (classType)
   {
@@ -2891,7 +2881,7 @@
       break;
   }
   v7 = pBaseManaPerLevelByClass[classType] * (GetActualLevel() + v3);
-  v8 = GetItemsBonus(CHARACTER_ATTRIBUTE_MANA, 0) + v7;
+  v8 = GetItemsBonus(CHARACTER_ATTRIBUTE_MANA) + v7;
   v9 = uFullManaBonus
       + pBaseManaByClass[classType / 4]
   + GetSkillBonus(CHARACTER_ATTRIBUTE_MANA)
@@ -2902,53 +2892,39 @@
 //----- (0048E656) --------------------------------------------------------
 int Player::GetBaseAC()
 {
-  Player *v1; // edi@1
   int v2; // eax@1
   int v3; // esi@1
   int v4; // esi@1
   int v5; // esi@1
-  int result; // eax@2
-
-  v1 = this;
+
   v2 = GetActualSpeed();
   v3 = GetParameterBonus(v2);
-  v4 = GetItemsBonus(CHARACTER_ATTRIBUTE_AC_BONUS, 0) + v3;
+  v4 = GetItemsBonus(CHARACTER_ATTRIBUTE_AC_BONUS) + v3;
   v5 = GetSkillBonus(CHARACTER_ATTRIBUTE_AC_BONUS) + v4;
-  if ( v5 >= 1 )
-    result = v5;
-  else
-    result = 0;
-  return result;
+  return max(0, v5);
 }
 
 //----- (0048E68F) --------------------------------------------------------
 int Player::GetActualAC()
 {
-  Player *v1; // edi@1
   int v2; // eax@1
   int v3; // esi@1
   int v4; // esi@1
   int v5; // esi@1
   int v6; // esi@1
-  int result; // eax@2
-
-  v1 = this;
+
   v2 = GetActualSpeed();
   v3 = GetParameterBonus(v2);
-  v4 = GetItemsBonus(CHARACTER_ATTRIBUTE_AC_BONUS, 0) + v3;
+  v4 = GetItemsBonus(CHARACTER_ATTRIBUTE_AC_BONUS) + v3;
   v5 = GetSkillBonus(CHARACTER_ATTRIBUTE_AC_BONUS) + v4;
-  v6 = v1->sACModifier + GetMagicalBonus(CHARACTER_ATTRIBUTE_AC_BONUS) + v5;
-  if ( v6 >= 1 )
-    result = v6;
-  else
-    result = 0;
-  return result;
+  v6 = this->sACModifier + GetMagicalBonus(CHARACTER_ATTRIBUTE_AC_BONUS) + v5;
+  return max(0, v6);
 }
 
 //----- (0048E6DC) --------------------------------------------------------
 unsigned int Player::GetBaseAge()
 {
-  return ((__int64)(pParty->uTimePlayed * 0.234375) / 60 / 60 / 24) / 7 / 4 / 12 - uBirthYear + game_starting_year;
+  return (unsigned int)(((__int64)(pParty->uTimePlayed * 0.234375) / 60 / 60 / 24) / 7 / 4 / 12 - uBirthYear + game_starting_year);
 }
 
 //----- (0048E72C) --------------------------------------------------------
@@ -2960,155 +2936,100 @@
 //----- (0048E73F) --------------------------------------------------------
 int Player::GetBaseResistance(enum CHARACTER_ATTRIBUTE_TYPE a2)
 {
-  Player *v2; // ebx@1
-  signed int v3; // esi@1
-  enum CHARACTER_RACE v4; // eax@1
-  signed int v5; // edi@8
-  char v6; // zf@9
   int v7; // esi@20
-  int result; // eax@21
-  signed int v9; // [sp-4h] [bp-10h]@11
-
-  v2 = this;
-  v3 = 0;
-  v4 = GetRace();
-  if ( a2 == CHARACTER_ATTRIBUTE_RESIST_FIRE )
-  {
-    v5 = 0;
-    goto LABEL_16;
-  }
-  if ( a2 == CHARACTER_ATTRIBUTE_RESIST_AIR )
-  {
-    v5 = 1;
-LABEL_16:
-    v6 = v4 == 2;
-    goto LABEL_17;
-  }
-  if ( a2 == CHARACTER_ATTRIBUTE_RESIST_WATER )
-  {
-    v6 = v4 == 3;
-    v5 = 2;
-    goto LABEL_17;
-  }
-  if ( a2 == CHARACTER_ATTRIBUTE_RESIST_EARTH )
-  {
-    v5 = 3;
-    v6 = v4 == 3;
-    goto LABEL_17;
-  }
-  if ( a2 == CHARACTER_ATTRIBUTE_RESIST_MIND )
-  {
-    v5 = 7;
-    if ( v4 != 1 )
-      goto LABEL_20;
-    v9 = 10;
-LABEL_19:
-    v3 = v9;
-    goto LABEL_20;
-  }
-  if ( a2 == CHARACTER_ATTRIBUTE_RESIST_BODY || a2 == 33 )
-  {
-    v5 = 8;
-    v6 = v4 == 0;
-LABEL_17:
-    if ( !v6 )
-      goto LABEL_20;
-    v9 = 5;
-    goto LABEL_19;
-  }
-  v5 = 0;
-LABEL_20:
-  v7 = GetItemsBonus(a2, 0) + v3;
-  if ( v2->classType != PLAYER_CLASS_LICH || (result = 200, v7 + *(&v2->sResFireBase + v5) <= 200) )
-    result = v7 + *(&v2->sResFireBase + v5);
-  return result;
+  int racialBonus = 0;
+  __int16* resStat;
+
+  switch (a2)
+  {
+    case CHARACTER_ATTRIBUTE_RESIST_FIRE:
+      resStat = &sResFireBase;
+      if (IsRaceGoblin())
+        racialBonus = 5;
+      break;
+    case CHARACTER_ATTRIBUTE_RESIST_AIR:
+      resStat = &sResAirBase;
+      if (IsRaceGoblin())
+        racialBonus = 5;
+      break;
+    case  CHARACTER_ATTRIBUTE_RESIST_WATER:
+      resStat = &sResWaterBase;
+      if (IsRaceDwarf())
+        racialBonus = 5;
+      break;
+    case CHARACTER_ATTRIBUTE_RESIST_EARTH:
+      resStat = &sResEarthBase;
+      if (IsRaceDwarf())
+        racialBonus = 5;
+    break;
+    case CHARACTER_ATTRIBUTE_RESIST_MIND:
+      resStat = &sResMindBase;
+      if (IsRaceElf())
+        racialBonus = 10;
+      break;
+    case CHARACTER_ATTRIBUTE_RESIST_BODY:
+    case CHARACTER_ATTRIBUTE_RESIST_SPIRIT:
+      resStat = &sResBodyBase;
+      if (IsRaceHuman())
+        racialBonus = 5;
+      break;
+  }
+  v7 = GetItemsBonus(a2) + racialBonus;
+  return v7 + *resStat;
 }
 
 //----- (0048E7D0) --------------------------------------------------------
 int Player::GetActualResistance(enum CHARACTER_ATTRIBUTE_TYPE a2)
 {
-  signed int v2; // edi@1
-  Player *v3; // esi@1
-  enum CHARACTER_RACE v4; // ebx@1
-  char v6; // zf@18
-  int v7; // ebx@28
-  int result; // eax@28
-  signed int v9; // [sp+10h] [bp-8h]@1
-  signed int v10; // [sp+14h] [bp-4h]@1
-
-  v2 = 0;
-  v3 = this;
-  v10 = 0;
-  v9 = 0;
-  v4 = GetRace();
+  signed int v10 = 0; // [sp+14h] [bp-4h]@1
+  __int16* resStat;
+  int result;
+  int baseRes;
+
+  int leatherArmorSkillLevel = GetActualSkillLevel(PLAYER_SKILL_LEATHER);
   if ( CheckHiredNPCSpeciality(Enchanter) )
     v10 = 20;
   if ( (a2 == CHARACTER_ATTRIBUTE_RESIST_FIRE
      || a2 == CHARACTER_ATTRIBUTE_RESIST_AIR
      || a2 == CHARACTER_ATTRIBUTE_RESIST_WATER
      || a2 == CHARACTER_ATTRIBUTE_RESIST_EARTH)
-    && SkillToMastery(v3->pActiveSkills[9]) == 4
+    && SkillToMastery(leatherArmorSkillLevel) == 4
     && HasItemEquipped(EQUIP_ARMOUR)
     && GetEquippedItemSkillType(EQUIP_ARMOUR) == PLAYER_SKILL_LEATHER )
-    v10 += v3->pActiveSkills[9] & 0x3F;
-  if ( a2 == CHARACTER_ATTRIBUTE_RESIST_FIRE )
-    goto LABEL_25;
-  if ( a2 == CHARACTER_ATTRIBUTE_RESIST_AIR )
-  {
-    v2 = 1;
-LABEL_25:
-    v6 = v4 == 2;
-LABEL_26:
-    if ( v6 )
-      v9 = 5;
-    goto LABEL_28;
-  }
-  if ( a2 == CHARACTER_ATTRIBUTE_RESIST_WATER )
-  {
-    v6 = v4 == 3;
-    v2 = 2;
-    goto LABEL_26;
-  }
-  if ( a2 == CHARACTER_ATTRIBUTE_RESIST_EARTH )
-  {
-    v2 = 3;
-    if ( v4 == 3 )
-      v10 += 5;
-  }
-  else
-  {
-    if ( a2 != CHARACTER_ATTRIBUTE_RESIST_MIND )
-    {
-      if ( a2 != CHARACTER_ATTRIBUTE_RESIST_BODY && a2 != 33 )
-        goto LABEL_28;
-      v2 = 8;
-      v6 = v4 == 0;
-      goto LABEL_26;
-    }
-    v2 = 7;
-    if ( v4 == 1 )
-      v9 = 10;
-  }
-LABEL_28:
-  v7 = GetItemsBonus(a2, 0);
-  result = v10 + GetMagicalBonus(a2) + v7 + v9 + *(&v3->sResFireBonus + v2) + *(&v3->sResFireBase + v2);
-  if ( v3->classType == PLAYER_CLASS_LICH )
-  {
-    if ( result > 200 )
-      result = 200;
-  }
+    v10 += leatherArmorSkillLevel & 0x3F;
+  switch (a2)
+  {
+  case CHARACTER_ATTRIBUTE_RESIST_FIRE:
+    resStat = &sResFireBonus;
+    break;
+  case CHARACTER_ATTRIBUTE_RESIST_AIR:
+    resStat = &sResAirBonus;
+    break;
+  case  CHARACTER_ATTRIBUTE_RESIST_WATER:
+    resStat = &sResWaterBonus;
+    break;
+  case CHARACTER_ATTRIBUTE_RESIST_EARTH:
+    resStat = &sResEarthBonus;
+    break;
+  case CHARACTER_ATTRIBUTE_RESIST_MIND:
+    resStat = &sResMindBonus;
+    break;
+  case CHARACTER_ATTRIBUTE_RESIST_BODY:
+  case CHARACTER_ATTRIBUTE_RESIST_SPIRIT:
+    resStat = &sResBodyBonus;
+    break;
+  }
+  baseRes = GetBaseResistance(a2);
+  result = v10 + GetMagicalBonus(a2) + baseRes + *(resStat);
   return result;
 }
 
 //----- (0048E8F5) --------------------------------------------------------
 bool Player::Recover(int dt)
 {
-  //Player *v2; // esi@1
-  signed __int64 v3; // qax@1
-  //bool result; // eax@4
-
-  //v2 = this;
-  v3 = (signed __int64)((double)(dt * _48EA46_calc_special_bonus_by_items(17)) * 0.01 + (double)dt);
+  int v3; // qax@1
+
+  v3 = (int)(dt * GetSpecialItemBonus(17) * 0.01 + dt);
 
   Log::Warning(L"Recover(dt = %u/%u - %u", dt, (uint)v3, (uint)uTimeToRecovery);
 
@@ -3161,866 +3082,312 @@
 
 //----- (0048EA1B) --------------------------------------------------------
 int Player::GetParameterBonus( int player_parameter )
-    {
+{
   int i; // eax@1
   i = 0;
   while (param_to_bonus_table[i])
-      { 
-      if (player_parameter >= param_to_bonus_table[i])
-          break;
-      ++i;    
-      }   
+  { 
+    if (player_parameter >= param_to_bonus_table[i])
+      break;
+    ++i;    
+  }   
   return parameter_to_bonus_value[i];
 }
 
 //----- (0048EA46) --------------------------------------------------------
-int Player::_48EA46_calc_special_bonus_by_items(int a2)
+int Player::GetSpecialItemBonus( int enchantmentId )
 {
   int inv_indx; // eax@3
 
-  for (int i=EQUIP_OFF_HAND; i<EQUIP_BOOK; ++i )
-      {
-      if ( !HasItemEquipped((ITEM_EQUIP_TYPE)i) )
-          continue;
+  for (int i = EQUIP_OFF_HAND; i < EQUIP_BOOK; ++i )
+  {
+    if ( HasItemEquipped((ITEM_EQUIP_TYPE)i) )
+    {
       inv_indx = pEquipment.pIndices[i]  - 1;
-      if (a2==17)
-          {
-          if ((pInventoryItemList[inv_indx].uSpecEnchantmentType==17)||(pInventoryItemList[inv_indx].uItemID==533)) //Elven Chainmail+Increases rate of Recovery
-              return 50;
-          }
-      if (a2==24)
-          {
-          if (pInventoryItemList[inv_indx].uSpecEnchantmentType==24) //Increased Knockback.
-              return 5;
-          }
+      if (enchantmentId == 17)
+      {
+        if ((pInventoryItemList[inv_indx].uSpecEnchantmentType == 17) || (pInventoryItemList[inv_indx].uItemID == 533)) //Elven Chainmail+Increases rate of Recovery
+          return 50;
       }
+      if (enchantmentId == 24) 
+      {
+        if (pInventoryItemList[inv_indx].uSpecEnchantmentType == 24) //Increased Knockback.
+          return 5;
+      }
+    }
+  }
   return 0;
 }
 
 //----- (0048EAAE) --------------------------------------------------------
-int Player::GetItemsBonus(CHARACTER_ATTRIBUTE_TYPE attr, int a3)
-{
-  CHARACTER_ATTRIBUTE_TYPE v3; // esi@1
- // signed int v4; // eax@1
+int Player::GetItemsBonus( enum CHARACTER_ATTRIBUTE_TYPE attr, bool getOnlyMainHandDmg /*= false*/ )
+{
   int v5; // edi@1
-  Player *v6; // ebx@1
-  Player *v8; // ecx@48
   int v9; // eax@49
-  int v10; // edx@49
-  Player *v11; // ecx@55
-  int v12; // eax@56
-  int v13; // edx@56
   int v14; // ecx@58
   int v15; // eax@58
-  Player *v16; // ecx@61
   int v17; // eax@62
-  Player *v18; // ecx@66
-  int v19; // eax@67
   int v20; // eax@69
-  Player *v21; // ecx@75
   int v22; // eax@76
   int v23; // edx@76
-  //int v24; // eax@79
   int v25; // ecx@80
   int v26; // edi@80
-  Player *v27; // ecx@84
-  int v28; // eax@85
-  int v29; // edx@85
-  Player *v30; // ecx@96
   int v31; // ebp@97
   int v32; // eax@98
   unsigned int v33; // eax@100
-  int v34; // eax@103
-  char v35; // zf@104
-  char v36; // zf@107
-  unsigned __int8 v37; // zf@119
-  char v38; // sf@119
-  unsigned __int8 v39; // of@119
-  char v40; // zf@122
-  char v41; // zf@145
-  char v42; // zf@164
-  char v43; // zf@173
-  char v44; // zf@189
-  char v45; // zf@198
-  char v46; // zf@239
-  int v47; // eax@268
-  int v48; // eax@269
-  int v49; // eax@291
-  char v50; // zf@295
-  int v51; // eax@306
-  int v52; // eax@307
-  char v53; // zf@312
-  char v54; // zf@336
-  char v55; // zf@348
   int v56; // eax@365
   int v57; // ebx@368
   signed int v58; // [sp-4h] [bp-20h]@10
-  signed int v59; // [sp-4h] [bp-20h]@71
-  signed int v60; // [sp-4h] [bp-20h]@347
   int v61; // [sp+10h] [bp-Ch]@1
   int v62; // [sp+14h] [bp-8h]@1
-  int v63; // [sp+18h] [bp-4h]@101
-  ItemGen *attra; // [sp+20h] [bp+4h]@101
-  unsigned int v65; // [sp+24h] [bp+8h]@95
+  ItemGen *currEquippedItem; // [sp+20h] [bp+4h]@101
   bool no_skills;
 
-  v3 = attr;
   v5 = 0;
-  v6 = this;
   v62 = 0;
   v61 = 0;
-
   
   no_skills=false;
   switch (attr)
+  {
+    case  CHARACTER_ATTRIBUTE_SKILL_ALCHEMY:      v58 = PLAYER_SKILL_ALCHEMY;      break;
+    case  CHARACTER_ATTRIBUTE_SKILL_STEALING:     v58 = PLAYER_SKILL_STEALING;     break;
+    case  CHARACTER_ATTRIBUTE_SKILL_TRAP_DISARM:  v58 = PLAYER_SKILL_TRAP_DISARM;  break;
+    case  CHARACTER_ATTRIBUTE_SKILL_ITEM_ID:      v58 = PLAYER_SKILL_ITEM_ID;      break;
+    case  CHARACTER_ATTRIBUTE_SKILL_MONSTER_ID:   v58 = PLAYER_SKILL_MONSTER_ID;   break;
+    case  CHARACTER_ATTRIBUTE_SKILL_ARMSMASTER:   v58 = PLAYER_SKILL_ARMSMASTER;   break;
+    case  CHARACTER_ATTRIBUTE_SKILL_DODGE:        v58 = PLAYER_SKILL_DODGE;        break;
+    case  CHARACTER_ATTRIBUTE_SKILL_UNARMED:      v58 = PLAYER_SKILL_UNARMED;      break;
+    case  CHARACTER_ATTRIBUTE_SKILL_FIRE:         v58 = PLAYER_SKILL_FIRE;         break;
+    case  CHARACTER_ATTRIBUTE_SKILL_AIR:          v58 = PLAYER_SKILL_AIR;          break;
+    case  CHARACTER_ATTRIBUTE_SKILL_WATER:        v58 = PLAYER_SKILL_WATER;        break;
+    case  CHARACTER_ATTRIBUTE_SKILL_EARTH:        v58 = PLAYER_SKILL_EARTH;        break;
+    case  CHARACTER_ATTRIBUTE_SKILL_SPIRIT:       v58 = PLAYER_SKILL_SPIRIT;       break;
+    case  CHARACTER_ATTRIBUTE_SKILL_MIND:         v58 = PLAYER_SKILL_MIND;         break;
+    case  CHARACTER_ATTRIBUTE_SKILL_BODY:         v58 = PLAYER_SKILL_BODY;         break;
+    case  CHARACTER_ATTRIBUTE_SKILL_LIGHT:        v58 = PLAYER_SKILL_LIGHT;        break;
+    case  CHARACTER_ATTRIBUTE_SKILL_DARK:         v58 = PLAYER_SKILL_DARK;         break;
+    case  CHARACTER_ATTRIBUTE_SKILL_MEDITATION:   v58 = PLAYER_SKILL_MEDITATION;   break;
+    case  CHARACTER_ATTRIBUTE_SKILL_BOW:          v58 = PLAYER_SKILL_BOW;          break;
+    case  CHARACTER_ATTRIBUTE_SKILL_SHIELD:       v58 = PLAYER_SKILL_SHIELD;       break;
+    case  CHARACTER_ATTRIBUTE_SKILL_LEARNING:     v58 = PLAYER_SKILL_LEARNING;     break;
+    default:
+      no_skills=true;
+  }
+  if (!no_skills)
+  {
+    if ( !this->pActiveSkills[v58] )
+      return 0;
+  }
+
+  switch(attr)      //TODO would be nice to move these into separate functions
+  {
+    case CHARACTER_ATTRIBUTE_RANGED_DMG_BONUS:
+    case CHARACTER_ATTRIBUTE_RANGED_ATTACK:
+      if ( HasItemEquipped(EQUIP_BOW) )
+        v5 = pItemsTable->pItems[this->pOwnItems[this->pEquipment.uBow-1].uItemID].uDamageMod;
+      return v5;
+      break;
+
+    case CHARACTER_ATTRIBUTE_RANGED_DMG_MIN:
+      if ( !HasItemEquipped(EQUIP_BOW) )
+        return 0;
+      v57 = this->pOwnItems[this->pEquipment.uBow-1].uItemID;
+      v5 = pItemsTable->pItems[v57].uDamageMod;
+      v56 = pItemsTable->pItems[v57].uDamageDice;
+      return v5 + v56;
+      break;
+
+    case CHARACTER_ATTRIBUTE_RANGED_DMG_MAX:
+      if ( !HasItemEquipped(EQUIP_BOW) )
+        return 0;
+      v20 = this->pOwnItems[this->pEquipment.uBow-1].uItemID;
+      v5 = pItemsTable->pItems[v20].uDamageDice * pItemsTable->pItems[v20].uDamageRoll;
+      v56 = pItemsTable->pItems[v20].uDamageMod;
+      return v5 + v56;
+
+    case CHARACTER_ATTRIBUTE_LEVEL: 
+      if ( !Player::HasEnchantedItemEquipped(25) )
+        return 0;
+      return 5;
+      break;
+
+    case CHARACTER_ATTRIBUTE_MELEE_DMG_MAX:
+      if ( IsUnarmed() )
       {
-  case  CHARACTER_ATTRIBUTE_SKILL_ALCHEMY:      v58 = PLAYER_SKILL_ALCHEMY;      break;
-  case  CHARACTER_ATTRIBUTE_SKILL_STEALING:     v58 = PLAYER_SKILL_STEALING;     break;
-  case  CHARACTER_ATTRIBUTE_SKILL_TRAP_DISARM:  v58 = PLAYER_SKILL_TRAP_DISARM;  break;
-  case  CHARACTER_ATTRIBUTE_SKILL_ITEM_ID:      v58 = PLAYER_SKILL_ITEM_ID;      break;
-  case  CHARACTER_ATTRIBUTE_SKILL_MONSTER_ID:   v58 = PLAYER_SKILL_MONSTER_ID;   break;
-  case  CHARACTER_ATTRIBUTE_SKILL_ARMSMASTER:   v58 = PLAYER_SKILL_ARMSMASTER;   break;
-  case  CHARACTER_ATTRIBUTE_SKILL_DODGE:        v58 = PLAYER_SKILL_DODGE;        break;
-  case  CHARACTER_ATTRIBUTE_SKILL_UNARMED:      v58 = PLAYER_SKILL_UNARMED;      break;
-  case  CHARACTER_ATTRIBUTE_SKILL_FIRE:         v58 = PLAYER_SKILL_FIRE;         break;
-  case  CHARACTER_ATTRIBUTE_SKILL_AIR:          v58 = PLAYER_SKILL_AIR;          break;
-  case  CHARACTER_ATTRIBUTE_SKILL_WATER:        v58 = PLAYER_SKILL_WATER;        break;
-  case  CHARACTER_ATTRIBUTE_SKILL_EARTH:        v58 = PLAYER_SKILL_EARTH;        break;
-  case  CHARACTER_ATTRIBUTE_SKILL_SPIRIT:       v58 = PLAYER_SKILL_SPIRIT;       break;
-  case  CHARACTER_ATTRIBUTE_SKILL_MIND:         v58 = PLAYER_SKILL_MIND;         break;
-  case  CHARACTER_ATTRIBUTE_SKILL_BODY:         v58 = PLAYER_SKILL_BODY;         break;
-  case  CHARACTER_ATTRIBUTE_SKILL_LIGHT:        v58 = PLAYER_SKILL_LIGHT;        break;
-  case  CHARACTER_ATTRIBUTE_SKILL_DARK:         v58 = PLAYER_SKILL_DARK;         break;
-  case  CHARACTER_ATTRIBUTE_SKILL_MEDITATION:   v58 = PLAYER_SKILL_MEDITATION;   break;
-  case  CHARACTER_ATTRIBUTE_SKILL_BOW:          v58 = PLAYER_SKILL_BOW;          break;
-  case  CHARACTER_ATTRIBUTE_SKILL_SHIELD:       v58 = PLAYER_SKILL_SHIELD;       break;
-  case  CHARACTER_ATTRIBUTE_SKILL_LEARNING:     v58 = PLAYER_SKILL_LEARNING;     break;
-  default:
-      no_skills=true;
+        return 3;
       }
-  if (!no_skills)
+      else
       {
-      if ( !this->pActiveSkills[v58] )
+        if ( this->HasItemEquipped(EQUIP_MAIN_HAND) )
+        {
+          v22 = this->GetEquippedItemEquipType(EQUIP_MAIN_HAND);
+          if ( v22 >= 0 && v22 <= 2)
+          {
+            v23 = this->pOwnItems[this->pEquipment.uMainHand].uItemID;
+            v26 = pItemsTable->pItems[v23].uDamageRoll;
+            if ( this->pEquipment.uShield || pItemsTable->pItems[v23].uSkillType != 4 )
+            {
+              v25 = pItemsTable->pItems[v23].uDamageDice;
+            }
+            else
+            {
+              v25 = pItemsTable->pItems[v23].uDamageDice + 1;
+            }
+            v5 = pItemsTable->pItems[v23].uDamageMod + v25 * v26;
+          }
+        }
+        if ( getOnlyMainHandDmg || !this->HasItemEquipped(EQUIP_OFF_HAND) ||  (GetEquippedItemEquipType(EQUIP_OFF_HAND) < 0 && GetEquippedItemEquipType(EQUIP_OFF_HAND) > 2))
+        {
+            return v5;
+        }
+        else
+        {
+          v23 = this->pOwnItems[this->pEquipment.uShield].uItemID;
+          v15 = pItemsTable->pItems[v23].uDamageMod;
+          v14 = pItemsTable->pItems[v23].uDamageDice * pItemsTable->pItems[v23].uDamageRoll;
+          return v5 + v15 + v14;
+        }
+      }
+    break;
+
+    case CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS:
+    case CHARACTER_ATTRIBUTE_ATTACK:
+      if ( IsUnarmed() )
+      {
         return 0;
       }
-
-  if ( (signed int)attr > 28 )
-  {
-    if ( (signed int)attr < 29 )
-      return v5 + v62 + v61;
-    if ( (signed int)attr <= CHARACTER_ATTRIBUTE_RANGED_DMG_BONUS )
-    {
-      if ( HasItemEquipped(EQUIP_BOW) )
-        v5 = pItemsTable->pItems[v6->pOwnItems[v6->pEquipment.uBow-1].uItemID].uDamageMod;
-      return v5 + v62 + v61;
-    }
-    if ( attr == CHARACTER_ATTRIBUTE_RANGED_DMG_MIN )
-    {
-      if ( !HasItemEquipped(EQUIP_BOW) )
-        return v5 + v62 + v61;
-      v57 = v6->pOwnItems[v6->pEquipment.uBow-1].uItemID;
-      v5 = pItemsTable->pItems[v57].uDamageMod;
-      v56 = pItemsTable->pItems[v57].uDamageDice;
-      v5 += v56;
-      return v5 + v62 + v61;
-    }
-    if ( attr == CHARACTER_ATTRIBUTE_RANGED_DMG_MAX )
-    {
-      if ( !HasItemEquipped(EQUIP_BOW) )
-        return v5 + v62 + v61;
-      v20 = v6->pOwnItems[v6->pEquipment.uBow-1].uItemID;
-      v5 = pItemsTable->pItems[v20].uDamageDice * pItemsTable->pItems[v20].uDamageRoll;
-LABEL_365:
-      v56 = pItemsTable->pItems[v20].uDamageMod;
-LABEL_366:
-      v5 += v56;
-      return v5 + v62 + v61;
-    }
-    if ( (signed int)attr <= 33 || (signed int)attr > 46 )
-      return v5 + v62 + v61;
-LABEL_95:
-    v65 = 0;
-    while ( 1 )
-    {
-      if ( !HasItemEquipped((ITEM_EQUIP_TYPE)v65) )
-        goto LABEL_361;
-      v31 = *(&v6->pEquipment.uShield + v65) - 1;
-      if ( v3 == 9 )
+      if ( this->HasItemEquipped(EQUIP_MAIN_HAND) )
+      {
+        v17 = this->GetEquippedItemEquipType(EQUIP_MAIN_HAND);
+        if ( v17 >= 0 && v17 <= 2)
+        {
+          v5 = pItemsTable->pItems[this->pOwnItems[this->pEquipment.uMainHand-1].uItemID].uDamageMod;
+        }
+      }
+      if ( getOnlyMainHandDmg || !this->HasItemEquipped(EQUIP_OFF_HAND) || (this->GetEquippedItemEquipType(EQUIP_OFF_HAND) < 0) || this->GetEquippedItemEquipType(EQUIP_OFF_HAND) > 2 )
+        return v5;
+      else
       {
-        v32 = GetEquippedItemEquipType((ITEM_EQUIP_TYPE)v65);
-        if ( v32 >= 3 )
+        v20 = this->pOwnItems[this->pEquipment.uShield - 1].uItemID;
+        v56 = pItemsTable->pItems[v20].uDamageMod;
+        return v5 + v56;
+      }
+      break;
+
+    case CHARACTER_ATTRIBUTE_MELEE_DMG_MIN:
+      if ( IsUnarmed() )
+      {
+        return 1;
+      }
+      if ( this->HasItemEquipped(EQUIP_MAIN_HAND) )
+      {
+        v9 = this->GetEquippedItemEquipType(EQUIP_MAIN_HAND);
+        if ( v9 >= 0 && v9 <= 2)
         {
-          if ( v32 <= 11 )
+          v5 = pItemsTable->pItems[this->pOwnItems[this->pEquipment.uMainHand].uItemID].uDamageDice +
+            pItemsTable->pItems[this->pOwnItems[this->pEquipment.uMainHand].uItemID].uDamageMod;
+          if ( !this->pEquipment.uShield && pItemsTable->pItems[this->pOwnItems[this->pEquipment.uMainHand].uItemID].uSkillType == 4)
           {
-            v33 = v6->pInventoryItemList[v31].uItemID;
-            v5 += pItemsTable->pItems[v33].uDamageDice + pItemsTable->pItems[v33].uDamageMod;
+            ++v5;
           }
         }
       }
-      v63 = (int)((char *)v6 + 36 * v31);
-      attra = (ItemGen *)(v63 + 532);
-      if ( pItemsTable->IsMaterialNonCommon((ItemGen *)(v63 + 532)) == 1
-        && !pItemsTable->IsMaterialSpecial(attra) )
+
+      if ( getOnlyMainHandDmg || !this->HasItemEquipped(EQUIP_OFF_HAND) || (this->GetEquippedItemEquipType(EQUIP_OFF_HAND) < 0) || this->GetEquippedItemEquipType(EQUIP_OFF_HAND) > 2 )
       {
-        v34 = attra->uItemID;
-        switch ( attra->uItemID )
-        {
-          case 0x1F4u:
-            v35 = v3 == 5;
-            goto LABEL_105;
-          case 0x1F5u:
-            v36 = v3 == 0;
-            goto LABEL_108;
-          case 0x1F6u:
-            if ( v3 == 21 )
-              v61 += 10;
-            v36 = v3 == 2;
-            goto LABEL_108;
-          case 0x1F7u:
-            if ( v3 == 17 )
-              v61 += 5;
-            if ( v3 == 18 )
-              v61 += 5;
-            v36 = v3 == 6;
-            goto LABEL_108;
-          case 0x1F8u:
-            goto LABEL_118;
-          case 0x1F9u:
-            v40 = v3 == 3;
-            goto LABEL_123;
-          case 0x1FAu:
-            v35 = v3 == 10;
-            goto LABEL_105;
-          case 0x1FEu:
-            v35 = v3 == 4;
-            goto LABEL_105;
-          case 0x1FFu:
-            if ( v3 == 23 )
-              v61 += 10;
-            if ( v3 == 22 )
-              v61 += 10;
-            goto LABEL_361;
-          case 0x200u:
-            if ( v3 == 36 )
-            {
-              LOBYTE(v34) = LOBYTE(v6->pActiveSkills[14]);
-              v62 = ((unsigned int)v34 >> 1) & 0x1F;
-            }
-            v36 = v3 == 5;
-LABEL_108:
-            if ( v36 )
-              v5 += 40;
-            goto LABEL_361;
-          case 0x201u:
-            if ( v3 == 39 )
-            {
-              LOBYTE(v34) = LOBYTE(v6->pActiveSkills[17]);
-              v34 = ((unsigned int)v34 >> 1) & 0x1F;
-              v62 = v34;
-            }
-            goto LABEL_136;
-          case 0x202u:
-            if ( !v3 )
-              v5 += 150;
-            if ( v3 == 1 )
-              v5 -= 40;
-            if ( v3 == 2 )
-              v5 -= 40;
-            goto LABEL_145;
-          case 0x203u:
-            if ( v3 == 42 )
-            {
-              LOBYTE(v34) = LOBYTE(v6->pActiveSkills[20]);
-              v62 = ((unsigned int)v34 >> 1) & 0x1F;
-            }
-            if ( v3 == 43 )
-              v61 += 15;
-            goto LABEL_361;
-          case 0x204u:
-            if ( v3 == 17 )
-              v61 += 5;
-            if ( v3 == 18 )
-              v61 += 5;
-            if ( v3 == 6 )
-              v5 += 50;
-            if ( v3 == 11 || v3 == 10 || v3 == 12 || v3 == 13 || v3 == 33 || v3 == 14 )
-              goto LABEL_166;
-            v42 = v3 == 15;
-            goto LABEL_165;
-          case 0x205u:
-            if ( v3 == 18 )
-              v61 += 5;
-            goto LABEL_361;
-          case 0x206u:
-            if ( !v3 )
-              v5 += 100;
-            if ( v3 == 3 )
-              v5 += 100;
-            v43 = v3 == 9;
-            goto LABEL_174;
-          case 0x207u:
-            if ( v3 == 45 )
-              v61 += 5;
-            if ( v3 == 15 )
-              v5 -= 10;
-            v42 = v3 == 14;
-LABEL_165:
-            if ( v42 )
-LABEL_166:
-              v5 -= 10;
-            goto LABEL_361;
-          case 0x208u:
-            v35 = v3 == 3;
-            goto LABEL_105;
-          case 0x209u:
-            if ( v3 == 2 )
-              v5 += 15;
-            if ( !v3 )
-              v5 += 15;
-            v41 = v3 == 6;
-            goto LABEL_146;
-          case 0x20Au:
-            if ( v3 == 46 )
-              v61 += 15;
-            v44 = v3 == 3;
-            goto LABEL_190;
-          case 0x20Bu:
-            if ( v3 == 34 )
-            {
-              LOBYTE(v34) = LOBYTE(v6->pActiveSkills[12]);
-              v62 = ((unsigned int)v34 >> 1) & 0x1F;
-            }
-            if ( v3 == 12 )
-              v5 += 50;
-            if ( v3 == 2 )
-              v5 += 30;
-            v45 = v3 == 9;
-            goto LABEL_199;
-          case 0x20Cu:
-            if ( !v3 )
-              v5 += 75;
-            goto LABEL_145;
-          case 0x20Du:
-            if ( v3 == 5 )
-              v5 += 50;
-            if ( v3 == 6 )
-              v5 += 50;
-            if ( v3 == 11 || v3 == 10 || v3 == 12 || v3 == 13 || v3 == 33 || v3 == 14 )
-              goto LABEL_374;
-            v43 = v3 == 15;
-LABEL_174:
-            if ( v43 )
-LABEL_374:
-              v5 -= 15;
-            goto LABEL_361;
-          case 0x20Eu:
-            if ( v3 == 4 )
-              v5 += 150;
-            if ( v3 == 44 )
-              v61 += 5;
-            if ( v3 == 9 )
-              v5 -= 25;
-            goto LABEL_361;
-          case 0x20Fu:
-            if ( v3 == 39 )
-            {
-              LOBYTE(v34) = LOBYTE(v6->pActiveSkills[17]);
-              v34 = ((unsigned int)v34 >> 1) & 0x1F;
-              v62 = v34;
-            }
-            if ( v3 == 40 )
-            {
-              LOBYTE(v34) = LOBYTE(v6->pActiveSkills[18]);
-              v62 = ((unsigned int)v34 >> 1) & 0x1F;
-            }
-LABEL_145:
-            v41 = v3 == 5;
-LABEL_146:
-            if ( v41 )
-              v5 -= 40;
-            goto LABEL_361;
-          case 0x210u:
-            if ( v3 == 38 )
-            {
-              LOBYTE(v34) = LOBYTE(v6->pActiveSkills[16]);
-              v62 = ((unsigned int)v34 >> 1) & 0x1F;
-            }
-            if ( !v3 )
-              v5 += 75;
-            v44 = v3 == 11;
-LABEL_190:
-            if ( v44 )
-              v5 -= 50;
-            goto LABEL_361;
-          case 0x211u:
-            if ( v3 == 5 )
-              v5 += 100;
-            if ( v3 == 4 )
-              v5 += 50;
-            v35 = v3 == 11;
-LABEL_105:
-            if ( v35 )
-              v5 += 50;
-            goto LABEL_361;
-          case 0x212u:
-            if ( v3 == 1 )
-              v5 -= 20;
-            v45 = v3 == 2;
-LABEL_199:
-            if ( v45 )
-              v5 -= 20;
-            goto LABEL_361;
-          case 0x214u:
-            if ( v3 == 1 )
-              v5 += 15;
-            v46 = v3 == 2;
-            goto LABEL_240;
-          case 0x215u:
-            if ( v3 == 5 )
-              v5 += 15;
-            v46 = v3 == 4;
-            goto LABEL_240;
-          case 0x216u:
-            if ( v3 == 10 )
-              v5 += 30;
-            if ( !v3 )
-              v5 += 15;
-            goto LABEL_315;
-          case 0x217u:
-            if ( v3 == 21 )
-              v61 += 5;
-            if ( !v3 )
-              v5 += 15;
-            goto LABEL_253;
-          case 0x218u:
-            goto LABEL_253;
-          default:
-            goto LABEL_361;
-        }
-        goto LABEL_361;
-      }
-      if ( *(int *)(v63 + 536) == v3 + 1 )
-      {
-        if ( (signed int)v3 >= 0 )
-        {
-          if ( (signed int)v3 <= 15 )
-          {
-            v5 += *((int *)v6->pConditions + 9 * v31 + 135);
-          }
-          else
-          {
-            if ( (signed int)v3 <= 23 && v5 < *((int *)v6->pConditions + 9 * v31 + 135) )
-              v5 = *((int *)v6->pConditions + 9 * v31 + 135);
-          }
-        }
-        goto LABEL_361;
-      }
-      v34 = *(int *)(v63 + 544);
-      if ( v34 > 48 )
-      {
-        switch ( v34 )
-        {
-          case 54:
-            goto LABEL_315;
-          case 49:
-            if ( v3 == 6 )
-              goto LABEL_121;
-            v50 = v3 == 1;
-            goto LABEL_296;
-          case 51:
-            if ( v3 != 5 && v3 != 1 )
-              goto LABEL_309;
-            goto LABEL_121;
-          case 52:
-            if ( v3 == 3 )
-              goto LABEL_121;
-            v50 = v3 == 4;
-            goto LABEL_296;
-          case 53:
-            if ( !v3 )
-              goto LABEL_121;
-            v50 = v3 == 2;
-            goto LABEL_296;
-          case 55:
-            v46 = v3 == 6;
-            goto LABEL_240;
-          case 56:
-            if ( !v3 )
-              goto LABEL_351;
-            v53 = v3 == 3;
-            goto LABEL_350;
-          case 57:
-            if ( v3 == 1 )
-              goto LABEL_351;
-            v53 = v3 == 2;
-            goto LABEL_350;
-          case 50:
-            if ( v3 == 10 )
-              v5 += 30;
-            goto LABEL_361;
-          case 60:
-            if ( v3 != 23 )
-              goto LABEL_336;
-            if ( v5 >= 3 )
-              goto LABEL_361;
-            v5 = 3;
-LABEL_336:
-            v54 = v3 == 22;
-            goto LABEL_345;
-          case 61:
-            if ( v3 != 17 )
-              goto LABEL_340;
-            if ( v5 >= 3 )
-              goto LABEL_361;
-            v5 = 3;
-LABEL_340:
-            v54 = v3 == 18;
-            goto LABEL_345;
-          case 62:
-            if ( v3 != 19 )
-              goto LABEL_344;
-            if ( v5 >= 3 )
-              goto LABEL_361;
-            v5 = 3;
-LABEL_344:
-            v54 = v3 == 20;
-LABEL_345:
-            if ( !v54 )
-              goto LABEL_361;
-            if ( v5 >= 3 )
-              goto LABEL_361;
-            v60 = 3;
-            goto LABEL_360;
-          case 67:
-            v55 = v3 == 18;
-            goto LABEL_357;
-          case 68:
-            v53 = v3 == 9;
-            goto LABEL_350;
-          case 69:
-            if ( v3 == 11 )
-              v5 += 20;
-            break;
-          case 70:
-            if ( v3 == 12 )
-              v5 += 10;
-            v55 = v3 == 16;
-LABEL_357:
-            if ( v55 && v5 < 2 )
-            {
-              v60 = 2;
-LABEL_360:
-              v5 = v60;
-            }
-            break;
-          default:
-            goto LABEL_361;
-        }
-        goto LABEL_361;
-      }
-      if ( v34 == 48 )
-      {
-        if ( v3 == 9 )
-          v5 += 5;
-LABEL_315:
-        v46 = v3 == 3;
-LABEL_240:
-        if ( v46 )
-          v5 += 15;
-        goto LABEL_361;
-      }
-      if ( v34 > 32 )
-      {
-        if ( v34 > 44 )
-        {
-          v51 = v34 - 45;
-          if ( !v51 )
-          {
-            if ( v3 == 5 )
-              goto LABEL_351;
-            v53 = v3 == 4;
-LABEL_350:
-            if ( v53 )
-LABEL_351:
-              v5 += 5;
-            goto LABEL_361;
-          }
-          v52 = v51 - 1;
-          if ( !v52 )
-          {
-            v40 = v3 == 0;
-LABEL_123:
-            if ( v40 )
-              v5 += 25;
-            goto LABEL_361;
-          }
-          if ( v52 == 1 )
-          {
-LABEL_309:
-            v50 = v3 == 8;
-            goto LABEL_296;
-          }
-        }
-        else
-        {
-          if ( v34 == 44 )
-          {
-            v50 = v3 == 7;
-            goto LABEL_296;
-          }
-          v34 -= 33;
-          if ( !v34 )
-          {
-            if ( v3 != 38 )
-              goto LABEL_361;
-            LOBYTE(v34) = LOBYTE(v6->pActiveSkills[16]);
-            goto LABEL_138;
-          }
-          --v34;
-          if ( !v34 )
-          {
-            if ( v3 != 36 )
-              goto LABEL_361;
-            LOBYTE(v34) = LOBYTE(v6->pActiveSkills[14]);
-            goto LABEL_138;
-          }
-          v49 = v34 - 8;
-          if ( !v49 )
-          {
-            if ( (signed int)v3 >= 0 && (signed int)v3 <= 15 )
-              ++v5;
-            goto LABEL_361;
-          }
-          if ( v49 == 1 )
-          {
-            if ( v3 != 3 && v3 != 7 )
-            {
-              v50 = v3 == 9;
-LABEL_296:
-              if ( !v50 )
-                goto LABEL_361;
-            }
-LABEL_121:
-            v5 += 10;
-            goto LABEL_361;
-          }
-        }
+        return v5;
       }
       else
       {
-        if ( v34 == 32 )
+        v14 = pItemsTable->pItems[this->pOwnItems[this->pEquipment.uShield].uItemID].uDamageMod;
+        v15 = pItemsTable->pItems[this->pOwnItems[this->pEquipment.uShield].uItemID].uDamageDice;
+        return v5 + v15 + v14;
+      }
+      break;
+
+    case   CHARACTER_ATTRIBUTE_STRENGTH:
+    case   CHARACTER_ATTRIBUTE_INTELLIGENCE:
+    case   CHARACTER_ATTRIBUTE_WILLPOWER:
+    case   CHARACTER_ATTRIBUTE_ENDURANCE:
+    case   CHARACTER_ATTRIBUTE_ACCURACY:
+    case   CHARACTER_ATTRIBUTE_SPEED:
+    case   CHARACTER_ATTRIBUTE_LUCK:
+    case   CHARACTER_ATTRIBUTE_HEALTH:
+    case   CHARACTER_ATTRIBUTE_MANA:
+    case   CHARACTER_ATTRIBUTE_AC_BONUS:
+
+    case   CHARACTER_ATTRIBUTE_RESIST_FIRE:
+    case   CHARACTER_ATTRIBUTE_RESIST_AIR:
+    case   CHARACTER_ATTRIBUTE_RESIST_WATER:
+    case   CHARACTER_ATTRIBUTE_RESIST_EARTH:
+    case   CHARACTER_ATTRIBUTE_RESIST_MIND:
+    case   CHARACTER_ATTRIBUTE_RESIST_BODY:        
+    case   CHARACTER_ATTRIBUTE_RESIST_SPIRIT:
+
+    case   CHARACTER_ATTRIBUTE_SKILL_ALCHEMY:
+    case   CHARACTER_ATTRIBUTE_SKILL_STEALING:
+    case   CHARACTER_ATTRIBUTE_SKILL_TRAP_DISARM:
+    case   CHARACTER_ATTRIBUTE_SKILL_ITEM_ID:
+    case   CHARACTER_ATTRIBUTE_SKILL_MONSTER_ID:
+    case   CHARACTER_ATTRIBUTE_SKILL_ARMSMASTER:
+    case   CHARACTER_ATTRIBUTE_SKILL_DODGE:
+    case   CHARACTER_ATTRIBUTE_SKILL_UNARMED:
+
+    case   CHARACTER_ATTRIBUTE_SKILL_FIRE:
+    case   CHARACTER_ATTRIBUTE_SKILL_AIR:
+    case   CHARACTER_ATTRIBUTE_SKILL_WATER:
+    case   CHARACTER_ATTRIBUTE_SKILL_EARTH:
+    case   CHARACTER_ATTRIBUTE_SKILL_SPIRIT:
+    case   CHARACTER_ATTRIBUTE_SKILL_MIND:
+    case   CHARACTER_ATTRIBUTE_SKILL_BODY:
+    case   CHARACTER_ATTRIBUTE_SKILL_LIGHT:
+    case   CHARACTER_ATTRIBUTE_SKILL_DARK:
+    case   CHARACTER_ATTRIBUTE_SKILL_MEDITATION:
+    case   CHARACTER_ATTRIBUTE_SKILL_BOW:
+    case   CHARACTER_ATTRIBUTE_SKILL_SHIELD:
+    case   CHARACTER_ATTRIBUTE_SKILL_LEARNING:
+      for (int i = 0; i < 16; i++)
+      {
+        if ( HasItemEquipped((ITEM_EQUIP_TYPE)i) )
         {
-          if ( v3 != 39 )
-            goto LABEL_361;
-          LOBYTE(v34) = LOBYTE(v6->pActiveSkills[17]);
-          goto LABEL_138;
-        }
-        if ( v34 > 28 )
-        {
-          v34 -= 29;
-          if ( v34 )
+          v31 = this->pEquipment.pIndices[i] - 1;
+          currEquippedItem = &this->pInventoryItemList[v31];
+          if ( attr == CHARACTER_ATTRIBUTE_AC_BONUS )
           {
-            --v34;
-            if ( v34 )
+            v32 = GetEquippedItemEquipType((ITEM_EQUIP_TYPE)i);
+            if ( v32 >= 3 && v32 <= 11 )
             {
-              --v34;
-              if ( v34 || v3 != 41 )
-                goto LABEL_361;
-              LOBYTE(v34) = LOBYTE(v6->pActiveSkills[19]);
+              v33 = currEquippedItem->uItemID;
+              v5 += pItemsTable->pItems[v33].uDamageDice + pItemsTable->pItems[v33].uDamageMod;
             }
-            else
+          }
+          if ( pItemsTable->IsMaterialNonCommon((ItemGen *)(currEquippedItem))
+            && !pItemsTable->IsMaterialSpecial(currEquippedItem) )
+          {
+            currEquippedItem->GetItemBonusArtifact(this, attr, &v62);
+          }
+          else if ( currEquippedItem->uEnchantmentType != 0 )
+          {
+            if (currEquippedItem->IsRegularEnchanmentForAttribute(attr))
             {
-              if ( v3 != 34 )
-                goto LABEL_361;
-              LOBYTE(v34) = LOBYTE(v6->pActiveSkills[12]);
+              if ( attr > CHARACTER_ATTRIBUTE_RESIST_BODY && v5 < currEquippedItem->m_enchantmentStrength )
+                v5 = currEquippedItem->m_enchantmentStrength;
+              else
+                v5 += currEquippedItem->m_enchantmentStrength;
             }
           }
           else
           {
-            if ( v3 != 37 )
-              goto LABEL_361;
-            LOBYTE(v34) = LOBYTE(v6->pActiveSkills[15]);
-          }
-          goto LABEL_138;
-        }
-        if ( v34 == 28 )
-        {
-LABEL_136:
-          if ( v3 == 42 )
-          {
-            LOBYTE(v34) = LOBYTE(v6->pActiveSkills[20]);
-LABEL_138:
-            v62 = ((unsigned int)v34 >> 1) & 0x1F;
-            goto LABEL_361;
-          }
-        }
-        else
-        {
-          v47 = v34 - 1;
-          if ( v47 )
-          {
-            v48 = v47 - 1;
-            if ( v48 )
-            {
-              v34 = v48 - 24;
-              if ( v34 )
-              {
-                --v34;
-                if ( v34 || v3 != 40 )
-                  goto LABEL_361;
-                LOBYTE(v34) = LOBYTE(v6->pActiveSkills[18]);
-              }
-              else
-              {
-                if ( v3 != 35 )
-                  goto LABEL_361;
-                LOBYTE(v34) = LOBYTE(v6->pActiveSkills[13]);
-              }
-              goto LABEL_138;
-            }
-LABEL_118:
-            if ( (signed int)v3 < 0 )
-              goto LABEL_361;
-            v39 = __OFSUB__((int)v3, 6);
-            v37 = v3 == 6;
-            v38 = v3 - 6 < 0;
-          }
-          else
-          {
-LABEL_253:
-            if ( (signed int)v3 < 10 )
-              goto LABEL_361;
-            v39 = __OFSUB__((int)v3, 15);
-            v37 = v3 == 15;
-            v38 = v3 - 15 < 0;
-          }
-          if ( (unsigned __int8)(v38 ^ v39) | v37 )
-            goto LABEL_121;
-        }
-      }
-LABEL_361:
-      ++v65;
-      if ( (signed int)v65 >= 16 )
-        return v5 + v62 + v61;
-    }
-  }
-  if ( attr == CHARACTER_ATTRIBUTE_MELEE_DMG_MAX )
-  {
-    if ( IsUnarmed() != 1 )
-    {
-      if ( v6->HasItemEquipped(EQUIP_MAIN_HAND) )
-      {
-        v22 = this->GetEquippedItemEquipType(EQUIP_MAIN_HAND);
-        if ( v22 >= 0 )
-        {
-          if ( v22 <= 2 )
-          {
-			  v23 = this->pOwnItems[this->pEquipment.uMainHand].uItemID;
-            if ( v6->pEquipment.uShield || pItemsTable->pItems[v23].uSkillType != 4 )
-            {
-              v26 = pItemsTable->pItems[v23].uDamageRoll;
-              v25 = pItemsTable->pItems[v23].uDamageDice;
-            }
-            else
-            {
-              v25 = pItemsTable->pItems[v23].uDamageRoll;
-              v26 = pItemsTable->pItems[v23].uDamageDice + 1;
-            }
-            v5 = pItemsTable->pItems[v23].uDamageMod + v25 * v26;
+            currEquippedItem->GetItemBonusSpecialEnchantment(this, attr, &v5, &v61);
           }
         }
       }
-      
-      if ( a3 || !v6->HasItemEquipped(EQUIP_OFF_HAND) )
-          {
-
-          v28 = v6->GetEquippedItemEquipType(EQUIP_OFF_HAND);
-          if ((v28 < 0) || v28 > 2 )
-              return v5 + v62 + v61;
-        }
-      v15 = pItemsTable->pItems[v23].uDamageMod;
-      v14 = pItemsTable->pItems[v23].uDamageDice * pItemsTable->pItems[v23].uDamageRoll;
-      v5 += v15 + v14;
       return v5 + v62 + v61;
-    }
-    v59 = 3;
-LABEL_74:
-    v5 = v59;
-    return v5 + v62 + v61;
-  }
-  if ( (signed int)attr < 0 )
-    return v5 + v62 + v61;
-  if ( (signed int)attr <= CHARACTER_ATTRIBUTE_SKILL_UNARMED )
-    goto LABEL_95;
-  if ( attr == CHARACTER_ATTRIBUTE_LEVEL )
-      {
-      if ( !Player::HasEnchantedItemEquipped(25) )
-          return v5 + v62 + v61;
-      v5 = 5;
-      return v5 + v62 + v61;
-      }
-  if ( (signed int)attr <= CHARACTER_ATTRIBUTE_LEVEL )
-    return v5 + v62 + v61;
-  if ( (signed int)attr <= CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS )
-  {
-    if ( IsUnarmed() == 1 )
-    {
-      v5 = 0;
-      return v5 + v62 + v61;
-    }
-    if ( v6->HasItemEquipped(EQUIP_MAIN_HAND) )
-    {
-      v17 = this->GetEquippedItemEquipType(EQUIP_MAIN_HAND);
-      if ( v17 >= 0 )
-      {
-        if ( v17 <= 2 )
-          v5 = pItemsTable->pItems[v6->pOwnItems[v6->pEquipment.uMainHand-1].uItemID].uDamageMod;
-      }
-    }
-    if ( a3 || !v6->HasItemEquipped(EQUIP_OFF_HAND) || (v19 = v6->GetEquippedItemEquipType(EQUIP_OFF_HAND), v19 < 0) || v19 > 2 )
-      return v5 + v62 + v61;
-    v20 = v6->pOwnItems[v6->pEquipment.uShield - 1].uItemID;
-    v56 = pItemsTable->pItems[v20].uDamageMod;
-    v5 += v56;
-    return v5 + v62 + v61;
-  }
-  if ( attr == CHARACTER_ATTRIBUTE_MELEE_DMG_MIN )
-  {
-    if ( IsUnarmed() == 1 )
-    {
-      v5 = 1;
-      return v5 + v62 + v61;
-    }
-    if ( v6->HasItemEquipped(EQUIP_MAIN_HAND) )
-    {
-      v9 = this->GetEquippedItemEquipType(EQUIP_MAIN_HAND);
-      if ( v9 >= 0 )
-      {
-        if ( v9 <= 2 )
-        {
-          v5 = pItemsTable->pItems[this->pOwnItems[this->pEquipment.uMainHand].uItemID].uDamageDice +
-                 pItemsTable->pItems[this->pOwnItems[this->pEquipment.uMainHand].uItemID].uDamageMod;
-          if ( !v6->pEquipment.uShield )
-          {
-            if ( pItemsTable->pItems[this->pOwnItems[this->pEquipment.uMainHand].uItemID].uSkillType == 4 )
-              ++v5;
-          }
-        }
-      }
-    }
-    
-    if ( a3 || !v6->HasItemEquipped(EQUIP_OFF_HAND))
-        {
-        v12 = v6->GetEquippedItemEquipType(EQUIP_OFF_HAND);
-        if  ((v12 < 0) || v12 > 2 )
-                return v5 + v62 + v61;
-        }
-    v14 = pItemsTable->pItems[this->pOwnItems[this->pEquipment.uShield].uItemID].uDamageMod;
-    v15 = pItemsTable->pItems[this->pOwnItems[this->pEquipment.uShield].uItemID].uDamageDice;
-LABEL_88:
-    v5 += v15 + v14;
-  }
-  return v5 + v62 + v61;
+      break;
+    default:
+      return 0;
+    }
 }
 
 //----- (0048F73C) --------------------------------------------------------
@@ -4137,7 +3504,7 @@
         bonus_value = 6;
       if ( CheckHiredNPCSpeciality(Sage) )
         bonus_value += 6;
-      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_MONSTER_ID, 0);
+      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_MONSTER_ID);
     }
     break;
 
@@ -4147,7 +3514,7 @@
           bonus_value = 2;
         if ( CheckHiredNPCSpeciality(Weaponsmaster) )
           bonus_value += 3;
-      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_ARMSMASTER, 0);
+      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_ARMSMASTER);
     }
     break;
 
@@ -4155,7 +3522,7 @@
     {
       if (CheckHiredNPCSpeciality(Burglar))
           bonus_value = 8;
-      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_STEALING, 0);
+      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_STEALING);
     }
     break;
 
@@ -4166,7 +3533,7 @@
           bonus_value = 4;
         if ( CheckHiredNPCSpeciality(Apothecary) )
           bonus_value += 8;
-        bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_ALCHEMY, 0);
+        bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_ALCHEMY);
     }
     break;
 
@@ -4178,7 +3545,7 @@
           bonus_value += 15;
         if ( CheckHiredNPCSpeciality(Scholar) )
           bonus_value += 5;
-      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_LEARNING, 0);
+      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_LEARNING);
     }
     break;
 
@@ -4186,7 +3553,7 @@
     {
       if (CheckHiredNPCSpeciality(Monk) )
         bonus_value = 2;
-      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_UNARMED, 0);
+      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_UNARMED);
     }
     break;
 
@@ -4194,15 +3561,15 @@
     {
       if ( CheckHiredNPCSpeciality(Monk) )
         bonus_value = 2;
-      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_DODGE, 0);
+      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_DODGE);
     }
     break;
     
     case PLAYER_SKILL_BOW:
-      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_BOW, 0);
+      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_BOW);
     break;
     case PLAYER_SKILL_SHIELD:
-      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_SHIELD, 0);
+      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_SHIELD);
     break;
 
     case PLAYER_SKILL_EARTH:
@@ -4214,7 +3581,7 @@
             bonus_value += 4;
           if ( classType == PLAYER_CLASS_WARLOCK && PartyHasDragon() )
             bonus_value += 3;
-      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_EARTH, 0);
+      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_EARTH);
     break;
     case PLAYER_SKILL_FIRE:
       if ( CheckHiredNPCSpeciality(Apprentice) )
@@ -4225,7 +3592,7 @@
             bonus_value += 4;
           if ( classType == PLAYER_CLASS_WARLOCK && PartyHasDragon() )
             bonus_value += 3;
-      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_FIRE, 0);
+      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_FIRE);
     break;
     case PLAYER_SKILL_AIR:
       if ( CheckHiredNPCSpeciality(Apprentice) )
@@ -4236,7 +3603,7 @@
             bonus_value += 4;
           if ( classType == PLAYER_CLASS_WARLOCK && PartyHasDragon() )
             bonus_value += 3;
-      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_AIR, 0);
+      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_AIR);
     break;
     case PLAYER_SKILL_WATER:
       if ( CheckHiredNPCSpeciality(Apprentice) )
@@ -4247,7 +3614,7 @@
             bonus_value += 4;
           if ( classType == PLAYER_CLASS_WARLOCK && PartyHasDragon() )
             bonus_value += 3;
-      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_WATER, 0);
+      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_WATER);
     break;
     case PLAYER_SKILL_SPIRIT:
           if ( CheckHiredNPCSpeciality(Acolyte2) )
@@ -4256,7 +3623,7 @@
             bonus_value += 3;
           if ( CheckHiredNPCSpeciality(Prelate) )
             bonus_value += 4;
-      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_SPIRIT, 0);
+      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_SPIRIT);
     break;
     case PLAYER_SKILL_MIND:
           if ( CheckHiredNPCSpeciality(Acolyte2) )
@@ -4265,7 +3632,7 @@
             bonus_value += 3;
           if ( CheckHiredNPCSpeciality(Prelate) )
             bonus_value += 4;
-      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_MIND, 0);
+      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_MIND);
     break;
     case PLAYER_SKILL_BODY:
           if ( CheckHiredNPCSpeciality(Acolyte2) )
@@ -4274,14 +3641,14 @@
             bonus_value += 3;
           if ( CheckHiredNPCSpeciality(Prelate) )
             bonus_value += 4;
-      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_BODY, 0);
+      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_BODY);
     break;
     case PLAYER_SKILL_LIGHT:
-      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_LIGHT, 0);
+      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_LIGHT);
     break;
     case PLAYER_SKILL_DARK:
     {
-      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_DARK, 0);
+      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_DARK);
     }
     break;
 
@@ -4308,10 +3675,10 @@
     break;
 
     case PLAYER_SKILL_ITEM_ID:
-      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_ITEM_ID, 0);
+      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_ITEM_ID);
       break;
     case PLAYER_SKILL_MEDITATION:
-      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_MEDITATION, 0);
+      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_MEDITATION);
     break;
     case PLAYER_SKILL_TRAP_DISARM:
     {
@@ -4321,7 +3688,7 @@
         bonus_value += 6;
       if ( CheckHiredNPCSpeciality(Burglar) )
         bonus_value += 8;
-      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_TRAP_DISARM, 0);
+      bonus_value += GetItemsBonus(CHARACTER_ATTRIBUTE_SKILL_TRAP_DISARM);
     }
     break;
   }
@@ -8991,4 +8358,4 @@
 void Player::SetCondUnconsciousWithBlockCheck( int blockable )
 {
   SetCondition(Condition_Dead, blockable);
-}
\ No newline at end of file
+}
--- a/Player.h	Sat Sep 14 10:28:13 2013 +0600
+++ b/Player.h	Sat Sep 14 10:28:23 2013 +0600
@@ -518,8 +518,8 @@
   void RandomizeName();
   unsigned int GetMajorConditionIdx();
   int GetParameterBonus(int player_parameter);
-  int _48EA46_calc_special_bonus_by_items(int a2);
-  int GetItemsBonus(enum CHARACTER_ATTRIBUTE_TYPE attr, int a3);
+  int GetSpecialItemBonus(int enchantmentId);
+  int GetItemsBonus(enum CHARACTER_ATTRIBUTE_TYPE attr, bool a3 = false);
   int GetMagicalBonus(enum CHARACTER_ATTRIBUTE_TYPE a2);
   int GetActualSkillLevel(PLAYER_SKILL_TYPE uSkillType);
   int GetSkillBonus(enum CHARACTER_ATTRIBUTE_TYPE a2);
@@ -584,6 +584,7 @@
   unsigned int GetMultiplierForSkillLevel(unsigned int skillValue, int mult1, int mult2, int mult3, int mult4);
   int CalculateMeleeDmgToEnemyWithWeapon( ItemGen * weapon, unsigned int uTargetActorID , bool addOneDice);
   bool WearsItemAnyWhere(int item_id);
+  float GetArmorRecoveryMultiplierFromSkillLevel( unsigned char armour_skill_type, float param2, float param3, float param4, float param5 );
 
   bool IsWeak();
   bool IsDead();
--- a/UI/UIPopup.cpp	Sat Sep 14 10:28:13 2013 +0600
+++ b/UI/UIPopup.cpp	Sat Sep 14 10:28:23 2013 +0600
@@ -439,12 +439,12 @@
         else if ( inspect_item->uEnchantmentType )
             {
             sprintf(out_text + 200, "%s: %s +%d", pGlobalTXT_LocalizationStrings[210],
-                pItemsTable->pEnchantments[inspect_item->uEnchantmentType-1].pBonusStat, inspect_item->_bonus_strength); //"Special"
+                pItemsTable->pEnchantments[inspect_item->uEnchantmentType-1].pBonusStat, inspect_item->m_enchantmentStrength); //"Special"
             }
         else  if ( inspect_item->uSpecEnchantmentType )
             {      
             sprintf(out_text + 200, "%s: %s", pGlobalTXT_LocalizationStrings[210], 
-                pItemsTable->pSpecialEnchantments[inspect_item->uSpecEnchantmentType-1].pBonusStatement, inspect_item->_bonus_strength);
+                pItemsTable->pSpecialEnchantments[inspect_item->uSpecEnchantmentType-1].pBonusStatement, inspect_item->m_enchantmentStrength);
             }
 
         else if ( inspect_item->uNumCharges )
--- a/mm7_2.cpp	Sat Sep 14 10:28:13 2013 +0600
+++ b/mm7_2.cpp	Sat Sep 14 10:28:23 2013 +0600
@@ -910,6 +910,7 @@
   v231 = 0;
   if ( dstHeight <= 0 )
     return result;
+  
   do
   {
     for (int counter = 0; counter < dstWidth; counter++)
@@ -935,11 +936,11 @@
         for(int i = 0; i < ratioDiff; i++)
         {
           if(field0value == 32)
-            v21 = _450FB1((int)v175[i]);
+            v21 = _450FB1(((int*)v175)[i]);
           else if(field0value == 16)
-            v21 = _450FB1((_WORD)v175[i]);
+            v21 = _450FB1(((_WORD*)v175)[i]);
           else
-            v21 = _450FB1((unsigned __int8)v175[i]);
+            v21 = _450FB1(((unsigned __int8*)v175)[i]);
           v240 += ((unsigned int)v21 >> 24);
           a6b += BYTE2(v21);
           v252 += BYTE1(v21);
--- a/mm7_4.cpp	Sat Sep 14 10:28:13 2013 +0600
+++ b/mm7_4.cpp	Sat Sep 14 10:28:23 2013 +0600
@@ -850,7 +850,7 @@
             v21->pConditions[13] = pParty->uTimePlayed;
           if ( v35 < 1 )
           {
-            if ( v21->sHealth + v21->uEndurance + v21->GetItemsBonus(CHARACTER_ATTRIBUTE_ENDURANCE, 0) >= 1
+            if ( v21->sHealth + v21->uEndurance + v21->GetItemsBonus(CHARACTER_ATTRIBUTE_ENDURANCE) >= 1
               || (signed __int64)v21->pPlayerBuffs[11].uExpireTime > 0 )
             {
               v21->pConditions[13] = pParty->uTimePlayed;
@@ -1139,7 +1139,7 @@
     if ( (*v62)->uTimeToRecovery )
       v21->Recover(a2a);
     v22 = v21->sHealth;
-    if ( v21->GetItemsBonus(CHARACTER_ATTRIBUTE_ENDURANCE, 0) + v22 + v21->uEndurance >= 1
+    if ( v21->GetItemsBonus(CHARACTER_ATTRIBUTE_ENDURANCE) + v22 + v21->uEndurance >= 1
       || (signed __int64)v21->pPlayerBuffs[11].uExpireTime > 0 )
     {
       if ( v22 < 1 )