summaryrefslogtreecommitdiffstats
path: root/src/Blocks
diff options
context:
space:
mode:
Diffstat (limited to 'src/Blocks')
-rw-r--r--src/Blocks/BlockAnvil.h33
-rw-r--r--src/Blocks/BlockBed.cpp150
-rw-r--r--src/Blocks/BlockBed.h28
-rw-r--r--src/Blocks/BlockBigFlower.h10
-rw-r--r--src/Blocks/BlockButton.h93
-rw-r--r--src/Blocks/BlockCactus.h23
-rw-r--r--src/Blocks/BlockCake.h15
-rw-r--r--src/Blocks/BlockCarpet.h16
-rw-r--r--src/Blocks/BlockCauldron.h21
-rw-r--r--src/Blocks/BlockChest.h27
-rw-r--r--src/Blocks/BlockCocoaPod.h13
-rw-r--r--src/Blocks/BlockComparator.h97
-rw-r--r--src/Blocks/BlockCrops.h6
-rw-r--r--src/Blocks/BlockDeadBush.h6
-rw-r--r--src/Blocks/BlockDoor.cpp44
-rw-r--r--src/Blocks/BlockDoor.h94
-rw-r--r--src/Blocks/BlockEnchantmentTable.h32
-rw-r--r--src/Blocks/BlockEndPortalFrame.h30
-rw-r--r--src/Blocks/BlockEntity.h11
-rw-r--r--src/Blocks/BlockFence.h48
-rw-r--r--src/Blocks/BlockFenceGate.h43
-rw-r--r--src/Blocks/BlockFlower.h17
-rw-r--r--src/Blocks/BlockGrass.h25
-rw-r--r--src/Blocks/BlockHandler.cpp17
-rw-r--r--src/Blocks/BlockHandler.h80
-rw-r--r--src/Blocks/BlockHopper.h10
-rw-r--r--src/Blocks/BlockLadder.h64
-rw-r--r--src/Blocks/BlockLever.h71
-rw-r--r--src/Blocks/BlockLilypad.h14
-rw-r--r--src/Blocks/BlockMobSpawner.h26
-rw-r--r--src/Blocks/BlockMushroom.h19
-rw-r--r--src/Blocks/BlockNetherWart.h6
-rw-r--r--src/Blocks/BlockPlanks.h26
-rw-r--r--src/Blocks/BlockPortal.h40
-rw-r--r--src/Blocks/BlockPressurePlate.h14
-rw-r--r--src/Blocks/BlockQuartz.h49
-rw-r--r--src/Blocks/BlockRail.h50
-rw-r--r--src/Blocks/BlockRedstone.h20
-rw-r--r--src/Blocks/BlockRedstoneOre.h32
-rw-r--r--src/Blocks/BlockRedstoneRepeater.h63
-rw-r--r--src/Blocks/BlockSapling.h4
-rw-r--r--src/Blocks/BlockSideways.h10
-rw-r--r--src/Blocks/BlockSignPost.h32
-rw-r--r--src/Blocks/BlockSlab.h42
-rw-r--r--src/Blocks/BlockSnow.h65
-rw-r--r--src/Blocks/BlockStairs.h50
-rw-r--r--src/Blocks/BlockStems.h4
-rw-r--r--src/Blocks/BlockSugarcane.h22
-rw-r--r--src/Blocks/BlockTNT.h25
-rw-r--r--src/Blocks/BlockTallGrass.h6
-rw-r--r--src/Blocks/BlockTorch.h112
-rw-r--r--src/Blocks/BlockTrapdoor.h57
-rw-r--r--src/Blocks/BlockTripwireHook.h29
-rw-r--r--src/Blocks/BlockVine.h14
-rw-r--r--src/Blocks/BlockWallSign.h36
-rw-r--r--src/Blocks/BlockWorkbench.h30
-rw-r--r--src/Blocks/Mixins.h24
-rw-r--r--src/Blocks/WorldInterface.h6
58 files changed, 1397 insertions, 654 deletions
diff --git a/src/Blocks/BlockAnvil.h b/src/Blocks/BlockAnvil.h
index f113f7905..ad6d216cd 100644
--- a/src/Blocks/BlockAnvil.h
+++ b/src/Blocks/BlockAnvil.h
@@ -35,21 +35,34 @@ public:
- virtual bool OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) 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
{
- cWindow * Window = new cAnvilWindow(a_BlockX, a_BlockY, a_BlockZ);
+ cWindow * Window = new cAnvilWindow(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z);
a_Player.OpenWindow(*Window);
return true;
}
+
+
+
+
virtual bool GetPlacementBlockTypeMeta(
- cChunkInterface & a_ChunkInterface, cPlayer & a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
- int a_CursorX, int a_CursorY, int a_CursorZ,
+ 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 (!Super::GetPlacementBlockTypeMeta(a_ChunkInterface, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, a_BlockType, a_BlockMeta))
+ if (!Super::GetPlacementBlockTypeMeta(a_ChunkInterface, a_Player, a_PlacedBlockPos, a_ClickedBlockFace, a_CursorPos, a_BlockType, a_BlockMeta))
{
return false;
}
@@ -58,11 +71,19 @@ public:
return true;
}
+
+
+
+
virtual bool IsUseable() override
{
return true;
}
+
+
+
+
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
{
UNUSED(a_Meta);
diff --git a/src/Blocks/BlockBed.cpp b/src/Blocks/BlockBed.cpp
index 8b349ef5e..6d50e8c41 100644
--- a/src/Blocks/BlockBed.cpp
+++ b/src/Blocks/BlockBed.cpp
@@ -15,7 +15,11 @@
-void cBlockBedHandler::OnBroken(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, Vector3i a_BlockPos, BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta)
+void cBlockBedHandler::OnBroken(
+ cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
+ const Vector3i a_BlockPos,
+ BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta
+)
{
auto Direction = MetaDataToDirection(a_OldBlockMeta & 0x03);
if ((a_OldBlockMeta & 0x08) != 0)
@@ -50,87 +54,97 @@ void cBlockBedHandler::OnBroken(cChunkInterface & a_ChunkInterface, cWorldInterf
-bool cBlockBedHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ)
+bool cBlockBedHandler::OnUse(
+ cChunkInterface & a_ChunkInterface,
+ cWorldInterface & a_WorldInterface,
+ cPlayer & a_Player,
+ const Vector3i a_BlockPos,
+ eBlockFace a_BlockFace,
+ const Vector3i a_CursorPos
+)
{
- Vector3i Coords(a_BlockX, a_BlockY, a_BlockZ);
+ // Sleeping in bed only allowed in Overworld, beds explode elsewhere:
if (a_WorldInterface.GetDimension() != dimOverworld)
{
- a_WorldInterface.DoExplosionAt(5, a_BlockX, a_BlockY, a_BlockZ, true, esBed, &Coords);
+ auto PosCopy = a_BlockPos;
+ a_WorldInterface.DoExplosionAt(5, a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, true, esBed, &PosCopy);
+ return true;
}
- else if (!((a_WorldInterface.GetTimeOfDay() > 12541) && (a_WorldInterface.GetTimeOfDay() < 23458))) // Source: https://minecraft.gamepedia.com/Bed#Sleeping
+
+ // Sleeping is allowed only during night:
+ // TODO: Also during thunderstorms
+ if (!((a_WorldInterface.GetTimeOfDay() > 12541) && (a_WorldInterface.GetTimeOfDay() < 23458))) // Source: https://minecraft.gamepedia.com/Bed#Sleeping
{
a_Player.SendMessageFailure("You can only sleep at night");
+ return true;
+ }
+
+ // Check if the bed is occupied:
+ auto Meta = a_ChunkInterface.GetBlockMeta(a_BlockPos);
+ if ((Meta & 0x04) == 0x04)
+ {
+ a_Player.SendMessageFailure("This bed is occupied");
+ return true;
+ }
+
+ // Cannot sleep if there are hostile mobs nearby:
+ auto FindMobs = [](cEntity & a_Entity)
+ {
+ return (
+ (a_Entity.GetEntityType() == cEntity::etMonster) &&
+ (static_cast<cMonster&>(a_Entity).GetMobFamily() == cMonster::mfHostile)
+ );
+ };
+ if (!a_Player.GetWorld()->ForEachEntityInBox(cBoundingBox(a_Player.GetPosition() - Vector3i(0, 5, 0), 8, 10), FindMobs))
+ {
+ a_Player.SendMessageFailure("You may not rest now, there are monsters nearby");
+ return true;
+ }
+
+ // Broadcast the "Use bed" for the pillow block:
+ if ((Meta & 0x8) == 0x8)
+ {
+ // Is pillow
+ a_WorldInterface.GetBroadcastManager().BroadcastUseBed(a_Player, a_BlockPos);
}
else
{
- NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(Coords);
- if ((Meta & 0x4) == 0x4)
+ // Is foot end
+ VERIFY((Meta & 0x04) != 0x04); // Occupied flag should never be set, else our compilator (intended) is broken
+
+ auto PillowPos = a_BlockPos + MetaDataToDirection(Meta & 0x03);
+ if (a_ChunkInterface.GetBlock(PillowPos) == E_BLOCK_BED) // Must always use pillow location for sleeping
{
- a_Player.SendMessageFailure("This bed is occupied");
+ a_WorldInterface.GetBroadcastManager().BroadcastUseBed(a_Player, PillowPos);
}
- else
- {
- auto FindMobs = [](cEntity & a_Entity)
- {
- return (
- (a_Entity.GetEntityType() == cEntity::etMonster) &&
- (static_cast<cMonster&>(a_Entity).GetMobFamily() == cMonster::mfHostile)
- );
- };
+ }
- if (!a_Player.GetWorld()->ForEachEntityInBox(cBoundingBox(a_Player.GetPosition() - Vector3i(0, 5, 0), 8, 10), FindMobs))
- {
- a_Player.SendMessageFailure("You may not rest now, there are monsters nearby");
- }
- else
+ // Occupy the bed:
+ a_Player.SetBedPos(a_BlockPos);
+ SetBedOccupationState(a_ChunkInterface, a_Player.GetLastBedPos(), true);
+ a_Player.SetIsInBed(true);
+ a_Player.SendMessageSuccess("Home position set successfully");
+
+ // Fast-forward the time if all players in the world are in their beds:
+ auto TimeFastForwardTester = [](cPlayer & a_OtherPlayer)
+ {
+ if (!a_OtherPlayer.IsInBed())
+ {
+ return true;
+ }
+ return false;
+ };
+ if (a_WorldInterface.ForEachPlayer(TimeFastForwardTester))
+ {
+ a_WorldInterface.ForEachPlayer([&](cPlayer & a_OtherPlayer)
{
- Vector3i PillowDirection(0, 0, 0);
-
- if ((Meta & 0x8) == 0x8)
- {
- // Is pillow
- a_WorldInterface.GetBroadcastManager().BroadcastUseBed(a_Player, { a_BlockX, a_BlockY, a_BlockZ });
- }
- else
- {
- // Is foot end
- VERIFY((Meta & 0x4) != 0x4); // Occupied flag should never be set, else our compilator (intended) is broken
-
- PillowDirection = MetaDataToDirection(Meta & 0x3);
- if (a_ChunkInterface.GetBlock(Coords + PillowDirection) == E_BLOCK_BED) // Must always use pillow location for sleeping
- {
- a_WorldInterface.GetBroadcastManager().BroadcastUseBed(a_Player, Vector3i{a_BlockX, a_BlockY, a_BlockZ} + PillowDirection);
- }
- }
-
- a_Player.SetBedPos(Coords);
- SetBedOccupationState(a_ChunkInterface, a_Player.GetLastBedPos(), true);
- a_Player.SetIsInBed(true);
- a_Player.SendMessageSuccess("Home position set successfully");
-
- auto TimeFastForwardTester = [](cPlayer & a_OtherPlayer)
- {
- if (!a_OtherPlayer.IsInBed())
- {
- return true;
- }
- return false;
- };
-
- if (a_WorldInterface.ForEachPlayer(TimeFastForwardTester))
- {
- a_WorldInterface.ForEachPlayer([&](cPlayer & a_OtherPlayer)
- {
- cBlockBedHandler::SetBedOccupationState(a_ChunkInterface, a_OtherPlayer.GetLastBedPos(), false);
- a_OtherPlayer.SetIsInBed(false);
- return false;
- }
- );
- a_WorldInterface.SetTimeOfDay(0);
- a_ChunkInterface.SetBlockMeta({a_BlockX, a_BlockY, a_BlockZ}, Meta & 0x0b); // Clear the "occupied" bit of the bed's block
- }
+ cBlockBedHandler::SetBedOccupationState(a_ChunkInterface, a_OtherPlayer.GetLastBedPos(), false);
+ a_OtherPlayer.SetIsInBed(false);
+ return false;
}
- }
+ );
+ a_WorldInterface.SetTimeOfDay(0);
+ a_ChunkInterface.SetBlockMeta(a_BlockPos, Meta & 0x0b); // Clear the "occupied" bit of the bed's block
}
return true;
}
diff --git a/src/Blocks/BlockBed.h b/src/Blocks/BlockBed.h
index 6793585b8..418d44ca5 100644
--- a/src/Blocks/BlockBed.h
+++ b/src/Blocks/BlockBed.h
@@ -32,10 +32,30 @@ public:
// Overrides:
- 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, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) 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;
+ 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;
diff --git a/src/Blocks/BlockBigFlower.h b/src/Blocks/BlockBigFlower.h
index e7bd9b957..150ae6633 100644
--- a/src/Blocks/BlockBigFlower.h
+++ b/src/Blocks/BlockBigFlower.h
@@ -9,7 +9,7 @@
-class cBlockBigFlowerHandler :
+class cBlockBigFlowerHandler:
public cBlockHandler
{
using Super = cBlockHandler;
@@ -95,15 +95,15 @@ public:
- virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override
{
- if (a_RelY <= 0)
+ if (a_RelPos.y <= 0)
{
return false;
}
BLOCKTYPE BlockType;
NIBBLETYPE BlockMeta;
- a_Chunk.GetBlockTypeMeta(a_RelX, a_RelY - 1, a_RelZ, BlockType, BlockMeta);
+ a_Chunk.GetBlockTypeMeta(a_RelPos.addedY(-1), BlockType, BlockMeta);
return IsBlockTypeOfDirt(BlockType) || ((BlockType == E_BLOCK_BIG_FLOWER) && !IsMetaTopPart(BlockMeta));
}
@@ -112,7 +112,7 @@ public:
- virtual void OnBroken(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, 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) override
{
if ((a_OldBlockMeta & 0x8) != 0)
{
diff --git a/src/Blocks/BlockButton.h b/src/Blocks/BlockButton.h
index c09dec56c..945c39b03 100644
--- a/src/Blocks/BlockButton.h
+++ b/src/Blocks/BlockButton.h
@@ -24,36 +24,40 @@ public:
- virtual bool OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) 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
{
- Vector3i Pos(a_BlockX, a_BlockY, a_BlockZ);
- NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(Pos);
-
- Vector3d SoundPos(Pos);
+ NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockPos);
- // If button is already on do nothing
+ // If button is already on, do nothing:
if (Meta & 0x08)
{
return false;
}
- // Set p the ON bit to on
+ // Set the ON bit to on
Meta |= 0x08;
- a_ChunkInterface.SetBlockMeta({a_BlockX, a_BlockY, a_BlockZ}, Meta, false);
- a_WorldInterface.WakeUpSimulators(Pos);
- a_WorldInterface.GetBroadcastManager().BroadcastSoundEffect("block.stone_button.click_on", SoundPos, 0.5f, 0.6f);
+ a_ChunkInterface.SetBlockMeta(a_BlockPos, Meta, false);
+ a_WorldInterface.WakeUpSimulators(a_BlockPos);
+ a_WorldInterface.GetBroadcastManager().BroadcastSoundEffect("block.stone_button.click_on", a_BlockPos, 0.5f, 0.6f);
// Queue a button reset (unpress)
auto TickDelay = (m_BlockType == E_BLOCK_STONE_BUTTON) ? 20 : 30;
- a_Player.GetWorld()->ScheduleTask(TickDelay, [SoundPos, Pos, this](cWorld & a_World)
+ a_Player.GetWorld()->ScheduleTask(TickDelay, [a_BlockPos, this](cWorld & a_World)
{
- if (a_World.GetBlock(Pos) == m_BlockType)
+ if (a_World.GetBlock(a_BlockPos) == m_BlockType)
{
// Block hasn't change in the meantime; set its meta
- a_World.SetBlockMeta(Pos.x, Pos.y, Pos.z, a_World.GetBlockMeta(Pos) & 0x07, false);
- a_World.WakeUpSimulators(Pos);
- a_World.BroadcastSoundEffect("block.stone_button.click_off", SoundPos, 0.5f, 0.5f);
+ a_World.SetBlockMeta(a_BlockPos, a_World.GetBlockMeta(a_BlockPos) & 0x07, false);
+ a_World.WakeUpSimulators(a_BlockPos);
+ a_World.BroadcastSoundEffect("block.stone_button.click_off", a_BlockPos, 0.5f, 0.5f);
}
}
);
@@ -61,23 +65,38 @@ public:
return true;
}
+
+
+
+
virtual bool IsUseable(void) override
{
return true;
}
+
+
+
+
virtual bool GetPlacementBlockTypeMeta(
- cChunkInterface & a_ChunkInterface, cPlayer & a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
- int a_CursorX, int a_CursorY, int a_CursorZ,
+ cChunkInterface & a_ChunkInterface,
+ cPlayer & a_Player,
+ const Vector3i a_PlacedBlockPos,
+ eBlockFace a_ClickedBlockFace,
+ const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{
a_BlockType = m_BlockType;
- a_BlockMeta = BlockFaceToMetaData(a_BlockFace);
+ a_BlockMeta = BlockFaceToMetaData(a_ClickedBlockFace);
return true;
}
+
+
+
+
+ /** Converts the block face of the neighbor to which the button is attached, to the block meta for this button. */
inline static NIBBLETYPE BlockFaceToMetaData(eBlockFace a_BlockFace)
{
switch (a_BlockFace)
@@ -97,6 +116,11 @@ public:
UNREACHABLE("Unsupported block face");
}
+
+
+
+
+ /** Converts the block meta of this button into a block face of the neighbor to which the button is attached. */
inline static eBlockFace BlockMetaDataToBlockFace(NIBBLETYPE a_Meta)
{
switch (a_Meta & 0x7)
@@ -115,24 +139,39 @@ public:
}
}
- virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
- {
- NIBBLETYPE Meta;
- a_Chunk.UnboundedRelGetBlockMeta(a_RelX, a_RelY, a_RelZ, Meta);
- AddFaceDirection(a_RelX, a_RelY, a_RelZ, BlockMetaDataToBlockFace(Meta), true);
- BLOCKTYPE BlockIsOn; a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockIsOn);
- return (a_RelY > 0) && (cBlockInfo::FullyOccupiesVoxel(BlockIsOn));
+
+
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override
+ {
+ auto Meta = a_Chunk.GetMeta(a_RelPos);
+ auto SupportRelPos = AddFaceDirection(a_RelPos, BlockMetaDataToBlockFace(Meta), true);
+ if (!cChunkDef::IsValidHeight(SupportRelPos.y))
+ {
+ return false;
+ }
+ BLOCKTYPE SupportBlockType;
+ a_Chunk.UnboundedRelGetBlockType(SupportRelPos, SupportBlockType);
+
+ return cBlockInfo::FullyOccupiesVoxel(SupportBlockType);
}
+
+
+
+
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
{
UNUSED(a_Meta);
return 0;
}
- /** Extracts the ON bit from metadata and returns if true if it is set */
+
+
+
+
+ /** Extracts the ON bit from metadata. */
static bool IsButtonOn(NIBBLETYPE a_BlockMeta)
{
return ((a_BlockMeta & 0x8) == 0x8);
diff --git a/src/Blocks/BlockCactus.h b/src/Blocks/BlockCactus.h
index db65ea15f..0c3577898 100644
--- a/src/Blocks/BlockCactus.h
+++ b/src/Blocks/BlockCactus.h
@@ -23,13 +23,13 @@ public:
- virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override
{
- if (a_RelY <= 0)
+ if (a_RelPos.y <= 0)
{
return false;
}
- BLOCKTYPE Surface = a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ);
+ BLOCKTYPE Surface = a_Chunk.GetBlock(a_RelPos.addedY(-1));
if ((Surface != E_BLOCK_SAND) && (Surface != E_BLOCK_CACTUS))
{
// Cactus can only be placed on sand and itself
@@ -37,22 +37,19 @@ public:
}
// Check surroundings. Cacti may ONLY be surrounded by non-solid blocks
- static const struct
+ static const Vector3i Coords[] =
{
- int x, z;
- } Coords[] =
- {
- {-1, 0},
- { 1, 0},
- { 0, -1},
- { 0, 1},
- } ;
+ {-1, 0, 0},
+ { 1, 0, 0},
+ { 0, 0, -1},
+ { 0, 0, 1},
+ };
for (size_t i = 0; i < ARRAYCOUNT(Coords); i++)
{
BLOCKTYPE BlockType;
NIBBLETYPE BlockMeta;
if (
- a_Chunk.UnboundedRelGetBlock(a_RelX + Coords[i].x, a_RelY, a_RelZ + Coords[i].z, BlockType, BlockMeta) &&
+ a_Chunk.UnboundedRelGetBlock(a_RelPos + Coords[i], BlockType, BlockMeta) &&
(
cBlockInfo::IsSolid(BlockType) ||
(BlockType == E_BLOCK_LAVA) ||
diff --git a/src/Blocks/BlockCake.h b/src/Blocks/BlockCake.h
index e30a79db1..dbcce5f17 100644
--- a/src/Blocks/BlockCake.h
+++ b/src/Blocks/BlockCake.h
@@ -20,9 +20,16 @@ public:
- virtual bool OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) 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
{
- NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta({a_BlockX, a_BlockY, a_BlockZ});
+ NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockPos);
if (!a_Player.Feed(2, 0.4))
{
@@ -31,11 +38,11 @@ public:
if (Meta >= 5)
{
- a_ChunkInterface.DigBlock(a_WorldInterface, {a_BlockX, a_BlockY, a_BlockZ});
+ a_ChunkInterface.DigBlock(a_WorldInterface, a_BlockPos);
}
else
{
- a_ChunkInterface.SetBlockMeta({a_BlockX, a_BlockY, a_BlockZ}, Meta + 1);
+ a_ChunkInterface.SetBlockMeta(a_BlockPos, Meta + 1);
}
return true;
}
diff --git a/src/Blocks/BlockCarpet.h b/src/Blocks/BlockCarpet.h
index 9f315caa8..41e84c47b 100644
--- a/src/Blocks/BlockCarpet.h
+++ b/src/Blocks/BlockCarpet.h
@@ -14,14 +14,14 @@
-class cBlockCarpetHandler :
+class cBlockCarpetHandler:
public cBlockHandler
{
using Super = cBlockHandler;
public:
- cBlockCarpetHandler(BLOCKTYPE a_BlockType) :
+ cBlockCarpetHandler(BLOCKTYPE a_BlockType):
Super(a_BlockType)
{
}
@@ -31,9 +31,11 @@ public:
virtual bool GetPlacementBlockTypeMeta(
- cChunkInterface & a_ChunkInterface, cPlayer & a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
- int a_CursorX, int a_CursorY, int a_CursorZ,
+ cChunkInterface & a_ChunkInterface,
+ cPlayer & a_Player,
+ const Vector3i a_PlacedBlockPos,
+ eBlockFace a_ClickedBlockFace,
+ const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{
@@ -46,9 +48,9 @@ public:
- virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override
{
- return (a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) != E_BLOCK_AIR);
+ return (a_RelPos.y > 0) && (a_Chunk.GetBlock(a_RelPos.addedY(-1)) != E_BLOCK_AIR);
}
diff --git a/src/Blocks/BlockCauldron.h b/src/Blocks/BlockCauldron.h
index 28c1dfda8..da7c43860 100644
--- a/src/Blocks/BlockCauldron.h
+++ b/src/Blocks/BlockCauldron.h
@@ -32,9 +32,16 @@ public:
- virtual bool OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) 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
{
- NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta({a_BlockX, a_BlockY, a_BlockZ});
+ NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockPos);
auto EquippedItem = a_Player.GetEquippedItem();
switch (EquippedItem.m_ItemType)
{
@@ -42,7 +49,7 @@ public:
{
if (Meta == 3)
{
- a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, 0);
+ a_ChunkInterface.SetBlockMeta(a_BlockPos, 0);
// Give new bucket, filled with fluid when the gamemode is not creative:
if (!a_Player.IsGameModeCreative())
{
@@ -55,7 +62,7 @@ public:
{
if (Meta < 3)
{
- a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, 3);
+ a_ChunkInterface.SetBlockMeta(a_BlockPos, 3);
// Give empty bucket back when the gamemode is not creative:
if (!a_Player.IsGameModeCreative())
{
@@ -68,7 +75,7 @@ public:
{
if (Meta > 0)
{
- a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, --Meta);
+ a_ChunkInterface.SetBlockMeta(a_BlockPos, --Meta);
// Give new potion when the gamemode is not creative:
if (!a_Player.IsGameModeCreative())
{
@@ -82,8 +89,8 @@ public:
// Refill cauldron with water bottles.
if ((Meta < 3) && (EquippedItem.m_ItemDamage == 0))
{
- a_ChunkInterface.SetBlockMeta(Vector3i(a_BlockX, a_BlockY, a_BlockZ), ++Meta);
- // Give empty bottle when the gamemode is not creative:
+ a_ChunkInterface.SetBlockMeta(Vector3i(a_BlockPos), ++Meta);
+ // Give back an empty bottle when the gamemode is not creative:
if (!a_Player.IsGameModeCreative())
{
a_Player.ReplaceOneEquippedItemTossRest(cItem(E_ITEM_GLASS_BOTTLE));
diff --git a/src/Blocks/BlockChest.h b/src/Blocks/BlockChest.h
index aeb687abb..d28ea81fd 100644
--- a/src/Blocks/BlockChest.h
+++ b/src/Blocks/BlockChest.h
@@ -27,14 +27,16 @@ public:
virtual bool GetPlacementBlockTypeMeta(
- cChunkInterface & a_ChunkInterface, cPlayer & a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
- int a_CursorX, int a_CursorY, int a_CursorZ,
+ cChunkInterface & a_ChunkInterface,
+ cPlayer & a_Player,
+ const Vector3i a_PlacedBlockPos,
+ eBlockFace a_ClickedBlockFace,
+ const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{
- // Is there a doublechest already next to this block?
- if (!CanBeAt(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ))
+ // Cannot place right next to double-chest:
+ if (!CanBeAt(a_ChunkInterface, a_PlacedBlockPos))
{
// Yup, cannot form a triple-chest, refuse:
return false;
@@ -42,13 +44,13 @@ public:
// Try to read double-chest information:
cBlockArea Area;
- if (!Area.Read(a_ChunkInterface, a_BlockX - 1, a_BlockX + 1, a_BlockY, a_BlockY, a_BlockZ - 1, a_BlockZ + 1))
+ if (!Area.Read(a_ChunkInterface, a_PlacedBlockPos - Vector3i(1, 0, 1), a_PlacedBlockPos + Vector3i(1, 0, 1)))
{
return false;
}
// Get meta as if this was a single-chest:
- if (!Super::GetPlacementBlockTypeMeta(a_ChunkInterface, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, a_BlockType, a_BlockMeta))
+ if (!Super::GetPlacementBlockTypeMeta(a_ChunkInterface, a_Player, a_PlacedBlockPos, a_ClickedBlockFace, a_CursorPos, a_BlockType, a_BlockMeta))
{
return false;
}
@@ -80,21 +82,20 @@ public:
- virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override
{
- int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width;
- int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width;
- return CanBeAt(a_ChunkInterface, BlockX, a_RelY, BlockZ);
+ auto BlockPos = a_Chunk.RelativeToAbsolute(a_RelPos);
+ return CanBeAt(a_ChunkInterface, BlockPos);
}
- virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ)
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_BlockPos)
{
cBlockArea Area;
- if (!Area.Read(a_ChunkInterface, a_BlockX - 2, a_BlockX + 2, a_BlockY, a_BlockY, a_BlockZ - 2, a_BlockZ + 2))
+ if (!Area.Read(a_ChunkInterface, a_BlockPos - Vector3i(2, 0, 2), a_BlockPos + Vector3i(2, 0, 2)))
{
// Cannot read the surroundings, probably at the edge of loaded chunks. Disallow.
return false;
diff --git a/src/Blocks/BlockCocoaPod.h b/src/Blocks/BlockCocoaPod.h
index 74b7c3caa..955a2e3fc 100644
--- a/src/Blocks/BlockCocoaPod.h
+++ b/src/Blocks/BlockCocoaPod.h
@@ -22,16 +22,15 @@ public:
- virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override
{
- eBlockFace BlockFace = MetaToBlockFace(a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ));
- AddFaceDirection(a_RelX, a_RelY, a_RelZ, BlockFace, true);
-
+ // Check that we're attached to a jungle log block:
+ eBlockFace BlockFace = MetaToBlockFace(a_Chunk.GetMeta(a_RelPos));
+ auto LogPos = AddFaceDirection(a_RelPos, BlockFace, true);
BLOCKTYPE BlockType;
NIBBLETYPE BlockMeta;
- a_Chunk.UnboundedRelGetBlock(a_RelX, a_RelY, a_RelZ, BlockType, BlockMeta);
-
- return ((BlockType == E_BLOCK_LOG) && ((BlockMeta & 0x3) == E_META_LOG_JUNGLE));
+ a_Chunk.UnboundedRelGetBlock(LogPos, BlockType, BlockMeta);
+ return ((BlockType == E_BLOCK_LOG) && ((BlockMeta & 0x03) == E_META_LOG_JUNGLE));
}
diff --git a/src/Blocks/BlockComparator.h b/src/Blocks/BlockComparator.h
index 5e6b3eaa6..a2f2d430d 100644
--- a/src/Blocks/BlockComparator.h
+++ b/src/Blocks/BlockComparator.h
@@ -21,45 +21,114 @@ public:
{
}
- virtual bool OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) 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
{
- NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta({a_BlockX, a_BlockY, a_BlockZ});
- Meta ^= 0x04; // Toggle 3rd (addition / subtraction) bit with XOR
- a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta);
+ // Toggle the 3rd bit (addition / subtraction):
+ NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockPos);
+ Meta ^= 0x04;
+ a_ChunkInterface.SetBlockMeta(a_BlockPos, Meta);
return true;
}
- virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override
+
+
+
+
+ virtual void OnCancelRightClick(
+ cChunkInterface & a_ChunkInterface,
+ cWorldInterface & a_WorldInterface,
+ cPlayer & a_Player,
+ const Vector3i a_BlockPos,
+ eBlockFace a_BlockFace
+ ) override
{
UNUSED(a_ChunkInterface);
- a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player);
+ UNUSED(a_BlockFace);
+
+ a_WorldInterface.SendBlockTo(a_BlockPos, a_Player);
}
+
+
+
+
virtual bool IsUseable(void) override
{
return true;
}
- virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+
+
+
+
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override
{
- return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) != E_BLOCK_AIR));
+ 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)
{
return ((a_Meta & 0x4) == 0x4);
}
+
+
+
+
inline static bool IsOn(NIBBLETYPE a_Meta)
{
return ((a_Meta & 0x8) == 0x8);
}
+
+
+
+
inline static Vector3i GetSideCoordinate(Vector3i a_Position, NIBBLETYPE a_Meta, bool a_bInverse)
{
if (!a_bInverse)
@@ -98,6 +167,10 @@ public:
return a_Position;
}
+
+
+
+
inline static Vector3i GetRearCoordinate(Vector3i a_Position, NIBBLETYPE a_Meta)
{
switch (a_Meta)
@@ -117,6 +190,10 @@ public:
return a_Position;
}
+
+
+
+
inline static Vector3i GetFrontCoordinate(Vector3i a_Position, NIBBLETYPE a_Meta)
{
switch (a_Meta)
@@ -136,6 +213,10 @@ public:
return a_Position;
}
+
+
+
+
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
{
UNUSED(a_Meta);
diff --git a/src/Blocks/BlockCrops.h b/src/Blocks/BlockCrops.h
index 4622d1ad5..05bb0d2f1 100644
--- a/src/Blocks/BlockCrops.h
+++ b/src/Blocks/BlockCrops.h
@@ -108,13 +108,15 @@ public:
- virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override
{
- return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) == E_BLOCK_FARMLAND));
+ return ((a_RelPos.y > 0) && (a_Chunk.GetBlock(a_RelPos.addedY(-1)) == E_BLOCK_FARMLAND));
}
+
+
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
{
UNUSED(a_Meta);
diff --git a/src/Blocks/BlockDeadBush.h b/src/Blocks/BlockDeadBush.h
index 52c9ac594..9eb0c8e84 100644
--- a/src/Blocks/BlockDeadBush.h
+++ b/src/Blocks/BlockDeadBush.h
@@ -31,14 +31,14 @@ public:
- virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override
{
- if (a_RelY <= 0)
+ if (a_RelPos.y <= 0)
{
return false;
}
- BLOCKTYPE BelowBlock = a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ);
+ BLOCKTYPE BelowBlock = a_Chunk.GetBlock(a_RelPos.addedY(-1));
switch (BelowBlock)
{
case E_BLOCK_CLAY:
diff --git a/src/Blocks/BlockDoor.cpp b/src/Blocks/BlockDoor.cpp
index bb694e5b2..fcc4ddbe6 100644
--- a/src/Blocks/BlockDoor.cpp
+++ b/src/Blocks/BlockDoor.cpp
@@ -40,15 +40,20 @@ void cBlockDoorHandler::OnBroken(cChunkInterface & a_ChunkInterface, cWorldInter
-bool cBlockDoorHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ)
+bool cBlockDoorHandler::OnUse(
+ cChunkInterface & a_ChunkInterface,
+ cWorldInterface & a_WorldInterface,
+ cPlayer & a_Player,
+ const Vector3i a_BlockPos,
+ eBlockFace a_BlockFace,
+ const Vector3i a_CursorPos
+)
{
UNUSED(a_WorldInterface);
UNUSED(a_BlockFace);
- UNUSED(a_CursorX);
- UNUSED(a_CursorY);
- UNUSED(a_CursorZ);
+ UNUSED(a_CursorPos);
- switch (a_ChunkInterface.GetBlock({a_BlockX, a_BlockY, a_BlockZ}))
+ switch (a_ChunkInterface.GetBlock(a_BlockPos))
{
default:
{
@@ -61,14 +66,14 @@ bool cBlockDoorHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterfac
case E_BLOCK_SPRUCE_DOOR:
case E_BLOCK_OAK_DOOR:
{
- ChangeDoor(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ);
- a_Player.GetWorld()->BroadcastSoundParticleEffect(EffectID::SFX_RANDOM_WOODEN_DOOR_OPEN, {a_BlockX, a_BlockY, a_BlockZ}, 0, a_Player.GetClientHandle());
+ ChangeDoor(a_ChunkInterface, a_BlockPos);
+ a_Player.GetWorld()->BroadcastSoundParticleEffect(EffectID::SFX_RANDOM_WOODEN_DOOR_OPEN, a_BlockPos, 0, a_Player.GetClientHandle());
break;
}
// Prevent iron door from opening on player click
case E_BLOCK_IRON_DOOR:
{
- OnCancelRightClick(a_ChunkInterface, a_WorldInterface, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
+ OnCancelRightClick(a_ChunkInterface, a_WorldInterface, a_Player, a_BlockPos, a_BlockFace);
break;
}
}
@@ -80,22 +85,29 @@ bool cBlockDoorHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterfac
-void cBlockDoorHandler::OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace)
+void cBlockDoorHandler::OnCancelRightClick(
+ cChunkInterface & a_ChunkInterface,
+ cWorldInterface & a_WorldInterface,
+ cPlayer & a_Player,
+ const Vector3i a_BlockPos,
+ eBlockFace a_BlockFace
+)
{
UNUSED(a_ChunkInterface);
+ UNUSED(a_BlockFace);
- a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player);
- NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta({a_BlockX, a_BlockY, a_BlockZ});
+ a_WorldInterface.SendBlockTo(a_BlockPos, a_Player);
+ NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockPos);
- if (Meta & 0x8)
+ if (Meta & 0x08)
{
- // Current block is top of the door
- a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY - 1, a_BlockZ, a_Player);
+ // Current block is top of the door, send the bottom part:
+ a_WorldInterface.SendBlockTo(a_BlockPos.addedY(-1), a_Player);
}
else
{
- // Current block is bottom of the door
- a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY + 1, a_BlockZ, a_Player);
+ // Current block is bottom of the door, send the top part:
+ a_WorldInterface.SendBlockTo(a_BlockPos.addedY(1), a_Player);
}
}
diff --git a/src/Blocks/BlockDoor.h b/src/Blocks/BlockDoor.h
index 48c761d05..a32649961 100644
--- a/src/Blocks/BlockDoor.h
+++ b/src/Blocks/BlockDoor.h
@@ -20,37 +20,63 @@ public:
cBlockDoorHandler(BLOCKTYPE a_BlockType);
- 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, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override;
- virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override;
+ virtual 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,
- int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
- int a_CursorX, int a_CursorY, int a_CursorZ,
+ 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:
- if (a_BlockFace == BLOCK_FACE_BOTTOM)
+ auto PlacedPos = a_PlacedBlockPos;
+ if (a_ClickedBlockFace == BLOCK_FACE_BOTTOM)
{
- a_BlockY--;
+ PlacedPos.y--;
}
if (
- !CanReplaceBlock(a_ChunkInterface.GetBlock({a_BlockX, a_BlockY, a_BlockZ})) ||
- !CanReplaceBlock(a_ChunkInterface.GetBlock({a_BlockX, a_BlockY + 1, a_BlockZ}))
+ !CanReplaceBlock(a_ChunkInterface.GetBlock(PlacedPos)) ||
+ !CanReplaceBlock(a_ChunkInterface.GetBlock(PlacedPos.addedY(1)))
)
{
return false;
}
- return Super::GetPlacementBlockTypeMeta(a_ChunkInterface, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, a_BlockType, a_BlockMeta);
+ 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;
@@ -93,11 +119,19 @@ public:
return true;
}
- virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+
+
+
+
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override
{
- return ((a_RelY > 0) && CanBeOn(a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ), a_Chunk.GetMeta(a_RelX, a_RelY - 1, a_RelZ)));
+ 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. */
static bool CanBeOn(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
{
@@ -188,9 +222,9 @@ public:
/** Returns true iff the door at the specified coords is open.
The coords may point to either the top part or the bottom part of the door. */
- static NIBBLETYPE IsOpen(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ)
+ static NIBBLETYPE IsOpen(cChunkInterface & a_ChunkInterface, const Vector3i a_BlockPos)
{
- NIBBLETYPE Meta = GetCompleteDoorMeta(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ);
+ NIBBLETYPE Meta = GetCompleteDoorMeta(a_ChunkInterface, a_BlockPos);
return ((Meta & 0x04) != 0);
}
@@ -201,17 +235,17 @@ public:
/** Returns the complete meta composed from the both parts of the door as (TopMeta << 4) | BottomMeta
The coords may point to either part of the door.
The returned value has bit 3 (0x08) set iff the coords point to the top part of the door.
- Fails gracefully for (invalid) doors on the world's top and bottom. */
- static NIBBLETYPE GetCompleteDoorMeta(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ)
+ Fails silently for (invalid) doors on the world's top and bottom. */
+ static NIBBLETYPE GetCompleteDoorMeta(cChunkInterface & a_ChunkInterface, const Vector3i a_BlockPos)
{
- NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta({a_BlockX, a_BlockY, a_BlockZ});
+ NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockPos);
if ((Meta & 0x08) != 0)
{
// The coords are pointing at the top part of the door
- if (a_BlockY > 0)
+ if (a_BlockPos.y > 0)
{
- NIBBLETYPE DownMeta = a_ChunkInterface.GetBlockMeta({a_BlockX, a_BlockY - 1, a_BlockZ});
+ NIBBLETYPE DownMeta = a_ChunkInterface.GetBlockMeta(a_BlockPos.addedY(-1));
return static_cast<NIBBLETYPE>((DownMeta & 0x07) | 0x08 | (Meta << 4));
}
// This is the top part of the door at the bottommost layer of the world, there's no bottom:
@@ -220,9 +254,9 @@ public:
else
{
// The coords are pointing at the bottom part of the door
- if (a_BlockY < cChunkDef::Height - 1)
+ if (a_BlockPos.y < cChunkDef::Height - 1)
{
- NIBBLETYPE UpMeta = a_ChunkInterface.GetBlockMeta({a_BlockX, a_BlockY + 1, a_BlockZ});
+ NIBBLETYPE UpMeta = a_ChunkInterface.GetBlockMeta(a_BlockPos.addedY(1));
return static_cast<NIBBLETYPE>(Meta | (UpMeta << 4));
}
// This is the bottom part of the door at the topmost layer of the world, there's no top:
@@ -235,15 +269,15 @@ public:
/** Sets the door to the specified state. If the door is already in that state, does nothing. */
- static void SetOpen(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ, bool a_Open)
+ static void SetOpen(cChunkInterface & a_ChunkInterface, const Vector3i a_BlockPos, bool a_Open)
{
- BLOCKTYPE Block = a_ChunkInterface.GetBlock({a_BlockX, a_BlockY, a_BlockZ});
+ BLOCKTYPE Block = a_ChunkInterface.GetBlock(a_BlockPos);
if (!IsDoorBlockType(Block))
{
return;
}
- NIBBLETYPE Meta = GetCompleteDoorMeta(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ);
+ NIBBLETYPE Meta = GetCompleteDoorMeta(a_ChunkInterface, a_BlockPos);
bool IsOpened = ((Meta & 0x04) != 0);
if (IsOpened == a_Open)
{
@@ -255,14 +289,14 @@ public:
if ((Meta & 0x08) == 0)
{
// The block is the bottom part of the door
- a_ChunkInterface.SetBlockMeta({a_BlockX, a_BlockY, a_BlockZ}, NewMeta);
+ 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_BlockY > 0)
+ if (a_BlockPos.y > 0)
{
- a_ChunkInterface.SetBlockMeta({a_BlockX, a_BlockY - 1, a_BlockZ}, NewMeta);
+ a_ChunkInterface.SetBlockMeta(a_BlockPos.addedY(-1), NewMeta);
}
}
}
@@ -272,9 +306,9 @@ public:
/** Changes the door at the specified coords from open to close or vice versa */
- static void ChangeDoor(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ)
+ static void ChangeDoor(cChunkInterface & a_ChunkInterface, const Vector3i a_BlockPos)
{
- SetOpen(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ, !IsOpen(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ));
+ SetOpen(a_ChunkInterface, a_BlockPos, !IsOpen(a_ChunkInterface, a_BlockPos));
}
diff --git a/src/Blocks/BlockEnchantmentTable.h b/src/Blocks/BlockEnchantmentTable.h
index bfb0f521c..a981cf7a7 100644
--- a/src/Blocks/BlockEnchantmentTable.h
+++ b/src/Blocks/BlockEnchantmentTable.h
@@ -9,27 +9,49 @@
-class cBlockEnchantmentTableHandler :
+class cBlockEnchantmentTableHandler:
public cBlockHandler
{
+ using Super = cBlockHandler;
+
public:
- cBlockEnchantmentTableHandler(BLOCKTYPE a_BlockType)
- : cBlockHandler(a_BlockType)
+
+ cBlockEnchantmentTableHandler(BLOCKTYPE a_BlockType):
+ Super(a_BlockType)
{
}
- virtual bool OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) 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
{
- cWindow * Window = new cEnchantingWindow(a_BlockX, a_BlockY, a_BlockZ);
+ cWindow * Window = new cEnchantingWindow(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z);
a_Player.OpenWindow(*Window);
return true;
}
+
+
+
+
virtual bool IsUseable(void) override
{
return true;
}
+
+
+
+
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
{
UNUSED(a_Meta);
diff --git a/src/Blocks/BlockEndPortalFrame.h b/src/Blocks/BlockEndPortalFrame.h
index c35d13929..be67bb4f9 100644
--- a/src/Blocks/BlockEndPortalFrame.h
+++ b/src/Blocks/BlockEndPortalFrame.h
@@ -7,22 +7,26 @@
-class cBlockEndPortalFrameHandler :
+class cBlockEndPortalFrameHandler:
public cMetaRotator<cBlockHandler, 0x03,
- E_META_END_PORTAL_FRAME_ZM,
- E_META_END_PORTAL_FRAME_XP,
- E_META_END_PORTAL_FRAME_ZP,
- E_META_END_PORTAL_FRAME_XM
+ E_META_END_PORTAL_FRAME_ZM,
+ E_META_END_PORTAL_FRAME_XP,
+ E_META_END_PORTAL_FRAME_ZP,
+ E_META_END_PORTAL_FRAME_XM
>
{
-public:
- cBlockEndPortalFrameHandler(BLOCKTYPE a_BlockType):
- cMetaRotator<cBlockHandler, 0x03,
+ using Super = cMetaRotator<
+ cBlockHandler, 0x03,
E_META_END_PORTAL_FRAME_ZM,
E_META_END_PORTAL_FRAME_XP,
E_META_END_PORTAL_FRAME_ZP,
E_META_END_PORTAL_FRAME_XM
- >(a_BlockType)
+ >;
+
+public:
+
+ cBlockEndPortalFrameHandler(BLOCKTYPE a_BlockType):
+ Super(a_BlockType)
{
}
@@ -31,9 +35,11 @@ public:
virtual bool GetPlacementBlockTypeMeta(
- cChunkInterface & a_ChunkInterface, cPlayer & a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
- int a_CursorX, int a_CursorY, int a_CursorZ,
+ cChunkInterface & a_ChunkInterface,
+ cPlayer & a_Player,
+ const Vector3i a_PlacedBlockPos,
+ eBlockFace a_ClickedBlockFace,
+ const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{
diff --git a/src/Blocks/BlockEntity.h b/src/Blocks/BlockEntity.h
index 8e7f92913..9fbb77a1f 100644
--- a/src/Blocks/BlockEntity.h
+++ b/src/Blocks/BlockEntity.h
@@ -28,9 +28,16 @@ public:
- virtual bool OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) 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
{
- return a_ChunkInterface.UseBlockEntity(&a_Player, a_BlockX, a_BlockY, a_BlockZ);
+ return a_ChunkInterface.UseBlockEntity(&a_Player, a_BlockPos.x, a_BlockPos.y, a_BlockPos.z);
}
diff --git a/src/Blocks/BlockFence.h b/src/Blocks/BlockFence.h
index 96a3d8d96..25ac85eed 100644
--- a/src/Blocks/BlockFence.h
+++ b/src/Blocks/BlockFence.h
@@ -10,21 +10,28 @@
-class cBlockFenceHandler :
+class cBlockFenceHandler:
public cBlockHandler
{
+ using Super = cBlockHandler;
+
public:
+
// These are the min and max coordinates (X and Z) for a straight fence.
// 0.4 and 0.6 are really just guesses, but they seem pretty good.
// (0.4 to 0.6 is a fence that's 0.2 wide, down the center of the block)
const double MIN_COORD = 0.4;
const double MAX_COORD = 0.6;
- cBlockFenceHandler(BLOCKTYPE a_BlockType)
- : cBlockHandler(a_BlockType)
+ cBlockFenceHandler(BLOCKTYPE a_BlockType):
+ 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);
@@ -76,9 +83,20 @@ public:
return PlacementBox;
}
- virtual bool OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) 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
{
- auto LeashKnot = cLeashKnot::FindKnotAtPos(*a_Player.GetWorld(), { a_BlockX, a_BlockY, a_BlockZ });
+ auto LeashKnot = cLeashKnot::FindKnotAtPos(*a_Player.GetWorld(), a_BlockPos);
auto KnotAlreadyExists = (LeashKnot != nullptr);
if (KnotAlreadyExists)
@@ -89,7 +107,7 @@ public:
// New knot? needs to init and produce sound effect
else
{
- auto NewLeashKnot = cpp14::make_unique<cLeashKnot>(a_BlockFace, Vector3i{a_BlockX, a_BlockY, a_BlockZ});
+ auto NewLeashKnot = cpp14::make_unique<cLeashKnot>(a_BlockFace, a_BlockPos);
auto NewLeashKnotPtr = NewLeashKnot.get();
NewLeashKnotPtr->TiePlayersLeashedMobs(a_Player, KnotAlreadyExists);
@@ -112,11 +130,25 @@ public:
return true;
}
- virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override
+
+
+
+
+ virtual void OnCancelRightClick(
+ cChunkInterface & a_ChunkInterface,
+ cWorldInterface & a_WorldInterface,
+ cPlayer & a_Player,
+ const Vector3i a_BlockPos,
+ eBlockFace a_BlockFace
+ ) override
{
- a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player);
+ a_WorldInterface.SendBlockTo(a_BlockPos, a_Player);
}
+
+
+
+
virtual bool IsUseable(void) override
{
return true;
diff --git a/src/Blocks/BlockFenceGate.h b/src/Blocks/BlockFenceGate.h
index 5d89ae021..bba308230 100644
--- a/src/Blocks/BlockFenceGate.h
+++ b/src/Blocks/BlockFenceGate.h
@@ -20,36 +20,65 @@ public:
{
}
- virtual bool OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) 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
{
- NIBBLETYPE OldMetaData = a_ChunkInterface.GetBlockMeta({a_BlockX, a_BlockY, a_BlockZ});
+ NIBBLETYPE OldMetaData = a_ChunkInterface.GetBlockMeta(a_BlockPos);
NIBBLETYPE NewMetaData = YawToMetaData(a_Player.GetYaw());
OldMetaData ^= 4; // Toggle the gate
if ((OldMetaData & 1) == (NewMetaData & 1))
{
// Standing in front of the gate - apply new direction
- a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, (OldMetaData & 4) | (NewMetaData & 3));
+ a_ChunkInterface.SetBlockMeta(a_BlockPos, (OldMetaData & 4) | (NewMetaData & 3));
}
else
{
// Standing aside - use last direction
- a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, OldMetaData);
+ a_ChunkInterface.SetBlockMeta(a_BlockPos, OldMetaData);
}
- a_Player.GetWorld()->BroadcastSoundParticleEffect(EffectID::SFX_RANDOM_FENCE_GATE_OPEN, {a_BlockX, a_BlockY, a_BlockZ}, 0, a_Player.GetClientHandle());
+ a_Player.GetWorld()->BroadcastSoundParticleEffect(EffectID::SFX_RANDOM_FENCE_GATE_OPEN, a_BlockPos, 0, a_Player.GetClientHandle());
return true;
}
- virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override
+
+
+
+
+ virtual void OnCancelRightClick(
+ cChunkInterface & a_ChunkInterface,
+ cWorldInterface & a_WorldInterface,
+ cPlayer & a_Player,
+ const Vector3i a_BlockPos,
+ eBlockFace a_BlockFace
+ ) override
{
- a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player);
+ a_WorldInterface.SendBlockTo(a_BlockPos, a_Player);
}
+
+
+
+
virtual bool IsUseable(void) override
{
return true;
}
+
+
+
+
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
{
UNUSED(a_Meta);
diff --git a/src/Blocks/BlockFlower.h b/src/Blocks/BlockFlower.h
index d88891d75..714ff9cab 100644
--- a/src/Blocks/BlockFlower.h
+++ b/src/Blocks/BlockFlower.h
@@ -7,12 +7,15 @@
-class cBlockFlowerHandler :
+class cBlockFlowerHandler:
public cBlockHandler
{
+ using Super = cBlockHandler;
+
public:
- cBlockFlowerHandler(BLOCKTYPE a_BlockType)
- : cBlockHandler(a_BlockType)
+
+ cBlockFlowerHandler(BLOCKTYPE a_BlockType):
+ Super(a_BlockType)
{
}
@@ -30,11 +33,15 @@ public:
- virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override
{
- return (a_RelY > 0) && IsBlockTypeOfDirt(a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ));
+ return ((a_RelPos.y > 0) && IsBlockTypeOfDirt(a_Chunk.GetBlock(a_RelPos.addedY(-1))));
}
+
+
+
+
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
{
UNUSED(a_Meta);
diff --git a/src/Blocks/BlockGrass.h b/src/Blocks/BlockGrass.h
index 374fcceed..51a321b35 100644
--- a/src/Blocks/BlockGrass.h
+++ b/src/Blocks/BlockGrass.h
@@ -90,30 +90,31 @@ public:
// Y Coord out of range
continue;
}
- auto chunk = a_Chunk.GetRelNeighborChunkAdjustCoords(Pos);
- if (chunk == nullptr)
+ auto Chunk = a_Chunk.GetRelNeighborChunkAdjustCoords(Pos);
+ if (Chunk == nullptr)
{
// Unloaded chunk
continue;
}
- chunk->GetBlockTypeMeta(Pos, DestBlock, DestMeta);
+ Chunk->GetBlockTypeMeta(Pos, DestBlock, DestMeta);
if ((DestBlock != E_BLOCK_DIRT) || (DestMeta != E_META_DIRT_NORMAL))
{
// Not a regular dirt block
continue;
}
- BLOCKTYPE Above = chunk->GetBlock(AbovePos);
- NIBBLETYPE light = std::max(chunk->GetBlockLight(AbovePos), chunk->GetTimeAlteredLight(chunk->GetSkyLight(AbovePos)));
- if ((light > 4) &&
- cBlockInfo::IsTransparent(Above) &&
- (!IsBlockLava(Above)) &&
- (!IsBlockWaterOrIce(Above))
+ auto AboveDestPos = Pos.addedY(1);
+ auto AboveBlockType = Chunk->GetBlock(AboveDestPos);
+ auto Light = std::max(Chunk->GetBlockLight(AboveDestPos), Chunk->GetTimeAlteredLight(Chunk->GetSkyLight(AboveDestPos)));
+ if ((Light > 4) &&
+ cBlockInfo::IsTransparent(AboveBlockType) &&
+ (!IsBlockLava(AboveBlockType)) &&
+ (!IsBlockWaterOrIce(AboveBlockType))
)
{
- auto absPos = chunk->RelativeToAbsolute(Pos);
- if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread(*chunk->GetWorld(), absPos.x, absPos.y, absPos.z, ssGrassSpread))
+ auto AbsPos = Chunk->RelativeToAbsolute(Pos);
+ if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread(*Chunk->GetWorld(), AbsPos.x, AbsPos.y, AbsPos.z, ssGrassSpread))
{
- chunk->FastSetBlock(Pos, E_BLOCK_GRASS, 0);
+ Chunk->FastSetBlock(Pos, E_BLOCK_GRASS, 0);
}
}
} // for i - repeat twice
diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp
index f1df4db44..5d6609836 100644
--- a/src/Blocks/BlockHandler.cpp
+++ b/src/Blocks/BlockHandler.cpp
@@ -406,8 +406,9 @@ cBlockHandler::cBlockHandler(BLOCKTYPE a_BlockType)
bool cBlockHandler::GetPlacementBlockTypeMeta(
cChunkInterface & a_ChunkInterface, cPlayer & a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
- int a_CursorX, int a_CursorY, int a_CursorZ,
+ const Vector3i a_ClickedBlockPos,
+ eBlockFace a_ClickedBlockFace,
+ const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
)
{
@@ -437,7 +438,7 @@ void cBlockHandler::OnUpdate(
void cBlockHandler::OnPlacedByPlayer(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, const sSetBlock & a_BlockChange)
{
- OnPlaced(a_ChunkInterface, a_WorldInterface, a_BlockChange.GetPos(), a_BlockChange.m_BlockType, a_BlockChange.m_BlockMeta);
+ OnPlaced(a_ChunkInterface, a_WorldInterface, a_BlockChange.GetAbsolutePos(), a_BlockChange.m_BlockType, a_BlockChange.m_BlockMeta);
}
@@ -509,7 +510,7 @@ cItems cBlockHandler::ConvertToPickups(
-bool cBlockHandler::CanBeAt(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ, const cChunk & a_Chunk)
+bool cBlockHandler::CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk)
{
return true;
}
@@ -554,10 +555,10 @@ bool cBlockHandler::DoesDropOnUnsuitable(void)
-/* default functionality: only test for height, since we assume full voxels with varying height */
-bool cBlockHandler::IsInsideBlock(Vector3d a_Position, const BLOCKTYPE a_BlockType, const NIBBLETYPE a_BlockMeta)
+bool cBlockHandler::IsInsideBlock(const Vector3d a_RelPosition, const NIBBLETYPE a_BlockMeta)
{
- return a_Position.y < cBlockInfo::GetBlockHeight(a_BlockType);
+ // Default functionality: Test the height, since we assume full voxels with varying height
+ return (a_RelPosition.y < cBlockInfo::GetBlockHeight(m_BlockType));
}
@@ -584,7 +585,7 @@ void cBlockHandler::Check(
cChunk & a_Chunk
)
{
- if (!CanBeAt(a_ChunkInterface, a_RelPos.x, a_RelPos.y, a_RelPos.z, a_Chunk))
+ if (!CanBeAt(a_ChunkInterface, a_RelPos, a_Chunk))
{
if (DoesDropOnUnsuitable())
{
diff --git a/src/Blocks/BlockHandler.h b/src/Blocks/BlockHandler.h
index f4a7fc674..a582b8dc2 100644
--- a/src/Blocks/BlockHandler.h
+++ b/src/Blocks/BlockHandler.h
@@ -44,19 +44,28 @@ public:
blocktype of the minus-X neighbor, the positive-X neighbor, etc. */
virtual cBoundingBox GetPlacementCollisionBox(BLOCKTYPE a_XM, BLOCKTYPE a_XP, BLOCKTYPE a_YM, BLOCKTYPE a_YP, BLOCKTYPE a_ZM, BLOCKTYPE a_ZP);
- /** Called before a block is placed into a world.
+ /** 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.
- Also, the handler should set a_BlockType and a_BlockMeta to correct values for the newly placed block.
- Called by cItemHandler::GetPlacementBlockTypeMeta() if the item is a block */
+ a_PlacedBlockPos is the coords of the block being placed
+ a_ClickedBlockFace is the face of the neighbor block clicked by the client to place this block.
+ a_CursorPos is the position of the cursor within the neighbor's face
+ The descendant handler should set a_BlockType and a_BlockMeta to correct values for the newly placed block.
+ The default handler uses the stored block type and meta copied from the lowest 4 bits of the player's equipped item's damage value. */
virtual bool GetPlacementBlockTypeMeta(
- cChunkInterface & a_ChunkInterface, cPlayer & a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
- int a_CursorX, int a_CursorY, int a_CursorZ,
+ cChunkInterface & a_ChunkInterface,
+ cPlayer & a_Player,
+ const Vector3i a_PlacedBlockPos,
+ eBlockFace a_ClickedBlockFace,
+ const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
);
/** Called by cWorld::SetBlock() after the block has been set */
- virtual void OnPlaced(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
+ virtual void OnPlaced(
+ cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
+ Vector3i a_BlockPos,
+ BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta
+ );
/** Called by cPlayer::PlaceBlocks() for each block after it has been set to the world. Called after OnPlaced(). */
virtual void OnPlacedByPlayer(
@@ -118,18 +127,37 @@ public:
cChunkInterface & a_ChunkInterface,
cWorldInterface & a_WorldInterface,
cPlayer & a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ
+ const Vector3i a_BlockPos
)
{
}
- /** Called if the user right clicks the block and the block is useable
- returns true if the use was successful, return false to use the block as a "normal" block */
- virtual bool OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) { return false; }
+ /** Called when the user right clicks the block and the block is useable.
+ a_CursorPos is the cursor position within the clicked block face.
+ Returns true if the use was successful, return false to use the block as a "normal" block */
+ virtual bool OnUse(
+ cChunkInterface & a_ChunkInterface,
+ cWorldInterface & a_WorldInterface,
+ cPlayer & a_Player,
+ const Vector3i a_BlockPos,
+ eBlockFace a_BlockFace,
+ const Vector3i a_CursorPos
+ )
+ {
+ return false;
+ }
/** Called when a right click to this block is cancelled.
- It forces the server to send the real state of a block to the client to prevent client assuming the operation is successfull */
- virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) {}
+ Descendants should force the server to send the real state of a block to the client to prevent client assuming the operation was successfull. */
+ virtual void OnCancelRightClick(
+ cChunkInterface & a_ChunkInterface,
+ cWorldInterface & a_WorldInterface,
+ cPlayer & a_Player,
+ const Vector3i a_BlockPos,
+ eBlockFace a_BlockFace
+ )
+ {
+ }
/** Returns the pickups that would result if the block was mined by a_Digger using a_Tool.
Doesn't do any actual block change / mining, only calculates the pickups.
@@ -145,41 +173,37 @@ public:
);
/** Checks if the block can stay at the specified relative coords in the chunk */
- virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk);
+ virtual bool CanBeAt(
+ cChunkInterface & a_ChunkInterface,
+ const Vector3i a_RelPos,
+ const cChunk & a_Chunk
+ );
/** Checks whether the block has an effect on growing the plant */
virtual bool CanSustainPlant(BLOCKTYPE a_Plant) { return false; }
- /** Checks if the block can be placed at this point.
- Default: CanBeAt(...)
- NOTE: This call doesn't actually place the block
- */
- // virtual bool CanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir);
-
/** Called to check whether this block supports a rclk action.
If it returns true, OnUse() is called */
virtual bool IsUseable(void);
/** 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);
/** 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
@param a_Pos Position of the block
@param a_Player Player trying to build on the block
- @param a_Meta Meta value of the block currently at a_Pos
- */
- virtual bool DoesIgnoreBuildCollision(cChunkInterface & ChunkInterface, Vector3i a_Pos, cPlayer & a_Player, NIBBLETYPE a_Meta);
+ @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);
/** Returns if this block drops if it gets destroyed by an unsuitable situation.
Default: true */
virtual bool DoesDropOnUnsuitable(void);
- /** Tests if a_Position is inside the block where a_Position is relative to the origin of the block
- Note that this is considered from a "top-down" perspective i.e. empty spaces on the bottom of a block don't matter */
- virtual bool IsInsideBlock(Vector3d a_Position, const BLOCKTYPE a_BlockType, const NIBBLETYPE a_BlockMeta);
+ /** 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. */
+ virtual bool IsInsideBlock(const Vector3d a_RelPosition, const NIBBLETYPE a_BlockMeta);
/** 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()),
diff --git a/src/Blocks/BlockHopper.h b/src/Blocks/BlockHopper.h
index a8d59440d..cb1ddf7d1 100644
--- a/src/Blocks/BlockHopper.h
+++ b/src/Blocks/BlockHopper.h
@@ -24,16 +24,18 @@ public:
virtual bool GetPlacementBlockTypeMeta(
- cChunkInterface & a_ChunkInterface, cPlayer & a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
- int a_CursorX, int a_CursorY, int a_CursorZ,
+ cChunkInterface & a_ChunkInterface,
+ cPlayer & a_Player,
+ const Vector3i a_PlacedBlockPos,
+ eBlockFace a_ClickedBlockFace,
+ const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{
a_BlockType = m_BlockType;
// Convert the blockface into meta:
- switch (a_BlockFace)
+ switch (a_ClickedBlockFace)
{
case BLOCK_FACE_BOTTOM: a_BlockMeta = E_META_HOPPER_FACING_YM; break;
case BLOCK_FACE_TOP: a_BlockMeta = E_META_HOPPER_FACING_YM; break;
diff --git a/src/Blocks/BlockLadder.h b/src/Blocks/BlockLadder.h
index c141faeb4..3f38d2c0c 100644
--- a/src/Blocks/BlockLadder.h
+++ b/src/Blocks/BlockLadder.h
@@ -8,7 +8,7 @@
-class cBlockLadderHandler :
+class cBlockLadderHandler:
public cClearMetaOnDrop<cMetaRotator<cBlockHandler, 0x07, 0x02, 0x05, 0x03, 0x04> >
{
using Super = cClearMetaOnDrop<cMetaRotator<cBlockHandler, 0x07, 0x02, 0x05, 0x03, 0x04>>;
@@ -25,24 +25,26 @@ public:
virtual bool GetPlacementBlockTypeMeta(
- cChunkInterface & a_ChunkInterface, cPlayer & a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
- int a_CursorX, int a_CursorY, int a_CursorZ,
+ 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 (!LadderCanBePlacedAt(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace))
+ // Try finding a suitable neighbor block face for the ladder; start with the given one.
+ if (!LadderCanBePlacedAt(a_ChunkInterface, a_PlacedBlockPos, a_ClickedBlockFace))
{
- a_BlockFace = FindSuitableBlockFace(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ);
-
- if (a_BlockFace == BLOCK_FACE_BOTTOM)
+ a_ClickedBlockFace = FindSuitableBlockFace(a_ChunkInterface, a_PlacedBlockPos);
+ if (a_ClickedBlockFace == BLOCK_FACE_NONE)
{
return false;
}
}
a_BlockType = m_BlockType;
- a_BlockMeta = DirectionToMetaData(a_BlockFace);
+ a_BlockMeta = BlockFaceToMetaData(a_ClickedBlockFace);
return true;
}
@@ -50,9 +52,10 @@ public:
- static NIBBLETYPE DirectionToMetaData(eBlockFace a_Direction)
+ /** Converts the block face of the neighbor to which the ladder is attached to the ladder block's meta. */
+ static NIBBLETYPE BlockFaceToMetaData(eBlockFace a_NeighborBlockFace)
{
- switch (a_Direction)
+ switch (a_NeighborBlockFace)
{
case BLOCK_FACE_ZM: return 0x2;
case BLOCK_FACE_ZP: return 0x3;
@@ -65,14 +68,15 @@ public:
return 0x2;
}
}
- UNREACHABLE("Unsupported block face");
+ UNREACHABLE("Unsupported neighbor block face");
}
- static eBlockFace MetaDataToDirection(NIBBLETYPE a_MetaData)
+ /** Converts the ladder block's meta to the block face of the neighbor to which the ladder is attached. */
+ static eBlockFace MetaDataToBlockFace(NIBBLETYPE a_MetaData)
{
switch (a_MetaData)
{
@@ -88,47 +92,51 @@ public:
- /** Finds a suitable Direction for the Ladder. Returns BLOCK_FACE_BOTTOM on failure */
- static eBlockFace FindSuitableBlockFace(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ)
+ /** Finds a suitable block face value for the Ladder.
+ The returned value is the block face of the neighbor of the specified block to which a ladder at a_LadderPos can be attached.
+ Returns BLOCK_FACE_NONE if no valid location is found */
+ static eBlockFace FindSuitableBlockFace(cChunkInterface & a_ChunkInterface, const Vector3i a_LadderPos)
{
for (int FaceInt = BLOCK_FACE_ZM; FaceInt <= BLOCK_FACE_XP; FaceInt++)
{
eBlockFace Face = static_cast<eBlockFace>(FaceInt);
- if (LadderCanBePlacedAt(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ, Face))
+ if (LadderCanBePlacedAt(a_ChunkInterface, a_LadderPos, Face))
{
return Face;
}
}
- return BLOCK_FACE_BOTTOM;
+ return BLOCK_FACE_NONE;
}
- static bool LadderCanBePlacedAt(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace)
+ /** Returns true if the ladder in the specified position will be supported by its neghbor through the specified neighbor's blockface. */
+ static bool LadderCanBePlacedAt(cChunkInterface & a_ChunkInterface, const Vector3i a_LadderPos, eBlockFace a_NeighborBlockFace)
{
- if ((a_BlockFace == BLOCK_FACE_BOTTOM) || (a_BlockFace == BLOCK_FACE_TOP))
+ if (
+ (a_NeighborBlockFace == BLOCK_FACE_NONE) ||
+ (a_NeighborBlockFace == BLOCK_FACE_BOTTOM) ||
+ (a_NeighborBlockFace == BLOCK_FACE_TOP)
+ )
{
return false;
}
- AddFaceDirection( a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, true);
-
- return cBlockInfo::IsSolid(a_ChunkInterface.GetBlock({a_BlockX, a_BlockY, a_BlockZ}));
+ auto NeighborPos = AddFaceDirection(a_LadderPos, a_NeighborBlockFace, true);
+ return cBlockInfo::IsSolid(a_ChunkInterface.GetBlock(NeighborPos));
}
- virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override
{
- // TODO: Use AdjustCoordsByMeta(), then cChunk::UnboundedRelGetBlock() and finally some comparison
- eBlockFace BlockFace = MetaDataToDirection(a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ));
- int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width;
- int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width;
- return LadderCanBePlacedAt(a_ChunkInterface, BlockX, a_RelY, BlockZ, BlockFace);
+ auto NeighborBlockFace = MetaDataToBlockFace(a_Chunk.GetMeta(a_RelPos));
+ auto LadderAbsPos = a_Chunk.RelativeToAbsolute(a_RelPos);
+ return LadderCanBePlacedAt(a_ChunkInterface, LadderAbsPos, NeighborBlockFace);
}
diff --git a/src/Blocks/BlockLever.h b/src/Blocks/BlockLever.h
index 8425b6620..4a682322d 100644
--- a/src/Blocks/BlockLever.h
+++ b/src/Blocks/BlockLever.h
@@ -6,14 +6,14 @@
#include "BlockSlab.h"
-class cBlockLeverHandler :
+class cBlockLeverHandler:
public cMetaRotator<cBlockHandler, 0x07, 0x04, 0x01, 0x03, 0x02, false>
{
using Super = cMetaRotator<cBlockHandler, 0x07, 0x04, 0x01, 0x03, 0x02, false>;
public:
- cBlockLeverHandler(BLOCKTYPE a_BlockType) :
+ cBlockLeverHandler(BLOCKTYPE a_BlockType):
Super(a_BlockType)
{
}
@@ -22,15 +22,21 @@ public:
- virtual bool OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) 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
{
- Vector3i Coords(a_BlockX, a_BlockY, a_BlockZ);
// Flip the ON bit on / off using the XOR bitwise operation
- NIBBLETYPE Meta = (a_ChunkInterface.GetBlockMeta(Coords) ^ 0x08);
+ NIBBLETYPE Meta = (a_ChunkInterface.GetBlockMeta(a_BlockPos) ^ 0x08);
- a_ChunkInterface.SetBlockMeta(Coords.x, Coords.y, Coords.z, Meta);
- a_WorldInterface.WakeUpSimulators(Coords);
- a_WorldInterface.GetBroadcastManager().BroadcastSoundEffect("block.lever.click", Vector3d(Coords), 0.5f, (Meta & 0x08) ? 0.6f : 0.5f);
+ a_ChunkInterface.SetBlockMeta(a_BlockPos, Meta);
+ a_WorldInterface.WakeUpSimulators(a_BlockPos);
+ a_WorldInterface.GetBroadcastManager().BroadcastSoundEffect("block.lever.click", a_BlockPos, 0.5f, (Meta & 0x08) ? 0.6f : 0.5f);
return true;
}
@@ -58,14 +64,16 @@ public:
virtual bool GetPlacementBlockTypeMeta(
- cChunkInterface & a_ChunkInterface, cPlayer & a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
- int a_CursorX, int a_CursorY, int a_CursorZ,
+ cChunkInterface & a_ChunkInterface,
+ cPlayer & a_Player,
+ const Vector3i a_PlacedBlockPos,
+ eBlockFace a_ClickedBlockFace,
+ const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{
a_BlockType = m_BlockType;
- a_BlockMeta = LeverDirectionToMetaData(a_BlockFace);
+ a_BlockMeta = LeverDirectionToMetaData(a_ClickedBlockFace);
return true;
}
@@ -73,6 +81,7 @@ public:
+ /** Converts the block face of the neighbor to which the lever is attached to the lever block's meta. */
inline static NIBBLETYPE LeverDirectionToMetaData(eBlockFace a_Dir)
{
// Determine lever direction:
@@ -93,6 +102,7 @@ public:
+ /** Converts the leve block's meta to the block face of the neighbor to which the lever is attached. */
inline static eBlockFace BlockMetaDataToBlockFace(NIBBLETYPE a_Meta)
{
switch (a_Meta & 0x7)
@@ -117,34 +127,33 @@ public:
- virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override
{
- NIBBLETYPE Meta = a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ);
-
- eBlockFace Face = BlockMetaDataToBlockFace(Meta);
-
- AddFaceDirection(a_RelX, a_RelY, a_RelZ, Face, true);
-
- if ((a_RelY < 0) || (a_RelY >= cChunkDef::Height -1))
+ // Find the type of block the lever is attached to:
+ auto Meta = a_Chunk.GetMeta(a_RelPos);
+ auto NeighborFace = BlockMetaDataToBlockFace(Meta);
+ auto NeighborPos = AddFaceDirection(a_RelPos, NeighborFace, true);
+ if (!cChunkDef::IsValidHeight(NeighborPos.y))
+ {
+ return false;
+ }
+ BLOCKTYPE NeighborBlockType;
+ if (!a_Chunk.UnboundedRelGetBlock(NeighborPos, NeighborBlockType, Meta))
{
return false;
}
- BLOCKTYPE BlockIsOn;
- a_Chunk.UnboundedRelGetBlock(a_RelX, a_RelY, a_RelZ, BlockIsOn, Meta);
-
-
- if (cBlockInfo::FullyOccupiesVoxel(BlockIsOn))
+ // Allow any full block or the "good" side of a half-slab:
+ if (cBlockInfo::FullyOccupiesVoxel(NeighborBlockType))
{
return true;
}
- else if (cBlockSlabHandler::IsAnySlabType(BlockIsOn))
+ else if (cBlockSlabHandler::IsAnySlabType(NeighborBlockType))
{
- // Check if the slab is turned up side down
- if (((Meta & 0x08) == 0x08) && (Face == BLOCK_FACE_TOP))
- {
- return true;
- }
+ return (
+ (((Meta & 0x08) == 0x08) && (NeighborFace == BLOCK_FACE_TOP)) ||
+ (((Meta & 0x08) == 0) && (NeighborFace == BLOCK_FACE_BOTTOM))
+ );
}
return false;
diff --git a/src/Blocks/BlockLilypad.h b/src/Blocks/BlockLilypad.h
index c51eb0a3d..8ffc8fd20 100644
--- a/src/Blocks/BlockLilypad.h
+++ b/src/Blocks/BlockLilypad.h
@@ -19,6 +19,10 @@ public:
{
}
+
+
+
+
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
{
UNUSED(a_Meta);
@@ -26,15 +30,19 @@ public:
}
- virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+
+
+
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override
{
- if ((a_RelY < 1) || (a_RelY >= cChunkDef::Height))
+ auto UnderPos = a_RelPos.addedY(-1);
+ if (!cChunkDef::IsValidHeight(UnderPos.y))
{
return false;
}
BLOCKTYPE UnderType;
NIBBLETYPE UnderMeta;
- a_Chunk.GetBlockTypeMeta(a_RelX, a_RelY - 1, a_RelZ, UnderType, UnderMeta);
+ a_Chunk.GetBlockTypeMeta(UnderPos, UnderType, UnderMeta);
return (
(((UnderType == E_BLOCK_STATIONARY_WATER) || (UnderType == E_BLOCK_WATER)) && (UnderMeta == 0)) || // A water source is below
(UnderType == E_BLOCK_ICE) || (UnderType == E_BLOCK_FROSTED_ICE) // Or (frosted) ice
diff --git a/src/Blocks/BlockMobSpawner.h b/src/Blocks/BlockMobSpawner.h
index c8a1c5696..78fa9ec31 100644
--- a/src/Blocks/BlockMobSpawner.h
+++ b/src/Blocks/BlockMobSpawner.h
@@ -8,22 +8,38 @@
-class cBlockMobSpawnerHandler :
+class cBlockMobSpawnerHandler:
public cBlockHandler
{
+ using Super = cBlockHandler;
+
public:
- cBlockMobSpawnerHandler(BLOCKTYPE a_BlockType)
- : cBlockHandler(a_BlockType)
+
+ cBlockMobSpawnerHandler(BLOCKTYPE a_BlockType):
+ Super(a_BlockType)
{
}
- virtual bool OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) 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
{
- return a_ChunkInterface.UseBlockEntity(&a_Player, a_BlockX, a_BlockY, a_BlockZ);
+ return a_ChunkInterface.UseBlockEntity(&a_Player, a_BlockPos.x, a_BlockPos.y, a_BlockPos.z);
}
+
+
+
virtual bool IsUseable() override
{
return true;
diff --git a/src/Blocks/BlockMushroom.h b/src/Blocks/BlockMushroom.h
index f44fbdc07..e40031465 100644
--- a/src/Blocks/BlockMushroom.h
+++ b/src/Blocks/BlockMushroom.h
@@ -7,6 +7,7 @@
+/** Handler for the small (singleblock) mushrooms. */
class cBlockMushroomHandler:
public cClearMetaOnDrop<cBlockHandler>
{
@@ -19,18 +20,26 @@ public:
{
}
+
+
+
+
// TODO: Add Mushroom Spread
- virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+
+
+
+
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override
{
- if (a_RelY <= 0)
+ if (a_RelPos.y <= 0)
{
return false;
}
// TODO: Cannot be at too much daylight
- switch (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ))
+ switch (a_Chunk.GetBlock(a_RelPos.addedY(-1)))
{
case E_BLOCK_GLASS:
case E_BLOCK_CACTUS:
@@ -45,6 +54,10 @@ public:
return true;
}
+
+
+
+
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
{
UNUSED(a_Meta);
diff --git a/src/Blocks/BlockNetherWart.h b/src/Blocks/BlockNetherWart.h
index 40ab1d886..86e348cf1 100644
--- a/src/Blocks/BlockNetherWart.h
+++ b/src/Blocks/BlockNetherWart.h
@@ -8,7 +8,7 @@
-class cBlockNetherWartHandler :
+class cBlockNetherWartHandler:
public cBlockPlant<false>
{
using Super = cBlockPlant<false>;
@@ -64,10 +64,10 @@ public:
- virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override
{
// Needs to be placed on top of a Soulsand block:
- return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) == E_BLOCK_SOULSAND));
+ return ((a_RelPos.y > 0) && (a_Chunk.GetBlock(a_RelPos.addedY(-1)) == E_BLOCK_SOULSAND));
}
diff --git a/src/Blocks/BlockPlanks.h b/src/Blocks/BlockPlanks.h
index 556f700ee..ea7d91398 100644
--- a/src/Blocks/BlockPlanks.h
+++ b/src/Blocks/BlockPlanks.h
@@ -7,18 +7,28 @@
-class cBlockPlanksHandler : public cBlockHandler
+class cBlockPlanksHandler:
+ public cBlockHandler
{
+ using Super = cBlockHandler;
+
public:
- cBlockPlanksHandler(BLOCKTYPE a_BlockType)
- : cBlockHandler(a_BlockType)
+
+ cBlockPlanksHandler(BLOCKTYPE a_BlockType):
+ Super(a_BlockType)
{
}
+
+
+
+
virtual bool GetPlacementBlockTypeMeta(
- cChunkInterface & a_ChunkInterface, cPlayer & a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
- int a_CursorX, int a_CursorY, int a_CursorZ,
+ cChunkInterface & a_ChunkInterface,
+ cPlayer & a_Player,
+ const Vector3i a_PlacedBlockPos,
+ eBlockFace a_ClickedBlockFace,
+ const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{
@@ -27,6 +37,10 @@ public:
return true;
}
+
+
+
+
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
{
switch (a_Meta)
diff --git a/src/Blocks/BlockPortal.h b/src/Blocks/BlockPortal.h
index 3f5d87155..c18da10be 100644
--- a/src/Blocks/BlockPortal.h
+++ b/src/Blocks/BlockPortal.h
@@ -7,25 +7,33 @@
-class cBlockPortalHandler :
+class cBlockPortalHandler:
public cBlockHandler
{
+ using Super = cBlockHandler;
public:
- cBlockPortalHandler(BLOCKTYPE a_BlockType)
- : cBlockHandler(a_BlockType)
+
+ cBlockPortalHandler(BLOCKTYPE a_BlockType):
+ Super(a_BlockType)
{
}
+
+
+
+
virtual bool GetPlacementBlockTypeMeta(
- cChunkInterface & a_ChunkInterface, cPlayer & a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
- int a_CursorX, int a_CursorY, int a_CursorZ,
+ cChunkInterface & a_ChunkInterface,
+ cPlayer & a_Player,
+ const Vector3i a_PlacedBlockPos,
+ eBlockFace a_ClickedBlockFace,
+ const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{
- // We set to zero so MCS doesn't stop you from building weird portals like vanilla does
+ // 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
- // We set to zero because the client sends meta = 2 to the server (it calculates rotation itself)
+ // We set to zero because the client sends meta = 1 or 2 to the server (it calculates rotation itself)
a_BlockType = m_BlockType;
a_BlockMeta = 0;
@@ -67,14 +75,14 @@ public:
- virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override
{
- if ((a_RelY <= 0) || (a_RelY >= cChunkDef::Height - 1))
+ if ((a_RelPos.y <= 0) || (a_RelPos.y >= cChunkDef::Height - 1))
{
return false; // In case someone places a portal with meta 1 or 2 at boundaries, and server tries to get invalid coords at Y - 1 or Y + 1
}
- switch (a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ))
+ switch (a_Chunk.GetMeta(a_RelPos))
{
case 0x1:
{
@@ -91,8 +99,7 @@ public:
for (const auto & Direction : PortalCheck)
{
BLOCKTYPE Block;
- a_Chunk.UnboundedRelGetBlockType(a_RelX + Direction.x, a_RelY + Direction.y, a_RelZ + Direction.z, Block);
-
+ a_Chunk.UnboundedRelGetBlockType(a_RelPos + Direction, Block);
if ((Block != E_BLOCK_NETHER_PORTAL) && (Block != E_BLOCK_OBSIDIAN))
{
return false;
@@ -115,8 +122,7 @@ public:
for (const auto & Direction : PortalCheck)
{
BLOCKTYPE Block;
- a_Chunk.UnboundedRelGetBlockType(a_RelX + Direction.x, a_RelY + Direction.y, a_RelZ + Direction.z, Block);
-
+ a_Chunk.UnboundedRelGetBlockType(a_RelPos + Direction, Block);
if ((Block != E_BLOCK_NETHER_PORTAL) && (Block != E_BLOCK_OBSIDIAN))
{
return false;
@@ -128,6 +134,10 @@ public:
return true;
}
+
+
+
+
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
{
UNUSED(a_Meta);
diff --git a/src/Blocks/BlockPressurePlate.h b/src/Blocks/BlockPressurePlate.h
index bac93675e..445ec9ff6 100644
--- a/src/Blocks/BlockPressurePlate.h
+++ b/src/Blocks/BlockPressurePlate.h
@@ -18,15 +18,19 @@ public:
{
}
- virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+
+
+
+
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override
{
- if (a_RelY - 1 <= 0)
+ if (a_RelPos.y <= 1)
{
return false;
}
// TODO: check if the block is upside-down slab or upside-down stairs
- BLOCKTYPE Block = a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ);
+ auto Block = a_Chunk.GetBlock(a_RelPos.addedY(-1));
switch (Block)
{
case E_BLOCK_ACACIA_FENCE:
@@ -47,6 +51,10 @@ public:
}
}
+
+
+
+
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
{
UNUSED(a_Meta);
diff --git a/src/Blocks/BlockQuartz.h b/src/Blocks/BlockQuartz.h
index c87240cf1..27d6b9984 100644
--- a/src/Blocks/BlockQuartz.h
+++ b/src/Blocks/BlockQuartz.h
@@ -7,42 +7,57 @@
-class cBlockQuartzHandler : public cBlockHandler
+class cBlockQuartzHandler:
+ public cBlockHandler
{
+ using Super = cBlockHandler;
+
public:
- cBlockQuartzHandler(BLOCKTYPE a_BlockType)
- : cBlockHandler(a_BlockType)
+
+ cBlockQuartzHandler(BLOCKTYPE a_BlockType):
+ Super(a_BlockType)
{
}
+
+
+
+
virtual bool GetPlacementBlockTypeMeta(
- cChunkInterface & a_ChunkInterface, cPlayer & a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
- int a_CursorX, int a_CursorY, int a_CursorZ,
+ cChunkInterface & a_ChunkInterface,
+ cPlayer & a_Player,
+ const Vector3i a_PlacedBlockPos,
+ eBlockFace a_ClickedBlockFace,
+ const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{
a_BlockType = m_BlockType;
- NIBBLETYPE Meta = static_cast<NIBBLETYPE>(a_Player.GetEquippedItem().m_ItemDamage);
+ auto Meta = static_cast<NIBBLETYPE>(a_Player.GetEquippedItem().m_ItemDamage);
- if (Meta != E_META_QUARTZ_PILLAR) // Check if the block is a pillar block.
+ // Pillar block needs additional direction in the metadata:
+ if (Meta != E_META_QUARTZ_PILLAR)
{
a_BlockMeta = Meta;
return true;
}
-
- a_BlockMeta = BlockFaceToMetaData(a_BlockFace, Meta);
+ a_BlockMeta = BlockFaceToMetaData(a_ClickedBlockFace);
return true;
}
- inline static NIBBLETYPE BlockFaceToMetaData(eBlockFace a_BlockFace, NIBBLETYPE a_QuartzMeta)
+
+
+
+
+ /** Converts the block face of the pillar block's "base" to the block's metadata. */
+ inline static NIBBLETYPE BlockFaceToMetaData(eBlockFace a_BlockFace)
{
switch (a_BlockFace)
{
case BLOCK_FACE_YM:
case BLOCK_FACE_YP:
{
- return a_QuartzMeta; // Top or bottom, just return original
+ return E_META_QUARTZ_PILLAR; // Top or bottom
}
case BLOCK_FACE_ZP:
@@ -57,15 +72,17 @@ public:
return 0x3; // East or west
}
- case BLOCK_FACE_NONE:
+ default:
{
- ASSERT(!"Unhandled block face!");
- return a_QuartzMeta; // No idea, give a special meta (all sides the same)
+ return E_META_QUARTZ_PILLAR;
}
}
- UNREACHABLE("Unsupported block face");
}
+
+
+
+
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
{
UNUSED(a_Meta);
diff --git a/src/Blocks/BlockRail.h b/src/Blocks/BlockRail.h
index 7ee98d576..f5cd7d8a2 100644
--- a/src/Blocks/BlockRail.h
+++ b/src/Blocks/BlockRail.h
@@ -28,21 +28,26 @@ public:
{
}
+
+
+
+
virtual bool GetPlacementBlockTypeMeta(
- cChunkInterface & a_ChunkInterface, cPlayer & a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
- int a_CursorX, int a_CursorY, int a_CursorZ,
+ cChunkInterface & a_ChunkInterface,
+ cPlayer & a_Player,
+ const Vector3i a_PlacedBlockPos,
+ eBlockFace a_ClickedBlockFace,
+ const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{
a_BlockType = m_BlockType;
- Vector3i Pos{ a_BlockX, a_BlockY, a_BlockZ };
- a_BlockMeta = FindMeta(a_ChunkInterface, Pos);
- return a_Player.GetWorld()->DoWithChunkAt(Pos,
- [this, Pos, &a_ChunkInterface](cChunk & a_Chunk)
+ a_BlockMeta = FindMeta(a_ChunkInterface, a_PlacedBlockPos);
+ return a_Player.GetWorld()->DoWithChunkAt(a_PlacedBlockPos,
+ [this, a_PlacedBlockPos, &a_ChunkInterface](cChunk & a_Chunk)
{
- auto RelPos = cChunkDef::AbsoluteToRelative(Pos);
- return CanBeAt(a_ChunkInterface, RelPos.x, RelPos.y, RelPos.z, a_Chunk);
+ auto RelPos = cChunkDef::AbsoluteToRelative(a_PlacedBlockPos);
+ return CanBeAt(a_ChunkInterface, RelPos, a_Chunk);
}
);
}
@@ -111,18 +116,18 @@ public:
- virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override
{
- if (a_RelY <= 0)
+ if (a_RelPos.y <= 0)
{
return false;
}
- if (!cBlockInfo::FullyOccupiesVoxel(a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)))
+ if (!cBlockInfo::FullyOccupiesVoxel(a_Chunk.GetBlock(a_RelPos.addedY(-1))))
{
return false;
}
- NIBBLETYPE Meta = a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ);
+ NIBBLETYPE Meta = a_Chunk.GetMeta(a_RelPos);
switch (Meta)
{
case E_META_RAIL_ASCEND_XP:
@@ -132,19 +137,16 @@ public:
{
// Mapping between the meta and the neighbors that need checking
Meta -= E_META_RAIL_ASCEND_XP; // Base index at zero
- static const struct
- {
- int x, z;
- } Coords[] =
+ static const Vector3i Coords[] =
{
- { 1, 0}, // east, XP
- {-1, 0}, // west, XM
- { 0, -1}, // north, ZM
- { 0, 1}, // south, ZP
+ { 1, 0, 0}, // east, XP
+ {-1, 0, 0}, // west, XM
+ { 0, 0, -1}, // north, ZM
+ { 0, 0, 1}, // south, ZP
} ;
BLOCKTYPE BlockType;
NIBBLETYPE BlockMeta;
- if (!a_Chunk.UnboundedRelGetBlock(a_RelX + Coords[Meta].x, a_RelY, a_RelZ + Coords[Meta].z, BlockType, BlockMeta))
+ if (!a_Chunk.UnboundedRelGetBlock(a_RelPos + Coords[Meta], BlockType, BlockMeta))
{
// Too close to the edge, cannot simulate
return true;
@@ -155,6 +157,10 @@ public:
return true;
}
+
+
+
+
NIBBLETYPE FindMeta(cChunkInterface & a_ChunkInterface, Vector3i a_BlockPos)
{
NIBBLETYPE Meta = 0;
diff --git a/src/Blocks/BlockRedstone.h b/src/Blocks/BlockRedstone.h
index 14621948e..e91c605db 100644
--- a/src/Blocks/BlockRedstone.h
+++ b/src/Blocks/BlockRedstone.h
@@ -8,7 +8,7 @@
-class cBlockRedstoneHandler :
+class cBlockRedstoneHandler:
public cBlockHandler
{
using Super = cBlockHandler;
@@ -20,16 +20,20 @@ public:
{
}
- virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+
+
+
+
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override
{
- if (a_RelY <= 0)
+ if (a_RelPos.y <= 0)
{
return false;
}
BLOCKTYPE BelowBlock;
NIBBLETYPE BelowBlockMeta;
- a_Chunk.GetBlockTypeMeta(a_RelX, a_RelY - 1, a_RelZ, BelowBlock, BelowBlockMeta);
+ a_Chunk.GetBlockTypeMeta(a_RelPos.addedY(-1), BelowBlock, BelowBlockMeta);
if (cBlockInfo::FullyOccupiesVoxel(BelowBlock))
{
@@ -46,11 +50,19 @@ public:
return false;
}
+
+
+
+
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{
return cItem(E_ITEM_REDSTONE_DUST, 1, 0);
}
+
+
+
+
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
{
UNUSED(a_Meta);
diff --git a/src/Blocks/BlockRedstoneOre.h b/src/Blocks/BlockRedstoneOre.h
index 4b570ab73..9042d7cc6 100644
--- a/src/Blocks/BlockRedstoneOre.h
+++ b/src/Blocks/BlockRedstoneOre.h
@@ -17,31 +17,39 @@ public:
using Super::Super; // Inherit constructor from base
+
+
+
+
virtual bool OnUse(
- cChunkInterface & a_ChunkInterface,
- cWorldInterface & a_WorldInterface,
- cPlayer & a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ,
+ cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player,
+ const Vector3i a_BlockPos,
eBlockFace a_BlockFace,
- int a_CursorX, int a_CursorY, int a_CursorZ
+ const Vector3i a_CursorPos
) override
{
- Vector3i BlockPos{a_BlockX, a_BlockY, a_BlockZ};
- a_ChunkInterface.SetBlock(BlockPos, E_BLOCK_REDSTONE_ORE_GLOWING, 0);
+ a_ChunkInterface.SetBlock(a_BlockPos, E_BLOCK_REDSTONE_ORE_GLOWING, 0);
return false;
}
+
+
+
+
virtual void OnDigging(
cChunkInterface & a_ChunkInterface,
cWorldInterface & a_WorldInterface,
cPlayer & a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ
+ const Vector3i a_BlockPos
) override
{
- Vector3i BlockPos{a_BlockX, a_BlockY, a_BlockZ};
- a_ChunkInterface.SetBlock(BlockPos, E_BLOCK_REDSTONE_ORE_GLOWING, 0);
+ a_ChunkInterface.SetBlock(a_BlockPos, E_BLOCK_REDSTONE_ORE_GLOWING, 0);
}
+
+
+
+
virtual bool IsUseable() override
{
return true;
@@ -61,6 +69,10 @@ public:
using Super::Super; // Inherit constructor from base
+
+
+
+
virtual void OnUpdate(
cChunkInterface & a_ChunkInterface,
cWorldInterface & a_WorldInterface,
diff --git a/src/Blocks/BlockRedstoneRepeater.h b/src/Blocks/BlockRedstoneRepeater.h
index 25aa9b795..e0b748821 100644
--- a/src/Blocks/BlockRedstoneRepeater.h
+++ b/src/Blocks/BlockRedstoneRepeater.h
@@ -23,33 +23,63 @@ public:
{
}
- virtual bool OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) 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
{
- a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, ((a_ChunkInterface.GetBlockMeta({a_BlockX, a_BlockY, a_BlockZ}) + 0x04) & 0x0f));
+ // Increment the delay setting:
+ a_ChunkInterface.SetBlockMeta(a_BlockPos, ((a_ChunkInterface.GetBlockMeta(a_BlockPos) + 0x04) & 0x0f));
return true;
}
- virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override
+
+
+
+
+ virtual void OnCancelRightClick(
+ cChunkInterface & a_ChunkInterface,
+ cWorldInterface & a_WorldInterface,
+ cPlayer & a_Player,
+ const Vector3i a_BlockPos,
+ eBlockFace a_BlockFace
+ ) override
{
UNUSED(a_ChunkInterface);
- a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player);
+ a_WorldInterface.SendBlockTo(a_BlockPos, a_Player);
}
+
+
+
+
virtual bool IsUseable(void) override
{
return true;
}
- virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+
+
+
+
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override
{
- if (a_RelY <= 0)
+ if (a_RelPos.y <= 0)
{
return false;
}
BLOCKTYPE BelowBlock;
NIBBLETYPE BelowBlockMeta;
- a_Chunk.GetBlockTypeMeta(a_RelX, a_RelY - 1, a_RelZ, BelowBlock, BelowBlockMeta);
+ a_Chunk.GetBlockTypeMeta(a_RelPos.addedY(-1), BelowBlock, BelowBlockMeta);
if (cBlockInfo::FullyOccupiesVoxel(BelowBlock))
{
@@ -66,17 +96,29 @@ public:
return false;
}
+
+
+
+
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{
return cItem(E_ITEM_REDSTONE_REPEATER, 1, 0);
}
+
+
+
+
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
{
UNUSED(a_Meta);
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
@@ -95,11 +137,18 @@ public:
}
}
+
+
+
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
diff --git a/src/Blocks/BlockSapling.h b/src/Blocks/BlockSapling.h
index 370353882..86397d806 100644
--- a/src/Blocks/BlockSapling.h
+++ b/src/Blocks/BlockSapling.h
@@ -34,9 +34,9 @@ public:
- virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override
{
- return (a_RelY > 0) && IsBlockTypeOfDirt(a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ));
+ return (a_RelPos.y > 0) && IsBlockTypeOfDirt(a_Chunk.GetBlock(a_RelPos.addedY(-1)));
}
diff --git a/src/Blocks/BlockSideways.h b/src/Blocks/BlockSideways.h
index 5854f334c..b94b9f8f3 100644
--- a/src/Blocks/BlockSideways.h
+++ b/src/Blocks/BlockSideways.h
@@ -27,15 +27,17 @@ public:
virtual bool GetPlacementBlockTypeMeta(
- cChunkInterface & a_ChunkInterface, cPlayer & a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
- int a_CursorX, int a_CursorY, int a_CursorZ,
+ cChunkInterface & a_ChunkInterface,
+ cPlayer & a_Player,
+ const Vector3i a_PlacedBlockPos,
+ eBlockFace a_ClickedBlockFace,
+ const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{
a_BlockType = m_BlockType;
NIBBLETYPE Meta = static_cast<NIBBLETYPE>(a_Player.GetEquippedItem().m_ItemDamage);
- a_BlockMeta = BlockFaceToMetaData(a_BlockFace, Meta);
+ a_BlockMeta = BlockFaceToMetaData(a_ClickedBlockFace, Meta);
return true;
}
diff --git a/src/Blocks/BlockSignPost.h b/src/Blocks/BlockSignPost.h
index 45fa7cad4..f493cb355 100644
--- a/src/Blocks/BlockSignPost.h
+++ b/src/Blocks/BlockSignPost.h
@@ -32,17 +32,21 @@ public:
- virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override
{
- if (a_RelY <= 0)
+ if (a_RelPos.y <= 0)
{
return false;
}
- BLOCKTYPE Type = a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ);
-
+ 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. */
static NIBBLETYPE RotationToMetaData(double a_Rotation)
{
a_Rotation += 180 + (180 / 16); // So it's not aligned with axis
@@ -56,16 +60,28 @@ public:
return (static_cast<char>(a_Rotation)) % 16;
}
+
+
+
+
virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override
{
return (a_Meta + 4) & 0x0f;
}
+
+
+
+
virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override
{
return (a_Meta + 12) & 0x0f;
}
+
+
+
+
virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override
{
// Mirrors signs over the XY plane (North-South Mirroring)
@@ -75,6 +91,10 @@ public:
return (a_Meta < 0x08) ? (0x08 - a_Meta) : (0x18 - a_Meta);
}
+
+
+
+
virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override
{
// Mirrors signs over the YZ plane (East-West Mirroring)
@@ -84,6 +104,10 @@ public:
return 0x0f - a_Meta;
}
+
+
+
+
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
{
UNUSED(a_Meta);
diff --git a/src/Blocks/BlockSlab.h b/src/Blocks/BlockSlab.h
index bd9c0299a..c59dc6f06 100644
--- a/src/Blocks/BlockSlab.h
+++ b/src/Blocks/BlockSlab.h
@@ -44,9 +44,11 @@ public:
virtual bool GetPlacementBlockTypeMeta(
- cChunkInterface & a_ChunkInterface, cPlayer & a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
- int a_CursorX, int a_CursorY, int a_CursorZ,
+ cChunkInterface & a_ChunkInterface,
+ cPlayer & a_Player,
+ const Vector3i a_PlacedBlockPos,
+ eBlockFace a_ClickedBlockFace,
+ const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{
@@ -54,18 +56,18 @@ public:
NIBBLETYPE Meta = static_cast<NIBBLETYPE>(a_Player.GetEquippedItem().m_ItemDamage);
// Set the correct metadata based on player equipped item (i.e. a_BlockMeta not initialised yet)
- switch (a_BlockFace)
+ switch (a_ClickedBlockFace)
{
case BLOCK_FACE_TOP:
{
// Bottom half slab block
- a_BlockMeta = Meta & 0x7;
+ a_BlockMeta = Meta & 0x07;
break;
}
case BLOCK_FACE_BOTTOM:
{
// Top half slab block
- a_BlockMeta = Meta | 0x8;
+ a_BlockMeta = Meta | 0x08;
break;
}
case BLOCK_FACE_EAST:
@@ -73,15 +75,15 @@ public:
case BLOCK_FACE_SOUTH:
case BLOCK_FACE_WEST:
{
- if (a_CursorY > 7)
+ if (a_CursorPos.y > 7)
{
// Cursor at top half of block, place top slab
- a_BlockMeta = Meta | 0x8; break;
+ a_BlockMeta = Meta | 0x08; break;
}
else
{
// Cursor at bottom half of block, place bottom slab
- a_BlockMeta = Meta & 0x7; break;
+ a_BlockMeta = Meta & 0x07; break;
}
}
case BLOCK_FACE_NONE: return false;
@@ -89,10 +91,10 @@ public:
// Check if the block at the coordinates is a single slab. Eligibility for combining has already been processed in ClientHandle
// Changed to-be-placed to a double slab if we are clicking on a single slab, as opposed to placing one for the first time
- if (IsAnySlabType(a_ChunkInterface.GetBlock({a_BlockX, a_BlockY, a_BlockZ})))
+ if (IsAnySlabType(a_ChunkInterface.GetBlock(a_PlacedBlockPos)))
{
a_BlockType = GetDoubleSlabType(m_BlockType);
- a_BlockMeta = a_BlockMeta & 0x7;
+ a_BlockMeta = a_BlockMeta & 0x07;
}
return true;
@@ -117,7 +119,13 @@ public:
- virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override
+ virtual void OnCancelRightClick(
+ cChunkInterface & a_ChunkInterface,
+ cWorldInterface & a_WorldInterface,
+ cPlayer & a_Player,
+ const Vector3i a_BlockPos,
+ eBlockFace a_BlockFace
+ ) override
{
if ((a_BlockFace == BLOCK_FACE_NONE) || (a_Player.GetEquippedItem().m_ItemType != static_cast<short>(m_BlockType)))
{
@@ -125,7 +133,7 @@ public:
}
// Sends the slab back to the client. It's to refuse a doubleslab placement. */
- a_Player.GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player);
+ a_Player.GetWorld()->SendBlockTo(a_BlockPos, a_Player);
}
@@ -222,13 +230,13 @@ public:
- virtual bool IsInsideBlock(Vector3d a_Position, const BLOCKTYPE a_BlockType, const NIBBLETYPE a_BlockMeta) override
+ virtual bool IsInsideBlock(Vector3d a_Position, const NIBBLETYPE a_BlockMeta) override
{
- if (a_BlockMeta & 0x8) // top half
+ if (a_BlockMeta & 0x08) // top half
{
return true;
}
- return cBlockHandler::IsInsideBlock(a_Position, a_BlockType, a_BlockMeta);
+ return cBlockHandler::IsInsideBlock(a_Position, a_BlockMeta);
}
} ;
@@ -236,7 +244,7 @@ public:
-class cBlockDoubleSlabHandler :
+class cBlockDoubleSlabHandler:
public cBlockHandler
{
using Super = cBlockHandler;
diff --git a/src/Blocks/BlockSnow.h b/src/Blocks/BlockSnow.h
index 4972e61fe..9b9ee85c0 100644
--- a/src/Blocks/BlockSnow.h
+++ b/src/Blocks/BlockSnow.h
@@ -10,30 +10,40 @@
class cBlockSnowHandler :
public cBlockHandler
{
+ using Super = cBlockHandler;
+
public:
+
enum
{
FullBlockMeta = 7 // Meta value of a full-height snow block
};
- cBlockSnowHandler(BLOCKTYPE a_BlockType)
- : cBlockHandler(a_BlockType)
+
+ cBlockSnowHandler(BLOCKTYPE a_BlockType):
+ Super(a_BlockType)
{
}
+
+
+
+
virtual bool GetPlacementBlockTypeMeta(
- cChunkInterface & a_ChunkInterface, cPlayer & a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
- int a_CursorX, int a_CursorY, int a_CursorZ,
+ cChunkInterface & a_ChunkInterface,
+ cPlayer & a_Player,
+ const Vector3i a_PlacedBlockPos,
+ eBlockFace a_ClickedBlockFace,
+ const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{
a_BlockType = m_BlockType;
+ // Check if incrementing existing snow height:
BLOCKTYPE BlockBeforePlacement;
NIBBLETYPE MetaBeforePlacement;
- a_ChunkInterface.GetBlockTypeMeta({a_BlockX, a_BlockY, a_BlockZ}, BlockBeforePlacement, MetaBeforePlacement);
-
+ a_ChunkInterface.GetBlockTypeMeta(a_PlacedBlockPos, BlockBeforePlacement, MetaBeforePlacement);
if ((BlockBeforePlacement == E_BLOCK_SNOW) && (MetaBeforePlacement < FullBlockMeta))
{
// Only increment if:
@@ -45,16 +55,19 @@ public:
// First time placement, check placement is valid
a_BlockMeta = 0;
-
BLOCKTYPE BlockBelow;
NIBBLETYPE MetaBelow;
return (
- (a_BlockY > 0) &&
- a_ChunkInterface.GetBlockTypeMeta({a_BlockX, a_BlockY - 1, a_BlockZ}, BlockBelow, MetaBelow) &&
+ (a_PlacedBlockPos.y > 0) &&
+ a_ChunkInterface.GetBlockTypeMeta(a_PlacedBlockPos.addedY(-1), BlockBelow, MetaBelow) &&
CanBeOn(BlockBelow, MetaBelow)
);
}
+
+
+
+
virtual bool DoesIgnoreBuildCollision(cChunkInterface & a_ChunkInterface, Vector3i a_Pos, cPlayer & a_Player, NIBBLETYPE a_Meta) override
{
if ((a_Player.GetEquippedItem().m_ItemType == E_BLOCK_SNOW) && (a_Meta < FullBlockMeta))
@@ -97,35 +110,47 @@ public:
- virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override
{
- if (a_RelY > 0)
+ if (a_RelPos.y <= 0)
{
- BLOCKTYPE BlockBelow = a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ);
- NIBBLETYPE MetaBelow = a_Chunk.GetMeta(a_RelX, a_RelY - 1, a_RelZ);
-
- return CanBeOn(BlockBelow, MetaBelow);
+ return false;
}
-
- return false;
+ auto BelowPos = a_RelPos.addedY(-1);
+ auto BlockBelow = a_Chunk.GetBlock(BelowPos);
+ auto MetaBelow = a_Chunk.GetMeta(BelowPos);
+ return CanBeOn(BlockBelow, MetaBelow);
}
+
+
+
+
virtual bool DoesDropOnUnsuitable(void) override
{
return false;
}
+
+
+
+
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
{
UNUSED(a_Meta);
return 14;
}
- virtual bool IsInsideBlock(Vector3d a_Position, const BLOCKTYPE a_BlockType, const NIBBLETYPE a_BlockMeta) override
+
+
+
+
+ virtual bool IsInsideBlock(const Vector3d a_RelPosition, const NIBBLETYPE a_BlockMeta) override
{
- return a_Position.y < (cBlockInfo::GetBlockHeight(a_BlockType) * (a_BlockMeta & 0x07));
+ return a_RelPosition.y < (cBlockInfo::GetBlockHeight(m_BlockType) * (a_BlockMeta & 0x07));
}
+
private:
/** Returns true if snow can be placed on top of a block with the given type and meta. */
diff --git a/src/Blocks/BlockStairs.h b/src/Blocks/BlockStairs.h
index c9e36d535..d616f5d67 100644
--- a/src/Blocks/BlockStairs.h
+++ b/src/Blocks/BlockStairs.h
@@ -17,25 +17,27 @@ public:
cBlockStairsHandler(BLOCKTYPE a_BlockType):
Super(a_BlockType)
{
-
}
+
+
+
+
virtual bool GetPlacementBlockTypeMeta(
- cChunkInterface & a_ChunkInterface, cPlayer & a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
- int a_CursorX, int a_CursorY, int a_CursorZ,
+ cChunkInterface & a_ChunkInterface,
+ cPlayer & a_Player,
+ const Vector3i a_PlacedBlockPos,
+ eBlockFace a_ClickedBlockFace,
+ const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{
UNUSED(a_ChunkInterface);
- UNUSED(a_BlockX);
- UNUSED(a_BlockY);
- UNUSED(a_BlockZ);
- UNUSED(a_CursorX);
- UNUSED(a_CursorZ);
+ UNUSED(a_PlacedBlockPos);
+ UNUSED(a_CursorPos);
a_BlockType = m_BlockType;
a_BlockMeta = RotationToMetaData(a_Player.GetYaw());
- switch (a_BlockFace)
+ switch (a_ClickedBlockFace)
{
case BLOCK_FACE_TOP: break;
case BLOCK_FACE_BOTTOM: a_BlockMeta = a_BlockMeta | 0x4; break; // When placing onto a bottom face, always place an upside-down stairs block
@@ -45,7 +47,7 @@ public:
case BLOCK_FACE_WEST:
{
// When placing onto a sideways face, check cursor, if in top half, make it an upside-down stairs block
- if (a_CursorY > 8)
+ if (a_CursorPos.y > 8)
{
a_BlockMeta |= 0x4;
}
@@ -56,6 +58,10 @@ public:
return true;
}
+
+
+
+
static NIBBLETYPE RotationToMetaData(double a_Rotation)
{
a_Rotation += 90 + 45; // So its not aligned with axis
@@ -81,12 +87,20 @@ public:
}
}
+
+
+
+
virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) override
{
// Toggle bit 3:
return (a_Meta & 0x0b) | ((~a_Meta) & 0x04);
}
+
+
+
+
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
{
UNUSED(a_Meta);
@@ -114,12 +128,16 @@ public:
}
}
+
+
+
+
/** EXCEPTION a.k.a. why is this removed:
This collision-detection is actually more accurate than the client, but since the client itself
sends inaccurate / sparse data, it's easier to just err on the side of the client and keep the
two in sync by assuming that if a player hit ANY of the stair's bounding cube, it counts as the ground. */
#if 0
- bool IsInsideBlock(const Vector3d & a_Position, const BLOCKTYPE a_BlockType, const NIBBLETYPE a_BlockMeta)
+ bool IsInsideBlock(Vector3d a_RelPosition, const BLOCKTYPE a_BlockType, const NIBBLETYPE a_BlockMeta)
{
if (a_BlockMeta & 0x4) // upside down
{
@@ -127,19 +145,19 @@ public:
}
else if ((a_BlockMeta & 0x3) == 0) // tall side is east (+X)
{
- return a_Position.y < ((a_Position.x > 0.5) ? 1.0 : 0.5);
+ return (a_RelPosition.y < ((a_RelPosition.x > 0.5) ? 1.0 : 0.5));
}
else if ((a_BlockMeta & 0x3) == 1) // tall side is west (-X)
{
- return a_Position.y < ((a_Position.x < 0.5) ? 1.0 : 0.5);
+ return (a_RelPosition.y < ((a_RelPosition.x < 0.5) ? 1.0 : 0.5));
}
else if ((a_BlockMeta & 0x3) == 2) // tall side is south (+Z)
{
- return a_Position.y < ((a_Position.z > 0.5) ? 1.0 : 0.5);
+ return (a_RelPosition.y < ((a_RelPosition.z > 0.5) ? 1.0 : 0.5));
}
else if ((a_BlockMeta & 0x3) == 3) // tall side is north (-Z)
{
- return a_Position.y < ((a_Position.z < 0.5) ? 1.0 : 0.5);
+ return (a_RelPosition.y < ((a_RelPosition.z < 0.5) ? 1.0 : 0.5));
}
return false;
}
diff --git a/src/Blocks/BlockStems.h b/src/Blocks/BlockStems.h
index bf0d7ce41..0e4b01c5a 100644
--- a/src/Blocks/BlockStems.h
+++ b/src/Blocks/BlockStems.h
@@ -36,9 +36,9 @@ public:
- virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override
{
- return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) == E_BLOCK_FARMLAND));
+ return ((a_RelPos.y > 0) && (a_Chunk.GetBlock(a_RelPos.addedY(-1)) == E_BLOCK_FARMLAND));
}
diff --git a/src/Blocks/BlockSugarcane.h b/src/Blocks/BlockSugarcane.h
index f45b312a8..fa153bd28 100644
--- a/src/Blocks/BlockSugarcane.h
+++ b/src/Blocks/BlockSugarcane.h
@@ -32,36 +32,32 @@ public:
- virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override
{
- if (a_RelY <= 0)
+ if (a_RelPos.y <= 0)
{
return false;
}
- switch (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ))
+ switch (a_Chunk.GetBlock(a_RelPos.addedY(-1)))
{
case E_BLOCK_DIRT:
case E_BLOCK_GRASS:
case E_BLOCK_FARMLAND:
case E_BLOCK_SAND:
{
- static const struct
+ static const Vector3i Coords[] =
{
- int x, z;
- } Coords[] =
- {
- {-1, 0},
- { 1, 0},
- { 0, -1},
- { 0, 1},
+ {-1, -1, 0},
+ { 1, -1, 0},
+ { 0, -1, -1},
+ { 0, -1, 1},
} ;
- a_RelY -= 1;
for (size_t i = 0; i < ARRAYCOUNT(Coords); i++)
{
BLOCKTYPE BlockType;
NIBBLETYPE BlockMeta;
- if (!a_Chunk.UnboundedRelGetBlock(a_RelX + Coords[i].x, a_RelY, a_RelZ + Coords[i].z, BlockType, BlockMeta))
+ if (!a_Chunk.UnboundedRelGetBlock(a_RelPos + Coords[i], BlockType, BlockMeta))
{
// Too close to the edge, cannot simulate
return true;
diff --git a/src/Blocks/BlockTNT.h b/src/Blocks/BlockTNT.h
index d8b50335a..fafa289da 100644
--- a/src/Blocks/BlockTNT.h
+++ b/src/Blocks/BlockTNT.h
@@ -10,17 +10,34 @@
class cBlockTNTHandler :
public cBlockHandler
{
+ using Super = cBlockHandler;
+
public:
- cBlockTNTHandler(BLOCKTYPE a_BlockType)
- : cBlockHandler(a_BlockType)
+
+ cBlockTNTHandler(BLOCKTYPE a_BlockType):
+ Super(a_BlockType)
{
}
- virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override
+
+
+
+
+ virtual void OnCancelRightClick(
+ cChunkInterface & a_ChunkInterface,
+ cWorldInterface & a_WorldInterface,
+ cPlayer & a_Player,
+ const Vector3i a_BlockPos,
+ eBlockFace a_BlockFace
+ ) override
{
- a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player);
+ a_WorldInterface.SendBlockTo(a_BlockPos, a_Player);
}
+
+
+
+
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
{
UNUSED(a_Meta);
diff --git a/src/Blocks/BlockTallGrass.h b/src/Blocks/BlockTallGrass.h
index d09e9d496..4cf115efd 100644
--- a/src/Blocks/BlockTallGrass.h
+++ b/src/Blocks/BlockTallGrass.h
@@ -54,14 +54,14 @@ public:
- virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override
{
- if (a_RelY <= 0)
+ if (a_RelPos.y <= 0)
{
return false;
}
- BLOCKTYPE BelowBlock = a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ);
+ BLOCKTYPE BelowBlock = a_Chunk.GetBlock(a_RelPos.addedY(-1));
return IsBlockTypeOfDirt(BelowBlock);
}
diff --git a/src/Blocks/BlockTorch.h b/src/Blocks/BlockTorch.h
index 93ca5e40d..e2a2dfcc9 100644
--- a/src/Blocks/BlockTorch.h
+++ b/src/Blocks/BlockTorch.h
@@ -8,7 +8,7 @@
-class cBlockTorchHandler :
+class cBlockTorchHandler:
public cClearMetaOnDrop<cMetaRotator<cBlockHandler, 0x7, 0x4, 0x1, 0x3, 0x2>>
{
using Super = cClearMetaOnDrop<cMetaRotator<cBlockHandler, 0x7, 0x4, 0x1, 0x3, 0x2>>;
@@ -20,39 +20,46 @@ public:
{
}
+
+
+
+
virtual bool GetPlacementBlockTypeMeta(
- cChunkInterface & a_ChunkInterface, cPlayer & a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
- int a_CursorX, int a_CursorY, int a_CursorZ,
+ cChunkInterface & a_ChunkInterface,
+ cPlayer & a_Player,
+ const Vector3i a_PlacedBlockPos,
+ eBlockFace a_ClickedBlockFace,
+ const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{
- BLOCKTYPE Block;
- NIBBLETYPE Meta;
- AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, true); // Set to clicked block
- a_ChunkInterface.GetBlockTypeMeta({a_BlockX, a_BlockY, a_BlockZ}, Block, Meta);
-
- if (!CanBePlacedOn(Block, Meta, a_BlockFace)) // Try to preserve original direction
+ BLOCKTYPE ClickedBlockType;
+ NIBBLETYPE ClickedBlockMeta;
+ auto ClickedBlockPos = AddFaceDirection(a_PlacedBlockPos, a_ClickedBlockFace, true);
+ a_ChunkInterface.GetBlockTypeMeta(ClickedBlockPos, ClickedBlockType, ClickedBlockMeta);
+ if (!CanBePlacedOn(ClickedBlockType, ClickedBlockMeta, a_ClickedBlockFace))
{
- // Torch couldn't be placed on whatever face was clicked, last ditch resort - find another face
-
- AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, false); // Reset to torch block
- a_BlockFace = FindSuitableFace(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); // Set a_BlockFace to a valid direction which will be converted later to a metadata
- if (a_BlockFace == BLOCK_FACE_NONE)
+ // Couldn't be placed on whatever face was clicked, last ditch resort - find another face
+ a_ClickedBlockFace = FindSuitableFace(a_ChunkInterface, a_PlacedBlockPos); // Set a_BlockFace to a valid direction which will be converted later to a metadata
+ if (a_ClickedBlockFace == BLOCK_FACE_NONE)
{
// No attachable face found - don't place the torch
return false;
}
}
-
a_BlockType = m_BlockType;
- a_BlockMeta = DirectionToMetaData(a_BlockFace);
+ a_BlockMeta = BlockFaceToMetaData(a_ClickedBlockFace);
return true;
}
- inline static NIBBLETYPE DirectionToMetaData(eBlockFace a_Direction)
+
+
+
+
+ /** Converts the block face of the neighbor to which the torch is attached, to the torch block's meta. */
+ inline static NIBBLETYPE BlockFaceToMetaData(eBlockFace a_NeighborBlockFace)
{
- switch (a_Direction)
+ switch (a_NeighborBlockFace)
{
case BLOCK_FACE_BOTTOM: ASSERT(!"Shouldn't be getting this face"); return 0;
case BLOCK_FACE_TOP: return E_META_TORCH_FLOOR;
@@ -69,7 +76,12 @@ public:
return 0x0;
}
- inline static eBlockFace MetaDataToDirection(NIBBLETYPE a_MetaData)
+
+
+
+
+ /** Converts the torch block's meta to the block face of the neighbor to which the torch is attached. */
+ inline static eBlockFace MetaDataToBlockFace(NIBBLETYPE a_MetaData)
{
switch (a_MetaData)
{
@@ -88,6 +100,11 @@ public:
return BLOCK_FACE_TOP;
}
+
+
+
+
+ /** Returns true if the torch can be placed on the specified block's face. */
static bool CanBePlacedOn(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, eBlockFace a_BlockFace)
{
switch (a_BlockType)
@@ -115,7 +132,7 @@ public:
case E_BLOCK_STONE_SLAB:
case E_BLOCK_WOODEN_SLAB:
{
- // Toches can be placed on the top of these slabs only if the occupy the top half of the voxel
+ // Toches can be placed only on the top of top-half-slabs
return ((a_BlockFace == BLOCK_FACE_YP) && ((a_BlockMeta & 0x08) == 0x08));
}
case E_BLOCK_OAK_WOOD_STAIRS:
@@ -146,45 +163,52 @@ public:
}
}
- /** Finds a suitable face to place the torch, returning BLOCK_FACE_NONE on failure */
- static eBlockFace FindSuitableFace(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ)
+
+
+
+
+ /** Returns a suitable neighbor's blockface to place the torch at the specified pos
+ Returns BLOCK_FACE_NONE on failure */
+ static eBlockFace FindSuitableFace(cChunkInterface & a_ChunkInterface, const Vector3i a_TorchPos)
{
- for (int i = BLOCK_FACE_YM; i <= BLOCK_FACE_XP; i++) // Loop through all directions
+ for (int i = BLOCK_FACE_YM; i <= BLOCK_FACE_XP; i++) // Loop through all faces
{
- eBlockFace Face = static_cast<eBlockFace>(i);
- AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, Face, true);
- BLOCKTYPE BlockInQuestion;
- NIBBLETYPE BlockInQuestionMeta;
- a_ChunkInterface.GetBlockTypeMeta({a_BlockX, a_BlockY, a_BlockZ}, BlockInQuestion, BlockInQuestionMeta);
-
- if (CanBePlacedOn(BlockInQuestion, BlockInQuestionMeta, Face))
+ auto Face = static_cast<eBlockFace>(i);
+ auto NeighborPos = AddFaceDirection(a_TorchPos, Face, true);
+ BLOCKTYPE NeighborBlockType;
+ NIBBLETYPE NeighborBlockMeta;
+ a_ChunkInterface.GetBlockTypeMeta(NeighborPos, NeighborBlockType, NeighborBlockMeta);
+ if (CanBePlacedOn(NeighborBlockType, NeighborBlockMeta, Face))
{
return Face;
}
- else
- {
- // Reset coords in preparation for next iteration
- AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, Face, false);
- }
}
return BLOCK_FACE_NONE;
}
- virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
- {
- eBlockFace Face = MetaDataToDirection(a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ));
- AddFaceDirection(a_RelX, a_RelY, a_RelZ, Face, true);
- BLOCKTYPE BlockInQuestion;
- NIBBLETYPE BlockInQuestionMeta;
- if (!a_Chunk.UnboundedRelGetBlock(a_RelX, a_RelY, a_RelZ, BlockInQuestion, BlockInQuestionMeta))
+
+
+
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override
+ {
+ auto Face = MetaDataToBlockFace(a_Chunk.GetMeta(a_RelPos));
+ auto NeighborRelPos = AddFaceDirection(a_RelPos, Face, true);
+ BLOCKTYPE NeighborBlockType;
+ NIBBLETYPE NeighborBlockMeta;
+ if (!a_Chunk.UnboundedRelGetBlock(NeighborRelPos, NeighborBlockType, NeighborBlockMeta))
{
+ // Neighbor in an unloaded chunk, bail out without changint this.
return false;
}
- return CanBePlacedOn(BlockInQuestion, BlockInQuestionMeta, Face);
+ return CanBePlacedOn(NeighborBlockType, NeighborBlockMeta, Face);
}
+
+
+
+
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
{
UNUSED(a_Meta);
diff --git a/src/Blocks/BlockTrapdoor.h b/src/Blocks/BlockTrapdoor.h
index 0ad2c64f5..f0c821764 100644
--- a/src/Blocks/BlockTrapdoor.h
+++ b/src/Blocks/BlockTrapdoor.h
@@ -32,7 +32,14 @@ public:
- virtual bool OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) 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
{
if (m_BlockType == E_BLOCK_IRON_TRAPDOOR)
{
@@ -41,36 +48,56 @@ public:
}
// Flip the ON bit on / off using the XOR bitwise operation
- NIBBLETYPE Meta = (a_ChunkInterface.GetBlockMeta({a_BlockX, a_BlockY, a_BlockZ}) ^ 0x04);
- a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta);
- a_WorldInterface.GetBroadcastManager().BroadcastSoundParticleEffect(EffectID::SFX_RANDOM_FENCE_GATE_OPEN, { a_BlockX, a_BlockY, a_BlockZ }, 0, a_Player.GetClientHandle());
+ NIBBLETYPE Meta = (a_ChunkInterface.GetBlockMeta(a_BlockPos) ^ 0x04);
+ a_ChunkInterface.SetBlockMeta(a_BlockPos, Meta);
+ a_WorldInterface.GetBroadcastManager().BroadcastSoundParticleEffect(EffectID::SFX_RANDOM_FENCE_GATE_OPEN, a_BlockPos, 0, a_Player.GetClientHandle());
return true;
}
- virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override
+
+
+
+
+ virtual void OnCancelRightClick(
+ cChunkInterface & a_ChunkInterface,
+ cWorldInterface & a_WorldInterface,
+ cPlayer & a_Player,
+ const Vector3i a_BlockPos,
+ eBlockFace a_BlockFace
+ ) override
{
UNUSED(a_ChunkInterface);
- a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player);
+ a_WorldInterface.SendBlockTo(a_BlockPos, a_Player);
}
+
+
+
+
virtual bool GetPlacementBlockTypeMeta(
- cChunkInterface & a_ChunkInterface, cPlayer & a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
- int a_CursorX, int a_CursorY, int a_CursorZ,
+ cChunkInterface & a_ChunkInterface,
+ cPlayer & a_Player,
+ const Vector3i a_PlacedBlockPos,
+ eBlockFace a_ClickedBlockFace,
+ const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{
a_BlockType = m_BlockType;
- a_BlockMeta = BlockFaceToMetaData(a_BlockFace);
+ a_BlockMeta = BlockFaceToMetaData(a_ClickedBlockFace);
- if (a_CursorY > 7)
+ if (a_CursorPos.y > 7)
{
a_BlockMeta |= 0x8;
}
return true;
}
+
+
+
+
inline static NIBBLETYPE BlockFaceToMetaData(eBlockFace a_BlockFace)
{
switch (a_BlockFace)
@@ -90,6 +117,10 @@ public:
UNREACHABLE("Unsupported block face");
}
+
+
+
+
inline static eBlockFace BlockMetaDataToBlockFace(NIBBLETYPE a_Meta)
{
switch (a_Meta & 0x3)
@@ -106,6 +137,10 @@ public:
}
}
+
+
+
+
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
{
UNUSED(a_Meta);
diff --git a/src/Blocks/BlockTripwireHook.h b/src/Blocks/BlockTripwireHook.h
index 797034ea0..766c0e404 100644
--- a/src/Blocks/BlockTripwireHook.h
+++ b/src/Blocks/BlockTripwireHook.h
@@ -24,14 +24,16 @@ public:
virtual bool GetPlacementBlockTypeMeta(
- cChunkInterface & a_ChunkInterface, cPlayer & a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
- int a_CursorX, int a_CursorY, int a_CursorZ,
+ cChunkInterface & a_ChunkInterface,
+ cPlayer & a_Player,
+ const Vector3i a_PlacedBlockPos,
+ eBlockFace a_ClickedBlockFace,
+ const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{
a_BlockType = m_BlockType;
- a_BlockMeta = DirectionToMetadata(a_BlockFace);
+ a_BlockMeta = DirectionToMetadata(a_ClickedBlockFace);
return true;
}
@@ -79,16 +81,17 @@ public:
- virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override
{
- NIBBLETYPE Meta;
- a_Chunk.UnboundedRelGetBlockMeta(a_RelX, a_RelY, a_RelZ, Meta);
-
- AddFaceDirection(a_RelX, a_RelY, a_RelZ, MetadataToDirection(Meta), true);
- BLOCKTYPE BlockIsOn;
- a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockIsOn);
-
- return ((a_RelY > 0) && cBlockInfo::FullyOccupiesVoxel(BlockIsOn));
+ auto Meta = a_Chunk.GetMeta(a_RelPos);
+ auto NeighborPos = AddFaceDirection(a_RelPos, MetadataToDirection(Meta), true);
+ if (!cChunkDef::IsValidHeight(NeighborPos.y))
+ {
+ return false;
+ }
+ BLOCKTYPE NeighborBlockType;
+ a_Chunk.UnboundedRelGetBlockType(a_RelPos, NeighborBlockType);
+ return cBlockInfo::FullyOccupiesVoxel(NeighborBlockType);
}
diff --git a/src/Blocks/BlockVine.h b/src/Blocks/BlockVine.h
index f8328f046..2cf6e985c 100644
--- a/src/Blocks/BlockVine.h
+++ b/src/Blocks/BlockVine.h
@@ -23,23 +23,25 @@ public:
virtual bool GetPlacementBlockTypeMeta(
- cChunkInterface & a_ChunkInterface, cPlayer & a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
- int a_CursorX, int a_CursorY, int a_CursorZ,
+ cChunkInterface & a_ChunkInterface,
+ cPlayer & a_Player,
+ const Vector3i a_PlacedBlockPos,
+ eBlockFace a_ClickedBlockFace,
+ const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{
// TODO: Disallow placement where the vine doesn't attach to something properly
BLOCKTYPE BlockType = 0;
NIBBLETYPE BlockMeta;
- a_ChunkInterface.GetBlockTypeMeta({a_BlockX, a_BlockY, a_BlockZ}, BlockType, BlockMeta);
+ a_ChunkInterface.GetBlockTypeMeta(a_PlacedBlockPos, BlockType, BlockMeta);
if (BlockType == m_BlockType)
{
- a_BlockMeta = BlockMeta | DirectionToMetaData(a_BlockFace);
+ a_BlockMeta = BlockMeta | DirectionToMetaData(a_ClickedBlockFace);
}
else
{
- a_BlockMeta = DirectionToMetaData(a_BlockFace);
+ a_BlockMeta = DirectionToMetaData(a_ClickedBlockFace);
}
a_BlockType = m_BlockType;
return true;
diff --git a/src/Blocks/BlockWallSign.h b/src/Blocks/BlockWallSign.h
index 551107d88..87c0355a9 100644
--- a/src/Blocks/BlockWallSign.h
+++ b/src/Blocks/BlockWallSign.h
@@ -33,39 +33,45 @@ public:
- virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override
{
- int BlockX = (a_Chunk.GetPosX() * cChunkDef::Width) + a_RelX;
- int BlockZ = (a_Chunk.GetPosZ() * cChunkDef::Width) + a_RelZ;
- GetBlockCoordsBehindTheSign(a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ), BlockX, BlockZ);
- BLOCKTYPE Type = a_ChunkInterface.GetBlock({BlockX, a_RelY, BlockZ});
-
- return ((Type == E_BLOCK_WALLSIGN) || (Type == E_BLOCK_SIGN_POST) || cBlockInfo::IsSolid(Type));
+ auto NeighborPos = a_RelPos + GetOffsetBehindTheSign(a_Chunk.GetMeta(a_RelPos));
+ BLOCKTYPE NeighborType;
+ if (!a_Chunk.UnboundedRelGetBlockType(NeighborPos, NeighborType))
+ {
+ // The neighbor is not accessible (unloaded chunk), bail out without changing this
+ return true;
+ }
+ return ((NeighborType == E_BLOCK_WALLSIGN) || (NeighborType == E_BLOCK_SIGN_POST) || cBlockInfo::IsSolid(NeighborType));
}
- static void GetBlockCoordsBehindTheSign(NIBBLETYPE a_BlockMeta, int & a_BlockX, int & a_BlockZ)
+ /** Returns the offset from the sign coords to the block to which the wallsign is attached, based on the wallsign's block meta.
+ Asserts / returns a zero vector on wrong meta. */
+ static Vector3i GetOffsetBehindTheSign(NIBBLETYPE a_BlockMeta)
{
switch (a_BlockMeta)
{
- case 2: a_BlockZ++; break;
- case 3: a_BlockZ--; break;
- case 4: a_BlockX++; break;
- case 5: a_BlockX--; break;
- default: break;
+ case 2: return Vector3i( 0, 0, 1);
+ case 3: return Vector3i( 0, 0, -1);
+ case 4: return Vector3i( 1, 0, 0);
+ case 5: return Vector3i(-1, 0, 0);
}
+ ASSERT(!"Invalid wallsign block meta");
+ return Vector3i();
}
- static NIBBLETYPE DirectionToMetaData(eBlockFace a_Direction)
+ /** 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_Direction)
+ switch (a_NeighborBlockFace)
{
case BLOCK_FACE_ZM: return 0x02;
case BLOCK_FACE_ZP: return 0x03;
diff --git a/src/Blocks/BlockWorkbench.h b/src/Blocks/BlockWorkbench.h
index c5eb48657..608754158 100644
--- a/src/Blocks/BlockWorkbench.h
+++ b/src/Blocks/BlockWorkbench.h
@@ -12,24 +12,46 @@
class cBlockWorkbenchHandler:
public cBlockHandler
{
+ using Super = cBlockHandler;
+
public:
- cBlockWorkbenchHandler(BLOCKTYPE a_BlockType)
- : cBlockHandler(a_BlockType)
+
+ cBlockWorkbenchHandler(BLOCKTYPE a_BlockType):
+ Super(a_BlockType)
{
}
- virtual bool OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) 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
{
- cWindow * Window = new cCraftingWindow(a_BlockX, a_BlockY, a_BlockZ);
+ cWindow * Window = new cCraftingWindow(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z);
a_Player.OpenWindow(*Window);
return true;
}
+
+
+
+
virtual bool IsUseable(void) override
{
return true;
}
+
+
+
+
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
{
UNUSED(a_Meta);
diff --git a/src/Blocks/Mixins.h b/src/Blocks/Mixins.h
index cddbb4850..7e581c876 100644
--- a/src/Blocks/Mixins.h
+++ b/src/Blocks/Mixins.h
@@ -189,7 +189,8 @@ public:
cYawRotator(BLOCKTYPE a_BlockType):
Super(a_BlockType)
- {}
+ {
+ }
@@ -197,13 +198,14 @@ public:
virtual bool GetPlacementBlockTypeMeta(
cChunkInterface & a_ChunkInterface, cPlayer & a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
- int a_CursorX, int a_CursorY, int a_CursorZ,
+ const Vector3i a_BlockPos,
+ eBlockFace a_BlockFace,
+ const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{
NIBBLETYPE BaseMeta;
- if (!Super::GetPlacementBlockTypeMeta(a_ChunkInterface, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, a_BlockType, BaseMeta))
+ if (!Super::GetPlacementBlockTypeMeta(a_ChunkInterface, a_Player, a_BlockPos, a_BlockFace, a_CursorPos, a_BlockType, BaseMeta))
{
return false;
}
@@ -259,25 +261,29 @@ class cPitchYawRotator:
public cYawRotator<Base, BitMask, North, East, South, West>
{
using Super = cYawRotator<Base, BitMask, North, East, South, West>;
+
public:
cPitchYawRotator(BLOCKTYPE a_BlockType):
Super(a_BlockType)
- {}
+ {
+ }
virtual bool GetPlacementBlockTypeMeta(
- cChunkInterface & a_ChunkInterface, cPlayer & a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
- int a_CursorX, int a_CursorY, int a_CursorZ,
+ cChunkInterface & a_ChunkInterface,
+ cPlayer & a_Player,
+ const Vector3i a_PlacedBlockPos,
+ eBlockFace a_ClickedBlockFace,
+ const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{
NIBBLETYPE BaseMeta;
- if (!Super::GetPlacementBlockTypeMeta(a_ChunkInterface, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, a_BlockType, BaseMeta))
+ if (!Super::GetPlacementBlockTypeMeta(a_ChunkInterface, a_Player, a_PlacedBlockPos, a_ClickedBlockFace, a_CursorPos, a_BlockType, BaseMeta))
{
return false;
}
diff --git a/src/Blocks/WorldInterface.h b/src/Blocks/WorldInterface.h
index 0967e2bb8..2a39ffbc2 100644
--- a/src/Blocks/WorldInterface.h
+++ b/src/Blocks/WorldInterface.h
@@ -60,6 +60,12 @@ public:
/** Sends the block on those coords to the player */
virtual void SendBlockTo(int a_BlockX, int a_BlockY, int a_BlockZ, cPlayer & a_Player) = 0;
+ /** Sends the block on those coords to the player */
+ inline void SendBlockTo(const Vector3i a_BlockPos, cPlayer & a_Player)
+ {
+ SendBlockTo(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, a_Player);
+ }
+
/** Calls the callback for each player in the list; returns true if all players processed, false if the callback aborted by returning true */
virtual bool ForEachPlayer(cPlayerListCallback a_Callback) = 0;