diff options
| author | treeston <treeston.mmoc@gmail.com> | 2016-01-13 18:38:54 +0100 |
|---|---|---|
| committer | treeston <treeston.mmoc@gmail.com> | 2016-01-13 18:38:54 +0100 |
| commit | 233297c5c8619af96e2aab4fa5ef6d205b5dc18a (patch) | |
| tree | a1a6f2275592e7639b17b71842cd7aaf90e1455d /src/server/game/Spells/Spell.cpp | |
| parent | 5b8b8c653039ec2add0b3a66468abb85e6f35054 (diff) | |
| parent | f481ae1048aac32ba3a40491f0304d0317234295 (diff) | |
Merge branch '3.3.5-spellfacing' into 3.3.5-base (PR #15641)
Diffstat (limited to 'src/server/game/Spells/Spell.cpp')
| -rw-r--r-- | src/server/game/Spells/Spell.cpp | 52 |
1 files changed, 45 insertions, 7 deletions
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index aed7c0db043..84bff4a69d6 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -602,6 +602,8 @@ m_caster((info->HasAttribute(SPELL_ATTR6_CAST_BY_CHARMER) && caster->GetCharmerO //Auto Shot & Shoot (wand) m_autoRepeat = m_spellInfo->IsAutoRepeatRangedSpell(); + + m_isDelayedInstantCast = false; m_runesState = 0; m_powerCost = 0; // setup to correct value in Spell::prepare, must not be used before. @@ -2936,6 +2938,27 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggered else m_casttime = m_spellInfo->CalcCastTime(this); + if (m_caster->GetTypeId() == TYPEID_UNIT && !m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED)) // _UNIT actually means creature. for some reason. + if (!(IsNextMeleeSwingSpell() || IsAutoRepeat() || _triggeredCastFlags & TRIGGERED_IGNORE_SET_FACING)) + { + if (m_targets.GetObjectTarget() && m_caster != m_targets.GetObjectTarget()) + { + if (m_caster->ToCreature()->FocusTarget(this, m_targets.GetObjectTarget())) + { + m_isDelayedInstantCast = true; + m_timer = 100; // 100ms delay ensures client has updated creature orientation when cast goes off + } + } + else if (m_spellInfo->HasAttribute(SPELL_ATTR5_DONT_TURN_DURING_CAST)) + { + if (m_caster->ToCreature()->FocusTarget(this, nullptr)) + { + m_isDelayedInstantCast = true; + m_timer = 100; + } + } + } + // don't allow channeled spells / spells with cast time to be cast while moving // (even if they are interrupted on moving, spells with almost immediate effect get to have their effect processed before movement interrupter kicks in) if ((m_spellInfo->IsChanneled() || m_casttime) && m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->isMoving() && m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_MOVEMENT) @@ -2971,18 +2994,14 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggered } m_caster->SetCurrentCastSpell(this); - SendSpellStart(); - - // set target for proper facing - if ((m_casttime || m_spellInfo->IsChanneled()) && !(_triggeredCastFlags & TRIGGERED_IGNORE_SET_FACING)) - if (m_caster->GetTypeId() == TYPEID_UNIT && m_targets.GetObjectTarget() && m_caster != m_targets.GetObjectTarget()) - m_caster->ToCreature()->FocusTarget(this, m_targets.GetObjectTarget()); + if (!m_isDelayedInstantCast) + SendSpellStart(); if (!(_triggeredCastFlags & TRIGGERED_IGNORE_GCD)) TriggerGlobalCooldown(); //item: first cast may destroy item and second cast causes crash - if (!m_casttime && !m_spellInfo->StartRecoveryTime && !m_castItemGUID && GetCurrentContainer() == CURRENT_GENERIC_SPELL) + if (!m_casttime && !m_isDelayedInstantCast && !m_spellInfo->StartRecoveryTime && !m_castItemGUID && GetCurrentContainer() == CURRENT_GENERIC_SPELL) cast(true); } } @@ -2991,6 +3010,9 @@ void Spell::cancel() { if (m_spellState == SPELL_STATE_FINISHED) return; + // delayed instant casts are used for client-side visual orientation; they are treated as instant for all intents and purposes server-side, and thus cannot be interrupted by another cast + if (m_isDelayedInstantCast) + return; uint32 oldState = m_spellState; m_spellState = SPELL_STATE_FINISHED; @@ -3060,6 +3082,9 @@ void Spell::cast(bool skipCheck) return; } + if (m_isDelayedInstantCast) + SendSpellStart(); + if (Player* playerCaster = m_caster->ToPlayer()) { // now that we've done the basic check, now run the scripts @@ -3139,6 +3164,16 @@ void Spell::cast(bool skipCheck) } } + // if the spell allows the creature to turn while casting, then adjust server-side orientation to face the target now + // client-side orientation is handled by the client itself, as the cast target is targeted due to Creature::FocusTarget + if (m_caster->GetTypeId() == TYPEID_UNIT && !m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED)) + if (!m_spellInfo->HasAttribute(SPELL_ATTR5_DONT_TURN_DURING_CAST)) + if (WorldObject* objTarget = m_targets.GetObjectTarget()) + { + m_caster->SetInFront(objTarget); + m_caster->SetFacingToObject(objTarget); + } + SelectSpellTargets(); // Spell may be finished after target map check @@ -3242,6 +3277,9 @@ void Spell::cast(bool skipCheck) } SetExecutedCurrently(false); + + if (Creature* creatureCaster = m_caster->ToCreature()) + creatureCaster->ReleaseFocus(this); } void Spell::handle_immediate() |
