summaryrefslogtreecommitdiffstats
path: root/src/Blocks
diff options
context:
space:
mode:
Diffstat (limited to 'src/Blocks')
-rw-r--r--src/Blocks/BlockDirt.h2
-rw-r--r--src/Blocks/BlockHandler.cpp5
-rw-r--r--src/Blocks/BlockHayBale.h22
-rw-r--r--src/Blocks/BlockPluginInterface.h11
-rw-r--r--src/Blocks/BlockStone.h2
-rw-r--r--src/Blocks/BlockTorch.h124
-rw-r--r--src/Blocks/BlockVine.h12
-rw-r--r--src/Blocks/CMakeLists.txt1
8 files changed, 77 insertions, 102 deletions
diff --git a/src/Blocks/BlockDirt.h b/src/Blocks/BlockDirt.h
index 19f889372..89dfc963d 100644
--- a/src/Blocks/BlockDirt.h
+++ b/src/Blocks/BlockDirt.h
@@ -89,7 +89,7 @@ public:
Chunk->GetBlockTypeMeta(BlockX, BlockY + 1, BlockZ, AboveDest, AboveMeta);
if (cBlockInfo::GetHandler(AboveDest)->CanDirtGrowGrass(AboveMeta))
{
- if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread(Chunk->GetWorld(), Chunk->GetPosX() * cChunkDef::Width + BlockX, BlockY, Chunk->GetPosZ() * cChunkDef::Width + BlockZ, ssGrassSpread))
+ if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread(*Chunk->GetWorld(), Chunk->GetPosX() * cChunkDef::Width + BlockX, BlockY, Chunk->GetPosZ() * cChunkDef::Width + BlockZ, ssGrassSpread))
{
Chunk->FastSetBlock(BlockX, BlockY, BlockZ, E_BLOCK_GRASS, 0);
}
diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp
index ff0b201e7..b6ef5dd6f 100644
--- a/src/Blocks/BlockHandler.cpp
+++ b/src/Blocks/BlockHandler.cpp
@@ -4,6 +4,7 @@
#include "../Item.h"
#include "../World.h"
#include "../Chunk.h"
+#include "BlockPluginInterface.h"
#include "BlockAnvil.h"
#include "BlockBed.h"
#include "BlockBigFlower.h"
@@ -36,7 +37,6 @@
#include "BlockGlass.h"
#include "BlockGlowstone.h"
#include "BlockGravel.h"
-#include "BlockHayBale.h"
#include "BlockMobHead.h"
#include "BlockHopper.h"
#include "BlockIce.h"
@@ -83,7 +83,6 @@
#include "BlockWorkbench.h"
-#include "BlockPluginInterface.h"
@@ -231,7 +230,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
case E_BLOCK_GLASS_PANE: return new cBlockGlassHandler (a_BlockType);
case E_BLOCK_GRASS: return new cBlockDirtHandler (a_BlockType);
case E_BLOCK_GRAVEL: return new cBlockGravelHandler (a_BlockType);
- case E_BLOCK_HAY_BALE: return new cBlockHayBaleHandler (a_BlockType);
+ case E_BLOCK_HAY_BALE: return new cBlockSidewaysHandler (a_BlockType);
case E_BLOCK_HEAD: return new cBlockMobHeadHandler (a_BlockType);
case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE: return new cBlockPressurePlateHandler(a_BlockType);
case E_BLOCK_HOPPER: return new cBlockHopperHandler (a_BlockType);
diff --git a/src/Blocks/BlockHayBale.h b/src/Blocks/BlockHayBale.h
deleted file mode 100644
index 8150b10d3..000000000
--- a/src/Blocks/BlockHayBale.h
+++ /dev/null
@@ -1,22 +0,0 @@
-
-#pragma once
-
-#include "BlockSideways.h"
-
-
-
-
-
-class cBlockHayBaleHandler :
- public cBlockSidewaysHandler
-{
-public:
- cBlockHayBaleHandler(BLOCKTYPE a_BlockType)
- : cBlockSidewaysHandler(a_BlockType)
- {
- }
-} ;
-
-
-
-
diff --git a/src/Blocks/BlockPluginInterface.h b/src/Blocks/BlockPluginInterface.h
index 3a36c40b1..b769bcf3e 100644
--- a/src/Blocks/BlockPluginInterface.h
+++ b/src/Blocks/BlockPluginInterface.h
@@ -1,7 +1,11 @@
#pragma once
-/** This interface is used to decouple block handlers from the cPluginManager dependancy through cWorld.
+
+
+
+
+/** This interface is used to decouple block handlers from the cPluginManager dependency through cWorld.
The block handlers call this interface, which is then implemented by the specific classes that
the caller provides.
*/
@@ -10,5 +14,10 @@ class cBlockPluginInterface
public:
virtual ~cBlockPluginInterface() {}
+ virtual bool CallHookBlockSpread(int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source) = 0;
virtual bool CallHookBlockToPickups(cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups) = 0;
};
+
+
+
+
diff --git a/src/Blocks/BlockStone.h b/src/Blocks/BlockStone.h
index e52599c0f..69cc8301b 100644
--- a/src/Blocks/BlockStone.h
+++ b/src/Blocks/BlockStone.h
@@ -18,7 +18,7 @@ public:
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
{
- if (a_BlockMeta == E_META_STONE)
+ if (a_BlockMeta == E_META_STONE_STONE)
{
a_Pickups.push_back(cItem(E_BLOCK_COBBLESTONE, 1, 0));
return;
diff --git a/src/Blocks/BlockTorch.h b/src/Blocks/BlockTorch.h
index dd252f2a4..e77bbd1b8 100644
--- a/src/Blocks/BlockTorch.h
+++ b/src/Blocks/BlockTorch.h
@@ -24,32 +24,23 @@ public:
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{
- // Find proper placement of torch
+ BLOCKTYPE Block;
+ NIBBLETYPE Meta;
+ AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, true); // Set to clicked block
+ a_ChunkInterface.GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, Block, Meta);
- if ((a_BlockFace == BLOCK_FACE_TOP) || (a_BlockFace == BLOCK_FACE_BOTTOM))
+ if (!CanBePlacedOn(Block, Meta, a_BlockFace)) // Try to preserve original direction
{
- a_BlockFace = FindSuitableFace(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); // Top or bottom faces clicked, find a suitable face
+ // Torch couldn't be placed on whatever face was clicked, last ditch resort - find another face
+
+ AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, false); // Reset to torch block
+ a_BlockFace = FindSuitableFace(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); // Set a_BlockFace to a valid direction which will be converted later to a metadata
if (a_BlockFace == BLOCK_FACE_NONE)
{
- // Client wouldn't have sent anything anyway, but whatever
+ // No attachable face found - don't place the torch
return false;
}
}
- else
- {
- // Not top or bottom faces, try to preserve whatever face was clicked
- AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, true); // Set to clicked block
- if (!CanBePlacedOn(a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ), a_BlockFace))
- {
- AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, false); // Reset to torch block
- // Torch couldn't be placed on whatever face was clicked, last ditch resort - find another face
- a_BlockFace = FindSuitableFace(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ);
- if (a_BlockFace == BLOCK_FACE_NONE)
- {
- return false;
- }
- }
- }
a_BlockType = m_BlockType;
a_BlockMeta = DirectionToMetaData(a_BlockFace);
@@ -97,46 +88,57 @@ public:
}
- static bool CanBePlacedOn(BLOCKTYPE a_BlockType, eBlockFace a_BlockFace)
+ static bool CanBePlacedOn(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, eBlockFace a_BlockFace)
{
- if (!cBlockInfo::FullyOccupiesVoxel(a_BlockType))
- {
- return (a_BlockFace == BLOCK_FACE_TOP); // Allow placement only when torch upright (for glass, etc.); exceptions won't even be sent by client, no need to handle
- }
- else
+ switch (a_BlockType)
{
- return true;
+ case E_BLOCK_END_PORTAL_FRAME:
+ case E_BLOCK_SOULSAND:
+ {
+ // Exceptional vanilla behaviour
+ return true;
+ }
+ case E_BLOCK_GLASS:
+ case E_BLOCK_STAINED_GLASS:
+ case E_BLOCK_FENCE:
+ case E_BLOCK_NETHER_BRICK_FENCE:
+ case E_BLOCK_COBBLESTONE_WALL:
+ {
+ // Torches can only be placed on top of these blocks
+ return (a_BlockFace == BLOCK_FACE_YP);
+ }
+ case E_BLOCK_STONE_SLAB:
+ case E_BLOCK_WOODEN_SLAB:
+ {
+ // Toches can be placed on the top of these slabs only if the occupy the top half of the voxel
+ return ((a_BlockFace == BLOCK_FACE_YP) && ((a_BlockMeta & 0x08) == 0x08));
+ }
+ default:
+ {
+ if (cBlockInfo::FullyOccupiesVoxel(a_BlockType))
+ {
+ // Torches can be placed on all sides of full blocks except the bottom
+ return (a_BlockFace != BLOCK_FACE_YM);
+ }
+ return false;
+ }
}
}
- /// Finds a suitable face to place the torch, returning BLOCK_FACE_NONE on failure
+ /** Finds a suitable face to place the torch, returning BLOCK_FACE_NONE on failure */
static eBlockFace FindSuitableFace(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ)
{
for (int i = BLOCK_FACE_YM; i <= BLOCK_FACE_XP; i++) // Loop through all directions
{
eBlockFace Face = static_cast<eBlockFace>(i);
AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, Face, true);
- BLOCKTYPE BlockInQuestion = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ);
-
- // If on a block that can only hold a torch if torch is standing on it, return that face
- if (
- (
- (BlockInQuestion == E_BLOCK_GLASS) ||
- (BlockInQuestion == E_BLOCK_FENCE) ||
- (BlockInQuestion == E_BLOCK_NETHER_BRICK_FENCE) ||
- (BlockInQuestion == E_BLOCK_COBBLESTONE_WALL) ||
- (BlockInQuestion == E_BLOCK_STONE_SLAB) ||
- (BlockInQuestion == E_BLOCK_WOODEN_SLAB)
- ) &&
- (Face == BLOCK_FACE_TOP)
- )
- {
- return Face;
- }
- else if (cBlockInfo::FullyOccupiesVoxel(BlockInQuestion) && (i != BLOCK_FACE_BOTTOM))
+ BLOCKTYPE BlockInQuestion;
+ NIBBLETYPE BlockInQuestionMeta;
+ a_ChunkInterface.GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, BlockInQuestion, BlockInQuestionMeta);
+
+ if (CanBePlacedOn(BlockInQuestion, BlockInQuestionMeta, Face))
{
- // Otherwise, if block in that direction is torch placeable and we haven't gotten to it via the bottom face, return that face
return Face;
}
else
@@ -152,36 +154,16 @@ public:
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
{
eBlockFace Face = MetaDataToDirection(a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ));
-
AddFaceDirection(a_RelX, a_RelY, a_RelZ, Face, true);
+
BLOCKTYPE BlockInQuestion;
- a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockInQuestion);
-
- if (
- (BlockInQuestion == E_BLOCK_GLASS) ||
- (BlockInQuestion == E_BLOCK_STAINED_GLASS) ||
- (BlockInQuestion == E_BLOCK_FENCE) ||
- (BlockInQuestion == E_BLOCK_SOULSAND) ||
- (BlockInQuestion == E_BLOCK_MOB_SPAWNER) ||
- (BlockInQuestion == E_BLOCK_END_PORTAL_FRAME) || // Actual vanilla behaviour
- (BlockInQuestion == E_BLOCK_NETHER_BRICK_FENCE) ||
- (BlockInQuestion == E_BLOCK_COBBLESTONE_WALL) ||
- (BlockInQuestion == E_BLOCK_STONE_SLAB) ||
- (BlockInQuestion == E_BLOCK_WOODEN_SLAB)
- )
- {
- // Torches can be placed on tops of glass and fences, despite them being 'untorcheable'
- // No need to check for upright orientation, it was done when the torch was placed
- return true;
- }
- else if (!cBlockInfo::FullyOccupiesVoxel(BlockInQuestion))
+ NIBBLETYPE BlockInQuestionMeta;
+ if (!a_Chunk.UnboundedRelGetBlock(a_RelX, a_RelY, a_RelZ, BlockInQuestion, BlockInQuestionMeta))
{
return false;
}
- else
- {
- return true;
- }
+
+ return CanBePlacedOn(BlockInQuestion, BlockInQuestionMeta, Face);
}
diff --git a/src/Blocks/BlockVine.h b/src/Blocks/BlockVine.h
index 06d84f2d4..213324cc1 100644
--- a/src/Blocks/BlockVine.h
+++ b/src/Blocks/BlockVine.h
@@ -166,23 +166,31 @@ public:
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)
{
UNUSED(a_ChunkInterface);
UNUSED(a_WorldInterface);
- UNUSED(a_BlockPluginInterface);
+ // Vine cannot grow down if at the bottom:
+ if (a_RelY < 1)
+ {
+ return;
+ }
+
+ // Grow one block down, if possible:
BLOCKTYPE Block;
a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY - 1, a_RelZ, Block);
if (Block == E_BLOCK_AIR)
{
- if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread((cWorld*) &a_WorldInterface, a_RelX + a_Chunk.GetPosX() * cChunkDef::Width, a_RelY - 1, a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width, ssVineSpread))
+ if (!a_BlockPluginInterface.CallHookBlockSpread(a_RelX + a_Chunk.GetPosX() * cChunkDef::Width, a_RelY - 1, a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width, ssVineSpread))
{
a_Chunk.UnboundedRelSetBlock(a_RelX, a_RelY - 1, a_RelZ, E_BLOCK_VINES, a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ));
}
}
}
+
virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override
{
return ((a_Meta >> 1) | (a_Meta << 3)) & 0x0f; // Rotate bits to the right
diff --git a/src/Blocks/CMakeLists.txt b/src/Blocks/CMakeLists.txt
index 9f971a8bd..eed949aab 100644
--- a/src/Blocks/CMakeLists.txt
+++ b/src/Blocks/CMakeLists.txt
@@ -45,7 +45,6 @@ SET (HDRS
BlockGlowstone.h
BlockGravel.h
BlockHandler.h
- BlockHayBale.h
BlockHopper.h
BlockIce.h
BlockLadder.h