diff --git a/Projects/UOContent/Items/Misc/Blighted Grove/MelisandesFermentedWine.cs b/Projects/UOContent/Items/Misc/Blighted Grove/MelisandesFermentedWine.cs index 92f18247a..be364fca2 100644 --- a/Projects/UOContent/Items/Misc/Blighted Grove/MelisandesFermentedWine.cs +++ b/Projects/UOContent/Items/Misc/Blighted Grove/MelisandesFermentedWine.cs @@ -22,13 +22,7 @@ public partial class MelisandesFermentedWine : GreaterExplosionPotion public override int LabelNumber => 1072114; // Melisande's Fermented Wine - public override void Drink(Mobile from) - { - if (MondainsLegacy.CheckML(from)) - { - base.Drink(from); - } - } + public override bool CanDrink(Mobile from) => MondainsLegacy.CheckML(from) && base.CanDrink(from); public override void GetProperties(IPropertyList list) { diff --git a/Projects/UOContent/Items/Skill Items/Magical/Potions/Agility Potions/BaseAgilityPotion.cs b/Projects/UOContent/Items/Skill Items/Magical/Potions/Agility Potions/BaseAgilityPotion.cs index ff886b9c9..7c914206b 100644 --- a/Projects/UOContent/Items/Skill Items/Magical/Potions/Agility Potions/BaseAgilityPotion.cs +++ b/Projects/UOContent/Items/Skill Items/Magical/Potions/Agility Potions/BaseAgilityPotion.cs @@ -14,25 +14,27 @@ public abstract partial class BaseAgilityPotion : BasePotion public abstract int DexOffset { get; } public abstract TimeSpan Duration { get; } - public bool DoAgility(Mobile from) + public override bool CanDrink(Mobile from) { - // TODO: Verify scaled; is it offset, duration, or both? - if (SpellHelper.AddStatOffset(from, StatType.Dex, Scale(from, DexOffset), Duration)) + if (!base.CanDrink(from)) { - from.FixedEffect(0x375A, 10, 15); - from.PlaySound(0x1E7); - return true; + return false; } - from.SendLocalizedMessage(502173); // You are already under a similar effect. - return false; + // TODO: Verify scaled; is it offset, duration, or both? + if (!SpellHelper.AddStatOffset(from, StatType.Dex, Scale(from, DexOffset), Duration)) + { + from.SendLocalizedMessage(502173); // You are already under a similar effect. + return false; + } + + from.FixedEffect(0x375A, 10, 15); + from.PlaySound(0x1E7); + return true; } public override void Drink(Mobile from) { - if (DoAgility(from)) - { - PlayDrinkEffect(from); - } + PlayDrinkEffect(from); } } diff --git a/Projects/UOContent/Items/Skill Items/Magical/Potions/BasePotion.cs b/Projects/UOContent/Items/Skill Items/Magical/Potions/BasePotion.cs index 54b6bfa6a..4c62b3771 100644 --- a/Projects/UOContent/Items/Skill Items/Magical/Potions/BasePotion.cs +++ b/Projects/UOContent/Items/Skill Items/Magical/Potions/BasePotion.cs @@ -129,23 +129,11 @@ public abstract partial class BasePotion : Item, ICraftable, ICommodity public override void OnDoubleClick(Mobile from) { - if (!Movable) + if (!CanDrink(from)) { return; } - if (!from.InRange(GetWorldLocation(), 1)) - { - from.SendLocalizedMessage(502138); // That is too far away for you to use - return; - } - - if (RequireFreeHand && !HasFreeHand(from)) - { - from.SendLocalizedMessage(502172); // You must have a free hand to drink a potion. - return; - } - var pot = this; if (IsThrowablePotion && Amount > 1) @@ -172,12 +160,33 @@ public abstract partial class BasePotion : Item, ICraftable, ICommodity _potionEffect = (PotionEffect)reader.ReadInt(); } + public virtual bool CanDrink(Mobile from) + { + if (!Movable) + { + return false; + } + + if (!from.InRange(GetWorldLocation(), 1)) + { + from.SendLocalizedMessage(502138); // That is too far away for you to use + return false; + } + + if (RequireFreeHand && !HasFreeHand(from)) + { + from.SendLocalizedMessage(502172); // You must have a free hand to drink a potion. + return false; + } + + return true; + } + public abstract void Drink(Mobile from); public void PlayDrinkEffect(Mobile m) { m.RevealingAction(); - m.PlaySound(0x2D6); if (!DuelContext.IsFreeConsume(m)) diff --git a/Projects/UOContent/Items/Skill Items/Magical/Potions/Conflagration Potions/BaseConflagrationPotion.cs b/Projects/UOContent/Items/Skill Items/Magical/Potions/Conflagration Potions/BaseConflagrationPotion.cs index 2927e795e..919b12a44 100644 --- a/Projects/UOContent/Items/Skill Items/Magical/Potions/Conflagration Potions/BaseConflagrationPotion.cs +++ b/Projects/UOContent/Items/Skill Items/Magical/Potions/Conflagration Potions/BaseConflagrationPotion.cs @@ -22,12 +22,17 @@ public abstract partial class BaseConflagrationPotion : BasePotion public override bool IsThrowablePotion => true; - public override void Drink(Mobile from) + public override bool CanDrink(Mobile from) { + if (!base.CanDrink(from)) + { + return false; + } + if (Core.AOS && (from.Paralyzed || from.Frozen || from.Spell?.IsCasting == true)) { from.SendLocalizedMessage(1062725); // You can not use that potion while paralyzed. - return; + return false; } var delay = GetDelay(from); @@ -36,14 +41,14 @@ public abstract partial class BaseConflagrationPotion : BasePotion { // You cannot use that for another ~1_NUM~ ~2_TIMEUNITS~ from.SendLocalizedMessage(1072529, $"{delay}\t{(delay > 1 ? "seconds." : "second.")}"); - return; + return false; } - if ((from.Target as ThrowTarget)?.Potion == this) - { - return; - } + return (from.Target as ThrowTarget)?.Potion != this; + } + public override void Drink(Mobile from) + { from.RevealingAction(); _users ??= []; diff --git a/Projects/UOContent/Items/Skill Items/Magical/Potions/Confusion Blast Potions/BaseConfusionBlastPotion.cs b/Projects/UOContent/Items/Skill Items/Magical/Potions/Confusion Blast Potions/BaseConfusionBlastPotion.cs index ff556019c..eb0236dad 100644 --- a/Projects/UOContent/Items/Skill Items/Magical/Potions/Confusion Blast Potions/BaseConfusionBlastPotion.cs +++ b/Projects/UOContent/Items/Skill Items/Magical/Potions/Confusion Blast Potions/BaseConfusionBlastPotion.cs @@ -23,12 +23,17 @@ public abstract partial class BaseConfusionBlastPotion : BasePotion public override bool IsThrowablePotion => true; - public override void Drink(Mobile from) + public override bool CanDrink(Mobile from) { + if (!base.CanDrink(from)) + { + return false; + } + if (Core.AOS && (from.Paralyzed || from.Frozen || from.Spell?.IsCasting == true)) { from.SendLocalizedMessage(1062725); // You can not use that potion while paralyzed. - return; + return false; } var delay = GetDelay(from); @@ -37,14 +42,14 @@ public abstract partial class BaseConfusionBlastPotion : BasePotion { // You cannot use that for another ~1_NUM~ ~2_TIMEUNITS~ from.SendLocalizedMessage(1072529, $"{delay}\t{(delay > 1 ? "seconds." : "second.")}"); - return; + return false; } - if ((from.Target as ThrowTarget)?.Potion == this) - { - return; - } + return (from.Target as ThrowTarget)?.Potion != this; + } + public override void Drink(Mobile from) + { from.RevealingAction(); _users ??= []; diff --git a/Projects/UOContent/Items/Skill Items/Magical/Potions/Cure Potions/BaseCurePotion.cs b/Projects/UOContent/Items/Skill Items/Magical/Potions/Cure Potions/BaseCurePotion.cs index 40b66ae38..10331b2e8 100644 --- a/Projects/UOContent/Items/Skill Items/Magical/Potions/Cure Potions/BaseCurePotion.cs +++ b/Projects/UOContent/Items/Skill Items/Magical/Potions/Cure Potions/BaseCurePotion.cs @@ -56,24 +56,35 @@ public abstract partial class BaseCurePotion : BasePotion } } - public override void Drink(Mobile from) + public override bool CanDrink(Mobile from) { + if (!base.CanDrink(from)) + { + return false; + } + if (TransformationSpellHelper.UnderTransformation(from, typeof(VampiricEmbraceSpell))) { from.SendLocalizedMessage(1061652); // The garlic in the potion would surely kill you. + return false; } - else if (from.Poisoned) - { - DoCure(from); - PlayDrinkEffect(from); - - from.FixedParticles(0x373A, 10, 15, 5012, EffectLayer.Waist); - from.PlaySound(0x1E0); - } - else + if (!from.Poisoned) { from.SendLocalizedMessage(1042000); // You are not poisoned. + return false; } + + return true; + } + + public override void Drink(Mobile from) + { + DoCure(from); + + PlayDrinkEffect(from); + + from.FixedParticles(0x373A, 10, 15, 5012, EffectLayer.Waist); + from.PlaySound(0x1E0); } } diff --git a/Projects/UOContent/Items/Skill Items/Magical/Potions/Explosion Potions/BaseExplosionPotion.cs b/Projects/UOContent/Items/Skill Items/Magical/Potions/Explosion Potions/BaseExplosionPotion.cs index bed396f2c..586c6a40d 100644 --- a/Projects/UOContent/Items/Skill Items/Magical/Potions/Explosion Potions/BaseExplosionPotion.cs +++ b/Projects/UOContent/Items/Skill Items/Magical/Potions/Explosion Potions/BaseExplosionPotion.cs @@ -51,22 +51,26 @@ public abstract partial class BaseExplosionPotion : BasePotion return this; } - public override void Drink(Mobile from) + public override bool CanDrink(Mobile from) { + if (!base.CanDrink(from)) + { + return false; + } + if (Core.AOS && (from.Paralyzed || from.Frozen || from.Spell?.IsCasting == true)) { from.SendLocalizedMessage(1062725); // You can not use a purple potion while paralyzed. - return; + return false; } - var targ = from.Target as ThrowTarget; + return (from.Target as ThrowTarget)?.Potion != this; + } + + public override void Drink(Mobile from) + { Stackable = false; // Scavenged explosion potions won't stack with those ones in backpack, and still will explode. - if (targ?.Potion == this) - { - return; - } - from.RevealingAction(); _users ??= []; diff --git a/Projects/UOContent/Items/Skill Items/Magical/Potions/Heal Potions/BaseHealPotion.cs b/Projects/UOContent/Items/Skill Items/Magical/Potions/Heal Potions/BaseHealPotion.cs index fa773b4f6..915f6f04a 100644 --- a/Projects/UOContent/Items/Skill Items/Magical/Potions/Heal Potions/BaseHealPotion.cs +++ b/Projects/UOContent/Items/Skill Items/Magical/Potions/Heal Potions/BaseHealPotion.cs @@ -22,29 +22,39 @@ public abstract partial class BaseHealPotion : BasePotion from.Heal(Utility.RandomMinMax(min, max)); } - public override void Drink(Mobile from) + public override bool CanDrink(Mobile from) { + if (!base.CanDrink(from)) + { + return false; + } + if (from.Hits >= from.HitsMax) { // You decide against drinking this potion, as you are already at full health. from.SendLocalizedMessage(1049547); - return; + return false; } if (from.Poisoned || MortalStrike.IsWounded(from)) { // You can not heal yourself in your current state. from.LocalOverheadMessage(MessageType.Regular, 0x22, 1005000); - return; + return false; } if (!from.BeginAction()) { // You must wait 10 seconds before using another healing potion. from.LocalOverheadMessage(MessageType.Regular, 0x22, 500235); - return; + return false; } + return true; + } + + public override void Drink(Mobile from) + { DoHeal(from); PlayDrinkEffect(from); diff --git a/Projects/UOContent/Items/Skill Items/Magical/Potions/InvisibilityPotion.cs b/Projects/UOContent/Items/Skill Items/Magical/Potions/InvisibilityPotion.cs index b498a2986..d3a2e4e5f 100644 --- a/Projects/UOContent/Items/Skill Items/Magical/Potions/InvisibilityPotion.cs +++ b/Projects/UOContent/Items/Skill Items/Magical/Potions/InvisibilityPotion.cs @@ -7,29 +7,39 @@ namespace Server.Items; [SerializationGenerator(0, false)] public partial class InvisibilityPotion : BasePotion { - private static readonly Dictionary m_Table = new(); + private static readonly Dictionary _table = new(); [Constructible] public InvisibilityPotion() : base(0xF0A, PotionEffect.Invisibility) => Hue = 0x48D; public override int LabelNumber => 1072941; // Potion of Invisibility - public override void Drink(Mobile from) + public override bool CanDrink(Mobile from) { + if (!base.CanDrink(from)) + { + return false; + } + if (from.Hidden) { from.SendLocalizedMessage(1073185); // You are already unseen. - return; + return false; } if (HasTimer(from)) { from.SendLocalizedMessage(1073186); // An invisibility potion is already taking effect on your person. - return; + return false; } + return true; + } + + public override void Drink(Mobile from) + { Timer.StartTimer(TimeSpan.FromSeconds(2), () => Hide(from), out var timerToken); - m_Table[from] = timerToken; + _table[from] = timerToken; PlayDrinkEffect(from); } @@ -61,11 +71,11 @@ public partial class InvisibilityPotion : BasePotion RemoveTimer(m); } - public static bool HasTimer(Mobile m) => m_Table.ContainsKey(m); + public static bool HasTimer(Mobile m) => _table.ContainsKey(m); public static void RemoveTimer(Mobile m, bool interrupted = false) { - if (m_Table.Remove(m, out var timer)) + if (_table.Remove(m, out var timer)) { if (interrupted) { diff --git a/Projects/UOContent/Items/Skill Items/Magical/Potions/NightSight.cs b/Projects/UOContent/Items/Skill Items/Magical/Potions/NightSight.cs index e7e68549b..d4f6942c5 100644 --- a/Projects/UOContent/Items/Skill Items/Magical/Potions/NightSight.cs +++ b/Projects/UOContent/Items/Skill Items/Magical/Potions/NightSight.cs @@ -10,21 +10,30 @@ public partial class NightSightPotion : BasePotion { } + public override bool CanDrink(Mobile from) + { + if (!base.CanDrink(from)) + { + return false; + } + + if (!from.BeginAction()) + { + from.SendMessage("You already have night sight."); + return false; + } + + return true; + } + public override void Drink(Mobile from) { - if (from.BeginAction()) - { - new LightCycle.NightSightTimer(from).Start(); - from.LightLevel = LightCycle.DungeonLevel / 2; + new LightCycle.NightSightTimer(from).Start(); + from.LightLevel = LightCycle.DungeonLevel / 2; - from.FixedParticles(0x376A, 9, 32, 5007, EffectLayer.Waist); - from.PlaySound(0x1E3); + from.FixedParticles(0x376A, 9, 32, 5007, EffectLayer.Waist); + from.PlaySound(0x1E3); - PlayDrinkEffect(from); - } - else - { - from.SendMessage("You already have nightsight."); - } + PlayDrinkEffect(from); } } diff --git a/Projects/UOContent/Items/Skill Items/Magical/Potions/Refresh Potions/BaseRefreshPotion.cs b/Projects/UOContent/Items/Skill Items/Magical/Potions/Refresh Potions/BaseRefreshPotion.cs index 528ee2e0b..ff24c4e4b 100644 --- a/Projects/UOContent/Items/Skill Items/Magical/Potions/Refresh Potions/BaseRefreshPotion.cs +++ b/Projects/UOContent/Items/Skill Items/Magical/Potions/Refresh Potions/BaseRefreshPotion.cs @@ -11,17 +11,26 @@ public abstract partial class BaseRefreshPotion : BasePotion public abstract double Refresh { get; } - public override void Drink(Mobile from) + public override bool CanDrink(Mobile from) { - if (from.Stam < from.StamMax) + if (!base.CanDrink(from)) { - from.Stam += Scale(from, (int)(Refresh * from.StamMax)); - - PlayDrinkEffect(from); + return false; } - else + + if (from.Stam >= from.StamMax) { from.SendMessage("You decide against drinking this potion, as you are already at full stamina."); + return false; } + + return true; + } + + public override void Drink(Mobile from) + { + from.Stam += Scale(from, (int)(Refresh * from.StamMax)); + + PlayDrinkEffect(from); } } diff --git a/Projects/UOContent/Items/Skill Items/Magical/Potions/Strength Potions/BaseStrengthPotion.cs b/Projects/UOContent/Items/Skill Items/Magical/Potions/Strength Potions/BaseStrengthPotion.cs index dc6cdcef1..a251a2a48 100644 --- a/Projects/UOContent/Items/Skill Items/Magical/Potions/Strength Potions/BaseStrengthPotion.cs +++ b/Projects/UOContent/Items/Skill Items/Magical/Potions/Strength Potions/BaseStrengthPotion.cs @@ -14,8 +14,13 @@ public abstract partial class BaseStrengthPotion : BasePotion public abstract int StrOffset { get; } public abstract TimeSpan Duration { get; } - public bool DoStrength(Mobile from) + public bool CanDrink(Mobile from) { + if (!base.CanDrink(from)) + { + return false; + } + // TODO: Verify scaled; is it offset, duration, or both? if (SpellHelper.AddStatOffset(from, StatType.Str, Scale(from, StrOffset), Duration)) { @@ -30,9 +35,6 @@ public abstract partial class BaseStrengthPotion : BasePotion public override void Drink(Mobile from) { - if (DoStrength(from)) - { - PlayDrinkEffect(from); - } + PlayDrinkEffect(from); } }