diff options
author | mathiascode <mail@mathias.is> | 2020-04-04 16:00:47 +0200 |
---|---|---|
committer | mathiascode <mail@mathias.is> | 2020-04-04 16:00:47 +0200 |
commit | b8165aebd488b6e4cbfbefb9bb899a811668c8ca (patch) | |
tree | 835857a8820062d3b5aa55878ba2a833afdaad07 | |
parent | Implement wither skeletons (#4563) (diff) | |
download | cuberite-spawning.tar cuberite-spawning.tar.gz cuberite-spawning.tar.bz2 cuberite-spawning.tar.lz cuberite-spawning.tar.xz cuberite-spawning.tar.zst cuberite-spawning.zip |
-rw-r--r-- | src/Chunk.cpp | 7 | ||||
-rw-r--r-- | src/Generating/ComposableGenerator.cpp | 9 | ||||
-rw-r--r-- | src/Generating/FinishGen.cpp | 165 | ||||
-rw-r--r-- | src/Generating/FinishGen.h | 33 | ||||
-rw-r--r-- | src/MobSpawner.cpp | 4 |
5 files changed, 8 insertions, 210 deletions
diff --git a/src/Chunk.cpp b/src/Chunk.cpp index 17e130cdd..f65cafe91 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -599,7 +599,10 @@ void cChunk::SpawnMobs(cMobSpawner & a_MobSpawner) ASSERT(TryY > 0); ASSERT(TryY < cChunkDef::Height - 1); - EMCSBiome Biome = m_ChunkMap->GetBiomeAt(TryX, TryZ); + int WorldX, WorldY, WorldZ; + PositionToWorldPosition(TryX, TryY, TryZ, WorldX, WorldY, WorldZ); + + EMCSBiome Biome = m_ChunkMap->GetBiomeAt(WorldX, WorldZ); // MG TODO : // Moon cycle (for slime) // check player and playerspawn presence < 24 blocks @@ -624,8 +627,6 @@ void cChunk::SpawnMobs(cMobSpawner & a_MobSpawner) { continue; } - int WorldX, WorldY, WorldZ; - PositionToWorldPosition(TryX, TryY, TryZ, WorldX, WorldY, WorldZ); double ActualX = WorldX + 0.5; double ActualZ = WorldZ + 0.5; newMob->SetPosition(ActualX, WorldY, ActualZ); diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp index f87d63493..b861907a2 100644 --- a/src/Generating/ComposableGenerator.cpp +++ b/src/Generating/ComposableGenerator.cpp @@ -225,8 +225,7 @@ void cComposableGenerator::InitializeGeneratorDefaults(cIniFile & a_IniFile, eDi "BottomLava, " "DeadBushes, " "NaturalPatches, " - "PreSimulator, " - "Animals" + "PreSimulator" ); break; } // dimOverworld @@ -387,11 +386,7 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) } const auto & finisher = split[0]; // Finishers, alpha-sorted: - if (NoCaseCompare(finisher, "Animals") == 0) - { - m_FinishGens.push_back(cFinishGenPtr(new cFinishGenPassiveMobs(m_Seed, a_IniFile, m_Dimension))); - } - else if (NoCaseCompare(finisher, "BottomLava") == 0) + if (NoCaseCompare(finisher, "BottomLava") == 0) { int DefaultBottomLavaLevel = (m_Dimension == dimNether) ? 30 : 10; int BottomLavaLevel = a_IniFile.GetValueSetI("Generator", "BottomLavaLevel", DefaultBottomLavaLevel); diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp index 5b328ec49..40999213c 100644 --- a/src/Generating/FinishGen.cpp +++ b/src/Generating/FinishGen.cpp @@ -26,8 +26,6 @@ #define DEF_OVERWORLD_LAVA_SPRINGS "0, 0; 10, 5; 11, 45; 48, 2; 64, 1; 255, 0" #define DEF_END_WATER_SPRINGS "0, 1; 255, 1" #define DEF_END_LAVA_SPRINGS "0, 1; 255, 1" -#define DEF_ANIMAL_SPAWN_PERCENT 10 -#define DEF_NO_ANIMALS 0 @@ -1425,169 +1423,6 @@ bool cFinishGenFluidSprings::TryPlaceSpring(cChunkDesc & a_ChunkDesc, int x, int //////////////////////////////////////////////////////////////////////////////// -// cFinishGenPassiveMobs: - -cFinishGenPassiveMobs::cFinishGenPassiveMobs(int a_Seed, cIniFile & a_IniFile, eDimension a_Dimension) : - m_Noise(a_Seed) -{ - AString SectionName = "Animals"; - int DefaultAnimalSpawnChunkPercentage = DEF_ANIMAL_SPAWN_PERCENT; - switch (a_Dimension) - { - case dimOverworld: - { - DefaultAnimalSpawnChunkPercentage = DEF_ANIMAL_SPAWN_PERCENT; - break; - } - case dimNether: - case dimEnd: // No nether or end animals (currently) - { - DefaultAnimalSpawnChunkPercentage = DEF_NO_ANIMALS; - break; - } - default: - { - ASSERT(!"Unhandled world dimension"); - DefaultAnimalSpawnChunkPercentage = DEF_NO_ANIMALS; - break; - } - } // switch (dimension) - m_AnimalProbability = a_IniFile.GetValueSetI(SectionName, "AnimalSpawnChunkPercentage", DefaultAnimalSpawnChunkPercentage); - if ((m_AnimalProbability < 0) || (m_AnimalProbability > 100)) - { - LOGWARNING("[Animals]: AnimalSpawnChunkPercentage is invalid, using the default of \"%d\".", DefaultAnimalSpawnChunkPercentage); - m_AnimalProbability = DefaultAnimalSpawnChunkPercentage; - } -} - - - - - -void cFinishGenPassiveMobs::GenFinish(cChunkDesc & a_ChunkDesc) -{ - int chunkX = a_ChunkDesc.GetChunkX(); - int chunkZ = a_ChunkDesc.GetChunkZ(); - int ChanceRnd = (m_Noise.IntNoise2DInt(chunkX, chunkZ) / 7) % 100; - if (ChanceRnd > m_AnimalProbability) - { - return; - } - - eMonsterType RandomMob = GetRandomMob(a_ChunkDesc); - if (RandomMob == mtInvalidType) - { - // No mobs here. Don't send an error, because if the biome was a desert it would return mtInvalidType as well. - return; - } - - // Try spawning a pack center 10 times, should get roughly the same probability - for (int Tries = 0; Tries < 10; Tries++) - { - int PackCenterX = (m_Noise.IntNoise2DInt(chunkX + chunkZ, Tries) / 7) % cChunkDef::Width; - int PackCenterZ = (m_Noise.IntNoise2DInt(chunkX, chunkZ + Tries) / 7) % cChunkDef::Width; - if (TrySpawnAnimals(a_ChunkDesc, PackCenterX, a_ChunkDesc.GetHeight(PackCenterX, PackCenterZ), PackCenterZ, RandomMob)) - { - for (int i = 0; i < 3; i++) - { - int OffsetX = (m_Noise.IntNoise2DInt(chunkX + chunkZ + i, Tries) / 7) % cChunkDef::Width; - int OffsetZ = (m_Noise.IntNoise2DInt(chunkX, chunkZ + Tries + i) / 7) % cChunkDef::Width; - TrySpawnAnimals(a_ChunkDesc, OffsetX, a_ChunkDesc.GetHeight(OffsetX, OffsetZ), OffsetZ, RandomMob); - } - return; - - } // if pack center spawn successful - } // for tries -} - - - - - -bool cFinishGenPassiveMobs::TrySpawnAnimals(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelY, int a_RelZ, eMonsterType AnimalToSpawn) -{ - if ((a_RelY >= cChunkDef::Height - 1) || (a_RelY <= 0)) - { - return false; - } - - BLOCKTYPE BlockAtHead = a_ChunkDesc.GetBlockType(a_RelX, a_RelY + 1, a_RelZ); - BLOCKTYPE BlockAtFeet = a_ChunkDesc.GetBlockType(a_RelX, a_RelY, a_RelZ); - BLOCKTYPE BlockUnderFeet = a_ChunkDesc.GetBlockType(a_RelX, a_RelY - 1, a_RelZ); - - // Check block below (opaque, grass, water), and above (air) - if ((AnimalToSpawn == mtSquid) && (BlockAtFeet != E_BLOCK_WATER)) - { - return false; - } - if ( - (AnimalToSpawn != mtSquid) && - (BlockAtHead != E_BLOCK_AIR) && - (BlockAtFeet != E_BLOCK_AIR) && - (!cBlockInfo::IsTransparent(BlockUnderFeet)) - ) - { - return false; - } - if ( - (BlockUnderFeet != E_BLOCK_GRASS) && - ((AnimalToSpawn == mtWolf) || (AnimalToSpawn == mtRabbit) || (AnimalToSpawn == mtCow) || (AnimalToSpawn == mtSheep) || (AnimalToSpawn == mtChicken) || (AnimalToSpawn == mtPig)) - ) - { - return false; - } - if ((AnimalToSpawn == mtMooshroom) && (BlockUnderFeet != E_BLOCK_MYCELIUM)) - { - return false; - } - - double AnimalX = static_cast<double>(a_ChunkDesc.GetChunkX() * cChunkDef::Width + a_RelX + 0.5); - double AnimalY = a_RelY; - double AnimalZ = static_cast<double>(a_ChunkDesc.GetChunkZ() * cChunkDef::Width + a_RelZ + 0.5); - - auto NewMob = cMonster::NewMonsterFromType(AnimalToSpawn); - NewMob->SetHealth(NewMob->GetMaxHealth()); - NewMob->SetPosition(AnimalX, AnimalY, AnimalZ); - FLOGD("Spawning {0} #{1} at {2:.02f}", NewMob->GetClass(), NewMob->GetUniqueID(), NewMob->GetPosition()); - a_ChunkDesc.GetEntities().emplace_back(std::move(NewMob)); - - return true; -} - - - - - -eMonsterType cFinishGenPassiveMobs::GetRandomMob(cChunkDesc & a_ChunkDesc) -{ - 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; - - for (auto MobType : cMobSpawner::GetAllowedMobTypes(a_ChunkDesc.GetBiome(x, z))) - { - if (cMonster::FamilyFromType(MobType) == cMonster::eFamily::mfPassive) - { - ListOfSpawnables.push_back(MobType); - } - } - - if (ListOfSpawnables.empty()) - { - return mtInvalidType; - } - - auto RandMob = (static_cast<size_t>(m_Noise.IntNoise2DInt(chunkX - chunkZ + 2, chunkX + 5) / 7) % ListOfSpawnables.size()); - return ListOfSpawnables[RandMob]; -} - - - - - -//////////////////////////////////////////////////////////////////////////////// // cFinishGenOres: void cFinishGenOres::GenFinish(cChunkDesc & a_ChunkDesc) diff --git a/src/Generating/FinishGen.h b/src/Generating/FinishGen.h index b6edce84f..d551eb0a7 100644 --- a/src/Generating/FinishGen.h +++ b/src/Generating/FinishGen.h @@ -447,39 +447,6 @@ protected: -/** This class populates generated chunks with packs of biome-dependant animals -Animals: cows, sheep, pigs, mooshrooms, squid, horses, wolves, ocelots */ -class cFinishGenPassiveMobs : - public cFinishGen -{ -public: - - cFinishGenPassiveMobs(int a_Seed, cIniFile & a_IniFile, eDimension a_Dimension); - -protected: - - /** The noise used as the source of randomness */ - cNoise m_Noise; - - /** Chance, [0..100], that an animal pack will be generated in a chunk */ - int m_AnimalProbability; - - - // cFinishGen override: - virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; - - /** Returns false if an animal cannot spawn at given coords, else adds it to the chunk's entity list and returns true */ - bool TrySpawnAnimals(cChunkDesc & a_ChunkDesc, int x, int y, int z, eMonsterType AnimalToSpawn); - - /** Picks a random animal from biome-dependant list for a random position in the chunk. - Returns the chosen mob type, or mtInvalid if no mob chosen. */ - eMonsterType GetRandomMob(cChunkDesc & a_ChunkDesc); -} ; - - - - - /** Base class for generators that have an ore list attached to them. Provides the storage and parsing for the ore list, as well as the generic plumbing for generating individual ores. Descendants should override GenerateOre() to provide the specific ore generation technique. diff --git a/src/MobSpawner.cpp b/src/MobSpawner.cpp index 4d18b7358..76b76839e 100644 --- a/src/MobSpawner.cpp +++ b/src/MobSpawner.cpp @@ -152,8 +152,8 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, Vector3i a_RelPos, eMonsterType case mtSheep: { return ( - (targetBlock == E_BLOCK_AIR) && - (blockAbove == E_BLOCK_AIR) && + (!cBlockInfo::IsTransparent(targetBlock)) && + (!cBlockInfo::IsTransparent(blockAbove)) && (blockBelow == E_BLOCK_GRASS) && (skyLight >= 9) ); |