the minimap and world map go stock, and the chat loses its white plate
- the minimap cluster and the battleground list are the reference's own `Minimap.xml` and `BattlefieldFrame.xml`, ours deleted, and the sixteen engine names the static probe found unbound are built, not stubbed: the battleground list and queue family (the as-group join refused client-side with no packet when the map's `MaxPlayers` is below the group), the bodyless `CMSG_BATTLEFIELD_STATUS` on world enter — benilla never sent it, so a queue joined before a reconnect was invisible — the 5.5556 yd `BATTLEFIELDS_CLOSED` leash, and the meeting-stone pair over the `0x295` five-way table with both asymmetries; the ping's lifetime is the stock Lua's now (held 5 s, faded 0.5 s), `GetPingPosition` answers two numbers always — our nil was a Lua error on every frame of the stock `Minimap_OnUpdate` — and the map-change drop the reference never had is gone (1974)
- the world map is the reference's own `WorldMapFrame.xml`, our transcription deleted; built for it: the arrow-frame family (an anonymous `Model` child at its 33.6 px footprint, drawn app-side as the minimap's own arrow sprite through one shared constant), the battleground position family over `MSG_BATTLEGROUND_PLAYER_POSITIONS` both ways (the reference's 5000 ms request throttle), and `GetPlayerMapPosition` resolving `raid1..raid40` where it knew only the party (B320); `SetupFullscreenScale` — the engine binding `0x48c270` the map's and the cinematic frame's OnShow call, which our map had stood in for with Lua — is bound to the carved law `min(0.75 · aspect, 1)` off the configured aspect, written through the frame's own `SetScale` (1.0 at 4:3 and wider, 0.9375 at 5:4); a hovered POI writes the map's own area label, not the tooltip; named gap: `WorldMapPing` draws nothing yet (1980, 1981)
- the tutorial frame is the reference's own `TutorialFrame.xml`, over a tutorial system benilla never had: two bit banks filled from `SMSG_TUTORIAL_FLAGS` — the fire-once bank `TriggerTutorial` reads and sets (never a send) and the acknowledged bank `FlagTutorial` writes and sends; there is no tutorial CVar in the binary (210 `CVar::Register` sites censused), so "disable tutorials" is every bit acknowledged; the sites this app can produce are wired (the world-enter Welcome cascade, the level-up arm, item pushes, the loot sparkle, the meeting-stone and battleground arms), the rest named; the loader learned `<TitleRegion>` — the stock frame's drag handle, a region that emits no quad; and the `TabardModel` widget kind arrives ahead of its window, five ints bounded by the `.rdata` table `{170, 17, 6, 17, 51}` and the constant 100 000 tabard cost (1976, 1977)
- the chat window drew as an opaque white plate: the chat-cache loader, gated on `InWorld` alone, restored into the boot VM 130 ms before the deferred entry load filled it, and its per-VM memo then blocked the restore that would have reached the real frames — the plate the stock Lua tints black stayed the XML's white; between the entry edge and the load there is now no VM in the world (the edge parks the boot VM, the load takes it back), so no in-world feed pushes into a VM with no interface; the perf pill reads `59 fps 7.0 ms 17.3 cpu` — the MAIN thread's milliseconds in full text and the process-wide sum dim, because the sum of every thread's CPU time had been read as a frame time (a raid read 17 on it at a solid 60 with the main thread at 7); and `WOW_PROBE_UI_ONE_TEX=1` is a pricing lever, never a look, for the draw-count ceiling a UI atlas would reach before one is built (1978, 1954)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -211,6 +211,11 @@ pub struct WorldMapState {
|
||||
/// `GetPlayerMapPosition("player")` for the CURRENT selection — projected app-side each frame
|
||||
/// (`map_proj`), `None`/(0,0) = off this map (the reference hides the blip).
|
||||
pub player_uv: Option<(f32, f32)>,
|
||||
/// The world map's arrow frame and the battlefield minimap's — the two per-session
|
||||
/// singletons `CreateWorldMapArrowFrame`/`CreateMiniWorldMapArrowFrame` build, by wrapper id
|
||||
/// (`worldmap_arrow`, 1980). `None` until the first create.
|
||||
pub arrow_world: Option<u32>,
|
||||
pub arrow_mini: Option<u32>,
|
||||
/// `GetPlayerMapPosition("party1".."party4")` for the CURRENT selection, in `party_slots`
|
||||
/// order — projected app-side through the same law as [`Self::player_uv`] (report B320).
|
||||
/// A slot is `None` when there is no member there, when we hold no position for them, or when
|
||||
@@ -219,6 +224,8 @@ pub struct WorldMapState {
|
||||
///
|
||||
/// Shorter than 4 whenever the party is: a missing index is a `None`.
|
||||
pub party_uv: Vec<Option<(f32, f32)>>,
|
||||
/// `raid1..raid40` in roster order — the stock map's raid arm (1980), fed like `party_uv`.
|
||||
pub raid_uv: Vec<Option<(f32, f32)>>,
|
||||
/// `GetPlayerFacing()` — wow orientation radians (0 = north, counterclockwise-positive). Our
|
||||
/// transcribed frame spins its arrow texture with it (`SetRotation`); the reference rotates
|
||||
/// an engine-rendered arrow model instead (0203 flags the stand-in).
|
||||
@@ -317,6 +324,7 @@ impl super::UiScript {
|
||||
player_facing: f32,
|
||||
corpse_uv: Option<(f32, f32)>,
|
||||
party_uv: Vec<Option<(f32, f32)>>,
|
||||
raid_uv: Vec<Option<(f32, f32)>>,
|
||||
) {
|
||||
let mut model = self.model_mut();
|
||||
model.worldmap.player_zone = player_zone;
|
||||
@@ -324,6 +332,7 @@ impl super::UiScript {
|
||||
model.worldmap.player_facing = player_facing;
|
||||
model.worldmap.corpse_uv = corpse_uv;
|
||||
model.worldmap.party_uv = party_uv;
|
||||
model.worldmap.raid_uv = raid_uv;
|
||||
}
|
||||
|
||||
/// The engine-owned selection `(continent, zone)` — the app reads it each frame to project
|
||||
@@ -491,22 +500,25 @@ pub(super) fn install(lua: &Lua) -> mlua::Result<()> {
|
||||
)?;
|
||||
|
||||
// GetPlayerMapPosition(unit) → x, y in [0,1] map UV; (0,0) = not on this map (hide the
|
||||
// blip). `"player"` and `"party1".."party4"` resolve (report B320); `"raid1".."raid40"` do
|
||||
// not yet — the reference's raid arm draws a 25-frame pool this map has no children for, and
|
||||
// its party arm is the one a five-man actually takes.
|
||||
// blip). `"player"`, `"party1".."party4"` (report B320) and `"raid1".."raid40"` (1980, the
|
||||
// stock map's raid arm over its `WorldMapRaid1..40` pool) resolve; anything else is (0,0).
|
||||
g.set(
|
||||
"GetPlayerMapPosition",
|
||||
lua.create_function(|lua, unit: String| {
|
||||
let model = lua.app_data_ref::<Model>().expect("model app_data");
|
||||
let (x, y) = match unit.as_str() {
|
||||
"player" => model.worldmap.player_uv.unwrap_or((0.0, 0.0)),
|
||||
u => u
|
||||
.strip_prefix("party")
|
||||
let slot = |prefix: &str, list: &[Option<(f32, f32)>]| {
|
||||
unit.strip_prefix(prefix)
|
||||
.and_then(|n| n.parse::<usize>().ok())
|
||||
.filter(|n| *n >= 1)
|
||||
.and_then(|n| model.worldmap.party_uv.get(n - 1).copied().flatten())
|
||||
.unwrap_or((0.0, 0.0)),
|
||||
.and_then(|n| list.get(n - 1).copied().flatten())
|
||||
};
|
||||
let (x, y) = match unit.as_str() {
|
||||
"player" => model.worldmap.player_uv,
|
||||
u if u.starts_with("party") => slot("party", &model.worldmap.party_uv),
|
||||
u if u.starts_with("raid") => slot("raid", &model.worldmap.raid_uv),
|
||||
_ => None,
|
||||
}
|
||||
.unwrap_or((0.0, 0.0));
|
||||
Ok((f64::from(x), f64::from(y)))
|
||||
})?,
|
||||
)?;
|
||||
|
||||
Reference in New Issue
Block a user