simplify
This commit is contained in:
+17
-14
@@ -269,21 +269,24 @@ impl Board {
|
|||||||
let (dx, dy): (i64, i64) = dir.into();
|
let (dx, dy): (i64, i64) = dir.into();
|
||||||
let (mut cx, mut cy) = (x, y);
|
let (mut cx, mut cy) = (x, y);
|
||||||
loop {
|
loop {
|
||||||
match self.solid_at(cx, cy) {
|
// Open space ends the walk with nothing bumped.
|
||||||
None => return None, // open space: nothing bumped
|
let solid = self.solid_at(cx, cy)?;
|
||||||
Some(s) if s.object_id().is_some() => return s.object_id(), // hit an object
|
// A solid object — directly, or at the end of a crate chain — is the target.
|
||||||
Some(s) if s.player() => return None, // the player is never "bumped"
|
if let Some(id) = solid.object_id() {
|
||||||
// A terrain cell: a pushable crate is walked through; a wall stops us.
|
return Some(id);
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
// The player is never itself "bumped"; a wall (non-pushable terrain) stops
|
||||||
|
// the chain with no object behind it. Only a pushable crate is walked
|
||||||
|
// through — reuse the already-fetched `solid` rather than re-scanning.
|
||||||
|
if solid.player() || !solid.pushable().allows(dir) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -485,10 +485,11 @@ impl GameState {
|
|||||||
// A solid object in the way is bumped by the player — possibly through a
|
// A solid object in the way is bumped by the player — possibly through a
|
||||||
// chain of crates the player is shoving (see `bump_target`) — but a grab
|
// chain of crates the player is shoving (see `bump_target`) — but a grab
|
||||||
// thing fires grab() instead of bump(), so don't also bump it.
|
// thing fires grab() instead of bump(), so don't also bump it.
|
||||||
bumped = grabbed
|
bumped = if grabbed.is_none() {
|
||||||
.is_none()
|
board.bump_target(nx, ny, dir)
|
||||||
.then(|| board.bump_target(nx, ny, dir))
|
} else {
|
||||||
.flatten();
|
None
|
||||||
|
};
|
||||||
if grabbed.is_some() || board.is_passable(nx, ny) || board.can_push(nx, ny, dir) {
|
if grabbed.is_some() || board.is_passable(nx, ny) || board.can_push(nx, ny, dir) {
|
||||||
// Don't push a grab thing aside — walk onto it. Otherwise shove any
|
// Don't push a grab thing aside — walk onto it. Otherwise shove any
|
||||||
// pushable chain out of the way (no-op when there's nothing to push).
|
// pushable chain out of the way (no-op when there's nothing to push).
|
||||||
|
|||||||
@@ -28,16 +28,6 @@ fn opposite_tag(me) {
|
|||||||
else { "BUILTIN_transporter_east" }
|
else { "BUILTIN_transporter_east" }
|
||||||
}
|
}
|
||||||
|
|
||||||
// The direction a front bump arrives from — the side opposite our facing (a
|
|
||||||
// north-facing transporter is entered from the south, etc.). `bump` reacts only
|
|
||||||
// when the reported direction matches this.
|
|
||||||
fn entrance_dir(me) {
|
|
||||||
if me.has_tag("BUILTIN_transporter_north") { South }
|
|
||||||
else if me.has_tag("BUILTIN_transporter_south") { North }
|
|
||||||
else if me.has_tag("BUILTIN_transporter_east") { West }
|
|
||||||
else { East }
|
|
||||||
}
|
|
||||||
|
|
||||||
// The 4-frame animation loop for this direction (CP437 tile codes).
|
// The 4-frame animation loop for this direction (CP437 tile codes).
|
||||||
fn frames(me) {
|
fn frames(me) {
|
||||||
if me.has_tag("BUILTIN_transporter_north") { [94, 45, 94, 126] } // ^ - ^ ~
|
if me.has_tag("BUILTIN_transporter_north") { [94, 45, 94, 126] } // ^ - ^ ~
|
||||||
@@ -67,14 +57,15 @@ fn transport(sx, sy, tx, ty) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn bump(me, dir) {
|
fn bump(me, dir) {
|
||||||
// Only transport things that hit us from the front — the entrance side. `dir`
|
|
||||||
// is the direction the bump came from; a bump from any other side does nothing.
|
|
||||||
if dir != entrance_dir(me) { return; }
|
|
||||||
|
|
||||||
let d = facing(me);
|
let d = facing(me);
|
||||||
let dx = d[0];
|
let dx = d[0];
|
||||||
let dy = d[1];
|
let dy = d[1];
|
||||||
|
|
||||||
|
// Only transport things that hit us from the front — the entrance side (-facing).
|
||||||
|
// `dir` is the side the bump came from, so its offset must be the opposite of our
|
||||||
|
// facing; a bump from any other side does nothing.
|
||||||
|
if dir.dx != -dx || dir.dy != -dy { return; }
|
||||||
|
|
||||||
// Whatever solid is pressed against our entrance cell (me - d) gets moved:
|
// Whatever solid is pressed against our entrance cell (me - d) gets moved:
|
||||||
// the player, another object, or a pushed crate — all handled uniformly by
|
// the player, another object, or a pushed crate — all handled uniformly by
|
||||||
// shifting the solid at that coordinate onto an empty destination.
|
// shifting the solid at that coordinate onto an empty destination.
|
||||||
|
|||||||
Reference in New Issue
Block a user