aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/game/DBCStructure.h55
-rw-r--r--src/game/ItemPrototype.h44
-rw-r--r--src/game/Player.cpp75
3 files changed, 105 insertions, 69 deletions
diff --git a/src/game/DBCStructure.h b/src/game/DBCStructure.h
index 3798785ca03..d5078e8b408 100644
--- a/src/game/DBCStructure.h
+++ b/src/game/DBCStructure.h
@@ -1143,7 +1143,7 @@ struct RandomPropertiesPointsEntry
struct ScalingStatDistributionEntry
{
uint32 Id;
- uint32 StatMod[10];
+ int32 StatMod[10];
uint32 Modifier[10];
uint32 MaxLevel;
};
@@ -1152,7 +1152,58 @@ struct ScalingStatValuesEntry
{
uint32 Id;
uint32 Level;
- uint32 Multiplier[17];
+ uint32 ssdMultiplier[5]; // Multiplier for ScalingStatDistribution
+ uint32 armorMod[4]; // Armor for level
+ uint32 dpsMod[6]; // DPS mod for level
+ uint32 spellBonus; // not sure.. TODO: need more info about
+ uint32 feralBonus; // Feral AP bonus
+
+ uint32 getssdMultiplier(uint32 mask) const
+ {
+ if (mask&0x001F)
+ {
+ if(mask & 0x00000001) return ssdMultiplier[0];
+ if(mask & 0x00000002) return ssdMultiplier[1];
+ if(mask & 0x00000004) return ssdMultiplier[2];
+ if(mask & 0x00000008) return ssdMultiplier[3];
+ if(mask & 0x00000010) return ssdMultiplier[4];
+ }
+ return 0;
+ }
+ uint32 getArmorMod(uint32 mask) const
+ {
+ if (mask&0x01E0)
+ {
+ if(mask & 0x00000020) return armorMod[0];
+ if(mask & 0x00000040) return armorMod[1];
+ if(mask & 0x00000080) return armorMod[2];
+ if(mask & 0x00000100) return armorMod[3];
+ }
+ return 0;
+ }
+ uint32 getDPSMod(uint32 mask) const
+ {
+ if (mask&0x7E00)
+ {
+ if(mask & 0x00000200) return dpsMod[0];
+ if(mask & 0x00000400) return dpsMod[1];
+ if(mask & 0x00000800) return dpsMod[2];
+ if(mask & 0x00001000) return dpsMod[3];
+ if(mask & 0x00002000) return dpsMod[4];
+ if(mask & 0x00004000) return dpsMod[5];
+ }
+ return 0;
+ }
+ uint32 getSpellBonus(uint32 mask) const
+ {
+ if (mask & 0x00008000) return spellBonus;
+ return 0;
+ }
+ uint32 getFeralBonus(uint32 mask) const
+ {
+ if (mask & 0x00010000) return feralBonus;
+ return 0;
+ }
};
//struct SkillLineCategoryEntry{
diff --git a/src/game/ItemPrototype.h b/src/game/ItemPrototype.h
index f87e52b2e22..e7a37dc8e14 100644
--- a/src/game/ItemPrototype.h
+++ b/src/game/ItemPrototype.h
@@ -600,46 +600,6 @@ struct ItemPrototype
return false;
}
- uint32 GetScalingStatValuesColumn() const
- {
- if(ScalingStatValue & 0x00000001) // stat mod
- return 0;
- if(ScalingStatValue & 0x00000002) // stat mod
- return 1;
- if(ScalingStatValue & 0x00000004) // stat mod
- return 2;
- if(ScalingStatValue & 0x00000008) // stat mod
- return 3;
- if(ScalingStatValue & 0x00000010) // stat mod
- return 4;
- if(ScalingStatValue & 0x00000020) // armor mod
- return 5;
- if(ScalingStatValue & 0x00000040) // armor mod
- return 6;
- if(ScalingStatValue & 0x00000080) // armor mod
- return 7;
- if(ScalingStatValue & 0x00000100) // armor mod
- return 8;
- if(ScalingStatValue & 0x00000200) // damage mod
- return 9;
- if(ScalingStatValue & 0x00000400) // damage mod
- return 10;
- if(ScalingStatValue & 0x00000800) // damage mod
- return 11;
- if(ScalingStatValue & 0x00001000) // damage mod
- return 12;
- if(ScalingStatValue & 0x00002000) // damage mod
- return 13;
- if(ScalingStatValue & 0x00004000) // damage mod
- return 14;
- if(ScalingStatValue & 0x00008000) // spell power
- return 15;
- if(ScalingStatValue & 0x00020000) // feral AP
- return 16;
-
- return 0;
- }
-
uint32 GetMaxStackSize() const { return Stackable > 0 ? uint32(Stackable) : uint32(0x7FFFFFFF-1); }
float getDPS() const
@@ -652,12 +612,12 @@ struct ItemPrototype
return temp*500/Delay;
}
- int32 getFeralBonus() const
+ int32 getFeralBonus(int32 extraDPS = 0) const
{
// 0x02A5F3 - is mask for Melee weapon from ItemSubClassMask.dbc
if (Class == ITEM_CLASS_WEAPON && (1<<SubClass)&0x02A5F3)
{
- int32 bonus = int32(getDPS()*14.0f) - 767;
+ int32 bonus = int32((extraDPS + getDPS())*14.0f) - 767;
if (bonus < 0)
return 0;
return bonus;
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index 2dffafc095a..c29c9abe065 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -6483,30 +6483,25 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool appl
if(slot >= INVENTORY_SLOT_BAG_END || !proto)
return;
+ ScalingStatDistributionEntry const *ssd = proto->ScalingStatDistribution ? sScalingStatDistributionStore.LookupEntry(proto->ScalingStatDistribution) : 0;
+ ScalingStatValuesEntry const *ssv = proto->ScalingStatValue ? sScalingStatValuesStore.LookupEntry(getLevel()) : 0;
+
for (int i = 0; i < MAX_ITEM_PROTO_STATS; ++i)
{
uint32 statType = 0;
- int32 val = 0;
-
- if(proto->ScalingStatDistribution)
+ int32 val = 0;
+ // If set ScalingStatDistribution need get stats and values from it
+ if (ssd && ssv)
{
- if(ScalingStatDistributionEntry const *ssd = sScalingStatDistributionStore.LookupEntry(proto->ScalingStatDistribution))
- {
- statType = ssd->StatMod[i];
-
- if(uint32 modifier = ssd->Modifier[i])
- {
- uint32 level = ((getLevel() > ssd->MaxLevel) ? ssd->MaxLevel : getLevel());
- if(ScalingStatValuesEntry const *ssv = sScalingStatValuesStore.LookupEntry(level))
- {
- uint32 multiplier = ssv->Multiplier[proto->GetScalingStatValuesColumn()];
- val = (multiplier * modifier) / 10000;
- }
- }
- }
+ if (ssd->StatMod[i] < 0)
+ continue;
+ statType = ssd->StatMod[i];
+ val = (ssv->getssdMultiplier(proto->ScalingStatValue) * ssd->Modifier[i]) / 10000;
}
else
{
+ if (proto->StatsCount >= i)
+ continue;
statType = proto->ItemStat[i].ItemStatType;
val = proto->ItemStat[i].ItemStatValue;
}
@@ -6661,8 +6656,15 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool appl
}
}
- if (proto->Armor)
- HandleStatModifier(UNIT_MOD_ARMOR, BASE_VALUE, float(proto->Armor), apply);
+ // If set ScalingStatValue armor get it or use item armor
+ uint32 armor = proto->Armor;
+ if (ssv)
+ {
+ if (uint32 ssvarmor = ssv->getArmorMod(proto->ScalingStatValue))
+ armor = ssvarmor;
+ }
+ if (armor)
+ HandleStatModifier(UNIT_MOD_ARMOR, BASE_VALUE, float(armor), apply);
if (proto->Block)
HandleBaseModValue(SHIELD_BLOCK_VALUE, FLAT_MOD, float(proto->Block), apply);
@@ -6699,23 +6701,42 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool appl
attType = OFF_ATTACK;
}
- if (proto->Damage[0].DamageMin > 0 )
+ float minDamage = proto->Damage[0].DamageMin;
+ float maxDamage = proto->Damage[0].DamageMax;
+ int32 extraDPS = 0;
+ // If set dpsMod in ScalingStatValue use it for min (70% from avernge), max (130% from averange) damage
+ if (ssv)
+ {
+ if (extraDPS = ssv->getDPSMod(proto->ScalingStatValue))
+ {
+ float averange = extraDPS * proto->Delay / 1000.0f;
+ minDamage = 0.7f * averange;
+ maxDamage = 1.3f * averange;
+ }
+ }
+ if (minDamage > 0 )
{
- damage = apply ? proto->Damage[0].DamageMin : BASE_MINDAMAGE;
+ damage = apply ? minDamage : BASE_MINDAMAGE;
SetBaseWeaponDamage(attType, MINDAMAGE, damage);
//sLog.outError("applying mindam: assigning %f to weapon mindamage, now is: %f", damage, GetWeaponDamageRange(attType, MINDAMAGE));
}
- if (proto->Damage[0].DamageMax > 0 )
+ if (maxDamage > 0 )
{
- damage = apply ? proto->Damage[0].DamageMax : BASE_MAXDAMAGE;
+ damage = apply ? maxDamage : BASE_MAXDAMAGE;
SetBaseWeaponDamage(attType, MAXDAMAGE, damage);
}
- // Druids get feral AP bonus from weapon dps
+ // Apply feral bonus from ScalingStatValue if set
+ if (ssv)
+ {
+ if (int32 feral_bonus = ssv->getFeralBonus(proto->ScalingStatValue))
+ ApplyFeralAPBonus(feral_bonus, apply);
+ }
+ // Druids get feral AP bonus from weapon dps (lso use DPS from ScalingStatValue)
if(getClass() == CLASS_DRUID)
{
- int32 feral_bonus = proto->getFeralBonus();
+ int32 feral_bonus = proto->getFeralBonus(extraDPS);
if (feral_bonus > 0)
ApplyFeralAPBonus(feral_bonus, apply);
}
@@ -9844,6 +9865,10 @@ uint8 Player::CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bo
return EQUIP_ERR_CANT_DO_RIGHT_NOW;
}
+ ScalingStatDistributionEntry const *ssd = pProto->ScalingStatDistribution ? sScalingStatDistributionStore.LookupEntry(pProto->ScalingStatDistribution) : 0;
+ if (ssd && ssd->MaxLevel < getLevel())
+ return EQUIP_ERR_ITEM_CANT_BE_EQUIPPED;
+
uint8 eslot = FindEquipSlot( pProto, slot, swap );
if( eslot == NULL_SLOT )
return EQUIP_ERR_ITEM_CANT_BE_EQUIPPED;