summaryrefslogtreecommitdiffstats
path: root/src/Items/ItemChest.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/Items/ItemChest.h')
-rw-r--r--src/Items/ItemChest.h62
1 files changed, 32 insertions, 30 deletions
diff --git a/src/Items/ItemChest.h b/src/Items/ItemChest.h
index b8807e5d8..014ccc3e6 100644
--- a/src/Items/ItemChest.h
+++ b/src/Items/ItemChest.h
@@ -25,56 +25,57 @@ public:
/** We need an OnPlayerPlace override because we're processing neighbor chests and changing their metas,
the parent class cannot do that. */
virtual bool OnPlayerPlace(
- cWorld & a_World, cPlayer & a_Player, const cItem & a_EquippedItem,
- int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
- int a_CursorX, int a_CursorY, int a_CursorZ
+ cWorld & a_World,
+ cPlayer & a_Player,
+ const cItem & a_EquippedItem,
+ const Vector3i a_ClickedBlockPos,
+ eBlockFace a_ClickedBlockFace,
+ const Vector3i a_CursorPos
) override
{
- if (a_BlockFace < 0)
+ if (a_ClickedBlockFace < 0)
{
// Clicked in air
return false;
}
- if ((a_BlockY < 0) || (a_BlockY >= cChunkDef::Height))
+ if (!cChunkDef::IsValidHeight(a_ClickedBlockPos.y))
{
// The clicked block is outside the world, ignore this call altogether (#128)
return false;
}
// Check if the block ignores build collision (water, grass etc.):
- BLOCKTYPE clickedBlock;
- NIBBLETYPE clickedBlockMeta;
- Vector3i blockPos(a_BlockX, a_BlockY, a_BlockZ);
- a_World.GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, clickedBlock, clickedBlockMeta);
+ BLOCKTYPE ClickedBlockType;
+ NIBBLETYPE ClickedBlockMeta;
+ a_World.GetBlockTypeMeta(a_ClickedBlockPos, ClickedBlockType, ClickedBlockMeta);
cChunkInterface ChunkInterface(a_World.GetChunkMap());
- auto blockHandler = BlockHandler(clickedBlock);
- if (blockHandler->DoesIgnoreBuildCollision(ChunkInterface, blockPos, a_Player, clickedBlockMeta))
+ auto blockHandler = BlockHandler(ClickedBlockType);
+ Vector3i PlacePos;
+ if (blockHandler->DoesIgnoreBuildCollision(ChunkInterface, a_ClickedBlockPos, a_Player, ClickedBlockMeta))
{
- blockHandler->OnPlayerBreakingBlock(ChunkInterface, a_World, a_Player, blockPos);
+ blockHandler->OnPlayerBreakingBlock(ChunkInterface, a_World, a_Player, a_ClickedBlockPos);
+ PlacePos = a_ClickedBlockPos;
}
else
{
- AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
-
- if ((a_BlockY < 0) || (a_BlockY >= cChunkDef::Height))
+ PlacePos = AddFaceDirection(a_ClickedBlockPos, a_ClickedBlockFace);
+ if (!cChunkDef::IsValidHeight(PlacePos.y))
{
// The block is being placed outside the world, ignore this packet altogether (#128)
return false;
}
- NIBBLETYPE PlaceMeta;
+ // Check if the chest can overwrite the block at PlacePos:
BLOCKTYPE PlaceBlock;
- a_World.GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, PlaceBlock, PlaceMeta);
-
- // Clicked on side of block, make sure that placement won't be cancelled if there is a slab able to be double slabbed.
- // No need to do combinability (dblslab) checks, client will do that here.
- if (blockHandler->DoesIgnoreBuildCollision(ChunkInterface, blockPos, a_Player, clickedBlockMeta))
+ NIBBLETYPE PlaceMeta;
+ a_World.GetBlockTypeMeta(PlacePos, PlaceBlock, PlaceMeta);
+ blockHandler = BlockHandler(PlaceBlock);
+ if (!blockHandler->DoesIgnoreBuildCollision(ChunkInterface, PlacePos, a_Player, PlaceMeta))
{
- // Tried to place a block into another?
- // Happens when you place a block aiming at side of block with a torch on it or stem beside it
return false;
}
+ blockHandler->OnPlayerBreakingBlock(ChunkInterface, a_World, a_Player, PlacePos);
}
// Check that there is at most one single neighbor of the same chest type:
@@ -88,7 +89,8 @@ public:
int NeighborIdx = -1;
for (size_t i = 0; i < ARRAYCOUNT(CrossCoords); i++)
{
- if (a_World.GetBlock(a_BlockX + CrossCoords[i].x, a_BlockY, a_BlockZ + CrossCoords[i].z) != m_ItemType)
+ auto NeighborPos = PlacePos + CrossCoords[i];
+ if (a_World.GetBlock(NeighborPos) != m_ItemType)
{
continue;
}
@@ -100,12 +102,11 @@ public:
NeighborIdx = static_cast<int>(i);
// Check that this neighbor is a single chest:
- int bx = a_BlockX + CrossCoords[i].x;
- int bz = a_BlockZ + CrossCoords[i].z;
for (size_t j = 0; j < ARRAYCOUNT(CrossCoords); j++)
{
- if (a_World.GetBlock(bx + CrossCoords[j].x, a_BlockY, bz + CrossCoords[j].z) == m_ItemType)
+ if (a_World.GetBlock(NeighborPos + CrossCoords[j]) == m_ItemType)
{
+ // Trying to place next to a dblchest
return false;
}
} // for j
@@ -133,13 +134,14 @@ public:
}
default:
{
+ // No neighbor, place based on yaw:
Meta = cBlockChestHandler::PlayerYawToMetaData(yaw);
break;
}
} // switch (NeighborIdx)
// Place the new chest:
- if (!a_Player.PlaceBlock(a_BlockX, a_BlockY, a_BlockZ, ChestBlockType, Meta))
+ if (!a_Player.PlaceBlock(PlacePos.x, PlacePos.y, PlacePos.z, ChestBlockType, Meta))
{
return false;
}
@@ -147,10 +149,10 @@ public:
// Adjust the existing chest, if any:
if (NeighborIdx != -1)
{
- a_World.FastSetBlock(a_BlockX + CrossCoords[NeighborIdx].x, a_BlockY, a_BlockZ + CrossCoords[NeighborIdx].z, ChestBlockType, Meta);
+ a_World.FastSetBlock(PlacePos + CrossCoords[NeighborIdx], ChestBlockType, Meta);
}
- // Remove the "placed" item:
+ // Remove the "placed" item from inventory:
if (a_Player.IsGameModeSurvival())
{
a_Player.GetInventory().RemoveOneEquippedItem();