Botcraft 26.2
Loading...
Searching...
No Matches
LivingEntity.cpp
Go to the documentation of this file.
3
4#include <mutex>
5
6namespace Botcraft
7{
8 const std::array<std::string, LivingEntity::metadata_count> LivingEntity::metadata_names{ {
9 "data_living_entity_flags",
10 "data_health_id",
11#if PROTOCOL_VERSION < 766 /* < 1.20.5 */
12 "data_effect_color_id",
13#else
14 "data_effect_particles",
15#endif
16 "data_effect_ambience_id",
17 "data_arrow_count_id",
18#if PROTOCOL_VERSION > 498 /* > 1.14.4 */
19 "data_stinger_count_id",
20#endif
21#if PROTOCOL_VERSION > 404 /* > 1.13.2 */
22 "sleeping_pos_id",
23#endif
24 } };
25
27 {
28 // Initialize all metadata with default values
30 SetDataHealthId(1.0f);
31#if PROTOCOL_VERSION < 766 /* < 1.20.5 */
32 SetDataEffectColorId(0);
33#else
35#endif
38#if PROTOCOL_VERSION > 498 /* > 1.14.4 */
40#endif
41#if PROTOCOL_VERSION > 404 /* > 1.13.2 */
42 SetSleepingPosId(std::optional<Position>());
43#endif
44
45 // Initialize all attributes with default values
51#if PROTOCOL_VERSION > 763 /* > 1.20.1 */
53#endif
54#if PROTOCOL_VERSION > 765 /* > 1.20.4 */
61#endif
62#if PROTOCOL_VERSION > 766 /* > 1.20.6 */
69#endif
70#if PROTOCOL_VERSION > 770 /* > 1.21.5 */
73#endif
74#if PROTOCOL_VERSION > 774 /* > 1.21.11 */
76#endif
77#if PROTOCOL_VERSION > 775 /* > 26.1.2 */
83#endif
84 }
85
90
92 {
93 return true;
94 }
95
96
98 {
100
101 output["metadata"]["data_living_entity_flags"] = GetDataLivingEntityFlags();
102 output["metadata"]["data_health_id"] = GetDataHealthId();
103#if PROTOCOL_VERSION < 766 /* < 1.20.5 */
104 output["metadata"]["data_effect_color_id"] = GetDataEffectColorId();
105#else
106 output["metadata"]["data_effect_particles"] = GetDataEffectParticles();
107#endif
108 output["metadata"]["data_effect_ambience_id"] = GetDataEffectAmbienceId();
109 output["metadata"]["data_arrow_count_id"] = GetDataArrowCountId();
110#if PROTOCOL_VERSION > 498 /* > 1.14.4 */
111 output["metadata"]["data_stinger_count_id"] = GetDataStingerCountId();
112#endif
113#if PROTOCOL_VERSION > 404 /* > 1.13.2 */
114 output["metadata"]["sleeping_pos_id"] = GetSleepingPosId() ? GetSleepingPosId().value().Serialize() : ProtocolCraft::Json::Value();
115#endif
116
117 output["attributes"] = ProtocolCraft::Json::Value();
118
119 output["attributes"]["max_health"] = GetAttributeMaxHealthValue();
120 output["attributes"]["knockback_resistance"] = GetAttributeKnockbackResistanceValue();
121 output["attributes"]["movement_speed"] = GetAttributeMovementSpeedValue();
122 output["attributes"]["armor"] = GetAttributeArmorValue();
123 output["attributes"]["armor_toughness"] = GetAttributeArmorToughnessValue();
124#if PROTOCOL_VERSION > 763 /* > 1.20.1 */
125 output["attributes"]["max_absorption"] = GetAttributeMaxAbsorptionValue();
126#endif
127#if PROTOCOL_VERSION > 765 /* > 1.20.4 */
128 output["attributes"]["step_height"] = GetAttributeStepHeightValue();
129 output["attributes"]["scale"] = GetAttributeScaleValue();
130 output["attributes"]["gravity"] = GetAttributeGravityValue();
131 output["attributes"]["safe_fall_distance"] = GetAttributeSafeFallDistanceValue();
132 output["attributes"]["fall_damage_multiplier"] = GetAttributeFallDamageMultiplierValue();
133 output["attributes"]["jump_strength"] = GetAttributeJumpStrengthValue();
134#endif
135#if PROTOCOL_VERSION > 766 /* > 1.20.6 */
136 output["attributes"]["oxygen_bonus"] = GetAttributeOxygenBonusValue();
137 output["attributes"]["burning_time"] = GetAttributeBurningTimeValue();
138 output["attributes"]["explosion_knockback_resistance"] = GetAttributeExplosionKnockbackResistanceValue();
139 output["attributes"]["water_movement_efficiency"] = GetAttributeWaterMovementEfficiencyValue();
140 output["attributes"]["movement_efficiency"] = GetAttributeMovementEfficiencyValue();
141 output["attributes"]["attack_knockback"] = GetAttributeAttackKnockbackValue();
142#endif
143#if PROTOCOL_VERSION > 770 /* > 1.21.5 */
144 output["attributes"]["camera_distance"] = GetAttributeCameraDistanceValue();
145 output["attributes"]["waypoint_transmit_range"] = GetAttributeWaypointTransmitRangeValue();
146#endif
147#if PROTOCOL_VERSION > 774 /* > 1.21.11 */
148 output["attributes"]["entity_interaction_range"] = GetAttributeEntityInteractionRangeValue();
149 output["attributes"]["entity_interaction_range"] = GetAttributeEntityInteractionRangeValue();
150#endif
151#if PROTOCOL_VERSION > 775 /* > 26.1.2 */
152 output["attributes"]["bounciness"] = GetAttributeBouncinessValue();
153 output["attributes"]["air_drag_modifier"] = GetAttributeAirDragModifierValue();
154 output["attributes"]["friction_modifier"] = GetAttributeFrictionModifierValue();
155 output["attributes"]["name_tag_distance"] = GetAttributeNameTagDistanceValue();
156 output["attributes"]["below_name_distance"] = GetAttributeBelowNameDistanceValue();
157
158#endif
159
160 return output;
161 }
162
163
164 void LivingEntity::SetMetadataValue(const int index, const std::any& value)
165 {
166 if (index < hierarchy_metadata_count)
167 {
168 Entity::SetMetadataValue(index, value);
169 }
170 else if (index - hierarchy_metadata_count < metadata_count)
171 {
172 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
174 }
175 }
176
178 {
179 std::shared_lock<std::shared_mutex> lock(entity_mutex);
181 }
182
184 {
185 std::shared_lock<std::shared_mutex> lock(entity_mutex);
186 return std::any_cast<float>(metadata.at("data_health_id"));
187 }
188
189#if PROTOCOL_VERSION < 766 /* < 1.20.5 */
190 int LivingEntity::GetDataEffectColorId() const
191 {
192 std::shared_lock<std::shared_mutex> lock(entity_mutex);
193 return std::any_cast<int>(metadata.at("data_effect_color_id"));
194 }
195#else
196 std::vector<ProtocolCraft::Particle> LivingEntity::GetDataEffectParticles() const
197 {
198 std::shared_lock<std::shared_mutex> lock(entity_mutex);
199 return std::any_cast<std::vector<ProtocolCraft::Particle>>(metadata.at("data_effect_particle"));
200 }
201#endif
202
204 {
205 std::shared_lock<std::shared_mutex> lock(entity_mutex);
206 return std::any_cast<bool>(metadata.at("data_effect_ambience_id"));
207 }
208
210 {
211 std::shared_lock<std::shared_mutex> lock(entity_mutex);
212 return std::any_cast<int>(metadata.at("data_arrow_count_id"));
213 }
214
215#if PROTOCOL_VERSION > 498 /* > 1.14.4 */
217 {
218 std::shared_lock<std::shared_mutex> lock(entity_mutex);
219 return std::any_cast<int>(metadata.at("data_stinger_count_id"));
220 }
221#endif
222
223#if PROTOCOL_VERSION > 404 /* > 1.13.2 */
224 std::optional<Position> LivingEntity::GetSleepingPosId() const
225 {
226 std::shared_lock<std::shared_mutex> lock(entity_mutex);
227 return GetSleepingPosIdImpl();
228 }
229#endif
230
231
232 void LivingEntity::SetDataLivingEntityFlags(const char data_living_entity_flags)
233 {
234 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
235 metadata["data_living_entity_flags"] = data_living_entity_flags;
236 }
237
238 void LivingEntity::SetDataHealthId(const float data_health_id)
239 {
240 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
241 metadata["data_health_id"] = data_health_id;
242 }
243
244#if PROTOCOL_VERSION < 766 /* < 1.20.5 */
245 void LivingEntity::SetDataEffectColorId(const int data_effect_color_id)
246 {
247 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
248 metadata["data_effect_color_id"] = data_effect_color_id;
249 }
250#else
251 void LivingEntity::SetDataEffectParticles(const std::vector<ProtocolCraft::Particle>& data_effect_particles)
252 {
253 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
254 metadata["data_effect_particles"] = data_effect_particles;
255 }
256#endif
257
258 void LivingEntity::SetDataEffectAmbienceId(const bool data_effect_ambience_id)
259 {
260 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
261 metadata["data_effect_ambience_id"] = data_effect_ambience_id;
262 }
263
264 void LivingEntity::SetDataArrowCountId(const int data_arrow_count_id)
265 {
266 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
267 metadata["data_arrow_count_id"] = data_arrow_count_id;
268 }
269
270#if PROTOCOL_VERSION > 498 /* > 1.14.4 */
271 void LivingEntity::SetDataStingerCountId(const int data_stinger_count_id)
272 {
273 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
274 metadata["data_stinger_count_id"] = data_stinger_count_id;
275 }
276#endif
277
278#if PROTOCOL_VERSION > 404 /* > 1.13.2 */
279 void LivingEntity::SetSleepingPosId(const std::optional<Position>& sleeping_pos_id)
280 {
281 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
282 metadata["sleeping_pos_id"] = sleeping_pos_id;
283 }
284#endif
285
286 std::optional<EntityAttribute> LivingEntity::GetAttribute(const EntityAttribute::Type type) const
287 {
288 std::shared_lock<std::shared_mutex> lock(entity_mutex);
289
290 auto it = attributes.find(type);
291 if (it == attributes.end())
292 {
293 return std::optional<EntityAttribute>();
294 }
295 return it->second;
296 }
297
299 {
300 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
301
302 auto it = attributes.find(type);
303 if (it == attributes.end())
304 {
305 LOG_WARNING("Trying to set attribute base value for " << type << " for a " << GetName() << " but it doesn't have this attribute");
306 return;
307 }
308 it->second.SetBaseValue(value);
309 }
310
312 {
313 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
315 }
316
318 {
319 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
320 SetAttributeModifierImpl(type, key, modifier);
321 }
322
324 {
325 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
326
327 auto it = attributes.find(type);
328 if (it == attributes.end())
329 {
330 return;
331 }
332 it->second.ClearModifiers();
333 }
334
336 {
337 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
338
339 auto it = attributes.find(attribute.GetType());
340 if (it == attributes.end())
341 {
342 LOG_WARNING("Trying to add an attribute " << attribute.GetType() << " to a " << GetName() << " but it was not present");
343 }
344 else
345 {
346 attributes.erase(it);
347 }
348 attributes.insert({ attribute.GetType(), attribute });
349 }
350
352 {
353 std::shared_lock<std::shared_mutex> lock(entity_mutex);
354 return attributes.at(EntityAttribute::Type::MaxHealth).GetValue();
355 }
356
358 {
359 std::shared_lock<std::shared_mutex> lock(entity_mutex);
361 }
362
364 {
365 std::shared_lock<std::shared_mutex> lock(entity_mutex);
367 }
368
370 {
371 std::shared_lock<std::shared_mutex> lock(entity_mutex);
372 return attributes.at(EntityAttribute::Type::Armor).GetValue();
373 }
374
376 {
377 std::shared_lock<std::shared_mutex> lock(entity_mutex);
379 }
380
381#if PROTOCOL_VERSION > 763 /* > 1.20.1 */
383 {
384 std::shared_lock<std::shared_mutex> lock(entity_mutex);
386 }
387#endif
388
393
394#if PROTOCOL_VERSION > 765 /* > 1.20.4 */
396 {
397 std::shared_lock<std::shared_mutex> lock(entity_mutex);
399 }
400
402 {
403 std::shared_lock<std::shared_mutex> lock(entity_mutex);
404 return attributes.at(EntityAttribute::Type::Scale).GetValue();
405 }
406
408 {
409 std::shared_lock<std::shared_mutex> lock(entity_mutex);
411 }
412
414 {
415 std::shared_lock<std::shared_mutex> lock(entity_mutex);
417 }
418
420 {
421 std::shared_lock<std::shared_mutex> lock(entity_mutex);
423 }
424
426 {
427 std::shared_lock<std::shared_mutex> lock(entity_mutex);
429 }
430#endif
431
432#if PROTOCOL_VERSION > 766 /* > 1.20.6 */
434 {
435 std::shared_lock<std::shared_mutex> lock(entity_mutex);
437 }
438
440 {
441 std::shared_lock<std::shared_mutex> lock(entity_mutex);
443 }
444
446 {
447 std::shared_lock<std::shared_mutex> lock(entity_mutex);
449 }
450
452 {
453 std::shared_lock<std::shared_mutex> lock(entity_mutex);
455 }
456
458 {
459 std::shared_lock<std::shared_mutex> lock(entity_mutex);
461 }
462
464 {
465 std::shared_lock<std::shared_mutex> lock(entity_mutex);
467 }
468#endif
469
470#if PROTOCOL_VERSION > 770 /* > 1.21.5 */
472 {
473 std::shared_lock<std::shared_mutex> lock(entity_mutex);
475 }
476
478 {
479 std::shared_lock<std::shared_mutex> lock(entity_mutex);
481 }
482#endif
483
484#if PROTOCOL_VERSION > 774 /* > 1.21.11 */
486 {
487 std::shared_lock<std::shared_mutex> lock(entity_mutex);
489 }
490#endif
491
492#if PROTOCOL_VERSION > 775 /* > 26.1.2 */
494 {
495 std::shared_lock<std::shared_mutex> lock(entity_mutex);
496 return attributes.at(EntityAttribute::Type::Bounciness).GetValue();
497 }
498
500 {
501 std::shared_lock<std::shared_mutex> lock(entity_mutex);
503 }
504
506 {
507 std::shared_lock<std::shared_mutex> lock(entity_mutex);
509 }
510
512 {
513 std::shared_lock<std::shared_mutex> lock(entity_mutex);
515 }
516
518 {
519 std::shared_lock<std::shared_mutex> lock(entity_mutex);
521 }
522#endif
523
525 {
526 auto it = attributes.find(type);
527 if (it == attributes.end())
528 {
529 return;
530 }
531 it->second.RemoveModifier(key);
532 }
533
535 {
536 auto it = attributes.find(type);
537 if (it == attributes.end())
538 {
539 LOG_WARNING("Trying to set attribute modifier for " << type << " for a " << GetName() << " but it doesn't have this attribute");
540 return;
541 }
542 it->second.SetModifier(key, modifier);
543 }
544
546 {
547 return std::any_cast<char>(metadata.at("data_living_entity_flags"));
548 }
549
550#if PROTOCOL_VERSION > 404 /* > 1.13.2 */
551 std::optional<Position> LivingEntity::GetSleepingPosIdImpl() const
552 {
553 return std::any_cast<std::optional<Position>>(metadata.at("sleeping_pos_id"));
554 }
555#endif
556
557#if PROTOCOL_VERSION > 765 /* > 1.20.4 */
562
564 {
565 return attributes.at(EntityAttribute::Type::Gravity).GetValue();
566 }
567
572#endif
573
574#if PROTOCOL_VERSION > 766 /* > 1.20.6 */
579
584#endif
585
586}
#define LOG_WARNING(osstream)
Definition Logger.hpp:44
virtual ProtocolCraft::Json::Value Serialize() const
Definition Entity.cpp:1245
virtual void SetMetadataValue(const int index, const std::any &value)
Definition Entity.cpp:772
std::shared_mutex entity_mutex
Definition Entity.hpp:270
virtual std::string GetName() const =0
std::map< std::string, std::any > metadata
Definition Entity.hpp:285
double GetAttributeGravityValueImpl() const
double GetAttributeMovementEfficiencyValueImpl() const
double GetAttributeFrictionModifierValue() const
char GetDataLivingEntityFlags() const
double GetAttributeStepHeightValueImpl() const
double GetAttributeExplosionKnockbackResistanceValue() const
double GetAttributeNameTagDistanceValue() const
double GetAttributeScaleValue() const
bool GetDataEffectAmbienceId() const
void RemoveAttributeModifier(const EntityAttribute::Type type, const EntityAttribute::ModifierKey &key)
double GetAttributeJumpStrengthValueImpl() const
void SetDataStingerCountId(const int data_stinger_count_id)
double GetAttributeMaxHealthValue() const
std::optional< Position > GetSleepingPosId() const
void SetAttributeModifierImpl(const EntityAttribute::Type type, const EntityAttribute::ModifierKey &key, const EntityAttribute::Modifier &modifier)
virtual bool IsLivingEntity() const override
double GetAttributeSafeFallDistanceValue() const
double GetAttributeOxygenBonusValue() const
void SetDataArrowCountId(const int data_arrow_count_id)
void ClearModifiers(const EntityAttribute::Type type)
static const std::array< std::string, metadata_count > metadata_names
double GetAttributeMaxAbsorptionValue() const
std::optional< Position > GetSleepingPosIdImpl() const
static constexpr int hierarchy_metadata_count
void SetAttributeModifier(const EntityAttribute::Type type, const EntityAttribute::ModifierKey &key, const EntityAttribute::Modifier &modifier)
void SetDataEffectAmbienceId(const bool data_effect_ambience_id)
int GetDataStingerCountId() const
std::map< EntityAttribute::Type, EntityAttribute > attributes
void SetDataLivingEntityFlags(const char data_living_entity_flags)
void RemoveAttributeModifierImpl(const EntityAttribute::Type type, const EntityAttribute::ModifierKey &key)
double GetAttributeJumpStrengthValue() const
void SetDataEffectParticles(const std::vector< ProtocolCraft::Particle > &data_effect_particles)
double GetAttributeMovementSpeedValueImpl() const
double GetAttributeMovementSpeedValue() const
void SetDataHealthId(const float data_health_id)
double GetAttributeWaterMovementEfficiencyValueImpl() const
double GetAttributeArmorToughnessValue() const
virtual ProtocolCraft::Json::Value Serialize() const override
static constexpr int metadata_count
double GetAttributeBurningTimeValue() const
char GetDataLivingEntityFlagsImpl() const
double GetAttributeGravityValue() const
int GetDataArrowCountId() const
double GetAttributeEntityInteractionRangeValue() const
double GetAttributeCameraDistanceValue() const
double GetAttributeArmorValue() const
double GetAttributeAirDragModifierValue() const
double GetAttributeStepHeightValue() const
double GetAttributeWaypointTransmitRangeValue() const
double GetAttributeBouncinessValue() const
void SetSleepingPosId(const std::optional< Position > &sleeping_pos_id)
double GetAttributeAttackKnockbackValue() const
double GetAttributeFallDamageMultiplierValue() const
double GetAttributeKnockbackResistanceValue() const
virtual void SetMetadataValue(const int index, const std::any &value) override
void AddAttribute(const EntityAttribute &attribute)
double GetAttributeMovementEfficiencyValue() const
float GetDataHealthId() const
double GetAttributeBelowNameDistanceValue() const
void SetAttributeBaseValue(const EntityAttribute::Type type, const double value)
std::vector< ProtocolCraft::Particle > GetDataEffectParticles() const
double GetAttributeWaterMovementEfficiencyValue() const
std::optional< EntityAttribute > GetAttribute(const EntityAttribute::Type type) const
Main class, basically a JsonVariant with extra utility functions it doesn't inherit JsonVariant direc...
Definition Json.hpp:45