Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
SpellEffectsTrigger.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 "AccountMgr.h"
7#include "AreaTrigger.h"
8#include "Battleground.h"
9#include "BattlegroundMgr.h"
10#include "BattlePetMgr.h"
11#include "CellImpl.h"
12#include "Common.h"
13#include "Creature.h"
14#include "CreatureAI.h"
15#include "DatabaseEnv.h"
16#include "DynamicObject.h"
17#include "Formulas.h"
18#include "GameObject.h"
19#include "GameObjectAI.h"
20#include "GossipDef.h"
21#include "GridNotifiers.h"
22#include "GridNotifiersImpl.h"
23#include "Group.h"
24#include "Guild.h"
25#include "GuildMgr.h"
26#include "InstanceScript.h"
27#include "Language.h"
28#include "Log.h"
29#include "MapManager.h"
30#include "ObjectAccessor.h"
31#include "ObjectMgr.h"
32#include "Opcodes.h"
33#include "OutdoorPvPMgr.h"
34#include "PathGenerator.h"
35#include "Pet.h"
36#include "Player.h"
37#include "ReputationMgr.h"
38#include "ScriptMgr.h"
39#include "SharedDefines.h"
40#include "SkillDiscovery.h"
41#include "SkillExtraItems.h"
42#include "SocialMgr.h"
43#include "Spell.h"
44#include "SpellAuraEffects.h"
45#include "SpellAuras.h"
46#include "SpellEffectMetadata.h"
47#include "SpellMgr.h"
48#include "SpellValidation.h"
49#include "TemporarySummon.h"
50#include "Totem.h"
51#include "Unit.h"
52#include "UpdateData.h"
53#include "UpdateMask.h"
54#include "Util.h"
55#include "Vehicle.h"
56#include "VMapFactory.h"
57#include "World.h"
58#include "WorldPacket.h"
59
61{
64 return;
65
66 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
67
69 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_TRIGGER_SPELL
71 {
72 if (Skyfire::Spells::TriggerSpellRule const* triggerRule =
73 Skyfire::Spells::GetTriggerSpellRule(triggered_spell_id))
74 {
75 switch (triggerRule->Kind)
76 {
78 {
79 unitTarget->RemoveMovementImpairingAuras();
80 unitTarget->RemoveAurasByType(SPELL_AURA_MOD_STALKED);
81
82 // If this spell is given to an NPC, it must handle the rest using its own AI
83 if (unitTarget->GetTypeId() != TypeID::TYPEID_PLAYER)
84 return;
85
86 // See if we already are stealthed. If so, we're done.
87 if (unitTarget->HasAura(triggerRule->CastSpellId))
88 return;
89
90 // Reset cooldown on stealth if needed
91 if (unitTarget->ToPlayer()->HasSpellCooldown(triggerRule->CastSpellId))
92 unitTarget->ToPlayer()->RemoveSpellCooldown(triggerRule->CastSpellId);
93
94 if (unitTarget->IsInCombat())
95 unitTarget->CombatStop();
96
97 unitTarget->CastSpell(unitTarget, triggerRule->CastSpellId, true);
98 return;
99 }
101 {
102 unitTarget->RemoveMovementImpairingAuras();
103 unitTarget->RemoveAurasByType(SPELL_AURA_MOD_STALKED);
104 unitTarget->RemoveAurasByType(SPELL_AURA_MOD_STUN);
105
106 unitTarget->CastSpell(unitTarget, triggerRule->CastSpellId, true);
107 return;
108 }
110 {
111 SpellInfo const* spell = sSpellMgr->GetSpellInfo(triggerRule->StackSpellId);
112 if (!spell)
113 return;
114
115 for (uint32 j = 0; j < spell->StackAmount; ++j)
116 m_caster->CastSpell(unitTarget, spell->Id, true);
117 return;
118 }
120 {
122 Unit::AuraApplicationMap& Auras = unitTarget->GetAppliedAuras();
123 for (Unit::AuraApplicationMap::iterator iter = Auras.begin(); iter != Auras.end();)
124 {
125 // remove all harmful spells on you...
126 SpellInfo const* spell = iter->second->GetBase()->GetSpellInfo();
127 if ((spell->DmgClass == SPELL_DAMAGE_CLASS_MAGIC // only affect magic spells
128 || ((spell->GetDispelMask()) & dispelMask))
129 // ignore positive and passive auras
130 && !iter->second->IsPositive() && !iter->second->GetBase()->IsPassive())
131 {
132 m_caster->RemoveAura(iter);
133 }
134 else
135 ++iter;
136 }
137 return;
138 }
139 default:
140 break;
141 }
142 }
143 }
144
145 // normal case
146 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
147 if (!spellInfo)
148 {
149 SF_LOG_DEBUG("spells", "Spell::EffectTriggerSpell spell %u tried to trigger unknown spell %u", m_spellInfo->Id, triggered_spell_id);
150 return;
151 }
152
153 SpellCastTargets targets;
155 {
157 return;
158 targets.SetUnitTarget(unitTarget);
159 }
160 else //if (effectHandleMode == SPELL_EFFECT_HANDLE_LAUNCH)
161 {
162 if (spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo) && (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK))
163 return;
164
166 targets.SetDst(m_targets);
167
168 targets.SetUnitTarget(m_caster);
169 }
170
171 CustomSpellValues values;
172 // set basepoints for trigger with value effect
173 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE)
174 {
178 }
179
180 // Remove spell cooldown (not category) if spell triggering spell with cooldown and same category
181 if (m_caster->GetTypeId() == TypeID::TYPEID_PLAYER && m_spellInfo->CategoryRecoveryTime && spellInfo->CategoryRecoveryTime
182 && m_spellInfo->GetCategory() == spellInfo->GetCategory())
183 m_caster->ToPlayer()->RemoveSpellCooldown(spellInfo->Id);
184
185 // original caster guid only for GO cast
186 m_caster->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK, NULL, NULL, m_originalCasterGUID);
187}
188
190{
193 return;
194
195 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
196
197 // normal case
198 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
199 if (!spellInfo)
200 {
201 SF_LOG_DEBUG("spells", "Spell::EffectTriggerMissileSpell spell %u tried to trigger unknown spell %u", m_spellInfo->Id, triggered_spell_id);
202 return;
203 }
204
205 SpellCastTargets targets;
207 {
209 return;
210 targets.SetUnitTarget(unitTarget);
211 }
212 else //if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT)
213 {
214 if (spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo) && (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK))
215 return;
216
218 targets.SetDst(m_targets);
219
220 targets.SetUnitTarget(m_caster);
221 }
222
223 CustomSpellValues values;
224 // set basepoints for trigger with value effect
225 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE)
226 {
227 // maybe need to set value only when basepoints == 0?
231 }
232
233 // Remove spell cooldown (not category) if spell triggering spell with cooldown and same category
234 if (m_caster->GetTypeId() == TypeID::TYPEID_PLAYER && m_spellInfo->CategoryRecoveryTime && spellInfo->CategoryRecoveryTime
235 && m_spellInfo->GetCategory() == spellInfo->GetCategory())
236 m_caster->ToPlayer()->RemoveSpellCooldown(spellInfo->Id);
237
238 // original caster guid only for GO cast
239 m_caster->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK, NULL, NULL, m_originalCasterGUID);
240}
241
243{
245 return;
246
247 if (!unitTarget)
248 return;
249
250 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
251
252 // normal case
253 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
254
255 if (!spellInfo)
256 {
257 SF_LOG_ERROR("spells", "Spell::EffectForceCast of spell %u: triggering unknown spell id %i", m_spellInfo->Id, triggered_spell_id);
258 return;
259 }
260
261 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_FORCE_CAST && damage)
262 {
263 if (Skyfire::Spells::ForceCastDamageRule const* forceCastRule =
265 {
266 switch (forceCastRule->Kind)
267 {
269 unitTarget->RemoveAura(damage);
270 break;
272 unitTarget->CastCustomSpell(unitTarget, spellInfo->Id, &damage, NULL, NULL, true, NULL, NULL, m_originalCasterGUID);
273 return;
275 unitTarget->CastSpell(unitTarget, spellInfo->Id, true, NULL, NULL, m_originalCasterGUID);
276 return;
277 default:
278 break;
279 }
280 }
281 }
282
283 CustomSpellValues values;
284 // set basepoints for trigger with value effect
285 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_FORCE_CAST_WITH_VALUE)
286 {
287 // maybe need to set value only when basepoints == 0?
291 }
292
293 SpellCastTargets targets;
294 targets.SetUnitTarget(m_caster);
295
296 unitTarget->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK);
297}
298
300{
301 // we do not handle a flag dropping or clicking on flag in battleground by sendevent system
304 return;
305
306 WorldObject* target = NULL;
307
308 // call events for object target if present
310 {
311 if (unitTarget)
312 target = unitTarget;
313 else if (gameObjTarget)
314 target = gameObjTarget;
315 }
316 else // if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT)
317 {
318 // let's prevent executing effect handler twice in case when spell effect is capable of targeting an object
319 // this check was requested by scripters, but it has some downsides:
320 // now it's impossible to script (using sEventScripts) a cast which misses all targets
321 // or to have an ability to script the moment spell hits dest (in a case when there are object targets present)
322 if (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_GAMEOBJECT_MASK))
323 return;
324 // some spells have no target entries in dbc and they use focus target
325 if (focusObject)
326 target = focusObject;
328 }
329
330 SF_LOG_DEBUG("spells", "Spell ScriptStart %u for spellid %u in EffectSendEvent ", m_spellInfo->Effects[effIndex].MiscValue, m_spellInfo->Id);
331
332 if (ZoneScript* zoneScript = m_caster->GetZoneScript())
333 zoneScript->ProcessEvent(target, m_spellInfo->Effects[effIndex].MiscValue);
334 else if (InstanceScript* instanceScript = m_caster->GetInstanceScript()) // needed in case Player is the caster
335 instanceScript->ProcessEvent(target, m_spellInfo->Effects[effIndex].MiscValue);
336
337 m_caster->GetMap()->ScriptsStart(sEventScripts, m_spellInfo->Effects[effIndex].MiscValue, m_caster, target);
338}
std::uint32_t uint32
Definition Define.h:77
#define SF_LOG_DEBUG(filterType__,...)
Definition Log.h:134
#define SF_LOG_ERROR(filterType__,...)
Definition Log.h:143
@ TYPEID_PLAYER
Definition Object.h:55
ScriptMapMap sEventScripts
Definition ObjectMgr.cpp:51
SpellEffIndex
@ SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE
@ SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE
@ SPELL_EFFECT_TRIGGER_SPELL
@ SPELL_EFFECT_FORCE_CAST
@ SPELL_EFFECT_FORCE_CAST_WITH_VALUE
@ SPELL_DAMAGE_CLASS_MAGIC
@ DISPEL_ALL
@ SPELL_EFFECT_HANDLE_LAUNCH_TARGET
Definition Spell.h:275
@ SPELL_EFFECT_HANDLE_LAUNCH
Definition Spell.h:274
@ SPELL_EFFECT_HANDLE_HIT
Definition Spell.h:276
@ SPELL_EFFECT_HANDLE_HIT_TARGET
Definition Spell.h:277
@ SPELL_AURA_MOD_STALKED
@ SPELL_AURA_MOD_STUN
#define sSpellMgr
Definition SpellMgr.h:744
@ TARGET_FLAG_DEST_LOCATION
@ TARGET_FLAG_UNIT_MASK
@ TARGET_FLAG_GAMEOBJECT_MASK
@ SPELLVALUE_BASE_POINT1
Definition Unit.h:115
@ SPELLVALUE_BASE_POINT2
Definition Unit.h:116
@ SPELLVALUE_BASE_POINT0
Definition Unit.h:114
@ TRIGGERED_FULL_MASK
Will ignore most target checks (mostly DBC target checks).
Definition Unit.h:435
void AddSpellMod(SpellValueMod mod, int32 value)
Definition Unit.h:131
void SetDst(float x, float y, float z, float orientation, uint32 mapId=MAPID_INVALID)
Definition Spell.cpp:388
void SetUnitTarget(Unit *target)
Definition Spell.cpp:228
GameObject * gameObjTarget
Definition Spell.h:628
SpellCastTargets m_targets
Definition Spell.h:535
void EffectSendEvent(SpellEffIndex effIndex)
int32 damage
Definition Spell.h:630
void EffectForceCast(SpellEffIndex effIndex)
SpellEffectHandleMode effectHandleMode
Definition Spell.h:631
Unit *const m_caster
Definition Spell.h:581
uint64 m_originalCasterGUID
Definition Spell.h:585
void EffectTriggerMissileSpell(SpellEffIndex effIndex)
Unit * unitTarget
Definition Spell.h:626
void EffectTriggerSpell(SpellEffIndex effIndex)
GameObject * focusObject
Definition Spell.h:640
SpellInfo const *const m_spellInfo
Definition Spell.h:530
uint32 GetCategory() const
uint32 StackAmount
Definition SpellInfo.h:211
uint32 Id
Definition SpellInfo.h:160
uint32 GetDispelMask() const
bool NeedsToBeTriggeredByCaster(SpellInfo const *triggeringSpell) const
uint32 CategoryRecoveryTime
Definition SpellInfo.h:195
uint32 GetExplicitTargetMask() const
uint32 DmgClass
Definition SpellInfo.h:228
std::multimap< uint32, AuraApplication * > AuraApplicationMap
Definition Unit.h:1376
@ FORCE_CAST_DAMAGE_RULE_TRIGGERED_ORIGINAL_CASTER
TriggerSpellRule const * GetTriggerSpellRule(uint32 triggerSpellId)
ForceCastDamageRule const * GetForceCastDamageRule(uint32 spellId)
@ TRIGGER_SPELL_RULE_DEMONIC_EMPOWERMENT_SUCCUBUS