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.cpp110
1 files changed, 44 insertions, 66 deletions
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index 41d01772c50..d9aa5ffc2a1 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -380,6 +380,7 @@ Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 origi
m_glyphIndex = 0;
m_preCastSpell = 0;
m_triggeredByAuraSpell = NULL;
+ m_spellAura = NULL;
//Auto Shot & Shoot (wand)
m_autoRepeat = IsAutoRepeatRangedSpell(m_spellInfo);
@@ -938,6 +939,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
uint32 procAttacker = m_procAttacker;
uint32 procVictim = m_procVictim;
uint32 procEx = PROC_EX_NONE;
+ m_spellAura = NULL; // Set aura to null for every target-make sure that pointer is not used for unit without aura applied
if (missInfo==SPELL_MISS_NONE) // In case spell hit target, do all effect on that target
DoSpellHitOnUnit(unit, mask);
@@ -981,6 +983,9 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
if (m_canTrigger && missInfo != SPELL_MISS_REFLECT)
caster->ProcDamageAndSpell(unitTarget, procAttacker, procVictim, procEx, addhealth, m_attackType, m_spellInfo);
+ if (m_spellAura)
+ m_spellAura->SetProcDamage(addhealth);
+
int32 gain = unitTarget->ModifyHealth( int32(addhealth) );
unitTarget->getHostilRefManager().threatAssist(caster, float(gain) * 0.5f, m_spellInfo);
@@ -1007,6 +1012,9 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
if (m_canTrigger && missInfo != SPELL_MISS_REFLECT)
caster->ProcDamageAndSpell(unitTarget, procAttacker, procVictim, procEx, damageInfo.damage, m_attackType, m_spellInfo);
+ if (m_spellAura)
+ m_spellAura->SetProcDamage(damageInfo.damage);
+
caster->DealSpellDamage(&damageInfo, true);
// Judgement of Blood
@@ -1186,7 +1194,9 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
if( m_spellInfo->SpellFamilyName == SPELLFAMILY_PRIEST && (m_spellInfo->SpellFamilyFlags[1] & 0x000020))
m_caster->CastSpell(unit, 41637, true, NULL, NULL, m_originalCasterGUID);
}
- unit->AddAura(Aur);
+ // Set aura only when successfully applied
+ if (unit->AddAura(Aur))
+ m_spellAura = Aur;
}
t_effmask = effectMask& ~t_effmask;
for(uint32 effectNumber=0;effectNumber<3;effectNumber++)
@@ -1236,6 +1246,7 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
_duration = aur ? aur->GetAuraDuration() : -1;
}
triggeredAur->SetAuraDuration(_duration);
+ triggeredAur->SetPermanent(false);
}
}
}
@@ -2570,8 +2581,8 @@ void Spell::SendSpellCooldown()
return;
}
- // have infinity cooldown but set at aura apply
- if(m_spellInfo->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE)
+ // have infinity cooldown but set at aura apply // do not set cooldown for triggered spells (needed by reincarnation)
+ if(m_spellInfo->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE || m_IsTriggeredSpell)
return;
_player->AddSpellAndCategoryCooldowns(m_spellInfo,m_CastItem ? m_CastItem->GetEntry() : 0, this);
@@ -2813,6 +2824,10 @@ void Spell::SendSpellStart()
uint32 castFlags = CAST_FLAG_UNKNOWN1;
if(IsRangedSpell())
castFlags |= CAST_FLAG_AMMO;
+ if ((m_caster->GetTypeId() == TYPEID_PLAYER ||
+ (m_caster->GetTypeId() == TYPEID_UNIT && ((Creature*)m_caster)->isPet()))
+ && m_spellInfo->powerType != POWER_HEALTH )
+ castFlags |= CAST_FLAG_POWER_LEFT_SELF;
if(m_spellInfo->runeCostID)
castFlags |= CAST_FLAG_UNKNOWN10;
@@ -2833,23 +2848,8 @@ void Spell::SendSpellStart()
m_targets.write(&data);
- if ( castFlags & CAST_FLAG_UNKNOWN6 ) // predicted power?
- data << uint32(0);
-
- if ( castFlags & CAST_FLAG_UNKNOWN7 ) // rune cooldowns list
- {
- uint8 v1 = 0;//m_runesState;
- uint8 v2 = 0;//((Player*)m_caster)->GetRunesState();
- data << uint8(v1); // runes state before
- data << uint8(v2); // runes state after
- for(uint8 i = 0; i < MAX_RUNES; ++i)
- {
- uint8 m = (1 << i);
- if(m & v1) // usable before...
- if(!(m & v2)) // ...but on cooldown now...
- data << uint8(0); // some unknown byte (time?)
- }
- }
+ if(castFlags & CAST_FLAG_POWER_LEFT_SELF)
+ data << uint32(m_caster->GetPower((Powers)m_spellInfo->powerType));
if ( castFlags & CAST_FLAG_AMMO )
WriteAmmoToPacket(&data);
@@ -2870,11 +2870,14 @@ void Spell::SendSpellGo()
uint32 castFlags = CAST_FLAG_UNKNOWN3;
if(IsRangedSpell())
castFlags |= CAST_FLAG_AMMO; // arrows/bullets visual
+ if ((m_caster->GetTypeId() == TYPEID_PLAYER ||
+ (m_caster->GetTypeId() == TYPEID_UNIT && ((Creature*)m_caster)->isPet()))
+ && m_spellInfo->powerType != POWER_HEALTH )
+ castFlags |= CAST_FLAG_POWER_LEFT_SELF; // should only be sent to self, but the current messaging doesn't make that possible
if((m_caster->GetTypeId() == TYPEID_PLAYER) && (m_caster->getClass() == CLASS_DEATH_KNIGHT) && m_spellInfo->runeCostID)
{
castFlags |= CAST_FLAG_UNKNOWN10; // same as in SMSG_SPELL_START
- castFlags |= CAST_FLAG_UNKNOWN6; // makes cooldowns visible
castFlags |= CAST_FLAG_UNKNOWN7; // rune cooldowns list
}
@@ -2895,8 +2898,8 @@ void Spell::SendSpellGo()
m_targets.write(&data);
- if ( castFlags & CAST_FLAG_UNKNOWN6 ) // unknown wotlk, predicted power?
- data << uint32(0);
+ if(castFlags & CAST_FLAG_POWER_LEFT_SELF)
+ data << uint32(m_caster->GetPower((Powers)m_spellInfo->powerType));
if ( castFlags & CAST_FLAG_UNKNOWN7 ) // rune cooldowns list
{
@@ -3658,19 +3661,23 @@ SpellCastResult Spell::CheckCast(bool strict)
}
}
- // caster state requirements
- if(m_spellInfo->CasterAuraState && !m_caster->HasAuraState(AuraState(m_spellInfo->CasterAuraState), m_spellInfo, m_caster))
- return SPELL_FAILED_CASTER_AURASTATE;
- if(m_spellInfo->CasterAuraStateNot && m_caster->HasAuraState(AuraState(m_spellInfo->CasterAuraStateNot), m_spellInfo, m_caster))
- return SPELL_FAILED_CASTER_AURASTATE;
+ // caster state requirements
+ // not for triggered spells (needed by execute)
+ if (!m_IsTriggeredSpell)
+ {
+ if(m_spellInfo->CasterAuraState && !m_caster->HasAuraState(AuraState(m_spellInfo->CasterAuraState), m_spellInfo, m_caster))
+ return SPELL_FAILED_CASTER_AURASTATE;
+ if(m_spellInfo->CasterAuraStateNot && m_caster->HasAuraState(AuraState(m_spellInfo->CasterAuraStateNot), m_spellInfo, m_caster))
+ return SPELL_FAILED_CASTER_AURASTATE;
- if(m_spellInfo->casterAuraSpell && !m_caster->HasAura(m_spellInfo->casterAuraSpell))
- return SPELL_FAILED_CASTER_AURASTATE;
- if(m_spellInfo->excludeCasterAuraSpell && m_caster->HasAura(m_spellInfo->excludeCasterAuraSpell))
- return SPELL_FAILED_CASTER_AURASTATE;
+ if(m_spellInfo->casterAuraSpell && !m_caster->HasAura(m_spellInfo->casterAuraSpell))
+ return SPELL_FAILED_CASTER_AURASTATE;
+ if(m_spellInfo->excludeCasterAuraSpell && m_caster->HasAura(m_spellInfo->excludeCasterAuraSpell))
+ return SPELL_FAILED_CASTER_AURASTATE;
- if(reqCombat && m_caster->isInCombat() && IsNonCombatSpell(m_spellInfo))
- return SPELL_FAILED_AFFECTING_COMBAT;
+ if(reqCombat && m_caster->isInCombat() && IsNonCombatSpell(m_spellInfo))
+ return SPELL_FAILED_AFFECTING_COMBAT;
+ }
// cancel autorepeat spells if cast start when moving
// (not wand currently autorepeat cast delayed to moving stop anyway in spell update code)
@@ -3684,9 +3691,8 @@ SpellCastResult Spell::CheckCast(bool strict)
if(Unit *target = m_targets.getUnitTarget())
{
-
// target state requirements (not allowed state), apply to self also
- if(m_spellInfo->TargetAuraStateNot && target->HasAuraState(AuraState(m_spellInfo->TargetAuraStateNot), m_spellInfo, m_caster))
+ if(!m_IsTriggeredSpell && m_spellInfo->TargetAuraStateNot && target->HasAuraState(AuraState(m_spellInfo->TargetAuraStateNot), m_spellInfo, m_caster))
return SPELL_FAILED_TARGET_AURASTATE;
if(m_spellInfo->targetAuraSpell && !target->HasAura(m_spellInfo->targetAuraSpell))
@@ -3698,7 +3704,7 @@ SpellCastResult Spell::CheckCast(bool strict)
if(target != m_caster)
{
// target state requirements (apply to non-self only), to allow cast affects to self like Dirty Deeds
- if(m_spellInfo->TargetAuraState && !target->HasAuraState(AuraState(m_spellInfo->TargetAuraState), m_spellInfo, m_caster))
+ if(!m_IsTriggeredSpell && m_spellInfo->TargetAuraState && !target->HasAuraState(AuraState(m_spellInfo->TargetAuraState), m_spellInfo, m_caster))
return SPELL_FAILED_TARGET_AURASTATE;
// Not allow casting on flying player
@@ -4004,22 +4010,7 @@ SpellCastResult Spell::CheckCast(bool strict)
{
case SPELL_EFFECT_DUMMY:
{
- if(m_spellInfo->SpellIconID == 1648) // Execute
- {
- if(!m_targets.getUnitTarget())
- return SPELL_FAILED_BAD_TARGETS;
- if (m_targets.getUnitTarget()->GetHealth() > m_targets.getUnitTarget()->GetMaxHealth()*0.2)
- {
- bool found = false;
- Unit::AuraEffectList const& stateAuras = m_caster->GetAurasByType(SPELL_AURA_ABILITY_IGNORE_AURASTATE);
- for(Unit::AuraEffectList::const_iterator j = stateAuras.begin();j != stateAuras.end(); ++j)
- if((*j)->isAffectedOnSpell(m_spellInfo))
- found=true;
- if (!found)
- return SPELL_FAILED_BAD_TARGETS;
- }
- }
- else if (m_spellInfo->Id == 51582) // Rocket Boots Engaged
+ if (m_spellInfo->Id == 51582) // Rocket Boots Engaged
{
if(m_caster->IsInWater())
return SPELL_FAILED_ONLY_ABOVEWATER;
@@ -4039,19 +4030,6 @@ SpellCastResult Spell::CheckCast(bool strict)
}
break;
}
- case SPELL_EFFECT_SCHOOL_DAMAGE:
- {
- // Hammer of Wrath
- if(m_spellInfo->SpellVisual[0] == 7250)
- {
- if (!m_targets.getUnitTarget())
- return SPELL_FAILED_BAD_IMPLICIT_TARGETS;
-
- if(m_targets.getUnitTarget()->GetHealth() > m_targets.getUnitTarget()->GetMaxHealth()*0.2)
- return SPELL_FAILED_BAD_TARGETS;
- }
- break;
- }
case SPELL_EFFECT_LEARN_SPELL:
{
if (m_caster->GetTypeId() != TYPEID_PLAYER)