Bar rack blocks: store 50 bars each, F lets them out oldest first (t1)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
// Each rack block owns its bars; only the bottom of a column releases them.
|
||||
const RACK_CAP = 50;
|
||||
let rackState = new Map();
|
||||
function newRack() { return { q: [], n: 0, open: false, wait: 0 }; }
|
||||
function rackTop(b) { while (b >= BW && blockP[b - BW] === BP_RACK) b -= BW; return b; }
|
||||
function rackBottom(b) { while (b + BW < NB && blockP[b + BW] === BP_RACK) b += BW; return b; }
|
||||
function rackPush(s, m, n) {
|
||||
const last = s.q[s.q.length - 1];
|
||||
if (last && last[0] === m) last[1] += n; else s.q.push([m, n]);
|
||||
s.n += n;
|
||||
}
|
||||
function rackShift(s, n) {
|
||||
s.q[0][1] -= n; s.n -= n;
|
||||
if (!s.q[0][1]) s.q.shift();
|
||||
}
|
||||
// Called with the moving bar unmarked, after its ordinary collision handling.
|
||||
function rackIntake(e) {
|
||||
const y = e.iy + BAR_H;
|
||||
if (e.vy !== 0 || Math.abs(e.vx) >= 0.05 || y >= H || y % BS) return false;
|
||||
for (let x = Math.max(0, e.ix); x < Math.min(W, e.ix + BAR_W); x += BS - x % BS) {
|
||||
const b = (y / BS) * BW + Math.floor(x / BS), left = (b % BW) * BS;
|
||||
if (blockP[b] !== BP_RACK || b >= BW && blockP[b - BW] === BP_RACK || Math.min(e.ix + BAR_W, left + BS) - Math.max(e.ix, left) < BAR_W / 2) continue;
|
||||
for (let q = rackBottom(b); q >= b; q -= BW) {
|
||||
const s = rackState.get(q);
|
||||
if (s.n < RACK_CAP) { rackPush(s, e.m, 1); return true; }
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function rackRefill(b) {
|
||||
const top = rackTop(b);
|
||||
for (let q = b; q > top; q -= BW) {
|
||||
const lower = rackState.get(q);
|
||||
for (let above = q - BW; above >= top && lower.n < RACK_CAP; above -= BW) {
|
||||
const upper = rackState.get(above);
|
||||
while (lower.n < RACK_CAP && upper.n) {
|
||||
const n = Math.min(RACK_CAP - lower.n, upper.q[0][1]);
|
||||
rackPush(lower, upper.q[0][0], n); rackShift(upper, n);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function rackTick() {
|
||||
for (const [b, s] of rackState) {
|
||||
if (b + BW < NB && blockP[b + BW] === BP_RACK) continue;
|
||||
if (!s.open) continue;
|
||||
if (!s.n) rackRefill(b);
|
||||
if (!s.n) continue;
|
||||
if (s.wait < 20) s.wait++;
|
||||
if (s.wait < 20) continue;
|
||||
const x = (b % BW) * BS, y = (((b / BW) | 0) + 1) * BS;
|
||||
if (!entFreeAt(x, y) || !spawnBar(s.q[0][0], x, y, 0, 0)) continue;
|
||||
rackShift(s, 1); s.wait = 0;
|
||||
rackRefill(b);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user