Shared drag placement; drags snap one block to join a diagonal (t67 phases 3-4)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -71,3 +71,35 @@ function endJoin(bx, by, endIndex, planned = null) {
|
||||
function pieceJoins(bx, by, planned = null) {
|
||||
return (endJoin(bx, by, 0, planned) >= 0 ? 1 : 0) | (endJoin(bx, by, 1, planned) >= 0 ? 2 : 0);
|
||||
}
|
||||
function endAt(b, end, planned = null) {
|
||||
const p = planned && planned.get(b);
|
||||
return pieceEnds(p ? p[0] : blockP[b], p ? p[1] : blockV[b])[end];
|
||||
}
|
||||
// A same-row join into a sloped belt's low end: the flat surface is level with the top of the
|
||||
// slope's first block, so grains drop about 3 grains onto its face. Joined, but not seamless.
|
||||
function joinIsDrop(bx, by, end, join, planned = null) {
|
||||
if (join < 0 || (((join >> 1) / BW) | 0) !== by) return false;
|
||||
const low = e => !!e && e.kind === 'belt-sloped' && e.dy > 0;
|
||||
return low(endAt(by * BW + bx, end, planned)) || low(endAt(join >> 1, join & 1, planned));
|
||||
}
|
||||
// Rows to move a line so its first block joins: 0, -1 or +1. A line that already joins stays
|
||||
// put; it moves only when one block up or down gives a seamless join involving a diagonal piece
|
||||
// and every block there is free, so straight lines beside straight lines never jump.
|
||||
function joinSnap(code, v, cells) {
|
||||
if (!cells.length) return 0;
|
||||
const joins = dy => {
|
||||
const plan = new Map(cells.map(([x, y]) => [(y + dy) * BW + x, [code, v]]));
|
||||
const x = cells[0][0], y = cells[0][1] + dy, own = pieceEnds(code, v);
|
||||
for (let end = 0; end < own.length; end++) {
|
||||
const j = endJoin(x, y, end, plan);
|
||||
if (j < 0 || plan.has(j >> 1) || joinIsDrop(x, y, end, j, plan)) continue;
|
||||
return own[end].diagonal || endAt(j >> 1, j & 1, plan).diagonal ? 2 : 1;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
if (!pieceEnds(code, v).length || joins(0)) return 0;
|
||||
for (const dy of [-1, 1]) {
|
||||
if (cells.every(([x, y]) => canPlaceBlock(x, y + dy, code) === '') && joins(dy) === 2) return dy;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user