Removing slopes no longer leaves unowned seal cells; loading clears them

A slope's seal can sit in a cell its neighbour leaves open (a slope's
open corner, or under a grate, screw or screen), but removal only
cleared it when the neighbour was a sloped wall, so cutting a sloped
belt next to a sloped filter or grate could leave a one-cell belt that
nothing owned and nothing could remove. Removal now asks whether the
neighbour fills that cell itself, and loading a world clears belt and
screen cells that no block or seal owns.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-26 23:00:15 -04:00
co-authored by Claude Opus 5.5
parent 3cb0182ac7
commit 8ce71f478a
4 changed files with 43 additions and 2 deletions
+13
View File
@@ -238,4 +238,17 @@ const legacy=JSON.parse(require('zlib').gunzipSync(fs.readFileSync(__dirname+'/f
globalThis.legacyBeltSave=legacy;
run('deserializeWorld(legacyBeltSave.meta,legacyBeltSave.buffers)');
check('old v2 saves keep all wall slope ids and materials',run('Array.from({length:4},(_,k)=>{const b=6*BW+2+k*3;return blockP[b]===15+k && blockV[b]===RSTONE && blockIntegrity(b)===10;}).every(Boolean)'));
// A slope's seal can sit in the open corner of a neighbouring slope or under a grate or screen;
// taking both away must leave nothing behind (it used to leave an unremovable belt cell).
const strayCells="(()=>{let n=0;for(let i=0;i<N;i++){const m=mat[i];if((m===BELTL||m===BELTR||part[i]===P_FILTER||m===RSTONE)&&!blockP[((i/W|0)>>2)*BW+((i%W)>>2)]&&slopeSealOwner(i)<0)n++;}return n;})()";
for(const [first,second] of [['BP_FILTER_DOWN,128,10,12','BP_BELT_DOWN,0,10,11'],['BP_GRATE,0,10,12','BP_BELT_DOWN,0,10,11'],['BP_FILTER,0,10,12','BP_SLOPE_BL,RSTONE,10,11']]) for(const order of [0,1]) for(const built of [0,1]) {
fresh();
const [a,b]=built?[second,first]:[first,second];
run(`placeBlock(${a},true,{m:[],inv:0});placeBlock(${b},true,{m:[],inv:0});`);
run(order?'removeBlock(10,12);removeBlock(10,11);':'removeBlock(10,11);removeBlock(10,12);');
check(`removing ${first.split(',')[0]} and the ${second.split(',')[0]} seal inside it (built ${built}, removed ${order}) leaves no stray cell`,run(strayCells)===0,run(strayCells));
}
fresh();
run("setCell(40*W+43,BELTL,20,0);globalThis.straySave=serializeWorld();deserializeWorld(straySave.meta,straySave.buffers);");
check('loading a world clears a stray belt cell left by the old removal bug',run('mat[40*W+43]===EMPTY'));
done();