Tighten local command targeting UX

This commit is contained in:
2026-06-19 20:41:37 +09:00
parent ce2c1889bf
commit 184a542b04
2 changed files with 112 additions and 17 deletions

View File

@@ -12,6 +12,7 @@ func _init() -> void:
_check_scene_post_move_scrolled_view_positioning(failures)
_check_scene_post_move_menu_tracks_map_scroll(failures)
_check_scene_post_move_text_fit(failures)
_check_scene_post_move_blocked_command_labels(failures)
_check_scene_post_move_tactic_picker_flow(failures)
_check_scene_post_move_item_picker_flow(failures)
_check_scene_enemy_click_auto_attack(failures)
@@ -105,6 +106,13 @@ func _check_scene_post_move_menu_flow(failures: Array[String]) -> void:
failures.append("post-move action menu should be visible after moving")
else:
_check_local_panel_position(failures, scene, scene.post_move_menu, Vector2i(2, 3), "post-move action menu")
_check_local_command_button_tooltips_suppressed(failures, [
scene.post_move_attack_button,
scene.post_move_tactic_button,
scene.post_move_item_button,
scene.post_move_wait_button,
scene.post_move_cancel_button
], "post-move action menu")
if cao_cao.get("pos", Vector2i.ZERO) != Vector2i(2, 3) or not bool(cao_cao.get("moved", false)) or bool(cao_cao.get("acted", false)):
failures.append("scene move should be pending with action still available")
if scene.state.get_selected_unit().is_empty():
@@ -285,6 +293,12 @@ func _check_scene_post_move_text_fit(failures: Array[String]) -> void:
failures.append("post-move picker should expose a fitted detail label")
else:
_check_fitted_label_font(failures, scene.post_move_picker_detail_label, BattleSceneScript.LOCAL_COMMAND_DETAIL_FONT_SIZE, BattleSceneScript.LOCAL_COMMAND_DETAIL_MIN_FONT_SIZE, "post-move picker detail")
_check_local_command_button_tooltips_suppressed(failures, [
scene.post_move_picker_back_button,
scene.post_move_picker_cancel_move_button,
scene.targeting_hint_back_button,
scene.targeting_hint_cancel_move_button
], "local command utility buttons")
scene.selected_item_id = "very_long_supply_order_marker_name"
scene.selected_skill_id = ""
@@ -292,6 +306,8 @@ func _check_scene_post_move_text_fit(failures: Array[String]) -> void:
scene._update_targeting_hint_panel()
if scene.targeting_hint_panel != null and scene.targeting_hint_panel.visible:
failures.append("targeting guidance should stay on the board instead of opening a hint panel")
if scene.targeting_hint_panel != null and scene.targeting_hint_panel.mouse_filter != Control.MOUSE_FILTER_IGNORE:
failures.append("retired targeting hint panel should never block board clicks")
if scene.targeting_hint_title_label == null:
failures.append("targeting hint should expose a fitted title label")
else:
@@ -304,6 +320,52 @@ func _check_scene_post_move_text_fit(failures: Array[String]) -> void:
scene.free()
func _check_scene_post_move_blocked_command_labels(failures: Array[String]) -> void:
var scene = BattleSceneScript.new()
scene._create_hud()
if not scene.state.load_battle("res://data/scenarios/001_yellow_turbans.json"):
failures.append("could not load opening battle for blocked command labels")
scene.free()
return
scene.battle_started = true
scene.campaign_complete_screen = false
scene.briefing_panel.visible = false
scene.result_panel.visible = false
scene._clear_pending_move_state()
scene.state.set_inventory_snapshot({})
var far_cell := Vector2i(scene.state.map_size.x - 2, scene.state.map_size.y - 2)
for unit in scene.state.units:
if unit.get("team", "") == BattleStateScript.TEAM_ENEMY:
unit["pos"] = far_cell
var cao_cao: Dictionary = scene.state.get_unit("cao_cao")
cao_cao["pos"] = Vector2i(1, 3)
cao_cao["mp"] = 0
if not scene.state.select_unit("cao_cao"):
failures.append("could not select Cao Cao for blocked command labels")
scene.free()
return
scene._refresh_ranges()
scene._handle_board_click(_screen_for_cell(Vector2i(2, 3)))
if scene.post_move_menu == null or not scene.post_move_menu.visible:
failures.append("blocked command label setup should show the post-move menu")
else:
if scene.post_move_attack_button == null or not scene.post_move_attack_button.disabled or scene.post_move_attack_button.text != "타격 없음":
failures.append("blocked attack command should explain itself through button text")
if scene.post_move_tactic_button == null or not scene.post_move_tactic_button.disabled or scene.post_move_tactic_button.text != "책략 없음":
failures.append("blocked tactic command should explain itself through button text")
if scene.post_move_item_button == null or not scene.post_move_item_button.disabled or scene.post_move_item_button.text != "보급 없음":
failures.append("blocked item command should explain itself through button text")
_check_local_command_button_tooltips_suppressed(failures, [
scene.post_move_attack_button,
scene.post_move_tactic_button,
scene.post_move_item_button
], "blocked post-move commands")
scene.free()
func _check_scene_post_move_attack_targeting(failures: Array[String]) -> void:
var scene = BattleSceneScript.new()
scene._create_hud()
@@ -346,6 +408,8 @@ func _check_scene_post_move_attack_targeting(failures: Array[String]) -> void:
scene._handle_board_click(_screen_for_cell(Vector2i(2, 3)))
if not scene._has_pending_move() or scene.post_move_menu == null or not scene.post_move_menu.visible:
failures.append("attack targeting setup should leave the post-move menu visible")
if scene.post_move_attack_button == null or scene.post_move_attack_button.disabled or scene.post_move_attack_button.text != "타격령":
failures.append("available attack command should stay compact and enabled")
if scene.basic_attack_targeting:
failures.append("attack targeting should be off before pressing Attack")
if not scene.attack_cells.is_empty():
@@ -537,6 +601,7 @@ func _check_scene_post_move_tactic_picker_flow(failures: Array[String]) -> void:
failures.append("post-move action menu should hide while the tactic picker is open")
if scene.tactic_menu != null and scene.tactic_menu.visible:
failures.append("post-move tactic shortcut should not use the side tactic menu")
_check_post_move_picker_option_tooltips_suppressed(failures, scene, "post-move tactic picker")
var escape := InputEventKey.new()
escape.keycode = KEY_ESCAPE
@@ -645,6 +710,7 @@ func _check_scene_post_move_item_picker_flow(failures: Array[String]) -> void:
failures.append("post-move action menu should hide while the item picker is open")
if scene.item_menu != null and scene.item_menu.visible:
failures.append("post-move item shortcut should not use the side item menu")
_check_post_move_picker_option_tooltips_suppressed(failures, scene, "post-move item picker")
scene._on_post_move_item_option_pressed("bean")
if scene.selected_item_id != "bean":
@@ -713,6 +779,24 @@ func _check_local_panel_position(failures: Array[String], scene, panel: Control,
failures.append("%s should not cover the moved unit cell: %s over %s" % [label, str(panel_rect), str(cell_rect)])
func _check_local_command_button_tooltips_suppressed(failures: Array[String], buttons: Array, label: String) -> void:
for button in buttons:
if button == null:
failures.append("%s should expose local command buttons for tooltip checks" % label)
continue
if not str(button.tooltip_text).is_empty():
failures.append("%s should keep guidance on the map instead of native tooltips: %s" % [label, str(button.tooltip_text)])
func _check_post_move_picker_option_tooltips_suppressed(failures: Array[String], scene, label: String) -> void:
if scene.post_move_picker_list == null:
failures.append("%s should expose a picker option list" % label)
return
for child in scene.post_move_picker_list.get_children():
if child is Button and not str(child.tooltip_text).is_empty():
failures.append("%s option should not rely on native tooltip popups: %s" % [label, str(child.tooltip_text)])
func _check_fitted_label_font(failures: Array[String], label: Label, base_size: int, min_size: int, label_name: String) -> void:
var font_size := label.get_theme_font_size("font_size")
if font_size < min_size or font_size > base_size: