All 22 placeholder 0-byte OGG files replaced with freesound.org previews
(128 kbps HQ OGG). All tracks are CC0. Includes Godot import sidecar files
(.ogg.import) for 11 files that had none previously.
Sprints 19, 21, 22 audio coverage complete.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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>
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>
Adds 11 empty .ogg placeholders (4 music tracks, 7 SFX) so the AudioManager
can reference them without errors during development. Includes docs/audio-assets-sprint19.md
with curated freesound.org download recommendations (CC0/CC-BY) for each file.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add UltrasoundCart, DeliveryCabinet, NurseryShelf, GardenTable, GardenStorage
chest nodes to their respective scenes. All 10 new tests pass (196 total).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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>
- 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
- 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
- HoldableItem: drag-and-drop base class, snaps to nearest free hand slot
- OutfitItem: extends HoldableItem, applies to character on drop, tap-to-undress
- Character: hand slot API (attach/detach/is_free), outfit layer API, tap detection
- GameState v2: outfit and held items persisted per character in save data
- 147 tests passing
- 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