mirror of
https://github.com/mangosfour/server.git
synced 2025-12-14 16:37:01 +00:00
[10681] Added new Cell::Visit* functions to visit grids with center in (x,y) coords
* This fixes possible problems with Spell::FillAreaTargets(center of search should be (x,y) position, not spell caster's position) * Cleanup Cell class, removed old and unused code
This commit is contained in:
parent
ef8789f780
commit
225b4db1ca
5 changed files with 62 additions and 178 deletions
|
|
@ -27,20 +27,6 @@
|
|||
class Map;
|
||||
class WorldObject;
|
||||
|
||||
enum District
|
||||
{
|
||||
UPPER_DISTRICT = 1,
|
||||
LOWER_DISTRICT = 1 << 1,
|
||||
LEFT_DISTRICT = 1 << 2,
|
||||
RIGHT_DISTRICT = 1 << 3,
|
||||
CENTER_DISTRICT = 1 << 4,
|
||||
UPPER_LEFT_DISTRICT = (UPPER_DISTRICT | LEFT_DISTRICT),
|
||||
UPPER_RIGHT_DISTRICT = (UPPER_DISTRICT | RIGHT_DISTRICT),
|
||||
LOWER_LEFT_DISTRICT = (LOWER_DISTRICT | LEFT_DISTRICT),
|
||||
LOWER_RIGHT_DISTRICT = (LOWER_DISTRICT | RIGHT_DISTRICT),
|
||||
ALL_DISTRICT = (UPPER_DISTRICT | LOWER_DISTRICT | LEFT_DISTRICT | RIGHT_DISTRICT | CENTER_DISTRICT)
|
||||
};
|
||||
|
||||
struct MANGOS_DLL_DECL CellArea
|
||||
{
|
||||
CellArea() : right_offset(0), left_offset(0), upper_offset(0), lower_offset(0) {}
|
||||
|
|
@ -67,43 +53,6 @@ struct MANGOS_DLL_DECL Cell
|
|||
Cell(const Cell &cell) { data.All = cell.data.All; }
|
||||
explicit Cell(CellPair const& p);
|
||||
|
||||
void operator|=(Cell &cell)
|
||||
{
|
||||
data.Part.reserved = 0;
|
||||
cell.data.Part.reserved = 0;
|
||||
uint32 x, y, old_x, old_y;
|
||||
Compute(x, y);
|
||||
cell.Compute(old_x, old_y);
|
||||
|
||||
if( std::abs(int(x-old_x)) > 1 || std::abs(int(y-old_y)) > 1)
|
||||
{
|
||||
data.Part.reserved = ALL_DISTRICT;
|
||||
cell.data.Part.reserved = ALL_DISTRICT;
|
||||
return;
|
||||
}
|
||||
|
||||
if( x < old_x )
|
||||
{
|
||||
data.Part.reserved |= LEFT_DISTRICT;
|
||||
cell.data.Part.reserved |= RIGHT_DISTRICT;
|
||||
}
|
||||
else if( old_x < x )
|
||||
{
|
||||
data.Part.reserved |= RIGHT_DISTRICT;
|
||||
cell.data.Part.reserved |= LEFT_DISTRICT;
|
||||
}
|
||||
if( y < old_y )
|
||||
{
|
||||
data.Part.reserved |= UPPER_DISTRICT;
|
||||
cell.data.Part.reserved |= LOWER_DISTRICT;
|
||||
}
|
||||
else if( old_y < y )
|
||||
{
|
||||
data.Part.reserved |= LOWER_DISTRICT;
|
||||
cell.data.Part.reserved |= UPPER_DISTRICT;
|
||||
}
|
||||
}
|
||||
|
||||
void Compute(uint32 &x, uint32 &y) const
|
||||
{
|
||||
x = data.Part.grid_x*MAX_NUMBER_OF_CELLS + data.Part.cell_x;
|
||||
|
|
@ -158,15 +107,19 @@ struct MANGOS_DLL_DECL Cell
|
|||
uint32 All;
|
||||
} data;
|
||||
|
||||
template<class T, class CONTAINER> void Visit(const CellPair &cellPair, TypeContainerVisitor<T, CONTAINER> &visitor, Map &) const;
|
||||
template<class T, class CONTAINER> void Visit(const CellPair &cellPair, TypeContainerVisitor<T, CONTAINER> &visitor, Map &m, const WorldObject &obj, float radius) const;
|
||||
template<class T, class CONTAINER> void Visit(const CellPair &cellPair, TypeContainerVisitor<T, CONTAINER> &visitor, Map &m, float x, float y, float radius) const;
|
||||
template<class T, class CONTAINER> void Visit(const CellPair &cellPair, TypeContainerVisitor<T, CONTAINER> &visitor, Map &m, const WorldObject& obj, float radius) const;
|
||||
|
||||
static CellArea CalculateCellArea(const WorldObject &obj, float radius);
|
||||
static CellArea CalculateCellArea(float x, float y, float radius);
|
||||
|
||||
template<class T> static void VisitGridObjects(const WorldObject *obj, T &visitor, float radius, bool dont_load = true);
|
||||
template<class T> static void VisitWorldObjects(const WorldObject *obj, T &visitor, float radius, bool dont_load = true);
|
||||
template<class T> static void VisitAllObjects(const WorldObject *obj, T &visitor, float radius, bool dont_load = true);
|
||||
|
||||
template<class T> static void VisitGridObjects(float x, float y, Map *map, T &visitor, float radius, bool dont_load = true);
|
||||
template<class T> static void VisitWorldObjects(float x, float y, Map *map, T &visitor, float radius, bool dont_load = true);
|
||||
template<class T> static void VisitAllObjects(float x, float y, Map *map, T &visitor, float radius, bool dont_load = true);
|
||||
|
||||
private:
|
||||
template<class T, class CONTAINER> void VisitCircle(TypeContainerVisitor<T, CONTAINER> &, Map &, const CellPair& , const CellPair& ) const;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -34,99 +34,6 @@ inline Cell::Cell(CellPair const& p)
|
|||
data.Part.reserved = 0;
|
||||
}
|
||||
|
||||
template<class T, class CONTAINER>
|
||||
inline void
|
||||
Cell::Visit(const CellPair &standing_cell, TypeContainerVisitor<T, CONTAINER> &visitor, Map &m) const
|
||||
{
|
||||
if (standing_cell.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || standing_cell.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP)
|
||||
return;
|
||||
|
||||
uint16 district = (District)this->data.Part.reserved;
|
||||
if(district == CENTER_DISTRICT)
|
||||
{
|
||||
m.Visit(*this, visitor);
|
||||
return;
|
||||
}
|
||||
|
||||
// set up the cell range based on the district
|
||||
// the overloaded operators handle range checking
|
||||
CellPair begin_cell = standing_cell;
|
||||
CellPair end_cell = standing_cell;
|
||||
|
||||
switch( district )
|
||||
{
|
||||
case ALL_DISTRICT:
|
||||
{
|
||||
begin_cell << 1; begin_cell -= 1; // upper left
|
||||
end_cell >> 1; end_cell += 1; // lower right
|
||||
break;
|
||||
}
|
||||
case UPPER_LEFT_DISTRICT:
|
||||
{
|
||||
begin_cell << 1; begin_cell -= 1; // upper left
|
||||
break;
|
||||
}
|
||||
case UPPER_RIGHT_DISTRICT:
|
||||
{
|
||||
begin_cell -= 1; // up
|
||||
end_cell >> 1; // right
|
||||
break;
|
||||
}
|
||||
case LOWER_LEFT_DISTRICT:
|
||||
{
|
||||
begin_cell << 1; // left
|
||||
end_cell += 1; // down
|
||||
break;
|
||||
}
|
||||
case LOWER_RIGHT_DISTRICT:
|
||||
{
|
||||
end_cell >> 1; end_cell += 1; // lower right
|
||||
break;
|
||||
}
|
||||
case LEFT_DISTRICT:
|
||||
{
|
||||
begin_cell -= 1; // up
|
||||
end_cell >> 1; end_cell += 1; // lower right
|
||||
break;
|
||||
}
|
||||
case RIGHT_DISTRICT:
|
||||
{
|
||||
begin_cell << 1; begin_cell -= 1; // upper left
|
||||
end_cell += 1; // down
|
||||
break;
|
||||
}
|
||||
case UPPER_DISTRICT:
|
||||
{
|
||||
begin_cell << 1; begin_cell -= 1; // upper left
|
||||
end_cell >> 1; // right
|
||||
break;
|
||||
}
|
||||
case LOWER_DISTRICT:
|
||||
{
|
||||
begin_cell << 1; // left
|
||||
end_cell >> 1; end_cell += 1; // lower right
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
MANGOS_ASSERT( false );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// loop the cell range
|
||||
for(uint32 x = begin_cell.x_coord; x <= end_cell.x_coord; x++)
|
||||
{
|
||||
for(uint32 y = begin_cell.y_coord; y <= end_cell.y_coord; y++)
|
||||
{
|
||||
CellPair cell_pair(x,y);
|
||||
Cell r_zone(cell_pair);
|
||||
r_zone.data.Part.nocreate = data.Part.nocreate;
|
||||
m.Visit(r_zone, visitor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline int CellHelper(const float radius)
|
||||
{
|
||||
if(radius < 1.0f)
|
||||
|
|
@ -135,18 +42,15 @@ inline int CellHelper(const float radius)
|
|||
return (int)ceilf(radius/SIZE_OF_GRID_CELL);
|
||||
}
|
||||
|
||||
inline CellArea Cell::CalculateCellArea(const WorldObject &obj, float radius)
|
||||
inline CellArea Cell::CalculateCellArea(float x, float y, float radius)
|
||||
{
|
||||
if(radius <= 0.0f)
|
||||
return CellArea();
|
||||
|
||||
//we should increase search radius by object's radius, otherwise
|
||||
//we could have problems with huge creatures, which won't attack nearest players etc
|
||||
radius += obj.GetObjectBoundingRadius();
|
||||
//lets calculate object coord offsets from cell borders.
|
||||
//TODO: add more correct/generic method for this task
|
||||
const float x_offset = (obj.GetPositionX() - CENTER_GRID_CELL_OFFSET)/SIZE_OF_GRID_CELL;
|
||||
const float y_offset = (obj.GetPositionY() - CENTER_GRID_CELL_OFFSET)/SIZE_OF_GRID_CELL;
|
||||
const float x_offset = (x - CENTER_GRID_CELL_OFFSET)/SIZE_OF_GRID_CELL;
|
||||
const float y_offset = (y - CENTER_GRID_CELL_OFFSET)/SIZE_OF_GRID_CELL;
|
||||
|
||||
const float x_val = floor(x_offset + CENTER_GRID_CELL_ID + 0.5f);
|
||||
const float y_val = floor(y_offset + CENTER_GRID_CELL_ID + 0.5f);
|
||||
|
|
@ -166,7 +70,15 @@ inline CellArea Cell::CalculateCellArea(const WorldObject &obj, float radius)
|
|||
|
||||
template<class T, class CONTAINER>
|
||||
inline void
|
||||
Cell::Visit(const CellPair &standing_cell, TypeContainerVisitor<T, CONTAINER> &visitor, Map &m, const WorldObject &obj, float radius) const
|
||||
Cell::Visit(const CellPair &standing_cell, TypeContainerVisitor<T, CONTAINER> &visitor, Map &m, const WorldObject& obj, float radius) const
|
||||
{
|
||||
Cell::Visit(standing_cell, visitor, m, obj.GetPositionX(), obj.GetPositionY(), radius + obj.GetObjectBoundingRadius());
|
||||
}
|
||||
|
||||
|
||||
template<class T, class CONTAINER>
|
||||
inline void
|
||||
Cell::Visit(const CellPair &standing_cell, TypeContainerVisitor<T, CONTAINER> &visitor, Map &m, float x, float y, float radius) const
|
||||
{
|
||||
if (standing_cell.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || standing_cell.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP)
|
||||
return;
|
||||
|
|
@ -184,7 +96,7 @@ Cell::Visit(const CellPair &standing_cell, TypeContainerVisitor<T, CONTAINER> &v
|
|||
radius = 333.0f;
|
||||
|
||||
//lets calculate object coord offsets from cell borders.
|
||||
CellArea area = Cell::CalculateCellArea(obj, radius);
|
||||
CellArea area = Cell::CalculateCellArea(x, y, radius);
|
||||
//if radius fits inside standing cell
|
||||
if(!area)
|
||||
{
|
||||
|
|
@ -315,4 +227,39 @@ inline void Cell::VisitAllObjects(const WorldObject *center_obj, T &visitor, flo
|
|||
cell.Visit(p, wnotifier, *center_obj->GetMap(), *center_obj, radius);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void Cell::VisitGridObjects(float x, float y, Map *map, T &visitor, float radius, bool dont_load)
|
||||
{
|
||||
CellPair p(MaNGOS::ComputeCellPair(x, y));
|
||||
Cell cell(p);
|
||||
if (dont_load)
|
||||
cell.SetNoCreate();
|
||||
TypeContainerVisitor<T, GridTypeMapContainer > gnotifier(visitor);
|
||||
cell.Visit(p, gnotifier, *map, x, y, radius);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void Cell::VisitWorldObjects(float x, float y, Map *map, T &visitor, float radius, bool dont_load)
|
||||
{
|
||||
CellPair p(MaNGOS::ComputeCellPair(x, y));
|
||||
Cell cell(p);
|
||||
if (dont_load)
|
||||
cell.SetNoCreate();
|
||||
TypeContainerVisitor<T, WorldTypeMapContainer > gnotifier(visitor);
|
||||
cell.Visit(p ,gnotifier, *map, x, y, radius);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void Cell::VisitAllObjects(float x, float y, Map *map, T &visitor, float radius, bool dont_load)
|
||||
{
|
||||
CellPair p(MaNGOS::ComputeCellPair(x, y));
|
||||
Cell cell(p);
|
||||
if (dont_load)
|
||||
cell.SetNoCreate();
|
||||
TypeContainerVisitor<T, GridTypeMapContainer > gnotifier(visitor);
|
||||
TypeContainerVisitor<T, WorldTypeMapContainer > wnotifier(visitor);
|
||||
cell.Visit(p, gnotifier, *map, x, y, radius);
|
||||
cell.Visit(p, wnotifier, *map, x, y, radius);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -430,7 +430,6 @@ void Map::MessageBroadcast(Player *player, WorldPacket *msg, bool to_self)
|
|||
}
|
||||
|
||||
Cell cell(p);
|
||||
cell.data.Part.reserved = ALL_DISTRICT;
|
||||
cell.SetNoCreate();
|
||||
|
||||
if( !loaded(GridPair(cell.data.Part.grid_x, cell.data.Part.grid_y)) )
|
||||
|
|
@ -452,7 +451,6 @@ void Map::MessageBroadcast(WorldObject *obj, WorldPacket *msg)
|
|||
}
|
||||
|
||||
Cell cell(p);
|
||||
cell.data.Part.reserved = ALL_DISTRICT;
|
||||
cell.SetNoCreate();
|
||||
|
||||
if( !loaded(GridPair(cell.data.Part.grid_x, cell.data.Part.grid_y)) )
|
||||
|
|
@ -476,7 +474,6 @@ void Map::MessageDistBroadcast(Player *player, WorldPacket *msg, float dist, boo
|
|||
}
|
||||
|
||||
Cell cell(p);
|
||||
cell.data.Part.reserved = ALL_DISTRICT;
|
||||
cell.SetNoCreate();
|
||||
|
||||
if( !loaded(GridPair(cell.data.Part.grid_x, cell.data.Part.grid_y)) )
|
||||
|
|
@ -498,7 +495,6 @@ void Map::MessageDistBroadcast(WorldObject *obj, WorldPacket *msg, float dist)
|
|||
}
|
||||
|
||||
Cell cell(p);
|
||||
cell.data.Part.reserved = ALL_DISTRICT;
|
||||
cell.SetNoCreate();
|
||||
|
||||
if( !loaded(GridPair(cell.data.Part.grid_x, cell.data.Part.grid_y)) )
|
||||
|
|
@ -550,7 +546,7 @@ void Map::Update(uint32 time_, uint32 diff)
|
|||
// so ther's no need for range checking inside the loop
|
||||
CellPair begin_cell(standing_cell), end_cell(standing_cell);
|
||||
//lets update mobs/objects in ALL visible cells around player!
|
||||
CellArea area = Cell::CalculateCellArea(*plr, GetVisibilityDistance());
|
||||
CellArea area = Cell::CalculateCellArea(plr->GetPositionX(), plr->GetPositionY(), GetVisibilityDistance());
|
||||
area.ResizeBorders(begin_cell, end_cell);
|
||||
|
||||
for(uint32 x = begin_cell.x_coord; x <= end_cell.x_coord; ++x)
|
||||
|
|
@ -565,10 +561,9 @@ void Map::Update(uint32 time_, uint32 diff)
|
|||
markCell(cell_id);
|
||||
CellPair pair(x,y);
|
||||
Cell cell(pair);
|
||||
cell.data.Part.reserved = CENTER_DISTRICT;
|
||||
cell.SetNoCreate();
|
||||
cell.Visit(pair, grid_object_update, *this);
|
||||
cell.Visit(pair, world_object_update, *this);
|
||||
Visit(cell, grid_object_update);
|
||||
Visit(cell, world_object_update);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -613,10 +608,9 @@ void Map::Update(uint32 time_, uint32 diff)
|
|||
markCell(cell_id);
|
||||
CellPair pair(x,y);
|
||||
Cell cell(pair);
|
||||
cell.data.Part.reserved = CENTER_DISTRICT;
|
||||
cell.SetNoCreate();
|
||||
cell.Visit(pair, grid_object_update, *this);
|
||||
cell.Visit(pair, world_object_update, *this);
|
||||
Visit(cell, grid_object_update);
|
||||
Visit(cell, world_object_update);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -744,7 +738,6 @@ Map::PlayerRelocation(Player *player, float x, float y, float z, float orientati
|
|||
|
||||
Cell old_cell(old_val);
|
||||
Cell new_cell(new_val);
|
||||
new_cell |= old_cell;
|
||||
bool same_cell = (new_cell == old_cell);
|
||||
|
||||
player->Relocate(x, y, z, orientation);
|
||||
|
|
@ -1362,7 +1355,6 @@ const char* Map::GetMapName() const
|
|||
|
||||
void Map::UpdateObjectVisibility( WorldObject* obj, Cell cell, CellPair cellpair)
|
||||
{
|
||||
cell.data.Part.reserved = ALL_DISTRICT;
|
||||
cell.SetNoCreate();
|
||||
MaNGOS::VisibleChangesNotifier notifier(*obj);
|
||||
TypeContainerVisitor<MaNGOS::VisibleChangesNotifier, WorldTypeMapContainer > player_notifier(notifier);
|
||||
|
|
@ -1372,7 +1364,6 @@ void Map::UpdateObjectVisibility( WorldObject* obj, Cell cell, CellPair cellpair
|
|||
void Map::PlayerRelocationNotify( Player* player, Cell cell, CellPair cellpair )
|
||||
{
|
||||
MaNGOS::PlayerRelocationNotifier relocationNotifier(*player);
|
||||
cell.data.Part.reserved = ALL_DISTRICT;
|
||||
|
||||
TypeContainerVisitor<MaNGOS::PlayerRelocationNotifier, GridTypeMapContainer > p2grid_relocation(relocationNotifier);
|
||||
TypeContainerVisitor<MaNGOS::PlayerRelocationNotifier, WorldTypeMapContainer > p2world_relocation(relocationNotifier);
|
||||
|
|
|
|||
|
|
@ -6623,15 +6623,8 @@ SpellCastResult Spell::CanOpenLock(SpellEffectIndex effIndex, uint32 lockId, Ski
|
|||
*/
|
||||
void Spell::FillAreaTargets(UnitList &targetUnitMap, float x, float y, float radius, SpellNotifyPushType pushType, SpellTargets spellTargets, WorldObject* originalCaster /*=NULL*/)
|
||||
{
|
||||
CellPair p(MaNGOS::ComputeCellPair(x, y));
|
||||
Cell cell(p);
|
||||
cell.data.Part.reserved = ALL_DISTRICT;
|
||||
cell.SetNoCreate();
|
||||
MaNGOS::SpellNotifierCreatureAndPlayer notifier(*this, targetUnitMap, radius, pushType, spellTargets, originalCaster);
|
||||
TypeContainerVisitor<MaNGOS::SpellNotifierCreatureAndPlayer, WorldTypeMapContainer > world_notifier(notifier);
|
||||
TypeContainerVisitor<MaNGOS::SpellNotifierCreatureAndPlayer, GridTypeMapContainer > grid_notifier(notifier);
|
||||
cell.Visit(p, world_notifier, *m_caster->GetMap(), *m_caster, radius);
|
||||
cell.Visit(p, grid_notifier, *m_caster->GetMap(), *m_caster, radius);
|
||||
Cell::VisitAllObjects(x, y, m_caster->GetMap(), notifier, radius);
|
||||
}
|
||||
|
||||
void Spell::FillRaidOrPartyTargets(UnitList &targetUnitMap, Unit* member, Unit* center, float radius, bool raid, bool withPets, bool withcaster)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "10680"
|
||||
#define REVISION_NR "10681"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue