feat(runtime): render real Guild formation
This commit is contained in:
@@ -0,0 +1,197 @@
|
||||
extends SceneTree
|
||||
|
||||
const MainScene = preload("res://main.tscn")
|
||||
const VIEWPORT_SIZE := Vector2i(844, 390)
|
||||
|
||||
var failures: Array[String] = []
|
||||
var capture_root := ""
|
||||
var viewport: SubViewport
|
||||
|
||||
|
||||
func _initialize() -> void:
|
||||
call_deferred("run_test")
|
||||
|
||||
|
||||
func run_test() -> void:
|
||||
capture_root = OS.get_environment("ABG_P9_1_FORMATION_CAPTURE_ROOT")
|
||||
if not capture_root.is_empty():
|
||||
DirAccess.make_dir_recursive_absolute(capture_root)
|
||||
viewport = SubViewport.new()
|
||||
viewport.size = VIEWPORT_SIZE
|
||||
viewport.render_target_update_mode = SubViewport.UPDATE_ALWAYS
|
||||
root.add_child(viewport)
|
||||
var game := MainScene.instantiate()
|
||||
game.auto_boot = false
|
||||
game.audio_enabled = false
|
||||
viewport.add_child(game)
|
||||
await settle(10)
|
||||
game.locale = "zh_CN"
|
||||
game.muted = true
|
||||
game.boot_verified = true
|
||||
game.page = game.AppPage.MAIN_MENU
|
||||
game.render()
|
||||
|
||||
start_pair(game, "Farstring", "Kindhand")
|
||||
resolve_battle(game, 6)
|
||||
expect(game.page == game.AppPage.VICTORY, "exceptional pair wins battle one")
|
||||
game.open_adaptation()
|
||||
game.choose_adaptation("EQ-002")
|
||||
game.begin_second_battle()
|
||||
resolve_battle(game, 6)
|
||||
expect(game.page == game.AppPage.SECOND_RESULT, "exceptional pair reaches the Guild handoff")
|
||||
|
||||
game.open_guild_return()
|
||||
expect(game.facade.session_service.mapped_guild_recruit() == "Hearthguard", "Guild domain maps Hearthguard for Farstring and Kindhand")
|
||||
var recruit_button := find_control(game, "GuildChoice_recruit_rear") as Button
|
||||
expect(recruit_button != null and recruit_button.text.contains(game.candidate_name("Hearthguard")), "unselected Guild option names Hearthguard")
|
||||
expect(recruit_button != null and recruit_button.text.contains("先行位"), "unselected Guild option previews Hearthguard as lead")
|
||||
game.choose_guild_option("recruit_rear")
|
||||
expect(game.facade.guild_preview_order() == ["Hearthguard", "Farstring", "Kindhand"], "selected Guild preview uses post-recruit order")
|
||||
expect(game.facade.guild_choice_guidance().contains("艾连") and game.facade.guild_choice_guidance().contains("艾连 → 妮娅 → 赛布尔"), "Guild guidance names recruit and complete order")
|
||||
expect(member_meta(game, "GuildFront") == "Hearthguard", "Guild preview puts the recruit at lead")
|
||||
expect(member_meta(game, "GuildRear") == "Farstring", "Guild preview moves Farstring to second")
|
||||
expect(member_meta(game, "GuildRecruitPreview") == "Kindhand", "Guild preview keeps Kindhand after Farstring")
|
||||
await capture_state("01-guild-reformation")
|
||||
|
||||
game.begin_third_battle()
|
||||
expect(game.facade.session_state.field_order == ["Hearthguard", "Farstring", "Kindhand"], "Guild commit produces the previewed order")
|
||||
expect(game.added_rear == "Hearthguard", "stable origin records Hearthguard as the Guild recruit")
|
||||
expect(member_meta(game, "FrontActor") == "Hearthguard", "battle three lead actor is Hearthguard")
|
||||
expect(member_meta(game, "RearActor") == "Farstring", "battle three second actor is Farstring")
|
||||
expect(member_meta(game, "AddedRearActor") == "Kindhand", "battle three third actor is Kindhand")
|
||||
expect(control_text(game, "FrontHealth").contains("艾连"), "lead health bar names Hearthguard")
|
||||
game.advance_battle_phase()
|
||||
await capture_state("02-battle-three")
|
||||
|
||||
game.advance_battle_phase()
|
||||
game.commit_phase_impact(2)
|
||||
expect(game.active_battle_feedback.get("target", "") == "front", "Hearthguard damage feedback lands on the current lead")
|
||||
resolve_remaining_battle(game, 2, 7)
|
||||
expect(game.page == game.AppPage.SESSION_RESULT, "re-formed line reaches battle-three result")
|
||||
|
||||
game.open_route_board()
|
||||
expect(member_meta(game, "RouteFront") == "Hearthguard", "route board keeps Hearthguard at lead")
|
||||
expect(member_meta(game, "RouteRear") == "Farstring", "route board keeps Farstring second")
|
||||
expect(member_meta(game, "RouteAddedRear") == "Kindhand", "route board keeps Kindhand third")
|
||||
await capture_state("03-route-board")
|
||||
game.choose_route("R6-03")
|
||||
game.open_route_review()
|
||||
game.commit_route()
|
||||
game.advance_battle_phase()
|
||||
game.advance_battle_phase()
|
||||
game.commit_phase_impact(2)
|
||||
expect(game.facade.session_state.marked_member_id() == "Kindhand", "route pressure retains Kindhand's stable identity")
|
||||
expect(game.active_battle_feedback.get("target", "") == "added", "Kindhand feedback lands on her current third position")
|
||||
resolve_remaining_battle(game, 2, 7)
|
||||
expect(game.page == game.AppPage.SECOND_CYCLE_RESULT, "re-formed line reaches battle-four result")
|
||||
|
||||
game.open_training()
|
||||
expect(training_member(game, "Training_Front") == "Hearthguard", "lead training control maps Hearthguard")
|
||||
expect(training_member(game, "Training_Rear") == "Farstring", "second training control maps Farstring")
|
||||
expect(training_member(game, "Training_Added") == "Kindhand", "third training control maps Kindhand")
|
||||
expect(member_meta(game, "TrainingActor_front") == "Hearthguard", "lead training actor matches its control")
|
||||
expect(member_meta(game, "TrainingActor_rear") == "Farstring", "second training actor matches its control")
|
||||
expect(member_meta(game, "TrainingActor_added") == "Kindhand", "third training actor matches its control")
|
||||
await capture_state("04-training")
|
||||
game.choose_training("front")
|
||||
game.open_training_review()
|
||||
game.commit_training()
|
||||
resolve_battle(game, 7)
|
||||
expect(game.page == game.AppPage.THIRD_CYCLE_RESULT, "re-formed line reaches the final result")
|
||||
expect(member_meta(game, "GrowthResultFront") == "Hearthguard", "final result keeps Hearthguard at lead")
|
||||
expect(member_meta(game, "GrowthResultRear") == "Farstring", "final result keeps Farstring second")
|
||||
expect(member_meta(game, "GrowthResultAddedRear") == "Kindhand", "final result keeps Kindhand third")
|
||||
await capture_state("05-final-result")
|
||||
|
||||
game.clear_experience()
|
||||
game.page = game.AppPage.MAIN_MENU
|
||||
game.render()
|
||||
start_pair(game, "Hearthguard", "Farstring")
|
||||
expect(game.facade.visible_member_ids() == ["Hearthguard", "Farstring"], "standard pair remains a two-person line")
|
||||
expect(member_meta(game, "FrontActor") == "Hearthguard" and member_meta(game, "RearActor") == "Farstring", "standard pair actor mapping is unchanged")
|
||||
expect(find_control(game, "AddedRearActor") == null, "standard pair has no third actor")
|
||||
|
||||
game.queue_free()
|
||||
viewport.queue_free()
|
||||
await settle(90)
|
||||
if failures.is_empty():
|
||||
print("ABG_P9_1_REAL_FORMATION_UI_OK preview=HG,FS,KH battle=HG,FS,KH feedback=lead,third training=HG,FS,KH standard=HG,FS")
|
||||
quit(0)
|
||||
else:
|
||||
for failure in failures:
|
||||
push_error(failure)
|
||||
quit(1)
|
||||
|
||||
|
||||
func start_pair(game: Control, first: String, second: String) -> void:
|
||||
game.start_new_game()
|
||||
game.open_recruit_selection()
|
||||
game.toggle_recruit(first)
|
||||
game.toggle_recruit(second)
|
||||
game.review_automatic_formation()
|
||||
game.commit_formation()
|
||||
|
||||
|
||||
func resolve_battle(game: Control, phase_count: int) -> void:
|
||||
for phase in range(phase_count):
|
||||
game.advance_battle_phase()
|
||||
|
||||
|
||||
func resolve_remaining_battle(game: Control, current_phase: int, phase_count: int) -> void:
|
||||
for phase in range(current_phase, phase_count):
|
||||
game.advance_battle_phase()
|
||||
|
||||
|
||||
func training_member(game: Control, node_name: String) -> String:
|
||||
var control := find_control(game, node_name)
|
||||
return String(control.get_meta("member_id", "")) if control != null else ""
|
||||
|
||||
|
||||
func capture_state(state_name: String) -> void:
|
||||
if capture_root.is_empty():
|
||||
return
|
||||
await settle(7)
|
||||
await RenderingServer.frame_post_draw
|
||||
var image := viewport.get_texture().get_image()
|
||||
var error := image.save_png(capture_root.path_join(state_name + ".png"))
|
||||
if error != OK:
|
||||
failures.append("P9.1 real formation UI: capture %s failed with %s" % [state_name, error])
|
||||
|
||||
|
||||
func member_meta(game: Control, node_name: String) -> String:
|
||||
var control := find_control(game, node_name)
|
||||
return String(control.get_meta("member_id", "")) if control != null else ""
|
||||
|
||||
|
||||
func control_text(game: Control, node_name: String) -> String:
|
||||
var control := find_control(game, node_name)
|
||||
return collect_text(control) if control != null else ""
|
||||
|
||||
|
||||
func collect_text(node: Node) -> String:
|
||||
var parts: Array[String] = []
|
||||
if node is Label or node is Button:
|
||||
parts.append(node.text)
|
||||
for child in node.get_children():
|
||||
parts.append(collect_text(child))
|
||||
return "\n".join(parts)
|
||||
|
||||
|
||||
func find_control(node: Node, node_name: String) -> Control:
|
||||
if node.name == node_name and node is Control and not node.is_queued_for_deletion():
|
||||
return node
|
||||
for child in node.get_children():
|
||||
var found := find_control(child, node_name)
|
||||
if found != null:
|
||||
return found
|
||||
return null
|
||||
|
||||
|
||||
func settle(frames: int) -> void:
|
||||
for frame in range(frames):
|
||||
await process_frame
|
||||
|
||||
|
||||
func expect(condition: bool, message: String) -> void:
|
||||
if not condition:
|
||||
failures.append("P9.1 real formation UI: %s" % message)
|
||||
Reference in New Issue
Block a user