[8552] implemented spells which can be casted while dead

i added a function IsDeathOnlySpell() which returns true
if this spell can ONLY be casted while dead, so i haven't
implemented all spells which could be cast while dead..
This commit is contained in:
balrok 2009-09-21 19:52:01 +02:00
parent 5385b385bc
commit 2da82a8c68
9 changed files with 25 additions and 11 deletions

View file

@ -329,7 +329,7 @@ const uint32 ItemQualityColors[MAX_ITEM_QUALITY] = {
#define SPELL_ATTR_EX3_UNK9 0x00000200 // 9 #define SPELL_ATTR_EX3_UNK9 0x00000200 // 9
#define SPELL_ATTR_EX3_MAIN_HAND 0x00000400 // 10 Main hand weapon required #define SPELL_ATTR_EX3_MAIN_HAND 0x00000400 // 10 Main hand weapon required
#define SPELL_ATTR_EX3_BATTLEGROUND 0x00000800 // 11 Can casted only on battleground #define SPELL_ATTR_EX3_BATTLEGROUND 0x00000800 // 11 Can casted only on battleground
#define SPELL_ATTR_EX3_UNK12 0x00001000 // 12 #define SPELL_ATTR_EX3_CAST_ON_DEAD 0x00001000 // 12 target is a dead player (not every spell has this flag)
#define SPELL_ATTR_EX3_UNK13 0x00002000 // 13 #define SPELL_ATTR_EX3_UNK13 0x00002000 // 13
#define SPELL_ATTR_EX3_UNK14 0x00004000 // 14 "Honorless Target" only this spells have this flag #define SPELL_ATTR_EX3_UNK14 0x00004000 // 14 "Honorless Target" only this spells have this flag
#define SPELL_ATTR_EX3_UNK15 0x00008000 // 15 Auto Shoot, Shoot, Throw, - this is autoshot flag #define SPELL_ATTR_EX3_UNK15 0x00008000 // 15 Auto Shoot, Shoot, Throw, - this is autoshot flag

View file

@ -1210,7 +1210,7 @@ bool Spell::IsAliveUnitPresentInTargetList()
{ {
Unit *unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID); Unit *unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
if (unit && unit->isAlive()) if (unit && (unit->isAlive() ^ IsDeathOnlySpell(m_spellInfo)))
needAliveTargetMask &= ~ihit->effectMask; // remove from need alive mask effect that have alive target needAliveTargetMask &= ~ihit->effectMask; // remove from need alive mask effect that have alive target
} }
} }
@ -3875,6 +3875,9 @@ SpellCastResult Spell::CheckCast(bool strict)
return SPELL_FAILED_NOT_READY; return SPELL_FAILED_NOT_READY;
} }
if (IsDeathOnlySpell(m_spellInfo) && m_caster->isAlive())
return SPELL_FAILED_TARGET_NOT_DEAD;
// only allow triggered spells if at an ended battleground // only allow triggered spells if at an ended battleground
if( !m_IsTriggeredSpell && m_caster->GetTypeId() == TYPEID_PLAYER) if( !m_IsTriggeredSpell && m_caster->GetTypeId() == TYPEID_PLAYER)
if(BattleGround * bg = ((Player*)m_caster)->GetBattleGround()) if(BattleGround * bg = ((Player*)m_caster)->GetBattleGround())

View file

@ -657,7 +657,9 @@ namespace MaNGOS
for(typename GridRefManager<T>::iterator itr = m.begin(); itr != m.end(); ++itr) for(typename GridRefManager<T>::iterator itr = m.begin(); itr != m.end(); ++itr)
{ {
if ( !itr->getSource()->isTargetableForAttack() // there are still more spells which can be casted on dead, but
// they are no AOE and don't have such a nice SPELL_ATTR flag
if ( !itr->getSource()->isTargetableForAttack(i_spell.m_spellInfo->AttributesEx3 & SPELL_ATTR_EX3_CAST_ON_DEAD)
// mostly phase check // mostly phase check
|| !itr->getSource()->IsInMap(i_originalCaster)) || !itr->getSource()->IsInMap(i_originalCaster))
continue; continue;

View file

@ -6267,7 +6267,7 @@ void Aura::HandleSchoolAbsorb(bool apply, bool Real)
void Aura::PeriodicTick() void Aura::PeriodicTick()
{ {
if(!m_target->isAlive()) if (!m_target->isAlive() ^ IsDeathOnlySpell(GetSpellProto()))
return; return;
switch(m_modifier.m_auraname) switch(m_modifier.m_auraname)

View file

@ -2427,7 +2427,7 @@ void Spell::EffectApplyAura(uint32 i)
return; return;
// ghost spell check, allow apply any auras at player loading in ghost mode (will be cleanup after load) // ghost spell check, allow apply any auras at player loading in ghost mode (will be cleanup after load)
if( !unitTarget->isAlive() && !IsDeathPersistentSpell(m_spellInfo) && if ( (!unitTarget->isAlive() && !(IsDeathOnlySpell(m_spellInfo) || IsDeathPersistentSpell(m_spellInfo))) &&
(unitTarget->GetTypeId() != TYPEID_PLAYER || !((Player*)unitTarget)->GetSession()->PlayerLoading()) ) (unitTarget->GetTypeId() != TYPEID_PLAYER || !((Player*)unitTarget)->GetSession()->PlayerLoading()) )
return; return;

View file

@ -198,6 +198,12 @@ inline bool IsPassiveSpellStackableWithRanks(SpellEntry const* spellProto)
return !IsSpellHaveEffect(spellProto,SPELL_EFFECT_APPLY_AURA); return !IsSpellHaveEffect(spellProto,SPELL_EFFECT_APPLY_AURA);
} }
inline bool IsDeathOnlySpell(SpellEntry const *spellInfo)
{
return spellInfo->AttributesEx & SPELL_ATTR_EX3_CAST_ON_DEAD
|| spellInfo->Id == 2584
|| spellInfo->Id == 22011;
}
inline bool IsDeathPersistentSpell(SpellEntry const *spellInfo) inline bool IsDeathPersistentSpell(SpellEntry const *spellInfo)
{ {

View file

@ -3403,7 +3403,7 @@ bool Unit::AddAura(Aura *Aur)
// ghost spell check, allow apply any auras at player loading in ghost mode (will be cleanup after load) // ghost spell check, allow apply any auras at player loading in ghost mode (will be cleanup after load)
if( !isAlive() && !IsDeathPersistentSpell(aurSpellInfo) && if( !isAlive() && !IsDeathPersistentSpell(aurSpellInfo) &&
Aur->GetId() != 2584 && // Waiting to Resurrect (not have death persistence flag) !IsDeathOnlySpell(aurSpellInfo) &&
(GetTypeId()!=TYPEID_PLAYER || !((Player*)this)->GetSession()->PlayerLoading()) ) (GetTypeId()!=TYPEID_PLAYER || !((Player*)this)->GetSession()->PlayerLoading()) )
{ {
delete Aur; delete Aur;
@ -9385,7 +9385,7 @@ void Unit::ClearInCombat()
((Player*)this)->UpdatePotionCooldown(); ((Player*)this)->UpdatePotionCooldown();
} }
bool Unit::isTargetableForAttack() const bool Unit::isTargetableForAttack(bool inverseAlive /*=false*/) const
{ {
if (GetTypeId()==TYPEID_PLAYER && ((Player *)this)->isGameMaster()) if (GetTypeId()==TYPEID_PLAYER && ((Player *)this)->isGameMaster())
return false; return false;
@ -9397,7 +9397,10 @@ bool Unit::isTargetableForAttack() const
if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE)) if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE))
return false; return false;
return IsInWorld() && isAlive() && !hasUnitState(UNIT_STAT_DIED)&& !isInFlight() /*&& !isStealth()*/; if (!(isAlive() ^ inverseAlive))
return false;
return IsInWorld() && !hasUnitState(UNIT_STAT_DIED)&& !isInFlight() /*&& !isStealth()*/;
} }
int32 Unit::ModifyHealth(int32 dVal) int32 Unit::ModifyHealth(int32 dVal)

View file

@ -1110,7 +1110,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
void RemoveSpellbyDamageTaken(AuraType auraType, uint32 damage); void RemoveSpellbyDamageTaken(AuraType auraType, uint32 damage);
bool isTargetableForAttack() const; bool isTargetableForAttack(bool inversAlive = false) const;
virtual bool IsInWater() const; virtual bool IsInWater() const;
virtual bool IsUnderWater() const; virtual bool IsUnderWater() const;
bool isInAccessablePlaceFor(Creature const* c) const; bool isInAccessablePlaceFor(Creature const* c) const;

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 "8551" #define REVISION_NR "8552"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__