1+ // Copyright 2015-2019 Piperift. All Rights Reserved.
2+
3+ #include " BaseAttr.h"
4+ #include " AttributesModule.h"
5+
6+
7+ uint32 FBaseAttr::IdCount{ 0 };
8+
9+
10+ void FBaseAttr::AddModifier (const FAttrModifier& Modifier, const FAttrCategory& Category)
11+ {
12+ if (Category == FAttrCategory::NoCategory)
13+ {
14+ BaseModifiers.Add (Modifier);
15+ }
16+ else if (!Category.IsNone ())
17+ {
18+ int32 Index = CategoryMods.IndexOfByKey (Category);
19+ if (Index == INDEX_NONE)
20+ {
21+ // Add category if non existent
22+ Index = CategoryMods.HeapPush ({ Category });
23+ }
24+
25+ CategoryMods[Index].Modifiers .Add (Modifier);
26+ }
27+ else
28+ {
29+ UE_LOG (LogAttributes, Warning, TEXT (" Attributes: tried to add a modifier to the unexisting category '%s'" ), *Category.Name .ToString ());
30+ return ;
31+ }
32+
33+ RefreshValue ();
34+ OnModified.Broadcast (EAttributeOperation::Add, Modifier, Category);
35+ }
36+
37+ bool FBaseAttr::RemoveModifier (const FAttrModifier& Modifier, const FAttrCategory& Category, bool bRemoveFromAllCategories)
38+ {
39+ bool bChanged = false ;
40+
41+ if (bRemoveFromAllCategories)
42+ {
43+ // Remove possible modifiers from all categories
44+ bChanged = BaseModifiers.Remove (Modifier) > 0 ;
45+
46+ for (int32 CatId = 0 ; CatId < CategoryMods.Num (); ++CatId)
47+ {
48+ FAttributeCategoryMods& CategoryMod = CategoryMods[CatId];
49+
50+ bChanged = CategoryMod.Modifiers .Remove (Modifier) > 0 || bChanged;
51+
52+ if (CategoryMod.Modifiers .Num () <= 0 )
53+ {
54+ // Remove category if empty
55+ CategoryMods.HeapRemoveAt (CatId);
56+
57+ // Reduce Id, because current one doesn't exist anymore
58+ --CatId;
59+ }
60+ }
61+ }
62+ else if (Category == FAttrCategory::NoCategory)
63+ {
64+ // Remove modifier from base modifiers
65+ bChanged = BaseModifiers.Remove (Modifier) > 0 ;
66+ }
67+ else
68+ {
69+ // Remove modifier from a category
70+ int32 Index = CategoryMods.IndexOfByKey (Category);
71+ if (Index != INDEX_NONE)
72+ {
73+ FAttributeCategoryMods& CategoryMod = CategoryMods[Index];
74+ bChanged = CategoryMod.Modifiers .Remove (Modifier) > 0 ;
75+
76+ if (CategoryMod.Modifiers .Num () <= 0 )
77+ {
78+ // Remove category if empty
79+ CategoryMods.HeapRemoveAt (Index);
80+ }
81+ }
82+ else
83+ {
84+ UE_LOG (LogAttributes, Warning, TEXT (" Attributes: Tried to remove with modifier category '%s', but it doesnt exist on the attribute" ), *Category.Name .ToString ());
85+ return false ;
86+ }
87+ }
88+
89+ if (bChanged)
90+ {
91+ RefreshValue ();
92+ OnModified.Broadcast (EAttributeOperation::Remove, Modifier, Category);
93+ }
94+ return bChanged;
95+ }
96+
97+ const TArray<FAttrModifier>& FBaseAttr::GetModifiers (const FAttrCategory Category) const
98+ {
99+ int32 Index = CategoryMods.IndexOfByKey (Category);
100+ if (Index != INDEX_NONE)
101+ {
102+ return CategoryMods[Index].Modifiers ;
103+ }
104+ return BaseModifiers;
105+ }
106+
107+ void FBaseAttr::GetModifiedCategories (TArray<FAttrCategory>& OutCategories) const
108+ {
109+ if (BaseModifiers.Num () > 0 )
110+ {
111+ OutCategories.Reserve (CategoryMods.Num () + 1 );
112+ OutCategories.Add (FAttrCategory::NoCategory);
113+ }
114+ else
115+ {
116+ OutCategories.Reserve (CategoryMods.Num ());
117+ }
118+
119+ for (const auto & CategoryMod : CategoryMods)
120+ {
121+ OutCategories.Add (CategoryMod.Category );
122+ }
123+ }
124+
125+ void FBaseAttr::CleanCategoryModifiers (const FAttrCategory& Category)
126+ {
127+ if (Category.IsNone ())
128+ {
129+ if (BaseModifiers.Num () > 0 )
130+ {
131+ BaseModifiers.Empty ();
132+
133+ // Notify
134+ RefreshValue ();
135+ OnModified.Broadcast (EAttributeOperation::RemoveCategory, {}, Category);
136+ }
137+ }
138+ else
139+ {
140+ int32 Index = CategoryMods.IndexOfByKey (Category);
141+ if (Index != INDEX_NONE)
142+ {
143+ // Remove category if empty
144+ CategoryMods.HeapRemoveAt (Index);
145+
146+ // Notify
147+ RefreshValue ();
148+ OnModified.Broadcast (EAttributeOperation::RemoveCategory, {}, Category);
149+ }
150+ else
151+ {
152+ UE_LOG (LogAttributes, Warning, TEXT (" Attributes: Tried to remove all modifiers of category '%s', but it didnt exist on the attribute" ), *Category.Name .ToString ());
153+ return ;
154+ }
155+ }
156+ }
157+
158+ void FBaseAttr::CleanModifiers ()
159+ {
160+ // Is there any modifier at all?
161+ if (BaseModifiers.Num () > 0 || CategoryMods.Num () > 0 )
162+ {
163+ BaseModifiers.Empty ();
164+ CategoryMods.Empty ();
165+
166+ RefreshValue ();
167+ OnModified.Broadcast (EAttributeOperation::RemoveAll, {}, FAttrCategory::NoCategory);
168+ }
169+ }
0 commit comments