redoing bump
This commit is contained in:
@@ -252,6 +252,41 @@ impl Board {
|
||||
.is_some_and(|s| s.pushable().allows(dir))
|
||||
}
|
||||
|
||||
/// The object that a move **into** `(x, y)` heading `dir` bumps, if any.
|
||||
///
|
||||
/// Walks the chain of pushable crates from the target cell in `dir` until it
|
||||
/// reaches something that stops it, and reports the object it presses against:
|
||||
/// - a solid object in the target cell (or at the end of a crate chain) is the
|
||||
/// bumped object,
|
||||
/// - open space or the player means nothing is bumped,
|
||||
/// - a non-pushable terrain cell (a wall) blocks the chain with no object to bump.
|
||||
///
|
||||
/// This is what lets *any* solid — the player, another object, or a pushed
|
||||
/// crate — trigger a `bump`: the bumper need not be an object, since we only
|
||||
/// return the *bumped* object's id (the direction it came from is supplied by
|
||||
/// the caller from its move direction).
|
||||
pub fn bump_target(&self, x: usize, y: usize, dir: Direction) -> Option<ObjectId> {
|
||||
let (dx, dy): (i64, i64) = dir.into();
|
||||
let (mut cx, mut cy) = (x, y);
|
||||
loop {
|
||||
match self.solid_at(cx, cy) {
|
||||
None => return None, // open space: nothing bumped
|
||||
Some(s) if s.object_id().is_some() => return s.object_id(), // hit an object
|
||||
Some(s) if s.player() => return None, // the player is never "bumped"
|
||||
// A terrain cell: a pushable crate is walked through; a wall stops us.
|
||||
Some(_) if self.is_pushable(cx, cy, dir) => {
|
||||
let next = (cx as i64 + dx, cy as i64 + dy);
|
||||
if !self.in_bounds(next) {
|
||||
return None; // crate chain runs off the board
|
||||
}
|
||||
cx = next.0 as usize;
|
||||
cy = next.1 as usize;
|
||||
}
|
||||
Some(_) => return None, // non-pushable terrain (wall): no object behind it here
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether the chain of pushable solids starting at `(x, y)` can be shoved one
|
||||
/// step in `dir` — i.e. the chain ends at a passable cell rather than the board
|
||||
/// edge or a non-pushable solid.
|
||||
|
||||
Reference in New Issue
Block a user