diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp index 2f77ee9c3..ad8c23ea6 100644 --- a/src/game/GameObject.cpp +++ b/src/game/GameObject.cpp @@ -240,11 +240,7 @@ void GameObject::Update(uint32 /*p_time*/) Unit* caster = GetOwner(); if(caster && caster->GetTypeId()==TYPEID_PLAYER) { - if(caster->m_currentSpells[CURRENT_CHANNELED_SPELL]) - { - caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->SendChannelUpdate(0); - caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->finish(false); - } + caster->FinishSpell(CURRENT_CHANNELED_SPELL); WorldPacket data(SMSG_FISH_NOT_HOOKED,0); ((Player*)caster)->GetSession()->SendPacket(&data); @@ -1065,11 +1061,7 @@ void GameObject::Use(Unit* user) } } - if(player->m_currentSpells[CURRENT_CHANNELED_SPELL]) - { - player->m_currentSpells[CURRENT_CHANNELED_SPELL]->SendChannelUpdate(0); - player->m_currentSpells[CURRENT_CHANNELED_SPELL]->finish(); - } + player->FinishSpell(CURRENT_CHANNELED_SPELL); return; } @@ -1100,7 +1092,7 @@ void GameObject::Use(Unit* user) // in case summoning ritual caster is GO creator spellCaster = caster; - if(!caster->m_currentSpells[CURRENT_CHANNELED_SPELL]) + if(!caster->GetCurrentSpell(CURRENT_CHANNELED_SPELL)) return; spellId = info->summoningRitual.spellId; @@ -1113,8 +1105,7 @@ void GameObject::Use(Unit* user) } // finish spell - caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->SendChannelUpdate(0); - caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->finish(); + player->FinishSpell(CURRENT_CHANNELED_SPELL); // can be deleted now SetLootState(GO_JUST_DEACTIVATED); diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 46bbf5a4c..32d63d8b8 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -16896,13 +16896,15 @@ bool Player::ActivateTaxiPathTo(std::vector const& nodes, Creature* npc if( m_ShapeShiftFormSpellId && m_form != FORM_BATTLESTANCE && m_form != FORM_BERSERKERSTANCE && m_form != FORM_DEFENSIVESTANCE && m_form != FORM_SHADOW ) RemoveAurasDueToSpell(m_ShapeShiftFormSpellId); - if(m_currentSpells[CURRENT_GENERIC_SPELL] && m_currentSpells[CURRENT_GENERIC_SPELL]->m_spellInfo->Id != spellid) - InterruptSpell(CURRENT_GENERIC_SPELL,false); + if (Spell* spell = GetCurrentSpell(CURRENT_GENERIC_SPELL)) + if (spell->m_spellInfo->Id != spellid) + InterruptSpell(CURRENT_GENERIC_SPELL,false); InterruptSpell(CURRENT_AUTOREPEAT_SPELL,false); - if(m_currentSpells[CURRENT_CHANNELED_SPELL] && m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo->Id != spellid) - InterruptSpell(CURRENT_CHANNELED_SPELL,true); + if (Spell* spell = GetCurrentSpell(CURRENT_CHANNELED_SPELL)) + if (spell->m_spellInfo->Id != spellid) + InterruptSpell(CURRENT_CHANNELED_SPELL,true); } uint32 sourcenode = nodes[0]; @@ -18852,11 +18854,9 @@ void Player::RemoveItemDependentAurasAndCasts( Item * pItem ) // currently casted spells can be dependent from item for (uint32 i = 0; i < CURRENT_MAX_SPELL; ++i) - { - if( m_currentSpells[i] && m_currentSpells[i]->getState()!=SPELL_STATE_DELAYED && - !HasItemFitToSpellReqirements(m_currentSpells[i]->m_spellInfo,pItem) ) - InterruptSpell(i); - } + if (Spell* spell = GetCurrentSpell(CurrentSpellTypes(i))) + if (spell->getState()!=SPELL_STATE_DELAYED && !HasItemFitToSpellReqirements(spell->m_spellInfo,pItem) ) + InterruptSpell(CurrentSpellTypes(i)); } uint32 Player::GetResurrectionSpellId() diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 6d350265f..19362bcef 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -2265,7 +2265,6 @@ void Spell::prepare(SpellCastTargets const* targets, Aura* triggeredByAura) else { m_caster->SetCurrentCastedSpell( this ); - m_selfContainer = &(m_caster->m_currentSpells[GetCurrentContainer()]); SendSpellStart(); } } diff --git a/src/game/Spell.h b/src/game/Spell.h index 288a0cf15..8e8dcf412 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -210,6 +210,7 @@ class Spell { friend struct MaNGOS::SpellNotifierPlayer; friend struct MaNGOS::SpellNotifierCreatureAndPlayer; + friend void Unit::SetCurrentCastedSpell( Spell * pSpell ); public: void EffectNULL(uint32 ); diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index c35188466..1d3e36181 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -3483,8 +3483,8 @@ void Aura::HandleFeignDeath(bool apply, bool Real) m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION); // prevent interrupt message - if(m_caster_guid==m_target->GetGUID() && m_target->m_currentSpells[CURRENT_GENERIC_SPELL]) - m_target->m_currentSpells[CURRENT_GENERIC_SPELL]->finish(); + if (m_caster_guid==m_target->GetGUID()) + m_target->FinishSpell(CURRENT_GENERIC_SPELL,false); m_target->InterruptNonMeleeSpells(true); m_target->getHostilRefManager().deleteReferences(); } @@ -3905,9 +3905,11 @@ void Aura::HandleAuraModSilence(bool apply, bool Real) { m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED); // Stop cast only spells vs PreventionType == SPELL_PREVENTION_TYPE_SILENCE - for (uint32 i = CURRENT_MELEE_SPELL; i < CURRENT_MAX_SPELL;i++) - if (m_target->m_currentSpells[i] && m_target->m_currentSpells[i]->m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE) - m_target->InterruptSpell(i, false); // Stop spells on prepare or casting state + for (uint32 i = CURRENT_MELEE_SPELL; i < CURRENT_MAX_SPELL; ++i) + if (Spell* spell = m_target->GetCurrentSpell(CurrentSpellTypes(i))) + if(spell->m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE) + // Stop spells on prepare or casting state + m_target->InterruptSpell(CurrentSpellTypes(i), false); } else { @@ -6268,13 +6270,10 @@ void Aura::PeriodicTick() int32 new_damage = pCaster->DealDamage(m_target, pdamage, &cleanDamage, DOT, GetSpellSchoolMask(GetSpellProto()), GetSpellProto(), false); if (!m_target->isAlive() && pCaster->IsNonMeleeSpellCasted(false)) - { for (uint32 i = CURRENT_FIRST_NON_MELEE_SPELL; i < CURRENT_MAX_SPELL; ++i) - { - if (pCaster->m_currentSpells[i] && pCaster->m_currentSpells[i]->m_spellInfo->Id == GetId()) - pCaster->m_currentSpells[i]->cancel(); - } - } + if (Spell* spell = pCaster->GetCurrentSpell(CurrentSpellTypes(i))) + if (spell->m_spellInfo->Id == GetId()) + spell->cancel(); if(Player *modOwner = pCaster->GetSpellModOwner()) @@ -6348,15 +6347,8 @@ void Aura::PeriodicTick() pCaster->RemoveAurasDueToSpell(GetId()); // finish current generic/channeling spells, don't affect autorepeat - if(pCaster->m_currentSpells[CURRENT_GENERIC_SPELL]) - { - pCaster->m_currentSpells[CURRENT_GENERIC_SPELL]->finish(); - } - if(pCaster->m_currentSpells[CURRENT_CHANNELED_SPELL]) - { - pCaster->m_currentSpells[CURRENT_CHANNELED_SPELL]->SendChannelUpdate(0); - pCaster->m_currentSpells[CURRENT_CHANNELED_SPELL]->finish(); - } + pCaster->FinishSpell(CURRENT_GENERIC_SPELL); + pCaster->FinishSpell(CURRENT_CHANNELED_SPELL); } else { diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index a153c784e..fd987c8d8 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -4681,15 +4681,16 @@ void Spell::EffectInterruptCast(uint32 /*i*/) // TODO: not all spells that used this effect apply cooldown at school spells // also exist case: apply cooldown to interrupted cast only and to all spells - for (uint32 i = CURRENT_FIRST_NON_MELEE_SPELL; i < CURRENT_MAX_SPELL; i++) + for (uint32 i = CURRENT_FIRST_NON_MELEE_SPELL; i < CURRENT_MAX_SPELL; ++i) { - if (unitTarget->m_currentSpells[i]) + if (Spell* spell = unitTarget->GetCurrentSpell(CurrentSpellTypes(i))) { + SpellEntry const* curSpellInfo = spell->m_spellInfo; // check if we can interrupt spell - if ( unitTarget->m_currentSpells[i]->m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_INTERRUPT && unitTarget->m_currentSpells[i]->m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE ) + if ((curSpellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_INTERRUPT) && curSpellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE ) { - unitTarget->ProhibitSpellScholl(GetSpellSchoolMask(unitTarget->m_currentSpells[i]->m_spellInfo), GetSpellDuration(m_spellInfo)); - unitTarget->InterruptSpell(i,false); + unitTarget->ProhibitSpellScholl(GetSpellSchoolMask(curSpellInfo), GetSpellDuration(m_spellInfo)); + unitTarget->InterruptSpell(CurrentSpellTypes(i),false); } } } diff --git a/src/game/SpellHandler.cpp b/src/game/SpellHandler.cpp index f616c8266..ec9fb6cfd 100644 --- a/src/game/SpellHandler.cpp +++ b/src/game/SpellHandler.cpp @@ -402,9 +402,9 @@ void WorldSession::HandleCancelAuraOpcode( WorldPacket& recvPacket) // channeled spell case (it currently casted then) if (IsChanneledSpell(spellInfo)) { - if (_player->m_currentSpells[CURRENT_CHANNELED_SPELL] && - _player->m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo->Id==spellId) - _player->InterruptSpell(CURRENT_CHANNELED_SPELL); + if (Spell* curSpell = _player->GetCurrentSpell(CURRENT_CHANNELED_SPELL)) + if (curSpell->m_spellInfo->Id==spellId) + _player->InterruptSpell(CURRENT_CHANNELED_SPELL); return; } diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index a118ead6b..50717b657 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -816,14 +816,16 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa if (i == CURRENT_CHANNELED_SPELL) continue; - if(Spell* spell = pVictim->m_currentSpells[i]) + if(Spell* spell = pVictim->GetCurrentSpell(CurrentSpellTypes(i))) + { if(spell->getState() == SPELL_STATE_PREPARING) { if(spell->m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_ABORT_ON_DMG) - pVictim->InterruptSpell(i); + pVictim->InterruptSpell(CurrentSpellTypes(i)); else spell->Delayed(); } + } } } @@ -879,7 +881,7 @@ void Unit::CastStop(uint32 except_spellid) { for (uint32 i = CURRENT_FIRST_NON_MELEE_SPELL; i < CURRENT_MAX_SPELL; ++i) if (m_currentSpells[i] && m_currentSpells[i]->m_spellInfo->Id!=except_spellid) - InterruptSpell(i,false); + InterruptSpell(CurrentSpellTypes(i),false); } void Unit::CastSpell(Unit* Victim, uint32 spellId, bool triggered, Item *castItem, Aura* triggeredByAura, uint64 originalCaster) @@ -2705,13 +2707,9 @@ float Unit::MeleeMissChanceCalc(const Unit *pVictim, WeaponAttackType attType) c } } if (isNormal || m_currentSpells[CURRENT_MELEE_SPELL]) - { misschance = 5.0f; - } else - { misschance = 24.0f; - } } // PvP : PvE melee misschances per leveldif > 2 @@ -3107,9 +3105,11 @@ void Unit::SetCurrentCastedSpell( Spell * pSpell ) // set new current spell m_currentSpells[CSpellType] = pSpell; pSpell->SetReferencedFromCurrent(true); + + pSpell->m_selfContainer = &(m_currentSpells[pSpell->GetCurrentContainer()]); } -void Unit::InterruptSpell(uint32 spellType, bool withDelayed) +void Unit::InterruptSpell(CurrentSpellTypes spellType, bool withDelayed) { assert(spellType < CURRENT_MAX_SPELL); @@ -3134,6 +3134,19 @@ void Unit::InterruptSpell(uint32 spellType, bool withDelayed) } } +void Unit::FinishSpell(CurrentSpellTypes spellType, bool ok /*= true*/) +{ + Spell* spell = m_currentSpells[spellType]; + if (!spell) + return; + + if (spellType == CURRENT_CHANNELED_SPELL) + spell->SendChannelUpdate(0); + + spell->finish(ok); +} + + bool Unit::IsNonMeleeSpellCasted(bool withDelayed, bool skipChanneled, bool skipAutorepeat) const { // We don't do loop here to explicitly show that melee spell is excluded. diff --git a/src/game/Unit.h b/src/game/Unit.h index d4ca820a5..6312968b0 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -710,14 +710,16 @@ struct DeclinedName enum CurrentSpellTypes { - CURRENT_MELEE_SPELL = 0, - CURRENT_FIRST_NON_MELEE_SPELL = 1, // just counter - CURRENT_GENERIC_SPELL = 1, - CURRENT_AUTOREPEAT_SPELL = 2, - CURRENT_CHANNELED_SPELL = 3, - CURRENT_MAX_SPELL = 4 // just counter + CURRENT_MELEE_SPELL = 0, + CURRENT_GENERIC_SPELL = 1, + CURRENT_AUTOREPEAT_SPELL = 2, + CURRENT_CHANNELED_SPELL = 3 }; +#define CURRENT_FIRST_NON_MELEE_SPELL 1 +#define CURRENT_MAX_SPELL 4 + + enum ActiveStates { ACT_PASSIVE = 0x01, // 0x01 - passive @@ -1249,7 +1251,8 @@ class MANGOS_DLL_SPEC Unit : public WorldObject void SetCurrentCastedSpell(Spell * pSpell); virtual void ProhibitSpellScholl(SpellSchoolMask /*idSchoolMask*/, uint32 /*unTimeMs*/ ) { } - void InterruptSpell(uint32 spellType, bool withDelayed = true); + void InterruptSpell(CurrentSpellTypes spellType, bool withDelayed = true); + void FinishSpell(CurrentSpellTypes spellType, bool ok = true); // set withDelayed to true to account delayed spells as casted // delayed+channeled spells are always accounted as casted @@ -1260,10 +1263,9 @@ class MANGOS_DLL_SPEC Unit : public WorldObject // delayed+channeled spells are always interrupted void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid = 0); + Spell* GetCurrentSpell(CurrentSpellTypes spellType) const { return m_currentSpells[spellType]; } Spell* FindCurrentSpellBySpellId(uint32 spell_id) const; - Spell* m_currentSpells[CURRENT_MAX_SPELL]; - uint32 m_addDmgOnce; uint64 m_TotemSlot[MAX_TOTEM]; uint64 m_ObjectSlot[4]; @@ -1557,6 +1559,8 @@ class MANGOS_DLL_SPEC Unit : public WorldObject uint32 m_CombatTimer; uint32 m_lastManaUse; // msecs + Spell* m_currentSpells[CURRENT_MAX_SPELL]; + UnitVisibility m_Visibility; Diminishing m_Diminishing; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 05e1c9bf5..4071b140f 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8380" + #define REVISION_NR "8381" #endif // __REVISION_NR_H__