Cuberite
A lightweight, fast and extensible game server for Minecraft
Boat.cpp
Go to the documentation of this file.
1 
2 // Boat.cpp
3 
4 // Implements the cBoat class representing a boat in the world
5 
6 #include "Globals.h"
7 #include "Boat.h"
8 #include "../BlockInfo.h"
9 #include "../World.h"
10 #include "../ClientHandle.h"
11 #include "Player.h"
12 
13 
14 
15 
16 
18 {
19 public:
20 
21  cBoatCollisionCallback(cBoat & a_Boat, cEntity * a_Attachee) :
22  m_Boat(a_Boat), m_Attachee(a_Attachee)
23  {
24  }
25 
26  bool operator()(cEntity & a_Entity)
27  {
28  // Checks if boat is empty and if given entity is a mob:
29  if ((m_Attachee == nullptr) && a_Entity.IsMob())
30  {
31  // If so attach and stop iterating:
32  a_Entity.AttachTo(m_Boat);
33  return true;
34  }
35 
36  return false;
37  }
38 
39 protected:
40 
43 };
44 
45 
46 
47 
48 
49 cBoat::cBoat(Vector3d a_Pos, eMaterial a_Material) :
50  Super(etBoat, a_Pos, 1.375f, 0.5625f),
51  m_LastDamage(0), m_ForwardDirection(0),
52  m_DamageTaken(0.0f), m_Material(a_Material),
53  m_RightPaddleUsed(false), m_LeftPaddleUsed(false)
54 {
55  SetMass(20.0f);
56  SetGravity(-16.0f);
57  SetAirDrag(0.05f);
58  SetMaxHealth(6);
59  SetHealth(6);
60 }
61 
62 
63 
64 
65 
66 void cBoat::SpawnOn(cClientHandle & a_ClientHandle)
67 {
68  a_ClientHandle.SendSpawnEntity(*this);
69  a_ClientHandle.SendEntityMetadata(*this); // Boat colour
70 }
71 
72 
73 
74 
75 
77 {
78  // Cannot use super::BroadcastMovementUpdate here, broadcasting position when not
79  // expected by the client breaks things. See https://github.com/cuberite/cuberite/pull/4488
80 
81  // Process packet sending every two ticks:
82  if ((GetWorld()->GetWorldTickAge() % 2_tick) != 0_tick)
83  {
84  return;
85  }
86 
87  Vector3i Diff = (GetPosition() * 32.0).Floor() - (m_LastSentPosition * 32.0).Floor();
88  if (Diff.HasNonZeroLength()) // Have we moved?
89  {
90  m_World->BroadcastEntityPosition(*this, a_Exclude);
92  m_bDirtyOrientation = false;
93  }
94 }
95 
96 
97 
98 
99 
101 {
102  m_LastDamage = 10;
103  if (!Super::DoTakeDamage(TDI))
104  {
105  return false;
106  }
107 
109 
110  if ((TDI.Attacker != nullptr) && (TDI.Attacker->IsPlayer()))
111  {
112  cPlayer * Destroyer = static_cast<cPlayer *>(TDI.Attacker);
113  if (Destroyer->IsGameModeCreative())
114  {
115  Destroy();
116  return true;
117  }
118  }
119 
120  if (GetHealth() <= 0)
121  {
122  if (TDI.Attacker != nullptr)
123  {
124  if (TDI.Attacker->IsPlayer())
125  {
126  cItems Pickups;
127  Pickups.Add(MaterialToItem(m_Material));
128  m_World->SpawnItemPickups(Pickups, GetPosX(), GetPosY(), GetPosZ(), 0, 0, 0, true);
129  }
130  }
131  Destroy();
132  }
133  return true;
134 }
135 
136 
137 
138 
139 
141 {
142  Super::OnRightClicked(a_Player);
143 
144  if (m_Attachee != nullptr)
145  {
146  if (m_Attachee->GetUniqueID() == a_Player.GetUniqueID())
147  {
148  // This player is already sitting in, they want out.
149  a_Player.Detach();
150  return;
151  }
152 
153  if (m_Attachee->IsPlayer())
154  {
155  // Another player is already sitting in here, cannot attach
156  return;
157  }
158 
159  // Detach whatever is sitting in this boat now:
160  m_Attachee->Detach();
161  }
162 
163  // Attach the player to this boat
164  a_Player.AttachTo(*this);
165 }
166 
167 
168 
169 
170 
171 void cBoat::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
172 {
173  Super::Tick(a_Dt, a_Chunk);
174  if (!IsTicking())
175  {
176  // The base class tick destroyed us
177  return;
178  }
180 
181  SetSpeed(GetSpeed() * 0.97); // Slowly decrease the speed
182 
183  if ((POSY_TOINT < 0) || (POSY_TOINT >= cChunkDef::Height))
184  {
185  return;
186  }
187 
189  {
190  if (GetSpeedY() < 2)
191  {
192  AddSpeedY(0.2);
193  }
194  }
195 
196  if (GetLastDamage() > 0)
197  {
199  }
200 }
201 
202 
203 
204 
205 
206 void cBoat::HandleSpeedFromAttachee(float a_Forward, float a_Sideways)
207 {
208  if (GetSpeed().Length() > 7.5)
209  {
210  return;
211  }
212 
213  Vector3d ToAddSpeed = m_Attachee->GetLookVector() * (a_Sideways * 0.4) ;
214  ToAddSpeed.y = 0;
215 
216  AddSpeed(ToAddSpeed);
217 }
218 
219 
220 
221 
222 
223 void cBoat::SetLastDamage(int TimeSinceLastHit)
224 {
225  m_LastDamage = TimeSinceLastHit;
226 
227  // Tell the client to play the shaking animation
229 }
230 
231 
232 
233 
234 
235 void cBoat::UpdatePaddles(bool a_RightPaddleUsed, bool a_LeftPaddleUsed)
236 {
237  // Avoid telling client what it already knows since it may reset animation 1.13+
238  const bool Changed = (m_RightPaddleUsed != a_RightPaddleUsed) || (m_LeftPaddleUsed != a_LeftPaddleUsed);
239 
240  m_RightPaddleUsed = a_RightPaddleUsed;
241  m_LeftPaddleUsed = a_LeftPaddleUsed;
242 
243  if (Changed)
244  {
246  }
247 }
248 
249 
250 
251 
252 
254 {
255  switch (a_Item.m_ItemType)
256  {
257  case E_ITEM_BOAT: return bmOak;
258  case E_ITEM_SPRUCE_BOAT: return bmSpruce;
259  case E_ITEM_BIRCH_BOAT: return bmBirch;
260  case E_ITEM_JUNGLE_BOAT: return bmJungle;
261  case E_ITEM_ACACIA_BOAT: return bmAcacia;
262  case E_ITEM_DARK_OAK_BOAT: return bmDarkOak;
263  default:
264  {
265  LOGWARNING("%s: Item type not handled %d.", __FUNCTION__, a_Item.m_ItemType);
266  return cBoat::bmOak;
267  }
268  }
269 }
270 
271 
272 
273 
274 
276 {
277  switch (a_Material)
278  {
279  case bmOak: return "oak";
280  case bmSpruce: return "spruce";
281  case bmBirch: return "birch";
282  case bmJungle: return "jungle";
283  case bmAcacia: return "acacia";
284  case bmDarkOak: return "dark_oak";
285  }
286  UNREACHABLE("Unsupported boat material");
287 }
288 
289 
290 
291 
292 
294 {
295  if (a_Material == "oak")
296  {
297  return bmOak;
298  }
299  else if (a_Material == "spruce")
300  {
301  return bmSpruce;
302  }
303  else if (a_Material == "birch")
304  {
305  return bmBirch;
306  }
307  else if (a_Material == "jungle")
308  {
309  return bmJungle;
310  }
311  else if (a_Material == "acacia")
312  {
313  return bmAcacia;
314  }
315  else if (a_Material == "dark_oak")
316  {
317  return bmDarkOak;
318  }
319  else
320  {
321  return bmOak;
322  }
323 }
324 
325 
326 
327 
328 
330 {
331  switch (a_Material)
332  {
333  case bmOak: return cItem(E_ITEM_BOAT);
334  case bmSpruce: return cItem(E_ITEM_SPRUCE_BOAT);
335  case bmBirch: return cItem(E_ITEM_BIRCH_BOAT);
336  case bmJungle: return cItem(E_ITEM_JUNGLE_BOAT);
337  case bmAcacia: return cItem(E_ITEM_ACACIA_BOAT);
338  case bmDarkOak: return cItem(E_ITEM_DARK_OAK_BOAT);
339  }
340  UNREACHABLE("Unsupported boat material");
341 }
342 
343 
344 
345 
346 
347 void cBoat::HandlePhysics(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
348 {
353  // Calculate boat's bounding box, run collision callback on all entities in said box
354  cBoatCollisionCallback BoatCollisionCallback(*this, m_Attachee);
355  Vector3d BoatPosition = GetPosition();
356  cBoundingBox bbBoat(
357  Vector3d(BoatPosition.x, floor(BoatPosition.y), BoatPosition.z), GetWidth() / 2, GetHeight());
358  m_World->ForEachEntityInBox(bbBoat, BoatCollisionCallback);
359 
360  // Return to calculating physics normally
361  Super::HandlePhysics(a_Dt, a_Chunk);
362 }
bool IsBlockWater(BLOCKTYPE a_BlockType)
Definition: BlockInfo.cpp:10
@ E_ITEM_SPRUCE_BOAT
Definition: BlockType.h:491
@ E_ITEM_BOAT
Definition: BlockType.h:377
@ E_ITEM_ACACIA_BOAT
Definition: BlockType.h:494
@ E_ITEM_JUNGLE_BOAT
Definition: BlockType.h:493
@ E_ITEM_DARK_OAK_BOAT
Definition: BlockType.h:495
@ E_ITEM_BIRCH_BOAT
Definition: BlockType.h:492
T Diff(T a_Val1, T a_Val2)
Definition: Defines.h:617
#define POS_TOINT
Definition: Entity.h:34
#define POSY_TOINT
Definition: Entity.h:32
#define UNREACHABLE(x)
Definition: Globals.h:288
void LOGWARNING(std::string_view a_Format, const Args &... args)
Definition: LoggerSimple.h:67
std::string AString
Definition: StringUtils.h:11
Vector3< double > Vector3d
Definition: Vector3.h:485
Represents two sets of coords, minimum and maximum for each direction.
Definition: BoundingBox.h:24
Definition: Chunk.h:36
static const int Height
Definition: ChunkDef.h:125
void SendSpawnEntity(const cEntity &a_Entity)
void SendEntityMetadata(const cEntity &a_Entity)
cEntity * m_Attachee
Definition: Boat.cpp:42
bool operator()(cEntity &a_Entity)
Definition: Boat.cpp:26
cBoatCollisionCallback(cBoat &a_Boat, cEntity *a_Attachee)
Definition: Boat.cpp:21
Definition: Boat.h:20
virtual void BroadcastMovementUpdate(const cClientHandle *a_Exclude=nullptr) override
Updates clients of changes in the entity.
Definition: Boat.cpp:76
cBoat(Vector3d a_Pos, eMaterial a_Material)
Definition: Boat.cpp:49
virtual void SpawnOn(cClientHandle &a_ClientHandle) override
Descendants override this function to send a command to the specified client to spawn the entity on t...
Definition: Boat.cpp:66
bool m_LeftPaddleUsed
Definition: Boat.h:95
static AString MaterialToString(const eMaterial a_Material)
Returns the eMaterial as string.
Definition: Boat.cpp:275
virtual void Tick(std::chrono::milliseconds a_Dt, cChunk &a_Chunk) override
Definition: Boat.cpp:171
static eMaterial ItemToMaterial(const cItem &a_Item)
Returns the eMaterial that should be used for a boat created from the specified item.
Definition: Boat.cpp:253
virtual void HandlePhysics(std::chrono::milliseconds a_Dt, cChunk &a_Chunk) override
Handles the physics of the entity - updates position based on speed, updates speed based on environme...
Definition: Boat.cpp:347
static eMaterial StringToMaterial(const AString &a_Material)
Returns the boat material for the passed string.
Definition: Boat.cpp:293
bool m_RightPaddleUsed
Definition: Boat.h:94
void UpdatePaddles(bool rightPaddleUsed, bool leftPaddleUsed)
Definition: Boat.cpp:235
int m_LastDamage
Definition: Boat.h:87
int GetLastDamage(void) const
Definition: Boat.h:53
eMaterial m_Material
Definition: Boat.h:92
virtual bool DoTakeDamage(TakeDamageInfo &TDI) override
Makes this entity take damage specified in the a_TDI.
Definition: Boat.cpp:100
void SetLastDamage(int TimeSinceLastHit)
Definition: Boat.cpp:223
virtual void OnRightClicked(cPlayer &a_Player) override
Called when the specified player right-clicks this entity.
Definition: Boat.cpp:140
eMaterial
Definition: Boat.h:29
@ bmAcacia
Definition: Boat.h:34
@ bmOak
Definition: Boat.h:30
@ bmBirch
Definition: Boat.h:32
@ bmDarkOak
Definition: Boat.h:35
@ bmJungle
Definition: Boat.h:33
@ bmSpruce
Definition: Boat.h:31
virtual void HandleSpeedFromAttachee(float a_Forward, float a_Sideways) override
Definition: Boat.cpp:206
static cItem MaterialToItem(eMaterial a_Material)
Returns the boat item of the boat material.
Definition: Boat.cpp:329
cEntity * Attacker
Definition: Entity.h:62
Definition: Entity.h:76
Vector3d m_LastSentPosition
Last position sent to client via the Relative Move or Teleport packets (not Velocity) Only updated if...
Definition: Entity.h:618
const Vector3d & GetSpeed(void) const
Exported in ManualBindings.
Definition: Entity.h:300
bool IsPlayer(void) const
Definition: Entity.h:160
virtual void Tick(std::chrono::milliseconds a_Dt, cChunk &a_Chunk)
Definition: Entity.cpp:909
cEntity * m_Attachee
The entity which is attached to this entity (rider), nullptr if none.
Definition: Entity.h:591
void Detach(void)
Detaches from the currently attached entity, if any.
Definition: Entity.cpp:2052
void AddSpeed(double a_AddSpeedX, double a_AddSpeedY, double a_AddSpeedZ)
Definition: Entity.cpp:2194
bool m_bDirtyOrientation
Stores whether our yaw / pitch / roll (body orientation) has been set manually.
Definition: Entity.h:597
void SetHealth(float a_Health)
Sets the health of this entity; doesn't broadcast any hurt animation.
Definition: Entity.cpp:900
double GetSpeedY(void) const
Definition: Entity.h:203
bool IsTicking(void) const
Returns true if the entity is valid and ticking.
Definition: Entity.cpp:2259
void SetGravity(float a_Gravity)
Definition: Entity.h:282
void SetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ)
Sets the speed of the entity, measured in m / sec.
Definition: Entity.cpp:2157
double GetPosX(void) const
Definition: Entity.h:195
float GetWidth(void) const
Definition: Entity.h:205
cWorld * m_World
Definition: Entity.h:624
double GetPosZ(void) const
Definition: Entity.h:197
UInt32 GetUniqueID(void) const
Definition: Entity.h:253
void Destroy()
Destroys the entity, schedules it for memory freeing and broadcasts the DestroyEntity packet.
Definition: Entity.cpp:243
void AddSpeedY(double a_AddSpeedY)
Definition: Entity.cpp:2212
double GetPosY(void) const
Definition: Entity.h:196
virtual void HandlePhysics(std::chrono::milliseconds a_Dt, cChunk &a_Chunk)
Handles the physics of the entity - updates position based on speed, updates speed based on environme...
Definition: Entity.cpp:1001
void SetMass(double a_Mass)
Definition: Entity.cpp:2113
float GetHeight(void) const
Definition: Entity.h:193
void SetAirDrag(float a_AirDrag)
Definition: Entity.h:286
virtual bool DoTakeDamage(TakeDamageInfo &a_TDI)
Makes this entity take damage specified in the a_TDI.
Definition: Entity.cpp:404
float GetHealth(void) const
Returns the health of this entity.
Definition: Entity.h:367
void SetMaxHealth(float a_MaxHealth)
Sets the maximum value for the health.
Definition: Entity.cpp:1887
virtual void OnRightClicked(cPlayer &a_Player)
Called when the specified player right-clicks this entity.
Definition: Entity.h:524
const Vector3d & GetPosition(void) const
Exported in ManualBindings.
Definition: Entity.h:297
Vector3d GetLookVector(void) const
Definition: Entity.cpp:2267
void AttachTo(cEntity &a_AttachTo)
Attaches to the specified entity; detaches from any previous one first.
Definition: Entity.cpp:2027
cWorld * GetWorld(void) const
Definition: Entity.h:190
bool IsMob(void) const
Definition: Entity.h:162
Definition: Player.h:29
bool IsGameModeCreative(void) const
Returns true if the player is in Creative mode, either explicitly, or by inheriting from current worl...
Definition: Player.cpp:1025
Definition: Item.h:37
short m_ItemType
Definition: Item.h:163
This class bridges a vector of cItem for safe access via Lua.
Definition: Item.h:215
void Add(const cItem &a_Item)
Definition: Item.h:233
T x
Definition: Vector3.h:17
T y
Definition: Vector3.h:17
T z
Definition: Vector3.h:17
virtual void BroadcastEntityMetadata(const cEntity &a_Entity, const cClientHandle *a_Exclude=nullptr) override
BLOCKTYPE GetBlock(Vector3i a_BlockPos) const
Returns the block type at the specified position.
Definition: World.h:363
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:2445
void SpawnItemPickups(const cItems &a_Pickups, Vector3i a_BlockPos, double a_FlyAwaySpeed=1.0, bool a_IsPlayerCreated=false)
Spawns item pickups for each item in the list.
Definition: World.cpp:1806
virtual void BroadcastEntityPosition(const cEntity &a_Entity, const cClientHandle *a_Exclude=nullptr) override