Core/Spells: Change low level bool triggered with bitmask TriggerCastFlags to better manipulate the behaviour of certain triggered spells.
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user