Improve entity position updates (#4701)
* Make puking pickups fly nicer * Improve entity position updates * Move determination of whether a delta is too big for a packet into the protocol handlers + Less jittery movement + Generalise CollectEntity to take any entity
This commit is contained in:
parent
258318ab98
commit
07ca095740
@ -32,7 +32,7 @@ public:
|
||||
virtual void BroadcastChatFatal (const AString & a_Message, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastChatDeath (const AString & a_Message, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastChat (const cCompositeChat & a_Message, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastCollectEntity (const cEntity & a_Pickup, const cPlayer & a_Player, int a_Count, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastCollectEntity (const cEntity & a_Collected, const cEntity & a_Collector, unsigned a_Count, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastDestroyEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastDetachEntity (const cEntity & a_Entity, const cEntity & a_PreviousVehicle) = 0;
|
||||
virtual void BroadcastEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, int a_Duration, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
@ -40,8 +40,7 @@ public:
|
||||
virtual void BroadcastEntityHeadLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastEntityLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastEntityMetadata (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastEntityRelMove (const cEntity & a_Entity, Vector3<Int8> a_RelMove, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastEntityRelMoveLook (const cEntity & a_Entity, Vector3<Int8> a_RelMove, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastEntityPosition (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastEntityStatus (const cEntity & a_Entity, Int8 a_Status, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastEntityVelocity (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastEntityAnimation (const cEntity & a_Entity, Int8 a_Animation, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
@ -60,7 +59,6 @@ public:
|
||||
virtual void BroadcastSoundEffect (const AString & a_SoundName, Vector3d a_Position, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastSoundParticleEffect (const EffectID a_EffectID, Vector3i a_SrcPos, int a_Data, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastSpawnEntity (cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastTeleportEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastThunderbolt (Vector3i a_BlockPos, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastTimeUpdate (const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastUnleashEntity (const cEntity & a_Entity) = 0;
|
||||
|
@ -197,11 +197,11 @@ void cWorld::BroadcastChat(const cCompositeChat & a_Message, const cClientHandle
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player, int a_Count, const cClientHandle * a_Exclude)
|
||||
void cWorld::BroadcastCollectEntity(const cEntity & a_Collected, const cEntity & a_Collector, unsigned a_Count, const cClientHandle * a_Exclude)
|
||||
{
|
||||
ForClientsWithEntity(a_Entity, *this, a_Exclude, [&](cClientHandle & a_Client)
|
||||
ForClientsWithEntity(a_Collected, *this, a_Exclude, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendCollectEntity(a_Entity, a_Player, a_Count);
|
||||
a_Client.SendCollectEntity(a_Collected, a_Collector, a_Count);
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -314,24 +314,11 @@ void cWorld::BroadcastEntityMetadata(const cEntity & a_Entity, const cClientHand
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastEntityRelMove(const cEntity & a_Entity, Vector3<Int8> a_RelMove, const cClientHandle * a_Exclude)
|
||||
void cWorld::BroadcastEntityPosition(const cEntity & a_Entity, const cClientHandle * a_Exclude)
|
||||
{
|
||||
ForClientsWithEntity(a_Entity, *this, a_Exclude, [&](cClientHandle & a_Client)
|
||||
ForClientsInWorld(*this, a_Exclude, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendEntityRelMove(a_Entity, a_RelMove.x, a_RelMove.y, a_RelMove.z);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastEntityRelMoveLook(const cEntity & a_Entity, Vector3<Int8> a_RelMove, const cClientHandle * a_Exclude)
|
||||
{
|
||||
ForClientsWithEntity(a_Entity, *this, a_Exclude, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendEntityRelMoveLook(a_Entity, a_RelMove.x, a_RelMove.y, a_RelMove.z);
|
||||
a_Client.SendEntityPosition(a_Entity);
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -561,19 +548,6 @@ void cWorld::BroadcastSpawnEntity(cEntity & a_Entity, const cClientHandle * a_Ex
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastTeleportEntity(const cEntity & a_Entity, const cClientHandle * a_Exclude)
|
||||
{
|
||||
ForClientsInWorld(*this, a_Exclude, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendTeleportEntity(a_Entity);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastThunderbolt(Vector3i a_BlockPos, const cClientHandle * a_Exclude)
|
||||
{
|
||||
ForClientsWithChunkAtPos(a_BlockPos, *this, a_Exclude, [&](cClientHandle & a_Client)
|
||||
|
@ -2497,9 +2497,9 @@ void cClientHandle::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializ
|
||||
|
||||
|
||||
|
||||
void cClientHandle::SendCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player, int a_Count)
|
||||
void cClientHandle::SendCollectEntity(const cEntity & a_Collected, const cEntity & a_Collector, unsigned a_Count)
|
||||
{
|
||||
m_Protocol->SendCollectEntity(a_Entity, a_Player, a_Count);
|
||||
m_Protocol->SendCollectEntity(a_Collected, a_Collector, a_Count);
|
||||
}
|
||||
|
||||
|
||||
@ -2603,22 +2603,9 @@ void cClientHandle::SendEntityMetadata(const cEntity & a_Entity)
|
||||
|
||||
|
||||
|
||||
void cClientHandle::SendEntityRelMove(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ)
|
||||
void cClientHandle::SendEntityPosition(const cEntity & a_Entity)
|
||||
{
|
||||
ASSERT(a_Entity.GetUniqueID() != m_Player->GetUniqueID()); // Must not send for self
|
||||
|
||||
m_Protocol->SendEntityRelMove(a_Entity, a_RelX, a_RelY, a_RelZ);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cClientHandle::SendEntityRelMoveLook(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ)
|
||||
{
|
||||
ASSERT(a_Entity.GetUniqueID() != m_Player->GetUniqueID()); // Must not send for self
|
||||
|
||||
m_Protocol->SendEntityRelMoveLook(a_Entity, a_RelX, a_RelY, a_RelZ);
|
||||
m_Protocol->SendEntityPosition(a_Entity);
|
||||
}
|
||||
|
||||
|
||||
@ -3058,15 +3045,6 @@ void cClientHandle::SendTabCompletionResults(const AStringVector & a_Results)
|
||||
|
||||
|
||||
|
||||
void cClientHandle::SendTeleportEntity(const cEntity & a_Entity)
|
||||
{
|
||||
m_Protocol->SendTeleportEntity(a_Entity);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cClientHandle::SendThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
m_Protocol->SendThunderbolt(a_BlockX, a_BlockY, a_BlockZ);
|
||||
|
@ -154,7 +154,7 @@ public: // tolua_export
|
||||
void SendChatSystem (const AString & a_Message, eMessageType a_ChatPrefix, const AString & a_AdditionalData = "");
|
||||
void SendChatSystem (const cCompositeChat & a_Message);
|
||||
void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer);
|
||||
void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player, int a_Count);
|
||||
void SendCollectEntity (const cEntity & a_Collected, const cEntity & a_Collector, unsigned a_Count);
|
||||
void SendDestroyEntity (const cEntity & a_Entity);
|
||||
void SendDetachEntity (const cEntity & a_Entity, const cEntity & a_PreviousVehicle);
|
||||
void SendDisconnect (const AString & a_Reason);
|
||||
@ -166,8 +166,7 @@ public: // tolua_export
|
||||
void SendEntityHeadLook (const cEntity & a_Entity);
|
||||
void SendEntityLook (const cEntity & a_Entity);
|
||||
void SendEntityMetadata (const cEntity & a_Entity);
|
||||
void SendEntityRelMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ);
|
||||
void SendEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ);
|
||||
void SendEntityPosition (const cEntity & a_Entity);
|
||||
void SendEntityStatus (const cEntity & a_Entity, char a_Status);
|
||||
void SendEntityVelocity (const cEntity & a_Entity);
|
||||
void SendExperience (void);
|
||||
@ -211,7 +210,6 @@ public: // tolua_export
|
||||
void SendSpawnMob (const cMonster & a_Mob);
|
||||
void SendStatistics (const cStatManager & a_Manager);
|
||||
void SendTabCompletionResults (const AStringVector & a_Results);
|
||||
void SendTeleportEntity (const cEntity & a_Entity);
|
||||
void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
void SendTitleTimes (int a_FadeInTicks, int a_DisplayTicks, int a_FadeOutTicks); // tolua_export
|
||||
void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle); // tolua_export
|
||||
|
@ -15,8 +15,6 @@ cArrowEntity::cArrowEntity(cEntity * a_Creator, Vector3d a_Pos, Vector3d a_Speed
|
||||
m_DamageCoeff(2),
|
||||
m_IsCritical(false),
|
||||
m_Timer(0),
|
||||
m_HitGroundTimer(0),
|
||||
m_HasTeleported(false),
|
||||
m_bIsCollected(false)
|
||||
{
|
||||
SetMass(0.1);
|
||||
@ -191,19 +189,6 @@ void cArrowEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
|
||||
|
||||
if (m_IsInGround)
|
||||
{
|
||||
if (!m_HasTeleported) // Sent a teleport already, don't do again
|
||||
{
|
||||
if (m_HitGroundTimer > std::chrono::milliseconds(500))
|
||||
{
|
||||
m_World->BroadcastTeleportEntity(*this);
|
||||
m_HasTeleported = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_HitGroundTimer += a_Dt;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_World->GetBlock(m_HitBlockPos) == E_BLOCK_AIR) // Block attached to was destroyed?
|
||||
{
|
||||
m_IsInGround = false; // Yes, begin simulating physics again
|
||||
|
@ -92,12 +92,6 @@ protected:
|
||||
/** Timer for pickup collection animation or five minute timeout */
|
||||
std::chrono::milliseconds m_Timer;
|
||||
|
||||
/** Timer for client arrow position confirmation via TeleportEntity */
|
||||
std::chrono::milliseconds m_HitGroundTimer;
|
||||
|
||||
// Whether the arrow has already been teleported into the proper position in the ground.
|
||||
bool m_HasTeleported;
|
||||
|
||||
/** If true, the arrow is in the process of being collected - don't go to anyone else */
|
||||
bool m_bIsCollected;
|
||||
|
||||
|
@ -49,19 +49,11 @@ void cBoat::BroadcastMovementUpdate(const cClientHandle * a_Exclude)
|
||||
}
|
||||
|
||||
Vector3i Diff = (GetPosition() * 32.0).Floor() - (m_LastSentPosition * 32.0).Floor();
|
||||
|
||||
if (Diff.HasNonZeroLength()) // Have we moved?
|
||||
{
|
||||
if ((abs(Diff.x) <= 127) && (abs(Diff.y) <= 127) && (abs(Diff.z) <= 127)) // Limitations of a Byte
|
||||
{
|
||||
m_World->BroadcastEntityRelMove(*this, Vector3<Int8>(Diff), a_Exclude);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Too big a movement, do a teleport
|
||||
m_World->BroadcastTeleportEntity(*this, a_Exclude);
|
||||
}
|
||||
m_World->BroadcastEntityPosition(*this, a_Exclude);
|
||||
m_LastSentPosition = GetPosition();
|
||||
m_bDirtyOrientation = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1917,12 +1917,7 @@ void cEntity::TeleportToCoords(double a_PosX, double a_PosY, double a_PosZ)
|
||||
// ask the plugins to allow teleport to the new position.
|
||||
if (!cRoot::Get()->GetPluginManager()->CallHookEntityTeleport(*this, m_LastPosition, Vector3d(a_PosX, a_PosY, a_PosZ)))
|
||||
{
|
||||
ResetPosition({a_PosX, a_PosY, a_PosZ});
|
||||
auto world = m_World;
|
||||
if (world != nullptr) // The entity might not be in a world yet (just spawned, in cWorld::m_EntitiesToAdd)
|
||||
{
|
||||
world->BroadcastTeleportEntity(*this);
|
||||
}
|
||||
SetPosition({a_PosX, a_PosY, a_PosZ});
|
||||
}
|
||||
}
|
||||
|
||||
@ -1938,58 +1933,39 @@ void cEntity::BroadcastMovementUpdate(const cClientHandle * a_Exclude)
|
||||
return;
|
||||
}
|
||||
|
||||
if (GetSpeed().HasNonZeroLength())
|
||||
if (GetSpeed().SqrLength() > 0.001)
|
||||
{
|
||||
// Movin'
|
||||
m_World->BroadcastEntityVelocity(*this, a_Exclude);
|
||||
m_bHasSentNoSpeed = false;
|
||||
}
|
||||
else
|
||||
else if (!m_bHasSentNoSpeed)
|
||||
{
|
||||
// Speed is zero, send this to clients once only as well as an absolute position
|
||||
if (!m_bHasSentNoSpeed)
|
||||
{
|
||||
m_World->BroadcastEntityVelocity(*this, a_Exclude);
|
||||
m_World->BroadcastTeleportEntity(*this, a_Exclude);
|
||||
m_World->BroadcastEntityPosition(*this, a_Exclude);
|
||||
m_LastSentPosition = GetPosition();
|
||||
m_bDirtyOrientation = false;
|
||||
m_bHasSentNoSpeed = true;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Pickups move disgracefully if relative move packets are sent as opposed to just velocity. Have a system to send relmove only when SetPosXXX() is called with a large difference in position
|
||||
Vector3i Diff = (GetPosition() * 32.0).Floor() - (m_LastSentPosition * 32.0).Floor();
|
||||
if (Diff.HasNonZeroLength()) // Have we moved?
|
||||
{
|
||||
if ((abs(Diff.x) <= 127) && (abs(Diff.y) <= 127) && (abs(Diff.z) <= 127)) // Limitations of a Byte
|
||||
{
|
||||
// Difference within Byte limitations, use a relative move packet
|
||||
if (m_bDirtyOrientation)
|
||||
{
|
||||
m_World->BroadcastEntityRelMoveLook(*this, Vector3<Int8>(Diff), a_Exclude);
|
||||
m_bDirtyOrientation = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_World->BroadcastEntityRelMove(*this, Vector3<Int8>(Diff), a_Exclude);
|
||||
}
|
||||
m_World->BroadcastEntityPosition(*this, a_Exclude);
|
||||
|
||||
// Clients seem to store two positions, one for the velocity packet and one for the teleport / relmove packet
|
||||
// The latter is only changed with a relmove / teleport, and m_LastSentPosition stores this position
|
||||
m_LastSentPosition = GetPosition();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Too big a movement, do a teleport
|
||||
m_World->BroadcastTeleportEntity(*this, a_Exclude);
|
||||
m_LastSentPosition = GetPosition(); // See above
|
||||
m_bDirtyOrientation = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_bDirtyHead)
|
||||
{
|
||||
m_World->BroadcastEntityHeadLook(*this, a_Exclude);
|
||||
m_bDirtyHead = false;
|
||||
}
|
||||
|
||||
if (m_bDirtyOrientation)
|
||||
{
|
||||
// Send individual update in case above (sending with rel-move packet) wasn't done
|
||||
@ -2076,6 +2052,15 @@ bool cEntity::IsAttachedTo(const cEntity * a_Entity) const
|
||||
|
||||
|
||||
|
||||
bool cEntity::IsOrientationDirty() const
|
||||
{
|
||||
return m_bDirtyOrientation;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cEntity::SetHeadYaw(double a_HeadYaw)
|
||||
{
|
||||
m_HeadYaw = a_HeadYaw;
|
||||
|
@ -338,7 +338,7 @@ public:
|
||||
|
||||
/** Returns the last position we sent to all the clients. Use this to
|
||||
initialize clients with our position. */
|
||||
Vector3d GetLastSentPos(void) const { return m_LastSentPosition; }
|
||||
Vector3d GetLastSentPosition(void) const { return m_LastSentPosition; }
|
||||
|
||||
/** Destroy the entity without scheduling memory freeing. This should only be used by cChunk or cClientHandle for internal memory management. */
|
||||
void DestroyNoScheduling(bool a_ShouldBroadcast);
|
||||
@ -511,6 +511,10 @@ public:
|
||||
/** Returns true if this entity is attached to the specified entity */
|
||||
bool IsAttachedTo(const cEntity * a_Entity) const;
|
||||
|
||||
/** Returns whether the entity's orientation has been set manually.
|
||||
Primarily inteded for protocol use. */
|
||||
bool IsOrientationDirty() const;
|
||||
|
||||
/** Makes sure head yaw is not over the specified range. */
|
||||
void WrapHeadYaw();
|
||||
|
||||
|
@ -59,10 +59,7 @@ public:
|
||||
|
||||
if (Item.m_ItemCount <= 0)
|
||||
{
|
||||
/* Experimental: show animation pickups getting together */
|
||||
auto Diff = (m_Pickup->GetPosition() * 32.0).Floor() - (EntityPos * 32.0).Floor();
|
||||
a_Entity.GetWorld()->BroadcastEntityRelMove(a_Entity, Vector3<char>(Diff));
|
||||
/* End of experimental animation */
|
||||
a_Entity.GetWorld()->BroadcastCollectEntity(a_Entity, *m_Pickup, static_cast<unsigned>(CombineCount));
|
||||
a_Entity.Destroy();
|
||||
|
||||
// Reset the timer
|
||||
@ -253,7 +250,7 @@ bool cPickup::CollectedBy(cPlayer & a_Dest)
|
||||
}
|
||||
|
||||
m_Item.m_ItemCount -= NumAdded;
|
||||
m_World->BroadcastCollectEntity(*this, a_Dest, NumAdded);
|
||||
m_World->BroadcastCollectEntity(*this, a_Dest, static_cast<unsigned>(NumAdded));
|
||||
|
||||
// Also send the "pop" sound effect with a somewhat random pitch (fast-random using EntityID ;)
|
||||
m_World->BroadcastSoundEffect("entity.item.pickup", GetPosition(), 0.3f, (1.2f + (static_cast<float>((GetUniqueID() * 23) % 32)) / 64));
|
||||
|
@ -681,6 +681,24 @@ void cPlayer::AddFoodExhaustion(double a_Exhaustion)
|
||||
|
||||
|
||||
|
||||
void cPlayer::TossItems(const cItems & a_Items)
|
||||
{
|
||||
if (IsGameModeSpectator()) // Players can't toss items in spectator
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_Stats.AddValue(statItemsDropped, static_cast<StatValue>(a_Items.Size()));
|
||||
|
||||
const auto Speed = (GetLookVector() + Vector3d(0, 0.2, 0)) * 6; // A dash of height and a dollop of speed
|
||||
const auto Position = GetEyePosition() - Vector3d(0, 0.2, 0); // Correct for eye-height weirdness
|
||||
m_World->SpawnItemPickups(a_Items, Position, Speed, true); // 'true' because created by player
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cPlayer::StartEating(void)
|
||||
{
|
||||
// Set the timer:
|
||||
@ -1647,11 +1665,10 @@ void cPlayer::TeleportToCoords(double a_PosX, double a_PosY, double a_PosZ)
|
||||
// ask plugins to allow teleport to the new position.
|
||||
if (!cRoot::Get()->GetPluginManager()->CallHookEntityTeleport(*this, m_LastPosition, Vector3d(a_PosX, a_PosY, a_PosZ)))
|
||||
{
|
||||
ResetPosition({a_PosX, a_PosY, a_PosZ});
|
||||
SetPosition({a_PosX, a_PosY, a_PosZ});
|
||||
FreezeInternal(GetPosition(), false);
|
||||
m_bIsTeleporting = true;
|
||||
|
||||
m_World->BroadcastTeleportEntity(*this, GetClientHandle());
|
||||
m_ClientHandle->SendPlayerMoveLook();
|
||||
}
|
||||
}
|
||||
@ -2017,25 +2034,6 @@ void cPlayer::TossPickup(const cItem & a_Item)
|
||||
|
||||
|
||||
|
||||
void cPlayer::TossItems(const cItems & a_Items)
|
||||
{
|
||||
if (IsGameModeSpectator()) // Players can't toss items in spectator
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_Stats.AddValue(statItemsDropped, static_cast<StatValue>(a_Items.Size()));
|
||||
|
||||
double vX = 0, vY = 0, vZ = 0;
|
||||
EulerToVector(-GetYaw(), GetPitch(), vZ, vX, vY);
|
||||
vY = -vY * 2 + 1.f;
|
||||
m_World->SpawnItemPickups(a_Items, GetPosX(), GetEyeHeight(), GetPosZ(), vX * 3, vY * 3, vZ * 3, true); // 'true' because created by player
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cPlayer::DoMoveToWorld(const cEntity::sWorldChangeInfo & a_WorldChangeInfo)
|
||||
{
|
||||
ASSERT(a_WorldChangeInfo.m_NewWorld != nullptr);
|
||||
|
@ -372,6 +372,9 @@ public:
|
||||
|
||||
// tolua_end
|
||||
|
||||
/** Tosses a list of items. */
|
||||
void TossItems(const cItems & a_Items);
|
||||
|
||||
/** Sets a player's in-bed state
|
||||
We can't be sure plugins will keep this value updated, so no exporting
|
||||
If value is false (not in bed), will update players of the fact that they have been ejected from the bed
|
||||
@ -769,9 +772,6 @@ protected:
|
||||
/** Called in each tick if the player is fishing to make sure the floater dissapears when the player doesn't have a fishing rod as equipped item. */
|
||||
void HandleFloater(void);
|
||||
|
||||
/** Tosses a list of items. */
|
||||
void TossItems(const cItems & a_Items);
|
||||
|
||||
/** Returns the filename for the player data based on the UUID given.
|
||||
This can be used both for online and offline UUIDs. */
|
||||
AString GetUUIDFileName(const cUUID & a_UUID);
|
||||
|
@ -158,19 +158,19 @@ public:
|
||||
virtual void SendChat (const cCompositeChat & a_Message, eChatType a_Type, bool a_ShouldUseChatPrefixes) = 0;
|
||||
virtual void SendChatRaw (const AString & a_MessageRaw, eChatType a_Type) = 0;
|
||||
virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) = 0;
|
||||
virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player, int a_Count) = 0;
|
||||
virtual void SendCollectEntity (const cEntity & a_Collected, const cEntity & a_Collector, unsigned a_Count) = 0;
|
||||
virtual void SendDestroyEntity (const cEntity & a_Entity) = 0;
|
||||
virtual void SendDetachEntity (const cEntity & a_Entity, const cEntity & a_PreviousVehicle) = 0;
|
||||
virtual void SendDisconnect (const AString & a_Reason) = 0;
|
||||
virtual void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ) = 0; ///< Request the client to open up the sign editor for the sign (1.6+)
|
||||
virtual void SendEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, int a_Duration) = 0;
|
||||
virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) = 0;
|
||||
virtual void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) = 0;
|
||||
virtual void SendEntityHeadLook (const cEntity & a_Entity) = 0;
|
||||
virtual void SendEntityLook (const cEntity & a_Entity) = 0;
|
||||
virtual void SendEntityMetadata (const cEntity & a_Entity) = 0;
|
||||
virtual void SendEntityPosition (const cEntity & a_Entity) = 0;
|
||||
virtual void SendEntityProperties (const cEntity & a_Entity) = 0;
|
||||
virtual void SendEntityRelMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) = 0;
|
||||
virtual void SendEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) = 0;
|
||||
virtual void SendEntityStatus (const cEntity & a_Entity, char a_Status) = 0;
|
||||
virtual void SendEntityVelocity (const cEntity & a_Entity) = 0;
|
||||
virtual void SendExplosion (double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, const cVector3iArray & a_BlocksAffected, const Vector3d & a_PlayerMotion) = 0;
|
||||
@ -186,7 +186,6 @@ public:
|
||||
virtual void SendMapData (const cMap & a_Map, int a_DataStartX, int a_DataStartY) = 0;
|
||||
virtual void SendPaintingSpawn (const cPainting & a_Painting) = 0;
|
||||
virtual void SendPlayerAbilities (void) = 0;
|
||||
virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) = 0;
|
||||
virtual void SendParticleEffect (const AString & a_SoundName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) = 0;
|
||||
virtual void SendParticleEffect (const AString & a_SoundName, Vector3f a_Src, Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array<int, 2> a_Data) = 0;
|
||||
virtual void SendPlayerListAddPlayer (const cPlayer & a_Player) = 0;
|
||||
@ -218,7 +217,6 @@ public:
|
||||
virtual void SendSpawnMob (const cMonster & a_Mob) = 0;
|
||||
virtual void SendStatistics (const cStatManager & a_Manager) = 0;
|
||||
virtual void SendTabCompletionResults (const AStringVector & a_Results) = 0;
|
||||
virtual void SendTeleportEntity (const cEntity & a_Entity) = 0;
|
||||
virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) = 0;
|
||||
virtual void SendTitleTimes (int a_FadeInTicks, int a_DisplayTicks, int a_FadeOutTicks) = 0;
|
||||
virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) = 0;
|
||||
|
@ -233,10 +233,10 @@ void cProtocolRecognizer::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSe
|
||||
|
||||
|
||||
|
||||
void cProtocolRecognizer::SendCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player, int a_Count)
|
||||
void cProtocolRecognizer::SendCollectEntity(const cEntity & a_Collected, const cEntity & a_Collector, unsigned a_Count)
|
||||
{
|
||||
ASSERT(m_Protocol != nullptr);
|
||||
m_Protocol->SendCollectEntity(a_Entity, a_Player, a_Count);
|
||||
m_Protocol->SendCollectEntity(a_Collected, a_Collector, a_Count);
|
||||
}
|
||||
|
||||
|
||||
@ -291,6 +291,16 @@ void cProtocolRecognizer::SendEditSign(int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
|
||||
|
||||
|
||||
void cProtocolRecognizer::SendEntityAnimation(const cEntity & a_Entity, char a_Animation)
|
||||
{
|
||||
ASSERT(m_Protocol != nullptr);
|
||||
m_Protocol->SendEntityAnimation(a_Entity, a_Animation);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cProtocolRecognizer::SendEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, int a_Duration)
|
||||
{
|
||||
ASSERT(m_Protocol != nullptr);
|
||||
@ -341,6 +351,16 @@ void cProtocolRecognizer::SendEntityMetadata(const cEntity & a_Entity)
|
||||
|
||||
|
||||
|
||||
void cProtocolRecognizer::SendEntityPosition(const cEntity & a_Entity)
|
||||
{
|
||||
ASSERT(m_Protocol != nullptr);
|
||||
m_Protocol->SendEntityPosition(a_Entity);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cProtocolRecognizer::SendEntityProperties(const cEntity & a_Entity)
|
||||
{
|
||||
ASSERT(m_Protocol != nullptr);
|
||||
@ -351,26 +371,6 @@ void cProtocolRecognizer::SendEntityProperties(const cEntity & a_Entity)
|
||||
|
||||
|
||||
|
||||
void cProtocolRecognizer::SendEntityRelMove(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ)
|
||||
{
|
||||
ASSERT(m_Protocol != nullptr);
|
||||
m_Protocol->SendEntityRelMove(a_Entity, a_RelX, a_RelY, a_RelZ);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cProtocolRecognizer::SendEntityRelMoveLook(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ)
|
||||
{
|
||||
ASSERT(m_Protocol != nullptr);
|
||||
m_Protocol->SendEntityRelMoveLook(a_Entity, a_RelX, a_RelY, a_RelZ);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cProtocolRecognizer::SendEntityStatus(const cEntity & a_Entity, char a_Status)
|
||||
{
|
||||
ASSERT(m_Protocol != nullptr);
|
||||
@ -560,16 +560,6 @@ void cProtocolRecognizer::SendPlayerAbilities(void)
|
||||
|
||||
|
||||
|
||||
void cProtocolRecognizer::SendEntityAnimation(const cEntity & a_Entity, char a_Animation)
|
||||
{
|
||||
ASSERT(m_Protocol != nullptr);
|
||||
m_Protocol->SendEntityAnimation(a_Entity, a_Animation);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cProtocolRecognizer::SendPlayerListAddPlayer(const cPlayer & a_Player)
|
||||
{
|
||||
ASSERT(m_Protocol != nullptr);
|
||||
@ -860,16 +850,6 @@ void cProtocolRecognizer::SendTabCompletionResults(const AStringVector & a_Resul
|
||||
|
||||
|
||||
|
||||
void cProtocolRecognizer::SendTeleportEntity(const cEntity & a_Entity)
|
||||
{
|
||||
ASSERT(m_Protocol != nullptr);
|
||||
m_Protocol->SendTeleportEntity(a_Entity);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cProtocolRecognizer::SendThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
ASSERT(m_Protocol != nullptr);
|
||||
|
@ -60,19 +60,19 @@ public:
|
||||
virtual void SendChat (const cCompositeChat & a_Message, eChatType a_Type, bool a_ShouldUseChatPrefixes) override;
|
||||
virtual void SendChatRaw (const AString & a_MessageRaw, eChatType a_Type) override;
|
||||
virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override;
|
||||
virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player, int a_Count) override;
|
||||
virtual void SendCollectEntity (const cEntity & a_Collected, const cEntity & a_Collector, unsigned a_Count) override;
|
||||
virtual void SendDestroyEntity (const cEntity & a_Entity) override;
|
||||
virtual void SendDetachEntity (const cEntity & a_Entity, const cEntity & a_PreviousVehicle) override;
|
||||
virtual void SendDisconnect (const AString & a_Reason) override;
|
||||
virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) override;
|
||||
virtual void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ) override; ///< Request the client to open up the sign editor for the sign (1.6+)
|
||||
virtual void SendEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, int a_Duration) override;
|
||||
virtual void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) override;
|
||||
virtual void SendEntityHeadLook (const cEntity & a_Entity) override;
|
||||
virtual void SendEntityLook (const cEntity & a_Entity) override;
|
||||
virtual void SendEntityMetadata (const cEntity & a_Entity) override;
|
||||
virtual void SendEntityPosition (const cEntity & a_Entity) override;
|
||||
virtual void SendEntityProperties (const cEntity & a_Entity) override;
|
||||
virtual void SendEntityRelMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override;
|
||||
virtual void SendEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override;
|
||||
virtual void SendEntityStatus (const cEntity & a_Entity, char a_Status) override;
|
||||
virtual void SendEntityVelocity (const cEntity & a_Entity) override;
|
||||
virtual void SendExplosion (double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, const cVector3iArray & a_BlocksAffected, const Vector3d & a_PlayerMotion) override;
|
||||
@ -90,7 +90,6 @@ public:
|
||||
virtual void SendParticleEffect (const AString & a_ParticleName, Vector3f a_Src, Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array<int, 2> a_Data) override;
|
||||
virtual void SendPaintingSpawn (const cPainting & a_Painting) override;
|
||||
virtual void SendPlayerAbilities (void) override;
|
||||
virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) override;
|
||||
virtual void SendPlayerListAddPlayer (const cPlayer & a_Player) override;
|
||||
virtual void SendPlayerListRemovePlayer (const cPlayer & a_Player) override;
|
||||
virtual void SendPlayerListUpdateGameMode (const cPlayer & a_Player) override;
|
||||
@ -120,7 +119,6 @@ public:
|
||||
virtual void SendSpawnMob (const cMonster & a_Mob) override;
|
||||
virtual void SendStatistics (const cStatManager & a_Manager) override;
|
||||
virtual void SendTabCompletionResults (const AStringVector & a_Results) override;
|
||||
virtual void SendTeleportEntity (const cEntity & a_Entity) override;
|
||||
virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override;
|
||||
virtual void SendTitleTimes (int a_FadeInTicks, int a_DisplayTicks, int a_FadeOutTicks) override;
|
||||
virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) override;
|
||||
|
@ -341,13 +341,13 @@ cProtocol_1_11_0::cProtocol_1_11_0(cClientHandle * a_Client, const AString & a_S
|
||||
|
||||
|
||||
|
||||
void cProtocol_1_11_0::SendCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player, int a_Count)
|
||||
void cProtocol_1_11_0::SendCollectEntity(const cEntity & a_Collected, const cEntity & a_Collector, unsigned a_Count)
|
||||
{
|
||||
ASSERT(m_State == 3); // In game mode?
|
||||
|
||||
cPacketizer Pkt(*this, pktCollectEntity);
|
||||
Pkt.WriteVarInt32(a_Entity.GetUniqueID());
|
||||
Pkt.WriteVarInt32(a_Player.GetUniqueID());
|
||||
Pkt.WriteVarInt32(a_Collected.GetUniqueID());
|
||||
Pkt.WriteVarInt32(a_Collector.GetUniqueID());
|
||||
Pkt.WriteVarInt32(static_cast<UInt32>(a_Count));
|
||||
}
|
||||
|
||||
@ -389,7 +389,7 @@ void cProtocol_1_11_0::SendSpawnMob(const cMonster & a_Mob)
|
||||
Pkt.WriteBEUInt64(0);
|
||||
Pkt.WriteBEUInt64(a_Mob.GetUniqueID());
|
||||
Pkt.WriteVarInt32(GetProtocolMobType(a_Mob.GetMobType()));
|
||||
Vector3d LastSentPos = a_Mob.GetLastSentPos();
|
||||
Vector3d LastSentPos = a_Mob.GetLastSentPosition();
|
||||
Pkt.WriteBEDouble(LastSentPos.x);
|
||||
Pkt.WriteBEDouble(LastSentPos.y);
|
||||
Pkt.WriteBEDouble(LastSentPos.z);
|
||||
|
@ -30,7 +30,7 @@ public:
|
||||
|
||||
cProtocol_1_11_0(cClientHandle * a_Client, const AString &a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State);
|
||||
|
||||
virtual void SendCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player, int a_Count) override;
|
||||
virtual void SendCollectEntity(const cEntity & a_Collected, const cEntity & a_Collector, unsigned a_Count) override;
|
||||
virtual void SendHideTitle (void) override;
|
||||
virtual void SendResetTitle (void) override;
|
||||
virtual void SendSpawnMob (const cMonster & a_Mob) override;
|
||||
|
@ -352,14 +352,14 @@ void cProtocol_1_8_0::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerial
|
||||
|
||||
|
||||
|
||||
void cProtocol_1_8_0::SendCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player, int a_Count)
|
||||
void cProtocol_1_8_0::SendCollectEntity(const cEntity & a_Collected, const cEntity & a_Collector, unsigned a_Count)
|
||||
{
|
||||
UNUSED(a_Count);
|
||||
ASSERT(m_State == 3); // In game mode?
|
||||
|
||||
cPacketizer Pkt(*this, pktCollectEntity);
|
||||
Pkt.WriteVarInt32(a_Entity.GetUniqueID());
|
||||
Pkt.WriteVarInt32(a_Player.GetUniqueID());
|
||||
Pkt.WriteVarInt32(a_Collected.GetUniqueID());
|
||||
Pkt.WriteVarInt32(a_Collector.GetUniqueID());
|
||||
}
|
||||
|
||||
|
||||
@ -430,6 +430,19 @@ void cProtocol_1_8_0::SendEditSign(int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
|
||||
|
||||
|
||||
void cProtocol_1_8_0::SendEntityAnimation(const cEntity & a_Entity, char a_Animation)
|
||||
{
|
||||
ASSERT(m_State == 3); // In game mode?
|
||||
|
||||
cPacketizer Pkt(*this, pktEntityAnimation);
|
||||
Pkt.WriteVarInt32(a_Entity.GetUniqueID());
|
||||
Pkt.WriteBEInt8(a_Animation);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cProtocol_1_8_0::SendEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, int a_Duration)
|
||||
{
|
||||
ASSERT(m_State == 3); // In game mode?
|
||||
@ -502,6 +515,52 @@ void cProtocol_1_8_0::SendEntityMetadata(const cEntity & a_Entity)
|
||||
|
||||
|
||||
|
||||
void cProtocol_1_8_0::SendEntityPosition(const cEntity & a_Entity)
|
||||
{
|
||||
ASSERT(m_State == 3); // In game mode?
|
||||
|
||||
const auto Delta = (a_Entity.GetPosition() - a_Entity.GetLastSentPosition()) * 32;
|
||||
|
||||
// Limitations of a byte
|
||||
static const auto Max = std::numeric_limits<Int8>::max();
|
||||
|
||||
if ((std::abs(Delta.x) <= Max) && (std::abs(Delta.y) <= Max) && (std::abs(Delta.z) <= Max))
|
||||
{
|
||||
const auto Move = static_cast<Vector3<Int8>>(Delta);
|
||||
|
||||
// Difference within limitations, use a relative move packet
|
||||
if (a_Entity.IsOrientationDirty())
|
||||
{
|
||||
cPacketizer Pkt(*this, pktEntityRelMoveLook);
|
||||
Pkt.WriteVarInt32(a_Entity.GetUniqueID());
|
||||
Pkt.WriteBEInt8(Move.x);
|
||||
Pkt.WriteBEInt8(Move.y);
|
||||
Pkt.WriteBEInt8(Move.z);
|
||||
Pkt.WriteByteAngle(a_Entity.GetYaw());
|
||||
Pkt.WriteByteAngle(a_Entity.GetPitch());
|
||||
Pkt.WriteBool(a_Entity.IsOnGround());
|
||||
}
|
||||
else
|
||||
{
|
||||
cPacketizer Pkt(*this, pktEntityRelMove);
|
||||
Pkt.WriteVarInt32(a_Entity.GetUniqueID());
|
||||
Pkt.WriteBEInt8(Move.x);
|
||||
Pkt.WriteBEInt8(Move.y);
|
||||
Pkt.WriteBEInt8(Move.z);
|
||||
Pkt.WriteBool(a_Entity.IsOnGround());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Too big a movement, do a teleport
|
||||
SendEntityTeleport(a_Entity);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cProtocol_1_8_0::SendEntityProperties(const cEntity & a_Entity)
|
||||
{
|
||||
ASSERT(m_State == 3); // In game mode?
|
||||
@ -515,40 +574,6 @@ void cProtocol_1_8_0::SendEntityProperties(const cEntity & a_Entity)
|
||||
|
||||
|
||||
|
||||
void cProtocol_1_8_0::SendEntityRelMove(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ)
|
||||
{
|
||||
ASSERT(m_State == 3); // In game mode?
|
||||
|
||||
cPacketizer Pkt(*this, pktEntityRelMove);
|
||||
Pkt.WriteVarInt32(a_Entity.GetUniqueID());
|
||||
Pkt.WriteBEInt8(a_RelX);
|
||||
Pkt.WriteBEInt8(a_RelY);
|
||||
Pkt.WriteBEInt8(a_RelZ);
|
||||
Pkt.WriteBool(a_Entity.IsOnGround());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cProtocol_1_8_0::SendEntityRelMoveLook(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ)
|
||||
{
|
||||
ASSERT(m_State == 3); // In game mode?
|
||||
|
||||
cPacketizer Pkt(*this, pktEntityRelMoveLook);
|
||||
Pkt.WriteVarInt32(a_Entity.GetUniqueID());
|
||||
Pkt.WriteBEInt8(a_RelX);
|
||||
Pkt.WriteBEInt8(a_RelY);
|
||||
Pkt.WriteBEInt8(a_RelZ);
|
||||
Pkt.WriteByteAngle(a_Entity.GetYaw());
|
||||
Pkt.WriteByteAngle(a_Entity.GetPitch());
|
||||
Pkt.WriteBool(a_Entity.IsOnGround());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cProtocol_1_8_0::SendEntityStatus(const cEntity & a_Entity, char a_Status)
|
||||
{
|
||||
ASSERT(m_State == 3); // In game mode?
|
||||
@ -882,19 +907,6 @@ void cProtocol_1_8_0::SendPlayerAbilities(void)
|
||||
|
||||
|
||||
|
||||
void cProtocol_1_8_0::SendEntityAnimation(const cEntity & a_Entity, char a_Animation)
|
||||
{
|
||||
ASSERT(m_State == 3); // In game mode?
|
||||
|
||||
cPacketizer Pkt(*this, pktEntityAnimation);
|
||||
Pkt.WriteVarInt32(a_Entity.GetUniqueID());
|
||||
Pkt.WriteBEInt8(a_Animation);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cProtocol_1_8_0::SendParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount)
|
||||
{
|
||||
ASSERT(m_State == 3); // In game mode?
|
||||
@ -1133,7 +1145,7 @@ void cProtocol_1_8_0::SendPlayerSpawn(const cPlayer & a_Player)
|
||||
cPacketizer Pkt(*this, pktSpawnOtherPlayer);
|
||||
Pkt.WriteVarInt32(a_Player.GetUniqueID());
|
||||
Pkt.WriteUUID(a_Player.GetUUID());
|
||||
Vector3d LastSentPos = a_Player.GetLastSentPos();
|
||||
Vector3d LastSentPos = a_Player.GetLastSentPosition();
|
||||
Pkt.WriteFPInt(LastSentPos.x);
|
||||
Pkt.WriteFPInt(LastSentPos.y + 0.001); // The "+ 0.001" is there because otherwise the player falls through the block they were standing on.
|
||||
Pkt.WriteFPInt(LastSentPos.z);
|
||||
@ -1386,8 +1398,7 @@ void cProtocol_1_8_0::SendSpawnEntity(const cEntity & a_Entity)
|
||||
}
|
||||
}
|
||||
|
||||
cPacketizer Pkt(*this, pktSpawnObject);
|
||||
WriteEntitySpawn(Pkt, a_Entity, EntityType, EntityData);
|
||||
SendEntitySpawn(a_Entity, EntityType, EntityData);
|
||||
}
|
||||
|
||||
|
||||
@ -1401,7 +1412,7 @@ void cProtocol_1_8_0::SendSpawnMob(const cMonster & a_Mob)
|
||||
cPacketizer Pkt(*this, pktSpawnMob);
|
||||
Pkt.WriteVarInt32(a_Mob.GetUniqueID());
|
||||
Pkt.WriteBEUInt8(static_cast<Byte>(GetProtocolMobType(a_Mob.GetMobType())));
|
||||
Vector3d LastSentPos = a_Mob.GetLastSentPos();
|
||||
Vector3d LastSentPos = a_Mob.GetLastSentPosition();
|
||||
Pkt.WriteFPInt(LastSentPos.x);
|
||||
Pkt.WriteFPInt(LastSentPos.y);
|
||||
Pkt.WriteFPInt(LastSentPos.z);
|
||||
@ -1458,24 +1469,6 @@ void cProtocol_1_8_0::SendTabCompletionResults(const AStringVector & a_Results)
|
||||
|
||||
|
||||
|
||||
void cProtocol_1_8_0::SendTeleportEntity(const cEntity & a_Entity)
|
||||
{
|
||||
ASSERT(m_State == 3); // In game mode?
|
||||
|
||||
cPacketizer Pkt(*this, pktTeleportEntity);
|
||||
Pkt.WriteVarInt32(a_Entity.GetUniqueID());
|
||||
Pkt.WriteFPInt(a_Entity.GetPosX());
|
||||
Pkt.WriteFPInt(a_Entity.GetPosY());
|
||||
Pkt.WriteFPInt(a_Entity.GetPosZ());
|
||||
Pkt.WriteByteAngle(a_Entity.GetYaw());
|
||||
Pkt.WriteByteAngle(a_Entity.GetPitch());
|
||||
Pkt.WriteBool(a_Entity.IsOnGround());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cProtocol_1_8_0::SendThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
ASSERT(m_State == 3); // In game mode?
|
||||
@ -3201,6 +3194,37 @@ void cProtocol_1_8_0::SendPacket(cPacketizer & a_Pkt)
|
||||
|
||||
|
||||
|
||||
void cProtocol_1_8_0::SendEntitySpawn(const cEntity & a_Entity, const UInt8 a_ObjectType, const Int32 a_ObjectData)
|
||||
{
|
||||
ASSERT(m_State == 3); // In game mode?
|
||||
|
||||
{
|
||||
cPacketizer Pkt(*this, pktSpawnObject);
|
||||
Pkt.WriteVarInt32(a_Entity.GetUniqueID());
|
||||
Pkt.WriteBEUInt8(a_ObjectType);
|
||||
Pkt.WriteFPInt(a_Entity.GetPosX()); // Position appears to be ignored...
|
||||
Pkt.WriteFPInt(a_Entity.GetPosY());
|
||||
Pkt.WriteFPInt(a_Entity.GetPosY());
|
||||
Pkt.WriteByteAngle(a_Entity.GetPitch());
|
||||
Pkt.WriteByteAngle(a_Entity.GetYaw());
|
||||
Pkt.WriteBEInt32(a_ObjectData);
|
||||
|
||||
if (a_ObjectData != 0)
|
||||
{
|
||||
Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedX() * 400));
|
||||
Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedY() * 400));
|
||||
Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedZ() * 400));
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise 1.8 clients don't show the entity
|
||||
SendEntityTeleport(a_Entity);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cProtocol_1_8_0::WriteItem(cPacketizer & a_Pkt, const cItem & a_Item)
|
||||
{
|
||||
short ItemType = a_Item.m_ItemType;
|
||||
@ -3831,25 +3855,16 @@ void cProtocol_1_8_0::WriteEntityProperties(cPacketizer & a_Pkt, const cEntity &
|
||||
|
||||
|
||||
|
||||
void cProtocol_1_8_0::WriteEntitySpawn(cPacketizer & a_Pkt, const cEntity & a_Entity, const UInt8 a_ObjectType, const Int32 a_ObjectData)
|
||||
void cProtocol_1_8_0::SendEntityTeleport(const cEntity & a_Entity)
|
||||
{
|
||||
ASSERT(m_State == 3); // In game mode?
|
||||
|
||||
a_Pkt.WriteVarInt32(a_Entity.GetUniqueID());
|
||||
a_Pkt.WriteBEUInt8(a_ObjectType);
|
||||
a_Pkt.WriteFPInt(a_Entity.GetPosX());
|
||||
a_Pkt.WriteFPInt(a_Entity.GetPosY());
|
||||
a_Pkt.WriteFPInt(a_Entity.GetPosY());
|
||||
a_Pkt.WriteByteAngle(a_Entity.GetPitch());
|
||||
a_Pkt.WriteByteAngle(a_Entity.GetYaw());
|
||||
a_Pkt.WriteBEInt32(a_ObjectData);
|
||||
|
||||
if (a_ObjectData != 0)
|
||||
{
|
||||
a_Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedX() * 400));
|
||||
a_Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedY() * 400));
|
||||
a_Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedZ() * 400));
|
||||
}
|
||||
cPacketizer Pkt(*this, pktTeleportEntity);
|
||||
Pkt.WriteVarInt32(a_Entity.GetUniqueID());
|
||||
Pkt.WriteFPInt(a_Entity.GetPosX());
|
||||
Pkt.WriteFPInt(a_Entity.GetPosY());
|
||||
Pkt.WriteFPInt(a_Entity.GetPosZ());
|
||||
Pkt.WriteByteAngle(a_Entity.GetYaw());
|
||||
Pkt.WriteByteAngle(a_Entity.GetPitch());
|
||||
Pkt.WriteBool(a_Entity.IsOnGround());
|
||||
}
|
||||
|
||||
|
||||
|
@ -47,19 +47,19 @@ public:
|
||||
virtual void SendChat (const cCompositeChat & a_Message, eChatType a_Type, bool a_ShouldUseChatPrefixes) override;
|
||||
virtual void SendChatRaw (const AString & a_MessageRaw, eChatType a_Type) override;
|
||||
virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override;
|
||||
virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player, int a_Count) override;
|
||||
virtual void SendCollectEntity (const cEntity & a_Collected, const cEntity & a_Collector, unsigned a_Count) override;
|
||||
virtual void SendDestroyEntity (const cEntity & a_Entity) override;
|
||||
virtual void SendDetachEntity (const cEntity & a_Entity, const cEntity & a_PreviousVehicle) override;
|
||||
virtual void SendDisconnect (const AString & a_Reason) override;
|
||||
virtual void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ) override; ///< Request the client to open up the sign editor for the sign (1.6+)
|
||||
virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) override;
|
||||
virtual void SendEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, int a_Duration) override;
|
||||
virtual void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) override;
|
||||
virtual void SendEntityHeadLook (const cEntity & a_Entity) override;
|
||||
virtual void SendEntityLook (const cEntity & a_Entity) override;
|
||||
virtual void SendEntityMetadata (const cEntity & a_Entity) override;
|
||||
virtual void SendEntityPosition (const cEntity & a_Entity) override;
|
||||
virtual void SendEntityProperties (const cEntity & a_Entity) override;
|
||||
virtual void SendEntityRelMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override;
|
||||
virtual void SendEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override;
|
||||
virtual void SendEntityStatus (const cEntity & a_Entity, char a_Status) override;
|
||||
virtual void SendEntityVelocity (const cEntity & a_Entity) override;
|
||||
virtual void SendExperience (void) override;
|
||||
@ -77,7 +77,6 @@ public:
|
||||
virtual void SendMapData (const cMap & a_Map, int a_DataStartX, int a_DataStartY) override;
|
||||
virtual void SendPaintingSpawn (const cPainting & a_Painting) override;
|
||||
virtual void SendPlayerAbilities (void) override;
|
||||
virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) override;
|
||||
virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) override;
|
||||
virtual void SendParticleEffect (const AString & a_ParticleName, Vector3f a_Src, Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array<int, 2> a_Data) override;
|
||||
virtual void SendPlayerListAddPlayer (const cPlayer & a_Player) override;
|
||||
@ -107,7 +106,6 @@ public:
|
||||
virtual void SendSpawnMob (const cMonster & a_Mob) override;
|
||||
virtual void SendStatistics (const cStatManager & a_Manager) override;
|
||||
virtual void SendTabCompletionResults (const AStringVector & a_Results) override;
|
||||
virtual void SendTeleportEntity (const cEntity & a_Entity) override;
|
||||
virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override;
|
||||
virtual void SendTitleTimes (int a_FadeInTicks, int a_DisplayTicks, int a_FadeOutTicks) override;
|
||||
virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) override;
|
||||
@ -228,6 +226,9 @@ protected:
|
||||
If the received value doesn't match any of our eBlockFace constants, BLOCK_FACE_NONE is returned. */
|
||||
eBlockFace FaceIntToBlockFace(Int8 a_FaceInt);
|
||||
|
||||
/** Sends the entity type and entity-dependent data required for the entity to initially spawn. */
|
||||
virtual void SendEntitySpawn(const cEntity & a_Entity, const UInt8 a_ObjectType, const Int32 a_ObjectData);
|
||||
|
||||
/** Writes the item data into a packet. */
|
||||
virtual void WriteItem(cPacketizer & a_Pkt, const cItem & a_Item);
|
||||
|
||||
@ -240,14 +241,16 @@ protected:
|
||||
/** Writes the entity properties for the specified entity, including the Count field. */
|
||||
virtual void WriteEntityProperties(cPacketizer & a_Pkt, const cEntity & a_Entity);
|
||||
|
||||
/** Writes the entity type and entity-dependent data into a packet structure required for the entity to initially spawn. */
|
||||
virtual void WriteEntitySpawn(cPacketizer & a_Pkt, const cEntity & a_Entity, const UInt8 a_ObjectType, const Int32 a_ObjectData);
|
||||
|
||||
/** Writes the block entity data for the specified block entity into the packet. */
|
||||
virtual void WriteBlockEntity(cPacketizer & a_Pkt, const cBlockEntity & a_BlockEntity);
|
||||
|
||||
private:
|
||||
|
||||
/** Sends an entity teleport packet.
|
||||
Mitigates a 1.8 bug where the position in the entity spawn packet is ignored,
|
||||
and so entities don't show up until a teleport is sent. */
|
||||
void SendEntityTeleport(const cEntity & a_Entity);
|
||||
|
||||
/** Converts an entity to a protocol-specific entity type.
|
||||
Only entities that the Send Spawn Entity packet supports are valid inputs to this method */
|
||||
UInt8 GetProtocolEntityType(const cEntity & a_Entity);
|
||||
|
@ -170,33 +170,50 @@ void cProtocol_1_9_0::SendEntityMetadata(const cEntity & a_Entity)
|
||||
|
||||
|
||||
|
||||
void cProtocol_1_9_0::SendEntityRelMove(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ)
|
||||
void cProtocol_1_9_0::SendEntityPosition(const cEntity & a_Entity)
|
||||
{
|
||||
ASSERT(m_State == 3); // In game mode?
|
||||
|
||||
cPacketizer Pkt(*this, pktEntityRelMove);
|
||||
Pkt.WriteVarInt32(a_Entity.GetUniqueID());
|
||||
// TODO: 1.9 changed these from chars to shorts, meaning that there can be more percision and data. Other code needs to be updated for that.
|
||||
Pkt.WriteBEInt16(a_RelX * 128);
|
||||
Pkt.WriteBEInt16(a_RelY * 128);
|
||||
Pkt.WriteBEInt16(a_RelZ * 128);
|
||||
Pkt.WriteBool(a_Entity.IsOnGround());
|
||||
}
|
||||
const auto Delta = (a_Entity.GetPosition() - a_Entity.GetLastSentPosition()) * 32 * 128;
|
||||
|
||||
// Limitations of a short
|
||||
static const auto Max = std::numeric_limits<Int16>::max();
|
||||
|
||||
if ((std::abs(Delta.x) <= Max) && (std::abs(Delta.y) <= Max) && (std::abs(Delta.z) <= Max))
|
||||
{
|
||||
const auto Move = static_cast<Vector3<Int16>>(Delta);
|
||||
|
||||
|
||||
|
||||
void cProtocol_1_9_0::SendEntityRelMoveLook(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ)
|
||||
{
|
||||
ASSERT(m_State == 3); // In game mode?
|
||||
|
||||
// Difference within limitations, use a relative move packet
|
||||
if (a_Entity.IsOrientationDirty())
|
||||
{
|
||||
cPacketizer Pkt(*this, pktEntityRelMoveLook);
|
||||
Pkt.WriteVarInt32(a_Entity.GetUniqueID());
|
||||
// TODO: 1.9 changed these from chars to shorts, meaning that there can be more percision and data. Other code needs to be updated for that.
|
||||
Pkt.WriteBEInt16(a_RelX * 128);
|
||||
Pkt.WriteBEInt16(a_RelY * 128);
|
||||
Pkt.WriteBEInt16(a_RelZ * 128);
|
||||
Pkt.WriteBEInt16(Move.x);
|
||||
Pkt.WriteBEInt16(Move.y);
|
||||
Pkt.WriteBEInt16(Move.z);
|
||||
Pkt.WriteByteAngle(a_Entity.GetYaw());
|
||||
Pkt.WriteByteAngle(a_Entity.GetPitch());
|
||||
Pkt.WriteBool(a_Entity.IsOnGround());
|
||||
}
|
||||
else
|
||||
{
|
||||
cPacketizer Pkt(*this, pktEntityRelMove);
|
||||
Pkt.WriteVarInt32(a_Entity.GetUniqueID());
|
||||
Pkt.WriteBEInt16(Move.x);
|
||||
Pkt.WriteBEInt16(Move.y);
|
||||
Pkt.WriteBEInt16(Move.z);
|
||||
Pkt.WriteBool(a_Entity.IsOnGround());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Too big a movement, do a teleport
|
||||
cPacketizer Pkt(*this, pktTeleportEntity);
|
||||
Pkt.WriteVarInt32(a_Entity.GetUniqueID());
|
||||
Pkt.WriteBEDouble(a_Entity.GetPosX());
|
||||
Pkt.WriteBEDouble(a_Entity.GetPosY());
|
||||
Pkt.WriteBEDouble(a_Entity.GetPosZ());
|
||||
Pkt.WriteByteAngle(a_Entity.GetYaw());
|
||||
Pkt.WriteByteAngle(a_Entity.GetPitch());
|
||||
Pkt.WriteBool(a_Entity.IsOnGround());
|
||||
@ -386,7 +403,7 @@ void cProtocol_1_9_0::SendPlayerSpawn(const cPlayer & a_Player)
|
||||
cPacketizer Pkt(*this, pktSpawnOtherPlayer);
|
||||
Pkt.WriteVarInt32(a_Player.GetUniqueID());
|
||||
Pkt.WriteUUID(a_Player.GetUUID());
|
||||
Vector3d LastSentPos = a_Player.GetLastSentPos();
|
||||
Vector3d LastSentPos = a_Player.GetLastSentPosition();
|
||||
Pkt.WriteBEDouble(LastSentPos.x);
|
||||
Pkt.WriteBEDouble(LastSentPos.y + 0.001); // The "+ 0.001" is there because otherwise the player falls through the block they were standing on.
|
||||
Pkt.WriteBEDouble(LastSentPos.z);
|
||||
@ -428,7 +445,7 @@ void cProtocol_1_9_0::SendSpawnMob(const cMonster & a_Mob)
|
||||
Pkt.WriteBEUInt64(0);
|
||||
Pkt.WriteBEUInt64(a_Mob.GetUniqueID());
|
||||
Pkt.WriteBEUInt8(static_cast<Byte>(GetProtocolMobType(a_Mob.GetMobType())));
|
||||
Vector3d LastSentPos = a_Mob.GetLastSentPos();
|
||||
Vector3d LastSentPos = a_Mob.GetLastSentPosition();
|
||||
Pkt.WriteBEDouble(LastSentPos.x);
|
||||
Pkt.WriteBEDouble(LastSentPos.y);
|
||||
Pkt.WriteBEDouble(LastSentPos.z);
|
||||
@ -446,24 +463,6 @@ void cProtocol_1_9_0::SendSpawnMob(const cMonster & a_Mob)
|
||||
|
||||
|
||||
|
||||
void cProtocol_1_9_0::SendTeleportEntity(const cEntity & a_Entity)
|
||||
{
|
||||
ASSERT(m_State == 3); // In game mode?
|
||||
|
||||
cPacketizer Pkt(*this, pktTeleportEntity);
|
||||
Pkt.WriteVarInt32(a_Entity.GetUniqueID());
|
||||
Pkt.WriteBEDouble(a_Entity.GetPosX());
|
||||
Pkt.WriteBEDouble(a_Entity.GetPosY());
|
||||
Pkt.WriteBEDouble(a_Entity.GetPosZ());
|
||||
Pkt.WriteByteAngle(a_Entity.GetYaw());
|
||||
Pkt.WriteByteAngle(a_Entity.GetPitch());
|
||||
Pkt.WriteBool(a_Entity.IsOnGround());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cProtocol_1_9_0::SendThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
ASSERT(m_State == 3); // In game mode?
|
||||
@ -1323,6 +1322,33 @@ eHand cProtocol_1_9_0::HandIntToEnum(Int32 a_Hand)
|
||||
|
||||
|
||||
|
||||
void cProtocol_1_9_0::SendEntitySpawn(const cEntity & a_Entity, const UInt8 a_ObjectType, const Int32 a_ObjectData)
|
||||
{
|
||||
ASSERT(m_State == 3); // In game mode?
|
||||
|
||||
cPacketizer Pkt(*this, pktSpawnObject);
|
||||
Pkt.WriteVarInt32(a_Entity.GetUniqueID());
|
||||
|
||||
// TODO: Bad way to write a UUID, and it's not a true UUID, but this is functional for now.
|
||||
Pkt.WriteBEUInt64(0);
|
||||
Pkt.WriteBEUInt64(a_Entity.GetUniqueID());
|
||||
|
||||
Pkt.WriteBEUInt8(a_ObjectType);
|
||||
Pkt.WriteBEDouble(a_Entity.GetPosX());
|
||||
Pkt.WriteBEDouble(a_Entity.GetPosY());
|
||||
Pkt.WriteBEDouble(a_Entity.GetPosZ());
|
||||
Pkt.WriteByteAngle(a_Entity.GetPitch());
|
||||
Pkt.WriteByteAngle(a_Entity.GetYaw());
|
||||
Pkt.WriteBEInt32(a_ObjectData);
|
||||
Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedX() * 400));
|
||||
Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedY() * 400));
|
||||
Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedZ() * 400));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cProtocol_1_9_0::WriteItem(cPacketizer & a_Pkt, const cItem & a_Item)
|
||||
{
|
||||
short ItemType = a_Item.m_ItemType;
|
||||
@ -2173,32 +2199,6 @@ void cProtocol_1_9_0::WriteEntityProperties(cPacketizer & a_Pkt, const cEntity &
|
||||
|
||||
|
||||
|
||||
void cProtocol_1_9_0::WriteEntitySpawn(cPacketizer & a_Pkt, const cEntity & a_Entity, const UInt8 a_ObjectType, const Int32 a_ObjectData)
|
||||
{
|
||||
ASSERT(m_State == 3); // In game mode?
|
||||
|
||||
a_Pkt.WriteVarInt32(a_Entity.GetUniqueID());
|
||||
|
||||
// TODO: Bad way to write a UUID, and it's not a true UUID, but this is functional for now.
|
||||
a_Pkt.WriteBEUInt64(0);
|
||||
a_Pkt.WriteBEUInt64(a_Entity.GetUniqueID());
|
||||
|
||||
a_Pkt.WriteBEUInt8(a_ObjectType);
|
||||
a_Pkt.WriteBEDouble(a_Entity.GetPosX());
|
||||
a_Pkt.WriteBEDouble(a_Entity.GetPosY());
|
||||
a_Pkt.WriteBEDouble(a_Entity.GetPosZ());
|
||||
a_Pkt.WriteByteAngle(a_Entity.GetPitch());
|
||||
a_Pkt.WriteByteAngle(a_Entity.GetYaw());
|
||||
a_Pkt.WriteBEInt32(a_ObjectData);
|
||||
a_Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedX() * 400));
|
||||
a_Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedY() * 400));
|
||||
a_Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedZ() * 400));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// cProtocol_1_9_1:
|
||||
|
||||
|
@ -46,8 +46,7 @@ public:
|
||||
virtual void SendDetachEntity (const cEntity & a_Entity, const cEntity & a_PreviousVehicle) override;
|
||||
virtual void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) override;
|
||||
virtual void SendEntityMetadata (const cEntity & a_Entity) override;
|
||||
virtual void SendEntityRelMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override;
|
||||
virtual void SendEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override;
|
||||
virtual void SendEntityPosition (const cEntity & a_Entity) override;
|
||||
virtual void SendEntityStatus (const cEntity & a_Entity, char a_Status) override;
|
||||
virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override;
|
||||
virtual void SendKeepAlive (UInt32 a_PingID) override;
|
||||
@ -59,7 +58,6 @@ public:
|
||||
virtual void SendPlayerSpawn (const cPlayer & a_Player) override;
|
||||
virtual void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch) override;
|
||||
virtual void SendSpawnMob (const cMonster & a_Mob) override;
|
||||
virtual void SendTeleportEntity (const cEntity & a_Entity) override;
|
||||
virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override;
|
||||
virtual void SendUnleashEntity (const cEntity & a_Entity) override;
|
||||
virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override;
|
||||
@ -111,6 +109,9 @@ protected:
|
||||
If the received value doesn't match any of the know value, raise an assertion fail or return hMain. */
|
||||
eHand HandIntToEnum(Int32 a_Hand);
|
||||
|
||||
/** Sends the entity type and entity-dependent data required for the entity to initially spawn. */
|
||||
virtual void SendEntitySpawn(const cEntity & a_Entity, const UInt8 a_ObjectType, const Int32 a_ObjectData) override;
|
||||
|
||||
/** Writes the item data into a packet. */
|
||||
virtual void WriteItem(cPacketizer & a_Pkt, const cItem & a_Item) override;
|
||||
|
||||
@ -123,9 +124,6 @@ protected:
|
||||
/** Writes the entity properties for the specified entity, including the Count field. */
|
||||
virtual void WriteEntityProperties(cPacketizer & a_Pkt, const cEntity & a_Entity) override;
|
||||
|
||||
/** Writes the entity type and entity-dependent data into a packet structure required for the entity to initially spawn. */
|
||||
virtual void WriteEntitySpawn(cPacketizer & a_Pkt, const cEntity & a_Entity, const UInt8 a_ObjectType, const Int32 a_ObjectData) override;
|
||||
|
||||
/** Writes the block entity data for the specified block entity into the packet. */
|
||||
virtual void WriteBlockEntity(cPacketizer & a_Pkt, const cBlockEntity & a_BlockEntity) override;
|
||||
|
||||
|
@ -2620,10 +2620,7 @@ void cSlotAreaTemporary::TossItems(cPlayer & a_Player, int a_Begin, int a_End)
|
||||
Item.Empty();
|
||||
} // for i - itr->second[]
|
||||
|
||||
double vX = 0, vY = 0, vZ = 0;
|
||||
EulerToVector(-a_Player.GetYaw(), a_Player.GetPitch(), vZ, vX, vY);
|
||||
vY = -vY * 2 + 1.f;
|
||||
a_Player.GetWorld()->SpawnItemPickups(Drops, a_Player.GetPosX(), a_Player.GetPosY() + 1.6f, a_Player.GetPosZ(), vX * 3, vY * 3, vZ * 3, true); // 'true' because player created
|
||||
a_Player.TossItems(Drops);
|
||||
}
|
||||
|
||||
|
||||
|
@ -182,7 +182,7 @@ public:
|
||||
virtual void BroadcastChat (const cCompositeChat & a_Message, const cClientHandle * a_Exclude = nullptr) override;
|
||||
// tolua_end
|
||||
|
||||
virtual void BroadcastCollectEntity (const cEntity & a_Pickup, const cPlayer & a_Player, int a_Count, const cClientHandle * a_Exclude = nullptr) override;
|
||||
virtual void BroadcastCollectEntity (const cEntity & a_Collected, const cEntity & a_Collector, unsigned a_Count, const cClientHandle * a_Exclude = nullptr) override;
|
||||
virtual void BroadcastDestroyEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr) override;
|
||||
virtual void BroadcastDetachEntity (const cEntity & a_Entity, const cEntity & a_PreviousVehicle) override;
|
||||
virtual void BroadcastEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, int a_Duration, const cClientHandle * a_Exclude = nullptr) override;
|
||||
@ -190,8 +190,7 @@ public:
|
||||
virtual void BroadcastEntityHeadLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr) override;
|
||||
virtual void BroadcastEntityLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr) override;
|
||||
virtual void BroadcastEntityMetadata (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr) override;
|
||||
virtual void BroadcastEntityRelMove (const cEntity & a_Entity, Vector3<Int8> a_RelMove, const cClientHandle * a_Exclude = nullptr) override;
|
||||
virtual void BroadcastEntityRelMoveLook (const cEntity & a_Entity, Vector3<Int8> a_RelMove, const cClientHandle * a_Exclude = nullptr) override;
|
||||
virtual void BroadcastEntityPosition (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr) override;
|
||||
virtual void BroadcastEntityStatus (const cEntity & a_Entity, Int8 a_Status, const cClientHandle * a_Exclude = nullptr) override;
|
||||
virtual void BroadcastEntityVelocity (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr) override;
|
||||
virtual void BroadcastEntityAnimation (const cEntity & a_Entity, Int8 a_Animation, const cClientHandle * a_Exclude = nullptr) override; // tolua_export
|
||||
@ -210,7 +209,6 @@ public:
|
||||
virtual void BroadcastSoundEffect (const AString & a_SoundName, Vector3d a_Position, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = nullptr) override; // Exported in ManualBindings_World.cpp
|
||||
virtual void BroadcastSoundParticleEffect (const EffectID a_EffectID, Vector3i a_SrcPos, int a_Data, const cClientHandle * a_Exclude = nullptr) override; // Exported in ManualBindings_World.cpp
|
||||
virtual void BroadcastSpawnEntity (cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr) override;
|
||||
virtual void BroadcastTeleportEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr) override;
|
||||
virtual void BroadcastThunderbolt (Vector3i a_BlockPos, const cClientHandle * a_Exclude = nullptr) override;
|
||||
virtual void BroadcastTimeUpdate (const cClientHandle * a_Exclude = nullptr) override;
|
||||
virtual void BroadcastUnleashEntity (const cEntity & a_Entity) override;
|
||||
|
Loading…
Reference in New Issue
Block a user