summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormadmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6>2013-03-03 09:40:37 +0100
committermadmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6>2013-03-03 09:40:37 +0100
commit46e1228f73d37753c9b888d97f941084b6fb558b (patch)
tree28b0a2ad07813924c9848f9b9c564d36e4631189
parentcSandSimulator: implemented InstantFall (diff)
downloadcuberite-46e1228f73d37753c9b888d97f941084b6fb558b.tar
cuberite-46e1228f73d37753c9b888d97f941084b6fb558b.tar.gz
cuberite-46e1228f73d37753c9b888d97f941084b6fb558b.tar.bz2
cuberite-46e1228f73d37753c9b888d97f941084b6fb558b.tar.lz
cuberite-46e1228f73d37753c9b888d97f941084b6fb558b.tar.xz
cuberite-46e1228f73d37753c9b888d97f941084b6fb558b.tar.zst
cuberite-46e1228f73d37753c9b888d97f941084b6fb558b.zip
-rw-r--r--source/FallingBlock.cpp18
-rw-r--r--source/Simulator/SandSimulator.cpp78
-rw-r--r--source/Simulator/SandSimulator.h2
3 files changed, 61 insertions, 37 deletions
diff --git a/source/FallingBlock.cpp b/source/FallingBlock.cpp
index 12362009d..8ad313bb9 100644
--- a/source/FallingBlock.cpp
+++ b/source/FallingBlock.cpp
@@ -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;
diff --git a/source/Simulator/SandSimulator.cpp b/source/Simulator/SandSimulator.cpp
index 84646a10a..baab76d67 100644
--- a/source/Simulator/SandSimulator.cpp
+++ b/source/Simulator/SandSimulator.cpp
@@ -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_BROWN_MUSHROOM:
+ case E_BLOCK_COBWEB:
+ case E_BLOCK_CROPS:
+ case E_BLOCK_DEAD_BUSH:
+ case E_BLOCK_DETECTOR_RAIL:
case E_BLOCK_FIRE:
- case E_BLOCK_WATER:
- case E_BLOCK_STATIONARY_WATER:
+ case E_BLOCK_FLOWER_POT:
case E_BLOCK_LAVA:
- case E_BLOCK_STATIONARY_LAVA:
+ case E_BLOCK_LEVER:
+ case E_BLOCK_MINECART_TRACKS:
+ case E_BLOCK_MELON_STEM:
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_CROPS:
case E_BLOCK_PUMPKIN_STEM:
- case E_BLOCK_MELON_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_REDSTONE_REPEATER_OFF:
- case E_BLOCK_REDSTONE_REPEATER_ON:
+ 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;
}
diff --git a/source/Simulator/SandSimulator.h b/source/Simulator/SandSimulator.h
index 571258049..6e9ea15ac 100644
--- a/source/Simulator/SandSimulator.h
+++ b/source/Simulator/SandSimulator.h
@@ -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.