Cuberite
A lightweight, fast and extensible game server for Minecraft
BlockVine.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "BlockHandler.h"
4 
5 
6 
7 
8 
10  public cBlockHandler
11 {
13 
14 public:
15 
17  super(a_BlockType)
18  {
19  }
20 
21 
22 
23 
24 
26  cChunkInterface & a_ChunkInterface, cPlayer & a_Player,
27  int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
28  int a_CursorX, int a_CursorY, int a_CursorZ,
29  BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
30  ) override
31  {
32  // TODO: Disallow placement where the vine doesn't attach to something properly
33  BLOCKTYPE BlockType = 0;
34  NIBBLETYPE BlockMeta;
35  a_ChunkInterface.GetBlockTypeMeta({a_BlockX, a_BlockY, a_BlockZ}, BlockType, BlockMeta);
36  if (BlockType == m_BlockType)
37  {
38  a_BlockMeta = BlockMeta | DirectionToMetaData(a_BlockFace);
39  }
40  else
41  {
42  a_BlockMeta = DirectionToMetaData(a_BlockFace);
43  }
44  a_BlockType = m_BlockType;
45  return true;
46  }
47 
48 
49 
50 
51 
52  virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
53  {
54  // Only drops self when using shears, otherwise drops nothing:
55  if ((a_Tool == nullptr) || (a_Tool->m_ItemType != E_ITEM_SHEARS))
56  {
57  return {};
58  }
59  return cItem(E_BLOCK_VINES, 1, 0);
60  }
61 
62 
63 
64 
65 
66  static NIBBLETYPE DirectionToMetaData(char a_BlockFace)
67  {
68  switch (a_BlockFace)
69  {
70  case BLOCK_FACE_NORTH: return 0x1;
71  case BLOCK_FACE_SOUTH: return 0x4;
72  case BLOCK_FACE_WEST: return 0x8;
73  case BLOCK_FACE_EAST: return 0x2;
74  default: return 0x0;
75  }
76  }
77 
78 
79 
80 
81 
82  static char MetaDataToDirection(NIBBLETYPE a_MetaData)
83  {
84  switch (a_MetaData)
85  {
86  case 0x1: return BLOCK_FACE_NORTH;
87  case 0x4: return BLOCK_FACE_SOUTH;
88  case 0x8: return BLOCK_FACE_WEST;
89  case 0x2: return BLOCK_FACE_EAST;
90  default: return BLOCK_FACE_TOP;
91  }
92  }
93 
94 
95 
96 
97 
99  static bool IsBlockAttachable(BLOCKTYPE a_BlockType)
100  {
101  switch (a_BlockType)
102  {
103  case E_BLOCK_CHEST:
104  case E_BLOCK_ENDER_CHEST:
105  case E_BLOCK_GLASS:
106  case E_BLOCK_PISTON:
113  {
114  // You can't attach a vine to this solid blocks.
115  return false;
116  }
117  default:
118  {
119  return cBlockInfo::IsSolid(a_BlockType);
120  }
121  }
122  }
123 
124 
125 
126 
127 
129  NIBBLETYPE GetMaxMeta(cChunk & a_Chunk, Vector3i a_RelPos)
130  {
131  static const struct
132  {
133  int x, z;
134  NIBBLETYPE Bit;
135  } Coords[] =
136  {
137  { 0, 1, 1}, // south, ZP
138  {-1, 0, 2}, // west, XM
139  { 0, -1, 4}, // north, ZM
140  { 1, 0, 8}, // east, XP
141  } ;
142  NIBBLETYPE res = 0;
143  for (auto & Coord : Coords)
144  {
145  BLOCKTYPE BlockType;
146  NIBBLETYPE BlockMeta;
147  auto checkPos = a_RelPos.addedXZ(Coord.x, Coord.z);
148  if (
149  a_Chunk.UnboundedRelGetBlock(checkPos.x, checkPos.y, checkPos.z, BlockType, BlockMeta) &&
150  IsBlockAttachable(BlockType)
151  )
152  {
153  res |= Coord.Bit;
154  }
155  }
156  return res;
157  }
158 
159 
160 
161 
162 
163  virtual void Check(
164  cChunkInterface & a_ChunkInterface, cBlockPluginInterface & a_PluginInterface,
165  Vector3i a_RelPos,
166  cChunk & a_Chunk
167  ) override
168  {
169  NIBBLETYPE CurMeta = a_Chunk.GetMeta(a_RelPos);
170  NIBBLETYPE MaxMeta = GetMaxMeta(a_Chunk, a_RelPos);
171 
172  // Check if vine above us, add its meta to MaxMeta
173  if ((a_RelPos.y < cChunkDef::Height - 1) && (a_Chunk.GetBlock(a_RelPos.addedY(1)) == m_BlockType))
174  {
175  MaxMeta |= a_Chunk.GetMeta(a_RelPos.addedY(1));
176  }
177 
178  NIBBLETYPE Common = CurMeta & MaxMeta; // Neighbors that we have and are legal
179  if (Common != CurMeta)
180  {
181  // There is a neighbor missing, need to update the meta or even destroy the block
182  bool HasTop = (a_RelPos.y < cChunkDef::Height - 1) && IsBlockAttachable(a_Chunk.GetBlock(a_RelPos.addedY(1)));
183  if ((Common == 0) && !HasTop)
184  {
185  // The vine just lost all its support, destroy the block:
186  if (DoesDropOnUnsuitable())
187  {
188  a_ChunkInterface.DropBlockAsPickups(a_Chunk.RelativeToAbsolute(a_RelPos));
189  }
190  a_Chunk.SetBlock(a_RelPos, E_BLOCK_AIR, 0);
191  return;
192  }
193  a_Chunk.SetBlock(a_RelPos, m_BlockType, Common);
194  }
195  else
196  {
197  auto absPos = a_Chunk.RelativeToAbsolute(a_RelPos);
198  a_Chunk.GetWorld()->GetSimulatorManager()->WakeUp(absPos, &a_Chunk);
199  }
200  }
201 
202 
203 
204 
205 
206  virtual bool DoesIgnoreBuildCollision(cChunkInterface & a_ChunkInterface, Vector3i a_Pos, cPlayer & a_Player, NIBBLETYPE a_Meta) override
207  {
208  return true;
209  }
210 
211 
212 
213 
214 
215  virtual bool DoesDropOnUnsuitable(void) override
216  {
217  return false;
218  }
219 
220 
221 
222 
223 
224  virtual void OnUpdate(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_BlockPluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
225  {
226  UNUSED(a_ChunkInterface);
227  UNUSED(a_WorldInterface);
228 
229  // Vine cannot grow down if at the bottom:
230  if (a_RelY < 1)
231  {
232  return;
233  }
234 
235  // Grow one block down, if possible:
236  BLOCKTYPE Block;
237  a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY - 1, a_RelZ, Block);
238  if (Block == E_BLOCK_AIR)
239  {
240  if (!a_BlockPluginInterface.CallHookBlockSpread(a_RelX + a_Chunk.GetPosX() * cChunkDef::Width, a_RelY - 1, a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width, ssVineSpread))
241  {
242  a_Chunk.UnboundedRelSetBlock(a_RelX, a_RelY - 1, a_RelZ, E_BLOCK_VINES, a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ));
243  }
244  }
245  }
246 
247 
248 
249 
250 
251  virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override
252  {
253  return ((a_Meta >> 1) | (a_Meta << 3)) & 0x0f; // Rotate bits to the right
254  }
255 
256 
257 
258 
259 
260  virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override
261  {
262  return ((a_Meta << 1) | (a_Meta >> 3)) & 0x0f; // Rotate bits to the left
263  }
264 
265 
266 
267 
268 
269  virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override
270  {
271  // Bits 2 and 4 stay, bits 1 and 3 swap
272  return static_cast<NIBBLETYPE>((a_Meta & 0x0a) | ((a_Meta & 0x01) << 2) | ((a_Meta & 0x04) >> 2));
273  }
274 
275 
276 
277 
278 
279  virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override
280  {
281  // Bits 1 and 3 stay, bits 2 and 4 swap
282  return static_cast<NIBBLETYPE>((a_Meta & 0x05) | ((a_Meta & 0x02) << 2) | ((a_Meta & 0x08) >> 2));
283  }
284 
285 
286 
287 
288 
289  virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
290  {
291  UNUSED(a_Meta);
292  return 7;
293  }
294 } ;
295 
296 
297 
298 
cWorld * GetWorld(void) const
Definition: Chunk.h:153
static bool IsBlockAttachable(BLOCKTYPE a_BlockType)
Returns true if the specified block type is good for vines to attach to.
Definition: BlockVine.h:99
static NIBBLETYPE DirectionToMetaData(char a_BlockFace)
Definition: BlockVine.h:66
void WakeUp(Vector3i a_Block, cChunk *a_Chunk)
virtual void Check(cChunkInterface &a_ChunkInterface, cBlockPluginInterface &a_PluginInterface, Vector3i a_RelPos, cChunk &a_Chunk) override
Called when one of the neighbors gets set; equivalent to MC block update.
Definition: BlockVine.h:163
virtual bool DoesDropOnUnsuitable(void) override
Returns if this block drops if it gets destroyed by an unsuitable situation.
Definition: BlockVine.h:215
static char MetaDataToDirection(NIBBLETYPE a_MetaData)
Definition: BlockVine.h:82
virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override
Rotates a given block meta clockwise.
Definition: BlockVine.h:260
static bool IsSolid(BLOCKTYPE a_Type)
Definition: BlockInfo.h:48
unsigned char BLOCKTYPE
The datatype used by blockdata.
Definition: ChunkDef.h:42
bool GetBlockTypeMeta(Vector3i a_Pos, BLOCKTYPE &a_BlockType, NIBBLETYPE &a_BlockMeta)
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:311
static const int Width
Definition: ChunkDef.h:134
Vector3i RelativeToAbsolute(Vector3i a_RelBlockPosition)
Converts the coord relative to this chunk into an absolute coord.
Definition: Chunk.h:569
bool UnboundedRelGetBlockType(Vector3i a_RelCoords, BLOCKTYPE &a_BlockType) const
Same as GetBlockType(), but relative coords needn&#39;t be in this chunk (uses m_Neighbor-s or m_ChunkMap...
Definition: Chunk.cpp:1018
Definition: Player.h:27
cBlockHandler(BLOCKTYPE a_BlockType)
void SetBlock(Vector3i a_RelBlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
Definition: Chunk.cpp:1313
BLOCKTYPE m_BlockType
Definition: BlockHandler.h:213
cSimulatorManager * GetSimulatorManager(void)
Definition: World.h:713
unsigned char NIBBLETYPE
The datatype used by nibbledata (meta, light, skylight)
Definition: ChunkDef.h:45
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
Returns the base colour ID of the block, as will be represented on a map, as per documentation: https...
Definition: BlockVine.h:289
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
Called before a block is placed into a world.
Definition: BlockVine.h:25
Definition: Chunk.h:49
T y
Definition: Vector3.h:17
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity *a_BlockEntity, const cEntity *a_Digger, const cItem *a_Tool) override
Returns the pickups that would result if the block was mined by a_Digger using a_Tool.
Definition: BlockVine.h:52
static const int Height
Definition: ChunkDef.h:135
Vector3< T > addedY(T a_AddY) const
Returns a copy of this vector moved by the specified amount on the y axis.
Definition: Vector3.h:299
This interface is used to decouple block handlers from the cPluginManager dependency through cWorld...
virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override
Mirrors a given block meta around the XY plane.
Definition: BlockVine.h:269
NIBBLETYPE GetMeta(int a_RelX, int a_RelY, int a_RelZ) const
Definition: Chunk.h:380
bool UnboundedRelSetBlock(Vector3i a_RelPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
Same as SetBlock(), but relative coords needn&#39;t be in this chunk (uses m_Neighbor-s or m_ChunkMap in ...
Definition: Chunk.cpp:1124
int GetPosX(void) const
Definition: Chunk.h:150
virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override
Rotates a given block meta counter-clockwise.
Definition: BlockVine.h:251
NIBBLETYPE GetMaxMeta(cChunk &a_Chunk, Vector3i a_RelPos)
Returns the meta that has the maximum allowable sides of the vine, given the surroundings.
Definition: BlockVine.h:129
#define UNUSED
Definition: Globals.h:152
void DropBlockAsPickups(Vector3i a_BlockPos, const cEntity *a_Digger=nullptr, const cItem *a_Tool=nullptr)
Digs the block and spawns the relevant pickups, as if a_Digger used a_Tool to dig the block...
virtual void OnUpdate(cChunkInterface &a_ChunkInterface, cWorldInterface &a_WorldInterface, cBlockPluginInterface &a_BlockPluginInterface, cChunk &a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
Called when the block gets ticked either by a random tick or by a queued tick.
Definition: BlockVine.h:224
eBlockFace
Block face constants, used in PlayerDigging and PlayerBlockPlacement packets and bbox collision calc...
Definition: Defines.h:29
virtual bool CallHookBlockSpread(int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source)=0
virtual bool DoesIgnoreBuildCollision(cChunkInterface &a_ChunkInterface, Vector3i a_Pos, cPlayer &a_Player, NIBBLETYPE a_Meta) override
Checks if the player can build "inside" this block.
Definition: BlockVine.h:206
bool UnboundedRelGetBlock(Vector3i a_RelCoords, BLOCKTYPE &a_BlockType, NIBBLETYPE &a_BlockMeta) const
Same as GetBlock(), but relative coords needn&#39;t be in this chunk (uses m_Neighbor-s or m_ChunkMap in ...
Definition: Chunk.cpp:997
BLOCKTYPE GetBlock(int a_RelX, int a_RelY, int a_RelZ) const
Definition: Chunk.h:177
Byte ColourID
Definition: Globals.h:118
int GetPosZ(void) const
Definition: Chunk.h:151
Definition: Entity.h:73
short m_ItemType
Definition: Item.h:209
virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override
Mirros a given block meta around the YZ plane.
Definition: BlockVine.h:279
Definition: Item.h:36
cBlockVineHandler(BLOCKTYPE a_BlockType)
Definition: BlockVine.h:16
This class bridges a vector of cItem for safe access via Lua.
Definition: Item.h:234