289 lines
9.0 KiB
C#
289 lines
9.0 KiB
C#
using UnityEngine;
|
|
using EasyTalk.Controller;
|
|
using EasyTalk.Nodes;
|
|
|
|
public enum NPCType
|
|
{
|
|
Villager,
|
|
Merchant,
|
|
Trainer,
|
|
Guard,
|
|
QuestGiver,
|
|
Other
|
|
}
|
|
|
|
public class NPC : Character
|
|
{
|
|
[Header("NPC Settings")]
|
|
public string npcName = "NPC";
|
|
public NPCType npcType = NPCType.Villager;
|
|
|
|
[Header("Debug")]
|
|
[SerializeField]
|
|
private bool enableDebugLogs = false;
|
|
|
|
[Header("Interaction Capabilities")]
|
|
public bool hasDialogue = true;
|
|
public bool isQuestGiver = false;
|
|
public bool isMerchant = false;
|
|
public bool isTrainer = false;
|
|
|
|
[Header("EasyTalk Integration")]
|
|
[Tooltip("The Dialogue asset for this NPC. Will be loaded into the central DialogueController.")]
|
|
public Dialogue dialogue;
|
|
[Tooltip("Optional: Entry point name for starting dialogue. Leave empty to use default entry point.")]
|
|
public string dialogueEntryPoint = "";
|
|
[Tooltip("Name of the GameObject with the central DialogueController. Leave empty to auto-find.")]
|
|
public string dialogueManagerName = "Manager";
|
|
|
|
// Cache the central DialogueController
|
|
private static DialogueController centralDialogueController;
|
|
|
|
[Header("Fallback Dialogue (if no EasyTalk)")]
|
|
[TextArea(3, 10)]
|
|
public string greetingText = "Hello, traveler!";
|
|
|
|
[Header("Quest")]
|
|
public string questId = ""; // ID of the quest this NPC offers
|
|
|
|
[Header("Merchant Settings")]
|
|
[Tooltip("Gold required to access merchant services")]
|
|
public int merchantGoldRequirement = 0;
|
|
|
|
[Header("Trainer Settings")]
|
|
[Tooltip("Skills this trainer can teach")]
|
|
public string[] trainableSkills;
|
|
public int trainingCost = 100;
|
|
|
|
/// <summary>
|
|
/// Called when player interacts with this NPC
|
|
/// </summary>
|
|
public virtual void OnInteract(GameObject player)
|
|
{
|
|
Log($"Interacting with {npcName} ({npcType})");
|
|
|
|
if (hasDialogue)
|
|
{
|
|
ShowDialogue();
|
|
}
|
|
|
|
if (isQuestGiver && !string.IsNullOrEmpty(questId))
|
|
{
|
|
//OfferQuest(player);
|
|
}
|
|
|
|
if (isMerchant)
|
|
{
|
|
OpenMerchantInterface(player);
|
|
}
|
|
|
|
if (isTrainer)
|
|
{
|
|
OpenTrainingInterface(player);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Display dialogue for this NPC using EasyTalk with centralized DialogueController
|
|
/// </summary>
|
|
protected virtual void ShowDialogue()
|
|
{
|
|
// Find the central DialogueController if not cached
|
|
if (centralDialogueController == null)
|
|
{
|
|
centralDialogueController = FindCentralDialogueController();
|
|
}
|
|
|
|
// Check if we have both a controller and dialogue asset
|
|
if (centralDialogueController != null && dialogue != null)
|
|
{
|
|
// Load this NPC's dialogue into the central controller
|
|
centralDialogueController.ChangeDialogue(dialogue);
|
|
|
|
// Play dialogue with optional entry point
|
|
if (!string.IsNullOrEmpty(dialogueEntryPoint))
|
|
{
|
|
centralDialogueController.PlayDialogue(dialogueEntryPoint);
|
|
Log($"{npcName}: Starting EasyTalk dialogue at entry point '{dialogueEntryPoint}'");
|
|
}
|
|
else
|
|
{
|
|
centralDialogueController.PlayDialogue();
|
|
Log($"{npcName}: Starting EasyTalk dialogue");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Fallback to simple greeting if no EasyTalk setup
|
|
if (centralDialogueController == null)
|
|
{
|
|
Debug.LogWarning($"No central DialogueController found. Make sure there's a DialogueController on a GameObject named '{dialogueManagerName}'.", gameObject);
|
|
}
|
|
if (dialogue == null)
|
|
{
|
|
Debug.LogWarning($"No Dialogue asset assigned to {npcName}. Assign a Dialogue asset in the inspector.", gameObject);
|
|
}
|
|
|
|
Log($"{npcName}: {greetingText}");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Finds the central DialogueController in the scene
|
|
/// </summary>
|
|
private DialogueController FindCentralDialogueController()
|
|
{
|
|
// First, try to find by the specified manager name
|
|
if (!string.IsNullOrEmpty(dialogueManagerName))
|
|
{
|
|
GameObject manager = GameObject.Find(dialogueManagerName);
|
|
if (manager != null)
|
|
{
|
|
DialogueController controller = manager.GetComponent<DialogueController>();
|
|
if (controller != null)
|
|
{
|
|
Log($"Found central DialogueController on '{dialogueManagerName}'");
|
|
return controller;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Fallback: search for any DialogueController in the scene
|
|
DialogueController foundController = FindAnyObjectByType<DialogueController>();
|
|
if (foundController != null)
|
|
{
|
|
Log($"Found DialogueController via FindAnyObjectByType on '{foundController.gameObject.name}'");
|
|
return foundController;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Offer quest to the player
|
|
/// </summary>
|
|
protected virtual void OfferQuest(GameObject player)
|
|
{
|
|
if (QuestManager.Instance == null)
|
|
{
|
|
Debug.LogWarning("QuestManager not found in scene. Cannot offer quest.", gameObject);
|
|
return;
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(questId))
|
|
{
|
|
Debug.LogWarning($"{npcName} has no questId assigned.", gameObject);
|
|
return;
|
|
}
|
|
|
|
// Check if player can accept this quest
|
|
if (QuestManager.Instance.CanAcceptQuest(questId))
|
|
{
|
|
// Start the quest
|
|
bool started = QuestManager.Instance.StartQuest(questId);
|
|
if (started)
|
|
{
|
|
Log($"{npcName} gave quest '{questId}' to player!");
|
|
}
|
|
}
|
|
else if (QuestManager.Instance.IsQuestActive(questId))
|
|
{
|
|
// Quest already active - check if it can be turned in
|
|
Quest activeQuest = QuestManager.Instance.GetActiveQuest(questId);
|
|
if (activeQuest != null && activeQuest.IsComplete())
|
|
{
|
|
Log($"{npcName}: You've completed the quest! Turn it in.");
|
|
// Player should use CompleteQuestWithNPC method or turn-in dialogue option
|
|
}
|
|
else
|
|
{
|
|
Log($"{npcName}: You already have this quest active.");
|
|
}
|
|
}
|
|
else if (QuestManager.Instance.IsQuestCompleted(questId))
|
|
{
|
|
Log($"{npcName}: You've already completed this quest.");
|
|
}
|
|
else
|
|
{
|
|
Log($"{npcName}: You don't meet the requirements for this quest yet.");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Complete a quest with this NPC (quest turn-in)
|
|
/// </summary>
|
|
public virtual bool CompleteQuestWithNPC(string questIdToComplete)
|
|
{
|
|
if (QuestManager.Instance == null)
|
|
{
|
|
Debug.LogWarning("QuestManager not found in scene.", gameObject);
|
|
return false;
|
|
}
|
|
|
|
Quest quest = QuestManager.Instance.GetActiveQuest(questIdToComplete);
|
|
if (quest != null && quest.IsComplete())
|
|
{
|
|
bool completed = QuestManager.Instance.CompleteQuest(questIdToComplete);
|
|
if (completed)
|
|
{
|
|
Log($"{npcName}: Quest complete! Here's your reward.");
|
|
return true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Log($"{npcName}: You haven't completed that quest yet.");
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Open merchant trading interface
|
|
/// </summary>
|
|
protected virtual void OpenMerchantInterface(GameObject player)
|
|
{
|
|
Debug.Log($"Opening merchant interface for {npcName}", gameObject);
|
|
// TODO: Implement merchant UI
|
|
}
|
|
|
|
/// <summary>
|
|
/// Open training interface for learning skills
|
|
/// </summary>
|
|
protected virtual void OpenTrainingInterface(GameObject player)
|
|
{
|
|
Debug.Log($"Opening training interface for {npcName}", gameObject);
|
|
// TODO: Implement training UI
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check if this NPC can perform a specific service
|
|
/// </summary>
|
|
public bool CanProvideService(NPCType serviceType)
|
|
{
|
|
return npcType == serviceType ||
|
|
(serviceType == NPCType.Merchant && isMerchant) ||
|
|
(serviceType == NPCType.Trainer && isTrainer) ||
|
|
(serviceType == NPCType.QuestGiver && isQuestGiver);
|
|
}
|
|
|
|
/// <summary>
|
|
/// NPCs don't die by default - override for hostile NPCs
|
|
/// </summary>
|
|
public override void Die()
|
|
{
|
|
Log($"{npcName} has been defeated!");
|
|
// NPCs might drop loot, give quest credit, etc.
|
|
base.Die();
|
|
}
|
|
|
|
private void Log(string message)
|
|
{
|
|
if (enableDebugLogs)
|
|
{
|
|
Debug.Log(message);
|
|
}
|
|
}
|
|
}
|