[10075] Attempt use more expected by result buffs downranking algo.

* In small rate more fast
* Not affect non-buff ranked spells like 10909
This commit is contained in:
VladimirMangos 2010-06-18 04:03:08 +04:00
parent 07a931e141
commit 81851074ad
6 changed files with 45 additions and 31 deletions

View file

@ -4253,21 +4253,11 @@ SpellCastResult Spell::CheckCast(bool strict)
// auto selection spell rank implemented in WorldSession::HandleCastSpellOpcode // auto selection spell rank implemented in WorldSession::HandleCastSpellOpcode
// this case can be triggered if rank not found (too low-level target for first rank) // this case can be triggered if rank not found (too low-level target for first rank)
if (m_caster->GetTypeId() == TYPEID_PLAYER && !IsPassiveSpell(m_spellInfo) && !m_CastItem) if (m_caster->GetTypeId() == TYPEID_PLAYER && !m_CastItem && !m_IsTriggeredSpell)
{ {
for(int i = 0; i < MAX_EFFECT_INDEX; ++i) // spell expected to be auto-downranking in cast handle, so must be same
{ if (m_spellInfo != sSpellMgr.SelectAuraRankForLevel(m_spellInfo, target->getLevel()))
// check only spell that apply positive auras return SPELL_FAILED_LOWLEVEL;
if (m_spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA &&
IsPositiveEffect(m_spellInfo->Id, SpellEffectIndex(i)) &&
// at not self target
!IsCasterSourceTarget(m_spellInfo->EffectImplicitTargetA[i]) &&
// and target low level
target->getLevel() + 10 < m_spellInfo->spellLevel)
{
return SPELL_FAILED_LOWLEVEL;
}
}
} }
} }
else if (m_caster == target) else if (m_caster == target)

View file

@ -813,7 +813,7 @@ void AreaAura::Update(uint32 diff)
if(!apply) if(!apply)
continue; continue;
if(SpellEntry const *actualSpellInfo = sSpellMgr.SelectAuraRankForPlayerLevel(GetSpellProto(), (*tIter)->getLevel())) if(SpellEntry const *actualSpellInfo = sSpellMgr.SelectAuraRankForLevel(GetSpellProto(), (*tIter)->getLevel()))
{ {
int32 actualBasePoints = m_currentBasePoints; int32 actualBasePoints = m_currentBasePoints;
// recalculate basepoints for lower rank (all AreaAura spell not use custom basepoints?) // recalculate basepoints for lower rank (all AreaAura spell not use custom basepoints?)

View file

@ -376,12 +376,10 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
} }
// auto-selection buff level base at target level (in spellInfo) // auto-selection buff level base at target level (in spellInfo)
if (targets.getUnitTarget()) if (Unit* target = targets.getUnitTarget())
{ {
SpellEntry const *actualSpellInfo = sSpellMgr.SelectAuraRankForPlayerLevel(spellInfo,targets.getUnitTarget()->getLevel());
// if rank not found then function return NULL but in explicit cast case original spell can be casted and later failed with appropriate error message // if rank not found then function return NULL but in explicit cast case original spell can be casted and later failed with appropriate error message
if(actualSpellInfo) if (SpellEntry const *actualSpellInfo = sSpellMgr.SelectAuraRankForLevel(spellInfo, target->getLevel()))
spellInfo = actualSpellInfo; spellInfo = actualSpellInfo;
} }

View file

@ -2216,37 +2216,44 @@ bool SpellMgr::IsSkillBonusSpell(uint32 spellId) const
return false; return false;
} }
SpellEntry const* SpellMgr::SelectAuraRankForPlayerLevel(SpellEntry const* spellInfo, uint32 playerLevel) const SpellEntry const* SpellMgr::SelectAuraRankForLevel(SpellEntry const* spellInfo, uint32 level) const
{ {
// ignore passive spells // fast case
if(IsPassiveSpell(spellInfo)) if (level + 10 >= spellInfo->spellLevel)
return spellInfo;
// ignore selection for passive spells
if (IsPassiveSpell(spellInfo))
return spellInfo; return spellInfo;
bool needRankSelection = false; bool needRankSelection = false;
for(int i = 0; i < MAX_EFFECT_INDEX; ++i) for(int i = 0; i < MAX_EFFECT_INDEX; ++i)
{ {
if (IsPositiveEffect(spellInfo->Id, SpellEffectIndex(i)) && ( // for simple aura in check apply to any non caster based targets, in rank search mode to any explicit targets
spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA || if (((spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA &&
(IsExplicitPositiveTarget(spellInfo->EffectImplicitTargetA[i]) ||
IsAreaEffectPossitiveTarget(Targets(spellInfo->EffectImplicitTargetA[i])))) ||
spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_PARTY || spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_PARTY ||
spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_RAID)) spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_RAID) &&
IsPositiveEffect(spellInfo->Id, SpellEffectIndex(i)))
{ {
needRankSelection = true; needRankSelection = true;
break; break;
} }
} }
// not required // not required (rank check more slow so check it here)
if(!needRankSelection) if (!needRankSelection || GetSpellRank(spellInfo->Id) == 0)
return spellInfo; return spellInfo;
for(uint32 nextSpellId = spellInfo->Id; nextSpellId != 0; nextSpellId = GetPrevSpellInChain(nextSpellId)) for(uint32 nextSpellId = spellInfo->Id; nextSpellId != 0; nextSpellId = GetPrevSpellInChain(nextSpellId))
{ {
SpellEntry const *nextSpellInfo = sSpellStore.LookupEntry(nextSpellId); SpellEntry const *nextSpellInfo = sSpellStore.LookupEntry(nextSpellId);
if(!nextSpellInfo) if (!nextSpellInfo)
break; break;
// if found appropriate level // if found appropriate level
if(playerLevel + 10 >= nextSpellInfo->spellLevel) if (level + 10 >= spellInfo->spellLevel)
return nextSpellInfo; return nextSpellInfo;
// one rank less then // one rank less then

View file

@ -320,6 +320,25 @@ inline bool IsPointEffectTarget( Targets target )
return false; return false;
} }
inline bool IsAreaEffectPossitiveTarget( Targets target )
{
switch (target )
{
case TARGET_ALL_PARTY_AROUND_CASTER:
case TARGET_ALL_FRIENDLY_UNITS_AROUND_CASTER:
case TARGET_ALL_FRIENDLY_UNITS_IN_AREA:
case TARGET_ALL_PARTY:
case TARGET_ALL_PARTY_AROUND_CASTER_2:
case TARGET_AREAEFFECT_PARTY:
case TARGET_ALL_RAID_AROUND_CASTER:
case TARGET_AREAEFFECT_PARTY_AND_CLASS:
return true;
default:
break;
}
return false;
}
inline bool IsAreaEffectTarget( Targets target ) inline bool IsAreaEffectTarget( Targets target )
{ {
switch (target ) switch (target )
@ -904,7 +923,7 @@ class SpellMgr
static bool canStackSpellRanks(SpellEntry const *spellInfo); static bool canStackSpellRanks(SpellEntry const *spellInfo);
bool IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) const; bool IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) const;
SpellEntry const* SelectAuraRankForPlayerLevel(SpellEntry const* spellInfo, uint32 playerLevel) const; SpellEntry const* SelectAuraRankForLevel(SpellEntry const* spellInfo, uint32 Level) const;
// Spell learning // Spell learning
SpellLearnSkillNode const* GetSpellLearnSkill(uint32 spell_id) const SpellLearnSkillNode const* GetSpellLearnSkill(uint32 spell_id) 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 "10074" #define REVISION_NR "10075"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__