Explosion: Switched from a cube to a sphere. Implemented using cBlockArea and moved block changing code to ChunkMap

git-svn-id: http://mc-server.googlecode.com/svn/trunk@1441 0a769ca7-a7f5-676a-18bf-c427514a06d6
master
keyboard.osh@gmail.com 2013-05-04 06:25:58 +00:00
parent ad4a61ae0e
commit c1e6fb454f
3 changed files with 37 additions and 31 deletions

View File

@ -1450,6 +1450,36 @@ bool cChunkMap::ForEachEntityInChunk(int a_ChunkX, int a_ChunkZ, cEntityCallback
cVector3iArray *cChunkMap::DoExplosiontAt(float a_ExplosionSize, int a_BlockX, int a_BlockY, int a_BlockZ)
{
cBlockArea area;
cVector3iArray *BlocksAffected = new cVector3iArray();
int ExplosionSizeInt = (int) ceil(a_ExplosionSize);
BlocksAffected->reserve(8 * ExplosionSizeInt * ExplosionSizeInt * ExplosionSizeInt);
area.Read(m_World,a_BlockX - ExplosionSizeInt,a_BlockX + ExplosionSizeInt,a_BlockY - ExplosionSizeInt,a_BlockY + ExplosionSizeInt,a_BlockZ - ExplosionSizeInt,a_BlockZ + ExplosionSizeInt);
for (int x = -ExplosionSizeInt; x < ExplosionSizeInt; x++)
{
for (int y = -ExplosionSizeInt; y < ExplosionSizeInt; y++)
{
for (int z = -ExplosionSizeInt; z < ExplosionSizeInt; z++)
{
if ((x*x + y*y + z*z) < (ExplosionSizeInt * ExplosionSizeInt))
{
area.SetBlockType(a_BlockX + x, a_BlockY + y, a_BlockZ + z,E_BLOCK_AIR);
BlocksAffected->push_back(Vector3i(a_BlockX + x, a_BlockY + y, a_BlockZ + z));
}
}
}
}
area.Write(m_World,a_BlockX - ExplosionSizeInt,a_BlockY - ExplosionSizeInt,a_BlockZ - ExplosionSizeInt);
return BlocksAffected;
}
bool cChunkMap::DoWithEntityByID(int a_UniqueID, cEntityCallback & a_Callback)
{
cCSLock Lock(m_CSLayers);

View File

@ -197,6 +197,9 @@ 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
// Destroys and returns a list of blocks destroyed in the explosion at the specified coordinates
cVector3iArray * DoExplosiontAt(float a_ExplosionSize, int a_BlockX, int a_BlockY, int a_BlockZ);
/// 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

View File

@ -705,37 +705,9 @@ bool cWorld::ForEachFurnaceInChunk(int a_ChunkX, int a_ChunkZ, cFurnaceCallback
void cWorld::DoExplosiontAt(float a_ExplosionSize, int a_BlockX, int a_BlockY, int a_BlockZ)
{
// TODO: implement explosion using cBlockArea / in cChunkMap, add damage to entities, add support for pickups, and implement block hardiness
// TODO: Add damage to entities, add support for pickups, and implement block hardiness
Vector3d explosion_pos = Vector3d(a_BlockX,a_BlockY,a_BlockZ);
cVector3iArray BlocksAffected;
int ExplosionSizeInt = (int)a_ExplosionSize;
BlocksAffected.reserve(8 * ExplosionSizeInt * ExplosionSizeInt * ExplosionSizeInt);
for (int x = 0; x < ExplosionSizeInt; x++)
{
for (int y = 0; y < ExplosionSizeInt; y++)
{
for (int z = 0; z < ExplosionSizeInt; z++)
{
DigBlock(a_BlockX + x, a_BlockY + y, a_BlockZ + z);
DigBlock(a_BlockX + x, a_BlockY - y, a_BlockZ + z);
DigBlock(a_BlockX - x, a_BlockY - y, a_BlockZ - z);
DigBlock(a_BlockX - x, a_BlockY + y, a_BlockZ - z);
DigBlock(a_BlockX + x, a_BlockY + y, a_BlockZ - z);
DigBlock(a_BlockX + x, a_BlockY - y, a_BlockZ - z);
DigBlock(a_BlockX - x, a_BlockY + y, a_BlockZ + z);
DigBlock(a_BlockX - x, a_BlockY - y, a_BlockZ + z);
BlocksAffected.push_back(Vector3i(a_BlockX + x, a_BlockY + y, a_BlockZ + z));
BlocksAffected.push_back(Vector3i(a_BlockX + x, a_BlockY - y, a_BlockZ + z));
BlocksAffected.push_back(Vector3i(a_BlockX - x, a_BlockY - y, a_BlockZ - z));
BlocksAffected.push_back(Vector3i(a_BlockX - x, a_BlockY + y, a_BlockZ - z));
BlocksAffected.push_back(Vector3i(a_BlockX + x, a_BlockY + y, a_BlockZ - z));
BlocksAffected.push_back(Vector3i(a_BlockX + x, a_BlockY - y, a_BlockZ - z));
BlocksAffected.push_back(Vector3i(a_BlockX - x, a_BlockY + y, a_BlockZ + z));
BlocksAffected.push_back(Vector3i(a_BlockX - x, a_BlockY - y, a_BlockZ + z));
}
}
}
cVector3iArray * BlocksAffected = m_ChunkMap->DoExplosiontAt(a_ExplosionSize,a_BlockX,a_BlockY,a_BlockZ);
BroadcastSoundEffect("random.explode", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 1.0f, 0.6f);
{
cCSLock Lock(m_CSPlayers);
@ -757,10 +729,11 @@ void cWorld::DoExplosiontAt(float a_ExplosionSize, int a_BlockX, int a_BlockY, i
}
distance_explosion.Normalize();
distance_explosion *= power;
ch->SendExplosion(a_BlockX, a_BlockY, a_BlockZ, a_ExplosionSize, BlocksAffected, distance_explosion);
ch->SendExplosion(a_BlockX, a_BlockY, a_BlockZ, a_ExplosionSize, *BlocksAffected, distance_explosion);
}
}
}
delete BlocksAffected;
}