From c627483a85d7f081335b456cd7b0c57d9733f835 Mon Sep 17 00:00:00 2001 From: Andrew Barnes <169967362+Bortlesboat@users.noreply.github.com> Date: Fri, 2 Oct 2026 02:45:16 -0400 Subject: [PATCH] Return numeric flags from spell-targeting predicates (#764) Use binding_abi::flag for SpellIsTargeting and SpellCanTargetUnit so addons can compare their results with 1, as in 1.12.1. Keep nil for false. Verified on Windows with Rust 1.98.1: three regression failures before the fix, all 35 focused spell tests passing after it, formatting and render-pass lint clean. The full UI run passed 1677 tests, with one ignored and one traceback-name failure reproduced on untouched main. Fixes #711 --- crates/benilla-app/src/spell/targeting/mod.rs | 8 +++--- crates/benilla-ui/src/script/spellbook.rs | 26 ++++++++++--------- .../benilla-ui/src/script/unit/chain_tests.rs | 2 +- crates/benilla-ui/src/script/unit/tests.rs | 4 +-- 4 files changed, 21 insertions(+), 19 deletions(-) diff --git a/crates/benilla-app/src/spell/targeting/mod.rs b/crates/benilla-app/src/spell/targeting/mod.rs index c55db2ed..c29b2c34 100644 --- a/crates/benilla-app/src/spell/targeting/mod.rs +++ b/crates/benilla-app/src/spell/targeting/mod.rs @@ -800,7 +800,7 @@ mod tests { .expect("the feed runs"); world .non_send_resource::() - .eval::(&format!("return SpellCanTargetUnit({token:?}) == true")) + .eval::(&format!("return SpellCanTargetUnit({token:?}) == 1")) .expect("a boolean") }; for token in ["pettarget", "playertarget", "PETTARGET", "target"] { @@ -988,7 +988,7 @@ mod tests { .expect("the feed runs"); let hover = world .non_send_resource::() - .eval::(&format!("return SpellCanTargetUnit({token:?}) == true")) + .eval::(&format!("return SpellCanTargetUnit({token:?}) == 1")) .expect("a boolean"); assert_eq!(hover, binds, "{label}: the hover verdict"); @@ -1226,7 +1226,7 @@ mod tests { .expect("the feed runs"); let hover = world .non_send_resource::() - .eval::(&format!("return SpellCanTargetUnit({token:?}) == true")) + .eval::(&format!("return SpellCanTargetUnit({token:?}) == 1")) .expect("a boolean"); assert_eq!(hover, binds, "{label}: the hover verdict"); @@ -1279,7 +1279,7 @@ mod tests { .expect("the feed runs"); world .non_send_resource::() - .eval::(&format!("return SpellCanTargetUnit({token:?}) == true")) + .eval::(&format!("return SpellCanTargetUnit({token:?}) == 1")) .expect("a boolean") }; assert!(can(10.0, HEAL, "target"), "in range"); diff --git a/crates/benilla-ui/src/script/spellbook.rs b/crates/benilla-ui/src/script/spellbook.rs index 8f9ac223..8ce11886 100644 --- a/crates/benilla-ui/src/script/spellbook.rs +++ b/crates/benilla-ui/src/script/spellbook.rs @@ -604,23 +604,19 @@ pub(super) fn install(lua: &Lua) -> mlua::Result<()> { })?, )?; - // SpellIsTargeting() (`0x6e6cd0`): true while the targeting cursor is up, else nil. + // SpellIsTargeting() (`0x6e6cd0`): 1 while the targeting cursor is up, else nil. g.set( "SpellIsTargeting", lua.create_function(|lua, ()| { let model = lua.app_data_ref::().expect("model app_data"); - if model.spell_targeting { - Ok(Value::Boolean(true)) - } else { - Ok(Value::Nil) - } + Ok(flag(model.spell_targeting)) })?, )?; // SpellCanTargetUnit("unit") (`0x6e6d00`): the argument is a string or a number (`0x6e6d0e`, // else `Usage:`), resolved through `0x515970` (`0x6e6d3a`), which raises for a token it does // not know; a token naming nobody answers nil (`0x6e6d43`), and a guid asks `0x6e6460`'s unit - // leg whether the standing word clears against it. + // leg whether the standing word clears against it, answering 1 or nil. g.set( "SpellCanTargetUnit", lua.create_function(|lua, unit: Value| { @@ -634,11 +630,7 @@ pub(super) fn install(lua: &Lua) -> mlua::Result<()> { .unit_guids .guid_of(&token)? .is_some_and(|guid| model.spell_targetable_units.contains(&guid)); - if can { - Ok(Value::Boolean(true)) - } else { - Ok(Value::Nil) - } + Ok(flag(can)) })?, )?; @@ -667,6 +659,16 @@ mod tests { use crate::script::cursor::{CursorAction, CursorPayload}; use crate::script::UiScript; + #[test] + fn spell_is_targeting_answers_one_or_nil() { + let mut s = UiScript::new().unwrap(); + assert!(s.eval::("return SpellIsTargeting() == nil").unwrap()); + s.set_spell_targeting(true); + assert!(s.eval::("return SpellIsTargeting() == 1").unwrap()); + s.set_spell_targeting(false); + assert!(s.eval::("return SpellIsTargeting() == nil").unwrap()); + } + /// Two tabs: Fire (Fireball, and Fire Blast marked passive) and Frost (Frost Armor). fn book() -> SpellBookState { SpellBookState { diff --git a/crates/benilla-ui/src/script/unit/chain_tests.rs b/crates/benilla-ui/src/script/unit/chain_tests.rs index 07311fc7..409c36c2 100644 --- a/crates/benilla-ui/src/script/unit/chain_tests.rs +++ b/crates/benilla-ui/src/script/unit/chain_tests.rs @@ -272,7 +272,7 @@ fn spell_can_target_unit_answers_the_verdict_of_the_unit_the_token_names() { let mut s = world(); s.set_spell_targetable_units([BOSS, P1]); let can = |s: &UiScript, token: &str| { - s.eval::(&format!("return SpellCanTargetUnit({token:?}) == true")) + s.eval::(&format!("return SpellCanTargetUnit({token:?}) == 1")) .unwrap() }; let refused = |s: &UiScript, token: &str| { diff --git a/crates/benilla-ui/src/script/unit/tests.rs b/crates/benilla-ui/src/script/unit/tests.rs index c68f3c1f..73908d7f 100644 --- a/crates/benilla-ui/src/script/unit/tests.rs +++ b/crates/benilla-ui/src/script/unit/tests.rs @@ -69,10 +69,10 @@ fn spell_can_target_unit_answers_per_validated_token() { }); s.set_spell_targetable_units([0x10, 0x21]); assert!(s - .eval::(r#"return SpellCanTargetUnit("player") == true"#) + .eval::(r#"return SpellCanTargetUnit("player") == 1"#) .unwrap()); assert!(s - .eval::(r#"return SpellCanTargetUnit("PARTY1") == true"#) + .eval::(r#"return SpellCanTargetUnit("PARTY1") == 1"#) .unwrap()); assert!(s .eval::(r#"return SpellCanTargetUnit("target") == nil"#)