changeset 1557:6292a522d322

Merge
author Nomad
date Sat, 07 Sep 2013 22:46:18 +0200
parents e668660457dc (current diff) 9c4cf5b07e98 (diff)
children c44db078127d
files
diffstat 4 files changed, 277 insertions(+), 628 deletions(-) [+]
line wrap: on
line diff
--- a/Actor.cpp	Sat Sep 07 22:38:53 2013 +0200
+++ b/Actor.cpp	Sat Sep 07 22:46:18 2013 +0200
@@ -5053,7 +5053,7 @@
     v50 = pMonster->pMonsterInfo.uID;
     a2 = 4;
     //v27 = player->CalculateMeleeDamageTo(0, 0, v50);
-    uDamageAmount = player->CalculateMeleeDamageTo(0, 0, v50);
+    uDamageAmount = player->CalculateMeleeDamageTo(false, false, v50);
     //if ( !v57 )
       goto LABEL_67;
     //goto LABEL_69;
@@ -5115,7 +5115,7 @@
     if ( (signed int)SkillToMastery(v16) >= 3 )
       a4 = player->pActiveSkills[7] & 0x3F;
     a2 = 4;
-    uDamageAmount = player->CalculateMeleeDamageTo(1, 1, 0);
+    uDamageAmount = player->CalculateMeleeDamageTo(true, true, 0);
     goto LABEL_67;
   }
   if ( v15 != SPELL_BOW_ARROW )
--- a/Items.h	Sat Sep 07 22:38:53 2013 +0200
+++ b/Items.h	Sat Sep 07 22:46:18 2013 +0200
@@ -81,21 +81,32 @@
   ITEM_SPELLBOOK_LIGHT_SUN_BURST = 0x1E6,
   ITEM_SPELLBOOK_LIGHT_DIVINE_INTERVENTION = 0x1E7,
   ITEM_ARTIFACT_PUCK = 500,//0x1F4,
+  ITEM_ARTIFACT_IRON_FEATHER = 501,
+  ITEM_ARTIFACT_WALLACE = 502,
+  ITEM_ARTIFACT_CORSAIR = 503,
   ITEM_ARTICACT_GOVERNONS_ARMOR = 504,//1F8
   ITEM_ARTIFACT_YORUBA = 505,//1F9
   ITEM_ARTIFACT_SPLITTER = 506,//1FA
   ITEM_ARTIFACT_GHOULSBANE = 507,//1FA
+  ITEM_ARTIFACT_GIBBET = 508,//1FA
+  ITEM_ARTIFACT_CHARELE = 509,//1FA
   ITEM_ARTEFACT_ULLYSES =510, 
+  ITEM_ARTEFACT_HANDS_OF_THE_MASTER =511, 
   ITEM_ARTIFACT_LEAGUE_BOOTS = 512,//200
+  ITEM_ARTIFACT_RULERS_RING = 513,
+  ITEM_RELIC_MASH = 514,
   ITEM_RELIC_ETHRICS_STAFF = 515,//204
   ITEM_RELIC_HARECS_LEATHER = 516,//204
-  ITEM_RELIC_OLD_NICK = 517,//204
+  ITEM_RELIC_OLD_NICK = 517,
+  ITEM_RELIC_AMUCK = 518,
+  ITEM_RELIC_GLORY_SHIELD = 519,
   ITEM_RELIC_KELEBRIM = 520,//208
   ITEM_RELIC_TALEDONS_HELM = 521,//209
   ITEM_RELIC_SCHOLARS_CAP = 522,//20A
   ITEM_RELIC_PHYNAXIAN_CROWN = 523,//20B
   ITEM_RILIC_TITANS_BELT = 524,//20C
   ITEM_RELIC_TWILIGHT = 525,//20D
+  ITEM_RELIC_ANIA_SELVING = 526,
   ITEM_RELIC_JUSTICE = 527,
   ITEM_RELIC_MEKORIGS_HAMMER = 528,
   ITEM_ARTIFACT_HERMES_SANDALS = 529,
@@ -177,6 +188,7 @@
   int _bonus_strength;  //8
   int uSpecEnchantmentType; // 25  +5 levels //0c
                             // 16  Drain Hit Points from target.
+                            // 35  Increases chance of disarming.
                             // 39  Double damage vs Demons.
                             // 40  Double damage vs Dragons
                             // 45  +5 Speed and Accuracy
--- a/Player.cpp	Sat Sep 07 22:38:53 2013 +0200
+++ b/Player.cpp	Sat Sep 07 22:46:18 2013 +0200
@@ -263,7 +263,7 @@
     if (item_idx)
     {
       item_id = pOwnItems[item_idx - 1].uItemID;
-      if ( item_id != 64 && item_id != 65 ) //blaster& blaster rifle
+      if ( item_id != ITEM_BLASTER && item_id != ITEM_LASER_RIFLE ) //blaster& blaster rifle
           return false;
     }
   }
@@ -340,7 +340,6 @@
 int Player::GetBuyingPrice(unsigned int uRealValue, float price_multiplier)
 {
   uint price = (uint)(((100 - GetMerchant()) * (uRealValue * price_multiplier)) / 100);
-  Assert (price > 0);
 
   if (price < uRealValue)
     price = uRealValue;
@@ -810,24 +809,19 @@
     texture->Release();
     pIcons_LOD->SyncLoadedFilesCount();
   }
-
-  Assert(slotHeight && slotWidth, "Items should have nonzero dimensions");
+  Assert(slotHeight > 0 && slotWidth > 0, "Items should have nonzero dimensions");
   if ( (slotWidth + uSlot % INVETORYSLOTSWIDTH) <= INVETORYSLOTSWIDTH && (slotHeight + uSlot / INVETORYSLOTSWIDTH) <= INVETORYSLOTSHEIGHT )
   {
-    int startOfInnerLoop = uSlot;
-    for (unsigned int y = 0; y < slotHeight; y++)
-    {
-      int innerLoopPos = startOfInnerLoop;
       for (unsigned int x = 0; x < slotWidth; x++)
       {
-        if (pInventoryMatrix[innerLoopPos] != 0)
+        for (unsigned int y = 0; y < slotHeight; y++)
         {
-          return false;
+          if (pInventoryMatrix[y * INVETORYSLOTSWIDTH + x + uSlot] != 0)
+          {
+            return false;
+          }
         }
-        innerLoopPos++;
       }
-      startOfInnerLoop += INVETORYSLOTSWIDTH;
-    }
     return true;
   }
   return false;
@@ -905,23 +899,19 @@
 int Player::AddItem(int index, unsigned int uItemID)
 {
   int xStartValue = 0;
-  int startOfInnerLoop = 0;
 
   if ( index == -1 )
   {
-    for (int ycoord = 0; ycoord < INVETORYSLOTSHEIGHT; ycoord++)
-    {
-      int innerLoopPos = startOfInnerLoop;
       for (int xcoord = 0; xcoord < INVETORYSLOTSWIDTH; xcoord++)
       {
-        if ( CanFitItem(innerLoopPos, uItemID) )
+        for (int ycoord = 0; ycoord < INVETORYSLOTSHEIGHT; ycoord++)
         {
-          return CreateItemInInventory(innerLoopPos, uItemID);
+          if ( CanFitItem(ycoord * INVETORYSLOTSWIDTH + xcoord, uItemID) )
+          {
+            return CreateItemInInventory(ycoord * INVETORYSLOTSWIDTH + xcoord, uItemID);
+          }
         }
-        innerLoopPos++;
       }
-      startOfInnerLoop += INVETORYSLOTSWIDTH;
-    }
     return 0;
   }
   if ( !CanFitItem(index, uItemID) )
@@ -935,24 +925,19 @@
 //----- (00492826) --------------------------------------------------------
 int Player::AddItem2(int index, ItemGen *Src)
 {
-  int xStartValue = 0;
   pItemsTable->SetSpecialBonus(Src);
-  int startOfInnerLoop = 0;
 
   if ( index == -1 )
   {
-    for (int ycoord = 0; ycoord < INVETORYSLOTSHEIGHT; ycoord++)      //TODO: change pInventoryMatrix to 2 dimensional array.
-    {
-      int innerLoopPos = startOfInnerLoop;
-      for (int xcoord = 0; xcoord < INVETORYSLOTSWIDTH; xcoord++)
+    for (int xcoord = 0; xcoord < INVETORYSLOTSWIDTH; xcoord++)
+    {
+      for (int ycoord = 0; ycoord < INVETORYSLOTSHEIGHT; ycoord++)      //TODO: change pInventoryMatrix to 2 dimensional array.
       {
-        if ( CanFitItem(innerLoopPos, Src->uItemID) )
+        if ( CanFitItem(ycoord * INVETORYSLOTSWIDTH + xcoord, Src->uItemID) )
         {
-          return CreateItemInInventory2(innerLoopPos, Src);
+          return CreateItemInInventory2(ycoord * INVETORYSLOTSWIDTH + xcoord, Src);
         }
-        innerLoopPos++;
       }
-      startOfInnerLoop += INVETORYSLOTSWIDTH;
     }
     return 0;
   }
@@ -1134,296 +1119,122 @@
 int Player::GetBodybuilding()
 {
   int v1; // al@1
-  int v2; // ecx@1
-  int v4; // eax@3
-  signed int v6; // [sp-4h] [bp-4h]@2
 
   v1 = GetActualSkillLevel(PLAYER_SKILL_BODYBUILDING);
-  v2 = v1 & 0x3F;
-  if ( v1 & 0x100 )
-  {
-    v6 = 5;
-  }
-  else
-  {
-    if ( (v1&0xFF) >= 0 )
-    {
-      v4 = ((v1 & 0x40) != 0) + 1;
-      return v2 * v4;
-    }
-    v6 = 3;
-  }
-  v4 = v6;
-  return v2 * v4;
+  int multiplier = GetMultiplierForSkillLevel(v1, 1, 2, 3, 5);
+  return multiplier * (v1 & 0x3F);
 }
 
 //----- (004910A8) --------------------------------------------------------
 int Player::GetMeditation()
 {
   int v1; // al@1
-  int base_level; // ecx@1
-  int v4; // eax@3
-  signed int v6; // [sp-4h] [bp-4h]@2
 
   v1 = GetActualSkillLevel(PLAYER_SKILL_MEDITATION);
-  base_level = v1 & 0x3F;
-  if ( v1 & 0x100 )
-  {
-    v6 = 5;
-  }
-  else
-  {
-    if ( (v1&0xFF) >= 0 )
-    {
-      v4 = ((v1 & 0x40) != 0) + 1;
-      return base_level * v4;
-    }
-    v6 = 3;
-  }
-  v4 = v6;
-  return base_level * v4;
+  int multiplier = GetMultiplierForSkillLevel(v1, 1, 2, 3, 5);
+  return multiplier * (v1 & 0x3F);
 }
 
 //----- (004910D3) --------------------------------------------------------
-int Player::CanIdentify(ItemGen *pItem)
+bool Player::CanIdentify( ItemGen *pItem )
 {
   unsigned __int16 v2; // ax@1
-  unsigned __int16 v3; // bx@1
-  int uSkillMult; // eax@3
   int v5; // edi@7
-  signed int v6; // ebp@7
-  char *v7; // esi@7
-  signed int uSkillMultiplier; // [sp-4h] [bp-14h]@2
 
   if (CheckHiredNPCSpeciality(Scholar))
     return true;
 
-  v2 = pPlayers[uActiveCharacter]->GetActualSkillLevel(PLAYER_SKILL_ITEM_ID);
-  v3 = v2;
-  if ( v2 & 1 )
-  {
-    uSkillMultiplier = 5;
-  }
-  else
-  {
-    if ( (v2 & 0x80u) == 0 )
-    {
-      uSkillMult = ((v2 & 0x40) != 0) + 1;
-      v5 = uSkillMult * (v3 & 0x3F);
-      v6 = 0;
-      v7 = (char *)&pItemsTable->pItems[pItem->uItemID].pIconName;
-
-      if ( (signed int)SkillToMastery(v3) >= 4 )
-        v6 = 1;
-      if ( v5 >= (unsigned __int8)v7[46] )
-        v6 = 1;
-      return v6;
-    }
-    uSkillMultiplier = 3;
-  }
-  uSkillMult = uSkillMultiplier;
-  v5 = uSkillMult * (v3 & 0x3F);
-  v6 = 0;
-  v7 = (char *)&pItemsTable->pItems[pItem->uItemID].pIconName;
-
-  if ( (signed int)SkillToMastery(v3) >= 4 )
-    v6 = 1;
-  if ( v5 >= (unsigned __int8)v7[46] )
-    v6 = 1;
-  return v6;
+  v2 = GetActualSkillLevel(PLAYER_SKILL_ITEM_ID);
+  if ( (signed int)SkillToMastery(v2) >= 4 )
+    return true;
+
+  int multiplier = GetMultiplierForSkillLevel(v2, 1, 2, 3, 5);
+  v5 = multiplier * (v2 & 0x3F);
+  return v5 >= pItemsTable->pItems[pItem->uItemID].uItemID_Rep_St;
 }
 
 //----- (00491151) --------------------------------------------------------
-int Player::CanRepair(ItemGen *a2)
+bool Player::CanRepair( ItemGen *pItem )
 {
   unsigned __int16 v2; // ax@1
-  unsigned __int16 v3; // bx@1
-  int v4; // eax@3
   int v5; // edi@7
-  signed int v6; // ebp@7
-  signed int v10; // [sp-4h] [bp-14h]@2
-
-  
-  auto v7 = &pItemsTable->pItems[a2->uItemID];
+
+  ItemDesc* v7 = &pItemsTable->pItems[pItem->uItemID];
   if (CheckHiredNPCSpeciality(Smith) && v7->uEquipType <= 2 ||
       CheckHiredNPCSpeciality(Armorer) && v7->uEquipType >= 3 && v7->uEquipType <= 9 ||
       CheckHiredNPCSpeciality(Alchemist) && v7->uEquipType >= 9 )
     return true;
 
   v2 = GetActualSkillLevel(PLAYER_SKILL_REPAIR);
-  v3 = v2;
-  if (v2 & 0x100 )
-  {
-    v10 = 5;
-  }
-  else
-  {
-    if ( (v2 & 0x80u) == 0 )
-    {
-      v4 = ((v2 & 0x40) != 0) + 1;
-      goto LABEL_7;
-    }
-    v10 = 3;
-  }
-  v4 = v10;
-LABEL_7:
-  v5 = v4 * (v3 & 0x3F);
-  v6 = 0;
-  if ( (signed int)SkillToMastery(v3) >= 4 )
+  if ( (signed int)SkillToMastery(v2) >= 4 )
     return true;
-  if ( v5 >= *((char *)(v7 + 1) + 2) )
-  {
-    __debugbreak(); // really odd
-    return true;
-  }
-  return false;
+
+  int multiplier = GetMultiplierForSkillLevel(v2, 1, 2, 3, 5);
+  v5 = multiplier * (v2 & 0x3F);
+  return v5 >= v7->uItemID_Rep_St;
 }
 
 //----- (004911F3) --------------------------------------------------------
 int Player::GetMerchant()
 {
-  Player *v1; // edi@1
   unsigned __int16 v2; // ax@1
-  unsigned __int16 v3; // bx@1
-  int v4; // esi@1
   int v5; // edi@1
   int v7; // eax@3
-  int v8; // ecx@7
-  signed int v9; // [sp-4h] [bp-10h]@6
-
-  v1 = this;
+
   v2 = GetActualSkillLevel(PLAYER_SKILL_MERCHANT);
-  v3 = v1->pActiveSkills[PLAYER_SKILL_MERCHANT];
-  v4 = v2 & 0x003F;
-  v5 = v1->pActiveSkills[PLAYER_SKILL_MERCHANT] & 0x3F;
-  if ( (signed int)SkillToMastery(v2) >= 4 )
+  if ( SkillToMastery(v2) >= 4 )
     return 10000;
+
   v7 = GetPartyReputation();
-  if ( !v4 )
+  int multiplier = GetMultiplierForSkillLevel(v2, 1, 2, 3, 5);
+  v5 = multiplier * (v2 & 0x3F);
+  if (v5 == 0)
+  {
     return -v7;
-  if ( v3 & 0x100 )
-  {
-    v9 = 5;
-  }
-  else
-  {
-    if ( (v3 & 0x80u) == 0 )
-    {
-      v8 = ((v3 & 0x40) != 0) + 1;
-      return v5 * (v8 - 1) - v7 + v4 + 7;
-    }
-    v9 = 3;
-  }
-  v8 = v9;
-  return v5 * (v8 - 1) - v7 + v4 + 7;
+  }
+  return v5 - v7 + 7;
 }
 
 //----- (0049125A) --------------------------------------------------------
 int Player::GetPerception()
 {
-  Player *v1; // edi@1
   unsigned __int16 v2; // ax@1
-  unsigned __int16 v3; // bx@1
-  int v4; // esi@1
   int v5; // edi@1
-  int v7; // eax@5
-  signed int v8; // [sp-4h] [bp-10h]@4
-
-  v1 = this;
+
   v2 = GetActualSkillLevel(PLAYER_SKILL_PERCEPTION);
-  v3 = v1->pActiveSkills[PLAYER_SKILL_PERCEPTION];
-  v4 = v2 & 0x3F;
-  v5 = v1->pActiveSkills[PLAYER_SKILL_PERCEPTION] & 0x3F;
-  if ( (signed int)SkillToMastery(v2) >= 4 )
+  if ( SkillToMastery(v2) >= 4 )
     return 10000;
-  if ( v3 & 0x100 )
-  {
-    v8 = 5;
-  }
-  else
-  {
-    if ( (v3 & 0x80u) == 0 )
-    {
-      v7 = ((v3 & 0x40) != 0) + 1;
-      return v4 + v5 * (v7 - 1);
-    }
-    v8 = 3;
-  }
-  v7 = v8;
-  return v4 + v5 * (v7 - 1);
+
+  int multiplier = GetMultiplierForSkillLevel(v2, 1, 2, 3, 5);
+  v5 = multiplier * (v2 & 0x3F);
+  return v5;
 }
 
 //----- (004912B0) --------------------------------------------------------
 int Player::GetDisarmTrap()
 {
-  Player *v1; // ebp@1
   unsigned __int16 v2; // ax@1
-  unsigned __int16 v3; // bx@1
-  int v4; // esi@1
   int v5; // edi@1
-  int v7; // eax@7
-  signed int v8; // [sp-4h] [bp-14h]@6
-
-  v1 = this;
+
   v2 = GetActualSkillLevel(PLAYER_SKILL_TRAP_DISARM);
-  v3 = v1->pActiveSkills[29];
-  v4 = v2 & 0x3F;
-  v5 = v1->pActiveSkills[29] & 0x3F;
   if ( (signed int)SkillToMastery(v2) >= 4 )
     return 10000;
-  if ( HasEnchantedItemEquipped(35) )
-    v4 *= 2;
-  if ( v3 & 0x100 )
-  {
-    v8 = 5;
-  }
-  else
-  {
-    if ( (v3 & 0x80u) == 0 )
-    {
-      v7 = ((v3 & 0x40) != 0) + 1;
-      return v4 + v5 * (v7 - 1);
-    }
-    v8 = 3;
-  }
-  v7 = v8;
-  return v4 + v5 * (v7 - 1);
+
+  int multiplier = GetMultiplierForSkillLevel(v2, 1, 2, 3, 5);
+  if ( HasEnchantedItemEquipped(35) )  //only the real skill level is supposed to be added again, not the multiplied value
+    multiplier++;
+  v5 = multiplier * (v2 & 0x3F);
+  return v5;
 }
 
 //----- (00491317) --------------------------------------------------------
 char Player::GetLearningPercent()
 {
-  Player *v1; // esi@1
   int v2; // eax@1
-  unsigned __int16 v3; // bx@1
-  int v4; // ecx@1
-  int v5; // eax@4
-  signed int v7; // [sp-4h] [bp-Ch]@3
-
-  v1 = this;
+
   v2 = GetActualSkillLevel(PLAYER_SKILL_LEARNING);
-  v3 = v1->pActiveSkills[36];
-  v4 = v2 & 0x3F;
-  if ( v2 )
-  {
-    if (v3 & 0x100 )
-    {
-      v7 = 5;
-    }
-    else
-    {
-      if ( (v3 & 0x80u) == 0 )
-      {
-        v5 = ((v3 & 0x40) != 0) + 1;
-        goto LABEL_8;
-      }
-      v7 = 3;
-    }
-    v5 = v7;
-LABEL_8:
-    v2 = (v1->pActiveSkills[36] & 0x3F) * (v5 - 1) + v4 + 9;
-  }
-  return v2;
+  int multiplier = GetMultiplierForSkillLevel(v2, 1, 2, 3, 5);
+  return multiplier * v2 + 9;
 }
 
 //----- (0048C6AF) --------------------------------------------------------
@@ -1687,37 +1498,37 @@
 //----- (0048C93C) --------------------------------------------------------
 int Player::GetActualMight()
 {
-  return GetActualAttribute(CHARACTER_ATTRIBUTE_STRENGTH);
+  return GetActualAttribute(CHARACTER_ATTRIBUTE_STRENGTH, &Player::uMight, &Player::uMightBonus);
 }
 
 //----- (0048C9C2) --------------------------------------------------------
 int Player::GetActualIntelligence()
 {
-  return GetActualAttribute(CHARACTER_ATTRIBUTE_INTELLIGENCE);
+  return GetActualAttribute(CHARACTER_ATTRIBUTE_INTELLIGENCE, &Player::uIntelligence, &Player::uIntelligenceBonus);
 }
 
 //----- (0048CA3F) --------------------------------------------------------
 int Player::GetActualWillpower()
 {
-  return GetActualAttribute(CHARACTER_ATTRIBUTE_WILLPOWER);
+  return GetActualAttribute(CHARACTER_ATTRIBUTE_WILLPOWER, &Player::uWillpower, &Player::uWillpowerBonus);
 }
 
 //----- (0048CABC) --------------------------------------------------------
 int Player::GetActualEndurance()
 {
-  return GetActualAttribute(CHARACTER_ATTRIBUTE_ENDURANCE);
+  return GetActualAttribute(CHARACTER_ATTRIBUTE_ENDURANCE, &Player::uEndurance, &Player::uEnduranceBonus);
 }
 
 //----- (0048CB39) --------------------------------------------------------
 int Player::GetActualAccuracy()
 {
-  return GetActualAttribute(CHARACTER_ATTRIBUTE_ACCURACY);
+  return GetActualAttribute(CHARACTER_ATTRIBUTE_ACCURACY, &Player::uAccuracy, &Player::uAccuracyBonus);
 }
 
 //----- (0048CBB6) --------------------------------------------------------
 int Player::GetActualSpeed()
 {
-  return GetActualAttribute(CHARACTER_ATTRIBUTE_SPEED);
+  return GetActualAttribute(CHARACTER_ATTRIBUTE_SPEED, &Player::uSpeed, &Player::uSpeedBonus);
 }
 
 //----- (0048CC33) --------------------------------------------------------
@@ -1733,49 +1544,13 @@
   if ( CheckHiredNPCSpeciality(Psychic) )
     npc_luck_bonus += 10;
 
-  return GetActualAttribute(CHARACTER_ATTRIBUTE_LUCK)
+  return GetActualAttribute(CHARACTER_ATTRIBUTE_LUCK, &Player::uLuck, &Player::uLuckBonus)
        + npc_luck_bonus;
 }
 
 //----- (new function) --------------------------------------------------------
-int Player::GetActualAttribute( CHARACTER_ATTRIBUTE_TYPE attrId )
-{
-  unsigned __int16 attrValue = 0;
-  unsigned __int16 attrBonus = 0;
-  switch (attrId)
-  {
-  case CHARACTER_ATTRIBUTE_STRENGTH:
-    attrValue = uMight;
-    attrBonus = uMightBonus;
-    break;
-  case CHARACTER_ATTRIBUTE_INTELLIGENCE:
-    attrValue = uIntelligence;
-    attrBonus = uIntelligenceBonus;
-    break;
-  case CHARACTER_ATTRIBUTE_WILLPOWER:
-    attrValue = uWillpower;
-    attrBonus = uWillpowerBonus;
-    break;
-  case CHARACTER_ATTRIBUTE_ENDURANCE:
-    attrValue = uEndurance;
-    attrBonus = uEnduranceBonus;
-    break;
-  case CHARACTER_ATTRIBUTE_ACCURACY:
-    attrValue = uAccuracy;
-    attrBonus = uAccuracyBonus;
-    break;
-  case CHARACTER_ATTRIBUTE_SPEED:
-    attrValue = uSpeed;
-    attrBonus = uSpeedBonus;
-    break;
-  case CHARACTER_ATTRIBUTE_LUCK:
-    attrValue = uLuck;
-    attrBonus = uLuckBonus;
-    break;
-  default:
-    return 0;
-  }
-
+int Player::GetActualAttribute( CHARACTER_ATTRIBUTE_TYPE attrId, unsigned short Player::* attrValue, unsigned short Player::* attrBonus )
+{
   uint uActualAge = this->sAgeModifier + GetBaseAge();
   uint uAgeingMultiplier = 100;
   for (uint i = 0; i < 4; ++i)
@@ -1789,10 +1564,10 @@
   auto uConditionMult = pConditionAttributeModifier[attrId][GetMajorConditionIdx()];
   int magicBonus = GetMagicalBonus(attrId);
   int itemBonus = GetItemsBonus(attrId, 0);
-  return uConditionMult * uAgeingMultiplier * attrValue / 100 / 100
+  return uConditionMult * uAgeingMultiplier * this->*attrValue / 100 / 100
     + magicBonus
-    + magicBonus
-    + attrBonus;
+    + itemBonus
+    + this->*attrBonus;
 }
 
 //----- (0048CCF5) --------------------------------------------------------
@@ -1858,208 +1633,101 @@
 }
 
 //----- (0048CDDB) --------------------------------------------------------
-int Player::CalculateMeleeDamageTo(int a2, int a3, unsigned int uTargetActorID)
-{
-  int v4; // esi@1
-  Player *v5; // edi@1
-  ItemGen *v6; // ebx@4
-  unsigned int v7; // ebp@4
-  unsigned int v8; // esi@4
-  int v9; // eax@4
-  int v10; // eax@9
-  char v11; // zf@9
-  int v12; // esi@10
-  int v13; // eax@11
-  enum MONSTER_SUPERTYPE v14; // edx@24
-  ItemGen *v15; // ebx@35
-  unsigned int v16; // ebp@35
-  unsigned int v17; // esi@35
-  int v18; // edx@38
-  int v19; // eax@40
-  enum MONSTER_SUPERTYPE v20; // edx@53
-  int v21; // esi@62
-  int v22; // eax@63
-  int v23; // ebx@63
-  int v24; // ebx@63
+int Player::CalculateMeleeDamageTo( bool ignoreSkillBonus, bool ignoreOffhand, unsigned int uTargetActorID )
+{
+  int dmgSum; // esi@62
   signed int result; // eax@64
-  MONSTER_SUPERTYPE v26; // [sp-4h] [bp-24h]@20
-  MONSTER_SUPERTYPE v27; // [sp-4h] [bp-24h]@49
-  int v28; // [sp+10h] [bp-10h]@1
-  int v29; // [sp+10h] [bp-10h]@33
-  signed int v30; // [sp+14h] [bp-Ch]@7
-  signed int v31; // [sp+14h] [bp-Ch]@36
-  int v32; // [sp+18h] [bp-8h]@1
-  int v33; // [sp+18h] [bp-8h]@8
-  int v34; // [sp+1Ch] [bp-4h]@1
-  int v35; // [sp+28h] [bp+8h]@37
-
-  v4 = 0;
-  v5 = this;
-  v34 = 0;
-  v32 = 0;
-  v28 = 0;
-  if ( IsUnarmed() == 1 )
-  {
-    v32 = rand() % 3 + 1;
-LABEL_61:
-    v34 = v4;
-    goto LABEL_62;
-  }
-  if ( HasItemEquipped(EQUIP_MAIN_HAND) )
-  {
-    v6 = (ItemGen *)&v5->pInventoryItemList[v5->pEquipment.uMainHand-1];
-    v7 = v6->uItemID;
-    v8 = v6->uItemID;
-    v9 = pItemsTable->pItems[v8].uDamageDice;
-    if ( pItemsTable->pItems[v8].uSkillType == PLAYER_SKILL_SPEAR && !v5->pEquipment.uShield )
-      ++v9;
-    v30 = pItemsTable->pItems[v8].uDamageRoll;
-    if ( v9 > 0 )
-    {
-      v33 = v9;
-      do
+  int mainWpnDmg; // [sp+18h] [bp-8h]@1
+  int offHndWpnDmg; // [sp+1Ch] [bp-4h]@1
+
+  offHndWpnDmg = 0;
+  mainWpnDmg = 0;
+  if ( IsUnarmed() )
+  {
+    mainWpnDmg = rand() % 3 + 1;
+  }
+  else
+  {
+    if ( HasItemEquipped(EQUIP_MAIN_HAND) )
+    {
+      ItemGen *mainHandItemGen = &this->pInventoryItemList[this->pEquipment.uMainHand-1];
+      int itemId = mainHandItemGen->uItemID;
+      bool addOneDice = false;
+      if ( pItemsTable->pItems[itemId].uSkillType == PLAYER_SKILL_SPEAR && !this->pEquipment.uShield )
+        addOneDice = true;
+      mainWpnDmg = CalculateMeleeDmgToEnemyWithWeapon(mainHandItemGen, uTargetActorID, addOneDice);
+    }
+    if ( !ignoreOffhand )
+    {
+      if ( this->HasItemEquipped(EQUIP_OFF_HAND) )
       {
-        v10 = rand();
-        v11 = v33-- == 1;
-        v28 += v10 % v30 + 1;
-      }
-      while ( !v11 );
-    }
-    v12 = pItemsTable->pItems[v8].uDamageMod + v28;
-    if ( !uTargetActorID )
-      goto LABEL_28;
-    v13 = v6->uSpecEnchantmentType;
-    if ( v13 == 64 || v7 == 507 || v7 == 508 || v7 == 527 )
-    {
-      v14 = (MONSTER_SUPERTYPE)1;
-    }
-    else
-    {
-      if ( v13 == 39 )
-      {
-        v26 = MONSTER_SUPERTYPE_KREEGAN;
-      }
-      else
-      {
-        if ( v13 == 40 )
+        ItemGen *offHandItemGen = (ItemGen *)&this->pInventoryItemList[this->pEquipment.uShield - 1];
+        int itemId = offHandItemGen->uItemID;
+        if ( pItemsTable->pItems[itemId].uEquipType != EQUIP_SHIELD )
         {
-          v26 = MONSTER_SUPERTYPE_DRAGON;
-        }
-        else
-        {
-          if ( v13 == 63 || v7 == 517 )
-          {
-            v26 = MONSTER_SUPERTYPE_ELF;
-          }
-          else
-          {
-            if ( v13 != 65 )
-            {
-LABEL_28:
-              if ( (signed int)SkillToMastery(v5->pActiveSkills[2]) >= 3
-                && pItemsTable->pItems[v6->uItemID].uSkillType == 2
-                && rand() % 100 < 10 )
-                v12 *= 3;
-              v32 = v12;
-              goto LABEL_33;
-            }
-            v26 = MONSTER_SUPERTYPE_TITAN;
-          }
+          offHndWpnDmg = CalculateMeleeDmgToEnemyWithWeapon(offHandItemGen, uTargetActorID, false);
         }
       }
-      v14 = v26;
-    }
-    if ( MonsterStats::BelongsToSupertype(uTargetActorID, v14) )
-      v12 *= 2;
-    goto LABEL_28;
-  }
-LABEL_33:
-  v29 = 0;
-  if ( !a3 )
-  {
-    if ( v5->HasItemEquipped((ITEM_EQUIP_TYPE)0) )
-    {
-      v15 = (ItemGen *)&v5->pInventoryItemList[v5->pEquipment.uShield - 1];
-      v16 = v15->uItemID;
-      v17 = v15->uItemID;
-      if ( pItemsTable->pItems[v17].uEquipType != 4 )
-      {
-        v31 = pItemsTable->pItems[v17].uDamageRoll;
-        if ( (signed int)pItemsTable->pItems[v17].uDamageDice > 0 )
-        {
-          v35 = pItemsTable->pItems[v17].uDamageDice;
-          do
-          {
-            v18 = rand() % v31;
-            v11 = v35-- == 1;
-            v29 += v18 + 1;
-          }
-          while ( !v11 );
-        }
-        v4 = pItemsTable->pItems[v17].uDamageMod + v29;
-        if ( !uTargetActorID )
-          goto LABEL_57;
-        v19 = v15->uSpecEnchantmentType;
-        if ( v19 == 64 || v16 == 507 || v16 == 508 || v16 == 527 )
-        {
-          v20 = (MONSTER_SUPERTYPE)1;
-        }
-        else
-        {
-          if ( v19 == 39 )
-          {
-            v27 = MONSTER_SUPERTYPE_KREEGAN;
-          }
-          else
-          {
-            if ( v19 == 40 )
-            {
-              v27 = MONSTER_SUPERTYPE_DRAGON;
-            }
-            else
-            {
-              if ( v19 == 63 || v16 == 517 )
-              {
-                v27 = MONSTER_SUPERTYPE_ELF;
-              }
-              else
-              {
-                if ( v19 != 65 )
-                {
-LABEL_57:
-                  if ( pItemsTable->pItems[v15->uItemID].uSkillType == PLAYER_SKILL_DAGGER
-                    && SkillToMastery(v5->pActiveSkills[2] >= 3u)
-                    && rand() % 100 < 10 )
-                    v4 *= 3;
-                  goto LABEL_61;
-                }
-                v27 = MONSTER_SUPERTYPE_TITAN;
-              }
-            }
-          }
-          v20 = v27;
-        }
-        if ( MonsterStats::BelongsToSupertype(uTargetActorID, v20) )
-          v4 *= 2;
-        goto LABEL_57;
-      }
-    }
-  }
-LABEL_62:
-  v21 = v32 + v34;
-  if ( !a2 )
-  {
-    v22 = GetActualMight();
-    v23 = GetParameterBonus(v22);
-    v24 = GetSkillBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS) + v23;
-    v21 += v5->_melee_dmg_bonus + GetMagicalBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS) + v24;
+    }
+  }
+  dmgSum = mainWpnDmg + offHndWpnDmg;
+  if ( !ignoreSkillBonus )
+  {
+    int might = GetActualMight();
+    int mightBonus = GetParameterBonus(might);
+    int mightAndSkillbonus = GetSkillBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS) + mightBonus;
+    dmgSum += this->_melee_dmg_bonus + GetMagicalBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS) + mightAndSkillbonus;
   }
   result = 1;
-  if ( v21 >= 1 )
-    result = v21;
+  if ( dmgSum >= 1 )
+    result = dmgSum;
   return result;
 }
 
+
+int Player::CalculateMeleeDmgToEnemyWithWeapon( ItemGen * weapon, unsigned int uTargetActorID , bool addOneDice )
+{
+  int itemId = weapon->uItemID;
+  int diceCount = pItemsTable->pItems[itemId].uDamageDice;
+  if (addOneDice)
+  {
+    diceCount++;
+  }
+  int diceSides = pItemsTable->pItems[itemId].uDamageRoll;
+  int diceResult = 0;
+  for (int i = 0; i < diceCount; i++)
+  {
+    diceResult += rand() % diceSides + 1;
+  }
+  int totalDmg = pItemsTable->pItems[itemId].uDamageMod + diceResult;
+  if ( uTargetActorID > 0)
+  {
+    int enchType = weapon->uSpecEnchantmentType;
+    if ( MonsterStats::BelongsToSupertype(uTargetActorID, MONSTER_SUPERTYPE_UNDEAD) && (enchType == 64 || itemId == ITEM_ARTIFACT_GHOULSBANE || itemId == ITEM_ARTIFACT_GIBBET || itemId == ITEM_RELIC_JUSTICE) )
+    {
+      totalDmg *= 2;
+    }
+    else if (MonsterStats::BelongsToSupertype(uTargetActorID, MONSTER_SUPERTYPE_KREEGAN) && ( enchType == 39 || itemId == ITEM_ARTIFACT_GIBBET))
+    {
+      totalDmg *= 2;
+    }
+    else if (MonsterStats::BelongsToSupertype(uTargetActorID, MONSTER_SUPERTYPE_DRAGON) && ( enchType == 40 || itemId == ITEM_ARTIFACT_GIBBET))
+    {
+      totalDmg *= 2;
+    }
+    else if (MonsterStats::BelongsToSupertype(uTargetActorID, MONSTER_SUPERTYPE_TITAN) && ( enchType == 65 ))
+    {
+      totalDmg *= 2;
+    }
+  }
+  if ( (signed int)SkillToMastery(this->pActiveSkills[2]) >= 3
+    && pItemsTable->pItems[itemId].uSkillType == 2
+    && rand() % 100 < 10 )
+    totalDmg *= 3;
+  return totalDmg;
+}
+
+
 //----- (0048D0B9) --------------------------------------------------------
 int Player::GetRangedAttack()
 {
@@ -2073,7 +1741,7 @@
 
   v1 = this;
   v2 = *(int *)&this->pInventoryItemList[this->pEquipment.uMainHand-1];
-  if ( v2 < 64 || v2 > 65 )
+  if ( v2 < ITEM_BLASTER || v2 > ITEM_LASER_RIFLE )
   {
     v4 = GetActualAccuracy();
     v5 = GetParameterBonus(v4);
@@ -2131,84 +1799,51 @@
 }
 
 //----- (0048D1FE) --------------------------------------------------------
-bool Player::CalculateRangedDamageTo(int a2)
-{
-  Player *v2; // ebx@1
+int Player::CalculateRangedDamageTo( int a2 )
+{
   bool result; // eax@1
   ItemGen *v4; // ebx@2
   unsigned int v5; // edi@2
-  unsigned int v6; // esi@2
   int v7; // edx@4
   char v8; // zf@4
   int v9; // esi@5
   int v10; // ebx@6
-  enum MONSTER_SUPERTYPE v11; // edx@7
-  unsigned __int16 v12; // ax@19
-  MONSTER_SUPERTYPE v13; // [sp-Ch] [bp-20h]@13
-  Player *v14; // [sp+4h] [bp-10h]@1
   signed int v15; // [sp+8h] [bp-Ch]@2
-  int v16; // [sp+Ch] [bp-8h]@3
   int v17; // [sp+10h] [bp-4h]@1
 
   v17 = 0;
-  v2 = this;
-  v14 = this;
-  result = HasItemEquipped(EQUIP_BOW);
-  if ( !result )
-    return result;
-  v4 = (ItemGen *)&v2->pInventoryItemList[v2->pEquipment.uBow-1];
+  if ( !HasItemEquipped(EQUIP_BOW) )
+    return 0;
+  v4 = (ItemGen *)&this->pInventoryItemList[this->pEquipment.uBow-1];
   v5 = v4->uItemID;
-  v6 = v4->uItemID;
-  v15 = pItemsTable->pItems[v6].uDamageRoll;
-  if ( (signed int)pItemsTable->pItems[v6].uDamageDice > 0 )
-  {
-    v16 = pItemsTable->pItems[v6].uDamageDice;
-    do
-    {
-      v7 = rand() % v15;
-      v8 = v16-- == 1;
-      v17 += v7 + 1;
-    }
-    while ( !v8 );
-  }
-  v9 = pItemsTable->pItems[v6].uDamageMod + v17;
+  v15 = pItemsTable->pItems[v5].uDamageRoll;
+  for( int i = 0; i < pItemsTable->pItems[v5].uDamageDice; i++ )
+  {
+    int v7 = rand() % v15;
+    v17 += v7 + 1;
+  }
+  v9 = pItemsTable->pItems[v5].uDamageMod + v17;
   if ( a2 )
   {
     v10 = v4->uSpecEnchantmentType;
-    if ( v10 == 64 )
-    {
-      v11 = (MONSTER_SUPERTYPE)1;
-      goto LABEL_17;
-    }
-    if ( v10 == 39 || v5 == 508 )
-    {
-      v13 = MONSTER_SUPERTYPE_KREEGAN;
-      goto LABEL_16;
-    }
-    if ( v10 == 40 )
-    {
-      v13 = MONSTER_SUPERTYPE_DRAGON;
-      goto LABEL_16;
-    }
-    if ( v10 == 63 || v5 == 517 )
-    {
-      v13 = MONSTER_SUPERTYPE_ELF;
-LABEL_16:
-      v11 = v13;
-LABEL_17:
-      if ( MonsterStats::BelongsToSupertype(a2, v11) )
-        v9 *= 2;
-      goto LABEL_19;
-    }
-  }
-LABEL_19:
-  v12 = v14->pActiveSkills[5];
-  if ( v12 )
-  {
-    if ( (signed int)SkillToMastery(v12) >= 4 )
-      v9 += v14->pActiveSkills[5] & 0x3F;
-  }
-  return v9;
+    if ( v10 == 64 && MonsterStats::BelongsToSupertype(a2, MONSTER_SUPERTYPE_UNDEAD))
+    {
+      v9 *= 2;
+    }
+    else if ( v10 == 39 && MonsterStats::BelongsToSupertype(a2, MONSTER_SUPERTYPE_KREEGAN))
+    {
+      v9 *= 2;
+    }
+    else if ( v10 == 40 && MonsterStats::BelongsToSupertype(a2, MONSTER_SUPERTYPE_DRAGON))
+    {
+      v9 *= 2;
+    }
+    else if ( v10 == 63 && MonsterStats::BelongsToSupertype(a2, MONSTER_SUPERTYPE_ELF))
+    {
+      v9 *= 2;
+    }
+  }
+  return v9 + this->GetSkillBonus(CHARACTER_ATTRIBUTE_RANGED_DMG_BONUS);
 }
 
 //----- (0048D2EA) --------------------------------------------------------
@@ -2223,7 +1858,7 @@
   if ( pEquipment.uMainHand)
       {
       itemid= pOwnItems[this->pEquipment.uMainHand-1].uItemID;
-      if ( itemid < 64 || itemid > 65 ) //blasters
+      if ( itemid < ITEM_BLASTER || itemid > ITEM_LASER_RIFLE ) //blasters
           {
           min_damage = GetMeleeDamageMinimal();
           max_damage = GetMeleeDamageMaximal();
@@ -2267,44 +1902,44 @@
     int max_damage; // eax@3
 
     static char player__getrangeddamagestring_static_buff[40]; // idb
-    if ( pEquipment.uMainHand)
-        {
-        itemid= pOwnItems[this->pEquipment.uMainHand-1].uItemID;
-        if ( itemid < 64 || itemid > 65 ) //blasters
-            {
-            min_damage = GetRangedDamageMin();
-            max_damage = GetRangedDamageMax();
-            }
-        else
-            {  //for blasters
-            min_damage = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MIN, 1);
-            max_damage = GetItemsBonus(CHARACTER_ATTRIBUTE_MELEE_DMG_MAX, 1);
-            }
-        if ( max_damage )
-            {
-            if ( min_damage == max_damage )
-                {
-                sprintf(player__getrangeddamagestring_static_buff, "%d", min_damage);
-                }
-            else
-                {
-                sprintf(player__getrangeddamagestring_static_buff, "%d - %d", min_damage, max_damage);
-                }
-            }
-        else
-            {
-            strcpy(player__getrangeddamagestring_static_buff, "N/A");
-            }
-
-        if (( itemid >= 135 )&&( itemid <= 159 )) //wands
-            {
-            strcpy(player__getrangeddamagestring_static_buff, pGlobalTXT_LocalizationStrings[595]); //"Wand"
-            }
-        }
+
+    if (pEquipment.uMainHand >= 0)
+    {
+      itemid = pOwnItems[this->pEquipment.uMainHand-1].uItemID;
+    }
+
+    if (pEquipment.uMainHand >= 0 && ( itemid >= 135 ) && ( itemid <= 159 ))
+    {
+      strcpy(player__getrangeddamagestring_static_buff, pGlobalTXT_LocalizationStrings[595]); //"Wand"
+      return player__getrangeddamagestring_static_buff;
+    }
+    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);
+    }
     else
-        strcpy(player__getrangeddamagestring_static_buff, "N/A");
+    {
+      min_damage = GetRangedDamageMin();
+      max_damage = GetRangedDamageMax();
+    }
+    if ( max_damage > 0)
+    {
+      if ( min_damage == max_damage )
+      {
+        sprintf(player__getrangeddamagestring_static_buff, "%d", min_damage);
+      }
+      else
+      {
+        sprintf(player__getrangeddamagestring_static_buff, "%d - %d", min_damage, max_damage);
+      }
+    }
+    else
+    {
+      strcpy(player__getrangeddamagestring_static_buff, "N/A");
+    }
     return player__getrangeddamagestring_static_buff;
-    }
+}
 
 //----- (0048D45A) --------------------------------------------------------
 bool Player::CanTrainToNextLevel()
@@ -4804,11 +4439,11 @@
     int multiplier = 0;
     if ( inSkill == CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS )
     {
-      multiplier = GetMultiplierForMastery(armmaster_skill, 0, 0, 1, 2);
+      multiplier = GetMultiplierForSkillLevel(armmaster_skill, 0, 0, 1, 2);
     }
     else if ( inSkill == CHARACTER_ATTRIBUTE_ATTACK )
     {
-      multiplier = GetMultiplierForMastery(armmaster_skill, 0, 1, 1, 2);
+      multiplier = GetMultiplierForSkillLevel(armmaster_skill, 0, 1, 1, 2);
     } 
     armsMasterBonus = multiplier * (armmaster_skill & 0x3F);
   }
@@ -4819,7 +4454,7 @@
     if (HasItemEquipped(EQUIP_BOW))
     {
       int bowSkillLevel = GetActualSkillLevel(PLAYER_SKILL_DODGE);
-      int multiplier = GetMultiplierForMastery(bowSkillLevel, 0, 0, 0, 1);
+      int multiplier = GetMultiplierForSkillLevel(bowSkillLevel, 0, 0, 0, 1);
       return multiplier * (bowSkillLevel & 0x3F);
     }
     return 0;
@@ -4848,34 +4483,34 @@
       {
         if (pEquipment.pIndices[j] && (!pOwnItems[pEquipment.pIndices[j]].Broken()))
         {
-          int curr_item = pOwnItems[pEquipment.pIndices[j]].uItemID;
+          int curr_item = pOwnItems[pEquipment.pIndices[j] - 1].uItemID;
           PLAYER_SKILL_TYPE itemSkillType = (PLAYER_SKILL_TYPE)pItemsTable->pItems[curr_item].uSkillType;
           int currArmorSkillLevel = GetActualSkillLevel(itemSkillType);
           int multiplier = 0;
           switch (itemSkillType)
           {
           case PLAYER_SKILL_STAFF:
-            multiplier = GetMultiplierForMastery(currArmorSkillLevel, 0, 1, 1, 1);
+            multiplier = GetMultiplierForSkillLevel(currArmorSkillLevel, 0, 1, 1, 1);
             break;
           case PLAYER_SKILL_SWORD:
           case PLAYER_SKILL_SPEAR:
-            multiplier = GetMultiplierForMastery(currArmorSkillLevel, 0, 0, 0, 1);
+            multiplier = GetMultiplierForSkillLevel(currArmorSkillLevel, 0, 0, 0, 1);
             break;
           case PLAYER_SKILL_SHIELD:
             wearingArmor = true;
-            multiplier = GetMultiplierForMastery(currArmorSkillLevel, 1, 1, 2, 2);
+            multiplier = GetMultiplierForSkillLevel(currArmorSkillLevel, 1, 1, 2, 2);
             break;
           case PLAYER_SKILL_LEATHER:
             wearingLeather = true;
-            multiplier = GetMultiplierForMastery(currArmorSkillLevel, 1, 1, 2, 2);
+            multiplier = GetMultiplierForSkillLevel(currArmorSkillLevel, 1, 1, 2, 2);
             break;
           case PLAYER_SKILL_CHAIN:
             wearingArmor = true;
-            multiplier = GetMultiplierForMastery(currArmorSkillLevel, 1, 1, 1, 1);
+            multiplier = GetMultiplierForSkillLevel(currArmorSkillLevel, 1, 1, 1, 1);
             break;
           case PLAYER_SKILL_PLATE:
             wearingArmor = true; 
-            multiplier = GetMultiplierForMastery(currArmorSkillLevel, 1, 1, 1, 1);
+            multiplier = GetMultiplierForSkillLevel(currArmorSkillLevel, 1, 1, 1, 1);
             break;
           }
           ACSum += multiplier * (currArmorSkillLevel & 0x3F);
@@ -4884,7 +4519,7 @@
 
       int dodgeSkillLevel = GetActualSkillLevel(PLAYER_SKILL_DODGE);
       int dodgeMastery = SkillToMastery(dodgeSkillLevel);
-      int multiplier = GetMultiplierForMastery(dodgeSkillLevel, 1, 2, 3, 3);
+      int multiplier = GetMultiplierForSkillLevel(dodgeSkillLevel, 1, 2, 3, 3);
       if ( !wearingArmor && (!wearingLeather || dodgeMastery == 4) )
       {
         ACSum += multiplier * (dodgeSkillLevel & 0x3F);
@@ -4900,27 +4535,27 @@
       {
         return 0;
       }
-      int multiplier = GetMultiplierForMastery(unarmedSkill, 0, 1, 2, 2);
+      int multiplier = GetMultiplierForSkillLevel(unarmedSkill, 0, 1, 2, 2);
       return armsMasterBonus + multiplier * (unarmedSkill & 0x3F);
     }
     for (int i = 0; i < 16; ++i)
     {
       if ( this->HasItemEquipped((ITEM_EQUIP_TYPE)i) )
       {
-        int currItemIndex = this->pEquipment.pIndices[i] - 1;
-        if ( pItemsTable->pItems[currItemIndex].uEquipType <= EQUIP_MAIN_HAND)
+        ItemDesc currItem = pItemsTable->pItems[this->pInventoryItemList[this->pEquipment.pIndices[i] - 1].uItemID];
+        if ( currItem.uEquipType <= EQUIP_MAIN_HAND)
         {
-          PLAYER_SKILL_TYPE currItemSkillType = (PLAYER_SKILL_TYPE)pItemsTable->pItems[currItemIndex].uSkillType;
+          PLAYER_SKILL_TYPE currItemSkillType = (PLAYER_SKILL_TYPE)currItem.uSkillType;
           int currentItemSkillLevel = this->GetActualSkillLevel(currItemSkillType);
           if (currItemSkillType == PLAYER_SKILL_BLASTER)
           {
-            int multiplier = GetMultiplierForMastery(currentItemSkillLevel, 1, 2, 3, 5);
+            int multiplier = GetMultiplierForSkillLevel(currentItemSkillLevel, 1, 2, 3, 5);
             return multiplier * (currentItemSkillLevel & 0x3F);
           }
           else if (currItemSkillType == PLAYER_SKILL_STAFF && this->GetActualSkillLevel(PLAYER_SKILL_UNARMED) > 0)
           {
             int unarmedSkillLevel = this->GetActualSkillLevel(PLAYER_SKILL_UNARMED);
-            int multiplier = GetMultiplierForMastery(currentItemSkillLevel, 1, 1, 2, 2);
+            int multiplier = GetMultiplierForSkillLevel(currentItemSkillLevel, 1, 1, 2, 2);
             return multiplier * (unarmedSkillLevel & 0x3F) + armsMasterBonus + (currentItemSkillLevel & 0x3F);
           }
           else
@@ -4942,12 +4577,12 @@
         int currentItemSkillLevel = this->GetActualSkillLevel(currentItemSkillType);
         if ( currentItemSkillType == PLAYER_SKILL_BOW )
         {
-          int multiplier = GetMultiplierForMastery(currentItemSkillLevel, 0, 0, 0, 0);
+          int multiplier = GetMultiplierForSkillLevel(currentItemSkillLevel, 1, 1, 1, 1);
           return multiplier * (currentItemSkillLevel & 0x3F);
         }
         else if ( currentItemSkillType == PLAYER_SKILL_BLASTER )
         {      
-          int multiplier = GetMultiplierForMastery(currentItemSkillLevel, 1, 2, 3, 5);
+          int multiplier = GetMultiplierForSkillLevel(currentItemSkillLevel, 1, 2, 3, 5);
           return multiplier * (currentItemSkillLevel & 0x3F);
         }
       }
@@ -4963,7 +4598,7 @@
       {
         return 0;
       }
-      int multiplier = GetMultiplierForMastery(unarmedSkillLevel, 0, 1, 2, 2);
+      int multiplier = GetMultiplierForSkillLevel(unarmedSkillLevel, 0, 1, 2, 2);
       return multiplier * (unarmedSkillLevel & 0x3F);
     }
     for (int i = 0; i < 16; i++)
@@ -4983,7 +4618,7 @@
             if ( SkillToMastery(currItemSkillLevel) >= 4 && this->GetActualSkillLevel(PLAYER_SKILL_UNARMED) > 0)
             {
               int unarmedSkillLevel = this->GetActualSkillLevel(PLAYER_SKILL_UNARMED);
-              int multiplier = GetMultiplierForMastery(unarmedSkillLevel, 0, 1, 2, 2);
+              int multiplier = GetMultiplierForSkillLevel(unarmedSkillLevel, 0, 1, 2, 2);
               return multiplier * (unarmedSkillLevel & 0x3F);
             }
             else
@@ -4993,23 +4628,23 @@
             break;
 
           case PLAYER_SKILL_DAGGER:
-            multiplier = GetMultiplierForMastery(currItemSkillLevel, 0, 0, 0, 1);
+            multiplier = GetMultiplierForSkillLevel(currItemSkillLevel, 0, 0, 0, 1);
             baseSkillBonus = multiplier * (currItemSkillLevel & 0x3F);
             return armsMasterBonus + baseSkillBonus;
             break;
           case PLAYER_SKILL_SWORD:
-            multiplier = GetMultiplierForMastery(currItemSkillLevel, 0, 0, 0, 0);
+            multiplier = GetMultiplierForSkillLevel(currItemSkillLevel, 0, 0, 0, 0);
             baseSkillBonus = multiplier * (currItemSkillLevel & 0x3F);
             return armsMasterBonus + baseSkillBonus;
             break;
           case PLAYER_SKILL_MACE:
           case PLAYER_SKILL_SPEAR:
-            multiplier = GetMultiplierForMastery(currItemSkillLevel, 0, 1, 1, 1);
+            multiplier = GetMultiplierForSkillLevel(currItemSkillLevel, 0, 1, 1, 1);
             baseSkillBonus = multiplier * (currItemSkillLevel & 0x3F);
             return armsMasterBonus + baseSkillBonus;
             break;
           case PLAYER_SKILL_AXE:
-            multiplier = GetMultiplierForMastery(currItemSkillLevel, 0, 0, 1, 1);
+            multiplier = GetMultiplierForSkillLevel(currItemSkillLevel, 0, 0, 1, 1);
             baseSkillBonus = multiplier * (currItemSkillLevel & 0x3F);
             return armsMasterBonus + baseSkillBonus;
             break;
@@ -5024,7 +4659,7 @@
   }
 }
 
-unsigned int Player::GetMultiplierForMastery(unsigned int skillValue, int mult1, int mult2, int mult3, int mult4)
+unsigned int Player::GetMultiplierForSkillLevel(unsigned int skillValue, int mult1, int mult2, int mult3, int mult4)
 {
   int masteryLvl = SkillToMastery(skillValue);
   switch (masteryLvl)
@@ -5367,7 +5002,7 @@
     }
   }
 
-  Error("(%u)", order);
+  return (PLAYER_SKILL_TYPE)37;
 }
 
 
--- a/Player.h	Sat Sep 07 22:38:53 2013 +0200
+++ b/Player.h	Sat Sep 07 22:46:18 2013 +0200
@@ -463,7 +463,7 @@
   bool CompareVariable(enum VariableType VarNum, signed int pValue);
   void UseItem_DrinkPotion_etc(signed int a2, int a3);
   bool AddItem(struct ItemGen *pItem);
-  int GetActualAttribute(CHARACTER_ATTRIBUTE_TYPE attrId);
+  int GetActualAttribute(CHARACTER_ATTRIBUTE_TYPE attrId, unsigned short Player::* attrValue, unsigned short Player::* attrBonus);
   int GetBaseStrength();
   int GetBaseIntelligence();
   int GetBaseWillpower();
@@ -483,11 +483,11 @@
   int GetActualAttack(int a2);
   int GetMeleeDamageMinimal();
   int GetMeleeDamageMaximal();
-  int CalculateMeleeDamageTo(int a2, int a3, unsigned int uTargetActorID);
+  int CalculateMeleeDamageTo(bool ignoreSkillBonus, bool ignoreOffhand, unsigned int uTargetActorID);
   int GetRangedAttack();
   int GetRangedDamageMin();
   int GetRangedDamageMax();
-  bool CalculateRangedDamageTo(int a2);
+  int CalculateRangedDamageTo(int a2);
   char *GetMeleeDamageString();
   char *GetRangedDamageString();
   bool CanTrainToNextLevel();
@@ -537,8 +537,8 @@
   int SelectPhrasesTransaction(ItemGen *pItem, int building_type, int BuildID_2Events, int a5);
   int GetBodybuilding();
   int GetMeditation();
-  int CanIdentify(ItemGen *pItem);
-  int CanRepair(ItemGen *);
+  bool CanIdentify(ItemGen *pItem);
+  bool CanRepair(ItemGen *pItem);
   int GetMerchant();
   int GetPerception();
   int GetDisarmTrap();
@@ -581,6 +581,9 @@
   void DrawPlayerBuffAnimBasedOnCondition(int currPlayerId);
   void EquipBody(ITEM_EQUIP_TYPE uEquipType);
 
+  unsigned int GetMultiplierForSkillLevel(unsigned int skillValue, int mult1, int mult2, int mult3, int mult4);
+  int CalculateMeleeDmgToEnemyWithWeapon( ItemGen * weapon, unsigned int uTargetActorID , bool addOneDice);
+
   bool IsWeak();
   bool IsDead();
   bool IsEradicated();
@@ -621,7 +624,6 @@
 
   inline bool IsMale() { return GetSexByVoice() == SEX_MALE;}
   inline bool IsFemale() { return !IsMale();}
-  unsigned int GetMultiplierForMastery(unsigned int skillValue, int mult1, int mult2, int mult3, int mult4);
   __int64 pConditions[20];
   unsigned __int64 uExperience;
   char pName[16];