mirror of
https://github.com/ServUO/ServUO
synced 2026-08-11 20:23:04 -04:00
+ Add MONO to Makefile compile definitions. + Update Ultima SDK to support MONO compile definition. + Rename Properties Gump parent directory to prevent VS issues. + Console error messages will now use red instead of dark red font. + Add crash state handler function to Core. + AI optimizations and housekeeping. + Context Menu optimizations and housekeeping. + Add ability to drop throttled packets. + Add string parsing support to Rectangle3D. + Optimize guild messages and chat. + IAddon implements IChopable. + Add more flexibility for altering Mobile names. + Add ability to enable or disable OPL for individual mobiles. + Optimize damaging regions and ensure timers are removed properly. + Update Welcome Timer with more intuitive message groups. + Normalize all virtue related objects to the Server.Services.Virtues namespace. + Add ability for ISpawner to append OPL and Context Menus to their spawn. + Add EventSink events for obtaining items, equipping items, context menus, and world broadcasts. + Add ability to lock a creature's direction and movement regardless of AI manipulation. + Add ability to dynamically change a creature's approach range and wait state. + Add extended enumeration features for AOS attributes. + Add ability to control whether creatures have blood, and its color. + Expose corpse flag manipulation methods. + Add ability to prevent criminal action when looting a corpse. + Corpse will now be permanently tagged as murderer at time of death if owner is a murderer. + Add TextDefinition support for Commodity Deed descriptions. + House add-on and component optimizations and housekeeping. + Item light is no longer backed by the direction property. + ITool implements IEntity. + Prevent trading of Siege Bless items. + Guards are naturally be immune to guards. + Siege Shard initialization housekeeping. + Character Creation housekeeping. + Generic commands housekeeping. + Add Mark command for staff.
332 lines
No EOL
7.7 KiB
C#
332 lines
No EOL
7.7 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 { return 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 { get { return 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)
|
|
{
|
|
NetState ns = m.NetState;
|
|
|
|
if (ns != null)
|
|
{
|
|
ns.Send(CancelTarget.Instance);
|
|
}
|
|
|
|
Target 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 { return m_CheckLOS; } set { m_CheckLOS = value; } }
|
|
|
|
public bool DisallowMultis { get; set; }
|
|
|
|
public bool AllowNonlocal { get { return m_AllowNonlocal; } set { m_AllowNonlocal = value; } }
|
|
|
|
public int TargetID { get { return 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)
|
|
{
|
|
bool 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)
|
|
{
|
|
Item item = (Item)targeted;
|
|
|
|
if (item.Deleted)
|
|
{
|
|
OnTargetDeleted(from, targeted);
|
|
OnTargetFinish(from);
|
|
return;
|
|
}
|
|
else if (!item.CanTarget)
|
|
{
|
|
OnTargetUntargetable(from, targeted);
|
|
OnTargetFinish(from);
|
|
return;
|
|
}
|
|
|
|
object 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 { return m_Range; } set { m_Range = value; } }
|
|
|
|
public bool AllowGround { get; set; }
|
|
|
|
public TargetFlags Flags { get; set; }
|
|
}
|
|
} |