Belts: a backed-up heap stands still instead of the top sliding over the bottom

carryColumn stops at the first blocked grain on a belt, so a heap whose front
is backed up (a screw tube taking less than the belt brings, or a wall) no
longer shears. New t_conveyors checks and a belt-heap screenshot scene.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-23 19:07:28 -04:00
co-authored by Claude Opus 5.5
parent de677b49c5
commit caa2463fda
6 changed files with 77 additions and 9 deletions
+8 -3
View File
@@ -1,10 +1,11 @@
// How belts, filters and screw tubes move what is on or in them.
// What rests on a belt or filter rides along: the whole stack standing on the carrying surface
// steps one cell toward d together (belts run front of the line first, so the way ahead is
// clear), the way a real belt carries a heap, not just its bottom layer. A filter's own
// material drops through it instead, unless the filter below is already full.
// clear). If a powder grain is blocked, the load above it stands still and the belt slips
// underneath. A filter's own material drops through it instead, unless it is already full.
const CARRY_DEPTH = 96;
function carryColumn(a, d, pass) {
let blocked = false;
for (let L = 0; L < CARRY_DEPTH; L++, a -= W) {
if (a < 0) return;
const m = mat[a];
@@ -16,12 +17,16 @@ function carryColumn(a, d, pass) {
const u = mat[a + W];
if (L > 0 && !pass[u] && PH[u] === PH_POWDER && stamp[a + W] !== tickStamp && !occ[a + W] && rnd() < 0.5) { const x = a % W, y = (a / W) | 0; move(a, a + W, x, y, x, y + 1); continue; }
}
if (blocked) continue; // filters still sift above a stopped load
const x = a % W, nx = x + d;
if (nx < 0 || nx >= W) return;
const j = a + d, tj = mat[j];
// grains on a wet belt push through the water rather than stopping at it
const wet = PH[tj] === PH_LIQUID && !occ[j] && stamp[j] !== tickStamp && (!part[j] || part[j] === P_FILTER || part[j] === P_GOPEN);
if (!wet && !enter(m, PH_POWDER, j, d, 0)) continue;
if (!wet && !enter(m, PH_POWDER, j, d, 0)) {
if (!pass) return;
blocked = true; continue;
}
const y = (a / W) | 0, bj = j + W;
// carried off the end with nothing under it: it leaves at belt speed and falls
if (mat[j] === EMPTY && !part[j] && bj < N && (mat[bj] === EMPTY || PH[mat[bj]] === PH_GAS) && !occ[bj] && !part[bj]) launchGrain(a, nx, y, d * 0.5, 0);