aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorariel- <ariel-@users.noreply.github.com>2016-10-11 22:01:42 -0300
committerariel- <ariel-@users.noreply.github.com>2016-10-11 22:01:42 -0300
commit449ec0d6ff74ccd1874bc09073353d97c1d0151c (patch)
tree36f2bcf4155f035edd0909ea7780b3e79fd8ae81 /src
parent3cbd4bc22f013e8a4ab593c6f0afd2654fed6a66 (diff)
Core/Auras: don't ignore SPELL_ATTR3_ONLY_TARGET_PLAYERS in area auras.
Also, start abusing the arbitrary containers for searchers introduced in 8775f8b28a5ad4403371577787131ff81f14332b
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Grids/Notifiers/GridNotifiers.h24
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.cpp93
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.h6
3 files changed, 64 insertions, 59 deletions
diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h
index 317378dfa8b..df4788a0a1e 100644
--- a/src/server/game/Grids/Notifiers/GridNotifiers.h
+++ b/src/server/game/Grids/Notifiers/GridNotifiers.h
@@ -877,10 +877,13 @@ namespace Trinity
class AnyGroupedUnitInObjectRangeCheck
{
public:
- AnyGroupedUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range, bool raid) : _source(obj), _refUnit(funit), _range(range), _raid(raid) { }
+ AnyGroupedUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range, bool raid, bool playerOnly = false) : _source(obj), _refUnit(funit), _range(range), _raid(raid), _playerOnly(playerOnly) { }
bool operator()(Unit* u)
{
- if (G3D::fuzzyEq(_range, 0))
+ if (G3D::fuzzyEq(_range, 0.0f))
+ return false;
+
+ if (_playerOnly && u->GetTypeId() != TYPEID_PLAYER)
return false;
if (_raid)
@@ -899,6 +902,7 @@ namespace Trinity
Unit const* _refUnit;
float _range;
bool _raid;
+ bool _playerOnly;
};
class AnyUnitInObjectRangeCheck
@@ -945,16 +949,18 @@ namespace Trinity
class AnyAoETargetUnitInObjectRangeCheck
{
public:
- AnyAoETargetUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range)
- : i_obj(obj), i_funit(funit), _spellInfo(NULL), i_range(range)
+ AnyAoETargetUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range, SpellInfo const* spellInfo = nullptr)
+ : i_obj(obj), i_funit(funit), _spellInfo(spellInfo), i_range(range)
{
Unit const* check = i_funit;
Unit const* owner = i_funit->GetOwner();
if (owner)
check = owner;
i_targetForPlayer = (check->GetTypeId() == TYPEID_PLAYER);
- if (DynamicObject const* dynObj = i_obj->ToDynObject())
- _spellInfo = sSpellMgr->GetSpellInfo(dynObj->GetSpellId());
+
+ if (!_spellInfo)
+ if (DynamicObject const* dynObj = i_obj->ToDynObject())
+ _spellInfo = sSpellMgr->GetSpellInfo(dynObj->GetSpellId());
}
bool operator()(Unit* u)
{
@@ -962,10 +968,10 @@ namespace Trinity
if (u->GetTypeId() == TYPEID_UNIT && u->IsTotem())
return false;
- if (i_funit->_IsValidAttackTarget(u, _spellInfo, i_obj->GetTypeId() == TYPEID_DYNAMICOBJECT ? i_obj : NULL) && i_obj->IsWithinDistInMap(u, i_range))
- return true;
+ if (_spellInfo && _spellInfo->HasAttribute(SPELL_ATTR3_ONLY_TARGET_PLAYERS) && u->GetTypeId() != TYPEID_PLAYER)
+ return false;
- return false;
+ return i_funit->_IsValidAttackTarget(u, _spellInfo, i_obj->GetTypeId() == TYPEID_DYNAMICOBJECT ? i_obj : nullptr) && i_obj->IsWithinDistInMap(u, i_range);
}
private:
bool i_targetForPlayer;
diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp
index 2a6545520ae..a11f4e9b808 100644
--- a/src/server/game/Spells/Auras/SpellAuras.cpp
+++ b/src/server/game/Spells/Auras/SpellAuras.cpp
@@ -490,37 +490,36 @@ void Aura::UpdateTargetMap(Unit* caster, bool apply)
m_updateTargetMapInterval = UPDATE_TARGET_MAP_INTERVAL;
// fill up to date target list
- // target, effMask
- std::map<Unit*, uint8> targets;
-
+ // target, effMask
+ std::unordered_map<Unit*, uint8> targets;
FillTargetMap(targets, caster);
- UnitList targetsToRemove;
+ std::deque<Unit*> targetsToRemove;
// mark all auras as ready to remove
for (ApplicationMap::iterator appIter = m_applications.begin(); appIter != m_applications.end();++appIter)
{
- std::map<Unit*, uint8>::iterator existing = targets.find(appIter->second->GetTarget());
+ auto itr = targets.find(appIter->second->GetTarget());
// not found in current area - remove the aura
- if (existing == targets.end())
+ if (itr == targets.end())
targetsToRemove.push_back(appIter->second->GetTarget());
else
{
// needs readding - remove now, will be applied in next update cycle
// (dbcs do not have auras which apply on same type of targets but have different radius, so this is not really needed)
- if (appIter->second->GetEffectMask() != existing->second || !CanBeAppliedOn(existing->first))
+ if (appIter->second->GetEffectMask() != itr->second || !CanBeAppliedOn(itr->first))
targetsToRemove.push_back(appIter->second->GetTarget());
// nothing todo - aura already applied
// remove from auras to register list
- targets.erase(existing);
+ targets.erase(itr);
}
}
// register auras for units
- for (std::map<Unit*, uint8>::iterator itr = targets.begin(); itr!= targets.end();)
+ for (auto itr = targets.begin(); itr!= targets.end();)
{
// aura mustn't be already applied on target
- if (AuraApplication * aurApp = GetApplicationOfTarget(itr->first->GetGUID()))
+ if (AuraApplication* aurApp = GetApplicationOfTarget(itr->first->GetGUID()))
{
// the core created 2 different units with same guid
// this is a major failue, which i can't fix right now
@@ -530,7 +529,7 @@ void Aura::UpdateTargetMap(Unit* caster, bool apply)
if (aurApp->GetTarget() != itr->first)
{
// remove from auras to register list
- targets.erase(itr++);
+ itr = targets.erase(itr);
continue;
}
else
@@ -584,7 +583,7 @@ void Aura::UpdateTargetMap(Unit* caster, bool apply)
}
}
if (!addUnit)
- targets.erase(itr++);
+ itr = targets.erase(itr);
else
{
// owner has to be in world, or effect has to be applied to self
@@ -602,17 +601,17 @@ void Aura::UpdateTargetMap(Unit* caster, bool apply)
}
// remove auras from units no longer needing them
- for (UnitList::iterator itr = targetsToRemove.begin(); itr != targetsToRemove.end();++itr)
- if (AuraApplication * aurApp = GetApplicationOfTarget((*itr)->GetGUID()))
- (*itr)->_UnapplyAura(aurApp, AURA_REMOVE_BY_DEFAULT);
+ for (Unit* unit : targetsToRemove)
+ if (AuraApplication* aurApp = GetApplicationOfTarget(unit->GetGUID()))
+ unit->_UnapplyAura(aurApp, AURA_REMOVE_BY_DEFAULT);
if (!apply)
return;
// apply aura effects for units
- for (std::map<Unit*, uint8>::iterator itr = targets.begin(); itr!= targets.end();++itr)
+ for (auto itr = targets.begin(); itr!= targets.end(); ++itr)
{
- if (AuraApplication * aurApp = GetApplicationOfTarget(itr->first->GetGUID()))
+ if (AuraApplication* aurApp = GetApplicationOfTarget(itr->first->GetGUID()))
{
// owner has to be in world, or effect has to be applied to self
ASSERT((!GetOwner()->IsInWorld() && GetOwner() == itr->first) || GetOwner()->IsInMap(itr->first));
@@ -2449,18 +2448,17 @@ void UnitAura::Remove(AuraRemoveMode removeMode)
GetUnitOwner()->RemoveOwnedAura(this, removeMode);
}
-void UnitAura::FillTargetMap(std::map<Unit*, uint8> & targets, Unit* caster)
+void UnitAura::FillTargetMap(std::unordered_map<Unit*, uint8>& targets, Unit* caster)
{
for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
{
if (!HasEffect(effIndex))
continue;
- UnitList targetList;
+
+ std::deque<Unit*> units;
// non-area aura
if (GetSpellInfo()->Effects[effIndex].Effect == SPELL_EFFECT_APPLY_AURA)
- {
- targetList.push_back(GetUnitOwner());
- }
+ units.push_back(GetUnitOwner());
else
{
float radius = GetSpellInfo()->Effects[effIndex].CalcRadius(caster);
@@ -2472,48 +2470,48 @@ void UnitAura::FillTargetMap(std::map<Unit*, uint8> & targets, Unit* caster)
case SPELL_EFFECT_APPLY_AREA_AURA_PARTY:
case SPELL_EFFECT_APPLY_AREA_AURA_RAID:
{
- targetList.push_back(GetUnitOwner());
- Trinity::AnyGroupedUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius, GetSpellInfo()->Effects[effIndex].Effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID);
- Trinity::UnitListSearcher<Trinity::AnyGroupedUnitInObjectRangeCheck> searcher(GetUnitOwner(), targetList, u_check);
+ units.push_back(GetUnitOwner());
+ Trinity::AnyGroupedUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius, m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID, m_spellInfo->HasAttribute(SPELL_ATTR3_ONLY_TARGET_PLAYERS));
+ Trinity::UnitListSearcher<Trinity::AnyGroupedUnitInObjectRangeCheck> searcher(GetUnitOwner(), units, u_check);
GetUnitOwner()->VisitNearbyObject(radius, searcher);
break;
}
case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND:
{
- targetList.push_back(GetUnitOwner());
- Trinity::AnyFriendlyUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius);
- Trinity::UnitListSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(GetUnitOwner(), targetList, u_check);
+ units.push_back(GetUnitOwner());
+ Trinity::AnyFriendlyUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius, m_spellInfo->HasAttribute(SPELL_ATTR3_ONLY_TARGET_PLAYERS));
+ Trinity::UnitListSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(GetUnitOwner(), units, u_check);
GetUnitOwner()->VisitNearbyObject(radius, searcher);
break;
}
case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY:
{
- Trinity::AnyAoETargetUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius); // No GetCharmer in searcher
- Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck> searcher(GetUnitOwner(), targetList, u_check);
+ Trinity::AnyAoETargetUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius, m_spellInfo); // No GetCharmer in searcher
+ Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck> searcher(GetUnitOwner(), units, u_check);
GetUnitOwner()->VisitNearbyObject(radius, searcher);
break;
}
case SPELL_EFFECT_APPLY_AREA_AURA_PET:
- targetList.push_back(GetUnitOwner());
+ units.push_back(GetUnitOwner());
// no break
case SPELL_EFFECT_APPLY_AREA_AURA_OWNER:
{
if (Unit* owner = GetUnitOwner()->GetCharmerOrOwner())
if (GetUnitOwner()->IsWithinDistInMap(owner, radius))
- targetList.push_back(owner);
+ units.push_back(owner);
break;
}
}
}
}
- for (UnitList::iterator itr = targetList.begin(); itr!= targetList.end();++itr)
+ for (Unit* unit : units)
{
- std::map<Unit*, uint8>::iterator existing = targets.find(*itr);
- if (existing != targets.end())
- existing->second |= 1<<effIndex;
+ auto itr = targets.find(unit);
+ if (itr != targets.end())
+ itr->second |= 1 << effIndex;
else
- targets[*itr] = 1<<effIndex;
+ targets[unit] = 1 << effIndex;
}
}
}
@@ -2536,7 +2534,7 @@ void DynObjAura::Remove(AuraRemoveMode removeMode)
_Remove(removeMode);
}
-void DynObjAura::FillTargetMap(std::map<Unit*, uint8> & targets, Unit* /*caster*/)
+void DynObjAura::FillTargetMap(std::unordered_map<Unit*, uint8>& targets, Unit* /*caster*/)
{
Unit* dynObjOwnerCaster = GetDynobjOwner()->GetCaster();
float radius = GetDynobjOwner()->GetRadius();
@@ -2545,28 +2543,29 @@ void DynObjAura::FillTargetMap(std::map<Unit*, uint8> & targets, Unit* /*caster*
{
if (!HasEffect(effIndex))
continue;
- UnitList targetList;
+
+ std::deque<Unit*> units;
if (GetSpellInfo()->Effects[effIndex].TargetB.GetTarget() == TARGET_DEST_DYNOBJ_ALLY
|| GetSpellInfo()->Effects[effIndex].TargetB.GetTarget() == TARGET_UNIT_DEST_AREA_ALLY)
{
- Trinity::AnyFriendlyUnitInObjectRangeCheck u_check(GetDynobjOwner(), dynObjOwnerCaster, radius);
- Trinity::UnitListSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(GetDynobjOwner(), targetList, u_check);
+ Trinity::AnyFriendlyUnitInObjectRangeCheck u_check(GetDynobjOwner(), dynObjOwnerCaster, radius, m_spellInfo->HasAttribute(SPELL_ATTR3_ONLY_TARGET_PLAYERS));
+ Trinity::UnitListSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(GetDynobjOwner(), units, u_check);
GetDynobjOwner()->VisitNearbyObject(radius, searcher);
}
else
{
Trinity::AnyAoETargetUnitInObjectRangeCheck u_check(GetDynobjOwner(), dynObjOwnerCaster, radius);
- Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck> searcher(GetDynobjOwner(), targetList, u_check);
+ Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck> searcher(GetDynobjOwner(), units, u_check);
GetDynobjOwner()->VisitNearbyObject(radius, searcher);
}
- for (UnitList::iterator itr = targetList.begin(); itr!= targetList.end();++itr)
+ for (Unit* unit : units)
{
- std::map<Unit*, uint8>::iterator existing = targets.find(*itr);
- if (existing != targets.end())
- existing->second |= 1<<effIndex;
+ auto itr = targets.find(unit);
+ if (itr != targets.end())
+ itr->second |= 1 << effIndex;
else
- targets[*itr] = 1<<effIndex;
+ targets[unit] = 1 << effIndex;
}
}
}
diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h
index a526dd8e340..a6dd29f11d0 100644
--- a/src/server/game/Spells/Auras/SpellAuras.h
+++ b/src/server/game/Spells/Auras/SpellAuras.h
@@ -113,7 +113,7 @@ class TC_GAME_API Aura
void _Remove(AuraRemoveMode removeMode);
virtual void Remove(AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT) = 0;
- virtual void FillTargetMap(std::map<Unit*, uint8> & targets, Unit* caster) = 0;
+ virtual void FillTargetMap(std::unordered_map<Unit*, uint8>& targets, Unit* caster) = 0;
void UpdateTargetMap(Unit* caster, bool apply = true);
void _RegisterForTargets() {Unit* caster = GetCaster(); UpdateTargetMap(caster, false);}
@@ -283,7 +283,7 @@ class TC_GAME_API UnitAura : public Aura
void Remove(AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT) override;
- void FillTargetMap(std::map<Unit*, uint8> & targets, Unit* caster) override;
+ void FillTargetMap(std::unordered_map<Unit*, uint8>& targets, Unit* caster) override;
// Allow Apply Aura Handler to modify and access m_AuraDRGroup
void SetDiminishGroup(DiminishingGroup group) { m_AuraDRGroup = group; }
@@ -301,7 +301,7 @@ class TC_GAME_API DynObjAura : public Aura
public:
void Remove(AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT) override;
- void FillTargetMap(std::map<Unit*, uint8> & targets, Unit* caster) override;
+ void FillTargetMap(std::unordered_map<Unit*, uint8>& targets, Unit* caster) override;
};
class TC_GAME_API ChargeDropEvent : public BasicEvent