Player text says Screw conveyor; code uses screw (BP_SCREW, piece id screw, screwIntake...). No compatibility code for old saves or blueprints. Suite outputs match before and after apart from names. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
101 lines
4.7 KiB
JavaScript
101 lines
4.7 KiB
JavaScript
// Drawing geometry against real parts, without changing transport.
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const { load, suite, flatWorld } = require('./harness');
|
|
const { run } = load();
|
|
const { check, done } = suite();
|
|
run(fs.readFileSync(path.join(__dirname, '../src/render/slope-belts.js'), 'utf8'));
|
|
flatWorld(run, 160, 120, 112);
|
|
for (const code of ['BP_BELT_UP', 'BP_BELT_DOWN', 'BP_FILTER_UP', 'BP_FILTER_DOWN']) {
|
|
run(`
|
|
mat.fill(EMPTY); part.fill(0); blockP.fill(0); blockV.fill(0);
|
|
var artCode = ${code}, artGrade = beltGrade(artCode), artB = 12 * BW + 12;
|
|
for (let k = -2; k <= 2; k++) placeBlock(artCode, 1, 12 + k, 12 + artGrade * k, true);
|
|
prepareSlopeBelts(0, 0, W, H);
|
|
`);
|
|
check(`${code}: diagonal neighbours continue the band`, run('(slopeBeltJoins[artB] & 12) === 12'));
|
|
check(`${code}: corner seals use the same band`, run(`(() => {
|
|
const i = slopeSeal(artCode, 12, 12);
|
|
return i < 0 || slopeBeltAt(i, i % W, (i / W) | 0) >= 0;
|
|
})()`));
|
|
check(`${code}: band is as thick as a flat belt`, run(`(() => {
|
|
const g = artGrade, x = 50 - g * 1.85 * Math.SQRT1_2, y = 50 + 1.85 * Math.SQRT1_2;
|
|
return slopeBeltShape(x, y, artB) < -1.8 &&
|
|
slopeBeltShape(x - g * 1.7 * Math.SQRT1_2, y + 1.7 * Math.SQRT1_2, artB) < 0 &&
|
|
slopeBeltShape(x - g * 2.1 * Math.SQRT1_2, y + 2.1 * Math.SQRT1_2, artB) > 0;
|
|
})()`));
|
|
check(`${code}: air below the triangle gets the continuous band`, run(`(() => {
|
|
for (let y = 48; y < 57; y++) for (let x = 48; x < 56; x++) {
|
|
const i = y * W + x, own = (y >> 2) * BW + (x >> 2);
|
|
if (!blockP[own] && mat[i] === EMPTY && slopeBeltAt(i, x, y) >= 0) return true;
|
|
}
|
|
return false;
|
|
})()`));
|
|
run(`
|
|
for (let end = 0; end < 2; end++) {
|
|
const side = end ? 1 : -1;
|
|
removeBlock(12 + side, 12 + side * artGrade, true);
|
|
placeBlock(BP_BELT, 1, 12 + side, 12 + (end ? artGrade > 0 : artGrade < 0), true);
|
|
}
|
|
prepareSlopeBelts(0, 0, W, H);
|
|
`);
|
|
check(`${code}: both flat joints form elbows`, run('(slopeBeltJoins[artB] & 3) === 3'));
|
|
check(`${code}: adjoining flats do not round off at the joint`, run(`(() => {
|
|
const l = (12 + (artGrade < 0)) * BW + 11, r = (12 + (artGrade > 0)) * BW + 13;
|
|
return !(flatBeltCaps(l) & 2) && !(flatBeltCaps(r) & 1);
|
|
})()`));
|
|
check(`${code}: overhang never covers terrain, parts, machines or bars`, run(`(() => {
|
|
for (let y = 48; y < 57; y++) for (let x = 48; x < 56; x++) {
|
|
const i = y * W + x, own = (y >> 2) * BW + (x >> 2);
|
|
if (blockP[own] || mat[i] !== EMPTY || slopeBeltAt(i, x, y) < 0) continue;
|
|
mat[i] = STONE; const ground = slopeBeltAt(i, x, y); mat[i] = EMPTY;
|
|
part[i] = P_GRATE; const built = slopeBeltAt(i, x, y); part[i] = 0;
|
|
mach[i] = 1; const machine = slopeBeltAt(i, x, y); mach[i] = 0;
|
|
occ[i] = 1; const bar = slopeBeltAt(i, x, y); occ[i] = 0;
|
|
return ground < 0 && built < 0 && machine < 0 && bar < 0;
|
|
}
|
|
return false;
|
|
})()`));
|
|
}
|
|
check('free end rounds its corners and stops at the end', run(`(() => {
|
|
const b = artB, x = 48 - Math.SQRT2, y = 48 + Math.SQRT2;
|
|
blockP[b] = BP_BELT_DOWN;
|
|
return slopeBeltShape(x + 0.8, y + 0.8, b, 0) < 0 && slopeBeltShape(x - 1, y - 1, b, 0) > 0;
|
|
})()`));
|
|
check('flat belts still meet diagonal screw elbows without an end cap', run(`(() => {
|
|
blockP[artB - 1] = BP_BELT;
|
|
blockP[artB] = BP_SCREW; blockV[artB] = 4;
|
|
const joined = !(flatBeltCaps(artB - 1) & 2);
|
|
blockP[artB] = BP_BELT_DOWN;
|
|
return joined;
|
|
})()`));
|
|
check('unpowered rollers and studs stand still', run(`(() => {
|
|
slopeBeltJoins[artB] &= ~16;
|
|
for (let y = 48; y < 56; y++) for (let x = 48; x < 56; x++)
|
|
if (slopeBeltColor(artB, x, y, 0, 150, 170, 190) !== slopeBeltColor(artB, x, y, 20, 150, 170, 190)) return false;
|
|
return true;
|
|
})()`));
|
|
check('powered rollers and studs reverse with the belt', run(`(() => {
|
|
slopeBeltJoins[artB] |= 16;
|
|
let moves = false;
|
|
for (let y = 48; y < 56; y++) for (let x = 48; x < 56; x++) {
|
|
blockV[artB] = 1;
|
|
const a = slopeBeltColor(artB, x, y, 12, 150, 170, 190), stopped = slopeBeltColor(artB, x, y, 0, 150, 170, 190);
|
|
blockV[artB] = 0;
|
|
if (a !== slopeBeltColor(artB, x, y, -12, 150, 170, 190)) return false;
|
|
if (a !== stopped) moves = true;
|
|
}
|
|
return moves;
|
|
})()`));
|
|
check('drawing leaves the seed, cells and saved block data unchanged', run(`(() => {
|
|
const snapshot = () => JSON.stringify([RS, Array.from(mat), Array.from(part), Array.from(blockP), Array.from(blockV)]);
|
|
const before = snapshot();
|
|
prepareSlopeBelts(0, 0, W, H);
|
|
for (let y = 40; y < 64; y++) for (let x = 40; x < 72; x++) {
|
|
const b = slopeBeltAt(y * W + x, x, y);
|
|
if (b >= 0) slopeBeltColor(b, x, y, 12, 150, 170, 190);
|
|
}
|
|
return snapshot() === before;
|
|
})()`));
|
|
done();
|