[11131] Check restriction for pool spawns at instanceable maps.

Pool system can't have mixed pool spawns at different maps
if one from map instanceable. In last case all pool spawns
must be at same instanceable maps for any pools that have
common mother pool.

Now this checked at server sartup.
This commit is contained in:
VladimirMangos 2011-02-10 20:15:13 +03:00
parent d7cf24970a
commit 26a4eed36c
2 changed files with 78 additions and 1 deletions

View file

@ -498,6 +498,59 @@ PoolManager::PoolManager()
{ {
} }
// Check listing all pool spawns in single instanceable map or only in non-instanceable maps
// This applied to all pools have common mother pool
struct PoolMapChecker
{
typedef std::map<uint32,MapEntry const*> Pool2Maps;
Pool2Maps m_pool2maps;
bool CheckAndRemember(uint32 mapid, uint32 pool_id, char const* tableName, char const* elementName)
{
MapEntry const* mapEntry = sMapStore.LookupEntry(mapid);
if (!mapEntry)
return false;
MapEntry const* poolMapEntry = GetPoolMapEntry(pool_id);
// if not listed then just remember
if (!poolMapEntry)
{
m_pool2maps[pool_id] = mapEntry;
return true;
}
// if at same map, then all ok
if (poolMapEntry == mapEntry)
return true;
// pool spawns must be at single instanceable map
if (mapEntry->Instanceable())
{
sLog.outErrorDb("`%s` has %s spawned at instanceable map %u when one or several other spawned at different map %u in pool id %i, skipped.",
tableName, elementName, mapid, poolMapEntry->MapID, pool_id);
return false;
}
// pool spawns must be at single instanceable map
if (poolMapEntry->Instanceable())
{
sLog.outErrorDb("`%s` has %s spawned at map %u when one or several other spawned at different instanceable map %u in pool id %i, skipped.",
tableName, elementName, mapid, poolMapEntry->MapID, pool_id);
return false;
}
// pool spawns can be at different non-instanceable maps
return true;
}
MapEntry const* GetPoolMapEntry(uint32 pool_id) const
{
Pool2Maps::const_iterator p2m_itr = m_pool2maps.find(pool_id);
return p2m_itr != m_pool2maps.end() ? p2m_itr->second : NULL;
}
};
void PoolManager::LoadFromDB() void PoolManager::LoadFromDB()
{ {
QueryResult *result = WorldDatabase.Query("SELECT MAX(entry) FROM pool_template"); QueryResult *result = WorldDatabase.Query("SELECT MAX(entry) FROM pool_template");
@ -547,6 +600,8 @@ void PoolManager::LoadFromDB()
sLog.outString( ">> Loaded %u objects pools", count ); sLog.outString( ">> Loaded %u objects pools", count );
delete result; delete result;
PoolMapChecker mapCheaker;
// Creatures // Creatures
mPoolCreatureGroups.resize(max_pool_id + 1); mPoolCreatureGroups.resize(max_pool_id + 1);
@ -593,6 +648,10 @@ void PoolManager::LoadFromDB()
sLog.outErrorDb("`pool_creature` has an invalid chance (%f) for creature guid (%u) in pool id (%i), skipped.", chance, guid, pool_id); sLog.outErrorDb("`pool_creature` has an invalid chance (%f) for creature guid (%u) in pool id (%i), skipped.", chance, guid, pool_id);
continue; continue;
} }
if (!mapCheaker.CheckAndRemember(data->mapid, pool_id, "pool_creature", "creature guid"))
continue;
PoolTemplateData *pPoolTemplate = &mPoolTemplate[pool_id]; PoolTemplateData *pPoolTemplate = &mPoolTemplate[pool_id];
++count; ++count;
@ -663,6 +722,10 @@ void PoolManager::LoadFromDB()
sLog.outErrorDb("`pool_gameobject` has an invalid chance (%f) for gameobject guid (%u) in pool id (%i), skipped.", chance, guid, pool_id); sLog.outErrorDb("`pool_gameobject` has an invalid chance (%f) for gameobject guid (%u) in pool id (%i), skipped.", chance, guid, pool_id);
continue; continue;
} }
if (!mapCheaker.CheckAndRemember(data->mapid, pool_id, "pool_gameobject", "gameobject guid"))
continue;
PoolTemplateData *pPoolTemplate = &mPoolTemplate[pool_id]; PoolTemplateData *pPoolTemplate = &mPoolTemplate[pool_id];
++count; ++count;
@ -728,6 +791,7 @@ void PoolManager::LoadFromDB()
sLog.outErrorDb("`pool_pool` has an invalid chance (%f) for pool id (%u) in mother pool id (%i), skipped.", chance, child_pool_id, mother_pool_id); sLog.outErrorDb("`pool_pool` has an invalid chance (%f) for pool id (%u) in mother pool id (%i), skipped.", chance, child_pool_id, mother_pool_id);
continue; continue;
} }
PoolTemplateData *pPoolTemplateMother = &mPoolTemplate[mother_pool_id]; PoolTemplateData *pPoolTemplateMother = &mPoolTemplate[mother_pool_id];
++count; ++count;
@ -750,6 +814,18 @@ void PoolManager::LoadFromDB()
std::set<uint16> checkedPools; std::set<uint16> checkedPools;
for(SearchMap::iterator poolItr = mPoolSearchMap.find(i); poolItr != mPoolSearchMap.end(); poolItr = mPoolSearchMap.find(poolItr->second)) for(SearchMap::iterator poolItr = mPoolSearchMap.find(i); poolItr != mPoolSearchMap.end(); poolItr = mPoolSearchMap.find(poolItr->second))
{ {
// if child pool not have map data then it empty or have not checked child then will checked and all line later
if (MapEntry const* childMapEntry = mapCheaker.GetPoolMapEntry(poolItr->first))
{
if (!mapCheaker.CheckAndRemember(childMapEntry->MapID, poolItr->second, "pool_pool", "pool with creature/gameobject"))
{
mPoolPoolGroups[poolItr->second].RemoveOneRelation(poolItr->first);
mPoolSearchMap.erase(poolItr);
--count;
break;
}
}
checkedPools.insert(poolItr->first); checkedPools.insert(poolItr->first);
if(checkedPools.find(poolItr->second) != checkedPools.end()) if(checkedPools.find(poolItr->second) != checkedPools.end())
{ {
@ -767,6 +843,7 @@ void PoolManager::LoadFromDB()
} }
} }
} }
sLog.outString(); sLog.outString();
sLog.outString( ">> Loaded %u pools in mother pools", count ); sLog.outString( ">> Loaded %u pools in mother pools", count );
delete result; delete result;

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "11130" #define REVISION_NR "11131"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__