mirror of
https://github.com/mangosfour/server.git
synced 2025-12-15 10:37:02 +00:00
[8524] New cell search algorithm implemented. You can now choose different visibility distances on continents, in BG/Arenas and instances.
Please, update your config files and check new options: Visibility.Distance.Continents = 90 Visibility.Distance.Instances = 120 Visibility.Distance.BGArenas = 180 Thanks everyone involved in patch tests! Signed-off-by: Ambal <pogrebniak@gala.net>
This commit is contained in:
parent
81456dc416
commit
cfea99ea62
28 changed files with 434 additions and 123 deletions
|
|
@ -41,6 +41,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];
|
||||
|
||||
|
|
@ -198,7 +199,8 @@ Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode, Map* _par
|
|||
: i_mapEntry (sMapStore.LookupEntry(id)), i_spawnMode(SpawnMode),
|
||||
i_id(id), 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)
|
||||
{
|
||||
for(unsigned int idx=0; idx < MAX_NUMBER_OF_GRIDS; ++idx)
|
||||
{
|
||||
|
|
@ -209,6 +211,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
|
||||
|
|
@ -346,8 +357,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);
|
||||
|
|
@ -491,7 +502,7 @@ void Map::MessageBroadcast(Player *player, WorldPacket *msg, bool to_self)
|
|||
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);
|
||||
cell_lock->Visit(cell_lock, message, *this, *player, GetVisibilityDistance());
|
||||
}
|
||||
|
||||
void Map::MessageBroadcast(WorldObject *obj, WorldPacket *msg)
|
||||
|
|
@ -511,10 +522,12 @@ void Map::MessageBroadcast(WorldObject *obj, WorldPacket *msg)
|
|||
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);
|
||||
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)
|
||||
|
|
@ -537,7 +550,7 @@ void Map::MessageDistBroadcast(Player *player, WorldPacket *msg, float dist, boo
|
|||
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);
|
||||
cell_lock->Visit(cell_lock, message, *this, *player, dist);
|
||||
}
|
||||
|
||||
void Map::MessageDistBroadcast(WorldObject *obj, WorldPacket *msg, float dist)
|
||||
|
|
@ -557,10 +570,10 @@ void Map::MessageDistBroadcast(WorldObject *obj, WorldPacket *msg, float dist)
|
|||
if( !loaded(GridPair(cell.data.Part.grid_x, cell.data.Part.grid_y)) )
|
||||
return;
|
||||
|
||||
MaNGOS::ObjectMessageDistDeliverer post_man(*obj, msg,dist);
|
||||
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);
|
||||
cell_lock->Visit(cell_lock, message, *this, *obj, dist);
|
||||
}
|
||||
|
||||
bool Map::loaded(const GridPair &p) const
|
||||
|
|
@ -605,8 +618,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)
|
||||
{
|
||||
|
|
@ -1044,8 +1058,9 @@ bool Map::UnloadGrid(const uint32 &x, const uint32 &y, bool pForce)
|
|||
delete getNGrid(x, y);
|
||||
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
|
||||
|
|
@ -1921,7 +1936,7 @@ void Map::UpdateObjectVisibility( WorldObject* obj, Cell cell, CellPair cellpair
|
|||
MaNGOS::VisibleChangesNotifier notifier(*obj);
|
||||
TypeContainerVisitor<MaNGOS::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 )
|
||||
|
|
@ -1932,7 +1947,7 @@ void Map::UpdatePlayerVisibility( Player* player, Cell cell, CellPair cellpair )
|
|||
TypeContainerVisitor<MaNGOS::PlayerNotifier, WorldTypeMapContainer > player_notifier(pl_notifier);
|
||||
|
||||
CellLock<ReadGuard> cell_lock(cell, cellpair);
|
||||
cell_lock->Visit(cell_lock, player_notifier, *this);
|
||||
cell_lock->Visit(cell_lock, player_notifier, *this, *player, GetVisibilityDistance());
|
||||
}
|
||||
|
||||
void Map::UpdateObjectsVisibilityFor( Player* player, Cell cell, CellPair cellpair )
|
||||
|
|
@ -1944,8 +1959,8 @@ void Map::UpdateObjectsVisibilityFor( Player* player, Cell cell, CellPair cellpa
|
|||
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);
|
||||
cell_lock->Visit(cell_lock, grid_notifier, *this);
|
||||
cell_lock->Visit(cell_lock, world_notifier, *this, *player, GetVisibilityDistance());
|
||||
cell_lock->Visit(cell_lock, grid_notifier, *this, *player, GetVisibilityDistance());
|
||||
|
||||
// send data
|
||||
notifier.Notify();
|
||||
|
|
@ -1960,8 +1975,8 @@ void Map::PlayerRelocationNotify( Player* player, Cell cell, CellPair cellpair )
|
|||
TypeContainerVisitor<MaNGOS::PlayerRelocationNotifier, GridTypeMapContainer > p2grid_relocation(relocationNotifier);
|
||||
TypeContainerVisitor<MaNGOS::PlayerRelocationNotifier, WorldTypeMapContainer > p2world_relocation(relocationNotifier);
|
||||
|
||||
cell_lock->Visit(cell_lock, p2grid_relocation, *this);
|
||||
cell_lock->Visit(cell_lock, p2world_relocation, *this);
|
||||
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)
|
||||
|
|
@ -1974,8 +1989,8 @@ void Map::CreatureRelocationNotify(Creature *creature, Cell cell, CellPair cellp
|
|||
TypeContainerVisitor<MaNGOS::CreatureRelocationNotifier, WorldTypeMapContainer > c2world_relocation(relocationNotifier);
|
||||
TypeContainerVisitor<MaNGOS::CreatureRelocationNotifier, GridTypeMapContainer > c2grid_relocation(relocationNotifier);
|
||||
|
||||
cell_lock->Visit(cell_lock, c2world_relocation, *this);
|
||||
cell_lock->Visit(cell_lock, c2grid_relocation, *this);
|
||||
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 )
|
||||
|
|
@ -2145,12 +2160,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)
|
||||
{
|
||||
|
|
@ -2234,6 +2257,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);
|
||||
|
|
@ -2248,6 +2274,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
|
||||
*/
|
||||
|
|
@ -2570,12 +2602,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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue