Fix relative cursor lifecycle across rounds #75

Merged
cammymoop merged 2 commits from feature/relative-cursor-fixes into master 2026-03-05 11:30:58 -06:00
Collaborator

Summary

  • Sprite no longer visible after death: _input now guards on MOUSE_MODE_CAPTURED instead of is_instance_valid, preventing cursor_offset from tracking the real mouse after release
  • Second round now works: replaced get_first_node_in_group("player") with get_parent().get_parent().get_node("Player") so we always find the player in our own scene instance, not a stale node from the previous round still pending queue_free
  • Removed from "relative_cursor" group on death so player.gd cannot accidentally pick up the dead cursor on the first frame of a new round
  • Sprite hidden on death

Test plan

  • Headless run exits clean
  • gdlint passes
  • After dying, cursor sprite disappears and real mouse works in shop
  • Starting a second round captures mouse and shows cursor correctly
  • Dying in second round releases mouse again
## Summary - Sprite no longer visible after death: `_input` now guards on `MOUSE_MODE_CAPTURED` instead of `is_instance_valid`, preventing cursor_offset from tracking the real mouse after release - Second round now works: replaced `get_first_node_in_group("player")` with `get_parent().get_parent().get_node("Player")` so we always find the player in our own scene instance, not a stale node from the previous round still pending `queue_free` - Removed from `"relative_cursor"` group on death so player.gd cannot accidentally pick up the dead cursor on the first frame of a new round - Sprite hidden on death ## Test plan - [x] Headless run exits clean - [x] gdlint passes - [ ] After dying, cursor sprite disappears and real mouse works in shop - [ ] Starting a second round captures mouse and shows cursor correctly - [ ] Dying in second round releases mouse again
Three bugs fixed:

1. Sprite visible after death: _input was still running (only checked
   is_instance_valid, not mouse mode) and updating cursor_offset from
   real mouse motion, causing the sprite to track the real cursor.
   Guard changed to check MOUSE_MODE_CAPTURED instead.

2. Wrong player on second round: get_first_node_in_group("player")
   could return the old round's player, which is still in the tree
   when _ready runs (queue_free is deferred). Replaced with a direct
   scene-relative path lookup (get_parent().get_parent().get_node)
   which always resolves within the current scene instance.

3. Stale group entry: RelativeCursor stayed in "relative_cursor" group
   after death, so player.gd could get the dead cursor on the first
   frame of a new round. Now removed from the group in _on_player_died.
   Sprite is also hidden there so nothing is visible between rounds.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds systems/control_settings.gd as an autoload that reads
"global/default_cursor_mode_is_relative" from ProjectSettings on
startup into a public `relative_aim` bool. This can be overridden at
runtime before a round starts (e.g. from a future options menu).

RelativeCursor._ready() now checks ControlSettings.relative_aim first.
If disabled it hides its sprite and returns immediately without
capturing the mouse, joining the group, or connecting to the player.
Player.gd's existing fallback (absolute get_global_mouse_position)
then takes over automatically since the group will be empty.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
cammymoop merged commit 33e07921f9 into master 2026-03-05 11:30:58 -06:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
cammymoop/semi-vibed-game!75
No description provided.