servuo/Server/Targeting/Target.cs
VitaNex f840e50340 Updated .editorconfig file with advanced configuration settings that will help maintain user code style and best practices with most IDE's.
Complete core housekeeping operation using "Profile 1" with new .editorconfig settings.
2021-01-15 12:51:10 -08:00

332 lines
No EOL
7.5 KiB
C#

#region References
using System;
using Server.Network;
#endregion
namespace Server.Targeting
{
public abstract class Target
{
private static int m_NextTargetID;
private static bool m_TargetIDValidation = true;
public static bool TargetIDValidation { get => m_TargetIDValidation; set => m_TargetIDValidation = value; }
private readonly int m_TargetID;
private int m_Range;
private bool m_CheckLOS;
private bool m_AllowNonlocal;
private DateTime m_TimeoutTime;
public DateTime TimeoutTime => m_TimeoutTime;
protected Target(int range, bool allowGround, TargetFlags flags)
{
m_TargetID = ++m_NextTargetID;
m_Range = range;
AllowGround = allowGround;
Flags = flags;
m_CheckLOS = true;
}
public static void Cancel(Mobile m)
{
var ns = m.NetState;
if (ns != null)
{
ns.Send(CancelTarget.Instance);
}
var targ = m.Target;
if (targ != null)
{
targ.OnTargetCancel(m, TargetCancelType.Canceled);
}
}
private Timer m_TimeoutTimer;
public void BeginTimeout(Mobile from, TimeSpan delay)
{
m_TimeoutTime = DateTime.UtcNow + delay;
if (m_TimeoutTimer != null)
{
m_TimeoutTimer.Stop();
}
m_TimeoutTimer = new TimeoutTimer(this, from, delay);
m_TimeoutTimer.Start();
}
public void CancelTimeout()
{
if (m_TimeoutTimer != null)
{
m_TimeoutTimer.Stop();
}
m_TimeoutTimer = null;
}
public void Timeout(Mobile from)
{
CancelTimeout();
from.ClearTarget();
Cancel(from);
OnTargetCancel(from, TargetCancelType.Timeout);
OnTargetFinish(from);
}
private class TimeoutTimer : Timer
{
private readonly Target m_Target;
private readonly Mobile m_Mobile;
private static readonly TimeSpan ThirtySeconds = TimeSpan.FromSeconds(30.0);
private static readonly TimeSpan TenSeconds = TimeSpan.FromSeconds(10.0);
private static readonly TimeSpan OneSecond = TimeSpan.FromSeconds(1.0);
public TimeoutTimer(Target target, Mobile m, TimeSpan delay)
: base(delay)
{
m_Target = target;
m_Mobile = m;
if (delay >= ThirtySeconds)
{
Priority = TimerPriority.FiveSeconds;
}
else if (delay >= TenSeconds)
{
Priority = TimerPriority.OneSecond;
}
else if (delay >= OneSecond)
{
Priority = TimerPriority.TwoFiftyMS;
}
else
{
Priority = TimerPriority.TwentyFiveMS;
}
}
protected override void OnTick()
{
if (m_Mobile.Target == m_Target)
{
m_Target.Timeout(m_Mobile);
}
}
}
public bool CheckLOS { get => m_CheckLOS; set => m_CheckLOS = value; }
public bool DisallowMultis { get; set; }
public bool AllowNonlocal { get => m_AllowNonlocal; set => m_AllowNonlocal = value; }
public int TargetID => m_TargetID;
public virtual Packet GetPacketFor(NetState ns)
{
return new TargetReq(this);
}
public void Cancel(Mobile from, TargetCancelType type)
{
CancelTimeout();
from.ClearTarget();
OnTargetCancel(from, type);
OnTargetFinish(from);
}
public void Invoke(Mobile from, object targeted)
{
var enhancedClient = from.NetState != null && from.NetState.IsEnhancedClient;
CancelTimeout();
from.ClearTarget();
if (from.Deleted)
{
OnTargetCancel(from, TargetCancelType.Canceled);
OnTargetFinish(from);
return;
}
Point3D loc;
Map map;
if (targeted is LandTarget)
{
loc = ((LandTarget)targeted).Location;
map = from.Map;
if (enhancedClient && loc.X == 0 && loc.Y == 0 && !from.InRange(loc, 10))
{
OnTargetCancel(from, TargetCancelType.Canceled);
OnTargetFinish(from);
return;
}
}
else if (targeted is StaticTarget)
{
loc = ((StaticTarget)targeted).Location;
map = from.Map;
}
else if (targeted is Mobile)
{
if (((Mobile)targeted).Deleted)
{
OnTargetDeleted(from, targeted);
OnTargetFinish(from);
return;
}
else if (!((Mobile)targeted).CanTarget)
{
OnTargetUntargetable(from, targeted);
OnTargetFinish(from);
return;
}
loc = ((Mobile)targeted).Location;
map = ((Mobile)targeted).Map;
}
else if (targeted is Item)
{
var item = (Item)targeted;
if (item.Deleted)
{
OnTargetDeleted(from, targeted);
OnTargetFinish(from);
return;
}
else if (!item.CanTarget)
{
OnTargetUntargetable(from, targeted);
OnTargetFinish(from);
return;
}
var root = item.RootParent;
if (!m_AllowNonlocal && root is Mobile && root != from && from.AccessLevel == AccessLevel.Player)
{
OnNonlocalTarget(from, targeted);
OnTargetFinish(from);
return;
}
loc = item.GetWorldLocation();
map = item.Map;
}
else
{
OnTargetCancel(from, TargetCancelType.Canceled);
OnTargetFinish(from);
return;
}
if (map == null || map != from.Map || (m_Range != -1 && !from.InRange(loc, m_Range)))
{
OnTargetOutOfRange(from, targeted);
}
else
{
if (!from.CanSee(targeted))
{
OnCantSeeTarget(from, targeted);
}
else if (m_CheckLOS && !from.InLOS(targeted))
{
OnTargetOutOfLOS(from, targeted);
}
else if (targeted is Item && ((Item)targeted).InSecureTrade)
{
OnTargetInSecureTrade(from, targeted);
}
else if (targeted is Item && !((Item)targeted).IsAccessibleTo(from))
{
OnTargetNotAccessible(from, targeted);
}
else if (targeted is Item && !((Item)targeted).CheckTarget(from, this, targeted))
{
OnTargetUntargetable(from, targeted);
}
else if (targeted is Mobile && !((Mobile)targeted).CheckTarget(from, this, targeted))
{
OnTargetUntargetable(from, targeted);
}
else if (from.Region.OnTarget(from, this, targeted))
{
OnTarget(from, targeted);
}
}
OnTargetFinish(from);
}
protected virtual void OnTarget(Mobile from, object targeted)
{ }
protected virtual void OnTargetNotAccessible(Mobile from, object targeted)
{
from.SendLocalizedMessage(500447); // That is not accessible.
}
protected virtual void OnTargetInSecureTrade(Mobile from, object targeted)
{
from.SendLocalizedMessage(500447); // That is not accessible.
}
protected virtual void OnNonlocalTarget(Mobile from, object targeted)
{
from.SendLocalizedMessage(500447); // That is not accessible.
}
protected virtual void OnCantSeeTarget(Mobile from, object targeted)
{
from.SendLocalizedMessage(500237); // Target can not be seen.
}
protected virtual void OnTargetOutOfLOS(Mobile from, object targeted)
{
from.SendLocalizedMessage(500237); // Target can not be seen.
}
protected virtual void OnTargetOutOfRange(Mobile from, object targeted)
{
from.SendLocalizedMessage(500446); // That is too far away.
}
protected virtual void OnTargetDeleted(Mobile from, object targeted)
{ }
protected virtual void OnTargetUntargetable(Mobile from, object targeted)
{
from.SendLocalizedMessage(500447); // That is not accessible.
}
protected virtual void OnTargetCancel(Mobile from, TargetCancelType cancelType)
{ }
protected virtual void OnTargetFinish(Mobile from)
{ }
public int Range { get => m_Range; set => m_Range = value; }
public bool AllowGround { get; set; }
public TargetFlags Flags { get; set; }
}
}