/*
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by the
* Free Software Foundation; either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see .
*/
#include "GridObjectLoader.h"
#include "CellImpl.h"
#include "Corpse.h"
#include "Creature.h"
#include "DynamicObject.h"
#include "GameObject.h"
#include "GridNotifiers.h"
#include "Transport.h"
template
void GridObjectLoader::AddObjectHelper(Map* map, T* obj)
{
CellCoord cellCoord = Acore::ComputeCellCoord(obj->GetPositionX(), obj->GetPositionY());
Cell cell(cellCoord);
map->AddToGrid(obj, cell);
obj->AddToWorld();
}
void GridObjectLoader::LoadCreatures(CellGuidSet const& guid_set, Map* map)
{
for (ObjectGuid::LowType const& guid : guid_set)
{
Creature* obj = new Creature();
if (!obj->LoadFromDB(guid, map))
{
delete obj;
continue;
}
AddObjectHelper(map, obj);
if (!obj->IsMoveInLineOfSightDisabled() && obj->GetDefaultMovementType() == IDLE_MOTION_TYPE && !obj->isNeedNotify(NOTIFY_VISIBILITY_CHANGED | NOTIFY_AI_RELOCATION))
{
if (obj->IsAlive() && !obj->HasUnitState(UNIT_STATE_SIGHTLESS) && obj->HasReactState(REACT_AGGRESSIVE) && !obj->IsImmuneToNPC())
{
// call MoveInLineOfSight for nearby grid creatures
Acore::AIRelocationNotifier notifier(*obj);
Cell::VisitObjects(obj, notifier, 60.f);
}
}
}
}
void GridObjectLoader::LoadGameObjects(CellGuidSet const& guid_set, Map* map)
{
for (ObjectGuid::LowType const& guid : guid_set)
{
GameObjectData const* data = sObjectMgr->GetGameObjectData(guid);
if (data && sObjectMgr->IsGameObjectStaticTransport(data->id))
{
StaticTransport* transport = new StaticTransport();
// Special case for static transports - we are loaded via grids
// but we do not want to actually be stored in the grid
if (!transport->LoadGameObjectFromDB(guid, map, true))
delete transport;
}
else
{
GameObject* obj = new GameObject();
if (!obj->LoadFromDB(guid, map))
{
delete obj;
continue;
}
AddObjectHelper(map, obj);
}
}
}
void GridObjectLoader::LoadAllCellsInGrid()
{
CellObjectGuids const& cell_guids = sObjectMgr->GetGridObjectGuids(_map->GetId(), _map->GetSpawnMode(), _grid.GetId());
LoadGameObjects(cell_guids.gameobjects, _map);
LoadCreatures(cell_guids.creatures, _map);
if (std::unordered_set const* corpses = _map->GetCorpsesInGrid(_grid.GetId()))
{
for (Corpse* corpse : *corpses)
{
if (corpse->IsInGrid())
continue;
AddObjectHelper(_map, corpse);
}
}
}
template
void GridObjectUnloader::Visit(GridRefMgr& m)
{
while (!m.IsEmpty())
{
T* obj = m.getFirst()->GetSource();
// if option set then object already saved at this moment
//if (!sWorld->getBoolConfig(CONFIG_SAVE_RESPAWN_TIME_IMMEDIATELY))
// obj->SaveRespawnTime();
//Some creatures may summon other temp summons in CleanupsBeforeDelete()
//So we need this even after cleaner (maybe we can remove cleaner)
//Example: Flame Leviathan Turret 33139 is summoned when a creature is deleted
//TODO: Check if that script has the correct logic. Do we really need to summons something before deleting?
obj->CleanupsBeforeDelete();
obj->GetMap()->RemoveObjectFromMapUpdateList(obj);
///- object will get delinked from the manager when deleted
delete obj;
}
}
template
void GridObjectCleaner::Visit(GridRefMgr& m)
{
for (typename GridRefMgr::iterator iter = m.begin(); iter != m.end(); ++iter)
iter->GetSource()->CleanupsBeforeDelete();
}
template void GridObjectUnloader::Visit(CreatureMapType&);
template void GridObjectUnloader::Visit(GameObjectMapType&);
template void GridObjectUnloader::Visit(DynamicObjectMapType&);
template void GridObjectCleaner::Visit(CreatureMapType&);
template void GridObjectCleaner::Visit(GameObjectMapType&);
template void GridObjectCleaner::Visit(DynamicObjectMapType&);
template void GridObjectCleaner::Visit(CorpseMapType&);