extends Node func _ready() -> void: EventBus.damage_requested.connect(_on_damage_requested) EventBus.heal_requested.connect(_on_heal_requested) if multiplayer.multiplayer_peer != null and not multiplayer.is_server() and not (multiplayer.multiplayer_peer is OfflineMultiplayerPeer): set_physics_process(false) else: set_physics_process(true) var _regen_accum: float = 0.0 func _physics_process(delta: float) -> void: if not multiplayer.is_server() and multiplayer.multiplayer_peer != null: return _regen_accum += delta if _regen_accum < 0.20: return var dt: float = _regen_accum _regen_accum = 0.0 for entity in Stats.entities(): if not is_instance_valid(entity): continue var hp: float = float(Stats.get_stat(entity, "health", 0.0)) var max_hp: float = float(Stats.get_stat(entity, "max_health", 0.0)) var regen: float = float(Stats.get_stat(entity, "health_regen", 0.0)) if regen > 0.0 and hp > 0.0 and hp < max_hp: var new_hp: float = min(max_hp, hp + regen * dt) Stats.set_stat(entity, "health", new_hp) EventBus.health_changed.emit(entity, new_hp, max_hp) func _on_damage_requested(attacker: Node, target: Node, amount: float, element: int) -> void: if not multiplayer.is_server() and multiplayer.multiplayer_peer != null: return if not is_instance_valid(target) or not Stats.has(target): return var hp: float = float(Stats.get_stat(target, "health", 0.0)) if hp <= 0.0: return var remaining := amount var shield: float = float(Stats.get_stat(target, "shield", 0.0)) if shield > 0.0: var absorbed: float = min(shield, remaining) Stats.set_stat(target, "shield", shield - absorbed) Stats.set_stat(target, "shield_regen_timer", float(Stats.get_stat(target, "shield_regen_delay", 5.0))) remaining -= absorbed EventBus.shield_changed.emit(target, Stats.get_stat(target, "shield"), Stats.get_stat(target, "max_shield", 0.0)) if shield - absorbed <= 0.0: EventBus.shield_broken.emit(target) if remaining > 0.0: var new_hp: float = max(0.0, hp - remaining) Stats.set_stat(target, "health", new_hp) EventBus.health_changed.emit(target, new_hp, Stats.get_stat(target, "max_health")) EventBus.damage_dealt.emit(attacker, target, amount) if new_hp <= 0.0: EventBus.entity_died.emit(target) func _on_heal_requested(healer: Node, target: Node, amount: float) -> void: if not multiplayer.is_server() and multiplayer.multiplayer_peer != null: return if not is_instance_valid(target) or not Stats.has(target): return var hp: float = float(Stats.get_stat(target, "health", 0.0)) if hp <= 0.0: return var max_hp: float = float(Stats.get_stat(target, "max_health", 0.0)) var new_hp: float = min(max_hp, hp + amount) Stats.set_stat(target, "health", new_hp) EventBus.health_changed.emit(target, new_hp, max_hp)