Cuberite
A lightweight, fast and extensible game server for Minecraft
BlockButton.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "BlockHandler.h"
4 #include "../Chunk.h"
5 #include "Mixins.h"
6 
7 
8 
9 
11  public cClearMetaOnDrop<cMetaRotator<cBlockHandler, 0x07, 0x04, 0x01, 0x03, 0x02, true>>
12 {
14 
15 public:
16 
18  super(a_BlockType)
19  {
20  }
21 
22 
23 
24 
25 
26  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
27  {
28  Vector3i Pos(a_BlockX, a_BlockY, a_BlockZ);
29  NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(Pos);
30 
31  Vector3d SoundPos(Pos);
32 
33  // If button is already on do nothing
34  if (Meta & 0x08)
35  {
36  return false;
37  }
38 
39  // Set p the ON bit to on
40  Meta |= 0x08;
41 
42  a_ChunkInterface.SetBlockMeta({a_BlockX, a_BlockY, a_BlockZ}, Meta, false);
43  a_WorldInterface.WakeUpSimulators(Pos);
44  a_WorldInterface.GetBroadcastManager().BroadcastSoundEffect("block.stone_button.click_on", SoundPos, 0.5f, 0.6f);
45 
46  // Queue a button reset (unpress)
47  auto TickDelay = (m_BlockType == E_BLOCK_STONE_BUTTON) ? 20 : 30;
48  a_Player.GetWorld()->ScheduleTask(TickDelay, [SoundPos, Pos, this](cWorld & a_World)
49  {
50  if (a_World.GetBlock(Pos) == m_BlockType)
51  {
52  // Block hasn't change in the meantime; set its meta
53  a_World.SetBlockMeta(Pos.x, Pos.y, Pos.z, a_World.GetBlockMeta(Pos) & 0x07, false);
54  a_World.WakeUpSimulators(Pos);
55  a_World.BroadcastSoundEffect("block.stone_button.click_off", SoundPos, 0.5f, 0.5f);
56  }
57  }
58  );
59 
60  return true;
61  }
62 
63  virtual bool IsUseable(void) override
64  {
65  return true;
66  }
67 
69  cChunkInterface & a_ChunkInterface, cPlayer & a_Player,
70  int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
71  int a_CursorX, int a_CursorY, int a_CursorZ,
72  BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
73  ) override
74  {
75  a_BlockType = m_BlockType;
76  a_BlockMeta = BlockFaceToMetaData(a_BlockFace);
77  return true;
78  }
79 
80  inline static NIBBLETYPE BlockFaceToMetaData(eBlockFace a_BlockFace)
81  {
82  switch (a_BlockFace)
83  {
84  case BLOCK_FACE_YP: return 0x5;
85  case BLOCK_FACE_ZM: return 0x4;
86  case BLOCK_FACE_ZP: return 0x3;
87  case BLOCK_FACE_XM: return 0x2;
88  case BLOCK_FACE_XP: return 0x1;
89  case BLOCK_FACE_YM: return 0x0;
90  case BLOCK_FACE_NONE:
91  {
92  ASSERT(!"Unhandled block face!");
93  return 0x0;
94  }
95  }
96  UNREACHABLE("Unsupported block face");
97  }
98 
100  {
101  switch (a_Meta & 0x7)
102  {
103  case 0x0: return BLOCK_FACE_YM;
104  case 0x1: return BLOCK_FACE_XP;
105  case 0x2: return BLOCK_FACE_XM;
106  case 0x3: return BLOCK_FACE_ZP;
107  case 0x4: return BLOCK_FACE_ZM;
108  case 0x5: return BLOCK_FACE_YP;
109  default:
110  {
111  ASSERT(!"Unhandled block meta!");
112  return BLOCK_FACE_NONE;
113  }
114  }
115  }
116 
117  virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
118  {
119  NIBBLETYPE Meta;
120  a_Chunk.UnboundedRelGetBlockMeta(a_RelX, a_RelY, a_RelZ, Meta);
121 
122  AddFaceDirection(a_RelX, a_RelY, a_RelZ, BlockMetaDataToBlockFace(Meta), true);
123  BLOCKTYPE BlockIsOn; a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockIsOn);
124 
125  return (a_RelY > 0) && (cBlockInfo::FullyOccupiesVoxel(BlockIsOn));
126  }
127 
128  virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
129  {
130  UNUSED(a_Meta);
131  return 0;
132  }
133 
135  static bool IsButtonOn(NIBBLETYPE a_BlockMeta)
136  {
137  return ((a_BlockMeta & 0x8) == 0x8);
138  }
139 } ;
140 
141 
142 
143 
BLOCKTYPE GetBlock(Vector3i a_BlockPos)
Returns the block type at the specified position.
Definition: World.h:416
T x
Definition: Vector3.h:17
unsigned char BLOCKTYPE
The datatype used by blockdata.
Definition: ChunkDef.h:42
bool UnboundedRelGetBlockType(Vector3i a_RelCoords, BLOCKTYPE &a_BlockType) const
Same as GetBlockType(), but relative coords needn&#39;t be in this chunk (uses m_Neighbor-s or m_ChunkMap...
Definition: Chunk.cpp:1018
cBlockButtonHandler(BLOCKTYPE a_BlockType)
Definition: BlockButton.h:17
Definition: Player.h:27
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
virtual void WakeUpSimulators(Vector3i a_Block) override
Wakes up the simulators for the specified block.
Definition: World.cpp:1308
bool UnboundedRelGetBlockMeta(Vector3i a_RelPos, NIBBLETYPE &a_BlockMeta) const
Same as GetBlockMeta(), but relative coords needn&#39;t be in this chunk (uses m_Neighbor-s or m_ChunkMap...
Definition: Chunk.cpp:1039
T y
Definition: Vector3.h:17
NIBBLETYPE GetBlockMeta(Vector3i a_BlockPos)
Returns the block meta at the specified position.
Definition: World.h:431
T z
Definition: Vector3.h:17
virtual void BroadcastSoundEffect(const AString &a_SoundName, Vector3d a_Position, float a_Volume, float a_Pitch, const cClientHandle *a_Exclude=nullptr) override
virtual void BroadcastSoundEffect(const AString &a_SoundName, Vector3d a_Position, float a_Volume, float a_Pitch, const cClientHandle *a_Exclude=nullptr)=0
void AddFaceDirection(int &a_BlockX, int &a_BlockY, int &a_BlockZ, eBlockFace a_BlockFace, bool a_bInverse=false)
Definition: Defines.h:859
static bool IsButtonOn(NIBBLETYPE a_BlockMeta)
Extracts the ON bit from metadata and returns if true if it is set.
Definition: BlockButton.h:135
Definition: World.h:65
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: BlockButton.h:26
#define ASSERT(x)
Definition: Globals.h:335
virtual bool IsUseable(void) override
Checks if the block can be placed at this point.
Definition: BlockButton.h:63
void ScheduleTask(int a_DelayTicks, std::function< void(cWorld &)> a_Task)
Queues a lambda task onto the tick thread, with the specified delay.
Definition: World.cpp:3020
#define UNUSED
Definition: Globals.h:152
static bool FullyOccupiesVoxel(BLOCKTYPE a_Type)
Definition: BlockInfo.h:50
eBlockFace
Block face constants, used in PlayerDigging and PlayerBlockPlacement packets and bbox collision calc...
Definition: Defines.h:29
static eBlockFace BlockMetaDataToBlockFace(NIBBLETYPE a_Meta)
Definition: BlockButton.h:99
NIBBLETYPE GetBlockMeta(Vector3i a_Pos)
Byte ColourID
Definition: Globals.h:118
virtual void WakeUpSimulators(Vector3i a_Block)=0
Wakes up the simulators for the specified block.
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: BlockButton.h:117
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: BlockButton.h:128
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.
Mixin to clear the block&#39;s meta value when converting to a pickup.
Definition: Mixins.h:55
static NIBBLETYPE BlockFaceToMetaData(eBlockFace a_BlockFace)
Definition: BlockButton.h:80
void SetBlockMeta(Vector3i a_BlockPos, NIBBLETYPE a_MetaData, bool a_ShouldMarkDirty=true, bool a_ShouldInformClients=true)
Sets the meta for the specified block, while keeping the blocktype.
Definition: World.cpp:1882
#define UNREACHABLE(x)
Use to mark code that should be impossible to reach.
Definition: Globals.h:344
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: BlockButton.h:68
virtual cBroadcastInterface & GetBroadcastManager()=0
cWorld * GetWorld(void) const
Definition: Entity.h:201