A Demo Project for the UnrealEngineSDK
Loading...
Searching...
No Matches
DlgCondition.cpp
Go to the documentation of this file.
1// Copyright Csaba Molnar, Daniel Butum. All Rights Reserved.
2#include "DlgCondition.h"
3
4#include "DlgConstants.h"
5#include "DlgMemory.h"
6#include "DlgContext.h"
7#include "Nodes/DlgNode.h"
9#include "Kismet/GameplayStatics.h"
11#include "DlgHelper.h"
12#include "Logging/DlgLogger.h"
13
14bool FDlgCondition::EvaluateArray(const UDlgContext& Context, const TArray<FDlgCondition>& ConditionsArray, FName DefaultParticipantName)
15{
16 bool bHasAnyWeak = false;
17 bool bHasSuccessfulWeak = false;
18
19 for (const FDlgCondition& Condition : ConditionsArray)
20 {
21 const FName ParticipantName = Condition.ParticipantName == NAME_None ? DefaultParticipantName : Condition.ParticipantName;
22 const bool bSatisfied = Condition.IsConditionMet(Context, Context.GetParticipant(ParticipantName));
24 {
25 bHasAnyWeak = true;
26 bHasSuccessfulWeak = bHasSuccessfulWeak || bSatisfied;
27 }
28 else if (!bSatisfied)
29 {
30 // All must be satisfied
31 return false;
32 }
33 }
34
35 return bHasSuccessfulWeak || !bHasAnyWeak;
36}
37
39{
40 bool bHasParticipant = true;
42 {
43 bHasParticipant = ValidateIsParticipantValid(Context, TEXT("IsConditionMet"), Participant);
44 }
45
46 // We don't care if it has a participant, but warn nonetheless by calling validate it before this
48 {
49 if (CustomCondition == nullptr)
50 {
52 TEXT("Custom Condition is empty (not valid). IsConditionMet returning false.\nContext:\n\t%s, Participant = %s"),
53 *Context.GetContextString(), Participant ? *Participant->GetPathName() : TEXT("INVALID")
54 );
55 return false;
56 }
57
59 }
60
61 // Must have participant from this point onwards
62 if (!bHasParticipant)
63 {
64 return false;
65 }
66 switch (ConditionType)
67 {
69 return IDlgDialogueParticipant::Execute_CheckCondition(Participant, &Context, CallbackName) == bBoolValue;
70
72 return CheckBool(Context, IDlgDialogueParticipant::Execute_GetBoolValue(Participant, CallbackName));
73
75 return CheckFloat(Context, IDlgDialogueParticipant::Execute_GetFloatValue(Participant, CallbackName));
76
78 return CheckInt(Context, IDlgDialogueParticipant::Execute_GetIntValue(Participant, CallbackName));
79
81 return CheckName(Context, IDlgDialogueParticipant::Execute_GetNameValue(Participant, CallbackName));
82
83
85 return CheckBool(Context, FNYReflectionHelper::GetVariable<FNYBoolProperty, bool>(Participant, CallbackName));
86
88 return CheckFloat(Context, FNYReflectionHelper::GetVariable<FNYFloatProperty, float>(Participant, CallbackName));
89
91 return CheckInt(Context, FNYReflectionHelper::GetVariable<FNYIntProperty, int32>(Participant, CallbackName));
92
94 return CheckName(Context, FNYReflectionHelper::GetVariable<FNYNameProperty, FName>(Participant, CallbackName));
95
96
99 {
101 }
102
104
106 {
107 // Use the GUID if it is valid as it is more reliable
108 const UDlgNode* Node = GUID.IsValid() ? Context.GetNodeFromGUID(GUID) : Context.GetNodeFromIndex(IntValue);
109 return Node != nullptr ? Node->HasAnySatisfiedChild(Context, {}) == bBoolValue : false;
110 }
111
112 default:
113 checkNoEntry();
114 return false;
115 }
116}
117
118bool FDlgCondition::CheckFloat(const UDlgContext& Context, float Value) const
119{
120 float ValueToCheckAgainst = FloatValue;
122 {
123 const UObject* OtherParticipant = Context.GetParticipant(OtherParticipantName);
124 if (!ValidateIsParticipantValid(Context, TEXT("CheckFloat"), OtherParticipant))
125 {
126 return false;
127 }
128
130 {
131 ValueToCheckAgainst = IDlgDialogueParticipant::Execute_GetFloatValue(OtherParticipant, OtherVariableName);
132 }
133 else
134 {
135 ValueToCheckAgainst = FNYReflectionHelper::GetVariable<FNYFloatProperty, float>(OtherParticipant, OtherVariableName);
136 }
137 }
138
139 switch (Operation)
140 {
142 return FMath::IsNearlyEqual(Value, ValueToCheckAgainst);
143
145 return Value > ValueToCheckAgainst;
146
148 return Value >= ValueToCheckAgainst;
149
151 return Value < ValueToCheckAgainst;
152
154 return Value <= ValueToCheckAgainst;
155
157 return !FMath::IsNearlyEqual(Value, ValueToCheckAgainst);
158
159 default:
161 TEXT("Invalid Operation in float based condition.\nContext:\n\t%s"),
162 *Context.GetContextString()
163 );
164 return false;
165 }
166}
167
168bool FDlgCondition::CheckInt(const UDlgContext& Context, int32 Value) const
169{
170 int32 ValueToCheckAgainst = IntValue;
172 {
173 const UObject* OtherParticipant = Context.GetParticipant(OtherParticipantName);
174 if (!ValidateIsParticipantValid(Context, TEXT("CheckInt"), OtherParticipant))
175 {
176 return false;
177 }
178
180 {
181 ValueToCheckAgainst = IDlgDialogueParticipant::Execute_GetIntValue(OtherParticipant, OtherVariableName);
182 }
183 else
184 {
185 ValueToCheckAgainst = FNYReflectionHelper::GetVariable<FNYIntProperty, int32>(OtherParticipant, OtherVariableName);
186 }
187 }
188
189 switch (Operation)
190 {
192 return Value == ValueToCheckAgainst;
193
195 return Value > ValueToCheckAgainst;
196
198 return Value >= ValueToCheckAgainst;
199
201 return Value < ValueToCheckAgainst;
202
204 return Value <= ValueToCheckAgainst;
205
207 return Value != ValueToCheckAgainst;
208
209 default:
211 TEXT("Invalid Operation in int based condition.\nContext:\n\t%s"),
212 *Context.GetContextString()
213 );
214 return false;
215 }
216}
217
218bool FDlgCondition::CheckBool(const UDlgContext& Context, bool bValue) const
219{
220 bool bResult = bValue;
222 {
223 const UObject* OtherParticipant = Context.GetParticipant(OtherParticipantName);
224 if (!ValidateIsParticipantValid(Context, TEXT("CheckBool"), OtherParticipant))
225 {
226 return false;
227 }
228
229 bool bValueToCheckAgainst;
231 {
232 bValueToCheckAgainst = IDlgDialogueParticipant::Execute_GetBoolValue(OtherParticipant, OtherVariableName);
233 }
234 else
235 {
236 bValueToCheckAgainst = FNYReflectionHelper::GetVariable<FNYBoolProperty, bool>(OtherParticipant, OtherVariableName);
237 }
238
239 // Check if value matches other variable
240 bResult = bValue == bValueToCheckAgainst;
241 }
242
243 return bResult == bBoolValue;
244}
245
246bool FDlgCondition::CheckName(const UDlgContext& Context, FName Value) const
247{
248 FName ValueToCheckAgainst = NameValue;
250 {
251 const UObject* OtherParticipant = Context.GetParticipant(OtherParticipantName);
252 if (!ValidateIsParticipantValid(Context, TEXT("CheckName"), OtherParticipant))
253 {
254 return false;
255 }
256
258 {
259 ValueToCheckAgainst = IDlgDialogueParticipant::Execute_GetNameValue(OtherParticipant, OtherVariableName);
260 }
261 else
262 {
263 ValueToCheckAgainst = FNYReflectionHelper::GetVariable<FNYNameProperty, FName>(OtherParticipant, OtherVariableName);
264 }
265 }
266
267 const bool bResult = ValueToCheckAgainst == Value;
268 return bResult == bBoolValue;
269}
270
271bool FDlgCondition::ValidateIsParticipantValid(const UDlgContext& Context, const FString& ContextString, const UObject* Participant) const
272{
273 if (IsValid(Participant))
274 {
275 return true;
276 }
277
279 TEXT("%s FAILED because the PARTICIPANT is INVALID.\nContext:\n\t%s, ConditionType = %s"),
280 *ContextString, *Context.GetContextString(), *ConditionTypeToString(ConditionType)
281 );
282 return false;
283}
284
290
292{
293 // Second participant requires first participant
295}
296
298{
299 FString EnumValue;
300 if (FDlgHelper::ConvertEnumToString<EDlgConditionType>(TEXT("EDlgConditionType"), Type, false, EnumValue))
301 return EnumValue;
302
303 return EnumValue;
304}
EDlgConditionType
UENUM(BlueprintType)
static FDlgLogger & Get()
Definition DlgLogger.h:24
void Errorf(const FmtType &Fmt, Types... Args)
Definition INYLogger.h:305
bool IsConditionMet(const UDlgContext *Context, const UObject *Participant)
UFUNCTION(BlueprintCallable, BlueprintNativeEvent, Category = "Dialogue")
UCLASS(BlueprintType)
Definition DlgContext.h:96
const FDlgHistory & GetHistoryOfThisContext() const
Definition DlgContext.h:584
FGuid GetDialogueGUID() const
UFUNCTION(BlueprintPure, Category = "Dialogue|Data")
Definition DlgContext.h:522
const UObject * GetParticipant(FName ParticipantName) const
FString GetContextString() const
UFUNCTION(BlueprintPure, Category = "Dialogue|Context")
const UDlgNode * GetNodeFromIndex(int32 NodeIndex) const
const UDlgNode * GetNodeFromGUID(const FGuid &NodeGUID) const
UCLASS(BlueprintType, Abstract, EditInlineNew, ClassGroup = "Dialogue")
Definition DlgNode.h:40
bool HasAnySatisfiedChild(const UDlgContext &Context, TSet< const UDlgNode * > AlreadyVisitedNodes) const
Definition DlgNode.cpp:212
USTRUCT(Blueprintable)
float FloatValue
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Dialogue|Condition")
UDlgConditionCustom * CustomCondition
UPROPERTY(Instanced, EditAnywhere, BlueprintReadWrite, Category = "Dialogue|Condition")
FName OtherParticipantName
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Dialogue|Condition")
bool IsConditionMet(const UDlgContext &Context, const UObject *Participant) const
FGuid GUID
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Dialogue|Condition")
bool CheckFloat(const UDlgContext &Context, float Value) const
static FString ConditionTypeToString(EDlgConditionType Type)
int32 IntValue
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Dialogue|Condition")
FName OtherVariableName
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Dialogue|Condition")
bool IsParticipantInvolved() const
bool ValidateIsParticipantValid(const UDlgContext &Context, const FString &ContextString, const UObject *Participant) const
bool IsSecondParticipantInvolved() const
bool CheckBool(const UDlgContext &Context, bool bValue) const
bool CheckName(const UDlgContext &Context, FName Value) const
static bool EvaluateArray(const UDlgContext &Context, const TArray< FDlgCondition > &ConditionsArray, FName DefaultParticipantName=NAME_None)
bool bLongTermMemory
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Dialogue|Condition")
bool CheckInt(const UDlgContext &Context, int32 Value) const
EDlgCompare CompareType
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Dialogue|Condition")
EDlgOperation Operation
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Dialogue|Condition")
FName NameValue
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Dialogue|Condition")
bool bBoolValue
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Dialogue|Condition")
EDlgConditionType ConditionType
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Dialogue|Condition")
FName ParticipantName
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Dialogue|Condition")
FName CallbackName
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Dialogue|Condition")
bool Contains(int32 NodeIndex, const FGuid &NodeGUID) const
Definition DlgMemory.h:67
bool IsNodeVisited(const FGuid &DialogueGUID, int32 NodeIndex, const FGuid &NodeGUID) const
Definition DlgMemory.h:157
static FDlgMemory & Get()
Definition DlgMemory.h:117