using System; using Server.Engines.ConPVP; using Server.Items; using Server.Misc; using Server.Targeting; namespace Server.SkillHandlers { public static class Poisoning { public static void Initialize() { SkillInfo.Table[(int)SkillName.Poisoning].Callback = OnUse; } public static TimeSpan OnUse(Mobile m) { m.Target = new InternalTargetPoison(); m.SendLocalizedMessage(502137); // Select the poison you wish to use return TimeSpan.FromSeconds(10.0); // 10 second delay before being able to re-use a skill } private class InternalTargetPoison : Target { public InternalTargetPoison() : base(2, false, TargetFlags.None) { } protected override void OnTarget(Mobile from, object targeted) { if (targeted is BasePoisonPotion potion) { from.SendLocalizedMessage(502142); // To what do you wish to apply the poison? from.Target = new InternalTarget(potion); } else // Not a Poison Potion { from.SendLocalizedMessage(502139); // That is not a poison potion. } } private class InternalTarget : Target { private readonly BasePoisonPotion m_Potion; public InternalTarget(BasePoisonPotion potion) : base(2, false, TargetFlags.None) => m_Potion = potion; protected override void OnTarget(Mobile from, object targeted) { if (m_Potion.Deleted) { return; } var startTimer = false; if (targeted is Food or FukiyaDarts or Shuriken) { startTimer = true; } else if (targeted is BaseWeapon weapon) { if (Core.AOS) { startTimer = weapon.PrimaryAbility == WeaponAbility.InfectiousStrike || weapon.SecondaryAbility == WeaponAbility.InfectiousStrike; } else if (weapon.Layer == Layer.OneHanded) { startTimer = weapon.Type is WeaponType.Slashing or WeaponType.Piercing; } } if (startTimer) { new InternalTimer(from, (Item)targeted, m_Potion).Start(); from.PlaySound(0x4F); if (!DuelContext.IsFreeConsume(from)) { m_Potion.Consume(); from.AddToBackpack(new Bottle()); } } else // Target can't be poisoned { if (Core.AOS) { from.SendLocalizedMessage( 1060204 ); // You cannot poison that! You can only poison infectious weapons, food or drink. } else { from.SendLocalizedMessage( 502145 ); // You cannot poison that! You can only poison bladed or piercing weapons, food or drink. } } } private class InternalTimer : Timer { private readonly Mobile m_From; private readonly double m_MaxSkill; private readonly double m_MinSkill; private readonly Poison m_Poison; private readonly Item m_Target; public InternalTimer(Mobile from, Item target, BasePoisonPotion potion) : base(TimeSpan.FromSeconds(2.0)) { m_From = from; m_Target = target; m_Poison = potion.Poison; m_MinSkill = potion.MinPoisoningSkill; m_MaxSkill = potion.MaxPoisoningSkill; } protected override void OnTick() { if (m_From.CheckTargetSkill(SkillName.Poisoning, m_Target, m_MinSkill, m_MaxSkill)) { if (m_Target is Food food) { food.Poison = m_Poison; } else if (m_Target is BaseWeapon weapon) { weapon.Poison = m_Poison; weapon.PoisonCharges = 18 - m_Poison.Level * 2; } else if (m_Target is FukiyaDarts darts) { darts.Poison = m_Poison; darts.PoisonCharges = Math.Min( 18 - m_Poison.Level * 2, darts.UsesRemaining ); } else if (m_Target is Shuriken shuriken) { shuriken.Poison = m_Poison; shuriken.PoisonCharges = Math.Min( 18 - m_Poison.Level * 2, shuriken.UsesRemaining ); } m_From.SendLocalizedMessage(1010517); // You apply the poison Titles.AwardKarma(m_From, -20, true); } else // Failed { // 5% of chance of getting poisoned if failed if (m_From.Skills.Poisoning.Base < 80.0 && Utility.Random(20) == 0) { m_From.SendLocalizedMessage(502148); // You make a grave mistake while applying the poison. m_From.ApplyPoison(m_From, m_Poison); } else { if (m_Target is BaseWeapon weapon) { if (weapon.Type == WeaponType.Slashing) { m_From.SendLocalizedMessage( 1010516 ); // You fail to apply a sufficient dose of poison on the blade } else { m_From.SendLocalizedMessage( 1010518 ); // You fail to apply a sufficient dose of poison } } else { m_From.SendLocalizedMessage(1010518); // You fail to apply a sufficient dose of poison } } } } } } } } }