diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/common/Utilities/Util.h | 7 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 45 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 1 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuraDefines.h | 12 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuraEffects.cpp | 60 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuraEffects.h | 2 |
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; |