summaryrefslogtreecommitdiffstats
path: root/src/Blocks
diff options
context:
space:
mode:
authorLane Kolbly <lane@rscheme.org>2017-07-28 18:59:21 +0200
committerTiger Wang <ziwei.tiger@outlook.com>2017-07-28 18:59:21 +0200
commit5402b214b31af60bc96cd4e47e9211715c3e99f5 (patch)
tree3d8b0fe5cc7a3f8c63e365afa9f118d755780ea2 /src/Blocks
parentTentative fix for player-limit race condition (#3862) (diff)
downloadcuberite-5402b214b31af60bc96cd4e47e9211715c3e99f5.tar
cuberite-5402b214b31af60bc96cd4e47e9211715c3e99f5.tar.gz
cuberite-5402b214b31af60bc96cd4e47e9211715c3e99f5.tar.bz2
cuberite-5402b214b31af60bc96cd4e47e9211715c3e99f5.tar.lz
cuberite-5402b214b31af60bc96cd4e47e9211715c3e99f5.tar.xz
cuberite-5402b214b31af60bc96cd4e47e9211715c3e99f5.tar.zst
cuberite-5402b214b31af60bc96cd4e47e9211715c3e99f5.zip
Diffstat (limited to '')
-rw-r--r--src/Blocks/BlockDoor.cpp10
-rw-r--r--src/Blocks/BlockDoor.h2
-rw-r--r--src/Blocks/BlockFence.h80
-rw-r--r--src/Blocks/BlockHandler.cpp23
-rw-r--r--src/Blocks/BlockHandler.h7
-rw-r--r--src/Blocks/CMakeLists.txt1
6 files changed, 122 insertions, 1 deletions
diff --git a/src/Blocks/BlockDoor.cpp b/src/Blocks/BlockDoor.cpp
index c2b0f66d8..2662dc261 100644
--- a/src/Blocks/BlockDoor.cpp
+++ b/src/Blocks/BlockDoor.cpp
@@ -106,6 +106,16 @@ void cBlockDoorHandler::OnCancelRightClick(cChunkInterface & a_ChunkInterface, c
+cBoundingBox cBlockDoorHandler::GetPlacementCollisionBox(BLOCKTYPE a_XM, BLOCKTYPE a_XP, BLOCKTYPE a_YM, BLOCKTYPE a_YP, BLOCKTYPE a_ZM, BLOCKTYPE a_ZP)
+{
+ // Doors can be placed inside the player
+ return cBoundingBox(0, 0, 0, 0, 0, 0);
+}
+
+
+
+
+
NIBBLETYPE cBlockDoorHandler::MetaRotateCCW(NIBBLETYPE a_Meta)
{
if (a_Meta & 0x08)
diff --git a/src/Blocks/BlockDoor.h b/src/Blocks/BlockDoor.h
index a19cbdc40..4b9eaa320 100644
--- a/src/Blocks/BlockDoor.h
+++ b/src/Blocks/BlockDoor.h
@@ -52,6 +52,8 @@ public:
return true;
}
+ virtual cBoundingBox GetPlacementCollisionBox(BLOCKTYPE a_XM, BLOCKTYPE a_XP, BLOCKTYPE a_YM, BLOCKTYPE a_YP, BLOCKTYPE a_ZM, BLOCKTYPE a_ZP) override;
+
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
{
if ((a_BlockMeta & 0x08) != 0) // is top part of door
diff --git a/src/Blocks/BlockFence.h b/src/Blocks/BlockFence.h
new file mode 100644
index 000000000..92f52cbbe
--- /dev/null
+++ b/src/Blocks/BlockFence.h
@@ -0,0 +1,80 @@
+
+#pragma once
+
+#include "BlockHandler.h"
+#include "BlockID.h"
+#include "../BoundingBox.h"
+
+
+
+
+class cBlockFenceHandler :
+ public cBlockHandler
+{
+public:
+ // These are the min and max coordinates (X and Z) for a straight fence.
+ // 0.4 and 0.6 are really just guesses, but they seem pretty good.
+ // (0.4 to 0.6 is a fence that's 0.2 wide, down the center of the block)
+ const double MIN_COORD = 0.4;
+ const double MAX_COORD = 0.6;
+
+ cBlockFenceHandler(BLOCKTYPE a_BlockType)
+ : cBlockHandler(a_BlockType)
+ {
+ }
+
+ virtual cBoundingBox GetPlacementCollisionBox(BLOCKTYPE a_XM, BLOCKTYPE a_XP, BLOCKTYPE a_YM, BLOCKTYPE a_YP, BLOCKTYPE a_ZM, BLOCKTYPE a_ZP) override
+ {
+ bool XMSolid = cBlockInfo::IsSolid(a_XM);
+ bool XPSolid = cBlockInfo::IsSolid(a_XP);
+ bool ZMSolid = cBlockInfo::IsSolid(a_ZM);
+ bool ZPSolid = cBlockInfo::IsSolid(a_ZP);
+
+ double FENCE_HEIGHT = cBlockInfo::GetBlockHeight(m_BlockType);
+
+ // Entities can never be in the center
+ cBoundingBox PlacementBox(MIN_COORD, MAX_COORD, 0, FENCE_HEIGHT, MIN_COORD, MAX_COORD);
+
+ // For each solid neighbor, the hitbox extends that way
+ if (XMSolid)
+ {
+ PlacementBox = PlacementBox.Union(cBoundingBox(0, 0.5, 0, FENCE_HEIGHT, MIN_COORD, MAX_COORD));
+ }
+ if (XPSolid)
+ {
+ PlacementBox = PlacementBox.Union(cBoundingBox(0.5, 1.0, 0, FENCE_HEIGHT, MIN_COORD, MAX_COORD));
+ }
+ if (ZMSolid)
+ {
+ PlacementBox = PlacementBox.Union(cBoundingBox(MIN_COORD, MAX_COORD, 0, FENCE_HEIGHT, 0.0, 0.5));
+ }
+ if (ZPSolid)
+ {
+ PlacementBox = PlacementBox.Union(cBoundingBox(MIN_COORD, MAX_COORD, 0, FENCE_HEIGHT, 0.5, 1.0));
+ }
+
+ // For each corner, fill in the corner
+ if (XMSolid && ZMSolid)
+ {
+ PlacementBox = PlacementBox.Union(cBoundingBox(0, 0.5, 0, FENCE_HEIGHT, 0, 0.5));
+ }
+ if (XPSolid && ZMSolid)
+ {
+ PlacementBox = PlacementBox.Union(cBoundingBox(0.5, 1.0, 0, FENCE_HEIGHT, 0, 0.5));
+ }
+ if (XPSolid && ZPSolid)
+ {
+ PlacementBox = PlacementBox.Union(cBoundingBox(0.5, 1.0, 0, FENCE_HEIGHT, 0.5, 1.0));
+ }
+ if (XMSolid && ZPSolid)
+ {
+ PlacementBox = PlacementBox.Union(cBoundingBox(0, 0.5, 0, FENCE_HEIGHT, 0.5, 1.0));
+ }
+
+ return PlacementBox;
+ }
+};
+
+
+
+
diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp
index 4b37d42ad..305676984 100644
--- a/src/Blocks/BlockHandler.cpp
+++ b/src/Blocks/BlockHandler.cpp
@@ -29,6 +29,7 @@
#include "BlockEnderchest.h"
#include "BlockEntity.h"
#include "BlockFarmland.h"
+#include "BlockFence.h"
#include "BlockFenceGate.h"
#include "BlockFire.h"
#include "BlockFlower.h"
@@ -181,6 +182,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
{
// Block handlers, alphabetically sorted:
case E_BLOCK_ACACIA_DOOR: return new cBlockDoorHandler (a_BlockType);
+ case E_BLOCK_ACACIA_FENCE: return new cBlockFenceHandler (a_BlockType);
case E_BLOCK_ACACIA_FENCE_GATE: return new cBlockFenceGateHandler (a_BlockType);
case E_BLOCK_ACACIA_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType);
case E_BLOCK_ACTIVATOR_RAIL: return new cBlockRailHandler (a_BlockType);
@@ -190,6 +192,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
case E_BLOCK_BEETROOTS: return new cBlockCropsHandler<3> (a_BlockType); // 4 stages of growth
case E_BLOCK_BIG_FLOWER: return new cBlockBigFlowerHandler (a_BlockType);
case E_BLOCK_BIRCH_DOOR: return new cBlockDoorHandler (a_BlockType);
+ case E_BLOCK_BIRCH_FENCE: return new cBlockFenceHandler (a_BlockType);
case E_BLOCK_BIRCH_FENCE_GATE: return new cBlockFenceGateHandler (a_BlockType);
case E_BLOCK_BIRCH_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType);
case E_BLOCK_BREWING_STAND: return new cBlockBrewingStandHandler (a_BlockType);
@@ -212,6 +215,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
case E_BLOCK_COBWEB: return new cBlockCobWebHandler (a_BlockType);
case E_BLOCK_CROPS: return new cBlockCropsHandler<7> (a_BlockType); // 8 stages of growth
case E_BLOCK_DARK_OAK_DOOR: return new cBlockDoorHandler (a_BlockType);
+ case E_BLOCK_DARK_OAK_FENCE: return new cBlockFenceHandler (a_BlockType);
case E_BLOCK_DARK_OAK_FENCE_GATE: return new cBlockFenceGateHandler (a_BlockType);
case E_BLOCK_DARK_OAK_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType);
case E_BLOCK_DEAD_BUSH: return new cBlockDeadBushHandler (a_BlockType);
@@ -227,6 +231,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
case E_BLOCK_ENCHANTMENT_TABLE: return new cBlockEnchantmentTableHandler(a_BlockType);
case E_BLOCK_ENDER_CHEST: return new cBlockEnderchestHandler (a_BlockType);
case E_BLOCK_FARMLAND: return new cBlockFarmlandHandler (a_BlockType);
+ case E_BLOCK_FENCE: return new cBlockFenceHandler (a_BlockType);
case E_BLOCK_FROSTED_ICE: return new cBlockIceHandler (a_BlockType);
case E_BLOCK_FIRE: return new cBlockFireHandler (a_BlockType);
case E_BLOCK_FLOWER_POT: return new cBlockFlowerPotHandler (a_BlockType);
@@ -249,6 +254,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
case E_BLOCK_JACK_O_LANTERN: return new cBlockPumpkinHandler (a_BlockType);
case E_BLOCK_JUKEBOX: return new cBlockEntityHandler (a_BlockType);
case E_BLOCK_JUNGLE_DOOR: return new cBlockDoorHandler (a_BlockType);
+ case E_BLOCK_JUNGLE_FENCE: return new cBlockFenceHandler (a_BlockType);
case E_BLOCK_JUNGLE_FENCE_GATE: return new cBlockFenceGateHandler (a_BlockType);
case E_BLOCK_JUNGLE_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType);
case E_BLOCK_LADDER: return new cBlockLadderHandler (a_BlockType);
@@ -264,6 +270,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
case E_BLOCK_MELON_STEM: return new cBlockStemsHandler (a_BlockType);
case E_BLOCK_MOB_SPAWNER: return new cBlockMobSpawnerHandler (a_BlockType);
case E_BLOCK_MYCELIUM: return new cBlockMyceliumHandler (a_BlockType);
+ case E_BLOCK_NETHER_BRICK_FENCE: return new cBlockFenceHandler (a_BlockType);
case E_BLOCK_NETHER_BRICK_STAIRS: return new cBlockStairsHandler (a_BlockType);
case E_BLOCK_NETHER_PORTAL: return new cBlockPortalHandler (a_BlockType);
case E_BLOCK_NETHER_WART: return new cBlockNetherWartHandler (a_BlockType);
@@ -308,6 +315,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
case E_BLOCK_SNOW: return new cBlockSnowHandler (a_BlockType);
case E_BLOCK_SLIME_BLOCK: return new cBlockSlimeHandler (a_BlockType);
case E_BLOCK_SPRUCE_DOOR: return new cBlockDoorHandler (a_BlockType);
+ case E_BLOCK_SPRUCE_FENCE: return new cBlockFenceHandler (a_BlockType);
case E_BLOCK_SPRUCE_FENCE_GATE: return new cBlockFenceGateHandler (a_BlockType);
case E_BLOCK_SPRUCE_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType);
case E_BLOCK_STAINED_GLASS: return new cBlockGlassHandler (a_BlockType);
@@ -555,7 +563,6 @@ void cBlockHandler::DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterfac
-
bool cBlockHandler::CanBeAt(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ, const cChunk & a_Chunk)
{
return true;
@@ -611,6 +618,20 @@ bool cBlockHandler::IsInsideBlock(const Vector3d & a_Position, const BLOCKTYPE a
+cBoundingBox cBlockHandler::GetPlacementCollisionBox(BLOCKTYPE a_XM, BLOCKTYPE a_XP, BLOCKTYPE a_YM, BLOCKTYPE a_YP, BLOCKTYPE a_ZM, BLOCKTYPE a_ZP)
+{
+ if (!cBlockInfo::IsSolid(m_BlockType))
+ {
+ // Non-solid things can be placed within entities
+ return cBoundingBox(0, 0, 0, 0, 0, 0);
+ }
+ return cBoundingBox(0, 1, 0, cBlockInfo::GetBlockHeight(m_BlockType), 0, 1);
+}
+
+
+
+
+
void cBlockHandler::Check(cChunkInterface & a_ChunkInterface, cBlockPluginInterface & a_PluginInterface, int a_RelX, int a_RelY, int a_RelZ, cChunk & a_Chunk)
{
if (!CanBeAt(a_ChunkInterface, a_RelX, a_RelY, a_RelZ, a_Chunk))
diff --git a/src/Blocks/BlockHandler.h b/src/Blocks/BlockHandler.h
index 302fdbc4b..e67058830 100644
--- a/src/Blocks/BlockHandler.h
+++ b/src/Blocks/BlockHandler.h
@@ -3,6 +3,8 @@
#include "../Defines.h"
+#include "../BoundingBox.h"
+
@@ -30,6 +32,11 @@ public:
Note that the coords are chunk-relative! */
virtual void OnUpdate(cChunkInterface & cChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_BlockPluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ);
+ /** Returns the relative bounding box that must be entity-free in
+ order for the block to be placed. a_XM, a_XP, etc. stand for the
+ blocktype of the minus-X neighbor, the positive-X neighbor, etc. */
+ virtual cBoundingBox GetPlacementCollisionBox(BLOCKTYPE a_XM, BLOCKTYPE a_XP, BLOCKTYPE a_YM, BLOCKTYPE a_YP, BLOCKTYPE a_ZM, BLOCKTYPE a_ZP);
+
/** Called before a block is placed into a world.
The handler should return true to allow placement, false to refuse.
Also, the handler should set a_BlockType and a_BlockMeta to correct values for the newly placed block.
diff --git a/src/Blocks/CMakeLists.txt b/src/Blocks/CMakeLists.txt
index 9f46a6809..bc1b62290 100644
--- a/src/Blocks/CMakeLists.txt
+++ b/src/Blocks/CMakeLists.txt
@@ -35,6 +35,7 @@ SET (HDRS
BlockEnderchest.h
BlockEntity.h
BlockFarmland.h
+ BlockFence.h
BlockFenceGate.h
BlockFire.h
BlockFlower.h