[8381] Some refactoring work in Unit::m_currentSpells code.

* Restrict access, use enum args, move some repeated code parts to function.
* Make m_selfContainer set only part of Unit::SetCurrentCastedSpell
This commit is contained in:
VladimirMangos 2009-08-18 02:07:39 +04:00
parent 1b1d013623
commit 74d27294aa
10 changed files with 70 additions and 69 deletions

View file

@ -240,11 +240,7 @@ void GameObject::Update(uint32 /*p_time*/)
Unit* caster = GetOwner(); Unit* caster = GetOwner();
if(caster && caster->GetTypeId()==TYPEID_PLAYER) if(caster && caster->GetTypeId()==TYPEID_PLAYER)
{ {
if(caster->m_currentSpells[CURRENT_CHANNELED_SPELL]) caster->FinishSpell(CURRENT_CHANNELED_SPELL);
{
caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->SendChannelUpdate(0);
caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->finish(false);
}
WorldPacket data(SMSG_FISH_NOT_HOOKED,0); WorldPacket data(SMSG_FISH_NOT_HOOKED,0);
((Player*)caster)->GetSession()->SendPacket(&data); ((Player*)caster)->GetSession()->SendPacket(&data);
@ -1065,11 +1061,7 @@ void GameObject::Use(Unit* user)
} }
} }
if(player->m_currentSpells[CURRENT_CHANNELED_SPELL]) player->FinishSpell(CURRENT_CHANNELED_SPELL);
{
player->m_currentSpells[CURRENT_CHANNELED_SPELL]->SendChannelUpdate(0);
player->m_currentSpells[CURRENT_CHANNELED_SPELL]->finish();
}
return; return;
} }
@ -1100,7 +1092,7 @@ void GameObject::Use(Unit* user)
// in case summoning ritual caster is GO creator // in case summoning ritual caster is GO creator
spellCaster = caster; spellCaster = caster;
if(!caster->m_currentSpells[CURRENT_CHANNELED_SPELL]) if(!caster->GetCurrentSpell(CURRENT_CHANNELED_SPELL))
return; return;
spellId = info->summoningRitual.spellId; spellId = info->summoningRitual.spellId;
@ -1113,8 +1105,7 @@ void GameObject::Use(Unit* user)
} }
// finish spell // finish spell
caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->SendChannelUpdate(0); player->FinishSpell(CURRENT_CHANNELED_SPELL);
caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->finish();
// can be deleted now // can be deleted now
SetLootState(GO_JUST_DEACTIVATED); SetLootState(GO_JUST_DEACTIVATED);

View file

@ -16896,13 +16896,15 @@ bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc
if( m_ShapeShiftFormSpellId && m_form != FORM_BATTLESTANCE && m_form != FORM_BERSERKERSTANCE && m_form != FORM_DEFENSIVESTANCE && m_form != FORM_SHADOW ) if( m_ShapeShiftFormSpellId && m_form != FORM_BATTLESTANCE && m_form != FORM_BERSERKERSTANCE && m_form != FORM_DEFENSIVESTANCE && m_form != FORM_SHADOW )
RemoveAurasDueToSpell(m_ShapeShiftFormSpellId); RemoveAurasDueToSpell(m_ShapeShiftFormSpellId);
if(m_currentSpells[CURRENT_GENERIC_SPELL] && m_currentSpells[CURRENT_GENERIC_SPELL]->m_spellInfo->Id != spellid) if (Spell* spell = GetCurrentSpell(CURRENT_GENERIC_SPELL))
InterruptSpell(CURRENT_GENERIC_SPELL,false); if (spell->m_spellInfo->Id != spellid)
InterruptSpell(CURRENT_GENERIC_SPELL,false);
InterruptSpell(CURRENT_AUTOREPEAT_SPELL,false); InterruptSpell(CURRENT_AUTOREPEAT_SPELL,false);
if(m_currentSpells[CURRENT_CHANNELED_SPELL] && m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo->Id != spellid) if (Spell* spell = GetCurrentSpell(CURRENT_CHANNELED_SPELL))
InterruptSpell(CURRENT_CHANNELED_SPELL,true); if (spell->m_spellInfo->Id != spellid)
InterruptSpell(CURRENT_CHANNELED_SPELL,true);
} }
uint32 sourcenode = nodes[0]; uint32 sourcenode = nodes[0];
@ -18852,11 +18854,9 @@ void Player::RemoveItemDependentAurasAndCasts( Item * pItem )
// currently casted spells can be dependent from item // currently casted spells can be dependent from item
for (uint32 i = 0; i < CURRENT_MAX_SPELL; ++i) for (uint32 i = 0; i < CURRENT_MAX_SPELL; ++i)
{ if (Spell* spell = GetCurrentSpell(CurrentSpellTypes(i)))
if( m_currentSpells[i] && m_currentSpells[i]->getState()!=SPELL_STATE_DELAYED && if (spell->getState()!=SPELL_STATE_DELAYED && !HasItemFitToSpellReqirements(spell->m_spellInfo,pItem) )
!HasItemFitToSpellReqirements(m_currentSpells[i]->m_spellInfo,pItem) ) InterruptSpell(CurrentSpellTypes(i));
InterruptSpell(i);
}
} }
uint32 Player::GetResurrectionSpellId() uint32 Player::GetResurrectionSpellId()

View file

@ -2265,7 +2265,6 @@ void Spell::prepare(SpellCastTargets const* targets, Aura* triggeredByAura)
else else
{ {
m_caster->SetCurrentCastedSpell( this ); m_caster->SetCurrentCastedSpell( this );
m_selfContainer = &(m_caster->m_currentSpells[GetCurrentContainer()]);
SendSpellStart(); SendSpellStart();
} }
} }

View file

@ -210,6 +210,7 @@ class Spell
{ {
friend struct MaNGOS::SpellNotifierPlayer; friend struct MaNGOS::SpellNotifierPlayer;
friend struct MaNGOS::SpellNotifierCreatureAndPlayer; friend struct MaNGOS::SpellNotifierCreatureAndPlayer;
friend void Unit::SetCurrentCastedSpell( Spell * pSpell );
public: public:
void EffectNULL(uint32 ); void EffectNULL(uint32 );

View file

@ -3483,8 +3483,8 @@ void Aura::HandleFeignDeath(bool apply, bool Real)
m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION); m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
// prevent interrupt message // prevent interrupt message
if(m_caster_guid==m_target->GetGUID() && m_target->m_currentSpells[CURRENT_GENERIC_SPELL]) if (m_caster_guid==m_target->GetGUID())
m_target->m_currentSpells[CURRENT_GENERIC_SPELL]->finish(); m_target->FinishSpell(CURRENT_GENERIC_SPELL,false);
m_target->InterruptNonMeleeSpells(true); m_target->InterruptNonMeleeSpells(true);
m_target->getHostilRefManager().deleteReferences(); m_target->getHostilRefManager().deleteReferences();
} }
@ -3905,9 +3905,11 @@ void Aura::HandleAuraModSilence(bool apply, bool Real)
{ {
m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED); m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED);
// Stop cast only spells vs PreventionType == SPELL_PREVENTION_TYPE_SILENCE // Stop cast only spells vs PreventionType == SPELL_PREVENTION_TYPE_SILENCE
for (uint32 i = CURRENT_MELEE_SPELL; i < CURRENT_MAX_SPELL;i++) 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) if (Spell* spell = m_target->GetCurrentSpell(CurrentSpellTypes(i)))
m_target->InterruptSpell(i, false); // Stop spells on prepare or casting state if(spell->m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE)
// Stop spells on prepare or casting state
m_target->InterruptSpell(CurrentSpellTypes(i), false);
} }
else else
{ {
@ -6268,13 +6270,10 @@ void Aura::PeriodicTick()
int32 new_damage = pCaster->DealDamage(m_target, pdamage, &cleanDamage, DOT, GetSpellSchoolMask(GetSpellProto()), GetSpellProto(), false); int32 new_damage = pCaster->DealDamage(m_target, pdamage, &cleanDamage, DOT, GetSpellSchoolMask(GetSpellProto()), GetSpellProto(), false);
if (!m_target->isAlive() && pCaster->IsNonMeleeSpellCasted(false)) if (!m_target->isAlive() && pCaster->IsNonMeleeSpellCasted(false))
{
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 (Spell* spell = pCaster->GetCurrentSpell(CurrentSpellTypes(i)))
if (pCaster->m_currentSpells[i] && pCaster->m_currentSpells[i]->m_spellInfo->Id == GetId()) if (spell->m_spellInfo->Id == GetId())
pCaster->m_currentSpells[i]->cancel(); spell->cancel();
}
}
if(Player *modOwner = pCaster->GetSpellModOwner()) if(Player *modOwner = pCaster->GetSpellModOwner())
@ -6348,15 +6347,8 @@ void Aura::PeriodicTick()
pCaster->RemoveAurasDueToSpell(GetId()); pCaster->RemoveAurasDueToSpell(GetId());
// finish current generic/channeling spells, don't affect autorepeat // finish current generic/channeling spells, don't affect autorepeat
if(pCaster->m_currentSpells[CURRENT_GENERIC_SPELL]) pCaster->FinishSpell(CURRENT_GENERIC_SPELL);
{ pCaster->FinishSpell(CURRENT_CHANNELED_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();
}
} }
else else
{ {

View file

@ -4681,15 +4681,16 @@ void Spell::EffectInterruptCast(uint32 /*i*/)
// TODO: not all spells that used this effect apply cooldown at school spells // 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 // 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 // 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->ProhibitSpellScholl(GetSpellSchoolMask(curSpellInfo), GetSpellDuration(m_spellInfo));
unitTarget->InterruptSpell(i,false); unitTarget->InterruptSpell(CurrentSpellTypes(i),false);
} }
} }
} }

View file

@ -402,9 +402,9 @@ void WorldSession::HandleCancelAuraOpcode( WorldPacket& recvPacket)
// channeled spell case (it currently casted then) // channeled spell case (it currently casted then)
if (IsChanneledSpell(spellInfo)) if (IsChanneledSpell(spellInfo))
{ {
if (_player->m_currentSpells[CURRENT_CHANNELED_SPELL] && if (Spell* curSpell = _player->GetCurrentSpell(CURRENT_CHANNELED_SPELL))
_player->m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo->Id==spellId) if (curSpell->m_spellInfo->Id==spellId)
_player->InterruptSpell(CURRENT_CHANNELED_SPELL); _player->InterruptSpell(CURRENT_CHANNELED_SPELL);
return; return;
} }

View file

@ -816,14 +816,16 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
if (i == CURRENT_CHANNELED_SPELL) if (i == CURRENT_CHANNELED_SPELL)
continue; continue;
if(Spell* spell = pVictim->m_currentSpells[i]) if(Spell* spell = pVictim->GetCurrentSpell(CurrentSpellTypes(i)))
{
if(spell->getState() == SPELL_STATE_PREPARING) if(spell->getState() == SPELL_STATE_PREPARING)
{ {
if(spell->m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_ABORT_ON_DMG) if(spell->m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_ABORT_ON_DMG)
pVictim->InterruptSpell(i); pVictim->InterruptSpell(CurrentSpellTypes(i));
else else
spell->Delayed(); 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) 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) 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) 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]) if (isNormal || m_currentSpells[CURRENT_MELEE_SPELL])
{
misschance = 5.0f; misschance = 5.0f;
}
else else
{
misschance = 24.0f; misschance = 24.0f;
}
} }
// PvP : PvE melee misschances per leveldif > 2 // PvP : PvE melee misschances per leveldif > 2
@ -3107,9 +3105,11 @@ void Unit::SetCurrentCastedSpell( Spell * pSpell )
// set new current spell // set new current spell
m_currentSpells[CSpellType] = pSpell; m_currentSpells[CSpellType] = pSpell;
pSpell->SetReferencedFromCurrent(true); 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); 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 bool Unit::IsNonMeleeSpellCasted(bool withDelayed, bool skipChanneled, bool skipAutorepeat) const
{ {
// We don't do loop here to explicitly show that melee spell is excluded. // We don't do loop here to explicitly show that melee spell is excluded.

View file

@ -710,14 +710,16 @@ struct DeclinedName
enum CurrentSpellTypes enum CurrentSpellTypes
{ {
CURRENT_MELEE_SPELL = 0, CURRENT_MELEE_SPELL = 0,
CURRENT_FIRST_NON_MELEE_SPELL = 1, // just counter CURRENT_GENERIC_SPELL = 1,
CURRENT_GENERIC_SPELL = 1, CURRENT_AUTOREPEAT_SPELL = 2,
CURRENT_AUTOREPEAT_SPELL = 2, CURRENT_CHANNELED_SPELL = 3
CURRENT_CHANNELED_SPELL = 3,
CURRENT_MAX_SPELL = 4 // just counter
}; };
#define CURRENT_FIRST_NON_MELEE_SPELL 1
#define CURRENT_MAX_SPELL 4
enum ActiveStates enum ActiveStates
{ {
ACT_PASSIVE = 0x01, // 0x01 - passive ACT_PASSIVE = 0x01, // 0x01 - passive
@ -1249,7 +1251,8 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
void SetCurrentCastedSpell(Spell * pSpell); void SetCurrentCastedSpell(Spell * pSpell);
virtual void ProhibitSpellScholl(SpellSchoolMask /*idSchoolMask*/, uint32 /*unTimeMs*/ ) { } 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 // set withDelayed to true to account delayed spells as casted
// delayed+channeled spells are always accounted 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 // delayed+channeled spells are always interrupted
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid = 0); void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid = 0);
Spell* GetCurrentSpell(CurrentSpellTypes spellType) const { return m_currentSpells[spellType]; }
Spell* FindCurrentSpellBySpellId(uint32 spell_id) const; Spell* FindCurrentSpellBySpellId(uint32 spell_id) const;
Spell* m_currentSpells[CURRENT_MAX_SPELL];
uint32 m_addDmgOnce; uint32 m_addDmgOnce;
uint64 m_TotemSlot[MAX_TOTEM]; uint64 m_TotemSlot[MAX_TOTEM];
uint64 m_ObjectSlot[4]; uint64 m_ObjectSlot[4];
@ -1557,6 +1559,8 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
uint32 m_CombatTimer; uint32 m_CombatTimer;
uint32 m_lastManaUse; // msecs uint32 m_lastManaUse; // msecs
Spell* m_currentSpells[CURRENT_MAX_SPELL];
UnitVisibility m_Visibility; UnitVisibility m_Visibility;
Diminishing m_Diminishing; Diminishing m_Diminishing;

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "8380" #define REVISION_NR "8381"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__