1
0
Fork 0

BlockHandler initialisation is a constant expression (#4891)

* BlockHandler initialisation is a constant expression

If we can't make it all namespaces, this is the next best I guess.

+ Tag handlers constexpr, const as needed
+ Inherit constructors
* Privatise handler functions

* More constexpr

Co-authored-by: Alexander Harkness <me@bearbin.net>
This commit is contained in:
Tiger Wang 2020-09-20 14:50:52 +01:00 committed by GitHub
parent 6a0669fb98
commit 68cced73af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
115 changed files with 1773 additions and 2242 deletions

View File

@ -1067,7 +1067,7 @@ void cBlockArea::RotateCCW(void)
auto NewIdx = MakeIndexForSize({ NewX, y, NewZ }, { m_Size.z, m_Size.y, m_Size.x }); auto NewIdx = MakeIndexForSize({ NewX, y, NewZ }, { m_Size.z, m_Size.y, m_Size.x });
auto OldIdx = MakeIndex(x, y, z); auto OldIdx = MakeIndex(x, y, z);
NewTypes[NewIdx] = m_BlockTypes[OldIdx]; NewTypes[NewIdx] = m_BlockTypes[OldIdx];
NewMetas[NewIdx] = BlockHandler(m_BlockTypes[OldIdx])->MetaRotateCCW(m_BlockMetas[OldIdx]); NewMetas[NewIdx] = cBlockHandler::For(m_BlockTypes[OldIdx]).MetaRotateCCW(m_BlockMetas[OldIdx]);
} // for y } // for y
} // for z } // for z
} // for x } // for x
@ -1127,7 +1127,7 @@ void cBlockArea::RotateCW(void)
auto NewIdx = MakeIndexForSize({ NewX, y, NewZ }, { m_Size.z, m_Size.y, m_Size.x }); auto NewIdx = MakeIndexForSize({ NewX, y, NewZ }, { m_Size.z, m_Size.y, m_Size.x });
auto OldIdx = MakeIndex(x, y, z); auto OldIdx = MakeIndex(x, y, z);
NewTypes[NewIdx] = m_BlockTypes[OldIdx]; NewTypes[NewIdx] = m_BlockTypes[OldIdx];
NewMetas[NewIdx] = BlockHandler(m_BlockTypes[OldIdx])->MetaRotateCW(m_BlockMetas[OldIdx]); NewMetas[NewIdx] = cBlockHandler::For(m_BlockTypes[OldIdx]).MetaRotateCW(m_BlockMetas[OldIdx]);
} // for y } // for y
} // for z } // for z
} // for x } // for x
@ -1185,8 +1185,8 @@ void cBlockArea::MirrorXY(void)
auto Idx1 = MakeIndex(x, y, z); auto Idx1 = MakeIndex(x, y, z);
auto Idx2 = MakeIndex(x, y, MaxZ - z); auto Idx2 = MakeIndex(x, y, MaxZ - z);
std::swap(m_BlockTypes[Idx1], m_BlockTypes[Idx2]); std::swap(m_BlockTypes[Idx1], m_BlockTypes[Idx2]);
NIBBLETYPE Meta1 = BlockHandler(m_BlockTypes[Idx2])->MetaMirrorXY(m_BlockMetas[Idx1]); NIBBLETYPE Meta1 = cBlockHandler::For(m_BlockTypes[Idx2]).MetaMirrorXY(m_BlockMetas[Idx1]);
NIBBLETYPE Meta2 = BlockHandler(m_BlockTypes[Idx1])->MetaMirrorXY(m_BlockMetas[Idx2]); NIBBLETYPE Meta2 = cBlockHandler::For(m_BlockTypes[Idx1]).MetaMirrorXY(m_BlockMetas[Idx2]);
m_BlockMetas[Idx1] = Meta2; m_BlockMetas[Idx1] = Meta2;
m_BlockMetas[Idx2] = Meta1; m_BlockMetas[Idx2] = Meta1;
} // for x } // for x
@ -1242,8 +1242,8 @@ void cBlockArea::MirrorXZ(void)
auto Idx1 = MakeIndex(x, y, z); auto Idx1 = MakeIndex(x, y, z);
auto Idx2 = MakeIndex(x, MaxY - y, z); auto Idx2 = MakeIndex(x, MaxY - y, z);
std::swap(m_BlockTypes[Idx1], m_BlockTypes[Idx2]); std::swap(m_BlockTypes[Idx1], m_BlockTypes[Idx2]);
NIBBLETYPE Meta1 = BlockHandler(m_BlockTypes[Idx2])->MetaMirrorXZ(m_BlockMetas[Idx1]); NIBBLETYPE Meta1 = cBlockHandler::For(m_BlockTypes[Idx2]).MetaMirrorXZ(m_BlockMetas[Idx1]);
NIBBLETYPE Meta2 = BlockHandler(m_BlockTypes[Idx1])->MetaMirrorXZ(m_BlockMetas[Idx2]); NIBBLETYPE Meta2 = cBlockHandler::For(m_BlockTypes[Idx1]).MetaMirrorXZ(m_BlockMetas[Idx2]);
m_BlockMetas[Idx1] = Meta2; m_BlockMetas[Idx1] = Meta2;
m_BlockMetas[Idx2] = Meta1; m_BlockMetas[Idx2] = Meta1;
} // for x } // for x
@ -1299,8 +1299,8 @@ void cBlockArea::MirrorYZ(void)
auto Idx1 = MakeIndex(x, y, z); auto Idx1 = MakeIndex(x, y, z);
auto Idx2 = MakeIndex(MaxX - x, y, z); auto Idx2 = MakeIndex(MaxX - x, y, z);
std::swap(m_BlockTypes[Idx1], m_BlockTypes[Idx2]); std::swap(m_BlockTypes[Idx1], m_BlockTypes[Idx2]);
NIBBLETYPE Meta1 = BlockHandler(m_BlockTypes[Idx2])->MetaMirrorYZ(m_BlockMetas[Idx1]); NIBBLETYPE Meta1 = cBlockHandler::For(m_BlockTypes[Idx2]).MetaMirrorYZ(m_BlockMetas[Idx1]);
NIBBLETYPE Meta2 = BlockHandler(m_BlockTypes[Idx1])->MetaMirrorYZ(m_BlockMetas[Idx2]); NIBBLETYPE Meta2 = cBlockHandler::For(m_BlockTypes[Idx1]).MetaMirrorYZ(m_BlockMetas[Idx2]);
m_BlockMetas[Idx1] = Meta2; m_BlockMetas[Idx1] = Meta2;
m_BlockMetas[Idx2] = Meta1; m_BlockMetas[Idx2] = Meta1;
} // for x } // for x
@ -2204,21 +2204,6 @@ bool cBlockArea::ForEachBlockEntity(cBlockEntityCallback a_Callback)
cItems cBlockArea::PickupsFromBlock(Vector3i a_AbsPos, const cEntity * a_Digger, const cItem * a_Tool)
{
auto relPos = a_AbsPos - m_Origin;
BLOCKTYPE blockType;
NIBBLETYPE blockMeta;
GetRelBlockTypeMeta(relPos.x, relPos.y, relPos.z, blockType, blockMeta);
auto blockEntity = GetBlockEntityRel(relPos);
auto handler = BlockHandler(blockType);
return handler->ConvertToPickups(blockMeta, blockEntity, a_Digger, a_Tool);
}
void cBlockArea::SetRelNibble(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Value, NIBBLETYPE * a_Array) void cBlockArea::SetRelNibble(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Value, NIBBLETYPE * a_Array)
{ {
if (a_Array == nullptr) if (a_Array == nullptr)

View File

@ -425,8 +425,6 @@ public:
/** Direct read-only access to block entities. */ /** Direct read-only access to block entities. */
const cBlockEntities & GetBlockEntities(void) const { ASSERT(HasBlockEntities()); return *m_BlockEntities; } const cBlockEntities & GetBlockEntities(void) const { ASSERT(HasBlockEntities()); return *m_BlockEntities; }
/** Returns the pickups that would result if the block at the specified position was mined by a_Digger, using a_Tool. */
cItems PickupsFromBlock(Vector3i a_AbsPos, const cEntity * a_Digger = nullptr, const cItem * a_Tool = nullptr);
protected: protected:

View File

@ -2,7 +2,6 @@
#include "BlockInfo.h" #include "BlockInfo.h"
#include "BlockType.h" #include "BlockType.h"
#include "Blocks/BlockHandler.h"
@ -422,15 +421,6 @@ cBlockInfo::cBlockInfo():
cBlockHandler * cBlockInfo::GetHandler(BLOCKTYPE a_Type)
{
return &cBlockHandler::GetBlockHandler(a_Type);
}
float cBlockInfo::GetExplosionAbsorption(const BLOCKTYPE Block) float cBlockInfo::GetExplosionAbsorption(const BLOCKTYPE Block)
{ {
switch (Block) switch (Block)

View File

@ -5,12 +5,6 @@
// fwd:
class cBlockHandler;
// tolua_begin // tolua_begin
class cBlockInfo class cBlockInfo
{ {
@ -54,9 +48,6 @@ public:
/** Creates a default BlockInfo structure, initializes all values to their defaults */ /** Creates a default BlockInfo structure, initializes all values to their defaults */
cBlockInfo(); cBlockInfo();
/** Gets the blockhandler for the given block type. */
static cBlockHandler * GetHandler(BLOCKTYPE a_Type);
private: private:
/** Storage for all the BlockInfo structures. */ /** Storage for all the BlockInfo structures. */
@ -157,13 +148,3 @@ inline const cBlockInfo & cBlockInfo::Get(BLOCKTYPE a_Type)
static const cBlockInfoArray ms_Info; static const cBlockInfoArray ms_Info;
return ms_Info[a_Type]; return ms_Info[a_Type];
} }
// Shortcut to get the blockhandler for a specific block
inline cBlockHandler * BlockHandler(BLOCKTYPE a_BlockType)
{
return cBlockInfo::GetHandler(a_BlockType);
}

View File

@ -17,16 +17,11 @@ class cBlockAnvilHandler:
public: public:
cBlockAnvilHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{ {
return cItem(m_BlockType, 1, a_BlockMeta >> 2); return cItem(m_BlockType, 1, a_BlockMeta >> 2);
} }
@ -42,7 +37,7 @@ public:
const Vector3i a_BlockPos, const Vector3i a_BlockPos,
eBlockFace a_BlockFace, eBlockFace a_BlockFace,
const Vector3i a_CursorPos const Vector3i a_CursorPos
) override ) const override
{ {
cWindow * Window = new cAnvilWindow(a_BlockPos); cWindow * Window = new cAnvilWindow(a_BlockPos);
a_Player.OpenWindow(*Window); a_Player.OpenWindow(*Window);
@ -60,7 +55,7 @@ public:
eBlockFace a_ClickedBlockFace, eBlockFace a_ClickedBlockFace,
const Vector3i a_CursorPos, const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override ) const override
{ {
if (!Super::GetPlacementBlockTypeMeta(a_ChunkInterface, a_Player, a_PlacedBlockPos, a_ClickedBlockFace, a_CursorPos, a_BlockType, a_BlockMeta)) if (!Super::GetPlacementBlockTypeMeta(a_ChunkInterface, a_Player, a_PlacedBlockPos, a_ClickedBlockFace, a_CursorPos, a_BlockType, a_BlockMeta))
{ {
@ -75,7 +70,7 @@ public:
virtual bool IsUseable() override virtual bool IsUseable() const override
{ {
return true; return true;
} }
@ -84,7 +79,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 6; return 6;

View File

@ -19,7 +19,7 @@ void cBlockBedHandler::OnBroken(
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
const Vector3i a_BlockPos, const Vector3i a_BlockPos,
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta
) ) const
{ {
auto Direction = MetaDataToDirection(a_OldBlockMeta & 0x03); auto Direction = MetaDataToDirection(a_OldBlockMeta & 0x03);
if ((a_OldBlockMeta & 0x08) != 0) if ((a_OldBlockMeta & 0x08) != 0)
@ -61,7 +61,7 @@ bool cBlockBedHandler::OnUse(
const Vector3i a_BlockPos, const Vector3i a_BlockPos,
eBlockFace a_BlockFace, eBlockFace a_BlockFace,
const Vector3i a_CursorPos const Vector3i a_CursorPos
) ) const
{ {
// Sleeping in bed only allowed in Overworld, beds explode elsewhere: // Sleeping in bed only allowed in Overworld, beds explode elsewhere:
if (a_WorldInterface.GetDimension() != dimOverworld) if (a_WorldInterface.GetDimension() != dimOverworld)
@ -154,7 +154,7 @@ bool cBlockBedHandler::OnUse(
void cBlockBedHandler::OnPlacedByPlayer(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, const sSetBlock & a_BlockChange) void cBlockBedHandler::OnPlacedByPlayer(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, const sSetBlock & a_BlockChange) const
{ {
a_Player.GetWorld()->DoWithBedAt(a_BlockChange.GetX(), a_BlockChange.GetY(), a_BlockChange.GetZ(), [&](cBedEntity & a_Bed) a_Player.GetWorld()->DoWithBedAt(a_BlockChange.GetX(), a_BlockChange.GetY(), a_BlockChange.GetZ(), [&](cBedEntity & a_Bed)
{ {
@ -168,7 +168,7 @@ void cBlockBedHandler::OnPlacedByPlayer(cChunkInterface & a_ChunkInterface, cWor
cItems cBlockBedHandler::ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) cItems cBlockBedHandler::ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const
{ {
short color = E_META_WOOL_RED; short color = E_META_WOOL_RED;
if (a_BlockEntity != nullptr) if (a_BlockEntity != nullptr)

View File

@ -22,61 +22,20 @@ class cBlockBedHandler :
public: public:
cBlockBedHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
// Overrides:
virtual void OnBroken(
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
const Vector3i a_BlockPos,
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta
) override;
virtual bool OnUse(
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player,
const Vector3i a_ClickedBlockPos,
eBlockFace a_ClickedBlockFace,
const Vector3i a_CursorPos
) override;
virtual cItems ConvertToPickups(
NIBBLETYPE a_BlockMeta,
cBlockEntity * a_BlockEntity,
const cEntity * a_Digger,
const cItem * a_Tool
) override;
virtual void OnPlacedByPlayer(
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player,
const sSetBlock & a_BlockChange
) override;
static Vector3i MetaDataToDirection(NIBBLETYPE a_MetaData) static Vector3i MetaDataToDirection(NIBBLETYPE a_MetaData)
{ {
switch (a_MetaData) switch (a_MetaData)
{ {
case 0: return Vector3i( 0, 0, 1); case 0: return Vector3i(0, 0, 1);
case 1: return Vector3i(-1, 0, 0); case 1: return Vector3i(-1, 0, 0);
case 2: return Vector3i( 0, 0, -1); case 2: return Vector3i(0, 0, -1);
case 3: return Vector3i( 1, 0, 0); case 3: return Vector3i(1, 0, 0);
} }
return Vector3i(); return Vector3i();
} }
static void SetBedOccupationState(cChunkInterface & a_ChunkInterface, Vector3i a_BedPosition, bool a_IsOccupied) static void SetBedOccupationState(cChunkInterface & a_ChunkInterface, Vector3i a_BedPosition, bool a_IsOccupied)
{ {
auto Meta = a_ChunkInterface.GetBlockMeta(a_BedPosition); auto Meta = a_ChunkInterface.GetBlockMeta(a_BedPosition);
@ -92,6 +51,34 @@ public:
a_ChunkInterface.SetBlockMeta(a_BedPosition, Meta); a_ChunkInterface.SetBlockMeta(a_BedPosition, Meta);
} }
private:
// Overrides:
virtual void OnBroken(
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
const Vector3i a_BlockPos,
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta
) const override;
virtual bool OnUse(
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player,
const Vector3i a_ClickedBlockPos,
eBlockFace a_ClickedBlockFace,
const Vector3i a_CursorPos
) const override;
virtual cItems ConvertToPickups(
NIBBLETYPE a_BlockMeta,
cBlockEntity * a_BlockEntity,
const cEntity * a_Digger,
const cItem * a_Tool
) const override;
virtual void OnPlacedByPlayer(
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player,
const sSetBlock & a_BlockChange
) const override;
@ -102,7 +89,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 28; return 28;

View File

@ -16,16 +16,11 @@ class cBlockBigFlowerHandler:
public: public:
cBlockBigFlowerHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual bool DoesIgnoreBuildCollision(cChunkInterface & a_ChunkInterface, Vector3i a_Pos, cPlayer & a_Player, NIBBLETYPE a_Meta) const override
virtual bool DoesIgnoreBuildCollision(cChunkInterface & a_ChunkInterface, Vector3i a_Pos, cPlayer & a_Player, NIBBLETYPE a_Meta) override
{ {
if (IsMetaTopPart(a_Meta)) if (IsMetaTopPart(a_Meta))
{ {
@ -52,7 +47,7 @@ public:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
{ {
if (IsMetaTopPart(a_BlockMeta)) if (IsMetaTopPart(a_BlockMeta))
{ {
@ -86,7 +81,7 @@ public:
bool IsMetaTopPart(NIBBLETYPE a_Meta) static bool IsMetaTopPart(NIBBLETYPE a_Meta)
{ {
return ((a_Meta & 0x08) != 0); return ((a_Meta & 0x08) != 0);
} }
@ -95,7 +90,7 @@ public:
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) const override
{ {
if (a_RelPos.y <= 0) if (a_RelPos.y <= 0)
{ {
@ -112,7 +107,7 @@ public:
virtual void OnBroken(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, const Vector3i a_BlockPos, BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta) override virtual void OnBroken(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, const Vector3i a_BlockPos, BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta) const override
{ {
if ((a_OldBlockMeta & 0x8) != 0) if ((a_OldBlockMeta & 0x8) != 0)
{ {
@ -138,7 +133,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 7; return 7;

View File

@ -1,26 +1,26 @@
#pragma once #pragma once
#include "BlockHandler.h" #include "BlockHandler.h"
class cBlockBookShelfHandler : class cBlockBookShelfHandler :
public cBlockHandler public cBlockHandler
{ {
public: public:
cBlockBookShelfHandler(BLOCKTYPE a_BlockType) :
cBlockHandler(a_BlockType) using cBlockHandler::cBlockHandler;
{
} private:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
{ {
if (ToolHasSilkTouch(a_Tool)) if (ToolHasSilkTouch(a_Tool))
{ {
return cItem(m_BlockType, 1); return cItem(m_BlockType, 1);
} }
return cItem(E_ITEM_BOOK, 3); return cItem(E_ITEM_BOOK, 3);
} }
}; };

View File

@ -15,16 +15,11 @@ class cBlockBrewingStandHandler :
public: public:
cBlockBrewingStandHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{ {
cItems res(cItem(E_ITEM_BREWING_STAND, 1)); // We have to drop the item form of a brewing stand cItems res(cItem(E_ITEM_BREWING_STAND, 1)); // We have to drop the item form of a brewing stand
if (a_BlockEntity != nullptr) if (a_BlockEntity != nullptr)
@ -39,7 +34,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 6; return 6;

View File

@ -16,14 +16,45 @@ class cBlockButtonHandler :
public: public:
cBlockButtonHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
/** Extracts the ON bit from metadata and returns if true if it is set */
static bool IsButtonOn(NIBBLETYPE a_Meta)
{ {
return (a_Meta & 0x08) == 0x08;
} }
/** Event handler for an arrow striking a block.
Performs appropriate handling if the arrow intersected a wooden button. */
static void OnArrowHit(cWorld & a_World, const Vector3i a_Position, const eBlockFace a_HitFace)
{
BLOCKTYPE Type;
NIBBLETYPE Meta;
const auto Pos = AddFaceDirection(a_Position, a_HitFace);
if (
!a_World.GetBlockTypeMeta(Pos, Type, Meta) ||
IsButtonOn(Meta) ||
!IsButtonPressedByArrow(a_World, Pos, Type, Meta)
)
{
// Bail if we're not specifically a wooden button, or it's already on
// or if the arrow didn't intersect. It is very important that nothing is
// done if the button is depressed, since the release task will already be queued
return;
}
a_World.SetBlockMeta(Pos, Meta | 0x08);
a_World.WakeUpSimulators(Pos);
// sound name is ok to be wood, because only wood gets triggered by arrow
a_World.GetBroadcastManager().BroadcastSoundEffect("block.wood_button.click_on", Pos, 0.5f, 0.6f);
// Queue a button reset
QueueButtonRelease(a_World, Pos, Type);
}
private:
virtual bool OnUse( virtual bool OnUse(
cChunkInterface & a_ChunkInterface, cChunkInterface & a_ChunkInterface,
@ -32,7 +63,7 @@ public:
const Vector3i a_BlockPos, const Vector3i a_BlockPos,
eBlockFace a_BlockFace, eBlockFace a_BlockFace,
const Vector3i a_CursorPos const Vector3i a_CursorPos
) override ) const override
{ {
NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockPos); NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockPos);
@ -61,7 +92,7 @@ public:
virtual bool IsUseable(void) override virtual bool IsUseable(void) const override
{ {
return true; return true;
} }
@ -77,7 +108,7 @@ public:
eBlockFace a_ClickedBlockFace, eBlockFace a_ClickedBlockFace,
const Vector3i a_CursorPos, const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override ) const override
{ {
a_BlockType = m_BlockType; a_BlockType = m_BlockType;
a_BlockMeta = BlockFaceToMetaData(a_ClickedBlockFace); a_BlockMeta = BlockFaceToMetaData(a_ClickedBlockFace);
@ -135,7 +166,7 @@ public:
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) const override
{ {
auto Meta = a_Chunk.GetMeta(a_RelPos); auto Meta = a_Chunk.GetMeta(a_RelPos);
auto SupportRelPos = AddFaceDirection(a_RelPos, BlockMetaDataToBlockFace(Meta), true); auto SupportRelPos = AddFaceDirection(a_RelPos, BlockMetaDataToBlockFace(Meta), true);
@ -153,50 +184,12 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 0; return 0;
} }
/** Extracts the ON bit from metadata and returns if true if it is set */
static bool IsButtonOn(NIBBLETYPE a_Meta)
{
return (a_Meta & 0x08) == 0x08;
}
/** Event handler for an arrow striking a block.
Performs appropriate handling if the arrow intersected a wooden button. */
static void OnArrowHit(cWorld & a_World, const Vector3i a_Position, const eBlockFace a_HitFace)
{
BLOCKTYPE Type;
NIBBLETYPE Meta;
const auto Pos = AddFaceDirection(a_Position, a_HitFace);
if (
!a_World.GetBlockTypeMeta(Pos, Type, Meta) ||
IsButtonOn(Meta) ||
!IsButtonPressedByArrow(a_World, Pos, Type, Meta)
)
{
// Bail if we're not specifically a wooden button, or it's already on
// or if the arrow didn't intersect. It is very important that nothing is
// done if the button is depressed, since the release task will already be queued
return;
}
a_World.SetBlockMeta(Pos, Meta | 0x08);
a_World.WakeUpSimulators(Pos);
// sound name is ok to be wood, because only wood gets triggered by arrow
a_World.GetBroadcastManager().BroadcastSoundEffect("block.wood_button.click_on", Pos, 0.5f, 0.6f);
// Queue a button reset
QueueButtonRelease(a_World, Pos, Type);
}
private:
/** Schedules a recurring event at appropriate intervals to release a button at a given position. /** Schedules a recurring event at appropriate intervals to release a button at a given position.
The given block type is checked when the task is executed to ensure the position still contains a button. */ The given block type is checked when the task is executed to ensure the position still contains a button. */
static void QueueButtonRelease(cWorld & a_ButtonWorld, const Vector3i a_Position, const BLOCKTYPE a_BlockType) static void QueueButtonRelease(cWorld & a_ButtonWorld, const Vector3i a_Position, const BLOCKTYPE a_BlockType)

View File

@ -14,14 +14,9 @@ class cBlockCactusHandler :
public: public:
cBlockCactusHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
/** Called before a cactus block is placed by a player, overrides cItemHandler::GetPlacementBlockTypeMeta(). /** Called before a cactus block is placed by a player, overrides cItemHandler::GetPlacementBlockTypeMeta().
Calls CanBeAt function to determine if a cactus block can be placed on a given block. */ Calls CanBeAt function to determine if a cactus block can be placed on a given block. */
@ -32,7 +27,7 @@ public:
eBlockFace a_ClickedBlockFace, eBlockFace a_ClickedBlockFace,
const Vector3i a_CursorPos, const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override ) const override
{ {
if ( if (
a_Player.GetWorld()->DoWithChunkAt(a_PlacedBlockPos, a_Player.GetWorld()->DoWithChunkAt(a_PlacedBlockPos,
@ -57,7 +52,7 @@ public:
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) const override
{ {
if (a_RelPos.y <= 0) if (a_RelPos.y <= 0)
{ {
@ -102,7 +97,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 7; return 7;
@ -111,7 +106,7 @@ public:
virtual int Grow(cChunk & a_Chunk, Vector3i a_RelPos, int a_NumStages = 1) override virtual int Grow(cChunk & a_Chunk, Vector3i a_RelPos, int a_NumStages = 1) const override
{ {
// Check the total height of the cacti blocks here: // Check the total height of the cacti blocks here:
int top = a_RelPos.y + 1; int top = a_RelPos.y + 1;
@ -179,13 +174,7 @@ public:
return numToGrow; return numToGrow;
} }
virtual PlantAction CanGrow(cChunk & a_Chunk, Vector3i a_RelPos) const override
protected:
virtual PlantAction CanGrow(cChunk & a_Chunk, Vector3i a_RelPos) override
{ {
// Only allow growing if there's an air block above: // Only allow growing if there's an air block above:
if (((a_RelPos.y + 1) < cChunkDef::Height) && (a_Chunk.GetBlock(a_RelPos.addedY(1)) == E_BLOCK_AIR)) if (((a_RelPos.y + 1) < cChunkDef::Height) && (a_Chunk.GetBlock(a_RelPos.addedY(1)) == E_BLOCK_AIR))

View File

@ -10,15 +10,12 @@ class cBlockCakeHandler:
public cBlockHandler public cBlockHandler
{ {
using Super = cBlockHandler; using Super = cBlockHandler;
public: public:
cBlockCakeHandler(BLOCKTYPE a_BlockType):
Super(a_BlockType)
{
}
using Super::Super;
private:
virtual bool OnUse( virtual bool OnUse(
cChunkInterface & a_ChunkInterface, cChunkInterface & a_ChunkInterface,
@ -27,7 +24,7 @@ public:
const Vector3i a_BlockPos, const Vector3i a_BlockPos,
eBlockFace a_BlockFace, eBlockFace a_BlockFace,
const Vector3i a_CursorPos const Vector3i a_CursorPos
) override ) const override
{ {
NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockPos); NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockPos);
@ -52,7 +49,7 @@ public:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
{ {
// Give nothing // Give nothing
return {}; return {};
@ -62,12 +59,12 @@ public:
virtual bool IsUseable(void) override virtual bool IsUseable(void) const override
{ {
return true; return true;
} }
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 14; return 14;

View File

@ -21,14 +21,9 @@ class cBlockCarpetHandler:
public: public:
cBlockCarpetHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual bool GetPlacementBlockTypeMeta( virtual bool GetPlacementBlockTypeMeta(
cChunkInterface & a_ChunkInterface, cChunkInterface & a_ChunkInterface,
@ -37,7 +32,7 @@ public:
eBlockFace a_ClickedBlockFace, eBlockFace a_ClickedBlockFace,
const Vector3i a_CursorPos, const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override ) const override
{ {
a_BlockType = m_BlockType; a_BlockType = m_BlockType;
a_BlockMeta = a_Player.GetEquippedItem().m_ItemDamage & 0x0f; a_BlockMeta = a_Player.GetEquippedItem().m_ItemDamage & 0x0f;
@ -48,7 +43,7 @@ public:
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) const override
{ {
return (a_RelPos.y > 0) && (a_Chunk.GetBlock(a_RelPos.addedY(-1)) != E_BLOCK_AIR); return (a_RelPos.y > 0) && (a_Chunk.GetBlock(a_RelPos.addedY(-1)) != E_BLOCK_AIR);
} }
@ -57,7 +52,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
switch (a_Meta) switch (a_Meta)
{ {

View File

@ -15,16 +15,11 @@ class cBlockCauldronHandler :
public: public:
cBlockCauldronHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{ {
return cItem(E_ITEM_CAULDRON, 1, 0); return cItem(E_ITEM_CAULDRON, 1, 0);
} }
@ -40,7 +35,7 @@ public:
const Vector3i a_BlockPos, const Vector3i a_BlockPos,
eBlockFace a_BlockFace, eBlockFace a_BlockFace,
const Vector3i a_CursorPos const Vector3i a_CursorPos
) override ) const override
{ {
NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockPos); NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockPos);
auto EquippedItem = a_Player.GetEquippedItem(); auto EquippedItem = a_Player.GetEquippedItem();
@ -162,7 +157,7 @@ public:
virtual bool IsUseable() override virtual bool IsUseable() const override
{ {
return true; return true;
} }
@ -177,7 +172,7 @@ public:
cBlockPluginInterface & a_PluginInterface, cBlockPluginInterface & a_PluginInterface,
cChunk & a_Chunk, cChunk & a_Chunk,
const Vector3i a_RelPos const Vector3i a_RelPos
) override ) const override
{ {
auto WorldPos = a_Chunk.RelativeToAbsolute(a_RelPos); auto WorldPos = a_Chunk.RelativeToAbsolute(a_RelPos);
if (!a_WorldInterface.IsWeatherWetAtXYZ(WorldPos.addedY(1))) if (!a_WorldInterface.IsWeatherWetAtXYZ(WorldPos.addedY(1)))
@ -197,7 +192,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 21; return 21;

View File

@ -17,14 +17,36 @@ class cBlockChestHandler :
public: public:
cBlockChestHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
/** Translates player yaw when placing a chest into the chest block metadata. Valid for single chests only */
static NIBBLETYPE PlayerYawToMetaData(double a_Yaw)
{ {
a_Yaw += 90 + 45; // So its not aligned with axis
if (a_Yaw > 360.f)
{
a_Yaw -= 360.f;
}
if ((a_Yaw >= 0.f) && (a_Yaw < 90.f))
{
return 0x04;
}
else if ((a_Yaw >= 180) && (a_Yaw < 270))
{
return 0x05;
}
else if ((a_Yaw >= 90) && (a_Yaw < 180))
{
return 0x02;
}
else
{
return 0x03;
}
} }
private:
virtual bool GetPlacementBlockTypeMeta( virtual bool GetPlacementBlockTypeMeta(
cChunkInterface & a_ChunkInterface, cChunkInterface & a_ChunkInterface,
@ -33,7 +55,7 @@ public:
eBlockFace a_ClickedBlockFace, eBlockFace a_ClickedBlockFace,
const Vector3i a_CursorPos, const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override ) const override
{ {
// Cannot place right next to double-chest: // Cannot place right next to double-chest:
if (!CanBeAt(a_ChunkInterface, a_PlacedBlockPos)) if (!CanBeAt(a_ChunkInterface, a_PlacedBlockPos))
@ -82,7 +104,7 @@ public:
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) const override
{ {
auto BlockPos = a_Chunk.RelativeToAbsolute(a_RelPos); auto BlockPos = a_Chunk.RelativeToAbsolute(a_RelPos);
return CanBeAt(a_ChunkInterface, BlockPos); return CanBeAt(a_ChunkInterface, BlockPos);
@ -92,7 +114,7 @@ public:
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_BlockPos) bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_BlockPos) const
{ {
cBlockArea Area; cBlockArea Area;
if (!Area.Read(a_ChunkInterface, a_BlockPos - Vector3i(2, 0, 2), a_BlockPos + Vector3i(2, 0, 2))) if (!Area.Read(a_ChunkInterface, a_BlockPos - Vector3i(2, 0, 2), a_BlockPos + Vector3i(2, 0, 2)))
@ -161,39 +183,8 @@ public:
/** Translates player yaw when placing a chest into the chest block metadata. Valid for single chests only */
static NIBBLETYPE PlayerYawToMetaData(double a_Yaw)
{
a_Yaw += 90 + 45; // So its not aligned with axis
if (a_Yaw > 360.f)
{
a_Yaw -= 360.f;
}
if ((a_Yaw >= 0.f) && (a_Yaw < 90.f))
{
return 0x04;
}
else if ((a_Yaw >= 180) && (a_Yaw < 270))
{
return 0x05;
}
else if ((a_Yaw >= 90) && (a_Yaw < 180))
{
return 0x02;
}
else
{
return 0x03;
}
}
/** If there's a chest in the a_Area in the specified coords, modifies its meta to a_NewMeta and returns true. */ /** If there's a chest in the a_Area in the specified coords, modifies its meta to a_NewMeta and returns true. */
bool CheckAndAdjustNeighbor(cChunkInterface & a_ChunkInterface, const cBlockArea & a_Area, int a_RelX, int a_RelZ, NIBBLETYPE a_NewMeta) bool CheckAndAdjustNeighbor(cChunkInterface & a_ChunkInterface, const cBlockArea & a_Area, int a_RelX, int a_RelZ, NIBBLETYPE a_NewMeta) const
{ {
if (a_Area.GetRelBlockType(a_RelX, 0, a_RelZ) != m_BlockType) if (a_Area.GetRelBlockType(a_RelX, 0, a_RelZ) != m_BlockType)
{ {
@ -207,7 +198,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 13; return 13;

View File

@ -11,12 +11,12 @@ class cBlockClothHandler :
public cBlockHandler public cBlockHandler
{ {
public: public:
cBlockClothHandler(BLOCKTYPE a_BlockType)
: cBlockHandler(a_BlockType)
{
}
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override using cBlockHandler::cBlockHandler;
private:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
switch (a_Meta) switch (a_Meta)
{ {
@ -44,7 +44,3 @@ public:
} }
} }
} ; } ;

View File

@ -13,16 +13,12 @@ class cBlockCobWebHandler :
public cBlockHandler public cBlockHandler
{ {
public: public:
cBlockCobWebHandler(BLOCKTYPE a_BlockType)
: cBlockHandler(a_BlockType)
{
}
using cBlockHandler::cBlockHandler;
private:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{ {
// Silk touch gives cobweb, anything else gives just string: // Silk touch gives cobweb, anything else gives just string:
if (ToolHasSilkTouch(a_Tool)) if (ToolHasSilkTouch(a_Tool))
@ -39,7 +35,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 3; return 3;

View File

@ -13,16 +13,31 @@ class cBlockCocoaPodHandler :
using Super = cBlockHandler; using Super = cBlockHandler;
public: public:
cBlockCocoaPodHandler(BLOCKTYPE a_BlockType):
Super(a_BlockType) using Super::Super;
static NIBBLETYPE BlockFaceToMeta(eBlockFace a_BlockFace)
{ {
switch (a_BlockFace)
{
case BLOCK_FACE_ZM: return 0;
case BLOCK_FACE_XM: return 3;
case BLOCK_FACE_XP: return 1;
case BLOCK_FACE_ZP: return 2;
case BLOCK_FACE_NONE:
case BLOCK_FACE_YM:
case BLOCK_FACE_YP:
{
ASSERT(!"Unknown face");
return 0;
}
}
UNREACHABLE("Unsupported block face");
} }
private:
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) const override
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override
{ {
// Check that we're attached to a jungle log block: // Check that we're attached to a jungle log block:
eBlockFace BlockFace = MetaToBlockFace(a_Chunk.GetMeta(a_RelPos)); eBlockFace BlockFace = MetaToBlockFace(a_Chunk.GetMeta(a_RelPos));
@ -43,7 +58,7 @@ public:
cBlockPluginInterface & a_PluginInterface, cBlockPluginInterface & a_PluginInterface,
cChunk & a_Chunk, cChunk & a_Chunk,
const Vector3i a_RelPos const Vector3i a_RelPos
) override ) const override
{ {
if (GetRandomProvider().RandBool(0.20)) if (GetRandomProvider().RandBool(0.20))
{ {
@ -55,7 +70,7 @@ public:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
{ {
// If fully grown, give 3 items, otherwise just one: // If fully grown, give 3 items, otherwise just one:
auto growState = a_BlockMeta >> 2; auto growState = a_BlockMeta >> 2;
@ -66,7 +81,7 @@ public:
virtual int Grow(cChunk & a_Chunk, Vector3i a_RelPos, int a_NumStages = 1) override virtual int Grow(cChunk & a_Chunk, Vector3i a_RelPos, int a_NumStages = 1) const override
{ {
auto meta = a_Chunk.GetMeta(a_RelPos); auto meta = a_Chunk.GetMeta(a_RelPos);
auto typeMeta = meta & 0x03; auto typeMeta = meta & 0x03;
@ -105,30 +120,7 @@ public:
static NIBBLETYPE BlockFaceToMeta(eBlockFace a_BlockFace) virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{
switch (a_BlockFace)
{
case BLOCK_FACE_ZM: return 0;
case BLOCK_FACE_XM: return 3;
case BLOCK_FACE_XP: return 1;
case BLOCK_FACE_ZP: return 2;
case BLOCK_FACE_NONE:
case BLOCK_FACE_YM:
case BLOCK_FACE_YP:
{
ASSERT(!"Unknown face");
return 0;
}
}
UNREACHABLE("Unsupported block face");
}
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 34; return 34;

View File

@ -14,16 +14,11 @@ class cBlockCommandBlockHandler :
public: public:
cBlockCommandBlockHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{ {
// Don't allow as a pickup: // Don't allow as a pickup:
return {}; return {};
@ -33,7 +28,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 10; return 10;

View File

@ -16,113 +16,31 @@ class cBlockComparatorHandler :
public: public:
cBlockComparatorHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
virtual bool OnUse(
cChunkInterface & a_ChunkInterface,
cWorldInterface & a_WorldInterface,
cPlayer & a_Player,
const Vector3i a_BlockPos,
eBlockFace a_BlockFace,
const Vector3i a_CursorPos
) override
{
const auto Meta = a_ChunkInterface.GetBlockMeta(a_BlockPos);
// Toggle the 3rd bit (addition / subtraction):
a_ChunkInterface.SetBlockMeta(a_BlockPos, Meta ^ 0x04);
// Update simulators:
a_WorldInterface.WakeUpSimulators(a_BlockPos);
return true;
}
virtual void OnCancelRightClick(
cChunkInterface & a_ChunkInterface,
cWorldInterface & a_WorldInterface,
cPlayer & a_Player,
const Vector3i a_BlockPos,
eBlockFace a_BlockFace
) override
{
UNUSED(a_ChunkInterface);
UNUSED(a_BlockFace);
a_WorldInterface.WakeUpSimulators(a_BlockPos);
a_WorldInterface.SendBlockTo(a_BlockPos, a_Player);
}
virtual bool IsUseable(void) override
{
return true;
}
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override
{
if (a_RelPos.y <= 0)
{
return false;
}
BLOCKTYPE BelowBlock;
NIBBLETYPE BelowBlockMeta;
a_Chunk.GetBlockTypeMeta(a_RelPos.addedY(-1), BelowBlock, BelowBlockMeta);
if (cBlockInfo::FullyOccupiesVoxel(BelowBlock))
{
return true;
}
else if (cBlockSlabHandler::IsAnySlabType(BelowBlock))
{
// Check if the slab is turned up side down
if ((BelowBlockMeta & 0x08) == 0x08)
{
return true;
}
}
return false;
}
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{
return cItem(E_ITEM_COMPARATOR, 1, 0);
}
inline static bool IsInSubtractionMode(NIBBLETYPE a_Meta) inline static bool IsInSubtractionMode(NIBBLETYPE a_Meta)
{ {
return ((a_Meta & 0x4) == 0x4); return ((a_Meta & 0x4) == 0x4);
} }
inline static Vector3i GetFrontCoordinate(Vector3i a_Position, NIBBLETYPE a_Meta)
{
switch (a_Meta)
{
case 0x0: a_Position.z--; break;
case 0x1: a_Position.x++; break;
case 0x2: a_Position.z++; break;
case 0x3: a_Position.x--; break;
default:
{
LOGWARNING("%s: Unknown metadata: %d", __FUNCTION__, a_Meta);
ASSERT(!"Unknown metadata while determining orientation of comparator!");
break;
}
}
return a_Position;
}
inline static Vector3i GetSideCoordinate(Vector3i a_Position, NIBBLETYPE a_Meta, bool a_bInverse) inline static Vector3i GetSideCoordinate(Vector3i a_Position, NIBBLETYPE a_Meta, bool a_bInverse)
{ {
@ -162,10 +80,6 @@ public:
return a_Position; return a_Position;
} }
inline static Vector3i GetRearCoordinate(Vector3i a_Position, NIBBLETYPE a_Meta) inline static Vector3i GetRearCoordinate(Vector3i a_Position, NIBBLETYPE a_Meta)
{ {
switch (a_Meta) switch (a_Meta)
@ -185,34 +99,99 @@ public:
return a_Position; return a_Position;
} }
private:
virtual bool OnUse(
cChunkInterface & a_ChunkInterface,
cWorldInterface & a_WorldInterface,
inline static Vector3i GetFrontCoordinate(Vector3i a_Position, NIBBLETYPE a_Meta) cPlayer & a_Player,
const Vector3i a_BlockPos,
eBlockFace a_BlockFace,
const Vector3i a_CursorPos
) const override
{ {
switch (a_Meta) const auto Meta = a_ChunkInterface.GetBlockMeta(a_BlockPos);
{
case 0x0: a_Position.z--; break;
case 0x1: a_Position.x++; break;
case 0x2: a_Position.z++; break;
case 0x3: a_Position.x--; break;
default:
{
LOGWARNING("%s: Unknown metadata: %d", __FUNCTION__, a_Meta);
ASSERT(!"Unknown metadata while determining orientation of comparator!");
break;
}
}
return a_Position; // Toggle the 3rd bit (addition / subtraction):
a_ChunkInterface.SetBlockMeta(a_BlockPos, Meta ^ 0x04);
// Update simulators:
a_WorldInterface.WakeUpSimulators(a_BlockPos);
return true;
} }
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual void OnCancelRightClick(
cChunkInterface & a_ChunkInterface,
cWorldInterface & a_WorldInterface,
cPlayer & a_Player,
const Vector3i a_BlockPos,
eBlockFace a_BlockFace
) const override
{
UNUSED(a_ChunkInterface);
UNUSED(a_BlockFace);
a_WorldInterface.WakeUpSimulators(a_BlockPos);
a_WorldInterface.SendBlockTo(a_BlockPos, a_Player);
}
virtual bool IsUseable(void) const override
{
return true;
}
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) const override
{
if (a_RelPos.y <= 0)
{
return false;
}
BLOCKTYPE BelowBlock;
NIBBLETYPE BelowBlockMeta;
a_Chunk.GetBlockTypeMeta(a_RelPos.addedY(-1), BelowBlock, BelowBlockMeta);
if (cBlockInfo::FullyOccupiesVoxel(BelowBlock))
{
return true;
}
else if (cBlockSlabHandler::IsAnySlabType(BelowBlock))
{
// Check if the slab is turned up side down
if ((BelowBlockMeta & 0x08) == 0x08)
{
return true;
}
}
return false;
}
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
{
return cItem(E_ITEM_COMPARATOR, 1, 0);
}
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 11; return 11;

View File

@ -14,27 +14,26 @@ class cBlockConcretePowderHandler :
public: public:
cBlockConcretePowderHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{ private:
}
virtual void OnPlaced( virtual void OnPlaced(
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
Vector3i a_BlockPos, Vector3i a_BlockPos,
BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta
) override ) const override
{ {
OnNeighborChanged(a_ChunkInterface, a_BlockPos, BLOCK_FACE_NONE); OnNeighborChanged(a_ChunkInterface, a_BlockPos, BLOCK_FACE_NONE);
} }
virtual void OnNeighborChanged(cChunkInterface & a_ChunkInterface, Vector3i a_BlockPos, eBlockFace a_WhichNeighbor) override virtual void OnNeighborChanged(cChunkInterface & a_ChunkInterface, Vector3i a_BlockPos, eBlockFace a_WhichNeighbor) const override
{ {
a_ChunkInterface.DoWithChunkAt(a_BlockPos, [&](cChunk & a_Chunk) { CheckSoaked(a_Chunk.AbsoluteToRelative(a_BlockPos), a_Chunk); return true; }); a_ChunkInterface.DoWithChunkAt(a_BlockPos, [&](cChunk & a_Chunk) { CheckSoaked(a_Chunk.AbsoluteToRelative(a_BlockPos), a_Chunk); return true; });
} }
/** Check blocks above and around to see if they are water. If one is, converts this into concrete block. */ /** Check blocks above and around to see if they are water. If one is, converts this into concrete block. */
void CheckSoaked(Vector3i a_Rel, cChunk & a_Chunk) static void CheckSoaked(Vector3i a_Rel, cChunk & a_Chunk)
{ {
const auto & WaterCheck = cSimulator::AdjacentOffsets; const auto & WaterCheck = cSimulator::AdjacentOffsets;
const bool ShouldSoak = std::any_of(WaterCheck.cbegin(), WaterCheck.cend(), [a_Rel, & a_Chunk](Vector3i a_Offset) const bool ShouldSoak = std::any_of(WaterCheck.cbegin(), WaterCheck.cend(), [a_Rel, & a_Chunk](Vector3i a_Offset)
@ -54,7 +53,7 @@ public:
} }
} }
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
switch (a_Meta) switch (a_Meta)
{ {

View File

@ -17,16 +17,11 @@ class cBlockCropsHandler:
public: public:
cBlockCropsHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{ {
auto & rand = GetRandomProvider(); auto & rand = GetRandomProvider();
@ -90,7 +85,7 @@ public:
virtual int Grow(cChunk & a_Chunk, Vector3i a_RelPos, int a_NumStages = 1) override virtual int Grow(cChunk & a_Chunk, Vector3i a_RelPos, int a_NumStages = 1) const override
{ {
auto oldMeta = a_Chunk.GetMeta(a_RelPos); auto oldMeta = a_Chunk.GetMeta(a_RelPos);
if (oldMeta >= RipeMeta) if (oldMeta >= RipeMeta)
@ -108,7 +103,7 @@ public:
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) const override
{ {
return ((a_RelPos.y > 0) && (a_Chunk.GetBlock(a_RelPos.addedY(-1)) == E_BLOCK_FARMLAND)); return ((a_RelPos.y > 0) && (a_Chunk.GetBlock(a_RelPos.addedY(-1)) == E_BLOCK_FARMLAND));
} }
@ -117,7 +112,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 7; return 7;

View File

@ -13,16 +13,12 @@ class cBlockDeadBushHandler:
using Super = cBlockHandler; using Super = cBlockHandler;
public: public:
cBlockDeadBushHandler(BLOCKTYPE a_BlockType):
Super(a_BlockType)
{
}
using Super::Super;
private:
virtual bool DoesIgnoreBuildCollision(cChunkInterface & a_ChunkInterface, Vector3i a_Pos, cPlayer & a_Player, NIBBLETYPE a_Meta) const override
virtual bool DoesIgnoreBuildCollision(cChunkInterface & a_ChunkInterface, Vector3i a_Pos, cPlayer & a_Player, NIBBLETYPE a_Meta) override
{ {
return true; return true;
} }
@ -31,7 +27,7 @@ public:
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) const override
{ {
if (a_RelPos.y <= 0) if (a_RelPos.y <= 0)
{ {
@ -56,7 +52,7 @@ public:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
{ {
// If cutting down with shears, drop self: // If cutting down with shears, drop self:
if ((a_Tool != nullptr) && (a_Tool->m_ItemType == E_ITEM_SHEARS)) if ((a_Tool != nullptr) && (a_Tool->m_ItemType == E_ITEM_SHEARS))
@ -77,7 +73,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 0; return 0;

View File

@ -14,16 +14,11 @@ class cBlockDirtHandler :
public: public:
cBlockDirtHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{ {
if (a_BlockMeta == E_META_DIRT_COARSE) if (a_BlockMeta == E_META_DIRT_COARSE)
{ {
@ -40,7 +35,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 10; return 10;

View File

@ -7,16 +7,7 @@
cBlockDoorHandler::cBlockDoorHandler(BLOCKTYPE a_BlockType): void cBlockDoorHandler::OnBroken(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, Vector3i a_BlockPos, BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta) const
Super(a_BlockType)
{
}
void cBlockDoorHandler::OnBroken(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, Vector3i a_BlockPos, BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta)
{ {
// A part of the multiblock door was broken; the relevant half will drop any pickups as required. // A part of the multiblock door was broken; the relevant half will drop any pickups as required.
// All that is left to do is to delete the other half of the multiblock. // All that is left to do is to delete the other half of the multiblock.
@ -52,7 +43,7 @@ bool cBlockDoorHandler::OnUse(
const Vector3i a_BlockPos, const Vector3i a_BlockPos,
eBlockFace a_BlockFace, eBlockFace a_BlockFace,
const Vector3i a_CursorPos const Vector3i a_CursorPos
) ) const
{ {
UNUSED(a_WorldInterface); UNUSED(a_WorldInterface);
UNUSED(a_BlockFace); UNUSED(a_BlockFace);
@ -98,7 +89,7 @@ void cBlockDoorHandler::OnCancelRightClick(
cPlayer & a_Player, cPlayer & a_Player,
const Vector3i a_BlockPos, const Vector3i a_BlockPos,
eBlockFace a_BlockFace eBlockFace a_BlockFace
) ) const
{ {
UNUSED(a_ChunkInterface); UNUSED(a_ChunkInterface);
UNUSED(a_BlockFace); UNUSED(a_BlockFace);
@ -122,7 +113,7 @@ void cBlockDoorHandler::OnCancelRightClick(
cBoundingBox cBlockDoorHandler::GetPlacementCollisionBox(BLOCKTYPE a_XM, BLOCKTYPE a_XP, BLOCKTYPE a_YM, BLOCKTYPE a_YP, BLOCKTYPE a_ZM, BLOCKTYPE a_ZP) cBoundingBox cBlockDoorHandler::GetPlacementCollisionBox(BLOCKTYPE a_XM, BLOCKTYPE a_XP, BLOCKTYPE a_YM, BLOCKTYPE a_YP, BLOCKTYPE a_ZM, BLOCKTYPE a_ZP) const
{ {
// Doors can be placed inside the player // Doors can be placed inside the player
return cBoundingBox(0, 0, 0, 0, 0, 0); return cBoundingBox(0, 0, 0, 0, 0, 0);
@ -132,7 +123,7 @@ cBoundingBox cBlockDoorHandler::GetPlacementCollisionBox(BLOCKTYPE a_XM, BLOCKTY
NIBBLETYPE cBlockDoorHandler::MetaRotateCCW(NIBBLETYPE a_Meta) NIBBLETYPE cBlockDoorHandler::MetaRotateCCW(NIBBLETYPE a_Meta) const
{ {
if (a_Meta & 0x08) if (a_Meta & 0x08)
{ {
@ -150,7 +141,7 @@ NIBBLETYPE cBlockDoorHandler::MetaRotateCCW(NIBBLETYPE a_Meta)
NIBBLETYPE cBlockDoorHandler::MetaRotateCW(NIBBLETYPE a_Meta) NIBBLETYPE cBlockDoorHandler::MetaRotateCW(NIBBLETYPE a_Meta) const
{ {
if (a_Meta & 0x08) if (a_Meta & 0x08)
{ {
@ -168,7 +159,7 @@ NIBBLETYPE cBlockDoorHandler::MetaRotateCW(NIBBLETYPE a_Meta)
NIBBLETYPE cBlockDoorHandler::MetaMirrorXY(NIBBLETYPE a_Meta) NIBBLETYPE cBlockDoorHandler::MetaMirrorXY(NIBBLETYPE a_Meta) const
{ {
/* /*
Top bit (0x08) contains door block position (Top / Bottom). Only Bottom blocks contain position data Top bit (0x08) contains door block position (Top / Bottom). Only Bottom blocks contain position data
@ -202,7 +193,7 @@ NIBBLETYPE cBlockDoorHandler::MetaMirrorXY(NIBBLETYPE a_Meta)
NIBBLETYPE cBlockDoorHandler::MetaMirrorYZ(NIBBLETYPE a_Meta) NIBBLETYPE cBlockDoorHandler::MetaMirrorYZ(NIBBLETYPE a_Meta) const
{ {
// Top bit (0x08) contains door panel type (Top / Bottom panel) Only Bottom panels contain position data // 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) // Return a_Meta if panel is a top panel (0x08 bit is set to 1)

View File

@ -18,113 +18,7 @@ class cBlockDoorHandler :
public: public:
cBlockDoorHandler(BLOCKTYPE a_BlockType); using Super::Super;
virtual void OnBroken(
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
Vector3i a_BlockPos,
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta
) override;
virtual bool OnUse(
cChunkInterface & a_ChunkInterface,
cWorldInterface & a_WorldInterface,
cPlayer & a_Player,
const Vector3i a_BlockPos,
eBlockFace a_BlockFace,
const Vector3i a_CursorPos
) override;
virtual void OnCancelRightClick(
cChunkInterface & a_ChunkInterface,
cWorldInterface & a_WorldInterface,
cPlayer & a_Player,
const Vector3i a_BlockPos,
eBlockFace a_BlockFace
) 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,
const Vector3i a_PlacedBlockPos,
eBlockFace a_ClickedBlockFace,
const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{
// If clicking a bottom face, place the door one block lower:
auto PlacedPos = a_PlacedBlockPos;
if (a_ClickedBlockFace == BLOCK_FACE_BOTTOM)
{
PlacedPos.y--;
}
if (
!CanReplaceBlock(a_ChunkInterface.GetBlock(PlacedPos)) ||
!CanReplaceBlock(a_ChunkInterface.GetBlock(PlacedPos.addedY(1)))
)
{
return false;
}
return Super::GetPlacementBlockTypeMeta(a_ChunkInterface, a_Player, PlacedPos, a_ClickedBlockFace, a_CursorPos, a_BlockType, a_BlockMeta);
}
virtual cBoundingBox GetPlacementCollisionBox(BLOCKTYPE a_XM, BLOCKTYPE a_XP, BLOCKTYPE a_YM, BLOCKTYPE a_YP, BLOCKTYPE a_ZM, BLOCKTYPE a_ZP) override;
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{
switch (m_BlockType)
{
case E_BLOCK_OAK_DOOR: return cItem(E_ITEM_WOODEN_DOOR);
case E_BLOCK_ACACIA_DOOR: return cItem(E_ITEM_ACACIA_DOOR);
case E_BLOCK_BIRCH_DOOR: return cItem(E_ITEM_BIRCH_DOOR);
case E_BLOCK_DARK_OAK_DOOR: return cItem(E_ITEM_DARK_OAK_DOOR);
case E_BLOCK_JUNGLE_DOOR: return cItem(E_ITEM_JUNGLE_DOOR);
case E_BLOCK_SPRUCE_DOOR: return cItem(E_ITEM_SPRUCE_DOOR);
case E_BLOCK_IRON_DOOR: return cItem(E_ITEM_IRON_DOOR);
default:
{
ASSERT(!"Unhandled door type!");
return {};
}
}
}
virtual bool IsUseable(void) override
{
return true;
}
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override
{
return ((a_RelPos.y > 0) && CanBeOn(a_Chunk.GetBlock(a_RelPos.addedY(-1)), a_Chunk.GetMeta(a_RelPos.addedY(-1))));
}
/** Returns true if door can be placed on the specified block type. */ /** Returns true if door can be placed on the specified block type. */
static bool CanBeOn(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) static bool CanBeOn(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
@ -168,26 +62,18 @@ public:
return false; return false;
} }
/** Returns a vector pointing one block in the direction the door is facing (where the outside is). */ /** Returns a vector pointing one block in the direction the door is facing (where the outside is). */
inline static Vector3i GetRelativeDirectionToOutside(NIBBLETYPE a_BlockMeta) inline static Vector3i GetRelativeDirectionToOutside(NIBBLETYPE a_BlockMeta)
{ {
switch (a_BlockMeta & 0x03) switch (a_BlockMeta & 0x03)
{ {
case 0: return Vector3i(-1, 0, 0); // Facing West / XM case 0: return Vector3i(-1, 0, 0); // Facing West / XM
case 1: return Vector3i( 0, 0, -1); // Facing North / ZM case 1: return Vector3i(0, 0, -1); // Facing North / ZM
case 2: return Vector3i( 1, 0, 0); // Facing East / XP case 2: return Vector3i(1, 0, 0); // Facing East / XP
default: return Vector3i( 0, 0, 1); // Facing South / ZP default: return Vector3i(0, 0, 1); // Facing South / ZP
} }
} }
/** Returns true if the specified blocktype is any kind of door */ /** Returns true if the specified blocktype is any kind of door */
inline static bool IsDoorBlockType(BLOCKTYPE a_Block) inline static bool IsDoorBlockType(BLOCKTYPE a_Block)
{ {
@ -210,6 +96,143 @@ public:
} }
} }
/** Sets the door to the specified state. If the door is already in that state, does nothing. */
static void SetOpen(cChunkInterface & a_ChunkInterface, const Vector3i a_BlockPos, bool a_Open)
{
BLOCKTYPE Block = a_ChunkInterface.GetBlock(a_BlockPos);
if (!IsDoorBlockType(Block))
{
return;
}
NIBBLETYPE Meta = GetCompleteDoorMeta(a_ChunkInterface, a_BlockPos);
bool IsOpened = ((Meta & 0x04) != 0);
if (IsOpened == a_Open)
{
return;
}
// Change the door
NIBBLETYPE NewMeta = (Meta & 0x07) ^ 0x04; // Flip the "IsOpen" bit (0x04)
if ((Meta & 0x08) == 0)
{
// The block is the bottom part of the door
a_ChunkInterface.SetBlockMeta(a_BlockPos, NewMeta);
}
else
{
// The block is the top part of the door, set the meta to the corresponding top part
if (a_BlockPos.y > 0)
{
a_ChunkInterface.SetBlockMeta(a_BlockPos.addedY(-1), NewMeta);
}
}
}
private:
virtual void OnBroken(
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
Vector3i a_BlockPos,
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta
) const override;
virtual bool OnUse(
cChunkInterface & a_ChunkInterface,
cWorldInterface & a_WorldInterface,
cPlayer & a_Player,
const Vector3i a_BlockPos,
eBlockFace a_BlockFace,
const Vector3i a_CursorPos
) const override;
virtual void OnCancelRightClick(
cChunkInterface & a_ChunkInterface,
cWorldInterface & a_WorldInterface,
cPlayer & a_Player,
const Vector3i a_BlockPos,
eBlockFace a_BlockFace
) const override;
virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) const override;
virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) const override;
virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) const override;
virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) const override;
virtual bool GetPlacementBlockTypeMeta(
cChunkInterface & a_ChunkInterface,
cPlayer & a_Player,
const Vector3i a_PlacedBlockPos,
eBlockFace a_ClickedBlockFace,
const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) const override
{
// If clicking a bottom face, place the door one block lower:
auto PlacedPos = a_PlacedBlockPos;
if (a_ClickedBlockFace == BLOCK_FACE_BOTTOM)
{
PlacedPos.y--;
}
if (
!CanReplaceBlock(a_ChunkInterface.GetBlock(PlacedPos)) ||
!CanReplaceBlock(a_ChunkInterface.GetBlock(PlacedPos.addedY(1)))
)
{
return false;
}
return Super::GetPlacementBlockTypeMeta(a_ChunkInterface, a_Player, PlacedPos, a_ClickedBlockFace, a_CursorPos, a_BlockType, a_BlockMeta);
}
virtual cBoundingBox GetPlacementCollisionBox(BLOCKTYPE a_XM, BLOCKTYPE a_XP, BLOCKTYPE a_YM, BLOCKTYPE a_YP, BLOCKTYPE a_ZM, BLOCKTYPE a_ZP) const override;
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
{
switch (m_BlockType)
{
case E_BLOCK_OAK_DOOR: return cItem(E_ITEM_WOODEN_DOOR);
case E_BLOCK_ACACIA_DOOR: return cItem(E_ITEM_ACACIA_DOOR);
case E_BLOCK_BIRCH_DOOR: return cItem(E_ITEM_BIRCH_DOOR);
case E_BLOCK_DARK_OAK_DOOR: return cItem(E_ITEM_DARK_OAK_DOOR);
case E_BLOCK_JUNGLE_DOOR: return cItem(E_ITEM_JUNGLE_DOOR);
case E_BLOCK_SPRUCE_DOOR: return cItem(E_ITEM_SPRUCE_DOOR);
case E_BLOCK_IRON_DOOR: return cItem(E_ITEM_IRON_DOOR);
default:
{
ASSERT(!"Unhandled door type!");
return {};
}
}
}
virtual bool IsUseable(void) const override
{
return true;
}
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) const override
{
return ((a_RelPos.y > 0) && CanBeOn(a_Chunk.GetBlock(a_RelPos.addedY(-1)), a_Chunk.GetMeta(a_RelPos.addedY(-1))));
}
@ -262,43 +285,6 @@ public:
/** Sets the door to the specified state. If the door is already in that state, does nothing. */
static void SetOpen(cChunkInterface & a_ChunkInterface, const Vector3i a_BlockPos, bool a_Open)
{
BLOCKTYPE Block = a_ChunkInterface.GetBlock(a_BlockPos);
if (!IsDoorBlockType(Block))
{
return;
}
NIBBLETYPE Meta = GetCompleteDoorMeta(a_ChunkInterface, a_BlockPos);
bool IsOpened = ((Meta & 0x04) != 0);
if (IsOpened == a_Open)
{
return;
}
// Change the door
NIBBLETYPE NewMeta = (Meta & 0x07) ^ 0x04; // Flip the "IsOpen" bit (0x04)
if ((Meta & 0x08) == 0)
{
// The block is the bottom part of the door
a_ChunkInterface.SetBlockMeta(a_BlockPos, NewMeta);
}
else
{
// The block is the top part of the door, set the meta to the corresponding top part
if (a_BlockPos.y > 0)
{
a_ChunkInterface.SetBlockMeta(a_BlockPos.addedY(-1), NewMeta);
}
}
}
/** Changes the door at the specified coords from open to close or vice versa */ /** Changes the door at the specified coords from open to close or vice versa */
static void ChangeDoor(cChunkInterface & a_ChunkInterface, const Vector3i a_BlockPos) static void ChangeDoor(cChunkInterface & a_ChunkInterface, const Vector3i a_BlockPos)
{ {
@ -309,7 +295,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
switch (m_BlockType) switch (m_BlockType)

View File

@ -20,16 +20,11 @@ class cBlockDropSpenserHandler :
public: public:
cBlockDropSpenserHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{ {
cItems res(cItem(m_BlockType, 1)); cItems res(cItem(m_BlockType, 1));
if (a_BlockEntity != nullptr) if (a_BlockEntity != nullptr)
@ -44,7 +39,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 11; return 11;

View File

@ -29,7 +29,7 @@ private:
const Vector3i a_BlockPos, const Vector3i a_BlockPos,
eBlockFace a_BlockFace, eBlockFace a_BlockFace,
const Vector3i a_CursorPos const Vector3i a_CursorPos
) override ) const override
{ {
AString WindowName = "Enchant"; AString WindowName = "Enchant";
a_WorldInterface.DoWithBlockEntityAt(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, [&WindowName](cBlockEntity & a_Entity) a_WorldInterface.DoWithBlockEntityAt(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, [&WindowName](cBlockEntity & a_Entity)
@ -56,13 +56,13 @@ private:
} }
virtual bool IsUseable(void) override virtual bool IsUseable(void) const override
{ {
return true; return true;
} }
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
{ {
if ((a_BlockEntity == nullptr) || (a_BlockEntity->GetBlockType() != E_BLOCK_ENCHANTMENT_TABLE)) if ((a_BlockEntity == nullptr) || (a_BlockEntity->GetBlockType() != E_BLOCK_ENCHANTMENT_TABLE))
{ {
@ -76,7 +76,7 @@ private:
} }
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 29; return 29;

View File

@ -25,14 +25,9 @@ class cBlockEndPortalFrameHandler:
public: public:
cBlockEndPortalFrameHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual bool GetPlacementBlockTypeMeta( virtual bool GetPlacementBlockTypeMeta(
cChunkInterface & a_ChunkInterface, cChunkInterface & a_ChunkInterface,
@ -41,7 +36,7 @@ public:
eBlockFace a_ClickedBlockFace, eBlockFace a_ClickedBlockFace,
const Vector3i a_CursorPos, const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override ) const override
{ {
a_BlockType = m_BlockType; a_BlockType = m_BlockType;
a_BlockMeta = YawToMetaData(a_Player.GetYaw()); a_BlockMeta = YawToMetaData(a_Player.GetYaw());
@ -82,7 +77,167 @@ public:
virtual bool IsClickedThrough(void) override virtual void OnPlaced(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) const override
{
// E_META_END_PORTAL_FRAME_EYE is the bit which signifies the eye of ender is in it.
// LOG("PortalPlaced, meta %d", a_BlockMeta);
if ((a_BlockMeta & E_META_END_PORTAL_FRAME_EYE) == E_META_END_PORTAL_FRAME_EYE)
{
// LOG("Location is %d %d %d", a_BlockX, a_BlockY, a_BlockZ);
// Direction is the first two bits, masked by 0x3
FindAndSetPortal(a_BlockPos, a_BlockMeta & 3, a_ChunkInterface, a_WorldInterface);
}
}
/** Returns false if portal cannot be made, true if portal was made. */
static bool FindAndSetPortal(Vector3i a_FirstFrame, NIBBLETYPE a_Direction, cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface)
{
/*
PORTAL FINDING ALGORITH
=======================
- Get clicked base block
- Check diagonally (clockwise) for another portal block
- if exists, and has eye, Continue. Abort if any are facing the wrong direction.
- if doesn't exist, check horizontally (the block to the left of this block). Abort if there is no horizontal block.
- After a corner has been met, traverse the portal clockwise, ensuring valid portal frames connect the rectangle.
- Track the NorthWest Corner, and the dimensions.
- If dimensions are valid, create the portal.
*/
static_assert((E_META_END_PORTAL_FRAME_ZM - E_META_END_PORTAL_FRAME_XM) == 1, "Should be going clockwise");
const int MIN_PORTAL_WIDTH = 3;
const int MAX_PORTAL_WIDTH = 4;
// Directions to use for the clockwise traversal.
static const Vector3i Left[] =
{
{ 1, 0, 0}, // 0, South, left block is East / XP
{ 0, 0, 1}, // 1, West, left block is South / ZP
{-1, 0, 0}, // 2, North, left block is West / XM
{ 0, 0, -1}, // 3, East, left block is North / ZM
};
static const Vector3i LeftForward[] =
{
{ 1, 0, 1}, // 0, South, left block is SouthEast / XP ZP
{-1, 0, 1}, // 1, West, left block is SouthWest / XM ZP
{-1, 0, -1}, // 2, North, left block is NorthWest / XM ZM
{ 1, 0, -1}, // 3, East, left block is NorthEast / XP ZM
};
int EdgesComplete = -1; // We start search _before_ finding the first edge
Vector3i NorthWestCorner;
int EdgeWidth[4] = { 1, 1, 1, 1 };
NIBBLETYPE CurrentDirection = a_Direction;
Vector3i CurrentPos = a_FirstFrame;
// Scan clockwise until we have seen all 4 edges
while (EdgesComplete < 4)
{
// Check if we are at a corner
Vector3i NextPos = CurrentPos + LeftForward[CurrentDirection];
if (IsPortalFrame(a_ChunkInterface.GetBlock(NextPos)))
{
// We have found the corner, move clockwise to next edge
if (CurrentDirection == E_META_END_PORTAL_FRAME_XP)
{
// We are on the NW (XM, ZM) Corner
// Relative to the previous frame, the portal should appear to the right of this portal frame.
NorthWestCorner = NextPos - Left[CurrentDirection];
}
if (EdgesComplete == -1)
{
// Reset current width, we will revisit it last
EdgeWidth[CurrentDirection] = 1;
}
// Rotate 90 degrees clockwise
CurrentDirection = (CurrentDirection + 1) % 4;
EdgesComplete++;
}
else
{
// We are not at a corner, keep walking the edge
NextPos = CurrentPos + Left[CurrentDirection];
EdgeWidth[CurrentDirection]++;
if (EdgeWidth[CurrentDirection] > MAX_PORTAL_WIDTH)
{
// Don't build a portal that is too long.
return false;
}
}
if (!IsValidFrameAtPos(a_ChunkInterface, NextPos, CurrentDirection))
{
// Neither the edge nor the corner are valid portal blocks.
return false;
}
CurrentPos = NextPos;
}
if ((EdgeWidth[0] != EdgeWidth[2]) || (EdgeWidth[1] != EdgeWidth[3]))
{
// Mismatched Portal Dimensions.
return false;
}
if ((EdgeWidth[0] < MIN_PORTAL_WIDTH) || (EdgeWidth[1] < MIN_PORTAL_WIDTH))
{
// Portal too small.
return false;
}
// LOG("NW corner (low corner) %d %d %d", Corner.x, Corner.y, Corner.z);
// LOG("%d by %d", Width[0], Width[1]);
for (int i = 0; i < EdgeWidth[0]; i++)
{
for (int j = 0; j < EdgeWidth[1]; j++)
{
a_ChunkInterface.SetBlock(NorthWestCorner.x + i, NorthWestCorner.y, NorthWestCorner.z + j, E_BLOCK_END_PORTAL, 0);
// TODO: Create block entity so portal doesn't become invisible on relog.
}
}
return true;
}
/** Return true if this block is a portal frame, has an eye, and is facing the correct direction. */
static bool IsValidFrameAtPos(cChunkInterface & a_ChunkInterface, Vector3i a_BlockPos, NIBBLETYPE a_ShouldFace)
{
BLOCKTYPE BlockType;
NIBBLETYPE BlockMeta;
return (
a_ChunkInterface.GetBlockTypeMeta(a_BlockPos, BlockType, BlockMeta) &&
(BlockType == E_BLOCK_END_PORTAL_FRAME) &&
(BlockMeta == (a_ShouldFace | E_META_END_PORTAL_FRAME_EYE))
);
}
/** Return true if this block is a portal frame. */
static bool IsPortalFrame(BLOCKTYPE BlockType)
{
return (BlockType == E_BLOCK_END_PORTAL_FRAME);
}
virtual bool IsClickedThrough(void) const override
{ {
// TODO: Colision // TODO: Colision
return true; return true;
@ -92,7 +247,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 27; return 27;

View File

@ -14,16 +14,11 @@ class cBlockEnderchestHandler :
public: public:
cBlockEnderchestHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{ {
// Only drop something when mined with a pickaxe: // Only drop something when mined with a pickaxe:
if ( if (

View File

@ -19,14 +19,9 @@ class cBlockEntityHandler:
public: public:
cBlockEntityHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual bool OnUse( virtual bool OnUse(
cChunkInterface & a_ChunkInterface, cChunkInterface & a_ChunkInterface,
@ -35,7 +30,7 @@ public:
const Vector3i a_BlockPos, const Vector3i a_BlockPos,
eBlockFace a_BlockFace, eBlockFace a_BlockFace,
const Vector3i a_CursorPos const Vector3i a_CursorPos
) override ) const override
{ {
return a_ChunkInterface.UseBlockEntity(&a_Player, a_BlockPos.x, a_BlockPos.y, a_BlockPos.z); return a_ChunkInterface.UseBlockEntity(&a_Player, a_BlockPos.x, a_BlockPos.y, a_BlockPos.z);
} }
@ -44,7 +39,7 @@ public:
virtual bool IsUseable() override virtual bool IsUseable() const override
{ {
return true; return true;
} }
@ -62,16 +57,14 @@ class cContainerEntityHandler:
{ {
public: public:
cContainerEntityHandler(BLOCKTYPE a_BlockType): constexpr cContainerEntityHandler(BLOCKTYPE a_BlockType):
Base(a_BlockType) Base(a_BlockType)
{ {
} }
private:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{ {
// Reset meta to 0 // Reset meta to 0
cItems res(cItem(Base::m_BlockType, 1, 0)); cItems res(cItem(Base::m_BlockType, 1, 0));

View File

@ -23,16 +23,11 @@ class cBlockFarmlandHandler :
public: public:
cBlockFarmlandHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{ {
return cItem(E_BLOCK_DIRT, 1, 0); return cItem(E_BLOCK_DIRT, 1, 0);
} }
@ -47,7 +42,7 @@ public:
cBlockPluginInterface & a_PluginInterface, cBlockPluginInterface & a_PluginInterface,
cChunk & a_Chunk, cChunk & a_Chunk,
const Vector3i a_RelPos const Vector3i a_RelPos
) override ) const override
{ {
auto BlockMeta = a_Chunk.GetMeta(a_RelPos); auto BlockMeta = a_Chunk.GetMeta(a_RelPos);
@ -91,7 +86,7 @@ public:
virtual void OnNeighborChanged(cChunkInterface & a_ChunkInterface, Vector3i a_BlockPos, eBlockFace a_WhichNeighbor) override virtual void OnNeighborChanged(cChunkInterface & a_ChunkInterface, Vector3i a_BlockPos, eBlockFace a_WhichNeighbor) const override
{ {
// Don't care about any neighbor but the one above us (fix recursion loop in #2213): // Don't care about any neighbor but the one above us (fix recursion loop in #2213):
if (a_WhichNeighbor != BLOCK_FACE_YP) if (a_WhichNeighbor != BLOCK_FACE_YP)
@ -118,7 +113,7 @@ public:
/** Returns true if there's either a water source block close enough to hydrate the specified position, or it's raining there. */ /** Returns true if there's either a water source block close enough to hydrate the specified position, or it's raining there. */
bool IsWaterInNear(cChunk & a_Chunk, const Vector3i a_RelPos) static bool IsWaterInNear(const cChunk & a_Chunk, const Vector3i a_RelPos)
{ {
const auto WorldPos = a_Chunk.RelativeToAbsolute(a_RelPos); const auto WorldPos = a_Chunk.RelativeToAbsolute(a_RelPos);
if (a_Chunk.GetWorld()->IsWeatherWetAtXYZ(WorldPos)) if (a_Chunk.GetWorld()->IsWeatherWetAtXYZ(WorldPos))
@ -154,7 +149,7 @@ public:
virtual bool CanSustainPlant(BLOCKTYPE a_Plant) override virtual bool CanSustainPlant(BLOCKTYPE a_Plant) const override
{ {
return ( return (
(a_Plant == E_BLOCK_BEETROOTS) || (a_Plant == E_BLOCK_BEETROOTS) ||

View File

@ -17,22 +17,17 @@ class cBlockFenceHandler:
public: public:
using Super::Super;
private:
// These are the min and max coordinates (X and Z) for a straight fence. // 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 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) // (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; static constexpr double MIN_COORD = 0.4;
const double MAX_COORD = 0.6; static constexpr double MAX_COORD = 0.6;
cBlockFenceHandler(BLOCKTYPE a_BlockType): virtual cBoundingBox GetPlacementCollisionBox(BLOCKTYPE a_XM, BLOCKTYPE a_XP, BLOCKTYPE a_YM, BLOCKTYPE a_YP, BLOCKTYPE a_ZM, BLOCKTYPE a_ZP) const override
Super(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 XMSolid = cBlockInfo::IsSolid(a_XM);
bool XPSolid = cBlockInfo::IsSolid(a_XP); bool XPSolid = cBlockInfo::IsSolid(a_XP);
@ -94,7 +89,7 @@ public:
const Vector3i a_BlockPos, const Vector3i a_BlockPos,
eBlockFace a_BlockFace, eBlockFace a_BlockFace,
const Vector3i a_CursorPos const Vector3i a_CursorPos
) override ) const override
{ {
auto LeashKnot = cLeashKnot::FindKnotAtPos(*a_Player.GetWorld(), a_BlockPos); auto LeashKnot = cLeashKnot::FindKnotAtPos(*a_Player.GetWorld(), a_BlockPos);
auto KnotAlreadyExists = (LeashKnot != nullptr); auto KnotAlreadyExists = (LeashKnot != nullptr);
@ -140,7 +135,7 @@ public:
cPlayer & a_Player, cPlayer & a_Player,
const Vector3i a_BlockPos, const Vector3i a_BlockPos,
eBlockFace a_BlockFace eBlockFace a_BlockFace
) override ) const override
{ {
a_WorldInterface.SendBlockTo(a_BlockPos, a_Player); a_WorldInterface.SendBlockTo(a_BlockPos, a_Player);
} }
@ -149,7 +144,7 @@ public:
virtual bool IsUseable(void) override virtual bool IsUseable(void) const override
{ {
return true; return true;
} }
@ -162,7 +157,7 @@ public:
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
Vector3i a_BlockPos, Vector3i a_BlockPos,
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta
) override ) const override
{ {
// Destroy any leash knot tied to the fence: // Destroy any leash knot tied to the fence:
auto leashKnot = cLeashKnot::FindKnotAtPos(a_WorldInterface, a_BlockPos); auto leashKnot = cLeashKnot::FindKnotAtPos(a_WorldInterface, a_BlockPos);

View File

@ -15,14 +15,9 @@ class cBlockFenceGateHandler :
public: public:
cBlockFenceGateHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual bool OnUse( virtual bool OnUse(
cChunkInterface & a_ChunkInterface, cChunkInterface & a_ChunkInterface,
@ -31,7 +26,7 @@ public:
const Vector3i a_BlockPos, const Vector3i a_BlockPos,
eBlockFace a_BlockFace, eBlockFace a_BlockFace,
const Vector3i a_CursorPos const Vector3i a_CursorPos
) override ) const override
{ {
NIBBLETYPE OldMetaData = a_ChunkInterface.GetBlockMeta(a_BlockPos); NIBBLETYPE OldMetaData = a_ChunkInterface.GetBlockMeta(a_BlockPos);
NIBBLETYPE NewMetaData = YawToMetaData(a_Player.GetYaw()); NIBBLETYPE NewMetaData = YawToMetaData(a_Player.GetYaw());
@ -61,7 +56,7 @@ public:
cPlayer & a_Player, cPlayer & a_Player,
const Vector3i a_BlockPos, const Vector3i a_BlockPos,
eBlockFace a_BlockFace eBlockFace a_BlockFace
) override ) const override
{ {
a_WorldInterface.SendBlockTo(a_BlockPos, a_Player); a_WorldInterface.SendBlockTo(a_BlockPos, a_Player);
} }
@ -70,7 +65,7 @@ public:
virtual bool IsUseable(void) override virtual bool IsUseable(void) const override
{ {
return true; return true;
} }
@ -79,7 +74,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
switch (m_BlockType) switch (m_BlockType)

View File

@ -11,23 +11,23 @@ class cBlockFireHandler :
public cBlockHandler public cBlockHandler
{ {
public: public:
cBlockFireHandler(BLOCKTYPE a_BlockType)
: cBlockHandler(a_BlockType), using cBlockHandler::cBlockHandler;
XZP(0), XZM(0), Dir(0)
private:
struct Scratch
{ {
} /** Portal boundary and direction variables */
int XZP = 0, XZM = 0;
/** Portal boundary and direction variables */ NIBBLETYPE Dir = 0;
// TODO: These need to be removed, BlockHandler instances are shared for all blocks in all worlds on the server };
// and are not supposed to have any data in them.
int XZP, XZM;
NIBBLETYPE Dir;
virtual void OnPlaced(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override virtual void OnPlaced(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) const override
{ {
/* /*
PORTAL FINDING ALGORITH PORTAL FINDING ALGORITH
@ -42,15 +42,17 @@ public:
- Loop through boundary variables, and fill with portal blocks based on Dir with meta from Dir - Loop through boundary variables, and fill with portal blocks based on Dir with meta from Dir
*/ */
Scratch Scratch;
// a_BlockY - 1: Because we want the block below the fire // a_BlockY - 1: Because we want the block below the fire
FindAndSetPortalFrame(a_BlockPos.x, a_BlockPos.y - 1, a_BlockPos.z, a_ChunkInterface, a_WorldInterface); FindAndSetPortalFrame(a_BlockPos.x, a_BlockPos.y - 1, a_BlockPos.z, a_ChunkInterface, a_WorldInterface, Scratch);
} }
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
{ {
// No pickups from this block // No pickups from this block
return {}; return {};
@ -60,14 +62,14 @@ public:
virtual bool IsClickedThrough(void) override virtual bool IsClickedThrough(void) const override
{ {
return true; return true;
} }
/** Traces along YP until it finds an obsidian block, returns Y difference or 0 if no portal, and -1 for border /** Traces along YP until it finds an obsidian block, returns Y difference or 0 if no portal, and -1 for border
Takes the X, Y, and Z of the base block; with an optional MaxY for portal border finding */ Takes the X, Y, and Z of the base block; with an optional MaxY for portal border finding */
int FindObsidianCeiling(int X, int Y, int Z, cChunkInterface & a_ChunkInterface, int MaxY = 0) static int FindObsidianCeiling(int X, int Y, int Z, cChunkInterface & a_ChunkInterface, int MaxY = 0)
{ {
if (a_ChunkInterface.GetBlock({X, Y, Z}) != E_BLOCK_OBSIDIAN) if (a_ChunkInterface.GetBlock({X, Y, Z}) != E_BLOCK_OBSIDIAN)
{ {
@ -102,7 +104,7 @@ public:
} }
/** Evaluates if coords have a valid border on top, based on MaxY */ /** Evaluates if coords have a valid border on top, based on MaxY */
bool EvaluatePortalBorder(int X, int FoundObsidianY, int Z, int MaxY, cChunkInterface & a_ChunkInterface) static bool EvaluatePortalBorder(int X, int FoundObsidianY, int Z, int MaxY, cChunkInterface & a_ChunkInterface)
{ {
for (int checkBorder = FoundObsidianY + 1; checkBorder <= MaxY - 1; checkBorder++) // FoundObsidianY + 1: FoundObsidianY has already been checked in FindObsidianCeiling; MaxY - 1: portal doesn't need corners for (int checkBorder = FoundObsidianY + 1; checkBorder <= MaxY - 1; checkBorder++) // FoundObsidianY + 1: FoundObsidianY has already been checked in FindObsidianCeiling; MaxY - 1: portal doesn't need corners
{ {
@ -121,7 +123,7 @@ public:
/** Finds entire frame in any direction with the coordinates of a base block and fills hole with nether portal (START HERE) */ /** Finds entire frame in any direction with the coordinates of a base block and fills hole with nether portal (START HERE) */
void FindAndSetPortalFrame(int X, int Y, int Z, cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface) static void FindAndSetPortalFrame(int X, int Y, int Z, cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, Scratch & a_Scratch)
{ {
int MaxY = FindObsidianCeiling(X, Y, Z, a_ChunkInterface); // Get topmost obsidian block as reference for all other checks int MaxY = FindObsidianCeiling(X, Y, Z, a_ChunkInterface); // Get topmost obsidian block as reference for all other checks
int X1 = X + 1, Z1 = Z + 1, X2 = X - 1, Z2 = Z - 1; // Duplicate XZ values, add / subtract one as we've checked the original already the line above int X1 = X + 1, Z1 = Z + 1, X2 = X - 1, Z2 = Z - 1; // Duplicate XZ values, add / subtract one as we've checked the original already the line above
@ -131,16 +133,16 @@ public:
return; return;
} }
if (!FindPortalSliceX(X1, X2, Y, Z, MaxY, a_ChunkInterface)) if (!FindPortalSliceX(X1, X2, Y, Z, MaxY, a_ChunkInterface, a_Scratch))
{ {
if (!FindPortalSliceZ(X, Y, Z1, Z2, MaxY, a_ChunkInterface)) if (!FindPortalSliceZ(X, Y, Z1, Z2, MaxY, a_ChunkInterface, a_Scratch))
{ {
return; // No eligible portal construct, abort abort abort!! return; // No eligible portal construct, abort abort abort!!
} }
} }
int PortalHeight = MaxY - Y - 1; int PortalHeight = MaxY - Y - 1;
int PortalWidth = XZP - XZM + 1; int PortalWidth = a_Scratch.XZP - a_Scratch.XZM + 1;
if ((PortalHeight < a_WorldInterface.GetMinNetherPortalHeight()) || (PortalHeight > a_WorldInterface.GetMaxNetherPortalHeight())) if ((PortalHeight < a_WorldInterface.GetMinNetherPortalHeight()) || (PortalHeight > a_WorldInterface.GetMaxNetherPortalHeight()))
{ {
// The portal isn't high enough, or is too high // The portal isn't high enough, or is too high
@ -155,15 +157,15 @@ public:
for (int Height = Y + 1; Height <= MaxY - 1; Height++) // Loop through boundary to set portal blocks for (int Height = Y + 1; Height <= MaxY - 1; Height++) // Loop through boundary to set portal blocks
{ {
for (int Width = XZM; Width <= XZP; Width++) for (int Width = a_Scratch.XZM; Width <= a_Scratch.XZP; Width++)
{ {
if (Dir == 1) if (a_Scratch.Dir == 1)
{ {
a_ChunkInterface.SetBlock(Width, Height, Z, E_BLOCK_NETHER_PORTAL, Dir); a_ChunkInterface.SetBlock(Width, Height, Z, E_BLOCK_NETHER_PORTAL, a_Scratch.Dir);
} }
else else
{ {
a_ChunkInterface.SetBlock(X, Height, Width, E_BLOCK_NETHER_PORTAL, Dir); a_ChunkInterface.SetBlock(X, Height, Width, E_BLOCK_NETHER_PORTAL, a_Scratch.Dir);
} }
} }
} }
@ -171,9 +173,9 @@ public:
/** Evaluates if coordinates are a portal going XP / XM; returns true if so, and writes boundaries to variable /** Evaluates if coordinates are a portal going XP / XM; returns true if so, and writes boundaries to variable
Takes coordinates of base block and Y coord of target obsidian ceiling */ Takes coordinates of base block and Y coord of target obsidian ceiling */
bool FindPortalSliceX(int X1, int X2, int Y, int Z, int MaxY, cChunkInterface & a_ChunkInterface) static bool FindPortalSliceX(int X1, int X2, int Y, int Z, int MaxY, cChunkInterface & a_ChunkInterface, Scratch & a_Scratch)
{ {
Dir = 1; // Set assumed direction (will change if portal turns out to be facing the other direction) a_Scratch.Dir = 1; // Set assumed direction (will change if portal turns out to be facing the other direction)
bool FoundFrameXP = false, FoundFrameXM = false; bool FoundFrameXP = false, FoundFrameXM = false;
for (; ((a_ChunkInterface.GetBlock({X1, Y, Z}) == E_BLOCK_OBSIDIAN) || (a_ChunkInterface.GetBlock({X1, Y + 1, Z}) == E_BLOCK_OBSIDIAN)); X1++) // Check XP for obsidian blocks, exempting corners for (; ((a_ChunkInterface.GetBlock({X1, Y, Z}) == E_BLOCK_OBSIDIAN) || (a_ChunkInterface.GetBlock({X1, Y + 1, Z}) == E_BLOCK_OBSIDIAN)); X1++) // Check XP for obsidian blocks, exempting corners
{ {
@ -189,7 +191,7 @@ public:
return false; // Not valid slice, no portal can be formed return false; // Not valid slice, no portal can be formed
} }
} }
XZP = X1 - 1; // Set boundary of frame interior a_Scratch.XZP = X1 - 1; // Set boundary of frame interior
for (; ((a_ChunkInterface.GetBlock({X2, Y, Z}) == E_BLOCK_OBSIDIAN) || (a_ChunkInterface.GetBlock({X2, Y + 1, Z}) == E_BLOCK_OBSIDIAN)); X2--) // Go the other direction (XM) for (; ((a_ChunkInterface.GetBlock({X2, Y, Z}) == E_BLOCK_OBSIDIAN) || (a_ChunkInterface.GetBlock({X2, Y + 1, Z}) == E_BLOCK_OBSIDIAN)); X2--) // Go the other direction (XM)
{ {
int Value = FindObsidianCeiling(X2, Y, Z, a_ChunkInterface, MaxY); int Value = FindObsidianCeiling(X2, Y, Z, a_ChunkInterface, MaxY);
@ -204,15 +206,15 @@ public:
return false; return false;
} }
} }
XZM = X2 + 1; // Set boundary, see previous a_Scratch.XZM = X2 + 1; // Set boundary, see previous
return (FoundFrameXP && FoundFrameXM); return (FoundFrameXP && FoundFrameXM);
} }
/** Evaluates if coords are a portal going ZP / ZM; returns true if so, and writes boundaries to variable */ /** Evaluates if coords are a portal going ZP / ZM; returns true if so, and writes boundaries to variable */
bool FindPortalSliceZ(int X, int Y, int Z1, int Z2, int MaxY, cChunkInterface & a_ChunkInterface) static bool FindPortalSliceZ(int X, int Y, int Z1, int Z2, int MaxY, cChunkInterface & a_ChunkInterface, Scratch & a_Scratch)
{ {
Dir = 2; a_Scratch.Dir = 2;
bool FoundFrameZP = false, FoundFrameZM = false; bool FoundFrameZP = false, FoundFrameZM = false;
for (; ((a_ChunkInterface.GetBlock({X, Y, Z1}) == E_BLOCK_OBSIDIAN) || (a_ChunkInterface.GetBlock({X, Y + 1, Z1}) == E_BLOCK_OBSIDIAN)); Z1++) for (; ((a_ChunkInterface.GetBlock({X, Y, Z1}) == E_BLOCK_OBSIDIAN) || (a_ChunkInterface.GetBlock({X, Y + 1, Z1}) == E_BLOCK_OBSIDIAN)); Z1++)
{ {
@ -228,7 +230,7 @@ public:
return false; return false;
} }
} }
XZP = Z1 - 1; a_Scratch.XZP = Z1 - 1;
for (; ((a_ChunkInterface.GetBlock({X, Y, Z2}) == E_BLOCK_OBSIDIAN) || (a_ChunkInterface.GetBlock({X, Y + 1, Z2}) == E_BLOCK_OBSIDIAN)); Z2--) for (; ((a_ChunkInterface.GetBlock({X, Y, Z2}) == E_BLOCK_OBSIDIAN) || (a_ChunkInterface.GetBlock({X, Y + 1, Z2}) == E_BLOCK_OBSIDIAN)); Z2--)
{ {
int Value = FindObsidianCeiling(X, Y, Z2, a_ChunkInterface, MaxY); int Value = FindObsidianCeiling(X, Y, Z2, a_ChunkInterface, MaxY);
@ -243,17 +245,17 @@ public:
return false; return false;
} }
} }
XZM = Z2 + 1; a_Scratch.XZM = Z2 + 1;
return (FoundFrameZP && FoundFrameZM); return (FoundFrameZP && FoundFrameZM);
} }
virtual bool DoesIgnoreBuildCollision(cChunkInterface & a_ChunkInterface, Vector3i a_Pos, cPlayer & a_Player, NIBBLETYPE a_Meta) override virtual bool DoesIgnoreBuildCollision(cChunkInterface & a_ChunkInterface, Vector3i a_Pos, cPlayer & a_Player, NIBBLETYPE a_Meta) const override
{ {
return true; return true;
} }
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 15; return 15;

View File

@ -14,16 +14,11 @@ class cBlockFlowerHandler:
public: public:
cBlockFlowerHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{ {
NIBBLETYPE meta = a_BlockMeta & 0x7; NIBBLETYPE meta = a_BlockMeta & 0x7;
return cItem(m_BlockType, 1, meta); return cItem(m_BlockType, 1, meta);
@ -33,7 +28,7 @@ public:
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) const override
{ {
return ((a_RelPos.y > 0) && IsBlockTypeOfDirt(a_Chunk.GetBlock(a_RelPos.addedY(-1)))); return ((a_RelPos.y > 0) && IsBlockTypeOfDirt(a_Chunk.GetBlock(a_RelPos.addedY(-1))));
} }
@ -42,7 +37,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 7; return 7;

View File

@ -14,16 +14,11 @@ class cBlockFlowerPotHandler :
public: public:
cBlockFlowerPotHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{ {
return cItem(E_ITEM_FLOWER_POT, 1, 0); return cItem(E_ITEM_FLOWER_POT, 1, 0);
} }
@ -32,7 +27,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 0; return 0;

View File

@ -14,17 +14,11 @@ class cBlockFluidHandler:
public: public:
cBlockFluidHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
} private:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{ {
// No pickups // No pickups
return {}; return {};
@ -34,7 +28,7 @@ public:
virtual bool DoesIgnoreBuildCollision(cChunkInterface & a_ChunkInterface, Vector3i a_Pos, cPlayer & a_Player, NIBBLETYPE a_Meta) override virtual bool DoesIgnoreBuildCollision(cChunkInterface & a_ChunkInterface, Vector3i a_Pos, cPlayer & a_Player, NIBBLETYPE a_Meta) const override
{ {
return true; return true;
} }
@ -43,7 +37,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
if (IsBlockWater(m_BlockType)) if (IsBlockWater(m_BlockType))
@ -58,7 +52,7 @@ public:
virtual bool CanSustainPlant(BLOCKTYPE a_Plant) override virtual bool CanSustainPlant(BLOCKTYPE a_Plant) const override
{ {
return ( return (
(a_Plant == E_BLOCK_BEETROOTS) || (a_Plant == E_BLOCK_BEETROOTS) ||
@ -82,14 +76,9 @@ class cBlockLavaHandler:
public: public:
cBlockLavaHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual void OnUpdate( virtual void OnUpdate(
cChunkInterface & a_ChunkInterface, cChunkInterface & a_ChunkInterface,
@ -97,7 +86,7 @@ public:
cBlockPluginInterface & a_PluginInterface, cBlockPluginInterface & a_PluginInterface,
cChunk & a_Chunk, cChunk & a_Chunk,
const Vector3i a_RelPos const Vector3i a_RelPos
) override ) const override
{ {
if (a_Chunk.GetWorld()->ShouldLavaSpawnFire()) if (a_Chunk.GetWorld()->ShouldLavaSpawnFire())
{ {
@ -165,7 +154,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 4; return 4;
@ -175,7 +164,7 @@ public:
virtual bool CanSustainPlant(BLOCKTYPE a_Plant) override virtual bool CanSustainPlant(BLOCKTYPE a_Plant) const override
{ {
return false; return false;
} }

View File

@ -15,16 +15,11 @@ class cBlockFurnaceHandler :
public: public:
cBlockFurnaceHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{ {
cItems res(cItem(E_BLOCK_FURNACE, 1)); // We can't drop a lit furnace cItems res(cItem(E_BLOCK_FURNACE, 1)); // We can't drop a lit furnace
if (a_BlockEntity != nullptr) if (a_BlockEntity != nullptr)
@ -39,7 +34,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 11; return 11;

View File

@ -11,16 +11,12 @@ class cBlockGlassHandler :
public cBlockHandler public cBlockHandler
{ {
public: public:
cBlockGlassHandler(BLOCKTYPE a_BlockType)
: cBlockHandler(a_BlockType)
{
}
using cBlockHandler::cBlockHandler;
private:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{ {
// Only drop self when mined with silk-touch: // Only drop self when mined with silk-touch:
if (ToolHasSilkTouch(a_Tool)) if (ToolHasSilkTouch(a_Tool))
@ -34,7 +30,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 0; return 0;

View File

@ -11,16 +11,12 @@ class cBlockGlowstoneHandler :
public cBlockHandler public cBlockHandler
{ {
public: public:
cBlockGlowstoneHandler(BLOCKTYPE a_BlockType)
: cBlockHandler(a_BlockType)
{
}
using cBlockHandler::cBlockHandler;
private:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{ {
// Drop self only when using silk-touch: // Drop self only when using silk-touch:
if (ToolHasSilkTouch(a_Tool)) if (ToolHasSilkTouch(a_Tool))
@ -38,7 +34,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 2; return 2;

View File

@ -13,7 +13,11 @@
class cBlockGrassHandler : class cBlockGrassHandler :
public cBlockHandler public cBlockHandler
{ {
using super = cBlockHandler; public:
using cBlockHandler::cBlockHandler;
private:
enum class Survivability enum class Survivability
{ {
@ -27,18 +31,7 @@ class cBlockGrassHandler :
DieInDarkness DieInDarkness
}; };
public: virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
cBlockGrassHandler(BLOCKTYPE a_BlockType):
super(a_BlockType)
{
}
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{ {
if (!ToolHasSilkTouch(a_Tool)) if (!ToolHasSilkTouch(a_Tool))
{ {
@ -57,7 +50,7 @@ public:
cBlockPluginInterface & a_PluginInterface, cBlockPluginInterface & a_PluginInterface,
cChunk & a_Chunk, cChunk & a_Chunk,
const Vector3i a_RelPos const Vector3i a_RelPos
) override ) const override
{ {
if (!a_Chunk.GetWorld()->IsChunkLighted(a_Chunk.GetPosX(), a_Chunk.GetPosZ())) if (!a_Chunk.GetWorld()->IsChunkLighted(a_Chunk.GetPosX(), a_Chunk.GetPosZ()))
{ {
@ -92,7 +85,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 1; return 1;

View File

@ -11,16 +11,12 @@ class cBlockGravelHandler :
public cBlockHandler public cBlockHandler
{ {
public: public:
cBlockGravelHandler(BLOCKTYPE a_BlockType)
: cBlockHandler(a_BlockType)
{
}
using cBlockHandler::cBlockHandler;
private:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{ {
// TODO: Handle the Fortune and Silk touch enchantments here // TODO: Handle the Fortune and Silk touch enchantments here
if (GetRandomProvider().RandBool(0.10)) if (GetRandomProvider().RandBool(0.10))
@ -37,7 +33,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 11; return 11;

View File

@ -189,260 +189,262 @@ public:
/** Static list of all block handlers.
Ensures that a handler can never be nullptr (FS #243) on invalid during restarts or other transition periods. */
namespace namespace
{ {
cBlockDoorHandler BlockAcaciaDoorHandler (E_BLOCK_ACACIA_DOOR); constexpr cBlockDoorHandler BlockAcaciaDoorHandler (E_BLOCK_ACACIA_DOOR);
cBlockFenceGateHandler BlockAcaciaFenceGateHandler (E_BLOCK_ACACIA_FENCE_GATE); constexpr cBlockFenceGateHandler BlockAcaciaFenceGateHandler (E_BLOCK_ACACIA_FENCE_GATE);
cBlockFenceHandler BlockAcaciaFenceHandler (E_BLOCK_ACACIA_FENCE); constexpr cBlockFenceHandler BlockAcaciaFenceHandler (E_BLOCK_ACACIA_FENCE);
cBlockStairsHandler BlockAcaciaWoodStairsHandler (E_BLOCK_ACACIA_WOOD_STAIRS); constexpr cBlockStairsHandler BlockAcaciaWoodStairsHandler (E_BLOCK_ACACIA_WOOD_STAIRS);
cBlockRailHandler BlockActivatorRailHandler (E_BLOCK_ACTIVATOR_RAIL); constexpr cBlockRailHandler BlockActivatorRailHandler (E_BLOCK_ACTIVATOR_RAIL);
cBlockComparatorHandler BlockActiveComparatorHandler (E_BLOCK_ACTIVE_COMPARATOR); constexpr cBlockComparatorHandler BlockActiveComparatorHandler (E_BLOCK_ACTIVE_COMPARATOR);
cBlockWithNoDrops<> BlockAirHandler (E_BLOCK_AIR); constexpr cBlockWithNoDrops<> BlockAirHandler (E_BLOCK_AIR);
cBlockAnvilHandler BlockAnvilHandler (E_BLOCK_ANVIL); constexpr cBlockAnvilHandler BlockAnvilHandler (E_BLOCK_ANVIL);
cBlockHandler BlockBarrierHandler (E_BLOCK_BARRIER); constexpr cBlockHandler BlockBarrierHandler (E_BLOCK_BARRIER);
cBlockEntityHandler BlockBeaconHandler (E_BLOCK_BEACON); constexpr cBlockEntityHandler BlockBeaconHandler (E_BLOCK_BEACON);
cBlockBedHandler BlockBedHandler (E_BLOCK_BED); constexpr cBlockBedHandler BlockBedHandler (E_BLOCK_BED);
cBlockHandler BlockBedrockHandler (E_BLOCK_BEDROCK); constexpr cBlockHandler BlockBedrockHandler (E_BLOCK_BEDROCK);
cBlockCropsHandler<3> BlockBeetrootsHandler (E_BLOCK_BEETROOTS); // 4 stages of growth constexpr cBlockCropsHandler<3> BlockBeetrootsHandler (E_BLOCK_BEETROOTS); // 4 stages of growth
cBlockBigFlowerHandler BlockBigFlowerHandler (E_BLOCK_BIG_FLOWER); constexpr cBlockBigFlowerHandler BlockBigFlowerHandler (E_BLOCK_BIG_FLOWER);
cBlockDoorHandler BlockBirchDoorHandler (E_BLOCK_BIRCH_DOOR); constexpr cBlockDoorHandler BlockBirchDoorHandler (E_BLOCK_BIRCH_DOOR);
cBlockFenceGateHandler BlockBirchFenceGateHandler (E_BLOCK_BIRCH_FENCE_GATE); constexpr cBlockFenceGateHandler BlockBirchFenceGateHandler (E_BLOCK_BIRCH_FENCE_GATE);
cBlockFenceHandler BlockBirchFenceHandler (E_BLOCK_BIRCH_FENCE); constexpr cBlockFenceHandler BlockBirchFenceHandler (E_BLOCK_BIRCH_FENCE);
cBlockStairsHandler BlockBirchWoodStairsHandler (E_BLOCK_BIRCH_WOOD_STAIRS); constexpr cBlockStairsHandler BlockBirchWoodStairsHandler (E_BLOCK_BIRCH_WOOD_STAIRS);
cBlockGlazedTerracottaHandler BlockBlackGlazedTerracottaHandler (E_BLOCK_BLACK_GLAZED_TERRACOTTA); constexpr cBlockGlazedTerracottaHandler BlockBlackGlazedTerracottaHandler (E_BLOCK_BLACK_GLAZED_TERRACOTTA);
cBlockHandler BlockBlackShulkerBoxHandler (E_BLOCK_BLACK_SHULKER_BOX); constexpr cBlockHandler BlockBlackShulkerBoxHandler (E_BLOCK_BLACK_SHULKER_BOX);
cBlockHandler BlockBlockOfCoalHandler (E_BLOCK_BLOCK_OF_COAL); constexpr cBlockHandler BlockBlockOfCoalHandler (E_BLOCK_BLOCK_OF_COAL);
cBlockHandler BlockBlockOfRedstoneHandler (E_BLOCK_BLOCK_OF_REDSTONE); constexpr cBlockHandler BlockBlockOfRedstoneHandler (E_BLOCK_BLOCK_OF_REDSTONE);
cBlockGlazedTerracottaHandler BlockBlueGlazedTerracottaHandler (E_BLOCK_BLUE_GLAZED_TERRACOTTA); constexpr cBlockGlazedTerracottaHandler BlockBlueGlazedTerracottaHandler (E_BLOCK_BLUE_GLAZED_TERRACOTTA);
cBlockHandler BlockBlueShulkerBoxHandler (E_BLOCK_BLUE_SHULKER_BOX); constexpr cBlockHandler BlockBlueShulkerBoxHandler (E_BLOCK_BLUE_SHULKER_BOX);
cBlockHandler BlockBoneBlockHandler (E_BLOCK_BONE_BLOCK); constexpr cBlockHandler BlockBoneBlockHandler (E_BLOCK_BONE_BLOCK);
cBlockBookShelfHandler BlockBookcaseHandler (E_BLOCK_BOOKCASE); constexpr cBlockBookShelfHandler BlockBookcaseHandler (E_BLOCK_BOOKCASE);
cBlockBrewingStandHandler BlockBrewingStandHandler (E_BLOCK_BREWING_STAND); constexpr cBlockBrewingStandHandler BlockBrewingStandHandler (E_BLOCK_BREWING_STAND);
cBlockHandler BlockBrickHandler (E_BLOCK_BRICK); constexpr cBlockHandler BlockBrickHandler (E_BLOCK_BRICK);
cBlockStairsHandler BlockBrickStairsHandler (E_BLOCK_BRICK_STAIRS); constexpr cBlockStairsHandler BlockBrickStairsHandler (E_BLOCK_BRICK_STAIRS);
cBlockGlazedTerracottaHandler BlockBrownGlazedTerracottaHandler (E_BLOCK_BROWN_GLAZED_TERRACOTTA); constexpr cBlockGlazedTerracottaHandler BlockBrownGlazedTerracottaHandler (E_BLOCK_BROWN_GLAZED_TERRACOTTA);
cBlockMushroomHandler BlockBrownMushroomHandler (E_BLOCK_BROWN_MUSHROOM); constexpr cBlockMushroomHandler BlockBrownMushroomHandler (E_BLOCK_BROWN_MUSHROOM);
cBlockHandler BlockBrownShulkerBoxHandler (E_BLOCK_BROWN_SHULKER_BOX); constexpr cBlockHandler BlockBrownShulkerBoxHandler (E_BLOCK_BROWN_SHULKER_BOX);
cBlockCactusHandler BlockCactusHandler (E_BLOCK_CACTUS); constexpr cBlockCactusHandler BlockCactusHandler (E_BLOCK_CACTUS);
cBlockCakeHandler BlockCakeHandler (E_BLOCK_CAKE); constexpr cBlockCakeHandler BlockCakeHandler (E_BLOCK_CAKE);
cBlockCarpetHandler BlockCarpetHandler (E_BLOCK_CARPET); constexpr cBlockCarpetHandler BlockCarpetHandler (E_BLOCK_CARPET);
cBlockCropsHandler<7> BlockCarrotsHandler (E_BLOCK_CARROTS); // 8 stages of growth constexpr cBlockCropsHandler<7> BlockCarrotsHandler (E_BLOCK_CARROTS); // 8 stages of growth
cBlockCauldronHandler BlockCauldronHandler (E_BLOCK_CAULDRON); constexpr cBlockCauldronHandler BlockCauldronHandler (E_BLOCK_CAULDRON);
cBlockCommandBlockHandler BlockChainCommandBlockHandler (E_BLOCK_CHAIN_COMMAND_BLOCK); constexpr cBlockCommandBlockHandler BlockChainCommandBlockHandler (E_BLOCK_CHAIN_COMMAND_BLOCK);
cBlockChestHandler BlockChestHandler (E_BLOCK_CHEST); constexpr cBlockChestHandler BlockChestHandler (E_BLOCK_CHEST);
cBlockHandler BlockChorusFlowerHandler (E_BLOCK_CHORUS_FLOWER); constexpr cBlockHandler BlockChorusFlowerHandler (E_BLOCK_CHORUS_FLOWER);
cBlockHandler BlockChorusPlantHandler (E_BLOCK_CHORUS_PLANT); constexpr cBlockHandler BlockChorusPlantHandler (E_BLOCK_CHORUS_PLANT);
cBlockOreHandler BlockClayHandler (E_BLOCK_CLAY); constexpr cBlockOreHandler BlockClayHandler (E_BLOCK_CLAY);
cBlockOreHandler BlockCoalOreHandler (E_BLOCK_COAL_ORE); constexpr cBlockOreHandler BlockCoalOreHandler (E_BLOCK_COAL_ORE);
cBlockStoneHandler BlockCobblestoneHandler (E_BLOCK_COBBLESTONE); constexpr cBlockStoneHandler BlockCobblestoneHandler (E_BLOCK_COBBLESTONE);
cBlockStairsHandler BlockCobblestoneStairsHandler (E_BLOCK_COBBLESTONE_STAIRS); constexpr cBlockStairsHandler BlockCobblestoneStairsHandler (E_BLOCK_COBBLESTONE_STAIRS);
cBlockHandler BlockCobblestoneWallHandler (E_BLOCK_COBBLESTONE_WALL); constexpr cBlockHandler BlockCobblestoneWallHandler (E_BLOCK_COBBLESTONE_WALL);
cBlockCobWebHandler BlockCobwebHandler (E_BLOCK_COBWEB); constexpr cBlockCobWebHandler BlockCobwebHandler (E_BLOCK_COBWEB);
cBlockCocoaPodHandler BlockCocoaPodHandler (E_BLOCK_COCOA_POD); constexpr cBlockCocoaPodHandler BlockCocoaPodHandler (E_BLOCK_COCOA_POD);
cBlockCommandBlockHandler BlockCommandBlockHandler (E_BLOCK_COMMAND_BLOCK); constexpr cBlockCommandBlockHandler BlockCommandBlockHandler (E_BLOCK_COMMAND_BLOCK);
cBlockHandler BlockConcreteHandler (E_BLOCK_CONCRETE); constexpr cBlockHandler BlockConcreteHandler (E_BLOCK_CONCRETE);
cBlockConcretePowderHandler BlockConcretePowderHandler (E_BLOCK_CONCRETE_POWDER); constexpr cBlockConcretePowderHandler BlockConcretePowderHandler (E_BLOCK_CONCRETE_POWDER);
cBlockCropsHandler<7> BlockCropsHandler (E_BLOCK_CROPS); // 8 stages of growth constexpr cBlockCropsHandler<7> BlockCropsHandler (E_BLOCK_CROPS); // 8 stages of growth
cBlockGlazedTerracottaHandler BlockCyanGlazedTerracottaHandler (E_BLOCK_CYAN_GLAZED_TERRACOTTA); constexpr cBlockGlazedTerracottaHandler BlockCyanGlazedTerracottaHandler (E_BLOCK_CYAN_GLAZED_TERRACOTTA);
cBlockHandler BlockCyanShulkerBoxHandler (E_BLOCK_CYAN_SHULKER_BOX); constexpr cBlockHandler BlockCyanShulkerBoxHandler (E_BLOCK_CYAN_SHULKER_BOX);
cBlockDoorHandler BlockDarkOakDoorHandler (E_BLOCK_DARK_OAK_DOOR); constexpr cBlockDoorHandler BlockDarkOakDoorHandler (E_BLOCK_DARK_OAK_DOOR);
cBlockFenceGateHandler BlockDarkOakFenceGateHandler (E_BLOCK_DARK_OAK_FENCE_GATE); constexpr cBlockFenceGateHandler BlockDarkOakFenceGateHandler (E_BLOCK_DARK_OAK_FENCE_GATE);
cBlockFenceHandler BlockDarkOakFenceHandler (E_BLOCK_DARK_OAK_FENCE); constexpr cBlockFenceHandler BlockDarkOakFenceHandler (E_BLOCK_DARK_OAK_FENCE);
cBlockStairsHandler BlockDarkOakWoodStairsHandler (E_BLOCK_DARK_OAK_WOOD_STAIRS); constexpr cBlockStairsHandler BlockDarkOakWoodStairsHandler (E_BLOCK_DARK_OAK_WOOD_STAIRS);
cBlockHandler BlockDaylightSensorHandler (E_BLOCK_DAYLIGHT_SENSOR); constexpr cBlockHandler BlockDaylightSensorHandler (E_BLOCK_DAYLIGHT_SENSOR);
cBlockDeadBushHandler BlockDeadBushHandler (E_BLOCK_DEAD_BUSH); constexpr cBlockDeadBushHandler BlockDeadBushHandler (E_BLOCK_DEAD_BUSH);
cBlockRailHandler BlockDetectorRailHandler (E_BLOCK_DETECTOR_RAIL); constexpr cBlockRailHandler BlockDetectorRailHandler (E_BLOCK_DETECTOR_RAIL);
cBlockHandler BlockDiamondBlockHandler (E_BLOCK_DIAMOND_BLOCK); constexpr cBlockHandler BlockDiamondBlockHandler (E_BLOCK_DIAMOND_BLOCK);
cBlockOreHandler BlockDiamondOreHandler (E_BLOCK_DIAMOND_ORE); constexpr cBlockOreHandler BlockDiamondOreHandler (E_BLOCK_DIAMOND_ORE);
cBlockDirtHandler BlockDirtHandler (E_BLOCK_DIRT); constexpr cBlockDirtHandler BlockDirtHandler (E_BLOCK_DIRT);
cBlockDropSpenserHandler BlockDispenserHandler (E_BLOCK_DISPENSER); constexpr cBlockDropSpenserHandler BlockDispenserHandler (E_BLOCK_DISPENSER);
cBlockDoubleSlabHandler BlockDoubleRedSandstoneSlabHandler(E_BLOCK_DOUBLE_RED_SANDSTONE_SLAB); constexpr cBlockDoubleSlabHandler BlockDoubleRedSandstoneSlabHandler(E_BLOCK_DOUBLE_RED_SANDSTONE_SLAB);
cBlockDoubleSlabHandler BlockDoubleStoneSlabHandler (E_BLOCK_DOUBLE_STONE_SLAB); constexpr cBlockDoubleSlabHandler BlockDoubleStoneSlabHandler (E_BLOCK_DOUBLE_STONE_SLAB);
cBlockDoubleSlabHandler BlockDoubleWoodenSlabHandler (E_BLOCK_DOUBLE_WOODEN_SLAB); constexpr cBlockDoubleSlabHandler BlockDoubleWoodenSlabHandler (E_BLOCK_DOUBLE_WOODEN_SLAB);
cBlockHandler BlockDragonEggHandler (E_BLOCK_DRAGON_EGG); constexpr cBlockHandler BlockDragonEggHandler (E_BLOCK_DRAGON_EGG);
cBlockDropSpenserHandler BlockDropperHandler (E_BLOCK_DROPPER); constexpr cBlockDropSpenserHandler BlockDropperHandler (E_BLOCK_DROPPER);
cBlockHandler BlockEmeraldBlockHandler (E_BLOCK_EMERALD_BLOCK); constexpr cBlockHandler BlockEmeraldBlockHandler (E_BLOCK_EMERALD_BLOCK);
cBlockOreHandler BlockEmeraldOreHandler (E_BLOCK_EMERALD_ORE); constexpr cBlockOreHandler BlockEmeraldOreHandler (E_BLOCK_EMERALD_ORE);
cBlockEnchantingTableHandler BlockEnchantingTableHandler (E_BLOCK_ENCHANTMENT_TABLE); constexpr cBlockEnchantingTableHandler BlockEnchantingTableHandler (E_BLOCK_ENCHANTMENT_TABLE);
cBlockHandler BlockEndBricksHandler (E_BLOCK_END_BRICKS); constexpr cBlockHandler BlockEndBricksHandler (E_BLOCK_END_BRICKS);
cBlockHandler BlockEndGatewayHandler (E_BLOCK_END_GATEWAY); constexpr cBlockHandler BlockEndGatewayHandler (E_BLOCK_END_GATEWAY);
cBlockEndPortalFrameHandler BlockEndPortalFrameHandler (E_BLOCK_END_PORTAL_FRAME); constexpr cBlockEndPortalFrameHandler BlockEndPortalFrameHandler (E_BLOCK_END_PORTAL_FRAME);
cBlockHandler BlockEndPortalHandler (E_BLOCK_END_PORTAL); constexpr cBlockHandler BlockEndPortalHandler (E_BLOCK_END_PORTAL);
cBlockHandler BlockEndRodHandler (E_BLOCK_END_ROD); constexpr cBlockHandler BlockEndRodHandler (E_BLOCK_END_ROD);
cBlockHandler BlockEndStoneHandler (E_BLOCK_END_STONE); constexpr cBlockHandler BlockEndStoneHandler (E_BLOCK_END_STONE);
cBlockEnderchestHandler BlockEnderChestHandler (E_BLOCK_ENDER_CHEST); constexpr cBlockEnderchestHandler BlockEnderChestHandler (E_BLOCK_ENDER_CHEST);
cBlockFarmlandHandler BlockFarmlandHandler (E_BLOCK_FARMLAND); constexpr cBlockFarmlandHandler BlockFarmlandHandler (E_BLOCK_FARMLAND);
cBlockFenceHandler BlockFenceHandler (E_BLOCK_FENCE); constexpr cBlockFenceHandler BlockFenceHandler (E_BLOCK_FENCE);
cBlockFireHandler BlockFireHandler (E_BLOCK_FIRE); constexpr cBlockFireHandler BlockFireHandler (E_BLOCK_FIRE);
cBlockFlowerPotHandler BlockFlowerPotHandler (E_BLOCK_FLOWER_POT); constexpr cBlockFlowerPotHandler BlockFlowerPotHandler (E_BLOCK_FLOWER_POT);
cBlockIceHandler BlockFrostedIceHandler (E_BLOCK_FROSTED_ICE); constexpr cBlockIceHandler BlockFrostedIceHandler (E_BLOCK_FROSTED_ICE);
cBlockFurnaceHandler BlockFurnaceHandler (E_BLOCK_FURNACE); constexpr cBlockFurnaceHandler BlockFurnaceHandler (E_BLOCK_FURNACE);
cBlockGlassHandler BlockGlassHandler (E_BLOCK_GLASS); constexpr cBlockGlassHandler BlockGlassHandler (E_BLOCK_GLASS);
cBlockGlassHandler BlockGlassPaneHandler (E_BLOCK_GLASS_PANE); constexpr cBlockGlassHandler BlockGlassPaneHandler (E_BLOCK_GLASS_PANE);
cBlockGlowstoneHandler BlockGlowstoneHandler (E_BLOCK_GLOWSTONE); constexpr cBlockGlowstoneHandler BlockGlowstoneHandler (E_BLOCK_GLOWSTONE);
cBlockHandler BlockGoldBlockHandler (E_BLOCK_GOLD_BLOCK); constexpr cBlockHandler BlockGoldBlockHandler (E_BLOCK_GOLD_BLOCK);
cBlockOreHandler BlockGoldOreHandler (E_BLOCK_GOLD_ORE); constexpr cBlockOreHandler BlockGoldOreHandler (E_BLOCK_GOLD_ORE);
cBlockGrassHandler BlockGrassHandler (E_BLOCK_GRASS); constexpr cBlockGrassHandler BlockGrassHandler (E_BLOCK_GRASS);
cBlockHandler BlockGrassPathHandler (E_BLOCK_GRASS_PATH); constexpr cBlockHandler BlockGrassPathHandler (E_BLOCK_GRASS_PATH);
cBlockGravelHandler BlockGravelHandler (E_BLOCK_GRAVEL); constexpr cBlockGravelHandler BlockGravelHandler (E_BLOCK_GRAVEL);
cBlockGlazedTerracottaHandler BlockGrayGlazedTerracottaHandler (E_BLOCK_GRAY_GLAZED_TERRACOTTA); constexpr cBlockGlazedTerracottaHandler BlockGrayGlazedTerracottaHandler (E_BLOCK_GRAY_GLAZED_TERRACOTTA);
cBlockHandler BlockGrayShulkerBoxHandler (E_BLOCK_GRAY_SHULKER_BOX); constexpr cBlockHandler BlockGrayShulkerBoxHandler (E_BLOCK_GRAY_SHULKER_BOX);
cBlockGlazedTerracottaHandler BlockGreenGlazedTerracottaHandler (E_BLOCK_GREEN_GLAZED_TERRACOTTA); constexpr cBlockGlazedTerracottaHandler BlockGreenGlazedTerracottaHandler (E_BLOCK_GREEN_GLAZED_TERRACOTTA);
cBlockHandler BlockGreenShulkerBoxHandler (E_BLOCK_GREEN_SHULKER_BOX); constexpr cBlockHandler BlockGreenShulkerBoxHandler (E_BLOCK_GREEN_SHULKER_BOX);
cBlockHandler BlockHardenedClayHandler (E_BLOCK_HARDENED_CLAY); constexpr cBlockHandler BlockHardenedClayHandler (E_BLOCK_HARDENED_CLAY);
cBlockSidewaysHandler BlockHayBaleHandler (E_BLOCK_HAY_BALE); constexpr cBlockSidewaysHandler BlockHayBaleHandler (E_BLOCK_HAY_BALE);
cBlockMobHeadHandler BlockHeadHandler (E_BLOCK_HEAD); constexpr cBlockMobHeadHandler BlockHeadHandler (E_BLOCK_HEAD);
cBlockPressurePlateHandler BlockHeavyWeightedPressurePHandler(E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE); constexpr cBlockPressurePlateHandler BlockHeavyWeightedPressurePHandler(E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE);
cBlockHopperHandler BlockHopperHandler (E_BLOCK_HOPPER); constexpr cBlockHopperHandler BlockHopperHandler (E_BLOCK_HOPPER);
cBlockHandler BlockHugeBrownMushroomHandler (E_BLOCK_HUGE_BROWN_MUSHROOM); constexpr cBlockHandler BlockHugeBrownMushroomHandler (E_BLOCK_HUGE_BROWN_MUSHROOM);
cBlockHandler BlockHugeRedMushroomHandler (E_BLOCK_HUGE_RED_MUSHROOM); constexpr cBlockHandler BlockHugeRedMushroomHandler (E_BLOCK_HUGE_RED_MUSHROOM);
cBlockIceHandler BlockIceHandler (E_BLOCK_ICE); constexpr cBlockIceHandler BlockIceHandler (E_BLOCK_ICE);
cBlockComparatorHandler BlockInactiveComparatorHandler (E_BLOCK_INACTIVE_COMPARATOR); constexpr cBlockComparatorHandler BlockInactiveComparatorHandler (E_BLOCK_INACTIVE_COMPARATOR);
cBlockHandler BlockInfestedBlockHandler (E_BLOCK_SILVERFISH_EGG); constexpr cBlockHandler BlockInfestedBlockHandler (E_BLOCK_SILVERFISH_EGG);
cBlockHandler BlockIronBarsHandler (E_BLOCK_IRON_BARS); constexpr cBlockHandler BlockIronBarsHandler (E_BLOCK_IRON_BARS);
cBlockHandler BlockIronBlockHandler (E_BLOCK_IRON_BLOCK); constexpr cBlockHandler BlockIronBlockHandler (E_BLOCK_IRON_BLOCK);
cBlockDoorHandler BlockIronDoorHandler (E_BLOCK_IRON_DOOR); constexpr cBlockDoorHandler BlockIronDoorHandler (E_BLOCK_IRON_DOOR);
cBlockOreHandler BlockIronOreHandler (E_BLOCK_IRON_ORE); constexpr cBlockOreHandler BlockIronOreHandler (E_BLOCK_IRON_ORE);
cBlockTrapdoorHandler BlockIronTrapdoorHandler (E_BLOCK_IRON_TRAPDOOR); constexpr cBlockTrapdoorHandler BlockIronTrapdoorHandler (E_BLOCK_IRON_TRAPDOOR);
cBlockPumpkinHandler BlockJackOLanternHandler (E_BLOCK_JACK_O_LANTERN); constexpr cBlockPumpkinHandler BlockJackOLanternHandler (E_BLOCK_JACK_O_LANTERN);
cBlockJukeboxHandler BlockJukeboxHandler (E_BLOCK_JUKEBOX); constexpr cBlockJukeboxHandler BlockJukeboxHandler (E_BLOCK_JUKEBOX);
cBlockDoorHandler BlockJungleDoorHandler (E_BLOCK_JUNGLE_DOOR); constexpr cBlockDoorHandler BlockJungleDoorHandler (E_BLOCK_JUNGLE_DOOR);
cBlockFenceGateHandler BlockJungleFenceGateHandler (E_BLOCK_JUNGLE_FENCE_GATE); constexpr cBlockFenceGateHandler BlockJungleFenceGateHandler (E_BLOCK_JUNGLE_FENCE_GATE);
cBlockFenceHandler BlockJungleFenceHandler (E_BLOCK_JUNGLE_FENCE); constexpr cBlockFenceHandler BlockJungleFenceHandler (E_BLOCK_JUNGLE_FENCE);
cBlockStairsHandler BlockJungleWoodStairsHandler (E_BLOCK_JUNGLE_WOOD_STAIRS); constexpr cBlockStairsHandler BlockJungleWoodStairsHandler (E_BLOCK_JUNGLE_WOOD_STAIRS);
cBlockLadderHandler BlockLadderHandler (E_BLOCK_LADDER); constexpr cBlockLadderHandler BlockLadderHandler (E_BLOCK_LADDER);
cBlockHandler BlockLapisBlockHandler (E_BLOCK_LAPIS_BLOCK); constexpr cBlockHandler BlockLapisBlockHandler (E_BLOCK_LAPIS_BLOCK);
cBlockOreHandler BlockLapisOreHandler (E_BLOCK_LAPIS_ORE); constexpr cBlockOreHandler BlockLapisOreHandler (E_BLOCK_LAPIS_ORE);
cBlockLavaHandler BlockLavaHandler (E_BLOCK_LAVA); constexpr cBlockLavaHandler BlockLavaHandler (E_BLOCK_LAVA);
cBlockLeavesHandler BlockLeavesHandler (E_BLOCK_LEAVES); constexpr cBlockLeavesHandler BlockLeavesHandler (E_BLOCK_LEAVES);
cBlockLeverHandler BlockLeverHandler (E_BLOCK_LEVER); constexpr cBlockLeverHandler BlockLeverHandler (E_BLOCK_LEVER);
cBlockGlazedTerracottaHandler BlockLightBlueGlazedTerracoHandler(E_BLOCK_LIGHT_BLUE_GLAZED_TERRACOTTA); constexpr cBlockGlazedTerracottaHandler BlockLightBlueGlazedTerracoHandler(E_BLOCK_LIGHT_BLUE_GLAZED_TERRACOTTA);
cBlockHandler BlockLightBlueShulkerBoxHandler (E_BLOCK_LIGHT_BLUE_SHULKER_BOX); constexpr cBlockHandler BlockLightBlueShulkerBoxHandler (E_BLOCK_LIGHT_BLUE_SHULKER_BOX);
cBlockGlazedTerracottaHandler BlockLightGrayGlazedTerracoHandler(E_BLOCK_LIGHT_GRAY_GLAZED_TERRACOTTA); constexpr cBlockGlazedTerracottaHandler BlockLightGrayGlazedTerracoHandler(E_BLOCK_LIGHT_GRAY_GLAZED_TERRACOTTA);
cBlockHandler BlockLightGrayShulkerBoxHandler (E_BLOCK_LIGHT_GRAY_SHULKER_BOX); constexpr cBlockHandler BlockLightGrayShulkerBoxHandler (E_BLOCK_LIGHT_GRAY_SHULKER_BOX);
cBlockPressurePlateHandler BlockLightWeightedPressurePHandler(E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE); constexpr cBlockPressurePlateHandler BlockLightWeightedPressurePHandler(E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE);
cBlockLilypadHandler BlockLilyPadHandler (E_BLOCK_LILY_PAD); constexpr cBlockLilypadHandler BlockLilyPadHandler (E_BLOCK_LILY_PAD);
cBlockGlazedTerracottaHandler BlockLimeGlazedTerracottaHandler (E_BLOCK_LIME_GLAZED_TERRACOTTA); constexpr cBlockGlazedTerracottaHandler BlockLimeGlazedTerracottaHandler (E_BLOCK_LIME_GLAZED_TERRACOTTA);
cBlockHandler BlockLimeShulkerBoxHandler (E_BLOCK_LIME_SHULKER_BOX); constexpr cBlockHandler BlockLimeShulkerBoxHandler (E_BLOCK_LIME_SHULKER_BOX);
cBlockFurnaceHandler BlockLitFurnaceHandler (E_BLOCK_LIT_FURNACE); constexpr cBlockFurnaceHandler BlockLitFurnaceHandler (E_BLOCK_LIT_FURNACE);
cBlockSidewaysHandler BlockLogHandler (E_BLOCK_LOG); constexpr cBlockSidewaysHandler BlockLogHandler (E_BLOCK_LOG);
cBlockGlazedTerracottaHandler BlockMagentaGlazedTerracottHandler(E_BLOCK_MAGENTA_GLAZED_TERRACOTTA); constexpr cBlockGlazedTerracottaHandler BlockMagentaGlazedTerracottHandler(E_BLOCK_MAGENTA_GLAZED_TERRACOTTA);
cBlockHandler BlockMagentaShulkerBoxHandler (E_BLOCK_MAGENTA_SHULKER_BOX); constexpr cBlockHandler BlockMagentaShulkerBoxHandler (E_BLOCK_MAGENTA_SHULKER_BOX);
cBlockHandler BlockMagmaHandler (E_BLOCK_MAGMA); constexpr cBlockHandler BlockMagmaHandler (E_BLOCK_MAGMA);
cBlockMelonHandler BlockMelonHandler (E_BLOCK_MELON); constexpr cBlockMelonHandler BlockMelonHandler (E_BLOCK_MELON);
cBlockMelonStemHandler BlockMelonStemHandler (E_BLOCK_MELON_STEM); constexpr cBlockMelonStemHandler BlockMelonStemHandler (E_BLOCK_MELON_STEM);
cBlockMobSpawnerHandler BlockMobSpawnerHandler (E_BLOCK_MOB_SPAWNER); constexpr cBlockMobSpawnerHandler BlockMobSpawnerHandler (E_BLOCK_MOB_SPAWNER);
cBlockHandler BlockMossyCobblestoneHandler (E_BLOCK_MOSSY_COBBLESTONE); constexpr cBlockHandler BlockMossyCobblestoneHandler (E_BLOCK_MOSSY_COBBLESTONE);
cBlockMyceliumHandler BlockMyceliumHandler (E_BLOCK_MYCELIUM); constexpr cBlockMyceliumHandler BlockMyceliumHandler (E_BLOCK_MYCELIUM);
cBlockFenceHandler BlockNetherBrickFenceHandler (E_BLOCK_NETHER_BRICK_FENCE); constexpr cBlockFenceHandler BlockNetherBrickFenceHandler (E_BLOCK_NETHER_BRICK_FENCE);
cBlockHandler BlockNetherBrickHandler (E_BLOCK_NETHER_BRICK); constexpr cBlockHandler BlockNetherBrickHandler (E_BLOCK_NETHER_BRICK);
cBlockStairsHandler BlockNetherBrickStairsHandler (E_BLOCK_NETHER_BRICK_STAIRS); constexpr cBlockStairsHandler BlockNetherBrickStairsHandler (E_BLOCK_NETHER_BRICK_STAIRS);
cBlockPortalHandler BlockNetherPortalHandler (E_BLOCK_NETHER_PORTAL); constexpr cBlockPortalHandler BlockNetherPortalHandler (E_BLOCK_NETHER_PORTAL);
cBlockOreHandler BlockNetherQuartzOreHandler (E_BLOCK_NETHER_QUARTZ_ORE); constexpr cBlockOreHandler BlockNetherQuartzOreHandler (E_BLOCK_NETHER_QUARTZ_ORE);
cBlockHandler BlockNetherWartBlockHandler (E_BLOCK_NETHER_WART_BLOCK); constexpr cBlockHandler BlockNetherWartBlockHandler (E_BLOCK_NETHER_WART_BLOCK);
cBlockNetherWartHandler BlockNetherWartHandler (E_BLOCK_NETHER_WART); constexpr cBlockNetherWartHandler BlockNetherWartHandler (E_BLOCK_NETHER_WART);
cBlockNetherrack BlockNetherrackHandler (E_BLOCK_NETHERRACK); constexpr cBlockNetherrack BlockNetherrackHandler (E_BLOCK_NETHERRACK);
cBlockLeavesHandler BlockNewLeavesHandler (E_BLOCK_NEW_LEAVES); constexpr cBlockLeavesHandler BlockNewLeavesHandler (E_BLOCK_NEW_LEAVES);
cBlockSidewaysHandler BlockNewLogHandler (E_BLOCK_NEW_LOG); constexpr cBlockSidewaysHandler BlockNewLogHandler (E_BLOCK_NEW_LOG);
cBlockEntityHandler BlockNoteBlockHandler (E_BLOCK_NOTE_BLOCK); constexpr cBlockEntityHandler BlockNoteBlockHandler (E_BLOCK_NOTE_BLOCK);
cBlockDoorHandler BlockOakDoorHandler (E_BLOCK_OAK_DOOR); constexpr cBlockDoorHandler BlockOakDoorHandler (E_BLOCK_OAK_DOOR);
cBlockFenceGateHandler BlockOakFenceGateHandler (E_BLOCK_OAK_FENCE_GATE); constexpr cBlockFenceGateHandler BlockOakFenceGateHandler (E_BLOCK_OAK_FENCE_GATE);
cBlockStairsHandler BlockOakWoodStairsHandler (E_BLOCK_OAK_WOOD_STAIRS); constexpr cBlockStairsHandler BlockOakWoodStairsHandler (E_BLOCK_OAK_WOOD_STAIRS);
cBlockObserverHandler BlockObserverHandler (E_BLOCK_OBSERVER); constexpr cBlockObserverHandler BlockObserverHandler (E_BLOCK_OBSERVER);
cBlockHandler BlockObsidianHandler (E_BLOCK_OBSIDIAN); constexpr cBlockHandler BlockObsidianHandler (E_BLOCK_OBSIDIAN);
cBlockGlazedTerracottaHandler BlockOrangeGlazedTerracottaHandler(E_BLOCK_ORANGE_GLAZED_TERRACOTTA); constexpr cBlockGlazedTerracottaHandler BlockOrangeGlazedTerracottaHandler(E_BLOCK_ORANGE_GLAZED_TERRACOTTA);
cBlockHandler BlockOrangeShulkerBoxHandler (E_BLOCK_ORANGE_SHULKER_BOX); constexpr cBlockHandler BlockOrangeShulkerBoxHandler (E_BLOCK_ORANGE_SHULKER_BOX);
cBlockIceHandler BlockPackedIceHandler (E_BLOCK_PACKED_ICE); constexpr cBlockIceHandler BlockPackedIceHandler (E_BLOCK_PACKED_ICE);
cBlockGlazedTerracottaHandler BlockPinkGlazedTerracottaHandler (E_BLOCK_PINK_GLAZED_TERRACOTTA); constexpr cBlockGlazedTerracottaHandler BlockPinkGlazedTerracottaHandler (E_BLOCK_PINK_GLAZED_TERRACOTTA);
cBlockHandler BlockPinkShulkerBoxHandler (E_BLOCK_PINK_SHULKER_BOX); constexpr cBlockHandler BlockPinkShulkerBoxHandler (E_BLOCK_PINK_SHULKER_BOX);
cBlockPistonHandler BlockPistonHandler (E_BLOCK_PISTON); constexpr cBlockPistonHandler BlockPistonHandler (E_BLOCK_PISTON);
cBlockPistonHeadHandler BlockPistonHeadHandler; constexpr cBlockPistonHeadHandler BlockPistonHeadHandler;
cBlockHandler BlockPistonMovedBlockHandler (E_BLOCK_PISTON_MOVED_BLOCK); constexpr cBlockHandler BlockPistonMovedBlockHandler (E_BLOCK_PISTON_MOVED_BLOCK);
cBlockPlanksHandler BlockPlanksHandler (E_BLOCK_PLANKS); constexpr cBlockPlanksHandler BlockPlanksHandler (E_BLOCK_PLANKS);
cBlockCropsHandler<7> BlockPotatoesHandler (E_BLOCK_POTATOES); // 8 stages of growth constexpr cBlockCropsHandler<7> BlockPotatoesHandler (E_BLOCK_POTATOES); // 8 stages of growth
cBlockRailHandler BlockPoweredRailHandler (E_BLOCK_POWERED_RAIL); constexpr cBlockRailHandler BlockPoweredRailHandler (E_BLOCK_POWERED_RAIL);
cBlockHandler BlockPrismarineBlockHandler (E_BLOCK_PRISMARINE_BLOCK); constexpr cBlockHandler BlockPrismarineBlockHandler (E_BLOCK_PRISMARINE_BLOCK);
cBlockPumpkinHandler BlockPumpkinHandler (E_BLOCK_PUMPKIN); constexpr cBlockPumpkinHandler BlockPumpkinHandler (E_BLOCK_PUMPKIN);
cBlockPumpkinStemHandler BlockPumpkinStemHandler (E_BLOCK_PUMPKIN_STEM); constexpr cBlockPumpkinStemHandler BlockPumpkinStemHandler (E_BLOCK_PUMPKIN_STEM);
cBlockGlazedTerracottaHandler BlockPurpleGlazedTerracottaHandler(E_BLOCK_PURPLE_GLAZED_TERRACOTTA); constexpr cBlockGlazedTerracottaHandler BlockPurpleGlazedTerracottaHandler(E_BLOCK_PURPLE_GLAZED_TERRACOTTA);
cBlockHandler BlockPurpleShulkerBoxHandler (E_BLOCK_PURPLE_SHULKER_BOX); constexpr cBlockHandler BlockPurpleShulkerBoxHandler (E_BLOCK_PURPLE_SHULKER_BOX);
cBlockHandler BlockPurpurBlockHandler (E_BLOCK_PURPUR_BLOCK); constexpr cBlockHandler BlockPurpurBlockHandler (E_BLOCK_PURPUR_BLOCK);
cBlockDoubleSlabHandler BlockPurpurDoubleSlabHandler (E_BLOCK_PURPUR_DOUBLE_SLAB); constexpr cBlockDoubleSlabHandler BlockPurpurDoubleSlabHandler (E_BLOCK_PURPUR_DOUBLE_SLAB);
cBlockHandler BlockPurpurPillarHandler (E_BLOCK_PURPUR_PILLAR); constexpr cBlockHandler BlockPurpurPillarHandler (E_BLOCK_PURPUR_PILLAR);
cBlockSlabHandler BlockPurpurSlabHandler (E_BLOCK_PURPUR_SLAB); constexpr cBlockSlabHandler BlockPurpurSlabHandler (E_BLOCK_PURPUR_SLAB);
cBlockStairsHandler BlockPurpurStairsHandler (E_BLOCK_PURPUR_STAIRS); constexpr cBlockStairsHandler BlockPurpurStairsHandler (E_BLOCK_PURPUR_STAIRS);
cBlockQuartzHandler BlockQuartzBlockHandler (E_BLOCK_QUARTZ_BLOCK); constexpr cBlockQuartzHandler BlockQuartzBlockHandler (E_BLOCK_QUARTZ_BLOCK);
cBlockStairsHandler BlockQuartzStairsHandler (E_BLOCK_QUARTZ_STAIRS); constexpr cBlockStairsHandler BlockQuartzStairsHandler (E_BLOCK_QUARTZ_STAIRS);
cBlockRailHandler BlockRailHandler (E_BLOCK_RAIL); constexpr cBlockRailHandler BlockRailHandler (E_BLOCK_RAIL);
cBlockGlazedTerracottaHandler BlockRedGlazedTerracottaHandler (E_BLOCK_RED_GLAZED_TERRACOTTA); constexpr cBlockGlazedTerracottaHandler BlockRedGlazedTerracottaHandler (E_BLOCK_RED_GLAZED_TERRACOTTA);
cBlockMushroomHandler BlockRedMushroomHandler (E_BLOCK_RED_MUSHROOM); constexpr cBlockMushroomHandler BlockRedMushroomHandler (E_BLOCK_RED_MUSHROOM);
cBlockHandler BlockRedNetherBrickHandler (E_BLOCK_RED_NETHER_BRICK); constexpr cBlockHandler BlockRedNetherBrickHandler (E_BLOCK_RED_NETHER_BRICK);
cBlockFlowerHandler BlockRedRoseHandler (E_BLOCK_RED_ROSE); constexpr cBlockFlowerHandler BlockRedRoseHandler (E_BLOCK_RED_ROSE);
cBlockHandler BlockRedSandstoneHandler (E_BLOCK_RED_SANDSTONE); constexpr cBlockHandler BlockRedSandstoneHandler (E_BLOCK_RED_SANDSTONE);
cBlockSlabHandler BlockRedSandstoneSlabHandler (E_BLOCK_RED_SANDSTONE_SLAB); constexpr cBlockSlabHandler BlockRedSandstoneSlabHandler (E_BLOCK_RED_SANDSTONE_SLAB);
cBlockStairsHandler BlockRedSandstoneStairsHandler (E_BLOCK_RED_SANDSTONE_STAIRS); constexpr cBlockStairsHandler BlockRedSandstoneStairsHandler (E_BLOCK_RED_SANDSTONE_STAIRS);
cBlockHandler BlockRedShulkerBoxHandler (E_BLOCK_RED_SHULKER_BOX); constexpr cBlockHandler BlockRedShulkerBoxHandler (E_BLOCK_RED_SHULKER_BOX);
cBlockRedstoneLampHandler BlockRedstoneLampHandler (E_BLOCK_REDSTONE_LAMP_ON); constexpr cBlockRedstoneLampHandler BlockRedstoneLampHandler (E_BLOCK_REDSTONE_LAMP_ON);
cBlockGlowingRedstoneOreHandler BlockRedstoneOreGlowingHandler (E_BLOCK_REDSTONE_ORE_GLOWING); constexpr cBlockGlowingRedstoneOreHandler BlockRedstoneOreGlowingHandler (E_BLOCK_REDSTONE_ORE_GLOWING);
cBlockRedstoneOreHandler BlockRedstoneOreHandler (E_BLOCK_REDSTONE_ORE); constexpr cBlockRedstoneOreHandler BlockRedstoneOreHandler (E_BLOCK_REDSTONE_ORE);
cBlockRedstoneRepeaterHandler BlockRedstoneRepeaterOffHandler (E_BLOCK_REDSTONE_REPEATER_OFF); constexpr cBlockRedstoneRepeaterHandler BlockRedstoneRepeaterOffHandler (E_BLOCK_REDSTONE_REPEATER_OFF);
cBlockRedstoneRepeaterHandler BlockRedstoneRepeaterOnHandler (E_BLOCK_REDSTONE_REPEATER_ON); constexpr cBlockRedstoneRepeaterHandler BlockRedstoneRepeaterOnHandler (E_BLOCK_REDSTONE_REPEATER_ON);
cBlockRedstoneTorchHandler BlockRedstoneTorchOffHandler (E_BLOCK_REDSTONE_TORCH_OFF); constexpr cBlockRedstoneTorchHandler BlockRedstoneTorchOffHandler (E_BLOCK_REDSTONE_TORCH_OFF);
cBlockRedstoneTorchHandler BlockRedstoneTorchOnHandler (E_BLOCK_REDSTONE_TORCH_ON); constexpr cBlockRedstoneTorchHandler BlockRedstoneTorchOnHandler (E_BLOCK_REDSTONE_TORCH_ON);
cBlockRedstoneHandler BlockRedstoneWireHandler (E_BLOCK_REDSTONE_WIRE); constexpr cBlockRedstoneHandler BlockRedstoneWireHandler (E_BLOCK_REDSTONE_WIRE);
cBlockCommandBlockHandler BlockRepeatingCommandBlockHandler (E_BLOCK_REPEATING_COMMAND_BLOCK); constexpr cBlockCommandBlockHandler BlockRepeatingCommandBlockHandler (E_BLOCK_REPEATING_COMMAND_BLOCK);
cBlockSandHandler BlockSandHandler (E_BLOCK_SAND); constexpr cBlockSandHandler BlockSandHandler (E_BLOCK_SAND);
cBlockHandler BlockSandstoneHandler (E_BLOCK_SANDSTONE); constexpr cBlockHandler BlockSandstoneHandler (E_BLOCK_SANDSTONE);
cBlockStairsHandler BlockSandstoneStairsHandler (E_BLOCK_SANDSTONE_STAIRS); constexpr cBlockStairsHandler BlockSandstoneStairsHandler (E_BLOCK_SANDSTONE_STAIRS);
cBlockSaplingHandler BlockSaplingHandler (E_BLOCK_SAPLING); constexpr cBlockSaplingHandler BlockSaplingHandler (E_BLOCK_SAPLING);
cBlockSeaLanternHandler BlockSeaLanternHandler (E_BLOCK_SEA_LANTERN); constexpr cBlockSeaLanternHandler BlockSeaLanternHandler (E_BLOCK_SEA_LANTERN);
cBlockSignPostHandler BlockSignPostHandler (E_BLOCK_SIGN_POST); constexpr cBlockSignPostHandler BlockSignPostHandler (E_BLOCK_SIGN_POST);
cBlockSlimeHandler BlockSlimeBlockHandler (E_BLOCK_SLIME_BLOCK); constexpr cBlockSlimeHandler BlockSlimeBlockHandler (E_BLOCK_SLIME_BLOCK);
cBlockHandler BlockSnowBlockHandler (E_BLOCK_SNOW_BLOCK); constexpr cBlockHandler BlockSnowBlockHandler (E_BLOCK_SNOW_BLOCK);
cBlockSnowHandler BlockSnowHandler (E_BLOCK_SNOW); constexpr cBlockSnowHandler BlockSnowHandler (E_BLOCK_SNOW);
cBlockHandler BlockSoulSandHandler (E_BLOCK_SOULSAND); constexpr cBlockHandler BlockSoulSandHandler (E_BLOCK_SOULSAND);
cBlockSpongeHandler BlockSpongeHandler (E_BLOCK_SPONGE); constexpr cBlockSpongeHandler BlockSpongeHandler (E_BLOCK_SPONGE);
cBlockDoorHandler BlockSpruceDoorHandler (E_BLOCK_SPRUCE_DOOR); constexpr cBlockDoorHandler BlockSpruceDoorHandler (E_BLOCK_SPRUCE_DOOR);
cBlockFenceGateHandler BlockSpruceFenceGateHandler (E_BLOCK_SPRUCE_FENCE_GATE); constexpr cBlockFenceGateHandler BlockSpruceFenceGateHandler (E_BLOCK_SPRUCE_FENCE_GATE);
cBlockFenceHandler BlockSpruceFenceHandler (E_BLOCK_SPRUCE_FENCE); constexpr cBlockFenceHandler BlockSpruceFenceHandler (E_BLOCK_SPRUCE_FENCE);
cBlockStairsHandler BlockSpruceWoodStairsHandler (E_BLOCK_SPRUCE_WOOD_STAIRS); constexpr cBlockStairsHandler BlockSpruceWoodStairsHandler (E_BLOCK_SPRUCE_WOOD_STAIRS);
cBlockHandler BlockStainedClayHandler (E_BLOCK_STAINED_CLAY); constexpr cBlockHandler BlockStainedClayHandler (E_BLOCK_STAINED_CLAY);
cBlockGlassHandler BlockStainedGlassHandler (E_BLOCK_STAINED_GLASS); constexpr cBlockGlassHandler BlockStainedGlassHandler (E_BLOCK_STAINED_GLASS);
cBlockGlassHandler BlockStainedGlassPaneHandler (E_BLOCK_STAINED_GLASS_PANE); constexpr cBlockGlassHandler BlockStainedGlassPaneHandler (E_BLOCK_STAINED_GLASS_PANE);
cBlockHandler BlockStandingBannerHandler (E_BLOCK_STANDING_BANNER); // TODO: drops correct? constexpr cBlockHandler BlockStandingBannerHandler (E_BLOCK_STANDING_BANNER); // TODO: drops correct?
cBlockLavaHandler BlockStationaryLavaHandler (E_BLOCK_STATIONARY_LAVA); constexpr cBlockLavaHandler BlockStationaryLavaHandler (E_BLOCK_STATIONARY_LAVA);
cBlockFluidHandler BlockStationaryWaterHandler (E_BLOCK_STATIONARY_WATER); constexpr cBlockFluidHandler BlockStationaryWaterHandler (E_BLOCK_STATIONARY_WATER);
cBlockPistonHandler BlockStickyPistonHandler (E_BLOCK_STICKY_PISTON); constexpr cBlockPistonHandler BlockStickyPistonHandler (E_BLOCK_STICKY_PISTON);
cBlockStairsHandler BlockStoneBrickStairsHandler (E_BLOCK_STONE_BRICK_STAIRS); constexpr cBlockStairsHandler BlockStoneBrickStairsHandler (E_BLOCK_STONE_BRICK_STAIRS);
cBlockHandler BlockStoneBricksHandler (E_BLOCK_STONE_BRICKS); constexpr cBlockHandler BlockStoneBricksHandler (E_BLOCK_STONE_BRICKS);
cBlockButtonHandler BlockStoneButtonHandler (E_BLOCK_STONE_BUTTON); constexpr cBlockButtonHandler BlockStoneButtonHandler (E_BLOCK_STONE_BUTTON);
cBlockStoneHandler BlockStoneHandler (E_BLOCK_STONE); constexpr cBlockStoneHandler BlockStoneHandler (E_BLOCK_STONE);
cBlockPressurePlateHandler BlockStonePressurePlateHandler (E_BLOCK_STONE_PRESSURE_PLATE); constexpr cBlockPressurePlateHandler BlockStonePressurePlateHandler (E_BLOCK_STONE_PRESSURE_PLATE);
cBlockSlabHandler BlockStoneSlabHandler (E_BLOCK_STONE_SLAB); constexpr cBlockSlabHandler BlockStoneSlabHandler (E_BLOCK_STONE_SLAB);
cBlockHandler BlockStructureBlockHandler (E_BLOCK_STRUCTURE_BLOCK); constexpr cBlockHandler BlockStructureBlockHandler (E_BLOCK_STRUCTURE_BLOCK);
cBlockHandler BlockStructureVoidHandler (E_BLOCK_STRUCTURE_VOID); constexpr cBlockHandler BlockStructureVoidHandler (E_BLOCK_STRUCTURE_VOID);
cBlockSugarcaneHandler BlockSugarcaneHandler (E_BLOCK_SUGARCANE); constexpr cBlockSugarcaneHandler BlockSugarcaneHandler (E_BLOCK_SUGARCANE);
cBlockTallGrassHandler BlockTallGrassHandler (E_BLOCK_TALL_GRASS); constexpr cBlockTallGrassHandler BlockTallGrassHandler (E_BLOCK_TALL_GRASS);
cBlockTNTHandler BlockTntHandler (E_BLOCK_TNT); constexpr cBlockTNTHandler BlockTntHandler (E_BLOCK_TNT);
cBlockTorchHandler BlockTorchHandler (E_BLOCK_TORCH); constexpr cBlockTorchHandler BlockTorchHandler (E_BLOCK_TORCH);
cBlockTrapdoorHandler BlockTrapdoorHandler (E_BLOCK_TRAPDOOR); constexpr cBlockTrapdoorHandler BlockTrapdoorHandler (E_BLOCK_TRAPDOOR);
cBlockChestHandler BlockTrappedChestHandler (E_BLOCK_TRAPPED_CHEST); constexpr cBlockChestHandler BlockTrappedChestHandler (E_BLOCK_TRAPPED_CHEST);
cBlockTripwireHandler BlockTripwireHandler (E_BLOCK_TRIPWIRE); constexpr cBlockTripwireHandler BlockTripwireHandler (E_BLOCK_TRIPWIRE);
cBlockTripwireHookHandler BlockTripwireHookHandler (E_BLOCK_TRIPWIRE_HOOK); constexpr cBlockTripwireHookHandler BlockTripwireHookHandler (E_BLOCK_TRIPWIRE_HOOK);
cBlockVineHandler BlockVinesHandler (E_BLOCK_VINES); constexpr cBlockVineHandler BlockVinesHandler (E_BLOCK_VINES);
cBlockHandler BlockWallBannerHandler (E_BLOCK_WALL_BANNER); // TODO: drops correct? constexpr cBlockHandler BlockWallBannerHandler (E_BLOCK_WALL_BANNER); // TODO: drops correct?
cBlockWallSignHandler BlockWallsignHandler (E_BLOCK_WALLSIGN); constexpr cBlockWallSignHandler BlockWallsignHandler (E_BLOCK_WALLSIGN);
cBlockFluidHandler BlockWaterHandler (E_BLOCK_WATER); constexpr cBlockFluidHandler BlockWaterHandler (E_BLOCK_WATER);
cBlockGlazedTerracottaHandler BlockWhiteGlazedTerracottaHandler (E_BLOCK_WHITE_GLAZED_TERRACOTTA); constexpr cBlockGlazedTerracottaHandler BlockWhiteGlazedTerracottaHandler (E_BLOCK_WHITE_GLAZED_TERRACOTTA);
cBlockHandler BlockWhiteShulkerBoxHandler (E_BLOCK_WHITE_SHULKER_BOX); constexpr cBlockHandler BlockWhiteShulkerBoxHandler (E_BLOCK_WHITE_SHULKER_BOX);
cBlockButtonHandler BlockWoodenButtonHandler (E_BLOCK_WOODEN_BUTTON); constexpr cBlockButtonHandler BlockWoodenButtonHandler (E_BLOCK_WOODEN_BUTTON);
cBlockPressurePlateHandler BlockWoodenPressurePlateHandler (E_BLOCK_WOODEN_PRESSURE_PLATE); constexpr cBlockPressurePlateHandler BlockWoodenPressurePlateHandler (E_BLOCK_WOODEN_PRESSURE_PLATE);
cBlockSlabHandler BlockWoodenSlabHandler (E_BLOCK_WOODEN_SLAB); constexpr cBlockSlabHandler BlockWoodenSlabHandler (E_BLOCK_WOODEN_SLAB);
cBlockClothHandler BlockWoolHandler (E_BLOCK_WOOL); constexpr cBlockClothHandler BlockWoolHandler (E_BLOCK_WOOL);
cBlockWorkbenchHandler BlockWorkbenchHandler (E_BLOCK_WORKBENCH); constexpr cBlockWorkbenchHandler BlockWorkbenchHandler (E_BLOCK_WORKBENCH);
cBlockFlowerHandler BlockYellowFlowerHandler (E_BLOCK_YELLOW_FLOWER); constexpr cBlockFlowerHandler BlockYellowFlowerHandler (E_BLOCK_YELLOW_FLOWER);
cBlockGlazedTerracottaHandler BlockYellowGlazedTerracottaHandler(E_BLOCK_YELLOW_GLAZED_TERRACOTTA); constexpr cBlockGlazedTerracottaHandler BlockYellowGlazedTerracottaHandler(E_BLOCK_YELLOW_GLAZED_TERRACOTTA);
cBlockHandler BlockYellowShulkerBoxHandler (E_BLOCK_YELLOW_SHULKER_BOX); constexpr cBlockHandler BlockYellowShulkerBoxHandler (E_BLOCK_YELLOW_SHULKER_BOX);
} }
@ -452,22 +454,13 @@ namespace
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// cBlockHandler: // cBlockHandler:
cBlockHandler::cBlockHandler(BLOCKTYPE a_BlockType)
{
m_BlockType = a_BlockType;
}
bool cBlockHandler::GetPlacementBlockTypeMeta( bool cBlockHandler::GetPlacementBlockTypeMeta(
cChunkInterface & a_ChunkInterface, cPlayer & a_Player, cChunkInterface & a_ChunkInterface, cPlayer & a_Player,
const Vector3i a_ClickedBlockPos, const Vector3i a_ClickedBlockPos,
eBlockFace a_ClickedBlockFace, eBlockFace a_ClickedBlockFace,
const Vector3i a_CursorPos, const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) ) const
{ {
// By default, all blocks can be placed and the meta is copied over from the item's damage value: // By default, all blocks can be placed and the meta is copied over from the item's damage value:
a_BlockType = m_BlockType; a_BlockType = m_BlockType;
@ -485,7 +478,7 @@ void cBlockHandler::OnUpdate(
cBlockPluginInterface & a_PluginInterface, cBlockPluginInterface & a_PluginInterface,
cChunk & a_Chunk, cChunk & a_Chunk,
const Vector3i a_RelPos const Vector3i a_RelPos
) ) const
{ {
} }
@ -493,7 +486,7 @@ void cBlockHandler::OnUpdate(
void cBlockHandler::OnNeighborChanged(cChunkInterface & a_ChunkInterface, Vector3i a_BlockPos, eBlockFace a_WhichNeighbor) void cBlockHandler::OnNeighborChanged(cChunkInterface & a_ChunkInterface, Vector3i a_BlockPos, eBlockFace a_WhichNeighbor) const
{ {
if (a_ChunkInterface.DoWithChunkAt(a_BlockPos, [&](cChunk & a_Chunk) { return CanBeAt(a_ChunkInterface, a_Chunk.AbsoluteToRelative(a_BlockPos), a_Chunk); })) if (a_ChunkInterface.DoWithChunkAt(a_BlockPos, [&](cChunk & a_Chunk) { return CanBeAt(a_ChunkInterface, a_Chunk.AbsoluteToRelative(a_BlockPos), a_Chunk); }))
{ {
@ -521,7 +514,7 @@ void cBlockHandler::NeighborChanged(cChunkInterface & a_ChunkInterface, Vector3i
return; return;
} }
cBlockInfo::GetHandler(a_ChunkInterface.GetBlock(a_NeighborPos))->OnNeighborChanged(a_ChunkInterface, a_NeighborPos, a_WhichNeighbor); cBlockHandler::For(a_ChunkInterface.GetBlock(a_NeighborPos)).OnNeighborChanged(a_ChunkInterface, a_NeighborPos, a_WhichNeighbor);
} }
@ -533,7 +526,7 @@ cItems cBlockHandler::ConvertToPickups(
cBlockEntity * a_BlockEntity, cBlockEntity * a_BlockEntity,
const cEntity * a_Digger, const cEntity * a_Digger,
const cItem * a_Tool const cItem * a_Tool
) ) const
{ {
UNUSED(a_BlockEntity); UNUSED(a_BlockEntity);
UNUSED(a_Digger); UNUSED(a_Digger);
@ -549,7 +542,7 @@ cItems cBlockHandler::ConvertToPickups(
bool cBlockHandler::CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) bool cBlockHandler::CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) const
{ {
return true; return true;
} }
@ -558,7 +551,7 @@ bool cBlockHandler::CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a
bool cBlockHandler::IsUseable() bool cBlockHandler::IsUseable() const
{ {
return false; return false;
} }
@ -567,7 +560,7 @@ bool cBlockHandler::IsUseable()
bool cBlockHandler::IsClickedThrough(void) bool cBlockHandler::IsClickedThrough(void) const
{ {
return false; return false;
} }
@ -576,7 +569,7 @@ bool cBlockHandler::IsClickedThrough(void)
bool cBlockHandler::DoesIgnoreBuildCollision(cChunkInterface & a_ChunkInterface, Vector3i a_Pos, cPlayer & a_Player, NIBBLETYPE a_Meta) bool cBlockHandler::DoesIgnoreBuildCollision(cChunkInterface & a_ChunkInterface, Vector3i a_Pos, cPlayer & a_Player, NIBBLETYPE a_Meta) const
{ {
return (m_BlockType == E_BLOCK_AIR); return (m_BlockType == E_BLOCK_AIR);
} }
@ -585,7 +578,7 @@ bool cBlockHandler::DoesIgnoreBuildCollision(cChunkInterface & a_ChunkInterface,
bool cBlockHandler::DoesDropOnUnsuitable(void) bool cBlockHandler::DoesDropOnUnsuitable(void) const
{ {
return true; return true;
} }
@ -594,7 +587,7 @@ bool cBlockHandler::DoesDropOnUnsuitable(void)
bool cBlockHandler::IsInsideBlock(const Vector3d a_RelPosition, const NIBBLETYPE a_BlockMeta) bool cBlockHandler::IsInsideBlock(const Vector3d a_RelPosition, const NIBBLETYPE a_BlockMeta) const
{ {
// Default functionality: Test the height, since we assume full voxels with varying height // Default functionality: Test the height, since we assume full voxels with varying height
return (a_RelPosition.y < cBlockInfo::GetBlockHeight(m_BlockType)); return (a_RelPosition.y < cBlockInfo::GetBlockHeight(m_BlockType));
@ -604,7 +597,7 @@ bool cBlockHandler::IsInsideBlock(const Vector3d a_RelPosition, const NIBBLETYPE
cBoundingBox cBlockHandler::GetPlacementCollisionBox(BLOCKTYPE a_XM, BLOCKTYPE a_XP, BLOCKTYPE a_YM, BLOCKTYPE a_YP, BLOCKTYPE a_ZM, BLOCKTYPE a_ZP) cBoundingBox cBlockHandler::GetPlacementCollisionBox(BLOCKTYPE a_XM, BLOCKTYPE a_XP, BLOCKTYPE a_YM, BLOCKTYPE a_YP, BLOCKTYPE a_ZM, BLOCKTYPE a_ZP) const
{ {
if (!cBlockInfo::IsSolid(m_BlockType)) if (!cBlockInfo::IsSolid(m_BlockType))
{ {
@ -622,7 +615,7 @@ void cBlockHandler::Check(
cChunkInterface & a_ChunkInterface, cBlockPluginInterface & a_PluginInterface, cChunkInterface & a_ChunkInterface, cBlockPluginInterface & a_PluginInterface,
Vector3i a_RelPos, Vector3i a_RelPos,
cChunk & a_Chunk cChunk & a_Chunk
) ) const
{ {
const auto Position = cChunkDef::RelativeToAbsolute(a_RelPos, a_Chunk.GetPos()); const auto Position = cChunkDef::RelativeToAbsolute(a_RelPos, a_Chunk.GetPos());
NeighborChanged(a_ChunkInterface, Position.addedX(-1), BLOCK_FACE_XP); NeighborChanged(a_ChunkInterface, Position.addedX(-1), BLOCK_FACE_XP);
@ -637,7 +630,7 @@ void cBlockHandler::Check(
ColourID cBlockHandler::GetMapBaseColourID(NIBBLETYPE a_Meta) ColourID cBlockHandler::GetMapBaseColourID(NIBBLETYPE a_Meta) const
{ {
// Zero for transparent // Zero for transparent
return 0; return 0;
@ -656,7 +649,7 @@ bool cBlockHandler::ToolHasSilkTouch(const cItem * a_Tool)
cBlockHandler & cBlockHandler::GetBlockHandler(BLOCKTYPE a_BlockType) const cBlockHandler & cBlockHandler::For(BLOCKTYPE a_BlockType)
{ {
// Switch on the block type, as an enumeration // Switch on the block type, as an enumeration
// Clang will fail if any type is unhandled: // Clang will fail if any type is unhandled:

View File

@ -25,9 +25,11 @@ class BlockTypeRegistry;
class cBlockHandler class cBlockHandler
{ {
public: public:
cBlockHandler(BLOCKTYPE a_BlockType);
virtual ~cBlockHandler() {} constexpr cBlockHandler(BLOCKTYPE a_BlockType) :
m_BlockType(a_BlockType)
{
}
/** Called when the block gets ticked either by a random tick or by a queued tick. /** Called when the block gets ticked either by a random tick or by a queued tick.
Note that the coords in a_RelPos are chunk-relative! */ Note that the coords in a_RelPos are chunk-relative! */
@ -37,12 +39,12 @@ public:
cBlockPluginInterface & a_BlockPluginInterface, cBlockPluginInterface & a_BlockPluginInterface,
cChunk & a_Chunk, cChunk & a_Chunk,
const Vector3i a_RelPos const Vector3i a_RelPos
); ) const;
/** Returns the relative bounding box that must be entity-free in /** 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 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. */ 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); virtual cBoundingBox GetPlacementCollisionBox(BLOCKTYPE a_XM, BLOCKTYPE a_XP, BLOCKTYPE a_YM, BLOCKTYPE a_YP, BLOCKTYPE a_ZM, BLOCKTYPE a_ZP) const;
/** Called before a block is placed into a world by player, by cItemHandler::GetPlacementBlockTypeMeta(). /** Called before a block is placed into a world by player, by cItemHandler::GetPlacementBlockTypeMeta().
The handler should return true to allow placement, false to refuse. The handler should return true to allow placement, false to refuse.
@ -58,19 +60,19 @@ public:
eBlockFace a_ClickedBlockFace, eBlockFace a_ClickedBlockFace,
const Vector3i a_CursorPos, const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
); ) const;
/** Called by cWorld::SetBlock() after the block has been set */ /** Called by cWorld::SetBlock() after the block has been set */
virtual void OnPlaced( virtual void OnPlaced(
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
Vector3i a_BlockPos, Vector3i a_BlockPos,
BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta
) {}; ) const {};
/** Called by cPlayer::PlaceBlocks() for each block after it has been set to the world. Called after OnPlaced(). */ /** Called by cPlayer::PlaceBlocks() for each block after it has been set to the world. Called after OnPlaced(). */
virtual void OnPlacedByPlayer( virtual void OnPlacedByPlayer(
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, const sSetBlock & a_BlockChange cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, const sSetBlock & a_BlockChange
) {}; ) const {};
/** Called just after the player breaks the block. /** Called just after the player breaks the block.
The block is already dug up in the world, the original block type and meta is passed in a_OldBlockType and a_OldBlockMeta. The block is already dug up in the world, the original block type and meta is passed in a_OldBlockType and a_OldBlockMeta.
@ -80,7 +82,7 @@ public:
cPlayer & a_Player, cPlayer & a_Player,
Vector3i a_BlockPos, Vector3i a_BlockPos,
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta
) {} ) const {}
/** Called after a block gets broken (replaced with air), either by player or by natural means. /** Called after a block gets broken (replaced with air), either by player or by natural means.
If by player, it is called before the OnPlayerBrokeBlock() callback. If by player, it is called before the OnPlayerBrokeBlock() callback.
@ -90,13 +92,13 @@ public:
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
Vector3i a_BlockPos, Vector3i a_BlockPos,
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta
) {}; ) const {};
/** Called when a direct neighbor of this block has been changed. /** Called when a direct neighbor of this block has been changed.
The position is the block's own position, NOT the changed neighbor's position. The position is the block's own position, NOT the changed neighbor's position.
a_WhichNeighbor indicates which neighbor has changed. For example, BLOCK_FACE_YP meant the neighbor above has changed. a_WhichNeighbor indicates which neighbor has changed. For example, BLOCK_FACE_YP meant the neighbor above has changed.
BLOCK_FACE_NONE means that it is a neighbor not directly adjacent (diagonal, etc.) */ BLOCK_FACE_NONE means that it is a neighbor not directly adjacent (diagonal, etc.) */
virtual void OnNeighborChanged(cChunkInterface & a_ChunkInterface, Vector3i a_BlockPos, eBlockFace a_WhichNeighbor); virtual void OnNeighborChanged(cChunkInterface & a_ChunkInterface, Vector3i a_BlockPos, eBlockFace a_WhichNeighbor) const;
/** Notifies the specified neighbor that the current block has changed. /** Notifies the specified neighbor that the current block has changed.
a_NeighborPos are the coords of the neighbor to be notified a_NeighborPos are the coords of the neighbor to be notified
@ -111,7 +113,7 @@ public:
cWorldInterface & a_WorldInterface, cWorldInterface & a_WorldInterface,
cPlayer & a_Player, cPlayer & a_Player,
const Vector3i a_BlockPos const Vector3i a_BlockPos
) ) const
{ {
} }
@ -125,7 +127,7 @@ public:
const Vector3i a_BlockPos, const Vector3i a_BlockPos,
eBlockFace a_BlockFace, eBlockFace a_BlockFace,
const Vector3i a_CursorPos const Vector3i a_CursorPos
) ) const
{ {
return false; return false;
} }
@ -138,7 +140,7 @@ public:
cPlayer & a_Player, cPlayer & a_Player,
const Vector3i a_BlockPos, const Vector3i a_BlockPos,
eBlockFace a_BlockFace eBlockFace a_BlockFace
) ) const
{ {
} }
@ -153,40 +155,40 @@ public:
cBlockEntity * a_BlockEntity, cBlockEntity * a_BlockEntity,
const cEntity * a_Digger = nullptr, const cEntity * a_Digger = nullptr,
const cItem * a_Tool = nullptr const cItem * a_Tool = nullptr
); ) const;
/** Checks if the block can stay at the specified relative coords in the chunk */ /** Checks if the block can stay at the specified relative coords in the chunk */
virtual bool CanBeAt( virtual bool CanBeAt(
cChunkInterface & a_ChunkInterface, cChunkInterface & a_ChunkInterface,
const Vector3i a_RelPos, const Vector3i a_RelPos,
const cChunk & a_Chunk const cChunk & a_Chunk
); ) const;
/** Checks whether the block has an effect on growing the plant */ /** Checks whether the block has an effect on growing the plant */
virtual bool CanSustainPlant(BLOCKTYPE a_Plant) { return false; } virtual bool CanSustainPlant(BLOCKTYPE a_Plant) const { return false; }
/** Called to check whether this block supports a rclk action. /** Called to check whether this block supports a rclk action.
If it returns true, OnUse() is called */ If it returns true, OnUse() is called */
virtual bool IsUseable(void); virtual bool IsUseable(void) const;
/** Indicates whether the client will click through this block. /** Indicates whether the client will click through this block.
For example digging a fire will hit the block below the fire so fire is clicked through. */ For example digging a fire will hit the block below the fire so fire is clicked through. */
virtual bool IsClickedThrough(void); virtual bool IsClickedThrough(void) const;
/** Checks if the player can build "inside" this block. /** Checks if the player can build "inside" this block.
For example blocks placed "on" snow will be placed at the same position. So: Snow ignores Build collision For example blocks placed "on" snow will be placed at the same position. So: Snow ignores Build collision
@param a_Pos Position of the block @param a_Pos Position of the block
@param a_Player Player trying to build on the block @param a_Player Player trying to build on the block
@param a_Meta Meta value of the block currently at a_Pos */ @param a_Meta Meta value of the block currently at a_Pos */
virtual bool DoesIgnoreBuildCollision(cChunkInterface & ChunkInterface, const Vector3i a_Pos, cPlayer & a_Player, NIBBLETYPE a_Meta); virtual bool DoesIgnoreBuildCollision(cChunkInterface & ChunkInterface, const Vector3i a_Pos, cPlayer & a_Player, NIBBLETYPE a_Meta) const;
/** Returns if this block drops if it gets destroyed by an unsuitable situation. /** Returns if this block drops if it gets destroyed by an unsuitable situation.
Default: true */ Default: true */
virtual bool DoesDropOnUnsuitable(void); virtual bool DoesDropOnUnsuitable(void) const;
/** Tests if a_RelPosition is inside the block, where a_RelPosition is relative to the origin of the block. /** Tests if a_RelPosition is inside the block, where a_RelPosition is relative to the origin of the block.
Coords in a_RelPosition are guaranteed to be in the [0..1] range. */ Coords in a_RelPosition are guaranteed to be in the [0..1] range. */
virtual bool IsInsideBlock(const Vector3d a_RelPosition, const NIBBLETYPE a_BlockMeta); virtual bool IsInsideBlock(const Vector3d a_RelPosition, const NIBBLETYPE a_BlockMeta) const;
/** Called when one of the neighbors gets set; equivalent to MC block update. /** Called when one of the neighbors gets set; equivalent to MC block update.
By default drops (DropBlockAsPickup() / SetBlock()) if the position is no longer suitable (CanBeAt(), DoesDropOnUnsuitable()), By default drops (DropBlockAsPickup() / SetBlock()) if the position is no longer suitable (CanBeAt(), DoesDropOnUnsuitable()),
@ -195,47 +197,45 @@ public:
cChunkInterface & ChunkInterface, cBlockPluginInterface & a_PluginInterface, cChunkInterface & ChunkInterface, cBlockPluginInterface & a_PluginInterface,
Vector3i a_RelPos, Vector3i a_RelPos,
cChunk & a_Chunk cChunk & a_Chunk
); ) const;
/** Returns the base colour ID of the block, as will be represented on a map, as per documentation: https://minecraft.gamepedia.com/Map_item_format */ /** Returns the base colour ID of the block, as will be represented on a map, as per documentation: https://minecraft.gamepedia.com/Map_item_format */
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta); virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const;
/** Rotates a given block meta counter-clockwise. Default: no change /** Rotates a given block meta counter-clockwise. Default: no change
Returns block meta following rotation */ Returns block meta following rotation */
virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) { return a_Meta; } virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) const { return a_Meta; }
/** Rotates a given block meta clockwise. Default: no change /** Rotates a given block meta clockwise. Default: no change
Returns block meta following rotation */ Returns block meta following rotation */
virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) { return a_Meta; } virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) const { return a_Meta; }
/** Mirrors a given block meta around the XY plane. Default: no change /** Mirrors a given block meta around the XY plane. Default: no change
Returns block meta following rotation */ Returns block meta following rotation */
virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) { return a_Meta; } virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) const { return a_Meta; }
/** Mirros a given block meta around the XZ plane. Default: no change /** Mirros a given block meta around the XZ plane. Default: no change
Returns block meta following rotation */ Returns block meta following rotation */
virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) { return a_Meta; } virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) const { return a_Meta; }
/** Mirros a given block meta around the YZ plane. Default: no change /** Mirros a given block meta around the YZ plane. Default: no change
Returns block meta following rotation */ Returns block meta following rotation */
virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) { return a_Meta; } virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) const { return a_Meta; }
/** Grows this block, if it supports growing, by the specified amount of stages (at most). /** Grows this block, if it supports growing, by the specified amount of stages (at most).
Returns the number of stages actually grown, zero if not supported (default). */ Returns the number of stages actually grown, zero if not supported (default). */
virtual int Grow(cChunk & a_Chunk, Vector3i a_RelPos, int a_NumStages = 1) { return 0; } virtual int Grow(cChunk & a_Chunk, Vector3i a_RelPos, int a_NumStages = 1) const { return 0; }
/** Returns true if the specified tool is valid and has a non-zero silk-touch enchantment. /** Returns true if the specified tool is valid and has a non-zero silk-touch enchantment.
Helper used in many ConvertToPickups() implementations. */ Helper used in many ConvertToPickups() implementations. */
static bool ToolHasSilkTouch(const cItem * a_Tool); static bool ToolHasSilkTouch(const cItem * a_Tool);
// Gets the blockhandler for the given block type. // Gets the blockhandler for the given block type.
static cBlockHandler & GetBlockHandler(BLOCKTYPE a_BlockType); static const cBlockHandler & For(BLOCKTYPE a_BlockType);
protected: protected:
BLOCKTYPE m_BlockType; BLOCKTYPE m_BlockType;
friend class cBlockInfo;
}; };

View File

@ -14,14 +14,9 @@ class cBlockHopperHandler :
public: public:
cBlockHopperHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual bool GetPlacementBlockTypeMeta( virtual bool GetPlacementBlockTypeMeta(
cChunkInterface & a_ChunkInterface, cChunkInterface & a_ChunkInterface,
@ -30,7 +25,7 @@ public:
eBlockFace a_ClickedBlockFace, eBlockFace a_ClickedBlockFace,
const Vector3i a_CursorPos, const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override ) const override
{ {
a_BlockType = m_BlockType; a_BlockType = m_BlockType;
@ -52,7 +47,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 11; return 11;

View File

@ -14,12 +14,11 @@ class cBlockIceHandler :
public: public:
cBlockIceHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override private:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
{ {
// Only drop self when using silk-touch: // Only drop self when using silk-touch:
if (ToolHasSilkTouch(a_Tool)) if (ToolHasSilkTouch(a_Tool))
@ -36,7 +35,7 @@ public:
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
Vector3i a_BlockPos, Vector3i a_BlockPos,
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta
) override ) const override
{ {
// If there's a solid block or a liquid underneath, convert to water, rather than air // If there's a solid block or a liquid underneath, convert to water, rather than air
if (a_BlockPos.y <= 0) if (a_BlockPos.y <= 0)
@ -51,7 +50,7 @@ public:
} }
} }
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 5; return 5;

View File

@ -11,26 +11,15 @@
class cBlockJukeboxHandler : class cBlockJukeboxHandler :
public cClearMetaOnDrop<cBlockEntityHandler> public cClearMetaOnDrop<cBlockEntityHandler>
{ {
using super = cClearMetaOnDrop<cBlockEntityHandler>;
public: public:
cBlockJukeboxHandler(BLOCKTYPE a_BlockType): using cClearMetaOnDrop<cBlockEntityHandler>::cClearMetaOnDrop;
super(a_BlockType)
{
}
private:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 6; return 6;
} }
} ; } ;

View File

@ -15,14 +15,9 @@ class cBlockLadderHandler:
public: public:
cBlockLadderHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual bool GetPlacementBlockTypeMeta( virtual bool GetPlacementBlockTypeMeta(
cChunkInterface & a_ChunkInterface, cChunkInterface & a_ChunkInterface,
@ -31,7 +26,7 @@ public:
eBlockFace a_ClickedBlockFace, eBlockFace a_ClickedBlockFace,
const Vector3i a_CursorPos, const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override ) const override
{ {
// Try finding a suitable neighbor block face for the ladder; start with the given one. // Try finding a suitable neighbor block face for the ladder; start with the given one.
if (!LadderCanBePlacedAt(a_ChunkInterface, a_PlacedBlockPos, a_ClickedBlockFace)) if (!LadderCanBePlacedAt(a_ChunkInterface, a_PlacedBlockPos, a_ClickedBlockFace))
@ -132,7 +127,7 @@ public:
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) const override
{ {
auto NeighborBlockFace = MetaDataToBlockFace(a_Chunk.GetMeta(a_RelPos)); auto NeighborBlockFace = MetaDataToBlockFace(a_Chunk.GetMeta(a_RelPos));
auto LadderAbsPos = a_Chunk.RelativeToAbsolute(a_RelPos); auto LadderAbsPos = a_Chunk.RelativeToAbsolute(a_RelPos);
@ -143,7 +138,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 0; return 0;

View File

@ -19,6 +19,12 @@ class cBlockLeavesHandler:
{ {
using Super = cBlockHandler; using Super = cBlockHandler;
public:
using Super::Super;
private:
/** Returns true if the area contains a continous path from the specified block to a log block entirely made out of leaves blocks. */ /** Returns true if the area contains a continous path from the specified block to a log block entirely made out of leaves blocks. */
static bool HasNearLog(cBlockArea & a_Area, const Vector3i a_BlockPos) static bool HasNearLog(cBlockArea & a_Area, const Vector3i a_BlockPos)
{ {
@ -87,19 +93,7 @@ class cBlockLeavesHandler:
return false; return false;
} }
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
public:
cBlockLeavesHandler(BLOCKTYPE a_BlockType):
Super(a_BlockType)
{
}
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{ {
// If breaking with shears, drop self: // If breaking with shears, drop self:
if ((a_Tool != nullptr) && (a_Tool->m_ItemType == E_ITEM_SHEARS)) if ((a_Tool != nullptr) && (a_Tool->m_ItemType == E_ITEM_SHEARS))
@ -148,7 +142,7 @@ public:
virtual void OnNeighborChanged(cChunkInterface & a_ChunkInterface, Vector3i a_BlockPos, eBlockFace a_WhichNeighbor) override virtual void OnNeighborChanged(cChunkInterface & a_ChunkInterface, Vector3i a_BlockPos, eBlockFace a_WhichNeighbor) const override
{ {
auto meta = a_ChunkInterface.GetBlockMeta(a_BlockPos); auto meta = a_ChunkInterface.GetBlockMeta(a_BlockPos);
@ -169,7 +163,7 @@ public:
cBlockPluginInterface & a_PluginInterface, cBlockPluginInterface & a_PluginInterface,
cChunk & a_Chunk, cChunk & a_Chunk,
const Vector3i a_RelPos const Vector3i a_RelPos
) override ) const override
{ {
auto Meta = a_Chunk.GetMeta(a_RelPos); auto Meta = a_Chunk.GetMeta(a_RelPos);
if ((Meta & 0x04) != 0) if ((Meta & 0x04) != 0)
@ -213,7 +207,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 7; return 7;

View File

@ -13,14 +13,15 @@ class cBlockLeverHandler:
public: public:
cBlockLeverHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
/** Extracts the ON bit from metadata and returns if true if it is set */
static bool IsLeverOn(NIBBLETYPE a_BlockMeta)
{ {
return ((a_BlockMeta & 0x8) == 0x8);
} }
private:
virtual bool OnUse( virtual bool OnUse(
cChunkInterface & a_ChunkInterface, cChunkInterface & a_ChunkInterface,
@ -29,7 +30,7 @@ public:
const Vector3i a_BlockPos, const Vector3i a_BlockPos,
eBlockFace a_BlockFace, eBlockFace a_BlockFace,
const Vector3i a_CursorPos const Vector3i a_CursorPos
) override ) const override
{ {
// Flip the ON bit on / off using the XOR bitwise operation // Flip the ON bit on / off using the XOR bitwise operation
NIBBLETYPE Meta = (a_ChunkInterface.GetBlockMeta(a_BlockPos) ^ 0x08); NIBBLETYPE Meta = (a_ChunkInterface.GetBlockMeta(a_BlockPos) ^ 0x08);
@ -44,7 +45,7 @@ public:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
{ {
// Reset meta to zero: // Reset meta to zero:
return cItem(E_BLOCK_LEVER, 1, 0); return cItem(E_BLOCK_LEVER, 1, 0);
@ -54,7 +55,7 @@ public:
virtual bool IsUseable(void) override virtual bool IsUseable(void) const override
{ {
return true; return true;
} }
@ -70,7 +71,7 @@ public:
eBlockFace a_ClickedBlockFace, eBlockFace a_ClickedBlockFace,
const Vector3i a_CursorPos, const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override ) const override
{ {
a_BlockType = m_BlockType; a_BlockType = m_BlockType;
a_BlockMeta = LeverDirectionToMetaData(a_ClickedBlockFace); a_BlockMeta = LeverDirectionToMetaData(a_ClickedBlockFace);
@ -127,7 +128,7 @@ public:
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) const override
{ {
// Find the type of block the lever is attached to: // Find the type of block the lever is attached to:
auto Meta = a_Chunk.GetMeta(a_RelPos); auto Meta = a_Chunk.GetMeta(a_RelPos);
@ -163,7 +164,7 @@ public:
virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) const override
{ {
switch (a_Meta) switch (a_Meta)
{ {
@ -181,7 +182,7 @@ public:
virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) const override
{ {
switch (a_Meta) switch (a_Meta)
{ {
@ -199,21 +200,11 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 0; return 0;
} }
/** Extracts the ON bit from metadata and returns if true if it is set */
static bool IsLeverOn(NIBBLETYPE a_BlockMeta)
{
return ((a_BlockMeta & 0x8) == 0x8);
}
} ; } ;

View File

@ -14,16 +14,11 @@ class cBlockLilypadHandler:
public: public:
cBlockLilypadHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 7; return 7;
@ -33,7 +28,7 @@ public:
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) const override
{ {
auto UnderPos = a_RelPos.addedY(-1); auto UnderPos = a_RelPos.addedY(-1);
if (!cChunkDef::IsValidHeight(UnderPos.y)) if (!cChunkDef::IsValidHeight(UnderPos.y))

View File

@ -14,16 +14,11 @@ class cBlockMelonHandler :
public: public:
cBlockMelonHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{ {
return cItem(E_ITEM_MELON_SLICE, GetRandomProvider().RandInt<char>(3, 7), 0); return cItem(E_ITEM_MELON_SLICE, GetRandomProvider().RandInt<char>(3, 7), 0);
} }
@ -32,7 +27,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 19; return 19;

View File

@ -14,16 +14,12 @@ class cBlockMobHeadHandler :
using Super = cBlockEntityHandler; using Super = cBlockEntityHandler;
public: public:
cBlockMobHeadHandler(BLOCKTYPE a_BlockType):
Super(a_BlockType)
{
}
using Super::Super;
private:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{ {
if ((a_BlockEntity == nullptr) || (a_BlockEntity->GetBlockType() != E_BLOCK_HEAD)) if ((a_BlockEntity == nullptr) || (a_BlockEntity->GetBlockType() != E_BLOCK_HEAD))
{ {
@ -37,7 +33,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 0; return 0;

View File

@ -15,14 +15,9 @@ class cBlockMobSpawnerHandler:
public: public:
cBlockMobSpawnerHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual bool OnUse( virtual bool OnUse(
cChunkInterface & a_ChunkInterface, cChunkInterface & a_ChunkInterface,
@ -31,7 +26,7 @@ public:
const Vector3i a_BlockPos, const Vector3i a_BlockPos,
eBlockFace a_BlockFace, eBlockFace a_BlockFace,
const Vector3i a_CursorPos const Vector3i a_CursorPos
) override ) const override
{ {
return a_ChunkInterface.UseBlockEntity(&a_Player, a_BlockPos.x, a_BlockPos.y, a_BlockPos.z); return a_ChunkInterface.UseBlockEntity(&a_Player, a_BlockPos.x, a_BlockPos.y, a_BlockPos.z);
} }
@ -40,7 +35,7 @@ public:
virtual bool IsUseable() override virtual bool IsUseable() const override
{ {
return true; return true;
} }
@ -49,7 +44,7 @@ public:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
{ {
// No pickups // No pickups
return {}; return {};
@ -64,7 +59,7 @@ public:
cPlayer & a_Player, cPlayer & a_Player,
Vector3i a_BlockPos, Vector3i a_BlockPos,
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta
) override ) const override
{ {
auto handler = a_Player.GetEquippedItem().GetHandler(); auto handler = a_Player.GetEquippedItem().GetHandler();
if (!a_Player.IsGameModeSurvival() || !handler->CanHarvestBlock(E_BLOCK_MOB_SPAWNER)) if (!a_Player.IsGameModeSurvival() || !handler->CanHarvestBlock(E_BLOCK_MOB_SPAWNER))

View File

@ -15,22 +15,13 @@ class cBlockMushroomHandler:
public: public:
cBlockMushroomHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
// TODO: Add Mushroom Spread // TODO: Add Mushroom Spread
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) const override
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override
{ {
if (a_RelPos.y <= 0) if (a_RelPos.y <= 0)
{ {
@ -58,7 +49,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 0; return 0;

View File

@ -11,18 +11,14 @@ class cBlockMyceliumHandler:
public cBlockHandler public cBlockHandler
{ {
public: public:
cBlockMyceliumHandler(BLOCKTYPE a_BlockType):
cBlockHandler(a_BlockType) using cBlockHandler::cBlockHandler;
{
} private:
// TODO: Add Mycel Spread // TODO: Add Mycel Spread
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{ {
return cItem(E_BLOCK_DIRT, 1, 0); return cItem(E_BLOCK_DIRT, 1, 0);
} }
@ -31,7 +27,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 24; return 24;

View File

@ -15,16 +15,11 @@ class cBlockNetherWartHandler:
public: public:
cBlockNetherWartHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{ {
if (a_BlockMeta == 0x03) if (a_BlockMeta == 0x03)
{ {
@ -42,7 +37,7 @@ public:
virtual int Grow(cChunk & a_Chunk, Vector3i a_RelPos, int a_NumStages = 1) override virtual int Grow(cChunk & a_Chunk, Vector3i a_RelPos, int a_NumStages = 1) const override
{ {
auto oldMeta = a_Chunk.GetMeta(a_RelPos); auto oldMeta = a_Chunk.GetMeta(a_RelPos);
auto meta = std::min(oldMeta + a_NumStages, 3); auto meta = std::min(oldMeta + a_NumStages, 3);
@ -64,7 +59,7 @@ public:
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) const override
{ {
// Needs to be placed on top of a Soulsand block: // Needs to be placed on top of a Soulsand block:
return ((a_RelPos.y > 0) && (a_Chunk.GetBlock(a_RelPos.addedY(-1)) == E_BLOCK_SOULSAND)); return ((a_RelPos.y > 0) && (a_Chunk.GetBlock(a_RelPos.addedY(-1)) == E_BLOCK_SOULSAND));
@ -74,7 +69,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 35; return 35;

View File

@ -1,12 +1,22 @@
#pragma once #pragma once
#include "BlockHandler.h" #include "BlockHandler.h"
class cBlockNetherrack : public cBlockHandler class cBlockNetherrack : public cBlockHandler
{ {
public: public:
cBlockNetherrack(BLOCKTYPE a_Type) : cBlockHandler(a_Type){}
virtual bool CanSustainPlant(BLOCKTYPE a_Plant) override { return (a_Plant == E_BLOCK_NETHER_WART); } using cBlockHandler::cBlockHandler;
private:
virtual bool CanSustainPlant(BLOCKTYPE a_Plant) const override
{
return a_Plant == E_BLOCK_NETHER_WART;
}
}; };

View File

@ -12,9 +12,7 @@ class cBlockObserverHandler:
public: public:
cBlockObserverHandler(BLOCKTYPE a_BlockType) : Super(a_BlockType) using Super::Super;
{
}
inline static Vector3i GetObservingFaceOffset(NIBBLETYPE a_Meta) inline static Vector3i GetObservingFaceOffset(NIBBLETYPE a_Meta)
{ {

View File

@ -13,16 +13,12 @@ class cBlockOreHandler:
using Super = cBlockHandler; using Super = cBlockHandler;
public: public:
cBlockOreHandler(BLOCKTYPE a_BlockType):
Super(a_BlockType)
{
}
using Super::Super;
private:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{ {
// If using silk-touch, drop self rather than the resource: // If using silk-touch, drop self rather than the resource:
if (ToolHasSilkTouch(a_Tool)) if (ToolHasSilkTouch(a_Tool))
@ -62,7 +58,7 @@ public:
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
cPlayer & a_Player, Vector3i a_BlockPos, cPlayer & a_Player, Vector3i a_BlockPos,
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta
) override ) const override
{ {
if (!a_Player.IsGameModeSurvival()) if (!a_Player.IsGameModeSurvival())
{ {

View File

@ -17,40 +17,6 @@
cBlockPistonHandler::cBlockPistonHandler(BLOCKTYPE a_BlockType):
Super(a_BlockType)
{
}
void cBlockPistonHandler::OnBroken(
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
Vector3i a_BlockPos,
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta
)
{
if (!IsExtended(a_OldBlockMeta))
{
return;
}
const auto Extension = a_BlockPos + MetadataToOffset(a_OldBlockMeta);
if (
cChunkDef::IsValidHeight(Extension.y) &&
(a_ChunkInterface.GetBlock(Extension) == E_BLOCK_PISTON_EXTENSION)
)
{
// If the piston is extended, destroy the extension as well:
a_ChunkInterface.SetBlock(Extension, E_BLOCK_AIR, 0);
}
}
Vector3i cBlockPistonHandler::MetadataToOffset(NIBBLETYPE a_PistonMeta) Vector3i cBlockPistonHandler::MetadataToOffset(NIBBLETYPE a_PistonMeta)
{ {
@ -75,118 +41,6 @@ Vector3i cBlockPistonHandler::MetadataToOffset(NIBBLETYPE a_PistonMeta)
void cBlockPistonHandler::PushBlocks(
const Vector3iSet & a_BlocksToPush,
cWorld & a_World, const Vector3i & a_PushDir
)
{
// Sort blocks to move the blocks first, which are farthest away from the piston
// This prevents the overwriting of existing blocks
std::vector<Vector3i> sortedBlocks(a_BlocksToPush.begin(), a_BlocksToPush.end());
std::sort(sortedBlocks.begin(), sortedBlocks.end(), [a_PushDir](const Vector3i & a, const Vector3i & b)
{
return (a.Dot(a_PushDir) > b.Dot(a_PushDir));
});
// Move every block
BLOCKTYPE moveBlock;
NIBBLETYPE moveMeta;
for (auto & moveBlockPos : sortedBlocks)
{
a_World.GetBlockTypeMeta(moveBlockPos.x, moveBlockPos.y, moveBlockPos.z, moveBlock, moveMeta);
if (cBlockInfo::IsPistonBreakable(moveBlock))
{
// Block is breakable, drop it:
a_World.DropBlockAsPickups(moveBlockPos, nullptr, nullptr);
}
else
{
// Not breakable, just move it
a_World.SetBlock(moveBlockPos.x, moveBlockPos.y, moveBlockPos.z, E_BLOCK_AIR, 0);
moveBlockPos += a_PushDir;
a_World.SetBlock(moveBlockPos.x, moveBlockPos.y, moveBlockPos.z, moveBlock, moveMeta);
}
}
}
bool cBlockPistonHandler::CanPushBlock(
const Vector3i & a_BlockPos, cWorld & a_World, bool a_RequirePushable,
Vector3iSet & a_BlocksPushed, const Vector3i & a_PushDir
)
{
const static std::array<Vector3i, 6> pushingDirs =
{
{
Vector3i(-1, 0, 0), Vector3i(1, 0, 0),
Vector3i( 0, -1, 0), Vector3i(0, 1, 0),
Vector3i( 0, 0, -1), Vector3i(0, 0, 1)
}
};
BLOCKTYPE currBlock;
NIBBLETYPE currMeta;
a_World.GetBlockTypeMeta(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, currBlock, currMeta);
if (!cChunkDef::IsValidHeight(a_BlockPos.y))
{
return !a_RequirePushable;
}
if (currBlock == E_BLOCK_AIR)
{
// Air can be pushed
return true;
}
if (!a_RequirePushable && cBlockInfo::IsPistonBreakable(currBlock))
{
// Block should not be broken, when it's not in the pushing direction
return true;
}
if (!CanPush(currBlock, currMeta))
{
// When it's not required to push this block, don't fail
return !a_RequirePushable;
}
if (a_BlocksPushed.size() >= PISTON_MAX_PUSH_DISTANCE)
{
// Do not allow to push too much blocks
return false;
}
if (!a_BlocksPushed.insert(a_BlockPos).second || cBlockInfo::IsPistonBreakable(currBlock))
{
return true; // Element exist already
}
if (currBlock == E_BLOCK_SLIME_BLOCK)
{
// Try to push the other directions
for (const auto & testDir : pushingDirs)
{
if (!CanPushBlock(a_BlockPos + testDir, a_World, false, a_BlocksPushed, a_PushDir))
{
// When it's not possible for a direction, then fail
return false;
}
}
}
// Try to push the block in front of this block
return CanPushBlock(a_BlockPos + a_PushDir, a_World, true, a_BlocksPushed, a_PushDir);
}
void cBlockPistonHandler::ExtendPiston(Vector3i a_BlockPos, cWorld & a_World) void cBlockPistonHandler::ExtendPiston(Vector3i a_BlockPos, cWorld & a_World)
{ {
{ {
@ -320,23 +174,152 @@ void cBlockPistonHandler::RetractPiston(Vector3i a_BlockPos, cWorld & a_World)
//////////////////////////////////////////////////////////////////////////////// void cBlockPistonHandler::PushBlocks(
// cBlockPistonHeadHandler: const Vector3iSet & a_BlocksToPush,
cWorld & a_World, const Vector3i & a_PushDir
cBlockPistonHeadHandler::cBlockPistonHeadHandler(void) : )
Super(E_BLOCK_PISTON_EXTENSION)
{ {
// Sort blocks to move the blocks first, which are farthest away from the piston
// This prevents the overwriting of existing blocks
std::vector<Vector3i> sortedBlocks(a_BlocksToPush.begin(), a_BlocksToPush.end());
std::sort(sortedBlocks.begin(), sortedBlocks.end(), [a_PushDir](const Vector3i & a, const Vector3i & b)
{
return (a.Dot(a_PushDir) > b.Dot(a_PushDir));
});
// Move every block
BLOCKTYPE moveBlock;
NIBBLETYPE moveMeta;
for (auto & moveBlockPos : sortedBlocks)
{
a_World.GetBlockTypeMeta(moveBlockPos.x, moveBlockPos.y, moveBlockPos.z, moveBlock, moveMeta);
if (cBlockInfo::IsPistonBreakable(moveBlock))
{
// Block is breakable, drop it:
a_World.DropBlockAsPickups(moveBlockPos, nullptr, nullptr);
}
else
{
// Not breakable, just move it
a_World.SetBlock(moveBlockPos.x, moveBlockPos.y, moveBlockPos.z, E_BLOCK_AIR, 0);
moveBlockPos += a_PushDir;
a_World.SetBlock(moveBlockPos.x, moveBlockPos.y, moveBlockPos.z, moveBlock, moveMeta);
}
}
} }
bool cBlockPistonHandler::CanPushBlock(
const Vector3i & a_BlockPos, cWorld & a_World, bool a_RequirePushable,
Vector3iSet & a_BlocksPushed, const Vector3i & a_PushDir
)
{
const static std::array<Vector3i, 6> pushingDirs =
{
{
Vector3i(-1, 0, 0), Vector3i(1, 0, 0),
Vector3i( 0, -1, 0), Vector3i(0, 1, 0),
Vector3i( 0, 0, -1), Vector3i(0, 0, 1)
}
};
BLOCKTYPE currBlock;
NIBBLETYPE currMeta;
a_World.GetBlockTypeMeta(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, currBlock, currMeta);
if (!cChunkDef::IsValidHeight(a_BlockPos.y))
{
return !a_RequirePushable;
}
if (currBlock == E_BLOCK_AIR)
{
// Air can be pushed
return true;
}
if (!a_RequirePushable && cBlockInfo::IsPistonBreakable(currBlock))
{
// Block should not be broken, when it's not in the pushing direction
return true;
}
if (!CanPush(currBlock, currMeta))
{
// When it's not required to push this block, don't fail
return !a_RequirePushable;
}
if (a_BlocksPushed.size() >= PISTON_MAX_PUSH_DISTANCE)
{
// Do not allow to push too much blocks
return false;
}
if (!a_BlocksPushed.insert(a_BlockPos).second || cBlockInfo::IsPistonBreakable(currBlock))
{
return true; // Element exist already
}
if (currBlock == E_BLOCK_SLIME_BLOCK)
{
// Try to push the other directions
for (const auto & testDir : pushingDirs)
{
if (!CanPushBlock(a_BlockPos + testDir, a_World, false, a_BlocksPushed, a_PushDir))
{
// When it's not possible for a direction, then fail
return false;
}
}
}
// Try to push the block in front of this block
return CanPushBlock(a_BlockPos + a_PushDir, a_World, true, a_BlocksPushed, a_PushDir);
}
void cBlockPistonHandler::OnBroken(
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
Vector3i a_BlockPos,
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta
) const
{
if (!IsExtended(a_OldBlockMeta))
{
return;
}
const auto Extension = a_BlockPos + MetadataToOffset(a_OldBlockMeta);
if (
cChunkDef::IsValidHeight(Extension.y) &&
(a_ChunkInterface.GetBlock(Extension) == E_BLOCK_PISTON_EXTENSION)
)
{
// If the piston is extended, destroy the extension as well:
a_ChunkInterface.SetBlock(Extension, E_BLOCK_AIR, 0);
}
}
////////////////////////////////////////////////////////////////////////////////
// cBlockPistonHeadHandler:
void cBlockPistonHeadHandler::OnBroken( void cBlockPistonHeadHandler::OnBroken(
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
Vector3i a_BlockPos, Vector3i a_BlockPos,
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta
) ) const
{ {
const auto Base = a_BlockPos - cBlockPistonHandler::MetadataToOffset(a_OldBlockMeta); const auto Base = a_BlockPos - cBlockPistonHandler::MetadataToOffset(a_OldBlockMeta);
if (!cChunkDef::IsValidHeight(Base.y)) if (!cChunkDef::IsValidHeight(Base.y))
@ -356,7 +339,7 @@ void cBlockPistonHeadHandler::OnBroken(
cItems cBlockPistonHeadHandler::ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) cItems cBlockPistonHeadHandler::ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const
{ {
// Give a normal\sticky piston base, not piston extension // Give a normal\sticky piston base, not piston extension
// With 1.7, the item forms of these technical blocks have been removed, so giving someone this will crash their client... // With 1.7, the item forms of these technical blocks have been removed, so giving someone this will crash their client...

View File

@ -22,13 +22,7 @@ class cBlockPistonHandler:
public: public:
cBlockPistonHandler(BLOCKTYPE a_BlockType); using Super::Super;
virtual void OnBroken(
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
Vector3i a_BlockPos,
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta
) override;
static eBlockFace MetaDataToDirection(NIBBLETYPE a_MetaData) static eBlockFace MetaDataToDirection(NIBBLETYPE a_MetaData)
{ {
@ -54,12 +48,6 @@ public:
static void ExtendPiston(Vector3i a_BlockPos, cWorld & a_World); static void ExtendPiston(Vector3i a_BlockPos, cWorld & a_World);
static void RetractPiston(Vector3i a_BlockPos, cWorld & a_World); static void RetractPiston(Vector3i a_BlockPos, cWorld & a_World);
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
{
UNUSED(a_Meta);
return 11;
}
/** Returns true if the piston (with the specified meta) is extended */ /** Returns true if the piston (with the specified meta) is extended */
static inline bool IsExtended(NIBBLETYPE a_PistonMeta) { return ((a_PistonMeta & 0x8) != 0x0); } static inline bool IsExtended(NIBBLETYPE a_PistonMeta) { return ((a_PistonMeta & 0x8) != 0x0); }
@ -131,6 +119,18 @@ private:
Vector3iSet & a_BlocksPushed, const Vector3i & a_PushDir Vector3iSet & a_BlocksPushed, const Vector3i & a_PushDir
); );
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{
UNUSED(a_Meta);
return 11;
}
virtual void OnBroken(
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
Vector3i a_BlockPos,
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta
) const override;
/** Moves a list of blocks in a specific direction */ /** Moves a list of blocks in a specific direction */
static void PushBlocks(const Vector3iSet & a_BlocksToPush, static void PushBlocks(const Vector3iSet & a_BlocksToPush,
cWorld & a_World, const Vector3i & a_PushDir cWorld & a_World, const Vector3i & a_PushDir
@ -147,13 +147,17 @@ class cBlockPistonHeadHandler:
using Super = cBlockHandler; using Super = cBlockHandler;
public: public:
cBlockPistonHeadHandler(void);
constexpr cBlockPistonHeadHandler(void) :
Super(E_BLOCK_PISTON_EXTENSION)
{
}
virtual void OnBroken( virtual void OnBroken(
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
Vector3i a_BlockPos, Vector3i a_BlockPos,
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta
) override; ) const override;
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override; virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override;
} ; } ;

View File

@ -14,14 +14,9 @@ class cBlockPlanksHandler:
public: public:
cBlockPlanksHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual bool GetPlacementBlockTypeMeta( virtual bool GetPlacementBlockTypeMeta(
cChunkInterface & a_ChunkInterface, cChunkInterface & a_ChunkInterface,
@ -30,7 +25,7 @@ public:
eBlockFace a_ClickedBlockFace, eBlockFace a_ClickedBlockFace,
const Vector3i a_CursorPos, const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override ) const override
{ {
a_BlockType = m_BlockType; a_BlockType = m_BlockType;
a_BlockMeta = static_cast<NIBBLETYPE>(a_Player.GetEquippedItem().m_ItemDamage); a_BlockMeta = static_cast<NIBBLETYPE>(a_Player.GetEquippedItem().m_ItemDamage);
@ -41,7 +36,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
switch (a_Meta) switch (a_Meta)
{ {

View File

@ -14,17 +14,11 @@ class cBlockPlant:
{ {
using Super = cBlockHandler; using Super = cBlockHandler;
public: public:
cBlockPlant(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual void OnUpdate( virtual void OnUpdate(
cChunkInterface & a_ChunkInterface, cChunkInterface & a_ChunkInterface,
@ -32,7 +26,7 @@ public:
cBlockPluginInterface & a_PluginInterface, cBlockPluginInterface & a_PluginInterface,
cChunk & a_Chunk, cChunk & a_Chunk,
const Vector3i a_RelPos const Vector3i a_RelPos
) override ) const override
{ {
auto Action = CanGrow(a_Chunk, a_RelPos); auto Action = CanGrow(a_Chunk, a_RelPos);
switch (Action) switch (Action)
@ -74,7 +68,7 @@ protected:
If the plant requires light to grow and there is enough light, it returns paGrowth. If the plant requires light to grow and there is enough light, it returns paGrowth.
If the plant requires light to grow and there isn't enough light, it returns paStay. If the plant requires light to grow and there isn't enough light, it returns paStay.
If the plant requires light to grow and there is too little light, it returns paDeath. */ If the plant requires light to grow and there is too little light, it returns paDeath. */
PlantAction HasEnoughLight(cChunk & a_Chunk, Vector3i a_RelPos) static PlantAction HasEnoughLight(cChunk & a_Chunk, Vector3i a_RelPos)
{ {
// If the plant requires light to grow, check to see if there is enough light // If the plant requires light to grow, check to see if there is enough light
// Otherwise, return true // Otherwise, return true
@ -117,7 +111,7 @@ protected:
paDeath is returned when there isn't enough light for the plant to survive. paDeath is returned when there isn't enough light for the plant to survive.
Plants that don't require light will never have a paDeath returned Plants that don't require light will never have a paDeath returned
*/ */
virtual PlantAction CanGrow(cChunk & a_Chunk, Vector3i a_RelPos) virtual PlantAction CanGrow(cChunk & a_Chunk, Vector3i a_RelPos) const
{ {
// Plant can grow if it has the required amount of light, and it passes a random chance based on surrounding blocks // Plant can grow if it has the required amount of light, and it passes a random chance based on surrounding blocks
auto action = HasEnoughLight(a_Chunk, a_RelPos); auto action = HasEnoughLight(a_Chunk, a_RelPos);
@ -134,7 +128,7 @@ protected:
/** Generates an int value between 4 and 25 based on surrounding blocks that affect how quickly the plant grows. /** Generates an int value between 4 and 25 based on surrounding blocks that affect how quickly the plant grows.
The higher the value, the less likely the plant is to grow */ The higher the value, the less likely the plant is to grow */
virtual int GetGrowthChance(cChunk & a_Chunk, Vector3i a_RelPos) virtual int GetGrowthChance(cChunk & a_Chunk, Vector3i a_RelPos) const
{ {
float Chance = 1.0f; float Chance = 1.0f;
a_RelPos.y -= 1; a_RelPos.y -= 1;
@ -149,10 +143,8 @@ protected:
// If the chunk we are trying to get the block information from is loaded // If the chunk we are trying to get the block information from is loaded
if (a_Chunk.UnboundedRelGetBlock(a_RelPos + Vector3i(x, 0, z), Block, Meta)) if (a_Chunk.UnboundedRelGetBlock(a_RelPos + Vector3i(x, 0, z), Block, Meta))
{ {
cBlockHandler * Handler = BlockHandler(Block);
// If the block affects growth, add to the adjustment // If the block affects growth, add to the adjustment
if (Handler->CanSustainPlant(m_BlockType)) if (cBlockHandler::For(Block).CanSustainPlant(m_BlockType))
{ {
Adjustment = 1.0f; Adjustment = 1.0f;

View File

@ -11,16 +11,12 @@ class cBlockPortalHandler:
public cBlockHandler public cBlockHandler
{ {
using Super = cBlockHandler; using Super = cBlockHandler;
public: public:
cBlockPortalHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual bool GetPlacementBlockTypeMeta( virtual bool GetPlacementBlockTypeMeta(
cChunkInterface & a_ChunkInterface, cChunkInterface & a_ChunkInterface,
@ -29,7 +25,7 @@ public:
eBlockFace a_ClickedBlockFace, eBlockFace a_ClickedBlockFace,
const Vector3i a_CursorPos, const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override ) const override
{ {
// We set meta to zero so Cuberite doesn't stop a Creative-mode player from building custom portal shapes // We set meta to zero so Cuberite doesn't stop a Creative-mode player from building custom portal shapes
// CanBeAt doesn't do anything if meta is zero // CanBeAt doesn't do anything if meta is zero
@ -44,7 +40,7 @@ public:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
{ {
// No pickups // No pickups
return {}; return {};
@ -60,7 +56,7 @@ public:
cBlockPluginInterface & a_PluginInterface, cBlockPluginInterface & a_PluginInterface,
cChunk & a_Chunk, cChunk & a_Chunk,
const Vector3i a_RelPos const Vector3i a_RelPos
) override ) const override
{ {
// Spawn zombie pigmen with a 0.05% chance: // Spawn zombie pigmen with a 0.05% chance:
if (GetRandomProvider().RandBool(0.9995)) if (GetRandomProvider().RandBool(0.9995))
@ -75,7 +71,7 @@ public:
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) const override
{ {
if ((a_RelPos.y <= 0) || (a_RelPos.y >= cChunkDef::Height - 1)) if ((a_RelPos.y <= 0) || (a_RelPos.y >= cChunkDef::Height - 1))
{ {
@ -138,7 +134,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 24; return 24;

View File

@ -13,16 +13,11 @@ class cBlockPressurePlateHandler :
public: public:
cBlockPressurePlateHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) const override
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override
{ {
if (a_RelPos.y <= 1) if (a_RelPos.y <= 1)
{ {
@ -55,7 +50,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
switch (m_BlockType) switch (m_BlockType)

View File

@ -9,14 +9,14 @@ class cBlockPumpkinHandler :
public cClearMetaOnDrop<cYawRotator<cBlockHandler, 0x03, 0x00, 0x01, 0x02, 0x03>> public cClearMetaOnDrop<cYawRotator<cBlockHandler, 0x03, 0x00, 0x01, 0x02, 0x03>>
{ {
using Super = cClearMetaOnDrop<cYawRotator<cBlockHandler, 0x03, 0x00, 0x01, 0x02, 0x03>>; using Super = cClearMetaOnDrop<cYawRotator<cBlockHandler, 0x03, 0x00, 0x01, 0x02, 0x03>>;
public: public:
cBlockPumpkinHandler(BLOCKTYPE a_BlockType) : using Super::Super;
Super(a_BlockType)
{
}
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override private:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 15; return 15;

View File

@ -14,14 +14,9 @@ class cBlockQuartzHandler:
public: public:
cBlockQuartzHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual bool GetPlacementBlockTypeMeta( virtual bool GetPlacementBlockTypeMeta(
cChunkInterface & a_ChunkInterface, cChunkInterface & a_ChunkInterface,
@ -30,7 +25,7 @@ public:
eBlockFace a_ClickedBlockFace, eBlockFace a_ClickedBlockFace,
const Vector3i a_CursorPos, const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override ) const override
{ {
a_BlockType = m_BlockType; a_BlockType = m_BlockType;
auto Meta = static_cast<NIBBLETYPE>(a_Player.GetEquippedItem().m_ItemDamage); auto Meta = static_cast<NIBBLETYPE>(a_Player.GetEquippedItem().m_ItemDamage);
@ -83,7 +78,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 8; return 8;

View File

@ -23,14 +23,9 @@ class cBlockRailHandler :
public: public:
cBlockRailHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual bool GetPlacementBlockTypeMeta( virtual bool GetPlacementBlockTypeMeta(
cChunkInterface & a_ChunkInterface, cChunkInterface & a_ChunkInterface,
@ -39,7 +34,7 @@ public:
eBlockFace a_ClickedBlockFace, eBlockFace a_ClickedBlockFace,
const Vector3i a_CursorPos, const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override ) const override
{ {
a_BlockType = m_BlockType; a_BlockType = m_BlockType;
a_BlockMeta = FindMeta(a_ChunkInterface, a_PlacedBlockPos); a_BlockMeta = FindMeta(a_ChunkInterface, a_PlacedBlockPos);
@ -60,7 +55,7 @@ public:
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
Vector3i a_BlockPos, Vector3i a_BlockPos,
BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta
) override ) const override
{ {
Super::OnPlaced(a_ChunkInterface, a_WorldInterface, a_BlockPos, a_BlockType, a_BlockMeta); Super::OnPlaced(a_ChunkInterface, a_WorldInterface, a_BlockPos, a_BlockType, a_BlockMeta);
@ -83,7 +78,7 @@ public:
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
Vector3i a_BlockPos, Vector3i a_BlockPos,
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta
) override ) const override
{ {
Super::OnBroken(a_ChunkInterface, a_WorldInterface, a_BlockPos, a_OldBlockType, a_OldBlockMeta); Super::OnBroken(a_ChunkInterface, a_WorldInterface, a_BlockPos, a_OldBlockType, a_OldBlockMeta);
@ -102,7 +97,7 @@ public:
virtual void OnNeighborChanged(cChunkInterface & a_ChunkInterface, Vector3i a_BlockPos, eBlockFace a_WhichNeighbor) override virtual void OnNeighborChanged(cChunkInterface & a_ChunkInterface, Vector3i a_BlockPos, eBlockFace a_WhichNeighbor) const override
{ {
const auto Meta = a_ChunkInterface.GetBlockMeta(a_BlockPos); const auto Meta = a_ChunkInterface.GetBlockMeta(a_BlockPos);
const auto NewMeta = FindMeta(a_ChunkInterface, a_BlockPos); const auto NewMeta = FindMeta(a_ChunkInterface, a_BlockPos);
@ -118,7 +113,7 @@ public:
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) const override
{ {
if (a_RelPos.y <= 0) if (a_RelPos.y <= 0)
{ {
@ -163,7 +158,7 @@ public:
NIBBLETYPE FindMeta(cChunkInterface & a_ChunkInterface, Vector3i a_BlockPos) NIBBLETYPE FindMeta(cChunkInterface & a_ChunkInterface, Vector3i a_BlockPos) const
{ {
NIBBLETYPE Meta = 0; NIBBLETYPE Meta = 0;
char RailsCnt = 0; char RailsCnt = 0;
@ -288,13 +283,13 @@ public:
} }
inline bool CanThisRailCurve(void) bool CanThisRailCurve(void) const
{ {
return m_BlockType == E_BLOCK_RAIL; return m_BlockType == E_BLOCK_RAIL;
} }
bool IsUnstable(cChunkInterface & a_ChunkInterface, Vector3i a_Pos) static bool IsUnstable(cChunkInterface & a_ChunkInterface, Vector3i a_Pos)
{ {
if (!IsBlockRail(a_ChunkInterface.GetBlock(a_Pos))) if (!IsBlockRail(a_ChunkInterface.GetBlock(a_Pos)))
{ {
@ -427,7 +422,7 @@ public:
} }
bool IsNotConnected(cChunkInterface & a_ChunkInterface, Vector3i a_Pos, eBlockFace a_BlockFace, char a_Pure = 0) static bool IsNotConnected(cChunkInterface & a_ChunkInterface, Vector3i a_Pos, eBlockFace a_BlockFace, char a_Pure = 0)
{ {
AddFaceDirection(a_Pos.x, a_Pos.y, a_Pos.z, a_BlockFace, false); AddFaceDirection(a_Pos.x, a_Pos.y, a_Pos.z, a_BlockFace, false);
NIBBLETYPE Meta; NIBBLETYPE Meta;
@ -525,7 +520,7 @@ public:
} }
virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) const override
{ {
// Bit 0x08 is a flag when a_Meta is in the range 0x00--0x05 and 0x0A--0x0F. // 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. // Bit 0x08 specifies direction when a_Meta is in the range 0x06-0x09.
@ -562,7 +557,7 @@ public:
} }
virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) const override
{ {
// Bit 0x08 is a flag for value in the range 0x00--0x05 and specifies direction for values withint 0x006--0x09. // 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)) if ((a_Meta < 0x06) || (a_Meta > 0x09))
@ -598,7 +593,7 @@ public:
} }
virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) const override
{ {
// MirrorXY basically flips the ZP and ZM parts of the meta // MirrorXY basically flips the ZP and ZM parts of the meta
if (m_BlockType == E_BLOCK_RAIL) if (m_BlockType == E_BLOCK_RAIL)
@ -637,7 +632,7 @@ public:
} }
virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) const override
{ {
// MirrorYZ basically flips the XP and XM parts of the meta // MirrorYZ basically flips the XP and XM parts of the meta
if (m_BlockType == E_BLOCK_RAIL) if (m_BlockType == E_BLOCK_RAIL)
@ -676,7 +671,7 @@ public:
} }
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 0; return 0;

View File

@ -15,16 +15,11 @@ class cBlockRedstoneHandler:
public: public:
cBlockRedstoneHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) const override
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override
{ {
if (a_RelPos.y <= 0) if (a_RelPos.y <= 0)
{ {
@ -54,7 +49,7 @@ public:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
{ {
return cItem(E_ITEM_REDSTONE_DUST, 1, 0); return cItem(E_ITEM_REDSTONE_DUST, 1, 0);
} }
@ -63,7 +58,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 0; return 0;

View File

@ -11,16 +11,12 @@ class cBlockRedstoneLampHandler:
public cBlockHandler public cBlockHandler
{ {
public: public:
cBlockRedstoneLampHandler(BLOCKTYPE a_BlockType):
cBlockHandler(a_BlockType)
{
}
using cBlockHandler::cBlockHandler;
private:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{ {
// Always drop the Off variant: // Always drop the Off variant:
return(cItem(E_BLOCK_REDSTONE_LAMP_OFF, 1, 0)); return(cItem(E_BLOCK_REDSTONE_LAMP_OFF, 1, 0));
@ -30,7 +26,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 15; return 15;

View File

@ -26,7 +26,7 @@ public:
const Vector3i a_BlockPos, const Vector3i a_BlockPos,
eBlockFace a_BlockFace, eBlockFace a_BlockFace,
const Vector3i a_CursorPos const Vector3i a_CursorPos
) override ) const override
{ {
a_ChunkInterface.SetBlock(a_BlockPos, E_BLOCK_REDSTONE_ORE_GLOWING, 0); a_ChunkInterface.SetBlock(a_BlockPos, E_BLOCK_REDSTONE_ORE_GLOWING, 0);
return false; return false;
@ -41,7 +41,7 @@ public:
cWorldInterface & a_WorldInterface, cWorldInterface & a_WorldInterface,
cPlayer & a_Player, cPlayer & a_Player,
const Vector3i a_BlockPos const Vector3i a_BlockPos
) override ) const override
{ {
a_ChunkInterface.SetBlock(a_BlockPos, E_BLOCK_REDSTONE_ORE_GLOWING, 0); a_ChunkInterface.SetBlock(a_BlockPos, E_BLOCK_REDSTONE_ORE_GLOWING, 0);
} }
@ -50,7 +50,7 @@ public:
virtual bool IsUseable() override virtual bool IsUseable() const override
{ {
return true; return true;
} }
@ -79,7 +79,7 @@ public:
cBlockPluginInterface & a_BlockPluginInterface, cBlockPluginInterface & a_BlockPluginInterface,
cChunk & a_Chunk, cChunk & a_Chunk,
const Vector3i a_RelPos const Vector3i a_RelPos
) override ) const override
{ {
auto BlockPos = a_Chunk.RelativeToAbsolute(a_RelPos); auto BlockPos = a_Chunk.RelativeToAbsolute(a_RelPos);
a_ChunkInterface.SetBlock(BlockPos, E_BLOCK_REDSTONE_ORE, 0); a_ChunkInterface.SetBlock(BlockPos, E_BLOCK_REDSTONE_ORE, 0);

View File

@ -18,14 +18,49 @@ class cBlockRedstoneRepeaterHandler:
public: public:
cBlockRedstoneRepeaterHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
inline static Vector3i GetFrontCoordinateOffset(NIBBLETYPE a_Meta)
{ {
return -GetRearCoordinateOffset(a_Meta);
} }
inline static Vector3i GetLeftCoordinateOffset(NIBBLETYPE a_Meta)
{
switch (a_Meta & E_META_REDSTONE_REPEATER_FACING_MASK) // We only want the direction (bottom) bits
{
case E_META_REDSTONE_REPEATER_FACING_ZM: return { -1, 0, 0 };
case E_META_REDSTONE_REPEATER_FACING_XP: return { 0, 0, -1 };
case E_META_REDSTONE_REPEATER_FACING_ZP: return { 1, 0, 0 };
case E_META_REDSTONE_REPEATER_FACING_XM: return { 0, 0, 1 };
default:
{
LOGWARNING("%s: Unknown metadata: %d", __FUNCTION__, a_Meta);
ASSERT(!"Unknown metadata while determining orientation of repeater!");
return { 0, 0, 0 };
}
}
}
inline static Vector3i GetRearCoordinateOffset(NIBBLETYPE a_Meta)
{
switch (a_Meta & E_META_REDSTONE_REPEATER_FACING_MASK) // We only want the direction (bottom) bits
{
case E_META_REDSTONE_REPEATER_FACING_ZM: return { 0, 0, 1 };
case E_META_REDSTONE_REPEATER_FACING_XP: return { -1, 0, 0 };
case E_META_REDSTONE_REPEATER_FACING_ZP: return { 0, 0, -1 };
case E_META_REDSTONE_REPEATER_FACING_XM: return { 1, 0, 0 };
default:
{
LOGWARNING("%s: Unknown metadata: %d", __FUNCTION__, a_Meta);
ASSERT(!"Unknown metadata while determining orientation of repeater!");
return { 0, 0, 0 };
}
}
}
private:
virtual bool OnUse( virtual bool OnUse(
cChunkInterface & a_ChunkInterface, cChunkInterface & a_ChunkInterface,
@ -34,7 +69,7 @@ public:
const Vector3i a_BlockPos, const Vector3i a_BlockPos,
eBlockFace a_BlockFace, eBlockFace a_BlockFace,
const Vector3i a_CursorPos const Vector3i a_CursorPos
) override ) const override
{ {
// Increment the delay setting: // Increment the delay setting:
a_ChunkInterface.SetBlockMeta(a_BlockPos, ((a_ChunkInterface.GetBlockMeta(a_BlockPos) + 0x04) & 0x0f)); a_ChunkInterface.SetBlockMeta(a_BlockPos, ((a_ChunkInterface.GetBlockMeta(a_BlockPos) + 0x04) & 0x0f));
@ -51,7 +86,7 @@ public:
cPlayer & a_Player, cPlayer & a_Player,
const Vector3i a_BlockPos, const Vector3i a_BlockPos,
eBlockFace a_BlockFace eBlockFace a_BlockFace
) override ) const override
{ {
UNUSED(a_ChunkInterface); UNUSED(a_ChunkInterface);
a_WorldInterface.SendBlockTo(a_BlockPos, a_Player); a_WorldInterface.SendBlockTo(a_BlockPos, a_Player);
@ -61,7 +96,7 @@ public:
virtual bool IsUseable(void) override virtual bool IsUseable(void) const override
{ {
return true; return true;
} }
@ -70,7 +105,7 @@ public:
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) const override
{ {
if (a_RelPos.y <= 0) if (a_RelPos.y <= 0)
{ {
@ -100,7 +135,7 @@ public:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
{ {
return cItem(E_ITEM_REDSTONE_REPEATER, 1, 0); return cItem(E_ITEM_REDSTONE_REPEATER, 1, 0);
} }
@ -109,62 +144,11 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 11; return 11;
} }
inline static Vector3i GetLeftCoordinateOffset(NIBBLETYPE a_Meta)
{
switch (a_Meta & E_META_REDSTONE_REPEATER_FACING_MASK) // We only want the direction (bottom) bits
{
case E_META_REDSTONE_REPEATER_FACING_ZM: return { -1, 0, 0 };
case E_META_REDSTONE_REPEATER_FACING_XP: return { 0, 0, -1 };
case E_META_REDSTONE_REPEATER_FACING_ZP: return { 1, 0, 0 };
case E_META_REDSTONE_REPEATER_FACING_XM: return { 0, 0, 1 };
default:
{
LOGWARNING("%s: Unknown metadata: %d", __FUNCTION__, a_Meta);
ASSERT(!"Unknown metadata while determining orientation of repeater!");
return { 0, 0, 0 };
}
}
}
inline static Vector3i GetFrontCoordinateOffset(NIBBLETYPE a_Meta)
{
return -GetRearCoordinateOffset(a_Meta);
}
inline static Vector3i GetRearCoordinateOffset(NIBBLETYPE a_Meta)
{
switch (a_Meta & E_META_REDSTONE_REPEATER_FACING_MASK) // We only want the direction (bottom) bits
{
case E_META_REDSTONE_REPEATER_FACING_ZM: return { 0, 0, 1 };
case E_META_REDSTONE_REPEATER_FACING_XP: return { -1, 0, 0 };
case E_META_REDSTONE_REPEATER_FACING_ZP: return { 0, 0, -1 };
case E_META_REDSTONE_REPEATER_FACING_XM: return { 1, 0, 0 };
default:
{
LOGWARNING("%s: Unknown metadata: %d", __FUNCTION__, a_Meta);
ASSERT(!"Unknown metadata while determining orientation of repeater!");
return { 0, 0, 0 };
}
}
}
} ; } ;

View File

@ -14,16 +14,11 @@ class cBlockRedstoneTorchHandler :
public: public:
cBlockRedstoneTorchHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{ {
// Always drop the ON torch, meta 0 // Always drop the ON torch, meta 0
return cItem(E_BLOCK_REDSTONE_TORCH_ON, 1, 0); return cItem(E_BLOCK_REDSTONE_TORCH_ON, 1, 0);
@ -33,7 +28,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 0; return 0;

View File

@ -11,18 +11,14 @@ class cBlockSandHandler :
public cBlockHandler public cBlockHandler
{ {
public: public:
cBlockSandHandler(BLOCKTYPE a_BlockType)
: cBlockHandler(a_BlockType)
{
}
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override using cBlockHandler::cBlockHandler;
private:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 2; return 2;
} }
}; };

View File

@ -15,16 +15,11 @@ class cBlockSaplingHandler :
public: public:
cBlockSaplingHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{ {
// The low 3 bits store the sapling type; bit 0x08 is the growth timer (not used in pickups) // The low 3 bits store the sapling type; bit 0x08 is the growth timer (not used in pickups)
return cItem(m_BlockType, 1, a_BlockMeta & 0x07); return cItem(m_BlockType, 1, a_BlockMeta & 0x07);
@ -34,7 +29,7 @@ public:
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) const override
{ {
return (a_RelPos.y > 0) && IsBlockTypeOfDirt(a_Chunk.GetBlock(a_RelPos.addedY(-1))); return (a_RelPos.y > 0) && IsBlockTypeOfDirt(a_Chunk.GetBlock(a_RelPos.addedY(-1)));
} }
@ -49,7 +44,7 @@ public:
cBlockPluginInterface & a_PluginInterface, cBlockPluginInterface & a_PluginInterface,
cChunk & a_Chunk, cChunk & a_Chunk,
const Vector3i a_RelPos const Vector3i a_RelPos
) override ) const override
{ {
auto Meta = a_Chunk.GetMeta(a_RelPos); auto Meta = a_Chunk.GetMeta(a_RelPos);
auto Light = std::max(a_Chunk.GetBlockLight(a_RelPos), a_Chunk.GetTimeAlteredLight(a_Chunk.GetSkyLight(a_RelPos))); auto Light = std::max(a_Chunk.GetBlockLight(a_RelPos), a_Chunk.GetTimeAlteredLight(a_Chunk.GetSkyLight(a_RelPos)));
@ -76,7 +71,7 @@ public:
bool CanGrowAt(cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Meta) static bool CanGrowAt(cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Meta)
{ {
a_Meta = a_Meta & 0x07; a_Meta = a_Meta & 0x07;
int CheckHeight = 0; int CheckHeight = 0;
@ -190,7 +185,7 @@ public:
virtual int Grow(cChunk & a_Chunk, Vector3i a_RelPos, int a_NumStages = 1) override virtual int Grow(cChunk & a_Chunk, Vector3i a_RelPos, int a_NumStages = 1) const override
{ {
auto blockMeta = a_Chunk.GetMeta(a_RelPos); auto blockMeta = a_Chunk.GetMeta(a_RelPos);
auto typeMeta = blockMeta & 0x07; auto typeMeta = blockMeta & 0x07;
@ -219,19 +214,13 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 7; return 7;
} }
static bool IsLargeTree(cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Meta)
private:
bool IsLargeTree(cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Meta)
{ {
BLOCKTYPE type; BLOCKTYPE type;
NIBBLETYPE meta; NIBBLETYPE meta;

View File

@ -14,23 +14,14 @@ class cBlockSeaLanternHandler :
public: public:
cBlockSeaLanternHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{ {
// Reset meta to 0 // Reset meta to 0
// TODO: Handle the Fortune enchantment // TODO: Handle the Fortune enchantment
return cItem(E_ITEM_PRISMARINE_CRYSTALS, GetRandomProvider().RandInt<char>(2, 3), 0); return cItem(E_ITEM_PRISMARINE_CRYSTALS, GetRandomProvider().RandInt<char>(2, 3), 0);
} }
} ; } ;

View File

@ -17,14 +17,9 @@ class cBlockSidewaysHandler:
public: public:
cBlockSidewaysHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual bool GetPlacementBlockTypeMeta( virtual bool GetPlacementBlockTypeMeta(
cChunkInterface & a_ChunkInterface, cChunkInterface & a_ChunkInterface,
@ -33,7 +28,7 @@ public:
eBlockFace a_ClickedBlockFace, eBlockFace a_ClickedBlockFace,
const Vector3i a_CursorPos, const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override ) const override
{ {
a_BlockType = m_BlockType; a_BlockType = m_BlockType;
NIBBLETYPE Meta = static_cast<NIBBLETYPE>(a_Player.GetEquippedItem().m_ItemDamage); NIBBLETYPE Meta = static_cast<NIBBLETYPE>(a_Player.GetEquippedItem().m_ItemDamage);
@ -45,7 +40,7 @@ public:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
{ {
// Reset the orientation part of meta, keep the sub-type part of meta // Reset the orientation part of meta, keep the sub-type part of meta
return cItem(m_BlockType, 1, a_BlockMeta & 0x03); return cItem(m_BlockType, 1, a_BlockMeta & 0x03);

View File

@ -15,36 +15,7 @@ class cBlockSignPostHandler:
public: public:
cBlockSignPostHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{
return cItem(E_ITEM_SIGN, 1, 0);
}
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override
{
if (a_RelPos.y <= 0)
{
return false;
}
BLOCKTYPE Type = a_Chunk.GetBlock(a_RelPos.addedY(-1));
return ((Type == E_BLOCK_SIGN_POST) || (Type == E_BLOCK_WALLSIGN) || cBlockInfo::IsSolid(Type));
}
/** Converts the (player) rotation to placed-signpost block meta. */ /** Converts the (player) rotation to placed-signpost block meta. */
static NIBBLETYPE RotationToMetaData(double a_Rotation) static NIBBLETYPE RotationToMetaData(double a_Rotation)
@ -60,11 +31,32 @@ public:
return (static_cast<char>(a_Rotation)) % 16; return (static_cast<char>(a_Rotation)) % 16;
} }
private:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
{
return cItem(E_ITEM_SIGN, 1, 0);
}
virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) const override
{
if (a_RelPos.y <= 0)
{
return false;
}
BLOCKTYPE Type = a_Chunk.GetBlock(a_RelPos.addedY(-1));
return ((Type == E_BLOCK_SIGN_POST) || (Type == E_BLOCK_WALLSIGN) || cBlockInfo::IsSolid(Type));
}
virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) const override
{ {
return (a_Meta + 4) & 0x0f; return (a_Meta + 4) & 0x0f;
} }
@ -73,7 +65,7 @@ public:
virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) const override
{ {
return (a_Meta + 12) & 0x0f; return (a_Meta + 12) & 0x0f;
} }
@ -82,7 +74,7 @@ public:
virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) const override
{ {
// Mirrors signs over the XY plane (North-South Mirroring) // Mirrors signs over the XY plane (North-South Mirroring)
@ -95,7 +87,7 @@ public:
virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) const override
{ {
// Mirrors signs over the YZ plane (East-West Mirroring) // Mirrors signs over the YZ plane (East-West Mirroring)
@ -108,7 +100,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 13; return 13;

View File

@ -24,16 +24,22 @@ class cBlockSlabHandler :
public: public:
cBlockSlabHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
/** Returns true if the specified blocktype is one of the slabs handled by this handler */
static bool IsAnySlabType(BLOCKTYPE a_BlockType)
{ {
return (
(a_BlockType == E_BLOCK_WOODEN_SLAB) ||
(a_BlockType == E_BLOCK_STONE_SLAB) ||
(a_BlockType == E_BLOCK_RED_SANDSTONE_SLAB) ||
(a_BlockType == E_BLOCK_PURPUR_SLAB)
);
} }
private:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{ {
// Reset the "top half" flag: // Reset the "top half" flag:
return cItem(m_BlockType, 1, a_BlockMeta & 0x07); return cItem(m_BlockType, 1, a_BlockMeta & 0x07);
@ -50,7 +56,7 @@ public:
eBlockFace a_ClickedBlockFace, eBlockFace a_ClickedBlockFace,
const Vector3i a_CursorPos, const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override ) const override
{ {
a_BlockType = m_BlockType; a_BlockType = m_BlockType;
NIBBLETYPE Meta = static_cast<NIBBLETYPE>(a_Player.GetEquippedItem().m_ItemDamage); NIBBLETYPE Meta = static_cast<NIBBLETYPE>(a_Player.GetEquippedItem().m_ItemDamage);
@ -104,28 +110,13 @@ public:
/** Returns true if the specified blocktype is one of the slabs handled by this handler */
static bool IsAnySlabType(BLOCKTYPE a_BlockType)
{
return (
(a_BlockType == E_BLOCK_WOODEN_SLAB) ||
(a_BlockType == E_BLOCK_STONE_SLAB) ||
(a_BlockType == E_BLOCK_RED_SANDSTONE_SLAB) ||
(a_BlockType == E_BLOCK_PURPUR_SLAB)
);
}
virtual void OnCancelRightClick( virtual void OnCancelRightClick(
cChunkInterface & a_ChunkInterface, cChunkInterface & a_ChunkInterface,
cWorldInterface & a_WorldInterface, cWorldInterface & a_WorldInterface,
cPlayer & a_Player, cPlayer & a_Player,
const Vector3i a_BlockPos, const Vector3i a_BlockPos,
eBlockFace a_BlockFace eBlockFace a_BlockFace
) override ) const override
{ {
if ((a_BlockFace == BLOCK_FACE_NONE) || (a_Player.GetEquippedItem().m_ItemType != static_cast<short>(m_BlockType))) if ((a_BlockFace == BLOCK_FACE_NONE) || (a_Player.GetEquippedItem().m_ItemType != static_cast<short>(m_BlockType)))
{ {
@ -158,7 +149,7 @@ public:
virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) override virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) const override
{ {
// Toggle the 4th bit - up / down: // Toggle the 4th bit - up / down:
return (a_Meta ^ 0x08); return (a_Meta ^ 0x08);
@ -168,7 +159,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
a_Meta &= 0x7; a_Meta &= 0x7;
@ -230,7 +221,7 @@ public:
virtual bool IsInsideBlock(Vector3d a_Position, const NIBBLETYPE a_BlockMeta) override virtual bool IsInsideBlock(Vector3d a_Position, const NIBBLETYPE a_BlockMeta) const override
{ {
if (a_BlockMeta & 0x08) // top half if (a_BlockMeta & 0x08) // top half
{ {
@ -251,16 +242,11 @@ class cBlockDoubleSlabHandler:
public: public:
cBlockDoubleSlabHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{ {
BLOCKTYPE Block = GetSingleSlabType(m_BlockType); BLOCKTYPE Block = GetSingleSlabType(m_BlockType);
return cItem(Block, 2, a_BlockMeta & 0x7); return cItem(Block, 2, a_BlockMeta & 0x7);
@ -287,10 +273,10 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
// For doule slabs, the meta values are the same. Only the meaning of the 4th bit changes, but that's ignored in the below handler // For doule slabs, the meta values are the same. Only the meaning of the 4th bit changes, but that's ignored in the below handler
return BlockHandler(GetSingleSlabType(m_BlockType))->GetMapBaseColourID(a_Meta); return cBlockHandler::For(GetSingleSlabType(m_BlockType)).GetMapBaseColourID(a_Meta);
} }
} ; } ;

View File

@ -9,26 +9,15 @@
class cBlockSlimeHandler: class cBlockSlimeHandler:
public cClearMetaOnDrop<cBlockHandler> public cClearMetaOnDrop<cBlockHandler>
{ {
using super = cClearMetaOnDrop<cBlockHandler>;
public: public:
cBlockSlimeHandler(BLOCKTYPE a_BlockType): using cClearMetaOnDrop<cBlockHandler>::cClearMetaOnDrop;
super(a_BlockType)
{
}
private:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 1; return 1;
} }
}; };

View File

@ -14,21 +14,15 @@ class cBlockSnowHandler :
public: public:
using Super::Super;
private:
enum enum
{ {
FullBlockMeta = 7 // Meta value of a full-height snow block FullBlockMeta = 7 // Meta value of a full-height snow block
}; };
cBlockSnowHandler(BLOCKTYPE a_BlockType):
Super(a_BlockType)
{
}
virtual bool GetPlacementBlockTypeMeta( virtual bool GetPlacementBlockTypeMeta(
cChunkInterface & a_ChunkInterface, cChunkInterface & a_ChunkInterface,
cPlayer & a_Player, cPlayer & a_Player,
@ -36,7 +30,7 @@ public:
eBlockFace a_ClickedBlockFace, eBlockFace a_ClickedBlockFace,
const Vector3i a_CursorPos, const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override ) const override
{ {
a_BlockType = m_BlockType; a_BlockType = m_BlockType;
@ -68,7 +62,7 @@ public:
virtual bool DoesIgnoreBuildCollision(cChunkInterface & a_ChunkInterface, Vector3i a_Pos, cPlayer & a_Player, NIBBLETYPE a_Meta) override virtual bool DoesIgnoreBuildCollision(cChunkInterface & a_ChunkInterface, Vector3i a_Pos, cPlayer & a_Player, NIBBLETYPE a_Meta) const override
{ {
if ((a_Player.GetEquippedItem().m_ItemType == E_BLOCK_SNOW) && (a_Meta < FullBlockMeta)) if ((a_Player.GetEquippedItem().m_ItemType == E_BLOCK_SNOW) && (a_Meta < FullBlockMeta))
{ {
@ -87,7 +81,7 @@ public:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
{ {
// No drop unless dug up with a shovel // No drop unless dug up with a shovel
if ((a_Tool == nullptr) || !ItemCategory::IsShovel(a_Tool->m_ItemType)) if ((a_Tool == nullptr) || !ItemCategory::IsShovel(a_Tool->m_ItemType))
@ -110,7 +104,7 @@ public:
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) const override
{ {
if (a_RelPos.y <= 0) if (a_RelPos.y <= 0)
{ {
@ -126,7 +120,7 @@ public:
virtual bool DoesDropOnUnsuitable(void) override virtual bool DoesDropOnUnsuitable(void) const override
{ {
return false; return false;
} }
@ -135,7 +129,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 14; return 14;
@ -145,7 +139,7 @@ public:
virtual bool IsInsideBlock(const Vector3d a_RelPosition, const NIBBLETYPE a_BlockMeta) override virtual bool IsInsideBlock(const Vector3d a_RelPosition, const NIBBLETYPE a_BlockMeta) const override
{ {
return a_RelPosition.y < (cBlockInfo::GetBlockHeight(m_BlockType) * (a_BlockMeta & 0x07)); return a_RelPosition.y < (cBlockInfo::GetBlockHeight(m_BlockType) * (a_BlockMeta & 0x07));
} }

View File

@ -14,21 +14,20 @@ class cBlockSpongeHandler :
public: public:
cBlockSpongeHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{ private:
}
virtual void OnPlaced( virtual void OnPlaced(
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
Vector3i a_BlockPos, Vector3i a_BlockPos,
BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta
) override ) const override
{ {
OnNeighborChanged(a_ChunkInterface, a_BlockPos, BLOCK_FACE_NONE); OnNeighborChanged(a_ChunkInterface, a_BlockPos, BLOCK_FACE_NONE);
} }
virtual void OnNeighborChanged(cChunkInterface & a_ChunkInterface, Vector3i a_BlockPos, eBlockFace a_WhichNeighbor) override virtual void OnNeighborChanged(cChunkInterface & a_ChunkInterface, Vector3i a_BlockPos, eBlockFace a_WhichNeighbor) const override
{ {
a_ChunkInterface.DoWithChunkAt(a_BlockPos, [&](cChunk & a_Chunk) { CheckSoaked(a_Chunk.AbsoluteToRelative(a_BlockPos), a_Chunk); return true; }); a_ChunkInterface.DoWithChunkAt(a_BlockPos, [&](cChunk & a_Chunk) { CheckSoaked(a_Chunk.AbsoluteToRelative(a_BlockPos), a_Chunk); return true; });
} }
@ -36,7 +35,7 @@ public:
/** Check blocks around the sponge to see if they are water. /** Check blocks around the sponge to see if they are water.
If a dry sponge is touching water, soak up up to 65 blocks of water, If a dry sponge is touching water, soak up up to 65 blocks of water,
with a taxicab distance of 7, and turn the sponge into a wet sponge. */ with a taxicab distance of 7, and turn the sponge into a wet sponge. */
void CheckSoaked(Vector3i a_Rel, cChunk & a_Chunk) static void CheckSoaked(Vector3i a_Rel, cChunk & a_Chunk)
{ {
struct sSeed struct sSeed
{ {
@ -117,7 +116,7 @@ public:
return(a_Chunk.UnboundedRelGetBlockType(a_Rel.x, a_Rel.y, a_Rel.z, Type) && IsBlockWater(Type)); return(a_Chunk.UnboundedRelGetBlockType(a_Rel.x, a_Rel.y, a_Rel.z, Type) && IsBlockWater(Type));
} }
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 18; return 18;

View File

@ -14,14 +14,9 @@ class cBlockStairsHandler :
public: public:
cBlockStairsHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual bool GetPlacementBlockTypeMeta( virtual bool GetPlacementBlockTypeMeta(
cChunkInterface & a_ChunkInterface, cChunkInterface & a_ChunkInterface,
@ -30,7 +25,7 @@ public:
eBlockFace a_ClickedBlockFace, eBlockFace a_ClickedBlockFace,
const Vector3i a_CursorPos, const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override ) const override
{ {
UNUSED(a_ChunkInterface); UNUSED(a_ChunkInterface);
UNUSED(a_PlacedBlockPos); UNUSED(a_PlacedBlockPos);
@ -91,7 +86,7 @@ public:
virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) override virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) const override
{ {
// Toggle bit 3: // Toggle bit 3:
return (a_Meta & 0x0b) | ((~a_Meta) & 0x04); return (a_Meta & 0x0b) | ((~a_Meta) & 0x04);
@ -101,7 +96,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
switch (m_BlockType) switch (m_BlockType)

View File

@ -18,16 +18,11 @@ class cBlockStemsHandler:
public: public:
cBlockStemsHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{ {
return cItem(StemPickupType, 1, 0); return cItem(StemPickupType, 1, 0);
} }
@ -36,7 +31,7 @@ public:
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) const override
{ {
return ((a_RelPos.y > 0) && (a_Chunk.GetBlock(a_RelPos.addedY(-1)) == E_BLOCK_FARMLAND)); return ((a_RelPos.y > 0) && (a_Chunk.GetBlock(a_RelPos.addedY(-1)) == E_BLOCK_FARMLAND));
} }
@ -45,7 +40,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 7; return 7;
@ -55,7 +50,7 @@ public:
virtual int Grow(cChunk & a_Chunk, Vector3i a_RelPos, int a_NumStages = 1) override virtual int Grow(cChunk & a_Chunk, Vector3i a_RelPos, int a_NumStages = 1) const override
{ {
auto oldMeta = a_Chunk.GetMeta(a_RelPos); auto oldMeta = a_Chunk.GetMeta(a_RelPos);
auto meta = oldMeta + a_NumStages; auto meta = oldMeta + a_NumStages;
@ -74,14 +69,9 @@ public:
return meta - oldMeta; return meta - oldMeta;
} }
protected:
/** Grows the final produce next to the stem at the specified pos. /** Grows the final produce next to the stem at the specified pos.
Returns true if successful, false if not. */ Returns true if successful, false if not. */
bool growProduce(cChunk & a_Chunk, Vector3i a_StemRelPos) static bool growProduce(cChunk & a_Chunk, Vector3i a_StemRelPos)
{ {
auto & random = GetRandomProvider(); auto & random = GetRandomProvider();

View File

@ -13,16 +13,11 @@ class cBlockStoneHandler:
public: public:
cBlockStoneHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{ {
// Convert stone to cobblestone, unless using silk-touch: // Convert stone to cobblestone, unless using silk-touch:
if ( if (
@ -39,7 +34,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 11; return 11;

View File

@ -14,16 +14,11 @@ class cBlockSugarcaneHandler :
public: public:
cBlockSugarcaneHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{ {
return cItem(E_ITEM_SUGARCANE, 1, 0); return cItem(E_ITEM_SUGARCANE, 1, 0);
} }
@ -32,7 +27,7 @@ public:
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) const override
{ {
if (a_RelPos.y <= 0) if (a_RelPos.y <= 0)
{ {
@ -82,7 +77,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 7; return 7;
@ -92,7 +87,7 @@ public:
virtual int Grow(cChunk & a_Chunk, Vector3i a_RelPos, int a_NumStages = 1) override virtual int Grow(cChunk & a_Chunk, Vector3i a_RelPos, int a_NumStages = 1) const override
{ {
// Check the total height of the sugarcane blocks here: // Check the total height of the sugarcane blocks here:
int top = a_RelPos.y + 1; int top = a_RelPos.y + 1;
@ -129,13 +124,7 @@ public:
return toGrow; return toGrow;
} }
virtual PlantAction CanGrow(cChunk & a_Chunk, Vector3i a_RelPos) const override
protected:
virtual PlantAction CanGrow(cChunk & a_Chunk, Vector3i a_RelPos) override
{ {
// Only allow growing if there's an air block above: // Only allow growing if there's an air block above:
if (((a_RelPos.y + 1) < cChunkDef::Height) && (a_Chunk.GetBlock(a_RelPos.addedY(1)) == E_BLOCK_AIR)) if (((a_RelPos.y + 1) < cChunkDef::Height) && (a_Chunk.GetBlock(a_RelPos.addedY(1)) == E_BLOCK_AIR))

View File

@ -14,14 +14,9 @@ class cBlockTNTHandler :
public: public:
cBlockTNTHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual void OnCancelRightClick( virtual void OnCancelRightClick(
cChunkInterface & a_ChunkInterface, cChunkInterface & a_ChunkInterface,
@ -29,7 +24,7 @@ public:
cPlayer & a_Player, cPlayer & a_Player,
const Vector3i a_BlockPos, const Vector3i a_BlockPos,
eBlockFace a_BlockFace eBlockFace a_BlockFace
) override ) const override
{ {
a_WorldInterface.SendBlockTo(a_BlockPos, a_Player); a_WorldInterface.SendBlockTo(a_BlockPos, a_Player);
} }
@ -38,7 +33,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 4; return 4;

View File

@ -16,16 +16,11 @@ class cBlockTallGrassHandler:
public: public:
cBlockTallGrassHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual bool DoesIgnoreBuildCollision(cChunkInterface & a_ChunkInterface, Vector3i a_Pos, cPlayer & a_Player, NIBBLETYPE a_Meta) const override
virtual bool DoesIgnoreBuildCollision(cChunkInterface & a_ChunkInterface, Vector3i a_Pos, cPlayer & a_Player, NIBBLETYPE a_Meta) override
{ {
return true; return true;
} }
@ -34,7 +29,7 @@ public:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
{ {
// If using shears, drop self: // If using shears, drop self:
if ((a_Tool != nullptr) && (a_Tool->m_ItemType == E_ITEM_SHEARS)) if ((a_Tool != nullptr) && (a_Tool->m_ItemType == E_ITEM_SHEARS))
@ -54,7 +49,7 @@ public:
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) const override
{ {
if (a_RelPos.y <= 0) if (a_RelPos.y <= 0)
{ {
@ -70,7 +65,7 @@ public:
/** Growing a tall grass produces a big flower (2-block high fern or double-tall grass). */ /** Growing a tall grass produces a big flower (2-block high fern or double-tall grass). */
virtual int Grow(cChunk & a_Chunk, Vector3i a_RelPos, int a_NumStages = 1) override virtual int Grow(cChunk & a_Chunk, Vector3i a_RelPos, int a_NumStages = 1) const override
{ {
if (a_RelPos.y > (cChunkDef::Height - 2)) if (a_RelPos.y > (cChunkDef::Height - 2))
{ {
@ -93,7 +88,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 7; return 7;

View File

@ -15,14 +15,9 @@ class cBlockTorchHandler:
public: public:
cBlockTorchHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual bool GetPlacementBlockTypeMeta( virtual bool GetPlacementBlockTypeMeta(
cChunkInterface & a_ChunkInterface, cChunkInterface & a_ChunkInterface,
@ -31,7 +26,7 @@ public:
eBlockFace a_ClickedBlockFace, eBlockFace a_ClickedBlockFace,
const Vector3i a_CursorPos, const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override ) const override
{ {
BLOCKTYPE ClickedBlockType; BLOCKTYPE ClickedBlockType;
NIBBLETYPE ClickedBlockMeta; NIBBLETYPE ClickedBlockMeta;
@ -190,7 +185,7 @@ public:
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) const override
{ {
auto Face = MetaDataToBlockFace(a_Chunk.GetMeta(a_RelPos)); auto Face = MetaDataToBlockFace(a_Chunk.GetMeta(a_RelPos));
auto NeighborRelPos = AddFaceDirection(a_RelPos, Face, true); auto NeighborRelPos = AddFaceDirection(a_RelPos, Face, true);
@ -209,7 +204,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 0; return 0;

View File

@ -15,15 +15,11 @@ class cBlockTrapdoorHandler :
public: public:
cBlockTrapdoorHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual bool IsUseable(void) const override
virtual bool IsUseable(void) override
{ {
return true; return true;
} }
@ -39,7 +35,7 @@ public:
const Vector3i a_BlockPos, const Vector3i a_BlockPos,
eBlockFace a_BlockFace, eBlockFace a_BlockFace,
const Vector3i a_CursorPos const Vector3i a_CursorPos
) override ) const override
{ {
if (m_BlockType == E_BLOCK_IRON_TRAPDOOR) if (m_BlockType == E_BLOCK_IRON_TRAPDOOR)
{ {
@ -65,7 +61,7 @@ public:
cPlayer & a_Player, cPlayer & a_Player,
const Vector3i a_BlockPos, const Vector3i a_BlockPos,
eBlockFace a_BlockFace eBlockFace a_BlockFace
) override ) const override
{ {
UNUSED(a_ChunkInterface); UNUSED(a_ChunkInterface);
a_WorldInterface.SendBlockTo(a_BlockPos, a_Player); a_WorldInterface.SendBlockTo(a_BlockPos, a_Player);
@ -82,7 +78,7 @@ public:
eBlockFace a_ClickedBlockFace, eBlockFace a_ClickedBlockFace,
const Vector3i a_CursorPos, const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override ) const override
{ {
a_BlockType = m_BlockType; a_BlockType = m_BlockType;
a_BlockMeta = BlockFaceToMetaData(a_ClickedBlockFace); a_BlockMeta = BlockFaceToMetaData(a_ClickedBlockFace);
@ -141,7 +137,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
switch (m_BlockType) switch (m_BlockType)

View File

@ -14,16 +14,11 @@ class cBlockTripwireHandler :
public: public:
cBlockTripwireHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{ {
return cItem(E_ITEM_STRING, 1, 0); return cItem(E_ITEM_STRING, 1, 0);
} }
@ -32,7 +27,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 0; return 0;

View File

@ -14,14 +14,21 @@ class cBlockTripwireHookHandler :
public: public:
cBlockTripwireHookHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
inline static eBlockFace MetadataToDirection(NIBBLETYPE a_Meta)
{ {
switch (a_Meta & 0x03)
{
case 0x1: return BLOCK_FACE_XM;
case 0x3: return BLOCK_FACE_XP;
case 0x2: return BLOCK_FACE_ZM;
case 0x0: return BLOCK_FACE_ZP;
default: ASSERT(!"Unhandled tripwire hook metadata!"); return BLOCK_FACE_NONE;
}
} }
private:
virtual bool GetPlacementBlockTypeMeta( virtual bool GetPlacementBlockTypeMeta(
cChunkInterface & a_ChunkInterface, cChunkInterface & a_ChunkInterface,
@ -30,7 +37,7 @@ public:
eBlockFace a_ClickedBlockFace, eBlockFace a_ClickedBlockFace,
const Vector3i a_CursorPos, const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override ) const override
{ {
a_BlockType = m_BlockType; a_BlockType = m_BlockType;
@ -71,23 +78,7 @@ public:
inline static eBlockFace MetadataToDirection(NIBBLETYPE a_Meta) virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) const override
{
switch (a_Meta & 0x03)
{
case 0x1: return BLOCK_FACE_XM;
case 0x3: return BLOCK_FACE_XP;
case 0x2: return BLOCK_FACE_ZM;
case 0x0: return BLOCK_FACE_ZP;
default: ASSERT(!"Unhandled tripwire hook metadata!"); return BLOCK_FACE_NONE;
}
}
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override
{ {
const auto Meta = a_Chunk.GetMeta(a_RelPos); const auto Meta = a_Chunk.GetMeta(a_RelPos);
const auto RearPosition = AddFaceDirection(a_RelPos, MetadataToDirection(Meta), true); const auto RearPosition = AddFaceDirection(a_RelPos, MetadataToDirection(Meta), true);
@ -105,7 +96,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 0; return 0;

View File

@ -13,14 +13,9 @@ class cBlockVineHandler :
public: public:
cBlockVineHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual bool GetPlacementBlockTypeMeta( virtual bool GetPlacementBlockTypeMeta(
cChunkInterface & a_ChunkInterface, cChunkInterface & a_ChunkInterface,
@ -29,7 +24,7 @@ public:
eBlockFace a_ClickedBlockFace, eBlockFace a_ClickedBlockFace,
const Vector3i a_CursorPos, const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override ) const override
{ {
// TODO: Disallow placement where the vine doesn't attach to something properly // TODO: Disallow placement where the vine doesn't attach to something properly
BLOCKTYPE BlockType = 0; BLOCKTYPE BlockType = 0;
@ -51,7 +46,7 @@ public:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
{ {
// Only drops self when using shears, otherwise drops nothing: // Only drops self when using shears, otherwise drops nothing:
if ((a_Tool == nullptr) || (a_Tool->m_ItemType != E_ITEM_SHEARS)) if ((a_Tool == nullptr) || (a_Tool->m_ItemType != E_ITEM_SHEARS))
@ -128,7 +123,7 @@ public:
/** Returns the meta that has the maximum allowable sides of the vine, given the surroundings */ /** Returns the meta that has the maximum allowable sides of the vine, given the surroundings */
NIBBLETYPE GetMaxMeta(cChunk & a_Chunk, Vector3i a_RelPos) static NIBBLETYPE GetMaxMeta(cChunk & a_Chunk, Vector3i a_RelPos)
{ {
static const struct static const struct
{ {
@ -162,7 +157,7 @@ public:
virtual void OnNeighborChanged(cChunkInterface & a_ChunkInterface, Vector3i a_BlockPos, eBlockFace a_WhichNeighbor) override virtual void OnNeighborChanged(cChunkInterface & a_ChunkInterface, Vector3i a_BlockPos, eBlockFace a_WhichNeighbor) const override
{ {
a_ChunkInterface.DoWithChunkAt(a_BlockPos, [&](cChunk & a_Chunk) a_ChunkInterface.DoWithChunkAt(a_BlockPos, [&](cChunk & a_Chunk)
{ {
@ -203,7 +198,7 @@ public:
virtual bool DoesIgnoreBuildCollision(cChunkInterface & a_ChunkInterface, Vector3i a_Pos, cPlayer & a_Player, NIBBLETYPE a_Meta) override virtual bool DoesIgnoreBuildCollision(cChunkInterface & a_ChunkInterface, Vector3i a_Pos, cPlayer & a_Player, NIBBLETYPE a_Meta) const override
{ {
return true; return true;
} }
@ -212,7 +207,7 @@ public:
virtual bool DoesDropOnUnsuitable(void) override virtual bool DoesDropOnUnsuitable(void) const override
{ {
return false; return false;
} }
@ -227,7 +222,7 @@ public:
cBlockPluginInterface & a_PluginInterface, cBlockPluginInterface & a_PluginInterface,
cChunk & a_Chunk, cChunk & a_Chunk,
const Vector3i a_RelPos const Vector3i a_RelPos
) override ) const override
{ {
UNUSED(a_ChunkInterface); UNUSED(a_ChunkInterface);
UNUSED(a_WorldInterface); UNUSED(a_WorldInterface);
@ -256,7 +251,7 @@ public:
virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) const override
{ {
return ((a_Meta >> 1) | (a_Meta << 3)) & 0x0f; // Rotate bits to the right return ((a_Meta >> 1) | (a_Meta << 3)) & 0x0f; // Rotate bits to the right
} }
@ -265,7 +260,7 @@ public:
virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) const override
{ {
return ((a_Meta << 1) | (a_Meta >> 3)) & 0x0f; // Rotate bits to the left return ((a_Meta << 1) | (a_Meta >> 3)) & 0x0f; // Rotate bits to the left
} }
@ -274,7 +269,7 @@ public:
virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) const override
{ {
// Bits 2 and 4 stay, bits 1 and 3 swap // Bits 2 and 4 stay, bits 1 and 3 swap
return static_cast<NIBBLETYPE>((a_Meta & 0x0a) | ((a_Meta & 0x01) << 2) | ((a_Meta & 0x04) >> 2)); return static_cast<NIBBLETYPE>((a_Meta & 0x0a) | ((a_Meta & 0x01) << 2) | ((a_Meta & 0x04) >> 2));
@ -284,7 +279,7 @@ public:
virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) const override
{ {
// Bits 1 and 3 stay, bits 2 and 4 swap // Bits 1 and 3 stay, bits 2 and 4 swap
return static_cast<NIBBLETYPE>((a_Meta & 0x05) | ((a_Meta & 0x02) << 2) | ((a_Meta & 0x08) >> 2)); return static_cast<NIBBLETYPE>((a_Meta & 0x05) | ((a_Meta & 0x02) << 2) | ((a_Meta & 0x08) >> 2));
@ -294,7 +289,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 7; return 7;

View File

@ -15,16 +15,30 @@ class cBlockWallSignHandler:
public: public:
cBlockWallSignHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
/** Converts the block face of the neighbor to which the wallsign is attached to the wallsign block's meta. */
static NIBBLETYPE BlockFaceToMetaData(eBlockFace a_NeighborBlockFace)
{ {
switch (a_NeighborBlockFace)
{
case BLOCK_FACE_ZM: return 0x02;
case BLOCK_FACE_ZP: return 0x03;
case BLOCK_FACE_XM: return 0x04;
case BLOCK_FACE_XP: return 0x05;
case BLOCK_FACE_NONE:
case BLOCK_FACE_YP:
case BLOCK_FACE_YM:
{
break;
}
}
return 0x02;
} }
private:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{ {
return cItem(E_ITEM_SIGN, 1, 0); return cItem(E_ITEM_SIGN, 1, 0);
} }
@ -33,7 +47,7 @@ public:
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) const override
{ {
auto NeighborPos = a_RelPos + GetOffsetBehindTheSign(a_Chunk.GetMeta(a_RelPos)); auto NeighborPos = a_RelPos + GetOffsetBehindTheSign(a_Chunk.GetMeta(a_RelPos));
BLOCKTYPE NeighborType; BLOCKTYPE NeighborType;
@ -68,30 +82,7 @@ public:
/** Converts the block face of the neighbor to which the wallsign is attached to the wallsign block's meta. */ virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
static NIBBLETYPE BlockFaceToMetaData(eBlockFace a_NeighborBlockFace)
{
switch (a_NeighborBlockFace)
{
case BLOCK_FACE_ZM: return 0x02;
case BLOCK_FACE_ZP: return 0x03;
case BLOCK_FACE_XM: return 0x04;
case BLOCK_FACE_XP: return 0x05;
case BLOCK_FACE_NONE:
case BLOCK_FACE_YP:
case BLOCK_FACE_YM:
{
break;
}
}
return 0x02;
}
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 13; return 13;

View File

@ -16,14 +16,9 @@ class cBlockWorkbenchHandler:
public: public:
cBlockWorkbenchHandler(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
private:
virtual bool OnUse( virtual bool OnUse(
cChunkInterface & a_ChunkInterface, cChunkInterface & a_ChunkInterface,
@ -32,7 +27,7 @@ public:
const Vector3i a_BlockPos, const Vector3i a_BlockPos,
eBlockFace a_BlockFace, eBlockFace a_BlockFace,
const Vector3i a_CursorPos const Vector3i a_CursorPos
) override ) const override
{ {
a_Player.GetStatManager().AddValue(Statistic::InteractWithCraftingTable); a_Player.GetStatManager().AddValue(Statistic::InteractWithCraftingTable);
@ -45,7 +40,7 @@ public:
virtual bool IsUseable(void) override virtual bool IsUseable(void) const override
{ {
return true; return true;
} }
@ -54,7 +49,7 @@ public:
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{ {
UNUSED(a_Meta); UNUSED(a_Meta);
return 13; return 13;

View File

@ -6,7 +6,6 @@
#include "WorldInterface.h" #include "WorldInterface.h"
#include "../ChunkMap.h" #include "../ChunkMap.h"
#include "../World.h" #include "../World.h"
#include "../BlockInfo.h"
@ -113,7 +112,7 @@ bool cChunkInterface::DigBlock(cWorldInterface & a_WorldInterface, Vector3i a_Bl
return false; return false;
} }
cBlockInfo::GetHandler(BlockType)->OnBroken(*this, a_WorldInterface, a_BlockPos, BlockType, BlockMeta); cBlockHandler::For(BlockType).OnBroken(*this, a_WorldInterface, a_BlockPos, BlockType, BlockMeta);
return true; return true;
} }

View File

@ -31,16 +31,14 @@ class cBlockWithNoDrops:
{ {
public: public:
cBlockWithNoDrops(BLOCKTYPE a_BlockType): constexpr cBlockWithNoDrops(BLOCKTYPE a_BlockType):
Base(a_BlockType) Base(a_BlockType)
{ {
} }
private:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{ {
// Don't drop anything: // Don't drop anything:
return {}; return {};
@ -58,16 +56,14 @@ class cClearMetaOnDrop:
{ {
public: public:
cClearMetaOnDrop(BLOCKTYPE a_BlockType): constexpr cClearMetaOnDrop(BLOCKTYPE a_BlockType):
Base(a_BlockType) Base(a_BlockType)
{ {
} }
private:
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{ {
// Reset the meta to zero: // Reset the meta to zero:
return cItem(this->m_BlockType); return cItem(this->m_BlockType);
@ -87,15 +83,14 @@ class cMetaRotator:
{ {
public: public:
cMetaRotator(BLOCKTYPE a_BlockType): constexpr cMetaRotator(BLOCKTYPE a_BlockType):
Base(a_BlockType) Base(a_BlockType)
{} {
}
protected:
virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) const override
virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override
{ {
NIBBLETYPE OtherMeta = a_Meta & (~BitMask); NIBBLETYPE OtherMeta = a_Meta & (~BitMask);
switch (a_Meta & BitMask) switch (a_Meta & BitMask)
@ -116,7 +111,7 @@ public:
virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) const override
{ {
NIBBLETYPE OtherMeta = a_Meta & (~BitMask); NIBBLETYPE OtherMeta = a_Meta & (~BitMask);
switch (a_Meta & BitMask) switch (a_Meta & BitMask)
@ -137,7 +132,7 @@ public:
virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) const override
{ {
NIBBLETYPE OtherMeta = a_Meta & (~BitMask); NIBBLETYPE OtherMeta = a_Meta & (~BitMask);
switch (a_Meta & BitMask) switch (a_Meta & BitMask)
@ -153,7 +148,7 @@ public:
virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) const override
{ {
NIBBLETYPE OtherMeta = a_Meta & (~BitMask); NIBBLETYPE OtherMeta = a_Meta & (~BitMask);
switch (a_Meta & BitMask) switch (a_Meta & BitMask)
@ -185,16 +180,12 @@ class cYawRotator:
public cMetaRotator<Base, BitMask, North, East, South, West, AssertIfNotMatched> public cMetaRotator<Base, BitMask, North, East, South, West, AssertIfNotMatched>
{ {
using Super = cMetaRotator<Base, BitMask, North, East, South, West, AssertIfNotMatched>; using Super = cMetaRotator<Base, BitMask, North, East, South, West, AssertIfNotMatched>;
public: public:
cYawRotator(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
public:
virtual bool GetPlacementBlockTypeMeta( virtual bool GetPlacementBlockTypeMeta(
cChunkInterface & a_ChunkInterface, cPlayer & a_Player, cChunkInterface & a_ChunkInterface, cPlayer & a_Player,
@ -202,7 +193,7 @@ public:
eBlockFace a_BlockFace, eBlockFace a_BlockFace,
const Vector3i a_CursorPos, const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override ) const override
{ {
NIBBLETYPE BaseMeta; NIBBLETYPE BaseMeta;
if (!Super::GetPlacementBlockTypeMeta(a_ChunkInterface, a_Player, a_BlockPos, a_BlockFace, a_CursorPos, a_BlockType, BaseMeta)) if (!Super::GetPlacementBlockTypeMeta(a_ChunkInterface, a_Player, a_BlockPos, a_BlockFace, a_CursorPos, a_BlockType, BaseMeta))
@ -264,14 +255,9 @@ class cPitchYawRotator:
public: public:
cPitchYawRotator(BLOCKTYPE a_BlockType): using Super::Super;
Super(a_BlockType)
{
}
protected:
virtual bool GetPlacementBlockTypeMeta( virtual bool GetPlacementBlockTypeMeta(
cChunkInterface & a_ChunkInterface, cChunkInterface & a_ChunkInterface,
@ -280,7 +266,7 @@ public:
eBlockFace a_ClickedBlockFace, eBlockFace a_ClickedBlockFace,
const Vector3i a_CursorPos, const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override ) const override
{ {
NIBBLETYPE BaseMeta; NIBBLETYPE BaseMeta;
if (!Super::GetPlacementBlockTypeMeta(a_ChunkInterface, a_Player, a_PlacedBlockPos, a_ClickedBlockFace, a_CursorPos, a_BlockType, BaseMeta)) if (!Super::GetPlacementBlockTypeMeta(a_ChunkInterface, a_Player, a_PlacedBlockPos, a_ClickedBlockFace, a_CursorPos, a_BlockType, BaseMeta))
@ -296,7 +282,7 @@ public:
virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) override virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) const override
{ {
NIBBLETYPE OtherMeta = a_Meta & (~BitMask); NIBBLETYPE OtherMeta = a_Meta & (~BitMask);
switch (a_Meta & BitMask) switch (a_Meta & BitMask)

Some files were not shown because too many files have changed in this diff Show More