using System; using System.Collections.Generic; using System.Text; using System.Threading; using LavishVMAPI; using LavishScriptAPI; namespace Bytebot { public enum NavigationMethod { Move, } public struct NavigationCoords { public double X; public double Y; public double Z; public NavigationMethod Method; } public class Navigator { const int FacePrecision = 15; const int MovementPrecision = 3; 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 public List Queue { get { return _movementqueue; } } #region Worker private static void Worker() { do { try { if (Bytebot.Global.Navigator.Queue.Count > 0) { NavigationCoords Coords = new NavigationCoords(); Coords = Bytebot.Global.Navigator.Queue[1]; // Check if point is behind us and distance is small, ifso don't reface just remove point if (true == false) { } else { Coords Location = new Coords(); Frame.Lock(); try { Location.X = Bytebot.Global.WoW.Me.Location.X; Location.Y = Bytebot.Global.WoW.Me.Location.Y; Location.Z = Bytebot.Global.WoW.Me.Location.Z; } finally { Frame.Unlock(); } Bytebot.Global.Navigator.Face(Coords.X, Coords.Y); if (Bytebot.Global.Distance(Location.X, Location.Y, Coords.X, Coords.Y) < MovementPrecision) { Bytebot.Global.Navigator.Queue.RemoveAt(1); } if (Bytebot.Global.Navigator.Queue.Count > 0 && Bytebot.Global.Movement.Speed == 0) { Bytebot.Global.Movement.Go(ISXWoW.MovementDirection.Forward); } } } } catch (Exception ex) { Bytebot.Global.Debug("Catched exception in navigator thread: " + ex.Message); } 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 = new Point3f(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)) { NavigationCoords navcoords = new NavigationCoords(); navcoords.X = Destination.X; navcoords.Y = Destination.Y; navcoords.Z = Destination.Z; navcoords.Method = NavigationMethod.Move; _movementqueue.Add(navcoords); Bytebot.Global.Debug(string.Format("Added to movement queue: {0} {1} {2}", navcoords.X, navcoords.Y, navcoords.Z)); } 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); Bytebot.Global.Debug(string.Format("Added to movement queue: {0} {1} {2}",navcoords.X,navcoords.Y,navcoords.Z)); } } 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 FlushQueue() { _movementqueue.Clear(); } public void Stop() { FlushQueue(); Bytebot.Global.Movement.Stop(); } #endregion } }