83 lines
4.3 KiB
GDScript
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()
|