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 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(); 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); } } 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); if (Container != null && Container.Type != "Universe") { return true; } return false; } public void PlotBox() { string RegionName; int Degrees = 0; double Distance = (MaximumBoxSize / 2) + 1; 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,Z2); if (CollisionPoint != null) { if (Bytebot.Global.Distance(Location.X, Location.Y, Z2, CollisionPoint.X, CollisionPoint.Y, Z2) < Distance) { Distance = Bytebot.Global.Distance(Location.X, Location.Y, Location.Z, CollisionPoint.X, CollisionPoint.Y, Z2); } } Degrees = Degrees + 30; } while (Degrees <= 360); X1 = Location.X - Distance; Y1 = Location.Y - Distance; X2 = Location.X + Distance; Y2 = Location.Y + Distance; Z1 = Location.Z; // Z handling is terrible but it's there. Improve when time. RegionName = string.Format("R{0}",SubZone.ChildCount); Bytebot.Global.Debug(string.Format("Added {0} Size: {1}",RegionName,(Distance * 2))); SubZone.AddBox(RegionName, X1, X2, Y1, Y2, Z1, Z2, 0); Save(); } #endregion #region Properties public LavishNavAPI.Regions.Region SubZone { get { LavishNavAPI.Regions.Region _subzone; string _subzonetext = Bytebot.Global.WoW.WoWScript("GetMinimapZoneText()")[0].ToString(); _subzone = this.Zone.FindRegion(_subzonetext); if (_subzone != null || _subzone.IsValid != true) { this.Zone.AddUniverse(_subzonetext,0); _subzone = this.Zone.FindRegion(_subzonetext); } return _subzone; } } 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) { this.Continent.AddUniverse(_zonetext,RegionFlags.Unique); _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 } }