the flight map goes stock, and vendors refuse in 1.12's own words
- the pet stable and the flight map are the reference's own files: `TaxiRouteFrame` maps to a plain Frame (factory `0x495ba0` allocates the base size, the ctor adds no field, no new virtual, no method table — and `GetObjectType` is not overridden, so its own kind would have been the divergence), and the swap found three silent behaviours — the close button did nothing (an unknown `inherits=` is a WARNING, so it loaded as a bare button), the "no paths" line drew empty, and the title is READ off `UnitName("npc")`, not received; the WMO skybox rides the interior crossfade — one weight (`[0xce9bdc]`, the same number the MFOG lerp rides), a 4 s alpha fade, so a skybox the flood publishes through a doorway draws at weight 0 instead of popping in whole
- a widget predicate answers the NUMBER 1 or nil, never a boolean: eleven of them (`IsShown`, `IsVisible`, `IsMovable`, `GetChecked`…) move to the 1.12 shape — the reference proves it in its own source (`tostring(this:GetChecked())` saved and read back `== "1"`; `tostring(true)` would never match and buff timers would never appear), 21 corpus sites compare directly (`IsVisible() == nil`, `GetChecked() == 1`), and one of our own tests had the guild rank editor sending `true` where a real client sends 1
- the vendor's refusals are the reference's table: `SMSG_BUY_FAILED`/`SMSG_SELL_ITEM` route through `0x5dcd60`/`0x5dd1f0`'s switches, six lines were wrong (code 3 printed "That vendor can't be found." — vmangos's identifier — where 1.12 prints "That merchant doesn't like you."), silence is now expressible, and keying them gives the vendor a voice (`ERR_NOT_ENOUGH_MONEY` carries error-speech line 0x28); the bank's three ids were right and its "purchase failed (n)" an invention; the logout refusal is one key, `ERR_LOGOUT_FAILED`, for every non-zero reason; the two mail codes we said had no string have one (`ERR_PLAYER_WRONG_FACTION`, `ERR_RESTRICTED_ACCOUNT`) and a sent mail says `ERR_MAIL_SENT` in yellow; a test runs the chain's own `GlobalStrings.lua` and requires non-empty text for all 193 `ERR_*` the workspace names
- a clicked quest timer no longer raises — stock `QuestTimerFrame.lua` calls `QuestLog_SetSelection`/`QuestLog_Update`, which existed nowhere in this tree; our quest log owns the reference's two names now, which also shrinks the delta when that window itself migrates
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -37,7 +37,9 @@ pub(super) fn install(lua: &Lua, m: &Table) -> mlua::Result<()> {
|
||||
lua.create_function(|lua, this: Table| {
|
||||
let h = frame_handle_of(lua, &this)?;
|
||||
let model = lua.app_data_ref::<Model>().expect("model");
|
||||
Ok(model.arena.frame(h).map(|f| f.shown).unwrap_or(false))
|
||||
Ok(crate::script::binding_abi::predicate(
|
||||
model.arena.frame(h).map(|f| f.shown).unwrap_or(false),
|
||||
))
|
||||
})?,
|
||||
)?;
|
||||
m.set(
|
||||
@@ -45,11 +47,13 @@ pub(super) fn install(lua: &Lua, m: &Table) -> mlua::Result<()> {
|
||||
lua.create_function(|lua, this: Table| {
|
||||
let h = frame_handle_of(lua, &this)?;
|
||||
let model = lua.app_data_ref::<Model>().expect("model");
|
||||
Ok(model
|
||||
.arena
|
||||
.frame(h)
|
||||
.map(|f| f.effective_visible)
|
||||
.unwrap_or(false))
|
||||
Ok(crate::script::binding_abi::predicate(
|
||||
model
|
||||
.arena
|
||||
.frame(h)
|
||||
.map(|f| f.effective_visible)
|
||||
.unwrap_or(false),
|
||||
))
|
||||
})?,
|
||||
)?;
|
||||
// Identity / hierarchy
|
||||
@@ -669,7 +673,9 @@ pub(super) fn install(lua: &Lua, m: &Table) -> mlua::Result<()> {
|
||||
lua.create_function(|lua, this: Table| {
|
||||
let h = frame_handle_of(lua, &this)?;
|
||||
let model = lua.app_data_ref::<Model>().expect("model");
|
||||
Ok(model.arena.is_mouse_enabled(h))
|
||||
Ok(crate::script::binding_abi::predicate(
|
||||
model.arena.is_mouse_enabled(h),
|
||||
))
|
||||
})?,
|
||||
)?;
|
||||
// EnableKeyboard(flag) / IsKeyboardEnabled() — `0x776f90` / `0x776ff0`, real Frame entries in
|
||||
@@ -703,7 +709,9 @@ pub(super) fn install(lua: &Lua, m: &Table) -> mlua::Result<()> {
|
||||
lua.create_function(|lua, this: Table| {
|
||||
let h = frame_handle_of(lua, &this)?;
|
||||
let model = lua.app_data_ref::<Model>().expect("model");
|
||||
Ok(model.arena.is_keyboard_enabled(h))
|
||||
Ok(crate::script::binding_abi::predicate(
|
||||
model.arena.is_keyboard_enabled(h),
|
||||
))
|
||||
})?,
|
||||
)?;
|
||||
// `EnableMouseWheel(flag)` / `IsMouseWheelEnabled()` — the wheel's own gate, a separate flag
|
||||
@@ -769,7 +777,9 @@ pub(super) fn install(lua: &Lua, m: &Table) -> mlua::Result<()> {
|
||||
lua.create_function(|lua, this: Table| {
|
||||
let h = frame_handle_of(lua, &this)?;
|
||||
let model = lua.app_data_ref::<Model>().expect("model");
|
||||
Ok(model.arena.is_mouse_wheel_enabled(h))
|
||||
Ok(crate::script::binding_abi::predicate(
|
||||
model.arena.is_mouse_wheel_enabled(h),
|
||||
))
|
||||
})?,
|
||||
)?;
|
||||
// Clamp-to-screen (`0x776c00`/`0x776cb0`, geometry flags bit4 — layout.md): the layout resolve
|
||||
@@ -793,7 +803,9 @@ pub(super) fn install(lua: &Lua, m: &Table) -> mlua::Result<()> {
|
||||
lua.create_function(|lua, this: Table| {
|
||||
let h = frame_handle_of(lua, &this)?;
|
||||
let model = lua.app_data_ref::<Model>().expect("model");
|
||||
Ok(model.arena.is_clamped_to_screen(h))
|
||||
Ok(crate::script::binding_abi::predicate(
|
||||
model.arena.is_clamped_to_screen(h),
|
||||
))
|
||||
})?,
|
||||
)?;
|
||||
// Hit-rect insets — the MOUSE rect only (widget::Frame::hit_rect_insets): the hit test shrinks
|
||||
|
||||
@@ -404,14 +404,18 @@ fn set_flag(lua: &Lua, this: &Table, which: Flag, value: bool) -> mlua::Result<(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_flag(lua: &Lua, this: &Table, which: Flag) -> mlua::Result<bool> {
|
||||
/// `IsMovable`/`IsResizable`/`IsUserPlaced` — the NUMBER 1 or nil, never a boolean (1830,
|
||||
/// [`crate::script::binding_abi::predicate`]).
|
||||
fn get_flag(lua: &Lua, this: &Table, which: Flag) -> mlua::Result<Value> {
|
||||
let h = frame_handle_of(lua, this)?;
|
||||
let model = lua.app_data_ref::<Model>().expect("model");
|
||||
Ok(model.arena.frame(h).is_some_and(|f| match which {
|
||||
Flag::Movable => f.movable,
|
||||
Flag::Resizable => f.resizable,
|
||||
Flag::UserPlaced => f.user_placed,
|
||||
}))
|
||||
Ok(crate::script::binding_abi::predicate(
|
||||
model.arena.frame(h).is_some_and(|f| match which {
|
||||
Flag::Movable => f.movable,
|
||||
Flag::Resizable => f.resizable,
|
||||
Flag::UserPlaced => f.user_placed,
|
||||
}),
|
||||
))
|
||||
}
|
||||
|
||||
/// The family's refusal, named frame and all — the reference's own shape (it formats the frame's
|
||||
|
||||
@@ -125,7 +125,9 @@ pub(super) fn install(lua: &Lua, m: &Table) -> mlua::Result<()> {
|
||||
lua.create_function(|lua, this: Table| {
|
||||
let h = frame_handle_of(lua, &this)?;
|
||||
let model = lua.app_data_ref::<Model>().expect("model");
|
||||
Ok(model.arena.is_toplevel(h))
|
||||
Ok(crate::script::binding_abi::predicate(
|
||||
model.arena.is_toplevel(h),
|
||||
))
|
||||
})?,
|
||||
)?;
|
||||
// Raise() — `0x775a50` → `0x76a5b0` → `0x7650f0(this, force = 1)`. Note it is legal on any
|
||||
|
||||
Reference in New Issue
Block a user