Files

52 lines
1.5 KiB
GDScript

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)