extends Node2D # Forgejo #87: a brief spray of sparks off the hull that just fired. # # Firing was silent at the ship's end - a bolt simply appeared in front of it. # With a whole fleet shooting there was nothing tying a shot to the vessel it # came from, which mattered more once the player started aiming: you could not # see which of your ships were actually in the fight. # # Deliberately tiny and short. This fires several times a second per vessel, # so it has to be legible at a glance and gone before the next one - anything # with weight would turn a firing fleet into a smear. # # No class_name, and it loads itself by path: a global class-name identifier # is not reliably resolvable from a script reached through a preload chain, # which is what happens here. Same reason as ResourcePickupVFX. const SELF_PATH: String = "res://vfx/MuzzleSparkVFX.gd" const SPARK_COUNT: int = 4 const DURATION: float = 0.13 const SPREAD: float = 0.5 const LENGTH: float = 9.0 const COLOR: Color = Color(1.0, 0.88, 0.42) var age: float = 0.0 var color: Color = COLOR var sparks: Array = [] # The colour is optional and defaults to the gun's own: #90 wanted the laser # to do something at the hull too, and a cyan weapon throwing gold sparks # would read as a different weapon firing from the same ship. static func spawn(parent: Node, world_position: Vector2, direction: Vector2, spark_color: Color = COLOR) -> void: if direction.length() < 0.001: return var vfx: Node2D = (load(SELF_PATH) as GDScript).new() vfx.position = world_position vfx.rotation = direction.angle() vfx.color = spark_color parent.add_child(vfx) func _ready() -> void: # Built once here rather than per frame: the streaks never change shape, # only how far along their own line they have travelled, so _draw reads # fixed values. Same discipline as the explosion particles. for i in range(SPARK_COUNT): sparks.append({ "angle": randf_range(-SPREAD, SPREAD), "speed": randf_range(190.0, 340.0), "length": randf_range(LENGTH * 0.6, LENGTH), }) queue_redraw() func _process(delta: float) -> void: age += delta if age >= DURATION: queue_free() return queue_redraw() func _draw() -> void: var t: float = clampf(age / DURATION, 0.0, 1.0) var fade: float = 1.0 - t for spark in sparks: var heading: Vector2 = Vector2.RIGHT.rotated(float(spark.angle)) var start: Vector2 = heading * float(spark.speed) * age var end: Vector2 = start + heading * float(spark.length) NeonDraw.draw_glowing_line(self, start, end, color, fade, 0.35, color.darkened(0.7))