diff --git a/Projects/Server/Migrations/Server.MobileMod.v0.json b/Projects/Server/Migrations/Server.MobileMod.v0.json index 5e9c66631..d9ecc6520 100644 --- a/Projects/Server/Migrations/Server.MobileMod.v0.json +++ b/Projects/Server/Migrations/Server.MobileMod.v0.json @@ -1,4 +1,14 @@ { "version": 0, - "type": "Server.MobileMod" + "type": "Server.MobileMod", + "properties": [ + { + "name": "Name", + "type": "string", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + } + ] } \ No newline at end of file diff --git a/Projects/Server/Migrations/Server.StatMod.v0.json b/Projects/Server/Migrations/Server.StatMod.v0.json index 5b3b28174..9d655f807 100644 --- a/Projects/Server/Migrations/Server.StatMod.v0.json +++ b/Projects/Server/Migrations/Server.StatMod.v0.json @@ -20,14 +20,6 @@ "type": "Server.StatType", "rule": "EnumMigrationRule" }, - { - "name": "Name", - "type": "string", - "rule": "PrimitiveTypeMigrationRule", - "ruleArguments": [ - "" - ] - }, { "name": "Offset", "type": "int", diff --git a/Projects/Server/Mobiles/Mobile.cs b/Projects/Server/Mobiles/Mobile.cs index fd1799d98..f434cd6fc 100644 --- a/Projects/Server/Mobiles/Mobile.cs +++ b/Projects/Server/Mobiles/Mobile.cs @@ -331,6 +331,9 @@ public class Mobile : IHued, IComparable, ISpawnable, IObjectPropertyLis private IWeapon m_Weapon; private bool m_YellowHealthbar; + private List _statMods; + private List _resistanceMods; + private List _skillMods; public Mobile() { @@ -402,8 +405,6 @@ public class Mobile : IHued, IComparable, ISpawnable, IObjectPropertyLis [CommandProperty(AccessLevel.Counselor)] public virtual int EnergyResistance => GetResistance(ResistanceType.Energy); - public List ResistanceMods { get; set; } - public static int MaxPlayerResistance { get; set; } = 70; public virtual bool NewGuildDisplay => false; @@ -415,7 +416,9 @@ public class Mobile : IHued, IComparable, ISpawnable, IObjectPropertyLis public object Party { get; set; } - public HashSet SkillMods { get; private set; } + public List SkillMods => _skillMods; + public List StatMods => _statMods; + public List ResistanceMods => _resistanceMods; [CommandProperty(AccessLevel.GameMaster)] public int VirtualArmorMod @@ -1783,11 +1786,6 @@ public class Mobile : IHued, IComparable, ISpawnable, IObjectPropertyLis } } - /// - /// Gets a list of all StatMod's currently active for the Mobile. - /// - public HashSet StatMods { get; private set; } - /// /// Gets or sets the base, unmodified, strength of the Mobile. Ranges from 1 to 65000, inclusive. /// @@ -1839,7 +1837,7 @@ public class Mobile : IHued, IComparable, ISpawnable, IObjectPropertyLis get => Math.Clamp(m_Str + GetStatOffset(StatType.Str), 1, 65000); set { - if (StatMods.Count == 0) + if (_statMods.Count == 0) { RawStr = value; } @@ -1897,7 +1895,7 @@ public class Mobile : IHued, IComparable, ISpawnable, IObjectPropertyLis get => Math.Clamp(m_Dex + GetStatOffset(StatType.Dex), 0, 65000); set { - if (StatMods.Count == 0) + if (_statMods.Count == 0) { RawDex = value; } @@ -1955,7 +1953,7 @@ public class Mobile : IHued, IComparable, ISpawnable, IObjectPropertyLis get => Math.Clamp(m_Int + GetStatOffset(StatType.Int), 0, 65000); set { - if (StatMods.Count == 0) + if (_statMods.Count == 0) { RawInt = value; } @@ -3090,26 +3088,76 @@ public class Mobile : IHued, IComparable, ISpawnable, IObjectPropertyLis return res; } - public virtual void AddResistanceMod(ResistanceMod toAdd) + public virtual void AddResistanceMod(ResistanceMod mod) { - ResistanceMods ??= new List(); + if (mod == null) + { + return; + } + + _resistanceMods ??= new List(); + _resistanceMods.Add(mod); - ResistanceMods.Add(toAdd); UpdateResistances(); } - public virtual void RemoveResistanceMod(ResistanceMod toRemove) + public virtual ResistanceMod GetResistanceMod(string name) { - if (ResistanceMods != null) + if (_resistanceMods == null || name == null) { - ResistanceMods.Remove(toRemove); + return null; + } - if (ResistanceMods.Count == 0) + for (var i = 0; i < _resistanceMods.Count; i++) + { + var mod = _resistanceMods[i]; + if (mod.Name == name) { - ResistanceMods = null; + return mod; } } + return null; + } + + public virtual void RemoveResistanceMod(string name) + { + if (_resistanceMods == null || name == null) + { + return; + } + + for (var i = _resistanceMods.Count - 1; i >= 0; i--) + { + var mod = _resistanceMods[i]; + if (mod.Name == name) + { + _resistanceMods.RemoveAt(i); + } + } + + if (_resistanceMods.Count == 0) + { + _resistanceMods = null; + } + + UpdateResistances(); + } + + public virtual void RemoveResistanceMod(ResistanceMod mod) + { + if (_resistanceMods == null) + { + return; + } + + _resistanceMods.Remove(mod); + + if (_resistanceMods.Count == 0) + { + _resistanceMods = null; + } + UpdateResistances(); } @@ -3128,9 +3176,9 @@ public class Mobile : IHued, IComparable, ISpawnable, IObjectPropertyLis Resistances[3] += BasePoisonResistance; Resistances[4] += BaseEnergyResistance; - for (var i = 0; i < ResistanceMods?.Count; ++i) + for (var i = 0; i < _resistanceMods.Count; i++) { - var mod = ResistanceMods[i]; + var mod = _resistanceMods[i]; var v = (int)mod.Type; if (v >= 0 && v < Resistances.Length) @@ -3362,32 +3410,25 @@ public class Mobile : IHued, IComparable, ISpawnable, IObjectPropertyLis { } - public virtual void UpdateSkillMods() - { - ValidateSkillMods(); - - foreach (var mod in SkillMods) - { - var sk = Skills[mod.Skill]; - sk?.Update(); - } - } - public virtual void ValidateSkillMods() { - using var queue = PooledRefQueue.Create(8); - foreach (var mod in SkillMods) + if (_skillMods == null) { + return; + } + + for (var i = _skillMods.Count - 1; i >= 0; i--) + { + var mod = _skillMods[i]; + if (!mod.CheckCondition()) { - queue.Enqueue(mod); + _skillMods.RemoveAt(i); + mod.Owner = null; + Skills[mod.Skill]?.Update(); } } - while (queue.Count > 0) - { - InternalRemoveSkillMod(queue.Dequeue()); - } } public virtual void AddSkillMod(SkillMod mod) @@ -3398,35 +3439,77 @@ public class Mobile : IHued, IComparable, ISpawnable, IObjectPropertyLis } ValidateSkillMods(); + _skillMods ??= new List(); + _skillMods.Add(mod); + mod.Owner = this; + Skills[mod.Skill]?.Update(); + } - if (SkillMods.Add(mod)) + public virtual SkillMod GetSkillMod(string name) + { + if (_skillMods == null || name == null) { - mod.Owner = this; + return null; + } - var sk = Skills[mod.Skill]; - sk?.Update(); + ValidateSkillMods(); + + for (var i = 0; i < _skillMods.Count; i++) + { + var mod = _skillMods[i]; + if (mod.Name == name) + { + return mod; + } + } + + return null; + } + + public virtual void RemoveSkillMod(string name) + { + if (_skillMods == null || name == null) + { + return; + } + + for (var i = _skillMods.Count - 1; i >= 0; i--) + { + var mod = _skillMods[i]; + if (mod.Name == name) + { + mod.Owner = null; + Skills[mod.Skill]?.Update(); + _skillMods.RemoveAt(i); + } + } + + ValidateSkillMods(); + + if (_skillMods.Count == 0) + { + _skillMods = null; } } public virtual void RemoveSkillMod(SkillMod mod) { - if (mod == null) + if (_skillMods == null || mod == null) { return; } - InternalRemoveSkillMod(mod); - ValidateSkillMods(); - } - - private void InternalRemoveSkillMod(SkillMod mod) - { - if (SkillMods.Remove(mod)) + if (_skillMods.Remove(mod)) { mod.Owner = null; + Skills[mod.Skill]?.Update(); + } - var sk = Skills[mod.Skill]; - sk?.Update(); + ValidateSkillMods(); + + if (_skillMods.Count == 0) + { + _skillMods = null; } } @@ -6259,8 +6342,8 @@ public class Mobile : IHued, IComparable, ISpawnable, IObjectPropertyLis m_DexLock = (StatLockType)reader.ReadByte(); m_IntLock = (StatLockType)reader.ReadByte(); - StatMods = new HashSet(); - SkillMods = new HashSet(); + _statMods = new List(); + _skillMods = new List(); if (version < 32) { @@ -7608,8 +7691,8 @@ public class Mobile : IHued, IComparable, ISpawnable, IObjectPropertyLis m_FollowersMax = 5; Skills = new Skills(this); Items = new List(); - StatMods = new HashSet(); - SkillMods = new HashSet(); + _statMods = new List(); + _skillMods = new List(); Map = Map.Internal; AutoPageNotify = true; Aggressors = new List(); @@ -8293,43 +8376,58 @@ public class Mobile : IHued, IComparable, ISpawnable, IObjectPropertyLis return false; } - public bool RemoveStatMod(string name) + public virtual void RemoveStatMod(string name) { - StatMods ??= new HashSet(); - - StatMod mod = GetStatMod(name); - - if (mod != null) + if (_statMods == null || name == null) { - StatMods.Remove(mod); - CheckStatTimers(); - Delta(MobileDelta.Stat | GetStatDelta(mod.Type)); - return true; + return; } - return false; + for (var i = _statMods.Count - 1; i >= 0; i--) + { + var mod = _statMods[i]; + if (mod.Name == name) + { + _statMods.RemoveAt(i); + CheckStatTimers(); + Delta(MobileDelta.Stat | GetStatDelta(mod.Type)); + } + } + + + if (_statMods.Count == 0) + { + _statMods = null; + } } - public StatMod GetStatMod(string name) + public virtual StatMod GetStatMod(string name) { - StatMods ??= new HashSet(); - - foreach (var check in StatMods) + if (_statMods == null || name == null) { - if (check.Name == name) + return null; + } + + for (var i = 0; i < _statMods.Count; i++) + { + var mod = _statMods[i]; + if (mod.Name == name) { - return check; + return mod; } } return null; } - public void AddStatMod(StatMod mod) + public virtual void AddStatMod(StatMod mod) { - RemoveStatMod(mod.Name); + if (mod == null) + { + return; + } - StatMods.Add(mod); + _statMods.Add(mod); Delta(MobileDelta.Stat | GetStatDelta(mod.Type)); CheckStatTimers(); } @@ -8361,32 +8459,35 @@ public class Mobile : IHued, IComparable, ISpawnable, IObjectPropertyLis /// public int GetStatOffset(StatType type) { + _statMods ??= new List(); + + if (_statMods.Count <= 0) + { + return 0; + } + var offset = 0; - StatMods ??= new HashSet(); - - if (StatMods.Count > 0) + using var queue = PooledRefQueue.Create(8); + for (var i = 0; i < _statMods.Count; i++) { - using var queue = PooledRefQueue.Create(8); - foreach (var mod in StatMods) + var mod = _statMods[i]; + if (mod.HasElapsed()) { - if (mod.HasElapsed()) - { - queue.Enqueue(mod); - } - else if ((mod.Type & type) != 0) - { - offset += mod.Offset; - } + queue.Enqueue(mod); } + else if ((mod.Type & type) != 0) + { + offset += mod.Offset; + } + } - while (queue.Count > 0) - { - var mod = queue.Dequeue(); - StatMods.Remove(mod); - Delta(MobileDelta.Stat | GetStatDelta(mod.Type)); - CheckStatTimers(); - } + while (queue.Count > 0) + { + var mod = queue.Dequeue(); + _statMods.Remove(mod); + Delta(MobileDelta.Stat | GetStatDelta(mod.Type)); + CheckStatTimers(); } return offset; diff --git a/Projects/Server/Mobiles/Mods/DefaultSkillMod.cs b/Projects/Server/Mobiles/Mods/DefaultSkillMod.cs index 578cf2cb5..9065df7e5 100644 --- a/Projects/Server/Mobiles/Mods/DefaultSkillMod.cs +++ b/Projects/Server/Mobiles/Mods/DefaultSkillMod.cs @@ -24,7 +24,7 @@ public partial class DefaultSkillMod : SkillMod { } - public DefaultSkillMod(SkillName skill, bool relative, double value) : base(skill, relative, value) + public DefaultSkillMod(SkillName skill, string name, bool relative, double value) : base(skill, name, relative, value) { } diff --git a/Projects/Server/Mobiles/Mods/EquippedSkillMod.cs b/Projects/Server/Mobiles/Mods/EquippedSkillMod.cs index 101a19681..870c6763e 100644 --- a/Projects/Server/Mobiles/Mods/EquippedSkillMod.cs +++ b/Projects/Server/Mobiles/Mods/EquippedSkillMod.cs @@ -27,8 +27,8 @@ public partial class EquippedSkillMod : SkillMod { } - public EquippedSkillMod(SkillName skill, bool relative, double value, Item item, Mobile mobile) - : base(skill, relative, value, mobile) => _item = item; + public EquippedSkillMod(SkillName skill, string name, bool relative, double value, Item item, Mobile owner) + : base(skill, name, relative, value, owner) => _item = item; public override bool CheckCondition() => !_item.Deleted && Owner?.Deleted == false && _item.Parent == Owner; } diff --git a/Projects/Server/Mobiles/Mods/MobileMod.cs b/Projects/Server/Mobiles/Mods/MobileMod.cs index 797e0e543..32ce0b83e 100644 --- a/Projects/Server/Mobiles/Mods/MobileMod.cs +++ b/Projects/Server/Mobiles/Mods/MobileMod.cs @@ -23,5 +23,14 @@ public partial class MobileMod [DirtyTrackingEntity] public Mobile Owner { get; set; } + [SerializableField(0)] + private string _name; + public MobileMod(Mobile owner) => Owner = owner; + + public MobileMod(Mobile owner, string name) + { + Owner = owner; + Name = name; + } } diff --git a/Projects/Server/Mobiles/Mods/ResistanceMod.cs b/Projects/Server/Mobiles/Mods/ResistanceMod.cs index 67d254692..13cb84c30 100644 --- a/Projects/Server/Mobiles/Mods/ResistanceMod.cs +++ b/Projects/Server/Mobiles/Mods/ResistanceMod.cs @@ -24,7 +24,7 @@ public partial class ResistanceMod : MobileMod { } - public ResistanceMod(ResistanceType type, int offset, Mobile owner = null) : base(owner) + public ResistanceMod(ResistanceType type, string name, int offset, Mobile owner = null) : base(owner, name) { _type = type; _offset = offset; diff --git a/Projects/Server/Mobiles/Mods/SkillMod.cs b/Projects/Server/Mobiles/Mods/SkillMod.cs index 57312e3ae..e92ee6981 100644 --- a/Projects/Server/Mobiles/Mods/SkillMod.cs +++ b/Projects/Server/Mobiles/Mods/SkillMod.cs @@ -25,7 +25,7 @@ public abstract partial class SkillMod : MobileMod { } - public SkillMod(SkillName skill, bool relative, double value, Mobile owner = null) : base(owner) + public SkillMod(SkillName skill, string name, bool relative, double value, Mobile owner = null) : base(owner, name) { _skill = skill; _relative = relative; diff --git a/Projects/Server/Mobiles/Mods/StatMod.cs b/Projects/Server/Mobiles/Mods/StatMod.cs index d92067368..0475879cd 100644 --- a/Projects/Server/Mobiles/Mods/StatMod.cs +++ b/Projects/Server/Mobiles/Mods/StatMod.cs @@ -31,19 +31,15 @@ public partial class StatMod : MobileMod private StatType _type; [SerializableField(3, setter: "private")] - private string _name; - - [SerializableField(4, setter: "private")] private int _offset; public StatMod(Mobile owner) : base(owner) { } - public StatMod(StatType type, string name, int offset, TimeSpan duration, Mobile owner = null) : base(owner) + public StatMod(StatType type, string name, int offset, TimeSpan duration, Mobile owner = null) : base(owner, name) { _type = type; - _name = name; _offset = offset; _duration = duration; _added = Core.Now; diff --git a/Projects/Server/Mobiles/Mods/TimedSkillMod.cs b/Projects/Server/Mobiles/Mods/TimedSkillMod.cs index 388e79c0e..0fc4cbdb6 100644 --- a/Projects/Server/Mobiles/Mods/TimedSkillMod.cs +++ b/Projects/Server/Mobiles/Mods/TimedSkillMod.cs @@ -28,13 +28,13 @@ public partial class TimedSkillMod : SkillMod { } - public TimedSkillMod(SkillName skill, bool relative, double value, TimeSpan delay) - : this(skill, relative, value, Core.Now + delay) + public TimedSkillMod(SkillName skill, string name, bool relative, double value, TimeSpan delay) + : this(skill, name, relative, value, Core.Now + delay) { } - public TimedSkillMod(SkillName skill, bool relative, double value, DateTime expire) - : base(skill, relative, value) => _expire = expire; + public TimedSkillMod(SkillName skill, string name, bool relative, double value, DateTime expire) + : base(skill, name, relative, value) => _expire = expire; public override bool CheckCondition() => Core.Now < _expire; } diff --git a/Projects/UOContent/Engines/Factions/Core/Faction.cs b/Projects/UOContent/Engines/Factions/Core/Faction.cs index f4f126922..066e2e397 100644 --- a/Projects/UOContent/Engines/Factions/Core/Faction.cs +++ b/Projects/UOContent/Engines/Factions/Core/Faction.cs @@ -1329,7 +1329,12 @@ namespace Server.Factions if (baseValue > 0) { - SkillMod mod = new DefaultSkillMod(sk.SkillName, true, -(baseValue * SkillLossFactor)); + SkillMod mod = new DefaultSkillMod( + sk.SkillName, + $"{sk.Name}FactionSkillLoss", + true, + -(baseValue * SkillLossFactor) + ); mods.Add(mod); mob.AddSkillMod(mod); diff --git a/Projects/UOContent/Items/Special/Bulk Order Rewards/Blacksmithy/AncientSmithyHammer.cs b/Projects/UOContent/Items/Special/Bulk Order Rewards/Blacksmithy/AncientSmithyHammer.cs index fb5795e02..065f67e84 100644 --- a/Projects/UOContent/Items/Special/Bulk Order Rewards/Blacksmithy/AncientSmithyHammer.cs +++ b/Projects/UOContent/Items/Special/Bulk Order Rewards/Blacksmithy/AncientSmithyHammer.cs @@ -38,7 +38,7 @@ namespace Server.Items } else if (m_SkillMod == null && Parent is Mobile mobile) { - m_SkillMod = new DefaultSkillMod(SkillName.Blacksmith, true, m_Bonus); + m_SkillMod = new DefaultSkillMod(SkillName.Blacksmith, "AncientSmithyHammer", true, m_Bonus); mobile.AddSkillMod(m_SkillMod); } else if (m_SkillMod != null) @@ -59,7 +59,7 @@ namespace Server.Items { m_SkillMod?.Remove(); - m_SkillMod = new DefaultSkillMod(SkillName.Blacksmith, true, m_Bonus); + m_SkillMod = new DefaultSkillMod(SkillName.Blacksmith, "AncientSmithyHammer", true, m_Bonus); mobile.AddSkillMod(m_SkillMod); } } @@ -111,7 +111,7 @@ namespace Server.Items { m_SkillMod?.Remove(); - m_SkillMod = new DefaultSkillMod(SkillName.Blacksmith, true, m_Bonus); + m_SkillMod = new DefaultSkillMod(SkillName.Blacksmith, "AncientSmithyHammer", true, m_Bonus); mobile.AddSkillMod(m_SkillMod); } diff --git a/Projects/UOContent/Items/Special/Bulk Order Rewards/Blacksmithy/GlovesOfMining.cs b/Projects/UOContent/Items/Special/Bulk Order Rewards/Blacksmithy/GlovesOfMining.cs index 8fe83deaa..65aefb647 100644 --- a/Projects/UOContent/Items/Special/Bulk Order Rewards/Blacksmithy/GlovesOfMining.cs +++ b/Projects/UOContent/Items/Special/Bulk Order Rewards/Blacksmithy/GlovesOfMining.cs @@ -164,7 +164,7 @@ namespace Server.Items } else if (m_SkillMod == null && Parent is Mobile mobile) { - m_SkillMod = new DefaultSkillMod(SkillName.Mining, true, m_Bonus); + m_SkillMod = new DefaultSkillMod(SkillName.Mining, "MiningGloves", true, m_Bonus); mobile.AddSkillMod(m_SkillMod); } else if (m_SkillMod != null) @@ -182,7 +182,7 @@ namespace Server.Items { m_SkillMod?.Remove(); - m_SkillMod = new DefaultSkillMod(SkillName.Mining, true, m_Bonus); + m_SkillMod = new DefaultSkillMod(SkillName.Mining, "MiningGloves", true, m_Bonus); mobile.AddSkillMod(m_SkillMod); } } @@ -234,7 +234,7 @@ namespace Server.Items { m_SkillMod?.Remove(); - m_SkillMod = new DefaultSkillMod(SkillName.Mining, true, m_Bonus); + m_SkillMod = new DefaultSkillMod(SkillName.Mining, "MiningGloves", true, m_Bonus); mobile.AddSkillMod(m_SkillMod); } } diff --git a/Projects/UOContent/Items/Weapons/Abilities/DefenseMastery.cs b/Projects/UOContent/Items/Weapons/Abilities/DefenseMastery.cs index ee6ce5792..44715634a 100644 --- a/Projects/UOContent/Items/Weapons/Abilities/DefenseMastery.cs +++ b/Projects/UOContent/Items/Weapons/Abilities/DefenseMastery.cs @@ -36,7 +36,7 @@ namespace Server.Items EndDefense(info); } - var mod = new ResistanceMod(ResistanceType.Physical, 50 + modifier); + var mod = new ResistanceMod(ResistanceType.Physical, "PhysicalResistDefenseMastery", 50 + modifier); attacker.AddResistanceMod(mod); info = new DefenseMasteryInfo(attacker, 80 - modifier, mod); diff --git a/Projects/UOContent/Items/Weapons/BaseWeapon.cs b/Projects/UOContent/Items/Weapons/BaseWeapon.cs index 01f5300da..8f835d62d 100644 --- a/Projects/UOContent/Items/Weapons/BaseWeapon.cs +++ b/Projects/UOContent/Items/Weapons/BaseWeapon.cs @@ -439,7 +439,7 @@ namespace Server.Items } else if (m_SkillMod == null && Parent is Mobile mobile) { - m_SkillMod = new DefaultSkillMod(AccuracySkill, true, (int)m_AccuracyLevel * 5); + m_SkillMod = new DefaultSkillMod(AccuracySkill, "WeaponAccuracy", true, (int)m_AccuracyLevel * 5); mobile.AddSkillMod(m_SkillMod); } else if (m_SkillMod != null) @@ -966,7 +966,7 @@ namespace Server.Items { m_SkillMod?.Remove(); - m_SkillMod = new DefaultSkillMod(AccuracySkill, true, (int)m_AccuracyLevel * 5); + m_SkillMod = new DefaultSkillMod(AccuracySkill, "WeaponAccuracy", true, (int)m_AccuracyLevel * 5); from.AddSkillMod(m_SkillMod); } @@ -974,7 +974,7 @@ namespace Server.Items { m_MageMod?.Remove(); - m_MageMod = new DefaultSkillMod(SkillName.Magery, true, -30 + WeaponAttributes.MageWeapon); + m_MageMod = new DefaultSkillMod(SkillName.Magery, "MageWeapon", true, -30 + WeaponAttributes.MageWeapon); from.AddSkillMod(m_MageMod); } @@ -3944,7 +3944,7 @@ namespace Server.Items if (UseSkillMod && m_AccuracyLevel != WeaponAccuracyLevel.Regular && parentMobile != null) { - m_SkillMod = new DefaultSkillMod(AccuracySkill, true, (int)m_AccuracyLevel * 5); + m_SkillMod = new DefaultSkillMod(AccuracySkill, "WeaponAccuracy", true, (int)m_AccuracyLevel * 5); parentMobile.AddSkillMod(m_SkillMod); } @@ -3956,7 +3956,7 @@ namespace Server.Items if (Core.AOS && WeaponAttributes.MageWeapon != 0 && WeaponAttributes.MageWeapon != 30 && parentMobile != null) { - m_MageMod = new DefaultSkillMod(SkillName.Magery, true, -30 + WeaponAttributes.MageWeapon); + m_MageMod = new DefaultSkillMod(SkillName.Magery, "MageWeapon", true, -30 + WeaponAttributes.MageWeapon); parentMobile.AddSkillMod(m_MageMod); } @@ -4111,7 +4111,7 @@ namespace Server.Items if (UseSkillMod && m_AccuracyLevel != WeaponAccuracyLevel.Regular && parentMobile != null) { - m_SkillMod = new DefaultSkillMod(AccuracySkill, true, (int)m_AccuracyLevel * 5); + m_SkillMod = new DefaultSkillMod(AccuracySkill, "WeaponAccuracy", true, (int)m_AccuracyLevel * 5); parentMobile.AddSkillMod(m_SkillMod); } diff --git a/Projects/UOContent/Misc/AOS.cs b/Projects/UOContent/Misc/AOS.cs index 18517ede7..92fa43fdc 100644 --- a/Projects/UOContent/Misc/AOS.cs +++ b/Projects/UOContent/Misc/AOS.cs @@ -590,21 +590,20 @@ namespace Server if (strBonus != 0 || dexBonus != 0 || intBonus != 0) { - var serial = Owner.Serial; - + var hashCode = GetHashCode(); if (strBonus != 0) { - to.AddStatMod(new StatMod(StatType.Str, $"{serial}Str", strBonus, TimeSpan.Zero)); + to.AddStatMod(new StatMod(StatType.Str, $"{hashCode}Str", strBonus, TimeSpan.Zero)); } if (dexBonus != 0) { - to.AddStatMod(new StatMod(StatType.Dex, $"{serial}Dex", dexBonus, TimeSpan.Zero)); + to.AddStatMod(new StatMod(StatType.Dex, $"{hashCode}Dex", dexBonus, TimeSpan.Zero)); } if (intBonus != 0) { - to.AddStatMod(new StatMod(StatType.Int, $"{serial}Int", intBonus, TimeSpan.Zero)); + to.AddStatMod(new StatMod(StatType.Int, $"{hashCode}Int", intBonus, TimeSpan.Zero)); } } @@ -1094,7 +1093,7 @@ namespace Server m_Mods ??= new HashSet(); - SkillMod sk = new DefaultSkillMod(skill, true, bonus); + SkillMod sk = new DefaultSkillMod(skill, $"{GetHashCode()}{skill}", true, bonus); sk.ObeyCap = true; m.AddSkillMod(sk); m_Mods.Add(sk); @@ -1346,10 +1345,10 @@ namespace Server public bool IsEmpty => _names == 0; - private Item _owner; + private IEntity _owner; [DirtyTrackingEntity] - public Item Owner => _owner; + public IEntity Owner => _owner; public int GetValue(int bitmask) { @@ -1483,23 +1482,30 @@ namespace Server } } - if (Owner?.Parent is Mobile m) + if (Owner is Item item) { - m.CheckStatTimers(); - m.UpdateResistances(); - m.Delta( - MobileDelta.Stat | MobileDelta.WeaponDamage | MobileDelta.Hits | MobileDelta.Stam | - MobileDelta.Mana - ); - - if (this is AosSkillBonuses) + if (item.Parent is Mobile m) { - ((AosSkillBonuses)this).Remove(); - ((AosSkillBonuses)this).AddTo(m); - } - } + m.CheckStatTimers(); + m.UpdateResistances(); + m.Delta( + MobileDelta.Stat | MobileDelta.WeaponDamage | MobileDelta.Hits | MobileDelta.Stam | + MobileDelta.Mana + ); - Owner?.InvalidateProperties(); + if (this is AosSkillBonuses skillBonuses) + { + skillBonuses.Remove(); + skillBonuses.AddTo(m); + } + } + + item.InvalidateProperties(); + } + else if (Owner is Mobile mob) + { + mob.InvalidateProperties(); + } } private int GetIndex(uint mask) diff --git a/Projects/UOContent/Mobiles/Abilities/GraspingClaw.cs b/Projects/UOContent/Mobiles/Abilities/GraspingClaw.cs index 8186de066..a1eccb911 100644 --- a/Projects/UOContent/Mobiles/Abilities/GraspingClaw.cs +++ b/Projects/UOContent/Mobiles/Abilities/GraspingClaw.cs @@ -44,7 +44,7 @@ public class GraspingClaw : MonsterAbility */ var effect = -(target.PhysicalResistance * 15 / 100); - var mod = new ResistanceMod(ResistanceType.Physical, effect); + var mod = new ResistanceMod(ResistanceType.Physical, "GraspingClaw", effect); target.FixedEffect(0x37B9, 10, 5); target.AddResistanceMod(mod); diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Bedlam/LadyJennifyr.cs b/Projects/UOContent/Mobiles/Monsters/ML/Bedlam/LadyJennifyr.cs index 6ebd6be98..5ea92aa3e 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Bedlam/LadyJennifyr.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Bedlam/LadyJennifyr.cs @@ -78,18 +78,17 @@ namespace Server.Mobiles return; } - if (m_Table.TryGetValue(defender, out var timer)) + if (m_Table.Remove(defender, out var timer)) { timer.DoExpire(); } defender.FixedParticles(0x3709, 10, 30, 5052, EffectLayer.LeftFoot); defender.PlaySound(0x208); - defender.SendLocalizedMessage( - 1070833 - ); // The creature fans you with fire, reducing your resistance to fire attacks. + // The creature fans you with fire, reducing your resistance to fire attacks. + defender.SendLocalizedMessage(1070833); - var mod = new ResistanceMod(ResistanceType.Fire, -10); + var mod = new ResistanceMod(ResistanceType.Fire, "FireResistFanningFire", -10); defender.AddResistanceMod(mod); m_Table[defender] = timer = new ExpireTimer(defender, mod); @@ -127,13 +126,13 @@ namespace Server.Mobiles m_Mobile.RemoveResistanceMod(m_Mod); Stop(); - m_Table.Remove(m_Mobile); } protected override void OnTick() { m_Mobile.SendLocalizedMessage(1070834); // Your resistance to fire attacks has returned. DoExpire(); + m_Table.Remove(m_Mobile); } } } diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Magic/Satyr.cs b/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Magic/Satyr.cs index c67242b21..98f2b9bf1 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Magic/Satyr.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Magic/Satyr.cs @@ -126,7 +126,7 @@ namespace Server.Mobiles { var s = target.Skills[i]; - target.AddSkillMod(new TimedSkillMod(s.SkillName, true, s.Base * -0.28, delay)); + target.AddSkillMod(new TimedSkillMod(s.SkillName, $"{s.Name}Satyr", true, s.Base * -0.28, delay)); } var count = (int)Math.Round(delay.TotalSeconds / 1.25); diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Twisted Weald/Swoop.cs b/Projects/UOContent/Mobiles/Monsters/ML/Twisted Weald/Swoop.cs index 60b16bbb0..67ec9b586 100644 --- a/Projects/UOContent/Mobiles/Monsters/ML/Twisted Weald/Swoop.cs +++ b/Projects/UOContent/Mobiles/Monsters/ML/Twisted Weald/Swoop.cs @@ -105,21 +105,20 @@ namespace Server.Mobiles return; } - if (m_Table.TryGetValue(defender, out var timer)) + if (m_Table.Remove(defender, out var timer)) { timer.DoExpire(); defender.SendLocalizedMessage(1070837); // The creature lands another blow in your weakened state. } else { - defender.SendLocalizedMessage( - 1070836 - ); // The blow from the creature's claws has made you more susceptible to physical attacks. + // The blow from the creature's claws has made you more susceptible to physical attacks. + defender.SendLocalizedMessage(1070836); } var effect = -(defender.PhysicalResistance * 15 / 100); - var mod = new ResistanceMod(ResistanceType.Physical, effect); + var mod = new ResistanceMod(ResistanceType.Physical, "PhysicalResistGraspingClaw", effect); defender.FixedEffect(0x37B9, 10, 5); defender.AddResistanceMod(mod); @@ -159,13 +158,13 @@ namespace Server.Mobiles { m_Mobile.RemoveResistanceMod(m_Mod); Stop(); - m_Table.Remove(m_Mobile); } protected override void OnTick() { m_Mobile.SendLocalizedMessage(1070838); // Your resistance to physical attacks has returned. DoExpire(); + m_Table.Remove(m_Mobile); } } } diff --git a/Projects/UOContent/Mobiles/Monsters/SE/FanDancer.cs b/Projects/UOContent/Mobiles/Monsters/SE/FanDancer.cs index 55d886efa..e272fac06 100644 --- a/Projects/UOContent/Mobiles/Monsters/SE/FanDancer.cs +++ b/Projects/UOContent/Mobiles/Monsters/SE/FanDancer.cs @@ -114,7 +114,7 @@ namespace Server.Mobiles { base.OnGaveMeleeAttack(defender, damage); - if (!IsFanned(defender) && Utility.RandomDouble() < 0.05) + if (m_Table.Add(defender) && Utility.RandomDouble() < 0.05) { /* Fanning Fire * Graphic: Type: "3" From: "0x57D4F5B" To: "0x0" ItemId: "0x3709" ItemIdName: "fire column" FromLocation: "(994 325, 16)" ToLocation: "(994 325, 16)" Speed: "10" Duration: "30" FixedDirection: "True" Explode: "False" Hue: "0x0" RenderMode: "0x0" Effect: "0x34" ExplodeEffect: "0x1" ExplodeSound: "0x0" Serial: "0x57D4F5B" Layer: "5" Unknown: "0x0" @@ -131,7 +131,7 @@ namespace Server.Mobiles var effect = -(defender.FireResistance / 10); - var mod = new ResistanceMod(ResistanceType.Fire, effect); + var mod = new ResistanceMod(ResistanceType.Fire, "FireResistFanningFire", effect); defender.FixedParticles(0x37B9, 10, 30, 0x34, EffectLayer.RightFoot); defender.PlaySound(0x208); @@ -143,11 +143,10 @@ namespace Server.Mobiles var timer = new ExpireTimer(defender, mod, TimeSpan.FromSeconds(10.0)); timer.Start(); - m_Table.Add(defender); } } - public bool IsFanned(Mobile m) => m_Table.Contains(m); + public static bool IsFanned(Mobile m) => m_Table.Contains(m); public override void Serialize(IGenericWriter writer) { diff --git a/Projects/UOContent/Mobiles/Monsters/SE/KazeKemono.cs b/Projects/UOContent/Mobiles/Monsters/SE/KazeKemono.cs index 15361db1f..ad32ec370 100644 --- a/Projects/UOContent/Mobiles/Monsters/SE/KazeKemono.cs +++ b/Projects/UOContent/Mobiles/Monsters/SE/KazeKemono.cs @@ -72,21 +72,20 @@ namespace Server.Mobiles * Effect: Type: "3" From: "0x57D4F5B" To: "0x0" ItemId: "0x37B9" ItemIdName: "glow" FromLocation: "(1048 779, 6)" ToLocation: "(1048 779, 6)" Speed: "10" Duration: "5" FixedDirection: "True" Explode: "False" */ - if (m_FlurryOfTwigsTable.TryGetValue(defender, out var timer)) + if (m_FlurryOfTwigsTable.Remove(defender, out var timer)) { timer.DoExpire(); defender.SendLocalizedMessage(1070851); // The creature lands another blow in your weakened state. } else { - defender.SendLocalizedMessage( - 1070850 - ); // The creature's flurry of twigs has made you more susceptible to physical attacks! + // The creature's flurry of twigs has made you more susceptible to physical attacks! + defender.SendLocalizedMessage(1070850); } var effect = -(defender.PhysicalResistance * 15 / 100); - var mod = new ResistanceMod(ResistanceType.Physical, effect); + var mod = new ResistanceMod(ResistanceType.Physical, "PhysicalResistFlurryOfTwigs", effect); defender.FixedEffect(0x37B9, 10, 5); defender.AddResistanceMod(mod); @@ -99,7 +98,7 @@ namespace Server.Mobiles if (Utility.RandomDouble() < 0.05) { - /* Chlorophyl Blast + /* Chlorophyll Blast * Start cliloc: 1070827 * Effect: Energy resistance -50% for 10 seconds * End cliloc: 1070829 @@ -113,14 +112,13 @@ namespace Server.Mobiles } else { - defender.SendLocalizedMessage( - 1070827 - ); // The creature's attack has made you more susceptible to energy attacks! + // The creature's attack has made you more susceptible to energy attacks! + defender.SendLocalizedMessage(1070827); } var effect = -(defender.EnergyResistance / 2); - var mod = new ResistanceMod(ResistanceType.Energy, effect); + var mod = new ResistanceMod(ResistanceType.Energy, "EnergyResistChlorophyllBlast", effect); defender.FixedEffect(0x37B9, 10, 5); defender.AddResistanceMod(mod); @@ -161,7 +159,6 @@ namespace Server.Mobiles { m_Mobile.RemoveResistanceMod(m_Mod); Stop(); - m_Table.Remove(m_Mobile); } protected override void OnTick() @@ -176,6 +173,7 @@ namespace Server.Mobiles } DoExpire(); + m_Table.Remove(m_Mobile); } } } diff --git a/Projects/UOContent/Mobiles/Monsters/SE/RuneBeetle.cs b/Projects/UOContent/Mobiles/Monsters/SE/RuneBeetle.cs index 0dfc427e6..cc130977f 100644 --- a/Projects/UOContent/Mobiles/Monsters/SE/RuneBeetle.cs +++ b/Projects/UOContent/Mobiles/Monsters/SE/RuneBeetle.cs @@ -110,7 +110,7 @@ namespace Server.Mobiles * End ASCII: "The corruption of your armor has worn off" */ - if (m_Table.TryGetValue(defender, out var timer)) + if (m_Table.Remove(defender, out var timer)) { timer.DoExpire(); defender.SendLocalizedMessage(1070845); // The creature continues to corrupt your armor! @@ -120,42 +120,59 @@ namespace Server.Mobiles defender.SendLocalizedMessage(1070846); // The creature magically corrupts your armor! } - var mods = new List(); - if (Core.ML) { if (defender.PhysicalResistance > 0) { - mods.Add(new ResistanceMod(ResistanceType.Physical, -(defender.PhysicalResistance / 2))); + defender.AddResistanceMod( + new ResistanceMod( + ResistanceType.Physical, + "RuneCorruption", + -(defender.PhysicalResistance / 2) + ) + ); } if (defender.FireResistance > 0) { - mods.Add(new ResistanceMod(ResistanceType.Fire, -(defender.FireResistance / 2))); + defender.AddResistanceMod(new ResistanceMod(ResistanceType.Fire, "RuneCorruption", -(defender.FireResistance / 2))); } if (defender.ColdResistance > 0) { - mods.Add(new ResistanceMod(ResistanceType.Cold, -(defender.ColdResistance / 2))); + defender.AddResistanceMod(new ResistanceMod(ResistanceType.Cold, "RuneCorruption", -(defender.ColdResistance / 2))); } if (defender.PoisonResistance > 0) { - mods.Add(new ResistanceMod(ResistanceType.Poison, -(defender.PoisonResistance / 2))); + defender.AddResistanceMod( + new ResistanceMod( + ResistanceType.Poison, + "RuneCorruption", + -(defender.PoisonResistance / 2) + ) + ); } if (defender.EnergyResistance > 0) { - mods.Add(new ResistanceMod(ResistanceType.Energy, -(defender.EnergyResistance / 2))); + defender.AddResistanceMod( + new ResistanceMod( + ResistanceType.Energy, + "RuneCorruption", + -(defender.EnergyResistance / 2) + ) + ); } } else { if (defender.PhysicalResistance > 0) { - mods.Add( + defender.AddResistanceMod( new ResistanceMod( ResistanceType.Physical, + "RuneCorruption", defender.PhysicalResistance > 70 ? -70 : -defender.PhysicalResistance ) ); @@ -163,9 +180,10 @@ namespace Server.Mobiles if (defender.FireResistance > 0) { - mods.Add( + defender.AddResistanceMod( new ResistanceMod( ResistanceType.Fire, + "RuneCorruption", defender.FireResistance > 70 ? -70 : -defender.FireResistance ) ); @@ -173,9 +191,10 @@ namespace Server.Mobiles if (defender.ColdResistance > 0) { - mods.Add( + defender.AddResistanceMod( new ResistanceMod( ResistanceType.Cold, + "RuneCorruption", defender.ColdResistance > 70 ? -70 : -defender.ColdResistance ) ); @@ -183,9 +202,10 @@ namespace Server.Mobiles if (defender.PoisonResistance > 0) { - mods.Add( + defender.AddResistanceMod( new ResistanceMod( ResistanceType.Poison, + "RuneCorruption", defender.PoisonResistance > 70 ? -70 : -defender.PoisonResistance ) ); @@ -193,23 +213,19 @@ namespace Server.Mobiles if (defender.EnergyResistance > 0) { - mods.Add( + defender.AddResistanceMod( new ResistanceMod( ResistanceType.Energy, + "RuneCorruption", defender.EnergyResistance > 70 ? -70 : -defender.EnergyResistance ) ); } } - for (var i = 0; i < mods.Count; ++i) - { - defender.AddResistanceMod(mods[i]); - } - defender.FixedEffect(0x37B9, 10, 5); - timer = new ExpireTimer(defender, mods, TimeSpan.FromSeconds(5.0)); + timer = new ExpireTimer(defender, TimeSpan.FromSeconds(5.0)); timer.Start(); m_Table[defender] = timer; } @@ -229,11 +245,12 @@ namespace Server.Mobiles { for (var i = 0; i < Skills.Length; ++i) { - Skills[i].Cap = Math.Max(100.0, Skills[i].Cap * 0.9); + var skill = Skills[i]; + skill.Cap = Math.Max(100.0, skill.Cap * 0.9); - if (Skills[i].Base > Skills[i].Cap) + if (skill.Base > skill.Cap) { - Skills[i].Base = Skills[i].Cap; + skill.Base = skill.Cap; } } } @@ -242,29 +259,20 @@ namespace Server.Mobiles private class ExpireTimer : Timer { private readonly Mobile m_Mobile; - private readonly List m_Mods; - public ExpireTimer(Mobile m, List mods, TimeSpan delay) : base(delay) - { - m_Mobile = m; - m_Mods = mods; - } + public ExpireTimer(Mobile m, TimeSpan delay) : base(delay) => m_Mobile = m; public void DoExpire() { - for (var i = 0; i < m_Mods.Count; ++i) - { - m_Mobile.RemoveResistanceMod(m_Mods[i]); - } - + m_Mobile.RemoveResistanceMod("RuneCorruption"); Stop(); - m_Table.Remove(m_Mobile); } protected override void OnTick() { m_Mobile.SendMessage("The corruption of your armor has worn off"); DoExpire(); + m_Table.Remove(m_Mobile); } } } diff --git a/Projects/UOContent/Skills/Discordance.cs b/Projects/UOContent/Skills/Discordance.cs index b4feb9288..15b7ed118 100644 --- a/Projects/UOContent/Skills/Discordance.cs +++ b/Projects/UOContent/Skills/Discordance.cs @@ -95,63 +95,24 @@ namespace Server.SkillHandlers public readonly Mobile m_Creature; public readonly int m_Effect; public readonly Mobile m_From; - public readonly List m_Mods; public bool m_Ending; public DateTime m_EndTime; public TimerExecutionToken _timerToken; - public DiscordanceInfo(Mobile from, Mobile creature, int effect, List mods) + public DiscordanceInfo(Mobile from, Mobile creature, int effect) { m_From = from; m_Creature = creature; m_EndTime = Core.Now; m_Ending = false; m_Effect = effect; - m_Mods = mods; - - Apply(); - } - - public void Apply() - { - for (var i = 0; i < m_Mods.Count; ++i) - { - var mod = m_Mods[i]; - - if (mod is ResistanceMod resistanceMod) - { - m_Creature.AddResistanceMod(resistanceMod); - } - else if (mod is StatMod statMod) - { - m_Creature.AddStatMod(statMod); - } - else if (mod is SkillMod skillMod) - { - m_Creature.AddSkillMod(skillMod); - } - } } public void Clear() { - for (var i = 0; i < m_Mods.Count; ++i) - { - var mod = m_Mods[i]; - - if (mod is ResistanceMod resistanceMod) - { - m_Creature.RemoveResistanceMod(resistanceMod); - } - else if (mod is StatMod statMod) - { - m_Creature.RemoveStatMod(statMod.Name); - } - else if (mod is SkillMod skillMod) - { - m_Creature.RemoveSkillMod(skillMod); - } - } + m_Creature.RemoveResistanceMod("Discordance"); + m_Creature.RemoveStatMod("Discordance"); + m_Creature.RemoveSkillMod("Discordance"); } } @@ -163,8 +124,7 @@ namespace Server.SkillHandlers BaseInstrument.GetBardRange(from, SkillName.Discordance), false, TargetFlags.None - ) => - m_Instrument = inst; + ) => m_Instrument = inst; protected override void OnTarget(Mobile from, object target) { @@ -211,7 +171,6 @@ namespace Server.SkillHandlers m_Instrument.PlayInstrumentWell(from); m_Instrument.ConsumeUse(from); - var mods = new List(); int effect; double scalar; @@ -235,60 +194,53 @@ namespace Server.SkillHandlers scalar = effect * 0.01; - mods.Add(new ResistanceMod(ResistanceType.Physical, effect)); - mods.Add(new ResistanceMod(ResistanceType.Fire, effect)); - mods.Add(new ResistanceMod(ResistanceType.Cold, effect)); - mods.Add(new ResistanceMod(ResistanceType.Poison, effect)); - mods.Add(new ResistanceMod(ResistanceType.Energy, effect)); - - for (var i = 0; i < targ.Skills.Length; ++i) - { - if (targ.Skills[i].Value > 0) - { - mods.Add(new DefaultSkillMod((SkillName)i, true, targ.Skills[i].Value * scalar)); - } - } + targ.AddResistanceMod(new ResistanceMod(ResistanceType.Physical, "Discordance", effect)); + targ.AddResistanceMod(new ResistanceMod(ResistanceType.Fire, "Discordance", effect)); + targ.AddResistanceMod(new ResistanceMod(ResistanceType.Cold, "Discordance", effect)); + targ.AddResistanceMod(new ResistanceMod(ResistanceType.Poison, "Discordance", effect)); + targ.AddResistanceMod(new ResistanceMod(ResistanceType.Energy, "Discordance", effect)); } else { effect = (int)(from.Skills.Discordance.Value / -5.0); scalar = effect * 0.01; - mods.Add( + targ.AddStatMod( new StatMod( StatType.Str, - "DiscordanceStr", + "Discordance", (int)(targ.RawStr * scalar), TimeSpan.Zero ) ); - mods.Add( + targ.AddStatMod( new StatMod( StatType.Int, - "DiscordanceInt", + "Discordance", (int)(targ.RawInt * scalar), TimeSpan.Zero ) ); - mods.Add( + targ.AddStatMod( new StatMod( StatType.Dex, - "DiscordanceDex", + "Discordance", (int)(targ.RawDex * scalar), TimeSpan.Zero ) ); + } - for (var i = 0; i < targ.Skills.Length; ++i) + for (var i = 0; i < targ.Skills.Length; ++i) + { + var skill = targ.Skills[i]; + if (skill.Value > 0) { - if (targ.Skills[i].Value > 0) - { - mods.Add(new DefaultSkillMod((SkillName)i, true, targ.Skills[i].Value * scalar)); - } + targ.AddSkillMod(new DefaultSkillMod(skill.SkillName, "Discordance", true, skill.Value * scalar)); } } - var info = new DiscordanceInfo(from, targ, effect.Abs(), mods); + var info = new DiscordanceInfo(from, targ, effect.Abs()); Timer.StartTimer( TimeSpan.Zero, TimeSpan.FromSeconds(1.25), diff --git a/Projects/UOContent/Spells/Base/SpellHelper.cs b/Projects/UOContent/Spells/Base/SpellHelper.cs index 2d701e78d..a41137627 100644 --- a/Projects/UOContent/Spells/Base/SpellHelper.cs +++ b/Projects/UOContent/Spells/Base/SpellHelper.cs @@ -1242,31 +1242,29 @@ namespace Server.Spells if (!ourTransform) { - var mods = new List(); - if (transformSpell.PhysResistOffset != 0) { - mods.Add(new ResistanceMod(ResistanceType.Physical, transformSpell.PhysResistOffset)); + caster.AddResistanceMod(new ResistanceMod(ResistanceType.Physical, "TransformSpell", transformSpell.PhysResistOffset)); } if (transformSpell.FireResistOffset != 0) { - mods.Add(new ResistanceMod(ResistanceType.Fire, transformSpell.FireResistOffset)); + caster.AddResistanceMod(new ResistanceMod(ResistanceType.Fire, "TransformSpell", transformSpell.FireResistOffset)); } if (transformSpell.ColdResistOffset != 0) { - mods.Add(new ResistanceMod(ResistanceType.Cold, transformSpell.ColdResistOffset)); + caster.AddResistanceMod(new ResistanceMod(ResistanceType.Cold, "TransformSpell", transformSpell.ColdResistOffset)); } if (transformSpell.PoisResistOffset != 0) { - mods.Add(new ResistanceMod(ResistanceType.Poison, transformSpell.PoisResistOffset)); + caster.AddResistanceMod(new ResistanceMod(ResistanceType.Poison, "TransformSpell", transformSpell.PoisResistOffset)); } if (transformSpell.NrgyResistOffset != 0) { - mods.Add(new ResistanceMod(ResistanceType.Energy, transformSpell.NrgyResistOffset)); + caster.AddResistanceMod(new ResistanceMod(ResistanceType.Energy, "TransformSpell", transformSpell.NrgyResistOffset)); } if (!((Body)transformSpell.Body).IsHuman) @@ -1282,17 +1280,12 @@ namespace Server.Spells caster.BodyMod = transformSpell.Body; caster.HueMod = transformSpell.Hue; - for (var i = 0; i < mods.Count; ++i) - { - caster.AddResistanceMod(mods[i]); - } - transformSpell.DoEffect(caster); Timer timer = new TransformTimer(caster, transformSpell); timer.Start(); - AddContext(caster, new TransformContext(timer, mods, ourType, transformSpell)); + AddContext(caster, new TransformContext(timer, ourType, transformSpell)); return true; } } @@ -1322,12 +1315,7 @@ namespace Server.Spells return; } - var mods = context.Mods; - - for (var i = 0; i < mods.Count; ++i) - { - m.RemoveResistanceMod(mods[i]); - } + m.RemoveResistanceMod("TransformSpell"); if (resetGraphics) { @@ -1371,18 +1359,15 @@ namespace Server.Spells public class TransformContext { - public TransformContext(Timer timer, List mods, Type type, ITransformationSpell spell) + public TransformContext(Timer timer, Type type, ITransformationSpell spell) { Timer = timer; - Mods = mods; Type = type; Spell = spell; } public Timer Timer { get; } - public List Mods { get; } - public Type Type { get; } public ITransformationSpell Spell { get; } diff --git a/Projects/UOContent/Spells/Bushido/HonorableExecution.cs b/Projects/UOContent/Spells/Bushido/HonorableExecution.cs index 266644850..4d00260bd 100644 --- a/Projects/UOContent/Spells/Bushido/HonorableExecution.cs +++ b/Projects/UOContent/Spells/Bushido/HonorableExecution.cs @@ -46,18 +46,18 @@ namespace Server.Spells.Bushido { var mods = new List { - new ResistanceMod(ResistanceType.Physical, -40), - new ResistanceMod(ResistanceType.Fire, -40), - new ResistanceMod(ResistanceType.Cold, -40), - new ResistanceMod(ResistanceType.Poison, -40), - new ResistanceMod(ResistanceType.Energy, -40) + new ResistanceMod(ResistanceType.Physical, "PhysicalResistHonorableExecution", -40), + new ResistanceMod(ResistanceType.Fire, "FireResistHonorableExecution", -40), + new ResistanceMod(ResistanceType.Cold, "ColdResistHonorableExecution", -40), + new ResistanceMod(ResistanceType.Poison, "PoisonResistHonorableExecution", -40), + new ResistanceMod(ResistanceType.Energy, "EnergyResistHonorableExecution", -40) }; var resSpells = attacker.Skills.MagicResist.Value; if (resSpells > 0.0) { - mods.Add(new DefaultSkillMod(SkillName.MagicResist, true, -resSpells)); + mods.Add(new DefaultSkillMod(SkillName.MagicResist, "MagicResistHonorableExecution", true, -resSpells)); } timer = new HonorableExecutionTimer(attacker, mods); diff --git a/Projects/UOContent/Spells/Fifth/MagicReflect.cs b/Projects/UOContent/Spells/Fifth/MagicReflect.cs index ca1e0256e..970da9101 100644 --- a/Projects/UOContent/Spells/Fifth/MagicReflect.cs +++ b/Projects/UOContent/Spells/Fifth/MagicReflect.cs @@ -78,15 +78,15 @@ namespace Server.Spells.Fifth targ.FixedParticles(0x375A, 10, 15, 5037, EffectLayer.Waist); var physiMod = -25 + (int)(targ.Skills.Inscribe.Value / 20); - var otherMod = 10; + const int otherMod = 10; mods = new[] { - new ResistanceMod(ResistanceType.Physical, physiMod), - new ResistanceMod(ResistanceType.Fire, otherMod), - new ResistanceMod(ResistanceType.Cold, otherMod), - new ResistanceMod(ResistanceType.Poison, otherMod), - new ResistanceMod(ResistanceType.Energy, otherMod) + new ResistanceMod(ResistanceType.Physical, "PhysicalResistMagicResist", physiMod), + new ResistanceMod(ResistanceType.Fire, "FireResistMagicResist", otherMod), + new ResistanceMod(ResistanceType.Cold, "ColdResistMagicResist", otherMod), + new ResistanceMod(ResistanceType.Poison, "PoisonResistMagicResist", otherMod), + new ResistanceMod(ResistanceType.Energy, "EnergyResistMagicResist", otherMod) }; _table[targ] = mods; diff --git a/Projects/UOContent/Spells/First/ReactiveArmor.cs b/Projects/UOContent/Spells/First/ReactiveArmor.cs index 168ba4b81..eee49802a 100644 --- a/Projects/UOContent/Spells/First/ReactiveArmor.cs +++ b/Projects/UOContent/Spells/First/ReactiveArmor.cs @@ -83,12 +83,13 @@ namespace Server.Spells.First { new ResistanceMod( ResistanceType.Physical, + "PhysicalResistReactiveArmorSpell", 15 + (int)(targ.Skills.Inscribe.Value / 20) ), - new ResistanceMod(ResistanceType.Fire, -5), - new ResistanceMod(ResistanceType.Cold, -5), - new ResistanceMod(ResistanceType.Poison, -5), - new ResistanceMod(ResistanceType.Energy, -5) + new ResistanceMod(ResistanceType.Fire, "FireResistReactiveArmorSpell", -5), + new ResistanceMod(ResistanceType.Cold, "ColdResistReactiveArmorSpell", -5), + new ResistanceMod(ResistanceType.Poison, "PoisonResistReactiveArmorSpell", -5), + new ResistanceMod(ResistanceType.Energy, "EnergyResistReactiveArmorSpell", -5) }; _table[targ] = mods; diff --git a/Projects/UOContent/Spells/Mysticism/StoneFormSpell.cs b/Projects/UOContent/Spells/Mysticism/StoneFormSpell.cs index fbd83c4b1..3648abb85 100644 --- a/Projects/UOContent/Spells/Mysticism/StoneFormSpell.cs +++ b/Projects/UOContent/Spells/Mysticism/StoneFormSpell.cs @@ -101,11 +101,11 @@ namespace Server.Spells.Mysticism ResistanceMod[] mods = { - new(ResistanceType.Physical, offset), - new(ResistanceType.Fire, offset), - new(ResistanceType.Cold, offset), - new(ResistanceType.Poison, offset), - new(ResistanceType.Energy, offset) + new(ResistanceType.Physical, "PhysicalResistStoneFormSpell", offset), + new(ResistanceType.Fire, "FireResistStoneFormSpell", offset), + new(ResistanceType.Cold, "ColdResistStoneFormSpell", offset), + new(ResistanceType.Poison, "PoisonResistStoneFormSpell", offset), + new(ResistanceType.Energy, "EnergyResistStoneFormSpell", offset) }; for (var i = 0; i < mods.Length; ++i) diff --git a/Projects/UOContent/Spells/Necromancy/CorpseSkin.cs b/Projects/UOContent/Spells/Necromancy/CorpseSkin.cs index 1ca3874c1..19ed3ba8b 100644 --- a/Projects/UOContent/Spells/Necromancy/CorpseSkin.cs +++ b/Projects/UOContent/Spells/Necromancy/CorpseSkin.cs @@ -71,10 +71,10 @@ namespace Server.Spells.Necromancy ResistanceMod[] mods = { - new(ResistanceType.Fire, -15), - new(ResistanceType.Poison, -15), - new(ResistanceType.Cold, +10), - new(ResistanceType.Physical, +10) + new(ResistanceType.Fire, "FireResistCorpseSkinSpell", -15), + new(ResistanceType.Poison, "PoisonResistCorpseSkinSpell", -15), + new(ResistanceType.Cold, "ColdResistCorpseSkinSpell", +10), + new(ResistanceType.Physical, "PhysicalResistCorpseSkinSpell", +10) }; timer = new ExpireTimer(m, mods, duration); diff --git a/Projects/UOContent/Spells/Necromancy/EvilOmen.cs b/Projects/UOContent/Spells/Necromancy/EvilOmen.cs index 44e77800f..4b213fad8 100644 --- a/Projects/UOContent/Spells/Necromancy/EvilOmen.cs +++ b/Projects/UOContent/Spells/Necromancy/EvilOmen.cs @@ -53,7 +53,7 @@ namespace Server.Spells.Necromancy if (!_table.ContainsKey(m)) { - var mod = new DefaultSkillMod(SkillName.MagicResist, false, m.Skills.MagicResist.Value / 2); + var mod = new DefaultSkillMod(SkillName.MagicResist, "EvilOmen", false, m.Skills.MagicResist.Value / 2); m.AddSkillMod(mod); _table[m] = mod; } diff --git a/Projects/UOContent/Spells/Ninjitsu/AnimalForm.cs b/Projects/UOContent/Spells/Ninjitsu/AnimalForm.cs index f68c03934..432fb8a28 100644 --- a/Projects/UOContent/Spells/Ninjitsu/AnimalForm.cs +++ b/Projects/UOContent/Spells/Ninjitsu/AnimalForm.cs @@ -237,11 +237,12 @@ namespace Server.Spells.Ninjitsu m.NetState.SendSpeedControl(SpeedControlSetting.Mount); } + // TODO: Determine if transform spell skill mods to a generic location like stat mods SkillMod mod = null; if (entry.StealthBonus) { - mod = new DefaultSkillMod(SkillName.Stealth, true, 20.0) { ObeyCap = true }; + mod = new DefaultSkillMod(SkillName.Stealth, "StealthAnimalForm", true, 20.0) { ObeyCap = true }; m.AddSkillMod(mod); } @@ -249,7 +250,7 @@ namespace Server.Spells.Ninjitsu if (entry.StealingBonus) { - stealingMod = new DefaultSkillMod(SkillName.Stealing, true, 10.0) { ObeyCap = true }; + stealingMod = new DefaultSkillMod(SkillName.Stealing, "StealingAnimalForm", true, 10.0) { ObeyCap = true }; m.AddSkillMod(stealingMod); } diff --git a/Projects/UOContent/Spells/Second/Protection.cs b/Projects/UOContent/Spells/Second/Protection.cs index 3e76b0a97..35fd04b97 100644 --- a/Projects/UOContent/Spells/Second/Protection.cs +++ b/Projects/UOContent/Spells/Second/Protection.cs @@ -79,8 +79,8 @@ namespace Server.Spells.Second var physLoss = -15 + (int)(caster.Skills.Inscribe.Value / 20); var resistLoss = -35 + (int)(caster.Skills.Inscribe.Value / 20); - var physMod = new ResistanceMod(ResistanceType.Physical, physLoss); - var resistMod = new DefaultSkillMod(SkillName.MagicResist, true, resistLoss); + var physMod = new ResistanceMod(ResistanceType.Physical, "PhysicalResistProtectionSpell", physLoss); + var resistMod = new DefaultSkillMod(SkillName.MagicResist, "MagicResistProtectionSpell", true, resistLoss); _table[target] = Tuple.Create(physMod, resistMod); Registry[target] = 1000; // 100.0% protection from disruption