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:
+23
-2
@@ -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; }
|
||||
|
||||
Reference in New Issue
Block a user