From 2361a5dc418a42092ed8040e6826b65b38e94fcb Mon Sep 17 00:00:00 2001 From: mgueydan Date: Sat, 7 Sep 2013 20:07:56 +0200 Subject: relockating mobs includes (they probably will end somewhere else in order not to recompile world each time you update a mob) --- source/World.cpp | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) (limited to 'source/World.cpp') diff --git a/source/World.cpp b/source/World.cpp index ab783d7a7..d0fa588b0 100644 --- a/source/World.cpp +++ b/source/World.cpp @@ -28,29 +28,7 @@ #include "Simulator/VaporizeFluidSimulator.h" // Mobs: -#include "Mobs/Bat.h" -#include "Mobs/Blaze.h" -#include "Mobs/Cavespider.h" -#include "Mobs/Chicken.h" -#include "Mobs/Cow.h" -#include "Mobs/Creeper.h" -#include "Mobs/Enderman.h" -#include "Mobs/Ghast.h" -#include "Mobs/Magmacube.h" -#include "Mobs/Mooshroom.h" -#include "Mobs/Ocelot.h" -#include "Mobs/Pig.h" -#include "Mobs/Sheep.h" -#include "Mobs/Silverfish.h" -#include "Mobs/Skeleton.h" -#include "Mobs/Slime.h" -#include "Mobs/Spider.h" -#include "Mobs/Squid.h" -#include "Mobs/Villager.h" -#include "Mobs/Witch.h" -#include "Mobs/Wolf.h" -#include "Mobs/Zombie.h" -#include "Mobs/Zombiepigman.h" +#include "Mobs/IncludeAllMonsters.h" #include "OSSupport/MakeDir.h" #include "MersenneTwister.h" -- cgit v1.2.3 From d2eb58f27780a3c65fedd0d21d152ee8866ebb86 Mon Sep 17 00:00:00 2001 From: mgueydan Date: Sat, 7 Sep 2013 22:19:56 +0200 Subject: Adding mob census (sorry this is a big commit as work was done before git integration i couldn't split it more) --- source/World.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source/World.cpp') diff --git a/source/World.cpp b/source/World.cpp index d0fa588b0..4bde20ede 100644 --- a/source/World.cpp +++ b/source/World.cpp @@ -29,6 +29,7 @@ // Mobs: #include "Mobs/IncludeAllMonsters.h" +#include "MobCensus.h" #include "OSSupport/MakeDir.h" #include "MersenneTwister.h" @@ -712,6 +713,10 @@ void cWorld::TickSpawnMobs(float a_Dt) { return; } + + cMobCensus MobCensus; + m_ChunkMap->CollectMobCensus(MobCensus); + MobCensus.logd(); m_LastSpawnMonster = m_WorldAge; Vector3d SpawnPos; -- cgit v1.2.3 From 04151677d57905e35993eac4899e6bd72831ec6f Mon Sep 17 00:00:00 2001 From: mgueydan Date: Sun, 8 Sep 2013 01:43:55 +0200 Subject: Disabeling current mob spawning and tick --- source/World.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'source/World.cpp') diff --git a/source/World.cpp b/source/World.cpp index 4bde20ede..17c5ccb3e 100644 --- a/source/World.cpp +++ b/source/World.cpp @@ -622,7 +622,7 @@ void cWorld::Tick(float a_Dt) UnloadUnusedChunks(); } - TickSpawnMobs(a_Dt); + TickMobs(a_Dt); std::vector m_RSList_copy(m_RSList); @@ -707,13 +707,13 @@ void cWorld::TickWeather(float a_Dt) -void cWorld::TickSpawnMobs(float a_Dt) +void cWorld::TickMobs(float a_Dt) { - if (!m_bAnimals || (m_WorldAge - m_LastSpawnMonster <= m_SpawnMonsterRate)) + if (!m_bAnimals) { return; } - +/* cMobCensus MobCensus; m_ChunkMap->CollectMobCensus(MobCensus); MobCensus.logd(); @@ -810,6 +810,7 @@ void cWorld::TickSpawnMobs(float a_Dt) // A proper mob type was selected, now spawn the mob: SpawnMob(SpawnPos.x, SpawnPos.y, SpawnPos.z, (cMonster::eType)MobType); } +*/ } -- cgit v1.2.3 From 7a5e3592ffcc80f8c768ed2391b0ad521c59b67e Mon Sep 17 00:00:00 2001 From: mgueydan Date: Sun, 8 Sep 2013 02:47:02 +0200 Subject: Adding glue to call everything done in last commits - now the mobs are spawning --- source/World.cpp | 209 +++++++++++++++++++------------------------------------ 1 file changed, 71 insertions(+), 138 deletions(-) (limited to 'source/World.cpp') diff --git a/source/World.cpp b/source/World.cpp index 17c5ccb3e..2e8f30840 100644 --- a/source/World.cpp +++ b/source/World.cpp @@ -30,6 +30,9 @@ // Mobs: #include "Mobs/IncludeAllMonsters.h" #include "MobCensus.h" +#include "MobSpawner.h" +#include "MobTypesManager.h" + #include "OSSupport/MakeDir.h" #include "MersenneTwister.h" @@ -226,7 +229,6 @@ cWorld::cWorld(const AString & a_WorldName) : m_WorldAge(0), m_TimeOfDay(0), m_LastTimeUpdate(0), - m_LastSpawnMonster(0), m_RSList(0), m_Weather(eWeather_Sunny), m_WeatherInterval(24000), // Guaranteed 1 day of sunshine at server start :) @@ -490,14 +492,13 @@ void cWorld::Start(void) m_GameMode = (eGameMode)IniFile.GetValueSetI("GameMode", "GameMode", m_GameMode); m_bAnimals = true; - m_SpawnMonsterRate = 200; // 1 mob each 10 seconds - cIniFile IniFile2("settings.ini"); - if (IniFile2.ReadFile()) - { - m_bAnimals = IniFile2.GetValueB("Monsters", "AnimalsOn", true); - m_SpawnMonsterRate = (Int64)(IniFile2.GetValueF("Monsters", "AnimalSpawnInterval", 10) * 20); // Convert from secs to ticks - - } + + m_AllowedMobs.insert(cMonster::mtCow); // MG TODO : temporary + m_AllowedMobs.insert(cMonster::mtZombie); + m_AllowedMobs.insert(cMonster::mtZombiePigman); + m_AllowedMobs.insert(cMonster::mtBat); + m_AllowedMobs.insert(cMonster::mtSpider); + m_AllowedMobs.insert(cMonster::mtGhast); m_ChunkMap = new cChunkMap(this); @@ -527,6 +528,13 @@ void cWorld::Start(void) m_ChunkSender.Start(this); m_TickThread.Start(); + // Init of the spawn monster time (as they are supposed to have different spawn rate) + m_LastSpawnMonster.insert(std::map::value_type(cMonster::mfHostile,0)); + m_LastSpawnMonster.insert(std::map::value_type(cMonster::mfPassive,0)); + m_LastSpawnMonster.insert(std::map::value_type(cMonster::mfAmbient,0)); + m_LastSpawnMonster.insert(std::map::value_type(cMonster::mfWater,0)); + + // Save any changes that the defaults may have done to the ini file: if (!IniFile.WriteFile()) { @@ -713,104 +721,52 @@ void cWorld::TickMobs(float a_Dt) { return; } -/* + + // before every Mob action, we have to "counts" them depending on the distance to players, on their megatype ... cMobCensus MobCensus; m_ChunkMap->CollectMobCensus(MobCensus); - MobCensus.logd(); - - m_LastSpawnMonster = m_WorldAge; - Vector3d SpawnPos; - { - cCSLock Lock(m_CSPlayers); - if (m_Players.size() <= 0) - { - return; - } - int RandomPlayerIdx = m_TickRand.randInt() & m_Players.size(); - cPlayerList::iterator itr = m_Players.begin(); - for (int i = 1; i < RandomPlayerIdx; i++) - { - itr++; - } - SpawnPos = (*itr)->GetPosition(); - } - - int dayRand = (m_TickRand.randInt() / 7) % 6; - int nightRand = (m_TickRand.randInt() / 11) % 10; - SpawnPos += Vector3d((double)(m_TickRand.randInt() % 64) - 32, (double)(m_TickRand.randInt() % 64) - 32, (double)(m_TickRand.randInt() % 64) - 32); - int Height = GetHeight((int)SpawnPos.x, (int)SpawnPos.z); - - int MobType = -1; - int Biome = GetBiomeAt((int)SpawnPos.x, (int)SpawnPos.z); - switch (Biome) + for(cMobFamilyCollecter::tMobFamilyList::const_iterator itr = cMobFamilyCollecter::m_AllFamilies().begin(); itr != cMobFamilyCollecter::m_AllFamilies().end(); itr++) { - case biNether: - { - // Spawn nether mobs - switch (nightRand) - { - case 5: MobType = cMonster::mtGhast; break; - case 6: MobType = cMonster::mtZombiePigman; break; - } - break; - } - - case biEnd: - { - // Only endermen spawn in the End - MobType = cMonster::mtEnderman; - break; - } - - case biMushroomIsland: - case biMushroomShore: - { - // Mushroom land gets only mooshrooms - MobType = cMonster::mtMooshroom; - break; - } - - default: + cMobCensus::tMobSpawnRate::const_iterator spawnrate = cMobCensus::m_SpawnRate().find(*itr); + // hostile mobs are spawned more often + if (spawnrate != cMobCensus::m_SpawnRate().end() && m_LastSpawnMonster[*itr] < m_WorldAge - spawnrate->second) { - // Overworld biomes depend on whether it's night or day: - if (m_TimeOfDay >= 12000 + 1000) + m_LastSpawnMonster[*itr] = m_WorldAge; + // each megatype of mob has it's own cap + if (!(MobCensus.isCaped(*itr))) { - // Night mobs: - switch (nightRand) - { - case 0: MobType = cMonster::mtSpider; break; - case 1: MobType = cMonster::mtZombie; break; - case 2: MobType = cMonster::mtEnderman; break; - case 3: MobType = cMonster::mtCreeper; break; - case 4: MobType = cMonster::mtCaveSpider; break; - case 7: MobType = cMonster::mtSlime; break; - case 8: MobType = cMonster::mtSilverfish; break; - case 9: MobType = cMonster::mtSkeleton; break; - } - } // if (night) - else - { - // During the day: - switch (dayRand) + if (m_bAnimals) { - case 0: MobType = cMonster::mtChicken; break; - case 1: MobType = cMonster::mtCow; break; - case 2: MobType = cMonster::mtPig; break; - case 3: MobType = cMonster::mtSheep; break; - case 4: MobType = cMonster::mtSquid; break; - case 5: MobType = cMonster::mtWolf; break; + cMobSpawner Spawner(*itr,m_AllowedMobs); + if (Spawner.CanSpawnSomething()) + { + m_ChunkMap->SpawnMobs(Spawner); + // do the spawn + + for(cMobSpawner::tSpawnedContainer::const_iterator itr2 = Spawner.getSpawned().begin(); itr2 != Spawner.getSpawned().end(); itr2++) + { + SpawnMobFinalize(*itr2); + } + } } - } // else (night) - } // case overworld biomes - } // switch (biome) + } + } + } - if (MobType >= 0) + // move close mobs + cMobProximityCounter::sIterablePair allCloseEnoughToMoveMobs = MobCensus.getProximityCounter().getMobWithinThosesDistances(-1,64*16);// MG TODO : deal with this magic number (the 16 is the size of a block) + for(cMobProximityCounter::tDistanceToMonster::const_iterator itr = allCloseEnoughToMoveMobs.m_Begin; itr != allCloseEnoughToMoveMobs.m_End; itr++) { - // A proper mob type was selected, now spawn the mob: - SpawnMob(SpawnPos.x, SpawnPos.y, SpawnPos.z, (cMonster::eType)MobType); + itr->second.m_Monster.Tick(a_Dt,itr->second.m_Chunk); + } + + // remove too far mobs + cMobProximityCounter::sIterablePair allTooFarMobs = MobCensus.getProximityCounter().getMobWithinThosesDistances(128*16,-1);// MG TODO : deal with this magic number (the 16 is the size of a block) + for(cMobProximityCounter::tDistanceToMonster::const_iterator itr = allTooFarMobs.m_Begin; itr != allTooFarMobs.m_End; itr++) + { + itr->second.m_Monster.Destroy(true); } -*/ } @@ -2578,55 +2534,32 @@ int cWorld::SpawnMob(double a_PosX, double a_PosY, double a_PosZ, cMonster::eTyp { cMonster * Monster = NULL; - int Size = GetTickRandomNumber(2) + 1; // 1 .. 3 - - switch (a_MonsterType) - { - case cMonster::mtBat: Monster = new cBat(); break; - case cMonster::mtBlaze: Monster = new cBlaze(); break; - case cMonster::mtCaveSpider: Monster = new cCavespider(); break; - case cMonster::mtChicken: Monster = new cChicken(); break; - case cMonster::mtCow: Monster = new cCow(); break; - case cMonster::mtCreeper: Monster = new cCreeper(); break; - case cMonster::mtEnderman: Monster = new cEnderman(); break; - case cMonster::mtGhast: Monster = new cGhast(); break; - case cMonster::mtMagmaCube: Monster = new cMagmacube(Size); break; - case cMonster::mtMooshroom: Monster = new cMooshroom(); break; - case cMonster::mtOcelot: Monster = new cOcelot(); break; - case cMonster::mtPig: Monster = new cPig(); break; - case cMonster::mtSheep: Monster = new cSheep(); break; - case cMonster::mtSilverfish: Monster = new cSilverfish(); break; - case cMonster::mtSkeleton: Monster = new cSkeleton(); break; - case cMonster::mtSlime: Monster = new cSlime(Size); break; - case cMonster::mtSpider: Monster = new cSpider(); break; - case cMonster::mtSquid: Monster = new cSquid(); break; - case cMonster::mtVillager: Monster = new cVillager(); break; - case cMonster::mtWitch: Monster = new cWitch(); break; - case cMonster::mtWolf: Monster = new cWolf(); break; - case cMonster::mtZombie: Monster = new cZombie(); break; - case cMonster::mtZombiePigman: Monster = new cZombiepigman(); break; - - default: - { - LOGWARNING("%s: Unhandled monster type: %d. Not spawning.", __FUNCTION__, a_MonsterType); - return -1; - } - } + cMobTypesManager::NewMonsterFromType(a_MonsterType); Monster->SetPosition(a_PosX, a_PosY, a_PosZ); - Monster->SetHealth(Monster->GetMaxHealth()); - if (cPluginManager::Get()->CallHookSpawningMonster(*this, *Monster)) + + return SpawnMobFinalize(Monster); +} + + + + +int cWorld::SpawnMobFinalize(cMonster* a_Monster) +{ + a_Monster->SetHealth(a_Monster->GetMaxHealth()); + if (cPluginManager::Get()->CallHookSpawningMonster(*this, *a_Monster)) { - delete Monster; + delete a_Monster; return -1; } - if (!Monster->Initialize(this)) + if (!a_Monster->Initialize(this)) { - delete Monster; + delete a_Monster; return -1; } - BroadcastSpawnEntity(*Monster); - cPluginManager::Get()->CallHookSpawnedMonster(*this, *Monster); - return Monster->GetUniqueID(); + BroadcastSpawnEntity(*a_Monster); + cPluginManager::Get()->CallHookSpawnedMonster(*this, *a_Monster); + + return a_Monster->GetUniqueID(); } -- cgit v1.2.3 From d67e8dcca5dda496480f3e983a0cf72c1d047bf7 Mon Sep 17 00:00:00 2001 From: mgueydan Date: Sun, 8 Sep 2013 03:30:09 +0200 Subject: Adding mobtype filter inside world.ini --- source/World.cpp | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'source/World.cpp') diff --git a/source/World.cpp b/source/World.cpp index 2e8f30840..9ca432f50 100644 --- a/source/World.cpp +++ b/source/World.cpp @@ -491,14 +491,19 @@ void cWorld::Start(void) m_GameMode = (eGameMode)IniFile.GetValueSetI("GameMode", "GameMode", m_GameMode); - m_bAnimals = true; - - m_AllowedMobs.insert(cMonster::mtCow); // MG TODO : temporary - m_AllowedMobs.insert(cMonster::mtZombie); - m_AllowedMobs.insert(cMonster::mtZombiePigman); - m_AllowedMobs.insert(cMonster::mtBat); - m_AllowedMobs.insert(cMonster::mtSpider); - m_AllowedMobs.insert(cMonster::mtGhast); + m_bAnimals = IniFile.GetValueB("Monsters", "AnimalsOn", true); + AString sAllMonsters = IniFile.GetValue("Monsters", "Types"); + AStringVector SplitList = StringSplit(sAllMonsters, ","); + for (unsigned int i = 0; i < SplitList.size(); ++i) + { + cMonster::eType ToAdd = cMobTypesManager::fromStringToMobType(SplitList[i]); + if (ToAdd != cMonster::mtInvalidType) + { + m_AllowedMobs.insert(ToAdd); + LOGD("Allowed mob: %s",cMobTypesManager::fromMobTypeToString(ToAdd).c_str()); // a bit reverse working, but very few ressources wasted + } + }; + m_ChunkMap = new cChunkMap(this); -- cgit v1.2.3