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:
Saqra1
2024-08-13 09:54:17 -05:00
committed by GitHub
parent cc2ef9d6dd
commit ed824de7b8
3 changed files with 48 additions and 27 deletions

View File

@@ -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();
}
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;
}
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;
if (info->summoningRitual.animSpell)
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,10 +1870,8 @@ 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
// channel ready, maintain this
m_cooldownTime = GameTime::GetGameTimeMS().count() + 5 * IN_MILLISECONDS;
}

View File

@@ -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());

View File

@@ -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
};