aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/game/Spell.cpp36
-rw-r--r--src/game/Unit.cpp65
-rw-r--r--src/game/Unit.h3
3 files changed, 91 insertions, 13 deletions
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index 8752bf41b41..5d7e57d2c34 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -4464,19 +4464,34 @@ SpellCastResult Spell::CheckCast(bool strict)
return SPELL_FAILED_LINE_OF_SIGHT;
}
- else if (m_caster->GetTypeId() == TYPEID_PLAYER) // Target - is player caster
+ else if (m_caster == target)
{
- // Additional check for some spells
- // If 0 spell effect empty - client not send target data (need use selection)
- // TODO: check it on next client version
- if (m_targets.m_targetMask == TARGET_FLAG_SELF &&
- m_spellInfo->EffectImplicitTargetA[1] == TARGET_UNIT_TARGET_ENEMY)
+
+ if (m_caster->GetTypeId() == TYPEID_PLAYER) // Target - is player caster
{
- if (target = m_caster->GetUnit(*m_caster, ((Player *)m_caster)->GetSelection()))
- m_targets.setUnitTarget(target);
- else
- return SPELL_FAILED_BAD_TARGETS;
+ // Additional check for some spells
+ // If 0 spell effect empty - client not send target data (need use selection)
+ // TODO: check it on next client version
+ if (m_targets.m_targetMask == TARGET_FLAG_SELF &&
+ m_spellInfo->EffectImplicitTargetA[1] == TARGET_UNIT_TARGET_ENEMY)
+ {
+ if (target = m_caster->GetUnit(*m_caster, ((Player *)m_caster)->GetSelection()))
+ m_targets.setUnitTarget(target);
+ else
+ return SPELL_FAILED_BAD_TARGETS;
+ }
}
+
+ // Some special spells with non-caster only mode
+
+ // Fire Shield
+ if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK &&
+ m_spellInfo->SpellIconID == 16)
+ return SPELL_FAILED_BAD_TARGETS;
+
+ // Focus Magic (main spell)
+ if (m_spellInfo->Id == 54646)
+ return SPELL_FAILED_BAD_TARGETS;
}
// check pet presents
@@ -6631,7 +6646,6 @@ void Spell::SelectTrajTargets()
}
#define CHECK_DIST {\
- //sLog.outError("Spell::SelectTrajTargets: dist %f, height %f.", dist, height);
if(dist < objDist2d + size && dist > objDist2d - size)\
{ bestDist = dist; break; }\
}
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index 6c47b56900e..d5c2068ea6c 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -4827,6 +4827,68 @@ bool Unit::HandleHasteAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
return true;
}
+bool Unit::HandleSpellCritChanceAuraProc(Unit *pVictim, uint32 /*damage*/, AuraEffect* triggeredByAura, SpellEntry const * /*procSpell*/, uint32 /*procFlag*/, uint32 /*procEx*/, uint32 cooldown)
+{
+ SpellEntry const *triggeredByAuraSpell = triggeredByAura->GetSpellProto();
+
+ Item* castItem = triggeredByAura->GetParentAura()->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER
+ ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetParentAura()->GetCastItemGUID()) : NULL;
+
+ uint32 triggered_spell_id = 0;
+ Unit* target = pVictim;
+ int32 basepoints0 = 0;
+
+ switch(triggeredByAuraSpell->SpellFamilyName)
+ {
+ case SPELLFAMILY_MAGE:
+ {
+ switch(triggeredByAuraSpell->Id)
+ {
+ // Focus Magic
+ case 54646:
+ {
+ Unit* caster = triggeredByAura->GetCaster();
+ if(!caster)
+ return false;
+
+ triggered_spell_id = 54648;
+ target = caster;
+ break;
+ }
+ }
+ }
+ }
+
+ // processed charge only counting case
+ if(!triggered_spell_id)
+ return true;
+
+ SpellEntry const* triggerEntry = sSpellStore.LookupEntry(triggered_spell_id);
+
+ if(!triggerEntry)
+ {
+ sLog.outError("Unit::HandleHasteAuraProc: Spell %u have not existed triggered spell %u",triggeredByAuraSpell->Id,triggered_spell_id);
+ return false;
+ }
+
+ // default case
+ if(!target || target!=this && !target->isAlive())
+ return false;
+
+ if( cooldown && GetTypeId()==TYPEID_PLAYER && ((Player*)this)->HasSpellCooldown(triggered_spell_id))
+ return false;
+
+ if(basepoints0)
+ CastCustomSpell(target,triggered_spell_id,&basepoints0,NULL,NULL,true,castItem,triggeredByAura);
+ else
+ CastSpell(target,triggered_spell_id,true,castItem,triggeredByAura);
+
+ if( cooldown && GetTypeId()==TYPEID_PLAYER )
+ ((Player*)this)->AddSpellCooldown(triggered_spell_id,0,time(NULL) + cooldown);
+
+ return true;
+}
+
bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const * procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown)
{
SpellEntry const *dummySpell = triggeredByAura->GetSpellProto ();
@@ -12860,7 +12922,8 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag
takeCharges=true;
break;
case SPELL_AURA_MOD_SPELL_CRIT_CHANCE:
- if (procSpell)
+ sLog.outDebug("ProcDamageAndSpell: casting spell id %u (triggered by %s spell crit chance aura of spell %u)", spellInfo->Id,(isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
+ if (procSpell && HandleSpellCritChanceAuraProc(pTarget, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
takeCharges=true;
break;
// CC Auras which use their amount amount to drop
diff --git a/src/game/Unit.h b/src/game/Unit.h
index 523b4c19f7a..1da17785c8f 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -1945,10 +1945,11 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
private:
bool IsTriggeredAtSpellProcEvent(Unit *pVictim, Aura* aura, SpellEntry const * procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const *& spellProcEvent );
bool HandleDummyAuraProc( Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
+ bool HandleHasteAuraProc( Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
+ bool HandleSpellCritChanceAuraProc( Unit *pVictim, uint32 damage, AuraEffect* triggredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
bool HandleObsModEnergyAuraProc( Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
bool HandleModDamagePctTakenAuraProc(Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
bool HandleAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const * procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, bool * handled);
- bool HandleHasteAuraProc( Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
bool HandleProcTriggerSpell(Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
bool HandleOverrideClassScriptAuraProc(Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const *procSpell, uint32 cooldown);
bool HandleAuraRaidProcFromChargeWithValue(AuraEffect* triggeredByAura);