Files
benilla-octo/crates/benilla-ui/src/script/binder.rs
T
SamandClaude Opus 5 9a184d3476 the guild window opens: roster, ranks, notes and the message of the day
- the social window's third tab is live — the roster in both its views, the member card with its promote/demote/remove verbs, the rank editor's thirteen permissions, the guild information board, and the invite, leave, kick and note dialogs behind them
- setting your hearthstone at an innkeeper now asks before it takes and says so afterwards, and the innkeeper's gossip lines get their own icons back
- unavailable talents grey out, and every greyed icon in the client now goes through the same luminance fold the original used
- the buff tooltip's remaining-time line reads gold with the client's own hour/minute ladder, the macro editor takes a shift-click to paste a spell, trainer rows repaint after a purchase, and a long book page stops flickering its ellipsis

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-16 17:38:54 +07:00

63 lines
2.6 KiB
Rust

//! The innkeeper-bind **Era API surface** (decision 1331) — two globals, no snapshot.
//!
//! These are the whole Lua side of setting a hearthstone, and they exist because the reference's
//! `CONFIRM_BINDER` dialog is written against exactly them (`StaticPopup.lua:1308-1322`):
//! `OnAccept` calls [`ConfirmBinder`], and `OnUpdate` hides the dialog the moment
//! [`CheckBinderDist`] goes false. Both are engine bindings in 1.12 (`reference/1.12-globals.tsv`
//! lists `ConfirmBinder` and `CheckBinderDist` as `function`/`engine`), and there are no others in
//! the family — the question itself arrives as the `CONFIRM_BINDER` event's argument, so there is
//! nothing to read back, exactly like [`super::duel`].
//!
//! The app owns the innkeeper's guid ([`crate::script::UiScript::set_binder_pending`]'s writer),
//! which is why `ConfirmBinder()` takes no arguments and queues only a count.
use mlua::Lua;
use super::Model;
impl super::UiScript {
/// Drain the `ConfirmBinder()` calls queued since the last drain — each one is a
/// `CMSG_BINDER_ACTIVATE`. [`super::UiScript::take_played_time_asks`]'s shape, and a count for
/// the same reason: the intent has no payload of its own.
pub fn take_binder_confirms(&mut self) -> u32 {
std::mem::take(&mut self.model_mut().binder_confirms)
}
/// Push whether an innkeeper's bind question is live and still in range — the host's half of
/// `CheckBinderDist()`. Idempotent; `false` covers both "no question pending" and "you walked
/// away", which is all the dialog's OnUpdate needs to decide to hide.
pub fn set_binder_pending(&mut self, pending: bool) {
let mut model = self.model_mut();
if model.binder_pending != pending {
model.binder_pending = pending;
}
}
}
/// Register the two binder globals (the style [`super::duel`] registers its four).
pub(super) fn install(lua: &Lua) -> mlua::Result<()> {
let g = lua.globals();
// ConfirmBinder() — the CONFIRM_BINDER dialog's Accept. The one call in the client that binds
// a hearthstone: everything before it is a question.
g.set(
"ConfirmBinder",
lua.create_function(|lua, ()| {
let mut model = lua.app_data_mut::<Model>().expect("model app_data");
model.binder_confirms += 1;
Ok(())
})?,
)?;
// CheckBinderDist() — polled from the dialog's OnUpdate; false hides it.
g.set(
"CheckBinderDist",
lua.create_function(|lua, ()| {
let model = lua.app_data_ref::<Model>().expect("model app_data");
Ok(model.binder_pending)
})?,
)?;
Ok(())
}