summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/BlockInfo.cpp3
-rw-r--r--src/Blocks/BlockBed.h6
-rw-r--r--src/Blocks/BlockButton.h6
-rw-r--r--src/Blocks/BlockChest.h6
-rw-r--r--src/Blocks/BlockComparator.h6
-rw-r--r--src/Blocks/BlockDoor.cpp84
-rw-r--r--src/Blocks/BlockDoor.h72
-rw-r--r--src/Blocks/BlockDropSpenser.h6
-rw-r--r--src/Blocks/BlockEnderchest.h6
-rw-r--r--src/Blocks/BlockFenceGate.h6
-rw-r--r--src/Blocks/BlockFurnace.h8
-rw-r--r--src/Blocks/BlockHandler.cpp2
-rw-r--r--src/Blocks/BlockHopper.h21
-rw-r--r--src/Blocks/BlockLadder.h4
-rw-r--r--src/Blocks/BlockLever.h37
-rw-r--r--src/Blocks/BlockLilypad.h28
-rw-r--r--src/Blocks/BlockPumpkin.h6
-rw-r--r--src/Blocks/BlockRail.h135
-rw-r--r--src/Blocks/BlockRedstoneRepeater.h6
-rw-r--r--src/Blocks/BlockSign.h31
-rw-r--r--src/Blocks/BlockSlab.h11
-rw-r--r--src/Blocks/BlockStairs.h6
-rw-r--r--src/Blocks/BlockTorch.h6
-rw-r--r--src/Blocks/BlockTrapdoor.h6
-rw-r--r--src/Blocks/BlockVine.h2
-rw-r--r--src/Blocks/MetaRotator.h (renamed from src/Blocks/MetaRotater.h)16
-rw-r--r--src/Chunk.cpp2
-rw-r--r--src/ClientHandle.cpp14
-rw-r--r--src/Items/ItemBucket.h8
-rw-r--r--src/Items/ItemHandler.cpp2
-rw-r--r--src/Items/ItemLilypad.h109
-rw-r--r--src/Items/ItemMinecart.h6
-rw-r--r--src/Simulator/FluidSimulator.cpp1
33 files changed, 534 insertions, 134 deletions
diff --git a/src/BlockInfo.cpp b/src/BlockInfo.cpp
index 7d438ba3e..6fb5aa5b3 100644
--- a/src/BlockInfo.cpp
+++ b/src/BlockInfo.cpp
@@ -365,7 +365,7 @@ void cBlockInfo::Initialize(void)
ms_Info[E_BLOCK_WOODEN_SLAB ].m_IsSolid = false;
- // Torch placeable blocks:
+ // Blocks that fully occupy their voxel - used as a guide for torch placeable blocks, amongst other things:
ms_Info[E_BLOCK_NEW_LOG ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_BEDROCK ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_BLOCK_OF_COAL ].m_FullyOccupiesVoxel = true;
@@ -397,6 +397,7 @@ void cBlockInfo::Initialize(void)
ms_Info[E_BLOCK_HAY_BALE ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_HUGE_BROWN_MUSHROOM ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_HUGE_RED_MUSHROOM ].m_FullyOccupiesVoxel = true;
+ ms_Info[E_BLOCK_ICE ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_IRON_BLOCK ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_IRON_ORE ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_JACK_O_LANTERN ].m_FullyOccupiesVoxel = true;
diff --git a/src/Blocks/BlockBed.h b/src/Blocks/BlockBed.h
index 6daa94730..92804aaac 100644
--- a/src/Blocks/BlockBed.h
+++ b/src/Blocks/BlockBed.h
@@ -4,7 +4,7 @@
#include "BlockHandler.h"
#include "ChunkInterface.h"
#include "WorldInterface.h"
-#include "MetaRotater.h"
+#include "MetaRotator.h"
#include "../Entities/Player.h"
@@ -12,11 +12,11 @@
class cBlockBedHandler :
- public cMetaRotater<cBlockHandler, 0x3, 0x02, 0x03, 0x00, 0x01, true>
+ public cMetaRotator<cBlockHandler, 0x3, 0x02, 0x03, 0x00, 0x01, true>
{
public:
cBlockBedHandler(BLOCKTYPE a_BlockType)
- : cMetaRotater<cBlockHandler, 0x3, 0x02, 0x03, 0x00, 0x01,true>(a_BlockType)
+ : cMetaRotator<cBlockHandler, 0x3, 0x02, 0x03, 0x00, 0x01,true>(a_BlockType)
{
}
diff --git a/src/Blocks/BlockButton.h b/src/Blocks/BlockButton.h
index 740cbe3c4..4b2f6f618 100644
--- a/src/Blocks/BlockButton.h
+++ b/src/Blocks/BlockButton.h
@@ -2,17 +2,17 @@
#include "BlockHandler.h"
#include "Chunk.h"
-#include "MetaRotater.h"
+#include "MetaRotator.h"
class cBlockButtonHandler :
- public cMetaRotater<cBlockHandler, 0x07, 0x04, 0x01, 0x03, 0x02, true>
+ public cMetaRotator<cBlockHandler, 0x07, 0x04, 0x01, 0x03, 0x02, true>
{
public:
cBlockButtonHandler(BLOCKTYPE a_BlockType)
- : cMetaRotater<cBlockHandler, 0x07, 0x04, 0x01, 0x03, 0x02, true>(a_BlockType)
+ : cMetaRotator<cBlockHandler, 0x07, 0x04, 0x01, 0x03, 0x02, true>(a_BlockType)
{
}
diff --git a/src/Blocks/BlockChest.h b/src/Blocks/BlockChest.h
index 7abf01301..a1ded4c26 100644
--- a/src/Blocks/BlockChest.h
+++ b/src/Blocks/BlockChest.h
@@ -4,18 +4,18 @@
#include "BlockEntity.h"
#include "../BlockArea.h"
#include "../Entities/Player.h"
-#include "MetaRotater.h"
+#include "MetaRotator.h"
class cBlockChestHandler :
- public cMetaRotater<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04, true>
+ public cMetaRotator<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>
{
public:
cBlockChestHandler(BLOCKTYPE a_BlockType)
- : cMetaRotater<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04, true>(a_BlockType)
+ : cMetaRotator<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>(a_BlockType)
{
}
diff --git a/src/Blocks/BlockComparator.h b/src/Blocks/BlockComparator.h
index e570ff302..4dd05366d 100644
--- a/src/Blocks/BlockComparator.h
+++ b/src/Blocks/BlockComparator.h
@@ -3,18 +3,18 @@
#include "BlockHandler.h"
#include "BlockRedstoneRepeater.h"
-#include "MetaRotater.h"
+#include "MetaRotator.h"
class cBlockComparatorHandler :
- public cMetaRotater<cBlockHandler, 0x03, 0x00, 0x01, 0x02, 0x03, true>
+ public cMetaRotator<cBlockHandler, 0x03, 0x00, 0x01, 0x02, 0x03, true>
{
public:
cBlockComparatorHandler(BLOCKTYPE a_BlockType)
- : cMetaRotater<cBlockHandler, 0x03, 0x00, 0x01, 0x02, 0x03, true>(a_BlockType)
+ : cMetaRotator<cBlockHandler, 0x03, 0x00, 0x01, 0x02, 0x03, true>(a_BlockType)
{
}
diff --git a/src/Blocks/BlockDoor.cpp b/src/Blocks/BlockDoor.cpp
index 4e38ef334..479c68153 100644
--- a/src/Blocks/BlockDoor.cpp
+++ b/src/Blocks/BlockDoor.cpp
@@ -110,3 +110,87 @@ const char * cBlockDoorHandler::GetStepSound(void)
+
+NIBBLETYPE cBlockDoorHandler::MetaRotateCCW(NIBBLETYPE a_Meta)
+{
+ if (a_Meta & 0x08)
+ {
+ return a_Meta;
+ }
+ else
+ {
+ return super::MetaRotateCCW(a_Meta);
+ }
+}
+
+
+
+NIBBLETYPE cBlockDoorHandler::MetaRotateCW(NIBBLETYPE a_Meta)
+{
+ if (a_Meta & 0x08)
+ {
+ return a_Meta;
+ }
+ else
+ {
+ return super::MetaRotateCW(a_Meta);
+ }
+}
+
+
+
+NIBBLETYPE cBlockDoorHandler::MetaMirrorXY(NIBBLETYPE a_Meta)
+{
+ // Top bit (0x08) contains door panel type (Top/Bottom panel) Only Bottom panels contain position data
+ // Return a_Meta if panel is a top panel (0x08 bit is set to 1)
+
+ // Note: Currently, you can not properly mirror the hinges on a double door. The orientation of the door is stored
+ // in only the bottom tile while the hinge position is in the top tile. This function only operates on one tile at a time,
+ // so the function can only see either the hinge position or orientation, but not both, at any given time. The class itself
+ // needs extra datamembers.
+ if (a_Meta & 0x08) return a_Meta;
+
+ // Holds open/closed meta data. 0x0C == 1100.
+ NIBBLETYPE OtherMeta = a_Meta & 0x0C;
+
+ // Mirrors according to a table. 0x03 == 0011.
+ switch (a_Meta & 0x03)
+ {
+ case 0x03: return 0x01 + OtherMeta; // South -> North
+ case 0x01: return 0x03 + OtherMeta; // North -> South
+ }
+
+ // Not Facing North or South; No change.
+ return a_Meta;
+}
+
+
+
+NIBBLETYPE cBlockDoorHandler::MetaMirrorYZ(NIBBLETYPE a_Meta)
+{
+ // Top bit (0x08) contains door panel type (Top/Bottom panel) Only Bottom panels contain position data
+ // Return a_Meta if panel is a top panel (0x08 bit is set to 1)
+
+ // Note: Currently, you can not properly mirror the hinges on a double door. The orientation of the door is stored
+ // in only the bottom tile while the hinge position is in the top tile. This function only operates on one tile at a time,
+ // so the function can only see either the hinge position or orientation, but not both, at any given time.The class itself
+ // needs extra datamembers.
+
+ if (a_Meta & 0x08) return a_Meta;
+
+ // Holds open/closed meta data. 0x0C == 1100.
+ NIBBLETYPE OtherMeta = a_Meta & 0x0C;
+
+ // Mirrors according to a table. 0x03 == 0011.
+ switch (a_Meta & 0x03)
+ {
+ case 0x00: return 0x02 + OtherMeta; // West -> East
+ case 0x02: return 0x00 + OtherMeta; // East -> West
+ }
+
+ // Not Facing North or South; No change.
+ return a_Meta;
+}
+
+
+
diff --git a/src/Blocks/BlockDoor.h b/src/Blocks/BlockDoor.h
index 981774c17..797fe484c 100644
--- a/src/Blocks/BlockDoor.h
+++ b/src/Blocks/BlockDoor.h
@@ -4,15 +4,15 @@
#include "BlockHandler.h"
#include "../Entities/Player.h"
#include "Chunk.h"
-#include "MetaRotater.h"
+#include "MetaRotator.h"
class cBlockDoorHandler :
- public cMetaRotater<cBlockHandler, 0x03, 0x01, 0x02, 0x03, 0x00, true>
+ public cMetaRotator<cBlockHandler, 0x03, 0x01, 0x02, 0x03, 0x00, true>
{
- typedef cMetaRotater<cBlockHandler, 0x03, 0x01, 0x02, 0x03, 0x00, true> super;
+ typedef cMetaRotator<cBlockHandler, 0x03, 0x01, 0x02, 0x03, 0x00, true> super;
public:
cBlockDoorHandler(BLOCKTYPE a_BlockType);
@@ -21,6 +21,10 @@ public:
virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override;
virtual const char * GetStepSound(void) override;
+ virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override;
+ virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override;
+ virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override;
+ virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override;
virtual bool GetPlacementBlockTypeMeta(
cChunkInterface & a_ChunkInterface, cPlayer * a_Player,
@@ -142,14 +146,14 @@ public:
static void ChangeDoor(cChunkInterface & a_ChunkInterface, int a_X, int a_Y, int a_Z)
{
NIBBLETYPE OldMetaData = a_ChunkInterface.GetBlockMeta(a_X, a_Y, a_Z);
-
+
a_ChunkInterface.SetBlockMeta(a_X, a_Y, a_Z, ChangeStateMetaData(OldMetaData));
-
+
if (OldMetaData & 8)
{
// Current block is top of the door
BLOCKTYPE BottomBlock = a_ChunkInterface.GetBlock(a_X, a_Y - 1, a_Z);
- NIBBLETYPE BottomMeta = a_ChunkInterface.GetBlockMeta(a_X, a_Y - 1, a_Z);
+ NIBBLETYPE BottomMeta = a_ChunkInterface.GetBlockMeta(a_X, a_Y - 1, a_Z);
if (IsDoor(BottomBlock) && !(BottomMeta & 8))
{
@@ -168,62 +172,6 @@ public:
}
}
}
-
-
- virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override
- {
- if (a_Meta & 0x08)
- {
- return a_Meta;
- }
- else
- {
- return super::MetaRotateCCW(a_Meta);
- }
- }
-
-
-
- virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override
- {
- if (a_Meta & 0x08)
- {
- return a_Meta;
- }
- else
- {
- return super::MetaRotateCW(a_Meta);
- }
- }
-
-
-
- virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override
- {
- if (a_Meta & 0x08)
- {
- return a_Meta;
- }
- else
- {
- return super::MetaMirrorXY(a_Meta);
- }
- }
-
-
-
- virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override
- {
- if (a_Meta & 0x08)
- {
- return a_Meta;
- }
- else
- {
- return super::MetaMirrorYZ(a_Meta);
- }
- }
-
} ;
diff --git a/src/Blocks/BlockDropSpenser.h b/src/Blocks/BlockDropSpenser.h
index 7e0ad0e55..88b61a418 100644
--- a/src/Blocks/BlockDropSpenser.h
+++ b/src/Blocks/BlockDropSpenser.h
@@ -6,18 +6,18 @@
#pragma once
#include "../Piston.h"
-#include "MetaRotater.h"
+#include "MetaRotator.h"
class cBlockDropSpenserHandler :
- public cMetaRotater<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>
+ public cMetaRotator<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>
{
public:
cBlockDropSpenserHandler(BLOCKTYPE a_BlockType) :
- cMetaRotater<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>(a_BlockType)
+ cMetaRotator<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>(a_BlockType)
{
}
diff --git a/src/Blocks/BlockEnderchest.h b/src/Blocks/BlockEnderchest.h
index 97cf484fb..67955f8ce 100644
--- a/src/Blocks/BlockEnderchest.h
+++ b/src/Blocks/BlockEnderchest.h
@@ -2,17 +2,17 @@
#pragma once
#include "BlockEntity.h"
-#include "MetaRotater.h"
+#include "MetaRotator.h"
class cBlockEnderchestHandler :
- public cMetaRotater<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>
+ public cMetaRotator<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>
{
public:
cBlockEnderchestHandler(BLOCKTYPE a_BlockType)
- : cMetaRotater<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>(a_BlockType)
+ : cMetaRotator<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>(a_BlockType)
{
}
diff --git a/src/Blocks/BlockFenceGate.h b/src/Blocks/BlockFenceGate.h
index e3162bbd6..e202c6610 100644
--- a/src/Blocks/BlockFenceGate.h
+++ b/src/Blocks/BlockFenceGate.h
@@ -2,17 +2,17 @@
#pragma once
#include "BlockHandler.h"
-#include "MetaRotater.h"
+#include "MetaRotator.h"
class cBlockFenceGateHandler :
- public cMetaRotater<cBlockHandler, 0x03, 0x02, 0x03, 0x00, 0x01, true>
+ public cMetaRotator<cBlockHandler, 0x03, 0x02, 0x03, 0x00, 0x01, true>
{
public:
cBlockFenceGateHandler(BLOCKTYPE a_BlockType) :
- cMetaRotater<cBlockHandler, 0x03, 0x02, 0x03, 0x00, 0x01, true>(a_BlockType)
+ cMetaRotator<cBlockHandler, 0x03, 0x02, 0x03, 0x00, 0x01, true>(a_BlockType)
{
}
diff --git a/src/Blocks/BlockFurnace.h b/src/Blocks/BlockFurnace.h
index 27ef2689f..a7a807957 100644
--- a/src/Blocks/BlockFurnace.h
+++ b/src/Blocks/BlockFurnace.h
@@ -4,17 +4,17 @@
#include "BlockEntity.h"
#include "../World.h"
#include "../Piston.h"
-
+#include "MetaRotator.h"
class cBlockFurnaceHandler :
- public cBlockEntityHandler
+ public cMetaRotator<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>
{
public:
- cBlockFurnaceHandler(BLOCKTYPE a_BlockType) :
- cBlockEntityHandler(a_BlockType)
+ cBlockFurnaceHandler(BLOCKTYPE a_BlockType)
+ : cMetaRotator<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>(a_BlockType)
{
}
diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp
index 4f74e2f45..7fd8c183c 100644
--- a/src/Blocks/BlockHandler.cpp
+++ b/src/Blocks/BlockHandler.cpp
@@ -41,6 +41,7 @@
#include "BlockIce.h"
#include "BlockLadder.h"
#include "BlockLeaves.h"
+#include "BlockLilypad.h"
#include "BlockNewLeaves.h"
#include "BlockLever.h"
#include "BlockMelon.h"
@@ -142,6 +143,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
case E_BLOCK_LAPIS_ORE: return new cBlockOreHandler (a_BlockType);
case E_BLOCK_LAVA: return new cBlockLavaHandler (a_BlockType);
case E_BLOCK_LEAVES: return new cBlockLeavesHandler (a_BlockType);
+ case E_BLOCK_LILY_PAD: return new cBlockLilypadHandler (a_BlockType);
case E_BLOCK_LIT_FURNACE: return new cBlockFurnaceHandler (a_BlockType);
case E_BLOCK_LOG: return new cBlockSidewaysHandler (a_BlockType);
case E_BLOCK_MELON: return new cBlockMelonHandler (a_BlockType);
diff --git a/src/Blocks/BlockHopper.h b/src/Blocks/BlockHopper.h
index 59b84aa0e..a882bb077 100644
--- a/src/Blocks/BlockHopper.h
+++ b/src/Blocks/BlockHopper.h
@@ -3,16 +3,16 @@
// Declares the cBlockHopperHandler class representing the handler for the Hopper block
-
+#include "MetaRotator.h"
class cBlockHopperHandler :
- public cBlockEntityHandler
+ public cMetaRotator<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>
{
public:
cBlockHopperHandler(BLOCKTYPE a_BlockType)
- : cBlockEntityHandler(a_BlockType)
+ : cMetaRotator<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>(a_BlockType)
{
}
@@ -39,6 +39,21 @@ public:
}
return true;
}
+
+
+ virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) override
+ {
+ // Bit 0x08 is a flag. Lowest three bits are position. 0x08 == 1000
+ NIBBLETYPE OtherMeta = a_Meta & 0x08;
+ // Mirrors defined by by a table. (Source, mincraft.gamepedia.com) 0x07 == 0111
+ switch (a_Meta & 0x07)
+ {
+ case 0x00: return 0x01 + OtherMeta; // Down -> Up
+ case 0x01: return 0x00 + OtherMeta; // Up -> Down
+ }
+ // Not Facing Up or Down; No change.
+ return a_Meta;
+ }
} ;
diff --git a/src/Blocks/BlockLadder.h b/src/Blocks/BlockLadder.h
index a3e9edc6b..a605edf3f 100644
--- a/src/Blocks/BlockLadder.h
+++ b/src/Blocks/BlockLadder.h
@@ -9,11 +9,11 @@
class cBlockLadderHandler :
- public cBlockHandler
+ public cMetaRotator<cBlockHandler, 0x07, 0x02, 0x05, 0x03, 0x04>
{
public:
cBlockLadderHandler(BLOCKTYPE a_BlockType)
- : cBlockHandler(a_BlockType)
+ : cMetaRotator<cBlockHandler, 0x07, 0x02, 0x05, 0x03, 0x04>(a_BlockType)
{
}
diff --git a/src/Blocks/BlockLever.h b/src/Blocks/BlockLever.h
index ef6e102cd..ad2ae29e5 100644
--- a/src/Blocks/BlockLever.h
+++ b/src/Blocks/BlockLever.h
@@ -1,17 +1,18 @@
#pragma once
#include "BlockHandler.h"
-
+#include "MetaRotator.h"
class cBlockLeverHandler :
- public cBlockHandler
+ public cMetaRotator<cBlockHandler, 0x07, 0x04, 0x02, 0x03, 0x01, false>
{
+ typedef cMetaRotator<cBlockHandler, 0x07, 0x04, 0x02, 0x03, 0x01, false> super;
public:
cBlockLeverHandler(BLOCKTYPE a_BlockType)
- : cBlockHandler(a_BlockType)
+ : cMetaRotator<cBlockHandler, 0x07, 0x04, 0x02, 0x03, 0x01, false>(a_BlockType)
{
}
@@ -104,6 +105,36 @@ public:
return (a_RelY > 0) && cBlockInfo::IsSolid(BlockIsOn);
}
+
+
+ virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override
+ {
+ switch (a_Meta)
+ {
+ case 0x00: return 0x07; // Ceiling rotation
+ case 0x07: return 0x00;
+
+ case 0x05: return 0x06; // Ground rotation
+ case 0x06: return 0x05;
+
+ default: return super::MetaRotateCCW(a_Meta); // Wall Rotation
+ }
+ }
+
+
+ virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override
+ {
+ switch (a_Meta)
+ {
+ case 0x00: return 0x07; // Ceiling rotation
+ case 0x07: return 0x00;
+
+ case 0x05: return 0x06; // Ground rotation
+ case 0x06: return 0x05;
+
+ default: return super::MetaRotateCCW(a_Meta); // Wall Rotation
+ }
+ }
} ;
diff --git a/src/Blocks/BlockLilypad.h b/src/Blocks/BlockLilypad.h
new file mode 100644
index 000000000..2dd4ec768
--- /dev/null
+++ b/src/Blocks/BlockLilypad.h
@@ -0,0 +1,28 @@
+
+#pragma once
+
+#include "BlockHandler.h"
+#include "Entities/Pickup.h"
+
+
+
+
+class cBlockLilypadHandler :
+ public cBlockHandler
+{
+public:
+ cBlockLilypadHandler(BLOCKTYPE a_BlockType)
+ : cBlockHandler(a_BlockType)
+ {
+ }
+
+ virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
+ {
+ // Reset meta to zero
+ a_Pickups.push_back(cItem(E_BLOCK_LILY_PAD, 1, 0));
+ }
+};
+
+
+
+
diff --git a/src/Blocks/BlockPumpkin.h b/src/Blocks/BlockPumpkin.h
index 349f52605..ac2b9817a 100644
--- a/src/Blocks/BlockPumpkin.h
+++ b/src/Blocks/BlockPumpkin.h
@@ -1,16 +1,16 @@
#pragma once
#include "BlockHandler.h"
-
+#include "MetaRotator.h"
class cBlockPumpkinHandler :
- public cBlockHandler
+ public cMetaRotator<cBlockHandler, 0x07, 0x02, 0x03, 0x00, 0x01, false>
{
public:
cBlockPumpkinHandler(BLOCKTYPE a_BlockType)
- : cBlockHandler(a_BlockType)
+ : cMetaRotator<cBlockHandler, 0x07, 0x02, 0x03, 0x00, 0x01, false>(a_BlockType)
{
}
diff --git a/src/Blocks/BlockRail.h b/src/Blocks/BlockRail.h
index 07e9814cd..477707a91 100644
--- a/src/Blocks/BlockRail.h
+++ b/src/Blocks/BlockRail.h
@@ -434,6 +434,141 @@ public:
}
return true;
}
+
+
+ virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override
+ {
+ // Bit 0x08 is a flag when a_Meta is in the range 0x00--0x05 and 0x0A--0x0F.
+ // Bit 0x08 specifies direction when a_Meta is in the range 0x06-0x09.
+ if ((a_Meta < 0x06) || (a_Meta > 0x09))
+ {
+ // Save powered rail flag.
+ NIBBLETYPE OtherMeta = a_Meta & 0x08;
+ // Rotates according to table; 0x07 == 0111.
+ // Rails can either be flat (North/South) or Ascending (Asc. East)
+ switch (a_Meta & 0x07)
+ {
+ case 0x00: return 0x01 + OtherMeta; // North/South -> East/West
+ case 0x01: return 0x00 + OtherMeta; // East/West -> North/South
+
+ case 0x02: return 0x04 + OtherMeta; // Asc. East -> Asc. North
+ case 0x04: return 0x03 + OtherMeta; // Asc. North -> Asc. West
+ case 0x03: return 0x05 + OtherMeta; // Asc. West -> Asc. South
+ case 0x05: return 0x02 + OtherMeta; // Asc. South -> Asc. East
+ }
+ }
+ else
+ {
+ switch (a_Meta)
+ {
+ // Corner Directions
+ case 0x06: return 0x09; // Northwest Cnr. -> Southwest Cnr.
+ case 0x07: return 0x06; // Northeast Cnr. -> Northwest Cnr.
+ case 0x08: return 0x07; // Southeast Cnr. -> Northeast Cnr.
+ case 0x09: return 0x08; // Southwest Cnr. -> Southeast Cnr.
+ }
+ }
+ // To avoid a compiler warning;
+ return a_Meta;
+ }
+
+
+ virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override
+ {
+ // Bit 0x08 is a flag for value in the range 0x00--0x05 and specifies direction for values withint 0x006--0x09.
+ if ((a_Meta < 0x06) || (a_Meta > 0x09))
+ {
+ // Save powered rail flag.
+ NIBBLETYPE OtherMeta = a_Meta & 0x08;
+ // Rotates according to table; 0x07 == 0111.
+ // Rails can either be flat (North/South) or Ascending (Asc. East)
+ switch (a_Meta & 0x07)
+ {
+ case 0x00: return 0x01 + OtherMeta; // North/South -> East/West
+ case 0x01: return 0x00 + OtherMeta; // East/West -> North/South
+
+ case 0x02: return 0x05 + OtherMeta; // Asc. East -> Asc. South
+ case 0x05: return 0x03 + OtherMeta; // Asc. South -> Asc. West
+ case 0x03: return 0x04 + OtherMeta; // Asc. West -> Asc. North
+ case 0x04: return 0x02 + OtherMeta; // Asc. North -> Asc. East
+ }
+ }
+ else
+ {
+ switch (a_Meta)
+ {
+ // Corner Directions
+ case 0x06: return 0x07; // Northwest Cnr. -> Northeast Cnr.
+ case 0x07: return 0x08; // Northeast Cnr. -> Southeast Cnr.
+ case 0x08: return 0x09; // Southeast Cnr. -> Southwest Cnr.
+ case 0x09: return 0x06; // Southwest Cnr. -> Northwest Cnr.
+ }
+ }
+ // To avoid a compiler warning;
+ return a_Meta;
+ }
+
+
+ virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override
+ {
+ // Bit 0x08 is a flag for value in the range 0x00--0x05 and specifies direction for values withint 0x006--0x09.
+ if ((a_Meta < 0x06) || (a_Meta > 0x09))
+ {
+ // Save powered rail flag.
+ NIBBLETYPE OtherMeta = a_Meta & 0x08;
+ // Mirrors according to table; 0x07 == 0111.
+ // Rails can either be flat (North/South) or Ascending (Asc. East)
+ switch (a_Meta & 0x07)
+ {
+ case 0x05: return 0x04 + OtherMeta; // Asc. South -> Asc. North
+ case 0x04: return 0x05 + OtherMeta; // Asc. North -> Asc. South
+ }
+ }
+ else
+ {
+ switch (a_Meta)
+ {
+ // Corner Directions
+ case 0x06: return 0x09; // Northwest Cnr. -> Southwest Cnr.
+ case 0x07: return 0x08; // Northeast Cnr. -> Southeast Cnr.
+ case 0x08: return 0x07; // Southeast Cnr. -> Northeast Cnr.
+ case 0x09: return 0x06; // Southwest Cnr. -> Northwest Cnr.
+ }
+ }
+ // To avoid a compiler warning;
+ return a_Meta;
+ }
+
+
+ virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override
+ {
+ // Bit 0x08 is a flag for value in the range 0x00--0x05 and specifies direction for values withint 0x006--0x09.
+ if ((a_Meta < 0x06) || (a_Meta > 0x09))
+ {
+ // Save powered rail flag.
+ NIBBLETYPE OtherMeta = a_Meta & 0x08;
+ // Mirrors according to table; 0x07 == 0111.
+ // Rails can either be flat (North/South) or Ascending (Asc. East)
+ switch (a_Meta & 0x07)
+ {
+ case 0x02: return 0x03 + OtherMeta; // Asc. East -> Asc. West
+ case 0x03: return 0x02 + OtherMeta; // Asc. West -> Asc. East
+ }
+ }
+ else
+ {
+ switch (a_Meta)
+ {
+ // Corner Directions
+ case 0x06: return 0x07; // Northwest Cnr. -> Northeast Cnr.
+ case 0x07: return 0x06; // Northeast Cnr. -> Northwest Cnr.
+ case 0x08: return 0x09; // Southeast Cnr. -> Southwest Cnr.
+ case 0x09: return 0x08; // Southwest Cnr. -> Southeast Cnr.
+ }
+ }
+ // To avoid a compiler warning;
+ return a_Meta;
+ }
} ;
diff --git a/src/Blocks/BlockRedstoneRepeater.h b/src/Blocks/BlockRedstoneRepeater.h
index 1e2a86949..fe6cd21b9 100644
--- a/src/Blocks/BlockRedstoneRepeater.h
+++ b/src/Blocks/BlockRedstoneRepeater.h
@@ -3,17 +3,17 @@
#include "BlockHandler.h"
#include "Chunk.h"
-
+#include "MetaRotator.h"
class cBlockRedstoneRepeaterHandler :
- public cBlockHandler
+ public cMetaRotator<cBlockHandler, 0x03, 0x00, 0x01, 0x02, 0x03, true>
{
public:
cBlockRedstoneRepeaterHandler(BLOCKTYPE a_BlockType)
- : cBlockHandler(a_BlockType)
+ : cMetaRotator<cBlockHandler, 0x03, 0x00, 0x01, 0x02, 0x03, true>(a_BlockType)
{
}
diff --git a/src/Blocks/BlockSign.h b/src/Blocks/BlockSign.h
index cd0c02a40..6c0becfd6 100644
--- a/src/Blocks/BlockSign.h
+++ b/src/Blocks/BlockSign.h
@@ -71,6 +71,37 @@ public:
{
a_Player->GetClientHandle()->SendEditSign(a_BlockX, a_BlockY, a_BlockZ);
}
+
+
+ virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override
+ {
+ return (++a_Meta) & 0x0F;
+ }
+
+
+ virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override
+ {
+ return (--a_Meta) & 0x0F;
+ }
+
+ virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override
+ {
+ // Mirrors signs over the XY plane (North-South Mirroring)
+
+ // There are 16 meta values which correspond to different directions.
+ // These values are equated to angles on a circle; 0x08 = 180 degrees.
+ return (a_Meta < 0x08) ? 0x08 + a_Meta : 0x08 - a_Meta;
+ }
+
+
+ virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override
+ {
+ // Mirrors signs over the YZ plane (East-West Mirroring)
+
+ // There are 16 meta values which correspond to different directions.
+ // These values are equated to angles on a circle; 0x10 = 360 degrees.
+ return 0x10 - a_Meta;
+ }
} ;
diff --git a/src/Blocks/BlockSlab.h b/src/Blocks/BlockSlab.h
index 7cd2c97b2..77e8b8e55 100644
--- a/src/Blocks/BlockSlab.h
+++ b/src/Blocks/BlockSlab.h
@@ -14,8 +14,6 @@
-
-
class cBlockSlabHandler :
public cBlockHandler
{
@@ -184,6 +182,15 @@ public:
ASSERT(!"Unhandled double slab type!");
return "";
}
+
+
+ virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) override
+ {
+ NIBBLETYPE OtherMeta = a_Meta & 0x07; // Contains unrelated meta data.
+
+ // 8th bit is up/down. 1 right-side-up, 0 is up-side-down.
+ return (a_Meta & 0x08) ? 0x00 + OtherMeta : 0x01 + OtherMeta;
+ }
} ;
diff --git a/src/Blocks/BlockStairs.h b/src/Blocks/BlockStairs.h
index ea8405597..1072b7e71 100644
--- a/src/Blocks/BlockStairs.h
+++ b/src/Blocks/BlockStairs.h
@@ -2,17 +2,17 @@
#pragma once
#include "BlockHandler.h"
-#include "MetaRotater.h"
+#include "MetaRotator.h"
class cBlockStairsHandler :
- public cMetaRotater<cBlockHandler, 0x03, 0x03, 0x00, 0x02, 0x01, true>
+ public cMetaRotator<cBlockHandler, 0x03, 0x03, 0x00, 0x02, 0x01, true>
{
public:
cBlockStairsHandler(BLOCKTYPE a_BlockType) :
- cMetaRotater<cBlockHandler, 0x03, 0x03, 0x00, 0x02, 0x01, true>(a_BlockType)
+ cMetaRotator<cBlockHandler, 0x03, 0x03, 0x00, 0x02, 0x01, true>(a_BlockType)
{
}
diff --git a/src/Blocks/BlockTorch.h b/src/Blocks/BlockTorch.h
index d32c77629..8ddec8de1 100644
--- a/src/Blocks/BlockTorch.h
+++ b/src/Blocks/BlockTorch.h
@@ -2,17 +2,17 @@
#include "BlockHandler.h"
#include "../Chunk.h"
-#include "MetaRotater.h"
+#include "MetaRotator.h"
class cBlockTorchHandler :
- public cMetaRotater<cBlockHandler, 0x7, 0x4, 0x1, 0x3, 0x2>
+ public cMetaRotator<cBlockHandler, 0x7, 0x4, 0x1, 0x3, 0x2>
{
public:
cBlockTorchHandler(BLOCKTYPE a_BlockType)
- : cMetaRotater<cBlockHandler, 0x7, 0x4, 0x1, 0x3, 0x2>(a_BlockType)
+ : cMetaRotator<cBlockHandler, 0x7, 0x4, 0x1, 0x3, 0x2>(a_BlockType)
{
}
diff --git a/src/Blocks/BlockTrapdoor.h b/src/Blocks/BlockTrapdoor.h
index 9bae92c4d..6a36ab874 100644
--- a/src/Blocks/BlockTrapdoor.h
+++ b/src/Blocks/BlockTrapdoor.h
@@ -2,17 +2,17 @@
#pragma once
#include "BlockHandler.h"
-
+#include "MetaRotator.h"
class cBlockTrapdoorHandler :
- public cBlockHandler
+ public cMetaRotator<cBlockHandler, 0x03, 0x01, 0x02, 0x00, 0x03, false>
{
public:
cBlockTrapdoorHandler(BLOCKTYPE a_BlockType)
- : cBlockHandler(a_BlockType)
+ : cMetaRotator<cBlockHandler, 0x03, 0x01, 0x02, 0x00, 0x03, false>(a_BlockType)
{
}
diff --git a/src/Blocks/BlockVine.h b/src/Blocks/BlockVine.h
index d096c81a8..e14218633 100644
--- a/src/Blocks/BlockVine.h
+++ b/src/Blocks/BlockVine.h
@@ -1,7 +1,7 @@
#pragma once
#include "BlockHandler.h"
-#include "MetaRotater.h"
+#include "MetaRotator.h"
diff --git a/src/Blocks/MetaRotater.h b/src/Blocks/MetaRotator.h
index dde88e6db..899c583e1 100644
--- a/src/Blocks/MetaRotater.h
+++ b/src/Blocks/MetaRotator.h
@@ -1,4 +1,4 @@
-// MetaRotater.h
+// MetaRotator.h
// Provides a mixin for rotations and reflections
@@ -21,15 +21,15 @@ Inherit from this class providing your base class as Base, the BitMask for the d
*/
template<class Base, NIBBLETYPE BitMask, NIBBLETYPE North, NIBBLETYPE East, NIBBLETYPE South, NIBBLETYPE West, bool AssertIfNotMatched = false>
-class cMetaRotater : public Base
+class cMetaRotator : public Base
{
public:
- cMetaRotater(BLOCKTYPE a_BlockType) :
+ cMetaRotator(BLOCKTYPE a_BlockType) :
Base(a_BlockType)
{}
- virtual ~cMetaRotater() {}
+ virtual ~cMetaRotator() {}
virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override;
virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override;
@@ -42,7 +42,7 @@ public:
template<class Base, NIBBLETYPE BitMask, NIBBLETYPE North, NIBBLETYPE East, NIBBLETYPE South, NIBBLETYPE West, bool AssertIfNotMatched>
-NIBBLETYPE cMetaRotater<Base, BitMask, North, East, South, West, AssertIfNotMatched>::MetaRotateCW(NIBBLETYPE a_Meta)
+NIBBLETYPE cMetaRotator<Base, BitMask, North, East, South, West, AssertIfNotMatched>::MetaRotateCW(NIBBLETYPE a_Meta)
{
NIBBLETYPE OtherMeta = a_Meta & (~BitMask);
switch (a_Meta & BitMask)
@@ -64,7 +64,7 @@ NIBBLETYPE cMetaRotater<Base, BitMask, North, East, South, West, AssertIfNotMatc
template<class Base, NIBBLETYPE BitMask, NIBBLETYPE North, NIBBLETYPE East, NIBBLETYPE South, NIBBLETYPE West, bool AssertIfNotMatched>
-NIBBLETYPE cMetaRotater<Base, BitMask, North, East, South, West, AssertIfNotMatched>::MetaRotateCCW(NIBBLETYPE a_Meta)
+NIBBLETYPE cMetaRotator<Base, BitMask, North, East, South, West, AssertIfNotMatched>::MetaRotateCCW(NIBBLETYPE a_Meta)
{
NIBBLETYPE OtherMeta = a_Meta & (~BitMask);
switch (a_Meta & BitMask)
@@ -86,7 +86,7 @@ NIBBLETYPE cMetaRotater<Base, BitMask, North, East, South, West, AssertIfNotMatc
template<class Base, NIBBLETYPE BitMask, NIBBLETYPE North, NIBBLETYPE East, NIBBLETYPE South, NIBBLETYPE West, bool AssertIfNotMatched>
-NIBBLETYPE cMetaRotater<Base, BitMask, North, East, South, West, AssertIfNotMatched>::MetaMirrorXY(NIBBLETYPE a_Meta)
+NIBBLETYPE cMetaRotator<Base, BitMask, North, East, South, West, AssertIfNotMatched>::MetaMirrorXY(NIBBLETYPE a_Meta)
{
NIBBLETYPE OtherMeta = a_Meta & (~BitMask);
switch (a_Meta & BitMask)
@@ -103,7 +103,7 @@ NIBBLETYPE cMetaRotater<Base, BitMask, North, East, South, West, AssertIfNotMatc
template<class Base, NIBBLETYPE BitMask, NIBBLETYPE North, NIBBLETYPE East, NIBBLETYPE South, NIBBLETYPE West, bool AssertIfNotMatched>
-NIBBLETYPE cMetaRotater<Base, BitMask, North, East, South, West, AssertIfNotMatched>::MetaMirrorYZ(NIBBLETYPE a_Meta)
+NIBBLETYPE cMetaRotator<Base, BitMask, North, East, South, West, AssertIfNotMatched>::MetaMirrorYZ(NIBBLETYPE a_Meta)
{
NIBBLETYPE OtherMeta = a_Meta & (~BitMask);
switch (a_Meta & BitMask)
diff --git a/src/Chunk.cpp b/src/Chunk.cpp
index bd4cb9937..22b33c595 100644
--- a/src/Chunk.cpp
+++ b/src/Chunk.cpp
@@ -884,7 +884,7 @@ void cChunk::ApplyWeatherToTop()
FastSetBlock(X, Height, Z, E_BLOCK_SNOW, TopMeta - 1);
}
}
- else if (cBlockInfo::IsSnowable(TopBlock))
+ else if (cBlockInfo::IsSnowable(TopBlock) && (Height + 1 < cChunkDef::Height))
{
SetBlock(X, Height + 1, Z, E_BLOCK_SNOW, 0);
}
diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp
index eb05ebdb7..5ed5f1085 100644
--- a/src/ClientHandle.cpp
+++ b/src/ClientHandle.cpp
@@ -941,6 +941,8 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e
}
return;
}
+
+ m_NumBlockChangeInteractionsThisTick++;
if (!CheckBlockInteractionsRate())
{
@@ -960,7 +962,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e
);
// Let's send the current world block to the client, so that it can immediately "let the user know" that they haven't placed the block
- if (a_BlockFace > -1)
+ if (a_BlockFace != BLOCK_FACE_NONE)
{
AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player);
@@ -988,7 +990,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e
cItemHandler * ItemHandler = cItemHandler::GetItemHandler(Equipped.m_ItemType);
- if (ItemHandler->IsPlaceable() && (a_BlockFace > -1))
+ if (ItemHandler->IsPlaceable() && (a_BlockFace != BLOCK_FACE_NONE))
{
HandlePlaceBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, *ItemHandler);
}
@@ -1026,6 +1028,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e
void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, cItemHandler & a_ItemHandler)
{
+ BLOCKTYPE EquippedBlock = (BLOCKTYPE)(m_Player->GetEquippedItem().m_ItemType);
if (a_BlockFace < 0)
{
// Clicked in air
@@ -1036,7 +1039,6 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, e
BLOCKTYPE ClickedBlock;
NIBBLETYPE ClickedBlockMeta;
- BLOCKTYPE EquippedBlock = (BLOCKTYPE)(m_Player->GetEquippedItem().m_ItemType);
NIBBLETYPE EquippedBlockDamage = (NIBBLETYPE)(m_Player->GetEquippedItem().m_ItemDamage);
if ((a_BlockY < 0) || (a_BlockY >= cChunkDef::Height))
@@ -1053,8 +1055,8 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, e
cBlockSlabHandler::IsAnySlabType(EquippedBlock) && // Is the player placing another slab?
((ClickedBlockMeta & 0x07) == EquippedBlockDamage) && // Is it the same slab type?
(
- (a_BlockFace == BLOCK_FACE_TOP) || // Clicking the top of a bottom slab
- (a_BlockFace == BLOCK_FACE_BOTTOM) // Clicking the bottom of a top slab
+ (a_BlockFace == BLOCK_FACE_TOP) || // Clicking the top of a bottom slab
+ (a_BlockFace == BLOCK_FACE_BOTTOM) // Clicking the bottom of a top slab
)
)
{
@@ -1138,7 +1140,7 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, e
// The actual block placement:
World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, BlockType, BlockMeta);
- if (m_Player->GetGameMode() != gmCreative)
+ if (!m_Player->IsGameModeCreative())
{
m_Player->GetInventory().RemoveOneEquippedItem();
}
diff --git a/src/Items/ItemBucket.h b/src/Items/ItemBucket.h
index 72cb8fa0a..68c89dd85 100644
--- a/src/Items/ItemBucket.h
+++ b/src/Items/ItemBucket.h
@@ -172,12 +172,12 @@ public:
virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, char a_EntryFace) override
{
- if (a_BlockMeta != 0) // Even if it was a water block it would not be a source.
- {
- return false;
- }
if (IsBlockWater(a_BlockType) || IsBlockLava(a_BlockType))
{
+ if (a_BlockMeta != 0) // GetBlockFromTrace is called for scooping up fluids; the hit block should be a source
+ {
+ return false;
+ }
m_HasHitFluid = true;
m_Pos.Set(a_BlockX, a_BlockY, a_BlockZ);
return true;
diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp
index 454fabdd7..337b3a83c 100644
--- a/src/Items/ItemHandler.cpp
+++ b/src/Items/ItemHandler.cpp
@@ -27,6 +27,7 @@
#include "ItemHoe.h"
#include "ItemLeaves.h"
#include "ItemLighter.h"
+#include "ItemLilypad.h"
#include "ItemMap.h"
#include "ItemMinecart.h"
#include "ItemNetherWart.h"
@@ -115,6 +116,7 @@ cItemHandler *cItemHandler::CreateItemHandler(int a_ItemType)
case E_ITEM_FISHING_ROD: return new cItemFishingRodHandler(a_ItemType);
case E_ITEM_FLINT_AND_STEEL: return new cItemLighterHandler(a_ItemType);
case E_ITEM_FLOWER_POT: return new cItemFlowerPotHandler(a_ItemType);
+ case E_BLOCK_LILY_PAD: return new cItemLilypadHandler(a_ItemType);
case E_ITEM_MAP: return new cItemMapHandler();
case E_ITEM_ITEM_FRAME: return new cItemItemFrameHandler(a_ItemType);
case E_ITEM_NETHER_WART: return new cItemNetherWartHandler(a_ItemType);
diff --git a/src/Items/ItemLilypad.h b/src/Items/ItemLilypad.h
new file mode 100644
index 000000000..5a29abe94
--- /dev/null
+++ b/src/Items/ItemLilypad.h
@@ -0,0 +1,109 @@
+#pragma once
+
+#include "ItemHandler.h"
+#include "../Entities/Player.h"
+#include "Vector3.h"
+#include "../LineBlockTracer.h"
+#include "BlockInfo.h"
+
+
+
+
+
+class cItemLilypadHandler :
+ public cItemHandler
+{
+ typedef cItemHandler super;
+
+public:
+ cItemLilypadHandler(BLOCKTYPE a_BlockType)
+ : cItemHandler(a_BlockType)
+ {
+
+ }
+
+ virtual bool IsPlaceable(void) override
+ {
+ return false; // Set as not placeable so OnItemUse is called
+ }
+
+ virtual bool OnItemUse(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override
+ {
+ if (a_BlockFace > BLOCK_FACE_NONE)
+ {
+ // Clicked on the side of a submerged block; vanilla allows placement, so should we
+ AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
+ a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_LILY_PAD, 0);
+ if (!a_Player->IsGameModeCreative())
+ {
+ a_Player->GetInventory().RemoveOneEquippedItem();
+ }
+ return true;
+ }
+
+ class cCallbacks :
+ public cBlockTracer::cCallbacks
+ {
+ public:
+ cCallbacks(cWorld * a_World) :
+ m_HasHitFluid(false),
+ m_World(a_World)
+ {
+ }
+
+ virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, char a_EntryFace) override
+ {
+ if (IsBlockWater(a_BlockType))
+ {
+ if ((a_BlockMeta != 0) || (a_EntryFace == BLOCK_FACE_NONE)) // The hit block should be a source. The FACE_NONE check is clicking whilst submerged
+ {
+ return false;
+ }
+ a_EntryFace = BLOCK_FACE_YP; // Always place pad at top of water block
+ AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, (eBlockFace)a_EntryFace);
+ BLOCKTYPE Block = m_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ);
+ if (
+ !IsBlockWater(Block) &&
+ cBlockInfo::FullyOccupiesVoxel(Block)
+ )
+ {
+ // Can't place lilypad on air/in another block!
+ return true;
+ }
+ m_HasHitFluid = true;
+ m_Pos.Set(a_BlockX, a_BlockY, a_BlockZ);
+ return true;
+ }
+ return false;
+ }
+
+ Vector3i m_Pos;
+ bool m_HasHitFluid;
+ cWorld * m_World;
+
+ };
+
+ cCallbacks Callbacks(a_World);
+ cLineBlockTracer Tracer(*a_Player->GetWorld(), Callbacks);
+ Vector3d Start(a_Player->GetEyePosition() + a_Player->GetLookVector());
+ Vector3d End(a_Player->GetEyePosition() + a_Player->GetLookVector() * 5);
+
+ Tracer.Trace(Start.x, Start.y, Start.z, End.x, End.y, End.z);
+
+ if (Callbacks.m_HasHitFluid)
+ {
+ a_World->SetBlock(Callbacks.m_Pos.x, Callbacks.m_Pos.y, Callbacks.m_Pos.z, E_BLOCK_LILY_PAD, 0);
+ if (!a_Player->IsGameModeCreative())
+ {
+ a_Player->GetInventory().RemoveOneEquippedItem();
+ }
+ return true;
+ }
+
+ return false;
+ }
+};
+
+
+
+
diff --git a/src/Items/ItemMinecart.h b/src/Items/ItemMinecart.h
index bcaa5635a..25500aeb9 100644
--- a/src/Items/ItemMinecart.h
+++ b/src/Items/ItemMinecart.h
@@ -1,4 +1,3 @@
-
// ItemMinecart.h
// Declares the various minecart ItemHandlers
@@ -72,6 +71,11 @@ public:
}
} // switch (m_ItemType)
Minecart->Initialize(a_World);
+
+ if (!a_Player->IsGameModeCreative())
+ {
+ a_Player->GetInventory().RemoveOneEquippedItem();
+ }
return true;
}
diff --git a/src/Simulator/FluidSimulator.cpp b/src/Simulator/FluidSimulator.cpp
index 61c93ed73..7779573d7 100644
--- a/src/Simulator/FluidSimulator.cpp
+++ b/src/Simulator/FluidSimulator.cpp
@@ -36,6 +36,7 @@ bool cFluidSimulator::CanWashAway(BLOCKTYPE a_BlockType)
case E_BLOCK_COBWEB:
case E_BLOCK_CROPS:
case E_BLOCK_DEAD_BUSH:
+ case E_BLOCK_LILY_PAD:
case E_BLOCK_RAIL:
case E_BLOCK_REDSTONE_TORCH_OFF:
case E_BLOCK_REDSTONE_TORCH_ON: