Paragon: server-authoritative CP/rune sync + cascade-spell revoke hardening
mod-paragon Paragon_Essence.cpp: - Broaden SkillLinesLinkedToSpell: collect every SkillLineAbility row for an anchor spell regardless of AcquireMethod, so anchor spells whose primary SLA uses AcquireMethod 0 (e.g. Blood Strike) correctly identify their skill lines and let the dependent classifier do its job. - IsSpellSkillLineCascadeDependent / RevokeUnwantedCascadeSpellsForPlayer use the broadened helper. HandleCommit calls the post-purchase sweep immediately so the spellbook never carries lingering cascade dependents (Blood Presence / Forceful Deflection / Death Coil / Death Grip). - New character_paragon_panel_spell_revoked table tracks which active dependents we've revoked per (guid, parent) so OnPlayerLogin can re-revoke them after AC's _LoadSkills -> learnSkillRewardedSpells silently re-grants them. - OnPlayerLogin opens the client SILENCE window via SendSilenceOpenForCommit with an empty allow list and intentionally omits the matching SendSilenceClose: the chat frame buffers CHAT_MSG_SYSTEM during the loading screen and only flushes after PLAYER_ENTERING_WORLD, so a paired CLOSE would shut the filter before the buffered "you have unlearned X" toasts hit it. The addon's 8s fail-open closes the window after the flush. - New `.paragon hat` chat command for diagnosing Honor Among Thieves triggers (talent rank, learned spell, applied aura, proc table entry). mod-paragon Paragon_SC.cpp: - OnPlayerUpdate pushes server-authoritative combo points to the client via PARAA "R CP <n>" whenever the count changes. The client-side ComboFrame Paragon simulator listens for this and updates the target frame, fixing HAT-generated CP not displaying (HAT's trigger casts with a null target, which the combat-log inference path can't see). - OnPlayerUpdate also pushes "R RUNES <cd0..cd5>" (ms remaining per rune slot) on rune mask changes, so the client RuneFrame simulator stays in lock-step with Spell::TakeRunePower instead of drifting through combat-log latency. mod-paragon SQL: - New updates/2026_05_09_00.sql migration creates character_paragon_panel_spell_revoked for AC's auto-DBUpdater so a fresh checkout can stand up an existing characters DB without manual intervention. Matching CREATE TABLE IF NOT EXISTS in base/character_paragon_panel_learned.sql for fresh installs. mod-paragon conf: - New Paragon.Diag.PanelLearn flag traces every PanelLearnSpellChain commit (chain ids, before/after spell-map sizes, side-spell classification) for diagnosing "spell reappears on relog" bugs. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -32,3 +32,20 @@ CREATE TABLE IF NOT EXISTS `character_paragon_panel_spell_children` (
|
||||
PRIMARY KEY (`guid`, `parent_spell_id`, `child_spell_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
COMMENT='mod-paragon: passive auto-learn dependents to unlearn on reset';
|
||||
|
||||
-- Active "dependent" spells that AzerothCore's `addSpell` /
|
||||
-- `learnSkillRewardedSpells` machinery auto-grants alongside a
|
||||
-- panel-purchased spell but that the player did NOT buy (e.g. Blood
|
||||
-- Presence, Death Coil, Death Grip from purchasing Plague Strike).
|
||||
-- We revoke them at panel-commit time, but AC's skill cascade re-runs
|
||||
-- on every login (`Player::_LoadSkills` -> `learnSkillRewardedSpells`)
|
||||
-- and silently re-grants them. We persist the revoke decisions here
|
||||
-- and re-revoke at `OnPlayerLogin` so the spellbook stays in sync with
|
||||
-- what the player actually purchased through Character Advancement.
|
||||
CREATE TABLE IF NOT EXISTS `character_paragon_panel_spell_revoked` (
|
||||
`guid` INT UNSIGNED NOT NULL COMMENT 'characters.guid',
|
||||
`parent_spell_id` INT UNSIGNED NOT NULL COMMENT 'character_paragon_panel_spells.spell_id',
|
||||
`revoked_spell_id` INT UNSIGNED NOT NULL COMMENT 'active spell id auto-granted by skill cascade and revoked',
|
||||
PRIMARY KEY (`guid`, `parent_spell_id`, `revoked_spell_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
COMMENT='mod-paragon: active auto-learn dependents to keep revoked across logins';
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
-- mod-paragon: tracking table for active spell dependents the panel
|
||||
-- revoked at commit time. AzerothCore's `Player::_LoadSkills` ->
|
||||
-- `learnSkillRewardedSpells` re-grants skill-rewarded actives (Blood
|
||||
-- Presence, Death Coil, Death Grip, ...) on every login. Persisting
|
||||
-- the revoke decisions here lets `OnPlayerLogin` re-revoke them after
|
||||
-- the cascade has run, so the spellbook stays in sync with what was
|
||||
-- actually purchased through Character Advancement.
|
||||
--
|
||||
-- This file lives under `updates/` so AC's DBUpdater applies it
|
||||
-- incrementally on existing databases (the matching `CREATE TABLE
|
||||
-- IF NOT EXISTS` block in base/character_paragon_panel_learned.sql
|
||||
-- handles fresh installs).
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `character_paragon_panel_spell_revoked` (
|
||||
`guid` INT UNSIGNED NOT NULL COMMENT 'characters.guid',
|
||||
`parent_spell_id` INT UNSIGNED NOT NULL COMMENT 'character_paragon_panel_spells.spell_id',
|
||||
`revoked_spell_id` INT UNSIGNED NOT NULL COMMENT 'active spell id auto-granted by skill cascade and revoked',
|
||||
PRIMARY KEY (`guid`, `parent_spell_id`, `revoked_spell_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
COMMENT='mod-paragon: active auto-learn dependents to keep revoked across logins';
|
||||
Reference in New Issue
Block a user