Faces cut into loose piles collapse outward instead of draining column by column (t93)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+34
-2
@@ -77,11 +77,43 @@ const SORTP_FUEL = 0.003;
|
||||
// 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 and corner sealing off, so seeds keep the same world.
|
||||
let LSTEP = 8, LFILM = 4;
|
||||
let CORNER_SEAL = true;
|
||||
let CORNER_SEAL = true, POWDER_FAN = true;
|
||||
function powder(i, x, y, m, barriers = cleatChunks[(y >> 5) * CW + (x >> 5)]) {
|
||||
if (y >= H - 1) return;
|
||||
const b = i + W;
|
||||
if ((!barriers || (!cleatMask[i] && !cleatMask[b])) && enterFree(m, PH_POWDER, b, 0, 1)) { move(i, b, x, y, x, y + 1); return; }
|
||||
if ((!barriers || (!cleatMask[i] && !cleatMask[b])) && enterFree(m, PH_POWDER, b, 0, 1)) {
|
||||
// A falling face fans outward; dropping straight down keeps a packed column in its way.
|
||||
if (POWDER_FAN && mat[b] === EMPTY && !part[i] && !(flags[i] & F_BURN) && x > 0 && x < W - 1) {
|
||||
const dx = mat[i - 1] === EMPTY && PH[mat[i + 1]] === PH_POWDER ? -1 :
|
||||
mat[i + 1] === EMPTY && PH[mat[i - 1]] === PH_POWDER ? 1 : 0;
|
||||
if (dx && y > 0 && PH[mat[i - W]] === PH_POWDER && mat[i - W + dx] === EMPTY &&
|
||||
PH[mat[b - dx]] === PH_POWDER) {
|
||||
// Deep faces spill across the falling column, within the eight-grain worker halo.
|
||||
let depth = 0;
|
||||
while (depth < 12 && y >= depth && PH[mat[i - dx - W * depth]] === PH_POWDER) depth++;
|
||||
let reach = 0;
|
||||
for (let step = 1; step <= (depth === 12 && stamp[b - dx] !== tickStamp ? 8 : 1); step++) {
|
||||
const nx = x + dx * step, side = i + dx * step, j = side + W;
|
||||
if (nx < 0 || nx >= W || mat[side] !== EMPTY || part[side] ||
|
||||
cleatMask[side] || !passable(m, PH_POWDER, side, dx, 0)) break;
|
||||
if (mat[j] === EMPTY && !part[j] && !cleatMask[j] &&
|
||||
passable(m, PH_POWDER, j, dx, 1)) reach = step;
|
||||
}
|
||||
if (reach) {
|
||||
let drop = 1;
|
||||
if (depth === 12 && stamp[b - dx] !== tickStamp) {
|
||||
for (let step = 2; step <= 8 && y + step < H; step++) {
|
||||
const j = i + W * step + dx * reach;
|
||||
if (mat[j] !== EMPTY || part[j] || cleatMask[j] || !passable(m, PH_POWDER, j, 0, 1)) break;
|
||||
drop = step;
|
||||
}
|
||||
}
|
||||
move(i, i + W * drop + dx * reach, x, y, x + dx * reach, y + drop); return;
|
||||
}
|
||||
}
|
||||
}
|
||||
move(i, b, x, y, x, y + 1); return;
|
||||
}
|
||||
// a grain at least twice as dense works its way down through a loose pile. Unlit fuel
|
||||
// packs too tight for that, so a mixed furnace charge stays mixed until the fire gets in.
|
||||
const t = mat[b];
|
||||
|
||||
+2
-2
@@ -86,11 +86,11 @@ function chunkPasses(heat) {
|
||||
}
|
||||
}
|
||||
function threadParams() {
|
||||
return { tick,tickStamp,worldSeed,LSTEP,LFILM,SORTP,CORNER_SEAL,
|
||||
return { tick,tickStamp,worldSeed,LSTEP,LFILM,SORTP,CORNER_SEAL,POWDER_FAN,
|
||||
seen, bot: {...bot}, skyY: weather.skyY, barriers: !!cleatCells.length, filterCfg };
|
||||
}
|
||||
function threadSetParams(s) {
|
||||
({tick,tickStamp,worldSeed,LSTEP,LFILM,SORTP,CORNER_SEAL,filterCfg} = s);
|
||||
({tick,tickStamp,worldSeed,LSTEP,LFILM,SORTP,CORNER_SEAL,POWDER_FAN,filterCfg} = s);
|
||||
seen.set(s.seen); Object.assign(bot, s.bot);
|
||||
weather.skyY = s.skyY; cleatCells = s.barriers ? [1] : [];
|
||||
}
|
||||
|
||||
+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, cornerSeal = CORNER_SEAL; LSTEP = LFILM = 1; SORTP = 0.003; CORNER_SEAL = false;
|
||||
const lstep = LSTEP, lfilm = LFILM, sortp = SORTP, cornerSeal = CORNER_SEAL, powderFan = POWDER_FAN; LSTEP = LFILM = 1; SORTP = 0.003; CORNER_SEAL = POWDER_FAN = 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; CORNER_SEAL = cornerSeal;
|
||||
LSTEP = lstep; LFILM = lfilm; SORTP = sortp; CORNER_SEAL = cornerSeal; POWDER_FAN = powderFan;
|
||||
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