your corpse answers the mouse, and a cinematic's last holes close
- a corpse is a body you can hover, cursor and click: it enters the same ray pass as units with the winner switched on type at publish (the reference's own shape — one trace over every object), the cursor classifier is transcribed whole (lootable-by-me → the pickup cursor, grayed by range; else the insignia leg behind the learned-skill latch; your own body falls through to the clear), and right-click is "not mounted AND lootable" → CMSG_LOOT; CORPSE_FIELD_FLAGS bit 5 is the PvP insignia flag, not "reclaimable" as an old note had it; the widening also caught that a GameObject anywhere on screen could steal the click from a nearer corpse, and that a left-click on a body cleared your target as if you had clicked ground
- the cinematic sweep closes eleven holes: a shot plays its sequence band's WIDTH, not its end — two shipped fly-bys band away from zero and ran long with their opening frames frozen (the Night Elf intro measured 102333 → 102000 ms); CMSG_NEXT_CINEMATIC_CAMERA announces every shot, the first included — the old "between shots" reading meant it was sent NEVER, since every 1.12 sequence row carries exactly one camera; the ack invariant is stated once (one CMSG_COMPLETE_CINEMATIC per accepted trigger, over-acking tolerated, under-acking never — a dropped ack despawns the world around you until relog); the hardware cursor hides for the shot; and the music cut lands in the frame that starts it — it was one frame late, exactly long enough for a first login's zone fanfare to start under the narration and be stamped as played
- RunBinding exists, and a fly-by stops handing the world its mouse: CinematicFrame's OnKeyDown hands the SCREENSHOT chord back to its binding through RunBinding, a global we never had, so every press during a fly-by raised and took no picture; and the mouse was fully live under a shot — right-drag turned the character, clicks picked targets through the flying camera, both buttons walked the body — so the pointer now reads as over the UI while a shot plays
- AdvanceTime and ReplaceIconTexture are carved off the bytes: AdvanceTime really is a no-op in the reference (its one reachable call is mov eax,1; ret), ReplaceIconTexture is a material swap over a model's type-14 texture slots that stores nothing on the widget, and SetModel(nil) RAISES — the "documented clear" our binding claimed was invented, not read; and the addon roster now says WHOSE package is short when a .toc names files the folder doesn't hold — nine of the corpus's twenty-nine load failures are the addon's own manifest, which the real client also shrugs off ("Couldn't open %s", carry on), so they stop reading as our defects
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -796,6 +796,20 @@ impl ObjectFields {
|
||||
self.get_u32(36).unwrap_or(0) & 0x01 != 0
|
||||
}
|
||||
|
||||
/// `CORPSE_FLAG_LOOTABLE` (`0x20`, [`Self::corpse_flags`] bit 5) — the **PvP insignia** flag,
|
||||
/// the one the reference's corpse cursor classifier `0x482740` reads at
|
||||
/// `[[corpse+0x110]+0x74] >> 5 & 1` for its second leg, and the corpse right-click `0x5d6bf0`
|
||||
/// reads again at `0x5d6c9c` for the matching send.
|
||||
///
|
||||
/// **It is not "reclaimable"** — `object-layer/scratch/w2a.md` calls it both things in one
|
||||
/// file (line 264 "reclaimable", line 618 "PvP flag") and only the second survives the byte
|
||||
/// read: both readers pair it with the `SPELL_EFFECT_SKIN_PLAYER_CORPSE` learn-time latch
|
||||
/// `[0xb700e8]`, which is a skinning precondition and has nothing to do with recovering your
|
||||
/// own body. Nothing in the reclaim path consults this bit.
|
||||
pub fn corpse_pvp_insignia(&self) -> bool {
|
||||
self.corpse_flags() & 0x20 != 0
|
||||
}
|
||||
|
||||
/// `DYNAMICOBJECT_CASTER` (fields 6–7, `OBJECT_END + 0x0`, a 2-field guid — vmangos
|
||||
/// `UpdateFields_1_12_1.h:325`): the unit whose ground cast anchored this object.
|
||||
/// Index-twin of [`Self::corpse_owner`] — each TYPEID reuses `OBJECT_END`; the TypeId (or
|
||||
|
||||
@@ -60,15 +60,17 @@ impl WorldWriter {
|
||||
self.send(opcode::CMSG_COMPLETE_CINEMATIC, &[])
|
||||
}
|
||||
|
||||
/// Advance a multi-camera cinematic to its next shot (`CMSG_NEXT_CINEMATIC_CAMERA`, empty
|
||||
/// body) — see the opcode's own note. Sent *between* cameras; the run still ends with exactly
|
||||
/// one [`complete_cinematic`](Self::complete_cinematic).
|
||||
/// Announce the cinematic shot being armed (`CMSG_NEXT_CINEMATIC_CAMERA`, empty body) — see
|
||||
/// the opcode's own note. Sent once per shot, **including the first**, so a stock single-camera
|
||||
/// race intro sends exactly one; the run still ends with exactly one
|
||||
/// [`complete_cinematic`](Self::complete_cinematic).
|
||||
///
|
||||
/// No shipped 1.12 `CinematicSequences` row carries a second camera, so this never fires
|
||||
/// against a stock server today. It exists because the sequencing is the *client's*, not the
|
||||
/// data's: a row with two cameras is one the client must play as a single continuous
|
||||
/// cinematic, and playing it silently — without the packet the reference sends at `0x48efe0`
|
||||
/// — is the kind of drift that only surfaces on a server shipping its own DBCs.
|
||||
/// The reference's send is inside the shot arm `0x48edf0` (`0x48ef11 push 0xfb` → the
|
||||
/// `0x418190` builder → `0x5ab630` flush), immediately before that shot's narration starts —
|
||||
/// *not* inside the shot advance `0x48efe0`, where benilla first placed it. That misreading
|
||||
/// mattered on the shipped path rather than only on a private server's: every 1.12
|
||||
/// `CinematicSequences` row carries exactly one camera, so "between cameras" meant benilla
|
||||
/// sent this packet **never**.
|
||||
pub fn next_cinematic_camera(&mut self) -> Result<()> {
|
||||
self.send(opcode::CMSG_NEXT_CINEMATIC_CAMERA, &[])
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user