redoing bump
This commit is contained in:
@@ -8,8 +8,9 @@
|
||||
//
|
||||
// The direction is not baked into this source: every transporter shares one
|
||||
// compiled copy and reads its `BUILTIN_transporter_<dir>` tag. The world is
|
||||
// reached through the global `Board`/`Player` constants; `teleport(id, x, y)`
|
||||
// moves an arbitrary entity (`-1` is the player).
|
||||
// reached through the global `Board`/`Player` constants. The bumper is moved by
|
||||
// coordinate via `shift([[from], [to]])`, which relocates whatever solid sits at
|
||||
// the entrance — player, object, or a pushed crate — onto the empty destination.
|
||||
|
||||
// This transporter's facing unit vector, from its direction tag.
|
||||
fn facing(me) {
|
||||
@@ -27,6 +28,16 @@ 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] } // ^ - ^ ~
|
||||
@@ -47,38 +58,41 @@ fn tick(me, dt) {
|
||||
me.delay(0.15);
|
||||
}
|
||||
|
||||
fn bump(me, id) {
|
||||
// Move whatever solid sits at (sx, sy) onto the empty cell (tx, ty) immediately.
|
||||
// A two-cell `shift` relocates the source solid — player, object, or crate — and
|
||||
// leaves its old cell empty (the destination is checked empty by the caller). Kept
|
||||
// as a helper so the nested-array literal stays at a shallow expression depth.
|
||||
fn transport(sx, sy, tx, ty) {
|
||||
shift([[sx, sy], [tx, ty]]); now();
|
||||
}
|
||||
|
||||
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 cell at
|
||||
// (me - d). A bump from any other side does nothing.
|
||||
let bx;
|
||||
let by;
|
||||
if id == -1 {
|
||||
bx = Player.x;
|
||||
by = Player.y;
|
||||
} else {
|
||||
let o = Board.get(id);
|
||||
if o == () { return; }
|
||||
bx = o.x;
|
||||
by = o.y;
|
||||
}
|
||||
if bx != me.x - dx || by != me.y - 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.
|
||||
let ex = me.x - dx;
|
||||
let ey = me.y - dy;
|
||||
|
||||
// 1. The cell just past us (the opposite side): if nothing solid is there,
|
||||
// drop the bumper onto it.
|
||||
let fx = me.x + dx;
|
||||
let fy = me.y + dy;
|
||||
if Board.passable(fx, fy) {
|
||||
teleport(id, fx, fy); now();
|
||||
transport(ex, ey, fx, fy);
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. Otherwise scan along our axis for the nearest opposite-facing transporter
|
||||
// whose entrance (the cell just before it) is free, and drop the bumper
|
||||
// there. A blocked pair is skipped; give up at the board edge.
|
||||
// whose far side (the cell just past it) is free, and drop the bumper there.
|
||||
// A blocked pair is skipped; give up at the board edge.
|
||||
let opp = Board.tagged(opposite_tag(me));
|
||||
let cx = fx;
|
||||
let cy = fy;
|
||||
@@ -94,10 +108,12 @@ fn bump(me, id) {
|
||||
if o.x == cx && o.y == cy { here = true; }
|
||||
}
|
||||
if here {
|
||||
let ex = cx + dx;
|
||||
let ey = cy + dy;
|
||||
if Board.passable(ex, ey) {
|
||||
teleport(id, ex, ey); now();
|
||||
// Emerge on the paired transporter's far side — the cell just past it
|
||||
// along our scan (cx + d), out its back.
|
||||
let tx = cx + dx;
|
||||
let ty = cy + dy;
|
||||
if Board.passable(tx, ty) {
|
||||
transport(ex, ey, tx, ty);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user