diff options
Diffstat (limited to '')
-rw-r--r-- | src/Blocks/BlockVine.h | 113 |
1 files changed, 90 insertions, 23 deletions
diff --git a/src/Blocks/BlockVine.h b/src/Blocks/BlockVine.h index f5716c58a..53224a5db 100644 --- a/src/Blocks/BlockVine.h +++ b/src/Blocks/BlockVine.h @@ -9,12 +9,19 @@ class cBlockVineHandler : public cBlockHandler { + using super = cBlockHandler; + public: - cBlockVineHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) + + cBlockVineHandler(BLOCKTYPE a_BlockType): + super(a_BlockType) { } + + + + virtual bool GetPlacementBlockTypeMeta( cChunkInterface & a_ChunkInterface, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, @@ -38,12 +45,24 @@ public: return true; } - virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + + + + + virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override { - // Reset meta to zero - a_Pickups.push_back(cItem(E_BLOCK_VINES, 1, 0)); + // Only drops self when using shears, otherwise drops nothing: + if ((a_Tool == nullptr) || (a_Tool->m_ItemType != E_ITEM_SHEARS)) + { + return {}; + } + return cItem(E_BLOCK_VINES, 1, 0); } + + + + static NIBBLETYPE DirectionToMetaData(char a_BlockFace) { switch (a_BlockFace) @@ -56,6 +75,10 @@ public: } } + + + + static char MetaDataToDirection(NIBBLETYPE a_MetaData) { switch (a_MetaData) @@ -68,6 +91,10 @@ public: } } + + + + /** Returns true if the specified block type is good for vines to attach to */ static bool IsBlockAttachable(BLOCKTYPE a_BlockType) { @@ -94,8 +121,12 @@ public: } } + + + + /** Returns the meta that has the maximum allowable sides of the vine, given the surroundings */ - NIBBLETYPE GetMaxMeta(cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) + NIBBLETYPE GetMaxMeta(cChunk & a_Chunk, Vector3i a_RelPos) { static const struct { @@ -113,8 +144,9 @@ public: { BLOCKTYPE BlockType; NIBBLETYPE BlockMeta; + auto checkPos = a_RelPos.addedXZ(Coord.x, Coord.z); if ( - a_Chunk.UnboundedRelGetBlock(a_RelX + Coord.x, a_RelY, a_RelZ + Coord.z, BlockType, BlockMeta) && + a_Chunk.UnboundedRelGetBlock(checkPos.x, checkPos.y, checkPos.z, BlockType, BlockMeta) && IsBlockAttachable(BlockType) ) { @@ -124,55 +156,71 @@ public: return res; } - void Check(cChunkInterface & a_ChunkInterface, cBlockPluginInterface & a_PluginInterface, int a_RelX, int a_RelY, int a_RelZ, cChunk & a_Chunk) override + + + + + virtual void Check( + cChunkInterface & a_ChunkInterface, cBlockPluginInterface & a_PluginInterface, + Vector3i a_RelPos, + cChunk & a_Chunk + ) override { - NIBBLETYPE CurMeta = a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ); - NIBBLETYPE MaxMeta = GetMaxMeta(a_Chunk, a_RelX, a_RelY, a_RelZ); + NIBBLETYPE CurMeta = a_Chunk.GetMeta(a_RelPos); + NIBBLETYPE MaxMeta = GetMaxMeta(a_Chunk, a_RelPos); // Check if vine above us, add its meta to MaxMeta - if ((a_RelY < cChunkDef::Height - 1) && (a_Chunk.GetBlock(a_RelX, a_RelY + 1, a_RelZ) == m_BlockType)) + if ((a_RelPos.y < cChunkDef::Height - 1) && (a_Chunk.GetBlock(a_RelPos.addedY(1)) == m_BlockType)) { - MaxMeta |= a_Chunk.GetMeta(a_RelX, a_RelY + 1, a_RelZ); + MaxMeta |= a_Chunk.GetMeta(a_RelPos.addedY(1)); } NIBBLETYPE Common = CurMeta & MaxMeta; // Neighbors that we have and are legal if (Common != CurMeta) { // There is a neighbor missing, need to update the meta or even destroy the block - bool HasTop = (a_RelY < cChunkDef::Height - 1) && IsBlockAttachable(a_Chunk.GetBlock(a_RelX, a_RelY + 1, a_RelZ)); + bool HasTop = (a_RelPos.y < cChunkDef::Height - 1) && IsBlockAttachable(a_Chunk.GetBlock(a_RelPos.addedY(1))); if ((Common == 0) && !HasTop) { // The vine just lost all its support, destroy the block: if (DoesDropOnUnsuitable()) { - int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width; - int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width; - DropBlock(a_ChunkInterface, *a_Chunk.GetWorld(), a_PluginInterface, nullptr, BlockX, a_RelY, BlockZ); + a_ChunkInterface.DropBlockAsPickups(a_Chunk.RelativeToAbsolute(a_RelPos)); } - a_Chunk.SetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_AIR, 0); + a_Chunk.SetBlock(a_RelPos, E_BLOCK_AIR, 0); return; } - a_Chunk.SetBlock(a_RelX, a_RelY, a_RelZ, m_BlockType, Common); + a_Chunk.SetBlock(a_RelPos, m_BlockType, Common); } else { - // Wake up the simulators for this block: - int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width; - int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width; - a_Chunk.GetWorld()->GetSimulatorManager()->WakeUp({BlockX, a_RelY, BlockZ}, &a_Chunk); + auto absPos = a_Chunk.RelativeToAbsolute(a_RelPos); + a_Chunk.GetWorld()->GetSimulatorManager()->WakeUp(absPos, &a_Chunk); } } + + + + virtual bool DoesIgnoreBuildCollision(cChunkInterface & a_ChunkInterface, Vector3i a_Pos, cPlayer & a_Player, NIBBLETYPE a_Meta) override { return true; } + + + + virtual bool DoesDropOnUnsuitable(void) override { return false; } + + + + virtual void OnUpdate(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_BlockPluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override { UNUSED(a_ChunkInterface); @@ -196,34 +244,53 @@ public: } } + + + + virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override { return ((a_Meta >> 1) | (a_Meta << 3)) & 0x0f; // Rotate bits to the right } + + + + virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override { return ((a_Meta << 1) | (a_Meta >> 3)) & 0x0f; // Rotate bits to the left } + + + + virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override { // Bits 2 and 4 stay, bits 1 and 3 swap return static_cast<NIBBLETYPE>((a_Meta & 0x0a) | ((a_Meta & 0x01) << 2) | ((a_Meta & 0x04) >> 2)); } + + + + virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override { // Bits 1 and 3 stay, bits 2 and 4 swap return static_cast<NIBBLETYPE>((a_Meta & 0x05) | ((a_Meta & 0x02) << 2) | ((a_Meta & 0x08) >> 2)); } + + + + virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override { UNUSED(a_Meta); return 7; } - } ; |