113 lines
2.5 KiB
GDScript
113 lines
2.5 KiB
GDScript
class_name Item
|
|
extends Node3D
|
|
|
|
const DEFAULT_MAX_HEALTH: int = 10
|
|
const MIN_MAX_HEALTH: int = 1
|
|
signal name_changed(item_name: String)
|
|
signal health_changed(current_health: int, maximum_health: int)
|
|
signal state_changed(new_state: States)
|
|
signal recalculate_navigation_map(requester: Node3D)
|
|
enum States {
|
|
hidden,
|
|
idle,
|
|
closed,
|
|
opened,
|
|
looted,
|
|
destroyed
|
|
}
|
|
|
|
@export var item_name: String:
|
|
get:
|
|
return _item_name
|
|
set(value):
|
|
if _item_name == value:
|
|
return
|
|
_item_name = value
|
|
if _initialized:
|
|
name_changed.emit(value)
|
|
|
|
@export var maximum_health: int = DEFAULT_MAX_HEALTH:
|
|
get:
|
|
return _maximum_health
|
|
set(value):
|
|
var new_max: int = max(MIN_MAX_HEALTH, value)
|
|
var max_changed: bool = (_maximum_health != new_max)
|
|
if max_changed:
|
|
_maximum_health = new_max
|
|
# Gesundheitswert bei Bedarf anpassen
|
|
var clamped_health: int = clamp(_health, 0, _maximum_health)
|
|
var health_changed_local: bool = (clamped_health != _health)
|
|
if health_changed_local:
|
|
_health = clamped_health
|
|
if _initialized and (max_changed or health_changed_local):
|
|
_emit_health_signal()
|
|
|
|
|
|
@export var health: int = DEFAULT_MAX_HEALTH:
|
|
get:
|
|
return _health
|
|
set(value):
|
|
var clamped := clampi(value, 0, maximum_health)
|
|
if _health == clamped:
|
|
return
|
|
_health = clamped
|
|
if _initialized:
|
|
_emit_health_signal()
|
|
_handle_death_if_needed()
|
|
|
|
@export var state: States = States.idle:
|
|
get:
|
|
return _state
|
|
set(value):
|
|
if _state == value:
|
|
return
|
|
_state = value
|
|
if _initialized:
|
|
state_changed.emit(value)
|
|
|
|
var _initialized: bool = false
|
|
var _item_name: String = ""
|
|
var _maximum_health: int = DEFAULT_MAX_HEALTH
|
|
var _health: int = DEFAULT_MAX_HEALTH
|
|
var _state: States = States.idle
|
|
|
|
|
|
func _ready() -> void:
|
|
_initialized = true
|
|
_emit_initial_signals()
|
|
|
|
|
|
# Öffentliche API
|
|
|
|
func take_damage(amount: int) -> void:
|
|
# Primäre API (kompatibel zu HurtBox)
|
|
if amount <= 0:
|
|
return
|
|
health = health - amount
|
|
|
|
|
|
func apply_damage(damage_amount: int) -> void:
|
|
# Veraltet: bitte take_damage verwenden (Alias zur Rückwärtskompatibilität)
|
|
take_damage(damage_amount)
|
|
|
|
|
|
func destroy_item() -> void:
|
|
recalculate_navigation_map.emit(self)
|
|
queue_free()
|
|
|
|
|
|
# Private Helfer
|
|
|
|
func _emit_initial_signals() -> void:
|
|
# Bewahrt Startverhalten (Name + Health); State wird nicht zusätzlich emittiert
|
|
name_changed.emit(item_name)
|
|
_emit_health_signal()
|
|
|
|
|
|
func _emit_health_signal() -> void:
|
|
health_changed.emit(_health, _maximum_health)
|
|
|
|
|
|
func _handle_death_if_needed() -> void:
|
|
if _health <= 0:
|
|
state = States.destroyed |