ModernUO/Projects/UOContent/Skills/Poisoning.cs
2021-12-24 15:53:59 -08:00

192 lines
7.7 KiB
C#

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
}
}
}
}
}
}
}
}
}