fr.jeanf.questsystem 0.0.60 → 0.0.62

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,32 @@
1
+ #if UNITY_EDITOR
2
+ using UnityEditor;
3
+ using UnityEngine;
4
+
5
+ namespace jeanf.questsystem
6
+ {
7
+ [CustomEditor(typeof(QuestItem), true)]
8
+ public class QuestItem_Editor : Editor
9
+ {
10
+ public override void OnInspectorGUI()
11
+ {
12
+ GUILayout.Space(10);
13
+ var eventToSend = (QuestItem)target;
14
+ GUILayout.BeginHorizontal();
15
+ if(GUILayout.Button("Log active steps", GUILayout.Height(20))) {
16
+ eventToSend.LogActiveSteps(); // how do i call this?
17
+ }
18
+ var originalColor = GUI.backgroundColor;
19
+ GUI.backgroundColor = Color.green;
20
+ if (GUILayout.Button("Validate Currently Active Steps", GUILayout.Height(20)))
21
+ {
22
+ eventToSend.ValidateCurrentlyActiveSteps(); // how do i call this?
23
+ }
24
+ GUI.backgroundColor = originalColor;
25
+ GUILayout.EndHorizontal();
26
+ GUILayout.Space(10);
27
+
28
+ DrawDefaultInspector();
29
+ }
30
+ }
31
+ }
32
+ #endif
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: 890f818e403e8554b90ebafaad84eafb
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -11,10 +11,18 @@ namespace jeanf.questsystem
11
11
  {
12
12
  GUILayout.Space(10);
13
13
  var eventToSend = (QuestStep)target;
14
+ GUILayout.BeginHorizontal();
14
15
  if (GUILayout.Button("Regenerate questStep id", GUILayout.Height(20)))
15
16
  {
16
17
  eventToSend.GenerateId(); // how do i call this?
17
18
  }
19
+ var originalColor = GUI.backgroundColor;
20
+ GUI.backgroundColor = Color.green;
21
+ if(GUILayout.Button("Validate step", GUILayout.Height(20))) {
22
+ eventToSend.FinishQuestStep(); // how do i call this?
23
+ }
24
+ GUI.backgroundColor = originalColor;
25
+ GUILayout.EndHorizontal();
18
26
  GUILayout.Space(10);
19
27
 
20
28
  DrawDefaultInspector();
@@ -47,37 +47,6 @@ namespace jeanf.questsystem
47
47
  this.questSO = questQuestSo;
48
48
  this.state = questState;
49
49
  this.questStepStates = questStepStates;
50
-
51
- //if the quest step states and prefabs are different lengths,
52
- //something has changed during development and the saved data is out of sync.
53
- //if (this.questStepStates.Length != this.questSO.questSteps.Length)
54
- //{
55
- // Debug.LogWarning("Quest Step Prefabs and Quest Step States are "
56
- // + "of different lengths. This indicates something changed "
57
- // + "with the QuestInfo and the saved data is now out of sync. "
58
- // + "Reset your data - as this might cause issues. QuestId: " + this.questSO.id);
59
- //}
60
50
  }
61
-
62
-
63
-
64
- //public void StoreQuestStepState(QuestStepState questStepState, int stepIndex)
65
- //{
66
- // if (stepIndex < questStepStates.Count)
67
- // {
68
- // questStepStates[stepIndex].state = questStepState.state;
69
- // }
70
- // else
71
- // {
72
- // Debug.LogWarning("Tried to access quest step data, but stepIndex was out of range: "
73
- // + "Quest Id = " + questSO.id + ", Step Index = " + stepIndex);
74
- // }
75
- //}
76
-
77
- //public QuestData GetQuestData()
78
- //{
79
- // return new QuestData(state, currentQuestStepIndex, questStepStates);
80
- //}
81
-
82
51
  }
83
52
  }
@@ -1,18 +1,18 @@
1
1
  using System;
2
2
  using System.Collections.Generic;
3
+ using System.Linq;
3
4
  using jeanf.EventSystem;
4
5
  using UnityEngine;
5
6
  using jeanf.propertyDrawer;
6
7
  using jeanf.validationTools;
7
8
  using UnityEditor;
8
- using System.Linq;
9
- using Object = UnityEngine.Object;
10
-
11
9
 
12
10
  namespace jeanf.questsystem
13
11
  {
14
12
  public class QuestItem : MonoBehaviour, IDebugBehaviour, IValidatable
15
13
  {
14
+
15
+ #region interface variables
16
16
  public bool isDebug
17
17
  {
18
18
  get => _isDebug;
@@ -22,24 +22,30 @@ namespace jeanf.questsystem
22
22
 
23
23
  [SerializeField] private bool _isDebug = false;
24
24
  [SerializeField] private bool _startQuestOnEnable = false;
25
+ #endregion
25
26
 
27
+ #region Step Dictionaries
26
28
  [Tooltip("Visual feedback for the quest state")] [Header("Quest")]
27
29
  [SerializeField] [Validation("A reference to a questSO is required")] private QuestSO questSO;
28
30
  private Dictionary<string, QuestStep> stepMap = new Dictionary<string, QuestStep>();
29
31
  private Dictionary<string, QuestStep> activeSteps = new Dictionary<string, QuestStep>();
30
32
  private Dictionary<string, QuestStep> completedSteps = new Dictionary<string, QuestStep>();
31
33
  private List<QuestStep> rootSteps = new List<QuestStep>();
34
+ #endregion
32
35
 
33
36
 
34
- [ReadOnly] [Range(0, 1)] [SerializeField]
35
- private float progress = 0.0f;
36
-
37
+ #region main data
37
38
  [SerializeField] [ReadOnly]
38
39
  private bool clearToStart = false;
39
-
40
40
  private string questId;
41
41
  private QuestState currentQuestState;
42
+ [ReadOnly][Range(0, 1)][SerializeField]
43
+ private float progress = 0.0f;
44
+ #endregion
42
45
 
46
+ #region events
47
+ public delegate void ValidateStep(string stepId);
48
+ public static ValidateStep ValidateStepEvent;
43
49
  // these events are Located in Assets/Resources/Quests/Channels - it is searched for at Awake time.
44
50
  // if they do not exist simply right click in the hierarchy and find >InitializeQuestSystem<
45
51
  [Header("Listening on:")]
@@ -51,10 +57,10 @@ namespace jeanf.questsystem
51
57
  private StringEventChannelSO requirementCheck;
52
58
  [SerializeField][Validation("A reference to the LoadRequiredScenesEventChannel SO is required")] StringListEventChannelSO loadRequiredScenesEventChannel;
53
59
  [SerializeField] IntEventChannelSO unlockDoorsEventChannel;
54
-
55
-
60
+ #endregion
56
61
 
57
- #region Awake/Enable/Disable
62
+
63
+ #region Standard Unity Methods
58
64
  private void Awake()
59
65
  {
60
66
  questId = questSO.id;
@@ -65,7 +71,10 @@ namespace jeanf.questsystem
65
71
  rootSteps.Add(questSO.rootSteps[i]);
66
72
  }
67
73
  }
68
-
74
+ private void Reset()
75
+ {
76
+ Init(questId);
77
+ }
69
78
  private void OnEnable()
70
79
  {
71
80
  Subscribe();
@@ -74,7 +83,6 @@ namespace jeanf.questsystem
74
83
  }
75
84
  private void OnDisable() => Unsubscribe();
76
85
  private void OnDestroy() => Unsubscribe();
77
-
78
86
  private void Subscribe()
79
87
  {
80
88
  resetChannel.OnEventRaised += Reset;
@@ -86,7 +94,6 @@ namespace jeanf.questsystem
86
94
  QuestStep.stepActive += UpdateStepStatus;
87
95
  QuestStep.childStep += AddStepToStepMap;
88
96
  }
89
-
90
97
  private void Unsubscribe()
91
98
  {
92
99
  resetChannel.OnEventRaised -= Reset;
@@ -102,11 +109,6 @@ namespace jeanf.questsystem
102
109
  }
103
110
  #endregion
104
111
 
105
- private void Reset()
106
- {
107
- Init(questId);
108
- }
109
-
110
112
  #region Instantiations & Loading
111
113
  public void InstantiateQuestStep(string id)
112
114
  {
@@ -114,10 +116,10 @@ namespace jeanf.questsystem
114
116
  if (stepMap[id].stepStatus != QuestStepStatus.Inactive) return;
115
117
  if (activeSteps.ContainsKey(id)) return;
116
118
 
119
+
117
120
  Instantiate(stepMap[id], this.transform, true);
118
- //if(!activeSteps.ContainsKey(id)) activeSteps.Add(id,Instantiate(stepMap[id], this.transform, true));
119
- }
120
121
 
122
+ }
121
123
  private void LoadDependencies()
122
124
  {
123
125
  loadRequiredScenesEventChannel.RaiseEvent(questSO.ScenesToLoad);
@@ -127,43 +129,22 @@ namespace jeanf.questsystem
127
129
  unlockDoorsEventChannel.RaiseEvent(roomToUnlock);
128
130
  }
129
131
  }
130
- #endregion
131
-
132
- public void UpdateStepStatus(string id, QuestStepStatus status)
133
- {
134
- switch (status)
135
- {
136
- case QuestStepStatus.Completed when activeSteps.ContainsKey(id):
137
- // put step in completed list
138
- activeSteps.Remove(id);
139
- completedSteps.Add(id, stepMap[id]);
140
- break;
141
- case QuestStepStatus.Active when !activeSteps.ContainsKey(id):
142
- // put step in active list
143
- activeSteps.Add(id, stepMap[id]);
144
- break;
145
- case QuestStepStatus.Inactive:
146
- // do nothing
147
- default:
148
- // do nothing
149
- return;
150
- }
151
- }
152
-
153
132
  private void AddStepToStepMap(QuestStep step)
154
133
  {
155
- if(isDebug) Debug.Log($"--- Received request to add step {step.name} with id: {step.StepId} to stepMap.");
134
+ if (isDebug) Debug.Log($"--- Received request to add step {step.name} with id: {step.StepId} to stepMap.");
156
135
  if (!stepMap.ContainsKey(step.StepId))
157
136
  {
158
- if(isDebug) Debug.Log($"--- Step [{step.StepId}] not found in stepMap, adding it.");
137
+ if (isDebug) Debug.Log($"--- Step [{step.StepId}] not found in stepMap, adding it.");
159
138
  stepMap.Add(step.StepId, step);
160
139
  }
161
140
  if (completedSteps.ContainsKey(step.StepId))
162
141
  {
163
- if(isDebug) Debug.Log($"--- Step [{step.StepId}] already completed removing it from completeSteps so that we can go through it again.");
142
+ if (isDebug) Debug.Log($"--- Step [{step.StepId}] already completed removing it from completeSteps so that we can go through it again.");
164
143
  completedSteps.Remove(step.StepId);
165
144
  }
166
145
  }
146
+ #endregion
147
+
167
148
  #region quest process
168
149
  private void Init(string id)
169
150
  {
@@ -194,7 +175,26 @@ namespace jeanf.questsystem
194
175
 
195
176
  LoadDependencies();
196
177
  }
197
-
178
+ public void UpdateStepStatus(string id, QuestStepStatus status)
179
+ {
180
+ switch (status)
181
+ {
182
+ case QuestStepStatus.Completed when activeSteps.ContainsKey(id):
183
+ // put step in completed list
184
+ activeSteps.Remove(id);
185
+ completedSteps.Add(id, stepMap[id]);
186
+ break;
187
+ case QuestStepStatus.Active when !activeSteps.ContainsKey(id):
188
+ // put step in active list
189
+ activeSteps.Add(id, stepMap[id]);
190
+ break;
191
+ case QuestStepStatus.Inactive:
192
+ // do nothing
193
+ default:
194
+ // do nothing
195
+ return;
196
+ }
197
+ }
198
198
  private void UpdateState()
199
199
  {
200
200
  if (isDebug) Debug.Log($"Updating State...");
@@ -230,14 +230,12 @@ namespace jeanf.questsystem
230
230
  throw new ArgumentOutOfRangeException();
231
231
  }
232
232
  }
233
-
234
233
  private void UpdateProgress(string id, float progress)
235
234
  {
236
235
  if (id != questId) return;
237
236
  this.progress = progress;
238
237
  if (isDebug) Debug.Log($"questid [{id}] progress = {progress * 100}%");
239
238
  }
240
-
241
239
  private void QuestStateChange(Quest quest)
242
240
  {
243
241
  // only update the quest state if this point has the corresponding quest
@@ -249,17 +247,27 @@ namespace jeanf.questsystem
249
247
  }
250
248
  #endregion
251
249
 
250
+ #region Complete all Steps
251
+ public void ValidateCurrentlyActiveSteps()
252
+ {
253
+ var currentlyActiveSteps = activeSteps.Keys;
254
+
255
+ for (var i = 0; i < currentlyActiveSteps.Count; i++)
256
+ {
257
+ var activeStep = activeSteps.ElementAt(i);
258
+ var stepKey = activeStep.Key;
259
+ if(activeSteps.ContainsKey(stepKey)) ValidateStepEvent.Invoke(stepKey);
260
+ }
261
+ }
262
+ #endregion
263
+
252
264
  #region validation tools
253
265
 
254
- #if UNITY_EDITOR
266
+ #if UNITY_EDITOR
255
267
  public void OnValidate()
256
268
  {
257
269
  ValidityCheck();
258
270
  }
259
-
260
-
261
-
262
-
263
271
  public void LogActiveSteps()
264
272
  {
265
273
  Debug.Log($"There is {activeSteps.Count} active steps at the moment.");
@@ -269,7 +277,6 @@ namespace jeanf.questsystem
269
277
  }
270
278
  }
271
279
  #endif
272
-
273
280
  private void ValidityCheck()
274
281
  {
275
282
  const string searching = "attempting to find";
@@ -354,20 +361,4 @@ namespace jeanf.questsystem
354
361
  }
355
362
  #endregion
356
363
  }
357
-
358
-
359
- #if UNITY_EDITOR
360
- [CustomEditor(typeof(QuestItem))]
361
- public class BoolEventOnClickEditor : Editor {
362
- override public void OnInspectorGUI () {
363
- DrawDefaultInspector();
364
- GUILayout.Space(10);
365
- var eventToSend = (QuestItem) target;
366
- if(GUILayout.Button("Log active steps", GUILayout.Height(30))) {
367
- eventToSend.LogActiveSteps(); // how do i call this?
368
- }
369
- GUILayout.Space(10);
370
- }
371
- }
372
- #endif
373
364
  }
@@ -11,6 +11,8 @@ namespace jeanf.questsystem
11
11
  {
12
12
  public class QuestManager : MonoBehaviour, IDebugBehaviour, IValidatable
13
13
  {
14
+ #region variables
15
+ #region interface variables
14
16
  public bool isDebug
15
17
  {
16
18
  get => _isDebug;
@@ -19,23 +21,26 @@ namespace jeanf.questsystem
19
21
  public bool IsValid { get; private set; }
20
22
 
21
23
  [SerializeField] private bool _isDebug = false;
24
+ #endregion
22
25
 
23
- [FormerlySerializedAs("loadQuestState")] [Header("Config")] [SerializeField]
24
- private bool loadSavedQuestState = true;
25
-
26
+ #region event channels
26
27
  [Header("Broadcasting on:")]
27
28
  [SerializeField] [Validation("A reference to the questStatusUpdateChannel is required.")] private StringEventChannelSO questStatusUpdateChannel;
28
29
  [SerializeField] [Validation("A reference to the questProgress is required.")] private StringFloatEventChannelSO questProgress;
29
30
  [SerializeField] [Validation("A reference to the questInitialCheck channel is required.")] private StringEventChannelSO QuestInitialCheck;
30
-
31
31
  [Header("Listening on:")] [SerializeField] [Validation("A reference to the questStatusUpdateRequested is required.")] private StringEventChannelSO questStatusUpdateRequested;
32
+ #endregion
32
33
 
34
+ #region other variables
35
+ [FormerlySerializedAs("loadQuestState")] [Header("Config")] [SerializeField]
36
+ private bool loadSavedQuestState = true;
33
37
  private Dictionary<string, Quest> questMap;
34
-
35
-
36
- // quest start requirements
37
38
  private int currentPlayerLevel;
39
+ #endregion
40
+ #endregion
38
41
 
42
+ #region Methods
43
+ #region Standard Unity Methods
39
44
  private void Awake()
40
45
  {
41
46
  questMap = CreateQuestMap();
@@ -45,25 +50,16 @@ namespace jeanf.questsystem
45
50
  CheckIfQuestIsAlreadyLoaded(quest.Key);
46
51
  }
47
52
  }
48
-
49
53
  private void OnEnable()
50
54
  {
51
55
  GameEventsManager.instance.questEvents.onStartQuest += StartQuest;
52
- GameEventsManager.instance.questEvents.onFinishQuest += FinishQuest;
53
-
56
+ GameEventsManager.instance.questEvents.onFinishQuest += FinishQuest;
54
57
  //GameEventsManager.instance.questEvents.onQuestStepStateChange += QuestStepStateChange;
55
-
56
58
  GameEventsManager.instance.playerEvents.onPlayerLevelChange += PlayerLevelChange;
57
-
58
59
  questStatusUpdateRequested.OnEventRaised += ctx => CheckRequirementsMet(questMap[ctx]);
59
-
60
-
61
60
  }
62
-
63
-
64
61
  private void OnDisable() => Unsubscribe();
65
62
  private void OnDestroy() => Unsubscribe();
66
-
67
63
  private void Unsubscribe()
68
64
  {
69
65
  GameEventsManager.instance.questEvents.onStartQuest -= StartQuest;
@@ -74,7 +70,6 @@ namespace jeanf.questsystem
74
70
  GameEventsManager.instance.playerEvents.onPlayerLevelChange -= PlayerLevelChange;
75
71
 
76
72
  }
77
-
78
73
  private void Start()
79
74
  {
80
75
  foreach (Quest quest in questMap.Values)
@@ -83,25 +78,63 @@ namespace jeanf.questsystem
83
78
  GameEventsManager.instance.questEvents.QuestStateChange(quest);
84
79
  }
85
80
  }
86
-
87
-
88
- private void CheckIfQuestIsAlreadyLoaded(string id)
81
+ private void Update()
89
82
  {
90
- QuestInitialCheck.RaiseEvent(id);
83
+ // loop through ALL quests
84
+ foreach (Quest quest in questMap.Values)
85
+ {
86
+ // if we're now meeting the requirements, switch over to the CAN_START state
87
+ if (quest.state == QuestState.REQUIREMENTS_NOT_MET && CheckRequirementsMet(quest))
88
+ {
89
+ ChangeQuestState(quest.questSO.id, QuestState.CAN_START);
90
+ }
91
+ }
91
92
  }
92
-
93
- private void ChangeQuestState(string id, QuestState state)
93
+ private void OnApplicationQuit()
94
94
  {
95
- Quest quest = GetQuestById(id);
96
- quest.state = state;
97
- GameEventsManager.instance.questEvents.QuestStateChange(quest);
95
+ foreach (Quest quest in questMap.Values)
96
+ {
97
+ SaveQuest(quest);
98
+ }
98
99
  }
100
+ #endregion
99
101
 
100
- private void PlayerLevelChange(int level)
102
+ #region Quest Checks and getters
103
+ private Dictionary<string, Quest> CreateQuestMap()
101
104
  {
102
- currentPlayerLevel = level;
105
+ // loads all QuestInfoSO Scriptable Objects under the Assets/Resources/Quests folder
106
+ QuestSO[] allQuests = Resources.LoadAll<QuestSO>("Quests");
107
+ // Create the quest map
108
+ Dictionary<string, Quest> questMap = new Dictionary<string, Quest>();
109
+ foreach (QuestSO questSO in allQuests)
110
+ {
111
+ var id = questSO.id;
112
+ if (questMap.ContainsKey(id))
113
+ {
114
+ Debug.LogWarning("Duplicate ID found when creating quest map: " + questSO.id);
115
+ }
116
+ else
117
+ {
118
+ questMap.Add(id, LoadQuest(questSO));
119
+ }
120
+ if (isDebug) Debug.Log($"Adding {questSO.name} to the questmap, its id is: {questSO.id}");
121
+ }
122
+ return questMap;
123
+ }
124
+ private void CheckIfQuestIsAlreadyLoaded(string id)
125
+ {
126
+ QuestInitialCheck.RaiseEvent(id);
103
127
  }
128
+ public Quest GetQuestById(string id)
129
+ {
130
+ Quest quest = questMap[id];
131
+ if (quest == null)
132
+ {
133
+ Debug.LogError("ID not found in the Quest Map: " + id);
134
+ }
104
135
 
136
+ return quest;
137
+ }
105
138
  private bool CheckRequirementsMet(Quest quest)
106
139
  {
107
140
  // check player level requirements
@@ -115,25 +148,20 @@ namespace jeanf.questsystem
115
148
  meetsRequirements = false;
116
149
  }
117
150
  }
118
-
119
- if(isDebug) Debug.Log($"checking requirements for quest: {quest.questSO.name}, [{quest.questSO.id}], meetsRequirements: {meetsRequirements}");
151
+
152
+ if (isDebug) Debug.Log($"checking requirements for quest: {quest.questSO.name}, [{quest.questSO.id}], meetsRequirements: {meetsRequirements}");
120
153
 
121
154
  return meetsRequirements;
122
155
  }
123
-
124
- private void Update()
156
+ private void ChangeQuestState(string id, QuestState state)
125
157
  {
126
- // loop through ALL quests
127
- foreach (Quest quest in questMap.Values)
128
- {
129
- // if we're now meeting the requirements, switch over to the CAN_START state
130
- if (quest.state == QuestState.REQUIREMENTS_NOT_MET && CheckRequirementsMet(quest))
131
- {
132
- ChangeQuestState(quest.questSO.id, QuestState.CAN_START);
133
- }
134
- }
158
+ Quest quest = GetQuestById(id);
159
+ quest.state = state;
160
+ GameEventsManager.instance.questEvents.QuestStateChange(quest);
135
161
  }
162
+ #endregion
136
163
 
164
+ #region main process
137
165
  private void StartQuest(string id)
138
166
  {
139
167
  Quest quest = GetQuestById(id);
@@ -143,7 +171,6 @@ namespace jeanf.questsystem
143
171
  quest.messageChannel.RaiseEvent(quest.messageToSendOnInit);
144
172
  if(isDebug) Debug.Log($"quest id:{id} started, a message was attatched to the initialization: {quest.messageToSendOnInit}");
145
173
  }
146
-
147
174
  private void UpdateProgress(Quest quest)
148
175
  {
149
176
  var progress = 0;
@@ -151,7 +178,6 @@ namespace jeanf.questsystem
151
178
  if (isDebug) Debug.Log($"[{quest.questSO.id}] progress: {progress * 100}%", this);
152
179
  questProgress.RaiseEvent(quest.questSO.id, progress);
153
180
  }
154
-
155
181
  private void FinishQuest(string id)
156
182
  {
157
183
  Quest quest = GetQuestById(id);
@@ -163,58 +189,26 @@ namespace jeanf.questsystem
163
189
  SaveQuest(quest);
164
190
  if (!quest.sendMessageOnFinish) return;
165
191
  }
192
+ #endregion
166
193
 
194
+ #region rewards and progress
167
195
  private void ClaimRewards(Quest quest)
168
196
  {
169
197
  GameEventsManager.instance.scenarioEvents.ScenarioUnlocked(quest.questSO.unlockedScenario);
170
198
  }
171
199
 
172
- private Dictionary<string, Quest> CreateQuestMap()
173
- {
174
- // loads all QuestInfoSO Scriptable Objects under the Assets/Resources/Quests folder
175
- QuestSO[] allQuests = Resources.LoadAll<QuestSO>("Quests");
176
- // Create the quest map
177
- Dictionary<string, Quest> questMap = new Dictionary<string, Quest>();
178
- foreach (QuestSO questSO in allQuests)
179
- {
180
- var id = questSO.id;
181
- if (questMap.ContainsKey(id))
182
- {
183
- Debug.LogWarning("Duplicate ID found when creating quest map: " + questSO.id);
184
- }
185
- else
186
- {
187
- questMap.Add(id, LoadQuest(questSO));
188
- }
189
- if(isDebug) Debug.Log($"Adding {questSO.name} to the questmap, its id is: {questSO.id}");
190
- }
191
-
192
- return questMap;
193
- }
194
-
195
- public Quest GetQuestById(string id)
196
- {
197
- Quest quest = questMap[id];
198
- if (quest == null)
199
- {
200
- Debug.LogError("ID not found in the Quest Map: " + id);
201
- }
202
-
203
- return quest;
204
- }
205
-
206
- private void OnApplicationQuit()
200
+ private void PlayerLevelChange(int level)
207
201
  {
208
- foreach (Quest quest in questMap.Values)
209
- {
210
- SaveQuest(quest);
211
- }
202
+ currentPlayerLevel = level;
212
203
  }
204
+ #endregion
213
205
 
206
+ #region saving and loading
214
207
  private void SaveQuest(Quest quest)
215
208
  {
216
209
  try
217
210
  {
211
+ //Save; active steps + quest step status for each, completed steps, quest status, progress/playerLevel/?
218
212
  QuestData questData = null;
219
213
  //quest.GetQuestData();
220
214
  // serialize using JsonUtility, but use whatever you want here (like JSON.NET)
@@ -230,7 +224,6 @@ namespace jeanf.questsystem
230
224
  Debug.LogError("Failed to save quest with id " + quest.questSO.id + ": " + e);
231
225
  }
232
226
  }
233
-
234
227
  private Quest LoadQuest(QuestSO questSO)
235
228
  {
236
229
  Debug.Log($"attempting to load quest with id: [{questSO.id}]");
@@ -259,6 +252,9 @@ namespace jeanf.questsystem
259
252
 
260
253
  return quest;
261
254
  }
255
+ #endregion
256
+
257
+ #region Validation Tools
262
258
  private void ValidityCheck()
263
259
  {
264
260
  const string searching = "attempting to find";
@@ -334,5 +330,7 @@ namespace jeanf.questsystem
334
330
  ValidityCheck();
335
331
  #endif
336
332
  }
333
+ #endregion
334
+ #endregion
337
335
  }
338
336
  }
@@ -1,3 +1,4 @@
1
+ using System;
1
2
  using jeanf.EventSystem;
2
3
  using jeanf.propertyDrawer;
3
4
  using UnityEngine;
@@ -5,21 +6,24 @@ using UnityEngine.Playables;
5
6
  using System.Collections.Generic;
6
7
  using GraphProcessor;
7
8
  using jeanf.validationTools;
9
+ using UnityEditor;
8
10
 
9
11
  namespace jeanf.questsystem
10
12
  {
11
13
  [System.Serializable, NodeMenuItem("questSystem/QuestStep"), DefaultExecutionOrder(1)]
12
14
  public class QuestStep : MonoBehaviour, IDebugBehaviour
13
15
  {
16
+ #region Ids and status
14
17
  [field: Space(10)][field: ReadOnly][SerializeField] string stepId;
15
18
  public string StepId { get { return stepId; } }
16
19
 
17
20
  string questId;
18
21
  public string QuestId { get { return questId; } }
22
+ [field: ReadOnly][SerializeField] public QuestStepStatus stepStatus;
23
+ #endregion
19
24
 
20
-
21
- [field: ReadOnly] [SerializeField] public QuestStepStatus stepStatus;
22
25
 
26
+ #region timeline
23
27
  [Tooltip("This boolean has to be enabled if the quest step has an intro timeline.")]
24
28
  public bool isUsingIntroTimeline = false;
25
29
 
@@ -27,7 +31,9 @@ namespace jeanf.questsystem
27
31
  [SerializeField] private TimelineTriggerEventChannelSO _timelineTriggerEventChannelSo;
28
32
  [DrawIf("isUsingIntroTimeline", true, ComparisonType.Equals, DisablingType.DontDraw)]
29
33
  public PlayableAsset timeline;
34
+ #endregion
30
35
 
36
+ #region step trigger and completion
31
37
  [Header("Quest Step Progression events & Variables")]
32
38
  public List<QuestStep> questStepsToTrigger = new List<QuestStep>();
33
39
  public delegate void SendNextStepId(string id);
@@ -39,22 +45,42 @@ namespace jeanf.questsystem
39
45
  public static StepActive stepActive;
40
46
  public delegate void ChildStep(QuestStep step);
41
47
  public static ChildStep childStep;
42
-
48
+ #endregion
49
+
50
+ #region events
43
51
  [Header("Quest Tooltip")]
44
52
  [SerializeField] private QuestTooltipSO questTooltipSO;
45
53
 
46
54
  [Header("Event Channels")]
47
55
  [SerializeField] private StringEventChannelSO sendQuestStepTooltip;
56
+ [SerializeField] private StringEventChannelSO stepValidationOverride;
57
+ #endregion
48
58
 
59
+ #region standard unity methods
60
+ public void OnEnable()
61
+ {
62
+ Subscribe();
63
+ InitializeQuestStep();
64
+ }
49
65
 
66
+ public void OnDisable() => Unsubscribe();
50
67
 
68
+ public void OnDestroy() => Unsubscribe();
51
69
 
52
- public void OnEnable()
70
+ private void Subscribe()
53
71
  {
54
- InitializeQuestStep();
72
+ QuestItem.ValidateStepEvent += ValidateCurrentStep;
73
+ if(stepValidationOverride) stepValidationOverride.OnEventRaised += ValidateCurrentStep;
55
74
  }
56
75
 
76
+ protected virtual void Unsubscribe()
77
+ {
78
+ QuestItem.ValidateStepEvent -= ValidateCurrentStep;
79
+ if(stepValidationOverride) stepValidationOverride.OnEventRaised -= ValidateCurrentStep;
80
+ }
81
+ #endregion
57
82
 
83
+ #region step progress
58
84
  public void InitializeQuestStep()
59
85
  {
60
86
  // failsafe to avoid lauching the same step more than once at a time.
@@ -74,6 +100,7 @@ namespace jeanf.questsystem
74
100
  {
75
101
  if(isDebug) Debug.Log($"sending trigger to timeline: {timeline.name}, triggerValue: true");
76
102
  _timelineTriggerEventChannelSo.RaiseEvent(timeline, true);
103
+
77
104
  }
78
105
 
79
106
  if(isDebug) Debug.Log($"Step with id [{stepId}] has {questStepsToTrigger.Count} childSteps");
@@ -84,9 +111,13 @@ namespace jeanf.questsystem
84
111
  }
85
112
  }
86
113
 
114
+ public void ValidateCurrentStep(string stepId)
115
+ {
116
+ if(stepId != this.stepId)return;
117
+ FinishQuestStep();
118
+ }
87
119
 
88
-
89
- protected void FinishQuestStep()
120
+ public void FinishQuestStep()
90
121
  {
91
122
  if(isDebug) Debug.Log($" ---- Step with id: {stepId} finished. Changing status to completed", this);
92
123
  stepStatus = QuestStepStatus.Completed;
@@ -96,23 +127,28 @@ namespace jeanf.questsystem
96
127
  if(isDebug) Debug.Log($" ---- Step with id: {stepId} finished. Sending tooltip", this);
97
128
  sendQuestStepTooltip.RaiseEvent(string.Empty);
98
129
  }
99
- ;
100
130
 
101
- foreach(QuestStep questStep in questStepsToTrigger)
102
- {
103
- if(isDebug) Debug.Log($" ---- Step with id: {stepId} finished. Requesting to start next step: {questStep.stepId}", this);
104
- sendNextStepId?.Invoke(questStep.stepId);
105
- }
131
+
106
132
  if(isDebug) Debug.Log($" ---- Step with id: {stepId} finished. Sending stepCompleted Event (delegate) with argument: {stepId}", this);
107
133
  stepCompleted?.Invoke(stepId);
108
- if(isDebug) Debug.Log($" ---- Step with id: {stepId} finished. Sending stepActive Event (delegate) with arguments: {stepId}, {stepStatus} ", this);
134
+ if (isDebug) Debug.Log($" ---- Step with id: {stepId} finished. Sending stepActive Event (delegate) with arguments: {stepId}, {stepStatus} ", this);
109
135
  stepActive?.Invoke(stepId, stepStatus);
110
136
 
137
+ foreach (QuestStep questStep in questStepsToTrigger)
138
+ {
139
+ if (isDebug) Debug.Log($" ---- Step with id: {stepId} finished. Requesting to start next step: {questStep.stepId}", this);
140
+
141
+ //Si questStep.prerequisitesStep are in QuestItem.stepsCompleted
142
+ sendNextStepId?.Invoke(questStep.stepId);
143
+ }
144
+
145
+
111
146
  if(isDebug) Debug.Log($" ---- Step with id: {stepId} finished. Destroying the gameobject with name {this.name}", this);
112
147
  Destroy(this.gameObject);
113
148
  }
149
+ #endregion
114
150
 
115
-
151
+ #region tooltip
116
152
  protected void DisplayActiveQuestStep()
117
153
  {
118
154
  if (questTooltipSO != null)
@@ -120,8 +156,10 @@ namespace jeanf.questsystem
120
156
  sendQuestStepTooltip.RaiseEvent(questTooltipSO.Tooltip);
121
157
  }
122
158
  }
159
+ #endregion
123
160
 
124
- #if UNITY_EDITOR
161
+ #region validation
162
+ #if UNITY_EDITOR
125
163
  private void OnValidate()
126
164
  {
127
165
  if (stepId == string.Empty || stepId == null) GenerateId();
@@ -133,16 +171,20 @@ namespace jeanf.questsystem
133
171
  UnityEditor.EditorUtility.SetDirty(this);
134
172
  }
135
173
 
136
- #endif
137
-
174
+ #endif
175
+ #endregion
138
176
 
177
+ #region debug
139
178
  public bool isDebug { get => _isDebug; set => _isDebug = value; }
140
179
  private bool _isDebug = true;
180
+ #endregion
141
181
 
182
+ #region Status
142
183
  public QuestStepStatus GetStatus()
143
184
  {
144
185
  return stepStatus;
145
186
  }
187
+ #endregion
146
188
  }
147
189
 
148
190
  public enum QuestStepStatus
package/package.json CHANGED
@@ -1,22 +1,20 @@
1
1
  {
2
- "name":"fr.jeanf.questsystem",
3
- "version":"0.0.60",
4
- "displayName":"Quest system",
5
- "description":"This package uses Scriptable Objects to define quests.",
2
+ "name": "fr.jeanf.questsystem",
3
+ "version": "0.0.62",
4
+ "displayName": "Quest system",
5
+ "description": "This package uses Scriptable Objects to define quests.",
6
6
  "unity": "2021.3",
7
7
  "keywords": [
8
8
  "jeanf",
9
9
  "quest system"
10
10
  ],
11
- "author":{
12
- "name":"Jean-François Robin",
13
- "email":"robin.jeanfrancois@gmail.com",
14
- "url":"https://jeanfrancoisrobin.art"
11
+ "author": {
12
+ "name": "Jean-François Robin",
13
+ "email": "robin.jeanfrancois@gmail.com",
14
+ "url": "https://jeanfrancoisrobin.art"
15
15
  },
16
16
  "dependencies": {
17
17
  "fr.jeanf.propertydrawer": "1.1.6"
18
18
  },
19
- "samples": [
20
-
21
- ]
22
- }
19
+ "samples": []
20
+ }