Cuberite
A lightweight, fast and extensible game server for Minecraft
Mixins.h
Go to the documentation of this file.
1 // Mixins.h
2 
3 // Provides various mixins for easier cBlockHandler descendant implementations
4 
5 /* The general use case is to derive a handler from these mixins, providing a suitable base to them:
6 class cBlockAir: public cBlockWithNoDrops<cBlockHandler>;
7 class cBlockLadder: public cMetaRotator<cClearMetaOnDrop, ...>
8 */
9 
10 #pragma once
11 
12 #include "../Item.h"
13 
14 
15 
16 
17 
18 // MSVC generates warnings for the templated AssertIfNotMatched parameter conditions, so disable it:
19 #ifdef _MSC_VER
20  #pragma warning(disable: 4127) // Conditional expression is constant
21 #endif
22 
23 
24 
25 
26 
28 template <class Base>
30  public Base
31 {
32 public:
33 
34  constexpr cClearMetaOnDrop(BLOCKTYPE a_BlockType):
35  Base(a_BlockType)
36  {
37  }
38 
39 protected:
40 
41  ~cClearMetaOnDrop() = default;
42 
43 private:
44 
45  virtual cItems ConvertToPickups(const NIBBLETYPE a_BlockMeta, const cItem * const a_Tool) const override
46  {
47  // Reset the meta to zero:
48  return cItem(this->m_BlockType);
49  }
50 };
51 
52 
53 
54 
55 
59 template <class Base, NIBBLETYPE BitMask, NIBBLETYPE North, NIBBLETYPE East, NIBBLETYPE South, NIBBLETYPE West, bool AssertIfNotMatched = false>
60 class cMetaRotator :
61  public Base
62 {
63 public:
64 
65  constexpr cMetaRotator(BLOCKTYPE a_BlockType):
66  Base(a_BlockType)
67  {
68  }
69 
70 protected:
71 
72  ~cMetaRotator() = default;
73 
74  virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) const override
75  {
76  NIBBLETYPE OtherMeta = a_Meta & (~BitMask);
77  switch (a_Meta & BitMask)
78  {
79  case South: return East | OtherMeta;
80  case East: return North | OtherMeta;
81  case North: return West | OtherMeta;
82  case West: return South | OtherMeta;
83  }
84  if (AssertIfNotMatched)
85  {
86  ASSERT(!"Invalid Meta value");
87  }
88  return a_Meta;
89  }
90 
91 
92 
93 
94 
95  virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) const override
96  {
97  NIBBLETYPE OtherMeta = a_Meta & (~BitMask);
98  switch (a_Meta & BitMask)
99  {
100  case South: return West | OtherMeta;
101  case West: return North | OtherMeta;
102  case North: return East | OtherMeta;
103  case East: return South | OtherMeta;
104  }
105  if (AssertIfNotMatched)
106  {
107  ASSERT(!"Invalid Meta value");
108  }
109  return a_Meta;
110  }
111 
112 
113 
114 
115 
116  virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) const override
117  {
118  NIBBLETYPE OtherMeta = a_Meta & (~BitMask);
119  switch (a_Meta & BitMask)
120  {
121  case South: return North | OtherMeta;
122  case North: return South | OtherMeta;
123  }
124  // Not Facing North or South; No change.
125  return a_Meta;
126  }
127 
128 
129 
130 
131 
132  virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) const override
133  {
134  NIBBLETYPE OtherMeta = a_Meta & (~BitMask);
135  switch (a_Meta & BitMask)
136  {
137  case West: return East | OtherMeta;
138  case East: return West | OtherMeta;
139  }
140  // Not Facing East or West; No change.
141  return a_Meta;
142  }
143 };
144 
145 
146 
147 
148 
151 template <
152  class Base,
153  NIBBLETYPE BitMask = 0x07,
154  NIBBLETYPE North = 0x02,
155  NIBBLETYPE East = 0x05,
156  NIBBLETYPE South = 0x03,
157  NIBBLETYPE West = 0x04,
158  bool AssertIfNotMatched = false
159 >
160 class cYawRotator :
161  public cMetaRotator<Base, BitMask, North, East, South, West, AssertIfNotMatched>
162 {
164 
165 public:
166 
167  using Super::Super;
168 
169 
172  static NIBBLETYPE YawToMetaData(double a_Rotation)
173  {
174  if ((a_Rotation >= -135) && (a_Rotation < -45))
175  {
176  return East;
177  }
178  else if ((a_Rotation >= -45) && (a_Rotation < 45))
179  {
180  return South;
181  }
182  else if ((a_Rotation >= 45) && (a_Rotation < 135))
183  {
184  return West;
185  }
186  else // degrees jumping from 180 to -180
187  {
188  return North;
189  }
190  }
191 
192 protected:
193 
194  ~cYawRotator() = default;
195 };
196 
197 
198 
199 
200 
203 template <
204  class Base,
205  NIBBLETYPE BitMask = 0x07,
206  NIBBLETYPE North = 0x02,
207  NIBBLETYPE East = 0x05,
208  NIBBLETYPE South = 0x03,
209  NIBBLETYPE West = 0x04,
210  NIBBLETYPE Up = 0x00,
211  NIBBLETYPE Down = 0x01
212 >
214  public cYawRotator<Base, BitMask, North, East, South, West>
215 {
217 
218 public:
219 
220  using Super::Super;
221 
222 
225  static NIBBLETYPE DisplacementYawToMetaData(const Vector3d a_PlacePosition, const Vector3d a_EyePosition, const double a_Rotation)
226  {
227  if (
228  const auto Displacement = a_EyePosition - a_PlacePosition.addedXZ(0.5, 0.5);
229  (std::abs(Displacement.x) < 2) && (std::abs(Displacement.z) < 2)
230  )
231  {
232  if (Displacement.y > 2)
233  {
234  return Up;
235  }
236 
237  if (Displacement.y < 0)
238  {
239  return Down;
240  }
241  }
242 
243  return Super::YawToMetaData(a_Rotation);
244  }
245 
246 protected:
247 
249 
250 
251  virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) const override
252  {
253  NIBBLETYPE OtherMeta = a_Meta & (~BitMask);
254  switch (a_Meta & BitMask)
255  {
256  case Down: return Up | OtherMeta; // Down -> Up
257  case Up: return Down | OtherMeta; // Up -> Down
258  }
259  // Not Facing Up or Down; No change.
260  return a_Meta;
261  }
262 };
unsigned char NIBBLETYPE
The datatype used by nibbledata (meta, light, skylight)
Definition: ChunkDef.h:44
unsigned char BLOCKTYPE
The datatype used by blockdata.
Definition: ChunkDef.h:41
#define ASSERT(x)
Definition: Globals.h:276
bool Up(const BlockState Block)
bool Down(const BlockState Block)
Mixin to clear the block's meta value when converting to a pickup.
Definition: Mixins.h:31
virtual cItems ConvertToPickups(const NIBBLETYPE a_BlockMeta, const cItem *const a_Tool) const override
Definition: Mixins.h:45
~cClearMetaOnDrop()=default
constexpr cClearMetaOnDrop(BLOCKTYPE a_BlockType)
Definition: Mixins.h:34
Mixin for rotations and reflections following the standard pattern of "apply mask,...
Definition: Mixins.h:62
virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) const override
Definition: Mixins.h:74
~cMetaRotator()=default
virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) const override
Definition: Mixins.h:95
constexpr cMetaRotator(BLOCKTYPE a_BlockType)
Definition: Mixins.h:65
virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) const override
Definition: Mixins.h:132
virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) const override
Definition: Mixins.h:116
Mixin for blocks whose meta on placement depends on the yaw of the player placing the block.
Definition: Mixins.h:162
cMetaRotator< Base, BitMask, North, East, South, West, AssertIfNotMatched > Super
Definition: Mixins.h:163
~cYawRotator()=default
static NIBBLETYPE YawToMetaData(double a_Rotation)
Converts the rotation value as returned by cPlayer::GetYaw() to the appropriate metadata value for a ...
Definition: Mixins.h:172
Mixin for blocks whose meta on placement depends on the relative position of the player to the block ...
Definition: Mixins.h:215
~cDisplacementYawRotator()=default
virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) const override
Definition: Mixins.h:251
static NIBBLETYPE DisplacementYawToMetaData(const Vector3d a_PlacePosition, const Vector3d a_EyePosition, const double a_Rotation)
Converts the placement position, eye position as returned by cPlayer::GetEyePosition(),...
Definition: Mixins.h:225
Definition: Item.h:37
This class bridges a vector of cItem for safe access via Lua.
Definition: Item.h:215
Vector3< T > addedXZ(T a_AddX, T a_AddZ) const
Returns a copy of this vector moved by the specified amount on the X and Z axes.
Definition: Vector3.h:326