extends Node2D var player: CharacterBody2D var _particles: Array[Dictionary] = [] var _emission := 0.0 var _phase := 0.0 func _ready() -> void: top_level = true process_physics_priority = 1 global_position = player.global_position reset_physics_interpolation() z_index = 22 func _physics_process(_delta: float) -> void: if is_instance_valid(player): global_position = player.global_position func _process(delta: float) -> void: if not is_instance_valid(player): return _phase += delta var bonus := float(player.call("get_solar_regeneration")) var charging := bonus > 0.0 and float(player.get("energy")) < float(player.get("max_energy")) if charging: _emission += delta * 30.0 while _emission >= 1.0 and _particles.size() < 32: _emission -= 1.0 var star: Node2D = player.get("charging_star") var direction := (global_position - star.global_position).normalized() var source := star.global_position + direction * float(star.get("radius")) source += direction.orthogonal() * randf_range(-35.0, 35.0) _particles.append({"source": source, "age": 0.0, "duration": randf_range(0.45, 0.8)}) else: _emission = 0.0 for index in range(_particles.size() - 1, -1, -1): _particles[index]["age"] += delta if _particles[index]["age"] >= _particles[index]["duration"]: _particles.remove_at(index) queue_redraw() func _draw() -> void: if not is_instance_valid(player) or bool(player.get("_is_destroyed")): return for particle in _particles: var progress: float = particle["age"] / particle["duration"] var source: Vector2 = particle["source"] - global_position var point := source.lerp(Vector2.ZERO, progress * progress) var tail := source.lerp(Vector2.ZERO, maxf(0, progress - 0.06) ** 2) var color := Color(0.35, 0.92, 1.0, sin(progress * PI)) draw_line(tail, point, color, 2.0, true) draw_circle(point, 2.5, color) if not _particles.is_empty(): draw_arc(Vector2.ZERO, 31.0 + sin(_phase * 5.0) * 2.0, 0, TAU, 48, Color(0.35, 0.92, 1.0, 0.45), 2.0, true)