From 59db2eeea0a35028779fd76372ae06cc98c8086f Mon Sep 17 00:00:00 2001 From: r00ty-tc Date: Sun, 7 May 2017 21:48:41 +0100 Subject: Dynamic Creature/Go spawning: - True blizzlike creature spawn/respawn behavior - new creature = new object - Toggleable spawn groups (with C++/SAI/command options to use them) - Custom feature: dynamic spawn rate scaling. Accelerates respawn rate based on players in the zone. - Backward compatibility mode (set via group and for summons) to support creatures/gos that currently don't work well with this (this should be removed once the exceptions are fixed) Fixes and closes #2858 Tags #8661 as fixable. Fixes and closes #13787 Fixes #15222. --- src/server/game/Pools/PoolMgr.cpp | 44 +++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 11 deletions(-) (limited to 'src/server/game/Pools/PoolMgr.cpp') diff --git a/src/server/game/Pools/PoolMgr.cpp b/src/server/game/Pools/PoolMgr.cpp index 9305e226421..7ab6c43d410 100644 --- a/src/server/game/Pools/PoolMgr.cpp +++ b/src/server/game/Pools/PoolMgr.cpp @@ -222,7 +222,7 @@ void PoolGroup::Despawn1Object(ObjectGuid::LowType guid) { sObjectMgr->RemoveCreatureFromGrid(guid, data); - Map* map = sMapMgr->CreateBaseMap(data->mapid); + Map* map = sMapMgr->CreateBaseMap(data->spawnPoint.GetMapId()); if (!map->Instanceable()) { auto creatureBounds = map->GetCreatureBySpawnIdStore().equal_range(guid); @@ -230,6 +230,9 @@ void PoolGroup::Despawn1Object(ObjectGuid::LowType guid) { Creature* creature = itr->second; ++itr; + // For dynamic spawns, save respawn time here + if (!creature->GetRespawnCompatibilityMode()) + creature->SaveRespawnTime(0, false); creature->AddObjectToRemoveList(); } } @@ -240,11 +243,11 @@ void PoolGroup::Despawn1Object(ObjectGuid::LowType guid) template<> void PoolGroup::Despawn1Object(ObjectGuid::LowType guid) { - if (GameObjectData const* data = sObjectMgr->GetGOData(guid)) + if (GameObjectData const* data = sObjectMgr->GetGameObjectData(guid)) { sObjectMgr->RemoveGameobjectFromGrid(guid, data); - Map* map = sMapMgr->CreateBaseMap(data->mapid); + Map* map = sMapMgr->CreateBaseMap(data->spawnPoint.GetMapId()); if (!map->Instanceable()) { auto gameobjectBounds = map->GetGameObjectBySpawnIdStore().equal_range(guid); @@ -252,6 +255,10 @@ void PoolGroup::Despawn1Object(ObjectGuid::LowType guid) { GameObject* go = itr->second; ++itr; + + // For dynamic spawns, save respawn time here + if (!go->GetRespawnCompatibilityMode()) + go->SaveRespawnTime(0, false); go->AddObjectToRemoveList(); } } @@ -379,13 +386,13 @@ void PoolGroup::Spawn1Object(PoolObject* obj) sObjectMgr->AddCreatureToGrid(obj->guid, data); // Spawn if necessary (loaded grids only) - Map* map = sMapMgr->CreateBaseMap(data->mapid); + Map* map = sMapMgr->CreateBaseMap(data->spawnPoint.GetMapId()); // We use spawn coords to spawn - if (!map->Instanceable() && map->IsGridLoaded(data->posX, data->posY)) + if (!map->Instanceable() && map->IsGridLoaded(data->spawnPoint)) { Creature* creature = new Creature(); //TC_LOG_DEBUG("pool", "Spawning creature %u", guid); - if (!creature->LoadCreatureFromDB(obj->guid, map)) + if (!creature->LoadFromDB(obj->guid, map, true, false)) { delete creature; return; @@ -398,18 +405,18 @@ void PoolGroup::Spawn1Object(PoolObject* obj) template <> void PoolGroup::Spawn1Object(PoolObject* obj) { - if (GameObjectData const* data = sObjectMgr->GetGOData(obj->guid)) + if (GameObjectData const* data = sObjectMgr->GetGameObjectData(obj->guid)) { sObjectMgr->AddGameobjectToGrid(obj->guid, data); // Spawn if necessary (loaded grids only) // this base map checked as non-instanced and then only existed - Map* map = sMapMgr->CreateBaseMap(data->mapid); + Map* map = sMapMgr->CreateBaseMap(data->spawnPoint.GetMapId()); // We use current coords to unspawn, not spawn coords since creature can have changed grid - if (!map->Instanceable() && map->IsGridLoaded(data->posX, data->posY)) + if (!map->Instanceable() && map->IsGridLoaded(data->spawnPoint)) { GameObject* pGameobject = new GameObject; //TC_LOG_DEBUG("pool", "Spawning gameobject %u", guid); - if (!pGameobject->LoadGameObjectFromDB(obj->guid, map, false)) + if (!pGameobject->LoadFromDB(obj->guid, map, false)) { delete pGameobject; return; @@ -688,7 +695,7 @@ void PoolMgr::LoadFromDB() uint32 pool_id = fields[1].GetUInt32(); float chance = fields[2].GetFloat(); - GameObjectData const* data = sObjectMgr->GetGOData(guid); + GameObjectData const* data = sObjectMgr->GetGameObjectData(guid); if (!data) { TC_LOG_ERROR("sql.sql", "`pool_gameobject` has a non existing gameobject spawn (GUID: %u) defined for pool id (%u), skipped.", guid, pool_id); @@ -1074,6 +1081,21 @@ void PoolMgr::DespawnPool(uint32 pool_id) mPoolQuestGroups[pool_id].DespawnObject(mSpawnedData); } +// Selects proper template overload to call based on passed type +uint32 PoolMgr::IsPartOfAPool(SpawnObjectType type, ObjectGuid::LowType spawnId) const +{ + switch (type) + { + case SPAWN_TYPE_CREATURE: + return IsPartOfAPool(spawnId); + case SPAWN_TYPE_GAMEOBJECT: + return IsPartOfAPool(spawnId); + default: + ASSERT(false, "Invalid spawn type %u passed to PoolMgr::IsPartOfPool (with spawnId %u)", uint32(type), spawnId); + return 0; + } +} + // Method that check chance integrity of the creatures and gameobjects in this pool bool PoolMgr::CheckPool(uint32 pool_id) const { -- cgit v1.2.3