using UnityEngine;
using BaseGames.Core;
using BaseGames.Dialogue;
using BaseGames.Player;
using QuestStateEnum = BaseGames.Core.Events.QuestState;
using SL = BaseGames.Core.ServiceLocator;
namespace BaseGames.Quest
{
///
/// 可发布/完成任务的 NPC(架构 22_QuestChallengeModule §6)。
/// 继承 InteractableNPC,根据任务状态切换对话版本,在交互时处理任务接收/完成。
///
public class QuestGiver : InteractableNPC
{
[Header("任务")]
[Tooltip("该 NPC 可提供的所有任务,按优先级从高到低排列。\n" +
"交互时从列表头部找到第一个 Available 或 Active 状态的任务作为当前任务;\n" +
"若全部已完成,显示最后一个已完成任务的 completedDialogue。")]
[SerializeField] private QuestSO[] _offeredQuests;
[Header("对话版本(根据任务状态切换)")]
[Tooltip("任务尚未接取(QuestState.Available)时播放。通常是 NPC 发布任务、介绍背景的对话。")]
[SerializeField] private DialogueSequenceSO _availableDialogue;
[Tooltip("任务已接取、目标尚未全部完成(QuestState.Active)时播放。通常是 NPC 催促或加油打气的对话。")]
[SerializeField] private DialogueSequenceSO _activeDialogue;
[Tooltip("全部非可选目标已达成、任务可以交付时播放(IsReadyToComplete = true)。\n" +
"通常是 NPC 感谢、确认收取物品的对话,播放后执行 CompleteQuest 逻辑。")]
[SerializeField] private DialogueSequenceSO _readyDialogue;
[Tooltip("任务已完成(QuestState.Completed)后再次交互时播放。通常是 NPC 闲聊或后续剧情的对话。")]
[SerializeField] private DialogueSequenceSO _completedDialogue;
// ── InteractableNPC 覆盖 ──────────────────────────────────────────────
public override string InteractPrompt
{
get
{
var qm = SL.GetOrDefault();
var quest = GetCurrentOrCompletedQuest(qm);
if (quest == null || qm == null) return base.InteractPrompt;
return qm.GetState(quest.questId) switch
{
QuestStateEnum.Available => "接受任务",
QuestStateEnum.Active => qm.IsReadyToComplete(quest.questId) ? "提交任务" : "进行中…",
QuestStateEnum.Paused => "暂停中…",
QuestStateEnum.Completed => "对话",
_ => base.InteractPrompt,
};
}
}
protected override void Interact_Internal(Transform player)
{
var qm = SL.GetOrDefault();
var quest = GetCurrentOrCompletedQuest(qm);
if (quest == null || qm == null) return;
var state = qm.GetState(quest.questId);
if (state == QuestStateEnum.Available)
{
qm.AcceptQuest(quest.questId);
}
else if (state == QuestStateEnum.Active && qm.IsReadyToComplete(quest.questId))
{
// 直接从 player 获取 PlayerStats,避免对 PlayerController 的程序集依赖
var stats = player.GetComponentInParent();
qm.CompleteQuest(quest.questId, stats);
}
}
protected override DialogueSequenceSO GetCurrentDialogue()
{
var qm = SL.GetOrDefault();
var quest = GetCurrentOrCompletedQuest(qm);
if (quest == null || qm == null) return base.GetCurrentDialogue();
var state = qm.GetState(quest.questId);
return state switch
{
QuestStateEnum.Available => _availableDialogue,
QuestStateEnum.Active => qm.IsReadyToComplete(quest.questId)
? _readyDialogue : _activeDialogue,
QuestStateEnum.Paused => _activeDialogue, // 暂停中显示"催促"对话,不触发任何状态推进
QuestStateEnum.Completed => _completedDialogue,
_ => base.GetCurrentDialogue(),
};
}
// ── 私有辅助 ─────────────────────────────────────────────────────────
///
/// 返回当前处于 Available 或 Active 状态的第一个任务;
/// 若全部已完成,返回最后一个已完成任务(用于显示 completedDialogue)。
///
private QuestSO GetCurrentOrCompletedQuest(IQuestManager qm = null)
{
if (_offeredQuests == null) return null;
qm ??= SL.GetOrDefault();
if (qm == null) return null;
QuestSO lastCompleted = null;
foreach (var q in _offeredQuests)
{
if (q == null) continue;
var s = qm.GetState(q.questId);
if (s == QuestStateEnum.Available || s == QuestStateEnum.Active || s == QuestStateEnum.Paused) return q;
if (s == QuestStateEnum.Completed) lastCompleted = q;
}
return lastCompleted;
}
}
}