diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/server/game/AI/CoreAI/PetAI.cpp | 2 | ||||
-rw-r--r-- | src/server/game/AI/ScriptedAI/ScriptedCreature.cpp | 2 | ||||
-rwxr-xr-x | src/server/game/Entities/Player/Player.cpp | 6 | ||||
-rwxr-xr-x | src/server/game/Entities/Unit/Unit.cpp | 26 | ||||
-rwxr-xr-x | src/server/game/Entities/Unit/Unit.h | 31 | ||||
-rwxr-xr-x | src/server/game/Server/Protocol/Handlers/PetHandler.cpp | 4 | ||||
-rwxr-xr-x | src/server/game/Server/Protocol/Handlers/SpellHandler.cpp | 2 | ||||
-rwxr-xr-x | src/server/game/Server/Protocol/Handlers/TradeHandler.cpp | 4 | ||||
-rwxr-xr-x | src/server/game/Spells/Spell.cpp | 133 | ||||
-rwxr-xr-x | src/server/game/Spells/Spell.h | 6 | ||||
-rwxr-xr-x | src/server/game/Spells/SpellEffects.cpp | 12 |
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); |