diff options
author | silver1ce <none@none> | 2010-01-05 20:34:50 +0200 |
---|---|---|
committer | silver1ce <none@none> | 2010-01-05 20:34:50 +0200 |
commit | 55d9ff7e35295e60a30e7d026da6883e57c690fd (patch) | |
tree | eb92ae97e53949cd28db77001b7d85c9bb658814 | |
parent | 082e7bac479137a8b71e99f0ba5e1fafad7e5d1d (diff) |
update cell search methtod (visiting grids by coords)
the old way will miss the grids when non standart cell size used
--HG--
branch : trunk
-rw-r--r-- | src/game/Cell.h | 1 | ||||
-rw-r--r-- | src/game/CellImpl.h | 70 |
2 files changed, 15 insertions, 56 deletions
diff --git a/src/game/Cell.h b/src/game/Cell.h index 5b9f62bdc64..802c7bd8c45 100644 --- a/src/game/Cell.h +++ b/src/game/Cell.h @@ -169,6 +169,7 @@ struct TRINITY_DLL_DECL Cell template<class LOCK_TYPE, class T, class CONTAINER> void Visit(const CellLock<LOCK_TYPE> &, TypeContainerVisitor<T, CONTAINER> &visitor, Map &, float radius, float x_off, float y_off) const; static CellArea CalculateCellArea(const WorldObject &obj, float radius); + static CellArea CalculateCellArea(float x, float y, float radius); private: template<class LOCK_TYPE, class T, class CONTAINER> void VisitCircle(const CellLock<LOCK_TYPE> &, TypeContainerVisitor<T, CONTAINER> &, Map &, const CellPair& , const CellPair& ) const; diff --git a/src/game/CellImpl.h b/src/game/CellImpl.h index 4f6bec82f8b..9dae6eeedcd 100644 --- a/src/game/CellImpl.h +++ b/src/game/CellImpl.h @@ -132,54 +132,6 @@ Cell::Visit(const CellLock<LOCK_TYPE> &l, TypeContainerVisitor<T, CONTAINER> &vi } } -template<class LOCK_TYPE,class T, class CONTAINER> -inline void -Cell::Visit(const CellLock<LOCK_TYPE> &l, TypeContainerVisitor<T, CONTAINER> &visitor, Map &m, float radius, float x_off, float y_off) const -{ - const CellPair &standing_cell = l.i_cellPair; - if (standing_cell.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || standing_cell.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP) - return; - - int left = 0, right = 0, upper = 0, lower = 0; - - // Origin = (CENTER_GRID_CELL_OFFSET, CENTER_GRID_CELL_OFFSET) - if(CENTER_GRID_CELL_OFFSET - x_off < radius) - ++right; - if(CENTER_GRID_CELL_OFFSET + x_off < radius) - ++left; - if(CENTER_GRID_CELL_OFFSET - y_off < radius) - ++upper; - if(CENTER_GRID_CELL_OFFSET + y_off < radius) - ++lower; - - if(!left && !right && !upper && !lower) - { - m.Visit(l, visitor); - return; - } - - CellPair begin_cell = standing_cell; - CellPair end_cell = standing_cell; - - begin_cell << left; //note: need change << if left > 1 - begin_cell -= lower; - end_cell >> right; - end_cell += upper; - - // 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 = l->data.Part.nocreate; - CellLock<LOCK_TYPE> lock(r_zone, cell_pair); - m.Visit(lock, visitor); - } - } -} - inline int CellHelper(const float radius) { if(radius < 1.0f) @@ -188,18 +140,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.GetObjectSize(); //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); @@ -219,7 +168,7 @@ inline CellArea Cell::CalculateCellArea(const WorldObject &obj, float radius) template<class LOCK_TYPE, class T, class CONTAINER> inline void -Cell::Visit(const CellLock<LOCK_TYPE> &l, TypeContainerVisitor<T, CONTAINER> &visitor, Map &m, const WorldObject &obj, float radius) const +Cell::Visit(const CellLock<LOCK_TYPE> &l, TypeContainerVisitor<T, CONTAINER> &visitor, Map &m, float radius, float x_off, float y_off) const { const CellPair &standing_cell = l.i_cellPair; if (standing_cell.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || standing_cell.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP) @@ -238,7 +187,7 @@ Cell::Visit(const CellLock<LOCK_TYPE> &l, TypeContainerVisitor<T, CONTAINER> &vi radius = 333.0f; //lets calculate object coord offsets from cell borders. - CellArea area = Cell::CalculateCellArea(obj, radius); + CellArea area = Cell::CalculateCellArea(x_off, y_off, radius); //if radius fits inside standing cell if (!area) { @@ -284,6 +233,15 @@ Cell::Visit(const CellLock<LOCK_TYPE> &l, TypeContainerVisitor<T, CONTAINER> &vi template<class LOCK_TYPE, class T, class CONTAINER> inline void +Cell::Visit(const CellLock<LOCK_TYPE> &l, TypeContainerVisitor<T, CONTAINER> &visitor, Map &m, const WorldObject &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 + Cell::Visit(l, visitor, m, radius + obj.GetObjectSize(), obj.GetPositionX(), obj.GetPositionY()); +} + +template<class LOCK_TYPE, class T, class CONTAINER> +inline void Cell::VisitCircle(const CellLock<LOCK_TYPE> &l, TypeContainerVisitor<T, CONTAINER> &visitor, Map &m, const CellPair& begin_cell, const CellPair& end_cell) const { //here is an algorithm for 'filling' circum-squared octagon |