Fix Dragon Form unlock, then prototype vehicle-based full transform Updated 2 weeks ago

mod-dragon-legacy

v1: lets a player transform into a dragon on command, taught by an NPC. First slice of a bigger idea โ€” see the project notes for planned follow-ups (dragons turning neutral toward a transformed player, custom quests/interactions).

What it does

  • Aerion Dragonspeaker (creature entry 901000, spawned next to Deputy Willem in Northshire Valley as a placeholder โ€” move with .npc move to wherever fits better, e.g. Wyrmrest Temple) offers to unlock the way of the dragon via gossip. Picking the option writes a row to mod_dragon_legacy_unlocked (characters DB) rather than teaching a spell โ€” see "Why a command, not a learned spell" below.
  • .dragon-rawr (SEC_PLAYER) toggles Dragon Form: if unlocked and not already transformed, casts spell 900000 (a self-only SPELL_AURA_TRANSFORM into a Black Dragon Whelp, triggered server-side, not learned/cast by the player); if already transformed, cancels it. Can also be cancelled the normal way, by right-clicking its buff icon โ€” that still works since it's just an active aura. Mounting also cancels it. Dying cancels it automatically (core behavior, no code needed). Logging out while transformed cancels it too (DragonLegacy_Player::OnPlayerBeforeLogout) so it doesn't carry over to the next login.
  • .dragon-rawr breath (SEC_PLAYER) casts Whelp Breath (spell 900001, a single-target fire bolt) at the player's current target. Only works while Dragon Form is active โ€” checked both in the command handler and via spell_dragon_legacy_whelp_breath's OnCheckCast hook checking HasAura(SPELL_DRAGON_FORM). The OnCheckCast gating pattern is what to copy for any future dragon-only abilities; the "command instead of spellbook" pattern is what to copy for how players actually trigger them.

Why a command, not a learned spell

Dragon Form and Whelp Breath are from-scratch spell IDs (900000/900001) with no entry in the client's own Spell.dbc. v1 taught them via Player::learnSpell() โ€” that persisted correctly to character_spell server-side, but the client had nothing to render or cast: no name, no icon, no macro resolution, since the 3.3.5a client's spellbook/cast bar/macro system reads from its own local DBC, not anything the server sends. .dragon-rawr sidesteps this entirely: the transform is applied via a triggered CastSpell from server-side C++, never something the player casts by name themselves, so the client never needs to resolve the spell to trigger it. Same lesson independently confirmed in mod-waygate-network โ€” see PLAN.md's "v1.1: spell โ†’ command pivot" for the full writeup, and its PLAN.md's "Deferred / rejected" section for the general rule.

Known v1.1 limitations

  • No custom visual/animation for Whelp Breath โ€” it works mechanically but has no spell visual yet (no SpellVisualID set).
  • Dragon Form's buff icon may render blank/generic even though the transform itself works, since icon art is tied to client-side SpellIcon.dbc/Spell.dbc data the client doesn't have an entry for. Cosmetic, not functional โ€” not yet confirmed in-game either way.
  • The NPC's spawn point is a placeholder next to an existing starting-zone NPC, picked because its coordinates were already verified valid in the world DB โ€” not because it's thematically right. Relocate it once the module is live.

Custom ID ranges

To avoid colliding with Blizzard content or other custom modules, this module reserves:

  • Spell IDs 900000โ€“900099 (data/sql/db-world/base/dragon_legacy_spells.sql)
  • Creature entries / npc_text IDs 901000โ€“901099 (data/sql/db-world/base/dragon_legacy_npc.sql)

Checked against data/sql/base/db_world/{spell_dbc,creature_template}.sql at the time this module was written: normal content topped out well under 200000. Re-check with the DB directly before adding more content to this module, in case other custom content has been added since.

Config

See conf/mod_dragon_legacy.conf.dist:

  • DragonLegacy.Enable (default 1) โ€” toggles whether the NPC offers to teach Dragon Form.