Core/Spells: SpellHistory updates
Port From (https://github.com/TrinityCore/TrinityCore/commit/8cc6520b89583d4bf6549b28fa5b7390fc2b0b9d)
This commit is contained in:
@@ -1578,7 +1578,7 @@ namespace Game.Entities
|
||||
{
|
||||
m_weaponChangeTimer = spellProto.StartRecoveryTime;
|
||||
|
||||
GetSpellHistory().AddGlobalCooldown(spellProto, m_weaponChangeTimer);
|
||||
GetSpellHistory().AddGlobalCooldown(spellProto, TimeSpan.FromMilliseconds(m_weaponChangeTimer));
|
||||
|
||||
SpellCooldownPkt spellCooldown = new();
|
||||
spellCooldown.Caster = GetGUID();
|
||||
@@ -3912,7 +3912,7 @@ namespace Game.Entities
|
||||
continue;
|
||||
|
||||
// Don't replace longer cooldowns by equip cooldown if we have any.
|
||||
if (GetSpellHistory().GetRemainingCooldown(effectSpellInfo) > 30 * Time.InMilliseconds)
|
||||
if (GetSpellHistory().GetRemainingCooldown(effectSpellInfo) > TimeSpan.FromSeconds(30))
|
||||
continue;
|
||||
|
||||
GetSpellHistory().AddCooldown((uint)effectData.SpellID, pItem.GetEntry(), TimeSpan.FromSeconds(30));
|
||||
|
||||
@@ -6388,7 +6388,7 @@ namespace Game.Entities
|
||||
BroadcastTextRecord bct = CliDB.BroadcastTextStorage.LookupByKey(textId);
|
||||
if (bct == null)
|
||||
{
|
||||
Log.outError(LogFilter.Unit, "WorldObject.MonsterWhisper: `broadcast_text` was not {0} found", textId);
|
||||
Log.outError(LogFilter.Unit, "WorldObject.Whisper: `broadcast_text` was not {0} found", textId);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -538,10 +538,12 @@ namespace Game.Networking.Packets
|
||||
_worldPacket.WriteUInt32(SpellID);
|
||||
_worldPacket.WriteInt32(DeltaTime);
|
||||
_worldPacket.WriteBit(IsPet);
|
||||
_worldPacket.WriteBit(WithoutCategoryCooldown);
|
||||
_worldPacket.FlushBits();
|
||||
}
|
||||
|
||||
public bool IsPet;
|
||||
public bool WithoutCategoryCooldown;
|
||||
public int DeltaTime;
|
||||
public uint SpellID;
|
||||
}
|
||||
|
||||
@@ -1361,7 +1361,7 @@ namespace Game.Spells
|
||||
{
|
||||
// This additional check is needed to add a minimal delay before cooldown in in effect
|
||||
// to allow all bubbles broken by a single damage source proc mana return
|
||||
if (caster.GetSpellHistory().GetRemainingCooldown(aura.GetSpellInfo()) <= 11 * Time.InMilliseconds)
|
||||
if (caster.GetSpellHistory().GetRemainingCooldown(aura.GetSpellInfo()) <= TimeSpan.FromSeconds(11))
|
||||
break;
|
||||
}
|
||||
else // and add if needed
|
||||
|
||||
+22
-11
@@ -7246,42 +7246,53 @@ namespace Game.Spells
|
||||
if (!CanHaveGlobalCooldown(m_caster))
|
||||
return;
|
||||
|
||||
int gcd = (int)m_spellInfo.StartRecoveryTime;
|
||||
if (gcd == 0 || m_spellInfo.StartRecoveryCategory == 0)
|
||||
TimeSpan gcd = TimeSpan.FromMilliseconds(m_spellInfo.StartRecoveryTime);
|
||||
if (gcd == TimeSpan.Zero || m_spellInfo.StartRecoveryCategory == 0)
|
||||
return;
|
||||
|
||||
if (m_caster.IsTypeId(TypeId.Player))
|
||||
if (m_caster.ToPlayer().GetCommandStatus(PlayerCommandStates.Cooldown))
|
||||
return;
|
||||
|
||||
TimeSpan MinGCD = TimeSpan.FromMilliseconds(750);
|
||||
TimeSpan MaxGCD = TimeSpan.FromMilliseconds(1500);
|
||||
|
||||
// Global cooldown can't leave range 1..1.5 secs
|
||||
// There are some spells (mostly not casted directly by player) that have < 1 sec and > 1.5 sec global cooldowns
|
||||
// but as tests show are not affected by any spell mods.
|
||||
if (m_spellInfo.StartRecoveryTime >= 750 && m_spellInfo.StartRecoveryTime <= 1500)
|
||||
if (gcd >= MinGCD && gcd <= MaxGCD)
|
||||
{
|
||||
// gcd modifier auras are applied only to own spells and only players have such mods
|
||||
Player modOwner = m_caster.GetSpellModOwner();
|
||||
if (modOwner)
|
||||
modOwner.ApplySpellMod(m_spellInfo, SpellModOp.StartCooldown, ref gcd, this);
|
||||
{
|
||||
int intGcd = (int)gcd.TotalMilliseconds;
|
||||
modOwner.ApplySpellMod(m_spellInfo, SpellModOp.StartCooldown, ref intGcd, this);
|
||||
gcd = TimeSpan.FromMilliseconds(intGcd);
|
||||
}
|
||||
|
||||
bool isMeleeOrRangedSpell = m_spellInfo.DmgClass == SpellDmgClass.Melee || m_spellInfo.DmgClass == SpellDmgClass.Ranged ||
|
||||
m_spellInfo.HasAttribute(SpellAttr0.ReqAmmo) || m_spellInfo.HasAttribute(SpellAttr0.Ability);
|
||||
|
||||
// Apply haste rating
|
||||
if (gcd > 750 && (m_spellInfo.StartRecoveryCategory == 133 && !isMeleeOrRangedSpell))
|
||||
if (gcd > MinGCD && (m_spellInfo.StartRecoveryCategory == 133 && !isMeleeOrRangedSpell))
|
||||
{
|
||||
gcd = (int)(gcd * m_caster.ToUnit().m_unitData.ModSpellHaste);
|
||||
MathFunctions.RoundToInterval(ref gcd, 750, 1500);
|
||||
gcd = TimeSpan.FromMilliseconds(gcd.TotalMilliseconds * m_caster.ToUnit().m_unitData.ModSpellHaste);
|
||||
int intGcd = (int)gcd.TotalMilliseconds;
|
||||
MathFunctions.RoundToInterval(ref intGcd, 750, 1500);
|
||||
gcd = TimeSpan.FromMilliseconds(intGcd);
|
||||
}
|
||||
|
||||
if (gcd > 750 && m_caster.ToUnit().HasAuraTypeWithAffectMask(AuraType.ModGlobalCooldownByHasteRegen, m_spellInfo))
|
||||
if (gcd > MinGCD && m_caster.ToUnit().HasAuraTypeWithAffectMask(AuraType.ModGlobalCooldownByHasteRegen, m_spellInfo))
|
||||
{
|
||||
gcd = (int)(gcd * m_caster.ToUnit().m_unitData.ModHasteRegen);
|
||||
MathFunctions.RoundToInterval(ref gcd, 750, 1500);
|
||||
gcd = TimeSpan.FromMilliseconds(gcd.TotalMilliseconds * m_caster.ToUnit().m_unitData.ModHasteRegen);
|
||||
int intGcd = (int)gcd.TotalMilliseconds;
|
||||
MathFunctions.RoundToInterval(ref intGcd, 750, 1500);
|
||||
gcd = TimeSpan.FromMilliseconds(intGcd);
|
||||
}
|
||||
}
|
||||
|
||||
m_caster.ToUnit().GetSpellHistory().AddGlobalCooldown(m_spellInfo, (uint)gcd);
|
||||
m_caster.ToUnit().GetSpellHistory().AddGlobalCooldown(m_spellInfo, gcd);
|
||||
}
|
||||
|
||||
void CancelGlobalCooldown()
|
||||
|
||||
@@ -2648,7 +2648,8 @@ namespace Game.Spells
|
||||
if (unitCaster != null)
|
||||
{
|
||||
int duration = m_spellInfo.GetDuration();
|
||||
unitTarget.GetSpellHistory().LockSpellSchool(curSpellInfo.GetSchoolMask(), (uint)unitTarget.ModSpellDuration(m_spellInfo, unitTarget, duration, false, (uint)(1 << (int)effectInfo.EffectIndex)));
|
||||
duration = unitTarget.ModSpellDuration(m_spellInfo, unitTarget, duration, false, 1u << (int)effectInfo.EffectIndex);
|
||||
unitTarget.GetSpellHistory().LockSpellSchool(curSpellInfo.GetSchoolMask(), TimeSpan.FromMilliseconds(duration));
|
||||
if (m_spellInfo.DmgClass == SpellDmgClass.Magic)
|
||||
Unit.ProcSkillsAndAuras(unitCaster, unitTarget, ProcFlags.DoneSpellMagicDmgClassNeg, ProcFlags.TakenSpellMagicDmgClassNeg, ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.Hit, ProcFlagsHit.Interrupt, null, null, null);
|
||||
else if (m_spellInfo.DmgClass == SpellDmgClass.Melee)
|
||||
|
||||
@@ -335,101 +335,116 @@ namespace Game.Spells
|
||||
}
|
||||
}
|
||||
|
||||
public void StartCooldown(SpellInfo spellInfo, uint itemId, Spell spell = null, bool onHold = false)
|
||||
public void StartCooldown(SpellInfo spellInfo, uint itemId, Spell spell = null, bool onHold = false, TimeSpan? forcedCooldown = null)
|
||||
{
|
||||
// init cooldown values
|
||||
uint categoryId = 0;
|
||||
int cooldown = -1;
|
||||
int categoryCooldown = -1;
|
||||
|
||||
GetCooldownDurations(spellInfo, itemId, ref cooldown, ref categoryId, ref categoryCooldown);
|
||||
TimeSpan cooldown = TimeSpan.Zero;
|
||||
TimeSpan categoryCooldown = TimeSpan.Zero;
|
||||
|
||||
DateTime curTime = GameTime.GetGameTimeSystemPoint();
|
||||
DateTime catrecTime;
|
||||
DateTime recTime;
|
||||
bool needsCooldownPacket = false;
|
||||
|
||||
if (!forcedCooldown.HasValue)
|
||||
GetCooldownDurations(spellInfo, itemId, ref cooldown, ref categoryId, ref categoryCooldown);
|
||||
else
|
||||
cooldown = forcedCooldown.Value;
|
||||
|
||||
// overwrite time for selected category
|
||||
if (onHold)
|
||||
{
|
||||
// use +MONTH as infinite cooldown marker
|
||||
catrecTime = categoryCooldown > 0 ? (curTime + PlayerConst.InfinityCooldownDelay) : curTime;
|
||||
recTime = cooldown > 0 ? (curTime + PlayerConst.InfinityCooldownDelay) : catrecTime;
|
||||
catrecTime = categoryCooldown > TimeSpan.Zero ? (curTime + PlayerConst.InfinityCooldownDelay) : curTime;
|
||||
recTime = cooldown > TimeSpan.Zero ? (curTime + PlayerConst.InfinityCooldownDelay) : catrecTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
// shoot spells used equipped item cooldown values already assigned in GetAttackTime(RANGED_ATTACK)
|
||||
// prevent 0 cooldowns set by another way
|
||||
if (cooldown <= 0 && categoryCooldown <= 0 && (categoryId == 76 || (spellInfo.IsAutoRepeatRangedSpell() && spellInfo.Id != 75)))
|
||||
cooldown = (int)(uint)_owner.m_unitData.RangedAttackRoundBaseTime;
|
||||
|
||||
// Now we have cooldown data (if found any), time to apply mods
|
||||
Player modOwner = _owner.GetSpellModOwner();
|
||||
if (modOwner)
|
||||
if (!forcedCooldown.HasValue)
|
||||
{
|
||||
if (cooldown >= 0)
|
||||
modOwner.ApplySpellMod(spellInfo, SpellModOp.Cooldown, ref cooldown, spell);
|
||||
// shoot spells used equipped item cooldown values already assigned in SetBaseAttackTime(RANGED_ATTACK)
|
||||
// prevent 0 cooldowns set by another way
|
||||
if (cooldown <= TimeSpan.Zero && categoryCooldown <= TimeSpan.Zero && (categoryId == 76 || (spellInfo.IsAutoRepeatRangedSpell() && spellInfo.Id != 75)))
|
||||
cooldown = TimeSpan.FromMilliseconds(_owner.m_unitData.RangedAttackRoundBaseTime);
|
||||
|
||||
if (categoryCooldown >= 0 && !spellInfo.HasAttribute(SpellAttr6.IgnoreCategoryCooldownMods))
|
||||
modOwner.ApplySpellMod(spellInfo, SpellModOp.Cooldown, ref categoryCooldown, spell);
|
||||
}
|
||||
|
||||
if (_owner.HasAuraTypeWithAffectMask(AuraType.ModSpellCooldownByHaste, spellInfo))
|
||||
{
|
||||
cooldown = (int)(cooldown * _owner.m_unitData.ModSpellHaste);
|
||||
categoryCooldown = (int)(categoryCooldown * _owner.m_unitData.ModSpellHaste);
|
||||
}
|
||||
|
||||
if (_owner.HasAuraTypeWithAffectMask(AuraType.ModCooldownByHasteRegen, spellInfo))
|
||||
{
|
||||
cooldown = (int)(cooldown * _owner.m_unitData.ModHasteRegen);
|
||||
categoryCooldown = (int)(categoryCooldown * _owner.m_unitData.ModHasteRegen);
|
||||
}
|
||||
|
||||
int cooldownMod = _owner.GetTotalAuraModifier(AuraType.ModCooldown);
|
||||
if (cooldownMod != 0)
|
||||
{
|
||||
// Apply SPELL_AURA_MOD_COOLDOWN only to own spells
|
||||
Player playerOwner = GetPlayerOwner();
|
||||
if (!playerOwner || playerOwner.HasSpell(spellInfo.Id))
|
||||
// Now we have cooldown data (if found any), time to apply mods
|
||||
Player modOwner = _owner.GetSpellModOwner();
|
||||
if (modOwner)
|
||||
{
|
||||
needsCooldownPacket = true;
|
||||
cooldown += cooldownMod * Time.InMilliseconds; // SPELL_AURA_MOD_COOLDOWN does not affect category cooldows, verified with shaman shocks
|
||||
}
|
||||
}
|
||||
void applySpellMod(ref TimeSpan value)
|
||||
{
|
||||
int intValue = (int)value.TotalMilliseconds;
|
||||
modOwner.ApplySpellMod(spellInfo, SpellModOp.Cooldown, ref intValue, spell);
|
||||
value = TimeSpan.FromMilliseconds(intValue);
|
||||
}
|
||||
|
||||
// Apply SPELL_AURA_MOD_SPELL_CATEGORY_COOLDOWN modifiers
|
||||
// Note: This aura applies its modifiers to all cooldowns of spells with set category, not to category cooldown only
|
||||
if (categoryId != 0)
|
||||
{
|
||||
int categoryModifier = _owner.GetTotalAuraModifierByMiscValue(AuraType.ModSpellCategoryCooldown, (int)categoryId);
|
||||
if (categoryModifier != 0)
|
||||
{
|
||||
if (cooldown > 0)
|
||||
cooldown += categoryModifier;
|
||||
if (cooldown >= TimeSpan.Zero)
|
||||
applySpellMod(ref cooldown);
|
||||
|
||||
if (categoryCooldown > 0)
|
||||
categoryCooldown += categoryModifier;
|
||||
if (categoryCooldown >= TimeSpan.Zero && !spellInfo.HasAttribute(SpellAttr6.IgnoreCategoryCooldownMods))
|
||||
applySpellMod(ref categoryCooldown);
|
||||
}
|
||||
|
||||
SpellCategoryRecord categoryEntry = CliDB.SpellCategoryStorage.LookupByKey(categoryId);
|
||||
if (categoryEntry.Flags.HasAnyFlag(SpellCategoryFlags.CooldownExpiresAtDailyReset))
|
||||
categoryCooldown = (int)(Time.UnixTimeToDateTime(Global.WorldMgr.GetNextDailyQuestsResetTime()) - GameTime.GetGameTimeSystemPoint()).TotalMilliseconds;
|
||||
if (_owner.HasAuraTypeWithAffectMask(AuraType.ModSpellCooldownByHaste, spellInfo))
|
||||
{
|
||||
cooldown = TimeSpan.FromMilliseconds(cooldown.TotalMilliseconds * _owner.m_unitData.ModSpellHaste);
|
||||
categoryCooldown = TimeSpan.FromMilliseconds(categoryCooldown.TotalMilliseconds * _owner.m_unitData.ModSpellHaste);
|
||||
}
|
||||
|
||||
if (_owner.HasAuraTypeWithAffectMask(AuraType.ModCooldownByHasteRegen, spellInfo))
|
||||
{
|
||||
cooldown = TimeSpan.FromMilliseconds(cooldown.TotalMilliseconds * _owner.m_unitData.ModHasteRegen);
|
||||
categoryCooldown = TimeSpan.FromMilliseconds(categoryCooldown.TotalMilliseconds * _owner.m_unitData.ModHasteRegen);
|
||||
}
|
||||
|
||||
int cooldownMod = _owner.GetTotalAuraModifier(AuraType.ModCooldown);
|
||||
if (cooldownMod != 0)
|
||||
{
|
||||
// Apply SPELL_AURA_MOD_COOLDOWN only to own spells
|
||||
Player playerOwner = GetPlayerOwner();
|
||||
if (!playerOwner || playerOwner.HasSpell(spellInfo.Id))
|
||||
{
|
||||
needsCooldownPacket = true;
|
||||
cooldown += TimeSpan.FromMilliseconds(cooldownMod); // SPELL_AURA_MOD_COOLDOWN does not affect category cooldows, verified with shaman shocks
|
||||
}
|
||||
}
|
||||
|
||||
// Apply SPELL_AURA_MOD_SPELL_CATEGORY_COOLDOWN modifiers
|
||||
// Note: This aura applies its modifiers to all cooldowns of spells with set category, not to category cooldown only
|
||||
if (categoryId != 0)
|
||||
{
|
||||
int categoryModifier = _owner.GetTotalAuraModifierByMiscValue(AuraType.ModSpellCategoryCooldown, (int)categoryId);
|
||||
if (categoryModifier != 0)
|
||||
{
|
||||
if (cooldown > TimeSpan.Zero)
|
||||
cooldown += TimeSpan.FromMilliseconds(categoryModifier);
|
||||
|
||||
if (categoryCooldown > TimeSpan.Zero)
|
||||
categoryCooldown += TimeSpan.FromMilliseconds(categoryModifier);
|
||||
}
|
||||
|
||||
SpellCategoryRecord categoryEntry = CliDB.SpellCategoryStorage.LookupByKey(categoryId);
|
||||
if (categoryEntry.Flags.HasAnyFlag(SpellCategoryFlags.CooldownExpiresAtDailyReset))
|
||||
categoryCooldown = Time.UnixTimeToDateTime(Global.WorldMgr.GetNextDailyQuestsResetTime()) - GameTime.GetGameTimeSystemPoint();
|
||||
}
|
||||
}
|
||||
else
|
||||
needsCooldownPacket = true;
|
||||
|
||||
// replace negative cooldowns by 0
|
||||
if (cooldown < 0)
|
||||
cooldown = 0;
|
||||
if (cooldown < TimeSpan.Zero)
|
||||
cooldown = TimeSpan.Zero;
|
||||
|
||||
if (categoryCooldown < 0)
|
||||
categoryCooldown = 0;
|
||||
if (categoryCooldown < TimeSpan.Zero)
|
||||
categoryCooldown = TimeSpan.Zero;
|
||||
|
||||
// no cooldown after applying spell mods
|
||||
if (cooldown == 0 && categoryCooldown == 0)
|
||||
if (cooldown == TimeSpan.Zero && categoryCooldown == TimeSpan.Zero)
|
||||
return;
|
||||
|
||||
catrecTime = categoryCooldown != 0 ? curTime + TimeSpan.FromMilliseconds(categoryCooldown) : curTime;
|
||||
recTime = cooldown != 0 ? curTime + TimeSpan.FromMilliseconds(cooldown) : catrecTime;
|
||||
catrecTime = categoryCooldown != TimeSpan.Zero ? curTime + categoryCooldown : curTime;
|
||||
recTime = cooldown != TimeSpan.Zero ? curTime + cooldown : catrecTime;
|
||||
}
|
||||
|
||||
// self spell cooldown
|
||||
@@ -445,7 +460,7 @@ namespace Game.Spells
|
||||
SpellCooldownPkt spellCooldown = new();
|
||||
spellCooldown.Caster = _owner.GetGUID();
|
||||
spellCooldown.Flags = SpellCooldownFlags.None;
|
||||
spellCooldown.SpellCooldowns.Add(new SpellCooldownStruct(spellInfo.Id, (uint)cooldown));
|
||||
spellCooldown.SpellCooldowns.Add(new SpellCooldownStruct(spellInfo.Id, (uint)cooldown.TotalMilliseconds));
|
||||
playerOwner.SendPacket(spellCooldown);
|
||||
}
|
||||
}
|
||||
@@ -486,16 +501,20 @@ namespace Game.Spells
|
||||
public void AddCooldown(uint spellId, uint itemId, DateTime cooldownEnd, uint categoryId, DateTime categoryEnd, bool onHold = false)
|
||||
{
|
||||
CooldownEntry cooldownEntry = new();
|
||||
cooldownEntry.SpellId = spellId;
|
||||
cooldownEntry.CooldownEnd = cooldownEnd;
|
||||
cooldownEntry.ItemId = itemId;
|
||||
cooldownEntry.CategoryId = categoryId;
|
||||
cooldownEntry.CategoryEnd = categoryEnd;
|
||||
cooldownEntry.OnHold = onHold;
|
||||
_spellCooldowns[spellId] = cooldownEntry;
|
||||
// scripts can start multiple cooldowns for a given spell, only store the longest one
|
||||
if (cooldownEnd > cooldownEntry.CooldownEnd || categoryEnd > cooldownEntry.CategoryEnd || onHold)
|
||||
{
|
||||
cooldownEntry.SpellId = spellId;
|
||||
cooldownEntry.CooldownEnd = cooldownEnd;
|
||||
cooldownEntry.ItemId = itemId;
|
||||
cooldownEntry.CategoryId = categoryId;
|
||||
cooldownEntry.CategoryEnd = categoryEnd;
|
||||
cooldownEntry.OnHold = onHold;
|
||||
_spellCooldowns[spellId] = cooldownEntry;
|
||||
|
||||
if (categoryId != 0)
|
||||
_categoryCooldowns[categoryId] = cooldownEntry;
|
||||
if (categoryId != 0)
|
||||
_categoryCooldowns[categoryId] = cooldownEntry;
|
||||
}
|
||||
}
|
||||
|
||||
public void ModifySpellCooldown(uint spellId, TimeSpan offset)
|
||||
@@ -623,7 +642,7 @@ namespace Game.Spells
|
||||
return _categoryCooldowns.ContainsKey(category);
|
||||
}
|
||||
|
||||
public uint GetRemainingCooldown(SpellInfo spellInfo)
|
||||
public TimeSpan GetRemainingCooldown(SpellInfo spellInfo)
|
||||
{
|
||||
DateTime end;
|
||||
var entry = _spellCooldowns.LookupByKey(spellInfo.Id);
|
||||
@@ -633,23 +652,23 @@ namespace Game.Spells
|
||||
{
|
||||
var cooldownEntry = _categoryCooldowns.LookupByKey(spellInfo.GetCategory());
|
||||
if (cooldownEntry == null)
|
||||
return 0;
|
||||
return TimeSpan.Zero;
|
||||
|
||||
end = cooldownEntry.CategoryEnd;
|
||||
}
|
||||
|
||||
DateTime now = GameTime.GetGameTimeSystemPoint();
|
||||
if (end < now)
|
||||
return 0;
|
||||
return TimeSpan.Zero;
|
||||
|
||||
var remaining = end - now;
|
||||
return (uint)remaining.TotalMilliseconds;
|
||||
return remaining;
|
||||
}
|
||||
|
||||
public void LockSpellSchool(SpellSchoolMask schoolMask, uint lockoutTime)
|
||||
public void LockSpellSchool(SpellSchoolMask schoolMask, TimeSpan lockoutTime)
|
||||
{
|
||||
DateTime now = GameTime.GetGameTimeSystemPoint();
|
||||
DateTime lockoutEnd = now + TimeSpan.FromMilliseconds(lockoutTime);
|
||||
DateTime lockoutEnd = now + lockoutTime;
|
||||
for (int i = 0; i < (int)SpellSchools.Max; ++i)
|
||||
if (Convert.ToBoolean((SpellSchoolMask)(1 << i) & schoolMask))
|
||||
_schoolLockouts[i] = lockoutEnd;
|
||||
@@ -679,7 +698,7 @@ namespace Game.Spells
|
||||
|
||||
SpellCooldownPkt spellCooldown = new();
|
||||
spellCooldown.Caster = _owner.GetGUID();
|
||||
spellCooldown.Flags = SpellCooldownFlags.None;
|
||||
spellCooldown.Flags = SpellCooldownFlags.LossOfControlUi;
|
||||
foreach (uint spellId in knownSpells)
|
||||
{
|
||||
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId, _owner.GetMap().GetDifficultyID());
|
||||
@@ -689,11 +708,14 @@ namespace Game.Spells
|
||||
if (!spellInfo.PreventionType.HasAnyFlag(SpellPreventionType.Silence))
|
||||
continue;
|
||||
|
||||
if (Convert.ToBoolean(schoolMask & spellInfo.GetSchoolMask()) && GetRemainingCooldown(spellInfo) < lockoutTime)
|
||||
{
|
||||
spellCooldown.SpellCooldowns.Add(new SpellCooldownStruct(spellId, lockoutTime));
|
||||
if ((schoolMask & spellInfo.GetSchoolMask()) == 0)
|
||||
continue;
|
||||
|
||||
if (GetRemainingCooldown(spellInfo) < lockoutTime)
|
||||
AddCooldown(spellId, 0, lockoutEnd, 0, now);
|
||||
}
|
||||
|
||||
// always send cooldown, even if it will be shorter than already existing cooldown for LossOfControl UI
|
||||
spellCooldown.SpellCooldowns.Add(new SpellCooldownStruct(spellId, (uint)lockoutTime.TotalMilliseconds));
|
||||
}
|
||||
|
||||
Player player = GetPlayerOwner();
|
||||
@@ -856,9 +878,9 @@ namespace Game.Spells
|
||||
return _globalCooldowns.ContainsKey(spellInfo.StartRecoveryCategory) && _globalCooldowns[spellInfo.StartRecoveryCategory] > GameTime.GetGameTimeSystemPoint();
|
||||
}
|
||||
|
||||
public void AddGlobalCooldown(SpellInfo spellInfo, uint duration)
|
||||
public void AddGlobalCooldown(SpellInfo spellInfo, TimeSpan durationMs)
|
||||
{
|
||||
_globalCooldowns[spellInfo.StartRecoveryCategory] = GameTime.GetGameTimeSystemPoint() + TimeSpan.FromMilliseconds(duration);
|
||||
_globalCooldowns[spellInfo.StartRecoveryCategory] = GameTime.GetGameTimeSystemPoint() + durationMs;
|
||||
}
|
||||
|
||||
public void CancelGlobalCooldown(SpellInfo spellInfo)
|
||||
@@ -900,15 +922,15 @@ namespace Game.Spells
|
||||
|
||||
void GetCooldownDurations(SpellInfo spellInfo, uint itemId, ref uint categoryId)
|
||||
{
|
||||
int notUsed = 0;
|
||||
TimeSpan notUsed = TimeSpan.Zero;
|
||||
GetCooldownDurations(spellInfo, itemId, ref notUsed, ref categoryId, ref notUsed);
|
||||
}
|
||||
|
||||
void GetCooldownDurations(SpellInfo spellInfo, uint itemId, ref int cooldown, ref uint categoryId, ref int categoryCooldown)
|
||||
void GetCooldownDurations(SpellInfo spellInfo, uint itemId, ref TimeSpan cooldown, ref uint categoryId, ref TimeSpan categoryCooldown)
|
||||
{
|
||||
int tmpCooldown = -1;
|
||||
TimeSpan tmpCooldown = TimeSpan.MinValue;
|
||||
uint tmpCategoryId = 0;
|
||||
int tmpCategoryCooldown = -1;
|
||||
TimeSpan tmpCategoryCooldown = TimeSpan.MinValue;
|
||||
|
||||
// cooldown information stored in ItemEffect.db2, overriding normal cooldown and category
|
||||
if (itemId != 0)
|
||||
@@ -920,9 +942,9 @@ namespace Game.Spells
|
||||
{
|
||||
if (itemEffect.SpellID == spellInfo.Id)
|
||||
{
|
||||
tmpCooldown = itemEffect.CoolDownMSec;
|
||||
tmpCooldown = TimeSpan.FromMilliseconds(itemEffect.CoolDownMSec);
|
||||
tmpCategoryId = itemEffect.SpellCategoryID;
|
||||
tmpCategoryCooldown = itemEffect.CategoryCoolDownMSec;
|
||||
tmpCategoryCooldown = TimeSpan.FromMilliseconds(itemEffect.CategoryCoolDownMSec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -930,11 +952,11 @@ namespace Game.Spells
|
||||
}
|
||||
|
||||
// if no cooldown found above then base at DBC data
|
||||
if (tmpCooldown < 0 && tmpCategoryCooldown < 0)
|
||||
if (tmpCooldown < TimeSpan.Zero && tmpCategoryCooldown < TimeSpan.Zero)
|
||||
{
|
||||
tmpCooldown = (int)spellInfo.RecoveryTime;
|
||||
tmpCooldown = TimeSpan.FromMilliseconds(spellInfo.RecoveryTime);
|
||||
tmpCategoryId = spellInfo.GetCategory();
|
||||
tmpCategoryCooldown = (int)spellInfo.CategoryRecoveryTime;
|
||||
tmpCategoryCooldown = TimeSpan.FromMilliseconds(spellInfo.CategoryRecoveryTime);
|
||||
}
|
||||
|
||||
cooldown = tmpCooldown;
|
||||
|
||||
@@ -101,26 +101,33 @@ namespace Scripts.World.DuelReset
|
||||
player.GetSpellHistory().ResetCooldowns(pair =>
|
||||
{
|
||||
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(pair.Key, Difficulty.None);
|
||||
uint remainingCooldown = player.GetSpellHistory().GetRemainingCooldown(spellInfo);
|
||||
uint totalCooldown = spellInfo.RecoveryTime;
|
||||
uint categoryCooldown = spellInfo.CategoryRecoveryTime;
|
||||
TimeSpan remainingCooldown = player.GetSpellHistory().GetRemainingCooldown(spellInfo);
|
||||
TimeSpan totalCooldown = TimeSpan.FromMilliseconds(spellInfo.RecoveryTime);
|
||||
TimeSpan categoryCooldown = TimeSpan.FromMilliseconds(spellInfo.CategoryRecoveryTime);
|
||||
|
||||
player.ApplySpellMod(spellInfo, SpellModOp.Cooldown, ref totalCooldown, null);
|
||||
void applySpellMod(ref TimeSpan value)
|
||||
{
|
||||
int intValue = (int)value.TotalMilliseconds;
|
||||
player.ApplySpellMod(spellInfo, SpellModOp.Cooldown, ref intValue, null);
|
||||
value = TimeSpan.FromMilliseconds(intValue);
|
||||
};
|
||||
|
||||
applySpellMod(ref totalCooldown);
|
||||
|
||||
int cooldownMod = player.GetTotalAuraModifier(AuraType.ModCooldown);
|
||||
if (cooldownMod != 0)
|
||||
totalCooldown += (uint)(cooldownMod * Time.InMilliseconds);
|
||||
totalCooldown += TimeSpan.FromMilliseconds(cooldownMod);
|
||||
|
||||
if (!spellInfo.HasAttribute(SpellAttr6.IgnoreCategoryCooldownMods))
|
||||
player.ApplySpellMod(spellInfo, SpellModOp.Cooldown, ref categoryCooldown, null);
|
||||
applySpellMod(ref categoryCooldown);
|
||||
|
||||
return remainingCooldown > 0
|
||||
return remainingCooldown > TimeSpan.Zero
|
||||
&& !pair.Value.OnHold
|
||||
&& TimeSpan.FromMilliseconds(totalCooldown) < TimeSpan.FromMinutes(10)
|
||||
&& TimeSpan.FromMilliseconds(categoryCooldown) < TimeSpan.FromMinutes(10)
|
||||
&& TimeSpan.FromMilliseconds(remainingCooldown) < TimeSpan.FromMinutes(10)
|
||||
&& (onStartDuel ? TimeSpan.FromMilliseconds(totalCooldown - remainingCooldown) > TimeSpan.FromSeconds(30) : true)
|
||||
&& (onStartDuel ? TimeSpan.FromMilliseconds(categoryCooldown - remainingCooldown) > TimeSpan.FromSeconds(30) : true);
|
||||
&& totalCooldown < TimeSpan.FromMinutes(10)
|
||||
&& categoryCooldown < TimeSpan.FromMinutes(10)
|
||||
&& remainingCooldown < TimeSpan.FromMinutes(10)
|
||||
&& (onStartDuel ? totalCooldown - remainingCooldown > TimeSpan.FromSeconds(30) : true)
|
||||
&& (onStartDuel ? categoryCooldown - remainingCooldown > TimeSpan.FromSeconds(30) : true);
|
||||
}, true);
|
||||
|
||||
// pet cooldowns
|
||||
|
||||
Reference in New Issue
Block a user