From fe86e646ed86861daa2588753ef761273bf5b53a Mon Sep 17 00:00:00 2001 From: Wickedness Date: Sat, 20 Jun 2026 01:30:47 +0900 Subject: [PATCH] Add Sishui camp dialogue bridge --- README.md | 1 + data/scenarios/002_sishui_gate.json | 20 ++++++++++++++++++++ tools/smoke_chapter_one_polish.gd | 16 ++++++++++++++++ tools/smoke_visual_assets.gd | 3 +++ 4 files changed, 40 insertions(+) diff --git a/README.md b/README.md index 17b0ff1..07dc994 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ Godot 4 tactical RPG prototype inspired by classic turn-based Romance of the Thr - Pre-battle Talk can list scenario camp conversations by officer or topic with portrait rows, compact topic/supply badges, hover dialogue previews, saved-branch filtering, one-time pre-battle supplies, and merchant flavor lines before a battle. - The opening battle's camp now includes a villager route report that frames the castle, village recovery point, and enemy approach before combat starts. - The opening victory dialogue now bridges Xiahou Yuan and Cao Ren's join into the Sishui Gate march against Hua Xiong. +- Sishui Gate now opens with camp dialogue that turns the coalition briefing into a spoken march order. - Pre-battle Armory equipment changes, including unequipping gear back into stock, save immediately and sync roster equipment plus inventory stock, with portrait and item-icon rows plus hover change details. - Pre-battle Roster can move optional officers between sortie and reserve within scenario limits, using portrait rows, compact status badges, and hover details. - Pre-battle Formation lets deployed officers swap starting positions inside scenario-defined cells, with portrait rows, coordinate badges, and hover placement instructions. diff --git a/data/scenarios/002_sishui_gate.json b/data/scenarios/002_sishui_gate.json index 2e3ee76..2633784 100644 --- a/data/scenarios/002_sishui_gate.json +++ b/data/scenarios/002_sishui_gate.json @@ -33,6 +33,26 @@ "조조는 작은 선봉을 이끌고 화웅의 진을 먼저 시험하려 한다.", "서남쪽 마을과 관문 안쪽 성채를 차지하면 병력을 고칠 수 있으나, 화웅의 후속 원군이 뒤따른다." ], + "camp_dialogue": [ + { + "speaker": "Cao Cao", + "display_speaker": "조조", + "side": "left", + "text": "영천의 불길은 껐으나 사수관 아래 제후의 군막은 아직 말뿐이다. 화웅이 관문 앞을 막는 동안 머뭇거리면 동탁은 더 깊이 숨는다." + }, + { + "speaker": "Xiahou Yuan", + "display_speaker": "하후연", + "side": "right", + "text": "그렇다면 선봉을 세우십시오. 능선의 궁수와 관문 앞 보병을 먼저 흔들어 화웅의 칼끝이 어디를 향하는지 드러내겠습니다." + }, + { + "speaker": "Cao Ren", + "display_speaker": "조인", + "side": "right", + "text": "제가 뒤따르는 병력을 묶겠습니다. 마을과 성채를 거점으로 삼으면 선봉이 오래 버틸 수 있습니다." + } + ], "camp_conversations": [ { "id": "sishui_coalition_reading", diff --git a/tools/smoke_chapter_one_polish.gd b/tools/smoke_chapter_one_polish.gd index a76ffd7..a1573c7 100644 --- a/tools/smoke_chapter_one_polish.gd +++ b/tools/smoke_chapter_one_polish.gd @@ -28,6 +28,7 @@ func _init() -> void: _check_event_dialogue_side_passthrough(failures) _check_opening_battle_camp_context(failures) _check_opening_battle_post_battle_bridge(failures) + _check_sishui_gate_camp_context(failures) _check_opening_battle_event_dialogue_structure(failures) _check_sishui_gate_event_dialogue_structure(failures) _check_xingyang_ambush_event_dialogue_structure(failures) @@ -676,6 +677,21 @@ func _check_opening_battle_post_battle_bridge(failures: Array[String]) -> void: failures.append("opening post-battle bridge should mention %s: %s" % [expected, bridge_text]) +func _check_sishui_gate_camp_context(failures: Array[String]) -> void: + var state = BattleStateScript.new() + if not state.load_battle("res://data/scenarios/002_sishui_gate.json"): + failures.append("could not load Sishui Gate for camp context") + return + var briefing: Dictionary = state.get_briefing() + var camp_dialogue: Array = briefing.get("camp_dialogue", []) + if camp_dialogue.size() < 3: + failures.append("Sishui Gate should open with camp dialogue before the second battle") + var camp_text := _dialogue_lines_text(camp_dialogue) + for expected in ["사수관", "화웅", "하후연", "조인", "마을", "성채"]: + if not camp_text.contains(expected): + failures.append("Sishui Gate camp dialogue should mention %s: %s" % [expected, camp_text]) + + func _check_opening_battle_event_dialogue_structure(failures: Array[String]) -> void: var state = BattleStateScript.new() if not state.load_battle("res://data/scenarios/001_yellow_turbans.json"): diff --git a/tools/smoke_visual_assets.gd b/tools/smoke_visual_assets.gd index a7b1259..f9d9746 100644 --- a/tools/smoke_visual_assets.gd +++ b/tools/smoke_visual_assets.gd @@ -183,6 +183,9 @@ func _check_battle_visual_data(failures: Array[String]) -> void: else: _check_unit_sprite_resolution(failures, gate_state, "hua_xiong_vanguard", "res://art/units/enemies/enemy_cavalry.png", true) var gate_briefing := gate_state.get_briefing() + var gate_camp_dialogue: Array = gate_briefing.get("camp_dialogue", []) + if gate_camp_dialogue.size() < 3 or not str(gate_camp_dialogue).contains("사수관") or not str(gate_camp_dialogue).contains("화웅"): + failures.append("002 briefing should expose camp dialogue that bridges Sishui Gate context") var gate_conversations: Array = gate_briefing.get("camp_conversations", []) if gate_conversations.size() < 3: failures.append("002 briefing should expose at least three camp conversations")