Implement playable Mac client and rendering validation
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
extends Node
|
||||
|
||||
## 离线加载实际鬼木林/赤鬼木林地图,并把树怪放进生产 GameScene 的实体挂载点。
|
||||
## 服务器刷新、选中、战斗和掉落仍由 playable_live_test 负责。
|
||||
|
||||
const GameScene = preload("res://game_scene.gd")
|
||||
const Fixtures = preload("res://gamescene_test.gd")
|
||||
const MobView = preload("res://ui/mob_view.gd")
|
||||
const Config = preload("res://testing/playable_config.gd")
|
||||
const PlayableReport = preload("res://testing/playable_report.gd")
|
||||
|
||||
var failures := 0
|
||||
|
||||
func _ready() -> void:
|
||||
call_deferred("run")
|
||||
|
||||
func _fail(message: String) -> void:
|
||||
failures += 1
|
||||
printerr("FOREST MAP FAIL: " + message)
|
||||
|
||||
func run() -> void:
|
||||
var map_key := OS.get_environment("MT_FOREST_MAP")
|
||||
var config_path := OS.get_environment("MT_PLAYABLE_CONFIG")
|
||||
var loaded_config := Config.load_file(config_path) if not config_path.is_empty() else {"ok": false, "config": {}}
|
||||
if map_key.is_empty() and loaded_config.ok:
|
||||
map_key = String(loaded_config.config.get("map_key", ""))
|
||||
if map_key.is_empty():
|
||||
map_key = "outdoortrent/metin2_map_trent"
|
||||
var race := int(OS.get_environment("MT_FOREST_MOB_RACE")) if not OS.get_environment("MT_FOREST_MOB_RACE").is_empty() else 2301
|
||||
var output := OS.get_environment("MT_TEST_OUTPUT")
|
||||
if output.is_empty():
|
||||
output = ProjectSettings.globalize_path("res://../build/rendering/forest-map-%d" % Time.get_unix_time_from_system())
|
||||
DirAccess.make_dir_recursive_absolute(output)
|
||||
var playable_report := PlayableReport.new()
|
||||
playable_report.begin(OS.get_environment("MT_PLAYABLE_RUN_ID"), "playable", loaded_config.config if loaded_config.ok else {})
|
||||
get_tree().root.size = Vector2i(1280, 720)
|
||||
print("FOREST MAP: loading %s" % map_key)
|
||||
var client := Fixtures.FakeClient.new()
|
||||
# Server-space values chosen inside the corresponding local map rectangle.
|
||||
# GameScene/MapCoord performs the actual base-position conversion.
|
||||
var base_x := 0.0 if map_key == "outdoortrent/metin2_map_trent" else 1049600.0
|
||||
var server_x := base_x + 12800.0
|
||||
var server_y := 12800.0
|
||||
client.spawn(1000, "ForestRender", Vector3(server_x * 0.01, 0.0, -server_y * 0.01), true)
|
||||
var scene := GameScene.new()
|
||||
get_tree().root.add_child(scene)
|
||||
await scene.setup(client, AssetRoot.path(), map_key)
|
||||
print("FOREST MAP: GameScene setup complete")
|
||||
if not scene._map_loaded():
|
||||
_fail("map did not load: %s" % map_key)
|
||||
if not scene._model_built or scene.player == null:
|
||||
_fail("local player model is not ready")
|
||||
var entities := scene.get_node_or_null("Entities")
|
||||
if entities == null:
|
||||
_fail("GameScene entity mount is missing")
|
||||
var positions := [Vector3(12.0, 0.0, 18.0), Vector3(15.0, 0.0, 21.0)]
|
||||
var monster := MobView.new()
|
||||
monster.name = "ForestTreeMonster_%d" % race
|
||||
if not monster.build(AssetRoot.path(), null, race):
|
||||
_fail("tree monster build failed race=%d" % race)
|
||||
else:
|
||||
entities.add_child(monster)
|
||||
monster.position = positions[0]
|
||||
monster.set_anim_state("wait")
|
||||
client.spawn(23001, "TreeMonster", Vector3(positions[0].x * 100.0, 0.0, -positions[0].z * 100.0))
|
||||
await get_tree().process_frame
|
||||
if monster.model == null or monster.model.call("get_visual_aabb").size.length() <= 0.0:
|
||||
_fail("tree monster has no visible geometry")
|
||||
if scene.cam and scene.cam.has_method("snap_to_target"):
|
||||
scene.cam.snap_to_target()
|
||||
await get_tree().process_frame
|
||||
await get_tree().process_frame
|
||||
var image_name := "forest-map-%s.png" % map_key.get_file()
|
||||
if DisplayServer.get_name() != "headless":
|
||||
await RenderingServer.frame_post_draw
|
||||
if get_tree().root.get_texture().get_image().save_png(output.path_join(image_name)) != OK:
|
||||
_fail("map screenshot could not be saved")
|
||||
var report := {"passed": failures == 0, "failures": failures, "map": map_key,
|
||||
"tree_monster_race": race, "tree_monster_model": monster.model != null,
|
||||
"map_loaded": scene._map_loaded(), "screenshot": image_name if DisplayServer.get_name() != "headless" else "",
|
||||
"assets": AssetRoot.path(), "headless": DisplayServer.get_name() == "headless",
|
||||
"scope": "production GameScene map load plus offline tree-monster placement; no server spawn"}
|
||||
var file := FileAccess.open(output.path_join("report.json"), FileAccess.WRITE)
|
||||
if file:
|
||||
file.store_string(JSON.stringify(report, "\t"))
|
||||
file.close()
|
||||
var client_report_path := OS.get_environment("MT_TEST_REPORT")
|
||||
if not client_report_path.is_empty():
|
||||
playable_report.add_case("MAP-FOREST-01", "PASS" if failures == 0 else "FAIL",
|
||||
"map=%s tree_monster_race=%d" % [map_key, race])
|
||||
playable_report.write(client_report_path)
|
||||
print("FOREST MAP RENDER: ", JSON.stringify(report))
|
||||
scene.queue_free()
|
||||
client.queue_free()
|
||||
await get_tree().process_frame
|
||||
get_tree().quit(1 if failures else 0)
|
||||
Reference in New Issue
Block a user