Overwrite
Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
206
Scripts/Services/Pathing/PathFollower.cs
Normal file
206
Scripts/Services/Pathing/PathFollower.cs
Normal file
@@ -0,0 +1,206 @@
|
||||
using System;
|
||||
using CalcMoves = Server.Movement.Movement;
|
||||
|
||||
namespace Server
|
||||
{
|
||||
public class PathFollower
|
||||
{
|
||||
// Should we use pathfinding? 'false' for not
|
||||
private static readonly bool Enabled = true;
|
||||
private static readonly TimeSpan RepathDelay = TimeSpan.FromSeconds(2.0);
|
||||
private readonly Mobile m_From;
|
||||
private readonly IPoint3D m_Goal;
|
||||
private MovementPath m_Path;
|
||||
private int m_Index;
|
||||
private Point3D m_Next, m_LastGoalLoc;
|
||||
private DateTime m_LastPathTime;
|
||||
private MoveMethod m_Mover;
|
||||
public PathFollower(Mobile from, IPoint3D goal)
|
||||
{
|
||||
this.m_From = from;
|
||||
this.m_Goal = goal;
|
||||
}
|
||||
|
||||
public MoveMethod Mover
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Mover;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_Mover = value;
|
||||
}
|
||||
}
|
||||
public IPoint3D Goal
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Goal;
|
||||
}
|
||||
}
|
||||
public MoveResult Move(Direction d)
|
||||
{
|
||||
if (this.m_Mover == null)
|
||||
return (this.m_From.Move(d) ? MoveResult.Success : MoveResult.Blocked);
|
||||
|
||||
return this.m_Mover(d);
|
||||
}
|
||||
|
||||
public Point3D GetGoalLocation()
|
||||
{
|
||||
if (this.m_Goal is Item)
|
||||
return ((Item)this.m_Goal).GetWorldLocation();
|
||||
|
||||
return new Point3D(this.m_Goal);
|
||||
}
|
||||
|
||||
public void Advance(ref Point3D p, int index)
|
||||
{
|
||||
if (this.m_Path != null && this.m_Path.Success)
|
||||
{
|
||||
Direction[] dirs = this.m_Path.Directions;
|
||||
|
||||
if (index >= 0 && index < dirs.Length)
|
||||
{
|
||||
int x = p.X, y = p.Y;
|
||||
|
||||
CalcMoves.Offset(dirs[index], ref x, ref y);
|
||||
|
||||
p.X = x;
|
||||
p.Y = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ForceRepath()
|
||||
{
|
||||
this.m_Path = null;
|
||||
}
|
||||
|
||||
public bool CheckPath()
|
||||
{
|
||||
if (!Enabled)
|
||||
return false;
|
||||
|
||||
bool repath = false;
|
||||
|
||||
Point3D goal = this.GetGoalLocation();
|
||||
|
||||
if (this.m_Path == null)
|
||||
repath = true;
|
||||
else if ((!this.m_Path.Success || goal != this.m_LastGoalLoc) && (this.m_LastPathTime + RepathDelay) <= DateTime.UtcNow)
|
||||
repath = true;
|
||||
else if (this.m_Path.Success && this.Check(this.m_From.Location, this.m_LastGoalLoc, 0))
|
||||
repath = true;
|
||||
|
||||
if (!repath)
|
||||
return false;
|
||||
|
||||
this.m_LastPathTime = DateTime.UtcNow;
|
||||
this.m_LastGoalLoc = goal;
|
||||
|
||||
this.m_Path = new MovementPath(this.m_From, goal);
|
||||
|
||||
this.m_Index = 0;
|
||||
this.m_Next = this.m_From.Location;
|
||||
|
||||
this.Advance(ref this.m_Next, this.m_Index);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Check(Point3D loc, Point3D goal, int range)
|
||||
{
|
||||
if (!Utility.InRange(loc, goal, range))
|
||||
return false;
|
||||
|
||||
if (range <= 1 && Math.Abs(loc.Z - goal.Z) >= 16)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Follow(bool run, int range)
|
||||
{
|
||||
Point3D goal = this.GetGoalLocation();
|
||||
Direction d;
|
||||
|
||||
if (this.Check(this.m_From.Location, goal, range))
|
||||
return true;
|
||||
|
||||
bool repathed = this.CheckPath();
|
||||
|
||||
if (!Enabled || !this.m_Path.Success)
|
||||
{
|
||||
d = this.m_From.GetDirectionTo(goal);
|
||||
|
||||
if (run)
|
||||
d |= Direction.Running;
|
||||
|
||||
this.m_From.SetDirection(d);
|
||||
this.Move(d);
|
||||
|
||||
return this.Check(this.m_From.Location, goal, range);
|
||||
}
|
||||
|
||||
d = this.m_From.GetDirectionTo(this.m_Next);
|
||||
|
||||
if (run)
|
||||
d |= Direction.Running;
|
||||
|
||||
this.m_From.SetDirection(d);
|
||||
|
||||
MoveResult res = this.Move(d);
|
||||
|
||||
if (res == MoveResult.Blocked)
|
||||
{
|
||||
if (repathed)
|
||||
return false;
|
||||
|
||||
this.m_Path = null;
|
||||
this.CheckPath();
|
||||
|
||||
if (!this.m_Path.Success)
|
||||
{
|
||||
d = this.m_From.GetDirectionTo(goal);
|
||||
|
||||
if (run)
|
||||
d |= Direction.Running;
|
||||
|
||||
this.m_From.SetDirection(d);
|
||||
this.Move(d);
|
||||
|
||||
return this.Check(this.m_From.Location, goal, range);
|
||||
}
|
||||
|
||||
d = this.m_From.GetDirectionTo(this.m_Next);
|
||||
|
||||
if (run)
|
||||
d |= Direction.Running;
|
||||
|
||||
this.m_From.SetDirection(d);
|
||||
|
||||
res = this.Move(d);
|
||||
|
||||
if (res == MoveResult.Blocked)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.m_From.X == this.m_Next.X && this.m_From.Y == this.m_Next.Y)
|
||||
{
|
||||
if (this.m_From.Z == this.m_Next.Z)
|
||||
{
|
||||
++this.m_Index;
|
||||
this.Advance(ref this.m_Next, this.m_Index);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.m_Path = null;
|
||||
}
|
||||
}
|
||||
|
||||
return this.Check(this.m_From.Location, goal, range);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user