changeset 1540:6e4980797714

Merge
author Grumpy7
date Sat, 07 Sep 2013 05:23:16 +0200
parents 5cf28ec7322d (diff) 3c33f3e44f71 (current diff)
children 7d986a396092 778916dfa666
files
diffstat 2 files changed, 224 insertions(+), 432 deletions(-) [+]
line wrap: on
line diff
--- a/Player.cpp	Fri Sep 06 16:32:08 2013 +0200
+++ b/Player.cpp	Sat Sep 07 05:23:16 2013 +0200
@@ -2108,9 +2108,6 @@
   v2 = GetItemsBonus(CHARACTER_ATTRIBUTE_RANGED_DMG_MIN, 0);
   v3 = GetSkillBonus(CHARACTER_ATTRIBUTE_RANGED_DMG_BONUS) + v2;
   v4 = v1->_ranged_dmg_bonus + GetMagicalBonus(CHARACTER_ATTRIBUTE_RANGED_DMG_BONUS) + v3;
-  v5 = v1->pActiveSkills[5];
-  if ( v5 && (signed int)SkillToMastery(v5) >= 4 && HasItemEquipped(EQUIP_BOW) )
-    v4 += v1->pActiveSkills[5] & 0x3F;
   if ( v4 >= 1 )
     result = v4;
   else
@@ -2132,9 +2129,6 @@
   v2 = GetItemsBonus(CHARACTER_ATTRIBUTE_RANGED_DMG_MAX, 0);
   v3 = GetSkillBonus(CHARACTER_ATTRIBUTE_RANGED_DMG_BONUS) + v2;
   v4 = v1->_ranged_dmg_bonus + GetMagicalBonus(CHARACTER_ATTRIBUTE_RANGED_DMG_BONUS) + v3;
-  v5 = v1->pActiveSkills[5];
-  if ( v5 && (signed int)SkillToMastery(v5) >= 4 && HasItemEquipped(EQUIP_BOW) )
-    v4 += v1->pActiveSkills[5] & 0x3F;
   if ( v4 >= 1 )
     result = v4;
   else
@@ -4803,455 +4797,252 @@
   return result;
 }
 
+
 //----- (0048FC00) --------------------------------------------------------
-int Player::GetSkillBonus(enum CHARACTER_ATTRIBUTE_TYPE a2)
-{
- 
-
-
-  Player *v2; // esi@1
-  int armmaster_skill; // eax@1
-  char v4; // di@1
-  signed int v5; // ebx@1
-  unsigned int armaster_mastery; // eax@2
-  unsigned __int8 v7; // sf@5
-  unsigned __int8 v8; // of@5
-  PlayerEquipment *v9; // ebx@19
-  Player *v10; // ecx@20
-  PLAYER_SKILL_TYPE v11; // edi@21
-  int v12; // eax@21
-  int v13; // edi@21
-  char v14; // di@25
-  signed int v15; // esi@25
-  char v16; // al@32
-  int v18; // eax@36
-  unsigned int v19; // eax@37
-  ITEM_EQUIP_TYPE v20; // edi@40
-  int v21; // edx@41
-  int v22; // eax@42
-  PLAYER_SKILL_TYPE v23; // edi@45
-  unsigned __int16 v24; // ax@45
-  unsigned __int16 v25; // bx@45
-  unsigned int v26; // eax@45
-  unsigned __int8 v27; // sf@50
-  unsigned __int8 v28; // of@50
-  unsigned int v29; // eax@52
-  int v30; // eax@55
-  int v31; // eax@58
-  unsigned int v32; // eax@59
-  int v33; // eax@65
-  char v34; // si@65
-  ITEM_EQUIP_TYPE v35; // edi@69
-  int v36; // edx@70
-  int v37; // eax@71
-  PLAYER_SKILL_TYPE v38; // edi@74
-  int v39; // eax@74
-  int v40; // eax@89
-  char v41; // si@89
-  int v42; // eax@96
-  PLAYER_SKILL_TYPE v43; // edx@97
-  int v44; // eax@97
-  int v45; // eax@98
-  int v46; // eax@99
-  int v47; // eax@100
-  int v48; // eax@101
-  int v49; // eax@102
-  unsigned __int16 v50; // ax@113
-  char v51; // di@113
-  unsigned int v52; // eax@113
-  int v53; // edi@113
-  signed int i; // ecx@113
-  unsigned __int16 v55; // ax@118
-  char v56; // si@118
-  unsigned int v57; // eax@118
-  int v58; // esi@121
-  signed int j; // ecx@121
-  int base_value; // edi@126
-  int attrib_modif; // eax@126
-  signed int v62; // [sp-4h] [bp-30h]@26
-  signed int v63; // [sp-4h] [bp-30h]@80
-  int v64; // [sp+Ch] [bp-20h]@104
-  int v65; // [sp+10h] [bp-1Ch]@104
-  int v66; // [sp+14h] [bp-18h]@104
-  int v67; // [sp+18h] [bp-14h]@104
-  int v68; // [sp+1Ch] [bp-10h]@69
-  PlayerEquipment *v69; // [sp+20h] [bp-Ch]@1
-  int skill_bonus; // [sp+24h] [bp-8h]@1
-  ITEM_EQUIP_TYPE v71; // [sp+28h] [bp-4h]@1
-  int a1; // [sp+34h] [bp+8h]@21
-  int a1a; // [sp+34h] [bp+8h]@74
-  signed int a1b; // [sp+34h] [bp+8h]@94
-  int multiplier;
-  int arm_bonus;
-  int lvl_avl[4];
-
-  v2 = this;
-  skill_bonus = 0;
-  v69 = 0;
-  multiplier =0;
-  arm_bonus =0;
-  v71 = (ITEM_EQUIP_TYPE)0;
-  armmaster_skill = GetActualSkillLevel(PLAYER_SKILL_ARMSMASTER);
-  v4 = armmaster_skill;
-  v5 = 1;
-  if ( armmaster_skill )
-  {
-    armaster_mastery = SkillToMastery(armmaster_skill);
-    if ( a2 == CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS )
-    {
-      if ( armaster_mastery == 4 )
-          multiplier =2;
-      else if ( armaster_mastery == 3 )
-          multiplier =1;
-    }
-    else if ( a2 == CHARACTER_ATTRIBUTE_ATTACK )
-    {
-    if ( armaster_mastery == 4 )
-        multiplier =2;
-    else if ( armaster_mastery >= 2 )
-        multiplier =1;
+int Player::GetSkillBonus(enum CHARACTER_ATTRIBUTE_TYPE inSkill)    //TODO: move the individual implementations to attribute classes once possible
+{
+  int armsMasterBonus;
+
+  armsMasterBonus = 0;
+  int armmaster_skill = GetActualSkillLevel(PLAYER_SKILL_ARMSMASTER);
+  if ( armmaster_skill > 0 )
+  {
+    int multiplier = 0;
+    if ( inSkill == CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS )
+    {
+      multiplier = GetMultiplierForMastery(armmaster_skill, 0, 0, 1, 2);
+    }
+    else if ( inSkill == CHARACTER_ATTRIBUTE_ATTACK )
+    {
+      multiplier = GetMultiplierForMastery(armmaster_skill, 0, 1, 1, 2);
     } 
-    arm_bonus=(armmaster_skill&0x3F)*multiplier;
-  }
- 
-  
-  if ( a2 == CHARACTER_ATTRIBUTE_HEALTH )
-  {
-    base_value = pBaseHealthPerLevelByClass[classType];
-    attrib_modif = GetBodybuilding();
-    return base_value * attrib_modif;
-  }
-  if ( a2 == CHARACTER_ATTRIBUTE_MANA )
-  {
-    base_value = pBaseManaPerLevelByClass[classType];
-    attrib_modif = GetMeditation();
-    return base_value * attrib_modif;
-  }
-  if ( a2 == CHARACTER_ATTRIBUTE_AC_BONUS )
-      {
-      a1b = 0;
-      v71 = (ITEM_EQUIP_TYPE)0;
-     
-      for (j=0; j<16; ++j) 
+    armsMasterBonus = multiplier * (armmaster_skill & 0x3F);
+  }
+
+  switch(inSkill)
+  {
+  case CHARACTER_ATTRIBUTE_RANGED_DMG_BONUS:
+    if (HasItemEquipped(EQUIP_BOW))
+    {
+      int bowSkillLevel = GetActualSkillLevel(PLAYER_SKILL_DODGE);
+      int multiplier = GetMultiplierForMastery(bowSkillLevel, 0, 0, 0, 1);
+      return multiplier * (bowSkillLevel & 0x3F);
+    }
+    return 0;
+    break;
+  case CHARACTER_ATTRIBUTE_HEALTH:
+    {
+      int base_value = pBaseHealthPerLevelByClass[classType];
+      int attrib_modif = GetBodybuilding();
+      return base_value * attrib_modif;
+    }
+    break;
+  case CHARACTER_ATTRIBUTE_MANA:
+    {
+      int base_value = pBaseManaPerLevelByClass[classType];
+      int attrib_modif = GetMeditation();
+      return base_value * attrib_modif;
+    }
+    break;
+  case CHARACTER_ATTRIBUTE_AC_BONUS:
+    {
+      bool wearingArmor = false;
+      bool wearingLeather = false;
+      unsigned int ACSum = 0;
+
+      for (int j = 0; j < 16; ++j) 
+      {
+        if (pEquipment.pIndices[j] && (!pOwnItems[pEquipment.pIndices[j]].Broken()))
+        {
+          int curr_item = pOwnItems[pEquipment.pIndices[j]].uItemID;
+          PLAYER_SKILL_TYPE itemSkillType = (PLAYER_SKILL_TYPE)pItemsTable->pItems[curr_item].uSkillType;
+          int currArmorSkillLevel = GetActualSkillLevel(itemSkillType);
+          int multiplier = 0;
+          switch (itemSkillType)
           {
-           if (pEquipment.pIndices[j]&&(!pOwnItems[ pEquipment.pIndices[j]].Broken()))
-               {
-               int curr_item =pOwnItems[pEquipment.pIndices[j]].uItemID;
-               v44=pItemsTable->pItems[curr_item].uSkillType;
-               switch (v44)
-                   {
-
-               case PLAYER_SKILL_STAFF:
-                   
-                   lvl_avl[0]=0;
-                   lvl_avl[1]=1;
-                   lvl_avl[2]=0;
-                   lvl_avl[3]=0;
-                   break;
-               case PLAYER_SKILL_SWORD:
-               case PLAYER_SKILL_SPEAR:
-                   lvl_avl[0]=0;
-                   lvl_avl[1]=0;
-                   lvl_avl[2]=0;
-                   lvl_avl[3]=1;
-                   break;
-               case PLAYER_SKILL_SHIELD:
-                    a1b = 1;
-                   lvl_avl[0]=1;
-                   lvl_avl[1]=0;
-                   lvl_avl[2]=1;
-                   lvl_avl[3]=0;
-                   break;
-               case PLAYER_SKILL_LEATHER:
-                   v71 = (ITEM_EQUIP_TYPE)1;
-                   lvl_avl[0]=1;
-                   lvl_avl[1]=0;
-                   lvl_avl[2]=1;
-                   lvl_avl[3]=0;
-
-                   break;
-               case PLAYER_SKILL_CHAIN:
-                    a1b = 1;
-                   lvl_avl[0]=1;
-                   lvl_avl[1]=0;
-                   lvl_avl[2]=0;
-                   lvl_avl[3]=0;
-                   break;
-               case PLAYER_SKILL_PLATE:
-                     a1b = 1; 
-                   lvl_avl[0]=1;
-                   lvl_avl[1]=0;
-                   lvl_avl[2]=0;
-                   lvl_avl[3]=0;
-                   break;
-               default:
-                   continue;
-                   }
-
-               v50= GetActualSkillLevel((PLAYER_SKILL_TYPE)v44);
-               v51 = v50;
-               v52 = SkillToMastery(v50);
-               v53 = v51 & 0x3F;
-               for ( i = 0; i < (signed int)v52; ++i )
-                   {
-                   if ( lvl_avl[i] )
-                       skill_bonus += v53;
-                   }
-
-               }
+          case PLAYER_SKILL_STAFF:
+            multiplier = GetMultiplierForMastery(currArmorSkillLevel, 0, 1, 1, 1);
+            break;
+          case PLAYER_SKILL_SWORD:
+          case PLAYER_SKILL_SPEAR:
+            multiplier = GetMultiplierForMastery(currArmorSkillLevel, 0, 0, 0, 1);
+            break;
+          case PLAYER_SKILL_SHIELD:
+            wearingArmor = true;
+            multiplier = GetMultiplierForMastery(currArmorSkillLevel, 1, 1, 2, 2);
+            break;
+          case PLAYER_SKILL_LEATHER:
+            wearingLeather = true;
+            multiplier = GetMultiplierForMastery(currArmorSkillLevel, 1, 1, 2, 2);
+            break;
+          case PLAYER_SKILL_CHAIN:
+            wearingArmor = true;
+            multiplier = GetMultiplierForMastery(currArmorSkillLevel, 1, 1, 1, 1);
+            break;
+          case PLAYER_SKILL_PLATE:
+            wearingArmor = true; 
+            multiplier = GetMultiplierForMastery(currArmorSkillLevel, 1, 1, 1, 1);
+            break;
           }
-
-      lvl_avl[0]=1;
-      lvl_avl[1]=1;
-      lvl_avl[2]=1;
-      lvl_avl[3]=0;
-
-      v55 = GetActualSkillLevel(PLAYER_SKILL_DODGE);
-      v56 = v55;
-      v57 = SkillToMastery(v55);
-      if ( !a1b && (!v71 || v57 == 4) )
-          {
-          v58 = v56 & 0x3F;
-          for ( j = 0; j < (signed int)v57; ++j )
-              {
-              if ( lvl_avl[j] )
-                  skill_bonus += v58;
-              }
-          }
-      return skill_bonus;
-
-    
-      }
-
-  if (a2 == CHARACTER_ATTRIBUTE_ATTACK)
-  {
-
-  if ( v2->IsUnarmed() == 1 )
-      {
-      v33 = v2->GetActualSkillLevel(PLAYER_SKILL_UNARMED);
-      v34 = v33;
-      if ( !v33 )
-          return skill_bonus;
-      if ( SkillToMastery(v33) >= 3 )
-          multiplier = 2;
-      else 
-          multiplier=1;
-      v30 = multiplier * (v34 & 0x3F);
-      return arm_bonus + v30;
-      }
-  v35 = (ITEM_EQUIP_TYPE)0;
-  v68 = 0;
-  for (i=0; i<16 ; ++i)
-      {
-      if ( v2->HasItemEquipped((ITEM_EQUIP_TYPE)i) )
+          ACSum += multiplier * (currArmorSkillLevel & 0x3F);
+        }
+      }
+
+      int dodgeSkillLevel = GetActualSkillLevel(PLAYER_SKILL_DODGE);
+      int dodgeMastery = SkillToMastery(dodgeSkillLevel);
+      int multiplier = GetMultiplierForMastery(dodgeSkillLevel, 1, 2, 3, 3);
+      if ( !wearingArmor && (!wearingLeather || dodgeMastery == 4) )
+      {
+        ACSum += multiplier * (dodgeSkillLevel & 0x3F);
+      }
+      return ACSum;
+    }
+    break;
+  case CHARACTER_ATTRIBUTE_ATTACK:
+    if ( this->IsUnarmed() )
+    {
+      int unarmedSkill = this->GetActualSkillLevel(PLAYER_SKILL_UNARMED);
+      if (!unarmedSkill)
+      {
+        return 0;
+      }
+      int multiplier = GetMultiplierForMastery(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)
+        {
+          PLAYER_SKILL_TYPE currItemSkillType = (PLAYER_SKILL_TYPE)pItemsTable->pItems[currItemIndex].uSkillType;
+          int currentItemSkillLevel = this->GetActualSkillLevel(currItemSkillType);
+          if (currItemSkillType == PLAYER_SKILL_BLASTER)
           {
-          v37 = v2->pEquipment.pIndices[i]-1;
-          if ( pItemsTable->pItems[v37].uEquipType <= EQUIP_MAIN_HAND)
-              break;
+            int multiplier = GetMultiplierForMastery(currentItemSkillLevel, 1, 2, 3, 5);
+            return multiplier * (currentItemSkillLevel & 0x3F);
           }
-      }
-  if ( i >= 16 )
-      return skill_bonus;
-  
-  v38 = (PLAYER_SKILL_TYPE)pItemsTable->pItems[v37].uSkillType;
-  a1a = v2->GetActualSkillLevel(v38);
-  v39=  SkillToMastery(a1a);
-  v71 = (ITEM_EQUIP_TYPE)0;
-  switch (v38)
-      {
-  case PLAYER_SKILL_STAFF:
-      v71 = (ITEM_EQUIP_TYPE)1;
-      if ( v39 == 4 )
+          else if (currItemSkillType == PLAYER_SKILL_STAFF && this->GetActualSkillLevel(PLAYER_SKILL_UNARMED) > 0)
           {
-          v40 = v2->GetActualSkillLevel(PLAYER_SKILL_UNARMED);
-          v41 = v40;
-
-          if ( v40 )
-              {
-              if ( SkillToMastery(v40) >= 3 )
-                  multiplier = 2;
-              else 
-                  multiplier=1;
-              v68 = multiplier * (v41 & 0x3F);
-              }
+            int unarmedSkillLevel = this->GetActualSkillLevel(PLAYER_SKILL_UNARMED);
+            int multiplier = GetMultiplierForMastery(currentItemSkillLevel, 1, 1, 2, 2);
+            return multiplier * (unarmedSkillLevel & 0x3F) + armsMasterBonus + (currentItemSkillLevel & 0x3F);
           }
-      break;
-  case PLAYER_SKILL_SWORD:
-  case PLAYER_SKILL_DAGGER:
-  case PLAYER_SKILL_AXE:
-  case PLAYER_SKILL_SPEAR:
-  case PLAYER_SKILL_MACE:
-            v71 = (ITEM_EQUIP_TYPE)1;
-        break;
-  case PLAYER_SKILL_BLASTER:
-
-      switch (v39)
+          else
           {
-      case 0: multiplier=1; break;
-      case 1: multiplier=3; break;
-      case 3: multiplier=3; break;
-      case 4: multiplier=5; break;
+            return armsMasterBonus + (currentItemSkillLevel & 0x3F);
           }
-      v5 = multiplier;
-      return v5 * (a1a & 0x3F);
-      break;
-      }
-
-
-  
-  v30 = v68 + v71 * (a1a & 0x3F);
-  return (int)((char *)v69 + v30);
-
-  }
-
-
-  if ( a2 != 9 )
-  {
-   
-      if ( a2 <= CHARACTER_ATTRIBUTE_ATTACK )
-        return skill_bonus;
-      if ( a2 > CHARACTER_ATTRIBUTE_MELEE_DMG_MAX )
-      {
-        if ( a2 != CHARACTER_ATTRIBUTE_RANGED_ATTACK )
-          return skill_bonus;
-        v71 = (ITEM_EQUIP_TYPE)0;
-        v9 = &v2->pEquipment;
-        while ( 1 )
+        }
+      }
+    }
+    return 0;
+    break;
+
+  case CHARACTER_ATTRIBUTE_RANGED_ATTACK:
+    for (int i = 0; i < 16; i++)
+    {
+      if ( this->HasItemEquipped((ITEM_EQUIP_TYPE)i) )
+      {
+        PLAYER_SKILL_TYPE currentItemSkillType = (PLAYER_SKILL_TYPE)pItemsTable->pItems[this->pInventoryItemList[this->pEquipment.pIndices[i] - 1].uItemID].uSkillType;
+        int currentItemSkillLevel = this->GetActualSkillLevel(currentItemSkillType);
+        if ( currentItemSkillType == PLAYER_SKILL_BOW )
         {
-          if ( v2->HasItemEquipped(v71) )
-          {
-            v11 = (PLAYER_SKILL_TYPE)pItemsTable->pItems[v2->pInventoryItemList[*(_DWORD *)v9].uItemID].uEquipType;
-            LOBYTE(v12) = this->GetActualSkillLevel(v11);
-            a1 = v12;
-            SkillToMastery(v12);
-            v13 = v11 - 5;
-            if ( !v13 )
-              return a1 & 0x3F;
-            if ( v13 == 2 )
-              break;
-          }
-          v71 = (ITEM_EQUIP_TYPE)((int)v71 + 1);
-          v9 = (PlayerEquipment *)((char *)v9 + 4);
-          if ( (signed int)v71 >= 16 )
-            return skill_bonus;
+          int multiplier = GetMultiplierForMastery(currentItemSkillLevel, 0, 0, 0, 0);
+          return multiplier * (currentItemSkillLevel & 0x3F);
         }
-        v14 = a1;
-        v15 = 1;
-        if ( (signed int)SkillToMastery(a1) >= 4 )
-        {
-          v62 = 5;
-          goto LABEL_31;
-        }
-        if ( (signed int)SkillToMastery(a1) >= 3 )
-        {
-          v62 = 3;
-          goto LABEL_31;
+        else if ( currentItemSkillType == PLAYER_SKILL_BLASTER )
+        {      
+          int multiplier = GetMultiplierForMastery(currentItemSkillLevel, 1, 2, 3, 5);
+          return multiplier * (currentItemSkillLevel & 0x3F);
         }
-        if ( (signed int)SkillToMastery(a1) < 2 )
-          goto LABEL_32;
-        goto LABEL_30;
-      }
-      if ( v2->IsUnarmed() )
-      {
-        LOBYTE(v18) = v2->GetActualSkillLevel(PLAYER_SKILL_UNARMED);
-        v14 = v18;
-        if ( !v18 )
-          return skill_bonus;
-        v15 = 0;
-        v19 = SkillToMastery(v18);
-        if ( (signed int)v19 < 3 )
+      }
+    }
+    return 0;
+    break;
+
+  case CHARACTER_ATTRIBUTE_MELEE_DMG_BONUS:
+    if ( this->IsUnarmed() )
+    {
+      int unarmedSkillLevel = this->GetActualSkillLevel(PLAYER_SKILL_UNARMED);
+      if ( !unarmedSkillLevel )
+      {
+        return 0;
+      }
+      int multiplier = GetMultiplierForMastery(unarmedSkillLevel, 0, 1, 2, 2);
+      return multiplier * (unarmedSkillLevel & 0x3F);
+    }
+    for (int i = 0; i < 16; i++)
+    {
+      if ( this->HasItemEquipped((ITEM_EQUIP_TYPE)i) )
+      {
+        int currItemId = this->pInventoryItemList[this->pEquipment.pIndices[i]].uItemID;
+        if ( pItemsTable->pItems[currItemId].uEquipType == EQUIP_MAIN_HAND || pItemsTable->pItems[currItemId].uEquipType == EQUIP_OFF_HAND )
         {
-          if ( (signed int)v19 >= 2 )
-            v15 = 1;
-LABEL_32:
-          v16 = v14;
-          return v15 * (v16 & 0x3F);
-        }
-LABEL_30:
-        v62 = 2;
-LABEL_31:
-        v15 = v62;
-        goto LABEL_32;
-      }
-      v20 = (ITEM_EQUIP_TYPE)0;
-      while ( 1 )
-      {
-        if ( v2->HasItemEquipped(v20) )
-        {
-          v22 = this->pInventoryItemList[this->pEquipment.pIndices[v20]].uItemID;
-          if ( pItemsTable->pItems[v22].uEquipType <= 1u )
-            break;
-        }
-        v20 = (ITEM_EQUIP_TYPE)((int)v20 + 1);
-        if ( (signed int)v20 >= 16 )
-          return skill_bonus;
-      }
-      v71 = (ITEM_EQUIP_TYPE)0;
-      v23 = (PLAYER_SKILL_TYPE)pItemsTable->pItems[v22].uSkillType;
-      LOBYTE(v24) = v2->GetActualSkillLevel(v23);
-      v25 = v24;
-      v26 = SkillToMastery(v24);
-      if ( !v23 )
-      {
-        if ( (signed int)SkillToMastery(v25) >= 4 )
-        {
-          LOBYTE(v31) = v2->GetActualSkillLevel(PLAYER_SKILL_UNARMED);
-          LOBYTE(v25) = v31;
-          if ( v31 )
+          PLAYER_SKILL_TYPE currItemSkillType = (PLAYER_SKILL_TYPE)pItemsTable->pItems[currItemId].uSkillType;
+          int currItemSkillLevel = this->GetActualSkillLevel(currItemSkillType);
+          int baseSkillBonus;
+          int multiplier;
+          switch (currItemSkillType)
           {
-            v15 = 0;
-            v32 = SkillToMastery(v31);
-            if ( (signed int)v32 < 3 )
+          case PLAYER_SKILL_STAFF:
+            if ( SkillToMastery(currItemSkillLevel) >= 4 && this->GetActualSkillLevel(PLAYER_SKILL_UNARMED) > 0)
             {
-              if ( (signed int)v32 >= 2 )
-                v15 = 1;
+              int unarmedSkillLevel = this->GetActualSkillLevel(PLAYER_SKILL_UNARMED);
+              int multiplier = GetMultiplierForMastery(unarmedSkillLevel, 0, 1, 2, 2);
+              return multiplier * (unarmedSkillLevel & 0x3F);
             }
             else
             {
-              v15 = 2;
+              return armsMasterBonus;
             }
-            v16 = v25;
-            return v15 * (v16 & 0x3F);
+            break;
+
+          case PLAYER_SKILL_DAGGER:
+            multiplier = GetMultiplierForMastery(currItemSkillLevel, 0, 0, 0, 1);
+            baseSkillBonus = multiplier * (currItemSkillLevel & 0x3F);
+            return armsMasterBonus + baseSkillBonus;
+            break;
+          case PLAYER_SKILL_SWORD:
+            multiplier = GetMultiplierForMastery(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);
+            baseSkillBonus = multiplier * (currItemSkillLevel & 0x3F);
+            return armsMasterBonus + baseSkillBonus;
+            break;
+          case PLAYER_SKILL_AXE:
+            multiplier = GetMultiplierForMastery(currItemSkillLevel, 0, 0, 1, 1);
+            baseSkillBonus = multiplier * (currItemSkillLevel & 0x3F);
+            return armsMasterBonus + baseSkillBonus;
+            break;
           }
         }
-        goto LABEL_55;
-      }
-      if ( v23 == PLAYER_SKILL_DAGGER )
-      {
-        v29 = SkillToMastery(v25);
-        v28 = __OFSUB__(v29, 4);
-        v27 = ((v29 - 4) & 0x80000000u) != 0;
-      }
-      else
-      {
-        if ( v23 <= PLAYER_SKILL_DAGGER )
-          goto LABEL_55;
-        if ( v23 > PLAYER_SKILL_SPEAR )
-        {
-          if ( v23 == PLAYER_SKILL_MACE )
-          {
-            v28 = __OFSUB__(v26, 2);
-            v27 = v26 - 2 < 0;
-            goto LABEL_53;
-          }
-LABEL_55:
-          v30 = v71 * (v25 & 0x3F);
-          return (int)((char *)v69 + v30);
-        }
-        v28 = __OFSUB__(v26, 3);
-        v27 = v26 - 3 < 0;
-      }
-LABEL_53:
-      if ( !(v27 ^ v28) )
-        v71 = (ITEM_EQUIP_TYPE)1;
-      goto LABEL_55;
-    }
-    
-  
-    assert(false && "Unknown attribute!");
+      }
+    }
+    return 0;
+    break;
+  default:
     return 0;
-}
-
+  }
+}
+
+unsigned int Player::GetMultiplierForMastery(unsigned int skillValue, int mult1, int mult2, int mult3, int mult4)
+{
+  int masteryLvl = SkillToMastery(skillValue);
+  switch (masteryLvl)
+  {
+    case 1: return mult1;
+    case 2: return mult2;
+    case 3: return mult3;
+    case 4: return mult4;
+  }
+  assert(false);
+  return 0;
+}
 //----- (00490109) --------------------------------------------------------
 // faces are:  0  1  2  3   human males
 //             4  5  6  7   human females
--- a/Player.h	Fri Sep 06 16:32:08 2013 +0200
+++ b/Player.h	Sat Sep 07 05:23:16 2013 +0200
@@ -621,6 +621,7 @@
 
   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];