Files
PIM_Laba4/Assets/Scripts/NPC.cs
T
2026-05-25 23:53:50 +03:00

163 lines
4.4 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
public class NPC : MonoBehaviour
{
[Serializable]
public class DialogueOption
{
public string playerReply;
public string npcReply;
public bool closeAfterSelection;
public bool requiresAllNotes;
public string unavailableReply;
}
[SerializeField] private string npcName = "Смотритель";
[SerializeField] private string openingLine = "Вы нашли что-нибудь интересное?";
[SerializeField] private List<DialogueOption> dialogueOptions = new List<DialogueOption>();
[SerializeField] private Renderer npcRenderer;
[SerializeField] private Material defaultMaterial;
[SerializeField] private Material highlightMaterial;
private bool playerInRange;
private bool hasRegisteredConversation;
public string NPCName => npcName;
public string OpeningLine => openingLine;
public IReadOnlyList<DialogueOption> DialogueOptions => dialogueOptions;
public void Configure(
string characterName,
string introLine,
Renderer targetRenderer,
Material baseMaterial,
Material selectedMaterial,
List<DialogueOption> options)
{
npcName = characterName;
openingLine = introLine;
npcRenderer = targetRenderer;
defaultMaterial = baseMaterial;
highlightMaterial = selectedMaterial;
dialogueOptions = options ?? new List<DialogueOption>();
}
private void Awake()
{
if (npcRenderer == null)
{
npcRenderer = GetComponentInChildren<Renderer>();
}
if (defaultMaterial == null && npcRenderer != null)
{
defaultMaterial = npcRenderer.sharedMaterial;
}
SetHighlighted(false);
}
private void Update()
{
if (playerInRange && !GameUIState.IsAnyBlockingUIOpen && Input.GetKeyDown(KeyCode.E))
{
Interact();
}
}
public void SetPlayerInRange(bool isInRange)
{
playerInRange = isInRange;
SetHighlighted(isInRange);
if (isInRange)
{
InteractionPromptUI.Instance?.ShowPrompt(this, "Нажмите E");
}
else
{
InteractionPromptUI.Instance?.HidePrompt(this);
}
}
public void Interact()
{
DialogueUI.Instance?.ShowDialogue(this);
}
public bool IsOptionAvailable(DialogueOption option)
{
if (option == null)
{
return false;
}
return !option.requiresAllNotes || (QuestManager.Instance != null && QuestManager.Instance.HasCollectedAllNotes);
}
public string GetOptionLabel(DialogueOption option)
{
if (option == null)
{
return string.Empty;
}
if (IsOptionAvailable(option))
{
return option.playerReply;
}
var requiredNotes = QuestManager.Instance != null ? QuestManager.Instance.TotalNotes : 3;
return $"{option.playerReply} (нужно {requiredNotes} записки)";
}
public void SelectOption(DialogueOption option)
{
if (option == null)
{
return;
}
if (!IsOptionAvailable(option))
{
var fallbackReply = string.IsNullOrWhiteSpace(option.unavailableReply)
? "Сначала найди все записки, потом мы продолжим этот разговор."
: option.unavailableReply;
DialogueUI.Instance?.ShowFollowUp(npcName, fallbackReply);
return;
}
if (!hasRegisteredConversation)
{
hasRegisteredConversation = true;
QuestManager.Instance?.NPCTalked();
}
if (option.closeAfterSelection || string.IsNullOrWhiteSpace(option.npcReply))
{
DialogueUI.Instance?.CloseDialogue();
return;
}
DialogueUI.Instance?.ShowFollowUp(npcName, option.npcReply);
}
private void SetHighlighted(bool highlighted)
{
if (npcRenderer == null)
{
return;
}
var targetMaterial = highlighted && highlightMaterial != null ? highlightMaterial : defaultMaterial;
if (targetMaterial != null)
{
npcRenderer.material = targetMaterial;
}
}
}