Refactored block placement workflow.
Multi-blocks can now use the default OnPlayerPlaced() callback in cItemHandler.
This commit is contained in:
@@ -367,37 +367,51 @@ bool cItemHandler::OnPlayerPlace(
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
BLOCKTYPE BlockType;
|
||||
NIBBLETYPE BlockMeta;
|
||||
if (!GetPlacementBlockTypeMeta(&a_World, &a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, BlockType, BlockMeta))
|
||||
|
||||
// Get all the blocks to place:
|
||||
sSetBlockVector blocks;
|
||||
if (!GetBlocksToPlace(a_World, a_Player, a_EquippedItem, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, blocks))
|
||||
{
|
||||
// Handler refused the placement, send that information back to the client:
|
||||
for (const auto & blk: blocks)
|
||||
{
|
||||
a_World.SendBlockTo(blk.GetX(), blk.GetY(), blk.GetZ(), &a_Player);
|
||||
}
|
||||
a_World.SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, &a_Player);
|
||||
a_Player.GetInventory().SendEquippedSlot();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!a_Player.PlaceBlock(a_BlockX, a_BlockY, a_BlockZ, BlockType, BlockMeta))
|
||||
// Try to place the blocks:
|
||||
if (!a_Player.PlaceBlocks(blocks))
|
||||
{
|
||||
// The placement failed, the block has already been re-sent, re-send inventory:
|
||||
// The placement failed, the blocks have already been re-sent, re-send inventory:
|
||||
a_Player.GetInventory().SendEquippedSlot();
|
||||
return false;
|
||||
}
|
||||
|
||||
AString PlaceSound = cBlockInfo::GetPlaceSound(BlockType);
|
||||
float Volume = 1.0f, Pitch = 0.8f;
|
||||
if (PlaceSound == "dig.metal")
|
||||
// Play the placement sound for the main block:
|
||||
for (const auto & blk: blocks)
|
||||
{
|
||||
Pitch = 1.2f;
|
||||
PlaceSound = "dig.stone";
|
||||
}
|
||||
else if (PlaceSound == "random.anvil_land")
|
||||
{
|
||||
Volume = 0.65f;
|
||||
}
|
||||
|
||||
a_World.BroadcastSoundEffect(PlaceSound, a_BlockX + 0.5, a_BlockY + 0.5, a_BlockZ + 0.5, Volume, Pitch);
|
||||
// Find the main block by comparing the coords:
|
||||
if ((blk.GetX() != a_BlockX) || (blk.GetY() != a_BlockY) || (blk.GetZ() != a_BlockZ))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
AString PlaceSound = cBlockInfo::GetPlaceSound(blk.m_BlockType);
|
||||
float Volume = 1.0f, Pitch = 0.8f;
|
||||
if (PlaceSound == "dig.metal")
|
||||
{
|
||||
Pitch = 1.2f;
|
||||
PlaceSound = "dig.stone";
|
||||
}
|
||||
else if (PlaceSound == "random.anvil_land")
|
||||
{
|
||||
Volume = 0.65f;
|
||||
}
|
||||
a_World.BroadcastSoundEffect(PlaceSound, a_BlockX + 0.5, a_BlockY + 0.5, a_BlockZ + 0.5, Volume, Pitch);
|
||||
break;
|
||||
} // for blk - blocks[]
|
||||
|
||||
// Remove the "placed" item:
|
||||
if (a_Player.IsGameModeSurvival())
|
||||
@@ -411,6 +425,27 @@ bool cItemHandler::OnPlayerPlace(
|
||||
|
||||
|
||||
|
||||
bool cItemHandler::GetBlocksToPlace(
|
||||
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,
|
||||
sSetBlockVector & a_BlocksToSet
|
||||
)
|
||||
{
|
||||
BLOCKTYPE BlockType;
|
||||
NIBBLETYPE BlockMeta;
|
||||
if (!GetPlacementBlockTypeMeta(&a_World, &a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, BlockType, BlockMeta))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
a_BlocksToSet.emplace_back(a_BlockX, a_BlockY, a_BlockZ, BlockType, BlockMeta);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cItemHandler::OnItemUse(
|
||||
cWorld * a_World, cPlayer * a_Player, cBlockPluginInterface & a_PluginInterface, const cItem & a_Item,
|
||||
int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace
|
||||
|
||||
Reference in New Issue
Block a user