Clarify opening and battle start cues
This commit is contained in:
@@ -650,6 +650,7 @@ var recent_sfx_keys: Array[String] = []
|
||||
var last_announced_battle_status := ""
|
||||
var floating_texts: Array[Dictionary] = []
|
||||
var objective_notice_timer := 0.0
|
||||
var battle_start_notice_pending := false
|
||||
var unit_motion_by_unit: Dictionary = {}
|
||||
var unit_action_motion_by_unit: Dictionary = {}
|
||||
var battle_presentation_sequence_active := false
|
||||
@@ -2676,7 +2677,7 @@ func _make_opening_story_beat_card(page: Dictionary, index: int, is_current: boo
|
||||
card_style.content_margin_right = 5
|
||||
card_style.content_margin_top = 4
|
||||
card_style.content_margin_bottom = 3
|
||||
card.modulate = Color(1.0, 1.0, 1.0, 1.0) if is_current else Color(0.56, 0.55, 0.50, 0.88)
|
||||
card.modulate = Color(1.0, 1.0, 1.0, 1.0) if is_current else Color(0.72, 0.70, 0.64, 0.94)
|
||||
|
||||
var column := VBoxContainer.new()
|
||||
column.custom_minimum_size = Vector2(126, 66)
|
||||
@@ -2692,7 +2693,7 @@ func _make_opening_story_beat_card(page: Dictionary, index: int, is_current: boo
|
||||
|
||||
var seal := _make_seal_tile("%d" % (index + 1), 18)
|
||||
seal.name = "OpeningStoryBeatSeal"
|
||||
seal.modulate = Color(1.0, 1.0, 1.0, 1.0) if is_current else Color(0.70, 0.68, 0.62, 0.90)
|
||||
seal.modulate = Color(1.0, 1.0, 1.0, 1.0) if is_current else Color(0.92, 0.87, 0.74, 0.96)
|
||||
title_row.add_child(seal)
|
||||
|
||||
var label := Label.new()
|
||||
@@ -2703,7 +2704,9 @@ func _make_opening_story_beat_card(page: Dictionary, index: int, is_current: boo
|
||||
label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
||||
label.clip_text = true
|
||||
label.tooltip_text = tooltip
|
||||
_apply_label_style(label, UI_PARCHMENT_TEXT if is_current else UI_OLD_BRONZE, 9)
|
||||
var label_color := UI_TITLE_TEXT if is_current else UI_TITLE_MUTED_TEXT
|
||||
_apply_label_style(label, label_color, 10 if is_current else 9)
|
||||
_apply_strong_text_legibility(label, label_color, 10 if is_current else 9)
|
||||
title_row.add_child(label)
|
||||
|
||||
var image_frame := PanelContainer.new()
|
||||
@@ -11003,6 +11006,34 @@ func _on_objective_updated(victory: String, defeat: String) -> void:
|
||||
_show_command_notice("군령 갱신", _join_strings(body_lines, "\n"))
|
||||
|
||||
|
||||
func _show_battle_start_notice_if_ready() -> void:
|
||||
if not battle_start_notice_pending or _is_dialogue_visible():
|
||||
return
|
||||
battle_start_notice_pending = false
|
||||
_show_command_notice("전투 개시", _format_battle_start_notice_body())
|
||||
|
||||
|
||||
func _format_battle_start_notice_body() -> String:
|
||||
var lines: Array[String] = []
|
||||
var progress_lines := state.get_objective_progress_lines(false, false)
|
||||
if not progress_lines.is_empty():
|
||||
lines.append("목표: %s" % _short_preview_text(_join_strings(progress_lines, " · "), 52))
|
||||
else:
|
||||
var victory := str(state.objectives.get("victory", "")).strip_edges()
|
||||
if not victory.is_empty():
|
||||
lines.append("목표: %s" % _short_preview_text(victory, 52))
|
||||
var risk_lines := state.get_defeat_progress_lines()
|
||||
if not risk_lines.is_empty():
|
||||
lines.append("주의: %s" % _short_preview_text(_join_strings(risk_lines, " · "), 42))
|
||||
else:
|
||||
var defeat := str(state.objectives.get("defeat", "")).strip_edges()
|
||||
if not defeat.is_empty():
|
||||
lines.append("주의: %s" % _short_preview_text(defeat, 42))
|
||||
if lines.is_empty():
|
||||
lines.append("목표를 확인하고 첫 군령을 내리십시오.")
|
||||
return _join_strings(lines, "\n")
|
||||
|
||||
|
||||
func _show_command_notice(title: String, body: String) -> void:
|
||||
var notice_lines := [title]
|
||||
var normalized_body := body.strip_edges()
|
||||
@@ -11638,9 +11669,10 @@ func _advance_dialogue() -> void:
|
||||
_render_dialogue_line()
|
||||
return
|
||||
_hide_dialogue_panel()
|
||||
if _can_show_dialogue_now():
|
||||
if _can_show_dialogue_now() and not dialogue_queue.is_empty():
|
||||
_show_next_dialogue()
|
||||
else:
|
||||
_show_battle_start_notice_if_ready()
|
||||
_update_hud()
|
||||
queue_redraw()
|
||||
|
||||
@@ -11832,6 +11864,7 @@ func _on_restart_pressed() -> void:
|
||||
if log_box != null:
|
||||
log_box.clear()
|
||||
battle_started = false
|
||||
battle_start_notice_pending = false
|
||||
battle_result_applied = false
|
||||
battle_result_summary.clear()
|
||||
post_battle_dialogue_started = false
|
||||
@@ -11880,6 +11913,7 @@ func _load_scenario(scenario_id: String) -> void:
|
||||
push_error("Missing scenario path for %s." % active_scenario_id)
|
||||
return
|
||||
battle_started = false
|
||||
battle_start_notice_pending = false
|
||||
battle_result_applied = false
|
||||
battle_result_summary.clear()
|
||||
post_battle_dialogue_started = false
|
||||
@@ -12543,6 +12577,7 @@ func _on_begin_battle_pressed() -> void:
|
||||
|
||||
func _start_battle_from_briefing() -> void:
|
||||
battle_started = true
|
||||
battle_start_notice_pending = true
|
||||
_play_bgm("battle")
|
||||
if briefing_panel != null:
|
||||
briefing_panel.visible = false
|
||||
@@ -12558,6 +12593,7 @@ func _start_battle_from_briefing() -> void:
|
||||
state.run_battle_begin_events()
|
||||
_focus_board_on_player_deployment(true)
|
||||
_show_next_dialogue()
|
||||
_show_battle_start_notice_if_ready()
|
||||
_update_hud()
|
||||
queue_redraw()
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ func _init() -> void:
|
||||
_check_minimap_navigation_contract(failures)
|
||||
_check_map_focus_contract(failures)
|
||||
_check_battle_presentation_sequence_contract(failures)
|
||||
_check_battle_start_notice_sequence(failures)
|
||||
_check_readability_contract(failures)
|
||||
_check_korean_fallback_labels(failures)
|
||||
_check_dialogue_localization_and_side(failures)
|
||||
@@ -550,6 +551,33 @@ func _check_battle_presentation_sequence_contract(failures: Array[String]) -> vo
|
||||
scene.free()
|
||||
|
||||
|
||||
func _check_battle_start_notice_sequence(failures: Array[String]) -> void:
|
||||
var scene = BattleSceneScript.new()
|
||||
scene._ready()
|
||||
scene._load_scenario("001_yellow_turbans")
|
||||
scene._show_briefing()
|
||||
scene._start_battle_from_briefing()
|
||||
if not scene._is_dialogue_visible():
|
||||
failures.append("opening battle should begin with contextual dialogue before command notices")
|
||||
if scene.objective_notice_label != null and scene.objective_notice_label.text.contains("전투 개시"):
|
||||
failures.append("battle start notice should wait until opening dialogue is closed")
|
||||
var guard := 0
|
||||
while scene._is_dialogue_visible() and guard < 12:
|
||||
scene._advance_dialogue()
|
||||
guard += 1
|
||||
if scene._is_dialogue_visible():
|
||||
failures.append("opening battle dialogue should be advanceable during start notice test")
|
||||
if scene.objective_notice_panel == null or not scene.objective_notice_panel.visible:
|
||||
failures.append("battle start should show a compact tactical command notice after dialogue")
|
||||
elif scene.objective_notice_label == null or not scene.objective_notice_label.text.contains("전투 개시"):
|
||||
failures.append("battle start notice should use a clear Korean title: %s" % ("" if scene.objective_notice_label == null else scene.objective_notice_label.text))
|
||||
elif not scene.objective_notice_label.text.contains("목표:") or not scene.objective_notice_label.text.contains("주의:"):
|
||||
failures.append("battle start notice should summarize objective and risk: %s" % scene.objective_notice_label.text)
|
||||
if scene.objective_notice_icon_strip == null or scene.objective_notice_icon_strip.get_child_count() < 2:
|
||||
failures.append("battle start notice should use generated objective and warning icons")
|
||||
scene.free()
|
||||
|
||||
|
||||
func _check_readability_contract(failures: Array[String]) -> void:
|
||||
var scene = BattleSceneScript.new()
|
||||
scene._create_hud()
|
||||
|
||||
@@ -259,6 +259,8 @@ func _check_title_menu_start_load_and_settings(failures: Array[String]) -> void:
|
||||
failures.append("opening story beat artwork should stay readable in the strip: %s" % str(beat_image.custom_minimum_size))
|
||||
if beat_label == null or beat_label.text.strip_edges().is_empty():
|
||||
failures.append("opening story beat card should name its scene")
|
||||
elif beat_label.get_theme_color("font_color").get_luminance() < 0.66 or beat_label.get_theme_constant("outline_size") < 3:
|
||||
failures.append("opening story beat label should remain readable over generated artwork: %s" % beat_label.text)
|
||||
if bool(card_node.get_meta("current_story_beat", false)):
|
||||
current_count += 1
|
||||
current_index = opening_story_cards.find(opening_story_card) + 1
|
||||
|
||||
Reference in New Issue
Block a user