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 :
|
||||
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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
} ;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
switch (a_PistonMeta & 0x07)
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -63,6 +63,7 @@ SET (HDRS
|
|||
BlockMycelium.h
|
||||
BlockNetherrack.h
|
||||
BlockNetherWart.h
|
||||
BlockObserver.h
|
||||
BlockOre.h
|
||||
BlockPiston.h
|
||||
BlockPlanks.h
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
} ;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
} ;
|
||||
|
|
Loading…
Reference in New Issue