Square wall corners hold grains, liquids and gas (t39)
Powder, liquid and gas no longer step diagonally between two solid cells; flyers and diagonal tube intakes obey the same corner. World generation settles with the rule off, so seeds make the same worlds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+8
-7
@@ -67,8 +67,9 @@ let SORTP = 0.06;
|
||||
const SORTP_FUEL = 0.003;
|
||||
// Liquids step up to LSTEP cells toward a drop in one tick (fewer the thicker they are), and a top-layer grain looks LFILM
|
||||
// times as far for one (a two-times range strands the far end of a 200-grain-wide ledge).
|
||||
// World generation settles with both at 1, so every seed keeps making the same world.
|
||||
// World generation settles with both at 1 and corner sealing off, so seeds keep the same world.
|
||||
let LSTEP = 8, LFILM = 4;
|
||||
let CORNER_SEAL = true;
|
||||
function powder(i, x, y, m) {
|
||||
if (y >= H - 1) return;
|
||||
const b = i + W;
|
||||
@@ -82,9 +83,9 @@ function powder(i, x, y, m) {
|
||||
if (rnd() < STICK[m]) {
|
||||
const d = (RS & 2) ? 1 : -1;
|
||||
let nx = x + d;
|
||||
if (nx >= 0 && nx < W && enter(m, PH_POWDER, b + d, d, 1)) { move(i, b + d, x, y, nx, y + 1); return; }
|
||||
if (nx >= 0 && nx < W && (!CORNER_SEAL || PH[mat[b]] !== PH_SOLID || PH[mat[i + d]] !== PH_SOLID) && enter(m, PH_POWDER, b + d, d, 1)) { move(i, b + d, x, y, nx, y + 1); return; }
|
||||
nx = x - d;
|
||||
if (nx >= 0 && nx < W && enter(m, PH_POWDER, b - d, -d, 1)) { move(i, b - d, x, y, nx, y + 1); return; }
|
||||
if (nx >= 0 && nx < W && (!CORNER_SEAL || PH[mat[b]] !== PH_SOLID || PH[mat[i - d]] !== PH_SOLID) && enter(m, PH_POWDER, b - d, -d, 1)) { move(i, b - d, x, y, nx, y + 1); return; }
|
||||
}
|
||||
}
|
||||
function passable(m, ph, j, dx, dy) {
|
||||
@@ -106,9 +107,9 @@ function liquid(i, x, y, m) {
|
||||
if (enter(m, PH_LIQUID, b, 0, 1)) { move(i, b, x, y, x, y + 1); return; }
|
||||
const d = (RS & 2) ? 1 : -1;
|
||||
let nx = x + d;
|
||||
if (nx >= 0 && nx < W && enter(m, PH_LIQUID, b + d, d, 1)) { move(i, b + d, x, y, nx, y + 1); return; }
|
||||
if (nx >= 0 && nx < W && (!CORNER_SEAL || PH[mat[b]] !== PH_SOLID || PH[mat[i + d]] !== PH_SOLID) && enter(m, PH_LIQUID, b + d, d, 1)) { move(i, b + d, x, y, nx, y + 1); return; }
|
||||
nx = x - d;
|
||||
if (nx >= 0 && nx < W && enter(m, PH_LIQUID, b - d, -d, 1)) { move(i, b - d, x, y, nx, y + 1); return; }
|
||||
if (nx >= 0 && nx < W && (!CORNER_SEAL || PH[mat[b]] !== PH_SOLID || PH[mat[i - d]] !== PH_SOLID) && enter(m, PH_LIQUID, b - d, -d, 1)) { move(i, b - d, x, y, nx, y + 1); return; }
|
||||
}
|
||||
if (rnd() > FLUID[m]) return;
|
||||
const sp = SPREAD[m] * (y === 0 || PH[mat[i - W]] !== PH_LIQUID ? LFILM : 1);
|
||||
@@ -153,9 +154,9 @@ function gas(i, x, y, m) {
|
||||
if (enter(m, PH_GAS, u, 0, -1)) { move(i, u, x, y, x, y - 1); return; }
|
||||
const d = (RS & 2) ? 1 : -1;
|
||||
let nx = x + d;
|
||||
if (nx >= 0 && nx < W && enter(m, PH_GAS, u + d, d, -1)) { move(i, u + d, x, y, nx, y - 1); return; }
|
||||
if (nx >= 0 && nx < W && (!CORNER_SEAL || PH[mat[u]] !== PH_SOLID || PH[mat[i + d]] !== PH_SOLID) && enter(m, PH_GAS, u + d, d, -1)) { move(i, u + d, x, y, nx, y - 1); return; }
|
||||
nx = x - d;
|
||||
if (nx >= 0 && nx < W && enter(m, PH_GAS, u - d, -d, -1)) { move(i, u - d, x, y, nx, y - 1); return; }
|
||||
if (nx >= 0 && nx < W && (!CORNER_SEAL || PH[mat[u]] !== PH_SOLID || PH[mat[i - d]] !== PH_SOLID) && enter(m, PH_GAS, u - d, -d, -1)) { move(i, u - d, x, y, nx, y - 1); return; }
|
||||
if (rnd() < 0.6) {
|
||||
nx = x + d;
|
||||
if (nx >= 0 && nx < W && mat[i + d] === EMPTY && passable(m, PH_GAS, i + d, d, 0)) { move(i, i + d, x, y, nx, y); }
|
||||
|
||||
@@ -169,6 +169,7 @@ function tubeIntake(i, p, dx, dy) {
|
||||
const oy = diagonal ? (k === 0 ? 0 : -dy) : k === 0 ? -dy : k === 1 ? dx : -dx;
|
||||
const nx = x + ox, ny = y + oy;
|
||||
if (nx < 0 || ny < 0 || nx >= W || ny >= H) continue;
|
||||
if (ox && oy && PH[mat[y * W + nx]] === PH_SOLID && PH[mat[ny * W + x]] === PH_SOLID) continue;
|
||||
const j = ny * W + nx, m = mat[j];
|
||||
if (m === EMPTY || occ[j] || stamp[j] === tickStamp) continue;
|
||||
if (PH[m] !== PH_POWDER) continue; // the screw only takes loose material; liquids just flow through
|
||||
|
||||
+4
-1
@@ -146,7 +146,10 @@ function flyTick() {
|
||||
if (cx < 0 || cx >= W) { f.vx = 0; continue; } // the world's edge stops it; it drops from there
|
||||
if (cy >= H) { landFlyer(f, px, H - 1); done = true; break; }
|
||||
if (cy < 0) { f.x = nx; f.y = ny; continue; }
|
||||
const open = flyOpen(f.m, cy * W + cx);
|
||||
// A free flyer must not cut across the point where two solid cells meet.
|
||||
const sealed = cx !== px && cy !== py && px >= 0 && px < W && py >= 0 && py < H &&
|
||||
PH[mat[py * W + cx]] === PH_SOLID && PH[mat[cy * W + px]] === PH_SOLID;
|
||||
const open = !sealed && flyOpen(f.m, cy * W + cx);
|
||||
if (!f.free) {
|
||||
// still inside whatever the bot is flying through: pass until the first open cell
|
||||
// a blocked nozzle spills: the grain backs up into the nearest open space
|
||||
|
||||
+2
-2
@@ -245,7 +245,7 @@ function* worldSteps(seedIn, w, h) {
|
||||
yield [0.75, 'Settling loose ground'];
|
||||
// settle loose material at the water and sorting speeds the seeds were made with
|
||||
awake.fill(3);
|
||||
const lstep = LSTEP, lfilm = LFILM, sortp = SORTP; LSTEP = LFILM = 1; SORTP = 0.003;
|
||||
const lstep = LSTEP, lfilm = LFILM, sortp = SORTP, cornerSeal = CORNER_SEAL; LSTEP = LFILM = 1; SORTP = 0.003; CORNER_SEAL = false;
|
||||
for (let k = 0; k < 260; k++) {
|
||||
tick++; tickStamp = (tickStamp % 255) + 1;
|
||||
simMove();
|
||||
@@ -253,7 +253,7 @@ function* worldSteps(seedIn, w, h) {
|
||||
if (!any) break;
|
||||
if ((k & 31) === 0) yield [0.75 + 0.24 * k / 260, 'Settling loose ground'];
|
||||
}
|
||||
LSTEP = lstep; LFILM = lfilm; SORTP = sortp;
|
||||
LSTEP = lstep; LFILM = lfilm; SORTP = sortp; CORNER_SEAL = cornerSeal;
|
||||
yield [0.99, 'Finishing'];
|
||||
// re-ambient after settling, then start clean
|
||||
for (let i = 0; i < N; i++) { const m = mat[i]; if (m !== MAGMA) temp[i] = AMB[(i / w) | 0]; life[i] = PH[m] === PH_LIQUID && FRZ[m] ? 255 : 0; }
|
||||
|
||||
Reference in New Issue
Block a user