redoing bump
This commit is contained in:
@@ -18,11 +18,11 @@ fn collision_priority_resolves_in_array_order_and_bumps() {
|
||||
scripts_from(&[
|
||||
(
|
||||
"e",
|
||||
"fn init(m) { move(East); } fn bump(m,id) { log(`o0 by ${id}`); }",
|
||||
"fn init(m) { move(East); } fn bump(m,dir) { log(`o0 from ${dir}`); }",
|
||||
),
|
||||
(
|
||||
"w",
|
||||
"fn init(m) { move(West); } fn bump(m,id) { log(`o1 by ${id}`); }",
|
||||
"fn init(m) { move(West); } fn bump(m,dir) { log(`o1 from ${dir}`); }",
|
||||
),
|
||||
]),
|
||||
);
|
||||
@@ -36,6 +36,7 @@ fn collision_priority_resolves_in_array_order_and_bumps() {
|
||||
assert_eq!((b.objects[&2].x, b.objects[&2].y), (2, 0)); // obj1 blocked
|
||||
}
|
||||
let logs = log_texts(&game);
|
||||
assert!(logs.iter().any(|t| t == "o0 by 2")); // obj0 bumped by obj1
|
||||
assert!(!logs.iter().any(|t| t.starts_with("o1 by"))); // obj1 not bumped
|
||||
// obj1 moved West into obj0, so the bump arrives from the East side of obj0.
|
||||
assert!(logs.iter().any(|t| t == "o0 from East")); // obj0 bumped by obj1
|
||||
assert!(!logs.iter().any(|t| t.starts_with("o1 from"))); // obj1 not bumped
|
||||
}
|
||||
|
||||
@@ -56,9 +56,9 @@ fn bumping_a_transporter_drops_you_on_its_far_side() {
|
||||
|
||||
#[test]
|
||||
fn a_blocked_far_side_transports_out_of_the_paired_transporter() {
|
||||
// Player, east transporter, a wall blocking its far side, the free entrance
|
||||
// cell, then the paired west transporter. The player should pop out at the
|
||||
// west transporter's entrance (the cell just before it), across the wall.
|
||||
// Player, east transporter, a wall blocking its far side, a gap, the paired
|
||||
// west transporter, then a free cell. The player should pop out on the paired
|
||||
// transporter's far side (the cell just past it), across the wall.
|
||||
let board = load_board(&map(
|
||||
6,
|
||||
1,
|
||||
@@ -81,11 +81,49 @@ fn a_blocked_far_side_transports_out_of_the_paired_transporter() {
|
||||
let b = game.board();
|
||||
assert_eq!(
|
||||
(b.player.x, b.player.y),
|
||||
(3, 0),
|
||||
"transported to the paired transporter's entrance",
|
||||
(5, 0),
|
||||
"transported past the paired transporter",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_pushed_crate_is_transported_through() {
|
||||
// Player, a crate, an east transporter, then a free cell. Pushing the crate
|
||||
// east into the transporter bumps it (through the crate chain); the transporter
|
||||
// moves the crate — a plain terrain solid, no object id — out its far side.
|
||||
let board = load_board(&map(
|
||||
4,
|
||||
1,
|
||||
&[layer(
|
||||
"@oT ",
|
||||
&[
|
||||
("@", "kind = \"player\""),
|
||||
("o", "kind = \"crate\""),
|
||||
("T", "kind = \"transporter_east\""),
|
||||
],
|
||||
)],
|
||||
));
|
||||
let mut game = GameState::new(board);
|
||||
game.run_init();
|
||||
|
||||
// Push east into the crate: the crate can't move (the transporter blocks it),
|
||||
// but the transporter is bumped from the West and teleports the crate to (3,0).
|
||||
game.try_move(Direction::East);
|
||||
game.tick(Duration::from_secs_f64(0.1));
|
||||
{
|
||||
let b = game.board();
|
||||
assert!(b.solid_at(3, 0).is_some(), "crate transported to the far side");
|
||||
assert!(b.is_passable(1, 0), "crate's old cell is now empty");
|
||||
assert_eq!((b.player.x, b.player.y), (0, 0), "player didn't move yet");
|
||||
}
|
||||
|
||||
// With the crate gone, a second push walks the player onto the vacated cell.
|
||||
game.try_move(Direction::East);
|
||||
game.tick(Duration::from_secs_f64(0.1));
|
||||
let b = game.board();
|
||||
assert_eq!((b.player.x, b.player.y), (1, 0), "player follows into the gap");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn transporter_round_trips_to_its_keyword() {
|
||||
let board = load_board(&map(
|
||||
|
||||
@@ -245,20 +245,40 @@ fn object_id_for_name_finds_by_name() {
|
||||
|
||||
// Ensure try_move from the player side also triggers scripted bump
|
||||
#[test]
|
||||
fn player_bump_fires_with_negative_one() {
|
||||
// The player walks into a solid scripted object; the object is bumped with -1
|
||||
// and the player does not move onto it.
|
||||
fn player_bump_reports_the_direction_it_came_from() {
|
||||
// The player walks East into a solid scripted object; the object is bumped from
|
||||
// the West side (opposite the player's travel) and the player does not move onto it.
|
||||
let board = open_board(3, 1, (0, 0), vec![scripted_object(1, 0, "b")]);
|
||||
let mut game = GameState::with_scripts(
|
||||
board,
|
||||
scripts_from(&[("b", "fn bump(m,id) { log(`bumped by ${id}`); }")]),
|
||||
scripts_from(&[("b", "fn bump(m,dir) { log(`bumped from ${dir}`); }")]),
|
||||
);
|
||||
game.run_init();
|
||||
game.try_move(Direction::East);
|
||||
assert_eq!((game.board().player.x, game.board().player.y), (0, 0)); // blocked
|
||||
// bump's log is emitted into the object's queue; a tick flushes it.
|
||||
game.tick(Duration::from_millis(16));
|
||||
assert!(log_texts(&game).iter().any(|t| t == "bumped by -1"));
|
||||
assert!(log_texts(&game).iter().any(|t| t == "bumped from West"));
|
||||
}
|
||||
|
||||
// A bump handler can compare the direction and read its `dx`/`dy` offset to
|
||||
// locate the bumper's cell.
|
||||
#[test]
|
||||
fn bump_direction_supports_comparison_and_offset() {
|
||||
let board = open_board(3, 1, (0, 0), vec![scripted_object(1, 0, "b")]);
|
||||
let mut game = GameState::with_scripts(
|
||||
board,
|
||||
scripts_from(&[(
|
||||
"b",
|
||||
// Player bumps from the West, so `dir == West` and the bumper sits at
|
||||
// (me.x + dir.dx) = 1 + (-1) = 0.
|
||||
"fn bump(m,dir) { if dir == West { log(`bumper at ${m.x + dir.dx}`); } }",
|
||||
)]),
|
||||
);
|
||||
game.run_init();
|
||||
game.try_move(Direction::East);
|
||||
game.tick(Duration::from_millis(16));
|
||||
assert!(log_texts(&game).iter().any(|t| t == "bumper at 0"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -271,7 +291,7 @@ fn scroll_opens_on_player_bump() {
|
||||
board,
|
||||
scripts_from(&[(
|
||||
"s",
|
||||
r#"fn bump(m,id) { scroll(["Hello world", ["eat", "Eat it"]]); }"#,
|
||||
r#"fn bump(m,dir) { scroll(["Hello world", ["eat", "Eat it"]]); }"#,
|
||||
)]),
|
||||
);
|
||||
game.run_init();
|
||||
@@ -295,7 +315,7 @@ fn handle_scroll_without_choice_clears_it() {
|
||||
let board = open_board(3, 1, (0, 0), vec![scripted_object(1, 0, "s")]);
|
||||
let mut game = GameState::with_scripts(
|
||||
board,
|
||||
scripts_from(&[("s", r#"fn bump(m,id) { scroll(["Hello"]); }"#)]),
|
||||
scripts_from(&[("s", r#"fn bump(m,dir) { scroll(["Hello"]); }"#)]),
|
||||
);
|
||||
game.run_init();
|
||||
game.try_move(Direction::East);
|
||||
@@ -317,7 +337,7 @@ fn handle_scroll_with_choice_dispatches_send_to_source() {
|
||||
scripts_from(&[(
|
||||
"s",
|
||||
r#"
|
||||
fn bump(m,id) { scroll(["Muffin?", ["eat", "Eat it"]]); }
|
||||
fn bump(m,dir) { scroll(["Muffin?", ["eat", "Eat it"]]); }
|
||||
fn eat() { log("eaten"); }
|
||||
"#,
|
||||
)]),
|
||||
|
||||
Reference in New Issue
Block a user