1
0

Merge branch 'master' into portals

Conflicts:
	src/ClientHandle.cpp
	src/Entities/Player.cpp
	src/Entities/Player.h
	src/Protocol/Protocol125.cpp
	src/Protocol/Protocol17x.cpp
This commit is contained in:
Tiger Wang
2014-06-10 20:51:22 +01:00
72 changed files with 2885 additions and 310 deletions

View File

@@ -813,6 +813,20 @@ void cWorld::Tick(float a_Dt, int a_LastTickDurationMSec)
m_LastTimeUpdate = m_WorldAge;
}
// Add entities waiting in the queue to be added:
{
cCSLock Lock(m_CSEntitiesToAdd);
for (cEntityList::iterator itr = m_EntitiesToAdd.begin(), end = m_EntitiesToAdd.end(); itr != end; ++itr)
{
(*itr)->SetWorld(this);
m_ChunkMap->AddEntity(*itr);
}
m_EntitiesToAdd.clear();
}
// Add players waiting in the queue to be added:
AddQueuedPlayers();
m_ChunkMap->Tick(a_Dt);
TickClients(a_Dt);
@@ -1701,7 +1715,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);
}
}
@@ -1722,7 +1736,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);
}
}
@@ -1733,7 +1747,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();
}
@@ -1749,7 +1763,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();
}
@@ -1772,7 +1786,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();
}
@@ -1783,7 +1797,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,
@@ -2299,7 +2313,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:
@@ -2392,23 +2406,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);
}
@@ -2417,17 +2416,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);
}
}
@@ -2878,9 +2886,11 @@ void cWorld::ScheduleTask(int a_DelayTicks, cTask * a_Task)
void cWorld::AddEntity(cEntity * a_Entity)
{
m_ChunkMap->AddEntity(a_Entity);
cCSLock Lock(m_CSEntitiesToAdd);
m_EntitiesToAdd.push_back(a_Entity);
}
@@ -2889,6 +2899,19 @@ void cWorld::AddEntity(cEntity * a_Entity)
bool cWorld::HasEntity(int a_UniqueID)
{
// Check if the entity is in the queue to be added to the world:
{
cCSLock Lock(m_CSEntitiesToAdd);
for (cEntityList::const_iterator itr = m_EntitiesToAdd.begin(), end = m_EntitiesToAdd.end(); itr != end; ++itr)
{
if ((*itr)->GetUniqueID() == a_UniqueID)
{
return true;
}
} // for itr - m_EntitiesToAdd[]
}
// Check if the entity is in the chunkmap:
return m_ChunkMap->HasEntity(a_UniqueID);
}
@@ -3021,7 +3044,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;
@@ -3043,7 +3066,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;
@@ -3173,6 +3196,60 @@ 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):
m_ChunkMap->AddEntityIfNotPresent(*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:
@@ -3313,4 +3390,3 @@ void cWorld::cChunkGeneratorCallbacks::CallHookChunkGenerated (cChunkDesc & a_Ch