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.
This commit is contained in:
r00ty-tc
2017-05-07 21:48:41 +01:00
committed by Treeston
parent d24ce1739a
commit 59db2eeea0
59 changed files with 2709 additions and 771 deletions

View File

@@ -27,6 +27,7 @@
#include "ObjectAccessor.h"
#include "ObjectMgr.h"
#include "World.h"
#include "ScriptMgr.h"
void ObjectGridEvacuator::Visit(CreatureMapType &m)
{
@@ -119,15 +120,47 @@ void LoadHelper(CellGuidSet const& guid_set, CellCoord &cell, GridRefManager<T>
for (CellGuidSet::const_iterator i_guid = guid_set.begin(); i_guid != guid_set.end(); ++i_guid)
{
T* obj = new T;
ObjectGuid::LowType guid = *i_guid;
//TC_LOG_INFO("misc", "DEBUG: LoadHelper from table: %s for (guid: %u) Loading", table, guid);
if (!obj->LoadFromDB(guid, map))
{
delete obj;
continue;
}
AddObjectHelper(cell, m, count, map, obj);
// Don't spawn at all if there's a respawn time
if ((obj->GetTypeId() == TYPEID_UNIT && !map->GetCreatureRespawnTime(*i_guid)) || (obj->GetTypeId() == TYPEID_GAMEOBJECT && !map->GetGORespawnTime(*i_guid)))
{
ObjectGuid::LowType guid = *i_guid;
//TC_LOG_INFO("misc", "DEBUG: LoadHelper from table: %s for (guid: %u) Loading", table, guid);
if (obj->GetTypeId() == TYPEID_UNIT)
{
CreatureData const* cdata = sObjectMgr->GetCreatureData(guid);
ASSERT(cdata, "Tried to load creature with spawnId %u, but no such creature exists.", guid);
SpawnGroupTemplateData const* const group = cdata->spawnGroupData;
// If creature in manual spawn group, don't spawn here, unless group is already active.
if ((group->flags & SPAWNGROUP_FLAG_MANUAL_SPAWN) && !group->isActive)
continue;
// If script is blocking spawn, don't spawn but queue for a re-check in a little bit
if (!(group->flags & SPAWNGROUP_FLAG_COMPATIBILITY_MODE) && !sScriptMgr->CanSpawn(guid, cdata->id, cdata, map))
{
map->SaveRespawnTime(SPAWN_TYPE_CREATURE, guid, cdata->id, time(NULL) + urand(4,7), map->GetZoneId(cdata->spawnPoint), Trinity::ComputeGridCoord(cdata->spawnPoint.GetPositionX(), cdata->spawnPoint.GetPositionY()).GetId(), false);
continue;
}
}
else if (obj->GetTypeId() == TYPEID_GAMEOBJECT)
{
// If gameobject in manual spawn group, don't spawn here, unless group is already active.
GameObjectData const* godata = sObjectMgr->GetGameObjectData(guid);
ASSERT(godata, "Tried to load gameobject with spawnId %u, but no such object exists.", guid);
if ((godata->spawnGroupData->flags & SPAWNGROUP_FLAG_MANUAL_SPAWN) && !godata->spawnGroupData->isActive)
continue;
}
if (!obj->LoadFromDB(guid, map, false, false))
{
delete obj;
continue;
}
AddObjectHelper(cell, m, count, map, obj);
}
else
delete obj;
}
}