2026-07-21 00:27:17 +07:00
extends Node
class_name HealthComponent
@export var max_health : float = 100.0
var current_health : float = 0.0
2026-08-02 17:30:18 +07:00
# Лимит высоты падения (если игрок падает ниже -20 метров по оси Y, он мгновенно погибает)
@export var fall_death_y_limit : float = - 20.0
2026-07-21 00:27:17 +07:00
# Сигналы, чтобы другие скрипты знали, когда объект ранен или умер
signal health_changed ( new_health : float )
signal died
func _ready () -> void :
2026-08-02 17:30:18 +07:00
# Инициализируем ХП. Если это игрок и у нас есть GameTransfer, берем ХП оттуда
2026-07-21 00:27:17 +07:00
current_health = max_health
2026-08-02 17:30:18 +07:00
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 ) # Наносим огромный урон, чтобы мгновенно вызвать смерть
2026-07-21 00:27:17 +07:00
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 , " погиб!" )
2026-08-02 17:30:18 +07:00
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 ()