grunk/src/world/gunk_node/gunk_node.gd

71 lines
1.8 KiB
GDScript

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
## Scale factor applied to the size and volume of the splatter effect on destruction.
@export var splatter_scale := 1.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:
collect()
## Destroy this node, with the player collecting the grunk value.
func collect() -> void:
Game.manager.collect_grunk(value)
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)
var splatter := GrunkSplatter.build(splatter_scale * scale.x)
add_sibling(splatter)
splatter.global_position = global_position
_destroy()
destroyed.emit()
queue_free()
func _destroy() -> void:
pass # Implemented in derived type