1
0
Fork 0

Add mixins for blocks that rotate based on player yaw at placement

Also add observer block handler.
This commit is contained in:
Alexander Harkness 2020-04-08 21:35:08 +01:00
parent 458d7f95c2
commit f40aba941e
22 changed files with 202 additions and 413 deletions

View File

@ -16,9 +16,9 @@ class cWorldInterface;
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:
@ -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)
{
switch (a_MetaData)

View File

@ -11,9 +11,9 @@
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:
@ -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;
}

View File

@ -10,9 +10,9 @@
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:
@ -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);

View File

@ -12,9 +12,9 @@
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:
@ -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)
{

View File

@ -14,9 +14,9 @@
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:
@ -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);

View File

@ -8,9 +8,9 @@
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:
@ -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;
}
}
} ;
};

View File

@ -9,9 +9,9 @@
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:
@ -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);

View File

@ -9,9 +9,9 @@
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:
@ -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

View File

@ -6,9 +6,9 @@
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:
@ -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;
}
};

View File

@ -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);

View File

@ -8,9 +8,9 @@
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:
@ -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);

View 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)
{
}
};

View File

@ -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)

View File

@ -17,9 +17,9 @@ class cWorld;
class cBlockPistonHandler:
public cClearMetaOnDrop<cBlockHandler>
public cClearMetaOnDrop<cPitchYawRotator<cBlockHandler>>
{
using super = cClearMetaOnDrop<cBlockHandler>;
using super = cClearMetaOnDrop<cPitchYawRotator<cBlockHandler>>;
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))

View File

@ -6,9 +6,9 @@
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:
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);

View File

@ -12,9 +12,9 @@
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:
@ -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);

View File

@ -63,6 +63,7 @@ SET (HDRS
BlockMycelium.h
BlockNetherrack.h
BlockNetherWart.h
BlockObserver.h
BlockOre.h
BlockPiston.h
BlockPlanks.h

View File

@ -10,6 +10,7 @@ class cBlockLadder: public cMetaRotator<cClearMetaOnDrop, ...>
#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 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);
}
};

View File

@ -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:

View File

@ -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;
}
} ;

View File

@ -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();

View File

@ -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;
}
} ;