Bars snap to a 2-grain grid and tip into gaps, so piles stack without air (t1)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-24 19:41:04 -04:00
co-authored by Claude Opus 5.5
parent d2eb388729
commit f34c34aa73
3 changed files with 67 additions and 4 deletions
+23 -2
View File
@@ -6,6 +6,12 @@
const BAR_W = 4, BAR_H = 2;
let entCurM = 0; // the bar being moved, so a filter can let its own kind of bar through
function entSolidCell(j) { const m = mat[j], p = part[j]; return occ[j] || PH[m] === PH_SOLID || PH[m] === PH_POWDER || (p !== 0 && (p <= P_GRATE || (p === P_FILTER && !filterPassAt(entCurM, j)))); }
function entSupportCount(x, y) {
if (y + BAR_H >= H) return BAR_W;
let n = 0;
for (let dx = 0; dx < BAR_W; dx++) if (entSolidCell((y + BAR_H) * W + x + dx)) n++;
return n;
}
function entFreeAt(x, y) {
if (x < 0 || y < 0 || x + BAR_W > W || y + BAR_H > H) return false;
for (let dy = 0; dy < BAR_H; dy++) for (let dx = 0; dx < BAR_W; dx++) if (entSolidCell((y + dy) * W + x + dx)) return false;
@@ -97,22 +103,37 @@ function entTick() {
const e = ents[k];
entMark(e, 0);
entCurM = e.m;
const ix = e.ix, iy = e.iy;
let ix = e.ix; const iy = e.iy;
const tube = entTubeAt(ix, iy);
if (tube) entTubeTick(e, tube);
else {
// what is underneath?
let belt = 0, bsat = 0, support = iy + BAR_H >= H;
let belt = 0, bsat = 0, transport = false, support = iy + BAR_H >= H;
if (!support) {
const yb = iy + BAR_H;
for (let dx = 0; dx < BAR_W; dx++) {
const x = ix + dx; if (x < 0 || x >= W) continue;
const j = yb * W + x, m = mat[j];
if (m === BELTL || m === BELTR || part[j] === P_FILTER) transport = true;
if (m === BELTL || m === BELTR) { const s = netSat(j); if (s > bsat) { bsat = s; belt = m === BELTR ? 1 : -1; } }
else if (part[j] === P_FILTER && !filterPassAt(e.m, j) && (yb & 3) === 0) { bsat = 1; belt = blockV[(yb >> 2) * BW + (x >> 2)] & 128 ? 1 : -1; }
if (entSolidCell(j)) support = true;
}
}
if (support && !transport && e.vy === 0 && Math.abs(e.vx) < 0.05) {
const n = entSupportCount(ix, iy);
if (n < 2) {
let left = 0, right = 0;
for (let dx = 0; dx < BAR_W; dx++) if (!entSolidCell((iy + BAR_H) * W + ix + dx)) {
if (dx < BAR_W / 2) left++; else right++;
}
const dir = left > right ? -1 : right > left ? 1 : ((ix + iy) & 1) ? 1 : -1;
if (entFreeAt(ix + dir, iy)) ix += dir;
} else if (ix & 1) {
for (let dir = -1; dir <= 1; dir += 2) if (entFreeAt(ix + dir, iy) && entSupportCount(ix + dir, iy) >= 2) { ix += dir; break; }
}
if (ix !== e.ix) { e.x = e.ix = ix; support = entSupportCount(ix, iy) > 0; }
}
const ci = Math.min(H - 1, iy + 1) * W + Math.min(W - 1, ix + 1);
const inLiq = PH[mat[ci]] === PH_LIQUID;
if (support) { if (e.vy > 0) e.vy = 0; e.vx = belt ? belt * 0.5 * bsat : e.vx * 0.55; }