Core/Spell: implement SPELL_FAILED_AURA_BOUNCED on DR spells

This commit is contained in:
ariel- authored and Aokromes committed 2017-12-26 16:58:53 +01:00
1 parent bd17c710b6
commit 72b14ea028
5 files changed
+75 -53

No files matched your search

@@ -2610,12 +2610,6 @@ void Creature::SetPosition(float x, float y, float z, float o)
GetVehicleKit()->RelocatePassengers();
}
bool Creature::IsDungeonBoss() const
{
CreatureTemplate const* cinfo = sObjectMgr->GetCreatureTemplate(GetEntry());
return cinfo && (cinfo->flags_extra & CREATURE_FLAG_EXTRA_DUNGEON_BOSS);
}
float Creature::GetAggroRange(Unit const* target) const
{
// Determines the aggro range for creatures (usually pets), used mainly for aggressive pet target selection.
+2 -2
View File
@@ -487,6 +487,8 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
bool CanWalk() const { return (GetCreatureTemplate()->InhabitType & INHABIT_GROUND) != 0; }
bool CanSwim() const { return (GetCreatureTemplate()->InhabitType & INHABIT_WATER) != 0 || IsPet(); }
bool CanFly() const override { return (GetCreatureTemplate()->InhabitType & INHABIT_AIR) != 0; }
bool IsDungeonBoss() const { return (GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_DUNGEON_BOSS) != 0; }
bool IsAffectedByDiminishingReturns() const override { return Unit::IsAffectedByDiminishingReturns() || (GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_ALL_DIMINISH) != 0; }
void SetReactState(ReactStates st) { m_reactState = st; }
ReactStates GetReactState() const { return m_reactState; }
@@ -503,8 +505,6 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
bool isElite() const;
bool isWorldBoss() const;
bool IsDungeonBoss() const;
uint8 getLevelForTarget(WorldObject const* target) const override; // overwrite Unit::getLevelForTarget for boss level support
bool IsInEvadeMode() const { return HasUnitState(UNIT_STATE_EVADE); }
+32 -29
View File
@@ -4458,17 +4458,6 @@ bool Unit::HasNegativeAuraWithInterruptFlag(uint32 flag, ObjectGuid guid) const
return false;
}
bool Unit::HasNegativeAuraWithAttribute(uint32 flag, ObjectGuid guid) const
{
for (AuraApplicationMap::const_iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end(); ++iter)
{
Aura const* aura = iter->second->GetBase();
if (!iter->second->IsPositive() && aura->GetSpellInfo()->Attributes & flag && (!guid || aura->GetCasterGUID() == guid))
return true;
}
return false;
}
bool Unit::HasAuraWithMechanic(uint32 mechanicMask) const
{
for (AuraApplicationMap::const_iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end(); ++iter)
@@ -4486,6 +4475,26 @@ bool Unit::HasAuraWithMechanic(uint32 mechanicMask) const
return false;
}
bool Unit::HasStrongerAuraWithDR(SpellInfo const* auraSpellInfo, Unit* caster, bool triggered) const
{
DiminishingGroup diminishGroup = auraSpellInfo->GetDiminishingReturnsGroupForSpell(triggered);
DiminishingLevels level = GetDiminishing(diminishGroup);
for (auto itr = m_appliedAuras.begin(); itr != m_appliedAuras.end(); ++itr)
{
SpellInfo const* spellInfo = itr->second->GetBase()->GetSpellInfo();
if (spellInfo->GetDiminishingReturnsGroupForSpell(triggered) != diminishGroup)
continue;
int32 existingDuration = itr->second->GetBase()->GetMaxDuration();
int32 newDuration = auraSpellInfo->GetMaxDuration();
ApplyDiminishingToDuration(auraSpellInfo, triggered, newDuration, caster, level);
if (newDuration > 0 && newDuration < existingDuration)
return true;
}
return false;
}
AuraEffect* Unit::IsScriptOverriden(SpellInfo const* spell, int32 script) const
{
AuraEffectList const& auras = GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
@@ -9411,31 +9420,28 @@ void Unit::ModSpellDurationTime(SpellInfo const* spellInfo, int32 & duration, Sp
duration = int32(float(duration) * m_modAttackSpeedPct[RANGED_ATTACK]);
}
DiminishingLevels Unit::GetDiminishing(DiminishingGroup group)
DiminishingLevels Unit::GetDiminishing(DiminishingGroup group) const
{
DiminishingReturn& diminish = m_Diminishing[group];
DiminishingReturn const& diminish = m_Diminishing[group];
if (!diminish.hitCount)
return DIMINISHING_LEVEL_1;
// If last spell was cast more than 15 seconds ago - reset the count.
// If last spell was cast more than 15 seconds ago - reset level
if (!diminish.stack && GetMSTimeDiffToNow(diminish.hitTime) > 15000)
{
diminish.hitCount = DIMINISHING_LEVEL_1;
return DIMINISHING_LEVEL_1;
}
return DiminishingLevels(diminish.hitCount);
}
void Unit::IncrDiminishing(SpellInfo const* auraSpellInfo, bool triggered)
{
DiminishingGroup const group = auraSpellInfo->GetDiminishingReturnsGroupForSpell(triggered);
DiminishingLevels const maxLevel = auraSpellInfo->GetDiminishingReturnsMaxLevel(triggered);
DiminishingGroup group = auraSpellInfo->GetDiminishingReturnsGroupForSpell(triggered);
uint32 currentLevel = GetDiminishing(group);
uint32 const maxLevel = auraSpellInfo->GetDiminishingReturnsMaxLevel(triggered);
// Checking for existing in the table
DiminishingReturn& diminish = m_Diminishing[group];
if (static_cast<int32>(diminish.hitCount) < maxLevel)
++diminish.hitCount;
if (currentLevel < maxLevel)
diminish.hitCount = currentLevel + 1;
}
bool Unit::ApplyDiminishingToDuration(SpellInfo const* auraSpellInfo, bool triggered, int32& duration, Unit* caster, DiminishingLevels previousLevel) const
@@ -9456,9 +9462,7 @@ bool Unit::ApplyDiminishingToDuration(SpellInfo const* auraSpellInfo, bool trigg
Unit const* target = targetOwner ? targetOwner : this;
Unit const* source = casterOwner ? casterOwner : caster;
if ((target->GetTypeId() == TYPEID_PLAYER
|| target->ToCreature()->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_ALL_DIMINISH)
&& source->GetTypeId() == TYPEID_PLAYER)
if (target->IsAffectedByDiminishingReturns() && source->GetTypeId() == TYPEID_PLAYER)
duration = limitDuration;
}
@@ -9480,10 +9484,9 @@ bool Unit::ApplyDiminishingToDuration(SpellInfo const* auraSpellInfo, bool trigg
}
}
// Some diminishings applies to mobs too (for example, Stun)
else if ((auraSpellInfo->GetDiminishingReturnsGroupType(triggered) == DRTYPE_PLAYER
&& ((targetOwner ? (targetOwner->GetTypeId() == TYPEID_PLAYER) : (GetTypeId() == TYPEID_PLAYER))
|| (GetTypeId() == TYPEID_UNIT && ToCreature()->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_ALL_DIMINISH)))
|| auraSpellInfo->GetDiminishingReturnsGroupType(triggered) == DRTYPE_ALL)
else if (auraSpellInfo->GetDiminishingReturnsGroupType(triggered) == DRTYPE_ALL ||
(auraSpellInfo->GetDiminishingReturnsGroupType(triggered) == DRTYPE_PLAYER &&
(targetOwner ? targetOwner->IsAffectedByDiminishingReturns() : IsAffectedByDiminishingReturns())))
{
DiminishingLevels diminish = previousLevel;
switch (diminish)
+3 -2
View File
@@ -1315,7 +1315,8 @@ class TC_GAME_API Unit : public WorldObject
void CleanupBeforeRemoveFromMap(bool finalCleanup);
void CleanupsBeforeDelete(bool finalCleanup = true) override; // used in ~Creature/~Player (or before mass creature delete to remove cross-references to already deleted units)
DiminishingLevels GetDiminishing(DiminishingGroup group);
virtual bool IsAffectedByDiminishingReturns() const { return (GetCharmerOrOwnerPlayerOrPlayerItself() != nullptr); }
DiminishingLevels GetDiminishing(DiminishingGroup group) const;
void IncrDiminishing(SpellInfo const* auraSpellInfo, bool triggered);
bool ApplyDiminishingToDuration(SpellInfo const* auraSpellInfo, bool triggered, int32& duration, Unit* caster, DiminishingLevels previousLevel) const;
void ApplyDiminishingAura(DiminishingGroup group, bool apply);
@@ -1842,8 +1843,8 @@ class TC_GAME_API Unit : public WorldObject
bool HasAuraTypeWithAffectMask(AuraType auratype, SpellInfo const* affectedSpell) const;
bool HasAuraTypeWithValue(AuraType auratype, int32 value) const;
bool HasNegativeAuraWithInterruptFlag(uint32 flag, ObjectGuid guid = ObjectGuid::Empty) const;
bool HasNegativeAuraWithAttribute(uint32 flag, ObjectGuid guid = ObjectGuid::Empty) const;
bool HasAuraWithMechanic(uint32 mechanicMask) const;
bool HasStrongerAuraWithDR(SpellInfo const* auraSpellInfo, Unit* caster, bool triggered) const;
AuraEffect* IsScriptOverriden(SpellInfo const* spell, int32 script) const;
uint32 GetDiseasesByCaster(ObjectGuid casterGUID, bool remove = false);
+38 -14
View File
@@ -2655,9 +2655,7 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA
diminishLevel = unit->GetDiminishing(diminishGroup);
DiminishingReturnsType type = m_spellInfo->GetDiminishingReturnsGroupType(triggered);
// Increase Diminishing on unit, current informations for actually casts will use values above
if ((type == DRTYPE_PLAYER &&
(unit->GetCharmerOrOwnerPlayerOrPlayerItself() || (unit->GetTypeId() == TYPEID_UNIT && unit->ToCreature()->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_ALL_DIMINISH))) ||
type == DRTYPE_ALL)
if (type == DRTYPE_ALL || (type == DRTYPE_PLAYER && unit->IsAffectedByDiminishingReturns()))
unit->IncrDiminishing(m_spellInfo, triggered);
}
@@ -3252,11 +3250,9 @@ void Spell::_cast(bool skipCheck)
// skip check if done already (for instant cast spells for example)
if (!skipCheck)
{
uint32 param1 = 0, param2 = 0;
SpellCastResult castResult = CheckCast(false, &param1, &param2);
if (castResult != SPELL_CAST_OK)
auto cleanupSpell = [this, modOwner](SpellCastResult res, uint32* p1 = nullptr, uint32* p2 = nullptr)
{
SendCastResult(castResult, &param1, &param2);
SendCastResult(res, p1, p2);
SendInterrupted(0);
if (modOwner)
@@ -3264,6 +3260,13 @@ void Spell::_cast(bool skipCheck)
finish(false);
SetExecutedCurrently(false);
};
uint32 param1 = 0, param2 = 0;
SpellCastResult castResult = CheckCast(false, &param1, &param2);
if (castResult != SPELL_CAST_OK)
{
cleanupSpell(castResult, &param1, &param2);
return;
}
@@ -3279,18 +3282,39 @@ void Spell::_cast(bool skipCheck)
{
// Spell will be cast after completing the trade. Silently ignore at this place
my_trade->SetSpell(m_spellInfo->Id, m_CastItem);
SendCastResult(SPELL_FAILED_DONT_REPORT);
SendInterrupted(0);
modOwner->SetSpellModTakingSpell(this, false);
finish(false);
SetExecutedCurrently(false);
cleanupSpell(SPELL_FAILED_DONT_REPORT);
return;
}
}
}
}
// check diminishing returns (again, only after finish cast bar, tested on retail)
if (Unit* target = m_targets.GetUnitTarget())
{
uint8 aura_effmask = 0;
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
if (m_spellInfo->Effects[i].IsUnitOwnedAuraEffect())
aura_effmask |= 1 << i;
if (aura_effmask)
{
bool const triggered = m_triggeredByAuraSpell != nullptr;
if (DiminishingGroup diminishGroup = m_spellInfo->GetDiminishingReturnsGroupForSpell(triggered))
{
DiminishingReturnsType type = m_spellInfo->GetDiminishingReturnsGroupType(triggered);
if (type == DRTYPE_ALL || (type == DRTYPE_PLAYER && target->IsAffectedByDiminishingReturns()))
{
Unit* caster = m_originalCaster ? m_originalCaster : m_caster;
if (target->HasStrongerAuraWithDR(m_spellInfo, caster, triggered))
{
cleanupSpell(SPELL_FAILED_AURA_BOUNCED);
return;
}
}
}
}
}
}
// if the spell allows the creature to turn while casting, then adjust server-side orientation to face the target now