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
*
* 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/>.
2010-07-24 22:41:42 +02:00
*/
#ifndef __SPELL_SCRIPT_H
#define __SPELL_SCRIPT_H
2010-07-27 04:31:27 +02:00
#include "Util.h"
2010-07-25 00:36:32 +02:00
#include "SharedDefines.h"
2010-08-24 00:10:49 +02:00
#include "SpellAuraDefines.h"
2011-05-26 16:12:33 +02:00
#include <stack>
2010-07-25 00:36:32 +02:00
2010-07-24 22:41:42 +02:00
class Unit ;
2011-07-26 23:09:28 +02:00
class SpellInfo ;
2010-07-24 22:41:42 +02:00
class SpellScript ;
class Spell ;
2010-08-19 14:31:31 +02:00
class Aura ;
2010-08-24 00:10:49 +02:00
class AuraEffect ;
struct SpellModifier ;
2010-07-25 00:36:32 +02:00
class Creature ;
class GameObject ;
2010-08-24 00:10:49 +02:00
class DynamicObject ;
2010-07-25 00:36:32 +02:00
class Player ;
class Item ;
2010-07-25 16:23:57 +02:00
class WorldLocation ;
2010-08-24 00:10:49 +02:00
class WorldObject ;
2010-07-24 22:41:42 +02:00
#define SPELL_EFFECT_ANY (uint16)-1
#define SPELL_AURA_ANY (uint16)-1
2010-10-04 17:44:49 +02:00
enum SpellScriptState
{
SPELL_SCRIPT_STATE_NONE = 0 ,
SPELL_SCRIPT_STATE_REGISTRATION ,
SPELL_SCRIPT_STATE_LOADING ,
SPELL_SCRIPT_STATE_UNLOADING ,
};
#define SPELL_SCRIPT_STATE_END SPELL_SCRIPT_STATE_UNLOADING + 1
2010-07-24 22:41:42 +02:00
// helper class from which SpellScript and SpellAura derive, use these classes instead
class _SpellScript
{
// internal use classes & functions
// DO NOT OVERRIDE THESE IN SCRIPTS
protected :
2011-07-26 23:09:28 +02:00
virtual bool _Validate ( SpellInfo const * entry );
2011-04-27 18:58:40 +02:00
2010-10-04 17:44:49 +02:00
public :
2011-05-26 16:12:33 +02:00
_SpellScript () : m_currentScriptState ( SPELL_SCRIPT_STATE_NONE ) {}
2010-12-14 15:46:54 +01:00
virtual ~ _SpellScript () {}
2010-10-04 17:44:49 +02:00
virtual void _Register ();
virtual void _Unload ();
2011-04-27 18:58:40 +02:00
virtual void _Init ( std :: string const * scriptname , uint32 spellId );
2010-07-24 22:41:42 +02:00
protected :
class EffectHook
{
public :
EffectHook ( uint8 _effIndex );
2011-07-26 23:09:28 +02:00
uint8 GetAffectedEffectsMask ( SpellInfo const * spellEntry );
bool IsEffectAffected ( SpellInfo const * spellEntry , uint8 effIndex );
virtual bool CheckEffect ( SpellInfo const * spellEntry , uint8 effIndex ) = 0 ;
2010-07-24 22:41:42 +02:00
std :: string EffIndexToString ();
protected :
uint8 effIndex ;
};
2011-04-27 18:58:40 +02:00
2010-07-24 22:41:42 +02:00
class EffectNameCheck
{
public :
EffectNameCheck ( uint16 _effName ) { effName = _effName ;};
2011-07-26 23:09:28 +02:00
bool Check ( SpellInfo const * spellEntry , uint8 effIndex );
2010-07-24 22:41:42 +02:00
std :: string ToString ();
private :
uint16 effName ;
};
2011-04-27 18:58:40 +02:00
2010-07-24 22:41:42 +02:00
class EffectAuraNameCheck
{
public :
EffectAuraNameCheck ( uint16 _effAurName ) { effAurName = _effAurName ; }
2011-07-26 23:09:28 +02:00
bool Check ( SpellInfo const * spellEntry , uint8 effIndex );
2010-07-24 22:41:42 +02:00
std :: string ToString ();
private :
uint16 effAurName ;
};
2010-10-04 17:44:49 +02:00
uint8 m_currentScriptState ;
2011-04-27 18:58:40 +02:00
std :: string const * m_scriptName ;
2010-10-04 17:44:49 +02:00
uint32 m_scriptSpellId ;
2010-07-24 22:41:42 +02:00
public :
//
// SpellScript/AuraScript interface base
// these functions are safe to override, see notes below for usage instructions
2010-08-08 19:45:53 +02:00
//
2010-07-24 22:41:42 +02:00
// Function in which handler functions are registered, must be implemented in script
virtual void Register () = 0 ;
// Function called on server startup, if returns false script won't be used in core
// use for: dbc/template data presence/correctness checks
2011-07-26 23:09:28 +02:00
virtual bool Validate ( SpellInfo const * /*spellEntry*/ ) { return true ; }
2010-07-24 22:41:42 +02:00
// Function called when script is created, if returns false script will be unloaded afterwards
// use for: initializing local script variables (DO NOT USE CONSTRUCTOR FOR THIS PURPOSE!)
2011-04-27 18:58:40 +02:00
virtual bool Load () { return true ; }
2010-07-24 22:41:42 +02:00
// Function called when script is destroyed
// use for: deallocating memory allocated by script
2011-04-27 18:58:40 +02:00
virtual void Unload () {}
2010-07-24 22:41:42 +02:00
};
2010-10-04 19:12:20 +02:00
// SpellScript interface - enum used for runtime checks of script function calls
enum SpellScriptHookType
{
SPELL_SCRIPT_HOOK_EFFECT = SPELL_SCRIPT_STATE_END ,
SPELL_SCRIPT_HOOK_BEFORE_HIT ,
SPELL_SCRIPT_HOOK_HIT ,
SPELL_SCRIPT_HOOK_AFTER_HIT ,
2011-01-21 23:42:51 +01:00
SPELL_SCRIPT_HOOK_UNIT_TARGET_SELECT ,
2011-03-04 21:18:38 +01:00
SPELL_SCRIPT_HOOK_CHECK_CAST ,
2010-10-04 19:12:20 +02:00
};
2011-04-27 18:58:40 +02:00
2010-10-04 19:12:20 +02:00
#define HOOK_SPELL_HIT_START SPELL_SCRIPT_HOOK_EFFECT
#define HOOK_SPELL_HIT_END SPELL_SCRIPT_HOOK_AFTER_HIT + 1
#define HOOK_SPELL_START SPELL_SCRIPT_HOOK_EFFECT
2011-03-04 21:18:38 +01:00
#define HOOK_SPELL_END SPELL_SCRIPT_HOOK_CHECK_CAST + 1
2010-10-04 19:12:20 +02:00
#define HOOK_SPELL_COUNT HOOK_SPELL_END - HOOK_SPELL_START
2010-07-24 22:41:42 +02:00
class SpellScript : public _SpellScript
{
// internal use classes & functions
// DO NOT OVERRIDE THESE IN SCRIPTS
public :
2010-10-08 21:33:44 +02:00
#define SPELLSCRIPT_FUNCTION_TYPE_DEFINES(CLASSNAME) \
2011-03-04 21:18:38 +01:00
typedef SpellCastResult(CLASSNAME::*SpellCheckCastFnType)(); \
2010-10-08 21:33:44 +02:00
typedef void(CLASSNAME::*SpellEffectFnType)(SpellEffIndex); \
typedef void(CLASSNAME::*SpellHitFnType)(); \
2011-01-21 23:42:51 +01:00
typedef void(CLASSNAME::*SpellUnitTargetFnType)(std::list<Unit*>&); \
2010-10-08 21:33:44 +02:00
SPELLSCRIPT_FUNCTION_TYPE_DEFINES ( SpellScript )
2010-08-24 00:10:49 +02:00
2011-03-04 21:18:38 +01:00
class CheckCastHandler
{
public :
CheckCastHandler ( SpellCheckCastFnType checkCastHandlerScript );
SpellCastResult Call ( SpellScript * spellScript );
private :
SpellCheckCastFnType _checkCastHandlerScript ;
};
2010-07-24 22:41:42 +02:00
class EffectHandler : public _SpellScript :: EffectNameCheck , public _SpellScript :: EffectHook
{
public :
2011-04-29 20:47:02 +02:00
EffectHandler ( SpellEffectFnType _pEffectHandlerScript , uint8 _effIndex , uint16 _effName );
2010-07-24 22:41:42 +02:00
std :: string ToString ();
2011-07-26 23:09:28 +02:00
bool CheckEffect ( SpellInfo const * spellEntry , uint8 effIndex );
2011-04-27 18:58:40 +02:00
void Call ( SpellScript * spellScript , SpellEffIndex effIndex );
2010-07-24 22:41:42 +02:00
private :
2010-08-24 00:10:49 +02:00
SpellEffectFnType pEffectHandlerScript ;
2010-07-24 22:41:42 +02:00
};
2010-10-08 21:33:44 +02:00
class HitHandler
{
public :
HitHandler ( SpellHitFnType _pHitHandlerScript );
2011-04-27 18:58:40 +02:00
void Call ( SpellScript * spellScript );
2010-10-08 21:33:44 +02:00
private :
SpellHitFnType pHitHandlerScript ;
};
2011-01-21 23:42:51 +01:00
class UnitTargetHandler : public _SpellScript :: EffectHook
{
public :
UnitTargetHandler ( SpellUnitTargetFnType _pUnitTargetHandlerScript , uint8 _effIndex , uint16 _targetType );
std :: string ToString ();
2011-07-26 23:09:28 +02:00
bool CheckEffect ( SpellInfo const * spellEntry , uint8 targetType );
2011-04-27 18:58:40 +02:00
void Call ( SpellScript * spellScript , std :: list < Unit *>& unitTargets );
2011-01-21 23:42:51 +01:00
private :
SpellUnitTargetFnType pUnitTargetHandlerScript ;
uint16 targetType ;
};
2010-10-08 21:33:44 +02:00
#define SPELLSCRIPT_FUNCTION_CAST_DEFINES(CLASSNAME) \
2011-03-04 21:18:38 +01:00
class CheckCastHandlerFunction : public SpellScript::CheckCastHandler { public: CheckCastHandlerFunction(SpellCheckCastFnType _checkCastHandlerScript) : SpellScript::CheckCastHandler((SpellScript::SpellCheckCastFnType)_checkCastHandlerScript) {} }; \
2011-04-29 20:47:02 +02:00
class EffectHandlerFunction : public SpellScript::EffectHandler { public: EffectHandlerFunction(SpellEffectFnType _pEffectHandlerScript, uint8 _effIndex, uint16 _effName) : SpellScript::EffectHandler((SpellScript::SpellEffectFnType)_pEffectHandlerScript, _effIndex, _effName) {} }; \
2010-10-08 21:33:44 +02:00
class HitHandlerFunction : public SpellScript::HitHandler { public: HitHandlerFunction(SpellHitFnType _pHitHandlerScript) : SpellScript::HitHandler((SpellScript::SpellHitFnType)_pHitHandlerScript) {} }; \
2011-01-21 23:42:51 +01:00
class UnitTargetHandlerFunction : public SpellScript::UnitTargetHandler { public: UnitTargetHandlerFunction(SpellUnitTargetFnType _pUnitTargetHandlerScript, uint8 _effIndex, uint16 _targetType) : SpellScript::UnitTargetHandler((SpellScript::SpellUnitTargetFnType)_pUnitTargetHandlerScript, _effIndex, _targetType) {} }; \
2010-10-08 21:33:44 +02:00
#define PrepareSpellScript(CLASSNAME) SPELLSCRIPT_FUNCTION_TYPE_DEFINES(CLASSNAME) SPELLSCRIPT_FUNCTION_CAST_DEFINES(CLASSNAME)
2010-07-24 22:41:42 +02:00
public :
2011-07-26 23:09:28 +02:00
bool _Validate ( SpellInfo const * entry );
2011-04-27 18:58:40 +02:00
bool _Load ( Spell * spell );
2010-08-19 14:31:31 +02:00
void _InitHit ();
2011-01-21 23:42:51 +01:00
bool _IsEffectPrevented ( SpellEffIndex effIndex ) { return m_hitPreventEffectMask & ( 1 << effIndex ); }
bool _IsDefaultEffectPrevented ( SpellEffIndex effIndex ) { return m_hitPreventDefaultEffectMask & ( 1 << effIndex ); }
2010-10-05 08:17:10 +02:00
void _PrepareScriptCall ( SpellScriptHookType hookType );
void _FinishScriptCall ();
2011-03-04 21:18:38 +01:00
bool IsInCheckCastHook () const { return m_currentScriptState == SPELL_SCRIPT_HOOK_CHECK_CAST ; }
bool IsInHitPhase () const { return ( m_currentScriptState >= HOOK_SPELL_HIT_START && m_currentScriptState < HOOK_SPELL_HIT_END ); }
bool IsInEffectHook () const { return ( m_currentScriptState == SPELL_SCRIPT_HOOK_EFFECT ); }
2010-07-24 22:41:42 +02:00
private :
2011-04-27 18:58:40 +02:00
Spell * m_spell ;
2010-08-19 14:31:31 +02:00
uint8 m_hitPreventEffectMask ;
uint8 m_hitPreventDefaultEffectMask ;
2010-07-24 22:41:42 +02:00
public :
//
// SpellScript interface
// hooks to which you can attach your functions
2010-08-08 19:45:53 +02:00
//
2011-03-04 21:18:38 +01:00
// example: OnCheckCast += SpellCheckCastFn();
// where function is SpellCastResult function()
HookList < CheckCastHandler > OnCheckCast ;
#define SpellCheckCastFn(F) CheckCastHandlerFunction(&F)
2010-08-24 00:10:49 +02:00
// example: OnEffect += SpellEffectFn(class::function, EffectIndexSpecifier, EffectNameSpecifier);
// where function is void function(SpellEffIndex effIndex)
HookList < EffectHandler > OnEffect ;
2010-10-08 21:33:44 +02:00
#define SpellEffectFn(F, I, N) EffectHandlerFunction(&F, I, N)
2010-08-24 00:10:49 +02:00
// example: BeforeHit += SpellHitFn(class::function);
2010-08-21 20:18:54 +02:00
HookList < HitHandler > BeforeHit ;
2010-08-24 00:10:49 +02:00
// example: OnHit += SpellHitFn(class::function);
2010-08-21 20:18:54 +02:00
HookList < HitHandler > OnHit ;
2010-08-24 00:10:49 +02:00
// example: AfterHit += SpellHitFn(class::function);
2010-08-21 20:18:54 +02:00
HookList < HitHandler > AfterHit ;
2010-08-24 00:10:49 +02:00
// where function is: void function()
2010-10-08 21:33:44 +02:00
#define SpellHitFn(F) HitHandlerFunction(&F)
2010-08-21 20:18:54 +02:00
2011-01-21 23:42:51 +01:00
// example: OnUnitTargetSelect += SpellUnitTargetFn(class::function, EffectIndexSpecifier, TargetsNameSpecifier);
// where function is void function(std::list<Unit*>& targetList)
HookList < UnitTargetHandler > OnUnitTargetSelect ;
#define SpellUnitTargetFn(F, I, N) UnitTargetHandlerFunction(&F, I, N)
2010-08-21 20:18:54 +02:00
// hooks are executed in following order, at specified event of spell:
2011-01-21 23:42:51 +01:00
// 1. OnUnitTargetSelect - executed just before adding selected targets to final target list
// 2. BeforeHit - executed just before spell hits a target
// 3. OnEffect - executed just before specified effect handler call
// 4. OnHit - executed just before spell deals damage and procs auras
// 5. AfterHit - executed just after spell finishes all it's jobs for target
2010-07-24 22:41:42 +02:00
2010-07-25 16:23:57 +02:00
//
2010-07-24 22:41:42 +02:00
// methods allowing interaction with Spell object
2010-07-25 16:23:57 +02:00
//
// methods useable during all spell handling phases
2011-04-27 18:58:40 +02:00
Unit * GetCaster ();
Unit * GetOriginalCaster ();
2011-07-26 23:09:28 +02:00
SpellInfo const * GetSpellInfo ();
2010-07-25 02:05:12 +02:00
2010-07-25 16:23:57 +02:00
// methods useable after spell targets are set
2010-10-04 20:32:10 +02:00
// accessors to the "focus" targets of the spell
// note: do not confuse these with spell hit targets
// returns: WorldLocation which was selected as a spell destination or NULL
2011-06-23 13:28:52 +02:00
WorldLocation const * GetTargetDest ();
void SetTargetDest ( WorldLocation & loc );
2010-10-04 20:32:10 +02:00
// returns: Unit which was selected as a spell target or NULL
2011-04-27 18:58:40 +02:00
Unit * GetTargetUnit ();
2010-10-04 20:32:10 +02:00
// returns: GameObject which was selected as a spell target or NULL
2011-04-27 18:58:40 +02:00
GameObject * GetTargetGObj ();
2010-10-04 20:32:10 +02:00
// returns: Item which was selected as a spell target or NULL
2011-04-27 18:58:40 +02:00
Item * GetTargetItem ();
2010-07-25 16:23:57 +02:00
// methods useable only during spell hit on target phase:
2010-08-08 19:45:53 +02:00
2010-07-25 02:05:12 +02:00
// returns: target of current effect if it was Unit otherwise NULL
2011-04-27 18:58:40 +02:00
Unit * GetHitUnit ();
2010-07-25 02:05:12 +02:00
// returns: target of current effect if it was Creature otherwise NULL
2011-04-27 18:58:40 +02:00
Creature * GetHitCreature ();
2010-07-25 02:05:12 +02:00
// returns: target of current effect if it was Player otherwise NULL
2011-04-27 18:58:40 +02:00
Player * GetHitPlayer ();
2010-07-25 02:05:12 +02:00
// returns: target of current effect if it was Item otherwise NULL
2011-06-11 22:35:29 +02:00
Item * GetHitItem ();
2010-07-25 02:05:12 +02:00
// returns: target of current effect if it was GameObject otherwise NULL
2011-04-27 18:58:40 +02:00
GameObject * GetHitGObj ();
2010-07-25 16:23:57 +02:00
// setter/getter for for damage done by spell to target of spell hit
int32 GetHitDamage ();
void SetHitDamage ( int32 damage );
2011-04-27 18:58:40 +02:00
void PreventHitDamage () { SetHitDamage ( 0 ); }
2010-07-25 16:23:57 +02:00
// setter/getter for for heal done by spell to target of spell hit
int32 GetHitHeal ();
void SetHitHeal ( int32 heal );
2011-04-27 18:58:40 +02:00
void PreventHitHeal () { SetHitHeal ( 0 ); }
2010-08-19 14:31:31 +02:00
// returns current spell hit target aura
2011-04-27 18:58:40 +02:00
Aura * GetHitAura ();
2010-08-19 14:31:31 +02:00
// prevents applying aura on current spell hit target
void PreventHitAura ();
// prevents effect execution on current spell hit target
// including other effect/hit scripts
// will not work on aura/damage/heal
// will not work if effects were already handled
void PreventHitEffect ( SpellEffIndex effIndex );
// prevents default effect execution on current spell hit target
// will not work on aura/damage/heal effects
// will not work if effects were already handled
void PreventHitDefaultEffect ( SpellEffIndex effIndex );
2010-07-25 16:23:57 +02:00
// method avalible only in EffectHandler method
2010-07-24 22:41:42 +02:00
int32 GetEffectValue ();
2010-08-18 00:20:23 +06:00
// returns: cast item if present.
2011-04-27 18:58:40 +02:00
Item * GetCastItem ();
2010-08-18 00:20:23 +06:00
// Creates item. Calls Spell::DoCreateItem method.
void CreateItem ( uint32 effIndex , uint32 itemId );
2011-01-22 17:21:24 +01:00
// finishes spellcast prematurely with selected error message
void FinishCast ( SpellCastResult result );
2011-03-04 21:18:38 +01:00
void SetCustomCastResultMessage ( SpellCustomErrors result );
2010-07-24 22:41:42 +02:00
};
2010-08-24 00:10:49 +02:00
2010-10-04 19:12:20 +02:00
// AuraScript interface - enum used for runtime checks of script function calls
2010-10-04 17:44:49 +02:00
enum AuraScriptHookType
{
AURA_SCRIPT_HOOK_EFFECT_APPLY = SPELL_SCRIPT_STATE_END ,
2011-05-26 16:12:33 +02:00
AURA_SCRIPT_HOOK_EFFECT_AFTER_APPLY ,
2010-10-04 17:44:49 +02:00
AURA_SCRIPT_HOOK_EFFECT_REMOVE ,
2011-05-26 16:12:33 +02:00
AURA_SCRIPT_HOOK_EFFECT_AFTER_REMOVE ,
2010-10-04 17:44:49 +02:00
AURA_SCRIPT_HOOK_EFFECT_PERIODIC ,
AURA_SCRIPT_HOOK_EFFECT_UPDATE_PERIODIC ,
AURA_SCRIPT_HOOK_EFFECT_CALC_AMOUNT ,
AURA_SCRIPT_HOOK_EFFECT_CALC_PERIODIC ,
AURA_SCRIPT_HOOK_EFFECT_CALC_SPELLMOD ,
2010-12-27 20:14:54 +01:00
AURA_SCRIPT_HOOK_EFFECT_ABSORB ,
2010-12-30 02:03:46 +01:00
AURA_SCRIPT_HOOK_EFFECT_AFTER_ABSORB ,
2010-12-30 19:05:19 +01:00
AURA_SCRIPT_HOOK_EFFECT_MANASHIELD ,
AURA_SCRIPT_HOOK_EFFECT_AFTER_MANASHIELD ,
2011-05-31 20:02:55 +02:00
AURA_SCRIPT_HOOK_CHECK_AREA_TARGET ,
2010-10-04 17:44:49 +02:00
/*AURA_SCRIPT_HOOK_APPLY,
2011-04-29 20:47:02 +02:00
AURA_SCRIPT_HOOK_REMOVE, */
2010-10-04 17:44:49 +02:00
};
#define HOOK_AURA_EFFECT_START HOOK_AURA_EFFECT_APPLY
#define HOOK_AURA_EFFECT_END HOOK_AURA_EFFECT_CALC_SPELLMOD + 1
#define HOOK_AURA_EFFECT_COUNT HOOK_AURA_EFFECT_END - HOOK_AURA_EFFECT_START
2010-08-24 00:10:49 +02:00
class AuraScript : public _SpellScript
{
// internal use classes & functions
// DO NOT OVERRIDE THESE IN SCRIPTS
public :
2010-10-08 21:33:44 +02:00
#define AURASCRIPT_FUNCTION_TYPE_DEFINES(CLASSNAME) \
2011-06-11 22:35:29 +02:00
typedef bool(CLASSNAME::*AuraCheckAreaTargetFnType)(Unit* target); \
2010-12-27 20:14:54 +01:00
typedef void(CLASSNAME::*AuraEffectApplicationModeFnType)(AuraEffect const *, AuraEffectHandleModes); \
typedef void(CLASSNAME::*AuraEffectPeriodicFnType)(AuraEffect const *); \
2010-10-08 21:33:44 +02:00
typedef void(CLASSNAME::*AuraEffectUpdatePeriodicFnType)(AuraEffect *); \
typedef void(CLASSNAME::*AuraEffectCalcAmountFnType)(AuraEffect const *, int32 &, bool &); \
typedef void(CLASSNAME::*AuraEffectCalcPeriodicFnType)(AuraEffect const *, bool &, int32 &); \
typedef void(CLASSNAME::*AuraEffectCalcSpellModFnType)(AuraEffect const *, SpellModifier *&); \
2010-12-27 20:14:54 +01:00
typedef void(CLASSNAME::*AuraEffectAbsorbFnType)(AuraEffect *, DamageInfo &, uint32 &); \
2010-10-08 21:33:44 +02:00
AURASCRIPT_FUNCTION_TYPE_DEFINES ( AuraScript )
2010-08-24 00:10:49 +02:00
2011-05-31 20:02:55 +02:00
class CheckAreaTargetHandler
{
public :
CheckAreaTargetHandler ( AuraCheckAreaTargetFnType pHandlerScript );
2011-06-11 22:35:29 +02:00
bool Call ( AuraScript * auraScript , Unit * target );
2011-05-31 20:02:55 +02:00
private :
AuraCheckAreaTargetFnType pHandlerScript ;
};
2010-08-24 00:10:49 +02:00
class EffectBase : public _SpellScript :: EffectAuraNameCheck , public _SpellScript :: EffectHook
{
public :
EffectBase ( uint8 _effIndex , uint16 _effName );
std :: string ToString ();
2011-07-26 23:09:28 +02:00
bool CheckEffect ( SpellInfo const * spellEntry , uint8 effIndex );
2010-08-24 00:10:49 +02:00
};
class EffectPeriodicHandler : public EffectBase
{
public :
2011-04-29 20:47:02 +02:00
EffectPeriodicHandler ( AuraEffectPeriodicFnType _pEffectHandlerScript , uint8 _effIndex , uint16 _effName );
2011-06-11 22:35:29 +02:00
void Call ( AuraScript * auraScript , AuraEffect const * _aurEff );
2010-08-24 00:10:49 +02:00
private :
AuraEffectPeriodicFnType pEffectHandlerScript ;
};
class EffectUpdatePeriodicHandler : public EffectBase
{
public :
2011-04-29 20:47:02 +02:00
EffectUpdatePeriodicHandler ( AuraEffectUpdatePeriodicFnType _pEffectHandlerScript , uint8 _effIndex , uint16 _effName );
2010-08-24 00:10:49 +02:00
void Call ( AuraScript * auraScript , AuraEffect * aurEff );
private :
AuraEffectUpdatePeriodicFnType pEffectHandlerScript ;
};
class EffectCalcAmountHandler : public EffectBase
{
public :
2011-04-29 20:47:02 +02:00
EffectCalcAmountHandler ( AuraEffectCalcAmountFnType _pEffectHandlerScript , uint8 _effIndex , uint16 _effName );
2010-08-24 00:10:49 +02:00
void Call ( AuraScript * auraScript , AuraEffect const * aurEff , int32 & amount , bool & canBeRecalculated );
private :
AuraEffectCalcAmountFnType pEffectHandlerScript ;
};
class EffectCalcPeriodicHandler : public EffectBase
{
public :
2011-04-29 20:47:02 +02:00
EffectCalcPeriodicHandler ( AuraEffectCalcPeriodicFnType _pEffectHandlerScript , uint8 _effIndex , uint16 _effName );
2010-08-24 00:10:49 +02:00
void Call ( AuraScript * auraScript , AuraEffect const * aurEff , bool & isPeriodic , int32 & periodicTimer );
private :
AuraEffectCalcPeriodicFnType pEffectHandlerScript ;
};
class EffectCalcSpellModHandler : public EffectBase
{
public :
2011-04-29 20:47:02 +02:00
EffectCalcSpellModHandler ( AuraEffectCalcSpellModFnType _pEffectHandlerScript , uint8 _effIndex , uint16 _effName );
2010-08-24 00:10:49 +02:00
void Call ( AuraScript * auraScript , AuraEffect const * aurEff , SpellModifier *& spellMod );
private :
AuraEffectCalcSpellModFnType pEffectHandlerScript ;
};
class EffectApplyHandler : public EffectBase
{
public :
2011-04-29 20:47:02 +02:00
EffectApplyHandler ( AuraEffectApplicationModeFnType _pEffectHandlerScript , uint8 _effIndex , uint16 _effName , AuraEffectHandleModes _mode );
2011-06-11 22:35:29 +02:00
void Call ( AuraScript * auraScript , AuraEffect const * _aurEff , AuraEffectHandleModes _mode );
2010-08-24 00:10:49 +02:00
private :
AuraEffectApplicationModeFnType pEffectHandlerScript ;
AuraEffectHandleModes mode ;
};
2010-12-27 20:14:54 +01:00
class EffectAbsorbHandler : public EffectBase
{
public :
EffectAbsorbHandler ( AuraEffectAbsorbFnType _pEffectHandlerScript , uint8 _effIndex );
void Call ( AuraScript * auraScript , AuraEffect * aurEff , DamageInfo & dmgInfo , uint32 & absorbAmount );
private :
AuraEffectAbsorbFnType pEffectHandlerScript ;
};
2010-12-30 19:05:19 +01:00
class EffectManaShieldHandler : public EffectBase
{
public :
EffectManaShieldHandler ( AuraEffectAbsorbFnType _pEffectHandlerScript , uint8 _effIndex );
void Call ( AuraScript * auraScript , AuraEffect * aurEff , DamageInfo & dmgInfo , uint32 & absorbAmount );
private :
AuraEffectAbsorbFnType pEffectHandlerScript ;
};
2010-10-08 22:33:21 +02:00
#define AURASCRIPT_FUNCTION_CAST_DEFINES(CLASSNAME) \
2011-05-31 20:02:55 +02:00
class CheckAreaTargetFunction : public AuraScript::CheckAreaTargetHandler { public: CheckAreaTargetFunction(AuraCheckAreaTargetFnType _pHandlerScript) : AuraScript::CheckAreaTargetHandler((AuraScript::AuraCheckAreaTargetFnType)_pHandlerScript) {} }; \
2011-04-29 20:47:02 +02:00
class EffectPeriodicHandlerFunction : public AuraScript::EffectPeriodicHandler { public: EffectPeriodicHandlerFunction(AuraEffectPeriodicFnType _pEffectHandlerScript, uint8 _effIndex, uint16 _effName) : AuraScript::EffectPeriodicHandler((AuraScript::AuraEffectPeriodicFnType)_pEffectHandlerScript, _effIndex, _effName) {} }; \
class EffectUpdatePeriodicHandlerFunction : public AuraScript::EffectUpdatePeriodicHandler { public: EffectUpdatePeriodicHandlerFunction(AuraEffectUpdatePeriodicFnType _pEffectHandlerScript, uint8 _effIndex, uint16 _effName) : AuraScript::EffectUpdatePeriodicHandler((AuraScript::AuraEffectUpdatePeriodicFnType)_pEffectHandlerScript, _effIndex, _effName) {} }; \
class EffectCalcAmountHandlerFunction : public AuraScript::EffectCalcAmountHandler { public: EffectCalcAmountHandlerFunction(AuraEffectCalcAmountFnType _pEffectHandlerScript, uint8 _effIndex, uint16 _effName) : AuraScript::EffectCalcAmountHandler((AuraScript::AuraEffectCalcAmountFnType)_pEffectHandlerScript, _effIndex, _effName) {} }; \
class EffectCalcPeriodicHandlerFunction : public AuraScript::EffectCalcPeriodicHandler { public: EffectCalcPeriodicHandlerFunction(AuraEffectCalcPeriodicFnType _pEffectHandlerScript, uint8 _effIndex, uint16 _effName) : AuraScript::EffectCalcPeriodicHandler((AuraScript::AuraEffectCalcPeriodicFnType)_pEffectHandlerScript, _effIndex, _effName) {} }; \
class EffectCalcSpellModHandlerFunction : public AuraScript::EffectCalcSpellModHandler { public: EffectCalcSpellModHandlerFunction(AuraEffectCalcSpellModFnType _pEffectHandlerScript, uint8 _effIndex, uint16 _effName) : AuraScript::EffectCalcSpellModHandler((AuraScript::AuraEffectCalcSpellModFnType)_pEffectHandlerScript, _effIndex, _effName) {} }; \
class EffectApplyHandlerFunction : public AuraScript::EffectApplyHandler { public: EffectApplyHandlerFunction(AuraEffectApplicationModeFnType _pEffectHandlerScript, uint8 _effIndex, uint16 _effName, AuraEffectHandleModes _mode) : AuraScript::EffectApplyHandler((AuraScript::AuraEffectApplicationModeFnType)_pEffectHandlerScript, _effIndex, _effName, _mode) {} }; \
class EffectAbsorbFunction : public AuraScript::EffectAbsorbHandler { public: EffectAbsorbFunction(AuraEffectAbsorbFnType _pEffectHandlerScript, uint8 _effIndex) : AuraScript::EffectAbsorbHandler((AuraScript::AuraEffectAbsorbFnType)_pEffectHandlerScript, _effIndex) {} }; \
class EffectManaShieldFunction : public AuraScript::EffectManaShieldHandler { public: EffectManaShieldFunction(AuraEffectAbsorbFnType _pEffectHandlerScript, uint8 _effIndex) : AuraScript::EffectManaShieldHandler((AuraScript::AuraEffectAbsorbFnType)_pEffectHandlerScript, _effIndex) {} }; \
2010-10-08 22:33:21 +02:00
#define PrepareAuraScript(CLASSNAME) AURASCRIPT_FUNCTION_TYPE_DEFINES(CLASSNAME) AURASCRIPT_FUNCTION_CAST_DEFINES(CLASSNAME)
2010-08-24 00:10:49 +02:00
public :
2011-05-26 16:12:33 +02:00
AuraScript () : _SpellScript (), m_aura ( NULL ), m_auraApplication ( NULL ), m_defaultActionPrevented ( false )
{}
2011-07-26 23:09:28 +02:00
bool _Validate ( SpellInfo const * entry );
2010-08-24 00:10:49 +02:00
bool _Load ( Aura * aura );
2011-06-11 22:35:29 +02:00
void _PrepareScriptCall ( AuraScriptHookType hookType , AuraApplication const * aurApp = NULL );
2010-10-04 17:44:49 +02:00
void _FinishScriptCall ();
bool _IsDefaultActionPrevented ();
2010-08-24 00:10:49 +02:00
private :
Aura * m_aura ;
2011-06-11 22:35:29 +02:00
AuraApplication const * m_auraApplication ;
2010-10-04 17:44:49 +02:00
bool m_defaultActionPrevented ;
2011-05-26 16:12:33 +02:00
class ScriptStateStore
{
public :
uint8 _currentScriptState ;
2011-06-11 22:35:29 +02:00
AuraApplication const * _auraApplication ;
2011-05-26 16:12:33 +02:00
bool _defaultActionPrevented ;
2011-06-11 22:35:29 +02:00
ScriptStateStore ( uint8 currentScriptState , AuraApplication const * auraApplication , bool defaultActionPrevented )
2011-05-26 16:12:33 +02:00
: _currentScriptState ( currentScriptState ), _auraApplication ( auraApplication ), _defaultActionPrevented ( defaultActionPrevented )
{}
};
typedef std :: stack < ScriptStateStore > ScriptStateStack ;
ScriptStateStack m_scriptStates ;
2011-06-18 19:51:28 +02:00
2010-08-24 00:10:49 +02:00
public :
//
// AuraScript interface
// hooks to which you can attach your functions
//
2011-05-31 20:02:55 +02:00
// executed when area aura checks if it can be applied on target
// example: OnEffectApply += AuraEffectApplyFn(class::function);
2011-06-11 22:35:29 +02:00
// where function is: bool function (Unit* target);
2011-05-31 20:02:55 +02:00
HookList < CheckAreaTargetHandler > DoCheckAreaTarget ;
#define AuraCheckAreaTargetFn(F) CheckAreaTargetFunction(&F)
2011-05-25 15:13:55 +02:00
// executed when aura effect is applied with specified mode to target
2011-05-25 17:13:32 +02:00
// should be used when when effect handler preventing/replacing is needed, do not use this hook for triggering spellcasts/removing auras etc - may be unsafe
2010-08-24 00:10:49 +02:00
// example: OnEffectApply += AuraEffectApplyFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier, AuraEffectHandleModes);
2011-05-19 13:22:17 +02:00
// where function is: void function (AuraEffect const* aurEff, AuraEffectHandleModes mode);
2010-08-24 00:10:49 +02:00
HookList < EffectApplyHandler > OnEffectApply ;
2011-05-25 17:13:32 +02:00
// executed after aura effect is applied with specified mode to target
// example: AfterEffectApply += AuraEffectApplyFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier, AuraEffectHandleModes);
// where function is: void function (AuraEffect const* aurEff, AuraEffectHandleModes mode);
HookList < EffectApplyHandler > AfterEffectApply ;
2010-12-27 20:14:54 +01:00
#define AuraEffectApplyFn(F, I, N, M) EffectApplyHandlerFunction(&F, I, N, M)
2010-08-24 00:10:49 +02:00
2011-05-25 17:13:32 +02:00
// executed after aura effect is removed with specified mode from target
// should be used when when effect handler preventing/replacing is needed, do not use this hook for triggering spellcasts/removing auras etc - may be unsafe
2010-08-24 00:10:49 +02:00
// example: OnEffectRemove += AuraEffectRemoveFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier, AuraEffectHandleModes);
2011-05-19 13:22:17 +02:00
// where function is: void function (AuraEffect const* aurEff, AuraEffectHandleModes mode);
2010-08-24 00:10:49 +02:00
HookList < EffectApplyHandler > OnEffectRemove ;
2011-05-25 17:13:32 +02:00
// executed when aura effect is removed with specified mode from target
// example: AfterEffectRemove += AuraEffectRemoveFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier, AuraEffectHandleModes);
// where function is: void function (AuraEffect const* aurEff, AuraEffectHandleModes mode);
HookList < EffectApplyHandler > AfterEffectRemove ;
2010-12-27 20:14:54 +01:00
#define AuraEffectRemoveFn(F, I, N, M) EffectApplyHandlerFunction(&F, I, N, M)
2010-08-24 00:10:49 +02:00
// executed when periodic aura effect ticks on target
// example: OnEffectPeriodic += AuraEffectPeriodicFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier);
2011-05-19 13:22:17 +02:00
// where function is: void function (AuraEffect const* aurEff);
2010-08-24 00:10:49 +02:00
HookList < EffectPeriodicHandler > OnEffectPeriodic ;
2010-12-27 20:14:54 +01:00
#define AuraEffectPeriodicFn(F, I, N) EffectPeriodicHandlerFunction(&F, I, N)
2010-08-24 00:10:49 +02:00
// executed when periodic aura effect is updated
// example: OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier);
2011-05-19 13:22:17 +02:00
// where function is: void function (AuraEffect* aurEff);
2010-08-24 00:10:49 +02:00
HookList < EffectUpdatePeriodicHandler > OnEffectUpdatePeriodic ;
2010-12-27 20:14:54 +01:00
#define AuraEffectUpdatePeriodicFn(F, I, N) EffectUpdatePeriodicHandlerFunction(&F, I, N)
2010-08-24 00:10:49 +02:00
// executed when aura effect calculates amount
2010-12-27 20:14:54 +01:00
// example: DoEffectCalcAmount += AuraEffectCalcAmounFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier);
2011-05-19 13:22:17 +02:00
// where function is: void function (AuraEffect* aurEff, int32& amount, bool& canBeRecalculated);
2010-12-27 20:14:54 +01:00
HookList < EffectCalcAmountHandler > DoEffectCalcAmount ;
#define AuraEffectCalcAmountFn(F, I, N) EffectCalcAmountHandlerFunction(&F, I, N)
2010-08-24 00:10:49 +02:00
// executed when aura effect calculates periodic data
2010-12-27 20:14:54 +01:00
// example: DoEffectCalcPeriodic += AuraEffectCalcPeriodicFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier);
2011-05-19 13:22:17 +02:00
// where function is: void function (AuraEffect const* aurEff, bool& isPeriodic, int32& amplitude);
2010-12-27 20:14:54 +01:00
HookList < EffectCalcPeriodicHandler > DoEffectCalcPeriodic ;
#define AuraEffectCalcPeriodicFn(F, I, N) EffectCalcPeriodicHandlerFunction(&F, I, N)
2010-08-24 00:10:49 +02:00
// executed when aura effect calculates spellmod
2010-12-27 20:14:54 +01:00
// example: DoEffectCalcSpellMod += AuraEffectCalcSpellModFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier);
2011-05-19 13:22:17 +02:00
// where function is: void function (AuraEffect const* aurEff, SpellModifier*& spellMod);
2010-12-27 20:14:54 +01:00
HookList < EffectCalcSpellModHandler > DoEffectCalcSpellMod ;
#define AuraEffectCalcSpellModFn(F, I, N) EffectCalcSpellModHandlerFunction(&F, I, N)
// executed when absorb aura effect is going to reduce damage
// example: OnEffectAbsorb += AuraEffectAbsorbFn(class::function, EffectIndexSpecifier);
2011-05-19 13:22:17 +02:00
// where function is: void function (AuraEffect const* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount);
2010-12-27 20:14:54 +01:00
HookList < EffectAbsorbHandler > OnEffectAbsorb ;
#define AuraEffectAbsorbFn(F, I) EffectAbsorbFunction(&F, I)
2010-12-30 19:05:19 +01:00
// executed after absorb aura effect reduced damage to target - absorbAmount is real amount absorbed by aura
// example: AfterEffectAbsorb += AuraEffectAbsorbFn(class::function, EffectIndexSpecifier);
2011-05-19 13:22:17 +02:00
// where function is: void function (AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount);
2010-12-30 02:03:46 +01:00
HookList < EffectAbsorbHandler > AfterEffectAbsorb ;
2010-12-30 19:05:19 +01:00
// executed when mana shield aura effect is going to reduce damage
// example: OnEffectManaShield += AuraEffectAbsorbFn(class::function, EffectIndexSpecifier);
2011-05-19 13:22:17 +02:00
// where function is: void function (AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount);
2010-12-30 19:05:19 +01:00
HookList < EffectManaShieldHandler > OnEffectManaShield ;
#define AuraEffectManaShieldFn(F, I) EffectManaShieldFunction(&F, I)
// executed after mana shield aura effect reduced damage to target - absorbAmount is real amount absorbed by aura
// example: AfterEffectManaShield += AuraEffectAbsorbFn(class::function, EffectIndexSpecifier);
2011-05-19 13:22:17 +02:00
// where function is: void function (AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount);
2010-12-30 19:05:19 +01:00
HookList < EffectManaShieldHandler > AfterEffectManaShield ;
2010-08-24 00:10:49 +02:00
2010-10-04 17:44:49 +02:00
// AuraScript interface - hook/effect execution manipulators
// prevents default action of a hook from being executed (works only while called in a hook which default action can be prevented)
void PreventDefaultAction ();
2010-08-24 00:10:49 +02:00
// AuraScript interface - functions which are redirecting to Aura class
// returns proto of the spell
2011-07-26 23:09:28 +02:00
SpellInfo const * GetSpellInfo () const ;
2010-08-24 00:10:49 +02:00
// returns spellid of the spell
uint32 GetId () const ;
// returns guid of object which casted the aura (m_originalCaster of the Spell class)
2011-08-01 14:51:44 +02:00
unit64 const GetCasterGUID () const ;
2010-08-24 00:10:49 +02:00
// returns unit which casted the aura or NULL if not avalible (caster logged out for example)
Unit * GetCaster () const ;
// returns object on which aura was casted, target for non-area auras, area aura source for area auras
WorldObject * GetOwner () const ;
2010-12-05 21:38:52 +01:00
// returns owner if it's unit or unit derived object, NULL otherwise (only for persistent area auras NULL is returned)
2011-06-11 22:35:29 +02:00
Unit * GetUnitOwner () const ;
2010-08-24 00:10:49 +02:00
// returns owner if it's dynobj, NULL otherwise
DynamicObject * GetDynobjOwner () const ;
// removes aura with remove mode (see AuraRemoveMode enum)
void Remove ( uint32 removeMode = 0 );
// returns aura object of script
Aura * GetAura () const ;
// returns type of the aura, may be dynobj owned aura or unit owned aura
AuraObjectType GetType () const ;
// aura duration manipulation - when duration goes to 0 aura is removed
int32 GetDuration () const ;
void SetDuration ( int32 duration , bool withMods = false );
// sets duration to maxduration
void RefreshDuration ();
time_t GetApplyTime () const ;
int32 GetMaxDuration () const ;
void SetMaxDuration ( int32 duration );
2011-06-07 17:25:34 +02:00
int32 CalcMaxDuration () const ;
2010-08-24 00:10:49 +02:00
// expired - duration just went to 0
bool IsExpired () const ;
// permament - has infinite duration
bool IsPermanent () const ;
// charges manipulation - 0 - not charged aura
uint8 GetCharges () const ;
void SetCharges ( uint8 charges );
2011-06-07 17:25:34 +02:00
uint8 CalcMaxCharges () const ;
bool ModCharges ( int8 num , AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT );
2010-08-24 00:10:49 +02:00
// returns true if last charge dropped
2011-06-07 17:25:34 +02:00
bool DropCharge ( AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT );
2010-08-24 00:10:49 +02:00
// stack amount manipulation
uint8 GetStackAmount () const ;
2011-05-29 13:18:47 +02:00
void SetStackAmount ( uint8 num );
2011-06-07 17:25:34 +02:00
bool ModStackAmount ( int32 num , AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT );
2010-08-24 00:10:49 +02:00
2011-06-16 20:08:28 +07:00
// passive - "working in background", not saved, not removed by immunities, not seen by player
2010-08-24 00:10:49 +02:00
bool IsPassive () const ;
// death persistent - not removed on death
bool IsDeathPersistent () const ;
// check if aura has effect of given effindex
bool HasEffect ( uint8 effIndex ) const ;
// returns aura effect of given effect index or NULL
AuraEffect * GetEffect ( uint8 effIndex ) const ;
// check if aura has effect of given aura type
bool HasEffectType ( AuraType type ) const ;
2010-12-27 20:14:54 +01:00
// AuraScript interface - functions which are redirecting to AuraApplication class
// Do not call these in hooks in which AuraApplication is not avalible, otherwise result will differ from expected (the functions will return NULL)
// returns currently processed target of an aura
2011-05-19 13:22:17 +02:00
// Return value does not need to be NULL-checked, the only situation this will (always)
// return NULL is when the call happens in an unsupported hook, in other cases, it is always valid
2011-06-11 22:35:29 +02:00
Unit * GetTarget () const ;
2010-12-27 20:14:54 +01:00
// returns AuraApplication object of currently processed target
2011-06-11 22:35:29 +02:00
AuraApplication const * GetTargetApplication () const ;
2010-08-24 00:10:49 +02:00
};
2010-08-21 20:18:54 +02:00
2010-07-24 22:41:42 +02:00
//
// definitions:
//
// EffectIndexSpecifier - specifies conditions for effects
// EFFECT_0 - first effect matches
// EFFECT_1 - second effect matches
// EFFECT_2 - third effect matches
// EFFECT_FIRST_FOUND - first effect matching other conditions matches
2010-08-08 19:45:53 +02:00
// EFFECT_ALL - all effects of spell match
2010-07-24 22:41:42 +02:00
//
// EffectNameSpecifier - specifies conditions for spell effect names
// SPELL_EFFECT_ANY - any effect but not 0 matches condition
// SPELL_EFFECT_XXX - one of values of enum SpellEffects - effect with equal name matches
//
#endif // __SPELL_SCRIPT_H