diff --git a/src/game/Cell.h b/src/game/Cell.h index 92227bd68..f01cddf2e 100644 --- a/src/game/Cell.h +++ b/src/game/Cell.h @@ -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 void Visit(const CellPair &cellPair, TypeContainerVisitor &visitor, Map &) const; - template void Visit(const CellPair &cellPair, TypeContainerVisitor &visitor, Map &m, const WorldObject &obj, float radius) const; + template void Visit(const CellPair &cellPair, TypeContainerVisitor &visitor, Map &m, float x, float y, float radius) const; + template void Visit(const CellPair &cellPair, TypeContainerVisitor &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 static void VisitGridObjects(const WorldObject *obj, T &visitor, float radius, bool dont_load = true); template static void VisitWorldObjects(const WorldObject *obj, T &visitor, float radius, bool dont_load = true); template static void VisitAllObjects(const WorldObject *obj, T &visitor, float radius, bool dont_load = true); + template static void VisitGridObjects(float x, float y, Map *map, T &visitor, float radius, bool dont_load = true); + template static void VisitWorldObjects(float x, float y, Map *map, T &visitor, float radius, bool dont_load = true); + template static void VisitAllObjects(float x, float y, Map *map, T &visitor, float radius, bool dont_load = true); + private: template void VisitCircle(TypeContainerVisitor &, Map &, const CellPair& , const CellPair& ) const; }; diff --git a/src/game/CellImpl.h b/src/game/CellImpl.h index d543380a9..58a797ae9 100644 --- a/src/game/CellImpl.h +++ b/src/game/CellImpl.h @@ -34,99 +34,6 @@ inline Cell::Cell(CellPair const& p) data.Part.reserved = 0; } -template -inline void -Cell::Visit(const CellPair &standing_cell, TypeContainerVisitor &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 inline void -Cell::Visit(const CellPair &standing_cell, TypeContainerVisitor &visitor, Map &m, const WorldObject &obj, float radius) const +Cell::Visit(const CellPair &standing_cell, TypeContainerVisitor &visitor, Map &m, const WorldObject& obj, float radius) const +{ + Cell::Visit(standing_cell, visitor, m, obj.GetPositionX(), obj.GetPositionY(), radius + obj.GetObjectBoundingRadius()); +} + + +template +inline void +Cell::Visit(const CellPair &standing_cell, TypeContainerVisitor &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 &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 +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 gnotifier(visitor); + cell.Visit(p, gnotifier, *map, x, y, radius); +} + +template +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 gnotifier(visitor); + cell.Visit(p ,gnotifier, *map, x, y, radius); +} + +template +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 gnotifier(visitor); + TypeContainerVisitor wnotifier(visitor); + cell.Visit(p, gnotifier, *map, x, y, radius); + cell.Visit(p, wnotifier, *map, x, y, radius); +} + #endif diff --git a/src/game/Map.cpp b/src/game/Map.cpp index 5eef7f386..fb2192365 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -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 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 p2grid_relocation(relocationNotifier); TypeContainerVisitor p2world_relocation(relocationNotifier); diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index fddd65afd..56e83bb8a 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -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 world_notifier(notifier); - TypeContainerVisitor 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) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index fabe6e9fc..03c90bc21 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10680" + #define REVISION_NR "10681" #endif // __REVISION_NR_H__