private void Start()
    {
        this.tilemap      = GameObject.Find("Walls").GetComponent <Tilemap>();
        this.CellSize     = (Vector2Int)tilemap.cellBounds.size;
        this.halfCellSize = this.CellSize / 2;
        this.mapSize      = new Vector2(16, 16);
        this.aStarNode    = new AStar2D();
        this.cellPath     = new List <Vector2>();
        this.obstacles    = new List <Vector2>();

        this.theGrid = GameObject.Find("Grid").GetComponent <Grid>();

        GameObject[] obstaclesArray = GameObject.FindGameObjectsWithTag("NavigationObstacle");
        Tilemap[]    maps           = new Tilemap[obstaclesArray.Length];

        for (int i = 0; i < obstaclesArray.Length; i++)
        {
            maps[i] = obstaclesArray[i].GetComponent <Tilemap>();

            foreach (Vector3Int pos in maps[i].cellBounds.allPositionsWithin)
            {
                if (maps[i].GetTile(pos) != null)
                {
                    this.obstacles.Add((Vector3)pos);
                }
            }
        }

        List <Vector2> walkableCells = CalculateAStarWalkableCells(this.obstacles);

        ConnectAStarWalkableCells(walkableCells);
    }
 void Start()
 {
     pathfind = GetComponent<AStar2D>();
     humanSpawnPoint = GameObject.Find ("HumanSpawnPoint");
     armyScript = humanSpawnPoint.GetComponent<HumanSpawnPoint> ().monsterCore.GetComponent<MonsterCore> ().armyScript;
     nearbyPawns = new List<GameObject> ();
     InvokeRepeating("healNearby", 0, 1);
 }
Esempio n. 3
0
    public void GetGoalPosition()
    {
        UpdateStartPosition();
        StartNode = new Node2D(
            GridManager2D.Instance.GetGridCellCenter(GridManager2D.Instance.GetGridIndex(_startPos)));

        GoalNode = new Node2D(
            GridManager2D.Instance.GetGridCellCenter(GridManager2D.Instance.GetGridIndex(_player.transform.position)));

        _pathArray = AStar2D.FindPath(StartNode, GoalNode);
    }
    void Start()
    {
        health = 50.0f + constitution * 10;
        maxHealth = 50.0f + constitution * 10;
        speed = 1.0f + agility * 0.33f;
        hitDamage = 4.0f + strength;

        pathfind = GetComponent<AStar2D>();
        pathfind.speed = speed;

        //		pathfind.seeker.StartPath(transform.position, spawnpoint.GetComponent<HumanSpawnPoint>().monsterCore.transform.position, pathfind.OnPathComplete);
    }
Esempio n. 5
0
    private void GetGoalPosition(Vector2 startPosition)
    {
        StartNode = new Node2D(
            GridManager2D.Instance.GetGridCellCenter(GridManager2D.Instance.GetGridIndex(startPosition)));

        var mousePos = GetMouseInput();

        GoalNode = new Node2D(
            GridManager2D.Instance.GetGridCellCenter(GridManager2D.Instance.GetGridIndex(mousePos)));

        if (GoalNode.position.y < 1f)
        {
            GoalNode = StartNode;
        }
        _pathArray = AStar2D.FindPath(StartNode, GoalNode);
    }
Esempio n. 6
0
    public override void _Ready()
    {
        _aStar = new AStar2D();
        _grid  = (Node2D)GetNode("Grid");

        if (!debug)
        {
            _grid.Visible = false;
        }

        _tilestoWorld = new Godot.Collections.Dictionary();
        _gridRects    = new Godot.Collections.Dictionary <int, ColorRect>();

        _updateTraversableTilesTimer          = (Timer)GetNode("UpdateTraversableTilesTimer");
        _updateTraversableTilesTimer.WaitTime = UpdateTRaversableTilesTime;
    }
Esempio n. 7
0
    // Called every time stabilizes (mode changes to RigidBody2D.MODE_STATIC).
    //
    // Once all rooms have stabilized it calculates a playable dungeon `_path` using the MST
    // algorithm. Based on the calculated `_path`, it populates `_data` with room and corridor tile
    // positions.
    //
    // It emits the "rooms_placed" signal when it finishes so we can begin the tileset placement.
    private void _on_Room_sleeping_state_changed()
    {
        GD.Print("_on_Room_sleeping_state_changed");

        _sleepingRooms++;
        if (_sleepingRooms < MaxRooms)
        {
            return;
        }

        var mainRooms          = new List <Room>();
        var mainRoomsPositions = new List <Vector2>();

        foreach (Room room in Rooms.GetChildren())
        {
            if (IsMainRoom(room))
            {
                mainRooms.Add(room);
                mainRoomsPositions.Add(room.Position);
            }
        }

        _path = Utils.MST(mainRoomsPositions);

        foreach (int point1Id in _path.GetPoints())
        {
            foreach (int point2Id in _path.GetPoints())
            {
                if (point1Id != point2Id &&
                    !_path.ArePointsConnected(point1Id, point2Id) &&
                    _rng.Randf() < ReconnectionFactor)
                {
                    _path.ConnectPoints(point1Id, point2Id);
                }
            }
        }

        foreach (Room room in mainRooms)
        {
            AddRoom(room);
        }
        AddCorridors();

        SetProcess(false);
        EmitSignal(nameof(RoomsPlaced));
    }
Esempio n. 8
0
    //Calculates the Minimum Spanning Tree (MST) for given points and returns an `AStar2D` graph using Prim's algorithm.
    // https://en.wikipedia.org/wiki/Prim%27s_algorithm
    // https://en.wikipedia.org/wiki/Minimum_spanning_tree
    public static AStar2D MST(List <Vector2> pointsList)
    {
        var result = new AStar2D();

        var firstPoint = pointsList.LastOrDefault();

        //Start from an arbitrary point in the list of points
        result.AddPoint(result.GetAvailablePointId(), firstPoint);
        pointsList.Remove(firstPoint);

        //Loop through all points, erasing them as we connect them.
        while (pointsList.Any())
        {
            var currentPosition = Vector2.Zero;
            var minPosition     = Vector2.Zero;
            var minDistance     = float.PositiveInfinity;

            foreach (int point1Id in result.GetPoints())
            {
                //Compare each point added to the Astar2D graph to each remaining point to find the closest one
                var point1Position = result.GetPointPosition(point1Id);
                foreach (var point2Position in pointsList)
                {
                    var distance = point1Position.DistanceTo(point2Position);
                    if (minDistance > distance)
                    {
                        //We use the variables to store the coordinates of the closest point.
                        //We have to loop over all points to ensure it's the closest.
                        currentPosition = point1Position;
                        minPosition     = point2Position;
                        minDistance     = distance;
                    }
                }
            }

            //Connect the point closest to the "current position" with our new point
            var pointId = result.GetAvailablePointId();
            result.AddPoint(pointId, minPosition);
            result.ConnectPoints(result.GetClosestPoint(currentPosition), pointId);
            pointsList.Remove(minPosition);
        }

        return(result);
    }
Esempio n. 9
0
        //private static IEnumerator CreateTunnels(IVector2 _entryPt) //UNITY
        private static void CreateTunnels(IVector2 _entryPt)
        {
            var map    = m_Tilemap.m_MapData;
            var points = new List <Point2D>();

            foreach (var room in m_Tilemap.m_Rooms)
            {
                points.Add(new Point2D(room.Anchor.x, room.Anchor.y));
            }

            var dt   = new DelaunayTriangulation(points);
            var tris = dt.Triangulate(); //TODO Creates null on seed 22

            if (tris == null)
            {
                m_Tilemap.m_Tunnels = null;
                //yield break; //UNITY
            }

            var roomGraph = new ioGraph <IVector2>();

            foreach (var tri in tris)
            {
                var p1 = new IVector2((int)tri.a.x, (int)tri.a.y);
                var p2 = new IVector2((int)tri.b.x, (int)tri.b.y);
                var p3 = new IVector2((int)tri.c.x, (int)tri.c.y);

                roomGraph.AddEdge(p1, p2, m_Random.NextDouble() * 100d);
                roomGraph.AddEdge(p2, p1, m_Random.NextDouble() * 100d);
                roomGraph.AddEdge(p2, p3, m_Random.NextDouble() * 100d);
                roomGraph.AddEdge(p3, p2, m_Random.NextDouble() * 100d);
                roomGraph.AddEdge(p1, p3, m_Random.NextDouble() * 100d);
                roomGraph.AddEdge(p3, p1, m_Random.NextDouble() * 100d);
            }

            var roomMST = roomGraph.PrimMST();


            //Get extra room connections beyond mst and add them to the graph

            var extTunnelPct = (Settings.ExtraTunnelMinPct +
                                (Settings.ExtraTunnelMaxPct - Settings.ExtraTunnelMinPct) * m_Random.NextDouble());
            var remEdgeAddCnt = (int)((roomGraph.EdgeCount - roomMST.EdgeCount) * extTunnelPct);

            Msg.LogDebug(TAG_DEBUG, "Room MST:", MsgPriLvl.HIGH);
            Msg.LogDebug(TAG_DEBUG, roomMST.ToString(), MsgPriLvl.HIGH);


            var remAvailEdges = roomGraph.GetNodeConnectionsList();

            foreach (var connection in roomMST.GetNodeConnectionsList())
            {
                if (remAvailEdges.Contains(connection))
                {
                    remAvailEdges.Remove(connection);
                }
                if (remAvailEdges.Contains(connection.Swapped))
                {
                    remAvailEdges.Remove(connection.Swapped);
                }
            }


            if (remEdgeAddCnt > remAvailEdges.Count)
            {
                Msg.LogDebug(TAG_DEBUG,
                             "Additional Edge count (beyond MST) greater than available edges remaining.  Trimming",
                             MsgPriLvl.HIGH);
                remEdgeAddCnt = remAvailEdges.Count;
            }

            for (var i = 0; i < remEdgeAddCnt; ++i)
            {
                var connection = remAvailEdges[m_Random.Next(remAvailEdges.Count)];

                var edge = new ioGraph <IVector2> .ioGraphEdge(1, connection.v2);

                roomMST.AddEdge(connection.v1, edge);
                remAvailEdges.Remove(connection);
            }

            Msg.LogDebug(TAG_DEBUG, "Room MST (with extra conns):", MsgPriLvl.HIGH);
            Msg.LogDebug(TAG_DEBUG, roomMST.ToString(), MsgPriLvl.HIGH);


            Msg.LogDebug(TAG_DEBUG, roomMST.GetEdgeDesc(), MsgPriLvl.LOW);

            //Create tunnel paths
            m_Tilemap.m_Tunnels = new List <TunnelNetwork>();

            var logMsg = "Creating Tunnels";

            Msg.Log(LOGKEY_MESSAGES, LOGKEY_MESSAGES, logMsg, MsgPriLvl.HIGH);
            var edgesDone = 0;

            double debugRoutingTime = 0;
            double debugAStarTime   = 0;

            for (var nodeIdx = 0; nodeIdx < roomMST.NodeCount; ++nodeIdx)
            {
                foreach (var edge in roomMST.GetConnectionsFast(nodeIdx))
                {
                    var fromVector = roomMST.GetNode(nodeIdx);
                    var toVector   = roomMST.GetNode(edge.ToNode);
                    Progress = 0.5d + (edgesDone / (double)roomMST.EdgeCount) / 2d;
                    logMsg   = "Creating Tunnels " + (int)((edgesDone / (float)roomMST.EdgeCount) * 100);
                    //Log(logMsg);
                    Msg.Log(LOGKEY_MESSAGES, LOGKEY_MESSAGES, logMsg, MsgPriLvl.HIGH);

                    var roomsToConnect = new[] { m_Tilemap.m_Rooms.Get(fromVector), m_Tilemap.m_Rooms.Get(toVector) };
                    Msg.LogDebug(TAG_DEBUG, fromVector + " -> " + toVector, MsgPriLvl.MED);

                    if (roomsToConnect[0] == null || roomsToConnect[1] == null)
                    {
                        throw new NullReferenceException(TAG_DEBUG + ":Room not found in roomGroup.");
                    }

                    //Find closest tunnel tie if exists =========================================
                    //If Rooms are already connected  then skip
                    var fromNets = new List <TunnelNetwork>();
                    var toNets   = new List <TunnelNetwork>();

                    var skipConnection = false;
                    foreach (var tNet in m_Tilemap.m_Tunnels)
                    {
                        if (tNet.ConnectsTo(roomsToConnect[0]))
                        {
                            fromNets.Add(tNet);
                        }
                        if (tNet.ConnectsTo(roomsToConnect[1]))
                        {
                            toNets.Add(tNet);
                        }
                    }

                    if (fromNets.Any(toNets.Contains))
                    {
                        skipConnection = true;
                    }

                    if (skipConnection)
                    {
                        Msg.LogDebug(TAG_DEBUG, "Rooms already connected by same Net... Skipping", MsgPriLvl.MED);
                        edgesDone++;
                        continue;
                    }


                    if (Settings.ClosestConnect)
                    {
                        var fromCoordsf = new HashSet <IVector2>();
                        var toCoordsf   = new HashSet <IVector2>();

                        //Get all coords of from and to nets (exluding room doorways)
                        foreach (var net in fromNets)
                        {
                            fromCoordsf.UnionWith(net.GetAllPathCoords(true));
                        }
                        foreach (var net in toNets)
                        {
                            toCoordsf.UnionWith(net.GetAllPathCoords(true));
                        }

                        //Remove room wall coordinates
                        foreach (var room in m_Tilemap.m_Rooms)
                        {
                            fromCoordsf.RemoveWhere(_coord => room.GetWallCoords(true).Contains(_coord));
                            toCoordsf.RemoveWhere(_coord => room.GetWallCoords(true).Contains(_coord));
                        }

                        //Add anchors of rooms to connect
                        fromCoordsf.Add(fromVector);
                        toCoordsf.Add(toVector);

                        //Use Manhattan Distance for distance calc
                        var distance            = AStar2D.ManhattanDistance(fromVector, toVector, 1);
                        var closestTunnelCoords =
                            Support2D.GetNearestCoords(fromCoordsf, toCoordsf, ref distance);
                        if (closestTunnelCoords[0] != null)
                        {
                            if (!closestTunnelCoords[0].Value.Equals(fromVector))
                            {
                                roomsToConnect[0] = null;
                                fromVector        = closestTunnelCoords[0].Value;
                            }
                        }

                        if (closestTunnelCoords[1] != null)
                        {
                            if (!closestTunnelCoords[1].Value.Equals(toVector))
                            {
                                roomsToConnect[1] = null;
                                toVector          = closestTunnelCoords[1].Value;
                            }
                        }
                    }


                    Msg.LogDebug(TAG_DEBUG, "Creating Routing Cost Map.", MsgPriLvl.MED);
                    var routingTimeStamp = DateTime.Now;
                    var costGrid         = CreateRoutingCostMap(roomsToConnect.ToList(), new IVector2(map.Dims.x, map.Dims.y),
                                                                Settings.TunnelBuffer, Settings.TunnelPathMag, Settings.CalcRoutingStrength);
                    debugRoutingTime += (DateTime.Now - routingTimeStamp).TotalSeconds;
                    Msg.LogDebug(TAG_DEBUG,
                                 "Rounting map finished. Took " + (DateTime.Now - routingTimeStamp).TotalSeconds + " seconds.",
                                 MsgPriLvl.MED);

                    //UNITY DEBUG

                    /*
                     * // Unity Draw routing map to texture
                     *
                     *
                     *
                     * //Clear texture to default weight
                     *
                     *
                     * var texture = (Texture2D)TileMap2D.meshRenderer.material.mainTexture;
                     * if (!texture)
                     * {
                     *
                     *  texture = new Texture2D(costGrid.Dims.x, costGrid.Dims.y);
                     *  texture.filterMode = FilterMode.Point;
                     *  TileMap2D.meshRenderer.material.mainTexture = texture;
                     *  if (costGrid.Dims.x > costGrid.Dims.y)
                     *      TileMap2D.instance.transform.localScale = new Vector3(1, 0, costGrid.Dims.y / (float)costGrid.Dims.x);
                     *  else
                     *      TileMap2D.instance.transform.localScale = new Vector3(costGrid.Dims.x / (float)costGrid.Dims.y, 1, 1);
                     * }
                     * if (true)
                     * {
                     *
                     *  var defCost = Settings.CalcRoutingStrength * 2d + 1;
                     *  var weightMax = (defCost + defCost * Settings.TunnelBuffer);
                     *
                     *  var weights = costGrid.Weights;
                     *  for (int y = 0; y < costGrid.Dims.y; ++y)
                     *      for (int x = 0; x < costGrid.Dims.x; ++x)
                     *      {
                     *          double weight = weights[x, y];
                     *          float whiteLevel = (float)(weight / defCost);
                     *          var color = new Color(whiteLevel / 2f, whiteLevel / 2f, whiteLevel / 2f, 1f);
                     *          if (whiteLevel > 1f)
                     *          {
                     *              whiteLevel = (float)(weight - defCost) / (float)(weightMax - defCost);
                     *              whiteLevel = (whiteLevel / 2f + 0.5f);
                     *              color = new Color(whiteLevel, whiteLevel, whiteLevel, 1f);
                     *          }
                     *          texture.SetPixel(x, y, color);
                     *      }
                     *
                     *  var doors = new HashSet<IVector2>();
                     *  foreach (var tNet in m_Tilemap.m_Tunnels)
                     *      foreach (var room in tNet.ConnectedRooms)
                     *          if (room != null) doors.UnionWith(room.Doorways);
                     *
                     *  foreach (var doorway in doors)
                     *      texture.SetPixel(doorway.x, doorway.y, new Color(0f, 0f, 1f, 1f));
                     *
                     *  texture.Apply();
                     *
                     *  yield return null;
                     * }
                     * // --------------------------
                     *///END UNITY BLOCK


                    Msg.LogDebug(TAG_DEBUG, "Running AStar algorithm...", MsgPriLvl.MED);
                    routingTimeStamp = DateTime.Now;
                    var routingStr = Settings.CalcRoutingStrength;
                    var turnCost   = Settings.CalcRoutingStrength * Settings.CalcTurnCost;
                    if (routingStr == 0)
                    {
                        turnCost = Settings.CalcTurnCost;
                    }

                    /*yield return  //UNITY
                     *  TileMap2D.instance.StartCoroutine(AStar2D.AStar(costGrid, fromVector, toVector,
                     *      turnCost, Settings.TunnelPathMag,
                     *      AStar2D.ManhattanDistance));
                     */
                    AStar2D.AStar(costGrid, fromVector, toVector, turnCost, Settings.TunnelPathMag,
                                  AStar2D.ManhattanDistance);
                    debugAStarTime += (DateTime.Now - routingTimeStamp).TotalSeconds;
                    Msg.LogDebug(TAG_DEBUG,
                                 "AStar finished. Took " + (DateTime.Now - routingTimeStamp).TotalSeconds + " seconds.",
                                 MsgPriLvl.MED);

                    var vecPath = AStar2D.AStarPath;

                    if (vecPath == null)
                    {
                        logMsg = "Unable to create path:  " + fromVector + " --> " + toVector;
                        //Log(logMsg);
                        Msg.LogDebug(TAG_DEBUG, logMsg, MsgPriLvl.HIGH);
                        continue;
                    }

                    var path = new TunnelNetwork.IPath(vecPath, roomsToConnect[0], roomsToConnect[1]);
                    TrimTunnelAtRooms(ref path);
                    AddPathToNetwork(path);


                    ++edgesDone;
                }
            }

            //Add Entry Point and connect to closest room

            var connectEntry = true;
            var entryDist    = int.MaxValue;

            //Connect entry point to closest room or tunnel
            foreach (var room in m_Tilemap.m_Rooms)
            {
                if (room.ContainsCoord(_entryPt, true))
                {
                    connectEntry = false;
                    break;
                }
            }

            if (connectEntry)
            {
                var availCoords = new HashSet <IVector2>();
                foreach (var tNet in m_Tilemap.m_Tunnels)
                {
                    availCoords.UnionWith(tNet.GetAllPathCoords(false));
                }

                foreach (var room in m_Tilemap.m_Rooms)
                {
                    availCoords.RemoveWhere(_coord => room.GetWallCoords(true).Contains(_coord));
                }

                availCoords.UnionWith(m_Tilemap.m_Rooms.Anchors);

                double distance      = m_Tilemap.Dims.x + m_Tilemap.Dims.y;
                var    closestCoords = Support2D.GetNearestCoords(new HashSet <IVector2> {
                    _entryPt
                }, availCoords,
                                                                  ref distance);

                var closestRoom = m_Tilemap.m_Rooms.Get(closestCoords[1].Value);
                var excludeList = new List <Room>();
                if (closestRoom != null)
                {
                    excludeList.Add(closestRoom);
                }

                var turnCost        = Settings.CalcRoutingStrength * Settings.CalcTurnCost;
                var entryRouteGraph = CreateRoutingCostMap(excludeList,
                                                           new IVector2(map.Dims.x, map.Dims.y), Settings.RoomBufferMax, Settings.TunnelPathMag,
                                                           Settings.CalcRoutingStrength);

                /*  //UNITY
                 * yield return TileMap2D.instance.StartCoroutine(AStar2D.AStar(entryRouteGraph, _entryPt, closestCoords[1].Value,
                 *  turnCost, Settings.TunnelPathMag,
                 *  AStar2D.ManhattanDistance));
                 * */
                AStar2D.AStar(entryRouteGraph, _entryPt, closestCoords[1].Value,
                              turnCost, Settings.TunnelPathMag,
                              AStar2D.ManhattanDistance);
                var entryConnect = AStar2D.AStarPath;

                //TODO make entry point a room?

                /*var entryRoom = new Room(new Bounds(_entryPt.x - 1, _entryPt.y - 1, _entryPt.x + 1, _entryPt.y + 1),
                 *  Room.ShapeType.Rectangle);
                 * m_Tilemap.m_Rooms.Add(entryRoom);*/

                var entryPath = new TunnelNetwork.IPath(entryConnect, null, closestRoom);
                TrimTunnelAtRooms(ref entryPath);
                AddPathToNetwork(entryPath);
            }

            Msg.LogDebug(TAG_DEBUG, "Total routing graph time: " + debugRoutingTime, MsgPriLvl.HIGH);
            Msg.LogDebug(TAG_DEBUG, "Total AStar time: " + debugAStarTime, MsgPriLvl.HIGH);
        }
Esempio n. 10
0
    void Start()
    {
        constitution = level;
        agility = level;
        strength = level;

        for(int i = 0; i < level - 1; i++) {
            int skill = UnityEngine.Random.Range (1, 5);

            switch(skill) {
            case 1:
                constitution ++;
                break;
            case 2:
                agility ++;
                break;
            case 3:
                strength ++;
                break;
            }
        }

        health = 50.0f + constitution * 10;
        speed = 1.0f + agility * 0.33f;
        hitDamage = 4.0f + strength;

        pathfind = GetComponent<AStar2D>();
        if(pathfind == null) {
            Debug.Log ("Pathfind not found!");
        }

        grid = spawnpoint.GetComponent<HumanSpawnPoint>().grid;
        map = spawnpoint.GetComponent<HumanSpawnPoint>().map;
        resourcesScript = Camera.main.gameObject.GetComponent<ResourcesControl>();
        armyScript = spawnpoint.GetComponent<HumanSpawnPoint>().monsterCore.GetComponent<MonsterCore>().armyScript;
        pathfind.speed = speed;
        pathfind.seeker.StartPath(transform.position, spawnpoint.GetComponent<HumanSpawnPoint>().monsterCore.transform.position, pathfind.OnPathComplete);
    }
Esempio n. 11
0
    void Start()
    {
        pathfind = GetComponent<AStar2D>();
        if(pathfind == null) {
            Debug.Log ("Pathfind not found!");
        }

        grid = spawnpoint.GetComponent<HumanSpawnPoint>().grid;
        map = spawnpoint.GetComponent<HumanSpawnPoint>().map;
        resourcesScript = Camera.main.gameObject.GetComponent<ResourcesControl>();
        pathfind.speed = 1.5f;
        pathfind.seeker.StartPath(transform.position, spawnpoint.GetComponent<HumanSpawnPoint>().monsterCore.transform.position, pathfind.OnPathComplete);
    }