Botcraft 26.1.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 }
78
83
85 {
86 return true;
87 }
88
89
91 {
93
94 output["metadata"]["data_living_entity_flags"] = GetDataLivingEntityFlags();
95 output["metadata"]["data_health_id"] = GetDataHealthId();
96#if PROTOCOL_VERSION < 766 /* < 1.20.5 */
97 output["metadata"]["data_effect_color_id"] = GetDataEffectColorId();
98#else
99 output["metadata"]["data_effect_particles"] = GetDataEffectParticles();
100#endif
101 output["metadata"]["data_effect_ambience_id"] = GetDataEffectAmbienceId();
102 output["metadata"]["data_arrow_count_id"] = GetDataArrowCountId();
103#if PROTOCOL_VERSION > 498 /* > 1.14.4 */
104 output["metadata"]["data_stinger_count_id"] = GetDataStingerCountId();
105#endif
106#if PROTOCOL_VERSION > 404 /* > 1.13.2 */
107 output["metadata"]["sleeping_pos_id"] = GetSleepingPosId() ? GetSleepingPosId().value().Serialize() : ProtocolCraft::Json::Value();
108#endif
109
110 output["attributes"] = ProtocolCraft::Json::Value();
111
112 output["attributes"]["max_health"] = GetAttributeMaxHealthValue();
113 output["attributes"]["knockback_resistance"] = GetAttributeKnockbackResistanceValue();
114 output["attributes"]["movement_speed"] = GetAttributeMovementSpeedValue();
115 output["attributes"]["armor"] = GetAttributeArmorValue();
116 output["attributes"]["armor_toughness"] = GetAttributeArmorToughnessValue();
117#if PROTOCOL_VERSION > 763 /* > 1.20.1 */
118 output["attributes"]["max_absorption"] = GetAttributeMaxAbsorptionValue();
119#endif
120#if PROTOCOL_VERSION > 765 /* > 1.20.4 */
121 output["attributes"]["step_height"] = GetAttributeStepHeightValue();
122 output["attributes"]["scale"] = GetAttributeScaleValue();
123 output["attributes"]["gravity"] = GetAttributeGravityValue();
124 output["attributes"]["safe_fall_distance"] = GetAttributeSafeFallDistanceValue();
125 output["attributes"]["fall_damage_multiplier"] = GetAttributeFallDamageMultiplierValue();
126 output["attributes"]["jump_strength"] = GetAttributeJumpStrengthValue();
127#endif
128#if PROTOCOL_VERSION > 766 /* > 1.20.6 */
129 output["attributes"]["oxygen_bonus"] = GetAttributeOxygenBonusValue();
130 output["attributes"]["burning_time"] = GetAttributeBurningTimeValue();
131 output["attributes"]["explosion_knockback_resistance"] = GetAttributeExplosionKnockbackResistanceValue();
132 output["attributes"]["water_movement_efficiency"] = GetAttributeWaterMovementEfficiencyValue();
133 output["attributes"]["movement_efficiency"] = GetAttributeMovementEfficiencyValue();
134 output["attributes"]["attack_knockback"] = GetAttributeAttackKnockbackValue();
135#endif
136#if PROTOCOL_VERSION > 770 /* > 1.21.5 */
137 output["attributes"]["camera_distance"] = GetAttributeCameraDistanceValue();
138 output["attributes"]["waypoint_transmit_range"] = GetAttributeWaypointTransmitRangeValue();
139#endif
140#if PROTOCOL_VERSION > 774 /* > 1.21.11 */
141 output["attributes"]["entity_interaction_range"] = GetAttributeEntityInteractionRangeValue();
142#endif
143
144 return output;
145 }
146
147
148 void LivingEntity::SetMetadataValue(const int index, const std::any& value)
149 {
150 if (index < hierarchy_metadata_count)
151 {
152 Entity::SetMetadataValue(index, value);
153 }
154 else if (index - hierarchy_metadata_count < metadata_count)
155 {
156 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
158 }
159 }
160
162 {
163 std::shared_lock<std::shared_mutex> lock(entity_mutex);
165 }
166
168 {
169 std::shared_lock<std::shared_mutex> lock(entity_mutex);
170 return std::any_cast<float>(metadata.at("data_health_id"));
171 }
172
173#if PROTOCOL_VERSION < 766 /* < 1.20.5 */
174 int LivingEntity::GetDataEffectColorId() const
175 {
176 std::shared_lock<std::shared_mutex> lock(entity_mutex);
177 return std::any_cast<int>(metadata.at("data_effect_color_id"));
178 }
179#else
180 std::vector<ProtocolCraft::Particle> LivingEntity::GetDataEffectParticles() const
181 {
182 std::shared_lock<std::shared_mutex> lock(entity_mutex);
183 return std::any_cast<std::vector<ProtocolCraft::Particle>>(metadata.at("data_effect_particle"));
184 }
185#endif
186
188 {
189 std::shared_lock<std::shared_mutex> lock(entity_mutex);
190 return std::any_cast<bool>(metadata.at("data_effect_ambience_id"));
191 }
192
194 {
195 std::shared_lock<std::shared_mutex> lock(entity_mutex);
196 return std::any_cast<int>(metadata.at("data_arrow_count_id"));
197 }
198
199#if PROTOCOL_VERSION > 498 /* > 1.14.4 */
201 {
202 std::shared_lock<std::shared_mutex> lock(entity_mutex);
203 return std::any_cast<int>(metadata.at("data_stinger_count_id"));
204 }
205#endif
206
207#if PROTOCOL_VERSION > 404 /* > 1.13.2 */
208 std::optional<Position> LivingEntity::GetSleepingPosId() const
209 {
210 std::shared_lock<std::shared_mutex> lock(entity_mutex);
211 return GetSleepingPosIdImpl();
212 }
213#endif
214
215
216 void LivingEntity::SetDataLivingEntityFlags(const char data_living_entity_flags)
217 {
218 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
219 metadata["data_living_entity_flags"] = data_living_entity_flags;
220 }
221
222 void LivingEntity::SetDataHealthId(const float data_health_id)
223 {
224 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
225 metadata["data_health_id"] = data_health_id;
226 }
227
228#if PROTOCOL_VERSION < 766 /* < 1.20.5 */
229 void LivingEntity::SetDataEffectColorId(const int data_effect_color_id)
230 {
231 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
232 metadata["data_effect_color_id"] = data_effect_color_id;
233 }
234#else
235 void LivingEntity::SetDataEffectParticles(const std::vector<ProtocolCraft::Particle>& data_effect_particles)
236 {
237 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
238 metadata["data_effect_particles"] = data_effect_particles;
239 }
240#endif
241
242 void LivingEntity::SetDataEffectAmbienceId(const bool data_effect_ambience_id)
243 {
244 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
245 metadata["data_effect_ambience_id"] = data_effect_ambience_id;
246 }
247
248 void LivingEntity::SetDataArrowCountId(const int data_arrow_count_id)
249 {
250 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
251 metadata["data_arrow_count_id"] = data_arrow_count_id;
252 }
253
254#if PROTOCOL_VERSION > 498 /* > 1.14.4 */
255 void LivingEntity::SetDataStingerCountId(const int data_stinger_count_id)
256 {
257 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
258 metadata["data_stinger_count_id"] = data_stinger_count_id;
259 }
260#endif
261
262#if PROTOCOL_VERSION > 404 /* > 1.13.2 */
263 void LivingEntity::SetSleepingPosId(const std::optional<Position>& sleeping_pos_id)
264 {
265 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
266 metadata["sleeping_pos_id"] = sleeping_pos_id;
267 }
268#endif
269
270 std::optional<EntityAttribute> LivingEntity::GetAttribute(const EntityAttribute::Type type) const
271 {
272 std::shared_lock<std::shared_mutex> lock(entity_mutex);
273
274 auto it = attributes.find(type);
275 if (it == attributes.end())
276 {
277 return std::optional<EntityAttribute>();
278 }
279 return it->second;
280 }
281
283 {
284 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
285
286 auto it = attributes.find(type);
287 if (it == attributes.end())
288 {
289 LOG_WARNING("Trying to set attribute base value for " << type << " for a " << GetName() << " but it doesn't have this attribute");
290 return;
291 }
292 it->second.SetBaseValue(value);
293 }
294
296 {
297 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
299 }
300
302 {
303 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
304 SetAttributeModifierImpl(type, key, modifier);
305 }
306
308 {
309 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
310
311 auto it = attributes.find(type);
312 if (it == attributes.end())
313 {
314 return;
315 }
316 it->second.ClearModifiers();
317 }
318
320 {
321 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
322
323 auto it = attributes.find(attribute.GetType());
324 if (it == attributes.end())
325 {
326 LOG_WARNING("Trying to add an attribute " << attribute.GetType() << " to a " << GetName() << " but it was not present");
327 }
328 else
329 {
330 attributes.erase(it);
331 }
332 attributes.insert({ attribute.GetType(), attribute });
333 }
334
336 {
337 std::shared_lock<std::shared_mutex> lock(entity_mutex);
338 return attributes.at(EntityAttribute::Type::MaxHealth).GetValue();
339 }
340
342 {
343 std::shared_lock<std::shared_mutex> lock(entity_mutex);
345 }
346
348 {
349 std::shared_lock<std::shared_mutex> lock(entity_mutex);
351 }
352
354 {
355 std::shared_lock<std::shared_mutex> lock(entity_mutex);
356 return attributes.at(EntityAttribute::Type::Armor).GetValue();
357 }
358
360 {
361 std::shared_lock<std::shared_mutex> lock(entity_mutex);
363 }
364
365#if PROTOCOL_VERSION > 763 /* > 1.20.1 */
367 {
368 std::shared_lock<std::shared_mutex> lock(entity_mutex);
370 }
371#endif
372
377
378#if PROTOCOL_VERSION > 765 /* > 1.20.4 */
380 {
381 std::shared_lock<std::shared_mutex> lock(entity_mutex);
383 }
384
386 {
387 std::shared_lock<std::shared_mutex> lock(entity_mutex);
388 return attributes.at(EntityAttribute::Type::Scale).GetValue();
389 }
390
392 {
393 std::shared_lock<std::shared_mutex> lock(entity_mutex);
395 }
396
398 {
399 std::shared_lock<std::shared_mutex> lock(entity_mutex);
401 }
402
404 {
405 std::shared_lock<std::shared_mutex> lock(entity_mutex);
407 }
408
410 {
411 std::shared_lock<std::shared_mutex> lock(entity_mutex);
413 }
414#endif
415
416#if PROTOCOL_VERSION > 766 /* > 1.20.6 */
418 {
419 std::shared_lock<std::shared_mutex> lock(entity_mutex);
421 }
422
424 {
425 std::shared_lock<std::shared_mutex> lock(entity_mutex);
427 }
428
430 {
431 std::shared_lock<std::shared_mutex> lock(entity_mutex);
433 }
434
436 {
437 std::shared_lock<std::shared_mutex> lock(entity_mutex);
439 }
440
442 {
443 std::shared_lock<std::shared_mutex> lock(entity_mutex);
445 }
446
448 {
449 std::shared_lock<std::shared_mutex> lock(entity_mutex);
451 }
452#endif
453
454#if PROTOCOL_VERSION > 770 /* > 1.21.5 */
456 {
457 std::shared_lock<std::shared_mutex> lock(entity_mutex);
459 }
460
462 {
463 std::shared_lock<std::shared_mutex> lock(entity_mutex);
465 }
466#endif
467
468#if PROTOCOL_VERSION > 774 /* > 1.21.11 */
470 {
471 std::shared_lock<std::shared_mutex> lock(entity_mutex);
473 }
474#endif
475
477 {
478 auto it = attributes.find(type);
479 if (it == attributes.end())
480 {
481 return;
482 }
483 it->second.RemoveModifier(key);
484 }
485
487 {
488 auto it = attributes.find(type);
489 if (it == attributes.end())
490 {
491 LOG_WARNING("Trying to set attribute modifier for " << type << " for a " << GetName() << " but it doesn't have this attribute");
492 return;
493 }
494 it->second.SetModifier(key, modifier);
495 }
496
498 {
499 return std::any_cast<char>(metadata.at("data_living_entity_flags"));
500 }
501
502#if PROTOCOL_VERSION > 404 /* > 1.13.2 */
503 std::optional<Position> LivingEntity::GetSleepingPosIdImpl() const
504 {
505 return std::any_cast<std::optional<Position>>(metadata.at("sleeping_pos_id"));
506 }
507#endif
508
509#if PROTOCOL_VERSION > 765 /* > 1.20.4 */
514
516 {
517 return attributes.at(EntityAttribute::Type::Gravity).GetValue();
518 }
519
524#endif
525
526#if PROTOCOL_VERSION > 766 /* > 1.20.6 */
531
536#endif
537
538}
#define LOG_WARNING(osstream)
Definition Logger.hpp:44
virtual ProtocolCraft::Json::Value Serialize() const
Definition Entity.cpp:1242
virtual void SetMetadataValue(const int index, const std::any &value)
Definition Entity.cpp:769
std::shared_mutex entity_mutex
Definition Entity.hpp:267
virtual std::string GetName() const =0
std::map< std::string, std::any > metadata
Definition Entity.hpp:282
double GetAttributeGravityValueImpl() const
double GetAttributeMovementEfficiencyValueImpl() const
char GetDataLivingEntityFlags() const
double GetAttributeStepHeightValueImpl() const
double GetAttributeExplosionKnockbackResistanceValue() 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 GetAttributeStepHeightValue() const
double GetAttributeWaypointTransmitRangeValue() 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
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