Cuberite
A lightweight, fast and extensible game server for Minecraft
FallingBlock.cpp
Go to the documentation of this file.
1 #include "Globals.h"
2 
3 #include "FallingBlock.h"
4 #include "../World.h"
5 #include "../ClientHandle.h"
6 #include "../Simulator/SandSimulator.h"
7 #include "../Chunk.h"
8 
9 
10 
11 
12 
13 cFallingBlock::cFallingBlock(Vector3i a_BlockPosition, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) :
14  super(etFallingBlock, Vector3d(0.5, 0, 0.5) + a_BlockPosition, 0.98, 0.98),
15  m_BlockType(a_BlockType),
16  m_BlockMeta(a_BlockMeta),
17  m_OriginalPosition(a_BlockPosition)
18 {
19  SetGravity(-16.0f);
20  SetAirDrag(0.02f);
21 }
22 
23 
24 
25 
26 
27 void cFallingBlock::SpawnOn(cClientHandle & a_ClientHandle)
28 {
29  a_ClientHandle.SendSpawnFallingBlock(*this);
30 }
31 
32 
33 
34 
35 
36 void cFallingBlock::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
37 {
38  // GetWorld()->BroadcastTeleportEntity(*this); // Test position
39 
40  int BlockX = POSX_TOINT;
41  int BlockY = static_cast<int>(GetPosY() - 0.5);
42  int BlockZ = POSZ_TOINT;
43 
44  if (BlockY < 0)
45  {
46  // Fallen out of this world, just continue falling until out of sight, then destroy:
47  if (BlockY < VOID_BOUNDARY)
48  {
49  Destroy(true);
50  }
51  return;
52  }
53 
54  if (BlockY >= cChunkDef::Height)
55  {
56  // Above the world, just wait for it to fall back down
57  return;
58  }
59 
60  BLOCKTYPE BlockBelow = a_Chunk.GetBlock(BlockX - a_Chunk.GetPosX() * cChunkDef::Width, BlockY, BlockZ - a_Chunk.GetPosZ() * cChunkDef::Width);
61  NIBBLETYPE BelowMeta = a_Chunk.GetMeta(BlockX - a_Chunk.GetPosX() * cChunkDef::Width, BlockY, BlockZ - a_Chunk.GetPosZ() * cChunkDef::Width);
62  if (cSandSimulator::DoesBreakFallingThrough(BlockBelow, BelowMeta))
63  {
64  // Fallen onto a block that breaks this into pickups (e. g. half-slab)
65  // Must finish the fall with coords one below the block:
67  Destroy(true);
68  return;
69  }
70  else if (!cSandSimulator::CanContinueFallThrough(BlockBelow))
71  {
72  // Fallen onto a solid block
73  /*
74  FLOGD(
75  "Sand: Checked below at {0} (rel {1}), it's {2}, finishing the fall.",
76  Vector3i{BlockX, BlockY, BlockZ},
77  cChunkDef::AbsoluteToRelative({BlockX, BlockY, BlockZ}, {a_Chunk.GetPosX(), a_Chunk.GetPosZ()}),
78  ItemTypeToString(BlockBelow)
79  );
80  */
81 
82  if (BlockY < cChunkDef::Height - 1)
83  {
84  cSandSimulator::FinishFalling(m_World, BlockX, BlockY + 1, BlockZ, m_BlockType, m_BlockMeta);
85  }
86  Destroy(true);
87  return;
88  }
89  else if ((m_BlockType == E_BLOCK_CONCRETE_POWDER) && IsBlockWater(BlockBelow))
90  {
91  // Concrete powder falling into water solidifies on the first water it touches
93  Destroy(true);
94  return;
95  }
96 
97  float MilliDt = a_Dt.count() * 0.001f;
98  AddSpeedY(MilliDt * -9.8f);
99  AddPosition(GetSpeed() * MilliDt);
100 
101  // If not static (one billionth precision) broadcast movement
102  if ((fabs(GetSpeedX()) > std::numeric_limits<double>::epsilon()) || (fabs(GetSpeedZ()) > std::numeric_limits<double>::epsilon()))
103  {
105  }
106 }
107 
108 
109 
110 
double GetPosY(void) const
Definition: Entity.h:207
static const int VOID_BOUNDARY
Y position to begin applying void damage.
Definition: Entity.h:152
bool IsBlockWater(BLOCKTYPE a_BlockType)
Definition: Defines.h:436
static void FinishFalling(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_FallingBlockType, NIBBLETYPE a_FallingBlockMeta)
Called when a block finishes falling at the specified coords, either by insta-fall, or through cFallingBlock entity.
double GetSpeedX(void) const
Definition: Entity.h:213
virtual void Tick(std::chrono::milliseconds a_Dt, cChunk &a_Chunk) override
unsigned char BLOCKTYPE
The datatype used by blockdata.
Definition: ChunkDef.h:42
cFallingBlock(Vector3i a_BlockPosition, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
Creates a new falling block.
void SendSpawnFallingBlock(const cFallingBlock &a_FallingBlock)
static const int Width
Definition: ChunkDef.h:134
cWorld * m_World
Definition: Entity.h:620
const Vector3d & GetSpeed(void) const
Exported in ManualBindings.
Definition: Entity.h:310
unsigned char NIBBLETYPE
The datatype used by nibbledata (meta, light, skylight)
Definition: ChunkDef.h:45
double GetSpeedZ(void) const
Definition: Entity.h:215
Definition: Chunk.h:49
virtual void Destroy(bool a_ShouldBroadcast=true)
Destroys the entity and schedules it for memory freeing; if a_ShouldBroadcast is set to true...
Definition: Entity.cpp:219
static const int Height
Definition: ChunkDef.h:135
NIBBLETYPE m_BlockMeta
Definition: FallingBlock.h:39
void AddPosition(double a_AddPosX, double a_AddPosY, double a_AddPosZ)
Definition: Entity.h:250
NIBBLETYPE GetMeta(int a_RelX, int a_RelY, int a_RelZ) const
Definition: Chunk.h:380
int GetPosX(void) const
Definition: Chunk.h:150
#define POSX_TOINT
Definition: Entity.h:29
static bool CanContinueFallThrough(BLOCKTYPE a_BlockType)
Returns true if an already-falling block can pass through the specified block type (e...
void SetGravity(float a_Gravity)
Definition: Entity.h:288
void AddSpeedY(double a_AddSpeedY)
Definition: Entity.cpp:2154
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...
BLOCKTYPE GetBlock(int a_RelX, int a_RelY, int a_RelZ) const
Definition: Chunk.h:177
int GetPosZ(void) const
Definition: Chunk.h:151
BLOCKTYPE m_BlockType
Definition: FallingBlock.h:38
Definition: Entity.h:73
void SetAirDrag(float a_AirDrag)
Definition: Entity.h:292
#define POSZ_TOINT
Definition: Entity.h:31
static bool DoesBreakFallingThrough(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
Returns true if the specified block breaks falling blocks while they fall through it (e...
virtual void BroadcastMovementUpdate(const cClientHandle *a_Exclude=nullptr)
Updates clients of changes in the entity.
Definition: Entity.cpp:1878