extends Node func _process(delta: float) -> void: _process_player(delta) _process_entities(delta, EnemyData.entities) _process_entities(delta, BossData.entities) func _process_player(delta: float) -> void: if not PlayerData.alive or PlayerData.max_shield <= 0: return if PlayerData.shield < PlayerData.max_shield: PlayerData.shield_regen_timer += delta if PlayerData.shield_regen_timer >= PlayerData.shield_regen_delay: var regen_rate: float = PlayerData.max_shield / PlayerData.shield_regen_time var shield: float = PlayerData.shield + regen_rate * delta if shield >= PlayerData.max_shield: shield = PlayerData.max_shield EventBus.shield_regenerated.emit(get_tree().get_first_node_in_group("player")) PlayerData.set_shield(shield) func _process_entities(delta: float, entities: Dictionary) -> void: for entity in entities: if not is_instance_valid(entity): continue var data: Dictionary = entities[entity] if not data["alive"]: continue var max_shield: float = data["max_shield"] if max_shield <= 0: continue var shield: float = data["shield"] if shield < max_shield: data["shield_regen_timer"] += delta if data["shield_regen_timer"] >= data["shield_regen_delay"]: var regen_rate: float = max_shield / data["shield_regen_time"] shield += regen_rate * delta if shield >= max_shield: shield = max_shield EventBus.shield_regenerated.emit(entity) data["shield"] = shield EventBus.shield_changed.emit(entity, shield, max_shield) func absorb(target: Node, amount: float) -> float: var player: Node = get_tree().get_first_node_in_group("player") if target == player: if PlayerData.shield <= 0: return amount PlayerData.shield_regen_timer = 0.0 var absorbed: float = min(amount, PlayerData.shield) var shield: float = PlayerData.shield - absorbed PlayerData.set_shield(shield) if shield <= 0: EventBus.shield_broken.emit(target) return amount - absorbed var data_source: Node = _get_data_source(target) if not data_source: return amount var shield: float = data_source.get_stat(target, "shield") if shield == null or shield <= 0: return amount data_source.set_stat(target, "shield_regen_timer", 0.0) var absorbed: float = min(amount, shield) shield -= absorbed data_source.set_shield(target, shield) if shield <= 0: EventBus.shield_broken.emit(target) return amount - absorbed func _get_data_source(entity: Node) -> Node: if entity.is_in_group("boss"): return BossData elif entity.is_in_group("enemies"): return EnemyData return null