Commit Graph

45 Commits

Author SHA1 Message Date
Steven Wroblewski c2edaf2761 feat(nav): add GameState.set_current_room and AudioManager.DEFAULT_MUSIC_VOLUME 2026-05-10 20:53:25 +02:00
Steven Wroblewski 2e0cd18b6e feat(audio): wire SFX into HoldableItem and OutfitItem 2026-05-10 20:19:40 +02:00
Steven Wroblewski a220b641ca feat(audio): add tap handler and SFX to RoomChest
Adds _get_press_position helper and _unhandled_input tap detection to
RoomChest, wires AudioManager.play_sfx calls for chest_tap and
item_spawn events. Guards AudioManager audio load calls with Dummy
driver check so headless unit tests stay green.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 20:18:16 +02:00
Steven Wroblewski bad2fbe65f feat(audio): add AudioManager with floor music cross-fade and SFX
Replaces placeholder AudioManager with full implementation: floor-based
music routing via _derive_floor_from_room, cross-fade tween between
AudioStreamPlayers, SFX event-key dispatch, and room-change guard to
prevent redundant load attempts. 11 new tests (207 total, 206 passing).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 20:14:10 +02:00
Steven Wroblewski a877d8f5fe feat(rooms): add RoomChest nodes to Floor 0 rooms
ReceptionDesk, GiftShopShelf, RestaurantCounter, EmergencyCabinet added
to their respective tscn files. Fixes spawn_items deferred call to avoid
add_child race during _ready tree setup.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 01:16:15 +02:00
Steven Wroblewski 87db92955a fix(items): safe cast in _try_return_to_chest, typed chest state param, object_states reset
- Replace unsafe direct cast in HoldableItem._try_return_to_chest() with guarded as-cast
- Type set_chest_state() parameter as Array[String] to match RoomChest._get_spawned_ids()
- Add else-branch in apply_save_data() to reset _object_states when key absent
- Rename test_save_data_has_version_two to test_save_data_has_version_three
2026-05-09 01:12:29 +02:00
Steven Wroblewski 96ec053331 feat(items): add chest-return priority to HoldableItem and GameState v3 chest states
- HoldableItem._try_return_to_chest() snaps item back if within CHEST_RETURN_RADIUS (80px)
- _on_drag_released checks chest return before hand-slot fallback
- OutfitItem._on_drag_released checks chest return before outfit/hand-slot logic
- GameState: _chest_states dict + get/set/clear_chest_state methods
- GameState.get_save_data() bumped to version 3, includes chest_states
- GameState.apply_save_data() restores chest_states from save data
2026-05-09 01:09:47 +02:00
Steven Wroblewski 4f1766834a refactor(items): strengthen RoomChest types, guard receive_item, expose get_spawned_item 2026-05-09 01:07:16 +02:00
Steven Wroblewski b9c73b80ea feat(items): add RoomChest with spawn and receive logic
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 01:04:34 +02:00
Steven Wroblewski 4e4743f14f refactor(items): use ItemType enum and offset constants in ChestItemData/RoomChestConfig
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 01:01:50 +02:00
Steven Wroblewski b97b110876 feat(items): add ChestItemData resource and RoomChestConfig static config
TDD: 4 tests written first (FAIL), then implemented — all 151 tests pass.
2026-05-09 00:58:32 +02:00
Steven Wroblewski c1df40361a feat(items): add OutfitItem, tap-to-undress, and outfit refs on Character
- Add OutfitItem (extends HoldableItem): applies outfit on drop within 80px
  of character body, falls back to hand slot attach if no character in range
- Add apply_outfit_item / remove_outfit / _handle_outfit_tap to Character
- Track item node refs in _outfit_item_refs for restoring visibility
- Fix animation state: reset to idle before tap handling in _on_drag_released
- Extract _ITEM_DROP_OFFSET constant (replaces magic Vector2(0,60))
- Add 5 tests in test_outfit_item.gd, 14 new tests in test_character_v2.gd
2026-05-09 00:19:15 +02:00
Steven Wroblewski 07c3b996d7 feat(save): extend GameState to v2 — outfit and held items persisted per character
- Add held_left/held_right fields to CharacterData
- Add get/set_character_outfit and get/set_character_held_item to GameState
- get_save_data now returns version:2 with character_outfits and character_held_items
- apply_save_data resets both dicts when keys absent (empty-dict reset safe)
- 11 new tests in test_game_state.gd — 147/147 passing
2026-05-09 00:12:33 +02:00
Steven Wroblewski ca1d20781e feat(items): add HoldableItem with hand slot detection, fix detach_item position
- Character registers in "characters" group on _ready for group scanning
- detach_item saves/restores global_position after reparenting
- New HoldableItem base class: scans "characters" group on drag_released,
  attaches to nearest free hand within 60px radius, detaches on pickup

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 00:03:25 +02:00
Steven Wroblewski 2f5e9d99a6 feat(snap-receiver): implement snap detection, position snapping, and pose animation trigger
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 22:12:18 +02:00
Steven Wroblewski 60fba44316 feat(character): add hand slot API (attach/detach/get_held_item/is_hand_free) 2026-05-08 22:09:56 +02:00
Steven Wroblewski 1a9d916293 feat(character): add outfit layer API (set/clear/get_outfit per layer 1-3) 2026-05-08 22:07:53 +02:00
Steven Wroblewski 9be67c8dfe feat(character): add animation state API (set/get_animation_state) 2026-05-08 22:02:59 +02:00
Steven Wroblewski 15ac8666f8 feat(character-data): add outfit array field for three outfit layer slots 2026-05-08 22:01:18 +02:00
Steven Wroblewski 80cecf732d feat(snap-receiver): add SnapReceiver stub (full implementation in sprint-15 task 8) 2026-05-08 21:57:47 +02:00
Steven Wroblewski cc5f205a7e feat(snap-point): add SnapPoint node with pose, baby_only filter, and occupant tracking
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 21:56:50 +02:00
Steven Wroblewski a4620a7f14 feat(teapot): add TeaPot with tap-to-pour tilt animation 2026-04-17 21:23:03 +02:00
Steven Wroblewski da3c934e5d feat(gift-box): add GiftBox with tap-to-open lid animation and gift reveal 2026-04-17 21:21:39 +02:00
Steven Wroblewski 033d38887f fix(home-button): add busy guard against double-tap during navigation transition 2026-04-17 21:20:23 +02:00
Steven Wroblewski 1a5d7918ab feat(home-button): add HomeButton component for hospital/garden navigation 2026-04-17 21:18:52 +02:00
Steven Wroblewski e7d0036c61 fix(navigator): kill active tween before starting new navigation to prevent camera jitter 2026-04-17 21:17:58 +02:00
Steven Wroblewski 819f18b64c feat(navigator): add go_to_home / go_to_hospital with home_entered / hospital_entered signals 2026-04-17 21:16:07 +02:00
Steven Wroblewski 5ea3a52ed4 feat(nursery): add Cradle component with pendulum rocking animation 2026-04-17 16:31:49 +02:00
Steven Wroblewski dfdf40ba8d feat(delivery): add DeliveryBed component with mama-arrives baby-appears animation 2026-04-17 16:30:31 +02:00
Steven Wroblewski a94cf61b79 feat(ultrasound): add UltrasoundMachine component with continuous heartbeat animation 2026-04-17 16:29:10 +02:00
Steven Wroblewski 5f33e16165 feat(xray): add XRayMachine component with plate slide-in animation 2026-04-17 14:25:04 +02:00
Steven Wroblewski 045aa8c3b6 feat(ambulance): add Ambulance component with drive-in/out animation triggered by room navigation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 13:56:11 +02:00
Steven Wroblewski 130317b516 feat(navigation): add NavigationArrow component for within-floor room navigation 2026-04-17 13:51:32 +02:00
Steven Wroblewski 903df578e2 feat(navigation): extend RoomNavigator for horizontal room-within-floor navigation 2026-04-17 13:50:00 +02:00
Steven Wroblewski 2bb73c905c fix(ui): sync settings sliders to saved values when menu opens
show_menu() now calls set_value_no_signal() to reflect the current
GameState volume values without re-triggering value_changed handlers.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 13:28:57 +02:00
Steven Wroblewski 6bc199f6c1 fix(core): correct camera Y offset in RoomNavigator floor navigation
Floor N spans from N*-720 to (N-1)*-720. The camera must center at the
floor midpoint, so target_y = floor_index * -720 + 360 (half floor height).
Previous formula placed the camera at the floor boundary, showing content
split between two floors.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 13:26:03 +02:00
Steven Wroblewski f4611e2443 fix(core): serialize character positions as [x,y] arrays for JSON compatibility
Vector2 is not a JSON-native type — JSON.stringify converts it to a string,
which cannot be assigned back to a Vector2 return type on load. Positions are
now saved as [x, y] float arrays and reconstructed as Vector2 in apply_save_data.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 13:22:56 +02:00
Steven Wroblewski 22f4b23897 fix(objects): replace Area2D.input_event with _input() for reliable Android touch
Area2D.input_event is unreliable on Android with gl_compatibility renderer.
Switched to manual _input() hit detection using canvas_transform coordinate
conversion, consistent with the DragDropComponent approach already used in
this project.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 13:20:14 +02:00
Steven Wroblewski 51bfd1718b fix(core): enforce CharacterData compile order and remove ClassDB type lookup on export
character.gd referenced CharacterData.State as a compile-time constant dict,
causing export to fail when character.gd was compiled before character_data.gd
(alphabetical order). The preload forces character_data.gd to be compiled first.
Changing SubResource type to "Resource" removes the ClassDB lookup for the
custom class name during scene export, relying on the explicit script reference
instead.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 13:11:30 +02:00
Steven Wroblewski 19d1ec1fe5 fix(core): remove class_name from autoload scripts to prevent singleton conflict
Godot 4 throws "Class hides an autoload singleton" when a script declares
class_name with the same name as its registered autoload. Removed class_name
from AudioManager and RoomNavigator — both are accessible globally via their
autoload name without it. Also ignores Godot-generated *.uid files.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 12:44:31 +02:00
Steven Wroblewski 6b0c41bbfd fix(core): resolve review findings in Sprint 3-4
- Fix SaveManager reset_game to use DirAccess.remove correctly
- Add null check for FileAccess.open in save_game
- Fix AudioManager crossfade tween callback chain
- Replace fragile absolute HUD path with relative onready
- Guard character position save against empty id
- Add GameState.has_character_position helper
- Emit room_changed signal after tween completes
- Add target_floor validation in ElevatorButton
- Persist audio settings via GameState
- Add class_name to RoomNavigator, AudioManager, HUD

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 12:22:27 +02:00
Steven Wroblewski 13db45bb04 feat(core): implement room navigation, character states, save/load and settings menu
- RoomNavigator autoload: smooth camera pan between floors
- Floor1 and Floor2 placeholder rooms with elevator buttons
- CharacterData Resource with State enum (HEALTHY/SICK/SLEEPING/TIRED)
- Character visual state feedback via ColorRect color
- Main scene loads saved state on startup
- SettingsMenu with music/sfx sliders and game reset
- HUD settings button to open SettingsMenu

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 12:17:56 +02:00
Steven Wroblewski f7c8a7ec03 fix(poc): resolve evaluator and review findings
- Add RectangleShape2D to Character and InteractiveObject collision areas
- Fix HUD button signal connections in _ready()
- Fix character_placed signal emitting global_position
- Extract DEFAULT_DRAG_RADIUS constant in DragDropComponent
- Type Variant on JSON parsed variable in SaveManager
- Extract music symbol constants in HUD
- Refactor duplicated drag input code in InputManager

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 11:16:05 +02:00
Steven Wroblewski 9a1e30d808 feat(poc): implement Sprint 1 proof of concept
- project.godot with autoload configuration
- Reception room with placeholder visuals
- Draggable Character with DragDropComponent
- Interactive flower object with bounce animation
- GameState, SaveManager, AudioManager, InputManager autoloads
- HUD with back button and music toggle

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 11:16:04 +02:00
Steven Wroblewski d1b771ddcb chore: initialize project structure for Sprint 0 2026-04-17 10:23:48 +02:00