4#include "UObject/UObjectIterator.h"
5#include "Engine/ObjectLibrary.h"
6#include "Interfaces/IPluginManager.h"
7#include "Engine/Blueprint.h"
8#include "EngineUtils.h"
9#include "Engine/Engine.h"
29 FDlgLogger::Get().
Error(TEXT(
"StartDialogueWithDefaultParticipants - FAILED to start dialogue because the Dialogue is INVALID (is nullptr)!"));
34 TSet<FName> ParticipantSet;
35 Dialogue->GetAllParticipantNames(ParticipantSet);
36 TArray<UObject*> Participants;
39 TMap<FName, TArray<UObject*>> ObjectMap;
40 for (
const FName&
Name : ParticipantSet)
42 ObjectMap.Add(
Name, {});
48 const FName ParticipantName = IDlgDialogueParticipant::Execute_GetParticipantName(
Participant);
49 if (ObjectMap.Contains(ParticipantName))
57 TArray<FString> MissingNames;
58 TArray<FString> DuplicatedNames;
59 for (
const auto& Pair : ObjectMap)
61 const FName ParticipantName = Pair.Key;
62 const TArray<UObject*>& Objects = Pair.Value;
64 if (Objects.Num() == 0)
66 MissingNames.Add(ParticipantName.ToString());
68 else if (Objects.Num() > 1)
72 DuplicatedNames.Add(Obj->GetName() +
"(" + ParticipantName.ToString() +
")");
77 if (MissingNames.Num() > 0)
79 const FString NameList = FString::Join(MissingNames, TEXT(
", "));
81 TEXT(
"StartDialogueWithDefaultParticipants - FAILED Dialogue = `%s`, the system FAILED to find the following Participant(s): %s"),
86 if (DuplicatedNames.Num() > 0)
88 const FString NameList = FString::Join(DuplicatedNames, TEXT(
", "));
90 TEXT(
"StartDialogueWithDefaultParticipants - FAILED for Dialogue = `%s`, the system found multiple participants using the same name: %s"),
95 if (MissingNames.Num() > 0 || DuplicatedNames.Num() > 0)
105 const FString ContextMessage = ContextString.IsEmpty()
106 ? FString::Printf(TEXT(
"StartDialogue"))
107 : FString::Printf(TEXT(
"%s - StartDialogue"), *ContextString);
109 TMap<FName, UObject*> ParticipantBinding;
115 auto* Context = NewObject<UDlgContext>(Participants[0], UDlgContext::StaticClass());
116 if (Context->StartWithContext(ContextMessage,
Dialogue, ParticipantBinding))
126 TMap<FName, UObject*> ParticipantBinding;
137 UPARAM(ref)
const TArray<UObject*>& Participants,
138 int32 StartNodeIndex,
139 const TSet<int32>& AlreadyVisitedNodes,
140 bool bFireEnterEvents
143 const FString ContextMessage = TEXT(
"ResumeDialogueFromNodeIndex");
144 TMap<FName, UObject*> ParticipantBinding;
150 auto* Context = NewObject<UDlgContext>(Participants[0], UDlgContext::StaticClass());
153 if (Context->StartWithContextFromNodeIndex(ContextMessage,
Dialogue, ParticipantBinding, StartNodeIndex, History, bFireEnterEvents))
163 UPARAM(ref)
const TArray<UObject*>& Participants,
164 const FGuid& StartNodeGUID,
165 const TSet<FGuid>& AlreadyVisitedNodes,
166 bool bFireEnterEvents
169 const FString ContextMessage = TEXT(
"ResumeDialogueFromNodeGUID");
170 TMap<FName, UObject*> ParticipantBinding;
176 auto* Context = NewObject<UDlgContext>(Participants[0], UDlgContext::StaticClass());
179 if (Context->StartWithContextFromNodeGUID(ContextMessage,
Dialogue, ParticipantBinding, StartNodeGUID, History, bFireEnterEvents))
189 TArray<UObject*> Participants;
196 TArray<UObject*> Participants;
197 Participants.Add(Participant0);
198 Participants.Add(Participant1);
204 TArray<UObject*> Participants;
205 Participants.Add(Participant0);
206 Participants.Add(Participant1);
207 Participants.Add(Participant2);
213 TArray<UObject*> Participants;
214 Participants.Add(Participant0);
215 Participants.Add(Participant1);
216 Participants.Add(Participant2);
217 Participants.Add(Participant3);
228 UObjectLibrary* ObjectLibrary = UObjectLibrary::CreateLibrary(UDlgDialogue::StaticClass(),
false, GIsEditor);
229 TArray<FString> PathsToSearch = { TEXT(
"/Game") };
230 ObjectLibrary->AddToRoot();
235 if (ThisPlugin.IsValid())
237 FString PluginPath = ThisPlugin->GetMountedAssetPath();
239 PluginPath.RemoveFromEnd(TEXT(
"/"));
240 PathsToSearch.Add(PluginPath);
243 const bool bForceSynchronousScan = !bAsync;
244 const int32 Count = ObjectLibrary->LoadAssetDataFromPaths(PathsToSearch, bForceSynchronousScan);
245 ObjectLibrary->LoadAssetsFromAssetData();
246 ObjectLibrary->RemoveFromRoot();
262 TArray<UDlgDialogue*>
Array;
263 for (TObjectIterator<UDlgDialogue> Itr; Itr; ++Itr)
276 TArray<TWeakObjectPtr<AActor>>
Array;
277 for (TActorIterator<AActor> Itr(World); Itr; ++Itr)
280 if (IsValid(
Actor) && !
Actor->IsPendingKill() &&
Actor->GetClass()->ImplementsInterface(UDlgDialogueParticipant::StaticClass()))
290 TArray<UObject*>
Array;
291 if (!WorldContextObject)
294 if (UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull))
299 TSet<UObject*> VisitedSet;
300 for (TActorIterator<AActor> Itr(World); Itr; ++Itr)
328 TMap<FName, FDlgObjectsArray> ObjectsMap;
331 const FName ParticipantName = IDlgDialogueParticipant::Execute_GetParticipantName(
Participant);
332 if (ObjectsMap.Contains(ParticipantName))
335 ObjectsMap[ParticipantName].Array.Add(
Participant);
342 ObjectsMap.Add(ParticipantName, ArrayStruct);
352 TArray<UDlgDialogue*> DuplicateDialogues;
354 TSet<FGuid> DialogueGUIDs;
357 const FGuid ID =
Dialogue->GetGUID();
358 if (DialogueGUIDs.Find(ID) ==
nullptr)
361 DialogueGUIDs.Add(ID);
370 return DuplicateDialogues;
376 TMap<FGuid, UDlgDialogue*> DialoguesMap;
380 const FGuid ID =
Dialogue->GetGUID();
381 if (DialoguesMap.Contains(ID))
384 TEXT(
"GetAllDialoguesGUIDsMap - ID = `%s` for Dialogue = `%s` already exists"),
385 *ID.ToString(), *
Dialogue->GetPathName()
437 TArray<UDlgDialogue*> DialoguesArray;
440 if (
Dialogue->HasParticipant(ParticipantName))
446 return DialoguesArray;
451 TSet<FName> UniqueNames;
454 Dialogue->GetAllParticipantNames(UniqueNames);
462 TSet<FName> UniqueNames;
465 Dialogue->GetAllSpeakerStates(UniqueNames);
473 TSet<FName> UniqueNames;
476 Dialogue->GetIntNames(ParticipantName, UniqueNames);
484 TSet<FName> UniqueNames;
487 Dialogue->GetFloatNames(ParticipantName, UniqueNames);
495 TSet<FName> UniqueNames;
498 Dialogue->GetBoolNames(ParticipantName, UniqueNames);
506 TSet<FName> UniqueNames;
509 Dialogue->GetNameNames(ParticipantName, UniqueNames);
517 TSet<FName> UniqueNames;
520 Dialogue->GetConditions(ParticipantName, UniqueNames);
528 TSet<FName> UniqueNames;
531 Dialogue->GetEvents(ParticipantName, UniqueNames);
541 FDlgLogger::Get().
Error(TEXT(
"RegisterDialogueConsoleCommands - The Dialogue System Module is NOT Loaded"));
553 FDlgLogger::Get().
Error(TEXT(
"UnregisterDialogueConsoleCommands - The Dialogue System Module is NOT Loaded"));
568 AlreadyVisited.Add(
Object);
569 if (
Object->GetClass()->ImplementsInterface(UDlgDialogueParticipant::StaticClass()))
575 for (
auto* Property =
Object->GetClass()->PropertyLink; Property !=
nullptr; Property = Property->PropertyLinkNext)
577 if (
auto* ObjectProperty = FNYReflectionHelper::CastProperty<FNYObjectProperty>(Property))
593 if (
auto* World = WorldContextObject->GetWorld())
605 for (
const FWorldContext& Context : GEngine->GetWorldContexts())
607 UWorld* World = Context.World();
608 if (!World || !World->IsPlayInEditor())
611 if (World->GetNetMode() == ENetMode::NM_Standalone ||
612 (World->GetNetMode() == ENetMode::NM_Client && Context.PIEInstance == 2))
619 for (
const FWorldContext& Context : GEngine->GetWorldContexts())
621 UWorld* World = Context.World();
622 if (!World || !World->IsGameWorld())
629 FDlgLogger::Get().
Error(TEXT(
"GetDialogueWorld - Could NOT find any valid world. Call SetDialoguePersistentWorldContextObject in the Being Play of your GameMode"));
const FName DIALOGUE_SYSTEM_PLUGIN_NAME(TEXT("DlgSystem"))
static bool IsObjectAChildOf(const UObject *Object, const UClass *ParentClass)
static void AppendSortedSetToArray(const TSet< FName > &InSet, TArray< FName > &OutArray)
static bool IsObjectImplementingInterface(const UObject *Object, const UClass *InterfaceClass)
static FDlgLogger & Get()
virtual void RegisterConsoleCommands(const TWeakObjectPtr< const UObject > &WorldContextObjectPtr)=0
virtual void UnregisterConsoleCommands()=0
static IDlgSystemModule & Get()
static bool IsAvailable()
FORCEINLINE void Error(const FString &Message)
void Errorf(const FmtType &Fmt, Types... Args)
static bool CanBeStarted(UDlgDialogue *InDialogue, const TMap< FName, UObject * > &InParticipants)
static bool ConvertArrayOfParticipantsToMap(const FString &ContextString, const UDlgDialogue *Dialogue, const TArray< UObject * > &ParticipantsArray, TMap< FName, UObject * > &OutParticipantsMap, bool bLog=true)
UCLASS(BlueprintType, Meta = (DisplayThumbnail = "true"))
static void GetAllDialoguesNameNames(FName ParticipantName, TArray< FName > &OutArray)
UFUNCTION(BlueprintPure, Category = "Dialogue|Data")
static void SetDialogueHistory(const TMap< FGuid, FDlgHistory > &DlgHistory)
UFUNCTION(BlueprintCallable, Category = "Dialogue|Memory")
static void GetAllDialoguesBoolNames(FName ParticipantName, TArray< FName > &OutArray)
UFUNCTION(BlueprintPure, Category = "Dialogue|Data")
static UDlgContext * StartMonologue(UDlgDialogue *Dialogue, UObject *Participant)
UFUNCTION(BlueprintCallable, Category = "Dialogue|Launch")
static TWeakObjectPtr< const UObject > UserWorldContextObjectPtr
static const TMap< FGuid, FDlgHistory > & GetDialogueHistory()
UFUNCTION(BlueprintPure, Category = "Dialogue|Memory")
static void GetAllDialoguesEventNames(FName ParticipantName, TArray< FName > &OutArray)
UFUNCTION(BlueprintPure, Category = "Dialogue|Data")
static void GetAllDialoguesIntNames(FName ParticipantName, TArray< FName > &OutArray)
UFUNCTION(BlueprintPure, Category = "Dialogue|Data")
static bool IsObjectANodeData(const UObject *Object)
UFUNCTION(BlueprintPure, Category = "Dialogue|Helper", DisplayName = "Is Object A Node Data")
static UDlgContext * StartDialogueWithContext(const FString &ContextString, UDlgDialogue *Dialogue, const TArray< UObject * > &Participants)
static UDlgContext * StartDialogue3(UDlgDialogue *Dialogue, UObject *Participant0, UObject *Participant1, UObject *Participant2)
UFUNCTION(BlueprintCallable, Category = "Dialogue|Launch")
static UDlgContext * StartDialogue2(UDlgDialogue *Dialogue, UObject *Participant0, UObject *Participant1)
UFUNCTION(BlueprintCallable, Category = "Dialogue|Launch")
static TMap< FName, FDlgObjectsArray > GetAllObjectsMapWithDialogueParticipantInterface(UObject *WorldContextObject)
UFUNCTION(BlueprintPure, Category = "Dialogue|Helper", meta = (WorldContext = "WorldContextObject"))
static void GetAllDialoguesConditionNames(FName ParticipantName, TArray< FName > &OutArray)
UFUNCTION(BlueprintPure, Category = "Dialogue|Data")
static void GetAllDialoguesFloatNames(FName ParticipantName, TArray< FName > &OutArray)
UFUNCTION(BlueprintPure, Category = "Dialogue|Data")
static TArray< TWeakObjectPtr< AActor > > GetAllWeakActorsWithDialogueParticipantInterface(UWorld *World)
static UDlgContext * StartDialogue4(UDlgDialogue *Dialogue, UObject *Participant0, UObject *Participant1, UObject *Participant2, UObject *Participant3)
UFUNCTION(BlueprintCallable, Category = "Dialogue|Launch")
static bool bCalledLoadAllDialoguesIntoMemory
static TMap< FGuid, UDlgDialogue * > GetAllDialoguesGUIDsMap()
static UDlgContext * ResumeDialogueFromNodeIndex(UDlgDialogue *Dialogue, UPARAM(ref) const TArray< UObject * > &Participants, UPARAM(DisplayName="Start Node Index") int32 StartIndex, const TSet< int32 > &AlreadyVisitedNodes, bool bFireEnterEvents)
UFUNCTION(BlueprintCallable, Category = "Dialogue|Launch")
static bool RegisterDialogueConsoleCommands()
UFUNCTION(BlueprintCallable, Category = "Dialogue|Console")
static void ClearDialogueHistory()
UFUNCTION(BlueprintCallable, Category = "Dialogue|Memory")
static bool IsObjectACustomCondition(const UObject *Object)
UFUNCTION(BlueprintPure, Category = "Dialogue|Helper", DisplayName = "Is Object A Custom Condition")
static void GatherParticipantsRecursive(UObject *Object, TArray< UObject * > &Array, TSet< UObject * > &AlreadyVisited)
static bool DoesObjectImplementDialogueParticipantInterface(const UObject *Object)
UFUNCTION(BlueprintPure, Category = "Dialogue|Helper")
static TArray< UDlgDialogue * > GetAllDialoguesForParticipantName(FName ParticipantName)
static UDlgContext * StartDialogueWithDefaultParticipants(UObject *WorldContextObject, UDlgDialogue *Dialogue)
UFUNCTION(BlueprintCallable, Category = "Dialogue|Launch", meta = (WorldContext = "WorldContextObject...
static bool IsObjectACustomTextArgument(const UObject *Object)
UFUNCTION(BlueprintPure, Category = "Dialogue|Helper", DisplayName = "Is Object A Custom Text Argumen...
static bool UnregisterDialogueConsoleCommands()
UFUNCTION(BlueprintCallable, Category = "Dialogue|Console")
static bool CanStartDialogue(UDlgDialogue *Dialogue, UPARAM(ref) const TArray< UObject * > &Participants)
UFUNCTION(BlueprintCallable, Category = "Dialogue|Launch")
static UDlgContext * ResumeDialogueFromNodeGUID(UDlgDialogue *Dialogue, UPARAM(ref) const TArray< UObject * > &Participants, const FGuid &StartNodeGUID, const TSet< FGuid > &AlreadyVisitedNodes, bool bFireEnterEvents)
UFUNCTION(BlueprintCallable, Category = "Dialogue|Launch")
static int32 LoadAllDialoguesIntoMemory(bool bAsync=false)
static TArray< UDlgDialogue * > GetDialoguesWithDuplicateGUIDs()
static void GetAllDialoguesSpeakerStates(TArray< FName > &OutArray)
UFUNCTION(BlueprintPure, Category = "Dialogue|Data")
static bool IsObjectACustomEvent(const UObject *Object)
UFUNCTION(BlueprintPure, Category = "Dialogue|Helper", DisplayName = "Is Object A Custom Event")
static TArray< UDlgDialogue * > GetAllDialoguesFromMemory()
static UWorld * GetDialogueWorld()
UFUNCTION(BlueprintCallable, Category = "Dialogue|Persistence")
static void GetAllDialoguesParticipantNames(TArray< FName > &OutArray)
UFUNCTION(BlueprintPure, Category = "Dialogue|Data")
static TArray< UObject * > GetAllObjectsWithDialogueParticipantInterface(UObject *WorldContextObject)
UFUNCTION(BlueprintPure, Category = "Dialogue|Helper", meta = (WorldContext = "WorldContextObject"))
TSet< FGuid > VisitedNodeGUIDs
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Dialogue|History")
TSet< int32 > VisitedNodeIndices
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Dialogue|History")
const TMap< FGuid, FDlgHistory > & GetHistoryMaps() const
void SetHistoryMap(const TMap< FGuid, FDlgHistory > &Map)
static FDlgMemory & Get()
TArray< UObject * > Array
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Data")