Vacuum controls: pick-up modes and separate pick-up and blow marks in the bag (t6, t15)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-24 01:54:12 -04:00
co-authored by Claude Opus 5.5
parent cc6f98a932
commit 255824ec6d
19 changed files with 213 additions and 118 deletions
+12 -16
View File
@@ -71,7 +71,7 @@ function pickUnderCursor() {
return;
}
const t = PH[m] === PH_POWDER || PH[m] === PH_LIQUID ? m : 0;
if (t && bag[t] > 0) { GAME.dropMat = t; GAME.matChosen = true; GAME.blowMix = false; selectTool(1); hudDirty = true; playSfx('ui'); setStatus(`Picked: ${MD[t].name} to blow out.`, 'info'); }
if (t) { GAME.blow = new Set([t]); selectTool(1); hudDirty = true; playSfx('ui'); setStatus(`Picked: ${MD[t].name} to blow out.`, 'info'); }
else setStatus('Nothing built here to pick.', 'info');
}
function aimBlock() { return blockOf(Math.floor(GAME.aim.x), Math.floor(GAME.aim.y)); }
@@ -118,11 +118,10 @@ function primaryPress(shift) {
return;
}
if (t === 'vacuum') {
// with anything ticked, the vacuum takes only the ticked materials, wherever you start;
// with nothing ticked, it takes what you start on
const g = GAME.collect.size ? 0 : grainAt(ax, ay);
GAME.vacFilter = shift ? -1 : g;
GAME.vacLocked = shift || !!g || GAME.collect.size > 0;
const g = GAME.pickMode === 'first' ? grainAt(ax, ay) : 0;
GAME.vacFilter = shift || GAME.pickMode === 'all' ? -1 : g;
GAME.vacLocked = shift || GAME.pickMode !== 'first' || !!g;
if (!shift && GAME.pickMode === 'marked' && !GAME.collect.size) setStatus('Nothing marked to pick up. R over something, or ⬇ in the bag.', 'info');
hudDirty = true;
} else if (t === 'build') {
const P = piece();
@@ -208,12 +207,10 @@ function toolTick() {
const r = toolPulse(ax, ay, GAME.drillW, GAME.drillTune);
if (r.fired) { playSfx('pulse', GAME.drillW); if (r.status) setStatus(r.status); }
} else if (t === 'vacuum') {
// started on empty space: the first loose thing you sweep over (that is not ticked) becomes the filter
// clicked on empty space: the first loose thing that comes under the cursor sets the filter, once
if (!GAME.vacLocked && !GAME.collect.size) { const g = grainAt(ax, ay); if (g) { GAME.vacFilter = g; GAME.vacLocked = true; hudDirty = true; } }
const f = GAME.vacFilter, list = GAME.collect;
if (f || list.size) {
const r = toolVacuum(ax, ay, GAME.brush[1], f < 0 ? () => true : list.size ? m => list.has(m) : m => m === f);
if (!GAME.vacLocked && GAME.pickMode === 'first') { const g = grainAt(ax, ay); if (g) { GAME.vacFilter = g; GAME.vacLocked = true; hudDirty = true; } }
const f = GAME.vacFilter, marked = GAME.pickMode === 'marked', list = GAME.collect;
if (f || marked && list.size) {
const r = toolVacuum(ax, ay, GAME.brush[1], f < 0 ? () => true : marked ? m => list.has(m) : m => m === f);
if (r.got) { playSfx('suck'); hudDirty = true; }
if (r.status) setStatus(r.status);
}
@@ -224,10 +221,9 @@ function toolTick() {
}
if (GAME.rmb && !GAME.rmbConsumed) {
if (t === 'vacuum') {
ensureDropMat();
// what right click blows is only ever what is selected (and shown by the cursor): one material, or the ticked mix
const mix = GAME.blowMix && GAME.collect.size ? [...GAME.collect] : null;
const r = toolBlow(ax, ay, GAME.brush[1], GAME.dropMat, mix);
ensureBlow();
const list = blowList();
const r = toolBlow(ax, ay, GAME.brush[1], list[0] || 0, list.length > 1 ? list : null);
if (r.placed) { playSfx('blow'); hudDirty = true; } else if (r.status) setStatus(r.status);
} else if (t === 'build') {
const key = `${(ax / BS) | 0},${(ay / BS) | 0}`;