166 lines
5.7 KiB
GDScript
166 lines
5.7 KiB
GDScript
extends SceneTree
|
|
|
|
const MainScene = preload("res://main.tscn")
|
|
const STATES := ["training_two", "training_three", "review_front", "review_farstring", "review_kindhand", "battle_front", "battle_farstring", "battle_kindhand", "result_front", "result_farstring", "result_kindhand"]
|
|
const VIEWPORT_SIZE := Vector2i(844, 390)
|
|
|
|
var output_root := ""
|
|
var failures: Array[String] = []
|
|
|
|
|
|
func _initialize() -> void:
|
|
call_deferred("run_test")
|
|
|
|
|
|
func run_test() -> void:
|
|
output_root = OS.get_environment("ABG_P9_0R7_CAPTURE_ROOT")
|
|
if output_root.is_empty():
|
|
output_root = "/tmp/abg-p9-0r7-preview"
|
|
DirAccess.make_dir_recursive_absolute(output_root)
|
|
var 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(12)
|
|
game.locale = "zh_CN"
|
|
game.text_scale = 1.0
|
|
game.reduced_motion = false
|
|
game.muted = true
|
|
for index in range(STATES.size()):
|
|
apply_state(game, STATES[index])
|
|
game.render()
|
|
await settle(7)
|
|
verify_interactive_bounds(game, Rect2(Vector2.ZERO, Vector2(VIEWPORT_SIZE)), STATES[index])
|
|
await RenderingServer.frame_post_draw
|
|
var image := viewport.get_texture().get_image()
|
|
var path := output_root.path_join("%02d-%s.png" % [index + 1, STATES[index]])
|
|
var error := image.save_png(path)
|
|
if error != OK:
|
|
failures.append("capture %s failed with %s" % [STATES[index], error])
|
|
game.queue_free()
|
|
viewport.queue_free()
|
|
await settle(120)
|
|
if failures.is_empty():
|
|
print("ABG_P9_0R7_PREVIEW_CAPTURE_OK frames=11 viewport=844x390 locale=zh_CN min_touch=44 root=%s" % output_root)
|
|
call_deferred("finish", 0)
|
|
else:
|
|
for failure in failures:
|
|
push_error(failure)
|
|
call_deferred("finish", 1)
|
|
|
|
|
|
func apply_state(game: Control, state_name: String) -> void:
|
|
var original_rear := "Farstring"
|
|
var added := "Kindhand"
|
|
var item := ""
|
|
if state_name == "training_two":
|
|
item = "EQ-002"
|
|
added = ""
|
|
prepare_second_cycle_result(game, item, original_rear, added)
|
|
match state_name:
|
|
"training_two":
|
|
game.page = game.AppPage.TRAINING
|
|
"training_three":
|
|
game.training_choice = "added"
|
|
game.page = game.AppPage.TRAINING
|
|
"review_front":
|
|
game.training_choice = "front"
|
|
game.page = game.AppPage.TRAINING_REVIEW
|
|
"review_farstring":
|
|
game.training_choice = "rear"
|
|
game.page = game.AppPage.TRAINING_REVIEW
|
|
"review_kindhand":
|
|
game.training_choice = "added"
|
|
game.page = game.AppPage.TRAINING_REVIEW
|
|
"battle_front":
|
|
prepare_fifth_battle(game, "front", 2, 90, 100, 140)
|
|
game.retained_item = "EQ-002"
|
|
game.emit_battle_feedback(2, "front", -10, "历练减伤", "trained mitigation", "medium")
|
|
game.battle_feedback_clock = 0.16
|
|
"battle_farstring":
|
|
prepare_fifth_battle(game, "rear", 1, 100, 100, 110)
|
|
game.emit_battle_feedback(1, "enemy", -30, "历练先射", "trained early shot", "medium")
|
|
game.battle_feedback_clock = 0.16
|
|
"battle_kindhand":
|
|
prepare_fifth_battle(game, "added", 5, 55, 85, 80)
|
|
game.emit_battle_feedback(5, "rear", 25, "历练强疗", "trained recovery", "medium")
|
|
game.battle_feedback_clock = 0.16
|
|
"result_front":
|
|
prepare_result(game, "front", "EQ-002", 90, 72, 7.40)
|
|
"result_farstring":
|
|
prepare_result(game, "rear", "", 55, 72, 6.40)
|
|
"result_kindhand":
|
|
prepare_result(game, "added", "", 55, 85, 7.40)
|
|
|
|
|
|
func prepare_second_cycle_result(game: Control, item: String, original_rear: String, extra_rear: String) -> void:
|
|
game.clear_experience()
|
|
game.front_choice = "Hearthguard"
|
|
game.rear_choice = original_rear
|
|
game.adaptation_choice = item if not item.is_empty() else "EQ-061"
|
|
game.adaptation_committed = true
|
|
game.guild_committed = true
|
|
game.guild_choice = "retain_item" if extra_rear.is_empty() else "recruit_rear"
|
|
game.retained_item = item
|
|
game.added_rear = extra_rear
|
|
game.coin = 12
|
|
game.route_choice = "R6-01"
|
|
game.route_committed = true
|
|
game.route_reward_committed = true
|
|
game.front_hp = 90
|
|
game.rear_hp = 100
|
|
game.enemy_hp = 0
|
|
game.fourth_result_time = 7.40
|
|
game.page = game.AppPage.SECOND_CYCLE_RESULT
|
|
|
|
|
|
func prepare_fifth_battle(game: Control, slot: String, phase: int, front_health: int, rear_health: int, enemy_health: int) -> void:
|
|
game.training_choice = slot
|
|
game.training_committed = true
|
|
game.trained_member = slot
|
|
game.page = game.AppPage.FIFTH_BATTLE
|
|
game.battle_playing = false
|
|
game.battle_phase = phase
|
|
game.battle_clock = 0.18
|
|
game.front_hp = front_health
|
|
game.rear_hp = rear_health
|
|
game.enemy_hp = enemy_health
|
|
|
|
|
|
func prepare_result(game: Control, slot: String, item: String, front_health: int, rear_health: int, result_time: float) -> void:
|
|
game.retained_item = item
|
|
game.training_choice = slot
|
|
game.training_committed = true
|
|
game.trained_member = slot
|
|
game.fifth_reward_committed = true
|
|
game.coin = 20
|
|
game.front_hp = front_health
|
|
game.rear_hp = rear_health
|
|
game.enemy_hp = 0
|
|
game.fifth_result_time = result_time
|
|
game.page = game.AppPage.THIRD_CYCLE_RESULT
|
|
|
|
|
|
func verify_interactive_bounds(node: Node, bounds: Rect2, label: String) -> void:
|
|
if node is BaseButton and node.is_visible_in_tree():
|
|
var rect: Rect2 = node.get_global_rect()
|
|
if rect.position.x < -0.5 or rect.position.y < -0.5 or rect.end.x > bounds.end.x + 0.5 or rect.end.y > bounds.end.y + 0.5:
|
|
failures.append("%s button %s outside viewport: %s" % [label, node.name, rect])
|
|
if rect.size.x < 44.0 or rect.size.y < 44.0:
|
|
failures.append("%s button %s below 44px: %s" % [label, node.name, rect.size])
|
|
for child in node.get_children():
|
|
verify_interactive_bounds(child, bounds, label)
|
|
|
|
|
|
func finish(exit_code: int) -> void:
|
|
quit(exit_code)
|
|
|
|
|
|
func settle(frames: int) -> void:
|
|
for frame in range(frames):
|
|
await process_frame
|