summaryrefslogtreecommitdiffstats
path: root/src/Entities
diff options
context:
space:
mode:
authorTiger Wang <ziwei.tiger@hotmail.co.uk>2014-07-20 11:46:45 +0200
committerTiger Wang <ziwei.tiger@hotmail.co.uk>2014-07-20 11:46:45 +0200
commit6ab9afd0fd808fad99cd8387c72ce461c37aef80 (patch)
treec7fdd4f7cdc75b4958c297e55e2801510654ee76 /src/Entities
parentFix failed merge and other issues (diff)
downloadcuberite-6ab9afd0fd808fad99cd8387c72ce461c37aef80.tar
cuberite-6ab9afd0fd808fad99cd8387c72ce461c37aef80.tar.gz
cuberite-6ab9afd0fd808fad99cd8387c72ce461c37aef80.tar.bz2
cuberite-6ab9afd0fd808fad99cd8387c72ce461c37aef80.tar.lz
cuberite-6ab9afd0fd808fad99cd8387c72ce461c37aef80.tar.xz
cuberite-6ab9afd0fd808fad99cd8387c72ce461c37aef80.tar.zst
cuberite-6ab9afd0fd808fad99cd8387c72ce461c37aef80.zip
Diffstat (limited to 'src/Entities')
-rw-r--r--src/Entities/Entity.cpp48
-rw-r--r--src/Entities/Entity.h15
-rw-r--r--src/Entities/Player.cpp35
-rw-r--r--src/Entities/Player.h15
4 files changed, 65 insertions, 48 deletions
diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp
index bd1839580..4768d38ae 100644
--- a/src/Entities/Entity.cpp
+++ b/src/Entities/Entity.cpp
@@ -37,7 +37,7 @@ cEntity::cEntity(eEntityType a_EntityType, double a_X, double a_Y, double a_Z, d
, m_Gravity(-9.81f)
, m_LastPos(a_X, a_Y, a_Z)
, m_IsInitialized(false)
- , m_IsTravellingThroughPortal(false)
+ , m_WorldTravellingFrom(NULL)
, m_EntityType(a_EntityType)
, m_World(NULL)
, m_IsFireproof(false)
@@ -1028,10 +1028,11 @@ void cEntity::DetectCacti(void)
void cEntity::DetectPortal()
{
- if (!GetWorld()->GetNetherWorldName().empty() && !GetWorld()->GetEndWorldName().empty())
+ if (GetWorld()->GetDimension() == dimOverworld)
{
- return;
+ if (GetWorld()->GetNetherWorldName().empty() && GetWorld()->GetEndWorldName().empty()) { return; }
}
+ else if (GetWorld()->GetLinkedOverworldName().empty()) { return; }
int X = POSX_TOINT, Y = POSY_TOINT, Z = POSZ_TOINT;
if ((Y > 0) && (Y < cChunkDef::Height))
@@ -1040,7 +1041,7 @@ void cEntity::DetectPortal()
{
case E_BLOCK_NETHER_PORTAL:
{
- if (GetWorld()->GetNetherWorldName().empty() || m_PortalCooldownData.second)
+ if (m_PortalCooldownData.second)
{
return;
}
@@ -1054,8 +1055,13 @@ void cEntity::DetectPortal()
switch (GetWorld()->GetDimension())
{
- case dimNether:
+ case dimNether:
{
+ if (GetWorld()->GetLinkedOverworldName().empty())
+ {
+ return;
+ }
+
m_PortalCooldownData.second = true; // Stop portals from working on respawn
if (IsPlayer())
@@ -1068,6 +1074,11 @@ void cEntity::DetectPortal()
}
case dimOverworld:
{
+ if (GetWorld()->GetNetherWorldName().empty())
+ {
+ return;
+ }
+
m_PortalCooldownData.second = true; // Stop portals from working on respawn
if (IsPlayer())
@@ -1079,28 +1090,25 @@ void cEntity::DetectPortal()
return;
}
- default: break;
+ default: return;
}
- return;
}
case E_BLOCK_END_PORTAL:
{
- if (GetWorld()->GetNetherWorldName().empty() || m_PortalCooldownData.second)
- {
- return;
- }
-
- if (m_PortalCooldownData.first != 80)
+ if (m_PortalCooldownData.second)
{
- m_PortalCooldownData.first++;
return;
}
- m_PortalCooldownData.first = 0;
switch (GetWorld()->GetDimension())
{
case dimEnd:
{
+ if (GetWorld()->GetLinkedOverworldName().empty())
+ {
+ return;
+ }
+
m_PortalCooldownData.second = true; // Stop portals from working on respawn
if (IsPlayer())
@@ -1115,6 +1123,11 @@ void cEntity::DetectPortal()
}
case dimOverworld:
{
+ if (GetWorld()->GetEndWorldName().empty())
+ {
+ return;
+ }
+
m_PortalCooldownData.second = true; // Stop portals from working on respawn
if (IsPlayer())
@@ -1126,9 +1139,8 @@ void cEntity::DetectPortal()
return;
}
- default: break;
+ default: return;
}
- return;
}
default: break;
}
@@ -1169,7 +1181,7 @@ bool cEntity::MoveToWorld(const AString & a_WorldName, cWorld * a_World, bool a_
}
// Remove all links to the old world
- SetIsTravellingThroughPortal(true); // cChunk handles entity removal
+ SetWorldTravellingFrom(GetWorld()); // cChunk handles entity removal
GetWorld()->BroadcastDestroyEntity(*this);
// Queue add to new world
diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h
index 8b6fc05f7..eea48a12f 100644
--- a/src/Entities/Entity.h
+++ b/src/Entities/Entity.h
@@ -387,11 +387,11 @@ public:
// tolua_end
- /** Returns if the entity is travelling through a portal. Set to true by MoveToWorld and to false when the entity is removed by the old chunk */
- bool IsTravellingThroughPortal(void) const { return m_IsTravellingThroughPortal; }
+ /** Returns if the entity is travelling away from a specified world */
+ bool IsWorldTravellingFrom(cWorld * a_World) const { return (m_WorldTravellingFrom == a_World); }
- /** Sets if the entity has begun travelling through a portal or not */
- void SetIsTravellingThroughPortal(bool a_Flag) { m_IsTravellingThroughPortal = a_Flag; }
+ /** Sets the world the entity will be leaving */
+ void SetWorldTravellingFrom(cWorld * a_World) { (m_WorldTravellingFrom = a_World); }
/// Updates clients of changes in the entity.
virtual void BroadcastMovementUpdate(const cClientHandle * a_Exclude = NULL);
@@ -491,8 +491,11 @@ protected:
/** True when entity is initialised (Initialize()) and false when destroyed pending deletion (Destroy()) */
bool m_IsInitialized;
- /** True when entity is being moved across worlds, false anytime else */
- bool m_IsTravellingThroughPortal;
+ /** World entity is travelling from
+ Set by MoveToWorld and back to NULL when the entity is removed by the old chunk
+ Can't be a simple boolean as context switches between worlds may leave the new chunk processing (and therefore immediately removing) the entity before the old chunk could remove it
+ */
+ cWorld * m_WorldTravellingFrom;
eEntityType m_EntityType;
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index 2a91600e7..0b1b4ce5f 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -88,7 +88,7 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName) :
m_PlayerName = a_PlayerName;
- cWorld * World;
+ cWorld * World = NULL;
if (!LoadFromDisk(World))
{
m_Inventory.Clear();
@@ -136,8 +136,6 @@ cPlayer::~cPlayer(void)
SaveToDisk();
- m_World->RemovePlayer(this);
-
m_ClientHandle = NULL;
delete m_InventoryWindow;
@@ -979,7 +977,7 @@ void cPlayer::Respawn(void)
m_LifetimeTotalXp = 0;
// ToDo: send score to client? How?
- m_ClientHandle->SendRespawn(GetWorld()->GetDimension());
+ m_ClientHandle->SendRespawn(GetWorld()->GetDimension(), true);
// Extinguish the fire:
StopBurning();
@@ -1643,11 +1641,12 @@ bool cPlayer::MoveToWorld(const AString & a_WorldName, cWorld * a_World, bool a_
}
// Remove player from the old world
- SetIsTravellingThroughPortal(true); // cChunk handles entity removal
- m_World->RemovePlayer(this);
+ SetWorldTravellingFrom(GetWorld()); // cChunk handles entity removal
+ GetWorld()->RemovePlayer(this);
// Queue adding player to the new world, including all the necessary adjustments to the object
World->AddPlayer(this);
+ SetWorld(World);
return true;
}
@@ -1697,12 +1696,6 @@ void cPlayer::LoadPermissionsFromDisk()
bool cPlayer::LoadFromDisk(cWorldPtr & a_World)
{
- a_World = cRoot::Get()->GetWorld(GetLoadedWorldName());
- if (a_World == NULL)
- {
- a_World = cRoot::Get()->GetDefaultWorld();
- }
-
LoadPermissionsFromDisk();
// Load from the UUID file:
@@ -1740,6 +1733,11 @@ bool cPlayer::LoadFromDisk(cWorldPtr & a_World)
LOG("Player data file not found for %s (%s, offline %s), will be reset to defaults.",
GetName().c_str(), m_UUID.c_str(), OfflineUUID.c_str()
);
+
+ if (a_World == NULL)
+ {
+ a_World = cRoot::Get()->GetDefaultWorld();
+ }
return false;
}
@@ -1747,7 +1745,7 @@ bool cPlayer::LoadFromDisk(cWorldPtr & a_World)
-bool cPlayer::LoadFromFile(const AString & a_FileName, cWorld * a_World)
+bool cPlayer::LoadFromFile(const AString & a_FileName, cWorldPtr & a_World)
{
// Load the data from the file:
cFile f;
@@ -1800,9 +1798,6 @@ bool cPlayer::LoadFromFile(const AString & a_FileName, cWorld * a_World)
m_LifetimeTotalXp = (short) root.get("xpTotal", 0).asInt();
m_CurrentXp = (short) root.get("xpCurrent", 0).asInt();
m_IsFlying = root.get("isflying", 0).asBool();
- m_LastBedPos.x = root.get("SpawnX", a_World->GetSpawnX()).asInt();
- m_LastBedPos.y = root.get("SpawnY", a_World->GetSpawnY()).asInt();
- m_LastBedPos.z = root.get("SpawnZ", a_World->GetSpawnZ()).asInt();
m_GameMode = (eGameMode) root.get("gamemode", eGameMode_NotSet).asInt();
@@ -1815,6 +1810,11 @@ bool cPlayer::LoadFromFile(const AString & a_FileName, cWorld * a_World)
cEnderChestEntity::LoadFromJson(root["enderchestinventory"], m_EnderChestContents);
m_LoadedWorldName = root.get("world", "world").asString();
+ a_World = cRoot::Get()->GetWorld(GetLoadedWorldName(), true);
+
+ m_LastBedPos.x = root.get("SpawnX", a_World->GetSpawnX()).asInt();
+ m_LastBedPos.y = root.get("SpawnY", a_World->GetSpawnY()).asInt();
+ m_LastBedPos.z = root.get("SpawnZ", a_World->GetSpawnZ()).asInt();
// Load the player stats.
// We use the default world name (like bukkit) because stats are shared between dimensions/worlds.
@@ -1822,7 +1822,7 @@ bool cPlayer::LoadFromFile(const AString & a_FileName, cWorld * a_World)
StatSerializer.Load();
LOGD("Player %s was read from file \"%s\", spawning at {%.2f, %.2f, %.2f} in world \"%s\"",
- GetName().c_str(), a_FileName.c_str(), GetPosX(), GetPosY(), GetPosZ(), m_LoadedWorldName.c_str()
+ GetName().c_str(), a_FileName.c_str(), GetPosX(), GetPosY(), GetPosZ(), a_World->GetName().c_str()
);
return true;
@@ -1834,7 +1834,6 @@ bool cPlayer::LoadFromFile(const AString & a_FileName, cWorld * a_World)
bool cPlayer::SaveToDisk()
{
- cFile::CreateFolder(FILE_IO_PREFIX + AString("players"));
cFile::CreateFolder(FILE_IO_PREFIX + AString("players/") + m_UUID.substr(0, 2));
// create the JSON data
diff --git a/src/Entities/Player.h b/src/Entities/Player.h
index ad434f036..226ec5e68 100644
--- a/src/Entities/Player.h
+++ b/src/Entities/Player.h
@@ -340,14 +340,17 @@ public:
typedef cWorld * cWorldPtr;
- /** Loads the player data from the disk file.
-Takes a (NULL) cWorld pointer which it will assign a value to based on either the loaded world or default world
- Returns true on success, false on failure. */
+ /** Loads the player data from the disk file
+ Takes a (NULL) cWorld pointer which it will assign a value to based on either the loaded world or default world by calling LoadFromFile()
+ Returns true on success, false on failure
+ */
bool LoadFromDisk(cWorldPtr & a_World);
- /** Loads the player data from the specified file.
- Returns true on success, false on failure. */
- bool LoadFromFile(const AString & a_FileName, cWorld * a_World);
+ /** Loads the player data from the specified file
+ Takes a (NULL) cWorld pointer which it will assign a value to based on either the loaded world or default world
+ Returns true on success, false on failure
+ */
+ bool LoadFromFile(const AString & a_FileName, cWorldPtr & a_World);
void LoadPermissionsFromDisk(void); // tolua_export