the combat log speaks, and the swim line follows your native form

- the client synthesises its combat-log chat lines: 44 chat types over 34 GlobalString families from 7 packets, the reference's own four hops (classify both endpoints → chat type → string key → format), text resolved out of the player's own GlobalStrings — so damage meters and Quiver's TranqAnnouncer have something to parse; wow-re's byte round corrected six gates (owner is charmed-by then created-by, "party" is your subgroup, friend-or-foe is CanAttack, the range gate, the miss defaults, the damage-shield chat type)
- the collision prism follows the NATIVE display, not the rendered one: a druid in bear form keeps the druid's swim, splash and wade lines and a morph keeps the human's — worst divergence on shipped data 0.72 yd (tauren moonkin), the sign flipping by form
- the creature swim gate is on both legs: a unit that loses its flag mid-water is driven out of swim at any depth, as the reference drops a charmed creature to the seabed on the next tick

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Sam
2026-08-25 18:35:32 +07:00
co-authored by Claude Fable 5
parent 2cb18768b3
commit 5c44704ac4
20 changed files with 3068 additions and 181 deletions
@@ -101,6 +101,18 @@ const FIELD_UNIT_BOUNDINGRADIUS: u16 = 129;
const FIELD_UNIT_COMBATREACH: u16 = 130;
const FIELD_UNIT_BASE_MANA: u16 = 162;
const FIELD_UNIT_DISPLAYID: u16 = 131;
/// `UNIT_FIELD_NATIVEDISPLAYID` (`OBJECT_END(6) + 0x7E` = 132, PUBLIC — vmangos
/// `UpdateFields_1_12_1.h:77`; it is the index between DISPLAYID (131) and MOUNTDISPLAYID (133),
/// both of which are independently pinned above). The unit's **unshifted** appearance: the server
/// writes it once at spawn/login and leaves it alone through every transform — a druid form
/// (`Aura::HandleAuraModShapeshift` sets DISPLAYID and restores it *from* this field), a GM
/// `.modify morph`, a polymorph. `UNIT_FIELD_DISPLAYID` is what you see; this is what the unit is.
///
/// The client reads it for exactly one thing benilla cares about: the **mover collision prism**
/// (`0x60b270` fetches its DBC row at `[unit+0x110]+0x1f8`, while its sibling `0x60ae10` uses
/// `+0x1f4` = DISPLAYID against the same array) — so a shapeshift does *not* resize the collision
/// box (wow-re `mover-collision-scalars.md`, `remote-swim-decision.md` §4; decision 1574).
const FIELD_UNIT_NATIVEDISPLAYID: u16 = 132;
/// `UNIT_FIELD_MOUNTDISPLAYID` (`OBJECT_END(6) + 0x7F` = 133, PUBLIC — vmangos
/// `UpdateFields_1_12_1.h:78`; byte-verified client-side at `[unit+0x110]+0x1fc` = index 0x85,
/// wow-re `rf39-field-index-map.md`/`d1.md`, HARD). A raw `CreatureDisplayInfo` id: the mount the
@@ -56,6 +56,13 @@ impl ObjectFields {
pub fn unit_displayid(&self) -> Option<i32> {
self.get_i32(FIELD_UNIT_DISPLAYID)
}
/// `UNIT_FIELD_NATIVEDISPLAYID` (units + players) — the unit's **unshifted** appearance, which
/// no transform touches. The collision prism is derived from *this*, not from
/// [`Self::unit_displayid`]: a druid in bear form keeps the druid's swim/splash/foam lines
/// (decision 1574). `None` when absent — the caller falls back to the render display.
pub fn unit_native_displayid(&self) -> Option<i32> {
self.get_i32(FIELD_UNIT_NATIVEDISPLAYID)
}
/// `UNIT_FIELD_MOUNTDISPLAYID` — the `CreatureDisplayInfo` id of the mount this unit rides;
/// `0` (or absent) = not mounted. The one and only mounted signal on the wire (decision 0441).
pub fn unit_mount_display_id(&self) -> u32 {