extends Node const AURA_REFRESH := 0.5 var active_auras: Dictionary = {} func _ready() -> void: EventBus.role_changed.connect(_on_role_changed) EventBus.entity_died.connect(_on_entity_died) func _process(_delta: float) -> void: for entity in active_auras.keys(): if not is_instance_valid(entity): active_auras.erase(entity) continue for aura in active_auras[entity]: _propagate(entity, aura) func _propagate(source_entity: Node, aura: Effect) -> void: if not source_entity is Node3D: return var buff_system: Node = get_node("../BuffSystem") var players := get_tree().get_nodes_in_group("player") for player in players: if not is_instance_valid(player) or not PlayerData.alive: continue var dist: float = source_entity.global_position.distance_to(player.global_position) if dist > aura.aura_radius: continue if buff_system.has_aura_buff(player, aura.effect_name, source_entity): buff_system.refresh_aura_buff(player, aura.effect_name, source_entity, AURA_REFRESH) else: var buff := Effect.new() buff.effect_name = aura.effect_name buff.type = Effect.Type.BUFF buff.stat = aura.stat buff.value = aura.value buff.duration = AURA_REFRESH buff.is_multiplier = aura.is_multiplier buff_system.apply_aura_buff(player, buff, source_entity) func _on_role_changed(player: Node, _role_type: int) -> void: active_auras.erase(player) var ability_set: AbilitySet = PlayerData.ability_set if not ability_set: return for ability in ability_set.abilities: if ability and ability.type == Ability.Type.PASSIVE: var effect := Effect.new() effect.effect_name = ability.ability_name effect.type = Effect.Type.AURA effect.stat = ability.passive_stat effect.value = ability.damage / 100.0 effect.duration = -1.0 effect.is_multiplier = true effect.aura_radius = ability.ability_range if not active_auras.has(player): active_auras[player] = [] active_auras[player].append(effect) func _on_entity_died(entity: Node) -> void: active_auras.erase(entity)