extends StaticBody2D const VFX := preload("res://scripts/game/extension_vfx.gd") const LIFETIME := 10.0 const MAX_PARTICLES := 80 var drift := Vector2.ZERO var _age := 0.0 var _emission := 0.0 var _particles: Array[Dictionary] = [] var _rng := RandomNumberGenerator.new() var _launch_direction := Vector2.DOWN func _ready() -> void: add_to_group("player_flares") collision_layer = 16 collision_mask = 0 z_index = 23 _rng.randomize() _launch_direction = drift.normalized() if drift.length_squared() > 0.01 else Vector2.DOWN var collision := CollisionShape2D.new() var shape := CircleShape2D.new() shape.radius = 9.0 collision.shape = shape add_child(collision) func _physics_process(delta: float) -> void: _age += delta position += drift * delta drift = drift.move_toward(Vector2.ZERO, 35.0 * delta) queue_redraw() if _age >= LIFETIME: queue_free() func _process(delta: float) -> void: for index in range(_particles.size() - 1, -1, -1): var particle := _particles[index] particle["age"] = float(particle["age"]) + delta particle["position"] = Vector2(particle["position"]) + Vector2(particle["velocity"]) * delta particle["velocity"] = Vector2(particle["velocity"]) * exp(-1.8 * delta) if float(particle["age"]) >= float(particle["life"]): _particles.remove_at(index) _emission += delta while _emission >= 0.018 and _particles.size() < MAX_PARTICLES: _emission -= 0.018 var side := Vector2(-_launch_direction.y, _launch_direction.x) _particles.append({"position": global_position, "velocity": -_launch_direction * _rng.randf_range(15, 55) + side * _rng.randf_range(-18, 18), "age": 0.0, "life": _rng.randf_range(0.35, 0.85), "size": _rng.randf_range(1, 2.4)}) _emission = minf(_emission, 0.018) queue_redraw() func take_damage(_amount: float) -> void: # Countermeasure burns for the full ten seconds even when hit. pass func _draw() -> void: var fade := clampf(LIFETIME - _age, 0.0, 1.0) var flicker := 0.90 + 0.06 * sin(_age * 29.0) + 0.04 * sin(_age * 47.0) var glow := VFX.radial_texture() for particle in _particles: var remaining := 1.0 - float(particle["age"]) / float(particle["life"]) var point := to_local(Vector2(particle["position"])) var radius := (5.0 + float(particle["age"]) * 10.0) * remaining draw_texture_rect(glow, Rect2(point - Vector2.ONE * radius, Vector2.ONE * radius * 2), false, Color(0.9, 0.25, 0.04, remaining * 0.16 * fade)) var spark_color := Color(1.0, lerpf(0.24, 0.85, remaining), lerpf(0.02, 0.4, remaining), remaining * fade) draw_line(point, point - Vector2(particle["velocity"]).normalized() * 5.0 * remaining, spark_color, float(particle["size"]) * remaining, true) var radius := 48.0 * flicker draw_texture_rect(glow, Rect2(-radius, -radius, radius * 2, radius * 2), false, Color(1.0, 0.28, 0.025, 0.52 * fade)) draw_texture_rect(glow, Rect2(-22, -22, 44, 44), false, Color(1.0, 0.66, 0.18, 0.9 * fade)) draw_texture_rect(glow, Rect2(-8, -8, 16, 16), false, Color(1.0, 0.97, 0.82, fade)) draw_circle(Vector2.ZERO, 2.4 * flicker, Color(1.0, 0.99, 0.9, fade)) draw_line(Vector2(-15, 0), Vector2(15, 0), Color(1.0, 0.74, 0.32, fade * 0.34), 1.0, true) draw_line(Vector2(0, -10), Vector2(0, 10), Color(1.0, 0.8, 0.4, fade * 0.22), 1.0, true)