aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/bindings/scripts/scripts/northrend/gundrak/boss_slad_ran.cpp4
-rw-r--r--src/framework/GameSystem/NGrid.h38
-rw-r--r--src/game/AchievementMgr.cpp2
-rw-r--r--src/game/Cell.h34
-rw-r--r--src/game/CellImpl.h156
-rw-r--r--src/game/ChatHandler.cpp2
-rw-r--r--src/game/Creature.cpp10
-rw-r--r--src/game/CreatureEventAI.cpp2
-rw-r--r--src/game/DynamicObject.cpp21
-rw-r--r--src/game/GameObject.cpp7
-rw-r--r--src/game/GridDefines.h8
-rw-r--r--src/game/Level3.cpp1
-rw-r--r--src/game/Map.cpp221
-rw-r--r--src/game/Map.h20
-rw-r--r--src/game/MapInstanced.cpp11
-rw-r--r--src/game/MapInstanced.h1
-rw-r--r--src/game/MapManager.cpp6
-rw-r--r--src/game/MapManager.h1
-rw-r--r--src/game/Object.cpp18
-rw-r--r--src/game/Object.h6
-rw-r--r--src/game/ObjectAccessor.cpp4
-rw-r--r--src/game/Player.cpp22
-rw-r--r--src/game/Spell.cpp9
-rw-r--r--src/game/SpellAuras.cpp8
-rw-r--r--src/game/SpellEffects.cpp4
-rw-r--r--src/game/Unit.cpp2
-rw-r--r--src/game/World.cpp73
-rw-r--r--src/game/World.h22
-rw-r--r--src/trinitycore/Main.cpp2
-rw-r--r--src/trinitycore/trinitycore.conf.dist23
30 files changed, 602 insertions, 136 deletions
diff --git a/src/bindings/scripts/scripts/northrend/gundrak/boss_slad_ran.cpp b/src/bindings/scripts/scripts/northrend/gundrak/boss_slad_ran.cpp
index 3dd0b651de1..05d95c46136 100644
--- a/src/bindings/scripts/scripts/northrend/gundrak/boss_slad_ran.cpp
+++ b/src/bindings/scripts/scripts/northrend/gundrak/boss_slad_ran.cpp
@@ -115,10 +115,10 @@ struct TRINITY_DLL_DECL boss_slad_ranAI : public ScriptedAI
if(uiSpawnTimer < diff)
{
if (uiPhase == 1)
- for (uint8 i = 0;i< HeroicMode ? 5 : 3;++i)
+ for (uint8 i = 0;i < (HeroicMode ? 5 : 3); ++i)
m_creature->SummonCreature(CREATURE_SNAKE, rand()%5, rand()%5, 0, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN,20000);
if (uiPhase == 2)
- for (uint8 i = 0;i< HeroicMode ? 5 : 3;++i)
+ for (uint8 i = 0;i < (HeroicMode ? 5 : 3); ++i)
m_creature->SummonCreature(CREATURE_CONSTRICTORS, rand()%5, rand()%5, 0, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN,20000);
uiSpawnTimer = 5000;
} else uiSpawnTimer -= diff;
diff --git a/src/framework/GameSystem/NGrid.h b/src/framework/GameSystem/NGrid.h
index 126703febd2..6ba5d10ffc1 100644
--- a/src/framework/GameSystem/NGrid.h
+++ b/src/framework/GameSystem/NGrid.h
@@ -81,8 +81,19 @@ class TRINITY_DLL_DECL NGrid
i_GridInfo = GridInfo(expiry, unload);
}
- const GridType& operator()(unsigned short x, unsigned short y) const { return i_cells[x][y]; }
- GridType& operator()(unsigned short x, unsigned short y) { return i_cells[x][y]; }
+ const GridType& operator()(unsigned short x, unsigned short y) const
+ {
+ ASSERT(x < N);
+ ASSERT(y < N);
+ return i_cells[x][y];
+ }
+
+ GridType& operator()(unsigned short x, unsigned short y)
+ {
+ ASSERT(x < N);
+ ASSERT(y < N);
+ return i_cells[x][y];
+ }
const uint32& GetGridId(void) const { return i_gridId; }
void SetGridId(const uint32 id) const { i_gridId = id; }
@@ -110,24 +121,24 @@ class TRINITY_DLL_DECL NGrid
template<class SPECIFIC_OBJECT> void AddWorldObject(const uint32 x, const uint32 y, SPECIFIC_OBJECT *obj, OBJECT_HANDLE hdl)
{
- i_cells[x][y].AddWorldObject(obj, hdl);
+ getGridType(x, y).AddWorldObject(obj, hdl);
}
template<class SPECIFIC_OBJECT> void RemoveWorldObject(const uint32 x, const uint32 y, SPECIFIC_OBJECT *obj, OBJECT_HANDLE hdl)
{
- i_cells[x][y].RemoveWorldObject(obj, hdl);
+ getGridType(x, y).RemoveWorldObject(obj, hdl);
}
template<class T, class TT> void Visit(TypeContainerVisitor<T, TypeMapContainer<TT> > &visitor)
{
for(unsigned int x=0; x < N; ++x)
for(unsigned int y=0; y < N; ++y)
- i_cells[x][y].Visit(visitor);
+ getGridType(x, y).Visit(visitor);
}
template<class T, class TT> void Visit(const uint32 &x, const uint32 &y, TypeContainerVisitor<T, TypeMapContainer<TT> > &visitor)
{
- i_cells[x][y].Visit(visitor);
+ getGridType(x, y).Visit(visitor);
}
unsigned int ActiveObjectsInGrid(void) const
@@ -141,26 +152,33 @@ class TRINITY_DLL_DECL NGrid
template<class SPECIFIC_OBJECT> const SPECIFIC_OBJECT* GetGridObject(const uint32 x, const uint32 y, OBJECT_HANDLE hdl) const
{
- return i_cells[x][y].template GetGridObject<SPECIFIC_OBJECT>(hdl);
+ return getGridType(x, y).template GetGridObject<SPECIFIC_OBJECT>(hdl);
}
template<class SPECIFIC_OBJECT> SPECIFIC_OBJECT* GetGridObject(const uint32 x, const uint32 y, OBJECT_HANDLE hdl)
{
- return i_cells[x][y].template GetGridObject<SPECIFIC_OBJECT>(hdl);
+ return getGridType(x, y).template GetGridObject<SPECIFIC_OBJECT>(hdl);
}
template<class SPECIFIC_OBJECT> bool AddGridObject(const uint32 x, const uint32 y, SPECIFIC_OBJECT *obj, OBJECT_HANDLE hdl)
{
- return i_cells[x][y].AddGridObject(hdl, obj);
+ return getGridType(x, y).AddGridObject(hdl, obj);
}
template<class SPECIFIC_OBJECT> bool RemoveGridObject(const uint32 x, const uint32 y, SPECIFIC_OBJECT *obj, OBJECT_HANDLE hdl)
{
- return i_cells[x][y].RemoveGridObject(obj, hdl);
+ return getGridType(x, y).RemoveGridObject(obj, hdl);
}
private:
+ GridType& getGridType(const uint32& x, const uint32& y)
+ {
+ ASSERT(x < N);
+ ASSERT(y < N);
+ return i_cells[x][y];
+ }
+
uint32 i_gridId;
GridInfo i_GridInfo;
GridReference<NGrid<N, ACTIVE_OBJECT, WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES, ThreadModel> > i_Reference;
diff --git a/src/game/AchievementMgr.cpp b/src/game/AchievementMgr.cpp
index f4512db3793..93fae0c6dd0 100644
--- a/src/game/AchievementMgr.cpp
+++ b/src/game/AchievementMgr.cpp
@@ -607,7 +607,7 @@ void AchievementMgr::SendAchievementEarned(AchievementEntry const* achievement)
MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::AchievementChatBuilder> > say_worker(GetPlayer(),sWorld.getConfig(CONFIG_LISTEN_RANGE_SAY),say_do);
TypeContainerVisitor<MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::AchievementChatBuilder> >, WorldTypeMapContainer > message(say_worker);
CellLock<GridReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, message, *GetPlayer()->GetMap());
+ cell_lock->Visit(cell_lock, message, *GetPlayer()->GetMap(), *GetPlayer(), sWorld.getConfig(CONFIG_LISTEN_RANGE_SAY));
}
WorldPacket data(SMSG_ACHIEVEMENT_EARNED, 8+4+8);
diff --git a/src/game/Cell.h b/src/game/Cell.h
index 6ccd3c96a00..9baf4104080 100644
--- a/src/game/Cell.h
+++ b/src/game/Cell.h
@@ -29,6 +29,7 @@
#include "GridDefines.h"
class Map;
+class WorldObject;
enum District
{
@@ -46,6 +47,27 @@ enum District
template<class T> struct CellLock;
+struct TRINITY_DLL_DECL CellArea
+{
+ CellArea() : right_offset(0), left_offset(0), upper_offset(0), lower_offset(0) {}
+ CellArea(int right, int left, int upper, int lower) : right_offset(right), left_offset(left), upper_offset(upper), lower_offset(lower) {}
+ bool operator!() const { return !right_offset && !left_offset && !upper_offset && !lower_offset; }
+
+ void ResizeBorders(CellPair& begin_cell, CellPair& end_cell) const
+ {
+ begin_cell << left_offset;
+ begin_cell -= lower_offset;
+ end_cell >> right_offset;
+ end_cell += upper_offset;
+ }
+
+ int right_offset;
+ int left_offset;
+ int upper_offset;
+ int lower_offset;
+};
+
+
struct TRINITY_DLL_DECL Cell
{
Cell() { data.All = 0; }
@@ -135,16 +157,22 @@ struct TRINITY_DLL_DECL Cell
{
unsigned grid_x : 6;
unsigned grid_y : 6;
- unsigned cell_x : 4;
- unsigned cell_y : 4;
+ unsigned cell_x : 6;
+ unsigned cell_y : 6;
unsigned nocreate : 1;
- unsigned reserved : 11;
+ unsigned reserved : 7;
} Part;
uint32 All;
} data;
template<class LOCK_TYPE, class T, class CONTAINER> void Visit(const CellLock<LOCK_TYPE> &, TypeContainerVisitor<T, CONTAINER> &visitor, Map &) const;
+ template<class LOCK_TYPE, class T, class CONTAINER> void Visit(const CellLock<LOCK_TYPE> &, TypeContainerVisitor<T, CONTAINER> &visitor, Map &m, const WorldObject &obj, float radius) const;
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);
+
+private:
+ template<class LOCK_TYPE, class T, class CONTAINER> void VisitCircle(const CellLock<LOCK_TYPE> &, TypeContainerVisitor<T, CONTAINER> &, Map &, const CellPair& , const CellPair& ) const;
};
template<class T>
diff --git a/src/game/CellImpl.h b/src/game/CellImpl.h
index 362c12579bb..d86091ee40a 100644
--- a/src/game/CellImpl.h
+++ b/src/game/CellImpl.h
@@ -25,6 +25,7 @@
#include "Cell.h"
#include "Map.h"
+#include "Object.h"
inline Cell::Cell(CellPair const& p)
{
@@ -178,5 +179,160 @@ Cell::Visit(const CellLock<LOCK_TYPE> &l, TypeContainerVisitor<T, CONTAINER> &vi
}
}
}
+
+inline int CellHelper(const float radius)
+{
+ if(radius < 1.0f)
+ return 0;
+
+ return (int)ceilf(radius/SIZE_OF_GRID_CELL);
+}
+
+inline CellArea Cell::CalculateCellArea(const WorldObject &obj, 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_val = floor(x_offset + CENTER_GRID_CELL_ID + 0.5f);
+ const float y_val = floor(y_offset + CENTER_GRID_CELL_ID + 0.5f);
+
+ const float x_off = (x_offset - x_val + CENTER_GRID_CELL_ID) * SIZE_OF_GRID_CELL;
+ const float y_off = (y_offset - y_val + CENTER_GRID_CELL_ID) * SIZE_OF_GRID_CELL;
+
+ const float tmp_diff = radius - CENTER_GRID_CELL_OFFSET;
+ //lets calculate upper/lower/right/left corners for cell search
+ int right = CellHelper(tmp_diff + x_off);
+ int left = CellHelper(tmp_diff - x_off);
+ int upper = CellHelper(tmp_diff + y_off);
+ int lower = CellHelper(tmp_diff - y_off);
+
+ return CellArea(right, left, upper, lower);
+}
+
+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
+{
+ 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;
+
+ //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)
+ {
+ m.Visit(l, visitor);
+ return;
+ }
+
+ //lets calculate object coord offsets from cell borders.
+ CellArea area = Cell::CalculateCellArea(obj, radius);
+ //if radius fits inside standing cell
+ if(!area)
+ {
+ m.Visit(l, visitor);
+ return;
+ }
+
+ CellPair begin_cell = standing_cell;
+ CellPair end_cell = standing_cell;
+
+ area.ResizeBorders(begin_cell, end_cell);
+ //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(((end_cell.x_coord - begin_cell.x_coord) > 4) && ((end_cell.y_coord - begin_cell.y_coord) > 4))
+ {
+ VisitCircle(l, visitor, m, begin_cell, end_cell);
+ return;
+ }
+
+ //ALWAYS visit standing cell first!!! Since we deal with small radiuses
+ //it is very essential to call visitor for standing cell firstly...
+ m.Visit(l, visitor);
+
+ // 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);
+ //lets skip standing cell since we already visited it
+ if(cell_pair != standing_cell)
+ {
+ 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);
+ }
+ }
+ }
+}
+
+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
+ 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)
+ {
+ 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);
+ }
+ }
+
+ //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...
+ CellPair cell_pair_left(x_start - step, y);
+ Cell r_zone_left(cell_pair_left);
+ r_zone_left.data.Part.nocreate = l->data.Part.nocreate;
+ CellLock<LOCK_TYPE> lock_left(r_zone_left, cell_pair_left);
+ m.Visit(lock_left, visitor);
+
+ //right trapezoid cell visit
+ CellPair cell_pair_right(x_end + step, y);
+ Cell r_zone_right(cell_pair_right);
+ r_zone_right.data.Part.nocreate = l->data.Part.nocreate;
+ CellLock<LOCK_TYPE> lock_right(r_zone_right, cell_pair_right);
+ m.Visit(lock_right, visitor);
+ }
+ }
+}
#endif
diff --git a/src/game/ChatHandler.cpp b/src/game/ChatHandler.cpp
index 082a4a6beac..e5aaab05c9d 100644
--- a/src/game/ChatHandler.cpp
+++ b/src/game/ChatHandler.cpp
@@ -670,7 +670,7 @@ void WorldSession::HandleTextEmoteOpcode( WorldPacket & recv_data )
MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::EmoteChatBuilder > > emote_worker(GetPlayer(),sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE),emote_do);
TypeContainerVisitor<MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::EmoteChatBuilder > >, WorldTypeMapContainer > message(emote_worker);
CellLock<GridReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, message, *GetPlayer()->GetMap());
+ cell_lock->Visit(cell_lock, message, *GetPlayer()->GetMap(), *GetPlayer(), sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE));
GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE, text_emote, 0, unit);
diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp
index 4aa4c48ffe8..b2261bb4b8d 100644
--- a/src/game/Creature.cpp
+++ b/src/game/Creature.cpp
@@ -655,7 +655,7 @@ void Creature::DoFleeToGetAssistance()
TypeContainerVisitor<MaNGOS::CreatureLastSearcher<MaNGOS::NearestAssistCreatureInCreatureRangeCheck>, GridTypeMapContainer > grid_creature_searcher(searcher);
CellLock<GridReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, grid_creature_searcher, *GetMap());
+ cell_lock->Visit(cell_lock, grid_creature_searcher, *GetMap(), *this, radius);
SetNoSearchAssistance(true);
if(!pCreature)
@@ -2051,8 +2051,8 @@ Unit* Creature::SelectNearestTarget(float dist) const
TypeContainerVisitor<Trinity::UnitLastSearcher<Trinity::NearestHostileUnitInAttackDistanceCheck>, GridTypeMapContainer > grid_unit_searcher(searcher);
CellLock<GridReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, world_unit_searcher, *GetMap());
- cell_lock->Visit(cell_lock, grid_unit_searcher, *GetMap());
+ cell_lock->Visit(cell_lock, world_unit_searcher, *GetMap(), *this, ATTACK_DISTANCE);
+ cell_lock->Visit(cell_lock, grid_unit_searcher, *GetMap(), *this, ATTACK_DISTANCE);
}
return target;
@@ -2082,7 +2082,7 @@ void Creature::CallAssistance()
TypeContainerVisitor<Trinity::CreatureListSearcher<Trinity::AnyAssistCreatureInRangeCheck>, GridTypeMapContainer > grid_creature_searcher(searcher);
CellLock<GridReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, grid_creature_searcher, *GetMap());
+ cell_lock->Visit(cell_lock, grid_creature_searcher, *GetMap(), *this, radius);
}
if (!assistList.empty())
@@ -2116,7 +2116,7 @@ void Creature::CallForHelp(float fRadius)
TypeContainerVisitor<MaNGOS::CreatureWorker<MaNGOS::CallOfHelpCreatureInRangeDo>, GridTypeMapContainer > grid_creature_searcher(worker);
CellLock<GridReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, grid_creature_searcher, *GetMap());
+ cell_lock->Visit(cell_lock, grid_creature_searcher, *GetMap(), *this, fRadius);
}
bool Creature::CanAssistTo(const Unit* u, const Unit* enemy, bool checkfaction /*= true*/) const
diff --git a/src/game/CreatureEventAI.cpp b/src/game/CreatureEventAI.cpp
index cb6cc3e7869..ad7df073cc1 100644
--- a/src/game/CreatureEventAI.cpp
+++ b/src/game/CreatureEventAI.cpp
@@ -1173,7 +1173,7 @@ Unit* CreatureEventAI::DoSelectLowestHpFriendly(float range, uint32 MinHPDiff)
TypeContainerVisitor<MaNGOS::UnitLastSearcher<MaNGOS::MostHPMissingInRange>, GridTypeMapContainer > grid_unit_searcher(searcher);
CellLock<GridReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, grid_unit_searcher, *m_creature->GetMap());
+ cell_lock->Visit(cell_lock, grid_unit_searcher, *m_creature->GetMap(), *m_creature, range);
return pUnit;
}
diff --git a/src/game/DynamicObject.cpp b/src/game/DynamicObject.cpp
index e616dc2f809..30147732b08 100644
--- a/src/game/DynamicObject.cpp
+++ b/src/game/DynamicObject.cpp
@@ -126,6 +126,27 @@ void DynamicObject::Update(uint32 p_time)
else
deleteThis = true;
+ /*
+ // have radius and work as persistent effect
+ if(m_radius)
+ {
+ // TODO: make a timer and update this in larger intervals
+ CellPair p(MaNGOS::ComputeCellPair(GetPositionX(), GetPositionY()));
+ Cell cell(p);
+ cell.data.Part.reserved = ALL_DISTRICT;
+ cell.SetNoCreate();
+
+ MaNGOS::DynamicObjectUpdater notifier(*this, caster);
+
+ TypeContainerVisitor<MaNGOS::DynamicObjectUpdater, WorldTypeMapContainer > world_object_notifier(notifier);
+ TypeContainerVisitor<MaNGOS::DynamicObjectUpdater, GridTypeMapContainer > grid_object_notifier(notifier);
+
+ CellLock<GridReadGuard> cell_lock(cell, p);
+ cell_lock->Visit(cell_lock, world_object_notifier, *GetMap(), *this, m_radius);
+ cell_lock->Visit(cell_lock, grid_object_notifier, *GetMap(), *this, m_radius);
+ }
+ */
+
if (m_effMask)
{
if (m_updateTimer < p_time)
diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp
index e92fcb70863..d22acfe57b3 100644
--- a/src/game/GameObject.cpp
+++ b/src/game/GameObject.cpp
@@ -858,7 +858,7 @@ void GameObject::TriggeringLinkedGameObject( uint32 trapEntry, Unit* target)
TypeContainerVisitor<Trinity::GameObjectLastSearcher<Trinity::NearestGameObjectEntryInObjectRangeCheck>, GridTypeMapContainer > object_checker(checker);
CellLock<GridReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, object_checker, *GetMap());
+ cell_lock->Visit(cell_lock, object_checker, *GetMap(), *target, range);
}
// found correct GO
@@ -880,7 +880,7 @@ GameObject* GameObject::LookupFishingHoleAround(float range)
CellLock<GridReadGuard> cell_lock(cell, p);
TypeContainerVisitor<Trinity::GameObjectSearcher<Trinity::NearestGameObjectFishingHole>, GridTypeMapContainer > grid_object_checker(checker);
- cell_lock->Visit(cell_lock, grid_object_checker, *GetMap());
+ cell_lock->Visit(cell_lock, grid_object_checker, *GetMap(), *this, range);
return ok;
}
@@ -1128,7 +1128,8 @@ void GameObject::Use(Unit* user)
//fish catched
player->UpdateFishingSkill();
- GameObject* ok = LookupFishingHoleAround(DEFAULT_VISIBILITY_DISTANCE);
+ //TODO: find reasonable value for fishing hole search
+ GameObject* ok = LookupFishingHoleAround(20.0f + CONTACT_DISTANCE);
if (ok)
{
player->SendLoot(ok->GetGUID(),LOOT_FISHINGHOLE);
diff --git a/src/game/GridDefines.h b/src/game/GridDefines.h
index 05080521f58..c51b507fcbd 100644
--- a/src/game/GridDefines.h
+++ b/src/game/GridDefines.h
@@ -33,11 +33,7 @@ class GameObject;
class Pet;
class Player;
-#ifdef LARGE_CELL
-#define MAX_NUMBER_OF_CELLS 4
-#else
#define MAX_NUMBER_OF_CELLS 8
-#endif
#define MAX_NUMBER_OF_GRIDS 64
@@ -93,7 +89,7 @@ struct TRINITY_DLL_DECL CoordPair
void operator<<(const uint32 val)
{
- if( x_coord >= val )
+ if( x_coord > val )
x_coord -= val;
else
x_coord = 0;
@@ -109,7 +105,7 @@ struct TRINITY_DLL_DECL CoordPair
void operator-=(const uint32 val)
{
- if( y_coord >= val )
+ if( y_coord > val )
y_coord -= val;
else
y_coord = 0;
diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp
index bd4208c9647..c2e7857fcfe 100644
--- a/src/game/Level3.cpp
+++ b/src/game/Level3.cpp
@@ -686,6 +686,7 @@ bool ChatHandler::HandleReloadConfigCommand(const char* /*args*/)
{
sLog.outString( "Re-Loading config settings..." );
sWorld.LoadConfigSettings(true);
+ MapManager::Instance().InitializeVisibilityDistanceInfo();
SendGlobalGMSysMessage("World config settings reloaded.");
return true;
}
diff --git a/src/game/Map.cpp b/src/game/Map.cpp
index 6b51fb80d4d..2f8c4d0e152 100644
--- a/src/game/Map.cpp
+++ b/src/game/Map.cpp
@@ -45,6 +45,7 @@
#define DEFAULT_GRID_EXPIRY 300
#define MAX_GRID_LOAD_TIME 50
+#define MAX_CREATURE_ATTACK_RADIUS (45.0f * sWorld.getRate(RATE_CREATURE_AGGRO))
GridState* si_GridStates[MAX_GRID_STATE];
@@ -210,7 +211,8 @@ void Map::DeleteStateMachine()
Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode, Map* _parent)
: i_mapEntry (sMapStore.LookupEntry(id)), i_spawnMode(SpawnMode), i_InstanceId(InstanceId), m_unloadTimer(0),
m_activeNonPlayersIter(m_activeNonPlayers.end()),
- i_gridExpiry(expiry), m_parentMap(_parent ? _parent : this)
+ i_gridExpiry(expiry), m_parentMap(_parent ? _parent : this),
+ m_VisibleDistance(DEFAULT_VISIBILITY_DISTANCE)
, i_notifyLock(false), i_scriptLock(false)
{
m_notifyTimer.SetInterval(IN_MILISECONDS/2);
@@ -224,6 +226,15 @@ Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode, Map* _par
setNGrid(NULL, idx, j);
}
}
+
+ //lets initialize visibility distance for map
+ Map::InitVisibilityDistance();
+}
+
+void Map::InitVisibilityDistance()
+{
+ //init visibility for continents
+ m_VisibleDistance = sWorld.GetMaxVisibleDistanceOnContinents();
}
// Template specialization of utility methods
@@ -356,8 +367,8 @@ Map::EnsureGridCreated(const GridPair &p)
getNGrid(p.x_coord, p.y_coord)->SetGridState(GRID_STATE_IDLE);
//z coord
- int gx=63-p.x_coord;
- int gy=63-p.y_coord;
+ int gx = (MAX_NUMBER_OF_GRIDS - 1) - p.x_coord;
+ int gy = (MAX_NUMBER_OF_GRIDS - 1) - p.y_coord;
if(!GridMaps[gx][gy])
LoadMapAndVMap(gx,gy);
@@ -486,6 +497,102 @@ Map::Add(T *obj)
AddNotifier(obj);
}
+/*
+void Map::MessageBroadcast(Player *player, WorldPacket *msg, bool to_self)
+{
+ CellPair p = MaNGOS::ComputeCellPair(player->GetPositionX(), player->GetPositionY());
+
+ if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP )
+ {
+ sLog.outError("Map::MessageBroadcast: Player (GUID: %u) have invalid coordinates X:%f Y:%f grid cell [%u:%u]", player->GetGUIDLow(), player->GetPositionX(), player->GetPositionY(), p.x_coord, p.y_coord);
+ return;
+ }
+
+ Cell cell(p);
+ cell.data.Part.reserved = ALL_DISTRICT;
+ cell.SetNoCreate();
+
+ if( !loaded(GridPair(cell.data.Part.grid_x, cell.data.Part.grid_y)) )
+ return;
+
+ MaNGOS::MessageDeliverer post_man(*player, msg, to_self);
+ TypeContainerVisitor<MaNGOS::MessageDeliverer, WorldTypeMapContainer > message(post_man);
+ CellLock<ReadGuard> cell_lock(cell, p);
+ cell_lock->Visit(cell_lock, message, *this, *player, GetVisibilityDistance());
+}
+
+void Map::MessageBroadcast(WorldObject *obj, WorldPacket *msg)
+{
+ CellPair p = MaNGOS::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY());
+
+ if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP )
+ {
+ sLog.outError("Map::MessageBroadcast: Object (GUID: %u TypeId: %u) have invalid coordinates X:%f Y:%f grid cell [%u:%u]", obj->GetGUIDLow(), obj->GetTypeId(), obj->GetPositionX(), obj->GetPositionY(), p.x_coord, p.y_coord);
+ return;
+ }
+
+ Cell cell(p);
+ cell.data.Part.reserved = ALL_DISTRICT;
+ cell.SetNoCreate();
+
+ if( !loaded(GridPair(cell.data.Part.grid_x, cell.data.Part.grid_y)) )
+ return;
+
+ //TODO: currently on continents when Visibility.Distance.InFlight > Visibility.Distance.Continents
+ //we have alot of blinking mobs because monster move packet send is broken...
+ MaNGOS::ObjectMessageDeliverer post_man(*obj,msg);
+ TypeContainerVisitor<MaNGOS::ObjectMessageDeliverer, WorldTypeMapContainer > message(post_man);
+ CellLock<ReadGuard> cell_lock(cell, p);
+ cell_lock->Visit(cell_lock, message, *this, *obj, GetVisibilityDistance());
+}
+
+void Map::MessageDistBroadcast(Player *player, WorldPacket *msg, float dist, bool to_self, bool own_team_only)
+{
+ CellPair p = MaNGOS::ComputeCellPair(player->GetPositionX(), player->GetPositionY());
+
+ if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP )
+ {
+ sLog.outError("Map::MessageBroadcast: Player (GUID: %u) have invalid coordinates X:%f Y:%f grid cell [%u:%u]", player->GetGUIDLow(), player->GetPositionX(), player->GetPositionY(), p.x_coord, p.y_coord);
+ return;
+ }
+
+ Cell cell(p);
+ cell.data.Part.reserved = ALL_DISTRICT;
+ cell.SetNoCreate();
+
+ if( !loaded(GridPair(cell.data.Part.grid_x, cell.data.Part.grid_y)) )
+ return;
+
+ MaNGOS::MessageDistDeliverer post_man(*player, msg, dist, to_self, own_team_only);
+ TypeContainerVisitor<MaNGOS::MessageDistDeliverer , WorldTypeMapContainer > message(post_man);
+ CellLock<ReadGuard> cell_lock(cell, p);
+ cell_lock->Visit(cell_lock, message, *this, *player, dist);
+}
+
+void Map::MessageDistBroadcast(WorldObject *obj, WorldPacket *msg, float dist)
+{
+ CellPair p = MaNGOS::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY());
+
+ if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP )
+ {
+ sLog.outError("Map::MessageBroadcast: Object (GUID: %u TypeId: %u) have invalid coordinates X:%f Y:%f grid cell [%u:%u]", obj->GetGUIDLow(), obj->GetTypeId(), obj->GetPositionX(), obj->GetPositionY(), p.x_coord, p.y_coord);
+ return;
+ }
+
+ Cell cell(p);
+ cell.data.Part.reserved = ALL_DISTRICT;
+ cell.SetNoCreate();
+
+ if( !loaded(GridPair(cell.data.Part.grid_x, cell.data.Part.grid_y)) )
+ return;
+
+ MaNGOS::ObjectMessageDistDeliverer post_man(*obj, msg, dist);
+ TypeContainerVisitor<MaNGOS::ObjectMessageDistDeliverer, WorldTypeMapContainer > message(post_man);
+ CellLock<ReadGuard> cell_lock(cell, p);
+ cell_lock->Visit(cell_lock, message, *this, *obj, dist);
+}
+*/
+
bool Map::loaded(const GridPair &p) const
{
return ( getNGrid(p.x_coord, p.y_coord) && isGridObjectDataLoaded(p.x_coord, p.y_coord) );
@@ -513,7 +620,7 @@ void Map::RelocationNotify()
if(dist > 10.0f)
{
Trinity::VisibleChangesNotifier notifier(*unit);
- VisitWorld(unit->oldX, unit->oldY, World::GetMaxVisibleDistance(), notifier);
+ VisitWorld(unit->oldX, unit->oldY, GetVisibilityDistance(), notifier);
dist = 0;
}
@@ -521,15 +628,15 @@ void Map::RelocationNotify()
{
Trinity::PlayerRelocationNotifier notifier(*((Player*)unit));
//if(((Player*)unit)->m_seer != unit)
- VisitAll(((Player*)unit)->m_seer->GetPositionX(), ((Player*)unit)->m_seer->GetPositionY(), World::GetMaxVisibleDistance() + dist, notifier);
+ VisitAll(((Player*)unit)->m_seer->GetPositionX(), ((Player*)unit)->m_seer->GetPositionY(), unit->GetMap()->GetVisibilityDistance() + dist, notifier);
//else
- //VisitAll(((Player*)unit)->GetPositionX(), ((Player*)unit)->GetPositionY(), World::GetMaxVisibleDistance() + dist, notifier);
+ //VisitAll(((Player*)unit)->GetPositionX(), ((Player*)unit)->GetPositionY(), unit->GetMap()->GetVisibilityDistance() + dist, notifier);
notifier.Notify();
}
else
{
Trinity::CreatureRelocationNotifier notifier(*((Creature*)unit));
- VisitAll(unit->GetPositionX(), unit->GetPositionY(), World::GetMaxVisibleDistance() + dist, notifier);
+ VisitAll(unit->GetPositionX(), unit->GetPositionY(), GetVisibilityDistance() + dist, notifier);
}
}
for(std::vector<Unit*>::iterator iter = i_unitsToNotify.begin(); iter != i_unitsToNotify.end(); ++iter)
@@ -631,8 +738,9 @@ void Map::Update(const uint32 &t_diff)
// the overloaded operators handle range checking
// so ther's no need for range checking inside the loop
CellPair begin_cell(standing_cell), end_cell(standing_cell);
- begin_cell << 1; begin_cell -= 1; // upper left
- end_cell >> 1; end_cell += 1; // lower right
+ //lets update mobs/objects in ALL visible cells around player!
+ CellArea area = Cell::CalculateCellArea(*plr, GetVisibilityDistance());
+ area.ResizeBorders(begin_cell, end_cell);
for(uint32 x = begin_cell.x_coord; x <= end_cell.x_coord; ++x)
{
@@ -1067,8 +1175,8 @@ bool Map::UnloadGrid(const uint32 &x, const uint32 &y, bool unloadAll)
delete grid;
setNGrid(NULL, x, y);
}
- int gx=63-x;
- int gy=63-y;
+ int gx = (MAX_NUMBER_OF_GRIDS - 1) - x;
+ int gy = (MAX_NUMBER_OF_GRIDS - 1) - y;
// delete grid map, but don't delete if it is from parent map (and thus only reference)
//+++if (GridMaps[gx][gy]) don't check for GridMaps[gx][gy], we might have to unload vmaps
@@ -2003,8 +2111,64 @@ void Map::UpdateObjectVisibility( WorldObject* obj, Cell cell, CellPair cellpair
Trinity::VisibleChangesNotifier notifier(*obj);
TypeContainerVisitor<Trinity::VisibleChangesNotifier, WorldTypeMapContainer > player_notifier(notifier);
CellLock<GridReadGuard> cell_lock(cell, cellpair);
- cell_lock->Visit(cell_lock, player_notifier, *this);
+ cell_lock->Visit(cell_lock, player_notifier, *this, *obj, GetVisibilityDistance());
+}
+
+/*
+void Map::UpdatePlayerVisibility( Player* player, Cell cell, CellPair cellpair )
+{
+ cell.data.Part.reserved = ALL_DISTRICT;
+
+ MaNGOS::PlayerNotifier pl_notifier(*player);
+ TypeContainerVisitor<MaNGOS::PlayerNotifier, WorldTypeMapContainer > player_notifier(pl_notifier);
+
+ CellLock<ReadGuard> cell_lock(cell, cellpair);
+ cell_lock->Visit(cell_lock, player_notifier, *this, *player, GetVisibilityDistance());
+}
+
+void Map::UpdateObjectsVisibilityFor( Player* player, Cell cell, CellPair cellpair )
+{
+ MaNGOS::VisibleNotifier notifier(*player);
+
+ cell.data.Part.reserved = ALL_DISTRICT;
+ cell.SetNoCreate();
+ TypeContainerVisitor<MaNGOS::VisibleNotifier, WorldTypeMapContainer > world_notifier(notifier);
+ TypeContainerVisitor<MaNGOS::VisibleNotifier, GridTypeMapContainer > grid_notifier(notifier);
+ CellLock<GridReadGuard> cell_lock(cell, cellpair);
+ cell_lock->Visit(cell_lock, world_notifier, *this, *player, GetVisibilityDistance());
+ cell_lock->Visit(cell_lock, grid_notifier, *this, *player, GetVisibilityDistance());
+
+ // send data
+ notifier.Notify();
+}
+
+void Map::PlayerRelocationNotify( Player* player, Cell cell, CellPair cellpair )
+{
+ CellLock<ReadGuard> cell_lock(cell, 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);
+
+ cell_lock->Visit(cell_lock, p2grid_relocation, *this, *player, MAX_CREATURE_ATTACK_RADIUS);
+ cell_lock->Visit(cell_lock, p2world_relocation, *this, *player, MAX_CREATURE_ATTACK_RADIUS);
+}
+
+void Map::CreatureRelocationNotify(Creature *creature, Cell cell, CellPair cellpair)
+{
+ CellLock<ReadGuard> cell_lock(cell, cellpair);
+ MaNGOS::CreatureRelocationNotifier relocationNotifier(*creature);
+ cell.data.Part.reserved = ALL_DISTRICT;
+ cell.SetNoCreate(); // not trigger load unloaded grids at notifier call
+
+ TypeContainerVisitor<MaNGOS::CreatureRelocationNotifier, WorldTypeMapContainer > c2world_relocation(relocationNotifier);
+ TypeContainerVisitor<MaNGOS::CreatureRelocationNotifier, GridTypeMapContainer > c2grid_relocation(relocationNotifier);
+
+ cell_lock->Visit(cell_lock, c2world_relocation, *this, *creature, MAX_CREATURE_ATTACK_RADIUS);
+ cell_lock->Visit(cell_lock, c2grid_relocation, *this, *creature, MAX_CREATURE_ATTACK_RADIUS);
}
+*/
void Map::SendInitSelf( Player * player )
{
@@ -2214,12 +2378,20 @@ void Map::SendToPlayers(WorldPacket const* data) const
bool Map::ActiveObjectsNearGrid(uint32 x, uint32 y) const
{
+ ASSERT(x < MAX_NUMBER_OF_GRIDS);
+ ASSERT(y < MAX_NUMBER_OF_GRIDS);
+
CellPair cell_min(x*MAX_NUMBER_OF_CELLS, y*MAX_NUMBER_OF_CELLS);
CellPair cell_max(cell_min.x_coord + MAX_NUMBER_OF_CELLS, cell_min.y_coord+MAX_NUMBER_OF_CELLS);
- cell_min << 2;
- cell_min -= 2;
- cell_max >> 2;
- cell_max += 2;
+
+ //we must find visible range in cells so we unload only non-visible cells...
+ float viewDist = GetVisibilityDistance();
+ int cell_range = (int)ceilf(viewDist / SIZE_OF_GRID_CELL) + 1;
+
+ cell_min << cell_range;
+ cell_min -= cell_range;
+ cell_max >> cell_range;
+ cell_max += cell_range;
for(MapRefManager::const_iterator iter = m_mapRefManager.begin(); iter != m_mapRefManager.end(); ++iter)
{
@@ -2303,6 +2475,9 @@ InstanceMap::InstanceMap(uint32 id, time_t expiry, uint32 InstanceId, uint8 Spaw
m_resetAfterUnload(false), m_unloadWhenEmpty(false),
i_data(NULL), i_script_id(0)
{
+ //lets initialize visibility distance for dungeons
+ InstanceMap::InitVisibilityDistance();
+
// the timer is started by default, and stopped when the first player joins
// this make sure it gets unloaded if for some reason no player joins
m_unloadTimer = std::max(sWorld.getConfig(CONFIG_INSTANCE_UNLOAD_DELAY), (uint32)MIN_UNLOAD_DELAY);
@@ -2317,6 +2492,12 @@ InstanceMap::~InstanceMap()
}
}
+void InstanceMap::InitVisibilityDistance()
+{
+ //init visibility distance for instances
+ m_VisibleDistance = sWorld.GetMaxVisibleDistanceInInstances();
+}
+
/*
Do map specific checks to see if the player can enter
*/
@@ -2630,12 +2811,20 @@ uint32 InstanceMap::GetMaxPlayers() const
BattleGroundMap::BattleGroundMap(uint32 id, time_t expiry, uint32 InstanceId, Map* _parent)
: Map(id, expiry, InstanceId, DIFFICULTY_NORMAL, _parent)
{
+ //lets initialize visibility distance for BG/Arenas
+ BattleGroundMap::InitVisibilityDistance();
}
BattleGroundMap::~BattleGroundMap()
{
}
+void BattleGroundMap::InitVisibilityDistance()
+{
+ //init visibility distance for BG/Arenas
+ m_VisibleDistance = sWorld.GetMaxVisibleDistanceInBGArenas();
+}
+
bool BattleGroundMap::CanEnter(Player * player)
{
if(player->GetMapRef().getTarget() == this)
diff --git a/src/game/Map.h b/src/game/Map.h
index cc411300f15..a8d94d350e7 100644
--- a/src/game/Map.h
+++ b/src/game/Map.h
@@ -283,6 +283,17 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
virtual void Update(const uint32&);
+ /*
+ void MessageBroadcast(Player *, WorldPacket *, bool to_self);
+ void MessageBroadcast(WorldObject *, WorldPacket *);
+ void MessageDistBroadcast(Player *, WorldPacket *, float dist, bool to_self, bool own_team_only = false);
+ void MessageDistBroadcast(WorldObject *, WorldPacket *, float dist);
+ */
+
+ float GetVisibilityDistance() const { return m_VisibleDistance; }
+ //function for setting up visibility distance for maps on per-type/per-Id basis
+ virtual void InitVisibilityDistance();
+
void PlayerRelocation(Player *, float x, float y, float z, float angl);
void CreatureRelocation(Creature *creature, float x, float y, float, float);
@@ -453,7 +464,6 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
GridMap *GetGrid(float x, float y);
void SetTimer(uint32 t) { i_gridExpiry = t < MIN_GRID_DELAY ? MIN_GRID_DELAY : t; }
- //uint64 CalculateGridMask(const uint32 &y) const;
void SendInitSelf( Player * player );
@@ -477,6 +487,8 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
NGridType* getNGrid(uint32 x, uint32 y) const
{
+ ASSERT(x < MAX_NUMBER_OF_GRIDS);
+ ASSERT(y < MAX_NUMBER_OF_GRIDS);
return i_grids[x][y];
}
@@ -496,6 +508,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
uint8 i_spawnMode;
uint32 i_InstanceId;
uint32 m_unloadTimer;
+ float m_VisibleDistance;
MapRefManager m_mapRefManager;
MapRefManager::iterator m_mapRefIter;
@@ -594,6 +607,8 @@ class TRINITY_DLL_SPEC InstanceMap : public Map
void SendResetWarnings(uint32 timeLeft) const;
void SetResetSchedule(bool on);
uint32 GetMaxPlayers() const;
+
+ virtual void InitVisibilityDistance();
private:
bool m_resetAfterUnload;
bool m_unloadWhenEmpty;
@@ -611,7 +626,10 @@ class TRINITY_DLL_SPEC BattleGroundMap : public Map
void Remove(Player *, bool);
bool CanEnter(Player* player);
void SetUnload();
+ //void UnloadAll(bool pForce);
void RemoveAllPlayers();
+
+ virtual void InitVisibilityDistance();
};
/*inline
diff --git a/src/game/MapInstanced.cpp b/src/game/MapInstanced.cpp
index d06d2b9b677..28faf52bf19 100644
--- a/src/game/MapInstanced.cpp
+++ b/src/game/MapInstanced.cpp
@@ -34,6 +34,17 @@ MapInstanced::MapInstanced(uint32 id, time_t expiry) : Map(id, expiry, 0, 0)
memset(&GridMapReference, 0, MAX_NUMBER_OF_GRIDS*MAX_NUMBER_OF_GRIDS*sizeof(uint16));
}
+void MapInstanced::InitVisibilityDistance()
+{
+ if(m_InstancedMaps.empty())
+ return;
+ //initialize visibility distances for all instance copies
+ for (InstancedMaps::iterator i = m_InstancedMaps.begin(); i != m_InstancedMaps.end(); ++i)
+ {
+ (*i).second->InitVisibilityDistance();
+ }
+}
+
void MapInstanced::Update(const uint32& t)
{
// take care of loaded GridMaps (when unused, unload it!)
diff --git a/src/game/MapInstanced.h b/src/game/MapInstanced.h
index d6b2091a8d8..22622d362ce 100644
--- a/src/game/MapInstanced.h
+++ b/src/game/MapInstanced.h
@@ -59,6 +59,7 @@ class TRINITY_DLL_DECL MapInstanced : public Map
}
InstancedMaps &GetInstancedMaps() { return m_InstancedMaps; }
+ virtual void InitVisibilityDistance();
private:
diff --git a/src/game/MapManager.cpp b/src/game/MapManager.cpp
index 93f3db814f3..0da5b19eb93 100644
--- a/src/game/MapManager.cpp
+++ b/src/game/MapManager.cpp
@@ -76,6 +76,12 @@ MapManager::Initialize()
InitMaxInstanceId();
}
+void MapManager::InitializeVisibilityDistanceInfo()
+{
+ for(MapMapType::iterator iter=i_maps.begin(); iter != i_maps.end(); ++iter)
+ (*iter).second->InitVisibilityDistance();
+}
+
// debugging code, should be deleted some day
void MapManager::checkAndCorrectGridStatesArray()
{
diff --git a/src/game/MapManager.h b/src/game/MapManager.h
index 896cc515e4a..f9e64240686 100644
--- a/src/game/MapManager.h
+++ b/src/game/MapManager.h
@@ -121,6 +121,7 @@ class MANGOS_DLL_DECL MapManager : public MaNGOS::Singleton<MapManager, MaNGOS::
void RemoveBonesFromMap(uint32 mapid, uint64 guid, float x, float y);
uint32 GenerateInstanceId() { return ++i_MaxInstanceId; }
void InitMaxInstanceId();
+ void InitializeVisibilityDistanceInfo();
/* statistics */
uint32 GetNumInstances();
diff --git a/src/game/Object.cpp b/src/game/Object.cpp
index c13a41d9d8c..6c892ff1d5d 100644
--- a/src/game/Object.cpp
+++ b/src/game/Object.cpp
@@ -1524,7 +1524,7 @@ void WorldObject::MonsterSay(int32 textId, uint32 language, uint64 TargetGuid)
MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> > say_worker(this,sWorld.getConfig(CONFIG_LISTEN_RANGE_SAY),say_do);
TypeContainerVisitor<MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> >, WorldTypeMapContainer > message(say_worker);
CellLock<GridReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, message, *GetMap());
+ cell_lock->Visit(cell_lock, message, *GetMap(), *this, sWorld.getConfig(CONFIG_LISTEN_RANGE_SAY));
}
void WorldObject::MonsterYell(int32 textId, uint32 language, uint64 TargetGuid)
@@ -1540,7 +1540,7 @@ void WorldObject::MonsterYell(int32 textId, uint32 language, uint64 TargetGuid)
MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> > say_worker(this,sWorld.getConfig(CONFIG_LISTEN_RANGE_YELL),say_do);
TypeContainerVisitor<MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> >, WorldTypeMapContainer > message(say_worker);
CellLock<GridReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, message, *GetMap());
+ cell_lock->Visit(cell_lock, message, *GetMap(), *this, sWorld.getConfig(CONFIG_LISTEN_RANGE_YELL));
}
void WorldObject::MonsterYellToZone(int32 textId, uint32 language, uint64 TargetGuid)
@@ -1569,7 +1569,7 @@ void WorldObject::MonsterTextEmote(int32 textId, uint64 TargetGuid, bool IsBossE
MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> > say_worker(this,sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE),say_do);
TypeContainerVisitor<MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> >, WorldTypeMapContainer > message(say_worker);
CellLock<GridReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, message, *GetMap());
+ cell_lock->Visit(cell_lock, message, *GetMap(), *this, sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE));
}
void WorldObject::MonsterWhisper(int32 textId, uint64 receiver, bool IsBossWhisper)
@@ -1615,8 +1615,8 @@ void Unit::BuildHeartBeatMsg(WorldPacket *data) const
void WorldObject::SendMessageToSet(WorldPacket *data, bool /*fake*/)
{
- Trinity::MessageDistDeliverer notifier(this, data, World::GetMaxVisibleDistance());
- VisitNearbyWorldObject(World::GetMaxVisibleDistance(), notifier);
+ Trinity::MessageDistDeliverer notifier(this, data, GetMap()->GetVisibilityDistance());
+ VisitNearbyWorldObject(GetMap()->GetVisibilityDistance(), notifier);
}
void WorldObject::SendMessageToSetInRange(WorldPacket *data, float dist, bool /*bToSelf*/)
@@ -2099,8 +2099,8 @@ void WorldObject::GetNearPoint(WorldObject const* searcher, float &x, float &y,
TypeContainerVisitor<MaNGOS::WorldObjectWorker<MaNGOS::NearUsedPosDo>, WorldTypeMapContainer > world_obj_worker(worker);
CellLock<GridReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, grid_obj_worker, *GetMap());
- cell_lock->Visit(cell_lock, world_obj_worker, *GetMap());
+ cell_lock->Visit(cell_lock, grid_obj_worker, *GetMap(), *this, distance2d);
+ cell_lock->Visit(cell_lock, world_obj_worker, *GetMap(), *this, distance2d);
}
// maybe can just place in primary position
@@ -2235,9 +2235,9 @@ void WorldObject::DestroyForNearbyPlayers()
return;
std::list<Unit*> targets;
- Trinity::AnyUnitInObjectRangeCheck check(this, World::GetMaxVisibleDistance());
+ Trinity::AnyUnitInObjectRangeCheck check(this, GetMap()->GetVisibilityDistance());
Trinity::UnitListSearcher<Trinity::AnyUnitInObjectRangeCheck> searcher(this, targets, check);
- VisitNearbyWorldObject(World::GetMaxVisibleDistance(), searcher);
+ VisitNearbyWorldObject(GetMap()->GetVisibilityDistance(), searcher);
for(std::list<Unit*>::const_iterator iter = targets.begin(); iter != targets.end(); ++iter)
{
Player *plr = dynamic_cast<Player*>(*iter);
diff --git a/src/game/Object.h b/src/game/Object.h
index 7e899f76d4a..9845ba10dce 100644
--- a/src/game/Object.h
+++ b/src/game/Object.h
@@ -35,8 +35,10 @@
#define CONTACT_DISTANCE 0.5f
#define INTERACTION_DISTANCE 5.0f
#define ATTACK_DISTANCE 5.0f
-#define MAX_VISIBILITY_DISTANCE (5*SIZE_OF_GRID_CELL/2.0f) // max distance for visible object show, limited by active zone for player based at cell size (active zone = 5x5 cells)
-#define DEFAULT_VISIBILITY_DISTANCE (SIZE_OF_GRID_CELL) // default visible distance
+#define MAX_VISIBILITY_DISTANCE 333.0f // max distance for visible object show, limited in 333 yards
+#define DEFAULT_VISIBILITY_DISTANCE 90.0f // default visible distance, 90 yards on continents
+#define DEFAULT_VISIBILITY_INSTANCE 120.0f // default visible distance in instances, 120 yards
+#define DEFAULT_VISIBILITY_BGARENAS 180.0f // default visible distance in BG/Arenas, 180 yards
#define DEFAULT_WORLD_OBJECT_SIZE 0.388999998569489f // player size, also currently used (correctly?) for any non Unit world objects
#define DEFAULT_COMBAT_REACH 1.5f
diff --git a/src/game/ObjectAccessor.cpp b/src/game/ObjectAccessor.cpp
index 8bc0e385f6f..7a12b4784e4 100644
--- a/src/game/ObjectAccessor.cpp
+++ b/src/game/ObjectAccessor.cpp
@@ -235,7 +235,9 @@ ObjectAccessor::_buildChangeObjectForPlayer(WorldObject *obj, UpdateDataMapType
WorldObjectChangeAccumulator notifier(*obj, update_players);
TypeContainerVisitor<WorldObjectChangeAccumulator, WorldTypeMapContainer > player_notifier(notifier);
CellLock<GridReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, player_notifier, *obj->GetMap());
+ Map& map = *obj->GetMap();
+ //we must build packets for all visible players
+ cell_lock->Visit(cell_lock, player_notifier, map, *obj, map.GetVisibilityDistance());
}
Pet*
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index 5ce152cd588..7d7f9427f9e 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -5988,8 +5988,9 @@ void Player::SendMessageToSet(WorldPacket *data, bool self)
GetSession()->SendPacket(data);
// we use World::GetMaxVisibleDistance() because i cannot see why not use a distance
- Trinity::MessageDistDeliverer notifier(this, data, World::GetMaxVisibleDistance());
- VisitNearbyWorldObject(World::GetMaxVisibleDistance(), notifier);
+ // update: replaced by GetMap()->GetVisibilityDistance()
+ Trinity::MessageDistDeliverer notifier(this, data, GetMap()->GetVisibilityDistance());
+ VisitNearbyWorldObject(GetMap()->GetVisibilityDistance(), notifier);
}
void Player::SendMessageToSetInRange(WorldPacket *data, float dist, bool self)
@@ -17776,7 +17777,7 @@ void Player::HandleStealthedUnitsDetection()
std::list<Unit*> stealthedUnits;
Trinity::AnyStealthedCheck u_check;
Trinity::UnitListSearcher<Trinity::AnyStealthedCheck > searcher(this, stealthedUnits, u_check);
- VisitNearbyObject(World::GetMaxVisibleDistance(), searcher);
+ VisitNearbyObject(GetMap()->GetVisibilityDistance(), searcher);
for (std::list<Unit*>::const_iterator i = stealthedUnits.begin(); i != stealthedUnits.end(); ++i)
{
@@ -18972,6 +18973,7 @@ bool Player::canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList, bool
//if(u->GetVisibility() == VISIBILITY_RESPAWN)
// return false;
+ Map& _map = *u->GetMap();
// Grid dead/alive checks
// non visible at grid for any stealth state
if(!u->IsVisibleInGridForPlayer(this))
@@ -18987,34 +18989,34 @@ bool Player::canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList, bool
return true;
// different visible distance checks
- if(isInFlight()) // what see player in flight
+ if(isInFlight()) // what see player in flight
{
- if (!m_seer->IsWithinDistInMap(u,World::GetMaxVisibleDistanceInFlight()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), is3dDistance))
+ if (!m_seer->IsWithinDistInMap(u, _map.GetVisibilityDistance() + (inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), is3dDistance))
return false;
}
else if(!u->isAlive()) // distance for show body
{
- if (!m_seer->IsWithinDistInMap(u,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), is3dDistance))
+ if (!m_seer->IsWithinDistInMap(u, _map.GetVisibilityDistance() + (inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), is3dDistance))
return false;
}
else if(u->GetTypeId()==TYPEID_PLAYER) // distance for show player
{
// Players far than max visible distance for player or not in our map are not visible too
- if (!at_same_transport && !m_seer->IsWithinDistInMap(u,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f), is3dDistance))
+ if (!at_same_transport && !m_seer->IsWithinDistInMap(u, _map.GetVisibilityDistance() + (inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f), is3dDistance))
return false;
}
else if(u->GetCharmerOrOwnerGUID()) // distance for show pet/charmed
{
// Pet/charmed far than max visible distance for player or not in our map are not visible too
- if (!m_seer->IsWithinDistInMap(u,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f), is3dDistance))
+ if (!m_seer->IsWithinDistInMap(u, _map.GetVisibilityDistance() + (inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f), is3dDistance))
return false;
}
else // distance for show creature
{
- // Units far than max visible distance for creature or not in our map are not visible too
+ // Units farther than max visible distance for creature or not in our map are not visible too
if (!m_seer->IsWithinDistInMap(u
, u->isActiveObject() ? (MAX_VISIBILITY_DISTANCE - (inVisibleList ? 0.0f : World::GetVisibleUnitGreyDistance()))
- : (World::GetMaxVisibleDistanceForCreature() + (inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))
+ : (_map.GetVisibilityDistance() + (inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))
, is3dDistance))
return false;
}
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index 1c0444cf782..4e9bfa9e804 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -507,12 +507,12 @@ WorldObject* Spell::FindCorpseUsing()
TypeContainerVisitor<MaNGOS::WorldObjectSearcher<T>, GridTypeMapContainer > grid_searcher(searcher);
CellLock<GridReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, grid_searcher, *m_caster->GetMap());
+ cell_lock->Visit(cell_lock, grid_searcher, *m_caster->GetMap(), *m_caster, max_range);
if (!result)
{
TypeContainerVisitor<MaNGOS::WorldObjectSearcher<T>, WorldTypeMapContainer > world_searcher(searcher);
- cell_lock->Visit(cell_lock, world_searcher, *m_caster->GetMap());
+ cell_lock->Visit(cell_lock, world_searcher, *m_caster->GetMap(), *m_caster, max_range);
}
return result;
@@ -4687,7 +4687,7 @@ SpellCastResult Spell::CheckCast(bool strict)
TypeContainerVisitor<MaNGOS::CreatureLastSearcher<MaNGOS::NearestCreatureEntryWithLiveStateInObjectRangeCheck>, GridTypeMapContainer > grid_creature_searcher(searcher);
CellLock<GridReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, grid_creature_searcher, *m_caster->GetMap());
+ cell_lock->Visit(cell_lock, grid_creature_searcher, *m_caster->GetMap(), *m_caster, range);
if(p_Creature )
{
@@ -5621,7 +5621,8 @@ SpellCastResult Spell::CheckItems()
TypeContainerVisitor<Trinity::GameObjectSearcher<Trinity::GameObjectFocusCheck>, GridTypeMapContainer > object_checker(checker);
CellLock<GridReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, object_checker, *m_caster->GetMap());
+ Map& map = *m_caster->GetMap();
+ cell_lock->Visit(cell_lock, object_checker, map, *m_caster, map.GetVisibilityDistance());
if(!ok)
return SPELL_FAILED_REQUIRES_SPELL_FOCUS;
diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
index f6871b00072..24ce2d02b78 100644
--- a/src/game/SpellAuras.cpp
+++ b/src/game/SpellAuras.cpp
@@ -3886,9 +3886,9 @@ void AuraEffect::HandleFeignDeath(bool apply, bool Real, bool /*changeAmount*/)
*/
std::list<Unit*> targets;
- Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(m_target, m_target, World::GetMaxVisibleDistance());
+ Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(m_target, m_target, m_target->GetMap()->GetVisibilityDistance());
Trinity::UnitListSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(m_target, targets, u_check);
- m_target->VisitNearbyObject(World::GetMaxVisibleDistance(), searcher);
+ m_target->VisitNearbyObject(m_target->GetMap()->GetVisibilityDistance(), searcher);
for(std::list<Unit*>::iterator iter = targets.begin(); iter != targets.end(); ++iter)
{
if(!(*iter)->hasUnitState(UNIT_STAT_CASTING))
@@ -6487,8 +6487,8 @@ void AuraEffect::PeriodicDummyTick()
CellLock<GridReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, grid_object_checker, *caster->GetMap());
- cell_lock->Visit(cell_lock, world_object_checker, *caster->GetMap());
+ cell_lock->Visit(cell_lock, grid_object_checker, *caster->GetMap(), *caster, radius);
+ cell_lock->Visit(cell_lock, world_object_checker, *caster->GetMap(), *caster, radius);
}
if(targets.empty())
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index e01744710e3..d676f8091ce 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -5763,9 +5763,9 @@ void Spell::EffectSanctuary(uint32 /*i*/)
return;
std::list<Unit*> targets;
- Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(unitTarget, unitTarget, World::GetMaxVisibleDistance());
+ Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(unitTarget, unitTarget, m_caster->GetMap()->GetVisibilityDistance());
Trinity::UnitListSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(unitTarget, targets, u_check);
- unitTarget->VisitNearbyObject(World::GetMaxVisibleDistance(), searcher);
+ unitTarget->VisitNearbyObject(m_caster->GetMap()->GetVisibilityDistance(), searcher);
for(std::list<Unit*>::iterator iter = targets.begin(); iter != targets.end(); ++iter)
{
if(!(*iter)->hasUnitState(UNIT_STAT_CASTING))
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index e0bd23b53b2..0d45ed36457 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -10770,7 +10770,7 @@ int32 Unit::ModifyPower(Powers power, int32 dVal)
bool Unit::isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList, bool is3dDistance) const
{
- if(!u)
+ if(!u || !IsInMap(u))
return false;
return u->canSeeOrDetect(this, detect, inVisibleList, is3dDistance);
diff --git a/src/game/World.cpp b/src/game/World.cpp
index dd83aaef530..0150b8fca12 100644
--- a/src/game/World.cpp
+++ b/src/game/World.cpp
@@ -75,10 +75,11 @@ volatile bool World::m_stopEvent = false;
uint8 World::m_ExitCode = SHUTDOWN_EXIT_CODE;
volatile uint32 World::m_worldLoopCounter = 0;
-float World::m_MaxVisibleDistance = DEFAULT_VISIBILITY_DISTANCE;
-float World::m_MaxVisibleDistanceForCreature = DEFAULT_VISIBILITY_DISTANCE;
-float World::m_MaxVisibleDistanceForPlayer = DEFAULT_VISIBILITY_DISTANCE;
+float World::m_MaxVisibleDistanceOnContinents = DEFAULT_VISIBILITY_DISTANCE;
+float World::m_MaxVisibleDistanceInInstances = DEFAULT_VISIBILITY_INSTANCE;
+float World::m_MaxVisibleDistanceInBGArenas = DEFAULT_VISIBILITY_BGARENAS;
float World::m_MaxVisibleDistanceForObject = DEFAULT_VISIBILITY_DISTANCE;
+
float World::m_MaxVisibleDistanceInFlight = DEFAULT_VISIBILITY_DISTANCE;
float World::m_VisibleUnitGreyDistance = 0;
float World::m_VisibleObjectGreyDistance = 0;
@@ -1065,54 +1066,62 @@ void World::LoadConfigSettings(bool reload)
m_VisibleObjectGreyDistance = MAX_VISIBILITY_DISTANCE;
}
- m_MaxVisibleDistanceForCreature = sConfig.GetFloatDefault("Visibility.Distance.Creature", DEFAULT_VISIBILITY_DISTANCE);
- if (m_MaxVisibleDistanceForCreature < 45*sWorld.getRate(RATE_CREATURE_AGGRO))
+ //visibility on continents
+ m_MaxVisibleDistanceOnContinents = sConfig.GetFloatDefault("Visibility.Distance.Continents", DEFAULT_VISIBILITY_DISTANCE);
+ if(m_MaxVisibleDistanceOnContinents < 45*sWorld.getRate(RATE_CREATURE_AGGRO))
{
- sLog.outError("Visibility.Distance.Creature can't be less max aggro radius %f",45*sWorld.getRate(RATE_CREATURE_AGGRO));
- m_MaxVisibleDistanceForCreature = 45*sWorld.getRate(RATE_CREATURE_AGGRO);
+ sLog.outError("Visibility.Distance.Continents can't be less max aggro radius %f", 45*sWorld.getRate(RATE_CREATURE_AGGRO));
+ m_MaxVisibleDistanceOnContinents = 45*sWorld.getRate(RATE_CREATURE_AGGRO);
}
- else if (m_MaxVisibleDistanceForCreature + m_VisibleUnitGreyDistance > MAX_VISIBILITY_DISTANCE)
+ else if(m_MaxVisibleDistanceOnContinents + m_VisibleUnitGreyDistance > MAX_VISIBILITY_DISTANCE)
{
- sLog.outString("Visibility. Distance .Creature can't be greater %f",MAX_VISIBILITY_DISTANCE - m_VisibleUnitGreyDistance);
- m_MaxVisibleDistanceForCreature = MAX_VISIBILITY_DISTANCE-m_VisibleUnitGreyDistance;
+ sLog.outError("Visibility.Distance.Continents can't be greater %f",MAX_VISIBILITY_DISTANCE - m_VisibleUnitGreyDistance);
+ m_MaxVisibleDistanceOnContinents = MAX_VISIBILITY_DISTANCE - m_VisibleUnitGreyDistance;
}
-
- m_MaxVisibleDistanceForPlayer = sConfig.GetFloatDefault("Visibility.Distance.Player", DEFAULT_VISIBILITY_DISTANCE);
- if (m_MaxVisibleDistanceForPlayer < 45*sWorld.getRate(RATE_CREATURE_AGGRO))
+
+ //visibility in instances
+ m_MaxVisibleDistanceInInstances = sConfig.GetFloatDefault("Visibility.Distance.Instances", DEFAULT_VISIBILITY_INSTANCE);
+ if(m_MaxVisibleDistanceInInstances < 45*sWorld.getRate(RATE_CREATURE_AGGRO))
+ {
+ sLog.outError("Visibility.Distance.Instances can't be less max aggro radius %f",45*sWorld.getRate(RATE_CREATURE_AGGRO));
+ m_MaxVisibleDistanceInInstances = 45*sWorld.getRate(RATE_CREATURE_AGGRO);
+ }
+ else if(m_MaxVisibleDistanceInInstances + m_VisibleUnitGreyDistance > MAX_VISIBILITY_DISTANCE)
{
- sLog.outError("Visibility.Distance.Player can't be less max aggro radius %f",45*sWorld.getRate(RATE_CREATURE_AGGRO));
- m_MaxVisibleDistanceForPlayer = 45*sWorld.getRate(RATE_CREATURE_AGGRO);
+ sLog.outError("Visibility.Distance.Instances can't be greater %f",MAX_VISIBILITY_DISTANCE - m_VisibleUnitGreyDistance);
+ m_MaxVisibleDistanceInInstances = MAX_VISIBILITY_DISTANCE - m_VisibleUnitGreyDistance;
}
- else if (m_MaxVisibleDistanceForPlayer + m_VisibleUnitGreyDistance > MAX_VISIBILITY_DISTANCE)
+
+ //visibility in BG/Arenas
+ m_MaxVisibleDistanceInBGArenas = sConfig.GetFloatDefault("Visibility.Distance.BGArenas", DEFAULT_VISIBILITY_BGARENAS);
+ if(m_MaxVisibleDistanceInBGArenas < 45*sWorld.getRate(RATE_CREATURE_AGGRO))
{
- sLog.outString("Visibility.Distance.Player can't be greater %f",MAX_VISIBILITY_DISTANCE - m_VisibleUnitGreyDistance);
- m_MaxVisibleDistanceForPlayer = MAX_VISIBILITY_DISTANCE - m_VisibleUnitGreyDistance;
+ sLog.outError("Visibility.Distance.BGArenas can't be less max aggro radius %f",45*sWorld.getRate(RATE_CREATURE_AGGRO));
+ m_MaxVisibleDistanceInBGArenas = 45*sWorld.getRate(RATE_CREATURE_AGGRO);
+ }
+ else if(m_MaxVisibleDistanceInBGArenas + m_VisibleUnitGreyDistance > MAX_VISIBILITY_DISTANCE)
+ {
+ sLog.outError("Visibility.Distance.BGArenas can't be greater %f",MAX_VISIBILITY_DISTANCE - m_VisibleUnitGreyDistance);
+ m_MaxVisibleDistanceInBGArenas = MAX_VISIBILITY_DISTANCE - m_VisibleUnitGreyDistance;
}
- m_MaxVisibleDistance = std::max(m_MaxVisibleDistanceForPlayer, m_MaxVisibleDistanceForCreature);
- m_MaxVisibleDistanceForObject = sConfig.GetFloatDefault("Visibility.Distance.Object", DEFAULT_VISIBILITY_DISTANCE);
- if (m_MaxVisibleDistanceForObject < INTERACTION_DISTANCE)
+ m_MaxVisibleDistanceForObject = sConfig.GetFloatDefault("Visibility.Distance.Object", DEFAULT_VISIBILITY_DISTANCE);
+ if(m_MaxVisibleDistanceForObject < INTERACTION_DISTANCE)
{
sLog.outError("Visibility.Distance.Object can't be less max aggro radius %f",float(INTERACTION_DISTANCE));
m_MaxVisibleDistanceForObject = INTERACTION_DISTANCE;
}
- else if (m_MaxVisibleDistanceForObject + m_VisibleObjectGreyDistance > MAX_VISIBILITY_DISTANCE)
+ else if(m_MaxVisibleDistanceForObject + m_VisibleObjectGreyDistance > MAX_VISIBILITY_DISTANCE)
{
- sLog.outString("Visibility.Distance.Object can't be greater %f",MAX_VISIBILITY_DISTANCE-m_VisibleObjectGreyDistance);
+ sLog.outError("Visibility.Distance.Object can't be greater %f",MAX_VISIBILITY_DISTANCE-m_VisibleObjectGreyDistance);
m_MaxVisibleDistanceForObject = MAX_VISIBILITY_DISTANCE - m_VisibleObjectGreyDistance;
}
- if (m_MaxVisibleDistance < m_MaxVisibleDistanceForObject)
- m_MaxVisibleDistance = m_MaxVisibleDistanceForObject;
-
- m_MaxVisibleDistanceInFlight = sConfig.GetFloatDefault("Visibility.Distance.InFlight", DEFAULT_VISIBILITY_DISTANCE);
- if (m_MaxVisibleDistanceInFlight + m_VisibleObjectGreyDistance > MAX_VISIBILITY_DISTANCE)
+ m_MaxVisibleDistanceInFlight = sConfig.GetFloatDefault("Visibility.Distance.InFlight", DEFAULT_VISIBILITY_DISTANCE);
+ if(m_MaxVisibleDistanceInFlight + m_VisibleObjectGreyDistance > MAX_VISIBILITY_DISTANCE)
{
- sLog.outString("Visibility.Distance.InFlight can't be greater %f",MAX_VISIBILITY_DISTANCE-m_VisibleObjectGreyDistance);
+ sLog.outError("Visibility.Distance.InFlight can't be greater %f",MAX_VISIBILITY_DISTANCE-m_VisibleObjectGreyDistance);
m_MaxVisibleDistanceInFlight = MAX_VISIBILITY_DISTANCE - m_VisibleObjectGreyDistance;
}
- if (m_MaxVisibleDistance < m_MaxVisibleDistanceInFlight)
- m_MaxVisibleDistance = m_MaxVisibleDistanceInFlight;
- m_MaxVisibleDistance += 1.0f;
///- Read the "Data" directory from the config file
std::string dataPath = sConfig.GetStringDefault("DataDir","./");
diff --git a/src/game/World.h b/src/game/World.h
index 6cd1fb6a82e..c5cf0d23366 100644
--- a/src/game/World.h
+++ b/src/game/World.h
@@ -583,13 +583,14 @@ class World
bool IsAllowedMap(uint32 mapid) { return m_forbiddenMapIds.count(mapid) == 0 ;}
// for max speed access
- static float GetMaxVisibleDistance() { return m_MaxVisibleDistance; }
- static float GetMaxVisibleDistanceForCreature() { return m_MaxVisibleDistanceForCreature; }
- static float GetMaxVisibleDistanceForPlayer() { return m_MaxVisibleDistanceForPlayer; }
- static float GetMaxVisibleDistanceForObject() { return m_MaxVisibleDistanceForObject; }
- static float GetMaxVisibleDistanceInFlight() { return m_MaxVisibleDistanceInFlight; }
- static float GetVisibleUnitGreyDistance() { return m_VisibleUnitGreyDistance; }
- static float GetVisibleObjectGreyDistance() { return m_VisibleObjectGreyDistance; }
+ static float GetMaxVisibleDistanceOnContinents() { return m_MaxVisibleDistanceOnContinents; }
+ static float GetMaxVisibleDistanceInInstances() { return m_MaxVisibleDistanceInInstances; }
+ static float GetMaxVisibleDistanceInBGArenas() { return m_MaxVisibleDistanceInBGArenas; }
+ static float GetMaxVisibleDistanceForObject() { return m_MaxVisibleDistanceForObject; }
+
+ static float GetMaxVisibleDistanceInFlight() { return m_MaxVisibleDistanceInFlight; }
+ static float GetVisibleUnitGreyDistance() { return m_VisibleUnitGreyDistance; }
+ static float GetVisibleObjectGreyDistance() { return m_VisibleObjectGreyDistance; }
void ProcessCliCommands();
void QueueCliCommand( CliCommandHolder::Print* zprintf, char const* input ) { cliCmdQueue.add(new CliCommandHolder(input, zprintf)); }
@@ -670,10 +671,11 @@ class World
std::set<uint32> m_forbiddenMapIds;
// for max speed access
- static float m_MaxVisibleDistance;
- static float m_MaxVisibleDistanceForCreature;
- static float m_MaxVisibleDistanceForPlayer;
+ static float m_MaxVisibleDistanceOnContinents;
+ static float m_MaxVisibleDistanceInInstances;
+ static float m_MaxVisibleDistanceInBGArenas;
static float m_MaxVisibleDistanceForObject;
+
static float m_MaxVisibleDistanceInFlight;
static float m_VisibleUnitGreyDistance;
static float m_VisibleObjectGreyDistance;
diff --git a/src/trinitycore/Main.cpp b/src/trinitycore/Main.cpp
index c62ada9ab6f..152f2ceb05e 100644
--- a/src/trinitycore/Main.cpp
+++ b/src/trinitycore/Main.cpp
@@ -40,7 +40,7 @@
// Format is YYYYMMDDRR where RR is the change in the conf file
// for that day.
#ifndef _TRINITY_CORE_CONFVER
-# define _TRINITY_CORE_CONFVER 2009091201
+# define _TRINITY_CORE_CONFVER 2009092701
#endif //_TRINITY_CORE_CONFVER
#ifdef WIN32
diff --git a/src/trinitycore/trinitycore.conf.dist b/src/trinitycore/trinitycore.conf.dist
index 2caeae3e33a..97d25cdd13f 100644
--- a/src/trinitycore/trinitycore.conf.dist
+++ b/src/trinitycore/trinitycore.conf.dist
@@ -1,7 +1,7 @@
##########################################
# Trinity Core worldd configuration file #
##########################################
-ConfVersion=2009091601
+ConfVersion=2009092701
###################################################################################################################
# CONNECTIONS AND DIRECTORIES
@@ -1142,12 +1142,12 @@ GM.AllowAchievementGain = 1
# 1 (raid members 100% auto detect invisible player from same raid)
# 2 (players from same team can 100% auto detect invisible player)
#
-# Visibility.Distance.Creature
-# Visibility.Distance.Player
-# Visibility distance for different in game object
-# Max limited by active player zone: ~ 166
-# Min limit dependent from objects
-# Default: 66 (cell size)
+# Visibility.Distance.Continents
+# Visibility.Distance.Instances
+# Visibility.Distance.BGArenas
+# Visibility distance for different ingame object in different maps.
+# Visibility on continents on offy ~90 yards. In BG/Arenas ~180. For instances default ~120.
+# Max limited by active player zone: ~ 333
# Min limit is max aggro radius (45) * Rate.Creature.Aggro
#
# Visibility.Distance.Object
@@ -1173,10 +1173,11 @@ GM.AllowAchievementGain = 1
###################################################################################################################
Visibility.GroupMode = 0
-Visibility.Distance.Creature = 999
-Visibility.Distance.Player = 66
-Visibility.Distance.Object = 999
-Visibility.Distance.InFlight = 66
+Visibility.Distance.Continents = 90
+Visibility.Distance.Instances = 120
+Visibility.Distance.BGArenas = 180
+Visibility.Distance.Object = 100
+Visibility.Distance.InFlight = 100
Visibility.Distance.Grey.Unit = 1
Visibility.Distance.Grey.Object = 10