diff options
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 |