summaryrefslogtreecommitdiffstats
path: root/src/Blocks/BlockTorch.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/Blocks/BlockTorch.h')
-rw-r--r--src/Blocks/BlockTorch.h112
1 files changed, 68 insertions, 44 deletions
diff --git a/src/Blocks/BlockTorch.h b/src/Blocks/BlockTorch.h
index 93ca5e40d..e2a2dfcc9 100644
--- a/src/Blocks/BlockTorch.h
+++ b/src/Blocks/BlockTorch.h
@@ -8,7 +8,7 @@
-class cBlockTorchHandler :
+class cBlockTorchHandler:
public cClearMetaOnDrop<cMetaRotator<cBlockHandler, 0x7, 0x4, 0x1, 0x3, 0x2>>
{
using Super = cClearMetaOnDrop<cMetaRotator<cBlockHandler, 0x7, 0x4, 0x1, 0x3, 0x2>>;
@@ -20,39 +20,46 @@ public:
{
}
+
+
+
+
virtual bool GetPlacementBlockTypeMeta(
- cChunkInterface & a_ChunkInterface, cPlayer & a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
- int a_CursorX, int a_CursorY, int a_CursorZ,
+ cChunkInterface & a_ChunkInterface,
+ cPlayer & a_Player,
+ const Vector3i a_PlacedBlockPos,
+ eBlockFace a_ClickedBlockFace,
+ const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{
- 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 (!CanBePlacedOn(Block, Meta, a_BlockFace)) // Try to preserve original direction
+ BLOCKTYPE ClickedBlockType;
+ NIBBLETYPE ClickedBlockMeta;
+ auto ClickedBlockPos = AddFaceDirection(a_PlacedBlockPos, a_ClickedBlockFace, true);
+ a_ChunkInterface.GetBlockTypeMeta(ClickedBlockPos, ClickedBlockType, ClickedBlockMeta);
+ if (!CanBePlacedOn(ClickedBlockType, ClickedBlockMeta, a_ClickedBlockFace))
{
- // 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)
+ // Couldn't be placed on whatever face was clicked, last ditch resort - find another face
+ a_ClickedBlockFace = FindSuitableFace(a_ChunkInterface, a_PlacedBlockPos); // Set a_BlockFace to a valid direction which will be converted later to a metadata
+ if (a_ClickedBlockFace == BLOCK_FACE_NONE)
{
// No attachable face found - don't place the torch
return false;
}
}
-
a_BlockType = m_BlockType;
- a_BlockMeta = DirectionToMetaData(a_BlockFace);
+ a_BlockMeta = BlockFaceToMetaData(a_ClickedBlockFace);
return true;
}
- inline static NIBBLETYPE DirectionToMetaData(eBlockFace a_Direction)
+
+
+
+
+ /** Converts the block face of the neighbor to which the torch is attached, to the torch block's meta. */
+ inline static NIBBLETYPE BlockFaceToMetaData(eBlockFace a_NeighborBlockFace)
{
- switch (a_Direction)
+ switch (a_NeighborBlockFace)
{
case BLOCK_FACE_BOTTOM: ASSERT(!"Shouldn't be getting this face"); return 0;
case BLOCK_FACE_TOP: return E_META_TORCH_FLOOR;
@@ -69,7 +76,12 @@ public:
return 0x0;
}
- inline static eBlockFace MetaDataToDirection(NIBBLETYPE a_MetaData)
+
+
+
+
+ /** Converts the torch block's meta to the block face of the neighbor to which the torch is attached. */
+ inline static eBlockFace MetaDataToBlockFace(NIBBLETYPE a_MetaData)
{
switch (a_MetaData)
{
@@ -88,6 +100,11 @@ public:
return BLOCK_FACE_TOP;
}
+
+
+
+
+ /** Returns true if the torch can be placed on the specified block's face. */
static bool CanBePlacedOn(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, eBlockFace a_BlockFace)
{
switch (a_BlockType)
@@ -115,7 +132,7 @@ public:
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
+ // Toches can be placed only on the top of top-half-slabs
return ((a_BlockFace == BLOCK_FACE_YP) && ((a_BlockMeta & 0x08) == 0x08));
}
case E_BLOCK_OAK_WOOD_STAIRS:
@@ -146,45 +163,52 @@ public:
}
}
- /** Finds a suitable face to place the torch, returning BLOCK_FACE_NONE on failure */
- static eBlockFace FindSuitableFace(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ)
+
+
+
+
+ /** Returns a suitable neighbor's blockface to place the torch at the specified pos
+ Returns BLOCK_FACE_NONE on failure */
+ static eBlockFace FindSuitableFace(cChunkInterface & a_ChunkInterface, const Vector3i a_TorchPos)
{
- for (int i = BLOCK_FACE_YM; i <= BLOCK_FACE_XP; i++) // Loop through all directions
+ for (int i = BLOCK_FACE_YM; i <= BLOCK_FACE_XP; i++) // Loop through all faces
{
- eBlockFace Face = static_cast<eBlockFace>(i);
- AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, Face, true);
- BLOCKTYPE BlockInQuestion;
- NIBBLETYPE BlockInQuestionMeta;
- a_ChunkInterface.GetBlockTypeMeta({a_BlockX, a_BlockY, a_BlockZ}, BlockInQuestion, BlockInQuestionMeta);
-
- if (CanBePlacedOn(BlockInQuestion, BlockInQuestionMeta, Face))
+ auto Face = static_cast<eBlockFace>(i);
+ auto NeighborPos = AddFaceDirection(a_TorchPos, Face, true);
+ BLOCKTYPE NeighborBlockType;
+ NIBBLETYPE NeighborBlockMeta;
+ a_ChunkInterface.GetBlockTypeMeta(NeighborPos, NeighborBlockType, NeighborBlockMeta);
+ if (CanBePlacedOn(NeighborBlockType, NeighborBlockMeta, Face))
{
return Face;
}
- else
- {
- // Reset coords in preparation for next iteration
- AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, Face, false);
- }
}
return BLOCK_FACE_NONE;
}
- 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;
- NIBBLETYPE BlockInQuestionMeta;
- if (!a_Chunk.UnboundedRelGetBlock(a_RelX, a_RelY, a_RelZ, BlockInQuestion, BlockInQuestionMeta))
+
+
+
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override
+ {
+ auto Face = MetaDataToBlockFace(a_Chunk.GetMeta(a_RelPos));
+ auto NeighborRelPos = AddFaceDirection(a_RelPos, Face, true);
+ BLOCKTYPE NeighborBlockType;
+ NIBBLETYPE NeighborBlockMeta;
+ if (!a_Chunk.UnboundedRelGetBlock(NeighborRelPos, NeighborBlockType, NeighborBlockMeta))
{
+ // Neighbor in an unloaded chunk, bail out without changint this.
return false;
}
- return CanBePlacedOn(BlockInQuestion, BlockInQuestionMeta, Face);
+ return CanBePlacedOn(NeighborBlockType, NeighborBlockMeta, Face);
}
+
+
+
+
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
{
UNUSED(a_Meta);