Refine large map navigation previews

This commit is contained in:
2026-06-19 20:14:13 +09:00
parent 8cb611ac1a
commit 190716fdfc
4 changed files with 172 additions and 17 deletions

View File

@@ -73,8 +73,8 @@ func _check_chapter_one_scenarios_have_visual_grounding(failures: Array[String])
func _check_edge_scroll_layout_contract(failures: Array[String]) -> void:
var scene = BattleSceneScript.new()
if not scene.state.load_battle("res://data/scenarios/009_xiapi_siege.json"):
failures.append("could not load large chapter one map for edge scrolling")
if not scene.state.load_battle("res://data/scenarios/001_yellow_turbans.json"):
failures.append("could not load opening chapter one map for edge scrolling")
scene.free()
return
@@ -82,8 +82,8 @@ func _check_edge_scroll_layout_contract(failures: Array[String]) -> void:
var board_size := scene._board_size()
if view_rect.size.x < 160.0 or view_rect.size.y < 160.0:
failures.append("map view rect should keep a usable minimum size")
if board_size.x <= view_rect.size.x and board_size.y <= view_rect.size.y:
failures.append("chapter one should include at least one map large enough to exercise edge scrolling")
if board_size.x <= view_rect.size.x or board_size.y <= view_rect.size.y:
failures.append("opening chapter one map should be larger than the visible map window: board=%s view=%s" % [str(board_size), str(view_rect.size)])
scene._reset_board_scroll()
if scene.board_scroll_offset.x > 0.0 or scene.board_scroll_offset.y > 0.0:
@@ -211,8 +211,8 @@ func _check_edge_scroll_velocity_curve(scene, view_rect: Rect2, failures: Array[
func _check_minimap_navigation_contract(failures: Array[String]) -> void:
var scene = BattleSceneScript.new()
if not scene.state.load_battle("res://data/scenarios/009_xiapi_siege.json"):
failures.append("could not load large chapter one map for minimap navigation")
if not scene.state.load_battle("res://data/scenarios/001_yellow_turbans.json"):
failures.append("could not load opening chapter one map for minimap navigation")
scene.free()
return
scene.battle_started = true
@@ -226,12 +226,17 @@ func _check_minimap_navigation_contract(failures: Array[String]) -> void:
"_scroll_board_to_minimap_position",
"_handle_minimap_mouse_button",
"_handle_minimap_mouse_motion",
"_is_minimap_visible"
"_is_minimap_visible",
"_map_has_scrollable_area"
]:
if not scene.has_method(method_name):
failures.append("missing minimap helper: %s" % method_name)
var view_rect := scene._map_view_rect()
if not scene._map_has_scrollable_area():
failures.append("opening map should require a scrollable minimap viewport")
if not scene._is_minimap_visible():
failures.append("minimap should be visible on the opening large map")
var minimap_rect: Rect2 = scene._minimap_rect()
if minimap_rect.size.x < 150.0 or minimap_rect.size.y < 110.0:
failures.append("minimap should reserve a usable tactical map plate: %s" % str(minimap_rect))
@@ -301,11 +306,29 @@ func _check_minimap_navigation_contract(failures: Array[String]) -> void:
failures.append("minimap release should end dragging")
scene.free()
var small_scene = BattleSceneScript.new()
if not small_scene.state.load_battle("res://data/scenarios/002_sishui_gate.json"):
failures.append("could not load compact chapter one map for minimap hiding")
small_scene.free()
return
small_scene.battle_started = true
if small_scene._map_has_scrollable_area():
failures.append("compact maps should not require minimap scrolling")
if small_scene._is_minimap_visible():
failures.append("minimap should stay hidden on compact maps")
var compact_press := InputEventMouseButton.new()
compact_press.button_index = MOUSE_BUTTON_LEFT
compact_press.pressed = true
compact_press.position = small_scene._map_view_rect().end - Vector2(18.0, 18.0)
if small_scene._handle_minimap_mouse_button(compact_press):
failures.append("hidden minimap should not consume lower-right board clicks on compact maps")
small_scene.free()
func _check_map_focus_contract(failures: Array[String]) -> void:
var scene = BattleSceneScript.new()
if not scene.state.load_battle("res://data/scenarios/009_xiapi_siege.json"):
failures.append("could not load large chapter one map for map focus")
if not scene.state.load_battle("res://data/scenarios/001_yellow_turbans.json"):
failures.append("could not load opening chapter one map for map focus")
scene.free()
return
scene.battle_started = true

View File

@@ -10,6 +10,7 @@ func _init() -> void:
_check_attack_updates_facing(failures)
_check_move_cancel_restores_facing(failures)
_check_scene_pixel_facing(failures)
_check_scene_directional_attack_badges(failures)
if failures.is_empty():
print("directional combat smoke ok")
@@ -163,6 +164,74 @@ func _check_scene_pixel_facing(failures: Array[String]) -> void:
scene.free()
func _check_scene_directional_attack_badges(failures: Array[String]) -> void:
var scene = BattleSceneScript.new()
if not scene.state.load_battle("res://data/scenarios/001_yellow_turbans.json"):
failures.append("could not load opening battle for directional attack badges")
scene.free()
return
var attacker: Dictionary = scene.state.get_unit("cao_cao")
var target: Dictionary = scene.state.get_unit("yellow_turban_1")
if attacker.is_empty() or target.is_empty():
failures.append("missing units for directional attack badge")
scene.free()
return
for unit in scene.state.units:
if str(unit.get("id", "")) != "cao_cao" and str(unit.get("id", "")) != "yellow_turban_1":
unit["alive"] = false
_configure_duel_units(attacker, target)
attacker["move"] = 4
attacker["pos"] = Vector2i(4, 9)
target["pos"] = Vector2i(5, 9)
target["facing_x"] = 1
target["controllable"] = false
scene.battle_started = true
if not scene.state.select_unit("cao_cao"):
failures.append("could not select Cao Cao for directional attack badge")
scene.free()
return
scene._refresh_ranges()
scene.hover_cell = Vector2i(5, 9)
var badge := scene._target_preview_badge()
if not str(badge.get("text", "")).contains("후+%d" % BattleStateScript.DIRECTIONAL_BACK_DAMAGE_BONUS):
failures.append("rear attack hover badge should expose compact rear bonus: %s" % str(badge))
var marker_text := ""
for marker in scene._attack_target_marker_entries():
if str(marker.get("target_id", "")) == "yellow_turban_1":
marker_text = str(marker.get("text", ""))
if not marker_text.contains("후+%d" % BattleStateScript.DIRECTIONAL_BACK_DAMAGE_BONUS):
failures.append("rear attack target marker should expose compact rear bonus: %s" % marker_text)
attacker["pos"] = Vector2i(5, 8)
scene._refresh_ranges()
scene.hover_cell = Vector2i(5, 9)
var side_badge: Dictionary = scene._target_preview_badge()
if not str(side_badge.get("text", "")).contains("측+%d" % BattleStateScript.DIRECTIONAL_SIDE_DAMAGE_BONUS):
failures.append("side attack hover badge should expose compact side bonus: %s" % str(side_badge))
attacker["pos"] = Vector2i(2, 9)
attacker["facing_x"] = -1
target["pos"] = Vector2i(5, 9)
target["facing_x"] = 1
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 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))
if scene._compact_directional_badge_label(BattleStateScript.DIRECTIONAL_SIDE_ATTACK) != "":
failures.append("directional badge helper should compact side attacks")
if scene._format_directional_badge_suffix({
"directional_attack": BattleStateScript.DIRECTIONAL_FRONT_ATTACK,
"directional_bonus": 0,
"directional_label": "정면"
}) != "":
failures.append("front/no-bonus directional badge suffix should stay empty")
scene.free()
func _configure_duel_units(attacker: Dictionary, target: Dictionary) -> void:
attacker["atk"] = 30
attacker["agi"] = 50