Cuberite
A lightweight, fast and extensible game server for Minecraft
BlockDoor.cpp
Go to the documentation of this file.
1 
2 #include "Globals.h"
3 #include "BlockDoor.h"
4 #include "../EffectID.h"
5 
6 
7 
8 
9 
11  super(a_BlockType)
12 {
13 }
14 
15 
16 
17 
18 
19 void cBlockDoorHandler::OnBroken(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, Vector3i a_BlockPos, BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta)
20 {
21  if ((a_OldBlockMeta & 0x08) != 0)
22  {
23  // Was upper part of door
24  if ((a_BlockPos.y > 0) && IsDoorBlockType(a_ChunkInterface.GetBlock(a_BlockPos.addedY(-1))))
25  {
26  a_ChunkInterface.DropBlockAsPickups(a_BlockPos.addedY(-1));
27  }
28  }
29  else
30  {
31  // Was lower part
32  if ((a_BlockPos.y < cChunkDef::Height - 1) && IsDoorBlockType(a_ChunkInterface.GetBlock(a_BlockPos.addedY(1))))
33  {
34  a_ChunkInterface.DropBlockAsPickups(a_BlockPos.addedY(1));
35  }
36  }
37 }
38 
39 
40 
41 
42 
43 bool cBlockDoorHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ)
44 {
45  UNUSED(a_WorldInterface);
46  UNUSED(a_BlockFace);
47  UNUSED(a_CursorX);
48  UNUSED(a_CursorY);
49  UNUSED(a_CursorZ);
50 
51  switch (a_ChunkInterface.GetBlock({a_BlockX, a_BlockY, a_BlockZ}))
52  {
53  default:
54  {
55  ASSERT(!"Unhandled door block type");
56  }
58  case E_BLOCK_BIRCH_DOOR:
62  case E_BLOCK_OAK_DOOR:
63  {
64  ChangeDoor(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ);
65  a_Player.GetWorld()->BroadcastSoundParticleEffect(EffectID::SFX_RANDOM_WOODEN_DOOR_OPEN, {a_BlockX, a_BlockY, a_BlockZ}, 0, a_Player.GetClientHandle());
66  break;
67  }
68  // Prevent iron door from opening on player click
69  case E_BLOCK_IRON_DOOR:
70  {
71  OnCancelRightClick(a_ChunkInterface, a_WorldInterface, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
72  break;
73  }
74  }
75 
76  return true;
77 }
78 
79 
80 
81 
82 
83 void cBlockDoorHandler::OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace)
84 {
85  UNUSED(a_ChunkInterface);
86 
87  a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player);
88  NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta({a_BlockX, a_BlockY, a_BlockZ});
89 
90  if (Meta & 0x8)
91  {
92  // Current block is top of the door
93  a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY - 1, a_BlockZ, a_Player);
94  }
95  else
96  {
97  // Current block is bottom of the door
98  a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY + 1, a_BlockZ, a_Player);
99  }
100 }
101 
102 
103 
104 
105 
107 {
108  // Doors can be placed inside the player
109  return cBoundingBox(0, 0, 0, 0, 0, 0);
110 }
111 
112 
113 
114 
115 
117 {
118  if (a_Meta & 0x08)
119  {
120  // The meta doesn't change for the top block
121  return a_Meta;
122  }
123  else
124  {
125  // Rotate the bottom block
126  return super::MetaRotateCCW(a_Meta);
127  }
128 }
129 
130 
131 
132 
133 
135 {
136  if (a_Meta & 0x08)
137  {
138  // The meta doesn't change for the top block
139  return a_Meta;
140  }
141  else
142  {
143  // Rotate the bottom block
144  return super::MetaRotateCW(a_Meta);
145  }
146 }
147 
148 
149 
150 
151 
153 {
154  /*
155  Top bit (0x08) contains door block position (Top / Bottom). Only Bottom blocks contain position data
156  Return a_Meta if panel is a top panel (0x08 bit is set to 1)
157  */
158 
159  // Note: Currently, you can not properly mirror the hinges on a double door. The orientation of the door is stored
160  // in only the bottom tile while the hinge position is in the top tile. This function only operates on one tile at a time,
161  // so the function can only see either the hinge position or orientation, but not both, at any given time. The class itself
162  // needs extra datamembers.
163  if (a_Meta & 0x08)
164  {
165  return a_Meta;
166  }
167 
168  // Holds open / closed meta data. 0x0C == 1100.
169  NIBBLETYPE OtherMeta = a_Meta & 0x0C;
170 
171  // Mirrors according to a table. 0x03 == 0011.
172  switch (a_Meta & 0x03)
173  {
174  case 0x03: return 0x01 + OtherMeta; // South -> North
175  case 0x01: return 0x03 + OtherMeta; // North -> South
176  }
177 
178  // Not Facing North or South; No change.
179  return a_Meta;
180 }
181 
182 
183 
184 
185 
187 {
188  // Top bit (0x08) contains door panel type (Top / Bottom panel) Only Bottom panels contain position data
189  // Return a_Meta if panel is a top panel (0x08 bit is set to 1)
190 
191  // Note: Currently, you can not properly mirror the hinges on a double door. The orientation of the door is stored
192  // in only the bottom tile while the hinge position is in the top tile. This function only operates on one tile at a time,
193  // so the function can only see either the hinge position or orientation, but not both, at any given time.The class itself
194  // needs extra datamembers.
195 
196  if (a_Meta & 0x08)
197  {
198  return a_Meta;
199  }
200 
201  // Holds open / closed meta data. 0x0C == 1100.
202  NIBBLETYPE OtherMeta = a_Meta & 0x0C;
203 
204  // Mirrors according to a table. 0x03 == 0011.
205  switch (a_Meta & 0x03)
206  {
207  case 0x00: return 0x02 + OtherMeta; // West -> East
208  case 0x02: return 0x00 + OtherMeta; // East -> West
209  }
210 
211  // Not Facing North or South; No change.
212  return a_Meta;
213 }
214 
215 
216 
virtual cBoundingBox GetPlacementCollisionBox(BLOCKTYPE a_XM, BLOCKTYPE a_XP, BLOCKTYPE a_YM, BLOCKTYPE a_YP, BLOCKTYPE a_ZM, BLOCKTYPE a_ZP) override
Returns the relative bounding box that must be entity-free in order for the block to be placed...
Definition: BlockDoor.cpp:106
virtual void OnCancelRightClick(cChunkInterface &a_ChunkInterface, cWorldInterface &a_WorldInterface, cPlayer &a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override
Called when a right click to this block is cancelled.
Definition: BlockDoor.cpp:83
static void ChangeDoor(cChunkInterface &a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ)
Changes the door at the specified coords from open to close or vice versa.
Definition: BlockDoor.h:308
cBlockDoorHandler(BLOCKTYPE a_BlockType)
Definition: BlockDoor.cpp:10
unsigned char BLOCKTYPE
The datatype used by blockdata.
Definition: ChunkDef.h:42
static bool IsDoorBlockType(BLOCKTYPE a_Block)
Returns true if the specified blocktype is any kind of door.
Definition: BlockDoor.h:197
virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override
Mirros a given block meta around the YZ plane.
Definition: BlockDoor.cpp:186
Definition: Player.h:27
unsigned char NIBBLETYPE
The datatype used by nibbledata (meta, light, skylight)
Definition: ChunkDef.h:45
Represents two sets of coords, minimum and maximum for each direction.
Definition: BoundingBox.h:23
T y
Definition: Vector3.h:17
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
virtual void BroadcastSoundParticleEffect(const EffectID a_EffectID, Vector3i a_SrcPos, int a_Data, const cClientHandle *a_Exclude=nullptr) override
virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override
Rotates a given block meta clockwise.
Definition: BlockDoor.cpp:134
virtual bool OnUse(cChunkInterface &a_ChunkInterface, cWorldInterface &a_WorldInterface, cPlayer &a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override
Called if the user right clicks the block and the block is useable returns true if the use was succes...
Definition: BlockDoor.cpp:43
#define ASSERT(x)
Definition: Globals.h:335
#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 NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override
Mirrors a given block meta around the XY plane.
Definition: BlockDoor.cpp:152
eBlockFace
Block face constants, used in PlayerDigging and PlayerBlockPlacement packets and bbox collision calc...
Definition: Defines.h:29
NIBBLETYPE GetBlockMeta(Vector3i a_Pos)
BLOCKTYPE GetBlock(Vector3i a_Pos)
virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override
Rotates a given block meta counter-clockwise.
Definition: BlockDoor.cpp:116
virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override
Rotates a given block meta clockwise.
Definition: Mixins.h:118
virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override
Rotates a given block meta counter-clockwise.
Definition: Mixins.h:97
virtual void SendBlockTo(int a_BlockX, int a_BlockY, int a_BlockZ, cPlayer &a_Player)=0
Sends the block on those coords to the player.
virtual void OnBroken(cChunkInterface &a_ChunkInterface, cWorldInterface &a_WorldInterface, Vector3i a_BlockPos, BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta) override
Called after a block gets broken (replaced with air), either by player or by natural means...
Definition: BlockDoor.cpp:19
cWorld * GetWorld(void) const
Definition: Entity.h:201
cClientHandle * GetClientHandle(void) const
Returns the raw client handle associated with the player.
Definition: Player.h:254