spell_fx: an effect on a host with no attachment points seats at its box top
Reported from play: "ore vein is still not sparkling" — so the switch fix landed and the sparkle still was not there. Reproduced offline in the `fxview` GameObject lane (`WOW_CAPTURE=fxview WOW_FX_GO=310 WOW_FX_GO_TYPE=3`, a copper mining node), which runs the real chain. Everything upstream works: the gate fires, `attach_spell_fx` spawns the instance (`kit spawn … Particles\LootFX.mdl`), and `WOW_PARTICLE_CENSUS` finds all four of LootFX's emitters at the node's position, live, ungated and drawn — while the captured frame is byte-identical to one taken with the sparkle gated off. Nothing was missing; nothing was visible. The attach cascade's last rung is the host's origin, and for a unit that is right: `0x13` is attachment 19, Base, which creature models author at the ground point under the feet, and the loot sparkle is a ground twinkle. A 1.12 GameObject model authors no attachment points at all (`copper_Miningnode_01.m2`: 0 — `benilla-m2`'s `dump_attach`), so the cascade fell through to the node's pivot, which is inside the rock: that model's own 397 vertices run y ∈ [-3.83, +2.73], and `Particles\LootFX.m2` is a ~1 yd twinkle (four emitters, 0.06–0.14 yd particles, ~0.9 yd reach) with nowhere to go. So a host with no attachment point seats the effect at the top centre of its own box. Not its middle — a node is modelled around its pivot, not above it, and this one's box centre is 0.55 yd underground, which capture-tested as invisible too, as did half the box height. At the box top the capture differs from the gated-off one; a peacebloom, whose model is small, already showed at the pivot. The placement is ours and says so: SuperWoW publishes no source and the reference has no object arm to copy. It stays subtle by design — row 14 of `SpellVisualEffectName` scales 1.0 — so it reads as a few twinkles over the node, not a beacon. If that is not what the real client shows him, the next lever is the effect's scale, and that one wants his eyes, not mine. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SgstFWtn1RxEJ5kVrpgYwn
This commit is contained in:
@@ -414,3 +414,4 @@ with the load checked after each.
|
||||
| SuperWoW's `LootSparkle` sparkled nothing | **fixed** — the decision was right, the switch feeding it was never on | Reported from play: *"Loot sparkle not working on a mining ore I'm looking at"*, with the unit arm visibly working on lootable mobs — which is the shape of the bug, since only the GameObject arm reads the switch. `LootSparkleMode` derived `Default`, so it booted `false` while its row registered `"1"`. A boot fires `CvarChanged` only for rows `config.toml` actually carries, and writing `"1"` over a value already `"1"` is a no-op that fires nothing either, so **nothing could ever tell the resource its real default** — not the boot, not the player toggling it. `vplates.rs`'s `VPlateMode::default` carries that warning in as many words, from `NameplateOcclusion` shipping inert the same way, and this is the same mistake one feature later. Fixed with a hand-written `Default` and the twin test `the_loot_sparkle_default_agrees_with_its_registered_cvar`, which reads the registered row rather than restating it. Swept the rest: of the 32 resources a `CvarChanged` observer writes, 6 derive `Default` (`AssistAttack`, `AuraCastFeed`, `AutoSelfCast`, `BlockTrades`, `FpsJournalSetting`, `GuildMemberNotify`) and **every one of their rows registers `"0"`**, so `LootSparkle` was the only one of this shape |
|
||||
| `PlayerModel:SetUnit` tracked the token instead of holding the unit | **fixed** | unitscan's alert reads `SetUnit'target'` on the rare it just found by name, and the addon restores the player's own target on the next line — so a pane that re-resolved `"target"` per paint showed the card for one frame and then emptied. Reported the moment the by-name targeting stopped leaving the target on the rare: *"unitscan is not targetting anymore, very nice, but now it only shows the 3d model when I do target"*. The reference resolves the token in `SetUnit`'s own rebuild worker (`0x505b50`, the one `RefreshUnit` also runs) and nothing re-resolves it per paint — which is why FrameXML re-issues `SetUnit` from `PaperDollFrame_OnShow` and on `UNIT_MODEL_CHANGED`, and why pfUI can detect a portrait change with **no event at all** by pinning a scratch pane and comparing `GetModel` against the shown one (`api/unitframes.lua:2069`), a test that only says anything if a pane holds what it was given. `ModelState::unit_guid` is that pin, resolved at the call and read by one helper (`Model::unit_pane_subject`) for both the paint gate and the extract. A pane seated **before** its unit streamed in keeps re-reading its token, since our subject arrives asynchronously where the reference's is already in the object manager; `RefreshUnit` re-pins, as its worker does. Test: `a_unit_pane_keeps_the_unit_it_was_given_when_the_token_moves_on`. Still true and still not built: `GetModel()` answers nil on a unit pane here, so pfUI's eventless detection leg can never fire — its event leg does, and that is what draws its portraits |
|
||||
| An item tooltip's rebuild was silent, so an addon's lines lasted one refresh | **fixed** | Reported from play with a video: hovering a bag item draws the enhanced tooltip — MasterTradeSkills' recipe block, AdvancedTradeSkillWindow2's `Bags/Bank/Total` — for about nine frames of sixty, and then the plate reverts to the bare one and stays bare while the cursor sits still. The loop behind it is stock: `ContainerFrameItemButton_OnUpdate` re-enters `..._OnEnter` every `TOOLTIP_UPDATE_TIME` (`ContainerFrame.lua:693` in the player's own `patch-4.mpq`, and pfUI's bag slots are `ContainerFrameItemButtonTemplate`, so they run it too), and each turn is `SetOwner` + `SetBagItem` — a clear that wipes every line an addon appended. What puts them back in the reference is a **hide/show pair**: the `SetOwner` binding hides the plate before it even reads the owner argument (`0x531179` zeroes the content gate at `+0xd0`, `0x531183` calls `[vtable+0x84]` = `0x530a60`, which is the `SetOwner(NULL)` core plus the base hide `0x76ad50`), and the content `Set*` re-shows it through the tooltip's own Show override (`0x530a80`), so every rebuild raises `OnHide` then `OnShow`. Ours cleared in place, and the base show early-outs on an already-visible frame (`0x76ae3b`), so the plate never hid and the `OnShow` never came. `LibItemTooltip-1.0` — the tooltip contract of MasterTradeSkills and Gromissingcrafts — hangs entirely on a scratch child frame of `GameTooltip` listening for `OnShow`, which is why exactly those two addons' lines vanished while pfUI's `ItemID` and sell-price lines, hooked on the `Set*` methods themselves, survived every refresh. All addresses read off the player's own `WoW.exe` |
|
||||
| The object sparkle was armed but buried inside the object | **fixed** — the placement is ours | *"ore vein is still not sparkling"*, after the switch fix. Reproduced offline in the `fxview` GameObject lane (`WOW_CAPTURE=fxview WOW_FX_GO=310 WOW_FX_GO_TYPE=3`, a copper mining node): the gate fires, `attach_spell_fx` spawns the instance (`kit spawn … Particles\LootFX.mdl`), and `WOW_PARTICLE_CENSUS` lists all four of `LootFX`'s emitters at the node's own position, live and ungated — while the captured frame is **byte-identical** to one taken with the sparkle gated off. The attach cascade's last rung is the host's origin, which for a unit is right (`0x13` is attachment 19, Base, the ground point under its feet, and this is a ground twinkle); a 1.12 **GameObject** model authors no attachment points at all (`copper_Miningnode_01.m2`: 0), so the effect sat at the node's pivot, inside the rock — that model's own vertices run y ∈ [-3.83, +2.73]. A host with no attachment points now seats the effect at the top centre of its own box, and the capture differs; the same sparkle on a peacebloom, whose model is small, already showed at the pivot. The placement is ours and no more: SuperWoW publishes no source and the reference has no object arm to copy. It is also **subtle by design** — `SpellVisualEffectName` row 14 scales 1.0 and `Particles\LootFX.m2` is four emitters of 0.06–0.14 yd particles with ~0.9 yd of reach — so it reads as a few twinkles over the node rather than a beacon |
|
||||
|
||||
Reference in New Issue
Block a user