SandSimulator: Fixed sand dropping on half-slabs; added more blocks that break falling sand into pickups, fixed instant-fall
git-svn-id: http://mc-server.googlecode.com/svn/trunk@1242 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
parent
86c97cb28a
commit
46e1228f73
@ -64,12 +64,20 @@ void cFallingBlock::Tick(float a_Dt, MTRand & a_TickRandom)
|
||||
|
||||
if (BlockY < cChunkDef::Height - 1)
|
||||
{
|
||||
BLOCKTYPE BlockBelow = GetWorld()->GetBlock(BlockX, BlockY, BlockZ);
|
||||
if (
|
||||
cSandSimulator::DoesBreakFallingThrough(BlockBelow) || // Fallen onto a block that breaks this into pickups (e. g. half-slab)
|
||||
!cSandSimulator::CanContinueFallThrough(BlockBelow) // Fallen onto a solid block
|
||||
)
|
||||
BLOCKTYPE BlockBelow;
|
||||
NIBBLETYPE BelowMeta;
|
||||
GetWorld()->GetBlockTypeMeta(BlockX, BlockY, BlockZ, BlockBelow, BelowMeta);
|
||||
if (cSandSimulator::DoesBreakFallingThrough(BlockBelow, BelowMeta))
|
||||
{
|
||||
// Fallen onto a block that breaks this into pickups (e. g. half-slab)
|
||||
// Must finish the fall with coords one below the block:
|
||||
cSandSimulator::FinishFalling(m_World, BlockX, BlockY, BlockZ, m_BlockType, m_BlockMeta);
|
||||
Destroy();
|
||||
return;
|
||||
}
|
||||
else if (!cSandSimulator::CanContinueFallThrough(BlockBelow))
|
||||
{
|
||||
// Fallen onto a solid block
|
||||
cSandSimulator::FinishFalling(m_World, BlockX, BlockY + 1, BlockZ, m_BlockType, m_BlockMeta);
|
||||
Destroy();
|
||||
return;
|
||||
|
@ -101,7 +101,7 @@ void cSandSimulator::AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk *
|
||||
cSandSimulatorChunkData & ChunkData = a_Chunk->GetSandSimulatorData();
|
||||
for (cSandSimulatorChunkData::iterator itr = ChunkData.begin(); itr != ChunkData.end(); ++itr)
|
||||
{
|
||||
if ((itr->x == RelX) && (itr->y == a_BlockY) && (itr->z == a_BlockZ))
|
||||
if ((itr->x == RelX) && (itr->y == a_BlockY) && (itr->z == RelZ))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -121,10 +121,10 @@ bool cSandSimulator::CanStartFallingThrough(BLOCKTYPE a_BlockType)
|
||||
{
|
||||
case E_BLOCK_AIR:
|
||||
case E_BLOCK_FIRE:
|
||||
case E_BLOCK_WATER:
|
||||
case E_BLOCK_STATIONARY_WATER:
|
||||
case E_BLOCK_LAVA:
|
||||
case E_BLOCK_STATIONARY_LAVA:
|
||||
case E_BLOCK_STATIONARY_WATER:
|
||||
case E_BLOCK_WATER:
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -141,33 +141,41 @@ bool cSandSimulator::CanContinueFallThrough(BLOCKTYPE a_BlockType)
|
||||
switch (a_BlockType)
|
||||
{
|
||||
case E_BLOCK_AIR:
|
||||
case E_BLOCK_FIRE:
|
||||
case E_BLOCK_WATER:
|
||||
case E_BLOCK_STATIONARY_WATER:
|
||||
case E_BLOCK_LAVA:
|
||||
case E_BLOCK_STATIONARY_LAVA:
|
||||
case E_BLOCK_POWERED_RAIL:
|
||||
case E_BLOCK_DETECTOR_RAIL:
|
||||
case E_BLOCK_COBWEB:
|
||||
case E_BLOCK_TALL_GRASS:
|
||||
case E_BLOCK_DEAD_BUSH:
|
||||
case E_BLOCK_YELLOW_FLOWER:
|
||||
case E_BLOCK_RED_ROSE:
|
||||
case E_BLOCK_BROWN_MUSHROOM:
|
||||
case E_BLOCK_RED_MUSHROOM:
|
||||
case E_BLOCK_TORCH:
|
||||
case E_BLOCK_REDSTONE_WIRE:
|
||||
case E_BLOCK_COBWEB:
|
||||
case E_BLOCK_CROPS:
|
||||
case E_BLOCK_PUMPKIN_STEM:
|
||||
case E_BLOCK_DEAD_BUSH:
|
||||
case E_BLOCK_DETECTOR_RAIL:
|
||||
case E_BLOCK_FIRE:
|
||||
case E_BLOCK_FLOWER_POT:
|
||||
case E_BLOCK_LAVA:
|
||||
case E_BLOCK_LEVER:
|
||||
case E_BLOCK_MINECART_TRACKS:
|
||||
case E_BLOCK_MELON_STEM:
|
||||
case E_BLOCK_REDSTONE_TORCH_OFF:
|
||||
case E_BLOCK_REDSTONE_TORCH_ON:
|
||||
case E_BLOCK_STONE_BUTTON:
|
||||
case E_BLOCK_STONE_PRESSURE_PLATE:
|
||||
case E_BLOCK_WOODEN_BUTTON:
|
||||
case E_BLOCK_WOODEN_PRESSURE_PLATE:
|
||||
case E_BLOCK_POWERED_RAIL:
|
||||
case E_BLOCK_PUMPKIN_STEM:
|
||||
case E_BLOCK_REDSTONE_REPEATER_OFF:
|
||||
case E_BLOCK_REDSTONE_REPEATER_ON:
|
||||
case E_BLOCK_REDSTONE_TORCH_OFF:
|
||||
case E_BLOCK_REDSTONE_TORCH_ON:
|
||||
case E_BLOCK_REDSTONE_WIRE:
|
||||
case E_BLOCK_RED_MUSHROOM:
|
||||
case E_BLOCK_RED_ROSE:
|
||||
case E_BLOCK_SIGN_POST:
|
||||
case E_BLOCK_STATIONARY_LAVA:
|
||||
case E_BLOCK_STATIONARY_WATER:
|
||||
case E_BLOCK_STONE_BUTTON:
|
||||
case E_BLOCK_STONE_PRESSURE_PLATE:
|
||||
case E_BLOCK_TALL_GRASS:
|
||||
case E_BLOCK_TORCH:
|
||||
case E_BLOCK_TRAPDOOR:
|
||||
case E_BLOCK_TRIPWIRE:
|
||||
case E_BLOCK_TRIPWIRE_HOOK:
|
||||
case E_BLOCK_WALLSIGN:
|
||||
case E_BLOCK_WATER:
|
||||
case E_BLOCK_WOODEN_BUTTON:
|
||||
case E_BLOCK_WOODEN_PRESSURE_PLATE:
|
||||
case E_BLOCK_YELLOW_FLOWER:
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -184,13 +192,13 @@ bool cSandSimulator::IsReplacedOnRematerialization(BLOCKTYPE a_BlockType)
|
||||
switch (a_BlockType)
|
||||
{
|
||||
case E_BLOCK_AIR:
|
||||
case E_BLOCK_DEAD_BUSH:
|
||||
case E_BLOCK_FIRE:
|
||||
case E_BLOCK_WATER:
|
||||
case E_BLOCK_STATIONARY_WATER:
|
||||
case E_BLOCK_LAVA:
|
||||
case E_BLOCK_STATIONARY_LAVA:
|
||||
case E_BLOCK_STATIONARY_WATER:
|
||||
case E_BLOCK_TALL_GRASS:
|
||||
case E_BLOCK_DEAD_BUSH:
|
||||
case E_BLOCK_WATER:
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -202,14 +210,14 @@ bool cSandSimulator::IsReplacedOnRematerialization(BLOCKTYPE a_BlockType)
|
||||
|
||||
|
||||
|
||||
bool cSandSimulator::DoesBreakFallingThrough(BLOCKTYPE a_BlockType)
|
||||
bool cSandSimulator::DoesBreakFallingThrough(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
|
||||
{
|
||||
switch (a_BlockType)
|
||||
{
|
||||
case E_BLOCK_STONE_SLAB:
|
||||
case E_BLOCK_WOODEN_SLAB:
|
||||
{
|
||||
return true;
|
||||
return ((a_BlockMeta & 0x08) == 0); // Only a bottom-slab breaks the block
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@ -255,11 +263,19 @@ void cSandSimulator::DoInstantFall(cChunk * a_Chunk, int a_RelX, int a_RelY, int
|
||||
// Search for a place to put it:
|
||||
for (int y = a_RelY - 1; y >= 0; y--)
|
||||
{
|
||||
BLOCKTYPE BlockType = a_Chunk->GetBlock(a_RelX, y, a_RelZ);
|
||||
if (
|
||||
!DoesBreakFallingThrough(BlockType) &&
|
||||
CanContinueFallThrough(BlockType)
|
||||
)
|
||||
BLOCKTYPE BlockType;
|
||||
NIBBLETYPE BlockMeta;
|
||||
a_Chunk->GetBlockTypeMeta(a_RelX, y, a_RelZ, BlockType, BlockMeta);
|
||||
int BlockY;
|
||||
if (DoesBreakFallingThrough(BlockType, BlockMeta))
|
||||
{
|
||||
BlockY = y;
|
||||
}
|
||||
else if (!CanContinueFallThrough(BlockType))
|
||||
{
|
||||
BlockY = y + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Can fall further down
|
||||
continue;
|
||||
@ -268,7 +284,7 @@ void cSandSimulator::DoInstantFall(cChunk * a_Chunk, int a_RelX, int a_RelY, int
|
||||
// Finish the fall at the found bottom:
|
||||
int BlockX = a_RelX + a_Chunk->GetPosX() * cChunkDef::Width;
|
||||
int BlockZ = a_RelZ + a_Chunk->GetPosZ() * cChunkDef::Width;
|
||||
FinishFalling(&m_World, BlockX, y + 1, BlockZ, FallingBlockType, FallingBlockMeta);
|
||||
FinishFalling(&m_World, BlockX, BlockY, BlockZ, FallingBlockType, FallingBlockMeta);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ public:
|
||||
static bool IsReplacedOnRematerialization(BLOCKTYPE a_BlockType);
|
||||
|
||||
/// Returns true if the specified block breaks falling blocks while they fall through it (e. g. halfslabs)
|
||||
static bool DoesBreakFallingThrough(BLOCKTYPE a_BlockType);
|
||||
static bool DoesBreakFallingThrough(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
|
||||
|
||||
/** Called when a block finishes falling at the specified coords, either by insta-fall,
|
||||
or through cFallingBlock entity.
|
||||
|
Loading…
Reference in New Issue
Block a user