From 3889b2cac26410650d7ec6f296e0bb19c3debb4b Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 21 Jun 2015 19:49:22 +0200 Subject: Refactored block placement workflow. Multi-blocks can now use the default OnPlayerPlaced() callback in cItemHandler. --- src/Items/ItemHandler.cpp | 71 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 53 insertions(+), 18 deletions(-) (limited to 'src/Items/ItemHandler.cpp') diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp index b7f89809e..a1fa67152 100644 --- a/src/Items/ItemHandler.cpp +++ b/src/Items/ItemHandler.cpp @@ -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") - { - Pitch = 1.2f; - PlaceSound = "dig.stone"; - } - else if (PlaceSound == "random.anvil_land") + // Play the placement sound for the main block: + for (const auto & blk: blocks) { - 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 -- cgit v1.2.3