diff --git a/scripts/scenes/battle_scene.gd b/scripts/scenes/battle_scene.gd index 37f030f..f20cccb 100644 --- a/scripts/scenes/battle_scene.gd +++ b/scripts/scenes/battle_scene.gd @@ -6699,11 +6699,12 @@ func _append_auto_attack_target_marker_entries(result: Array[Dictionary], select result.append({ "cell": target_cell, "target_id": target_id, - "text": "행공", + "text": "진격", "kind": marker_kind, "icon": _target_preview_badge_icon_kind(marker_kind), "panel": _target_marker_panel_key(), "origin_panel": _target_marker_panel_key(), + "tooltip": _format_auto_attack_target_hint(preview), "origin": attack_origin, "requires_move": true, "damage": int(preview.get("damage", 0)), @@ -8210,12 +8211,43 @@ func _auto_attack_target_preview_badge_for_origin(selected: Dictionary, target: if preview.is_empty(): return {} var target_cell: Vector2i = preview.get("target_cell", Vector2i(-1, -1)) + var badge := _make_target_preview_badge_at( + _format_auto_attack_target_badge_text(preview), + _auto_attack_preview_badge_kind(preview), + target_cell + ) + badge["tooltip"] = _format_auto_attack_target_hint(preview) + badge["advance_origin"] = attack_origin + return badge + + +func _format_auto_attack_target_badge_text(preview: Dictionary) -> String: var damage := int(preview.get("damage", 0)) var hit_chance := int(preview.get("hit_chance", 0)) - var result_text := "행공 퇴각" if bool(preview.get("would_defeat", false)) else "행공 -%d" % damage + var result_text := "퇴각" if bool(preview.get("would_defeat", false)) else "-%d" % damage var directional_text := _format_directional_badge_suffix(preview) var counter_text := _format_auto_attack_counter_badge_suffix(preview) - return _make_target_preview_badge_at("%s%s %d%%%s" % [result_text, directional_text, hit_chance, counter_text], _auto_attack_preview_badge_kind(preview), target_cell) + return "%s%s %d%%%s" % [result_text, directional_text, hit_chance, counter_text] + + +func _format_auto_attack_target_hint(preview: Dictionary) -> String: + var parts: Array[String] = ["이동 후 공격"] + var origin: Vector2i = preview.get("origin", Vector2i(-1, -1)) + if state.is_inside(origin): + parts.append("진입 위치 %d,%d" % [origin.x + 1, origin.y + 1]) + parts.append("피해 %d, 명중 %d%%" % [ + int(preview.get("damage", 0)), + int(preview.get("hit_chance", 0)) + ]) + if bool(preview.get("counter_in_range", false)): + var counter_text := "반격 %d, 명중 %d%%" % [ + int(preview.get("counter_damage", 0)), + int(preview.get("counter_hit_chance", 0)) + ] + if bool(preview.get("counter_would_defeat", false)): + counter_text += ", 아군 퇴각 위험" + parts.append(counter_text) + return "\n".join(parts) func _auto_attack_preview_for_origin(selected: Dictionary, target: Dictionary, attack_origin: Vector2i) -> Dictionary: @@ -9961,16 +9993,16 @@ func _format_auto_attack_forecast_text(selected: Dictionary, target: Dictionary) int(preview.get("counter_hit_chance", 0)), counter_defeat ] - return "전황: 행공 진 %d,%d 이동 %d칸\n피해 %d%s, 명중 %d%%, 적 병력 %d/%d.%s%s" % [ - origin.x + 1, - origin.y + 1, - move_distance, + return "전황: 진격 공격\n피해 %d%s, 명중 %d%%, 적 병력 %d/%d.%s\n진입 위치 %d,%d, 이동 %d칸%s" % [ int(preview.get("damage", 0)), directional_text, int(preview.get("hit_chance", 0)), int(preview.get("target_hp_after", 0)), int(target.get("max_hp", 1)), defeat_text, + origin.x + 1, + origin.y + 1, + move_distance, counter_text ] diff --git a/tools/smoke_directional_combat.gd b/tools/smoke_directional_combat.gd index 40be280..93da8c3 100644 --- a/tools/smoke_directional_combat.gd +++ b/tools/smoke_directional_combat.gd @@ -216,8 +216,8 @@ func _check_scene_directional_attack_badges(failures: Array[String]) -> void: scene._refresh_ranges() scene.hover_cell = Vector2i(5, 9) var auto_badge: Dictionary = scene._target_preview_badge() - if not str(auto_badge.get("text", "")).contains("행공"): - failures.append("auto-move attack hover badge should be used for reachable distant enemy: %s" % str(auto_badge)) + if str(auto_badge.get("text", "")).contains("행공") or not str(auto_badge.get("tooltip", "")).contains("이동 후 공격"): + failures.append("auto-move attack hover badge should use a clear hint instead of jargon: %s" % str(auto_badge)) if not str(auto_badge.get("text", "")).contains("후+%d" % BattleStateScript.DIRECTIONAL_BACK_DAMAGE_BONUS): failures.append("auto-move attack hover badge should expose compact rear bonus: %s" % str(auto_badge)) diff --git a/tools/smoke_post_move_action_flow.gd b/tools/smoke_post_move_action_flow.gd index f1504bd..961d2e2 100644 --- a/tools/smoke_post_move_action_flow.gd +++ b/tools/smoke_post_move_action_flow.gd @@ -616,8 +616,10 @@ func _check_scene_enemy_click_auto_attack(failures: Array[String]) -> void: found_auto_marker = true if marker.get("target_id", "") != "yellow_turban_1": failures.append("move+attack marker should keep the clicked target id: %s" % str(marker)) - if marker.get("text", "") != "행공": - failures.append("move+attack marker should use compact battlefield text: %s" % str(marker)) + if marker.get("text", "") != "진격": + failures.append("move+attack marker should use clear compact battlefield text: %s" % str(marker)) + if not str(marker.get("tooltip", "")).contains("이동 후 공격"): + failures.append("move+attack marker should keep route detail in hover metadata: %s" % str(marker)) if marker.get("origin", Vector2i.ZERO) != Vector2i(3, 3): failures.append("move+attack marker should expose the chosen attack origin: %s" % str(marker)) if marker.get("origin", Vector2i.ZERO) == Vector2i(1, 3): @@ -634,8 +636,8 @@ func _check_scene_enemy_click_auto_attack(failures: Array[String]) -> void: failures.append("selected unit should mark enemies reachable by move+attack: %s" % str(auto_markers)) scene.hover_cell = Vector2i(4, 3) var auto_badge := scene._target_preview_badge() - if not str(auto_badge.get("text", "")).contains("행공"): - failures.append("hovering a move+attack target should explain the combined action: %s" % str(auto_badge)) + if str(auto_badge.get("text", "")).contains("행공") or not str(auto_badge.get("tooltip", "")).contains("이동 후 공격"): + failures.append("hovering a move+attack target should use metadata instead of jargon text: %s" % str(auto_badge)) if not ["advance", "counter", "danger"].has(str(auto_badge.get("kind", ""))): failures.append("move+attack hover badge should use an attack-risk color kind: %s" % str(auto_badge)) if str(auto_badge.get("icon", "")).strip_edges().is_empty(): @@ -653,7 +655,7 @@ func _check_scene_enemy_click_auto_attack(failures: Array[String]) -> void: failures.append("attack-locked units should not mark move+attack targets: %s" % str(marker)) scene.hover_cell = Vector2i(4, 3) var locked_badge := scene._target_preview_badge() - if str(locked_badge.get("text", "")).contains("행공"): + if str(locked_badge.get("text", "")).contains("진격") or str(locked_badge.get("text", "")).contains("행공"): failures.append("attack-locked hover badge should not offer move+attack: %s" % str(locked_badge)) scene._handle_board_click(_screen_for_cell(Vector2i(4, 3))) if cao_cao.get("pos", Vector2i.ZERO) != Vector2i(1, 3) or int(enemy.get("hp", 0)) != 24: @@ -756,7 +758,7 @@ func _check_scene_auto_attack_safe_origin_and_counter_preview(failures: Array[St failures.append("formal attack targeting should not show move+attack origin routes: %s" % str(marker)) scene.hover_cell = Vector2i(5, 3) scene._update_forecast() - if scene.forecast_label.text.contains("행공"): + if scene.forecast_label.text.contains("진격 공격") or scene.forecast_label.text.contains("행공"): failures.append("formal attack targeting forecast should not describe auto move+attack: %s" % scene.forecast_label.text) scene.basic_attack_targeting = false scene._refresh_ranges() @@ -767,8 +769,11 @@ func _check_scene_auto_attack_safe_origin_and_counter_preview(failures: Array[St failures.append("safe auto attack hover should not show counter risk: %s" % str(safe_badge)) scene._update_forecast() var safe_forecast: String = scene.forecast_label.text - if not safe_forecast.contains("행공") or not safe_forecast.contains("진 4,4") or safe_forecast.contains("사거리 밖"): - failures.append("safe auto attack forecast should describe the chosen advance origin: %s" % safe_forecast) + var safe_detail := str(scene.forecast_label.tooltip_text) + if not safe_forecast.contains("진격 공격") or safe_forecast.contains("4,4") or safe_forecast.contains("사거리 밖"): + failures.append("safe auto attack forecast should summarize without raw origin coordinates: %s" % safe_forecast) + if not safe_detail.contains("진입 위치 4,4"): + failures.append("safe auto attack tooltip should keep the chosen advance origin: %s" % safe_detail) scene._handle_board_click(_screen_for_cell(Vector2i(5, 3))) cao_cao = scene.state.get_unit("cao_cao") @@ -826,7 +831,7 @@ func _check_scene_auto_attack_safe_origin_and_counter_preview(failures: Array[St risky_scene._update_forecast() var risky_forecast: String = risky_scene.forecast_label.text var risky_detail := str(risky_scene.forecast_label.tooltip_text) - if not risky_forecast.contains("행공") or not risky_detail.contains("반격"): + if not risky_forecast.contains("진격 공격") or not risky_detail.contains("반격"): failures.append("risky auto attack forecast should summarize on the label and keep counter risk in the tooltip: %s / %s" % [risky_forecast, risky_detail]) risky_enemy["controllable"] = false var escort_preview := risky_scene._auto_attack_preview_for_origin(risky_attacker, risky_enemy, Vector2i(4, 3))