mirror of
https://github.com/runuo/runuo
synced 2026-08-11 22:26:04 -04:00
Convert movement, actions (lift/use), combat, and spells to use Core.TickCount and avoid DateTime caveats (performance, system time dependency, etc) Refactor DateTime.Now to DateTime.UtcNow Add LOS check for Iron Maiden addon
384 lines
No EOL
8.5 KiB
C#
384 lines
No EOL
8.5 KiB
C#
/***************************************************************************
|
|
* Target.cs
|
|
* -------------------
|
|
* begin : May 1, 2002
|
|
* copyright : (C) The RunUO Software Team
|
|
* email : info@runuo.com
|
|
*
|
|
* $Id$
|
|
*
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
***************************************************************************/
|
|
|
|
using System;
|
|
using Server.Network;
|
|
|
|
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 int m_TargetID;
|
|
private int m_Range;
|
|
private bool m_AllowGround;
|
|
private bool m_CheckLOS;
|
|
private bool m_AllowNonlocal;
|
|
private bool m_DisallowMultis;
|
|
private TargetFlags m_Flags;
|
|
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;
|
|
m_AllowGround = allowGround;
|
|
m_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 Target m_Target;
|
|
private Mobile m_Mobile;
|
|
|
|
private static TimeSpan ThirtySeconds = TimeSpan.FromSeconds( 30.0 );
|
|
private static TimeSpan TenSeconds = TimeSpan.FromSeconds( 10.0 );
|
|
private static 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
|
|
{
|
|
return m_DisallowMultis;
|
|
}
|
|
set
|
|
{
|
|
m_DisallowMultis = value;
|
|
}
|
|
}
|
|
|
|
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 )
|
|
{
|
|
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;
|
|
}
|
|
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
|
|
{
|
|
return m_AllowGround;
|
|
}
|
|
set
|
|
{
|
|
m_AllowGround = value;
|
|
}
|
|
}
|
|
|
|
public TargetFlags Flags
|
|
{
|
|
get
|
|
{
|
|
return m_Flags;
|
|
}
|
|
set
|
|
{
|
|
m_Flags = value;
|
|
}
|
|
}
|
|
}
|
|
} |