261 lines
9.8 KiB
C#
261 lines
9.8 KiB
C#
using System;
|
|
using Server.Mobiles;
|
|
using Server.Network;
|
|
using Server.Targeting;
|
|
using Server.Spells.Ninjitsu;
|
|
|
|
namespace Server.Items
|
|
{
|
|
public class Bola : Item
|
|
{
|
|
[Constructable]
|
|
public Bola()
|
|
: this(1)
|
|
{
|
|
}
|
|
|
|
[Constructable]
|
|
public Bola(int amount)
|
|
: base(0x26AC)
|
|
{
|
|
Weight = 4.0;
|
|
Stackable = true;
|
|
Amount = amount;
|
|
}
|
|
|
|
public Bola(Serial serial)
|
|
: base(serial)
|
|
{
|
|
}
|
|
|
|
public override void OnDoubleClick(Mobile from)
|
|
{
|
|
if (!IsChildOf(from.Backpack))
|
|
{
|
|
this.PrivateOverheadMessage(MessageType.Regular, 946, 1040019, from.NetState); // The bola must be in your pack to use it.
|
|
}
|
|
else if (!from.CanBeginAction(typeof(Bola)))
|
|
{
|
|
this.PrivateOverheadMessage(MessageType.Regular, 946, 1049624, from.NetState); // // You have to wait a few moments before you can use another bola!
|
|
}
|
|
else if (from.Target is BolaTarget)
|
|
{
|
|
this.PrivateOverheadMessage(MessageType.Regular, 946, 1049631, from.NetState); // This bola is already being used.
|
|
}
|
|
else if (from.Mounted)
|
|
{
|
|
this.PrivateOverheadMessage(MessageType.Regular, 946, 1042053, from.NetState); // You can't use this while on a mount!
|
|
}
|
|
else if (from.Flying)
|
|
{
|
|
this.PrivateOverheadMessage(MessageType.Regular, 946, 1113414, from.NetState); // You can't use this while flying!
|
|
}
|
|
else if (AnimalForm.UnderTransformation(from))
|
|
{
|
|
this.PrivateOverheadMessage(MessageType.Regular, 946, 1070902, from.NetState); // You can't use this while in an animal form!
|
|
}
|
|
else
|
|
{
|
|
EtherealMount.StopMounting(from);
|
|
|
|
if (Core.AOS)
|
|
{
|
|
Item one = from.FindItemOnLayer(Layer.OneHanded);
|
|
Item two = from.FindItemOnLayer(Layer.TwoHanded);
|
|
|
|
if (one != null)
|
|
from.AddToBackpack(one);
|
|
|
|
if (two != null)
|
|
from.AddToBackpack(two);
|
|
}
|
|
|
|
from.Target = new BolaTarget(this);
|
|
from.LocalOverheadMessage(MessageType.Emote, 201, 1049632); // * You begin to swing the bola...*
|
|
from.NonlocalOverheadMessage(MessageType.Emote, 201, 1049633, from.Name); // ~1_NAME~ begins to menacingly swing a bola...
|
|
}
|
|
}
|
|
|
|
public override void Serialize(GenericWriter writer)
|
|
{
|
|
base.Serialize(writer);
|
|
writer.Write((int)0);
|
|
}
|
|
|
|
public override void Deserialize(GenericReader reader)
|
|
{
|
|
base.Deserialize(reader);
|
|
int version = reader.ReadInt();
|
|
}
|
|
|
|
private static void ReleaseBolaLock(object state)
|
|
{
|
|
((Mobile)state).EndAction(typeof(Bola));
|
|
}
|
|
|
|
private static void FinishThrow(object state)
|
|
{
|
|
object[] states = (object[])state;
|
|
|
|
Mobile from = (Mobile)states[0];
|
|
Mobile to = (Mobile)states[1];
|
|
Item bola = (Item)states[2];
|
|
|
|
if (!from.Alive)
|
|
{
|
|
return;
|
|
}
|
|
if (!bola.IsChildOf(from.Backpack))
|
|
{
|
|
bola.PrivateOverheadMessage(MessageType.Regular, 946, 1040019, from.NetState); // The bola must be in your pack to use it.
|
|
}
|
|
else if (!from.InRange(to, 15) || !from.InLOS(to) || !from.CanSee(to))
|
|
{
|
|
from.PrivateOverheadMessage(MessageType.Regular, 946, 1042060, from.NetState); // You cannot see that target!
|
|
}
|
|
else if (!to.Mounted && !to.Flying && (!Core.ML || !AnimalForm.UnderTransformation(to)))
|
|
{
|
|
to.PrivateOverheadMessage(MessageType.Regular, 946, 1049628, from.NetState); // You have no reason to throw a bola at that.
|
|
}
|
|
else
|
|
{
|
|
bola.Consume();
|
|
|
|
from.Direction = from.GetDirectionTo(to);
|
|
from.Animate(AnimationType.Attack, 4);
|
|
from.MovingEffect(to, 0x26AC, 10, 0, false, false);
|
|
|
|
new Bola().MoveToWorld(to.Location, to.Map);
|
|
|
|
if (to is Neira || to is ChaosDragoon || to is ChaosDragoonElite)
|
|
{
|
|
to.PrivateOverheadMessage(MessageType.Regular, 946, 1042047, from.NetState); // You fail to knock the rider from its mount.
|
|
}
|
|
else
|
|
{
|
|
if (CheckHit(to, from))
|
|
{
|
|
to.Damage(Utility.RandomMinMax(10, 20), from);
|
|
|
|
if (from.Flying)
|
|
to.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1113590, from.Name); // You have been grounded by ~1_NAME~!
|
|
else
|
|
to.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1049623, from.Name); // You have been knocked off of your mount by ~1_NAME~!
|
|
|
|
BaseMount.Dismount(to);
|
|
|
|
BaseMount.SetMountPrevention(to, BlockMountType.Dazed, TimeSpan.FromSeconds(10.0));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private static bool CheckHit(Mobile to, Mobile from)
|
|
{
|
|
if (!Core.TOL)
|
|
return true;
|
|
|
|
double toChance = Math.Min(45 + BaseArmor.GetRefinedDefenseChance(to),
|
|
AosAttributes.GetValue(to, AosAttribute.DefendChance)) + 1;
|
|
double fromChance = AosAttributes.GetValue(from, AosAttribute.AttackChance) + 1;
|
|
|
|
double hitChance = toChance / (fromChance * 2);
|
|
|
|
if (Utility.RandomDouble() < hitChance)
|
|
{
|
|
if (BaseWeapon.CheckParry(to))
|
|
{
|
|
to.FixedEffect(0x37B9, 10, 16);
|
|
to.Animate(AnimationType.Parry, 0);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
to.NonlocalOverheadMessage(MessageType.Emote, 0x3B2, false, "*miss*");
|
|
return false;
|
|
}
|
|
|
|
private class BolaTarget : Target
|
|
{
|
|
private readonly Bola m_Bola;
|
|
public BolaTarget(Bola bola)
|
|
: base(20, false, TargetFlags.Harmful)
|
|
{
|
|
m_Bola = bola;
|
|
}
|
|
|
|
protected override void OnTarget(Mobile from, object obj)
|
|
{
|
|
if (m_Bola.Deleted)
|
|
return;
|
|
|
|
if ((obj is Item))
|
|
{
|
|
((Item)obj).PrivateOverheadMessage(MessageType.Regular, 0x3B2, 1049628, from.NetState); // You have no reason to throw a bola at that.
|
|
return;
|
|
}
|
|
|
|
if (obj is Mobile)
|
|
{
|
|
Mobile to = (Mobile)obj;
|
|
|
|
if (!m_Bola.IsChildOf(from.Backpack))
|
|
{
|
|
m_Bola.PrivateOverheadMessage(MessageType.Regular, 946, 1040019, from.NetState); // The bola must be in your pack to use it.
|
|
}
|
|
else if (from.Mounted)
|
|
{
|
|
m_Bola.PrivateOverheadMessage(MessageType.Regular, 946, 1042053, from.NetState); // You can't use this while on a mount!
|
|
}
|
|
else if (from.Flying)
|
|
{
|
|
m_Bola.PrivateOverheadMessage(MessageType.Regular, 946, 1113414, from.NetState); // You can't use this while flying!
|
|
}
|
|
else if (from == to)
|
|
{
|
|
from.SendLocalizedMessage(1005576); // You can't throw this at yourself.
|
|
}
|
|
else if (AnimalForm.UnderTransformation(from))
|
|
{
|
|
from.PrivateOverheadMessage(MessageType.Regular, 946, 1070902, from.NetState); // You can't use this while in an animal form!
|
|
}
|
|
else if (!to.Mounted && !to.Flying && (!Core.ML || !AnimalForm.UnderTransformation(to)))
|
|
{
|
|
to.PrivateOverheadMessage(MessageType.Regular, 946, 1049628, from.NetState); // You have no reason to throw a bola at that.
|
|
}
|
|
else if (!from.CanBeHarmful(to))
|
|
{
|
|
}
|
|
else if (from.BeginAction(typeof(Bola)))
|
|
{
|
|
from.RevealingAction();
|
|
|
|
EtherealMount.StopMounting(from);
|
|
|
|
Item one = from.FindItemOnLayer(Layer.OneHanded);
|
|
Item two = from.FindItemOnLayer(Layer.TwoHanded);
|
|
|
|
if (one != null)
|
|
from.AddToBackpack(one);
|
|
|
|
if (two != null)
|
|
from.AddToBackpack(two);
|
|
|
|
from.DoHarmful(to);
|
|
|
|
BaseMount.SetMountPrevention(from, BlockMountType.BolaRecovery, TimeSpan.FromSeconds(10.0));
|
|
Timer.DelayCall(TimeSpan.FromSeconds(10.0), new TimerStateCallback(ReleaseBolaLock), from);
|
|
Timer.DelayCall(TimeSpan.FromSeconds(3.0), new TimerStateCallback(FinishThrow), new object[] { from, to, m_Bola });
|
|
}
|
|
else
|
|
{
|
|
m_Bola.PrivateOverheadMessage(MessageType.Regular, 946, 1049624, from.NetState); // You have to wait a few moments before you can use another bola!
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|