Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
SpellAuraProcRuntime.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#include "CellImpl.h"
7#include "Common.h"
8#include "DynamicObject.h"
9#include "GridNotifiers.h"
10#include "GridNotifiersImpl.h"
11#include "Log.h"
12#include "ObjectAccessor.h"
13#include "ObjectMgr.h"
14#include "Opcodes.h"
15#include "Player.h"
16#include "ScriptMgr.h"
17#include "Spell.h"
18#include "SpellAuraEffects.h"
19#include "SpellMgr.h"
20#include "SpellScript.h"
21#include "Unit.h"
22#include "Util.h"
23#include "Vehicle.h"
24#include "WorldPacket.h"
25
27{
28 /*if (m_procCooldown)
29 {
30 if (m_procCooldown > time(NULL))
31 return true;
32 }*/
33 return false;
34}
35
37{
38 //m_procCooldown = time(NULL) + msec;
39}
40
42{
43 bool prepare = CallScriptPrepareProcHandlers(aurApp, eventInfo);
44 if (!prepare)
45 return;
46
47 // take one charge, aura expiration will be handled in Aura::TriggerProcOnEvent (if needed)
48 if (IsUsingCharges())
49 {
52 }
53
54 SpellProcEntry const* procEntry = sSpellMgr->GetSpellProcEntry(GetId());
55
56 ASSERT(procEntry);
57
58 // cooldowns should be added to the whole aura (see 51698 area aura)
59 AddProcCooldown(procEntry->cooldown);
60}
61
63{
64 SpellProcEntry const* procEntry = sSpellMgr->GetSpellProcEntry(GetId());
65 // only auras with spell proc entry can trigger proc
66 if (!procEntry)
67 return false;
68
69 // check if we have charges to proc with
70 if (IsUsingCharges() && !GetCharges())
71 return false;
72
73 // check proc cooldown
74 if (IsProcOnCooldown())
75 return false;
76
78 // something about triggered spells triggering, and add extra attack effect
79
80 // do checks against db data
81 if (!sSpellMgr->CanSpellTriggerProcOnEvent(*procEntry, eventInfo))
82 return false;
83
84 // do checks using conditions table
85 ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL_PROC, GetId());
86 ConditionSourceInfo condInfo = ConditionSourceInfo(eventInfo.GetActor(), eventInfo.GetActionTarget());
87 if (!sConditionMgr->IsObjectMeetToConditions(condInfo, conditions))
88 return false;
89
90 // AuraScript Hook
91 bool check = const_cast<Aura*>(this)->CallScriptCheckProcHandlers(aurApp, eventInfo);
92 if (!check)
93 return false;
94
96 // do allow additional requirements for procs
97 // this is needed because this is the last moment in which you can prevent aura charge drop on proc
98 // and possibly a way to prevent default checks (if there're going to be any)
99
100 // Check if current equipment meets aura requirements
101 // do that only for passive spells
103 Unit* target = aurApp->GetTarget();
104 if (IsPassive() && target->GetTypeId() == TypeID::TYPEID_PLAYER)
105 {
106 if (GetSpellInfo()->EquippedItemClass == ITEM_CLASS_WEAPON)
107 {
108 if (target->ToPlayer()->IsInFeralForm())
109 return false;
110
111 if (eventInfo.GetDamageInfo())
112 {
113 WeaponAttackType attType = eventInfo.GetDamageInfo()->GetAttackType();
114 Item* item = NULL;
117 else if (attType == WeaponAttackType::OFF_ATTACK)
119
120 if (!item || item->IsBroken() || item->GetTemplate()->Class != ITEM_CLASS_WEAPON || !((1 << item->GetTemplate()->SubClass) & GetSpellInfo()->EquippedItemSubClassMask))
121 return false;
122 }
123 }
124 else if (GetSpellInfo()->EquippedItemClass == ITEM_CLASS_ARMOR)
125 {
126 // Check if player is wearing shield
128 if (!item || item->IsBroken() || item->GetTemplate()->Class != ITEM_CLASS_ARMOR || !((1 << item->GetTemplate()->SubClass) & GetSpellInfo()->EquippedItemSubClassMask))
129 return false;
130 }
131 }
132
133 return roll_chance_f(CalcProcChance(*procEntry, eventInfo));
134}
135
136float Aura::CalcProcChance(SpellProcEntry const& procEntry, ProcEventInfo& eventInfo) const
137{
138 float chance = procEntry.chance;
139 // calculate chances depending on unit with caster's data
140 // so talents modifying chances and judgements will have properly calculated proc chance
141 if (Unit* caster = GetCaster())
142 {
143 // calculate ppm chance if present and we're using weapon
144 if (eventInfo.GetDamageInfo() && procEntry.ratePerMinute != 0)
145 {
146 uint32 WeaponSpeed = caster->GetAttackTime(eventInfo.GetDamageInfo()->GetAttackType());
147 chance = caster->GetPPMProcChance(WeaponSpeed, procEntry.ratePerMinute, GetSpellInfo());
148 }
149 // apply chance modifer aura, applies also to ppm chance (see improved judgement of light spell)
150 if (Player* modOwner = caster->GetSpellModOwner())
151 modOwner->ApplySpellMod(GetId(), SPELLMOD_CHANCE_OF_SUCCESS, chance);
152 }
153 return chance;
154}
155
157{
158 CallScriptProcHandlers(aurApp, eventInfo);
159
160 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
161 if (aurApp->HasEffect(i))
162 // OnEffectProc / AfterEffectProc hooks handled in AuraEffect::HandleProc()
163 GetEffect(i)->HandleProc(aurApp, eventInfo);
164
165 CallScriptAfterProcHandlers(aurApp, eventInfo);
166
167 // Remove aura if we've used last charge to proc
168 if (IsUsingCharges() && !GetCharges())
169 Remove();
170}
#define sConditionMgr
@ CONDITION_SOURCE_TYPE_SPELL_PROC
std::list< Condition * > ConditionList
#define MAX_SPELL_EFFECTS
std::uint32_t uint32
Definition Define.h:77
#define ASSERT
Definition Errors.h:29
@ ITEM_CLASS_ARMOR
@ ITEM_CLASS_WEAPON
@ TYPEID_PLAYER
Definition Object.h:55
@ EQUIPMENT_SLOT_MAINHAND
Definition Player.h:704
@ EQUIPMENT_SLOT_OFFHAND
Definition Player.h:705
#define INVENTORY_SLOT_BAG_0
Definition Player.h:684
#define sSpellMgr
Definition SpellMgr.h:744
WeaponAttackType
Definition Unit.h:572
@ SPELLMOD_CHANCE_OF_SUCCESS
Definition Unit.h:91
bool roll_chance_f(float chance)
Definition Util.h:83
Unit * GetTarget() const
Definition SpellAuras.h:54
bool HasEffect(uint32 effect) const
Definition SpellAuras.h:60
void HandleProc(AuraApplication *aurApp, ProcEventInfo &eventInfo)
void AddProcCooldown(uint32 msec)
void CallScriptAfterProcHandlers(AuraApplication const *aurApp, ProcEventInfo &eventInfo)
uint32 GetId() const
Definition SpellAuras.h:88
bool IsUsingCharges() const
Definition SpellAuras.h:192
bool CallScriptPrepareProcHandlers(AuraApplication const *aurApp, ProcEventInfo &eventInfo)
AuraEffect * GetEffect(uint8 effIndex) const
Definition SpellAuras.h:168
Unit * GetCaster() const
bool CallScriptCheckProcHandlers(AuraApplication const *aurApp, ProcEventInfo &eventInfo)
void SetNeedClientUpdateForTargets() const
bool CallScriptProcHandlers(AuraApplication const *aurApp, ProcEventInfo &eventInfo)
bool IsProcOnCooldown() const
float CalcProcChance(SpellProcEntry const &procEntry, ProcEventInfo &eventInfo) const
uint8 GetCharges() const
Definition SpellAuras.h:126
void TriggerProcOnEvent(AuraApplication *aurApp, ProcEventInfo &eventInfo)
SpellInfo const * GetSpellInfo() const
Definition SpellAuras.h:87
bool IsProcTriggeredOnEvent(AuraApplication *aurApp, ProcEventInfo &eventInfo) const
void PrepareProcToTrigger(AuraApplication *aurApp, ProcEventInfo &eventInfo)
Aura(SpellInfo const *spellproto, WorldObject *owner, Unit *caster, Item *castItem, uint64 casterGUID)
bool IsPassive() const
uint8 m_procCharges
Definition SpellAuras.h:243
virtual void Remove(AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)=0
WeaponAttackType GetAttackType() const
Definition Unit.h:919
Definition Item.h:202
ItemTemplate const * GetTemplate() const
Definition Item.cpp:528
bool IsBroken() const
Definition Item.h:247
Player * ToPlayer()
Definition Object.h:204
TypeID GetTypeId() const
Definition Object.h:131
Item * GetUseableItemByPos(uint8 bag, uint8 slot) const
Unit * GetActionTarget() const
Definition Unit.h:973
DamageInfo * GetDamageInfo() const
Definition Unit.h:985
Unit * GetActor() const
Definition Unit.h:972
Definition Unit.h:1367
Player * GetSpellModOwner() const
Definition Unit.cpp:5818
bool IsInFeralForm() const
Definition Unit.cpp:4936
Definition SpellMgr.h:277
uint32 cooldown
Definition SpellMgr.h:288
float chance
Definition SpellMgr.h:287
float ratePerMinute
Definition SpellMgr.h:286