Files
TCPlayerbotCore/src/server/game/Grids/ObjectGridLoader.cpp
T

322 lines
9.9 KiB
C++
Raw Normal View History

/*
2011-01-01 15:01:13 +01:00
* Copyright (C) 2008-2011 TrinityCore <http://www.trinitycore.org/>
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 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 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 <http://www.gnu.org/licenses/>.
2008-10-02 16:23:55 -05:00
*/
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
#include "ObjectGridLoader.h"
#include "ObjectAccessor.h"
#include "ObjectMgr.h"
#include "Creature.h"
2009-03-28 22:44:09 -06:00
#include "Vehicle.h"
2008-10-02 16:23:55 -05:00
#include "GameObject.h"
#include "DynamicObject.h"
#include "Corpse.h"
#include "World.h"
#include "CellImpl.h"
#include "CreatureAI.h"
2009-10-17 15:51:44 -07:00
2010-02-05 00:31:28 +01:00
class ObjectGridRespawnMover
2008-10-02 16:23:55 -05:00
{
public:
ObjectGridRespawnMover() {}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
void Move(GridType &grid);
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
template<class T> void Visit(GridRefManager<T> &) {}
void Visit(CreatureMapType &m);
};
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
void
ObjectGridRespawnMover::Move(GridType &grid)
{
TypeContainerVisitor<ObjectGridRespawnMover, GridTypeMapContainer > mover(*this);
grid.Visit(mover);
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
void
ObjectGridRespawnMover::Visit(CreatureMapType &m)
{
// creature in unloading grid can have respawn point in another grid
// if it will be unloaded then it will not respawn in original grid until unload/load original grid
2008-12-12 11:21:28 -06:00
// move to respawn point to prevent this case. For player view in respawn grid this will be normal respawn.
2009-11-20 19:11:28 -08:00
for (CreatureMapType::iterator iter = m.begin(); iter != m.end();)
2008-10-02 16:23:55 -05:00
{
Creature * c = iter->getSource();
++iter;
2009-10-17 15:51:44 -07:00
ASSERT(!c->isPet() && "ObjectGridRespawnMover don't must be called for pets");
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
Cell const& cur_cell = c->GetCurrentCell();
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
float resp_x, resp_y, resp_z;
c->GetRespawnCoord(resp_x, resp_y, resp_z);
2008-10-14 11:57:03 -05:00
CellPair resp_val = Trinity::ComputeCellPair(resp_x, resp_y);
2008-10-02 16:23:55 -05:00
Cell resp_cell(resp_val);
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if (cur_cell.DiffGrid(resp_cell))
2008-10-02 16:23:55 -05:00
{
c->GetMap()->CreatureRespawnRelocation(c);
2008-10-02 16:23:55 -05:00
// false result ignored: will be unload with other creatures at grid
}
}
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
// for loading world object at grid loading (Corpses)
class ObjectWorldLoader
{
public:
explicit ObjectWorldLoader(ObjectGridLoader& gloader)
: i_cell(gloader.i_cell), i_grid(gloader.i_grid), i_map(gloader.i_map), i_corpses (0)
{}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
void Visit(CorpseMapType &m);
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
template<class T> void Visit(GridRefManager<T>&) { }
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
private:
Cell i_cell;
NGridType &i_grid;
Map* i_map;
public:
uint32 i_corpses;
};
2009-10-17 15:51:44 -07:00
template<class T> void AddUnitState(T* /*obj*/, CellPair const& /*cell_pair*/)
2008-10-02 16:23:55 -05:00
{
}
2009-10-17 15:51:44 -07:00
template<> void AddUnitState(Creature *obj, CellPair const& cell_pair)
2008-10-02 16:23:55 -05:00
{
Cell cell(cell_pair);
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
obj->SetCurrentCell(cell);
}
2009-10-17 15:51:44 -07:00
2009-08-11 11:11:22 -05:00
template <class T>
void AddObjectHelper(CellPair &cell, GridRefManager<T> &m, uint32 &count, Map* map, T *obj)
{
obj->GetGridRef().link(&m, obj);
AddUnitState(obj,cell);
2009-08-11 11:11:22 -05:00
obj->AddToWorld();
2010-04-07 19:14:10 +02:00
if (obj->isActiveObject())
2009-08-11 11:11:22 -05:00
map->AddToActive(obj);
2009-10-17 15:51:44 -07:00
2009-08-11 11:11:22 -05:00
++count;
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
template <class T>
void LoadHelper(CellGuidSet const& guid_set, CellPair &cell, GridRefManager<T> &m, uint32 &count, Map* map)
{
2009-10-17 16:20:24 -07:00
for (CellGuidSet::const_iterator i_guid = guid_set.begin(); i_guid != guid_set.end(); ++i_guid)
2008-10-02 16:23:55 -05:00
{
T* obj = new T;
uint32 guid = *i_guid;
//sLog->outString("DEBUG: LoadHelper from table: %s for (guid: %u) Loading",table,guid);
2010-04-07 19:14:10 +02:00
if (!obj->LoadFromDB(guid, map))
2008-10-02 16:23:55 -05:00
{
delete obj;
continue;
}
2009-10-17 15:51:44 -07:00
2009-08-11 11:11:22 -05:00
AddObjectHelper(cell, m, count, map, obj);
2008-10-02 16:23:55 -05:00
}
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
void LoadHelper(CellCorpseSet const& cell_corpses, CellPair &cell, CorpseMapType &m, uint32 &count, Map* map)
{
2010-04-07 19:14:10 +02:00
if (cell_corpses.empty())
2008-10-02 16:23:55 -05:00
return;
2009-10-17 15:51:44 -07:00
2009-10-17 16:20:24 -07:00
for (CellCorpseSet::const_iterator itr = cell_corpses.begin(); itr != cell_corpses.end(); ++itr)
2008-10-02 16:23:55 -05:00
{
2010-04-07 19:14:10 +02:00
if (itr->second != map->GetInstanceId())
2008-10-02 16:23:55 -05:00
continue;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
uint32 player_guid = itr->first;
2009-10-17 15:51:44 -07:00
Corpse *obj = sObjectAccessor->GetCorpseForPlayerGUID(player_guid);
2010-04-07 19:14:10 +02:00
if (!obj)
2008-10-02 16:23:55 -05:00
continue;
2009-10-17 15:51:44 -07:00
// TODO: this is a hack
// corpse's map should be reset when the map is unloaded
// but it may still exist when the grid is unloaded but map is not
// in that case map == currMap
obj->SetMap(map);
2009-10-17 15:51:44 -07:00
2009-08-11 11:11:22 -05:00
AddObjectHelper(cell, m, count, map, obj);
2008-10-02 16:23:55 -05:00
}
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
void
ObjectGridLoader::Visit(GameObjectMapType &m)
{
uint32 x = (i_cell.GridX()*MAX_NUMBER_OF_CELLS) + i_cell.CellX();
uint32 y = (i_cell.GridY()*MAX_NUMBER_OF_CELLS) + i_cell.CellY();
CellPair cell_pair(x,y);
uint32 cell_id = (cell_pair.y_coord*TOTAL_NUMBER_OF_CELLS_PER_MAP) + cell_pair.x_coord;
2009-10-17 15:51:44 -07:00
CellObjectGuids const& cell_guids = sObjectMgr->GetCellObjectGuids(i_map->GetId(), i_map->GetSpawnMode(), cell_id);
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
LoadHelper(cell_guids.gameobjects, cell_pair, m, i_gameObjects, i_map);
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
void
ObjectGridLoader::Visit(CreatureMapType &m)
{
uint32 x = (i_cell.GridX()*MAX_NUMBER_OF_CELLS) + i_cell.CellX();
uint32 y = (i_cell.GridY()*MAX_NUMBER_OF_CELLS) + i_cell.CellY();
CellPair cell_pair(x,y);
uint32 cell_id = (cell_pair.y_coord*TOTAL_NUMBER_OF_CELLS_PER_MAP) + cell_pair.x_coord;
2009-10-17 15:51:44 -07:00
CellObjectGuids const& cell_guids = sObjectMgr->GetCellObjectGuids(i_map->GetId(), i_map->GetSpawnMode(), cell_id);
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
LoadHelper(cell_guids.creatures, cell_pair, m, i_creatures, i_map);
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
void
ObjectWorldLoader::Visit(CorpseMapType &m)
{
uint32 x = (i_cell.GridX()*MAX_NUMBER_OF_CELLS) + i_cell.CellX();
uint32 y = (i_cell.GridY()*MAX_NUMBER_OF_CELLS) + i_cell.CellY();
CellPair cell_pair(x,y);
uint32 cell_id = (cell_pair.y_coord*TOTAL_NUMBER_OF_CELLS_PER_MAP) + cell_pair.x_coord;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
// corpses are always added to spawn mode 0 and they are spawned by their instance id
CellObjectGuids const& cell_guids = sObjectMgr->GetCellObjectGuids(i_map->GetId(), 0, cell_id);
2008-10-02 16:23:55 -05:00
LoadHelper(cell_guids.corpses, cell_pair, m, i_corpses, i_map);
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
void
ObjectGridLoader::Load(GridType &grid)
{
{
TypeContainerVisitor<ObjectGridLoader, GridTypeMapContainer > loader(*this);
grid.Visit(loader);
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
{
ObjectWorldLoader wloader(*this);
TypeContainerVisitor<ObjectWorldLoader, WorldTypeMapContainer > loader(wloader);
grid.Visit(loader);
i_corpses = wloader.i_corpses;
}
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
void ObjectGridLoader::LoadN(void)
{
i_gameObjects = 0; i_creatures = 0; i_corpses = 0;
i_cell.data.Part.cell_y = 0;
2009-10-17 16:20:24 -07:00
for (unsigned int x=0; x < MAX_NUMBER_OF_CELLS; ++x)
2008-10-02 16:23:55 -05:00
{
i_cell.data.Part.cell_x = x;
2009-10-17 16:20:24 -07:00
for (unsigned int y=0; y < MAX_NUMBER_OF_CELLS; ++y)
2008-10-02 16:23:55 -05:00
{
i_cell.data.Part.cell_y = y;
GridLoader<Player, AllWorldObjectTypes, AllGridObjectTypes> loader;
loader.Load(i_grid(x, y), *this);
}
}
sLog->outDebug("%u GameObjects, %u Creatures, and %u Corpses/Bones loaded for grid %u on map %u", i_gameObjects, i_creatures, i_corpses,i_grid.GetGridId(), i_map->GetId());
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
void ObjectGridUnloader::MoveToRespawnN()
{
2009-10-17 16:20:24 -07:00
for (unsigned int x=0; x < MAX_NUMBER_OF_CELLS; ++x)
2008-10-02 16:23:55 -05:00
{
2009-10-17 16:20:24 -07:00
for (unsigned int y=0; y < MAX_NUMBER_OF_CELLS; ++y)
2008-10-02 16:23:55 -05:00
{
ObjectGridRespawnMover mover;
mover.Move(i_grid(x, y));
}
}
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
void
ObjectGridUnloader::Unload(GridType &grid)
{
TypeContainerVisitor<ObjectGridUnloader, GridTypeMapContainer > unloader(*this);
grid.Visit(unloader);
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
template<class T>
void
ObjectGridUnloader::Visit(GridRefManager<T> &m)
{
2010-04-07 19:13:19 +02:00
while (!m.isEmpty())
2008-10-02 16:23:55 -05:00
{
T *obj = m.getFirst()->getSource();
// if option set then object already saved at this moment
if (!sWorld->getBoolConfig(CONFIG_SAVE_RESPAWN_TIME_IMMEDIATELY))
2008-10-02 16:23:55 -05:00
obj->SaveRespawnTime();
///- object will get delinked from the manager when deleted
delete obj;
}
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
void
ObjectGridStoper::Stop(GridType &grid)
{
TypeContainerVisitor<ObjectGridStoper, GridTypeMapContainer > stoper(*this);
grid.Visit(stoper);
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
void
ObjectGridStoper::Visit(CreatureMapType &m)
{
// stop any fights at grid de-activation and remove dynobjects created at cast by creatures
2009-10-17 16:20:24 -07:00
for (CreatureMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
2008-10-02 16:23:55 -05:00
{
2010-04-07 19:14:10 +02:00
if (iter->getSource()->isInCombat())
{
iter->getSource()->CombatStop();
iter->getSource()->DeleteThreatList();
iter->getSource()->AI()->EnterEvadeMode(); // Calls RemoveAllAuras
}
iter->getSource()->RemoveAllDynObjects(); // Calls RemoveFromWorld, needs to be after RemoveAllAuras or we invalidate the Owner pointer of the aura
2008-10-02 16:23:55 -05:00
}
}
2009-10-17 15:51:44 -07:00
2009-03-29 11:58:19 -06:00
void
ObjectGridCleaner::Stop(GridType &grid)
{
TypeContainerVisitor<ObjectGridCleaner, GridTypeMapContainer > stoper(*this);
grid.Visit(stoper);
}
2009-10-17 15:51:44 -07:00
2009-03-29 11:58:19 -06:00
void
ObjectGridCleaner::Visit(CreatureMapType &m)
{
2009-10-17 16:20:24 -07:00
for (CreatureMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
2009-03-29 11:58:19 -06:00
iter->getSource()->CleanupsBeforeDelete();
}
2009-10-17 15:51:44 -07:00
2009-03-29 11:58:19 -06:00
template<class T>
void
ObjectGridCleaner::Visit(GridRefManager<T> &m)
{
2009-10-17 16:20:24 -07:00
for (typename GridRefManager<T>::iterator iter = m.begin(); iter != m.end(); ++iter)
2009-03-29 11:58:19 -06:00
iter->getSource()->RemoveFromWorld();
}
2009-10-17 15:51:44 -07:00
2009-03-29 13:38:50 -06:00
template void ObjectGridUnloader::Visit(CreatureMapType &);
template void ObjectGridUnloader::Visit(GameObjectMapType &);
2009-03-29 11:58:19 -06:00
template void ObjectGridUnloader::Visit(DynamicObjectMapType &);
2009-03-29 13:38:50 -06:00
template void ObjectGridUnloader::Visit(CorpseMapType &);
2009-03-29 15:03:50 -06:00
template void ObjectGridCleaner::Visit<GameObject>(GameObjectMapType &);
template void ObjectGridCleaner::Visit<DynamicObject>(DynamicObjectMapType &);
template void ObjectGridCleaner::Visit<Corpse>(CorpseMapType &);