class_name ShakePivot
extends Node2D
## Shakes on command. Use this node as the parent of a sprite or a camera to make it shake!
## Adapted from https://shaggydev.com/2022/02/23/screen-shake-godot/.

## How quickly to move through the noise.
@export var NOISE_SHAKE_SPEED: float = 20.0
## How much to multiply the noise values (which are in the range (-1, 1)) by.
@export var NOISE_SHAKE_STRENGTH: float = 15.0
## Multiplier for lerping the shake strength to zero.
@export var SHAKE_DECAY_RATE: float = 10.0

## Object that creates random noise to make for a nice shaking motion.
@onready var _noise := FastNoiseLite.new()

## Used to keep track of where we are in the noise so we can smoothly move through it.
var noise_i: float = 0.0
## Value taken from the noise to calculate the shaking node's position.
var shake_strength: float = 0.0


# Called when the node enters the scene tree for the first time.
func _ready() -> void:
	# Set noise type to simplex, since the tutorial I'm copying (uh I mean taking inspiration from)
	# is for an older version of Godot that had a dedicated simplex noise class
	_noise.noise_type = FastNoiseLite.TYPE_SIMPLEX
	# Randomize the generated noise
	_noise.seed = randi()
	# Period affects how quickly the noise changes values
	_noise.frequency = 0.5


# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
	# Fade out the intensity over time
	shake_strength = lerp(shake_strength, 0.0, SHAKE_DECAY_RATE * delta)
	
	# Shake by adjusting position so we can move the object around
	position = get_noise_offset(delta)


## Uses noise to generate a random 2D vector
func get_noise_offset(delta: float) -> Vector2:
	noise_i += delta * NOISE_SHAKE_SPEED
	# Set the x values of each call to 'get_noise_2d' to a different value so that our x and y 
	# vectors will read from unrelated areas of noise
	return Vector2(
		_noise.get_noise_2d(1, noise_i) * shake_strength,
		_noise.get_noise_2d(100, noise_i) * shake_strength
	)


## Sets the strength to its initial value.
func shake() -> void:
	shake_strength = NOISE_SHAKE_STRENGTH
