Exemple #1
0
    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);
    }
Exemple #2
0
        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;
                }
            }
        }
Exemple #3
0
        /// <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);
        }
Exemple #4
0
    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);
    }
Exemple #5
0
    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>();
    }
Exemple #6
0
    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);
    }
Exemple #7
0
    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);
    }
Exemple #8
0
 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);
 }
Exemple #9
0
    // 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);
    }
Exemple #10
0
        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("");
            }
        }
Exemple #11
0
        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;
        }
Exemple #12
0
        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);
        }
Exemple #13
0
        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;
                }
            }
        }
Exemple #14
0
        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();
        }
Exemple #15
0
        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 }
            };
        }
Exemple #16
0
        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;
            }
        }
Exemple #17
0
        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;
            }
        }
Exemple #18
0
    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);
    }
Exemple #19
0
        /// <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());
        }
Exemple #20
0
 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);
 }
Exemple #23
0
        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();
            }
        }
Exemple #24
0
    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);
    }
Exemple #25
0
        /// <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);
        }
Exemple #26
0
 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);
         }
     }
 }
Exemple #27
0
        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();
        }
Exemple #28
0
 public uint GetAllMaps(ushort pid, MapArray maps)
 {
     return Global_GetAllMaps(pid, (IntPtr)maps);
 }
Exemple #29
0
        /// <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);
        }