grunk/src/equipment/wide_spray/wide_spray.gd
2025-07-08 23:13:27 -06:00

77 lines
1.9 KiB
GDScript

class_name WideSpray extends Spray
## Wide spray pattern
const SPRAYCAST_GROUP := "SprayCast"
@export var spray_scale := 1.0
# NOTE: this is damage _per spray_, so multiply by up to 7 damage per frame depending on spread.
@export var damage := 0.015
var _horizontal := true
var _busy := false
@onready var spray_casts: Node3D = %SprayCasts
@onready var animation_player: AnimationPlayer = %AnimationPlayer
@onready var spray_sfx: SpraySFX = %SpraySFX
func switch_mode() -> void:
if not _busy:
if _horizontal:
animation_player.play("rotate")
else:
animation_player.play_backwards("rotate")
_horizontal = not _horizontal
_busy = true
else:
# TODO: bonk
pass
func _fire() -> void:
if _busy:
idle()
else:
super._fire()
func _spray() -> void:
var prev_target: Gunkable = null
var prev_point: Vector3
var prev_normal: Vector3
for laser: LaserCast in spray_casts.get_children():
if laser.is_colliding():
spray_sfx.activate()
spray_sfx.set_angle_from_normal(laser.get_collision_normal())
var collider := laser.get_collider()
var gunk_component := Gunkable.get_component(collider)
if gunk_component:
var point := laser.get_collision_point()
var normal := laser.get_collision_normal()
# Always paint at least a dot, to cap the ends of the line
gunk_component.paint_dot(point, normal, spray_scale)
if gunk_component == prev_target:
# Continue the multiline if possible
gunk_component.add_to_multiline(
prev_point, prev_normal, point, normal, spray_scale * 2
)
prev_point = point
prev_normal = normal
prev_target = gunk_component
prev_point = point
prev_normal = normal
elif collider is Sprayable:
(collider as Sprayable).hit(damage)
func _on_animation_finished(anim_name: StringName) -> void:
if anim_name == "rotate":
_busy = false
func on_equip() -> void:
Tutorial.manager.activate("game/tutorial/progress/mode_switch")