Skip to content

Commit

Permalink
[10681] Added new Cell::Visit* functions to visit grids with center i…
Browse files Browse the repository at this point in the history
…n (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
  • Loading branch information
SilverIce committed Nov 4, 2010
1 parent 24cd8f1 commit 142d535
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 178 deletions.
61 changes: 7 additions & 54 deletions src/game/Cell.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) {}
Expand All @@ -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;
Expand Down Expand Up @@ -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;
};
Expand Down
149 changes: 48 additions & 101 deletions src/game/CellImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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);
Expand All @@ -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;
Expand All @@ -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)
{
Expand Down Expand Up @@ -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
19 changes: 5 additions & 14 deletions src/game/Map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)) )
Expand All @@ -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)) )
Expand All @@ -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)) )
Expand All @@ -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)) )
Expand Down Expand Up @@ -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)
Expand All @@ -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);
}
}
}
Expand Down Expand Up @@ -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);
}
}
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down
9 changes: 1 addition & 8 deletions src/game/Spell.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion src/shared/revision_nr.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "10680"
#define REVISION_NR "10681"
#endif // __REVISION_NR_H__

0 comments on commit 142d535

Please sign in to comment.