class_name GunkNode extends StaticBody3D
## A static body which can be destroyed and collected by the player.

## Emitted immediately after this node has been destroyed by the player,
## but before it's removed from the scene tree
signal destroyed

const JITTER_FADE_RATE := 0.8

## Time in seconds the player must hit this node with a sustained beam before it's destroyed.
@export var durability := 1.0

## Value added to the player's grunk total on destruction.
@export var value := 1000.0

var _sustained_damage := 0.0
var _hit_this_frame := false


## Called each frame this node takes a hit.
##
## Derived types should override `_hit()` as a lifecycle method.
func hit(damage: float = 0.05) -> void:
	_sustained_damage += damage
	_hit_this_frame = true
	_hit()


## Return this node's current damage as a proportion of it's total durability.
func pct_damage() -> float:
	return _sustained_damage / durability


func _hit() -> void:
	pass  # Implemented in derived type


func _process(_delta: float) -> void:
	if not _hit_this_frame:
		_sustained_damage *= JITTER_FADE_RATE
	_hit_this_frame = false

	if _sustained_damage >= durability:
		destroy()


## Destroy this node. Called automatically when this node sustains damage beyond its durability.
##
## Derived types should override `_destroy` as a lifecycle method.
func destroy() -> void:
	Game.manager.collect_grunk(value)
	_destroy()
	destroyed.emit()
	queue_free()


func _destroy() -> void:
	pass  # Implemented in derived type
