1
0
Fork 0

Added cWorld::ForEachEntityInBox()

This commit is contained in:
madmaxoft 2014-09-03 17:00:26 +02:00
parent 9eb07f483a
commit a51c1e0b73
8 changed files with 117 additions and 0 deletions

View File

@ -859,6 +859,32 @@ void cLuaState::GetStackValue(int a_StackPos, eWeather & a_ReturnedVal)
void cLuaState::GetStackValue(int a_StackPos, pBoundingBox & a_ReturnedVal)
{
tolua_Error err;
if (tolua_isusertable(m_LuaState, a_StackPos, "cBoundingBox", false, &err))
{
a_ReturnedVal = (cBoundingBox *)lua_touserdata(m_LuaState, a_StackPos);
}
}
void cLuaState::GetStackValue(int a_StackPos, pWorld & a_ReturnedVal)
{
tolua_Error err;
if (tolua_isusertable(m_LuaState, a_StackPos, "cWorld", false, &err))
{
a_ReturnedVal = (cWorld *)lua_touserdata(m_LuaState, a_StackPos);
}
}
bool cLuaState::CallFunction(int a_NumResults)
{
ASSERT (m_NumCurrentFunctionArgs >= 0); // A function must be pushed to stack first

View File

@ -59,6 +59,10 @@ class cTNTEntity;
class cCreeper;
class cHopperEntity;
class cBlockEntity;
class cBoundingBox;
typedef cBoundingBox * pBoundingBox;
typedef cWorld * pWorld;
@ -230,6 +234,12 @@ public:
/** Retrieve value at a_StackPos, if it is a valid number, converting and clamping it to eWeather.
If not, a_Value is unchanged. */
void GetStackValue(int a_StackPos, eWeather & a_Value);
/** Retrieve value at a_StackPos, if it is a valid cBoundingBox class. If not, a_Value is unchanged */
void GetStackValue(int a_StackPos, pBoundingBox & a_Value);
/** Retrieve value at a_StackPos, if it is a valid cWorld class. If not, a_Value is unchanged */
void GetStackValue(int a_StackPos, pWorld & a_Value);
// Include the cLuaState::Call() overload implementation that is generated by the gen_LuaState_Call.lua script:

View File

@ -37,6 +37,7 @@
#include "MobSpawner.h"
#include "BlockInServerPluginInterface.h"
#include "SetChunkData.h"
#include "BoundingBox.h"
#include "json/json.h"
@ -1960,6 +1961,30 @@ bool cChunk::ForEachEntity(cEntityCallback & a_Callback)
bool cChunk::ForEachEntityInBox(const cBoundingBox & a_Box, cEntityCallback & a_Callback)
{
// The entity list is locked by the parent chunkmap's CS
for (cEntityList::iterator itr = m_Entities.begin(), itr2 = itr; itr != m_Entities.end(); itr = itr2)
{
++itr2;
cBoundingBox EntBox((*itr)->GetPosition(), (*itr)->GetWidth() / 2, (*itr)->GetHeight());
if (!EntBox.DoesIntersect(a_Box))
{
// The entity is not in the specified box
continue;
}
if (a_Callback.Item(*itr))
{
return false;
}
} // for itr - m_Entitites[]
return true;
}
bool cChunk::DoWithEntityByID(int a_EntityID, cEntityCallback & a_Callback, bool & a_CallbackResult)
{
// The entity list is locked by the parent chunkmap's CS

View File

@ -216,6 +216,10 @@ public:
/** 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
/** Calls the callback for each entity that has a nonempty intersection with the specified boundingbox.
Returns true if all entities processed, false if the callback aborted by returning true. */
bool ForEachEntityInBox(const cBoundingBox & a_Box, 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

View File

@ -1775,6 +1775,38 @@ bool cChunkMap::ForEachEntityInChunk(int a_ChunkX, int a_ChunkZ, cEntityCallback
bool cChunkMap::ForEachEntityInBox(const cBoundingBox & a_Box, cEntityCallback & a_Callback)
{
// Calculate the chunk range for the box:
int MinChunkX = (int)floor(a_Box.GetMinX() / cChunkDef::Width);
int MinChunkZ = (int)floor(a_Box.GetMinZ() / cChunkDef::Width);
int MaxChunkX = (int)floor((a_Box.GetMaxX() + cChunkDef::Width) / cChunkDef::Width);
int MaxChunkZ = (int)floor((a_Box.GetMaxZ() + cChunkDef::Width) / cChunkDef::Width);
// Iterate over each chunk in the range:
cCSLock Lock(m_CSLayers);
for (int z = MinChunkZ; z <= MaxChunkZ; z++)
{
for (int x = MinChunkX; x <= MaxChunkX; x++)
{
cChunkPtr Chunk = GetChunkNoGen(x, ZERO_CHUNK_Y, z);
if ((Chunk == NULL) || !Chunk->IsValid())
{
continue;
}
if (!Chunk->ForEachEntityInBox(a_Box, a_Callback))
{
return false;
}
} // for x
} // for z
return true;
}
void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, cVector3iArray & a_BlocksAffected)
{
// Don't explode if outside of Y range (prevents the following test running into unallocated memory):

View File

@ -36,6 +36,7 @@ class cBlockArea;
class cMobCensus;
class cMobSpawner;
class cSetChunkData;
class cBoundingBox;
typedef std::list<cClientHandle *> cClientHandleList;
typedef cChunk * cChunkPtr;
@ -209,6 +210,11 @@ 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 */
bool ForEachEntityInChunk(int a_ChunkX, int a_ChunkZ, cEntityCallback & a_Callback); // Lua-accessible
/** Calls the callback for each entity that has a nonempty intersection with the specified boundingbox.
Returns true if all entities processed, false if the callback aborted by returning true.
If any chunk in the box is missing, ignores the entities in that chunk silently. */
bool ForEachEntityInBox(const cBoundingBox & a_Box, cEntityCallback & a_Callback); // Lua-accessible
/** Destroys and returns a list of blocks destroyed in the explosion at the specified coordinates */
void DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, cVector3iArray & a_BlockAffected);

View File

@ -2696,6 +2696,15 @@ bool cWorld::ForEachEntityInChunk(int a_ChunkX, int a_ChunkZ, cEntityCallback &
bool cWorld::ForEachEntityInBox(const cBoundingBox & a_Box, cEntityCallback & a_Callback)
{
return m_ChunkMap->ForEachEntityInBox(a_Box, a_Callback);
}
bool cWorld::DoWithEntityByID(int a_UniqueID, cEntityCallback & a_Callback)
{
return m_ChunkMap->DoWithEntityByID(a_UniqueID, a_Callback);

View File

@ -324,6 +324,11 @@ 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 */
bool ForEachEntityInChunk(int a_ChunkX, int a_ChunkZ, cEntityCallback & a_Callback); // Exported in ManualBindings.cpp
/** Calls the callback for each entity that has a nonempty intersection with the specified boundingbox.
Returns true if all entities processed, false if the callback aborted by returning true.
If any chunk in the box is missing, ignores the entities in that chunk silently. */
bool ForEachEntityInBox(const cBoundingBox & a_Box, 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. Returns true if entity found and callback returned false. */
bool DoWithEntityByID(int a_UniqueID, cEntityCallback & a_Callback); // Exported in ManualBindings.cpp