extends Area3D class_name HealthOrb ## Floating pickup that restores health when a player walks into it. ## Server-authoritative pickup; the bob/spin visuals run locally on every peer. @export var heal_amount: float = 25.0 @export var bob_height: float = 0.3 @export var bob_speed: float = 2.0 @export var spin_speed: float = 2.0 var orb_id: int = -1 # Assigned by Level when spawned var _base_y: float = 0.0 var _time: float = 0.0 var _collected: bool = false @onready var _mesh: Node3D = get_node_or_null("Mesh") func _ready(): _base_y = position.y _time = randf() * TAU # Random phase so multiple orbs don't bob in unison # Detect players (physics layer 1) without colliding with anything collision_layer = 0 collision_mask = 1 # Only the server resolves pickups if multiplayer.is_server(): body_entered.connect(_on_body_entered) func _process(delta): _time += delta position.y = _base_y + sin(_time * bob_speed) * bob_height if _mesh: _mesh.rotate_y(spin_speed * delta) func _on_body_entered(body: Node3D): if _collected or not multiplayer.is_server(): return if not (body is Character) or body.is_dead: return # Leave the orb in place if the player is already at full health if body.current_health >= body.max_health: return _collected = true body.heal(heal_amount) # Remove the orb from every client via the level's centralized system var level = get_tree().get_current_scene() if level and level.has_method("remove_health_orb"): level.remove_health_orb(orb_id)