aboutsummaryrefslogtreecommitdiff
path: root/src/game/Unit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/Unit.cpp')
-rw-r--r--src/game/Unit.cpp122
1 files changed, 84 insertions, 38 deletions
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index efa85d137a4..f2ae30ffee6 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -1023,66 +1023,75 @@ void Unit::CastSpell(Unit* Victim,SpellEntry const *spellInfo, bool triggered, I
spell->prepare(&targets, triggeredByAura);
}
-void Unit::CastCustomSpell(Unit* Victim,uint32 spellId, int32 const* bp0, int32 const* bp1, int32 const* bp2, bool triggered, Item *castItem, AuraEffect* triggeredByAura, uint64 originalCaster)
+void Unit::CastCustomSpell(Unit* target, uint32 spellId, int32 const* bp0, int32 const* bp1, int32 const* bp2, bool triggered, Item *castItem, AuraEffect* triggeredByAura, uint64 originalCaster)
{
- SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId );
-
- if(!spellInfo)
- {
- sLog.outError("CastCustomSpell: unknown spell id %i", spellId);
- return;
- }
+ CustomSpellValues values;
+ if(bp0) values.AddSpellMod(SPELLVALUE_BASE_POINT0, *bp0);
+ if(bp1) values.AddSpellMod(SPELLVALUE_BASE_POINT1, *bp1);
+ if(bp2) values.AddSpellMod(SPELLVALUE_BASE_POINT2, *bp2);
+ CastCustomSpell(spellId, values, target, triggered, castItem, triggeredByAura, originalCaster);
+}
- CastCustomSpell(Victim,spellInfo,bp0,bp1,bp2,triggered,castItem,triggeredByAura, originalCaster);
+void Unit::CastCustomSpell(uint32 spellId, SpellValueMod mod, uint32 value, Unit* target, bool triggered, Item *castItem, AuraEffect* triggeredByAura, uint64 originalCaster)
+{
+ CustomSpellValues values;
+ values.AddSpellMod(mod, value);
+ CastCustomSpell(spellId, values, target, triggered, castItem, triggeredByAura, originalCaster);
}
-void Unit::CastCustomSpell(Unit* Victim,SpellEntry const *spellInfo, int32 const* bp0, int32 const* bp1, int32 const* bp2, bool triggered, Item *castItem, AuraEffect* triggeredByAura, uint64 originalCaster)
+void Unit::CastCustomSpell(uint32 spellId, CustomSpellValues const &value, Unit* Victim, bool triggered, Item *castItem, AuraEffect* triggeredByAura, uint64 originalCaster)
{
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId );
if(!spellInfo)
{
- sLog.outError("CastCustomSpell: unknown spell");
+ sLog.outError("CastSpell: unknown spell id %i by caster: %s %u)", spellId,(GetTypeId()==TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"),(GetTypeId()==TYPEID_PLAYER ? GetGUIDLow() : GetEntry()));
return;
}
SpellCastTargets targets;
uint32 targetMask = spellInfo->Targets;
- targets.setUnitTarget(Victim);
- /*if(targetMask & (TARGET_FLAG_UNIT|TARGET_FLAG_UNK2))
+
+ //check unit target
+ for(int i = 0; i < 3; ++i)
{
- if(!Victim)
+ if(spellmgr.SpellTargetType[spellInfo->EffectImplicitTargetA[i]] == TARGET_TYPE_UNIT_TARGET)
{
- sLog.outError("CastCustomSpell: spell id %i by caster: %s %u) does not have unit target", spellInfo->Id,(GetTypeId()==TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"),(GetTypeId()==TYPEID_PLAYER ? GetGUIDLow() : GetEntry()));
- return;
+ if(!Victim)
+ {
+ sLog.outError("CastSpell: spell id %i by caster: %s %u) does not have unit target", spellInfo->Id,(GetTypeId()==TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"),(GetTypeId()==TYPEID_PLAYER ? GetGUIDLow() : GetEntry()));
+ return;
+ }
+ else
+ break;
}
- }*/
+ }
+ targets.setUnitTarget(Victim);
+
+ //check destination
if(targetMask & (TARGET_FLAG_SOURCE_LOCATION|TARGET_FLAG_DEST_LOCATION))
{
if(!Victim)
{
- sLog.outError("CastCustomSpell: spell id %i by caster: %s %u) does not have destination", spellInfo->Id,(GetTypeId()==TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"),(GetTypeId()==TYPEID_PLAYER ? GetGUIDLow() : GetEntry()));
+ sLog.outError("CastSpell: spell id %i by caster: %s %u) does not have destination", spellInfo->Id,(GetTypeId()==TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"),(GetTypeId()==TYPEID_PLAYER ? GetGUIDLow() : GetEntry()));
return;
}
targets.setDestination(Victim);
}
- if (castItem)
- DEBUG_LOG("WORLD: cast Item spellId - %i", spellInfo->Id);
-
if(!originalCaster && triggeredByAura)
originalCaster = triggeredByAura->GetCasterGUID();
- Spell *spell = new Spell(this, spellInfo, triggered, originalCaster);
-
- if(bp0)
- spell->m_currentBasePoints[0] = *bp0-int32(spellInfo->EffectBaseDice[0]);
+ Spell *spell = new Spell(this, spellInfo, triggered, originalCaster );
- if(bp1)
- spell->m_currentBasePoints[1] = *bp1-int32(spellInfo->EffectBaseDice[1]);
+ if(castItem)
+ {
+ DEBUG_LOG("WORLD: cast Item spellId - %i", spellInfo->Id);
+ spell->m_CastItem = castItem;
+ }
- if(bp2)
- spell->m_currentBasePoints[2] = *bp2-int32(spellInfo->EffectBaseDice[2]);
+ for(CustomSpellValues::const_iterator itr = value.begin(); itr != value.end(); ++itr)
+ spell->SetSpellValue(itr->first, itr->second);
- spell->m_CastItem = castItem;
spell->prepare(&targets, triggeredByAura);
}
@@ -2257,6 +2266,9 @@ void Unit::AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType, bool ex
return;
}
+ // attack can be redirected to another target
+ pVictim = SelectMagnetTarget(pVictim);
+
CalcDamageInfo damageInfo;
CalculateMeleeDamage(pVictim, 0, &damageInfo, attType);
// Send log damage message to client
@@ -6285,8 +6297,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
{
uint32 spell = (*itr)->GetSpellProto()->EffectTriggerSpell[(*itr)->GetEffIndex()];
CastSpell(this, spell, true, castItem, triggeredByAura);
- if ((*itr)->GetParentAura()->DropAuraCharge())
- RemoveAurasDueToSpell((*itr)->GetId());
+ (*itr)->GetParentAura()->DropAuraCharge();
return true;
}
}
@@ -6370,8 +6381,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
return false;
}
CastSpell(this, spell, true, castItem, triggeredByAura);
- if ((*itr)->GetParentAura()->DropAuraCharge())
- RemoveAurasDueToSpell((*itr)->GetId());
+ (*itr)->GetParentAura()->DropAuraCharge();
return true;
}
}
@@ -8166,6 +8176,44 @@ void Unit::SetCharm(Unit* charm, bool apply)
}
}
+Unit* Unit::SelectMagnetTarget(Unit *victim, SpellEntry const *spellInfo)
+{
+ if(!victim)
+ return NULL;
+
+ // Magic case
+ if(spellInfo && (spellInfo->DmgClass == SPELL_DAMAGE_CLASS_NONE || spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MAGIC))
+ {
+ //I am not sure if this should be redirected.
+ if(spellInfo->DmgClass == SPELL_DAMAGE_CLASS_NONE)
+ return victim;
+
+ Unit::AuraEffectList const& magnetAuras = victim->GetAurasByType(SPELL_AURA_SPELL_MAGNET);
+ for(Unit::AuraEffectList::const_iterator itr = magnetAuras.begin(); itr != magnetAuras.end(); ++itr)
+ if(Unit* magnet = (*itr)->GetCaster())
+ if(magnet->isAlive())
+ {
+ (*itr)->GetParentAura()->DropAuraCharge();
+ return magnet;
+ }
+ }
+ // Melee && ranged case
+ else
+ {
+ AuraEffectList const& hitTriggerAuras = victim->GetAurasByType(SPELL_AURA_ADD_CASTER_HIT_TRIGGER);
+ for(AuraEffectList::const_iterator i = hitTriggerAuras.begin(); i != hitTriggerAuras.end(); ++i)
+ if(Unit* magnet = (*i)->GetCaster())
+ if(magnet->isAlive() && magnet->IsWithinLOSInMap(this))
+ if(roll_chance_i((*i)->GetAmount()))
+ {
+ (*i)->GetParentAura()->DropAuraCharge();
+ return magnet;
+ }
+ }
+
+ return victim;
+}
+
Unit* Unit::GetFirstControlled() const
{
//Sequence: charmed, pet, other guardians
@@ -8774,8 +8822,7 @@ bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolM
// Fingers of Frost
// TODO: Change this code to less hacky
if (Aura * aur = GetAura(44544))
- if (aur->DropAuraCharge())
- RemoveAura(aur);
+ aur->DropAuraCharge();
break;
case 7917: // Glyph of Shadowburn
if (pVictim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, spellProto, this))
@@ -11759,8 +11806,7 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag
// Remove charge (aura can be removed by triggers)
if(useCharges && takeCharges)
{
- if (i->aura->DropAuraCharge())
- RemoveAura(i->aura);
+ i->aura->DropAuraCharge();
}
}
}