From 386967e936ef63790dd89f0fda3f97174cd40b62 Mon Sep 17 00:00:00 2001 From: Ross Andrews Date: Thu, 9 Jul 2026 00:18:40 -0500 Subject: [PATCH] simplify --- kiln-core/src/board.rs | 31 ++++++++++++++------------ kiln-core/src/game.rs | 9 ++++---- kiln-core/src/scripts/transporter.rhai | 19 +++++----------- 3 files changed, 27 insertions(+), 32 deletions(-) diff --git a/kiln-core/src/board.rs b/kiln-core/src/board.rs index cdbda60..86cead6 100644 --- a/kiln-core/src/board.rs +++ b/kiln-core/src/board.rs @@ -269,21 +269,24 @@ impl Board { 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 + // Open space ends the walk with nothing bumped. + let solid = self.solid_at(cx, cy)?; + // A solid object — directly, or at the end of a crate chain — is the target. + if let Some(id) = solid.object_id() { + return Some(id); } + // 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; } } diff --git a/kiln-core/src/game.rs b/kiln-core/src/game.rs index 6c75284..b98ad0f 100644 --- a/kiln-core/src/game.rs +++ b/kiln-core/src/game.rs @@ -485,10 +485,11 @@ impl GameState { // 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 // thing fires grab() instead of bump(), so don't also bump it. - bumped = grabbed - .is_none() - .then(|| board.bump_target(nx, ny, dir)) - .flatten(); + bumped = if grabbed.is_none() { + board.bump_target(nx, ny, dir) + } else { + None + }; 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 // pushable chain out of the way (no-op when there's nothing to push). diff --git a/kiln-core/src/scripts/transporter.rhai b/kiln-core/src/scripts/transporter.rhai index 8fa6a09..4d0492a 100644 --- a/kiln-core/src/scripts/transporter.rhai +++ b/kiln-core/src/scripts/transporter.rhai @@ -28,16 +28,6 @@ fn opposite_tag(me) { 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). fn frames(me) { 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) { - // 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 dx = d[0]; 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: // the player, another object, or a pushed crate — all handled uniformly by // shifting the solid at that coordinate onto an empty destination.