*Update relocation notification code. Always store pointers instead of guids.

--HG--
branch : trunk
This commit is contained in:
megamage
2009-06-09 16:05:14 -05:00
parent 0643c3df83
commit 2625b4b6c6
4 changed files with 64 additions and 40 deletions
+46 -27
View File
@@ -370,16 +370,16 @@ void Map::AddNotifier(T*)
template<> template<>
void Map::AddNotifier(Player* obj) void Map::AddNotifier(Player* obj)
{ {
obj->m_Notified = false; //obj->m_Notified = false;
obj->m_IsInNotifyList = false; //obj->m_IsInNotifyList = false;
AddUnitToNotify(obj); AddUnitToNotify(obj);
} }
template<> template<>
void Map::AddNotifier(Creature* obj) void Map::AddNotifier(Creature* obj)
{ {
obj->m_Notified = false; //obj->m_Notified = false;
obj->m_IsInNotifyList = false; //obj->m_IsInNotifyList = false;
AddUnitToNotify(obj); AddUnitToNotify(obj);
} }
@@ -561,25 +561,21 @@ bool Map::loaded(const GridPair &p) const
void Map::RelocationNotify() void Map::RelocationNotify()
{ {
//Move backlog to notify list i_lock = true;
for(std::vector<uint64>::iterator iter = i_unitsToNotifyBacklog.begin(); iter != i_unitsToNotifyBacklog.end(); ++iter)
{
if(Unit *unit = ObjectAccessor::GetObjectInWorld(*iter, (Unit*)NULL))
{
i_unitsToNotify.push_back(unit);
}
}
i_unitsToNotifyBacklog.clear();
//Notify //Notify
for(std::vector<Unit*>::iterator iter = i_unitsToNotify.begin(); iter != i_unitsToNotify.end(); ++iter) for(std::vector<Unit*>::iterator iter = i_unitsToNotify.begin(); iter != i_unitsToNotify.end(); ++iter)
{ {
Unit *unit = *iter; Unit *unit = *iter;
if(unit->m_Notified || !unit->IsInWorld() || unit->GetMapId() != GetId()) if(!unit)
continue;
unit->m_NotifyListPos = -1;
if(unit->m_Notified)
continue; continue;
unit->m_Notified = true; unit->m_Notified = true;
unit->m_IsInNotifyList = false;
float dist = abs(unit->GetPositionX() - unit->oldX) + abs(unit->GetPositionY() - unit->oldY); float dist = abs(unit->GetPositionX() - unit->oldX) + abs(unit->GetPositionY() - unit->oldY);
if(dist > 10.0f) if(dist > 10.0f)
@@ -592,10 +588,10 @@ void Map::RelocationNotify()
if(unit->GetTypeId() == TYPEID_PLAYER) if(unit->GetTypeId() == TYPEID_PLAYER)
{ {
Trinity::PlayerRelocationNotifier notifier(*((Player*)unit)); Trinity::PlayerRelocationNotifier notifier(*((Player*)unit));
if(((Player*)unit)->m_seer != 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(), World::GetMaxVisibleDistance() + dist, notifier);
else //else
VisitAll(((Player*)unit)->GetPositionX(), ((Player*)unit)->GetPositionY(), World::GetMaxVisibleDistance() + dist, notifier); //VisitAll(((Player*)unit)->GetPositionX(), ((Player*)unit)->GetPositionY(), World::GetMaxVisibleDistance() + dist, notifier);
notifier.Notify(); notifier.Notify();
} }
else else
@@ -609,27 +605,52 @@ void Map::RelocationNotify()
(*iter)->m_Notified = false; (*iter)->m_Notified = false;
} }
i_unitsToNotify.clear(); i_unitsToNotify.clear();
i_lock = false;
if(!i_unitsToNotifyBacklog.empty())
{
i_unitsToNotify.insert(i_unitsToNotify.end(), i_unitsToNotifyBacklog.begin(), i_unitsToNotifyBacklog.end());
i_unitsToNotifyBacklog.clear();
}
} }
void Map::AddUnitToNotify(Unit* u) void Map::AddUnitToNotify(Unit* u)
{ {
if(u->m_IsInNotifyList) if(u->m_NotifyListPos < 0)
return; {
u->m_IsInNotifyList = true;
u->oldX = u->GetPositionX(); u->oldX = u->GetPositionX();
u->oldY = u->GetPositionY(); u->oldY = u->GetPositionY();
if(i_lock) if(i_lock)
i_unitsToNotifyBacklog.push_back(u->GetGUID()); {
u->m_NotifyListPos = i_unitsToNotifyBacklog.size();
i_unitsToNotifyBacklog.push_back(u);
}
else else
{
u->m_NotifyListPos = i_unitsToNotify.size();
i_unitsToNotify.push_back(u); i_unitsToNotify.push_back(u);
}
}
}
void Map::RemoveUnitFromNotify(int32 slot)
{
if(i_lock)
{
assert(slot < i_unitsToNotifyBacklog.size());
i_unitsToNotifyBacklog[slot] = NULL;
}
else
{
assert(slot < i_unitsToNotify.size());
i_unitsToNotify[slot] = NULL;
}
} }
void Map::Update(const uint32 &t_diff) void Map::Update(const uint32 &t_diff)
{ {
i_lock = false;
resetMarkedCells(); resetMarkedCells();
Trinity::ObjectUpdater updater(t_diff); Trinity::ObjectUpdater updater(t_diff);
@@ -734,8 +755,6 @@ void Map::Update(const uint32 &t_diff)
} }
} }
i_lock = true;
MoveAllCreaturesInMoveList(); MoveAllCreaturesInMoveList();
RelocationNotify(); RelocationNotify();
RemoveAllObjectsInRemoveList(); RemoveAllObjectsInRemoveList();
+2 -1
View File
@@ -388,6 +388,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
bool ActiveObjectsNearGrid(uint32 x, uint32 y) const; bool ActiveObjectsNearGrid(uint32 x, uint32 y) const;
void AddUnitToNotify(Unit* unit); void AddUnitToNotify(Unit* unit);
void RemoveUnitFromNotify(int32 slot);
void RelocationNotify(); void RelocationNotify();
void SendToPlayers(WorldPacket const* data) const; void SendToPlayers(WorldPacket const* data) const;
@@ -496,7 +497,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
time_t i_gridExpiry; time_t i_gridExpiry;
bool i_lock; bool i_lock;
std::vector<uint64> i_unitsToNotifyBacklog; std::vector<Unit*> i_unitsToNotifyBacklog;
std::vector<Unit*> i_unitsToNotify; std::vector<Unit*> i_unitsToNotify;
std::set<WorldObject *> i_objectsToRemove; std::set<WorldObject *> i_objectsToRemove;
std::map<WorldObject*, bool> i_objectsToSwitch; std::map<WorldObject*, bool> i_objectsToSwitch;
+11 -8
View File
@@ -80,7 +80,7 @@ static bool procPrepared = InitTriggerAuraData();
Unit::Unit() Unit::Unit()
: WorldObject(), i_motionMaster(this), m_ThreatManager(this), m_HostilRefManager(this) : WorldObject(), i_motionMaster(this), m_ThreatManager(this), m_HostilRefManager(this)
, m_IsInNotifyList(false), m_Notified(false), IsAIEnabled(false), NeedChangeAI(false) , m_NotifyListPos(-1), m_Notified(false), IsAIEnabled(false), NeedChangeAI(false)
, i_AI(NULL), i_disabledAI(NULL), m_removedAurasCount(0), m_Vehicle(NULL), m_transport(NULL) , i_AI(NULL), i_disabledAI(NULL), m_removedAurasCount(0), m_Vehicle(NULL), m_transport(NULL)
, m_ControlledByPlayer(false), m_procDeep(0) , m_ControlledByPlayer(false), m_procDeep(0)
{ {
@@ -10448,7 +10448,6 @@ void Unit::SetVisibility(UnitVisibility x)
{ {
m_Visibility = x; m_Visibility = x;
if(IsInWorld())
SetToNotify(); SetToNotify();
if(x == VISIBILITY_GROUP_STEALTH) if(x == VISIBILITY_GROUP_STEALTH)
@@ -11683,7 +11682,7 @@ void Unit::AddToWorld()
{ {
WorldObject::AddToWorld(); WorldObject::AddToWorld();
m_Notified = false; m_Notified = false;
m_IsInNotifyList = false; assert(m_NotifyListPos < 0);
SetToNotify(); SetToNotify();
} }
} }
@@ -11702,6 +11701,12 @@ void Unit::RemoveFromWorld()
RemoveNotOwnSingleTargetAuras(); RemoveNotOwnSingleTargetAuras();
ExitVehicle(); ExitVehicle();
if(m_NotifyListPos >= 0)
{
GetMap()->RemoveUnitFromNotify(m_NotifyListPos);
m_NotifyListPos = -1;
}
if(GetCharmerGUID()) if(GetCharmerGUID())
{ {
sLog.outCrash("Unit %u has charmer guid when removed from world", GetEntry()); sLog.outCrash("Unit %u has charmer guid when removed from world", GetEntry());
@@ -13227,11 +13232,9 @@ bool Unit::HandleAuraRaidProcFromCharge( AuraEffect* triggeredByAura )
void Unit::SetToNotify() void Unit::SetToNotify()
{ {
if(m_IsInNotifyList) // it is called somewhere when obj is not in world (crash when log in instance)
return; if(m_NotifyListPos < 0 && IsInWorld())
GetMap()->AddUnitToNotify(this);
if(Map *map = GetMap())
map->AddUnitToNotify(this);
} }
void Unit::Kill(Unit *pVictim, bool durabilityLoss) void Unit::Kill(Unit *pVictim, bool durabilityLoss)
+2 -1
View File
@@ -1722,7 +1722,8 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
// relocation notification // relocation notification
void SetToNotify(); void SetToNotify();
bool m_Notified, m_IsInNotifyList; bool m_Notified;
int32 m_NotifyListPos;
float oldX, oldY; float oldX, oldY;
void SetReducedThreatPercent(uint32 pct, uint64 guid) void SetReducedThreatPercent(uint32 pct, uint64 guid)