2025-03-02 12:00:42 -07:00
|
|
|
class_name WideSpray extends Spray
|
|
|
|
## Wide spray pattern
|
|
|
|
|
|
|
|
const SPRAYCAST_GROUP := "SprayCast"
|
|
|
|
|
2025-03-09 16:40:19 -06:00
|
|
|
@export var spray_scale := 1.0
|
2025-03-13 11:25:11 -06:00
|
|
|
# NOTE: this is damage _per spray_, so multiply by up to 7 damage per frame depending on spread.
|
|
|
|
@export var damage := 0.015
|
2025-03-02 12:00:42 -07:00
|
|
|
|
2025-03-12 11:23:21 -06:00
|
|
|
var _horizontal := true
|
|
|
|
var _busy := false
|
|
|
|
|
2025-03-02 12:00:42 -07:00
|
|
|
@onready var spray_casts: Node3D = %SprayCasts
|
2025-03-12 11:23:21 -06:00
|
|
|
@onready var animation_player: AnimationPlayer = %AnimationPlayer
|
2025-03-29 12:31:23 -06:00
|
|
|
@onready var spray_sfx: SpraySFX = %SpraySFX
|
2025-03-12 11:23:21 -06:00
|
|
|
|
|
|
|
|
|
|
|
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()
|
2025-03-02 12:00:42 -07:00
|
|
|
|
|
|
|
|
2025-03-12 11:03:41 -06:00
|
|
|
func _spray() -> void:
|
2025-03-02 12:00:42 -07:00
|
|
|
var prev_target: GunkBody = null
|
|
|
|
var prev_point: Vector3
|
|
|
|
var prev_normal: Vector3
|
|
|
|
|
2025-03-06 14:57:57 -07:00
|
|
|
for laser: LaserCast in spray_casts.get_children():
|
|
|
|
if laser.is_colliding():
|
2025-03-29 12:31:23 -06:00
|
|
|
spray_sfx.activate()
|
2025-04-03 12:49:53 -06:00
|
|
|
spray_sfx.set_angle_from_normal(laser.get_collision_normal())
|
2025-03-29 12:31:23 -06:00
|
|
|
|
2025-03-12 00:18:27 -06:00
|
|
|
var collider := laser.get_collider()
|
|
|
|
if collider is GunkBody:
|
|
|
|
var target := collider as GunkBody
|
2025-03-06 14:57:57 -07:00
|
|
|
var point := laser.get_collision_point()
|
|
|
|
var normal := laser.get_collision_normal()
|
2025-03-02 12:00:42 -07:00
|
|
|
|
|
|
|
# Always paint at least a dot, to cap the ends of the line
|
|
|
|
target.paint_dot(point, normal, spray_scale)
|
|
|
|
if target == prev_target:
|
|
|
|
# Continue the multiline if possible
|
|
|
|
target.add_to_multiline(prev_point, prev_normal, point, normal, spray_scale * 2)
|
|
|
|
prev_point = point
|
|
|
|
prev_normal = normal
|
|
|
|
prev_target = target
|
|
|
|
prev_point = point
|
|
|
|
prev_normal = normal
|
2025-03-12 00:18:27 -06:00
|
|
|
elif collider is GunkNode:
|
2025-03-13 11:25:11 -06:00
|
|
|
(collider as GunkNode).hit(damage)
|
2025-03-12 11:23:21 -06:00
|
|
|
|
|
|
|
|
|
|
|
func _on_animation_finished(anim_name: StringName) -> void:
|
|
|
|
if anim_name == "rotate":
|
|
|
|
_busy = false
|