superwow: TrackUnit/UntrackUnit, and the four chat-bubble CVars
TrackUnit is the one with a live consumer and a real feature behind it: 1.12 draws party members on the minimap and raid members NOWHERE, and pfUI puts the whole raid on it with these two — for every party and raid token on PARTY_MEMBERS_CHANGED/RAID_ROSTER_UPDATE/PLAYER_ENTERING_WORLD, each inside a pcall, so on a client without the function the feature is simply absent, which is what it has been here. The set is guids, not tokens, so a tracked raid member keeps its dot while the roster shuffles its token out from under it. The dot itself is drawn by a fourth always-show clause beside the reference's own three (`shows_tracking_dot`) — `tracked_creature` stays exactly `0x5ed210`, so the predicate that file documents is still the client's, and a tracked unit gets the ordinary cell, hover name and distance cull with nothing new drawn. The set is read off the VM handle the blip system already holds rather than behind a resource of its own: `BlipInputs` is at the 16-param ceiling and its last element is already a nested pair for that very reason. The bubble four come straight off the DLL's string pool. Three are nampower's `NP_ChatBubbles*` under SuperWoW's unprefixed names, writing the same fields — two mods, one knob, last writer wins, as the nameplate reach already is — each keeping 0 because the reference bubbles none of those kinds. `ChatBubblesCreatures` is SuperWoW's alone and the only behaviour of the four: it NARROWS `ChatBubbles` rather than standing beside it, because the mod hooks the reference's own gate and a switch added at that site can only subtract; the other reading would bubble creatures with the master switch off. It ships 1, so an untouched client bubbles monster say and yell exactly as 1.12 does. All four are welded to their struct literals in the defaults-mirror test. CREATE_CHATBUBBLE is deliberately NOT fired, and the row says why: its payload can only be the bubble, and this client's bubbles are not Lua frames — the same wall `C_ChatBubbles.GetAllChatBubbles` already answers an empty list for. Argless would be worse than silence, since an addon written against upstream reaches for arg1's regions and raises once per bubble. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SgstFWtn1RxEJ5kVrpgYwn
This commit is contained in:
+24
-2
@@ -38,7 +38,7 @@ nothing behind it.
|
||||
| `UNIT_CASTEVENT` | done | `crates/benilla-app/src/superwow_events.rs`: a `CastEventFeed` queue the cast handlers push into, drained once per tick by one VM-holding system that fires the event — the pattern `ui_mirror.rs` already uses, and the only way across, since `spell/net.rs`'s `Lifecycle`/`Scene` bundles deliberately hold no `UiScript` (`game_plugins.rs`'s `every_vm_holder_in_update_declares_its_side_of_the_tick` gates that). Edges wired: `START` from `SMSG_SPELL_START` with its wire cast time as `arg5` (an instant raises none — its only edge is `CAST`, which is what the wiki's own START/CAST split means), `CAST` from `SMSG_SPELL_GO`, `FAIL` from `SMSG_SPELL_FAILED_OTHER`, `CHANNEL` from `MSG_CHANNEL_START` with its duration. GUIDs go out in the same 16-hex-digit spelling every other `compat/` surface uses, so `arg1`/`arg2` compare directly against a `UnitExists`/`UnitGUID` return. Not wired: `MAINHAND`/`OFFHAND` — benilla's melee-swing path raises no cast edge at all, so there is nothing to forward. `MSG_CHANNEL_START` names no caster (1.12 sends it for the local player's own channel only), so `CHANNEL`'s `arg1` is self and its `arg2` is 0 |
|
||||
| `RAW_COMBATLOG` | **done** | `ui_chat/frames.rs`'s `route` — the one funnel every combat line already passes on its way to a window and to `WoWCombatLog.txt`. Two arguments, as its one consumer in grom's corpus destructures them: the printed sentence, and the same sentence with each unit name spelled as its GUID (`PendingCombat::guid_fills`, composed a second time through the same `compose_line`, so the two can only ever differ in the name slots). Fired **before** the `CHAT_MSG_*`, which is what "raw" means upstream — it hooks the combat-log parse, ahead of the client's own formatting. Gated on `has_listener`, the gate nampower's combat-log family already uses, and the `arg2` composition is skipped under the same test: a raid's log is tens of lines a second. A variant whose template says "you" keeps saying it, because that word is in the *template* and not in a fill — and its consumer depends on exactly that, reading the word and then asking `UnitExists("player")` for its own guid. **Why this row came first:** of SuperWoW's whole surface, it and `CombatLogAdd` are the only two names grom's addons call that this client lacked (`scripts/dll-surface.py --wanted`), and `SuperCleveRoidMacros/Utility.lua:10206` funnels **five** subsystems through this single event — immunity and resist learning, hidden-CC ("afflicted by") detection, debuff-duration learning off the GUID half, and the reactive-proc window that lights **Overpower** and **Revenge**. Its own comment there is why the last of those can come from nowhere else: "SPELL_GO only provides hit/miss COUNTS, not miss TYPES, so it cannot distinguish dodge (Overpower proc) from parry/block/resist". This does **not** by itself fix the Overpower complaint: that needs the dodged-*ability* sentence to be emitted at all, which is its own open item (`benilla-overpower-aura-spelldodged`) |
|
||||
| `CombatLogAdd(text)` | **done** | `compat/superwow.rs` queues the line; `ui_chat/logging.rs`'s `sync_chat_logging` appends it to `WoWCombatLog.txt` through the same `record` every routed line uses, so it is stamped identically and one writer owns the file. Dropped while the log is closed, which is upstream's behaviour too (it appends to an open file). A non-string argument is ignored rather than raising: its one real caller is a debug-trace helper (`BigWigs/Plugins/MageTools.lua:761`, under a `fileDebug` profile flag) and a raise there would take the addon down for something the player cannot act on. **It is also a detection name**: `BigWigs/Plugins/SpellRequests.lua:6` is `if CombatLogAdd then hasSuperWow = true`, which gates that whole module's SuperWoW path |
|
||||
| `CREATE_CHATBUBBLE` | todo | needs the chat-bubble creation site in `chat_bubble.rs` (its `push`/`drive_bubbles`); now that `superwow_events.rs` exists with the queue-plus-drain pattern established, this is a small addition rather than new architecture. It is the **last** of SuperWoW's three events — `SUPERWOW_COMBAT_LOG_EVENT`, which this row used to carry, is a ghost: see the manifest below |
|
||||
| `CREATE_CHATBUBBLE` | **blocked, deliberately not fired** | the last of SuperWoW's three events, and the one that cannot be made good: its payload can only be the bubble, and this client's bubbles are not Lua frames — they are a 2-D world overlay (`chat_bubble.rs`), as the reference's own `CGChatBubbleFrame` is. The same wall `C_ChatBubbles.GetAllChatBubbles` hit, and firing it argless would be *worse* than silence (an addon reaching for `arg1`'s regions raises, once per bubble). See the manifest section below for what the one piece of work behind it would close. `SUPERWOW_COMBAT_LOG_EVENT`, which this row used to carry, is a ghost |
|
||||
| `NameplateRange` | done | one CVar, two readers: `nameplates.rs`'s `NameConfig::range_sq` (the overhead name — introduces a cull where the reference has none at all) and `vplates.rs`'s `VPlateMode::range_sq` (replaces the reference's own hardcoded 20 yd V-key-plate range). Default `80`, the top of the mod's documented 10-80 range — no shipped default is published, so this is the least-restrictive honest choice, not a confirmed number |
|
||||
| `ChatBubbleRange` | done | `chat_bubble.rs`'s `BubbleConfig::range_sq`, replacing the reference's hardcoded 20 yd. Default `20` (today's exact value) — no shipped default published for this one either, within the mod's documented 10-200 yd range |
|
||||
| `NameplateMotion`, `NameplateVerticalSpacing` | todo | needs locating whatever (if anything) already staggers overlapping nameplates, not investigated |
|
||||
@@ -77,7 +77,7 @@ The usage strings, verbatim, for what is left:
|
||||
| Usage string, as the DLL prints it | Status |
|
||||
|---|---|
|
||||
| `CombatLogAdd("text" [, addToRawLog])` | **done** — the second argument is why this row is here: nothing in the corpus passes it, and it would have been missed |
|
||||
| `TrackUnit("unit")` / `UntrackUnit("unit")` | todo — pfUI calls `TrackUnit` for every party and raid member under `C.unitframes.track_group` (`modules/superwow.lua:96-127`, inside `pcall`), to put the group on the minimap |
|
||||
| `TrackUnit("unit")` / `UntrackUnit("unit")` | **done** — a set of **guids** in the VM (`compat/superwow.rs`), read by the minimap's blip pass as a **fourth always-show clause** beside the reference's own three (`shows_tracking_dot` in `minimap/blips/dots.rs`; `tracked_creature` stays exactly `0x5ed210`). So a tracked unit gets the ordinary tracked-unit cell, hover name and distance cull, and nothing new is drawn. Guids rather than tokens, so a tracked raid member keeps its dot while the roster shuffles its token. **Why it is a real feature and not a cosmetic one:** 1.12 draws party members on the minimap and raid members **nowhere** — `emit_party_dots` walks `party_slots()`, which is what the reference's own placement does — and pfUI puts the whole raid on it with these two, for every party and raid token on `PARTY_MEMBERS_CHANGED`/`RAID_ROSTER_UPDATE`/`PLAYER_ENTERING_WORLD` under `C.unitframes.track_group`, each inside a `pcall`. So on a client without the function the feature is simply absent, which is what it has been here. The set is read off the VM handle the blip system already holds rather than behind a resource of its own, because `BlipInputs` is at the 16-param ceiling |
|
||||
| `UnitPosition("unit")` | done |
|
||||
| `GetPlayerBuffID(buffIndex)` | done |
|
||||
| `UnitNameplate("unit")` | **done** — `compat/superwow.rs`, over `NamePlates::frame_for_guid`, through the **same** `plate_frame` wrapper ClassicAPI's `C_NamePlate.GetNamePlateForUnit` uses, so the two names cannot hand back different objects for one plate. Welded by a test that asserts exactly that, because an addon may feature-detect either |
|
||||
@@ -91,6 +91,28 @@ The usage strings, verbatim, for what is left:
|
||||
| `GetQuestLinkForID(questID)` | todo — the same link for a quest the log does not hold, which is a server round trip (`Requesting quest ID %d from server` is the DLL's own next string) |
|
||||
| `ImportFile("filename")` / `ExportFile("filename","text")` | done, under nampower's fence. **Upstream's own folder is `Imports\<name>.txt`** (two more of its literals), where ours is `benilla-config/CustomFiles/` — the deviation is written up in the file-and-credential section below |
|
||||
|
||||
**The four chat-bubble rows are now live.** `ChatBubblesWhisper`, `ChatBubblesRaid` and
|
||||
`ChatBubblesBattleground` are nampower's `NP_ChatBubbles*` under SuperWoW's own names, writing the
|
||||
same `BubbleConfig` fields — two mods, one knob, last writer wins, as the nameplate reach already
|
||||
is — and each keeps `0`, because the reference bubbles none of those three kinds.
|
||||
`ChatBubblesCreatures` is SuperWoW's alone and the only *behaviour* of the four: it splits the
|
||||
monster say and yell kinds out of `ChatBubbles`, which 1.12 gates them under. It ships `1`, so an
|
||||
untouched client bubbles them exactly as 1.12 does, and it **narrows** `ChatBubbles` rather than
|
||||
standing beside it — the mod hooks the reference's own gate (`0x608b0d`), and a switch added at
|
||||
that site can only subtract; the other reading would bubble creatures with the master switch off,
|
||||
which is a surprise no setting advertises. All four are welded to their struct literals in
|
||||
`cvars.rs`'s own defaults-mirror test, the `benilla-cvar-default-trap` discipline.
|
||||
|
||||
**`CREATE_CHATBUBBLE` cannot be made good, and the reason is already written up elsewhere in this
|
||||
file.** Its payload can only be the bubble, and this client's bubbles are not Lua frames at all —
|
||||
they are a 2-D world overlay drawn by `chat_bubble.rs`, the same way the reference's own
|
||||
`CGChatBubbleFrame` is drawn. That is the identical wall `C_ChatBubbles.GetAllChatBubbles` hit, and
|
||||
it answers an empty list for it. Firing the event argless would be worse than not firing: an addon
|
||||
written against upstream would reach for `arg1`'s regions and raise, once per bubble. **The real
|
||||
item behind both** is making the native bubbles addressable from Lua — a frame with a texture and a
|
||||
`FontString` per live bubble, kept in step with the overlay's own spawn, stacking and expiry rules —
|
||||
and that one piece of work closes the event, the namespace and pfUI's bubble skinning together.
|
||||
|
||||
And the CVars it registers, as names: `NameplateRange`, `NameplateMotion`, `ChatBubbleRange`,
|
||||
`ChatBubblesRaid`, `ChatBubblesBattleground`, `ChatBubblesWhisper`, `ChatBubblesCreatures`,
|
||||
`BackgroundSound`, `UncapSounds`, `InterfaceVolume`, `LootSparkle`, `HealingText`,
|
||||
|
||||
Reference in New Issue
Block a user