Cuberite
A lightweight, fast and extensible game server for Minecraft
ItemBanner.h
Go to the documentation of this file.
1 
2 
3 #pragma once
4 
5 #include "ItemHandler.h"
6 #include "../World.h"
7 #include "../Blocks/BlockHandler.h"
8 #include "../BlockEntities/BannerEntity.h"
9 #include "../Blocks/ChunkInterface.h"
10 
11 
12 
13 
14 
15 class cItemBannerHandler final:
16  public cItemHandler
17 {
19 
20 public:
21 
22  using Super::Super;
23 
24 private:
25 
26  virtual bool CommitPlacement(cPlayer & a_Player, const cItem & a_HeldItem, const Vector3i a_PlacePosition, const eBlockFace a_ClickedBlockFace, const Vector3i a_CursorPosition) const override
27  {
28  // Cannot place a banner at "no face" and from the bottom:
29  if ((a_ClickedBlockFace == BLOCK_FACE_NONE) || (a_ClickedBlockFace == BLOCK_FACE_BOTTOM))
30  {
31  return false;
32  }
33 
34  if (!TryPlaceBanner(a_Player, a_PlacePosition, a_ClickedBlockFace))
35  {
36  return false;
37  }
38 
39  a_Player.GetWorld()->DoWithBlockEntityAt(a_PlacePosition, [&a_HeldItem](cBlockEntity & a_BlockEntity)
40  {
41  ASSERT((a_BlockEntity.GetBlockType() == E_BLOCK_STANDING_BANNER) || (a_BlockEntity.GetBlockType() == E_BLOCK_WALL_BANNER));
42 
43  cBannerEntity & BannerEntity = static_cast<cBannerEntity &>(a_BlockEntity);
44  BannerEntity.SetBaseColor(static_cast<NIBBLETYPE>(a_HeldItem.m_ItemDamage));
45  BannerEntity.SetCustomName(a_HeldItem.m_CustomName);
46  return false;
47  });
48 
49  return true;
50  }
51 
52 
53 
54 
55 
56  virtual bool IsPlaceable(void) const override
57  {
58  return true;
59  }
60 
61 
62 
63 
64  static bool TryPlaceBanner(cPlayer & a_Player, const Vector3i a_PlacePosition, const eBlockFace a_ClickedBlockFace)
65  {
66  const auto Rotation = a_Player.GetYaw();
67 
68  // Placing on the floor:
69  if (a_ClickedBlockFace == BLOCK_FACE_TOP)
70  {
71  NIBBLETYPE Meta;
72 
73  if ((Rotation >= -11.25f) && (Rotation < 11.25f))
74  {
75  // South
76  Meta = 0x08;
77  }
78  else if ((Rotation >= 11.25f) && (Rotation < 33.75f))
79  {
80  // SouthSouthWest
81  Meta = 0x09;
82  }
83  else if ((Rotation >= 23.75f) && (Rotation < 56.25f))
84  {
85  // SouthWest
86  Meta = 0x0a;
87  }
88  else if ((Rotation >= 56.25f) && (Rotation < 78.75f))
89  {
90  // WestSouthWest
91  Meta = 0x0b;
92  }
93  else if ((Rotation >= 78.75f) && (Rotation < 101.25f))
94  {
95  // West
96  Meta = 0x0c;
97  }
98  else if ((Rotation >= 101.25f) && (Rotation < 123.75f))
99  {
100  // WestNorthWest
101  Meta = 0x0d;
102  }
103  else if ((Rotation >= 123.75f) && (Rotation < 146.25f))
104  {
105  // NorthWest
106  Meta = 0x0e;
107  }
108  else if ((Rotation >= 146.25f) && (Rotation < 168.75f))
109  {
110  // NorthNorthWest
111  Meta = 0x0f;
112  }
113  else if ((Rotation >= -168.75f) && (Rotation < -146.25f))
114  {
115  // NorthNorthEast
116  Meta = 0x01;
117  }
118  else if ((Rotation >= -146.25f) && (Rotation < -123.75f))
119  {
120  // NorthEast
121  Meta = 0x02;
122  }
123  else if ((Rotation >= -123.75f) && (Rotation < -101.25f))
124  {
125  // EastNorthEast
126  Meta = 0x03;
127  }
128  else if ((Rotation >= -101.25) && (Rotation < -78.75f))
129  {
130  // East
131  Meta = 0x04;
132  }
133  else if ((Rotation >= -78.75) && (Rotation < -56.25f))
134  {
135  // EastSouthEast
136  Meta = 0x05;
137  }
138  else if ((Rotation >= -56.25f) && (Rotation < -33.75f))
139  {
140  // SouthEast
141  Meta = 0x06;
142  }
143  else if ((Rotation >= -33.75f) && (Rotation < -11.25f))
144  {
145  // SouthSouthEast
146  Meta = 0x07;
147  }
148  else // degrees jumping from 180 to -180
149  {
150  // North
151  Meta = 0x00;
152  }
153 
154  return a_Player.PlaceBlock(a_PlacePosition, E_BLOCK_STANDING_BANNER, Meta);
155  }
156 
157  // We must be placing on the side of a block.
158 
159  NIBBLETYPE Meta;
160 
161  if (a_ClickedBlockFace == BLOCK_FACE_EAST)
162  {
163  Meta = 0x05;
164  }
165  else if (a_ClickedBlockFace == BLOCK_FACE_WEST)
166  {
167  Meta = 0x04;
168  }
169  else if (a_ClickedBlockFace == BLOCK_FACE_NORTH)
170  {
171  Meta = 0x02;
172  }
173  else // degrees jumping from 180 to -180
174  {
175  Meta = 0x03;
176  }
177 
178  return a_Player.PlaceBlock(a_PlacePosition, E_BLOCK_WALL_BANNER, Meta);
179  }
180 };
@ E_BLOCK_STANDING_BANNER
Definition: BlockType.h:195
@ E_BLOCK_WALL_BANNER
Definition: BlockType.h:196
unsigned char NIBBLETYPE
The datatype used by nibbledata (meta, light, skylight)
Definition: ChunkDef.h:44
eBlockFace
Block face constants, used in PlayerDigging and PlayerBlockPlacement packets and bbox collision calc.
Definition: Defines.h:38
@ BLOCK_FACE_EAST
Definition: Defines.h:53
@ BLOCK_FACE_TOP
Definition: Defines.h:49
@ BLOCK_FACE_WEST
Definition: Defines.h:52
@ BLOCK_FACE_BOTTOM
Definition: Defines.h:48
@ BLOCK_FACE_NORTH
Definition: Defines.h:50
@ BLOCK_FACE_NONE
Definition: Defines.h:39
#define ASSERT(x)
Definition: Globals.h:276
unsigned char Rotation(const BlockState Block)
void SetBaseColor(unsigned char a_Color)
Definition: BannerEntity.h:31
void SetCustomName(const AString &a_CustomName)
Definition: BannerEntity.h:34
BLOCKTYPE GetBlockType() const
Definition: BlockEntity.h:97
double GetYaw(void) const
Definition: Entity.h:198
cWorld * GetWorld(void) const
Definition: Entity.h:190
Definition: Player.h:29
bool PlaceBlock(Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
Attempts to place the block in the world with a call to PlaceBlocks.
Definition: Player.cpp:2440
Definition: Item.h:37
AString m_CustomName
Definition: Item.h:167
short m_ItemDamage
Definition: Item.h:165
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: ItemBanner.h:26
static bool TryPlaceBanner(cPlayer &a_Player, const Vector3i a_PlacePosition, const eBlockFace a_ClickedBlockFace)
Definition: ItemBanner.h:64
virtual bool IsPlaceable(void) const override
Blocks simply get placed.
Definition: ItemBanner.h:56
constexpr cItemHandler(int a_ItemType)
Definition: ItemHandler.h:37
virtual bool DoWithBlockEntityAt(Vector3i a_Position, cBlockEntityCallback a_Callback) override
Calls the callback for the block entity at the specified coords; returns false if there's no block en...
Definition: World.cpp:1420