Improve opening battle pacing and objectives UI

This commit is contained in:
2026-06-19 13:32:05 +09:00
parent b9fb2dd79e
commit f69438e964
4 changed files with 352 additions and 56 deletions

View File

@@ -95,6 +95,7 @@ func _init() -> void:
_check_hud_focus_text(failures)
_check_ancient_ui_theme(failures)
_check_hover_intent_badges(failures)
_check_counter_attack_badge_variants(failures)
_check_action_button_disabled_reasons(failures)
_check_terrain_and_unit_presentation(failures)
_check_objective_and_status_marker_helpers(failures)
@@ -3085,19 +3086,24 @@ func _check_ancient_ui_theme(failures: Array[String]) -> void:
scene.free()
return
var briefing_text := scene._format_briefing_objectives()
for expected in ["승리 조건", "패배 조건", "보상"]:
scene.briefing_objective_label.text = briefing_text
scene._update_briefing_objective_visibility()
for expected in ["승리:", "패배:", "보상:"]:
if not briefing_text.contains(expected):
failures.append("briefing objective parchment should use Korean heading `%s`: %s" % [expected, briefing_text])
for clutter in ["진행", "위험"]:
for clutter in ["승리 조건", "패배 조건", "진행", "위험"]:
if briefing_text.contains(clutter):
failures.append("briefing objective parchment should stay concise without `%s`: %s" % [clutter, briefing_text])
var hud_objective := scene._format_objective_hud_text()
if not hud_objective.contains("승리:") or not hud_objective.contains("패배:"):
failures.append("HUD objective should use concise Korean labels: %s" % hud_objective)
var mission_text := scene._format_mission_panel_text()
for expected in ["승리 조건", "패배 조건", "진행", "위험", "목표|", "주의|", "현황|", "경고|"]:
for expected in ["승리:", "패배:", "진행:", "주의:"]:
if not mission_text.contains(expected):
failures.append("mission panel should use Korean campaign wording `%s`: %s" % [expected, mission_text])
for clutter in ["목표|", "주의|", "현황|", "경고|"]:
if mission_text.contains(clutter):
failures.append("mission panel should avoid old verbose marker `%s`: %s" % [clutter, mission_text])
_check_panel_style_fill(failures, scene.briefing_panel, "briefing panel", Color(0.54, 0.36, 0.14, 0.997))
_check_panel_style_frame(failures, scene.briefing_panel, "briefing panel", Color(0.035, 0.014, 0.008, 1.0), 16)
_check_panel_style_fill(failures, scene.briefing_objective_panel, "briefing objective edict panel", Color(0.67, 0.49, 0.24, 0.998))
@@ -3182,8 +3188,34 @@ func _check_ancient_ui_theme(failures: Array[String]) -> void:
failures.append("dialogue continue button should use the project serif font override")
if scene.mission_title_label == null or scene.mission_title_label.text != "전투 목표":
failures.append("mission panel title should use clear Korean wording")
if scene.briefing_start_button == null or scene.briefing_start_button.text != "닫고 전투 시작":
failures.append("briefing start button should clearly close the briefing")
if scene.mission_toggle_button == null or scene.mission_toggle_button.text != "접기":
failures.append("mission objective panel should expose a close control")
else:
scene._on_mission_toggle_pressed()
if scene.mission_detail_panel == null or scene.mission_detail_panel.visible or scene.mission_toggle_button.text != "보기":
failures.append("mission objective panel should collapse cleanly")
scene._on_mission_toggle_pressed()
if scene.mission_detail_panel == null or not scene.mission_detail_panel.visible or scene.mission_toggle_button.text != "접기":
failures.append("mission objective panel should reopen cleanly")
if scene.briefing_start_button == null or scene.briefing_start_button.text != "전투 시작":
failures.append("briefing start button should clearly start after briefing")
if scene.briefing_objective_toggle_button == null or scene.briefing_objective_toggle_button.text != "조건 접기":
failures.append("briefing objective panel should expose a collapse button")
else:
scene._set_briefing_objective_collapsed(true)
if scene.briefing_objective_panel == null or scene.briefing_objective_panel.visible or scene.briefing_objective_toggle_button.text != "조건 보기":
failures.append("briefing objective panel should collapse cleanly")
scene._set_briefing_objective_collapsed(false)
if scene.briefing_objective_panel == null or not scene.briefing_objective_panel.visible or scene.briefing_objective_toggle_button.text != "조건 접기":
failures.append("briefing objective panel should reopen cleanly")
scene.briefing_panel.visible = true
scene.battle_started = false
var escape_event := InputEventKey.new()
escape_event.keycode = KEY_ESCAPE
scene._handle_key(escape_event)
if not scene.briefing_objective_collapsed or scene.battle_started:
failures.append("briefing Escape should collapse conditions before starting battle")
scene.briefing_panel.visible = false
if scene.shop_button == null or scene.shop_button.text != "군상":
failures.append("briefing shop button should use sutler wording")
if scene.talk_button == null or scene.talk_button.text != "군막 회의":
@@ -3212,8 +3244,8 @@ func _check_ancient_ui_theme(failures: Array[String]) -> void:
failures.append("targeting hint title should use mark foe wording")
if scene.targeting_hint_back_button == null or scene.targeting_hint_back_button.text != "죽간 거두기":
failures.append("targeting hint back button should use bamboo-slip wording")
scene._on_objective_updated("동문에 조서를 꽂아라.", "조조가 퇴각하면 패전이다.")
if scene.objective_notice_label == null or not scene.objective_notice_label.text.contains("목표") or not scene.objective_notice_label.text.contains("주의"):
scene._on_objective_updated("동문에 깃발을 세워라.", "조조가 퇴각하면 패전이다.")
if scene.objective_notice_label == null or not scene.objective_notice_label.text.contains("목표:") or not scene.objective_notice_label.text.contains("주의:"):
failures.append("objective update notice should use Korean annotation wording")
scene._update_briefing_camp_overview(scene.state.get_briefing(), false)
if scene.briefing_camp_overview_fallback_label == null or scene.briefing_camp_overview_fallback_label.text != "비단 전장도":
@@ -3492,6 +3524,10 @@ func _check_hover_intent_badges(failures: Array[String]) -> void:
var attack_badge := scene._target_preview_badge()
if attack_badge.is_empty() or str(attack_badge.get("kind", "")) == "move" or str(attack_badge.get("text", "")) == "행군":
failures.append("enemy hover should keep attack badge priority: %s" % str(attack_badge))
if not str(attack_badge.get("text", "")).contains(""):
failures.append("adjacent attack badge should expose counterattack risk: %s" % str(attack_badge))
if str(attack_badge.get("kind", "")) != "counter" and str(attack_badge.get("kind", "")) != "danger":
failures.append("counterable attack badge should use a counter danger color kind: %s" % str(attack_badge))
var cao_cao: Dictionary = scene.state.get_unit("cao_cao")
cao_cao["moved"] = true
@@ -3506,6 +3542,10 @@ func _check_hover_intent_badges(failures: Array[String]) -> void:
failures.append("MOVE badge should use a distinct color")
if scene._target_preview_badge_color("select") == default_color:
failures.append("SELECT badge should use a distinct color")
if scene._target_preview_badge_color("counter") == default_color:
failures.append("COUNTER badge should use a distinct color")
if scene._target_preview_badge_color("danger") == default_color:
failures.append("DANGER badge should use a distinct color")
var board_rect: Rect2 = scene._board_rect()
var edge_badge_rect: Rect2 = scene._target_preview_badge_rect(Vector2i(13, 9))
if edge_badge_rect.position.x < board_rect.position.x or edge_badge_rect.position.y < board_rect.position.y:
@@ -3517,6 +3557,60 @@ func _check_hover_intent_badges(failures: Array[String]) -> void:
scene.free()
func _check_counter_attack_badge_variants(failures: Array[String]) -> void:
var scene = BattleSceneScript.new()
if not scene.state.load_battle("res://data/scenarios/001_yellow_turbans.json"):
failures.append("could not load battle scene state for counter badge variants")
scene.free()
return
scene.battle_started = true
scene.state.select_unit("cao_cao")
var cao_cao: Dictionary = scene.state.get_unit("cao_cao")
var infantry: Dictionary = scene.state.get_unit("yellow_turban_2")
var archer: Dictionary = scene.state.get_unit("yellow_turban_3")
if cao_cao.is_empty() or infantry.is_empty() or archer.is_empty():
failures.append("counter badge variant smoke missing units")
scene.free()
return
infantry["pos"] = Vector2i(2, 3)
infantry["hp"] = 99
infantry["max_hp"] = 99
archer["pos"] = Vector2i(10, 8)
scene.hover_cell = Vector2i(2, 3)
var counter_badge := scene._target_preview_badge()
if str(counter_badge.get("kind", "")) != "counter" or not str(counter_badge.get("text", "")).contains(""):
failures.append("melee target should expose counter badge: %s" % str(counter_badge))
scene.basic_attack_targeting = true
scene._refresh_ranges()
var marker_entries := scene._attack_target_marker_entries()
if marker_entries.is_empty() or str(marker_entries[0].get("kind", "")) != "counter":
failures.append("attack target marker should carry counter kind: %s" % str(marker_entries))
scene.basic_attack_targeting = false
infantry["pos"] = Vector2i(10, 8)
archer["pos"] = Vector2i(2, 3)
archer["hp"] = 99
archer["max_hp"] = 99
scene.hover_cell = Vector2i(2, 3)
var no_counter_badge := scene._target_preview_badge()
if str(no_counter_badge.get("kind", "")) != "damage" or str(no_counter_badge.get("text", "")).contains(""):
failures.append("adjacent archer target should not expose counter badge: %s" % str(no_counter_badge))
archer["pos"] = Vector2i(10, 8)
infantry["pos"] = Vector2i(2, 3)
infantry["hp"] = 99
infantry["max_hp"] = 99
infantry["atk"] = 999
cao_cao["hp"] = 1
scene.hover_cell = Vector2i(2, 3)
var danger_badge := scene._target_preview_badge()
if str(danger_badge.get("kind", "")) != "danger" or not str(danger_badge.get("text", "")).contains("반격!"):
failures.append("lethal counter should expose danger badge: %s" % str(danger_badge))
scene.free()
func _check_terrain_and_unit_presentation(failures: Array[String]) -> void:
var scene = BattleSceneScript.new()
if not scene.state.load_battle("res://data/scenarios/001_yellow_turbans.json"):