Build menu: Shift+Q/E switch tabs, G no longer picks (middle mouse does)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+4
-3
@@ -79,7 +79,8 @@ Details and numbers live in the code and in `docs/systems/`.
|
|||||||
- Machines: fan, Refiner, Stone cutter, Silo.
|
- Machines: fan, Refiner, Stone cutter, Silo.
|
||||||
- Molds: ingot, bit, tank.
|
- Molds: ingot, bit, tank.
|
||||||
- Build actions: drag for lines, Shift-drag for rectangles, Ctrl to replace, hold C / X and
|
- Build actions: drag for lines, Shift-drag for rectangles, Ctrl to replace, hold C / X and
|
||||||
drag to copy / cut, V to paste, Ctrl+Z to undo, middle mouse (or G) to pick.
|
drag to copy / cut, V to paste, Ctrl+Z to undo, middle mouse to pick,
|
||||||
|
Shift+Q/E to switch build tabs.
|
||||||
- **Economy:**
|
- **Economy:**
|
||||||
- The trade dock pays for anything dropped through its grate, at the market price.
|
- The trade dock pays for anything dropped through its grate, at the market price.
|
||||||
- Prices dip when you sell a lot of one thing and recover over minutes.
|
- Prices dip when you sell a lot of one thing and recover over minutes.
|
||||||
@@ -135,8 +136,8 @@ above, including:
|
|||||||
build more lines.
|
build more lines.
|
||||||
- **A heap on a belt moves as one**, up to 96 grains deep, not just its bottom layer. The owner
|
- **A heap on a belt moves as one**, up to 96 grains deep, not just its bottom layer. The owner
|
||||||
reports this still misbehaves (see NOTES.md).
|
reports this still misbehaves (see NOTES.md).
|
||||||
- **Pick** (middle mouse, also G for now) selects the piece under the cursor with its direction,
|
- **Pick** (middle mouse) selects the piece under the cursor with its direction,
|
||||||
wall material and filter settings. The owner wants G dropped (see NOTES.md).
|
wall material and filter settings. G is unbound, as the owner requested.
|
||||||
- **The build menu** is a bar of tabs and icon tiles along the bottom: Structure, Moving,
|
- **The build menu** is a bar of tabs and icon tiles along the bottom: Structure, Moving,
|
||||||
Liquids, Machines, Molds. The owner wants more changes (see NOTES.md).
|
Liquids, Machines, Molds. The owner wants more changes (see NOTES.md).
|
||||||
- **No length limit when dragging.** Blocks out of the bot's reach become ghosts that it builds
|
- **No length limit when dragging.** Blocks out of the bot's reach become ghosts that it builds
|
||||||
|
|||||||
+3
-3
@@ -392,9 +392,9 @@ The notebook (N): milestones, market, wallet, blueprints, controls.
|
|||||||
The tool hotbar and what is selected.
|
The tool hotbar and what is selected.
|
||||||
- functions: renderHotbar, toolId, steering, modShift, grainAt, selectTool, bagMaterials, mixList, ensureDropMat, piece
|
- functions: renderHotbar, toolId, steering, modShift, grainAt, selectTool, bagMaterials, mixList, ensureDropMat, piece
|
||||||
|
|
||||||
### src/ui/build-menu.js (72 lines)
|
### src/ui/build-menu.js (80 lines)
|
||||||
The build menu along the bottom: categories, piece tiles and their icons.
|
The build menu along the bottom: categories, piece tiles and their icons.
|
||||||
- functions: pieceIcon, catOf, renderBuildBar, setupBuildBar
|
- functions: pieceIcon, catOf, selectBuildCat, cycleBuildCat, renderBuildBar, setupBuildBar
|
||||||
- variables: BUILD_CATS, BUILD_ORDER, PIECE_ICONS, lastBuildKey
|
- variables: BUILD_CATS, BUILD_ORDER, PIECE_ICONS, lastBuildKey
|
||||||
|
|
||||||
### src/ui/selection.js (246 lines)
|
### src/ui/selection.js (246 lines)
|
||||||
@@ -406,7 +406,7 @@ The selected tool and piece: R / Q / E, drill width, filter picker, the selectio
|
|||||||
Discovery cards, hover info (I) and the cursor label.
|
Discovery cards, hover info (I) and the cursor label.
|
||||||
- functions: showCard, howText, discoveryCard, reactionsOf, hoverInfo, renderInfo, drawCursorLabel
|
- functions: showCard, howText, discoveryCard, reactionsOf, hoverInfo, renderInfo, drawCursorLabel
|
||||||
|
|
||||||
### src/ui/input.js (76 lines)
|
### src/ui/input.js (75 lines)
|
||||||
Keyboard and mouse listeners.
|
Keyboard and mouse listeners.
|
||||||
- functions: isTyping
|
- functions: isTyping
|
||||||
- variables: canvas
|
- variables: canvas
|
||||||
|
|||||||
@@ -4,6 +4,23 @@ What agents have done, newest first. Add an entry for every piece of work: the d
|
|||||||
note or request it was for, what changed, the files touched, the tests run, and anything left
|
note or request it was for, what changed, the files touched, the tests run, and anything left
|
||||||
open or not verified. Keep each entry short; the git history has the details.
|
open or not verified. Keep each entry short; the git history has the details.
|
||||||
|
|
||||||
|
## 2026-10-23: Shift+Q/E build tabs, G pick key removed (Claude Code, with Codex)
|
||||||
|
|
||||||
|
Notes: "add shift + q/e to move tabs" and "having the "g pick" there is confusing".
|
||||||
|
|
||||||
|
- `src/ui/build-menu.js`: `selectBuildCat(c)` (shared with tab clicks) and `cycleBuildCat(d)`;
|
||||||
|
the menu hint now reads Q/E cycle · Shift+Q/E tab.
|
||||||
|
- `src/ui/input.js`: Shift+Q/E switch tabs with the build tool; G is unbound.
|
||||||
|
- Text: build card (`selection.js`), notebook controls (`notebook.js`), `actions.js` comment,
|
||||||
|
`docs/DESIGN.md`, `docs/PROJECT_MAP.md` (regenerated, `--check` passes).
|
||||||
|
- `test/play.py`: checks for Shift+Q/E, wrapping, the remembered piece per tab, plain Q/E,
|
||||||
|
and that G no longer calls pick while middle mouse still does (109 checks).
|
||||||
|
- Tests: all 11 headless suites and `play.py` pass; a `tools/shot.py` shot of the Moving tab
|
||||||
|
shows the new hint. `t_smooth.py` passes, but its "half-resolution smooth still draws" check
|
||||||
|
failed on several runs with the 'slow' pixel fallback while the machine was busy (load ~14).
|
||||||
|
The previous commit fails the same way under the same load, so this change didn't cause it.
|
||||||
|
- Open: that check is timing-sensitive on a loaded machine; rerun it when the machine is idle.
|
||||||
|
|
||||||
## 2026-10-23: browser tests run locally (Claude Code, with Codex)
|
## 2026-10-23: browser tests run locally (Claude Code, with Codex)
|
||||||
|
|
||||||
Request: get the browser tests, Playwright and Chromium working on the owner's Arch machine
|
Request: get the browser tests, Playwright and Chromium working on the owner's Arch machine
|
||||||
|
|||||||
+1
-1
@@ -45,7 +45,7 @@ function doInteract() {
|
|||||||
if (msg) { setStatus(msg, 'info'); if (!/^New (drill bit|bag)/.test(msg)) toast(msg); }
|
if (msg) { setStatus(msg, 'info'); if (!/^New (drill bit|bag)/.test(msg)) toast(msg); }
|
||||||
else { setStatus('Nothing to use there. F works on gates, molds, fans and filters.', 'info'); }
|
else { setStatus('Nothing to use there. F works on gates, molds, fans and filters.', 'info'); }
|
||||||
}
|
}
|
||||||
// Pick (G or middle mouse): the piece under the cursor becomes the one you build, with its
|
// Pick (middle mouse): the piece under the cursor becomes the one you build, with its
|
||||||
// direction, wall material and filter settings. On loose material it picks that to blow out.
|
// direction, wall material and filter settings. On loose material it picks that to blow out.
|
||||||
function pickUnderCursor() {
|
function pickUnderCursor() {
|
||||||
const ax = Math.floor(GAME.aim.x), ay = Math.floor(GAME.aim.y);
|
const ax = Math.floor(GAME.aim.x), ay = Math.floor(GAME.aim.y);
|
||||||
|
|||||||
+14
-6
@@ -29,6 +29,17 @@ const PIECE_ICONS = {
|
|||||||
function pieceIcon(id) { return `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linejoin="round" stroke-linecap="round" aria-hidden="true">${PIECE_ICONS[id] || ''}</svg>`; }
|
function pieceIcon(id) { return `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linejoin="round" stroke-linecap="round" aria-hidden="true">${PIECE_ICONS[id] || ''}</svg>`; }
|
||||||
function catOf(id) { const c = BUILD_CATS.findIndex(([, ids]) => ids.includes(id)); return c < 0 ? 0 : c; }
|
function catOf(id) { const c = BUILD_CATS.findIndex(([, ids]) => ids.includes(id)); return c < 0 ? 0 : c; }
|
||||||
let lastBuildKey = '';
|
let lastBuildKey = '';
|
||||||
|
function selectBuildCat(c) {
|
||||||
|
GAME.buildCat = c;
|
||||||
|
const ids = BUILD_CATS[c][1], keep = GAME.catPick && GAME.catPick[c];
|
||||||
|
GAME.pieceIdx = PIECE_BY_ID[ids.includes(keep) ? keep : ids[0]].index;
|
||||||
|
GAME.catPick = GAME.catPick || {}; GAME.catPick[c] = piece().id;
|
||||||
|
GAME.drag = null; hudDirty = true; lastBuildKey = ''; playSfx('ui');
|
||||||
|
}
|
||||||
|
function cycleBuildCat(d) {
|
||||||
|
const c = GAME.buildCat != null ? GAME.buildCat : catOf(piece().id);
|
||||||
|
selectBuildCat((c + d + BUILD_CATS.length) % BUILD_CATS.length);
|
||||||
|
}
|
||||||
function renderBuildBar() {
|
function renderBuildBar() {
|
||||||
const bar = $('buildbar'); if (!bar) return;
|
const bar = $('buildbar'); if (!bar) return;
|
||||||
const show = GAME.running && toolId() === 'build' && !GAME.paste && !GAME.selDrag && !selModeHeld();
|
const show = GAME.running && toolId() === 'build' && !GAME.paste && !GAME.selDrag && !selModeHeld();
|
||||||
@@ -42,7 +53,7 @@ function renderBuildBar() {
|
|||||||
lastBuildKey = key;
|
lastBuildKey = key;
|
||||||
const tip = PIECE_BY_ID[hov && ids.includes(hov) ? hov : P.id];
|
const tip = PIECE_BY_ID[hov && ids.includes(hov) ? hov : P.id];
|
||||||
let h = '<div class="bb-head">' + BUILD_CATS.map(([name], k) => `<button class="bb-tab${k === cat ? ' on' : ''}" data-cat="${k}">${esc(name)}</button>`).join('')
|
let h = '<div class="bb-head">' + BUILD_CATS.map(([name], k) => `<button class="bb-tab${k === cat ? ' on' : ''}" data-cat="${k}">${esc(name)}</button>`).join('')
|
||||||
+ '<span class="bb-keys"><kbd>Q</kbd>/<kbd>E</kbd> cycle · <kbd>G</kbd> pick</span></div><div class="bb-tiles">';
|
+ '<span class="bb-keys"><kbd>Q</kbd>/<kbd>E</kbd> cycle · <kbd>Shift</kbd>+<kbd>Q</kbd>/<kbd>E</kbd> tab</span></div><div class="bb-tiles">';
|
||||||
for (const id of ids) {
|
for (const id of ids) {
|
||||||
const Q = PIECE_BY_ID[id], cost = pieceCostNow(Q), ok = canAfford(cost, 1);
|
const Q = PIECE_BY_ID[id], cost = pieceCostNow(Q), ok = canAfford(cost, 1);
|
||||||
const sw = Q.variants === 'wall' ? `<span class="sw" style="background:${rgbOf(WALL_OF[GAME.wallMat])}"></span>` : '';
|
const sw = Q.variants === 'wall' ? `<span class="sw" style="background:${rgbOf(WALL_OF[GAME.wallMat])}"></span>` : '';
|
||||||
@@ -57,11 +68,8 @@ function setupBuildBar() {
|
|||||||
const bar = $('buildbar'); if (!bar) return;
|
const bar = $('buildbar'); if (!bar) return;
|
||||||
bar.addEventListener('click', e => {
|
bar.addEventListener('click', e => {
|
||||||
const t = e.target.closest('[data-cat],[data-piece]'); if (!t) return;
|
const t = e.target.closest('[data-cat],[data-piece]'); if (!t) return;
|
||||||
if (t.dataset.cat != null) {
|
if (t.dataset.cat != null) { selectBuildCat(+t.dataset.cat); return; }
|
||||||
const c = +t.dataset.cat; GAME.buildCat = c;
|
GAME.pieceIdx = PIECE_BY_ID[t.dataset.piece].index; GAME.buildCat = catOf(t.dataset.piece);
|
||||||
const ids = BUILD_CATS[c][1], keep = GAME.catPick && GAME.catPick[c];
|
|
||||||
GAME.pieceIdx = PIECE_BY_ID[ids.includes(keep) ? keep : ids[0]].index;
|
|
||||||
} else { GAME.pieceIdx = PIECE_BY_ID[t.dataset.piece].index; GAME.buildCat = catOf(t.dataset.piece); }
|
|
||||||
GAME.catPick = GAME.catPick || {}; GAME.catPick[catOf(piece().id)] = piece().id;
|
GAME.catPick = GAME.catPick || {}; GAME.catPick[catOf(piece().id)] = piece().id;
|
||||||
GAME.drag = null; hudDirty = true; lastBuildKey = ''; playSfx('ui');
|
GAME.drag = null; hudDirty = true; lastBuildKey = ''; playSfx('ui');
|
||||||
});
|
});
|
||||||
|
|||||||
+2
-3
@@ -25,9 +25,8 @@ window.addEventListener('keydown', e => {
|
|||||||
case '1': case '2': case '3': case '4': selectTool(+k - 1); break;
|
case '1': case '2': case '3': case '4': selectTool(+k - 1); break;
|
||||||
case 'c': case 'x': hudDirty = true; break;
|
case 'c': case 'x': hudDirty = true; break;
|
||||||
case 'v': startPaste(); break;
|
case 'v': startPaste(); break;
|
||||||
case 'g': pickUnderCursor(); break;
|
case 'q': if (e.shiftKey && toolId() === 'build') cycleBuildCat(-1); else cycleItem(-1); break;
|
||||||
case 'q': cycleItem(-1); break;
|
case 'e': if (e.shiftKey && toolId() === 'build') cycleBuildCat(1); else cycleItem(1); break;
|
||||||
case 'e': cycleItem(1); break;
|
|
||||||
case 'r': rotate(); break;
|
case 'r': rotate(); break;
|
||||||
case 't': if (toolId() === 'vacuum') toggleCollectUnderCursor(); else if (toolId() === 'build' && piece().filter) pickFilterUnderCursor(); break;
|
case 't': if (toolId() === 'vacuum') toggleCollectUnderCursor(); else if (toolId() === 'build' && piece().filter) pickFilterUnderCursor(); break;
|
||||||
case 'f': doInteract(); break;
|
case 'f': doInteract(); break;
|
||||||
|
|||||||
+2
-2
@@ -169,10 +169,10 @@ function copyCode(code) {
|
|||||||
function controlsHtml() {
|
function controlsHtml() {
|
||||||
const kb = [
|
const kb = [
|
||||||
['Fly', 'W A S D'], ['Boost while flying', 'Shift'], ['Tool modifier (while not flying)', 'Shift'], ['Use tool', 'Left mouse'], ['Second action', 'Right mouse'],
|
['Fly', 'W A S D'], ['Boost while flying', 'Shift'], ['Tool modifier (while not flying)', 'Shift'], ['Use tool', 'Left mouse'], ['Second action', 'Right mouse'],
|
||||||
['Tools', '1 – 4'], ['Cycle what you blow · piece', 'Q / E'], ['Variant: material · direction · flip', 'R'],
|
['Tools', '1 – 4'], ['Cycle what you blow · piece', 'Q / E'], ['Switch build tab', 'Shift + Q / E'], ['Variant: material · direction · flip', 'R'],
|
||||||
['Tick/untick what is under the cursor (Vacuum)', 'R or T'], ['Nozzle or brush size', '[ ] or Shift + wheel'],
|
['Tick/untick what is under the cursor (Vacuum)', 'R or T'], ['Nozzle or brush size', '[ ] or Shift + wheel'],
|
||||||
['Replace what is built (Build)', 'Hold Ctrl'], ['Copy a box of what you built', 'Hold C, drag'], ['Cut a box (refunded, paste it back)', 'Hold X, drag'], ['Paste again', 'V'], ['Undo building', 'Ctrl + Z'], ['Blueprint library', 'B'], ['Zoom', 'Mouse wheel'], ['Interact (gates, molds, fans, filters)', 'F'], ['Thermal lens', 'H'], ['Info overlay: filters, belt and tube directions', 'I'], ['Bot lamp', 'L'],
|
['Replace what is built (Build)', 'Hold Ctrl'], ['Copy a box of what you built', 'Hold C, drag'], ['Cut a box (refunded, paste it back)', 'Hold X, drag'], ['Paste again', 'V'], ['Undo building', 'Ctrl + Z'], ['Blueprint library', 'B'], ['Zoom', 'Mouse wheel'], ['Interact (gates, molds, fans, filters)', 'F'], ['Thermal lens', 'H'], ['Info overlay: filters, belt and tube directions', 'I'], ['Bot lamp', 'L'],
|
||||||
['Pick the piece under the cursor (with its direction and settings)', 'G or middle mouse'], ['Notebook', 'N'], ['Clear all blueprint ghosts', 'Delete'], ['Save', 'Ctrl + S'], ['Pause · menu', 'Esc'], ['Mute', 'M'],
|
['Pick the piece under the cursor (with its direction and settings)', 'Middle mouse'], ['Notebook', 'N'], ['Clear all blueprint ghosts', 'Delete'], ['Save', 'Ctrl + S'], ['Pause · menu', 'Esc'], ['Mute', 'M'],
|
||||||
];
|
];
|
||||||
const pad = [
|
const pad = [
|
||||||
['Fly', 'Left stick'], ['Boost', 'Left stick pushed all the way'], ['Aim', 'Right stick'], ['Use tool · suck', 'RT'], ['Second action · blow', 'LT'], ['Tools', 'LB / RB'],
|
['Fly', 'Left stick'], ['Boost', 'Left stick pushed all the way'], ['Aim', 'Right stick'], ['Use tool · suck', 'RT'], ['Second action · blow', 'LT'], ['Tools', 'LB / RB'],
|
||||||
|
|||||||
+1
-1
@@ -199,7 +199,7 @@ function renderSelCard() {
|
|||||||
<div class="sub">${esc(P.desc)}</div>
|
<div class="sub">${esc(P.desc)}</div>
|
||||||
${P.filter ? `<div class="sub">New ones will ${esc(filterSentence(GAME.filterCfg))}. <kbd>F</kbd> sets materials and mode (or click materials in the bag, or <kbd>T</kbd> over one); <kbd>F</kbd> on a placed filter changes its whole row.</div>` : ''}
|
${P.filter ? `<div class="sub">New ones will ${esc(filterSentence(GAME.filterCfg))}. <kbd>F</kbd> sets materials and mode (or click materials in the bag, or <kbd>T</kbd> over one); <kbd>F</kbd> on a placed filter changes its whole row.</div>` : ''}
|
||||||
<div class="sub">${P.kind === 'block' ? 'Drag for a line (any length: what is out of reach becomes ghosts), Shift-drag for a rectangle.' : 'Click to place.'}${P.dirs && P.kind === 'block' ? ' A dragged line runs the way you drag it; a single click uses <kbd>R</kbd>.' : P.dirs ? ' <kbd>R</kbd> turns it.' : pieceUsesWall(P) ? ' <kbd>R</kbd> picks the material.' : ''}</div>
|
<div class="sub">${P.kind === 'block' ? 'Drag for a line (any length: what is out of reach becomes ghosts), Shift-drag for a rectangle.' : 'Click to place.'}${P.dirs && P.kind === 'block' ? ' A dragged line runs the way you drag it; a single click uses <kbd>R</kbd>.' : P.dirs ? ' <kbd>R</kbd> turns it.' : pieceUsesWall(P) ? ' <kbd>R</kbd> picks the material.' : ''}</div>
|
||||||
<div class="sub keys-mini"><kbd>Ctrl</kbd> replace · <kbd>Ctrl</kbd>+<kbd>Z</kbd> undo · right click take back · <kbd>G</kbd> pick · hold <kbd>C</kbd>/<kbd>X</kbd> copy/cut · <kbd>V</kbd> paste</div>${ng ? `<div class="sub" style="color:var(--patina)">${ng} ghost pieces waiting${ghostMissing ? ', some short on materials' : ''}.</div>` : ''}`;
|
<div class="sub keys-mini"><kbd>Ctrl</kbd> replace · <kbd>Ctrl</kbd>+<kbd>Z</kbd> undo · right click take back · middle mouse pick · hold <kbd>C</kbd>/<kbd>X</kbd> copy/cut · <kbd>V</kbd> paste</div>${ng ? `<div class="sub" style="color:var(--patina)">${ng} ghost pieces waiting${ghostMissing ? ', some short on materials' : ''}.</div>` : ''}`;
|
||||||
} else if (t === 'ignite') {
|
} else if (t === 'ignite') {
|
||||||
h = `<div class="row"><span class="name">Igniter</span><span class="chip hot">up to 640°C</span></div><div class="sub">Hold on fuel to light it. Coal catches around 420°C, wood around 300°C. Fuel needs open air next to it.</div>`;
|
h = `<div class="row"><span class="name">Igniter</span><span class="chip hot">up to 640°C</span></div><div class="sub">Hold on fuel to light it. Coal catches around 420°C, wood around 300°C. Fuel needs open air next to it.</div>`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -208,6 +208,30 @@ with sync_playwright() as p:
|
|||||||
ok = select('3', "piece().id === 'wall'")
|
ok = select('3', "piece().id === 'wall'")
|
||||||
ev('GAME.wallMat = RSTONE; hudDirty = true')
|
ev('GAME.wallMat = RSTONE; hudDirty = true')
|
||||||
check('build tool starts on wall blocks', ok)
|
check('build tool starts on wall blocks', ok)
|
||||||
|
c0 = ev('GAME.buildCat != null ? GAME.buildCat : catOf(piece().id)')
|
||||||
|
pg.keyboard.press('Shift+E')
|
||||||
|
check('Shift+E switches build tabs and selects a piece in the tab', ev('GAME.buildCat') == (c0 + 1) % ev('BUILD_CATS.length') and ev('BUILD_CATS[GAME.buildCat][1].includes(piece().id)'))
|
||||||
|
pg.keyboard.press('Shift+Q')
|
||||||
|
check('Shift+Q returns to the tab and restores its wall piece', ev('GAME.buildCat') == c0 and ev("piece().id === 'wall'"))
|
||||||
|
ev('selectBuildCat(0)')
|
||||||
|
pg.keyboard.press('Shift+Q')
|
||||||
|
check('Shift+Q wraps from the first build tab to the last', ev('GAME.buildCat === BUILD_CATS.length - 1'))
|
||||||
|
pg.keyboard.press('Shift+E')
|
||||||
|
check('Shift+E wraps back to the first build tab', ev('GAME.buildCat === 0'))
|
||||||
|
p0 = ev('piece().id')
|
||||||
|
pg.keyboard.press('e')
|
||||||
|
check('plain E cycles pieces without switching tabs', ev('piece().id') != p0 and ev('GAME.buildCat') == 0)
|
||||||
|
pg.keyboard.press('q')
|
||||||
|
check('plain Q returns to the piece without switching tabs', ev('piece().id') == p0 and ev('GAME.buildCat') == 0)
|
||||||
|
pg.mouse.move(*cell_to_screen(bx + 6, gy + 8)); settle(100)
|
||||||
|
ev('window._pickN = 0; window._pickOrig = pickUnderCursor; pickUnderCursor = function () { _pickN++; }; 0') # 0: evaluate would call a returned function
|
||||||
|
pg.keyboard.press('g'); settle(60)
|
||||||
|
g_picks = ev('_pickN')
|
||||||
|
pg.mouse.click(*cell_to_screen(bx + 6, gy + 8), button='middle'); settle(60)
|
||||||
|
check('G no longer picks; middle mouse still does', g_picks == 0 and ev('_pickN') == 1, f"G {g_picks}, then {ev('_pickN')}")
|
||||||
|
ev('pickUnderCursor = _pickOrig')
|
||||||
|
check('G leaves the build piece unchanged over the world', ev('piece().id') == p0)
|
||||||
|
ev("GAME.pieceIdx = PIECE_BY_ID.wall.index; GAME.wallMat = RSTONE; hudDirty = true")
|
||||||
bbx, bby = ev('[Math.floor((bot.x + 2) / 4), Math.floor((bot.y + 2) / 4)]')
|
bbx, bby = ev('[Math.floor((bot.x + 2) / 4), Math.floor((bot.y + 2) / 4)]')
|
||||||
rb = ev('bag[RSTONE]'); nb0 = ev('blockP.reduce((a, v) => a + (v === BP_WALL), 0)')
|
rb = ev('bag[RSTONE]'); nb0 = ev('blockP.reduce((a, v) => a + (v === BP_WALL), 0)')
|
||||||
drag(lambda: blk(bbx + 3, bby - 4), lambda: blk(bbx + 8, bby - 4))
|
drag(lambda: blk(bbx + 3, bby - 4), lambda: blk(bbx + 8, bby - 4))
|
||||||
|
|||||||
Reference in New Issue
Block a user