Botcraft 1.21.5
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 }
71
76
78 {
79 return true;
80 }
81
82
84 {
86
87 output["metadata"]["data_living_entity_flags"] = GetDataLivingEntityFlags();
88 output["metadata"]["data_health_id"] = GetDataHealthId();
89#if PROTOCOL_VERSION < 766 /* < 1.20.5 */
90 output["metadata"]["data_effect_color_id"] = GetDataEffectColorId();
91#else
92 output["metadata"]["data_effect_particles"] = GetDataEffectParticles();
93#endif
94 output["metadata"]["data_effect_ambience_id"] = GetDataEffectAmbienceId();
95 output["metadata"]["data_arrow_count_id"] = GetDataArrowCountId();
96#if PROTOCOL_VERSION > 498 /* > 1.14.4 */
97 output["metadata"]["data_stinger_count_id"] = GetDataStingerCountId();
98#endif
99#if PROTOCOL_VERSION > 404 /* > 1.13.2 */
100 output["metadata"]["sleeping_pos_id"] = GetSleepingPosId() ? GetSleepingPosId().value().Serialize() : ProtocolCraft::Json::Value();
101#endif
102
103 output["attributes"] = ProtocolCraft::Json::Value();
104
105 output["attributes"]["max_health"] = GetAttributeMaxHealthValue();
106 output["attributes"]["knockback_resistance"] = GetAttributeKnockbackResistanceValue();
107 output["attributes"]["movement_speed"] = GetAttributeMovementSpeedValue();
108 output["attributes"]["armor"] = GetAttributeArmorValue();
109 output["attributes"]["armor_toughness"] = GetAttributeArmorToughnessValue();
110#if PROTOCOL_VERSION > 763 /* > 1.20.1 */
111 output["attributes"]["max_absorption"] = GetAttributeMaxAbsorptionValue();
112#endif
113#if PROTOCOL_VERSION > 765 /* > 1.20.4 */
114 output["attributes"]["step_height"] = GetAttributeStepHeightValue();
115 output["attributes"]["scale"] = GetAttributeScaleValue();
116 output["attributes"]["gravity"] = GetAttributeGravityValue();
117 output["attributes"]["safe_fall_distance"] = GetAttributeSafeFallDistanceValue();
118 output["attributes"]["fall_damage_multiplier"] = GetAttributeFallDamageMultiplierValue();
119 output["attributes"]["jump_strength"] = GetAttributeJumpStrengthValue();
120#endif
121#if PROTOCOL_VERSION > 766 /* > 1.20.6 */
122 output["attributes"]["oxygen_bonus"] = GetAttributeOxygenBonusValue();
123 output["attributes"]["burning_time"] = GetAttributeBurningTimeValue();
124 output["attributes"]["explosion_knockback_resistance"] = GetAttributeExplosionKnockbackResistanceValue();
125 output["attributes"]["water_movement_efficiency"] = GetAttributeWaterMovementEfficiencyValue();
126 output["attributes"]["movement_efficiency"] = GetAttributeMovementEfficiencyValue();
127 output["attributes"]["attack_knockback"] = GetAttributeAttackKnockbackValue();
128#endif
129
130 return output;
131 }
132
133
134 void LivingEntity::SetMetadataValue(const int index, const std::any& value)
135 {
136 if (index < hierarchy_metadata_count)
137 {
138 Entity::SetMetadataValue(index, value);
139 }
140 else if (index - hierarchy_metadata_count < metadata_count)
141 {
142 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
144 }
145 }
146
148 {
149 std::shared_lock<std::shared_mutex> lock(entity_mutex);
151 }
152
154 {
155 std::shared_lock<std::shared_mutex> lock(entity_mutex);
156 return std::any_cast<float>(metadata.at("data_health_id"));
157 }
158
159#if PROTOCOL_VERSION < 766 /* < 1.20.5 */
160 int LivingEntity::GetDataEffectColorId() const
161 {
162 std::shared_lock<std::shared_mutex> lock(entity_mutex);
163 return std::any_cast<int>(metadata.at("data_effect_color_id"));
164 }
165#else
166 std::vector<ProtocolCraft::Particle> LivingEntity::GetDataEffectParticles() const
167 {
168 std::shared_lock<std::shared_mutex> lock(entity_mutex);
169 return std::any_cast<std::vector<ProtocolCraft::Particle>>(metadata.at("data_effect_particle"));
170 }
171#endif
172
174 {
175 std::shared_lock<std::shared_mutex> lock(entity_mutex);
176 return std::any_cast<bool>(metadata.at("data_effect_ambience_id"));
177 }
178
180 {
181 std::shared_lock<std::shared_mutex> lock(entity_mutex);
182 return std::any_cast<int>(metadata.at("data_arrow_count_id"));
183 }
184
185#if PROTOCOL_VERSION > 498 /* > 1.14.4 */
187 {
188 std::shared_lock<std::shared_mutex> lock(entity_mutex);
189 return std::any_cast<int>(metadata.at("data_stinger_count_id"));
190 }
191#endif
192
193#if PROTOCOL_VERSION > 404 /* > 1.13.2 */
194 std::optional<Position> LivingEntity::GetSleepingPosId() const
195 {
196 std::shared_lock<std::shared_mutex> lock(entity_mutex);
197 return GetSleepingPosIdImpl();
198 }
199#endif
200
201
202 void LivingEntity::SetDataLivingEntityFlags(const char data_living_entity_flags)
203 {
204 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
205 metadata["data_living_entity_flags"] = data_living_entity_flags;
206 }
207
208 void LivingEntity::SetDataHealthId(const float data_health_id)
209 {
210 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
211 metadata["data_health_id"] = data_health_id;
212 }
213
214#if PROTOCOL_VERSION < 766 /* < 1.20.5 */
215 void LivingEntity::SetDataEffectColorId(const int data_effect_color_id)
216 {
217 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
218 metadata["data_effect_color_id"] = data_effect_color_id;
219 }
220#else
221 void LivingEntity::SetDataEffectParticles(const std::vector<ProtocolCraft::Particle>& data_effect_particles)
222 {
223 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
224 metadata["data_effect_particles"] = data_effect_particles;
225 }
226#endif
227
228 void LivingEntity::SetDataEffectAmbienceId(const bool data_effect_ambience_id)
229 {
230 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
231 metadata["data_effect_ambience_id"] = data_effect_ambience_id;
232 }
233
234 void LivingEntity::SetDataArrowCountId(const int data_arrow_count_id)
235 {
236 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
237 metadata["data_arrow_count_id"] = data_arrow_count_id;
238 }
239
240#if PROTOCOL_VERSION > 498 /* > 1.14.4 */
241 void LivingEntity::SetDataStingerCountId(const int data_stinger_count_id)
242 {
243 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
244 metadata["data_stinger_count_id"] = data_stinger_count_id;
245 }
246#endif
247
248#if PROTOCOL_VERSION > 404 /* > 1.13.2 */
249 void LivingEntity::SetSleepingPosId(const std::optional<Position>& sleeping_pos_id)
250 {
251 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
252 metadata["sleeping_pos_id"] = sleeping_pos_id;
253 }
254#endif
255
256 std::optional<EntityAttribute> LivingEntity::GetAttribute(const EntityAttribute::Type type) const
257 {
258 std::shared_lock<std::shared_mutex> lock(entity_mutex);
259
260 auto it = attributes.find(type);
261 if (it == attributes.end())
262 {
263 return std::optional<EntityAttribute>();
264 }
265 return it->second;
266 }
267
269 {
270 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
271
272 auto it = attributes.find(type);
273 if (it == attributes.end())
274 {
275 LOG_WARNING("Trying to set attribute base value for " << type << " for a " << GetName() << " but it doesn't have this attribute");
276 return;
277 }
278 it->second.SetBaseValue(value);
279 }
280
282 {
283 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
285 }
286
288 {
289 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
290 SetAttributeModifierImpl(type, key, modifier);
291 }
292
294 {
295 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
296
297 auto it = attributes.find(type);
298 if (it == attributes.end())
299 {
300 return;
301 }
302 it->second.ClearModifiers();
303 }
304
306 {
307 std::scoped_lock<std::shared_mutex> lock(entity_mutex);
308
309 auto it = attributes.find(attribute.GetType());
310 if (it == attributes.end())
311 {
312 LOG_WARNING("Trying to add an attribute " << attribute.GetType() << " to a " << GetName() << " but it was not present");
313 }
314 else
315 {
316 attributes.erase(it);
317 }
318 attributes.insert({ attribute.GetType(), attribute });
319 }
320
322 {
323 std::shared_lock<std::shared_mutex> lock(entity_mutex);
324 return attributes.at(EntityAttribute::Type::MaxHealth).GetValue();
325 }
326
328 {
329 std::shared_lock<std::shared_mutex> lock(entity_mutex);
331 }
332
334 {
335 std::shared_lock<std::shared_mutex> lock(entity_mutex);
337 }
338
340 {
341 std::shared_lock<std::shared_mutex> lock(entity_mutex);
342 return attributes.at(EntityAttribute::Type::Armor).GetValue();
343 }
344
346 {
347 std::shared_lock<std::shared_mutex> lock(entity_mutex);
349 }
350
351#if PROTOCOL_VERSION > 763 /* > 1.20.1 */
353 {
354 std::shared_lock<std::shared_mutex> lock(entity_mutex);
356 }
357#endif
358
363
364#if PROTOCOL_VERSION > 765 /* > 1.20.4 */
366 {
367 std::shared_lock<std::shared_mutex> lock(entity_mutex);
369 }
370
372 {
373 std::shared_lock<std::shared_mutex> lock(entity_mutex);
374 return attributes.at(EntityAttribute::Type::Scale).GetValue();
375 }
376
378 {
379 std::shared_lock<std::shared_mutex> lock(entity_mutex);
381 }
382
384 {
385 std::shared_lock<std::shared_mutex> lock(entity_mutex);
387 }
388
390 {
391 std::shared_lock<std::shared_mutex> lock(entity_mutex);
393 }
394
396 {
397 std::shared_lock<std::shared_mutex> lock(entity_mutex);
399 }
400#endif
401
402#if PROTOCOL_VERSION > 766 /* > 1.20.6 */
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
416 {
417 std::shared_lock<std::shared_mutex> lock(entity_mutex);
419 }
420
422 {
423 std::shared_lock<std::shared_mutex> lock(entity_mutex);
425 }
426
428 {
429 std::shared_lock<std::shared_mutex> lock(entity_mutex);
431 }
432
434 {
435 std::shared_lock<std::shared_mutex> lock(entity_mutex);
437 }
438#endif
439
441 {
442 auto it = attributes.find(type);
443 if (it == attributes.end())
444 {
445 return;
446 }
447 it->second.RemoveModifier(key);
448 }
449
451 {
452 auto it = attributes.find(type);
453 if (it == attributes.end())
454 {
455 LOG_WARNING("Trying to set attribute modifier for " << type << " for a " << GetName() << " but it doesn't have this attribute");
456 return;
457 }
458 it->second.SetModifier(key, modifier);
459 }
460
462 {
463 return std::any_cast<char>(metadata.at("data_living_entity_flags"));
464 }
465
466#if PROTOCOL_VERSION > 404 /* > 1.13.2 */
467 std::optional<Position> LivingEntity::GetSleepingPosIdImpl() const
468 {
469 return std::any_cast<std::optional<Position>>(metadata.at("sleeping_pos_id"));
470 }
471#endif
472
473#if PROTOCOL_VERSION > 765 /* > 1.20.4 */
478
480 {
481 return attributes.at(EntityAttribute::Type::Gravity).GetValue();
482 }
483
488#endif
489
490#if PROTOCOL_VERSION > 766 /* > 1.20.6 */
495
500#endif
501
502}
#define LOG_WARNING(osstream)
Definition Logger.hpp:44
virtual ProtocolCraft::Json::Value Serialize() const
Definition Entity.cpp:1151
virtual void SetMetadataValue(const int index, const std::any &value)
Definition Entity.cpp:678
std::shared_mutex entity_mutex
Definition Entity.hpp:259
virtual std::string GetName() const =0
std::map< std::string, std::any > metadata
Definition Entity.hpp:274
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 GetAttributeArmorValue() const
double GetAttributeStepHeightValue() 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