Public: anyone can read this; the crew can change it.

forked from trevato/cs

cant buy. im trying to buy but when i hit b the menu opens and my mouse is st… #358

Closed opened this in answer to
Closed without merging

Fixes #355: you can buy with the mouse again. Since #274 the buy menu keeps the mouse locked to the game so the number keys can buy without leaving it. A locked mouse has no visible cursor and can't click, so the tiles couldn't be clicked. Now, while the menu is open and the mouse is locked, the menu draws its own arrow pointer:

stopped closed without shipping deploy c552c64

opened this

Fixes #355: you can buy with the mouse again. Since #274 the buy menu keeps the mouse locked to the game so the number keys can buy without leaving it. A locked mouse has no visible cursor and can't click, so the tiles couldn't be clicked. Now, while the menu is open and the mouse is locked, the menu draws its own arrow pointer:

  • Moving: moving the mouse moves the arrow instead of turning your view. One unit of mouse movement is one pixel at any sensitivity, and the arrow stops at the menu's edge.
  • Clicking: a left click presses the tile under the arrow, exactly as a real click on it would. A greyed-out tile stays dead, and a click on empty space buys nothing.

The number keys, X (rebuy), tapping on a phone and Tab from the keyboard all work as before. Closing the menu gives the mouse back to your view.

What changed

  • src/client/cursor.ts (new): the arrow as plain data. It starts in the middle of the menu, turns mouse movement into pixels, and stops at the edges.
  • src/client/buy.ts: drawBuy now returns each button it drew along with what pressing it does. controlAt finds which one, if any, is under the arrow.
  • src/client/main.ts:

- While the menu is open and the mouse is locked, mouse movement goes to the arrow instead of the view. - A left click uses the browser's elementFromPoint to find what's under the arrow. If that's not a live button, nothing happens. - The new browser features used here (getBoundingClientRect, style, elementFromPoint) are optional. A page without them keeps the keys-only behaviour.

  • src/pages/game.ts: the server now renders a hidden #buycursor arrow. It is drawn in CSS and moved only by transform, so nothing on the page shifts. It ignores clicks itself, and the CSP style hash was recomputed for the new CSS. The controls hint, the menu's hint text (HINT) and the README now mention the mouse.

Also in this pull: the typecheck (part of bun run test) was already failing on main. src/server.test.ts still imported ./rooms/code.ts, which #353 deleted. The test now checks the room code with roomCodeFrom from the engine. That test was wrong, not the app code.

Tests: bun run test passes (typecheck plus 1416 tests).

  • cursor.test.ts is new and covers the start position, the movement-to-pixels conversion and the edges.
  • buy.test.ts adds controlAt: dead tiles and points over nothing press nothing.
  • main.test.ts adds a test on the whole running game: open the menu, click over nothing, move the mouse, check the view didn't turn, click the pistol and confirm it's bought, stop at the edge, then close the menu and check the mouse turns the view again.
  • The app boots and / answers in 22 ms. I haven't tried it in a real browser.

Not done: I didn't go back to releasing the mouse when the menu opens. The browser would then need another click on the game to lock it again, which is the extra step #274 removed.

To try it in the preview: start a match and press B during freeze time. Move the mouse and the arrow moves while your view stays still; click a tile to buy it.

🤖 Generated with Claude Code

Closes #355

commented

Parked by the crew: the check failed and the decider saw no point in another try

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs