diff options
Diffstat (limited to 'src/server/game/Spells/Spell.cpp')
| -rwxr-xr-x | src/server/game/Spells/Spell.cpp | 324 |
1 files changed, 153 insertions, 171 deletions
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index d833782bc76..54b3ae310e2 100755 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -828,7 +828,7 @@ void Spell::SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTar break; } - switch(targetType.GetSelectionCategory()) + switch (targetType.GetSelectionCategory()) { case TARGET_SELECT_CATEGORY_CHANNEL: SelectImplicitChannelTargets(effIndex, targetType); @@ -846,7 +846,7 @@ void Spell::SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTar switch (targetType.GetObjectType()) { case TARGET_OBJECT_TYPE_SRC: - switch(targetType.GetReferenceType()) + switch (targetType.GetReferenceType()) { case TARGET_REFERENCE_TYPE_CASTER: m_targets.SetSrc(*m_caster); @@ -857,7 +857,7 @@ void Spell::SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTar } break; case TARGET_OBJECT_TYPE_DEST: - switch(targetType.GetReferenceType()) + switch (targetType.GetReferenceType()) { case TARGET_REFERENCE_TYPE_CASTER: SelectImplicitCasterDestTargets(effIndex, targetType); @@ -874,7 +874,7 @@ void Spell::SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTar } break; default: - switch(targetType.GetReferenceType()) + switch (targetType.GetReferenceType()) { case TARGET_REFERENCE_TYPE_CASTER: SelectImplicitCasterObjectTargets(effIndex, targetType); @@ -915,17 +915,25 @@ void Spell::SelectImplicitChannelTargets(SpellEffIndex effIndex, SpellImplicitTa switch (targetType.GetTarget()) { case TARGET_UNIT_CHANNEL_TARGET: + { + WorldObject* target = ObjectAccessor::GetUnit(*m_caster, channeledSpell->m_targets.GetUnitTargetGUID()); + CallScriptObjectTargetSelectHandlers(target, effIndex); // unit target may be no longer avalible - teleported out of map for example - if (Unit* target = Unit::GetUnit(*m_caster, channeledSpell->m_targets.GetUnitTargetGUID())) - AddUnitTarget(target, 1 << effIndex); + if (target && target->ToUnit()) + AddUnitTarget(target->ToUnit(), 1 << effIndex); else sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "SPELL: cannot find channel spell target for spell ID %u, effect %u", m_spellInfo->Id, effIndex); break; + } case TARGET_DEST_CHANNEL_TARGET: if (channeledSpell->m_targets.HasDst()) m_targets.SetDst(channeledSpell->m_targets); else if (WorldObject* target = ObjectAccessor::GetWorldObject(*m_caster, channeledSpell->m_targets.GetObjectTargetGUID())) - m_targets.SetDst(*target); + { + CallScriptObjectTargetSelectHandlers(target, effIndex); + if (target) + m_targets.SetDst(*target); + } else sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "SPELL: cannot find channel spell destination for spell ID %u, effect %u", m_spellInfo->Id, effIndex); break; @@ -1003,6 +1011,8 @@ void Spell::SelectImplicitNearbyTargets(SpellEffIndex effIndex, SpellImplicitTar return; } + CallScriptObjectTargetSelectHandlers(target, effIndex); + switch (targetType.GetObjectType()) { case TARGET_OBJECT_TYPE_UNIT: @@ -1042,7 +1052,9 @@ void Spell::SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTarge { Trinity::WorldObjectSpellConeTargetCheck check(coneAngle, radius, m_caster, m_spellInfo, selectionType, condList); Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellConeTargetCheck> searcher(m_caster, targets, check, containerTypeMask); - SearchTargets<Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellConeTargetCheck> > (searcher, containerTypeMask, m_caster, m_caster, radius); + SearchTargets<Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellConeTargetCheck> >(searcher, containerTypeMask, m_caster, m_caster, radius); + + CallScriptObjectAreaTargetSelectHandlers(targets, effIndex); if (!targets.empty()) { @@ -1070,8 +1082,6 @@ void Spell::SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTarge gObjTargets.push_back(gObjTarget); } - CallScriptAfterUnitTargetSelectHandlers(unitTargets, effIndex); - for (std::list<Unit*>::iterator itr = unitTargets.begin(); itr != unitTargets.end(); ++itr) AddUnitTarget(*itr, effMask, false); @@ -1206,6 +1216,9 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge default: break; } + + CallScriptObjectAreaTargetSelectHandlers(targets, effIndex); + std::list<Unit*> unitTargets; std::list<GameObject*> gObjTargets; // for compability with older code - add only unit and go targets @@ -1287,18 +1300,6 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge maxSize = m_caster->HasAura(62970) ? 6 : 5; // Glyph of Wild Growth power = POWER_HEALTH; } - else if (m_spellInfo->SpellFamilyFlags[2] == 0x0100) // Starfall - { - // Remove targets not in LoS or in stealth - for (std::list<Unit*>::iterator itr = unitTargets.begin(); itr != unitTargets.end();) - { - if ((*itr)->HasStealthAura() || (*itr)->HasInvisibilityAura() || !(*itr)->IsWithinLOSInMap(m_caster)) - itr = unitTargets.erase(itr); - else - ++itr; - } - break; - } else break; @@ -1339,6 +1340,11 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge } } + // todo: move to scripts, but we must call it before resize list by MaxAffectedTargets + // Intimidating Shout + if (m_spellInfo->Id == 5246 && effIndex != EFFECT_0) + unitTargets.remove(m_targets.GetUnitTarget()); + // Other special target selection goes here if (uint32 maxTargets = m_spellValue->MaxAffectedTargets) { @@ -1347,13 +1353,9 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge if ((*j)->IsAffectingSpell(m_spellInfo)) maxTargets += (*j)->GetAmount(); - if (m_spellInfo->Id == 5246) //Intimidating Shout - unitTargets.remove(m_targets.GetUnitTarget()); Trinity::Containers::RandomResizeList(unitTargets, maxTargets); } - CallScriptAfterUnitTargetSelectHandlers(unitTargets, effIndex); - for (std::list<Unit*>::iterator itr = unitTargets.begin(); itr != unitTargets.end(); ++itr) AddUnitTarget(*itr, effMask, false); } @@ -1369,6 +1371,7 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge Trinity::Containers::RandomResizeList(gObjTargets, maxTargets); } + for (std::list<GameObject*>::iterator itr = gObjTargets.begin(); itr != gObjTargets.end(); ++itr) AddGOTarget(*itr, effMask); } @@ -1376,7 +1379,7 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType) { - switch(targetType.GetTarget()) + switch (targetType.GetTarget()) { case TARGET_DEST_CASTER: m_targets.SetDst(*m_caster); @@ -1441,7 +1444,7 @@ void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplici void Spell::SelectImplicitTargetDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType) { WorldObject* target = m_targets.GetObjectTarget(); - switch(targetType.GetTarget()) + switch (targetType.GetTarget()) { case TARGET_DEST_TARGET_ENEMY: case TARGET_DEST_TARGET_ANY: @@ -1474,7 +1477,7 @@ void Spell::SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitT if (!m_targets.HasDst()) m_targets.SetDst(*m_caster); - switch(targetType.GetTarget()) + switch (targetType.GetTarget()) { case TARGET_DEST_DYNOBJ_ENEMY: case TARGET_DEST_DYNOBJ_ALLY: @@ -1500,27 +1503,27 @@ void Spell::SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitT void Spell::SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType) { - switch(targetType.GetTarget()) + WorldObject* target = NULL; + bool checkIfValid = true; + + switch (targetType.GetTarget()) { case TARGET_UNIT_CASTER: - AddUnitTarget(m_caster, 1 << effIndex, false); + target = m_caster; + checkIfValid = false; break; case TARGET_UNIT_MASTER: - if (Unit* owner = m_caster->GetCharmerOrOwner()) - AddUnitTarget(owner, 1 << effIndex); + target = m_caster->GetCharmerOrOwner(); break; case TARGET_UNIT_PET: - if (Guardian* pet = m_caster->GetGuardianPet()) - AddUnitTarget(pet, 1 << effIndex); + target = m_caster->GetGuardianPet(); break; case TARGET_UNIT_SUMMONER: if (m_caster->isSummon()) - if (Unit* unit = m_caster->ToTempSummon()->GetSummoner()) - AddUnitTarget(unit, 1 << effIndex); + target = m_caster->ToTempSummon()->GetSummoner(); break; case TARGET_UNIT_VEHICLE: - if (Unit *vehicle = m_caster->GetVehicleBase()) - AddUnitTarget(vehicle, 1 << effIndex); + target = m_caster->GetVehicleBase(); break; case TARGET_UNIT_PASSENGER_0: case TARGET_UNIT_PASSENGER_1: @@ -1531,26 +1534,38 @@ void Spell::SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImpli case TARGET_UNIT_PASSENGER_6: case TARGET_UNIT_PASSENGER_7: if (m_caster->GetTypeId() == TYPEID_UNIT && m_caster->ToCreature()->IsVehicle()) - if (Unit *unit = m_caster->GetVehicleKit()->GetPassenger(targetType.GetTarget() - TARGET_UNIT_PASSENGER_0)) - AddUnitTarget(unit, 1 << effIndex); + target = m_caster->GetVehicleKit()->GetPassenger(targetType.GetTarget() - TARGET_UNIT_PASSENGER_0); break; default: break; } + + CallScriptObjectTargetSelectHandlers(target, effIndex); + + if (target && target->ToUnit()) + AddUnitTarget(target->ToUnit(), 1 << effIndex, checkIfValid); } void Spell::SelectImplicitTargetObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType) { ASSERT((m_targets.GetObjectTarget() || m_targets.GetItemTarget()) && "Spell::SelectImplicitTargetObjectTargets - no explicit object or item target available!"); - if (Unit* unit = m_targets.GetUnitTarget()) - AddUnitTarget(unit, 1 << effIndex, true, false); - else if (GameObject* gobj = m_targets.GetGOTarget()) - AddGOTarget(gobj, 1 << effIndex); - else - AddItemTarget(m_targets.GetItemTarget(), 1 << effIndex); - if (WorldObject* target = m_targets.GetObjectTarget()) + WorldObject* target = m_targets.GetObjectTarget(); + + CallScriptObjectTargetSelectHandlers(target, effIndex); + + if (target) + { + if (Unit* unit = target->ToUnit()) + AddUnitTarget(unit, 1 << effIndex, true, false); + else if (GameObject* gobj = target->ToGameObject()) + AddGOTarget(gobj, 1 << effIndex); + SelectImplicitChainTargets(effIndex, targetType, target, 1 << effIndex); + } + // Script hook can remove object target and we would wrongly land here + else if (Item* item = m_targets.GetItemTarget()) + AddItemTarget(item, 1 << effIndex); } void Spell::SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, WorldObject* target, uint32 effMask) @@ -1571,14 +1586,15 @@ void Spell::SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTarg SearchChainTargets(targets, maxTargets - 1, target, targetType.GetObjectType(), targetType.GetCheckType() , m_spellInfo->Effects[effIndex].ImplicitTargetConditions, targetType.GetTarget() == TARGET_UNIT_TARGET_CHAINHEAL_ALLY); + // Chain primary target is added earlier + CallScriptObjectAreaTargetSelectHandlers(targets, effIndex); + // for backward compability std::list<Unit*> unitTargets; for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr) if (Unit* unitTarget = (*itr)->ToUnit()) unitTargets.push_back(unitTarget); - CallScriptAfterUnitTargetSelectHandlers(unitTargets, effIndex); - for (std::list<Unit*>::iterator itr = unitTargets.begin(); itr != unitTargets.end(); ++itr) AddUnitTarget(*itr, effMask, false); } @@ -1741,9 +1757,12 @@ void Spell::SelectEffectTypeImplicitTargets(uint8 effIndex) case SPELL_EFFECT_SUMMON_PLAYER: if (m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->ToPlayer()->GetSelection()) { - Player* target = ObjectAccessor::FindPlayer(m_caster->ToPlayer()->GetSelection()); - if (target) - AddUnitTarget(target, 1 << effIndex, false); + WorldObject* target = ObjectAccessor::FindPlayer(m_caster->ToPlayer()->GetSelection()); + + CallScriptObjectTargetSelectHandlers(target, SpellEffIndex(effIndex)); + + if (target && target->ToPlayer()) + AddUnitTarget(target->ToUnit(), 1 << effIndex, false); } return; default: @@ -1759,6 +1778,8 @@ void Spell::SelectEffectTypeImplicitTargets(uint8 effIndex) if (!targetMask) return; + WorldObject* target = NULL; + switch (m_spellInfo->Effects[effIndex].GetImplicitTargetType()) { // add explicit object target or self to the target map @@ -1767,40 +1788,46 @@ void Spell::SelectEffectTypeImplicitTargets(uint8 effIndex) if (targetMask & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_CORPSE_MASK)) { if (Unit* unitTarget = m_targets.GetUnitTarget()) - AddUnitTarget(unitTarget, 1 << effIndex, false); + target = unitTarget; else if (targetMask & TARGET_FLAG_CORPSE_MASK) { if (Corpse* corpseTarget = m_targets.GetCorpseTarget()) { // TODO: this is a workaround - corpses should be added to spell target map too, but we can't do that so we add owner instead if (Player* owner = ObjectAccessor::FindPlayer(corpseTarget->GetOwnerGUID())) - AddUnitTarget(owner, 1 << effIndex, false); + target = owner; } } else //if (targetMask & TARGET_FLAG_UNIT_MASK) - { - AddUnitTarget(m_caster, 1 << effIndex, false); - } + target = m_caster; } if (targetMask & TARGET_FLAG_ITEM_MASK) { if (Item* itemTarget = m_targets.GetItemTarget()) AddItemTarget(itemTarget, 1 << effIndex); + return; } if (targetMask & TARGET_FLAG_GAMEOBJECT_MASK) - { - if (GameObject* gObjTarget = m_targets.GetGOTarget()) - AddGOTarget(gObjTarget, 1 << effIndex); - } + target = m_targets.GetGOTarget(); break; // add self to the target map case EFFECT_IMPLICIT_TARGET_CASTER: if (targetMask & TARGET_FLAG_UNIT_MASK) - AddUnitTarget(m_caster, 1 << effIndex, false); + target = m_caster; break; default: break; } + + CallScriptObjectTargetSelectHandlers(target, SpellEffIndex(effIndex)); + + if (target) + { + if (target->ToUnit()) + AddUnitTarget(target->ToUnit(), 1 << effIndex, false); + else if (target->ToGameObject()) + AddGOTarget(target->ToGameObject(), 1 << effIndex); + } } uint32 Spell::GetSearcherTypeMask(SpellTargetObjectTypes objType, ConditionList* condList) @@ -2474,12 +2501,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) caster->ToPlayer()->CastItemCombatSpell(unitTarget, m_attackType, procVictim, procEx); } - // Haunt - if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellInfo->SpellFamilyFlags[1] & 0x40000 && m_spellAura && m_spellAura->GetEffect(1)) - { - AuraEffect* aurEff = m_spellAura->GetEffect(1); - aurEff->SetAmount(CalculatePctU(aurEff->GetAmount(), damageInfo.damage)); - } + m_damage = damageInfo.damage; @@ -2548,12 +2570,31 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA return SPELL_MISS_EVADE; // For delayed spells immunity may be applied between missile launch and hit - check immunity for that case + if (m_spellInfo->Speed && (unit->IsImmunedToDamage(m_spellInfo) || unit->IsImmunedToSpell(m_spellInfo))) + return SPELL_MISS_IMMUNE; + // disable effects to which unit is immune + SpellMissInfo returnVal = SPELL_MISS_IMMUNE; for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber) - if (effectMask & (1 << effectNumber) && unit->IsImmunedToSpellEffect(m_spellInfo, effectNumber)) - effectMask &= ~(1 << effectNumber); - if (!effectMask || (m_spellInfo->Speed && (unit->IsImmunedToDamage(m_spellInfo) || unit->IsImmunedToSpell(m_spellInfo)))) - return SPELL_MISS_IMMUNE; + { + if (effectMask & (1 << effectNumber)) + if (unit->IsImmunedToSpellEffect(m_spellInfo, effectNumber)) + effectMask &= ~(1 << effectNumber); + else if (m_spellInfo->Effects[effectNumber].IsAura() && !m_spellInfo->IsPositiveEffect(effectNumber)) + { + int32 debuff_resist_chance = unit->GetMaxPositiveAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel)); + debuff_resist_chance += unit->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel)); + + if (debuff_resist_chance > 0) + if (irand(0,10000) <= (debuff_resist_chance * 100)) + { + effectMask &= ~(1 << effectNumber); + returnVal = SPELL_MISS_RESIST; + } + } + } + if (!effectMask) + return returnVal; PrepareScriptHitHandlers(); CallScriptBeforeHitHandlers(); @@ -3855,7 +3896,7 @@ void Spell::SendSpellStart() data << uint8(0); // unkByte // if (unkByte == 2) // data.append(0); - + } m_caster->SendMessageToSet(&data, true); @@ -3876,6 +3917,7 @@ void Spell::SendSpellGo() castFlags |= CAST_FLAG_PENDING; + if ((m_caster->GetTypeId() == TYPEID_PLAYER || (m_caster->GetTypeId() == TYPEID_UNIT && m_caster->ToCreature()->isPet())) && m_spellInfo->PowerType != POWER_HEALTH) @@ -4804,19 +4846,9 @@ SpellCastResult Spell::CheckCast(bool strict) if (!(m_spellInfo->AttributesEx2 & SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) && VMAP::VMapFactory::checkSpellForLoS(m_spellInfo->Id) && !m_caster->IsWithinLOSInMap(target)) return SPELL_FAILED_LINE_OF_SIGHT; } - else - { - if (m_caster->GetTypeId() == TYPEID_PLAYER) // Target - is player caster - { - // Lay on Hands - cannot be self-cast on paladin with Forbearance or after using Avenging Wrath - if (m_spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN && m_spellInfo->SpellFamilyFlags[0] & 0x0008000) - if (target->HasAura(61988)) // Immunity shield marker - return SPELL_FAILED_TARGET_AURASTATE; - } - } } - //Check for line of sight for spells with dest + // Check for line of sight for spells with dest if (m_targets.HasDst()) { float x, y, z; @@ -4915,7 +4947,9 @@ SpellCastResult Spell::CheckCast(bool strict) bool hasDispellableAura = false; bool hasNonDispelEffect = false; - for (int i = 0; i < MAX_SPELL_EFFECTS; i++) + uint32 dispelMask = 0; + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + { if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_DISPEL) { if (m_spellInfo->Effects[i].IsTargetingArea() || m_spellInfo->AttributesEx & SPELL_ATTR1_MELEE_COMBAT_START) @@ -4923,28 +4957,28 @@ SpellCastResult Spell::CheckCast(bool strict) hasDispellableAura = true; break; } - if (Unit* target = m_targets.GetUnitTarget()) - { - DispelChargesList dispelList; - uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue)); - target->GetDispellableAuraList(m_caster, dispelMask, dispelList); - if (!dispelList.empty()) - { - hasDispellableAura = true; - break; - } - } + + dispelMask |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue)); } else if (m_spellInfo->Effects[i].IsEffect()) { hasNonDispelEffect = true; break; } + } - if (!hasNonDispelEffect && !hasDispellableAura && m_spellInfo->HasEffect(SPELL_EFFECT_DISPEL) && !IsTriggered()) - return SPELL_FAILED_NOTHING_TO_DISPEL; + if (!hasNonDispelEffect && !hasDispellableAura && dispelMask && !IsTriggered()) + { + if (Unit* target = m_targets.GetUnitTarget()) + { + DispelChargesList dispelList; + target->GetDispellableAuraList(m_caster, dispelMask, dispelList); + if (dispelList.empty()) + return SPELL_FAILED_NOTHING_TO_DISPEL; + } + } - for (int i = 0; i < MAX_SPELL_EFFECTS; i++) + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) { // for effects of spells that have only one target switch (m_spellInfo->Effects[i].Effect) @@ -5285,10 +5319,6 @@ SpellCastResult Spell::CheckCast(bool strict) } case SPELL_EFFECT_LEAP_BACK: { - // Spell 781 (Disengage) requires player to be in combat - if (m_caster->GetTypeId() == TYPEID_PLAYER && m_spellInfo->Id == 781 && !m_caster->isInCombat()) - return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW; - if (m_caster->HasUnitState(UNIT_STATE_ROOT)) { if (m_caster->GetTypeId() == TYPEID_PLAYER) @@ -5310,66 +5340,10 @@ SpellCastResult Spell::CheckCast(bool strict) } } - for (int i = 0; i < MAX_SPELL_EFFECTS; i++) + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) { switch (m_spellInfo->Effects[i].ApplyAuraName) { - case SPELL_AURA_DUMMY: - { - //custom check - switch (m_spellInfo->Id) - { - // Tag Murloc - case 30877: - { - Unit* target = m_targets.GetUnitTarget(); - if (!target || target->GetEntry() != 17326) - return SPELL_FAILED_BAD_TARGETS; - break; - } - case 61336: - if (m_caster->GetTypeId() != TYPEID_PLAYER || !m_caster->ToPlayer()->IsInFeralForm()) - return SPELL_FAILED_ONLY_SHAPESHIFT; - break; - case 1515: - { - if (m_caster->GetTypeId() != TYPEID_PLAYER) - return SPELL_FAILED_BAD_TARGETS; - - if (!m_targets.GetUnitTarget() || m_targets.GetUnitTarget()->GetTypeId() == TYPEID_PLAYER) - return SPELL_FAILED_BAD_IMPLICIT_TARGETS; - - Creature* target = m_targets.GetUnitTarget()->ToCreature(); - - if (target->getLevel() > m_caster->getLevel()) - return SPELL_FAILED_HIGHLEVEL; - - // use SMSG_PET_TAME_FAILURE? - if (!target->GetCreatureTemplate()->isTameable (m_caster->ToPlayer()->CanTameExoticPets())) - return SPELL_FAILED_BAD_TARGETS; - - if (m_caster->GetPetGUID()) - return SPELL_FAILED_ALREADY_HAVE_SUMMON; - - if (m_caster->GetCharmGUID()) - return SPELL_FAILED_ALREADY_HAVE_CHARM; - - break; - } - case 44795: // Parachute - { - float x, y, z; - m_caster->GetPosition(x, y, z); - float ground_Z = m_caster->GetMap()->GetHeight(m_caster->GetPhaseMask(), x, y, z); - if (fabs(ground_Z - z) < 0.1f) - return SPELL_FAILED_DONT_REPORT; - break; - } - default: - break; - } - break; - } case SPELL_AURA_MOD_POSSESS_PET: { if (m_caster->GetTypeId() != TYPEID_PLAYER) @@ -7047,15 +7021,29 @@ void Spell::CallScriptAfterHitHandlers() } } -void Spell::CallScriptAfterUnitTargetSelectHandlers(std::list<Unit*>& unitTargets, SpellEffIndex effIndex) +void Spell::CallScriptObjectAreaTargetSelectHandlers(std::list<WorldObject*>& targets, SpellEffIndex effIndex) { for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr) { - (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_UNIT_TARGET_SELECT); - std::list<SpellScript::UnitTargetHandler>::iterator hookItrEnd = (*scritr)->OnUnitTargetSelect.end(), hookItr = (*scritr)->OnUnitTargetSelect.begin(); + (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT); + std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectAreaTargetSelect.end(), hookItr = (*scritr)->OnObjectAreaTargetSelect.begin(); for (; hookItr != hookItrEnd; ++hookItr) if ((*hookItr).IsEffectAffected(m_spellInfo, effIndex)) - (*hookItr).Call(*scritr, unitTargets); + (*hookItr).Call(*scritr, targets); + + (*scritr)->_FinishScriptCall(); + } +} + +void Spell::CallScriptObjectTargetSelectHandlers(WorldObject*& target, SpellEffIndex effIndex) +{ + for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr) + { + (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT); + std::list<SpellScript::ObjectTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectTargetSelect.end(), hookItr = (*scritr)->OnObjectTargetSelect.begin(); + for (; hookItr != hookItrEnd; ++hookItr) + if ((*hookItr).IsEffectAffected(m_spellInfo, effIndex)) + (*hookItr).Call(*scritr, target); (*scritr)->_FinishScriptCall(); } @@ -7089,12 +7077,6 @@ void Spell::PrepareTriggersExecutedOnHit() // todo: move this to scripts switch (m_spellInfo->SpellFamilyName) { - case SPELLFAMILY_GENERIC: - { - if (m_spellInfo->Mechanic == MECHANIC_BANDAGE) // Bandages - m_preCastSpell = 11196; // Recently Bandaged - break; - } case SPELLFAMILY_MAGE: { // Permafrost |
