Core/Spells: dropped spell_bonus_data table and use the dbc internal data to calculate ap and sp bonus values

* some spells have a special formula in their tooltips, which need manual scripting via the CalcDamage and CalcHealing hooks respectively
This commit is contained in:
Ovahlord committed 2025-06-08 15:16:17 +02:00
1 parent 373dd1b6ac
commit 5c9ecf27e9
15 files changed
+182 -252

No files matched your search

+1 -1
View File
@@ -589,7 +589,7 @@ enum RBACPermissions
RBAC_PERM_COMMAND_RELOAD_SMART_SCRIPTS = 689,
RBAC_PERM_COMMAND_RELOAD_SPELL_REQUIRED = 690,
RBAC_PERM_COMMAND_RELOAD_SPELL_AREA = 691,
RBAC_PERM_COMMAND_RELOAD_SPELL_BONUS_DATA = 692,
RBAC_PERM_COMMAND_RELOAD_SPELL_BONUS_DATA = 692, // unused in 4.3.4
RBAC_PERM_COMMAND_RELOAD_SPELL_GROUP = 693,
RBAC_PERM_COMMAND_RELOAD_SPELL_LEARN_SPELL = 694,
RBAC_PERM_COMMAND_RELOAD_SPELL_LOOT_TEMPLATE = 695,
+28 -70
View File
@@ -1207,7 +1207,7 @@ void Unit::CalculateMeleeDamage(Unit* victim, CalcDamageInfo* damageInfo, Weapon
uint32 damage = 0;
damage += CalculateDamage(damageInfo->AttackType, false, true);
// Add melee damage bonus
damage = MeleeDamageBonusDone(damageInfo->Target, damage, damageInfo->AttackType, DIRECT_DAMAGE, nullptr, MECHANIC_NONE, true, SpellSchoolMask(damageInfo->DamageSchoolMask));
damage = MeleeDamageBonusDone(damageInfo->Target, damage, damageInfo->AttackType, DIRECT_DAMAGE, nullptr, MECHANIC_NONE, SpellSchoolMask(damageInfo->DamageSchoolMask));
damage = damageInfo->Target->MeleeDamageBonusTaken(this, damage, damageInfo->AttackType, nullptr, SpellSchoolMask(damageInfo->DamageSchoolMask));
// Script Hook For CalculateMeleeDamage -- Allow scripts to change the Damage pre class mitigation calculations
@@ -6382,63 +6382,48 @@ int32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, int3
break;
}
// Check for table values
float spellPowerCoeff = spellProto->Effects[effIndex].BonusMultiplier;
float attackPowerCoeff = spellProto->BonusCoefficient;
WeaponAttackType const attType = [&]()
if (spellProto->BonusCoefficientFromAP > 0.0f)
{
if ((spellProto->IsRangedWeaponSpell() && spellProto->DmgClass != SPELL_DAMAGE_CLASS_MELEE))
return RANGED_ATTACK;
if (spellProto->HasAttribute(SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON) && !spellProto->HasAttribute(SPELL_ATTR3_REQUIRES_MAIN_HAND_WEAPON))
return OFF_ATTACK;
return BASE_ATTACK;
}();
if (SpellBonusEntry const* bonus = sSpellMgr->GetSpellBonusData(spellProto->Id))
{
if (damagetype == DOT)
float ApCoeffMod = spellProto->BonusCoefficientFromAP;
if (Player* modOwner = GetSpellModOwner())
{
spellPowerCoeff = bonus->dot_damage;
attackPowerCoeff = bonus->ap_dot_bonus;
ApCoeffMod *= 100.0f;
modOwner->ApplySpellMod(spellProto, SpellModOp::BonusCoefficient, ApCoeffMod);
ApCoeffMod /= 100.0f;
}
else
WeaponAttackType const attType = [&]()
{
spellPowerCoeff = bonus->direct_damage;
attackPowerCoeff = bonus->ap_bonus;
}
}
if ((spellProto->IsRangedWeaponSpell() && spellProto->DmgClass != SPELL_DAMAGE_CLASS_MELEE))
return RANGED_ATTACK;
if (spellPowerCoeff > 0.f)
spellPowerCoeff = spellProto->CalculateScaledCoefficient(this, spellPowerCoeff);
if (spellProto->HasAttribute(SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON) && !spellProto->HasAttribute(SPELL_ATTR3_REQUIRES_MAIN_HAND_WEAPON))
return OFF_ATTACK;
if (attackPowerCoeff > 0.f)
{
float APbonus = float(victim->GetTotalAuraModifier(attType == BASE_ATTACK ? SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS : SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS));
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(attackPowerCoeff * stack * APbonus);
DoneTotal += int32(stack * ApCoeffMod * APbonus);
}
// Default calculation
if (DoneAdvertisedBenefit)
{
if (spellPowerCoeff < 0.f)
spellPowerCoeff = CalculateDefaultCoefficient(spellProto, damagetype); // As wowwiki says: C = (Cast Time / 3.5)
float coeff = spellProto->Effects[effIndex].BonusMultiplier * spellProto->GetSpellScalingMultiplier(getLevel(), false);
if (Player* modOwner = GetSpellModOwner())
{
spellPowerCoeff *= 100.0f;
modOwner->ApplySpellMod(spellProto, SpellModOp::BonusCoefficient, spellPowerCoeff);
spellPowerCoeff /= 100.0f;
coeff *= 100.0f;
modOwner->ApplySpellMod(spellProto, SpellModOp::BonusCoefficient, coeff);
coeff /= 100.0f;
}
DoneTotal += int32(DoneAdvertisedBenefit * spellPowerCoeff * stack);
DoneTotal += int32(DoneAdvertisedBenefit * coeff * stack);
}
callDamageScript(pdamage, DoneTotal, DoneTotalMod);
float tmpDamage = float(pdamage + DoneTotal) * DoneTotalMod;
// apply spellmod to Done damage (flat and pct)
@@ -7108,34 +7093,19 @@ int32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, int
// Check for table values
float coeff = spellProto->Effects[effIndex].BonusMultiplier;
if (SpellBonusEntry const* bonus = sSpellMgr->GetSpellBonusData(spellProto->Id))
if (spellProto->BonusCoefficientFromAP > 0.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));
APbonus += GetTotalAttackPowerValue(attType);
if (damagetype == DOT)
{
coeff = bonus->dot_damage;
if (bonus->ap_dot_bonus > 0)
if (bonus->ap_dot_bonus > 0)
DoneTotal += int32(bonus->ap_dot_bonus * stack * APbonus);
}
else
{
coeff = bonus->direct_damage;
if (bonus->ap_bonus > 0)
DoneTotal += int32(bonus->ap_bonus * stack * APbonus);
}
DoneTotal += int32(spellProto->BonusCoefficientFromAP * stack * APbonus);
}
// Default calculation
if (DoneAdvertisedBenefit)
{
if (coeff < 0.f)
coeff = CalculateDefaultCoefficient(spellProto, damagetype) * 1.88f; // As wowwiki says: C = (Cast Time / 3.5) * 1.88 (for healing spells)
float coeff = spellProto->Effects[effIndex].BonusMultiplier * spellProto->GetSpellScalingMultiplier(getLevel(), false);
if (Player* modOwner = GetSpellModOwner())
{
coeff *= 100.0f;
@@ -7585,7 +7555,7 @@ bool Unit::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index, Worl
return false;
}
int32 Unit::MeleeDamageBonusDone(Unit* victim, int32 damage, WeaponAttackType attType, DamageEffectType damagetype, SpellInfo const* spellProto /*= nullptr*/, Mechanics mechanic /*= MECHANIC_NONE*/, bool useSpellBonusData /*= true*/, SpellSchoolMask damageSchoolMask /*= SPELL_SCHOOL_MASK_NORMAL*/, Spell* spell /*= nullptr*/, AuraEffect const* aurEff /*= nullptr*/)
int32 Unit::MeleeDamageBonusDone(Unit* victim, int32 damage, WeaponAttackType attType, DamageEffectType damagetype, SpellInfo const* spellProto /*= nullptr*/, Mechanics mechanic /*= MECHANIC_NONE*/, SpellSchoolMask damageSchoolMask /*= SPELL_SCHOOL_MASK_NORMAL*/, Spell* spell /*= nullptr*/, AuraEffect const* aurEff /*= nullptr*/)
{
if (!victim || damage == 0)
return 0;
@@ -7625,18 +7595,6 @@ int32 Unit::MeleeDamageBonusDone(Unit* victim, int32 damage, WeaponAttackType at
DoneFlatBenefit += int32(APbonus / 14.0f * GetAPMultiplier(attType, normalized));
}
if (spellProto && useSpellBonusData)
{
float attackPowerCoeff = spellProto->BonusCoefficient;
// Check for table values
if (SpellBonusEntry const* bonus = sSpellMgr->GetSpellBonusData(spellProto->Id))
attackPowerCoeff = bonus->ap_bonus;
if (attackPowerCoeff > 0.f)
DoneFlatBenefit += attackPowerCoeff * GetTotalAttackPowerValue(attType);
}
// Done total percent damage auras
float DoneTotalMod = 1.0f;
+1 -1
View File
@@ -1570,7 +1570,7 @@ class TC_GAME_API Unit : public WorldObject
float SpellHealingPctDone(Unit* victim, SpellInfo const* spellProto) const;
int32 SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, int32 healamount, DamageEffectType damagetype) const;
int32 MeleeDamageBonusDone(Unit* pVictim, int32 damage, WeaponAttackType attType, DamageEffectType damagetype, SpellInfo const* spellProto = nullptr, Mechanics mechanic = MECHANIC_NONE, bool useSpellBonusData = true, SpellSchoolMask damageSchoolMask = SPELL_SCHOOL_MASK_NORMAL, Spell* spell = nullptr, AuraEffect const* aurEff = nullptr);
int32 MeleeDamageBonusDone(Unit* pVictim, int32 damage, WeaponAttackType attType, DamageEffectType damagetype, SpellInfo const* spellProto = nullptr, Mechanics mechanic = MECHANIC_NONE, SpellSchoolMask damageSchoolMask = SPELL_SCHOOL_MASK_NORMAL, Spell* spell = nullptr, AuraEffect const* aurEff = nullptr);
int32 MeleeDamageBonusTaken(Unit* attacker, int32 pdamage, WeaponAttackType attType, SpellInfo const* spellProto = nullptr, SpellSchoolMask damageSchoolMask = SPELL_SCHOOL_MASK_NORMAL);
bool IsBlockCritical() const;
+4 -19
View File
@@ -2784,14 +2784,14 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex)
{
case SPELL_EFFECT_WEAPON_DAMAGE:
case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL:
fixed_bonus += damage;
fixed_bonus += CalculateDamage(j, unitTarget);
break;
case SPELL_EFFECT_NORMALIZED_WEAPON_DMG:
fixed_bonus += damage;
fixed_bonus += CalculateDamage(j, unitTarget);
normalized = true;
break;
case SPELL_EFFECT_WEAPON_PERCENT_DAMAGE:
ApplyPct(weaponDamagePercentMod, damage);
ApplyPct(weaponDamagePercentMod, CalculateDamage(j, unitTarget));
break;
default:
continue; // not weapon damage effect, just skip
@@ -2805,21 +2805,6 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex)
{
switch (m_spellInfo->SpellFamilyName)
{
case SPELLFAMILY_ROGUE:
{
// Hemorrhage
if (m_spellInfo->SpellFamilyFlags[0] & 0x2000000)
{
if (unitCaster->GetTypeId() == TYPEID_PLAYER)
unitCaster->ToPlayer()->AddComboPoints(unitTarget, 1, this);
// 45% more damage with daggers
if (unitCaster->GetTypeId() == TYPEID_PLAYER)
if (Item* item = unitCaster->ToPlayer()->GetWeaponForAttack(m_attackType, true))
if (item->GetTemplate()->GetSubClass() == ITEM_SUBCLASS_WEAPON_DAGGER)
totalDamagePercentMod *= 1.45f;
}
break;
}
case SPELLFAMILY_SHAMAN:
{
// Skyshatter Harness item set bonus
@@ -2948,7 +2933,7 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex)
weaponDamage = std::max(weaponDamage, 0);
// Add melee damage bonuses (also check for negative)
weaponDamage = unitCaster->MeleeDamageBonusDone(unitTarget, weaponDamage, m_attackType, SPELL_DIRECT_DAMAGE, m_spellInfo, mechanic, !useWeaponDamage, m_spellSchoolMask, this);
weaponDamage = unitCaster->MeleeDamageBonusDone(unitTarget, weaponDamage, m_attackType, SPELL_DIRECT_DAMAGE, m_spellInfo, mechanic, m_spellSchoolMask, this);
m_damage += unitTarget->MeleeDamageBonusTaken(unitCaster, weaponDamage, m_attackType, m_spellInfo);
}
+1 -1
View File
@@ -890,7 +890,7 @@ SpellInfo::SpellInfo(SpellEntry const* spellEntry, SpellEffectEntry const** effe
SchoolMask = spellEntry->SchoolMask;
RuneCostID = spellEntry->RuneCostID;
SpellDifficultyId = spellEntry->Difficulty;
BonusCoefficient = spellEntry->BonusCoefficient;
BonusCoefficientFromAP = spellEntry->BonusCoefficient;
SpellScalingId = spellEntry->ScalingID;
SpellAuraOptionsId = spellEntry->AuraOptionsID;
SpellAuraRestrictionsId = spellEntry->AuraRestrictionsID;
+1 -1
View File
@@ -423,7 +423,7 @@ class TC_GAME_API SpellInfo
int32 AreaGroupId;
uint32 SchoolMask;
uint32 SpellDifficultyId;
float BonusCoefficient;
float BonusCoefficientFromAP;
uint32 SpellScalingId;
uint32 SpellAuraOptionsId;
uint32 SpellAuraRestrictionsId;
+1 -56
View File
@@ -571,22 +571,6 @@ bool SpellMgr::CanSpellTriggerProcOnEvent(SpellProcEntry const& procEntry, ProcE
return true;
}
SpellBonusEntry const* SpellMgr::GetSpellBonusData(uint32 spellId) const
{
// Lookup data
SpellBonusMap::const_iterator itr = mSpellBonusMap.find(spellId);
if (itr != mSpellBonusMap.end())
return &itr->second;
// Not found, try lookup for 1 spell rank if exist
if (uint32 rank_1 = GetFirstSpellInChain(spellId))
{
SpellBonusMap::const_iterator itr2 = mSpellBonusMap.find(rank_1);
if (itr2 != mSpellBonusMap.end())
return &itr2->second;
}
return nullptr;
}
SpellThreatEntry const* SpellMgr::GetSpellThreatEntry(uint32 spellID) const
{
SpellThreatMap::const_iterator itr = mSpellThreatMap.find(spellID);
@@ -1925,45 +1909,6 @@ void SpellMgr::LoadSpellProcs()
TC_LOG_INFO("server.loading", ">> Generated spell proc data for %u spells in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
}
void SpellMgr::LoadSpellBonuses()
{
uint32 oldMSTime = getMSTime();
mSpellBonusMap.clear(); // need for reload case
// 0 1 2 3 4
QueryResult result = WorldDatabase.Query("SELECT entry, direct_bonus, dot_bonus, ap_bonus, ap_dot_bonus FROM spell_bonus_data");
if (!result)
{
TC_LOG_INFO("server.loading", ">> Loaded 0 spell bonus data. DB table `spell_bonus_data` is empty.");
return;
}
uint32 count = 0;
do
{
Field* fields = result->Fetch();
uint32 entry = fields[0].GetUInt32();
SpellInfo const* spell = GetSpellInfo(entry);
if (!spell)
{
TC_LOG_ERROR("sql.sql", "The spell %u listed in `spell_bonus_data` does not exist.", entry);
continue;
}
SpellBonusEntry& sbe = mSpellBonusMap[entry];
sbe.direct_damage = fields[1].GetFloat();
sbe.dot_damage = fields[2].GetFloat();
sbe.ap_bonus = fields[3].GetFloat();
sbe.ap_dot_bonus = fields[4].GetFloat();
++count;
} while (result->NextRow());
TC_LOG_INFO("server.loading", ">> Loaded %u extra spell bonus data in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
}
void SpellMgr::LoadSpellThreats()
{
uint32 oldMSTime = getMSTime();
@@ -3499,7 +3444,7 @@ void SpellMgr::LoadSpellInfoCorrections()
47134 // Quest Complete
}, [](SpellInfo* spellInfo)
{
//! HACK: This spell break quest complete for alliance and on retail not used °_O
//! HACK: This spell break quest complete for alliance and on retail not used �_O
spellInfo->Effects[EFFECT_0].Effect = 0;
});
-15
View File
@@ -290,16 +290,6 @@ struct SpellEnchantProcEntry
typedef std::unordered_map<uint32, SpellEnchantProcEntry> SpellEnchantProcEventMap;
struct SpellBonusEntry
{
float direct_damage;
float dot_damage;
float ap_bonus;
float ap_dot_bonus;
};
typedef std::unordered_map<uint32, SpellBonusEntry> SpellBonusMap;
enum SpellGroup
{
SPELL_GROUP_NONE = 0,
@@ -662,9 +652,6 @@ class TC_GAME_API SpellMgr
SpellProcEntry const* GetSpellProcEntry(uint32 spellId) const;
static bool CanSpellTriggerProcOnEvent(SpellProcEntry const& procEntry, ProcEventInfo& eventInfo);
// Spell bonus data table
SpellBonusEntry const* GetSpellBonusData(uint32 spellId) const;
// Spell threat table
SpellThreatEntry const* GetSpellThreatEntry(uint32 spellID) const;
@@ -716,7 +703,6 @@ class TC_GAME_API SpellMgr
void LoadSpellGroups();
void LoadSpellGroupStackRules();
void LoadSpellProcs();
void LoadSpellBonuses();
void LoadSpellThreats();
void LoadSkillLineAbilityMap();
void LoadSpellPetAuras();
@@ -748,7 +734,6 @@ class TC_GAME_API SpellMgr
SpellGroupStackMap mSpellGroupStack;
SameEffectStackMap mSpellSameEffectStack;
SpellProcMap mSpellProcMap;
SpellBonusMap mSpellBonusMap;
SpellThreatMap mSpellThreatMap;
SpellPetAuraMap mSpellPetAuraMap;
SpellLinkedMap mSpellLinkedMap;
-3
View File
@@ -1847,9 +1847,6 @@ void World::SetInitialWorldSettings()
TC_LOG_INFO("server.loading", "Loading Spell Proc conditions and data...");
sSpellMgr->LoadSpellProcs();
TC_LOG_INFO("server.loading", "Loading Spell Bonus Data...");
sSpellMgr->LoadSpellBonuses();
TC_LOG_INFO("server.loading", "Loading Aggro Spells Definitions...");
sSpellMgr->LoadSpellThreats();
-10
View File
@@ -142,7 +142,6 @@ public:
{ "smart_scripts", rbac::RBAC_PERM_COMMAND_RELOAD_SMART_SCRIPTS, true, &HandleReloadSmartScripts, "" },
{ "spell_required", rbac::RBAC_PERM_COMMAND_RELOAD_SPELL_REQUIRED, true, &HandleReloadSpellRequiredCommand, "" },
{ "spell_area", rbac::RBAC_PERM_COMMAND_RELOAD_SPELL_AREA, true, &HandleReloadSpellAreaCommand, "" },
{ "spell_bonus_data", rbac::RBAC_PERM_COMMAND_RELOAD_SPELL_BONUS_DATA, true, &HandleReloadSpellBonusesCommand, "" },
{ "spell_group", rbac::RBAC_PERM_COMMAND_RELOAD_SPELL_GROUP, true, &HandleReloadSpellGroupsCommand, "" },
{ "spell_learn_spell", rbac::RBAC_PERM_COMMAND_RELOAD_SPELL_LEARN_SPELL, true, &HandleReloadSpellLearnSpellCommand, "" },
{ "spell_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_SPELL_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesSpellCommand, "" },
@@ -283,7 +282,6 @@ public:
HandleReloadSpellLearnSpellCommand(handler, "a");
HandleReloadSpellLinkedSpellCommand(handler, "a");
HandleReloadSpellProcsCommand(handler, "a");
HandleReloadSpellBonusesCommand(handler, "a");
HandleReloadSpellTargetPositionCommand(handler, "a");
HandleReloadSpellThreatsCommand(handler, "a");
HandleReloadSpellGroupStackRulesCommand(handler, "a");
@@ -854,14 +852,6 @@ public:
return true;
}
static bool HandleReloadSpellBonusesCommand(ChatHandler* handler, char const* /*args*/)
{
TC_LOG_INFO("misc", "Re-Loading Spell Bonus Data...");
sSpellMgr->LoadSpellBonuses();
handler->SendGlobalGMSysMessage("DB table `spell_bonus_data` (spell damage/healing coefficients) reloaded.");
return true;
}
static bool HandleReloadSpellTargetPositionCommand(ChatHandler* handler, char const* /*args*/)
{
TC_LOG_INFO("misc", "Re-Loading Spell target coordinates...");
+16 -1
View File
@@ -1863,6 +1863,20 @@ class spell_dk_strangulate : public SpellScript
OnEffectHitTarget.Register(&spell_dk_strangulate::HandleCreatureInterrupt, EFFECT_0, SPELL_EFFECT_APPLY_AURA);
}
};
// 45477 - Icy Touch
class spell_dk_icy_touch : public SpellScript
{
void CalculateDamage(Unit* /*victim*/, int32& /*damage*/, int32& flatMod, float& /*pctMod*/)
{
flatMod += GetCaster()->GetTotalAttackPowerValue(BASE_ATTACK) * 0.2f;
}
void Register() override
{
CalcDamage.Register(&spell_dk_icy_touch::CalculateDamage);
}
};
}
void AddSC_deathknight_spell_scripts()
@@ -1901,6 +1915,7 @@ void AddSC_deathknight_spell_scripts()
RegisterSpellScript(spell_dk_ghoul_taunt);
RegisterSpellScript(spell_dk_howling_blast);
RegisterSpellScript(spell_dk_icebound_fortitude);
RegisterSpellScript(spell_dk_icy_touch);
RegisterSpellScript(spell_dk_improved_presence);
RegisterSpellScript(spell_dk_killing_machine);
RegisterSpellScript(spell_dk_necrotic_strike);
@@ -1920,4 +1935,4 @@ void AddSC_deathknight_spell_scripts()
RegisterSpellScript(spell_dk_unholy_command);
RegisterSpellScript(spell_dk_vampiric_blood);
RegisterSpellScript(spell_dk_will_of_the_necropolis);
}
}
+4 -8
View File
@@ -5108,18 +5108,14 @@ class spell_gen_wounded : public SpellScript
// 69041 - Rocket Barrage (Racial)
class spell_gen_rocket_barrage : public SpellScript
{
void HandleDamage(SpellEffIndex effIndex)
void CalculateDamage(Unit* /*victim*/, int32& /*damage*/, int32& flatMod, float& /*pctMod*/)
{
Unit* caster = GetCaster();
int32 basePoints = GetEffectValue() + caster->getLevel() * 2;
basePoints += caster->SpellBaseDamageBonusDone(GetSpellInfo()->GetSchoolMask()) * GetSpellInfo()->Effects[effIndex].BonusMultiplier;
basePoints += caster->GetTotalAttackPowerValue(caster->getClass() != CLASS_HUNTER ? BASE_ATTACK : RANGED_ATTACK) * GetSpellInfo()->BonusCoefficient;
SetEffectValue(basePoints);
flatMod += GetCaster()->getLevel() * 2;
}
void Register() override
{
OnEffectLaunchTarget.Register(&spell_gen_rocket_barrage::HandleDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
CalcDamage.Register(&spell_gen_rocket_barrage::CalculateDamage);
}
};
@@ -5494,4 +5490,4 @@ void AddSC_generic_spell_scripts()
RegisterSpellScript(spell_gen_vehicle_control_link);
RegisterSpellScript(spell_gen_polymorph_cast_visual);
RegisterSpellScript(spell_gen_prevent_emotes);
}
}
+22 -1
View File
@@ -137,6 +137,20 @@ class spell_hun_ancient_hysteria : public SpellScript
}
};
// 3044 - Arcane Shot
class spell_hun_arcane_shot : public SpellScript
{
void CalculateDamage(Unit* /*victim*/, int32& /*damage*/, int32& flatMod, float& /*pctMod*/)
{
flatMod += GetCaster()->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.0493f;
}
void Register() override
{
CalcDamage.Register(&spell_hun_arcane_shot::CalculateDamage);
}
};
// Universal helper to get the serpent sting aura of all variants of it (original and the procced versions of Serpent Spread)
static Aura* GetSerpentStingAura(Unit* target, ObjectGuid casterGUID)
{
@@ -655,6 +669,11 @@ class spell_hun_steady_shot : public SpellScript
return ValidateSpellInfo({ SPELL_HUNTER_STEADY_SHOT_FOCUS });
}
void CalculateDamage(Unit* /*victim*/, int32& /*damage*/, int32& flatMod, float& /*pctMod*/)
{
flatMod += GetCaster()->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.021f;
}
void HandleLaunch(SpellEffIndex /*effIndex*/)
{
Unit* caster = GetCaster();
@@ -676,6 +695,7 @@ class spell_hun_steady_shot : public SpellScript
void Register() override
{
CalcDamage.Register(&spell_hun_steady_shot::CalculateDamage);
OnEffectLaunch.Register(&spell_hun_steady_shot::HandleLaunch, EFFECT_0, SPELL_EFFECT_NORMALIZED_WEAPON_DMG);
}
};
@@ -1444,6 +1464,7 @@ void AddSC_hunter_spell_scripts()
{
using namespace Spells::Hunter;
RegisterSpellScript(spell_hun_ancient_hysteria);
RegisterSpellScript(spell_hun_arcane_shot);
RegisterSpellScript(spell_hun_camouflage);
RegisterSpellScript(spell_hun_camouflage_duration);
RegisterSpellScript(spell_hun_camouflage_triggered);
@@ -1484,4 +1505,4 @@ void AddSC_hunter_spell_scripts()
RegisterSpellScript(spell_hun_tnt);
RegisterSpellScript(spell_hun_trap_launcher);
RegisterSpellScript(spell_hun_wild_quiver);
}
}
+33 -1
View File
@@ -1286,6 +1286,37 @@ class spell_rog_gouge : public AuraScript
}
};
// 16511 - Hemorrhage
class spell_rog_hemorrhage : public SpellScript
{
bool Load() override
{
return GetCaster()->IsPlayer();
}
void CalculateDamage(Unit* /*victim*/, int32& /*damage*/, int32& /*flatMod*/, float& pctMod)
{
for (WeaponAttackType attType : { BASE_ATTACK, OFF_ATTACK })
{
// Dealing additional 45% damage when a dagger is equipped
if (Item* item = GetCaster()->ToPlayer()->GetWeaponForAttack(attType, true))
{
if (item->GetTemplate()->GetSubClass() == ITEM_SUBCLASS_WEAPON_DAGGER)
{
pctMod *= 1.45f;
return;
}
}
}
}
void Register() override
{
CalcDamage.Register(&spell_rog_hemorrhage::CalculateDamage);
}
};
// -11327 - Vanish
class spell_rog_vanish : public AuraScript
{
@@ -1388,6 +1419,7 @@ void AddSC_rogue_spell_scripts()
RegisterSpellScript(spell_rog_eviscerate);
RegisterSpellScript(spell_rog_glyph_of_hemorrhage);
RegisterSpellScript(spell_rog_gouge);
RegisterSpellScript(spell_rog_hemorrhage);
RegisterSpellScript(spell_rog_improved_expose_armor);
new spell_rog_killing_spree();
RegisterSpellScript(spell_rog_main_gauche);
@@ -1410,4 +1442,4 @@ void AddSC_rogue_spell_scripts()
RegisterSpellScript(spell_rog_honor_among_thieves);
RegisterSpellScript(spell_rog_vanish);
RegisterSpellScript(spell_rogue_venomous_wounds);
}
}
+70 -64
View File
@@ -48,6 +48,7 @@ enum WarriorSpells
SPELL_WARRIOR_DEEP_WOUNDS_PERIODIC = 12721,
SPELL_WARRIOR_EXECUTE = 20647,
SPELL_WARRIOR_GLYPH_OF_EXECUTION = 58367,
SPELL_WARRIOR_IMPENDING_VICTORY = 80128,
SPELL_WARRIOR_INTERCEPT = 20252,
SPELL_WARRIOR_JUGGERNAUT_CRIT_BONUS_BUFF = 65156,
SPELL_WARRIOR_JUGGERNAUT_CRIT_BONUS_TALENT = 64976,
@@ -95,10 +96,9 @@ class spell_warr_bloodthirst : public SpellScript
return ValidateSpellInfo({ SPELL_WARRIOR_BLOODTHIRST });
}
void HandleDamage(SpellEffIndex /*effIndex*/)
void CalculateDamage(Unit* /*victim*/, int32& damage, int32& /*flatMod*/, float& /*pctMod*/)
{
if (Unit* caster = GetCaster())
SetEffectValue(CalculatePct(caster->GetTotalAttackPowerValue(BASE_ATTACK) * GetEffectValue(), 1));
damage = CalculatePct(GetCaster()->GetTotalAttackPowerValue(BASE_ATTACK), damage);
}
void HandleBloodthirstHealEffect()
@@ -108,7 +108,7 @@ class spell_warr_bloodthirst : public SpellScript
void Register() override
{
OnEffectLaunchTarget.Register(&spell_warr_bloodthirst::HandleDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
CalcDamage.Register(&spell_warr_bloodthirst::CalculateDamage);
AfterHit.Register(&spell_warr_bloodthirst::HandleBloodthirstHealEffect);
}
};
@@ -175,16 +175,17 @@ class spell_warr_charge : public SpellScript
};
/// Updated 4.3.4
// 12809 - Concussion Blow
class spell_warr_concussion_blow : public SpellScript
{
void HandleDummy(SpellEffIndex /*effIndex*/)
void CalculateDamage(Unit* victim, int32& damage, int32& flatMod, float& pctMod)
{
SetEffectValue(CalculatePct(GetCaster()->GetTotalAttackPowerValue(BASE_ATTACK), GetSpellInfo()->Effects[EFFECT_2].CalcValue()));
damage = CalculatePct(GetCaster()->GetTotalAttackPowerValue(BASE_ATTACK), GetSpellInfo()->Effects[EFFECT_2].CalcValue());
}
void Register() override
{
OnEffectLaunchTarget.Register(&spell_warr_concussion_blow::HandleDummy, EFFECT_1, SPELL_EFFECT_SCHOOL_DAMAGE);
CalcDamage.Register(&spell_warr_concussion_blow::CalculateDamage);
}
};
@@ -237,6 +238,7 @@ class spell_warr_deep_wounds : public AuraScript
};
/// Updated 4.3.4
// 5308 - Execute
class spell_warr_execute : public SpellScript
{
bool Validate(SpellInfo const* /*spellInfo*/) override
@@ -244,36 +246,50 @@ class spell_warr_execute : public SpellScript
return ValidateSpellInfo({ SPELL_WARRIOR_SUDDEN_DEATH });
}
void HandleEffect(SpellEffIndex /*effIndex*/)
// Formula: ${10+$AP*0.437*$m1/100} plus up to $m2 additional rage for up to ${10+$AP*0.437*$m1/100} extra damage
void CalculateDamage(Unit* /*victim*/, int32& damage, int32& /*flatMod*/, float& /*pctMod*/)
{
Unit* caster = GetCaster();
if (!GetHitUnit())
int apPct = GetSpellInfo()->Effects[EFFECT_0].CalcValue(caster);
damage = static_cast<int32>(10 + CalculatePct(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.437, apPct));
int32 additionalRageCap = GetSpellInfo()->Effects[EFFECT_1].CalcValue(caster) * 10;
if (!additionalRageCap)
return;
// Formula taken from DBC: "${10+$AP*0.437*$m1/100}"
int32 bp = int32(10 + caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.437f * GetEffectValue() / 100.0f);
int32 additionalRage = std::min<int32>(caster->GetPower(POWER_RAGE) - GetSpell()->GetPowerCost(), additionalRageCap);
// Up to 20 additional Rage can be converted into damage
// Formula taken from DBC: "to ${$ap*0.874*$m1/100-1}"
int32 additionalRage = std::min<int32>(caster->GetPower(POWER_RAGE) - GetSpell()->GetPowerCost(), GetSpellInfo()->Effects[EFFECT_1].CalcValue() * 10);
if (additionalRage > 0)
bp += (additionalRage * (caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.874f * GetEffectValue() / 100.0f - 1) / 200);
// Based on the pct of extra rage consumed the damage will be increased
float extraRagePct = additionalRage / additionalRageCap;
int32 bonusDamage = std::max<int32>(0, CalculatePct(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.874f, apPct) - 1);
SetEffectValue(bp);
damage += bonusDamage * extraRagePct;
_additionalRageConsumed = additionalRage;
}
void ConsumeAdditionalRage()
{
if (_additionalRageConsumed == 0)
return;
int32 preservedRage = 0;
// Sudden Death bonus (keep 5/10 Rage after using Execute)
if (Aura const* aura = caster->GetAuraOfRankedSpell(SPELL_WARRIOR_SUDDEN_DEATH, caster->GetGUID()))
int32 preservedRage = 0;
if (Aura const* aura = GetCaster()->GetAuraOfRankedSpell(SPELL_WARRIOR_SUDDEN_DEATH, GetCaster()->GetGUID()))
if (AuraEffect const* suddenDeath = aura->GetEffect(EFFECT_0))
preservedRage = std::min<int32>(suddenDeath->GetAmount() * 10, GetSpell()->GetPowerCost() + additionalRage);
preservedRage = std::min<int32>(suddenDeath->GetAmount() * 10, GetSpell()->GetPowerCost() + _additionalRageConsumed);
caster->ModifyPower(POWER_RAGE, -(additionalRage - preservedRage));
GetCaster()->ModifyPower(POWER_RAGE, -(_additionalRageConsumed - preservedRage));
}
void Register() override
{
OnEffectLaunchTarget.Register(&spell_warr_execute::HandleEffect, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
CalcDamage.Register(&spell_warr_execute::CalculateDamage);
AfterCast.Register(&spell_warr_execute::ConsumeAdditionalRage);
}
private:
int32 _additionalRageConsumed = 0;
};
// 58387 - Glyph of Sunder Armor
@@ -479,6 +495,7 @@ class spell_warr_shattering_throw : public SpellScript
};
/// Updated 4.3.4
// 1464 - Slam
class spell_warr_slam : public SpellScript
{
bool Validate(SpellInfo const* /*spellInfo*/) override
@@ -535,27 +552,21 @@ class spell_warr_slam_triggered : public SpellScript
_affectedByBloodsurge = GetCaster()->GetAuraEffect(SPELL_AURA_ADD_PCT_MODIFIER, SPELLFAMILY_WARRIOR, 0x0, 0x1000000, 0x0, GetCaster()->GetGUID()) != nullptr;
}
void HandleBonusDamage(SpellEffIndex /*effIndex*/)
void CalculateDamage(Unit* /*victim*/, int32& /*damage*/, int32& /*flatMod*/, float& pctMod)
{
Unit* caster = GetCaster();
if (!caster)
// Bloodsurge damage bonus
if (!_affectedByBloodsurge)
return;
int32 basePoints = GetEffectValue();
// Bloodsurge damage bonus
if (_affectedByBloodsurge)
if (Aura const* aura = caster->GetAuraOfRankedSpell(SPELL_WARRIOR_BLOODSURGE_R1))
if (AuraEffect const* effect = aura->GetEffect(EFFECT_0))
AddPct(basePoints, effect->GetAmount());
SetEffectValue(basePoints);
if (Aura const* aura = GetCaster()->GetAuraOfRankedSpell(SPELL_WARRIOR_BLOODSURGE_R1))
if (AuraEffect const* effect = aura->GetEffect(EFFECT_0))
AddPct(pctMod, effect->GetAmount());
}
void Register() override
{
BeforeCast.Register(&spell_warr_slam_triggered::HandleBeforeCast);
OnEffectLaunchTarget.Register(&spell_warr_slam_triggered::HandleBonusDamage, EFFECT_1, SPELL_EFFECT_WEAPON_PERCENT_DAMAGE);
CalcDamage.Register(&spell_warr_slam_triggered::CalculateDamage);
}
private:
bool _affectedByBloodsurge = false;
@@ -688,7 +699,7 @@ private:
// -46951 - Sword and Board
class spell_warr_sword_and_board : public AuraScript
{private:
{
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_WARRIOR_SHIELD_SLAM });
@@ -719,39 +730,33 @@ class spell_warr_victory_rush : public SpellScript
});
}
void HandleDamage(SpellEffIndex /*effIndex*/)
// ${$AP*$m1/100}
void CalculateDamage(Unit* /*victim*/, int32& damage, int32& /*flatMod*/, float& /*pctMod*/)
{
SetEffectValue(CalculatePct(GetCaster()->GetTotalAttackPowerValue(BASE_ATTACK), GetSpellInfo()->Effects[EFFECT_0].CalcValue()));
damage = CalculatePct(GetCaster()->GetTotalAttackPowerValue(BASE_ATTACK), damage);
}
void HandleImpendingVictoryHeal(SpellEffIndex effIndex)
void CalculateHeal(Unit* /*victim*/, int32& heal, int32& /*flatMod*/, float& /*pctMod*/)
{
if (Unit* caster = GetCaster())
{
// Impending Victory also allows players to cast Victory Rush but with 5% healing effect only
if (caster->HasAura(SPELL_WARRIOR_VICTORIOUS_IMPENDING_VICTORY))
{
int32 damage = 5;
Unit* caster = GetCaster();
// Glyph: Victory Rush
if (Player* modOwner = caster->GetSpellModOwner())
modOwner->ApplySpellMod(GetSpellInfo(), SpellModOp::PointsIndex2, damage);
SetEffectValue(damage);
}
else
SetEffectValue(GetSpellInfo()->Effects[effIndex].CalcValue());
caster->RemoveAurasDueToSpell(SPELL_WARRIOR_VICTORIOUS);
caster->RemoveAurasDueToSpell(SPELL_WARRIOR_VICTORIOUS_IMPENDING_VICTORY);
}
// Impending Victory has a chance to allow casting Victory rush but it only heals for $s1% of our health
if (caster->HasAura(SPELL_WARRIOR_VICTORIOUS_IMPENDING_VICTORY, caster->GetGUID()))
if (AuraEffect const* impendingVictoryEff = caster->GetAuraEffectOfRankedSpell(SPELL_WARRIOR_VICTORIOUS_IMPENDING_VICTORY, EFFECT_0, caster->GetGUID()))
heal = caster->CountPctFromMaxHealth(impendingVictoryEff->GetAmount());
}
void RemoveVictorious()
{
GetCaster()->RemoveAurasDueToSpell(SPELL_WARRIOR_VICTORIOUS);
GetCaster()->RemoveAurasDueToSpell(SPELL_WARRIOR_VICTORIOUS_IMPENDING_VICTORY);
}
void Register() override
{
OnEffectLaunchTarget.Register(&spell_warr_victory_rush::HandleDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
OnEffectHitTarget.Register(&spell_warr_victory_rush::HandleImpendingVictoryHeal, EFFECT_2, SPELL_EFFECT_HEAL_PCT);
CalcDamage.Register(&spell_warr_victory_rush::CalculateDamage);
CalcHealing.Register(&spell_warr_victory_rush::CalculateHeal);
AfterCast.Register(&spell_warr_victory_rush::RemoveVictorious);
}
};
@@ -889,7 +894,7 @@ class spell_warr_thunder_clap : public SpellScript
OnEffectHitTarget.Register(&spell_warr_thunder_clap::HandleHit, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
}
private:
bool _allowRendSpread;
bool _allowRendSpread = false;
};
class spell_warr_shield_specialization : public AuraScript
@@ -932,17 +937,18 @@ class spell_warr_blood_craze : public AuraScript
// 46968 - Shockwave
class spell_warr_shockwave : public SpellScript
{
void HandleDamage(SpellEffIndex /*effIndex*/)
void CalculateDamage(Unit* /*victim*/, int32& damage, int32& /*flatMod*/, float& /*pctMod*/)
{
SetEffectValue(CalculatePct(GetCaster()->GetTotalAttackPowerValue(BASE_ATTACK), GetSpellInfo()->Effects[EFFECT_2].CalcValue()));
damage = CalculatePct(GetCaster()->GetTotalAttackPowerValue(BASE_ATTACK), GetSpellInfo()->Effects[EFFECT_2].CalcValue(GetCaster()));
}
void Register() override
{
OnEffectLaunchTarget.Register(&spell_warr_shockwave::HandleDamage, EFFECT_1, SPELL_EFFECT_SCHOOL_DAMAGE);
CalcDamage.Register(&spell_warr_shockwave::CalculateDamage);
}
};
// 20243 - Devastate
class spell_warr_devastate : public SpellScript
{
bool Validate(SpellInfo const* /*spellInfo*/) override
@@ -1133,4 +1139,4 @@ void AddSC_warrior_spell_scripts()
RegisterSpellScript(spell_warr_vigilance);
RegisterSpellScript(spell_warr_vigilance_trigger);
RegisterSpellScript(spell_warr_whirlwind);
}
}