summaryrefslogtreecommitdiffstats
path: root/src/World.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/World.cpp111
1 files changed, 82 insertions, 29 deletions
diff --git a/src/World.cpp b/src/World.cpp
index ccd47d3b0..ebe6b53e6 100644
--- a/src/World.cpp
+++ b/src/World.cpp
@@ -754,6 +754,9 @@ void cWorld::Tick(float a_Dt, int a_LastTickDurationMSec)
m_EntitiesToAdd.clear();
}
+ // Add players waiting in the queue to be added:
+ AddQueuedPlayers();
+
m_ChunkMap->Tick(a_Dt);
TickClients(a_Dt);
@@ -1642,7 +1645,7 @@ void cWorld::SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double
a_BlockX, a_BlockY, a_BlockZ,
*itr, IsPlayerCreated, SpeedX, SpeedY, SpeedZ
);
- Pickup->Initialize(this);
+ Pickup->Initialize(*this);
}
}
@@ -1663,7 +1666,7 @@ void cWorld::SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double
a_BlockX, a_BlockY, a_BlockZ,
*itr, IsPlayerCreated, (float)a_SpeedX, (float)a_SpeedY, (float)a_SpeedZ
);
- Pickup->Initialize(this);
+ Pickup->Initialize(*this);
}
}
@@ -1674,7 +1677,7 @@ void cWorld::SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double
int cWorld::SpawnFallingBlock(int a_X, int a_Y, int a_Z, BLOCKTYPE BlockType, NIBBLETYPE BlockMeta)
{
cFallingBlock * FallingBlock = new cFallingBlock(Vector3i(a_X, a_Y, a_Z), BlockType, BlockMeta);
- FallingBlock->Initialize(this);
+ FallingBlock->Initialize(*this);
return FallingBlock->GetUniqueID();
}
@@ -1690,7 +1693,7 @@ int cWorld::SpawnExperienceOrb(double a_X, double a_Y, double a_Z, int a_Reward)
}
cExpOrb * ExpOrb = new cExpOrb(a_X, a_Y, a_Z, a_Reward);
- ExpOrb->Initialize(this);
+ ExpOrb->Initialize(*this);
return ExpOrb->GetUniqueID();
}
@@ -1713,7 +1716,7 @@ int cWorld::SpawnMinecart(double a_X, double a_Y, double a_Z, int a_MinecartType
return -1;
}
} // switch (a_MinecartType)
- Minecart->Initialize(this);
+ Minecart->Initialize(*this);
return Minecart->GetUniqueID();
}
@@ -1724,7 +1727,7 @@ int cWorld::SpawnMinecart(double a_X, double a_Y, double a_Z, int a_MinecartType
void cWorld::SpawnPrimedTNT(double a_X, double a_Y, double a_Z, int a_FuseTicks, double a_InitialVelocityCoeff)
{
cTNTEntity * TNT = new cTNTEntity(a_X, a_Y, a_Z, a_FuseTicks);
- TNT->Initialize(this);
+ TNT->Initialize(*this);
TNT->SetSpeed(
a_InitialVelocityCoeff * (GetTickRandomNumber(2) - 1), /** -1, 0, 1 */
a_InitialVelocityCoeff * 2,
@@ -2240,7 +2243,7 @@ void cWorld::SetChunkData(
// Initialize the entities (outside the m_ChunkMap's CS, to fix FS #347):
for (cEntityList::iterator itr = a_Entities.begin(), end = a_Entities.end(); itr != end; ++itr)
{
- (*itr)->Initialize(this);
+ (*itr)->Initialize(*this);
}
// If a client is requesting this chunk, send it to them:
@@ -2333,23 +2336,8 @@ void cWorld::CollectPickupsByPlayer(cPlayer * a_Player)
void cWorld::AddPlayer(cPlayer * a_Player)
{
- {
- cCSLock Lock(m_CSPlayers);
-
- ASSERT(std::find(m_Players.begin(), m_Players.end(), a_Player) == m_Players.end()); // Is it already in the list? HOW?
-
- m_Players.remove(a_Player); // Make sure the player is registered only once
- m_Players.push_back(a_Player);
- }
-
- // Add the player's client to the list of clients to be ticked:
- if (a_Player->GetClientHandle() != NULL)
- {
- cCSLock Lock(m_CSClients);
- m_ClientsToAdd.push_back(a_Player->GetClientHandle());
- }
-
- // The player has already been added to the chunkmap as the entity, do NOT add again!
+ cCSLock Lock(m_CSPlayersToAdd);
+ m_PlayersToAdd.push_back(a_Player);
}
@@ -2358,17 +2346,26 @@ void cWorld::AddPlayer(cPlayer * a_Player)
void cWorld::RemovePlayer(cPlayer * a_Player)
{
+
m_ChunkMap->RemoveEntity(a_Player);
{
+ cCSLock Lock(m_CSPlayersToAdd);
+ m_PlayersToAdd.remove(a_Player);
+ }
+ {
cCSLock Lock(m_CSPlayers);
+ LOGD("Removing player \"%s\" from world \"%s\".", a_Player->GetName().c_str(), m_WorldName.c_str());
m_Players.remove(a_Player);
}
// Remove the player's client from the list of clients to be ticked:
- if (a_Player->GetClientHandle() != NULL)
+ cClientHandle * Client = a_Player->GetClientHandle();
+ if (Client != NULL)
{
+ Client->RemoveFromWorld();
+ m_ChunkMap->RemoveClientFromChunks(Client);
cCSLock Lock(m_CSClients);
- m_ClientsToRemove.push_back(a_Player->GetClientHandle());
+ m_ClientsToRemove.push_back(Client);
}
}
@@ -2977,7 +2974,7 @@ int cWorld::SpawnMobFinalize(cMonster * a_Monster)
delete a_Monster;
return -1;
}
- if (!a_Monster->Initialize(this))
+ if (!a_Monster->Initialize(*this))
{
delete a_Monster;
return -1;
@@ -2999,7 +2996,7 @@ int cWorld::CreateProjectile(double a_PosX, double a_PosY, double a_PosZ, cProje
{
return -1;
}
- if (!Projectile->Initialize(this))
+ if (!Projectile->Initialize(*this))
{
delete Projectile;
return -1;
@@ -3129,6 +3126,63 @@ cFluidSimulator * cWorld::InitializeFluidSimulator(cIniFile & a_IniFile, const c
+void cWorld::AddQueuedPlayers(void)
+{
+ ASSERT(m_TickThread.IsCurrentThread());
+
+ // Grab the list of players to add, it has to be locked to access it:
+ cPlayerList PlayersToAdd;
+ {
+ cCSLock Lock(m_CSPlayersToAdd);
+ std::swap(PlayersToAdd, m_PlayersToAdd);
+ }
+
+ // Add all the players in the grabbed list:
+ {
+ cCSLock Lock(m_CSPlayers);
+ for (cPlayerList::iterator itr = PlayersToAdd.begin(), end = PlayersToAdd.end(); itr != end; ++itr)
+ {
+ ASSERT(std::find(m_Players.begin(), m_Players.end(), *itr) == m_Players.end()); // Is it already in the list? HOW?
+
+ m_Players.push_back(*itr);
+ (*itr)->SetWorld(this);
+
+ // Add to chunkmap, if not already there (Spawn vs MoveToWorld):
+ if (!m_ChunkMap->HasEntity((*itr)->GetUniqueID()))
+ {
+ m_ChunkMap->AddEntity(*itr);
+ }
+ } // for itr - PlayersToAdd[]
+ } // Lock(m_CSPlayers)
+
+ // Add all the players' clienthandles:
+ {
+ cCSLock Lock(m_CSClients);
+ for (cPlayerList::iterator itr = PlayersToAdd.begin(), end = PlayersToAdd.end(); itr != end; ++itr)
+ {
+ cClientHandle * Client = (*itr)->GetClientHandle();
+ if (Client != NULL)
+ {
+ m_Clients.push_back(Client);
+ }
+ } // for itr - PlayersToAdd[]
+ } // Lock(m_CSClients)
+
+ // Stream chunks to all eligible clients:
+ for (cPlayerList::iterator itr = PlayersToAdd.begin(), end = PlayersToAdd.end(); itr != end; ++itr)
+ {
+ cClientHandle * Client = (*itr)->GetClientHandle();
+ if (Client != NULL)
+ {
+ Client->StreamChunks();
+ }
+ } // for itr - PlayersToAdd[]
+}
+
+
+
+
+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cWorld::cTaskSaveAllChunks:
@@ -3269,4 +3323,3 @@ void cWorld::cChunkGeneratorCallbacks::CallHookChunkGenerated (cChunkDesc & a_Ch
-