mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-16 15:40:45 +01:00
Core/Spells: Implemented using base weapon damage in spell attack power formulas
This commit is contained in:
@@ -331,8 +331,6 @@ class TC_GAME_API Item : public Object
|
||||
SocketColor GetSocketColor(uint32 index) const { ASSERT(index < MAX_ITEM_PROTO_SOCKETS); return SocketColor(_bonusData.SocketColor[index]); }
|
||||
uint32 GetAppearanceModId() const { return m_itemData->ItemAppearanceModID; }
|
||||
void SetAppearanceModId(uint32 appearanceModId) { SetUpdateFieldValue(m_values.ModifyValue(&Item::m_itemData).ModifyValue(&UF::ItemData::ItemAppearanceModID), appearanceModId); }
|
||||
uint32 GetArmor(Player const* owner) const { return GetTemplate()->GetArmor(GetItemLevel(owner)); }
|
||||
void GetDamage(Player const* owner, float& minDamage, float& maxDamage) const { GetTemplate()->GetDamage(GetItemLevel(owner), minDamage, maxDamage); }
|
||||
uint32 GetDisplayId(Player const* owner) const;
|
||||
ItemModifiedAppearanceEntry const* GetItemModifiedAppearance() const;
|
||||
float GetRepairCostMultiplier() const { return _bonusData.RepairCostMultiplier; }
|
||||
|
||||
@@ -175,16 +175,11 @@ uint32 ItemTemplate::GetArmor(uint32 itemLevel) const
|
||||
return uint32(shield->Quality[quality] + 0.5f);
|
||||
}
|
||||
|
||||
void ItemTemplate::GetDamage(uint32 itemLevel, float& minDamage, float& maxDamage) const
|
||||
float ItemTemplate::GetDPS(uint32 itemLevel) const
|
||||
{
|
||||
minDamage = maxDamage = 0.0f;
|
||||
uint32 quality = ItemQualities(GetQuality()) != ITEM_QUALITY_HEIRLOOM ? ItemQualities(GetQuality()) : ITEM_QUALITY_RARE;
|
||||
if (GetClass() != ITEM_CLASS_WEAPON || quality > ITEM_QUALITY_ARTIFACT)
|
||||
return;
|
||||
|
||||
// get the right store here
|
||||
if (GetInventoryType() > INVTYPE_RANGEDRIGHT)
|
||||
return;
|
||||
return 0.0f;
|
||||
|
||||
float dps = 0.0f;
|
||||
switch (GetInventoryType())
|
||||
@@ -215,7 +210,7 @@ void ItemTemplate::GetDamage(uint32 itemLevel, float& minDamage, float& maxDamag
|
||||
dps = sItemDamageTwoHandStore.AssertEntry(itemLevel)->Quality[quality];
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case INVTYPE_WEAPON:
|
||||
@@ -227,12 +222,22 @@ void ItemTemplate::GetDamage(uint32 itemLevel, float& minDamage, float& maxDamag
|
||||
dps = sItemDamageOneHandStore.AssertEntry(itemLevel)->Quality[quality];
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
float avgDamage = dps * GetDelay() * 0.001f;
|
||||
minDamage = (GetDmgVariance() * -0.5f + 1.0f) * avgDamage;
|
||||
maxDamage = floor(float(avgDamage * (GetDmgVariance() * 0.5f + 1.0f) + 0.5f));
|
||||
return dps;
|
||||
}
|
||||
|
||||
void ItemTemplate::GetDamage(uint32 itemLevel, float& minDamage, float& maxDamage) const
|
||||
{
|
||||
minDamage = maxDamage = 0.0f;
|
||||
float dps = GetDPS(itemLevel);
|
||||
if (dps > 0.0f)
|
||||
{
|
||||
float avgDamage = dps * GetDelay() * 0.001f;
|
||||
minDamage = (GetDmgVariance() * -0.5f + 1.0f) * avgDamage;
|
||||
maxDamage = floor(float(avgDamage * (GetDmgVariance() * 0.5f + 1.0f) + 0.5f));
|
||||
}
|
||||
}
|
||||
|
||||
bool ItemTemplate::IsUsableByLootSpecialization(Player const* player, bool alwaysAllowBoundToAccount) const
|
||||
|
||||
@@ -826,6 +826,7 @@ struct TC_GAME_API ItemTemplate
|
||||
|
||||
char const* GetDefaultLocaleName() const;
|
||||
uint32 GetArmor(uint32 itemLevel) const;
|
||||
float GetDPS(uint32 itemLevel) const;
|
||||
void GetDamage(uint32 itemLevel, float& minDamage, float& maxDamage) const;
|
||||
bool IsUsableByLootSpecialization(Player const* player, bool alwaysAllowBoundToAccount) const;
|
||||
static std::size_t CalculateItemSpecBit(ChrSpecializationEntry const* spec);
|
||||
|
||||
@@ -7688,21 +7688,11 @@ void Player::_ApplyItemBonuses(Item* item, uint8 slot, bool apply)
|
||||
}
|
||||
}
|
||||
|
||||
if (uint32 armor = item->GetArmor(this))
|
||||
if (uint32 armor = proto->GetArmor(itemLevel))
|
||||
HandleStatFlatModifier(UNIT_MOD_ARMOR, BASE_VALUE, float(armor), apply);
|
||||
|
||||
WeaponAttackType attType = BASE_ATTACK;
|
||||
|
||||
if (slot == EQUIPMENT_SLOT_MAINHAND && (proto->GetInventoryType() == INVTYPE_RANGED || proto->GetInventoryType() == INVTYPE_RANGEDRIGHT))
|
||||
{
|
||||
attType = RANGED_ATTACK;
|
||||
}
|
||||
else if (slot == EQUIPMENT_SLOT_OFFHAND)
|
||||
{
|
||||
attType = OFF_ATTACK;
|
||||
}
|
||||
|
||||
if (CanUseAttackType(attType))
|
||||
WeaponAttackType attType = GetAttackBySlot(slot, proto->GetInventoryType());
|
||||
if (attType != MAX_ATTACK && CanUseAttackType(attType))
|
||||
_ApplyWeaponDamage(slot, item, apply);
|
||||
}
|
||||
|
||||
@@ -7717,8 +7707,9 @@ void Player::_ApplyWeaponDamage(uint8 slot, Item* item, bool apply)
|
||||
else if (slot == EQUIPMENT_SLOT_OFFHAND)
|
||||
attType = OFF_ATTACK;
|
||||
|
||||
uint32 itemLevel = item->GetItemLevel(this);
|
||||
float minDamage, maxDamage;
|
||||
item->GetDamage(this, minDamage, maxDamage);
|
||||
proto->GetDamage(itemLevel, minDamage, maxDamage);
|
||||
|
||||
if (minDamage > 0)
|
||||
{
|
||||
@@ -7736,6 +7727,22 @@ void Player::_ApplyWeaponDamage(uint8 slot, Item* item, bool apply)
|
||||
if (proto->GetDelay() && !(shapeshift && shapeshift->CombatRoundTime))
|
||||
SetBaseAttackTime(attType, apply ? proto->GetDelay() : BASE_ATTACK_TIME);
|
||||
|
||||
int32 weaponBasedAttackPower = apply ? int32(proto->GetDPS(itemLevel) * 6.0f) : 0;
|
||||
switch (attType)
|
||||
{
|
||||
case BASE_ATTACK:
|
||||
SetMainHandWeaponAttackPower(weaponBasedAttackPower);
|
||||
break;
|
||||
case OFF_ATTACK:
|
||||
SetOffHandWeaponAttackPower(weaponBasedAttackPower);
|
||||
break;
|
||||
case RANGED_ATTACK:
|
||||
SetRangedWeaponAttackPower(weaponBasedAttackPower);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (CanModifyStats() && (damage || proto->GetDelay()))
|
||||
UpdateDamagePhysical(attType);
|
||||
}
|
||||
|
||||
@@ -358,7 +358,7 @@ void Player::UpdateAttackPowerAndDamage(bool ranged)
|
||||
|
||||
SetStatFlatModifier(unitMod, BASE_VALUE, val2);
|
||||
|
||||
float base_attPower = GetFlatModifierValue(unitMod, BASE_VALUE) * GetPctModifierValue(unitMod, BASE_PCT);
|
||||
float base_attPower = GetFlatModifierValue(unitMod, BASE_VALUE) * GetPctModifierValue(unitMod, BASE_PCT);
|
||||
float attPowerMod = GetFlatModifierValue(unitMod, TOTAL_VALUE);
|
||||
float attPowerMultiplier = GetPctModifierValue(unitMod, TOTAL_PCT) - 1.0f;
|
||||
|
||||
@@ -424,7 +424,7 @@ void Player::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bo
|
||||
|
||||
float attackPowerMod = std::max(GetAPMultiplier(attType, normalized), 0.25f);
|
||||
|
||||
float baseValue = GetFlatModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType) / 3.5f * attackPowerMod;
|
||||
float baseValue = GetFlatModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType, false) / 3.5f * attackPowerMod;
|
||||
float basePct = GetPctModifierValue(unitMod, BASE_PCT);
|
||||
float totalValue = GetFlatModifierValue(unitMod, TOTAL_VALUE);
|
||||
float totalPct = addTotalPct ? GetPctModifierValue(unitMod, TOTAL_PCT) : 1.0f;
|
||||
@@ -987,7 +987,7 @@ void Creature::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized,
|
||||
weaponMaxDamage = 0.0f;
|
||||
}
|
||||
|
||||
float attackPower = GetTotalAttackPowerValue(attType);
|
||||
float attackPower = GetTotalAttackPowerValue(attType, false);
|
||||
float attackSpeedMulti = GetAPMultiplier(attType, normalized);
|
||||
float baseValue = GetFlatModifierValue(unitMod, BASE_VALUE) + (attackPower / 3.5f) * variance;
|
||||
float basePct = GetPctModifierValue(unitMod, BASE_PCT) * attackSpeedMulti;
|
||||
@@ -1269,7 +1269,7 @@ void Guardian::UpdateDamagePhysical(WeaponAttackType attType)
|
||||
|
||||
float att_speed = float(GetBaseAttackTime(BASE_ATTACK))/1000.0f;
|
||||
|
||||
float base_value = GetFlatModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType)/ 3.5f * att_speed + bonusDamage;
|
||||
float base_value = GetFlatModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType, false) / 3.5f * att_speed + bonusDamage;
|
||||
float base_pct = GetPctModifierValue(unitMod, BASE_PCT);
|
||||
float total_value = GetFlatModifierValue(unitMod, TOTAL_VALUE);
|
||||
float total_pct = GetPctModifierValue(unitMod, TOTAL_PCT);
|
||||
|
||||
@@ -6696,8 +6696,17 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin
|
||||
ApCoeffMod /= 100.0f;
|
||||
}
|
||||
|
||||
WeaponAttackType const attType = (spellProto->IsRangedWeaponSpell() && spellProto->DmgClass != SPELL_DAMAGE_CLASS_MELEE) ? RANGED_ATTACK : BASE_ATTACK;
|
||||
float APbonus = float(victim->GetTotalAuraModifier(attType == BASE_ATTACK ? SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS : SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS));
|
||||
WeaponAttackType const attType = [&]()
|
||||
{
|
||||
if ((spellProto->IsRangedWeaponSpell() && spellProto->DmgClass != SPELL_DAMAGE_CLASS_MELEE))
|
||||
return RANGED_ATTACK;
|
||||
|
||||
if (spellProto->HasAttribute(SPELL_ATTR3_REQ_OFFHAND) && !spellProto->HasAttribute(SPELL_ATTR3_MAIN_HAND))
|
||||
return OFF_ATTACK;
|
||||
|
||||
return BASE_ATTACK;
|
||||
}();
|
||||
float APbonus = float(victim->GetTotalAuraModifier(attType != RANGED_ATTACK ? SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS : SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS));
|
||||
APbonus += GetTotalAttackPowerValue(attType);
|
||||
DoneTotal += int32(stack * ApCoeffMod * APbonus);
|
||||
}
|
||||
@@ -9752,18 +9761,30 @@ void Unit::UpdateResistances(uint32 school)
|
||||
UpdateArmor();
|
||||
}
|
||||
|
||||
float Unit::GetTotalAttackPowerValue(WeaponAttackType attType) const
|
||||
float Unit::GetTotalAttackPowerValue(WeaponAttackType attType, bool includeWeapon /*= true*/) const
|
||||
{
|
||||
if (attType == RANGED_ATTACK)
|
||||
{
|
||||
int32 ap = m_unitData->RangedAttackPower;
|
||||
float ap = m_unitData->RangedAttackPower + m_unitData->RangedAttackPowerModPos + m_unitData->RangedAttackPowerModNeg;
|
||||
if (includeWeapon)
|
||||
ap += std::max<float>(m_unitData->MainHandWeaponAttackPower, m_unitData->RangedWeaponAttackPower);
|
||||
if (ap < 0)
|
||||
return 0.0f;
|
||||
return ap * (1.0f + m_unitData->RangedAttackPowerMultiplier);
|
||||
}
|
||||
else
|
||||
{
|
||||
int32 ap = m_unitData->AttackPower;
|
||||
float ap = m_unitData->AttackPower + m_unitData->AttackPowerModPos + m_unitData->AttackPowerModNeg;
|
||||
if (includeWeapon)
|
||||
{
|
||||
if (attType == BASE_ATTACK)
|
||||
ap += std::max<float>(m_unitData->MainHandWeaponAttackPower, m_unitData->RangedWeaponAttackPower);
|
||||
else
|
||||
{
|
||||
ap += m_unitData->OffHandWeaponAttackPower;
|
||||
ap /= 2;
|
||||
}
|
||||
}
|
||||
if (ap < 0)
|
||||
return 0.0f;
|
||||
return ap * (1.0f + m_unitData->AttackPowerMultiplier);
|
||||
|
||||
@@ -1753,8 +1753,11 @@ class TC_GAME_API Unit : public WorldObject
|
||||
void SetRangedAttackPowerModPos(int32 attackPowerMod) { SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::RangedAttackPowerModPos), attackPowerMod); }
|
||||
void SetRangedAttackPowerModNeg(int32 attackPowerMod) { SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::RangedAttackPowerModNeg), attackPowerMod); }
|
||||
void SetRangedAttackPowerMultiplier(float attackPowerMult) { SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::RangedAttackPowerMultiplier), attackPowerMult); }
|
||||
void SetMainHandWeaponAttackPower(int32 attackPower) { SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::MainHandWeaponAttackPower), attackPower); }
|
||||
void SetOffHandWeaponAttackPower(int32 attackPower) { SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::OffHandWeaponAttackPower), attackPower); }
|
||||
void SetRangedWeaponAttackPower(int32 attackPower) { SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::RangedWeaponAttackPower), attackPower); }
|
||||
virtual void UpdateDamagePhysical(WeaponAttackType attType);
|
||||
float GetTotalAttackPowerValue(WeaponAttackType attType) const;
|
||||
float GetTotalAttackPowerValue(WeaponAttackType attType, bool includeWeapon = true) const;
|
||||
float GetWeaponDamageRange(WeaponAttackType attType, WeaponDamageRange type) const;
|
||||
void SetBaseWeaponDamage(WeaponAttackType attType, WeaponDamageRange damageRange, float value) { m_weaponDamage[attType][damageRange] = value; }
|
||||
virtual void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage) const = 0;
|
||||
|
||||
Reference in New Issue
Block a user