diff options
author | Mattes D <github@xoft.cz> | 2013-11-30 16:20:27 +0100 |
---|---|---|
committer | Mattes D <github@xoft.cz> | 2013-11-30 16:20:27 +0100 |
commit | 2bbe5046e9d2119f2751af01cbce3185ee9514ed (patch) | |
tree | 059a36e4c22c22b1f6d591bc02ade598153015b4 /src | |
parent | Changed cBlockHandler->OnUpdate() to use cChunk directly. (diff) | |
parent | Fixed pistons extending (diff) | |
download | cuberite-2bbe5046e9d2119f2751af01cbce3185ee9514ed.tar cuberite-2bbe5046e9d2119f2751af01cbce3185ee9514ed.tar.gz cuberite-2bbe5046e9d2119f2751af01cbce3185ee9514ed.tar.bz2 cuberite-2bbe5046e9d2119f2751af01cbce3185ee9514ed.tar.lz cuberite-2bbe5046e9d2119f2751af01cbce3185ee9514ed.tar.xz cuberite-2bbe5046e9d2119f2751af01cbce3185ee9514ed.tar.zst cuberite-2bbe5046e9d2119f2751af01cbce3185ee9514ed.zip |
Diffstat (limited to 'src')
-rw-r--r-- | src/BlockID.h | 5 | ||||
-rw-r--r-- | src/Blocks/BlockButton.cpp | 32 | ||||
-rw-r--r-- | src/Blocks/BlockButton.h | 26 | ||||
-rw-r--r-- | src/Blocks/BlockComparator.cpp | 53 | ||||
-rw-r--r-- | src/Blocks/BlockComparator.h | 24 | ||||
-rw-r--r-- | src/Blocks/BlockHandler.cpp | 2 | ||||
-rw-r--r-- | src/Blocks/BlockHandler.h | 27 | ||||
-rw-r--r-- | src/Blocks/BlockLever.cpp | 31 | ||||
-rw-r--r-- | src/Blocks/BlockLever.h | 14 | ||||
-rw-r--r-- | src/Blocks/BlockRedstone.cpp | 27 | ||||
-rw-r--r-- | src/Blocks/BlockRedstone.h | 7 | ||||
-rw-r--r-- | src/Blocks/BlockRedstoneRepeater.cpp | 50 | ||||
-rw-r--r-- | src/Blocks/BlockRedstoneRepeater.h | 33 | ||||
-rw-r--r-- | src/Blocks/BlockSnow.h | 42 | ||||
-rw-r--r-- | src/Blocks/BlockStairs.h | 24 | ||||
-rw-r--r-- | src/Blocks/BlockStems.h | 1 | ||||
-rw-r--r-- | src/Blocks/BlockTrapdoor.h | 108 | ||||
-rw-r--r-- | src/ClientHandle.cpp | 23 | ||||
-rw-r--r-- | src/Simulator/RedstoneSimulator.cpp | 228 | ||||
-rw-r--r-- | src/Simulator/RedstoneSimulator.h | 4 |
20 files changed, 431 insertions, 330 deletions
diff --git a/src/BlockID.h b/src/BlockID.h index e5f49fe2c..9742e9745 100644 --- a/src/BlockID.h +++ b/src/BlockID.h @@ -174,7 +174,7 @@ enum ENUM_BLOCK_ID E_BLOCK_NEW_LEAVES = 161, // Acacia and Dark Oak IDs in Minecraft 1.7.x E_BLOCK_NEW_LOG = 162, E_BLOCK_ACACIA_WOOD_STAIRS = 163, - E_BLOCK_DARK_OAK_WOOD_STAIRS = 164, ///////////////////////////////// + E_BLOCK_DARK_OAK_WOOD_STAIRS = 164, E_BLOCK_HAY_BALE = 170, E_BLOCK_CARPET = 171, E_BLOCK_HARDENED_CLAY = 172, @@ -187,8 +187,7 @@ enum ENUM_BLOCK_ID E_BLOCK_NUMBER_OF_TYPES, ///< Number of individual (different) blocktypes E_BLOCK_MAX_TYPE_ID = E_BLOCK_NUMBER_OF_TYPES - 1, ///< Maximum BlockType number used - // Synonym or ID compatibility - + // Synonym or ID compatibility E_BLOCK_YELLOW_FLOWER = E_BLOCK_DANDELION, E_BLOCK_RED_ROSE = E_BLOCK_FLOWER, E_BLOCK_LOCKED_CHEST = E_BLOCK_STAINED_GLASS, diff --git a/src/Blocks/BlockButton.cpp b/src/Blocks/BlockButton.cpp deleted file mode 100644 index a48e82f4d..000000000 --- a/src/Blocks/BlockButton.cpp +++ /dev/null @@ -1,32 +0,0 @@ - -#include "Globals.h" -#include "BlockButton.h" - - - - - -cBlockButtonHandler::cBlockButtonHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) -{ -} - - - - - -void cBlockButtonHandler::OnUse(cWorld *a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) -{ - // Flip the ON bit on/off using the XOR bitwise operation - NIBBLETYPE Meta = (a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) | 0x08); - - a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, Meta); - a_World->BroadcastSoundEffect("random.click", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, (Meta & 0x08) ? 0.6f : 0.5f); - - // Queue a button reset (unpress) - a_World->QueueSetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, (a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) & 0x07), m_BlockType == E_BLOCK_STONE_BUTTON ? 20 : 30); -} - - - - diff --git a/src/Blocks/BlockButton.h b/src/Blocks/BlockButton.h index e2c60002b..ec897835a 100644 --- a/src/Blocks/BlockButton.h +++ b/src/Blocks/BlockButton.h @@ -10,9 +10,23 @@ class cBlockButtonHandler : public cBlockHandler { public: - cBlockButtonHandler(BLOCKTYPE a_BlockType); + cBlockButtonHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + - virtual void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override; + virtual void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override + { + // Flip the ON bit on/off using the XOR bitwise operation + NIBBLETYPE Meta = (a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) | 0x08); + + a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta); + a_World->BroadcastSoundEffect("random.click", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, (Meta & 0x08) ? 0.6f : 0.5f); + + // Queue a button reset (unpress) + a_World->QueueSetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, (a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) & 0x07), m_BlockType == E_BLOCK_STONE_BUTTON ? 20 : 30); + } virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override @@ -51,10 +65,10 @@ public: { switch (a_BlockFace) { - case BLOCK_FACE_ZM: { return 0x4; } - case BLOCK_FACE_ZP: { return 0x3; } - case BLOCK_FACE_XM: { return 0x2; } - case BLOCK_FACE_XP: { return 0x1; } + case BLOCK_FACE_ZM: return 0x4; + case BLOCK_FACE_ZP: return 0x3; + case BLOCK_FACE_XM: return 0x2; + case BLOCK_FACE_XP: return 0x1; default: { ASSERT(!"Unhandled block face!"); diff --git a/src/Blocks/BlockComparator.cpp b/src/Blocks/BlockComparator.cpp deleted file mode 100644 index 8bc0ac5ac..000000000 --- a/src/Blocks/BlockComparator.cpp +++ /dev/null @@ -1,53 +0,0 @@ - -#include "Globals.h" -#include "BlockComparator.h" -#include "BlockRedstoneRepeater.h" -#include "../Entities/Player.h" - - - - - -cBlockComparatorHandler::cBlockComparatorHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) -{ -} - - - - - -void cBlockComparatorHandler::OnDestroyed(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ) -{ - // Nothing needed yet -} - - - - - -void cBlockComparatorHandler::OnUse(cWorld *a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) -{ - NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - Meta ^= 0x04; // Toggle 3rd (addition/subtraction) bit with XOR - a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta); -} - - - - -bool cBlockComparatorHandler::GetPlacementBlockTypeMeta( - cWorld * a_World, cPlayer * a_Player, - int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, - int a_CursorX, int a_CursorY, int a_CursorZ, - BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta -) -{ - a_BlockType = m_BlockType; - a_BlockMeta = cBlockRedstoneRepeaterHandler::RepeaterRotationToMetaData(a_Player->GetRotation()); - return true; -} - - - - diff --git a/src/Blocks/BlockComparator.h b/src/Blocks/BlockComparator.h index cb2941d3c..e7e18bac9 100644 --- a/src/Blocks/BlockComparator.h +++ b/src/Blocks/BlockComparator.h @@ -2,6 +2,7 @@ #pragma once #include "BlockHandler.h" +#include "BlockRedstoneRepeater.h" @@ -11,10 +12,18 @@ class cBlockComparatorHandler : public cBlockHandler { public: - cBlockComparatorHandler(BLOCKTYPE a_BlockType); - virtual void OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override; + cBlockComparatorHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + - virtual void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override; + virtual void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override + { + NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); + Meta ^= 0x04; // Toggle 3rd (addition/subtraction) bit with XOR + a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta); + } virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override @@ -38,10 +47,15 @@ public: virtual bool GetPlacementBlockTypeMeta( cWorld * a_World, cPlayer * a_Player, - int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, + int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta - ) override; + ) override + { + a_BlockType = m_BlockType; + a_BlockMeta = cBlockRedstoneRepeaterHandler::RepeaterRotationToMetaData(a_Player->GetRotation()); + return true; + } virtual const char * GetStepSound(void) override diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index 3448cf8a1..7bb35efeb 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -61,6 +61,7 @@ #include "BlockSugarcane.h" #include "BlockTallGrass.h" #include "BlockTorch.h" +#include "BlockTrapdoor.h" #include "BlockVine.h" #include "BlockWood.h" #include "BlockWorkbench.h" @@ -193,6 +194,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) case E_BLOCK_SUGARCANE: return new cBlockSugarcaneHandler (a_BlockType); case E_BLOCK_TALL_GRASS: return new cBlockTallGrassHandler (a_BlockType); case E_BLOCK_TORCH: return new cBlockTorchHandler (a_BlockType); + case E_BLOCK_TRAPDOOR: return new cBlockTrapdoorHandler (a_BlockType); case E_BLOCK_VINES: return new cBlockVineHandler (a_BlockType); case E_BLOCK_WALLSIGN: return new cBlockSignHandler (a_BlockType); case E_BLOCK_WATER: return new cBlockFluidHandler (a_BlockType); diff --git a/src/Blocks/BlockHandler.h b/src/Blocks/BlockHandler.h index 80dccd8c7..107d36476 100644 --- a/src/Blocks/BlockHandler.h +++ b/src/Blocks/BlockHandler.h @@ -98,7 +98,10 @@ public: */ virtual bool DoesIgnoreBuildCollision(void); - /// Does this block drop if it gets destroyed by an unsuitable situation? Default: true + /// <summary>Similar to DoesIgnoreBuildCollision(void), but is used for cases where block meta/player item-in-hand is needed to determine collision (thin snow)</summary> + virtual bool DoesIgnoreBuildCollision(cPlayer * a_Player, NIBBLETYPE a_Meta) { return DoesIgnoreBuildCollision(); } + + /// <summary>Returns if this block drops if it gets destroyed by an unsuitable situation. Default: true</summary> virtual bool DoesDropOnUnsuitable(void); /** Called when one of the neighbors gets set; equivalent to MC block update. @@ -107,26 +110,30 @@ public: */ virtual void Check(int a_RelX, int a_RelY, int a_RelZ, cChunk & a_Chunk); - /// Returns the meta for a block after rotating it counter-clockwise from the specified meta. Default: no change + /// <summary>Rotates a given block meta counter-clockwise. Default: no change</summary> + /// <returns>Block meta following rotation</returns> virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) { return a_Meta; } - /// Returns the meta for a block after rotating it clockwise from the specified meta. Default: no change + /// <summary>Rotates a given block meta clockwise. Default: no change</summary> + /// <returns>Block meta following rotation</returns> virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) { return a_Meta; } - /// Returns the meta for a block after mirroring it around the XY plane. Default: no change + /// <summary>Mirros a given block meta around the XY plane. Default: no change</summary> + /// <returns>Block meta following mirroring</returns> virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) { return a_Meta; } - /// Returns the meta for a block after mirroring it around the XZ plane. Default: no change + /// <summary>Mirros a given block meta around the XZ plane. Default: no change</summary> + /// <returns>Block meta following mirroring</returns> virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) { return a_Meta; } - /// Returns the meta for a block after mirroring it around the YZ plane. Default: no change + /// <summary>Mirros a given block meta around the YZ plane. Default: no change</summary> + /// <returns>Block meta following mirroring</returns> virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) { return a_Meta; } - - - /// Get the blockhandler for a specific block id + + /// <summary>Get the blockhandler for a specific block id</summary> static cBlockHandler * GetBlockHandler(BLOCKTYPE a_BlockType); - /// Deletes all initialised block handlers + /// <summary>Deletes all initialised block handlers</summary> static void Deinit(); protected: diff --git a/src/Blocks/BlockLever.cpp b/src/Blocks/BlockLever.cpp deleted file mode 100644 index c482b0246..000000000 --- a/src/Blocks/BlockLever.cpp +++ /dev/null @@ -1,31 +0,0 @@ - -#include "Globals.h" -#include "BlockLever.h" -#include "../Entities/Player.h" -#include "../Simulator/RedstoneSimulator.h" - - - - - -cBlockLeverHandler::cBlockLeverHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) -{ -} - - - - - -void cBlockLeverHandler::OnUse(cWorld *a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) -{ - // Flip the ON bit on/off using the XOR bitwise operation - NIBBLETYPE Meta = (a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) ^ 0x08); - - a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, Meta); - a_World->BroadcastSoundEffect("random.click", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, (Meta & 0x08) ? 0.6f : 0.5f); -} - - - - diff --git a/src/Blocks/BlockLever.h b/src/Blocks/BlockLever.h index 5e6a3bd1e..15fe2071c 100644 --- a/src/Blocks/BlockLever.h +++ b/src/Blocks/BlockLever.h @@ -10,9 +10,19 @@ class cBlockLeverHandler : public cBlockHandler { public: - cBlockLeverHandler(BLOCKTYPE a_BlockType); + cBlockLeverHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } - virtual void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override; + virtual void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override + { + // Flip the ON bit on/off using the XOR bitwise operation + NIBBLETYPE Meta = (a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) ^ 0x08); + + a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta); + a_World->BroadcastSoundEffect("random.click", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, (Meta & 0x08) ? 0.6f : 0.5f); + } virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override diff --git a/src/Blocks/BlockRedstone.cpp b/src/Blocks/BlockRedstone.cpp deleted file mode 100644 index 35cdc34cf..000000000 --- a/src/Blocks/BlockRedstone.cpp +++ /dev/null @@ -1,27 +0,0 @@ - -#include "Globals.h" -#include "BlockRedstone.h" -#include "../Item.h" -#include "../World.h" - - - - - -cBlockRedstoneHandler::cBlockRedstoneHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) -{ -} - - - - - -void cBlockRedstoneHandler::OnDestroyed(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ) -{ - // Nothing needed yet -} - - - - diff --git a/src/Blocks/BlockRedstone.h b/src/Blocks/BlockRedstone.h index f28f3f2d6..57bd91b46 100644 --- a/src/Blocks/BlockRedstone.h +++ b/src/Blocks/BlockRedstone.h @@ -12,9 +12,10 @@ class cBlockRedstoneHandler : public cBlockHandler { public: - cBlockRedstoneHandler(BLOCKTYPE a_BlockType); - - virtual void OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override; + cBlockRedstoneHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override diff --git a/src/Blocks/BlockRedstoneRepeater.cpp b/src/Blocks/BlockRedstoneRepeater.cpp deleted file mode 100644 index 3ab5bc559..000000000 --- a/src/Blocks/BlockRedstoneRepeater.cpp +++ /dev/null @@ -1,50 +0,0 @@ - -#include "Globals.h" -#include "BlockRedstoneRepeater.h" -#include "../Entities/Player.h" - - - - - -cBlockRedstoneRepeaterHandler::cBlockRedstoneRepeaterHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) -{ -} - - - - - -void cBlockRedstoneRepeaterHandler::OnDestroyed(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ) -{ - // Nothing needed yet -} - - - - - -void cBlockRedstoneRepeaterHandler::OnUse(cWorld *a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) -{ - a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, ((a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) + 0x04) & 0x0f)); -} - - - - -bool cBlockRedstoneRepeaterHandler::GetPlacementBlockTypeMeta( - cWorld * a_World, cPlayer * a_Player, - int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, - int a_CursorX, int a_CursorY, int a_CursorZ, - BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta -) -{ - a_BlockType = m_BlockType; - a_BlockMeta = RepeaterRotationToMetaData(a_Player->GetRotation()); - return true; -} - - - - diff --git a/src/Blocks/BlockRedstoneRepeater.h b/src/Blocks/BlockRedstoneRepeater.h index a61121d3a..1fcddd4f8 100644 --- a/src/Blocks/BlockRedstoneRepeater.h +++ b/src/Blocks/BlockRedstoneRepeater.h @@ -11,10 +11,29 @@ class cBlockRedstoneRepeaterHandler : public cBlockHandler { public: - cBlockRedstoneRepeaterHandler(BLOCKTYPE a_BlockType); - virtual void OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override; + cBlockRedstoneRepeaterHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + + virtual bool GetPlacementBlockTypeMeta( + cWorld * a_World, cPlayer * a_Player, + int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, + int a_CursorX, int a_CursorY, int a_CursorZ, + BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta + ) override + { + a_BlockType = m_BlockType; + a_BlockMeta = RepeaterRotationToMetaData(a_Player->GetRotation()); + return true; + } - virtual void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override; + + virtual void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override + { + a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, ((a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) + 0x04) & 0x0f)); + } virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override @@ -34,14 +53,6 @@ public: { return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) != E_BLOCK_AIR)); } - - - virtual bool GetPlacementBlockTypeMeta( - cWorld * a_World, cPlayer * a_Player, - int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, - int a_CursorX, int a_CursorY, int a_CursorZ, - BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta - ) override; virtual const char * GetStepSound(void) override diff --git a/src/Blocks/BlockSnow.h b/src/Blocks/BlockSnow.h index b8d48362c..d7fd1e19e 100644 --- a/src/Blocks/BlockSnow.h +++ b/src/Blocks/BlockSnow.h @@ -25,21 +25,37 @@ public: ) override { a_BlockType = m_BlockType; - NIBBLETYPE Meta = a_World->GetBlockMeta(Vector3i(a_BlockX, a_BlockY, a_BlockZ)); - if ((Meta < 7) && (Meta != 0)) // Is height at maximum (7) or at mininum (0)? Don't do anything if so + BLOCKTYPE BlockBeforePlacement; + NIBBLETYPE MetaBeforePlacement; + a_World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, BlockBeforePlacement, MetaBeforePlacement); + + if ((BlockBeforePlacement == E_BLOCK_SNOW) && (MetaBeforePlacement < 7)) { - Meta++; + // Only increment if: + // A snow block was already there (not first time placement) AND + // Height is smaller than 7, the maximum possible height + MetaBeforePlacement++; } - a_BlockMeta = Meta; + a_BlockMeta = MetaBeforePlacement; return true; } - virtual bool DoesIgnoreBuildCollision(void) override + virtual bool DoesIgnoreBuildCollision(cPlayer * a_Player, NIBBLETYPE a_Meta) override { - return true; + if ((a_Player->GetEquippedItem().m_ItemType == E_BLOCK_SNOW) && (a_Meta < 7)) + { + return true; // If a player is holding a (thin) snow block and it's size can be increased, return collision ignored + } + + if (a_Meta == 0) + { + return true; // If at normal snowfall height (lowest), we ignore collision + } + + return false; } @@ -51,7 +67,19 @@ public: virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { - return (a_RelY > 0) && g_BlockIsSnowable[a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)]; + if (a_RelY > 0) + { + BLOCKTYPE BlockBelow = a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ); + NIBBLETYPE MetaBelow = a_Chunk.GetMeta(a_RelX, a_RelY - 1, a_RelZ); + + if (g_BlockIsSnowable[BlockBelow] || ((BlockBelow == E_BLOCK_SNOW) && (MetaBelow == 7))) + { + // If block below is snowable, or it is a thin slow block and has a meta of 7 (full thin snow block), say yay + return true; + } + } + + return false; } diff --git a/src/Blocks/BlockStairs.h b/src/Blocks/BlockStairs.h index 8d259eee3..fa378e4b5 100644 --- a/src/Blocks/BlockStairs.h +++ b/src/Blocks/BlockStairs.h @@ -47,8 +47,28 @@ public: return true; } - // TODO: step sound - + virtual const char * GetStepSound(void) override + { + if ( + (m_BlockType == E_BLOCK_WOODEN_STAIRS) || + (m_BlockType == E_BLOCK_SPRUCE_WOOD_STAIRS) || + (m_BlockType == E_BLOCK_JUNGLE_WOOD_STAIRS) || + (m_BlockType == E_BLOCK_ACACIA_WOOD_STAIRS) || + (m_BlockType == E_BLOCK_BIRCH_WOOD_STAIRS) || + (m_BlockType == E_BLOCK_DARK_OAK_WOOD_STAIRS) + ) + { + return "step.wood"; + } + + return "step.stone"; + } + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + // Reset meta to 0 + a_Pickups.push_back(cItem(m_BlockType, 1, 0)); + } static NIBBLETYPE RotationToMetaData(double a_Rotation) { diff --git a/src/Blocks/BlockStems.h b/src/Blocks/BlockStems.h index e17f2ea3d..c2dff62cf 100644 --- a/src/Blocks/BlockStems.h +++ b/src/Blocks/BlockStems.h @@ -2,7 +2,6 @@ #pragma once #include "BlockHandler.h" -#include "../MersenneTwister.h" #include "../World.h" diff --git a/src/Blocks/BlockTrapdoor.h b/src/Blocks/BlockTrapdoor.h new file mode 100644 index 000000000..58d770d23 --- /dev/null +++ b/src/Blocks/BlockTrapdoor.h @@ -0,0 +1,108 @@ + +#pragma once + +#include "BlockHandler.h" + + + + + +class cBlockTrapdoorHandler : + public cBlockHandler +{ +public: + cBlockTrapdoorHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + virtual const char * GetStepSound(void) override + { + return "step.wood"; + } + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + // Reset meta to 0 + a_Pickups.push_back(cItem(m_BlockType, 1, 0)); + } + + virtual bool IsUseable(void) override + { + return true; + } + + void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) + { + // Flip the ON bit on/off using the XOR bitwise operation + NIBBLETYPE Meta = (a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) ^ 0x04); + + a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta); + } + + virtual bool GetPlacementBlockTypeMeta( + cWorld * a_World, cPlayer * a_Player, + int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, + int a_CursorX, int a_CursorY, int a_CursorZ, + BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta + ) override + { + a_BlockType = m_BlockType; + a_BlockMeta = BlockFaceToMetaData(a_BlockFace); + + /* TODO: fix CursorY issues and uncomment this + if (a_CursorY > 7) + { + a_BlockMeta |= 0x8; + } + */ + return true; + } + + inline static NIBBLETYPE BlockFaceToMetaData(char a_BlockFace) + { + switch (a_BlockFace) + { + case BLOCK_FACE_ZP: return 0x1; + case BLOCK_FACE_ZM: return 0x0; + case BLOCK_FACE_XP: return 0x3; + case BLOCK_FACE_XM: return 0x2; + default: + { + ASSERT(!"Unhandled block face!"); + return 0x0; + } + } + } + + inline static NIBBLETYPE BlockMetaDataToBlockFace(NIBBLETYPE a_Meta) + { + switch (a_Meta & 0x3) + { + case 0x0: return BLOCK_FACE_ZM; + case 0x1: return BLOCK_FACE_ZP; + case 0x2: return BLOCK_FACE_XM; + case 0x3: return BLOCK_FACE_XP; + default: + { + ASSERT(!"Unhandled block meta!"); + return BLOCK_FACE_NONE; + } + } + } + + virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override + { + NIBBLETYPE Meta; + a_Chunk.UnboundedRelGetBlockMeta(a_RelX, a_RelY, a_RelZ, Meta); + + AddFaceDirection(a_RelX, a_RelY, a_RelZ, BlockMetaDataToBlockFace(Meta), true); + BLOCKTYPE BlockIsOn; a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockIsOn); + + return (a_RelY > 0) && (g_BlockIsSolid[BlockIsOn]); + } +}; + + + + diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index b3e12ce77..f9a48003e 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -891,14 +891,14 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, c else { // Check if the block ignores build collision (water, grass etc.): - cBlockHandler * Handler = cBlockHandler::GetBlockHandler(ClickedBlock); - if (Handler->DoesIgnoreBuildCollision()) + if ( + BlockHandler(ClickedBlock)->DoesIgnoreBuildCollision() || + BlockHandler(ClickedBlock)->DoesIgnoreBuildCollision(m_Player, ClickedBlockMeta) + ) { - Handler->OnDestroyedByPlayer(World, m_Player, a_BlockX, a_BlockY, a_BlockZ); + BlockHandler(ClickedBlock)->OnDestroyedByPlayer(World, m_Player, a_BlockX, a_BlockY, a_BlockZ); } - - BLOCKTYPE PlaceBlock = World->GetBlock(a_BlockX, a_BlockY, a_BlockZ); - if (!BlockHandler(PlaceBlock)->DoesIgnoreBuildCollision()) + else { AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); @@ -908,7 +908,9 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, c return; } - BLOCKTYPE PlaceBlock = World->GetBlock(a_BlockX, a_BlockY, a_BlockZ); + NIBBLETYPE PlaceMeta; + BLOCKTYPE PlaceBlock; + World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, PlaceBlock, PlaceMeta); // Clicked on side of block, make sure that placement won't be cancelled if there is a slab able to be double slabbed. // No need to do combinability (dblslab) checks, client will do that here. @@ -918,10 +920,13 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, c } else { - if (!BlockHandler(PlaceBlock)->DoesIgnoreBuildCollision()) + if ( + !BlockHandler(PlaceBlock)->DoesIgnoreBuildCollision() && + !BlockHandler(PlaceBlock)->DoesIgnoreBuildCollision(m_Player, PlaceMeta) + ) { // Tried to place a block *into* another? - // Happens when you place a block aiming at side of block like torch or stem + // Happens when you place a block aiming at side of block with a torch on it or stem beside it return; } } diff --git a/src/Simulator/RedstoneSimulator.cpp b/src/Simulator/RedstoneSimulator.cpp index 81d4e26f6..c93741a0e 100644 --- a/src/Simulator/RedstoneSimulator.cpp +++ b/src/Simulator/RedstoneSimulator.cpp @@ -76,92 +76,100 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c int BaseX = a_Chunk->GetPosX() * cChunkDef::Width; int BaseZ = a_Chunk->GetPosZ() * cChunkDef::Width; - for (cRedstoneSimulatorChunkData::iterator dataitr = ChunkData.begin(), end = ChunkData.end(); dataitr != end;) + // Check to see if PoweredBlocks have invalid items (source is air or unpowered) + for (PoweredBlocksList::iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end();) { - BLOCKTYPE BlockType = a_Chunk->GetBlock(dataitr->x, dataitr->y, dataitr->z); - if (!IsAllowedBlock(BlockType)) + sPoweredBlocks & Change = *itr; + + int RelX = Change.a_SourcePos.x - a_ChunkX * cChunkDef::Width; + int RelZ = Change.a_SourcePos.z - a_ChunkZ * cChunkDef::Width; + + BLOCKTYPE SourceBlockType; + NIBBLETYPE SourceBlockMeta; + if (!a_Chunk->UnboundedRelGetBlock(RelX, Change.a_SourcePos.y, RelZ, SourceBlockType, SourceBlockMeta)) { - dataitr = ChunkData.erase(dataitr); continue; } - // Check to see if PoweredBlocks have invalid items (source is air or unpowered) - for (PoweredBlocksList::iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end();) + if (SourceBlockType != Change.a_SourceBlock) { - sPoweredBlocks & Change = *itr; + itr = m_PoweredBlocks.erase(itr); + LOGD("cRedstoneSimulator: Erased block %s from powered blocks list due to present/past block type mismatch", ItemToFullString(Change.a_SourceBlock)); + } + else if ( + // Changeable sources + ((SourceBlockType == E_BLOCK_REDSTONE_WIRE) && (SourceBlockMeta == 0)) || + ((SourceBlockType == E_BLOCK_LEVER) && !IsLeverOn(SourceBlockMeta)) || + ((SourceBlockType == E_BLOCK_DETECTOR_RAIL) && (SourceBlockMeta & 0x08) == 0x08) || + (((SourceBlockType == E_BLOCK_STONE_BUTTON) || (SourceBlockType == E_BLOCK_WOODEN_BUTTON)) && (!IsButtonOn(SourceBlockMeta))) + ) + { + itr = m_PoweredBlocks.erase(itr); + LOGD("cRedstoneSimulator: Erased block %s from powered blocks list due to present/past metadata mismatch", ItemToFullString(Change.a_SourceBlock)); + } + else + { + itr++; + } + } - int RelX = Change.a_SourcePos.x - a_ChunkX * cChunkDef::Width; - int RelZ = Change.a_SourcePos.z - a_ChunkZ * cChunkDef::Width; + // Check to see if LinkedPoweredBlocks have invalid items: source, block powered through, or power destination block has changed + for (LinkedBlocksList::iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end();) + { + sLinkedPoweredBlocks & Change = *itr; - BLOCKTYPE SourceBlockType; - NIBBLETYPE SourceBlockMeta; - a_Chunk->UnboundedRelGetBlock(RelX, Change.a_SourcePos.y, RelZ, SourceBlockType, SourceBlockMeta); + int RelX = Change.a_SourcePos.x - a_ChunkX * cChunkDef::Width; + int RelZ = Change.a_SourcePos.z - a_ChunkZ * cChunkDef::Width; + int MidRelX = Change.a_MiddlePos.x - a_ChunkX * cChunkDef::Width; + int MidRelZ = Change.a_MiddlePos.z - a_ChunkZ * cChunkDef::Width; - if (SourceBlockType != Change.a_SourceBlock) - { - itr = m_PoweredBlocks.erase(itr); - LOGD("cRedstoneSimulator: Erased block %s from powered blocks list due to present/past block type mismatch", ItemToFullString(Change.a_SourceBlock)); - } - else if ( - // Changeable sources - ((SourceBlockType == E_BLOCK_REDSTONE_WIRE) && (SourceBlockMeta == 0)) || - ((SourceBlockType == E_BLOCK_LEVER) && !IsLeverOn(SourceBlockMeta)) || - ((SourceBlockType == E_BLOCK_DETECTOR_RAIL) && (SourceBlockMeta & 0x08) == 0x08) || - (((SourceBlockType == E_BLOCK_STONE_BUTTON) || (SourceBlockType == E_BLOCK_WOODEN_BUTTON)) && (!IsButtonOn(SourceBlockMeta))) - ) - { - itr = m_PoweredBlocks.erase(itr); - LOGD("cRedstoneSimulator: Erased block %s from powered blocks list due to present/past metadata mismatch", ItemToFullString(Change.a_SourceBlock)); - } - else - { - itr++; - } + BLOCKTYPE SourceBlockType; + NIBBLETYPE SourceBlockMeta; + BLOCKTYPE MiddleBlockType; + if ( + !a_Chunk->UnboundedRelGetBlock(RelX, Change.a_SourcePos.y, RelZ, SourceBlockType, SourceBlockMeta) || + !a_Chunk->UnboundedRelGetBlockType(MidRelX, Change.a_MiddlePos.y, MidRelZ, MiddleBlockType) + ) + { + continue; } - // Check to see if LinkedPoweredBlocks have invalid items: source, block powered through, or power destination block has changed - for (LinkedBlocksList::iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end();) + if (SourceBlockType != Change.a_SourceBlock) { - sLinkedPoweredBlocks & Change = *itr; - - int RelX = Change.a_SourcePos.x - a_ChunkX * cChunkDef::Width; - int RelZ = Change.a_SourcePos.z - a_ChunkZ * cChunkDef::Width; - int MidRelX = Change.a_MiddlePos.x - a_ChunkX * cChunkDef::Width; - int MidRelZ = Change.a_MiddlePos.z - a_ChunkZ * cChunkDef::Width; - - BLOCKTYPE SourceBlockType; - NIBBLETYPE SourceBlockMeta; - BLOCKTYPE MiddleBlockType; - a_Chunk->UnboundedRelGetBlock(RelX, Change.a_SourcePos.y, RelZ, SourceBlockType, SourceBlockMeta); - a_Chunk->UnboundedRelGetBlockType(MidRelX, Change.a_MiddlePos.y, MidRelZ, MiddleBlockType); - - if (SourceBlockType != Change.a_SourceBlock) - { - itr = m_LinkedPoweredBlocks.erase(itr); - LOGD("cRedstoneSimulator: Erased block %s from linked powered blocks list due to present/past block type mismatch", ItemToFullString(Change.a_SourceBlock)); - } - else if (MiddleBlockType != Change.a_MiddleBlock) - { - itr = m_LinkedPoweredBlocks.erase(itr); - LOGD("cRedstoneSimulator: Erased block %s from linked powered blocks list due to present/past middle block mismatch", ItemToFullString(Change.a_SourceBlock)); - } - else if ( - // Things that can send power through a block but which depends on meta - ((SourceBlockType == E_BLOCK_REDSTONE_WIRE) && (SourceBlockMeta == 0)) || - ((SourceBlockType == E_BLOCK_LEVER) && !IsLeverOn(SourceBlockMeta)) || - (((SourceBlockType == E_BLOCK_STONE_BUTTON) || (SourceBlockType == E_BLOCK_WOODEN_BUTTON)) && (!IsButtonOn(SourceBlockMeta))) - ) - { - itr = m_LinkedPoweredBlocks.erase(itr); - LOGD("cRedstoneSimulator: Erased block %s from linked powered blocks list due to present/past metadata mismatch", ItemToFullString(Change.a_SourceBlock)); - } - else - { - itr++; - } + itr = m_LinkedPoweredBlocks.erase(itr); + LOGD("cRedstoneSimulator: Erased block %s from linked powered blocks list due to present/past block type mismatch", ItemToFullString(Change.a_SourceBlock)); } + else if (MiddleBlockType != Change.a_MiddleBlock) + { + itr = m_LinkedPoweredBlocks.erase(itr); + LOGD("cRedstoneSimulator: Erased block %s from linked powered blocks list due to present/past middle block mismatch", ItemToFullString(Change.a_SourceBlock)); + } + else if ( + // Things that can send power through a block but which depends on meta + ((SourceBlockType == E_BLOCK_REDSTONE_WIRE) && (SourceBlockMeta == 0)) || + ((SourceBlockType == E_BLOCK_LEVER) && !IsLeverOn(SourceBlockMeta)) || + (((SourceBlockType == E_BLOCK_STONE_BUTTON) || (SourceBlockType == E_BLOCK_WOODEN_BUTTON)) && (!IsButtonOn(SourceBlockMeta))) + ) + { + itr = m_LinkedPoweredBlocks.erase(itr); + LOGD("cRedstoneSimulator: Erased block %s from linked powered blocks list due to present/past metadata mismatch", ItemToFullString(Change.a_SourceBlock)); + } + else + { + itr++; + } + } - // PoweredBlock list was fine, now to the actual handling + for (cRedstoneSimulatorChunkData::iterator dataitr = ChunkData.begin(), end = ChunkData.end(); dataitr != end;) + { + BLOCKTYPE BlockType = a_Chunk->GetBlock(dataitr->x, dataitr->y, dataitr->z); + if (!IsAllowedBlock(BlockType)) + { + dataitr = ChunkData.erase(dataitr); + continue; + } + + // PoweredBlock and LinkedPoweredBlock list was fine, now to the actual handling int a_X = BaseX + dataitr->x; int a_Z = BaseZ + dataitr->z; switch (BlockType) @@ -169,6 +177,7 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c case E_BLOCK_BLOCK_OF_REDSTONE: HandleRedstoneBlock(a_X, dataitr->y, a_Z); break; case E_BLOCK_LEVER: HandleRedstoneLever(a_X, dataitr->y, a_Z); break; case E_BLOCK_TNT: HandleTNT(a_X, dataitr->y, a_Z); break; + case E_BLOCK_TRAPDOOR: HandleTrapdoor(a_X, dataitr->y, a_Z); break; case E_BLOCK_REDSTONE_WIRE: HandleRedstoneWire(a_X, dataitr->y, a_Z); break; case E_BLOCK_REDSTONE_TORCH_OFF: @@ -406,7 +415,9 @@ void cRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_Bl if (SurroundMeta > 1) // Wires of power 1 or 0 cannot transfer power TO ME, don't bother checking { - if (SurroundMeta > MyMeta) // Does surrounding wire have a higher power level than self? + // Does surrounding wire have a higher power level than self? + // >= to fix a bug where wires bordering each other with the same power level will appear (in terms of meta) to power each other, when they aren't actually in the powered list + if (SurroundMeta >= MyMeta) { m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, SurroundMeta - 1); } @@ -555,7 +566,7 @@ void cRedstoneSimulator::HandleRedstoneRepeater(int a_BlockX, int a_BlockY, int void cRedstoneSimulator::HandlePiston(int a_BlockX, int a_BlockY, int a_BlockZ) { cPiston Piston(&m_World); - if (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ)) + if (IsPistonPowered(a_BlockX, a_BlockY, a_BlockZ, m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) & 0x7)) // We only want the bottom three bits (4th controls extended-ness) { Piston.ExtendPiston(a_BlockX, a_BlockY, a_BlockZ); } @@ -717,6 +728,22 @@ void cRedstoneSimulator::HandleRail(int a_BlockX, int a_BlockY, int a_BlockZ, BL +void cRedstoneSimulator::HandleTrapdoor(int a_BlockX, int a_BlockY, int a_BlockZ) +{ + if (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ)) + { + m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) | 0x4); + } + else + { + m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) & 0xB); // Take into account that the fourth bit is needed for trapdoors too + } +} + + + + + bool cRedstoneSimulator::AreCoordsPowered(int a_BlockX, int a_BlockY, int a_BlockZ) { for (PoweredBlocksList::iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end(); ++itr) // Check powered list @@ -747,7 +774,8 @@ bool cRedstoneSimulator::AreCoordsPowered(int a_BlockX, int a_BlockY, int a_Bloc bool cRedstoneSimulator::IsRepeaterPowered(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta) { - // Check through powered blocks list + // Repeaters cannot be powered by any face except their back; verify that this is true for a source + for (PoweredBlocksList::iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end(); ++itr) { sPoweredBlocks & Change = *itr; @@ -780,7 +808,6 @@ bool cRedstoneSimulator::IsRepeaterPowered(int a_BlockX, int a_BlockY, int a_Blo } } - // Check linked powered list, 'middle' blocks for (LinkedBlocksList::iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end(); ++itr) { sLinkedPoweredBlocks & Change = *itr; @@ -817,6 +844,53 @@ bool cRedstoneSimulator::IsRepeaterPowered(int a_BlockX, int a_BlockY, int a_Blo +bool cRedstoneSimulator::IsPistonPowered(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta) +{ + // Pistons cannot be powered through their front face; this function verifies that a source meets this requirement + + int OldX = a_BlockX, OldY = a_BlockY, OldZ = a_BlockZ; + + for (PoweredBlocksList::iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end(); ++itr) + { + sPoweredBlocks & Change = *itr; + + if (!Change.a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; } + + AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_Meta); // Piston meta is based on what direction they face, so we can do this + + if (!Change.a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) + { + return true; + } + + a_BlockX = OldX; + a_BlockY = OldY; + a_BlockZ = OldZ; + } + + for (LinkedBlocksList::iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end(); ++itr) + { + sLinkedPoweredBlocks & Change = *itr; + + if (!Change.a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; } + + AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_Meta); + + if (!Change.a_MiddlePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) + { + return true; + } + + a_BlockX = OldX; + a_BlockY = OldY; + a_BlockZ = OldZ; + } + return false; // Source was in front of the piston's front face +} + + + + void cRedstoneSimulator::SetDirectionLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Direction, BLOCKTYPE a_SourceType) { @@ -1086,7 +1160,6 @@ void cRedstoneSimulator::SetAllDirsAsPowered(int a_BlockX, int a_BlockY, int a_B void cRedstoneSimulator::SetBlockPowered(int a_BlockX, int a_BlockY, int a_BlockZ, int a_SourceX, int a_SourceY, int a_SourceZ, BLOCKTYPE a_SourceBlock) { if (m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ) == E_BLOCK_AIR) { return; } // Don't set air, fixes some bugs (wires powering themselves) - if (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ)) { return; } // Check for duplicates sPoweredBlocks RC; RC.a_BlockPos = Vector3i(a_BlockX, a_BlockY, a_BlockZ); @@ -1107,7 +1180,6 @@ void cRedstoneSimulator::SetBlockLinkedPowered(int a_BlockX, int a_BlockY, int a ) { if (m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ) == E_BLOCK_AIR) { return; } // Don't set air, fixes some bugs (wires powering themselves) - if (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ)) { return; } // Check for duplicates if (!IsViableMiddleBlock(m_World.GetBlock(a_MiddleX, a_MiddleY, a_MiddleZ))) { return; } // See if middle block is viable sLinkedPoweredBlocks RC; diff --git a/src/Simulator/RedstoneSimulator.h b/src/Simulator/RedstoneSimulator.h index d3002394a..59400b614 100644 --- a/src/Simulator/RedstoneSimulator.h +++ b/src/Simulator/RedstoneSimulator.h @@ -93,6 +93,8 @@ private: void HandleDoor(int a_BlockX, int a_BlockY, int a_BlockZ); /// <summary>Handles activator, detector, and powered rails</summary> void HandleRail(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyType); + /// <summary>Handles trapdoors</summary> + void HandleTrapdoor(int a_BlockX, int a_BlockY, int a_BlockZ); /* ===================== */ /* ====== Helper functions ====== */ @@ -109,6 +111,8 @@ private: bool AreCoordsPowered(int a_BlockX, int a_BlockY, int a_BlockZ); /// <summary>Returns if a repeater is powered</summary> bool IsRepeaterPowered(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta); + /// <summary>Returns if a piston is powered</summary> + bool IsPistonPowered(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta); /// <summary>Returns if lever metadata marks it as emitting power</summary> bool IsLeverOn(NIBBLETYPE a_BlockMeta); |