extends Camera3D
class_name CameraController
# Partly from https://shaggydev.com/2022/02/23/screen-shake-godot/ a bit adjusted

# How quickly to move through the noise
@export var NOISE_SHAKE_SPEED: float = 30.0
# Multiplier for lerping the shake strength to zero
var shake_decay_rate: float = 8.0

var noise: FastNoiseLite


# Used to keep track of where we are in the noise
# so that we can smoothly move through it
var noise_i: float = 0.0

var shake_strength: float = 0.0

func _ready() -> void:
	var rand: RandomNumberGenerator = RandomNumberGenerator.new()
	rand.randomize()
	noise = FastNoiseLite.new()
	noise.noise_type = FastNoiseLite.TYPE_SIMPLEX
	noise.seed = rand.randi()
	# Period affects how quickly the noise changes values
	noise.frequency = 2.0

func shake(strength, decay_rate) -> void:
	
	shake_strength = strength
	shake_decay_rate = decay_rate

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 cameras offset so we can move the camera around the level via it's position
	
	var noise_offset: Vector2 = _get_noise_offset(delta)
	self.h_offset = noise_offset.x
	self.v_offset = noise_offset.y

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 be reading from unrelated areas of noise
	if noise != null and is_instance_valid(noise):
		return Vector2(
			noise.get_noise_2d(1, noise_i) * shake_strength,
			noise.get_noise_2d(100, noise_i) * shake_strength
		)
	else:
		return Vector2.ZERO
