diff options
| author | treeston <treeston.mmoc@gmail.com> | 2016-01-13 18:38:54 +0100 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2016-03-29 19:36:05 +0200 |
| commit | 009cabb4b9d60a02ed2f219127c0df293ea96580 (patch) | |
| tree | 8cf5a56aeee002e94329c339a1a934dae451b868 /src/server/game/Spells/Spell.cpp | |
| parent | 21371075ff4efc82a8567dfd604137577f4400e7 (diff) | |
Merge branch '3.3.5-spellfacing' into 3.3.5-base (PR #15641)
(cherry picked from commit 233297c5c8619af96e2aab4fa5ef6d205b5dc18a)
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 256600e4010..fb4a24a5e40 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -598,6 +598,8 @@ m_spellValue(new SpellValue(caster->GetMap()->GetDifficultyID(), m_spellInfo)), //Auto Shot & Shoot (wand) m_autoRepeat = m_spellInfo->IsAutoRepeatRangedSpell(); + + m_isDelayedInstantCast = false; m_runesState = 0; m_casttime = 0; // setup to correct value in Spell::prepare, must not be used before. @@ -2986,6 +2988,27 @@ 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->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) // don't cancel spells which are affected by a SPELL_AURA_CAST_WHILE_WALKING effect @@ -3023,18 +3046,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); } } @@ -3043,6 +3062,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; @@ -3112,6 +3134,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 @@ -3191,6 +3216,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 @@ -3297,6 +3332,9 @@ void Spell::cast(bool skipCheck) } SetExecutedCurrently(false); + + if (Creature* creatureCaster = m_caster->ToCreature()) + creatureCaster->ReleaseFocus(this); } void Spell::handle_immediate() |
