root/trunk/src/game/ObjectGridLoader.cpp @ 102

Revision 102, 9.2 kB (checked in by yumileroy, 17 years ago)

[svn] Fixed copyright notices to comply with GPL.

Original author: w12x
Date: 2008-10-23 03:29:52-05:00

Line 
1/*
2 * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
3 *
4 * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include "ObjectGridLoader.h"
22#include "ObjectAccessor.h"
23#include "ObjectMgr.h"
24#include "MapManager.h"
25#include "Creature.h"
26#include "GameObject.h"
27#include "DynamicObject.h"
28#include "Corpse.h"
29#include "World.h"
30#include "CellImpl.h"
31
32class TRINITY_DLL_DECL ObjectGridRespawnMover
33{
34    public:
35        ObjectGridRespawnMover() {}
36
37        void Move(GridType &grid);
38
39        template<class T> void Visit(GridRefManager<T> &) {}
40        void Visit(CreatureMapType &m);
41};
42
43void
44ObjectGridRespawnMover::Move(GridType &grid)
45{
46    TypeContainerVisitor<ObjectGridRespawnMover, GridTypeMapContainer > mover(*this);
47    grid.Visit(mover);
48}
49
50void
51ObjectGridRespawnMover::Visit(CreatureMapType &m)
52{
53    // creature in unloading grid can have respawn point in another grid
54    // if it will be unloaded then it will not respawn in original grid until unload/load original grid
55    // move to respwn point to prevent this case. For player view in respawn grid this wll be normal respawn.
56    for(CreatureMapType::iterator iter=m.begin(), next; iter != m.end(); iter = next)
57    {
58        next = iter; ++next;
59
60        Creature * c = iter->getSource();
61
62        assert(!c->isPet() && "ObjectGridRespawnMover don't must be called for pets");
63
64        Cell const& cur_cell  = c->GetCurrentCell();
65
66        float resp_x, resp_y, resp_z;
67        c->GetRespawnCoord(resp_x, resp_y, resp_z);
68        CellPair resp_val = Trinity::ComputeCellPair(resp_x, resp_y);
69        Cell resp_cell(resp_val);
70
71        if(cur_cell.DiffGrid(resp_cell))
72        {
73            MapManager::Instance().GetMap(c->GetMapId(), c)->CreatureRespawnRelocation(c);
74            // false result ignored: will be unload with other creatures at grid
75        }
76    }
77}
78
79// for loading world object at grid loading (Corpses)
80class ObjectWorldLoader
81{
82    public:
83        explicit ObjectWorldLoader(ObjectGridLoader& gloader)
84            : i_cell(gloader.i_cell), i_grid(gloader.i_grid), i_map(gloader.i_map), i_corpses (0)
85            {}
86
87        void Visit(CorpseMapType &m);
88
89        template<class T> void Visit(GridRefManager<T>&) { }
90
91    private:
92        Cell i_cell;
93        NGridType &i_grid;
94        Map* i_map;
95    public:
96        uint32 i_corpses;
97};
98
99template<class T> void addUnitState(T* /*obj*/, CellPair const& /*cell_pair*/)
100{
101}
102
103template<> void addUnitState(Creature *obj, CellPair const& cell_pair)
104{
105    Cell cell(cell_pair);
106
107    obj->SetCurrentCell(cell);
108    if(obj->isSpiritService())
109        obj->setDeathState(DEAD);
110}
111
112template <class T>
113void LoadHelper(CellGuidSet const& guid_set, CellPair &cell, GridRefManager<T> &m, uint32 &count, Map* map)
114{
115    for(CellGuidSet::const_iterator i_guid = guid_set.begin(); i_guid != guid_set.end(); ++i_guid)
116    {
117        T* obj = new T;
118        uint32 guid = *i_guid;
119        //sLog.outString("DEBUG: LoadHelper from table: %s for (guid: %u) Loading",table,guid);
120        if(!obj->LoadFromDB(guid, map))
121        {
122            delete obj;
123            continue;
124        }
125
126        obj->GetGridRef().link(&m, obj);
127
128        addUnitState(obj,cell);
129        obj->AddToWorld();
130        ++count;
131
132    }
133}
134
135void LoadHelper(CellCorpseSet const& cell_corpses, CellPair &cell, CorpseMapType &m, uint32 &count, Map* map)
136{
137    if(cell_corpses.empty())
138        return;
139
140    for(CellCorpseSet::const_iterator itr = cell_corpses.begin(); itr != cell_corpses.end(); ++itr)
141    {
142        if(itr->second != map->GetInstanceId())
143            continue;
144
145        uint32 player_guid = itr->first;
146
147        Corpse *obj = ObjectAccessor::Instance().GetCorpseForPlayerGUID(player_guid);
148        if(!obj)
149            continue;
150
151        obj->GetGridRef().link(&m, obj);
152
153        addUnitState(obj,cell);
154        obj->AddToWorld();
155        ++count;
156    }
157}
158
159void
160ObjectGridLoader::Visit(GameObjectMapType &m)
161{
162    uint32 x = (i_cell.GridX()*MAX_NUMBER_OF_CELLS) + i_cell.CellX();
163    uint32 y = (i_cell.GridY()*MAX_NUMBER_OF_CELLS) + i_cell.CellY();
164    CellPair cell_pair(x,y);
165    uint32 cell_id = (cell_pair.y_coord*TOTAL_NUMBER_OF_CELLS_PER_MAP) + cell_pair.x_coord;
166
167    CellObjectGuids const& cell_guids = objmgr.GetCellObjectGuids(i_map->GetId(), i_map->GetSpawnMode(), cell_id);
168
169    LoadHelper(cell_guids.gameobjects, cell_pair, m, i_gameObjects, i_map);
170}
171
172void
173ObjectGridLoader::Visit(CreatureMapType &m)
174{
175    uint32 x = (i_cell.GridX()*MAX_NUMBER_OF_CELLS) + i_cell.CellX();
176    uint32 y = (i_cell.GridY()*MAX_NUMBER_OF_CELLS) + i_cell.CellY();
177    CellPair cell_pair(x,y);
178    uint32 cell_id = (cell_pair.y_coord*TOTAL_NUMBER_OF_CELLS_PER_MAP) + cell_pair.x_coord;
179
180    CellObjectGuids const& cell_guids = objmgr.GetCellObjectGuids(i_map->GetId(), i_map->GetSpawnMode(), cell_id);
181
182    LoadHelper(cell_guids.creatures, cell_pair, m, i_creatures, i_map);
183}
184
185void
186ObjectWorldLoader::Visit(CorpseMapType &m)
187{
188    uint32 x = (i_cell.GridX()*MAX_NUMBER_OF_CELLS) + i_cell.CellX();
189    uint32 y = (i_cell.GridY()*MAX_NUMBER_OF_CELLS) + i_cell.CellY();
190    CellPair cell_pair(x,y);
191    uint32 cell_id = (cell_pair.y_coord*TOTAL_NUMBER_OF_CELLS_PER_MAP) + cell_pair.x_coord;
192
193    // corpses are always added to spawn mode 0 and they are spawned by their instance id
194    CellObjectGuids const& cell_guids = objmgr.GetCellObjectGuids(i_map->GetId(), 0, cell_id);
195    LoadHelper(cell_guids.corpses, cell_pair, m, i_corpses, i_map);
196}
197
198void
199ObjectGridLoader::Load(GridType &grid)
200{
201    {
202        TypeContainerVisitor<ObjectGridLoader, GridTypeMapContainer > loader(*this);
203        grid.Visit(loader);
204    }
205
206    {
207        ObjectWorldLoader wloader(*this);
208        TypeContainerVisitor<ObjectWorldLoader, WorldTypeMapContainer > loader(wloader);
209        grid.Visit(loader);
210        i_corpses = wloader.i_corpses;
211    }
212}
213
214void ObjectGridLoader::LoadN(void)
215{
216    i_gameObjects = 0; i_creatures = 0; i_corpses = 0;
217    i_cell.data.Part.cell_y = 0;
218    for(unsigned int x=0; x < MAX_NUMBER_OF_CELLS; ++x)
219    {
220        i_cell.data.Part.cell_x = x;
221        for(unsigned int y=0; y < MAX_NUMBER_OF_CELLS; ++y)
222        {
223            i_cell.data.Part.cell_y = y;
224            GridLoader<Player, AllWorldObjectTypes, AllGridObjectTypes> loader;
225            loader.Load(i_grid(x, y), *this);
226        }
227    }
228    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());
229}
230
231void ObjectGridUnloader::MoveToRespawnN()
232{
233    for(unsigned int x=0; x < MAX_NUMBER_OF_CELLS; ++x)
234    {
235        for(unsigned int y=0; y < MAX_NUMBER_OF_CELLS; ++y)
236        {
237            ObjectGridRespawnMover mover;
238            mover.Move(i_grid(x, y));
239        }
240    }
241}
242
243void
244ObjectGridUnloader::Unload(GridType &grid)
245{
246    TypeContainerVisitor<ObjectGridUnloader, GridTypeMapContainer > unloader(*this);
247    grid.Visit(unloader);
248}
249
250template<class T>
251void
252ObjectGridUnloader::Visit(GridRefManager<T> &m)
253{
254    while(!m.isEmpty())
255    {
256        T *obj = m.getFirst()->getSource();
257        // if option set then object already saved at this moment
258        if(!sWorld.getConfig(CONFIG_SAVE_RESPAWN_TIME_IMMEDIATLY))
259            obj->SaveRespawnTime();
260        ///- object must be out of world before delete
261        obj->RemoveFromWorld();
262        ///- object will get delinked from the manager when deleted
263        delete obj;
264    }
265}
266
267template<>
268void
269ObjectGridUnloader::Visit(CreatureMapType &m)
270{
271    // remove all cross-reference before deleting
272    for(CreatureMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
273        iter->getSource()->CleanupsBeforeDelete();
274
275    while(!m.isEmpty())
276    {
277        Creature *obj = m.getFirst()->getSource();
278        // if option set then object already saved at this moment
279        if(!sWorld.getConfig(CONFIG_SAVE_RESPAWN_TIME_IMMEDIATLY))
280            obj->SaveRespawnTime();
281        ///- object will get delinked from the manager when deleted
282        delete obj;
283    }
284}
285
286void
287ObjectGridStoper::Stop(GridType &grid)
288{
289    TypeContainerVisitor<ObjectGridStoper, GridTypeMapContainer > stoper(*this);
290    grid.Visit(stoper);
291}
292
293void
294ObjectGridStoper::Visit(CreatureMapType &m)
295{
296    // stop any fights at grid de-activation and remove dynobjects created at cast by creatures
297    for(CreatureMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
298    {
299        iter->getSource()->CombatStop();
300        iter->getSource()->DeleteThreatList();
301        iter->getSource()->RemoveAllDynObjects();
302    }
303}
304
305template void ObjectGridUnloader::Visit(GameObjectMapType &);
306template void ObjectGridUnloader::Visit(DynamicObjectMapType &);
Note: See TracBrowser for help on using the browser.