diff options
author | Tiger Wang <ziwei.tiger@hotmail.co.uk> | 2014-09-30 23:00:33 +0200 |
---|---|---|
committer | Tiger Wang <ziwei.tiger@hotmail.co.uk> | 2014-09-30 23:00:33 +0200 |
commit | 48c99dcd2ec972ebf627aa0b4d64a0e484d47aa5 (patch) | |
tree | 36bb54e6666f2480b38437b1020ca61dc691b895 | |
parent | Merge pull request #1485 from mc-server/PluginMessages (diff) | |
download | cuberite-48c99dcd2ec972ebf627aa0b4d64a0e484d47aa5.tar cuberite-48c99dcd2ec972ebf627aa0b4d64a0e484d47aa5.tar.gz cuberite-48c99dcd2ec972ebf627aa0b4d64a0e484d47aa5.tar.bz2 cuberite-48c99dcd2ec972ebf627aa0b4d64a0e484d47aa5.tar.lz cuberite-48c99dcd2ec972ebf627aa0b4d64a0e484d47aa5.tar.xz cuberite-48c99dcd2ec972ebf627aa0b4d64a0e484d47aa5.tar.zst cuberite-48c99dcd2ec972ebf627aa0b4d64a0e484d47aa5.zip |
-rw-r--r-- | src/BlockInfo.cpp | 1 | ||||
-rw-r--r-- | src/Blocks/BlockTorch.h | 121 |
2 files changed, 52 insertions, 70 deletions
diff --git a/src/BlockInfo.cpp b/src/BlockInfo.cpp index 14e814084..05a1e13f8 100644 --- a/src/BlockInfo.cpp +++ b/src/BlockInfo.cpp @@ -527,6 +527,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_LAPIS_ORE ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_LOG ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_MELON ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_MOB_SPAWNER ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_MOSSY_COBBLESTONE ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_MYCELIUM ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_NETHERRACK ].m_FullyOccupiesVoxel = true; diff --git a/src/Blocks/BlockTorch.h b/src/Blocks/BlockTorch.h index dd252f2a4..3070adfd9 100644 --- a/src/Blocks/BlockTorch.h +++ b/src/Blocks/BlockTorch.h @@ -24,32 +24,22 @@ public: BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta ) override { - // Find proper placement of torch + BLOCKTYPE Block; + NIBBLETYPE Meta; + AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, true); // Set to clicked block + a_ChunkInterface.GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, Block, Meta); - if ((a_BlockFace == BLOCK_FACE_TOP) || (a_BlockFace == BLOCK_FACE_BOTTOM)) + if (!CanBePlacedOn(Block, Meta, a_BlockFace)) // Try to preserve original direction { - a_BlockFace = FindSuitableFace(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); // Top or bottom faces clicked, find a suitable face + // Torch couldn't be placed on whatever face was clicked, last ditch resort - find another face + + AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, false); // Reset to torch block + a_BlockFace = FindSuitableFace(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); // Set a_BlockFace to a valid direction which will be converted later to a metadata if (a_BlockFace == BLOCK_FACE_NONE) { - // Client wouldn't have sent anything anyway, but whatever return false; } } - else - { - // Not top or bottom faces, try to preserve whatever face was clicked - AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, true); // Set to clicked block - if (!CanBePlacedOn(a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ), a_BlockFace)) - { - AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, false); // Reset to torch block - // Torch couldn't be placed on whatever face was clicked, last ditch resort - find another face - a_BlockFace = FindSuitableFace(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); - if (a_BlockFace == BLOCK_FACE_NONE) - { - return false; - } - } - } a_BlockType = m_BlockType; a_BlockMeta = DirectionToMetaData(a_BlockFace); @@ -97,15 +87,40 @@ public: } - static bool CanBePlacedOn(BLOCKTYPE a_BlockType, eBlockFace a_BlockFace) + static bool CanBePlacedOn(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, eBlockFace a_BlockFace) { - if (!cBlockInfo::FullyOccupiesVoxel(a_BlockType)) - { - return (a_BlockFace == BLOCK_FACE_TOP); // Allow placement only when torch upright (for glass, etc.); exceptions won't even be sent by client, no need to handle - } - else + switch (a_BlockType) { - return true; + case E_BLOCK_END_PORTAL_FRAME: + case E_BLOCK_SOULSAND: + { + // Exceptional vanilla behaviour + return true; + } + case E_BLOCK_GLASS: + case E_BLOCK_STAINED_GLASS: + case E_BLOCK_FENCE: + case E_BLOCK_NETHER_BRICK_FENCE: + case E_BLOCK_COBBLESTONE_WALL: + { + // Torches can only be placed on top of these blocks + return (a_BlockFace == BLOCK_FACE_YP); + } + case E_BLOCK_STONE_SLAB: + case E_BLOCK_WOODEN_SLAB: + { + // Toches can be placed on the top of these slabs only if the occupy the top half of the voxel + return ((a_BlockFace == BLOCK_FACE_YP) && ((a_BlockMeta & 0x08) == 0x08)); + } + default: + { + if (cBlockInfo::FullyOccupiesVoxel(a_BlockType)) + { + // Torches can be placed on full blocks unless their bottom side is clicked + return (a_BlockFace != BLOCK_FACE_YM); + } + return false; + } } } @@ -117,26 +132,12 @@ public: { eBlockFace Face = static_cast<eBlockFace>(i); AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, Face, true); - BLOCKTYPE BlockInQuestion = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ); - - // If on a block that can only hold a torch if torch is standing on it, return that face - if ( - ( - (BlockInQuestion == E_BLOCK_GLASS) || - (BlockInQuestion == E_BLOCK_FENCE) || - (BlockInQuestion == E_BLOCK_NETHER_BRICK_FENCE) || - (BlockInQuestion == E_BLOCK_COBBLESTONE_WALL) || - (BlockInQuestion == E_BLOCK_STONE_SLAB) || - (BlockInQuestion == E_BLOCK_WOODEN_SLAB) - ) && - (Face == BLOCK_FACE_TOP) - ) - { - return Face; - } - else if (cBlockInfo::FullyOccupiesVoxel(BlockInQuestion) && (i != BLOCK_FACE_BOTTOM)) + BLOCKTYPE BlockInQuestion; + NIBBLETYPE BlockInQuestionMeta; + a_ChunkInterface.GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, BlockInQuestion, BlockInQuestionMeta); + + if (CanBePlacedOn(BlockInQuestion, BlockInQuestionMeta, Face)) { - // Otherwise, if block in that direction is torch placeable and we haven't gotten to it via the bottom face, return that face return Face; } else @@ -152,36 +153,16 @@ public: virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { eBlockFace Face = MetaDataToDirection(a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ)); - AddFaceDirection(a_RelX, a_RelY, a_RelZ, Face, true); + BLOCKTYPE BlockInQuestion; - a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockInQuestion); - - if ( - (BlockInQuestion == E_BLOCK_GLASS) || - (BlockInQuestion == E_BLOCK_STAINED_GLASS) || - (BlockInQuestion == E_BLOCK_FENCE) || - (BlockInQuestion == E_BLOCK_SOULSAND) || - (BlockInQuestion == E_BLOCK_MOB_SPAWNER) || - (BlockInQuestion == E_BLOCK_END_PORTAL_FRAME) || // Actual vanilla behaviour - (BlockInQuestion == E_BLOCK_NETHER_BRICK_FENCE) || - (BlockInQuestion == E_BLOCK_COBBLESTONE_WALL) || - (BlockInQuestion == E_BLOCK_STONE_SLAB) || - (BlockInQuestion == E_BLOCK_WOODEN_SLAB) - ) - { - // Torches can be placed on tops of glass and fences, despite them being 'untorcheable' - // No need to check for upright orientation, it was done when the torch was placed - return true; - } - else if (!cBlockInfo::FullyOccupiesVoxel(BlockInQuestion)) + NIBBLETYPE BlockInQuestionMeta; + if (!a_Chunk.UnboundedRelGetBlock(a_RelX, a_RelY, a_RelZ, BlockInQuestion, BlockInQuestionMeta)) { return false; } - else - { - return true; - } + + return CanBePlacedOn(BlockInQuestion, BlockInQuestionMeta, Face); } |