9#if PROTOCOL_VERSION > 776
29 return it ==
entities.end() ? nullptr : it->second;
34 if (entity ==
nullptr)
40 entities[entity->GetEntityID()] = entity;
53#if PROTOCOL_VERSION < 764
56 local_player->SetGameMode(
static_cast<GameType>(packet.GetCommonPlayerSpawnInfo().GetGameType()));
62#if PROTOCOL_VERSION < 755
66 auto it =
entities.find(packet.GetEntityId());
69 std::shared_ptr<Entity> entity = std::make_shared<UnknownEntity>();
70 entity->SetEntityID(packet.GetEntityId());
71 entities[packet.GetEntityId()] = entity;
78 std::shared_ptr<Entity> entity =
nullptr;
82 auto it =
entities.find(packet.GetEntityId());
89 if (entity !=
nullptr)
92#if PROTOCOL_VERSION < 777
94 (packet.GetXA() / 128.0f + entity_position.
x * 32.0f) / 32.0f,
95 (packet.GetYA() / 128.0f + entity_position.
y * 32.0f) / 32.0f,
96 (packet.GetZA() / 128.0f + entity_position.
z * 32.0f) / 32.0f
99 if (packet.GetSingleDelta().has_value())
101 const std::array<short, 3>& delta = packet.GetSingleDelta().value();
102 for (
int i = 0; i < 3; ++i)
108 entity_position[i] = (delta[i] + std::round(entity_position[i]) * 4096.0) / 4096.0;
111 else if (packet.GetSteppedDeltas().has_value())
113 const std::vector<std::pair<int, std::array<short, 3>>>& steps = packet.GetSteppedDeltas().value();
114 for (
auto& [tick, delta] : steps)
116 for (
int i = 0; i < 3; ++i)
122 entity_position[i] = (delta[i] + std::round(entity_position[i]) * 4096.0) / 4096.0;
128 throw std::runtime_error(
"Invalid ClientboundMoveEntityPacket");
131 entity->SetPosition(entity_position);
138 std::shared_ptr<Entity> entity =
nullptr;
142 auto it =
entities.find(packet.GetEntityId());
149 if (entity !=
nullptr)
152#if PROTOCOL_VERSION < 777
154 (packet.GetXA() / 128.0f + entity_position.
x * 32.0f) / 32.0f,
155 (packet.GetYA() / 128.0f + entity_position.
y * 32.0f) / 32.0f,
156 (packet.GetZA() / 128.0f + entity_position.
z * 32.0f) / 32.0f
159 if (packet.GetSingleDelta().has_value())
161 const std::array<short, 3>& delta = packet.GetSingleDelta().value();
162 for (
int i = 0; i < 3; ++i)
168 entity_position[i] = (delta[i] + std::round(entity_position[i]) * 4096.0) / 4096.0;
171 else if (packet.GetSteppedDeltas().has_value())
173 const std::vector<std::pair<int, std::array<short, 3>>>& steps = packet.GetSteppedDeltas().value();
174 for (
auto& [tick, delta] : steps)
176 for (
int i = 0; i < 3; ++i)
182 entity_position[i] = (delta[i] + std::round(entity_position[i]) * 4096.0) / 4096.0;
188 throw std::runtime_error(
"Invalid ClientboundMoveEntityPacketPosRot");
191 entity->SetPosition(entity_position);
192 entity->SetYaw(360.0f * packet.GetYRot() / 256.0f);
193 entity->SetPitch(360.0f * packet.GetXRot() / 256.0f);
200 std::shared_ptr<Entity> entity =
nullptr;
204 auto it =
entities.find(packet.GetEntityId());
211 if (entity !=
nullptr)
213 entity->SetYaw(360.0f * packet.GetYRot() / 256.0f);
214 entity->SetPitch(360.0f * packet.GetXRot() / 256.0f);
215 entity->SetOnGround(packet.GetOnGround());
221#if PROTOCOL_VERSION < 458
222 std::shared_ptr<Entity> entity = Entity::CreateObjectEntity(
static_cast<ObjectEntityType
>(packet.GetType()));
227 entity->SetEntityID(packet.GetEntityId());
228 entity->SetX(packet.GetX());
229 entity->SetY(packet.GetY());
230 entity->SetZ(packet.GetZ());
231 entity->SetYaw(360.0f * packet.GetYRot() / 256.0f);
232 entity->SetPitch(360.0f * packet.GetXRot() / 256.0f);
233 entity->SetUUID(packet.GetUuid());
234#if PROTOCOL_VERSION < 773
236 entity->SetSpeed(
Vector3<double>(packet.GetXa(), packet.GetYa(), packet.GetZa()) / 8000.0);
242 entities[packet.GetEntityId()] = entity;
250 if (entity ==
nullptr)
252 LOG_WARNING(
"Trying to apply knockback without a valid player");
256#if PROTOCOL_VERSION < 768
258 static_cast<double>(packet.GetKnockbackX()),
259 static_cast<double>(packet.GetKnockbackY()),
260 static_cast<double>(packet.GetKnockbackZ())
263 if (packet.GetPlayerKnockback().has_value())
265 entity->SetSpeed(entity->GetSpeed() + packet.GetPlayerKnockback().value());
271#if PROTOCOL_VERSION < 759
276 entity->SetEntityID(packet.GetEntityId());
277 entity->SetX(packet.GetX());
278 entity->SetY(packet.GetY());
279 entity->SetZ(packet.GetZ());
280 entity->SetYaw(360.0f * packet.GetYRot() / 256.0f);
281 entity->SetPitch(360.0f * packet.GetXRot() / 256.0f);
282 entity->SetUUID(packet.GetUuid());
285 entities[packet.GetEntityId()] = entity;
289#if PROTOCOL_VERSION < 770
294 entity->SetEntityID(packet.GetEntityId());
295 entity->SetX(packet.GetX());
296 entity->SetY(packet.GetY());
297 entity->SetZ(packet.GetZ());
300 entities[packet.GetEntityId()] = entity;
304#if PROTOCOL_VERSION < 721
309 entity->SetEntityID(packet.GetEntityId());
310 entity->SetX(packet.GetX());
311 entity->SetY(packet.GetY());
312 entity->SetZ(packet.GetZ());
315 entities[packet.GetEntityId()] = entity;
319#if PROTOCOL_VERSION < 764
322 std::shared_ptr<Entity> entity =
nullptr;
326 auto it =
entities.find(packet.GetEntityId());
330 entities[packet.GetEntityId()] = entity;
338 entity->SetEntityID(packet.GetEntityId());
339 entity->SetPosition(Vector3<double>(
344 entity->SetYaw(360.0f * packet.GetYRot() / 256.0f);
345 entity->SetPitch(360.0f * packet.GetXRot() / 256.0f);
346 entity->SetUUID(packet.GetPlayerId());
354 local_player->SetFoodSaturation(packet.GetFoodSaturation());
359 std::shared_ptr<Entity> entity =
nullptr;
363 auto it =
entities.find(packet.GetEntityId());
370 if (entity !=
nullptr)
372#if PROTOCOL_VERSION < 768
378 entity->SetYaw(360.0f * packet.GetYRot() / 256.0f);
379 entity->SetPitch(360.0f * packet.GetXRot() / 256.0f);
382 packet.GetRelatives() & (1 << 0) ? entity->GetX() + packet.GetChange().GetPosition()[0] : packet.GetChange().GetPosition()[0],
383 packet.GetRelatives() & (1 << 1) ? entity->GetY() + packet.GetChange().GetPosition()[1] : packet.GetChange().GetPosition()[1],
384 packet.GetRelatives() & (1 << 2) ? entity->GetZ() + packet.GetChange().GetPosition()[2] : packet.GetChange().GetPosition()[2]
386 entity->SetYaw(packet.GetRelatives() & (1 << 3) ? entity->GetYaw() + packet.GetChange().GetYRot() : packet.GetChange().GetYRot());
387 entity->SetPitch(packet.GetRelatives() & (1 << 4) ? entity->GetPitch() + packet.GetChange().GetXRot() : packet.GetChange().GetXRot());
389 entity->SetOnGround(packet.GetOnGround());
397 local_player->SetWalkingSpeed(packet.GetWalkingSpeed());
400#if PROTOCOL_VERSION == 755
404 entities.erase(packet.GetEntityId());
410 for (
int i = 0; i < packet.GetEntityIds().size(); ++i)
412 entities.erase(packet.GetEntityIds()[i]);
419#if PROTOCOL_VERSION < 764
422 local_player->SetGameMode(
static_cast<GameType>(packet.GetCommonPlayerSpawnInfo().GetGameType()));
428 switch (packet.GetType())
440 std::shared_ptr<Entity> entity =
nullptr;
444 auto it =
entities.find(packet.GetEntityId());
451 if (entity ==
nullptr)
453 LOG_WARNING(
"Trying to load metadata in unexisting entity");
457 entity->LoadMetadataFromRawArray(packet.GetPackedItems());
463 std::shared_ptr<Entity> entity =
nullptr;
467 auto it =
entities.find(packet.GetEntityId());
474 if (entity ==
nullptr)
476 LOG_WARNING(
"Trying to set speed of an unexisting entity");
480#if PROTOCOL_VERSION < 773
482 entity->SetSpeed(
Vector3<double>(packet.GetXA(), packet.GetYA(), packet.GetZA()) / 8000.0);
491 std::shared_ptr<Entity> entity =
nullptr;
495 auto it =
entities.find(packet.GetEntityId());
502 if (entity ==
nullptr)
504 LOG_WARNING(
"Trying to set equipment of an unexisting entity");
508#if PROTOCOL_VERSION > 730
509 for (
auto& p : packet.GetSlots())
511 entity->SetEquipment(
static_cast<EquipmentSlot>(p.first), p.second);
514 entity->SetEquipment(
static_cast<EquipmentSlot>(packet.GetSlot().first), packet.GetSlot().second);
521 std::shared_ptr<Entity> entity =
nullptr;
525 auto it =
entities.find(packet.GetEntityId());
532 if (entity ==
nullptr)
534 LOG_WARNING(
"Trying to set attributes of an unexisting entity");
536 else if (!entity->IsLivingEntity())
538 LOG_WARNING(
"Trying to set attributes of a non LivingEntity");
542 std::shared_ptr<LivingEntity> living_entity = std::dynamic_pointer_cast<LivingEntity>(entity);
543 for (
const auto& a : packet.GetAttributes())
545#if PROTOCOL_VERSION > 765
547#elif PROTOCOL_VERSION > 709
553 for (
const auto& m : a.GetModifiers())
556#
if PROTOCOL_VERSION < 767
564 living_entity->AddAttribute(attribute);
571 std::shared_ptr<Entity> entity =
nullptr;
575 auto it =
entities.find(packet.GetEntityId());
582 if (entity ==
nullptr)
584 LOG_WARNING(
"Trying to set effect of an unexisting entity");
590 static_cast<unsigned char>(packet.GetEffectAmplifier()),
591 std::chrono::steady_clock::now() + std::chrono::milliseconds(50 * packet.GetEffectDurationTicks())
599 std::shared_ptr<Entity> entity =
nullptr;
603 auto it =
entities.find(packet.GetEntityId());
610 if (entity ==
nullptr)
612 LOG_WARNING(
"Trying to remove effect of an unexisting entity");
620#if PROTOCOL_VERSION > 767
623 std::shared_ptr<Entity> entity =
nullptr;
627 auto it =
entities.find(packet.GetEntityId());
634 if (entity !=
nullptr)
636#if PROTOCOL_VERSION < 777
637 entity->SetPosition(packet.GetValues().GetPosition());
642 entity->SetYaw(packet.GetValues().GetYRot());
643 entity->SetPitch(packet.GetValues().GetXRot());
645 if (packet.GetPosition().GetValue().GetLeft().has_value())
647 entity->SetPosition(packet.GetPosition().GetValue().GetLeft().value().GetSteps().back().GetPosition());
651 entity->SetPosition(packet.GetPosition().GetValue().GetRight().value().GetEndPosition());
657 entity->SetYaw(packet.GetYRot());
658 entity->SetPitch(packet.GetXRot());
660 entity->SetOnGround(packet.GetOnGround());
666 std::shared_ptr<Entity> entity =
nullptr;
670 auto it =
entities.find(packet.GetEntityId());
677 if (entity ==
nullptr || !entity->IsAbstractMinecart())
685 entity->SetPosition(step.GetPosition());
686 entity->SetYaw(360.0f * step.GetYRot() / 256.0f);
687 entity->SetPitch(360.0f * step.GetXRot() / 256.0f);
#define LOG_WARNING(osstream)
void SetModifier(const ModifierKey &key, const Modifier &modifier)
virtual void Handle(ProtocolCraft::ClientboundLoginPacket &packet) override
std::shared_ptr< LocalPlayer > GetLocalPlayer()
std::shared_ptr< LocalPlayer > local_player
std::shared_mutex entity_manager_mutex
Utilities::ScopeLockedWrapper< const std::unordered_map< int, std::shared_ptr< Entity > >, std::shared_mutex, std::shared_lock > GetEntities() const
Get a read-only locked version of all the loaded entities (including local player)
std::unordered_map< int, std::shared_ptr< Entity > > entities
void AddEntity(const std::shared_ptr< Entity > &entity)
EntityManager(const std::shared_ptr< NetworkManager > &network_manager)
std::shared_ptr< Entity > GetEntity(const int id) const
static std::shared_ptr< Entity > CreateEntity(const EntityType type)
Mutex protected reference, will be locked until destroyed.