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:
2026-10-24 19:53:09 -04:00
co-authored by Claude Opus 5.5
parent f34c34aa73
commit 99d04b4972
20 changed files with 272 additions and 22 deletions
+56
View File
@@ -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);
}
}