Skip to content

Commit

Permalink
feat(Core/Items): Implemented elemental weapon damage. Source: Trinit… (
Browse files Browse the repository at this point in the history
#13050)

...yCore.
  • Loading branch information
UltraNix committed Oct 8, 2022
1 parent 02b3f74 commit e390087
Show file tree
Hide file tree
Showing 13 changed files with 770 additions and 279 deletions.
4 changes: 2 additions & 2 deletions src/server/game/Entities/Creature/Creature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2156,7 +2156,7 @@ void Creature::LoadSpellTemplateImmunity()
}
}

bool Creature::IsImmunedToSpell(SpellInfo const* spellInfo)
bool Creature::IsImmunedToSpell(SpellInfo const* spellInfo, Spell const* spell)
{
if (!spellInfo)
return false;
Expand All @@ -2178,7 +2178,7 @@ bool Creature::IsImmunedToSpell(SpellInfo const* spellInfo)
if (immunedToAllEffects)
return true;

return Unit::IsImmunedToSpell(spellInfo);
return Unit::IsImmunedToSpell(spellInfo, spell);
}

bool Creature::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) const
Expand Down
6 changes: 3 additions & 3 deletions src/server/game/Entities/Creature/Creature.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ class Creature : public Unit, public GridObject<Creature>, public MovableMapObje
[[nodiscard]] bool IsValidTrainerForPlayer(Player* player, uint32* npcFlags = nullptr) const;
bool CanCreatureAttack(Unit const* victim, bool skipDistCheck = false) const;
void LoadSpellTemplateImmunity();
bool IsImmunedToSpell(SpellInfo const* spellInfo) override;
bool IsImmunedToSpell(SpellInfo const* spellInfo, Spell const* spell = nullptr) override;

[[nodiscard]] bool HasMechanicTemplateImmunity(uint32 mask) const;
// redefine Unit::IsImmunedToSpell
Expand Down Expand Up @@ -155,7 +155,7 @@ class Creature : public Unit, public GridObject<Creature>, public MovableMapObje
return (getLevel() / 2 + uint32(GetStat(STAT_STRENGTH) / 20));
}

[[nodiscard]] SpellSchoolMask GetMeleeDamageSchoolMask() const override { return m_meleeDamageSchoolMask; }
[[nodiscard]] SpellSchoolMask GetMeleeDamageSchoolMask(WeaponAttackType /*attackType*/ = BASE_ATTACK, uint8 /*damageIndex*/ = 0) const override { return m_meleeDamageSchoolMask; }
void SetMeleeDamageSchool(SpellSchools school) { m_meleeDamageSchoolMask = SpellSchoolMask(1 << school); }

void _AddCreatureSpellCooldown(uint32 spell_id, uint16 categoryId, uint32 end_time);
Expand All @@ -178,7 +178,7 @@ class Creature : public Unit, public GridObject<Creature>, public MovableMapObje
void UpdateMaxHealth() override;
void UpdateMaxPower(Powers power) override;
void UpdateAttackPowerAndDamage(bool ranged = false) override;
void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage) override;
void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage, uint8 damageIndex) override;

void SetCanDualWield(bool value) override;
[[nodiscard]] int8 GetOriginalEquipmentId() const { return m_originalEquipmentId; }
Expand Down
97 changes: 54 additions & 43 deletions src/server/game/Entities/Player/Player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6740,21 +6740,11 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply
if (proto->ArcaneRes)
HandleStatModifier(UNIT_MOD_RESISTANCE_ARCANE, BASE_VALUE, float(proto->ArcaneRes), apply);

WeaponAttackType attType = BASE_ATTACK;

if (slot == EQUIPMENT_SLOT_RANGED && (
proto->InventoryType == INVTYPE_RANGED || proto->InventoryType == INVTYPE_THROWN ||
proto->InventoryType == INVTYPE_RANGEDRIGHT))
{
attType = RANGED_ATTACK;
}
else if (slot == EQUIPMENT_SLOT_OFFHAND)
uint8 attType = Player::GetAttackBySlot(slot);
if (attType != MAX_ATTACK)
{
attType = OFF_ATTACK;
}

if (CanUseAttackType(attType))
_ApplyWeaponDamage(slot, proto, ssv, apply);
}

// Druids get feral AP bonus from weapon dps (also use DPS from ScalingStatValue)
if (getClass() == CLASS_DRUID)
Expand Down Expand Up @@ -6797,45 +6787,56 @@ void Player::_ApplyWeaponDamage(uint8 slot, ItemTemplate const* proto, ScalingSt
ssv = ScalingStatValue ? sScalingStatValuesStore.LookupEntry(ssd_level) : nullptr;
}

WeaponAttackType attType = BASE_ATTACK;
float damage = 0.0f;

if (slot == EQUIPMENT_SLOT_RANGED && (
proto->InventoryType == INVTYPE_RANGED || proto->InventoryType == INVTYPE_THROWN ||
proto->InventoryType == INVTYPE_RANGEDRIGHT))
uint8 attType = Player::GetAttackBySlot(slot);
if (!IsInFeralForm() && apply && !CanUseAttackType(attType))
{
attType = RANGED_ATTACK;
return;
}
else if (slot == EQUIPMENT_SLOT_OFFHAND)

for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
{
attType = OFF_ATTACK;
}
float minDamage = proto->Damage[i].DamageMin;
float maxDamage = proto->Damage[i].DamageMax;

float minDamage = proto->Damage[0].DamageMin;
float maxDamage = proto->Damage[0].DamageMax;
// If set dpsMod in ScalingStatValue use it for min (70% from average), max (130% from average) damage
if (ssv)
{
int32 extraDPS = ssv->getDPSMod(ScalingStatValue);
if (extraDPS)
{
float average = extraDPS * proto->Delay / 1000.0f;
minDamage = 0.7f * average;
maxDamage = 1.3f * average;
}
}

// If set dpsMod in ScalingStatValue use it for min (70% from average), max (130% from average) damage
if (ssv)
{
int32 extraDPS = ssv->getDPSMod(ScalingStatValue);
if (extraDPS)
if (apply)
{
float average = extraDPS * proto->Delay / 1000.0f;
minDamage = 0.7f * average;
maxDamage = 1.3f * average;
if (minDamage > 0.f)
{
SetBaseWeaponDamage(WeaponAttackType(attType), MINDAMAGE, minDamage, i);
}

if (maxDamage > 0.f)
{
SetBaseWeaponDamage(WeaponAttackType(attType), MAXDAMAGE, maxDamage, i);
}
}
}

if (minDamage > 0)
if (!apply)
{
damage = apply ? minDamage : BASE_MINDAMAGE;
SetBaseWeaponDamage(attType, MINDAMAGE, damage);
}
for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
{
SetBaseWeaponDamage(WeaponAttackType(attType), MINDAMAGE, 0.f, i);
SetBaseWeaponDamage(WeaponAttackType(attType), MAXDAMAGE, 0.f, i);
}

if (maxDamage > 0)
{
damage = apply ? maxDamage : BASE_MAXDAMAGE;
SetBaseWeaponDamage(attType, MAXDAMAGE, damage);
if (attType == BASE_ATTACK)
{
SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, BASE_MINDAMAGE);
SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, BASE_MAXDAMAGE);
}
}

if (proto->Delay && !IsInFeralForm())
Expand All @@ -6852,8 +6853,18 @@ void Player::_ApplyWeaponDamage(uint8 slot, ItemTemplate const* proto, ScalingSt
if (IsInFeralForm())
return;

if (CanModifyStats() && (damage || proto->Delay))
UpdateDamagePhysical(attType);
if (CanModifyStats() && (GetWeaponDamageRange(WeaponAttackType(attType), MAXDAMAGE) || proto->Delay))
UpdateDamagePhysical(WeaponAttackType(attType));
}

SpellSchoolMask Player::GetMeleeDamageSchoolMask(WeaponAttackType attackType /*= BASE_ATTACK*/, uint8 damageIndex /*= 0*/) const
{
if (Item const* weapon = GetWeaponForAttack(attackType, true))
{
return SpellSchoolMask(1 << weapon->GetTemplate()->Damage[damageIndex].DamageType);
}

return SPELL_SCHOOL_MASK_NORMAL;
}

void Player::_ApplyWeaponDependentAuraMods(Item* item, WeaponAttackType attackType, bool apply)
Expand Down
4 changes: 3 additions & 1 deletion src/server/game/Entities/Player/Player.h
Original file line number Diff line number Diff line change
Expand Up @@ -1905,7 +1905,7 @@ class Player : public Unit, public GridObject<Player>
void UpdateRating(CombatRating cr);
void UpdateAllRatings();

void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage) override;
void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage, uint8 damageIndex) override;

void UpdateDefenseBonusesMod();
inline void RecalculateRating(CombatRating cr) { ApplyRatingMod(cr, 0, true);}
Expand Down Expand Up @@ -2147,6 +2147,8 @@ class Player : public Unit, public GridObject<Player>

void ResetAllPowers();

SpellSchoolMask GetMeleeDamageSchoolMask(WeaponAttackType attackType = BASE_ATTACK, uint8 damageIndex = 0) const override;

void _ApplyWeaponDependentAuraMods(Item* item, WeaponAttackType attackType, bool apply);
void _ApplyWeaponDependentAuraCritMod(Item* item, WeaponAttackType attackType, AuraEffect const* aura, bool apply);
void _ApplyWeaponDependentAuraDamageMod(Item* item, WeaponAttackType attackType, AuraEffect const* aura, bool apply);
Expand Down
51 changes: 40 additions & 11 deletions src/server/game/Entities/Unit/StatSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,25 +59,31 @@ void Unit::UpdateAllResistances()

void Unit::UpdateDamagePhysical(WeaponAttackType attType)
{
float minDamage = 0.0f;
float maxDamage = 0.0f;
float totalMin = 0.f;
float totalMax = 0.f;

CalculateMinMaxDamage(attType, false, true, minDamage, maxDamage);
for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
{
float tmpMin, tmpMax;
CalculateMinMaxDamage(attType, false, true, tmpMin, tmpMax, i);
totalMin += tmpMin;
totalMax += tmpMax;
}

switch (attType)
{
case BASE_ATTACK:
default:
SetStatFloatValue(UNIT_FIELD_MINDAMAGE, minDamage);
SetStatFloatValue(UNIT_FIELD_MAXDAMAGE, maxDamage);
SetStatFloatValue(UNIT_FIELD_MINDAMAGE, totalMin);
SetStatFloatValue(UNIT_FIELD_MAXDAMAGE, totalMax);
break;
case OFF_ATTACK:
SetStatFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE, minDamage);
SetStatFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE, maxDamage);
SetStatFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE, totalMin);
SetStatFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE, totalMax);
break;
case RANGED_ATTACK:
SetStatFloatValue(UNIT_FIELD_MINRANGEDDAMAGE, minDamage);
SetStatFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE, maxDamage);
SetStatFloatValue(UNIT_FIELD_MINRANGEDDAMAGE, totalMin);
SetStatFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE, totalMax);
break;
}
}
Expand Down Expand Up @@ -525,8 +531,23 @@ void Player::UpdateShieldBlockValue()
SetUInt32Value(PLAYER_SHIELD_BLOCK, GetShieldBlockValue());
}

void Player::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage)
void Player::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage, uint8 damageIndex)
{
// Only proto damage, not affected by any mods
if (damageIndex != 0)
{
minDamage = 0.0f;
maxDamage = 0.0f;

if (!IsInFeralForm() && CanUseAttackType(attType))
{
minDamage = GetWeaponDamageRange(attType, MINDAMAGE, damageIndex);
maxDamage = GetWeaponDamageRange(attType, MAXDAMAGE, damageIndex);
}

return;
}

UnitMods unitMod;

switch (attType)
Expand Down Expand Up @@ -1075,8 +1096,16 @@ void Creature::UpdateAttackPowerAndDamage(bool ranged)
}
}

void Creature::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage)
void Creature::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage, uint8 damageIndex /*= 0*/)
{
// creatures only have one damage
if (damageIndex != 0)
{
minDamage = 0.f;
maxDamage = 0.f;
return;
}

UnitMods unitMod;
float variance = 1.0f;
switch (attType)
Expand Down

0 comments on commit e390087

Please sign in to comment.