mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-16 07:30:42 +01:00
Core/Spell: implement SPELL_FAILED_AURA_BOUNCED on DR spells
Closes #13695
(cherry picked from commit 5e2c5a52cd)
This commit is contained in:
@@ -101,6 +101,7 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
|
||||
bool CanSwim() const override { 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; }
|
||||
|
||||
@@ -4633,17 +4633,6 @@ bool Unit::HasNegativeAuraWithInterruptFlag(InterruptFlags flag, ObjectGuid guid
|
||||
template TC_GAME_API bool Unit::HasNegativeAuraWithInterruptFlag(SpellAuraInterruptFlags flag, ObjectGuid guid) const;
|
||||
template TC_GAME_API bool Unit::HasNegativeAuraWithInterruptFlag(SpellAuraInterruptFlags2 flag, ObjectGuid guid) const;
|
||||
|
||||
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)
|
||||
@@ -4661,6 +4650,26 @@ bool Unit::HasAuraWithMechanic(uint32 mechanicMask) const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Unit::HasStrongerAuraWithDR(SpellInfo const* auraSpellInfo, Unit* caster) const
|
||||
{
|
||||
DiminishingGroup diminishGroup = auraSpellInfo->GetDiminishingReturnsGroupForSpell();
|
||||
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() != diminishGroup)
|
||||
continue;
|
||||
|
||||
int32 existingDuration = itr->second->GetBase()->GetMaxDuration();
|
||||
int32 newDuration = auraSpellInfo->GetMaxDuration();
|
||||
ApplyDiminishingToDuration(auraSpellInfo, 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);
|
||||
@@ -9403,31 +9412,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 18 seconds ago - reset the count.
|
||||
// If last spell was cast more than 18 seconds ago - reset level.
|
||||
if (!diminish.stack && GetMSTimeDiffToNow(diminish.hitTime) > 18 * IN_MILLISECONDS)
|
||||
{
|
||||
diminish.hitCount = DIMINISHING_LEVEL_1;
|
||||
return DIMINISHING_LEVEL_1;
|
||||
}
|
||||
|
||||
return DiminishingLevels(diminish.hitCount);
|
||||
}
|
||||
|
||||
void Unit::IncrDiminishing(SpellInfo const* auraSpellInfo)
|
||||
{
|
||||
DiminishingGroup const group = auraSpellInfo->GetDiminishingReturnsGroupForSpell();
|
||||
DiminishingLevels const maxLevel = auraSpellInfo->GetDiminishingReturnsMaxLevel();
|
||||
DiminishingGroup group = auraSpellInfo->GetDiminishingReturnsGroupForSpell();
|
||||
uint32 currentLevel = GetDiminishing(group);
|
||||
uint32 const maxLevel = auraSpellInfo->GetDiminishingReturnsMaxLevel();
|
||||
|
||||
// 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, int32& duration, Unit* caster, DiminishingLevels previousLevel) const
|
||||
@@ -9447,9 +9453,7 @@ bool Unit::ApplyDiminishingToDuration(SpellInfo const* auraSpellInfo, int32& dur
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -9475,9 +9479,9 @@ bool Unit::ApplyDiminishingToDuration(SpellInfo const* auraSpellInfo, int32& dur
|
||||
}
|
||||
case DIMINISHING_AOE_KNOCKBACK:
|
||||
{
|
||||
if ((auraSpellInfo->GetDiminishingReturnsGroupType() == DRTYPE_PLAYER && (((targetOwner ? targetOwner : this)->ToPlayer())
|
||||
|| (ToCreature() && (ToCreature()->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_ALL_DIMINISH))))
|
||||
|| auraSpellInfo->GetDiminishingReturnsGroupType() == DRTYPE_ALL)
|
||||
if (auraSpellInfo->GetDiminishingReturnsGroupType() == DRTYPE_ALL ||
|
||||
(auraSpellInfo->GetDiminishingReturnsGroupType() == DRTYPE_PLAYER &&
|
||||
(targetOwner ? targetOwner->IsAffectedByDiminishingReturns() : IsAffectedByDiminishingReturns())))
|
||||
{
|
||||
DiminishingLevels diminish = previousLevel;
|
||||
switch (diminish)
|
||||
@@ -9491,9 +9495,9 @@ bool Unit::ApplyDiminishingToDuration(SpellInfo const* auraSpellInfo, int32& dur
|
||||
}
|
||||
default:
|
||||
{
|
||||
if ((auraSpellInfo->GetDiminishingReturnsGroupType() == DRTYPE_PLAYER && (((targetOwner ? targetOwner : this)->ToPlayer())
|
||||
|| (ToCreature() && (ToCreature()->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_ALL_DIMINISH))))
|
||||
|| auraSpellInfo->GetDiminishingReturnsGroupType() == DRTYPE_ALL)
|
||||
if (auraSpellInfo->GetDiminishingReturnsGroupType() == DRTYPE_ALL ||
|
||||
(auraSpellInfo->GetDiminishingReturnsGroupType() == DRTYPE_PLAYER &&
|
||||
(targetOwner ? targetOwner->IsAffectedByDiminishingReturns() : IsAffectedByDiminishingReturns())))
|
||||
{
|
||||
DiminishingLevels diminish = previousLevel;
|
||||
switch (diminish)
|
||||
|
||||
@@ -952,7 +952,8 @@ class TC_GAME_API Unit : public WorldObject
|
||||
|
||||
void SendCombatLogMessage(WorldPackets::CombatLog::CombatLogServerPacket* combatLog) const;
|
||||
|
||||
DiminishingLevels GetDiminishing(DiminishingGroup group);
|
||||
virtual bool IsAffectedByDiminishingReturns() const { return (GetCharmerOrOwnerPlayerOrPlayerItself() != nullptr); }
|
||||
DiminishingLevels GetDiminishing(DiminishingGroup group) const;
|
||||
void IncrDiminishing(SpellInfo const* auraSpellInfo);
|
||||
bool ApplyDiminishingToDuration(SpellInfo const* auraSpellInfo, int32& duration, Unit* caster, DiminishingLevels previousLevel) const;
|
||||
void ApplyDiminishingAura(DiminishingGroup group, bool apply);
|
||||
@@ -1598,8 +1599,8 @@ class TC_GAME_API Unit : public WorldObject
|
||||
bool HasAuraTypeWithValue(AuraType auratype, int32 value) const;
|
||||
template <typename InterruptFlags>
|
||||
bool HasNegativeAuraWithInterruptFlag(InterruptFlags 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) const;
|
||||
|
||||
AuraEffect* IsScriptOverriden(SpellInfo const* spell, int32 script) const;
|
||||
uint32 GetDiseasesByCaster(ObjectGuid casterGUID, bool remove = false);
|
||||
|
||||
@@ -2650,9 +2650,7 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask)
|
||||
diminishLevel = unit->GetDiminishing(diminishGroup);
|
||||
DiminishingReturnsType type = m_spellInfo->GetDiminishingReturnsGroupType();
|
||||
// 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);
|
||||
}
|
||||
|
||||
@@ -3203,11 +3201,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, ¶m1, ¶m2);
|
||||
if (castResult != SPELL_CAST_OK)
|
||||
auto cleanupSpell = [this, modOwner](SpellCastResult res, uint32* p1 = nullptr, uint32* p2 = nullptr)
|
||||
{
|
||||
SendCastResult(castResult, ¶m1, ¶m2);
|
||||
SendCastResult(res, p1, p2);
|
||||
SendInterrupted(0);
|
||||
|
||||
if (modOwner)
|
||||
@@ -3215,6 +3211,13 @@ void Spell::_cast(bool skipCheck)
|
||||
|
||||
finish(false);
|
||||
SetExecutedCurrently(false);
|
||||
};
|
||||
|
||||
uint32 param1 = 0, param2 = 0;
|
||||
SpellCastResult castResult = CheckCast(false, ¶m1, ¶m2);
|
||||
if (castResult != SPELL_CAST_OK)
|
||||
{
|
||||
cleanupSpell(castResult, ¶m1, ¶m2);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3230,18 +3233,38 @@ 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->GetEffect(i)->IsUnitOwnedAuraEffect())
|
||||
aura_effmask |= 1 << i;
|
||||
|
||||
if (aura_effmask)
|
||||
{
|
||||
if (DiminishingGroup diminishGroup = m_spellInfo->GetDiminishingReturnsGroupForSpell())
|
||||
{
|
||||
DiminishingReturnsType type = m_spellInfo->GetDiminishingReturnsGroupType();
|
||||
if (type == DRTYPE_ALL || (type == DRTYPE_PLAYER && target->IsAffectedByDiminishingReturns()))
|
||||
{
|
||||
Unit* caster = m_originalCaster ? m_originalCaster : m_caster;
|
||||
if (target->HasStrongerAuraWithDR(m_spellInfo, caster))
|
||||
{
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user