extends StaticBody3D @export var stats_resource: GateStats @export var is_red: bool = false @onready var mesh: MeshInstance3D = $Mesh @onready var healthbar: MeshInstance3D = $Healthbar @onready var name_label: Label3D = $NameLabel @onready var spawn_point: Node3D = $SpawnPoint var spawn_timer: float = 0.0 var spawned_count: int = 0 var dead: bool = false func _enter_tree() -> void: set_multiplayer_authority(1) func _ready() -> void: add_to_group("gates") if is_red: add_to_group("red_gate") if stats_resource == null: stats_resource = GateStats.new() if is_red: stats_resource.max_health = 600.0 stats_resource.spawn_count = 8 else: stats_resource.max_health = 200.0 stats_resource.spawn_count = 5 stats_resource.is_red = is_red Stats.register(self, stats_resource) EventBus.health_changed.connect(_on_health_changed) EventBus.entity_died.connect(_on_entity_died) if is_red: var mat: StandardMaterial3D = StandardMaterial3D.new() mat.albedo_color = Color(0.95, 0.2, 0.15) mat.emission_enabled = true mat.emission = Color(1.0, 0.4, 0.2) mat.emission_energy_multiplier = 0.6 mesh.material_override = mat name_label.text = "Red Gate" else: name_label.text = "Gate" set_physics_process(true) func _exit_tree() -> void: Stats.deregister(self) func _physics_process(delta: float) -> void: if dead: return if not multiplayer.is_server() and multiplayer.multiplayer_peer != null: return spawn_timer = max(0.0, spawn_timer - delta) if spawn_timer <= 0.0 and spawned_count < int(Stats.get_stat(self, "spawn_count", 5)): var spawn_sys: Node = get_node_or_null("/root/World/Systems/SpawnSystem") if spawn_sys and spawn_sys.has_method("spawn_enemy_at"): spawn_sys.spawn_enemy_at(spawn_point.global_position + Vector3(randf_range(-1.5, 1.5), 0.0, randf_range(-1.5, 1.5)), is_red) spawned_count += 1 spawn_timer = float(Stats.get_stat(self, "spawn_interval", 4.0)) func _on_health_changed(entity: Node, current: float, max: float) -> void: if entity != self: return var ratio: float = clamp(current / max if max > 0 else 0.0, 0.0, 1.0) healthbar.scale.x = max(0.01, ratio * 2.0) func _on_entity_died(entity: Node) -> void: if entity != self or dead: return dead = true if multiplayer.is_server() or multiplayer.multiplayer_peer == null: var spawn_sys: Node = get_node_or_null("/root/World/Systems/SpawnSystem") if spawn_sys and spawn_sys.has_method("spawn_portal_at"): spawn_sys.spawn_portal_at(global_position, is_red) EventBus.gate_destroyed.emit(self) var t := get_tree().create_timer(0.5) t.timeout.connect(func(): if is_instance_valid(self): queue_free())