diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index d0fa1bb31..26b1721f4 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -203,6 +203,10 @@ void GameObject::CheckRitualList() if (m_unique_users.empty()) return; + uint32 animSpell = GetGOInfo()->summoningRitual.animSpell; + if (!animSpell) + animSpell = GetSpellId(); + for (GuidSet::iterator itr = m_unique_users.begin(); itr != m_unique_users.end();) { if (*itr == GetOwnerGUID()) @@ -214,7 +218,7 @@ void GameObject::CheckRitualList() bool erase = true; if (Player* channeler = ObjectAccessor::GetPlayer(*this, *itr)) if (Spell* spell = channeler->GetCurrentSpell(CURRENT_CHANNELED_SPELL)) - if (spell->m_spellInfo->Id == GetGOInfo()->summoningRitual.animSpell) + if (spell->m_spellInfo->Id == animSpell) erase = false; if (erase) @@ -226,10 +230,13 @@ void GameObject::CheckRitualList() void GameObject::ClearRitualList() { - uint32 animSpell = GetGOInfo()->summoningRitual.animSpell; - if (!animSpell || m_unique_users.empty()) + if (m_unique_users.empty()) return; + uint32 animSpell = GetGOInfo()->summoningRitual.animSpell; + if (!animSpell) + animSpell = GetSpellId(); + for (ObjectGuid const& guid : m_unique_users) { if (Player* channeler = ObjectAccessor::GetPlayer(*this, guid)) @@ -526,18 +533,15 @@ void GameObject::Update(uint32 diff) if (GameTime::GetGameTimeMS().count() < m_cooldownTime) return; GameObjectTemplate const* info = GetGOInfo(); - if (info->summoningRitual.animSpell) - { - // xinef: if ritual requires animation, ensure that all users performs channel - CheckRitualList(); - } + + CheckRitualList(); + if (GetUniqueUseCount() < info->summoningRitual.reqParticipants) { SetLootState(GO_READY); return; } - bool triggered = info->summoningRitual.animSpell; Unit* owner = GetOwner(); Unit* spellCaster = owner ? owner : ObjectAccessor::GetPlayer(*this, m_ritualOwnerGUID); if (!spellCaster) @@ -553,7 +557,6 @@ void GameObject::Update(uint32 diff) // spell have reagent and mana cost but it not expected use its // it triggered spell in fact casted at currently channeled GO spellId = 61993; - triggered = true; } // Cast casterTargetSpell at a random GO user @@ -583,7 +586,7 @@ void GameObject::Update(uint32 diff) SetLootState(GO_READY); ClearRitualList(); - spellCaster->CastSpell(spellCaster, spellId, triggered); + spellCaster->CastSpell(spellCaster, spellId, true); return; } case GAMEOBJECT_TYPE_CHEST: @@ -1848,17 +1851,18 @@ void GameObject::Use(Unit* user) return; } + CheckRitualList(); + + if (GetUniqueUseCount() == info->summoningRitual.reqParticipants) + return; + if (info->summoningRitual.animSpell) - { - // xinef: if ritual requires animation, ensure that all users performs channel - CheckRitualList(); - - // xinef: all participants found - if (GetUniqueUseCount() == info->summoningRitual.reqParticipants) - return; - player->CastSpell(player, info->summoningRitual.animSpell, true); - } + else + player->CastSpell(player, GetSpellId(), + TriggerCastFlags(TRIGGERED_IGNORE_EFFECTS + | TRIGGERED_IGNORE_POWER_AND_REAGENT_COST + | TRIGGERED_CAST_DIRECTLY)); AddUniqueUse(player); @@ -1866,11 +1870,9 @@ void GameObject::Use(Unit* user) if (GetUniqueUseCount() == info->summoningRitual.reqParticipants) { SetLootState(GO_NOT_READY); - // can be deleted now, if - if (!info->summoningRitual.animSpell) - m_cooldownTime = 0; - else // channel ready, maintain this - m_cooldownTime = GameTime::GetGameTimeMS().count() + 5 * IN_MILLISECONDS; + + // channel ready, maintain this + m_cooldownTime = GameTime::GetGameTimeMS().count() + 5 * IN_MILLISECONDS; } return; diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 4a6e43f56..37eaf0a0b 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -4104,6 +4104,9 @@ void Spell::handle_immediate() if (m_spellInfo->IsChanneled()) { int32 duration = m_spellInfo->GetDuration(); + if (HasTriggeredCastFlag(TRIGGERED_IGNORE_EFFECTS)) + duration = -1; + if (duration > 0) { // First mod_duration then haste - see Missile Barrage @@ -4370,8 +4373,12 @@ void Spell::SendSpellCooldown() return; } - // have infinity cooldown but set at aura apply // do not set cooldown for triggered spells (needed by reincarnation) - if (m_spellInfo->IsCooldownStartedOnEvent() || m_spellInfo->IsPassive() || (HasTriggeredCastFlag(TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD) && !m_CastItem)) + // have infinity cooldown but set at aura apply + // do not set cooldown for triggered spells (needed by reincarnation) + if (m_spellInfo->IsCooldownStartedOnEvent() + || m_spellInfo->IsPassive() + || (HasTriggeredCastFlag(TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD) && !m_CastItem) + || HasTriggeredCastFlag(TRIGGERED_IGNORE_EFFECTS)) return; _player->AddSpellAndCategoryCooldowns(m_spellInfo, m_CastItem ? m_CastItem->GetEntry() : 0, this); @@ -5600,6 +5607,9 @@ void Spell::HandleThreatSpells() void Spell::HandleEffects(Unit* pUnitTarget, Item* pItemTarget, GameObject* pGOTarget, uint32 i, SpellEffectHandleMode mode) { + if (HasTriggeredCastFlag(TRIGGERED_IGNORE_EFFECTS)) + return; + effectHandleMode = mode; unitTarget = pUnitTarget; itemTarget = pItemTarget; @@ -6016,6 +6026,11 @@ SpellCastResult Spell::CheckCast(bool strict) return castResult; } + if (HasTriggeredCastFlag(TRIGGERED_IGNORE_EFFECTS)) + { + return SPELL_CAST_OK; + } + // xinef: do not skip triggered spells if they posses prevention type (eg. Bladestorm vs Hand of Protection) if (!HasTriggeredCastFlag(TRIGGERED_IGNORE_CASTER_AURAS) || (m_spellInfo->PreventionType > SPELL_PREVENTION_TYPE_NONE && m_triggeredByAuraSpell && m_triggeredByAuraSpell.spellInfo->IsPositive())) { @@ -8056,6 +8071,9 @@ bool Spell::IsAutoActionResetSpell() const bool Spell::IsNeedSendToClient(bool go) const { + if (HasTriggeredCastFlag(TRIGGERED_IGNORE_EFFECTS)) + return false; + return m_spellInfo->SpellVisual[0] || m_spellInfo->SpellVisual[1] || m_spellInfo->IsChanneled() || m_spellInfo->Speed > 0.0f || (!m_triggeredByAuraSpell && !IsTriggered()) || (go && m_triggeredByAuraSpell && m_triggeredByAuraSpell.spellInfo->IsChanneled()); diff --git a/src/server/game/Spells/SpellDefines.h b/src/server/game/Spells/SpellDefines.h index f3e08fc34..08a76cba6 100644 --- a/src/server/game/Spells/SpellDefines.h +++ b/src/server/game/Spells/SpellDefines.h @@ -148,6 +148,7 @@ enum TriggerCastFlags TRIGGERED_FULL_MASK = 0x0007FFFF, //! Used when doing CastSpell with triggered == true TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT = 0x00080000, //! Will ignore equipped item requirements TRIGGERED_NO_PERIODIC_RESET = 0x00100000, //! Periodic aura tick wont be reset on override + TRIGGERED_IGNORE_EFFECTS = 0x00200000, //! Ignore spell effects - used for ritual portals TRIGGERED_FULL_DEBUG_MASK = 0xFFFFFFFF };