the action bars' empty slots go ghost, and a rooted creature stays put
- picking a spell up off the bar no longer blacks out every empty slot: `UI-Quickslot` is a FILLED 60%-black plate, not a hollow ring (decoded off the shipped BLPs — Quickslot2's interior is RGBA 0,0,0,0, Quickslot's 0,0,0,153), and the reference dims it to half alpha in `ActionButton_ShowGrid`, so an empty well now ghosts at 30% black where it read as a hole; the wow-re cross-check then found the reference never UN-dims it (a 3-argument `SetVertexColor` preserves the current alpha at `0x79abd0`, and `SetNormalTexture` reuses the region), so in the real client the first drag leaves every button's border at half alpha for the rest of the session — benilla ends the dim on purpose and records it as the divergence it is (1782) - the bag bar is the reference's own `MainMenuBarBagButtons.xml` (window 3 of the stock-first migration), and the swap found a real bug rather than a move: the reference's `ItemAnim_OnEvent` matches a push against the button's inventory-slot id (20..23) and benilla emitted its own container numbering (1..4), so all four bag-push cards would have silently never played against the stock body — `push_container` now emits the reference's selector (`bag + 1`), which is what an addon expects anyway; beside it, a readiness probe that asks the LOADER, not a grep, which of the 85 stock windows load off the player's chain today (58 do; the 27 that don't name their own blocker) - a rooted, hovering, water-walking or walking creature reached benilla as an unhandled opcode: the twelve `SMSG_SPLINE_MOVE_*` (the observer twin of the ack'd force family — bare packed guid, no ack, any unit) now decode into one MOVEMENTFLAGS word per unit, which benilla kept for our mover and for a relayed player and not at all for a creature, the one body this family is ever addressed to; ROOT wipes the direction bits so the dead-reckon stops walking a rooted body on for its next heartbeat (`0x7c7340`), HOVER clears a yard off the floor without climbing a body already inside that yard (`0x636e81`), WATERWALK elects the liquid surface against the terrain, SAFE_FALL's terminal is 7.0 not 60.148 (`0x7c5d23`), and SET_RUN_MODE's bool is inverted against the bit, folded at the parse; the inspect card names a unit's granted modes in words (`granted rooted+hover`) so a creature resting a yard off the floor reads as intended rather than broken Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -39,6 +39,28 @@ fn kind_color(kind: ModelKind) -> egui::Color32 {
|
||||
}
|
||||
}
|
||||
|
||||
/// The granted movement modes as the card names them (decision 1780) — `None` when the unit has
|
||||
/// none, which is nearly all of them, so the common line is unchanged. Named rather than derived
|
||||
/// from the raw word on the card: `0x40001000` says nothing to the eye, and the whole reason this
|
||||
/// is on the card is that the modes explain a body that looks wrong and is not.
|
||||
fn granted_modes(modes: Option<&crate::net::UnitMoveModes>) -> Option<String> {
|
||||
use crate::creature_anim::move_flags as f;
|
||||
let w = modes?.0;
|
||||
let named = [
|
||||
(f::ROOT, "rooted"),
|
||||
(f::HOVER, "hover"),
|
||||
(f::WATER_WALKING, "waterwalk"),
|
||||
(f::SAFE_FALL, "feather"),
|
||||
(f::WALK_MODE, "walk-mode"),
|
||||
(f::SWIMMING, "swim"),
|
||||
]
|
||||
.into_iter()
|
||||
.filter(|(bit, _)| w & bit != 0)
|
||||
.map(|(_, name)| name)
|
||||
.collect::<Vec<_>>();
|
||||
(!named.is_empty()).then(|| format!("granted {}", named.join("+")))
|
||||
}
|
||||
|
||||
/// The inspector's GameObject collision readout (decision 0763): does a hull exist, is it disabled
|
||||
/// right now, and what stored state does the passability gate see. Named so the bundled `stores`
|
||||
/// param stays readable.
|
||||
@@ -56,9 +78,16 @@ type GoCollisionReadout = (
|
||||
/// fast?* The AQ drakes are the case that earned it — a Brood of Nozdormu 190 yd overhead beating
|
||||
/// its wings at a flat 1× while its path crawls at walk pace reads as frozen, and nothing on the
|
||||
/// card said the path was the slow half.
|
||||
///
|
||||
/// …and, since 1780, the third producer: the modes the server **granted** this unit
|
||||
/// ([`crate::net::UnitMoveModes`]). They belong on the same line because they answer the same
|
||||
/// report from the other side — a body a yard off the floor, standing on water, or refusing every
|
||||
/// path the server sends it looks broken and is not, and the mode word is the only place that
|
||||
/// difference is written down. A unit with none reads nothing extra, which is nearly all of them.
|
||||
type MotionReadout = (
|
||||
Option<&'static crate::net::Spline>,
|
||||
Option<&'static crate::net::RemoteMotion>,
|
||||
Option<&'static crate::net::UnitMoveModes>,
|
||||
);
|
||||
|
||||
/// The inspector's entity LIGHT readout (decision 0776): the lane this object's parts render
|
||||
@@ -444,18 +473,24 @@ pub(super) fn inspect_ui(
|
||||
let motion_line = net_entity
|
||||
.filter(|_| is_unit)
|
||||
.and_then(|p| motion.get(p).ok())
|
||||
.map(|(spline, remote)| match (spline, remote) {
|
||||
(Some(sp), _) => format!(
|
||||
"motion {:.2} yd/s · {} path {:.0}% of {:.0}s",
|
||||
sp.speed(),
|
||||
if sp.grounded { "ground" } else { "flying" },
|
||||
100.0 * sp.elapsed_frac(),
|
||||
sp.duration.as_secs_f32(),
|
||||
),
|
||||
(None, Some(r)) if r.speed > 0.0 => {
|
||||
format!("motion {:.2} yd/s · dead-reckoned", r.speed)
|
||||
.map(|(spline, remote, modes)| {
|
||||
let moving = match (spline, remote) {
|
||||
(Some(sp), _) => format!(
|
||||
"motion {:.2} yd/s · {} path {:.0}% of {:.0}s",
|
||||
sp.speed(),
|
||||
if sp.grounded { "ground" } else { "flying" },
|
||||
100.0 * sp.elapsed_frac(),
|
||||
sp.duration.as_secs_f32(),
|
||||
),
|
||||
(None, Some(r)) if r.speed > 0.0 => {
|
||||
format!("motion {:.2} yd/s · dead-reckoned", r.speed)
|
||||
}
|
||||
_ => "motion still".to_string(),
|
||||
};
|
||||
match granted_modes(modes) {
|
||||
Some(m) => format!("{moving} · {m}"),
|
||||
None => moving,
|
||||
}
|
||||
_ => "motion still".to_string(),
|
||||
});
|
||||
// An `AnimationData` id as the card names it — shared by the creature and GameObject anim
|
||||
// lines below, which read the same id space.
|
||||
|
||||
Reference in New Issue
Block a user