diff options
Diffstat (limited to 'source/MobSpawner.cpp')
-rw-r--r-- | source/MobSpawner.cpp | 140 |
1 files changed, 78 insertions, 62 deletions
diff --git a/source/MobSpawner.cpp b/source/MobSpawner.cpp index 1b3796f70..7dff56d61 100644 --- a/source/MobSpawner.cpp +++ b/source/MobSpawner.cpp @@ -124,87 +124,103 @@ cMonster::eType cMobSpawner::ChooseMobType(EMCSBiome a_Biome) -bool cMobSpawner::CanSpawnHere(cMonster::eType a_MobType, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, BLOCKTYPE a_BlockType_below, NIBBLETYPE a_BlockMeta_below, BLOCKTYPE a_BlockType_above, NIBBLETYPE a_BlockMeta_above, EMCSBiome a_Biome, int a_Level) +bool cMobSpawner::CanSpawnHere(const cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, cMonster::eType a_MobType, int a_TimeOfDay, EMCSBiome a_Biome) { - bool toReturn = false; - std::set<cMonster::eType>::iterator itr = m_AllowedTypes.find(a_MobType); - if (itr != m_AllowedTypes.end()) + BLOCKTYPE TargetBlock; + BLOCKTYPE BlockAbove; + BLOCKTYPE BlockBelow; + NIBBLETYPE BlockLight; + NIBBLETYPE SkyLight; + if (m_AllowedTypes.find(a_MobType) != m_AllowedTypes.end() && a_Chunk->UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, TargetBlock)) { - // MG TODO : find a nicer paging - if (a_MobType == cMonster::mtSquid) - { - toReturn = ( - IsBlockLiquid(a_BlockType) && - a_Level >= 45 && - a_Level <= 62 - ); - } - else if (a_MobType == cMonster::mtBat) - { - toReturn = a_Level <= 60; // MG TODO : find a real rule - } - else + + a_Chunk->UnboundedRelGetBlockBlockLight(a_RelX, a_RelY, a_RelZ, BlockLight); + a_Chunk->UnboundedRelGetBlockSkyLight(a_RelX, a_RelY, a_RelZ, SkyLight); + a_Chunk->UnboundedRelGetBlockType(a_RelX, a_RelY + 1, a_RelZ, BlockAbove); + a_Chunk->UnboundedRelGetBlockType(a_RelX, a_RelY - 1, a_RelZ, BlockBelow); + switch(a_MobType) { - if ( - a_BlockType == E_BLOCK_AIR && - a_BlockType_above == E_BLOCK_AIR && - ! (g_BlockTransparent[a_BlockType_below]) - ) + case cMonster::mtSquid: + return IsBlockWater(TargetBlock) && (a_RelY >= 45) && (a_RelY <= 62); + + case cMonster::mtBat: + return (a_RelY <= 63) && (BlockLight <= 4) && (SkyLight <= 4 || a_TimeOfDay > 12500) && (TargetBlock == E_BLOCK_AIR) && (!g_BlockTransparent[BlockAbove]); + + case cMonster::mtChicken: + case cMonster::mtCow: + case cMonster::mtPig: + case cMonster::mtHorse: + case cMonster::mtSheep: { - if (a_MobType == cMonster::mtChicken || a_MobType == cMonster::mtPig || a_MobType == cMonster::mtCow || a_MobType == cMonster::mtSheep) - { - toReturn = ( - a_BlockType_below == E_BLOCK_GRASS /*&& // MG TODO - a_LightLevel >= 9 */ - ); - } - else if (a_MobType == cMonster::mtOcelot) + return (TargetBlock == E_BLOCK_AIR) && (BlockAbove == E_BLOCK_AIR) && (!g_BlockTransparent[BlockBelow]) && + (BlockBelow == E_BLOCK_GRASS) && (SkyLight >= 9) && (a_TimeOfDay <= 12500); + } + + case cMonster::mtOcelot: + { + return (TargetBlock == E_BLOCK_AIR) && (BlockAbove == E_BLOCK_AIR) && + ((BlockBelow == E_BLOCK_GRASS) || (BlockBelow == E_BLOCK_LEAVES)) && (a_RelY >= 62) && (m_Random.NextInt(3,a_Biome) != 0); + } + case cMonster::mtEnderman: + { + if (a_RelY < 250) { - toReturn = ( - a_Level >= 62 && - ( - a_BlockType_below == E_BLOCK_GRASS || - a_BlockType_below == E_BLOCK_LEAVES - ) && - m_Random.NextInt(3,a_Biome) != 0 - ); + BLOCKTYPE BlockTop; + a_Chunk->UnboundedRelGetBlockType(a_RelX, a_RelY + 2, a_RelZ, BlockTop); + return (TargetBlock == E_BLOCK_AIR) && (BlockAbove == E_BLOCK_AIR) && (BlockTop == E_BLOCK_AIR) && (!g_BlockTransparent[BlockBelow]) && + ((SkyLight <= 7) || a_TimeOfDay > 12500 ) && (BlockLight <= 7) ; } - else if (a_MobType == cMonster::mtCreeper || a_MobType == cMonster::mtSkeleton || a_MobType == cMonster::mtZombie || a_MobType == cMonster::mtSpider || a_MobType == cMonster::mtEnderman || a_MobType == cMonster::mtZombiePigman) + break; + } + case cMonster::mtSpider: + { + bool CanSpawn = true; + bool HaveFloor = false; + for (int x = 0; x < 2; ++x) { - toReturn = true /*a_LightLevel <= 7 MG TODO*/; - /*if (a_SunLight) MG TODO + for(int z = 0; z < 2; ++z) { - if (m_Random.NextInt(2,a_Biome) != 0) + CanSpawn = a_Chunk->UnboundedRelGetBlockType(a_RelX + x, a_RelY, a_RelZ + z, TargetBlock); + CanSpawn = CanSpawn && (TargetBlock == E_BLOCK_AIR); + if (!CanSpawn) { - toReturn = false; + return false; } - }*/ - } - else if (a_MobType == cMonster::mtSlime) - { - toReturn = a_Level <= 40; - // MG TODO : much more complicated rules - } - else if (a_MobType == cMonster::mtGhast) - { - toReturn = m_Random.NextInt(20,a_Biome) == 0; - } - else - { - LOGD("MG TODO : check I've got a Rule to write for type %d",a_MobType); - toReturn = true; + if (!HaveFloor) + { + a_Chunk->UnboundedRelGetBlockType(a_RelX + x, a_RelY - 1, a_RelZ + z, TargetBlock); + HaveFloor = HaveFloor || !g_BlockTransparent[TargetBlock]; + } + } } + return CanSpawn && HaveFloor && ((SkyLight <= 7) || a_TimeOfDay > 12500) && (BlockLight <= 7); + } + case cMonster::mtCreeper: + case cMonster::mtZombie: + return (TargetBlock == E_BLOCK_AIR) && (BlockAbove == E_BLOCK_AIR) && (!g_BlockTransparent[BlockBelow]) && + ((SkyLight <= 7) || a_TimeOfDay > 12500) && (BlockLight <= 7) && (m_Random.NextInt(2,a_Biome) == 0); + + case cMonster::mtSlime: + return (TargetBlock == E_BLOCK_AIR) && (BlockAbove == E_BLOCK_AIR) && (!g_BlockTransparent[BlockBelow]) && + ((a_RelY <= 40) || a_Biome == biSwampland); + case cMonster::mtGhast: + case cMonster::mtZombiePigman: + return (TargetBlock == E_BLOCK_AIR) && (BlockAbove == E_BLOCK_AIR) && (!g_BlockTransparent[BlockBelow]) && + (m_Random.NextInt(20,a_Biome) == 0); + default: + LOGD("MG TODO : check I've got a Rule to write for type %d",a_MobType); + return false; } } - return toReturn; + return false; } -cMonster* cMobSpawner::TryToSpawnHere(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, BLOCKTYPE a_BlockType_below, NIBBLETYPE a_BlockMeta_below, BLOCKTYPE a_BlockType_above, NIBBLETYPE a_BlockMeta_above, EMCSBiome a_Biome, int a_Level, int& a_MaxPackSize) +cMonster* cMobSpawner::TryToSpawnHere(const cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, EMCSBiome a_Biome, int a_TimeOfDay, int& a_MaxPackSize) { cMonster* toReturn = NULL; if (m_NewPack) @@ -226,7 +242,7 @@ cMonster* cMobSpawner::TryToSpawnHere(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockM } - if (CanSpawnHere(m_MobType, a_BlockType, a_BlockMeta, a_BlockType_below, a_BlockMeta_below, a_BlockType_above, a_BlockMeta_above, a_Biome, a_Level)) + if (CanSpawnHere(a_Chunk, a_RelX, a_RelY, a_RelZ, m_MobType, a_TimeOfDay, a_Biome)) { cMonster * newMob = cMonster::NewMonsterFromType(m_MobType); if (newMob) |