Core/Spells: Implemented using base weapon damage in spell attack power formulas
Port From (https://github.com/TrinityCore/TrinityCore/commit/dd21e7ff404aed1d449b09db2b7fcbe2be8536c3)
This commit is contained in:
@@ -2514,8 +2514,6 @@ namespace Game.Entities
|
|||||||
}
|
}
|
||||||
public uint GetAppearanceModId() { return m_itemData.ItemAppearanceModID; }
|
public uint GetAppearanceModId() { return m_itemData.ItemAppearanceModID; }
|
||||||
public void SetAppearanceModId(uint appearanceModId) { SetUpdateFieldValue(m_values.ModifyValue(m_itemData).ModifyValue(m_itemData.ItemAppearanceModID), (byte)appearanceModId); }
|
public void SetAppearanceModId(uint appearanceModId) { SetUpdateFieldValue(m_values.ModifyValue(m_itemData).ModifyValue(m_itemData.ItemAppearanceModID), (byte)appearanceModId); }
|
||||||
public uint GetArmor(Player owner) { return GetTemplate().GetArmor(GetItemLevel(owner)); }
|
|
||||||
public void GetDamage(Player owner, out float minDamage, out float maxDamage) { GetTemplate().GetDamage(GetItemLevel(owner), out minDamage, out maxDamage); }
|
|
||||||
public float GetRepairCostMultiplier() { return _bonusData.RepairCostMultiplier; }
|
public float GetRepairCostMultiplier() { return _bonusData.RepairCostMultiplier; }
|
||||||
public uint GetScalingStatDistribution() { return _bonusData.ScalingStatDistribution; }
|
public uint GetScalingStatDistribution() { return _bonusData.ScalingStatDistribution; }
|
||||||
|
|
||||||
|
|||||||
@@ -158,16 +158,11 @@ namespace Game.Entities
|
|||||||
return (uint)(shield.Quality[(int)quality] + 0.5f);
|
return (uint)(shield.Quality[(int)quality] + 0.5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GetDamage(uint itemLevel, out float minDamage, out float maxDamage)
|
public float GetDPS(uint itemLevel)
|
||||||
{
|
{
|
||||||
minDamage = maxDamage = 0.0f;
|
|
||||||
ItemQuality quality = GetQuality() != ItemQuality.Heirloom ? GetQuality() : ItemQuality.Rare;
|
ItemQuality quality = GetQuality() != ItemQuality.Heirloom ? GetQuality() : ItemQuality.Rare;
|
||||||
if (GetClass() != ItemClass.Weapon || quality > ItemQuality.Artifact)
|
if (GetClass() != ItemClass.Weapon || quality > ItemQuality.Artifact)
|
||||||
return;
|
return 0.0f;
|
||||||
|
|
||||||
// get the right store here
|
|
||||||
if (GetInventoryType() > InventoryType.RangedRight)
|
|
||||||
return;
|
|
||||||
|
|
||||||
float dps = 0.0f;
|
float dps = 0.0f;
|
||||||
switch (GetInventoryType())
|
switch (GetInventoryType())
|
||||||
@@ -198,7 +193,7 @@ namespace Game.Entities
|
|||||||
dps = CliDB.ItemDamageTwoHandStorage.LookupByKey(itemLevel).Quality[(int)quality];
|
dps = CliDB.ItemDamageTwoHandStorage.LookupByKey(itemLevel).Quality[(int)quality];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case InventoryType.Weapon:
|
case InventoryType.Weapon:
|
||||||
@@ -210,12 +205,22 @@ namespace Game.Entities
|
|||||||
dps = CliDB.ItemDamageOneHandStorage.LookupByKey(itemLevel).Quality[(int)quality];
|
dps = CliDB.ItemDamageOneHandStorage.LookupByKey(itemLevel).Quality[(int)quality];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
float avgDamage = dps * GetDelay() * 0.001f;
|
return dps;
|
||||||
minDamage = (GetDmgVariance() * -0.5f + 1.0f) * avgDamage;
|
}
|
||||||
maxDamage = (float)Math.Floor(avgDamage * (GetDmgVariance() * 0.5f + 1.0f) + 0.5f);
|
|
||||||
|
public void GetDamage(uint itemLevel, out float minDamage, out float maxDamage)
|
||||||
|
{
|
||||||
|
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 = (float)Math.Floor(avgDamage * (GetDmgVariance() * 0.5f + 1.0f) + 0.5f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsUsableByLootSpecialization(Player player, bool alwaysAllowBoundToAccount)
|
public bool IsUsableByLootSpecialization(Player player, bool alwaysAllowBoundToAccount)
|
||||||
|
|||||||
@@ -251,8 +251,9 @@ namespace Game.Entities
|
|||||||
else if (slot == EquipmentSlot.OffHand)
|
else if (slot == EquipmentSlot.OffHand)
|
||||||
attType = WeaponAttackType.OffAttack;
|
attType = WeaponAttackType.OffAttack;
|
||||||
|
|
||||||
|
uint itemLevel = item.GetItemLevel(this);
|
||||||
float minDamage, maxDamage;
|
float minDamage, maxDamage;
|
||||||
item.GetDamage(this, out minDamage, out maxDamage);
|
proto.GetDamage(itemLevel, out minDamage, out maxDamage);
|
||||||
|
|
||||||
if (minDamage > 0)
|
if (minDamage > 0)
|
||||||
{
|
{
|
||||||
@@ -270,6 +271,22 @@ namespace Game.Entities
|
|||||||
if (proto.GetDelay() != 0 && !(shapeshift != null && shapeshift.CombatRoundTime != 0))
|
if (proto.GetDelay() != 0 && !(shapeshift != null && shapeshift.CombatRoundTime != 0))
|
||||||
SetBaseAttackTime(attType, apply ? proto.GetDelay() : SharedConst.BaseAttackTime);
|
SetBaseAttackTime(attType, apply ? proto.GetDelay() : SharedConst.BaseAttackTime);
|
||||||
|
|
||||||
|
int weaponBasedAttackPower = apply ? (int)(proto.GetDPS(itemLevel) * 6.0f) : 0;
|
||||||
|
switch (attType)
|
||||||
|
{
|
||||||
|
case WeaponAttackType.BaseAttack:
|
||||||
|
SetMainHandWeaponAttackPower(weaponBasedAttackPower);
|
||||||
|
break;
|
||||||
|
case WeaponAttackType.OffAttack:
|
||||||
|
SetOffHandWeaponAttackPower(weaponBasedAttackPower);
|
||||||
|
break;
|
||||||
|
case WeaponAttackType.RangedAttack:
|
||||||
|
SetRangedWeaponAttackPower(weaponBasedAttackPower);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (CanModifyStats() && (damage != 0 || proto.GetDelay() != 0))
|
if (CanModifyStats() && (damage != 0 || proto.GetDelay() != 0))
|
||||||
UpdateDamagePhysical(attType);
|
UpdateDamagePhysical(attType);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4230,21 +4230,12 @@ namespace Game.Entities
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint armor = item.GetArmor(this);
|
uint armor = proto.GetArmor(itemLevel);
|
||||||
if (armor != 0)
|
if (armor != 0)
|
||||||
HandleStatFlatModifier(UnitMods.Armor, UnitModifierFlatType.Base, (float)armor, apply);
|
HandleStatFlatModifier(UnitMods.Armor, UnitModifierFlatType.Base, (float)armor, apply);
|
||||||
|
|
||||||
WeaponAttackType attType = WeaponAttackType.BaseAttack;
|
WeaponAttackType attType = GetAttackBySlot(slot, proto.GetInventoryType());
|
||||||
if (slot == EquipmentSlot.MainHand && (proto.GetInventoryType() == InventoryType.Ranged || proto.GetInventoryType() == InventoryType.RangedRight))
|
if (attType != WeaponAttackType.Max && CanUseAttackType(attType))
|
||||||
{
|
|
||||||
attType = WeaponAttackType.RangedAttack;
|
|
||||||
}
|
|
||||||
else if (slot == EquipmentSlot.OffHand)
|
|
||||||
{
|
|
||||||
attType = WeaponAttackType.OffAttack;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CanUseAttackType(attType))
|
|
||||||
_ApplyWeaponDamage(slot, item, apply);
|
_ApplyWeaponDamage(slot, item, apply);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -709,6 +709,9 @@ namespace Game.Entities
|
|||||||
public void SetRangedAttackPowerModPos(int attackPowerMod) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.RangedAttackPowerModPos), attackPowerMod); }
|
public void SetRangedAttackPowerModPos(int attackPowerMod) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.RangedAttackPowerModPos), attackPowerMod); }
|
||||||
public void SetRangedAttackPowerModNeg(int attackPowerMod) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.RangedAttackPowerModNeg), attackPowerMod); }
|
public void SetRangedAttackPowerModNeg(int attackPowerMod) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.RangedAttackPowerModNeg), attackPowerMod); }
|
||||||
public void SetRangedAttackPowerMultiplier(float attackPowerMult) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.RangedAttackPowerMultiplier), attackPowerMult); }
|
public void SetRangedAttackPowerMultiplier(float attackPowerMult) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.RangedAttackPowerMultiplier), attackPowerMult); }
|
||||||
|
public void SetMainHandWeaponAttackPower(int attackPower) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.MainHandWeaponAttackPower), attackPower); }
|
||||||
|
public void SetOffHandWeaponAttackPower(int attackPower) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.OffHandWeaponAttackPower), attackPower); }
|
||||||
|
public void SetRangedWeaponAttackPower(int attackPower) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.RangedWeaponAttackPower), attackPower); }
|
||||||
|
|
||||||
//Chances
|
//Chances
|
||||||
float MeleeSpellMissChance(Unit victim, WeaponAttackType attType, uint spellId)
|
float MeleeSpellMissChance(Unit victim, WeaponAttackType attType, uint spellId)
|
||||||
@@ -1076,7 +1079,7 @@ namespace Game.Entities
|
|||||||
|
|
||||||
float attackPowerMod = Math.Max(GetAPMultiplier(attType, normalized), 0.25f);
|
float attackPowerMod = Math.Max(GetAPMultiplier(attType, normalized), 0.25f);
|
||||||
|
|
||||||
float baseValue = GetFlatModifierValue(unitMod, UnitModifierFlatType.Base) + GetTotalAttackPowerValue(attType) / 3.5f * attackPowerMod;
|
float baseValue = GetFlatModifierValue(unitMod, UnitModifierFlatType.Base) + GetTotalAttackPowerValue(attType, false) / 3.5f * attackPowerMod;
|
||||||
float basePct = GetPctModifierValue(unitMod, UnitModifierPctType.Base);
|
float basePct = GetPctModifierValue(unitMod, UnitModifierPctType.Base);
|
||||||
float totalValue = GetFlatModifierValue(unitMod, UnitModifierFlatType.Total);
|
float totalValue = GetFlatModifierValue(unitMod, UnitModifierFlatType.Total);
|
||||||
float totalPct = addTotalPct ? GetPctModifierValue(unitMod, UnitModifierPctType.Total) : 1.0f;
|
float totalPct = addTotalPct ? GetPctModifierValue(unitMod, UnitModifierPctType.Total) : 1.0f;
|
||||||
@@ -2040,7 +2043,7 @@ namespace Game.Entities
|
|||||||
weaponMaxDamage = 0.0f;
|
weaponMaxDamage = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
float attackPower = GetTotalAttackPowerValue(attType);
|
float attackPower = GetTotalAttackPowerValue(attType, false);
|
||||||
float attackSpeedMulti = Math.Max(GetAPMultiplier(attType, normalized), 0.25f);
|
float attackSpeedMulti = Math.Max(GetAPMultiplier(attType, normalized), 0.25f);
|
||||||
|
|
||||||
float baseValue = GetFlatModifierValue(unitMod, UnitModifierFlatType.Base) + (attackPower / 3.5f) * variance;
|
float baseValue = GetFlatModifierValue(unitMod, UnitModifierFlatType.Base) + (attackPower / 3.5f) * variance;
|
||||||
|
|||||||
@@ -929,7 +929,7 @@ namespace Game.Entities
|
|||||||
|
|
||||||
float att_speed = GetBaseAttackTime(WeaponAttackType.BaseAttack) / 1000.0f;
|
float att_speed = GetBaseAttackTime(WeaponAttackType.BaseAttack) / 1000.0f;
|
||||||
|
|
||||||
float base_value = GetFlatModifierValue(unitMod, UnitModifierFlatType.Base) + GetTotalAttackPowerValue(attType) / 3.5f * att_speed + bonusDamage;
|
float base_value = GetFlatModifierValue(unitMod, UnitModifierFlatType.Base) + GetTotalAttackPowerValue(attType, false) / 3.5f * att_speed + bonusDamage;
|
||||||
float base_pct = GetPctModifierValue(unitMod, UnitModifierPctType.Base);
|
float base_pct = GetPctModifierValue(unitMod, UnitModifierPctType.Base);
|
||||||
float total_value = GetFlatModifierValue(unitMod, UnitModifierFlatType.Total);
|
float total_value = GetFlatModifierValue(unitMod, UnitModifierFlatType.Total);
|
||||||
float total_pct = GetPctModifierValue(unitMod, UnitModifierPctType.Total);
|
float total_pct = GetPctModifierValue(unitMod, UnitModifierPctType.Total);
|
||||||
|
|||||||
@@ -2253,18 +2253,30 @@ namespace Game.Entities
|
|||||||
return weapon.GetTemplate().GetDelay() / 1000.0f;
|
return weapon.GetTemplate().GetDelay() / 1000.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public float GetTotalAttackPowerValue(WeaponAttackType attType)
|
public float GetTotalAttackPowerValue(WeaponAttackType attType, bool includeWeapon = true)
|
||||||
{
|
{
|
||||||
if (attType == WeaponAttackType.RangedAttack)
|
if (attType == WeaponAttackType.RangedAttack)
|
||||||
{
|
{
|
||||||
int ap = m_unitData.RangedAttackPower;
|
float ap = m_unitData.RangedAttackPower + m_unitData.RangedAttackPowerModPos + m_unitData.RangedAttackPowerModNeg;
|
||||||
|
if (includeWeapon)
|
||||||
|
ap += Math.Max(m_unitData.MainHandWeaponAttackPower, m_unitData.RangedWeaponAttackPower);
|
||||||
if (ap < 0)
|
if (ap < 0)
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
return ap * (1.0f + m_unitData.RangedAttackPowerMultiplier);
|
return ap * (1.0f + m_unitData.RangedAttackPowerMultiplier);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int ap = m_unitData.AttackPower;
|
float ap = m_unitData.AttackPower + m_unitData.AttackPowerModPos + m_unitData.AttackPowerModNeg;
|
||||||
|
if (includeWeapon)
|
||||||
|
{
|
||||||
|
if (attType == WeaponAttackType.BaseAttack)
|
||||||
|
ap += Math.Max(m_unitData.MainHandWeaponAttackPower, m_unitData.RangedWeaponAttackPower);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ap += m_unitData.OffHandWeaponAttackPower;
|
||||||
|
ap /= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (ap < 0)
|
if (ap < 0)
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
return ap * (1.0f + m_unitData.AttackPowerMultiplier);
|
return ap * (1.0f + m_unitData.AttackPowerMultiplier);
|
||||||
|
|||||||
@@ -128,8 +128,14 @@ namespace Game.Entities
|
|||||||
ApCoeffMod /= 100.0f;
|
ApCoeffMod /= 100.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
WeaponAttackType attType = (spellProto.IsRangedWeaponSpell() && spellProto.DmgClass != SpellDmgClass.Melee) ? WeaponAttackType.RangedAttack : WeaponAttackType.BaseAttack;
|
WeaponAttackType attType = WeaponAttackType.BaseAttack;
|
||||||
float APbonus = victim.GetTotalAuraModifier(attType == WeaponAttackType.BaseAttack ? AuraType.MeleeAttackPowerAttackerBonus : AuraType.RangedAttackPowerAttackerBonus);
|
if ((spellProto.IsRangedWeaponSpell() && spellProto.DmgClass != SpellDmgClass.Melee))
|
||||||
|
attType = WeaponAttackType.RangedAttack;
|
||||||
|
|
||||||
|
if (spellProto.HasAttribute(SpellAttr3.ReqOffhand) && !spellProto.HasAttribute(SpellAttr3.MainHand))
|
||||||
|
attType = WeaponAttackType.OffAttack;
|
||||||
|
|
||||||
|
float APbonus = (float)(victim.GetTotalAuraModifier(attType != WeaponAttackType.RangedAttack ? AuraType.MeleeAttackPowerAttackerBonus : AuraType.RangedAttackPowerAttackerBonus));
|
||||||
APbonus += GetTotalAttackPowerValue(attType);
|
APbonus += GetTotalAttackPowerValue(attType);
|
||||||
DoneTotal += (int)(stack * ApCoeffMod * APbonus);
|
DoneTotal += (int)(stack * ApCoeffMod * APbonus);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user