aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xsrc/server/game/AI/CoreAI/PetAI.cpp2
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedCreature.cpp2
-rwxr-xr-xsrc/server/game/Entities/Player/Player.cpp6
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.cpp26
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.h31
-rwxr-xr-xsrc/server/game/Server/Protocol/Handlers/PetHandler.cpp4
-rwxr-xr-xsrc/server/game/Server/Protocol/Handlers/SpellHandler.cpp2
-rwxr-xr-xsrc/server/game/Server/Protocol/Handlers/TradeHandler.cpp4
-rwxr-xr-xsrc/server/game/Spells/Spell.cpp133
-rwxr-xr-xsrc/server/game/Spells/Spell.h6
-rwxr-xr-xsrc/server/game/Spells/SpellEffects.cpp12
11 files changed, 132 insertions, 96 deletions
diff --git a/src/server/game/AI/CoreAI/PetAI.cpp b/src/server/game/AI/CoreAI/PetAI.cpp
index b22cd3ecd95..ff67e3b344b 100755
--- a/src/server/game/AI/CoreAI/PetAI.cpp
+++ b/src/server/game/AI/CoreAI/PetAI.cpp
@@ -171,7 +171,7 @@ void PetAI::UpdateAI(const uint32 diff)
continue;
}
- Spell* spell = new Spell(me, spellInfo, false, 0);
+ Spell* spell = new Spell(me, spellInfo, TRIGGERED_NONE, 0);
// Fix to allow pets on STAY to autocast
if (me->getVictim() && _CanAttack(me->getVictim()) && spell->CanAutoCast(me->getVictim()))
diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
index 64655c0d50a..001296e5c45 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
+++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
@@ -170,7 +170,7 @@ void ScriptedAI::DoCastSpell(Unit* pTarget, SpellInfo const* pSpellInfo, bool bT
return;
me->StopMoving();
- me->CastSpell(pTarget, pSpellInfo, bTriggered);
+ me->CastSpell(pTarget, pSpellInfo, bTriggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE);
}
void ScriptedAI::DoPlaySoundToSet(WorldObject* pSource, uint32 uiSoundId)
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 06ca30bf9cb..6b032f40e8a 100755
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -8343,7 +8343,7 @@ void Player::CastItemUseSpell(Item *item, SpellCastTargets const& targets, uint8
return;
}
- Spell* spell = new Spell(this, spellInfo, false);
+ Spell* spell = new Spell(this, spellInfo, TRIGGERED_NONE);
spell->m_CastItem = item;
spell->m_cast_count = cast_count; //set count of casts
spell->SetSpellValue(SPELLVALUE_BASE_POINT0, learning_spell_id);
@@ -8374,7 +8374,7 @@ void Player::CastItemUseSpell(Item *item, SpellCastTargets const& targets, uint8
continue;
}
- Spell* spell = new Spell(this, spellInfo, (count > 0));
+ Spell* spell = new Spell(this, spellInfo, (count > 0) ? TRIGGERED_FULL_MASK : TRIGGERED_NONE);
spell->m_CastItem = item;
spell->m_cast_count = cast_count; // set count of casts
spell->m_glyphIndex = glyphIndex; // glyph index
@@ -8402,7 +8402,7 @@ void Player::CastItemUseSpell(Item *item, SpellCastTargets const& targets, uint8
continue;
}
- Spell* spell = new Spell(this, spellInfo, (count > 0));
+ Spell* spell = new Spell(this, spellInfo, (count > 0) ? TRIGGERED_FULL_MASK : TRIGGERED_NONE);
spell->m_CastItem = item;
spell->m_cast_count = cast_count; // set count of casts
spell->m_glyphIndex = glyphIndex; // glyph index
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 0627caee97e..3cba4c678de 100755
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -890,7 +890,12 @@ void Unit::CastStop(uint32 except_spellid)
InterruptSpell(CurrentSpellTypes(i), false);
}
-void Unit::CastSpell(Unit* Victim, uint32 spellId, bool triggered, Item* castItem, AuraEffect const* triggeredByAura, uint64 originalCaster)
+inline void Unit::CastSpell(Unit* victim, uint32 spellId, bool triggered, Item* castItem, AuraEffect const* triggeredByAura, uint64 originalCaster)
+{
+ CastSpell(victim, spellId, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE, castItem, triggeredByAura, originalCaster);
+}
+
+void Unit::CastSpell(Unit* victim, uint32 spellId, TriggerCastFlags triggerFlags /*= TRIGGER_NONE*/, Item* castItem /*= NULL*/, AuraEffect const* triggeredByAura /*= NULL*/, uint64 originalCaster /*= 0*/)
{
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
@@ -900,10 +905,15 @@ void Unit::CastSpell(Unit* Victim, uint32 spellId, bool triggered, Item* castIte
return;
}
- CastSpell(Victim, spellInfo, triggered, castItem, triggeredByAura, originalCaster);
+ CastSpell(victim, spellInfo, triggerFlags, castItem, triggeredByAura, originalCaster);
+}
+
+inline void Unit::CastSpell(Unit* victim, SpellInfo const *spellInfo, bool triggered, Item *castItem/*= NULL*/, AuraEffect const* triggeredByAura /*= NULL*/, uint64 originalCaster /*= 0*/)
+{
+ CastSpell(victim, spellInfo, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE, castItem, triggeredByAura, originalCaster);
}
-void Unit::CastSpell(Unit* Victim, SpellInfo const* spellInfo, bool triggered, Item* castItem, AuraEffect const* triggeredByAura, uint64 originalCaster)
+void Unit::CastSpell(Unit* Victim, SpellInfo const* spellInfo, TriggerCastFlags triggerFlags, Item* castItem, AuraEffect const* triggeredByAura, uint64 originalCaster)
{
if (!spellInfo)
{
@@ -924,7 +934,7 @@ void Unit::CastSpell(Unit* Victim, SpellInfo const* spellInfo, bool triggered, I
if (!originalCaster && triggeredByAura)
originalCaster = triggeredByAura->GetCasterGUID();
- Spell* spell = new Spell(this, spellInfo, triggered, originalCaster);
+ Spell* spell = new Spell(this, spellInfo, triggerFlags, originalCaster);
spell->m_CastItem = castItem;
spell->prepare(&targets, triggeredByAura);
@@ -964,7 +974,7 @@ void Unit::CastCustomSpell(uint32 spellId, CustomSpellValues const& value, Unit*
if (!originalCaster && triggeredByAura)
originalCaster = triggeredByAura->GetCasterGUID();
- Spell* spell = new Spell(this, spellInfo, triggered, originalCaster);
+ Spell* spell = new Spell(this, spellInfo, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE, originalCaster);
if (castItem)
{
@@ -995,7 +1005,7 @@ void Unit::CastSpell(float x, float y, float z, uint32 spellId, bool triggered,
if (!originalCaster && triggeredByAura)
originalCaster = triggeredByAura->GetCasterGUID();
- Spell* spell = new Spell(this, spellInfo, triggered, originalCaster);
+ Spell* spell = new Spell(this, spellInfo, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE, originalCaster);
SpellCastTargets targets;
targets.SetDst(x, y, z, GetOrientation());
@@ -1025,7 +1035,7 @@ void Unit::CastSpell(GameObject *go, uint32 spellId, bool triggered, Item* castI
if (!originalCaster && triggeredByAura)
originalCaster = triggeredByAura->GetCasterGUID();
- Spell* spell = new Spell(this, spellInfo, triggered, originalCaster);
+ Spell* spell = new Spell(this, spellInfo, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE, originalCaster);
SpellCastTargets targets;
targets.SetGOTarget(go);
@@ -2939,7 +2949,7 @@ void Unit::_UpdateAutoRepeatSpell()
}
// we want to shoot
- Spell* spell = new Spell(this, m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo, true);
+ Spell* spell = new Spell(this, m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo, TRIGGERED_FULL_MASK);
spell->prepare(&(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_targets));
// all went good, reset attack
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 9f1437b7512..a368309f8cd 100755
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -380,6 +380,31 @@ enum AuraRemoveMode
AURA_REMOVE_BY_DEATH
};
+enum TriggerCastFlags
+{
+ TRIGGERED_NONE = 0x00000000, //! Not triggered
+ TRIGGERED_IGNORE_GCD = 0x00000001, //! Will ignore GCD
+ TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD = 0x00000002, //! Will ignore Spell and Category cooldowns
+ TRIGGERED_IGNORE_POWER_AND_REAGENT_COST = 0x00000004, //! Will ignore power and reagent cost
+ TRIGGERED_IGNORE_CAST_ITEM = 0x00000008, //! Will not take away cast item or update related achievement criteria
+ TRIGGERED_IGNORE_AURA_SCALING = 0x00000010, //! Will ignore aura scaling
+ TRIGGERED_IGNORE_CAST_IN_PROGRESS = 0x00000020, //! Will not check if a current cast is in progress
+ TRIGGERED_IGNORE_COMBO_POINTS = 0x00000040, //! Will ignore combo point requirement
+ TRIGGERED_CAST_DIRECTLY = 0x00000080, //! In Spell::prepare, will be cast directly without setting containers for executed spell
+ TRIGGERED_IGNORE_AURA_INTERRUPT_FLAGS = 0x00000100, //! Will ignore interruptible aura's at cast
+ TRIGGERED_IGNORE_SET_FACING = 0x00000200, //! Will not adjust facing to target (if any)
+ TRIGGERED_IGNORE_SHAPESHIFT = 0x00000400, //! Will ignore shapeshift checks
+ TRIGGERED_IGNORE_CASTER_AURASTATE = 0x00000800, //! Will ignore caster aura states including combat requirements and death state
+ TRIGGERED_IGNORE_TARGET_AURASTATE = 0x00001000, //! Will ignore target aura states
+ TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE = 0x00002000, //! Will ignore mounted/on vehicle restrictions
+ TRIGGERED_IGNORE_TARGET_DETECTABILITY = 0x00004000, //! Will ignore canSeeOrDetect
+ TRIGGERED_IGNORE_LOS = 0x00008000, //! Will ignore LOS to target
+ TRIGGERED_IGNORE_CASTER_AURAS = 0x00010000, //! Will ignore caster aura restrictions or requirements
+ TRIGGERED_ALLOW_PROC_EVENTS = 0x00020000, //! Allows proc events from triggere spell
+ TRIGGERED_DONT_REPORT_CAST_ERROR = 0x00040000, //! Will return SPELL_FAILED_DONT_REPORT in CheckCast functions
+ TRIGGERED_FULL_MASK = 0xFFFFFFFF,
+};
+
enum UnitMods
{
UNIT_MOD_STAT_STRENGTH, // UNIT_MOD_STAT_STRENGTH..UNIT_MOD_STAT_SPIRIT must be in existed order, it's accessed by index values of Stats enum.
@@ -1534,8 +1559,10 @@ class Unit : public WorldObject
void SendEnergizeSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage, Powers powertype);
void EnergizeBySpell(Unit *pVictim, uint32 SpellID, uint32 Damage, Powers powertype);
uint32 SpellNonMeleeDamageLog(Unit *pVictim, uint32 spellID, uint32 damage);
- void CastSpell(Unit* Victim, uint32 spellId, bool triggered, Item *castItem = NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0);
- void CastSpell(Unit* Victim, SpellInfo const *spellInfo, bool triggered, Item *castItem= NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0);
+ void CastSpell(Unit* victim, uint32 spellId, bool triggered, Item *castItem = NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0);
+ void CastSpell(Unit* victim, uint32 spellId, TriggerCastFlags triggerFlags = TRIGGERED_NONE, Item* castItem = NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0);
+ void CastSpell(Unit* victim, SpellInfo const *spellInfo, bool triggered, Item *castItem= NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0);
+ void CastSpell(Unit* victim, SpellInfo const *spellInfo, TriggerCastFlags triggerFlags, Item *castItem= NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0);
void CastSpell(float x, float y, float z, uint32 spellId, bool triggered, Item *castItem = NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0, Unit* originalVictim = 0);
void CastCustomSpell(Unit* Victim, uint32 spellId, int32 const* bp0, int32 const* bp1, int32 const* bp2, bool triggered, Item *castItem= NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0);
void CastCustomSpell(uint32 spellId, SpellValueMod mod, int32 value, Unit* Victim = NULL, bool triggered = true, Item *castItem = NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0);
diff --git a/src/server/game/Server/Protocol/Handlers/PetHandler.cpp b/src/server/game/Server/Protocol/Handlers/PetHandler.cpp
index 48ddba2694c..2f28f83de8f 100755
--- a/src/server/game/Server/Protocol/Handlers/PetHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/PetHandler.cpp
@@ -320,7 +320,7 @@ void WorldSession::HandlePetActionHelper(Unit *pet, uint64 guid1, uint16 spellid
pet->GetCharmInfo()->SetIsFollowing(false);
}
- Spell* spell = new Spell(pet, spellInfo, false);
+ Spell* spell = new Spell(pet, spellInfo, TRIGGERED_NONE);
SpellCastResult result = spell->CheckPetCast(unit_target);
@@ -779,7 +779,7 @@ void WorldSession::HandlePetCastSpellOpcode(WorldPacket& recvPacket)
caster->ClearUnitState(UNIT_STAT_FOLLOW);
- Spell* spell = new Spell(caster, spellInfo, false);
+ Spell* spell = new Spell(caster, spellInfo, TRIGGERED_NONE);
spell->m_cast_count = castCount; // probably pending spell cast
spell->m_targets = targets;
diff --git a/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp b/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp
index cd757f2f0f3..2043d88adfc 100755
--- a/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp
@@ -403,7 +403,7 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
spellInfo = actualSpellInfo;
}
- Spell* spell = new Spell(mover, spellInfo, false, 0, false);
+ Spell* spell = new Spell(mover, spellInfo, TRIGGERED_NONE, 0, false);
spell->m_cast_count = castCount; // set count of casts
spell->prepare(&targets);
}
diff --git a/src/server/game/Server/Protocol/Handlers/TradeHandler.cpp b/src/server/game/Server/Protocol/Handlers/TradeHandler.cpp
index d059e15d63b..dfcf84b816b 100755
--- a/src/server/game/Server/Protocol/Handlers/TradeHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/TradeHandler.cpp
@@ -351,7 +351,7 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/)
return;
}
- my_spell = new Spell(_player, spellEntry, true);
+ my_spell = new Spell(_player, spellEntry, TRIGGERED_FULL_MASK);
my_spell->m_CastItem = castItem;
my_targets.SetTradeItemTarget(_player);
my_spell->m_targets = my_targets;
@@ -386,7 +386,7 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/)
return;
}
- his_spell = new Spell(trader, spellEntry, true);
+ his_spell = new Spell(trader, spellEntry, TRIGGERED_FULL_MASK);
his_spell->m_CastItem = castItem;
his_targets.SetTradeItemTarget(trader);
his_spell->m_targets = his_targets;
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 4dfb735d264..6a9bdddbfc8 100755
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -449,9 +449,9 @@ SpellValue::SpellValue(SpellInfo const* proto)
AuraStackAmount = 1;
}
-Spell::Spell(Unit* Caster, SpellInfo const *info, bool triggered, uint64 originalCasterGUID, bool skipCheck):
-m_spellInfo(sSpellMgr->GetSpellForDifficultyFromSpell(info, Caster)),
-m_caster(Caster), m_spellValue(new SpellValue(m_spellInfo))
+Spell::Spell(Unit* caster, SpellInfo const *info, TriggerCastFlags triggerFlags, uint64 originalCasterGUID, bool skipCheck) :
+m_spellInfo(sSpellMgr->GetSpellForDifficultyFromSpell(info, caster)),
+m_caster(caster), m_spellValue(new SpellValue(m_spellInfo))
{
m_customError = SPELL_CUSTOM_ERROR_NONE;
m_skipCheck = skipCheck;
@@ -510,7 +510,10 @@ m_caster(Caster), m_spellValue(new SpellValue(m_spellInfo))
}
m_spellState = SPELL_STATE_NULL;
- m_IsTriggeredSpell = bool(triggered || (info->AttributesEx4 & SPELL_ATTR4_TRIGGERED));
+ _triggeredCastFlags = triggerFlags;
+ if (info->AttributesEx4 & SPELL_ATTR4_TRIGGERED)
+ _triggeredCastFlags = TRIGGERED_FULL_MASK;
+
m_CastItem = NULL;
unitTarget = NULL;
@@ -895,11 +898,11 @@ void Spell::prepareDataForTriggerSystem(AuraEffect const* /*triggeredByAura*/)
// Ranged autorepeat attack is set as triggered spell - ignore it
if (!(m_procAttacker & PROC_FLAG_DONE_RANGED_AUTO_ATTACK))
{
- if (m_IsTriggeredSpell &&
+ if (!(_triggeredCastFlags & TRIGGERED_ALLOW_PROC_EVENTS) &&
(m_spellInfo->AttributesEx2 & SPELL_ATTR2_TRIGGERED_CAN_TRIGGER_PROC ||
m_spellInfo->AttributesEx3 & SPELL_ATTR3_TRIGGERED_CAN_TRIGGER_PROC_2))
m_procEx |= PROC_EX_INTERNAL_CANT_PROC;
- else if (m_IsTriggeredSpell)
+ else if (!(_triggeredCastFlags & TRIGGERED_ALLOW_PROC_EVENTS))
m_procEx |= PROC_EX_INTERNAL_TRIGGERED;
}
// Totem casts require spellfamilymask defined in spell_proc_event to proc
@@ -2862,7 +2865,7 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggered
}
// Fill aura scaling information
- if (m_caster->IsControlledByPlayer() && !m_spellInfo->IsPassive() && m_spellInfo->SpellLevel && !m_spellInfo->IsChanneled() && !m_IsTriggeredSpell)
+ if (m_caster->IsControlledByPlayer() && !m_spellInfo->IsPassive() && m_spellInfo->SpellLevel && !m_spellInfo->IsChanneled() && !(_triggeredCastFlags & TRIGGERED_IGNORE_AURA_SCALING))
{
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
@@ -2892,7 +2895,7 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggered
m_caster->m_Events.AddEvent(Event, m_caster->m_Events.CalculateTime(1));
//Prevent casting at cast another spell (ServerSide check)
- if (!m_IsTriggeredSpell && m_caster->IsNonMeleeSpellCasted(false, true, true) && m_cast_count)
+ if (!(_triggeredCastFlags & TRIGGERED_IGNORE_CAST_IN_PROGRESS) && m_caster->IsNonMeleeSpellCasted(false, true, true) && m_cast_count)
{
SendCastResult(SPELL_FAILED_SPELL_IN_PROGRESS);
finish(false);
@@ -2915,7 +2918,7 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggered
m_caster->ToPlayer()->SetSpellModTakingSpell(this, false);
// Set combo point requirement
- if (m_IsTriggeredSpell || m_CastItem || !m_caster->m_movedPlayer)
+ if ((_triggeredCastFlags & TRIGGERED_IGNORE_COMBO_POINTS) || m_CastItem || !m_caster->m_movedPlayer)
m_needComboPoints = false;
SpellCastResult result = CheckCast(true);
@@ -2954,18 +2957,18 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggered
// set timer base at cast time
ReSetTimer();
- sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "Spell::prepare: spell id %u source %u caster %d triggered %u mask %u", m_spellInfo->Id, m_caster->GetEntry(), m_originalCaster ? m_originalCaster->GetEntry() : -1, m_IsTriggeredSpell ? 1 : 0, m_targets.GetTargetMask());
+ sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "Spell::prepare: spell id %u source %u caster %d customCastFlags %u mask %u", m_spellInfo->Id, m_caster->GetEntry(), m_originalCaster ? m_originalCaster->GetEntry() : -1, _triggeredCastFlags, m_targets.GetTargetMask());
//Containers for channeled spells have to be set
//TODO:Apply this to all casted spells if needed
// Why check duration? 29350: channelled triggers channelled
- if (m_IsTriggeredSpell && (!m_spellInfo->IsChanneled() || !m_spellInfo->GetMaxDuration()))
+ if ((_triggeredCastFlags & TRIGGERED_CAST_DIRECTLY) && (!m_spellInfo->IsChanneled() || !m_spellInfo->GetMaxDuration()))
cast(true);
else
{
// stealth must be removed at cast starting (at show channel bar)
// skip triggered spell (item equip spell casting and other not explicit character casts/item uses)
- if (!m_IsTriggeredSpell && m_spellInfo->IsBreakingStealth())
+ if (!(_triggeredCastFlags & TRIGGERED_IGNORE_AURA_INTERRUPT_FLAGS) && m_spellInfo->IsBreakingStealth())
{
m_caster->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_CAST);
for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
@@ -2980,12 +2983,13 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggered
SendSpellStart();
// set target for proper facing
- if (m_casttime && !m_IsTriggeredSpell)
+ if (m_casttime && !(_triggeredCastFlags & TRIGGERED_IGNORE_SET_FACING))
if (uint64 target = m_targets.GetUnitTargetGUID())
if (m_caster->GetGUID() != target && m_caster->GetTypeId() == TYPEID_UNIT)
m_caster->FocusTarget(this, target);
- TriggerGlobalCooldown();
+ if (!(_triggeredCastFlags & TRIGGERED_IGNORE_GCD))
+ TriggerGlobalCooldown();
//item: first cast may destroy item and second cast causes crash
if (!m_casttime && !m_spellInfo->StartRecoveryTime && !m_castItemGUID && GetCurrentContainer() == CURRENT_GENERIC_SPELL)
@@ -3092,7 +3096,7 @@ void Spell::cast(bool skipCheck)
}
// triggered cast called from Spell::prepare where it was already checked
- if (!m_IsTriggeredSpell || !skipCheck)
+ if (!IsTriggered() || !skipCheck)
{
SpellCastResult castResult = CheckCast(false);
if (castResult != SPELL_CAST_OK)
@@ -3166,7 +3170,7 @@ void Spell::cast(bool skipCheck)
if (m_caster->GetTypeId() == TYPEID_PLAYER)
{
- if (!m_IsTriggeredSpell && m_CastItem)
+ if (!(_triggeredCastFlags & TRIGGERED_IGNORE_CAST_ITEM) && m_CastItem)
{
m_caster->ToPlayer()->GetAchievementMgr().StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_ITEM, m_CastItem->GetEntry());
m_caster->ToPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM, m_CastItem->GetEntry());
@@ -3175,7 +3179,7 @@ void Spell::cast(bool skipCheck)
m_caster->ToPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, m_spellInfo->Id);
}
- if (!m_IsTriggeredSpell)
+ if (!(_triggeredCastFlags & TRIGGERED_IGNORE_POWER_AND_REAGENT_COST))
{
// Powers have to be taken before SendSpellGo
TakePower();
@@ -3481,7 +3485,7 @@ void Spell::SendSpellCooldown()
}
// have infinity cooldown but set at aura apply // do not set cooldown for triggered spells (needed by reincarnation)
- if (m_spellInfo->Attributes & (SPELL_ATTR0_DISABLED_WHILE_ACTIVE | SPELL_ATTR0_PASSIVE) || m_IsTriggeredSpell)
+ if (m_spellInfo->Attributes & (SPELL_ATTR0_DISABLED_WHILE_ACTIVE | SPELL_ATTR0_PASSIVE) || (_triggeredCastFlags & TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD))
return;
_player->AddSpellAndCategoryCooldowns(m_spellInfo, m_CastItem ? m_CastItem->GetEntry() : 0, this);
@@ -3505,7 +3509,7 @@ void Spell::update(uint32 difftime)
(m_spellInfo->Effects[0].Effect != SPELL_EFFECT_STUCK || !m_caster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING)))
{
// don't cancel for melee, autorepeat, triggered and instant spells
- if (!IsNextMeleeSwingSpell() && !IsAutoRepeat() && !m_IsTriggeredSpell)
+ if (!IsNextMeleeSwingSpell() && !IsAutoRepeat() && !IsTriggered())
cancel();
}
@@ -3769,7 +3773,7 @@ void Spell::SendSpellStart()
uint32 castFlags = CAST_FLAG_UNKNOWN_2;
- if ((m_IsTriggeredSpell && !m_spellInfo->IsAutoRepeatRangedSpell()) || m_triggeredByAuraSpell)
+ if ((IsTriggered() && !m_spellInfo->IsAutoRepeatRangedSpell()) || m_triggeredByAuraSpell)
castFlags |= CAST_FLAG_PENDING;
if (m_spellInfo->Attributes & SPELL_ATTR0_REQ_AMMO)
@@ -3822,7 +3826,7 @@ void Spell::SendSpellGo()
uint32 castFlags = CAST_FLAG_UNKNOWN_9;
// triggered spells with spell visual != 0
- if ((m_IsTriggeredSpell && !m_spellInfo->IsAutoRepeatRangedSpell()) || m_triggeredByAuraSpell)
+ if ((IsTriggered() && !m_spellInfo->IsAutoRepeatRangedSpell()) || m_triggeredByAuraSpell)
castFlags |= CAST_FLAG_PENDING;
if (m_spellInfo->Attributes & SPELL_ATTR0_REQ_AMMO)
@@ -4249,7 +4253,7 @@ void Spell::TakeCastItem()
return;
// not remove cast item at triggered spell (equipping, weapon damage, etc)
- if (m_IsTriggeredSpell)
+ if (_triggeredCastFlags & TRIGGERED_IGNORE_CAST_ITEM)
return;
ItemTemplate const *proto = m_CastItem->GetTemplate();
@@ -4507,14 +4511,6 @@ void Spell::TakeRunePower(bool didHit)
void Spell::TakeReagents()
{
- if (m_IsTriggeredSpell) // reagents used in triggered spell removed by original spell or don't must be removed.
- {
- Item* targetItem = m_targets.GetItemTarget();
- /// Not own traded item (in trader trade slot) req. reagents including triggered spell case
- if (!(targetItem && targetItem->GetOwnerGUID() != m_caster->GetGUID()))
- return;
- }
-
if (m_caster->GetTypeId() != TYPEID_PLAYER)
return;
@@ -4609,14 +4605,14 @@ void Spell::HandleEffects(Unit *pUnitTarget, Item *pItemTarget, GameObject *pGOT
SpellCastResult Spell::CheckCast(bool strict)
{
// check death state
- if (!m_IsTriggeredSpell && !m_caster->isAlive() && !(m_spellInfo->Attributes & SPELL_ATTR0_PASSIVE) && !(m_spellInfo->Attributes & SPELL_ATTR0_CASTABLE_WHILE_DEAD))
+ if (!(_triggeredCastFlags & TRIGGERED_IGNORE_CASTER_AURASTATE) && !m_caster->isAlive() && !(m_spellInfo->Attributes & SPELL_ATTR0_PASSIVE) && !(m_spellInfo->Attributes & SPELL_ATTR0_CASTABLE_WHILE_DEAD))
return SPELL_FAILED_CASTER_DEAD;
// check cooldowns to prevent cheating
if (m_caster->GetTypeId() == TYPEID_PLAYER && !(m_spellInfo->Attributes & SPELL_ATTR0_PASSIVE))
{
//can cast triggered (by aura only?) spells while have this flag
- if (!m_IsTriggeredSpell && m_caster->ToPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_ALLOW_ONLY_ABILITY))
+ if (!(_triggeredCastFlags & TRIGGERED_IGNORE_CASTER_AURASTATE) && m_caster->ToPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_ALLOW_ONLY_ABILITY))
return SPELL_FAILED_SPELL_IN_PROGRESS;
if (m_caster->ToPlayer()->HasSpellCooldown(m_spellInfo->Id))
@@ -4632,11 +4628,11 @@ SpellCastResult Spell::CheckCast(bool strict)
return SPELL_FAILED_SPELL_UNAVAILABLE;
// Check global cooldown
- if (strict && !m_IsTriggeredSpell && HasGlobalCooldown())
+ if (strict && !(_triggeredCastFlags & TRIGGERED_IGNORE_GCD) && HasGlobalCooldown())
return SPELL_FAILED_NOT_READY;
- // only allow triggered spells if at an ended battleground
- if (!m_IsTriggeredSpell && m_caster->GetTypeId() == TYPEID_PLAYER)
+ // only triggered spells can be processed an ended battleground
+ if (!IsTriggered() && m_caster->GetTypeId() == TYPEID_PLAYER)
if (Battleground* bg = m_caster->ToPlayer()->GetBattleground())
if (bg->GetStatus() == STATUS_WAIT_LEAVE)
return SPELL_FAILED_DONT_REPORT;
@@ -4654,7 +4650,7 @@ SpellCastResult Spell::CheckCast(bool strict)
// only check at first call, Stealth auras are already removed at second call
// for now, ignore triggered spells
- if (strict && !m_IsTriggeredSpell)
+ if (strict && !(_triggeredCastFlags & TRIGGERED_IGNORE_SHAPESHIFT))
{
bool checkForm = true;
// Ignore form req aura
@@ -4695,7 +4691,7 @@ SpellCastResult Spell::CheckCast(bool strict)
// caster state requirements
// not for triggered spells (needed by execute)
- if (!m_IsTriggeredSpell)
+ if (!(_triggeredCastFlags & TRIGGERED_IGNORE_CASTER_AURASTATE))
{
if (m_spellInfo->CasterAuraState && !m_caster->HasAuraState(AuraStateType(m_spellInfo->CasterAuraState), m_spellInfo, m_caster))
return SPELL_FAILED_CASTER_AURASTATE;
@@ -4722,7 +4718,9 @@ SpellCastResult Spell::CheckCast(bool strict)
return SPELL_FAILED_MOVING;
}
- if (Vehicle* vehicle = m_caster->GetVehicle())
+
+ Vehicle* vehicle = m_caster->GetVehicle();
+ if (vehicle && !(_triggeredCastFlags & TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE))
{
uint16 checkMask = 0;
for (uint8 effIndex = EFFECT_0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
@@ -4757,7 +4755,7 @@ SpellCastResult Spell::CheckCast(bool strict)
if (target)
{
// target state requirements (not allowed state), apply to self also
- if (!m_IsTriggeredSpell && m_spellInfo->TargetAuraStateNot && target->HasAuraState(AuraStateType(m_spellInfo->TargetAuraStateNot), m_spellInfo, m_caster))
+ if (!(_triggeredCastFlags & TRIGGERED_IGNORE_TARGET_AURASTATE) && m_spellInfo->TargetAuraStateNot && target->HasAuraState(AuraStateType(m_spellInfo->TargetAuraStateNot), m_spellInfo, m_caster))
return SPELL_FAILED_TARGET_AURASTATE;
if (m_spellInfo->TargetAuraSpell && !target->HasAura(sSpellMgr->GetSpellIdForDifficulty(m_spellInfo->TargetAuraSpell, m_caster)))
@@ -4766,7 +4764,7 @@ SpellCastResult Spell::CheckCast(bool strict)
if (m_spellInfo->ExcludeTargetAuraSpell && target->HasAura(sSpellMgr->GetSpellIdForDifficulty(m_spellInfo->ExcludeTargetAuraSpell, m_caster)))
return SPELL_FAILED_TARGET_AURASTATE;
- if (!m_IsTriggeredSpell && target == m_caster && m_spellInfo->AttributesEx & SPELL_ATTR1_CANT_TARGET_SELF)
+ if (!IsTriggered() && target == m_caster && m_spellInfo->AttributesEx & SPELL_ATTR1_CANT_TARGET_SELF)
return SPELL_FAILED_BAD_TARGETS;
bool non_caster_target = target != m_caster && m_spellInfo->IsRequiringSelectedTarget();
@@ -4774,14 +4772,14 @@ SpellCastResult Spell::CheckCast(bool strict)
if (non_caster_target)
{
// target state requirements (apply to non-self only), to allow cast affects to self like Dirty Deeds
- if (!m_IsTriggeredSpell && m_spellInfo->TargetAuraState && !target->HasAuraState(AuraStateType(m_spellInfo->TargetAuraState), m_spellInfo, m_caster))
+ if (!(_triggeredCastFlags & TRIGGERED_IGNORE_TARGET_AURASTATE) && m_spellInfo->TargetAuraState && !target->HasAuraState(AuraStateType(m_spellInfo->TargetAuraState), m_spellInfo, m_caster))
return SPELL_FAILED_TARGET_AURASTATE;
// Not allow casting on flying player or on vehicle player (if caster isnt vehicle)
if (target->HasUnitState(UNIT_STAT_IN_FLIGHT) /*|| (target->HasUnitState(UNIT_STAT_ONVEHICLE) && target->GetVehicleBase() != m_caster)*/)
return SPELL_FAILED_BAD_TARGETS;
- if (!m_IsTriggeredSpell && !m_caster->canSeeOrDetect(target))
+ if (!(_triggeredCastFlags & TRIGGERED_IGNORE_TARGET_DETECTABILITY) && !m_caster->canSeeOrDetect(target))
return SPELL_FAILED_BAD_TARGETS;
if (m_caster->GetTypeId() == TYPEID_PLAYER)
@@ -4814,7 +4812,7 @@ SpellCastResult Spell::CheckCast(bool strict)
}
}
- if (!m_IsTriggeredSpell && VMAP::VMapFactory::checkSpellForLoS(m_spellInfo->Id) && !m_caster->IsWithinLOSInMap(target))
+ if (!(_triggeredCastFlags & TRIGGERED_IGNORE_LOS) && VMAP::VMapFactory::checkSpellForLoS(m_spellInfo->Id) && !m_caster->IsWithinLOSInMap(target))
return SPELL_FAILED_LINE_OF_SIGHT;
}
@@ -4916,7 +4914,7 @@ SpellCastResult Spell::CheckCast(bool strict)
}
// not let players cast spells at mount (and let do it to creatures)
- if (m_caster->IsMounted() && m_caster->GetTypeId() == TYPEID_PLAYER && !m_IsTriggeredSpell &&
+ if (m_caster->IsMounted() && m_caster->GetTypeId() == TYPEID_PLAYER && !(_triggeredCastFlags & TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE) &&
!m_spellInfo->IsPassive() && !(m_spellInfo->Attributes & SPELL_ATTR0_CASTABLE_WHILE_MOUNTED))
{
if (m_caster->isInFlight())
@@ -4941,12 +4939,15 @@ SpellCastResult Spell::CheckCast(bool strict)
if (castResult != SPELL_CAST_OK)
return castResult;
- if (!m_IsTriggeredSpell)
+ if (!(_triggeredCastFlags & TRIGGERED_IGNORE_POWER_AND_REAGENT_COST))
{
castResult = CheckPower();
if (castResult != SPELL_CAST_OK)
return castResult;
-
+ }
+
+ if (!(_triggeredCastFlags & TRIGGERED_IGNORE_CASTER_AURAS))
+ {
castResult = CheckCasterAuras();
if (castResult != SPELL_CAST_OK)
return castResult;
@@ -5446,11 +5447,11 @@ SpellCastResult Spell::CheckCast(bool strict)
return SPELL_FAILED_ONLY_ABOVEWATER;
// Ignore map check if spell have AreaId. AreaId already checked and this prevent special mount spells
- bool AllowMount = !m_caster->GetMap()->IsDungeon() || m_caster->GetMap()->IsBattlegroundOrArena();
+ bool allowMount = !m_caster->GetMap()->IsDungeon() || m_caster->GetMap()->IsBattlegroundOrArena();
InstanceTemplate const *it = sObjectMgr->GetInstanceTemplate(m_caster->GetMapId());
if (it)
- AllowMount = it->AllowMount;
- if (m_caster->GetTypeId() == TYPEID_PLAYER && !AllowMount && !m_IsTriggeredSpell && !m_spellInfo->AreaGroupId)
+ allowMount = it->AllowMount;
+ if (m_caster->GetTypeId() == TYPEID_PLAYER && !allowMount && !m_spellInfo->AreaGroupId)
return SPELL_FAILED_NO_MOUNTS_ALLOWED;
if (m_caster->IsInDisallowedMountForm())
@@ -5478,7 +5479,7 @@ SpellCastResult Spell::CheckCast(bool strict)
{
if (AreaTableEntry const* pArea = GetAreaEntryByAreaID(m_originalCaster->GetAreaId()))
if (pArea->flags & AREA_FLAG_NO_FLY_ZONE)
- return m_IsTriggeredSpell ? SPELL_FAILED_DONT_REPORT : SPELL_FAILED_NOT_HERE;
+ return (_triggeredCastFlags & TRIGGERED_DONT_REPORT_CAST_ERROR) ? SPELL_FAILED_DONT_REPORT : SPELL_FAILED_NOT_HERE;
}
break;
}
@@ -5518,7 +5519,7 @@ SpellCastResult Spell::CheckCast(bool strict)
if (slot != TRADE_SLOT_NONTRADED)
return SPELL_FAILED_BAD_TARGETS;
- if (!m_IsTriggeredSpell)
+ if (!IsTriggered())
if (my_trade->GetSpell())
return SPELL_FAILED_ITEM_ALREADY_ENCHANTED;
}
@@ -5538,7 +5539,7 @@ SpellCastResult Spell::CheckPetCast(Unit* target)
if (!m_caster->isAlive() && !(m_spellInfo->Attributes & SPELL_ATTR0_CASTABLE_WHILE_DEAD))
return SPELL_FAILED_CASTER_DEAD;
- if (m_caster->HasUnitState(UNIT_STAT_CASTING) && !m_IsTriggeredSpell) //prevent spellcast interruption by another spellcast
+ if (m_caster->HasUnitState(UNIT_STAT_CASTING) && !(_triggeredCastFlags & TRIGGERED_IGNORE_CAST_IN_PROGRESS)) //prevent spellcast interruption by another spellcast
return SPELL_FAILED_SPELL_IN_PROGRESS;
if (m_caster->isInCombat() && !m_spellInfo->CanBeUsedInCombat())
return SPELL_FAILED_AFFECTING_COMBAT;
@@ -5764,22 +5765,22 @@ SpellCastResult Spell::CheckRange(bool strict)
{
// Because of lag, we can not check too strictly here.
if (!m_caster->IsWithinMeleeRange(target, max_range))
- return !m_IsTriggeredSpell ? SPELL_FAILED_OUT_OF_RANGE : SPELL_FAILED_DONT_REPORT;
+ return !(_triggeredCastFlags & TRIGGERED_DONT_REPORT_CAST_ERROR) ? SPELL_FAILED_OUT_OF_RANGE : SPELL_FAILED_DONT_REPORT;
}
else if (!m_caster->IsWithinCombatRange(target, max_range))
- return !m_IsTriggeredSpell ? SPELL_FAILED_OUT_OF_RANGE : SPELL_FAILED_DONT_REPORT; //0x5A;
+ return !(_triggeredCastFlags & TRIGGERED_DONT_REPORT_CAST_ERROR) ? SPELL_FAILED_OUT_OF_RANGE : SPELL_FAILED_DONT_REPORT; //0x5A;
if (range_type == SPELL_RANGE_RANGED)
{
if (m_caster->IsWithinMeleeRange(target))
- return !m_IsTriggeredSpell ? SPELL_FAILED_TOO_CLOSE : SPELL_FAILED_DONT_REPORT;
+ return !(_triggeredCastFlags & TRIGGERED_DONT_REPORT_CAST_ERROR) ? SPELL_FAILED_TOO_CLOSE : SPELL_FAILED_DONT_REPORT;
}
else if (min_range && m_caster->IsWithinCombatRange(target, min_range)) // skip this check if min_range = 0
- return !m_IsTriggeredSpell ? SPELL_FAILED_TOO_CLOSE : SPELL_FAILED_DONT_REPORT;
+ return !(_triggeredCastFlags & TRIGGERED_DONT_REPORT_CAST_ERROR) ? SPELL_FAILED_TOO_CLOSE : SPELL_FAILED_DONT_REPORT;
if (m_caster->GetTypeId() == TYPEID_PLAYER &&
(m_spellInfo->FacingCasterFlags & SPELL_FACING_FLAG_INFRONT) && !m_caster->HasInArc(static_cast<float>(M_PI), target))
- return !m_IsTriggeredSpell ? SPELL_FAILED_UNIT_NOT_INFRONT : SPELL_FAILED_DONT_REPORT;
+ return !(_triggeredCastFlags & TRIGGERED_DONT_REPORT_CAST_ERROR) ? SPELL_FAILED_UNIT_NOT_INFRONT : SPELL_FAILED_DONT_REPORT;
}
if (m_targets.HasDst() && !m_targets.HasTraj())
@@ -5951,7 +5952,7 @@ SpellCastResult Spell::CheckItems()
// do not take reagents for these item casts
if (!(m_CastItem && m_CastItem->GetTemplate()->Flags & ITEM_PROTO_FLAG_TRIGGERED_CAST))
{
- bool checkReagents = !m_IsTriggeredSpell && !p_caster->CanNoReagentCast(m_spellInfo);
+ bool checkReagents = !(_triggeredCastFlags & TRIGGERED_IGNORE_POWER_AND_REAGENT_COST) && !p_caster->CanNoReagentCast(m_spellInfo);
// Not own traded item (in trader trade slot) requires reagents even if triggered spell
if (!checkReagents)
if (Item* targetItem = m_targets.GetItemTarget())
@@ -6035,7 +6036,7 @@ SpellCastResult Spell::CheckItems()
case SPELL_EFFECT_CREATE_ITEM:
case SPELL_EFFECT_CREATE_ITEM_2:
{
- if (!m_IsTriggeredSpell && m_spellInfo->Effects[i].ItemType)
+ if (!IsTriggered() && m_spellInfo->Effects[i].ItemType)
{
ItemPosCountVec dest;
InventoryResult msg = p_caster->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, 1);
@@ -6312,11 +6313,11 @@ SpellCastResult Spell::CheckItems()
// skip spell if no weapon in slot or broken
if (!item || item->IsBroken())
- return m_IsTriggeredSpell? SPELL_FAILED_DONT_REPORT : SPELL_FAILED_EQUIPPED_ITEM_CLASS;
+ return (_triggeredCastFlags & TRIGGERED_DONT_REPORT_CAST_ERROR) ? SPELL_FAILED_DONT_REPORT : SPELL_FAILED_EQUIPPED_ITEM_CLASS;
// skip spell if weapon not fit to triggered spell
if (!item->IsFitToSpellRequirements(m_spellInfo))
- return m_IsTriggeredSpell? SPELL_FAILED_DONT_REPORT : SPELL_FAILED_EQUIPPED_ITEM_CLASS;
+ return (_triggeredCastFlags & TRIGGERED_DONT_REPORT_CAST_ERROR) ? SPELL_FAILED_DONT_REPORT : SPELL_FAILED_EQUIPPED_ITEM_CLASS;
}
// offhand hand weapon required
@@ -6326,11 +6327,11 @@ SpellCastResult Spell::CheckItems()
// skip spell if no weapon in slot or broken
if (!item || item->IsBroken())
- return m_IsTriggeredSpell? SPELL_FAILED_DONT_REPORT : SPELL_FAILED_EQUIPPED_ITEM_CLASS;
+ return (_triggeredCastFlags & TRIGGERED_DONT_REPORT_CAST_ERROR) ? SPELL_FAILED_DONT_REPORT : SPELL_FAILED_EQUIPPED_ITEM_CLASS;
// skip spell if weapon not fit to triggered spell
if (!item->IsFitToSpellRequirements(m_spellInfo))
- return m_IsTriggeredSpell? SPELL_FAILED_DONT_REPORT : SPELL_FAILED_EQUIPPED_ITEM_CLASS;
+ return (_triggeredCastFlags & TRIGGERED_DONT_REPORT_CAST_ERROR) ? SPELL_FAILED_DONT_REPORT : SPELL_FAILED_EQUIPPED_ITEM_CLASS;
}
}
@@ -6542,7 +6543,7 @@ bool Spell::CheckTarget(Unit* target, uint32 eff)
}
//Do not do further checks for triggered spells
- if (m_IsTriggeredSpell)
+ if (IsTriggered())
return true;
//Check targets for LOS visibility (except spells without range limitations)
@@ -6598,13 +6599,13 @@ bool Spell::IsNextMeleeSwingSpell() const
bool Spell::IsAutoActionResetSpell() const
{
- return !m_IsTriggeredSpell && (m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_AUTOATTACK);
+ return !IsTriggered() && (m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_AUTOATTACK);
}
bool Spell::IsNeedSendToClient() const
{
return m_spellInfo->SpellVisual[0] || m_spellInfo->SpellVisual[1] || m_spellInfo->IsChanneled() ||
- m_spellInfo->Speed > 0.0f || (!m_triggeredByAuraSpell && !m_IsTriggeredSpell);
+ m_spellInfo->Speed > 0.0f || (!m_triggeredByAuraSpell && !IsTriggered());
}
bool Spell::HaveTargetsForEffect(uint8 effect) const
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index c4a86788482..9007f44e26d 100755
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -379,7 +379,7 @@ class Spell
typedef std::set<Aura*> UsedSpellMods;
- Spell(Unit* Caster, SpellInfo const *info, bool triggered, uint64 originalCasterGUID = 0, bool skipCheck = false);
+ Spell(Unit* caster, SpellInfo const *info, TriggerCastFlags triggerFlags, uint64 originalCasterGUID = 0, bool skipCheck = false);
~Spell();
void prepare(SpellCastTargets const* targets, AuraEffect const* triggeredByAura = NULL);
@@ -474,7 +474,7 @@ class Spell
void SetAutoRepeat(bool rep) { m_autoRepeat = rep; }
void ReSetTimer() { m_timer = m_casttime > 0 ? m_casttime : 0; }
bool IsNextMeleeSwingSpell() const;
- bool IsTriggered() const {return m_IsTriggeredSpell;};
+ bool IsTriggered() const {return _triggeredCastFlags & TRIGGERED_FULL_MASK;};
bool IsChannelActive() const { return m_caster->GetUInt32Value(UNIT_CHANNEL_SPELL) != 0; }
bool IsAutoActionResetSpell() const;
@@ -672,7 +672,7 @@ class Spell
uint32 m_spellState;
uint32 m_timer;
- bool m_IsTriggeredSpell;
+ TriggerCastFlags _triggeredCastFlags;
// if need this can be replaced by Aura copy
// we can't store original aura link to prevent access to deleted auras
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index d726e874f27..f35b8c5123d 100755
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -1504,7 +1504,7 @@ void Spell::EffectDummy(SpellEffIndex effIndex)
}
targets.SetUnitTarget(unitTarget);
- Spell* spell = new Spell(m_caster, spellInfo, triggered, m_originalCasterGUID, true);
+ Spell* spell = new Spell(m_caster, spellInfo, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE, m_originalCasterGUID, true);
if (bp) spell->SetSpellValue(SPELLVALUE_BASE_POINT0, bp);
spell->prepare(&targets);
}
@@ -3570,7 +3570,7 @@ void Spell::EffectEnchantItemTmp(SpellEffIndex effIndex)
{
if (item->IsFitToSpellRequirements(m_spellInfo))
{
- Spell* spell = new Spell(m_caster, spellInfo, true);
+ Spell* spell = new Spell(m_caster, spellInfo, TRIGGERED_FULL_MASK);
SpellCastTargets targets;
targets.SetItemTarget(item);
spell->prepare(&targets);
@@ -5490,7 +5490,7 @@ void Spell::EffectStuck(SpellEffIndex /*effIndex*/)
SpellInfo const *spellInfo = sSpellMgr->GetSpellInfo(8690);
if (!spellInfo)
return;
- Spell spell(pTarget, spellInfo, true, 0);
+ Spell spell(pTarget, spellInfo, TRIGGERED_FULL_MASK);
spell.SendSpellCooldown();
}
@@ -6980,14 +6980,12 @@ void Spell::EffectCastButtons(SpellEffIndex effIndex)
if (!p_caster->HasSpell(spell_id) || p_caster->HasSpellCooldown(spell_id))
continue;
- //! Valid totem spells only have the first TotemCategory field set, so only check this
- if (spellInfo->TotemCategory[0] < TC_EARTH_TOTEM || spellInfo->TotemCategory[0] > TC_WATER_TOTEM)
+ if (!(spellInfo->AttributesEx7 & SPELL_ATTR7_SUMMON_PLAYER_TOTEM))
continue;
uint32 cost = spellInfo->CalcPowerCost(m_caster, spellInfo->GetSchoolMask());
-
if (m_caster->GetPower(POWER_MANA) < cost)
- break;
+ continue;
m_caster->CastSpell(unitTarget, spell_id, true);
m_caster->ModifyPower(POWER_MANA, -(int32)cost);