Botcraft 1.21.8
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 }
75
80
82 {
83 return true;
84 }
85
86
88 {
90
91 output["metadata"]["data_living_entity_flags"] = GetDataLivingEntityFlags();
92 output["metadata"]["data_health_id"] = GetDataHealthId();
93#if PROTOCOL_VERSION < 766 /* < 1.20.5 */
94 output["metadata"]["data_effect_color_id"] = GetDataEffectColorId();
95#else
96 output["metadata"]["data_effect_particles"] = GetDataEffectParticles();
97#endif
98 output["metadata"]["data_effect_ambience_id"] = GetDataEffectAmbienceId();
99 output["metadata"]["data_arrow_count_id"] = GetDataArrowCountId();
100#if PROTOCOL_VERSION > 498 /* > 1.14.4 */
101 output["metadata"]["data_stinger_count_id"] = GetDataStingerCountId();
102#endif
103#if PROTOCOL_VERSION > 404 /* > 1.13.2 */
104 output["metadata"]["sleeping_pos_id"] = GetSleepingPosId() ? GetSleepingPosId().value().Serialize() : ProtocolCraft::Json::Value();
105#endif
106
107 output["attributes"] = ProtocolCraft::Json::Value();
108
109 output["attributes"]["max_health"] = GetAttributeMaxHealthValue();
110 output["attributes"]["knockback_resistance"] = GetAttributeKnockbackResistanceValue();
111 output["attributes"]["movement_speed"] = GetAttributeMovementSpeedValue();
112 output["attributes"]["armor"] = GetAttributeArmorValue();
113 output["attributes"]["armor_toughness"] = GetAttributeArmorToughnessValue();
114#if PROTOCOL_VERSION > 763 /* > 1.20.1 */
115 output["attributes"]["max_absorption"] = GetAttributeMaxAbsorptionValue();
116#endif
117#if PROTOCOL_VERSION > 765 /* > 1.20.4 */
118 output["attributes"]["step_height"] = GetAttributeStepHeightValue();
119 output["attributes"]["scale"] = GetAttributeScaleValue();
120 output["attributes"]["gravity"] = GetAttributeGravityValue();
121 output["attributes"]["safe_fall_distance"] = GetAttributeSafeFallDistanceValue();
122 output["attributes"]["fall_damage_multiplier"] = GetAttributeFallDamageMultiplierValue();
123 output["attributes"]["jump_strength"] = GetAttributeJumpStrengthValue();
124#endif
125#if PROTOCOL_VERSION > 766 /* > 1.20.6 */
126 output["attributes"]["oxygen_bonus"] = GetAttributeOxygenBonusValue();
127 output["attributes"]["burning_time"] = GetAttributeBurningTimeValue();
128 output["attributes"]["explosion_knockback_resistance"] = GetAttributeExplosionKnockbackResistanceValue();
129 output["attributes"]["water_movement_efficiency"] = GetAttributeWaterMovementEfficiencyValue();
130 output["attributes"]["movement_efficiency"] = GetAttributeMovementEfficiencyValue();
131 output["attributes"]["attack_knockback"] = GetAttributeAttackKnockbackValue();
132#endif
133#if PROTOCOL_VERSION > 770 /* > 1.21.5 */
134 output["attributes"]["camera_distance"] = GetAttributeCameraDistanceValue();
135 output["attributes"]["waypoint_transmit_range"] = GetAttributeWaypointTransmitRangeValue();
136#endif
137
138 return output;
139 }
140
141
142 void LivingEntity::SetMetadataValue(const int index, const std::any& value)
143 {
144 if (index < hierarchy_metadata_count)
145 {
146 Entity::SetMetadataValue(index, value);
147 }
148 else if (index - hierarchy_metadata_count < metadata_count)
149 {
150 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
152 }
153 }
154
156 {
157 std::shared_lock<std::shared_mutex> lock(entity_mutex);
159 }
160
162 {
163 std::shared_lock<std::shared_mutex> lock(entity_mutex);
164 return std::any_cast<float>(metadata.at("data_health_id"));
165 }
166
167#if PROTOCOL_VERSION < 766 /* < 1.20.5 */
168 int LivingEntity::GetDataEffectColorId() const
169 {
170 std::shared_lock<std::shared_mutex> lock(entity_mutex);
171 return std::any_cast<int>(metadata.at("data_effect_color_id"));
172 }
173#else
174 std::vector<ProtocolCraft::Particle> LivingEntity::GetDataEffectParticles() const
175 {
176 std::shared_lock<std::shared_mutex> lock(entity_mutex);
177 return std::any_cast<std::vector<ProtocolCraft::Particle>>(metadata.at("data_effect_particle"));
178 }
179#endif
180
182 {
183 std::shared_lock<std::shared_mutex> lock(entity_mutex);
184 return std::any_cast<bool>(metadata.at("data_effect_ambience_id"));
185 }
186
188 {
189 std::shared_lock<std::shared_mutex> lock(entity_mutex);
190 return std::any_cast<int>(metadata.at("data_arrow_count_id"));
191 }
192
193#if PROTOCOL_VERSION > 498 /* > 1.14.4 */
195 {
196 std::shared_lock<std::shared_mutex> lock(entity_mutex);
197 return std::any_cast<int>(metadata.at("data_stinger_count_id"));
198 }
199#endif
200
201#if PROTOCOL_VERSION > 404 /* > 1.13.2 */
202 std::optional<Position> LivingEntity::GetSleepingPosId() const
203 {
204 std::shared_lock<std::shared_mutex> lock(entity_mutex);
205 return GetSleepingPosIdImpl();
206 }
207#endif
208
209
210 void LivingEntity::SetDataLivingEntityFlags(const char data_living_entity_flags)
211 {
212 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
213 metadata["data_living_entity_flags"] = data_living_entity_flags;
214 }
215
216 void LivingEntity::SetDataHealthId(const float data_health_id)
217 {
218 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
219 metadata["data_health_id"] = data_health_id;
220 }
221
222#if PROTOCOL_VERSION < 766 /* < 1.20.5 */
223 void LivingEntity::SetDataEffectColorId(const int data_effect_color_id)
224 {
225 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
226 metadata["data_effect_color_id"] = data_effect_color_id;
227 }
228#else
229 void LivingEntity::SetDataEffectParticles(const std::vector<ProtocolCraft::Particle>& data_effect_particles)
230 {
231 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
232 metadata["data_effect_particles"] = data_effect_particles;
233 }
234#endif
235
236 void LivingEntity::SetDataEffectAmbienceId(const bool data_effect_ambience_id)
237 {
238 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
239 metadata["data_effect_ambience_id"] = data_effect_ambience_id;
240 }
241
242 void LivingEntity::SetDataArrowCountId(const int data_arrow_count_id)
243 {
244 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
245 metadata["data_arrow_count_id"] = data_arrow_count_id;
246 }
247
248#if PROTOCOL_VERSION > 498 /* > 1.14.4 */
249 void LivingEntity::SetDataStingerCountId(const int data_stinger_count_id)
250 {
251 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
252 metadata["data_stinger_count_id"] = data_stinger_count_id;
253 }
254#endif
255
256#if PROTOCOL_VERSION > 404 /* > 1.13.2 */
257 void LivingEntity::SetSleepingPosId(const std::optional<Position>& sleeping_pos_id)
258 {
259 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
260 metadata["sleeping_pos_id"] = sleeping_pos_id;
261 }
262#endif
263
264 std::optional<EntityAttribute> LivingEntity::GetAttribute(const EntityAttribute::Type type) const
265 {
266 std::shared_lock<std::shared_mutex> lock(entity_mutex);
267
268 auto it = attributes.find(type);
269 if (it == attributes.end())
270 {
271 return std::optional<EntityAttribute>();
272 }
273 return it->second;
274 }
275
277 {
278 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
279
280 auto it = attributes.find(type);
281 if (it == attributes.end())
282 {
283 LOG_WARNING("Trying to set attribute base value for " << type << " for a " << GetName() << " but it doesn't have this attribute");
284 return;
285 }
286 it->second.SetBaseValue(value);
287 }
288
290 {
291 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
293 }
294
296 {
297 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
298 SetAttributeModifierImpl(type, key, modifier);
299 }
300
302 {
303 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
304
305 auto it = attributes.find(type);
306 if (it == attributes.end())
307 {
308 return;
309 }
310 it->second.ClearModifiers();
311 }
312
314 {
315 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
316
317 auto it = attributes.find(attribute.GetType());
318 if (it == attributes.end())
319 {
320 LOG_WARNING("Trying to add an attribute " << attribute.GetType() << " to a " << GetName() << " but it was not present");
321 }
322 else
323 {
324 attributes.erase(it);
325 }
326 attributes.insert({ attribute.GetType(), attribute });
327 }
328
330 {
331 std::shared_lock<std::shared_mutex> lock(entity_mutex);
332 return attributes.at(EntityAttribute::Type::MaxHealth).GetValue();
333 }
334
336 {
337 std::shared_lock<std::shared_mutex> lock(entity_mutex);
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);
350 return attributes.at(EntityAttribute::Type::Armor).GetValue();
351 }
352
354 {
355 std::shared_lock<std::shared_mutex> lock(entity_mutex);
357 }
358
359#if PROTOCOL_VERSION > 763 /* > 1.20.1 */
361 {
362 std::shared_lock<std::shared_mutex> lock(entity_mutex);
364 }
365#endif
366
371
372#if PROTOCOL_VERSION > 765 /* > 1.20.4 */
374 {
375 std::shared_lock<std::shared_mutex> lock(entity_mutex);
377 }
378
380 {
381 std::shared_lock<std::shared_mutex> lock(entity_mutex);
382 return attributes.at(EntityAttribute::Type::Scale).GetValue();
383 }
384
386 {
387 std::shared_lock<std::shared_mutex> lock(entity_mutex);
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#endif
409
410#if PROTOCOL_VERSION > 766 /* > 1.20.6 */
412 {
413 std::shared_lock<std::shared_mutex> lock(entity_mutex);
415 }
416
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#endif
447
448#if PROTOCOL_VERSION > 770 /* > 1.21.5 */
450 {
451 std::shared_lock<std::shared_mutex> lock(entity_mutex);
453 }
454
456 {
457 std::shared_lock<std::shared_mutex> lock(entity_mutex);
459 }
460#endif
461
463 {
464 auto it = attributes.find(type);
465 if (it == attributes.end())
466 {
467 return;
468 }
469 it->second.RemoveModifier(key);
470 }
471
473 {
474 auto it = attributes.find(type);
475 if (it == attributes.end())
476 {
477 LOG_WARNING("Trying to set attribute modifier for " << type << " for a " << GetName() << " but it doesn't have this attribute");
478 return;
479 }
480 it->second.SetModifier(key, modifier);
481 }
482
484 {
485 return std::any_cast<char>(metadata.at("data_living_entity_flags"));
486 }
487
488#if PROTOCOL_VERSION > 404 /* > 1.13.2 */
489 std::optional<Position> LivingEntity::GetSleepingPosIdImpl() const
490 {
491 return std::any_cast<std::optional<Position>>(metadata.at("sleeping_pos_id"));
492 }
493#endif
494
495#if PROTOCOL_VERSION > 765 /* > 1.20.4 */
500
502 {
503 return attributes.at(EntityAttribute::Type::Gravity).GetValue();
504 }
505
510#endif
511
512#if PROTOCOL_VERSION > 766 /* > 1.20.6 */
517
522#endif
523
524}
#define LOG_WARNING(osstream)
Definition Logger.hpp:44
virtual ProtocolCraft::Json::Value Serialize() const
Definition Entity.cpp:1154
virtual void SetMetadataValue(const int index, const std::any &value)
Definition Entity.cpp:681
std::shared_mutex entity_mutex
Definition Entity.hpp:261
virtual std::string GetName() const =0
std::map< std::string, std::any > metadata
Definition Entity.hpp:276
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 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