mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-06-03 13:41:43 -04:00
afb447367feb82fa2a6ca4f077acb262a7ebd8bd
160 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
4b5b7ccd3e |
feat(pipeline): WLNK chat hyperlink template catalog (146th open format)
Novel replacement for the implicit chat-link format templates
vanilla WoW carried in client-side LUA — each link kind (item /
quest / spell / achievement / talent / trade-skill) had a hard-
coded sprintf template baked into ChatFrame_OnHyperlinkClick
with no formal data-driven extension point. Each WLNK entry
binds one hyperlink kind to its sprintf-style chat-link
template (with %%d/%%s placeholders for link parameters),
tooltip-popup template, quality color (RGBA), icon source
rule, and server-lookup requirement flag.
Three presets covering the link-kind spectrum:
--gen-lnk-std 4 standard hyperlink kinds (Item with
classic 4-rune-slot template / Quest
yellow / Spell white / Achievement with 9
placeholders for criteria-progress data)
--gen-lnk-talent 2 less-common kinds (Talent green for
passive enhancements / Trade-skill recipe
orange with server lookup for ingredients)
--gen-lnk-quality 3 Item-kind variants distinguished by
quality color (Common gray 0x9D9D9D / Epic
purple 0xA335EE / Legendary orange
0xFF8000) — chat composer picks variant by
item quality at link time
Validator catches: id+name+linkTemplate required, linkKind
0..5, no duplicate linkIds. CRITICAL: linkTemplate MUST contain
at least one %%d/%%s placeholder — composer would emit a static
string regardless of input (every link rendering identically
regardless of which item/spell/quest was clicked). Walks the
template character-by-character counting valid format
specifiers (%%d, %%s, %%u, %%i, %%x, %%X, with %%%% literal
double-percent excluded). Warns on > 12 placeholders (unusual,
verify intentional), colorRGBA=0 (fully transparent — link text
invisible), and requireServerLookup=true with empty
tooltipTemplate (server data has nowhere to render).
Format count 145 -> 146. CLI flag count 1508 -> 1515.
|
||
|
|
6462a08927 |
feat(pipeline): WCFR combat formula catalog (145th open format)
Originally attempted WMRR (instance lockouts) for this slot but
hit a name-collision with the existing WHLD catalog at the same
file path. Reverted plumbing additions and pivoted to WCFR — a
distinct, complementary domain not covered by any existing
format.
Novel replacement for the per-stat-conversion ratios vanilla
WoW carried in the gtChanceTo*.dbc gameobject tables + the
per-class hard-coded constants in the server's StatSystem (the
"Strength gives 2 AP for Warriors but 1 AP for Mages" rule was
hard-coded; the "1 Agility = 1 Crit% for Hunters but 0.5 Crit%
for Druids" was hard-coded). Each WCFR entry binds one
(outputStat, inputStat, classMask, level-band) tuple to its
conversion ratio in fixed-point units (fp_x100: 100 = 1.0).
Three presets demonstrating per-class ratio variation:
--gen-cfr-warrior 4 Warrior formulas (Str->AP 2.0 / Agi->
Crit 0.05% / Agi->Dodge 0.05% / Str->
Parry 0.04% gated to level 30+)
--gen-cfr-mage 3 Mage formulas (Int->SpellPower 1.0 /
Int->SpellCrit 0.02% / Spi->OOC SpellPower
0.50)
--gen-cfr-rogue 4 Rogue formulas (Str->AP 1.0 / Agi->AP
1.0 / Agi->Crit 0.07% / Agi->Dodge 0.07%)
— Rogue Agi->Crit ratio (7) significantly
better than Warrior's (5), demonstrating
the per-class differentiation the format
captures
Validator catches: id+name required, outputStatKind 0..7,
inputStatKind 0..4, no duplicate formulaIds, no zero
conversionRatio (no-op formula). CRITICAL: no duplicate
(output, input, classMask, levelMin) quad — runtime stat-
compute would apply both formulas, doubling the contribution.
levelMax >= levelMin when set. Warns on conversionRatio > 100x
(likely units-mismatch typo from porting a percentage table
without dividing by 100).
Format count 144 -> 145. CLI flag count 1499 -> 1506.
|
||
|
|
ab69171ad9 |
feat(pipeline): WCAM camera presets catalog (144th open format)
Novel format covering what vanilla WoW handled with hard-coded
camera profiles in the client's CameraMgr (the standard third-
person camera, the flight-path camera, vehicle cameras and
cinematic cameras were all bespoke C++ classes with no data-
driven extension point). Each WCAM entry binds one camera
preset to its FOV, distance, pitch/yaw offsets, shoulder offset,
focus-bone tracking target (M2 bone index, 0xFFFF = follow root),
motion damping curve (0=instant follow / 255=maximum lag), and
intended purpose (Cinematic / Combat / Mounted / Vehicle /
Cutscene / PhotoMode).
Three presets covering common camera scenarios:
--gen-cam-combat 3 Combat variants (default 75deg / wide
ranged 90deg / tight melee 60deg
shoulder-cam tracking chest bone) with
low motion damping (8-15) for responsive
tracking
--gen-cam-mounted 2 Mounted variants (ground 80deg pulled-
back / flying 85deg high-pitch wing-frame)
with medium-high damping (60-90) for
smooth turning
--gen-cam-cinematic 3 Cinematic angles (over-shoulder
dialogue 50deg telephoto / wide
establishing 100deg / portrait 35deg
3/4-face composition with yaw offset and
head-bone tracking) with high damping
(180-220) for film-quality motion
Validator catches: id+name required, purposeKind 0..5, no
duplicate presetIds, FOV in (0,180) (zero/negative makes no
sense, >=180 inverts the view frustum), distanceFromTarget >= 0
(negative places camera in front of target). CRITICAL: pitch
within (-89, +89) — beyond gimbal-locks the camera. Warns on
FOV outside 30..120 player-comfort range (motion-sickness risk
or extreme telephoto compression), distanceFromTarget < 0.5m
(clips into model), and yawOffsetDegrees beyond ±180° (wraps to
smaller equivalent angle — simplify).
Format count 143 -> 144. CLI flag count 1490 -> 1497.
|
||
|
|
5f5a696495 |
feat(pipeline): WCMD chat slash command catalog (143rd open format)
Novel replacement for the implicit slash-command registry
vanilla WoW carried in the client's ChatFrame.lua + server-side
per-command CommandHandler hooks (no formal data-driven catalog;
commands were registered ad-hoc with hard-coded security checks
scattered across LevelMgr / WorldMgr / CharacterMgr). Each WCMD
entry binds one command name to its aliases, minimum security
level required, argument schema string, help text, per-player
throttle in ms, hidden flag (for debug-only commands), and
category.
Three presets covering the security-tier spectrum:
--gen-cmd-basic 4 standard player Info commands (/who
/played /time /ginfo) at Player security
with no throttle
--gen-cmd-movement 3 emote-style Movement commands (/sit
/stand /sleep) with short typing-speed
aliases ("sd" / "su" / "sd")
--gen-cmd-admin 3 GameMaster-only Admin commands
(/announce 5s throttle / /kick 2s
throttle / /ban 10s throttle —
demonstrating per-command rate-limiting
to prevent admin-spam abuse)
Validator catches: id+command required, minSecurityLevel 0..4,
category 0..4, no duplicate cmdIds. CRITICAL: command names
AND aliases share one flat namespace (chat parser dispatches
uniformly by typed string) — duplicate name across canonical+
aliases errors. Warns on uppercase chars in names (parser is
case-insensitive but convention is lowercase), Admin-category
command at Player/Helper security level (likely security
misconfiguration — admin commands usually require GameMaster+),
throttleMs > 60000 (likely ms-vs-s units typo — 60+ second
throttle is nearly unusable), self-alias (canonical already
matches), and empty helpText (/help would show the command
without description).
Format count 142 -> 143. CLI flag count 1481 -> 1488.
|
||
|
|
ec81c9b529 |
feat(pipeline): WTUR tutorial steps catalog (142nd open format)
Novel format covering what vanilla WoW had as a hard-coded LUA
tipbox sequence (TutorialFrame.xml + Tutorial.lua client-side
with no data-driven extension point). Each WTUR entry binds
one tutorial step to a trigger event (Login / ZoneEnter /
LevelUp / ItemPickup / SkillTrain), an ordered stepIndex within
that trigger group, a title + body for the popup, optional UI-
element name to highlight, and a hide-after auto-dismiss timer.
Three presets covering the most common tutorial scenarios:
--gen-tut-newbie 5 first-login steps (Welcome / Camera /
Interact NPCs / OpenQuestLog / OpenBags)
with 30s auto-dismiss and UI-element
highlight names ("MovementHint",
"QuestLogButton", "BagButton")
--gen-tut-levelup 3 LevelUp-trigger steps gated on
specific level milestones (level 2
spellbook hint / level 5 trainer visit /
level 10 talent unlock)
--gen-tut-bg 3 ZoneEnter-trigger steps gated to BG
mapIds (AV=30 explains 40v40 / WSG=489
explains capture-flag / AB=529 explains
control-point) — explains each ruleset
on first BG entry
Validator catches: id+name+title+body required, triggerEvent
0..4, stepIndex > 0 (sequence starts at 1), no duplicate
tutIds, no duplicate (event,value,step) triples (sequence
ordering ambiguity). CRITICAL: hideAfterSec MUST be 0 (no
auto-dismiss) OR >= 5s — else popup vanishes before player
can read it. Warns on Login event with non-zero triggerValue
(dead data, Login is unconditional), non-Login event with
triggerValue=0 (would fire for ALL events of that kind), and
body length < 10 chars (likely placeholder text).
Format count 141 -> 142. CLI flag count 1472 -> 1479.
|
||
|
|
8c36fc5274 |
feat(pipeline): WSWP sound swap rules catalog (141st open format)
Novel format covering a need vanilla WoW lacked entirely:
priority-based sound substitution. Blizzard had no formal
mechanism for swapping a stock SoundEntry for a custom
replacement conditionally on zone/class/race/gender; the
closest equivalents were patch-level SoundEntries.dbc edits
with no condition support. Each WSWP entry binds one
(originalSoundId, condition) trigger to a replacementSoundId,
a priority index for tie-breaking (higher wins), and an
optional gain adjustment in 0.1 dB units (range ±30 dB
practical mixer limit).
Three presets covering common substitution scenarios:
--gen-swp-bosses 3 raid-boss zone-only swaps (Onyxia roar
in Onyxia's Lair / Ragnaros emerge in
Molten Core +2dB / Nefarian shout in BWL).
Priority 100 — beats global rules
--gen-swp-race 3 race-conditional voice swaps (BloodElf
priest / Tauren shaman / Undead warlock
cast voices). Priority 50
--gen-swp-ui 3 always-on UI sound swaps (level-up /
quest-complete / mount-up) at priority
10 with +3dB gain (boss/race overrides
win the priority fight)
Validator catches: id+name+original+replacement required,
conditionKind 0..4, no duplicate ruleIds, no self-replacement
(orig==repl is a no-op slot), non-Always kinds require non-
zero conditionValue (kind without target = matches everything,
duplicating Always semantics). CRITICAL: no duplicate
(originalSoundId, conditionKind, conditionValue) trigger
triple — runtime would have two rules for the same trigger
without a tie-breaker. Warns on priorityIndex=0 (rule never
wins), |gainAdjustDb_x10| > 300 (clip risk), Always condition
with non-zero conditionValue (dead data ignored at runtime),
and same-priority within same originalSoundId (tie-break
undefined when both rules' conditions match simultaneously).
Format count 140 -> 141. CLI flag count 1463 -> 1470.
|
||
|
|
a10497a026 |
feat(pipeline): WBRD battleground reward stages catalog (140th open format)
Novel replacement for the per-BG per-bracket reward
configuration vanilla WoW carried in BattlemasterList.dbc +
the hard-coded honor table in the server's BattlegroundMgr
(the "Mark of Honor" item granted on win/loss was hard-coded
per-BG type with no formal data-driven scaling). Each WBRD
entry binds one (battlegroundId, levelBracket) pair to its
win/loss honor amounts, win/loss marks, the mark itemId, an
optional weekly-bonus item, and a minimum-players-to-start
gate.
Three presets covering canonical vanilla BGs:
--gen-brd-av Alterac Valley reward ladder for brackets
5-6 (51-69 only — AV was endgame). 20
players/side, Mark of AV item 17502
--gen-brd-wsg Warsong Gulch ladder for all 6 brackets
(10-69), 10 players/side, Mark of WSG item
20558, monotonically scaling honor
(50/100/200/350/500/750)
--gen-brd-ab Arathi Basin ladder for brackets 2-6
(20-69), 15 players/side, Mark of AB item
20559, includes weekly bonus quest token
(placeholder itemId 20560)
Validator catches: id+battlegroundId required, bracketIndex
1..6 (vanilla), no duplicate rewardIds, no duplicate
(bgId,bracket) pairs (runtime reward-lookup tie),
bonusItemCount > 0 requires non-zero bonusItemId, minPlayers
ToStart > 0 (else BG queue would never start a match).
CRITICAL: lossHonor <= winHonor (else losing rewards more
than winning, no incentive to play to win — would degenerate
into AFK farming). Warns on winMarks=0 with markItemId set
(vanilla wins always granted at least 1 mark).
Format count 139 -> 140. CLI flag count 1454 -> 1461.
|
||
|
|
4b63025e4a |
feat(pipeline): WAUH auction house config catalog (139th open format)
Novel replacement for the implicit per-faction auction-house
policy vanilla WoW carried in AuctionHouse.dbc + the hard-
coded deposit/cut rate constants in the server's AuctionMgr
(the 5% Alliance/Horde rate vs 15% neutral Booty Bay rate
was hard-coded on AH faction id). Each WAUH entry binds one
auction house instance to its faction-access rules,
deposit-rate (% of vendor sell price held as deposit), AH cut
(% taken from final sale price before crediting seller),
allowed listing durations (min/max hours), per-slot copper
fee, and the auctioneer NPC binding.
Three presets capturing canonical vanilla AH instances:
--gen-auh-stormwind Alliance Stormwind Trade District AH
with 5%/5% deposit/cut rates, 12-48hr
listing tiers, NPC Auctioneer Tricket
(creatureId 8666)
--gen-auh-orgrimmar Horde Orgrimmar Valley of Strength AH
with same vanilla rates as Stormwind,
NPC Auctioneer Tahesh (9856)
--gen-auh-bootybay Neutral Booty Bay AH with the famous
15%/15% penalty rates, NPC Auctioneer
Beardo (9858)
Validator catches: id+name required, factionAccess 0..3,
depositRatePct + cutPct each in 0..10000 (basis points), no
duplicate ahIds, no duplicate (faction,name) pairs (UI tab
dispatch tie), no duplicate npcAuctioneerId (gossip dispatch
tie), maxListingDurationHours > 0 and minListing <= maxListing.
CRITICAL: combined depositRatePct + cutPct < 10000 (else
seller would lose money on every successful sale — economic
trap). Warns on combined > 50% (sellers may abandon AH;
verify intentional like neutral AH penalty).
Format count 138 -> 139. CLI flag count 1445 -> 1452.
|
||
|
|
73d66a04d0 |
feat(pipeline): WPRC spell proc rules catalog (138th open format)
Novel replacement for the implicit proc-on-event spell triggers
vanilla WoW carried in SpellProcEvents (later rows of
Spell.dbc) + the per-spell procFlags + procChance fields
scattered across multiple DBC tables. Each WPRC entry binds
one proc rule to its source spell (the aura/buff that has the
proc), trigger event (OnHit/OnCrit/OnCast/OnTakeDamage/OnHeal/
OnDodge/OnParry/OnBlock/OnKill), proc chance in basis points
(0..10000 = 0..100%), internal cooldown ms, the spell to
trigger on proc, max-stacks-on-target cap, and optional
condition flags (RequireMeleeWeapon / RequireSpellSchool /
ExcludeAutoAttack / OnlyFromBehind / OnlyVsPvPTarget).
Three presets covering common vanilla proc archetypes:
--gen-prc-weapon 3 weapon-enchant procs (Crusader 2%
OnHit / Lifestealing 5% / Fiery Weapon
7% with 1.5s ICD to handle dual-wield)
--gen-prc-ret 4 Retribution Paladin procs (Vengeance
OnCrit 5-stack / Seal of Justice OnHit
25% with 60s per-target ICD / Reckoning
OnBlock 10% extra-attack / Sanctity Aura
OnCast bookkeeping)
--gen-prc-rage 3 Warrior Rage-generation procs
(Bloodrage OnCast / Berserker Rage
OnCast immunity aura / Anger Mgmt OnDodge
passive)
Validator catches: id+name+sourceSpellId+procEffectSpellId
required, triggerEvent 0..8, procChancePct in 1..10000
(0 = never fires; > 10000 = > 100% basis points). CRITICAL:
sourceSpellId == procEffectSpellId on OnCast trigger errors
(infinite proc loop — the effect re-casts itself which fires
the proc again). Warns on 100% + 0ms ICD on high-frequency
events (OnHit/OnCrit/OnTakeDamage) — would spam every swing
without rate limiting.
Validator immediately caught a real preset bug during smoke-
test: Berserker Rage initially had sourceSpellId=18499 ==
procEffectSpellId=18499 with OnCast trigger. Validator
correctly errored with "infinite proc loop". Fixed preset to
use procEffectSpellId=23691 (the immunity-aura effect — a
distinct spell from the cast trigger).
Format count 137 -> 138. CLI flag count 1436 -> 1443.
|
||
|
|
b6a88ff964 |
feat(pipeline): WIRC item random-property pool catalog (137th open format)
Novel replacement for the random-suffix enchant pool that
vanilla WoW carried in ItemRandomProperties.dbc +
ItemRandomSuffix.dbc (TBC+) + the per-item RandomProperty
rolls baked into the LootMgr. Each WIRC entry binds one
random-property pool to a name suffix ("of the Bear", "of the
Eagle"), a weighted enchant table (variable-length array of
{enchantId, weight}), and the equipment slots + class
restrictions where the suffix can roll.
At loot time, each green+ item rolls one pool based on its
slot, then picks one enchant from that pool weighted by
enchant.weight / totalWeight. The denormalized totalWeight
field is precomputed for the loot generator's hot-path roll.
Three presets covering the canonical vanilla suffix archetypes:
--gen-irc-bear STA-focused for plate slots (Helm/Chest/
Leg/Boot) with 4 weighted +Sta enchants
(3/5/7/10 — middle tier most common at
weight 50/100). Warrior+Paladin+DK class
mask
--gen-irc-eagle INT+STA caster pool for cloth slots with
5 weighted +Int+Sta enchants (3/5/7/10/12).
Mage+Priest+Warlock class mask
--gen-irc-tiger STR+AGI hybrid for leather slots with 5
weighted enchants. Rogue+Hunter+Druid class
mask
Validator catches: id+name required, allowedSlotsMask != 0
(else pool is unreachable — no slot would ever roll it),
non-empty enchant array, no zero-id enchants, no duplicate
enchantIds within same pool (should be merged with summed
weight). CRITICAL: totalWeight MUST equal sum of enchant
weights (else the loot generator's denormalized roll
mis-picks the distribution — players would see wrong rates of
each enchant tier). Warns on enchant weight=0 (never picked,
dead entry to remove or assign weight).
Format count 136 -> 137. CLI flag count 1427 -> 1434.
|
||
|
|
d2e623de9f |
feat(pipeline): WBHV creature behavior catalog (136th open format)
Novel replacement for the implicit creature-behavior rules
vanilla WoW carried in creature_template.AIName + per-creature
C++ scripts in the server's ScriptMgr (most rare-elites and
bosses had hand-coded class-derived behaviors). Each WBHV entry
binds one combat behavior archetype to its creature kind (Melee
/ Caster / Tank / Healer / Pet / Beast), aggro / leash radii,
evade-on-leash policy (ResetToSpawn / HealAtPath / FleeToSpawn
/ NoEvade for raid bosses), corpse persistence duration,
default rotation spell, and a variable-length list of special
abilities (spellId + cooldown + use-chance triplets in basis
points).
Three presets covering common archetypes:
--gen-bhv-melee 3 entry-tier melee creatures (Kobold Worker
+ Timber Wolf + Stranglethorn Raptor) with
1 special ability each
--gen-bhv-caster 3 caster patterns (Defias Wizard with
Polymorph + Frost Nova / Murloc Coastrunner
with Frost Bolt + Lesser Heal / Voidwalker
Pet Pattern with Taunt + Sacrifice +
Suffering — Sacrifice intentionally has
useChancePct=0 as owner-triggered, exercising
the validator owner-triggered warning)
--gen-bhv-boss 1 Onyxia-pattern dragon (Tank kind,
NoEvade leash, 600s corpse for 40-man loot
distribution, 4 abilities including 90s-CD
Deep Breath)
Validator catches: id+name required, creatureKind 0..5,
evadeBehavior 0..3, aggroRadius > 0, no duplicate behaviorIds,
no zero-spellId specials, no duplicate spellId within same
behavior. CRITICAL invariant: leashRadius >= aggroRadius (else
creature evades back to spawn before reaching its target —
permanently un-killable from outside the leash radius). Warns
on corpseDuration < 60s (looting may fail in busy zones), and
useChancePct=0 on a special ability (correctly flagged on the
Voidwalker Sacrifice spec — verified live in smoke-test).
Format count 135 -> 136. CLI flag count 1418 -> 1425.
|
||
|
|
19af564a27 |
feat(pipeline): WBND soulbind rules catalog (135th open format)
Novel replacement for the implicit item-binding policy vanilla
WoW carried in ItemTemplate.bondingType + per-item special-case
rules in the server's LootMgr (the 2-hour raid-loot trade
window was hard-coded; the account-bound-shared-across-faction
rule for heirlooms was a TBC+ addition with no formal data-
driven format). Each WBND entry binds one soulbind rule to its
bind kind (BoP / BoE / BoU / BoA / Soulbound / NoBind),
itemQualityFloor predicate (rule applies to items of this
quality and above unless overridden by a stricter rule),
tradable-window duration, raid-trade allowance, BoE-becomes-
BoP trigger, and cross-faction sharing flag.
Three presets capturing actual expansion-era policy evolution:
--gen-bnd-vanilla 4 rules — Poor=NoBind, Common=BoE,
Uncommon+=BoP no-window, Epic+=Soulbound.
NO raid-trade window — the 1.12 master-
loot drama era
--gen-bnd-tbc 5 rules adding the iconic 2-hour raid-
trade window for BoP items (Uncommon and
Rare quality)
--gen-bnd-wotlk 6 rules adding Heirloom = BindOnAccount
+ cross-faction (Alliance<->Horde via
account-mail) for the WotLK level-1-to-80
twink path
Validator catches: id+name required, bindKind 0..5,
itemQualityFloor 0..7, no duplicate ruleIds, no duplicate
(bindKind,qualityFloor) pairs (resolveForQuality lookup tie).
Hard error: tradableForRaidGroup=true with window=0 (window
expires instantly = no window at all). Warns on contradictions:
tradableForRaidGroup with non-BoP kind, window > 0 without
raid-trade flag, boeBecomesBoP without BoE kind,
accountBoundCrossFaction without BoA kind (all flag-ignored at
runtime).
Format count 134 -> 135. CLI flag count 1409 -> 1416.
|
||
|
|
fd6039973a |
feat(pipeline): WLOC world locations catalog (134th open format)
Novel unified replacement for the half-dozen proprietary
location tables vanilla WoW scattered across AreaPOI.dbc
(zone-discovery landmarks), gameobject_template.spawn rows
(herb/mineral/fishing nodes), creature_template rare-spawn
entries, and AreaTrigger.dbc (zone boundary teleports). Each
WLOC entry binds one world coord (mapId, x, y, z) to its kind
(POI / RareSpawn / HerbNode / MineralVein / FishingSpot /
AreaTrigger / PortalLanding), respawn timer, gathering-skill
gate, and on-discovery XP.
Three presets covering the major location flavors:
--gen-loc-poi 4 Alliance POIs (Stormwind/Ironforge/
Goldshire/Sentinel Hill) with discoverable
XP (50..100) and POI-kind iconry
--gen-loc-herb 5 Elwynn/Westfall herb nodes (Peacebloom
skill 1 to Stranglekelp skill 85) with 600s
respawn and Herbalism (skillId 182) gating
--gen-loc-rare 4 vanilla rare-elites with realistic
respawn timers (Mor'Ladim 1hr, Princess
Tempestria 2hr, Foreman Rigger 30min, Lord
Sakrasis 1hr)
Validator catches: id+name required, locKind 0..6,
factionAccess 0..3, no duplicate locationIds, spawnable kinds
(Rare/Herb/Mineral/Fishing) MUST have respawnSec > 0 (else
entity spawns once and never returns — common typo when
adding new spawns). Warns on discoverableXp set with non-POI
kind (XP would never award), requiredSkillId set with non-
gather kind (skill check would never fire), and gather kind
with skill > 0 but level = 0 (every player satisfies — almost
certainly a typo).
Format count 133 -> 134. CLI flag count 1400 -> 1407.
|
||
|
|
7df59b1d80 |
feat(pipeline): WCRA crafting recipe catalog (133rd open format)
Novel replacement for the implicit recipe expansion vanilla WoW
carried in SpellReagents.dbc + Spell.dbc effect-24 (CREATE_ITEM)
+ per-trade-skill SkillLineAbility rows. Each WCRA entry binds
one trade-skill recipe spell to its variable-length reagent
list (itemId+count pairs, vanilla cap 8, format cap 32),
produced-item id + count, the trade skill it belongs to, the
minimum skill level to cast, and the source item that teaches
the recipe.
Three presets seeded with canonical vanilla item/spell IDs:
--gen-cra-alchemy 4 potions (Minor/Lesser Healing+Mana,
Greater Healing, Major Mana) using
herb itemIds 2447/765/2450/3357/etc
and Empty Vial / Crystal Vial
--gen-cra-engineering 3 recipes including Target Dummy with
5 reagents (variable reagent count
demonstration); learnedFromItemId
references the recipe blueprint
--gen-cra-blacksmithing 3 recipes covering low/mid/high tiers
(skill 1 / 50 / 235) including Heavy
Mithril Helm with 4 different bar/ore
reagents
Validator catches: id+name+spellId+tradeSkillId+producedItemId+
producedCount required, no duplicate recipeIds, no duplicate
spellIds (cast-handler conflict — two recipes responding to the
same cast), no zero-itemId/zero-count reagents, no duplicate
reagent itemIds within a single recipe (should be merged into
single entry with summed count), no self-reagent (recipe
consuming its own produced item is a perpetual-motion bug).
Warns on requiredSkillLevel > 450 (above WotLK cap) and empty
reagent list (free-to-craft is unusual but allowed for some
alchemy transmutes).
Format count 132 -> 133. CLI flag count 1391 -> 1398.
|
||
|
|
76cda20297 |
feat(pipeline): WQGR quest graph catalog (132nd open format)
Novel representation of quest-chain dependencies that vanilla
WoW carried implicitly in QuestRelations.dbc (the prequest
column) + per-quest server scripts. Each WQGR entry binds one
quest to its display name, level/class/race gating,
prerequisite quest list (must be completed first), follow-up
quest hints (next-quest suggestions for the journal UI), and
quest type flags (Normal / Daily / Repeatable / Group / Raid).
Three presets:
--gen-qgr-starter 5-quest linear chain (Northshire human-
starter Q100..Q104, levels 1..8) with
chainHeadHint=1 on Q100
--gen-qgr-branched 4-quest converging DAG (Q200 unlocks
both Q201 + Q202, both required for Q203)
— demonstrates true DAG semantics, not
just linear lists
--gen-qgr-dailies 3 standalone daily quests (Daily type,
no prereqs, no followups)
Validator catches: id+name required, questType 0..4,
factionAccess 0..3, maxLevel >= minLevel, no self-prereq
(catch-22), no missing prereq questId, full DFS cycle detection
on prevQuestIds (progression deadlock — quests would be
unreachable). Reuses the proven cycle-extraction pattern from
WMOD addon manifest (extracts back-edge path so the editor sees
the loop). Warns on followup hint to self/missing-id (advisory
only — followups are hints not contracts) and on
chainHeadHint=1 with non-empty prereqs (contradicts chain-head
semantics).
Format count 131 -> 132. CLI flag count 1382 -> 1389.
|
||
|
|
98316b48ac |
feat(pipeline): WGBK guild bank tabs catalog (131st open format)
Novel format providing what vanilla WoW lacked entirely: a
guild-level shared storage facility (Blizzard added guild banks
in TBC, but the Wowee project provides this format from day one
for the Classic-1.12 server flavor as well as later expansions).
Each WGBK entry binds one guild bank tab to its display label,
slot count (1..98 vanilla cap), deposit-only flag, icon, and a
fixed-size per-guild-rank withdrawal limit array (slots/day cap
per rank 0..7, where rank 0 is GuildMaster, kUnlimited =
0xFFFFFFFF).
Three presets:
--gen-gbk Standard 4-tab bank (General/Materials/
Consumables/Officer) for guildId 1 with
progressive per-rank caps
--gen-gbk-raid 5-tab raid guild (Tier1_BWL/Tier2_AQ40/
Tier3_Naxx + Consumables + Officer) — tier
tabs strictly officer-only with 4-slot/day
cap on rank 1
--gen-gbk-small 2-tab small guild (General + Officer) with
tight 5-slot/day caps below officer rank
Validator catches: id+guildId+tabName required, slotCount 1..98
(vanilla cap), GM withdrawal limit > 0 (rank 0 cannot be locked
out — almost certainly a typo), per-rank monotonicity (lower
rank cannot exceed higher rank's cap — kUnlimited treated as
infinity for compare), no duplicate tabIds, no duplicate
(guildId,tabName) pairs (UI dispatch tie). Warns on depositOnly
flag set with non-zero rank-0 limit (self-contradiction — flag
overrides at runtime but data is contradictory).
Format count 130 -> 131. CLI flag count 1373 -> 1380.
|
||
|
|
b66e41df87 |
feat(pipeline): WCST combat stats baseline catalog (130th open format)
Novel replacement for the per-class per-level base-stat scaling
table that vanilla WoW scattered across CharBaseInfo.dbc +
CharStartOutfit.dbc + GtChanceTo*.dbc + the hard-coded HP/mana-
per-level constants in the server's StatSystem. Each WCST entry
binds one (classId, level) pair to base health, mana, armor, and
the five primary stats (Str/Agi/Sta/Int/Spi).
Sparse design: presets emit ~6 sample levels per class with the
runtime stat-interpolator computing intermediate levels.
Three presets:
--gen-cst-warrior Warrior (classId=1) sparse sample at L1/
10/20/30/40/60. baseMana=0 across all
entries (Warrior uses Rage)
--gen-cst-mage Mage (classId=8) same 6 levels with mana
growth tracking Intellect
--gen-cst-starting All 9 vanilla classes at level 1 — shows
per-class flat starting differences
(Warrior/Paladin high Str; Hunter/Rogue
high Agi; Mage/Priest/Warlock high Int;
Shaman/Druid balanced)
Validator catches: id+classId+level required, classId 1..11,
level 1..60, zero baseHealth (player would die instantly),
duplicate statIds, duplicate (classId,level) pairs (runtime
stat-lookup tie). Warns on classId 6/10 (DK/Monk gap unused
in vanilla), Warrior/Rogue baseMana > 0 (these classes use
Rage/Energy not mana), and per-class monotonicity violations
across all 8 stats — sorts by level, walks adjacent pairs,
flags any stat that regresses as level increases (typo guard).
Format count 129 -> 130. CLI flag count 1364 -> 1371.
|
||
|
|
be3a253dcc |
feat(pipeline): WPRT mage portal destinations catalog (129th open format)
Novel replacement for the implicit portal-spell -> destination-
coordinate binding vanilla WoW carried in scattered pieces:
SpellEffects.dbc effect-71 (TELEPORT_UNITS) + per-spell hard-
coded destination tables in the server's SpellMgr +
AreaTrigger.dbc destination rows. Each WPRT entry binds one
Teleport/Portal spellId to its destination world coords,
faction-access gate, level requirement, and reagent
requirement.
PortalKind enum captures the canonical Teleport (self-only,
Rune of Teleportation, level 20) vs Portal (group, Rune of
Portals, level 40) distinction.
Three presets:
--gen-prt-alliance 4 Alliance city portals (Stormwind /
Ironforge / Darnassus / Theramore) with
canonical spellIds 10059/11416/11419/
49361 and Rune of Portals reagent
--gen-prt-horde 3 Horde city portals (Orgrimmar /
Undercity / Thunder Bluff)
--gen-prt-teleports 3 self-teleports paired across factions
(Teleport: Stormwind/Ironforge Alliance +
Teleport: Orgrimmar Horde) — illustrates
the Teleport-vs-Portal kind distinction
with proper reagent (Rune of Teleportation
17031 NOT Rune of Portals 17032)
Validator catches: id+spellId+destination required,
factionAccess/portalKind range, no duplicate portalIds, no
duplicate spellIds (cast-handler conflict). Warns on
levelRequirement < 20 (vanilla mage cannot unlock), Portal kind
without Rune of Portals (17032), Teleport kind without Rune of
Teleportation (17031), and duplicate destination names (could be
legitimate Teleport+Portal pair OR copy-paste bug — the editor
flags both).
Format count 128 -> 129. CLI flag count 1355 -> 1362.
|
||
|
|
12e77e69ce |
feat(pipeline): WTSC transit schedule catalog (128th open format)
Novel replacement for the implicit taxi/zeppelin/boat scheduling
that vanilla WoW drove from a tangle of TaxiNodes.dbc +
TaxiPath.dbc + per-zeppelin GameObject scripts + hard-coded
transport interval timers in the server's MapManager. Each WTSC
entry binds one scheduled passenger route to its origin /
destination coords, vehicle type (Taxi/Zeppelin/Boat/Mount),
departure interval, in-flight duration, capacity, and faction-
access gate.
Initially designed with magic 'WTRN' but discovered collision
with existing trainers catalog (also WTRN) — renamed to 'WTSC'
(Transit SChedule) and updated all CLI flags.
Three presets:
--gen-trn-zeppelins 3 vanilla Horde zeppelin routes
(OG<->UC 240s interval, OG<->Grom'Gol,
UC<->Grom'Gol)
--gen-trn-boats 3 vanilla boat routes (Auberdine<->
Stormwind Alliance, Menethil<->Theramore
Alliance, BootyBay<->Ratchet Neutral
cross-faction)
--gen-trn-taxis 3 taxi gryphon/wyvern routes — capacity=0
indicates solo gryphon ride
CRITICAL scheduling invariant validator catches: when capacity > 0
the departureInterval MUST be >= travelDuration. A zeppelin with
interval=60s + travel=90s with capacity=40 would overflow the
vehicle pool — next zeppelin departs before prior arrives. Solo
gryphon (capacity=0) is exempt because each ride is independent.
Validator also catches: id+name+origin+destination required,
vehicleType/factionAccess range, zero intervals/travel, duplicate
routeIds, duplicate route names. Warns on same-map routes
(originMapId == destinationMapId) — preset taxi route Crossroads
to Razor Hill triggered this warning in smoke-test (both in
Kalimdor mapId=1, intentional).
Format count 127 -> 128. CLI flag count 1346 -> 1353.
|
||
|
|
949a6e0182 |
feat(pipeline): WPHM player movement-to-animation map (127th open format)
Novel replacement for the implicit movementState->animation
binding that vanilla WoW baked into per-race M2 model files.
Each WPHM entry binds one (raceId, genderId, movementState)
tuple to a base M2 animation sequence id, an optional variant
sequence (drunk-walk, wounded-run), and a blend transition
duration in milliseconds.
8-state machine: Idle / Walk / Run / Swim / Fly / Sit / Mount /
Death. Three presets each emit the full 16 bindings (M+F):
--gen-phm-human 16 bindings with drunk-walk variant on Walk
--gen-phm-orc 16 bindings with AttackRun variant on Run
for war-stance flavor
--gen-phm-undead 16 bindings with canonical shambling variant
(anim 38) on Run for low-health renderer
override + slower swim transition (undead are
awkward in water)
Validator catches: id required, raceId 1..10, genderId 0..1,
movementState 0..7, no duplicate mapIds, no duplicate
(race,gender,state) triples (renderer dispatch ambiguity),
baseAnimId=0 forbidden on non-Idle states (model would freeze
when entering that state). Warns on variantAnimId==baseAnimId
(no-op overhead) and transitionMs > 2000 (would feel like
animation hang).
Format count 126 -> 127. CLI flag count 1337 -> 1344.
|
||
|
|
6d9d00fbb9 |
feat(pipeline): WSPK spell pack catalog (126th open format)
Novel replacement for the implicit per-class spellbook layout
that vanilla WoW derived from SkillLineAbility.dbc + the hard-
coded per-spec tab order baked into the client UI. Each WSPK
entry binds one (classId, tabIndex) pair to an ordered list of
spellIds shown in that spellbook tab.
Three presets seeded with canonical vanilla low-rank spellIds:
--gen-spk-warrior 4 tabs (General + Arms/Fury/Protection)
including Charge, Mortal Strike,
Bloodthirst, Shield Block
--gen-spk-mage 4 tabs (General + Arcane/Fire/Frost)
including Frostbolt rank 1 (spellId 116)
— the canonical "every mage starts here"
--gen-spk-rogue 4 tabs (General + Assassination/Combat/
Subtlety) with poison + lethality picks
Validator catches: packId+tabName required, classId in 1..11,
tabIndex in 0..3, no duplicate packIds, no duplicate
(classId,tabIndex) pairs (spellbook UI dispatch tie), no zero
spellIds, no duplicate spellIds within any single tab (would
render twice in spellbook). Warns on classId 6 and 10 (vanilla
PlayerClass DBC gaps) and on empty tabs (player would see a
blank spellbook tab).
Format count 125 -> 126. CLI flag count 1328 -> 1335.
|
||
|
|
9df1fa39cd |
feat(pipeline): WMOD addon manifest catalog (125th open format)
Novel replacement for vanilla per-addon TOC (.toc) text files
scattered across Interface/AddOns/. Each WMOD entry binds one
addon to display metadata (name / description / version / author),
client-build gate (minClientBuild), persistence + lazy-load
flags (requiresSavedVariables / loadOnDemand), and required +
optional dependency lists.
Three presets:
--gen-mod 4 vanilla-era addons (Recount standalone +
Atlas standalone + Auctioneer optional-dep
on Atlas + Questie standalone)
--gen-mod-ui 3 UI-replacement chain (Bartender4 root ->
ElvUI required-dep on Bartender4 -> SuperOrders
required-dep on ElvUI). Exercises the chained
required-dep resolution path.
--gen-mod-util 3 standalone utility addons (XPerl, Decursive,
GearVendor loadOnDemand) — empty-deps baseline.
Validator catches: id+name+version required, duplicate addonIds,
duplicate addon names (load-order ambiguity), self-dependency
(load deadlock), missing required-dep addonId, full DFS cycle
detection on required deps (deadlock at load — extracts the
back-edge path so the user can see the loop). Warns on optional
self-dep (no effect, prune) and on minClientBuild < 4500
(below vanilla floor — likely typo).
Format count 124 -> 125. CLI flag count 1319 -> 1326.
|
||
|
|
c7d85fc598 |
feat(pipeline): WGCH global chat channel catalog (124th open format)
Novel replacement for vanilla ChatChannels.dbc + the per-server
zone-default chat-join behavior. Each WGCH entry binds one chat
channel to its access policy: PublicJoin, InviteOnly,
AutoJoinOnZone (with zoneDefaultMapId), or Moderated. Entries
also carry channelKind (Global/RealmZone/Faction/Custom),
passwordRequired, levelMin, maxMembers cap, topic-mod-only flag,
and an icon RGBA color.
Three presets:
--gen-gch 4 standard server channels (LookingForGroup,
World, Trade auto-join Stormwind, General)
--gen-gch-rp 4 RP channels (RP_OOC public, RP_IC moderated
200-cap, RP_Forum invite-only 50-cap, RP_Events
password-protected)
--gen-gch-admin 3 moderator-only channels (GMTraffic, AuditLog,
Backstage — all password-gated)
Validator catches: id+name required, channelKind/accessKind
range, duplicate channelIds, duplicate channel names (which
would route /join ambiguously), AutoJoinOnZone with
zoneDefaultMapId=0 (auto-join trigger would never fire). Warns
on dead zoneDefaultMapId set with non-AutoJoin kind.
Format count 123 -> 124. CLI flag count 1290 -> 1317.
|
||
|
|
73323f0b9d |
feat(editor): add WLAN (Localization) — 123rd open format
Novel replacement for the per-language overlay tables vanilla WoW carried as Locale_*.MPQ patches plus the Spell.dbc / Item.dbc trailing 16-locale string columns. Each entry binds one (originalKey, languageCode, namespace) triple to its localized translation, forming a per-language overlay applied AFTER any per-format catalog has resolved its primary text. Eleven languageCode values cover the canonical WoW locales (enUS / enGB / deDE / esES / frFR / itIT / koKR / ptBR / ruRU / zhCN / zhTW) plus Unknown=255 as escape hatch. Eight namespace values segment the lookup space (UI / Quest / Item / Spell / Creature / Tooltip / Gossip / System) so a UI button "Cancel" doesn't collide with an item description containing the word "Cancel". UTF-8 multibyte support is the novel demonstration — the originalKey field is typically ASCII (English canonical key), but localizedText holds Korean (취소), Simplified Chinese (取消), or other non-Latin scripts. The string-length-prefixed binary serialization preserves byte-identical round-trip regardless of encoding. Three preset emitters: makeUIBasics (5 UI translations of the "Cancel" button across deDE/frFR/esES/koKR/zhCN including the Korean and Chinese multibyte UTF-8 strings), makeQuestSample (3 entries — one quest title in deDE/frFR/koKR illustrating the dotted-key convention "QUEST.123.title"), makeTooltipSet (4 item-tooltip strings in deDE+frFR — the high-volume client localization use case). Validator's most novel check is per-(originalKey, languageCode, namespace) triple uniqueness — two entries with all three matching would tie at runtime when the locale-aware text layer looks up an override. Plus the warning on empty localizedText (the override would render blank — possibly worse than fallback to the catalog default). Format count 122 -> 123. CLI flag count 1283 -> 1288. |
||
|
|
4ce07d5ca9 |
feat(editor): add WPRG (PvP Ranking grades) — 122nd open format
Novel replacement for the hardcoded 14-rank vanilla WoW PvP ladder (Private through Grand Marshal Alliance, Scout through High Warlord Horde). Each entry binds one (factionFilter, tier) combination to its display name, weekly RP threshold to maintain rank, lifetime honor for first-time achievement, title prefix for player- name display, and tier-set gear reward. The vanilla rank-ladder system used a weekly RP-decay mechanic that punished any week without play with rank- loss; this catalog stores both the weekly threshold (maintenance) and the lifetime threshold (achievement) since both are needed for accurate rank-progression simulation. Three preset emitters spanning the rank ladder: makeAllianceRanks (7 lower-tier ranks Private through Knight-Lieutenant), makeHordeRanks (7 mirrored Horde titles Scout through Blood Guard with identical honor thresholds — factionFilter disambiguates the shared "Sergeant" title), makeHighRanks (8 high-tier ranks across both factions Knight-Captain through Lt. Commander, tiers 8-11 with the iconic legendary battlegear shoulder unlocks). Tier 14 (Grand Marshal / High Warlord) intentionally omitted from presets — it's the legendary top-rank that historically required dedicated 24/7 grinding. Catalog supports tiers 1..14 in the schema; consumers extend as needed. Validator's most novel checks: per-(faction, tier) tuple uniqueness — two ranks at the same tier for the same faction would tie at runtime when the rank- progression UI looks up "what's tier 5 for Alliance?" Plus per-faction honor-threshold monotonicity — a higher tier requiring less honor than a lower tier would let players "downrank" by gaining honor, which is a content authoring bug. Format count 121 -> 122. CLI flag count 1276 -> 1281. |
||
|
|
0df50f9f72 |
feat(editor): add WANV (Anniversary & Recurring Events) — 121st open format
Novel replacement for the implicit recurring-event scheduler vanilla WoW encoded across the GameEvent SQL table + per-holiday script hooks. Each entry binds one calendar-driven recurring event (yearly holiday like Hallow's End, monthly tribute day, weekly Double XP Weekend, anniversary celebration) to its scheduling rule and its payload (a spell buff applied to all online players, a gift item granted on first event- window login). Eight eventKind values (Holiday / Anniversary / DoubleXP / DoubleHonor / PetBattleWeekend / BattlegroundBonus / SeasonalQuest / Misc) and four recurrenceKind values (Yearly / Monthly / Weekly / OneOff). The startDay field is polymorphic per recurrenceKind: Yearly/Monthly/OneOff use it as 1..31 day-of-month, Weekly uses it as 0..6 weekday (Sun..Sat) — the validator enforces both ranges per kind. Three preset emitters: makeStandardHolidays (5 yearly holidays with realistic spell+item payload bindings — Hallow's End spell 24710, Winter Veil 26157, Brewfest 42500, etc.), makeBonusEvents (4 weekly recurring bonuses — Friday triple-day weekends and Saturday- Sunday double-day pet-battle bonus), makeAnniversary (3 game-launch anniversaries — WoW Nov 23 / TBC Jan 16 / WotLK Nov 13 with overlapping celebration windows). Validator's most novel checks combine calendar + recurrence semantics: per-kind schedule validity (Weekly startDay 0..6 weekday, durationDays <= 7 to prevent self-overlap; Yearly/Monthly/OneOff startMonth 1..12, startDay 1..31 with calendar sanity — Feb cap at 29, Apr/Jun/Sep/Nov cap at 30 for "no Feb 30" / "no Apr 31" errors). Format count 120 -> 121. CLI flag count 1269 -> 1274. |
||
|
|
441ca0d139 |
feat(editor): add WCFG (Server Config) — 120th open format
Novel replacement for the worldserver.conf / mangosd.conf flat-text configuration files vanilla server forks shipped. Each entry binds one configId to its polymorphic value via the valueKind enum (Float / Int / Bool / String) — only the matching value field is authoritative per entry. The polymorphic value is the novel data shape: each entry stores ALL three value carriers on disk (floatValue float / intValue int64 / strValue string), and valueKind picks which is meaningful at runtime. Bool folds into intValue with strict 0/1 semantics. JSON export reflects this: an activeValue derived field renders the right form per kind so operators editing JSON see only the relevant value. Nine configKind values cover the full server-tunable surface: XPRate / DropRate / HonorRate / RestedXP / RealmType / WorldFlag / Performance / Security / Misc. Each kind groups settings the server iterates by kind at startup (all XPRate entries seed the per-class experience matrix; all Security entries configure the anti-cheat thresholds). Three preset emitters: makeRates (4 vanilla baseline rate multipliers with valueKind=Float), makePerformance (4 server tuning configs mixing Int and Float kinds — max creatures per cell, view distance yards, GC interval seconds, etc.), makeSecurity (4 anti-cheat configs FIRST format using valueKind=String for the cheat-detection sensitivity preset name). Validator's most novel checks are per-valueKind cross- field consistency: Bool requires intValue strictly 0/1 (error), and warns on cross-field bleed (Float kind with non-zero intValue means the int is silently ignored at runtime but persists on disk). Plus name uniqueness — server name-based config lookups would be ambiguous otherwise. Format count 119 -> 120 (multiple-of-10 milestone). CLI flag count 1262 -> 1267. |
||
|
|
0016b0d597 |
feat(editor): add WSKP (Sky Parameters) — 119th open format
Novel replacement for the LightParams.dbc + Light.dbc pair vanilla WoW used to drive the per-zone diurnal sky cycle. Each entry binds one (mapId, areaId, timeOfDayHour) triplet to its sky-rendering parameters: sky-dome zenith and horizon colors, sun angle and color, fog start/end distances, cloud-layer opacity, and cloud drift speed in tenths-mph. The renderer interpolates between adjacent keyframes when the in-game clock crosses an hour boundary, so a 4-keyframe set (Dawn/Noon/Dusk/Midnight) produces the full diurnal cycle through linear interpolation. Servers can author finer-grained keyframes (e.g. every 3 hours) for smoother transitions. Three preset emitters demonstrating the catalog's range: makeStormwindDay (4 standard temperate keyframes from lavender dawn through bright noon to deep blue-black midnight), makeNorthrendArctic (4 cold steel-blue keyframes with high-density ice fog peaking at the midnight blizzard whiteout — minimum 30yd visibility), makeOutlandHellfire (3 keyframes — no midnight, since Outland's permanent gravitational anomaly from the Twisting Nether keeps the sky lit; iconic crimson + orange palette throughout). Validator's most novel checks: per-(mapId, areaId, timeOfDayHour) triple uniqueness — two keyframes at the same hour for the same area would render in unstable order during diurnal interpolation. Plus fogStartYards >= fogEndYards (inverted falloff) error, sunAngleDeg outside [0,360] warning (renderer wraps modulo but suggests authoring confusion). Format count 118 -> 119. CLI flag count 1255 -> 1260. |
||
|
|
6fa81cf185 |
feat(editor): add WLMA (Loot Mode Policy) — 118th open format
Novel replacement for the implicit loot-distribution rules vanilla WoW encoded across the GroupLoot system (CMSG_LOOT_METHOD), the per-quality thresholds for Need-roll triggering, and the master-looter permission gates. Each entry binds one group-loot policy mode to its kind (FFA / RoundRobin / MasterLoot / Need-Before- Greed / Personal / Disenchant) plus quality threshold, master-looter requirement, idle-skip seconds, and disconnect-fallback policy. Six modeKind values cover the full loot-distribution surface. The thresholdQuality field uses the WIQR quality tier convention (0=Poor through 7=Heirloom) to gate Need-roll triggering — anything below threshold auto-distributes via FFA-equivalent semantics. The disconnect-fallback (timeoutFallbackKind) field is unique to MasterLoot policies — if the master looter disconnects mid-distribution, the policy auto-promotes to the fallback mode for democratic recovery. Common fallbacks: Need-Before-Greed (full roll system), FreeForAll (fastest unblock). Three preset emitters: makeStandard (4 5-man / casual modes covering FFA farming, RoundRobin trash, NBG Uncommon, MasterLoot Rare), makeRaidPolicies (3 raid loot policies including MasterLoot Epic with NBG fallback, Personal Loot, NBG Rare), makeAFKPrevention (3 AFK-mitigating modes with idleSkipSec gates). Validator's most novel check is per-kind consistency: MasterLoot kind REQUIRES masterLooterRequired=1 (else the policy contradicts itself — "Master Loot mode without requiring a master looter"). Personal kind warns if masterLooterRequired=1 (no-op flag). Tightened fallback-to-self warning to fire ONLY for MasterLoot where the field is meaningful — original version fired falsely for FFA/Personal/RoundRobin where the leader- disconnect scenario doesn't apply (caught + tightened during smoke-test). Format count 117 -> 118. CLI flag count 1248 -> 1253. |
||
|
|
42842958df |
feat(editor): add WMAR (Raid Marker Set) — 117th open format
Novel replacement for the hardcoded 8-marker raid set
vanilla WoW shipped (Star/Circle/Diamond/Triangle/Moon/
Square/Cross/Skull) plus world-map pin markers and
5-man party role markers. Each entry binds one marker
slot to its icon resource, single-character chat-overlay
glyph (for "{star}" chat-style links), and priority for
sort order in the marker-picker UI.
Four markerKind values (RaidTarget / WorldMap / Party /
Custom) cover the full marker-system surface. The chat-
overlay displayChar field enables the WoW-canonical
chat shortcuts: "{star}" gets rendered as a star icon
inline in chat, with "*" as the fallback glyph for
non-rich-text contexts (clipboard, log files, mod-
script handlers).
Three preset emitters: makeRaidTargets (8 canonical
raid markers in /raidicon priority order 0..7 with
their iconic colors and glyph mnemonics), makeWorldMap-
Pins (5 world-map pin markers — Pin/Flag/Crosshair/
Question/Compass), makeParty (4 role markers for group-
finder filtering — Tank/Healer/DPS/Caster).
Validator's most novel checks: per-(markerKind,
priority) tuple uniqueness — two markers at same kind+
priority would render in unstable picker UI order. Plus
RaidTarget priority > 7 warns (exceeds canonical 8-slot
/raidicon dispatch range; client keybind macros may not
reach the slot).
Format count 116 -> 117. CLI flag count 1241 -> 1246.
|
||
|
|
7d201cd6f3 |
feat(editor): add WWFL (Word Filter) — 116th open format
Novel replacement for the implicit chat-moderation patterns vanilla WoW carried in the bad-word checker (the hardcoded substring list the CMSG_MESSAGECHAT handler walked before broadcasting). Each entry defines one pattern the chat preprocessor matches against outbound messages, the replacement to apply (or "drop"/"warn"/"mute" the sender), and a kind tag for analytics. Seven filterKind values (Spam / GoldSeller / AllCaps / RepeatChar / URL / AdvertReward / Misc) and four severity levels (Warn — log only, Replace — substitute matched span, Drop — silently discard, Mute — drop AND mute sender). Per-filter caseSensitive flag for context- specific rules (uppercase shouting detection vs lowercase RMT keyword detection). Intentionally non-profanity focused — the ecosystem distributes through CI / public PRs where embedded profanity creates reviewer-experience and licensing concerns. The presets cover the moderation surfaces server admins actually need: makeSpamRMT (5 RMT patterns: wts/wtb gold drops, g0ld typo-substitution replace, 1000g-for bulk-offer drop, free-gold mute), makeAllCaps (3 shouting patterns), makeURLDetect (3 URL-leakage patterns: http://, https://, www.). Profanity-list integration is left to deployment-time configuration where local laws and community standards apply. Validator's most novel check is per-pattern uniqueness — two filters with the same pattern would dispatch ambiguously through the chat preprocessor. Also warns on Replace severity with empty replacement (would silently lose match — use Drop explicitly if intended). Format count 115 -> 116. CLI flag count 1234 -> 1239. |
||
|
|
05bb96d23b |
feat(editor): add WTRD (Trade Window Rules) — 115th open format
Novel replacement for the implicit player-to-player trade policy rules vanilla WoW hardcoded across the trade-window message handlers (CMSG_INITIATE_TRADE, CMSG_SET_TRADE_ITEM, CMSG_SET_TRADE_GOLD), the soulbound-item check, the cross-faction-trade rejection, and the GM-trade audit hooks. Each entry is one trade-policy rule the trade-window state machine consults at every state transition. Seven ruleKind values (Allowed / Forbidden / SoulboundException / CrossFactionAllowed / LevelGated / GoldEscrowMax / AuditLogged) and five targetingFilter values (AnyPlayer / SameRealmOnly / SameFactionOnly / SameAccountOnly / GMOnly) cover the full trade-policy surface. Priority field resolves rule conflicts — higher priority wins (Allowed at 100 overrides Forbidden at 10). Three preset emitters cover real-world deployment patterns: makeStandard (4 baseline rules — Soulbound Forbidden globally, Quest items Forbidden, 2hr Soul- boundException for raid trade-back, SameFactionOnly), makeServerAdmin (3 server-custom overrides — GM-only escrow at priority 100, AccountBound own-character transfer, CrossFactionAllowed at level 80 for RP servers), makeRMTPrevent (4 anti-RMT rules — 10g cap for low-level trades, 500g cap for accounts < 30 days, audit log for trades > 1000g, 24hr first-trade delay). Validator's most novel check is the GoldEscrowMax / goldEscrowMaxCopper consistency rule: a GoldEscrowMax- kind rule MUST specify a non-zero gold cap (zero would mean unlimited which contradicts the rule's purpose). Also warns on GMOnly targeting with priority < 50 (GM- mediated rules typically need high priority to override player-initiated rules) and levelRequirement > 80 (exceeds current cap, rule never applies). Format count 114 -> 115. CLI flag count 1227 -> 1232. |
||
|
|
78555a79b0 |
feat(editor): add WVOX (Voiceover Audio) — 114th open format
Novel replacement for the implicit per-NPC voice dialog system vanilla WoW encoded across CreatureTextSounds (server-side aggro/death barks), npc_text (gossip audio cross-references), and per-quest dialog blobs. Each entry binds one NPC to one voice clip for one triggering event with metadata covering audio path, duration, volume, gender hint for randomized casts, variant index for multiple lines per event, and a transcript field for accessibility (TTS engines + chat- bubble subtitles). Nine eventKind values cover the full NPC dialog surface: Greeting / Aggro / Death / QuestStart / QuestProgress / QuestComplete / Goodbye / Special / Phase. The Phase kind specifically supports boss-fight percentage milestones (75%/50%/25% transitions) where multiple Phase entries with distinct variantIndex disambiguate the boss-encounter scripting. Three preset emitters: makeQuestgiver (5-clip canonical quest dialog flow), makeBoss (6-clip Lich King fight with phase milestones at 75/50/25%, special mechanic call at +5dB for raid audibility, death line), makeVendor (4-clip vendor interaction). Validator's most novel check is per-(npcId, eventKind, variantIndex) triple uniqueness — two clips with all three matching would be ambiguous when the trigger handler picks one randomly. The vendor preset originally bound both Buy and Sell to (Special, 0) which the validator caught and flagged before commit; fix uses variantIndex 0 for Buy and 1 for Sell so the trigger handler can distinguish. Validator also warns on durationMs=0 with non-empty audioPath (subtitle sync impossible), volumeDb outside [-20,+6] (clip risk), and empty transcript (TTS + chat-bubble subtitle would be blank). Format count 113 -> 114. CLI flag count 1220 -> 1225. |
||
|
|
6403d84a28 |
feat(editor): add WSPV (Spell Variant) — 113th open format
Novel replacement for the implicit context-conditional spell substitution rules vanilla WoW encoded across SpellSpecificType, SpellEffect.EffectMechanic override fields, and the proc-modified spell tables in SpellProcEvent. Each entry binds one base spell to a variant spell that activates when a runtime condition is met (player in a specific stance, talent talented, racial buff active, weapon equipped, aura present). Six conditionKind values cover the full substitution surface: Stance / Form / Talent / Race / EquippedWeapon / AuraActive. The conditionValue field is polymorphic — its semantics depend on conditionKind (a stance spellId, a talentId, a race bit, etc.). The spell-cast pipeline iterates findByBaseSpell at cast time and picks the highest-priority variant whose condition is satisfied, falling through to the base spell if none matches. Three preset emitters demonstrating the pattern: makeWarriorStance (4 stance-conditional Warrior variants — Heroic Strike Berserker damage bonus, Battle baseline, Mocking Blow Defensive AoE taunt, Pummel Berserker-only gate), makeTalentMod (4 talent- modified variants — Frostbolt + Brain Freeze instant, Lava Burst + Flame Shock auto-crit, Earth Shield + Improved bonus heal, Ferocious Bite + Berserk), makeRacial (4 race-gated racials — Stoneform Dwarf, War Stomp Tauren, Berserking Troll, Will of the Forsaken). Validator's most novel check is the (baseSpell, conditionKind, conditionValue, priority) 4-tuple uniqueness — two variants with all four matching would tie at runtime and resolve non-deterministically (the spell-cast pipeline's std::sort by priority is stable but the underlying iteration order is undefined when priorities tie). Packs the tuple into 64 bits (base 32 | value 16 | kind 8 | prio 8) for set lookup. Format count 112 -> 113. CLI flag count 1213 -> 1218. |
||
|
|
46213baea0 |
feat(editor): add WMVC (Movie Credits Roll) — 112th open format
Novel replacement for the embedded credit-roll text vanilla WoW carried inside the cinematic-renderer blob (the post-cinematic credits that scroll up the screen after each expansion intro). Each entry binds one credits category (Production / Music / Voice Acting / etc.) for one cinematic to its ordered list of credit lines. First catalog with a variable-length STRING array payload — previous variable-length formats used int arrays (WCMR waypoints / WCMG mutex spells / WPTT rank-spells / WBAB rank chains / WRPR unlocked items + recipes). The lines[] field serializes as count + (length + bytes)* per line, mirroring how strings work elsewhere in the catalog set just lifted into a per- entry array. Seven category enum values cover the full credit taxonomy: Production / Music / Audio / Engineering / Art / Voice / Special. Three preset emitters: makeWotLKIntro (5 blocks for the WotLK Arthas/Terenas cinematic with the actual canonical music credits — Brower/Duke/Stafford/Hayes), makeQuestCinema (3-block template for per-quest cinematics), makeStarterRoll (4-block generic template). orderHint sorts blocks within a single cinematic so the renderer can render Production -> Direction -> Music -> Voice -> Special Thanks in canonical order without depending on entry order in the binary. Validator's most novel checks combine string + grouping constraints unique to credit rolls: per-cinematic orderHint slot uniqueness — two blocks at the same (cinematicId, orderHint) would render in non- deterministic order due to the std::sort being stable but content-order undefined. Per-line: empty lines warn (would render as blank, intentional spacers should use a placeholder character), lines >80 chars warn (text-buffer wrap at the canonical 80-char credit-renderer width). Format count 111 -> 112. CLI flag count 1206 -> 1211. |
||
|
|
cebf821205 |
feat(editor): add WPCR (Pet Care & Action) — 111th open format
Novel replacement for the implicit pet-management action rules vanilla WoW scattered across spell_template (Revive Pet / Mend Pet / Feed Pet / Dismiss Pet definitions), npc_text (stable master gossip), and per-class trainer SQL. Each entry binds one pet management action to its dispatching spell, gold cost, reagent requirement, cast time, cooldown, and pet/NPC pre-conditions. Eleven actionKind enum values cover the full pet management surface: Revive / Mend / Feed / Dismiss / Tame / BeastLore / Stable / Untrain / Rename / Abandon (Hunter), plus Summon (Warlock minion conjures). The classFilter field uses WCHC class-bit conventions (4=Hunter, 256=Warlock) so a single WPCR catalog can cover both class systems. Three preset emitters: makeHunterCare (5 Hunter pet care actions), makeStableActions (4 stable-master gold-cost actions), makeWarlockMinions (4 Warlock minion summons with shared 10s cooldown + Soul Shard reagent). Validator's most novel checks are PER-KIND constraints: Tame and Summon require requiresPet=0 (you can't tame or summon while another pet is active) — these are ERRORS, not warnings, since the action would simply fail at runtime. Stable kind without requiresStableNPC warns (stable-slot purchases are normally gated to stable-master conversation). Tame kind without cooldown warns (canonical 15s anti-macro-spam cooldown). The TameBeast preset originally omitted this cooldown — the validator caught and flagged it during smoke-test, fix applied before commit. Format count 110 -> 111. CLI flag count 1199 -> 1204. |
||
|
|
cbc4991305 |
feat(editor): add --catalog-id-range for ID-allocation planning
New utility scans every catalog file under a directory tree and reports the primary-key id range, gap count, first gap, and recommended next id (smallest gap if any, else max+1). Useful when adding new entries without conflicts: instead of opening the file in --info to read the current max id, run --catalog-id-range and pick the recNext value. Optional --magic <WXXX> filter narrows to one format family. Output is sorted by file path for deterministic shell-pipeline behavior. Skips files whose format has no --info-* surface (asset formats like .wom/.wob/.whm). Permission-denied subdirs handled gracefully via skip_permission_denied. Reuses the same primary-key heuristic + foreign-key filter as --catalog-pluck and --catalog-find. CLI flag count 1198 -> 1199. |
||
|
|
d49080db92 |
feat(editor): add WMNL (Minimap Multi-Level) — 110th open format
Novel replacement for the WorldMapTransforms.dbc + WorldMapOverlay.dbc pair vanilla used to describe zones with multiple vertical layers visible on the minimap (Stormwind has Old Town / Cathedral / Keep at three altitudes; Dalaran has Sewers / Street / Above Street / Floating; Undercity has 5 distinct levels Sewer to Throne Room). Each entry binds one (mapId, areaId, levelIndex) triplet to a Z-range, minimap layer texture, and display label. The catalog acts as a per-level overlay on top of WMPX world-map mappings: at every camera tick, the minimap renderer queries findContainingZ(playerZ) to swap the overlay layer when the player crosses a floor boundary. Three preset emitters one per layered city: makeStormwind (3 levels), makeDalaran (4 levels), makeUndercity (5 levels — deepest stack). Z-ranges abut precisely to ensure clean transitions: Sewer Z[-110, -85), Canal Z[-85, -65), Outer Ring Z[-65, -45), Inner Ring Z[-45, -20), Throne Z[-20, 30) — half-open intervals so the boundary Z value belongs to the upper level. Validator's most novel checks combine grouping + geometric constraints unique to multi-level layouts: - per-area levelIndex uniqueness (no two levels at the same index — picker UI would show duplicate slot) - per-area Z-range non-overlap (overlapping ranges would cause minimap-flicker as the player crosses the overlap region; the renderer can't decide which layer to display) Plus the standard: id+name+areaId required, minZ<maxZ (non-empty range), no duplicate levelIds. Format count 109 -> 110. CLI flag count 1191 -> 1196. |
||
|
|
8fee281899 |
feat(editor): add WRPR (Reputation Reward tier) — 109th open format
Novel replacement for the implicit reputation-tier rules vanilla WoW encoded across multiple SQL tables (npc_vendor with reqstanding columns, item_template faction gates, quest_template ReqMinRepFaction). Each WRPR entry binds one (factionId, minStanding) tier to its rewards: a vendor discount percentage, two variable- length arrays of unlocked content (item IDs + recipe IDs), and tabard + mount unlock boolean flags. First catalog with TWO variable-length payload arrays per entry (unlockedItemIds + unlockedRecipeIds) — previous variable-length formats used a single array (WCMR waypoints, WCMG members, WPTT spellIdsByRank, WBAB rank-chain pointers). The two-array shape is serialized as count1 + ids1[] + count2 + ids2[] for easy reader-side validation. Three preset emitters: makeArgentCrusade (4 tiers Friendly/Honored/Revered/Exalted with progressive items + recipes plus Argent Charger mount at Exalted), makeKaluak (4 fishing-themed tiers with cooking recipe unlocks plus Pygmy Suit cosmetic at Exalted), makeAccordTabard (3 tiers showcasing both grantsTabard and grantsMount flags via Wyrmrest Accord's iconic Reins of the Red Drake mount). Validator's most novel checks combine relational and domain logic: (factionId, minStanding) tuple uniqueness prevents ambiguous active-tier lookup, AND per-faction monotonic discount progression — sorts each faction's tiers by standing and verifies discountPct is non- decreasing. A higher reputation tier giving a worse vendor discount would be a content authoring bug. findActiveTierFor() helper picks the highest-standing tier the player meets — used by the vendor UI to compute the active discount without scanning the catalog. Format count 108 -> 109. CLI flag count 1184 -> 1189. |
||
|
|
ede6fb9c3a |
feat(editor): add WHRD (Heroic Loot Scaling) — 108th open format
Novel replacement for the implicit Heroic-mode loot rules vanilla WoW encoded in dungeon/raid script systems: a Normal-mode boss drops items from one loot table, the Heroic-mode version drops the same items at +N item levels with M× drop chance plus an optional Heroic-only currency token. Each WHRD entry binds one (mapId, difficultyId) combination to its scaling rules so the loot-roll engine can layer the modifiers over the base WLOT loot table at encounter death. Six tunable fields per scaling: itemLevelDelta (signed int16, typically +13 for 5-man Heroic, +13 to +26 for raid Heroic), bonusQualityChance (basis points 0..10000 for the probability of a +1-quality-tier bonus drop), dropChanceMultiplier (float, 1.0 = same rate, 1.5 = +50%), heroicTokenItemId (per-tier currency reward like Emblem of Frost), bonusEmblemCount (extra emblems on top of base 1× per boss). mapId=0 is a wildcard that applies the scaling to ANY map at the given difficultyId — used by the ChallengeMode preset to define generic Bronze/Silver/ Gold tier scalings without naming each instance. Three preset emitters: makeWotLK5manHeroic (5 WotLK 5-man Heroics: Utgarde Keep, Nexus, Azjol-Nerub, Ahn'kahet, Drak'Tharon — all +13/2× Emblem of Heroism), makeRaid25Heroic (4 25H raids: Naxx +13, EoE +13, Ulduar +26, ICC +26 with corresponding Conquest/Triumph/ Frost emblems), makeChallengeMode (3 anachronistic challenge-mode tiers as a template for custom servers backporting MoP-era systems). Validator's most novel checks are bounds-aware: bonusQualityChance capped at 10000 basis points (above that would guarantee multiple bonus drops), no negative itemLevelDelta (Heroic shouldn't be worse than Normal — warning, not error), no >50 ilvl delta (beyond canonical range — warning), no zero or excessive dropChance- Multiplier, AND (mapId, difficultyId) tuple uniqueness unless mapId=0 wildcard (multiple scalings binding the same instance+difficulty would make loot-roll lookup ambiguous). Format count 107 -> 108. CLI flag count 1175 -> 1180. |
||
|
|
81070c470c |
feat(editor): add WPTT (Pet Talent Tree) — 107th open format
Novel replacement for the PetTalent.dbc + PetTalentTab.dbc pair that defined the Hunter pet talent system added in WotLK. Each entry is one talent in one of the three pet trees (Cunning/utility, Ferocity/DPS, Tenacity/tank), placed at a (tier, column) grid position with a per-rank spell ID array, an optional prerequisite-talent edge, and a legacy loyalty-level requirement carried over from Vanilla pet happiness mechanics. Combines three patterns previously seen separately into one format: variable-length payload (spellIdsByRank[] mirroring WCMR's members[]), graph edge (prerequisiteTalentId mirroring WBAB's previousRankId), and grid placement (tier+column — first format with explicit 2D layout coordinates the renderer can use to draw the talent tree UI). Three preset emitters one per tree: makeFerocity (6 talents tiers 0-3 with prereq chain CobraReflexes -> SpikedCollar -> SpidersBite plus parallel Serpent -> Boars -> Rabid), makeCunning (5 talents Dash/Owls/ Recovery/Cornered/Phoenix), makeTenacity (5 talents Charge/Stamina/Stomp/Taunt/LastStand). Validator's most novel checks combine grid + graph constraints unique to talent-tree formats: - (tree, tier, column) cell uniqueness — two talents in the same cell would render on top of each other - prereq must resolve to an existing talent IN THE SAME TREE (cross-tree prereqs are illegal) - prereq tier must be STRICTLY LESS than this tier (talents only depend on earlier tiers, no same-tier or backward dependencies) - spellIdsByRank.size() must EQUAL maxRank exactly - no zero spell IDs within the rank array Plus the standard: id+name required, treeKind 0..2, tier 0..6 (7 tiers), column 0..2 (3 columns), maxRank 1..5, no duplicate talentIds, no self-referencing prereqs. Format count 106 -> 107. CLI flag count 1170 -> 1175. |
||
|
|
3c69f33465 |
feat(editor): add --catalog-by-name entry-name substring search
New utility complements --catalog-find (id-based, single-id lookup) and --catalog-grep (catalog-header label only) by searching every catalog file under a directory tree for entries whose `name` field contains a substring. Reports each hit as [WXXX] file id=N "name" so the operator can find catalog entries by half- remembered names — "find anything called Mark of the Wild" hits all 5 rank entries across WBAB, "find Argent" hits the WTBD tabard, etc. Optional flags: - --magic <WXXX>: limit search to one format family, same convention as --catalog-find. - --ignore-case: lowercase both pattern and haystack before substring match. Returns rc=0 on hits, rc=1 if no entries matched (so the caller can `if --catalog-by-name ... ; then ...; fi`). Skips files with unknown magic and files whose format has no --info-* surface (asset formats like .wom). Permission-denied subdirs skipped via skip_permission_denied directory_options. Closes the search triplet: --catalog-grep catalog-header label --catalog-find entry primary-key id --catalog-by-name entry name substring CLI flag count 1169 -> 1170. |
||
|
|
f9cad45154 |
feat(editor): add WCRE (Creature Resistance & Immunity) — 106th open format
Novel replacement for the per-creature resistance columns
that vanilla WoW buried inside creature_template
(resistance1..6 fields) plus the SpellSchoolMask immunity
and mechanic_immune_mask columns. Each entry is one
creature's full defensive profile: 6 magic-school resist
values (int16, with 32767 as the full-immunity sentinel),
a physical-resistance percentage (0..75 game-engine cap),
plus three immunity bitmasks (CC kinds, spell mechanics,
magic schools).
The CC-immunity mask uses 14 named bits: ImmuneRoot /
Snare / Stun / Fear / Sleep / Silence / Charm / Disarm /
Polymorph / Banish / Knockback / Interrupt / Taunt /
Bleed. The info display renders the mask as a "+"-joined
token list ("root+stun+fear") for readability; "all" for
0xFFFF (typical raid-boss CC profile) and "none" for 0.
Three preset emitters: makeRaidBosses (5 canonical raid
bosses with iconic single-school immunities — Ragnaros
fire / Vael 50%-all / Hakkar arcane / Kel'Thuzad shadow
/ Onyxia fire+frost partial), makeElites (5 mid-tier
elites with single-school resists), makeImmunities (4
selective CC-immunity test cases — root-immune treant,
stun-immune worg, silence-immune acolyte, fear+charm+
poly-immune undead).
Validator's most novel check is creatureEntry uniqueness
— multiple WCRE entries binding the same creature would
make the damage-calc lookup ambiguous (which profile
applies?). Also catches negative resists < -100 (extreme
>2x damage taken), physicalResistPct > 75 (clamped at
runtime to game-engine armor cap), and reserved bits in
schoolImmunityMask (only bits 0-5 are meaningful).
Format count 105 -> 106. CLI flag count 1162 -> 1167.
|
||
|
|
15bb3e09bf |
feat(editor): add WLDN (Learning Notification) — 105th open format
Novel replacement for the hardcoded server-side
milestone messages that fire when a player crosses a
progression threshold ("You can now learn Apprentice
Riding" at level 20, "Dual specialization is now
available", "You have unlocked the auction house"). Each
entry binds one trigger condition (LevelReach /
FactionStanding / ItemAcquired / QuestComplete /
SpellLearned / ZoneEntered) to a delivery channel
(RaidWarning banner / SystemMsg / Subtitle / Tutorial
popup / MOTDAppend) and an optional fanfare sound.
The triggerValue field is polymorphic — its semantics
depend on triggerKind. The validator enforces per-kind
ranges: LevelReach 1-80 (current cap), FactionStanding
+/-42000 (Hated to Exalted bounds), ItemAcquired/
QuestComplete/SpellLearned/ZoneEntered must be a
positive id (>0). This is the first format to use
per-trigger discriminated value validation.
Three preset emitters: makeLevelMilestones (5
LevelReach unlocks at canonical thresholds 20/30/40/60/
80), makeAccountUnlocks (4 mixed-kind notifications:
first-mail tutorial gated to <2hr playtime, Stormwind
auction-house location subtitle, dual-spec activation
on spell-learn, transmog vendor unlock on quest-
complete), makeReputation (3 FactionStanding milestones
at Honored/Revered/Exalted standings).
minTotalTimePlayed gates first-time-only tutorials —
the auction-house location subtitle fires only for
characters with <2hr total time so veterans don't get
spammed.
Format count 104 -> 105. CLI flag count 1155 -> 1160.
|
||
|
|
62a10937e0 |
feat(editor): add WSPM (Spell Persistent Marker) — 104th open format
Novel replacement for the SpellAreaTrigger.dbc + AreaTriggerCreateProperties pair vanilla used for AoE ground decals. Each entry binds one spellId to a ground-tracked decal: texture path, radius (in yards), duration, damage tick interval, RGBA decal color, edge- fade rendering mode (Hard / SoftEdge / Pulse), stack flag, and destroy-on-cancel semantics for channeled spells. The catalog covers three distinct gameplay surfaces in one shape: player-cast AoE (Blizzard, Flamestrike, etc. that the visual effects pipeline spawns at cast time), boss-arena hazard zones (Putricide poison pool, Sindragosa frost tomb, Marrowgar Bone Storm radius that raid encounters need to render so players know to move), and persistent environmental effects (Wintergrasp lightning strike, Silithus sandstorm cone that the weather system spawns). Three preset emitters one per surface: makeMageAoE (Blizzard/Flamestrike/BlastWave/FrostNova), makeRaid- Hazards (5 ICC encounter zones), makeEnvironment (3 weather/world hazards). Hazard variants set destroyOnCancel=0 since they persist beyond any caster; environment variants additionally set stackable=1 since multiple lightning strikes can overlap. Validator's most novel check is spellId uniqueness — multiple WSPM entries binding the same spellId would make the spell-cast lookup ambiguous (which decal does the spell spawn?). Also catches empty texture paths (decal would render solid color), radius<=0 (zero area), tickIntervalMs<100ms (perf risk for stackable markers), decalColor alpha=0 (invisible), and edge-fade enum range. Format count 103 -> 104. CLI flag count 1148 -> 1153. |
||
|
|
0f4c619b49 |
feat(editor): add WTBD (Tabard Design / Heraldry) — 103rd open format
Novel replacement for the GuildBankTabard / TabardConfig blob that vanilla WoW stores per-guild in guild_member SQL. Each entry is one tabard design: triplet of (background pattern + color, border pattern + color, emblem glyph + color), plus optional guild and creator attribution and a server-approval flag for tabard- moderation policies. Five background patterns (Solid / Gradient / Chevron / Quartered / Starburst), four border patterns (None / Thin / Thick / Decorative), and 1024 possible emblem glyph IDs. Three preset emitters demonstrate the convention: makeAllianceClassic (4 Alliance-themed system tabards: Lion, DwarvenHammer, KulTirasAnchor, HighlordSword), makeHordeClassic (4 Horde: Wolfhead, CrossedAxes, Skull, Pyramid), makeFactionVendor (6 faction-rep tabards spanning Argent Crusade, Ebon Blade, Sons of Hodir, Wyrmrest Accord, Kalu'ak, Frenzyheart Tribe). Validator's most novel check is a color-similarity heuristic — squared RGB distance between background and emblem colors. If under 1500 (empirically derived threshold for visual readability), warns the operator that the emblem won't be readable against its background. Also catches alpha=0 on any color layer (would render fully transparent), pattern enum out-of- range, and emblemId>1023 (beyond canonical glyph range). Also added per-magic explicit primary-key override to --catalog-pluck and --catalog-find so they pick the right field for catalogs where the heuristic fails. WTBD has creatorPlayerId/emblemId/guildId all alphabetically before tabardId, and guildId can't be filtered globally because WGLD uses it as a primary key. The override table is small (1 entry currently — WTBD->tabardId) and grows only when a new format catches the same conflict. Format count 102 -> 103. CLI flag count 1141 -> 1146. |
||
|
|
abf264abfe |
feat(editor): add WBAB (Buff & Aura Book) — 102nd open format
Novel replacement for the implicit rank-chain relationships that vanilla WoW encoded by burying nextRank/prevRank pointers inside Spell.dbc with no explicit graph structure. Each WBAB entry is one long- duration class buff at one specific rank, with explicit edges to adjacent ranks via previousRankId and nextRankId fields. The graph-shaped data is novel among the 100+ catalog set: most catalogs have flat rows; WBAB is genuinely a graph where rows are nodes and the rank fields are edges. Both directions are stored explicitly so the spellbook UI's "upgrade to next rank" button can traverse without scanning the full table. Helper methods walkChainBack- ToRoot() returns the full chain root->tip for the rank- picker widget; findChainTip() returns the highest rank for auto-cast logic. Three preset emitters demonstrating the pattern: makeMage (Arcane Intellect ranks 1-4 with chain edges), makeDruid (Mark of the Wild ranks 1-5 with chain edges), makeRaidMax (6 max-rank standalone raid buffs — one per buffing class — with no chain edges to show the standalone case). Validator catches several rank-chain-specific bugs: self-referencing edges (entry.next == entry.id would create a 1-element cycle), missing referenced entries (next/prev pointing to non-existent ids), and most importantly back-edge symmetry — if A.nextRankId=B then B.previousRankId MUST equal A.buffId or the spellbook upgrade traversal will derail. Symmetric back-edge check is unique to graph-shaped catalogs. Also fixed a crash in --catalog-find where the recursive directory iterator threw on permission-denied subdirs (common when walking /tmp). Now uses the skip_permission_denied directory_options + per-step error_code clearing for defensive resumption. Format count 101 -> 102. CLI flag count 1134 -> 1139. |
||
|
|
471ddfef07 |
feat(editor): add --catalog-find directory-wide id search
New utility complements --catalog-pluck (single-file id lookup) by walking a directory tree recursively and searching every catalog for entries whose primary key matches the supplied id. Reports each hit as [WXXX] file:fieldName=id "name" so the operator can locate where any given id lives across a 100+ format project. Useful when chasing cross-references like "id 631 is referenced by WGRP.mapId — where is it actually defined?" Optional --magic <WXXX> filter narrows the search to one format family. Necessary because primary-key id ranges overlap across formats (id=200 might be both a WCMG group and a WGRP composition); without the filter the operator gets all collisions, which is itself useful for spotting unintentional id reuse. Auto-detects per-file format magic, skips files with unknown magic and files whose format has no --info-* surface (asset formats like .wom that aren't catalog- shaped). Re-uses the same primary-key auto-discovery + external-ref filter as --catalog-pluck. Both utilities should grow into a shared helper header once a third utility needs the same lookup logic — for now a noted duplication. CLI flag count 1133 -> 1134. |
||
|
|
c9b822002f |
feat(editor): add WEMO (Emote Definition) — 101st open format
Novel replacement for the EmotesText.dbc + EmotesTextSound + EmotesTextData trio that maps /slash-emote commands (/dance, /wave, /laugh, etc.) to their visible chat text, animation ID, and per-race voice clip. Each entry binds one slashCommand to an animationId (refs WANI), soundId (refs WSND), targetMessage / noTargetMessage formats, emote kind (Social / Combat / RolePlay / System), sex filter (Both / Male / Female), required race bit, and a TTS hint (Talk / Whisper / Yell / Silent) for accessibility text-to-speech engines. Three preset emitters covering the canonical emote buckets: makeBasic (8 universal social emotes — wave / bow / laugh / cheer / cry / sleep / kneel / applaud), makeCombat (5 combat-themed — roar / threaten / charge / victory / surrender), makeRolePlay (6 RP-focused — bonk / ponder / soothe / plead / shoo / scoff). Animation IDs match AnimationData.dbc convention so existing WoW client mods continue to play the right anims. Validator catches authoring bugs unique to slash-command parsing: leading '/' on slashCommand (chat parser strips it before lookup so the entry would be doubly-prefixed), uppercase letters (parser case-folds before lookup so the entry is unreachable), duplicate slash commands (parser dispatches by exact match — ambiguity would crash the chat input handler), %s token counts that don't match target/no-target distinction. Also expanded --catalog-pluck's foreign-key filter to include animationId / soundId / particleId / ribbonId / vehicleId / seatId / currencyId / trainerId / vendorId / mailTemplateId — caught during smoke-test where pluck mis-identified WEMO entries by animationId instead of emoteId. Same class of bug as the WHRT areaId fix. Format count 100 -> 101. CLI flag count 1126 -> 1131. |
||
|
|
054f44e4aa |
feat(editor): add WMSP (Master Server Profile) — 100th open format
Novel replacement for the hardcoded realmlist that the
WoW client receives via SMSG_REALM_LIST during login.
Each entry is one selectable realm: name, network address
(host:port), realm type (Normal/PvP/RP/RPPvP/Test), realm
category (Public/Private/Beta/Dev), expansion gating
(Vanilla 1.12.1 / TBC 2.4.3 / WotLK 3.3.5a / Cata 4.3.4),
population indicator (Low/Medium/High/Full/Locked), char-
acter cap, GM-only flag, timezone hint, and per-realm
version+build numbers.
100th open format — milestone marker for the catalog
ecosystem. WMSP is a TOP-LEVEL bootstrap catalog (read by
the login server before any character is loaded), so it
deliberately has no cross-references to other catalogs;
all other social/world/spell catalogs depend on a player
session that doesn't exist until WMSP has been consulted.
Three preset emitters covering common deployment shapes:
makeSingleRealm (1 default WoweeMain WotLK Public),
makePvPCluster (3 realms — PvE/PvP/RP — sharing one login
address so players pick rule-set without changing servers),
makeMultiExpansion (4 progression realms across all
expansion gates with their canonical build numbers from
the matching client).
Validator catches several real misconfigurations: empty
address (login server cannot route session), realmType
out of {0,1,4,6,8} (the WoW client's RealmType enum is
non-contiguous — 2/3/5/7 are unused values that crash the
picker), characterCap=0 (players can't make characters),
duplicate realm names (picker requires unique display
names), missing port in address.
Format count 99 -> 100. CLI flag count 1119 -> 1124.
|