summaryrefslogtreecommitdiffstats
path: root/src/Blocks/Mixins.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/Blocks/Mixins.h')
-rw-r--r--src/Blocks/Mixins.h134
1 files changed, 134 insertions, 0 deletions
diff --git a/src/Blocks/Mixins.h b/src/Blocks/Mixins.h
index a65fe7b06..2ab83a4d5 100644
--- a/src/Blocks/Mixins.h
+++ b/src/Blocks/Mixins.h
@@ -10,6 +10,7 @@ class cBlockLadder: public cMetaRotator<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);
+ }
+};