135 lines
3.9 KiB
GDScript
135 lines
3.9 KiB
GDScript
extends SceneTree
|
|
|
|
const MainScene = preload("res://main.tscn")
|
|
|
|
const STATES := [
|
|
"title",
|
|
"yard_empty",
|
|
"yard_front",
|
|
"yard_ready",
|
|
"battle_pressure",
|
|
"victory",
|
|
]
|
|
|
|
var output_root := ""
|
|
var viewport_size := Vector2i(1280, 720)
|
|
var locale := "zh_CN"
|
|
var text_scale := 1.0
|
|
var failures: Array[String] = []
|
|
|
|
|
|
func _initialize() -> void:
|
|
call_deferred("run_test")
|
|
|
|
|
|
func run_test() -> void:
|
|
output_root = OS.get_environment("ABG_P9_0R1_CAPTURE_ROOT")
|
|
if output_root.is_empty():
|
|
output_root = "/tmp/abg-p9-0r1-captures"
|
|
viewport_size = Vector2i(
|
|
read_int("ABG_P9_0R1_VIEWPORT_WIDTH", 1280),
|
|
read_int("ABG_P9_0R1_VIEWPORT_HEIGHT", 720)
|
|
)
|
|
locale = read_string("ABG_P9_0R1_LOCALE", "zh_CN")
|
|
text_scale = read_float("ABG_P9_0R1_TEXT_SCALE", 1.0)
|
|
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
|
|
viewport.add_child(game)
|
|
await settle()
|
|
game.locale = locale
|
|
game.text_scale = text_scale
|
|
game.reduced_motion = true
|
|
game.muted = true
|
|
game.boot_verified = true
|
|
for index in range(STATES.size()):
|
|
await capture_state(viewport, game, index + 1, STATES[index])
|
|
game.queue_free()
|
|
viewport.queue_free()
|
|
await drain_cleanup()
|
|
if failures.is_empty():
|
|
print("ABG_P9_0R1_RUNTIME_CAPTURE_OK frames=6 viewport=%sx%s locale=%s text_scale=%.1f renderer=normal input_claim=none root=%s" % [viewport_size.x, viewport_size.y, locale, text_scale, output_root])
|
|
call_deferred("finish", 0)
|
|
else:
|
|
for failure in failures:
|
|
push_error(failure)
|
|
call_deferred("finish", 1)
|
|
|
|
|
|
func finish(exit_code: int) -> void:
|
|
quit(exit_code)
|
|
|
|
|
|
func capture_state(viewport: SubViewport, game: Control, index: int, state_name: String) -> void:
|
|
game.clear_experience()
|
|
apply_state(game, state_name)
|
|
game.render()
|
|
await settle()
|
|
await RenderingServer.frame_post_draw
|
|
var image := viewport.get_texture().get_image()
|
|
var path := output_root.path_join("%02d-%s.png" % [index, state_name])
|
|
var error := image.save_png(path)
|
|
if error != OK:
|
|
failures.append("capture %s failed with %s" % [state_name, error])
|
|
|
|
|
|
func apply_state(game: Control, state_name: String) -> void:
|
|
match state_name:
|
|
"title":
|
|
game.page = game.AppPage.TITLE
|
|
"yard_empty":
|
|
game.page = game.AppPage.YARD
|
|
game.notice = game.tr_text("先选前排:盾卫更稳,游侠更灵活。", "Choose the front: Guardian is steady, Runner is agile.")
|
|
"yard_front":
|
|
game.page = game.AppPage.YARD
|
|
game.front_choice = "Hearthguard"
|
|
game.notice = game.tr_text("艾连进入前排。现在选择一名后排。", "Elian joined the front. Now choose a rear role.")
|
|
"yard_ready":
|
|
game.page = game.AppPage.YARD
|
|
game.front_choice = "Hearthguard"
|
|
game.rear_choice = "Farstring"
|
|
game.notice = game.tr_text("妮娅进入后排。队伍已准备好。", "Nia joined the rear. The squad is ready.")
|
|
"battle_pressure":
|
|
game.page = game.AppPage.BATTLE
|
|
game.front_choice = "Hearthguard"
|
|
game.rear_choice = "Farstring"
|
|
game.battle_playing = false
|
|
game.battle_phase = 2
|
|
game.front_hp = 82
|
|
game.enemy_hp = 100
|
|
"victory":
|
|
game.page = game.AppPage.VICTORY
|
|
game.front_choice = "Hearthguard"
|
|
game.rear_choice = "Farstring"
|
|
game.front_hp = 82
|
|
game.enemy_hp = 0
|
|
|
|
|
|
func read_string(key: String, fallback: String) -> String:
|
|
var value := OS.get_environment(key)
|
|
return value if not value.is_empty() else fallback
|
|
|
|
|
|
func read_int(key: String, fallback: int) -> int:
|
|
var value := OS.get_environment(key)
|
|
return int(value) if not value.is_empty() else fallback
|
|
|
|
|
|
func read_float(key: String, fallback: float) -> float:
|
|
var value := OS.get_environment(key)
|
|
return float(value) if not value.is_empty() else fallback
|
|
|
|
|
|
func settle() -> void:
|
|
for frame in range(10):
|
|
await process_frame
|
|
|
|
|
|
func drain_cleanup() -> void:
|
|
for frame in range(120):
|
|
await process_frame
|