extends SceneTree const PythonUISurface = preload("res://python_ui_surface.gd") const Python3DSurface = preload("res://python_3d_surface.gd") func _initialize() -> void: call_deferred("run") func _py(source: String) -> bool: return Metin2PythonHost.run_line(source) == "" func _pump_until(seconds: float, condition: Callable) -> bool: var deadline := Time.get_ticks_msec() + int(seconds * 1000.0) while Time.get_ticks_msec() < deadline: if condition.call(): return true await process_frame return condition.call() func run() -> void: root.size = Vector2i(1024, 768) var world = Python3DSurface.new() var ui = PythonUISurface.new() root.add_child(ui) root.add_child(world) ui.run_app() await _pump_until(15, func(): return _py( "import __main__, os, networkModule, introLogin, introSelect, game, player, background, chr, chrmgr\n" + "__main__._stream = [o for o in __import__('gc').get_objects() if isinstance(o, networkModule.MainStream)][0]" )) await _pump_until(20, func(): return _py("assert isinstance(_stream.curPhaseWindow, introLogin.LoginWindow)")) var host = OS.get_environment("MT_LIVE_HOST") var login = OS.get_environment("MT_LIVE_LOGIN") var pwd = OS.get_environment("MT_LIVE_PASSWORD") var auth_port = int(OS.get_environment("MT_LIVE_AUTH_PORT")) var game_port = int(OS.get_environment("MT_LIVE_GAME_PORT")) _py("_stream.SetConnectInfo('%s', %d, '%s', %d)\n_stream.curPhaseWindow.Connect('%s', '%s')" % [host, game_port, host, auth_port, login, pwd]) await _pump_until(30, func(): return _py("assert isinstance(_stream.curPhaseWindow, introSelect.SelectCharacterWindow)")) _py("_stream.curPhaseWindow.SelectSlot(0)\n_stream.curPhaseWindow.StartGame()") await _pump_until(30, func(): return _py("assert isinstance(_stream.curPhaseWindow, game.GameWindow) and _stream.curPhaseWindow.IsShow()")) for i in 60: await process_frame print("=== INSPECTING STONE TILES AROUND PLAYER (59700, 68200) ===") var draws: Array = Metin2PythonHost.render3d_draws() var player_z := 19851.5 for d in draws: var tex: String = d.get("texture0", "") if tex.contains("stone") or tex.contains("floor") or tex.contains("tile") or tex.contains("sign"): var wm: PackedFloat32Array = d["world"] var xform: Transform3D = Python3DSurface.d3d_transform(wm) # check if this object is near player (within 2000cm): if absf(xform.origin.x - 59700.0) < 3000.0 and absf(-xform.origin.y - 68200.0) < 3000.0: var min_z := 1e9 var max_z := -1e9 for p in d["positions"]: var wp: Vector3 = xform * p min_z = minf(min_z, wp.z) max_z = maxf(max_z, wp.z) print("Object [%s] at (%.1f, %.1f, %.1f), Z range: [%.2f, %.2f], diff vs player_z(19851.5): min=%.2f, max=%.2f" % [ tex.get_file(), xform.origin.x, -xform.origin.y, xform.origin.z, min_z, max_z, min_z - player_z, max_z - player_z ]) quit(0)