Cuberite
A lightweight, fast and extensible game server for Minecraft
ItemDoor.h
Go to the documentation of this file.
1 
2 #pragma once
3 
4 #include "ItemHandler.h"
5 #include "../World.h"
6 #include "../Blocks/BlockDoor.h"
7 
8 
9 
10 
11 
13  public cItemHandler
14 {
15 public:
16  cItemDoorHandler(int a_ItemType) :
17  cItemHandler(a_ItemType)
18  {
19 
20  }
21 
22 
23  virtual bool GetBlocksToPlace(
24  cWorld & a_World, cPlayer & a_Player, const cItem & a_EquippedItem,
25  int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
26  int a_CursorX, int a_CursorY, int a_CursorZ,
27  sSetBlockVector & a_BlocksToSet
28  ) override
29  {
30  // Vanilla only allows door placement while clicking on the top face of the block below the door:
31  if (a_BlockFace != BLOCK_FACE_TOP)
32  {
33  return false;
34  }
35 
36  // Door (bottom block) can be placed in Y range of [1, 254]:
37  if ((a_BlockY < 1) || (a_BlockY >= cChunkDef::Height - 2))
38  {
39  return false;
40  }
41 
42  // The door needs a compatible block below it:
43  if (!cBlockDoorHandler::CanBeOn(a_World.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ), a_World.GetBlockMeta(a_BlockX, a_BlockY - 1, a_BlockZ)))
44  {
45  return false;
46  }
47 
48  // Get the block type of the door to place:
49  BLOCKTYPE BlockType;
50  switch (m_ItemType)
51  {
52  case E_ITEM_WOODEN_DOOR: BlockType = E_BLOCK_OAK_DOOR; break;
53  case E_ITEM_IRON_DOOR: BlockType = E_BLOCK_IRON_DOOR; break;
54  case E_ITEM_SPRUCE_DOOR: BlockType = E_BLOCK_SPRUCE_DOOR; break;
55  case E_ITEM_BIRCH_DOOR: BlockType = E_BLOCK_BIRCH_DOOR; break;
56  case E_ITEM_JUNGLE_DOOR: BlockType = E_BLOCK_JUNGLE_DOOR; break;
57  case E_ITEM_DARK_OAK_DOOR: BlockType = E_BLOCK_DARK_OAK_DOOR; break;
58  case E_ITEM_ACACIA_DOOR: BlockType = E_BLOCK_ACACIA_DOOR; break;
59  default:
60  {
61  ASSERT(!"Unhandled door type");
62  return false;
63  }
64  }
65 
66  // Check the two blocks that will get replaced by the door:
67  BLOCKTYPE LowerBlockType = a_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ);
68  BLOCKTYPE UpperBlockType = a_World.GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ);
69  if (
70  !cBlockDoorHandler::CanReplaceBlock(LowerBlockType) ||
71  !cBlockDoorHandler::CanReplaceBlock(UpperBlockType))
72  {
73  return false;
74  }
75 
76  // Get the coords of the neighboring blocks:
77  NIBBLETYPE LowerBlockMeta = cBlockDoorHandler::PlayerYawToMetaData(a_Player.GetYaw());
78  Vector3i RelDirToOutside = cBlockDoorHandler::GetRelativeDirectionToOutside(LowerBlockMeta);
79  Vector3i LeftNeighborPos = RelDirToOutside;
80  LeftNeighborPos.TurnCW();
81  LeftNeighborPos.Move(a_BlockX, a_BlockY, a_BlockZ);
82  Vector3i RightNeighborPos = RelDirToOutside;
83  RightNeighborPos.TurnCCW();
84  RightNeighborPos.Move(a_BlockX, a_BlockY, a_BlockZ);
85 
86  // Decide whether the hinge is on the left (default) or on the right:
87  NIBBLETYPE UpperBlockMeta = 0x08;
88  BLOCKTYPE LeftNeighborBlock = a_World.GetBlock(LeftNeighborPos);
89  BLOCKTYPE RightNeighborBlock = a_World.GetBlock(RightNeighborPos);
90  /*
91  // DEBUG:
92  FLOGD("Door being placed at {0}", Vector3i{a_BlockX, a_BlockY, a_BlockZ});
93  FLOGD("RelDirToOutside: {0}", RelDirToOutside);
94  FLOGD("Left neighbor at {0}: {1} ({2})", LeftNeighborPos, LeftNeighborBlock, ItemTypeToString(LeftNeighborBlock));
95  FLOGD("Right neighbor at {0}: {1} ({2})", RightNeighborPos, RightNeighborBlock, ItemTypeToString(RightNeighborBlock));
96  */
97  if (
98  cBlockDoorHandler::IsDoorBlockType(LeftNeighborBlock) || // The block to the left is a door block
99  (
100  !cBlockInfo::IsSolid(LeftNeighborBlock) && // Prioritize hinge on the left side
101  cBlockInfo::IsSolid(RightNeighborBlock) && // The block to the right is solid...
102  !cBlockDoorHandler::IsDoorBlockType(RightNeighborBlock) // ... but not a door
103  )
104  )
105  {
106  // DEBUG: LOGD("Setting hinge to right side");
107  UpperBlockMeta = 0x09; // Upper block | hinge on right
108  }
109 
110  // Set the blocks:
111  a_BlocksToSet.emplace_back(a_BlockX, a_BlockY, a_BlockZ, BlockType, LowerBlockMeta);
112  a_BlocksToSet.emplace_back(a_BlockX, a_BlockY + 1, a_BlockZ, BlockType, UpperBlockMeta);
113  return true;
114  }
115 
116 
117  virtual bool IsPlaceable(void) override
118  {
119  return true;
120  }
121 } ;
BLOCKTYPE GetBlock(Vector3i a_BlockPos)
Returns the block type at the specified position.
Definition: World.h:416
virtual bool GetBlocksToPlace(cWorld &a_World, cPlayer &a_Player, const cItem &a_EquippedItem, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, sSetBlockVector &a_BlocksToSet) override
Called from OnPlayerPlace() to determine the blocks that the current placement operation should set...
Definition: ItemDoor.h:23
static bool IsSolid(BLOCKTYPE a_Type)
Definition: BlockInfo.h:48
unsigned char BLOCKTYPE
The datatype used by blockdata.
Definition: ChunkDef.h:42
void TurnCCW(void)
Rotates the vector 90 degrees counterclockwise around the vertical axis.
Definition: Vector3.h:371
static bool IsDoorBlockType(BLOCKTYPE a_Block)
Returns true if the specified blocktype is any kind of door.
Definition: BlockDoor.h:197
Definition: Player.h:27
static Vector3i GetRelativeDirectionToOutside(NIBBLETYPE a_BlockMeta)
Returns a vector pointing one block in the direction the door is facing (where the outside is)...
Definition: BlockDoor.h:181
void Move(T a_X, T a_Y, T a_Z)
Definition: Vector3.h:157
unsigned char NIBBLETYPE
The datatype used by nibbledata (meta, light, skylight)
Definition: ChunkDef.h:45
NIBBLETYPE GetBlockMeta(Vector3i a_BlockPos)
Returns the block meta at the specified position.
Definition: World.h:431
cItemDoorHandler(int a_ItemType)
Definition: ItemDoor.h:16
static const int Height
Definition: ChunkDef.h:135
Definition: World.h:65
static NIBBLETYPE PlayerYawToMetaData(double a_Yaw)
Converts the player&#39;s yaw to placed door&#39;s blockmeta.
Definition: BlockDoor.h:149
#define ASSERT(x)
Definition: Globals.h:335
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
virtual bool IsPlaceable(void) override
Blocks simply get placed.
Definition: ItemDoor.h:117
static bool CanBeOn(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
Returns true if door can be placed on the specified block type.
Definition: BlockDoor.h:103
static bool CanReplaceBlock(BLOCKTYPE a_BlockType)
Definition: BlockDoor.h:125
void TurnCW(void)
Rotates the vector 90 degrees clockwise around the vertical axis.
Definition: Vector3.h:363
Definition: Item.h:36
std::vector< sSetBlock > sSetBlockVector
Definition: ChunkDef.h:564