ed524ab1849f99a5eb04818f2efbc141aba2a012
6
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
ed524ab184 |
druids get their relic slot, and the loot window is the reference's own
- `UnitHasRelicSlot` is real in 1.12 and benilla had no binding for it: `0x519e50` reads `ChrClasses.dbc` field 16 — set for Paladin, Shaman and Druid in `patch.MPQ`'s 17-column copy (the base `dbc.MPQ` copy has 16 columns and no such field, which is how the "always false in vanilla" belief survived twice in decisions and seven times in code) — and stock `PaperDollFrame.lua` calls it unconditionally, so the character sheet would have raised for EVERY class; a druid, paladin or shaman's sheet now hides the ammo slot, shows the relic plate where the bow was, tooltips "Relic", and reports ranged Attack/Damage/Power as N/A, all four branches transcribed from the reference - the loot window is the reference's own `LootFrame.xml`: `LootButton` is built as a real widget type rather than aliased (a Button plus one slot dword and one overridden OnClick — right-click loots exactly like left, no shift/ctrl/alt takes, a row whose Lua handler errored still loots, a fast double-click takes two slots), `LOOT_SLOT_CLEARED` fires per row again because the stock file hangs hide-in-place AND the emptied-page auto-advance off it, `EditBox:Insert(nil)` is a no-op as `lua_tostring` makes it, and an alias `GameTooltip.xml` had quietly become a reader of would have turned every item tooltip white, silently, had it just gone nil - the vendor cursor: `PickupMerchantItem` is two verbs behind one name, decided by what the cursor holds and never by the caller — a held bag item SELLS (index ignored, no merchant-open gate), otherwise the vendor row is grabbed as cursor mode 5, which is invisible to `CursorHasItem` (modes 1 and 9 only) so all thirteen stock gates stay closed while it is held; the drop is the buy, `CMSG_BUY_ITEM_IN_SLOT`, count 1, into a bag or an equipment slot, and every refusal is silent and clears the cursor; the four `Model_*` rotation handlers land in UIParent where the reference keeps them - the gap report reads `:Method(` sites now — it found `SetMerchantCompareItem`, which would have raised on the first vendor-row hover with every check green, and `LootButton:SetSlot`, and 28 "free" windows became 25; the shared coin kit moved out of the merchant window into `MoneyFrame.xml` so the eight windows that draw coins through it can reach it without loading a vendor Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
e7aa04f41c |
the buff bar goes stock, and gossip quests show their level
- the buff bar is the reference's own `BuffFrame.xml`, and the swap found an engine defect: an empty `<OnLoad>` in 1.12's XML is a BLANK that takes an inherited handler away again (seven such sites across four stock files), which our loader read as "none given" — so the two enchant slots would have painted the player's first buff in the corner and cancelled it on right-click; the first fix then had to be corrected at the bytes (`SetScript 0x7025c0` tests only NULL and empty, and nothing trims, so `<OnLoad>↵</OnLoad>` compiles to a valid empty function rather than storing nil, which any addon calling `GetScript` can observe); `SHOW_BUFF_DURATIONS` is applied once post-load because 1.12 leaves that to `UIOptionsFrame.lua`, which benilla does not build — without it the bar ships a 10px pitch error on every buff - gossip quests come through the reference's four verbs — `GetGossipAvailableQuests`/`GetGossipActiveQuests` returning (title, level) PAIRS, with the two `Select*` verbs indexing into that list — replacing three invented names that sat on the beyond-1.12 exception list; the quest LEVEL was on the wire, parsed and dropped because the invented verb had nowhere to put it, and the reference's order (available before active, whatever the packet interleaved) comes with them - eight more files off the chain as groundwork: `LocaleProperties.lua` (the gendered/plural `GetText` selector that eleven stock call sites read their words through — fifty lines of FrameXML that looked like an engine binding), `CinematicFrame.xml`, the UIMenu kit, the `UnitFrame.lua`/`CombatFeedback.lua` kits (the only two names blocking the stock player, party, target and pet frames), the money-input kit, and `ItemButtonTemplate.xml` — the base every bag, bank, merchant, loot, trade and mail slot inherits; `GetMerchantItemMaxStack` (on the wire the whole time, dropped) and the two trade item-link verbs join the engine - two instruments for the migration: a gap report that reads a stock window's call sites against a LOADED VM and says which engine verbs it still needs (28 windows need none, the rest name 1–5), and the readiness probe's documented false positive — loading a stock window on top of our same-named one leaves `getglobal(name)` pointing at ours while the stock handlers run against theirs, so a failure inside a colliding name is a question, not an answer Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
6da7ed3fca |
the action bars' empty slots go ghost, and a rooted creature stays put
- picking a spell up off the bar no longer blacks out every empty slot: `UI-Quickslot` is a FILLED 60%-black plate, not a hollow ring (decoded off the shipped BLPs — Quickslot2's interior is RGBA 0,0,0,0, Quickslot's 0,0,0,153), and the reference dims it to half alpha in `ActionButton_ShowGrid`, so an empty well now ghosts at 30% black where it read as a hole; the wow-re cross-check then found the reference never UN-dims it (a 3-argument `SetVertexColor` preserves the current alpha at `0x79abd0`, and `SetNormalTexture` reuses the region), so in the real client the first drag leaves every button's border at half alpha for the rest of the session — benilla ends the dim on purpose and records it as the divergence it is (1782) - the bag bar is the reference's own `MainMenuBarBagButtons.xml` (window 3 of the stock-first migration), and the swap found a real bug rather than a move: the reference's `ItemAnim_OnEvent` matches a push against the button's inventory-slot id (20..23) and benilla emitted its own container numbering (1..4), so all four bag-push cards would have silently never played against the stock body — `push_container` now emits the reference's selector (`bag + 1`), which is what an addon expects anyway; beside it, a readiness probe that asks the LOADER, not a grep, which of the 85 stock windows load off the player's chain today (58 do; the 27 that don't name their own blocker) - a rooted, hovering, water-walking or walking creature reached benilla as an unhandled opcode: the twelve `SMSG_SPLINE_MOVE_*` (the observer twin of the ack'd force family — bare packed guid, no ack, any unit) now decode into one MOVEMENTFLAGS word per unit, which benilla kept for our mover and for a relayed player and not at all for a creature, the one body this family is ever addressed to; ROOT wipes the direction bits so the dead-reckon stops walking a rooted body on for its next heartbeat (`0x7c7340`), HOVER clears a yard off the floor without climbing a body already inside that yard (`0x636e81`), WATERWALK elects the liquid surface against the terrain, SAFE_FALL's terminal is 7.0 not 60.148 (`0x7c5d23`), and SET_RUN_MODE's bool is inverted against the bit, folded at the parse; the inspect card names a unit's granted modes in words (`granted rooted+hover`) so a creature resting a yard off the floor reads as intended rather than broken Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
67315143f9 |
the bag windows are the real 1.12 files, and /walk actually walks
- the bag windows are the reference's own `ContainerFrame.xml` running off the player's patch chain — decision 1751 makes the stock 1.12 UI off the install the end state and `assets/ui` scaffolding that retires file-by-file (86 files against the 99-file stock corpus, 72% of the 1128-function global surface already built) — via one ordered manifest, `benilla.toc`, where a bare name is a file we ship and an `Interface\FrameXML\` path is the player's own file; the windows on screen are `ContainerFrame1..12`, the bank's six copy-pasted popouts fold into them at ids 5..10, net −750 lines, and the swap forced real engine verbs into being rather than stubs (`SetBagPortaitTexture` with its id-0 no-texture arm, `GameTooltip:AppendText`, `SetButtonPulse`, and a `<Model>` whose file is the cooldown indicator materializing as the native sweep, which three corpus addons inherit) - the 1.12 walk toggle lands: `TOGGLERUN` latches one bit with `ToggleRun`'s own silent refusal chain (dead, rooted, on a live server spline), and the walk animation was never missing at all — the flag reaches it through exactly one channel, the speed (`0x5fd100` picks Walk over Run on `speed > 2 × walkSpeed`); pinning it caught our remote extrapolator with the two min rungs backwards — `min(walk, run)` runs BEFORE the backward min, so a walking backpedaller moves at 2.5 yd/s where we would have played them the Run clip at 4.5 — and one shared `current_speed` now keeps the local controller and the extrapolator from ever disagreeing about it - the instance and raid lockout messages exist — six packets that were dropped as unknown opcodes now land, four of them as the CHAT_MSG_SYSTEM lines the client composes itself, which is why no Lua handler ever surfaced them — plus `IsInInstance`, `ResetInstances`, and the unit popup's "Reset all instances" row behind the reference's own predicate; where the binary contradicts vmangos: the ownership flag means "any instance bind" but vmangos only ever names raid binds, so the row was dead for every character without a raid lockout — term 1 is now also satisfied by our own eyes, walking out of a party dungeon the server itself bound us to - opening the world map showed 3D world at the sheet's margins: `BlackoutWorld` was parented to the very `UIParent` a fullscreen panel hides, and three more frames had crossed the same boundary — the shared dropdown lists (so the map's continent and zone pickers answered a click with nothing at all), the master-looter menu, and the screenshot confirmation, which could never appear during a cinematic; `frame_flag_gate` now checks the parent seat against the reference both ways a frame acquires one (the attribute, template-inherited included, and `<Frames>` nesting), and its first harvest took 30 divergences down to three accepted ones Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
a0d2fc383b |
the world map blips are the reference's, and particles go untinted
- the world map speaks the reference's names: WorldMapTooltip is declared (six corpus addons index it; pfUI dies on it at file scope), the blackout frame takes the reference's spelling BlackoutWorld, and the four hand-written party blips become the reference's own unit-blip templates — all 44 blips as instances, each with its published $parentIcon, the name pfUI recolours group blips by class through; the 40 raid ones are declared but not positioned yet, named in the OUT list rather than faked
- the templates addons build their own buttons from are published: ItemButtonTemplate, ContainerFrameItemButtonTemplate and the bag-slot chain — most of the handler scripts were live the whole time (this client executes the reference's own container and paper-doll code off the player's patch chain), so what was missing was mostly declarations, not behaviour — the bank arm stays out and is named as the omission it is; OptionsFrameSliders becomes real, with the three Graphics rows reading it and re-reading on show, so an addon's write to a slider's bounds actually moves the slider; and the template census that had ranked these at "zero demand" learns to see a local bound to a literal — its table went from 3 rows to 7
- the bindings answer in 1.12's own shapes: Button:IsEnabled() answers the NUMBER 1 or 0 (0 is truthy in Lua, so the reference's own == 0 tests got false forever, and three of our files had hand-worked around the divergence rather than fixed it); the constructors' string arguments are four shapes, not one rule — pfUI passes a Button where a template name goes and the reference constructs the FontString and ignores it; SetInventoryItem returns THREE values, the reference's own paper doll destructuring repairCost; UnitIsVisible is object presence and nothing else (57 bytes, one branch, no distance — an out-of-range party member is exists-yes, visible-nil); the tapped pair reads the two dynamic-flags bits, and its repaint wire fires UNIT_FACTION on the tap bit — the half a passing predicate test never sees; UnitIsPartyLeader is two ORed legs covering disjoint failures (a held stranger leading their own party, and an out-of-range member with no object to read a flag from); and the four nameplate verbs take no argument and return zero values
- the ghost's wisps compose onto its body instead of over it — the four emitters drew at full strength over a body at alpha 0.5, and now inherit the instance alpha down the attachment chain the way the reference recomposes it per frame; the residual we had parked ("the wisps should inherit the tint too") is REFUTED at the bytes: a particle batch commits hardcoded white RGB, and even that never reaches the fragment — particles are never tinted, only the alpha crosses, applied to the alpha byte alone — so the shipped shader split was already right and no code changes
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
||
|
|
9662553528 |
addons come alive: Bagnon draws, hovers and clicks
- Lua 5.0's generic-for and nested long strings are restored in a forked VM — 60 corpus addons stopped dying on one deleted opcode - a day of demand-driven carving takes the 218-addon corpus from 24 addons surviving a session start to 114, with 144 loading without a single error - Bagnon draws a real bag and answers real gestures — hover tooltip, pickup, use, drag — because our frames wear the reference's names, and the reference's own ContainerFrame.lua runs off the player's install instead of being transcribed - the physics broad phase leaves: nothing in the client reads a contact, and it was measured at up to 41% of main-thread samples in real sessions Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |