aboutsummaryrefslogtreecommitdiff
path: root/src/game/Spell.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/Spell.cpp')
-rw-r--r--src/game/Spell.cpp94
1 files changed, 54 insertions, 40 deletions
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index 8a5585aad21..78809841e3a 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -286,8 +286,6 @@ Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 origi
m_caster = Caster;
m_selfContainer = NULL;
m_triggeringContainer = triggeringContainer;
- m_magnetPair.first = false;
- m_magnetPair.second = NULL;
m_referencedFromCurrentSpell = false;
m_executedCurrently = false;
m_delayAtDamageCount = 0;
@@ -1037,6 +1035,12 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
if (target->reflectResult == SPELL_MISS_NONE) // If reflected spell hit caster -> do all effect on him
DoSpellHitOnUnit(m_caster, mask);
}
+ else if (missInfo == SPELL_MISS_KILL)
+ {
+ // remove spell_magnet aura after first spell redirect and destroy target if its totem
+ if(unit->GetTypeId() == TYPEID_UNIT && ((Creature*)unit)->isTotem())
+ unit->Kill(unit);
+ }
else //TODO: This is a hack. need fix
{
uint32 tempMask = 0;
@@ -1169,14 +1173,6 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
if(!unit || !effectMask)
return;
- // remove spell_magnet aura after first spell redirect and destroy target if its totem
- if(m_magnetPair.first && m_magnetPair.second && m_magnetPair.second == unit)
- {
- if(unit->GetTypeId() == TYPEID_UNIT && ((Creature*)unit)->isTotem())
- unit->DealDamage(unit,unit->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
- return;
- }
-
// Recheck immune (only for delayed spells)
if( m_spellInfo->speed &&
!(m_spellInfo->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY)
@@ -1199,8 +1195,7 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
}
unit->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_HITBYSPELL);
- //TODO: find a better way to judge CC auras
- if(m_spellInfo->Attributes & SPELL_ATTR_BREAKABLE_BY_DAMAGE)
+ if(spellmgr.GetSpellCustomAttr(m_spellInfo->Id) & SPELL_ATTR_CU_AURA_CC)
unit->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_CC);
}
else
@@ -1475,7 +1470,8 @@ void Spell::SearchAreaTarget(std::list<Unit*> &TagUnitMap, float radius, const u
y = m_caster->GetPositionY();
}
- CellPair p(Trinity::ComputeCellPair(x, y));
+ float x_off, y_off;
+ CellPair p(Trinity::ComputeCellPair(x, y, x_off, y_off));
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
@@ -1486,12 +1482,12 @@ void Spell::SearchAreaTarget(std::list<Unit*> &TagUnitMap, float radius, const u
//if(TargetType != SPELL_TARGETS_ENTRY)
{
TypeContainerVisitor<Trinity::SpellNotifierCreatureAndPlayer, WorldTypeMapContainer > world_object_notifier(notifier);
- cell_lock->Visit(cell_lock, world_object_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster));
+ cell_lock->Visit(cell_lock, world_object_notifier, *m_caster->GetMap(), radius, x_off, y_off);
}
if(!(m_spellInfo->AttributesEx3 & SPELL_ATTR_EX3_PLAYERS_ONLY))
{
TypeContainerVisitor<Trinity::SpellNotifierCreatureAndPlayer, GridTypeMapContainer > grid_object_notifier(notifier);
- cell_lock->Visit(cell_lock, grid_object_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster));
+ cell_lock->Visit(cell_lock, grid_object_notifier, *m_caster->GetMap(), radius, x_off, y_off);
}
}
@@ -4501,26 +4497,8 @@ int16 Spell::PetCanCast(Unit* target)
if(!_target->isAlive())
return SPELL_FAILED_BAD_TARGETS;
- if(IsPositiveSpell(m_spellInfo->Id))
- {
- if(m_caster->IsHostileTo(_target))
- return SPELL_FAILED_BAD_TARGETS;
- }
- else
- {
- bool duelvsplayertar = false;
- for(int j=0;j<3;j++)
- {
- //TARGET_DUELVSPLAYER is positive AND negative
- duelvsplayertar |= (m_spellInfo->EffectImplicitTargetA[j] == TARGET_DUELVSPLAYER);
- }
- // AoE spells have the caster as their target
- // AOE spells should not have target
- if(m_caster->IsFriendlyTo(target) /*&& m_caster != target*/ && !duelvsplayertar)
- {
- return SPELL_FAILED_BAD_TARGETS;
- }
- }
+ if(!IsValidSingleTargetSpell(_target))
+ return SPELL_FAILED_BAD_TARGETS;
}
//cooldown
if(((Creature*)m_caster)->HasSpellCooldown(m_spellInfo->Id))
@@ -5311,7 +5289,7 @@ CurrentSpellTypes Spell::GetCurrentContainer()
bool Spell::CheckTarget( Unit* target, uint32 eff, bool hitPhase )
{
// Check targets for creature type mask and remove not appropriate (skip explicit self target case, maybe need other explicit targets)
- if(m_spellInfo->EffectImplicitTargetA[eff]!=TARGET_SELF && !m_magnetPair.first)
+ if(m_spellInfo->EffectImplicitTargetA[eff]!=TARGET_SELF)
{
if (!CheckTargetCreatureType(target))
return false;
@@ -5392,14 +5370,21 @@ Unit* Spell::SelectMagnetTarget()
{
if(Unit* magnet = (*itr)->GetCaster())
{
- if((*itr)->m_procCharges>0 && magnet->IsWithinLOSInMap(m_caster))
+ if((*itr)->m_procCharges>0)
{
(*itr)->SetAuraProcCharges((*itr)->m_procCharges-1);
- m_magnetPair.first = true;
- m_magnetPair.second = magnet;
-
target = magnet;
m_targets.setUnitTarget(target);
+ AddUnitTarget(target, 0);
+ uint64 targetGUID = target->GetGUID();
+ for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit)
+ {
+ if (targetGUID == ihit->targetGUID) // Found in list
+ {
+ (*ihit).missCondition = SPELL_MISS_KILL;
+ break;
+ }
+ }
break;
}
}
@@ -5551,3 +5536,32 @@ bool SpellEvent::IsDeletable() const
{
return m_Spell->IsDeletable();
}
+
+bool Spell::IsValidSingleTargetEffect(Unit const* target, Targets type) const
+{
+ switch(type)
+ {
+ case TARGET_UNIT_TARGET_ENEMY:
+ return !m_caster->IsFriendlyTo(target);
+ case TARGET_UNIT_TARGET_ALLY:
+ return m_caster->IsFriendlyTo(target);
+ case TARGET_UNIT_TARGET_PARTY:
+ return m_caster->IsInPartyWith(target);
+ case TARGET_UNIT_TARGET_RAID:
+ return m_caster->IsInRaidWith(target);
+ }
+ return true;
+}
+
+bool Spell::IsValidSingleTargetSpell(Unit const* target) const
+{
+ for(int i = 0; i < 3; ++i)
+ {
+ if(!IsValidSingleTargetEffect(target, Targets(m_spellInfo->EffectImplicitTargetA[i])))
+ return false;
+ // Need to check B?
+ //if(!IsValidSingleTargetEffect(m_spellInfo->EffectImplicitTargetB[i], target)
+ // return false;
+ }
+ return true;
+} \ No newline at end of file