extends Node2D # Draws the transport vessels GameState is simulating, and only while they # are somewhere the player could see them. Same arrangement as HaulerField, # and for the same reason: the simulation is authoritative and the visuals # are optional, so a run happening far away costs nothing but still moves # ore. Position comes from the very same `progress` that decides when the # ore actually changes hands. @export var visible_radius: float = 2600.0 @onready var fleet: Node2D = get_node("../Fleet") var transporter_scene: PackedScene = preload("res://logistics/Transporter.tscn") # index into GameState.transporters -> live node var active: Dictionary = {} func _process(_delta: float) -> void: var centre: Vector2 = fleet.get_centroid() for i in range(GameState.transporters.size()): var t: Dictionary = GameState.transporters[i] var pos: Vector2 = GameState.transporter_position(t) if pos.distance_to(centre) > visible_radius: _despawn(i) continue var node: Node2D = active.get(i) if node == null or not is_instance_valid(node): node = transporter_scene.instantiate() get_parent().add_child(node) active[i] = node var previous: Vector2 = node.position node.position = pos node.set_laden(int(t.carrying) > 0) var travel: Vector2 = pos - previous if travel.length() > 0.5: node.rotation = travel.angle() + PI / 2.0 for key in active.keys(): if key >= GameState.transporters.size(): _despawn(key) func _despawn(index: int) -> void: var node: Node2D = active.get(index) if node != null and is_instance_valid(node): node.queue_free() active.erase(index)