speech bubble fixes, multi objects

This commit is contained in:
2026-06-13 13:59:13 -05:00
parent f327e77e3d
commit 887e1fefea
7 changed files with 675 additions and 178 deletions
@@ -35,13 +35,30 @@ fn palette_char_absent_from_grid_drops_object() {
}
#[test]
fn palette_char_appearing_twice_uses_first() {
// `G` appears at (0,0) and (2,0): the object lands at the first, and the
// map is flagged invalid (an extra appearance was reported).
let board = load_board(&map_3x1("G.G", &obj_palette("G", "")));
assert_eq!(board.objects.len(), 1);
fn palette_char_appearing_twice_spawns_two_objects() {
// `G` appears at (0,0) and (1,0); player is at (2,0) so neither G conflicts.
// Two independent ObjectDefs are spawned.
let board = load_board(&map_3x1("GG.", &obj_palette("G", "")));
assert_eq!(board.objects.len(), 2);
// IDs are assigned in reading order (left-to-right).
assert_eq!((board.objects[&1].x, board.objects[&1].y), (0, 0));
assert!(!board.is_valid());
assert_eq!((board.objects[&2].x, board.objects[&2].y), (1, 0));
// Both cells load as Empty in the grid.
assert_eq!(board.get(0, 0).1, Archetype::Empty);
assert_eq!(board.get(1, 0).1, Archetype::Empty);
assert!(board.is_valid(), "multiple occurrences are not an error");
}
#[test]
fn palette_char_multi_occurrence_only_first_keeps_name() {
// Two occurrences of a named entry (solid = false to avoid player conflict at (2,0)).
// First instance gets the name; second is anonymous.
let entry = obj_palette("G", "solid = false\nname = \"guard\"\n");
let board = load_board(&map_3x1("GGG", &entry));
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);
}
#[test]
+3 -1
View File
@@ -106,7 +106,9 @@ fn start_map_greeter_runs_init() {
// confirm the greeter read the board (interpolated message) and wrote to
// itself (set_tile). Also guards the example from drifting out of sync.
let path = concat!(env!("CARGO_MANIFEST_DIR"), "/../maps/start.toml");
let world = crate::world::load(path).expect("load start.toml");
let mut world = crate::world::load(path).expect("load start.toml");
// Pin to the "start" board regardless of the world's current default entry point.
world.start = "start".to_string();
let mut game = GameState::from_world(world);
game.run_init();
assert!(