mirror of
https://github.com/mangosfour/server.git
synced 2025-12-14 16:37:01 +00:00
Merge branch 'master' into 303
This commit is contained in:
commit
52b0ab1f89
20 changed files with 294 additions and 128 deletions
|
|
@ -31,7 +31,9 @@ template <class TO, class FROM> class RefManager : public LinkedListHead
|
||||||
virtual ~RefManager() { clearReferences(); }
|
virtual ~RefManager() { clearReferences(); }
|
||||||
|
|
||||||
Reference<TO, FROM>* getFirst() { return ((Reference<TO, FROM>*) LinkedListHead::getFirst()); }
|
Reference<TO, FROM>* getFirst() { return ((Reference<TO, FROM>*) LinkedListHead::getFirst()); }
|
||||||
|
Reference<TO, FROM> const* getFirst() const { return ((Reference<TO, FROM> const*) LinkedListHead::getFirst()); }
|
||||||
Reference<TO, FROM>* getLast() { return ((Reference<TO, FROM>*) LinkedListHead::getLast()); }
|
Reference<TO, FROM>* getLast() { return ((Reference<TO, FROM>*) LinkedListHead::getLast()); }
|
||||||
|
Reference<TO, FROM> const* getLast() const { return ((Reference<TO, FROM> const*) LinkedListHead::getLast()); }
|
||||||
|
|
||||||
iterator begin() { return iterator(getFirst()); }
|
iterator begin() { return iterator(getFirst()); }
|
||||||
iterator end() { return iterator(NULL); }
|
iterator end() { return iterator(NULL); }
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,7 @@ template <class TO, class FROM> class Reference : public LinkedListElement
|
||||||
}
|
}
|
||||||
|
|
||||||
Reference<TO,FROM>* next() { return((Reference<TO,FROM>*)LinkedListElement::next()); }
|
Reference<TO,FROM>* next() { return((Reference<TO,FROM>*)LinkedListElement::next()); }
|
||||||
|
Reference<TO,FROM>const* next() const { return((Reference<TO,FROM> const*)LinkedListElement::next()); }
|
||||||
Reference<TO,FROM>* prev() { return((Reference<TO,FROM>*)LinkedListElement::prev()); }
|
Reference<TO,FROM>* prev() { return((Reference<TO,FROM>*)LinkedListElement::prev()); }
|
||||||
|
|
||||||
inline TO* operator ->() const { return iRefTo; }
|
inline TO* operator ->() const { return iRefTo; }
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ ActiveState::Update(Map &m, NGridType &grid, GridInfo & info, const uint32 &x, c
|
||||||
info.UpdateTimeTracker(t_diff);
|
info.UpdateTimeTracker(t_diff);
|
||||||
if( info.getTimeTracker().Passed() )
|
if( info.getTimeTracker().Passed() )
|
||||||
{
|
{
|
||||||
if( grid.ActiveObjectsInGrid() == 0 && !ObjectAccessor::Instance().PlayersNearGrid(x, y, m.GetId(), m.GetInstanceId()) )
|
if( grid.ActiveObjectsInGrid() == 0 && !m.PlayersNearGrid(x, y) )
|
||||||
{
|
{
|
||||||
ObjectGridStoper stoper(grid);
|
ObjectGridStoper stoper(grid);
|
||||||
stoper.StopN();
|
stoper.StopN();
|
||||||
|
|
|
||||||
|
|
@ -160,6 +160,8 @@ libmangosgame_a_SOURCES = \
|
||||||
MapInstanced.h \
|
MapInstanced.h \
|
||||||
MapManager.cpp \
|
MapManager.cpp \
|
||||||
MapManager.h \
|
MapManager.h \
|
||||||
|
MapReference.h \
|
||||||
|
MapRefManager.h \
|
||||||
MiscHandler.cpp \
|
MiscHandler.cpp \
|
||||||
MotionMaster.cpp \
|
MotionMaster.cpp \
|
||||||
MotionMaster.h \
|
MotionMaster.h \
|
||||||
|
|
|
||||||
152
src/game/Map.cpp
152
src/game/Map.cpp
|
|
@ -33,6 +33,7 @@
|
||||||
#include "World.h"
|
#include "World.h"
|
||||||
#include "ScriptCalls.h"
|
#include "ScriptCalls.h"
|
||||||
#include "Group.h"
|
#include "Group.h"
|
||||||
|
#include "MapRefManager.h"
|
||||||
|
|
||||||
#include "MapInstanced.h"
|
#include "MapInstanced.h"
|
||||||
#include "InstanceSaveMgr.h"
|
#include "InstanceSaveMgr.h"
|
||||||
|
|
@ -418,6 +419,8 @@ Map::LoadGrid(const Cell& cell, bool no_unload)
|
||||||
|
|
||||||
bool Map::Add(Player *player)
|
bool Map::Add(Player *player)
|
||||||
{
|
{
|
||||||
|
player->GetMapRef().link(this, player);
|
||||||
|
|
||||||
player->SetInstanceId(GetInstanceId());
|
player->SetInstanceId(GetInstanceId());
|
||||||
|
|
||||||
// update player state for other player and visa-versa
|
// update player state for other player and visa-versa
|
||||||
|
|
@ -570,22 +573,13 @@ void Map::Update(const uint32 &t_diff)
|
||||||
// for pets
|
// for pets
|
||||||
TypeContainerVisitor<MaNGOS::ObjectUpdater, WorldTypeMapContainer > world_object_update(updater);
|
TypeContainerVisitor<MaNGOS::ObjectUpdater, WorldTypeMapContainer > world_object_update(updater);
|
||||||
|
|
||||||
//TODO: Player guard
|
for(MapRefManager::iterator iter = m_mapRefManager.begin(); iter != m_mapRefManager.end(); ++iter)
|
||||||
HashMapHolder<Player>::MapType& playerMap = HashMapHolder<Player>::GetContainer();
|
|
||||||
for(HashMapHolder<Player>::MapType::iterator iter = playerMap.begin(); iter != playerMap.end(); ++iter)
|
|
||||||
{
|
{
|
||||||
WorldObject* obj = iter->second;
|
Player* plr = iter->getSource();
|
||||||
|
if(!plr->IsInWorld())
|
||||||
if(!obj->IsInWorld())
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(obj->GetMapId() != GetId())
|
CellPair standing_cell(MaNGOS::ComputeCellPair(plr->GetPositionX(), plr->GetPositionY()));
|
||||||
continue;
|
|
||||||
|
|
||||||
if(obj->GetInstanceId() != GetInstanceId())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
CellPair standing_cell(MaNGOS::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY()));
|
|
||||||
|
|
||||||
// Check for correctness of standing_cell, it also avoids problems with update_cell
|
// Check for correctness of standing_cell, it also avoids problems with update_cell
|
||||||
if (standing_cell.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || standing_cell.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP)
|
if (standing_cell.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || standing_cell.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP)
|
||||||
|
|
@ -637,6 +631,7 @@ void Map::Update(const uint32 &t_diff)
|
||||||
|
|
||||||
void Map::Remove(Player *player, bool remove)
|
void Map::Remove(Player *player, bool remove)
|
||||||
{
|
{
|
||||||
|
player->GetMapRef().unlink();
|
||||||
CellPair p = MaNGOS::ComputeCellPair(player->GetPositionX(), player->GetPositionY());
|
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)
|
if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP)
|
||||||
{
|
{
|
||||||
|
|
@ -925,7 +920,7 @@ bool Map::UnloadGrid(const uint32 &x, const uint32 &y, bool pForce)
|
||||||
assert( grid != NULL);
|
assert( grid != NULL);
|
||||||
|
|
||||||
{
|
{
|
||||||
if(!pForce && ObjectAccessor::Instance().PlayersNearGrid(x, y, i_id, i_InstanceId) )
|
if(!pForce && PlayersNearGrid(x, y) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
DEBUG_LOG("Unloading grid[%u,%u] for map %u", x,y, i_id);
|
DEBUG_LOG("Unloading grid[%u,%u] for map %u", x,y, i_id);
|
||||||
|
|
@ -1434,6 +1429,43 @@ bool Map::CanUnload(const uint32 &diff)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32 Map::GetPlayersCountExceptGMs() const
|
||||||
|
{
|
||||||
|
uint32 count = 0;
|
||||||
|
for(MapRefManager::const_iterator itr = m_mapRefManager.begin(); itr != m_mapRefManager.end(); ++itr)
|
||||||
|
if(!itr->getSource()->isGameMaster())
|
||||||
|
++count;
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Map::SendToPlayers(WorldPacket const* data) const
|
||||||
|
{
|
||||||
|
for(MapRefManager::const_iterator itr = m_mapRefManager.begin(); itr != m_mapRefManager.end(); ++itr)
|
||||||
|
itr->getSource()->GetSession()->SendPacket(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Map::PlayersNearGrid(uint32 x, uint32 y) const
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
for(MapRefManager::const_iterator iter = m_mapRefManager.begin(); iter != m_mapRefManager.end(); ++iter)
|
||||||
|
{
|
||||||
|
Player* plr = iter->getSource();
|
||||||
|
|
||||||
|
CellPair p = MaNGOS::ComputeCellPair(plr->GetPositionX(), plr->GetPositionY());
|
||||||
|
if( (cell_min.x_coord <= p.x_coord && p.x_coord <= cell_max.x_coord) &&
|
||||||
|
(cell_min.y_coord <= p.y_coord && p.y_coord <= cell_max.y_coord) )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
template void Map::Add(Corpse *);
|
template void Map::Add(Corpse *);
|
||||||
template void Map::Add(Creature *);
|
template void Map::Add(Creature *);
|
||||||
template void Map::Add(GameObject *);
|
template void Map::Add(GameObject *);
|
||||||
|
|
@ -1469,7 +1501,7 @@ InstanceMap::~InstanceMap()
|
||||||
*/
|
*/
|
||||||
bool InstanceMap::CanEnter(Player *player)
|
bool InstanceMap::CanEnter(Player *player)
|
||||||
{
|
{
|
||||||
if(std::find(i_Players.begin(),i_Players.end(),player)!=i_Players.end())
|
if(player->GetMapRef().getTarget() == this)
|
||||||
{
|
{
|
||||||
sLog.outError("InstanceMap::CanEnter - player %s(%u) already in map %d,%d,%d!", player->GetName(), player->GetGUIDLow(), GetId(), GetInstanceId(), GetSpawnMode());
|
sLog.outError("InstanceMap::CanEnter - player %s(%u) already in map %d,%d,%d!", player->GetName(), player->GetGUIDLow(), GetId(), GetInstanceId(), GetSpawnMode());
|
||||||
assert(false);
|
assert(false);
|
||||||
|
|
@ -1586,7 +1618,6 @@ bool InstanceMap::Add(Player *player)
|
||||||
if(i_data) i_data->OnPlayerEnter(player);
|
if(i_data) i_data->OnPlayerEnter(player);
|
||||||
SetResetSchedule(false);
|
SetResetSchedule(false);
|
||||||
|
|
||||||
i_Players.push_back(player);
|
|
||||||
player->SendInitWorldStates();
|
player->SendInitWorldStates();
|
||||||
sLog.outDetail("MAP: Player '%s' entered the instance '%u' of map '%s'", player->GetName(), GetInstanceId(), GetMapName());
|
sLog.outDetail("MAP: Player '%s' entered the instance '%u' of map '%s'", player->GetName(), GetInstanceId(), GetMapName());
|
||||||
// initialize unload state
|
// initialize unload state
|
||||||
|
|
@ -1611,9 +1642,9 @@ void InstanceMap::Update(const uint32& t_diff)
|
||||||
void InstanceMap::Remove(Player *player, bool remove)
|
void InstanceMap::Remove(Player *player, bool remove)
|
||||||
{
|
{
|
||||||
sLog.outDetail("MAP: Removing player '%s' from instance '%u' of map '%s' before relocating to other map", player->GetName(), GetInstanceId(), GetMapName());
|
sLog.outDetail("MAP: Removing player '%s' from instance '%u' of map '%s' before relocating to other map", player->GetName(), GetInstanceId(), GetMapName());
|
||||||
i_Players.remove(player);
|
|
||||||
SetResetSchedule(true);
|
SetResetSchedule(true);
|
||||||
if(!m_unloadTimer && i_Players.empty())
|
//if last player set unload timer
|
||||||
|
if(!m_unloadTimer && m_mapRefManager.getSize() == 1)
|
||||||
m_unloadTimer = m_unloadWhenEmpty ? MIN_UNLOAD_DELAY : std::max(sWorld.getConfig(CONFIG_INSTANCE_UNLOAD_DELAY), (uint32)MIN_UNLOAD_DELAY);
|
m_unloadTimer = m_unloadWhenEmpty ? MIN_UNLOAD_DELAY : std::max(sWorld.getConfig(CONFIG_INSTANCE_UNLOAD_DELAY), (uint32)MIN_UNLOAD_DELAY);
|
||||||
Map::Remove(player, remove);
|
Map::Remove(player, remove);
|
||||||
}
|
}
|
||||||
|
|
@ -1664,21 +1695,21 @@ bool InstanceMap::Reset(uint8 method)
|
||||||
// note: since the map may not be loaded when the instance needs to be reset
|
// note: since the map may not be loaded when the instance needs to be reset
|
||||||
// the instance must be deleted from the DB by InstanceSaveManager
|
// the instance must be deleted from the DB by InstanceSaveManager
|
||||||
|
|
||||||
if(!i_Players.empty())
|
if(HavePlayers())
|
||||||
{
|
{
|
||||||
if(method == INSTANCE_RESET_ALL)
|
if(method == INSTANCE_RESET_ALL)
|
||||||
{
|
{
|
||||||
// notify the players to leave the instance so it can be reset
|
// notify the players to leave the instance so it can be reset
|
||||||
for(PlayerList::iterator itr = i_Players.begin(); itr != i_Players.end(); ++itr)
|
for(MapRefManager::iterator itr = m_mapRefManager.begin(); itr != m_mapRefManager.end(); ++itr)
|
||||||
(*itr)->SendResetFailedNotify(GetId());
|
itr->getSource()->SendResetFailedNotify(GetId());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(method == INSTANCE_RESET_GLOBAL)
|
if(method == INSTANCE_RESET_GLOBAL)
|
||||||
{
|
{
|
||||||
// set the homebind timer for players inside (1 minute)
|
// set the homebind timer for players inside (1 minute)
|
||||||
for(PlayerList::iterator itr = i_Players.begin(); itr != i_Players.end(); ++itr)
|
for(MapRefManager::iterator itr = m_mapRefManager.begin(); itr != m_mapRefManager.end(); ++itr)
|
||||||
(*itr)->m_InstanceValid = false;
|
itr->getSource()->m_InstanceValid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// the unload timer is not started
|
// the unload timer is not started
|
||||||
|
|
@ -1694,16 +1725,7 @@ bool InstanceMap::Reset(uint8 method)
|
||||||
m_resetAfterUnload = true;
|
m_resetAfterUnload = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return i_Players.empty();
|
return m_mapRefManager.isEmpty();
|
||||||
}
|
|
||||||
|
|
||||||
uint32 InstanceMap::GetPlayersCountExceptGMs() const
|
|
||||||
{
|
|
||||||
uint32 count = 0;
|
|
||||||
for(PlayerList::const_iterator itr = i_Players.begin(); itr != i_Players.end(); ++itr)
|
|
||||||
if(!(*itr)->isGameMaster())
|
|
||||||
++count;
|
|
||||||
return count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstanceMap::PermBindAllPlayers(Player *player)
|
void InstanceMap::PermBindAllPlayers(Player *player)
|
||||||
|
|
@ -1717,25 +1739,23 @@ void InstanceMap::PermBindAllPlayers(Player *player)
|
||||||
|
|
||||||
Group *group = player->GetGroup();
|
Group *group = player->GetGroup();
|
||||||
// group members outside the instance group don't get bound
|
// group members outside the instance group don't get bound
|
||||||
for(PlayerList::iterator itr = i_Players.begin(); itr != i_Players.end(); ++itr)
|
for(MapRefManager::iterator itr = m_mapRefManager.begin(); itr != m_mapRefManager.end(); ++itr)
|
||||||
{
|
{
|
||||||
if(*itr)
|
Player* plr = itr->getSource();
|
||||||
|
// players inside an instance cannot be bound to other instances
|
||||||
|
// some players may already be permanently bound, in this case nothing happens
|
||||||
|
InstancePlayerBind *bind = plr->GetBoundInstance(save->GetMapId(), save->GetDifficulty());
|
||||||
|
if(!bind || !bind->perm)
|
||||||
{
|
{
|
||||||
// players inside an instance cannot be bound to other instances
|
plr->BindToInstance(save, true);
|
||||||
// some players may already be permanently bound, in this case nothing happens
|
WorldPacket data(SMSG_INSTANCE_SAVE_CREATED, 4);
|
||||||
InstancePlayerBind *bind = (*itr)->GetBoundInstance(save->GetMapId(), save->GetDifficulty());
|
data << uint32(0);
|
||||||
if(!bind || !bind->perm)
|
plr->GetSession()->SendPacket(&data);
|
||||||
{
|
|
||||||
(*itr)->BindToInstance(save, true);
|
|
||||||
WorldPacket data(SMSG_INSTANCE_SAVE_CREATED, 4);
|
|
||||||
data << uint32(0);
|
|
||||||
(*itr)->GetSession()->SendPacket(&data);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the leader is not in the instance the group will not get a perm bind
|
|
||||||
if(group && group->GetLeaderGUID() == (*itr)->GetGUID())
|
|
||||||
group->BindToInstance(save, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if the leader is not in the instance the group will not get a perm bind
|
||||||
|
if(group && group->GetLeaderGUID() == plr->GetGUID())
|
||||||
|
group->BindToInstance(save, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1747,11 +1767,14 @@ time_t InstanceMap::GetResetTime()
|
||||||
|
|
||||||
void InstanceMap::UnloadAll(bool pForce)
|
void InstanceMap::UnloadAll(bool pForce)
|
||||||
{
|
{
|
||||||
if(!i_Players.empty())
|
if(HavePlayers())
|
||||||
{
|
{
|
||||||
sLog.outError("InstanceMap::UnloadAll: there are still players in the instance at unload, should not happen!");
|
sLog.outError("InstanceMap::UnloadAll: there are still players in the instance at unload, should not happen!");
|
||||||
for(PlayerList::iterator itr = i_Players.begin(); itr != i_Players.end(); ++itr)
|
for(MapRefManager::iterator itr = m_mapRefManager.begin(); itr != m_mapRefManager.end(); ++itr)
|
||||||
if(*itr) (*itr)->TeleportTo((*itr)->m_homebindMapId, (*itr)->m_homebindX, (*itr)->m_homebindY, (*itr)->m_homebindZ, (*itr)->GetOrientation());
|
{
|
||||||
|
Player* plr = itr->getSource();
|
||||||
|
plr->TeleportTo(plr->m_homebindMapId, plr->m_homebindX, plr->m_homebindY, plr->m_homebindZ, plr->GetOrientation());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_resetAfterUnload == true)
|
if(m_resetAfterUnload == true)
|
||||||
|
|
@ -1762,8 +1785,8 @@ void InstanceMap::UnloadAll(bool pForce)
|
||||||
|
|
||||||
void InstanceMap::SendResetWarnings(uint32 timeLeft)
|
void InstanceMap::SendResetWarnings(uint32 timeLeft)
|
||||||
{
|
{
|
||||||
for(PlayerList::iterator itr = i_Players.begin(); itr != i_Players.end(); ++itr)
|
for(MapRefManager::iterator itr = m_mapRefManager.begin(); itr != m_mapRefManager.end(); ++itr)
|
||||||
(*itr)->SendInstanceResetWarning(GetId(), timeLeft);
|
itr->getSource()->SendInstanceResetWarning(GetId(), timeLeft);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstanceMap::SetResetSchedule(bool on)
|
void InstanceMap::SetResetSchedule(bool on)
|
||||||
|
|
@ -1771,7 +1794,7 @@ void InstanceMap::SetResetSchedule(bool on)
|
||||||
// only for normal instances
|
// only for normal instances
|
||||||
// the reset time is only scheduled when there are no payers inside
|
// the reset time is only scheduled when there are no payers inside
|
||||||
// it is assumed that the reset time will rarely (if ever) change while the reset is scheduled
|
// it is assumed that the reset time will rarely (if ever) change while the reset is scheduled
|
||||||
if(i_Players.empty() && !IsRaid() && !IsHeroic())
|
if(!HavePlayers() && !IsRaid() && !IsHeroic())
|
||||||
{
|
{
|
||||||
InstanceSave *save = sInstanceSaveManager.GetInstanceSave(GetInstanceId());
|
InstanceSave *save = sInstanceSaveManager.GetInstanceSave(GetInstanceId());
|
||||||
if(!save) sLog.outError("InstanceMap::SetResetSchedule: cannot turn schedule %s, no save available for instance %d of %d", on ? "on" : "off", GetInstanceId(), GetId());
|
if(!save) sLog.outError("InstanceMap::SetResetSchedule: cannot turn schedule %s, no save available for instance %d of %d", on ? "on" : "off", GetInstanceId(), GetId());
|
||||||
|
|
@ -1779,12 +1802,6 @@ void InstanceMap::SetResetSchedule(bool on)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstanceMap::SendToPlayers(WorldPacket const* data) const
|
|
||||||
{
|
|
||||||
for(PlayerList::const_iterator itr = i_Players.begin(); itr != i_Players.end(); ++itr)
|
|
||||||
(*itr)->GetSession()->SendPacket(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ******* Battleground Instance Maps ******* */
|
/* ******* Battleground Instance Maps ******* */
|
||||||
|
|
||||||
BattleGroundMap::BattleGroundMap(uint32 id, time_t expiry, uint32 InstanceId)
|
BattleGroundMap::BattleGroundMap(uint32 id, time_t expiry, uint32 InstanceId)
|
||||||
|
|
@ -1798,7 +1815,7 @@ BattleGroundMap::~BattleGroundMap()
|
||||||
|
|
||||||
bool BattleGroundMap::CanEnter(Player * player)
|
bool BattleGroundMap::CanEnter(Player * player)
|
||||||
{
|
{
|
||||||
if(std::find(i_Players.begin(),i_Players.end(),player)!=i_Players.end())
|
if(player->GetMapRef().getTarget() == this)
|
||||||
{
|
{
|
||||||
sLog.outError("BGMap::CanEnter - player %u already in map!", player->GetGUIDLow());
|
sLog.outError("BGMap::CanEnter - player %u already in map!", player->GetGUIDLow());
|
||||||
assert(false);
|
assert(false);
|
||||||
|
|
@ -1819,7 +1836,6 @@ bool BattleGroundMap::Add(Player * player)
|
||||||
Guard guard(*this);
|
Guard guard(*this);
|
||||||
if(!CanEnter(player))
|
if(!CanEnter(player))
|
||||||
return false;
|
return false;
|
||||||
i_Players.push_back(player);
|
|
||||||
// reset instance validity, battleground maps do not homebind
|
// reset instance validity, battleground maps do not homebind
|
||||||
player->m_InstanceValid = true;
|
player->m_InstanceValid = true;
|
||||||
}
|
}
|
||||||
|
|
@ -1829,7 +1845,6 @@ bool BattleGroundMap::Add(Player * player)
|
||||||
void BattleGroundMap::Remove(Player *player, bool remove)
|
void BattleGroundMap::Remove(Player *player, bool remove)
|
||||||
{
|
{
|
||||||
sLog.outDetail("MAP: Removing player '%s' from bg '%u' of map '%s' before relocating to other map", player->GetName(), GetInstanceId(), GetMapName());
|
sLog.outDetail("MAP: Removing player '%s' from bg '%u' of map '%s' before relocating to other map", player->GetName(), GetInstanceId(), GetMapName());
|
||||||
i_Players.remove(player);
|
|
||||||
Map::Remove(player, remove);
|
Map::Remove(player, remove);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1840,15 +1855,14 @@ void BattleGroundMap::SetUnload()
|
||||||
|
|
||||||
void BattleGroundMap::UnloadAll(bool pForce)
|
void BattleGroundMap::UnloadAll(bool pForce)
|
||||||
{
|
{
|
||||||
while(!i_Players.empty())
|
while(HavePlayers())
|
||||||
{
|
{
|
||||||
PlayerList::iterator itr = i_Players.begin();
|
Player * plr = m_mapRefManager.getFirst()->getSource();
|
||||||
Player * plr = *itr;
|
if(plr) (plr)->TeleportTo(plr->m_homebindMapId, plr->m_homebindX, plr->m_homebindY, plr->m_homebindZ, plr->GetOrientation());
|
||||||
if(plr) (plr)->TeleportTo((*itr)->m_homebindMapId, (*itr)->m_homebindX, (*itr)->m_homebindY, (*itr)->m_homebindZ, (*itr)->GetOrientation());
|
|
||||||
// TeleportTo removes the player from this map (if the map exists) -> calls BattleGroundMap::Remove -> invalidates the iterator.
|
// TeleportTo removes the player from this map (if the map exists) -> calls BattleGroundMap::Remove -> invalidates the iterator.
|
||||||
// just in case, remove the player from the list explicitly here as well to prevent a possible infinite loop
|
// just in case, remove the player from the list explicitly here as well to prevent a possible infinite loop
|
||||||
// note that this remove is not needed if the code works well in other places
|
// note that this remove is not needed if the code works well in other places
|
||||||
i_Players.remove(plr);
|
plr->GetMapRef().unlink();
|
||||||
}
|
}
|
||||||
|
|
||||||
Map::UnloadAll(pForce);
|
Map::UnloadAll(pForce);
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
#include "SharedDefines.h"
|
#include "SharedDefines.h"
|
||||||
#include "GameSystem/GridRefManager.h"
|
#include "GameSystem/GridRefManager.h"
|
||||||
|
#include "MapRefManager.h"
|
||||||
|
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
@ -244,6 +245,14 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
|
||||||
bool isCellMarked(uint32 pCellId) { return marked_cells.test(pCellId); }
|
bool isCellMarked(uint32 pCellId) { return marked_cells.test(pCellId); }
|
||||||
void markCell(uint32 pCellId) { marked_cells.set(pCellId); }
|
void markCell(uint32 pCellId) { marked_cells.set(pCellId); }
|
||||||
|
|
||||||
|
bool HavePlayers() const { return !m_mapRefManager.isEmpty(); }
|
||||||
|
uint32 GetPlayersCountExceptGMs() const;
|
||||||
|
bool PlayersNearGrid(uint32 x,uint32 y) const;
|
||||||
|
|
||||||
|
void SendToPlayers(WorldPacket const* data) const;
|
||||||
|
|
||||||
|
MapRefManager m_mapRefManager;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void LoadVMap(int pX, int pY);
|
void LoadVMap(int pX, int pY);
|
||||||
void LoadMap(uint32 mapid, uint32 instanceid, int x,int y);
|
void LoadMap(uint32 mapid, uint32 instanceid, int x,int y);
|
||||||
|
|
@ -343,13 +352,9 @@ class MANGOS_DLL_SPEC InstanceMap : public Map
|
||||||
uint32 GetScriptId() { return i_script_id; }
|
uint32 GetScriptId() { return i_script_id; }
|
||||||
InstanceData* GetInstanceData() { return i_data; }
|
InstanceData* GetInstanceData() { return i_data; }
|
||||||
void PermBindAllPlayers(Player *player);
|
void PermBindAllPlayers(Player *player);
|
||||||
PlayerList const& GetPlayers() const { return i_Players;}
|
|
||||||
void SendToPlayers(WorldPacket const* data) const;
|
|
||||||
time_t GetResetTime();
|
time_t GetResetTime();
|
||||||
void UnloadAll(bool pForce);
|
void UnloadAll(bool pForce);
|
||||||
bool CanEnter(Player* player);
|
bool CanEnter(Player* player);
|
||||||
uint32 GetPlayersCountExceptGMs() const;
|
|
||||||
uint32 HavePlayers() const { return !i_Players.empty(); }
|
|
||||||
void SendResetWarnings(uint32 timeLeft);
|
void SendResetWarnings(uint32 timeLeft);
|
||||||
void SetResetSchedule(bool on);
|
void SetResetSchedule(bool on);
|
||||||
private:
|
private:
|
||||||
|
|
@ -357,16 +362,11 @@ class MANGOS_DLL_SPEC InstanceMap : public Map
|
||||||
bool m_unloadWhenEmpty;
|
bool m_unloadWhenEmpty;
|
||||||
InstanceData* i_data;
|
InstanceData* i_data;
|
||||||
uint32 i_script_id;
|
uint32 i_script_id;
|
||||||
// only online players that are inside the instance currently
|
|
||||||
// TODO ? - use the grid instead to access the players
|
|
||||||
PlayerList i_Players;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class MANGOS_DLL_SPEC BattleGroundMap : public Map
|
class MANGOS_DLL_SPEC BattleGroundMap : public Map
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::list<Player *> PlayerList; // online players only
|
|
||||||
|
|
||||||
BattleGroundMap(uint32 id, time_t, uint32 InstanceId);
|
BattleGroundMap(uint32 id, time_t, uint32 InstanceId);
|
||||||
~BattleGroundMap();
|
~BattleGroundMap();
|
||||||
|
|
||||||
|
|
@ -375,8 +375,6 @@ class MANGOS_DLL_SPEC BattleGroundMap : public Map
|
||||||
bool CanEnter(Player* player);
|
bool CanEnter(Player* player);
|
||||||
void SetUnload();
|
void SetUnload();
|
||||||
void UnloadAll(bool pForce);
|
void UnloadAll(bool pForce);
|
||||||
private:
|
|
||||||
PlayerList i_Players;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*inline
|
/*inline
|
||||||
|
|
|
||||||
|
|
@ -337,7 +337,7 @@ uint32 MapManager::GetNumPlayersInInstances()
|
||||||
MapInstanced::InstancedMaps &maps = ((MapInstanced *)map)->GetInstancedMaps();
|
MapInstanced::InstancedMaps &maps = ((MapInstanced *)map)->GetInstancedMaps();
|
||||||
for(MapInstanced::InstancedMaps::iterator mitr = maps.begin(); mitr != maps.end(); ++mitr)
|
for(MapInstanced::InstancedMaps::iterator mitr = maps.begin(); mitr != maps.end(); ++mitr)
|
||||||
if(mitr->second->IsDungeon())
|
if(mitr->second->IsDungeon())
|
||||||
ret += ((InstanceMap*)mitr->second)->GetPlayers().size();
|
ret += ((InstanceMap*)mitr->second)->m_mapRefManager.getSize();
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
44
src/game/MapRefManager.h
Normal file
44
src/game/MapRefManager.h
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _MAPREFMANAGER
|
||||||
|
#define _MAPREFMANAGER
|
||||||
|
|
||||||
|
#include "Utilities/LinkedReference/RefManager.h"
|
||||||
|
|
||||||
|
class MapReference;
|
||||||
|
|
||||||
|
class MapRefManager : public RefManager<Map, Player>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef LinkedListHead::Iterator< MapReference > iterator;
|
||||||
|
typedef LinkedListHead::Iterator< MapReference const > const_iterator;
|
||||||
|
|
||||||
|
MapReference* getFirst() { return (MapReference*)RefManager<Map, Player>::getFirst(); }
|
||||||
|
MapReference const* getFirst() const { return (MapReference const*)RefManager<Map, Player>::getFirst(); }
|
||||||
|
MapReference* getLast() { return (MapReference*)RefManager<Map, Player>::getLast(); }
|
||||||
|
MapReference const* getLast() const { return (MapReference const*)RefManager<Map, Player>::getLast(); }
|
||||||
|
|
||||||
|
iterator begin() { return iterator(getFirst()); }
|
||||||
|
iterator end() { return iterator(NULL); }
|
||||||
|
iterator rbegin() { return iterator(getLast()); }
|
||||||
|
iterator rend() { return iterator(NULL); }
|
||||||
|
const_iterator begin() const { return const_iterator(getFirst()); }
|
||||||
|
const_iterator end() const { return const_iterator(getLast()); }
|
||||||
|
};
|
||||||
|
#endif
|
||||||
50
src/game/MapReference.h
Normal file
50
src/game/MapReference.h
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _MAPREFERENCE_H
|
||||||
|
#define _MAPREFERENCE_H
|
||||||
|
|
||||||
|
#include "Utilities/LinkedReference/Reference.h"
|
||||||
|
#include "Map.h"
|
||||||
|
|
||||||
|
class MANGOS_DLL_SPEC MapReference : public Reference<Map, Player>
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
void targetObjectBuildLink()
|
||||||
|
{
|
||||||
|
// called from link()
|
||||||
|
getTarget()->m_mapRefManager.insertFirst(this);
|
||||||
|
getTarget()->m_mapRefManager.incSize();
|
||||||
|
}
|
||||||
|
void targetObjectDestroyLink()
|
||||||
|
{
|
||||||
|
// called from unlink()
|
||||||
|
if(isValid()) getTarget()->m_mapRefManager.decSize();
|
||||||
|
}
|
||||||
|
void sourceObjectDestroyLink()
|
||||||
|
{
|
||||||
|
// called from invalidate()
|
||||||
|
getTarget()->m_mapRefManager.decSize();
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
MapReference() : Reference<Map, Player>() {}
|
||||||
|
~MapReference() { unlink(); }
|
||||||
|
MapReference *next() { return (MapReference*)Reference<Map, Player>::next(); }
|
||||||
|
MapReference const *next() const { return (MapReference const*)Reference<Map, Player>::next(); }
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
@ -519,32 +519,6 @@ ObjectAccessor::UpdatePlayers(uint32 diff)
|
||||||
iter->second->Update(diff);
|
iter->second->Update(diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
ObjectAccessor::PlayersNearGrid(uint32 x, uint32 y, uint32 m_id, uint32 i_id) const
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
|
|
||||||
//TODO: Guard player
|
|
||||||
HashMapHolder<Player>::MapType& playerMap = HashMapHolder<Player>::GetContainer();
|
|
||||||
for(HashMapHolder<Player>::MapType::const_iterator iter=playerMap.begin(); iter != playerMap.end(); ++iter)
|
|
||||||
{
|
|
||||||
if( m_id != iter->second->GetMapId() || i_id != iter->second->GetInstanceId() )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
CellPair p = MaNGOS::ComputeCellPair(iter->second->GetPositionX(), iter->second->GetPositionY());
|
|
||||||
if( (cell_min.x_coord <= p.x_coord && p.x_coord <= cell_max.x_coord) &&
|
|
||||||
(cell_min.y_coord <= p.y_coord && p.y_coord <= cell_max.y_coord) )
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ObjectAccessor::WorldObjectChangeAccumulator::Visit(PlayerMapType &m)
|
ObjectAccessor::WorldObjectChangeAccumulator::Visit(PlayerMapType &m)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -194,8 +194,6 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,
|
||||||
void AddCorpsesToGrid(GridPair const& gridpair,GridType& grid,Map* map);
|
void AddCorpsesToGrid(GridPair const& gridpair,GridType& grid,Map* map);
|
||||||
Corpse* ConvertCorpseForPlayer(uint64 player_guid);
|
Corpse* ConvertCorpseForPlayer(uint64 player_guid);
|
||||||
|
|
||||||
bool PlayersNearGrid(uint32 x,uint32 y,uint32 m_id,uint32 i_id) const;
|
|
||||||
|
|
||||||
static void UpdateObject(Object* obj, Player* exceptPlayer);
|
static void UpdateObject(Object* obj, Player* exceptPlayer);
|
||||||
static void _buildUpdateObject(Object* obj, UpdateDataMapType &);
|
static void _buildUpdateObject(Object* obj, UpdateDataMapType &);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@
|
||||||
#include "Bag.h"
|
#include "Bag.h"
|
||||||
#include "WorldSession.h"
|
#include "WorldSession.h"
|
||||||
#include "Pet.h"
|
#include "Pet.h"
|
||||||
|
#include "MapReference.h"
|
||||||
#include "Util.h" // for Tokens typedef
|
#include "Util.h" // for Tokens typedef
|
||||||
#include "AchievementMgr.h"
|
#include "AchievementMgr.h"
|
||||||
|
|
||||||
|
|
@ -2057,6 +2058,8 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
Player* GetNextRandomRaidMember(float radius);
|
Player* GetNextRandomRaidMember(float radius);
|
||||||
|
|
||||||
GridReference<Player> &GetGridRef() { return m_gridRef; }
|
GridReference<Player> &GetGridRef() { return m_gridRef; }
|
||||||
|
MapReference &GetMapRef() { return m_mapRef; }
|
||||||
|
|
||||||
bool isAllowedToLoot(Creature* creature);
|
bool isAllowedToLoot(Creature* creature);
|
||||||
|
|
||||||
WorldLocation& GetTeleportDest() { return m_teleport_dest; }
|
WorldLocation& GetTeleportDest() { return m_teleport_dest; }
|
||||||
|
|
@ -2303,6 +2306,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
Item* _StoreItem( uint16 pos, Item *pItem, uint32 count, bool clone, bool update );
|
Item* _StoreItem( uint16 pos, Item *pItem, uint32 count, bool clone, bool update );
|
||||||
|
|
||||||
GridReference<Player> m_gridRef;
|
GridReference<Player> m_gridRef;
|
||||||
|
MapReference m_mapRef;
|
||||||
};
|
};
|
||||||
|
|
||||||
void AddItemsSetItem(Player*player,Item *item);
|
void AddItemsSetItem(Player*player,Item *item);
|
||||||
|
|
|
||||||
|
|
@ -2035,6 +2035,17 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
|
||||||
caster->CastSpell(m_target,finalSpelId,true,NULL,this);
|
caster->CastSpell(m_target,finalSpelId,true,NULL,this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Waiting to Resurrect
|
||||||
|
if(GetId()==2584)
|
||||||
|
{
|
||||||
|
// Waiting to resurrect spell cancel, we must remove player from resurrect queue
|
||||||
|
if(m_target->GetTypeId() == TYPEID_PLAYER)
|
||||||
|
if(BattleGround *bg = ((Player*)m_target)->GetBattleGround())
|
||||||
|
bg->RemovePlayerFromResurrectQueue(m_target->GetGUID());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Dark Fiend
|
// Dark Fiend
|
||||||
if(GetId()==45934)
|
if(GetId()==45934)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -363,15 +363,23 @@ void WorldSession::HandleCancelAuraOpcode( WorldPacket& recvPacket)
|
||||||
if(!IsPositiveSpell(spellId) || (spellInfo->Attributes & SPELL_ATTR_CANT_CANCEL))
|
if(!IsPositiveSpell(spellId) || (spellInfo->Attributes & SPELL_ATTR_CANT_CANCEL))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_player->RemoveAurasDueToSpellByCancel(spellId);
|
// channeled spell case (it currently casted then)
|
||||||
|
if(IsChanneledSpell(spellInfo))
|
||||||
if (spellId == 2584) // Waiting to resurrect spell cancel, we must remove player from resurrect queue
|
|
||||||
{
|
{
|
||||||
BattleGround *bg = _player->GetBattleGround();
|
if(Spell* spell = _player->m_currentSpells[CURRENT_CHANNELED_SPELL])
|
||||||
if(!bg)
|
{
|
||||||
return;
|
if(spell->m_spellInfo->Id==spellId)
|
||||||
bg->RemovePlayerFromResurrectQueue(_player->GetGUID());
|
{
|
||||||
|
spell->cancel();
|
||||||
|
spell->SetReferencedFromCurrent(false);
|
||||||
|
_player->m_currentSpells[CURRENT_CHANNELED_SPELL] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// non channeled case
|
||||||
|
_player->RemoveAurasDueToSpellByCancel(spellId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldSession::HandlePetCancelAuraOpcode( WorldPacket& recvPacket)
|
void WorldSession::HandlePetCancelAuraOpcode( WorldPacket& recvPacket)
|
||||||
|
|
|
||||||
|
|
@ -4105,12 +4105,17 @@ void Unit::RemoveNotOwnSingleTargetAuras()
|
||||||
|
|
||||||
void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode)
|
void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode)
|
||||||
{
|
{
|
||||||
if (IsSingleTargetSpell((*i).second->GetSpellProto()))
|
Aura* Aur = i->second;
|
||||||
|
SpellEntry const* AurSpellInfo = Aur->GetSpellProto();
|
||||||
|
|
||||||
|
Unit* caster = NULL;
|
||||||
|
if (IsSingleTargetSpell(AurSpellInfo))
|
||||||
{
|
{
|
||||||
if(Unit* caster = (*i).second->GetCaster())
|
caster = Aur->GetCaster();
|
||||||
|
if(!caster)
|
||||||
{
|
{
|
||||||
AuraList& scAuras = caster->GetSingleCastAuras();
|
AuraList& scAuras = caster->GetSingleCastAuras();
|
||||||
scAuras.remove((*i).second);
|
scAuras.remove(Aur);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -4119,13 +4124,12 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((*i).second->GetModifier()->m_auraname < TOTAL_AURAS)
|
// remove from list before mods removing (prevent cyclic calls, mods added before including to aura list - use reverse order)
|
||||||
|
if (Aur->GetModifier()->m_auraname < TOTAL_AURAS)
|
||||||
{
|
{
|
||||||
m_modAuras[(*i).second->GetModifier()->m_auraname].remove((*i).second);
|
m_modAuras[Aur->GetModifier()->m_auraname].remove(Aur);
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove from list before mods removing (prevent cyclic calls, mods added before including to aura list - use reverse order)
|
|
||||||
Aura* Aur = i->second;
|
|
||||||
// Set remove mode
|
// Set remove mode
|
||||||
Aur->SetRemoveMode(mode);
|
Aur->SetRemoveMode(mode);
|
||||||
// some ShapeshiftBoosts at remove trigger removing other auras including parent Shapeshift aura
|
// some ShapeshiftBoosts at remove trigger removing other auras including parent Shapeshift aura
|
||||||
|
|
@ -4135,16 +4139,29 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode)
|
||||||
|
|
||||||
// Statue unsummoned at aura remove
|
// Statue unsummoned at aura remove
|
||||||
Totem* statue = NULL;
|
Totem* statue = NULL;
|
||||||
if(IsChanneledSpell(Aur->GetSpellProto()))
|
bool caster_channeled = false;
|
||||||
if(Unit* caster = Aur->GetCaster())
|
if(IsChanneledSpell(AurSpellInfo))
|
||||||
|
{
|
||||||
|
if(!caster) // can be already located for IsSingleTargetSpell case
|
||||||
|
caster = Aur->GetCaster();
|
||||||
|
|
||||||
|
if(caster)
|
||||||
|
{
|
||||||
if(caster->GetTypeId()==TYPEID_UNIT && ((Creature*)caster)->isTotem() && ((Totem*)caster)->GetTotemType()==TOTEM_STATUE)
|
if(caster->GetTypeId()==TYPEID_UNIT && ((Creature*)caster)->isTotem() && ((Totem*)caster)->GetTotemType()==TOTEM_STATUE)
|
||||||
statue = ((Totem*)caster);
|
statue = ((Totem*)caster);
|
||||||
|
else
|
||||||
|
caster_channeled = caster==this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sLog.outDebug("Aura %u now is remove mode %d",Aur->GetModifier()->m_auraname, mode);
|
sLog.outDebug("Aura %u now is remove mode %d",Aur->GetModifier()->m_auraname, mode);
|
||||||
Aur->ApplyModifier(false,true);
|
Aur->ApplyModifier(false,true);
|
||||||
Aur->_RemoveAura();
|
Aur->_RemoveAura();
|
||||||
delete Aur;
|
delete Aur;
|
||||||
|
|
||||||
|
if(caster_channeled)
|
||||||
|
RemoveAurasAtChanneledTarget (AurSpellInfo);
|
||||||
|
|
||||||
if(statue)
|
if(statue)
|
||||||
statue->UnSummon();
|
statue->UnSummon();
|
||||||
|
|
||||||
|
|
@ -10919,3 +10936,23 @@ bool Unit::HandleMeandingAuraProc( Aura* triggeredByAura )
|
||||||
CastCustomSpell(this,33110,&heal,NULL,NULL,true,NULL,NULL,caster_guid);
|
CastCustomSpell(this,33110,&heal,NULL,NULL,true,NULL,NULL,caster_guid);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Unit::RemoveAurasAtChanneledTarget(SpellEntry const* spellInfo)
|
||||||
|
{
|
||||||
|
uint64 target_guid = GetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT);
|
||||||
|
|
||||||
|
if(!IS_UNIT_GUID(target_guid))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Unit* target = ObjectAccessor::GetUnit(*this, target_guid);
|
||||||
|
if(!target)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (AuraMap::iterator iter = target->GetAuras().begin(); iter != target->GetAuras().end(); )
|
||||||
|
{
|
||||||
|
if (iter->second->GetId() == spellInfo->Id && iter->second->GetCasterGUID()==GetGUID())
|
||||||
|
target->RemoveAura(iter);
|
||||||
|
else
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1031,6 +1031,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
|
||||||
void RemoveAurasDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit *dispeler);
|
void RemoveAurasDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit *dispeler);
|
||||||
void RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit *stealer);
|
void RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit *stealer);
|
||||||
void RemoveAurasDueToSpellByCancel(uint32 spellId);
|
void RemoveAurasDueToSpellByCancel(uint32 spellId);
|
||||||
|
void RemoveAurasAtChanneledTarget(SpellEntry const* spellInfo);
|
||||||
void RemoveNotOwnSingleTargetAuras();
|
void RemoveNotOwnSingleTargetAuras();
|
||||||
|
|
||||||
void RemoveSpellsCausingAura(AuraType auraType);
|
void RemoveSpellsCausingAura(AuraType auraType);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "6832"
|
#define REVISION_NR "6833"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
|
|
@ -876,6 +876,12 @@
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\src\game\HostilRefManager.h">
|
RelativePath="..\..\src\game\HostilRefManager.h">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\src\game\MapReference.h">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\src\game\MapRefManager.h">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\src\game\ThreatManager.cpp">
|
RelativePath="..\..\src\game\ThreatManager.cpp">
|
||||||
</File>
|
</File>
|
||||||
|
|
|
||||||
|
|
@ -1338,6 +1338,14 @@
|
||||||
RelativePath="..\..\src\game\HostilRefManager.h"
|
RelativePath="..\..\src\game\HostilRefManager.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\src\game\MapRefManager.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\src\game\MapReference.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\src\game\ThreatManager.cpp"
|
RelativePath="..\..\src\game\ThreatManager.cpp"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -1340,6 +1340,14 @@
|
||||||
RelativePath="..\..\src\game\HostilRefManager.h"
|
RelativePath="..\..\src\game\HostilRefManager.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\src\game\MapRefManager.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\src\game\MapReference.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\src\game\ThreatManager.cpp"
|
RelativePath="..\..\src\game\ThreatManager.cpp"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue