[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_MAIN_HAND 0x00000400 // 10 Main hand weapon required
#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_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

View file

@ -1210,7 +1210,7 @@ bool Spell::IsAliveUnitPresentInTargetList()
{
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
}
}
@ -3875,6 +3875,9 @@ SpellCastResult Spell::CheckCast(bool strict)
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
if( !m_IsTriggeredSpell && m_caster->GetTypeId() == TYPEID_PLAYER)
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)
{
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
|| !itr->getSource()->IsInMap(i_originalCaster))
continue;

View file

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

View file

@ -2427,7 +2427,7 @@ void Spell::EffectApplyAura(uint32 i)
return;
// 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()) )
return;

View file

@ -198,6 +198,12 @@ inline bool IsPassiveSpellStackableWithRanks(SpellEntry const* spellProto)
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)
{

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)
if( !isAlive() && !IsDeathPersistentSpell(aurSpellInfo) &&
Aur->GetId() != 2584 && // Waiting to Resurrect (not have death persistence flag)
!IsDeathOnlySpell(aurSpellInfo) &&
(GetTypeId()!=TYPEID_PLAYER || !((Player*)this)->GetSession()->PlayerLoading()) )
{
delete Aur;
@ -9385,7 +9385,7 @@ void Unit::ClearInCombat()
((Player*)this)->UpdatePotionCooldown();
}
bool Unit::isTargetableForAttack() const
bool Unit::isTargetableForAttack(bool inverseAlive /*=false*/) const
{
if (GetTypeId()==TYPEID_PLAYER && ((Player *)this)->isGameMaster())
return false;
@ -9397,7 +9397,10 @@ bool Unit::isTargetableForAttack() const
if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE))
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)

View file

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

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "8551"
#define REVISION_NR "8552"
#endif // __REVISION_NR_H__