diff --git a/docs/agent-log.md b/docs/agent-log.md index bef5858..c3354ad 100644 --- a/docs/agent-log.md +++ b/docs/agent-log.md @@ -4,6 +4,24 @@ 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 open or not verified. Keep each entry short; the git history has the details. +## 2026-10-27: OS pointer hidden over the game (Claude Code) + +- The canvas used `cursor: crosshair`, so the system pointer showed on top of the game's own aim; + it was hidden only while a gamepad was in use. Now `cursor: none` on the canvas always; the + gamepad's `nocursor` toggling is gone. Files: `src/styles/style.css`, `src/ui/input.js`, + `src/ui/gamepad.js`. + +## 2026-10-27: t77 identify ores with the cursor (Claude Code + Codex) + +- New `src/ui/cursor.js`: `oreLike`, `bitNeeded`, `pingVisible` (a ping's cells, while showing), + `hoveredVein` (cached capped flood fill and edges), `cursorLabelAlpha` (2 s then fade). + `hoverInfo` identifies pinged cells under fog and says "needs "; `drawCursorLabel` honours + the new Off / Ores only / Everything setting (`SET.cursorLabel`, booleans migrated); + `drawHoveredVein` in `src/render/overlays.js` draws the outline. +- Tests: `test/t_cursor.js`, `test/t_smooth.py`, `test/play.py`; `python3 test/run_all.py --browser` + all passed. Open: the outline keeps its old shape if the vein is drilled while hovered, until + the cursor moves to another cell. + ## 2026-10-27: t75 ping recharge, natural ore colour, glints (Claude Code) - 10 s recharge (`PING_RECHARGE`, `pingWait`) with a drill panel chip. `pingImage` draws veins in diff --git a/src/styles/style.css b/src/styles/style.css index 86162c2..9a1c246 100644 --- a/src/styles/style.css +++ b/src/styles/style.css @@ -29,8 +29,7 @@ body { font-family: var(--font-ui); font-size: calc(13.5px * var(--ui)); line-height: 1.4; -webkit-user-select: none; user-select: none; touch-action: none; } -canvas#game { position: fixed; inset: 0; width: 100vw; height: 100vh; display: block; image-rendering: pixelated; cursor: crosshair; } -canvas#game.nocursor { cursor: none; } +canvas#game { position: fixed; inset: 0; width: 100vw; height: 100vh; display: block; image-rendering: pixelated; cursor: none; } /* the game draws its own aim */ /* overlay modes (thermal lens, info overlay): a coloured frame with corner brackets, a light wash for the info overlay so the world stays clear, and a named badge at the bottom of the screen */ #ovframe { position: fixed; inset: 0; pointer-events: none; opacity: 0; transition: opacity 0.2s; --ov: 92, 186, 166; } diff --git a/src/ui/gamepad.js b/src/ui/gamepad.js index c2382be..28910f3 100644 --- a/src/ui/gamepad.js +++ b/src/ui/gamepad.js @@ -10,7 +10,7 @@ function pollPad() { const ax = v => Math.abs(v) < dz ? 0 : (v - Math.sign(v) * dz) / (1 - dz); const lx = ax(gp.axes[0] || 0), ly = ax(gp.axes[1] || 0), rx = ax(gp.axes[2] || 0), ry = ax(gp.axes[3] || 0); const pressedAny = gp.buttons.some(b => b && b.pressed) || lx || ly || rx || ry; - if (pressedAny && !GAME.usingPad) { GAME.usingPad = true; canvas.classList.add('nocursor'); } + if (pressedAny) GAME.usingPad = true; const modal = topModal(); if (modal || !GAME.running) { const now = performance.now(); diff --git a/src/ui/input.js b/src/ui/input.js index c216abc..1e419c9 100644 --- a/src/ui/input.js +++ b/src/ui/input.js @@ -49,7 +49,7 @@ window.addEventListener('keydown', e => { }); window.addEventListener('keyup', e => { const k = e.key.length === 1 ? e.key.toLowerCase() : e.key; keys.delete(k); if ((k === 'Control' || k === 'Meta') && GAME.ctrl) { GAME.ctrl = false; lastBagKey = ''; hudDirty = true; } if (k === 'g') { GAME.replace = false; hudDirty = true; } if (k === 'c' || k === 'x') hudDirty = true; }); window.addEventListener('blur', () => { keys.clear(); if (GAME.ctrl) { GAME.ctrl = false; lastBagKey = ''; hudDirty = true; } GAME.lmb = GAME.rmb = false; GAME.replace = false; GAME.selDrag = null; endRmbRecord(); }); -canvas.addEventListener('mousemove', e => { GAME.mouse.x = e.clientX; GAME.mouse.y = e.clientY; GAME.mouse.in = true; if (GAME.usingPad) { GAME.usingPad = false; canvas.classList.remove('nocursor'); } }); +canvas.addEventListener('mousemove', e => { GAME.mouse.x = e.clientX; GAME.mouse.y = e.clientY; GAME.mouse.in = true; GAME.usingPad = false; }); canvas.addEventListener('mouseleave', () => { GAME.mouse.in = false; }); canvas.addEventListener('contextmenu', e => e.preventDefault()); canvas.addEventListener('mousedown', e => {