From d5160bd6db4932610bd91801671d4b4596a1ac36 Mon Sep 17 00:00:00 2001 From: mark1145 Date: Sat, 25 Jan 2025 13:20:23 +1100 Subject: [PATCH] fix: Fixes buffs don't start/stop properly. Streamlines constructor and Add/Remove buffs. (#2082) --- .../Network/Packets/BuffIconPacketTests.cs | 29 +- .../Tests/Network/Packets/BuffIconPackets.cs | 5 +- .../UOContent/Engines/BuffIcons/BuffIcon.cs | 192 ++++++++++ .../BuffIcons}/BuffIconPackets.cs | 3 +- .../UOContent/Engines/BuffIcons/BuffInfo.cs | 66 ++++ .../Magical/Potions/InvisibilityPotion.cs | 9 +- .../UOContent/Items/Talismans/BaseTalisman.cs | 237 +++++++------ .../Items/Weapons/Abilities/Disarm.cs | 4 +- .../Items/Weapons/Abilities/ForceArrow.cs | 13 +- .../Items/Weapons/Abilities/PsychicAttack.cs | 16 +- Projects/UOContent/Misc/BuffIcons.cs | 335 ------------------ Projects/UOContent/Misc/LightCycle.cs | 3 +- Projects/UOContent/Mobiles/PlayerMobile.cs | 49 +-- Projects/UOContent/Skills/Meditation.cs | 4 +- .../UOContent/Spells/Bushido/Confidence.cs | 18 +- .../Spells/Bushido/HonorableExecution.cs | 15 +- .../UOContent/Spells/Chivalry/DivineFury.cs | 13 +- .../UOContent/Spells/Chivalry/EnemyOfOne.cs | 6 +- .../Spells/Chivalry/NobleSacrifice.cs | 20 +- .../UOContent/Spells/Chivalry/RemoveCurse.cs | 22 +- Projects/UOContent/Spells/Fifth/Incognito.cs | 5 +- .../UOContent/Spells/Fifth/MagicReflect.cs | 9 +- Projects/UOContent/Spells/First/Clumsy.cs | 4 +- Projects/UOContent/Spells/First/Feeblemind.cs | 4 +- Projects/UOContent/Spells/First/NightSight.cs | 4 +- .../UOContent/Spells/First/ReactiveArmor.cs | 7 +- Projects/UOContent/Spells/First/Weaken.cs | 4 +- Projects/UOContent/Spells/Fourth/Curse.cs | 4 +- .../Gargoyle/SpellDefinitions/FlySpell.cs | 5 +- .../Spells/Mysticism/CleansingWindsSpell.cs | 23 +- .../Spells/Mysticism/SpellPlagueSpell.cs | 10 +- .../Spells/Mysticism/StoneFormSpell.cs | 9 +- .../Spells/Necromancy/BloodOathSpell.cs | 9 +- .../UOContent/Spells/Necromancy/CorpseSkin.cs | 6 +- .../UOContent/Spells/Necromancy/EvilOmen.cs | 3 +- .../UOContent/Spells/Necromancy/MindRot.cs | 6 +- .../UOContent/Spells/Necromancy/PainSpike.cs | 6 +- .../UOContent/Spells/Necromancy/Strangle.cs | 4 +- Projects/UOContent/Spells/Second/Agility.cs | 4 +- Projects/UOContent/Spells/Second/Cunning.cs | 4 +- .../UOContent/Spells/Second/Protection.cs | 7 +- Projects/UOContent/Spells/Second/Strength.cs | 4 +- .../UOContent/Spells/Sixth/Invisibility.cs | 8 +- .../Spells/Spellweaving/AttuneWeapon.cs | 9 +- .../Spells/Spellweaving/EssenceOfWind.cs | 9 +- .../Spells/Spellweaving/EtherealVoyage.cs | 6 +- .../Spells/Spellweaving/GiftOfLife.cs | 7 +- .../Spells/Spellweaving/GiftOfRenewal.cs | 15 +- .../Spells/Spellweaving/Thunderstorm.cs | 9 +- Projects/UOContent/Spells/Third/Bless.cs | 4 +- 50 files changed, 651 insertions(+), 616 deletions(-) create mode 100644 Projects/UOContent/Engines/BuffIcons/BuffIcon.cs rename Projects/UOContent/{Network => Engines/BuffIcons}/BuffIconPackets.cs (97%) create mode 100644 Projects/UOContent/Engines/BuffIcons/BuffInfo.cs delete mode 100644 Projects/UOContent/Misc/BuffIcons.cs diff --git a/Projects/UOContent.Tests/Tests/Network/Packets/BuffIconPacketTests.cs b/Projects/UOContent.Tests/Tests/Network/Packets/BuffIconPacketTests.cs index 71aa2fa10..1d31aa4e9 100644 --- a/Projects/UOContent.Tests/Tests/Network/Packets/BuffIconPacketTests.cs +++ b/Projects/UOContent.Tests/Tests/Network/Packets/BuffIconPacketTests.cs @@ -1,5 +1,6 @@ using System; using Server; +using Server.Engines.BuffIcons; using Server.Network; using Server.Tests; using Server.Tests.Network; @@ -14,29 +15,29 @@ public class BuffIconPacketTests [InlineData(0x2048u, BuffIcon.Disguised, 500102, 300203, null, 9000)] public void TestAddBuffIcon(uint mob, BuffIcon iconID, int titleCliloc, int secondaryCliloc, string args, int ts) { - var timeSpan = new TimeSpan(ts); - var expected = new AddBuffPacket( - (Serial)mob, iconID, titleCliloc, secondaryCliloc, args, timeSpan - ).Compile(); + var timeSpan = new TimeSpan(ts); + var expected = new AddBuffPacket( + (Serial)mob, iconID, titleCliloc, secondaryCliloc, args, timeSpan + ).Compile(); - var ns = PacketTestUtilities.CreateTestNetState(); - ns.SendAddBuffPacket((Serial)mob, iconID, titleCliloc, secondaryCliloc, args, (int)timeSpan.TotalMilliseconds); + var ns = PacketTestUtilities.CreateTestNetState(); + ns.SendAddBuffPacket((Serial)mob, iconID, titleCliloc, secondaryCliloc, args, (int)timeSpan.TotalMilliseconds); var result = ns.SendPipe.Reader.AvailableToRead(); AssertThat.Equal(result, expected); - } + } [Fact] public void TestRemoveBuffIcon() { - Serial m = (Serial)0x1024; - var buffIcon = BuffIcon.Disguised; - var expected = new RemoveBuffPacket(m, buffIcon).Compile(); + Serial m = (Serial)0x1024; + var buffIcon = BuffIcon.Disguised; + var expected = new RemoveBuffPacket(m, buffIcon).Compile(); - var ns = PacketTestUtilities.CreateTestNetState(); - ns.SendRemoveBuffPacket(m, buffIcon); + var ns = PacketTestUtilities.CreateTestNetState(); + ns.SendRemoveBuffPacket(m, buffIcon); var result = ns.SendPipe.Reader.AvailableToRead(); AssertThat.Equal(result, expected); - } -} \ No newline at end of file + } +} diff --git a/Projects/UOContent.Tests/Tests/Network/Packets/BuffIconPackets.cs b/Projects/UOContent.Tests/Tests/Network/Packets/BuffIconPackets.cs index 208d15207..9910ffaa7 100644 --- a/Projects/UOContent.Tests/Tests/Network/Packets/BuffIconPackets.cs +++ b/Projects/UOContent.Tests/Tests/Network/Packets/BuffIconPackets.cs @@ -1,4 +1,5 @@ using System; +using Server.Engines.BuffIcons; namespace Server.Network { @@ -11,9 +12,7 @@ namespace Server.Network info.TitleCliloc, info.SecondaryCliloc, info.Args, - info.TimeStart != 0 ? - TimeSpan.FromMilliseconds(info.TimeStart + (long)info.TimeLength.TotalMilliseconds - Core.TickCount) : - TimeSpan.Zero + info.Duration ) { } diff --git a/Projects/UOContent/Engines/BuffIcons/BuffIcon.cs b/Projects/UOContent/Engines/BuffIcons/BuffIcon.cs new file mode 100644 index 000000000..6ddb44ae5 --- /dev/null +++ b/Projects/UOContent/Engines/BuffIcons/BuffIcon.cs @@ -0,0 +1,192 @@ +namespace Server.Engines.BuffIcons; + +public enum BuffIcon : short +{ + DismountPrevention = 0x3E9, + NoRearm = 0x3EA, + //Currently, no 0x3EB or 0x3EC + NightSight = 0x3ED, //* + DeathStrike, + EvilOmen, + HonoredDebuff, + AchievePerfection, + DivineFury, //* + EnemyOfOne, //* + HidingAndOrStealth, //* + ActiveMeditation, //* + BloodOathCaster, //* + BloodOathCurse, //* + CorpseSkin, //* + Mindrot, //* + PainSpike, //* + Strangle, + GiftOfRenewal, //* + AttuneWeapon, //* + Thunderstorm, //* + EssenceOfWind, //* + EtherealVoyage, //* + GiftOfLife, //* + ArcaneEmpowerment, //* + MortalStrike, + ReactiveArmor, //* + Protection, //* + ArchProtection, + MagicReflection, //* + Incognito, //* + Disguised, + AnimalForm, + Polymorph, + Invisibility, //* + Paralyze, //* + Poison, + Bleed, + Clumsy, //* + FeebleMind, //* + Weaken, //* + Curse, //* + MassCurse, + Agility, //* + Cunning, //* + Strength, //* + Bless, //* + Sleep, + StoneForm, + SpellPlague, + Berserk, + MassSleep, + Fly, + Inspire, + Invigorate, + Resilience, + Perseverance, + TribulationTarget, + DespairTarget, + FishPie = 0x426, + HitLowerAttack, + HitLowerDefense, + DualWield, + Block, + DefenseMastery, + DespairCaster, + Healing, + SpellFocusingBuff, + SpellFocusingDebuff, + RageFocusingDebuff, + RageFocusingBuff, + Warding, + TribulationCaster, + ForceArrow, + Disarm, + Surge, + Feint, + TalonStrike, + PsychicAttack, + ConsecrateWeapon, + GrapesOfWrath, + EnemyOfOneDebuff, + HorrificBeast, + LichForm, + VampiricEmbrace, + CurseWeapon, + ReaperForm, + ImmolatingWeapon, + Enchant, + HonorableExecution, + Confidence, + Evasion, + CounterAttack, + LightningStrike, + MomentumStrike, + OrangePetals, + RoseOfTrinsic, + PoisonImmunity, + Veterinary, + Perfection, + Honored, + ManaPhase, + FanDancerFanFire, + Rage, + Webbing, + MedusaStone, + TrueFear, + AuraOfNausea, + HowlOfCacophony, + GazeDespair, + HiryuPhysicalResistance, + RuneBeetleCorruption, + BloodwormAnemia, + RotwormBloodDisease, + SkillUseDelay, + FactionStatLoss, + HeatOfBattleStatus, + CriminalStatus, + ArmorPierce, + SplinteringEffect, + SwingSpeedDebuff, + WraithForm, + CityTradeDeal = 0x466, + HumilityDebuff = 0x467, + Spirituality, + Humility, + // Skill Masteries + Rampage, + Stagger, // Debuff + Toughness, + Thrust, + Pierce, // Debuff + PlayingTheOdds, + FocusedEye, + Onslaught, // Debuff + ElementalFury, + ElementalFuryDebuff, // Debuff + CalledShot, + Knockout, + SavingThrow, + Conduit, + EtherealBurst, + MysticWeapon, + ManaShield, + AnticipateHit, + Warcry, + Shadow, + WhiteTigerForm, + Bodyguard, + HeightenedSenses, + Tolerance, + DeathRay, + DeathRayDebuff, + Intuition, + EnchantedSummoning, + ShieldBash, + Whispering, + CombatTraining, + InjectedStrikeDebuff, + InjectedStrike, + UnknownTomato, + PlayingTheOddsDebuff, + DragonTurtleDebuff, + Boarding, + Potency, + ThrustDebuff, + FistsOfFury, // 1169 + BarrabHemolymphConcentrate, + JukariBurnPoiltice, + KurakAmbushersEssence, + BarakoDraftOfMight, + UraliTranceTonic, + SakkhraProphylaxis, // 1175 + Sparks, + Swarm, + BoneBreaker, + Unknown2, + SwarmImmune, + BoneBreakerImmune, + UnknownGoblin, + UnknownRedDrop, + UnknownStar, + FeintDebuff, + CaddelliteInfused, + PotionGloriousFortune, + MysticalPolymorphTotem, + UnknownDebuff, +} diff --git a/Projects/UOContent/Network/BuffIconPackets.cs b/Projects/UOContent/Engines/BuffIcons/BuffIconPackets.cs similarity index 97% rename from Projects/UOContent/Network/BuffIconPackets.cs rename to Projects/UOContent/Engines/BuffIcons/BuffIconPackets.cs index fc615ee5f..61db36a5c 100644 --- a/Projects/UOContent/Network/BuffIconPackets.cs +++ b/Projects/UOContent/Engines/BuffIcons/BuffIconPackets.cs @@ -1,6 +1,7 @@ using System.Buffers; +using Server.Network; -namespace Server.Network; +namespace Server.Engines.BuffIcons; public static class BuffIconPackets { diff --git a/Projects/UOContent/Engines/BuffIcons/BuffInfo.cs b/Projects/UOContent/Engines/BuffIcons/BuffInfo.cs new file mode 100644 index 000000000..d0c1ed6c5 --- /dev/null +++ b/Projects/UOContent/Engines/BuffIcons/BuffInfo.cs @@ -0,0 +1,66 @@ +using System; +using ModernUO.CodeGeneratedEvents; +using Server.Mobiles; + +namespace Server.Engines.BuffIcons; + +public class BuffInfo +{ + private TimerExecutionToken _timerToken; + + public BuffInfo( + BuffIcon iconID, int titleCliloc, TimeSpan duration = default, TextDefinition args = null, + bool retainThroughDeath = false + ) : this(iconID, titleCliloc, titleCliloc + 1, duration, args, retainThroughDeath) + { + } + + public BuffInfo( + BuffIcon iconID, int titleCliloc, int secondaryCliloc, TimeSpan duration = default, TextDefinition args = null, + bool retainThroughDeath = false + ) + { + ID = iconID; + TitleCliloc = titleCliloc; + SecondaryCliloc = secondaryCliloc; + Duration = duration; + Args = args; + RetainThroughDeath = retainThroughDeath; + } + + public static bool Enabled { get; private set; } + + public BuffIcon ID { get; } + + public int TitleCliloc { get; } + + public int SecondaryCliloc { get; } + + public DateTime StartTime { get; private set; } + + public TimeSpan Duration { get; } + + public bool RetainThroughDeath { get; } + + public TextDefinition Args { get; } + + public static void Configure() + { + Enabled = ServerConfiguration.GetOrUpdateSetting("buffIcons.enable", Core.ML); + } + + public void StartTimer(PlayerMobile m) + { + if (Duration != TimeSpan.Zero) + { + StartTime = Core.Now; + var id = ID; + Timer.StartTimer(Duration, () => m.RemoveBuff(id), out _timerToken); + } + } + + public void StopTimer() + { + _timerToken.Cancel(); + } +} diff --git a/Projects/UOContent/Items/Skill Items/Magical/Potions/InvisibilityPotion.cs b/Projects/UOContent/Items/Skill Items/Magical/Potions/InvisibilityPotion.cs index d3a2e4e5f..e7b631a7c 100644 --- a/Projects/UOContent/Items/Skill Items/Magical/Potions/InvisibilityPotion.cs +++ b/Projects/UOContent/Items/Skill Items/Magical/Potions/InvisibilityPotion.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; using ModernUO.Serialization; +using Server.Engines.BuffIcons; +using Server.Mobiles; namespace Server.Items; @@ -57,8 +59,11 @@ public partial class InvisibilityPotion : BasePotion m.Hidden = true; - BuffInfo.RemoveBuff(m, BuffIcon.HidingAndOrStealth); - BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.Invisibility, 1075825)); // Invisibility/Invisible + if (m is PlayerMobile pm) + { + pm.RemoveBuff(BuffIcon.HidingAndOrStealth); + pm.AddBuff(new BuffInfo(BuffIcon.Invisibility, 1075825)); // Invisibility/Invisible + } RemoveTimer(m); diff --git a/Projects/UOContent/Items/Talismans/BaseTalisman.cs b/Projects/UOContent/Items/Talismans/BaseTalisman.cs index c96e70f68..9c659f525 100644 --- a/Projects/UOContent/Items/Talismans/BaseTalisman.cs +++ b/Projects/UOContent/Items/Talismans/BaseTalisman.cs @@ -1,5 +1,6 @@ using System; using ModernUO.Serialization; +using Server.Engines.BuffIcons; using Server.Mobiles; using Server.Spells.Fifth; using Server.Spells.First; @@ -973,126 +974,140 @@ public partial class BaseTalisman : Item, IAosItem switch (m_Talisman.Removal) { case TalismanRemoval.Curse: - target.PlaySound(0xF6); - target.PlaySound(0x1F7); - target.FixedParticles(0x3709, 1, 30, 9963, 13, 3, EffectLayer.Head); - - IEntity mfrom = new Entity( - Serial.Zero, - new Point3D(target.X, target.Y, target.Z - 10), - from.Map - ); - IEntity mto = new Entity(Serial.Zero, new Point3D(target.X, target.Y, target.Z + 50), from.Map); - Effects.SendMovingParticles( - mfrom, - mto, - 0x2255, - 1, - 0, - false, - false, - 13, - 3, - 9501, - 1, - 0, - EffectLayer.Head, - 0x100 - ); - - var mod = target.GetStatMod("[Magic] Str Curse"); - if (mod?.Offset < 0) { - target.RemoveStatMod("[Magic] Str Curse"); + target.PlaySound(0xF6); + target.PlaySound(0x1F7); + target.FixedParticles(0x3709, 1, 30, 9963, 13, 3, EffectLayer.Head); + + IEntity mfrom = new Entity( + Serial.Zero, + new Point3D(target.X, target.Y, target.Z - 10), + from.Map + ); + IEntity mto = new Entity(Serial.Zero, new Point3D(target.X, target.Y, target.Z + 50), from.Map); + Effects.SendMovingParticles( + mfrom, + mto, + 0x2255, + 1, + 0, + false, + false, + 13, + 3, + 9501, + 1, + 0, + EffectLayer.Head, + 0x100 + ); + + var mod = target.GetStatMod("[Magic] Str Curse"); + if (mod?.Offset < 0) + { + target.RemoveStatMod("[Magic] Str Curse"); + } + + mod = target.GetStatMod("[Magic] Dex Curse"); + if (mod?.Offset < 0) + { + target.RemoveStatMod("[Magic] Dex Curse"); + } + + mod = target.GetStatMod("[Magic] Int Curse"); + if (mod?.Offset < 0) + { + target.RemoveStatMod("[Magic] Int Curse"); + } + + target.Paralyzed = false; + + EvilOmenSpell.EndEffect(target); + StrangleSpell.RemoveCurse(target); + CorpseSkinSpell.RemoveCurse(target); + CurseSpell.RemoveEffect(target); + + if (target is PlayerMobile pm) + { + pm.RemoveBuff(BuffIcon.Clumsy); + pm.RemoveBuff(BuffIcon.FeebleMind); + pm.RemoveBuff(BuffIcon.Weaken); + pm.RemoveBuff(BuffIcon.MassCurse); + } + + target.SendLocalizedMessage(1072408); // Any curses on you have been lifted + + if (target != from) + { + from.SendLocalizedMessage(1072409); // Your targets curses have been lifted + } + + break; } - - mod = target.GetStatMod("[Magic] Dex Curse"); - if (mod?.Offset < 0) - { - target.RemoveStatMod("[Magic] Dex Curse"); - } - - mod = target.GetStatMod("[Magic] Int Curse"); - if (mod?.Offset < 0) - { - target.RemoveStatMod("[Magic] Int Curse"); - } - - target.Paralyzed = false; - - EvilOmenSpell.EndEffect(target); - StrangleSpell.RemoveCurse(target); - CorpseSkinSpell.RemoveCurse(target); - CurseSpell.RemoveEffect(target); - - BuffInfo.RemoveBuff(target, BuffIcon.Clumsy); - BuffInfo.RemoveBuff(target, BuffIcon.FeebleMind); - BuffInfo.RemoveBuff(target, BuffIcon.Weaken); - BuffInfo.RemoveBuff(target, BuffIcon.MassCurse); - - target.SendLocalizedMessage(1072408); // Any curses on you have been lifted - - if (target != from) - { - from.SendLocalizedMessage(1072409); // Your targets curses have been lifted - } - - break; case TalismanRemoval.Damage: - target.PlaySound(0x201); - Effects.SendLocationParticles( - EffectItem.Create(target.Location, target.Map, EffectItem.DefaultDuration), - 0x3728, - 1, - 13, - 0x834, - 0, - 0x13B2, - 0 - ); - - BleedAttack.EndBleed(target, true); - MortalStrike.EndWound(target); - - BuffInfo.RemoveBuff(target, BuffIcon.Bleed); - BuffInfo.RemoveBuff(target, BuffIcon.MortalStrike); - - target.SendLocalizedMessage(1072405); // Your lasting damage effects have been removed! - - if (target != from) { - from.SendLocalizedMessage(1072406); // Your Targets lasting damage effects have been removed! - } + target.PlaySound(0x201); + Effects.SendLocationParticles( + EffectItem.Create(target.Location, target.Map, EffectItem.DefaultDuration), + 0x3728, + 1, + 13, + 0x834, + 0, + 0x13B2, + 0 + ); - break; + BleedAttack.EndBleed(target, true); + MortalStrike.EndWound(target); + + if (target is PlayerMobile pm) + { + pm.RemoveBuff(BuffIcon.Bleed); + pm.RemoveBuff(BuffIcon.MortalStrike); + } + + target.SendLocalizedMessage(1072405); // Your lasting damage effects have been removed! + + if (target != from) + { + from.SendLocalizedMessage(1072406); // Your Targets lasting damage effects have been removed! + } + + break; + } case TalismanRemoval.Ward: - target.PlaySound(0x201); - Effects.SendLocationParticles( - EffectItem.Create(target.Location, target.Map, EffectItem.DefaultDuration), - 0x3728, - 1, - 13, - 0x834, - 0, - 0x13B2, - 0 - ); - - MagicReflectSpell.EndReflect(target); - ReactiveArmorSpell.EndArmor(target); - ProtectionSpell.EndProtection(target); - - target.SendLocalizedMessage(1072402); // Your wards have been removed! - - if (target != from) { - from.SendLocalizedMessage(1072403); // Your target's wards have been removed! - } + target.PlaySound(0x201); + Effects.SendLocationParticles( + EffectItem.Create(target.Location, target.Map, EffectItem.DefaultDuration), + 0x3728, + 1, + 13, + 0x834, + 0, + 0x13B2, + 0 + ); - break; + MagicReflectSpell.EndReflect(target); + ReactiveArmorSpell.EndArmor(target); + ProtectionSpell.EndProtection(target); + + target.SendLocalizedMessage(1072402); // Your wards have been removed! + + if (target != from) + { + from.SendLocalizedMessage(1072403); // Your target's wards have been removed! + } + + break; + } case TalismanRemoval.Wildfire: - // TODO - break; + { + // TODO + break; + } } m_Talisman.OnAfterUse(from); diff --git a/Projects/UOContent/Items/Weapons/Abilities/Disarm.cs b/Projects/UOContent/Items/Weapons/Abilities/Disarm.cs index 7aa4149c5..96b4a79d1 100644 --- a/Projects/UOContent/Items/Weapons/Abilities/Disarm.cs +++ b/Projects/UOContent/Items/Weapons/Abilities/Disarm.cs @@ -1,4 +1,6 @@ using System; +using Server.Engines.BuffIcons; +using Server.Mobiles; namespace Server.Items { @@ -69,7 +71,7 @@ namespace Server.Items pack.DropItem(toDisarm); - BuffInfo.AddBuff(defender, new BuffInfo(BuffIcon.NoRearm, 1075637, BlockEquipDuration, defender)); + (defender as PlayerMobile)?.AddBuff(new BuffInfo(BuffIcon.NoRearm, 1075637, BlockEquipDuration)); BaseWeapon.BlockEquip(defender, BlockEquipDuration); } diff --git a/Projects/UOContent/Items/Weapons/Abilities/ForceArrow.cs b/Projects/UOContent/Items/Weapons/Abilities/ForceArrow.cs index c846b3f60..c554b8c3b 100644 --- a/Projects/UOContent/Items/Weapons/Abilities/ForceArrow.cs +++ b/Projects/UOContent/Items/Weapons/Abilities/ForceArrow.cs @@ -1,6 +1,8 @@ using Server.Spells; using System; using System.Collections.Generic; +using Server.Engines.BuffIcons; +using Server.Mobiles; namespace Server.Items { @@ -38,8 +40,9 @@ namespace Server.Items { info.Timer.IncreaseExpiration(); - BuffInfo.RemoveBuff(defender, BuffIcon.ForceArrow); - BuffInfo.AddBuff(defender, new BuffInfo(BuffIcon.ForceArrow, 1151285, 1151286, info.DefenseChanceMalus.ToString())); + (defender as PlayerMobile)?.AddBuff( + new BuffInfo(BuffIcon.ForceArrow, 1151285, 1151286, args: info.DefenseChanceMalus.ToString()) + ); } if (defender.Spell is Spell spell && spell.IsCasting) @@ -64,7 +67,9 @@ namespace Server.Items _table.Add(attacker, new List { info }); } - BuffInfo.AddBuff(defender, new BuffInfo(BuffIcon.ForceArrow, 1151285, 1151286, info.DefenseChanceMalus.ToString())); + (defender as PlayerMobile)?.AddBuff( + new BuffInfo(BuffIcon.ForceArrow, 1151285, 1151286, args: info.DefenseChanceMalus.ToString()) + ); } public static void EndForceArrow(ForceArrowInfo info) @@ -81,7 +86,7 @@ namespace Server.Items _table.Remove(attacker); } - BuffInfo.RemoveBuff(info.Defender, BuffIcon.ForceArrow); + (info.Defender as PlayerMobile)?.RemoveBuff(BuffIcon.ForceArrow); } public static bool HasForceArrow(Mobile attacker, Mobile defender) diff --git a/Projects/UOContent/Items/Weapons/Abilities/PsychicAttack.cs b/Projects/UOContent/Items/Weapons/Abilities/PsychicAttack.cs index c6e084062..7443fdecd 100644 --- a/Projects/UOContent/Items/Weapons/Abilities/PsychicAttack.cs +++ b/Projects/UOContent/Items/Weapons/Abilities/PsychicAttack.cs @@ -1,5 +1,7 @@ using System; using System.Collections.Generic; +using Server.Engines.BuffIcons; +using Server.Mobiles; namespace Server.Items { @@ -38,10 +40,14 @@ namespace Server.Items Registry.Add(defender, timer); } - BuffInfo.RemoveBuff(defender, BuffIcon.PsychicAttack); - - string args = $"{timer.SpellDamageMalus}\t{timer.ManaCostMalus}"; - BuffInfo.AddBuff(defender, new BuffInfo(BuffIcon.PsychicAttack, 1151296, 1151297, args)); + (defender as PlayerMobile)?.AddBuff( + new BuffInfo( + BuffIcon.PsychicAttack, + 1151296, + 1151297, + args: $"{timer.SpellDamageMalus}\t{timer.ManaCostMalus}" + ) + ); } public static void RemoveEffects(Mobile defender) @@ -51,7 +57,7 @@ namespace Server.Items return; } - BuffInfo.RemoveBuff(defender, BuffIcon.PsychicAttack); + (defender as PlayerMobile)?.RemoveBuff(BuffIcon.PsychicAttack); Registry.Remove(defender); diff --git a/Projects/UOContent/Misc/BuffIcons.cs b/Projects/UOContent/Misc/BuffIcons.cs deleted file mode 100644 index f393747b5..000000000 --- a/Projects/UOContent/Misc/BuffIcons.cs +++ /dev/null @@ -1,335 +0,0 @@ -using System; -using ModernUO.CodeGeneratedEvents; -using Server.Mobiles; -using Server.Network; - -namespace Server -{ - public class BuffInfo - { - private TimerExecutionToken _timerToken; - - public BuffInfo(BuffIcon iconID, int titleCliloc) : this(iconID, titleCliloc, titleCliloc + 1) - { - } - - public BuffInfo(BuffIcon iconID, int titleCliloc, int secondaryCliloc) - { - ID = iconID; - TitleCliloc = titleCliloc; - SecondaryCliloc = secondaryCliloc; - } - - public BuffInfo(BuffIcon iconID, int titleCliloc, TimeSpan length, Mobile m) - : this(iconID, titleCliloc, titleCliloc + 1, length, m) - { - } - - // Only the timed one needs the Mobile to know when to automagically remove it. - public BuffInfo(BuffIcon iconID, int titleCliloc, int secondaryCliloc, TimeSpan length, Mobile m) - : this(iconID, titleCliloc, secondaryCliloc) - { - TimeLength = length; - TimeStart = Core.TickCount; - - Timer.StartTimer(length, () => RemoveBuff(m, this), out _timerToken); - } - - public BuffInfo(BuffIcon iconID, int titleCliloc, TextDefinition args) - : this(iconID, titleCliloc, titleCliloc + 1, args) - { - } - - public BuffInfo(BuffIcon iconID, int titleCliloc, int secondaryCliloc, TextDefinition args) - : this(iconID, titleCliloc, secondaryCliloc) => - Args = args; - - public BuffInfo(BuffIcon iconID, int titleCliloc, bool retainThroughDeath) - : this(iconID, titleCliloc, titleCliloc + 1, retainThroughDeath) - { - } - - public BuffInfo(BuffIcon iconID, int titleCliloc, int secondaryCliloc, bool retainThroughDeath) - : this(iconID, titleCliloc, secondaryCliloc) => - RetainThroughDeath = retainThroughDeath; - - public BuffInfo(BuffIcon iconID, int titleCliloc, TextDefinition args, bool retainThroughDeath) - : this(iconID, titleCliloc, titleCliloc + 1, args, retainThroughDeath) - { - } - - public BuffInfo(BuffIcon iconID, int titleCliloc, int secondaryCliloc, TextDefinition args, bool retainThroughDeath) - : this(iconID, titleCliloc, secondaryCliloc, args) => - RetainThroughDeath = retainThroughDeath; - - public BuffInfo(BuffIcon iconID, int titleCliloc, TimeSpan length, Mobile m, TextDefinition args) - : this(iconID, titleCliloc, titleCliloc + 1, length, m, args) - { - } - - public BuffInfo( - BuffIcon iconID, int titleCliloc, int secondaryCliloc, TimeSpan length, Mobile m, - TextDefinition args - ) : this(iconID, titleCliloc, secondaryCliloc, length, m) => Args = args; - - public BuffInfo( - BuffIcon iconID, int titleCliloc, TimeSpan length, Mobile m, TextDefinition args, - bool retainThroughDeath - ) : this(iconID, titleCliloc, titleCliloc + 1, length, m, args, retainThroughDeath) - { - } - - public BuffInfo( - BuffIcon iconID, int titleCliloc, int secondaryCliloc, TimeSpan length, Mobile m, - TextDefinition args, bool retainThroughDeath - ) : this(iconID, titleCliloc, secondaryCliloc, length, m) - { - Args = args; - RetainThroughDeath = retainThroughDeath; - } - - public static bool Enabled { get; private set; } - - public BuffIcon ID { get; } - - public int TitleCliloc { get; } - - public int SecondaryCliloc { get; } - - public TimeSpan TimeLength { get; } - - public long TimeStart { get; } - - public bool RetainThroughDeath { get; } - - public TextDefinition Args { get; } - - public static void Configure() - { - Enabled = ServerConfiguration.GetOrUpdateSetting("buffIcons.enable", Core.ML); - } - - [OnEvent(nameof(PlayerMobile.PlayerLoginEvent))] - public static void OnLogin(PlayerMobile pm) - { - if (!Enabled) - { - return; - } - - pm.ResendBuffs(); - } - - public static void AddBuff(Mobile m, BuffInfo b) - { - (m as PlayerMobile)?.AddBuff(b); - } - - public static void RemoveBuff(Mobile m, BuffInfo b) - { - if (b == null) - { - return; - } - - b._timerToken.Cancel(); - (m as PlayerMobile)?.RemoveBuff(b.ID); - } - - public static void RemoveBuff(Mobile m, BuffIcon b) - { - (m as PlayerMobile)?.RemoveBuff(b); - } - } - - public enum BuffIcon : short - { - DismountPrevention = 0x3E9, - NoRearm = 0x3EA, - //Currently, no 0x3EB or 0x3EC - NightSight = 0x3ED, //* - DeathStrike, - EvilOmen, - HonoredDebuff, - AchievePerfection, - DivineFury, //* - EnemyOfOne, //* - HidingAndOrStealth, //* - ActiveMeditation, //* - BloodOathCaster, //* - BloodOathCurse, //* - CorpseSkin, //* - Mindrot, //* - PainSpike, //* - Strangle, - GiftOfRenewal, //* - AttuneWeapon, //* - Thunderstorm, //* - EssenceOfWind, //* - EtherealVoyage, //* - GiftOfLife, //* - ArcaneEmpowerment, //* - MortalStrike, - ReactiveArmor, //* - Protection, //* - ArchProtection, - MagicReflection, //* - Incognito, //* - Disguised, - AnimalForm, - Polymorph, - Invisibility, //* - Paralyze, //* - Poison, - Bleed, - Clumsy, //* - FeebleMind, //* - Weaken, //* - Curse, //* - MassCurse, - Agility, //* - Cunning, //* - Strength, //* - Bless, //* - Sleep, - StoneForm, - SpellPlague, - Berserk, - MassSleep, - Fly, - Inspire, - Invigorate, - Resilience, - Perseverance, - TribulationTarget, - DespairTarget, - FishPie = 0x426, - HitLowerAttack, - HitLowerDefense, - DualWield, - Block, - DefenseMastery, - DespairCaster, - Healing, - SpellFocusingBuff, - SpellFocusingDebuff, - RageFocusingDebuff, - RageFocusingBuff, - Warding, - TribulationCaster, - ForceArrow, - Disarm, - Surge, - Feint, - TalonStrike, - PsychicAttack, - ConsecrateWeapon, - GrapesOfWrath, - EnemyOfOneDebuff, - HorrificBeast, - LichForm, - VampiricEmbrace, - CurseWeapon, - ReaperForm, - ImmolatingWeapon, - Enchant, - HonorableExecution, - Confidence, - Evasion, - CounterAttack, - LightningStrike, - MomentumStrike, - OrangePetals, - RoseOfTrinsic, - PoisonImmunity, - Veterinary, - Perfection, - Honored, - ManaPhase, - FanDancerFanFire, - Rage, - Webbing, - MedusaStone, - TrueFear, - AuraOfNausea, - HowlOfCacophony, - GazeDespair, - HiryuPhysicalResistance, - RuneBeetleCorruption, - BloodwormAnemia, - RotwormBloodDisease, - SkillUseDelay, - FactionStatLoss, - HeatOfBattleStatus, - CriminalStatus, - ArmorPierce, - SplinteringEffect, - SwingSpeedDebuff, - WraithForm, - CityTradeDeal = 0x466, - HumilityDebuff = 0x467, - Spirituality, - Humility, - // Skill Masteries - Rampage, - Stagger, // Debuff - Toughness, - Thrust, - Pierce, // Debuff - PlayingTheOdds, - FocusedEye, - Onslaught, // Debuff - ElementalFury, - ElementalFuryDebuff, // Debuff - CalledShot, - Knockout, - SavingThrow, - Conduit, - EtherealBurst, - MysticWeapon, - ManaShield, - AnticipateHit, - Warcry, - Shadow, - WhiteTigerForm, - Bodyguard, - HeightenedSenses, - Tolerance, - DeathRay, - DeathRayDebuff, - Intuition, - EnchantedSummoning, - ShieldBash, - Whispering, - CombatTraining, - InjectedStrikeDebuff, - InjectedStrike, - UnknownTomato, - PlayingTheOddsDebuff, - DragonTurtleDebuff, - Boarding, - Potency, - ThrustDebuff, - FistsOfFury, // 1169 - BarrabHemolymphConcentrate, - JukariBurnPoiltice, - KurakAmbushersEssence, - BarakoDraftOfMight, - UraliTranceTonic, - SakkhraProphylaxis, // 1175 - Sparks, - Swarm, - BoneBreaker, - Unknown2, - SwarmImmune, - BoneBreakerImmune, - UnknownGoblin, - UnknownRedDrop, - UnknownStar, - FeintDebuff, - CaddelliteInfused, - PotionGloriousFortune, - MysticalPolymorphTotem, - UnknownDebuff, - } -} diff --git a/Projects/UOContent/Misc/LightCycle.cs b/Projects/UOContent/Misc/LightCycle.cs index 441fefeb2..3c25b696a 100644 --- a/Projects/UOContent/Misc/LightCycle.cs +++ b/Projects/UOContent/Misc/LightCycle.cs @@ -1,5 +1,6 @@ using System; using ModernUO.CodeGeneratedEvents; +using Server.Engines.BuffIcons; using Server.Items; using Server.Mobiles; using Server.Network; @@ -120,7 +121,7 @@ namespace Server { m_Owner.EndAction(); m_Owner.LightLevel = 0; - BuffInfo.RemoveBuff(m_Owner, BuffIcon.NightSight); + (m_Owner as PlayerMobile)?.RemoveBuff(BuffIcon.NightSight); } } } diff --git a/Projects/UOContent/Mobiles/PlayerMobile.cs b/Projects/UOContent/Mobiles/PlayerMobile.cs index 3efb322b9..8b4e82603 100644 --- a/Projects/UOContent/Mobiles/PlayerMobile.cs +++ b/Projects/UOContent/Mobiles/PlayerMobile.cs @@ -4,6 +4,7 @@ using ModernUO.CodeGeneratedEvents; using Server.Accounting; using Server.Collections; using Server.ContextMenus; +using Server.Engines.BuffIcons; using Server.Engines.BulkOrders; using Server.Engines.CannedEvil; using Server.Engines.ConPVP; @@ -752,7 +753,7 @@ namespace Server.Mobiles Freeze(TimeSpan.FromSeconds(1)); Animate(61, 10, 1, true, false, 0); Flying = false; - BuffInfo.RemoveBuff(this, BuffIcon.Fly); + RemoveBuff(BuffIcon.Fly); SendMessage("You have landed."); BaseMount.Dismount(this); @@ -810,7 +811,7 @@ namespace Server.Mobiles else { Flying = false; - BuffInfo.RemoveBuff(this, BuffIcon.Fly); + RemoveBuff(BuffIcon.Fly); } } } @@ -1216,7 +1217,7 @@ namespace Server.Mobiles if (!Meditating) { - BuffInfo.RemoveBuff(this, BuffIcon.ActiveMeditation); + RemoveBuff(BuffIcon.ActiveMeditation); } } @@ -1264,6 +1265,7 @@ namespace Server.Mobiles VirtueSystem.CheckAtrophies(from); from.ClaimAutoStabledPets(); AnimalForm.GetContext(from)?.Timer.Start(); + from.ResendBuffs(); } private class ServerLockdownNoticeGump : StaticNoticeGump @@ -1601,7 +1603,7 @@ namespace Server.Mobiles else // if (!InvisibilitySpell.HasTimer( this )) { // Hidden/Stealthing & You Are Hidden - BuffInfo.AddBuff(this, new BuffInfo(BuffIcon.HidingAndOrStealth, 1075655)); + AddBuff(new BuffInfo(BuffIcon.HidingAndOrStealth, 1075655)); } } @@ -2548,7 +2550,7 @@ namespace Server.Mobiles if (Flying) { Flying = false; - BuffInfo.RemoveBuff(this, BuffIcon.Fly); + RemoveBuff(BuffIcon.Fly); } if (PermaFlags.Count > 0) @@ -2635,19 +2637,19 @@ namespace Server.Mobiles if (m_BuffTable != null) { - using var queue = PooledRefQueue.Create(); + using var queue = PooledRefQueue.Create(); foreach (var buff in m_BuffTable.Values) { if (!buff.RetainThroughDeath) { - queue.Enqueue(buff); + queue.Enqueue(buff.ID); } } while (queue.Count > 0) { - BuffInfo.RemoveBuff(this, queue.Dequeue()); + RemoveBuff(queue.Dequeue()); } } @@ -4476,22 +4478,24 @@ namespace Server.Mobiles return; } - // Synchronize the buff icon as close to _on the second_ as we can. - var msecs = buffInfo.TimeLength.Milliseconds; - if (msecs >= 8) + var duration = Utility.Max(buffInfo.Duration - (Core.Now - buffInfo.StartTime), TimeSpan.Zero).TotalSeconds; + var rounded = Math.Round(duration); + var offset = duration - rounded; + if (offset > 0) { - Timer.DelayCall(TimeSpan.FromMilliseconds(msecs), () => - { - // They are still online, we still have the buff icon in the table, and it is the same buff icon - if (NetState != null && m_BuffTable?.GetValueOrDefault(buffInfo.ID) == buffInfo) + Timer.DelayCall(TimeSpan.FromSeconds(offset), () => { - SendAddBuffPacket(buffInfo, (long)buffInfo.TimeLength.TotalMilliseconds - msecs); + // They are still online, we still have the buff icon in the table, and it is the same buff icon + if (NetState != null && m_BuffTable?.GetValueOrDefault(buffInfo.ID) == buffInfo) + { + SendAddBuffPacket(buffInfo, (long)rounded); + } } - }); + ); } - else + else // Round up, will be removed a little bit early by the server { - SendAddBuffPacket(buffInfo, (long)buffInfo.TimeLength.TotalMilliseconds); + SendAddBuffPacket(buffInfo, (long)rounded); } } @@ -4525,7 +4529,8 @@ namespace Server.Mobiles return; } - BuffInfo.RemoveBuff(this, b); // Check, stop old timer, & subsequently remove the old one. + RemoveBuff(b.ID); // Check, stop old timer, & subsequently remove the old one. + b.StartTimer(this); m_BuffTable ??= new Dictionary(); m_BuffTable.Add(b.ID, b); @@ -4535,11 +4540,13 @@ namespace Server.Mobiles public void RemoveBuff(BuffIcon b) { - if (m_BuffTable?.Remove(b) != true) + if (m_BuffTable?.Remove(b, out var buffInfo) != true) { return; } + buffInfo.StopTimer(); + if (NetState?.BuffIcon == true) { NetState.SendRemoveBuffPacket(Serial, b); diff --git a/Projects/UOContent/Skills/Meditation.cs b/Projects/UOContent/Skills/Meditation.cs index b30f63a91..d382c7c3a 100644 --- a/Projects/UOContent/Skills/Meditation.cs +++ b/Projects/UOContent/Skills/Meditation.cs @@ -1,6 +1,8 @@ using System; +using Server.Engines.BuffIcons; using Server.Items; using Server.Misc; +using Server.Mobiles; namespace Server.SkillHandlers { @@ -79,7 +81,7 @@ namespace Server.SkillHandlers m.SendLocalizedMessage(501851); // You enter a meditative trance. m.Meditating = true; - BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.ActiveMeditation, 1075657)); + (m as PlayerMobile)?.AddBuff(new BuffInfo(BuffIcon.ActiveMeditation, 1075657)); if (m.Player || m.Body.IsHuman) { diff --git a/Projects/UOContent/Spells/Bushido/Confidence.cs b/Projects/UOContent/Spells/Bushido/Confidence.cs index fb9757904..2dd21bc0e 100644 --- a/Projects/UOContent/Spells/Bushido/Confidence.cs +++ b/Projects/UOContent/Spells/Bushido/Confidence.cs @@ -1,5 +1,7 @@ using System; using System.Collections.Generic; +using Server.Engines.BuffIcons; +using Server.Mobiles; namespace Server.Spells.Bushido; @@ -69,13 +71,19 @@ public class Confidence : SamuraiSpell if (Core.HS) { var bushido = m.Skills.Bushido.Fixed; - BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.Confidence, 1060596, 1153809, TimeSpan.FromSeconds(30), m, - $"{bushido / 120}\t{bushido / 50}\t{"100"}" - )); + (m as PlayerMobile)?.AddBuff( + new BuffInfo( + BuffIcon.Confidence, + 1060596, + 1153809, + TimeSpan.FromSeconds(30), + $"{bushido / 120}\t{bushido / 50}\t{"100"}" + ) + ); } else { - BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.Confidence, 1060596, TimeSpan.FromSeconds(30), m)); + (m as PlayerMobile)?.AddBuff(new BuffInfo(BuffIcon.Confidence, 1060596, TimeSpan.FromSeconds(30))); } } @@ -97,7 +105,7 @@ public class Confidence : SamuraiSpell if (StopConfidenceTimer(m)) { OnEffectEnd(m, typeof(Confidence)); - BuffInfo.RemoveBuff(m, BuffIcon.Confidence); + (m as PlayerMobile)?.RemoveBuff(BuffIcon.Confidence); } } diff --git a/Projects/UOContent/Spells/Bushido/HonorableExecution.cs b/Projects/UOContent/Spells/Bushido/HonorableExecution.cs index 0cb0cd3e2..935ad55be 100644 --- a/Projects/UOContent/Spells/Bushido/HonorableExecution.cs +++ b/Projects/UOContent/Spells/Bushido/HonorableExecution.cs @@ -1,5 +1,7 @@ using System; using System.Collections.Generic; +using Server.Engines.BuffIcons; +using Server.Mobiles; namespace Server.Spells.Bushido; @@ -42,14 +44,12 @@ public class HonorableExecution : SamuraiMove timer = new HonorableExecutionTimer(attacker, swingBonus); - BuffInfo.AddBuff( - attacker, + (attacker as PlayerMobile)?.AddBuff( new BuffInfo( BuffIcon.HonorableExecution, 1060595, 1153807, TimeSpan.FromSeconds(20.0), - attacker, $"{swingBonus}" ) ); @@ -76,23 +76,20 @@ public class HonorableExecution : SamuraiMove if (Core.HS) { - BuffInfo.AddBuff( - attacker, + (attacker as PlayerMobile)?.AddBuff( new BuffInfo( BuffIcon.HonorableExecution, 1060595, 1153808, TimeSpan.FromSeconds(7.0), - attacker, $"{resSpells}\t{40}\t{40}\t{40}\t{40}\t{40}" ) ); } else { - BuffInfo.AddBuff( - attacker, - new BuffInfo(BuffIcon.HonorableExecution, 1060595, TimeSpan.FromSeconds(7.0), attacker) + (attacker as PlayerMobile)?.AddBuff( + new BuffInfo(BuffIcon.HonorableExecution, 1060595, TimeSpan.FromSeconds(7.0)) ); } } diff --git a/Projects/UOContent/Spells/Chivalry/DivineFury.cs b/Projects/UOContent/Spells/Chivalry/DivineFury.cs index c2afcfa36..1429c9da2 100644 --- a/Projects/UOContent/Spells/Chivalry/DivineFury.cs +++ b/Projects/UOContent/Spells/Chivalry/DivineFury.cs @@ -1,5 +1,7 @@ using System; using System.Collections.Generic; +using Server.Engines.BuffIcons; +using Server.Mobiles; namespace Server.Spells.Chivalry; @@ -52,24 +54,19 @@ public class DivineFurySpell : PaladinSpell if (Core.HS) // Publish 71 with boost { - BuffInfo.AddBuff( - Caster, + (Caster as PlayerMobile)?.AddBuff( new BuffInfo( BuffIcon.DivineFury, 1060589, 1150218, delay, - Caster, $"{timer.AttackBonus}\t{timer.DamageBonus}\t{timer.WeaponSpeed}\t{timer.DefendMalus}" ) ); } else { - BuffInfo.AddBuff( - Caster, - new BuffInfo(BuffIcon.DivineFury, 1060589, 1075634, delay, Caster) - ); + (Caster as PlayerMobile)?.AddBuff(new BuffInfo(BuffIcon.DivineFury, 1060589, 1075634, delay)); } } @@ -116,7 +113,7 @@ public class DivineFurySpell : PaladinSpell RemoveTimer(m); m.Delta(MobileDelta.WeaponDamage); m.PlaySound(0xF8); - BuffInfo.RemoveBuff(m, BuffIcon.DivineFury); + (m as PlayerMobile)?.RemoveBuff(BuffIcon.DivineFury); } public static bool UnderEffect(Mobile m) => _table.ContainsKey(m); diff --git a/Projects/UOContent/Spells/Chivalry/EnemyOfOne.cs b/Projects/UOContent/Spells/Chivalry/EnemyOfOne.cs index 5014eab26..0956bfc69 100644 --- a/Projects/UOContent/Spells/Chivalry/EnemyOfOne.cs +++ b/Projects/UOContent/Spells/Chivalry/EnemyOfOne.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using Server.Engines.BuffIcons; using Server.Mobiles; namespace Server.Spells.Chivalry @@ -49,9 +50,8 @@ namespace Server.Spells.Chivalry mobile.EnemyOfOneType = null; mobile.WaitingForEnemy = true; - BuffInfo.AddBuff( - mobile, - new BuffInfo(BuffIcon.EnemyOfOne, 1075653, 1044111, TimeSpan.FromMinutes(delay), mobile) + mobile.AddBuff( + new BuffInfo(BuffIcon.EnemyOfOne, 1075653, 1044111, TimeSpan.FromMinutes(delay)) ); } } diff --git a/Projects/UOContent/Spells/Chivalry/NobleSacrifice.cs b/Projects/UOContent/Spells/Chivalry/NobleSacrifice.cs index a63a9fe38..4af9d1fa8 100644 --- a/Projects/UOContent/Spells/Chivalry/NobleSacrifice.cs +++ b/Projects/UOContent/Spells/Chivalry/NobleSacrifice.cs @@ -1,5 +1,6 @@ using System; using Server.Collections; +using Server.Engines.BuffIcons; using Server.Gumps; using Server.Items; using Server.Mobiles; @@ -142,14 +143,17 @@ namespace Server.Spells.Chivalry sendEffect = SpellPlagueSpell.RemoveEffect(m) || sendEffect; // TODO: Move these into their respective end effect methods - BuffInfo.RemoveBuff(m, BuffIcon.Clumsy); - BuffInfo.RemoveBuff(m, BuffIcon.FeebleMind); - BuffInfo.RemoveBuff(m, BuffIcon.Weaken); - BuffInfo.RemoveBuff(m, BuffIcon.Curse); - BuffInfo.RemoveBuff(m, BuffIcon.MassCurse); - BuffInfo.RemoveBuff(m, BuffIcon.MortalStrike); - BuffInfo.RemoveBuff(m, BuffIcon.Strangle); - BuffInfo.RemoveBuff(m, BuffIcon.EvilOmen); + if (m is PlayerMobile pm) + { + pm.RemoveBuff(BuffIcon.Clumsy); + pm.RemoveBuff(BuffIcon.FeebleMind); + pm.RemoveBuff(BuffIcon.Weaken); + pm.RemoveBuff(BuffIcon.Curse); + pm.RemoveBuff(BuffIcon.MassCurse); + pm.RemoveBuff(BuffIcon.MortalStrike); + pm.RemoveBuff(BuffIcon.Strangle); + pm.RemoveBuff(BuffIcon.EvilOmen); + } if (sendEffect) { diff --git a/Projects/UOContent/Spells/Chivalry/RemoveCurse.cs b/Projects/UOContent/Spells/Chivalry/RemoveCurse.cs index 6f89d8562..6137433b9 100644 --- a/Projects/UOContent/Spells/Chivalry/RemoveCurse.cs +++ b/Projects/UOContent/Spells/Chivalry/RemoveCurse.cs @@ -1,6 +1,8 @@ using System; +using Server.Engines.BuffIcons; using Server.Engines.ConPVP; using Server.Items; +using Server.Mobiles; using Server.Spells.Fourth; using Server.Spells.Mysticism; using Server.Spells.Necromancy; @@ -109,15 +111,17 @@ namespace Server.Spells.Chivalry BloodOathSpell.RemoveCurse(m); SpellPlagueSpell.RemoveEffect(m); - // TODO: Move these into their respective end effect methods - BuffInfo.RemoveBuff(m, BuffIcon.Clumsy); - BuffInfo.RemoveBuff(m, BuffIcon.FeebleMind); - BuffInfo.RemoveBuff(m, BuffIcon.Weaken); - BuffInfo.RemoveBuff(m, BuffIcon.Curse); - BuffInfo.RemoveBuff(m, BuffIcon.MassCurse); - BuffInfo.RemoveBuff(m, BuffIcon.MortalStrike); - BuffInfo.RemoveBuff(m, BuffIcon.Strangle); - BuffInfo.RemoveBuff(m, BuffIcon.EvilOmen); + if (m is PlayerMobile pm) + { + pm.RemoveBuff(BuffIcon.Clumsy); + pm.RemoveBuff(BuffIcon.FeebleMind); + pm.RemoveBuff(BuffIcon.Weaken); + pm.RemoveBuff(BuffIcon.Curse); + pm.RemoveBuff(BuffIcon.MassCurse); + pm.RemoveBuff(BuffIcon.MortalStrike); + pm.RemoveBuff(BuffIcon.Strangle); + pm.RemoveBuff(BuffIcon.EvilOmen); + } } else { diff --git a/Projects/UOContent/Spells/Fifth/Incognito.cs b/Projects/UOContent/Spells/Fifth/Incognito.cs index a1092a307..77d50c703 100644 --- a/Projects/UOContent/Spells/Fifth/Incognito.cs +++ b/Projects/UOContent/Spells/Fifth/Incognito.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using ModernUO.CodeGeneratedEvents; +using Server.Engines.BuffIcons; using Server.Factions; using Server.Items; using Server.Mobiles; @@ -114,7 +115,7 @@ namespace Server.Spells.Fifth Timer.StartTimer(duration, () => EndIncognito(Caster), out var timerToken); _table[Caster] = timerToken; - BuffInfo.AddBuff(Caster, new BuffInfo(BuffIcon.Incognito, 1075819, duration, Caster)); + pm?.AddBuff(new BuffInfo(BuffIcon.Incognito, 1075819, duration)); } else { @@ -139,7 +140,7 @@ namespace Server.Spells.Fifth timerToken.Cancel(); } - BuffInfo.RemoveBuff(m, BuffIcon.Incognito); + (m as PlayerMobile)?.RemoveBuff(BuffIcon.Incognito); } public static void EndIncognito(Mobile m) diff --git a/Projects/UOContent/Spells/Fifth/MagicReflect.cs b/Projects/UOContent/Spells/Fifth/MagicReflect.cs index d6a85e91c..94f1fbb38 100644 --- a/Projects/UOContent/Spells/Fifth/MagicReflect.cs +++ b/Projects/UOContent/Spells/Fifth/MagicReflect.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using ModernUO.CodeGeneratedEvents; +using Server.Engines.BuffIcons; using Server.Mobiles; namespace Server.Spells.Fifth @@ -70,7 +71,7 @@ namespace Server.Spells.Fifth Caster.RemoveResistanceMod(mods[i]); } - BuffInfo.RemoveBuff(Caster, BuffIcon.MagicReflection); + (Caster as PlayerMobile)?.RemoveBuff(BuffIcon.MagicReflection); } else { @@ -98,7 +99,9 @@ namespace Server.Spells.Fifth var buffFormat = $"{physiMod}\t+{otherMod}\t+{otherMod}\t+{otherMod}\t+{otherMod}"; - BuffInfo.AddBuff(Caster, new BuffInfo(BuffIcon.MagicReflection, 1075817, buffFormat, true)); + (Caster as PlayerMobile)?.AddBuff( + new BuffInfo(BuffIcon.MagicReflection, 1075817, args: buffFormat, retainThroughDeath: true) + ); } } } @@ -147,7 +150,7 @@ namespace Server.Spells.Fifth m.RemoveResistanceMod(mods[i]); } - BuffInfo.RemoveBuff(m, BuffIcon.MagicReflection); + (m as PlayerMobile)?.RemoveBuff(BuffIcon.MagicReflection); } } } diff --git a/Projects/UOContent/Spells/First/Clumsy.cs b/Projects/UOContent/Spells/First/Clumsy.cs index 5d942991b..539473bb3 100644 --- a/Projects/UOContent/Spells/First/Clumsy.cs +++ b/Projects/UOContent/Spells/First/Clumsy.cs @@ -1,3 +1,5 @@ +using Server.Engines.BuffIcons; +using Server.Mobiles; using Server.Targeting; namespace Server.Spells.First @@ -39,7 +41,7 @@ namespace Server.Spells.First var percentage = (int)(SpellHelper.GetOffsetScalar(Caster, m, true) * 100); - BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.Clumsy, 1075831, length, m, percentage.ToString())); + (m as PlayerMobile)?.AddBuff(new BuffInfo(BuffIcon.Clumsy, 1075831, length, percentage.ToString())); HarmfulSpell(m); } diff --git a/Projects/UOContent/Spells/First/Feeblemind.cs b/Projects/UOContent/Spells/First/Feeblemind.cs index e762d5684..93cbb32da 100644 --- a/Projects/UOContent/Spells/First/Feeblemind.cs +++ b/Projects/UOContent/Spells/First/Feeblemind.cs @@ -1,3 +1,5 @@ +using Server.Engines.BuffIcons; +using Server.Mobiles; using Server.Targeting; namespace Server.Spells.First @@ -41,7 +43,7 @@ namespace Server.Spells.First var percentage = (int)(SpellHelper.GetOffsetScalar(Caster, m, true) * 100); - BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.FeebleMind, 1075833, length, m, percentage.ToString())); + (m as PlayerMobile)?.AddBuff(new BuffInfo(BuffIcon.FeebleMind, 1075833, length, percentage.ToString())); HarmfulSpell(m); } diff --git a/Projects/UOContent/Spells/First/NightSight.cs b/Projects/UOContent/Spells/First/NightSight.cs index 6c23a13f7..01aeb2af1 100644 --- a/Projects/UOContent/Spells/First/NightSight.cs +++ b/Projects/UOContent/Spells/First/NightSight.cs @@ -1,4 +1,6 @@ using System; +using Server.Engines.BuffIcons; +using Server.Mobiles; using Server.Targeting; namespace Server.Spells.First; @@ -46,7 +48,7 @@ public class NightSightSpell : MagerySpell, ITargetingSpell m.PlaySound(0x1E3); // Night Sight/You ignore lighting effects - BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.NightSight, 1075643)); + (m as PlayerMobile)?.AddBuff(new BuffInfo(BuffIcon.NightSight, 1075643)); } else if (m == Caster) { diff --git a/Projects/UOContent/Spells/First/ReactiveArmor.cs b/Projects/UOContent/Spells/First/ReactiveArmor.cs index 887f1228a..768273244 100644 --- a/Projects/UOContent/Spells/First/ReactiveArmor.cs +++ b/Projects/UOContent/Spells/First/ReactiveArmor.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using ModernUO.CodeGeneratedEvents; +using Server.Engines.BuffIcons; using Server.Mobiles; namespace Server.Spells.First @@ -72,7 +73,7 @@ namespace Server.Spells.First Caster.RemoveResistanceMod(mods[i]); } - BuffInfo.RemoveBuff(Caster, BuffIcon.ReactiveArmor); + (Caster as PlayerMobile)?.RemoveBuff(BuffIcon.ReactiveArmor); } else { @@ -102,7 +103,7 @@ namespace Server.Spells.First var physresist = 15 + (int)(Caster.Skills.Inscribe.Value / 20); var args = $"{physresist}\t{5}\t{5}\t{5}\t{5}"; - BuffInfo.AddBuff(Caster, new BuffInfo(BuffIcon.ReactiveArmor, 1075812, 1075813, args)); + (Caster as PlayerMobile)?.AddBuff(new BuffInfo(BuffIcon.ReactiveArmor, 1075812, 1075813, args: args)); } } @@ -157,7 +158,7 @@ namespace Server.Spells.First m.RemoveResistanceMod(mods[i]); } - BuffInfo.RemoveBuff(m, BuffIcon.ReactiveArmor); + (m as PlayerMobile)?.RemoveBuff(BuffIcon.ReactiveArmor); } } } diff --git a/Projects/UOContent/Spells/First/Weaken.cs b/Projects/UOContent/Spells/First/Weaken.cs index 082027ad0..eee9f5036 100644 --- a/Projects/UOContent/Spells/First/Weaken.cs +++ b/Projects/UOContent/Spells/First/Weaken.cs @@ -1,3 +1,5 @@ +using Server.Engines.BuffIcons; +using Server.Mobiles; using Server.Targeting; namespace Server.Spells.First @@ -39,7 +41,7 @@ namespace Server.Spells.First var percentage = (int)(SpellHelper.GetOffsetScalar(Caster, m, true) * 100); - BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.Weaken, 1075837, length, m, percentage.ToString())); + (m as PlayerMobile)?.AddBuff(new BuffInfo(BuffIcon.Weaken, 1075837, length, percentage.ToString())); HarmfulSpell(m); } diff --git a/Projects/UOContent/Spells/Fourth/Curse.cs b/Projects/UOContent/Spells/Fourth/Curse.cs index 0f01b0a3c..2f70789ea 100644 --- a/Projects/UOContent/Spells/Fourth/Curse.cs +++ b/Projects/UOContent/Spells/Fourth/Curse.cs @@ -1,5 +1,7 @@ using System; using System.Collections.Generic; +using Server.Engines.BuffIcons; +using Server.Mobiles; using Server.Targeting; namespace Server.Spells.Fourth @@ -80,7 +82,7 @@ namespace Server.Spells.Fourth var percentage = (int)(SpellHelper.GetOffsetScalar(caster, m, true) * 100); var args = $"{percentage}\t{percentage}\t{percentage}\t{10}\t{10}\t{10}\t{10}"; - BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.Curse, 1075835, 1075836, duration, m, args)); + (m as PlayerMobile)?.AddBuff(new BuffInfo(BuffIcon.Curse, 1075835, 1075836, duration, args)); return true; } diff --git a/Projects/UOContent/Spells/Gargoyle/SpellDefinitions/FlySpell.cs b/Projects/UOContent/Spells/Gargoyle/SpellDefinitions/FlySpell.cs index 6339be747..db7106524 100644 --- a/Projects/UOContent/Spells/Gargoyle/SpellDefinitions/FlySpell.cs +++ b/Projects/UOContent/Spells/Gargoyle/SpellDefinitions/FlySpell.cs @@ -1,4 +1,6 @@ using System; +using Server.Engines.BuffIcons; +using Server.Mobiles; namespace Server.Spells { @@ -55,11 +57,10 @@ namespace Server.Spells public override void OnCast() { Caster.Flying = false; - BuffInfo.RemoveBuff(Caster, BuffIcon.Fly); Caster.Animate(60, 10, 1, true, false, 0); Caster.SendLocalizedMessage(1112567); // You are flying. Caster.Flying = true; - BuffInfo.AddBuff(Caster, new BuffInfo(BuffIcon.Fly, 1112567)); + (Caster as PlayerMobile)?.AddBuff(new BuffInfo(BuffIcon.Fly, 1112567)); FinishSequence(); } } diff --git a/Projects/UOContent/Spells/Mysticism/CleansingWindsSpell.cs b/Projects/UOContent/Spells/Mysticism/CleansingWindsSpell.cs index c871dd9b8..dbb9011c0 100644 --- a/Projects/UOContent/Spells/Mysticism/CleansingWindsSpell.cs +++ b/Projects/UOContent/Spells/Mysticism/CleansingWindsSpell.cs @@ -4,6 +4,8 @@ using Server.Spells.Fourth; using Server.Spells.Necromancy; using Server.Targeting; using Server.Collections; +using Server.Engines.BuffIcons; +using Server.Mobiles; namespace Server.Spells.Mysticism; @@ -198,15 +200,18 @@ public class CleansingWindsSpell : MysticSpell, ITargetingSpell curseLevel += 2; } - BuffInfo.RemoveBuff(m, BuffIcon.Clumsy); - BuffInfo.RemoveBuff(m, BuffIcon.FeebleMind); - BuffInfo.RemoveBuff(m, BuffIcon.Weaken); - BuffInfo.RemoveBuff(m, BuffIcon.Curse); - BuffInfo.RemoveBuff(m, BuffIcon.MassCurse); - BuffInfo.RemoveBuff(m, BuffIcon.MortalStrike); - BuffInfo.RemoveBuff(m, BuffIcon.CorpseSkin); - BuffInfo.RemoveBuff(m, BuffIcon.Strangle); - BuffInfo.RemoveBuff(m, BuffIcon.EvilOmen); + if (m is PlayerMobile pm) + { + pm.RemoveBuff(BuffIcon.Clumsy); + pm.RemoveBuff(BuffIcon.FeebleMind); + pm.RemoveBuff(BuffIcon.Weaken); + pm.RemoveBuff(BuffIcon.Curse); + pm.RemoveBuff(BuffIcon.MassCurse); + pm.RemoveBuff(BuffIcon.MortalStrike); + pm.RemoveBuff(BuffIcon.CorpseSkin); + pm.RemoveBuff(BuffIcon.Strangle); + pm.RemoveBuff(BuffIcon.EvilOmen); + } return curseLevel; } diff --git a/Projects/UOContent/Spells/Mysticism/SpellPlagueSpell.cs b/Projects/UOContent/Spells/Mysticism/SpellPlagueSpell.cs index f1ed5d675..266b2f6cc 100644 --- a/Projects/UOContent/Spells/Mysticism/SpellPlagueSpell.cs +++ b/Projects/UOContent/Spells/Mysticism/SpellPlagueSpell.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using ModernUO.CodeGeneratedEvents; +using Server.Engines.BuffIcons; using Server.Mobiles; using Server.Targeting; @@ -78,7 +79,7 @@ public class SpellPlagueSpell : MysticSpell, ITargetingSpell if (_table.Remove(m, out var timer)) { timer.Stop(); - BuffInfo.RemoveBuff(m, BuffIcon.SpellPlague); + (m as PlayerMobile)?.RemoveBuff(BuffIcon.SpellPlague); return true; } @@ -129,9 +130,8 @@ public class SpellPlagueSpell : MysticSpell, ITargetingSpell public void StartPlague() { - BuffInfo.AddBuff( - _target, - new BuffInfo(BuffIcon.SpellPlague, 1031690, 1080167, TimeSpan.FromSeconds(8.5), _target) + (_target as PlayerMobile)?.AddBuff( + new BuffInfo(BuffIcon.SpellPlague, 1031690, 1080167, TimeSpan.FromSeconds(8.5)) ); _nextExplosion = Core.Now + TimeSpan.FromSeconds(1); @@ -184,7 +184,7 @@ public class SpellPlagueSpell : MysticSpell, ITargetingSpell else { _table.Remove(_target); - BuffInfo.RemoveBuff(_target, BuffIcon.SpellPlague); + (_target as PlayerMobile)?.RemoveBuff(BuffIcon.SpellPlague); } _next = null; diff --git a/Projects/UOContent/Spells/Mysticism/StoneFormSpell.cs b/Projects/UOContent/Spells/Mysticism/StoneFormSpell.cs index 60ad336c5..eca4ba1e9 100644 --- a/Projects/UOContent/Spells/Mysticism/StoneFormSpell.cs +++ b/Projects/UOContent/Spells/Mysticism/StoneFormSpell.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using ModernUO.CodeGeneratedEvents; +using Server.Engines.BuffIcons; using Server.Factions; using Server.Mobiles; using Server.Spells.Fifth; @@ -118,14 +119,12 @@ namespace Server.Spells.Mysticism var damageBonus = (int)((GetBaseSkill(Caster) + GetDamageSkill(Caster)) / 12.0); var resistCap = (int)((GetBaseSkill(Caster) + GetDamageSkill(Caster)) / 48.0); - BuffInfo.AddBuff( - Caster, + (Caster as PlayerMobile)?.AddBuff( new BuffInfo( BuffIcon.StoneForm, 1080145, 1080146, - $"-10\t-2\t{offset}\t{resistCap}\t{damageBonus}", - false + args: $"-10\t-2\t{offset}\t{resistCap}\t{damageBonus}" ) ); } @@ -151,7 +150,7 @@ namespace Server.Spells.Mysticism m.BodyMod = 0; m.HueMod = -1; - BuffInfo.RemoveBuff(m, BuffIcon.StoneForm); + (m as PlayerMobile)?.RemoveBuff(BuffIcon.StoneForm); } } } diff --git a/Projects/UOContent/Spells/Necromancy/BloodOathSpell.cs b/Projects/UOContent/Spells/Necromancy/BloodOathSpell.cs index bc3903dd3..847b3dbd7 100644 --- a/Projects/UOContent/Spells/Necromancy/BloodOathSpell.cs +++ b/Projects/UOContent/Spells/Necromancy/BloodOathSpell.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using Server.Engines.BuffIcons; using Server.Mobiles; using Server.Targeting; @@ -86,8 +87,8 @@ public class BloodOathSpell : NecromancerSpell, ITargetingSpell var timer = new ExpireTimer(Caster, m, duration); timer.Start(); - BuffInfo.AddBuff(Caster, new BuffInfo(BuffIcon.BloodOathCaster, 1075659, duration, Caster, m.Name)); - BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.BloodOathCurse, 1075661, duration, m, Caster.Name)); + (Caster as PlayerMobile)?.AddBuff(new BuffInfo(BuffIcon.BloodOathCaster, 1075659, duration, m.Name)); + (m as PlayerMobile)?.AddBuff(new BuffInfo(BuffIcon.BloodOathCurse, 1075661, duration, Caster.Name)); _table[m] = timer; HarmfulSpell(m); @@ -119,8 +120,8 @@ public class BloodOathSpell : NecromancerSpell, ITargetingSpell timer.Stop(); - BuffInfo.RemoveBuff(caster, BuffIcon.BloodOathCaster); - BuffInfo.RemoveBuff(target, BuffIcon.BloodOathCurse); + (caster as PlayerMobile)?.RemoveBuff(BuffIcon.BloodOathCaster); + (target as PlayerMobile)?.RemoveBuff(BuffIcon.BloodOathCurse); return true; } diff --git a/Projects/UOContent/Spells/Necromancy/CorpseSkin.cs b/Projects/UOContent/Spells/Necromancy/CorpseSkin.cs index 74f81eb1c..5f9ad6ba7 100644 --- a/Projects/UOContent/Spells/Necromancy/CorpseSkin.cs +++ b/Projects/UOContent/Spells/Necromancy/CorpseSkin.cs @@ -1,5 +1,7 @@ using System; using System.Collections.Generic; +using Server.Engines.BuffIcons; +using Server.Mobiles; using Server.Targeting; namespace Server.Spells.Necromancy; @@ -80,7 +82,7 @@ public class CorpseSkinSpell : NecromancerSpell, ITargetingSpell timer = new ExpireTimer(m, mods, duration); timer.Start(); - BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.CorpseSkin, 1075663, duration, m)); + (m as PlayerMobile)?.AddBuff(new BuffInfo(BuffIcon.CorpseSkin, 1075663, duration)); _table[m] = timer; @@ -129,7 +131,7 @@ public class CorpseSkinSpell : NecromancerSpell, ITargetingSpell } Stop(); - BuffInfo.RemoveBuff(_mobile, BuffIcon.CorpseSkin); + (_mobile as PlayerMobile)?.RemoveBuff(BuffIcon.CorpseSkin); _table.Remove(_mobile); } diff --git a/Projects/UOContent/Spells/Necromancy/EvilOmen.cs b/Projects/UOContent/Spells/Necromancy/EvilOmen.cs index b515fc736..f87db36e4 100644 --- a/Projects/UOContent/Spells/Necromancy/EvilOmen.cs +++ b/Projects/UOContent/Spells/Necromancy/EvilOmen.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using Server.Engines.BuffIcons; using Server.Mobiles; using Server.Targeting; @@ -64,7 +65,7 @@ public class EvilOmenSpell : NecromancerSpell, ITargetingSpell HarmfulSpell(m); - BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.EvilOmen, 1075647, 1075648, duration, m)); + (m as PlayerMobile)?.AddBuff(new BuffInfo(BuffIcon.EvilOmen, 1075647, 1075648, duration)); } } diff --git a/Projects/UOContent/Spells/Necromancy/MindRot.cs b/Projects/UOContent/Spells/Necromancy/MindRot.cs index 9d32af258..8ec5758a8 100644 --- a/Projects/UOContent/Spells/Necromancy/MindRot.cs +++ b/Projects/UOContent/Spells/Necromancy/MindRot.cs @@ -1,5 +1,7 @@ using System; using System.Collections.Generic; +using Server.Engines.BuffIcons; +using Server.Mobiles; using Server.Targeting; namespace Server.Spells.Necromancy; @@ -72,7 +74,7 @@ public class MindRotSpell : NecromancerSpell, ITargetingSpell { timer.Stop(); m.SendLocalizedMessage(1060872); // Your mind feels normal again. - BuffInfo.RemoveBuff(m, BuffIcon.Mindrot); + (m as PlayerMobile)?.RemoveBuff(BuffIcon.Mindrot); return true; } @@ -101,7 +103,7 @@ public class MindRotSpell : NecromancerSpell, ITargetingSpell timer.Start(); _table[target] = timer; - BuffInfo.AddBuff(target, new BuffInfo(BuffIcon.Mindrot, 1075665, duration, target)); + (target as PlayerMobile)?.AddBuff(new BuffInfo(BuffIcon.Mindrot, 1075665, duration)); target.SendLocalizedMessage(1074384); } } diff --git a/Projects/UOContent/Spells/Necromancy/PainSpike.cs b/Projects/UOContent/Spells/Necromancy/PainSpike.cs index b3623ce48..eca3bd275 100644 --- a/Projects/UOContent/Spells/Necromancy/PainSpike.cs +++ b/Projects/UOContent/Spells/Necromancy/PainSpike.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; +using Server.Engines.BuffIcons; using Server.Misc; +using Server.Mobiles; using Server.Targeting; namespace Server.Spells.Necromancy; @@ -70,7 +72,7 @@ public class PainSpikeSpell : NecromancerSpell, ITargetingSpell buffTime = timer.Next - Core.Now; } - BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.PainSpike, 1075667, buffTime, m, Convert.ToString((int)damage))); + (m as PlayerMobile)?.AddBuff(new BuffInfo(BuffIcon.PainSpike, 1075667, buffTime, Convert.ToString((int)damage))); // TODO: Find a better way to do this StaminaSystem.DFA = DFAlgorithm.PainSpike; @@ -109,7 +111,7 @@ public class PainSpikeSpell : NecromancerSpell, ITargetingSpell _mobile.Hits += _toRestore; } - BuffInfo.RemoveBuff(_mobile, BuffIcon.PainSpike); + (_mobile as PlayerMobile)?.RemoveBuff(BuffIcon.PainSpike); } } } diff --git a/Projects/UOContent/Spells/Necromancy/Strangle.cs b/Projects/UOContent/Spells/Necromancy/Strangle.cs index 1e9f7d1d2..1b4a0465d 100644 --- a/Projects/UOContent/Spells/Necromancy/Strangle.cs +++ b/Projects/UOContent/Spells/Necromancy/Strangle.cs @@ -1,5 +1,7 @@ using System; using System.Collections.Generic; +using Server.Engines.BuffIcons; +using Server.Mobiles; using Server.Targeting; namespace Server.Spells.Necromancy; @@ -96,7 +98,7 @@ public class StrangleSpell : NecromancerSpell, ITargetingSpell var maxDamage = ((int)power + 1) * 3; var args = $"{minDamage}\t{maxDamage}"; - BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.Strangle, 1075794, 1075795, duration, m, args)); + (m as PlayerMobile)?.AddBuff(new BuffInfo(BuffIcon.Strangle, 1075794, 1075795, duration, args)); } } diff --git a/Projects/UOContent/Spells/Second/Agility.cs b/Projects/UOContent/Spells/Second/Agility.cs index 73ef9c554..ed0c7ef6c 100644 --- a/Projects/UOContent/Spells/Second/Agility.cs +++ b/Projects/UOContent/Spells/Second/Agility.cs @@ -1,4 +1,6 @@ +using Server.Engines.BuffIcons; using Server.Engines.ConPVP; +using Server.Mobiles; using Server.Targeting; namespace Server.Spells.Second @@ -34,7 +36,7 @@ namespace Server.Spells.Second var percentage = (int)(SpellHelper.GetOffsetScalar(Caster, m, false) * 100); - BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.Agility, 1075841, length, m, percentage.ToString())); + (m as PlayerMobile)?.AddBuff(new BuffInfo(BuffIcon.Agility, 1075841, length, percentage.ToString())); } } diff --git a/Projects/UOContent/Spells/Second/Cunning.cs b/Projects/UOContent/Spells/Second/Cunning.cs index d44881640..fefc40a0e 100644 --- a/Projects/UOContent/Spells/Second/Cunning.cs +++ b/Projects/UOContent/Spells/Second/Cunning.cs @@ -1,4 +1,6 @@ +using Server.Engines.BuffIcons; using Server.Engines.ConPVP; +using Server.Mobiles; using Server.Targeting; namespace Server.Spells.Second @@ -34,7 +36,7 @@ namespace Server.Spells.Second var percentage = (int)(SpellHelper.GetOffsetScalar(Caster, m, false) * 100); - BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.Cunning, 1075843, length, m, percentage.ToString())); + (m as PlayerMobile)?.AddBuff(new BuffInfo(BuffIcon.Cunning, 1075843, length, percentage.ToString())); } } diff --git a/Projects/UOContent/Spells/Second/Protection.cs b/Projects/UOContent/Spells/Second/Protection.cs index 460990bc8..0d4ceca48 100644 --- a/Projects/UOContent/Spells/Second/Protection.cs +++ b/Projects/UOContent/Spells/Second/Protection.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using ModernUO.CodeGeneratedEvents; +using Server.Engines.BuffIcons; using Server.Mobiles; namespace Server.Spells.Second @@ -72,7 +73,7 @@ namespace Server.Spells.Second target.RemoveResistanceMod(mods.Item1); target.RemoveSkillMod(mods.Item2); - BuffInfo.RemoveBuff(target, BuffIcon.Protection); + (target as PlayerMobile)?.RemoveBuff(BuffIcon.Protection); } else { @@ -91,7 +92,7 @@ namespace Server.Spells.Second target.AddSkillMod(resistMod); var args = $"{physLoss}\t{resistLoss}"; - BuffInfo.AddBuff(target, new BuffInfo(BuffIcon.Protection, 1075814, 1075815, args)); + (target as PlayerMobile)?.AddBuff(new BuffInfo(BuffIcon.Protection, 1075814, 1075815, args: args)); } } @@ -108,7 +109,7 @@ namespace Server.Spells.Second m.RemoveResistanceMod(mods.Item1); m.RemoveSkillMod(mods.Item2); - BuffInfo.RemoveBuff(m, BuffIcon.Protection); + (m as PlayerMobile)?.RemoveBuff(BuffIcon.Protection); } public override void OnCast() diff --git a/Projects/UOContent/Spells/Second/Strength.cs b/Projects/UOContent/Spells/Second/Strength.cs index 82d5dff13..3f0f978ae 100644 --- a/Projects/UOContent/Spells/Second/Strength.cs +++ b/Projects/UOContent/Spells/Second/Strength.cs @@ -1,4 +1,6 @@ +using Server.Engines.BuffIcons; using Server.Engines.ConPVP; +using Server.Mobiles; using Server.Targeting; namespace Server.Spells.Second @@ -34,7 +36,7 @@ namespace Server.Spells.Second var percentage = (int)(SpellHelper.GetOffsetScalar(Caster, m, false) * 100); - BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.Strength, 1075845, length, m, percentage.ToString())); + (m as PlayerMobile)?.AddBuff(new BuffInfo(BuffIcon.Strength, 1075845, length, percentage.ToString())); } } diff --git a/Projects/UOContent/Spells/Sixth/Invisibility.cs b/Projects/UOContent/Spells/Sixth/Invisibility.cs index 916707bcb..21ca2d302 100644 --- a/Projects/UOContent/Spells/Sixth/Invisibility.cs +++ b/Projects/UOContent/Spells/Sixth/Invisibility.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using Server.Engines.BuffIcons; using Server.Engines.ConPVP; using Server.Items; using Server.Mobiles; @@ -53,8 +54,11 @@ namespace Server.Spells.Sixth var duration = TimeSpan.FromSeconds(1.2 * Caster.Skills.Magery.Value); - BuffInfo.RemoveBuff(m, BuffIcon.HidingAndOrStealth); - BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.Invisibility, 1075825, duration, m)); // Invisibility/Invisible + if (m is PlayerMobile pm) + { + pm.RemoveBuff(BuffIcon.HidingAndOrStealth); + pm.AddBuff(new BuffInfo(BuffIcon.Invisibility, 1075825, duration)); // Invisibility/Invisible + } Timer.StartTimer(duration, () => diff --git a/Projects/UOContent/Spells/Spellweaving/AttuneWeapon.cs b/Projects/UOContent/Spells/Spellweaving/AttuneWeapon.cs index aa898843c..64dd6e705 100644 --- a/Projects/UOContent/Spells/Spellweaving/AttuneWeapon.cs +++ b/Projects/UOContent/Spells/Spellweaving/AttuneWeapon.cs @@ -1,5 +1,7 @@ using System; using System.Collections.Generic; +using Server.Engines.BuffIcons; +using Server.Mobiles; namespace Server.Spells.Spellweaving { @@ -62,9 +64,8 @@ namespace Server.Spells.Spellweaving Caster.BeginAction(); - BuffInfo.AddBuff( - Caster, - new BuffInfo(BuffIcon.AttuneWeapon, 1075798, duration, Caster, damageAbsorb.ToString()) + (Caster as PlayerMobile)?.AddBuff( + new BuffInfo(BuffIcon.AttuneWeapon, 1075798, duration, damageAbsorb.ToString()) ); } @@ -130,7 +131,7 @@ namespace Server.Spells.Spellweaving _table.Remove(m_Mobile); StartTimer(TimeSpan.FromSeconds(120), m_Mobile.EndAction); - BuffInfo.RemoveBuff(m_Mobile, BuffIcon.AttuneWeapon); + (m_Mobile as PlayerMobile)?.RemoveBuff(BuffIcon.AttuneWeapon); } } } diff --git a/Projects/UOContent/Spells/Spellweaving/EssenceOfWind.cs b/Projects/UOContent/Spells/Spellweaving/EssenceOfWind.cs index 75debc119..6a85c317c 100644 --- a/Projects/UOContent/Spells/Spellweaving/EssenceOfWind.cs +++ b/Projects/UOContent/Spells/Spellweaving/EssenceOfWind.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; using Server.Collections; +using Server.Engines.BuffIcons; +using Server.Mobiles; namespace Server.Spells.Spellweaving { @@ -63,9 +65,8 @@ namespace Server.Spells.Spellweaving _table[m] = t; - BuffInfo.AddBuff( - m, - new BuffInfo(BuffIcon.EssenceOfWind, 1075802, duration, m, $"{fcMalus}\t{ssiMalus}") + (m as PlayerMobile)?.AddBuff( + new BuffInfo(BuffIcon.EssenceOfWind, 1075802, duration, $"{fcMalus}\t{ssiMalus}") ); } } @@ -110,7 +111,7 @@ namespace Server.Spells.Spellweaving Stop(); _table.Remove(_defender); - BuffInfo.RemoveBuff(_defender, BuffIcon.EssenceOfWind); + (_defender as PlayerMobile)?.RemoveBuff(BuffIcon.EssenceOfWind); } } } diff --git a/Projects/UOContent/Spells/Spellweaving/EtherealVoyage.cs b/Projects/UOContent/Spells/Spellweaving/EtherealVoyage.cs index 6d2aa6bee..5a033b14d 100644 --- a/Projects/UOContent/Spells/Spellweaving/EtherealVoyage.cs +++ b/Projects/UOContent/Spells/Spellweaving/EtherealVoyage.cs @@ -1,4 +1,6 @@ using System; +using Server.Engines.BuffIcons; +using Server.Mobiles; namespace Server.Spells.Spellweaving { @@ -71,7 +73,7 @@ namespace Server.Spells.Spellweaving // Cannot cast this spell for another 5 minutes(300sec) after effect removed. Caster.BeginAction(); - BuffInfo.AddBuff(Caster, new BuffInfo(BuffIcon.EtherealVoyage, 1031613, 1075805, duration, Caster)); + (Caster as PlayerMobile)?.AddBuff(new BuffInfo(BuffIcon.EtherealVoyage, 1031613, 1075805, duration)); } public override void RemoveEffect(Mobile m) @@ -82,7 +84,7 @@ namespace Server.Spells.Spellweaving Timer.StartTimer(TimeSpan.FromMinutes(5), m.EndAction); - BuffInfo.RemoveBuff(m, BuffIcon.EtherealVoyage); + (m as PlayerMobile)?.RemoveBuff(BuffIcon.EtherealVoyage); } } } diff --git a/Projects/UOContent/Spells/Spellweaving/GiftOfLife.cs b/Projects/UOContent/Spells/Spellweaving/GiftOfLife.cs index 7118854b7..585d37284 100644 --- a/Projects/UOContent/Spells/Spellweaving/GiftOfLife.cs +++ b/Projects/UOContent/Spells/Spellweaving/GiftOfLife.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using ModernUO.CodeGeneratedEvents; +using Server.Engines.BuffIcons; using Server.Gumps; using Server.Mobiles; using Server.Targeting; @@ -67,7 +68,9 @@ namespace Server.Spells.Spellweaving _table[m] = t; - BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.GiftOfLife, 1031615, 1075807, duration, m, null, true)); + (m as PlayerMobile)?.AddBuff( + new BuffInfo(BuffIcon.GiftOfLife, 1031615, 1075807, duration, retainThroughDeath: true) + ); } } @@ -152,7 +155,7 @@ namespace Server.Spells.Spellweaving _mobile.SendLocalizedMessage(1074776); // You are no longer protected with Gift of Life. _table.Remove(_mobile); - BuffInfo.RemoveBuff(_mobile, BuffIcon.GiftOfLife); + (_mobile as PlayerMobile)?.RemoveBuff(BuffIcon.GiftOfLife); } } } diff --git a/Projects/UOContent/Spells/Spellweaving/GiftOfRenewal.cs b/Projects/UOContent/Spells/Spellweaving/GiftOfRenewal.cs index 557367e71..11f21993c 100644 --- a/Projects/UOContent/Spells/Spellweaving/GiftOfRenewal.cs +++ b/Projects/UOContent/Spells/Spellweaving/GiftOfRenewal.cs @@ -1,5 +1,7 @@ using System; using System.Collections.Generic; +using Server.Engines.BuffIcons; +using Server.Mobiles; using Server.Targeting; namespace Server.Spells.Spellweaving @@ -59,9 +61,14 @@ namespace Server.Spells.Spellweaving Caster.BeginAction(); - BuffInfo.AddBuff( - m, - new BuffInfo(BuffIcon.GiftOfRenewal, 1031602, 1075797, TimeSpan.FromSeconds(duration), m, hitsPerRound.ToString()) + (m as PlayerMobile)?.AddBuff( + new BuffInfo( + BuffIcon.GiftOfRenewal, + 1031602, + 1075797, + TimeSpan.FromSeconds(duration), + hitsPerRound.ToString() + ) ); } } @@ -74,7 +81,7 @@ namespace Server.Spells.Spellweaving public static bool StopEffect(Mobile m) { - BuffInfo.RemoveBuff(m, BuffIcon.GiftOfRenewal); + (m as PlayerMobile)?.RemoveBuff(BuffIcon.GiftOfRenewal); if (_table.Remove(m, out var timer)) { diff --git a/Projects/UOContent/Spells/Spellweaving/Thunderstorm.cs b/Projects/UOContent/Spells/Spellweaving/Thunderstorm.cs index 14de37d65..0096d3dbf 100644 --- a/Projects/UOContent/Spells/Spellweaving/Thunderstorm.cs +++ b/Projects/UOContent/Spells/Spellweaving/Thunderstorm.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; using Server.Collections; +using Server.Engines.BuffIcons; +using Server.Mobiles; namespace Server.Spells.Spellweaving { @@ -72,9 +74,8 @@ namespace Server.Spells.Spellweaving Timer.StartTimer(duration, () => DoExpire(m), out var timerToken); _table[m] = timerToken; - BuffInfo.AddBuff( - m, - new BuffInfo(BuffIcon.Thunderstorm, 1075800, duration, m, GetCastRecoveryMalus(m)) + (m as PlayerMobile)?.AddBuff( + new BuffInfo(BuffIcon.Thunderstorm, 1075800, duration, GetCastRecoveryMalus(m)) ); } } @@ -95,7 +96,7 @@ namespace Server.Spells.Spellweaving public static void DoExpire(Mobile m) { StopTimer(m); - BuffInfo.RemoveBuff(m, BuffIcon.Thunderstorm); + (m as PlayerMobile)?.RemoveBuff(BuffIcon.Thunderstorm); } } } diff --git a/Projects/UOContent/Spells/Third/Bless.cs b/Projects/UOContent/Spells/Third/Bless.cs index 9cb2f16aa..de23ad93e 100644 --- a/Projects/UOContent/Spells/Third/Bless.cs +++ b/Projects/UOContent/Spells/Third/Bless.cs @@ -1,4 +1,6 @@ +using Server.Engines.BuffIcons; using Server.Engines.ConPVP; +using Server.Mobiles; using Server.Targeting; namespace Server.Spells.Third @@ -38,7 +40,7 @@ namespace Server.Spells.Third var args = $"{percentage}\t{percentage}\t{percentage}"; - BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.Bless, 1075847, 1075848, length, m, args)); + (m as PlayerMobile)?.AddBuff(new BuffInfo(BuffIcon.Bless, 1075847, 1075848, length, args)); } }