From f40aba941eaf69b52ac0fbe3d8cea1ea349b97a6 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Wed, 8 Apr 2020 21:35:08 +0100 Subject: Add mixins for blocks that rotate based on player yaw at placement Also add observer block handler. --- src/Blocks/Mixins.h | 134 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) (limited to 'src/Blocks/Mixins.h') 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 #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 cYawRotator: + public cMetaRotator +{ + using super = cMetaRotator; +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 cPitchYawRotator: + public cYawRotator +{ + using super = cYawRotator; +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); + } +}; -- cgit v1.2.3