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()