diff options
Diffstat (limited to 'src/server/game/Spells/Spell.cpp')
-rw-r--r-- | src/server/game/Spells/Spell.cpp | 85 |
1 files changed, 52 insertions, 33 deletions
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index a03788cdda5..85388dc5821 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -2626,11 +2626,24 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask) } // Now Reduce spell duration using data received at spell hit + // check whatever effects we're going to apply, diminishing returns only apply to negative aura effects + bool positive = true; + if (m_originalCaster == unit || !m_originalCaster->IsFriendlyTo(unit)) + { + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + { + if ((effectMask & (1 << i)) && !m_spellInfo->IsPositiveEffect(i)) + { + positive = false; + break; + } + } + } + int32 duration = m_spellAura->GetMaxDuration(); - float diminishMod = unit->ApplyDiminishingToDuration(m_spellInfo, duration, m_originalCaster, diminishLevel); // unit is immune to aura if it was diminished to 0 duration - if (diminishMod == 0.0f) + if (!positive && !unit->ApplyDiminishingToDuration(m_spellInfo, duration, m_originalCaster, diminishLevel)) { m_spellAura->Remove(); bool found = false; @@ -2642,11 +2655,7 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask) } else { - ((UnitAura*)m_spellAura)->SetDiminishGroup(diminishGroup); - - bool positive = m_spellAura->GetSpellInfo()->IsPositive(); - if (AuraApplication* aurApp = m_spellAura->GetApplicationOfTarget(m_originalCaster->GetGUID())) - positive = aurApp->IsPositive(); + static_cast<UnitAura*>(m_spellAura)->SetDiminishGroup(diminishGroup); duration = m_originalCaster->ModSpellDuration(m_spellInfo, unit, duration, positive, effectMask); @@ -2944,15 +2953,6 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggered else m_casttime = m_spellInfo->CalcCastTime(m_caster->getLevel(), this); - if (m_caster->GetTypeId() == TYPEID_UNIT && !m_caster->HasUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED)) // _UNIT actually means creature. for some reason. - if (!(m_spellInfo->IsNextMeleeSwingSpell() || IsAutoRepeat() || (_triggeredCastFlags & TRIGGERED_IGNORE_SET_FACING))) - { - if (m_targets.GetObjectTarget() && m_caster != m_targets.GetObjectTarget()) - m_caster->ToCreature()->FocusTarget(this, m_targets.GetObjectTarget()); - else if (m_spellInfo->HasAttribute(SPELL_ATTR5_DONT_TURN_DURING_CAST)) - m_caster->ToCreature()->FocusTarget(this, nullptr); - } - // don't allow channeled spells / spells with cast time to be cast while moving // exception are only channeled spells that have no casttime and SPELL_ATTR5_CAN_CHANNEL_WHEN_MOVING // (even if they are interrupted on moving, spells with almost immediate effect get to have their effect processed before movement interrupter kicks in) @@ -2969,6 +2969,18 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggered } } + // focus if not controlled creature + if (m_caster->GetTypeId() == TYPEID_UNIT && !m_caster->HasUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED)) + { + if (!(m_spellInfo->IsNextMeleeSwingSpell() || IsAutoRepeat() || (_triggeredCastFlags & TRIGGERED_IGNORE_SET_FACING))) + { + if (m_targets.GetObjectTarget() && m_caster != m_targets.GetObjectTarget()) + m_caster->ToCreature()->FocusTarget(this, m_targets.GetObjectTarget()); + else if (m_spellInfo->HasAttribute(SPELL_ATTR5_DONT_TURN_DURING_CAST)) + m_caster->ToCreature()->FocusTarget(this, nullptr); + } + } + // set timer base at cast time ReSetTimer(); @@ -3116,11 +3128,12 @@ void Spell::_cast(bool skipCheck) m_caster->SetInFront(m_targets.GetObjectTarget()); // Should this be done for original caster? - if (m_caster->GetTypeId() == TYPEID_PLAYER) + Player* modOwner = m_caster->GetSpellModOwner(); + if (modOwner) { // Set spell which will drop charges for triggered cast spells // if not successfully cast, will be remove in finish(false) - m_caster->ToPlayer()->SetSpellModTakingSpell(this, true); + modOwner->SetSpellModTakingSpell(this, true); } CallScriptBeforeCastHandlers(); @@ -3135,8 +3148,8 @@ void Spell::_cast(bool skipCheck) SendCastResult(castResult, ¶m1, ¶m2); SendInterrupted(0); - if (m_caster->GetTypeId() == TYPEID_PLAYER) - m_caster->ToPlayer()->SetSpellModTakingSpell(this, false); + if (modOwner) + modOwner->SetSpellModTakingSpell(this, false); finish(false); SetExecutedCurrently(false); @@ -3147,9 +3160,9 @@ void Spell::_cast(bool skipCheck) // if trade not complete then remember it in trade data if (m_targets.GetTargetMask() & TARGET_FLAG_TRADE_ITEM) { - if (m_caster->GetTypeId() == TYPEID_PLAYER) + if (modOwner) { - if (TradeData* my_trade = m_caster->ToPlayer()->GetTradeData()) + if (TradeData* my_trade = modOwner->GetTradeData()) { if (!my_trade->IsInAcceptProcess()) { @@ -3158,7 +3171,7 @@ void Spell::_cast(bool skipCheck) SendCastResult(SPELL_FAILED_DONT_REPORT); SendInterrupted(0); - m_caster->ToPlayer()->SetSpellModTakingSpell(this, false); + modOwner->SetSpellModTakingSpell(this, false); finish(false); SetExecutedCurrently(false); @@ -3275,12 +3288,12 @@ void Spell::_cast(bool skipCheck) m_caster->CastSpell(m_targets.GetUnitTarget() ? m_targets.GetUnitTarget() : m_caster, *i, true); } - if (m_caster->GetTypeId() == TYPEID_PLAYER) + if (modOwner) { - m_caster->ToPlayer()->SetSpellModTakingSpell(this, false); + modOwner->SetSpellModTakingSpell(this, false); //Clear spell cooldowns after every spell is cast if .cheat cooldown is enabled. - if (m_caster->ToPlayer()->GetCommandStatus(CHEAT_COOLDOWN)) + if (modOwner->GetCommandStatus(CHEAT_COOLDOWN)) { m_caster->GetSpellHistory()->ResetCooldown(m_spellInfo->Id, true); m_caster->GetSpellHistory()->RestoreCharge(m_spellInfo->ChargeCategoryId); @@ -3289,9 +3302,6 @@ void Spell::_cast(bool skipCheck) SetExecutedCurrently(false); - if (Creature* creatureCaster = m_caster->ToCreature()) - creatureCaster->ReleaseFocus(this); - if (!m_originalCaster) return; @@ -3411,8 +3421,9 @@ uint64 Spell::handle_delayed(uint64 t_offset) if (single_missile && !t_offset) return m_delayMoment; - if (m_caster->GetTypeId() == TYPEID_PLAYER) - m_caster->ToPlayer()->SetSpellModTakingSpell(this, true); + Player* modOwner = m_caster->GetSpellModOwner(); + if (modOwner) + modOwner->SetSpellModTakingSpell(this, true); PrepareTargetProcessing(); @@ -3451,8 +3462,8 @@ uint64 Spell::handle_delayed(uint64 t_offset) FinishTargetProcessing(); - if (m_caster->GetTypeId() == TYPEID_PLAYER) - m_caster->ToPlayer()->SetSpellModTakingSpell(this, false); + if (modOwner) + modOwner->SetSpellModTakingSpell(this, false); // All targets passed - need finish phase if (next_time == 0) @@ -4449,8 +4460,16 @@ void Spell::SendChannelStart(uint32 duration) m_timer = duration; for (TargetInfo const& target : m_UniqueTargetInfo) + { m_caster->AddChannelObject(target.targetGUID); + if (m_UniqueTargetInfo.size() == 1 && m_UniqueGOTargetInfo.empty()) + if(target.targetGUID != m_caster->GetGUID()) + if (Creature* creatureCaster = m_caster->ToCreature()) + if (!creatureCaster->IsFocusing(this)) + creatureCaster->FocusTarget(this, ObjectAccessor::GetWorldObject(*creatureCaster, target.targetGUID)); + } + for (GOTargetInfo const& target : m_UniqueGOTargetInfo) m_caster->AddChannelObject(target.targetGUID); |