mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-30 17:13:47 +00:00
First Commit
For Azeroth!
This commit is contained in:
120
src/server/game/Grids/Cells/Cell.h
Normal file
120
src/server/game/Grids/Cells/Cell.h
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef TRINITY_CELL_H
|
||||
#define TRINITY_CELL_H
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "TypeContainer.h"
|
||||
#include "TypeContainerVisitor.h"
|
||||
|
||||
#include "GridDefines.h"
|
||||
|
||||
class Map;
|
||||
class WorldObject;
|
||||
|
||||
struct CellArea
|
||||
{
|
||||
CellArea() {}
|
||||
CellArea(CellCoord low, CellCoord high) : low_bound(low), high_bound(high) {}
|
||||
|
||||
bool operator!() const { return low_bound == high_bound; }
|
||||
|
||||
void ResizeBorders(CellCoord& begin_cell, CellCoord& end_cell) const
|
||||
{
|
||||
begin_cell = low_bound;
|
||||
end_cell = high_bound;
|
||||
}
|
||||
|
||||
CellCoord low_bound;
|
||||
CellCoord high_bound;
|
||||
};
|
||||
|
||||
struct Cell
|
||||
{
|
||||
Cell() { data.All = 0; }
|
||||
Cell(Cell const& cell) { data.All = cell.data.All; }
|
||||
explicit Cell(CellCoord const& p);
|
||||
explicit Cell(float x, float y);
|
||||
|
||||
void Compute(uint32 &x, uint32 &y) const
|
||||
{
|
||||
x = data.Part.grid_x * MAX_NUMBER_OF_CELLS + data.Part.cell_x;
|
||||
y = data.Part.grid_y * MAX_NUMBER_OF_CELLS + data.Part.cell_y;
|
||||
}
|
||||
|
||||
bool DiffCell(const Cell &cell) const
|
||||
{
|
||||
return(data.Part.cell_x != cell.data.Part.cell_x ||
|
||||
data.Part.cell_y != cell.data.Part.cell_y);
|
||||
}
|
||||
|
||||
bool DiffGrid(const Cell &cell) const
|
||||
{
|
||||
return(data.Part.grid_x != cell.data.Part.grid_x ||
|
||||
data.Part.grid_y != cell.data.Part.grid_y);
|
||||
}
|
||||
|
||||
uint32 CellX() const { return data.Part.cell_x; }
|
||||
uint32 CellY() const { return data.Part.cell_y; }
|
||||
uint32 GridX() const { return data.Part.grid_x; }
|
||||
uint32 GridY() const { return data.Part.grid_y; }
|
||||
bool NoCreate() const { return data.Part.nocreate; }
|
||||
void SetNoCreate() { data.Part.nocreate = 1; }
|
||||
|
||||
CellCoord GetCellCoord() const
|
||||
{
|
||||
return CellCoord(
|
||||
data.Part.grid_x * MAX_NUMBER_OF_CELLS+data.Part.cell_x,
|
||||
data.Part.grid_y * MAX_NUMBER_OF_CELLS+data.Part.cell_y);
|
||||
}
|
||||
|
||||
Cell& operator=(Cell const& cell)
|
||||
{
|
||||
this->data.All = cell.data.All;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator == (Cell const& cell) const { return (data.All == cell.data.All); }
|
||||
bool operator != (Cell const& cell) const { return !operator == (cell); }
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
unsigned grid_x : 6;
|
||||
unsigned grid_y : 6;
|
||||
unsigned cell_x : 6;
|
||||
unsigned cell_y : 6;
|
||||
unsigned nocreate : 1;
|
||||
unsigned reserved : 7;
|
||||
} Part;
|
||||
uint32 All;
|
||||
} data;
|
||||
|
||||
template<class T, class CONTAINER> void Visit(CellCoord const&, TypeContainerVisitor<T, CONTAINER>& visitor, Map &, WorldObject const&, float) const;
|
||||
template<class T, class CONTAINER> void Visit(CellCoord const&, TypeContainerVisitor<T, CONTAINER>& visitor, Map &, float, float, float) const;
|
||||
|
||||
static CellArea CalculateCellArea(float x, float y, float radius);
|
||||
|
||||
private:
|
||||
template<class T, class CONTAINER> void VisitCircle(TypeContainerVisitor<T, CONTAINER> &, Map &, CellCoord const&, CellCoord const&) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
181
src/server/game/Grids/Cells/CellImpl.h
Normal file
181
src/server/game/Grids/Cells/CellImpl.h
Normal file
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef TRINITY_CELLIMPL_H
|
||||
#define TRINITY_CELLIMPL_H
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "Cell.h"
|
||||
#include "Map.h"
|
||||
#include "Object.h"
|
||||
|
||||
inline Cell::Cell(CellCoord const& p)
|
||||
{
|
||||
data.Part.grid_x = p.x_coord / MAX_NUMBER_OF_CELLS;
|
||||
data.Part.grid_y = p.y_coord / MAX_NUMBER_OF_CELLS;
|
||||
data.Part.cell_x = p.x_coord % MAX_NUMBER_OF_CELLS;
|
||||
data.Part.cell_y = p.y_coord % MAX_NUMBER_OF_CELLS;
|
||||
data.Part.nocreate = 0;
|
||||
data.Part.reserved = 0;
|
||||
}
|
||||
|
||||
inline Cell::Cell(float x, float y)
|
||||
{
|
||||
CellCoord p = Trinity::ComputeCellCoord(x, y);
|
||||
data.Part.grid_x = p.x_coord / MAX_NUMBER_OF_CELLS;
|
||||
data.Part.grid_y = p.y_coord / MAX_NUMBER_OF_CELLS;
|
||||
data.Part.cell_x = p.x_coord % MAX_NUMBER_OF_CELLS;
|
||||
data.Part.cell_y = p.y_coord % MAX_NUMBER_OF_CELLS;
|
||||
data.Part.nocreate = 0;
|
||||
data.Part.reserved = 0;
|
||||
}
|
||||
|
||||
inline CellArea Cell::CalculateCellArea(float x, float y, float radius)
|
||||
{
|
||||
if (radius <= 0.0f)
|
||||
{
|
||||
CellCoord center = Trinity::ComputeCellCoord(x, y).normalize();
|
||||
return CellArea(center, center);
|
||||
}
|
||||
|
||||
CellCoord centerX = Trinity::ComputeCellCoord(x - radius, y - radius).normalize();
|
||||
CellCoord centerY = Trinity::ComputeCellCoord(x + radius, y + radius).normalize();
|
||||
|
||||
return CellArea(centerX, centerY);
|
||||
}
|
||||
|
||||
template<class T, class CONTAINER>
|
||||
inline void Cell::Visit(CellCoord const& standing_cell, TypeContainerVisitor<T, CONTAINER>& visitor, Map& map, float radius, float x_off, float y_off) const
|
||||
{
|
||||
if (!standing_cell.IsCoordValid())
|
||||
return;
|
||||
|
||||
//no jokes here... Actually placing ASSERT() here was good idea, but
|
||||
//we had some problems with DynamicObjects, which pass radius = 0.0f (DB issue?)
|
||||
//maybe it is better to just return when radius <= 0.0f?
|
||||
if (radius <= 0.0f)
|
||||
{
|
||||
map.Visit(*this, visitor);
|
||||
return;
|
||||
}
|
||||
//lets limit the upper value for search radius
|
||||
if (radius > SIZE_OF_GRIDS)
|
||||
radius = SIZE_OF_GRIDS;
|
||||
|
||||
//lets calculate object coord offsets from cell borders.
|
||||
CellArea area = Cell::CalculateCellArea(x_off, y_off, radius);
|
||||
//if radius fits inside standing cell
|
||||
if (!area)
|
||||
{
|
||||
map.Visit(*this, visitor);
|
||||
return;
|
||||
}
|
||||
|
||||
//visit all cells, found in CalculateCellArea()
|
||||
//if radius is known to reach cell area more than 4x4 then we should call optimized VisitCircle
|
||||
//currently this technique works with MAX_NUMBER_OF_CELLS 16 and higher, with lower values
|
||||
//there are nothing to optimize because SIZE_OF_GRID_CELL is too big...
|
||||
if ((area.high_bound.x_coord > (area.low_bound.x_coord + 4)) && (area.high_bound.y_coord > (area.low_bound.y_coord + 4)))
|
||||
{
|
||||
VisitCircle(visitor, map, area.low_bound, area.high_bound);
|
||||
return;
|
||||
}
|
||||
|
||||
//ALWAYS visit standing cell first!!! Since we deal with small radiuses
|
||||
//it is very essential to call visitor for standing cell firstly...
|
||||
map.Visit(*this, visitor);
|
||||
|
||||
// loop the cell range
|
||||
for (uint32 x = area.low_bound.x_coord; x <= area.high_bound.x_coord; ++x)
|
||||
{
|
||||
for (uint32 y = area.low_bound.y_coord; y <= area.high_bound.y_coord; ++y)
|
||||
{
|
||||
CellCoord cellCoord(x, y);
|
||||
//lets skip standing cell since we already visited it
|
||||
if (cellCoord != standing_cell)
|
||||
{
|
||||
Cell r_zone(cellCoord);
|
||||
r_zone.data.Part.nocreate = this->data.Part.nocreate;
|
||||
map.Visit(r_zone, visitor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class T, class CONTAINER>
|
||||
inline void Cell::Visit(CellCoord const& standing_cell, TypeContainerVisitor<T, CONTAINER>& visitor, Map& map, WorldObject const& obj, float radius) const
|
||||
{
|
||||
//we should increase search radius by object's radius, otherwise
|
||||
//we could have problems with huge creatures, which won't attack nearest players etc
|
||||
Visit(standing_cell, visitor, map, radius + obj.GetObjectSize(), obj.GetPositionX(), obj.GetPositionY());
|
||||
}
|
||||
|
||||
template<class T, class CONTAINER>
|
||||
inline void Cell::VisitCircle(TypeContainerVisitor<T, CONTAINER>& visitor, Map& map, CellCoord const& begin_cell, CellCoord const& end_cell) const
|
||||
{
|
||||
//here is an algorithm for 'filling' circum-squared octagon
|
||||
uint32 x_shift = (uint32)ceilf((end_cell.x_coord - begin_cell.x_coord) * 0.3f - 0.5f);
|
||||
//lets calculate x_start/x_end coords for central strip...
|
||||
const uint32 x_start = begin_cell.x_coord + x_shift;
|
||||
const uint32 x_end = end_cell.x_coord - x_shift;
|
||||
|
||||
//visit central strip with constant width...
|
||||
for (uint32 x = x_start; x <= x_end; ++x)
|
||||
{
|
||||
for (uint32 y = begin_cell.y_coord; y <= end_cell.y_coord; ++y)
|
||||
{
|
||||
CellCoord cellCoord(x, y);
|
||||
Cell r_zone(cellCoord);
|
||||
r_zone.data.Part.nocreate = this->data.Part.nocreate;
|
||||
map.Visit(r_zone, visitor);
|
||||
}
|
||||
}
|
||||
|
||||
//if x_shift == 0 then we have too small cell area, which were already
|
||||
//visited at previous step, so just return from procedure...
|
||||
if (x_shift == 0)
|
||||
return;
|
||||
|
||||
uint32 y_start = end_cell.y_coord;
|
||||
uint32 y_end = begin_cell.y_coord;
|
||||
//now we are visiting borders of an octagon...
|
||||
for (uint32 step = 1; step <= (x_start - begin_cell.x_coord); ++step)
|
||||
{
|
||||
//each step reduces strip height by 2 cells...
|
||||
y_end += 1;
|
||||
y_start -= 1;
|
||||
for (uint32 y = y_start; y >= y_end; --y)
|
||||
{
|
||||
//we visit cells symmetrically from both sides, heading from center to sides and from up to bottom
|
||||
//e.g. filling 2 trapezoids after filling central cell strip...
|
||||
CellCoord cellCoord_left(x_start - step, y);
|
||||
Cell r_zone_left(cellCoord_left);
|
||||
r_zone_left.data.Part.nocreate = this->data.Part.nocreate;
|
||||
map.Visit(r_zone_left, visitor);
|
||||
|
||||
//right trapezoid cell visit
|
||||
CellCoord cellCoord_right(x_end + step, y);
|
||||
Cell r_zone_right(cellCoord_right);
|
||||
r_zone_right.data.Part.nocreate = this->data.Part.nocreate;
|
||||
map.Visit(r_zone_right, visitor);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
135
src/server/game/Grids/Grid.h
Normal file
135
src/server/game/Grids/Grid.h
Normal file
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef TRINITY_GRID_H
|
||||
#define TRINITY_GRID_H
|
||||
|
||||
/*
|
||||
@class Grid
|
||||
Grid is a logical segment of the game world represented inside TrinIty.
|
||||
Grid is bind at compile time to a particular type of object which
|
||||
we call it the object of interested. There are many types of loader,
|
||||
specially, dynamic loader, static loader, or on-demand loader. There's
|
||||
a subtle difference between dynamic loader and on-demand loader but
|
||||
this is implementation specific to the loader class. From the
|
||||
Grid's perspective, the loader meets its API requirement is suffice.
|
||||
*/
|
||||
|
||||
#include "Define.h"
|
||||
#include "TypeContainer.h"
|
||||
#include "TypeContainerVisitor.h"
|
||||
|
||||
// forward declaration
|
||||
template<class A, class T, class O> class GridLoader;
|
||||
|
||||
template
|
||||
<
|
||||
class ACTIVE_OBJECT,
|
||||
class WORLD_OBJECT_TYPES,
|
||||
class GRID_OBJECT_TYPES
|
||||
>
|
||||
class Grid
|
||||
{
|
||||
// allows the GridLoader to access its internals
|
||||
template<class A, class T, class O> friend class GridLoader;
|
||||
public:
|
||||
|
||||
/** destructor to clean up its resources. This includes unloading the
|
||||
grid if it has not been unload.
|
||||
*/
|
||||
~Grid() {}
|
||||
|
||||
/** an object of interested enters the grid
|
||||
*/
|
||||
template<class SPECIFIC_OBJECT> void AddWorldObject(SPECIFIC_OBJECT *obj)
|
||||
{
|
||||
i_objects.template insert<SPECIFIC_OBJECT>(obj);
|
||||
ASSERT(obj->IsInGrid());
|
||||
}
|
||||
|
||||
/** an object of interested exits the grid
|
||||
*/
|
||||
//Actually an unlink is enough, no need to go through the container
|
||||
//template<class SPECIFIC_OBJECT> void RemoveWorldObject(SPECIFIC_OBJECT *obj)
|
||||
//{
|
||||
// ASSERT(obj->GetGridRef().isValid());
|
||||
// i_objects.template remove<SPECIFIC_OBJECT>(obj);
|
||||
// ASSERT(!obj->GetGridRef().isValid());
|
||||
//}
|
||||
|
||||
/** Refreshes/update the grid. This required for remote grids.
|
||||
*/
|
||||
//void RefreshGrid(void) { /* TBI */}
|
||||
|
||||
/** Locks a grid. Any object enters must wait until the grid is unlock.
|
||||
*/
|
||||
//void LockGrid(void) { /* TBI */ }
|
||||
|
||||
/** Unlocks the grid.
|
||||
*/
|
||||
//void UnlockGrid(void) { /* TBI */ }
|
||||
|
||||
// Visit grid objects
|
||||
template<class T>
|
||||
void Visit(TypeContainerVisitor<T, TypeMapContainer<GRID_OBJECT_TYPES> > &visitor)
|
||||
{
|
||||
visitor.Visit(i_container);
|
||||
}
|
||||
|
||||
// Visit world objects
|
||||
template<class T>
|
||||
void Visit(TypeContainerVisitor<T, TypeMapContainer<WORLD_OBJECT_TYPES> > &visitor)
|
||||
{
|
||||
visitor.Visit(i_objects);
|
||||
}
|
||||
|
||||
/** Inserts a container type object into the grid.
|
||||
*/
|
||||
template<class SPECIFIC_OBJECT> void AddGridObject(SPECIFIC_OBJECT *obj)
|
||||
{
|
||||
i_container.template insert<SPECIFIC_OBJECT>(obj);
|
||||
ASSERT(obj->IsInGrid());
|
||||
}
|
||||
|
||||
/** Removes a containter type object from the grid
|
||||
*/
|
||||
//template<class SPECIFIC_OBJECT> void RemoveGridObject(SPECIFIC_OBJECT *obj)
|
||||
//{
|
||||
// ASSERT(obj->GetGridRef().isValid());
|
||||
// i_container.template remove<SPECIFIC_OBJECT>(obj);
|
||||
// ASSERT(!obj->GetGridRef().isValid());
|
||||
//}
|
||||
|
||||
/*bool NoWorldObjectInGrid() const
|
||||
{
|
||||
return i_objects.GetElements().isEmpty();
|
||||
}
|
||||
|
||||
bool NoGridObjectInGrid() const
|
||||
{
|
||||
return i_container.GetElements().isEmpty();
|
||||
}*/
|
||||
private:
|
||||
|
||||
TypeMapContainer<GRID_OBJECT_TYPES> i_container;
|
||||
TypeMapContainer<WORLD_OBJECT_TYPES> i_objects;
|
||||
//typedef std::set<void*> ActiveGridObjects;
|
||||
//ActiveGridObjects m_activeGridObjects;
|
||||
};
|
||||
#endif
|
||||
|
||||
236
src/server/game/Grids/GridDefines.h
Normal file
236
src/server/game/Grids/GridDefines.h
Normal file
@@ -0,0 +1,236 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef TRINITY_GRIDDEFINES_H
|
||||
#define TRINITY_GRIDDEFINES_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "NGrid.h"
|
||||
#include <cmath>
|
||||
|
||||
// Forward class definitions
|
||||
class Corpse;
|
||||
class Creature;
|
||||
class DynamicObject;
|
||||
class GameObject;
|
||||
class Pet;
|
||||
class Player;
|
||||
|
||||
#define MAX_NUMBER_OF_CELLS 8
|
||||
|
||||
#define MAX_NUMBER_OF_GRIDS 64
|
||||
|
||||
#define SIZE_OF_GRIDS 533.33333f
|
||||
#define CENTER_GRID_ID (MAX_NUMBER_OF_GRIDS/2)
|
||||
|
||||
#define CENTER_GRID_OFFSET (SIZE_OF_GRIDS/2)
|
||||
|
||||
#define MIN_GRID_DELAY (MINUTE*IN_MILLISECONDS)
|
||||
#define MIN_MAP_UPDATE_DELAY 10
|
||||
|
||||
#define SIZE_OF_GRID_CELL (SIZE_OF_GRIDS/MAX_NUMBER_OF_CELLS)
|
||||
|
||||
#define CENTER_GRID_CELL_ID (MAX_NUMBER_OF_CELLS*MAX_NUMBER_OF_GRIDS/2)
|
||||
#define CENTER_GRID_CELL_OFFSET (SIZE_OF_GRID_CELL/2)
|
||||
|
||||
#define TOTAL_NUMBER_OF_CELLS_PER_MAP (MAX_NUMBER_OF_GRIDS*MAX_NUMBER_OF_CELLS)
|
||||
|
||||
#define MAP_RESOLUTION 128
|
||||
|
||||
#define MAP_SIZE (SIZE_OF_GRIDS*MAX_NUMBER_OF_GRIDS)
|
||||
#define MAP_HALFSIZE (MAP_SIZE/2)
|
||||
|
||||
// Creature used instead pet to simplify *::Visit templates (not required duplicate code for Creature->Pet case)
|
||||
typedef TYPELIST_5(GameObject, Player, Creature/*pets*/, Corpse/*resurrectable*/, DynamicObject/*farsight target*/) AllWorldObjectTypes;
|
||||
typedef TYPELIST_4(GameObject, Creature/*except pets*/, DynamicObject, Corpse/*Bones*/) AllGridObjectTypes;
|
||||
|
||||
typedef GridRefManager<Corpse> CorpseMapType;
|
||||
typedef GridRefManager<Creature> CreatureMapType;
|
||||
typedef GridRefManager<DynamicObject> DynamicObjectMapType;
|
||||
typedef GridRefManager<GameObject> GameObjectMapType;
|
||||
typedef GridRefManager<Player> PlayerMapType;
|
||||
|
||||
enum GridMapTypeMask
|
||||
{
|
||||
GRID_MAP_TYPE_MASK_CORPSE = 0x01,
|
||||
GRID_MAP_TYPE_MASK_CREATURE = 0x02,
|
||||
GRID_MAP_TYPE_MASK_DYNAMICOBJECT = 0x04,
|
||||
GRID_MAP_TYPE_MASK_GAMEOBJECT = 0x08,
|
||||
GRID_MAP_TYPE_MASK_PLAYER = 0x10,
|
||||
GRID_MAP_TYPE_MASK_ALL = 0x1F
|
||||
};
|
||||
|
||||
typedef Grid<Player, AllWorldObjectTypes, AllGridObjectTypes> GridType;
|
||||
typedef NGrid<MAX_NUMBER_OF_CELLS, Player, AllWorldObjectTypes, AllGridObjectTypes> NGridType;
|
||||
|
||||
typedef TypeMapContainer<AllGridObjectTypes> GridTypeMapContainer;
|
||||
typedef TypeMapContainer<AllWorldObjectTypes> WorldTypeMapContainer;
|
||||
|
||||
template<uint32 LIMIT>
|
||||
struct CoordPair
|
||||
{
|
||||
CoordPair(uint32 x=0, uint32 y=0)
|
||||
: x_coord(x)
|
||||
, y_coord(y)
|
||||
{}
|
||||
|
||||
CoordPair(const CoordPair<LIMIT> &obj)
|
||||
: x_coord(obj.x_coord)
|
||||
, y_coord(obj.y_coord)
|
||||
{}
|
||||
|
||||
CoordPair<LIMIT> & operator=(const CoordPair<LIMIT> &obj)
|
||||
{
|
||||
x_coord = obj.x_coord;
|
||||
y_coord = obj.y_coord;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void dec_x(uint32 val)
|
||||
{
|
||||
if (x_coord > val)
|
||||
x_coord -= val;
|
||||
else
|
||||
x_coord = 0;
|
||||
}
|
||||
|
||||
void inc_x(uint32 val)
|
||||
{
|
||||
if (x_coord + val < LIMIT)
|
||||
x_coord += val;
|
||||
else
|
||||
x_coord = LIMIT - 1;
|
||||
}
|
||||
|
||||
void dec_y(uint32 val)
|
||||
{
|
||||
if (y_coord > val)
|
||||
y_coord -= val;
|
||||
else
|
||||
y_coord = 0;
|
||||
}
|
||||
|
||||
void inc_y(uint32 val)
|
||||
{
|
||||
if (y_coord + val < LIMIT)
|
||||
y_coord += val;
|
||||
else
|
||||
y_coord = LIMIT - 1;
|
||||
}
|
||||
|
||||
bool IsCoordValid() const
|
||||
{
|
||||
return x_coord < LIMIT && y_coord < LIMIT;
|
||||
}
|
||||
|
||||
CoordPair& normalize()
|
||||
{
|
||||
x_coord = std::min(x_coord, LIMIT - 1);
|
||||
y_coord = std::min(y_coord, LIMIT - 1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
uint32 GetId() const
|
||||
{
|
||||
return y_coord * LIMIT + x_coord;
|
||||
}
|
||||
|
||||
uint32 x_coord;
|
||||
uint32 y_coord;
|
||||
};
|
||||
|
||||
template<uint32 LIMIT>
|
||||
bool operator==(const CoordPair<LIMIT> &p1, const CoordPair<LIMIT> &p2)
|
||||
{
|
||||
return (p1.x_coord == p2.x_coord && p1.y_coord == p2.y_coord);
|
||||
}
|
||||
|
||||
template<uint32 LIMIT>
|
||||
bool operator!=(const CoordPair<LIMIT> &p1, const CoordPair<LIMIT> &p2)
|
||||
{
|
||||
return !(p1 == p2);
|
||||
}
|
||||
|
||||
typedef CoordPair<MAX_NUMBER_OF_GRIDS> GridCoord;
|
||||
typedef CoordPair<TOTAL_NUMBER_OF_CELLS_PER_MAP> CellCoord;
|
||||
|
||||
namespace Trinity
|
||||
{
|
||||
template<class RET_TYPE, int CENTER_VAL>
|
||||
inline RET_TYPE Compute(float x, float y, float center_offset, float size)
|
||||
{
|
||||
// calculate and store temporary values in double format for having same result as same mySQL calculations
|
||||
double x_offset = (double(x) - center_offset)/size;
|
||||
double y_offset = (double(y) - center_offset)/size;
|
||||
|
||||
int x_val = int(x_offset + CENTER_VAL + 0.5f);
|
||||
int y_val = int(y_offset + CENTER_VAL + 0.5f);
|
||||
return RET_TYPE(x_val, y_val);
|
||||
}
|
||||
|
||||
inline GridCoord ComputeGridCoord(float x, float y)
|
||||
{
|
||||
return Compute<GridCoord, CENTER_GRID_ID>(x, y, CENTER_GRID_OFFSET, SIZE_OF_GRIDS);
|
||||
}
|
||||
|
||||
inline CellCoord ComputeCellCoord(float x, float y)
|
||||
{
|
||||
return Compute<CellCoord, CENTER_GRID_CELL_ID>(x, y, CENTER_GRID_CELL_OFFSET, SIZE_OF_GRID_CELL);
|
||||
}
|
||||
|
||||
inline CellCoord ComputeCellCoord(float x, float y, float &x_off, float &y_off)
|
||||
{
|
||||
double x_offset = (double(x) - CENTER_GRID_CELL_OFFSET)/SIZE_OF_GRID_CELL;
|
||||
double y_offset = (double(y) - CENTER_GRID_CELL_OFFSET)/SIZE_OF_GRID_CELL;
|
||||
|
||||
int x_val = int(x_offset + CENTER_GRID_CELL_ID + 0.5f);
|
||||
int y_val = int(y_offset + CENTER_GRID_CELL_ID + 0.5f);
|
||||
x_off = (float(x_offset) - x_val + CENTER_GRID_CELL_ID) * SIZE_OF_GRID_CELL;
|
||||
y_off = (float(y_offset) - y_val + CENTER_GRID_CELL_ID) * SIZE_OF_GRID_CELL;
|
||||
return CellCoord(x_val, y_val);
|
||||
}
|
||||
|
||||
inline void NormalizeMapCoord(float &c)
|
||||
{
|
||||
if (c > MAP_HALFSIZE - 0.5f)
|
||||
c = MAP_HALFSIZE - 0.5f;
|
||||
else if (c < -(MAP_HALFSIZE - 0.5f))
|
||||
c = -(MAP_HALFSIZE - 0.5f);
|
||||
}
|
||||
|
||||
inline bool IsValidMapCoord(float c)
|
||||
{
|
||||
return finite(c) && (std::fabs(c) <= MAP_HALFSIZE - 0.5f);
|
||||
}
|
||||
|
||||
inline bool IsValidMapCoord(float x, float y)
|
||||
{
|
||||
return IsValidMapCoord(x) && IsValidMapCoord(y);
|
||||
}
|
||||
|
||||
inline bool IsValidMapCoord(float x, float y, float z)
|
||||
{
|
||||
return IsValidMapCoord(x, y) && finite(z);
|
||||
}
|
||||
|
||||
inline bool IsValidMapCoord(float x, float y, float z, float o)
|
||||
{
|
||||
return IsValidMapCoord(x, y, z) && finite(o);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
78
src/server/game/Grids/GridLoader.h
Normal file
78
src/server/game/Grids/GridLoader.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef TRINITY_GRIDLOADER_H
|
||||
#define TRINITY_GRIDLOADER_H
|
||||
|
||||
/**
|
||||
@class GridLoader
|
||||
The GridLoader is working in conjuction with the Grid and responsible
|
||||
for loading and unloading object-types (one or more) when objects
|
||||
enters a grid. Unloading is scheduled and might be canceled if
|
||||
an interested object re-enters. GridLoader does not do the actuall
|
||||
loading and unloading but implements as a template pattern that
|
||||
delicate its loading and unloading for the actualy loader and unloader.
|
||||
GridLoader manages the grid (both local and remote).
|
||||
*/
|
||||
|
||||
//I cannot see why this cannot be replaced by a Grid::Visit
|
||||
/*
|
||||
#include "Define.h"
|
||||
#include "Grid.h"
|
||||
#include "TypeContainerVisitor.h"
|
||||
|
||||
template
|
||||
<
|
||||
class ACTIVE_OBJECT,
|
||||
class WORLD_OBJECT_TYPES,
|
||||
class GRID_OBJECT_TYPES
|
||||
>
|
||||
class GridLoader
|
||||
{
|
||||
public:
|
||||
|
||||
// Loads the grid
|
||||
template<class LOADER>
|
||||
void Load(Grid<ACTIVE_OBJECT, WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES> &grid, LOADER &loader)
|
||||
{
|
||||
grid.LockGrid();
|
||||
loader.Load(grid);
|
||||
grid.UnlockGrid();
|
||||
}
|
||||
|
||||
// Stop the grid
|
||||
template<class STOPER>
|
||||
void Stop(Grid<ACTIVE_OBJECT, WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES> &grid, STOPER &stoper)
|
||||
{
|
||||
grid.LockGrid();
|
||||
stoper.Stop(grid);
|
||||
grid.UnlockGrid();
|
||||
}
|
||||
|
||||
// Unloads the grid
|
||||
template<class UNLOADER>
|
||||
void Unload(Grid<ACTIVE_OBJECT, WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES> &grid, UNLOADER &unloader)
|
||||
{
|
||||
grid.LockGrid();
|
||||
unloader.Unload(grid);
|
||||
grid.UnlockGrid();
|
||||
}
|
||||
};
|
||||
*/
|
||||
#endif
|
||||
|
||||
42
src/server/game/Grids/GridRefManager.h
Normal file
42
src/server/game/Grids/GridRefManager.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef _GRIDREFMANAGER
|
||||
#define _GRIDREFMANAGER
|
||||
|
||||
#include "RefManager.h"
|
||||
|
||||
template<class OBJECT>
|
||||
class GridReference;
|
||||
|
||||
template<class OBJECT>
|
||||
class GridRefManager : public RefManager<GridRefManager<OBJECT>, OBJECT>
|
||||
{
|
||||
public:
|
||||
typedef LinkedListHead::Iterator< GridReference<OBJECT> > iterator;
|
||||
|
||||
GridReference<OBJECT>* getFirst() { return (GridReference<OBJECT>*)RefManager<GridRefManager<OBJECT>, OBJECT>::getFirst(); }
|
||||
GridReference<OBJECT>* getLast() { return (GridReference<OBJECT>*)RefManager<GridRefManager<OBJECT>, OBJECT>::getLast(); }
|
||||
|
||||
iterator begin() { return iterator(getFirst()); }
|
||||
iterator end() { return iterator(NULL); }
|
||||
iterator rbegin() { return iterator(getLast()); }
|
||||
iterator rend() { return iterator(NULL); }
|
||||
};
|
||||
#endif
|
||||
|
||||
53
src/server/game/Grids/GridReference.h
Normal file
53
src/server/game/Grids/GridReference.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef _GRIDREFERENCE_H
|
||||
#define _GRIDREFERENCE_H
|
||||
|
||||
#include "LinkedReference/Reference.h"
|
||||
|
||||
template<class OBJECT>
|
||||
class GridRefManager;
|
||||
|
||||
template<class OBJECT>
|
||||
class GridReference : public Reference<GridRefManager<OBJECT>, OBJECT>
|
||||
{
|
||||
protected:
|
||||
void targetObjectBuildLink()
|
||||
{
|
||||
// called from link()
|
||||
this->getTarget()->insertFirst(this);
|
||||
this->getTarget()->incSize();
|
||||
}
|
||||
void targetObjectDestroyLink()
|
||||
{
|
||||
// called from unlink()
|
||||
if (this->isValid()) this->getTarget()->decSize();
|
||||
}
|
||||
void sourceObjectDestroyLink()
|
||||
{
|
||||
// called from invalidate()
|
||||
this->getTarget()->decSize();
|
||||
}
|
||||
public:
|
||||
GridReference() : Reference<GridRefManager<OBJECT>, OBJECT>() {}
|
||||
~GridReference() { this->unlink(); }
|
||||
GridReference* next() { return (GridReference*)Reference<GridRefManager<OBJECT>, OBJECT>::next(); }
|
||||
};
|
||||
#endif
|
||||
|
||||
117
src/server/game/Grids/NGrid.h
Normal file
117
src/server/game/Grids/NGrid.h
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef TRINITY_NGRID_H
|
||||
#define TRINITY_NGRID_H
|
||||
|
||||
/** NGrid is nothing more than a wrapper of the Grid with an NxN cells
|
||||
*/
|
||||
|
||||
#include "Grid.h"
|
||||
#include "GridReference.h"
|
||||
#include "Timer.h"
|
||||
#include "Util.h"
|
||||
|
||||
template
|
||||
<
|
||||
uint32 N,
|
||||
class ACTIVE_OBJECT,
|
||||
class WORLD_OBJECT_TYPES,
|
||||
class GRID_OBJECT_TYPES
|
||||
>
|
||||
class NGrid
|
||||
{
|
||||
public:
|
||||
typedef Grid<ACTIVE_OBJECT, WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES> GridType;
|
||||
NGrid(uint32 id, int32 x, int32 y)
|
||||
: i_gridId(id), i_x(x), i_y(y), i_GridObjectDataLoaded(false)
|
||||
{
|
||||
}
|
||||
|
||||
GridType& GetGridType(const uint32 x, const uint32 y)
|
||||
{
|
||||
ASSERT(x < N && y < N);
|
||||
return i_cells[x][y];
|
||||
}
|
||||
|
||||
GridType const& GetGridType(const uint32 x, const uint32 y) const
|
||||
{
|
||||
ASSERT(x < N && y < N);
|
||||
return i_cells[x][y];
|
||||
}
|
||||
|
||||
uint32 GetGridId(void) const { return i_gridId; }
|
||||
void SetGridId(const uint32 id) const { i_gridId = id; }
|
||||
int32 getX() const { return i_x; }
|
||||
int32 getY() const { return i_y; }
|
||||
|
||||
void link(GridRefManager<NGrid<N, ACTIVE_OBJECT, WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES> >* pTo)
|
||||
{
|
||||
i_Reference.link(pTo, this);
|
||||
}
|
||||
bool isGridObjectDataLoaded() const { return i_GridObjectDataLoaded; }
|
||||
void setGridObjectDataLoaded(bool pLoaded) { i_GridObjectDataLoaded = pLoaded; }
|
||||
|
||||
/*
|
||||
template<class SPECIFIC_OBJECT> void AddWorldObject(const uint32 x, const uint32 y, SPECIFIC_OBJECT *obj)
|
||||
{
|
||||
GetGridType(x, y).AddWorldObject(obj);
|
||||
}
|
||||
|
||||
template<class SPECIFIC_OBJECT> void RemoveWorldObject(const uint32 x, const uint32 y, SPECIFIC_OBJECT *obj)
|
||||
{
|
||||
GetGridType(x, y).RemoveWorldObject(obj);
|
||||
}
|
||||
|
||||
template<class SPECIFIC_OBJECT> void AddGridObject(const uint32 x, const uint32 y, SPECIFIC_OBJECT *obj)
|
||||
{
|
||||
GetGridType(x, y).AddGridObject(obj);
|
||||
}
|
||||
|
||||
template<class SPECIFIC_OBJECT> void RemoveGridObject(const uint32 x, const uint32 y, SPECIFIC_OBJECT *obj)
|
||||
{
|
||||
GetGridType(x, y).RemoveGridObject(obj);
|
||||
}
|
||||
*/
|
||||
|
||||
// Visit all Grids (cells) in NGrid (grid)
|
||||
template<class T, class TT>
|
||||
void VisitAllGrids(TypeContainerVisitor<T, TypeMapContainer<TT> > &visitor)
|
||||
{
|
||||
for (uint32 x = 0; x < N; ++x)
|
||||
for (uint32 y = 0; y < N; ++y)
|
||||
GetGridType(x, y).Visit(visitor);
|
||||
}
|
||||
|
||||
// Visit a single Grid (cell) in NGrid (grid)
|
||||
template<class T, class TT>
|
||||
void VisitGrid(const uint32 x, const uint32 y, TypeContainerVisitor<T, TypeMapContainer<TT> > &visitor)
|
||||
{
|
||||
GetGridType(x, y).Visit(visitor);
|
||||
}
|
||||
|
||||
private:
|
||||
uint32 i_gridId;
|
||||
GridReference<NGrid<N, ACTIVE_OBJECT, WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES> > i_Reference;
|
||||
int32 i_x;
|
||||
int32 i_y;
|
||||
GridType i_cells[N][N];
|
||||
bool i_GridObjectDataLoaded;
|
||||
};
|
||||
#endif
|
||||
|
||||
363
src/server/game/Grids/Notifiers/GridNotifiers.cpp
Normal file
363
src/server/game/Grids/Notifiers/GridNotifiers.cpp
Normal file
@@ -0,0 +1,363 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "GridNotifiers.h"
|
||||
#include "GridNotifiersImpl.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
#include "UpdateData.h"
|
||||
#include "Item.h"
|
||||
#include "Map.h"
|
||||
#include "Transport.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "CellImpl.h"
|
||||
#include "SpellInfo.h"
|
||||
|
||||
using namespace Trinity;
|
||||
|
||||
|
||||
void VisibleNotifier::Visit(GameObjectMapType &m)
|
||||
{
|
||||
for (GameObjectMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||
{
|
||||
vis_guids.erase(iter->GetSource()->GetGUID());
|
||||
i_player.UpdateVisibilityOf(iter->GetSource(), i_data, i_visibleNow);
|
||||
}
|
||||
}
|
||||
|
||||
void VisibleNotifier::SendToSelf()
|
||||
{
|
||||
// at this moment i_clientGUIDs have guids that not iterate at grid level checks
|
||||
// but exist one case when this possible and object not out of range: transports
|
||||
if (Transport* transport = i_player.GetTransport())
|
||||
for (Transport::PassengerSet::const_iterator itr = transport->GetPassengers().begin(); itr != transport->GetPassengers().end();++itr)
|
||||
{
|
||||
if (vis_guids.find((*itr)->GetGUID()) != vis_guids.end())
|
||||
{
|
||||
vis_guids.erase((*itr)->GetGUID());
|
||||
|
||||
switch ((*itr)->GetTypeId())
|
||||
{
|
||||
case TYPEID_GAMEOBJECT:
|
||||
i_player.UpdateVisibilityOf((*itr)->ToGameObject(), i_data, i_visibleNow);
|
||||
break;
|
||||
case TYPEID_PLAYER:
|
||||
i_player.UpdateVisibilityOf((*itr)->ToPlayer(), i_data, i_visibleNow);
|
||||
(*itr)->ToPlayer()->UpdateVisibilityOf(&i_player);
|
||||
break;
|
||||
case TYPEID_UNIT:
|
||||
i_player.UpdateVisibilityOf((*itr)->ToCreature(), i_data, i_visibleNow);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Player::ClientGUIDs::const_iterator it = vis_guids.begin();it != vis_guids.end(); ++it)
|
||||
{
|
||||
// pussywizard: static transports are removed only in RemovePlayerFromMap and here if can no longer detect (eg. phase changed)
|
||||
if (IS_TRANSPORT_GUID(*it))
|
||||
if (GameObject* staticTrans = i_player.GetMap()->GetGameObject(*it))
|
||||
if (i_player.CanSeeOrDetect(staticTrans, false, true))
|
||||
continue;
|
||||
|
||||
i_player.m_clientGUIDs.erase(*it);
|
||||
i_data.AddOutOfRangeGUID(*it);
|
||||
|
||||
if (IS_PLAYER_GUID(*it))
|
||||
{
|
||||
Player* player = ObjectAccessor::FindPlayer(*it);
|
||||
if (player && player->IsInMap(&i_player))
|
||||
player->UpdateVisibilityOf(&i_player);
|
||||
}
|
||||
}
|
||||
|
||||
if (!i_data.HasData())
|
||||
return;
|
||||
|
||||
WorldPacket packet;
|
||||
i_data.BuildPacket(&packet);
|
||||
i_player.GetSession()->SendPacket(&packet);
|
||||
|
||||
for (std::vector<Unit*>::const_iterator it = i_visibleNow.begin(); it != i_visibleNow.end(); ++it)
|
||||
i_player.GetInitialVisiblePackets(*it);
|
||||
}
|
||||
|
||||
void VisibleChangesNotifier::Visit(PlayerMapType &m)
|
||||
{
|
||||
for (PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||
{
|
||||
if (iter->GetSource() == &i_object)
|
||||
continue;
|
||||
|
||||
iter->GetSource()->UpdateVisibilityOf(&i_object);
|
||||
|
||||
if (iter->GetSource()->HasSharedVision())
|
||||
for (SharedVisionList::const_iterator i = iter->GetSource()->GetSharedVisionList().begin(); i != iter->GetSource()->GetSharedVisionList().end(); ++i)
|
||||
if ((*i)->m_seer == iter->GetSource())
|
||||
(*i)->UpdateVisibilityOf(&i_object);
|
||||
}
|
||||
}
|
||||
|
||||
void VisibleChangesNotifier::Visit(CreatureMapType &m)
|
||||
{
|
||||
for (CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||
if (iter->GetSource()->HasSharedVision())
|
||||
for (SharedVisionList::const_iterator i = iter->GetSource()->GetSharedVisionList().begin(); i != iter->GetSource()->GetSharedVisionList().end(); ++i)
|
||||
if ((*i)->m_seer == iter->GetSource())
|
||||
(*i)->UpdateVisibilityOf(&i_object);
|
||||
}
|
||||
|
||||
void VisibleChangesNotifier::Visit(DynamicObjectMapType &m)
|
||||
{
|
||||
for (DynamicObjectMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||
if (IS_PLAYER_GUID(iter->GetSource()->GetCasterGUID()))
|
||||
if (Unit* caster = iter->GetSource()->GetCaster())
|
||||
if (Player* player = caster->ToPlayer())
|
||||
if (player->m_seer == iter->GetSource())
|
||||
player->UpdateVisibilityOf(&i_object);
|
||||
}
|
||||
|
||||
inline void CreatureUnitRelocationWorker(Creature* c, Unit* u)
|
||||
{
|
||||
if (!u->IsAlive() || !c->IsAlive() || c == u || u->IsInFlight())
|
||||
return;
|
||||
|
||||
if (c->HasReactState(REACT_AGGRESSIVE) && !c->HasUnitState(UNIT_STATE_SIGHTLESS))
|
||||
if (c->IsAIEnabled && c->CanSeeOrDetect(u, false, true))
|
||||
c->AI()->MoveInLineOfSight_Safe(u);
|
||||
}
|
||||
|
||||
void PlayerRelocationNotifier::Visit(PlayerMapType &m)
|
||||
{
|
||||
for (PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||
{
|
||||
Player* player = iter->GetSource();
|
||||
vis_guids.erase(player->GetGUID());
|
||||
i_player.UpdateVisibilityOf(player, i_data, i_visibleNow);
|
||||
player->UpdateVisibilityOf(&i_player); // this notifier with different Visit(PlayerMapType&) than VisibleNotifier is needed to update visibility of self for other players when we move (eg. stealth detection changes)
|
||||
}
|
||||
}
|
||||
|
||||
void CreatureRelocationNotifier::Visit(PlayerMapType &m)
|
||||
{
|
||||
for (PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||
{
|
||||
Player* player = iter->GetSource();
|
||||
|
||||
// NOTIFY_VISIBILITY_CHANGED does not guarantee that player will do it himself (because distance is also checked), but screw it, it's not that important
|
||||
if (!player->m_seer->isNeedNotify(NOTIFY_VISIBILITY_CHANGED))
|
||||
player->UpdateVisibilityOf(&i_creature);
|
||||
|
||||
// NOTIFY_AI_RELOCATION does not guarantee that player will do it himself (because distance is also checked), but screw it, it's not that important
|
||||
if (!player->m_seer->isNeedNotify(NOTIFY_AI_RELOCATION) && !i_creature.IsMoveInLineOfSightStrictlyDisabled())
|
||||
CreatureUnitRelocationWorker(&i_creature, player);
|
||||
}
|
||||
}
|
||||
|
||||
void AIRelocationNotifier::Visit(CreatureMapType &m)
|
||||
{
|
||||
bool self = isCreature && !((Creature*)(&i_unit))->IsMoveInLineOfSightStrictlyDisabled();
|
||||
for (CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||
{
|
||||
Creature* c = iter->GetSource();
|
||||
|
||||
// NOTIFY_VISIBILITY_CHANGED | NOTIFY_AI_RELOCATION does not guarantee that unit will do it itself (because distance is also checked), but screw it, it's not that important
|
||||
if (!c->isNeedNotify(NOTIFY_VISIBILITY_CHANGED | NOTIFY_AI_RELOCATION) && !c->IsMoveInLineOfSightStrictlyDisabled())
|
||||
CreatureUnitRelocationWorker(c, &i_unit);
|
||||
|
||||
if (self)
|
||||
CreatureUnitRelocationWorker((Creature*)&i_unit, c);
|
||||
}
|
||||
}
|
||||
|
||||
void MessageDistDeliverer::Visit(PlayerMapType &m)
|
||||
{
|
||||
for (PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||
{
|
||||
Player* target = iter->GetSource();
|
||||
if (!target->InSamePhase(i_phaseMask))
|
||||
continue;
|
||||
|
||||
if (target->GetExactDist2dSq(i_source) > i_distSq)
|
||||
continue;
|
||||
|
||||
// Send packet to all who are sharing the player's vision
|
||||
if (target->HasSharedVision())
|
||||
{
|
||||
SharedVisionList::const_iterator i = target->GetSharedVisionList().begin();
|
||||
for (; i != target->GetSharedVisionList().end(); ++i)
|
||||
if ((*i)->m_seer == target)
|
||||
SendPacket(*i);
|
||||
}
|
||||
|
||||
if (target->m_seer == target || target->GetVehicle())
|
||||
SendPacket(target);
|
||||
}
|
||||
}
|
||||
|
||||
void MessageDistDeliverer::Visit(CreatureMapType &m)
|
||||
{
|
||||
for (CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||
{
|
||||
Creature* target = iter->GetSource();
|
||||
if (!target->HasSharedVision() || !target->InSamePhase(i_phaseMask))
|
||||
continue;
|
||||
|
||||
if (target->GetExactDist2dSq(i_source) > i_distSq)
|
||||
continue;
|
||||
|
||||
// Send packet to all who are sharing the creature's vision
|
||||
SharedVisionList::const_iterator i = target->GetSharedVisionList().begin();
|
||||
for (; i != target->GetSharedVisionList().end(); ++i)
|
||||
if ((*i)->m_seer == target)
|
||||
SendPacket(*i);
|
||||
}
|
||||
}
|
||||
|
||||
void MessageDistDeliverer::Visit(DynamicObjectMapType &m)
|
||||
{
|
||||
for (DynamicObjectMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||
{
|
||||
DynamicObject* target = iter->GetSource();
|
||||
if (!IS_PLAYER_GUID(target->GetCasterGUID()) || !target->InSamePhase(i_phaseMask))
|
||||
continue;
|
||||
|
||||
// Xinef: Check whether the dynobject allows to see through it
|
||||
if (!target->IsViewpoint())
|
||||
continue;
|
||||
|
||||
if (target->GetExactDist2dSq(i_source) > i_distSq)
|
||||
continue;
|
||||
|
||||
// Send packet back to the caster if the caster has vision of dynamic object
|
||||
Player* caster = (Player*)target->GetCaster();
|
||||
if (caster && caster->m_seer == target)
|
||||
SendPacket(caster);
|
||||
}
|
||||
}
|
||||
|
||||
void MessageDistDelivererToHostile::Visit(PlayerMapType &m)
|
||||
{
|
||||
for (PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||
{
|
||||
Player* target = iter->GetSource();
|
||||
if (!target->InSamePhase(i_phaseMask))
|
||||
continue;
|
||||
|
||||
if (target->GetExactDist2dSq(i_source) > i_distSq)
|
||||
continue;
|
||||
|
||||
// Send packet to all who are sharing the player's vision
|
||||
if (target->HasSharedVision())
|
||||
{
|
||||
SharedVisionList::const_iterator i = target->GetSharedVisionList().begin();
|
||||
for (; i != target->GetSharedVisionList().end(); ++i)
|
||||
if ((*i)->m_seer == target)
|
||||
SendPacket(*i);
|
||||
}
|
||||
|
||||
if (target->m_seer == target || target->GetVehicle())
|
||||
SendPacket(target);
|
||||
}
|
||||
}
|
||||
|
||||
void MessageDistDelivererToHostile::Visit(CreatureMapType &m)
|
||||
{
|
||||
for (CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||
{
|
||||
Creature* target = iter->GetSource();
|
||||
if (!target->HasSharedVision() || !target->InSamePhase(i_phaseMask))
|
||||
continue;
|
||||
|
||||
if (target->GetExactDist2dSq(i_source) > i_distSq)
|
||||
continue;
|
||||
|
||||
// Send packet to all who are sharing the creature's vision
|
||||
SharedVisionList::const_iterator i = target->GetSharedVisionList().begin();
|
||||
for (; i != target->GetSharedVisionList().end(); ++i)
|
||||
if ((*i)->m_seer == target)
|
||||
SendPacket(*i);
|
||||
}
|
||||
}
|
||||
|
||||
void MessageDistDelivererToHostile::Visit(DynamicObjectMapType &m)
|
||||
{
|
||||
for (DynamicObjectMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||
{
|
||||
DynamicObject* target = iter->GetSource();
|
||||
if (!IS_PLAYER_GUID(target->GetCasterGUID()) || !target->InSamePhase(i_phaseMask))
|
||||
continue;
|
||||
|
||||
if (target->GetExactDist2dSq(i_source) > i_distSq)
|
||||
continue;
|
||||
|
||||
// Send packet back to the caster if the caster has vision of dynamic object
|
||||
Player* caster = (Player*)target->GetCaster();
|
||||
if (caster && caster->m_seer == target)
|
||||
SendPacket(caster);
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void ObjectUpdater::Visit(GridRefManager<T> &m)
|
||||
{
|
||||
T* obj;
|
||||
for (typename GridRefManager<T>::iterator iter = m.begin(); iter != m.end(); )
|
||||
{
|
||||
obj = iter->GetSource();
|
||||
++iter;
|
||||
if (obj->IsInWorld())
|
||||
obj->Update(i_timeDiff);
|
||||
}
|
||||
}
|
||||
|
||||
bool AnyDeadUnitObjectInRangeCheck::operator()(Player* u)
|
||||
{
|
||||
return !u->IsAlive() && !u->HasAuraType(SPELL_AURA_GHOST) && i_searchObj->IsWithinDistInMap(u, i_range);
|
||||
}
|
||||
|
||||
bool AnyDeadUnitObjectInRangeCheck::operator()(Corpse* u)
|
||||
{
|
||||
return u->GetType() != CORPSE_BONES && i_searchObj->IsWithinDistInMap(u, i_range);
|
||||
}
|
||||
|
||||
bool AnyDeadUnitObjectInRangeCheck::operator()(Creature* u)
|
||||
{
|
||||
return !u->IsAlive() && i_searchObj->IsWithinDistInMap(u, i_range);
|
||||
}
|
||||
|
||||
bool AnyDeadUnitSpellTargetInRangeCheck::operator()(Player* u)
|
||||
{
|
||||
return AnyDeadUnitObjectInRangeCheck::operator()(u) && i_check(u);
|
||||
}
|
||||
|
||||
bool AnyDeadUnitSpellTargetInRangeCheck::operator()(Corpse* u)
|
||||
{
|
||||
return AnyDeadUnitObjectInRangeCheck::operator()(u) && i_check(u);
|
||||
}
|
||||
|
||||
bool AnyDeadUnitSpellTargetInRangeCheck::operator()(Creature* u)
|
||||
{
|
||||
return AnyDeadUnitObjectInRangeCheck::operator()(u) && i_check(u);
|
||||
}
|
||||
|
||||
template void ObjectUpdater::Visit<Creature>(CreatureMapType&);
|
||||
template void ObjectUpdater::Visit<GameObject>(GameObjectMapType&);
|
||||
template void ObjectUpdater::Visit<DynamicObject>(DynamicObjectMapType&);
|
||||
1536
src/server/game/Grids/Notifiers/GridNotifiers.h
Normal file
1536
src/server/game/Grids/Notifiers/GridNotifiers.h
Normal file
File diff suppressed because it is too large
Load Diff
586
src/server/game/Grids/Notifiers/GridNotifiersImpl.h
Normal file
586
src/server/game/Grids/Notifiers/GridNotifiersImpl.h
Normal file
@@ -0,0 +1,586 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef TRINITY_GRIDNOTIFIERSIMPL_H
|
||||
#define TRINITY_GRIDNOTIFIERSIMPL_H
|
||||
|
||||
#include "GridNotifiers.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "Corpse.h"
|
||||
#include "Player.h"
|
||||
#include "UpdateData.h"
|
||||
#include "CreatureAI.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "Opcodes.h"
|
||||
|
||||
template<class T>
|
||||
inline void Trinity::VisibleNotifier::Visit(GridRefManager<T> &m)
|
||||
{
|
||||
// Xinef: Update gameobjects only
|
||||
if (i_gobjOnly)
|
||||
return;
|
||||
|
||||
for (typename GridRefManager<T>::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||
{
|
||||
vis_guids.erase(iter->GetSource()->GetGUID());
|
||||
i_player.UpdateVisibilityOf(iter->GetSource(), i_data, i_visibleNow);
|
||||
}
|
||||
}
|
||||
|
||||
// SEARCHERS & LIST SEARCHERS & WORKERS
|
||||
|
||||
// WorldObject searchers & workers
|
||||
|
||||
template<class Check>
|
||||
void Trinity::WorldObjectSearcher<Check>::Visit(GameObjectMapType &m)
|
||||
{
|
||||
if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_GAMEOBJECT))
|
||||
return;
|
||||
|
||||
// already found
|
||||
if (i_object)
|
||||
return;
|
||||
|
||||
for (GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
|
||||
{
|
||||
if (!itr->GetSource()->InSamePhase(i_phaseMask))
|
||||
continue;
|
||||
|
||||
if (i_check(itr->GetSource()))
|
||||
{
|
||||
i_object = itr->GetSource();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class Check>
|
||||
void Trinity::WorldObjectSearcher<Check>::Visit(PlayerMapType &m)
|
||||
{
|
||||
if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_PLAYER))
|
||||
return;
|
||||
|
||||
// already found
|
||||
if (i_object)
|
||||
return;
|
||||
|
||||
for (PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
|
||||
{
|
||||
if (!itr->GetSource()->InSamePhase(i_phaseMask))
|
||||
continue;
|
||||
|
||||
if (i_check(itr->GetSource()))
|
||||
{
|
||||
i_object = itr->GetSource();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class Check>
|
||||
void Trinity::WorldObjectSearcher<Check>::Visit(CreatureMapType &m)
|
||||
{
|
||||
if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_CREATURE))
|
||||
return;
|
||||
|
||||
// already found
|
||||
if (i_object)
|
||||
return;
|
||||
|
||||
for (CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
|
||||
{
|
||||
if (!itr->GetSource()->InSamePhase(i_phaseMask))
|
||||
continue;
|
||||
|
||||
if (i_check(itr->GetSource()))
|
||||
{
|
||||
i_object = itr->GetSource();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class Check>
|
||||
void Trinity::WorldObjectSearcher<Check>::Visit(CorpseMapType &m)
|
||||
{
|
||||
if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_CORPSE))
|
||||
return;
|
||||
|
||||
// already found
|
||||
if (i_object)
|
||||
return;
|
||||
|
||||
for (CorpseMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
|
||||
{
|
||||
if (!itr->GetSource()->InSamePhase(i_phaseMask))
|
||||
continue;
|
||||
|
||||
if (i_check(itr->GetSource()))
|
||||
{
|
||||
i_object = itr->GetSource();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class Check>
|
||||
void Trinity::WorldObjectSearcher<Check>::Visit(DynamicObjectMapType &m)
|
||||
{
|
||||
if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_DYNAMICOBJECT))
|
||||
return;
|
||||
|
||||
// already found
|
||||
if (i_object)
|
||||
return;
|
||||
|
||||
for (DynamicObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
|
||||
{
|
||||
if (!itr->GetSource()->InSamePhase(i_phaseMask))
|
||||
continue;
|
||||
|
||||
if (i_check(itr->GetSource()))
|
||||
{
|
||||
i_object = itr->GetSource();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Check>
|
||||
void Trinity::WorldObjectLastSearcher<Check>::Visit(GameObjectMapType &m)
|
||||
{
|
||||
if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_GAMEOBJECT))
|
||||
return;
|
||||
|
||||
for (GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
|
||||
{
|
||||
if (!itr->GetSource()->InSamePhase(i_phaseMask))
|
||||
continue;
|
||||
|
||||
if (i_check(itr->GetSource()))
|
||||
i_object = itr->GetSource();
|
||||
}
|
||||
}
|
||||
|
||||
template<class Check>
|
||||
void Trinity::WorldObjectLastSearcher<Check>::Visit(PlayerMapType &m)
|
||||
{
|
||||
if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_PLAYER))
|
||||
return;
|
||||
|
||||
for (PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
|
||||
{
|
||||
if (!itr->GetSource()->InSamePhase(i_phaseMask))
|
||||
continue;
|
||||
|
||||
if (i_check(itr->GetSource()))
|
||||
i_object = itr->GetSource();
|
||||
}
|
||||
}
|
||||
|
||||
template<class Check>
|
||||
void Trinity::WorldObjectLastSearcher<Check>::Visit(CreatureMapType &m)
|
||||
{
|
||||
if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_CREATURE))
|
||||
return;
|
||||
|
||||
for (CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
|
||||
{
|
||||
if (!itr->GetSource()->InSamePhase(i_phaseMask))
|
||||
continue;
|
||||
|
||||
if (i_check(itr->GetSource()))
|
||||
i_object = itr->GetSource();
|
||||
}
|
||||
}
|
||||
|
||||
template<class Check>
|
||||
void Trinity::WorldObjectLastSearcher<Check>::Visit(CorpseMapType &m)
|
||||
{
|
||||
if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_CORPSE))
|
||||
return;
|
||||
|
||||
for (CorpseMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
|
||||
{
|
||||
if (!itr->GetSource()->InSamePhase(i_phaseMask))
|
||||
continue;
|
||||
|
||||
if (i_check(itr->GetSource()))
|
||||
i_object = itr->GetSource();
|
||||
}
|
||||
}
|
||||
|
||||
template<class Check>
|
||||
void Trinity::WorldObjectLastSearcher<Check>::Visit(DynamicObjectMapType &m)
|
||||
{
|
||||
if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_DYNAMICOBJECT))
|
||||
return;
|
||||
|
||||
for (DynamicObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
|
||||
{
|
||||
if (!itr->GetSource()->InSamePhase(i_phaseMask))
|
||||
continue;
|
||||
|
||||
if (i_check(itr->GetSource()))
|
||||
i_object = itr->GetSource();
|
||||
}
|
||||
}
|
||||
|
||||
template<class Check>
|
||||
void Trinity::WorldObjectListSearcher<Check>::Visit(PlayerMapType &m)
|
||||
{
|
||||
if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_PLAYER))
|
||||
return;
|
||||
|
||||
for (PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
|
||||
if (i_check(itr->GetSource()))
|
||||
i_objects.push_back(itr->GetSource());
|
||||
}
|
||||
|
||||
template<class Check>
|
||||
void Trinity::WorldObjectListSearcher<Check>::Visit(CreatureMapType &m)
|
||||
{
|
||||
if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_CREATURE))
|
||||
return;
|
||||
|
||||
for (CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
|
||||
if (i_check(itr->GetSource()))
|
||||
i_objects.push_back(itr->GetSource());
|
||||
}
|
||||
|
||||
template<class Check>
|
||||
void Trinity::WorldObjectListSearcher<Check>::Visit(CorpseMapType &m)
|
||||
{
|
||||
if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_CORPSE))
|
||||
return;
|
||||
|
||||
for (CorpseMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
|
||||
if (i_check(itr->GetSource()))
|
||||
i_objects.push_back(itr->GetSource());
|
||||
}
|
||||
|
||||
template<class Check>
|
||||
void Trinity::WorldObjectListSearcher<Check>::Visit(GameObjectMapType &m)
|
||||
{
|
||||
if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_GAMEOBJECT))
|
||||
return;
|
||||
|
||||
for (GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
|
||||
if (i_check(itr->GetSource()))
|
||||
i_objects.push_back(itr->GetSource());
|
||||
}
|
||||
|
||||
template<class Check>
|
||||
void Trinity::WorldObjectListSearcher<Check>::Visit(DynamicObjectMapType &m)
|
||||
{
|
||||
if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_DYNAMICOBJECT))
|
||||
return;
|
||||
|
||||
for (DynamicObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
|
||||
if (i_check(itr->GetSource()))
|
||||
i_objects.push_back(itr->GetSource());
|
||||
}
|
||||
|
||||
// Gameobject searchers
|
||||
|
||||
template<class Check>
|
||||
void Trinity::GameObjectSearcher<Check>::Visit(GameObjectMapType &m)
|
||||
{
|
||||
// already found
|
||||
if (i_object)
|
||||
return;
|
||||
|
||||
for (GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
|
||||
{
|
||||
if (!itr->GetSource()->InSamePhase(i_phaseMask))
|
||||
continue;
|
||||
|
||||
if (i_check(itr->GetSource()))
|
||||
{
|
||||
i_object = itr->GetSource();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class Check>
|
||||
void Trinity::GameObjectLastSearcher<Check>::Visit(GameObjectMapType &m)
|
||||
{
|
||||
for (GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
|
||||
{
|
||||
if (!itr->GetSource()->InSamePhase(i_phaseMask))
|
||||
continue;
|
||||
|
||||
if (i_check(itr->GetSource()))
|
||||
i_object = itr->GetSource();
|
||||
}
|
||||
}
|
||||
|
||||
template<class Check>
|
||||
void Trinity::GameObjectListSearcher<Check>::Visit(GameObjectMapType &m)
|
||||
{
|
||||
for (GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
|
||||
if (itr->GetSource()->InSamePhase(i_phaseMask))
|
||||
if (i_check(itr->GetSource()))
|
||||
i_objects.push_back(itr->GetSource());
|
||||
}
|
||||
|
||||
// Unit searchers
|
||||
|
||||
template<class Check>
|
||||
void Trinity::UnitSearcher<Check>::Visit(CreatureMapType &m)
|
||||
{
|
||||
// already found
|
||||
if (i_object)
|
||||
return;
|
||||
|
||||
for (CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
|
||||
{
|
||||
if (!itr->GetSource()->InSamePhase(i_phaseMask))
|
||||
continue;
|
||||
|
||||
if (i_check(itr->GetSource()))
|
||||
{
|
||||
i_object = itr->GetSource();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class Check>
|
||||
void Trinity::UnitSearcher<Check>::Visit(PlayerMapType &m)
|
||||
{
|
||||
// already found
|
||||
if (i_object)
|
||||
return;
|
||||
|
||||
for (PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
|
||||
{
|
||||
if (!itr->GetSource()->InSamePhase(i_phaseMask))
|
||||
continue;
|
||||
|
||||
if (i_check(itr->GetSource()))
|
||||
{
|
||||
i_object = itr->GetSource();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class Check>
|
||||
void Trinity::UnitLastSearcher<Check>::Visit(CreatureMapType &m)
|
||||
{
|
||||
for (CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
|
||||
{
|
||||
if (!itr->GetSource()->InSamePhase(i_phaseMask))
|
||||
continue;
|
||||
|
||||
if (i_check(itr->GetSource()))
|
||||
i_object = itr->GetSource();
|
||||
}
|
||||
}
|
||||
|
||||
template<class Check>
|
||||
void Trinity::UnitLastSearcher<Check>::Visit(PlayerMapType &m)
|
||||
{
|
||||
for (PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
|
||||
{
|
||||
if (!itr->GetSource()->InSamePhase(i_phaseMask))
|
||||
continue;
|
||||
|
||||
if (i_check(itr->GetSource()))
|
||||
i_object = itr->GetSource();
|
||||
}
|
||||
}
|
||||
|
||||
template<class Check>
|
||||
void Trinity::UnitListSearcher<Check>::Visit(PlayerMapType &m)
|
||||
{
|
||||
for (PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
|
||||
if (itr->GetSource()->InSamePhase(i_phaseMask))
|
||||
if (i_check(itr->GetSource()))
|
||||
i_objects.push_back(itr->GetSource());
|
||||
}
|
||||
|
||||
template<class Check>
|
||||
void Trinity::UnitListSearcher<Check>::Visit(CreatureMapType &m)
|
||||
{
|
||||
for (CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
|
||||
if (itr->GetSource()->InSamePhase(i_phaseMask))
|
||||
if (i_check(itr->GetSource()))
|
||||
i_objects.push_back(itr->GetSource());
|
||||
}
|
||||
|
||||
// Creature searchers
|
||||
|
||||
template<class Check>
|
||||
void Trinity::CreatureSearcher<Check>::Visit(CreatureMapType &m)
|
||||
{
|
||||
// already found
|
||||
if (i_object)
|
||||
return;
|
||||
|
||||
for (CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
|
||||
{
|
||||
if (!itr->GetSource()->InSamePhase(i_phaseMask))
|
||||
continue;
|
||||
|
||||
if (i_check(itr->GetSource()))
|
||||
{
|
||||
i_object = itr->GetSource();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class Check>
|
||||
void Trinity::CreatureLastSearcher<Check>::Visit(CreatureMapType &m)
|
||||
{
|
||||
for (CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
|
||||
{
|
||||
if (!itr->GetSource()->InSamePhase(i_phaseMask))
|
||||
continue;
|
||||
|
||||
if (i_check(itr->GetSource()))
|
||||
i_object = itr->GetSource();
|
||||
}
|
||||
}
|
||||
|
||||
template<class Check>
|
||||
void Trinity::CreatureListSearcher<Check>::Visit(CreatureMapType &m)
|
||||
{
|
||||
for (CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
|
||||
if (itr->GetSource()->InSamePhase(i_phaseMask))
|
||||
if (i_check(itr->GetSource()))
|
||||
i_objects.push_back(itr->GetSource());
|
||||
}
|
||||
|
||||
template<class Check>
|
||||
void Trinity::PlayerListSearcher<Check>::Visit(PlayerMapType &m)
|
||||
{
|
||||
for (PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
|
||||
if (itr->GetSource()->InSamePhase(i_phaseMask))
|
||||
if (i_check(itr->GetSource()))
|
||||
i_objects.push_back(itr->GetSource());
|
||||
}
|
||||
|
||||
template<class Check>
|
||||
void Trinity::PlayerListSearcherWithSharedVision<Check>::Visit(PlayerMapType &m)
|
||||
{
|
||||
for (PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
|
||||
if (itr->GetSource()->InSamePhase(i_phaseMask))
|
||||
if (i_check(itr->GetSource(), true))
|
||||
i_objects.push_back(itr->GetSource());
|
||||
}
|
||||
|
||||
template<class Check>
|
||||
void Trinity::PlayerListSearcherWithSharedVision<Check>::Visit(CreatureMapType &m)
|
||||
{
|
||||
for (CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
|
||||
if (itr->GetSource()->InSamePhase(i_phaseMask) && itr->GetSource()->HasSharedVision())
|
||||
for (SharedVisionList::const_iterator i = itr->GetSource()->GetSharedVisionList().begin(); i != itr->GetSource()->GetSharedVisionList().end(); ++i)
|
||||
if (i_check(*i, false))
|
||||
i_objects.push_back(*i);
|
||||
}
|
||||
|
||||
template<class Check>
|
||||
void Trinity::PlayerSearcher<Check>::Visit(PlayerMapType &m)
|
||||
{
|
||||
// already found
|
||||
if (i_object)
|
||||
return;
|
||||
|
||||
for (PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
|
||||
{
|
||||
if (!itr->GetSource()->InSamePhase(i_phaseMask))
|
||||
continue;
|
||||
|
||||
if (i_check(itr->GetSource()))
|
||||
{
|
||||
i_object = itr->GetSource();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class Check>
|
||||
void Trinity::PlayerLastSearcher<Check>::Visit(PlayerMapType& m)
|
||||
{
|
||||
for (PlayerMapType::iterator itr = m.begin(); itr != m.end(); ++itr)
|
||||
{
|
||||
if (!itr->GetSource()->InSamePhase(i_phaseMask))
|
||||
continue;
|
||||
|
||||
if (i_check(itr->GetSource()))
|
||||
i_object = itr->GetSource();
|
||||
}
|
||||
}
|
||||
|
||||
template<class Builder>
|
||||
void Trinity::LocalizedPacketDo<Builder>::operator()(Player* p)
|
||||
{
|
||||
LocaleConstant loc_idx = p->GetSession()->GetSessionDbLocaleIndex();
|
||||
uint32 cache_idx = loc_idx+1;
|
||||
WorldPacket* data;
|
||||
|
||||
// create if not cached yet
|
||||
if (i_data_cache.size() < cache_idx + 1 || !i_data_cache[cache_idx])
|
||||
{
|
||||
if (i_data_cache.size() < cache_idx + 1)
|
||||
i_data_cache.resize(cache_idx + 1);
|
||||
|
||||
data = new WorldPacket();
|
||||
|
||||
i_builder(*data, loc_idx);
|
||||
|
||||
ASSERT(data->GetOpcode() != MSG_NULL_ACTION);
|
||||
|
||||
i_data_cache[cache_idx] = data;
|
||||
}
|
||||
else
|
||||
data = i_data_cache[cache_idx];
|
||||
|
||||
p->SendDirectMessage(data);
|
||||
}
|
||||
|
||||
template<class Builder>
|
||||
void Trinity::LocalizedPacketListDo<Builder>::operator()(Player* p)
|
||||
{
|
||||
LocaleConstant loc_idx = p->GetSession()->GetSessionDbLocaleIndex();
|
||||
uint32 cache_idx = loc_idx+1;
|
||||
WorldPacketList* data_list;
|
||||
|
||||
// create if not cached yet
|
||||
if (i_data_cache.size() < cache_idx+1 || i_data_cache[cache_idx].empty())
|
||||
{
|
||||
if (i_data_cache.size() < cache_idx+1)
|
||||
i_data_cache.resize(cache_idx+1);
|
||||
|
||||
data_list = &i_data_cache[cache_idx];
|
||||
|
||||
i_builder(*data_list, loc_idx);
|
||||
}
|
||||
else
|
||||
data_list = &i_data_cache[cache_idx];
|
||||
|
||||
for (size_t i = 0; i < data_list->size(); ++i)
|
||||
p->SendDirectMessage((*data_list)[i]);
|
||||
}
|
||||
|
||||
#endif // TRINITY_GRIDNOTIFIERSIMPL_H
|
||||
255
src/server/game/Grids/ObjectGridLoader.cpp
Normal file
255
src/server/game/Grids/ObjectGridLoader.cpp
Normal file
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "ObjectGridLoader.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Creature.h"
|
||||
#include "Vehicle.h"
|
||||
#include "GameObject.h"
|
||||
#include "DynamicObject.h"
|
||||
#include "Corpse.h"
|
||||
#include "World.h"
|
||||
#include "CellImpl.h"
|
||||
#include "CreatureAI.h"
|
||||
#include "Transport.h"
|
||||
|
||||
// for loading world object at grid loading (Corpses)
|
||||
//TODO: to implement npc on transport, also need to load npcs at grid loading
|
||||
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)
|
||||
{}
|
||||
|
||||
void Visit(CorpseMapType &m);
|
||||
|
||||
template<class T> void Visit(GridRefManager<T>&) { }
|
||||
|
||||
private:
|
||||
Cell i_cell;
|
||||
NGridType &i_grid;
|
||||
Map* i_map;
|
||||
public:
|
||||
uint32 i_corpses;
|
||||
};
|
||||
|
||||
template<class T> void ObjectGridLoader::SetObjectCell(T* /*obj*/, CellCoord const& /*cellCoord*/)
|
||||
{
|
||||
}
|
||||
|
||||
template<> void ObjectGridLoader::SetObjectCell(Creature* obj, CellCoord const& cellCoord)
|
||||
{
|
||||
Cell cell(cellCoord);
|
||||
obj->SetCurrentCell(cell);
|
||||
}
|
||||
|
||||
template<> void ObjectGridLoader::SetObjectCell(GameObject* obj, CellCoord const& cellCoord)
|
||||
{
|
||||
Cell cell(cellCoord);
|
||||
obj->SetCurrentCell(cell);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void AddObjectHelper(CellCoord &cell, GridRefManager<T> &m, uint32 &count, Map* /*map*/, T *obj)
|
||||
{
|
||||
obj->AddToGrid(m);
|
||||
ObjectGridLoader::SetObjectCell(obj, cell);
|
||||
obj->AddToWorld();
|
||||
++count;
|
||||
}
|
||||
|
||||
template <>
|
||||
void AddObjectHelper(CellCoord &cell, CreatureMapType &m, uint32 &count, Map* map, Creature *obj)
|
||||
{
|
||||
obj->AddToGrid(m);
|
||||
ObjectGridLoader::SetObjectCell(obj, cell);
|
||||
obj->AddToWorld();
|
||||
if (obj->isActiveObject())
|
||||
map->AddToActive(obj);
|
||||
|
||||
++count;
|
||||
}
|
||||
|
||||
template <>
|
||||
void AddObjectHelper(CellCoord &cell, GameObjectMapType &m, uint32 &count, Map* map, GameObject *obj)
|
||||
{
|
||||
obj->AddToGrid(m);
|
||||
ObjectGridLoader::SetObjectCell(obj, cell);
|
||||
obj->AddToWorld();
|
||||
if (obj->isActiveObject())
|
||||
map->AddToActive(obj);
|
||||
|
||||
++count;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void LoadHelper(CellGuidSet const& guid_set, CellCoord &cell, GridRefManager<T> &m, uint32 &count, Map* map)
|
||||
{
|
||||
for (CellGuidSet::const_iterator i_guid = guid_set.begin(); i_guid != guid_set.end(); ++i_guid)
|
||||
{
|
||||
T* obj = new T;
|
||||
uint32 guid = *i_guid;
|
||||
//sLog->outString("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);
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
void LoadHelper(CellGuidSet const& guid_set, CellCoord &cell, GridRefManager<GameObject> &m, uint32 &count, Map* map)
|
||||
{
|
||||
for (CellGuidSet::const_iterator i_guid = guid_set.begin(); i_guid != guid_set.end(); ++i_guid)
|
||||
{
|
||||
uint32 guid = *i_guid;
|
||||
GameObjectData const* data = sObjectMgr->GetGOData(guid);
|
||||
GameObject* obj = data && sObjectMgr->IsGameObjectStaticTransport(data->id) ? new StaticTransport() : new GameObject();
|
||||
//sLog->outString("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);
|
||||
}
|
||||
}
|
||||
|
||||
void LoadHelper(CellCorpseSet const& cell_corpses, CellCoord &cell, CorpseMapType &m, uint32 &count, Map* map)
|
||||
{
|
||||
if (cell_corpses.empty())
|
||||
return;
|
||||
|
||||
for (CellCorpseSet::const_iterator itr = cell_corpses.begin(); itr != cell_corpses.end(); ++itr)
|
||||
{
|
||||
if (itr->second != map->GetInstanceId())
|
||||
continue;
|
||||
|
||||
uint32 player_guid = itr->first;
|
||||
|
||||
Corpse* obj = sObjectAccessor->GetCorpseForPlayerGUID(player_guid);
|
||||
if (!obj)
|
||||
continue;
|
||||
|
||||
// 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);
|
||||
|
||||
if (obj->IsInGrid())
|
||||
{
|
||||
obj->AddToWorld();
|
||||
continue;
|
||||
}
|
||||
|
||||
AddObjectHelper(cell, m, count, map, obj);
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectGridLoader::Visit(GameObjectMapType &m)
|
||||
{
|
||||
CellCoord cellCoord = i_cell.GetCellCoord();
|
||||
CellObjectGuids const& cell_guids = sObjectMgr->GetCellObjectGuids(i_map->GetId(), i_map->GetSpawnMode(), cellCoord.GetId());
|
||||
LoadHelper(cell_guids.gameobjects, cellCoord, m, i_gameObjects, i_map);
|
||||
}
|
||||
|
||||
void ObjectGridLoader::Visit(CreatureMapType &m)
|
||||
{
|
||||
CellCoord cellCoord = i_cell.GetCellCoord();
|
||||
CellObjectGuids const& cell_guids = sObjectMgr->GetCellObjectGuids(i_map->GetId(), i_map->GetSpawnMode(), cellCoord.GetId());
|
||||
LoadHelper(cell_guids.creatures, cellCoord, m, i_creatures, i_map);
|
||||
}
|
||||
|
||||
void ObjectWorldLoader::Visit(CorpseMapType &m)
|
||||
{
|
||||
CellCoord cellCoord = i_cell.GetCellCoord();
|
||||
// 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, cellCoord.GetId());
|
||||
LoadHelper(cell_guids.corpses, cellCoord, m, i_corpses, i_map);
|
||||
}
|
||||
|
||||
void ObjectGridLoader::LoadN(void)
|
||||
{
|
||||
i_gameObjects = 0; i_creatures = 0; i_corpses = 0;
|
||||
i_cell.data.Part.cell_y = 0;
|
||||
for (unsigned int x=0; x < MAX_NUMBER_OF_CELLS; ++x)
|
||||
{
|
||||
i_cell.data.Part.cell_x = x;
|
||||
for (unsigned int y=0; y < MAX_NUMBER_OF_CELLS; ++y)
|
||||
{
|
||||
i_cell.data.Part.cell_y = y;
|
||||
|
||||
//Load creatures and game objects
|
||||
{
|
||||
TypeContainerVisitor<ObjectGridLoader, GridTypeMapContainer> visitor(*this);
|
||||
i_grid.VisitGrid(x, y, visitor);
|
||||
}
|
||||
|
||||
//Load corpses (not bones)
|
||||
{
|
||||
ObjectWorldLoader worker(*this);
|
||||
TypeContainerVisitor<ObjectWorldLoader, WorldTypeMapContainer> visitor(worker);
|
||||
i_grid.VisitGrid(x, y, visitor);
|
||||
i_corpses += worker.i_corpses;
|
||||
}
|
||||
}
|
||||
}
|
||||
;//sLog->outDebug(LOG_FILTER_MAPS, "%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());
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void ObjectGridUnloader::Visit(GridRefManager<T> &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();
|
||||
///- object will get delinked from the manager when deleted
|
||||
delete obj;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void ObjectGridCleaner::Visit(GridRefManager<T> &m)
|
||||
{
|
||||
for (typename GridRefManager<T>::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||
iter->GetSource()->CleanupsBeforeDelete();
|
||||
}
|
||||
|
||||
template void ObjectGridUnloader::Visit(CreatureMapType &);
|
||||
template void ObjectGridUnloader::Visit(GameObjectMapType &);
|
||||
template void ObjectGridUnloader::Visit(DynamicObjectMapType &);
|
||||
template void ObjectGridUnloader::Visit(CorpseMapType &);
|
||||
template void ObjectGridCleaner::Visit(CreatureMapType &);
|
||||
template void ObjectGridCleaner::Visit<GameObject>(GameObjectMapType &);
|
||||
template void ObjectGridCleaner::Visit<DynamicObject>(DynamicObjectMapType &);
|
||||
template void ObjectGridCleaner::Visit<Corpse>(CorpseMapType &);
|
||||
70
src/server/game/Grids/ObjectGridLoader.h
Normal file
70
src/server/game/Grids/ObjectGridLoader.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef TRINITY_OBJECTGRIDLOADER_H
|
||||
#define TRINITY_OBJECTGRIDLOADER_H
|
||||
|
||||
#include "TypeList.h"
|
||||
#include "Define.h"
|
||||
#include "GridLoader.h"
|
||||
#include "GridDefines.h"
|
||||
#include "Cell.h"
|
||||
|
||||
class ObjectWorldLoader;
|
||||
|
||||
class ObjectGridLoader
|
||||
{
|
||||
friend class ObjectWorldLoader;
|
||||
|
||||
public:
|
||||
ObjectGridLoader(NGridType &grid, Map* map, const Cell &cell)
|
||||
: i_cell(cell), i_grid(grid), i_map(map), i_gameObjects(0), i_creatures(0), i_corpses (0)
|
||||
{}
|
||||
|
||||
void Visit(GameObjectMapType &m);
|
||||
void Visit(CreatureMapType &m);
|
||||
void Visit(CorpseMapType &) const {}
|
||||
void Visit(DynamicObjectMapType&) const {}
|
||||
|
||||
void LoadN(void);
|
||||
|
||||
template<class T> static void SetObjectCell(T* obj, CellCoord const& cellCoord);
|
||||
|
||||
private:
|
||||
Cell i_cell;
|
||||
NGridType &i_grid;
|
||||
Map* i_map;
|
||||
uint32 i_gameObjects;
|
||||
uint32 i_creatures;
|
||||
uint32 i_corpses;
|
||||
};
|
||||
|
||||
//Clean up and remove from world
|
||||
class ObjectGridCleaner
|
||||
{
|
||||
public:
|
||||
template<class T> void Visit(GridRefManager<T> &);
|
||||
};
|
||||
|
||||
//Delete objects before deleting NGrid
|
||||
class ObjectGridUnloader
|
||||
{
|
||||
public:
|
||||
template<class T> void Visit(GridRefManager<T> &m);
|
||||
};
|
||||
#endif
|
||||
Reference in New Issue
Block a user