242 lines
9.4 KiB
C#
242 lines
9.4 KiB
C#
using UnityEngine;
|
|
using System.Collections.Generic;
|
|
using Sirenix.OdinInspector;
|
|
using PixelCrushers.DialogueSystem;
|
|
using PixelCrushers.QuestMachine; // Required
|
|
using Invector.vCharacterController.vActions;
|
|
using UnityEngine.Events;
|
|
|
|
namespace Beyond
|
|
{
|
|
[AddComponentMenu("Beyond/Quests/Generic Quest Trigger")]
|
|
[RequireComponent(typeof(bTriggerGenericAction))]
|
|
public class GenericQuestTrigger : MonoBehaviour
|
|
{
|
|
#region --- ODIN-POWERED INSPECTOR ---
|
|
|
|
[Title("Invector Trigger Link")]
|
|
[InfoBox("Links into bTriggerGenericAction to add quest/dialogue functionality.")]
|
|
[Required("A bTriggerGenericAction component is required.")]
|
|
[OnInspectorInit("FindTriggerReference")]
|
|
public bTriggerGenericAction invectorTrigger;
|
|
|
|
[Title("Quest and Dialogue Actions")]
|
|
[ListDrawerSettings(Expanded = true, DraggableItems = true, NumberOfItemsPerPage = 10)]
|
|
public List<TriggeredAction> actions = new List<TriggeredAction>();
|
|
|
|
#endregion
|
|
|
|
private GameObject _lastInteractor;
|
|
|
|
private void FindTriggerReference()
|
|
{
|
|
if (invectorTrigger == null) invectorTrigger = GetComponent<bTriggerGenericAction>();
|
|
}
|
|
|
|
#region --- CORE LOGIC ---
|
|
|
|
private void Start()
|
|
{
|
|
if (invectorTrigger == null)
|
|
{
|
|
this.enabled = false;
|
|
return;
|
|
}
|
|
|
|
// Subscribe to Invector Events
|
|
invectorTrigger.OnPressActionInput.AddListener(() => HandleEvent(TriggerEventType.OnPressActionInput, _lastInteractor));
|
|
invectorTrigger.OnStartAnimation.AddListener(() => HandleEvent(TriggerEventType.OnStartAnimation, _lastInteractor));
|
|
invectorTrigger.OnEndAnimation.AddListener(() => HandleEvent(TriggerEventType.OnEndAnimation, _lastInteractor));
|
|
|
|
invectorTrigger.OnPlayerEnter.AddListener(HandlePlayerEnter);
|
|
invectorTrigger.OnPlayerExit.AddListener(HandlePlayerExit);
|
|
invectorTrigger.OnValidate.AddListener((interactor) => HandleEvent(TriggerEventType.OnValidate, interactor));
|
|
invectorTrigger.OnInvalidate.AddListener((interactor) => HandleEvent(TriggerEventType.OnInvalidate, interactor));
|
|
|
|
if (DialogueManager.instance != null) DialogueManager.instance.conversationEnded += OnConversationEnded;
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
if (DialogueManager.instance != null) DialogueManager.instance.conversationEnded -= OnConversationEnded;
|
|
|
|
if (invectorTrigger != null)
|
|
{
|
|
invectorTrigger.OnPressActionInput.RemoveAllListeners();
|
|
invectorTrigger.OnStartAnimation.RemoveAllListeners();
|
|
invectorTrigger.OnEndAnimation.RemoveAllListeners();
|
|
invectorTrigger.OnPlayerEnter.RemoveListener(HandlePlayerEnter);
|
|
invectorTrigger.OnPlayerExit.RemoveListener(HandlePlayerExit);
|
|
}
|
|
}
|
|
|
|
private void HandlePlayerEnter(GameObject interactor)
|
|
{
|
|
_lastInteractor = interactor;
|
|
HandleEvent(TriggerEventType.OnPlayerEnter, interactor);
|
|
}
|
|
|
|
private void HandlePlayerExit(GameObject interactor)
|
|
{
|
|
HandleEvent(TriggerEventType.OnPlayerExit, interactor);
|
|
_lastInteractor = null;
|
|
}
|
|
|
|
private void OnConversationEnded(Transform actor)
|
|
{
|
|
if (_lastInteractor != null && actor.gameObject == _lastInteractor)
|
|
{
|
|
HandleEvent(TriggerEventType.OnConversationEnd, actor.gameObject);
|
|
}
|
|
}
|
|
|
|
private void HandleEvent(TriggerEventType eventType, GameObject interactor)
|
|
{
|
|
foreach (var action in actions)
|
|
{
|
|
if (action.triggerEvent == eventType)
|
|
{
|
|
// 1. Check Dialogue System (Lua)
|
|
bool dsConditionMet = action.condition == null || action.condition.IsTrue(interactor?.transform);
|
|
|
|
// 2. Check Quest Machine (Synchronous State Check)
|
|
bool qmConditionMet = true;
|
|
if (action.questRequirements != null && action.questRequirements.Count > 0)
|
|
{
|
|
foreach (var req in action.questRequirements)
|
|
{
|
|
if (!req.IsMet())
|
|
{
|
|
qmConditionMet = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (dsConditionMet && qmConditionMet)
|
|
{
|
|
PerformAction(action, interactor);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void PerformAction(TriggeredAction action, GameObject interactor)
|
|
{
|
|
var actorTransform = interactor?.transform;
|
|
|
|
switch (action.actionType)
|
|
{
|
|
case ActionType.StartConversation:
|
|
if (!string.IsNullOrEmpty(action.conversation))
|
|
{
|
|
Transform conversant = action.conversant != null ? action.conversant : this.transform;
|
|
DialogueManager.StartConversation(action.conversation, actorTransform, conversant);
|
|
}
|
|
break;
|
|
|
|
case ActionType.ExecuteLua:
|
|
if (!string.IsNullOrEmpty(action.luaCode)) Lua.Run(action.luaCode, true);
|
|
break;
|
|
|
|
case ActionType.SendQuestMachineMessage:
|
|
if (!string.IsNullOrEmpty(action.questMachineMessage)) QuestMachineMessages.SendCompositeMessage(this, action.questMachineMessage);
|
|
break;
|
|
|
|
case ActionType.SetQuestState:
|
|
if (!string.IsNullOrEmpty(action.questID)) QuestMachine.SetQuestState(action.questID, action.questState);
|
|
break;
|
|
|
|
case ActionType.SetQuestNodeState:
|
|
if (!string.IsNullOrEmpty(action.questID) && !string.IsNullOrEmpty(action.questNodeID)) QuestMachine.SetQuestNodeState(action.questID, action.questNodeID, action.questNodeState);
|
|
break;
|
|
|
|
case ActionType.InvokeUnityEvent:
|
|
action.onExecute?.Invoke();
|
|
break;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
#region --- Definitions ---
|
|
|
|
public enum TriggerEventType
|
|
{
|
|
OnPlayerEnter, OnPlayerExit, OnValidate, OnInvalidate, OnPressActionInput, OnStartAnimation, OnEndAnimation, OnConversationEnd
|
|
}
|
|
|
|
public enum ActionType
|
|
{
|
|
StartConversation, ExecuteLua, SendQuestMachineMessage, SetQuestState, SetQuestNodeState, InvokeUnityEvent
|
|
}
|
|
|
|
|
|
|
|
[System.Serializable]
|
|
public class TriggeredAction
|
|
{
|
|
[HorizontalGroup("Top", 120)]
|
|
[BoxGroup("Top/Trigger", showLabel: false)]
|
|
[EnumToggleButtons, HideLabel]
|
|
public TriggerEventType triggerEvent;
|
|
|
|
[BoxGroup("Top/Action", showLabel: false)]
|
|
[EnumToggleButtons, HideLabel]
|
|
public ActionType actionType;
|
|
|
|
[BoxGroup("Conditions")]
|
|
[LabelText("Dialogue Condition")]
|
|
[DrawWithUnity]
|
|
public Condition condition;
|
|
|
|
[BoxGroup("Conditions")]
|
|
[LabelText("Quest Requirements")]
|
|
[InfoBox("All requirements listed here must be met.")]
|
|
public List<QuestRequirement> questRequirements = new List<QuestRequirement>();
|
|
|
|
[BoxGroup("Settings")]
|
|
[ShowIf("actionType", ActionType.StartConversation)]
|
|
[ConversationPopup(false)]
|
|
[DrawWithUnity]
|
|
public string conversation;
|
|
|
|
[BoxGroup("Settings")]
|
|
[ShowIf("actionType", ActionType.StartConversation)]
|
|
public Transform conversant;
|
|
|
|
[BoxGroup("Settings")]
|
|
[ShowIf("actionType", ActionType.ExecuteLua)]
|
|
[TextArea(2, 5)]
|
|
public string luaCode;
|
|
|
|
[BoxGroup("Settings")]
|
|
[ShowIf("actionType", ActionType.SendQuestMachineMessage)]
|
|
public string questMachineMessage;
|
|
|
|
[BoxGroup("Settings")]
|
|
[ShowIf("@this.actionType == ActionType.SetQuestState || this.actionType == ActionType.SetQuestNodeState")]
|
|
public string questID;
|
|
|
|
// --- AMBIGUITY FIXED: Explicitly using Quest Machine types ---
|
|
[BoxGroup("Settings")]
|
|
[ShowIf("actionType", ActionType.SetQuestState)]
|
|
public PixelCrushers.QuestMachine.QuestState questState;
|
|
|
|
[BoxGroup("Settings")]
|
|
[ShowIf("actionType", ActionType.SetQuestNodeState)]
|
|
public string questNodeID;
|
|
|
|
// --- AMBIGUITY FIXED: Explicitly using Quest Machine types ---
|
|
[BoxGroup("Settings")]
|
|
[ShowIf("actionType", ActionType.SetQuestNodeState)]
|
|
public PixelCrushers.QuestMachine.QuestNodeState questNodeState;
|
|
|
|
[BoxGroup("Settings")]
|
|
[ShowIf("actionType", ActionType.InvokeUnityEvent)]
|
|
public UnityEvent onExecute;
|
|
}
|
|
|
|
#endregion
|
|
} |