aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTraesh <traesh@farahlon.com>2018-05-18 20:25:23 +0200
committerShauren <shauren.trinity@gmail.com>2021-03-05 23:25:51 +0100
commit56e9560661adca81fc1e9a297cb6823cf7a6cb22 (patch)
treeed03278638be2de9eff688354b3b7bdc2b416349 /src
parentc0f34522869992c7a03ed40a20e7fb5cd2a9e145 (diff)
Core/Spells Handle auras 328 & 396 (SPELL_AURA_TRIGGER_SPELL_ON_POWER_*)
Diffstat (limited to 'src')
-rw-r--r--src/common/Utilities/Util.h7
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp45
-rw-r--r--src/server/game/Entities/Unit/Unit.h1
-rw-r--r--src/server/game/Spells/Auras/SpellAuraDefines.h12
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp60
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.h2
6 files changed, 122 insertions, 5 deletions
diff --git a/src/common/Utilities/Util.h b/src/common/Utilities/Util.h
index 308da01335d..1060f5d090f 100644
--- a/src/common/Utilities/Util.h
+++ b/src/common/Utilities/Util.h
@@ -72,6 +72,13 @@ inline T CalculatePct(T base, U pct)
return T(base * static_cast<float>(pct) / 100.0f);
}
+template <class T>
+inline float GetPctOf(T value, T max)
+{
+ ASSERT(max);
+ return float(static_cast<float>(value) / static_cast<float>(max) * 100.0f);
+}
+
template <class T, class U>
inline T AddPct(T &base, U pct)
{
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 73fc28572ce..57b9f4f2b7e 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -9964,6 +9964,7 @@ void Unit::SetPower(Powers power, int32 val)
if (maxPower < val)
val = maxPower;
+ int32 oldPower = m_unitData->Power[powerIndex];
SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::Power, powerIndex), val);
if (IsInWorld())
@@ -9975,6 +9976,8 @@ void Unit::SetPower(Powers power, int32 val)
SendMessageToSet(packet.Write(), GetTypeId() == TYPEID_PLAYER);
}
+ TriggerOnPowerChangeAuras(power, oldPower, val);
+
// group update
if (Player* player = ToPlayer())
{
@@ -10013,6 +10016,48 @@ void Unit::SetMaxPower(Powers power, int32 val)
SetPower(power, val);
}
+void Unit::TriggerOnPowerChangeAuras(Powers power, int32 oldVal, int32 newVal)
+{
+ AuraEffectList effects = GetAuraEffectsByType(SPELL_AURA_TRIGGER_SPELL_ON_POWER_PCT);
+ AuraEffectList effectsAmount = GetAuraEffectsByType(SPELL_AURA_TRIGGER_SPELL_ON_POWER_AMOUNT);
+ effects.splice(effects.end(), effectsAmount);
+
+ for (AuraEffect const* effect : effects)
+ {
+ if (effect->GetMiscValue() == power)
+ {
+ uint32 effectAmount = effect->GetAmount();
+ uint32 triggerSpell = effect->GetSpellEffectInfo()->TriggerSpell;
+
+ float oldValueCheck = oldVal;
+ float newValueCheck = newVal;
+
+ if (effect->GetAuraType() == SPELL_AURA_TRIGGER_SPELL_ON_POWER_PCT)
+ {
+ int32 maxPower = GetMaxPower(power);
+ oldValueCheck = GetPctOf(oldVal, maxPower);
+ newValueCheck = GetPctOf(newVal, maxPower);
+ }
+
+ switch (AuraTriggerOnPowerChangeDirection(effect->GetMiscValueB()))
+ {
+ case AuraTriggerOnPowerChangeDirection::Gain:
+ if (oldValueCheck >= effect->GetAmount() || newValueCheck < effectAmount)
+ continue;
+ break;
+ case AuraTriggerOnPowerChangeDirection::Loss:
+ if (oldValueCheck <= effect->GetAmount() || newValueCheck > effectAmount)
+ continue;
+ break;
+ default:
+ break;
+ }
+
+ CastSpell(this, triggerSpell, true, nullptr, effect);
+ }
+ }
+}
+
int32 Unit::GetCreatePowers(Powers power) const
{
if (power == POWER_MANA)
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 5a00541e0ae..7a57301cbc6 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1083,6 +1083,7 @@ class TC_GAME_API Unit : public WorldObject
int32 CountPctFromMaxPower(Powers power, int32 pct) const { return CalculatePct(GetMaxPower(power), pct); }
void SetPower(Powers power, int32 val);
void SetMaxPower(Powers power, int32 val);
+ void TriggerOnPowerChangeAuras(Powers power, int32 oldVal, int32 newVal);
inline void SetFullPower(Powers power) { SetPower(power, GetMaxPower(power)); }
// returns the change in power
int32 ModifyPower(Powers power, int32 val);
diff --git a/src/server/game/Spells/Auras/SpellAuraDefines.h b/src/server/game/Spells/Auras/SpellAuraDefines.h
index f9bdf8ddfcd..1790db5028f 100644
--- a/src/server/game/Spells/Auras/SpellAuraDefines.h
+++ b/src/server/game/Spells/Auras/SpellAuraDefines.h
@@ -70,6 +70,12 @@ enum DAMAGE_ABSORB_TYPE
ONLY_MAGIC_ABSORB = -1
};
+enum class AuraTriggerOnPowerChangeDirection : int32
+{
+ Gain = 0,
+ Loss = 1
+};
+
enum AuraType : uint32
{
SPELL_AURA_NONE = 0,
@@ -400,7 +406,7 @@ enum AuraType : uint32
SPELL_AURA_LEARN_PVP_TALENT = 325, // NYI
SPELL_AURA_PHASE_GROUP = 326, // Puts the player in all the phases that are in the group with id = miscB
SPELL_AURA_PHASE_ALWAYS_VISIBLE = 327, // Sets PhaseShiftFlags::AlwaysVisible
- SPELL_AURA_TRIGGER_SPELL_ON_POWER_PCT = 328, // NYI Triggers spell when power goes above (MiscB = 0) or falls below (MiscB = 1) specified percent value (once, not every time condition has meet)
+ SPELL_AURA_TRIGGER_SPELL_ON_POWER_PCT = 328, // Triggers spell when power goes above (MiscB = 0) or falls below (MiscB = 1) specified percent value (once, not every time condition has meet)
SPELL_AURA_MOD_POWER_GAIN_PCT = 329,
SPELL_AURA_CAST_WHILE_WALKING = 330,
SPELL_AURA_FORCE_WEATHER = 331,
@@ -418,7 +424,7 @@ enum AuraType : uint32
SPELL_AURA_MOD_MELEE_DAMAGE_FROM_CASTER = 343, // NYI
SPELL_AURA_MOD_AUTOATTACK_DAMAGE = 344,
SPELL_AURA_BYPASS_ARMOR_FOR_CASTER = 345,
- SPELL_AURA_ENABLE_ALT_POWER = 346, // NYI
+ SPELL_AURA_ENABLE_ALT_POWER = 346,
SPELL_AURA_MOD_SPELL_COOLDOWN_BY_HASTE = 347,
SPELL_AURA_MOD_MONEY_GAIN = 348, // Modifies gold gains from source: [Misc = 0, Quests][Misc = 1, Loot]
SPELL_AURA_MOD_CURRENCY_GAIN = 349,
@@ -468,7 +474,7 @@ enum AuraType : uint32
SPELL_AURA_BLOCK_SPELLS_IN_FRONT = 393, // NYI
SPELL_AURA_SHOW_CONFIRMATION_PROMPT = 394,
SPELL_AURA_AREA_TRIGGER = 395, // NYI
- SPELL_AURA_TRIGGER_SPELL_ON_POWER_AMOUNT = 396, // NYI Triggers spell when health goes above (MiscA = 0) or falls below (MiscA = 1) specified percent value (once, not every time condition has meet)
+ SPELL_AURA_TRIGGER_SPELL_ON_POWER_AMOUNT = 396, // Triggers spell when power goes above (MiscA = 0) or falls below (MiscA = 1) specified percent value (once, not every time condition has meet)
SPELL_AURA_BATTLEGROUND_PLAYER_POSITION_FACTIONAL = 397,
SPELL_AURA_BATTLEGROUND_PLAYER_POSITION = 398,
SPELL_AURA_MOD_TIME_RATE = 399,
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index c14729e8a55..48bbd51acc9 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -396,7 +396,7 @@ NonDefaultConstructible<pAuraEffectHandler> AuraEffectHandler[TOTAL_AURAS]=
&AuraEffect::HandleUnused, //325 SPELL_AURA_LEARN_PVP_TALENT
&AuraEffect::HandlePhaseGroup, //326 SPELL_AURA_PHASE_GROUP
&AuraEffect::HandlePhaseAlwaysVisible, //327 SPELL_AURA_PHASE_ALWAYS_VISIBLE
- &AuraEffect::HandleNULL, //328 SPELL_AURA_TRIGGER_SPELL_ON_POWER_PCT
+ &AuraEffect::HandleTriggerSpellOnPowerPercent, //328 SPELL_AURA_TRIGGER_SPELL_ON_POWER_PCT
&AuraEffect::HandleNULL, //329 SPELL_AURA_MOD_POWER_GAIN_PCT
&AuraEffect::HandleNoImmediateEffect, //330 SPELL_AURA_CAST_WHILE_WALKING
&AuraEffect::HandleAuraForceWeather, //331 SPELL_AURA_FORCE_WEATHER
@@ -464,7 +464,7 @@ NonDefaultConstructible<pAuraEffectHandler> AuraEffectHandler[TOTAL_AURAS]=
&AuraEffect::HandleNULL, //393 SPELL_AURA_BLOCK_SPELLS_IN_FRONT
&AuraEffect::HandleShowConfirmationPrompt, //394 SPELL_AURA_SHOW_CONFIRMATION_PROMPT
&AuraEffect::HandleCreateAreaTrigger, //395 SPELL_AURA_AREA_TRIGGER
- &AuraEffect::HandleNULL, //396 SPELL_AURA_TRIGGER_SPELL_ON_POWER_AMOUNT
+ &AuraEffect::HandleTriggerSpellOnPowerAmount, //396 SPELL_AURA_TRIGGER_SPELL_ON_POWER_AMOUNT
&AuraEffect::HandleBattlegroundPlayerPosition, //397 SPELL_AURA_BATTLEGROUND_PLAYER_POSITION_FACTIONAL
&AuraEffect::HandleBattlegroundPlayerPosition, //398 SPELL_AURA_BATTLEGROUND_PLAYER_POSITION
&AuraEffect::HandleNULL, //399 SPELL_AURA_MOD_TIME_RATE
@@ -4988,6 +4988,62 @@ void AuraEffect::HandleAuraLinked(AuraApplication const* aurApp, uint8 mode, boo
}
}
+void AuraEffect::HandleTriggerSpellOnPowerPercent(AuraApplication const* aurApp, uint8 mode, bool apply) const
+{
+ if (!(mode & AURA_EFFECT_HANDLE_REAL) || !apply)
+ return;
+
+ Unit* target = aurApp->GetTarget();
+
+ int32 effectAmount = GetAmount();
+ uint32 triggerSpell = GetSpellEffectInfo()->TriggerSpell;
+ float powerAmountPct = GetPctOf(target->GetPower(Powers(GetMiscValue())), target->GetMaxPower(Powers(GetMiscValue())));
+
+ switch (AuraTriggerOnPowerChangeDirection(GetMiscValueB()))
+ {
+ case AuraTriggerOnPowerChangeDirection::Gain:
+ if (powerAmountPct < effectAmount)
+ return;
+ break;
+ case AuraTriggerOnPowerChangeDirection::Loss:
+ if (powerAmountPct > effectAmount)
+ return;
+ break;
+ default:
+ break;
+ }
+
+ target->CastSpell(target, triggerSpell, true);
+}
+
+void AuraEffect::HandleTriggerSpellOnPowerAmount(AuraApplication const* aurApp, uint8 mode, bool apply) const
+{
+ if (!(mode & AURA_EFFECT_HANDLE_REAL) || !apply)
+ return;
+
+ Unit* target = aurApp->GetTarget();
+
+ int32 effectAmount = GetAmount();
+ uint32 triggerSpell = GetSpellEffectInfo()->TriggerSpell;
+ float powerAmount = target->GetPower(Powers(GetMiscValue()));
+
+ switch (AuraTriggerOnPowerChangeDirection(GetMiscValueB()))
+ {
+ case AuraTriggerOnPowerChangeDirection::Gain:
+ if (powerAmount < effectAmount)
+ return;
+ break;
+ case AuraTriggerOnPowerChangeDirection::Loss:
+ if (powerAmount > effectAmount)
+ return;
+ break;
+ default:
+ break;
+ }
+
+ target->CastSpell(target, triggerSpell, true);
+}
+
void AuraEffect::HandleAuraOpenStable(AuraApplication const* aurApp, uint8 mode, bool apply) const
{
if (!(mode & AURA_EFFECT_HANDLE_REAL))
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.h b/src/server/game/Spells/Auras/SpellAuraEffects.h
index 8326cc55840..0819f294b7f 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.h
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.h
@@ -320,6 +320,8 @@ class TC_GAME_API AuraEffect
void HandleSetFFAPvP(AuraApplication const* aurApp, uint8 mode, bool apply) const;
void HandleModOverrideZonePVPType(AuraApplication const* aurApp, uint8 mode, bool apply) const;
void HandleBattlegroundPlayerPosition(AuraApplication const* aurApp, uint8 mode, bool apply) const;
+ void HandleTriggerSpellOnPowerAmount(AuraApplication const* aurApp, uint8 mode, bool apply) const;
+ void HandleTriggerSpellOnPowerPercent(AuraApplication const* aurApp, uint8 mode, bool apply) const;
// aura effect periodic tick handlers
void HandlePeriodicDummyAuraTick(Unit* target, Unit* caster) const;