Sloped belts hold their load with moving cleats (t42); sloped filters are downhill shaking screens (t43)
The magic grip is gone: cleats every 8 face cells, 6 grains tall, carry pockets uphill (about 71 grains/s against 90 flat) and overflow rolls back. Sloped filters always run downhill; grains travel by gravity and a shake, and sorting stays exact. Drawing needs another pass. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -13,6 +13,7 @@ vec3 slopeCorner(vec2 p, vec2 a, float origin) {
|
||||
return vec3(radius - 1.85, origin + d.x, 2.0 + d.y);
|
||||
}
|
||||
vec3 slopeShape(vec2 p, vec2 worldOrigin, float grade, int joins) {
|
||||
if ((joins & 64) != 0) p.y -= 0.45;
|
||||
float sy = grade < 0.0 ? 4.0 : 0.0;
|
||||
vec2 a = vec2(-grade * 1.30814755, sy + 1.30814755), b = vec2(4.0 - grade * 1.30814755, 4.0 - sy + 1.30814755);
|
||||
if ((joins & 1) != 0) { a.y = sy + 2.0; a.x = (a.y - sy - 2.61629509) / grade; }
|
||||
@@ -52,11 +53,11 @@ const SM_SLOPE_DRAW = `
|
||||
vec2 local = floor(tag.gb * 255.0 + 0.5) - 8.0 + fract(w);
|
||||
vec3 shapePos = slopeShape(local, w - local, grade, joins);
|
||||
float sd = shapePos.x, axis = shapePos.y, depth = shapePos.z;
|
||||
float time = (joins & 16) != 0 ? uTime : 0.0;
|
||||
float time = !mesh && (joins & 16) != 0 ? uTime : 0.0;
|
||||
vec2 lb = vec2(axis, depth), alongWorld = vec2(axis, depth);
|
||||
float rg = step(0.72, fract((axis - dir * (depth < 2.0 ? 1.0 : -1.0) * time * 30.0) * 0.5));
|
||||
vec3 belt;
|
||||
if (-sd < 0.8) {
|
||||
if (-sd < (mesh ? 1.1 : 0.8)) {
|
||||
belt = bandColor(lb, rg);
|
||||
if (mesh && ((joins & 32) != 0) == (depth < 2.0) && dot(own.rgb, vec3(1)) > 0.01)
|
||||
belt = mix(belt, own.rgb * (depth < 2.0 ? 1.0 : 0.8), 0.75 * rg);
|
||||
|
||||
@@ -42,8 +42,8 @@ function prepareSlopeBelts(x0, y0, x1, y1) {
|
||||
if (c === BP_BELT || c === BP_FILTER) beltCaps[b] = flatBeltCaps(b);
|
||||
if (!isSlopeBelt(c)) continue;
|
||||
const face = beltFaceY(c, bx, by, bx * BS) * W + bx * BS;
|
||||
slopeBeltJoins[b] = slopeBeltConnections(bx, by, c) | (netSat(face) > 0 ? 16 : 0) | (filterCfg.get(b)?.inv ? 32 : 0);
|
||||
for (let yy = Math.max(0, by - 1); yy <= Math.min(BH - 1, by + 1); yy++)
|
||||
slopeBeltJoins[b] = slopeBeltConnections(bx, by, c) | (netSat(face) > 0 ? 16 : 0) | (filterCfg.get(b)?.inv ? 32 : 0) | (isFilter(c) && netSat(face) > 0 && screenLoaded(b) && (tick & 2) ? 64 : 0);
|
||||
for (let yy = Math.max(0, by - 2); yy <= Math.min(BH - 1, by + 1); yy++)
|
||||
for (let xx = Math.max(0, bx - 1); xx <= Math.min(BW - 1, bx + 1); xx++) slopeBeltHalo[yy * BW + xx] = 1;
|
||||
}
|
||||
}
|
||||
@@ -63,6 +63,7 @@ function slopeBeltCorner(x, y, ax, ay, origin) {
|
||||
function slopeBeltShape(x, y, b, joins = slopeBeltJoins[b], code = blockP[b]) {
|
||||
const grade = beltGrade(code), ox = (b % BW) * BS, oy = ((b / BW) | 0) * BS;
|
||||
x -= ox; y -= oy;
|
||||
if (isFilter(code) && (joins & 64)) y -= 0.45;
|
||||
const offset = 1.85 * Math.SQRT2, sy = grade < 0 ? 4 : 0;
|
||||
const normal = 1.85 * Math.SQRT1_2;
|
||||
let ax = -grade * normal, ay = sy + normal, bx = 4 - grade * normal, by = 4 - sy + normal;
|
||||
@@ -107,9 +108,9 @@ function slopeBeltColor(b, x, y, anim, br, bg, bb) {
|
||||
if (sd > 1e-8) return (br | 0) | ((bg | 0) << 8) | ((bb | 0) << 16);
|
||||
const c = blockP[b], joins = slopeBeltJoins[b], mesh = isFilter(c);
|
||||
const dir = mesh ? (blockV[b] & 128 ? 1 : -1) : (blockV[b] ? 1 : -1);
|
||||
const a = slopeAlong, d = slopeAcross, time = joins & 16 ? anim : 0;
|
||||
const a = slopeAlong, d = slopeAcross, time = !mesh && joins & 16 ? anim : 0;
|
||||
let r = 38, g = 41, blue = 46;
|
||||
if (-sd < 0.8) {
|
||||
if (-sd < (mesh ? 1.1 : 0.8)) {
|
||||
const stripe = (Math.floor((a - dir * (d < 2 ? 1 : -1) * (time >> 1)) / 2) & 1), k = d < 2 ? 1 : 0.72;
|
||||
r = (stripe ? 92 : 56) * k; g = (stripe ? 96 : 58) * k; blue = (stripe ? 104 : 66) * k;
|
||||
} else if (mesh) {
|
||||
@@ -125,3 +126,25 @@ function slopeBeltColor(b, x, y, anim, br, bg, bb) {
|
||||
}
|
||||
return (r | 0) | ((g | 0) << 8) | ((blue | 0) << 16);
|
||||
}
|
||||
|
||||
function screenLoaded(b) {
|
||||
const bx = b % BW, by = (b / BW) | 0, c = blockP[b];
|
||||
for (let x = bx * BS; x < bx * BS + BS; x++) {
|
||||
const i = (beltFaceY(c, bx, by, x) - 1) * W + x;
|
||||
if (i >= 0 && (PH[mat[i]] === PH_POWDER || occ[i])) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// Far sidewalls stay behind the load. The cleat raster is the simulation barrier raster.
|
||||
function slopeDetailAt(i, x, y) {
|
||||
if (!slopeBeltHalo[(y >> 2) * BW + (x >> 2)] && !cleatMask[i]) return 0;
|
||||
if (occ[i] || mach[i] || (mat[i] !== EMPTY && PH[mat[i]] !== PH_GAS) || part[i]) return 0;
|
||||
if (cleatMask[i]) return 1;
|
||||
for (let by = y >> 2; by <= Math.min(BH - 1, (y + 9) >> 2); by++) {
|
||||
const b = by * BW + (x >> 2), c = blockP[b];
|
||||
if (!isSlopeBelt(c)) continue;
|
||||
const depth = beltFaceY(c, x >> 2, by, x) - y;
|
||||
if (isFilter(c) ? depth === 2 : depth >= 6 && depth <= 7 + ((x + slopePhase[b]) & 1)) return isFilter(c) ? 3 : 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -289,6 +289,12 @@ function drawWorld() {
|
||||
const color = slopeBeltColor(sb, x, y, anim, br, bgc, bb);
|
||||
r = color & 255; g = color >> 8 & 255; b = color >> 16 & 255;
|
||||
}
|
||||
const slopeDetail = slopeDetailAt(i, x, y);
|
||||
if (slopeDetail) {
|
||||
r = slopeDetail === 1 ? 145 : slopeDetail === 3 ? 96 : 48;
|
||||
g = slopeDetail === 1 ? 125 : slopeDetail === 3 ? 106 : 52;
|
||||
b = slopeDetail === 1 ? 94 : slopeDetail === 3 ? 120 : 60;
|
||||
}
|
||||
// incandescence
|
||||
if (T > 450 && m !== EMPTY && incand) {
|
||||
const gi = glowIndex(PH[m] === PH_SOLID ? T + nz * 0.9 : m === MAGMA ? T + Math.sin(x * 0.19 + y * 0.11 + anim * 0.03 + nz * 0.04) * 55 - 30 : T), w = GLOW_W[gi];
|
||||
@@ -339,6 +345,7 @@ function drawWorld() {
|
||||
((y - ((sb / BW) | 0) * BS + 8) << 16) | ((x - (sb % BW) * BS + 8) << 8);
|
||||
if (slopeArt) { r = fm ? COLR[fm] : 0; g = fm ? COLG[fm] : 0; b = fm ? COLB[fm] : 0; }
|
||||
}
|
||||
if (slopeDetail) cl = 4;
|
||||
top = cl << 24;
|
||||
fpx[row + bx] = (tb ? 0xff000000 : 0) | (cl === 5 ? 0xff0000 : 0) | (cl === 3 ? 0xff00 : 0) | (cl === 1 && !builtForLight(i, x, y) ? 0xff : 0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user