[11740] Restore spellmod charges used by fail spell cast

Signed-off-by: VladimirMangos <vladimir@getmangos.com>

Also

 * Prevent more one charge use for same spell cast
 * Cleanup enum SpellState from unused cases
 * Propertly remove spellmod charges at spell finish in case pet/totem caster
This commit is contained in:
rowman 2011-07-16 10:10:52 +04:00 committed by VladimirMangos
parent f1bec402e9
commit 222612fa51
5 changed files with 63 additions and 26 deletions

View file

@ -18718,6 +18718,31 @@ void Player::RemoveSpellMods(Spell const* spell)
}
}
void Player::ResetSpellModsDueToCanceledSpell (Spell const* spell)
{
for(int i = 0; i < MAX_SPELLMOD; ++i )
{
for (SpellModList::const_iterator itr = m_spellMods[i].begin(); itr != m_spellMods[i].end(); ++itr)
{
SpellModifier *mod = *itr;
if (mod->lastAffected != spell)
continue;
mod->lastAffected = NULL;
if (mod->charges == -1)
{
mod->charges = 1;
if (m_SpellModRemoveCount > 0)
--m_SpellModRemoveCount;
}
else if (mod->charges > 0)
++mod->charges;
}
}
}
// send Proficiency
void Player::SendProficiency(ItemClass itemClass, uint32 itemSubclassMask)
{

View file

@ -139,7 +139,7 @@ struct SpellModifier
int32 value;
ClassFamilyMask mask;
uint32 spellId;
Spell const* lastAffected;
Spell const* lastAffected; // mark last charge user, used for cleanup delayed remove spellmods at spell success or restore charges at cast fail (Is one pointer only need for cases mixed castes?)
};
typedef std::list<SpellModifier*> SpellModList;
@ -1647,6 +1647,7 @@ class MANGOS_DLL_SPEC Player : public Unit
bool IsAffectedBySpellmod(SpellEntry const *spellInfo, SpellModifier *mod, Spell const* spell = NULL);
template <class T> T ApplySpellMod(uint32 spellId, SpellModOp op, T &basevalue, Spell const* spell = NULL);
void RemoveSpellMods(Spell const* spell);
void ResetSpellModsDueToCanceledSpell (Spell const* spell);
static uint32 const infinityCooldownDelay = MONTH; // used for set "infinity cooldowns" for spells and check
static uint32 const infinityCooldownDelayCheck = MONTH/2;
@ -2693,16 +2694,23 @@ template <class T> T Player::ApplySpellMod(uint32 spellId, SpellModOp op, T &bas
}
if (mod->charges > 0)
{
if (!spell)
spell = FindCurrentSpellBySpellId(spellId);
// avoid double use spellmod charge by same spell
if (!mod->lastAffected || mod->lastAffected != spell)
{
--mod->charges;
if (mod->charges == 0)
{
mod->charges = -1;
mod->lastAffected = spell;
if(!mod->lastAffected)
mod->lastAffected = FindCurrentSpellBySpellId(spellId);
++m_SpellModRemoveCount;
}
mod->lastAffected = spell;
}
}
}

View file

@ -361,7 +361,7 @@ Spell::Spell( Unit* caster, SpellEntry const *info, bool triggered, ObjectGuid o
for(int i = 0; i < MAX_EFFECT_INDEX; ++i)
m_currentBasePoints[i] = m_spellInfo->CalculateSimpleValue(SpellEffectIndex(i));
m_spellState = SPELL_STATE_NULL;
m_spellState = SPELL_STATE_PREPARING;
m_castPositionX = m_castPositionY = m_castPositionZ = 0;
m_TriggerSpells.clear();
@ -3500,16 +3500,22 @@ void Spell::finish(bool ok)
if (m_spellState == SPELL_STATE_FINISHED)
return;
// remove/restore spell mods before m_spellState update
if (Player* modOwner = m_caster->GetSpellModOwner())
{
if (ok || m_spellState != SPELL_STATE_PREPARING) // fail after start channeling or throw to target not affect spell mods
modOwner->RemoveSpellMods(this);
else
modOwner->ResetSpellModsDueToCanceledSpell(this);
}
m_spellState = SPELL_STATE_FINISHED;
// other code related only to successfully finished spells
if (!ok)
return;
// remove spell mods
if (m_caster->GetTypeId() == TYPEID_PLAYER)
((Player*)m_caster)->RemoveSpellMods(this);
// handle SPELL_AURA_ADD_TARGET_TRIGGER auras
Unit::AuraList const& targetTriggers = m_caster->GetAurasByType(SPELL_AURA_ADD_TARGET_TRIGGER);
for(Unit::AuraList::const_iterator i = targetTriggers.begin(); i != targetTriggers.end(); ++i)

View file

@ -201,12 +201,10 @@ inline ByteBuffer& operator>> (ByteBuffer& buf, SpellCastTargetsReader const& ta
enum SpellState
{
SPELL_STATE_NULL = 0,
SPELL_STATE_PREPARING = 1,
SPELL_STATE_CASTING = 2,
SPELL_STATE_FINISHED = 3,
SPELL_STATE_IDLE = 4,
SPELL_STATE_DELAYED = 5
SPELL_STATE_PREPARING = 0, // cast time delay period, non channeled spell
SPELL_STATE_CASTING = 1, // channeled time period spell casting state
SPELL_STATE_FINISHED = 2, // cast finished to success or fail
SPELL_STATE_DELAYED = 3 // spell casted but need time to hit target(s)
};
enum SpellTargets

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "11739"
#define REVISION_NR "11740"
#endif // __REVISION_NR_H__