summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBond-009 <bond.009@outlook.com>2018-04-11 13:17:30 +0200
committerAlexander Harkness <me@bearbin.net>2018-04-11 13:17:30 +0200
commit98d807187bbaec4cd65dbe7c1ecac0435efb6df0 (patch)
treed917cf6bc68e013ff1229303d3668c2947b2682b
parentUpdate m_LastSentPosition in TeleportToCoords and DoMoveToWorld. (#4211) (diff)
downloadcuberite-98d807187bbaec4cd65dbe7c1ecac0435efb6df0.tar
cuberite-98d807187bbaec4cd65dbe7c1ecac0435efb6df0.tar.gz
cuberite-98d807187bbaec4cd65dbe7c1ecac0435efb6df0.tar.bz2
cuberite-98d807187bbaec4cd65dbe7c1ecac0435efb6df0.tar.lz
cuberite-98d807187bbaec4cd65dbe7c1ecac0435efb6df0.tar.xz
cuberite-98d807187bbaec4cd65dbe7c1ecac0435efb6df0.tar.zst
cuberite-98d807187bbaec4cd65dbe7c1ecac0435efb6df0.zip
-rw-r--r--src/Generating/FinishGen.cpp87
-rw-r--r--src/MobSpawner.cpp211
-rw-r--r--src/MobSpawner.h6
-rw-r--r--src/World.cpp2
4 files changed, 159 insertions, 147 deletions
diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp
index a79973a9d..8c54be0d0 100644
--- a/src/Generating/FinishGen.cpp
+++ b/src/Generating/FinishGen.cpp
@@ -14,6 +14,7 @@
#include "../Simulator/FireSimulator.h"
#include "../World.h"
#include "../IniFile.h"
+#include "../MobSpawner.h"
@@ -1504,101 +1505,27 @@ bool cFinishGenPassiveMobs::TrySpawnAnimals(cChunkDesc & a_ChunkDesc, int a_RelX
eMonsterType cFinishGenPassiveMobs::GetRandomMob(cChunkDesc & a_ChunkDesc)
{
-
- std::set<eMonsterType> ListOfSpawnables;
+ std::vector<eMonsterType> ListOfSpawnables;
int chunkX = a_ChunkDesc.GetChunkX();
int chunkZ = a_ChunkDesc.GetChunkZ();
int x = (m_Noise.IntNoise2DInt(chunkX, chunkZ + 10) / 7) % cChunkDef::Width;
int z = (m_Noise.IntNoise2DInt(chunkX + chunkZ, chunkZ) / 7) % cChunkDef::Width;
- // Check biomes first to get a list of animals
- switch (a_ChunkDesc.GetBiome(x, z))
+ for (auto MobType : cMobSpawner::GetAllowedMobTypes(a_ChunkDesc.GetBiome(x, z)))
{
- // No animals in deserts or non-overworld dimensions
- case biNether:
- case biEnd:
- case biDesertHills:
- case biDesert:
- case biDesertM:
- {
- return mtInvalidType;
- }
-
- // Mooshroom only - no other mobs on mushroom islands
- case biMushroomIsland:
- case biMushroomShore:
- {
- return mtMooshroom;
- }
-
- // Add squid in ocean biomes
- case biOcean:
- case biFrozenOcean:
- case biFrozenRiver:
- case biRiver:
- case biDeepOcean:
- {
- ListOfSpawnables.insert(mtSquid);
- break;
- }
-
- // Add ocelots in jungle biomes
- case biJungle:
- case biJungleHills:
- case biJungleEdge:
- case biJungleM:
- case biJungleEdgeM:
- {
- ListOfSpawnables.insert(mtOcelot);
- break;
- }
-
- // Add horses in plains-like biomes
- case biPlains:
- case biSunflowerPlains:
- case biSavanna:
- case biSavannaPlateau:
- case biSavannaM:
- case biSavannaPlateauM:
+ if (cMonster::FamilyFromType(MobType) == cMonster::eFamily::mfPassive)
{
- ListOfSpawnables.insert(mtHorse);
- break;
- }
-
- // Add wolves in taiga biomes
- case biTaiga:
- case biMegaTaiga:
- case biColdTaiga:
- case biColdTaigaM:
- {
- ListOfSpawnables.insert(mtWolf);
- break;
- }
- // Nothing special about this biome
- default:
- {
- break;
+ ListOfSpawnables.push_back(MobType);
}
}
- ListOfSpawnables.insert(mtChicken);
- ListOfSpawnables.insert(mtCow);
- ListOfSpawnables.insert(mtPig);
- ListOfSpawnables.insert(mtSheep);
if (ListOfSpawnables.empty())
{
return mtInvalidType;
}
- auto MobIter = ListOfSpawnables.begin();
- using diff_type =
- std::iterator_traits<decltype(MobIter)>::difference_type;
- diff_type RandMob = static_cast<diff_type>
- (static_cast<size_t>(m_Noise.IntNoise2DInt(chunkX - chunkZ + 2, chunkX + 5) / 7)
- % ListOfSpawnables.size());
- std::advance(MobIter, RandMob);
-
- return *MobIter;
+ auto RandMob = (static_cast<size_t>(m_Noise.IntNoise2DInt(chunkX - chunkZ + 2, chunkX + 5) / 7) % ListOfSpawnables.size());
+ return ListOfSpawnables[RandMob];
}
diff --git a/src/MobSpawner.cpp b/src/MobSpawner.cpp
index eb5684202..f04cfa178 100644
--- a/src/MobSpawner.cpp
+++ b/src/MobSpawner.cpp
@@ -45,75 +45,26 @@ bool cMobSpawner::CheckPackCenter(BLOCKTYPE a_BlockType)
-void cMobSpawner::addIfAllowed(eMonsterType toAdd, std::vector<eMonsterType> & toAddIn)
-{
- std::set<eMonsterType>::iterator itr = m_AllowedTypes.find(toAdd);
- if (itr != m_AllowedTypes.end())
- {
- toAddIn.push_back(toAdd);
- }
-}
-
-
-
-
-
eMonsterType cMobSpawner::ChooseMobType(EMCSBiome a_Biome)
{
- std::vector<eMonsterType> allowedMobs;
+ std::vector<eMonsterType> AllowedMobs;
- if ((a_Biome == biMushroomIsland) || (a_Biome == biMushroomShore))
- {
- addIfAllowed(mtMooshroom, allowedMobs);
- }
- else if (a_Biome == biNether)
- {
- addIfAllowed(mtGhast, allowedMobs);
- addIfAllowed(mtZombiePigman, allowedMobs);
- addIfAllowed(mtMagmaCube, allowedMobs);
- }
- else if (a_Biome == biEnd)
- {
- addIfAllowed(mtEnderman, allowedMobs);
- }
- else
+ for (eMonsterType MobType : GetAllowedMobTypes(a_Biome))
{
- addIfAllowed(mtBat, allowedMobs);
- addIfAllowed(mtSpider, allowedMobs);
- addIfAllowed(mtZombie, allowedMobs);
- addIfAllowed(mtSkeleton, allowedMobs);
- addIfAllowed(mtCreeper, allowedMobs);
- addIfAllowed(mtSquid, allowedMobs);
- addIfAllowed(mtGuardian, allowedMobs);
-
- if ((a_Biome != biDesert) && (a_Biome != biBeach) && (a_Biome != biOcean))
+ auto itr = m_AllowedTypes.find(MobType);
+ if (itr != m_AllowedTypes.end())
{
- addIfAllowed(mtSheep, allowedMobs);
- addIfAllowed(mtPig, allowedMobs);
- addIfAllowed(mtCow, allowedMobs);
- addIfAllowed(mtChicken, allowedMobs);
- addIfAllowed(mtEnderman, allowedMobs);
- addIfAllowed(mtRabbit, allowedMobs);
- addIfAllowed(mtSlime, allowedMobs); // MG TODO : much more complicated rule
-
- if ((a_Biome == biForest) || (a_Biome == biForestHills) || (a_Biome == biTaiga) || (a_Biome == biTaigaHills))
- {
- addIfAllowed(mtWolf, allowedMobs);
- }
- else if ((a_Biome == biJungle) || (a_Biome == biJungleHills))
- {
- addIfAllowed(mtOcelot, allowedMobs);
- }
+ AllowedMobs.push_back(MobType);
}
}
// Pick a random mob from the options:
- size_t allowedMobsSize = allowedMobs.size();
- if (allowedMobsSize > 0)
+ if (AllowedMobs.empty())
{
- return allowedMobs[GetRandomProvider().RandInt(allowedMobsSize - 1)];
+ return mtInvalidType;
}
- return mtInvalidType;
+
+ return AllowedMobs[GetRandomProvider().RandInt(AllowedMobs.size() - 1)];
}
@@ -157,7 +108,7 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R
{
case mtGuardian:
{
- return IsBlockWater(TargetBlock) && (a_RelY >= 45) && (a_RelY <= 62);
+ return IsBlockWater(TargetBlock) && IsBlockWater(BlockBelow) && (a_RelY >= 45) && (a_RelY <= 62);
}
case mtSquid:
@@ -301,12 +252,12 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R
(TargetBlock == E_BLOCK_GRASS) &&
(BlockAbove == E_BLOCK_AIR) &&
(
- (a_Biome == biTaiga) ||
- (a_Biome == biTaigaHills) ||
- (a_Biome == biForest) ||
- (a_Biome == biForestHills) ||
(a_Biome == biColdTaiga) ||
(a_Biome == biColdTaigaHills) ||
+ (a_Biome == biColdTaigaM) ||
+ (a_Biome == biForest) ||
+ (a_Biome == biTaiga) ||
+ (a_Biome == biTaigaHills) ||
(a_Biome == biTaigaM) ||
(a_Biome == biMegaTaiga) ||
(a_Biome == biMegaTaigaHills)
@@ -340,6 +291,140 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R
+std::set<eMonsterType> cMobSpawner::GetAllowedMobTypes(EMCSBiome a_Biome)
+{
+ std::set<eMonsterType> ListOfSpawnables;
+ // Check biomes first to get a list of animals
+ switch (a_Biome)
+ {
+ // Nether mobs and endermen only - no other mobs in the nether
+ case biNether:
+ {
+ ListOfSpawnables.insert(mtGhast);
+ ListOfSpawnables.insert(mtMagmaCube);
+ ListOfSpawnables.insert(mtZombiePigman);
+ ListOfSpawnables.insert(mtEnderman);
+ return ListOfSpawnables;
+ }
+
+ // Endermen only - no other mobs in the end
+ case biEnd:
+ {
+ ListOfSpawnables.insert(mtEnderman);
+ return ListOfSpawnables;
+ }
+
+ // Mooshroom only - no other mobs on mushroom islands
+ case biMushroomIsland:
+ case biMushroomShore:
+ {
+ ListOfSpawnables.insert(mtMooshroom);
+ return ListOfSpawnables;
+ }
+
+ // Add Squid in ocean and river biomes
+ case biOcean:
+ case biFrozenOcean:
+ case biFrozenRiver:
+ case biRiver:
+ case biDeepOcean:
+ {
+ ListOfSpawnables.insert(mtGuardian);
+ break;
+ }
+
+ // Add ocelots in jungle biomes
+ case biJungle:
+ case biJungleHills:
+ case biJungleEdge:
+ case biJungleM:
+ case biJungleEdgeM:
+ {
+ ListOfSpawnables.insert(mtOcelot);
+ break;
+ }
+
+ // Add horses in plains-like biomes
+ case biPlains:
+ case biSunflowerPlains:
+ case biSavanna:
+ case biSavannaPlateau:
+ case biSavannaM:
+ case biSavannaPlateauM:
+ {
+ ListOfSpawnables.insert(mtHorse);
+ break;
+ }
+
+ // Add wolves in forest biomes
+ case biForest:
+ {
+ ListOfSpawnables.insert(mtWolf);
+ break;
+ }
+
+ // Add wolves and rabbits in all taiga biomes
+ case biColdTaiga:
+ case biColdTaigaM:
+ case biColdTaigaHills:
+ case biTaiga:
+ case biTaigaHills:
+ case biTaigaM:
+ case biMegaTaiga:
+ case biMegaTaigaHills:
+ {
+ ListOfSpawnables.insert(mtWolf);
+ ListOfSpawnables.insert(mtRabbit);
+ break;
+ }
+
+ // Add rabbits in desert and flower forest biomes
+ case biDesert:
+ case biDesertHills:
+ case biDesertM:
+ case biFlowerForest:
+ {
+ ListOfSpawnables.insert(mtRabbit);
+ break;
+ }
+
+ // Nothing special about this biome
+ default:
+ {
+ break;
+ }
+ }
+
+ if (
+ (a_Biome != biDesertHills) &&
+ (a_Biome != biDesert) &&
+ (a_Biome != biDesertM) &&
+ (a_Biome != biBeach) &&
+ (a_Biome != biOcean) &&
+ (a_Biome != biDeepOcean))
+ {
+ ListOfSpawnables.insert(mtSheep);
+ ListOfSpawnables.insert(mtPig);
+ ListOfSpawnables.insert(mtCow);
+ ListOfSpawnables.insert(mtChicken);
+ ListOfSpawnables.insert(mtEnderman);
+ ListOfSpawnables.insert(mtSlime);
+ }
+
+ ListOfSpawnables.insert(mtBat);
+ ListOfSpawnables.insert(mtSpider);
+ ListOfSpawnables.insert(mtZombie);
+ ListOfSpawnables.insert(mtSkeleton);
+ ListOfSpawnables.insert(mtCreeper);
+ ListOfSpawnables.insert(mtSquid);
+
+ return ListOfSpawnables;
+}
+
+
+
+
+
cMonster * cMobSpawner::TryToSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, EMCSBiome a_Biome, int & a_MaxPackSize)
{
if (m_NewPack)
diff --git a/src/MobSpawner.h b/src/MobSpawner.h
index c396637d5..695467692 100644
--- a/src/MobSpawner.h
+++ b/src/MobSpawner.h
@@ -45,14 +45,14 @@ public :
/** Returns true if specified type of mob can spawn on specified block */
static bool CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, eMonsterType a_MobType, EMCSBiome a_Biome);
+ /** Returns all mob types that can spawn that biome */
+ static std::set<eMonsterType> GetAllowedMobTypes(EMCSBiome a_Biome);
+
protected :
/** Returns a random type that can spawn in the specified biome.
Returns mtInvalidType if none is possible. */
eMonsterType ChooseMobType(EMCSBiome a_Biome);
- /** Adds toAdd into toAddIn, if toAdd is in m_AllowedTypes */
- void addIfAllowed(eMonsterType toAdd, std::vector<eMonsterType> & toAddIn);
-
cMonster::eFamily m_MonsterFamily;
std::set<eMonsterType> m_AllowedTypes;
bool m_NewPack;
diff --git a/src/World.cpp b/src/World.cpp
index 1b7bc8643..adbac33bf 100644
--- a/src/World.cpp
+++ b/src/World.cpp
@@ -1199,7 +1199,7 @@ void cWorld::TickMobs(std::chrono::milliseconds a_Dt)
else
{
auto & Wolf = static_cast<cWolf &>(Monster);
- if (Wolf.IsAngry())
+ if (!Wolf.IsAngry() && !Wolf.IsTame())
{
Monster.Destroy(true);
}