Rewritten entities so that they are owned by individual chunks and ticked within their chunk's Tick()
git-svn-id: http://mc-server.googlecode.com/svn/trunk@1385 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
parent
58fb05980d
commit
a49c004278
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
** Lua binding: AllToLua
|
** Lua binding: AllToLua
|
||||||
** Generated automatically by tolua++-1.0.92 on 04/11/13 11:57:58.
|
** Generated automatically by tolua++-1.0.92 on 04/13/13 22:59:55.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __cplusplus
|
#ifndef __cplusplus
|
||||||
@ -4717,38 +4717,6 @@ static int tolua_AllToLua_cEntity_GetChunkX00(lua_State* tolua_S)
|
|||||||
}
|
}
|
||||||
#endif //#ifndef TOLUA_DISABLE
|
#endif //#ifndef TOLUA_DISABLE
|
||||||
|
|
||||||
/* method: GetChunkY of class cEntity */
|
|
||||||
#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetChunkY00
|
|
||||||
static int tolua_AllToLua_cEntity_GetChunkY00(lua_State* tolua_S)
|
|
||||||
{
|
|
||||||
#ifndef TOLUA_RELEASE
|
|
||||||
tolua_Error tolua_err;
|
|
||||||
if (
|
|
||||||
!tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) ||
|
|
||||||
!tolua_isnoobj(tolua_S,2,&tolua_err)
|
|
||||||
)
|
|
||||||
goto tolua_lerror;
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0);
|
|
||||||
#ifndef TOLUA_RELEASE
|
|
||||||
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetChunkY'", NULL);
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
int tolua_ret = (int) self->GetChunkY();
|
|
||||||
tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
#ifndef TOLUA_RELEASE
|
|
||||||
tolua_lerror:
|
|
||||||
tolua_error(tolua_S,"#ferror in function 'GetChunkY'.",&tolua_err);
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif //#ifndef TOLUA_DISABLE
|
|
||||||
|
|
||||||
/* method: GetChunkZ of class cEntity */
|
/* method: GetChunkZ of class cEntity */
|
||||||
#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetChunkZ00
|
#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetChunkZ00
|
||||||
static int tolua_AllToLua_cEntity_GetChunkZ00(lua_State* tolua_S)
|
static int tolua_AllToLua_cEntity_GetChunkZ00(lua_State* tolua_S)
|
||||||
@ -24470,7 +24438,6 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
|
|||||||
tolua_function(tolua_S,"GetSpeedY",tolua_AllToLua_cEntity_GetSpeedY00);
|
tolua_function(tolua_S,"GetSpeedY",tolua_AllToLua_cEntity_GetSpeedY00);
|
||||||
tolua_function(tolua_S,"GetSpeedZ",tolua_AllToLua_cEntity_GetSpeedZ00);
|
tolua_function(tolua_S,"GetSpeedZ",tolua_AllToLua_cEntity_GetSpeedZ00);
|
||||||
tolua_function(tolua_S,"GetChunkX",tolua_AllToLua_cEntity_GetChunkX00);
|
tolua_function(tolua_S,"GetChunkX",tolua_AllToLua_cEntity_GetChunkX00);
|
||||||
tolua_function(tolua_S,"GetChunkY",tolua_AllToLua_cEntity_GetChunkY00);
|
|
||||||
tolua_function(tolua_S,"GetChunkZ",tolua_AllToLua_cEntity_GetChunkZ00);
|
tolua_function(tolua_S,"GetChunkZ",tolua_AllToLua_cEntity_GetChunkZ00);
|
||||||
tolua_function(tolua_S,"SetHeadYaw",tolua_AllToLua_cEntity_SetHeadYaw00);
|
tolua_function(tolua_S,"SetHeadYaw",tolua_AllToLua_cEntity_SetHeadYaw00);
|
||||||
tolua_function(tolua_S,"SetPosX",tolua_AllToLua_cEntity_SetPosX00);
|
tolua_function(tolua_S,"SetPosX",tolua_AllToLua_cEntity_SetPosX00);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
** Lua binding: AllToLua
|
** Lua binding: AllToLua
|
||||||
** Generated automatically by tolua++-1.0.92 on 04/11/13 11:57:59.
|
** Generated automatically by tolua++-1.0.92 on 04/13/13 22:59:55.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Exported function */
|
/* Exported function */
|
||||||
|
@ -144,9 +144,9 @@ void cChestEntity::UsedBy(cPlayer * a_Player)
|
|||||||
// Instead of marking the chunk as dirty upon chest contents change, we mark it dirty now
|
// Instead of marking the chunk as dirty upon chest contents change, we mark it dirty now
|
||||||
// We cannot properly detect contents change, but such a change doesn't happen without a player opening the chest first.
|
// We cannot properly detect contents change, but such a change doesn't happen without a player opening the chest first.
|
||||||
// The few false positives aren't much to worry about
|
// The few false positives aren't much to worry about
|
||||||
int ChunkX, ChunkY = 0, ChunkZ;
|
int ChunkX, ChunkZ;
|
||||||
cChunkDef::BlockToChunk(m_PosX, m_PosY, m_PosZ, ChunkX, ChunkZ);
|
cChunkDef::BlockToChunk(m_PosX, m_PosY, m_PosZ, ChunkX, ChunkZ);
|
||||||
m_World->MarkChunkDirty(ChunkX, ChunkY, ChunkZ);
|
m_World->MarkChunkDirty(ChunkX, ChunkZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
142
source/Chunk.cpp
142
source/Chunk.cpp
@ -118,19 +118,15 @@ cChunk::~cChunk()
|
|||||||
|
|
||||||
// Remove and destroy all entities that are not players:
|
// Remove and destroy all entities that are not players:
|
||||||
cEntityList Entities;
|
cEntityList Entities;
|
||||||
for (cEntityList::const_iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr)
|
std::swap(Entities, m_Entities); // Need another list because cEntity destructors check if they've been removed from chunk
|
||||||
|
for (cEntityList::const_iterator itr = Entities.begin(); itr != Entities.end(); ++itr)
|
||||||
{
|
{
|
||||||
if (!(*itr)->IsPlayer())
|
if (!(*itr)->IsPlayer())
|
||||||
{
|
{
|
||||||
Entities.push_back(*itr);
|
(*itr)->Destroy();
|
||||||
|
delete *itr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (cEntityList::iterator itr = Entities.begin(); itr != Entities.end(); ++itr)
|
|
||||||
{
|
|
||||||
(*itr)->RemoveFromChunk();
|
|
||||||
(*itr)->Destroy();
|
|
||||||
}
|
|
||||||
m_Entities.clear();
|
|
||||||
|
|
||||||
if (m_NeighborXM != NULL)
|
if (m_NeighborXM != NULL)
|
||||||
{
|
{
|
||||||
@ -267,7 +263,6 @@ void cChunk::SetAllData(
|
|||||||
const NIBBLETYPE * a_BlockSkyLight,
|
const NIBBLETYPE * a_BlockSkyLight,
|
||||||
const HeightMap * a_HeightMap,
|
const HeightMap * a_HeightMap,
|
||||||
const BiomeMap & a_BiomeMap,
|
const BiomeMap & a_BiomeMap,
|
||||||
cEntityList & a_Entities,
|
|
||||||
cBlockEntityList & a_BlockEntities
|
cBlockEntityList & a_BlockEntities
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@ -296,9 +291,6 @@ void cChunk::SetAllData(
|
|||||||
CalculateHeightmap();
|
CalculateHeightmap();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append entities to current entity list:
|
|
||||||
m_Entities.insert(m_Entities.end(), a_Entities.begin(), a_Entities.end());
|
|
||||||
|
|
||||||
// Clear the block entities present - either the loader / saver has better, or we'll create empty ones:
|
// Clear the block entities present - either the loader / saver has better, or we'll create empty ones:
|
||||||
for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr)
|
for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr)
|
||||||
{
|
{
|
||||||
@ -438,7 +430,7 @@ void cChunk::Stay(bool a_Stay)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cChunk::Tick(float a_Dt, MTRand & a_TickRandom)
|
void cChunk::Tick(float a_Dt)
|
||||||
{
|
{
|
||||||
BroadcastPendingBlockChanges();
|
BroadcastPendingBlockChanges();
|
||||||
|
|
||||||
@ -454,7 +446,7 @@ void cChunk::Tick(float a_Dt, MTRand & a_TickRandom)
|
|||||||
// Tick simulators:
|
// Tick simulators:
|
||||||
m_World->GetSimulatorManager()->SimulateChunk(a_Dt, m_PosX, m_PosZ, this);
|
m_World->GetSimulatorManager()->SimulateChunk(a_Dt, m_PosX, m_PosZ, this);
|
||||||
|
|
||||||
TickBlocks(a_TickRandom);
|
TickBlocks();
|
||||||
|
|
||||||
// Tick all block entities in this chunk:
|
// Tick all block entities in this chunk:
|
||||||
for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr)
|
for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr)
|
||||||
@ -462,6 +454,43 @@ void cChunk::Tick(float a_Dt, MTRand & a_TickRandom)
|
|||||||
m_IsDirty = (*itr)->Tick(a_Dt) | m_IsDirty;
|
m_IsDirty = (*itr)->Tick(a_Dt) | m_IsDirty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tick all entities in this chunk:
|
||||||
|
for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr)
|
||||||
|
{
|
||||||
|
(*itr)->Tick(a_Dt, *this);
|
||||||
|
} // for itr - m_Entitites[]
|
||||||
|
|
||||||
|
// Remove all entities that were scheduled for removal:
|
||||||
|
for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end();)
|
||||||
|
{
|
||||||
|
if ((*itr)->IsDestroyed())
|
||||||
|
{
|
||||||
|
LOGD("Destroying entity #%i (%s)", (*itr)->GetUniqueID(), (*itr)->GetClass());
|
||||||
|
cEntity * ToDelete = *itr;
|
||||||
|
itr = m_Entities.erase(itr);
|
||||||
|
delete ToDelete;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
itr++;
|
||||||
|
} // for itr - m_Entitites[]
|
||||||
|
|
||||||
|
// If any entity moved out of the chunk, move it to the neighbor:
|
||||||
|
for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end();)
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
((*itr)->GetChunkX() != m_PosX) ||
|
||||||
|
((*itr)->GetChunkZ() != m_PosZ)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
MoveEntityToNewChunk(*itr);
|
||||||
|
itr = m_Entities.erase(itr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
++itr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ApplyWeatherToTop();
|
ApplyWeatherToTop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -469,6 +498,46 @@ void cChunk::Tick(float a_Dt, MTRand & a_TickRandom)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cChunk::MoveEntityToNewChunk(cEntity * a_Entity)
|
||||||
|
{
|
||||||
|
cChunk * Neighbor = GetNeighborChunk((int)a_Entity->GetPosX(), (int)a_Entity->GetPosZ());
|
||||||
|
if (Neighbor == NULL)
|
||||||
|
{
|
||||||
|
// TODO: What to do with this?
|
||||||
|
LOGWARNING("%s: Failed to move entity, destination chunk unreachable. Entity lost", __FUNCTION__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Neighbor->AddEntity(a_Entity);
|
||||||
|
|
||||||
|
class cMover :
|
||||||
|
public cClientDiffCallback
|
||||||
|
{
|
||||||
|
virtual void Removed(cClientHandle * a_Client) override
|
||||||
|
{
|
||||||
|
a_Client->SendDestroyEntity(*m_Entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void Added(cClientHandle * a_Client) override
|
||||||
|
{
|
||||||
|
m_Entity->SpawnOn(*a_Client);
|
||||||
|
}
|
||||||
|
|
||||||
|
cEntity * m_Entity;
|
||||||
|
|
||||||
|
public:
|
||||||
|
cMover(cEntity * a_Entity) :
|
||||||
|
m_Entity(a_Entity)
|
||||||
|
{}
|
||||||
|
} Mover(a_Entity);
|
||||||
|
|
||||||
|
m_ChunkMap->CompareChunkClients(this, Neighbor, Mover);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cChunk::BroadcastPendingBlockChanges(void)
|
void cChunk::BroadcastPendingBlockChanges(void)
|
||||||
{
|
{
|
||||||
sSetBlockVector Changes;
|
sSetBlockVector Changes;
|
||||||
@ -516,13 +585,13 @@ void cChunk::CheckBlocks(void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cChunk::TickBlocks(MTRand & a_TickRandom)
|
void cChunk::TickBlocks(void)
|
||||||
{
|
{
|
||||||
// Tick dem blocks
|
// Tick dem blocks
|
||||||
// _X: We must limit the random number or else we get a nasty int overflow bug ( http://forum.mc-server.org/showthread.php?tid=457 )
|
// _X: We must limit the random number or else we get a nasty int overflow bug ( http://forum.mc-server.org/showthread.php?tid=457 )
|
||||||
int RandomX = a_TickRandom.randInt(0x00ffffff);
|
int RandomX = m_World->GetTickRandomNumber(0x00ffffff);
|
||||||
int RandomY = a_TickRandom.randInt(0x00ffffff);
|
int RandomY = m_World->GetTickRandomNumber(0x00ffffff);
|
||||||
int RandomZ = a_TickRandom.randInt(0x00ffffff);
|
int RandomZ = m_World->GetTickRandomNumber(0x00ffffff);
|
||||||
int TickX = m_BlockTickX;
|
int TickX = m_BlockTickX;
|
||||||
int TickY = m_BlockTickY;
|
int TickY = m_BlockTickY;
|
||||||
int TickZ = m_BlockTickZ;
|
int TickZ = m_BlockTickZ;
|
||||||
@ -1609,6 +1678,9 @@ void cChunk::AddEntity(cEntity * a_Entity)
|
|||||||
{
|
{
|
||||||
MarkDirty();
|
MarkDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ASSERT(std::find(m_Entities.begin(), m_Entities.end(), a_Entity) == m_Entities.end()); // Not there already
|
||||||
|
|
||||||
m_Entities.push_back(a_Entity);
|
m_Entities.push_back(a_Entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1636,6 +1708,22 @@ void cChunk::RemoveEntity(cEntity * a_Entity)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cChunk::HasEntity(int a_EntityID)
|
||||||
|
{
|
||||||
|
for (cEntityList::const_iterator itr = m_Entities.begin(), end = m_Entities.end(); itr != end; ++itr)
|
||||||
|
{
|
||||||
|
if ((*itr)->GetUniqueID() == a_EntityID)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} // for itr - m_Entities[]
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunk::ForEachEntity(cEntityCallback & a_Callback)
|
bool cChunk::ForEachEntity(cEntityCallback & a_Callback)
|
||||||
{
|
{
|
||||||
// The entity list is locked by the parent chunkmap's CS
|
// The entity list is locked by the parent chunkmap's CS
|
||||||
@ -1654,6 +1742,24 @@ bool cChunk::ForEachEntity(cEntityCallback & a_Callback)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cChunk::DoWithEntityByID(int a_EntityID, cEntityCallback & a_Callback, bool & a_CallbackResult)
|
||||||
|
{
|
||||||
|
// The entity list is locked by the parent chunkmap's CS
|
||||||
|
for (cEntityList::iterator itr = m_Entities.begin(), end = m_Entities.end(); itr != end; ++itr)
|
||||||
|
{
|
||||||
|
if ((*itr)->GetUniqueID() == a_EntityID)
|
||||||
|
{
|
||||||
|
a_CallbackResult = a_Callback.Item(*itr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} // for itr - m_Entitites[]
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunk::ForEachChest(cChestCallback & a_Callback)
|
bool cChunk::ForEachChest(cChestCallback & a_Callback)
|
||||||
{
|
{
|
||||||
// The blockentity list is locked by the parent chunkmap's CS
|
// The blockentity list is locked by the parent chunkmap's CS
|
||||||
|
@ -104,7 +104,6 @@ public:
|
|||||||
const NIBBLETYPE * a_BlockSkyLight,
|
const NIBBLETYPE * a_BlockSkyLight,
|
||||||
const cChunkDef::HeightMap * a_HeightMap,
|
const cChunkDef::HeightMap * a_HeightMap,
|
||||||
const cChunkDef::BiomeMap & a_BiomeMap,
|
const cChunkDef::BiomeMap & a_BiomeMap,
|
||||||
cEntityList & a_Entities,
|
|
||||||
cBlockEntityList & a_BlockEntities
|
cBlockEntityList & a_BlockEntities
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -125,7 +124,7 @@ public:
|
|||||||
/// Sets or resets the internal flag that prevents chunk from being unloaded
|
/// Sets or resets the internal flag that prevents chunk from being unloaded
|
||||||
void Stay(bool a_Stay = true);
|
void Stay(bool a_Stay = true);
|
||||||
|
|
||||||
void Tick(float a_Dt, MTRand & a_TickRandom);
|
void Tick(float a_Dt);
|
||||||
|
|
||||||
int GetPosX(void) const { return m_PosX; }
|
int GetPosX(void) const { return m_PosX; }
|
||||||
int GetPosY(void) const { return m_PosY; }
|
int GetPosY(void) const { return m_PosY; }
|
||||||
@ -176,12 +175,16 @@ public:
|
|||||||
bool HasClient (cClientHandle* a_Client );
|
bool HasClient (cClientHandle* a_Client );
|
||||||
bool HasAnyClients(void); // Returns true if theres any client in the chunk; false otherwise
|
bool HasAnyClients(void); // Returns true if theres any client in the chunk; false otherwise
|
||||||
|
|
||||||
void AddEntity( cEntity * a_Entity);
|
void AddEntity(cEntity * a_Entity);
|
||||||
void RemoveEntity( cEntity * a_Entity);
|
void RemoveEntity(cEntity * a_Entity);
|
||||||
|
bool HasEntity(int a_EntityID);
|
||||||
|
|
||||||
/// Calls the callback for each entity; returns true if all entities processed, false if the callback aborted by returning true
|
/// Calls the callback for each entity; returns true if all entities processed, false if the callback aborted by returning true
|
||||||
bool ForEachEntity(cEntityCallback & a_Callback); // Lua-accessible
|
bool ForEachEntity(cEntityCallback & a_Callback); // Lua-accessible
|
||||||
|
|
||||||
|
/// Calls the callback if the entity with the specified ID is found, with the entity object as the callback param. Returns true if entity found.
|
||||||
|
bool DoWithEntityByID(int a_EntityID, cEntityCallback & a_Callback, bool & a_CallbackResult); // Lua-accessible
|
||||||
|
|
||||||
/// Calls the callback for each chest; returns true if all chests processed, false if the callback aborted by returning true
|
/// Calls the callback for each chest; returns true if all chests processed, false if the callback aborted by returning true
|
||||||
bool ForEachChest(cChestCallback & a_Callback); // Lua-accessible
|
bool ForEachChest(cChestCallback & a_Callback); // Lua-accessible
|
||||||
|
|
||||||
@ -352,7 +355,8 @@ private:
|
|||||||
/// Checks the block scheduled for checking in m_ToTickBlocks[]
|
/// Checks the block scheduled for checking in m_ToTickBlocks[]
|
||||||
void CheckBlocks(void);
|
void CheckBlocks(void);
|
||||||
|
|
||||||
void TickBlocks (MTRand & a_TickRandom);
|
/// Ticks several random blocks in the chunk
|
||||||
|
void TickBlocks(void);
|
||||||
|
|
||||||
/// Adds snow to the top of snowy biomes and hydrates farmland / fills cauldrons in rainy biomes
|
/// Adds snow to the top of snowy biomes and hydrates farmland / fills cauldrons in rainy biomes
|
||||||
void ApplyWeatherToTop(void);
|
void ApplyWeatherToTop(void);
|
||||||
@ -368,6 +372,9 @@ private:
|
|||||||
|
|
||||||
/// Checks if a leaves block at the specified coords has a log up to 4 blocks away connected by other leaves blocks (false if no log)
|
/// Checks if a leaves block at the specified coords has a log up to 4 blocks away connected by other leaves blocks (false if no log)
|
||||||
bool HasNearLog(cBlockArea & a_Area, int a_BlockX, int a_BlockY, int a_BlockZ);
|
bool HasNearLog(cBlockArea & a_Area, int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||||
|
|
||||||
|
/// Called by Tick() when an entity moves out of this chunk into a neighbor; moves the entity and sends spawn / despawn packet to clients
|
||||||
|
void MoveEntityToNewChunk(cEntity * a_Entity);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef cChunk * cChunkPtr;
|
typedef cChunk * cChunkPtr;
|
||||||
|
@ -277,7 +277,7 @@ cChunk * cChunkMap::FindChunk(int a_ChunkX, int a_ChunkZ)
|
|||||||
void cChunkMap::BroadcastAttachEntity(const cEntity & a_Entity, const cEntity * a_Vehicle)
|
void cChunkMap::BroadcastAttachEntity(const cEntity & a_Entity, const cEntity * a_Vehicle)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSLayers);
|
cCSLock Lock(m_CSLayers);
|
||||||
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkY(), a_Entity.GetChunkZ());
|
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), ZERO_CHUNK_Y, a_Entity.GetChunkZ());
|
||||||
if (Chunk == NULL)
|
if (Chunk == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -292,7 +292,7 @@ void cChunkMap::BroadcastAttachEntity(const cEntity & a_Entity, const cEntity *
|
|||||||
void cChunkMap::BroadcastPlayerAnimation(const cPlayer & a_Player, char a_Animation, const cClientHandle * a_Exclude)
|
void cChunkMap::BroadcastPlayerAnimation(const cPlayer & a_Player, char a_Animation, const cClientHandle * a_Exclude)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSLayers);
|
cCSLock Lock(m_CSLayers);
|
||||||
cChunkPtr Chunk = GetChunkNoGen(a_Player.GetChunkX(), a_Player.GetChunkY(), a_Player.GetChunkZ());
|
cChunkPtr Chunk = GetChunkNoGen(a_Player.GetChunkX(), ZERO_CHUNK_Y, a_Player.GetChunkZ());
|
||||||
if (Chunk == NULL)
|
if (Chunk == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -308,7 +308,7 @@ void cChunkMap::BroadcastPlayerAnimation(const cPlayer & a_Player, char a_Animat
|
|||||||
void cChunkMap::BroadcastEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude)
|
void cChunkMap::BroadcastEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSLayers);
|
cCSLock Lock(m_CSLayers);
|
||||||
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkY(), a_Entity.GetChunkZ());
|
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), ZERO_CHUNK_Y, a_Entity.GetChunkZ());
|
||||||
if (Chunk == NULL)
|
if (Chunk == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -325,7 +325,7 @@ void cChunkMap::BroadcastEntityEquipment(const cEntity & a_Entity, short a_SlotN
|
|||||||
void cChunkMap::BroadcastEntVelocity(const cEntity & a_Entity, const cClientHandle * a_Exclude)
|
void cChunkMap::BroadcastEntVelocity(const cEntity & a_Entity, const cClientHandle * a_Exclude)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSLayers);
|
cCSLock Lock(m_CSLayers);
|
||||||
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkY(), a_Entity.GetChunkZ());
|
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), ZERO_CHUNK_Y, a_Entity.GetChunkZ());
|
||||||
if (Chunk == NULL)
|
if (Chunk == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -341,7 +341,7 @@ void cChunkMap::BroadcastEntVelocity(const cEntity & a_Entity, const cClientHand
|
|||||||
void cChunkMap::BroadcastEntRelMoveLook(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude)
|
void cChunkMap::BroadcastEntRelMoveLook(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSLayers);
|
cCSLock Lock(m_CSLayers);
|
||||||
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkY(), a_Entity.GetChunkZ());
|
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), ZERO_CHUNK_Y, a_Entity.GetChunkZ());
|
||||||
if (Chunk == NULL)
|
if (Chunk == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -358,7 +358,7 @@ void cChunkMap::BroadcastEntRelMoveLook(const cEntity & a_Entity, char a_RelX, c
|
|||||||
void cChunkMap::BroadcastEntRelMove(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude)
|
void cChunkMap::BroadcastEntRelMove(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSLayers);
|
cCSLock Lock(m_CSLayers);
|
||||||
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkY(), a_Entity.GetChunkZ());
|
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), ZERO_CHUNK_Y, a_Entity.GetChunkZ());
|
||||||
if (Chunk == NULL)
|
if (Chunk == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -375,7 +375,7 @@ void cChunkMap::BroadcastEntRelMove(const cEntity & a_Entity, char a_RelX, char
|
|||||||
void cChunkMap::BroadcastEntLook(const cEntity & a_Entity, const cClientHandle * a_Exclude)
|
void cChunkMap::BroadcastEntLook(const cEntity & a_Entity, const cClientHandle * a_Exclude)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSLayers);
|
cCSLock Lock(m_CSLayers);
|
||||||
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkY(), a_Entity.GetChunkZ());
|
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), ZERO_CHUNK_Y, a_Entity.GetChunkZ());
|
||||||
if (Chunk == NULL)
|
if (Chunk == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -392,7 +392,7 @@ void cChunkMap::BroadcastEntLook(const cEntity & a_Entity, const cClientHandle *
|
|||||||
void cChunkMap::BroadcastEntHeadLook(const cEntity & a_Entity, const cClientHandle * a_Exclude)
|
void cChunkMap::BroadcastEntHeadLook(const cEntity & a_Entity, const cClientHandle * a_Exclude)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSLayers);
|
cCSLock Lock(m_CSLayers);
|
||||||
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkY(), a_Entity.GetChunkZ());
|
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), ZERO_CHUNK_Y, a_Entity.GetChunkZ());
|
||||||
if (Chunk == NULL)
|
if (Chunk == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -431,7 +431,7 @@ void cChunkMap::BroadcastBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, c
|
|||||||
void cChunkMap::BroadcastDestroyEntity(const cEntity & a_Entity, const cClientHandle * a_Exclude)
|
void cChunkMap::BroadcastDestroyEntity(const cEntity & a_Entity, const cClientHandle * a_Exclude)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSLayers);
|
cCSLock Lock(m_CSLayers);
|
||||||
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkY(), a_Entity.GetChunkZ());
|
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), ZERO_CHUNK_Y, a_Entity.GetChunkZ());
|
||||||
if (Chunk == NULL)
|
if (Chunk == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -448,7 +448,7 @@ void cChunkMap::BroadcastDestroyEntity(const cEntity & a_Entity, const cClientHa
|
|||||||
void cChunkMap::BroadcastEntityStatus(const cEntity & a_Entity, char a_Status, const cClientHandle * a_Exclude)
|
void cChunkMap::BroadcastEntityStatus(const cEntity & a_Entity, char a_Status, const cClientHandle * a_Exclude)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSLayers);
|
cCSLock Lock(m_CSLayers);
|
||||||
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkY(), a_Entity.GetChunkZ());
|
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), ZERO_CHUNK_Y, a_Entity.GetChunkZ());
|
||||||
if (Chunk == NULL)
|
if (Chunk == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -465,7 +465,7 @@ void cChunkMap::BroadcastEntityStatus(const cEntity & a_Entity, char a_Status, c
|
|||||||
void cChunkMap::BroadcastMetadata(const cPawn & a_Pawn, const cClientHandle * a_Exclude)
|
void cChunkMap::BroadcastMetadata(const cPawn & a_Pawn, const cClientHandle * a_Exclude)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSLayers);
|
cCSLock Lock(m_CSLayers);
|
||||||
cChunkPtr Chunk = GetChunkNoGen(a_Pawn.GetChunkX(), a_Pawn.GetChunkY(), a_Pawn.GetChunkZ());
|
cChunkPtr Chunk = GetChunkNoGen(a_Pawn.GetChunkX(), ZERO_CHUNK_Y, a_Pawn.GetChunkZ());
|
||||||
if (Chunk == NULL)
|
if (Chunk == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -481,7 +481,7 @@ void cChunkMap::BroadcastMetadata(const cPawn & a_Pawn, const cClientHandle * a_
|
|||||||
void cChunkMap::BroadcastSpawn(cEntity & a_Entity, const cClientHandle * a_Exclude)
|
void cChunkMap::BroadcastSpawn(cEntity & a_Entity, const cClientHandle * a_Exclude)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSLayers);
|
cCSLock Lock(m_CSLayers);
|
||||||
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkY(), a_Entity.GetChunkZ());
|
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), ZERO_CHUNK_Y, a_Entity.GetChunkZ());
|
||||||
if (Chunk == NULL)
|
if (Chunk == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -497,7 +497,7 @@ void cChunkMap::BroadcastSpawn(cEntity & a_Entity, const cClientHandle * a_Exclu
|
|||||||
void cChunkMap::BroadcastCollectPickup(const cPickup & a_Pickup, const cPlayer & a_Player, const cClientHandle * a_Exclude)
|
void cChunkMap::BroadcastCollectPickup(const cPickup & a_Pickup, const cPlayer & a_Player, const cClientHandle * a_Exclude)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSLayers);
|
cCSLock Lock(m_CSLayers);
|
||||||
cChunkPtr Chunk = GetChunkNoGen(a_Pickup.GetChunkX(), a_Pickup.GetChunkY(), a_Pickup.GetChunkZ());
|
cChunkPtr Chunk = GetChunkNoGen(a_Pickup.GetChunkX(), ZERO_CHUNK_Y, a_Pickup.GetChunkZ());
|
||||||
if (Chunk == NULL)
|
if (Chunk == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -689,10 +689,10 @@ void cChunkMap::WakeUpSimulators(int a_BlockX, int a_BlockY, int a_BlockZ)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cChunkMap::MarkChunkDirty (int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
void cChunkMap::MarkChunkDirty (int a_ChunkX, int a_ChunkZ)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSLayers);
|
cCSLock Lock(m_CSLayers);
|
||||||
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ);
|
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ);
|
||||||
if ((Chunk == NULL) || !Chunk->IsValid())
|
if ((Chunk == NULL) || !Chunk->IsValid())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -704,10 +704,10 @@ void cChunkMap::MarkChunkDirty (int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cChunkMap::MarkChunkSaving(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
void cChunkMap::MarkChunkSaving(int a_ChunkX, int a_ChunkZ)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSLayers);
|
cCSLock Lock(m_CSLayers);
|
||||||
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ);
|
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ);
|
||||||
if ((Chunk == NULL) || !Chunk->IsValid())
|
if ((Chunk == NULL) || !Chunk->IsValid())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -719,10 +719,10 @@ void cChunkMap::MarkChunkSaving(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cChunkMap::MarkChunkSaved (int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
void cChunkMap::MarkChunkSaved (int a_ChunkX, int a_ChunkZ)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSLayers);
|
cCSLock Lock(m_CSLayers);
|
||||||
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ);
|
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ);
|
||||||
if ((Chunk == NULL) || !Chunk->IsValid())
|
if ((Chunk == NULL) || !Chunk->IsValid())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -735,25 +735,24 @@ void cChunkMap::MarkChunkSaved (int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
|||||||
|
|
||||||
|
|
||||||
void cChunkMap::SetChunkData(
|
void cChunkMap::SetChunkData(
|
||||||
int a_ChunkX, int a_ChunkY, int a_ChunkZ,
|
int a_ChunkX, int a_ChunkZ,
|
||||||
const BLOCKTYPE * a_BlockTypes,
|
const BLOCKTYPE * a_BlockTypes,
|
||||||
const NIBBLETYPE * a_BlockMeta,
|
const NIBBLETYPE * a_BlockMeta,
|
||||||
const NIBBLETYPE * a_BlockLight,
|
const NIBBLETYPE * a_BlockLight,
|
||||||
const NIBBLETYPE * a_BlockSkyLight,
|
const NIBBLETYPE * a_BlockSkyLight,
|
||||||
const cChunkDef::HeightMap * a_HeightMap,
|
const cChunkDef::HeightMap * a_HeightMap,
|
||||||
const cChunkDef::BiomeMap & a_BiomeMap,
|
const cChunkDef::BiomeMap & a_BiomeMap,
|
||||||
cEntityList & a_Entities,
|
|
||||||
cBlockEntityList & a_BlockEntities,
|
cBlockEntityList & a_BlockEntities,
|
||||||
bool a_MarkDirty
|
bool a_MarkDirty
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSLayers);
|
cCSLock Lock(m_CSLayers);
|
||||||
cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkY, a_ChunkZ);
|
cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ);
|
||||||
if (Chunk == NULL)
|
if (Chunk == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Chunk->SetAllData(a_BlockTypes, a_BlockMeta, a_BlockLight, a_BlockSkyLight, a_HeightMap, a_BiomeMap, a_Entities, a_BlockEntities);
|
Chunk->SetAllData(a_BlockTypes, a_BlockMeta, a_BlockLight, a_BlockSkyLight, a_HeightMap, a_BiomeMap, a_BlockEntities);
|
||||||
|
|
||||||
if (a_MarkDirty)
|
if (a_MarkDirty)
|
||||||
{
|
{
|
||||||
@ -788,10 +787,10 @@ void cChunkMap::ChunkLighted(
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunkMap::GetChunkData(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkDataCallback & a_Callback)
|
bool cChunkMap::GetChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataCallback & a_Callback)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSLayers);
|
cCSLock Lock(m_CSLayers);
|
||||||
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ);
|
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ);
|
||||||
if ((Chunk == NULL) || !Chunk->IsValid())
|
if ((Chunk == NULL) || !Chunk->IsValid())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@ -804,10 +803,10 @@ bool cChunkMap::GetChunkData(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkDat
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunkMap::GetChunkBlockTypes(int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_BlockTypes)
|
bool cChunkMap::GetChunkBlockTypes(int a_ChunkX, int a_ChunkZ, BLOCKTYPE * a_BlockTypes)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSLayers);
|
cCSLock Lock(m_CSLayers);
|
||||||
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ);
|
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ);
|
||||||
if ((Chunk == NULL) || !Chunk->IsValid())
|
if ((Chunk == NULL) || !Chunk->IsValid())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@ -820,10 +819,10 @@ bool cChunkMap::GetChunkBlockTypes(int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLO
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunkMap::IsChunkValid(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
bool cChunkMap::IsChunkValid(int a_ChunkX, int a_ChunkZ)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSLayers);
|
cCSLock Lock(m_CSLayers);
|
||||||
cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkY, a_ChunkZ);
|
cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ);
|
||||||
return (Chunk != NULL) && Chunk->IsValid();
|
return (Chunk != NULL) && Chunk->IsValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -831,10 +830,10 @@ bool cChunkMap::IsChunkValid(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunkMap::HasChunkAnyClients(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
bool cChunkMap::HasChunkAnyClients(int a_ChunkX, int a_ChunkZ)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSLayers);
|
cCSLock Lock(m_CSLayers);
|
||||||
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ);
|
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ);
|
||||||
return (Chunk != NULL) && Chunk->HasAnyClients();
|
return (Chunk != NULL) && Chunk->HasAnyClients();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -844,24 +843,45 @@ bool cChunkMap::HasChunkAnyClients(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
|||||||
|
|
||||||
int cChunkMap::GetHeight(int a_BlockX, int a_BlockZ)
|
int cChunkMap::GetHeight(int a_BlockX, int a_BlockZ)
|
||||||
{
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
cCSLock Lock(m_CSLayers);
|
||||||
|
int ChunkX, ChunkZ, BlockY = 0;
|
||||||
|
cChunkDef::AbsoluteToRelative(a_BlockX, BlockY, a_BlockZ, ChunkX, ChunkZ);
|
||||||
|
cChunkPtr Chunk = GetChunk(ChunkX, ZERO_CHUNK_Y, ChunkZ);
|
||||||
|
if (Chunk == NULL)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Chunk->IsValid())
|
||||||
|
{
|
||||||
|
return Chunk->GetHeight(a_BlockX, a_BlockZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The chunk is not valid, wait for it to become valid:
|
||||||
|
cCSUnlock Unlock(Lock);
|
||||||
|
m_evtChunkValid.Wait();
|
||||||
|
} // while (true)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cChunkMap::TryGetHeight(int a_BlockX, int a_BlockZ, int & a_Height)
|
||||||
|
{
|
||||||
|
// Returns false if chunk not loaded / generated
|
||||||
cCSLock Lock(m_CSLayers);
|
cCSLock Lock(m_CSLayers);
|
||||||
int ChunkX, ChunkZ, BlockY = 0;
|
int ChunkX, ChunkZ, BlockY = 0;
|
||||||
cChunkDef::AbsoluteToRelative(a_BlockX, BlockY, a_BlockZ, ChunkX, ChunkZ);
|
cChunkDef::AbsoluteToRelative(a_BlockX, BlockY, a_BlockZ, ChunkX, ChunkZ);
|
||||||
cChunkPtr Chunk = GetChunk(ChunkX, ZERO_CHUNK_Y, ChunkZ);
|
cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ);
|
||||||
if (Chunk == NULL)
|
if ((Chunk == NULL) || !Chunk->IsValid())
|
||||||
{
|
{
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
a_Height = Chunk->GetHeight(a_BlockX, a_BlockZ);
|
||||||
// Wait for the chunk to become valid:
|
return true;
|
||||||
while (!Chunk->IsValid())
|
|
||||||
{
|
|
||||||
GetChunk(ChunkX, ZERO_CHUNK_Y, ChunkZ); // Re-queue (in case it managed to get unloaded before we caught it
|
|
||||||
cCSUnlock Unlock(Lock);
|
|
||||||
m_evtChunkValid.Wait();
|
|
||||||
}
|
|
||||||
|
|
||||||
return Chunk->GetHeight(a_BlockX, a_BlockZ);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1239,22 +1259,31 @@ void cChunkMap::SendBlockTo(int a_X, int a_Y, int a_Z, cPlayer * a_Player)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cChunkMap::CompareChunkClients(int a_ChunkX1, int a_ChunkY1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkY2, int a_ChunkZ2, cClientDiffCallback & a_Callback)
|
void cChunkMap::CompareChunkClients(int a_ChunkX1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkZ2, cClientDiffCallback & a_Callback)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSLayers);
|
cCSLock Lock(m_CSLayers);
|
||||||
cChunkPtr Chunk1 = GetChunkNoGen(a_ChunkX1, a_ChunkY1, a_ChunkZ1);
|
cChunkPtr Chunk1 = GetChunkNoGen(a_ChunkX1, ZERO_CHUNK_Y, a_ChunkZ1);
|
||||||
if (Chunk1 == NULL)
|
if (Chunk1 == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cChunkPtr Chunk2 = GetChunkNoGen(a_ChunkX2, a_ChunkY2, a_ChunkZ2);
|
cChunkPtr Chunk2 = GetChunkNoGen(a_ChunkX2, ZERO_CHUNK_Y, a_ChunkZ2);
|
||||||
if (Chunk2 == NULL)
|
if (Chunk2 == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cClientHandleList Clients1(Chunk1->GetAllClients());
|
CompareChunkClients(Chunk1, Chunk2, a_Callback);
|
||||||
cClientHandleList Clients2(Chunk2->GetAllClients());
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cChunkMap::CompareChunkClients(cChunk * a_Chunk1, cChunk * a_Chunk2, cClientDiffCallback & a_Callback)
|
||||||
|
{
|
||||||
|
cClientHandleList Clients1(a_Chunk1->GetAllClients());
|
||||||
|
cClientHandleList Clients2(a_Chunk2->GetAllClients());
|
||||||
|
|
||||||
// Find "removed" clients:
|
// Find "removed" clients:
|
||||||
for (cClientHandleList::iterator itr1 = Clients1.begin(); itr1 != Clients1.end(); ++itr1)
|
for (cClientHandleList::iterator itr1 = Clients1.begin(); itr1 != Clients1.end(); ++itr1)
|
||||||
@ -1297,10 +1326,10 @@ void cChunkMap::CompareChunkClients(int a_ChunkX1, int a_ChunkY1, int a_ChunkZ1,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunkMap::AddChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client)
|
bool cChunkMap::AddChunkClient(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Client)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSLayers);
|
cCSLock Lock(m_CSLayers);
|
||||||
cChunkPtr Chunk = GetChunk(a_ChunkX, a_ChunkY, a_ChunkZ);
|
cChunkPtr Chunk = GetChunk(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ);
|
||||||
if (Chunk == NULL)
|
if (Chunk == NULL)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@ -1312,10 +1341,10 @@ bool cChunkMap::AddChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClient
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cChunkMap::RemoveChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client)
|
void cChunkMap::RemoveChunkClient(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Client)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSLayers);
|
cCSLock Lock(m_CSLayers);
|
||||||
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ);
|
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ);
|
||||||
if (Chunk == NULL)
|
if (Chunk == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -1341,15 +1370,16 @@ void cChunkMap::RemoveClientFromChunks(cClientHandle * a_Client)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cChunkMap::MoveEntityToChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
// TODO: This function should not be needed, remove?
|
||||||
|
void cChunkMap::MoveEntityToChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkZ)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSLayers);
|
cCSLock Lock(m_CSLayers);
|
||||||
cChunkPtr OldChunk = GetChunkNoGen(a_Entity->GetChunkX(), a_Entity->GetChunkY(), a_Entity->GetChunkZ());
|
cChunkPtr OldChunk = GetChunkNoGen(a_Entity->GetChunkX(), ZERO_CHUNK_Y, a_Entity->GetChunkZ());
|
||||||
if (OldChunk != NULL)
|
if (OldChunk != NULL)
|
||||||
{
|
{
|
||||||
OldChunk->RemoveEntity(a_Entity);
|
OldChunk->RemoveEntity(a_Entity);
|
||||||
}
|
}
|
||||||
cChunkPtr NewChunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ);
|
cChunkPtr NewChunk = GetChunkNoGen(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ);
|
||||||
if (NewChunk != NULL)
|
if (NewChunk != NULL)
|
||||||
{
|
{
|
||||||
NewChunk->AddEntity(a_Entity);
|
NewChunk->AddEntity(a_Entity);
|
||||||
@ -1360,10 +1390,10 @@ void cChunkMap::MoveEntityToChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cChunkMap::RemoveEntityFromChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
void cChunkMap::RemoveEntityFromChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkZ)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSLayers);
|
cCSLock Lock(m_CSLayers);
|
||||||
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ);
|
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ);
|
||||||
if ((Chunk == NULL) && !Chunk->IsValid())
|
if ((Chunk == NULL) && !Chunk->IsValid())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -1375,6 +1405,55 @@ void cChunkMap::RemoveEntityFromChunk(cEntity * a_Entity, int a_ChunkX, int a_Ch
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cChunkMap::AddEntity(cEntity * a_Entity)
|
||||||
|
{
|
||||||
|
cCSLock Lock(m_CSLayers);
|
||||||
|
cChunkPtr Chunk = GetChunkNoGen(a_Entity->GetChunkX(), ZERO_CHUNK_Y, a_Entity->GetChunkZ());
|
||||||
|
if ((Chunk == NULL) && !Chunk->IsValid())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Chunk->AddEntity(a_Entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cChunkMap::HasEntity(int a_UniqueID)
|
||||||
|
{
|
||||||
|
cCSLock Lock(m_CSLayers);
|
||||||
|
for (cChunkLayerList::const_iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr)
|
||||||
|
{
|
||||||
|
if ((*itr)->HasEntity(a_UniqueID))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cChunkMap::ForEachEntity(cEntityCallback & a_Callback)
|
||||||
|
{
|
||||||
|
cCSLock Lock(m_CSLayers);
|
||||||
|
for (cChunkLayerList::const_iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr)
|
||||||
|
{
|
||||||
|
if ((*itr)->ForEachEntity(a_Callback))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunkMap::ForEachEntityInChunk(int a_ChunkX, int a_ChunkZ, cEntityCallback & a_Callback)
|
bool cChunkMap::ForEachEntityInChunk(int a_ChunkX, int a_ChunkZ, cEntityCallback & a_Callback)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSLayers);
|
cCSLock Lock(m_CSLayers);
|
||||||
@ -1390,6 +1469,24 @@ bool cChunkMap::ForEachEntityInChunk(int a_ChunkX, int a_ChunkZ, cEntityCallback
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cChunkMap::DoWithEntityByID(int a_UniqueID, cEntityCallback & a_Callback)
|
||||||
|
{
|
||||||
|
cCSLock Lock(m_CSLayers);
|
||||||
|
bool res = false;
|
||||||
|
for (cChunkLayerList::const_iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr)
|
||||||
|
{
|
||||||
|
if ((*itr)->DoWithEntityByID(a_UniqueID, a_Callback, res))
|
||||||
|
{
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunkMap::ForEachChestInChunk(int a_ChunkX, int a_ChunkZ, cChestCallback & a_Callback)
|
bool cChunkMap::ForEachChestInChunk(int a_ChunkX, int a_ChunkZ, cChestCallback & a_Callback)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSLayers);
|
cCSLock Lock(m_CSLayers);
|
||||||
@ -1794,12 +1891,12 @@ void cChunkMap::SetNextBlockTick(int a_BlockX, int a_BlockY, int a_BlockZ)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cChunkMap::Tick( float a_Dt, MTRand & a_TickRandom )
|
void cChunkMap::Tick(float a_Dt)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSLayers);
|
cCSLock Lock(m_CSLayers);
|
||||||
for (cChunkLayerList::iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr)
|
for (cChunkLayerList::iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr)
|
||||||
{
|
{
|
||||||
(*itr)->Tick(a_Dt, a_TickRandom);
|
(*itr)->Tick(a_Dt);
|
||||||
} // for itr - m_Layers
|
} // for itr - m_Layers
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1951,14 +2048,14 @@ cChunk * cChunkMap::cChunkLayer::FindChunk(int a_ChunkX, int a_ChunkZ)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cChunkMap::cChunkLayer::Tick(float a_Dt, MTRand & a_TickRand)
|
void cChunkMap::cChunkLayer::Tick(float a_Dt)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < ARRAYCOUNT(m_Chunks); i++)
|
for (int i = 0; i < ARRAYCOUNT(m_Chunks); i++)
|
||||||
{
|
{
|
||||||
// Only tick chunks that are valid and have clients:
|
// Only tick chunks that are valid and have clients:
|
||||||
if ((m_Chunks[i] != NULL) && m_Chunks[i]->IsValid() && m_Chunks[i]->HasAnyClients())
|
if ((m_Chunks[i] != NULL) && m_Chunks[i]->IsValid() && m_Chunks[i]->HasAnyClients())
|
||||||
{
|
{
|
||||||
m_Chunks[i]->Tick(a_Dt, a_TickRand);
|
m_Chunks[i]->Tick(a_Dt);
|
||||||
}
|
}
|
||||||
} // for i - m_Chunks[]
|
} // for i - m_Chunks[]
|
||||||
}
|
}
|
||||||
@ -1982,6 +2079,65 @@ void cChunkMap::cChunkLayer::RemoveClient(cClientHandle * a_Client)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cChunkMap::cChunkLayer::ForEachEntity(cEntityCallback & a_Callback)
|
||||||
|
{
|
||||||
|
// Calls the callback for each entity in the entire world; returns true if all entities processed, false if the callback aborted by returning true
|
||||||
|
for (int i = 0; i < ARRAYCOUNT(m_Chunks); i++)
|
||||||
|
{
|
||||||
|
if ((m_Chunks[i] != NULL) && m_Chunks[i]->IsValid())
|
||||||
|
{
|
||||||
|
if (!m_Chunks[i]->ForEachEntity(a_Callback))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cChunkMap::cChunkLayer::DoWithEntityByID(int a_EntityID, cEntityCallback & a_Callback, bool & a_CallbackReturn)
|
||||||
|
{
|
||||||
|
// Calls the callback if the entity with the specified ID is found, with the entity object as the callback param. Returns true if entity found.
|
||||||
|
for (int i = 0; i < ARRAYCOUNT(m_Chunks); i++)
|
||||||
|
{
|
||||||
|
if ((m_Chunks[i] != NULL) && m_Chunks[i]->IsValid())
|
||||||
|
{
|
||||||
|
if (m_Chunks[i]->DoWithEntityByID(a_EntityID, a_Callback, a_CallbackReturn))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cChunkMap::cChunkLayer::HasEntity(int a_EntityID)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < ARRAYCOUNT(m_Chunks); i++)
|
||||||
|
{
|
||||||
|
if ((m_Chunks[i] != NULL) && m_Chunks[i]->IsValid())
|
||||||
|
{
|
||||||
|
if (m_Chunks[i]->HasEntity(a_EntityID))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int cChunkMap::cChunkLayer::GetNumChunksLoaded(void) const
|
int cChunkMap::cChunkLayer::GetNumChunksLoaded(void) const
|
||||||
{
|
{
|
||||||
int NumChunks = 0;
|
int NumChunks = 0;
|
||||||
|
@ -105,9 +105,9 @@ public:
|
|||||||
/// Wakes up simulators for the specified block
|
/// Wakes up simulators for the specified block
|
||||||
void WakeUpSimulators(int a_BlockX, int a_BlockY, int a_BlockZ);
|
void WakeUpSimulators(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||||
|
|
||||||
void MarkChunkDirty (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
|
void MarkChunkDirty (int a_ChunkX, int a_ChunkZ);
|
||||||
void MarkChunkSaving (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
|
void MarkChunkSaving (int a_ChunkX, int a_ChunkZ);
|
||||||
void MarkChunkSaved (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
|
void MarkChunkSaved (int a_ChunkX, int a_ChunkZ);
|
||||||
|
|
||||||
/** Sets the chunk data as either loaded from the storage or generated.
|
/** Sets the chunk data as either loaded from the storage or generated.
|
||||||
a_BlockLight and a_BlockSkyLight are optional, if not present, chunk will be marked as unlighted.
|
a_BlockLight and a_BlockSkyLight are optional, if not present, chunk will be marked as unlighted.
|
||||||
@ -116,14 +116,13 @@ public:
|
|||||||
If a_MarkDirty is set, the chunk is set as dirty (used after generating)
|
If a_MarkDirty is set, the chunk is set as dirty (used after generating)
|
||||||
*/
|
*/
|
||||||
void SetChunkData(
|
void SetChunkData(
|
||||||
int a_ChunkX, int a_ChunkY, int a_ChunkZ,
|
int a_ChunkX, int a_ChunkZ,
|
||||||
const BLOCKTYPE * a_BlockTypes,
|
const BLOCKTYPE * a_BlockTypes,
|
||||||
const NIBBLETYPE * a_BlockMeta,
|
const NIBBLETYPE * a_BlockMeta,
|
||||||
const NIBBLETYPE * a_BlockLight,
|
const NIBBLETYPE * a_BlockLight,
|
||||||
const NIBBLETYPE * a_BlockSkyLight,
|
const NIBBLETYPE * a_BlockSkyLight,
|
||||||
const cChunkDef::HeightMap * a_HeightMap,
|
const cChunkDef::HeightMap * a_HeightMap,
|
||||||
const cChunkDef::BiomeMap & a_BiomeMap,
|
const cChunkDef::BiomeMap & a_BiomeMap,
|
||||||
cEntityList & a_Entities,
|
|
||||||
cBlockEntityList & a_BlockEntities,
|
cBlockEntityList & a_BlockEntities,
|
||||||
bool a_MarkDirty
|
bool a_MarkDirty
|
||||||
);
|
);
|
||||||
@ -134,14 +133,15 @@ public:
|
|||||||
const cChunkDef::BlockNibbles & a_SkyLight
|
const cChunkDef::BlockNibbles & a_SkyLight
|
||||||
);
|
);
|
||||||
|
|
||||||
bool GetChunkData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkDataCallback & a_Callback);
|
bool GetChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataCallback & a_Callback);
|
||||||
|
|
||||||
/// Copies the chunk's blocktypes into a_Blocks; returns true if successful
|
/// Copies the chunk's blocktypes into a_Blocks; returns true if successful
|
||||||
bool GetChunkBlockTypes (int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_Blocks);
|
bool GetChunkBlockTypes (int a_ChunkX, int a_ChunkZ, BLOCKTYPE * a_Blocks);
|
||||||
|
|
||||||
bool IsChunkValid (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
|
bool IsChunkValid (int a_ChunkX, int a_ChunkZ);
|
||||||
bool HasChunkAnyClients (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
|
bool HasChunkAnyClients (int a_ChunkX, int a_ChunkZ);
|
||||||
int GetHeight (int a_BlockX, int a_BlockZ);
|
int GetHeight (int a_BlockX, int a_BlockZ); // Waits for the chunk to get loaded / generated
|
||||||
|
bool TryGetHeight (int a_BlockX, int a_BlockZ, int & a_Height); // Returns false if chunk not loaded / generated
|
||||||
void FastSetBlocks (sSetBlockList & a_BlockList);
|
void FastSetBlocks (sSetBlockList & a_BlockList);
|
||||||
void CollectPickupsByPlayer(cPlayer * a_Player);
|
void CollectPickupsByPlayer(cPlayer * a_Player);
|
||||||
|
|
||||||
@ -169,26 +169,41 @@ public:
|
|||||||
void SendBlockTo(int a_X, int a_Y, int a_Z, cPlayer * a_Player);
|
void SendBlockTo(int a_X, int a_Y, int a_Z, cPlayer * a_Player);
|
||||||
|
|
||||||
/// Compares clients of two chunks, calls the callback accordingly
|
/// Compares clients of two chunks, calls the callback accordingly
|
||||||
void CompareChunkClients(int a_ChunkX1, int a_ChunkY1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkY2, int a_ChunkZ2, cClientDiffCallback & a_Callback);
|
void CompareChunkClients(int a_ChunkX1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkZ2, cClientDiffCallback & a_Callback);
|
||||||
|
|
||||||
|
/// Compares clients of two chunks, calls the callback accordingly
|
||||||
|
void CompareChunkClients(cChunk * a_Chunk1, cChunk * a_Chunk2, cClientDiffCallback & a_Callback);
|
||||||
|
|
||||||
/// Adds client to a chunk, if not already present; returns true if added, false if present
|
/// Adds client to a chunk, if not already present; returns true if added, false if present
|
||||||
bool AddChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client);
|
bool AddChunkClient(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Client);
|
||||||
|
|
||||||
/// Removes the client from the chunk
|
/// Removes the client from the chunk
|
||||||
void RemoveChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client);
|
void RemoveChunkClient(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Client);
|
||||||
|
|
||||||
/// Removes the client from all chunks it is present in
|
/// Removes the client from all chunks it is present in
|
||||||
void RemoveClientFromChunks(cClientHandle * a_Client);
|
void RemoveClientFromChunks(cClientHandle * a_Client);
|
||||||
|
|
||||||
/// Moves the entity from its current chunk to the new chunk specified
|
/// Moves the entity from its current chunk to the new chunk specified
|
||||||
void MoveEntityToChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ);
|
void MoveEntityToChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkZ);
|
||||||
|
|
||||||
/// Removes the entity from the chunk specified
|
/// Removes the entity from the chunk specified
|
||||||
void RemoveEntityFromChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ);
|
void RemoveEntityFromChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkZ);
|
||||||
|
|
||||||
|
/// Adds the entity to its appropriate chunk, takes ownership of the entity pointer
|
||||||
|
void AddEntity(cEntity * a_Entity);
|
||||||
|
|
||||||
|
/// Returns true if the entity with specified ID is present in the chunks
|
||||||
|
bool HasEntity(int a_EntityID);
|
||||||
|
|
||||||
|
/// Calls the callback for each entity in the entire world; returns true if all entities processed, false if the callback aborted by returning true
|
||||||
|
bool ForEachEntity(cEntityCallback & a_Callback); // Lua-accessible
|
||||||
|
|
||||||
/// Calls the callback for each entity in the specified chunk; returns true if all entities processed, false if the callback aborted by returning true
|
/// Calls the callback for each entity in the specified chunk; returns true if all entities processed, false if the callback aborted by returning true
|
||||||
bool ForEachEntityInChunk(int a_ChunkX, int a_ChunkZ, cEntityCallback & a_Callback); // Lua-accessible
|
bool ForEachEntityInChunk(int a_ChunkX, int a_ChunkZ, cEntityCallback & a_Callback); // Lua-accessible
|
||||||
|
|
||||||
|
/// Calls the callback if the entity with the specified ID is found, with the entity object as the callback param. Returns true if entity found and callback returned false.
|
||||||
|
bool DoWithEntityByID(int a_UniqueID, cEntityCallback & a_Callback); // Lua-accessible
|
||||||
|
|
||||||
/// Calls the callback for each chest in the specified chunk; returns true if all chests processed, false if the callback aborted by returning true
|
/// Calls the callback for each chest in the specified chunk; returns true if all chests processed, false if the callback aborted by returning true
|
||||||
bool ForEachChestInChunk (int a_ChunkX, int a_ChunkZ, cChestCallback & a_Callback); // Lua-accessible
|
bool ForEachChestInChunk (int a_ChunkX, int a_ChunkZ, cChestCallback & a_Callback); // Lua-accessible
|
||||||
|
|
||||||
@ -253,12 +268,12 @@ public:
|
|||||||
/// Sets the blockticking to start at the specified block. Only one blocktick per chunk may be set, second call overwrites the first call
|
/// Sets the blockticking to start at the specified block. Only one blocktick per chunk may be set, second call overwrites the first call
|
||||||
void SetNextBlockTick(int a_BlockX, int a_BlockY, int a_BlockZ);
|
void SetNextBlockTick(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||||
|
|
||||||
void Tick( float a_Dt, MTRand & a_TickRand );
|
void Tick(float a_Dt);
|
||||||
|
|
||||||
void UnloadUnusedChunks();
|
void UnloadUnusedChunks(void);
|
||||||
void SaveAllChunks();
|
void SaveAllChunks(void);
|
||||||
|
|
||||||
cWorld * GetWorld() { return m_World; }
|
cWorld * GetWorld(void) { return m_World; }
|
||||||
|
|
||||||
int GetNumChunks(void);
|
int GetNumChunks(void);
|
||||||
|
|
||||||
@ -293,10 +308,19 @@ private:
|
|||||||
void Save(void);
|
void Save(void);
|
||||||
void UnloadUnusedChunks(void);
|
void UnloadUnusedChunks(void);
|
||||||
|
|
||||||
void Tick( float a_Dt, MTRand & a_TickRand );
|
void Tick(float a_Dt);
|
||||||
|
|
||||||
void RemoveClient(cClientHandle * a_Client);
|
void RemoveClient(cClientHandle * a_Client);
|
||||||
|
|
||||||
|
/// Calls the callback for each entity in the entire world; returns true if all entities processed, false if the callback aborted by returning true
|
||||||
|
bool ForEachEntity(cEntityCallback & a_Callback); // Lua-accessible
|
||||||
|
|
||||||
|
/// Calls the callback if the entity with the specified ID is found, with the entity object as the callback param. Returns true if entity found.
|
||||||
|
bool DoWithEntityByID(int a_EntityID, cEntityCallback & a_Callback, bool & a_CallbackReturn); // Lua-accessible
|
||||||
|
|
||||||
|
/// Returns true if there is an entity with the specified ID within this layer's chunks
|
||||||
|
bool HasEntity(int a_EntityID);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
cChunkPtr m_Chunks[LAYER_SIZE * LAYER_SIZE];
|
cChunkPtr m_Chunks[LAYER_SIZE * LAYER_SIZE];
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
void cNotifyChunkSender::Call(int a_ChunkX, int a_ChunkZ)
|
void cNotifyChunkSender::Call(int a_ChunkX, int a_ChunkZ)
|
||||||
{
|
{
|
||||||
m_ChunkSender->ChunkReady(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ);
|
m_ChunkSender->ChunkReady(a_ChunkX, a_ChunkZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -76,12 +76,12 @@ void cChunkSender::Stop(void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cChunkSender::ChunkReady(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
void cChunkSender::ChunkReady(int a_ChunkX, int a_ChunkZ)
|
||||||
{
|
{
|
||||||
// This is probably never gonna be called twice for the same chunk, and if it is, we don't mind, so we don't check
|
// This is probably never gonna be called twice for the same chunk, and if it is, we don't mind, so we don't check
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CS);
|
cCSLock Lock(m_CS);
|
||||||
m_ChunksReady.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ));
|
m_ChunksReady.push_back(cChunkCoords(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ));
|
||||||
}
|
}
|
||||||
m_evtQueue.Set();
|
m_evtQueue.Set();
|
||||||
}
|
}
|
||||||
@ -90,17 +90,17 @@ void cChunkSender::ChunkReady(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cChunkSender::QueueSendChunkTo(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client)
|
void cChunkSender::QueueSendChunkTo(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Client)
|
||||||
{
|
{
|
||||||
ASSERT(a_Client != NULL);
|
ASSERT(a_Client != NULL);
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CS);
|
cCSLock Lock(m_CS);
|
||||||
if (std::find(m_SendChunks.begin(), m_SendChunks.end(), sSendChunk(a_ChunkX, a_ChunkY, a_ChunkZ, a_Client)) != m_SendChunks.end())
|
if (std::find(m_SendChunks.begin(), m_SendChunks.end(), sSendChunk(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ, a_Client)) != m_SendChunks.end())
|
||||||
{
|
{
|
||||||
// Already queued, bail out
|
// Already queued, bail out
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_SendChunks.push_back(sSendChunk(a_ChunkX, a_ChunkY, a_ChunkZ, a_Client));
|
m_SendChunks.push_back(sSendChunk(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ, a_Client));
|
||||||
}
|
}
|
||||||
m_evtQueue.Set();
|
m_evtQueue.Set();
|
||||||
}
|
}
|
||||||
@ -200,13 +200,13 @@ void cChunkSender::SendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHa
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If the chunk has no clients, no need to packetize it:
|
// If the chunk has no clients, no need to packetize it:
|
||||||
if (!m_World->HasChunkAnyClients(a_ChunkX, a_ChunkY, a_ChunkZ))
|
if (!m_World->HasChunkAnyClients(a_ChunkX, a_ChunkZ))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the chunk is not valid, do nothing - whoever needs it has queued it for loading / generating
|
// If the chunk is not valid, do nothing - whoever needs it has queued it for loading / generating
|
||||||
if (!m_World->IsChunkValid(a_ChunkX, a_ChunkY, a_ChunkZ))
|
if (!m_World->IsChunkValid(a_ChunkX, a_ChunkZ))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -219,7 +219,7 @@ void cChunkSender::SendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHa
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Query and prepare chunk data:
|
// Query and prepare chunk data:
|
||||||
if( !m_World->GetChunkData(a_ChunkX, a_ChunkY, a_ChunkZ, *this) )
|
if (!m_World->GetChunkData(a_ChunkX, a_ChunkZ, *this))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -80,10 +80,10 @@ public:
|
|||||||
void Stop(void);
|
void Stop(void);
|
||||||
|
|
||||||
/// Notifies that a chunk has become ready and it should be sent to all its clients
|
/// Notifies that a chunk has become ready and it should be sent to all its clients
|
||||||
void ChunkReady(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
|
void ChunkReady(int a_ChunkX, int a_ChunkZ);
|
||||||
|
|
||||||
/// Queues a chunk to be sent to a specific client
|
/// Queues a chunk to be sent to a specific client
|
||||||
void QueueSendChunkTo(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client);
|
void QueueSendChunkTo(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Client);
|
||||||
|
|
||||||
/// Removes the a_Client from all waiting chunk send operations
|
/// Removes the a_Client from all waiting chunk send operations
|
||||||
void RemoveClient(cClientHandle * a_Client);
|
void RemoveClient(cClientHandle * a_Client);
|
||||||
|
@ -137,7 +137,10 @@ cClientHandle::~cClientHandle()
|
|||||||
if (World != NULL)
|
if (World != NULL)
|
||||||
{
|
{
|
||||||
World->RemovePlayer(m_Player);
|
World->RemovePlayer(m_Player);
|
||||||
|
m_Player->Destroy();
|
||||||
}
|
}
|
||||||
|
delete m_Player;
|
||||||
|
m_Player = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_HasSentDC)
|
if (!m_HasSentDC)
|
||||||
@ -145,12 +148,6 @@ cClientHandle::~cClientHandle()
|
|||||||
SendDisconnect("Server shut down? Kthnxbai");
|
SendDisconnect("Server shut down? Kthnxbai");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_Player != NULL)
|
|
||||||
{
|
|
||||||
m_Player->Destroy();
|
|
||||||
m_Player = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Queue all remaining outgoing packets to cSocketThreads:
|
// Queue all remaining outgoing packets to cSocketThreads:
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSOutgoingData);
|
cCSLock Lock(m_CSOutgoingData);
|
||||||
@ -325,7 +322,7 @@ void cClientHandle::StreamChunks(void)
|
|||||||
}
|
}
|
||||||
for (cChunkCoordsList::iterator itr = RemoveChunks.begin(); itr != RemoveChunks.end(); ++itr)
|
for (cChunkCoordsList::iterator itr = RemoveChunks.begin(); itr != RemoveChunks.end(); ++itr)
|
||||||
{
|
{
|
||||||
World->RemoveChunkClient(itr->m_ChunkX, itr->m_ChunkY, itr->m_ChunkZ, this);
|
World->RemoveChunkClient(itr->m_ChunkX, itr->m_ChunkZ, this);
|
||||||
m_Protocol->SendUnloadChunk(itr->m_ChunkX, itr->m_ChunkZ);
|
m_Protocol->SendUnloadChunk(itr->m_ChunkX, itr->m_ChunkZ);
|
||||||
} // for itr - RemoveChunks[]
|
} // for itr - RemoveChunks[]
|
||||||
|
|
||||||
@ -336,13 +333,13 @@ void cClientHandle::StreamChunks(void)
|
|||||||
// For each distance add chunks in a hollow square centered around current position:
|
// For each distance add chunks in a hollow square centered around current position:
|
||||||
for (int i = -d; i <= d; ++i)
|
for (int i = -d; i <= d; ++i)
|
||||||
{
|
{
|
||||||
StreamChunk(ChunkPosX + d, ZERO_CHUNK_Y, ChunkPosZ + i);
|
StreamChunk(ChunkPosX + d, ChunkPosZ + i);
|
||||||
StreamChunk(ChunkPosX - d, ZERO_CHUNK_Y, ChunkPosZ + i);
|
StreamChunk(ChunkPosX - d, ChunkPosZ + i);
|
||||||
} // for i
|
} // for i
|
||||||
for (int i = -d + 1; i < d; ++i)
|
for (int i = -d + 1; i < d; ++i)
|
||||||
{
|
{
|
||||||
StreamChunk(ChunkPosX + i, ZERO_CHUNK_Y, ChunkPosZ + d);
|
StreamChunk(ChunkPosX + i, ChunkPosZ + d);
|
||||||
StreamChunk(ChunkPosX + i, ZERO_CHUNK_Y, ChunkPosZ - d);
|
StreamChunk(ChunkPosX + i, ChunkPosZ - d);
|
||||||
} // for i
|
} // for i
|
||||||
} // for d
|
} // for d
|
||||||
|
|
||||||
@ -366,7 +363,7 @@ void cClientHandle::StreamChunks(void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cClientHandle::StreamChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
void cClientHandle::StreamChunk(int a_ChunkX, int a_ChunkZ)
|
||||||
{
|
{
|
||||||
if (m_State >= csDestroying)
|
if (m_State >= csDestroying)
|
||||||
{
|
{
|
||||||
@ -377,14 +374,14 @@ void cClientHandle::StreamChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
|||||||
cWorld * World = m_Player->GetWorld();
|
cWorld * World = m_Player->GetWorld();
|
||||||
ASSERT(World != NULL);
|
ASSERT(World != NULL);
|
||||||
|
|
||||||
if (World->AddChunkClient(a_ChunkX, a_ChunkY, a_ChunkZ, this))
|
if (World->AddChunkClient(a_ChunkX, a_ChunkZ, this))
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSChunkLists);
|
cCSLock Lock(m_CSChunkLists);
|
||||||
m_LoadedChunks.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ));
|
m_LoadedChunks.push_back(cChunkCoords(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ));
|
||||||
m_ChunksToSend.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ));
|
m_ChunksToSend.push_back(cChunkCoords(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ));
|
||||||
}
|
}
|
||||||
World->SendChunkTo(a_ChunkX, a_ChunkY, a_ChunkZ, this);
|
World->SendChunkTo(a_ChunkX, a_ChunkZ, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1128,6 +1125,7 @@ void cClientHandle::HandleDisconnect(const AString & a_Reason)
|
|||||||
Printf(DisconnectMessage, "%s disconnected: %s", m_Username.c_str(), a_Reason.c_str());
|
Printf(DisconnectMessage, "%s disconnected: %s", m_Username.c_str(), a_Reason.c_str());
|
||||||
m_Player->GetWorld()->BroadcastChat(DisconnectMessage, this);
|
m_Player->GetWorld()->BroadcastChat(DisconnectMessage, this);
|
||||||
}
|
}
|
||||||
|
m_HasSentDC = true;
|
||||||
Destroy();
|
Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,7 +209,7 @@ private:
|
|||||||
|
|
||||||
cPlayer * m_Player;
|
cPlayer * m_Player;
|
||||||
|
|
||||||
bool m_HasSentDC;
|
bool m_HasSentDC; ///< True if a D/C packet has been sent in either direction
|
||||||
|
|
||||||
// Chunk position when the last StreamChunks() was called; used to avoid re-streaming while in the same chunk
|
// Chunk position when the last StreamChunks() was called; used to avoid re-streaming while in the same chunk
|
||||||
int m_LastStreamedChunkX;
|
int m_LastStreamedChunkX;
|
||||||
@ -267,7 +267,7 @@ private:
|
|||||||
void SendConfirmPosition(void);
|
void SendConfirmPosition(void);
|
||||||
|
|
||||||
/// Adds a single chunk to be streamed to the client; used by StreamChunks()
|
/// Adds a single chunk to be streamed to the client; used by StreamChunks()
|
||||||
void StreamChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
|
void StreamChunk(int a_ChunkX, int a_ChunkZ);
|
||||||
|
|
||||||
/// Handles the DIG_STARTED dig packet:
|
/// Handles the DIG_STARTED dig packet:
|
||||||
void HandleBlockDigStarted (int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_OldBlock, NIBBLETYPE a_OldMeta);
|
void HandleBlockDigStarted (int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_OldBlock, NIBBLETYPE a_OldMeta);
|
||||||
|
@ -27,16 +27,13 @@ cEntity::cEntity(eEntityType a_EntityType, double a_X, double a_Y, double a_Z)
|
|||||||
, m_Attachee(NULL)
|
, m_Attachee(NULL)
|
||||||
, m_Referencers(new cReferenceManager(cReferenceManager::RFMNGR_REFERENCERS))
|
, m_Referencers(new cReferenceManager(cReferenceManager::RFMNGR_REFERENCERS))
|
||||||
, m_References(new cReferenceManager(cReferenceManager::RFMNGR_REFERENCES))
|
, m_References(new cReferenceManager(cReferenceManager::RFMNGR_REFERENCES))
|
||||||
, m_ChunkX(0)
|
|
||||||
, m_ChunkY(0)
|
|
||||||
, m_ChunkZ(0)
|
|
||||||
, m_HeadYaw( 0.0 )
|
, m_HeadYaw( 0.0 )
|
||||||
, m_Pos(a_X, a_Y, a_Z)
|
, m_Pos(a_X, a_Y, a_Z)
|
||||||
, m_bDirtyHead(true)
|
, m_bDirtyHead(true)
|
||||||
, m_bDirtyOrientation(true)
|
, m_bDirtyOrientation(true)
|
||||||
, m_bDirtyPosition(true)
|
, m_bDirtyPosition(true)
|
||||||
, m_bDirtySpeed(true)
|
, m_bDirtySpeed(true)
|
||||||
, m_bDestroyed(true)
|
, m_IsInitialized(false)
|
||||||
, m_LastPosX( 0.0 )
|
, m_LastPosX( 0.0 )
|
||||||
, m_LastPosY( 0.0 )
|
, m_LastPosY( 0.0 )
|
||||||
, m_LastPosZ( 0.0 )
|
, m_LastPosZ( 0.0 )
|
||||||
@ -45,7 +42,6 @@ cEntity::cEntity(eEntityType a_EntityType, double a_X, double a_Y, double a_Z)
|
|||||||
, m_TimeLastSpeedPacket(0)
|
, m_TimeLastSpeedPacket(0)
|
||||||
, m_EntityType(a_EntityType)
|
, m_EntityType(a_EntityType)
|
||||||
, m_World(NULL)
|
, m_World(NULL)
|
||||||
, m_bRemovedFromChunk(true)
|
|
||||||
, m_FireDamageInterval(0.f)
|
, m_FireDamageInterval(0.f)
|
||||||
, m_BurnPeriod(0.f)
|
, m_BurnPeriod(0.f)
|
||||||
{
|
{
|
||||||
@ -60,6 +56,8 @@ cEntity::cEntity(eEntityType a_EntityType, double a_X, double a_Y, double a_Z)
|
|||||||
|
|
||||||
cEntity::~cEntity()
|
cEntity::~cEntity()
|
||||||
{
|
{
|
||||||
|
ASSERT(!m_World->HasEntity(m_UniqueID)); // Before deleting, the entity needs to have been removed from the world
|
||||||
|
|
||||||
LOGD("Deleting entity %d at pos {%.2f, %.2f, %.2f} ~ [%d, %d]; ptr %p",
|
LOGD("Deleting entity %d at pos {%.2f, %.2f, %.2f} ~ [%d, %d]; ptr %p",
|
||||||
m_UniqueID,
|
m_UniqueID,
|
||||||
m_Pos.x, m_Pos.y, m_Pos.z,
|
m_Pos.x, m_Pos.y, m_Pos.z,
|
||||||
@ -76,9 +74,9 @@ cEntity::~cEntity()
|
|||||||
m_Attachee->Detach();
|
m_Attachee->Detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_bDestroyed || !m_bRemovedFromChunk)
|
if (m_IsInitialized)
|
||||||
{
|
{
|
||||||
LOGERROR("ERROR: Entity deallocated without being destroyed %i or unlinked %i", m_bDestroyed, m_bRemovedFromChunk);
|
LOGWARNING("ERROR: Entity deallocated without being destroyed");
|
||||||
ASSERT(!"Entity deallocated without being destroyed or unlinked");
|
ASSERT(!"Entity deallocated without being destroyed or unlinked");
|
||||||
}
|
}
|
||||||
delete m_Referencers;
|
delete m_Referencers;
|
||||||
@ -118,41 +116,43 @@ const char * cEntity::GetParentClass(void) const
|
|||||||
|
|
||||||
void cEntity::Initialize(cWorld * a_World)
|
void cEntity::Initialize(cWorld * a_World)
|
||||||
{
|
{
|
||||||
m_bDestroyed = false;
|
LOGD("Initializing entity #%d (%s) at {%.02f, %.02f, %.02f}",
|
||||||
m_bRemovedFromChunk = false;
|
m_UniqueID, GetClass(), m_Pos.x, m_Pos.y, m_Pos.z
|
||||||
|
);
|
||||||
|
m_IsInitialized = true;
|
||||||
m_World = a_World;
|
m_World = a_World;
|
||||||
m_World->AddEntity(this);
|
m_World->AddEntity(this);
|
||||||
|
|
||||||
MoveToCorrectChunk(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cEntity::WrapHeadYaw()
|
void cEntity::WrapHeadYaw(void)
|
||||||
{
|
{
|
||||||
while (m_HeadYaw > 180.f) m_HeadYaw -=360.f; // Wrap it
|
while (m_HeadYaw > 180.f) m_HeadYaw -= 360.f; // Wrap it
|
||||||
while (m_HeadYaw < -180.f) m_HeadYaw +=360.f;
|
while (m_HeadYaw < -180.f) m_HeadYaw += 360.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cEntity::WrapRotation()
|
void cEntity::WrapRotation(void)
|
||||||
{
|
{
|
||||||
while (m_Rot.x > 180.f) m_Rot.x-=360.f; // Wrap it
|
while (m_Rot.x > 180.f) m_Rot.x -= 360.f; // Wrap it
|
||||||
while (m_Rot.x < -180.f) m_Rot.x+=360.f;
|
while (m_Rot.x < -180.f) m_Rot.x += 360.f;
|
||||||
while (m_Rot.y > 180.f) m_Rot.y-=360.f;
|
while (m_Rot.y > 180.f) m_Rot.y -= 360.f;
|
||||||
while (m_Rot.y < -180.f) m_Rot.y+=360.f;
|
while (m_Rot.y < -180.f) m_Rot.y += 360.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cEntity::WrapSpeed()
|
|
||||||
|
|
||||||
|
|
||||||
|
void cEntity::WrapSpeed(void)
|
||||||
{
|
{
|
||||||
//There shoudn't be a need for flipping the flag on because this function is called
|
// There shoudn't be a need for flipping the flag on because this function is called
|
||||||
//after any update, so the flag is already turned on
|
// after any update, so the flag is already turned on
|
||||||
if (m_Speed.x > 20.0f) m_Speed.x = 20.0f;
|
if (m_Speed.x > 20.0f) m_Speed.x = 20.0f;
|
||||||
else if (m_Speed.x < -20.0f) m_Speed.x = -20.0f;
|
else if (m_Speed.x < -20.0f) m_Speed.x = -20.0f;
|
||||||
if (m_Speed.y > 20.0f) m_Speed.y = 20.0f;
|
if (m_Speed.y > 20.0f) m_Speed.y = 20.0f;
|
||||||
@ -165,74 +165,15 @@ void cEntity::WrapSpeed()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cEntity::MoveToCorrectChunk(bool a_bIgnoreOldChunk)
|
void cEntity::Destroy(void)
|
||||||
{
|
{
|
||||||
if (!m_World)
|
if (!m_IsInitialized)
|
||||||
{
|
|
||||||
// This is normal for entities being currently loaded
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ChunkX = 0, ChunkY = 0, ChunkZ = 0;
|
|
||||||
cWorld::BlockToChunk((int)m_Pos.x, (int)m_Pos.y, (int)m_Pos.z, ChunkX, ChunkY, ChunkZ);
|
|
||||||
if (!a_bIgnoreOldChunk && (m_ChunkX == ChunkX) && (m_ChunkY == ChunkY) && (m_ChunkZ == ChunkZ))
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
class cMover :
|
|
||||||
public cClientDiffCallback
|
|
||||||
{
|
|
||||||
virtual void Removed(cClientHandle * a_Client) override
|
|
||||||
{
|
|
||||||
if (m_IgnoreOldChunk)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
a_Client->SendDestroyEntity(*m_Entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void Added(cClientHandle * a_Client) override
|
|
||||||
{
|
|
||||||
m_Entity->SpawnOn(*a_Client);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool m_IgnoreOldChunk;
|
|
||||||
cEntity * m_Entity;
|
|
||||||
|
|
||||||
public:
|
|
||||||
cMover(cEntity * a_Entity, bool a_IgnoreOldChunk) :
|
|
||||||
m_IgnoreOldChunk(a_IgnoreOldChunk),
|
|
||||||
m_Entity(a_Entity)
|
|
||||||
{}
|
|
||||||
} Mover(this, a_bIgnoreOldChunk);
|
|
||||||
|
|
||||||
m_World->CompareChunkClients(m_ChunkX, m_ChunkY, m_ChunkZ, ChunkX, ChunkY, ChunkZ, Mover);
|
|
||||||
m_World->MoveEntityToChunk(this, ChunkX, ChunkY, ChunkZ);
|
|
||||||
|
|
||||||
m_ChunkX = ChunkX;
|
|
||||||
m_ChunkY = ChunkY;
|
|
||||||
m_ChunkZ = ChunkZ;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cEntity::Destroy()
|
|
||||||
{
|
|
||||||
if (m_bDestroyed)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!m_bRemovedFromChunk)
|
|
||||||
{
|
|
||||||
RemoveFromChunk();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_World->BroadcastDestroyEntity(*this);
|
m_World->BroadcastDestroyEntity(*this);
|
||||||
|
|
||||||
m_bDestroyed = true;
|
m_IsInitialized = false;
|
||||||
|
|
||||||
Destroyed();
|
Destroyed();
|
||||||
}
|
}
|
||||||
@ -241,25 +182,8 @@ void cEntity::Destroy()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cEntity::RemoveFromChunk(void)
|
void cEntity::Tick(float a_Dt, cChunk & a_Chunk)
|
||||||
{
|
{
|
||||||
if (m_World == NULL)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_World->RemoveEntityFromChunk(this, m_ChunkX, m_ChunkY, m_ChunkZ);
|
|
||||||
m_bRemovedFromChunk = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cEntity::Tick(float a_Dt, MTRand & a_TickRandom)
|
|
||||||
{
|
|
||||||
UNUSED(a_TickRandom);
|
|
||||||
|
|
||||||
if (m_AttachedTo != NULL)
|
if (m_AttachedTo != NULL)
|
||||||
{
|
{
|
||||||
if ((m_Pos - m_AttachedTo->GetPosition()).Length() > 0.5)
|
if ((m_Pos - m_AttachedTo->GetPosition()).Length() > 0.5)
|
||||||
@ -269,7 +193,7 @@ void cEntity::Tick(float a_Dt, MTRand & a_TickRandom)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HandlePhysics(a_Dt);
|
HandlePhysics(a_Dt, a_Chunk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -496,7 +420,6 @@ void cEntity::SetSpeedZ(double a_SpeedZ)
|
|||||||
void cEntity::AddPosX(double a_AddPosX)
|
void cEntity::AddPosX(double a_AddPosX)
|
||||||
{
|
{
|
||||||
m_Pos.x += a_AddPosX;
|
m_Pos.x += a_AddPosX;
|
||||||
MoveToCorrectChunk();
|
|
||||||
m_bDirtyPosition = true;
|
m_bDirtyPosition = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -506,7 +429,6 @@ void cEntity::AddPosX(double a_AddPosX)
|
|||||||
void cEntity::AddPosY(double a_AddPosY)
|
void cEntity::AddPosY(double a_AddPosY)
|
||||||
{
|
{
|
||||||
m_Pos.y += a_AddPosY;
|
m_Pos.y += a_AddPosY;
|
||||||
MoveToCorrectChunk();
|
|
||||||
m_bDirtyPosition = true;
|
m_bDirtyPosition = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -516,7 +438,6 @@ void cEntity::AddPosY(double a_AddPosY)
|
|||||||
void cEntity::AddPosZ(double a_AddPosZ)
|
void cEntity::AddPosZ(double a_AddPosZ)
|
||||||
{
|
{
|
||||||
m_Pos.z += a_AddPosZ;
|
m_Pos.z += a_AddPosZ;
|
||||||
MoveToCorrectChunk();
|
|
||||||
m_bDirtyPosition = true;
|
m_bDirtyPosition = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -528,7 +449,6 @@ void cEntity::AddPosition(double a_AddPosX, double a_AddPosY, double a_AddPosZ)
|
|||||||
m_Pos.x += a_AddPosX;
|
m_Pos.x += a_AddPosX;
|
||||||
m_Pos.y += a_AddPosY;
|
m_Pos.y += a_AddPosY;
|
||||||
m_Pos.z += a_AddPosZ;
|
m_Pos.z += a_AddPosZ;
|
||||||
MoveToCorrectChunk();
|
|
||||||
m_bDirtyPosition = true;
|
m_bDirtyPosition = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -600,7 +520,6 @@ Vector3d cEntity::GetLookVector(void) const
|
|||||||
void cEntity::SetPosition(double a_PosX, double a_PosY, double a_PosZ)
|
void cEntity::SetPosition(double a_PosX, double a_PosY, double a_PosZ)
|
||||||
{
|
{
|
||||||
m_Pos.Set(a_PosX, a_PosY, a_PosZ);
|
m_Pos.Set(a_PosX, a_PosY, a_PosZ);
|
||||||
MoveToCorrectChunk();
|
|
||||||
m_bDirtyPosition = true;
|
m_bDirtyPosition = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -611,7 +530,6 @@ void cEntity::SetPosition(double a_PosX, double a_PosY, double a_PosZ)
|
|||||||
void cEntity::SetPosX(double a_PosX)
|
void cEntity::SetPosX(double a_PosX)
|
||||||
{
|
{
|
||||||
m_Pos.x = a_PosX;
|
m_Pos.x = a_PosX;
|
||||||
MoveToCorrectChunk();
|
|
||||||
m_bDirtyPosition = true;
|
m_bDirtyPosition = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -622,7 +540,6 @@ void cEntity::SetPosX(double a_PosX)
|
|||||||
void cEntity::SetPosY(double a_PosY)
|
void cEntity::SetPosY(double a_PosY)
|
||||||
{
|
{
|
||||||
m_Pos.y = a_PosY;
|
m_Pos.y = a_PosY;
|
||||||
MoveToCorrectChunk();
|
|
||||||
m_bDirtyPosition = true;
|
m_bDirtyPosition = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -633,7 +550,6 @@ void cEntity::SetPosY(double a_PosY)
|
|||||||
void cEntity::SetPosZ(double a_PosZ)
|
void cEntity::SetPosZ(double a_PosZ)
|
||||||
{
|
{
|
||||||
m_Pos.z = a_PosZ;
|
m_Pos.z = a_PosZ;
|
||||||
MoveToCorrectChunk();
|
|
||||||
m_bDirtyPosition = true;
|
m_bDirtyPosition = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ class cWorld;
|
|||||||
class cReferenceManager;
|
class cReferenceManager;
|
||||||
class cClientHandle;
|
class cClientHandle;
|
||||||
class cPlayer;
|
class cPlayer;
|
||||||
class MTRand;
|
class cChunk;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -120,9 +120,8 @@ public:
|
|||||||
double GetSpeedY (void) const { return m_Speed.y; }
|
double GetSpeedY (void) const { return m_Speed.y; }
|
||||||
double GetSpeedZ (void) const { return m_Speed.z; }
|
double GetSpeedZ (void) const { return m_Speed.z; }
|
||||||
|
|
||||||
int GetChunkX(void) const {return m_ChunkX; }
|
int GetChunkX(void) const {return FAST_FLOOR_DIV(((int)m_Pos.x), cChunkDef::Width); }
|
||||||
int GetChunkY(void) const {return m_ChunkY; }
|
int GetChunkZ(void) const {return FAST_FLOOR_DIV(((int)m_Pos.z), cChunkDef::Width); }
|
||||||
int GetChunkZ(void) const {return m_ChunkZ; }
|
|
||||||
|
|
||||||
void SetHeadYaw (double a_HeadYaw);
|
void SetHeadYaw (double a_HeadYaw);
|
||||||
void SetPosX (double a_PosX);
|
void SetPosX (double a_PosX);
|
||||||
@ -135,7 +134,7 @@ public:
|
|||||||
void SetPitch (double a_Pitch);
|
void SetPitch (double a_Pitch);
|
||||||
void SetRoll (double a_Roll);
|
void SetRoll (double a_Roll);
|
||||||
void SetSpeed (double a_SpeedX, double a_SpeedY, double a_SpeedZ);
|
void SetSpeed (double a_SpeedX, double a_SpeedY, double a_SpeedZ);
|
||||||
void SetSpeed (const Vector3d & a_Speed) { SetSpeed(a_Speed.x,a_Speed.y,a_Speed.z); }
|
void SetSpeed (const Vector3d & a_Speed) { SetSpeed(a_Speed.x, a_Speed.y, a_Speed.z); }
|
||||||
void SetSpeedX (double a_SpeedX);
|
void SetSpeedX (double a_SpeedX);
|
||||||
void SetSpeedY (double a_SpeedY);
|
void SetSpeedY (double a_SpeedY);
|
||||||
void SetSpeedZ (double a_SpeedZ);
|
void SetSpeedZ (double a_SpeedZ);
|
||||||
@ -151,16 +150,15 @@ public:
|
|||||||
void AddSpeedY (double a_AddSpeedY);
|
void AddSpeedY (double a_AddSpeedY);
|
||||||
void AddSpeedZ (double a_AddSpeedZ);
|
void AddSpeedZ (double a_AddSpeedZ);
|
||||||
|
|
||||||
|
inline int GetUniqueID(void) const { return m_UniqueID; }
|
||||||
|
inline bool IsDestroyed(void) const { return !m_IsInitialized; }
|
||||||
|
|
||||||
|
void Destroy(void);
|
||||||
|
|
||||||
// tolua_end
|
// tolua_end
|
||||||
|
|
||||||
inline int GetUniqueID(void) const { return m_UniqueID; } // tolua_export
|
virtual void Tick(float a_Dt, cChunk & a_Chunk);
|
||||||
inline bool IsDestroyed(void) const { return m_bDestroyed; } // tolua_export
|
virtual void HandlePhysics(float a_Dt, cChunk & a_Chunk) {}
|
||||||
|
|
||||||
void Destroy(); // tolua_export
|
|
||||||
void RemoveFromChunk(void); // for internal use in cChunk
|
|
||||||
|
|
||||||
virtual void Tick(float a_Dt, MTRand & a_TickRandom);
|
|
||||||
virtual void HandlePhysics(float a_Dt) {}
|
|
||||||
|
|
||||||
/** Descendants override this function to send a command to the specified client to spawn the entity on the client.
|
/** Descendants override this function to send a command to the specified client to spawn the entity on the client.
|
||||||
To spawn on all eligible clients, use cChunkMap::BroadcastSpawnEntity()
|
To spawn on all eligible clients, use cChunkMap::BroadcastSpawnEntity()
|
||||||
@ -215,22 +213,19 @@ protected:
|
|||||||
cReferenceManager* m_Referencers;
|
cReferenceManager* m_Referencers;
|
||||||
cReferenceManager* m_References;
|
cReferenceManager* m_References;
|
||||||
|
|
||||||
int m_ChunkX, m_ChunkY, m_ChunkZ;
|
// Flags that signal that we haven't updated the clients with the latest.
|
||||||
|
|
||||||
//Flags that signal that we haven't updated the clients with the latest.
|
|
||||||
bool m_bDirtyHead;
|
bool m_bDirtyHead;
|
||||||
bool m_bDirtyOrientation;
|
bool m_bDirtyOrientation;
|
||||||
bool m_bDirtyPosition;
|
bool m_bDirtyPosition;
|
||||||
bool m_bDirtySpeed;
|
bool m_bDirtySpeed;
|
||||||
|
|
||||||
//Last Position.
|
// Last Position.
|
||||||
double m_LastPosX, m_LastPosY, m_LastPosZ;
|
double m_LastPosX, m_LastPosY, m_LastPosZ;
|
||||||
|
|
||||||
//This variables keep track of the last time a packet was sent
|
// This variables keep track of the last time a packet was sent
|
||||||
Int64 m_TimeLastTeleportPacket,m_TimeLastMoveReltPacket,m_TimeLastSpeedPacket; // In ticks
|
Int64 m_TimeLastTeleportPacket,m_TimeLastMoveReltPacket,m_TimeLastSpeedPacket; // In ticks
|
||||||
|
|
||||||
bool m_bDestroyed;
|
bool m_IsInitialized; // Is set to true when it's initialized, until it's destroyed (Initialize() till Destroy() )
|
||||||
bool m_bRemovedFromChunk;
|
|
||||||
|
|
||||||
eEntityType m_EntityType;
|
eEntityType m_EntityType;
|
||||||
|
|
||||||
@ -242,7 +237,6 @@ protected:
|
|||||||
virtual void Destroyed(void) {} // Called after the entity has been destroyed
|
virtual void Destroyed(void) {} // Called after the entity has been destroyed
|
||||||
|
|
||||||
void SetWorld(cWorld * a_World) { m_World = a_World; }
|
void SetWorld(cWorld * a_World) { m_World = a_World; }
|
||||||
void MoveToCorrectChunk(bool a_bIgnoreOldChunk = false);
|
|
||||||
|
|
||||||
friend class cReferenceManager;
|
friend class cReferenceManager;
|
||||||
void AddReference( cEntity*& a_EntityPtr );
|
void AddReference( cEntity*& a_EntityPtr );
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "World.h"
|
#include "World.h"
|
||||||
#include "ClientHandle.h"
|
#include "ClientHandle.h"
|
||||||
#include "Simulator/SandSimulator.h"
|
#include "Simulator/SandSimulator.h"
|
||||||
|
#include "Chunk.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -40,7 +41,7 @@ void cFallingBlock::SpawnOn(cClientHandle & a_ClientHandle)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cFallingBlock::Tick(float a_Dt, MTRand & a_TickRandom)
|
void cFallingBlock::Tick(float a_Dt, cChunk & a_Chunk)
|
||||||
{
|
{
|
||||||
float MilliDt = a_Dt * 0.001f;
|
float MilliDt = a_Dt * 0.001f;
|
||||||
AddSpeedY(MilliDt * -9.8f);
|
AddSpeedY(MilliDt * -9.8f);
|
||||||
@ -62,26 +63,29 @@ void cFallingBlock::Tick(float a_Dt, MTRand & a_TickRandom)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BlockY < cChunkDef::Height - 1)
|
if (BlockY >= cChunkDef::Height)
|
||||||
{
|
{
|
||||||
BLOCKTYPE BlockBelow;
|
// Above the world, just wait for it to fall back down
|
||||||
NIBBLETYPE BelowMeta;
|
return;
|
||||||
GetWorld()->GetBlockTypeMeta(BlockX, BlockY, BlockZ, BlockBelow, BelowMeta);
|
}
|
||||||
if (cSandSimulator::DoesBreakFallingThrough(BlockBelow, BelowMeta))
|
|
||||||
{
|
int idx = a_Chunk.MakeIndexNoCheck(BlockX - a_Chunk.GetPosX() * cChunkDef::Width, BlockY, BlockZ - a_Chunk.GetPosZ() * cChunkDef::Width);
|
||||||
// Fallen onto a block that breaks this into pickups (e. g. half-slab)
|
BLOCKTYPE BlockBelow = a_Chunk.GetBlock(idx);
|
||||||
// Must finish the fall with coords one below the block:
|
NIBBLETYPE BelowMeta = a_Chunk.GetMeta(idx);
|
||||||
cSandSimulator::FinishFalling(m_World, BlockX, BlockY, BlockZ, m_BlockType, m_BlockMeta);
|
if (cSandSimulator::DoesBreakFallingThrough(BlockBelow, BelowMeta))
|
||||||
Destroy();
|
{
|
||||||
return;
|
// Fallen onto a block that breaks this into pickups (e. g. half-slab)
|
||||||
}
|
// Must finish the fall with coords one below the block:
|
||||||
else if (!cSandSimulator::CanContinueFallThrough(BlockBelow))
|
cSandSimulator::FinishFalling(m_World, BlockX, BlockY, BlockZ, m_BlockType, m_BlockMeta);
|
||||||
{
|
Destroy();
|
||||||
// Fallen onto a solid block
|
return;
|
||||||
cSandSimulator::FinishFalling(m_World, BlockX, BlockY + 1, BlockZ, m_BlockType, m_BlockMeta);
|
}
|
||||||
Destroy();
|
else if (!cSandSimulator::CanContinueFallThrough(BlockBelow))
|
||||||
return;
|
{
|
||||||
}
|
// Fallen onto a solid block
|
||||||
|
cSandSimulator::FinishFalling(m_World, BlockX, BlockY + 1, BlockZ, m_BlockType, m_BlockMeta);
|
||||||
|
Destroy();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ public:
|
|||||||
// cEntity overrides:
|
// cEntity overrides:
|
||||||
virtual void Initialize(cWorld * a_World) override;
|
virtual void Initialize(cWorld * a_World) override;
|
||||||
virtual void SpawnOn(cClientHandle & a_ClientHandle) override;
|
virtual void SpawnOn(cClientHandle & a_ClientHandle) override;
|
||||||
virtual void Tick(float a_Dt, MTRand & a_TickRandom) override;
|
virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BLOCKTYPE m_BlockType;
|
BLOCKTYPE m_BlockType;
|
||||||
|
@ -238,16 +238,16 @@ void cChunkGenerator::Execute(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Hack for regenerating chunks: if Y != 0, the chunk is considered invalid, even if it has its data set
|
// Hack for regenerating chunks: if Y != 0, the chunk is considered invalid, even if it has its data set
|
||||||
if ((coords.m_ChunkY == 0) && m_World->IsChunkValid(coords.m_ChunkX, coords.m_ChunkY, coords.m_ChunkZ))
|
if ((coords.m_ChunkY == 0) && m_World->IsChunkValid(coords.m_ChunkX, coords.m_ChunkZ))
|
||||||
{
|
{
|
||||||
LOGD("Chunk [%d, %d] already generated, skipping generation", coords.m_ChunkX, coords.m_ChunkZ);
|
LOGD("Chunk [%d, %d] already generated, skipping generation", coords.m_ChunkX, coords.m_ChunkZ);
|
||||||
// Already generated, ignore request
|
// Already generated, ignore request
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SkipEnabled && !m_World->HasChunkAnyClients(coords.m_ChunkX, coords.m_ChunkY, coords.m_ChunkZ))
|
if (SkipEnabled && !m_World->HasChunkAnyClients(coords.m_ChunkX, coords.m_ChunkZ))
|
||||||
{
|
{
|
||||||
LOGWARNING("Chunk generator overloaded, skipping chunk [%d, %d, %d]", coords.m_ChunkX, coords.m_ChunkY, coords.m_ChunkZ);
|
LOGWARNING("Chunk generator overloaded, skipping chunk [%d, %d]", coords.m_ChunkX, coords.m_ChunkZ);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,7 +275,7 @@ void cChunkGenerator::DoGenerate(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
|||||||
ChunkDesc.CompressBlockMetas(BlockMetas);
|
ChunkDesc.CompressBlockMetas(BlockMetas);
|
||||||
|
|
||||||
m_World->SetChunkData(
|
m_World->SetChunkData(
|
||||||
a_ChunkX, a_ChunkY, a_ChunkZ,
|
a_ChunkX, a_ChunkZ,
|
||||||
ChunkDesc.GetBlockTypes(), BlockMetas,
|
ChunkDesc.GetBlockTypes(), BlockMetas,
|
||||||
NULL, NULL, // We don't have lighting, chunk will be lighted when needed
|
NULL, NULL, // We don't have lighting, chunk will be lighted when needed
|
||||||
&ChunkDesc.GetHeightMap(), &ChunkDesc.GetBiomeMap(),
|
&ChunkDesc.GetHeightMap(), &ChunkDesc.GetBiomeMap(),
|
||||||
|
@ -338,7 +338,7 @@ bool cLightingThread::ReadChunks(int a_ChunkX, int a_ChunkZ)
|
|||||||
for (int x = 0; x < 3; x++)
|
for (int x = 0; x < 3; x++)
|
||||||
{
|
{
|
||||||
Reader.m_ReadingChunkX = x;
|
Reader.m_ReadingChunkX = x;
|
||||||
if (!m_World->GetChunkData(a_ChunkX + x - 1, ZERO_CHUNK_Y, a_ChunkZ + z - 1, Reader))
|
if (!m_World->GetChunkData(a_ChunkX + x - 1, a_ChunkZ + z - 1, Reader))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ void cMinecart::SpawnOn(cClientHandle & a_ClientHandle)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cMinecart::Tick(float a_Dt, MTRand & a_TickRandom)
|
void cMinecart::Tick(float a_Dt, cChunk & a_Chunk)
|
||||||
{
|
{
|
||||||
// TODO: the physics
|
// TODO: the physics
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ public:
|
|||||||
// cEntity overrides:
|
// cEntity overrides:
|
||||||
virtual void Initialize(cWorld * a_World) override;
|
virtual void Initialize(cWorld * a_World) override;
|
||||||
virtual void SpawnOn(cClientHandle & a_ClientHandle) override;
|
virtual void SpawnOn(cClientHandle & a_ClientHandle) override;
|
||||||
virtual void Tick(float a_Dt, MTRand & a_TickRandom) override;
|
virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
|
||||||
|
|
||||||
ePayload GetPayload(void) const { return m_Payload; }
|
ePayload GetPayload(void) const { return m_Payload; }
|
||||||
|
|
||||||
|
@ -23,9 +23,9 @@ cAggressiveMonster::cAggressiveMonster(const AString & a_ConfigName, char a_Prot
|
|||||||
|
|
||||||
|
|
||||||
// What to do if in Chasing State
|
// What to do if in Chasing State
|
||||||
void cAggressiveMonster::InStateChasing(float a_Dt, MTRand & a_TickRandom)
|
void cAggressiveMonster::InStateChasing(float a_Dt)
|
||||||
{
|
{
|
||||||
super::InStateChasing(a_Dt, a_TickRandom);
|
super::InStateChasing(a_Dt);
|
||||||
m_ChaseTime += a_Dt;
|
m_ChaseTime += a_Dt;
|
||||||
if (m_Target != NULL)
|
if (m_Target != NULL)
|
||||||
{
|
{
|
||||||
@ -58,9 +58,9 @@ void cAggressiveMonster::InStateChasing(float a_Dt, MTRand & a_TickRandom)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cAggressiveMonster::EventSeePlayer(cEntity * a_Entity, MTRand & a_TickRandom)
|
void cAggressiveMonster::EventSeePlayer(cEntity * a_Entity)
|
||||||
{
|
{
|
||||||
super::EventSeePlayer(a_Entity, a_TickRandom);
|
super::EventSeePlayer(a_Entity);
|
||||||
m_EMState = CHASING;
|
m_EMState = CHASING;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,26 +68,26 @@ void cAggressiveMonster::EventSeePlayer(cEntity * a_Entity, MTRand & a_TickRando
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cAggressiveMonster::Tick(float a_Dt, MTRand & a_TickRandom)
|
void cAggressiveMonster::Tick(float a_Dt, cChunk & a_Chunk)
|
||||||
{
|
{
|
||||||
super::Tick(a_Dt, a_TickRandom);
|
super::Tick(a_Dt, a_Chunk);
|
||||||
|
|
||||||
m_SeePlayerInterval += a_Dt;
|
m_SeePlayerInterval += a_Dt;
|
||||||
|
|
||||||
if (m_SeePlayerInterval > 1)
|
if (m_SeePlayerInterval > 1)
|
||||||
{
|
{
|
||||||
int rem = a_TickRandom.randInt() % 3 + 1; // Check most of the time but miss occasionally
|
int rem = m_World->GetTickRandomNumber(3) + 1; // Check most of the time but miss occasionally
|
||||||
|
|
||||||
m_SeePlayerInterval = 0.0;
|
m_SeePlayerInterval = 0.0;
|
||||||
if (rem >= 2)
|
if (rem >= 2)
|
||||||
{
|
{
|
||||||
if (m_EMState == CHASING)
|
if (m_EMState == CHASING)
|
||||||
{
|
{
|
||||||
CheckEventLostPlayer(a_TickRandom);
|
CheckEventLostPlayer();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CheckEventSeePlayer(a_TickRandom);
|
CheckEventSeePlayer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,10 +15,10 @@ class cAggressiveMonster :
|
|||||||
public:
|
public:
|
||||||
cAggressiveMonster(const AString & a_ConfigName, char a_ProtocolMobType, const AString & a_SoundHurt, const AString & a_SoundDeath);
|
cAggressiveMonster(const AString & a_ConfigName, char a_ProtocolMobType, const AString & a_SoundHurt, const AString & a_SoundDeath);
|
||||||
|
|
||||||
virtual void Tick (float a_Dt, MTRand & a_TickRandom) override;
|
virtual void Tick (float a_Dt, cChunk & a_Chunk) override;
|
||||||
virtual void InStateChasing(float a_Dt, MTRand & a_TickRandom) override;
|
virtual void InStateChasing(float a_Dt) override;
|
||||||
|
|
||||||
virtual void EventSeePlayer(cEntity *, MTRand & a_TickRandom) override;
|
virtual void EventSeePlayer(cEntity *) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
float m_ChaseTime;
|
float m_ChaseTime;
|
||||||
|
@ -16,11 +16,11 @@ cCavespider::cCavespider(void) :
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cCavespider::Tick(float a_Dt, MTRand & a_TickRandom)
|
void cCavespider::Tick(float a_Dt, cChunk & a_Chunk)
|
||||||
{
|
{
|
||||||
super::Tick(a_Dt, a_TickRandom);
|
super::Tick(a_Dt, a_Chunk);
|
||||||
|
|
||||||
// TODO: Check vanilla if cavespiders really get passive during the day
|
// TODO: Check vanilla if cavespiders really get passive during the day / in daylight
|
||||||
m_EMPersonality = (GetWorld()->GetTimeOfDay() < (12000 + 1000)) ? PASSIVE : AGGRESSIVE;
|
m_EMPersonality = (GetWorld()->GetTimeOfDay() < (12000 + 1000)) ? PASSIVE : AGGRESSIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ public:
|
|||||||
|
|
||||||
CLASS_PROTODEF(cCaveSpider);
|
CLASS_PROTODEF(cCaveSpider);
|
||||||
|
|
||||||
virtual void Tick(float a_Dt, MTRand & a_TickRandom) override;
|
virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
|
||||||
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
|
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
@ -16,21 +16,6 @@ cEnderman::cEnderman(void) :
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cEnderman::Tick(float a_Dt, MTRand & a_TickRandom)
|
|
||||||
{
|
|
||||||
cMonster::Tick(a_Dt, a_TickRandom);
|
|
||||||
|
|
||||||
// TODO Same as stated in cSkeleton
|
|
||||||
if ((GetWorld()->GetTimeOfDay() < (12000 + 1000)) && (GetMetaData() != BURNING))
|
|
||||||
{
|
|
||||||
SetMetaData(BURNING); // BURN, BABY, BURN! >:D
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cEnderman::GetDrops(cItems & a_Drops, cPawn * a_Killer)
|
void cEnderman::GetDrops(cItems & a_Drops, cPawn * a_Killer)
|
||||||
{
|
{
|
||||||
AddRandomDropItem(a_Drops, 0, 1, E_ITEM_ENDER_PEARL);
|
AddRandomDropItem(a_Drops, 0, 1, E_ITEM_ENDER_PEARL);
|
||||||
|
@ -17,7 +17,6 @@ public:
|
|||||||
|
|
||||||
CLASS_PROTODEF(cEnderman);
|
CLASS_PROTODEF(cEnderman);
|
||||||
|
|
||||||
virtual void Tick(float a_Dt, MTRand & a_TickRandom) override;
|
|
||||||
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
|
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
@ -87,9 +87,9 @@ bool cMonster::ReachedDestination()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cMonster::Tick(float a_Dt, MTRand & a_TickRandom)
|
void cMonster::Tick(float a_Dt, cChunk & a_Chunk)
|
||||||
{
|
{
|
||||||
super::Tick(a_Dt, a_TickRandom);
|
super::Tick(a_Dt, a_Chunk);
|
||||||
|
|
||||||
if (m_Health <= 0)
|
if (m_Health <= 0)
|
||||||
{
|
{
|
||||||
@ -145,7 +145,6 @@ void cMonster::Tick(float a_Dt, MTRand & a_TickRandom)
|
|||||||
|
|
||||||
HandlePhysics(a_Dt);
|
HandlePhysics(a_Dt);
|
||||||
BroadcastMovementUpdate();
|
BroadcastMovementUpdate();
|
||||||
MoveToCorrectChunk();
|
|
||||||
|
|
||||||
Vector3d Distance = m_Destination - GetPosition();
|
Vector3d Distance = m_Destination - GetPosition();
|
||||||
if (Distance.SqrLength() > 0.1f)
|
if (Distance.SqrLength() > 0.1f)
|
||||||
@ -163,20 +162,20 @@ void cMonster::Tick(float a_Dt, MTRand & a_TickRandom)
|
|||||||
case IDLE:
|
case IDLE:
|
||||||
{
|
{
|
||||||
// If enemy passive we ignore checks for player visibility
|
// If enemy passive we ignore checks for player visibility
|
||||||
InStateIdle(a_Dt, a_TickRandom);
|
InStateIdle(a_Dt);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case CHASING:
|
case CHASING:
|
||||||
{
|
{
|
||||||
// If we do not see a player anymore skip chasing action
|
// If we do not see a player anymore skip chasing action
|
||||||
InStateChasing(a_Dt, a_TickRandom);
|
InStateChasing(a_Dt);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ESCAPING:
|
case ESCAPING:
|
||||||
{
|
{
|
||||||
InStateEscaping(a_Dt, a_TickRandom);
|
InStateEscaping(a_Dt);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} // switch (m_EMState)
|
} // switch (m_EMState)
|
||||||
@ -227,8 +226,6 @@ void cMonster::ReplicateMovement()
|
|||||||
m_LastPosZ = GetPosZ();
|
m_LastPosZ = GetPosZ();
|
||||||
m_bDirtyPosition = false;
|
m_bDirtyPosition = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
MoveToCorrectChunk();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -374,14 +371,14 @@ void cMonster::SetState(const AString & a_State)
|
|||||||
|
|
||||||
//Checks to see if EventSeePlayer should be fired
|
//Checks to see if EventSeePlayer should be fired
|
||||||
//monster sez: Do I see the player
|
//monster sez: Do I see the player
|
||||||
void cMonster::CheckEventSeePlayer(MTRand & a_TickRandom)
|
void cMonster::CheckEventSeePlayer(void)
|
||||||
{
|
{
|
||||||
// TODO: Rewrite this to use cWorld's DoWithPlayers()
|
// TODO: Rewrite this to use cWorld's DoWithPlayers()
|
||||||
cPlayer * Closest = FindClosestPlayer();
|
cPlayer * Closest = FindClosestPlayer();
|
||||||
|
|
||||||
if (Closest != NULL)
|
if (Closest != NULL)
|
||||||
{
|
{
|
||||||
EventSeePlayer(Closest, a_TickRandom);
|
EventSeePlayer(Closest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -389,10 +386,8 @@ void cMonster::CheckEventSeePlayer(MTRand & a_TickRandom)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cMonster::CheckEventLostPlayer(MTRand & a_TickRandom)
|
void cMonster::CheckEventLostPlayer(void)
|
||||||
{
|
{
|
||||||
UNUSED(a_TickRandom);
|
|
||||||
|
|
||||||
Vector3f pos;
|
Vector3f pos;
|
||||||
cTracer LineOfSight(GetWorld());
|
cTracer LineOfSight(GetWorld());
|
||||||
|
|
||||||
@ -416,12 +411,10 @@ void cMonster::CheckEventLostPlayer(MTRand & a_TickRandom)
|
|||||||
|
|
||||||
// What to do if player is seen
|
// What to do if player is seen
|
||||||
// default to change state to chasing
|
// default to change state to chasing
|
||||||
void cMonster::EventSeePlayer(cEntity * a_SeenPlayer, MTRand & a_TickRandom)
|
void cMonster::EventSeePlayer(cEntity * a_SeenPlayer)
|
||||||
{
|
{
|
||||||
UNUSED(a_TickRandom);
|
|
||||||
|
|
||||||
m_Target = a_SeenPlayer;
|
m_Target = a_SeenPlayer;
|
||||||
AddReference( m_Target );
|
AddReference(m_Target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -431,7 +424,7 @@ void cMonster::EventSeePlayer(cEntity * a_SeenPlayer, MTRand & a_TickRandom)
|
|||||||
void cMonster::EventLosePlayer(void)
|
void cMonster::EventLosePlayer(void)
|
||||||
{
|
{
|
||||||
Dereference(m_Target);
|
Dereference(m_Target);
|
||||||
m_Target = 0;
|
m_Target = NULL;
|
||||||
m_EMState = IDLE;
|
m_EMState = IDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -440,24 +433,28 @@ void cMonster::EventLosePlayer(void)
|
|||||||
|
|
||||||
|
|
||||||
// What to do if in Idle State
|
// What to do if in Idle State
|
||||||
void cMonster::InStateIdle(float a_Dt, MTRand & a_TickRandom)
|
void cMonster::InStateIdle(float a_Dt)
|
||||||
{
|
{
|
||||||
idle_interval += a_Dt;
|
idle_interval += a_Dt;
|
||||||
if (idle_interval > 1)
|
if (idle_interval > 1)
|
||||||
{
|
{
|
||||||
// at this interval the results are predictable
|
// at this interval the results are predictable
|
||||||
int rem = (a_TickRandom.randInt() % 6) + 1;
|
int rem = m_World->GetTickRandomNumber(6) + 1;
|
||||||
// LOGD("Moving: int: %3.3f rem: %i",idle_interval,rem);
|
// LOGD("Moving: int: %3.3f rem: %i",idle_interval,rem);
|
||||||
idle_interval -= 1; // So nothing gets dropped when the server hangs for a few seconds
|
idle_interval -= 1; // So nothing gets dropped when the server hangs for a few seconds
|
||||||
Vector3f Dist;
|
Vector3f Dist;
|
||||||
Dist.x = (float)((a_TickRandom.randInt() % 11) - 5);
|
Dist.x = (float)(m_World->GetTickRandomNumber(10) - 5);
|
||||||
Dist.z = (float)((a_TickRandom.randInt() % 11) - 5);
|
Dist.z = (float)(m_World->GetTickRandomNumber(10) - 5);
|
||||||
if ((Dist.SqrLength() > 2) && (rem >= 3))
|
if ((Dist.SqrLength() > 2) && (rem >= 3))
|
||||||
{
|
{
|
||||||
m_Destination.x = (float)(GetPosX() + Dist.x);
|
m_Destination.x = (float)(GetPosX() + Dist.x);
|
||||||
m_Destination.z = (float)(GetPosZ() + Dist.z);
|
m_Destination.z = (float)(GetPosZ() + Dist.z);
|
||||||
m_Destination.y = (float)GetWorld()->GetHeight((int)m_Destination.x, (int)m_Destination.z) + 1.2f;
|
int PosY;
|
||||||
MoveToPosition(m_Destination);
|
if (m_World->TryGetHeight((int)m_Destination.x, (int)m_Destination.z, PosY))
|
||||||
|
{
|
||||||
|
m_Destination.y = (float)PosY + 1.2f;
|
||||||
|
MoveToPosition(m_Destination);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -468,10 +465,9 @@ void cMonster::InStateIdle(float a_Dt, MTRand & a_TickRandom)
|
|||||||
|
|
||||||
// What to do if in Chasing State
|
// What to do if in Chasing State
|
||||||
// This state should always be defined in each child class
|
// This state should always be defined in each child class
|
||||||
void cMonster::InStateChasing(float a_Dt, MTRand & a_TickRandom)
|
void cMonster::InStateChasing(float a_Dt)
|
||||||
{
|
{
|
||||||
UNUSED(a_Dt);
|
UNUSED(a_Dt);
|
||||||
UNUSED(a_TickRandom);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -479,10 +475,9 @@ void cMonster::InStateChasing(float a_Dt, MTRand & a_TickRandom)
|
|||||||
|
|
||||||
|
|
||||||
// What to do if in Escaping State
|
// What to do if in Escaping State
|
||||||
void cMonster::InStateEscaping(float a_Dt, MTRand & a_TickRandom)
|
void cMonster::InStateEscaping(float a_Dt)
|
||||||
{
|
{
|
||||||
UNUSED(a_Dt);
|
UNUSED(a_Dt);
|
||||||
UNUSED(a_TickRandom);
|
|
||||||
|
|
||||||
if (m_Target != NULL)
|
if (m_Target != NULL)
|
||||||
{
|
{
|
||||||
|
@ -24,6 +24,7 @@ class cMonster :
|
|||||||
typedef cPawn super;
|
typedef cPawn super;
|
||||||
public:
|
public:
|
||||||
// tolua_end
|
// tolua_end
|
||||||
|
float m_SightDistance;
|
||||||
|
|
||||||
/** Creates the mob object.
|
/** Creates the mob object.
|
||||||
* If a_ConfigName is not empty, the configuration is loaded using GetMonsterConfig()
|
* If a_ConfigName is not empty, the configuration is loaded using GetMonsterConfig()
|
||||||
@ -36,7 +37,7 @@ public:
|
|||||||
|
|
||||||
virtual void SpawnOn(cClientHandle & a_ClientHandle) override;
|
virtual void SpawnOn(cClientHandle & a_ClientHandle) override;
|
||||||
|
|
||||||
virtual void Tick(float a_Dt, MTRand & a_TickRandom) override;
|
virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
|
||||||
|
|
||||||
virtual void HandlePhysics(float a_Dt);
|
virtual void HandlePhysics(float a_Dt);
|
||||||
virtual void ReplicateMovement(void);
|
virtual void ReplicateMovement(void);
|
||||||
@ -53,20 +54,19 @@ public:
|
|||||||
const char * GetState();
|
const char * GetState();
|
||||||
void SetState(const AString & str);
|
void SetState(const AString & str);
|
||||||
|
|
||||||
virtual void CheckEventSeePlayer(MTRand & a_TickRandom);
|
virtual void CheckEventSeePlayer(void);
|
||||||
virtual void EventSeePlayer(cEntity *, MTRand & a_TickRandom);
|
virtual void EventSeePlayer(cEntity * a_Player);
|
||||||
float m_SightDistance;
|
|
||||||
virtual cPlayer * FindClosestPlayer(); // non static is easier. also virtual so other mobs can implement their own searching algo
|
virtual cPlayer * FindClosestPlayer(); // non static is easier. also virtual so other mobs can implement their own searching algo
|
||||||
|
|
||||||
/// Reads the monster configuration for the specified monster name and assigns it to this object.
|
/// Reads the monster configuration for the specified monster name and assigns it to this object.
|
||||||
void GetMonsterConfig(const AString & a_Name);
|
void GetMonsterConfig(const AString & a_Name);
|
||||||
|
|
||||||
virtual void EventLosePlayer(void);
|
virtual void EventLosePlayer(void);
|
||||||
virtual void CheckEventLostPlayer(MTRand & a_TickRandom);
|
virtual void CheckEventLostPlayer(void);
|
||||||
|
|
||||||
virtual void InStateIdle (float a_Dt, MTRand & a_TickRandom);
|
virtual void InStateIdle (float a_Dt);
|
||||||
virtual void InStateChasing (float a_Dt, MTRand & a_TickRandom);
|
virtual void InStateChasing (float a_Dt);
|
||||||
virtual void InStateEscaping(float a_Dt, MTRand & a_TickRandom);
|
virtual void InStateEscaping(float a_Dt);
|
||||||
|
|
||||||
virtual void Attack(float a_Dt);
|
virtual void Attack(float a_Dt);
|
||||||
int GetMobType() {return m_MobType;}
|
int GetMobType() {return m_MobType;}
|
||||||
|
@ -31,22 +31,22 @@ void cPassiveMonster::DoTakeDamage(TakeDamageInfo & a_TDI)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cPassiveMonster::Tick(float a_Dt, MTRand & a_TickRandom)
|
void cPassiveMonster::Tick(float a_Dt, cChunk & a_Chunk)
|
||||||
{
|
{
|
||||||
super::Tick(a_Dt, a_TickRandom);
|
super::Tick(a_Dt, a_Chunk);
|
||||||
|
|
||||||
m_SeePlayerInterval += a_Dt;
|
m_SeePlayerInterval += a_Dt;
|
||||||
|
|
||||||
if (m_SeePlayerInterval > 1) // Check every second
|
if (m_SeePlayerInterval > 1) // Check every second
|
||||||
{
|
{
|
||||||
int rem = a_TickRandom.randInt() % 3 + 1; // Check most of the time but miss occasionally
|
int rem = m_World->GetTickRandomNumber(3) + 1; // Check most of the time but miss occasionally
|
||||||
|
|
||||||
m_SeePlayerInterval = 0.0;
|
m_SeePlayerInterval = 0.0;
|
||||||
if (rem >= 2)
|
if (rem >= 2)
|
||||||
{
|
{
|
||||||
if (m_EMState == ESCAPING)
|
if (m_EMState == ESCAPING)
|
||||||
{
|
{
|
||||||
CheckEventLostPlayer(a_TickRandom);
|
CheckEventLostPlayer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ class cPassiveMonster :
|
|||||||
public:
|
public:
|
||||||
cPassiveMonster(const AString & a_ConfigName, char a_ProtocolMobType, const AString & a_SoundHurt, const AString & a_SoundDeath);
|
cPassiveMonster(const AString & a_ConfigName, char a_ProtocolMobType, const AString & a_SoundHurt, const AString & a_SoundDeath);
|
||||||
|
|
||||||
virtual void Tick(float a_Dt, MTRand & a_TickRandom) override;
|
virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
|
||||||
|
|
||||||
/// When hit by someone, run away
|
/// When hit by someone, run away
|
||||||
virtual void DoTakeDamage(TakeDamageInfo & a_TDI) override;
|
virtual void DoTakeDamage(TakeDamageInfo & a_TDI) override;
|
||||||
|
@ -16,13 +16,13 @@ cSkeleton::cSkeleton(void) :
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cSkeleton::Tick(float a_Dt, MTRand & a_TickRandom)
|
void cSkeleton::Tick(float a_Dt, cChunk & a_Chunk)
|
||||||
{
|
{
|
||||||
cMonster::Tick(a_Dt, a_TickRandom);
|
cMonster::Tick(a_Dt, a_Chunk);
|
||||||
|
|
||||||
// TODO Outsource
|
// TODO Outsource
|
||||||
// TODO should do SkyLight check, mobs in the dark don´t burn
|
// TODO should do SkyLight check, mobs in the dark don´t burn
|
||||||
if ((GetWorld()->GetTimeOfDay() < (12000 + 1000)) && (GetMetaData() != BURNING))
|
if ((GetWorld()->GetTimeOfDay() < (12000 + 1000)) && !IsBurning())
|
||||||
{
|
{
|
||||||
SetMetaData(BURNING); // BURN, BABY, BURN! >:D
|
SetMetaData(BURNING); // BURN, BABY, BURN! >:D
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ public:
|
|||||||
|
|
||||||
CLASS_PROTODEF(cSkeleton);
|
CLASS_PROTODEF(cSkeleton);
|
||||||
|
|
||||||
virtual void Tick(float a_Dt, MTRand & a_TickRandom) override;
|
virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
|
||||||
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
|
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
@ -27,14 +27,15 @@ void cSquid::GetDrops(cItems & a_Drops, cPawn * a_Killer)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cSquid::Tick(float a_Dt, MTRand & a_TickRandom)
|
void cSquid::Tick(float a_Dt, cChunk & a_Chunk)
|
||||||
{
|
{
|
||||||
super::Tick(a_Dt, a_TickRandom);
|
// TODO: Rewrite this function to use a_Chunk instead of m_World
|
||||||
|
super::Tick(a_Dt, a_Chunk);
|
||||||
|
|
||||||
Vector3d Pos = GetPosition();
|
Vector3d Pos = GetPosition();
|
||||||
|
|
||||||
// TODO: Not a real behavior, but cool :D
|
// TODO: Not a real behavior, but cool :D
|
||||||
if (!IsBlockWater(GetWorld()->GetBlock((int) Pos.x, (int) Pos.y, (int) Pos.z)) && GetMetaData() != BURNING)
|
if (!IsBlockWater(GetWorld()->GetBlock((int) Pos.x, (int) Pos.y, (int) Pos.z)) && !IsBurning())
|
||||||
{
|
{
|
||||||
SetMetaData(BURNING);
|
SetMetaData(BURNING);
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ class cSquid :
|
|||||||
public:
|
public:
|
||||||
cSquid();
|
cSquid();
|
||||||
|
|
||||||
virtual void Tick(float a_Dt, MTRand & a_TickRandom) override;
|
virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
|
||||||
|
|
||||||
CLASS_PROTODEF(cSquid);
|
CLASS_PROTODEF(cSquid);
|
||||||
|
|
||||||
|
@ -16,12 +16,12 @@ cZombie::cZombie(void) :
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cZombie::Tick(float a_Dt, MTRand & a_TickRandom)
|
void cZombie::Tick(float a_Dt, cChunk & a_Chunk)
|
||||||
{
|
{
|
||||||
super::Tick(a_Dt, a_TickRandom);
|
super::Tick(a_Dt, a_Chunk);
|
||||||
|
|
||||||
// TODO Same as in cSkeleton :D
|
// TODO Same as in cSkeleton :D
|
||||||
if ((GetWorld()->GetTimeOfDay() < (12000 + 1000)) && (GetMetaData() != BURNING))
|
if ((GetWorld()->GetTimeOfDay() < (12000 + 1000)) && !IsBurning())
|
||||||
{
|
{
|
||||||
SetMetaData(BURNING); // BURN, BABY, BURN! >:D
|
SetMetaData(BURNING); // BURN, BABY, BURN! >:D
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ public:
|
|||||||
|
|
||||||
CLASS_PROTODEF(cZombie);
|
CLASS_PROTODEF(cZombie);
|
||||||
|
|
||||||
virtual void Tick(float a_Dt, MTRand & a_TickRandom) override;
|
virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
|
||||||
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
|
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
@ -16,12 +16,12 @@ cZombiepigman::cZombiepigman(void) :
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cZombiepigman::Tick(float a_Dt, MTRand & a_TickRandom)
|
void cZombiepigman::Tick(float a_Dt, cChunk & a_Chunk)
|
||||||
{
|
{
|
||||||
super::Tick(a_Dt, a_TickRandom);
|
super::Tick(a_Dt, a_Chunk);
|
||||||
|
|
||||||
// TODO Same as noticed in cSkeleton AND Do they really burn by sun?? :D In the neather is no sun :D
|
// TODO Same as noticed in cSkeleton AND Do they really burn by sun?? :D In the neather is no sun :D
|
||||||
if ((GetWorld()->GetTimeOfDay() < (12000 + 1000)) && (GetMetaData() != BURNING))
|
if ((GetWorld()->GetTimeOfDay() < (12000 + 1000)) && !IsBurning())
|
||||||
{
|
{
|
||||||
SetMetaData(BURNING); // BURN, BABY, BURN! >:D
|
SetMetaData(BURNING); // BURN, BABY, BURN! >:D
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ public:
|
|||||||
|
|
||||||
CLASS_PROTODEF(cZombiepigman);
|
CLASS_PROTODEF(cZombiepigman);
|
||||||
|
|
||||||
virtual void Tick(float a_Dt, MTRand & a_TickRandom) override;
|
virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
|
||||||
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
|
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
|
||||||
virtual void KilledBy(cPawn * a_Killer) override;
|
virtual void KilledBy(cPawn * a_Killer) override;
|
||||||
} ;
|
} ;
|
||||||
|
@ -288,11 +288,11 @@ void cPawn::TeleportTo(double a_PosX, double a_PosY, double a_PosZ)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cPawn::Tick(float a_Dt, MTRand & a_TickRandom)
|
void cPawn::Tick(float a_Dt, cChunk & a_Chunk)
|
||||||
{
|
{
|
||||||
CheckMetaDataBurn(); // Check to see if pawn should burn based on block they are on
|
CheckMetaDataBurn(a_Chunk); // Check to see if pawn should burn based on block they are on
|
||||||
|
|
||||||
if (GetMetaData() == BURNING)
|
if (IsBurning())
|
||||||
{
|
{
|
||||||
InStateBurning(a_Dt);
|
InStateBurning(a_Dt);
|
||||||
}
|
}
|
||||||
@ -315,8 +315,10 @@ void cPawn::SetMetaData(MetaData a_MetaData)
|
|||||||
|
|
||||||
|
|
||||||
//----Change Entity MetaData
|
//----Change Entity MetaData
|
||||||
void cPawn::CheckMetaDataBurn(void)
|
void cPawn::CheckMetaDataBurn(cChunk & a_Chunk)
|
||||||
{
|
{
|
||||||
|
// TODO: Rewrite this function to use a_Chunk instead of m_World
|
||||||
|
|
||||||
if ((GetPosY() < 1) || (GetPosY() >= 254))
|
if ((GetPosY() < 1) || (GetPosY() >= 254))
|
||||||
{
|
{
|
||||||
// Y coord out of range
|
// Y coord out of range
|
||||||
|
@ -83,7 +83,7 @@ public:
|
|||||||
|
|
||||||
cPawn(eEntityType a_EntityType);
|
cPawn(eEntityType a_EntityType);
|
||||||
|
|
||||||
virtual void Tick(float a_Dt, MTRand & a_TickRandom) override;
|
virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
|
||||||
|
|
||||||
// tolua_begin
|
// tolua_begin
|
||||||
|
|
||||||
@ -150,11 +150,13 @@ public:
|
|||||||
|
|
||||||
virtual void InStateBurning(float a_Dt);
|
virtual void InStateBurning(float a_Dt);
|
||||||
|
|
||||||
virtual void CheckMetaDataBurn(void);
|
virtual void CheckMetaDataBurn(cChunk & a_Chunk);
|
||||||
|
|
||||||
virtual void SetMaxHealth(short a_MaxHealth);
|
virtual void SetMaxHealth(short a_MaxHealth);
|
||||||
virtual short GetMaxHealth() { return m_MaxHealth; }
|
virtual short GetMaxHealth() { return m_MaxHealth; }
|
||||||
|
|
||||||
|
bool IsBurning(void) const { return (m_MetaData == BURNING); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
short m_Health;
|
short m_Health;
|
||||||
short m_MaxHealth;
|
short m_MaxHealth;
|
||||||
|
@ -59,9 +59,9 @@ void cPickup::SpawnOn(cClientHandle & a_Client)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cPickup::Tick(float a_Dt, MTRand & a_TickRandom)
|
void cPickup::Tick(float a_Dt, cChunk & a_Chunk)
|
||||||
{
|
{
|
||||||
super::Tick(a_Dt, a_TickRandom);
|
super::Tick(a_Dt, a_Chunk);
|
||||||
|
|
||||||
m_Timer += a_Dt;
|
m_Timer += a_Dt;
|
||||||
a_Dt = a_Dt / 1000.f;
|
a_Dt = a_Dt / 1000.f;
|
||||||
@ -88,7 +88,6 @@ void cPickup::Tick(float a_Dt, MTRand & a_TickRandom)
|
|||||||
|
|
||||||
if (!m_bReplicated || m_bDirtyPosition)
|
if (!m_bReplicated || m_bDirtyPosition)
|
||||||
{
|
{
|
||||||
MoveToCorrectChunk();
|
|
||||||
m_bReplicated = true;
|
m_bReplicated = true;
|
||||||
m_bDirtyPosition = false;
|
m_bDirtyPosition = false;
|
||||||
GetWorld()->BroadcastTeleportEntity(*this);
|
GetWorld()->BroadcastTeleportEntity(*this);
|
||||||
@ -99,8 +98,10 @@ void cPickup::Tick(float a_Dt, MTRand & a_TickRandom)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cPickup::HandlePhysics(float a_Dt)
|
void cPickup::HandlePhysics(float a_Dt, cChunk & a_Chunk)
|
||||||
{
|
{
|
||||||
|
// TODO: Rewrite this function to use a_Chunk instead of m_World
|
||||||
|
|
||||||
m_ResultingSpeed.Set(0.f, 0.f, 0.f);
|
m_ResultingSpeed.Set(0.f, 0.f, 0.f);
|
||||||
cWorld * World = GetWorld();
|
cWorld * World = GetWorld();
|
||||||
|
|
||||||
|
@ -35,8 +35,8 @@ public:
|
|||||||
|
|
||||||
virtual bool CollectedBy(cPlayer * a_Dest); // tolua_export
|
virtual bool CollectedBy(cPlayer * a_Dest); // tolua_export
|
||||||
|
|
||||||
virtual void Tick(float a_Dt, MTRand & a_TickRandom) override;
|
virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
|
||||||
virtual void HandlePhysics(float a_Dt) override;
|
virtual void HandlePhysics(float a_Dt, cChunk & a_Chunk) override;
|
||||||
|
|
||||||
short GetHealth(void) const { return m_Health; }
|
short GetHealth(void) const { return m_Health; }
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName)
|
|||||||
|
|
||||||
cPlayer::~cPlayer(void)
|
cPlayer::~cPlayer(void)
|
||||||
{
|
{
|
||||||
LOG("Deleting cPlayer \"%s\" at %p, ID %d; inv win %p", m_PlayerName.c_str(), this, GetUniqueID(), m_InventoryWindow);
|
LOG("Deleting cPlayer \"%s\" at %p, ID %d", m_PlayerName.c_str(), this, GetUniqueID());
|
||||||
|
|
||||||
SaveToDisk();
|
SaveToDisk();
|
||||||
|
|
||||||
@ -109,7 +109,7 @@ cPlayer::~cPlayer(void)
|
|||||||
|
|
||||||
delete m_InventoryWindow;
|
delete m_InventoryWindow;
|
||||||
|
|
||||||
LOG("Player %p deleted", this);
|
LOGD("Player %p deleted", this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -119,7 +119,7 @@ cPlayer::~cPlayer(void)
|
|||||||
void cPlayer::Initialize( cWorld* a_World )
|
void cPlayer::Initialize( cWorld* a_World )
|
||||||
{
|
{
|
||||||
cPawn::Initialize( a_World );
|
cPawn::Initialize( a_World );
|
||||||
GetWorld()->AddPlayer( this );
|
GetWorld()->AddPlayer(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -156,7 +156,7 @@ void cPlayer::SpawnOn(cClientHandle & a_Client)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cPlayer::Tick(float a_Dt, MTRand & a_TickRandom)
|
void cPlayer::Tick(float a_Dt, cChunk & a_Chunk)
|
||||||
{
|
{
|
||||||
if (!m_ClientHandle->IsPlaying())
|
if (!m_ClientHandle->IsPlaying())
|
||||||
{
|
{
|
||||||
@ -164,7 +164,7 @@ void cPlayer::Tick(float a_Dt, MTRand & a_TickRandom)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
super::Tick(a_Dt, a_TickRandom);
|
super::Tick(a_Dt, a_Chunk);
|
||||||
//TODO: Change this to use the BroadcastMovementUpdate function
|
//TODO: Change this to use the BroadcastMovementUpdate function
|
||||||
if (m_bDirtyOrientation && !m_bDirtyPosition)
|
if (m_bDirtyOrientation && !m_bDirtyPosition)
|
||||||
{
|
{
|
||||||
@ -853,12 +853,11 @@ bool cPlayer::MoveToWorld( const char* a_WorldName )
|
|||||||
/* Remove all links to the old world */
|
/* Remove all links to the old world */
|
||||||
m_World->RemovePlayer( this );
|
m_World->RemovePlayer( this );
|
||||||
m_ClientHandle->RemoveFromAllChunks();
|
m_ClientHandle->RemoveFromAllChunks();
|
||||||
m_World->RemoveEntityFromChunk(this, m_ChunkX, m_ChunkY, m_ChunkZ);
|
m_World->RemoveEntityFromChunk(this, GetChunkX(), GetChunkZ());
|
||||||
|
|
||||||
/* Add player to all the necessary parts of the new world */
|
/* Add player to all the necessary parts of the new world */
|
||||||
SetWorld( World );
|
SetWorld( World );
|
||||||
GetWorld()->AddPlayer( this );
|
GetWorld()->AddPlayer(this);
|
||||||
MoveToCorrectChunk(true);
|
|
||||||
GetClientHandle()->StreamChunks();
|
GetClientHandle()->StreamChunks();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -35,11 +35,11 @@ public:
|
|||||||
cPlayer(cClientHandle * a_Client, const AString & a_PlayerName);
|
cPlayer(cClientHandle * a_Client, const AString & a_PlayerName);
|
||||||
virtual ~cPlayer();
|
virtual ~cPlayer();
|
||||||
|
|
||||||
virtual void Initialize( cWorld* a_World ); // tolua_export
|
virtual void Initialize(cWorld * a_World); // tolua_export
|
||||||
|
|
||||||
virtual void SpawnOn(cClientHandle & a_Client) override;
|
virtual void SpawnOn(cClientHandle & a_Client) override;
|
||||||
|
|
||||||
virtual void Tick(float a_Dt, MTRand & a_TickRandom) override;
|
virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
|
||||||
|
|
||||||
/// Returns the curently equipped weapon; empty item if none
|
/// Returns the curently equipped weapon; empty item if none
|
||||||
virtual cItem GetEquippedWeapon(void) const override { return m_Inventory.GetEquippedItem(); }
|
virtual cItem GetEquippedWeapon(void) const override { return m_Inventory.GetEquippedItem(); }
|
||||||
|
@ -38,10 +38,10 @@ protected:
|
|||||||
unsigned m_BurnStepTimeNonfuel;
|
unsigned m_BurnStepTimeNonfuel;
|
||||||
|
|
||||||
/// Chance [0..100000] of an adjacent fuel to catch fire on each tick
|
/// Chance [0..100000] of an adjacent fuel to catch fire on each tick
|
||||||
unsigned m_Flammability;
|
int m_Flammability;
|
||||||
|
|
||||||
/// Chance [0..100000] of a fuel burning out being replaced by a new fire block instead of an air block
|
/// Chance [0..100000] of a fuel burning out being replaced by a new fire block instead of an air block
|
||||||
unsigned m_ReplaceFuelChance;
|
int m_ReplaceFuelChance;
|
||||||
|
|
||||||
|
|
||||||
virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) override;
|
virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) override;
|
||||||
|
157
source/World.cpp
157
source/World.cpp
@ -294,20 +294,6 @@ cWorld::cWorld(const AString & a_WorldName) :
|
|||||||
|
|
||||||
cWorld::~cWorld()
|
cWorld::~cWorld()
|
||||||
{
|
{
|
||||||
{
|
|
||||||
cCSLock Lock(m_CSEntities);
|
|
||||||
while (m_AllEntities.begin() != m_AllEntities.end())
|
|
||||||
{
|
|
||||||
cEntity* Entity = *m_AllEntities.begin();
|
|
||||||
m_AllEntities.remove(Entity);
|
|
||||||
if (!Entity->IsDestroyed())
|
|
||||||
{
|
|
||||||
Entity->Destroy();
|
|
||||||
}
|
|
||||||
delete Entity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delete m_SimulatorManager;
|
delete m_SimulatorManager;
|
||||||
delete m_SandSimulator;
|
delete m_SandSimulator;
|
||||||
delete m_WaterSimulator;
|
delete m_WaterSimulator;
|
||||||
@ -480,25 +466,7 @@ void cWorld::Tick(float a_Dt)
|
|||||||
m_LastTimeUpdate = m_WorldAge;
|
m_LastTimeUpdate = m_WorldAge;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove entities scheduled for removal:
|
m_ChunkMap->Tick(a_Dt);
|
||||||
{
|
|
||||||
cCSLock Lock(m_CSEntities);
|
|
||||||
for (cEntityList::iterator itr = m_AllEntities.begin(); itr != m_AllEntities.end();)
|
|
||||||
{
|
|
||||||
if ((*itr)->IsDestroyed())
|
|
||||||
{
|
|
||||||
LOGD("Destroying entity #%i", (*itr)->GetUniqueID());
|
|
||||||
cEntity * RemoveMe = *itr;
|
|
||||||
itr = m_AllEntities.erase(itr);
|
|
||||||
m_RemoveEntityQueue.push_back(RemoveMe);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
(*itr)->Tick(a_Dt, m_TickRand);
|
|
||||||
itr++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_ChunkMap->Tick(a_Dt, m_TickRand);
|
|
||||||
|
|
||||||
TickQueuedBlocks(a_Dt);
|
TickQueuedBlocks(a_Dt);
|
||||||
|
|
||||||
@ -530,13 +498,6 @@ void cWorld::Tick(float a_Dt)
|
|||||||
UnloadUnusedChunks();
|
UnloadUnusedChunks();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete entities queued for removal:
|
|
||||||
for (cEntityList::iterator itr = m_RemoveEntityQueue.begin(); itr != m_RemoveEntityQueue.end(); ++itr)
|
|
||||||
{
|
|
||||||
delete *itr;
|
|
||||||
}
|
|
||||||
m_RemoveEntityQueue.clear();
|
|
||||||
|
|
||||||
TickSpawnMobs(a_Dt);
|
TickSpawnMobs(a_Dt);
|
||||||
|
|
||||||
std::vector<int> m_RSList_copy(m_RSList);
|
std::vector<int> m_RSList_copy(m_RSList);
|
||||||
@ -1290,6 +1251,15 @@ int cWorld::GetHeight(int a_X, int a_Z)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cWorld::TryGetHeight(int a_BlockX, int a_BlockZ, int & a_Height)
|
||||||
|
{
|
||||||
|
return m_ChunkMap->TryGetHeight(a_BlockX, a_BlockZ, a_Height);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cWorld::BroadcastAttachEntity(const cEntity & a_Entity, const cEntity * a_Vehicle)
|
void cWorld::BroadcastAttachEntity(const cEntity & a_Entity, const cEntity * a_Vehicle)
|
||||||
{
|
{
|
||||||
return m_ChunkMap->BroadcastAttachEntity(a_Entity, a_Vehicle);
|
return m_ChunkMap->BroadcastAttachEntity(a_Entity, a_Vehicle);
|
||||||
@ -1577,27 +1547,27 @@ void cWorld::SendBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cClientHa
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cWorld::MarkChunkDirty (int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
void cWorld::MarkChunkDirty (int a_ChunkX, int a_ChunkZ)
|
||||||
{
|
{
|
||||||
m_ChunkMap->MarkChunkDirty (a_ChunkX, a_ChunkY, a_ChunkZ);
|
m_ChunkMap->MarkChunkDirty (a_ChunkX, a_ChunkZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cWorld::MarkChunkSaving(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
void cWorld::MarkChunkSaving(int a_ChunkX, int a_ChunkZ)
|
||||||
{
|
{
|
||||||
m_ChunkMap->MarkChunkSaving(a_ChunkX, a_ChunkY, a_ChunkZ);
|
m_ChunkMap->MarkChunkSaving(a_ChunkX, a_ChunkZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cWorld::MarkChunkSaved (int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
void cWorld::MarkChunkSaved (int a_ChunkX, int a_ChunkZ)
|
||||||
{
|
{
|
||||||
m_ChunkMap->MarkChunkSaved (a_ChunkX, a_ChunkY, a_ChunkZ);
|
m_ChunkMap->MarkChunkSaved (a_ChunkX, a_ChunkZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1605,7 +1575,7 @@ void cWorld::MarkChunkSaved (int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
|||||||
|
|
||||||
|
|
||||||
void cWorld::SetChunkData(
|
void cWorld::SetChunkData(
|
||||||
int a_ChunkX, int a_ChunkY, int a_ChunkZ,
|
int a_ChunkX, int a_ChunkZ,
|
||||||
const BLOCKTYPE * a_BlockTypes,
|
const BLOCKTYPE * a_BlockTypes,
|
||||||
const NIBBLETYPE * a_BlockMeta,
|
const NIBBLETYPE * a_BlockMeta,
|
||||||
const NIBBLETYPE * a_BlockLight,
|
const NIBBLETYPE * a_BlockLight,
|
||||||
@ -1628,10 +1598,10 @@ void cWorld::SetChunkData(
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_ChunkMap->SetChunkData(
|
m_ChunkMap->SetChunkData(
|
||||||
a_ChunkX, a_ChunkY, a_ChunkZ,
|
a_ChunkX, a_ChunkZ,
|
||||||
a_BlockTypes, a_BlockMeta, a_BlockLight, a_BlockSkyLight,
|
a_BlockTypes, a_BlockMeta, a_BlockLight, a_BlockSkyLight,
|
||||||
a_HeightMap, *Biomes,
|
a_HeightMap, *Biomes,
|
||||||
a_Entities, a_BlockEntities,
|
a_BlockEntities,
|
||||||
a_MarkDirty
|
a_MarkDirty
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1642,9 +1612,9 @@ void cWorld::SetChunkData(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If a client is requesting this chunk, send it to them:
|
// If a client is requesting this chunk, send it to them:
|
||||||
if (m_ChunkMap->HasChunkAnyClients(a_ChunkX, a_ChunkY, a_ChunkZ))
|
if (m_ChunkMap->HasChunkAnyClients(a_ChunkX, a_ChunkZ))
|
||||||
{
|
{
|
||||||
m_ChunkSender.ChunkReady(a_ChunkX, a_ChunkY, a_ChunkZ);
|
m_ChunkSender.ChunkReady(a_ChunkX, a_ChunkZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notify the lighting thread that the chunk has become valid (in case it is a neighbor of a postponed chunk):
|
// Notify the lighting thread that the chunk has become valid (in case it is a neighbor of a postponed chunk):
|
||||||
@ -1668,36 +1638,36 @@ void cWorld::ChunkLighted(
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWorld::GetChunkData(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkDataCallback & a_Callback)
|
bool cWorld::GetChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataCallback & a_Callback)
|
||||||
{
|
{
|
||||||
return m_ChunkMap->GetChunkData(a_ChunkX, a_ChunkY, a_ChunkZ, a_Callback);
|
return m_ChunkMap->GetChunkData(a_ChunkX, a_ChunkZ, a_Callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWorld::GetChunkBlockTypes(int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_BlockTypes)
|
bool cWorld::GetChunkBlockTypes(int a_ChunkX, int a_ChunkZ, BLOCKTYPE * a_BlockTypes)
|
||||||
{
|
{
|
||||||
return m_ChunkMap->GetChunkBlockTypes(a_ChunkX, a_ChunkY, a_ChunkZ, a_BlockTypes);
|
return m_ChunkMap->GetChunkBlockTypes(a_ChunkX, a_ChunkZ, a_BlockTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWorld::IsChunkValid(int a_ChunkX, int a_ChunkY, int a_ChunkZ) const
|
bool cWorld::IsChunkValid(int a_ChunkX, int a_ChunkZ) const
|
||||||
{
|
{
|
||||||
return m_ChunkMap->IsChunkValid(a_ChunkX, a_ChunkY, a_ChunkZ);
|
return m_ChunkMap->IsChunkValid(a_ChunkX, a_ChunkZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWorld::HasChunkAnyClients(int a_ChunkX, int a_ChunkY, int a_ChunkZ) const
|
bool cWorld::HasChunkAnyClients(int a_ChunkX, int a_ChunkZ) const
|
||||||
{
|
{
|
||||||
return m_ChunkMap->HasChunkAnyClients(a_ChunkX, a_ChunkY, a_ChunkZ);
|
return m_ChunkMap->HasChunkAnyClients(a_ChunkX, a_ChunkZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1736,7 +1706,7 @@ void cWorld::SetMaxPlayers(int iMax)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cWorld::AddPlayer(cPlayer* a_Player)
|
void cWorld::AddPlayer(cPlayer * a_Player)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSPlayers);
|
cCSLock Lock(m_CSPlayers);
|
||||||
|
|
||||||
@ -1750,8 +1720,9 @@ void cWorld::AddPlayer(cPlayer* a_Player)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cWorld::RemovePlayer(cPlayer* a_Player)
|
void cWorld::RemovePlayer(cPlayer * a_Player)
|
||||||
{
|
{
|
||||||
|
m_ChunkMap->RemoveEntityFromChunk(a_Player, a_Player->GetChunkX(), a_Player->GetChunkZ());
|
||||||
cCSLock Lock(m_CSPlayers);
|
cCSLock Lock(m_CSPlayers);
|
||||||
m_Players.remove(a_Player);
|
m_Players.remove(a_Player);
|
||||||
}
|
}
|
||||||
@ -1882,18 +1853,9 @@ void cWorld::SendPlayerList(cPlayer * a_DestPlayer)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cWorld::RemoveEntityFromChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
void cWorld::RemoveEntityFromChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkZ)
|
||||||
{
|
{
|
||||||
m_ChunkMap->RemoveEntityFromChunk(a_Entity, a_ChunkX, a_ChunkY, a_ChunkZ);
|
m_ChunkMap->RemoveEntityFromChunk(a_Entity, a_ChunkX, a_ChunkZ);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cWorld::MoveEntityToChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
|
||||||
{
|
|
||||||
m_ChunkMap->MoveEntityToChunk(a_Entity, a_ChunkX, a_ChunkY, a_ChunkZ);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1902,16 +1864,7 @@ void cWorld::MoveEntityToChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, i
|
|||||||
|
|
||||||
bool cWorld::ForEachEntity(cEntityCallback & a_Callback)
|
bool cWorld::ForEachEntity(cEntityCallback & a_Callback)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSEntities);
|
return m_ChunkMap->ForEachEntity(a_Callback);
|
||||||
for (cEntityList::iterator itr = m_AllEntities.begin(), itr2 = itr; itr != m_AllEntities.end(); itr = itr2)
|
|
||||||
{
|
|
||||||
++itr2;
|
|
||||||
if (a_Callback.Item(*itr))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} // for itr - m_AllEntities[]
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1929,42 +1882,34 @@ bool cWorld::ForEachEntityInChunk(int a_ChunkX, int a_ChunkZ, cEntityCallback &
|
|||||||
|
|
||||||
bool cWorld::DoWithEntityByID(int a_UniqueID, cEntityCallback & a_Callback)
|
bool cWorld::DoWithEntityByID(int a_UniqueID, cEntityCallback & a_Callback)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSEntities);
|
return m_ChunkMap->DoWithEntityByID(a_UniqueID, a_Callback);
|
||||||
for (cEntityList::iterator itr = m_AllEntities.begin(), end = m_AllEntities.end(); itr != end; ++itr)
|
|
||||||
{
|
|
||||||
if ((*itr)->GetUniqueID() == a_UniqueID)
|
|
||||||
{
|
|
||||||
return a_Callback.Item(*itr);
|
|
||||||
}
|
|
||||||
} // for itr - m_AllEntities[]
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cWorld::CompareChunkClients(int a_ChunkX1, int a_ChunkY1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkY2, int a_ChunkZ2, cClientDiffCallback & a_Callback)
|
void cWorld::CompareChunkClients(int a_ChunkX1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkZ2, cClientDiffCallback & a_Callback)
|
||||||
{
|
{
|
||||||
m_ChunkMap->CompareChunkClients(a_ChunkX1, a_ChunkY1, a_ChunkZ1, a_ChunkX2, a_ChunkY2, a_ChunkZ2, a_Callback);
|
m_ChunkMap->CompareChunkClients(a_ChunkX1, a_ChunkZ1, a_ChunkX2, a_ChunkZ2, a_Callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWorld::AddChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client)
|
bool cWorld::AddChunkClient(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Client)
|
||||||
{
|
{
|
||||||
return m_ChunkMap->AddChunkClient(a_ChunkX, a_ChunkY, a_ChunkZ, a_Client);
|
return m_ChunkMap->AddChunkClient(a_ChunkX, a_ChunkZ, a_Client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cWorld::RemoveChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client)
|
void cWorld::RemoveChunkClient(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Client)
|
||||||
{
|
{
|
||||||
m_ChunkMap->RemoveChunkClient(a_ChunkX, a_ChunkY, a_ChunkZ, a_Client);
|
m_ChunkMap->RemoveChunkClient(a_ChunkX, a_ChunkZ, a_Client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1980,9 +1925,9 @@ void cWorld::RemoveClientFromChunks(cClientHandle * a_Client)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cWorld::SendChunkTo(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client)
|
void cWorld::SendChunkTo(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Client)
|
||||||
{
|
{
|
||||||
m_ChunkSender.QueueSendChunkTo(a_ChunkX, a_ChunkY, a_ChunkZ, a_Client);
|
m_ChunkSender.QueueSendChunkTo(a_ChunkX, a_ChunkZ, a_Client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2123,8 +2068,16 @@ void cWorld::SaveAllChunks(void)
|
|||||||
|
|
||||||
void cWorld::AddEntity(cEntity * a_Entity)
|
void cWorld::AddEntity(cEntity * a_Entity)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSEntities);
|
m_ChunkMap->AddEntity(a_Entity);
|
||||||
m_AllEntities.push_back(a_Entity);
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cWorld::HasEntity(int a_UniqueID)
|
||||||
|
{
|
||||||
|
return m_ChunkMap->HasEntity(a_UniqueID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2254,8 +2207,8 @@ int cWorld::SpawnMob(double a_PosX, double a_PosY, double a_PosZ, int a_EntityTy
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Monster->SetPosition(a_PosX, a_PosY, a_PosZ);
|
||||||
Monster->Initialize(this);
|
Monster->Initialize(this);
|
||||||
Monster->TeleportTo(a_PosX, a_PosY, a_PosZ);
|
|
||||||
BroadcastSpawn(*Monster);
|
BroadcastSpawn(*Monster);
|
||||||
return Monster->GetUniqueID();
|
return Monster->GetUniqueID();
|
||||||
}
|
}
|
||||||
|
@ -100,10 +100,14 @@ public:
|
|||||||
|
|
||||||
eDimension GetDimension(void) const { return m_Dimension; }
|
eDimension GetDimension(void) const { return m_Dimension; }
|
||||||
|
|
||||||
|
/// Returns the world height at the specified coords; waits for the chunk to get loaded / generated
|
||||||
int GetHeight(int a_BlockX, int a_BlockZ);
|
int GetHeight(int a_BlockX, int a_BlockZ);
|
||||||
|
|
||||||
// tolua_end
|
// tolua_end
|
||||||
|
|
||||||
|
/// Retrieves the world height at the specified coords; returns false if chunk not loaded / generated
|
||||||
|
bool TryGetHeight(int a_BlockX, int a_BlockZ, int & a_Height); // TODO: Export in ManualBindings.cpp
|
||||||
|
|
||||||
void BroadcastAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle);
|
void BroadcastAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle);
|
||||||
void BroadcastChat (const AString & a_Message, const cClientHandle * a_Exclude = NULL);
|
void BroadcastChat (const AString & a_Message, const cClientHandle * a_Exclude = NULL);
|
||||||
void BroadcastPlayerAnimation (const cPlayer & a_Player, char a_Animation, const cClientHandle * a_Exclude = NULL);
|
void BroadcastPlayerAnimation (const cPlayer & a_Player, char a_Animation, const cClientHandle * a_Exclude = NULL);
|
||||||
@ -136,9 +140,9 @@ public:
|
|||||||
/// If there is a block entity at the specified coords, sends it to the client specified
|
/// If there is a block entity at the specified coords, sends it to the client specified
|
||||||
void SendBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cClientHandle & a_Client);
|
void SendBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cClientHandle & a_Client);
|
||||||
|
|
||||||
void MarkChunkDirty (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
|
void MarkChunkDirty (int a_ChunkX, int a_ChunkZ);
|
||||||
void MarkChunkSaving(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
|
void MarkChunkSaving(int a_ChunkX, int a_ChunkZ);
|
||||||
void MarkChunkSaved (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
|
void MarkChunkSaved (int a_ChunkX, int a_ChunkZ);
|
||||||
|
|
||||||
/** Sets the chunk data as either loaded from the storage or generated.
|
/** Sets the chunk data as either loaded from the storage or generated.
|
||||||
a_BlockLight and a_BlockSkyLight are optional, if not present, chunk will be marked as unlighted.
|
a_BlockLight and a_BlockSkyLight are optional, if not present, chunk will be marked as unlighted.
|
||||||
@ -147,7 +151,7 @@ public:
|
|||||||
If a_MarkDirty is set, the chunk is set as dirty (used after generating)
|
If a_MarkDirty is set, the chunk is set as dirty (used after generating)
|
||||||
*/
|
*/
|
||||||
void SetChunkData(
|
void SetChunkData(
|
||||||
int a_ChunkX, int a_ChunkY, int a_ChunkZ,
|
int a_ChunkX, int a_ChunkZ,
|
||||||
const BLOCKTYPE * a_BlockTypes,
|
const BLOCKTYPE * a_BlockTypes,
|
||||||
const NIBBLETYPE * a_BlockMeta,
|
const NIBBLETYPE * a_BlockMeta,
|
||||||
const NIBBLETYPE * a_BlockLight,
|
const NIBBLETYPE * a_BlockLight,
|
||||||
@ -165,13 +169,13 @@ public:
|
|||||||
const cChunkDef::BlockNibbles & a_SkyLight
|
const cChunkDef::BlockNibbles & a_SkyLight
|
||||||
);
|
);
|
||||||
|
|
||||||
bool GetChunkData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkDataCallback & a_Callback);
|
bool GetChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataCallback & a_Callback);
|
||||||
|
|
||||||
/// Gets the chunk's blocks, only the block types
|
/// Gets the chunk's blocks, only the block types
|
||||||
bool GetChunkBlockTypes(int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_BlockTypes);
|
bool GetChunkBlockTypes(int a_ChunkX, int a_ChunkZ, BLOCKTYPE * a_BlockTypes);
|
||||||
|
|
||||||
bool IsChunkValid (int a_ChunkX, int a_ChunkY, int a_ChunkZ) const;
|
bool IsChunkValid (int a_ChunkX, int a_ChunkZ) const;
|
||||||
bool HasChunkAnyClients(int a_ChunkX, int a_ChunkY, int a_ChunkZ) const;
|
bool HasChunkAnyClients(int a_ChunkX, int a_ChunkZ) const;
|
||||||
|
|
||||||
void UnloadUnusedChunks(void); // tolua_export
|
void UnloadUnusedChunks(void); // tolua_export
|
||||||
|
|
||||||
@ -203,13 +207,12 @@ public:
|
|||||||
|
|
||||||
void SendPlayerList(cPlayer * a_DestPlayer); // Sends playerlist to the player
|
void SendPlayerList(cPlayer * a_DestPlayer); // Sends playerlist to the player
|
||||||
|
|
||||||
void AddEntity( cEntity* a_Entity );
|
void AddEntity(cEntity * a_Entity);
|
||||||
|
|
||||||
|
bool HasEntity(int a_UniqueID);
|
||||||
|
|
||||||
/// Removes the entity from the chunk specified
|
/// Removes the entity from the chunk specified
|
||||||
void RemoveEntityFromChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ);
|
void RemoveEntityFromChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkZ);
|
||||||
|
|
||||||
/// Moves the entity from its current chunk to the new chunk specified
|
|
||||||
void MoveEntityToChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ);
|
|
||||||
|
|
||||||
/// Calls the callback for each entity in the entire world; returns true if all entities processed, false if the callback aborted by returning true
|
/// Calls the callback for each entity in the entire world; returns true if all entities processed, false if the callback aborted by returning true
|
||||||
bool ForEachEntity(cEntityCallback & a_Callback); // Exported in ManualBindings.cpp
|
bool ForEachEntity(cEntityCallback & a_Callback); // Exported in ManualBindings.cpp
|
||||||
@ -217,23 +220,23 @@ public:
|
|||||||
/// Calls the callback for each entity in the specified chunk; returns true if all entities processed, false if the callback aborted by returning true
|
/// Calls the callback for each entity in the specified chunk; returns true if all entities processed, false if the callback aborted by returning true
|
||||||
bool ForEachEntityInChunk(int a_ChunkX, int a_ChunkZ, cEntityCallback & a_Callback); // Exported in ManualBindings.cpp
|
bool ForEachEntityInChunk(int a_ChunkX, int a_ChunkZ, cEntityCallback & a_Callback); // Exported in ManualBindings.cpp
|
||||||
|
|
||||||
/// Calls the callback if the entity with the specified ID is found, with the entity object as the callback param
|
/// Calls the callback if the entity with the specified ID is found, with the entity object as the callback param. Returns true if entity found and callback returned false.
|
||||||
bool DoWithEntityByID(int a_UniqueID, cEntityCallback & a_Callback); // TODO: Exported in ManualBindings.cpp
|
bool DoWithEntityByID(int a_UniqueID, cEntityCallback & a_Callback); // TODO: Exported in ManualBindings.cpp
|
||||||
|
|
||||||
/// Compares clients of two chunks, calls the callback accordingly
|
/// Compares clients of two chunks, calls the callback accordingly
|
||||||
void CompareChunkClients(int a_ChunkX1, int a_ChunkY1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkY2, int a_ChunkZ2, cClientDiffCallback & a_Callback);
|
void CompareChunkClients(int a_ChunkX1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkZ2, cClientDiffCallback & a_Callback);
|
||||||
|
|
||||||
/// Adds client to a chunk, if not already present; returns true if added, false if present
|
/// Adds client to a chunk, if not already present; returns true if added, false if present
|
||||||
bool AddChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client);
|
bool AddChunkClient(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Client);
|
||||||
|
|
||||||
/// Removes client from the chunk specified
|
/// Removes client from the chunk specified
|
||||||
void RemoveChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client);
|
void RemoveChunkClient(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Client);
|
||||||
|
|
||||||
/// Removes the client from all chunks it is present in
|
/// Removes the client from all chunks it is present in
|
||||||
void RemoveClientFromChunks(cClientHandle * a_Client);
|
void RemoveClientFromChunks(cClientHandle * a_Client);
|
||||||
|
|
||||||
/// Sends the chunk to the client specified, if the chunk is valid. If not valid, the request is postponed (ChunkSender will send that chunk when it becomes valid+lighted)
|
/// Sends the chunk to the client specified, if the chunk is valid. If not valid, the request is postponed (ChunkSender will send that chunk when it becomes valid+lighted)
|
||||||
void SendChunkTo(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client);
|
void SendChunkTo(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Client);
|
||||||
|
|
||||||
/// Removes client from ChunkSender's queue of chunks to be sent
|
/// Removes client from ChunkSender's queue of chunks to be sent
|
||||||
void RemoveClientFromChunkSender(cClientHandle * a_Client);
|
void RemoveClientFromChunkSender(cClientHandle * a_Client);
|
||||||
@ -461,7 +464,7 @@ public:
|
|||||||
int SpawnMob(double a_PosX, double a_PosY, double a_PosZ, int a_EntityType); // tolua_export
|
int SpawnMob(double a_PosX, double a_PosY, double a_PosZ, int a_EntityType); // tolua_export
|
||||||
|
|
||||||
/// Returns a random number from the m_TickRand in range [0 .. a_Range]. To be used only in the tick thread!
|
/// Returns a random number from the m_TickRand in range [0 .. a_Range]. To be used only in the tick thread!
|
||||||
unsigned GetTickRandomNumber(unsigned a_Range) { return m_TickRand.randInt(a_Range); }
|
int GetTickRandomNumber(unsigned a_Range) { return (int)(m_TickRand.randInt(a_Range)); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -505,7 +508,6 @@ private:
|
|||||||
cRedstoneSimulator * m_RedstoneSimulator;
|
cRedstoneSimulator * m_RedstoneSimulator;
|
||||||
|
|
||||||
cCriticalSection m_CSClients;
|
cCriticalSection m_CSClients;
|
||||||
cCriticalSection m_CSEntities;
|
|
||||||
cCriticalSection m_CSPlayers;
|
cCriticalSection m_CSPlayers;
|
||||||
|
|
||||||
cWorldStorage m_Storage;
|
cWorldStorage m_Storage;
|
||||||
@ -536,8 +538,6 @@ private:
|
|||||||
bool m_IsSaplingBonemealable;
|
bool m_IsSaplingBonemealable;
|
||||||
bool m_IsSugarcaneBonemealable;
|
bool m_IsSugarcaneBonemealable;
|
||||||
|
|
||||||
cEntityList m_RemoveEntityQueue;
|
|
||||||
cEntityList m_AllEntities;
|
|
||||||
cClientHandleList m_Clients;
|
cClientHandleList m_Clients;
|
||||||
cPlayerList m_Players;
|
cPlayerList m_Players;
|
||||||
|
|
||||||
|
@ -113,10 +113,12 @@ bool cWSSAnvil::SaveChunk(const cChunkCoords & a_Chunk)
|
|||||||
AString ChunkData;
|
AString ChunkData;
|
||||||
if (!SaveChunkToData(a_Chunk, ChunkData))
|
if (!SaveChunkToData(a_Chunk, ChunkData))
|
||||||
{
|
{
|
||||||
|
LOGWARNING("Cannot serialize chunk [%d, %d] into data", a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!SetChunkData(a_Chunk, ChunkData))
|
if (!SetChunkData(a_Chunk, ChunkData))
|
||||||
{
|
{
|
||||||
|
LOGWARNING("Cannot store chunk [%d, %d] data", a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -252,6 +254,7 @@ bool cWSSAnvil::SaveChunkToData(const cChunkCoords & a_Chunk, AString & a_Data)
|
|||||||
cFastNBTWriter Writer;
|
cFastNBTWriter Writer;
|
||||||
if (!SaveChunkToNBT(a_Chunk, Writer))
|
if (!SaveChunkToNBT(a_Chunk, Writer))
|
||||||
{
|
{
|
||||||
|
LOGWARNING("Cannot save chunk [%d, %d] to NBT", a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Writer.Finish();
|
Writer.Finish();
|
||||||
@ -360,7 +363,7 @@ bool cWSSAnvil::LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT
|
|||||||
//*/
|
//*/
|
||||||
|
|
||||||
m_World->SetChunkData(
|
m_World->SetChunkData(
|
||||||
a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ,
|
a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ,
|
||||||
BlockTypes, MetaData,
|
BlockTypes, MetaData,
|
||||||
IsLightValid ? BlockLight : NULL,
|
IsLightValid ? BlockLight : NULL,
|
||||||
IsLightValid ? SkyLight : NULL,
|
IsLightValid ? SkyLight : NULL,
|
||||||
@ -393,8 +396,9 @@ bool cWSSAnvil::SaveChunkToNBT(const cChunkCoords & a_Chunk, cFastNBTWriter & a_
|
|||||||
a_Writer.AddInt("xPos", a_Chunk.m_ChunkX);
|
a_Writer.AddInt("xPos", a_Chunk.m_ChunkX);
|
||||||
a_Writer.AddInt("zPos", a_Chunk.m_ChunkZ);
|
a_Writer.AddInt("zPos", a_Chunk.m_ChunkZ);
|
||||||
cNBTChunkSerializer Serializer(a_Writer);
|
cNBTChunkSerializer Serializer(a_Writer);
|
||||||
if (!m_World->GetChunkData(a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ, Serializer))
|
if (!m_World->GetChunkData(a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, Serializer))
|
||||||
{
|
{
|
||||||
|
LOGWARNING("Cannot get chunk [%d, %d] data for NBT saving", a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Serializer.Finish(); // Close NBT tags
|
Serializer.Finish(); // Close NBT tags
|
||||||
|
@ -875,7 +875,7 @@ bool cWSSCompact::LoadChunkFromData(const cChunkCoords & a_Chunk, int & a_Uncomp
|
|||||||
NIBBLETYPE * SkyLight = (NIBBLETYPE *)(BlockData + cChunkDef::SkyLightOffset);
|
NIBBLETYPE * SkyLight = (NIBBLETYPE *)(BlockData + cChunkDef::SkyLightOffset);
|
||||||
|
|
||||||
a_World->SetChunkData(
|
a_World->SetChunkData(
|
||||||
a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ,
|
a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ,
|
||||||
BlockData, MetaData,
|
BlockData, MetaData,
|
||||||
IsLightValid ? BlockLight : NULL,
|
IsLightValid ? BlockLight : NULL,
|
||||||
IsLightValid ? SkyLight : NULL,
|
IsLightValid ? SkyLight : NULL,
|
||||||
@ -919,7 +919,7 @@ bool cWSSCompact::cPAKFile::SaveChunkToData(const cChunkCoords & a_Chunk, cWorld
|
|||||||
{
|
{
|
||||||
// Serialize the chunk:
|
// Serialize the chunk:
|
||||||
cJsonChunkSerializer Serializer;
|
cJsonChunkSerializer Serializer;
|
||||||
if (!a_World->GetChunkData(a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ, Serializer))
|
if (!a_World->GetChunkData(a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, Serializer))
|
||||||
{
|
{
|
||||||
// Chunk not valid
|
// Chunk not valid
|
||||||
LOG("cWSSCompact: Trying to save chunk [%d, %d, %d] that has no data, ignoring request.", a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ);
|
LOG("cWSSCompact: Trying to save chunk [%d, %d, %d] that has no data, ignoring request.", a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ);
|
||||||
|
@ -349,16 +349,12 @@ bool cWorldStorage::SaveOneChunk(void)
|
|||||||
LOGINFO("Saved all chunks in world %s", m_World->GetName().c_str());
|
LOGINFO("Saved all chunks in world %s", m_World->GetName().c_str());
|
||||||
return HasMore;
|
return HasMore;
|
||||||
}
|
}
|
||||||
if (ShouldSave && m_World->IsChunkValid(Save.m_ChunkX, Save.m_ChunkY, Save.m_ChunkZ))
|
if (ShouldSave && m_World->IsChunkValid(Save.m_ChunkX, Save.m_ChunkZ))
|
||||||
{
|
{
|
||||||
m_World->MarkChunkSaving(Save.m_ChunkX, Save.m_ChunkY, Save.m_ChunkZ);
|
m_World->MarkChunkSaving(Save.m_ChunkX, Save.m_ChunkZ);
|
||||||
if (m_SaveSchema->SaveChunk(Save))
|
if (m_SaveSchema->SaveChunk(Save))
|
||||||
{
|
{
|
||||||
m_World->MarkChunkSaved(Save.m_ChunkX, Save.m_ChunkY, Save.m_ChunkZ);
|
m_World->MarkChunkSaved(Save.m_ChunkX, Save.m_ChunkZ);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LOGWARNING("Cannot save chunk [%d, %d, %d]", Save.m_ChunkX, Save.m_ChunkY, Save.m_ChunkZ);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return HasMore;
|
return HasMore;
|
||||||
@ -370,7 +366,7 @@ bool cWorldStorage::SaveOneChunk(void)
|
|||||||
|
|
||||||
bool cWorldStorage::LoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
bool cWorldStorage::LoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
||||||
{
|
{
|
||||||
if (m_World->IsChunkValid(a_ChunkX, a_ChunkY, a_ChunkZ))
|
if (m_World->IsChunkValid(a_ChunkX, a_ChunkZ))
|
||||||
{
|
{
|
||||||
// Already loaded (can happen, since the queue is async)
|
// Already loaded (can happen, since the queue is async)
|
||||||
return true;
|
return true;
|
||||||
|
Loading…
Reference in New Issue
Block a user