aboutsummaryrefslogtreecommitdiff
path: root/src/game/Map.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/Map.cpp')
-rw-r--r--src/game/Map.cpp257
1 files changed, 221 insertions, 36 deletions
diff --git a/src/game/Map.cpp b/src/game/Map.cpp
index 5a72c6ed8f0..0ddbf359f40 100644
--- a/src/game/Map.cpp
+++ b/src/game/Map.cpp
@@ -214,7 +214,10 @@ Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode, Map* _par
m_activeNonPlayersIter(m_activeNonPlayers.end()),
i_gridExpiry(expiry), m_parentMap(_parent ? _parent : this),
m_VisibleDistance(DEFAULT_VISIBILITY_DISTANCE)
- , i_notifyLock(false), i_scriptLock(false)
+ , i_notifyLock(false), i_scriptLock(false),
+ m_PlayerVisibilityNotifyTimer(0.75*DEFAULT_VISIBILITY_NOTIFY_PERIOD, 0.25*DEFAULT_VISIBILITY_NOTIFY_PERIOD),
+ m_ObjectVisibilityNotifyTimer(DEFAULT_VISIBILITY_NOTIFY_PERIOD, 0 * DEFAULT_VISIBILITY_NOTIFY_PERIOD),
+ m_RelocationNotifyTimer(DEFAULT_VISIBILITY_NOTIFY_PERIOD,0.5*DEFAULT_VISIBILITY_NOTIFY_PERIOD)
{
m_notifyTimer.SetInterval(IN_MILISECONDS/2);
@@ -236,6 +239,10 @@ void Map::InitVisibilityDistance()
{
//init visibility for continents
m_VisibleDistance = World::GetMaxVisibleDistanceOnContinents();
+
+ m_PlayerVisibilityNotifyTimer.SetPeriodic(0.75*sWorld.GetVisibilityNotifyPeriodOnContinents(), 0.25*sWorld.GetVisibilityNotifyPeriodOnContinents());
+ m_ObjectVisibilityNotifyTimer.SetPeriodic(sWorld.GetVisibilityNotifyPeriodOnContinents(), 0 * sWorld.GetVisibilityNotifyPeriodOnContinents());
+ m_RelocationNotifyTimer.SetPeriodic(sWorld.GetVisibilityNotifyPeriodOnContinents(),0.5*sWorld.GetVisibilityNotifyPeriodOnContinents());
}
// Template specialization of utility methods
@@ -336,17 +343,13 @@ void Map::AddNotifier(T*)
template<>
void Map::AddNotifier(Player* obj)
{
- //obj->m_Notified = false;
- //obj->m_IsInNotifyList = false;
- AddUnitToNotify(obj);
+ obj->AddToNotify(NOTIFY_VISIBILITY_CHANGED | NOTIFY_AI_RELOCATION | NOTIFY_PLAYER_VISIBILITY);
}
template<>
void Map::AddNotifier(Creature* obj)
{
- //obj->m_Notified = false;
- //obj->m_IsInNotifyList = false;
- AddUnitToNotify(obj);
+ obj->AddToNotify(NOTIFY_VISIBILITY_CHANGED | NOTIFY_AI_RELOCATION);
}
void
@@ -444,13 +447,14 @@ bool Map::Add(Player *player)
CellPair p = Trinity::ComputeCellPair(player->GetPositionX(), player->GetPositionY());
Cell cell(p);
EnsureGridLoadedAtEnter(cell, player);
+ player->ResetAllNotifies();
player->AddToWorld();
SendInitSelf(player);
SendInitTransports(player);
player->m_clientGUIDs.clear();
- //AddNotifier(player);
+ AddNotifier<Player>(player);
return true;
}
@@ -494,8 +498,8 @@ Map::Add(T *obj)
//something, such as vehicle, needs to be update immediately
//also, trigger needs to cast spell, if not update, cannot see visual
//if(obj->GetTypeId() != TYPEID_UNIT)
- UpdateObjectVisibility(obj,cell,p);
- AddNotifier(obj);
+ UpdateObjectVisibility(obj,cell,p);
+ AddNotifier<T>(obj);
}
/*
@@ -601,7 +605,7 @@ bool Map::loaded(const GridPair &p) const
void Map::RelocationNotify()
{
- i_notifyLock = true;
+/* i_notifyLock = true;
//Notify
for (std::vector<Unit*>::iterator iter = i_unitsToNotify.begin(); iter != i_unitsToNotify.end(); ++iter)
@@ -651,12 +655,12 @@ void Map::RelocationNotify()
{
i_unitsToNotify.insert(i_unitsToNotify.end(), i_unitsToNotifyBacklog.begin(), i_unitsToNotifyBacklog.end());
i_unitsToNotifyBacklog.clear();
- }
+ }*/
}
void Map::AddUnitToNotify(Unit* u)
{
- if(u->m_NotifyListPos < 0 && u->IsInWorld())
+/* if(u->m_NotifyListPos < 0 && u->IsInWorld())
{
u->oldX = u->GetPositionX();
u->oldY = u->GetPositionY();
@@ -671,7 +675,7 @@ void Map::AddUnitToNotify(Unit* u)
u->m_NotifyListPos = i_unitsToNotify.size();
i_unitsToNotify.push_back(u);
}
- }
+ }*/
}
void Map::RemoveUnitFromNotify(Unit *unit)
@@ -714,13 +718,6 @@ void Map::Update(const uint32 &t_diff)
plr->Update(t_diff);
}
- m_notifyTimer.Update(t_diff);
- if (m_notifyTimer.Passed())
- {
- m_notifyTimer.Reset();
- RelocationNotify();
- }
-
/// update active cells around players and active objects
resetMarkedCells();
@@ -772,9 +769,6 @@ void Map::Update(const uint32 &t_diff)
}
}
}
-
- if (plr->m_seer != plr && !plr->GetVehicle())
- AddUnitToNotify(plr);
}
// non-player active objects
@@ -836,10 +830,191 @@ void Map::Update(const uint32 &t_diff)
}
MoveAllCreaturesInMoveList();
+
+ {
+ bool hasPlayers = !m_mapRefManager.isEmpty();
+ bool hasActiveObjects = !m_activeNonPlayers.empty();
+
+ if(hasPlayers)
+ {
+ if(m_PlayerVisibilityNotifyTimer.Update(t_diff))
+ { // process player-player visibility
+ ProcesssPlayersVisibility();
+ ResetNotifies(NOTIFY_PLAYER_VISIBILITY);
+ }
+
+ if(m_ObjectVisibilityNotifyTimer.Update(t_diff))
+ {
+ ProcessObjectsVisibility();
+ ResetNotifies(NOTIFY_VISIBILITY_CHANGED);
+ }
+ }
+
+ if(hasActiveObjects || hasPlayers)
+ if(m_RelocationNotifyTimer.Update(t_diff))
+ {
+ ProcessRelocationNotifies();
+ ResetNotifies(NOTIFY_AI_RELOCATION);
+ }
+ }
+}
+
+void Map::ProcesssPlayersVisibility()
+{
+ for(m_mapRefIter = m_mapRefManager.begin(); m_mapRefIter != m_mapRefManager.end(); ++m_mapRefIter)
+ {
+ Player* player = m_mapRefIter->getSource();
+
+ if (player->m_seer != player && !player->GetVehicle())
+ AddNotifier<Player>(player);
+
+ if(!player->IsInWorld() || !player->isNeedNotify(NOTIFY_PLAYER_VISIBILITY))
+ continue;
+
+ WorldObject const *viewPoint = player->m_seer;
+ CellPair cellpair(Trinity::ComputeCellPair(viewPoint->GetPositionX(), viewPoint->GetPositionY()));
+
+ if (cellpair.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || cellpair.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP)
+ continue;
+
+ Trinity::Player2PlayerNotifier notifier(*player);
+
+ Cell cell(cellpair);
+ cell.data.Part.reserved = ALL_DISTRICT;
+ //cell.SetNoCreate();
+ TypeContainerVisitor<Trinity::Player2PlayerNotifier, WorldTypeMapContainer > world_notifier(notifier);
+ CellLock<ReadGuard> cell_lock(cell, cellpair);
+ cell_lock->Visit(cell_lock, world_notifier, *this, *viewPoint, GetVisibilityDistance());
+
+ // send data
+ notifier.SendToSelf();
+ player->RemoveFromNotify(NOTIFY_PLAYER_VISIBILITY);
+ player->SetNotified(NOTIFY_PLAYER_VISIBILITY);
+ }
+}
+
+void Map::ProcessObjectsVisibility()
+{
+ for(m_mapRefIter = m_mapRefManager.begin(); m_mapRefIter != m_mapRefManager.end(); ++m_mapRefIter)
+ {
+ Player* player = m_mapRefIter->getSource();
+
+ if (player->m_seer != player && !player->GetVehicle())
+ AddNotifier<Player>(player);
+
+ if(!player->IsInWorld())
+ continue;
+
+ WorldObject const *viewPoint = player->m_seer;
+ CellPair cellpair(Trinity::ComputeCellPair(viewPoint->GetPositionX(), viewPoint->GetPositionY()));
+
+ if (cellpair.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || cellpair.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP)
+ continue;
+
+ Cell cell(cellpair);
+ cell.data.Part.reserved = ALL_DISTRICT;
+ cell.SetNoCreate();
+
+ Trinity::VisibleNotifier notifier(*player);
+
+ TypeContainerVisitor<Trinity::VisibleNotifier, WorldTypeMapContainer > world_notifier(notifier);
+ TypeContainerVisitor<Trinity::VisibleNotifier, GridTypeMapContainer > grid_notifier(notifier);
+ CellLock<ReadGuard> cell_lock(cell, cellpair);
+ cell_lock->Visit(cell_lock, world_notifier, *this, *viewPoint, GetVisibilityDistance());
+ cell_lock->Visit(cell_lock, grid_notifier, *this, *viewPoint, GetVisibilityDistance());
+
+ // send data
+ notifier.SendToSelf();
+ player->SetNotified(NOTIFY_VISIBILITY_CHANGED);
+ }
+}
+
+void Map::ProcessRelocationNotifies()
+{
+ for(GridRefManager<NGridType>::iterator i = GridRefManager<NGridType>::begin(); i != GridRefManager<NGridType>::end(); ++i)
+ {
+ NGridType *grid = i->getSource();
+
+ if(!grid || grid->GetGridState() != GRID_STATE_ACTIVE)
+ continue;
+
+ uint32 gx = grid->getX(), gy = grid->getY();
+
+ CellPair cell_min(gx*MAX_NUMBER_OF_CELLS, gy*MAX_NUMBER_OF_CELLS);
+ CellPair cell_max(cell_min.x_coord + MAX_NUMBER_OF_CELLS, cell_min.y_coord+MAX_NUMBER_OF_CELLS);
+
+ for(uint32 x = cell_min.x_coord; x <= cell_max.x_coord; ++x)
+ {
+ for(uint32 y = cell_min.y_coord; y <= cell_max.y_coord; ++y)
+ {
+ uint32 cell_id = (y * TOTAL_NUMBER_OF_CELLS_PER_MAP) + x;
+ if(!isCellMarked(cell_id))
+ continue;
+
+ CellPair pair(x,y);
+ Cell cell(pair);
+ cell.data.Part.reserved = CENTER_DISTRICT;
+ cell.SetNoCreate();
+
+ CellLock<ReadGuard> cell_lock(cell, pair);
+ Trinity::DelayedUnitRelocation cell_relocation(cell_lock, *this, GetVisibilityDistance());
+ TypeContainerVisitor<Trinity::DelayedUnitRelocation, GridTypeMapContainer > grid_object_relocation(cell_relocation);
+ TypeContainerVisitor<Trinity::DelayedUnitRelocation, WorldTypeMapContainer > world_object_relocation(cell_relocation);
+ cell_lock->Visit(cell_lock, grid_object_relocation, *this);
+ cell_lock->Visit(cell_lock, world_object_relocation, *this);
+ }
+ }
+ }
+}
+
+void Map::ResetNotifies(uint16 notify_mask)
+{
+ if(notify_mask == NOTIFY_PLAYER_VISIBILITY)
+ {
+ for(m_mapRefIter = m_mapRefManager.begin(); m_mapRefIter != m_mapRefManager.end(); ++m_mapRefIter)
+ m_mapRefIter->getSource()->ResetAllNotifiesbyMask(notify_mask);
+ return;
+ }
+
+ Trinity::ResetNotifier reset(notify_mask);
+ TypeContainerVisitor<Trinity::ResetNotifier, GridTypeMapContainer > grid_notifier(reset);
+ TypeContainerVisitor<Trinity::ResetNotifier, WorldTypeMapContainer > world_notifier(reset);
+
+ for(GridRefManager<NGridType>::iterator i = GridRefManager<NGridType>::begin(); i != GridRefManager<NGridType>::end(); ++i)
+ {
+ NGridType *grid = i->getSource();
+
+ if(!grid || grid->GetGridState() != GRID_STATE_ACTIVE)
+ continue;
+
+ uint32 gx = grid->getX(), gy = grid->getY();
+
+ CellPair cell_min(gx*MAX_NUMBER_OF_CELLS, gy*MAX_NUMBER_OF_CELLS);
+ CellPair cell_max(cell_min.x_coord + MAX_NUMBER_OF_CELLS, cell_min.y_coord+MAX_NUMBER_OF_CELLS);
+
+ for(uint32 x = cell_min.x_coord; x <= cell_max.x_coord; ++x)
+ {
+ for(uint32 y = cell_min.y_coord; y <= cell_max.y_coord; ++y)
+ {
+ uint32 cell_id = (y * TOTAL_NUMBER_OF_CELLS_PER_MAP) + x;
+ if(!isCellMarked(cell_id))
+ continue;
+
+ CellPair pair(x,y);
+ Cell cell(pair);
+ cell.data.Part.reserved = CENTER_DISTRICT;
+ cell.SetNoCreate();
+ CellLock<NullGuard> cell_lock(cell, pair);
+ cell_lock->Visit(cell_lock, grid_notifier, *this);
+ cell_lock->Visit(cell_lock, world_notifier, *this);
+ }
+ }
+ }
}
void Map::Remove(Player *player, bool remove)
{
+ player->ResetAllNotifies();
player->RemoveFromWorld();
SendRemoveTransports(player);
@@ -883,6 +1058,7 @@ template<class T>
void
Map::Remove(T *obj, bool remove)
{
+ obj->ResetAllNotifies();
obj->RemoveFromWorld();
if (obj->isActiveObject())
RemoveFromActive(obj);
@@ -946,7 +1122,7 @@ Map::PlayerRelocation(Player *player, float x, float y, float z, float orientati
EnsureGridLoadedAtEnter(new_cell, player);
}
- AddUnitToNotify(player);
+ AddNotifier<Player>(player);
NGridType* newGrid = getNGrid(new_cell.GridX(), new_cell.GridY());
if (!same_cell && newGrid->GetGridState()!= GRID_STATE_ACTIVE)
@@ -979,7 +1155,7 @@ Map::CreatureRelocation(Creature *creature, float x, float y, float z, float ang
else
{
creature->Relocate(x, y, z, ang);
- AddUnitToNotify(creature);
+ AddNotifier<Creature>(creature);
}
if (creature->IsVehicle())
@@ -1033,7 +1209,7 @@ void Map::MoveAllCreaturesInMoveList()
// update pos
c->Relocate(cm.x, cm.y, cm.z, cm.ang);
//CreatureRelocationNotify(c,new_cell,new_cell.cellPair());
- AddUnitToNotify(c);
+ AddNotifier<Creature>(c);
}
else
{
@@ -1140,7 +1316,7 @@ bool Map::CreatureRespawnRelocation(Creature *c)
c->Relocate(resp_x, resp_y, resp_z, resp_o);
c->GetMotionMaster()->Initialize(); // prevent possible problems with default move generators
//CreatureRelocationNotify(c,resp_cell,resp_cell.cellPair());
- AddUnitToNotify(c);
+ AddNotifier<Creature>(c);
return true;
}
else
@@ -2141,34 +2317,35 @@ void Map::UpdateObjectVisibility( WorldObject* obj, Cell cell, CellPair cellpair
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);
+ Trinity::Player2PlayerNotifier pl_notifier(*player);
+ TypeContainerVisitor<Trinity::Player2PlayerNotifier, WorldTypeMapContainer > player_notifier(pl_notifier);
CellLock<ReadGuard> cell_lock(cell, cellpair);
cell_lock->Visit(cell_lock, player_notifier, *this, *player, GetVisibilityDistance());
+ pl_notifier.SendToSelf();
}
void Map::UpdateObjectsVisibilityFor( Player* player, Cell cell, CellPair cellpair )
{
- MaNGOS::VisibleNotifier notifier(*player);
+ Trinity::VisibleNotifier notifier(*player, true);
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
- TypeContainerVisitor<MaNGOS::VisibleNotifier, WorldTypeMapContainer > world_notifier(notifier);
- TypeContainerVisitor<MaNGOS::VisibleNotifier, GridTypeMapContainer > grid_notifier(notifier);
+ TypeContainerVisitor<Trinity::VisibleNotifier, WorldTypeMapContainer > world_notifier(notifier);
+ TypeContainerVisitor<Trinity::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();
+ notifier.SendToSelf();
}
-
+/*
void Map::PlayerRelocationNotify( Player* player, Cell cell, CellPair cellpair )
{
CellLock<ReadGuard> cell_lock(cell, cellpair);
@@ -2524,6 +2701,10 @@ void InstanceMap::InitVisibilityDistance()
{
//init visibility distance for instances
m_VisibleDistance = World::GetMaxVisibleDistanceInInstances();
+
+ m_PlayerVisibilityNotifyTimer.SetPeriodic(0.75*sWorld.GetVisibilityNotifyPeriodInInstances(), 0.25*sWorld.GetVisibilityNotifyPeriodInInstances());
+ m_ObjectVisibilityNotifyTimer.SetPeriodic(sWorld.GetVisibilityNotifyPeriodInInstances(), 0 * sWorld.GetVisibilityNotifyPeriodInInstances());
+ m_RelocationNotifyTimer.SetPeriodic(sWorld.GetVisibilityNotifyPeriodInInstances(),0.5*sWorld.GetVisibilityNotifyPeriodInInstances());
}
/*
@@ -2873,6 +3054,10 @@ void BattleGroundMap::InitVisibilityDistance()
{
//init visibility distance for BG/Arenas
m_VisibleDistance = World::GetMaxVisibleDistanceInBGArenas();
+
+ m_PlayerVisibilityNotifyTimer.SetPeriodic(0.75*sWorld.GetVisibilityNotifyPeriodInBGArenas(), 0.25*sWorld.GetVisibilityNotifyPeriodInBGArenas());
+ m_ObjectVisibilityNotifyTimer.SetPeriodic(sWorld.GetVisibilityNotifyPeriodInBGArenas(), 0 * sWorld.GetVisibilityNotifyPeriodInBGArenas());
+ m_RelocationNotifyTimer.SetPeriodic(sWorld.GetVisibilityNotifyPeriodInBGArenas(),0.5*sWorld.GetVisibilityNotifyPeriodInBGArenas());
}
bool BattleGroundMap::CanEnter(Player * player)