summaryrefslogtreecommitdiffstats
path: root/src/Entities
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/Entities/ArrowEntity.cpp15
-rw-r--r--src/Entities/ArrowEntity.h6
-rw-r--r--src/Entities/Boat.cpp12
-rw-r--r--src/Entities/Entity.cpp63
-rw-r--r--src/Entities/Entity.h6
-rw-r--r--src/Entities/Pickup.cpp7
-rw-r--r--src/Entities/Player.cpp40
-rw-r--r--src/Entities/Player.h6
8 files changed, 55 insertions, 100 deletions
diff --git a/src/Entities/ArrowEntity.cpp b/src/Entities/ArrowEntity.cpp
index ebb8524f1..e2bc6ffe0 100644
--- a/src/Entities/ArrowEntity.cpp
+++ b/src/Entities/ArrowEntity.cpp
@@ -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
diff --git a/src/Entities/ArrowEntity.h b/src/Entities/ArrowEntity.h
index 474932514..6b6e5d010 100644
--- a/src/Entities/ArrowEntity.h
+++ b/src/Entities/ArrowEntity.h
@@ -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;
diff --git a/src/Entities/Boat.cpp b/src/Entities/Boat.cpp
index 872b7e4d4..317a5e1d5 100644
--- a/src/Entities/Boat.cpp
+++ b/src/Entities/Boat.cpp
@@ -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;
}
}
diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp
index 431d5f54b..8c2b6fea8 100644
--- a/src/Entities/Entity.cpp
+++ b/src/Entities/Entity.cpp
@@ -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,51 +1933,31 @@ 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_LastSentPosition = GetPosition();
- m_bHasSentNoSpeed = true;
- }
+ m_World->BroadcastEntityVelocity(*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);
- }
- // 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;
- }
+ 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();
+ m_bDirtyOrientation = false;
}
if (m_bDirtyHead)
@@ -1990,6 +1965,7 @@ void cEntity::BroadcastMovementUpdate(const cClientHandle * a_Exclude)
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;
diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h
index 15a9cc824..7d8238c21 100644
--- a/src/Entities/Entity.h
+++ b/src/Entities/Entity.h
@@ -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();
diff --git a/src/Entities/Pickup.cpp b/src/Entities/Pickup.cpp
index 785d29ce9..1faeadaa7 100644
--- a/src/Entities/Pickup.cpp
+++ b/src/Entities/Pickup.cpp
@@ -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));
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index 46a1606d0..3f2ab21c1 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -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);
diff --git a/src/Entities/Player.h b/src/Entities/Player.h
index a28e37be0..592b91546 100644
--- a/src/Entities/Player.h
+++ b/src/Entities/Player.h
@@ -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);