wasteland till prisoner

This commit is contained in:
2026-02-13 18:16:32 +01:00
parent 9b449b22cb
commit 984deabf49
8 changed files with 3882 additions and 2737 deletions

View File

@@ -15742,7 +15742,7 @@ MonoBehaviour:
type: 0
typeString: CustomFieldType_Text
- title: Dialogue Text
value: 'A scroll... I need to find a way to open this grate.
value: 'A scroll... I need to find a way to open this gate.
'
type: 0
@@ -38536,6 +38536,275 @@ MonoBehaviour:
height: 30
canvasScrollPosition: {x: 0, y: 0}
canvasZoom: 1
- id: 137
fields:
- title: Title
value: CH01/WASTELAND/Prisoner
type: 0
typeString: CustomFieldType_Text
- title: Pictures
value: '[]'
type: 3
typeString: CustomFieldType_Files
- title: Description
value:
type: 0
typeString: CustomFieldType_Text
- title: Actor
value: 1
type: 5
typeString: CustomFieldType_Actor
- title: Conversant
value: 2
type: 5
typeString: CustomFieldType_Actor
overrideSettings:
useOverrides: 0
overrideSubtitleSettings: 0
showNPCSubtitlesDuringLine: 1
showNPCSubtitlesWithResponses: 1
showPCSubtitlesDuringLine: 0
skipPCSubtitleAfterResponseMenu: 0
subtitleCharsPerSecond: 30
minSubtitleSeconds: 2
continueButton: 0
overrideSequenceSettings: 0
defaultSequence:
defaultPlayerSequence:
defaultResponseMenuSequence:
overrideInputSettings: 0
alwaysForceResponseMenu: 1
includeInvalidEntries: 0
responseTimeout: 0
cancelSubtitle:
key: 27
buttonName:
cancelConversation:
key: 27
buttonName:
nodeColor:
dialogueEntries:
- id: 0
fields:
- title: Title
value: START
type: 0
typeString:
- title: Pictures
value: '[]'
type: 3
typeString: CustomFieldType_Files
- title: Description
value:
type: 0
typeString:
- title: Actor
value: 1
type: 5
typeString: CustomFieldType_Actor
- title: Conversant
value: 2
type: 5
typeString: CustomFieldType_Actor
- title: Menu Text
value:
type: 0
typeString:
- title: Dialogue Text
value:
type: 0
typeString:
- title: Parenthetical
value:
type: 0
typeString:
- title: Audio Files
value: '[]'
type: 3
typeString: CustomFieldType_Files
- title: Video File
value:
type: 0
typeString:
- title: Sequence
value: None()
type: 0
typeString:
- title: pl
value:
type: 4
typeString: CustomFieldType_Localization
conversationID: 137
isRoot: 0
isGroup: 0
nodeColor:
delaySimStatus: 0
falseConditionAction: Block
conditionPriority: 2
outgoingLinks:
- originConversationID: 137
originDialogueID: 0
destinationConversationID: 137
destinationDialogueID: 1
isConnector: 0
priority: 2
conditionsString:
userScript:
onExecute:
m_PersistentCalls:
m_Calls: []
canvasRect:
serializedVersion: 2
x: 20
y: 30
width: 160
height: 30
- id: 1
fields:
- title: Title
value:
type: 0
typeString: CustomFieldType_Text
- title: Pictures
value: '[]'
type: 3
typeString: CustomFieldType_Files
- title: Description
value:
type: 0
typeString: CustomFieldType_Text
- title: Actor
value: 2
type: 5
typeString: CustomFieldType_Actor
- title: Conversant
value: 1
type: 5
typeString: CustomFieldType_Actor
- title: Menu Text
value:
type: 0
typeString: CustomFieldType_Text
- title: Dialogue Text
value: Take this key..
type: 0
typeString: CustomFieldType_Text
- title: Parenthetical
value:
type: 0
typeString: CustomFieldType_Text
- title: Audio Files
value: '[]'
type: 3
typeString: CustomFieldType_Files
- title: Video File
value:
type: 0
typeString: CustomFieldType_Text
- title: Sequence
value:
type: 0
typeString: CustomFieldType_Text
- title: pl
value:
type: 4
typeString: CustomFieldType_Localization
conversationID: 137
isRoot: 0
isGroup: 0
nodeColor:
delaySimStatus: 0
falseConditionAction: Block
conditionPriority: 2
outgoingLinks:
- originConversationID: 137
originDialogueID: 1
destinationConversationID: 137
destinationDialogueID: 2
isConnector: 0
priority: 2
conditionsString:
userScript:
onExecute:
m_PersistentCalls:
m_Calls: []
canvasRect:
serializedVersion: 2
x: 20
y: 80
width: 160
height: 30
- id: 2
fields:
- title: Title
value:
type: 0
typeString: CustomFieldType_Text
- title: Pictures
value: '[]'
type: 3
typeString: CustomFieldType_Files
- title: Description
value:
type: 0
typeString: CustomFieldType_Text
- title: Actor
value: 1
type: 5
typeString: CustomFieldType_Actor
- title: Conversant
value: 2
type: 5
typeString: CustomFieldType_Actor
- title: Menu Text
value:
type: 0
typeString: CustomFieldType_Text
- title: Dialogue Text
value: Thanks...
type: 0
typeString: CustomFieldType_Text
- title: Parenthetical
value:
type: 0
typeString: CustomFieldType_Text
- title: Audio Files
value: '[]'
type: 3
typeString: CustomFieldType_Files
- title: Video File
value:
type: 0
typeString: CustomFieldType_Text
- title: Sequence
value:
type: 0
typeString: CustomFieldType_Text
- title: pl
value:
type: 4
typeString: CustomFieldType_Localization
conversationID: 137
isRoot: 0
isGroup: 0
nodeColor:
delaySimStatus: 0
falseConditionAction: Block
conditionPriority: 2
outgoingLinks: []
conditionsString:
userScript:
onExecute:
m_PersistentCalls:
m_Calls: []
canvasRect:
serializedVersion: 2
x: 20
y: 130
width: 160
height: 30
canvasScrollPosition: {x: 0, y: 0}
canvasZoom: 1
syncInfo:
syncActors: 0
syncItems: 0

View File

@@ -99,7 +99,7 @@ Material:
m_Ints: []
m_Floats:
- AOStrength: 0.42
- AlphaClipThreshold: 0.5
- AlphaClipThreshold: 0.53
- BASETEXTYPE: 0
- DissolveNoiseScale: 25
- EffectStrenght: 1
@@ -110,7 +110,7 @@ Material:
- USEDISSOLVE: 0
- USEDISSOLVEMASK: 0
- USEFRESNEL: 0
- Vector1_473704f964214ae2bc68475022d1524b: 0.05
- Vector1_473704f964214ae2bc68475022d1524b: 0.042
- _AlphaClip: 0
- _AlphaToMask: 0
- _BendEffect: 0
@@ -129,6 +129,7 @@ Material:
- _DetailAlbedoMapScale: 1
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _DstBlendAlpha: 0
- _EffectThreshold: 0
- _EnvironmentReflections: 1
- _FadeDistance: 0
@@ -148,6 +149,7 @@ Material:
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _SrcBlendAlpha: 1
- _Surface: 0
- _Threshold: 0
- _USEDISTANCEFADE: 0

View File

@@ -40,6 +40,19 @@ MonoBehaviour:
m_textTable: {fileID: 0}
m_textTableFieldID: 0
m_headingLevel: 1
--- !u!114 &-7700608773188768678
MonoBehaviour:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: c94e8fb3b9b54114cbe8185003729c1b, type: 3}
m_Name: SceneEventQuestAction
m_EditorClassIdentifier:
m_guid: 5824733f-cb06-4615-b1e7-f273d2b7ca93
--- !u!114 &-7627361466168527038
MonoBehaviour:
m_ObjectHideFlags: 1
@@ -139,6 +152,19 @@ MonoBehaviour:
m_textTable: {fileID: 0}
m_textTableFieldID: 0
m_headingLevel: 1
--- !u!114 &-6517953463989009324
MonoBehaviour:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: c94e8fb3b9b54114cbe8185003729c1b, type: 3}
m_Name: SceneEventQuestAction
m_EditorClassIdentifier:
m_guid: 761f26b6-8722-4aad-98dc-ed153f37162c
--- !u!114 &-6315871691196920026
MonoBehaviour:
m_ObjectHideFlags: 1
@@ -217,6 +243,19 @@ MonoBehaviour:
m_valueType: 0
m_intValue: 0
m_stringValue:
--- !u!114 &-5942682521202166274
MonoBehaviour:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: c94e8fb3b9b54114cbe8185003729c1b, type: 3}
m_Name: SceneEventQuestAction
m_EditorClassIdentifier:
m_guid: 45283fd7-abe7-45f8-87d5-91c43da61d3b
--- !u!114 &-5677736433535961500
MonoBehaviour:
m_ObjectHideFlags: 1
@@ -276,6 +315,19 @@ MonoBehaviour:
m_valueType: 0
m_intValue: 0
m_stringValue:
--- !u!114 &-4165716243446720717
MonoBehaviour:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: c94e8fb3b9b54114cbe8185003729c1b, type: 3}
m_Name: SceneEventQuestAction
m_EditorClassIdentifier:
m_guid: ae5da372-08d7-4fd1-8fee-d262096b856e
--- !u!114 &-3856706510345368141
MonoBehaviour:
m_ObjectHideFlags: 1
@@ -342,12 +394,12 @@ MonoBehaviour:
m_textTable: {fileID: 0}
m_textTableFieldID: 0
m_message:
m_text: Caves
m_text: Chest
m_stringAsset: {fileID: 0}
m_textTable: {fileID: 0}
m_textTableFieldID: 0
m_parameter:
m_text: Explored
m_text: Opened
m_stringAsset: {fileID: 0}
m_textTable: {fileID: 0}
m_textTableFieldID: 0
@@ -925,7 +977,8 @@ MonoBehaviour:
- m_contentList: []
- m_contentList: []
- m_contentList: []
- m_actionList: []
- m_actionList:
- {fileID: -4165716243446720717}
m_categorizedContentList:
- m_contentList: []
- m_contentList: []
@@ -1120,7 +1173,8 @@ MonoBehaviour:
- m_contentList: []
- m_contentList: []
- m_contentList: []
- m_actionList: []
- m_actionList:
- {fileID: -5942682521202166274}
m_categorizedContentList:
- m_contentList: []
- m_contentList: []
@@ -1168,7 +1222,8 @@ MonoBehaviour:
- m_contentList: []
- m_contentList: []
- m_contentList: []
- m_actionList: []
- m_actionList:
- {fileID: -6517953463989009324}
m_categorizedContentList:
- m_contentList: []
- m_contentList: []
@@ -1216,7 +1271,8 @@ MonoBehaviour:
- m_contentList: []
- m_contentList: []
- m_contentList: []
- m_actionList: []
- m_actionList:
- {fileID: -7700608773188768678}
m_categorizedContentList:
- m_contentList: []
- m_contentList: []
@@ -1264,7 +1320,8 @@ MonoBehaviour:
- m_contentList: []
- m_contentList: []
- m_contentList: []
- m_actionList: []
- m_actionList:
- {fileID: 6905461424178767340}
m_categorizedContentList:
- m_contentList: []
- m_contentList: []
@@ -1289,7 +1346,7 @@ MonoBehaviour:
width: 120
height: 48
- m_id:
m_text: UseTheKeyToOpenTheAltar
m_text: OpenTheAltar
m_stringAsset: {fileID: 0}
m_textTable: {fileID: 0}
m_textTableFieldID: 0
@@ -1312,7 +1369,8 @@ MonoBehaviour:
- m_contentList: []
- m_contentList: []
- m_contentList: []
- m_actionList: []
- m_actionList:
- {fileID: 8579568951749031860}
m_categorizedContentList:
- m_contentList: []
- m_contentList: []
@@ -1609,7 +1667,7 @@ MonoBehaviour:
m_textTable: {fileID: 0}
m_textTableFieldID: 0
m_parameter:
m_text: Examine
m_text: Examined
m_stringAsset: {fileID: 0}
m_textTable: {fileID: 0}
m_textTableFieldID: 0
@@ -1840,6 +1898,19 @@ MonoBehaviour:
m_Name: SceneEventQuestAction
m_EditorClassIdentifier:
m_guid: ba7b126c-32b3-4580-a4a2-989a78500bcc
--- !u!114 &6905461424178767340
MonoBehaviour:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: c94e8fb3b9b54114cbe8185003729c1b, type: 3}
m_Name: SceneEventQuestAction
m_EditorClassIdentifier:
m_guid: 1ab5c368-9daf-48a6-95e9-3a671c7e3488
--- !u!114 &7083521629110602899
MonoBehaviour:
m_ObjectHideFlags: 1
@@ -1993,6 +2064,19 @@ MonoBehaviour:
m_textTable: {fileID: 0}
m_textTableFieldID: 0
m_headingLevel: 1
--- !u!114 &8579568951749031860
MonoBehaviour:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: c94e8fb3b9b54114cbe8185003729c1b, type: 3}
m_Name: SceneEventQuestAction
m_EditorClassIdentifier:
m_guid: ac13fa0e-c1af-4a0f-9299-d31aea6e9ad1
--- !u!114 &8579667891300100917
MonoBehaviour:
m_ObjectHideFlags: 1

File diff suppressed because it is too large Load Diff

View File

@@ -2,192 +2,242 @@
using Invector.vCharacterController;
using Invector.vCharacterController.vActions;
using System.Collections;
using System.Collections.Generic; // Required for List
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Serialization;
using Sirenix.OdinInspector;
using PixelCrushers.QuestMachine;
using PixelCrushers.QuestMachine; // Required for Quest Machine
using PixelCrushers.DialogueSystem;
using TMPro;
namespace Beyond
{
[vClassHeader("bTrigger Generic Action", false, iconName = "triggerIcon")]
public class bTriggerGenericAction : vTriggerGenericAction
{
[vEditorToolbar("Conditions", order = 0)] [SerializeField]
private Condition m_questCondition;
public bool m_itemChecking;
public int m_itemToCheckId;
[vHelpBox("Disable Selected HUD OnValidate, and enable OnInvalidate. Script ActionTriggerEvent.cs")]
public bool disableHUD = true;
[vHelpBox("Changes interaction image")]
//public bool isDialogueTrigger = false;
public TriggerDescriptor.TriggerType triggerType = TriggerDescriptor.TriggerType.Generic;
public UnityEvent OnPlayerMatchTargetPosition;
[vEditorToolbar("Animation", order = 2)] [SerializeField]
public bool useFadeOnMatchingToTarget;
[SerializeField] private AnimationCurve m_fadeInCurve;
[SerializeField] private AnimationCurve m_fadeOutCurve;
[SerializeField] private float m_fadeSpeed = 2f;
[vEditorToolbar("Interaction", order = 4)] [SerializeField]
private bool m_enableInteractionLegality;
public Quest m_guilt;
private bool m_faded;
public bool Faded => m_faded;
public float animationDelay = 0f;
private TriggerDescriptor m_triggerDescriptor;
private void OnEnable()
[vClassHeader("bTrigger Generic Action", false, iconName = "triggerIcon")]
public class bTriggerGenericAction : vTriggerGenericAction
{
if (useFadeOnMatchingToTarget)
#region --- CONDITIONS ---
[vEditorToolbar("Conditions", order = 0)]
[LabelText("Dialogue Condition")]
[Tooltip("Lua condition from Dialogue System")]
[SerializeField]
private Condition m_questCondition;
[LabelText("Quest Requirements")]
[InfoBox("The trigger will only activate if these Quest Machine states are met.")]
[SerializeField]
public List<QuestRequirement> questRequirements = new List<QuestRequirement>();
[Title("Item Checking")]
public bool m_itemChecking;
[ShowIf("m_itemChecking")]
public int m_itemToCheckId;
#endregion
#region --- SETTINGS ---
[vHelpBox("Disable Selected HUD OnValidate, and enable OnInvalidate. Script ActionTriggerEvent.cs")]
public bool disableHUD = true;
public TriggerDescriptor.TriggerType triggerType = TriggerDescriptor.TriggerType.Generic;
public UnityEvent OnPlayerMatchTargetPosition;
[vEditorToolbar("Animation", order = 2)] [SerializeField]
public bool useFadeOnMatchingToTarget;
[SerializeField] private AnimationCurve m_fadeInCurve;
[SerializeField] private AnimationCurve m_fadeOutCurve;
[SerializeField] private float m_fadeSpeed = 2f;
[vEditorToolbar("Interaction", order = 4)] [SerializeField]
private bool m_enableInteractionLegality;
public Quest m_guilt;
private bool m_faded;
public bool Faded => m_faded;
public float animationDelay = 0f;
private TriggerDescriptor m_triggerDescriptor;
#endregion
#region --- LIFECYCLE ---
private void OnEnable()
{
OnPressActionInput.AddListener(ToggleFade);
OnPlayerMatchTargetPosition.AddListener(ToggleFade);
if (FadeCanvasGroup.Instance)
if (useFadeOnMatchingToTarget)
{
FadeCanvasGroup.Instance.OnFadeInEnd.AddListener(OnFadeInEnd);
FadeCanvasGroup.Instance.OnFadeOutEnd.AddListener(OnFadeOutEnd);
OnPressActionInput.AddListener(ToggleFade);
OnPlayerMatchTargetPosition.AddListener(ToggleFade);
if (FadeCanvasGroup.Instance)
{
FadeCanvasGroup.Instance.OnFadeInEnd.AddListener(OnFadeInEnd);
FadeCanvasGroup.Instance.OnFadeOutEnd.AddListener(OnFadeOutEnd);
}
}
}
}
private void OnDisable()
{
if (useFadeOnMatchingToTarget)
private void OnDisable()
{
OnPressActionInput.RemoveListener(ToggleFade);
OnPlayerMatchTargetPosition.RemoveListener(ToggleFade);
if (FadeCanvasGroup.Instance)
if (useFadeOnMatchingToTarget)
{
FadeCanvasGroup.Instance.OnFadeInEnd.RemoveListener(OnFadeInEnd);
FadeCanvasGroup.Instance.OnFadeOutEnd.RemoveListener(OnFadeOutEnd);
OnPressActionInput.RemoveListener(ToggleFade);
OnPlayerMatchTargetPosition.RemoveListener(ToggleFade);
if (FadeCanvasGroup.Instance)
{
FadeCanvasGroup.Instance.OnFadeInEnd.RemoveListener(OnFadeInEnd);
FadeCanvasGroup.Instance.OnFadeOutEnd.RemoveListener(OnFadeOutEnd);
}
}
}
protected override void Start()
{
base.Start();
m_triggerDescriptor = new TriggerDescriptor(gameObject, triggerType);
OnValidate.AddListener(OnActionTriggerEnter);
OnInvalidate.AddListener(OnActionTriggerExit);
OnEndAnimation.AddListener(() => OnActionEndAnimation(gameObject));
}
#endregion
#region --- ACTION LOGIC ---
public override IEnumerator OnPressActionDelay(GameObject obj)
{
// 1. Security Check: Re-validate conditions before executing
// This prevents race conditions where the player pressed the button just as the quest state changed.
if (!AreConditionsMet())
{
yield break;
}
if (!m_itemChecking)
{
yield return base.OnPressActionDelay(obj);
}
else
{
if (Player.Instance.ItemManager.ContainItem(m_itemToCheckId))
{
yield return base.OnPressActionDelay(obj);
}
else
{
var item = Player.Instance.ItemManager.itemListData.items.Find(x => x.id == m_itemToCheckId);
string itemName = item != null ? item.name : "Item";
DialogueManager.BarkString($"{itemName} Required", Player.Instance.transform);
}
}
}
private void OnActionTriggerEnter(GameObject gameObject)
{
// 1. Check all conditions (Dialogue System + Quest Machine)
if (!AreConditionsMet())
{
return;
}
if (disableHUD)
{
ActionTriggerEvent.ActionTriggerEnter?.Invoke(m_triggerDescriptor);
}
if (triggerType == TriggerDescriptor.TriggerType.Dialogue)
{
Player.Instance.SetDialogueIntaractableButtonImage();
}
}
private void OnActionTriggerExit(GameObject gameObject)
{
if (disableHUD)
{
ActionTriggerEvent.ActionTriggerExit?.Invoke(m_triggerDescriptor);
}
if (triggerType == TriggerDescriptor.TriggerType.Dialogue)
{
Player.Instance.ResetIntaractableButtonImage();
}
}
#endregion
#region --- HELPER METHODS ---
private bool AreConditionsMet()
{
// 1. Check Dialogue System Condition
if (!m_questCondition.IsTrue(null))
{
return false;
}
// 2. Check Quest Machine Requirements
if (questRequirements != null && questRequirements.Count > 0)
{
foreach (var req in questRequirements)
{
if (!req.IsMet()) return false;
}
}
return true;
}
private void OnActionEndAnimation(GameObject gameObject)
{
if (disableHUD)
{
ActionTriggerEvent.ActionTriggerExit?.Invoke(m_triggerDescriptor);
}
if (triggerType == TriggerDescriptor.TriggerType.Dialogue)
{
Player.Instance.ResetIntaractableButtonImage();
}
if (!m_enableInteractionLegality)
{
return;
}
if (m_guilt == null)
{
Debug.LogError("There is no guilt assigned to interactable game object: " + gameObject.name);
return;
}
Player.Instance.PlayerConfessionController.AddGuilt(m_guilt);
}
private void ToggleFade()
{
if (FadeCanvasGroup.Instance == null) return;
if (!m_faded)
{
m_faded = true;
FadeCanvasGroup.Instance.FadeOut(1f / m_fadeSpeed);
return;
}
FadeCanvasGroup.Instance.FadeIn(1f / m_fadeSpeed);
}
private void OnFadeInEnd() => m_faded = false;
private void OnFadeOutEnd() => m_faded = true;
#endregion
}
public override IEnumerator OnPressActionDelay(GameObject obj)
{
if (!m_itemChecking)
{
yield return base.OnPressActionDelay(obj);
}
if (m_itemChecking && Player.Instance.ItemManager.ContainItem(m_itemToCheckId))
{
yield return base.OnPressActionDelay(obj);
}
if (!Player.Instance.ItemManager.ContainItem(m_itemToCheckId))
{
var item = Player.Instance.ItemManager.itemListData.items.Find(item => item.id == m_itemToCheckId);
DialogueManager.BarkString($"{item.name} Required", Player.Instance.transform);
}
}
private void OnActionTriggerEnter(GameObject gameObject)
{
if (!m_questCondition.IsTrue(null))
{
return;
}
if (disableHUD)
{
ActionTriggerEvent.ActionTriggerEnter?.Invoke(m_triggerDescriptor);
}
if (triggerType == TriggerDescriptor.TriggerType.Dialogue)
{
Player.Instance.SetDialogueIntaractableButtonImage();
}
}
private void OnActionTriggerExit(GameObject gameObject)
{
if (disableHUD)
{
ActionTriggerEvent.ActionTriggerExit?.Invoke(m_triggerDescriptor);
}
if (triggerType == TriggerDescriptor.TriggerType.Dialogue)
{
Player.Instance.ResetIntaractableButtonImage();
}
}
private void OnActionEndAnimation(GameObject gameObject)
{
if (disableHUD)
{
ActionTriggerEvent.ActionTriggerExit?.Invoke(m_triggerDescriptor);
}
if (triggerType == TriggerDescriptor.TriggerType.Dialogue)
{
Player.Instance.ResetIntaractableButtonImage();
}
if (!m_enableInteractionLegality)
{
return;
}
if (m_guilt == null)
{
Debug.LogError("There is no quilt assigned to interactable game object: " + gameObject.name);
return;
}
Player.Instance.PlayerConfessionController.AddGuilt(m_guilt);
}
private void ToggleFade()
{
if (FadeCanvasGroup.Instance == null)
{
return;
}
if (!m_faded)
{
m_faded = true;
FadeCanvasGroup.Instance.FadeOut(1f / m_fadeSpeed);
//.InvokeFade(m_fadeInCurve, m_fadeSpeed);
return;
}
FadeCanvasGroup.Instance.FadeIn(1f / m_fadeSpeed);
//FadeCanvasGroup.InvokeFade(m_fadeOutCurve, m_fadeSpeed);
}
private void OnFadeInEnd()
{
m_faded = false;
}
private void OnFadeOutEnd()
{
m_faded = true;
}
protected override void Start()
{
base.Start();
m_triggerDescriptor = new TriggerDescriptor(gameObject, triggerType);
OnValidate.AddListener(OnActionTriggerEnter);
OnInvalidate.AddListener(OnActionTriggerExit);
OnEndAnimation.AddListener(() => OnActionEndAnimation(gameObject));
}
}
}
}

View File

@@ -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;

View 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;
}
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 4eb8c508c00e347708412631a7d08e68