From a62b2b1be2103d7de2fd66c7304b7473e369be3c Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 5 May 2021 14:25:10 +0100 Subject: Move item placement into item handlers (#5184) * Move item placement into item handlers + Add appropriate CanBeAt checks in cPlayer::PlaceBlocks, into which all placement handlers call. * Partly addresses #5157 * Fixes #4878 * Fixes #2919 * Fixes #4629 * Fixes #4239 * Fixes #4849 Co-authored-by: changyong guo Co-authored-by: Xotheus Co-authored-by: Krist Pregracke * Review fixes * Update APIDesc.lua * Rename Co-authored-by: changyong guo Co-authored-by: Xotheus Co-authored-by: Krist Pregracke --- src/Items/ItemDoor.h | 67 ++++++++++++++++++++-------------------------------- 1 file changed, 26 insertions(+), 41 deletions(-) (limited to 'src/Items/ItemDoor.h') diff --git a/src/Items/ItemDoor.h b/src/Items/ItemDoor.h index aec6bc0fe..b85f018bc 100644 --- a/src/Items/ItemDoor.h +++ b/src/Items/ItemDoor.h @@ -25,13 +25,7 @@ public: - virtual bool GetBlocksToPlace( - cWorld & a_World, cPlayer & a_Player, const cItem & a_EquippedItem, - const Vector3i a_PlacedBlockPos, - eBlockFace a_ClickedBlockFace, - const Vector3i a_CursorPos, - sSetBlockVector & a_BlocksToSet - ) override + virtual bool CommitPlacement(cPlayer & a_Player, const cItem & a_HeldItem, const Vector3i a_PlacePosition, const eBlockFace a_ClickedBlockFace, const Vector3i a_CursorPosition) override { // Vanilla only allows door placement while clicking on the top face of the block below the door: if (a_ClickedBlockFace != BLOCK_FACE_TOP) @@ -39,19 +33,6 @@ public: return false; } - // Door (bottom block) can be placed in Y range of [1, 254]: - if ((a_PlacedBlockPos.y < 1) || (a_PlacedBlockPos.y >= cChunkDef::Height - 2)) - { - return false; - } - - // The door needs a compatible block below it: - auto BelowPos = a_PlacedBlockPos.addedY(-1); - if (!cBlockDoorHandler::CanBeOn(a_World.GetBlock(BelowPos), a_World.GetBlockMeta(BelowPos))) - { - return false; - } - // Get the block type of the door to place: BLOCKTYPE BlockType; switch (m_ItemType) @@ -63,22 +44,22 @@ public: case E_ITEM_JUNGLE_DOOR: BlockType = E_BLOCK_JUNGLE_DOOR; break; case E_ITEM_DARK_OAK_DOOR: BlockType = E_BLOCK_DARK_OAK_DOOR; break; case E_ITEM_ACACIA_DOOR: BlockType = E_BLOCK_ACACIA_DOOR; break; - default: - { - ASSERT(!"Unhandled door type"); - return false; - } + default: UNREACHABLE("Unhandled door type"); } - // Check the two blocks that will get replaced by the door: - auto UpperBlockPos = a_PlacedBlockPos.addedY(1); - BLOCKTYPE LowerBlockType = a_World.GetBlock(a_PlacedBlockPos); - BLOCKTYPE UpperBlockType = a_World.GetBlock(UpperBlockPos); - if ( - !cBlockDoorHandler::CanReplaceBlock(LowerBlockType) || - !cBlockDoorHandler::CanReplaceBlock(UpperBlockType)) + const auto & World = *a_Player.GetWorld(); + const auto UpperBlockPosition = a_PlacePosition.addedY(1); + + // Check the block that will get replaced by the door: { - return false; + BLOCKTYPE TopType; + NIBBLETYPE TopMeta; + World.GetBlockTypeMeta(UpperBlockPosition, TopType, TopMeta); + + if (!cBlockHandler::For(TopType).DoesIgnoreBuildCollision(World, a_HeldItem, UpperBlockPosition, TopMeta, a_ClickedBlockFace, false)) + { + return false; + } } // Get the coords of the neighboring blocks: @@ -86,22 +67,24 @@ public: Vector3i RelDirToOutside = cBlockDoorHandler::GetRelativeDirectionToOutside(LowerBlockMeta); Vector3i LeftNeighborPos = RelDirToOutside; LeftNeighborPos.TurnCW(); - LeftNeighborPos.Move(a_PlacedBlockPos); + LeftNeighborPos.Move(a_PlacePosition); Vector3i RightNeighborPos = RelDirToOutside; RightNeighborPos.TurnCCW(); - RightNeighborPos.Move(a_PlacedBlockPos); + RightNeighborPos.Move(a_PlacePosition); // Decide whether the hinge is on the left (default) or on the right: NIBBLETYPE UpperBlockMeta = 0x08; - BLOCKTYPE LeftNeighborBlock = a_World.GetBlock(LeftNeighborPos); - BLOCKTYPE RightNeighborBlock = a_World.GetBlock(RightNeighborPos); + BLOCKTYPE LeftNeighborBlock = World.GetBlock(LeftNeighborPos); + BLOCKTYPE RightNeighborBlock = World.GetBlock(RightNeighborPos); + /* // DEBUG: - FLOGD("Door being placed at {0}", a_PlacedBlockPos); + FLOGD("Door being placed at {0}", a_PlacePosition); FLOGD("RelDirToOutside: {0}", RelDirToOutside); FLOGD("Left neighbor at {0}: {1} ({2})", LeftNeighborPos, LeftNeighborBlock, ItemTypeToString(LeftNeighborBlock)); FLOGD("Right neighbor at {0}: {1} ({2})", RightNeighborPos, RightNeighborBlock, ItemTypeToString(RightNeighborBlock)); */ + if ( cBlockDoorHandler::IsDoorBlockType(LeftNeighborBlock) || // The block to the left is a door block ( @@ -116,9 +99,11 @@ public: } // Set the blocks: - a_BlocksToSet.emplace_back(a_PlacedBlockPos, BlockType, LowerBlockMeta); - a_BlocksToSet.emplace_back(UpperBlockPos, BlockType, UpperBlockMeta); - return true; + return a_Player.PlaceBlocks( + { + { a_PlacePosition, BlockType, LowerBlockMeta }, + { UpperBlockPosition, BlockType, UpperBlockMeta } + }); } -- cgit v1.2.3