/* * 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&);