diff --git a/Projects/UOContent/Mobiles/BaseCreature.cs b/Projects/UOContent/Mobiles/BaseCreature.cs index 952fe37a1..5732fb1a4 100644 --- a/Projects/UOContent/Mobiles/BaseCreature.cs +++ b/Projects/UOContent/Mobiles/BaseCreature.cs @@ -262,7 +262,7 @@ namespace Server.Mobiles private readonly List m_SpellAttack; // List of attack spell/power private readonly List m_SpellDefense; // List of defensive spell/power - private bool m_bSummoned; + private bool _summoned; private bool m_bTamable; private int m_ColdResistance; @@ -554,7 +554,7 @@ namespace Server.Mobiles Summoned && m_ControlMaster != null && SummonFamiliarSpell.Table.TryGetValue(m_ControlMaster, out var bc) && bc == this; - public virtual bool DeleteCorpseOnDeath => !Core.AOS && m_bSummoned; + public virtual bool DeleteCorpseOnDeath => !Core.AOS && _summoned; [CommandProperty(AccessLevel.GameMaster)] public int Loyalty @@ -824,17 +824,17 @@ namespace Server.Mobiles [CommandProperty(AccessLevel.Administrator)] public bool Summoned { - get => m_bSummoned; + get => _summoned; set { - if (m_bSummoned == value) + if (_summoned == value) { return; } NextReacquireTime = Core.TickCount; - m_bSummoned = value; + _summoned = value; Delta(MobileDelta.Noto); InvalidateProperties(); @@ -855,7 +855,7 @@ namespace Server.Mobiles public virtual bool CanRummageCorpses => false; - public virtual bool DeleteOnRelease => m_bSummoned; + public virtual bool DeleteOnRelease => _summoned; public virtual bool CanDrop => IsBonded; @@ -1228,7 +1228,7 @@ namespace Server.Mobiles return true; } - return m_Team != c.m_Team || (m_bSummoned || m_Controlled) != (c.m_bSummoned || c.m_Controlled); + return m_Team != c.m_Team || (_summoned || m_Controlled) != (c._summoned || c.m_Controlled); } public override string ApplyNameSuffix(string suffix) @@ -1268,28 +1268,31 @@ namespace Server.Mobiles public virtual double GetControlChance(Mobile m, bool useBaseSkill = false) { - if (MinTameSkill <= 29.1 || m_bSummoned || m.AccessLevel >= AccessLevel.GameMaster) + if (MinTameSkill <= 29.1 || _summoned || m.AccessLevel >= AccessLevel.GameMaster) { return 1.0; } - var dMinTameSkill = MinTameSkill; + var minTameSkill = MinTameSkill; - if (dMinTameSkill > -24.9 && AnimalTaming.CheckMastery(m, this)) + if (minTameSkill > -24.9 && AnimalTaming.CheckMastery(m, this)) { - dMinTameSkill = -24.9; + minTameSkill = -24.9; } - var taming = - (int)((useBaseSkill ? m.Skills.AnimalTaming.Base : m.Skills.AnimalTaming.Value) * 10); - var lore = - (int)((useBaseSkill ? m.Skills.AnimalLore.Base : m.Skills.AnimalLore.Value) * 10); + var taming = useBaseSkill + ? m.Skills.AnimalTaming.BaseFixedPoint + : m.Skills.AnimalTaming.Fixed; + var lore = useBaseSkill + ? m.Skills.AnimalLore.BaseFixedPoint + : m.Skills.AnimalLore.Fixed; + int bonus; if (Core.ML) { - var skillBonus = taming - (int)(dMinTameSkill * 10); - var loreBonus = lore - (int)(dMinTameSkill * 10); + var skillBonus = taming - (int)(minTameSkill * 10); + var loreBonus = lore - (int)(minTameSkill * 10); var skillMod = 6; var loreMod = 6; @@ -1311,7 +1314,7 @@ namespace Server.Mobiles } else { - var difficulty = (int)(dMinTameSkill * 10); + var difficulty = (int)(minTameSkill * 10); var weighted = (taming * 4 + lore) / 5; bonus = weighted - difficulty; @@ -1325,20 +1328,11 @@ namespace Server.Mobiles } } - var chance = 700 + bonus; - - if (chance > 990) - { - chance = 990; - } - else if (chance >= 0) - { - chance = 220; - } + var chance = Math.Clamp(700 + bonus, 220, 990); chance -= (MaxLoyalty - m_Loyalty) * 10; - return (double)chance / 1000; + return chance / 1000.0; } public override void Damage(int amount, Mobile from = null, bool informMount = true) @@ -1732,9 +1726,9 @@ namespace Server.Mobiles // Removed in version 9 // writer.Write( (double) m_dMaxTameSkill ); writer.Write(m_bTamable); - writer.Write(m_bSummoned); + writer.Write(_summoned); - if (m_bSummoned) + if (_summoned) { writer.WriteDeltaTime(SummonEnd); } @@ -1899,9 +1893,9 @@ namespace Server.Mobiles } m_bTamable = reader.ReadBool(); - m_bSummoned = reader.ReadBool(); + _summoned = reader.ReadBool(); - if (m_bSummoned) + if (_summoned) { SummonEnd = reader.ReadDeltaTime(); new UnsummonTimer(m_ControlMaster, this, SummonEnd - Core.Now).Start(); @@ -2447,7 +2441,7 @@ namespace Server.Mobiles } } - if (aggressor.ChangingCombatant && (m_Controlled || m_bSummoned) && + if (aggressor.ChangingCombatant && (m_Controlled || _summoned) && (ct == OrderType.Come || !Core.ML && ct == OrderType.Stay || ct == OrderType.Stop || ct == OrderType.None || ct == OrderType.Follow)) { @@ -3703,7 +3697,7 @@ namespace Server.Mobiles return m_ControlMaster; } - if (m_bSummoned && m_SummonMaster != null) + if (_summoned && m_SummonMaster != null) { return m_SummonMaster; } @@ -4212,7 +4206,7 @@ namespace Server.Mobiles public virtual bool IsFriend(Mobile m) => OppositionGroup?.IsEnemy(this, m) != true && m is BaseCreature c && m_Team == c.m_Team - && (m_bSummoned || m_Controlled) == (c.m_bSummoned || c.m_Controlled); + && (_summoned || m_Controlled) == (c._summoned || c.m_Controlled); public virtual Allegiance GetFactionAllegiance(Mobile mob) { diff --git a/Projects/UOContent/Skills/AnimalTaming.cs b/Projects/UOContent/Skills/AnimalTaming.cs index 15f976454..99833a41e 100644 --- a/Projects/UOContent/Skills/AnimalTaming.cs +++ b/Projects/UOContent/Skills/AnimalTaming.cs @@ -37,8 +37,9 @@ namespace Server.SkillHandlers } public static bool CheckMastery(Mobile tamer, BaseCreature creature) => - SummonFamiliarSpell.Table.TryGetValue(tamer, out var bc) && bc is DarkWolfFamiliar familiar && - !familiar.Deleted && creature is DireWolf or GreyWolf or TimberWolf or WhiteWolf or BakeKitsune; + SummonFamiliarSpell.Table.TryGetValue(tamer, out var bc) + && bc is DarkWolfFamiliar { Deleted: false } + && creature is DireWolf or GreyWolf or TimberWolf or WhiteWolf or BakeKitsune; public static bool MustBeSubdued(BaseCreature bc) => bc.Owners.Count <= 0 && bc.SubdueBeforeTame && bc.Hits > bc.HitsMax / 10; diff --git a/Projects/UOContent/Spells/Base/Spell.cs b/Projects/UOContent/Spells/Base/Spell.cs index ee84ee119..4be93b9b3 100644 --- a/Projects/UOContent/Spells/Base/Spell.cs +++ b/Projects/UOContent/Spells/Base/Spell.cs @@ -84,10 +84,13 @@ namespace Server.Spells public virtual void OnCasterHurt() { // Confirm: Monsters and pets cannot be disturbed. - if (Caster.Player && IsCasting && ProtectionSpell.Registry.TryGetValue(Caster, out var d) && - d <= Utility.RandomDouble() * 100.0) + if (Caster.Player && IsCasting) { - Disturb(DisturbType.Hurt, false, true); + var hasProtection = ProtectionSpell.Registry.TryGetValue(Caster, out var d); + if (!hasProtection || d < 1000 && d < Utility.Random(1000)) + { + Disturb(DisturbType.Hurt, false, true); + } } } @@ -704,7 +707,7 @@ namespace Server.Spells { DoFizzle(); } - else if (Scroll != null && !(Scroll is Runebook) && + else if (Scroll != null && Scroll is not Runebook && (Scroll.Amount <= 0 || Scroll.Deleted || Scroll.RootParent != Caster || Scroll is BaseWand baseWand && (baseWand.Charges <= 0 || baseWand.Parent != Caster))) { diff --git a/Projects/UOContent/Spells/Fourth/ArchProtection.cs b/Projects/UOContent/Spells/Fourth/ArchProtection.cs index 874fd3c2f..2f1923f3f 100644 --- a/Projects/UOContent/Spells/Fourth/ArchProtection.cs +++ b/Projects/UOContent/Spells/Fourth/ArchProtection.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using System.Linq; +using Server.Collections; using Server.Engines.PartySystem; using Server.Spells.Second; using Server.Targeting; @@ -53,15 +53,26 @@ namespace Server.Spells.Fourth return; } - var targets = Caster.Map.GetMobilesInRange(loc, Core.AOS ? 2 : 3) - .Where(m => Caster.CanBeBeneficial(m, false)); + var eable = Caster.Map.GetMobilesInRange(loc, Core.AOS ? 2 : 3); + using var targets = PooledRefQueue.Create(); + + foreach (var m in eable) + { + if (Caster.CanBeBeneficial(m, false)) + { + targets.Enqueue(m); + } + } + + eable.Free(); if (Core.AOS) { var party = Party.Get(Caster); - foreach (var m in targets) + while (targets.Count > 0) { + var m = targets.Dequeue(); if (m == Caster || party?.Contains(m) == true) { Caster.DoBeneficial(m); @@ -73,8 +84,9 @@ namespace Server.Spells.Fourth { var val = (int)(Caster.Skills.Magery.Value / 10.0 + 1); - foreach (var m in targets) + while (targets.Count > 0) { + var m = targets.Dequeue(); if (m.BeginAction()) { Caster.DoBeneficial(m); diff --git a/Projects/UOContent/Spells/Fourth/FireField.cs b/Projects/UOContent/Spells/Fourth/FireField.cs index 54ee7087b..1123b1476 100644 --- a/Projects/UOContent/Spells/Fourth/FireField.cs +++ b/Projects/UOContent/Spells/Fourth/FireField.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using Server.Collections; using Server.Items; using Server.Misc; diff --git a/Projects/UOContent/Spells/Second/Protection.cs b/Projects/UOContent/Spells/Second/Protection.cs index d115ec855..430df38b6 100644 --- a/Projects/UOContent/Spells/Second/Protection.cs +++ b/Projects/UOContent/Spells/Second/Protection.cs @@ -22,7 +22,7 @@ namespace Server.Spells.Second { } - public static Dictionary Registry { get; } = new(); + public static Dictionary Registry { get; } = new(); public override SpellCircle Circle => SpellCircle.Second; @@ -48,6 +48,7 @@ namespace Server.Spells.Second return false; } + // AOS+ only public static void Toggle(Mobile caster, Mobile target) { /* Players under the protection spell effect can no longer have their spells "disrupted" when hit. @@ -89,7 +90,7 @@ namespace Server.Spells.Second ); m_Table[target] = mods; - Registry[target] = 100.0; + Registry[target] = 1000; // 100.0% protection from disruption target.AddResistanceMod(mods.Item1); target.AddSkillMod(mods.Item2); @@ -141,12 +142,11 @@ namespace Server.Spells.Second { if (Caster.BeginAction()) { - double value = (int)(Caster.Skills.EvalInt.Value + - Caster.Skills.Meditation.Value + - Caster.Skills.Inscribe.Value); - value /= 4; + int value = (Caster.Skills.EvalInt.Fixed + + Caster.Skills.Meditation.Fixed + + Caster.Skills.Inscribe.Fixed) / 4; - Registry.Add(Caster, Math.Clamp(value, 0.0, 75.0)); + Registry.Add(Caster, Math.Clamp(value, 0, 750)); // 75.0% protection from disruption new InternalTimer(Caster).Start(); Caster.FixedParticles(0x375A, 9, 20, 5016, EffectLayer.Waist);