From f40aba941eaf69b52ac0fbe3d8cea1ea349b97a6 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Wed, 8 Apr 2020 21:35:08 +0100 Subject: Add mixins for blocks that rotate based on player yaw at placement Also add observer block handler. --- src/Blocks/BlockBed.h | 22 +----- src/Blocks/BlockChest.h | 24 ++++--- src/Blocks/BlockComparator.h | 16 +---- src/Blocks/BlockDoor.h | 40 +---------- src/Blocks/BlockDropSpenser.h | 40 +---------- src/Blocks/BlockEnderchest.h | 47 +------------ src/Blocks/BlockFenceGate.h | 46 +------------ src/Blocks/BlockFurnace.h | 23 +------ src/Blocks/BlockGlazedTerracotta.h | 19 +----- src/Blocks/BlockHandler.cpp | 2 + src/Blocks/BlockHopper.h | 22 +----- src/Blocks/BlockObserver.h | 19 ++++++ src/Blocks/BlockPiston.cpp | 16 ----- src/Blocks/BlockPiston.h | 48 +------------ src/Blocks/BlockPumpkin.h | 43 +----------- src/Blocks/BlockRedstoneRepeater.h | 43 +----------- src/Blocks/CMakeLists.txt | 1 + src/Blocks/Mixins.h | 134 +++++++++++++++++++++++++++++++++++++ src/Items/ItemBed.h | 2 +- src/Items/ItemComparator.h | 4 +- src/Items/ItemDoor.h | 2 +- src/Items/ItemRedstoneRepeater.h | 2 +- 22 files changed, 202 insertions(+), 413 deletions(-) create mode 100644 src/Blocks/BlockObserver.h diff --git a/src/Blocks/BlockBed.h b/src/Blocks/BlockBed.h index bedc383e1..3d35b2bf5 100644 --- a/src/Blocks/BlockBed.h +++ b/src/Blocks/BlockBed.h @@ -16,9 +16,9 @@ class cWorldInterface; class cBlockBedHandler : - public cMetaRotator + public cYawRotator { - using super = cMetaRotator; + using super = cYawRotator; public: @@ -41,24 +41,6 @@ public: - // Bed specific helper functions - static NIBBLETYPE RotationToMetaData(double a_Rotation) - { - a_Rotation += 180 + (180 / 4); // So its not aligned with axis - if (a_Rotation > 360) - { - a_Rotation -= 360; - } - - a_Rotation = (a_Rotation / 360) * 4; - - return (static_cast(a_Rotation + 2)) % 4; - } - - - - - static Vector3i MetaDataToDirection(NIBBLETYPE a_MetaData) { switch (a_MetaData) diff --git a/src/Blocks/BlockChest.h b/src/Blocks/BlockChest.h index 0e277532e..2176bba96 100644 --- a/src/Blocks/BlockChest.h +++ b/src/Blocks/BlockChest.h @@ -11,9 +11,9 @@ class cBlockChestHandler : - public cMetaRotator, 0x07, 0x02, 0x05, 0x03, 0x04> + public cYawRotator> { - using super = cMetaRotator, 0x07, 0x02, 0x05, 0x03, 0x04>; + using super = cYawRotator>; public: @@ -33,8 +33,6 @@ public: BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta ) override { - a_BlockType = m_BlockType; - // Is there a doublechest already next to this block? if (!CanBeAt(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ)) { @@ -42,12 +40,20 @@ public: return false; } - // Check if this forms a doublechest, if so, need to adjust the meta: + // Try to read double-chest information: cBlockArea Area; if (!Area.Read(a_ChunkInterface, a_BlockX - 1, a_BlockX + 1, a_BlockY, a_BlockY, a_BlockZ - 1, a_BlockZ + 1)) { return false; } + + // Get meta as if this was a single-chest: + if (!super::GetPlacementBlockTypeMeta(a_ChunkInterface, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, a_BlockType, a_BlockMeta)) + { + return false; + } + + // Check if this forms a doublechest, if so, need to adjust the meta: double yaw = a_Player.GetYaw(); if ( (Area.GetRelBlockType(0, 0, 1) == m_BlockType) || @@ -58,17 +64,15 @@ public: return true; } if ( - (Area.GetRelBlockType(0, 0, 1) == m_BlockType) || - (Area.GetRelBlockType(2, 0, 1) == m_BlockType) + (Area.GetRelBlockType(1, 0, 0) == m_BlockType) || + (Area.GetRelBlockType(1, 0, 2) == m_BlockType) ) { - // FIXME: This is unreachable, as the condition is the same as the above one a_BlockMeta = (yaw < 0) ? 4 : 5; return true; } - // Single chest, get meta from rotation only - a_BlockMeta = PlayerYawToMetaData(yaw); + return true; } diff --git a/src/Blocks/BlockComparator.h b/src/Blocks/BlockComparator.h index e4dca5d77..0826e3133 100644 --- a/src/Blocks/BlockComparator.h +++ b/src/Blocks/BlockComparator.h @@ -10,9 +10,9 @@ class cBlockComparatorHandler : - public cMetaRotator + public cYawRotator { - using super = cMetaRotator; + using super = cYawRotator; public: @@ -50,18 +50,6 @@ public: return cItem(E_ITEM_COMPARATOR, 1, 0); } - virtual bool GetPlacementBlockTypeMeta( - cChunkInterface & a_ChunkInterface, cPlayer & a_Player, - int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, - int a_CursorX, int a_CursorY, int a_CursorZ, - BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta - ) override - { - a_BlockType = m_BlockType; - a_BlockMeta = cBlockRedstoneRepeaterHandler::RepeaterRotationToMetaData(a_Player.GetYaw()); - return true; - } - inline static bool IsInSubtractionMode(NIBBLETYPE a_Meta) { return ((a_Meta & 0x4) == 0x4); diff --git a/src/Blocks/BlockDoor.h b/src/Blocks/BlockDoor.h index ccb34c5a9..61185f562 100644 --- a/src/Blocks/BlockDoor.h +++ b/src/Blocks/BlockDoor.h @@ -12,9 +12,9 @@ class cBlockDoorHandler : - public cMetaRotator + public cYawRotator { - using super = cMetaRotator; + using super = cYawRotator; public: @@ -50,9 +50,7 @@ public: return false; } - a_BlockType = m_BlockType; - a_BlockMeta = PlayerYawToMetaData(a_Player.GetYaw()); - return true; + return super::GetPlacementBlockTypeMeta(a_ChunkInterface, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, a_BlockType, a_BlockMeta); } virtual cBoundingBox GetPlacementCollisionBox(BLOCKTYPE a_XM, BLOCKTYPE a_XP, BLOCKTYPE a_YM, BLOCKTYPE a_YP, BLOCKTYPE a_ZM, BLOCKTYPE a_ZP) override; @@ -146,38 +144,6 @@ public: - /** Converts the player's yaw to placed door's blockmeta */ - inline static NIBBLETYPE PlayerYawToMetaData(double a_Yaw) - { - ASSERT((a_Yaw >= -180) && (a_Yaw < 180)); - - a_Yaw += 90 + 45; - if (a_Yaw > 360) - { - a_Yaw -= 360; - } - if ((a_Yaw >= 0) && (a_Yaw < 90)) - { - return 0x00; - } - else if ((a_Yaw >= 180) && (a_Yaw < 270)) - { - return 0x02; - } - else if ((a_Yaw >= 90) && (a_Yaw < 180)) - { - return 0x01; - } - else - { - return 0x03; - } - } - - - - - /** Returns a vector pointing one block in the direction the door is facing (where the outside is). */ inline static Vector3i GetRelativeDirectionToOutside(NIBBLETYPE a_BlockMeta) { diff --git a/src/Blocks/BlockDropSpenser.h b/src/Blocks/BlockDropSpenser.h index ce98940d2..df29ca14a 100644 --- a/src/Blocks/BlockDropSpenser.h +++ b/src/Blocks/BlockDropSpenser.h @@ -14,9 +14,9 @@ class cBlockDropSpenserHandler : - public cMetaRotator + public cPitchYawRotator { - using super = cMetaRotator; + using super = cPitchYawRotator; public: @@ -29,24 +29,6 @@ public: - virtual bool GetPlacementBlockTypeMeta( - cChunkInterface & a_ChunkInterface, cPlayer & a_Player, - int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, - int a_CursorX, int a_CursorY, int a_CursorZ, - BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta - ) override - { - a_BlockType = m_BlockType; - - // FIXME: Do not use cPiston class for dispenser placement! - a_BlockMeta = cBlockPistonHandler::RotationPitchToMetaData(a_Player.GetYaw(), a_Player.GetPitch()); - return true; - } - - - - - virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override { cItems res(cItem(m_BlockType, 1)); @@ -62,24 +44,6 @@ public: - virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) override - { - // Bit 0x08 is a flag. Lowest three bits are position. - NIBBLETYPE OtherMeta = a_Meta & 0x08; - // Mirrors defined by a table. (Source, minecraft.gamepedia.com) - switch (a_Meta & 0x07) - { - case 0x00: return 0x01 + OtherMeta; // Down -> Up - case 0x01: return 0x00 + OtherMeta; // Up -> Down - } - // Not Facing Up or Down; No change. - return a_Meta; - } - - - - - virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override { UNUSED(a_Meta); diff --git a/src/Blocks/BlockEnderchest.h b/src/Blocks/BlockEnderchest.h index f233468f4..f3df6da28 100644 --- a/src/Blocks/BlockEnderchest.h +++ b/src/Blocks/BlockEnderchest.h @@ -8,9 +8,9 @@ class cBlockEnderchestHandler : - public cMetaRotator + public cYawRotator { - using super = cMetaRotator; + using super = cYawRotator; public: @@ -44,48 +44,7 @@ public: return {}; } - - - - - virtual bool GetPlacementBlockTypeMeta( - cChunkInterface & a_ChunkInterface, cPlayer & a_Player, - int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, - int a_CursorX, int a_CursorY, int a_CursorZ, - BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta - ) override - { - a_BlockType = m_BlockType; - a_BlockMeta = RotationToMetaData(a_Player.GetYaw()); - return true; - } - - static NIBBLETYPE RotationToMetaData(double a_Rotation) - { - a_Rotation += 90 + 45; // So its not aligned with axis - - if (a_Rotation > 360.f) - { - a_Rotation -= 360.f; - } - if ((a_Rotation >= 0.f) && (a_Rotation < 90.f)) - { - return 0x4; - } - else if ((a_Rotation >= 180) && (a_Rotation < 270)) - { - return 0x5; - } - else if ((a_Rotation >= 90) && (a_Rotation < 180)) - { - return 0x2; - } - else - { - return 0x3; - } - } -} ; +}; diff --git a/src/Blocks/BlockFenceGate.h b/src/Blocks/BlockFenceGate.h index c56925633..5646c51b2 100644 --- a/src/Blocks/BlockFenceGate.h +++ b/src/Blocks/BlockFenceGate.h @@ -9,9 +9,9 @@ class cBlockFenceGateHandler : - public cClearMetaOnDrop> + public cClearMetaOnDrop> { - using super = cClearMetaOnDrop>; + using super = cClearMetaOnDrop>; public: @@ -20,22 +20,10 @@ public: { } - virtual bool GetPlacementBlockTypeMeta( - cChunkInterface & a_ChunkInterface, cPlayer & a_Player, - int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, - int a_CursorX, int a_CursorY, int a_CursorZ, - BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta - ) override - { - a_BlockType = m_BlockType; - a_BlockMeta = PlayerYawToMetaData(a_Player.GetYaw()); - return true; - } - virtual bool OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override { NIBBLETYPE OldMetaData = a_ChunkInterface.GetBlockMeta({a_BlockX, a_BlockY, a_BlockZ}); - NIBBLETYPE NewMetaData = PlayerYawToMetaData(a_Player.GetYaw()); + NIBBLETYPE NewMetaData = YawToMetaData(a_Player.GetYaw()); OldMetaData ^= 4; // Toggle the gate if ((OldMetaData & 1) == (NewMetaData & 1)) @@ -62,34 +50,6 @@ public: return true; } - /** Converts the player's yaw to placed gate's blockmeta */ - inline static NIBBLETYPE PlayerYawToMetaData(double a_Yaw) - { - ASSERT((a_Yaw >= -180) && (a_Yaw < 180)); - - a_Yaw += 360 + 45; - if (a_Yaw > 360) - { - a_Yaw -= 360; - } - if ((a_Yaw >= 0) && (a_Yaw < 90)) - { - return 0x0; - } - else if ((a_Yaw >= 180) && (a_Yaw < 270)) - { - return 0x2; - } - else if ((a_Yaw >= 90) && (a_Yaw < 180)) - { - return 0x1; - } - else - { - return 0x3; - } - } - virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override { UNUSED(a_Meta); diff --git a/src/Blocks/BlockFurnace.h b/src/Blocks/BlockFurnace.h index 9a59f95f8..10606242b 100644 --- a/src/Blocks/BlockFurnace.h +++ b/src/Blocks/BlockFurnace.h @@ -9,9 +9,9 @@ class cBlockFurnaceHandler : - public cMetaRotator + public cYawRotator { - using super = cMetaRotator; + using super = cYawRotator; public: @@ -24,25 +24,6 @@ public: - virtual bool GetPlacementBlockTypeMeta( - cChunkInterface & a_ChunkInterface, cPlayer & a_Player, - int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, - int a_CursorX, int a_CursorY, int a_CursorZ, - BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta - ) override - { - a_BlockType = m_BlockType; - - // FIXME: Do not use cPiston class for furnace placement! - a_BlockMeta = cBlockPistonHandler::RotationPitchToMetaData(a_Player.GetYaw(), 0); - - return true; - } - - - - - virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override { cItems res(cItem(E_BLOCK_FURNACE, 1)); // We can't drop a lit furnace diff --git a/src/Blocks/BlockGlazedTerracotta.h b/src/Blocks/BlockGlazedTerracotta.h index 380c3c923..44ebd7012 100644 --- a/src/Blocks/BlockGlazedTerracotta.h +++ b/src/Blocks/BlockGlazedTerracotta.h @@ -6,9 +6,9 @@ class cBlockGlazedTerracottaHandler: - public cClearMetaOnDrop + public cClearMetaOnDrop> { - using super = cClearMetaOnDrop; + using super = cClearMetaOnDrop>; public: @@ -16,19 +16,4 @@ public: { } - virtual bool GetPlacementBlockTypeMeta( - cChunkInterface & a_ChunkInterface, cPlayer & a_Player, - int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, - int a_CursorX, int a_CursorY, int a_CursorZ, - BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta - ) override - { - a_BlockType = m_BlockType; - - // FIXME: Do not use cPiston class for furnace placement! - a_BlockMeta = cBlockPistonHandler::RotationPitchToMetaData(a_Player.GetYaw(), 0); - - return true; - } - }; diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index f690d7448..0a6462348 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -58,6 +58,7 @@ #include "BlockMycelium.h" #include "BlockNetherrack.h" #include "BlockNetherWart.h" +#include "BlockObserver.h" #include "BlockOre.h" #include "BlockPiston.h" #include "BlockPlanks.h" @@ -303,6 +304,7 @@ static cBlockHandler * CreateBlockHandler(BLOCKTYPE a_BlockType) case E_BLOCK_OAK_DOOR: return new cBlockDoorHandler (a_BlockType); case E_BLOCK_OAK_FENCE_GATE: return new cBlockFenceGateHandler (a_BlockType); case E_BLOCK_OAK_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType); + case E_BLOCK_OBSERVER: return new cBlockObserverHandler (a_BlockType); case E_BLOCK_ORANGE_GLAZED_TERRACOTTA: return new cBlockGlazedTerracottaHandler(a_BlockType); case E_BLOCK_PACKED_ICE: return new cBlockIceHandler (a_BlockType); case E_BLOCK_PINK_GLAZED_TERRACOTTA: return new cBlockGlazedTerracottaHandler(a_BlockType); diff --git a/src/Blocks/BlockHopper.h b/src/Blocks/BlockHopper.h index da2f7c6e1..0c6724d76 100644 --- a/src/Blocks/BlockHopper.h +++ b/src/Blocks/BlockHopper.h @@ -8,9 +8,9 @@ class cBlockHopperHandler : - public cMetaRotator, 0x07, 0x02, 0x05, 0x03, 0x04> + public cPitchYawRotator> { - using super = cMetaRotator, 0x07, 0x02, 0x05, 0x03, 0x04>; + using super = cPitchYawRotator>; public: @@ -50,24 +50,6 @@ public: - virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) override - { - // Bit 0x08 is a flag. Lowest three bits are position. 0x08 == 1000 - NIBBLETYPE OtherMeta = a_Meta & 0x08; - // Mirrors defined by by a table. (Source, mincraft.gamepedia.com) 0x07 == 0111 - switch (a_Meta & 0x07) - { - case 0x00: return 0x01 + OtherMeta; // Down -> Up - case 0x01: return 0x00 + OtherMeta; // Up -> Down - } - // Not Facing Up or Down; No change. - return a_Meta; - } - - - - - virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override { UNUSED(a_Meta); diff --git a/src/Blocks/BlockObserver.h b/src/Blocks/BlockObserver.h new file mode 100644 index 000000000..ebac0ee31 --- /dev/null +++ b/src/Blocks/BlockObserver.h @@ -0,0 +1,19 @@ + +#pragma once + +#include "BlockHandler.h" +#include "Mixins.h" + + +class cBlockObserverHandler: + public cClearMetaOnDrop> +{ + using super = cClearMetaOnDrop>; + +public: + + cBlockObserverHandler(BLOCKTYPE a_BlockType) : super(a_BlockType) + { + } + +}; diff --git a/src/Blocks/BlockPiston.cpp b/src/Blocks/BlockPiston.cpp index 8c6940454..26c078e5c 100644 --- a/src/Blocks/BlockPiston.cpp +++ b/src/Blocks/BlockPiston.cpp @@ -47,22 +47,6 @@ void cBlockPistonHandler::OnBroken( -bool cBlockPistonHandler::GetPlacementBlockTypeMeta( - cChunkInterface & a_ChunkInterface, cPlayer & a_Player, - int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, - int a_CursorX, int a_CursorY, int a_CursorZ, - BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta -) -{ - a_BlockType = m_BlockType; - a_BlockMeta = RotationPitchToMetaData(a_Player.GetYaw(), a_Player.GetPitch()); - return true; -} - - - - - Vector3i cBlockPistonHandler::MetadataToOffset(NIBBLETYPE a_PistonMeta) { switch (a_PistonMeta & 0x07) diff --git a/src/Blocks/BlockPiston.h b/src/Blocks/BlockPiston.h index 0836d6471..0ced74626 100644 --- a/src/Blocks/BlockPiston.h +++ b/src/Blocks/BlockPiston.h @@ -17,9 +17,9 @@ class cWorld; class cBlockPistonHandler: - public cClearMetaOnDrop + public cClearMetaOnDrop> { - using super = cClearMetaOnDrop; + using super = cClearMetaOnDrop>; public: @@ -31,50 +31,6 @@ public: BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta ) override; - virtual bool GetPlacementBlockTypeMeta( - cChunkInterface & a_ChunkInterface, cPlayer & a_Player, - int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, - int a_CursorX, int a_CursorY, int a_CursorZ, - BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta - ) override; - - static NIBBLETYPE RotationPitchToMetaData(double a_Rotation, double a_Pitch) - { - if (a_Pitch >= 50) - { - return 0x1; - } - else if (a_Pitch <= -50) - { - return 0x0; - } - else - { - a_Rotation += 90 + 45; // So its not aligned with axis - - if (a_Rotation > 360) - { - a_Rotation -= 360; - } - if ((a_Rotation >= 0) && (a_Rotation < 90)) - { - return 0x4; - } - else if ((a_Rotation >= 180) && (a_Rotation < 270)) - { - return 0x5; - } - else if ((a_Rotation >= 90) && (a_Rotation < 180)) - { - return 0x2; - } - else - { - return 0x3; - } - } - } - static eBlockFace MetaDataToDirection(NIBBLETYPE a_MetaData) { switch (a_MetaData & 0x7) // We only want the bottom three bits (4th controls extended-ness)) diff --git a/src/Blocks/BlockPumpkin.h b/src/Blocks/BlockPumpkin.h index 29834900f..ac1c77ecc 100644 --- a/src/Blocks/BlockPumpkin.h +++ b/src/Blocks/BlockPumpkin.h @@ -6,9 +6,9 @@ class cBlockPumpkinHandler : - public cClearMetaOnDrop > + public cClearMetaOnDrop> { - typedef cClearMetaOnDrop > super; + using super = cClearMetaOnDrop>; public: cBlockPumpkinHandler(BLOCKTYPE a_BlockType) : @@ -16,45 +16,6 @@ public: { } - virtual bool GetPlacementBlockTypeMeta( - cChunkInterface & a_ChunkInterface, cPlayer & a_Player, - int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, - int a_CursorX, int a_CursorY, int a_CursorZ, - BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta - ) override - { - a_BlockType = m_BlockType; - a_BlockMeta = PlayerYawToMetaData(a_Player.GetYaw()); - return true; - } - - inline static NIBBLETYPE PlayerYawToMetaData(double a_Yaw) - { - ASSERT((a_Yaw >= -180) && (a_Yaw < 180)); - - a_Yaw += 180 + 45; - if (a_Yaw > 360) - { - a_Yaw -= 360; - } - if ((a_Yaw >= 0) && (a_Yaw < 90)) - { - return 0x0; - } - else if ((a_Yaw >= 180) && (a_Yaw < 270)) - { - return 0x2; - } - else if ((a_Yaw >= 90) && (a_Yaw < 180)) - { - return 0x1; - } - else - { - return 0x3; - } - } - virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override { UNUSED(a_Meta); diff --git a/src/Blocks/BlockRedstoneRepeater.h b/src/Blocks/BlockRedstoneRepeater.h index de55debf1..1fea6e38b 100644 --- a/src/Blocks/BlockRedstoneRepeater.h +++ b/src/Blocks/BlockRedstoneRepeater.h @@ -12,9 +12,9 @@ class cBlockRedstoneRepeaterHandler: - public cMetaRotator + public cYawRotator { - using super = cMetaRotator; + using super = cYawRotator; public: @@ -23,19 +23,6 @@ public: { } - virtual bool GetPlacementBlockTypeMeta( - cChunkInterface & a_ChunkInterface, cPlayer & a_Player, - int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, - int a_CursorX, int a_CursorY, int a_CursorZ, - BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta - ) override - { - a_BlockType = m_BlockType; - a_BlockMeta = RepeaterRotationToMetaData(a_Player.GetYaw()); - - return true; - } - virtual bool OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override { a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, ((a_ChunkInterface.GetBlockMeta({a_BlockX, a_BlockY, a_BlockZ}) + 0x04) & 0x0f)); @@ -84,32 +71,6 @@ public: return cItem(E_ITEM_REDSTONE_REPEATER, 1, 0); } - inline static NIBBLETYPE RepeaterRotationToMetaData(double a_Rotation) - { - a_Rotation += 90 + 45; // So its not aligned with axis - if (a_Rotation > 360) - { - a_Rotation -= 360; - } - - if ((a_Rotation >= 0) && (a_Rotation < 90)) - { - return 0x1; - } - else if ((a_Rotation >= 180) && (a_Rotation < 270)) - { - return 0x3; - } - else if ((a_Rotation >= 90) && (a_Rotation < 180)) - { - return 0x2; - } - else - { - return 0x0; - } - } - virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override { UNUSED(a_Meta); diff --git a/src/Blocks/CMakeLists.txt b/src/Blocks/CMakeLists.txt index fd46f672a..f67ae5270 100644 --- a/src/Blocks/CMakeLists.txt +++ b/src/Blocks/CMakeLists.txt @@ -63,6 +63,7 @@ SET (HDRS BlockMycelium.h BlockNetherrack.h BlockNetherWart.h + BlockObserver.h BlockOre.h BlockPiston.h BlockPlanks.h diff --git a/src/Blocks/Mixins.h b/src/Blocks/Mixins.h index a65fe7b06..2ab83a4d5 100644 --- a/src/Blocks/Mixins.h +++ b/src/Blocks/Mixins.h @@ -10,6 +10,7 @@ class cBlockLadder: public cMetaRotator #pragma once #include "../Item.h" +#include "../Entities/Player.h" @@ -164,3 +165,136 @@ public: return a_Meta; } }; + + +/** Mixin for rotations and reflections following the standard pattern of "apply mask, then use a switch". +Inherit from this class providing your base class as Base, the BitMask for the direction bits in bitmask and the masked value for the directions in North, East, South, West. +There is also an aptional parameter AssertIfNotMatched, set this if it is invalid for a block to exist in any other state. */ +template +class cYawRotator: + public cMetaRotator +{ + using super = cMetaRotator; +public: + + cYawRotator(BLOCKTYPE a_BlockType): + super(a_BlockType) + {} + + + + + + virtual bool GetPlacementBlockTypeMeta( + cChunkInterface & a_ChunkInterface, cPlayer & a_Player, + int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, + int a_CursorX, int a_CursorY, int a_CursorZ, + BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta + ) override + { + NIBBLETYPE BaseMeta; + super::GetPlacementBlockTypeMeta(a_ChunkInterface, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, a_BlockType, BaseMeta); + + a_BlockMeta = (BaseMeta & ~BitMask) | YawToMetaData(a_Player.GetYaw()); + return true; + } + + + + + + static NIBBLETYPE YawToMetaData(double a_Rotation) + { + a_Rotation += 90 + 45; // So its not aligned with axis + + if (a_Rotation >= 360) + { + a_Rotation -= 360; + } + if ((a_Rotation >= 0) && (a_Rotation < 90)) + { + return West; + } + else if ((a_Rotation >= 90) && (a_Rotation < 180)) + { + return North; + } + else if ((a_Rotation >= 180) && (a_Rotation < 270)) + { + return East; + } + else // (a_Rotation >= 270) && (a_Rotation < 360) + { + return South; + } + } +}; + +/** Mixin for rotations and reflections following the standard pattern of "apply mask, then use a switch". +Inherit from this class providing your base class as Base, the BitMask for the direction bits in bitmask and the masked value for the directions in North, East, South, West. +There is also an aptional parameter AssertIfNotMatched, set this if it is invalid for a block to exist in any other state. */ +template +class cPitchYawRotator: + public cYawRotator +{ + using super = cYawRotator; +public: + + cPitchYawRotator(BLOCKTYPE a_BlockType): + super(a_BlockType) + {} + + + + + + virtual bool GetPlacementBlockTypeMeta( + cChunkInterface & a_ChunkInterface, cPlayer & a_Player, + int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, + int a_CursorX, int a_CursorY, int a_CursorZ, + BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta + ) override + { + NIBBLETYPE BaseMeta; + super::GetPlacementBlockTypeMeta(a_ChunkInterface, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, a_BlockType, BaseMeta); + + a_BlockMeta = (BaseMeta & ~BitMask) | PitchYawToMetaData(a_Player.GetYaw(), a_Player.GetPitch()); + return true; + } + + + + + + virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) override + { + // Bit 0x08 is a flag. Lowest three bits are position. + NIBBLETYPE OtherMeta = a_Meta & (~BitMask); + // Mirrors defined by a table. (Source, minecraft.gamepedia.com) + switch (a_Meta & BitMask) + { + case Down: return Up | OtherMeta; // Down -> Up + case Up: return Down | OtherMeta; // Up -> Down + } + // Not Facing Up or Down; No change. + return a_Meta; + } + + + + + + static NIBBLETYPE PitchYawToMetaData(double a_Rotation, double a_Pitch) + { + if (a_Pitch >= 50) + { + return Up; + } + else if (a_Pitch <= -50) + { + return Down; + } + + return super::YawToMetaData(a_Rotation); + } +}; diff --git a/src/Items/ItemBed.h b/src/Items/ItemBed.h index 7f30a65c5..0f085d489 100644 --- a/src/Items/ItemBed.h +++ b/src/Items/ItemBed.h @@ -39,7 +39,7 @@ public: } // The "foot" block: - NIBBLETYPE BlockMeta = cBlockBedHandler::RotationToMetaData(a_Player.GetYaw()); + NIBBLETYPE BlockMeta = cBlockBedHandler::YawToMetaData(a_Player.GetYaw()); a_BlocksToPlace.emplace_back(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_BED, BlockMeta); // Check if there is empty space for the "head" block: diff --git a/src/Items/ItemComparator.h b/src/Items/ItemComparator.h index fc843c186..6f32e229d 100644 --- a/src/Items/ItemComparator.h +++ b/src/Items/ItemComparator.h @@ -2,7 +2,7 @@ #pragma once #include "ItemHandler.h" -#include "../Blocks/BlockRedstoneRepeater.h" +#include "../Blocks/BlockComparator.h" @@ -30,7 +30,7 @@ public: ) override { a_BlockType = E_BLOCK_INACTIVE_COMPARATOR; - a_BlockMeta = cBlockRedstoneRepeaterHandler::RepeaterRotationToMetaData(a_Player->GetYaw()); + a_BlockMeta = cBlockComparatorHandler::YawToMetaData(a_Player->GetYaw()); return true; } } ; diff --git a/src/Items/ItemDoor.h b/src/Items/ItemDoor.h index 7c2f81ef9..790e08ffc 100644 --- a/src/Items/ItemDoor.h +++ b/src/Items/ItemDoor.h @@ -74,7 +74,7 @@ public: } // Get the coords of the neighboring blocks: - NIBBLETYPE LowerBlockMeta = cBlockDoorHandler::PlayerYawToMetaData(a_Player.GetYaw()); + NIBBLETYPE LowerBlockMeta = cBlockDoorHandler::YawToMetaData(a_Player.GetYaw()); Vector3i RelDirToOutside = cBlockDoorHandler::GetRelativeDirectionToOutside(LowerBlockMeta); Vector3i LeftNeighborPos = RelDirToOutside; LeftNeighborPos.TurnCW(); diff --git a/src/Items/ItemRedstoneRepeater.h b/src/Items/ItemRedstoneRepeater.h index 13a797d00..9b0fc1bcc 100644 --- a/src/Items/ItemRedstoneRepeater.h +++ b/src/Items/ItemRedstoneRepeater.h @@ -30,7 +30,7 @@ public: ) override { a_BlockType = E_BLOCK_REDSTONE_REPEATER_OFF; - a_BlockMeta = cBlockRedstoneRepeaterHandler::RepeaterRotationToMetaData(a_Player->GetYaw()); + a_BlockMeta = cBlockRedstoneRepeaterHandler::YawToMetaData(a_Player->GetYaw()); return true; } } ; -- cgit v1.2.3