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 
12 class cItemDoorHandler final:
13  public cItemHandler
14 {
16 
17 public:
18 
19  constexpr cItemDoorHandler(int a_ItemType):
20  Super(a_ItemType)
21  {
22 
23  }
24 
25 
26 
27 
28  virtual bool CommitPlacement(cPlayer & a_Player, const cItem & a_HeldItem, const Vector3i a_PlacePosition, const eBlockFace a_ClickedBlockFace, const Vector3i a_CursorPosition) const override
29  {
30  // Vanilla only allows door placement while clicking on the top face of the block below the door:
31  if (a_ClickedBlockFace != BLOCK_FACE_TOP)
32  {
33  return false;
34  }
35 
36  // Get the block type of the door to place:
38  switch (m_ItemType)
39  {
47  default: UNREACHABLE("Unhandled door type");
48  }
49 
50  const auto & World = *a_Player.GetWorld();
51  const auto UpperBlockPosition = a_PlacePosition.addedY(1);
52 
53  // Check the block that will get replaced by the door:
54  {
55  BLOCKTYPE TopType;
56  NIBBLETYPE TopMeta;
57  World.GetBlockTypeMeta(UpperBlockPosition, TopType, TopMeta);
58 
59  if (!cBlockHandler::For(TopType).DoesIgnoreBuildCollision(World, a_HeldItem, UpperBlockPosition, TopMeta, a_ClickedBlockFace, false))
60  {
61  return false;
62  }
63  }
64 
65  // Get the coords of the neighboring blocks:
66  NIBBLETYPE LowerBlockMeta = cBlockDoorHandler::YawToMetaData(a_Player.GetYaw());
67  Vector3i RelDirToOutside = cBlockDoorHandler::GetRelativeDirectionToOutside(LowerBlockMeta);
68  Vector3i LeftNeighborPos = RelDirToOutside;
69  LeftNeighborPos.TurnCW();
70  LeftNeighborPos.Move(a_PlacePosition);
71  Vector3i RightNeighborPos = RelDirToOutside;
72  RightNeighborPos.TurnCCW();
73  RightNeighborPos.Move(a_PlacePosition);
74 
75  // Decide whether the hinge is on the left (default) or on the right:
76  NIBBLETYPE UpperBlockMeta = 0x08;
77  BLOCKTYPE LeftNeighborBlock = World.GetBlock(LeftNeighborPos);
78  BLOCKTYPE RightNeighborBlock = World.GetBlock(RightNeighborPos);
79 
80  /*
81  // DEBUG:
82  FLOGD("Door being placed at {0}", a_PlacePosition);
83  FLOGD("RelDirToOutside: {0}", RelDirToOutside);
84  FLOGD("Left neighbor at {0}: {1} ({2})", LeftNeighborPos, LeftNeighborBlock, ItemTypeToString(LeftNeighborBlock));
85  FLOGD("Right neighbor at {0}: {1} ({2})", RightNeighborPos, RightNeighborBlock, ItemTypeToString(RightNeighborBlock));
86  */
87 
88  if (
89  cBlockDoorHandler::IsDoorBlockType(LeftNeighborBlock) || // The block to the left is a door block
90  (
91  !cBlockInfo::IsSolid(LeftNeighborBlock) && // Prioritize hinge on the left side
92  cBlockInfo::IsSolid(RightNeighborBlock) && // The block to the right is solid...
93  !cBlockDoorHandler::IsDoorBlockType(RightNeighborBlock) // ... but not a door
94  )
95  )
96  {
97  // DEBUG: LOGD("Setting hinge to right side");
98  UpperBlockMeta = 0x09; // Upper block | hinge on right
99  }
100 
101  // Set the blocks:
102  return a_Player.PlaceBlocks(
103  {
104  { a_PlacePosition, BlockType, LowerBlockMeta },
105  { UpperBlockPosition, BlockType, UpperBlockMeta }
106  });
107  }
108 
109 
110 
111 
112  virtual bool IsPlaceable(void) const override
113  {
114  return true;
115  }
116 } ;
@ E_BLOCK_SPRUCE_DOOR
Definition: BlockType.h:212
@ E_BLOCK_BIRCH_DOOR
Definition: BlockType.h:213
@ E_BLOCK_IRON_DOOR
Definition: BlockType.h:85
@ E_BLOCK_JUNGLE_DOOR
Definition: BlockType.h:214
@ E_BLOCK_OAK_DOOR
Definition: BlockType.h:77
@ E_BLOCK_DARK_OAK_DOOR
Definition: BlockType.h:216
@ E_BLOCK_ACACIA_DOOR
Definition: BlockType.h:215
@ E_ITEM_ACACIA_DOOR
Definition: BlockType.h:477
@ E_ITEM_WOODEN_DOOR
Definition: BlockType.h:368
@ E_ITEM_DARK_OAK_DOOR
Definition: BlockType.h:478
@ E_ITEM_JUNGLE_DOOR
Definition: BlockType.h:476
@ E_ITEM_IRON_DOOR
Definition: BlockType.h:374
@ E_ITEM_BIRCH_DOOR
Definition: BlockType.h:475
@ E_ITEM_SPRUCE_DOOR
Definition: BlockType.h:474
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
eBlockFace
Block face constants, used in PlayerDigging and PlayerBlockPlacement packets and bbox collision calc.
Definition: Defines.h:38
@ BLOCK_FACE_TOP
Definition: Defines.h:49
#define UNREACHABLE(x)
Definition: Globals.h:288
BlockType
Definition: BlockTypes.h:4
Utilities to allow casting a cWorld to one of its interfaces without including World....
Definition: OpaqueWorld.h:13
static bool IsSolid(BLOCKTYPE Block)
Is this block solid (player cannot walk through)?
Definition: BlockInfo.cpp:892
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:49
static bool IsDoorBlockType(BLOCKTYPE a_Block)
Returns true if the specified blocktype is any kind of door.
Definition: BlockDoor.h:61
static const cBlockHandler & For(BLOCKTYPE a_BlockType)
static NIBBLETYPE YawToMetaData(double a_Rotation)
Converts the rotation value as returned by cPlayer::GetYaw() to the appropriate metadata value for a ...
Definition: Mixins.h:172
double GetYaw(void) const
Definition: Entity.h:198
cWorld * GetWorld(void) const
Definition: Entity.h:190
Definition: Player.h:29
bool PlaceBlocks(std::initializer_list< sSetBlock > a_Blocks)
Calls the block placement hooks and places the blocks in the world.
Definition: Player.cpp:2449
Definition: Item.h:37
virtual bool CommitPlacement(cPlayer &a_Player, const cItem &a_HeldItem, const Vector3i a_PlacePosition, const eBlockFace a_ClickedBlockFace, const Vector3i a_CursorPosition) const override
Performs the actual placement of this placeable item.
Definition: ItemDoor.h:28
constexpr cItemDoorHandler(int a_ItemType)
Definition: ItemDoor.h:19
virtual bool IsPlaceable(void) const override
Blocks simply get placed.
Definition: ItemDoor.h:112
const int m_ItemType
Definition: ItemHandler.h:141
constexpr cItemHandler(int a_ItemType)
Definition: ItemHandler.h:37
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:314
void Move(T a_X, T a_Y, T a_Z)
Definition: Vector3.h:162
void TurnCCW(void)
Rotates the vector 90 degrees counterclockwise around the vertical axis.
Definition: Vector3.h:386
void TurnCW(void)
Rotates the vector 90 degrees clockwise around the vertical axis.
Definition: Vector3.h:378