Improve battle notice marker chips
This commit is contained in:
@@ -169,7 +169,7 @@ const TITLE_MENU_ICON_MAX_WIDTH := 42
|
||||
const OPENING_STORY_PROGRESS_CARD_SIZE := Vector2(50, 24)
|
||||
const OPENING_STORY_PROGRESS_KNOT_SIZE := Vector2(18, 18)
|
||||
const COMMAND_NOTICE_ICON_SIZE := Vector2(32, 32)
|
||||
const COMMAND_NOTICE_MAX_ICONS := 4
|
||||
const COMMAND_NOTICE_MAX_ICONS := 5
|
||||
const CHAPTER_SEAL_BADGE_SIZE := Vector2(54, 54)
|
||||
const CHAPTER_SCENARIO_THUMBNAIL_SIZE := Vector2(72, 50)
|
||||
const CHAPTER_INFO_BADGE_SIZE := Vector2(86, 22)
|
||||
@@ -11220,18 +11220,15 @@ func _command_notice_icon_entries(title: String, body: String) -> Array[Dictiona
|
||||
var entries: Array[Dictionary] = []
|
||||
var seen := {}
|
||||
var combined_text := "%s\n%s" % [title, body]
|
||||
if combined_text.contains("아군"):
|
||||
var is_player_turn_notice := title.contains("아군") or body.contains("아군 차례")
|
||||
var is_enemy_turn_notice := title.contains("적군") or body.contains("적군 차례")
|
||||
if is_player_turn_notice:
|
||||
_append_command_notice_icon_entry(entries, seen, "toolbar", "move", "행군")
|
||||
_append_command_notice_icon_entry(entries, seen, "toolbar", "attack", "타격")
|
||||
_append_command_notice_icon_entry(entries, seen, "toolbar", "wait", "대기")
|
||||
elif combined_text.contains("적군"):
|
||||
elif is_enemy_turn_notice:
|
||||
_append_command_notice_icon_entry(entries, seen, "toolbar", "threat", "적세")
|
||||
_append_command_notice_icon_entry(entries, seen, "toolbar", "forecast", "예측")
|
||||
if combined_text.contains("증원") or combined_text.contains("잔병") or combined_text.contains("약탈대") or combined_text.contains("잔당") or combined_text.contains("반격"):
|
||||
_append_command_notice_icon_entry(entries, seen, "toolbar", "threat", "적세")
|
||||
_append_command_notice_icon_entry(entries, seen, "toolbar", "status", "주의")
|
||||
if combined_text.contains("경계") or combined_text.contains("표적") or combined_text.contains("노린다") or combined_text.contains("시선"):
|
||||
_append_command_notice_icon_entry(entries, seen, "toolbar", "threat", "적세")
|
||||
if combined_text.contains("목표") or combined_text.contains("성채") or combined_text.contains("깃발"):
|
||||
_append_command_notice_icon_entry(entries, seen, "badge", "objective", "목표")
|
||||
if combined_text.contains("유인"):
|
||||
@@ -11242,10 +11239,19 @@ func _command_notice_icon_entries(title: String, body: String) -> Array[Dictiona
|
||||
_append_command_notice_icon_entry(entries, seen, "badge", "recover", "회복")
|
||||
if combined_text.contains("군자금"):
|
||||
_append_command_notice_icon_entry(entries, seen, "badge", "gold", "군자금")
|
||||
if combined_text.contains("증원") or combined_text.contains("잔병") or combined_text.contains("약탈대") or combined_text.contains("잔당") or combined_text.contains("반격"):
|
||||
_append_command_notice_icon_entry(entries, seen, "toolbar", "threat", "적세")
|
||||
_append_command_notice_icon_entry(entries, seen, "toolbar", "status", "주의")
|
||||
if combined_text.contains("경계") or combined_text.contains("표적") or combined_text.contains("노린다") or combined_text.contains("시선"):
|
||||
_append_command_notice_icon_entry(entries, seen, "toolbar", "threat", "적세")
|
||||
if combined_text.contains("퇴각") or combined_text.contains("주의"):
|
||||
_append_command_notice_icon_entry(entries, seen, "toolbar", "status", "주의")
|
||||
if entries.is_empty():
|
||||
_append_command_notice_icon_entry(entries, seen, "badge", "event", "군령")
|
||||
for index in range(entries.size()):
|
||||
var entry := entries[index]
|
||||
entry["tooltip"] = _command_notice_icon_entry_tooltip(entry, title, body)
|
||||
entries[index] = entry
|
||||
return entries
|
||||
|
||||
|
||||
@@ -11265,9 +11271,11 @@ func _append_command_notice_icon_entry(entries: Array[Dictionary], seen: Diction
|
||||
|
||||
func _make_command_notice_icon_chip(entry: Dictionary) -> PanelContainer:
|
||||
var label_text := str(entry.get("label", "군령"))
|
||||
var tooltip_text := str(entry.get("tooltip", label_text))
|
||||
var chip := PanelContainer.new()
|
||||
chip.name = "CommandNoticeIconChip"
|
||||
chip.custom_minimum_size = COMMAND_NOTICE_ICON_SIZE
|
||||
chip.tooltip_text = tooltip_text
|
||||
chip.mouse_filter = Control.MOUSE_FILTER_PASS
|
||||
_apply_panel_style(chip, "caption")
|
||||
var chip_style := chip.get_theme_stylebox("panel")
|
||||
@@ -11277,16 +11285,41 @@ func _make_command_notice_icon_chip(entry: Dictionary) -> PanelContainer:
|
||||
chip_style.content_margin_top = 2
|
||||
chip_style.content_margin_bottom = 2
|
||||
|
||||
chip.add_child(_make_command_notice_icon_art(entry, tooltip_text))
|
||||
_set_control_tree_tooltip(chip, tooltip_text)
|
||||
return chip
|
||||
|
||||
|
||||
func _make_command_notice_icon_art(entry: Dictionary, tooltip_text: String) -> Control:
|
||||
var stack := Control.new()
|
||||
stack.name = "CommandNoticeIconArt"
|
||||
stack.custom_minimum_size = COMMAND_NOTICE_ICON_SIZE
|
||||
stack.tooltip_text = tooltip_text
|
||||
stack.mouse_filter = Control.MOUSE_FILTER_PASS
|
||||
var source := str(entry.get("source", "toolbar"))
|
||||
if source == "badge":
|
||||
var marker_texture := _load_tile_marker_texture(_command_notice_tile_marker_key(str(entry.get("key", "event"))))
|
||||
if marker_texture != null:
|
||||
var marker_rect := TextureRect.new()
|
||||
marker_rect.name = "CommandNoticeTileMarkerImage"
|
||||
marker_rect.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
marker_rect.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
|
||||
marker_rect.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
|
||||
marker_rect.modulate = Color(1.0, 1.0, 1.0, 0.42)
|
||||
marker_rect.mouse_filter = Control.MOUSE_FILTER_PASS
|
||||
marker_rect.texture = marker_texture
|
||||
marker_rect.tooltip_text = tooltip_text
|
||||
stack.add_child(marker_rect)
|
||||
var icon := TextureRect.new()
|
||||
icon.name = "CommandNoticeIconImage"
|
||||
icon.custom_minimum_size = COMMAND_NOTICE_ICON_SIZE
|
||||
icon.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
icon.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
|
||||
icon.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
|
||||
icon.mouse_filter = Control.MOUSE_FILTER_PASS
|
||||
icon.texture = _command_notice_icon_texture(entry)
|
||||
chip.add_child(icon)
|
||||
_set_control_tree_tooltip(chip, label_text)
|
||||
return chip
|
||||
icon.tooltip_text = tooltip_text
|
||||
stack.add_child(icon)
|
||||
return stack
|
||||
|
||||
|
||||
func _command_notice_icon_texture(entry: Dictionary) -> Texture2D:
|
||||
@@ -11297,6 +11330,61 @@ func _command_notice_icon_texture(entry: Dictionary) -> Texture2D:
|
||||
return _make_toolbar_icon(key)
|
||||
|
||||
|
||||
func _command_notice_tile_marker_key(key: String) -> String:
|
||||
match key:
|
||||
"objective":
|
||||
return "objective"
|
||||
"tactic":
|
||||
return "target"
|
||||
"supply":
|
||||
return "recover"
|
||||
"recover":
|
||||
return "recover"
|
||||
"gold":
|
||||
return "select"
|
||||
_:
|
||||
return "select"
|
||||
|
||||
|
||||
func _command_notice_icon_entry_tooltip(entry: Dictionary, title: String, body: String) -> String:
|
||||
var label_text := str(entry.get("label", "군령"))
|
||||
var key := str(entry.get("key", "status"))
|
||||
var detail := ""
|
||||
match key:
|
||||
"objective":
|
||||
detail = _first_notice_body_line(body, ["목표", "성채", "깃발"])
|
||||
"status":
|
||||
detail = _first_notice_body_line(body, ["주의", "퇴각", "위험", "패"])
|
||||
"tactic":
|
||||
detail = _first_notice_body_line(body, ["유인", "표식"])
|
||||
"supply":
|
||||
detail = _first_notice_body_line(body, ["보급", "마을"])
|
||||
"recover":
|
||||
detail = _first_notice_body_line(body, ["회복", "마을"])
|
||||
"gold":
|
||||
detail = _first_notice_body_line(body, ["군자금"])
|
||||
"threat", "forecast":
|
||||
detail = _first_notice_body_line(body, ["적군", "증원", "잔병", "경계", "표적", "주의"])
|
||||
"move", "attack", "wait":
|
||||
detail = _first_notice_body_line(body, ["아군", "군령", "차례"])
|
||||
if detail.is_empty():
|
||||
detail = body.strip_edges()
|
||||
if detail.is_empty():
|
||||
detail = title.strip_edges()
|
||||
return "%s\n%s" % [label_text, _short_preview_text(detail, 110)]
|
||||
|
||||
|
||||
func _first_notice_body_line(body: String, keywords: Array[String]) -> String:
|
||||
for line in body.split("\n", false):
|
||||
var normalized_line := str(line).strip_edges()
|
||||
if normalized_line.is_empty():
|
||||
continue
|
||||
for keyword in keywords:
|
||||
if normalized_line.contains(keyword):
|
||||
return normalized_line
|
||||
return ""
|
||||
|
||||
|
||||
func _on_dialogue_requested(lines: Array) -> void:
|
||||
var normalized_lines := _normalized_dialogue_lines(lines)
|
||||
if normalized_lines.is_empty():
|
||||
|
||||
@@ -580,6 +580,12 @@ func _check_battle_start_notice_sequence(failures: Array[String]) -> void:
|
||||
failures.append("battle start notice should not expose raw grid coordinates: %s" % start_notice_text)
|
||||
if scene.objective_notice_icon_strip == null or scene.objective_notice_icon_strip.get_child_count() < 3:
|
||||
failures.append("battle start notice should use generated objective, warning, and marker icons")
|
||||
else:
|
||||
var notice_icon_tooltips := _collect_tooltips(scene.objective_notice_icon_strip)
|
||||
if not notice_icon_tooltips.contains("목표:") or not notice_icon_tooltips.contains("주의:") or not notice_icon_tooltips.contains("유인선") or not notice_icon_tooltips.contains("북숲 보급고") or not notice_icon_tooltips.contains("마을 보급"):
|
||||
failures.append("battle start notice icon hover should explain objective, risk, and tactical markers: %s" % notice_icon_tooltips)
|
||||
if _count_descendants_by_name(scene.objective_notice_icon_strip, "CommandNoticeTileMarkerImage") < 3:
|
||||
failures.append("battle start marker notice chips should layer generated map marker art behind objective/tactic/supply icons")
|
||||
scene.free()
|
||||
|
||||
|
||||
@@ -1971,3 +1977,31 @@ func _check_pixel_unit_idle_state(scene, failures: Array[String]) -> void:
|
||||
failures.append("pixel idle clock should not advance while dialogue is visible")
|
||||
scene.dialogue_panel.free()
|
||||
scene.dialogue_panel = null
|
||||
|
||||
|
||||
func _collect_tooltips(root: Node) -> String:
|
||||
var parts: Array[String] = []
|
||||
_collect_tooltips_into(root, parts)
|
||||
return "\n".join(parts)
|
||||
|
||||
|
||||
func _collect_tooltips_into(root: Node, parts: Array[String]) -> void:
|
||||
if root == null:
|
||||
return
|
||||
if root is Control:
|
||||
var tooltip := str((root as Control).tooltip_text).strip_edges()
|
||||
if not tooltip.is_empty():
|
||||
parts.append(tooltip)
|
||||
for child in root.get_children():
|
||||
_collect_tooltips_into(child, parts)
|
||||
|
||||
|
||||
func _count_descendants_by_name(root: Node, node_name: String) -> int:
|
||||
if root == null:
|
||||
return 0
|
||||
var count := 0
|
||||
for child in root.get_children():
|
||||
if child.name == node_name:
|
||||
count += 1
|
||||
count += _count_descendants_by_name(child, node_name)
|
||||
return count
|
||||
|
||||
Reference in New Issue
Block a user