every dialog is the reference's own, and the trainer loads on demand
- every dialog is the reference's own: `StaticPopup.xml` + `StaticPopup.lua` load off the player's chain, and 0308's engine with its 37 dialogs leaves `UiPanels.xml`; all 76 of the reference's dialogs are the stock table's, 28 of which no file of ours had ever registered (the resurrect family among them); the nine hidden listener frames that existed only because benilla once had no `UIParent_OnEvent` come home to it verbatim from UIParent.lua, and the seven files that were nothing but a dialog and its driver are deleted; what the swap surfaced: the reference capitalises the countdown's unit word ("5 Minutes until release") where ours had lowercased it, and ESC in the typed delete confirm's box is swallowed — the entry names no escape handler; arms for events this engine never fires (PLAYER_SKINNED, TRADE_REQUEST) wait on their feeds rather than being armed blind (1960)
- the social window and the unit menus are the reference's own files: `FriendsFrame.xml` loads off the chain and our transcription is deleted — its twelve dialogs re-homed, `FRIENDLIST_SHOW` fired as the answer to an explicit `ShowFriends()`, and `Get`/`SetLookingForGroup` a client-side flag until their bodies are carved; `UnitPopup.xml` loads off the chain, our row catalogue and its driver frame go, and nine verbs are built for it — `HasFullControl` off the player-control flag the reference reads at `0x51a158`, `UnitPlayerOrPetInParty`/`InRaid` over a new unit owner, and the six pet one-shots, each pressing the bar's own reaction or command slot word through the same latch and `CMSG_PET_ACTION`, confirmed by wow-re's carve; the Guild Leave/Promote confirms 1958 believed nothing registered were our social file's all along, and the duplicate went with it (1958, 1959)
- the trainer loads on demand: our `TrainerFrame.xml` is deleted and no row replaces it — `Blizzard_TrainerUI` loads off the player's own chain through the reference's `ClassTrainerFrame_LoadUI`, and the LoadOnDemand `Blizzard_*` addons are registry rows read off the chain; the timing IS the mechanism: the list builder writes the state-filter mask to 3 on every `SMSG_TRAINER_LIST` (`0x4d75d9`) and the stock addon pushes its saved filters exactly once, on its own ADDON_LOADED — which fires on the session's first trainer, after that packet, so the saved filters win that open and an eager load would never have applied them; the loader holds an anchor to a sibling not built yet and applies it once the subtree exists; and `UNIT_FLAGS` fires only on a change between two snapshots — wow-re's trio found the per-field watch bridge runs no notify pass on the create leg, correcting 1953 (1957)
- the additive window, built and withdrawn the same hour: under `BLEND_ADD` every additive particle draw commutes with every other, so same-key additive draws can be regrouped exactly — built in the effect lane's merge walk and measured on the crowd rig (Stormwind, forty partybots): the adjacency merge already folds about half the effect items and the regroup found two more folds in a frame of ninety-three, so the pre-regroup walk is what runs; what stays: an `fx=` items/merged census on the FPS probe line, a `DRESS_PART` line per drawn part of the self body on the dress census, and the regression the A/B uncovered: 1948's stock chat migration dropped the drain's plain-line sender, so every `WOW_PROBE_CHAT` rig — the crowd rig's forty `.partybot add`s among them — had gone silent on the server; a probe's slash-less line reaches the wire as SAY again (1955)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -553,6 +553,61 @@ pub(in crate::script) fn install(lua: &Lua) -> mlua::Result<()> {
|
||||
// string, unlike its `GetRaidRosterInfo` sibling.
|
||||
// * **The player is in the roster array**, so no `t == "player"` special case is needed here
|
||||
// — unlike `UnitInParty` below, whose roster excludes the recipient.
|
||||
// HasFullControl() → 1 | nil: the reference's `[0xb4b3e4]` read at `0x51a158` (wow-re
|
||||
// `control-loss-and-restore.md`) — the control flag `SMSG_CLIENT_CONTROL_UPDATE` writes for
|
||||
// the local player, which the stock unit menu greys its follow/trade rows on (1958).
|
||||
g.set(
|
||||
"HasFullControl",
|
||||
lua.create_function(|lua, ()| {
|
||||
let model = lua.app_data_ref::<Model>().expect("model app_data");
|
||||
Ok(if model.player_control {
|
||||
Value::Integer(1)
|
||||
} else {
|
||||
Value::Nil
|
||||
})
|
||||
})?,
|
||||
)?;
|
||||
|
||||
// UnitPlayerOrPetInParty(unit) / UnitPlayerOrPetInRaid(unit) → 1 | nil: the unit is a
|
||||
// member of the group, or a member's pet — its owner (`UNIT_FIELD_SUMMONEDBY`, else the
|
||||
// charmer, else the creator: `UnitState::owner`) is. The bindings are registered
|
||||
// (`0x5162f0` / `0x5163b0`) and delegate to a C++ predicate wow-re has not carved; the
|
||||
// owner reading is this file's, flagged in 1958.
|
||||
for (name, raid) in [
|
||||
("UnitPlayerOrPetInParty", false),
|
||||
("UnitPlayerOrPetInRaid", true),
|
||||
] {
|
||||
g.set(
|
||||
name,
|
||||
lua.create_function(move |lua, token: Option<String>| {
|
||||
check_unit_token(&token)?;
|
||||
let model = lua.app_data_ref::<Model>().expect("model app_data");
|
||||
let Some(u) = token.as_ref().and_then(|t| model.unit(t)) else {
|
||||
return Ok(Value::Nil);
|
||||
};
|
||||
if !u.exists || u.guid == 0 {
|
||||
return Ok(Value::Nil);
|
||||
}
|
||||
let me = model.unit("player").map(|p| p.guid).unwrap_or(0);
|
||||
let in_group = |guid: u64| {
|
||||
guid != 0
|
||||
&& if raid {
|
||||
model.party.raid.iter().any(|m| m.guid == guid)
|
||||
} else {
|
||||
guid == me || model.party.members.iter().any(|m| m.guid == guid)
|
||||
}
|
||||
};
|
||||
let grouped = if raid {
|
||||
!model.party.raid.is_empty()
|
||||
} else {
|
||||
!model.party.members.is_empty()
|
||||
};
|
||||
let hit = grouped && (in_group(u.guid) || in_group(u.owner));
|
||||
Ok(if hit { Value::Integer(1) } else { Value::Nil })
|
||||
})?,
|
||||
)?;
|
||||
}
|
||||
|
||||
g.set(
|
||||
"UnitInRaid",
|
||||
lua.create_function(|lua, token: Option<String>| {
|
||||
|
||||
@@ -198,6 +198,9 @@ pub struct UnitState {
|
||||
/// `UNIT_FIELD_FLAGS`, raw — what `UNIT_FLAGS` fires on (the app's `fire_transitions`); the
|
||||
/// three readings above are bits of it.
|
||||
pub flags: u32,
|
||||
/// The unit's owner — `UNIT_FIELD_SUMMONEDBY`, else its charmer, else its creator; `0` for
|
||||
/// nobody's. What `UnitPlayerOrPetInParty`/`InRaid` read for the "or pet" half (1958).
|
||||
pub owner: u64,
|
||||
/// The unit's guild membership (`GetGuildInfo(unit)`, decision 1257). `None` = guildless, or
|
||||
/// a creature, or a player whose `PLAYER_GUILDID` has not streamed yet. Filled from the
|
||||
/// PUBLIC descriptor fields 191/192 joined against the app's guild-identity cache — see
|
||||
|
||||
Reference in New Issue
Block a user