mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-16 07:30:42 +01:00
Core/Spell: move attribute helpers to spellInfo
- Renamed CheckEffectExecuteData to AssertEffectExecuteData and made const, better reflects its purpose - Added missing attribute check to IsNextMeleeSwingSpell - Reworked SPELL_ATTR4_CAST_ONLY_IN_OUTLAND attr check (researched behavior)
This commit is contained in:
@@ -192,6 +192,17 @@ struct AreaTableEntry
|
||||
return true;
|
||||
return (flags & AREA_FLAG_SANCTUARY) != 0;
|
||||
}
|
||||
|
||||
bool IsFlyable() const
|
||||
{
|
||||
if (flags & AREA_FLAG_OUTLAND)
|
||||
{
|
||||
if (!(flags & AREA_FLAG_NO_FLY_ZONE))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
#define MAX_GROUP_AREA_IDS 6
|
||||
|
||||
@@ -647,7 +647,8 @@ Spell::~Spell()
|
||||
|
||||
delete m_spellValue;
|
||||
|
||||
CheckEffectExecuteData();
|
||||
// missing cleanup somewhere, mem leaks so let's crash
|
||||
AssertEffectExecuteData();
|
||||
}
|
||||
|
||||
void Spell::InitExplicitTargets(SpellCastTargets const& targets)
|
||||
@@ -2992,7 +2993,7 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggered
|
||||
m_casttime = m_spellInfo->CalcCastTime(this);
|
||||
|
||||
if (m_caster->GetTypeId() == TYPEID_UNIT && !m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED)) // _UNIT actually means creature. for some reason.
|
||||
if (!(IsNextMeleeSwingSpell() || IsAutoRepeat() || _triggeredCastFlags & TRIGGERED_IGNORE_SET_FACING))
|
||||
if (!(m_spellInfo->IsNextMeleeSwingSpell() || IsAutoRepeat() || (_triggeredCastFlags & TRIGGERED_IGNORE_SET_FACING)))
|
||||
{
|
||||
if (m_targets.GetObjectTarget() && m_caster != m_targets.GetObjectTarget())
|
||||
m_caster->ToCreature()->FocusTarget(this, m_targets.GetObjectTarget());
|
||||
@@ -3005,8 +3006,8 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggered
|
||||
// (even if they are interrupted on moving, spells with almost immediate effect get to have their effect processed before movement interrupter kicks in)
|
||||
if ((m_spellInfo->IsChanneled() || m_casttime) && m_caster->GetTypeId() == TYPEID_PLAYER && !(m_caster->IsCharmed() && m_caster->GetCharmerGUID().IsCreature()) && m_caster->isMoving() && (m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_MOVEMENT))
|
||||
{
|
||||
// 1. Is a channel spell, 2. Has no casttime, 3. And has flag to allow movement during channel
|
||||
if (!(m_spellInfo->IsChanneled() && !m_casttime && m_spellInfo->HasAttribute(SPELL_ATTR5_CAN_CHANNEL_WHEN_MOVING)))
|
||||
// 1. Has casttime, 2. Or doesn't have flag to allow movement during channel
|
||||
if (m_casttime || !m_spellInfo->IsMoveAllowedChannel())
|
||||
{
|
||||
SendCastResult(SPELL_FAILED_MOVING);
|
||||
finish(false);
|
||||
@@ -3561,7 +3562,7 @@ void Spell::update(uint32 difftime)
|
||||
(m_spellInfo->Effects[0].Effect != SPELL_EFFECT_STUCK || !m_caster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING_FAR))))
|
||||
{
|
||||
// don't cancel for melee, autorepeat, triggered and instant spells
|
||||
if (!IsNextMeleeSwingSpell() && !IsAutoRepeat() && !IsTriggered() && !(IsChannelActive() && m_spellInfo->HasAttribute(SPELL_ATTR5_CAN_CHANNEL_WHEN_MOVING)))
|
||||
if (!m_spellInfo->IsNextMeleeSwingSpell() && !IsAutoRepeat() && !IsTriggered() && !(IsChannelActive() && m_spellInfo->IsMoveAllowedChannel()))
|
||||
{
|
||||
// if charmed by creature, trust the AI not to cheat and allow the cast to proceed
|
||||
// @todo this is a hack, "creature" movesplines don't differentiate turning/moving right now
|
||||
@@ -3583,7 +3584,7 @@ void Spell::update(uint32 difftime)
|
||||
m_timer -= difftime;
|
||||
}
|
||||
|
||||
if (m_timer == 0 && !IsNextMeleeSwingSpell() && !IsAutoRepeat())
|
||||
if (m_timer == 0 && !m_spellInfo->IsNextMeleeSwingSpell() && !IsAutoRepeat())
|
||||
// don't CheckCast for instant spells - done in spell::prepare, skip duplicate checks, needed for range checks for example
|
||||
cast(!m_casttime);
|
||||
break;
|
||||
@@ -6618,14 +6619,14 @@ bool Spell::UpdatePointers()
|
||||
|
||||
CurrentSpellTypes Spell::GetCurrentContainer() const
|
||||
{
|
||||
if (IsNextMeleeSwingSpell())
|
||||
return(CURRENT_MELEE_SPELL);
|
||||
if (m_spellInfo->IsNextMeleeSwingSpell())
|
||||
return CURRENT_MELEE_SPELL;
|
||||
else if (IsAutoRepeat())
|
||||
return(CURRENT_AUTOREPEAT_SPELL);
|
||||
return CURRENT_AUTOREPEAT_SPELL;
|
||||
else if (m_spellInfo->IsChanneled())
|
||||
return(CURRENT_CHANNELED_SPELL);
|
||||
else
|
||||
return(CURRENT_GENERIC_SPELL);
|
||||
return CURRENT_CHANNELED_SPELL;
|
||||
|
||||
return CURRENT_GENERIC_SPELL;
|
||||
}
|
||||
|
||||
bool Spell::CheckEffectTarget(Unit const* target, uint32 eff, Position const* losPosition) const
|
||||
@@ -6704,11 +6705,6 @@ bool Spell::CheckEffectTarget(Unit const* target, uint32 eff, Position const* lo
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Spell::IsNextMeleeSwingSpell() const
|
||||
{
|
||||
return m_spellInfo->HasAttribute(SPELL_ATTR0_ON_NEXT_SWING);
|
||||
}
|
||||
|
||||
bool Spell::IsAutoActionResetSpell() const
|
||||
{
|
||||
/// @todo changed SPELL_INTERRUPT_FLAG_AUTOATTACK -> SPELL_INTERRUPT_FLAG_INTERRUPT to fix compile - is this check correct at all?
|
||||
@@ -7086,7 +7082,7 @@ void Spell::SetSpellValue(SpellValueMod mod, int32 value)
|
||||
|
||||
void Spell::PrepareTargetProcessing()
|
||||
{
|
||||
CheckEffectExecuteData();
|
||||
AssertEffectExecuteData();
|
||||
}
|
||||
|
||||
void Spell::FinishTargetProcessing()
|
||||
@@ -7111,7 +7107,7 @@ void Spell::InitEffectExecuteData(uint8 effIndex)
|
||||
}
|
||||
}
|
||||
|
||||
void Spell::CheckEffectExecuteData()
|
||||
void Spell::AssertEffectExecuteData() const
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
|
||||
ASSERT(!m_effectExecuteData[i]);
|
||||
|
||||
@@ -473,7 +473,6 @@ class TC_GAME_API Spell
|
||||
bool IsAutoRepeat() const { return m_autoRepeat; }
|
||||
void SetAutoRepeat(bool rep) { m_autoRepeat = rep; }
|
||||
void ReSetTimer() { m_timer = m_casttime > 0 ? m_casttime : 0; }
|
||||
bool IsNextMeleeSwingSpell() const;
|
||||
bool IsTriggered() const { return (_triggeredCastFlags & TRIGGERED_FULL_MASK) != 0; }
|
||||
bool IsIgnoringCooldowns() const { return (_triggeredCastFlags & TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD) != 0; }
|
||||
bool IsProcDisabled() const { return (_triggeredCastFlags & TRIGGERED_DISALLOW_PROC_EVENTS) != 0; }
|
||||
@@ -637,7 +636,7 @@ class TC_GAME_API Spell
|
||||
|
||||
// spell execution log
|
||||
void InitEffectExecuteData(uint8 effIndex);
|
||||
void CheckEffectExecuteData();
|
||||
void AssertEffectExecuteData() const;
|
||||
|
||||
// Scripting system
|
||||
void LoadScripts();
|
||||
|
||||
@@ -1181,12 +1181,22 @@ bool SpellInfo::IsPositiveEffect(uint8 effIndex) const
|
||||
|
||||
bool SpellInfo::IsChanneled() const
|
||||
{
|
||||
return HasAttribute(SPELL_ATTR1_CHANNELED_1) || HasAttribute(SPELL_ATTR1_CHANNELED_2);
|
||||
return HasAttribute(SpellAttr1(SPELL_ATTR1_CHANNELED_1 | SPELL_ATTR1_CHANNELED_2));
|
||||
}
|
||||
|
||||
bool SpellInfo::IsMoveAllowedChannel() const
|
||||
{
|
||||
return IsChanneled() && HasAttribute(SPELL_ATTR5_CAN_CHANNEL_WHEN_MOVING);
|
||||
}
|
||||
|
||||
bool SpellInfo::NeedsComboPoints() const
|
||||
{
|
||||
return HasAttribute(SPELL_ATTR1_REQ_COMBO_POINTS1) || HasAttribute(SPELL_ATTR1_REQ_COMBO_POINTS2);
|
||||
return HasAttribute(SpellAttr1(SPELL_ATTR1_REQ_COMBO_POINTS1 | SPELL_ATTR1_REQ_COMBO_POINTS2));
|
||||
}
|
||||
|
||||
bool SpellInfo::IsNextMeleeSwingSpell() const
|
||||
{
|
||||
return HasAttribute(SpellAttr0(SPELL_ATTR0_ON_NEXT_SWING | SPELL_ATTR0_ON_NEXT_SWING_2));
|
||||
}
|
||||
|
||||
bool SpellInfo::IsBreakingStealth() const
|
||||
@@ -1420,9 +1430,11 @@ SpellCastResult SpellInfo::CheckLocation(uint32 map_id, uint32 zone_id, uint32 a
|
||||
// continent limitation (virtual continent)
|
||||
if (HasAttribute(SPELL_ATTR4_CAST_ONLY_IN_OUTLAND))
|
||||
{
|
||||
uint32 v_map = GetVirtualMapForMapAndZone(map_id, zone_id);
|
||||
MapEntry const* mapEntry = sMapStore.LookupEntry(v_map);
|
||||
if (!mapEntry || mapEntry->addon < 1 || !mapEntry->IsContinent())
|
||||
AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(area_id);
|
||||
if (!areaEntry)
|
||||
areaEntry = sAreaTableStore.LookupEntry(zone_id);
|
||||
|
||||
if (!areaEntry || !areaEntry->IsFlyable() || !player->CanFlyInZone(map_id, zone_id))
|
||||
return SPELL_FAILED_INCORRECT_AREA;
|
||||
}
|
||||
|
||||
|
||||
@@ -429,7 +429,9 @@ class TC_GAME_API SpellInfo
|
||||
bool IsPositive() const;
|
||||
bool IsPositiveEffect(uint8 effIndex) const;
|
||||
bool IsChanneled() const;
|
||||
bool IsMoveAllowedChannel() const;
|
||||
bool NeedsComboPoints() const;
|
||||
bool IsNextMeleeSwingSpell() const;
|
||||
bool IsBreakingStealth() const;
|
||||
bool IsRangedWeaponSpell() const;
|
||||
bool IsAutoRepeatRangedSpell() const;
|
||||
|
||||
Reference in New Issue
Block a user