Core/Spells: Implemented using base weapon damage in spell attack power formulas

This commit is contained in:
Shauren
2020-09-07 20:59:50 +02:00
parent 3d4910d6ba
commit dd21e7ff40
7 changed files with 73 additions and 38 deletions

View File

@@ -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; }

View File

@@ -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

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;