Diagonal tubes as thick as straight ones, with centred elbows where they join (t35)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+25
-8
@@ -112,6 +112,7 @@ function drawPreviews() {
|
||||
if (dd !== GAME.dragDir) { GAME.dragDir = dd; hudDirty = true; }
|
||||
const dIdx = dd >= 0 ? dd : (GAME.pieceDir[P.id] || 0);
|
||||
const afford = canAfford(pieceCostNow(P), cells.length);
|
||||
const planned = code === BP_TUBE && dIdx >= 4 ? new Map(cells.map(([x, y]) => [y * BW + x, [BP_TUBE, dIdx]])) : null;
|
||||
for (const [bx, by] of cells) {
|
||||
const err = canPlaceBlock(bx, by, code), rb = by * BW + bx;
|
||||
const swap = GAME.replace && !!blockP[rb] && /already built/.test(err) && !blockIs(rb, code, v, pieceExtra(P));
|
||||
@@ -119,10 +120,10 @@ function drawPreviews() {
|
||||
const ok = (!err || swap) && !ghost && afford;
|
||||
const [x, y, w, h] = blockRectPx(bx, by, 1, 1);
|
||||
ctx.fillStyle = ghost ? 'rgba(90,190,230,0.22)' : ok ? (swap ? 'rgba(255,190,90,0.5)' : `rgba(${col},0.55)`) : 'rgba(239,106,85,0.35)';
|
||||
previewBlock(code, x, y, w, h, false, P.id === 'tube' ? dIdx : -1);
|
||||
previewBlock(code, x, y, w, h, false, P.id === 'tube' ? dIdx : -1, bx, by, planned);
|
||||
ctx.strokeStyle = ghost ? 'rgba(90,190,230,0.8)' : ok ? 'rgba(236,226,210,0.8)' : 'rgba(239,106,85,0.9)'; ctx.lineWidth = Math.max(1, zp * 0.25);
|
||||
if (ghost) ctx.setLineDash([zp, zp * 0.7]);
|
||||
previewBlock(code, x, y, w, h, true, P.id === 'tube' ? dIdx : -1); ctx.setLineDash([]);
|
||||
previewBlock(code, x, y, w, h, true, P.id === 'tube' ? dIdx : -1, bx, by, planned); ctx.setLineDash([]);
|
||||
if (P.dirs && (P.id === 'belt' || P.id === 'tube' || P.filter || P.id === 'pump' || P.id === 'outlet')) {
|
||||
// a chevron on every block, pointing the way it will carry (or pump, or pour)
|
||||
const [dx, dy] = P.id === 'tube' ? TUBE_DIRS[dIdx] : P.id === 'pump' ? PUMP_V[dIdx] : P.id === 'outlet' ? OUTLET_V[dIdx] : [[-1, 0], [1, 0]][dIdx];
|
||||
@@ -179,14 +180,30 @@ function drawPreviews() {
|
||||
drawCursorLabel(p.x, p.y, t === 'vacuum' ? GAME.brush[GAME.tool] : t === 'ignite' || t === 'drill' ? 1 : 2);
|
||||
}
|
||||
|
||||
function previewBlock(code, x, y, w, h, stroke = false, direction = -1) {
|
||||
function previewBlock(code, x, y, w, h, stroke = false, direction = -1, bx = -1, by = -1, planned = null) {
|
||||
const ctx = R.ctx;
|
||||
if (code === BP_TUBE && direction >= 4) {
|
||||
const rising = direction === 4 || direction === 6;
|
||||
ctx.save(); ctx.translate(x + w / 2, y + h / 2); ctx.rotate(rising ? -Math.PI / 4 : Math.PI / 4);
|
||||
const length = w * Math.SQRT2, width = w * 0.75;
|
||||
if (stroke) ctx.strokeRect(-length / 2, -width / 2, length, width);
|
||||
else ctx.fillRect(-length / 2, -width / 2, length, width);
|
||||
const joins = bx >= 0 ? diagonalTubeJoins(bx, by, direction, planned) : 0;
|
||||
const points = [];
|
||||
for (let end = 0; end < 2; end++) {
|
||||
const join = (joins >> (end * 3)) & 7, side = end ? 1 : -1;
|
||||
const d = join ? TUBE_DIRS[join - 1] : [side, side * (direction === 4 || direction === 6 ? -1 : 1)];
|
||||
points.push([d[0] * w / 2, d[1] * h / 2]);
|
||||
}
|
||||
const r = w / 2, a = points[0], b = points[1];
|
||||
const al = Math.hypot(...a), bl = Math.hypot(...b);
|
||||
const n0 = [a[1] / al, -a[0] / al], n1 = [-b[1] / bl, b[0] / bl];
|
||||
const turn = n0[0] * n1[1] - n0[1] * n1[0], dot = n0[0] * n1[0] + n0[1] * n1[1];
|
||||
ctx.save(); ctx.translate(x + w / 2, y + h / 2); ctx.beginPath();
|
||||
ctx.moveTo(a[0] + n0[0] * r, a[1] + n0[1] * r);
|
||||
if (turn >= 0) ctx.lineTo((n0[0] + n1[0]) * r / (1 + dot), (n0[1] + n1[1]) * r / (1 + dot));
|
||||
else ctx.arc(0, 0, r, Math.atan2(n0[1], n0[0]), Math.atan2(n1[1], n1[0]), true);
|
||||
ctx.lineTo(b[0] + n1[0] * r, b[1] + n1[1] * r);
|
||||
ctx.lineTo(b[0] - n1[0] * r, b[1] - n1[1] * r);
|
||||
if (turn <= 0) ctx.lineTo(-(n0[0] + n1[0]) * r / (1 + dot), -(n0[1] + n1[1]) * r / (1 + dot));
|
||||
else ctx.arc(0, 0, r, Math.atan2(-n1[1], -n1[0]), Math.atan2(-n0[1], -n0[0]), true);
|
||||
ctx.lineTo(a[0] - n0[0] * r, a[1] - n0[1] * r); ctx.closePath();
|
||||
if (stroke) ctx.stroke(); else ctx.fill();
|
||||
ctx.restore(); return;
|
||||
}
|
||||
if (!isSlope(code)) { if (stroke) ctx.strokeRect(x, y, w, h); else ctx.fillRect(x, y, w, h); return; }
|
||||
|
||||
Reference in New Issue
Block a user