Add mixins for blocks that rotate based on player yaw at placement
Also add observer block handler.
This commit is contained in:
parent
458d7f95c2
commit
f40aba941e
@ -16,9 +16,9 @@ class cWorldInterface;
|
|||||||
|
|
||||||
|
|
||||||
class cBlockBedHandler :
|
class cBlockBedHandler :
|
||||||
public cMetaRotator<cBlockEntityHandler, 0x3, 0x02, 0x03, 0x00, 0x01, true>
|
public cYawRotator<cBlockEntityHandler, 0x3, 0x02, 0x03, 0x00, 0x01>
|
||||||
{
|
{
|
||||||
using super = cMetaRotator<cBlockEntityHandler, 0x3, 0x02, 0x03, 0x00, 0x01, true>;
|
using super = cYawRotator<cBlockEntityHandler, 0x3, 0x02, 0x03, 0x00, 0x01>;
|
||||||
|
|
||||||
public:
|
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<NIBBLETYPE>(a_Rotation + 2)) % 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static Vector3i MetaDataToDirection(NIBBLETYPE a_MetaData)
|
static Vector3i MetaDataToDirection(NIBBLETYPE a_MetaData)
|
||||||
{
|
{
|
||||||
switch (a_MetaData)
|
switch (a_MetaData)
|
||||||
|
@ -11,9 +11,9 @@
|
|||||||
|
|
||||||
|
|
||||||
class cBlockChestHandler :
|
class cBlockChestHandler :
|
||||||
public cMetaRotator<cContainerEntityHandler<cBlockEntityHandler>, 0x07, 0x02, 0x05, 0x03, 0x04>
|
public cYawRotator<cContainerEntityHandler<cBlockEntityHandler>>
|
||||||
{
|
{
|
||||||
using super = cMetaRotator<cContainerEntityHandler<cBlockEntityHandler>, 0x07, 0x02, 0x05, 0x03, 0x04>;
|
using super = cYawRotator<cContainerEntityHandler<cBlockEntityHandler>>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -33,8 +33,6 @@ public:
|
|||||||
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
|
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
|
||||||
) override
|
) override
|
||||||
{
|
{
|
||||||
a_BlockType = m_BlockType;
|
|
||||||
|
|
||||||
// Is there a doublechest already next to this block?
|
// Is there a doublechest already next to this block?
|
||||||
if (!CanBeAt(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ))
|
if (!CanBeAt(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ))
|
||||||
{
|
{
|
||||||
@ -42,12 +40,20 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if this forms a doublechest, if so, need to adjust the meta:
|
// Try to read double-chest information:
|
||||||
cBlockArea Area;
|
cBlockArea Area;
|
||||||
if (!Area.Read(a_ChunkInterface, a_BlockX - 1, a_BlockX + 1, a_BlockY, a_BlockY, a_BlockZ - 1, a_BlockZ + 1))
|
if (!Area.Read(a_ChunkInterface, a_BlockX - 1, a_BlockX + 1, a_BlockY, a_BlockY, a_BlockZ - 1, a_BlockZ + 1))
|
||||||
{
|
{
|
||||||
return false;
|
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();
|
double yaw = a_Player.GetYaw();
|
||||||
if (
|
if (
|
||||||
(Area.GetRelBlockType(0, 0, 1) == m_BlockType) ||
|
(Area.GetRelBlockType(0, 0, 1) == m_BlockType) ||
|
||||||
@ -58,17 +64,15 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
(Area.GetRelBlockType(0, 0, 1) == m_BlockType) ||
|
(Area.GetRelBlockType(1, 0, 0) == m_BlockType) ||
|
||||||
(Area.GetRelBlockType(2, 0, 1) == 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;
|
a_BlockMeta = (yaw < 0) ? 4 : 5;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Single chest, get meta from rotation only
|
|
||||||
a_BlockMeta = PlayerYawToMetaData(yaw);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,9 +10,9 @@
|
|||||||
|
|
||||||
|
|
||||||
class cBlockComparatorHandler :
|
class cBlockComparatorHandler :
|
||||||
public cMetaRotator<cBlockHandler, 0x03, 0x00, 0x01, 0x02, 0x03, true>
|
public cYawRotator<cBlockHandler, 0x03, 0x00, 0x01, 0x02, 0x03>
|
||||||
{
|
{
|
||||||
using super = cMetaRotator<cBlockHandler, 0x03, 0x00, 0x01, 0x02, 0x03, true>;
|
using super = cYawRotator<cBlockHandler, 0x03, 0x00, 0x01, 0x02, 0x03>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -50,18 +50,6 @@ public:
|
|||||||
return cItem(E_ITEM_COMPARATOR, 1, 0);
|
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)
|
inline static bool IsInSubtractionMode(NIBBLETYPE a_Meta)
|
||||||
{
|
{
|
||||||
return ((a_Meta & 0x4) == 0x4);
|
return ((a_Meta & 0x4) == 0x4);
|
||||||
|
@ -12,9 +12,9 @@
|
|||||||
|
|
||||||
|
|
||||||
class cBlockDoorHandler :
|
class cBlockDoorHandler :
|
||||||
public cMetaRotator<cBlockHandler, 0x03, 0x01, 0x02, 0x03, 0x00, true>
|
public cYawRotator<cBlockHandler, 0x03, 0x01, 0x02, 0x03, 0x00, true>
|
||||||
{
|
{
|
||||||
using super = cMetaRotator<cBlockHandler, 0x03, 0x01, 0x02, 0x03, 0x00, true>;
|
using super = cYawRotator<cBlockHandler, 0x03, 0x01, 0x02, 0x03, 0x00, true>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -50,9 +50,7 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
a_BlockType = m_BlockType;
|
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);
|
||||||
a_BlockMeta = PlayerYawToMetaData(a_Player.GetYaw());
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual cBoundingBox GetPlacementCollisionBox(BLOCKTYPE a_XM, BLOCKTYPE a_XP, BLOCKTYPE a_YM, BLOCKTYPE a_YP, BLOCKTYPE a_ZM, BLOCKTYPE a_ZP) override;
|
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). */
|
/** Returns a vector pointing one block in the direction the door is facing (where the outside is). */
|
||||||
inline static Vector3i GetRelativeDirectionToOutside(NIBBLETYPE a_BlockMeta)
|
inline static Vector3i GetRelativeDirectionToOutside(NIBBLETYPE a_BlockMeta)
|
||||||
{
|
{
|
||||||
|
@ -14,9 +14,9 @@
|
|||||||
|
|
||||||
|
|
||||||
class cBlockDropSpenserHandler :
|
class cBlockDropSpenserHandler :
|
||||||
public cMetaRotator<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>
|
public cPitchYawRotator<cBlockEntityHandler>
|
||||||
{
|
{
|
||||||
using super = cMetaRotator<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>;
|
using super = cPitchYawRotator<cBlockEntityHandler>;
|
||||||
|
|
||||||
public:
|
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
|
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
|
||||||
{
|
{
|
||||||
cItems res(cItem(m_BlockType, 1));
|
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
|
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
|
||||||
{
|
{
|
||||||
UNUSED(a_Meta);
|
UNUSED(a_Meta);
|
||||||
|
@ -8,9 +8,9 @@
|
|||||||
|
|
||||||
|
|
||||||
class cBlockEnderchestHandler :
|
class cBlockEnderchestHandler :
|
||||||
public cMetaRotator<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>
|
public cYawRotator<cBlockEntityHandler>
|
||||||
{
|
{
|
||||||
using super = cMetaRotator<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>;
|
using super = cYawRotator<cBlockEntityHandler>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -44,48 +44,7 @@ public:
|
|||||||
return {};
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} ;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -9,9 +9,9 @@
|
|||||||
|
|
||||||
|
|
||||||
class cBlockFenceGateHandler :
|
class cBlockFenceGateHandler :
|
||||||
public cClearMetaOnDrop<cMetaRotator<cBlockHandler, 0x03, 0x02, 0x03, 0x00, 0x01, true>>
|
public cClearMetaOnDrop<cYawRotator<cBlockHandler, 0x03, 0x02, 0x03, 0x00, 0x01>>
|
||||||
{
|
{
|
||||||
using super = cClearMetaOnDrop<cMetaRotator<cBlockHandler, 0x03, 0x02, 0x03, 0x00, 0x01, true>>;
|
using super = cClearMetaOnDrop<cYawRotator<cBlockHandler, 0x03, 0x02, 0x03, 0x00, 0x01>>;
|
||||||
|
|
||||||
public:
|
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
|
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 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
|
OldMetaData ^= 4; // Toggle the gate
|
||||||
|
|
||||||
if ((OldMetaData & 1) == (NewMetaData & 1))
|
if ((OldMetaData & 1) == (NewMetaData & 1))
|
||||||
@ -62,34 +50,6 @@ public:
|
|||||||
return true;
|
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
|
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
|
||||||
{
|
{
|
||||||
UNUSED(a_Meta);
|
UNUSED(a_Meta);
|
||||||
|
@ -9,9 +9,9 @@
|
|||||||
|
|
||||||
|
|
||||||
class cBlockFurnaceHandler :
|
class cBlockFurnaceHandler :
|
||||||
public cMetaRotator<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>
|
public cYawRotator<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>
|
||||||
{
|
{
|
||||||
using super = cMetaRotator<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>;
|
using super = cYawRotator<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>;
|
||||||
|
|
||||||
public:
|
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
|
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
|
cItems res(cItem(E_BLOCK_FURNACE, 1)); // We can't drop a lit furnace
|
||||||
|
@ -6,9 +6,9 @@
|
|||||||
|
|
||||||
|
|
||||||
class cBlockGlazedTerracottaHandler:
|
class cBlockGlazedTerracottaHandler:
|
||||||
public cClearMetaOnDrop<cBlockHandler>
|
public cClearMetaOnDrop<cYawRotator<cBlockHandler, 0x3, 0x1, 0x3, 0x0, 0x2>>
|
||||||
{
|
{
|
||||||
using super = cClearMetaOnDrop<cBlockHandler>;
|
using super = cClearMetaOnDrop<cYawRotator<cBlockHandler, 0x3, 0x1, 0x3, 0x0, 0x2>>;
|
||||||
|
|
||||||
public:
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -58,6 +58,7 @@
|
|||||||
#include "BlockMycelium.h"
|
#include "BlockMycelium.h"
|
||||||
#include "BlockNetherrack.h"
|
#include "BlockNetherrack.h"
|
||||||
#include "BlockNetherWart.h"
|
#include "BlockNetherWart.h"
|
||||||
|
#include "BlockObserver.h"
|
||||||
#include "BlockOre.h"
|
#include "BlockOre.h"
|
||||||
#include "BlockPiston.h"
|
#include "BlockPiston.h"
|
||||||
#include "BlockPlanks.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_DOOR: return new cBlockDoorHandler (a_BlockType);
|
||||||
case E_BLOCK_OAK_FENCE_GATE: return new cBlockFenceGateHandler (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_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_ORANGE_GLAZED_TERRACOTTA: return new cBlockGlazedTerracottaHandler(a_BlockType);
|
||||||
case E_BLOCK_PACKED_ICE: return new cBlockIceHandler (a_BlockType);
|
case E_BLOCK_PACKED_ICE: return new cBlockIceHandler (a_BlockType);
|
||||||
case E_BLOCK_PINK_GLAZED_TERRACOTTA: return new cBlockGlazedTerracottaHandler(a_BlockType);
|
case E_BLOCK_PINK_GLAZED_TERRACOTTA: return new cBlockGlazedTerracottaHandler(a_BlockType);
|
||||||
|
@ -8,9 +8,9 @@
|
|||||||
|
|
||||||
|
|
||||||
class cBlockHopperHandler :
|
class cBlockHopperHandler :
|
||||||
public cMetaRotator<cContainerEntityHandler<cBlockEntityHandler>, 0x07, 0x02, 0x05, 0x03, 0x04>
|
public cPitchYawRotator<cContainerEntityHandler<cBlockEntityHandler>>
|
||||||
{
|
{
|
||||||
using super = cMetaRotator<cContainerEntityHandler<cBlockEntityHandler>, 0x07, 0x02, 0x05, 0x03, 0x04>;
|
using super = cPitchYawRotator<cContainerEntityHandler<cBlockEntityHandler>>;
|
||||||
|
|
||||||
public:
|
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
|
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
|
||||||
{
|
{
|
||||||
UNUSED(a_Meta);
|
UNUSED(a_Meta);
|
||||||
|
19
src/Blocks/BlockObserver.h
Normal file
19
src/Blocks/BlockObserver.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "BlockHandler.h"
|
||||||
|
#include "Mixins.h"
|
||||||
|
|
||||||
|
|
||||||
|
class cBlockObserverHandler:
|
||||||
|
public cClearMetaOnDrop<cPitchYawRotator<cBlockHandler>>
|
||||||
|
{
|
||||||
|
using super = cClearMetaOnDrop<cPitchYawRotator<cBlockHandler>>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
cBlockObserverHandler(BLOCKTYPE a_BlockType) : super(a_BlockType)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
@ -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)
|
Vector3i cBlockPistonHandler::MetadataToOffset(NIBBLETYPE a_PistonMeta)
|
||||||
{
|
{
|
||||||
switch (a_PistonMeta & 0x07)
|
switch (a_PistonMeta & 0x07)
|
||||||
|
@ -17,9 +17,9 @@ class cWorld;
|
|||||||
|
|
||||||
|
|
||||||
class cBlockPistonHandler:
|
class cBlockPistonHandler:
|
||||||
public cClearMetaOnDrop<cBlockHandler>
|
public cClearMetaOnDrop<cPitchYawRotator<cBlockHandler>>
|
||||||
{
|
{
|
||||||
using super = cClearMetaOnDrop<cBlockHandler>;
|
using super = cClearMetaOnDrop<cPitchYawRotator<cBlockHandler>>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -31,50 +31,6 @@ public:
|
|||||||
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta
|
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta
|
||||||
) override;
|
) 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)
|
static eBlockFace MetaDataToDirection(NIBBLETYPE a_MetaData)
|
||||||
{
|
{
|
||||||
switch (a_MetaData & 0x7) // We only want the bottom three bits (4th controls extended-ness))
|
switch (a_MetaData & 0x7) // We only want the bottom three bits (4th controls extended-ness))
|
||||||
|
@ -6,9 +6,9 @@
|
|||||||
|
|
||||||
|
|
||||||
class cBlockPumpkinHandler :
|
class cBlockPumpkinHandler :
|
||||||
public cClearMetaOnDrop<cMetaRotator<cBlockHandler, 0x07, 0x02, 0x03, 0x00, 0x01, false> >
|
public cClearMetaOnDrop<cYawRotator<cBlockHandler, 0x07, 0x02, 0x03, 0x00, 0x01>>
|
||||||
{
|
{
|
||||||
typedef cClearMetaOnDrop<cMetaRotator<cBlockHandler, 0x07, 0x02, 0x03, 0x00, 0x01, false> > super;
|
using super = cClearMetaOnDrop<cYawRotator<cBlockHandler, 0x07, 0x02, 0x03, 0x00, 0x01>>;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
cBlockPumpkinHandler(BLOCKTYPE a_BlockType) :
|
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
|
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
|
||||||
{
|
{
|
||||||
UNUSED(a_Meta);
|
UNUSED(a_Meta);
|
||||||
|
@ -12,9 +12,9 @@
|
|||||||
|
|
||||||
|
|
||||||
class cBlockRedstoneRepeaterHandler:
|
class cBlockRedstoneRepeaterHandler:
|
||||||
public cMetaRotator<cBlockHandler, 0x03, 0x00, 0x01, 0x02, 0x03, true>
|
public cYawRotator<cBlockHandler, 0x03, 0x00, 0x01, 0x02, 0x03>
|
||||||
{
|
{
|
||||||
using super = cMetaRotator<cBlockHandler, 0x03, 0x00, 0x01, 0x02, 0x03, true>;
|
using super = cYawRotator<cBlockHandler, 0x03, 0x00, 0x01, 0x02, 0x03>;
|
||||||
|
|
||||||
public:
|
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
|
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));
|
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);
|
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
|
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
|
||||||
{
|
{
|
||||||
UNUSED(a_Meta);
|
UNUSED(a_Meta);
|
||||||
|
@ -63,6 +63,7 @@ SET (HDRS
|
|||||||
BlockMycelium.h
|
BlockMycelium.h
|
||||||
BlockNetherrack.h
|
BlockNetherrack.h
|
||||||
BlockNetherWart.h
|
BlockNetherWart.h
|
||||||
|
BlockObserver.h
|
||||||
BlockOre.h
|
BlockOre.h
|
||||||
BlockPiston.h
|
BlockPiston.h
|
||||||
BlockPlanks.h
|
BlockPlanks.h
|
||||||
|
@ -10,6 +10,7 @@ class cBlockLadder: public cMetaRotator<cClearMetaOnDrop, ...>
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../Item.h"
|
#include "../Item.h"
|
||||||
|
#include "../Entities/Player.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -164,3 +165,136 @@ public:
|
|||||||
return a_Meta;
|
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 Base, NIBBLETYPE BitMask = 0x7, NIBBLETYPE North = 0x2, NIBBLETYPE East = 0x5, NIBBLETYPE South = 0x3, NIBBLETYPE West = 0x4, bool AssertIfNotMatched = false>
|
||||||
|
class cYawRotator:
|
||||||
|
public cMetaRotator<Base, BitMask, North, East, South, West, AssertIfNotMatched>
|
||||||
|
{
|
||||||
|
using super = cMetaRotator<Base, BitMask, North, East, South, West, AssertIfNotMatched>;
|
||||||
|
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 Base, NIBBLETYPE BitMask = 0x7, NIBBLETYPE North = 0x2, NIBBLETYPE East = 0x5, NIBBLETYPE South = 0x3, NIBBLETYPE West = 0x4, NIBBLETYPE Up = 0x1, NIBBLETYPE Down = 0x0>
|
||||||
|
class cPitchYawRotator:
|
||||||
|
public cYawRotator<Base, BitMask, North, East, South, West>
|
||||||
|
{
|
||||||
|
using super = cYawRotator<Base, BitMask, North, East, South, West>;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
@ -39,7 +39,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The "foot" block:
|
// 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);
|
a_BlocksToPlace.emplace_back(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_BED, BlockMeta);
|
||||||
|
|
||||||
// Check if there is empty space for the "head" block:
|
// Check if there is empty space for the "head" block:
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "ItemHandler.h"
|
#include "ItemHandler.h"
|
||||||
#include "../Blocks/BlockRedstoneRepeater.h"
|
#include "../Blocks/BlockComparator.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ public:
|
|||||||
) override
|
) override
|
||||||
{
|
{
|
||||||
a_BlockType = E_BLOCK_INACTIVE_COMPARATOR;
|
a_BlockType = E_BLOCK_INACTIVE_COMPARATOR;
|
||||||
a_BlockMeta = cBlockRedstoneRepeaterHandler::RepeaterRotationToMetaData(a_Player->GetYaw());
|
a_BlockMeta = cBlockComparatorHandler::YawToMetaData(a_Player->GetYaw());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} ;
|
} ;
|
||||||
|
@ -74,7 +74,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the coords of the neighboring blocks:
|
// 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 RelDirToOutside = cBlockDoorHandler::GetRelativeDirectionToOutside(LowerBlockMeta);
|
||||||
Vector3i LeftNeighborPos = RelDirToOutside;
|
Vector3i LeftNeighborPos = RelDirToOutside;
|
||||||
LeftNeighborPos.TurnCW();
|
LeftNeighborPos.TurnCW();
|
||||||
|
@ -30,7 +30,7 @@ public:
|
|||||||
) override
|
) override
|
||||||
{
|
{
|
||||||
a_BlockType = E_BLOCK_REDSTONE_REPEATER_OFF;
|
a_BlockType = E_BLOCK_REDSTONE_REPEATER_OFF;
|
||||||
a_BlockMeta = cBlockRedstoneRepeaterHandler::RepeaterRotationToMetaData(a_Player->GetYaw());
|
a_BlockMeta = cBlockRedstoneRepeaterHandler::YawToMetaData(a_Player->GetYaw());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} ;
|
} ;
|
||||||
|
Loading…
Reference in New Issue
Block a user