# 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 . ## 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