Cuberite
A lightweight, fast and extensible game server for Minecraft
BlockChest.h
Go to the documentation of this file.
1 
2 #pragma once
3 
4 #include "../BlockEntities/ChestEntity.h"
5 #include "../BlockArea.h"
6 #include "../Entities/Player.h"
7 #include "Mixins.h"
8 
9 
10 
11 
12 
14  public cMetaRotator<cContainerEntityHandler<cBlockEntityHandler>, 0x07, 0x02, 0x05, 0x03, 0x04>
15 {
16  using super = cMetaRotator<cContainerEntityHandler<cBlockEntityHandler>, 0x07, 0x02, 0x05, 0x03, 0x04>;
17 
18 public:
19 
21  super(a_BlockType)
22  {
23  }
24 
25 
26 
27 
28 
30  cChunkInterface & a_ChunkInterface, cPlayer & a_Player,
31  int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
32  int a_CursorX, int a_CursorY, int a_CursorZ,
33  BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
34  ) override
35  {
36  a_BlockType = m_BlockType;
37 
38  // Is there a doublechest already next to this block?
39  if (!CanBeAt(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ))
40  {
41  // Yup, cannot form a triple-chest, refuse:
42  return false;
43  }
44 
45  // Check if this forms a doublechest, if so, need to adjust the meta:
46  cBlockArea Area;
47  if (!Area.Read(a_ChunkInterface, a_BlockX - 1, a_BlockX + 1, a_BlockY, a_BlockY, a_BlockZ - 1, a_BlockZ + 1))
48  {
49  return false;
50  }
51  double yaw = a_Player.GetYaw();
52  if (
53  (Area.GetRelBlockType(0, 0, 1) == m_BlockType) ||
54  (Area.GetRelBlockType(2, 0, 1) == m_BlockType)
55  )
56  {
57  a_BlockMeta = ((yaw >= -90) && (yaw < 90)) ? 2 : 3;
58  return true;
59  }
60  if (
61  (Area.GetRelBlockType(0, 0, 1) == m_BlockType) ||
62  (Area.GetRelBlockType(2, 0, 1) == m_BlockType)
63  )
64  {
65  // FIXME: This is unreachable, as the condition is the same as the above one
66  a_BlockMeta = (yaw < 0) ? 4 : 5;
67  return true;
68  }
69 
70  // Single chest, get meta from rotation only
71  a_BlockMeta = PlayerYawToMetaData(yaw);
72  return true;
73  }
74 
75 
76 
77 
78 
79  virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
80  {
81  int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width;
82  int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width;
83  return CanBeAt(a_ChunkInterface, BlockX, a_RelY, BlockZ);
84  }
85 
86 
87 
88 
89 
90  virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ)
91  {
92  cBlockArea Area;
93  if (!Area.Read(a_ChunkInterface, a_BlockX - 2, a_BlockX + 2, a_BlockY, a_BlockY, a_BlockZ - 2, a_BlockZ + 2))
94  {
95  // Cannot read the surroundings, probably at the edge of loaded chunks. Disallow.
96  return false;
97  }
98 
99  int NumChestNeighbors = 0;
100  if (Area.GetRelBlockType(1, 0, 2) == m_BlockType)
101  {
102  if (
103  (Area.GetRelBlockType(0, 0, 2) == m_BlockType) ||
104  (Area.GetRelBlockType(1, 0, 1) == m_BlockType) ||
105  (Area.GetRelBlockType(1, 0, 3) == m_BlockType)
106  )
107  {
108  // Already a doublechest neighbor, disallow:
109  return false;
110  }
111  NumChestNeighbors += 1;
112  }
113  if (Area.GetRelBlockType(3, 0, 2) == m_BlockType)
114  {
115  if (
116  (Area.GetRelBlockType(4, 0, 2) == m_BlockType) ||
117  (Area.GetRelBlockType(3, 0, 1) == m_BlockType) ||
118  (Area.GetRelBlockType(3, 0, 3) == m_BlockType)
119  )
120  {
121  // Already a doublechest neighbor, disallow:
122  return false;
123  }
124  NumChestNeighbors += 1;
125  }
126  if (Area.GetRelBlockType(2, 0, 1) == m_BlockType)
127  {
128  if (
129  (Area.GetRelBlockType(2, 0, 0) == m_BlockType) ||
130  (Area.GetRelBlockType(1, 0, 1) == m_BlockType) ||
131  (Area.GetRelBlockType(3, 0, 1) == m_BlockType)
132  )
133  {
134  // Already a doublechest neighbor, disallow:
135  return false;
136  }
137  NumChestNeighbors += 1;
138  }
139  if (Area.GetRelBlockType(2, 0, 3) == m_BlockType)
140  {
141  if (
142  (Area.GetRelBlockType(2, 0, 4) == m_BlockType) ||
143  (Area.GetRelBlockType(1, 0, 3) == m_BlockType) ||
144  (Area.GetRelBlockType(3, 0, 3) == m_BlockType)
145  )
146  {
147  // Already a doublechest neighbor, disallow:
148  return false;
149  }
150  NumChestNeighbors += 1;
151  }
152  return (NumChestNeighbors < 2);
153  }
154 
155 
156 
157 
158 
160  static NIBBLETYPE PlayerYawToMetaData(double a_Yaw)
161  {
162  a_Yaw += 90 + 45; // So its not aligned with axis
163 
164  if (a_Yaw > 360.f)
165  {
166  a_Yaw -= 360.f;
167  }
168  if ((a_Yaw >= 0.f) && (a_Yaw < 90.f))
169  {
170  return 0x04;
171  }
172  else if ((a_Yaw >= 180) && (a_Yaw < 270))
173  {
174  return 0x05;
175  }
176  else if ((a_Yaw >= 90) && (a_Yaw < 180))
177  {
178  return 0x02;
179  }
180  else
181  {
182  return 0x03;
183  }
184  }
185 
186 
187 
188 
189 
191  bool CheckAndAdjustNeighbor(cChunkInterface & a_ChunkInterface, const cBlockArea & a_Area, int a_RelX, int a_RelZ, NIBBLETYPE a_NewMeta)
192  {
193  if (a_Area.GetRelBlockType(a_RelX, 0, a_RelZ) != m_BlockType)
194  {
195  return false;
196  }
197  a_ChunkInterface.SetBlockMeta(a_Area.GetOriginX() + a_RelX, a_Area.GetOriginY(), a_Area.GetOriginZ() + a_RelZ, a_NewMeta);
198  return true;
199  }
200 
201 
202 
203 
204 
205  virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
206  {
207  UNUSED(a_Meta);
208  return 13;
209  }
210 } ;
211 
212 
213 
214 
static NIBBLETYPE PlayerYawToMetaData(double a_Yaw)
Translates player yaw when placing a chest into the chest block metadata.
Definition: BlockChest.h:160
int GetOriginZ(void) const
Definition: BlockArea.h:353
unsigned char BLOCKTYPE
The datatype used by blockdata.
Definition: ChunkDef.h:42
static const int Width
Definition: ChunkDef.h:134
cBlockChestHandler(BLOCKTYPE a_BlockType)
Definition: BlockChest.h:20
Definition: Player.h:27
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: BlockChest.h:29
BLOCKTYPE m_BlockType
Definition: BlockHandler.h:213
unsigned char NIBBLETYPE
The datatype used by nibbledata (meta, light, skylight)
Definition: ChunkDef.h:45
Definition: Chunk.h:49
bool CheckAndAdjustNeighbor(cChunkInterface &a_ChunkInterface, const cBlockArea &a_Area, int a_RelX, int a_RelZ, NIBBLETYPE a_NewMeta)
If there&#39;s a chest in the a_Area in the specified coords, modifies its meta to a_NewMeta and returns ...
Definition: BlockChest.h:191
int GetOriginY(void) const
Definition: BlockArea.h:352
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: BlockChest.h:205
Mixin for rotations and reflections following the standard pattern of "apply mask, then use a switch".
Definition: Mixins.h:84
int GetPosX(void) const
Definition: Chunk.h:150
BLOCKTYPE GetRelBlockType(int a_RelX, int a_RelY, int a_RelZ) const
Definition: BlockArea.cpp:1722
virtual bool CanBeAt(cChunkInterface &a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ)
Definition: BlockChest.h:90
#define UNUSED
Definition: Globals.h:152
double GetYaw(void) const
Definition: Entity.h:209
eBlockFace
Block face constants, used in PlayerDigging and PlayerBlockPlacement packets and bbox collision calc...
Definition: Defines.h:29
bool Read(cForEachChunkProvider &a_ForEachChunkProvider, int a_MinBlockX, int a_MaxBlockX, int a_MinBlockY, int a_MaxBlockY, int a_MinBlockZ, int a_MaxBlockZ, int a_DataTypes=baTypes|baMetas|baBlockEntities)
Reads an area of blocks specified.
Definition: BlockArea.cpp:443
Byte ColourID
Definition: Globals.h:118
int GetPosZ(void) const
Definition: Chunk.h:151
int GetOriginX(void) const
Definition: BlockArea.h:351
void SetBlockMeta(Vector3i a_BlockPos, NIBBLETYPE a_MetaData, bool a_ShouldMarkDirty=true, bool a_ShouldInformClient=true)
Sets the meta for the specified block, while keeping the blocktype.
virtual bool CanBeAt(cChunkInterface &a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk &a_Chunk) override
Checks if the block can stay at the specified relative coords in the chunk.
Definition: BlockChest.h:79