object tags

This commit is contained in:
2026-06-07 01:26:18 -05:00
parent 9c2212520c
commit a8d2cb8303
8 changed files with 240 additions and 6 deletions
+74
View File
@@ -117,6 +117,80 @@ fn start_map_greeter_runs_init() {
);
}
#[test]
fn set_tag_adds_and_removes_via_my_id() {
// A script calls set_tag(MY_ID, "active", true) in init; the tag must be
// present on the object afterward.
let board = board_with_object(
Some("t"),
&[("t", r#"fn init() { set_tag(MY_ID, "active", true); }"#)],
);
let mut game = GameState::new(board);
game.run_init();
assert!(game.board().objects[&1].tags.contains("active"));
// A script removes a pre-existing tag.
let board2 = board_with_object(
Some("t2"),
&[("t2", r#"fn init() { set_tag(MY_ID, "active", false); }"#)],
);
// Seed the tag before construction.
let mut game2 = GameState::new({
let mut b = board2; // need mut to insert tag
b.objects.get_mut(&1).unwrap().tags.insert("active".to_string());
b
});
game2.run_init();
assert!(!game2.board().objects[&1].tags.contains("active"));
}
#[test]
fn has_tag_reads_own_tags() {
// set_tag queues an action; has_tag reads the board state. So set_tag in
// init() takes effect after init returns; a subsequent tick sees it.
let board = board_with_object(
Some("t"),
&[(
"t",
r#"fn init() { set_tag(MY_ID, "active", true); }
fn tick(dt) { log(has_tag("active").to_string()); }"#,
)],
);
let mut game = GameState::new(board);
game.run_init();
game.tick(Duration::from_millis(16));
assert!(log_texts(&game).iter().any(|t| t == "true"));
}
#[test]
fn objects_with_tag_returns_matching_ids() {
// A 5×1 board with two objects; one has tag "enemy". The script on the first
// object queries objects_with_tag("enemy") and logs the ids it finds.
let obj1 = scripted_object(0, 0, "q");
let mut obj2 = scripted_object(1, 0, "none");
// obj2 (id=2) has the "enemy" tag; obj1 (id=1) does not.
obj2.tags.insert("enemy".to_string());
let board = open_board(
5,
1,
(4, 0),
vec![obj1, obj2],
&[
("q", r#"fn init() {
let ids = objects_with_tag("enemy");
log(ids.len().to_string());
log(ids[0].to_string());
}"#),
("none", ""),
],
);
let mut game = GameState::new(board);
game.run_init();
let texts = log_texts(&game);
assert_eq!(texts[0], "1"); // exactly one match
assert_eq!(texts[1], "2"); // obj2 is id 2
}
// Ensure try_move from the player side also triggers scripted bump
#[test]
fn player_bump_fires_with_negative_one() {