Cuberite
A lightweight, fast and extensible game server for Minecraft
SimulatorManager.cpp
Go to the documentation of this file.
1 
2 #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
3 
4 #include "SimulatorManager.h"
5 #include "../Chunk.h"
6 #include "../Cuboid.h"
7 #include "../World.h"
8 
9 
10 
11 
12 
14  m_World(a_World),
15  m_Ticks(0)
16 {
17 }
18 
19 
20 
21 
22 
24 {
25 }
26 
27 
28 
29 
30 
32 {
33  m_Ticks++;
34 
35  for (cSimulators::iterator itr = m_Simulators.begin(); itr != m_Simulators.end(); ++itr)
36  {
37  if ((m_Ticks % itr->second) == 0)
38  {
39  itr->first->Simulate(a_Dt);
40  }
41  }
42 }
43 
44 
45 
46 
47 
48 void cSimulatorManager::SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk)
49 {
50  // m_Ticks has already been increased in Simulate()
51 
52  for (cSimulators::iterator itr = m_Simulators.begin(); itr != m_Simulators.end(); ++itr)
53  {
54  if ((m_Ticks % itr->second) == 0)
55  {
56  itr->first->SimulateChunk(a_Dt, a_ChunkX, a_ChunkZ, a_Chunk);
57  }
58  }
59 }
60 
61 
62 
63 
64 
65 void cSimulatorManager::WakeUp(cChunk & a_Chunk, Vector3i a_Position)
66 {
67  ASSERT(a_Chunk.IsValid());
68 
69  for (const auto & Item : m_Simulators)
70  {
71  Item.first->WakeUp(a_Chunk, a_Position, a_Chunk.GetBlock(a_Position));
72  }
73 
74  for (const auto & Offset : cSimulator::AdjacentOffsets)
75  {
76  auto Relative = a_Position + Offset;
77 
78  if (!cChunkDef::IsValidHeight(Relative))
79  {
80  continue;
81  }
82 
83  const auto Chunk = a_Chunk.GetRelNeighborChunkAdjustCoords(Relative);
84 
85  if ((Chunk == nullptr) || !Chunk->IsValid())
86  {
87  continue;
88  }
89 
90  // Stored block to give to simulators for performance
91  // Since they all need this we save them querying it themselves
92  const auto Block = Chunk->GetBlock(Relative);
93 
94  for (const auto & Item : m_Simulators)
95  {
96  Item.first->WakeUp(*Chunk, Relative, Offset, Block);
97  }
98  }
99 }
100 
101 
102 
103 
104 
105 void cSimulatorManager::WakeUp(const cCuboid & a_Area)
106 {
107  cCuboid area(a_Area);
108  area.Sort();
109  area.Expand(1, 1, 1, 1, 1, 1); // Expand the area to contain the neighbors, too.
110  area.ClampY(0, cChunkDef::Height - 1);
111 
112  cChunkCoords ChunkStart = cChunkDef::BlockToChunk(area.p1);
113  cChunkCoords ChunkEnd = cChunkDef::BlockToChunk(area.p2);
114 
115  // Add all blocks, in a per-chunk manner:
116  for (int cz = ChunkStart.m_ChunkZ; cz <= ChunkEnd.m_ChunkZ; ++cz)
117  {
118  for (int cx = ChunkStart.m_ChunkX; cx <= ChunkEnd.m_ChunkX; ++cx)
119  {
120  m_World.DoWithChunk(cx, cz, [this, &area](cChunk & a_CBChunk)
121  {
122  int startX = std::max(area.p1.x, a_CBChunk.GetPosX() * cChunkDef::Width);
123  int startZ = std::max(area.p1.z, a_CBChunk.GetPosZ() * cChunkDef::Width);
124  int endX = std::min(area.p2.x, a_CBChunk.GetPosX() * cChunkDef::Width + cChunkDef::Width - 1);
125  int endZ = std::min(area.p2.z, a_CBChunk.GetPosZ() * cChunkDef::Width + cChunkDef::Width - 1);
126 
127  for (const auto & Item : m_Simulators)
128  {
129  const auto Simulator = Item.first;
130 
131  for (int y = area.p1.y; y <= area.p2.y; ++y)
132  {
133  for (int z = startZ; z <= endZ; ++z)
134  {
135  for (int x = startX; x <= endX; ++x)
136  {
137  const auto Position = cChunkDef::AbsoluteToRelative({ x, y, z });
138  Simulator->WakeUp(a_CBChunk, Position, a_CBChunk.GetBlock(Position));
139  } // for x
140  } // for z
141  } // for y
142  }
143  return true;
144  });
145  } // for cx
146  } // for cz
147 }
148 
149 
150 
151 
152 
153 void cSimulatorManager::RegisterSimulator(cSimulator * a_Simulator, int a_Rate)
154 {
155  m_Simulators.push_back(std::make_pair(a_Simulator, a_Rate));
156 }
#define ASSERT(x)
Definition: Globals.h:276
Item
Definition: Items.h:4
Definition: Chunk.h:36
int GetPosX(void) const
Definition: Chunk.h:131
BLOCKTYPE GetBlock(int a_RelX, int a_RelY, int a_RelZ) const
Definition: Chunk.h:146
cChunk * GetRelNeighborChunkAdjustCoords(Vector3i &a_RelPos) const
Returns the chunk into which the relatively-specified block belongs.
Definition: Chunk.cpp:1885
bool IsValid(void) const
Returns true iff the chunk block data is valid (loaded / generated)
Definition: Chunk.h:58
int GetPosZ(void) const
Definition: Chunk.h:132
Wraps the chunk coords into a single structure.
Definition: ChunkDef.h:57
int m_ChunkZ
Definition: ChunkDef.h:60
int m_ChunkX
Definition: ChunkDef.h:59
static bool IsValidHeight(Vector3i a_BlockPosition)
Validates a height-coordinate.
Definition: ChunkDef.h:185
static void BlockToChunk(int a_X, int a_Z, int &a_ChunkX, int &a_ChunkZ)
Converts absolute block coords to chunk coords:
Definition: ChunkDef.h:210
static void AbsoluteToRelative(int &a_X, int &a_Y, int &a_Z, int &a_ChunkX, int &a_ChunkZ)
Converts absolute block coords into relative (chunk + block) coords:
Definition: ChunkDef.h:147
static const int Width
Definition: ChunkDef.h:124
static const int Height
Definition: ChunkDef.h:125
Definition: Cuboid.h:10
void Expand(int a_SubMinX, int a_AddMaxX, int a_SubMinY, int a_AddMaxY, int a_SubMinZ, int a_AddMaxZ)
Expands the cuboid by the specified amount in each direction.
Definition: Cuboid.cpp:84
Vector3i p2
Definition: Cuboid.h:13
void Sort(void)
Definition: Cuboid.cpp:23
Vector3i p1
Definition: Cuboid.h:13
void ClampY(int a_MinY, int a_MaxY)
Clamps both Y coords to the specified range.
Definition: Cuboid.cpp:173
Base class for all block-based physics simulators (such as fluid, fire, falling blocks etc....
Definition: Simulator.h:22
static constexpr std::array< Vector3i, 6 > AdjacentOffsets
Contains offsets for direct adjacents of any position.
Definition: Simulator.h:34
cSimulators m_Simulators
void RegisterSimulator(cSimulator *a_Simulator, int a_Rate)
cSimulatorManager(cWorld &a_World)
void SimulateChunk(std::chrono::milliseconds a_DT, int a_ChunkX, int a_ChunkZ, cChunk *a_Chunk)
Called in each tick for each chunk, a_Dt is the time passed since the last tick, in msec; direct acce...
void Simulate(float a_Dt)
Called in each tick, a_Dt is the time passed since the last tick, in msec.
void WakeUp(cChunk &a_Chunk, Vector3i a_Position)
T x
Definition: Vector3.h:17
T y
Definition: Vector3.h:17
T z
Definition: Vector3.h:17
Definition: World.h:53
bool DoWithChunk(int a_ChunkX, int a_ChunkZ, cChunkCallback a_Callback)
Calls the callback for the chunk specified, with ChunkMapCS locked.
Definition: World.cpp:1451