extends Node2D ## Root of the playable client scene. Wires the view and HUD to whatever client ## runtime [Net] currently has, and survives that runtime being null (during ## connection) or replaced (on reconnect). @onready var world_view: Node2D = $WorldView @onready var hud: CanvasLayer = $HUD @onready var menu: CanvasLayer = $GameMenu var _bound: ClientRuntime = null func _ready() -> void: _recentre() get_viewport().size_changed.connect(_recentre) menu.return_to_hub_requested.connect(_on_return_to_hub) menu.disconnect_requested.connect(_on_disconnect) hud.respawn_pressed.connect(_on_respawn_pressed) var _screen_centre := Vector2.ZERO func _recentre() -> void: _screen_centre = get_viewport_rect().size * 0.5 ## Scroll the world so the local player stays centred. Dungeons are larger than ## the viewport now, so a fixed camera would simply lose the player off-screen. func _follow_camera() -> void: var focus := Vector2.ZERO if _bound != null: focus = _bound.predicted_pos world_view.position = _screen_centre - focus if _bound != null: # The client converts cursor position to world space with this, so it # has to come from the transform actually used to draw, not from a # second assumption about where the camera is. _bound.camera_offset = world_view.position func _process(_delta: float) -> void: if Net.client != _bound: _bound = Net.client if _bound != null and not _bound.local_hit.is_connected(_on_local_hit): _bound.local_hit.connect(_on_local_hit) _follow_camera() menu.set_in_dungeon(_bound != null and _bound.instance_kind == Protocol.InstanceKind.DUNGEON) ## Routed through the same held-escape channel the F key uses, rather than a ## direct "teleport me" message -- the server has no such message, and adding ## one would hand clients an instant, uninterruptible exit. func _on_return_to_hub() -> void: if _bound != null: _bound.request_escape = true func _on_disconnect() -> void: Net.shutdown() ## Sets the intent bit; the server decides whether the lockout has expired. func _on_respawn_pressed() -> void: if _bound != null: _bound.request_respawn = true func _on_local_hit(_damage: int) -> void: hud.flash_hit()