diff options
| author | Machiavelli <machiavelli.trinity@gmail.com> | 2011-07-31 19:03:06 +0200 |
|---|---|---|
| committer | Machiavelli <machiavelli.trinity@gmail.com> | 2011-07-31 21:58:25 +0200 |
| commit | 58f10c74f72f4bdf00dcf200ce11528d005906cd (patch) | |
| tree | 36c1239988cde21d760342dad8550b51c02c3c30 /src/server/game/Spells | |
| parent | 8753a182631cc7930e7c652092b7176812932435 (diff) | |
Core/Spells: Change low level bool triggered with bitmask TriggerCastFlags to better manipulate the behaviour of certain triggered spells.
Diffstat (limited to 'src/server/game/Spells')
| -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 |
3 files changed, 75 insertions, 76 deletions
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); |
