A Demo Project for the UnrealEngineSDK
Loading...
Searching...
No Matches
StoryManager.cpp
Go to the documentation of this file.
1// Copyright(c) Pixo Group. All Rights Reserved.
2
4#include "Net/UnrealNetwork.h"
11
14
15DEFINE_LOG_CATEGORY(LogStoryManager);
16
17bool FStoryStep::operator==(const FStoryStep& Step) const
18{
19 return Step.StepName.EqualTo(StepName);
20}
21
26
27bool UStoryManager::InitNewStory(int newStoryIndex)
28{
29 if (StoryDataArray.Num() == 0)
30 {
31 UE_LOG(LogStoryManager, Warning, TEXT("AStoryManager::InitNewStory StoryDataArray is empty"));
32 //GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, "AStoryManager::InitNewStory StoryDataArray is empty");
33 return false;
34 }
35
36 if (!StoryDataArray.IsValidIndex(newStoryIndex))
37 {
38 UE_LOG(LogStoryManager, Warning, TEXT("AStoryManager::InitNewStory Index out of range"));
39 return false;
40 }
41 // rewrite StoryDataArray with updated StoryData when loading new story in one experience
42 if (StoryData)
43 {
45 }
46 StoryData = StoryDataArray[newStoryIndex];
48 StepIndex = 0;
49 SubStepIndex = 0;
50 if (!StepData.IsValidIndex(StepIndex))
51 {
52 return false;
53 }
54
56 if (StepData[StepIndex].SubStep.IsValidIndex(SubStepIndex))
57 {
59 }
60 else
61 {
64 }
65 StoryIndex = newStoryIndex;
66 EventLogService::NewEvent<UNewStoryLoadedEvent>(nullptr, CurrentStep, true);
67 OnStoryLoaded.Broadcast();
68
69 return true;
70}
71
73{
74 if (!StepData.IsValidIndex(StepIndex))
75 {
76 return false;
77 }
78
79 if (!StepData.IsValidIndex(StepIndex + 1))
80 {
81 StoryFinished = true;
82 OnEndOfStory.Broadcast();
83 EventLogService::NewEvent<UEndOfStoryReached>();
84
85 UE_LOG(LogStoryManager, Warning, TEXT("AStoryManager::GoToNextStep Index out of range"));
86 return false;
87 }
88
89 StepIndex++;
92 SubStepIndex = 0;
93 if (StepData[StepIndex].SubStep.IsValidIndex(SubStepIndex))
94 {
96 }
97 else
98 {
101 }
102
103 OnNewStep.Broadcast(CurrentStep, true);
104 EventLogService::NewEvent<UNewStepLoadedEvent>(nullptr, CurrentStep, true);
105 UE_LOG(LogStoryManager, Log, TEXT("AStoryManager::GoToNextStep Next Step %s"), *CurrentStep.StepName.ToString());
106
107 return true;
108}
109
111{
112 if (!StepData.IsValidIndex(StepIndex))
113 {
114 return false;
115 }
116
117 if (!StepData[StepIndex].SubStep.IsValidIndex(SubStepIndex + 1))
118 {
120 SubStepIndex = 0;
121 return false;
122 }
123
124 SubStepIndex++;
125 //PreviousStep = CurrentStep;
127
128 OnNewSubStep.Broadcast(CurrentSubStep);
129 EventLogService::NewEvent<UNewSubStepLoadedEvent>(nullptr, CurrentSubStep, true);
130 UE_LOG(LogStoryManager, Log, TEXT("AStoryManager::GoToNextSubStep Next SubStep %s"),
131 *CurrentSubStep.StepName.ToString());
132
133 return true;
134}
135
137{
138 if (!StepData.IsValidIndex(StepIndex))
139 {
140 return;
141 }
142
143 for (int i = 0; i < StepData[StepIndex].SubStep.Num(); i++)
144 {
145 if (StepData[StepIndex].SubStep[i].StepName.EqualTo(completedStep.StepName))
146 {
147 StepData[StepIndex].SubStep[i].Completed = true;
148 }
149 }
151 {
153 SubStepIndex = 0;
154 }
155}
156
158{
159 if (!StepData.IsValidIndex(index))
160 {
161 UE_LOG(LogStoryManager, Warning, TEXT("AStoryManager::JumpToStepByIndex Couldn't find a step by index %d"),
162 index);
163 return false;
164 }
165
166 bool isForward;
167 if (index < StepIndex)
168 {
169 isForward = false;
170
171 for (int i = StepIndex - 1; i >= index; i--)
172 {
173 OnStepSkipped.Broadcast(StepData[i].Step, false);
174 }
175 }
176 else
177 {
178 isForward = true;
179
180 for (int i = StepIndex; i < index; i++)
181 {
182 OnStepSkipped.Broadcast(StepData[i].Step, true);
183 }
184 }
185
186 StepIndex = index;
189 SubStepIndex = 0;
190 if (StepData[StepIndex].SubStep.IsValidIndex(SubStepIndex))
191 {
193 }
194 else
195 {
198 }
199
200 OnNewStep.Broadcast(CurrentStep, isForward);
201 EventLogService::NewEvent<UNewStepLoadedEvent>(nullptr, CurrentStep, true);
202 UE_LOG(LogStoryManager, Log, TEXT("AStoryManager::JumpToStepByIndex Jump To Step %s"),
203 *CurrentStep.StepName.ToString());
204
205 return true;
206}
207
209{
210 bool found = false;
211 int index = 0;
212
213 for (int i = 0; i < StepData.Num(); i++)
214 {
215 if (stepId.EqualTo(StepData[i].Step.StepName))
216 {
217 index = i;
218 found = true;
219 break;
220 }
221 }
222
223 if (found == false)
224 {
225 UE_LOG(LogStoryManager, Warning, TEXT("AStoryManager::JumpToStepByName Couldn't find a step %s"),
226 *stepId.ToString());
227 return false;
228 }
229
230 bool isForward;
231 if (index < StepIndex)
232 {
233 isForward = false;
234
235 for (int i = StepIndex - 1; i >= index; i--)
236 {
237 OnStepSkipped.Broadcast(StepData[i].Step, false);
238 }
239 }
240 else
241 {
242 isForward = true;
243
244 for (int i = StepIndex; i < index; i++)
245 {
246 OnStepSkipped.Broadcast(StepData[i].Step, true);
247 }
248 }
249
250 StepIndex = index;
253 SubStepIndex = 0;
254 if (StepData[StepIndex].SubStep.IsValidIndex(SubStepIndex))
255 {
257 }
258 else
259 {
262 }
263
264 OnNewStep.Broadcast(CurrentStep, isForward);
265 EventLogService::NewEvent<UNewStepLoadedEvent>(nullptr, CurrentStep, true);
266 UE_LOG(LogStoryManager, Log, TEXT("AStoryManager::JumpToStepByName Jump To Step %s"),
267 *CurrentStep.StepName.ToString());
268
269 return true;
270}
271
272void UStoryManager::StepCompleted(FText stepToUpdate, bool goToNext)
273{
274 if (!StepData.IsValidIndex(StepIndex))
275 {
276 return;
277 }
278
279 if (BlockStory == false)
280 {
281 if (stepToUpdate.EqualTo(CurrentStep.StepName))
282 {
283 StepData[StepIndex].Step.Completed = true;
285 OnStepCompleted.Broadcast(CurrentStep);
286 EventLogService::NewEvent<UStepCompletedEvent>(nullptr, CurrentStep);
287
288 if (goToNext)
289 {
290 GoToNextStep();
291 }
292 }
293 }
294}
295
297{
298 StoryComponents.AddUnique(storyComponent);
299}
300
301void UStoryManager::SetupNextStory(int newNextStoryIndex, TArray<FText> newStoryParameters)
302{
303 NextStoryIndex = newNextStoryIndex;
304 StoryParameters = newStoryParameters;
305}
306
308{
309 if (!StepData.IsValidIndex(StepIndex))
310 {
311 return false;
312 }
313
314 bool isCompleted = true;
315 for (FStoryStep steps : StepData[StepIndex].SubStep)
316 {
317 if (!steps.Completed)
318 {
319 isCompleted = false;
320 }
321 }
322 return isCompleted;
323}
324
326{
327 bool StoryAlreadyInArray = false;
328 int32 FoundedStoryIndex = 0;
329 for (int i = 0; i <= (PassedExperiencesArray.Num() - 1); i++)
330 {
332 {
333 StoryAlreadyInArray = true;
334 FoundedStoryIndex = i;
335 }
336 }
337 if (StoryAlreadyInArray)
338 {
339 PassedExperiencesArray[FoundedStoryIndex].PassedStepData = StepData;
340 }
341 else
342 {
343 FPassedExperiences TempExp;
344 TempExp.PassedStepData = StepData;
345 TempExp.StoryIndex = StoryIndex;
346 PassedExperiencesArray.Add(TempExp);
347 }
348}
349
350void UStoryManager::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
351{
352 Super::GetLifetimeReplicatedProps(OutLifetimeProps);
353
354 DOREPLIFETIME(UStoryManager, StoryData);
355 DOREPLIFETIME(UStoryManager, StepData);
356 DOREPLIFETIME(UStoryManager, CurrentStep);
357 DOREPLIFETIME(UStoryManager, StepIndex);
358 DOREPLIFETIME(UStoryManager, PreviousStep);
359 DOREPLIFETIME(UStoryManager, CurrentSubStep);
360 DOREPLIFETIME(UStoryManager, SubStepIndex);
361 DOREPLIFETIME(UStoryManager, StoryIndex);
362}
363
368{
369 if (!StoryData->IsValidLowLevel() || StoryData->StepData.Num() == 0)
370 {
372 {
373 UE_LOG(LogStoryManager, Error, TEXT("AStoryManager::UInitializationEvent StoryDataArray is empty"));
374 }
375 }
376}
#define DEFINE_EVENT_HANDLER(TEventType)
Definition BaseManager.h:13
DEFINE_LOG_CATEGORY(LogStoryManager)
void HandleEvent_Impl(class UBaseEvent *Event)
Event called when we on init experience.
A component responsible for managing the story progression in story actors.
TArray< FStepData > StepData
UPROPERTY(EditAnywhere)
Manager that provides handling story-related operations and data.
int StoryIndex
UPROPERTY(BlueprintReadWrite, Replicated)
UStoryManager()
FOnStepSkipped OnStepSkipped
UPROPERTY(BlueprintAssignable, Category = "Story Delegate")
TArray< UStoryComponent * > StoryComponents
UPROPERTY()
FOnNewStep OnNewStep
UPROPERTY(BlueprintAssignable, Category = "Story Delegate")
FStoryStep PreviousStep
UPROPERTY(BlueprintReadWrite, Replicated)
bool JumpToStepByIndex(int index)
UFUNCTION(BlueprintCallable)
void RecordStoryStepData()
Records the data for a story step. It checks if the story is already present in the PassedExperiences...
bool JumpToStepByName(FText stepId)
UFUNCTION(BlueprintCallable)
UStoryData * StoryData
UPROPERTY(BlueprintReadWrite, Replicated)
TArray< FPassedExperiences > PassedExperiencesArray
UPROPERTY(BlueprintReadWrite)
FStoryStep CurrentSubStep
UPROPERTY(BlueprintReadWrite, Replicated)
int StepIndex
UPROPERTY(BlueprintReadWrite, Replicated)
FOnStoryLoaded OnStoryLoaded
UPROPERTY(BlueprintAssignable, Category = "Story Delegate")
int SubStepIndex
UPROPERTY(BlueprintReadWrite, Replicated)
void CompleteSubStep(FStoryStep completedStep)
UFUNCTION(BlueprintCallable)
static TArray< FText > StoryParameters
void AddStoryComponent(UStoryComponent *storyComponent)
bool InitNewStory(int newStoryIndex)
Choose one story from StoryDataArray.
bool BlockStory
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TArray< UStoryData * > StoryDataArray
UPROPERTY(EditAnywhere, BlueprintReadWrite)
virtual void GetLifetimeReplicatedProps(TArray< FLifetimeProperty > &OutLifetimeProps) const override
bool GoToNextSubStep()
UFUNCTION(BlueprintCallable)
bool GoToNextStep()
UFUNCTION(BlueprintCallable)
static void SetupNextStory(int newNextStoryIndex, TArray< FText > newStoryParameters)
UFUNCTION(BlueprintCallable)
TArray< FStepData > StepData
UPROPERTY(BlueprintReadWrite, Replicated)
FOnStepCompleted OnStepCompleted
UPROPERTY(BlueprintAssignable, Category = "Story Delegate")
void StepCompleted(FText stepToUpdate, bool goToNext=true)
UFUNCTION(BlueprintCallable)
bool StoryFinished
UPROPERTY(BlueprintReadOnly)
FOnNewSubStep OnNewSubStep
UPROPERTY(BlueprintAssignable, Category = "Story Delegate")
static int NextStoryIndex
Keeps track of which story should be loaded next by index, saved between levels.
bool IsAllSubStepsCompleted()
UFUNCTION()
FStoryStep CurrentStep
UPROPERTY(BlueprintReadWrite, Replicated)
FOnEndOfStory OnEndOfStory
UPROPERTY(BlueprintAssignable, Category = "Story Delegate")
USTRUCT(BlueprintType)
int32 StoryIndex
UPROPERTY(BlueprintReadWrite)
TArray< FStepData > PassedStepData
UPROPERTY(BlueprintReadWrite)
USTRUCT(BlueprintType)
bool operator==(const FStoryStep &Step) const
FText StepName
UPROPERTY(BlueprintReadWrite, EditAnywhere)
bool Completed
UPROPERTY(BlueprintReadWrite, EditAnywhere)