diff options
author | madmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6> | 2013-03-03 09:40:37 +0100 |
---|---|---|
committer | madmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6> | 2013-03-03 09:40:37 +0100 |
commit | 46e1228f73d37753c9b888d97f941084b6fb558b (patch) | |
tree | 28b0a2ad07813924c9848f9b9c564d36e4631189 /source | |
parent | cSandSimulator: implemented InstantFall (diff) | |
download | cuberite-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 |
Diffstat (limited to '')
-rw-r--r-- | source/FallingBlock.cpp | 18 | ||||
-rw-r--r-- | source/Simulator/SandSimulator.cpp | 78 | ||||
-rw-r--r-- | source/Simulator/SandSimulator.h | 2 |
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. |