Skip to content

Instantly share code, notes, and snippets.

@Demonid
Last active August 29, 2015 14:16
Show Gist options
  • Save Demonid/9a68d54367f897255ca1 to your computer and use it in GitHub Desktop.
Save Demonid/9a68d54367f897255ca1 to your computer and use it in GitHub Desktop.
From d68964ad0ab614fb8069833a64c85cbb83995519 Mon Sep 17 00:00:00 2001
From: trickerer <onlysuffering@gmail.com>
Date: Sat, 19 Oct 2013 18:33:47 +0700
Subject: [PATCH] Multiple spell reflection
---
src/server/game/Entities/Unit/Unit.cpp | 38 ++++++++++++++++++++++++++-
src/server/game/Spells/Auras/SpellAuras.cpp | 6 +++-
src/server/game/Spells/Auras/SpellAuras.h | 2 +-
3 files changed, 43 insertions(+), 3 deletions(-)
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 74c5014..289de71 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -100,6 +100,26 @@ static bool isAlwaysTriggeredAura[TOTAL_AURAS];
// Prepare lists
static bool procPrepared = InitTriggerAuraData();
+class DropChargeEvent : public BasicEvent
+{
+ public:
+ DropChargeEvent(Unit* target, uint32 spellId, uint64 caster = 0) : _target(target), _spellId(spellId), _caster(caster)
+ {
+ }
+
+ bool Execute(uint64 /*time*/, uint32 /*diff*/)
+ {
+ if (Aura* aura = _target->GetAura(_spellId, _caster))
+ aura->DropCharge();
+ return true;
+ }
+
+ private:
+ Unit* _target;
+ uint32 _spellId;
+ uint64 _caster;
+};
+
DamageInfo::DamageInfo(Unit* _attacker, Unit* _victim, uint32 _damage, SpellInfo const* _spellInfo, SpellSchoolMask _schoolMask, DamageEffectType _damageType)
: m_attacker(_attacker), m_victim(_victim), m_damage(_damage), m_spellInfo(_spellInfo), m_schoolMask(_schoolMask),
m_damageType(_damageType), m_attackType(BASE_ATTACK)
@@ -14259,7 +14279,23 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
// Remove charge (aura can be removed by triggers)
if (prepare && useCharges && takeCharges)
- i->aura->DropCharge();
+ {
+ // Set charge drop delay (only for missiles)
+ if ((procExtra & PROC_EX_REFLECT) && procSpell && procSpell->Speed > 0.0f)
+ {
+ // Set up missile speed based delay (from Spell.cpp: Spell::AddUnitTarget()::L2237)
+ int32 delay = target ? int32(floor(std::max<float>(target->GetDistance(this), 5.0f) / procSpell->Speed * 1000.0f)) : (1 * IN_MILLISECONDS) / 2;
+
+ // Do not allow aura to be removed too soon (do not update clientside timer)
+ i->aura->SetDuration(std::max<int32>(i->aura->GetDuration(), delay), false, false);
+
+ // Schedule charge drop
+ DropChargeEvent* dropEvent = new DropChargeEvent(this, i->aura->GetId(), i->aura->GetCasterGUID());
+ m_Events.AddEvent(dropEvent, m_Events.CalculateTime(delay));
+ }
+ else
+ i->aura->DropCharge();
+ }
i->aura->CallScriptAfterProcHandlers(aurApp, eventInfo);
diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp
index d7b8003..7b2ab01 100644
--- a/src/server/game/Spells/Auras/SpellAuras.cpp
+++ b/src/server/game/Spells/Auras/SpellAuras.cpp
@@ -733,7 +733,7 @@ int32 Aura::CalcMaxDuration(Unit* caster) const
return maxDuration;
}
-void Aura::SetDuration(int32 duration, bool withMods)
+void Aura::SetDuration(int32 duration, bool withMods, bool update)
{
if (withMods)
{
@@ -742,6 +742,10 @@ void Aura::SetDuration(int32 duration, bool withMods)
modOwner->ApplySpellMod(GetId(), SPELLMOD_DURATION, duration);
}
m_duration = duration;
+
+ if (!update)
+ return;
+
SetNeedClientUpdateForTargets();
}
diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h
index 9e7d0cc..19b8209 100644
--- a/src/server/game/Spells/Auras/SpellAuras.h
+++ b/src/server/game/Spells/Auras/SpellAuras.h
@@ -128,7 +128,7 @@ class Aura
int32 CalcMaxDuration() const { return CalcMaxDuration(GetCaster()); }
int32 CalcMaxDuration(Unit* caster) const;
int32 GetDuration() const { return m_duration; }
- void SetDuration(int32 duration, bool withMods = false);
+ void SetDuration(int32 duration, bool withMods = false, bool update = true);
void RefreshDuration();
void RefreshTimers();
bool IsExpired() const { return !GetDuration();}
--
1.7.6.msysgit.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment