using System; using System.Collections.Generic; using System.Text; using System.Threading; using LavishVMAPI; using LavishScriptAPI; namespace Bytebot { public enum NavigationMethod { Move, Taxi, } public struct NavigationCoords { public double X; public double Y; public double Z; public NavigationMethod Method; } public class Navigator { const int FacePrecision = 15; const int DirectMoveRange = 40; private Thread _thread; private List _movementqueue = new List(); #region Constructor public Navigator() { _thread = new Thread(new ThreadStart(Worker)); _thread.Name = "Navigator"; _thread.IsBackground = true; _thread.Start(); } #endregion #region Worker private static void Worker() { do { Thread.Sleep(50); } while (true); } #endregion #region Public methods public void Face(double X, double Y, bool Exact) { double Heading = 180; double HeadingTo = 0; if (!Exact) { Frame.Lock(); Heading = Bytebot.Global.WoW.Me.Heading; HeadingTo = Bytebot.Global.WoW.Me.HeadingTo(X, Y); Frame.Unlock(); } if (Math.Abs(Heading-HeadingTo) > FacePrecision) { Bytebot.Global.WoW.Face(X, Y); } } public void Face(double X, double Y) { Face(X,Y); } public void Face(LavishScriptAPI.Point3f Point) { Face(Point.X, Point.Y, false); } public LavishNavAPI.Regions.Region BestRegion(double X, double Y, double Z) { LavishNavAPI.Regions.Region Container = Bytebot.Global.Map.Zone.BestContainer(X, Y, Z + 0.3); if (Container != null && Container.Type != "Universe") { return Container; } List SurroundingRegions; SurroundingRegions = Bytebot.Global.Map.Continent.DescendantsWithin(X, Y, Z, 100); if (SurroundingRegions != null && SurroundingRegions.Count > 0) { return SurroundingRegions[0]; } return null; } public LavishNavAPI.Regions.Region BestRegion(Point3f Point) { return BestRegion(Point.X, Point.Y, Point.Z); } public LavishNavAPI.Regions.Region BestRegion(Coords Point) { return BestRegion(Point.X, Point.Y, Point.Z); } public void MoveTo(double X, double Y, double Z) { Coords Location = new Coords(); Coords Destination = new Coords(); Point3f loc = Bytebot.Global.WoW.Me.Location; Location.X = loc.X; Location.Y = loc.Y; Location.Z = loc.Z; Destination.X = X; Destination.Y = Y; Destination.Z = Z; if ((Bytebot.Global.Distance(Location, Destination) < DirectMoveRange) && !Bytebot.Global.WoW.Me.IsPathObstructed(Destination.X,Destination.Y,Destination.Z,DirectMoveRange)) { Bytebot.Global.Debug(string.Format("MoveTo Direct: {0} {1} {2}",Destination.X,Destination.Y,Destination.Z)); NavigationCoords navcoords = new NavigationCoords(); navcoords.X = Destination.X; navcoords.Y = Destination.Y; navcoords.Z = Destination.Z; navcoords.Method = NavigationMethod.Move; _movementqueue.Add(navcoords); } else { LavishNavAPI.Path path = new LavishNavAPI.Path(); LavishNavAPI.Pathfinders.Dijkstra pathfinder = new LavishNavAPI.Pathfinders.Dijkstra(); LavishNavAPI.Regions.Region fromregion; LavishNavAPI.Regions.Region toregion; fromregion = BestRegion(Location); toregion = BestRegion(Destination); if (fromregion != null && toregion != null) { path.Clear(); if (pathfinder.SelectPath(fromregion.ID, toregion.ID, ref path)) { for (int i = 1; i <= path.Hops; i++) { NavigationCoords navcoords = new NavigationCoords(); LavishNavAPI.Regions.Box Region; Region = new LavishNavAPI.Regions.Box(path.Region((uint)i)); //regions are free for movement, select random spot navcoords.X = Region.CenterPoint.X; navcoords.Y = Region.CenterPoint.Y; navcoords.Z = Region.Z1; navcoords.Method = NavigationMethod.Move; _movementqueue.Add(navcoords); } } else { Bytebot.Global.Debug(string.Format("No path to destination, you are screwed.")); } } else { Bytebot.Global.Debug(string.Format("No path to destination, you are screwed.")); } } } public void MoveTo(LavishScriptAPI.Point3f Point) { MoveTo(Point.X, Point.Y, Point.Z); } public void MoveTo(Coords Point) { MoveTo(Point.X, Point.Y, Point.Z); } public void Stop() { _movementqueue.Clear(); } #endregion } }