Files
CybelovZOVod/addons/hp/health_component.gd

83 lines
4.3 KiB
GDScript

extends Node
class_name HealthComponent
@export var max_health: float = 100.0
var current_health: float = 0.0
# Лимит высоты падения (если игрок падает ниже -20 метров по оси Y, он мгновенно погибает)
@export var fall_death_y_limit: float = -20.0
# Сигналы, чтобы другие скрипты знали, когда объект ранен или умер
signal health_changed(new_health: float)
signal died
func _ready() -> void:
# Инициализируем ХП. Если это игрок и у нас есть GameTransfer, берем ХП оттуда
current_health = max_health
var parent_name = get_parent().name if get_parent() else ""
if "Player" in parent_name or "Character" in parent_name:
var gt = get_node_or_null("/root/GameTransfer")
if gt and "saved_health" in gt and gt.saved_health > 0:
current_health = gt.saved_health
func _physics_process(_delta: float) -> void:
# --- ПРОВЕРКА ПАДЕНИЯ В БЕЗДНУ (ОТРИЦАТЕЛЬНАЯ ВЫСОТА) ---
if current_health > 0 and get_parent() is Node3D:
# Проверяем координату Y родителя (высоту в 3D мире)
if get_parent().global_position.y < fall_death_y_limit:
print("[БЕЗДНА] ", get_parent().name, " упал под карту! Наношу смертельный урон.")
take_damage(9999.0) # Наносим огромный урон, чтобы мгновенно вызвать смерть
func take_damage(amount: float) -> void:
if current_health <= 0:
return
current_health -= amount
health_changed.emit(current_health)
print("[Здоровье] ", get_parent().name, " получил урон: ", amount, ". Осталось: ", current_health)
if current_health <= 0:
current_health = 0
die()
func die() -> void:
died.emit()
print("[Здоровье] ", get_parent().name, " погиб!")
var parent_node = get_parent()
if parent_node:
# Проверяем, кто погиб: Игрок или Моб
var is_player = "Player" in parent_node.name or "Character" in parent_node.name
if is_player:
print("[Здоровье] Игрок уничтожен. Аппаратно загружаю и спавню твою сцену DeathScreen...")
# 1. ЗАГРУЖАЕМ И СПАВНИМ ТВОЙ ГОТОВЫЙ ФАЙЛ СМЕРТИ ИЗ ПАПКИ ПРОЕКТА
# Код берет файл DeathScreen.tscn и материализует его прямо в корень игры поверх всех карт!
var death_scene_file = load("res://addons/PlayerCharacter/death_screen.tscn.tscn") # Проверь имя файла, если оно лежит в папке (например res://scenes/DeathScreen.tscn)
if death_scene_file:
var death_instance = death_scene_file.instantiate()
get_tree().get_root().add_child(death_instance)
print("[Здоровье] Твоя сцена DeathScreen успешно заспавнена в корень игры!")
else:
print("[Здоровье] ОШИБКА: Файл 'res://DeathScreen.tscn' не найден в папке проекта! Проверь его точный путь.")
# 2. ОСВОБОЖДАЕМ КУРСОР МЫШКИ ДЛЯ КЛИКА ПО ТВОЕЙ КНОПКЕ RESTARTBUTTON
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
# 3. БЛОКИРУЕМ СТРЕЛЬБУ В МЕНЕДЖЕРЕ ОРУЖИЯ ШУТЕРА
var wm = parent_node.find_child("WeaponManager", true, false)
if wm and "canUseWeapon" in wm:
wm.canUseWeapon = false
print("[WeaponManager] Стрельба и перезарядка намертво заблокированы для трупа.")
# 4. ЗАМОРАЖИВАЕМ ДВИЖЕНИЕ ПЛЕЕРА ТАК, ЧТОБЫ НЕ УСЫПЛЯТЬ UI КНОПКИ
if "moveSpeed" in parent_node: parent_node.moveSpeed = 0.0
parent_node.velocity = Vector3.ZERO
if "can_move" in parent_node: parent_node.can_move = false
print("[Здоровье] Физика игрока остановлена. Экран смерти выведен, ждем клика по кнопке.")
else:
# Если это обычный бегающий МОБ — просто удаляем его со сцены, как и раньше
parent_node.queue_free()