Cuberite
A lightweight, fast and extensible game server for Minecraft
BlockBed.cpp
Go to the documentation of this file.
1 
2 // BlockBed.cpp
3 
4 #include "Globals.h"
5 #include "BlockBed.h"
6 
7 #include "BroadcastInterface.h"
8 #include "../Entities/Player.h"
9 #include "../World.h"
10 #include "../BoundingBox.h"
11 #include "../Mobs/Monster.h"
12 #include "../BlockEntities/BedEntity.h"
13 
14 
15 
16 
17 
18 void cBlockBedHandler::OnBroken(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, Vector3i a_BlockPos, BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta)
19 {
20  auto Direction = MetaDataToDirection(a_OldBlockMeta & 0x03);
21  if ((a_OldBlockMeta & 0x08) != 0)
22  {
23  // Was pillow
24  if (a_ChunkInterface.GetBlock(a_BlockPos - Direction) == E_BLOCK_BED)
25  {
26  // First replace the bed with air
27  a_ChunkInterface.FastSetBlock(a_BlockPos - Direction, E_BLOCK_AIR, 0);
28 
29  // Then destroy the bed entity
30  Vector3i PillowPos(a_BlockPos - Direction);
31  a_ChunkInterface.SetBlock(PillowPos, E_BLOCK_AIR, 0);
32  }
33  }
34  else
35  {
36  // Was foot end
37  if (a_ChunkInterface.GetBlock(a_BlockPos + Direction) == E_BLOCK_BED)
38  {
39  // First replace the bed with air
40  a_ChunkInterface.FastSetBlock(a_BlockPos + Direction, E_BLOCK_AIR, 0);
41 
42  // Then destroy the bed entity
43  Vector3i FootPos(a_BlockPos + Direction);
44  a_ChunkInterface.SetBlock(FootPos, E_BLOCK_AIR, 0);
45  }
46  }
47 }
48 
49 
50 
51 
52 
53 bool cBlockBedHandler::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)
54 {
55  Vector3i Coords(a_BlockX, a_BlockY, a_BlockZ);
56  if (a_WorldInterface.GetDimension() != dimOverworld)
57  {
58  a_WorldInterface.DoExplosionAt(5, a_BlockX, a_BlockY, a_BlockZ, true, esBed, &Coords);
59  }
60  else if (!((a_WorldInterface.GetTimeOfDay() > 12541) && (a_WorldInterface.GetTimeOfDay() < 23458))) // Source: https://minecraft.gamepedia.com/Bed#Sleeping
61  {
62  a_Player.SendMessageFailure("You can only sleep at night");
63  }
64  else
65  {
66  NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(Coords);
67  if ((Meta & 0x4) == 0x4)
68  {
69  a_Player.SendMessageFailure("This bed is occupied");
70  }
71  else
72  {
73  auto FindMobs = [](cEntity & a_Entity)
74  {
75  return (
76  (a_Entity.GetEntityType() == cEntity::etMonster) &&
77  (static_cast<cMonster&>(a_Entity).GetMobFamily() == cMonster::mfHostile)
78  );
79  };
80 
81  if (!a_Player.GetWorld()->ForEachEntityInBox(cBoundingBox(a_Player.GetPosition() - Vector3i(0, 5, 0), 8, 10), FindMobs))
82  {
83  a_Player.SendMessageFailure("You may not rest now, there are monsters nearby");
84  }
85  else
86  {
87  Vector3i PillowDirection(0, 0, 0);
88 
89  if ((Meta & 0x8) == 0x8)
90  {
91  // Is pillow
92  a_WorldInterface.GetBroadcastManager().BroadcastUseBed(a_Player, { a_BlockX, a_BlockY, a_BlockZ });
93  }
94  else
95  {
96  // Is foot end
97  VERIFY((Meta & 0x4) != 0x4); // Occupied flag should never be set, else our compilator (intended) is broken
98 
99  PillowDirection = MetaDataToDirection(Meta & 0x3);
100  if (a_ChunkInterface.GetBlock(Coords + PillowDirection) == E_BLOCK_BED) // Must always use pillow location for sleeping
101  {
102  a_WorldInterface.GetBroadcastManager().BroadcastUseBed(a_Player, Vector3i{a_BlockX, a_BlockY, a_BlockZ} + PillowDirection);
103  }
104  }
105 
106  a_Player.SetBedPos(Coords);
107  SetBedOccupationState(a_ChunkInterface, a_Player.GetLastBedPos(), true);
108  a_Player.SetIsInBed(true);
109  a_Player.SendMessageSuccess("Home position set successfully");
110 
111  auto TimeFastForwardTester = [](cPlayer & a_OtherPlayer)
112  {
113  if (!a_OtherPlayer.IsInBed())
114  {
115  return true;
116  }
117  return false;
118  };
119 
120  if (a_WorldInterface.ForEachPlayer(TimeFastForwardTester))
121  {
122  a_WorldInterface.ForEachPlayer([&](cPlayer & a_OtherPlayer)
123  {
124  cBlockBedHandler::SetBedOccupationState(a_ChunkInterface, a_OtherPlayer.GetLastBedPos(), false);
125  a_OtherPlayer.SetIsInBed(false);
126  return false;
127  }
128  );
129  a_WorldInterface.SetTimeOfDay(0);
130  a_ChunkInterface.SetBlockMeta({a_BlockX, a_BlockY, a_BlockZ}, Meta & 0x0b); // Clear the "occupied" bit of the bed's block
131  }
132  }
133  }
134  }
135  return true;
136 }
137 
138 
139 
140 
141 
142 void cBlockBedHandler::OnPlacedByPlayer(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, const sSetBlock & a_BlockChange)
143 {
144  a_Player.GetWorld()->DoWithBedAt(a_BlockChange.GetX(), a_BlockChange.GetY(), a_BlockChange.GetZ(), [&](cBedEntity & a_Bed)
145  {
146  a_Bed.SetColor(a_Player.GetEquippedItem().m_ItemDamage);
147  return true;
148  }
149  );
150 }
151 
152 
153 
154 
155 
156 cItems cBlockBedHandler::ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool)
157 {
158  short color = E_META_WOOL_RED;
159  if (a_BlockEntity != nullptr)
160  {
161  color = reinterpret_cast<cBedEntity *>(a_BlockEntity)->GetColor();
162  }
163  return cItem(E_ITEM_BED, 1, color);
164 }
void SetBlock(Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
Sets the block at the specified coords to the specified value.
virtual bool ForEachEntityInBox(const cBoundingBox &a_Box, cEntityCallback a_Callback) override
Calls the callback for each entity that has a nonempty intersection with the specified boundingbox...
Definition: World.cpp:2729
virtual void OnPlacedByPlayer(cChunkInterface &a_ChunkInterface, cWorldInterface &a_WorldInterface, cPlayer &a_Player, const sSetBlock &a_BlockChange) override
Called by cPlayer::PlaceBlocks() for each block after it has been set to the world.
Definition: BlockBed.cpp:142
void FastSetBlock(Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
Sets the block at the specified coords to the specified value.
#define VERIFY(x)
Definition: Globals.h:339
short m_ItemDamage
Definition: Item.h:211
virtual bool ForEachPlayer(cPlayerListCallback a_Callback)=0
Calls the callback for each player in the list; returns true if all players processed, false if the callback aborted by returning true.
virtual void SetTimeOfDay(int a_TimeOfDay)=0
unsigned char BLOCKTYPE
The datatype used by blockdata.
Definition: ChunkDef.h:42
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: BlockBed.cpp:18
int GetY(void) const
Returns the absolute Y coord of the stored block.
Definition: ChunkDef.h:554
const cItem & GetEquippedItem(void) const
Definition: Player.h:142
Definition: Player.h:27
static Vector3i MetaDataToDirection(NIBBLETYPE a_MetaData)
Definition: BlockBed.h:62
virtual bool DoWithBedAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBedCallback a_Callback) override
Calls the callback for the bed at the specified coords; returns false if there&#39;s no bed at those coor...
Definition: World.cpp:1450
static void SetBedOccupationState(cChunkInterface &a_ChunkInterface, Vector3i a_BedPosition, bool a_IsOccupied)
Definition: BlockBed.h:78
unsigned char NIBBLETYPE
The datatype used by nibbledata (meta, light, skylight)
Definition: ChunkDef.h:45
void SetBedPos(const Vector3i &a_Pos)
Sets the player&#39;s bed (home / respawn) position to the specified position.
Definition: Player.cpp:938
Represents two sets of coords, minimum and maximum for each direction.
Definition: BoundingBox.h:23
virtual void DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, bool a_CanCauseFire, eExplosionSource a_Source, void *a_SourceData)=0
int GetZ(void) const
Returns the absolute Z coord of the stored block.
Definition: ChunkDef.h:557
void SetIsInBed(bool a_Flag)
Sets a player&#39;s in-bed state We can&#39;t be sure plugins will keep this value updated, so no exporting If value is false (not in bed), will update players of the fact that they have been ejected from the bed.
Definition: Player.h:363
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: BlockBed.cpp:53
int GetX(void) const
Returns the absolute X coord of the stored block.
Definition: ChunkDef.h:550
void SendMessageFailure(const AString &a_Message)
Definition: Player.cpp:1426
Direction
Vector3i GetLastBedPos(void) const
Gets the last position that the player slept in This is initialised to the world spawn point if the p...
Definition: Player.h:500
void SendMessageSuccess(const AString &a_Message)
Definition: Player.cpp:1435
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 int GetTimeOfDay(void) const =0
virtual void BroadcastUseBed(const cEntity &a_Entity, Vector3i a_BedPos)=0
Definition: Entity.h:73
const Vector3d & GetPosition(void) const
Exported in ManualBindings.
Definition: Entity.h:307
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.
Vector3< int > Vector3i
Definition: Vector3.h:447
virtual eDimension GetDimension(void) const =0
Definition: Item.h:36
virtual cBroadcastInterface & GetBroadcastManager()=0
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity *a_BlockEntity, const cEntity *a_Digger, const cItem *a_Tool) override
Returns the pickups that would result if the block was mined by a_Digger using a_Tool.
Definition: BlockBed.cpp:156
cWorld * GetWorld(void) const
Definition: Entity.h:201
This class bridges a vector of cItem for safe access via Lua.
Definition: Item.h:234