Downhill sloped belts draw as plain belts, ghosts and previews too

Downhill runs have no cleats, so they no longer draw the sidewall or
ribs either: placed, as ghosts, or in the drag preview, which now knows
the belt's direction. Uphill runs keep the wall and ribs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-26 22:46:34 -04:00
co-authored by Claude Opus 5.5
parent 2e5ad0f1a1
commit be93ad1251
9 changed files with 32 additions and 15 deletions
+1 -1
View File
@@ -107,7 +107,7 @@ function carryBeltsAndFilters(belts, filters, d, bm, carrying) {
if (carrying) {
if (PH[above] === PH_LIQUID) beltDrain(b);
// uphill, the cleats do the carrying
if (!isSlopeBelt(code) || !slopeUphill(code, (y >> 2) * BW + (x >> 2))) carryColumn(b - W, d, null);
if (!isSlopeBelt(code) || !slopeUphill(code, blockV[(y >> 2) * BW + (x >> 2)])) carryColumn(b - W, d, null);
}
}
}
+4 -4
View File
@@ -27,7 +27,7 @@ function ribCells(x, y, g) {
}
return out;
}
function slopeUphill(c, b) { return beltGrade(c) * (blockV[b] & 1 ? 1 : -1) < 0; }
function slopeUphill(c, v) { return beltGrade(c) * (v & 1 ? 1 : -1) < 0; } // v: the belt's direction
// Is (x, y) a face cell of a sloped belt with grade g?
function slopeFaceAt(x, y, g) {
if (x < 0 || x >= W || y < 0 || y >= H) return false;
@@ -143,7 +143,7 @@ function slopeCleatsTick(advance = true) {
const runs = new Map();
for (const list of [beltR, beltL]) for (const i of list) {
const x = i % W, y = (i / W) | 0, b = (y >> 2) * BW + (x >> 2), c = blockP[b];
if (!isBelt(c) || !isSlopeBelt(c) || !slopeUphill(c, b) || beltFaceY(c, x >> 2, y >> 2, x) !== y || netSat(i) <= 0) continue;
if (!isBelt(c) || !isSlopeBelt(c) || !slopeUphill(c, blockV[b]) || beltFaceY(c, x >> 2, y >> 2, x) !== y || netSat(i) <= 0) continue;
// lift the run's ribs off; each is put back where it moves to, and a rib leaving the top is gone
if (cleatFoot(x, b)) for (const j of ribCells(x, y, beltGrade(c))) if (j >= 0) cleatMask[j] = 0;
if (!cleatFoot(x, b, (slopePhase[b] + 1) % CLEAT_SPACING)) continue;
@@ -172,7 +172,7 @@ function slopeCleatsTick(advance = true) {
// they slide back down between steps, which on 45° is faster than the belt runs
for (const list of [beltR, beltL]) for (const i of list) {
const x = i % W, y = (i / W) | 0, b = (y >> 2) * BW + (x >> 2), c = blockP[b], a = i - W;
if (!isBelt(c) || !isSlopeBelt(c) || !slopeUphill(c, b) || beltFaceY(c, x >> 2, y >> 2, x) !== y || netSat(i) <= 0) continue;
if (!isBelt(c) || !isSlopeBelt(c) || !slopeUphill(c, blockV[b]) || beltFaceY(c, x >> 2, y >> 2, x) !== y || netSat(i) <= 0) continue;
if (a < 0 || PH[mat[a]] !== PH_POWDER || occ[a] || cleatMask[a] || stamp[a] === tickStamp) continue;
const d = blockV[b] & 1 ? 1 : -1, st = conveyorStep(x, y, d), j = a + d + st * W;
if (x + d < 0 || x + d >= W || j < 0 || cleatMask[j] || !passable(mat[a], PH_POWDER, j, d, st)) continue;
@@ -190,7 +190,7 @@ function rebuildCleatMask() {
cleatCells.length = 0;
for (const list of [beltR, beltL]) for (const i of list) {
const x = i % W, y = (i / W) | 0, b = (y >> 2) * BW + (x >> 2), c = blockP[b];
if (!isBelt(c) || !isSlopeBelt(c) || !slopeUphill(c, b) || beltFaceY(c, x >> 2, y >> 2, x) !== y || !cleatFoot(x, b)) continue;
if (!isBelt(c) || !isSlopeBelt(c) || !slopeUphill(c, blockV[b]) || beltFaceY(c, x >> 2, y >> 2, x) !== y || !cleatFoot(x, b)) continue;
for (const j of ribCells(x, y, beltGrade(c))) if (j >= 0) cleatCells.push(j);
}
for (const i of cleatCells) {