fix(Core/Spells): Implement TrinityCore spell_group and spell_group_stack_rules (#23346)

Co-authored-by: treeston <treeston.mmoc@gmail.com>
Co-authored-by: Trisjdc <trisjdc@gmail.com>
Co-authored-by: QAston <none@none>
Co-authored-by: ariel- <ariel-@users.noreply.github.com>
Co-authored-by: Shauren <shauren.trinity@gmail.com>
Co-authored-by: Jelle Meeus <sogladev@gmail.com>
This commit is contained in:
Tereneckla
2025-11-28 19:01:25 +00:00
committed by GitHub
parent 55989205e7
commit 2f7f9bd72f
42 changed files with 1976 additions and 1705 deletions

View File

@@ -174,8 +174,8 @@ class spell_dk_raise_ally : public SpellScript
if (pInfo) // exist in DB
{
ghoul->SetCreateHealth(pInfo->health);
ghoul->SetModifierValue(UNIT_MOD_HEALTH, BASE_VALUE, pInfo->health);
ghoul->SetModifierValue(UNIT_MOD_ARMOR, BASE_VALUE, float(pInfo->armor));
ghoul->SetStatFlatModifier(UNIT_MOD_HEALTH, BASE_VALUE, pInfo->health);
ghoul->SetStatFlatModifier(UNIT_MOD_ARMOR, BASE_VALUE, float(pInfo->armor));
for (uint8 stat = 0; stat < MAX_STATS; ++stat)
ghoul->SetCreateStat(Stats(stat), float(pInfo->stats[stat]));
}
@@ -194,9 +194,9 @@ class spell_dk_raise_ally : public SpellScript
// DK Ghoul haste refresh
float val = (GetCaster()->m_modAttackSpeedPct[BASE_ATTACK] - 1.0f) * 100.0f;
val *= 2000.0f + 2000.0f * ((100.0f + val) / 100.0f);
ghoul->m_modAttackSpeedPct[BASE_ATTACK] = GetCaster()->m_modAttackSpeedPct[BASE_ATTACK];
ghoul->SetFloatValue(UNIT_FIELD_BASEATTACKTIME, 2000.0f);
ghoul->ApplyPercentModFloatValue(UNIT_FIELD_BASEATTACKTIME, val, true); // we want to reduce attack time
ghoul->SetFloatValue(UNIT_FIELD_BASEATTACKTIME, val);
// Strength + Stamina
for (uint8 i = STAT_STRENGTH; i <= STAT_STAMINA; ++i)
@@ -223,20 +223,20 @@ class spell_dk_raise_ally : public SpellScript
value = float(GetCaster()->GetStat(stat)) * mod;
value = ghoul->GetTotalStatValue(stat, value);
ghoul->SetStat(stat, int32(value));
ghoul->ApplyStatBuffMod(stat, value, true);
ghoul->UpdateStatBuffMod(stat);
}
// Attack Power
ghoul->SetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE, 589 + ghoul->GetStat(STAT_STRENGTH) + ghoul->GetStat(STAT_AGILITY));
ghoul->SetInt32Value(UNIT_FIELD_ATTACK_POWER, (int32)ghoul->GetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE) * ghoul->GetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_PCT));
ghoul->SetInt32Value(UNIT_FIELD_ATTACK_POWER_MODS, (int32)ghoul->GetModifierValue(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE));
ghoul->SetFloatValue(UNIT_FIELD_ATTACK_POWER_MULTIPLIER, ghoul->GetModifierValue(UNIT_MOD_ATTACK_POWER, TOTAL_PCT) - 1.0f);
ghoul->SetStatFlatModifier(UNIT_MOD_ATTACK_POWER, BASE_VALUE, 589 + ghoul->GetStat(STAT_STRENGTH) + ghoul->GetStat(STAT_AGILITY));
ghoul->SetInt32Value(UNIT_FIELD_ATTACK_POWER, (int32)ghoul->GetFlatModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE) * ghoul->GetPctModifierValue(UNIT_MOD_ATTACK_POWER, BASE_PCT));
ghoul->SetInt32Value(UNIT_FIELD_ATTACK_POWER_MODS, (int32)ghoul->GetFlatModifierValue(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE));
ghoul->SetFloatValue(UNIT_FIELD_ATTACK_POWER_MULTIPLIER, ghoul->GetPctModifierValue(UNIT_MOD_ATTACK_POWER, TOTAL_PCT) - 1.0f);
// Health
ghoul->SetModifierValue(UNIT_MOD_HEALTH, TOTAL_VALUE, (ghoul->GetStat(STAT_STAMINA) - ghoul->GetCreateStat(STAT_STAMINA)) * 10.0f);
ghoul->SetStatFlatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, (ghoul->GetStat(STAT_STAMINA) - ghoul->GetCreateStat(STAT_STAMINA)) * 10.0f);
// Power Energy
ghoul->SetModifierValue(UnitMods(UNIT_MOD_POWER_START + static_cast<uint8>(POWER_ENERGY)), BASE_VALUE, ghoul->GetCreatePowers(POWER_ENERGY));
ghoul->SetStatFlatModifier(UnitMods(UNIT_MOD_POWER_START + static_cast<uint8>(POWER_ENERGY)), BASE_VALUE, ghoul->GetCreatePowers(POWER_ENERGY));
ghoul->UpdateAllStats();
ghoul->SetFullHealth();

View File

@@ -473,11 +473,7 @@ class spell_pal_blessing_of_sanctuary : public AuraScript
{
Unit* target = GetTarget();
if (Unit* caster = GetCaster())
{
// xinef: hack
int32 value = 9;
caster->CastCustomSpell(target, SPELL_PALADIN_BLESSING_OF_SANCTUARY_BUFF, &value, &value, 0, true);
}
caster->CastSpell(target, SPELL_PALADIN_BLESSING_OF_SANCTUARY_BUFF, true);
}
void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)

View File

@@ -18,6 +18,7 @@
#include "AreaDefines.h"
#include "CreatureScript.h"
#include "Pet.h"
#include "PetDefines.h"
#include "Player.h"
#include "SpellAuraEffects.h"
#include "SpellInfo.h"
@@ -25,6 +26,8 @@
#include "SpellScript.h"
#include "SpellScriptLoader.h"
#include "TemporarySummon.h"
#include "Unit.h"
#include "Util.h"
/*
* Scripts for spells with SPELLFAMILY_WARLOCK and SPELLFAMILY_GENERIC spells used by warlock players.
* Ordered alphabetically using scriptname.
@@ -73,6 +76,7 @@ enum WarlockSpells
SPELL_WARLOCK_EYE_OF_KILROGG_FLY = 58083,
SPELL_WARLOCK_PET_VOID_STAR_TALISMAN = 37386, // Void Star Talisman
SPELL_WARLOCK_DEMONIC_PACT_PROC = 48090,
SPELL_WARLOCK_GLYPH_OF_VOIDWALKER = 56247,
};
enum WarlockSpellIcons
@@ -292,7 +296,7 @@ class spell_warl_generic_scaling : public AuraScript
void CalculateResistanceAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/)
{
// xinef: pet inherits 40% of resistance from owner and 35% of armor
// pet inherits 40% of resistance from owner and 35% of armor
if (Unit* owner = GetUnitOwner()->GetOwner())
{
SpellSchoolMask schoolMask = SpellSchoolMask(aurEff->GetSpellInfo()->Effects[aurEff->GetEffIndex()].MiscValue);
@@ -308,7 +312,7 @@ class spell_warl_generic_scaling : public AuraScript
void CalculateStatAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/)
{
// xinef: by default warlock pet inherits 75% of stamina and 30% of intellect
// by default warlock pet inherits 75% of stamina and 30% of intellect
if (Unit* owner = GetUnitOwner()->GetOwner())
{
Stats stat = Stats(aurEff->GetSpellInfo()->Effects[aurEff->GetEffIndex()].MiscValue);
@@ -317,21 +321,33 @@ class spell_warl_generic_scaling : public AuraScript
}
}
void CalculateAPAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
void CalculateAPAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/)
{
// xinef: by default warlock pet inherits 57% of max(SP FIRE, SP SHADOW) as AP
if (Unit* owner = GetUnitOwner()->GetOwner())
if (Unit* pet = GetUnitOwner())
{
int32 fire = owner->SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_FIRE);
int32 shadow = owner->SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_SHADOW);
int32 maximum = (fire > shadow) ? fire : shadow;
amount = CalculatePct(std::max<int32>(0, maximum), 57);
// by default warlock pet inherits 57% of max(SP FIRE, SP SHADOW) as AP
if (Unit* owner = pet->GetOwner())
{
int32 fire = owner->SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_FIRE);
int32 shadow = owner->SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_SHADOW);
int32 maximum = (fire > shadow) ? fire : shadow;
amount = CalculatePct(std::max<int32>(0, maximum), 57);
// Glyph of felguard, 99% sure this is a HACK
if (pet->GetEntry() == NPC_FELGUARD)
{
if (AuraEffect* glyph = owner->GetAuraEffect(SPELL_GLYPH_OF_FELGUARD, EFFECT_0))
{
amount += CalculatePct(pet->GetTotalAuraModValue(UNIT_MOD_ATTACK_POWER) - aurEff->GetAmount() + amount, glyph->GetAmount());
}
}
}
}
}
void CalculateSPAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
{
// xinef: by default warlock pet inherits 15% of max(SP FIRE, SP SHADOW) as SP
// by default warlock pet inherits 15% of max(SP FIRE, SP SHADOW) as SP
if (Unit* owner = GetUnitOwner()->GetOwner())
{
int32 fire = owner->SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_FIRE);
@@ -339,7 +355,7 @@ class spell_warl_generic_scaling : public AuraScript
int32 maximum = (fire > shadow) ? fire : shadow;
amount = CalculatePct(std::max<int32>(0, maximum), 15);
// xinef: Update appropriate player field
// Update appropriate player field
if (owner->IsPlayer())
owner->SetUInt32Value(PLAYER_PET_SPELL_POWER, (uint32)amount);
}
@@ -1370,81 +1386,27 @@ class spell_warl_shadowburn : public AuraScript
}
};
class spell_warl_glyph_of_felguard : public AuraScript
class spell_warl_voidwalker_pet_passive : public AuraScript
{
PrepareAuraScript(spell_warl_glyph_of_felguard);
PrepareAuraScript(spell_warl_voidwalker_pet_passive);
void HandleApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
bool Validate(SpellInfo const* /*spellInfo*/) override
{
if (Player* player = GetCaster()->ToPlayer())
{
if (Pet* pet = player->GetPet())
{
if (pet->GetEntry() == NPC_FELGUARD)
{
pet->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_PCT, aurEff->GetAmount(), true);
}
}
}
return ValidateSpellInfo({ SPELL_WARLOCK_GLYPH_OF_VOIDWALKER });
}
void HandleRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
void CalculateAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
{
if (Player* player = GetCaster()->ToPlayer())
{
if (Pet* pet = player->GetPet())
{
if (pet->GetEntry() == NPC_FELGUARD)
{
pet->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_PCT, aurEff->GetAmount(), false);
}
}
}
if (Unit* pet = GetUnitOwner())
if (pet->IsPet())
if (Unit* owner = pet->ToPet()->GetOwner())
if (AuraEffect* aurEff = owner->GetAuraEffect(SPELL_WARLOCK_GLYPH_OF_VOIDWALKER, EFFECT_0))
amount += aurEff->GetAmount();
}
void Register() override
{
OnEffectApply += AuraEffectApplyFn(spell_warl_glyph_of_felguard::HandleApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
OnEffectRemove += AuraEffectRemoveFn(spell_warl_glyph_of_felguard::HandleRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
};
class spell_warl_glyph_of_voidwalker : public AuraScript
{
PrepareAuraScript(spell_warl_glyph_of_voidwalker);
void HandleApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
{
if (Player* player = GetCaster()->ToPlayer())
{
if (Pet* pet = player->GetPet())
{
if (pet->GetEntry() == NPC_VOIDWALKER)
{
pet->HandleStatModifier(UNIT_MOD_STAT_STAMINA, TOTAL_PCT, aurEff->GetAmount(), true);
}
}
}
}
void HandleRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
{
if (Player* player = GetCaster()->ToPlayer())
{
if (Pet* pet = player->GetPet())
{
if (pet->GetEntry() == NPC_VOIDWALKER)
{
pet->HandleStatModifier(UNIT_MOD_STAT_STAMINA, TOTAL_PCT, aurEff->GetAmount(), false);
}
}
}
}
void Register() override
{
OnEffectApply += AuraEffectApplyFn(spell_warl_glyph_of_voidwalker::HandleApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
OnEffectRemove += AuraEffectRemoveFn(spell_warl_glyph_of_voidwalker::HandleRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_voidwalker_pet_passive::CalculateAmount, EFFECT_0, SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE);
}
};
@@ -1529,7 +1491,6 @@ void AddSC_warlock_spell_scripts()
RegisterSpellScript(spell_warl_unstable_affliction);
RegisterSpellScript(spell_warl_drain_soul);
RegisterSpellScript(spell_warl_shadowburn);
RegisterSpellScript(spell_warl_glyph_of_felguard);
RegisterSpellScript(spell_warl_glyph_of_voidwalker);
RegisterSpellScript(spell_warl_voidwalker_pet_passive);
RegisterSpellScript(spell_warl_demonic_pact_aura);
}