From f8de67aace4e65ff4c34a1f46f6d8b258b6839aa Mon Sep 17 00:00:00 2001 From: 12xx12 <12xx12100@gmail.com> Date: Thu, 17 Sep 2020 16:16:20 +0200 Subject: Added end portal and enchanting table block entities --- src/Blocks/BlockEnchantingTable.h | 84 +++++++++++++++++++ src/Blocks/BlockEnchantmentTable.h | 64 --------------- src/Blocks/BlockEndPortalFrame.h | 160 ------------------------------------- src/Blocks/BlockHandler.cpp | 6 +- src/Blocks/CMakeLists.txt | 2 +- 5 files changed, 88 insertions(+), 228 deletions(-) create mode 100644 src/Blocks/BlockEnchantingTable.h delete mode 100644 src/Blocks/BlockEnchantmentTable.h (limited to 'src/Blocks') diff --git a/src/Blocks/BlockEnchantingTable.h b/src/Blocks/BlockEnchantingTable.h new file mode 100644 index 000000000..ddd25182b --- /dev/null +++ b/src/Blocks/BlockEnchantingTable.h @@ -0,0 +1,84 @@ + +#pragma once + +#include "BlockHandler.h" +#include "../Item.h" +#include "../UI/EnchantingWindow.h" +#include "../BlockEntities/EnchantingTableEntity.h" +#include "../Entities/Player.h" + + + + + +class cBlockEnchantingTableHandler : + public cBlockHandler +{ + using Super = cBlockHandler; + +public: + + using Super::Super; + +private: + + virtual bool OnUse( + cChunkInterface & a_ChunkInterface, + cWorldInterface & a_WorldInterface, + cPlayer & a_Player, + const Vector3i a_BlockPos, + eBlockFace a_BlockFace, + const Vector3i a_CursorPos + ) override + { + AString WindowName = "Enchant"; + a_WorldInterface.DoWithBlockEntityAt(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, [&WindowName](cBlockEntity & a_Entity) + { + if (a_Entity.GetBlockType() != E_BLOCK_ENCHANTMENT_TABLE) + { + return false; + } + + const auto & EnchantingTable = static_cast(a_Entity); + const auto & CustomName = EnchantingTable.GetCustomName(); + if (!CustomName.empty()) + { + WindowName = CustomName; + } + + return true; + }); + + cWindow * Window = new cEnchantingWindow(a_BlockPos, std::move(WindowName)); + a_Player.OpenWindow(*Window); + + return true; + } + + + virtual bool IsUseable(void) override + { + return true; + } + + + virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override + { + if ((a_BlockEntity == nullptr) || (a_BlockEntity->GetBlockType() != E_BLOCK_ENCHANTMENT_TABLE)) + { + return {}; + } + + auto & EnchantingTable = static_cast(*a_BlockEntity); + cItem Item = cItem(E_BLOCK_ENCHANTMENT_TABLE); + Item.m_CustomName = EnchantingTable.GetCustomName(); + return Item; + } + + + virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override + { + UNUSED(a_Meta); + return 29; + } +}; diff --git a/src/Blocks/BlockEnchantmentTable.h b/src/Blocks/BlockEnchantmentTable.h deleted file mode 100644 index 48560451b..000000000 --- a/src/Blocks/BlockEnchantmentTable.h +++ /dev/null @@ -1,64 +0,0 @@ - -#pragma once - -#include "BlockHandler.h" -#include "../UI/EnchantingWindow.h" -#include "../Entities/Player.h" - - - - - -class cBlockEnchantmentTableHandler: - public cBlockHandler -{ - using Super = cBlockHandler; - -public: - - cBlockEnchantmentTableHandler(BLOCKTYPE a_BlockType): - Super(a_BlockType) - { - } - - - - - - virtual bool OnUse( - cChunkInterface & a_ChunkInterface, - cWorldInterface & a_WorldInterface, - cPlayer & a_Player, - const Vector3i a_BlockPos, - eBlockFace a_BlockFace, - const Vector3i a_CursorPos - ) override - { - cWindow * Window = new cEnchantingWindow(a_BlockPos); - a_Player.OpenWindow(*Window); - return true; - } - - - - - - virtual bool IsUseable(void) override - { - return true; - } - - - - - - virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override - { - UNUSED(a_Meta); - return 29; - } -}; - - - - diff --git a/src/Blocks/BlockEndPortalFrame.h b/src/Blocks/BlockEndPortalFrame.h index be67bb4f9..567de8bcc 100644 --- a/src/Blocks/BlockEndPortalFrame.h +++ b/src/Blocks/BlockEndPortalFrame.h @@ -82,166 +82,6 @@ public: - virtual void OnPlaced(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override - { - // E_META_END_PORTAL_FRAME_EYE is the bit which signifies the eye of ender is in it. - // LOG("PortalPlaced, meta %d", a_BlockMeta); - if ((a_BlockMeta & E_META_END_PORTAL_FRAME_EYE) == E_META_END_PORTAL_FRAME_EYE) - { - // LOG("Location is %d %d %d", a_BlockX, a_BlockY, a_BlockZ); - // Direction is the first two bits, masked by 0x3 - FindAndSetPortal(a_BlockPos, a_BlockMeta & 3, a_ChunkInterface, a_WorldInterface); - } - } - - - - - - /** Returns false if portal cannot be made, true if portal was made. */ - bool FindAndSetPortal(Vector3i a_FirstFrame, NIBBLETYPE a_Direction, cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface) - { - /* - PORTAL FINDING ALGORITH - ======================= - - Get clicked base block - - Check diagonally (clockwise) for another portal block - - if exists, and has eye, Continue. Abort if any are facing the wrong direction. - - if doesn't exist, check horizontally (the block to the left of this block). Abort if there is no horizontal block. - - After a corner has been met, traverse the portal clockwise, ensuring valid portal frames connect the rectangle. - - Track the NorthWest Corner, and the dimensions. - - If dimensions are valid, create the portal. - */ - - static_assert((E_META_END_PORTAL_FRAME_ZM - E_META_END_PORTAL_FRAME_XM) == 1, "Should be going clockwise"); - - const int MIN_PORTAL_WIDTH = 3; - const int MAX_PORTAL_WIDTH = 4; - - // Directions to use for the clockwise traversal. - static const Vector3i Left[] = - { - { 1, 0, 0}, // 0, South, left block is East / XP - { 0, 0, 1}, // 1, West, left block is South / ZP - {-1, 0, 0}, // 2, North, left block is West / XM - { 0, 0, -1}, // 3, East, left block is North / ZM - }; - static const Vector3i LeftForward[] = - { - { 1, 0, 1}, // 0, South, left block is SouthEast / XP ZP - {-1, 0, 1}, // 1, West, left block is SouthWest / XM ZP - {-1, 0, -1}, // 2, North, left block is NorthWest / XM ZM - { 1, 0, -1}, // 3, East, left block is NorthEast / XP ZM - }; - - - int EdgesComplete = -1; // We start search _before_ finding the first edge - Vector3i NorthWestCorner; - int EdgeWidth[4] = { 1, 1, 1, 1 }; - NIBBLETYPE CurrentDirection = a_Direction; - Vector3i CurrentPos = a_FirstFrame; - - // Scan clockwise until we have seen all 4 edges - while (EdgesComplete < 4) - { - // Check if we are at a corner - Vector3i NextPos = CurrentPos + LeftForward[CurrentDirection]; - if (IsPortalFrame(a_ChunkInterface.GetBlock(NextPos))) - { - // We have found the corner, move clockwise to next edge - if (CurrentDirection == E_META_END_PORTAL_FRAME_XP) - { - // We are on the NW (XM, ZM) Corner - // Relative to the previous frame, the portal should appear to the right of this portal frame. - NorthWestCorner = NextPos - Left[CurrentDirection]; - } - - if (EdgesComplete == -1) - { - // Reset current width, we will revisit it last - EdgeWidth[CurrentDirection] = 1; - } - - // Rotate 90 degrees clockwise - CurrentDirection = (CurrentDirection + 1) % 4; - EdgesComplete++; - } - else - { - // We are not at a corner, keep walking the edge - NextPos = CurrentPos + Left[CurrentDirection]; - - EdgeWidth[CurrentDirection]++; - if (EdgeWidth[CurrentDirection] > MAX_PORTAL_WIDTH) - { - // Don't build a portal that is too long. - return false; - } - } - - if (!IsValidFrameAtPos(a_ChunkInterface, NextPos, CurrentDirection)) - { - // Neither the edge nor the corner are valid portal blocks. - return false; - } - - CurrentPos = NextPos; - } - - if ((EdgeWidth[0] != EdgeWidth[2]) || (EdgeWidth[1] != EdgeWidth[3])) - { - // Mismatched Portal Dimensions. - return false; - } - if ((EdgeWidth[0] < MIN_PORTAL_WIDTH) || (EdgeWidth[1] < MIN_PORTAL_WIDTH)) - { - // Portal too small. - return false; - } - - // LOG("NW corner (low corner) %d %d %d", Corner.x, Corner.y, Corner.z); - // LOG("%d by %d", Width[0], Width[1]); - for (int i = 0; i < EdgeWidth[0]; i++) - { - for (int j = 0; j < EdgeWidth[1]; j++) - { - a_ChunkInterface.SetBlock(NorthWestCorner.x + i, NorthWestCorner.y, NorthWestCorner.z + j, E_BLOCK_END_PORTAL, 0); - // TODO: Create block entity so portal doesn't become invisible on relog. - } - } - return true; - } - - - - - - /** Return true if this block is a portal frame, has an eye, and is facing the correct direction. */ - bool IsValidFrameAtPos(cChunkInterface & a_ChunkInterface, Vector3i a_BlockPos, NIBBLETYPE a_ShouldFace) - { - BLOCKTYPE BlockType; - NIBBLETYPE BlockMeta; - - return ( - a_ChunkInterface.GetBlockTypeMeta(a_BlockPos, BlockType, BlockMeta) && - (BlockType == E_BLOCK_END_PORTAL_FRAME) && - (BlockMeta == (a_ShouldFace | E_META_END_PORTAL_FRAME_EYE)) - ); - } - - - - - /** Return true if this block is a portal frame. */ - bool IsPortalFrame(BLOCKTYPE BlockType) - { - return (BlockType == E_BLOCK_END_PORTAL_FRAME); - } - - - - - virtual bool IsClickedThrough(void) override { // TODO: Colision diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index 7938ec065..20ba6edb5 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -27,7 +27,7 @@ #include "BlockDirt.h" #include "BlockDoor.h" #include "BlockDropSpenser.h" -#include "BlockEnchantmentTable.h" +#include "BlockEnchantingTable.h" #include "BlockEnderchest.h" #include "BlockEndPortalFrame.h" #include "BlockEntity.h" @@ -263,7 +263,7 @@ namespace cBlockDropSpenserHandler BlockDropperHandler (E_BLOCK_DROPPER); cBlockHandler BlockEmeraldBlockHandler (E_BLOCK_EMERALD_BLOCK); cBlockOreHandler BlockEmeraldOreHandler (E_BLOCK_EMERALD_ORE); - cBlockEnchantmentTableHandler BlockEnchantmentTableHandler (E_BLOCK_ENCHANTMENT_TABLE); + cBlockEnchantingTableHandler BlockEnchantingTableHandler (E_BLOCK_ENCHANTMENT_TABLE); cBlockHandler BlockEndBricksHandler (E_BLOCK_END_BRICKS); cBlockHandler BlockEndGatewayHandler (E_BLOCK_END_GATEWAY); cBlockEndPortalFrameHandler BlockEndPortalFrameHandler (E_BLOCK_END_PORTAL_FRAME); @@ -735,7 +735,7 @@ cBlockHandler & cBlockHandler::GetBlockHandler(BLOCKTYPE a_BlockType) case E_BLOCK_DROPPER: return BlockDropperHandler; case E_BLOCK_EMERALD_BLOCK: return BlockEmeraldBlockHandler; case E_BLOCK_EMERALD_ORE: return BlockEmeraldOreHandler; - case E_BLOCK_ENCHANTMENT_TABLE: return BlockEnchantmentTableHandler; + case E_BLOCK_ENCHANTMENT_TABLE: return BlockEnchantingTableHandler; case E_BLOCK_ENDER_CHEST: return BlockEnderChestHandler; case E_BLOCK_END_BRICKS: return BlockEndBricksHandler; case E_BLOCK_END_GATEWAY: return BlockEndGatewayHandler; diff --git a/src/Blocks/CMakeLists.txt b/src/Blocks/CMakeLists.txt index 87464bd04..a3d1e5cb2 100644 --- a/src/Blocks/CMakeLists.txt +++ b/src/Blocks/CMakeLists.txt @@ -29,7 +29,7 @@ target_sources( BlockDirt.h BlockDoor.h BlockDropSpenser.h - BlockEnchantmentTable.h + BlockEnchantingTable.h BlockEnderchest.h BlockEndPortalFrame.h BlockEntity.h -- cgit v1.2.3