2026-07-21 00:27:17 +07:00
|
|
|
extends StaticBody3D
|
|
|
|
|
|
2026-07-30 01:02:19 +07:00
|
|
|
# --- ОПЦИЯ 1: БЫСТРЫЙ ДИАЛОГ НАПРЯМУЮ В ИНСПЕКТОРЕ NPC ---
|
2026-07-21 00:27:17 +07:00
|
|
|
@export var dialogue_data: Array[Dictionary] = [
|
2026-07-30 01:02:19 +07:00
|
|
|
{"name": "Сталкер", "text": "Привет! Наконец-то ты подошел."}
|
2026-07-21 00:27:17 +07:00
|
|
|
]
|
|
|
|
|
|
2026-07-30 01:02:19 +07:00
|
|
|
# --- ОПЦИЯ 2: ВНЕШНИЙ ФАЙЛ ДЛЯ БОЛЬШИХ ДIАЛОГОВ ---
|
|
|
|
|
# Сюда можно будет перетащить файл .json из папки проекта!
|
|
|
|
|
@export var dialogue_file: JSON
|
|
|
|
|
|
2026-07-25 23:26:07 +07:00
|
|
|
const DIALOGUE_UI_FILE = preload("res://addons/dialoge/dialogue_ui.tscn")
|
|
|
|
|
|
2026-07-21 00:27:17 +07:00
|
|
|
var is_player_inside: bool = false
|
2026-07-25 23:26:07 +07:00
|
|
|
var is_dialogue_active: bool = false
|
|
|
|
|
var ui_instance: Node = null
|
2026-07-21 00:27:17 +07:00
|
|
|
var detect_area: Area3D = null
|
|
|
|
|
|
2026-07-30 01:02:19 +07:00
|
|
|
# Финальный массив фраз, который мы передадим в UI на основе проверки
|
|
|
|
|
var final_dialogue_lines: Array = []
|
|
|
|
|
|
2026-07-21 00:27:17 +07:00
|
|
|
func _ready() -> void:
|
2026-07-25 23:26:07 +07:00
|
|
|
detect_area = get_node_or_null("DetectArea")
|
|
|
|
|
if detect_area == null:
|
|
|
|
|
detect_area = find_child("DetectArea", true, false)
|
2026-07-30 01:02:19 +07:00
|
|
|
if detect_area:
|
|
|
|
|
print("[NPC] Зона DetectArea найдена. Универсальный скрипт запущен.")
|
2026-07-25 23:26:07 +07:00
|
|
|
|
2026-07-30 01:02:19 +07:00
|
|
|
# Готовим текст перед стартом
|
|
|
|
|
_prepare_dialogue_data()
|
|
|
|
|
|
2026-07-25 23:26:07 +07:00
|
|
|
if ui_instance == null:
|
|
|
|
|
ui_instance = DIALOGUE_UI_FILE.instantiate()
|
|
|
|
|
get_tree().get_root().add_child.call_deferred(ui_instance)
|
|
|
|
|
if "layer" in ui_instance: ui_instance.layer = 135
|
2026-07-21 00:27:17 +07:00
|
|
|
|
2026-07-30 01:02:19 +07:00
|
|
|
func _prepare_dialogue_data() -> void:
|
|
|
|
|
# Проверяем, закинул ли ты внешний JSON-файл в инспектор этого конкретного NPC
|
|
|
|
|
if dialogue_file != null and dialogue_file.data is Array:
|
|
|
|
|
final_dialogue_lines = dialogue_file.data
|
|
|
|
|
print("[NPC] Успешно загружен диалог из внешнего JSON файла для: ", name)
|
|
|
|
|
else:
|
|
|
|
|
# Если файла нет, используем ручные строчки из инспектора
|
|
|
|
|
final_dialogue_lines = dialogue_data
|
|
|
|
|
print("[NPC] Использую ручной массив диалога из инспектора для: ", name)
|
|
|
|
|
|
2026-07-21 00:27:17 +07:00
|
|
|
func _process(_delta: float) -> void:
|
2026-07-25 23:26:07 +07:00
|
|
|
if detect_area == null: return
|
2026-07-21 00:27:17 +07:00
|
|
|
|
|
|
|
|
var overlapping_bodies = detect_area.get_overlapping_bodies()
|
|
|
|
|
var found_player_this_frame = false
|
|
|
|
|
|
|
|
|
|
for body in overlapping_bodies:
|
2026-07-25 23:26:07 +07:00
|
|
|
if "Player" in body.name or "Character" in body.name or body.find_child("WeaponManager", true, false) != null:
|
2026-07-21 00:27:17 +07:00
|
|
|
found_player_this_frame = true
|
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
if found_player_this_frame and not is_player_inside:
|
|
|
|
|
is_player_inside = true
|
2026-07-25 23:26:07 +07:00
|
|
|
if ui_instance and not is_dialogue_active:
|
|
|
|
|
if ui_instance.has_method("show_prompt"):
|
|
|
|
|
ui_instance.show_prompt()
|
2026-07-21 00:27:17 +07:00
|
|
|
|
|
|
|
|
elif not found_player_this_frame and is_player_inside:
|
|
|
|
|
is_player_inside = false
|
2026-07-25 23:26:07 +07:00
|
|
|
is_dialogue_active = false
|
|
|
|
|
if ui_instance:
|
|
|
|
|
if ui_instance.has_method("hide_prompt"): ui_instance.hide_prompt()
|
|
|
|
|
if ui_instance.has_method("end_dialogue"): ui_instance.end_dialogue()
|
2026-07-21 00:27:17 +07:00
|
|
|
|
2026-07-25 23:26:07 +07:00
|
|
|
if is_player_inside and not is_dialogue_active:
|
|
|
|
|
if Input.is_key_pressed(KEY_E) or Input.is_action_just_pressed("interact"):
|
|
|
|
|
is_dialogue_active = true
|
|
|
|
|
if ui_instance:
|
|
|
|
|
if ui_instance.has_method("hide_prompt"): ui_instance.hide_prompt()
|
|
|
|
|
if ui_instance.has_method("start_dialogue"):
|
2026-07-30 01:02:19 +07:00
|
|
|
# ПЕРЕДАЕМ НАШ СФОРМИРОВАННЫЙ ТЕКСТ
|
|
|
|
|
ui_instance.start_dialogue(final_dialogue_lines)
|