Core/Auras: Implemented SPELL_AURA_MOD_RECOVERY_RATE and SPELL_AURA_MOD_RECOVERY_RATE_BY_SPELL_LABEL
Port From (https://github.com/TrinityCore/TrinityCore/commit/0c198938005bb22f20a0d150a6505324a2d941de)
This commit is contained in:
@@ -501,16 +501,32 @@ namespace Game.Networking.Packets
|
||||
_worldPacket.WriteUInt32(SpellID);
|
||||
_worldPacket.WriteInt32(DeltaTime);
|
||||
_worldPacket.WriteBit(IsPet);
|
||||
_worldPacket.WriteBit(WithoutCategoryCooldown);
|
||||
_worldPacket.WriteBit(SkipCategory);
|
||||
_worldPacket.FlushBits();
|
||||
}
|
||||
|
||||
public bool IsPet;
|
||||
public bool WithoutCategoryCooldown;
|
||||
public bool SkipCategory;
|
||||
public int DeltaTime;
|
||||
public uint SpellID;
|
||||
}
|
||||
|
||||
class UpdateCooldown : ServerPacket
|
||||
{
|
||||
public uint SpellID;
|
||||
public float ModChange = 1.0f;
|
||||
public float ModRate = 1.0f;
|
||||
|
||||
public UpdateCooldown() : base(ServerOpcodes.UpdateCooldown, ConnectionType.Instance) { }
|
||||
|
||||
public override void Write()
|
||||
{
|
||||
_worldPacket.WriteUInt32(SpellID);
|
||||
_worldPacket.WriteFloat(ModChange);
|
||||
_worldPacket.WriteFloat(ModRate);
|
||||
}
|
||||
}
|
||||
|
||||
public class SpellCooldownPkt : ServerPacket
|
||||
{
|
||||
public SpellCooldownPkt() : base(ServerOpcodes.SpellCooldown, ConnectionType.Instance) { }
|
||||
|
||||
@@ -5813,6 +5813,35 @@ namespace Game.Spells
|
||||
target.RemoveSpellCategoryCooldownMod(GetMiscValue(), GetAmount());
|
||||
}
|
||||
|
||||
[AuraEffectHandler(AuraType.ModRecoveryRate)]
|
||||
void HandleModRecoveryRate(AuraApplication aurApp, AuraEffectHandleModes mode, bool apply)
|
||||
{
|
||||
if (!mode.HasAnyFlag(AuraEffectHandleModes.ChangeAmountMask))
|
||||
return;
|
||||
|
||||
float rate = 100.0f / (Math.Max(GetAmount(), -99.0f) + 100.0f);
|
||||
|
||||
aurApp.GetTarget().GetSpellHistory().UpdateCooldownRecoveryRate(cooldown =>
|
||||
{
|
||||
return IsAffectingSpell(Global.SpellMgr.GetSpellInfo(cooldown.SpellId, Difficulty.None));
|
||||
}, rate, apply);
|
||||
}
|
||||
|
||||
[AuraEffectHandler(AuraType.ModRecoveryRateBySpellLabel)]
|
||||
void HandleModRecoveryRateBySpellLabel(AuraApplication aurApp, AuraEffectHandleModes mode, bool apply)
|
||||
{
|
||||
if (!mode.HasAnyFlag(AuraEffectHandleModes.ChangeAmountMask))
|
||||
return;
|
||||
|
||||
float rate = 100.0f / (Math.Max(GetAmount(), -99.0f) + 100.0f);
|
||||
|
||||
aurApp.GetTarget().GetSpellHistory().UpdateCooldownRecoveryRate(cooldown =>
|
||||
{
|
||||
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(cooldown.SpellId, Difficulty.None);
|
||||
return spellInfo.HasLabel((uint)GetMiscValue()) || (GetMiscValueB() != 0 && spellInfo.HasLabel((uint)GetMiscValueB()));
|
||||
}, rate, apply);
|
||||
}
|
||||
|
||||
[AuraEffectHandler(AuraType.ShowConfirmationPrompt)]
|
||||
[AuraEffectHandler(AuraType.ShowConfirmationPromptWithDifficulty)]
|
||||
void HandleShowConfirmationPrompt(AuraApplication aurApp, AuraEffectHandleModes mode, bool apply)
|
||||
|
||||
@@ -354,6 +354,8 @@ namespace Game.Spells
|
||||
{
|
||||
if (!forcedCooldown.HasValue)
|
||||
{
|
||||
TimeSpan baseCooldown = cooldown;
|
||||
|
||||
// Now we have cooldown data (if found any), time to apply mods
|
||||
Player modOwner = _owner.GetSpellModOwner();
|
||||
if (modOwner != null)
|
||||
@@ -384,6 +386,35 @@ namespace Game.Spells
|
||||
categoryCooldown = TimeSpan.FromMilliseconds(categoryCooldown.TotalMilliseconds * _owner.m_unitData.ModHasteRegen);
|
||||
}
|
||||
|
||||
{
|
||||
float calcRecoveryRate(AuraEffect modRecoveryRate)
|
||||
{
|
||||
float rate = 100.0f / (Math.Max(modRecoveryRate.GetAmount(), -99.0f) + 100.0f);
|
||||
if (baseCooldown <= TimeSpan.FromHours(1)
|
||||
&& !spellInfo.HasAttribute(SpellAttr6.IgnoreForModTimeRate)
|
||||
&& !modRecoveryRate.GetSpellEffectInfo().EffectAttributes.HasFlag(SpellEffectAttributes.IgnoreDuringCooldownTimeRateCalculation))
|
||||
rate *= _owner.m_unitData.ModTimeRate;
|
||||
|
||||
return rate;
|
||||
}
|
||||
|
||||
|
||||
float recoveryRate = 1.0f;
|
||||
foreach (AuraEffect modRecoveryRate in _owner.GetAuraEffectsByType(AuraType.ModRecoveryRate))
|
||||
if (modRecoveryRate.IsAffectingSpell(spellInfo))
|
||||
recoveryRate *= calcRecoveryRate(modRecoveryRate);
|
||||
|
||||
foreach (AuraEffect modRecoveryRate in _owner.GetAuraEffectsByType(AuraType.ModRecoveryRateBySpellLabel))
|
||||
if (spellInfo.HasLabel((uint)modRecoveryRate.GetMiscValue()) || (modRecoveryRate.GetMiscValueB() != 0 && spellInfo.HasLabel((uint)modRecoveryRate.GetMiscValueB())))
|
||||
recoveryRate *= calcRecoveryRate(modRecoveryRate);
|
||||
|
||||
if (recoveryRate > 0.0f)
|
||||
{
|
||||
cooldown = TimeSpan.FromMilliseconds((long)(cooldown.TotalMilliseconds * recoveryRate));
|
||||
categoryCooldown = TimeSpan.FromMilliseconds((long)(categoryCooldown.TotalMilliseconds * recoveryRate));
|
||||
}
|
||||
}
|
||||
|
||||
int cooldownMod = _owner.GetTotalAuraModifier(AuraType.ModCooldown);
|
||||
if (cooldownMod != 0)
|
||||
{
|
||||
@@ -535,7 +566,7 @@ namespace Game.Spells
|
||||
modifyCooldown.IsPet = _owner != playerOwner;
|
||||
modifyCooldown.SpellID = cooldownEntry.SpellId;
|
||||
modifyCooldown.DeltaTime = (int)cooldownMod.TotalMilliseconds;
|
||||
modifyCooldown.WithoutCategoryCooldown = withoutCategoryCooldown;
|
||||
modifyCooldown.SkipCategory = withoutCategoryCooldown;
|
||||
playerOwner.SendPacket(modifyCooldown);
|
||||
}
|
||||
|
||||
@@ -546,6 +577,40 @@ namespace Game.Spells
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateCooldownRecoveryRate(Func<CooldownEntry, bool> predicate, float modChange, bool apply)
|
||||
{
|
||||
foreach (var cooldownEntry in _spellCooldowns.Values)
|
||||
{
|
||||
if (predicate(cooldownEntry))
|
||||
UpdateCooldownRecoveryRate(cooldownEntry, modChange, apply);
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateCooldownRecoveryRate(CooldownEntry cooldownEntry, float modChange, bool apply)
|
||||
{
|
||||
if (modChange <= 0.0f)
|
||||
return;
|
||||
|
||||
if (!apply)
|
||||
modChange = 1.0f / modChange;
|
||||
|
||||
DateTime now = GameTime.GetDateAndTime();
|
||||
|
||||
cooldownEntry.CooldownEnd = now + TimeSpan.FromMilliseconds((cooldownEntry.CooldownEnd - now).TotalMilliseconds * modChange);
|
||||
|
||||
if (cooldownEntry.CategoryId != 0)
|
||||
cooldownEntry.CategoryEnd = now + TimeSpan.FromMilliseconds((cooldownEntry.CategoryEnd - now).TotalMilliseconds * modChange);
|
||||
|
||||
Player playerOwner = GetPlayerOwner();
|
||||
if (playerOwner != null)
|
||||
{
|
||||
UpdateCooldown updateCooldown = new();
|
||||
updateCooldown.SpellID = cooldownEntry.SpellId;
|
||||
updateCooldown.ModChange = modChange;
|
||||
playerOwner.SendPacket(updateCooldown);
|
||||
}
|
||||
}
|
||||
|
||||
public void ModifyCooldown(uint spellId, TimeSpan cooldownMod, bool withoutCategoryCooldown = false)
|
||||
{
|
||||
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId, _owner.GetMap().GetDifficultyID());
|
||||
|
||||
Reference in New Issue
Block a user