Botcraft 1.21.4
Loading...
Searching...
No Matches
EntityAttribute.cpp
Go to the documentation of this file.
3
4namespace Botcraft
5{
6 EntityAttribute::EntityAttribute(const Type type_, const double base_value_)
7 {
8 type = type_;
9 base_value = base_value_;
11 up_to_date = false;
12 }
13
14 void EntityAttribute::SetBaseValue(const double new_value)
15 {
16 if (new_value == base_value)
17 {
18 return;
19 }
20 base_value = new_value;
21 up_to_date = false;
22 }
23
25 {
26 modifiers.clear();
27 up_to_date = false;
28 }
29
31 {
32 // If no element is removed, value is still up to date
33 up_to_date = modifiers.erase(key) > 0;
34 }
35
36 void EntityAttribute::SetModifier(const ModifierKey& key, const Modifier& modifier)
37 {
38 modifiers[key] = modifier;
39 up_to_date = false;
40 }
41
46
48 {
49 return base_value;
50 }
51
52 const std::map<EntityAttribute::ModifierKey, EntityAttribute::Modifier>& EntityAttribute::GetModifiers() const
53 {
54 return modifiers;
55 }
56
58 {
59 if (!up_to_date)
60 {
62 }
63 return current_value;
64 }
65
66 std::optional<EntityAttribute::Modifier> EntityAttribute::GetModifier(const ModifierKey& key)
67 {
68 auto it = modifiers.find(key);
69 if (it == modifiers.end())
70 {
71 return std::optional<Modifier>();
72 }
73 return it->second;
74 }
75
76#if PROTOCOL_VERSION < 766 /* < 1.20.4 */
77 std::string EntityAttribute::TypeToString(const Type type)
78 {
79 switch (type)
80 {
81#if PROTOCOL_VERSION < 735 /* < 1.16 */
82 case Type::MaxHealth:
83 return "generic.maxHealth";
85 return "generic.followRange";
87 return "generic.knockbackResistance";
89 return "generic.movementSpeed";
91 return "generic.flyingSpeed";
93 return "generic.attackDamage";
94#if PROTOCOL_VERSION > 404 /* > 1.13.2 */
96 return "generic.attackKnockback";
97#endif
99 return "generic.attackSpeed";
100 case Type::Armor:
101 return "generic.armor";
103 return "generic.armorToughness";
104 case Type::Luck:
105 return "generic.luck";
107 return "zombie.spawnReinforcements";
108 case Type::HorseJumpStrength:
109 return "horse.jumpStrength";
110#else
111 case Type::MaxHealth:
112 return "minecraft:generic.max_health";
114 return "minecraft:generic.follow_range";
116 return "minecraft:generic.knockback_resistance";
118 return "minecraft:generic.movement_speed";
120 return "minecraft:generic.flying_speed";
122 return "minecraft:generic.attack_damage";
124 return "minecraft:generic.attack_knockback";
126 return "minecraft:generic.attack_speed";
127 case Type::Armor:
128 return "minecraft:generic.armor";
130 return "minecraft:generic.armor_toughness";
131 case Type::Luck:
132 return "minecraft:generic.luck";
133#if PROTOCOL_VERSION > 763 /* > 1.20.1 */
135 return "minecraft:generic.max_absorption";
136#endif
138 return "minecraft:zombie.spawn_reinforcements";
139 case Type::HorseJumpStrength:
140 return "minecraft:horse.jump_strength";
141#endif
142 default:
143 return "";
144 }
145 }
146
147 EntityAttribute::Type EntityAttribute::StringToType(const std::string& s)
148 {
149
150#if PROTOCOL_VERSION < 735 /* < 1.16 */
151 if (s == "generic.maxHealth")
152 {
154 }
155 if (s == "generic.followRange")
156 {
158 }
159 if (s == "generic.knockbackResistance")
160 {
162 }
163 if (s == "generic.movementSpeed")
164 {
166 }
167 if (s == "generic.flyingSpeed")
168 {
170 }
171 if (s == "generic.attackDamage")
172 {
174 }
175#if PROTOCOL_VERSION > 404 /* > 1.13.2 */
176 if (s == "generic.attackKnockback")
177 {
179 }
180#endif
181 if (s == "generic.attackSpeed")
182 {
184 }
185 if (s == "generic.armor")
186 {
188 }
189 if (s == "generic.armorToughness")
190 {
192 }
193 if (s == "generic.luck")
194 {
196 }
197 if (s == "zombie.spawnReinforcements")
198 {
200 }
201 if (s == "horse.jumpStrength")
202 {
203 return Type::HorseJumpStrength;
204 }
205#else
206 if (s == "minecraft:generic.max_health")
207 {
208 return Type::MaxHealth;
209 }
210 if (s == "minecraft:generic.follow_range")
211 {
212 return Type::FollowRange;
213 }
214 if (s == "minecraft:generic.knockback_resistance")
215 {
217 }
218 if (s == "minecraft:generic.movement_speed")
219 {
220 return Type::MovementSpeed;
221 }
222 if (s == "minecraft:generic.flying_speed")
223 {
224 return Type::FlyingSpeed;
225 }
226 if (s == "minecraft:generic.attack_damage")
227 {
228 return Type::AttackDamage;
229 }
230 if (s == "minecraft:generic.attack_knockback")
231 {
233 }
234 if (s == "minecraft:generic.attack_speed")
235 {
236 return Type::AttackSpeed;
237 }
238 if (s == "minecraft:generic.armor")
239 {
240 return Type::Armor;
241 }
242 if (s == "minecraft:generic.armor_toughness")
243 {
245 }
246 if (s == "minecraft:generic.luck")
247 {
248 return Type::Luck;
249 }
250#if PROTOCOL_VERSION > 763 /* > 1.20.1 */
251 if (s == "minecraft:generic.max_absorption")
252 {
253 return Type::MaxAbsorption;
254 }
255#endif
256 if (s == "minecraft:zombie.spawn_reinforcements")
257 {
259 }
260 if (s == "minecraft:horse.jump_strength")
261 {
262 return Type::HorseJumpStrength;
263 }
264#endif
265 return Type::Unknown;
266 }
267#endif
268
270 {
272 for (const auto& [uuid, m] : modifiers)
273 {
274 if (m.operation != Modifier::Operation::Add)
275 {
276 continue;
277 }
278 current_value += m.amount;
279 }
280
281 double current_mult = 1.0;
282 for (const auto& [uuid, m] : modifiers)
283 {
284 if (m.operation != Modifier::Operation::MultiplyBase)
285 {
286 continue;
287 }
288 current_mult += m.amount;
289 }
290 current_value *= current_mult;
291
292 for (const auto& [uuid, m] : modifiers)
293 {
294 if (m.operation != Modifier::Operation::MultiplyTotal)
295 {
296 continue;
297 }
298 current_value *= (1.0 + m.amount);
299 }
300
301 switch (type)
302 {
303 case Type::MaxHealth:
304 current_value = std::clamp(current_value, 1.0, 1024.0);
305 break;
307 current_value = std::clamp(current_value, 0.0, 2048.0);
308 break;
310 current_value = std::clamp(current_value, 0.0, 1.0);
311 break;
313 current_value = std::clamp(current_value, 0.0, 1024.0);
314 break;
316 current_value = std::clamp(current_value, 0.0, 1024.0);
317 break;
319 current_value = std::clamp(current_value, 0.0, 2048.0);
320 break;
321#if PROTOCOL_VERSION > 404 /* > 1.13.2 */
323 current_value = std::clamp(current_value, 0.0, 5.0);
324 break;
325#endif
327 current_value = std::clamp(current_value, 0.0, 1024.0);
328 break;
329 case Type::Armor:
330 current_value = std::clamp(current_value, 0.0, 30.0);
331 break;
333 current_value = std::clamp(current_value, 0.0, 20.0);
334 break;
335 case Type::Luck:
336 current_value = std::clamp(current_value, -1024.0, 1024.0);
337 break;
338#if PROTOCOL_VERSION > 763 /* > 1.20.1 */
340 current_value = std::clamp(current_value, 0.0, 2048.0);
341 break;
342#endif
344 current_value = std::clamp(current_value, 0.0, 1.0);
345 break;
346#if PROTOCOL_VERSION < 766 /* < 1.20.5 */
347 case Type::HorseJumpStrength:
348 current_value = std::clamp(current_value, 0.0, 2.0);
349 break;
350#endif
351#if PROTOCOL_VERSION > 765 /* > 1.20.4 */
353 current_value = std::clamp(current_value, 0.0, 1024.0);
354 break;
356 current_value = std::clamp(current_value, 0.0, 64.0);
357 break;
359 current_value = std::clamp(current_value, 0.0, 64.0);
360 break;
362 current_value = std::clamp(current_value, 0.0, 100.0);
363 break;
364 case Type::Gravity:
365 current_value = std::clamp(current_value, -1.0, 1.0);
366 break;
368 current_value = std::clamp(current_value, 0.0, 32.0);
369 break;
371 current_value = std::clamp(current_value, -1024.0, 1024.0);
372 break;
373 case Type::Scale:
374 current_value = std::clamp(current_value, 0.0625, 16.0);
375 break;
376 case Type::StepHeight:
377 current_value = std::clamp(current_value, 0.0, 10.0);
378 break;
379#endif
380#if PROTOCOL_VERSION > 766 /* > 1.20.6 */
382 current_value = std::clamp(current_value, 0.0, 1024.0);
383 break;
385 current_value = std::clamp(current_value, 0.0, 1.0);
386 break;
388 current_value = std::clamp(current_value, 0.0, 1024.0);
389 break;
391 current_value = std::clamp(current_value, 0.0, 1.0);
392 break;
394 current_value = std::clamp(current_value, 0.0, 1024.0);
395 break;
397 current_value = std::clamp(current_value, 0.0, 1.0);
398 break;
400 current_value = std::clamp(current_value, 0.0, 20.0);
401 break;
403 current_value = std::clamp(current_value, 0.0, 1.0);
404 break;
406 current_value = std::clamp(current_value, 0.0, 1.0);
407 break;
408#endif
409#if PROTOCOL_VERSION > 767 /* > 1.21.1 */
410 case Type::TemptRange:
411 current_value = std::clamp(current_value, 0.0, 2048.0);
412 break;
413#endif
414 default:
415 // No min or max value in case of Unknown attribute
416 break;
417 }
418
419 up_to_date = true;
420 }
421
423}
#define DEFINE_ENUM_STRINGIFYER_RANGE(Enum, min_value, max_value)
void RemoveModifier(const ModifierKey &key)
const std::map< ModifierKey, Modifier > & GetModifiers() const
std::optional< Modifier > GetModifier(const ModifierKey &key)
void SetBaseValue(const double new_value)
void SetModifier(const ModifierKey &key, const Modifier &modifier)
std::map< ModifierKey, Modifier > modifiers