using System; using System.Collections.Generic; using System.Text; using ISXWoW; using LavishVMAPI; using LavishNavAPI.Regions; using System.IO; using System.Threading; namespace Bytebot { public class Mapper { const int MaximumBoxSize = 15; private Thread _thread; private string mapfolder = "c:/bytebot"; #region Constructor public Mapper() { Initialize(); _thread = new Thread(new ThreadStart(Worker)); _thread.Name = "Mapper"; _thread.IsBackground = true; _thread.Start(); } #endregion #region Destructor ~Mapper() { } #endregion Destructor #region Private methods private void Initialize() { Bytebot.Global.Debug("Initializing lavish nav."); Bytebot.Global.Nav.Tree.Clear(); Bytebot.Global.Nav.Tree.AddUniverse("Azeroth", RegionFlags.Unique); if (!File.Exists(string.Format("{0}/azeroth.xml", mapfolder))) { Bytebot.Global.Debug(string.Format("{0}/azeroth.xml not found, generating continents and zones.", mapfolder)); Bytebot.Global.Nav.Tree.FindRegion("Azeroth").AddUniverse("Instance", RegionFlags.Unique | RegionFlags.CoordinateSystem); List Continents = Bytebot.Global.WoW.WoWScript("GetMapContinents()"); for (int i = 0; i < Continents.Count; i++) { Bytebot.Global.Nav.Tree.FindRegion("Azeroth").AddUniverse(Continents[i], RegionFlags.Unique | RegionFlags.CoordinateSystem); List Zones = Bytebot.Global.WoW.WoWScript("GetMapZones(" + (i + 1).ToString() + ")"); for (int zi = 0; zi < Zones.Count; zi++) { Bytebot.Global.Nav.Tree.FindRegion("Azeroth").FindRegion(Continents[i]).AddUniverse(Zones[zi], RegionFlags.Unique); } } } else { Bytebot.Global.Debug(string.Format("{0}/azeroth.xml found, loading.", mapfolder)); Bytebot.Global.Nav.Tree.FindRegion("Azeroth").ImportXML(string.Format("{0}/azeroth.xml", mapfolder)); } } // Threaded loop to plot out points if needed private static void Worker() { do { Frame.Lock(); try { if (Bytebot.Global.WoW.Me.IsValid && !Bytebot.Global.WoW.Me.Flying) { try { if (!Bytebot.Global.Map.IsMapped()) { Bytebot.Global.Map.PlotBox(); } } catch (Exception ex) { Bytebot.Global.Debug("Caught exception in Mapper thread: " + ex.Message); } } } finally { Frame.Unlock(); } Thread.Sleep(100); } while (true); } #endregion #region Public methods public void Save() { Bytebot.Global.Nav.Tree.FindRegion("Azeroth").ExportXML(string.Format("{0}/azeroth.xml", mapfolder)); } public bool IsMapped() { LavishNavAPI.Regions.Region Container = Zone.BestContainer(Bytebot.Global.WoW.Me.X, Bytebot.Global.WoW.Me.Y, Bytebot.Global.WoW.Me.Z + 0.3); if (Container != null && Container.Type != "Universe") { return true; } return false; } public void PlotBox() { string RegionName; int Degrees = 0; double Distance = (MaximumBoxSize / 2) + 5; // To compensate for the corners of the square double X1, X2, Y1, Y2, Z1, Z2; LavishScriptAPI.Point3f Location = Bytebot.Global.WoW.Me.Location; LavishScriptAPI.Point3f CollisionPoint; double X, Y; Z1 = Location.Z; Z2 = Location.Z; do { X = Location.X + (MaximumBoxSize / 2) * Math.Cos(Degrees); Y = Location.Y - (MaximumBoxSize / 2) * Math.Sin(Degrees); CollisionPoint = Bytebot.Global.WoW.IsPathObstructed(Location.X,Location.Y,Location.Z,X,Y,Location.Z); if (CollisionPoint != null) { if (Bytebot.Global.Distance(Location.X, Location.Y, Location.Z, CollisionPoint.X, CollisionPoint.Y, Location.Z) < Distance) { Distance = Bytebot.Global.Distance(Location.X, Location.Y, Location.Z, CollisionPoint.X, CollisionPoint.Y, Location.Z); } } Degrees = Degrees + 30; } while (Degrees <= 360); if (Distance > (MaximumBoxSize / 2)) { Distance = (MaximumBoxSize / 2); } X1 = Location.X - Distance; Y1 = Location.Y - Distance; X2 = Location.X + Distance; Y2 = Location.Y + Distance; Z1 = Location.Z - 0.3; Z2 = Location.Z + 1.3; // Z handling is terrible but it's there. Improve when time. RegionName = string.Format("R{0}",Zone.ChildCount); Zone.AddBox(RegionName, X1, X2, Y1, Y2, Z1, Z2, 0); // Done plotting connect them List SurroundingRegions; LavishNavAPI.Regions.Region NewRegion; int Connections = 0; SurroundingRegions = Continent.DescendantsWithin(Location.X, Location.Y, Location.Z, MaximumBoxSize * 2); if (SurroundingRegions != null) { NewRegion = Zone.FindRegion(RegionName); for (int i = 0; i < SurroundingRegions.Count; i++) { if (NewRegion.ID != SurroundingRegions[i].ID && Connections < 10) { Box NewBox = new Box(NewRegion); Box SurroundingBox = new Box(SurroundingRegions[i]); if (!Bytebot.Global.WoW.Me.IsPathObstructed(NewBox.X1,NewBox.Y1,NewBox.Z1,999,SurroundingBox.X1,SurroundingBox.Y1,SurroundingBox.Z1) && !Bytebot.Global.WoW.Me.IsPathObstructed(NewBox.X1,NewBox.Y2,NewBox.Z1,999,SurroundingBox.X1,SurroundingBox.Y2,SurroundingBox.Z1) && !Bytebot.Global.WoW.Me.IsPathObstructed(NewBox.X2,NewBox.Y1,NewBox.Z1,999,SurroundingBox.X2,SurroundingBox.Y1,SurroundingBox.Z1) && !Bytebot.Global.WoW.Me.IsPathObstructed(NewBox.X2,NewBox.Y2,NewBox.Z1,999,SurroundingBox.X2,SurroundingBox.Y2,SurroundingBox.Z1)) { NewRegion.Connect(SurroundingRegions[i].ID); Connections++; } if (!Bytebot.Global.WoW.Me.IsPathObstructed(SurroundingBox.X1, SurroundingBox.Y1, SurroundingBox.Z1, 999, NewBox.X1, NewBox.Y1, NewBox.Z1) && !Bytebot.Global.WoW.Me.IsPathObstructed(SurroundingBox.X1, SurroundingBox.Y2, SurroundingBox.Z1, 999, NewBox.X1, NewBox.Y2, NewBox.Z1) && !Bytebot.Global.WoW.Me.IsPathObstructed(SurroundingBox.X2, SurroundingBox.Y1, SurroundingBox.Z1, 999, NewBox.X2, NewBox.Y1, NewBox.Z1) && !Bytebot.Global.WoW.Me.IsPathObstructed(SurroundingBox.X2, SurroundingBox.Y2, SurroundingBox.Z1, 999, NewBox.X2, NewBox.Y2, NewBox.Z1)) { SurroundingRegions[i].Connect(NewRegion.ID); Connections++; } } } } if (Connections == 0) { Bytebot.Global.Debug(string.Format("Critical: {0} has no connections",RegionName)); } Bytebot.Global.Debug(string.Format("Added: {0} Size: {1} Connections: {2}", RegionName, (Distance * 2), Connections)); Save(); } #endregion #region Properties public string SubZone { get { string _subzonetext = Bytebot.Global.WoW.WoWScript("GetSubZoneText()")[0].ToString(); return _subzonetext; } } public LavishNavAPI.Regions.Region Zone { get { LavishNavAPI.Regions.Region _zone; string _zonetext = Bytebot.Global.WoW.WoWScript("GetRealZoneText()")[0].ToString(); _zone = this.Continent.FindRegion(_zonetext); if (_zone.IsValid != true) { _zone = this.Continent.FindRegion(_zonetext); } return _zone; } } public LavishNavAPI.Regions.Region Continent { get { Bytebot.Global.WoW.WoWScript("SetMapToCurrentZone()"); List Continents = Bytebot.Global.WoW.WoWScript("GetMapContinents()"); int ContinentIndex = int.Parse(Bytebot.Global.WoW.WoWScript("GetCurrentMapContinent()")[0]); string ContinentString = Continents[ContinentIndex - 1]; if (ContinentString == null) { ContinentString = "Instance"; } return Bytebot.Global.Nav.Tree.FindRegion("Azeroth").FindRegion(ContinentString); } } #endregion } }