mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2025-11-29 17:38:24 +08:00
fix(Core): Ritual animations (#19602)
Channel the same spell as the original caster when clicking on a ritual portal, but ignore the effects of the spell. Co-authored-by: killerwife <killerwife@gmail.com>
This commit is contained in:
@@ -203,6 +203,10 @@ void GameObject::CheckRitualList()
|
|||||||
if (m_unique_users.empty())
|
if (m_unique_users.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
uint32 animSpell = GetGOInfo()->summoningRitual.animSpell;
|
||||||
|
if (!animSpell)
|
||||||
|
animSpell = GetSpellId();
|
||||||
|
|
||||||
for (GuidSet::iterator itr = m_unique_users.begin(); itr != m_unique_users.end();)
|
for (GuidSet::iterator itr = m_unique_users.begin(); itr != m_unique_users.end();)
|
||||||
{
|
{
|
||||||
if (*itr == GetOwnerGUID())
|
if (*itr == GetOwnerGUID())
|
||||||
@@ -214,7 +218,7 @@ void GameObject::CheckRitualList()
|
|||||||
bool erase = true;
|
bool erase = true;
|
||||||
if (Player* channeler = ObjectAccessor::GetPlayer(*this, *itr))
|
if (Player* channeler = ObjectAccessor::GetPlayer(*this, *itr))
|
||||||
if (Spell* spell = channeler->GetCurrentSpell(CURRENT_CHANNELED_SPELL))
|
if (Spell* spell = channeler->GetCurrentSpell(CURRENT_CHANNELED_SPELL))
|
||||||
if (spell->m_spellInfo->Id == GetGOInfo()->summoningRitual.animSpell)
|
if (spell->m_spellInfo->Id == animSpell)
|
||||||
erase = false;
|
erase = false;
|
||||||
|
|
||||||
if (erase)
|
if (erase)
|
||||||
@@ -226,10 +230,13 @@ void GameObject::CheckRitualList()
|
|||||||
|
|
||||||
void GameObject::ClearRitualList()
|
void GameObject::ClearRitualList()
|
||||||
{
|
{
|
||||||
uint32 animSpell = GetGOInfo()->summoningRitual.animSpell;
|
if (m_unique_users.empty())
|
||||||
if (!animSpell || m_unique_users.empty())
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
uint32 animSpell = GetGOInfo()->summoningRitual.animSpell;
|
||||||
|
if (!animSpell)
|
||||||
|
animSpell = GetSpellId();
|
||||||
|
|
||||||
for (ObjectGuid const& guid : m_unique_users)
|
for (ObjectGuid const& guid : m_unique_users)
|
||||||
{
|
{
|
||||||
if (Player* channeler = ObjectAccessor::GetPlayer(*this, guid))
|
if (Player* channeler = ObjectAccessor::GetPlayer(*this, guid))
|
||||||
@@ -526,18 +533,15 @@ void GameObject::Update(uint32 diff)
|
|||||||
if (GameTime::GetGameTimeMS().count() < m_cooldownTime)
|
if (GameTime::GetGameTimeMS().count() < m_cooldownTime)
|
||||||
return;
|
return;
|
||||||
GameObjectTemplate const* info = GetGOInfo();
|
GameObjectTemplate const* info = GetGOInfo();
|
||||||
if (info->summoningRitual.animSpell)
|
|
||||||
{
|
CheckRitualList();
|
||||||
// xinef: if ritual requires animation, ensure that all users performs channel
|
|
||||||
CheckRitualList();
|
|
||||||
}
|
|
||||||
if (GetUniqueUseCount() < info->summoningRitual.reqParticipants)
|
if (GetUniqueUseCount() < info->summoningRitual.reqParticipants)
|
||||||
{
|
{
|
||||||
SetLootState(GO_READY);
|
SetLootState(GO_READY);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool triggered = info->summoningRitual.animSpell;
|
|
||||||
Unit* owner = GetOwner();
|
Unit* owner = GetOwner();
|
||||||
Unit* spellCaster = owner ? owner : ObjectAccessor::GetPlayer(*this, m_ritualOwnerGUID);
|
Unit* spellCaster = owner ? owner : ObjectAccessor::GetPlayer(*this, m_ritualOwnerGUID);
|
||||||
if (!spellCaster)
|
if (!spellCaster)
|
||||||
@@ -553,7 +557,6 @@ void GameObject::Update(uint32 diff)
|
|||||||
// spell have reagent and mana cost but it not expected use its
|
// spell have reagent and mana cost but it not expected use its
|
||||||
// it triggered spell in fact casted at currently channeled GO
|
// it triggered spell in fact casted at currently channeled GO
|
||||||
spellId = 61993;
|
spellId = 61993;
|
||||||
triggered = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cast casterTargetSpell at a random GO user
|
// Cast casterTargetSpell at a random GO user
|
||||||
@@ -583,7 +586,7 @@ void GameObject::Update(uint32 diff)
|
|||||||
SetLootState(GO_READY);
|
SetLootState(GO_READY);
|
||||||
|
|
||||||
ClearRitualList();
|
ClearRitualList();
|
||||||
spellCaster->CastSpell(spellCaster, spellId, triggered);
|
spellCaster->CastSpell(spellCaster, spellId, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case GAMEOBJECT_TYPE_CHEST:
|
case GAMEOBJECT_TYPE_CHEST:
|
||||||
@@ -1848,17 +1851,18 @@ void GameObject::Use(Unit* user)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CheckRitualList();
|
||||||
|
|
||||||
|
if (GetUniqueUseCount() == info->summoningRitual.reqParticipants)
|
||||||
|
return;
|
||||||
|
|
||||||
if (info->summoningRitual.animSpell)
|
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);
|
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);
|
AddUniqueUse(player);
|
||||||
|
|
||||||
@@ -1866,11 +1870,9 @@ void GameObject::Use(Unit* user)
|
|||||||
if (GetUniqueUseCount() == info->summoningRitual.reqParticipants)
|
if (GetUniqueUseCount() == info->summoningRitual.reqParticipants)
|
||||||
{
|
{
|
||||||
SetLootState(GO_NOT_READY);
|
SetLootState(GO_NOT_READY);
|
||||||
// can be deleted now, if
|
|
||||||
if (!info->summoningRitual.animSpell)
|
// channel ready, maintain this
|
||||||
m_cooldownTime = 0;
|
m_cooldownTime = GameTime::GetGameTimeMS().count() + 5 * IN_MILLISECONDS;
|
||||||
else // channel ready, maintain this
|
|
||||||
m_cooldownTime = GameTime::GetGameTimeMS().count() + 5 * IN_MILLISECONDS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -4104,6 +4104,9 @@ void Spell::handle_immediate()
|
|||||||
if (m_spellInfo->IsChanneled())
|
if (m_spellInfo->IsChanneled())
|
||||||
{
|
{
|
||||||
int32 duration = m_spellInfo->GetDuration();
|
int32 duration = m_spellInfo->GetDuration();
|
||||||
|
if (HasTriggeredCastFlag(TRIGGERED_IGNORE_EFFECTS))
|
||||||
|
duration = -1;
|
||||||
|
|
||||||
if (duration > 0)
|
if (duration > 0)
|
||||||
{
|
{
|
||||||
// First mod_duration then haste - see Missile Barrage
|
// First mod_duration then haste - see Missile Barrage
|
||||||
@@ -4370,8 +4373,12 @@ void Spell::SendSpellCooldown()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// have infinity cooldown but set at aura apply // do not set cooldown for triggered spells (needed by reincarnation)
|
// have infinity cooldown but set at aura apply
|
||||||
if (m_spellInfo->IsCooldownStartedOnEvent() || m_spellInfo->IsPassive() || (HasTriggeredCastFlag(TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD) && !m_CastItem))
|
// 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;
|
return;
|
||||||
|
|
||||||
_player->AddSpellAndCategoryCooldowns(m_spellInfo, m_CastItem ? m_CastItem->GetEntry() : 0, this);
|
_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)
|
void Spell::HandleEffects(Unit* pUnitTarget, Item* pItemTarget, GameObject* pGOTarget, uint32 i, SpellEffectHandleMode mode)
|
||||||
{
|
{
|
||||||
|
if (HasTriggeredCastFlag(TRIGGERED_IGNORE_EFFECTS))
|
||||||
|
return;
|
||||||
|
|
||||||
effectHandleMode = mode;
|
effectHandleMode = mode;
|
||||||
unitTarget = pUnitTarget;
|
unitTarget = pUnitTarget;
|
||||||
itemTarget = pItemTarget;
|
itemTarget = pItemTarget;
|
||||||
@@ -6016,6 +6026,11 @@ SpellCastResult Spell::CheckCast(bool strict)
|
|||||||
return castResult;
|
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)
|
// 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()))
|
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
|
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() ||
|
return m_spellInfo->SpellVisual[0] || m_spellInfo->SpellVisual[1] || m_spellInfo->IsChanneled() ||
|
||||||
m_spellInfo->Speed > 0.0f || (!m_triggeredByAuraSpell && !IsTriggered()) ||
|
m_spellInfo->Speed > 0.0f || (!m_triggeredByAuraSpell && !IsTriggered()) ||
|
||||||
(go && m_triggeredByAuraSpell && m_triggeredByAuraSpell.spellInfo->IsChanneled());
|
(go && m_triggeredByAuraSpell && m_triggeredByAuraSpell.spellInfo->IsChanneled());
|
||||||
|
|||||||
@@ -148,6 +148,7 @@ enum TriggerCastFlags
|
|||||||
TRIGGERED_FULL_MASK = 0x0007FFFF, //! Used when doing CastSpell with triggered == true
|
TRIGGERED_FULL_MASK = 0x0007FFFF, //! Used when doing CastSpell with triggered == true
|
||||||
TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT = 0x00080000, //! Will ignore equipped item requirements
|
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_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
|
TRIGGERED_FULL_DEBUG_MASK = 0xFFFFFFFF
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user