private MapArray <int> GenerateLandMask(MapArray <int> bitmask) { var simplex = new Simplex2D(43); int gbt_radius = (int)Mathf.Max(ChunkOrder, Mathf.Ceil(2.0f * Mathf.Log(1.0f + 1.00f * Radius) / Mathf.Log(7.0f))) - ChunkOrder + 1; for (int i = 0; i < Utils.Pow(7, gbt_radius); i++) { for (int j = 0; j < ChunkSize; j++) { GBTHex hex = new GBTHex(i * ChunkSize + j); Vector2 pos = hex.position; if (GetLandMaskValue(pos, simplex) > Threshold) { bitmask[hex] |= 1; foreach (GBTCorner corner in hex.GetCorners()) { bitmask[corner] |= 1; } } else { bitmask[hex] |= 2; foreach (GBTCorner corner in hex.GetCorners()) { bitmask[corner] |= 2; } } } } return(bitmask); }
private void ReadMEXP(int size, ref BinaryReader reader) { string[] names = ReadStringTable(ref reader, false, false); for (int i = 0; i < MapVariables.Count; i++) { Console.WriteLine($"{i} = {names[i]}; ${MapVariables.Count}"); if (MapVariables.ContainsKey(i)) { MapVariable v = MapVariables[i]; // v.Name = names[i]; MapVariables[i] = v; } } for (int i = MapVariables.Count; i < MapArrays.Count; i++) { Console.WriteLine($"{i} = {names[i]}; ${MapVariables.Count}"); if (MapArrays.ContainsKey(i)) { MapArray v = MapArrays[i]; // v.Name = names[i]; MapArrays[i] = v; } } }
/// <summary> /// Determines which areas are neighbors of other areas. /// </summary> /// <param name="areas">A map representation where each contiguous area has the same number (i.e. the output of <see cref="GetAreaGrid"/>).</param> /// <returns>A distinct set of neighbor relationships as byte-tuples (with the lower-value id coming first in each tuple).</returns> private static HashSet <(byte, byte)> GetNeighbors(MapArray <byte> areas) { /* Neighbors are areas with bordering spaces. I'm pretty sure we don't * have to worry about diagonals because I don't think they come up specifically, * and I don't think you can move between two diagonal neighbor spaces if there * are no other open spaces around. * * As such, this just goes from left-to-right in each row and bottom-to-top * in each column and whenever the adjacent numbers are different and non-zero, * that's a neighboring relationship. */ var neighbors = new HashSet <(byte, byte)>(); // TODO: Get rid of code duplication for (var x = 0; x < areas.Size.X; x++) { for (var y = 1; y < areas.Size.Y; y++) { if (areas[x, y - 1] != 0 && areas[x, y] != 0 && areas[x, y - 1] != areas[x, y]) { var first = areas[x, y - 1]; var second = areas[x, y]; // Consistently put the lesser number first to avoid duplication if (first < second) { neighbors.Add((first, second)); } else { neighbors.Add((second, first)); } } } } for (var y = 0; y < areas.Size.Y; y++) { for (var x = 1; x < areas.Size.X; x++) { if (areas[x - 1, y] != 0 && areas[x, y] != 0 && areas[x - 1, y] != areas[x, y]) { var first = areas[x - 1, y]; var second = areas[x, y]; // Consistently put the lesser number first to avoid duplication if (first < second) { neighbors.Add((first, second)); } else { neighbors.Add((second, first)); } } } } return(neighbors); }
private void DrawLandMask(MapArray <int> bitmask) { int gbt_radius = (int)Mathf.Max(ChunkOrder, Mathf.Ceil(2.0f * Mathf.Log(1.0f + 1.00f * Radius) / Mathf.Log(7.0f))) - ChunkOrder + 1; int count = 0; var chunks = new List <ChunkData>(); for (int i = 0; i < Utils.Pow(7, gbt_radius); i++) { var chunk = new ChunkData(i, ChunkSize); for (int j = 0; j < ChunkSize; j++) { var hex = new GBTHex(i * ChunkSize + j); Color hex_color = Color.black; if ((bitmask[hex] & 1) > 0) { count += 1; hex_color = Color.white; } chunk.AddColors(hex_color); } chunks.Add(chunk); } Debug.Log(count); m_DrawPolygonEvent.Invoke(chunks); }
void Start() { // Load Map Controllers Grid grid = FindObjectOfType <Grid>(); foreach (Tilemap map in FindObjectsOfType <Tilemap>()) { if (map.name == "FloorMap") { floorMap = map; } else if (map.name == "LeftWallMap") { leftWallMap = map; } else if (map.name == "RightWallMap") { rightWallMap = map; } else if (map.name == "BlockMap") { blockMap = map; } } maps = new Dictionary <string, Tilemap>(); maps.Add("left", leftWallMap); maps.Add("right", rightWallMap); nodes = new MapArray <Node>(); }
private bool CheckValidAdjacent(RiverNode node, GBTCorner adjacent, MapArray <int> bitmask, Dictionary <GBTCorner, RiverNode> node_lookup) { bool result = true; result = result && ((bitmask[adjacent] & 2) < 2); result = result && (node.Downslope == null || node.Downslope.Vertex != adjacent); result = result && (!node_lookup.ContainsKey(adjacent)); return(result); }
private MapArray <float> CalculateRiverWidths(List <RiverNode> rivernet) { var river_widths = new MapArray <float>(0.0f); foreach (RiverNode node in rivernet) { GetRiverWidth(node, river_widths); } return(river_widths); }
private float GetRiverWidth(RiverNode node, MapArray <float> river_widths) { if (node == null) { return(0.0f); } node.Width = CombineWidths(GetRiverWidth(node.Left, river_widths), GetRiverWidth(node.Right, river_widths)); river_widths[node.Vertex] = node.Width; return(node.Width); }
// Use this for initialization void Start() { ChunkSize = Utils.Pow(7, ChunkOrder); MapArray <int> bitmask = GenerateLandMask(new MapArray <int>(0)); List <RiverNode> rivernet = GenerateDownslopes(bitmask); //DrawGrayscaleArray(CalculateRiverWidths(rivernet), bitmask, 0.0f, 100.0f); CalculateRiverWidths(rivernet); DrawLandMask(bitmask); m_DrawRiverEvent.Invoke(rivernet); }
public void PrintMap() { for (int y = 0; y < MapArray.GetLength(1); y++) { for (int x = 0; x < MapArray.GetLength(0); x++) { Console.Write(MapArray[x, y]); Console.Write("\t"); } Console.WriteLine(""); } }
public void Compress() { string result = ""; for (int y = 0; y < MapArray.GetLength(0); y++) { for (int x = 0; x < MapArray.GetLength(1); x++) { result += MapArray[y, x].ToString(); } if (y != MapArray.GetLength(0) - 1) { result += ","; } } CompressedMapString = result; }
private void Move(int x, int y) { int newX = MapLocation[0] + x; int newY = MapLocation[1] + y; string errorMessage = string.Empty; if (newX < 1 || newX >= MapArray.GetLength(0) + 1 || newY < 1 || newY >= MapArray.GetLength(1) + 1) { errorMessage = "You don't go to outside map"; } else { MapLocation[0] = newX; MapLocation[1] = newY; } Print(errorMessage); }
private void ReadASTR(int size, ref BinaryReader reader) { int num = size / 4; for (int i = 0; i < num; i++) { int index = reader.ReadInt32(); if (MapArrays.ContainsKey(index)) { MapArray v = MapArrays[index]; v.IsString = true; MapArrays[index] = v; } else { ArrayIsStringCache[index] = true; } } }
public void Find() { Dictionary <double, int[]> distances = new Dictionary <double, int[]>(); for (int x = 0; x < MapArray.GetLength(0); x++) { for (int y = 0; y < MapArray.GetLength(1); y++) { char building = MapArray[x, y]; if (building != '#') { double euclidianDistance = CalculateEuclidian(x, y); distances.TryAdd(euclidianDistance, new int[] { x, y }); } } } Console.WriteLine("-------------------------------------"); Console.WriteLine(); if (distances.Keys.Count > 0) { IOrderedEnumerable <KeyValuePair <double, int[]> > orderedDistance = distances.OrderBy(o => o.Key); KeyValuePair <double, int[]> closestDistance = orderedDistance.FirstOrDefault(); Console.WriteLine($"Nearest Building is :{MapArray[closestDistance.Value[0], closestDistance.Value[1]]}"); Console.WriteLine($"Location X:{closestDistance.Value[0]} Location Y:{closestDistance.Value[1]}"); Console.WriteLine($"Distance : {Math.Round(closestDistance.Key, 2)}"); } else { Console.WriteLine("Nearest Building wasn't Found."); } Console.WriteLine(); Console.WriteLine("-------------------------------------"); Console.ReadKey(); }
public void ClearGrid(Terrain[,] t) { for (int x = 0; x < MapArray.GetLength(0); x++) { for (int y = 0; y < MapArray.GetLength(1); y++) { int tt = t[x, y].PassCost; MapArray[x, y] = t[x, y].PassCost; CandArray[x, y] = 1;//ignore if (t[x, y].PassCost == 999) { CandArray[x, y] = 1; } PlayerAStarArray[x, y] = t[x, y].PassCost; } } LocalArray = new int[, ] { { 999, 999, 999 }, { 999, 999, 999 }, { 999, 999, 999 } }; }
private void ReadARAY(int size, ref BinaryReader reader) { int numArrays = size / 8; for (int i = 0; i < numArrays; i++) { int num = reader.ReadInt32(); int arraySize = reader.ReadInt32(); MapArray a = new MapArray(); a.Values = new int[arraySize]; a.IsString = false; if (ArrayIsStringCache.ContainsKey(num)) { a.IsString = true; } MapArrays[num] = a; } }
private void ReadAINI(int size, ref BinaryReader reader) { InputStream.Seek(InputStream.Position - 4, SeekOrigin.Begin); int numArrays = MapArrays.Count; if (numArrays < 1) { Program.PrintError("AINI found before ARAY!"); return; } int num = (reader.ReadInt32() - 4) / 4; int index = reader.ReadInt32(); MapArray b = MapArrays[index]; for (int i = 0; i < num; i++) { int v = reader.ReadInt32(); b.Values[i] = v; } }
private void DrawGrayscaleArray(MapArray <float> array, MapArray <int> bitmask, float minimum, float maximum) { int gbt_radius = (int)Mathf.Max(ChunkOrder, Mathf.Ceil(2.0f * Mathf.Log(1.0f + 1.00f * Radius) / Mathf.Log(7.0f))) - ChunkOrder + 1; int count = 0; var chunks = new List <ChunkData>(); for (int i = 0; i < Utils.Pow(7, gbt_radius); i++) { var chunk = new ChunkData(i, ChunkSize); for (int j = 0; j < ChunkSize; j++) { var hex = new GBTHex(i * ChunkSize + j); if ((bitmask[hex] & 1) > 0) { var colors = new Color[7]; var corners = hex.GetCorners(); float average = 0.0f; for (int k = 0; k < 6; k++) { colors[1 + k] = GetGrayscale((array[corners[k]] - minimum) / (maximum - minimum)); average += array[corners[k]] / 6.0f; } colors[0] = GetGrayscale((average - minimum) / (maximum - minimum)); chunk.AddColors(colors); } else { chunk.AddColors(null); } } chunks.Add(chunk); } Debug.Log(count); m_DrawPolygonEvent.Invoke(chunks); }
/// <summary> /// Builds a list of <see cref="Area"/>s that have references to their neighbors. /// </summary> private List <Area> GetAreas(Map map, MapArray <byte> areaGrid) // TODO: Break up this function { var neighbors = GetNeighbors(areaGrid); var mesas = new Dictionary <byte, Mesa>(); var ramps = new Dictionary <byte, Ramp>(); var edges = new Dictionary <byte, Edge>(); var maxAreaId = areaGrid.Data.Max(); // Need to get the center of each area. To avoid translation confusion, // I'm just going to create arrays with an extra space even though there's // no relevant area 0 (which instead represents impassible terrain). var centers = new Location[maxAreaId + 1]; var locationLists = new List <Location> [maxAreaId + 1]; var xTotals = new int[maxAreaId + 1]; var yTotals = new int[maxAreaId + 1]; var counts = new int[maxAreaId + 1]; for (var x = 0; x < map.Size.X; x++) { for (var y = 0; y < map.Size.Y; y++) { var areaId = areaGrid[x, y]; if (areaId != 0) { xTotals[areaId] += x; yTotals[areaId] += y; counts[areaId] += 1; locationLists[areaId] = locationLists[areaId] ?? new List <Location>(); locationLists[areaId].Add(new Location { X = x, Y = y }); } } } // Build mesas first - ramps need mesa info in their constructor, // and for convenience mesas can add neighbors post-construction for (byte areaId = 1; areaId <= maxAreaId; areaId++) { // This part can really be done once for both ramps and mesas var center = new Location { X = xTotals[areaId] / counts[areaId], Y = yTotals[areaId] / counts[areaId] }; if (locationLists[areaId].Contains(center)) { centers[areaId] = center; } else { centers[areaId] = center.GetClosest(locationLists[areaId]); } if (map.CanBuild(locationLists[areaId][0])) { var height = map.HeightGrid[locationLists[areaId][0]]; mesas[areaId] = new Mesa(areaId, locationLists[areaId], centers[areaId], height); } } for (byte areaId = 1; areaId <= maxAreaId; areaId++) { if (!map.CanBuild(locationLists[areaId][0])) { var topAndBottomNeighborIds = neighbors .Where(pair => pair.Item1 == areaId || pair.Item2 == areaId) .Select(pair => pair.Item1 == areaId ? pair.Item2 : pair.Item1).ToList(); if (topAndBottomNeighborIds.Count != 2) { // This isn't really a ramp. Using the 'Edge' class for miscellaneous non-buildable // areas for now. This does assume that an Edge won't connect to a Ramp. var neighborMesas = topAndBottomNeighborIds.Select(id => mesas[id]).ToArray(); edges[areaId] = new Edge(areaId, locationLists[areaId], centers[areaId], neighborMesas); foreach (var neighborMesa in neighborMesas) { neighborMesa.AddNeighbor(edges[areaId]); } } else { var topAndBottomNeighbors = topAndBottomNeighborIds.Select(id => mesas[id]).OrderBy(mesa => mesa.Height).ToArray(); ramps[areaId] = new Ramp(areaId, locationLists[areaId], centers[areaId], topAndBottomNeighbors[1], topAndBottomNeighbors[0]); mesas[topAndBottomNeighborIds[0]].AddNeighbor(ramps[areaId]); mesas[topAndBottomNeighborIds[1]].AddNeighbor(ramps[areaId]); } } } // At some point there might be 'mesas' that are adjacent, because we want to // subdivide large areas with multiple mining locations even if there's no ramp. foreach (var neighbor in neighbors) { if (mesas.ContainsKey(neighbor.Item1) && mesas.ContainsKey(neighbor.Item2)) { mesas[neighbor.Item1].AddNeighbor(mesas[neighbor.Item2]); mesas[neighbor.Item2].AddNeighbor(mesas[neighbor.Item1]); } } return(mesas.Values.Concat <Area>(ramps.Values).ToList()); }
private static Bitmap GetImage(MapArray <byte> data) { return(GetImage(data.Data, data.Size)); }
public virtual uint GetMaps(MapArray maps) { return Location_GetMaps(thisptr, (IntPtr)maps); }
public BasicMapData(IEnumerable <Area> areas, MapArray <byte> areaGrid, IEnumerable <Deposit> deposits) { this.areas = new List <Area>(areas); this.areaGrid = new MapArray <byte>(areaGrid); this.deposits = new List <Deposit>(deposits); }
public void Disassemble(Stream outputStream) { OutputStream = outputStream; AssemblyName assemblyName = Assembly.GetExecutingAssembly().GetName(); WriteLine("// Disassembled by " + assemblyName.Name + " version " + assemblyName.Version); WriteLine("//"); WriteLine("// String Table:"); for (int i = 0; i < StringTable.Count; i++) { WriteLine($"// {i,4} " + StringTable[i]); } WriteLine(); if (Format == AcsFormat.Acs95) { WriteLine("#include \"common.acs\""); } else { WriteLine("#include \"zcommon.acs\""); } WriteLine(); foreach (var library in Libraries) { WriteLine($"#import \"{library}\""); } WriteLine(); WriteLine("// ================================================== MAP ARRAYS"); WriteLine(); if (ImportedMapArrays.Count > 0) { WriteLine($"/* Imported map arrays ({ImportedMapArrays.Count}:"); foreach (KeyValuePair <int, ImportedArray> pair in ImportedMapArrays) { int index = pair.Key; ImportedArray array = pair.Value; WriteLine($"/* imported - index {index:x4} */ int {array.Name}[{array.Size}];"); } WriteLine("//*/"); } foreach (var pair in MapArrays) { int index = pair.Key; MapArray mapArray = pair.Value; int[] array = mapArray.Values; string name = (!String.IsNullOrEmpty(mapArray.Name) ? mapArray.Name : $"_a_{index:x4}_"); string type = (mapArray.IsString ? "str" : "int"); Write($"{type} {name}[{array.Length}] = " + "{"); for (int i = 0; i < array.Length; i++) { if (mapArray.IsString) { string s; int sI = array[i]; if (sI < StringTable.Count) { s = StringTable[array[i]]; } else { s = "(DeACC: Invalid string index " + sI + ")"; } Write($"\"{s}\""); } else { Write(array[i].ToString()); } if (i < array.Length - 1) { Write(", "); } } WriteLine("};"); } WriteLine(); WriteLine("// ================================================== MAP VARIABLES"); WriteLine(); if (ImportedMapVariables.Count > 0) { WriteLine($"/* Imported map variables ({ImportedMapVariables.Count}:"); foreach (KeyValuePair <int, string> pair in ImportedMapVariables) { int index = pair.Key; string name = pair.Value; WriteLine($"int {name}; // imported - index {index:x4}"); } WriteLine("//*/"); } foreach (var pair in MapVariables) { int index = pair.Key; MapVariable var = pair.Value; string type = (var.IsString ? "str" : "int"); WriteLine($"{type} {var.Name} = {var.Value};"); } WriteLine(); WriteLine("// ================================================== FUNCTIONS"); WriteLine(); foreach (KeyValuePair <string, AcsFunction> pair in FunctionMap) { string name = pair.Key; AcsFunction function = pair.Value; string returnType = (function.Returns ? "int" : "void"); string args; if (function.NumberOfArguments > 0) { args = ""; for (int i = 0; i < function.NumberOfArguments; i++) { args += $"int _p_{ParameterCounter:x4}_"; ParameterCounter++; if (i < function.NumberOfArguments - 1) { args += ", "; } } } else { args = "void"; } WriteLine($"// Pointer: {function.Pointer}; Size = {function.CodeSize}"); WriteLine($"function {returnType} {name} ({args})"); WriteLine("{"); WriteCode(function.Code); WriteLine("}"); WriteLine(); } WriteLine(); WriteLine("// ================================================== SCRIPTS"); WriteLine(); foreach (KeyValuePair <int, AcsScript> pair in Scripts) { int number = pair.Key; AcsScript script = pair.Value; string args = "(void)"; string type = ""; string flags = ""; if (script.NumberOfArguments > 0) { args = "("; for (int i = 0; i < script.NumberOfArguments; i++) { args += $"int _p_{ParameterCounter:x4}_"; ParameterCounter++; if (i < script.NumberOfArguments - 1) { args += ", "; } } args += ")"; } else if (script.NumberOfArguments == 0 && script.Type != ScriptType.Closed) { args = ""; } if (script.Type != ScriptType.Closed) { type = script.Type.ToString().ToUpper(); } if ((script.Flags & (int)ScriptFlags.Net) != 0) { flags += "NET "; } if ((script.Flags & (int)ScriptFlags.Clientside) != 0) { flags += "CLIENTSIDE "; } string argsSpace = (String.IsNullOrEmpty(args) ? "" : " "); string typeSpace = (script.Type != ScriptType.Closed ? " " : ""); string name = (String.IsNullOrEmpty(script.Name) ? number.ToString() : $"\"{script.Name}\""); WriteLine($"// Pointer: {script.Pointer}; Size = {script.CodeSize}"); WriteLine($"Script {name}{argsSpace}{args}{typeSpace}{type} {flags}"); WriteLine("{"); WriteCode(script.Code); WriteLine("}"); WriteLine(); } }
private List <RiverNode> GenerateDownslopes(MapArray <int> bitmask) { var simplex = new Simplex2D(52562); MapArray <float> weights = new MapArray <float>(1000.0f); var rivernet = new List <RiverNode>(); var node_lookup = new Dictionary <GBTCorner, RiverNode>(); var queue = new BinaryMinHeap <QueueElement <RiverNode> >(); // Assign weights to each land vertex and add coast vertices to the queue. foreach (KeyValuePair <GBTCorner, int> kvp in bitmask.GetCornerEnumerator()) { if ((kvp.Value & 1) > 0) { weights[kvp.Key] = simplex.GetFractalNoise(4.0f * kvp.Key.position / Radius); if ((kvp.Value & 2) > 0) { RiverNode node = new RiverNode(kvp.Key); queue.Push(new QueueElement <RiverNode>(weights[kvp.Key], node)); rivernet.Add(node); node_lookup[kvp.Key] = node; } } } while (queue.Count > 0) { RiverNode node = queue.Pop().value; GBTCorner lowest = new GBTCorner(-1); float lowest_weight = 999.0f; // Find the neighboring land node with the lowest weight which has not already // been added to the network. foreach (GBTCorner adjacent in node.Vertex.GetAdjacent()) { if (CheckValidAdjacent(node, adjacent, bitmask, node_lookup) && weights[adjacent] < lowest_weight) { lowest_weight = weights[adjacent]; lowest = adjacent; } } // Add the lowest node to the network, and push it and the into the queue. if (lowest.isValid()) { var new_node = new RiverNode(lowest); new_node.Downslope = node; if (node.Left == null) { node.Left = new_node; // If the node hasn't been filled, add it to the queue again, but with a lower weight. weights[node.Vertex] += 0.05f; queue.Push(new QueueElement <RiverNode>(weights[node.Vertex], node)); } else if (node.Right == null) { node.Right = new_node; } node_lookup[lowest] = new_node; queue.Push(new QueueElement <RiverNode>(weights[lowest], new_node)); } } return(rivernet); }
/// <summary> /// Builds a representation of the map where each distinct area has a different value. /// </summary> /// <returns>A represntation of the map where all spaces that are the same 'area' have the same numeric value. /// Locations that are not accessible to ground units have a value of 0.</returns> private MapArray <byte> GetAreaGrid(Map map) { /* Pick a starting location and fan out to adjacent locations. * * If it's a buildable zone, find all spots that are also buildable, * adjacent, and at the same height. This will be a 'mesa'. * * If it's not buildable but it can be traversed then it's a ramp, * find all adjacent spots that can also be traversed and are not buildable. * * We can probably use the starting locations on the map as safe places to begin, * since they'll be base locations. */ // TODO: Add support for "islands" - this mechanism will only capture areas connected to the starting location // Resulting array of areas MapArray <byte> areas = new MapArray <byte>(map.Size); // Area id - will be incremented as we move to other areas // (and before assigning the first area as well) byte currentId = 0; var locations = new HashSet <Location>(); var otherAreaLocations = new HashSet <Location>(); var startPosition = map.Raw.StartLocations[0]; otherAreaLocations.Add(new Location { X = (int)startPosition.X, Y = (int)startPosition.Y }); while (otherAreaLocations.Count > 0) { var lastLocation = otherAreaLocations.First(); otherAreaLocations.Remove(lastLocation); currentId++; areas[lastLocation] = currentId; AddAdjacentLocations(map, lastLocation, locations, areas); while (locations.Count > 0) { var location = locations.First(); locations.Remove(location); otherAreaLocations.Remove(location); if (map.CanBuild(lastLocation) == map.CanBuild(location)) { areas[location] = currentId; AddAdjacentLocations(map, location, locations, areas); } else { otherAreaLocations.Add(location); } } } return(areas); }
private void AddAdjacentLocations(Map map, Location location, HashSet <Location> locations, MapArray <byte> areas) { foreach (var adjacentLocation in AdjacentLocations(map, location)) { if (areas[adjacentLocation] == 0 && (map.CanBuild(adjacentLocation) || map.CanTraverse(adjacentLocation))) { locations.Add(adjacentLocation); } } }
public void Print(string message = "") { Console.Clear(); Console.WriteLine(); for (int x = 0; x < MapArray.GetLength(0) + 1; x++) { Console.WriteLine(); for (int y = 0; y < MapArray.GetLength(1) + 1; y++) { string writing = string.Empty; if (x == 0 && y == 0) { writing = $"X|Y"; } else if (x == 0) { writing = $"{y - 1}"; } else { if (y == 0) { writing = $"{x - 1}"; } else { if (x == MapLocation[0] && y == MapLocation[1]) { Console.BackgroundColor = ConsoleColor.White; Console.ForegroundColor = ConsoleColor.Black; } else { Console.BackgroundColor = ConsoleColor.Black; Console.ForegroundColor = ConsoleColor.White; } writing = $"{MapArray[x - 1, y - 1]}"; } } while (writing.Length < 3) { writing += " "; } Console.Write($"{writing}"); } } if (!string.IsNullOrEmpty(message)) { Console.WriteLine(); Console.WriteLine(message); Console.WriteLine(); } Console.WriteLine(); Console.WriteLine(); }
public uint GetAllMaps(ushort pid, MapArray maps) { return Global_GetAllMaps(pid, (IntPtr)maps); }
/// <summary> /// Builds a list of resource deposits. Requires that the 'areas' and 'areaGrid' fields be set. /// </summary> private List <Deposit> GetDeposits(IReadOnlyList <Unit> units, IReadOnlyList <Area> areas, MapArray <byte> areaGrid) { var resourcesByArea = units.Where(u => u.IsMineralDeposit || u.IsVespeneGeyser) .GroupBy(m => areaGrid[(int)m.X, (int)m.Y]); var deposits = new List <Deposit>(); foreach (var resourceArea in resourcesByArea) { var resources = resourceArea.ToList(); while (resources.Count > 0) { var depositResources = new List <Unit>(); var nextResource = resources[0]; resources.RemoveAt(0); while (nextResource != null) { depositResources.Add(nextResource); resources.Remove(nextResource); nextResource = resources.FirstOrDefault(r => depositResources.Any(d => r.GetDistance(d) < 5f)); } var area = areas.First(a => a.Id == areaGrid[(int)depositResources[0].X, (int)depositResources[0].Y]); var center = new Location { X = (int)(depositResources.Sum(u => u.X) / depositResources.Count), Y = (int)(depositResources.Sum(u => u.Y) / depositResources.Count) }; deposits.Add(new Deposit(area, center, depositResources)); } } return(deposits); }