RevokeUnwantedCascadeSpellsForPlayer and RevokeBlockedSpellsForPlayer built their allowlist only from character_paragon_panel_spells and panel_spell_children. Many Character Advancement "abilities" (e.g. Scourge Strike) are panel talents stored in character_paragon_panel_talents, so learning Death Coil afterward activated DK skill lines and the sweep removed those spells as false orphans. Add BuildPanelOwnedSpellsAllowlist to union spell chains, talent rank spell IDs up to the purchased rank, and passive children. Also keep the prior fixes: clear stale panel_spell_revoked rows on purchase and skip+delete revoke entries that now match the allowlist on login. Co-authored-by: Cursor <cursoragent@cursor.com>
mod-paragon
Server-side support module for the custom CLASS_PARAGON (id 12).
What it does today
Hooks Player::IsClass / Player::HasActivePowerType so Paragon
inherits Death Knight ability mechanics where it matters:
- Rune system:
InitRunes, rune cooldown tick, runic power regen,Spell::CheckRuneCost/Spell::TakeRunePower,SMSG_RESYNC_RUNEScast flags, combat exit grace reset. - DK ability scripts:
spell_dk_*,MUST_BE_DEATH_KNIGHTcast result, DK aura effects.
It is intentionally narrow: the hook only fires for
(realClass == PARAGON, queriedClass == DEATH_KNIGHT, context == CLASS_CONTEXT_ABILITY).
Other DK-flavored contexts (Ebon Hold teleport gating, heroic start
level, DK-only taxi mount, talent point math on Ebon Hold, etc.) keep
their normal behavior for Paragon.
HasActivePowerType additionally claims POWER_RUNIC_POWER and
POWER_RUNE for Paragon, which keeps the rune pool sized correctly
in Player::InitStatsForLevel even if Paragon's primary power type is
later switched away from runic power.
Building
Auto-detected by modules/CMakeLists.txt (GetModuleSourceList globs
every subdirectory). No additional CMake plumbing is needed; rebuild
the worldserver image and the loader symbol Addmod_paragonScripts
gets linked into the static modules target.
SQL layout
SQL files live under data/sql/db-world/base/ and
data/sql/db-characters/base/ — the standard AzerothCore module path
that the built-in DBUpdater scans (see
src/server/database/Updater/UpdateFetcher.cpp). Files placed there
are applied automatically by worldserver / dbimport on startup and
recorded by hash in the updates table of the target database, so
re-runs are idempotent. Any new SQL added under those directories will
be picked up on the next container/server start without manual import.