summaryrefslogtreecommitdiffstats
path: root/src/Entities
diff options
context:
space:
mode:
authorTiger Wang <ziwei.tiger@hotmail.co.uk>2014-07-21 23:49:06 +0200
committerTiger Wang <ziwei.tiger@hotmail.co.uk>2014-07-21 23:49:06 +0200
commit8050a5b98a3003c2a4bed39b896b4a3a4c1068c0 (patch)
treebb0be233efcf1052125862812569ce3874b4d9d0 /src/Entities
parentBug and crash fixes (diff)
downloadcuberite-8050a5b98a3003c2a4bed39b896b4a3a4c1068c0.tar
cuberite-8050a5b98a3003c2a4bed39b896b4a3a4c1068c0.tar.gz
cuberite-8050a5b98a3003c2a4bed39b896b4a3a4c1068c0.tar.bz2
cuberite-8050a5b98a3003c2a4bed39b896b4a3a4c1068c0.tar.lz
cuberite-8050a5b98a3003c2a4bed39b896b4a3a4c1068c0.tar.xz
cuberite-8050a5b98a3003c2a4bed39b896b4a3a4c1068c0.tar.zst
cuberite-8050a5b98a3003c2a4bed39b896b4a3a4c1068c0.zip
Diffstat (limited to 'src/Entities')
-rw-r--r--src/Entities/Entity.cpp78
-rw-r--r--src/Entities/Entity.h30
-rw-r--r--src/Entities/Player.cpp25
-rw-r--r--src/Entities/Player.h2
4 files changed, 70 insertions, 65 deletions
diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp
index 4768d38ae..1254541ed 100644
--- a/src/Entities/Entity.cpp
+++ b/src/Entities/Entity.cpp
@@ -1030,9 +1030,15 @@ void cEntity::DetectPortal()
{
if (GetWorld()->GetDimension() == dimOverworld)
{
- if (GetWorld()->GetNetherWorldName().empty() && GetWorld()->GetEndWorldName().empty()) { return; }
+ if (GetWorld()->GetNetherWorldName().empty() && GetWorld()->GetEndWorldName().empty())
+ {
+ return;
+ }
+ }
+ else if (GetWorld()->GetLinkedOverworldName().empty())
+ {
+ return;
}
- else if (GetWorld()->GetLinkedOverworldName().empty()) { return; }
int X = POSX_TOINT, Y = POSY_TOINT, Z = POSZ_TOINT;
if ((Y > 0) && (Y < cChunkDef::Height))
@@ -1041,17 +1047,17 @@ void cEntity::DetectPortal()
{
case E_BLOCK_NETHER_PORTAL:
{
- if (m_PortalCooldownData.second)
+ if (m_PortalCooldownData.m_ShouldPreventTeleportation)
{
return;
}
- if (m_PortalCooldownData.first != 80)
+ if (IsPlayer() && !((cPlayer *)this)->IsGameModeCreative() && m_PortalCooldownData.m_TicksDelayed != 80)
{
- m_PortalCooldownData.first++;
+ m_PortalCooldownData.m_TicksDelayed++;
return;
}
- m_PortalCooldownData.first = 0;
+ m_PortalCooldownData.m_TicksDelayed = 0;
switch (GetWorld()->GetDimension())
{
@@ -1062,13 +1068,13 @@ void cEntity::DetectPortal()
return;
}
- m_PortalCooldownData.second = true; // Stop portals from working on respawn
+ m_PortalCooldownData.m_ShouldPreventTeleportation = true; // Stop portals from working on respawn
if (IsPlayer())
{
((cPlayer *)this)->GetClientHandle()->SendRespawn(dimOverworld);
}
- MoveToWorld(GetWorld()->GetLinkedOverworldName(), cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetLinkedOverworldName()), false);
+ MoveToWorld(cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetLinkedOverworldName()), false);
return;
}
@@ -1079,14 +1085,14 @@ void cEntity::DetectPortal()
return;
}
- m_PortalCooldownData.second = true; // Stop portals from working on respawn
+ m_PortalCooldownData.m_ShouldPreventTeleportation = true; // Stop portals from working on respawn
if (IsPlayer())
{
((cPlayer *)this)->AwardAchievement(achEnterPortal);
((cPlayer *)this)->GetClientHandle()->SendRespawn(dimNether);
}
- MoveToWorld(GetWorld()->GetNetherWorldName(), cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetNetherWorldName(), dimNether, GetWorld()->GetName()), false);
+ MoveToWorld(cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetNetherWorldName(), dimNether, GetWorld()->GetName()), false);
return;
}
@@ -1095,7 +1101,7 @@ void cEntity::DetectPortal()
}
case E_BLOCK_END_PORTAL:
{
- if (m_PortalCooldownData.second)
+ if (m_PortalCooldownData.m_ShouldPreventTeleportation)
{
return;
}
@@ -1109,7 +1115,7 @@ void cEntity::DetectPortal()
return;
}
- m_PortalCooldownData.second = true; // Stop portals from working on respawn
+ m_PortalCooldownData.m_ShouldPreventTeleportation = true; // Stop portals from working on respawn
if (IsPlayer())
{
@@ -1117,7 +1123,7 @@ void cEntity::DetectPortal()
Player->TeleportToCoords(Player->GetLastBedPos().x, Player->GetLastBedPos().y, Player->GetLastBedPos().z);
Player->GetClientHandle()->SendRespawn(dimOverworld);
}
- MoveToWorld(GetWorld()->GetLinkedOverworldName(), cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetLinkedOverworldName()), false);
+ MoveToWorld(cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetLinkedOverworldName()), false);
return;
}
@@ -1128,14 +1134,14 @@ void cEntity::DetectPortal()
return;
}
- m_PortalCooldownData.second = true; // Stop portals from working on respawn
+ m_PortalCooldownData.m_ShouldPreventTeleportation = true; // Stop portals from working on respawn
if (IsPlayer())
{
((cPlayer *)this)->AwardAchievement(achEnterTheEnd);
((cPlayer *)this)->GetClientHandle()->SendRespawn(dimEnd);
}
- MoveToWorld(GetWorld()->GetEndWorldName(), cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetEndWorldName(), dimEnd, GetWorld()->GetName()), false);
+ MoveToWorld(cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetEndWorldName(), dimEnd, GetWorld()->GetName()), false);
return;
}
@@ -1147,34 +1153,20 @@ void cEntity::DetectPortal()
}
// Allow portals to work again
- m_PortalCooldownData.second = false;
- m_PortalCooldownData.first = 0;
+ m_PortalCooldownData.m_ShouldPreventTeleportation = false;
+ m_PortalCooldownData.m_ShouldPreventTeleportation = 0;
}
-bool cEntity::MoveToWorld(const AString & a_WorldName, cWorld * a_World, bool a_ShouldSendRespawn)
+bool cEntity::MoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn)
{
UNUSED(a_ShouldSendRespawn);
+ ASSERT(a_World == NULL);
- cWorld * World;
- if (a_World == NULL)
- {
- World = cRoot::Get()->GetWorld(a_WorldName);
- if (World == NULL)
- {
- LOG("%s: Couldn't find world \"%s\".", __FUNCTION__, a_WorldName.c_str());
- return false;
- }
- }
- else
- {
- World = a_World;
- }
-
- if (GetWorld() == World)
+ if (GetWorld() == a_World)
{
// Don't move to same world
return false;
@@ -1185,7 +1177,7 @@ bool cEntity::MoveToWorld(const AString & a_WorldName, cWorld * a_World, bool a_
GetWorld()->BroadcastDestroyEntity(*this);
// Queue add to new world
- World->AddEntity(this);
+ a_World->AddEntity(this);
return true;
}
@@ -1194,6 +1186,22 @@ bool cEntity::MoveToWorld(const AString & a_WorldName, cWorld * a_World, bool a_
+bool cEntity::MoveToWorld(const AString & a_WorldName, bool a_ShouldSendRespawn)
+{
+ cWorld * World = cRoot::Get()->GetWorld(a_WorldName);
+ if (World == NULL)
+ {
+ LOG("%s: Couldn't find world \"%s\".", __FUNCTION__, a_WorldName.c_str());
+ return false;
+ }
+
+ return MoveToWorld(World, a_ShouldSendRespawn);
+}
+
+
+
+
+
void cEntity::SetSwimState(cChunk & a_Chunk)
{
int RelY = (int)floor(GetPosY() + 0.1);
diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h
index eea48a12f..58254a493 100644
--- a/src/Entities/Entity.h
+++ b/src/Entities/Entity.h
@@ -382,16 +382,19 @@ public:
/// Teleports to the coordinates specified
virtual void TeleportToCoords(double a_PosX, double a_PosY, double a_PosZ);
- /** Moves entity to specified world */
- virtual bool MoveToWorld(const AString & a_WorldName, cWorld * a_World = NULL, bool a_ShouldSendRespawn = true);
+ /** Moves entity to specified world, taking a world pointer */
+ virtual bool MoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn = true);
+
+ /** Moves entity to specified world, taking a world name */
+ bool MoveToWorld(const AString & a_WorldName, bool a_ShouldSendRespawn = true);
// tolua_end
/** Returns if the entity is travelling away from a specified world */
- bool IsWorldTravellingFrom(cWorld * a_World) const { return (m_WorldTravellingFrom == a_World); }
+ bool IsWorldTravellingFrom(cWorld * a_World) const { return m_WorldTravellingFrom == a_World; }
/** Sets the world the entity will be leaving */
- void SetWorldTravellingFrom(cWorld * a_World) { (m_WorldTravellingFrom = a_World); }
+ void SetWorldTravellingFrom(cWorld * a_World) { m_WorldTravellingFrom = a_World; }
/// Updates clients of changes in the entity.
virtual void BroadcastMovementUpdate(const cClientHandle * a_Exclude = NULL);
@@ -538,11 +541,20 @@ protected:
int m_AirLevel;
int m_AirTickTimer;
- /** Portal delay timer and cooldown boolean
- First value is to delay sending the respawn packet (which triggers the Entering the {Dimension} screen).
- Second value is to prevent a teleportation loop by ensuring we do not reenter a portal that we came out of.
- */
- std::pair<unsigned short, bool> m_PortalCooldownData;
+ /** Structure storing the portal delay timer and cooldown boolean */
+ struct sPortalCooldownData
+ {
+ /** Ticks since entry of portal, used to delay teleportation */
+ unsigned short m_TicksDelayed;
+
+ /** Whether the entity has just exited the portal, and should therefore not be teleported again
+ This prevents teleportation loops, and is reset when the entity has moved out of the portal
+ */
+ bool m_ShouldPreventTeleportation;
+ };
+
+ /** Portal delay timer and cooldown boolean data */
+ sPortalCooldownData m_PortalCooldownData;
private:
/** Measured in degrees, [-180, +180) */
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index 0b1b4ce5f..1159891cd 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -1611,24 +1611,9 @@ void cPlayer::TossItems(const cItems & a_Items)
-bool cPlayer::MoveToWorld(const AString & a_WorldName, cWorld * a_World, bool a_ShouldSendRespawn)
+bool cPlayer::MoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn)
{
- cWorld * World;
- if (a_World == NULL)
- {
- World = cRoot::Get()->GetWorld(a_WorldName);
- if (World == NULL)
- {
- LOG("%s: Couldn't find world \"%s\".", __FUNCTION__, a_WorldName.c_str());
- return false;
- }
- }
- else
- {
- World = a_World;
- }
-
- if (GetWorld() == World)
+ if (GetWorld() == a_World)
{
// Don't move to same world
return false;
@@ -1637,7 +1622,7 @@ bool cPlayer::MoveToWorld(const AString & a_WorldName, cWorld * a_World, bool a_
// Send the respawn packet:
if (a_ShouldSendRespawn && (m_ClientHandle != NULL))
{
- m_ClientHandle->SendRespawn(World->GetDimension());
+ m_ClientHandle->SendRespawn(a_World->GetDimension());
}
// Remove player from the old world
@@ -1645,8 +1630,8 @@ bool cPlayer::MoveToWorld(const AString & a_WorldName, cWorld * a_World, bool a_
GetWorld()->RemovePlayer(this);
// Queue adding player to the new world, including all the necessary adjustments to the object
- World->AddPlayer(this);
- SetWorld(World);
+ a_World->AddPlayer(this);
+ SetWorld(a_World); // Chunks may be streamed before cWorld::AddPlayer() sets the world to the new value
return true;
}
diff --git a/src/Entities/Player.h b/src/Entities/Player.h
index 226ec5e68..f972063bb 100644
--- a/src/Entities/Player.h
+++ b/src/Entities/Player.h
@@ -333,7 +333,7 @@ public:
/** Moves the player to the specified world.
Returns true if successful, false on failure (world not found). */
- virtual bool MoveToWorld(const AString & a_WorldName, cWorld * a_World = NULL, bool a_ShouldSendRespawn = true) override; // tolua_export
+ virtual bool MoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn = true) override; // tolua_export
/** Saves all player data, such as inventory, to JSON */
bool SaveToDisk(void);