From 31c07af5569988bc1373f8e616a805c887371de6 Mon Sep 17 00:00:00 2001 From: Wickedness Date: Sat, 20 Jun 2026 13:06:43 +0900 Subject: [PATCH] Show move preview detail badges --- scripts/scenes/battle_scene.gd | 57 ++++++++++++++++++++++++++++++++++ tools/smoke_visual_assets.gd | 18 +++++++++++ 2 files changed, 75 insertions(+) diff --git a/scripts/scenes/battle_scene.gd b/scripts/scenes/battle_scene.gd index e6cf175..150216c 100644 --- a/scripts/scenes/battle_scene.gd +++ b/scripts/scenes/battle_scene.gd @@ -112,6 +112,9 @@ const RECOVERY_TERRAIN_MARKER_SIZE := Vector2(30, 30) const RECOVERY_TERRAIN_AMOUNT_BADGE_SIZE := Vector2(24, 12) const TARGET_PREVIEW_BADGE_SIZE := Vector2(122, 24) const TARGET_PREVIEW_BADGE_ICON_SIZE := Vector2(18, 18) +const TARGET_PREVIEW_DETAIL_BADGE_HEIGHT := 22.0 +const TARGET_PREVIEW_DETAIL_BADGE_MAX_WIDTH := 244.0 +const TARGET_PREVIEW_DETAIL_BADGE_GAP := 3.0 const HOVER_INFO_BADGE_ICON_SIZE := Vector2(19, 19) const HOVER_INFO_BADGE_MAX_WIDTH := 196.0 const HOVER_INFO_BADGE_MIN_WIDTH := 126.0 @@ -8071,6 +8074,41 @@ func _draw_target_preview_badge() -> void: 14, color ) + _draw_target_preview_detail_badge(cell, str(badge.get("tooltip", "")), color, badge_rect, str(badge.get("panel", "hud_jade"))) + + +func _draw_target_preview_detail_badge(cell: Vector2i, tooltip: String, color: Color, anchor_rect: Rect2, panel_key: String) -> void: + var detail_text := _target_preview_detail_badge_text(tooltip) + if detail_text.is_empty(): + return + var rect := _target_preview_detail_badge_rect(cell, detail_text, anchor_rect) + var background := Color(0.022, 0.020, 0.017, 0.72) + _draw_generated_badge_panel(rect, color, background, panel_key, 0.05, 1.15) + _draw_ink_text( + _draw_ui_font(true), + rect.position + Vector2(8.0, 15.0), + detail_text, + HORIZONTAL_ALIGNMENT_LEFT, + rect.size.x - 16.0, + 11, + UI_PARCHMENT_TEXT + ) + + +func _target_preview_detail_badge_text(tooltip: String) -> String: + var normalized := tooltip.strip_edges().replace("\n", " · ") + if normalized.is_empty(): + return "" + return _truncate_hud_text(normalized, 34) + + +func _target_preview_detail_badge_size(text: String) -> Vector2: + var width := clampf( + _weighted_text_length(text) * 7.4 + 18.0, + TARGET_PREVIEW_BADGE_SIZE.x, + TARGET_PREVIEW_DETAIL_BADGE_MAX_WIDTH + ) + return Vector2(width, TARGET_PREVIEW_DETAIL_BADGE_HEIGHT) func _draw_generated_badge_panel(rect: Rect2, color: Color, background: Color, texture_key: String = "hud_jade", accent_alpha: float = 0.10, border_width: float = 2.0) -> void: @@ -8135,6 +8173,25 @@ func _target_preview_badge_rect(cell: Vector2i, size: Vector2 = TARGET_PREVIEW_B return Rect2(position, size) +func _target_preview_detail_badge_rect(cell: Vector2i, tooltip: String, anchor_rect: Rect2) -> Rect2: + var text := _target_preview_detail_badge_text(tooltip) + var size := _target_preview_detail_badge_size(text) + var visible_board := _board_rect().intersection(_map_view_rect()) + if visible_board.size.x <= 0.0 or visible_board.size.y <= 0.0: + visible_board = _board_rect() + var min_x := visible_board.position.x + 2.0 + var min_y := visible_board.position.y + 2.0 + var max_x := maxf(min_x, visible_board.end.x - size.x - 2.0) + var max_y := maxf(min_y, visible_board.end.y - size.y - 2.0) + var position := anchor_rect.position + Vector2((anchor_rect.size.x - size.x) * 0.5, anchor_rect.size.y + TARGET_PREVIEW_DETAIL_BADGE_GAP) + var above_y := anchor_rect.position.y - size.y - TARGET_PREVIEW_DETAIL_BADGE_GAP + if position.y + size.y > visible_board.end.y - 2.0 and above_y >= min_y: + position.y = above_y + position.x = clampf(position.x, min_x, max_x) + position.y = clampf(position.y, min_y, max_y) + return Rect2(position, size) + + func _hover_info_badge() -> Dictionary: if _is_input_locked() or not state.is_inside(hover_cell): return {} diff --git a/tools/smoke_visual_assets.gd b/tools/smoke_visual_assets.gd index c4693db..7ec8a72 100644 --- a/tools/smoke_visual_assets.gd +++ b/tools/smoke_visual_assets.gd @@ -4774,6 +4774,9 @@ func _check_hover_intent_badges(failures: Array[String]) -> void: failures.append("moving into current enemy attack range should show DANGER badge: %s" % str(danger_move_badge)) if not str(danger_move_badge.get("tooltip", "")).contains("현재 적 공격권"): failures.append("danger move badge should explain current enemy attack range: %s" % str(danger_move_badge)) + var danger_detail_text := scene._target_preview_detail_badge_text(str(danger_move_badge.get("tooltip", ""))) + if not danger_detail_text.contains("현재 적 공격권"): + failures.append("danger move badge detail text should be visible on the map: %s" % danger_detail_text) scene.hover_cell = Vector2i(1, 7) var select_badge := scene._target_preview_badge() @@ -4824,6 +4827,17 @@ func _check_hover_intent_badges(failures: Array[String]) -> void: failures.append("target preview badge should remain wide enough for Korean tactical text") if edge_badge_rect.size.x < 120.0: failures.append("target preview badge should reserve room for icon and Korean text") + var edge_detail_rect: Rect2 = scene._target_preview_detail_badge_rect( + Vector2i(13, 9), + "현재 적 공격권: 장만성, 마을 방패병, +2", + edge_badge_rect + ) + if edge_detail_rect.position.x < board_rect.position.x or edge_detail_rect.position.y < board_rect.position.y: + failures.append("edge target preview detail should stay inside visible board minimum: %s / %s" % [str(edge_detail_rect), str(board_rect)]) + if edge_detail_rect.end.x > board_rect.end.x or edge_detail_rect.end.y > board_rect.end.y: + failures.append("edge target preview detail should stay inside visible board maximum: %s / %s" % [str(edge_detail_rect), str(board_rect)]) + if edge_detail_rect.size.y > BattleSceneScript.TARGET_PREVIEW_DETAIL_BADGE_HEIGHT + 0.1: + failures.append("target preview detail should remain a compact one-line strip: %s" % str(edge_detail_rect)) scene.state.clear_selection() scene.selected_skill_id = "" @@ -4852,6 +4866,8 @@ func _check_hover_intent_badges(failures: Array[String]) -> void: failures.append("move preview should mark cells that wake sleeping sentries: %s" % str(lure_move_badge)) if not str(lure_move_badge.get("tooltip", "")).contains("초병 반응권"): failures.append("lure move badge should explain sentry reaction zone: %s" % str(lure_move_badge)) + if not scene._target_preview_detail_badge_text(str(lure_move_badge.get("tooltip", ""))).contains("초병 반응권"): + failures.append("lure move badge detail text should be drawable: %s" % str(lure_move_badge)) central_sentry["ai_awake"] = true var awake_sentry_hover_badge := scene._hover_info_badge() if not str(awake_sentry_hover_badge.get("lines", [])).contains("초병 경계"): @@ -4883,6 +4899,8 @@ func _check_hover_intent_badges(failures: Array[String]) -> void: failures.append("move preview should mark guard reaction cells: %s" % str(guard_move_badge)) if not str(guard_move_badge.get("tooltip", "")).contains("거점 경계권"): failures.append("guard move badge should explain guard reaction zone: %s" % str(guard_move_badge)) + if not scene._target_preview_detail_badge_text(str(guard_move_badge.get("tooltip", ""))).contains("거점 경계권"): + failures.append("guard move badge detail text should be drawable: %s" % str(guard_move_badge)) var hovered_guard: Dictionary = scene._hovered_ai_zone_unit() if str(hovered_guard.get("id", "")) != "yellow_turban_4": failures.append("hovered guard should expose a drawable AI zone: %s" % str(hovered_guard))