-
-
Notifications
You must be signed in to change notification settings - Fork 633
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Animal terrain finisher #1642
Animal terrain finisher #1642
Changes from all commits
9831220
2d93274
978c996
585662e
8d7c2d4
6803df1
2ea8a36
7f8f2f1
d348433
8c3b9ae
83d4bec
a36e766
b7c4ef0
99a5b38
53a3359
538991c
78f0aeb
bd8c185
c655d97
750b4a3
a8bbd5e
b25fcb0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,6 +18,7 @@ mgueydan | |
MikeHunsinger | ||
mtilden | ||
nesco | ||
p-mcgowan | ||
rs2k | ||
SamJBarney | ||
Sofapriester | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,6 +26,8 @@ | |
#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 | ||
|
||
|
||
|
||
|
@@ -958,3 +960,237 @@ 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); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You say you're using the default, but I see no code doing that. |
||
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) | ||
{ | ||
LOGWARNING("Attempted to spawn invalid mob type."); | ||
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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Still not good here. The |
||
} | ||
|
||
|
||
|
||
|
||
|
||
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); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will fail if the spawning is requested at a_RelY = 0 or a_RelY = 255 (it may happen for some custom terrain generator settings). |
||
|
||
// 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)) | ||
) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When breaking conditions on separate lines, put the first condition on a separate line as well: if (
(AnimalToSpawn != mtSquid) &&
(BlockAtHead != E_BLOCK_AIR) &&
(BlockAtFeet != E_BLOCK_AIR) &&
(!cBlockInfo::IsTransparent(BlockUnderFeet))
) |
||
{ | ||
return false; | ||
} | ||
if ( | ||
(BlockUnderFeet != E_BLOCK_GRASS) && | ||
((AnimalToSpawn == mtSheep) || (AnimalToSpawn == mtChicken) || (AnimalToSpawn == mtPig)) | ||
) | ||
{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Condition formatting - separate first line, closing parenthesis on next line. |
||
return false; | ||
} | ||
if ((AnimalToSpawn == mtMooshroom) && (BlockUnderFeet != E_BLOCK_MYCELIUM)) | ||
{ | ||
return false; | ||
} | ||
|
||
int AnimalX, AnimalY, AnimalZ; | ||
AnimalX = (double)(a_ChunkDesc.GetChunkX()*cChunkDef::Width + a_RelX + 0.5); | ||
AnimalY = a_RelY; | ||
AnimalZ = (double)(a_ChunkDesc.GetChunkZ()*cChunkDef::Width + a_RelZ + 0.5); | ||
|
||
cEntityList ChunkEntities = a_ChunkDesc.GetEntities(); | ||
cMonster * NewMob = cMonster::NewMonsterFromType(AnimalToSpawn); | ||
NewMob->SetPosition(AnimalX, AnimalY, AnimalZ); | ||
ChunkEntities.push_back(NewMob); | ||
LOGD("Spawning %s #%i at {%d, %d, %d}", NewMob->GetClass(), NewMob->GetUniqueID(), AnimalX, AnimalY, AnimalZ); | ||
|
||
return true; | ||
} | ||
|
||
|
||
|
||
|
||
|
||
eMonsterType cFinishGenPassiveMobs::GetRandomMob(cChunkDesc & a_ChunkDesc) | ||
{ | ||
|
||
std::set<eMonsterType> ListOfSpawnables; | ||
std::set<eMonsterType>::iterator MobIter = ListOfSpawnables.begin(); | ||
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)) | ||
{ | ||
// 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(MobIter, mtSquid); | ||
break; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We use braces for the case contents as well. |
||
} | ||
// Add ocelots in jungle biomes | ||
case biJungle: | ||
case biJungleHills: | ||
case biJungleEdge: | ||
case biJungleM: | ||
case biJungleEdgeM: | ||
{ | ||
ListOfSpawnables.insert(MobIter, mtOcelot); | ||
break; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Probably missing a |
||
case biPlains: | ||
case biSunflowerPlains: | ||
case biSavanna: | ||
case biSavannaPlateau: | ||
case biSavannaM: | ||
case biSavannaPlateauM: | ||
{ | ||
ListOfSpawnables.insert(MobIter, mtHorse); | ||
// ListOfSpawnables.insert(mtDonkey); | ||
break; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing |
||
// Add wolves in forest and spruce forests | ||
case biForest: | ||
case biTaiga: | ||
case biMegaTaiga: | ||
case biColdTaiga: | ||
case biColdTaigaM: | ||
{ | ||
ListOfSpawnables.insert(MobIter, mtWolf); | ||
break; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing |
||
// Nothing special about this biome | ||
default: | ||
{ | ||
break; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The default mobs should probably added to all biomes, shouldn't they? Why not take them out of the |
||
} | ||
ListOfSpawnables.insert(MobIter, mtChicken); | ||
ListOfSpawnables.insert(MobIter, mtCow); | ||
ListOfSpawnables.insert(MobIter, mtPig); | ||
ListOfSpawnables.insert(MobIter, mtSheep); | ||
|
||
if (ListOfSpawnables.empty()) | ||
{ | ||
return mtInvalidType; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should not log this situation, it's perfectly normal for an |
||
|
||
int RandMob = (m_Noise.IntNoise2DInt(chunkX - chunkZ + 2, chunkX + 5) / 7) % ListOfSpawnables.size(); | ||
MobIter = ListOfSpawnables.begin(); | ||
for (int i = 0; i < RandMob; i++) | ||
{ | ||
++MobIter; | ||
} | ||
|
||
return *MobIter; | ||
} | ||
|
||
|
||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,6 +18,7 @@ | |
#include "ComposableGenerator.h" | ||
#include "../Noise/Noise.h" | ||
#include "../ProbabDistrib.h" | ||
#include "../Mobs/Monster.h" | ||
|
||
|
||
|
||
|
@@ -311,10 +312,39 @@ class cFinishGenFluidSprings : | |
// cFinishGen override: | ||
virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; | ||
|
||
/// Tries to place a spring at the specified coords, checks neighbors. Returns true if successful | ||
// Tries to place a spring at the specified coords, checks neighbors. Returns true if successful | ||
bool TryPlaceSpring(cChunkDesc & a_ChunkDesc, int x, int y, int z); | ||
} ; | ||
|
||
|
||
|
||
|
||
|
||
/** 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: | ||
|
||
cNoise m_Noise; | ||
int m_AnimalProbability; // Chance, [0..100], that an animal pack will be generated in a chunk | ||
|
||
// cFinishGen override: | ||
virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not a good candidate for doxy-comment, it's just a note about where the original function comes from, it doesn't explain what it does. This comment should use regular C++ comment style ( There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To explain further: These functions should be doxy-commented in the base class, where it should be explained what they're used for and what can be achieved by overriding them. Then, the individual overrides would just repeat the description, going out of date really easily. So instead they just point to the original class. With multi-level and sometimes even multiple inheritance, this helps folks who don't have an IDE capable of searching for the parent. |
||
|
||
// 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); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The comment is wrong, the function doesn't spawn any more animals. |
||
|
||
// Gets a random animal from biome-dependant list | ||
eMonsterType GetRandomMob(cChunkDesc & a_ChunkDesc); | ||
} ; | ||
|
||
|
||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indenting is wrong inside the switch, there's a needless extra level.