diff options
Diffstat (limited to '')
-rw-r--r-- | src/Blocks/Mixins.h | 134 |
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); + } +}; |