295cb6df525f457e8ad9f64c399a7f4853bb24b7
13 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
87219cb4eb |
Paragon: multidot Devouring Plague, stance/presence clones, advancement SLA
- Allow multiple Devouring Plague DoTs on different targets (core + DK script). - Warrior stance and DK presence clone spells for Character Advancement; spellbook SkillLineAbility rows and aura/shapeshift attribute fixes. - World SQL updates 2026_05_12_02 through 07 (mod-paragon db-world). Client patch-enUS-4/5/6 and Wow.exe ship on the matching GitHub Release (not in repo). Co-authored-by: Cursor <cursoragent@cursor.com> |
||
|
|
999f7e94bd |
Paragon: narrow weapon bypass; cascade talent ranks; Savage Defense
* Weapon-narrow: replace blanket EquippedItemSubClassMask bypass with an explicit allowlist (IsParagonWeaponSubclassWildcardSpell, currently Maelstrom Weapon 51528 only). Applied at all three gates: Player:: HasItemFitToSpellRequirements, Player::CheckAttackFitToAuraRequirement, and Aura::IsProcTriggeredOnEvent. Maelstrom Weapon still procs from any weapon for Paragon, but Hack and Slash / Sword / Mace Specialization remain correctly weapon-gated. * Talent ability-rank cascade: TeachLevelGatedAbilityChainNoPanel + CascadeRanksForTalentLearnSpellEffects walk the SPELL_EFFECT_LEARN_SPELL chain a talent rank grants and learn each rank up to the player's level. Wired into HandleCommit (on talent purchase) and OnPlayerLevelChanged (on level-up). Fixes Mangle (and any future LEARN_SPELL talent) being stuck at rank 1 because Player::learnSkillRewardedSpells is intentionally disabled for Paragon's class skill lines. * Riding-skill gate for flight forms (IsParagonSpellAllowedByRidingSkill): Flight Form (33943) requires Expert Riding (34090); Swift Flight Form (40120) requires Artisan Riding (34091). Applied in PanelLearnSpellChain and TeachLevelGatedAbilityChainNoPanel so the cascade can't push past a rank the player isn't trained for. Also backticks `rank` in the level-up query (MySQL reserved word). * Savage Defense (62600) on the panel: the SpellData bake's blanket SPELL_ATTR0_PASSIVE filter dropped Savage Defense even though Druid trainer 33 sells it at level 40. Bake (in fractured-tooling) now carves out a small PASSIVE_TRAINER_ALLOWLIST and the regenerated paragon_spell_ae_cost.sql + 2026_05_11_05.sql migration surface it on the Druid Feral spell tab. Co-authored-by: Cursor <cursoragent@cursor.com> |
||
|
|
e649402163 |
Paragon: cross-class talents + Warrior stance bypass + Mirror Image spellbook draw
Server-side cross-class wildcard pass for several talents that were
previously locked to a single SpellFamilyName, plus a server+client
Warrior stance bypass and a Paragon-aware Mirror Image rebuild that
mimics the owner's spellbook instead of stock Frostbolt/Fire Blast.
Talent expansions (Paragon owners only; stock classes unchanged):
- Cold Snap (11958): resets cooldown of any Frost-school spell.
- Nature's Swiftness (17116, 16188) + Predator's Swiftness (69369):
instant-cast on any Nature-school spell.
- Vampiric Embrace (15286): leech-heals from any single-target
Shadow-school spell.
- Fingers of Frost (44543/44545) + Frostbite (11071/12496/12497):
proc from any Frost-school chill effect (DK Howling Blast / Icy
Touch / Chains of Ice, Hunter Frost Trap, Shaman Frost Shock,
cross-class chill auras via SPELL_AURA_MOD_DECREASE_SPEED).
- Maelstrom Weapon (53817): now also affects Mage Fireball (133),
Frostbolt (116), and Arcane Blast (30451) at every rank, both
for cast-time/cost spellmod and for stack consumption.
Warrior stance bypass:
- SpellInfo::CheckShapeshift returns SPELL_CAST_OK whenever a
Paragon caster hits any Stances!=0 spell (no SpellFamilyName
gate). Stock classes still see the regular form rules.
- Client side: patch-enUS-4.MPQ now zeroes Stances on every
SPELLFAMILY_WARRIOR Spell.dbc row (105 spells) so the engine's
pre-cast "Must be in Battle/Defensive/Berserker Stance" check
no longer eats CMSG_CAST_SPELL packets for Paragons. Server
bypass enforces the actual decision; stock Warriors still
error mid-cast if they actually click while out of stance.
- patch-enUS-5.MPQ Lua tooltip post-processor recolors and
appends "(Paragon: bypassed)" to "Requires *Stance*" lines on
Warrior abilities, plus Paragon notes on Maelstrom Weapon and
Mirror Image tooltips. Action-bar UseAction wrapper routes
stance-gated Warrior spell clicks through CastSpellByName so
the stance-zero DBC + server bypass actually run.
Mirror Image:
- npc_pet_mage_mirror_image rebuilds its spell list from the
Paragon owner's spellbook on InitializeAI AND JustEngagedWith
(the second pass + events.Reset clears any stale events the
CasterAI base scheduler may have queued from stock 59637 /
59638 entries before the rebuild ran).
- Curated filter keeps single-target damaging spells (instant,
cast-time, or channeled) with a base cooldown <=10s, with the
"damaging" definition expanded to include
SPELL_EFFECT_TRIGGER_MISSILE and
SPELL_AURA_PERIODIC_TRIGGER_SPELL so Arcane Missiles
qualifies. Rejects passives, AoE, melee/ranged weapon strikes,
item/reagent/stance/equip-gated, and lower spell ranks.
- UpdateAI picks a random spell from the curated list per cast
and reschedules the next pick by the actually-cast spell's
cast/channel duration + 750ms breather, so a 5s Arcane
Missiles channel waits its full duration before re-rolling
rather than visually looping across four images.
Helpers:
- Unit::IsParagonWildcardCaller / Unit::ParagonFamilyMatches
used by Spell.cpp, SpellInfo.cpp, Player.cpp,
SpellAuraEffects.cpp, and the spell scripts.
- SpellInfo::CheckShapeshift signature gains an optional caster
pointer; all call sites updated.
SQL migrations under modules/mod-paragon/data/sql/db-world/updates/:
- 2026_05_11_01.sql Vampiric Embrace spell_proc relax + script
gate (CheckProc enforces stock for non-Paragon).
- 2026_05_11_02.sql Maelstrom Weapon spell_proc relax (initial,
superseded by _04 below for stack-consumption fix).
- 2026_05_11_03.sql Fingers of Frost / Frostbite spell_proc relax
and spell_script_names binding.
- 2026_05_11_04.sql Maelstrom Weapon spell_proc fixup: restore
SpellPhaseMask=1 (CAST) and AttributesMask=8
(REQ_SPELLMOD); previous _02 set 8/0 which
silently dropped every proc event.
Diagnostics from this debugging session demoted from LOG_INFO to
LOG_DEBUG (silent at default info level) so production logs stay
quiet but the probes remain available for reproducing future
regressions: pet_mage.cpp MirrorImage probe/kept/rebuild/init/
engage/cast lines and SpellInfo.cpp CheckShapeshift bypass line.
CLIENT-PATCHES.md updated to document the new Warrior stance DBC
patcher (_patch_spell_dbc_stances.py), the spell-tooltip post-
processor and stance UseAction wrapper in patch-enUS-5.MPQ, and
the Mirror Image / Maelstrom Weapon Paragon notes.
Co-authored-by: Cursor <cursoragent@cursor.com>
|
||
|
|
a1c9172beb |
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> |
||
|
|
8ad6a2aca3 |
Paragon: cascade guard for class skill lines + panel catalog backfill
The skill-line cascade in Player::learnSkillRewardedSpells re-fires from _LoadSkills (every login), UpdateSkillsForLevel (every level-up), UpdateSkillPro (every weapon-skill tick on a training dummy), and SetSkill (first time a class skill is granted). Each pass re-grants every SkillLineAbility-tagged class ability on the matching skill line, which leaks Blood Presence / Death Coil / Death Grip / etc. back into the spellbook within seconds even after the player intentionally refunded them via the Character Advancement panel. Path B fix: a 5-line guard at the top of learnSkillRewardedSpells skips the cascade for class-category skill lines on CLASS_PARAGON characters. mod-paragon already calls Player::learnSpell directly for the abilities the player actually purchased (and their attached passives), so the panel becomes the sole authority over class abilities. Profession, weapon, language, and racial cascades stay enabled so recipe auto-learn, weapon proficiencies, and racial perks still work. Side effect: passives that previously rode along on the cascade (Forceful Deflection on Blood Strike, Runic Focus on Icy Touch) must be force-attached the same way Blood Plague / Frost Fever already are. Extend kAttached and kFixup in Paragon_Essence.cpp to do that; existing characters self-heal on next login. Backfill paragon_spell_ae_cost for 42 spells newly exposed by the panel after the ClassMask=0 filter was removed from the client catalog generator (Lava Burst, Hex, Evocation, Kill Shot, Path of Frost, Horn of Winter, Rune Strike, Raise Ally, Dark Command, etc.). Migration is INSERT IGNORE so any per-spell tuning on existing rows is preserved. Co-authored-by: Cursor <cursoragent@cursor.com> |
||
|
|
f986fdcddd |
mod-paragon: let class 12 actually USE class-restricted glyphs / items
Two paths still rejected glyph use on Paragon characters even after the earlier AllowableClass server bypass: 1. Spell::CheckItems (server) treated cast-from-glyph as a normal "equipped item required" cast and called HasItemFitToSpellRequirements, which only handles weapon/armor and falls through default for ITEM_CLASS_GLYPH -> SPELL_FAILED_EQUIPPED_ITEM_CLASS. Skip that check when the cast item itself is the glyph. 2. The 3.3.5 client engine pre-checks ItemTemplate.AllowableClass against the player's class locally and refuses the right-click before sending CMSG_USE_ITEM, regardless of what the server would do. Bake the Paragon class bit (1<<11 = 2048) into AllowableClass for every class-restricted item via a mod-paragon SQL migration so the engine's pre-check passes for class 12. Cache caveat: clients that previously inspected an affected item have the old AllowableClass cached in Cache/<locale>/itemcache.wdb; deleting the Cache folder forces a re-query. The server also caches item_template in memory at boot, so this migration only takes effect for clients after a worldserver restart (or .reload item_template) once the SQL has been applied -- DBUpdater handles the SQL automatically on the next start. Co-authored-by: Cursor <cursoragent@cursor.com> |
||
|
|
16717acdd3 |
mod-paragon: combined Arcane Torrent that refunds mana, energy, and runic power
Building on the previous fix that hid the rogue and DK Arcane Torrent variants for Paragon Blood Elves: instead of just dropping the duplicates, turn the remaining mana variant (28730) into a single combined racial that refunds whichever resource pool the character is using at the moment. Add SpellScript spell_paragon_arcane_torrent in modules/mod-paragon/src/ Paragon_SC.cpp. Hooks AfterCast on 28730: when the caster is class 12 the script EnergizeBySpell's 15 energy and 150 internal runic power (= 15 displayed, matching stock 25046 / 50613 amounts) on top of the spell's stock mana effect. ModifyPower no-ops on pools the player has no max for, so it is safe even before the Paragon picks up energy- or RP-using abilities. Non-Paragon Blood Elves are untouched and keep learning their stock racial. Update migration 2026_05_10_03.sql to also register the script binding via spell_script_names (28730 -> 'spell_paragon_arcane_torrent'). Idempotent DELETE + INSERT. Co-authored-by: Cursor <cursoragent@cursor.com> |
||
|
|
d96123e661 |
mod-paragon: single Arcane Torrent for Paragon Blood Elves
Blood Elf racial skill line 756 grants three different Arcane Torrent spell IDs (28730 mana, 25046 rogue energy, 50613 DK runic power). The blanket SkillLineAbility overlay in 2026_05_10_02 OR'd class 12 into all three, so Paragon Blood Elves auto-learned every variant and the spellbook listed three identical "Arcane Torrent" entries. Add db-world migration 2026_05_10_03.sql to clear the class-12 bit on the rogue and DK rows only (SkillLineAbility IDs 13338 and 17510), leaving 28730 as the sole Paragon-visible racial cast. OnPlayerLogin removes 25046/50613 if still present so existing characters self-heal without a manual unlearn. The fractured-tooling DBC overlay generator is updated in the same workspace to skip those two rows when regenerating SkillLineAbility SQL. Co-authored-by: Cursor <cursoragent@cursor.com> |
||
|
|
8363b1b6c8 |
Paragon: ship class-12 SkillLineAbility overlay so proficiency passives auto-learn
Companion to 2026_05_09_00.sql (DBC overlay for chrclasses + srci) and
2026_05_10_01.sql (proficiency skill rows in playercreateinfo_skills).
Those two grant the SKILL (Maces, Shield, Cloth, ...) to Paragon at
character creation; this one opens the SkillLineAbility rows that
CASCADE skill -> passive spell, so when a fresh Paragon is created
AC's `Player::LearnDefaultSkill` actually grants the proficiency
passives:
Block (107), Parry (3127), Dual Wield (674), Defense, weapon Shoot,
racial Mace/Sword Specialization, ...
Without this overlay, a class-12 Paragon spawns with the right skill
rows but a near-empty spellbook past the racials and class defaults
that come from playercreateinfo_action.
How it works
------------
AC's DBCStores.cpp::LoadDBC loads each store from the on-disk .dbc
file first, then merges <table>_dbc world-DB rows on top. Our patched
client SkillLineAbility.dbc (in patch-enUS-4.MPQ) OR's the class-12
bit (0x800) into ClassMask on 3,314 rows -- the same rows the server
needs for the cascade to fire on Paragon. Stock Docker installs use
the upstream `ac-wotlk-client-data` image which fills data/dbc/ from
a vanilla 3.3.5a extract, so without this SQL overlay the server
runs against an unmodified SkillLineAbility.dbc and the cascade
never fires.
Generation
----------
Auto-generated end-to-end by
`fractured-tooling/from-workspace-root/_gen_paragon_dbc_overlay_sql.py`,
extended in this commit to handle SkillLineAbility.dbc (14-int
WotLK layout, 56 bytes per record). The script diffs patched vs
stock by ID, keeps only rows whose stock ClassMask did NOT include
the class-12 bit but whose patched ClassMask does, and emits the
3,314 REPLACE INTO rows. Re-running with the same inputs is byte-
stable.
Verified locally
----------------
- Migration applies twice in a row at exactly 3,314 SQL overlay rows
(idempotent: DELETE WHERE ID IN (...) before INSERT).
- ac-worldserver restart logs:
>> Loaded 10219 SkillLineAbility MultiMap Data
-- the same total as stock (10,219 rows), confirming our overlay
REPLACES existing rows by ID rather than appending duplicates.
- Spot-checked spell IDs: 107 (Block, ClassMask 2115 = warrior +
paladin + dk + Paragon), 3127 (Parry, 2063), 674 (Dual Wield,
2157), 75 (Auto Shoot, 2052) all carry the 0x800 bit.
Existing characters
-------------------
The cascade fires inside Player::Create and Player::LearnDefaultSkill
at character spawn, so existing class-12 characters created before
this migration keep their broken state. Delete and re-roll, or hand-
grant the missing spells via .learn for individual existing chars.
CLIENT-PATCHES.md updated to add the third symptom ("proficiency
skills exist but passive spells don't auto-learn") and document
this migration as the fourth piece of the class-12 bootstrap.
Co-authored-by: Cursor <cursoragent@cursor.com>
|
||
|
|
2874119c6d |
Paragon: ship class-12 weapon/armor proficiencies as SQL migration
Companion to 2026_05_10_00.sql. The spawn-data migration teaches the
worldserver where Paragon characters spawn and what per-level base
stats they have; this one teaches it which weapon/armor skill lines
to grant at first character login.
Without these rows a fresh Paragon character lands in their newbie
zone with no weapon or armor proficiencies (auto-attack greys out
on anything beyond a fist) -- the universal classMask=0 rows in
playercreateinfo_skills only cover Defense, Unarmed, Cloth,
languages, Mounts, and Companion Pets.
Adds 20 rows in playercreateinfo_skills with classMask=2048 (class
12 only) for every weapon and armor proficiency:
- Weapons: Swords, Axes, Bows, Guns, Maces, 2H Swords, Dual Wield,
Staves, 2H Maces, 2H Axes, Daggers, Thrown, Crossbows,
Wands, Polearms, Fist Weapons.
- Armor: Plate Mail, Mail, Leather, Shield. (Cloth already
granted via the classMask=0 universal row.)
Idempotent: DELETE WHERE classMask=2048 then INSERT, so it replays
cleanly on a partially-seeded DB (e.g. one where a contributor hand-
patched these rows before the migration landed).
Verified locally: applies cleanly twice in a row, worldserver restart
now logs `>> Loaded 1391 Player Create Skills` (was 1371 pre-Paragon
= +20 class-12 rows) and a freshly-rolled Draenei Paragon spawns with
the full weapon/armor kit.
CLIENT-PATCHES.md troubleshooting block updated to call out the
"Paragon spawns naked / can't equip anything" failure mode and list
all three migrations in the current rebuild recipe.
Co-authored-by: Cursor <cursoragent@cursor.com>
|
||
|
|
5deb9e3255 |
Paragon: ship class-12 starter spawn data so character creation works on fresh installs
Companion to 2026_05_09_00.sql (DBC overlay). The DBC overlay teaches
the world server that class 12 (Paragon) exists; this migration
teaches it WHERE class-12 characters spawn, what action bar they boot
with, and what per-level base stats Player::InitStatsForLevel uses.
Without these rows, contributors hit:
- Player::Create -> "invalid race/class pair (R/12) - refusing"
and the client shows "Error creating character".
- WorldServer load -> "class-12 Level-L does not have stats data!"
integrity warnings.
Tables touched (idempotent: DELETE WHERE class=12 then INSERT):
- playercreateinfo : 10 rows, every DK-eligible race spawning
in their racial newbie zone (Northshire,
Valley of Trials, Ammen Vale, ...).
NOT Acherus -- Paragon is from-level-1.
- playercreateinfo_action : 46 rows, default action bar layout
per race (attack 6603, eat 78, racial,
etc.).
- player_class_stats : 80 rows, per-level base HP/Mana/STR/AGI/
STA/INT/SPI. Curve mirrors Warrior to
level 60, Paladin-style HP inflation
past 60 to keep Paragon competitive
in Wrath content.
Tables intentionally untouched: playercreateinfo_item is empty for
class 12 (Paragon ships no per-class starting items, only racial
kit), and the mask-based playercreateinfo_skills/_cast_spell/
_spell_custom rows already cover class 12 via their classMask=0
"all classes" entries.
Verified locally: applies cleanly twice in a row (idempotent),
worldserver restart now logs `>> Loaded 72 Player Create Definitions`
(was 62 pre-Paragon = +10 races for class 12) and creates a Draenei
Paragon without rejection.
CLIENT-PATCHES.md troubleshooting block updated to merge the two
"Character Creation Failed" modes (DBC overlay missing + spawn data
missing) into a single fix recipe. Existing contributors with a
pre-built dbimport image need
`docker compose build ac-db-import ac-worldserver` before this
migration is visible to DBUpdater; fresh clones get it on first
`docker compose up`.
Co-authored-by: Cursor <cursoragent@cursor.com>
|
||
|
|
fae3ff5028 |
Paragon: ship server-side DBC overlay as SQL so fresh installs can roll class 12
Stock Docker installs fill data/dbc/ from the vanilla 3.3.5a extract
in `ac-wotlk-client-data`, which has no class 12 in ChrClasses.dbc and
no class-12 bit on SkillRaceClassInfo.dbc. CharacterHandler.cpp's
sChrClassesStore.LookupEntry(12) returns null and the create fails
with CHAR_CREATE_FAILED ("Class (12) not found in DBC ...") before the
contributor ever sees the panel. Fixing it required hand-copying the
patched DBCs onto the named volume — undocumented, fragile, and not
portable to native installs.
DBCStores.cpp::LoadDBC merges every <table>_dbc world-DB row on top of
the on-disk DBC store (storage.LoadFromDB after storage.Load). We use
that merge layer to ship Paragon's class-12 deltas as SQL:
- chrclasses_dbc: 1 row defining class 12 (Paragon, power=Mana,
family=Warrior, expansion=2). Resolves CHAR_CREATE_FAILED.
- skillraceclassinfo_dbc: 235 rows REPLACEing stock entries with the
patched ClassMask (class-12 bit OR'd in) so baseline skills (defense,
weapon skills, etc.) are available to Paragon characters.
The new `modules/mod-paragon/data/sql/db-world/updates/2026_05_09_00.sql`
is applied automatically by AC's DBUpdater on every fresh `ac-db-import`
run (Docker) or first worldserver boot (native). End-to-end verified
locally: truncate -> docker compose up ac-db-import -> rows reappear
with hash 33B1A05 recorded in updates table.
The migration is auto-generated by
fractured-tooling/from-workspace-root/_gen_paragon_dbc_overlay_sql.py
(outside this repo per the repo-tidy policy). Re-run it whenever the
DBC bake changes.
CLIENT-PATCHES.md is rewritten so contributors no longer need the
manual DBC sync section as their primary install path. Manual overlay
is preserved as a labelled fallback for tools that read data/dbc/
directly.
Co-authored-by: Cursor <cursoragent@cursor.com>
|
||
|
|
df7e943a74 |
Paragon: move module SQL to AC's data/sql/db-* layout for auto-update
AzerothCore's DBUpdater scans modules/<mod>/data/sql/db-{world,characters,auth}/
(see src/server/database/Updater/UpdateFetcher.cpp). The previous
modules/mod-paragon/sql/{world,characters}/base/ layout was non-standard
and skipped by the updater, so a fresh deploy never had Paragon tables
created automatically.
Move all five SQL files into the standard layout. Files are idempotent
(CREATE TABLE IF NOT EXISTS plus a DELETE+INSERT for the cost table)
and now apply on every dbimport / worldserver start, recorded by hash
in <db>.updates so re-runs are skipped.
Update BUILD-NATIVE.md to drop the manual mysql import section, and
document the SQL layout in the mod-paragon README.
Co-authored-by: Cursor <cursoragent@cursor.com>
|