diff --git a/README.md b/README.md index cb613c6..18a7f7c 100644 --- a/README.md +++ b/README.md @@ -131,7 +131,7 @@ Godot 4 tactical RPG prototype inspired by classic turn-based Romance of the Thr - Campaign completion screen. - New campaign save reset. - Manual campaign checkpoint save/load. -- Cinematic title screen uses a dedicated ancient-war-camp dawn backdrop, Cao Cao portrait art, and a compact left-side command board with `처음부터`, `로드하기`, and `환경설정`; new campaigns then move into a generated four-panel Yellow Turban rebellion, Cao Cao resolve, Xiahou Dun meeting, and Yingchuan contact prologue with full-screen story artwork, a chapter seal, a highlighted four-beat story strip, and a bottom scroll caption panel. Title and in-game settings expose clearer background-music, combat-SFX, and edge-scroll controls, include one-click audio recovery, and persist preferences in `user://heros_settings.json`. +- Cinematic title screen uses a dedicated ancient-war-camp dawn backdrop, Cao Cao portrait art, and a compact left-side command board with `처음부터`, `로드하기`, and `환경설정`; new campaigns then move into a generated four-panel Yellow Turban rebellion, Cao Cao resolve, Xiahou Dun meeting, and Yingchuan contact prologue with full-screen story artwork, a chapter seal, a highlighted four-beat story strip, and a bottom scroll caption panel. Title and in-game settings expose clearer background-music, combat-SFX, edge-scroll, and fullscreen display controls, include one-click audio recovery, and persist preferences in `user://heros_settings.json`. - Victory and defeat result overlay. - Dialogue portrait slot stays fixed across speaker and narration lines, with officer default image paths, optional per-line overrides, and speaker-initial or record fallback. - Initial AI-generated photorealistic officer portraits for Cao Cao, Xiahou Dun, Xiahou Yuan, Cao Ren, Dian Wei, Guo Jia, and Zhang He. diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 377151f..b8d64a9 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -56,7 +56,7 @@ `BattleState` owns tactical runtime fields. `CampaignState` saves only campaign-facing data: completed scenario ids, gold, inventory counts, joined officers, campaign flags, and a player roster snapshot. It does not save map positions, pre-battle Roster/Formation choices, action flags, temporary status effects, or transient battle occupancy. -Presentation preferences are separate from campaign progression. `BattleScene` reads and writes `user://heros_settings.json` for BGM/SFX toggles, BGM/SFX volume percentages, and edge-scroll preference, exposing the same values through the title settings menu and the top in-game toolbar settings panel. Both settings surfaces include a one-click audio recovery control that re-enables BGM/SFX, restores audible default volumes, and plays an immediate confirmation cue. These values apply to menu and battle audio playback without mutating `CampaignState`. +Presentation preferences are separate from campaign progression. `BattleScene` reads and writes `user://heros_settings.json` for BGM/SFX toggles, BGM/SFX volume percentages, edge-scroll preference, and fullscreen display preference, exposing the same values through the title settings menu and the top in-game toolbar settings panel. Both settings surfaces include a one-click audio recovery control that re-enables BGM/SFX, restores audible default volumes, and plays an immediate confirmation cue. These values apply to menu and battle audio playback plus window display mode without mutating `CampaignState`. Joined officers gate whether `requires_joined` player deployments are loaded at all. Rewards and post-battle choices can add or remove joined officers without deleting their saved roster snapshot, so a later rejoin can preserve progression. When a save loads, `CampaignState` scans completed scenarios in campaign order and reapplies only officer join/leave transitions from rewards and the saved `applied_post_battle_choices` ledger, allowing added recruitment rewards to reach older saves without replaying gold or items. Old saves without the ledger can backfill a choice id only when exactly one completed scenario choice matches saved flags. Roster entries are keyed by `officer_id` when available, so future scenarios can deploy the same joined officer under different scenario-specific `unit_id` values. Saved progression overlays final battle stats for now; a later equipment refactor should split base stats from equipment bonuses before adding item leveling or stat recalculation. New battles currently start player units healed to their saved maximum HP/MP. Skill access is carried in roster snapshots, with class defaults still applied for old saves that do not include skills. Promoted class ids are saved in the roster, and the next battle rehydrates class-derived movement, growth, skills, and range from the saved class id before equipment range is recalculated. diff --git a/scripts/scenes/battle_scene.gd b/scripts/scenes/battle_scene.gd index 7e47e85..9268d8d 100644 --- a/scripts/scenes/battle_scene.gd +++ b/scripts/scenes/battle_scene.gd @@ -3044,7 +3044,7 @@ func _create_hud() -> void: top_tool_row.add_child(battle_unit_list_button) top_settings_button = Button.new() - _configure_top_tool_button(top_settings_button, "TopSettingsButton", "settings", "환경 설정\n배경 음악, 전투 효과음, 가장자리 스크롤을 조절합니다.") + _configure_top_tool_button(top_settings_button, "TopSettingsButton", "settings", "환경 설정\n배경 음악, 전투 효과음, 가장자리 스크롤, 전체화면을 조절합니다.") top_settings_button.pressed.connect(_on_settings_pressed) top_tool_row.add_child(top_settings_button) @@ -4661,7 +4661,7 @@ func _create_hud() -> void: "TitleSettingsButton", "settings", "환경설정", - "소리와 전장 조작 옵션을 바꿉니다.", + "소리, 화면, 전장 조작 옵션을 바꿉니다.", Vector2(390, 58) ) title_settings_button.pressed.connect(_on_title_settings_pressed) @@ -13698,7 +13698,7 @@ func _update_settings_button() -> void: top_settings_button, "환경 설정", not can_show, - "배경 음악, 전투 효과음, 가장자리 스크롤을 조절합니다." if can_show else "타이틀 화면에서는 왼쪽 메뉴의 환경 설정을 사용합니다." + "배경 음악, 전투 효과음, 가장자리 스크롤, 전체화면을 조절합니다." if can_show else "타이틀 화면에서는 왼쪽 메뉴의 환경 설정에서 소리와 전체화면을 조절합니다." ) if not can_show: _hide_settings_panel() diff --git a/tools/smoke_title_menu.gd b/tools/smoke_title_menu.gd index 53a924c..32ddb3f 100644 --- a/tools/smoke_title_menu.gd +++ b/tools/smoke_title_menu.gd @@ -83,6 +83,8 @@ func _check_title_menu_start_load_and_settings(failures: Array[String]) -> void: var sampled_button := button_spec["button"] as Button if sampled_button != null: _check_button_texture_slice_fit(failures, sampled_button, str(button_spec["context"])) + if scene.top_settings_button == null or not str(scene.top_settings_button.tooltip_text).contains("전체화면"): + failures.append("top settings tooltip should mention fullscreen display control") if scene.title_portrait_texture_rect == null or scene.title_portrait_texture_rect.texture == null: failures.append("title screen should show Cao Cao portrait art") elif scene.title_portrait_texture_rect.material == null or not bool(scene.title_portrait_texture_rect.material.get_meta("title_portrait_feather_material", false)): @@ -161,6 +163,8 @@ func _check_title_menu_start_load_and_settings(failures: Array[String]) -> void: _check_title_command_fit(failures, scene.title_settings_button, "title settings") _check_title_button_text_contrast(failures, scene.title_settings_button, "title settings") _check_title_menu_button_art(failures, scene.title_settings_button, "settings", "title settings") + if not str(scene.title_settings_button.tooltip_text).contains("화면"): + failures.append("title settings tooltip should mention display settings") if scene.title_settings_back_button != null and scene.title_settings_back_button.visible: failures.append("title settings back command should stay hidden until settings are open")