Skip to content

Instantly share code, notes, and snippets.

@rsa
Created July 7, 2011 19:20
Show Gist options
  • Save rsa/1070313 to your computer and use it in GitHub Desktop.
Save rsa/1070313 to your computer and use it in GitHub Desktop.
attackers patch
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index 018c7e9..2052815 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -5942,6 +5942,26 @@ bool Unit::IsNeutralToAll() const
return my_faction->IsNeutralToAll();
}
+Unit* Unit::getAttackerForHelper()
+{
+ if (getVictim())
+ return getVictim();
+
+ if (!m_attackers.empty())
+ {
+ for(AttackerSet::iterator i = m_attackers.begin(); i != m_attackers.end();)
+ {
+ ObjectGuid guid = *i;
+ Unit* attacker = GetMap()->GetUnit(guid);
+ if (!attacker || !attacker->isAlive())
+ m_attackers.erase(i);
+ else
+ return attacker;
+ }
+ }
+ return NULL;
+}
+
bool Unit::Attack(Unit *victim, bool meleeAttack)
{
if(!victim || victim == this)
@@ -6128,7 +6148,8 @@ void Unit::RemoveAllAttackers()
while (!m_attackers.empty())
{
AttackerSet::iterator iter = m_attackers.begin();
- if(!(*iter)->AttackStop())
+ Unit* attacker = GetMap()->GetUnit(*iter);
+ if(!attacker || !attacker->AttackStop())
{
sLog.outError("WORLD: Unit has an attacker that isn't attacking it!");
m_attackers.erase(iter);
@@ -9340,7 +9361,8 @@ bool Unit::SelectHostileTarget()
{
for(AttackerSet::const_iterator itr = m_attackers.begin(); itr != m_attackers.end(); ++itr)
{
- if ((*itr)->IsInMap(this) && (*itr)->isTargetableForAttack() && (*itr)->isInAccessablePlaceFor((Creature*)this))
+ Unit* attacker = GetMap()->GetUnit(*itr);
+ if (attacker && attacker->IsInMap(this) && attacker->isTargetableForAttack() && attacker->isInAccessablePlaceFor((Creature*)this))
return false;
}
}
@@ -11932,9 +11954,10 @@ void Unit::StopAttackFaction(uint32 faction_id)
AttackerSet const& attackers = getAttackers();
for(AttackerSet::const_iterator itr = attackers.begin(); itr != attackers.end();)
{
- if ((*itr)->getFactionTemplateEntry()->faction==faction_id)
+ Unit* attacker = GetMap()->GetUnit(*itr);
+ if (attacker && attacker->getFactionTemplateEntry()->faction==faction_id)
{
- (*itr)->AttackStop();
+ attacker->AttackStop();
itr = attackers.begin();
}
else
diff --git a/src/game/Unit.h b/src/game/Unit.h
index 83097b6..e52432f 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -1141,7 +1141,7 @@ class VehicleKit;
class MANGOS_DLL_SPEC Unit : public WorldObject
{
public:
- typedef std::set<Unit*> AttackerSet;
+ typedef std::set<ObjectGuid> AttackerSet;
typedef std::multimap< uint32, SpellAuraHolder*> SpellAuraHolderMap;
typedef std::pair<SpellAuraHolderMap::iterator, SpellAuraHolderMap::iterator> SpellAuraHolderBounds;
typedef std::pair<SpellAuraHolderMap::const_iterator, SpellAuraHolderMap::const_iterator> SpellAuraHolderConstBounds;
@@ -1197,26 +1197,23 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
bool CanReachWithMeleeAttack(Unit* pVictim, float flat_mod = 0.0f) const;
uint32 m_extraAttacks;
- void _addAttacker(Unit *pAttacker) // must be called only from Unit::Attack(Unit*)
+ void _addAttacker(Unit* pAttacker) // must be called only from Unit::Attack(Unit*)
{
- AttackerSet::const_iterator itr = m_attackers.find(pAttacker);
+ if (!pAttacker)
+ return;
+
+ AttackerSet::const_iterator itr = m_attackers.find(pAttacker->GetObjectGuid());
if(itr == m_attackers.end())
- m_attackers.insert(pAttacker);
- }
- void _removeAttacker(Unit *pAttacker) // must be called only from Unit::AttackStop()
- {
- m_attackers.erase(pAttacker);
+ m_attackers.insert(pAttacker->GetObjectGuid());
}
- Unit * getAttackerForHelper() // If someone wants to help, who to give them
+ void _removeAttacker(Unit* pAttacker) // must be called only from Unit::AttackStop()
{
- if (getVictim() != NULL)
- return getVictim();
-
- if (!m_attackers.empty())
- return *(m_attackers.begin());
+ if (!pAttacker)
+ return;
- return NULL;
+ m_attackers.erase(pAttacker->GetObjectGuid());
}
+ Unit* getAttackerForHelper(); // If someone wants to help, who to give them
bool Attack(Unit *victim, bool meleeAttack);
void AttackedBy(Unit *attacker);
void CastStop(uint32 except_spellid = 0);
diff --git a/src/game/WorldSession.cpp b/src/game/WorldSession.cpp
index 7eead9c..10a759d 100644
--- a/src/game/WorldSession.cpp
+++ b/src/game/WorldSession.cpp
@@ -413,15 +413,19 @@ void WorldSession::LogoutPlayer(bool Save)
std::set<Player*> aset;
for(Unit::AttackerSet::const_iterator itr = _player->getAttackers().begin(); itr != _player->getAttackers().end(); ++itr)
{
- Unit* owner = (*itr)->GetOwner(); // including player controlled case
+ Unit* attacker = _player->GetMap()->GetUnit(*itr);
+ if (!attacker)
+ continue;
+
+ Unit* owner = attacker->GetOwner(); // including player controlled case
if(owner)
{
- if(owner->GetTypeId()==TYPEID_PLAYER)
+ if(owner->GetTypeId() == TYPEID_PLAYER)
aset.insert((Player*)owner);
}
else
- if((*itr)->GetTypeId()==TYPEID_PLAYER)
- aset.insert((Player*)(*itr));
+ if(attacker->GetTypeId() == TYPEID_PLAYER)
+ aset.insert((Player*)(attacker));
}
_player->SetPvPDeath(!aset.empty());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment