feat(sprint-20): RoomNavigator-GameState-AudioManager integration

This commit is contained in:
Steven Wroblewski
2026-05-10 20:55:34 +02:00
7 changed files with 106 additions and 9 deletions
+1
View File
@@ -3,6 +3,7 @@
extends Node extends Node
const CROSSFADE_DURATION: float = 0.8 const CROSSFADE_DURATION: float = 0.8
const DEFAULT_MUSIC_VOLUME: float = 0.6
const _MUSIC_MAP: Dictionary = { const _MUSIC_MAP: Dictionary = {
0: "res://assets/audio/music/floor_0.ogg", 0: "res://assets/audio/music/floor_0.ogg",
+5
View File
@@ -73,6 +73,11 @@ func clear_chest_state(chest_id: String) -> void:
state_changed.emit() state_changed.emit()
func set_current_room(room: String) -> void:
current_room = room
state_changed.emit()
func get_save_data() -> Dictionary: func get_save_data() -> Dictionary:
var positions: Dictionary = {} var positions: Dictionary = {}
for key: String in _character_positions: for key: String in _character_positions:
+1
View File
@@ -8,6 +8,7 @@ func _ready() -> void:
AudioManager.set_music_volume(GameState.music_volume) AudioManager.set_music_volume(GameState.music_volume)
AudioManager.set_sfx_volume(GameState.sfx_volume) AudioManager.set_sfx_volume(GameState.sfx_volume)
_apply_saved_state() _apply_saved_state()
RoomNavigator.go_to_room_by_name(GameState.current_room)
func _apply_saved_state() -> void: func _apply_saved_state() -> void:
+42 -6
View File
@@ -10,6 +10,21 @@ const ROOM_WIDTH: float = 1280.0
const HOME_CAMERA_X: float = 640.0 const HOME_CAMERA_X: float = 640.0
const HOME_CAMERA_Y: float = 1080.0 const HOME_CAMERA_Y: float = 1080.0
const CAMERA_TWEEN_DURATION: float = 0.6 const CAMERA_TWEEN_DURATION: float = 0.6
const HOME_ROOM_NAME: String = "garden_party"
const _ROOM_NAMES: Dictionary = {
Vector2i(0, 0): "reception",
Vector2i(0, 1): "giftshop",
Vector2i(0, 2): "restaurant",
Vector2i(0, 3): "emergency",
Vector2i(1, 0): "xray",
Vector2i(1, 1): "pharmacy",
Vector2i(1, 2): "lab",
Vector2i(1, 3): "patient_rooms",
Vector2i(2, 0): "ultrasound",
Vector2i(2, 1): "delivery_room",
Vector2i(2, 2): "nursery",
}
var _current_floor: int = 0 var _current_floor: int = 0
var _current_room: int = 0 var _current_room: int = 0
@@ -27,13 +42,16 @@ func go_to_floor(floor_index: int) -> void:
func go_to_room(floor_index: int, room_index: int) -> void: func go_to_room(floor_index: int, room_index: int) -> void:
if _camera == null:
return
if not _is_at_home and floor_index == _current_floor and room_index == _current_room: if not _is_at_home and floor_index == _current_floor and room_index == _current_room:
return return
_is_at_home = false _is_at_home = false
_current_floor = floor_index _current_floor = floor_index
_current_room = room_index _current_room = room_index
var room_name: String = _ROOM_NAMES.get(Vector2i(floor_index, room_index), "")
if not room_name.is_empty():
GameState.set_current_room(room_name)
if _camera == null:
return
var target_x: float = room_index * ROOM_WIDTH + ROOM_WIDTH * 0.5 var target_x: float = room_index * ROOM_WIDTH + ROOM_WIDTH * 0.5
var target_y: float = floor_index * -FLOOR_HEIGHT + FLOOR_HEIGHT * 0.5 var target_y: float = floor_index * -FLOOR_HEIGHT + FLOOR_HEIGHT * 0.5
if _active_tween != null: if _active_tween != null:
@@ -46,11 +64,12 @@ func go_to_room(floor_index: int, room_index: int) -> void:
func go_to_home() -> void: func go_to_home() -> void:
if _camera == null:
return
if _is_at_home: if _is_at_home:
return return
_is_at_home = true _is_at_home = true
GameState.set_current_room(HOME_ROOM_NAME)
if _camera == null:
return
if _active_tween != null: if _active_tween != null:
_active_tween.kill() _active_tween.kill()
_active_tween = create_tween() _active_tween = create_tween()
@@ -61,11 +80,14 @@ func go_to_home() -> void:
func go_to_hospital() -> void: func go_to_hospital() -> void:
if _camera == null:
return
if not _is_at_home: if not _is_at_home:
return return
_is_at_home = false _is_at_home = false
var room_name: String = _ROOM_NAMES.get(Vector2i(_current_floor, _current_room), "")
if not room_name.is_empty():
GameState.set_current_room(room_name)
if _camera == null:
return
var target_x: float = _current_room * ROOM_WIDTH + ROOM_WIDTH * 0.5 var target_x: float = _current_room * ROOM_WIDTH + ROOM_WIDTH * 0.5
var target_y: float = _current_floor * -FLOOR_HEIGHT + FLOOR_HEIGHT * 0.5 var target_y: float = _current_floor * -FLOOR_HEIGHT + FLOOR_HEIGHT * 0.5
if _active_tween != null: if _active_tween != null:
@@ -77,6 +99,20 @@ func go_to_hospital() -> void:
_active_tween.finished.connect(func() -> void: hospital_entered.emit()) _active_tween.finished.connect(func() -> void: hospital_entered.emit())
func go_to_room_by_name(room_name: String) -> void:
if room_name == HOME_ROOM_NAME:
go_to_home()
return
for key: Vector2i in _ROOM_NAMES:
if _ROOM_NAMES[key] == room_name:
go_to_room(key.x, key.y)
return
func get_room_name(floor_index: int, room_index: int) -> String:
return _ROOM_NAMES.get(Vector2i(floor_index, room_index), "")
func get_current_floor() -> int: func get_current_floor() -> int:
return _current_floor return _current_floor
+4
View File
@@ -69,3 +69,7 @@ func test_music_map_has_all_four_floors() -> void:
assert_true(AudioManager._MUSIC_MAP.has(1)) assert_true(AudioManager._MUSIC_MAP.has(1))
assert_true(AudioManager._MUSIC_MAP.has(2)) assert_true(AudioManager._MUSIC_MAP.has(2))
assert_true(AudioManager._MUSIC_MAP.has(3)) assert_true(AudioManager._MUSIC_MAP.has(3))
func test_default_music_volume_constant_is_0_6() -> void:
assert_eq(AudioManager.DEFAULT_MUSIC_VOLUME, 0.6)
+13
View File
@@ -181,3 +181,16 @@ func test_apply_save_data_restores_chest_state() -> void:
} }
GameState.apply_save_data(data) GameState.apply_save_data(data)
assert_eq(GameState.get_chest_state("reception_desk_test"), ["clipboard", "pen"]) assert_eq(GameState.get_chest_state("reception_desk_test"), ["clipboard", "pen"])
func test_set_current_room_updates_value() -> void:
GameState.set_current_room("xray")
assert_eq(GameState.current_room, "xray")
GameState.set_current_room("reception")
func test_set_current_room_emits_state_changed() -> void:
watch_signals(GameState)
GameState.set_current_room("pharmacy")
assert_signal_emitted(GameState, "state_changed")
GameState.set_current_room("reception")
+40 -3
View File
@@ -74,13 +74,13 @@ func test_go_to_floor_does_not_emit_if_already_on_floor_room_zero() -> void:
assert_signal_not_emitted(_nav, "room_changed") assert_signal_not_emitted(_nav, "room_changed")
func test_initialize_with_null_camera_prevents_state_update() -> void: func test_initialize_with_null_camera_still_updates_state() -> void:
var nav: Node = RoomNavigatorScript.new() var nav: Node = RoomNavigatorScript.new()
add_child_autofree(nav) add_child_autofree(nav)
nav.initialize(null) nav.initialize(null)
nav.go_to_room(1, 2) nav.go_to_room(1, 2)
assert_eq(nav.get_current_floor(), 0) assert_eq(nav.get_current_floor(), 1)
assert_eq(nav.get_current_room(), 0) assert_eq(nav.get_current_room(), 2)
func test_multiple_room_changes_update_state() -> void: func test_multiple_room_changes_update_state() -> void:
@@ -138,3 +138,40 @@ func test_go_to_room_after_home_clears_is_at_home() -> void:
_nav.go_to_home() _nav.go_to_home()
_nav.go_to_room(0, 0) _nav.go_to_room(0, 0)
assert_false(_nav.is_at_home()) assert_false(_nav.is_at_home())
func test_room_names_dict_has_eleven_entries() -> void:
assert_eq(RoomNavigator._ROOM_NAMES.size(), 11)
func test_get_room_name_floor0_room0_is_reception() -> void:
assert_eq(RoomNavigator.get_room_name(0, 0), "reception")
func test_get_room_name_floor0_room3_is_emergency() -> void:
assert_eq(RoomNavigator.get_room_name(0, 3), "emergency")
func test_get_room_name_floor1_room2_is_lab() -> void:
assert_eq(RoomNavigator.get_room_name(1, 2), "lab")
func test_get_room_name_floor2_room1_is_delivery_room() -> void:
assert_eq(RoomNavigator.get_room_name(2, 1), "delivery_room")
func test_get_room_name_unknown_returns_empty_string() -> void:
assert_eq(RoomNavigator.get_room_name(99, 0), "")
assert_eq(RoomNavigator.get_room_name(0, 99), "")
func test_go_to_room_by_name_garden_party_sets_is_at_home() -> void:
RoomNavigator.go_to_room_by_name("garden_party")
assert_true(RoomNavigator.is_at_home())
RoomNavigator._is_at_home = false
func test_go_to_room_by_name_unknown_is_noop() -> void:
var floor_before: int = RoomNavigator.get_current_floor()
RoomNavigator.go_to_room_by_name("nonexistent_room_xyz")
assert_eq(RoomNavigator.get_current_floor(), floor_before)