2010-10-07 15:54:07 +02:00
|
|
|
/*
|
2011-01-01 15:01:13 +01:00
|
|
|
* Copyright (C) 2008-2011 TrinityCore <http://www.trinitycore.org/>
|
2010-10-07 15:54:07 +02:00
|
|
|
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
|
|
|
|
*
|
|
|
|
|
* 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 <http://www.gnu.org/licenses/>.
|
2008-10-02 16:23:55 -05:00
|
|
|
*/
|
2010-01-10 01:23:15 +01:00
|
|
|
|
2008-10-14 11:57:03 -05:00
|
|
|
#ifndef TRINITY_SPELLAURAS_H
|
|
|
|
|
#define TRINITY_SPELLAURAS_H
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2008-10-02 16:23:55 -05:00
|
|
|
#include "SpellAuraDefines.h"
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2010-02-05 00:31:28 +01:00
|
|
|
class Unit;
|
2008-10-02 16:23:55 -05:00
|
|
|
struct SpellEntry;
|
|
|
|
|
struct SpellModifier;
|
|
|
|
|
struct ProcTriggerSpell;
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2008-10-02 16:23:55 -05:00
|
|
|
// forward decl
|
2009-04-06 13:31:14 +02:00
|
|
|
class AuraEffect;
|
2010-01-10 01:23:15 +01:00
|
|
|
class Aura;
|
|
|
|
|
class DynamicObject;
|
2010-08-24 00:10:49 +02:00
|
|
|
class AuraScript;
|
2010-01-10 01:23:15 +01:00
|
|
|
|
2010-01-22 18:06:01 +01:00
|
|
|
// update aura target map every 500 ms instead of every update - reduce amount of grid searcher calls
|
|
|
|
|
#define UPDATE_TARGET_MAP_INTERVAL 500
|
|
|
|
|
|
2010-01-10 01:23:15 +01:00
|
|
|
class AuraApplication
|
|
|
|
|
{
|
2010-01-24 13:08:25 +01:00
|
|
|
friend void Unit::_ApplyAura(AuraApplication * aurApp, uint8 effMask);
|
|
|
|
|
friend void Unit::_UnapplyAura(AuraApplicationMap::iterator &i, AuraRemoveMode removeMode);
|
|
|
|
|
friend void Unit::_ApplyAuraEffect(Aura * aura, uint8 effIndex);
|
|
|
|
|
friend AuraApplication * Unit::_CreateAuraApplication(Aura * aura, uint8 effMask);
|
2010-01-10 02:12:02 +01:00
|
|
|
private:
|
|
|
|
|
Unit * const m_target;
|
|
|
|
|
Aura * const m_base;
|
|
|
|
|
uint8 m_slot; // Aura slot on unit
|
|
|
|
|
uint8 m_flags; // Aura info flag
|
2010-01-24 13:08:25 +01:00
|
|
|
uint8 m_effectsToApply; // Used only at spell hit to determine which effect should be applied
|
2010-01-10 01:23:15 +01:00
|
|
|
AuraRemoveMode m_removeMode:8; // Store info for know remove aura reason
|
|
|
|
|
bool m_needClientUpdate:1;
|
|
|
|
|
|
2010-01-24 13:08:25 +01:00
|
|
|
explicit AuraApplication(Unit * target, Unit * caster, Aura * base, uint8 effMask);
|
2010-01-10 01:23:15 +01:00
|
|
|
void _Remove();
|
|
|
|
|
private:
|
2010-12-31 12:50:17 +01:00
|
|
|
void _InitFlags(Unit * caster, uint8 effMask);
|
2010-01-10 01:23:15 +01:00
|
|
|
void _HandleEffect(uint8 effIndex, bool apply);
|
2010-01-10 02:12:02 +01:00
|
|
|
public:
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2010-01-10 01:23:15 +01:00
|
|
|
Unit * GetTarget() const { return m_target; }
|
|
|
|
|
Aura * GetBase() const { return m_base; }
|
|
|
|
|
|
2010-01-10 02:12:02 +01:00
|
|
|
uint8 GetSlot() const { return m_slot; }
|
|
|
|
|
uint8 GetFlags() const { return m_flags; }
|
2010-01-10 01:23:15 +01:00
|
|
|
uint8 GetEffectMask() const { return m_flags & (AFLAG_EFF_INDEX_0 | AFLAG_EFF_INDEX_1 | AFLAG_EFF_INDEX_2); }
|
2010-07-30 20:04:28 +02:00
|
|
|
bool HasEffect(uint8 effect) const { ASSERT(effect < MAX_SPELL_EFFECTS); return m_flags & (1<<effect); }
|
2010-01-10 01:23:15 +01:00
|
|
|
bool IsPositive() const { return m_flags & AFLAG_POSITIVE; }
|
2010-12-31 12:50:17 +01:00
|
|
|
bool IsSelfcasted() const { return m_flags & AFLAG_CASTER; }
|
2010-01-24 13:08:25 +01:00
|
|
|
uint8 GetEffectsToApply() const { return m_effectsToApply; }
|
2010-01-10 01:23:15 +01:00
|
|
|
|
|
|
|
|
void SetRemoveMode(AuraRemoveMode mode) { m_removeMode = mode; }
|
|
|
|
|
AuraRemoveMode GetRemoveMode() const {return m_removeMode;}
|
|
|
|
|
|
|
|
|
|
void SetNeedClientUpdate() { m_needClientUpdate = true;}
|
|
|
|
|
bool IsNeedClientUpdate() const { return m_needClientUpdate;}
|
|
|
|
|
void ClientUpdate(bool remove = false);
|
|
|
|
|
};
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2010-02-05 00:31:28 +01:00
|
|
|
class Aura
|
2008-10-02 16:23:55 -05:00
|
|
|
{
|
2009-04-06 13:31:14 +02:00
|
|
|
public:
|
2010-01-18 20:15:23 +01:00
|
|
|
typedef std::map<uint64, AuraApplication *> ApplicationMap;
|
2010-01-10 01:23:15 +01:00
|
|
|
|
|
|
|
|
static Aura * TryCreate(SpellEntry const* spellproto, uint8 effMask, WorldObject * owner, Unit * caster, int32 *baseAmount = NULL, Item * castItem = NULL, uint64 casterGUID = 0);
|
|
|
|
|
static Aura * TryCreate(SpellEntry const* spellproto, WorldObject * owner, Unit * caster, int32 *baseAmount = NULL, Item * castItem = NULL, uint64 casterGUID = 0);
|
|
|
|
|
static Aura * Create(SpellEntry const* spellproto, uint8 effMask, WorldObject * owner, Unit * caster, int32 *baseAmount = NULL, Item * castItem = NULL, uint64 casterGUID = 0);
|
2011-03-08 16:42:00 +01:00
|
|
|
explicit Aura(SpellEntry const* spellproto, WorldObject * owner, Unit * caster, Item * castItem, uint64 casterGUID);
|
2011-02-06 13:17:29 +01:00
|
|
|
void _InitEffects(uint8 effMask, Unit * caster, int32 *baseAmount);
|
2011-05-07 19:08:50 +02:00
|
|
|
virtual ~Aura();
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2009-04-06 13:31:14 +02:00
|
|
|
SpellEntry const* GetSpellProto() const { return m_spellProto; }
|
2010-01-10 01:23:15 +01:00
|
|
|
uint32 GetId() const{ return GetSpellProto()->Id; }
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2010-01-10 01:23:15 +01:00
|
|
|
uint64 GetCastItemGUID() const { return m_castItemGuid; }
|
2009-08-25 00:43:31 -05:00
|
|
|
uint64 const& GetCasterGUID() const { return m_casterGuid; }
|
2009-04-06 13:31:14 +02:00
|
|
|
Unit* GetCaster() const;
|
2010-01-10 01:23:15 +01:00
|
|
|
WorldObject * GetOwner() const { return m_owner; }
|
2010-07-30 20:04:28 +02:00
|
|
|
Unit * GetUnitOwner() const { ASSERT(GetType() == UNIT_AURA_TYPE); return (Unit*)m_owner; }
|
|
|
|
|
DynamicObject * GetDynobjOwner() const { ASSERT(GetType() == DYNOBJ_AURA_TYPE); return (DynamicObject*)m_owner; }
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2010-01-10 01:23:15 +01:00
|
|
|
AuraObjectType GetType() const;
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2010-01-10 01:23:15 +01:00
|
|
|
virtual void _ApplyForTarget(Unit * target, Unit * caster, AuraApplication * auraApp);
|
|
|
|
|
virtual void _UnapplyForTarget(Unit * target, Unit * caster, AuraApplication * auraApp);
|
|
|
|
|
void _Remove(AuraRemoveMode removeMode);
|
|
|
|
|
virtual void Remove(AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT) = 0;
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2010-01-24 13:08:25 +01:00
|
|
|
virtual void FillTargetMap(std::map<Unit *, uint8> & targets, Unit * caster) = 0;
|
|
|
|
|
void UpdateTargetMap(Unit * caster, bool apply = true);
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2010-01-24 13:08:25 +01:00
|
|
|
void _RegisterForTargets() {Unit * caster = GetCaster(); UpdateTargetMap(caster, false);}
|
|
|
|
|
void ApplyForTargets() {Unit * caster = GetCaster(); UpdateTargetMap(caster, true);}
|
|
|
|
|
void _ApplyEffectForTargets(uint8 effIndex);
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2010-01-10 01:23:15 +01:00
|
|
|
void UpdateOwner(uint32 diff, WorldObject * owner);
|
|
|
|
|
void Update(uint32 diff, Unit * caster);
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2010-01-10 01:23:15 +01:00
|
|
|
time_t GetApplyTime() const { return m_applyTime; }
|
|
|
|
|
int32 GetMaxDuration() const { return m_maxDuration; }
|
|
|
|
|
void SetMaxDuration(int32 duration) { m_maxDuration = duration; }
|
|
|
|
|
int32 GetDuration() const { return m_duration; }
|
|
|
|
|
void SetDuration(int32 duration, bool withMods = false);
|
|
|
|
|
void RefreshDuration();
|
|
|
|
|
bool IsExpired() const { return !GetDuration();}
|
|
|
|
|
bool IsPermanent() const { return GetMaxDuration() == -1; }
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2010-01-10 01:23:15 +01:00
|
|
|
uint8 GetCharges() const { return m_procCharges; }
|
|
|
|
|
void SetCharges(uint8 charges);
|
|
|
|
|
bool DropCharge();
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2010-01-10 01:23:15 +01:00
|
|
|
uint8 GetStackAmount() const { return m_stackAmount; }
|
|
|
|
|
void SetStackAmount(uint8 num, bool applied = true);
|
|
|
|
|
bool ModStackAmount(int32 num); // return true if last charge dropped
|
|
|
|
|
|
|
|
|
|
uint8 GetCasterLevel() const { return m_casterLevel; }
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2010-01-10 01:23:15 +01:00
|
|
|
bool IsPassive() const;
|
|
|
|
|
bool IsDeathPersistent() const;
|
2010-12-19 05:15:47 +01:00
|
|
|
bool IsRemovedOnShapeLost(Unit * target) const { return (GetCasterGUID() == target->GetGUID() && m_spellProto->Stances && !(m_spellProto->AttributesEx2 & SPELL_ATTR2_NOT_NEED_SHAPESHIFT) && !(m_spellProto->Attributes & SPELL_ATTR0_NOT_SHAPESHIFT)); }
|
2010-01-10 01:23:15 +01:00
|
|
|
bool CanBeSaved() const;
|
|
|
|
|
bool IsRemoved() const { return m_isRemoved; }
|
|
|
|
|
bool IsVisible() const;
|
|
|
|
|
// Single cast aura helpers
|
|
|
|
|
bool IsSingleTarget() const {return m_isSingleTarget;}
|
|
|
|
|
void SetIsSingleTarget(bool val) { m_isSingleTarget = val;}
|
2010-01-16 15:12:21 +01:00
|
|
|
void UnregisterSingleTarget();
|
2010-01-10 01:23:15 +01:00
|
|
|
|
|
|
|
|
void SetLoadedState(int32 maxduration, int32 duration, int32 charges, uint8 stackamount, uint8 recalculateMask, int32 * amount);
|
|
|
|
|
|
|
|
|
|
// helpers for aura effects
|
|
|
|
|
bool HasEffect(uint8 effIndex) const { return bool(GetEffect(effIndex)); }
|
|
|
|
|
bool HasEffectType(AuraType type) const;
|
2010-08-24 00:10:49 +02:00
|
|
|
AuraEffect * GetEffect(uint8 effIndex) const { ASSERT (effIndex < MAX_SPELL_EFFECTS); return m_effects[effIndex]; }
|
2010-04-07 19:12:44 +02:00
|
|
|
uint8 GetEffectMask() const { uint8 effMask = 0; for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) if (m_effects[i]) effMask |= 1<<i; return effMask; }
|
2010-01-10 01:23:15 +01:00
|
|
|
void RecalculateAmountOfEffects();
|
|
|
|
|
void HandleAllEffects(AuraApplication const * aurApp, uint8 mode, bool apply);
|
|
|
|
|
|
|
|
|
|
// Helpers for targets
|
|
|
|
|
ApplicationMap const & GetApplicationMap() {return m_applications;}
|
|
|
|
|
const AuraApplication * GetApplicationOfTarget (uint64 const & guid) const { ApplicationMap::const_iterator itr = m_applications.find(guid); if (itr != m_applications.end()) return itr->second; return NULL; }
|
|
|
|
|
AuraApplication * GetApplicationOfTarget (uint64 const & guid) { ApplicationMap::iterator itr = m_applications.find(guid); if (itr != m_applications.end()) return itr->second; return NULL; }
|
2010-08-24 00:10:49 +02:00
|
|
|
bool IsAppliedOnTarget(uint64 const & guid) const { return m_applications.find(guid) != m_applications.end(); }
|
2010-01-10 01:23:15 +01:00
|
|
|
|
|
|
|
|
void SetNeedClientUpdateForTargets() const;
|
|
|
|
|
void HandleAuraSpecificMods(AuraApplication const * aurApp, Unit * caster, bool apply);
|
2010-08-03 06:11:03 +02:00
|
|
|
bool CanBeAppliedOn(Unit *target);
|
2010-07-13 21:41:21 +02:00
|
|
|
bool CheckAreaTarget(Unit *target);
|
2010-08-24 00:10:49 +02:00
|
|
|
|
|
|
|
|
// AuraScript
|
|
|
|
|
void LoadScripts();
|
|
|
|
|
bool CallScriptEffectApplyHandlers(AuraEffect const * aurEff, AuraApplication const * aurApp, AuraEffectHandleModes mode);
|
|
|
|
|
bool CallScriptEffectRemoveHandlers(AuraEffect const * aurEff, AuraApplication const * aurApp, AuraEffectHandleModes mode);
|
|
|
|
|
bool CallScriptEffectPeriodicHandlers(AuraEffect const * aurEff, AuraApplication const * aurApp);
|
|
|
|
|
void CallScriptEffectUpdatePeriodicHandlers(AuraEffect * aurEff);
|
|
|
|
|
void CallScriptEffectCalcAmountHandlers(AuraEffect const * aurEff, int32 & amount, bool & canBeRecalculated);
|
|
|
|
|
void CallScriptEffectCalcPeriodicHandlers(AuraEffect const * aurEff, bool & isPeriodic, int32 & amplitude);
|
|
|
|
|
void CallScriptEffectCalcSpellModHandlers(AuraEffect const * aurEff, SpellModifier *& spellMod);
|
2010-12-27 20:14:54 +01:00
|
|
|
void CallScriptEffectAbsorbHandlers(AuraEffect * aurEff, AuraApplication const * aurApp, DamageInfo & dmgInfo, uint32 & absorbAmount, bool & defaultPrevented);
|
2010-12-30 02:03:46 +01:00
|
|
|
void CallScriptEffectAfterAbsorbHandlers(AuraEffect * aurEff, AuraApplication const * aurApp, DamageInfo & dmgInfo, uint32 & absorbAmount);
|
2010-12-30 19:05:19 +01:00
|
|
|
void CallScriptEffectManaShieldHandlers(AuraEffect * aurEff, AuraApplication const * aurApp, DamageInfo & dmgInfo, uint32 & absorbAmount, bool & defaultPrevented);
|
|
|
|
|
void CallScriptEffectAfterManaShieldHandlers(AuraEffect * aurEff, AuraApplication const * aurApp, DamageInfo & dmgInfo, uint32 & absorbAmount);
|
2010-08-24 00:10:49 +02:00
|
|
|
std::list<AuraScript *> m_loadedScripts;
|
2009-04-06 13:31:14 +02:00
|
|
|
private:
|
2010-01-10 01:23:15 +01:00
|
|
|
void _DeleteRemovedApplications();
|
|
|
|
|
protected:
|
|
|
|
|
SpellEntry const * const m_spellProto;
|
|
|
|
|
uint64 const m_casterGuid;
|
|
|
|
|
uint64 const m_castItemGuid; // it is NOT safe to keep a pointer to the item because it may get deleted
|
|
|
|
|
time_t const m_applyTime;
|
|
|
|
|
WorldObject * const m_owner; //
|
|
|
|
|
|
|
|
|
|
int32 m_maxDuration; // Max aura duration
|
2009-04-06 13:31:14 +02:00
|
|
|
int32 m_duration; // Current time
|
|
|
|
|
int32 m_timeCla; // Timer for power per sec calcultion
|
2010-01-22 18:06:01 +01:00
|
|
|
int32 m_updateTargetMapInterval; // Timer for UpdateTargetMapOfEffect
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2010-01-10 02:12:02 +01:00
|
|
|
uint8 const m_casterLevel; // Aura level (store caster level for correct show level dep amount)
|
2009-04-06 13:31:14 +02:00
|
|
|
uint8 m_procCharges; // Aura charges (0 for infinite)
|
2009-10-02 02:45:00 -07:00
|
|
|
uint8 m_stackAmount; // Aura stack amount
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2010-01-10 01:23:15 +01:00
|
|
|
AuraEffect * m_effects[3];
|
2010-01-10 02:12:02 +01:00
|
|
|
ApplicationMap m_applications;
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2009-04-07 20:27:34 +02:00
|
|
|
bool m_isRemoved:1;
|
2010-01-10 01:23:15 +01:00
|
|
|
bool m_isSingleTarget:1; // true if it's a single target spell and registered at caster - can change at spell steal for example
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2010-01-10 01:23:15 +01:00
|
|
|
private:
|
|
|
|
|
Unit::AuraApplicationList m_removedApplications;
|
2009-04-06 13:31:14 +02:00
|
|
|
};
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2010-02-05 00:31:28 +01:00
|
|
|
class UnitAura : public Aura
|
2009-04-06 13:31:14 +02:00
|
|
|
{
|
2010-01-10 01:23:15 +01:00
|
|
|
friend Aura * Aura::Create(SpellEntry const* spellproto, uint8 effMask, WorldObject * owner, Unit * caster, int32 *baseAmount, Item * castItem, uint64 casterGUID);
|
2009-04-06 13:31:14 +02:00
|
|
|
protected:
|
2010-01-10 01:23:15 +01:00
|
|
|
explicit UnitAura(SpellEntry const* spellproto, uint8 effMask, WorldObject * owner, Unit * caster, int32 *baseAmount, Item * castItem, uint64 casterGUID);
|
|
|
|
|
public:
|
|
|
|
|
void _ApplyForTarget(Unit * target, Unit * caster, AuraApplication * aurApp);
|
|
|
|
|
void _UnapplyForTarget(Unit * target, Unit * caster, AuraApplication * aurApp);
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2010-01-10 01:23:15 +01:00
|
|
|
void Remove(AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2010-01-24 13:08:25 +01:00
|
|
|
void FillTargetMap(std::map<Unit *, uint8> & targets, Unit * caster);
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2010-01-10 01:23:15 +01:00
|
|
|
// Allow Apply Aura Handler to modify and access m_AuraDRGroup
|
|
|
|
|
void SetDiminishGroup(DiminishingGroup group) { m_AuraDRGroup = group; }
|
|
|
|
|
DiminishingGroup GetDiminishGroup() const { return m_AuraDRGroup; }
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2009-08-28 19:46:09 +02:00
|
|
|
private:
|
2010-01-10 01:23:15 +01:00
|
|
|
DiminishingGroup m_AuraDRGroup:8; // Diminishing
|
2008-10-02 16:23:55 -05:00
|
|
|
};
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2010-02-05 00:31:28 +01:00
|
|
|
class DynObjAura : public Aura
|
2008-10-02 16:23:55 -05:00
|
|
|
{
|
2010-01-10 01:23:15 +01:00
|
|
|
friend Aura * Aura::Create(SpellEntry const* spellproto, uint8 effMask, WorldObject * owner, Unit * caster, int32 *baseAmount, Item * castItem, uint64 casterGUID);
|
2009-08-24 22:31:54 -05:00
|
|
|
protected:
|
2010-01-10 01:23:15 +01:00
|
|
|
explicit DynObjAura(SpellEntry const* spellproto, uint8 effMask, WorldObject * owner, Unit * caster, int32 *baseAmount, Item * castItem, uint64 casterGUID);
|
2008-10-02 16:23:55 -05:00
|
|
|
public:
|
2010-01-10 01:23:15 +01:00
|
|
|
void Remove(AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2010-01-24 13:08:25 +01:00
|
|
|
void FillTargetMap(std::map<Unit *, uint8> & targets, Unit * caster);
|
2010-01-10 01:23:15 +01:00
|
|
|
};
|
2008-10-02 16:23:55 -05:00
|
|
|
#endif
|