Cuberite
A lightweight, fast and extensible game server for Minecraft
MobSpawner.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 "MobSpawner.h"
5 #include "BlockInfo.h"
7 #include "World.h"
8 
9 
10 
11 
12 
13 cMobSpawner::cMobSpawner(cMonster::eFamily a_MonsterFamily, const std::set<eMonsterType>& a_AllowedTypes) :
14  m_MonsterFamily(a_MonsterFamily),
15  m_NewPack(true),
16  m_MobType(mtInvalidType)
17 {
18  for (std::set<eMonsterType>::const_iterator itr = a_AllowedTypes.begin(); itr != a_AllowedTypes.end(); ++itr)
19  {
20  if (cMonster::FamilyFromType(*itr) == a_MonsterFamily)
21  {
22  m_AllowedTypes.insert(*itr);
23  }
24  }
25 }
26 
27 
28 
29 
30 
32 {
33  // Packs of non-water mobs can only be centered on an air block
34  // Packs of water mobs can only be centered on a water block
36  {
37  return IsBlockWater(a_BlockType);
38  }
39  else
40  {
41  return a_BlockType == E_BLOCK_AIR;
42  }
43 }
44 
45 
46 
47 
48 
50 {
51  std::vector<eMonsterType> AllowedMobs;
52 
53  for (eMonsterType MobType : GetAllowedMobTypes(a_Biome))
54  {
55  auto itr = m_AllowedTypes.find(MobType);
56  if (itr != m_AllowedTypes.end())
57  {
58  AllowedMobs.push_back(MobType);
59  }
60  }
61 
62  // Pick a random mob from the options:
63  if (AllowedMobs.empty())
64  {
65  return mtInvalidType;
66  }
67 
68  return AllowedMobs[GetRandomProvider().RandInt(AllowedMobs.size() - 1)];
69 }
70 
71 
72 
73 
74 
75 bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, Vector3i a_RelPos, eMonsterType a_MobType, EMCSBiome a_Biome, bool a_DisableSolidBelowCheck)
76 {
77  if ((a_RelPos.y >= cChunkDef::Height - 1) || (a_RelPos.y <= 0))
78  {
79  return false;
80  }
81 
82  if (cChunkDef::IsValidHeight(a_RelPos.addedY(-1)) && (a_Chunk->GetBlock(a_RelPos.addedY(-1)) == E_BLOCK_BEDROCK))
83  {
84  return false; // Make sure mobs do not spawn on bedrock.
85  }
86 
87  auto & Random = GetRandomProvider();
88  auto TargetBlock = a_Chunk->GetBlock(a_RelPos);
89 
90  auto BlockLight = a_Chunk->GetBlockLight(a_RelPos);
91  auto SkyLight = a_Chunk->GetSkyLight(a_RelPos);
92  auto BlockAbove = a_Chunk->GetBlock(a_RelPos.addedY(1));
93  auto BlockBelow = a_Chunk->GetBlock(a_RelPos.addedY(-1));
94 
95  SkyLight = a_Chunk->GetTimeAlteredLight(SkyLight);
96 
97  switch (a_MobType)
98  {
99  case mtBat:
100  {
101  return
102  (
103  (a_RelPos.y <= 63) &&
104  (BlockLight <= 4) &&
105  (SkyLight <= 4) &&
106  (TargetBlock == E_BLOCK_AIR) &&
107  (!cBlockInfo::IsTransparent(BlockAbove))
108  );
109  }
110 
111  case mtBlaze:
112  {
113  return
114  (
115  (TargetBlock == E_BLOCK_AIR) &&
116  (BlockAbove == E_BLOCK_AIR) &&
117  ((!cBlockInfo::IsTransparent(BlockBelow)) || (a_DisableSolidBelowCheck)) &&
118  (Random.RandBool())
119  );
120  }
121 
122  case mtCaveSpider:
123  {
124  return
125  (
126  (TargetBlock == E_BLOCK_AIR) &&
127  ((!cBlockInfo::IsTransparent(BlockBelow)) || (a_DisableSolidBelowCheck)) &&
128  (SkyLight <= 7) &&
129  (BlockLight <= 7) &&
130  (Random.RandBool())
131  );
132  }
133 
134  case mtChicken:
135  case mtCow:
136  case mtPig:
137  case mtHorse:
138  case mtRabbit:
139  case mtSheep:
140  {
141  return
142  (
143  (TargetBlock == E_BLOCK_AIR) &&
144  (BlockAbove == E_BLOCK_AIR) &&
145  (BlockBelow == E_BLOCK_GRASS) &&
146  (SkyLight >= 9)
147  );
148  }
149 
150  case mtCreeper:
151  case mtSkeleton:
152  case mtZombie:
153  {
154  return
155  (
156  (TargetBlock == E_BLOCK_AIR) &&
157  (BlockAbove == E_BLOCK_AIR) &&
158  ((!cBlockInfo::IsTransparent(BlockBelow)) || (a_DisableSolidBelowCheck)) &&
159  (SkyLight <= 7) &&
160  (BlockLight <= 7) &&
161  (Random.RandBool())
162  );
163  }
164 
165  case mtEnderman:
166  {
167  if (a_RelPos.y < 250)
168  {
169  auto blockTop = a_Chunk->GetBlock(a_RelPos.addedY(2));
170  if (blockTop == E_BLOCK_AIR)
171  {
172  blockTop = a_Chunk->GetBlock(a_RelPos.addedY(3));
173  return
174  (
175  (TargetBlock == E_BLOCK_AIR) &&
176  (BlockAbove == E_BLOCK_AIR) &&
177  (blockTop == E_BLOCK_AIR) &&
178  ((!cBlockInfo::IsTransparent(BlockBelow)) || (a_DisableSolidBelowCheck)) &&
179  (SkyLight <= 7) &&
180  (BlockLight <= 7)
181  );
182  }
183  }
184  break;
185  }
186 
187  case mtGhast:
188  {
189  return
190  (
191  (TargetBlock == E_BLOCK_AIR) &&
192  (BlockAbove == E_BLOCK_AIR) &&
193  (Random.RandBool(0.01))
194  );
195  }
196 
197  case mtGuardian:
198  {
199  return
200  (
201  IsBlockWater(TargetBlock) &&
202  IsBlockWater(BlockBelow) &&
203  (a_RelPos.y >= 45) &&
204  (a_RelPos.y <= 62)
205  );
206  }
207 
208  case mtMagmaCube:
209  case mtSlime:
210  {
211  const int AMOUNT_MOON_PHASES = 8;
212  auto maxLight = Random.RandInt(0, 7);
213  auto moonPhaseNumber = static_cast<int>(std::floor(a_Chunk->GetWorld()->GetWorldAge().count() / 24000)) % AMOUNT_MOON_PHASES;
214  auto moonThreshold = static_cast<float>(std::abs(moonPhaseNumber - (AMOUNT_MOON_PHASES / 2)) / (AMOUNT_MOON_PHASES / 2));
215  return
216  (
217  (TargetBlock == E_BLOCK_AIR) &&
218  (BlockAbove == E_BLOCK_AIR) &&
219  (
220  (!cBlockInfo::IsTransparent(BlockBelow)) ||
221  (a_DisableSolidBelowCheck)) &&
222  (
223  (
224  (a_RelPos.y <= 40) &&
225  a_Chunk->IsSlimeChunk()
226  ) ||
227  (
228  (a_Biome == biSwampland) &&
229  (a_RelPos.y >= 50) &&
230  (a_RelPos.y <= 70) &&
231  (SkyLight <= maxLight) &&
232  (BlockLight <= maxLight) &&
233  (Random.RandBool(moonThreshold)) &&
234  (Random.RandBool(0.5))
235  )
236  )
237  );
238  }
239 
240  case mtMooshroom:
241  {
242  return
243  (
244  (TargetBlock == E_BLOCK_AIR) &&
245  (BlockAbove == E_BLOCK_AIR) &&
246  (BlockBelow == E_BLOCK_MYCELIUM) &&
247  (
248  (a_Biome == biMushroomShore) ||
249  (a_Biome == biMushroomIsland)
250  )
251  );
252  }
253 
254  case mtOcelot:
255  {
256  return (
257  (TargetBlock == E_BLOCK_AIR) &&
258  (BlockAbove == E_BLOCK_AIR) &&
259  (
260  (BlockBelow == E_BLOCK_GRASS) || (BlockBelow == E_BLOCK_LEAVES) || (BlockBelow == E_BLOCK_NEW_LEAVES)
261  ) &&
262  (a_RelPos.y >= 62) &&
263  (Random.RandBool(2.0 / 3.0))
264  );
265  }
266 
267  case mtSpider:
268  {
269  bool CanSpawn = true;
270  bool HasFloor = false;
271  for (int x = 0; x < 2; ++x)
272  {
273  for (int z = 0; z < 2; ++z)
274  {
275  CanSpawn = a_Chunk->UnboundedRelGetBlockType(a_RelPos.addedXZ(x, z), TargetBlock);
276  CanSpawn = CanSpawn && (TargetBlock == E_BLOCK_AIR);
277  if (!CanSpawn)
278  {
279  return false;
280  }
281  HasFloor = (
282  HasFloor ||
283  (
284  a_Chunk->UnboundedRelGetBlockType(a_RelPos + Vector3i(x, -1, z), TargetBlock) &&
285  !cBlockInfo::IsTransparent(TargetBlock)
286  )
287  );
288  }
289  }
290  return CanSpawn && HasFloor && (SkyLight <= 7) && (BlockLight <= 7);
291  }
292 
293  case mtSquid:
294  {
295  return (
296  IsBlockWater(TargetBlock) &&
297  (a_RelPos.y >= 45) &&
298  (a_RelPos.y <= 62)
299  );
300  }
301 
302  case mtWitherSkeleton:
303  {
304  return (
305  (TargetBlock == E_BLOCK_AIR) &&
306  (BlockAbove == E_BLOCK_AIR) &&
307  ((!cBlockInfo::IsTransparent(BlockBelow)) || (a_DisableSolidBelowCheck)) &&
308  (SkyLight <= 7) &&
309  (BlockLight <= 7) &&
310  (Random.RandBool(0.6))
311  );
312  }
313 
314  case mtWolf:
315  {
316  return (
317  (TargetBlock == E_BLOCK_GRASS) &&
318  (BlockAbove == E_BLOCK_AIR) &&
319  (
320  (a_Biome == biColdTaiga) ||
321  (a_Biome == biColdTaigaHills) ||
322  (a_Biome == biColdTaigaM) ||
323  (a_Biome == biForest) ||
324  (a_Biome == biTaiga) ||
325  (a_Biome == biTaigaHills) ||
326  (a_Biome == biTaigaM) ||
327  (a_Biome == biMegaTaiga) ||
328  (a_Biome == biMegaTaigaHills)
329  )
330  );
331  }
332 
333  case mtZombiePigman:
334  {
335  return (
336  (TargetBlock == E_BLOCK_AIR) &&
337  (BlockAbove == E_BLOCK_AIR) &&
338  ((!cBlockInfo::IsTransparent(BlockBelow)) || (a_DisableSolidBelowCheck))
339  );
340  }
341 
342  default:
343  {
344  LOGD("MG TODO: Write spawning rule for mob type %d", a_MobType);
345  return false;
346  }
347  }
348  return false;
349 }
350 
351 
352 
353 
354 
355 std::set<eMonsterType> cMobSpawner::GetAllowedMobTypes(EMCSBiome a_Biome)
356 {
357  std::set<eMonsterType> ListOfSpawnables;
358  // Check biomes first to get a list of animals
359  switch (a_Biome)
360  {
361  // Mooshroom only - no other mobs on mushroom islands
362  case biMushroomIsland:
363  case biMushroomShore:
364  {
365  ListOfSpawnables.insert(mtMooshroom);
366  return ListOfSpawnables;
367  }
368 
369  // Add Squid in ocean and river biomes
370  case biOcean:
371  case biFrozenOcean:
372  case biFrozenRiver:
373  case biRiver:
374  case biDeepOcean:
375  {
376  ListOfSpawnables.insert(mtGuardian);
377  break;
378  }
379 
380  // Add ocelots in jungle biomes
381  case biJungle:
382  case biJungleHills:
383  case biJungleEdge:
384  case biJungleM:
385  case biJungleEdgeM:
386  {
387  ListOfSpawnables.insert(mtOcelot);
388  break;
389  }
390 
391  // Add horses in plains-like biomes
392  case biPlains:
393  case biSunflowerPlains:
394  case biSavanna:
395  case biSavannaPlateau:
396  case biSavannaM:
397  case biSavannaPlateauM:
398  {
399  ListOfSpawnables.insert(mtHorse);
400  break;
401  }
402 
403  // Add wolves in forest biomes
404  case biForest:
405  {
406  ListOfSpawnables.insert(mtWolf);
407  break;
408  }
409 
410  // Add wolves and rabbits in all taiga biomes
411  case biColdTaiga:
412  case biColdTaigaM:
413  case biColdTaigaHills:
414  case biTaiga:
415  case biTaigaHills:
416  case biTaigaM:
417  case biMegaTaiga:
418  case biMegaTaigaHills:
419  {
420  ListOfSpawnables.insert(mtWolf);
421  ListOfSpawnables.insert(mtRabbit);
422  break;
423  }
424 
425  // Add rabbits in desert and flower forest biomes
426  case biDesert:
427  case biDesertHills:
428  case biDesertM:
429  case biFlowerForest:
430  {
431  ListOfSpawnables.insert(mtRabbit);
432  break;
433  }
434 
435  // Nothing special about this biome
436  default:
437  {
438  break;
439  }
440  }
441 
442  // Overworld
443  if (
444  (a_Biome != biDesertHills) &&
445  (a_Biome != biDesert) &&
446  (a_Biome != biDesertM) &&
447  (a_Biome != biBeach) &&
448  (a_Biome != biOcean) &&
449  (a_Biome != biDeepOcean))
450  {
451  ListOfSpawnables.insert(mtSheep);
452  ListOfSpawnables.insert(mtPig);
453  ListOfSpawnables.insert(mtCow);
454  ListOfSpawnables.insert(mtChicken);
455  ListOfSpawnables.insert(mtEnderman);
456  ListOfSpawnables.insert(mtSlime);
457  }
458 
459  ListOfSpawnables.insert(mtBat);
460  ListOfSpawnables.insert(mtSpider);
461  ListOfSpawnables.insert(mtZombie);
462  ListOfSpawnables.insert(mtSkeleton);
463  ListOfSpawnables.insert(mtCreeper);
464  ListOfSpawnables.insert(mtSquid);
465 
466  // Nether
467  ListOfSpawnables.insert(mtBlaze);
468  ListOfSpawnables.insert(mtGhast);
469  ListOfSpawnables.insert(mtMagmaCube);
470  ListOfSpawnables.insert(mtWitherSkeleton);
471  ListOfSpawnables.insert(mtZombiePigman);
472 
473  return ListOfSpawnables;
474 }
475 
476 
477 
478 
479 
480 cMonster * cMobSpawner::TryToSpawnHere(cChunk * a_Chunk, Vector3i a_RelPos, EMCSBiome a_Biome, int & a_MaxPackSize)
481 {
482  // If too close to any player, don't spawn anything
483  auto AbsPos = a_Chunk->RelativeToAbsolute(a_RelPos);
484  static const double RangeLimit = 24;
485  if (
486  a_Chunk->GetWorld()->DoWithNearestPlayer(
487  AbsPos,
488  RangeLimit,
489  [](cPlayer & a_Player)
490  {
491  return true;
492  }
493  )
494  )
495  {
496  return nullptr;
497  }
498 
499  if (m_NewPack)
500  {
501  m_MobType = ChooseMobType(a_Biome);
502  if (m_MobType == mtInvalidType)
503  {
504  return nullptr;
505  }
507  {
508  a_MaxPackSize = 5;
509  }
510  else if (m_MobType == mtWolf)
511  {
512  a_MaxPackSize = 8;
513  }
514  else if (m_MobType == mtGhast)
515  {
516  a_MaxPackSize = 1;
517  }
518  m_NewPack = false;
519  }
520 
521  if ((m_AllowedTypes.find(m_MobType) != m_AllowedTypes.end()) && CanSpawnHere(a_Chunk, a_RelPos, m_MobType, a_Biome))
522  {
524  auto NewMobPtr = NewMob.get();
525  if (NewMob)
526  {
527  m_Spawned.push_back(std::move(NewMob));
528  }
529  return NewMobPtr;
530  }
531 
532  return nullptr;
533 }
534 
535 
536 
537 
538 
540 {
541  m_NewPack = true;
542 }
543 
544 
545 
546 
547 
549 {
550  return !m_AllowedTypes.empty();
551 }
552 
553 
554 
555 
EMCSBiome
Biome IDs The first batch corresponds to the clientside biomes, used by MineCraft.
Definition: BiomeDef.h:18
@ biJungleEdge
Definition: BiomeDef.h:50
@ biDesert
Definition: BiomeDef.h:24
@ biSunflowerPlains
Definition: BiomeDef.h:77
@ biColdTaigaHills
Definition: BiomeDef.h:58
@ biFlowerForest
Definition: BiomeDef.h:80
@ biMushroomShore
Definition: BiomeDef.h:40
@ biSavanna
Definition: BiomeDef.h:62
@ biTaigaHills
Definition: BiomeDef.h:44
@ biJungle
Definition: BiomeDef.h:46
@ biMegaTaiga
Definition: BiomeDef.h:59
@ biJungleHills
Definition: BiomeDef.h:47
@ biOcean
Definition: BiomeDef.h:22
@ biDesertHills
Definition: BiomeDef.h:42
@ biBeach
Definition: BiomeDef.h:41
@ biForest
Definition: BiomeDef.h:26
@ biJungleEdgeM
Definition: BiomeDef.h:85
@ biTaigaM
Definition: BiomeDef.h:81
@ biJungleM
Definition: BiomeDef.h:84
@ biFrozenRiver
Definition: BiomeDef.h:35
@ biRiver
Definition: BiomeDef.h:29
@ biMushroomIsland
Definition: BiomeDef.h:39
@ biDeepOcean
Definition: BiomeDef.h:51
@ biSavannaPlateauM
Definition: BiomeDef.h:94
@ biPlains
Definition: BiomeDef.h:23
@ biSavannaM
Definition: BiomeDef.h:93
@ biFrozenOcean
Definition: BiomeDef.h:34
@ biColdTaiga
Definition: BiomeDef.h:57
@ biMegaTaigaHills
Definition: BiomeDef.h:60
@ biTaiga
Definition: BiomeDef.h:27
@ biDesertM
Definition: BiomeDef.h:78
@ biSavannaPlateau
Definition: BiomeDef.h:63
@ biColdTaigaM
Definition: BiomeDef.h:89
@ biSwampland
Definition: BiomeDef.h:28
bool IsBlockWater(BLOCKTYPE a_BlockType)
Definition: BlockInfo.cpp:10
@ E_BLOCK_NEW_LEAVES
Definition: BlockType.h:180
@ E_BLOCK_AIR
Definition: BlockType.h:10
@ E_BLOCK_LEAVES
Definition: BlockType.h:28
@ E_BLOCK_GRASS
Definition: BlockType.h:12
@ E_BLOCK_BEDROCK
Definition: BlockType.h:17
@ E_BLOCK_MYCELIUM
Definition: BlockType.h:125
unsigned char BLOCKTYPE
The datatype used by blockdata.
Definition: ChunkDef.h:41
MTRand & GetRandomProvider()
Returns the current thread's random number source.
Definition: FastRandom.cpp:12
#define LOGD
Definition: LoggerSimple.h:83
eMonsterType
Identifies individual monster type.
Definition: MonsterTypes.h:11
@ mtSkeleton
Definition: MonsterTypes.h:59
@ mtSheep
Definition: MonsterTypes.h:56
@ mtMagmaCube
Definition: MonsterTypes.h:40
@ mtWolf
Definition: MonsterTypes.h:77
@ mtRabbit
Definition: MonsterTypes.h:53
@ mtZombie
Definition: MonsterTypes.h:79
@ mtOcelot
Definition: MonsterTypes.h:43
@ mtEnderman
Definition: MonsterTypes.h:27
@ mtCaveSpider
Definition: MonsterTypes.h:17
@ mtPig
Definition: MonsterTypes.h:47
@ mtHorse
Definition: MonsterTypes.h:34
@ mtCow
Definition: MonsterTypes.h:20
@ mtMooshroom
Definition: MonsterTypes.h:41
@ mtSquid
Definition: MonsterTypes.h:64
@ mtInvalidType
Definition: MonsterTypes.h:12
@ mtBat
Definition: MonsterTypes.h:14
@ mtChicken
Definition: MonsterTypes.h:18
@ mtBlaze
Definition: MonsterTypes.h:15
@ mtCreeper
Definition: MonsterTypes.h:21
@ mtSpider
Definition: MonsterTypes.h:63
@ mtGhast
Definition: MonsterTypes.h:31
@ mtZombiePigman
Definition: MonsterTypes.h:85
@ mtSlime
Definition: MonsterTypes.h:61
@ mtWitherSkeleton
Definition: MonsterTypes.h:76
@ mtGuardian
Definition: MonsterTypes.h:33
Vector3< int > Vector3i
Definition: Vector3.h:487
static bool IsTransparent(BLOCKTYPE Block)
Is a block transparent? (https://minecraft.wiki/w/Opacity)
Definition: BlockInfo.cpp:961
Definition: Chunk.h:36
NIBBLETYPE GetBlockLight(Vector3i a_RelPos) const
Get the level of artificial light illuminating the block (0 - 15)
Definition: Chunk.h:302
bool IsSlimeChunk() const
Returns true if slimes should spawn in the chunk.
Definition: Chunk.cpp:1988
BLOCKTYPE GetBlock(int a_RelX, int a_RelY, int a_RelZ) const
Definition: Chunk.h:146
Vector3i RelativeToAbsolute(Vector3i a_RelBlockPosition) const
Converts the coord relative to this chunk into an absolute coord.
Definition: Chunk.h:450
NIBBLETYPE GetSkyLight(Vector3i a_RelPos) const
Get the level of sky light illuminating the block (0 - 15) independent of daytime.
Definition: Chunk.h:306
NIBBLETYPE GetTimeAlteredLight(NIBBLETYPE a_Skylight) const
Light alterations based on time.
Definition: Chunk.cpp:1977
cWorld * GetWorld(void) const
Definition: Chunk.h:135
bool UnboundedRelGetBlockType(Vector3i a_RelCoords, BLOCKTYPE &a_BlockType) const
Same as GetBlockType(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_ChunkMap...
Definition: Chunk.cpp:1029
static bool IsValidHeight(Vector3i a_BlockPosition)
Validates a height-coordinate.
Definition: ChunkDef.h:185
static const int Height
Definition: ChunkDef.h:125
Definition: Player.h:29
IntType RandInt(IntType a_Min, IntType a_Max)
Return a random IntType in the range [a_Min, a_Max].
Definition: FastRandom.h:78
static std::unique_ptr< cMonster > NewMonsterFromType(eMonsterType a_MobType)
Creates a new object of the specified mob.
Definition: Monster.cpp:1252
static eFamily FamilyFromType(eMonsterType a_MobType)
Returns the mob family based on the type.
Definition: Monster.cpp:1102
@ mfWater
Definition: Monster.h:33
bool CheckPackCenter(BLOCKTYPE a_BlockType)
Check if specified block can be a Pack center for this spawner.
Definition: MobSpawner.cpp:31
cMobSpawner(cMonster::eFamily MobFamily, const std::set< eMonsterType > &a_AllowedTypes)
Constructor a_MobFamily is the Family of mobs that this spawner will spawn a_AllowedTypes is the set ...
Definition: MobSpawner.cpp:13
static std::set< eMonsterType > GetAllowedMobTypes(EMCSBiome a_Biome)
Returns all mob types that can spawn that biome.
Definition: MobSpawner.cpp:355
eMonsterType m_MobType
Definition: MobSpawner.h:61
eMonsterType ChooseMobType(EMCSBiome a_Biome)
Returns a random type that can spawn in the specified biome.
Definition: MobSpawner.cpp:49
std::vector< std::unique_ptr< cMonster > > m_Spawned
Definition: MobSpawner.h:62
bool m_NewPack
Definition: MobSpawner.h:60
bool CanSpawnAnything(void)
Definition: MobSpawner.cpp:548
void NewPack(void)
Mark the beginning of a new Pack.
Definition: MobSpawner.cpp:539
std::set< eMonsterType > m_AllowedTypes
Definition: MobSpawner.h:59
cMonster * TryToSpawnHere(cChunk *a_Chunk, Vector3i a_RelPos, EMCSBiome a_Biome, int &a_MaxPackSize)
Try to create a monster here If this is the first of a Pack, determine the type of monster a_Biome,...
Definition: MobSpawner.cpp:480
cMonster::eFamily m_MonsterFamily
Definition: MobSpawner.h:58
static bool CanSpawnHere(cChunk *a_Chunk, Vector3i a_RelPos, eMonsterType a_MobType, EMCSBiome a_Biome, bool a_DisableSolidBelowCheck=false)
Returns true if specified type of mob can spawn on specified block.
Definition: MobSpawner.cpp:75
Vector3< T > addedY(T a_AddY) const
Returns a copy of this vector moved by the specified amount on the y axis.
Definition: Vector3.h:314
Vector3< T > addedXZ(T a_AddX, T a_AddZ) const
Returns a copy of this vector moved by the specified amount on the X and Z axes.
Definition: Vector3.h:326
T y
Definition: Vector3.h:17
virtual cTickTimeLong GetWorldAge(void) const override
Definition: World.cpp:491
bool DoWithNearestPlayer(Vector3d a_Pos, double a_RangeLimit, cPlayerListCallback a_Callback, bool a_CheckLineOfSight=true, bool a_IgnoreSpectator=true)
Calls the callback for nearest player for given position, Returns false if player not found,...
Definition: World.cpp:2356