summaryrefslogtreecommitdiffstats
path: root/src/MobSpawner.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/MobSpawner.cpp')
-rw-r--r--src/MobSpawner.cpp217
1 files changed, 115 insertions, 102 deletions
diff --git a/src/MobSpawner.cpp b/src/MobSpawner.cpp
index 4d18b7358..b83cd247d 100644
--- a/src/MobSpawner.cpp
+++ b/src/MobSpawner.cpp
@@ -72,7 +72,7 @@ eMonsterType cMobSpawner::ChooseMobType(EMCSBiome a_Biome)
-bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, Vector3i a_RelPos, eMonsterType a_MobType, EMCSBiome a_Biome)
+bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, Vector3i a_RelPos, eMonsterType a_MobType, EMCSBiome a_Biome, bool a_DisableSolidBelowCheck)
{
if (a_Chunk == nullptr)
{
@@ -88,59 +88,50 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, Vector3i a_RelPos, eMonsterType
return false; // Make sure mobs do not spawn on bedrock.
}
- auto & random = GetRandomProvider();
- auto targetBlock = a_Chunk->GetBlock(a_RelPos);
+ auto & Random = GetRandomProvider();
+ auto TargetBlock = a_Chunk->GetBlock(a_RelPos);
- // If too close to any player, don't spawn anything
- auto absPos = a_Chunk->RelativeToAbsolute(a_RelPos);
- static const double rangeLimit = 24;
- if (a_Chunk->GetWorld()->DoWithNearestPlayer(absPos, rangeLimit, [](cPlayer & a_Player) -> bool
- {
- return true;
- })
- )
- {
- return false;
- }
-
- auto blockLight = a_Chunk->GetBlockLight(a_RelPos);
- auto skyLight = a_Chunk->GetSkyLight(a_RelPos);
- auto blockAbove = a_Chunk->GetBlock(a_RelPos.addedY(1));
- auto blockBelow = a_Chunk->GetBlock(a_RelPos.addedY(-1));
+ auto BlockLight = a_Chunk->GetBlockLight(a_RelPos);
+ auto SkyLight = a_Chunk->GetSkyLight(a_RelPos);
+ auto BlockAbove = a_Chunk->GetBlock(a_RelPos.addedY(1));
+ auto BlockBelow = a_Chunk->GetBlock(a_RelPos.addedY(-1));
- skyLight = a_Chunk->GetTimeAlteredLight(skyLight);
+ SkyLight = a_Chunk->GetTimeAlteredLight(SkyLight);
switch (a_MobType)
{
case mtBat:
{
- return (
+ return
+ (
(a_RelPos.y <= 63) &&
- (blockLight <= 4) &&
- (skyLight <= 4) &&
- (targetBlock == E_BLOCK_AIR) &&
- (!cBlockInfo::IsTransparent(blockAbove))
+ (BlockLight <= 4) &&
+ (SkyLight <= 4) &&
+ (TargetBlock == E_BLOCK_AIR) &&
+ (!cBlockInfo::IsTransparent(BlockAbove))
);
}
case mtBlaze:
{
- return (
- (targetBlock == E_BLOCK_AIR) &&
- (blockAbove == E_BLOCK_AIR) &&
- (!cBlockInfo::IsTransparent(blockBelow)) &&
- (random.RandBool())
+ return
+ (
+ (TargetBlock == E_BLOCK_AIR) &&
+ (BlockAbove == E_BLOCK_AIR) &&
+ ((!cBlockInfo::IsTransparent(BlockBelow)) || (a_DisableSolidBelowCheck)) &&
+ (Random.RandBool())
);
}
case mtCaveSpider:
{
- return (
- (targetBlock == E_BLOCK_AIR) &&
- (!cBlockInfo::IsTransparent(blockBelow)) &&
- (skyLight <= 7) &&
- (blockLight <= 7) &&
- (random.RandBool())
+ return
+ (
+ (TargetBlock == E_BLOCK_AIR) &&
+ ((!cBlockInfo::IsTransparent(BlockBelow)) || (a_DisableSolidBelowCheck)) &&
+ (SkyLight <= 7) &&
+ (BlockLight <= 7) &&
+ (Random.RandBool())
);
}
@@ -151,11 +142,12 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, Vector3i a_RelPos, eMonsterType
case mtRabbit:
case mtSheep:
{
- return (
- (targetBlock == E_BLOCK_AIR) &&
- (blockAbove == E_BLOCK_AIR) &&
- (blockBelow == E_BLOCK_GRASS) &&
- (skyLight >= 9)
+ return
+ (
+ (TargetBlock == E_BLOCK_AIR) &&
+ (BlockAbove == E_BLOCK_AIR) &&
+ (BlockBelow == E_BLOCK_GRASS) &&
+ (SkyLight >= 9)
);
}
@@ -163,13 +155,14 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, Vector3i a_RelPos, eMonsterType
case mtSkeleton:
case mtZombie:
{
- return (
- (targetBlock == E_BLOCK_AIR) &&
- (blockAbove == E_BLOCK_AIR) &&
- (!cBlockInfo::IsTransparent(blockBelow)) &&
- (skyLight <= 7) &&
- (blockLight <= 7) &&
- (random.RandBool())
+ return
+ (
+ (TargetBlock == E_BLOCK_AIR) &&
+ (BlockAbove == E_BLOCK_AIR) &&
+ ((!cBlockInfo::IsTransparent(BlockBelow)) || (a_DisableSolidBelowCheck)) &&
+ (SkyLight <= 7) &&
+ (BlockLight <= 7) &&
+ (Random.RandBool())
);
}
@@ -181,13 +174,14 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, Vector3i a_RelPos, eMonsterType
if (blockTop == E_BLOCK_AIR)
{
blockTop = a_Chunk->GetBlock(a_RelPos.addedY(3));
- return (
- (targetBlock == E_BLOCK_AIR) &&
- (blockAbove == E_BLOCK_AIR) &&
+ return
+ (
+ (TargetBlock == E_BLOCK_AIR) &&
+ (BlockAbove == E_BLOCK_AIR) &&
(blockTop == E_BLOCK_AIR) &&
- (!cBlockInfo::IsTransparent(blockBelow)) &&
- (skyLight <= 7) &&
- (blockLight <= 7)
+ ((!cBlockInfo::IsTransparent(BlockBelow)) || (a_DisableSolidBelowCheck)) &&
+ (SkyLight <= 7) &&
+ (BlockLight <= 7)
);
}
}
@@ -196,18 +190,20 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, Vector3i a_RelPos, eMonsterType
case mtGhast:
{
- return (
- (targetBlock == E_BLOCK_AIR) &&
- (blockAbove == E_BLOCK_AIR) &&
- (random.RandBool(0.01))
+ return
+ (
+ (TargetBlock == E_BLOCK_AIR) &&
+ (BlockAbove == E_BLOCK_AIR) &&
+ (Random.RandBool(0.01))
);
}
case mtGuardian:
{
- return (
- IsBlockWater(targetBlock) &&
- IsBlockWater(blockBelow) &&
+ return
+ (
+ IsBlockWater(TargetBlock) &&
+ IsBlockWater(BlockBelow) &&
(a_RelPos.y >= 45) &&
(a_RelPos.y <= 62)
);
@@ -216,22 +212,22 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, Vector3i a_RelPos, eMonsterType
case mtMagmaCube:
case mtSlime:
{
- return (
- (targetBlock == E_BLOCK_AIR) &&
- (blockAbove == E_BLOCK_AIR) &&
- (!cBlockInfo::IsTransparent(blockBelow)) &&
- (
- (a_RelPos.y <= 40) || (a_Biome == biSwampland)
- )
+ return
+ (
+ (TargetBlock == E_BLOCK_AIR) &&
+ (BlockAbove == E_BLOCK_AIR) &&
+ ((!cBlockInfo::IsTransparent(BlockBelow)) || (a_DisableSolidBelowCheck)) &&
+ ((a_RelPos.y <= 40) || (a_Biome == biSwampland))
);
}
case mtMooshroom:
{
- return (
- (targetBlock == E_BLOCK_AIR) &&
- (blockAbove == E_BLOCK_AIR) &&
- (blockBelow == E_BLOCK_MYCELIUM) &&
+ return
+ (
+ (TargetBlock == E_BLOCK_AIR) &&
+ (BlockAbove == E_BLOCK_AIR) &&
+ (BlockBelow == E_BLOCK_MYCELIUM) &&
(
(a_Biome == biMushroomShore) ||
(a_Biome == biMushroomIsland)
@@ -242,46 +238,46 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, Vector3i a_RelPos, eMonsterType
case mtOcelot:
{
return (
- (targetBlock == E_BLOCK_AIR) &&
- (blockAbove == E_BLOCK_AIR) &&
+ (TargetBlock == E_BLOCK_AIR) &&
+ (BlockAbove == E_BLOCK_AIR) &&
(
- (blockBelow == E_BLOCK_GRASS) || (blockBelow == E_BLOCK_LEAVES) || (blockBelow == E_BLOCK_NEW_LEAVES)
+ (BlockBelow == E_BLOCK_GRASS) || (BlockBelow == E_BLOCK_LEAVES) || (BlockBelow == E_BLOCK_NEW_LEAVES)
) &&
(a_RelPos.y >= 62) &&
- (random.RandBool(2.0 / 3.0))
+ (Random.RandBool(2.0 / 3.0))
);
}
case mtSpider:
{
- bool canSpawn = true;
- bool hasFloor = false;
+ bool CanSpawn = true;
+ bool HasFloor = false;
for (int x = 0; x < 2; ++x)
{
for (int z = 0; z < 2; ++z)
{
- canSpawn = a_Chunk->UnboundedRelGetBlockType(a_RelPos.addedXZ(x, z), targetBlock);
- canSpawn = canSpawn && (targetBlock == E_BLOCK_AIR);
- if (!canSpawn)
+ CanSpawn = a_Chunk->UnboundedRelGetBlockType(a_RelPos.addedXZ(x, z), TargetBlock);
+ CanSpawn = CanSpawn && (TargetBlock == E_BLOCK_AIR);
+ if (!CanSpawn)
{
return false;
}
- hasFloor = (
- hasFloor ||
+ HasFloor = (
+ HasFloor ||
(
- a_Chunk->UnboundedRelGetBlockType(a_RelPos + Vector3i(x, -1, z), targetBlock) &&
- !cBlockInfo::IsTransparent(targetBlock)
+ a_Chunk->UnboundedRelGetBlockType(a_RelPos + Vector3i(x, -1, z), TargetBlock) &&
+ !cBlockInfo::IsTransparent(TargetBlock)
)
);
}
}
- return canSpawn && hasFloor && (skyLight <= 7) && (blockLight <= 7);
+ return CanSpawn && HasFloor && (SkyLight <= 7) && (BlockLight <= 7);
}
case mtSquid:
{
return (
- IsBlockWater(targetBlock) &&
+ IsBlockWater(TargetBlock) &&
(a_RelPos.y >= 45) &&
(a_RelPos.y <= 62)
);
@@ -290,20 +286,20 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, Vector3i a_RelPos, eMonsterType
case mtWitherSkeleton:
{
return (
- (targetBlock == E_BLOCK_AIR) &&
- (blockAbove == E_BLOCK_AIR) &&
- (!cBlockInfo::IsTransparent(blockBelow)) &&
- (skyLight <= 7) &&
- (blockLight <= 7) &&
- (random.RandBool(0.6))
+ (TargetBlock == E_BLOCK_AIR) &&
+ (BlockAbove == E_BLOCK_AIR) &&
+ ((!cBlockInfo::IsTransparent(BlockBelow)) || (a_DisableSolidBelowCheck)) &&
+ (SkyLight <= 7) &&
+ (BlockLight <= 7) &&
+ (Random.RandBool(0.6))
);
}
case mtWolf:
{
return (
- (targetBlock == E_BLOCK_GRASS) &&
- (blockAbove == E_BLOCK_AIR) &&
+ (TargetBlock == E_BLOCK_GRASS) &&
+ (BlockAbove == E_BLOCK_AIR) &&
(
(a_Biome == biColdTaiga) ||
(a_Biome == biColdTaigaHills) ||
@@ -321,9 +317,9 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, Vector3i a_RelPos, eMonsterType
case mtZombiePigman:
{
return (
- (targetBlock == E_BLOCK_AIR) &&
- (blockAbove == E_BLOCK_AIR) &&
- (!cBlockInfo::IsTransparent(blockBelow))
+ (TargetBlock == E_BLOCK_AIR) &&
+ (BlockAbove == E_BLOCK_AIR) &&
+ ((!cBlockInfo::IsTransparent(BlockBelow)) || (a_DisableSolidBelowCheck))
);
}
@@ -467,6 +463,23 @@ std::set<eMonsterType> cMobSpawner::GetAllowedMobTypes(EMCSBiome a_Biome)
cMonster * cMobSpawner::TryToSpawnHere(cChunk * a_Chunk, Vector3i a_RelPos, EMCSBiome a_Biome, int & a_MaxPackSize)
{
+ // If too close to any player, don't spawn anything
+ auto AbsPos = a_Chunk->RelativeToAbsolute(a_RelPos);
+ static const double RangeLimit = 24;
+ if (
+ a_Chunk->GetWorld()->DoWithNearestPlayer(
+ AbsPos,
+ RangeLimit,
+ [](cPlayer & a_Player)
+ {
+ return true;
+ }
+ )
+ )
+ {
+ return nullptr;
+ }
+
if (m_NewPack)
{
m_MobType = ChooseMobType(a_Biome);
@@ -494,11 +507,11 @@ cMonster * cMobSpawner::TryToSpawnHere(cChunk * a_Chunk, Vector3i a_RelPos, EMCS
if ((m_AllowedTypes.find(m_MobType) != m_AllowedTypes.end()) && CanSpawnHere(a_Chunk, a_RelPos, m_MobType, a_Biome))
{
- auto newMob = cMonster::NewMonsterFromType(m_MobType);
- auto NewMobPtr = newMob.get();
- if (newMob)
+ auto NewMob = cMonster::NewMonsterFromType(m_MobType);
+ auto NewMobPtr = NewMob.get();
+ if (NewMob)
{
- m_Spawned.push_back(std::move(newMob));
+ m_Spawned.push_back(std::move(NewMob));
}
return NewMobPtr;
}