2025-03-12 00:18:27 -06:00
|
|
|
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
|
|
|
|
|
2025-03-13 11:25:11 -06:00
|
|
|
const JITTER_FADE_RATE := 0.8
|
2025-03-12 00:18:27 -06:00
|
|
|
|
|
|
|
## 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.
|
2025-03-13 11:25:11 -06:00
|
|
|
func hit(damage: float = 0.05) -> void:
|
|
|
|
_sustained_damage += damage
|
2025-03-12 00:18:27 -06:00
|
|
|
_hit_this_frame = true
|
|
|
|
_hit()
|
|
|
|
|
|
|
|
|
2025-03-14 15:27:55 -06:00
|
|
|
## Return this node's current damage as a proportion of it's total durability.
|
|
|
|
func pct_damage() -> float:
|
|
|
|
return _sustained_damage / durability
|
|
|
|
|
|
|
|
|
2025-03-12 00:18:27 -06:00
|
|
|
func _hit() -> void:
|
|
|
|
pass # Implemented in derived type
|
|
|
|
|
|
|
|
|
2025-03-13 11:25:11 -06:00
|
|
|
func _process(_delta: float) -> void:
|
|
|
|
if not _hit_this_frame:
|
2025-03-12 00:18:27 -06:00
|
|
|
_sustained_damage *= JITTER_FADE_RATE
|
|
|
|
_hit_this_frame = false
|
|
|
|
|
|
|
|
if _sustained_damage >= durability:
|
2025-04-06 21:05:39 -06:00
|
|
|
collect()
|
|
|
|
|
|
|
|
|
|
|
|
## Destroy this node, with the player collecting the grunk value.
|
|
|
|
func collect() -> void:
|
|
|
|
Game.manager.collect_grunk(value)
|
|
|
|
destroy()
|
2025-03-12 00:18:27 -06:00
|
|
|
|
|
|
|
|
|
|
|
## 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
|