Sidewall belt and screen drawing, cheaper cleat checks (t42, t43)
Far sidewall drawn behind the load with cleat ribs at their physics positions; sloped screens get a tinted mesh between rails and shake only when loaded. Powder skips cleat checks outside chunks that have cleats, and empty slopes let their chunks sleep. Record the screw conveyor and stall/carry-depth decisions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -105,7 +105,7 @@ for (const grade of [-1,1]) {
|
||||
check(`grade ${grade} phase ${phase} draws exactly the physical cleat raster`,run(`(()=>{
|
||||
let drawn=0;
|
||||
for(let i=0;i<N;i++){const x=i%W,y=(i/W)|0,detail=slopeDetailAt(i,x,y);if(detail===1)drawn++;
|
||||
if((detail===1)!==Boolean(cleatMask[i] && !part[i] && !occ[i] && !mach[i] && (mat[i]===EMPTY || PH[mat[i]]===PH_GAS)))return false;
|
||||
if((detail===1)!==Boolean(cleatMask[i] && !part[i] && !occ[i] && !mach[i] && PH[mat[i]]!==PH_SOLID))return false;
|
||||
}return drawn>0;
|
||||
})()`));
|
||||
}
|
||||
@@ -117,4 +117,40 @@ run('setCell(47*W+48,SAND,20,0);prepareSlopeBelts(0,0,W,H);');
|
||||
check('loaded screen shakes the frame with the simulation tick',run('(slopeBeltJoins[12*BW+12]&64)!==0'));
|
||||
run('tick=4;prepareSlopeBelts(0,0,W,H);');
|
||||
check('loaded frame returns on the next shake beat',run('(slopeBeltJoins[12*BW+12]&64)===0'));
|
||||
flatWorld(run,160,120,112);
|
||||
run('for(let k=0;k<6;k++)placeBlock(BP_BELT_UP,1,12+k,20-k,true);rebuildPower();slopeCleatsTick(false);');
|
||||
check('wall reaches the belt and cleat height, and clips its free ends',run(`(()=>{
|
||||
const b=20*BW+12,g=-1,sy=84;
|
||||
for(const depth of [0.5,3,5.5])
|
||||
if(slopeWallShape(50+g*depth*Math.SQRT1_2,sy-2-depth*Math.SQRT1_2,b)>0)return false;
|
||||
return slopeWallShape(46,sy+2,b)>0 && slopeWallShape(54,sy-6,b)>0;
|
||||
})()`));
|
||||
check('far wall is filled down to the belt and grains cover it',run(`(()=>{
|
||||
prepareSlopeBelts(0,0,W,H);
|
||||
let wall=0;
|
||||
for(let y=8;y<100;y++)for(let x=8;x<140;x++) {
|
||||
const i=y*W+x;
|
||||
if(slopeDetailAt(i,x,y)!==2)continue;
|
||||
wall++;
|
||||
mat[i]=SAND;const covered=slopeDetailAt(i,x,y)===0;mat[i]=EMPTY;
|
||||
if(!covered)return false;
|
||||
}
|
||||
return wall>20;
|
||||
})()`));
|
||||
flatWorld(run,320,240,232);
|
||||
run('for(let k=0;k<8;k++)placeBlock(BP_BELT_UP,1,12+k,30-k,true);for(let t=0;t<120;t++)simTick();');
|
||||
check('idle empty slope lets every moving area sleep',run('awake.every(v=>v===0)'),run('awake.reduce((n,v)=>n+(v>0),0)'));
|
||||
check('cleat chunk flags include neighbours across chunk borders',run(`(()=>{
|
||||
for(const i of cleatCells) {
|
||||
const x=i%W,y=(i/W)|0;
|
||||
for(let yy=y-1;yy<=y+1;yy++)for(let xx=x-1;xx<=x+1;xx++)
|
||||
if(xx>=0 && xx<W && yy>=0 && yy<H && !cleatChunks[(yy>>5)*CW+(xx>>5)])return false;
|
||||
}
|
||||
return cleatCells.length>0 && cleatChunks.some(v=>v===0);
|
||||
})()`));
|
||||
check('a load next to a cleat wakes after the empty line slept',run(`(()=>{
|
||||
const i=cleatCells[0];setCell(i,SAND,20,0);awake.fill(0);
|
||||
slopeCleatsTick(false);
|
||||
return awake.some(v=>v>0) && awake[0]===0;
|
||||
})()`));
|
||||
done();
|
||||
|
||||
Reference in New Issue
Block a user