88
99struct FFloatAttr ;
1010
11- /* *
12- *
13- */
11+ /* Masks modifier effects in editor. */
12+ UENUM (BlueprintType)
13+ enum class EModifierMask : uint8
14+ {
15+ Increment, // X += Value | Sums a value to the attribute
16+ LastMultiplier, // X += X * Cof | Adds the incremental coefficient of the last modified value.
17+ BaseMultiplier // X += Base * Cof | Adds the incremental coefficient of the base value of the attribute.
18+ };
19+
20+
21+ /* * Contains modifier values to be applied to an attribute. 32B */
1422USTRUCT (BlueprintType)
1523struct ATTRIBUTES_API FAttrModifier
1624{
1725 GENERATED_BODY ()
1826
19- FAttrModifier ()
20- : Guid (FGuid::NewGuid ())
21- , Increment (0 .f )
22- , LastValueMultiplier (0 .f )
23- , BaseValueMultiplier (0 .f )
24- {}
27+ /* ***********************************************************************/
28+ /* PROPERTIES */
29+ /* ***********************************************************************/
30+ protected:
2531
26- FAttrModifier ( float BaseValueMultiplier, float LastValueMultiplier = 0 . f , float Increment = 0 . f )
27- : Guid ( FGuid::NewGuid ())
28- , Increment (Increment)
29- , LastValueMultiplier (LastValueMultiplier)
30- , BaseValueMultiplier (BaseValueMultiplier )
31- {}
32+ UPROPERTY (BlueprintReadOnly, Category = Modifier )
33+ FGuid Guid;
34+
35+ // We use 4 bytes of alignment for Dirty flags
36+ UPROPERTY (Transient )
37+ bool bNetDirty_Guid = true ;
3238
3339public:
3440
35- UPROPERTY (BlueprintReadOnly, Category = Modifier)
36- FGuid Guid;
41+ // X += Value | Sums a value to the attribute
42+ UPROPERTY (EditAnywhere, BlueprintReadWrite, Category = Modifier, meta = (ColumnWidth = " 70" , Delta = " 0.01" ))
43+ float Increment = 0 .f ;
3744
38- /* Sums an amount to the attribute */
39- UPROPERTY (EditAnywhere, BlueprintReadWrite, Category = Modifier)
40- float Increment ;
45+ // X += X * Cof | Adds the incremental coefficient of the last modified value.
46+ UPROPERTY (EditAnywhere, BlueprintReadWrite, Category = Modifier, meta = (ColumnWidth = " 70 " , UIMin = " -1.0 " , UIMax = " 1.0 " , Delta= " 0.05 " , Units = " x " ) )
47+ float LastMultiplier = 0 . f ;
4148
42- /* Adds the incremental coefficient of the last attribute value. E.g: +5% health
43- * X += X * Cof
44- */
45- UPROPERTY (EditAnywhere, BlueprintReadWrite, Category = Modifier, meta = (UIMin = " -1.0" , UIMax = " 1.0" ))
46- float LastValueMultiplier;
49+ // X += Base * Cof | Adds the incremental coefficient of the base value of the attribute.
50+ UPROPERTY (EditAnywhere, BlueprintReadWrite, Category = Modifier, meta = (UIMin = " -1.0" , UIMax = " 1.0" , Delta = " 0.05" , Units = " x" ))
51+ float BaseMultiplier = 0 .f ;
4752
48- /* Adds the incremental coefficient of Base. E.g: +5% damage
49- * X += Base * Cof
50- */
51- UPROPERTY (EditAnywhere, BlueprintReadWrite, Category = Modifier, meta = (UIMin = " -1.0" , UIMax = " 1.0" ))
52- float BaseValueMultiplier;
5353
54+ /* ***********************************************************************/
55+ /* METHODS */
56+ /* ***********************************************************************/
57+
58+ FAttrModifier () : Guid (FGuid::NewGuid ()) {}
59+
60+ FAttrModifier (EModifierMask Mode, float Value = 0 .f );
61+
62+ FAttrModifier (float Increment, float LastValueMultiplier = 0 .f , float BaseValueMultiplier = 0 .f );
63+
64+ FAttrModifier (FAttrModifier&& Other) : Guid (Other.Guid ) { SetValues (Other); }
65+ FAttrModifier (const FAttrModifier& Other) : Guid (Other.Guid ) { SetValues (Other); }
66+ FAttrModifier& operator =(FAttrModifier&& Other)
67+ {
68+ Guid = Other.Guid ;
69+ bNetDirty_Guid = true ;
70+ SetValues (Other);
71+ return *this ;
72+ }
73+ FAttrModifier& operator =(const FAttrModifier& Other)
74+ {
75+ Guid = Other.Guid ;
76+ bNetDirty_Guid = true ;
77+ SetValues (Other);
78+ return *this ;
79+ }
5480
5581 /* * Apply changes to the value */
5682 void Apply (float & Value, float BaseValue) const ;
@@ -73,4 +99,70 @@ struct ATTRIBUTES_API FAttrModifier
7399 {
74100 return Guid == Other.Guid ;
75101 }
102+ FORCEINLINE bool operator !=(const FAttrModifier& Other) const { return !(*this == Other); }
103+
104+ void SetValues (FAttrModifier&& Other)
105+ {
106+ Increment = Other.Increment ;
107+ LastMultiplier = Other.LastMultiplier ;
108+ BaseMultiplier = Other.BaseMultiplier ;
109+ }
110+
111+ void SetValues (const FAttrModifier& Other)
112+ {
113+ Increment = Other.Increment ;
114+ LastMultiplier = Other.LastMultiplier ;
115+ BaseMultiplier = Other.BaseMultiplier ;
116+ }
117+
118+ bool NetSerialize (FArchive& Ar, class UPackageMap * Map, bool & bOutSuccess);
76119};
120+
121+ template <>
122+ struct TStructOpsTypeTraits <FAttrModifier> : public TStructOpsTypeTraitsBase2<FAttrModifier>
123+ {
124+ enum
125+ {
126+ WithCopy = true ,
127+ WithNetSerializer = true ,
128+ WithNetSharedSerialization = true ,
129+ // WithIdenticalViaEquality = true
130+ };
131+ };
132+
133+
134+ inline bool FAttrModifier::NetSerialize (FArchive& Ar, UPackageMap* Map, bool & bOutSuccess)
135+ {
136+ // Only replicate non-zero values
137+ uint8 Flags = (bNetDirty_Guid << 0 )
138+ | (!FMath::IsNearlyZero (Increment) << 1 )
139+ | (!FMath::IsNearlyZero (LastMultiplier) << 2 )
140+ | (!FMath::IsNearlyZero (BaseMultiplier) << 3 );
141+
142+ Ar.SerializeBits (&Flags, 4 );
143+
144+ bNetDirty_Guid = Flags & 1 << 0 ;
145+ if (bNetDirty_Guid)
146+ {
147+ Ar << Guid;
148+ bNetDirty_Guid = false ;
149+ }
150+
151+ if (Flags & 1 << 1 )
152+ Ar << Increment;
153+ else
154+ Increment = 0 .f ;
155+
156+ if (Flags & 1 << 2 )
157+ Ar << LastMultiplier;
158+ else
159+ LastMultiplier = 0 .f ;
160+
161+ if (Flags & 1 << 3 )
162+ Ar << BaseMultiplier;
163+ else
164+ BaseMultiplier = 0 .f ;
165+
166+ bOutSuccess = true ;
167+ return true ;
168+ }
0 commit comments