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/ItemBanner.h | 160 +++++++++++++++++++------------------------------ 1 file changed, 62 insertions(+), 98 deletions(-) (limited to 'src/Items/ItemBanner.h') diff --git a/src/Items/ItemBanner.h b/src/Items/ItemBanner.h index 3f082c5a5..2ebfca44a 100644 --- a/src/Items/ItemBanner.h +++ b/src/Items/ItemBanner.h @@ -24,6 +24,32 @@ public: { } +private: + + virtual bool CommitPlacement(cPlayer & a_Player, const cItem & a_HeldItem, const Vector3i a_PlacePosition, const eBlockFace a_ClickedBlockFace, const Vector3i a_CursorPosition) override + { + // Cannot place a banner at "no face" and from the bottom: + if ((a_ClickedBlockFace == BLOCK_FACE_NONE) || (a_ClickedBlockFace == BLOCK_FACE_BOTTOM)) + { + return false; + } + + if (!TryPlaceBanner(a_Player, a_PlacePosition, a_ClickedBlockFace)) + { + return false; + } + + a_Player.GetWorld()->DoWithBlockEntityAt(a_PlacePosition, [&a_HeldItem](cBlockEntity & a_BlockEntity) + { + ASSERT((a_BlockEntity.GetBlockType() == E_BLOCK_STANDING_BANNER) || (a_BlockEntity.GetBlockType() == E_BLOCK_WALL_BANNER)); + + static_cast(a_BlockEntity).SetBaseColor(static_cast(a_HeldItem.m_ItemDamage)); + return false; + }); + + return true; + } + @@ -36,182 +62,120 @@ public: - - virtual bool GetPlacementBlockTypeMeta( - cWorld * a_World, cPlayer * a_Player, - const Vector3i a_PlacedBlockPos, - eBlockFace a_ClickedBlockFace, - const Vector3i a_CursorPos, - BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta - ) override + static bool TryPlaceBanner(cPlayer & a_Player, const Vector3i a_PlacePosition, const eBlockFace a_ClickedBlockFace) { - a_BlockMeta = 0x00; - const double Rotation = a_Player->GetYaw(); + const auto Rotation = a_Player.GetYaw(); - // Placing on the floor + // Placing on the floor: if (a_ClickedBlockFace == BLOCK_FACE_TOP) { - if ((Rotation >= - 11.25f) && (Rotation < 11.25f)) + NIBBLETYPE Meta; + + if ((Rotation >= -11.25f) && (Rotation < 11.25f)) { // South - a_BlockMeta |= 0x08; + Meta = 0x08; } else if ((Rotation >= 11.25f) && (Rotation < 33.75f)) { // SouthSouthWest - a_BlockMeta |= 0x09; + Meta = 0x09; } else if ((Rotation >= 23.75f) && (Rotation < 56.25f)) { // SouthWest - a_BlockMeta |= 0x0a; + Meta = 0x0a; } else if ((Rotation >= 56.25f) && (Rotation < 78.75f)) { // WestSouthWest - a_BlockMeta |= 0x0b; + Meta = 0x0b; } else if ((Rotation >= 78.75f) && (Rotation < 101.25f)) { // West - a_BlockMeta |= 0x0c; + Meta = 0x0c; } else if ((Rotation >= 101.25f) && (Rotation < 123.75f)) { // WestNorthWest - a_BlockMeta |= 0x0d; + Meta = 0x0d; } else if ((Rotation >= 123.75f) && (Rotation < 146.25f)) { // NorthWest - a_BlockMeta |= 0x0e; + Meta = 0x0e; } else if ((Rotation >= 146.25f) && (Rotation < 168.75f)) { // NorthNorthWest - a_BlockMeta |= 0x0f; + Meta = 0x0f; } else if ((Rotation >= -168.75f) && (Rotation < -146.25f)) { // NorthNorthEast - a_BlockMeta |= 0x01; + Meta = 0x01; } else if ((Rotation >= -146.25f) && (Rotation < -123.75f)) { // NorthEast - a_BlockMeta |= 0x02; + Meta = 0x02; } else if ((Rotation >= -123.75f) && (Rotation < -101.25f)) { // EastNorthEast - a_BlockMeta |= 0x03; + Meta = 0x03; } else if ((Rotation >= -101.25) && (Rotation < -78.75f)) { // East - a_BlockMeta |= 0x04; + Meta = 0x04; } else if ((Rotation >= -78.75) && (Rotation < -56.25f)) { // EastSouthEast - a_BlockMeta |= 0x05; + Meta = 0x05; } else if ((Rotation >= -56.25f) && (Rotation < -33.75f)) { // SouthEast - a_BlockMeta |= 0x06; + Meta = 0x06; } else if ((Rotation >= -33.75f) && (Rotation < -11.25f)) { // SouthSouthEast - a_BlockMeta |= 0x07; + Meta = 0x07; } else // degrees jumping from 180 to -180 { // North - a_BlockMeta |= 0x00; - } - a_BlockType = E_BLOCK_STANDING_BANNER; - } - // placing on the sides - else if (a_ClickedBlockFace != BLOCK_FACE_NONE) - { - if (a_ClickedBlockFace == BLOCK_FACE_EAST) - { - a_BlockMeta |= 0x05; - } - else if (a_ClickedBlockFace == BLOCK_FACE_WEST) - { - a_BlockMeta |= 0x04; + Meta = 0x00; } - else if (a_ClickedBlockFace == BLOCK_FACE_NORTH) - { - a_BlockMeta |= 0x02; - } - else // degrees jumping from 180 to -180 - { - a_BlockMeta |= 0x03; - } - a_BlockType = E_BLOCK_WALL_BANNER; - } - else - { - return false; - } - - return true; - } - + return a_Player.PlaceBlock(a_PlacePosition, E_BLOCK_STANDING_BANNER, Meta); + } + // We must be placing on the side of a block. + NIBBLETYPE Meta; - virtual bool OnPlayerPlace( - cWorld & a_World, - cPlayer & a_Player, - const cItem & a_EquippedItem, - const Vector3i a_ClickedBlockPos, - eBlockFace a_ClickedBlockFace, - const Vector3i a_CursorPos - ) override - { - // Cannot place a banner at "no face" and from the bottom: - if ((a_ClickedBlockFace == BLOCK_FACE_NONE) || (a_ClickedBlockFace == BLOCK_FACE_BOTTOM)) + if (a_ClickedBlockFace == BLOCK_FACE_EAST) { - return true; + Meta = 0x05; } - - // Checks if the banner replaced the block - BLOCKTYPE ClickedBlockType; - NIBBLETYPE ClickedBlockMeta; - a_World.GetBlockTypeMeta(a_ClickedBlockPos, ClickedBlockType, ClickedBlockMeta); - cChunkInterface ChunkInterface(a_World.GetChunkMap()); - bool IsReplacingClickedBlock = cBlockHandler::For(ClickedBlockType).DoesIgnoreBuildCollision(ChunkInterface, a_ClickedBlockPos, a_Player, ClickedBlockMeta); - if (IsReplacingClickedBlock) + else if (a_ClickedBlockFace == BLOCK_FACE_WEST) { - // TODO: There is a bug in the network which prevents the client from receiving the new block entity on placement - // For now the replaced blocks are disabled - return false; + Meta = 0x04; } - - // saving the color of the banner in case it's the players last one - NIBBLETYPE Color = static_cast(a_EquippedItem.m_ItemDamage); - - if (!Super::OnPlayerPlace(a_World, a_Player, a_EquippedItem, a_ClickedBlockPos, a_ClickedBlockFace, a_ClickedBlockPos)) + else if (a_ClickedBlockFace == BLOCK_FACE_NORTH) { - return false; + Meta = 0x02; } - - const auto BannerPos = AddFaceDirection(a_ClickedBlockPos, a_ClickedBlockFace); - a_World.DoWithBlockEntityAt(BannerPos, [Color](cBlockEntity & a_BlockEntity) + else // degrees jumping from 180 to -180 { - ASSERT((a_BlockEntity.GetBlockType() == E_BLOCK_STANDING_BANNER) || (a_BlockEntity.GetBlockType() == E_BLOCK_WALL_BANNER)); - - auto & Banner = static_cast(a_BlockEntity); - Banner.SetBaseColor(Color); - return false; - }); + Meta = 0x03; + } - return true; + return a_Player.PlaceBlock(a_PlacePosition, E_BLOCK_WALL_BANNER, Meta); } }; -- cgit v1.2.3