fr.jeanf.questsystem 0.1.8 β 1.0.0
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.
- package/.github/workflows/publish.yml +14 -12
- package/Runtime/Scripts/Core/QuestCatalogue.cs +63 -0
- package/Runtime/Scripts/Core/QuestCatalogue.cs.meta +3 -0
- package/Runtime/Scripts/Core/QuestItem.cs +43 -22
- package/Runtime/Scripts/Core/QuestManager.cs +172 -49
- package/Runtime/Scripts/Core/QuestStep.cs +11 -11
- package/Runtime/Scripts/Events/QuestEvents.cs +10 -10
- package/Runtime/Scripts/jeanf.QuestSystem.asmdef +3 -1
- package/package.json +5 -1
|
@@ -3,21 +3,23 @@ name: "π publish"
|
|
|
3
3
|
on:
|
|
4
4
|
push:
|
|
5
5
|
branches:
|
|
6
|
-
|
|
6
|
+
- main
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
id-token: write # Required for OIDC
|
|
10
|
+
contents: read
|
|
7
11
|
|
|
8
12
|
jobs:
|
|
9
13
|
release:
|
|
10
14
|
name: π publish
|
|
11
15
|
runs-on: ubuntu-latest
|
|
12
16
|
steps:
|
|
13
|
-
-
|
|
14
|
-
|
|
15
|
-
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
-
|
|
21
|
-
|
|
22
|
-
env:
|
|
23
|
-
NODE_AUTH_TOKEN: ${{secrets.NPM_AUTH_TOKEN}}
|
|
17
|
+
- name: π checkout
|
|
18
|
+
uses: actions/checkout@v6
|
|
19
|
+
- name: π’ node
|
|
20
|
+
uses: actions/setup-node@v6
|
|
21
|
+
with:
|
|
22
|
+
node-version: 24
|
|
23
|
+
registry-url: https://registry.npmjs.org
|
|
24
|
+
- name: π publish
|
|
25
|
+
run: npm publish --access public
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using UnityEngine;
|
|
3
|
+
|
|
4
|
+
namespace jeanf.questsystem
|
|
5
|
+
{
|
|
6
|
+
/// <summary>
|
|
7
|
+
/// Tracks when <see cref="QuestManager"/> has finished loading addressable quest definitions.
|
|
8
|
+
/// Consumers should await <see cref="WhenReadyAsync"/> before driving quest lifecycle (start/finish/init).
|
|
9
|
+
/// </summary>
|
|
10
|
+
public static class QuestCatalogue
|
|
11
|
+
{
|
|
12
|
+
public static bool IsReady { get; private set; }
|
|
13
|
+
public static bool HasFailed { get; private set; }
|
|
14
|
+
public static Exception LoadFailure { get; private set; }
|
|
15
|
+
|
|
16
|
+
public static event Action Ready;
|
|
17
|
+
public static event Action<Exception> Failed;
|
|
18
|
+
|
|
19
|
+
public static async Awaitable WhenReadyAsync()
|
|
20
|
+
{
|
|
21
|
+
while (!IsReady && !HasFailed)
|
|
22
|
+
await Awaitable.NextFrameAsync();
|
|
23
|
+
|
|
24
|
+
if (HasFailed)
|
|
25
|
+
throw new InvalidOperationException(
|
|
26
|
+
"Quest catalog failed to load addressable quests.",
|
|
27
|
+
LoadFailure);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
internal static void BeginLoad()
|
|
31
|
+
{
|
|
32
|
+
IsReady = false;
|
|
33
|
+
HasFailed = false;
|
|
34
|
+
LoadFailure = null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
internal static void MarkReady()
|
|
38
|
+
{
|
|
39
|
+
if (IsReady)
|
|
40
|
+
return;
|
|
41
|
+
|
|
42
|
+
IsReady = true;
|
|
43
|
+
Ready?.Invoke();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
internal static void MarkFailed(Exception exception)
|
|
47
|
+
{
|
|
48
|
+
if (HasFailed)
|
|
49
|
+
return;
|
|
50
|
+
|
|
51
|
+
HasFailed = true;
|
|
52
|
+
LoadFailure = exception;
|
|
53
|
+
Failed?.Invoke(exception);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
internal static void Reset()
|
|
57
|
+
{
|
|
58
|
+
IsReady = false;
|
|
59
|
+
HasFailed = false;
|
|
60
|
+
LoadFailure = null;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -41,6 +41,7 @@ namespace jeanf.questsystem
|
|
|
41
41
|
[ReadOnly]
|
|
42
42
|
private bool clearToStart = false;
|
|
43
43
|
private string questId;
|
|
44
|
+
private int _initRequestVersion;
|
|
44
45
|
private QuestState currentQuestState;
|
|
45
46
|
[ReadOnly]
|
|
46
47
|
[Range(0, 1)]
|
|
@@ -75,7 +76,7 @@ namespace jeanf.questsystem
|
|
|
75
76
|
questId = questSO.id;
|
|
76
77
|
for (int i = 0; i < questSO.rootSteps.Length; i++)
|
|
77
78
|
{
|
|
78
|
-
if (isDebug) Debug.Log($"id on awake {questSO.rootSteps[i].StepId}, added to {this.name}'s dictionary", this);
|
|
79
|
+
//if (isDebug) Debug.Log($"id on awake {questSO.rootSteps[i].StepId}, added to {this.name}'s dictionary", this);
|
|
79
80
|
AddStepToStepMap(questSO.rootSteps[i]);
|
|
80
81
|
rootSteps.Add(questSO.rootSteps[i]);
|
|
81
82
|
}
|
|
@@ -87,15 +88,14 @@ namespace jeanf.questsystem
|
|
|
87
88
|
private void OnEnable()
|
|
88
89
|
{
|
|
89
90
|
Subscribe();
|
|
90
|
-
|
|
91
|
-
Init(questId);
|
|
91
|
+
RunInitWhenCatalogueReady(questId);
|
|
92
92
|
}
|
|
93
93
|
private void OnDisable() => Unsubscribe();
|
|
94
94
|
private void OnDestroy() => Unsubscribe();
|
|
95
95
|
private void Subscribe()
|
|
96
96
|
{
|
|
97
97
|
resetChannel.OnEventRaised += Reset;
|
|
98
|
-
QuestInitialCheck.OnEventRaised +=
|
|
98
|
+
QuestInitialCheck.OnEventRaised += OnQuestInitialCheck;
|
|
99
99
|
QuestProgress.OnEventRaised += UpdateProgress;
|
|
100
100
|
GameEventsManager.instance.questEvents.onQuestStateChange += QuestStateChange;
|
|
101
101
|
GameEventsManager.instance.inputEvents.onSubmitPressed += UpdateState;
|
|
@@ -108,7 +108,7 @@ namespace jeanf.questsystem
|
|
|
108
108
|
private void Unsubscribe()
|
|
109
109
|
{
|
|
110
110
|
resetChannel.OnEventRaised -= Reset;
|
|
111
|
-
QuestInitialCheck.OnEventRaised -=
|
|
111
|
+
QuestInitialCheck.OnEventRaised -= OnQuestInitialCheck;
|
|
112
112
|
QuestProgress.OnEventRaised -= UpdateProgress;
|
|
113
113
|
GameEventsManager.instance.questEvents.onQuestStateChange -= QuestStateChange;
|
|
114
114
|
GameEventsManager.instance.inputEvents.onSubmitPressed -= UpdateState;
|
|
@@ -155,21 +155,42 @@ namespace jeanf.questsystem
|
|
|
155
155
|
}
|
|
156
156
|
private void AddStepToStepMap(QuestStep step)
|
|
157
157
|
{
|
|
158
|
-
if (isDebug) Debug.Log($"--- Received request to add step {step.name} with id: {step.StepId} to stepMap.");
|
|
158
|
+
//if (isDebug) Debug.Log($"--- Received request to add step {step.name} with id: {step.StepId} to stepMap.");
|
|
159
159
|
if (!stepMap.ContainsKey(step.StepId))
|
|
160
160
|
{
|
|
161
|
-
if (isDebug) Debug.Log($"--- Step [{step.StepId}] not found in stepMap, adding it.");
|
|
161
|
+
//if (isDebug) Debug.Log($"--- Step [{step.StepId}] not found in stepMap, adding it.");
|
|
162
162
|
stepMap.Add(step.StepId, step);
|
|
163
163
|
}
|
|
164
164
|
if (completedSteps.ContainsKey(step.StepId))
|
|
165
165
|
{
|
|
166
|
-
if (isDebug) Debug.Log($"--- Step [{step.StepId}] already completed removing it from completeSteps so that we can go through it again.");
|
|
166
|
+
//if (isDebug) Debug.Log($"--- Step [{step.StepId}] already completed removing it from completeSteps so that we can go through it again.");
|
|
167
167
|
completedSteps.Remove(step.StepId);
|
|
168
168
|
}
|
|
169
169
|
}
|
|
170
170
|
#endregion
|
|
171
171
|
|
|
172
172
|
#region quest process
|
|
173
|
+
private void OnQuestInitialCheck(string id) => RunInitWhenCatalogueReady(id);
|
|
174
|
+
|
|
175
|
+
private async void RunInitWhenCatalogueReady(string id)
|
|
176
|
+
{
|
|
177
|
+
var requestVersion = ++_initRequestVersion;
|
|
178
|
+
try
|
|
179
|
+
{
|
|
180
|
+
await QuestCatalogue.WhenReadyAsync();
|
|
181
|
+
}
|
|
182
|
+
catch (InvalidOperationException e)
|
|
183
|
+
{
|
|
184
|
+
Debug.LogError($"[QuestItem] Cannot initialize quest '{id}': {e.Message}", this);
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if (requestVersion != _initRequestVersion || !isActiveAndEnabled)
|
|
189
|
+
return;
|
|
190
|
+
|
|
191
|
+
Init(id);
|
|
192
|
+
}
|
|
193
|
+
|
|
173
194
|
private void Init(string id)
|
|
174
195
|
{
|
|
175
196
|
if (transform.childCount > 0)
|
|
@@ -185,7 +206,7 @@ namespace jeanf.questsystem
|
|
|
185
206
|
completedSteps.Clear();
|
|
186
207
|
completedSteps.TrimExcess();
|
|
187
208
|
|
|
188
|
-
if (isDebug) Debug.Log($"Quest [{id}]: _startQuestOnEnable value is: [{_startQuestOnEnable}]");
|
|
209
|
+
//if (isDebug) Debug.Log($"Quest [{id}]: _startQuestOnEnable value is: [{_startQuestOnEnable}]");
|
|
189
210
|
if (!_startQuestOnEnable || id != questId) return;
|
|
190
211
|
clearToStart = true;
|
|
191
212
|
currentQuestState = QuestState.CAN_START;
|
|
@@ -221,28 +242,28 @@ namespace jeanf.questsystem
|
|
|
221
242
|
}
|
|
222
243
|
private void UpdateState()
|
|
223
244
|
{
|
|
224
|
-
if (isDebug) Debug.Log($"Updating State...");
|
|
245
|
+
//if (isDebug) Debug.Log($"Updating State...");
|
|
225
246
|
if (!clearToStart) return;
|
|
226
|
-
if (isDebug) Debug.Log($"All is clear, continuing ...");
|
|
247
|
+
//if (isDebug) Debug.Log($"All is clear, continuing ...");
|
|
227
248
|
|
|
228
249
|
switch (currentQuestState)
|
|
229
250
|
{
|
|
230
251
|
case QuestState.CAN_START:
|
|
231
252
|
{
|
|
232
|
-
if (isDebug) Debug.Log($"Starting quest: {questId}");
|
|
253
|
+
//if (isDebug) Debug.Log($"Starting quest: {questId}");
|
|
233
254
|
GameEventsManager.instance.questEvents.StartQuest(questId);
|
|
234
255
|
break;
|
|
235
256
|
}
|
|
236
257
|
case QuestState.CAN_FINISH:
|
|
237
258
|
{
|
|
238
|
-
if (isDebug) Debug.Log($"Finishing quest: {questId}");
|
|
259
|
+
//if (isDebug) Debug.Log($"Finishing quest: {questId}");
|
|
239
260
|
GameEventsManager.instance.questEvents.FinishQuest(questId);
|
|
240
261
|
break;
|
|
241
262
|
}
|
|
242
263
|
case QuestState.REQUIREMENTS_NOT_MET:
|
|
243
264
|
if (_startQuestOnEnable)
|
|
244
265
|
{
|
|
245
|
-
if (isDebug) Debug.Log($"forcing start of quest: {questId}");
|
|
266
|
+
//if (isDebug) Debug.Log($"forcing start of quest: {questId}");
|
|
246
267
|
GameEventsManager.instance.questEvents.StartQuest(questId);
|
|
247
268
|
}
|
|
248
269
|
break;
|
|
@@ -258,7 +279,7 @@ namespace jeanf.questsystem
|
|
|
258
279
|
{
|
|
259
280
|
if (id != questId) return;
|
|
260
281
|
this.progress = progress;
|
|
261
|
-
if (isDebug) Debug.Log($"questid [{id}] progress = {progress * 100}%");
|
|
282
|
+
//if (isDebug) Debug.Log($"questid [{id}] progress = {progress * 100}%");
|
|
262
283
|
}
|
|
263
284
|
private void QuestStateChange(Quest quest)
|
|
264
285
|
{
|
|
@@ -294,10 +315,10 @@ namespace jeanf.questsystem
|
|
|
294
315
|
}
|
|
295
316
|
public void LogActiveSteps()
|
|
296
317
|
{
|
|
297
|
-
Debug.Log($"There is {activeSteps.Count} active steps at the moment.");
|
|
318
|
+
//Debug.Log($"There is {activeSteps.Count} active steps at the moment.");
|
|
298
319
|
foreach (var step in activeSteps.Keys)
|
|
299
320
|
{
|
|
300
|
-
Debug.Log($"active step: {step}");
|
|
321
|
+
//Debug.Log($"active step: {step}");
|
|
301
322
|
}
|
|
302
323
|
}
|
|
303
324
|
#endif
|
|
@@ -316,7 +337,7 @@ namespace jeanf.questsystem
|
|
|
316
337
|
|
|
317
338
|
if (QuestInitialCheck == null)
|
|
318
339
|
{
|
|
319
|
-
if (isDebug) Debug.Log($"{searching} {_}/QuestInitialCheck in {searchLocation} ", this);
|
|
340
|
+
//if (isDebug) Debug.Log($"{searching} {_}/QuestInitialCheck in {searchLocation} ", this);
|
|
320
341
|
QuestInitialCheck = Resources.Load<StringEventChannelSO>($"{_}/QuestInitialCheck");
|
|
321
342
|
if (QuestInitialCheck == null)
|
|
322
343
|
{
|
|
@@ -329,7 +350,7 @@ namespace jeanf.questsystem
|
|
|
329
350
|
|
|
330
351
|
if (questSO == null)
|
|
331
352
|
{
|
|
332
|
-
if (isDebug) Debug.Log($"There is no questSO in the questItem");
|
|
353
|
+
//if (isDebug) Debug.Log($"There is no questSO in the questItem");
|
|
333
354
|
validityCheck = false;
|
|
334
355
|
invalidObjects.Add(questSO);
|
|
335
356
|
}
|
|
@@ -337,7 +358,7 @@ namespace jeanf.questsystem
|
|
|
337
358
|
|
|
338
359
|
if (QuestProgress == null)
|
|
339
360
|
{
|
|
340
|
-
if (isDebug) Debug.Log($"{searching} {_}/QuestsProgressChannel in {searchLocation} ", this);
|
|
361
|
+
//if (isDebug) Debug.Log($"{searching} {_}/QuestsProgressChannel in {searchLocation} ", this);
|
|
341
362
|
QuestProgress = Resources.Load<StringFloatEventChannelSO>($"{_}/QuestsProgressChannel");
|
|
342
363
|
if (QuestProgress == null)
|
|
343
364
|
{
|
|
@@ -350,7 +371,7 @@ namespace jeanf.questsystem
|
|
|
350
371
|
|
|
351
372
|
if (loadRequiredScenesEventChannel == null)
|
|
352
373
|
{
|
|
353
|
-
if (isDebug) Debug.Log($"{searching} {_}/loadRequiredScenesEventChannel in {searchLocation} ", this);
|
|
374
|
+
//if (isDebug) Debug.Log($"{searching} {_}/loadRequiredScenesEventChannel in {searchLocation} ", this);
|
|
354
375
|
loadRequiredScenesEventChannel = Resources.Load<StringListEventChannelSO>($"{_}/LoadRequiredScenesEventChannel");
|
|
355
376
|
if (loadRequiredScenesEventChannel == null)
|
|
356
377
|
{
|
|
@@ -363,7 +384,7 @@ namespace jeanf.questsystem
|
|
|
363
384
|
|
|
364
385
|
if (requirementCheck == null)
|
|
365
386
|
{
|
|
366
|
-
if (isDebug) Debug.Log($"{searching} {_}/QuestRequirementCheck in {searchLocation}", this);
|
|
387
|
+
//if (isDebug) Debug.Log($"{searching} {_}/QuestRequirementCheck in {searchLocation}", this);
|
|
367
388
|
requirementCheck = Resources.Load<StringEventChannelSO>($"{_}/QuestRequirementCheck");
|
|
368
389
|
if (requirementCheck == null)
|
|
369
390
|
{
|
|
@@ -4,6 +4,8 @@ using System.Collections.Generic;
|
|
|
4
4
|
using jeanf.EventSystem;
|
|
5
5
|
using jeanf.validationTools;
|
|
6
6
|
using UnityEngine;
|
|
7
|
+
using UnityEngine.AddressableAssets;
|
|
8
|
+
using UnityEngine.ResourceManagement.AsyncOperations;
|
|
7
9
|
using UnityEngine.Serialization;
|
|
8
10
|
|
|
9
11
|
namespace jeanf.questsystem
|
|
@@ -34,28 +36,29 @@ namespace jeanf.questsystem
|
|
|
34
36
|
[FormerlySerializedAs("loadQuestState")] [Header("Config")] [SerializeField]
|
|
35
37
|
private bool loadSavedQuestState = true;
|
|
36
38
|
private Dictionary<string, Quest> questMap;
|
|
39
|
+
private readonly Queue<string> _pendingStartQuestIds = new Queue<string>();
|
|
40
|
+
private readonly Queue<string> _pendingFinishQuestIds = new Queue<string>();
|
|
37
41
|
private int currentPlayerLevel;
|
|
42
|
+
|
|
43
|
+
// Label strings to load for scriptable objects
|
|
44
|
+
[Header("Addressables group to load:")]
|
|
45
|
+
[Tooltip("This group should contain all the scriptable objects that define your quests.")]
|
|
46
|
+
public List<string> _keys = new List<string>() { "Quests" };
|
|
47
|
+
private AsyncOperationHandle<IList<QuestSO>> _questAssetsHandle;
|
|
48
|
+
|
|
38
49
|
#endregion
|
|
39
50
|
#endregion
|
|
40
51
|
|
|
41
52
|
#region Methods
|
|
42
53
|
#region Standard Unity Methods
|
|
43
|
-
|
|
44
|
-
{
|
|
45
|
-
questMap = CreateQuestMap();
|
|
46
|
-
|
|
47
|
-
foreach (var quest in questMap)
|
|
48
|
-
{
|
|
49
|
-
CheckIfQuestIsAlreadyLoaded(quest.Key);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
54
|
+
|
|
52
55
|
private void OnEnable()
|
|
53
56
|
{
|
|
54
57
|
GameEventsManager.instance.questEvents.onStartQuest += StartQuest;
|
|
55
58
|
GameEventsManager.instance.questEvents.onFinishQuest += FinishQuest;
|
|
56
|
-
//GameEventsManager.instance.questEvents.onQuestStepStateChange += QuestStepStateChange;
|
|
57
59
|
GameEventsManager.instance.playerEvents.onPlayerLevelChange += PlayerLevelChange;
|
|
58
|
-
questStatusUpdateRequested.OnEventRaised +=
|
|
60
|
+
questStatusUpdateRequested.OnEventRaised += OnQuestStatusUpdateRequested;
|
|
61
|
+
//GameEventsManager.instance.questEvents.onQuestStepStateChange += QuestStepStateChange;
|
|
59
62
|
}
|
|
60
63
|
private void OnDisable() => Unsubscribe();
|
|
61
64
|
private void OnDestroy() => Unsubscribe();
|
|
@@ -63,22 +66,50 @@ namespace jeanf.questsystem
|
|
|
63
66
|
{
|
|
64
67
|
GameEventsManager.instance.questEvents.onStartQuest -= StartQuest;
|
|
65
68
|
GameEventsManager.instance.questEvents.onFinishQuest -= FinishQuest;
|
|
66
|
-
|
|
67
|
-
//GameEventsManager.instance.questEvents.onQuestStepStateChange -= QuestStepStateChange;
|
|
68
|
-
|
|
69
69
|
GameEventsManager.instance.playerEvents.onPlayerLevelChange -= PlayerLevelChange;
|
|
70
|
+
questStatusUpdateRequested.OnEventRaised -= OnQuestStatusUpdateRequested;
|
|
71
|
+
if (_questAssetsHandle.IsValid())
|
|
72
|
+
Addressables.Release(_questAssetsHandle);
|
|
73
|
+
QuestCatalogue.Reset();
|
|
74
|
+
_pendingStartQuestIds.Clear();
|
|
75
|
+
_pendingFinishQuestIds.Clear();
|
|
76
|
+
//GameEventsManager.instance.questEvents.onQuestStepStateChange -= QuestStepStateChange;
|
|
77
|
+
}
|
|
70
78
|
|
|
79
|
+
private void OnQuestStatusUpdateRequested(string questId)
|
|
80
|
+
{
|
|
81
|
+
if (questMap == null || !questMap.TryGetValue(questId, out var quest))
|
|
82
|
+
return;
|
|
83
|
+
CheckRequirementsMet(quest);
|
|
71
84
|
}
|
|
72
|
-
|
|
85
|
+
|
|
86
|
+
private async Awaitable Start()
|
|
73
87
|
{
|
|
74
|
-
|
|
88
|
+
QuestCatalogue.BeginLoad();
|
|
89
|
+
try
|
|
75
90
|
{
|
|
76
|
-
|
|
77
|
-
|
|
91
|
+
questMap = await CreateQuestMap();
|
|
92
|
+
QuestCatalogue.MarkReady();
|
|
93
|
+
FlushPendingQuestOperations();
|
|
94
|
+
|
|
95
|
+
foreach (var quest in questMap)
|
|
96
|
+
{
|
|
97
|
+
CheckIfQuestIsAlreadyLoaded(quest.Key);
|
|
98
|
+
GameEventsManager.instance.questEvents.QuestStateChange(quest.Value);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
catch (Exception e)
|
|
102
|
+
{
|
|
103
|
+
QuestCatalogue.MarkFailed(e);
|
|
104
|
+
Debug.LogError($"[QuestManager] Error loading quest catalogue: {e.Message}");
|
|
78
105
|
}
|
|
79
106
|
}
|
|
107
|
+
|
|
80
108
|
private void Update()
|
|
81
109
|
{
|
|
110
|
+
if (!QuestCatalogue.IsReady || questMap == null)
|
|
111
|
+
return;
|
|
112
|
+
|
|
82
113
|
// loop through ALL quests
|
|
83
114
|
foreach (Quest quest in questMap.Values)
|
|
84
115
|
{
|
|
@@ -91,6 +122,8 @@ namespace jeanf.questsystem
|
|
|
91
122
|
}
|
|
92
123
|
private void OnApplicationQuit()
|
|
93
124
|
{
|
|
125
|
+
if (questMap == null)
|
|
126
|
+
return;
|
|
94
127
|
foreach (Quest quest in questMap.Values)
|
|
95
128
|
{
|
|
96
129
|
SaveQuest(quest);
|
|
@@ -99,10 +132,47 @@ namespace jeanf.questsystem
|
|
|
99
132
|
#endregion
|
|
100
133
|
|
|
101
134
|
#region Quest Checks and getters
|
|
102
|
-
|
|
135
|
+
|
|
136
|
+
private static async Awaitable AwaitAsyncOperation<T>(AsyncOperationHandle<T> handle)
|
|
137
|
+
{
|
|
138
|
+
while (!handle.IsDone)
|
|
139
|
+
await Awaitable.NextFrameAsync();
|
|
140
|
+
|
|
141
|
+
if (handle.Status != AsyncOperationStatus.Succeeded)
|
|
142
|
+
throw new Exception("QuestManager failed to load Addressable assets.");
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
private async Awaitable<IList<QuestSO>> LoadQuestAssets(List<string> labels)
|
|
103
146
|
{
|
|
104
|
-
|
|
105
|
-
|
|
147
|
+
_questAssetsHandle = Addressables.LoadAssetsAsync<QuestSO>(
|
|
148
|
+
labels,
|
|
149
|
+
addressable =>
|
|
150
|
+
{
|
|
151
|
+
if (isDebug) Debug.Log($"[QuestManager] Loaded quest SO: {addressable.name}");
|
|
152
|
+
},
|
|
153
|
+
Addressables.MergeMode.Union,
|
|
154
|
+
true);
|
|
155
|
+
|
|
156
|
+
await AwaitAsyncOperation(_questAssetsHandle);
|
|
157
|
+
return _questAssetsHandle.Result;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
private async Awaitable<Dictionary<string, Quest>> CreateQuestMap()
|
|
161
|
+
{
|
|
162
|
+
// loads all QuestInfoSO Scriptable Objects under the Assets/Quests folder
|
|
163
|
+
Debug.Log("[QuestManager] Creating quest map");
|
|
164
|
+
IList<QuestSO> allQuests = new List<QuestSO>();
|
|
165
|
+
try
|
|
166
|
+
{
|
|
167
|
+
allQuests = await LoadQuestAssets(_keys);
|
|
168
|
+
if (isDebug) Debug.Log($"[QuestManager] Successfully loaded {allQuests.Count} assets!");
|
|
169
|
+
}
|
|
170
|
+
catch (Exception e)
|
|
171
|
+
{
|
|
172
|
+
Debug.LogError($"[QuestManager] Error loading assets: {e.Message}");
|
|
173
|
+
throw;
|
|
174
|
+
}
|
|
175
|
+
|
|
106
176
|
// Create the quest map
|
|
107
177
|
Dictionary<string, Quest> questMap = new Dictionary<string, Quest>();
|
|
108
178
|
foreach (QuestSO questSO in allQuests)
|
|
@@ -110,13 +180,13 @@ namespace jeanf.questsystem
|
|
|
110
180
|
var id = questSO.id;
|
|
111
181
|
if (questMap.ContainsKey(id))
|
|
112
182
|
{
|
|
113
|
-
Debug.LogWarning("Duplicate ID found when creating quest map:
|
|
183
|
+
Debug.LogWarning($"[QuestManager] Duplicate ID found when creating quest map: {questSO.id}");
|
|
114
184
|
}
|
|
115
185
|
else
|
|
116
186
|
{
|
|
117
187
|
questMap.Add(id, LoadQuest(questSO));
|
|
118
188
|
}
|
|
119
|
-
if (isDebug) Debug.Log($"Adding {questSO.name} to the questmap, its id is: {questSO.id}");
|
|
189
|
+
if (isDebug) Debug.Log($"[QuestManager] Adding {questSO.name} to the questmap, its id is: {questSO.id}");
|
|
120
190
|
}
|
|
121
191
|
return questMap;
|
|
122
192
|
}
|
|
@@ -126,14 +196,35 @@ namespace jeanf.questsystem
|
|
|
126
196
|
}
|
|
127
197
|
public Quest GetQuestById(string id)
|
|
128
198
|
{
|
|
129
|
-
|
|
130
|
-
if (quest == null)
|
|
199
|
+
if (questMap == null || !questMap.TryGetValue(id, out var quest))
|
|
131
200
|
{
|
|
132
|
-
Debug.LogError("ID not found in the
|
|
201
|
+
Debug.LogError($"[QuestManager] ID not found in the quest map: {id}");
|
|
202
|
+
return null;
|
|
133
203
|
}
|
|
134
204
|
|
|
135
205
|
return quest;
|
|
136
206
|
}
|
|
207
|
+
|
|
208
|
+
private void FlushPendingQuestOperations()
|
|
209
|
+
{
|
|
210
|
+
while (_pendingStartQuestIds.Count > 0)
|
|
211
|
+
StartQuestCore(_pendingStartQuestIds.Dequeue());
|
|
212
|
+
|
|
213
|
+
while (_pendingFinishQuestIds.Count > 0)
|
|
214
|
+
FinishQuestCore(_pendingFinishQuestIds.Dequeue());
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
private static bool EnqueueUnique(Queue<string> queue, string id)
|
|
218
|
+
{
|
|
219
|
+
foreach (var pending in queue)
|
|
220
|
+
{
|
|
221
|
+
if (pending == id)
|
|
222
|
+
return false;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
queue.Enqueue(id);
|
|
226
|
+
return true;
|
|
227
|
+
}
|
|
137
228
|
private bool CheckRequirementsMet(Quest quest)
|
|
138
229
|
{
|
|
139
230
|
// check player level requirements
|
|
@@ -142,19 +233,21 @@ namespace jeanf.questsystem
|
|
|
142
233
|
// check quest prerequisites for completion
|
|
143
234
|
foreach (QuestSO prerequisiteQuestInfo in quest.questSO.questPrerequisites)
|
|
144
235
|
{
|
|
145
|
-
|
|
146
|
-
|
|
236
|
+
var prerequisite = GetQuestById(prerequisiteQuestInfo.id);
|
|
237
|
+
if (prerequisite == null || prerequisite.state != QuestState.FINISHED)
|
|
147
238
|
meetsRequirements = false;
|
|
148
|
-
}
|
|
149
239
|
}
|
|
150
240
|
|
|
151
|
-
if (isDebug) Debug.Log($"checking requirements for quest: {quest.questSO.name}, [{quest.questSO.id}], meetsRequirements: {meetsRequirements}");
|
|
241
|
+
if (isDebug) Debug.Log($"[QuestManager] checking requirements for quest: {quest.questSO.name}, [{quest.questSO.id}], meetsRequirements: {meetsRequirements}");
|
|
152
242
|
|
|
153
243
|
return meetsRequirements;
|
|
154
244
|
}
|
|
155
245
|
private void ChangeQuestState(string id, QuestState state)
|
|
156
246
|
{
|
|
157
|
-
|
|
247
|
+
var quest = GetQuestById(id);
|
|
248
|
+
if (quest == null)
|
|
249
|
+
return;
|
|
250
|
+
|
|
158
251
|
quest.state = state;
|
|
159
252
|
GameEventsManager.instance.questEvents.QuestStateChange(quest);
|
|
160
253
|
}
|
|
@@ -163,30 +256,60 @@ namespace jeanf.questsystem
|
|
|
163
256
|
#region main process
|
|
164
257
|
private void StartQuest(string id)
|
|
165
258
|
{
|
|
166
|
-
|
|
259
|
+
if (!QuestCatalogue.IsReady || questMap == null)
|
|
260
|
+
{
|
|
261
|
+
if (EnqueueUnique(_pendingStartQuestIds, id) && isDebug)
|
|
262
|
+
Debug.Log($"[QuestManager] StartQuest deferred until catalogue is ready: {id}");
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
StartQuestCore(id);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
private void StartQuestCore(string id)
|
|
270
|
+
{
|
|
271
|
+
var quest = GetQuestById(id);
|
|
272
|
+
if (quest == null)
|
|
273
|
+
return;
|
|
274
|
+
|
|
167
275
|
ChangeQuestState(quest.questSO.id, QuestState.IN_PROGRESS);
|
|
168
276
|
SaveQuest(quest);
|
|
169
277
|
if (!quest.sendMessageOnInitialization) return;
|
|
170
278
|
quest.messageChannel.RaiseEvent(quest.messageToSendOnInit);
|
|
171
|
-
if(isDebug)
|
|
279
|
+
if (isDebug)
|
|
280
|
+
Debug.Log($"[QuestManager] quest id:{id} started, message on init: {quest.messageToSendOnInit}");
|
|
172
281
|
}
|
|
173
282
|
private void UpdateProgress(Quest quest)
|
|
174
283
|
{
|
|
175
284
|
var progress = 0;
|
|
176
|
-
if (quest.questSO.id == null) Debug.
|
|
177
|
-
if (isDebug) Debug.Log($"[{quest.questSO.id}] progress: {progress * 100}%", this);
|
|
285
|
+
if (quest.questSO.id == null) Debug.LogError("[QuestManager] quest.questSO.id is null");
|
|
286
|
+
if (isDebug) Debug.Log($"[QuestManager] [{quest.questSO.id}] progress: {progress * 100}%", this);
|
|
178
287
|
questProgress.RaiseEvent(quest.questSO.id, progress);
|
|
179
288
|
}
|
|
180
289
|
private void FinishQuest(string id)
|
|
181
290
|
{
|
|
182
|
-
|
|
291
|
+
if (!QuestCatalogue.IsReady || questMap == null)
|
|
292
|
+
{
|
|
293
|
+
if (EnqueueUnique(_pendingFinishQuestIds, id) && isDebug)
|
|
294
|
+
Debug.Log($"[QuestManager] FinishQuest deferred until catalogue is ready: {id}");
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
FinishQuestCore(id);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
private void FinishQuestCore(string id)
|
|
302
|
+
{
|
|
303
|
+
var quest = GetQuestById(id);
|
|
304
|
+
if (quest == null)
|
|
305
|
+
return;
|
|
306
|
+
|
|
183
307
|
UpdateProgress(quest);
|
|
184
308
|
ClaimRewards(quest);
|
|
185
309
|
ChangeQuestState(quest.questSO.id, QuestState.FINISHED);
|
|
186
310
|
questStatusUpdateChannel.RaiseEvent(quest.questSO.id);
|
|
187
311
|
questProgress.RaiseEvent(quest.questSO.id, 1);
|
|
188
312
|
SaveQuest(quest);
|
|
189
|
-
if (!quest.sendMessageOnFinish) return;
|
|
190
313
|
}
|
|
191
314
|
#endregion
|
|
192
315
|
|
|
@@ -212,7 +335,7 @@ namespace jeanf.questsystem
|
|
|
212
335
|
//quest.GetQuestData();
|
|
213
336
|
// serialize using JsonUtility, but use whatever you want here (like JSON.NET)
|
|
214
337
|
string serializedData = JsonUtility.ToJson(questData);
|
|
215
|
-
if(isDebug) Debug.Log($"saved data {serializedData}");
|
|
338
|
+
//if(isDebug) Debug.Log($"saved data {serializedData}");
|
|
216
339
|
// saving to PlayerPrefs is just a quick example for this tutorial video,
|
|
217
340
|
// you probably don't want to save this info there long-term.
|
|
218
341
|
// instead, use an actual Save & Load system and write to a file, the cloud, etc..
|
|
@@ -220,12 +343,12 @@ namespace jeanf.questsystem
|
|
|
220
343
|
}
|
|
221
344
|
catch (System.Exception e)
|
|
222
345
|
{
|
|
223
|
-
Debug.LogError("Failed to save quest with id " + quest.questSO.id + ": " + e);
|
|
346
|
+
//Debug.LogError("Failed to save quest with id " + quest.questSO.id + ": " + e);
|
|
224
347
|
}
|
|
225
348
|
}
|
|
226
349
|
private Quest LoadQuest(QuestSO questSO)
|
|
227
350
|
{
|
|
228
|
-
Debug.Log($"attempting to load quest with id: [{questSO.id}]");
|
|
351
|
+
if (isDebug) Debug.Log($"[QuestManager] attempting to load quest with id: [{questSO.id}]");
|
|
229
352
|
var quest = new Quest(questSO);
|
|
230
353
|
try
|
|
231
354
|
{
|
|
@@ -235,18 +358,18 @@ namespace jeanf.questsystem
|
|
|
235
358
|
var serializedData = PlayerPrefs.GetString(questSO.id);
|
|
236
359
|
var questData = JsonUtility.FromJson<QuestData>(serializedData);
|
|
237
360
|
quest = new Quest(questSO, questData.state, questData.questStepIndex, questData.questStepStates);
|
|
238
|
-
Debug.Log($"loaded previously saved quest with id: [{quest.questSO.id}]");
|
|
361
|
+
if (isDebug) Debug.Log($"[QuestManager] loaded previously saved quest with id: [{quest.questSO.id}]");
|
|
239
362
|
}
|
|
240
363
|
// otherwise, initialize a new quest
|
|
241
364
|
else
|
|
242
365
|
{
|
|
243
366
|
quest = new Quest(questSO);
|
|
244
|
-
Debug.Log($"loaded a fresh instance of quest with id: [{quest.questSO.id}]");
|
|
367
|
+
if (isDebug) Debug.Log($"[QuestManager] loaded a fresh instance of quest with id: [{quest.questSO.id}]");
|
|
245
368
|
}
|
|
246
369
|
}
|
|
247
|
-
catch (
|
|
370
|
+
catch (Exception e)
|
|
248
371
|
{
|
|
249
|
-
Debug.LogError($"Failed to load quest with id: [{quest.questSO.id}] - exception: {e}");
|
|
372
|
+
Debug.LogError($"[QuestManager] Failed to load quest with id: [{quest.questSO.id}] - exception: {e}");
|
|
250
373
|
}
|
|
251
374
|
|
|
252
375
|
return quest;
|
|
@@ -268,7 +391,7 @@ namespace jeanf.questsystem
|
|
|
268
391
|
|
|
269
392
|
if (QuestInitialCheck == null)
|
|
270
393
|
{
|
|
271
|
-
if (isDebug) Debug.Log($"{searching} {_}/QuestInitialCheck in {searchLocation}", this);
|
|
394
|
+
if (isDebug) Debug.Log($"[QuestManager] {searching} {_}/QuestInitialCheck in {searchLocation}", this);
|
|
272
395
|
QuestInitialCheck = Resources.Load<StringEventChannelSO>($"{_}/QuestInitialCheck");
|
|
273
396
|
if (QuestInitialCheck == null)
|
|
274
397
|
{
|
|
@@ -280,7 +403,7 @@ namespace jeanf.questsystem
|
|
|
280
403
|
|
|
281
404
|
if (questStatusUpdateChannel == null)
|
|
282
405
|
{
|
|
283
|
-
if (isDebug) Debug.Log($"{searching} {_}/QuestStatusUpdate in {searchLocation}", this);
|
|
406
|
+
if (isDebug) Debug.Log($"[QuestManager] {searching} {_}/QuestStatusUpdate in {searchLocation}", this);
|
|
284
407
|
questStatusUpdateChannel = Resources.Load<StringEventChannelSO>($"{_}/QuestStatusUpdate");
|
|
285
408
|
if (questStatusUpdateChannel == null)
|
|
286
409
|
{
|
|
@@ -292,7 +415,7 @@ namespace jeanf.questsystem
|
|
|
292
415
|
|
|
293
416
|
if (questProgress == null)
|
|
294
417
|
{
|
|
295
|
-
if (isDebug) Debug.Log($"{searching} {_}/QuestsProgressChannel in {searchLocation}", this);
|
|
418
|
+
if (isDebug) Debug.Log($"[QuestManager] {searching} {_}/QuestsProgressChannel in {searchLocation}", this);
|
|
296
419
|
questProgress = Resources.Load<StringFloatEventChannelSO>($"{_}/QuestsProgressChannel");
|
|
297
420
|
if (questProgress == null)
|
|
298
421
|
{
|
|
@@ -304,7 +427,7 @@ namespace jeanf.questsystem
|
|
|
304
427
|
|
|
305
428
|
if (questStatusUpdateRequested == null)
|
|
306
429
|
{
|
|
307
|
-
if (isDebug) Debug.Log($"{searching} {_}/QuestRequirementCheck in {searchLocation}", this);
|
|
430
|
+
if (isDebug) Debug.Log($"[QuestManager] {searching} {_}/QuestRequirementCheck in {searchLocation}", this);
|
|
308
431
|
questStatusUpdateRequested = Resources.Load<StringEventChannelSO>($"{_}/QuestRequirementCheck");
|
|
309
432
|
if (questStatusUpdateRequested == null)
|
|
310
433
|
{
|
|
@@ -320,7 +443,7 @@ namespace jeanf.questsystem
|
|
|
320
443
|
if (IsValid && !Application.isPlaying) return;
|
|
321
444
|
for(var i = 0 ; i < invalidObjects.Count ; i++)
|
|
322
445
|
{
|
|
323
|
-
Debug.LogError($"Error: {errorMessages[i]} " , this.gameObject);
|
|
446
|
+
Debug.LogError($"[QuestManager] Error: {errorMessages[i]} " , this.gameObject);
|
|
324
447
|
}
|
|
325
448
|
}
|
|
326
449
|
public void OnValidate()
|
|
@@ -103,7 +103,7 @@ namespace jeanf.questsystem
|
|
|
103
103
|
// failsafe to avoid lauching the same step more than once at a time.
|
|
104
104
|
if (stepStatus == QuestStepStatus.Active) return;
|
|
105
105
|
|
|
106
|
-
if(isDebug) Debug.Log($"Initializing questStep [{stepId}] with for quest with questId: [{questId}]");
|
|
106
|
+
//if(isDebug) Debug.Log($"Initializing questStep [{stepId}] with for quest with questId: [{questId}]");
|
|
107
107
|
|
|
108
108
|
stepStatus = QuestStepStatus.Active;
|
|
109
109
|
stepActive?.Invoke(stepId, stepStatus);
|
|
@@ -115,15 +115,15 @@ namespace jeanf.questsystem
|
|
|
115
115
|
}
|
|
116
116
|
if (isUsingIntroTimeline && timeline)
|
|
117
117
|
{
|
|
118
|
-
if(isDebug) Debug.Log($"sending trigger to timeline: {timeline.name}, triggerValue: true");
|
|
118
|
+
//if(isDebug) Debug.Log($"sending trigger to timeline: {timeline.name}, triggerValue: true");
|
|
119
119
|
_timelineTriggerEventChannelSo.RaiseEvent(timeline, true);
|
|
120
120
|
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
-
if(isDebug) Debug.Log($"Step with id [{stepId}] has {questStepsToTrigger.Count} childSteps");
|
|
123
|
+
//if(isDebug) Debug.Log($"Step with id [{stepId}] has {questStepsToTrigger.Count} childSteps");
|
|
124
124
|
foreach(QuestStep questStep in questStepsToTrigger)
|
|
125
125
|
{
|
|
126
|
-
if(isDebug) Debug.Log($"sending childstep to initialization: {questStep.name}, stepId: [{questStep.stepId}]");
|
|
126
|
+
//if(isDebug) Debug.Log($"sending childstep to initialization: {questStep.name}, stepId: [{questStep.stepId}]");
|
|
127
127
|
childStep?.Invoke(questStep);
|
|
128
128
|
}
|
|
129
129
|
}
|
|
@@ -145,7 +145,7 @@ namespace jeanf.questsystem
|
|
|
145
145
|
endStepChannel.RaiseEvent(stepId);
|
|
146
146
|
foreach (QuestStep questStep in questStepsTriggeredOnFailure)
|
|
147
147
|
{
|
|
148
|
-
if (isDebug) Debug.Log($" ---- Step with id: {stepId} finished. Requesting to start next step: {questStep.stepId}", this);
|
|
148
|
+
//if (isDebug) Debug.Log($" ---- Step with id: {stepId} finished. Requesting to start next step: {questStep.stepId}", this);
|
|
149
149
|
|
|
150
150
|
//Si questStep.prerequisitesStep are in QuestItem.stepsCompleted
|
|
151
151
|
sendNextStepId?.Invoke(questStep.stepId);
|
|
@@ -153,31 +153,31 @@ namespace jeanf.questsystem
|
|
|
153
153
|
}
|
|
154
154
|
public void FinishQuestStep()
|
|
155
155
|
{
|
|
156
|
-
if(isDebug) Debug.Log($" ---- Step with id: {stepId} finished. Changing status to completed", this);
|
|
156
|
+
//if(isDebug) Debug.Log($" ---- Step with id: {stepId} finished. Changing status to completed", this);
|
|
157
157
|
stepStatus = QuestStepStatus.Completed;
|
|
158
158
|
|
|
159
159
|
if (sendQuestStepTooltip != null)
|
|
160
160
|
{
|
|
161
|
-
if(isDebug) Debug.Log($" ---- Step with id: {stepId} finished. Sending tooltip", this);
|
|
161
|
+
//if(isDebug) Debug.Log($" ---- Step with id: {stepId} finished. Sending tooltip", this);
|
|
162
162
|
sendQuestStepTooltip.RaiseEvent(string.Empty);
|
|
163
163
|
}
|
|
164
164
|
|
|
165
165
|
|
|
166
|
-
if(isDebug) Debug.Log($" ---- Step with id: {stepId} finished. Sending stepCompleted Event (delegate) with argument: {stepId}", this);
|
|
166
|
+
//if(isDebug) Debug.Log($" ---- Step with id: {stepId} finished. Sending stepCompleted Event (delegate) with argument: {stepId}", this);
|
|
167
167
|
stepCompleted?.Invoke(stepId);
|
|
168
|
-
if (isDebug) Debug.Log($" ---- Step with id: {stepId} finished. Sending stepActive Event (delegate) with arguments: {stepId}, {stepStatus} ", this);
|
|
168
|
+
//if (isDebug) Debug.Log($" ---- Step with id: {stepId} finished. Sending stepActive Event (delegate) with arguments: {stepId}, {stepStatus} ", this);
|
|
169
169
|
stepActive?.Invoke(stepId, stepStatus);
|
|
170
170
|
|
|
171
171
|
foreach (QuestStep questStep in questStepsToTrigger)
|
|
172
172
|
{
|
|
173
|
-
if (isDebug) Debug.Log($" ---- Step with id: {stepId} finished. Requesting to start next step: {questStep.stepId}", this);
|
|
173
|
+
//if (isDebug) Debug.Log($" ---- Step with id: {stepId} finished. Requesting to start next step: {questStep.stepId}", this);
|
|
174
174
|
|
|
175
175
|
//Si questStep.prerequisitesStep are in QuestItem.stepsCompleted
|
|
176
176
|
sendNextStepId?.Invoke(questStep.stepId);
|
|
177
177
|
}
|
|
178
178
|
|
|
179
179
|
|
|
180
|
-
if(isDebug) Debug.Log($" ---- Step with id: {stepId} finished. Destroying the gameobject with name {this.name}", this);
|
|
180
|
+
//if(isDebug) Debug.Log($" ---- Step with id: {stepId} finished. Destroying the gameobject with name {this.name}", this);
|
|
181
181
|
Destroy(this.gameObject);
|
|
182
182
|
}
|
|
183
183
|
#endregion
|
|
@@ -11,22 +11,22 @@ namespace jeanf.questsystem
|
|
|
11
11
|
|
|
12
12
|
public void StartQuest(string id)
|
|
13
13
|
{
|
|
14
|
-
if (onStartQuest
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
if (onStartQuest == null)
|
|
15
|
+
return;
|
|
16
|
+
|
|
17
|
+
Debug.Log($"starting quest: {id}");
|
|
18
|
+
onStartQuest(id);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
public event Action<string> onFinishQuest;
|
|
22
22
|
|
|
23
23
|
public void FinishQuest(string id)
|
|
24
24
|
{
|
|
25
|
-
if (onFinishQuest
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
if (onFinishQuest == null)
|
|
26
|
+
return;
|
|
27
|
+
|
|
28
|
+
Debug.Log($"finishing quest: {id}");
|
|
29
|
+
onFinishQuest(id);
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
public event Action<Quest> onQuestStateChange;
|
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
"GUID:75469ad4d38634e559750d17036d5f7c",
|
|
6
6
|
"GUID:e134609276952144282613c65d798616",
|
|
7
7
|
"GUID:e8958e6939af7314a97769de4be4ce25",
|
|
8
|
-
"GUID:db1b0a3157155ad47996061dbcc07bbb"
|
|
8
|
+
"GUID:db1b0a3157155ad47996061dbcc07bbb",
|
|
9
|
+
"GUID:84651a3751eca9349aac36a66bba901b",
|
|
10
|
+
"GUID:9e24947de15b9834991c9d8411ea37cf"
|
|
9
11
|
],
|
|
10
12
|
"includePlatforms": [],
|
|
11
13
|
"excludePlatforms": [],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fr.jeanf.questsystem",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"displayName": "Quest system",
|
|
5
5
|
"description": "This package uses Scriptable Objects to define quests.",
|
|
6
6
|
"unity": "2021.3",
|
|
@@ -8,6 +8,10 @@
|
|
|
8
8
|
"jeanf",
|
|
9
9
|
"quest system"
|
|
10
10
|
],
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "https://github.com/lejeanf/QuestSystem"
|
|
14
|
+
},
|
|
11
15
|
"author": {
|
|
12
16
|
"name": "Jean-FranΓ§ois Robin",
|
|
13
17
|
"email": "robin.jeanfrancois@gmail.com",
|