Cuberite
A lightweight, fast and extensible game server for Minecraft
BlockLever.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "BlockHandler.h"
4 #include "../Chunk.h"
5 #include "Blocks/BlockStairs.h"
6 #include "ChunkDef.h"
7 #include "Defines.h"
8 #include "Mixins.h"
9 #include "BlockSlab.h"
10 
11 
12 class cBlockLeverHandler final :
13  public cMetaRotator<cBlockHandler, 0x07, 0x04, 0x01, 0x03, 0x02, false>
14 {
16 
17 public:
18 
19  using Super::Super;
20 
22  static bool IsLeverOn(NIBBLETYPE a_BlockMeta)
23  {
24  return ((a_BlockMeta & 0x8) == 0x8);
25  }
26 
27 private:
28 
29  virtual bool OnUse(
30  cChunkInterface & a_ChunkInterface,
31  cWorldInterface & a_WorldInterface,
32  cPlayer & a_Player,
33  const Vector3i a_BlockPos,
34  eBlockFace a_BlockFace,
35  const Vector3i a_CursorPos
36  ) const override
37  {
38  // Flip the ON bit on / off using the XOR bitwise operation
39  NIBBLETYPE Meta = (a_ChunkInterface.GetBlockMeta(a_BlockPos) ^ 0x08);
40 
41  a_ChunkInterface.SetBlockMeta(a_BlockPos, Meta);
42  a_WorldInterface.WakeUpSimulators(a_BlockPos);
43  a_WorldInterface.GetBroadcastManager().BroadcastSoundEffect("block.lever.click", a_BlockPos, 0.5f, (Meta & 0x08) ? 0.6f : 0.5f);
44  return true;
45  }
46 
47 
48 
49 
50 
51  virtual cItems ConvertToPickups(const NIBBLETYPE a_BlockMeta, const cItem * const a_Tool) const override
52  {
53  // Reset meta to zero:
54  return cItem(E_BLOCK_LEVER, 1, 0);
55  }
56 
57 
58 
59 
60 
61  virtual bool IsUseable(void) const override
62  {
63  return true;
64  }
65 
66 
67 
68 
69 
72  {
73  switch (a_Meta & 0x7)
74  {
75  case 0x1: return BLOCK_FACE_XP;
76  case 0x2: return BLOCK_FACE_XM;
77  case 0x3: return BLOCK_FACE_ZP;
78  case 0x4: return BLOCK_FACE_ZM;
79  case 0x5:
80  case 0x6: return BLOCK_FACE_YP;
81  case 0x7:
82  case 0x0: return BLOCK_FACE_YM;
83  default:
84  {
85  ASSERT(!"Unhandled block meta!");
86  return BLOCK_FACE_NONE;
87  }
88  }
89  }
90 
91 
92 
93 
94 
95  virtual bool CanBeAt(const cChunk & a_Chunk, const Vector3i a_Position, const NIBBLETYPE a_Meta) const override
96  {
97  // Find the type of block the lever is attached to:
98  auto NeighborFace = BlockMetaDataToBlockFace(a_Meta);
99  auto NeighborPos = AddFaceDirection(a_Position, NeighborFace, true);
100  if (!cChunkDef::IsValidHeight(NeighborPos))
101  {
102  return false;
103  }
104  BLOCKTYPE NeighborBlockType;
105  NIBBLETYPE NeighborMeta;
106  if (!a_Chunk.UnboundedRelGetBlock(NeighborPos, NeighborBlockType, NeighborMeta))
107  {
108  return false;
109  }
110 
111  // Allow any full block or the "good" side of a half-slab:
112  if (cBlockInfo::FullyOccupiesVoxel(NeighborBlockType))
113  {
114  return true;
115  }
116  else if (cBlockSlabHandler::IsAnySlabType(NeighborBlockType))
117  {
118  return (
119  (((NeighborMeta & 0x08) == 0x08) && (NeighborFace == BLOCK_FACE_TOP)) ||
120  (((NeighborMeta & 0x08) == 0) && (NeighborFace == BLOCK_FACE_BOTTOM))
121  );
122  }
123  else if (cBlockStairsHandler::IsAnyStairType(NeighborBlockType))
124  {
125  switch (NeighborFace)
126  {
128  return !(NeighborMeta & E_BLOCK_STAIRS_UPSIDE_DOWN);
130  return (NeighborMeta & E_BLOCK_STAIRS_UPSIDE_DOWN);
132  return ((NeighborMeta & 0b11) == E_BLOCK_STAIRS_XP);
134  return ((NeighborMeta & 0b11) == E_BLOCK_STAIRS_XM);
136  return ((NeighborMeta & 0b11) == E_BLOCK_STAIRS_ZP);
138  return ((NeighborMeta & 0b11) == E_BLOCK_STAIRS_ZM);
139  default:
140  {
141  return false;
142  }
143  }
144  }
145  return false;
146  }
147 
148 
149 
150 
151 
152  virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) const override
153  {
154  switch (a_Meta)
155  {
156  case 0x00: return 0x07; // Ceiling rotation
157  case 0x07: return 0x00;
158 
159  case 0x05: return 0x06; // Ground rotation
160  case 0x06: return 0x05;
161 
162  default: return Super::MetaRotateCCW(a_Meta); // Wall Rotation
163  }
164  }
165 
166 
167 
168 
169 
170  virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) const override
171  {
172  switch (a_Meta)
173  {
174  case 0x00: return 0x07; // Ceiling rotation
175  case 0x07: return 0x00;
176 
177  case 0x05: return 0x06; // Ground rotation
178  case 0x06: return 0x05;
179 
180  default: return Super::MetaRotateCW(a_Meta); // Wall Rotation
181  }
182  }
183 
184 
185 
186 
187 
188  virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
189  {
190  UNUSED(a_Meta);
191  return 0;
192  }
193 } ;
194 
195 
196 
197 
@ E_BLOCK_STAIRS_UPSIDE_DOWN
Definition: BlockType.h:902
@ E_BLOCK_STAIRS_ZP
Definition: BlockType.h:900
@ E_BLOCK_STAIRS_ZM
Definition: BlockType.h:901
@ E_BLOCK_STAIRS_XM
Definition: BlockType.h:899
@ E_BLOCK_STAIRS_XP
Definition: BlockType.h:898
@ E_BLOCK_LEVER
Definition: BlockType.h:83
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
void AddFaceDirection(int &a_BlockX, int &a_BlockY, int &a_BlockZ, eBlockFace a_BlockFace, bool a_bInverse)
Modifies the specified coords so that they point to the block adjacent to the one specified through i...
Definition: Defines.cpp:378
eBlockFace
Block face constants, used in PlayerDigging and PlayerBlockPlacement packets and bbox collision calc.
Definition: Defines.h:38
@ BLOCK_FACE_XP
Definition: Defines.h:41
@ BLOCK_FACE_YP
Definition: Defines.h:43
@ BLOCK_FACE_YM
Definition: Defines.h:42
@ BLOCK_FACE_TOP
Definition: Defines.h:49
@ BLOCK_FACE_ZM
Definition: Defines.h:44
@ BLOCK_FACE_BOTTOM
Definition: Defines.h:48
@ BLOCK_FACE_ZP
Definition: Defines.h:45
@ BLOCK_FACE_XM
Definition: Defines.h:40
@ BLOCK_FACE_NONE
Definition: Defines.h:39
Byte ColourID
Definition: Globals.h:162
#define ASSERT(x)
Definition: Globals.h:276
#define UNUSED
Definition: Globals.h:72
static bool FullyOccupiesVoxel(BLOCKTYPE Block)
Does this block fully occupy its voxel - is it a 'full' block?
Definition: BlockInfo.cpp:606
static eBlockFace BlockMetaDataToBlockFace(NIBBLETYPE a_Meta)
Converts the leve block's meta to the block face of the neighbor to which the lever is attached.
Definition: BlockLever.h:71
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
Returns the base colour ID of the block, as will be represented on a map, as per documentation: https...
Definition: BlockLever.h:188
virtual bool OnUse(cChunkInterface &a_ChunkInterface, cWorldInterface &a_WorldInterface, cPlayer &a_Player, const Vector3i a_BlockPos, eBlockFace a_BlockFace, const Vector3i a_CursorPos) const override
Called when the user right clicks the block and the block is useable.
Definition: BlockLever.h:29
static bool IsLeverOn(NIBBLETYPE a_BlockMeta)
Extracts the ON bit from metadata and returns if true if it is set.
Definition: BlockLever.h:22
virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) const override
Rotates a given block meta counter-clockwise.
Definition: BlockLever.h:152
virtual cItems ConvertToPickups(const NIBBLETYPE a_BlockMeta, const cItem *const a_Tool) const override
Returns the pickups that would result if the block was mined by a_Digger using a_Tool.
Definition: BlockLever.h:51
virtual bool IsUseable(void) const override
Called to check whether this block supports a rclk action.
Definition: BlockLever.h:61
virtual bool CanBeAt(const cChunk &a_Chunk, const Vector3i a_Position, const NIBBLETYPE a_Meta) const override
Checks if the block can stay at the specified relative coords in the chunk.
Definition: BlockLever.h:95
virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) const override
Rotates a given block meta clockwise.
Definition: BlockLever.h:170
static bool IsAnySlabType(BLOCKTYPE a_BlockType)
Returns true if the specified blocktype is one of the slabs handled by this handler.
Definition: BlockSlab.h:30
static bool IsAnyStairType(BLOCKTYPE a_Block)
Definition: BlockStairs.h:19
virtual void BroadcastSoundEffect(const AString &a_SoundName, Vector3d a_Position, float a_Volume, float a_Pitch, const cClientHandle *a_Exclude=nullptr)=0
void SetBlockMeta(Vector3i a_BlockPos, NIBBLETYPE a_MetaData)
Sets the meta for the specified block, while keeping the blocktype.
NIBBLETYPE GetBlockMeta(Vector3i a_Pos)
Mixin for rotations and reflections following the standard pattern of "apply mask,...
Definition: Mixins.h:62
virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) const override
Rotates a given block meta counter-clockwise.
Definition: Mixins.h:74
virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) const override
Rotates a given block meta clockwise.
Definition: Mixins.h:95
virtual cBroadcastInterface & GetBroadcastManager()=0
virtual void WakeUpSimulators(Vector3i a_Block)=0
Wakes up the simulators for the specified block.
Definition: Chunk.h:36
bool UnboundedRelGetBlock(Vector3i a_RelCoords, BLOCKTYPE &a_BlockType, NIBBLETYPE &a_BlockMeta) const
Same as GetBlock(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_ChunkMap in ...
Definition: Chunk.cpp:1008
static bool IsValidHeight(Vector3i a_BlockPosition)
Validates a height-coordinate.
Definition: ChunkDef.h:185
Definition: Player.h:29
Definition: Item.h:37
This class bridges a vector of cItem for safe access via Lua.
Definition: Item.h:215