/* * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef __SPELL_H #define __SPELL_H #include "ConditionMgr.h" #include "DBCEnums.h" #include "ObjectGuid.h" #include "Position.h" #include "SharedDefines.h" #include "SpellDefines.h" #include "UniqueTrackablePtr.h" #include namespace WorldPackets { namespace Spells { struct SpellTargetData; struct SpellAmmo; struct SpellCastData; } } class Aura; class AuraEffect; class Corpse; class DamageInfo; class DynamicObject; class DynObjAura; class GameObject; class Item; class Object; class PathGenerator; class Player; class SpellEffectInfo; class SpellEvent; class SpellImplicitTargetInfo; class SpellInfo; class SpellScript; class Unit; class UnitAura; class WorldObject; class WorldPacket; struct SummonPropertiesEntry; enum AuraType : uint32; enum CurrentSpellTypes : uint8; enum LootType : uint8; enum SpellCastTargetFlags : uint32; enum SpellTargetCheckTypes : uint8; enum SpellTargetObjectTypes : uint8; enum SpellValueMod : uint8; enum TriggerCastFlags : uint32; enum WeaponAttackType : uint8; #define SPELL_CHANNEL_UPDATE_INTERVAL (1 * IN_MILLISECONDS) #define MAX_SPELL_RANGE_TOLERANCE 3.0f #define TRAJECTORY_MISSILE_SIZE 3.0f enum SpellCastFlags { CAST_FLAG_NONE = 0x00000000, CAST_FLAG_PENDING = 0x00000001, // aoe combat log? CAST_FLAG_HAS_TRAJECTORY = 0x00000002, CAST_FLAG_UNKNOWN_3 = 0x00000004, CAST_FLAG_UNKNOWN_4 = 0x00000008, // ignore AOE visual CAST_FLAG_UNKNOWN_5 = 0x00000010, CAST_FLAG_AMMO = 0x00000020, // Projectiles visual CAST_FLAG_UNKNOWN_7 = 0x00000040, CAST_FLAG_UNKNOWN_8 = 0x00000080, CAST_FLAG_UNKNOWN_9 = 0x00000100, CAST_FLAG_UNKNOWN_10 = 0x00000200, CAST_FLAG_UNKNOWN_11 = 0x00000400, CAST_FLAG_POWER_LEFT_SELF = 0x00000800, CAST_FLAG_UNKNOWN_13 = 0x00001000, CAST_FLAG_UNKNOWN_14 = 0x00002000, CAST_FLAG_UNKNOWN_15 = 0x00004000, CAST_FLAG_UNKNOWN_16 = 0x00008000, CAST_FLAG_UNKNOWN_17 = 0x00010000, CAST_FLAG_ADJUST_MISSILE = 0x00020000, CAST_FLAG_NO_GCD = 0x00040000, // no GCD for spell casts from charm/summon (vehicle spells is an example) CAST_FLAG_VISUAL_CHAIN = 0x00080000, CAST_FLAG_UNKNOWN_21 = 0x00100000, CAST_FLAG_RUNE_LIST = 0x00200000, CAST_FLAG_UNKNOWN_23 = 0x00400000, CAST_FLAG_UNKNOWN_24 = 0x00800000, CAST_FLAG_UNKNOWN_25 = 0x01000000, CAST_FLAG_UNKNOWN_26 = 0x02000000, CAST_FLAG_IMMUNITY = 0x04000000, CAST_FLAG_UNKNOWN_28 = 0x08000000, CAST_FLAG_UNKNOWN_29 = 0x10000000, CAST_FLAG_UNKNOWN_30 = 0x20000000, CAST_FLAG_UNKNOWN_31 = 0x40000000, CAST_FLAG_UNKNOWN_32 = 0x80000000 }; enum SpellRangeFlag { SPELL_RANGE_DEFAULT = 0, SPELL_RANGE_MELEE = 1, //melee SPELL_RANGE_RANGED = 2 //hunter range and ranged weapon }; struct SpellValue { explicit SpellValue(SpellInfo const* proto); int32 EffectBasePoints[MAX_SPELL_EFFECTS]; uint32 MaxAffectedTargets; float RadiusMod; uint8 AuraStackAmount; float CriticalChance; }; enum SpellState { SPELL_STATE_NULL = 0, SPELL_STATE_PREPARING = 1, SPELL_STATE_CASTING = 2, SPELL_STATE_FINISHED = 3, SPELL_STATE_IDLE = 4, SPELL_STATE_DELAYED = 5 }; enum SpellEffectHandleMode { SPELL_EFFECT_HANDLE_LAUNCH, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_EFFECT_HANDLE_HIT, SPELL_EFFECT_HANDLE_HIT_TARGET }; typedef std::vector> DispelList; static const uint32 SPELL_INTERRUPT_NONPLAYER = 32747; class TC_GAME_API Spell { friend class SpellScript; public: void EffectNULL(); void EffectUnused(); void EffectDistract(); void EffectPull(); void EffectSchoolDMG(); void EffectEnvironmentalDMG(); void EffectInstaKill(); void EffectDummy(); void EffectTeleportUnits(); void EffectApplyAura(); void EffectSendEvent(); void EffectPowerBurn(); void EffectPowerDrain(); void EffectHeal(); void EffectBind(); void EffectHealthLeech(); void EffectQuestComplete(); void EffectCreateItem(); void EffectCreateItem2(); void EffectCreateRandomItem(); void EffectPersistentAA(); void EffectEnergize(); void EffectOpenLock(); void EffectSummonChangeItem(); void EffectProficiency(); void EffectSummonType(); void EffectLearnSpell(); void EffectDispel(); void EffectDualWield(); void EffectPickPocket(); void EffectAddFarsight(); void EffectUntrainTalents(); void EffectHealMechanical(); void EffectJump(); void EffectJumpDest(); void EffectLeapBack(); void EffectQuestClear(); void EffectTeleUnitsFaceCaster(); void EffectLearnSkill(); void EffectAddHonor(); void EffectTradeSkill(); void EffectEnchantItemPerm(); void EffectEnchantItemTmp(); void EffectTameCreature(); void EffectSummonPet(); void EffectLearnPetSpell(); void EffectWeaponDmg(); void EffectForceCast(); void EffectTriggerSpell(); void EffectTriggerMissileSpell(); void EffectThreat(); void EffectHealMaxHealth(); void EffectInterruptCast(); void EffectSummonObjectWild(); void EffectScriptEffect(); void EffectSanctuary(); void EffectAddComboPoints(); void EffectDuel(); void EffectStuck(); void EffectSummonPlayer(); void EffectActivateObject(); void EffectApplyGlyph(); void EffectEnchantHeldItem(); void EffectSummonObject(); void EffectResurrect(); void EffectParry(); void EffectBlock(); void EffectLeap(); void EffectTransmitted(); void EffectDisEnchant(); void EffectInebriate(); void EffectFeedPet(); void EffectDismissPet(); void EffectReputation(); void EffectForceDeselect(); void EffectSelfResurrect(); void EffectSkinning(); void EffectCharge(); void EffectChargeDest(); void EffectProspecting(); void EffectMilling(); void EffectRenamePet(); void EffectSendTaxi(); void EffectKnockBack(); void EffectPullTowards(); void EffectPullTowardsDest(); void EffectDispelMechanic(); void EffectResurrectPet(); void EffectDestroyAllTotems(); void EffectDurabilityDamage(); void EffectSkill(); void EffectTaunt(); void EffectDurabilityDamagePCT(); void EffectModifyThreatPercent(); void EffectResurrectNew(); void EffectAddExtraAttacks(); void EffectSpiritHeal(); void EffectSkinPlayerCorpse(); void EffectStealBeneficialBuff(); void EffectUnlearnSpecialization(); void EffectHealPct(); void EffectEnergizePct(); void EffectTriggerRitualOfSummoning(); void EffectSummonRaFFriend(); void EffectKillCreditPersonal(); void EffectKillCredit(); void EffectQuestFail(); void EffectQuestStart(); void EffectRedirectThreat(); void EffectGameObjectDamage(); void EffectGameObjectRepair(); void EffectGameObjectSetDestructionState(); void EffectActivateRune(); void EffectCreateTamedPet(); void EffectDiscoverTaxi(); void EffectTitanGrip(); void EffectEnchantItemPrismatic(); void EffectPlayMusic(); void EffectSpecCount(); void EffectActivateSpec(); void EffectPlaySound(); void EffectRemoveAura(); void EffectCastButtons(); void EffectRechargeManaGem(); typedef std::unordered_set UsedSpellMods; Spell(WorldObject* caster, SpellInfo const* info, TriggerCastFlags triggerFlags, ObjectGuid originalCasterGUID = ObjectGuid::Empty); ~Spell(); void InitExplicitTargets(SpellCastTargets const& targets); void SelectExplicitTargets(); void SelectSpellTargets(); void SelectEffectImplicitTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType, uint32 effectMask); void SelectImplicitChannelTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType, uint32 effMask); void SelectImplicitNearbyTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType, uint32 effMask); void SelectImplicitConeTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType, uint32 effMask); void SelectImplicitAreaTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType, uint32 effMask); void SelectImplicitCasterDestTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType); void SelectImplicitTargetDestTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType); void SelectImplicitDestDestTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType); void SelectImplicitCasterObjectTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType, uint32 effMask); void SelectImplicitTargetObjectTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType, uint32 effMask); void SelectImplicitChainTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType, WorldObject* target, uint32 effMask); void SelectImplicitTrajTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType); void SelectEffectTypeImplicitTargets(SpellEffectInfo const& spellEffectInfo); uint32 GetSearcherTypeMask(SpellTargetObjectTypes objType, ConditionContainer* condList); template void SearchTargets(SEARCHER& searcher, uint32 containerMask, WorldObject* referer, Position const* pos, float radius); WorldObject* SearchNearbyTarget(float range, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionContainer* condList = nullptr); void SearchAreaTargets(std::list& targets, float range, Position const* position, WorldObject* referer, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionContainer* condList); void SearchChainTargets(std::list& targets, uint32 chainTargets, WorldObject* target, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectType, ConditionContainer* condList, bool isChainHeal); GameObject* SearchSpellFocus(); SpellCastResult prepare(SpellCastTargets const& targets, AuraEffect const* triggeredByAura = nullptr); void cancel(SpellCastResult result = SPELL_FAILED_INTERRUPTED, Optional resultOther = {}); void update(uint32 difftime); void cast(bool skipCheck = false); void finish(bool ok = true); void TakePower(); void TakeAmmo(); void TakeRunePower(bool didHit); void TakeReagents(); void TakeCastItem(); SpellCastResult CheckCast(bool strict, uint32* param1 = nullptr, uint32* param2 = nullptr); SpellCastResult CheckPetCast(Unit* target); // handlers void handle_immediate(); uint64 handle_delayed(uint64 t_offset); // handler helpers void _handle_immediate_phase(); void _handle_finish_phase(); SpellCastResult CheckItems(uint32* param1, uint32* param2) const; SpellCastResult CheckRange(bool strict) const; SpellCastResult CheckPower() const; SpellCastResult CheckRuneCost(uint32 runeCostID) const; SpellCastResult CheckCasterAuras(uint32* param1) const; SpellCastResult CheckArenaCastRules() const; SpellCastResult CheckMovement() const; bool CheckSpellCancelsAuraEffect(AuraType auraType, uint32* param1) const; bool CheckSpellCancelsCharm(uint32* param1) const; bool CheckSpellCancelsStun(uint32* param1) const; bool CheckSpellCancelsSilence(uint32* param1) const; bool CheckSpellCancelsPacify(uint32* param1) const; bool CheckSpellCancelsFear(uint32* param1) const; bool CheckSpellCancelsConfuse(uint32* param1) const; int32 CalculateDamage(SpellEffectInfo const& spellEffectInfo) const; void Delayed(); void DelayedChannel(); uint32 getState() const { return m_spellState; } void setState(uint32 state) { m_spellState = state; } void DoCreateItem(uint32 itemId); void UpdateSpellCastDataTargets(WorldPackets::Spells::SpellCastData& data); void UpdateSpellCastDataAmmo(WorldPackets::Spells::SpellAmmo& data); bool CheckEffectTarget(Unit const* target, SpellEffectInfo const& spellEffectInfo, Position const* losPosition) const; bool CanAutoCast(Unit* target); void CheckSrc(); void CheckDst(); static void WriteCastResultInfo(WorldPacket& data, Player* caster, SpellInfo const* spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError, uint32* param1 = nullptr, uint32* param2 = nullptr); static void SendCastResult(Player* caster, SpellInfo const* spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError = SPELL_CUSTOM_ERROR_NONE, uint32* param1 = nullptr, uint32* param2 = nullptr); void SendCastResult(SpellCastResult result, uint32* param1 = nullptr, uint32* param2 = nullptr) const; void SendPetCastResult(SpellCastResult result); void SendMountResult(MountResult result); void SendSpellStart(); void SendSpellGo(); void SendSpellCooldown(); void SendLogExecute(); void ExecuteLogEffectTakeTargetPower(uint8 effIndex, Unit* target, uint32 powerType, uint32 powerTaken, float gainMultiplier); void ExecuteLogEffectExtraAttacks(uint8 effIndex, Unit* victim, uint32 attCount); void ExecuteLogEffectInterruptCast(uint8 effIndex, Unit* victim, uint32 spellId); void ExecuteLogEffectDurabilityDamage(uint8 effIndex, Unit* victim, int32 itemId, int32 slot); void ExecuteLogEffectOpenLock(uint8 effIndex, Object* obj); void ExecuteLogEffectCreateItem(uint8 effIndex, uint32 entry); void ExecuteLogEffectDestroyItem(uint8 effIndex, uint32 entry); void ExecuteLogEffectSummonObject(uint8 effIndex, WorldObject* obj); void ExecuteLogEffectUnsummonObject(uint8 effIndex, WorldObject* obj); void ExecuteLogEffectResurrect(uint8 effIndex, Unit* target); void SendInterrupted(SpellCastResult result, Optional resultOther = {}); void SendChannelUpdate(uint32 time); void SendChannelStart(uint32 duration); void SendResurrectRequest(Player* target); void HandleEffects(Unit* pUnitTarget, Item* pItemTarget, GameObject* pGoTarget, Corpse* pCorpseTarget, SpellEffectInfo const& spellEffectInfo, SpellEffectHandleMode mode); void HandleThreatSpells(); SpellInfo const* const m_spellInfo; Item* m_CastItem; ObjectGuid m_castItemGUID; uint32 m_castItemEntry; uint8 m_cast_count; bool m_fromClient; uint32 m_glyphIndex; SpellCastTargets m_targets; void AddComboPointGain(Unit* target, int8 amount) { if (target != m_comboTarget) { m_comboTarget = target; m_comboPointGain = amount; } else m_comboPointGain += amount; } Unit* m_comboTarget; int8 m_comboPointGain; SpellCustomErrors m_customError; UsedSpellMods m_appliedMods; int32 GetCastTime() const { return m_casttime; } bool IsAutoRepeat() const { return m_autoRepeat; } void SetAutoRepeat(bool rep) { m_autoRepeat = rep; } void ReSetTimer() { m_timer = m_casttime > 0 ? m_casttime : 0; } bool IsTriggered() const; bool IsIgnoringCooldowns() const; bool IsFocusDisabled() const; bool IsProcDisabled() const; bool IsChannelActive() const; bool IsAutoActionResetSpell() const; bool IsPositive() const; bool IsTriggeredByAura(SpellInfo const* auraSpellInfo) const { return (auraSpellInfo == m_triggeredByAuraSpell); } bool IsDeletable() const { return !m_referencedFromCurrentSpell && !m_executedCurrently; } void SetReferencedFromCurrent(bool yes) { m_referencedFromCurrentSpell = yes; } bool IsInterruptable() const { return !m_executedCurrently; } void SetExecutedCurrently(bool yes) {m_executedCurrently = yes;} uint64 GetDelayStart() const { return m_delayStart; } void SetDelayStart(uint64 m_time) { m_delayStart = m_time; } uint64 GetDelayMoment() const { return m_delayMoment; } uint64 CalculateDelayMomentForDst() const; void RecalculateDelayMomentForDst(); uint8 GetRuneState() const { return m_runesState; } void SetRuneState(uint8 value) { m_runesState = value; } bool IsNeedSendToClient() const; CurrentSpellTypes GetCurrentContainer() const; WorldObject* GetCaster() const { return m_caster; } Unit* GetOriginalCaster() const { return m_originalCaster; } SpellInfo const* GetSpellInfo() const { return m_spellInfo; } int32 GetPowerCost() const { return m_powerCost; } bool UpdatePointers(); // must be used at call Spell code after time delay (non triggered spell cast/update spell call/etc) void CleanupTargetList(); void SetSpellValue(SpellValueMod mod, int32 value); Spell** m_selfContainer; // pointer to our spell container (if applicable) std::string GetDebugInfo() const; Trinity::unique_weak_ptr GetWeakPtr() const; void CallScriptOnResistAbsorbCalculateHandlers(DamageInfo const& damageInfo, uint32& resistAmount, int32& absorbAmount); protected: bool HasGlobalCooldown() const; void TriggerGlobalCooldown(); void CancelGlobalCooldown(); void _cast(bool skipCheck = false); void SendLoot(ObjectGuid guid, LootType loottype); std::pair GetMinMaxRange(bool strict) const; WorldObject* const m_caster; SpellValue* const m_spellValue; ObjectGuid m_originalCasterGUID; // real source of cast (aura caster/etc), used for spell targets selection // e.g. damage around area spell trigered by victim aura and damage enemies of aura caster Unit* m_originalCaster; // cached pointer for m_originalCaster, updated at Spell::UpdatePointers() // Spell data SpellSchoolMask m_spellSchoolMask; // Spell school (can be overwrite for some spells (wand shoot for example) WeaponAttackType m_attackType; // For weapon based attack int32 m_powerCost; // Calculated spell cost initialized only in Spell::prepare int32 m_casttime; // Calculated spell cast time initialized only in Spell::prepare int32 m_channeledDuration; // Calculated channeled spell duration in order to calculate correct pushback. bool m_canReflect; // can reflect this spell? bool m_autoRepeat; uint8 m_runesState; uint8 m_delayAtDamageCount; bool IsDelayableNoMore() { if (m_delayAtDamageCount >= 2) return true; ++m_delayAtDamageCount; return false; } // Delayed spells system uint64 m_delayStart; // time of spell delay start, filled by event handler, zero = just started uint64 m_delayMoment; // moment of next delay call, used internally bool m_immediateHandled; // were immediate actions handled? (used by delayed spells only) // These vars are used in both delayed spell system and modified immediate spell system bool m_referencedFromCurrentSpell; // mark as references to prevent deleted and access by dead pointers bool m_executedCurrently; // mark as executed to prevent deleted and access by dead pointers bool m_needComboPoints; uint8 m_applyMultiplierMask; float m_damageMultipliers[MAX_SPELL_EFFECTS]; // Current targets, to be used in SpellEffects (MUST BE USED ONLY IN SPELL EFFECTS) Unit* unitTarget; Item* itemTarget; GameObject* gameObjTarget; Corpse* m_corpseTarget; WorldLocation* destTarget; int32 damage; SpellMissInfo targetMissInfo; SpellEffectHandleMode effectHandleMode; SpellEffectInfo const* effectInfo; // used in effects handlers Unit* GetUnitCasterForEffectHandlers() const; UnitAura* _spellAura; DynObjAura* _dynObjAura; // ------------------------------------------- ObjectGuid m_focusObjectGUID; GameObject* focusObject; // Damage and healing in effects need just calculate int32 m_damage; // Damage in effects count here int32 m_healing; // Healing in effects count here // ****************************************** // Spell trigger system // ****************************************** uint32 m_procAttacker; // Attacker trigger flags uint32 m_procVictim; // Victim trigger flags uint32 m_hitMask; void prepareDataForTriggerSystem(); // ***************************************** // Spell target subsystem // ***************************************** // Targets store structures and data struct TargetInfoBase { virtual void PreprocessTarget(Spell* /*spell*/) { } virtual void DoTargetSpellHit(Spell* spell, SpellEffectInfo const& spellEffectInfo) = 0; virtual void DoDamageAndTriggers(Spell* /*spell*/) { } uint8 EffectMask = 0; protected: TargetInfoBase() { } virtual ~TargetInfoBase() { } }; struct TargetInfo : public TargetInfoBase { void PreprocessTarget(Spell* spell) override; void DoTargetSpellHit(Spell* spell, SpellEffectInfo const& spellEffectInfo) override; void DoDamageAndTriggers(Spell* spell) override; ObjectGuid TargetGUID; uint64 TimeDelay = 0ULL; int32 Damage = 0; int32 Healing = 0; SpellMissInfo MissCondition = SPELL_MISS_NONE; SpellMissInfo ReflectResult = SPELL_MISS_NONE; bool IsAlive = false; bool IsCrit = false; bool ScaleAura = false; // info set at PreprocessTarget, used by DoTargetSpellHit DiminishingGroup DRGroup = DIMINISHING_NONE; int32 AuraDuration = 0; SpellInfo const* AuraSpellInfo = nullptr; int32 AuraBasePoints[MAX_SPELL_EFFECTS] = { }; bool Positive = true; UnitAura* HitAura = nullptr; private: Unit* _spellHitTarget = nullptr; // changed for example by reflect bool _enablePVP = false; // need to enable PVP at DoDamageAndTriggers? }; std::vector m_UniqueTargetInfo; uint8 m_channelTargetEffectMask; // Mask req. alive targets struct GOTargetInfo : public TargetInfoBase { void DoTargetSpellHit(Spell* spell, SpellEffectInfo const& spellEffectInfo) override; ObjectGuid TargetGUID; uint64 TimeDelay = 0ULL; }; std::vector m_UniqueGOTargetInfo; struct ItemTargetInfo : public TargetInfoBase { void DoTargetSpellHit(Spell* spell, SpellEffectInfo const& spellEffectInfo) override; Item* TargetItem = nullptr; }; std::vector m_UniqueItemInfo; struct CorpseTargetInfo : public TargetInfoBase { void DoTargetSpellHit(Spell* spell, SpellEffectInfo const& spellEffectInfo) override; ObjectGuid TargetGUID; uint64 TimeDelay = 0ULL; }; std::vector m_UniqueCorpseTargetInfo; template void DoProcessTargetContainer(Container& targetContainer); SpellDestination m_destTargets[MAX_SPELL_EFFECTS]; void AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid = true, bool implicit = true, Position const* losPosition = nullptr); void AddGOTarget(GameObject* target, uint32 effectMask); void AddItemTarget(Item* item, uint32 effectMask); void AddCorpseTarget(Corpse* target, uint32 effectMask); void AddDestTarget(SpellDestination const& dest, uint32 effIndex); void PreprocessSpellLaunch(TargetInfo& targetInfo); SpellMissInfo PreprocessSpellHit(Unit* unit, bool scaleAura, TargetInfo& targetInfo); void DoSpellEffectHit(Unit* unit, SpellEffectInfo const& spellEffectInfo, TargetInfo& targetInfo); void DoTriggersOnSpellHit(Unit* unit, uint8 effMask); bool UpdateChanneledTargetList(); bool IsValidDeadOrAliveTarget(Unit const* target) const; void HandleLaunchPhase(); void DoEffectOnLaunchTarget(TargetInfo& targetInfo, float multiplier, SpellEffectInfo const& spellEffectInfo); void PrepareTargetProcessing(); void FinishTargetProcessing(); // spell execution log void InitEffectExecuteData(uint8 effIndex); void AssertEffectExecuteData() const; // Scripting system void LoadScripts(); void CallScriptBeforeCastHandlers(); void CallScriptOnCastHandlers(); void CallScriptAfterCastHandlers(); SpellCastResult CallScriptCheckCastHandlers(); bool CallScriptEffectHandlers(SpellEffIndex effIndex, SpellEffectHandleMode mode); void CallScriptSuccessfulDispel(SpellEffIndex effIndex); void CallScriptBeforeHitHandlers(SpellMissInfo missInfo); void CallScriptOnHitHandlers(); void CallScriptAfterHitHandlers(); void CallScriptObjectAreaTargetSelectHandlers(std::list& targets, SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType); void CallScriptObjectTargetSelectHandlers(WorldObject*& target, SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType); void CallScriptDestinationTargetSelectHandlers(SpellDestination& target, SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType); bool CheckScriptEffectImplicitTargets(uint32 effIndex, uint32 effIndexToCheck); std::vector m_loadedScripts; struct HitTriggerSpell { HitTriggerSpell(SpellInfo const* spellInfo, SpellInfo const* auraSpellInfo, int32 procChance) : triggeredSpell(spellInfo), triggeredByAura(auraSpellInfo), chance(procChance) { } SpellInfo const* triggeredSpell; SpellInfo const* triggeredByAura; // uint8 triggeredByEffIdx This might be needed at a later stage - No need known for now int32 chance; }; bool CanExecuteTriggersOnHit(uint8 effMask, SpellInfo const* triggeredByAura = nullptr) const; void PrepareTriggersExecutedOnHit(); typedef std::vector HitTriggerSpellList; HitTriggerSpellList m_hitTriggerSpells; // effect helpers void SummonGuardian(SpellEffectInfo const& spellEffectInfo, uint32 entry, SummonPropertiesEntry const* properties, uint32 numSummons); void CalculateJumpSpeeds(SpellEffectInfo const& spellEffectInfo, float dist, float& speedXY, float& speedZ); SpellCastResult CanOpenLock(SpellEffectInfo const& spellEffectInfo, uint32 lockid, SkillType& skillid, int32& reqSkillValue, int32& skillValue); // ------------------------------------------- uint32 m_spellState; int32 m_timer; SpellEvent* _spellEvent; TriggerCastFlags _triggeredCastFlags; // if need this can be replaced by Aura copy // we can't store original aura link to prevent access to deleted auras // and in same time need aura data and after aura deleting. SpellInfo const* m_triggeredByAuraSpell; uint8 m_auraScaleMask; std::unique_ptr m_preGeneratedPath; ByteBuffer* m_effectExecuteData[MAX_SPELL_EFFECTS]; Spell(Spell const& right) = delete; Spell& operator=(Spell const& right) = delete; }; namespace Trinity { struct TC_GAME_API WorldObjectSpellTargetCheck { protected: WorldObject* _caster; WorldObject* _referer; SpellInfo const* _spellInfo; SpellTargetCheckTypes _targetSelectionType; std::unique_ptr _condSrcInfo; ConditionContainer const* _condList; WorldObjectSpellTargetCheck(WorldObject* caster, WorldObject* referer, SpellInfo const* spellInfo, SpellTargetCheckTypes selectionType, ConditionContainer const* condList); ~WorldObjectSpellTargetCheck(); bool operator()(WorldObject* target) const; }; struct TC_GAME_API WorldObjectSpellNearbyTargetCheck : public WorldObjectSpellTargetCheck { float _range; Position const* _position; WorldObjectSpellNearbyTargetCheck(float range, WorldObject* caster, SpellInfo const* spellInfo, SpellTargetCheckTypes selectionType, ConditionContainer const* condList); bool operator()(WorldObject* target); }; struct TC_GAME_API WorldObjectSpellAreaTargetCheck : public WorldObjectSpellTargetCheck { float _range; Position const* _position; WorldObjectSpellAreaTargetCheck(float range, Position const* position, WorldObject* caster, WorldObject* referer, SpellInfo const* spellInfo, SpellTargetCheckTypes selectionType, ConditionContainer const* condList); bool operator()(WorldObject* target) const; }; struct TC_GAME_API WorldObjectSpellConeTargetCheck : public WorldObjectSpellAreaTargetCheck { float _coneAngle; WorldObjectSpellConeTargetCheck(float coneAngle, float range, WorldObject* caster, SpellInfo const* spellInfo, SpellTargetCheckTypes selectionType, ConditionContainer const* condList); bool operator()(WorldObject* target) const; }; struct TC_GAME_API WorldObjectSpellTrajTargetCheck : public WorldObjectSpellTargetCheck { float _range; Position const* _position; WorldObjectSpellTrajTargetCheck(float range, Position const* position, WorldObject* caster, SpellInfo const* spellInfo, SpellTargetCheckTypes selectionType, ConditionContainer const* condList); bool operator()(WorldObject* target) const; }; } using SpellEffectHandlerFn = void(Spell::*)(); #endif