A Demo Project for the UnrealEngineSDK
Loading...
Searching...
No Matches
DlgCondition.h
Go to the documentation of this file.
1// Copyright Csaba Molnar, Daniel Butum. All Rights Reserved.
2#pragma once
3
4#include "CoreMinimal.h"
6
7
8#include "DlgCondition.generated.h"
9
11class UDlgContext;
12
13// Defines the way the condition is interpreted inside a condition array
14UENUM(BlueprintType)
15enum class EDlgConditionStrength : uint8
16{
18 // Aka an AND condition
19 Strong = 0 UMETA(DisplayName = "Strong Condition (AND Condition)"),
20
21 // At least one of the weak conditions must be satisfied inside the condition array (if there is any)
22 // Aka an OR condition
23 Weak UMETA(DisplayName = "Weak Condition (OR Condition)"),
24};
25
26// The Type of condition FDlgCondition is based upon
27UENUM(BlueprintType)
28enum class EDlgConditionType : uint8
29{
30 // Calls GetIntValue on the Participant
31 IntCall = 0 UMETA(DisplayName = "Check Dialogue Int Value"),
32
33 // Calls GetFloatValue on the Participant
34 FloatCall UMETA(DisplayName = "Check Dialogue Float Value"),
35
36 // Calls GetBoolValue on the Participant
37 BoolCall UMETA(DisplayName = "Check Dialogue Bool Value"),
38
39 // Calls GetNameValue on the Participant
40 NameCall UMETA(DisplayName = "Check Dialogue Name Value"),
41
42 // A named condition call.
43 // Calls CheckCondition on the Participant
44 EventCall UMETA(DisplayName = "Check Dialogue Named Condition"),
45
46 // Gets the value from the Participant Int Variable
47 ClassIntVariable UMETA(DisplayName = "Check Class Int Variable"),
48
49 // Gets the value from the Participant Float Variable
50 ClassFloatVariable UMETA(DisplayName = "Check Class Float Variable"),
51
52 // Gets the value from the Participant Bool Variable
53 ClassBoolVariable UMETA(DisplayName = "Check Class Bool Variable"),
54
55 // Gets the value from the Participant Name Variable
56 ClassNameVariable UMETA(DisplayName = "Check Class Name Variable"),
57
58 // Checks if the target node was already visited
59 WasNodeVisited UMETA(DisplayName = "Was node already visited?"),
60
61 // Checks if the target node has any satisfied child
62 HasSatisfiedChild UMETA(DisplayName = "Has satisfied child?"),
63
64 // User Defined Condition, calls IsConditionMet on the custom condition object.
65 //
66 // 1. Create a new Blueprint derived from DlgConditionCustom (or DlgConditionCustomHideCategories)
67 // 2. Override IsConditionMet
68 // 3. Return true if you want the condition to succeed or false otherwise
69 Custom UMETA(DisplayName = "Custom Condition")
70};
71
72// Operation the return value of a IntCall/FloatCall is checked with
73UENUM(BlueprintType)
74enum class EDlgOperation : uint8
75{
76 Equal = 0 UMETA(DisplayName = "== (Is Equal To)"),
77 NotEqual UMETA(DisplayName = "!= (Is Not Equal To)"),
78 Less UMETA(DisplayName = "< (Is Less Than)"),
79 LessOrEqual UMETA(DisplayName = "<= (Is Less Than Or Equal To)"),
80 Greater UMETA(DisplayName = "> (Is Greater Than)"),
81 GreaterOrEqual UMETA(DisplayName = ">= (Is Greater Than Or Equal To)"),
82};
84// Type of value the participant's value is checked against
85UENUM(BlueprintType)
86enum class EDlgCompare : uint8
87{
88 // Compares against a constat value
89 ToConst = 0 UMETA(DisplayName = "Compare to Constant"),
90
91 // Compares against a Dialogue Value
92 ToVariable UMETA(DisplayName = "Compare to Dialogue Value"),
93
94 // Compares against a Participant Class Variable
95 ToClassVariable UMETA(DisplayName = "Compare to Class Variable")
96};
97
99// A condition is a logical operation which is evaluated based on a participant or on the local (context based) or global dialogue memory.
100// More conditions are stored together in condition arrays in FDlgEdge and in UDlgNode, the node (or the edge's target node) is only visitable
101// if the condition array is satisfied
102USTRUCT(Blueprintable)
103struct DLGSYSTEM_API FDlgCondition
104{
105 GENERATED_USTRUCT_BODY()
106
107public:
108 //
109 // ICppStructOps Interface
110 //
111 bool operator==(const FDlgCondition& Other) const
112 {
113 return Strength == Other.Strength &&
114 ConditionType == Other.ConditionType &&
115 ParticipantName == Other.ParticipantName &&
116 CallbackName == Other.CallbackName &&
117 IntValue == Other.IntValue &&
118 FMath::IsNearlyEqual(FloatValue, Other.FloatValue) &&
119 NameValue == Other.NameValue &&
120 bBoolValue == Other.bBoolValue &&
121 bLongTermMemory == Other.bLongTermMemory &&
122 Operation == Other.Operation &&
123 CompareType == Other.CompareType &&
124 OtherParticipantName == Other.OtherParticipantName &&
125 OtherVariableName == Other.OtherVariableName &&
126 GUID == Other.GUID &&
127 CustomCondition == Other.CustomCondition;
128 }
129
130 //
131 // Own methods
132 //
133
134 static bool EvaluateArray(const UDlgContext& Context, const TArray<FDlgCondition>& ConditionsArray, FName DefaultParticipantName = NAME_None);
135 bool IsConditionMet(const UDlgContext& Context, const UObject* Participant) const;
136
137 // returns true if ParticipantName has to belong to match with a valid Participant in order for the condition type to work */
138 bool IsParticipantInvolved() const;
139 bool IsSecondParticipantInvolved() const;
140
141 // Does this Condition have a IntValue which is in fact a NodeIndex
142 static bool HasNodeIndex(EDlgConditionType ConditionType)
143 {
144 return ConditionType == EDlgConditionType::WasNodeVisited
145 || ConditionType == EDlgConditionType::HasSatisfiedChild;
146 }
147
148 // Is this a Condition which has a Dialogue Value
149 // NOTE: without EDlgConditionType::EventCall, for that call HasParticipantInterfaceValue
150 static bool HasDialogueValue(EDlgConditionType Type)
151 {
152 return Type == EDlgConditionType::BoolCall
156 }
158 // Same as HasDialogueValue but also Has the Event
159 static bool HasParticipantInterfaceValue(EDlgConditionType Type)
160 {
161 return Type == EDlgConditionType::EventCall || HasDialogueValue(Type);
162 }
163
164 // Is this a Condition which has a Class Variable
165 static bool HasClassVariable(EDlgConditionType Type)
166 {
171 }
172
173 // Does the type for FirstType and SecondType match?
174 // Aka are both for int, float, bool, name?
175 static bool IsSameValueType(EDlgConditionType FirstType, EDlgConditionType SecondType)
176 {
178 {
179 return SecondType == EDlgConditionType::BoolCall || SecondType == EDlgConditionType::ClassBoolVariable;
182 {
183 return SecondType == EDlgConditionType::IntCall || SecondType == EDlgConditionType::ClassIntVariable;
184 }
186 {
187 return SecondType == EDlgConditionType::FloatCall || SecondType == EDlgConditionType::ClassFloatVariable;
188 }
191 return SecondType == EDlgConditionType::NameCall || SecondType == EDlgConditionType::ClassNameVariable;
192 }
193
194 return false;
195 }
196
197 static FString ConditionTypeToString(EDlgConditionType Type);
198
199protected:
200 //
201 // Helper functions doing the check on the primary value based on EDlgCompare
202 //
203
204 bool CheckFloat(const UDlgContext& Context, float Value) const;
205 bool CheckInt(const UDlgContext& Context, int32 Value) const;
206 bool CheckBool(const UDlgContext& Context, bool bValue) const;
207 bool CheckName(const UDlgContext& Context, FName Value) const;
208
209 // Checks Participant, prints warning if it is nullptr
210 bool ValidateIsParticipantValid(const UDlgContext& Context, const FString& ContextString, const UObject* Participant) const;
211
212public:
213 // Defines the way the condition is interpreted inside the condition array
214 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Dialogue|Condition")
216
217 // Type of the condition, defines the behavior
218 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Dialogue|Condition")
220
221 // Name of the participant (speaker) the event is called on.
222 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Dialogue|Condition")
223 FName ParticipantName;
224
225 // Name of the variable or event, passed in the function call to the participant
226 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Dialogue|Condition")
227 FName CallbackName;
228
229 // The desired operation on the selected variable
230 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Dialogue|Condition")
231 EDlgOperation Operation = EDlgOperation::Equal;
232
233 // Type of value to check against
234 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Dialogue|Condition")
235 EDlgCompare CompareType = EDlgCompare::ToConst;
236
237 // Name of the other participant (speaker) the check is performed against (with some compare types)
238 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Dialogue|Condition")
239 FName OtherParticipantName;
240
241 // Name of the variable of the other participant the value is checked against (with some compare types)
242 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Dialogue|Condition")
243 FName OtherVariableName;
244
245 // Node index for "node already visited" condition, the value the participant's int is checked against otherwise
246 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Dialogue|Condition")
247 int32 IntValue = 0;
248
249 // Float the participants float is checked against
250 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Dialogue|Condition")
251 float FloatValue = 0.f;
252
253 // FName the participants name is checked against
254 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Dialogue|Condition")
255 FName NameValue;
256
257 // Weather the result defined by the other params has to be true or false in order for this condition to be satisfied
258 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Dialogue|Condition")
259 bool bBoolValue = true;
260
261 // Weather to check if the node was visited at all (in the long term).
262 // Set it to false to check if it was visited in the actual dialogue context
263 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Dialogue|Condition")
264 bool bLongTermMemory = true;
265
266 // GUID for the Node, used for "node already visited"
267 UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Dialogue|Condition")
268 FGuid GUID;
269
270 // User Defined Condition, calls IsConditionMet on the custom condition object.
271 //
272 // 1. Create a new Blueprint derived from DlgConditionCustom (or DlgConditionCustomHideCategories)
273 // 2. Override IsConditionMet
274 // 3. Return true if you want the condition to succeed or false otherwise
275 UPROPERTY(Instanced, EditAnywhere, BlueprintReadWrite, Category = "Dialogue|Condition")
276 UDlgConditionCustom* CustomCondition = nullptr;
277};
278
279template<>
280struct TStructOpsTypeTraits<FDlgCondition> : public TStructOpsTypeTraitsBase2<FDlgCondition>
281{
282 enum
283 {
284 WithIdenticalViaEquality = true
285 };
286};
EDlgOperation
UENUM(BlueprintType)
EDlgConditionType
UENUM(BlueprintType)
EDlgConditionStrength
UENUM(BlueprintType)
@ Strong
All strong condition must be satisfied inside the condition array.
EDlgCompare
UENUM(BlueprintType)
UCLASS(Blueprintable, BlueprintType, Abstract, EditInlineNew)
UCLASS(BlueprintType)
Definition DlgContext.h:96
USTRUCT(Blueprintable)
static bool HasNodeIndex(EDlgConditionType ConditionType)
FName OtherParticipantName
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Dialogue|Condition")
bool operator==(const FDlgCondition &Other) const
FGuid GUID
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Dialogue|Condition")
static bool HasDialogueValue(EDlgConditionType Type)
FName OtherVariableName
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Dialogue|Condition")
static bool HasParticipantInterfaceValue(EDlgConditionType Type)
static bool HasClassVariable(EDlgConditionType Type)
static bool IsSameValueType(EDlgConditionType FirstType, EDlgConditionType SecondType)
EDlgConditionStrength Strength
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Dialogue|Condition")
FName NameValue
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Dialogue|Condition")
FName ParticipantName
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Dialogue|Condition")
FName CallbackName
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Dialogue|Condition")