using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using SOTF_Struct.Generic; namespace SOTF_Struct { [Flags] public enum eLocationList : int { Actor = 1, Construction = 2, StructureInstance = 4 } public static class LocationList { public static void ExportLocation(List list) { if (!Directory.Exists("locations")) Directory.CreateDirectory("locations"); string file = getLocationFile(eLocationList.Actor); List poses = new List(); if (File.Exists(file)) { StreamReader reader = new StreamReader(file); BinaryReader binreader = new BinaryReader(reader.BaseStream); while (binreader.BaseStream.Position < binreader.BaseStream.Length) { int area = binreader.ReadInt32(); double x = binreader.ReadDouble(); double y = binreader.ReadDouble(); double z = binreader.ReadDouble(); poses.Add(new Position(Math.Round(x/2), Math.Round(y/2), Math.Round(z/2))); } reader.Close(); reader.Dispose(); reader = null; } StreamWriter writer = new StreamWriter(file, true); BinaryWriter bin = new BinaryWriter(writer.BaseStream); int count = 0; foreach (Actor i in list) { Position tmpPos = new Position(Math.Round(i.Position.x / 2), Math.Round(i.Position.y / 2), Math.Round(i.Position.z / 2)); if (IsValidActor(i) && !poses.Contains(tmpPos)) { bin.Write(i.GraphMask); bin.Write(i.Position.x); bin.Write(i.Position.y); bin.Write(i.Position.z); count++; } } System.Diagnostics.Debug.WriteLine(count.ToString() + " Position added (Actor[])"); writer.Close(); writer.Dispose(); writer = null; } public static void ExportLocation(Actor actor) { if (!Directory.Exists("locations")) Directory.CreateDirectory("locations"); if (!IsValidActor(actor)) return; string file = getLocationFile(eLocationList.Actor); List poses = new List(); if (File.Exists(file)) { StreamReader reader = new StreamReader(file); BinaryReader binreader = new BinaryReader(reader.BaseStream); while (binreader.BaseStream.Position < binreader.BaseStream.Length) { int area = binreader.ReadInt32(); double x = binreader.ReadDouble(); double y = binreader.ReadDouble(); double z = binreader.ReadDouble(); poses.Add(new Position(Math.Round(x / 2), Math.Round(y / 2), Math.Round(z / 2))); } reader.Close(); reader.Dispose(); reader = null; } Position tmpPos = new Position(Math.Round(actor.Position.x / 2), Math.Round(actor.Position.y / 2), Math.Round(actor.Position.z / 2)); if (poses.Contains(tmpPos)) return; StreamWriter writer = new StreamWriter(file, true); BinaryWriter bin = new BinaryWriter(writer.BaseStream); bin.Write(actor.GraphMask); bin.Write(actor.Position.x); bin.Write(actor.Position.y); bin.Write(actor.Position.z); System.Diagnostics.Debug.WriteLine("1 Position added (Actor[])"); writer.Close(); writer.Dispose(); writer = null; } public static void ExportLocation(List list) { if (!Directory.Exists("locations")) Directory.CreateDirectory("locations"); string file = getLocationFile(eLocationList.StructureInstance); List poses = new List(); if (File.Exists(file)) { StreamReader reader = new StreamReader(file); BinaryReader binreader = new BinaryReader(reader.BaseStream); while (binreader.BaseStream.Position < binreader.BaseStream.Length) { int area = binreader.ReadInt32(); double x = binreader.ReadDouble(); double y = binreader.ReadDouble(); double z = binreader.ReadDouble(); poses.Add(new Position(Math.Round(x / 2), Math.Round(y / 2), Math.Round(z / 2))); } reader.Close(); } StreamWriter writer = new StreamWriter(file, true); BinaryWriter bin = new BinaryWriter(writer.BaseStream); int count = 0; foreach (Structure i in list) { Position tmpPos = new Position(Math.Round(i.Pos.x / 2), Math.Round(i.Pos.y / 2), Math.Round(i.Pos.z / 2)); if (!poses.Contains(tmpPos)) { bin.Write((int)1); bin.Write(i.Pos.x); bin.Write(i.Pos.y); bin.Write(i.Pos.z); count++; } } System.Diagnostics.Debug.WriteLine(count.ToString() + " Position added (Structure[])"); writer.Close(); } public static void ExportLocation(Structure structure) { if (!Directory.Exists("locations")) Directory.CreateDirectory("locations"); string file = getLocationFile(eLocationList.StructureInstance); List poses = new List(); if (File.Exists(file)) { StreamReader reader = new StreamReader(file); BinaryReader binreader = new BinaryReader(reader.BaseStream); while (binreader.BaseStream.Position < binreader.BaseStream.Length) { int area = binreader.ReadInt32(); double x = binreader.ReadDouble(); double y = binreader.ReadDouble(); double z = binreader.ReadDouble(); poses.Add(new Position(Math.Round(x / 2), Math.Round(y / 2), Math.Round(z / 2))); } reader.Close(); reader.Dispose(); reader = null; } StreamWriter writer = new StreamWriter(file, true); BinaryWriter bin = new BinaryWriter(writer.BaseStream); Position tmpPos = new Position(Math.Round(structure.Pos.x / 2), Math.Round(structure.Pos.y / 2), Math.Round(structure.Pos.z / 2)); if (!poses.Contains(tmpPos)) { bin.Write((int)1); bin.Write(structure.Pos.x); bin.Write(structure.Pos.y); bin.Write(structure.Pos.z); System.Diagnostics.Debug.WriteLine("1 Position added (Structure[])"); } writer.Close(); writer.Dispose(); writer = null; } public static void ExportLocation(int area, Position Position, eLocationList location) { if (!Directory.Exists("locations")) Directory.CreateDirectory("locations"); if (location.HasFlag(eLocationList.Actor)) ExportLocationWrite(area, Position, eLocationList.Actor); if (location.HasFlag(eLocationList.Construction)) ExportLocationWrite(area, Position, eLocationList.Construction); if (location.HasFlag(eLocationList.StructureInstance)) ExportLocationWrite(area, Position, eLocationList.StructureInstance); } public static void ExportLocation(int area, double[] pos, eLocationList location) { ExportLocation(area, new Position(pos[0], pos[1], pos[2]), location); } public static void ExportLocation(int area, double x, double y, double z, eLocationList location) { ExportLocation(area, new Position(x, y, z), location); } private static void ExportLocationWrite(int area, Position Position, eLocationList location) { string file = getLocationFile(eLocationList.Actor); List poses = new List(); if (File.Exists(file)) { StreamReader reader = new StreamReader(file); BinaryReader binreader = new BinaryReader(reader.BaseStream); while (binreader.BaseStream.Position < binreader.BaseStream.Length) { int area2 = binreader.ReadInt32(); double x = binreader.ReadDouble(); double y = binreader.ReadDouble(); double z = binreader.ReadDouble(); poses.Add(new Position(Math.Round(x / 2), Math.Round(y / 2), Math.Round(z / 2))); } reader.Close(); reader.Dispose(); reader = null; } Position tmpPos = new Position(Math.Round(Position.x / 2), Math.Round(Position.y / 2), Math.Round(Position.z / 2)); if (!poses.Contains(tmpPos)) { StreamWriter writer = new StreamWriter(file, true); BinaryWriter bin = new BinaryWriter(writer.BaseStream); bin.Write(area); bin.Write(Position.x); bin.Write(Position.y); bin.Write(Position.z); writer.Close(); writer.Dispose(); writer = null; System.Diagnostics.Debug.WriteLine("1 Position added (Position)"); } } #region GetLocationNear public static Position? GetLocationNear(Position pos, double MinDistance, double MaxDistance, eLocationList location) { System.Diagnostics.Debug.WriteLine("GetLocationNear(Position, location)"); System.Diagnostics.Debug.WriteLine(location.ToString()); if (!Directory.Exists("locations")) { System.Diagnostics.Debug.WriteLine("Directory missing"); return null; } Position? closes = null; double distanceCloses = double.MaxValue; if (location.HasFlag(eLocationList.Actor)) { System.Diagnostics.Debug.WriteLine("Get by Actor"); getLocationNearJob(pos, 0, MinDistance, MaxDistance, eLocationList.Actor, ref distanceCloses, ref closes); } if (location.HasFlag(eLocationList.StructureInstance)) { System.Diagnostics.Debug.WriteLine("Get by StructureInstance"); getLocationNearJob(pos, 0, MinDistance, MaxDistance, eLocationList.StructureInstance, ref distanceCloses, ref closes); } if (location.HasFlag(eLocationList.Construction)) { System.Diagnostics.Debug.WriteLine("Get by Construction"); getLocationNearJob(pos, 0, MinDistance, MaxDistance, eLocationList.Construction, ref distanceCloses, ref closes); } return closes; } public static Position? GetLocationNear(Position pos, double MinDistance, eLocationList location) { return GetLocationNear(pos, 0, MinDistance, double.MaxValue, location); } public static Position? GetLocationNear(Position pos, eLocationList location) { return GetLocationNear(pos, 0, 0.0f, double.MaxValue, location); } public static Position? GetLocationNear(Position pos) { return GetLocationNear(pos, 0, 0.0f, double.MaxValue, eLocationList.Actor | eLocationList.StructureInstance); } public static Position? GetLocationNear(double[] pos, eLocationList location) { if (pos.Length < 3) { System.Diagnostics.Debug.WriteLine(" Array to small: " + pos.Length); return null; } return GetLocationNear(new Position(pos[0], pos[1], pos[2]), 0, 0.0f, double.MaxValue, location); } public static Position? GetLocationNear(double[] pos) { if (pos.Length < 3) { System.Diagnostics.Debug.WriteLine(" Array to small: " + pos.Length); return null; } return GetLocationNear(new Position(pos[0], pos[1], pos[2]), 0, 0.0f, double.MaxValue, eLocationList.Actor | eLocationList.StructureInstance); } public static Position? GetLocationNear(Position pos, double MinOffset) { return GetLocationNear(pos, 0, MinOffset, double.MaxValue, eLocationList.Actor | eLocationList.StructureInstance); } public static Position? GetLocationNear(double[] pos, double MinOffset, eLocationList location) { if (pos.Length < 3) { System.Diagnostics.Debug.WriteLine(" Array to small: " + pos.Length); return null; } return GetLocationNear(new Position(pos[0], pos[1], pos[2]), 0, MinOffset, double.MaxValue, location); } public static Position? GetLocationNear(double[] pos, double MinOffset) { if (pos.Length < 3) { System.Diagnostics.Debug.WriteLine(" Array to small: " + pos.Length); return null; } return GetLocationNear(new Position(pos[0], pos[1], pos[2]), 0, MinOffset, double.MaxValue, eLocationList.Actor | eLocationList.StructureInstance); } public static Position? GetLocationNear(Position pos, double MinOffset, double MaxOffset) { return GetLocationNear(pos, 0, MinOffset, MaxOffset, eLocationList.Actor | eLocationList.StructureInstance); } public static Position? GetLocationNear(double[] pos, double MinOffset, double MaxOffset, eLocationList location) { if (pos.Length < 3) { System.Diagnostics.Debug.WriteLine(" Array to small: " + pos.Length); return null; } return GetLocationNear(new Position(pos[0], pos[1], pos[2]), 0, MinOffset, MaxOffset, location); } public static Position? GetLocationNear(double[] pos, double MinOffset, double MaxOffset) { if (pos.Length < 3) { System.Diagnostics.Debug.WriteLine(" Array to small: " + pos.Length); return null; } return GetLocationNear(new Position(pos[0], pos[1], pos[2]), 0, MinOffset, MaxOffset, eLocationList.Actor | eLocationList.StructureInstance); } ///////////////////////////////////////////////////////////////////////////// public static Position? GetLocationNear(Position pos, int area, double MinDistance, double MaxDistance, eLocationList location) { System.Diagnostics.Debug.WriteLine("GetLocationNear(Position, location)"); System.Diagnostics.Debug.WriteLine(location.ToString()); if (!Directory.Exists("locations")) { System.Diagnostics.Debug.WriteLine("Directory missing"); return null; } Position? closes = null; double distanceCloses = double.MaxValue; if (location.HasFlag(eLocationList.Actor)) { System.Diagnostics.Debug.WriteLine("Get by Actor"); getLocationNearJob(pos, area, MinDistance, MaxDistance, eLocationList.Actor, ref distanceCloses, ref closes); } if (location.HasFlag(eLocationList.StructureInstance)) { System.Diagnostics.Debug.WriteLine("Get by StructureInstance"); getLocationNearJob(pos, area, MinDistance, MaxDistance, eLocationList.StructureInstance, ref distanceCloses, ref closes); } if (location.HasFlag(eLocationList.Construction)) { System.Diagnostics.Debug.WriteLine("Get by Construction"); getLocationNearJob(pos, area, MinDistance, MaxDistance, eLocationList.Construction, ref distanceCloses, ref closes); } return closes; } public static Position? GetLocationNear(Position pos, int area, double MinDistance, eLocationList location) { return GetLocationNear(pos, area, MinDistance, double.MaxValue, location); } public static Position? GetLocationNear(Position pos, int area, eLocationList location) { return GetLocationNear(pos, area, 0.0f, double.MaxValue, location); } public static Position? GetLocationNear(Position pos, int area) { return GetLocationNear(pos, area, 0.0f, double.MaxValue, eLocationList.Actor | eLocationList.StructureInstance); } public static Position? GetLocationNear(double[] pos, int area, eLocationList location) { if (pos.Length < 3) { System.Diagnostics.Debug.WriteLine(" Array to small: " + pos.Length); return null; } return GetLocationNear(new Position(pos[0], pos[1], pos[2]), area, 0.0f, double.MaxValue, location); } public static Position? GetLocationNear(double[] pos, int area) { if (pos.Length < 3) { System.Diagnostics.Debug.WriteLine(" Array to small: " + pos.Length); return null; } return GetLocationNear(new Position(pos[0], pos[1], pos[2]), area, 0.0f, double.MaxValue, eLocationList.Actor | eLocationList.StructureInstance); } public static Position? GetLocationNear(Position pos, int area, double MinOffset) { return GetLocationNear(pos, area, MinOffset, double.MaxValue, eLocationList.Actor | eLocationList.StructureInstance); } public static Position? GetLocationNear(double[] pos, int area, double MinOffset, eLocationList location) { if (pos.Length < 3) { System.Diagnostics.Debug.WriteLine(" Array to small: " + pos.Length); return null; } return GetLocationNear(new Position(pos[0], pos[1], pos[2]), area, MinOffset, double.MaxValue, location); } public static Position? GetLocationNear(double[] pos, int area, double MinOffset) { if (pos.Length < 3) { System.Diagnostics.Debug.WriteLine(" Array to small: " + pos.Length); return null; } return GetLocationNear(new Position(pos[0], pos[1], pos[2]), area, MinOffset, double.MaxValue, eLocationList.Actor | eLocationList.StructureInstance); } public static Position? GetLocationNear(Position pos, int area, double MinOffset, double MaxOffset) { return GetLocationNear(pos, area, MinOffset, MaxOffset, eLocationList.Actor | eLocationList.StructureInstance); } public static Position? GetLocationNear(double[] pos, int area, double MinOffset, double MaxOffset, eLocationList location) { if (pos.Length < 3) { System.Diagnostics.Debug.WriteLine(" Array to small: " + pos.Length); return null; } return GetLocationNear(new Position(pos[0], pos[1], pos[2]), area, MinOffset, MaxOffset, location); } public static Position? GetLocationNear(double[] pos, int area, double MinOffset, double MaxOffset) { if (pos.Length < 3) { System.Diagnostics.Debug.WriteLine(" Array to small: " + pos.Length); return null; } return GetLocationNear(new Position(pos[0], pos[1], pos[2]), area, MinOffset, MaxOffset, eLocationList.Actor | eLocationList.StructureInstance); } #endregion #region GetLocationArrayNear public static Position[]? GetLocationArrayNear(int Count, Position pos, double MinDistance, double MaxDistance, eLocationList location) { System.Diagnostics.Debug.WriteLine("GetLocationNear(Position, location)"); System.Diagnostics.Debug.WriteLine(location.ToString()); if (!Directory.Exists("locations")) { System.Diagnostics.Debug.WriteLine("Directory missing"); return null; } Position[]? closes = new Position[Count]; double[] distanceCloses = new double[Count]; for (int i = 0; i < Count; i++) distanceCloses[i] = double.MaxValue; if (location.HasFlag(eLocationList.Actor)) { System.Diagnostics.Debug.WriteLine("Get by Actor"); getLocationNearJob(pos, 0, MinDistance, MaxDistance, eLocationList.Actor, ref distanceCloses, ref closes); } if (location.HasFlag(eLocationList.StructureInstance)) { System.Diagnostics.Debug.WriteLine("Get by StructureInstance"); getLocationNearJob(pos, 0, MinDistance, MaxDistance, eLocationList.StructureInstance, ref distanceCloses, ref closes); } if (location.HasFlag(eLocationList.Construction)) { System.Diagnostics.Debug.WriteLine("Get by Construction"); getLocationNearJob(pos, 0, MinDistance, MaxDistance, eLocationList.Construction, ref distanceCloses, ref closes); } int itmCount = 0; for(int i = 0; i MinOffset && dist < MaxOffset && (a == 0 || (a | area)==area)) { //System.Diagnostics.Debug.WriteLine(" [" + x.ToString() + " x " + y.ToString() + " x " + z.ToString() + "] = " + dist.ToString()); if (dist < distanceCloses) { System.Diagnostics.Debug.WriteLine(" New nearest found"); closes = new Position() { x = x, y = y, z = z }; distanceCloses = dist; } } } reader.Close(); reader.Dispose(); reader = null; } } private static void getLocationNearJob(Position pos, int area, double MinOffset, double MaxOffset, eLocationList location, ref double[] distanceCloses, ref Position[]? closes) { string file = getLocationFile(location); if (File.Exists(file)) { System.Diagnostics.Debug.WriteLine("Check Near by"); System.Diagnostics.Debug.WriteLine(" File: " + file); System.Diagnostics.Debug.WriteLine(" Area: " + area.ToString()); System.Diagnostics.Debug.WriteLine(" Coords: [" + pos.x.ToString() + " x " + pos.y.ToString() + " x " + pos.z.ToString() + "]"); StreamReader reader = new StreamReader(file); BinaryReader bin = new BinaryReader(reader.BaseStream); while (bin.BaseStream.Position < bin.BaseStream.Length) { int a = bin.ReadInt32(); double x = bin.ReadDouble(); double y = bin.ReadDouble(); double z = bin.ReadDouble(); double dist = pos.DistanceTo(x, y, z); if (dist > MinOffset && dist < MaxOffset && (a==0 || (a |area) == area)) { for(int i=0,c=distanceCloses.Length;ii;j--) { closes[j]=closes[j-1]; distanceCloses[j] = distanceCloses[j-1]; } closes[i] = new Position() { x = x, y = y, z = z }; distanceCloses[i] = dist; break; } } } } reader.Close(); reader.Dispose(); reader = null; } } public static int GetPositionCount(eLocationList location) { string file = getLocationFile(location); if (!File.Exists(file)) return 0; long size = (new FileInfo(file)).Length / 28; return (int) size; } public static Position? GetRandomPosition(int area, eLocationList location) { string file = getLocationFile(location); if (!File.Exists(file)) return null; int count = GetPositionCount(location); StreamReader reader = new StreamReader(file); BinaryReader bin = new BinaryReader(reader.BaseStream); int a; double x; double y; double z; int c = 5; bool bFound = false; if (area == 1) { do { int rnd = Random.Shared.Next(0, count - 1); bin.BaseStream.Seek(rnd * 28, SeekOrigin.Begin); a = bin.ReadInt32(); x = bin.ReadDouble(); y = bin.ReadDouble(); z = bin.ReadDouble(); if(a == area) { reader.Close(); reader.Dispose(); reader = null; return new Position(x, y, z); } c--; } while (c >= 0); } List pos = new List(); bin.BaseStream.Seek(0, SeekOrigin.Begin); do { a = bin.ReadInt32(); x = bin.ReadDouble(); y = bin.ReadDouble(); z = bin.ReadDouble(); if (a == area) pos.Add(new Position(x, y, z)); } while (bin.BaseStream.Position <= bin.BaseStream.Length - 28); if (pos.Count > 0) { int rnd = Random.Shared.Next(0, pos.Count - 1); reader.Close(); reader.Dispose(); reader = null; return pos[rnd]; } reader.Close(); reader.Dispose(); reader = null; return null; } public static Position? GetPositionAt(int area, eLocationList location, int index) { string file = getLocationFile(location); if (!File.Exists(file)) return null; int count = GetPositionCount(location); if (index >= count) return null; StreamReader reader = new StreamReader(file); BinaryReader bin = new BinaryReader(reader.BaseStream); bin.BaseStream.Seek(index * 28, SeekOrigin.Begin); int a = bin.ReadInt32(); double x = bin.ReadDouble(); double y = bin.ReadDouble(); double z = bin.ReadDouble(); reader.Close(); reader.Dispose(); reader = null; return new Position(x, y, z); } private static bool IsValidActor(Actor a) { if (a.SpawnerId == 0 && a.ActorSeed == 0) return false; if (a == null) return false; if (a.TypeId < 3) return true; if (a.TypeId < 7) return false; if (a.TypeId == 34) return false; if (a.TypeId == 36) return false; if (a.TypeId == 37) return false; return true; } public static string getLocationFile(eLocationList loc) { if (loc == eLocationList.Actor) return "locations\\actor.pos"; else if (loc == eLocationList.Construction) return "locations\\construction.pos"; else if (loc == eLocationList.StructureInstance) return "locations\\structure.pos"; return "temp.pos"; } } }