Paragon cross-class family wildcard + Predatory Strikes proc

- CONFIG_PARAGON_WILDCARD_FAMILY + Paragon.WildcardFamilyMatching (reloadable)
- SpellInfo::IsAffected / IsAffectedBySpellMod(listenerOwner) for Paragon proc/mod wildcard
- SpellMgr::CanSpellTriggerProcOnEvent(procOwner) + Aura::IsProcTriggeredOnEvent wiring
- Player::IsAffectedBySpellmod passes listener for SpellMod wildcard
- ParagonFamilyMatches helper + Nourish / Shred-Maul bleed gate usage in Unit.cpp
- Spell::prepare: Paragon consumes 69369 for Nature spells <10s base cast (non-channeled)
- spell_paragon_predatory_strikes + SQL 2026_05_11_00.sql (spell_proc + spell_script_names)

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Docker Build
2026-05-11 01:24:50 -04:00
parent b408c8a95d
commit a1c9172beb
14 changed files with 337 additions and 9 deletions
+26
View File
@@ -3540,6 +3540,32 @@ SpellCastResult Spell::prepare(SpellCastTargets const* targets, AuraEffect const
if (m_caster->ToPlayer()->GetCommandStatus(CHEAT_CASTTIME))
m_casttime = 0;
// Fractured / Paragon: cross-class Predator's Swiftness (69369).
// Stock 3.3.5 only ADD_PCT_MODIFIER's the cast time of Druid-family
// Nature spells via class mask, so a Paragon with the buff cannot
// instant-cast Shaman Chain Lightning / Lightning Bolt or any other
// non-Druid Nature spell. The tooltip ("next Nature spell with a
// base cast time below 10 sec becomes instant") expects all-Nature
// behavior; honor that here for CLASS_PARAGON. We deliberately do
// not touch the stock SpellMod path -- real Druids continue to hit
// the existing class-mask code path unchanged.
if (Player* paragonCaster = m_caster->ToPlayer())
{
constexpr uint32 SPELL_PARAGON_PREDATORY_SWIFTNESS = 69369;
if (m_casttime > 0
&& paragonCaster->getClass() == CLASS_PARAGON
&& (m_spellInfo->SchoolMask & SPELL_SCHOOL_MASK_NATURE)
&& m_spellInfo->CastTimeEntry
&& !m_spellInfo->IsChanneled()
&& !HasTriggeredCastFlag(TRIGGERED_FULL_MASK)
&& m_spellInfo->CalcCastTime() < 10 * IN_MILLISECONDS
&& paragonCaster->HasAura(SPELL_PARAGON_PREDATORY_SWIFTNESS))
{
m_casttime = 0;
paragonCaster->RemoveAurasDueToSpell(SPELL_PARAGON_PREDATORY_SWIFTNESS);
}
}
// don't allow channeled spells / spells with cast time to be casted while moving
// (even if they are interrupted on moving, spells with almost immediate effect get to have their effect processed before movement interrupter kicks in)
if ((m_spellInfo->IsChanneled() || m_casttime) && m_caster->IsPlayer() && m_caster->isMoving() && m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_MOVEMENT && !IsTriggered())