| 826 | |
| 827 | |
| 828 | void cWorld::TickMobs(float a_Dt) |
| 829 | { |
| 830 | // _X 2013_10_22: This is a quick fix for #283 - the world needs to be locked while ticking mobs |
| 831 | cWorld::cLock Lock(*this); |
| 832 | |
| 833 | // before every Mob action, we have to count them depending on the distance to players, on their family ... |
| 834 | cMobCensus MobCensus; |
| 835 | m_ChunkMap->CollectMobCensus(MobCensus); |
| 836 | if (m_bAnimals) |
| 837 | { |
| 838 | // Spawning is enabled, spawn now: |
| 839 | static const cMonster::eFamily AllFamilies[] = |
| 840 | { |
| 841 | cMonster::mfHostile, |
| 842 | cMonster::mfPassive, |
| 843 | cMonster::mfAmbient, |
| 844 | cMonster::mfWater, |
| 845 | } ; |
| 846 | for (size_t i = 0; i < ARRAYCOUNT(AllFamilies); i++) |
| 847 | { |
| 848 | cMonster::eFamily Family = AllFamilies[i]; |
| 849 | int SpawnDelay = cMonster::GetSpawnDelay(Family); |
| 850 | if ( |
| 851 | (m_LastSpawnMonster[Family] > m_WorldAge - SpawnDelay) || // Not reached the needed ticks before the next round |
| 852 | MobCensus.IsCapped(Family) |
| 853 | ) |
| 854 | { |
| 855 | continue; |
| 856 | } |
| 857 | m_LastSpawnMonster[Family] = m_WorldAge; |
| 858 | cMobSpawner Spawner(Family, m_AllowedMobs); |
| 859 | if (Spawner.CanSpawnAnything()) |
| 860 | { |
| 861 | m_ChunkMap->SpawnMobs(Spawner); |
| 862 | // do the spawn |
| 863 | for (cMobSpawner::tSpawnedContainer::const_iterator itr2 = Spawner.getSpawned().begin(); itr2 != Spawner.getSpawned().end(); itr2++) |
| 864 | { |
| 865 | SpawnMobFinalize(*itr2); |
| 866 | } |
| 867 | } |
| 868 | } // for i - AllFamilies[] |
| 869 | } // if (Spawning enabled) |
| 870 | |
| 871 | // move close mobs |
| 872 | cMobProximityCounter::sIterablePair allCloseEnoughToMoveMobs = MobCensus.GetProximityCounter().getMobWithinThosesDistances(-1, 64 * 16);// MG TODO : deal with this magic number (the 16 is the size of a block) |
| 873 | for(cMobProximityCounter::tDistanceToMonster::const_iterator itr = allCloseEnoughToMoveMobs.m_Begin; itr != allCloseEnoughToMoveMobs.m_End; itr++) |
| 874 | { |
| 875 | itr->second.m_Monster.Tick(a_Dt, itr->second.m_Chunk); |
| 876 | } |
| 877 | |
| 878 | // remove too far mobs |
| 879 | cMobProximityCounter::sIterablePair allTooFarMobs = MobCensus.GetProximityCounter().getMobWithinThosesDistances(128 * 16, -1);// MG TODO : deal with this magic number (the 16 is the size of a block) |
| 880 | for(cMobProximityCounter::tDistanceToMonster::const_iterator itr = allTooFarMobs.m_Begin; itr != allTooFarMobs.m_End; itr++) |
| 881 | { |
| 882 | itr->second.m_Monster.Destroy(true); |
| 883 | } |
| 884 | } |
| 885 |
nothing calls this directly
no test coverage detected