Files

132 lines
5.6 KiB
GDScript
Raw Permalink Normal View History

2026-07-21 00:27:17 +07:00
extends CanvasLayer
@onready var dialogue_box = $DialogueBox
@onready var name_label = $DialogueBox/NameLabel
@onready var text_label = $DialogueBox/TextLabel
@onready var press_e_label = $PressE
var current_dialogue_lines: Array = []
var current_line_index: int = 0
var player_ref: Node3D = null
var is_active: bool = false
# --- НАШИ НОВЫЕ ПЕРЕМЕННЫЕ ДЛЯ ЗАМОРОЗКИ ВЗГЛЯДА ---
var camera_node: Camera3D = null
var saved_camera_rotation: Vector3 = Vector3.ZERO
var is_camera_locked: bool = false
2026-07-21 00:27:17 +07:00
func _ready():
if dialogue_box: dialogue_box.visible = false
if press_e_label: press_e_label.visible = false
2026-07-21 00:27:17 +07:00
func start_dialogue(lines: Array):
hide_prompt()
current_dialogue_lines = lines
current_line_index = 0
if dialogue_box: dialogue_box.visible = true
is_active = true
2026-07-21 00:27:17 +07:00
player_ref = get_tree().current_scene.find_child("PlayerCharacter", true, false)
if player_ref:
# Блокируем стрельбу
var wm = player_ref.find_child("WeaponManager", true, false)
if wm:
if "canUseWeapon" in wm: wm.canUseWeapon = false
if wm.has_method("disable_weapons_for_dialogue"): wm.disable_weapons_for_dialogue()
# --- ЖЕСТКАЯ ФИКСАЦИЯ УГЛА КАМЕРЫ ---
# Находим 3D-камеру внутри игрока
camera_node = player_ref.find_child("Camera3D", true, false)
if camera_node == null:
camera_node = player_ref.find_child("PlayerCamera", true, false)
if camera_node:
# Запоминаем точный угол, куда смотрел игрок в момент нажатия Е
saved_camera_rotation = camera_node.rotation
is_camera_locked = true
print("[UI] Угол камеры успешно сохранен: ", saved_camera_rotation)
2026-07-21 00:27:17 +07:00
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
show_current_line()
# Физический цикл интерфейса, который работает пока открыто окно диалога
func _process(_delta: float) -> void:
# Пока диалог активен, мы КАЖДЫЙ КАДР принудительно возвращаем камере сохраненный угол,
# полностью перебивая любые попытки ассета уронить взгляд в пол!
if is_camera_locked and camera_node != null and is_instance_valid(camera_node):
camera_node.rotation = saved_camera_rotation
2026-07-21 00:27:17 +07:00
func show_current_line():
if current_line_index < current_dialogue_lines.size():
var line_data = current_dialogue_lines[current_line_index]
if name_label: name_label.text = line_data.get("name", "NPC")
if text_label: text_label.text = line_data.get("text", "")
2026-07-21 00:27:17 +07:00
else:
# Перед закрытием просим Сталкера обнулить статус активности
var current_scene = get_tree().current_scene
if current_scene:
var npc = current_scene.find_child("StaticBody3D", true, false)
if npc == null: npc = current_scene.find_child("bot", true, false)
if npc and "_restore_player_control" in npc:
npc._restore_player_control()
if "is_dialogue_active" in npc: npc.is_dialogue_active = false
2026-07-21 00:27:17 +07:00
end_dialogue()
func _unhandled_input(event: InputEvent) -> void:
if is_active and dialogue_box and dialogue_box.visible:
var is_click = event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_LEFT
var is_space = event is InputEventKey and event.pressed and event.keycode == KEY_SPACE
2026-07-21 00:27:17 +07:00
if is_click or is_space:
2026-07-21 00:27:17 +07:00
current_line_index += 1
show_current_line()
get_viewport().set_input_as_handled()
func end_dialogue():
is_active = false
if dialogue_box:
dialogue_box.visible = false
if press_e_label:
2026-07-21 00:27:17 +07:00
press_e_label.visible = false
is_camera_locked = false
# Даем игре фору в два физических кадра, чтобы финальный клик мышки полностью угас
await get_tree().process_frame
await get_tree().process_frame
# --- БРОНЕБОЙНЫЙ РАЗБЛОК СТРЕЛЬБЫ, ПЕРЕЗАРЯДКИ И КОЛЕСИКА ОРУЖИЯ ---
if player_ref:
var wm = player_ref.find_child("WeaponManager", true, false)
if wm:
# 1. Возвращаем базовые флаги использования и смены пушек
if "canUseWeapon" in wm: wm.canUseWeapon = true
if "canChangeWeapons" in wm: wm.canChangeWeapons = true
if "canReload" in wm: wm.canReload = true
# 2. Вызываем ВСЕ возможные методы включения оружия, какие заложил автор ассета:
if wm.has_method("enable_weapons_after_dialogue"):
wm.enable_weapons_after_dialogue()
elif wm.has_method("enable_weapons"):
wm.enable_weapons()
elif wm.has_method("activate_weapons"):
wm.activate_weapons()
# 3. Принудительно заставляем HUD и пушку обновиться, чтобы вернуть её в руки
if wm.has_method("displayStats"):
wm.displayStats()
if "cW" in wm and wm.cW != null and wm.has_method("changeWeapon"):
# Насильно заставляем персонажа достать текущее оружие обратно
wm.changeWeapon(wm.weaponStack[wm.weaponIndex])
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
print("[UI] Диалог чисто закрыт. Оружие, перезарядка и колесико принудительно возвращены в строй!")
func show_prompt() -> void:
if press_e_label and (dialogue_box == null or not dialogue_box.visible):
press_e_label.visible = true
func hide_prompt() -> void:
if press_e_label: press_e_label.visible = false