mirror of
https://codeberg.org/sunder/sunder.git
synced 2026-07-13 13:04:34 +00:00
78 lines
2.5 KiB
GDScript
78 lines
2.5 KiB
GDScript
# This file is part of sunder.
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU Affero General Public License as
|
|
# published by the Free Software Foundation, either version 3 of the
|
|
# License, or (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU Affero General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Affero General Public License
|
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
## This class defines a Health component for entities.
|
|
class_name Health extends Area3D
|
|
|
|
## An entity with this component can be either dead or alive.
|
|
enum HealthState {
|
|
## The entity is dead
|
|
DEAD,
|
|
## The entity is alive ([member value] > 0)
|
|
ALIVE,
|
|
## The entity is wounded ([member value] < 128)
|
|
DEGRADED,
|
|
## Stop it, get help ([member value] < 32)
|
|
CRITICAL
|
|
}
|
|
|
|
@export var state : HealthState = HealthState.ALIVE
|
|
@export var max_value:int = 255
|
|
@export var value:int = 255:
|
|
set(new_value):
|
|
value = clampi(new_value, 0, max_value)
|
|
changed.emit(value)
|
|
|
|
@export var shape:Shape3D:
|
|
set(new_shape):
|
|
shape = new_shape
|
|
if is_node_ready():
|
|
collider.shape = new_shape
|
|
|
|
@onready var collider: CollisionShape3D = $CollisionShape3D
|
|
|
|
## Emitted when a peer damaged this component too much.
|
|
signal killed(by_peer_id:int)
|
|
## Emitted when value is exhausted.
|
|
signal exhausted()
|
|
## Emitted when the value is changed.
|
|
signal changed(new_value:int)
|
|
|
|
## Emitted when the health component is damaged.
|
|
signal damaged(source: Node, target: Node, amount: int)
|
|
|
|
func _ready() -> void:
|
|
# only collide with the layer 3 named "Damage", disable monitoring completely
|
|
collision_layer = 0b00000000_00000000_00000000_00000100
|
|
collision_mask = 0
|
|
monitoring = false
|
|
|
|
func _get_configuration_warnings() -> PackedStringArray:
|
|
if not collider.shape:
|
|
return ["A shape must be provided for Health to be damaged. Please create or load a shape resource."]
|
|
return []
|
|
|
|
@rpc("authority", "call_local", "reliable")
|
|
func damage(amount:int, by_peer_id:int) -> void:
|
|
value -= amount
|
|
if value == 0 and state != HealthState.DEAD:
|
|
state = HealthState.DEAD
|
|
killed.emit(by_peer_id)
|
|
exhausted.emit(owner)
|
|
|
|
@rpc("authority", "call_local", "reliable")
|
|
func heal(amount:int = max_value) -> void:
|
|
# add strictly positive amount to value
|
|
value += clampi(amount, 1, max_value)
|
|
state = HealthState.ALIVE
|