Corner placements of screw conveyors stay separate ends (t62 follow-up)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,7 @@ for (let p = P_SCREW_UR; p <= P_SCREW_UL; p++) SCREW_CLASS[p] = 19 + p - P_SCREW
|
||||
// Drawing only: the four transport lanes remain in the square block.
|
||||
let diagonalJoins = new Uint8Array(0);
|
||||
function diagonalScrewJoins(bx, by, v, planned = null) {
|
||||
// Three bits per end: 1..4 edge exits, 5/6 corner horizontal/vertical; bits 6/7 are collars.
|
||||
// Three bits per end: 1..4 edge exits; bits 6/7 are collars.
|
||||
const dy = v === 4 || v === 6 ? -1 : 1;
|
||||
let joins = 0;
|
||||
for (let end = 0; end < 2; end++) {
|
||||
@@ -23,7 +23,6 @@ function diagonalScrewJoins(bx, by, v, planned = null) {
|
||||
if ((code === BP_SCREW && nv < 4 && (nv & 1) === (dir & 1)) ||
|
||||
((code === BP_BELT || code === BP_FILTER) && (dir & 1))) { join = dir + 1; break; }
|
||||
}
|
||||
if (!join && nx >= 0 && ny >= 0 && nx < BW && ny < BH && nc === BP_SCREW && nv < 4) join = nv & 1 ? 5 : 6;
|
||||
joins |= join << (end * 3);
|
||||
if (!join) joins |= 64 << end;
|
||||
}
|
||||
@@ -37,15 +36,10 @@ function diagonalScrewShape(x, y, b, v, joins) {
|
||||
for (let end = 0; end < 2; end++) {
|
||||
const join = (joins >> (end * 3)) & 7, side = end ? 1 : -1;
|
||||
const slope = v === 4 || v === 6 ? -1 : 1;
|
||||
const dx = join >= 5 ? (join === 5 ? side : 0) : join ? SCREW_DIRS[join - 1][0] : side * Math.SQRT1_2;
|
||||
const dy = join >= 5 ? (join === 6 ? side * slope : 0) : join ? SCREW_DIRS[join - 1][1] : side * slope * Math.SQRT1_2;
|
||||
const ox = join === 6 ? side * BS : 0, oy = join === 5 ? side * slope * BS : 0;
|
||||
const along = (lx - ox) * dx + (ly - oy) * dy, across = -(lx - ox) * dy + (ly - oy) * dx;
|
||||
let radius = Math.hypot(across, Math.min(0, along));
|
||||
if (join >= 5) {
|
||||
const t = Math.max(0, Math.min(1, (lx * ox + ly * oy) / (BS * BS)));
|
||||
radius = Math.min(radius, Math.hypot(lx - ox * t, ly - oy * t));
|
||||
}
|
||||
const dx = join ? SCREW_DIRS[join - 1][0] : side * Math.SQRT1_2;
|
||||
const dy = join ? SCREW_DIRS[join - 1][1] : side * slope * Math.SQRT1_2;
|
||||
const along = lx * dx + ly * dy, across = -lx * dy + ly * dx;
|
||||
const radius = Math.hypot(across, Math.min(0, along));
|
||||
const cap = along - (join ? 2 : 2 * Math.SQRT2);
|
||||
const sd = Math.max(radius - 2, join || (joins & (64 << end)) ? cap : -10);
|
||||
if (sd < best) {
|
||||
|
||||
@@ -265,12 +265,9 @@ ${SM_SLOPE_DRAW}
|
||||
int join = (joins >> (end * 3)) & 7;
|
||||
float side = end == 0 ? -1.0 : 1.0;
|
||||
vec2 ray = join == 0 ? vec2(side, side * (nc == 19 || nc == 21 ? -1.0 : 1.0)) * 0.70710678 :
|
||||
join == 5 ? vec2(side, 0) : join == 6 ? vec2(0, side * d.y) :
|
||||
join == 1 ? vec2(0, -1) : join == 2 ? vec2(1, 0) : join == 3 ? vec2(0, 1) : vec2(-1, 0);
|
||||
vec2 offset = join == 5 ? vec2(0, side * d.y * 4.0) : join == 6 ? vec2(side * 4.0, 0) : vec2(0);
|
||||
float t = dot(local - offset, ray), cross2 = dot(local - offset, vec2(-ray.y, ray.x));
|
||||
float t = dot(local, ray), cross2 = dot(local, vec2(-ray.y, ray.x));
|
||||
float radius = length(vec2(cross2, min(0.0, t))), cap = t - (join == 0 ? 2.82842712 : 2.0);
|
||||
if (join >= 5) radius = min(radius, length(local - offset * clamp(dot(local, offset) / 16.0, 0.0, 1.0)));
|
||||
// A connected mouth meets another opaque pipe; fading its edge leaves a seam.
|
||||
float sd = max(radius - 2.0, (joins & (64 << end)) != 0 ? cap : -10.0);
|
||||
if (sd < screwSD) {
|
||||
|
||||
+6
-16
@@ -176,20 +176,6 @@ function screwIntake(i, p, dx, dy) {
|
||||
}
|
||||
}
|
||||
|
||||
// A straight mouth can feed a diagonal tail one block across the corner.
|
||||
function straightScrewNext(i, p) {
|
||||
const dx = SCREW_DX[p], dy = SCREW_DY[p], x = i % W, y = (i / W) | 0;
|
||||
const xx = x + dx, yy = y + dy, next = i + dx + dy * W;
|
||||
if (xx < 0 || yy < 0 || xx >= W || yy >= H) return -1;
|
||||
if (((xx >> 2) === (x >> 2) && (yy >> 2) === (y >> 2)) || part[next] || blockP[(yy >> 2) * BW + (xx >> 2)]) return next;
|
||||
for (let side = -1; side <= 1; side += 2) {
|
||||
const nx = xx + (dx ? 0 : side * BS), ny = yy + (dy ? 0 : side * BS);
|
||||
if (nx < 0 || ny < 0 || nx >= W || ny >= H) continue;
|
||||
const j = ny * W + nx, q = part[j];
|
||||
if (SCREW_DX[q] === (dx || side) && SCREW_DY[q] === (dy || side)) return j;
|
||||
}
|
||||
return next;
|
||||
}
|
||||
// Four lanes cross a block in four beats; the casing carries every lane across the corner.
|
||||
// Prefer the next diagonal block, then either straight join, then the open head.
|
||||
function diagonalScrewNext(i, p) {
|
||||
@@ -198,11 +184,15 @@ function diagonalScrewNext(i, p) {
|
||||
if (xx < 0 || xx >= W) return -1;
|
||||
if ((xx >> 2) === (x >> 2)) return i + dx;
|
||||
const yy = y + dy * BS;
|
||||
if (yy >= 0 && yy < H && IS_SCREW[part[yy * W + xx]]) return yy * W + xx;
|
||||
if (yy >= 0 && yy < H) {
|
||||
const q = part[yy * W + xx];
|
||||
if (q >= P_SCREW_UR && q <= P_SCREW_UL && SCREW_DX[q] === dx && SCREW_DY[q] === dy) return yy * W + xx;
|
||||
}
|
||||
if (IS_SCREW[part[y * W + xx]]) return y * W + xx;
|
||||
if (dy > 0 && yy < H && (mat[yy * W + xx] === BELTL || mat[yy * W + xx] === BELTR)) return ((yy & ~3) - 1) * W + xx;
|
||||
const hy = by + (dy > 0 ? BS : -1), hx = bx + (y & 3);
|
||||
if (hy >= 0 && hy < H && IS_SCREW[part[hy * W + hx]]) return hy * W + hx;
|
||||
// An open mouth discharges along the diagonal, clear of the last block.
|
||||
return yy >= 0 && yy < H ? yy * W + xx : -1;
|
||||
// A corner screw is a separate end, not an open discharge cell.
|
||||
return yy >= 0 && yy < H && !IS_SCREW[part[yy * W + xx]] ? yy * W + xx : -1;
|
||||
}
|
||||
|
||||
+1
-8
@@ -90,13 +90,6 @@ function entScrewTick(e, p) {
|
||||
if ((tick & 1) || netSat(ci) <= 0 || rnd() > netSat(ci)) return;
|
||||
const dx = SCREW_DX[p], dy = SCREW_DY[p];
|
||||
if (dx && dy) { entDiagonalScrewTick(e, p); return; }
|
||||
const edge = entScrewEdge(e, dx, dy, 0), behind = edge - dx - dy * W;
|
||||
const corner = edge >= 0 ? straightScrewNext(behind, p) : -1;
|
||||
if (corner >= 0 && corner !== edge) {
|
||||
const x = (corner % W) & ~3, y = entScrewLane((corner / W) | 0, e.iy);
|
||||
if (entScrewMove(e, x, y, true)) stats.moved++;
|
||||
return;
|
||||
}
|
||||
let x = e.ix + dx, y = e.iy + dy, next = 0, ax = 0, ay = 0;
|
||||
for (let k = 0; k < (dx ? BAR_H : BAR_W); k++) {
|
||||
const i = entScrewEdge(e, dx, dy, k);
|
||||
@@ -124,7 +117,7 @@ function entDiagonalScrewTick(e, p) {
|
||||
const dx = SCREW_DX[p], dy = SCREW_DY[p], bx = e.ix & ~3, by = e.iy & ~3, lane = e.iy & 3;
|
||||
for (const [ox, oy] of [[dx, dy], [dx, 0], [0, dy]]) {
|
||||
const x = bx + ox * BS, y = by + oy * BS + lane, q = entScrewAt(x, y);
|
||||
if (!q) continue;
|
||||
if (!q || (ox && oy && (q < P_SCREW_UR || q > P_SCREW_UL || SCREW_DX[q] !== dx || SCREW_DY[q] !== dy))) continue;
|
||||
if (SCREW_DX[q] * dx + SCREW_DY[q] * dy < 0) return;
|
||||
if (entScrewMove(e, x, y, true)) stats.moved++;
|
||||
return;
|
||||
|
||||
@@ -130,7 +130,7 @@ function machinesTick() {
|
||||
if (shifted) continue;
|
||||
}
|
||||
if (x + dx < 0 || x + dx >= W || y + dy < 0 || y + dy >= H) continue;
|
||||
const dest = dx && dy ? diagonalScrewNext(i, p) : straightScrewNext(i, p);
|
||||
const dest = dx && dy ? diagonalScrewNext(i, p) : i + dj;
|
||||
if (dest < 0) continue;
|
||||
const nx = dest % W, ny = (dest / W) | 0;
|
||||
if (nx < 0 || ny < 0 || nx >= W || ny >= H) continue;
|
||||
|
||||
Reference in New Issue
Block a user