Screw tubes carry bars, one whole bar at a time
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -250,4 +250,60 @@ for (const lift of [true, false]) {
|
||||
}
|
||||
run('carryColumn = __carry;');
|
||||
|
||||
// --- whole bars in screw tubes; position an existing bar inside for mid-ride cases
|
||||
function putBar(x, y) { run(`{ spawnBar(BARCU, 20, 40, 0, 0); const e=ents[0]; entMark(e,0); e.x=e.ix=${x}; e.y=e.iy=${y}; entMark(e,1); }`); }
|
||||
function barTube(corner = false) {
|
||||
fresh();
|
||||
run(`for (let by = 20; by < 24; by++) placeBlock(BP_TUBE, 0, 25, by, true);
|
||||
${corner ? 'for (let bx = 25; bx < 29; bx++) placeBlock(BP_TUBE, 1, bx, 19, true);' : ''}`);
|
||||
putBar(100,94);
|
||||
}
|
||||
function watchBar(n, condition) { return run(`(() => { for (let k=0;k<${n};k++) { simTick(); if (${condition}) return true; } return false; })()`); }
|
||||
fresh();
|
||||
run('for (let bx=20;bx<25;bx++) placeBlock(BP_BELT,1,bx,25,true); for(let by=21;by<25;by++) placeBlock(BP_TUBE,0,25,by,true); spawnBar(BARCU,84,98,0,0);');
|
||||
check('a belt feeds a whole copper bar into a lift and out its top', watchBar(200, 'ents.length===1 && ents[0].iy+BAR_H<=84'), run('JSON.stringify(ents)'));
|
||||
fresh();
|
||||
run('for(let bx=20;bx<24;bx++) placeBlock(BP_TUBE,1,bx,20,true);'); putBar(80,82);
|
||||
check('a whole bar leaves a right tube', watchBar(100,'ents.length===1 && ents[0].ix>=96'));
|
||||
// steam and smoke drift through tubes near furnaces: a bar passes them as it does in the open
|
||||
barTube();
|
||||
check('steam and smoke in a tube do not stop a bar', run(`(() => { for (let k = 0; k < 120; k++) {
|
||||
for (let y = 80; y < 94; y++) for (let x = 100; x < 104; x++) if (mat[y*W+x] === EMPTY && !occ[y*W+x]) setCell(y*W+x, (x + y) & 1 ? STEAM : SMOKE, 120, 0);
|
||||
simTick(); if (ents.length === 1 && ents[0].iy + BAR_H <= 80) return true; } return false; })()`), run('JSON.stringify(ents)'));
|
||||
barTube(true);
|
||||
check('a bar turns from an up tube into a right tube and leaves', watchBar(200,'ents.length===1 && ents[0].ix>=116'));
|
||||
fresh();
|
||||
run('for(let bx=20;bx<24;bx++) placeBlock(BP_TUBE,1,bx,20,true);'); putBar(80,82);
|
||||
rect(run,96,80,99,83,run('STONE'));
|
||||
ticks(run,100);
|
||||
check('a blocked mouth holds the whole bar inside without wall overlap',run('ents.length===1 && ents[0].ix===92 && !mat.some((m,i)=>m===STONE && occ[i])'),run('JSON.stringify(ents)'));
|
||||
rect(run,96,80,99,83,run('EMPTY'));
|
||||
check('the bar leaves when the mouth wall is removed',watchBar(80,'ents[0].ix>=96'));
|
||||
barTube();
|
||||
rect(run,100,88,103,89,run('SAND'));
|
||||
const shared = run(`(() => { let overlap=false, rose=false; const n=mat.reduce((n,m)=>n+(m===SAND),0); for(let k=0;k<160;k++) { simTick(); if(mat.some((m,i)=>m===SAND && occ[i])) overlap=true; if(ents[0].iy<90) rose=true; } return { overlap, rose, n, after:mat.reduce((n,m)=>n+(m===SAND),0)+flyers.filter(f=>f.m===SAND).length }; })()`);
|
||||
check('grains and a moving bar share a lift without overlap or lost sand',!shared.overlap && shared.rose && shared.n===shared.after,JSON.stringify(shared));
|
||||
barTube(); ticks(run,8);
|
||||
run('globalThis.__barSave=serializeWorld(); deserializeWorld(__barSave.meta,__barSave.buffers);');
|
||||
check('a bar saved mid-tube continues out of its mouth',watchBar(100,'ents.length===1 && ents[0].iy+BAR_H<=80'));
|
||||
fresh();
|
||||
run('for(let bx=20;bx<24;bx++) placeBlock(BP_BELT,1,bx,25,true); placeBlock(BP_WALL,RSTONE,24,25,true); placeBlock(BP_WALL,RSTONE,24,24,true); spawnBar(BARCU,80,98,0,0);');
|
||||
ticks(run,100);
|
||||
check('a normal belt still carries a bar and stops at its blocked end',run('ents.length===1 && ents[0].ix===92 && ents[0].iy===98'));
|
||||
fresh(); run('placeBlock(BP_TUBE,1,25,25,true); spawnBar(BARCU,100,98,0,0);'); ticks(run,100);
|
||||
check('a bar resting on a horizontal tube stays on top',run('ents[0].ix===100 && ents[0].iy===98'));
|
||||
|
||||
for (const dir of [0, 2]) {
|
||||
fresh(); run(`placeBlock(BP_TUBE,${dir},25,20,true); spawnBar(BARCU,100,${dir ? 78 : 84},0,${dir ? 0 : -0.4});`);
|
||||
check(dir ? 'a falling bar enters a down tube from above' : 'an upward moving bar enters the bottom of an up tube',watchBar(20,'entTubeAt(ents[0].ix,ents[0].iy)!==0'));
|
||||
}
|
||||
fresh(); run('for(let bx=20;bx<24;bx++) placeBlock(BP_TUBE,1,bx,20,true); for(let by=21;by<25;by++) placeBlock(BP_TUBE,2,23,by,true);'); putBar(80,82);
|
||||
check('a bar turns from a right tube down into a vertical lane',watchBar(160,'ents[0].iy>=100'));
|
||||
barTube(true); rect(run,100,76,103,79,run('STONE')); ticks(run,100);
|
||||
check('a blocked corner waits without overlapping stone',run('ents[0].iy===80 && !mat.some((m,i)=>m===STONE && occ[i])'));
|
||||
rect(run,100,76,103,79,run('EMPTY'));
|
||||
check('a blocked corner resumes when cleared',watchBar(120,'ents[0].ix>=116'));
|
||||
barTube(); run('ents[0].T=1200; for(let y=94;y<96;y++) for(let x=100;x<104;x++) temp[y*W+x]=1200; entTick();');
|
||||
check('a bar melting inside a tube becomes eight molten grains',run('ents.length===0') && count(run,run('MCU'))===8);
|
||||
|
||||
done();
|
||||
|
||||
Reference in New Issue
Block a user