wasteland till prisoner
This commit is contained in:
@@ -1,26 +1,24 @@
|
||||
// --- THIS SCRIPT CAN BE PLACED ANYWHERE IN YOUR ASSETS FOLDER ---
|
||||
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
using Sirenix.OdinInspector;
|
||||
using PixelCrushers.DialogueSystem; // Required for [ConversationPopup] attribute
|
||||
using PixelCrushers.QuestMachine;
|
||||
using Invector.vCharacterController.vActions; // Required for the vTriggerGenericAction reference
|
||||
using PixelCrushers.DialogueSystem;
|
||||
using PixelCrushers.QuestMachine; // Required
|
||||
using Invector.vCharacterController.vActions;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace Beyond
|
||||
{
|
||||
[AddComponentMenu("Beyond/Quests/Generic Quest Trigger")]
|
||||
[RequireComponent(typeof(vTriggerGenericAction))] // IMPORTANT: Ensures the Invector trigger is always on the same GameObject
|
||||
[RequireComponent(typeof(bTriggerGenericAction))]
|
||||
public class GenericQuestTrigger : MonoBehaviour
|
||||
{
|
||||
#region --- ODIN-POWERED INSPECTOR ---
|
||||
|
||||
[Title("Invector Trigger Link")]
|
||||
[InfoBox("This component links into the vTriggerGenericAction below and adds quest/dialogue functionality to its events.")]
|
||||
[Required("A vTriggerGenericAction component is required on this GameObject.")]
|
||||
[OnInspectorInit("FindTriggerReference")] // Odin attribute to auto-fill the reference on first view
|
||||
public vTriggerGenericAction invectorTrigger;
|
||||
[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)]
|
||||
@@ -30,27 +28,22 @@ namespace Beyond
|
||||
|
||||
private GameObject _lastInteractor;
|
||||
|
||||
// This is a helper method for the Odin attribute [OnInspectorInit]
|
||||
private void FindTriggerReference()
|
||||
{
|
||||
if (invectorTrigger == null)
|
||||
{
|
||||
invectorTrigger = GetComponent<vTriggerGenericAction>();
|
||||
}
|
||||
if (invectorTrigger == null) invectorTrigger = GetComponent<bTriggerGenericAction>();
|
||||
}
|
||||
|
||||
#region --- CORE LOGIC (Lifecycle & Event Handlers) ---
|
||||
#region --- CORE LOGIC ---
|
||||
|
||||
private void Start()
|
||||
{
|
||||
if (invectorTrigger == null)
|
||||
{
|
||||
Debug.LogError("GenericQuestTrigger requires a vTriggerGenericAction component, but none was found. Disabling component.", this);
|
||||
this.enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Subscribe our methods to the events on the Invector component
|
||||
// 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));
|
||||
@@ -60,29 +53,20 @@ namespace Beyond
|
||||
invectorTrigger.OnValidate.AddListener((interactor) => HandleEvent(TriggerEventType.OnValidate, interactor));
|
||||
invectorTrigger.OnInvalidate.AddListener((interactor) => HandleEvent(TriggerEventType.OnInvalidate, interactor));
|
||||
|
||||
if (DialogueManager.instance != null)
|
||||
{
|
||||
DialogueManager.instance.conversationEnded += OnConversationEnded;
|
||||
}
|
||||
if (DialogueManager.instance != null) DialogueManager.instance.conversationEnded += OnConversationEnded;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
if (DialogueManager.instance != null)
|
||||
{
|
||||
DialogueManager.instance.conversationEnded -= OnConversationEnded;
|
||||
}
|
||||
if (DialogueManager.instance != null) DialogueManager.instance.conversationEnded -= OnConversationEnded;
|
||||
|
||||
// It's good practice to unsubscribe from events when disabled/destroyed to prevent memory leaks
|
||||
if (invectorTrigger != null)
|
||||
{
|
||||
invectorTrigger.OnPressActionInput.RemoveListener(() => HandleEvent(TriggerEventType.OnPressActionInput, _lastInteractor));
|
||||
invectorTrigger.OnStartAnimation.RemoveListener(() => HandleEvent(TriggerEventType.OnStartAnimation, _lastInteractor));
|
||||
invectorTrigger.OnEndAnimation.RemoveListener(() => HandleEvent(TriggerEventType.OnEndAnimation, _lastInteractor));
|
||||
invectorTrigger.OnPressActionInput.RemoveAllListeners();
|
||||
invectorTrigger.OnStartAnimation.RemoveAllListeners();
|
||||
invectorTrigger.OnEndAnimation.RemoveAllListeners();
|
||||
invectorTrigger.OnPlayerEnter.RemoveListener(HandlePlayerEnter);
|
||||
invectorTrigger.OnPlayerExit.RemoveListener(HandlePlayerExit);
|
||||
invectorTrigger.OnValidate.RemoveListener((interactor) => HandleEvent(TriggerEventType.OnValidate, interactor));
|
||||
invectorTrigger.OnInvalidate.RemoveListener((interactor) => HandleEvent(TriggerEventType.OnInvalidate, interactor));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,8 +96,24 @@ namespace Beyond
|
||||
{
|
||||
if (action.triggerEvent == eventType)
|
||||
{
|
||||
// Check if the optional Dialogue System condition is met
|
||||
if (action.condition == null || action.condition.IsTrue(interactor?.transform))
|
||||
// 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);
|
||||
}
|
||||
@@ -136,31 +136,19 @@ namespace Beyond
|
||||
break;
|
||||
|
||||
case ActionType.ExecuteLua:
|
||||
if (!string.IsNullOrEmpty(action.luaCode))
|
||||
{
|
||||
Lua.Run(action.luaCode, true);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(action.luaCode)) Lua.Run(action.luaCode, true);
|
||||
break;
|
||||
|
||||
case ActionType.SendQuestMachineMessage:
|
||||
if (!string.IsNullOrEmpty(action.questMachineMessage))
|
||||
{
|
||||
QuestMachineMessages.SendCompositeMessage(this, action.questMachineMessage);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(action.questID) && !string.IsNullOrEmpty(action.questNodeID)) QuestMachine.SetQuestNodeState(action.questID, action.questNodeID, action.questNodeState);
|
||||
break;
|
||||
|
||||
case ActionType.InvokeUnityEvent:
|
||||
@@ -172,29 +160,19 @@ namespace Beyond
|
||||
#endregion
|
||||
}
|
||||
|
||||
#region --- Action Definitions (Enums and Class) ---
|
||||
#region --- Definitions ---
|
||||
|
||||
public enum TriggerEventType
|
||||
{
|
||||
OnPlayerEnter,
|
||||
OnPlayerExit,
|
||||
OnValidate,
|
||||
OnInvalidate,
|
||||
OnPressActionInput,
|
||||
OnStartAnimation,
|
||||
OnEndAnimation,
|
||||
OnConversationEnd
|
||||
OnPlayerEnter, OnPlayerExit, OnValidate, OnInvalidate, OnPressActionInput, OnStartAnimation, OnEndAnimation, OnConversationEnd
|
||||
}
|
||||
|
||||
public enum ActionType
|
||||
{
|
||||
StartConversation,
|
||||
ExecuteLua,
|
||||
SendQuestMachineMessage,
|
||||
SetQuestState,
|
||||
SetQuestNodeState,
|
||||
InvokeUnityEvent
|
||||
StartConversation, ExecuteLua, SendQuestMachineMessage, SetQuestState, SetQuestNodeState, InvokeUnityEvent
|
||||
}
|
||||
|
||||
|
||||
|
||||
[System.Serializable]
|
||||
public class TriggeredAction
|
||||
@@ -208,20 +186,24 @@ namespace Beyond
|
||||
[EnumToggleButtons, HideLabel]
|
||||
public ActionType actionType;
|
||||
|
||||
[BoxGroup("Settings")]
|
||||
[Tooltip("Optional Dialogue System condition that must be true for this action to fire.")]
|
||||
[DrawWithUnity] // <-- Tells Odin to use the Pixel Crushers drawer for this field.
|
||||
[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)] // <-- The Dialogue System attribute that creates the dropdown.
|
||||
[DrawWithUnity] // <-- The Odin attribute that allows the above attribute to work.
|
||||
[ConversationPopup(false)]
|
||||
[DrawWithUnity]
|
||||
public string conversation;
|
||||
|
||||
[BoxGroup("Settings")]
|
||||
[ShowIf("actionType", ActionType.StartConversation)]
|
||||
[Tooltip("The other participant in the conversation. If unassigned, this trigger object will be the conversant.")]
|
||||
public Transform conversant;
|
||||
|
||||
[BoxGroup("Settings")]
|
||||
@@ -235,18 +217,18 @@ namespace Beyond
|
||||
|
||||
[BoxGroup("Settings")]
|
||||
[ShowIf("@this.actionType == ActionType.SetQuestState || this.actionType == ActionType.SetQuestNodeState")]
|
||||
[DrawWithUnity] // <-- Tells Odin to use the Quest Machine drawer for the quest ID field.
|
||||
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)]
|
||||
[DrawWithUnity] // <-- Tells Odin to use the Quest Machine drawer for the node ID field.
|
||||
public string questNodeID;
|
||||
|
||||
// --- AMBIGUITY FIXED: Explicitly using Quest Machine types ---
|
||||
[BoxGroup("Settings")]
|
||||
[ShowIf("actionType", ActionType.SetQuestNodeState)]
|
||||
public PixelCrushers.QuestMachine.QuestNodeState questNodeState;
|
||||
|
||||
40
Assets/Scripts/Triggers/QuestRequirement.cs
Normal file
40
Assets/Scripts/Triggers/QuestRequirement.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using UnityEngine;
|
||||
using Sirenix.OdinInspector; // Required for [ShowIf]
|
||||
using PixelCrushers.QuestMachine; // Required for Quest Machine types
|
||||
|
||||
namespace Beyond
|
||||
{
|
||||
[System.Serializable]
|
||||
public class QuestRequirement
|
||||
{
|
||||
[Tooltip("The ID of the quest to check. (Case-sensitive, copy from Quest Editor)")]
|
||||
public string questID;
|
||||
|
||||
[Tooltip("If checking a specific node, enter ID here. Leave empty to check the overall Quest State.")]
|
||||
public string questNodeID;
|
||||
|
||||
[ShowIf("@string.IsNullOrEmpty(this.questNodeID)")]
|
||||
[Tooltip("The state the Main Quest must be in.")]
|
||||
public QuestState requiredQuestState = QuestState.Active;
|
||||
|
||||
[ShowIf("@!string.IsNullOrEmpty(this.questNodeID)")]
|
||||
[Tooltip("The state the specific Node must be in.")]
|
||||
public QuestNodeState requiredNodeState = QuestNodeState.Active;
|
||||
|
||||
public bool IsMet()
|
||||
{
|
||||
if (string.IsNullOrEmpty(questID)) return true;
|
||||
|
||||
if (string.IsNullOrEmpty(questNodeID))
|
||||
{
|
||||
// CHECK QUEST STATE
|
||||
return QuestMachine.GetQuestState(questID) == requiredQuestState;
|
||||
}
|
||||
else
|
||||
{
|
||||
// CHECK NODE STATE
|
||||
return QuestMachine.GetQuestNodeState(questID, questNodeID) == requiredNodeState;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/Triggers/QuestRequirement.cs.meta
Normal file
2
Assets/Scripts/Triggers/QuestRequirement.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4eb8c508c00e347708412631a7d08e68
|
||||
Reference in New Issue
Block a user