diff options
Diffstat (limited to 'src/server/game/Spells/Spell.cpp')
| -rw-r--r-- | src/server/game/Spells/Spell.cpp | 41 |
1 files changed, 27 insertions, 14 deletions
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 60554e0717c..883f051b700 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -1564,7 +1564,7 @@ void Spell::SelectImplicitTrajTargets(SpellEffIndex effIndex) if (Creature* creatureTarget = unit->ToCreature()) { - if (!(creatureTarget->GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_PROJECTILE_COLLISION)) + if (!(creatureTarget->GetCreatureTemplate()->type_flags & CREATURE_TYPE_FLAG_CAN_COLLIDE_WITH_MISSILES)) continue; } } @@ -2320,8 +2320,13 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) } } + bool enablePvP = false; // need to check PvP state before spell effects, but act on it afterwards + if (spellHitTarget) { + // if target is flagged for pvp also flag caster if a player + if (unit->IsPvP() && m_caster->GetTypeId() == TYPEID_PLAYER) + enablePvP = true; // Decide on PvP flagging now, but act on it later. SpellMissInfo missInfo2 = DoSpellHitOnUnit(spellHitTarget, mask, target->scaleAura); if (missInfo2 != SPELL_MISS_NONE) { @@ -2474,8 +2479,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) // Needs to be called after dealing damage/healing to not remove breaking on damage auras DoTriggersOnSpellHit(spellHitTarget, mask); - // if target is fallged for pvp also flag caster if a player - if (unit->IsPvP() && m_caster->GetTypeId() == TYPEID_PLAYER) + if (enablePvP) m_caster->ToPlayer()->UpdatePvP(true); CallScriptAfterHitHandlers(); @@ -2986,12 +2990,17 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggered } // 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) if ((m_spellInfo->IsChanneled() || m_casttime) && m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->isMoving() && m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_MOVEMENT) { - SendCastResult(SPELL_FAILED_MOVING); - finish(false); - return; + // 1. Is a channel spell, 2. Has no casttime, 3. And has flag to allow movement during channel + if (!(m_spellInfo->IsChanneled() && !m_casttime && m_spellInfo->HasAttribute(SPELL_ATTR5_CAN_CHANNEL_WHEN_MOVING))) + { + SendCastResult(SPELL_FAILED_MOVING); + finish(false); + return; + } } // set timer base at cast time @@ -3219,6 +3228,10 @@ void Spell::cast(bool skipCheck) return; } + if (m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET)) + if (Creature* pet = ObjectAccessor::GetCreature(*m_caster, m_caster->GetPetGUID())) + pet->DespawnOrUnsummon(); + PrepareTriggersExecutedOnHit(); CallScriptOnCastHandlers(); @@ -3528,11 +3541,11 @@ void Spell::update(uint32 difftime) // check if the player caster has moved before the spell finished if ((m_caster->GetTypeId() == TYPEID_PLAYER && m_timer != 0) && - m_caster->isMoving() && (m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_MOVEMENT) && - (m_spellInfo->Effects[0].Effect != SPELL_EFFECT_STUCK || !m_caster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING_FAR))) + m_caster->isMoving() && (m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_MOVEMENT && + (m_spellInfo->Effects[0].Effect != SPELL_EFFECT_STUCK || !m_caster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING_FAR)))) { // don't cancel for melee, autorepeat, triggered and instant spells - if (!IsNextMeleeSwingSpell() && !IsAutoRepeat() && !IsTriggered()) + if (!IsNextMeleeSwingSpell() && !IsAutoRepeat() && !IsTriggered() && !(IsChannelActive() && m_spellInfo->HasAttribute(SPELL_ATTR5_CAN_CHANNEL_WHEN_MOVING))) cancel(); } @@ -5286,7 +5299,7 @@ SpellCastResult Spell::CheckCast(bool strict) switch (SummonProperties->Category) { case SUMMON_CATEGORY_PET: - if (m_caster->GetPetGUID()) + if (!m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET) && m_caster->GetPetGUID()) return SPELL_FAILED_ALREADY_HAVE_SUMMON; // intentional missing break, check both GetPetGUID() and GetCharmGUID for SUMMON_CATEGORY_PET case SUMMON_CATEGORY_PUPPET: @@ -5302,7 +5315,7 @@ SpellCastResult Spell::CheckCast(bool strict) { if (m_targets.GetUnitTarget()->GetTypeId() != TYPEID_PLAYER) return SPELL_FAILED_BAD_TARGETS; - if (m_targets.GetUnitTarget()->GetPetGUID()) + if (!m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET) && m_targets.GetUnitTarget()->GetPetGUID()) return SPELL_FAILED_ALREADY_HAVE_SUMMON; } break; @@ -5311,13 +5324,13 @@ SpellCastResult Spell::CheckCast(bool strict) { if (m_caster->GetPetGUID()) //let warlock do a replacement summon { - if (m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->getClass() == CLASS_WARLOCK) + if (m_caster->GetTypeId() == TYPEID_PLAYER) { if (strict) //starting cast, trigger pet stun (cast by pet so it doesn't attack player) if (Pet* pet = m_caster->ToPlayer()->GetPet()) pet->CastSpell(pet, 32752, true, NULL, NULL, pet->GetGUID()); } - else + else if (!m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET)) return SPELL_FAILED_ALREADY_HAVE_SUMMON; } @@ -5444,7 +5457,7 @@ SpellCastResult Spell::CheckCast(bool strict) if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_CHARM || m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_POSSESS) { - if (m_caster->GetPetGUID()) + if (!m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET) && m_caster->GetPetGUID()) return SPELL_FAILED_ALREADY_HAVE_SUMMON; if (m_caster->GetCharmGUID()) |
