Skip to content

Commit 287041c

Browse files
committed
2 parents 76ba9af + 51c6301 commit 287041c

11 files changed

Lines changed: 422 additions & 14 deletions

File tree

Source/Attributes/Private/AttrModifier.cpp

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,23 +31,19 @@ FAttrModifier::FAttrModifier(float Increment, float LastValueMultiplier, float B
3131

3232
void FAttrModifier::Apply(float& Value, float BaseValue) const
3333
{
34-
if (!FMath::IsNearlyZero(LastMultiplier))
35-
{
36-
Value *= 1.0f + LastMultiplier;
37-
}
34+
Value *= 1.0f + LastMultiplier;
35+
3836
if (!FMath::IsNearlyZero(BaseMultiplier))
3937
{
4038
Value += BaseMultiplier * BaseValue;
4139
}
4240
Value += Increment;
4341
}
4442

45-
void FAttrModifier::Apply(double& Value, int32 BaseValue) const
43+
void FAttrModifier::Apply(double& Value, double BaseValue) const
4644
{
47-
if (!FMath::IsNearlyZero(LastMultiplier))
48-
{
49-
Value *= 1.0 + LastMultiplier;
50-
}
45+
Value *= 1.0 + LastMultiplier;
46+
5147
if (!FMath::IsNearlyZero(BaseMultiplier))
5248
{
5349
Value += BaseMultiplier * BaseValue;
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright 2015-2020 Piperift. All Rights Reserved.
2+
3+
#include "DoubleAttr.h"
4+
#include "AttributesModule.h"
5+
6+
7+
void FDoubleAttr::SetBaseValue(double NewValue)
8+
{
9+
if (NewValue != BaseValue)
10+
{
11+
BaseValue = NewValue;
12+
13+
// Notify
14+
InternalRefreshValue({
15+
EAttributeOperation::BaseValueChanged,
16+
{},
17+
FAttrCategory::NoCategory
18+
});
19+
}
20+
}
21+
22+
void FDoubleAttr::PostScriptConstruct()
23+
{
24+
RefreshValue();
25+
}
26+
27+
void FDoubleAttr::InternalRefreshValue(FAttributeChangeInfo&& ChangeInfo)
28+
{
29+
const double LastValue = Value;
30+
Value = BaseValue;
31+
32+
for (const auto& Mod : BaseModifiers)
33+
{
34+
Mod.Apply(Value, BaseValue);
35+
}
36+
37+
for (const auto& Category : CategoryMods)
38+
{
39+
for (const auto& Mod : Category.Modifiers)
40+
{
41+
Mod.Apply(Value, BaseValue);
42+
}
43+
}
44+
45+
// Notify changes
46+
OnModified.Broadcast(LastValue, ChangeInfo);
47+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// Copyright 2015-2020 Piperift. All Rights Reserved.
2+
3+
#include "DoubleAttributesLibrary.h"

Source/Attributes/Private/Int32Attr.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ void FInt32Attr::InternalRefreshValue(FAttributeChangeInfo&& ChangeInfo)
3838
{
3939
for (const auto& Mod : Category.Modifiers)
4040
{
41-
Mod.Apply(TempValue, BaseValue);
41+
Mod.Apply(TempValue, double(BaseValue));
4242
}
4343
}
4444

Source/Attributes/Public/AttrModifier.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,9 @@ struct ATTRIBUTES_API FAttrModifier
7878
return *this;
7979
}
8080

81-
/** Apply changes to the value */
81+
/** Applies changes to value */
8282
void Apply(float& Value, float BaseValue) const;
83-
84-
/** Applies the modifier to the value. This version operates as double to avoid int32 precision lose */
85-
void Apply(double& Value, int32 BaseValue) const;
83+
void Apply(double& Value, double BaseValue) const;
8684

8785
/** Stack other modifiers values into this mod.
8886
* Now applying this modifier will be equivalent to applying all the others at the same time

Source/Attributes/Public/AttributeEvents.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,5 +40,8 @@ struct FAttributeChangeInfo
4040
DECLARE_DYNAMIC_DELEGATE_TwoParams(FFloatModifiedDelegate, float, LastValue, const FAttributeChangeInfo&, Modification);
4141
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FFloatModifiedMCDelegate, float, LastValue, const FAttributeChangeInfo&, Modification);
4242

43+
DECLARE_DYNAMIC_DELEGATE_TwoParams(FDoubleModifiedDelegate, double, LastValue, const FAttributeChangeInfo&, Modification);
44+
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FDoubleModifiedMCDelegate, double, LastValue, const FAttributeChangeInfo&, Modification);
45+
4346
DECLARE_DYNAMIC_DELEGATE_TwoParams(FInt32ModifiedDelegate, int32, LastValue, const FAttributeChangeInfo&, Modification);
4447
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FInt32ModifiedMCDelegate, int32, LastValue, const FAttributeChangeInfo&, Modification);
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
// Copyright 2015-2020 Piperift. All Rights Reserved.
2+
3+
#pragma once
4+
5+
#include <CoreMinimal.h>
6+
7+
#include "BaseAttr.h"
8+
#include "AttrModifier.h"
9+
#include "AttrCategory.h"
10+
11+
#include "DoubleAttr.generated.h"
12+
13+
14+
/**
15+
* Double Attribute
16+
* Used as a modular double depending on modifiers
17+
*/
18+
USTRUCT(BlueprintType, meta = (HasNativeBreak = "Attributes.DoubleAttributesLibrary.Break", HasNativeMake = "Attributes.DoubleAttributesLibrary.Make"))
19+
struct ATTRIBUTES_API FDoubleAttr : public FBaseAttr
20+
{
21+
GENERATED_BODY()
22+
protected:
23+
24+
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Attribute, SaveGame)
25+
double BaseValue = 0;
26+
27+
/** Cached final value from modifiers */
28+
UPROPERTY(EditAnywhere, Category = Attribute, Transient)
29+
double Value = 0;
30+
31+
UPROPERTY()
32+
FDoubleModifiedMCDelegate OnModified;
33+
34+
35+
public:
36+
37+
FDoubleAttr() : FBaseAttr() {}
38+
FDoubleAttr(double BaseValue) : FBaseAttr(), BaseValue(BaseValue), Value(BaseValue) {}
39+
40+
void SetBaseValue(double NewValue);
41+
double GetBaseValue() const { return BaseValue; }
42+
double GetValue() const { return Value; }
43+
44+
/* Get Attribute final value */
45+
FORCEINLINE operator double() const { return GetValue(); }
46+
47+
FORCEINLINE double operator+(const double Other) const { return GetValue() + Other; }
48+
49+
FORCEINLINE double operator-(const double Other) const { return GetValue() - Other; }
50+
51+
FORCEINLINE double operator+(const FDoubleAttr& Other) const { return *this + Other.GetValue(); }
52+
53+
FORCEINLINE double operator-(const FDoubleAttr& Other) const { return *this - Other.GetValue(); }
54+
55+
bool NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess);
56+
57+
void PostSerialize(const FArchive& Ar);
58+
void PostScriptConstruct();
59+
60+
FDoubleModifiedMCDelegate& GetOnModified() { return OnModified; }
61+
const FDoubleModifiedMCDelegate& GetOnModified() const { return OnModified; }
62+
63+
private:
64+
65+
virtual void InternalRefreshValue(FAttributeChangeInfo&& ChangeInfo) override;
66+
};
67+
68+
69+
template<>
70+
struct TStructOpsTypeTraits<FDoubleAttr> : public TStructOpsTypeTraitsBase2<FDoubleAttr>
71+
{
72+
enum {
73+
WithNetSerializer = true,
74+
WithNetSharedSerialization = true,
75+
WithPostSerialize = true,
76+
WithPostScriptConstruct = true
77+
};
78+
};
79+
80+
81+
inline bool FDoubleAttr::NetSerialize(FArchive& Ar, UPackageMap* Map, bool& bOutSuccess)
82+
{
83+
if (UAttributesSettings::GetReplication().bReplicateBaseValue)
84+
{
85+
Ar << BaseValue;
86+
}
87+
88+
Ar << Value;
89+
90+
bOutSuccess = true;
91+
return true;
92+
}
93+
94+
inline void FDoubleAttr::PostSerialize(const FArchive& Ar)
95+
{
96+
// We refresh serialized value for overrided properties or instanced objects
97+
if(Ar.IsLoading())
98+
{
99+
RefreshValue();
100+
}
101+
}
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
// Copyright 2015-2020 Piperift. All Rights Reserved.
2+
3+
#pragma once
4+
5+
#include <CoreMinimal.h>
6+
#include <Kismet/BlueprintFunctionLibrary.h>
7+
8+
#include "DoubleAttr.h"
9+
10+
#include "DoubleAttributesLibrary.generated.h"
11+
12+
13+
/**
14+
*
15+
*/
16+
UCLASS()
17+
class ATTRIBUTES_API UDoubleAttributesLibrary : public UBlueprintFunctionLibrary
18+
{
19+
GENERATED_BODY()
20+
21+
public:
22+
23+
/** @return true when two Attributes are the same */
24+
UFUNCTION(BlueprintPure, Category = Attributes, meta = (CompactNodeTitle = "=="))
25+
static FORCEINLINE bool Is(const FDoubleAttr& A, const FDoubleAttr& B) { return A == B; }
26+
27+
/** @return true when two Attributes are not the same */
28+
UFUNCTION(BlueprintPure, Category = Attributes, meta = (CompactNodeTitle = "!="))
29+
static FORCEINLINE bool IsNot(const FDoubleAttr& A, const FDoubleAttr& B) { return A != B; }
30+
31+
/** @return true if two attributes have the same base value */
32+
UFUNCTION(BlueprintPure, Category = Attributes)
33+
static FORCEINLINE bool Equals(const FDoubleAttr& A, const FDoubleAttr& B)
34+
{
35+
return A.GetBaseValue() == B.GetBaseValue();
36+
}
37+
38+
/**
39+
* Get the final value of an attribute
40+
* @param Attribute to get value from
41+
* @return the final value
42+
*/
43+
UFUNCTION(BlueprintPure, Category = Attributes, meta = (Keywords = "get value double total final"))
44+
static FORCEINLINE double GetValue(const FDoubleAttr& Attribute) { return Attribute.GetValue(); }
45+
46+
// Get final value
47+
UFUNCTION(BlueprintPure, Category = Attributes, meta = (DisplayName = "ToFloat (DoubleAttr)", CompactNodeTitle = "->", Keywords = "get value double", BlueprintAutocast))
48+
static FORCEINLINE double Conv_AttributeToFloat(const FDoubleAttr& Attribute) { return GetValue(Attribute); }
49+
50+
// Get final value as String
51+
UFUNCTION(BlueprintPure, Category = Attributes, meta = (DisplayName = "ToString (DoubleAttr)", CompactNodeTitle = "->", BlueprintAutocast))
52+
static FORCEINLINE FString Conv_AttributeToString(const FDoubleAttr& Attribute) {
53+
return FString::SanitizeFloat(GetValue(Attribute));
54+
}
55+
56+
/**
57+
* Get the base value of an attribute
58+
* @param Attribute to get base value from
59+
* @return the base value
60+
*/
61+
UFUNCTION(BlueprintPure, Category = Attributes)
62+
static FORCEINLINE double GetBase(const FDoubleAttr& Attribute) { return Attribute.GetBaseValue(); }
63+
64+
/**
65+
* Set the base value of an attribute
66+
* @param Attribute to set base value at
67+
* @param Value to set as the base value
68+
*/
69+
UFUNCTION(BlueprintCallable, Category = Attributes)
70+
static void SetBase(UPARAM(ref) FDoubleAttr& Attribute, double Value) { Attribute.SetBaseValue(Value); }
71+
72+
/**
73+
* Adds a modifier to an attribute
74+
* @param Attribute to be modified
75+
* @param Modifier to apply to the attribute
76+
* @param Category of the modifier (Optional)
77+
*/
78+
UFUNCTION(BlueprintCallable, Category = Attributes, meta = (AdvancedDisplay = "Category"))
79+
static void AddModifier(UPARAM(ref) FDoubleAttr& Attribute, const FAttrModifier& Modifier, const FAttrCategory Category)
80+
{
81+
Attribute.AddModifier(Modifier, Category);
82+
}
83+
84+
/**
85+
* Removes a modifier from an attribute
86+
* @param Attribute to be modified
87+
* @param Modifier to remove from the attribute
88+
* @param Category of the modifier (Optional)
89+
* @return true if any modifier was removed
90+
*/
91+
UFUNCTION(BlueprintCallable, Category = Attributes, meta=(AdvancedDisplay="Category,bRemoveFromAllCategories"))
92+
static FORCEINLINE bool RemoveModifier(UPARAM(ref) FDoubleAttr& Attribute, const FAttrModifier& Modifier, const FAttrCategory Category, bool bRemoveFromAllCategories = false)
93+
{
94+
return Attribute.RemoveModifier(Modifier, Category, bRemoveFromAllCategories);
95+
}
96+
97+
/**
98+
* Get all modifiers of a category, base mods will be returned if category is None
99+
* @param Attribute to get modifiers from
100+
* @return Modifiers of a category as an Array
101+
*/
102+
UFUNCTION(BlueprintPure, Category = Attributes, meta = (AdvancedDisplay = "Category"))
103+
static void GetModifiers(const FDoubleAttr& Attribute, const FAttrCategory Category, TArray<FAttrModifier>& Modifiers)
104+
{
105+
Modifiers = Attribute.GetModifiers(Category);
106+
}
107+
108+
/**
109+
* Get all categories where the attribute has any modifiers
110+
* @param Attribute to get categories from
111+
* @return Categories of an attribute as an Array
112+
*/
113+
UFUNCTION(BlueprintPure, Category = Attributes)
114+
static void GetModifiedCategories(const FDoubleAttr& Attribute, TArray<FAttrCategory>& Categories)
115+
{
116+
Attribute.GetModifiedCategories(Categories);
117+
}
118+
119+
/**
120+
* Remove all modifiers of an attribute
121+
* @param Attribute to clean
122+
*/
123+
UFUNCTION(BlueprintCallable, Category = Attributes)
124+
static void CleanModifiers(UPARAM(ref) FDoubleAttr& Attribute)
125+
{
126+
return Attribute.CleanModifiers();
127+
}
128+
129+
UFUNCTION(BlueprintCallable, Category = Attributes, meta = (AdvancedDisplay = "Category"))
130+
static void CleanCategoryModifiers(UPARAM(ref) FDoubleAttr& Attribute, const FAttrCategory Category)
131+
{
132+
Attribute.CleanCategoryModifiers(Category);
133+
}
134+
135+
UFUNCTION(BlueprintCallable, Category = Attributes, meta = (AdvancedDisplay = "Category"))
136+
static void BindOnModified(UPARAM(ref) FDoubleAttr& Attribute, const FFloatModifiedDelegate& Event)
137+
{
138+
Attribute.GetOnModified().AddUnique(Event);
139+
}
140+
141+
UFUNCTION(BlueprintCallable, Category = Attributes, meta = (AdvancedDisplay = "Category"))
142+
static void UnbindOnModified(UPARAM(ref) FDoubleAttr& Attribute, const FFloatModifiedDelegate& Event)
143+
{
144+
Attribute.GetOnModified().Remove(Event);
145+
}
146+
147+
protected:
148+
149+
UFUNCTION(BlueprintPure, Category = Attributes)
150+
static void Make(double BaseValue, FDoubleAttr& DoubleAttr) { DoubleAttr = { BaseValue }; }
151+
152+
UFUNCTION(BlueprintPure, Category = Attributes)
153+
static void Break(const FDoubleAttr& DoubleAttr, double& BaseValue, double& Value) {
154+
BaseValue = DoubleAttr.GetBaseValue();
155+
Value = DoubleAttr.GetValue();
156+
}
157+
};

Source/Editor/Private/AttributesEditor.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <AssetToolsModule.h>
55

66
#include "Customizations/FloatAttrCustomization.h"
7+
#include "Customizations/DoubleAttrCustomization.h"
78
#include "Customizations/Int32AttrCustomization.h"
89
#include "Customizations/AttrModifierCustomization.h"
910
#include "Customizations/AttrCategoryCustomization.h"
@@ -51,6 +52,7 @@ void FAttributesEditorModule::ShutdownModule()
5152
void FAttributesEditorModule::RegisterPropertyTypeCustomizations()
5253
{
5354
RegisterCustomPropertyTypeLayout("FloatAttr", FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FFloatAttrCustomization::MakeInstance));
55+
RegisterCustomPropertyTypeLayout("DoubleAttr", FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FDoubleAttrCustomization::MakeInstance));
5456
RegisterCustomPropertyTypeLayout("Int32Attr", FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FInt32AttrCustomization::MakeInstance));
5557
RegisterCustomPropertyTypeLayout("AttrModifier", FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FAttrModifierCustomization::MakeInstance));
5658
RegisterCustomPropertyTypeLayout("AttrCategory", FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FAttrCategoryCustomization::MakeInstance));

0 commit comments

Comments
 (0)