the huge refactor

This commit is contained in:
2026-07-24 21:52:05 -05:00
parent 5146cc9bcc
commit 917f4b1bf0
43 changed files with 1807 additions and 3267 deletions
+2 -2
View File
@@ -1,5 +1,5 @@
use super::load_board;
use crate::archetype::Archetype;
use crate::builtin::Archetype;
#[test]
fn fill_builds_a_full_grid_of_one_char() {
@@ -23,7 +23,7 @@ palette = { "#" = { kind = "wall", tile = 35, fg = "#808080", bg = "#606060" } }
assert!(board.solid_at(x, y).unwrap().player());
} else {
let obj = &board.objects[&board.object_ids_at(x, y)[0]];
let tag = obj.tags.iter().next().unwrap();
let tag = obj.scripting.tags.iter().next().unwrap();
assert_eq!(tag, "BUILTIN_wall")
}
+1 -1
View File
@@ -1,5 +1,5 @@
use super::{grid, load_board, map};
use crate::archetype::Archetype;
use crate::builtin::Archetype;
use crate::board::Board;
use crate::map_file::MapFile;
@@ -1,5 +1,5 @@
use super::{grid, load_board, map, map_3x1_object};
use crate::archetype::Archetype;
use crate::builtin::Archetype;
/// Palette shorthand.
const PLAYER: (&str, &str) = ("@", "kind = \"player\"");
@@ -30,8 +30,8 @@ fn duplicate_name_clears_second_but_keeps_both_objects() {
),
));
assert_eq!(board.objects.len(), 2, "both objects survive");
assert_eq!(board.objects[&1].name.as_deref(), Some("gate"));
assert_eq!(board.objects[&2].name, None);
assert_eq!(board.objects[&1].scripting.name.as_deref(), Some("gate"));
assert_eq!(board.objects[&2].scripting.name, None);
assert!(!board.is_valid(), "duplicate name is a nonfatal load error");
}
@@ -66,9 +66,9 @@ fn palette_char_multi_occurrence_only_first_keeps_name() {
),
));
assert_eq!(board.objects.len(), 3);
assert_eq!(board.objects[&1].name.as_deref(), Some("guard"));
assert_eq!(board.objects[&2].name, None);
assert_eq!(board.objects[&3].name, None);
assert_eq!(board.objects[&1].scripting.name.as_deref(), Some("guard"));
assert_eq!(board.objects[&2].scripting.name, None);
assert_eq!(board.objects[&3].scripting.name, None);
}
#[test]
@@ -1,5 +1,5 @@
use super::{grid, load_board, map};
use crate::archetype::Archetype;
use crate::builtin::Archetype;
/// Palette shorthands shared by these tests.
const EMPTY: (&str, &str) = (".", "kind = \"empty\"");
+7 -7
View File
@@ -2,19 +2,19 @@
//! carrying the embedded `pusher.rhai` plus a `BUILTIN_pusher_<dir>` tag).
use super::{grid, load_board, map};
use crate::archetype::Archetype;
use crate::builtin::Archetype;
use crate::game::GameState;
use crate::map_file::MapFile;
use crate::object_def::ObjectDef;
use std::time::Duration;
use crate::{Board, Builtin};
use crate::Board;
/// Finds the pusher object on a board (by its built-in tag).
fn pusher<'a>(board: &'a crate::board::Board, id: &mut u32) -> &'a ObjectDef {
let (&oid, obj) = board
.objects
.iter()
.find(|(_, o)| o.tags.contains("BUILTIN_pusher_east"))
.find(|(_, o)| o.scripting.tags.contains("BUILTIN_pusher_east"))
.expect("pusher object");
*id = oid;
obj
@@ -34,17 +34,17 @@ fn pusher_loads_as_a_tagged_scripted_solid_object() {
let p = pusher(&board, &mut id);
assert_eq!((p.x, p.y), (0, 0));
assert!(
p.builtin_script.is_some(),
p.scripting.builtin_script.is_some(),
"carries the embedded pusher script"
);
// Each alias gets its own compile-cache key (e.g. "BUILTIN_pusher_east") so the
// script can read direction from Me.has_tag("BUILTIN_pusher_east").
assert_eq!(p.script_name.as_deref(), Some("BUILTIN_pusher_east"));
assert_eq!(p.scripting.script_name.as_deref(), Some("BUILTIN_pusher_east"));
assert!(!board.is_passable(0, 0), "pusher is solid");
}
fn is_tag(board: &Board, x: usize, y: usize, tag: &str) -> bool {
board.object_ids_at(x, y).iter().any(|id| board.objects[id].tags.contains(tag))
board.object_ids_at(x, y).iter().any(|id| board.objects[id].scripting.tags.contains(tag))
}
#[test]
@@ -135,5 +135,5 @@ fn pusher_round_trips_to_its_keyword() {
let mut id = 0;
let p = pusher(&board2, &mut id);
assert_eq!((p.x, p.y), (0, 0));
assert!(p.builtin_script.is_some());
assert!(p.scripting.builtin_script.is_some());
}
+6 -6
View File
@@ -60,8 +60,8 @@ fn object_tags_round_trip_through_toml() {
);
let board = load_board(&toml);
let obj0 = &board.objects[&1];
assert!(obj0.tags.contains("enemy") && obj0.tags.contains("boss"));
assert_eq!(obj0.tags.len(), 2);
assert!(obj0.scripting.tags.contains("enemy") && obj0.scripting.tags.contains("boss"));
assert_eq!(obj0.scripting.tags.len(), 2);
// Saved tags must be sorted alphabetically (boss before enemy).
let toml_out = toml::to_string_pretty(&MapFile::from(&board)).unwrap();
@@ -70,7 +70,7 @@ fn object_tags_round_trip_through_toml() {
assert!(boss < enemy, "tags must be sorted: boss before enemy");
let board2 = load_board(&toml_out);
assert_eq!(board2.objects[&1].tags, obj0.tags);
assert_eq!(board2.objects[&1].scripting.tags, obj0.scripting.tags);
}
#[test]
@@ -95,7 +95,7 @@ fn object_name_round_trips_through_toml() {
),
);
let board = load_board(&toml);
assert_eq!(board.objects[&1].name.as_deref(), Some("beacon"));
assert_eq!(board.objects[&1].scripting.name.as_deref(), Some("beacon"));
let toml_out = toml::to_string_pretty(&MapFile::from(&board)).unwrap();
assert!(
@@ -103,7 +103,7 @@ fn object_name_round_trips_through_toml() {
"name must appear in saved TOML"
);
let board2 = load_board(&toml_out);
assert_eq!(board2.objects[&1].name.as_deref(), Some("beacon"));
assert_eq!(board2.objects[&1].scripting.name.as_deref(), Some("beacon"));
}
#[test]
@@ -111,7 +111,7 @@ fn unnamed_object_name_stays_none_through_toml() {
let toml = map(3, 1, &grid("@O.", &[PLAYER, ("O", &obj("")), EMPTY]));
let board2 = round_trip(&toml);
assert_eq!(
board2.objects[&1].name, None,
board2.objects[&1].scripting.name, None,
"unnamed object must round-trip as None"
);
}
+5 -5
View File
@@ -18,16 +18,16 @@ fn spinner_loads_as_a_tagged_scripted_solid_object() {
let (_, obj) = board
.objects
.iter()
.find(|(_, o)| o.tags.contains("BUILTIN_spinner_cw"))
.find(|(_, o)| o.scripting.tags.contains("BUILTIN_spinner_cw"))
.expect("spinner object");
assert_eq!((obj.x, obj.y), (0, 0));
assert!(
obj.builtin_script.is_some(),
obj.scripting.builtin_script.is_some(),
"carries the embedded spinner script"
);
// Each alias gets its own compile-cache key (e.g. "BUILTIN_spinner_cw") so the
// script can read direction from Me.has_tag("BUILTIN_spinner_cw").
assert_eq!(obj.script_name.as_deref(), Some("BUILTIN_spinner_cw"));
assert_eq!(obj.scripting.script_name.as_deref(), Some("BUILTIN_spinner_cw"));
assert!(!board.is_passable(0, 0), "spinner is solid");
}
@@ -53,8 +53,8 @@ fn spinner_round_trips_to_its_keyword() {
let (_, obj) = board2
.objects
.iter()
.find(|(_, o)| o.tags.contains("BUILTIN_spinner_ccw"))
.find(|(_, o)| o.scripting.tags.contains("BUILTIN_spinner_ccw"))
.expect("spinner object after round-trip");
assert_eq!((obj.x, obj.y), (0, 0));
assert!(obj.builtin_script.is_some());
assert!(obj.scripting.builtin_script.is_some());
}
+3 -3
View File
@@ -22,10 +22,10 @@ fn transporter_loads_as_a_tagged_scripted_object() {
let (_, obj) = board
.objects
.iter()
.find(|(_, o)| o.tags.contains("BUILTIN_transporter_east"))
.find(|(_, o)| o.scripting.tags.contains("BUILTIN_transporter_east"))
.expect("transporter object");
assert_eq!((obj.x, obj.y), (1, 0));
assert!(obj.builtin_script.is_some(), "carries the embedded script");
assert!(obj.scripting.builtin_script.is_some(), "carries the embedded script");
}
#[test]
@@ -145,7 +145,7 @@ fn transporter_round_trips_to_its_keyword() {
board2
.objects
.values()
.any(|o| o.tags.contains("BUILTIN_transporter_east") && o.builtin_script.is_some()),
.any(|o| o.scripting.tags.contains("BUILTIN_transporter_east") && o.scripting.builtin_script.is_some()),
"reloads as a tagged transporter object",
);
}