Beispiel #1
0
    void CheckForWires()
    {
        for (int x = -1; x <= 1; x++)
        {
            for (int y = -1; y <= 1; y++)
            {
                Vector3Int pos = new Vector3Int(x, y, 0);

                Vector3Int localPos = (Vector3Int.FloorToInt(transform.position) + pos) - GameManager.manager.tileManager.worldOrigin;

                if (pos.magnitude <= 1 && pos.magnitude > 0)
                {
                    SaveableObject electronicObj = GameManager.manager.tileManager.utilityObjects[localPos.x, localPos.y];
                    if (electronicObj != null)
                    {
                        if (electronicObj.GetComponent <Electronic>() != null)
                        {
                            Electronic electronic = (Electronic)electronicObj;
                            Debug.Log(electronic.GetType());

                            if (!input.Contains(electronic))
                            {
                                //If the object is a wire, it will check it's connections to update other wires and/or add this wire to the list
                                if (electronic.GetType() == typeof(Wire) && electronic.generator != null)
                                {
                                    Debug.DrawRay(transform.position, pos, Color.blue, 1);
                                    ((Wire)electronic).CheckConnections();
                                    continue;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
Beispiel #2
0
    protected new void Update()
    {
        base.Update();
        if (!occupied && tasks.Count > 0 && delay < Time.time)
        {
            GiveTask(tasks[0]);
            tasks.RemoveAt(0);
            idleTimer = 0;
        }
        else if (!occupied)
        {
            idleTimer += Time.deltaTime;
        }

        if (occupied && task != null && Vector3.Distance(transform.position, task.position) <= task.radius + 1)
        {
            ExecuteTask();
        }

        if (pathfinding.path.Count > 0)
        {
            Vector3Int relativePos = pathfinding.path[0] - tileManager.worldOrigin;
            if (tileManager.objects[relativePos.x, relativePos.y] != null)
            {
                SaveableObject _object = tileManager.objects[relativePos.x, relativePos.y];
                switch (_object.tag)
                {
                case "Door":
                    if (_object.GetComponent <Door>().accessLevel <= accessLevel && !_object.GetComponent <Door>().on)
                    {
                        //Replace the current task with a door open task
                        Task openTask = new Task
                        {
                            type     = TaskType.Enable,
                            priority = 10,
                            radius   = 1,
                            delay    = 0.5f,
                            target   = _object.transform,
                            position = _object.transform.position
                        };
                        ReplaceTask(openTask);

                        //Add a door close task with a low priority
                        Task closeTask = new Task
                        {
                            type     = TaskType.Disable,
                            priority = 7,
                            radius   = 1,
                            delay    = 0.5f,
                            target   = _object.transform,

                            //Get the direction between the AI and the door, and use that to find the other side
                            position = _object.transform.position + ((_object.transform.position - transform.position).normalized * 2)
                        };
                        AddTask(closeTask);
                    }
                    break;
                }
            }
        }
    }
Beispiel #3
0
    public IEnumerator GeneratePath(Vector3Int destination, bool startMoving = false)
    {
        closedTiles    = new List <Vector3Int>();
        availableTiles = new List <Vector3Int>();
        tiles          = new Tile[gridSize.x, gridSize.y];
        origin         = tileManager.SnapToGrid(transform.position - new Vector3Int(gridSize.y / 2, gridSize.y / 2, 0));

        targetPosition           = destination;
        destinationTile.position = destination - origin;

        Vector3Int startingPosition = new Vector3Int(gridSize.y / 2, gridSize.y / 2, 0);
        Tile       startTile        = new Tile(startingPosition, startingPosition, 0, (int)(destinationTile.position - (startingPosition)).magnitude);

        tiles[startingPosition.x, startingPosition.y] = startTile;
        closedTiles.Add(startingPosition);

        Tile currentTile = startTile;
        bool foundPath   = false;
        bool stuck       = false;

        while (!foundPath && !stuck)
        {
            if (currentTile.score > maxScore)
            {
                stuck = true;
                Debug.LogWarning("AI '" + gameObject.name + "' was stuck. Minimum path score was too high.");
                continue;
            }
            //Sweep from bottom left to top right, grabbing all the tiles that are walkable
            Vector3Int startPos = currentTile.position + Vector3Int.left + Vector3Int.down;
            Vector3Int endPos   = currentTile.position + Vector3Int.right + Vector3Int.up;

            for (int y = startPos.y; y <= endPos.y && y < gridSize.y && y > 0; y++)
            {
                for (int x = startPos.x; x <= endPos.x && x < gridSize.x && x > 0; x++)
                {
                    Vector3Int pos = new Vector3Int(x, y, 0);
                    if ((pos - currentTile.position).magnitude == 1 || useCorners && (pos - currentTile.position).magnitude > 0)
                    {
                        Tile tile = new Tile(new Vector3Int(x, y, 0), currentTile.position);

                        float movementCost  = 1;
                        float movementRatio = 1;

                        if (!flying)
                        {
                            //Get the movement cost of the tile beneath
                            Vector3Int tileMapPos = origin + tile.position - tileManager.worldOrigin;
                            movementCost  = tileManager.tileData.pathfindingCosts[tileMapPos.x, tileMapPos.y];
                            movementRatio = tileManager.tileData.pathfindingRatios[tileMapPos.x, tileMapPos.y];

                            //If there is an object on this tile
                            if (tileManager.tilemaps[1].GetTile(origin + tile.position) != null)
                            {
                                movementCost += tileManager.tileData.wallHealth[tileMapPos.x, tileMapPos.y] + 10;
                            }

                            if (tileManager.objects[x, y] != null)
                            {
                                SaveableObject _object = tileManager.objects[x, y];
                                switch (_object.tag)
                                {
                                case "Door":
                                    if (!_object.GetComponent <Interactable>().on)
                                    {
                                        if (_object.GetComponent <Door>().accessLevel <= AIController.accessLevel)
                                        {
                                            movementCost += 1;
                                        }
                                        else
                                        {
                                            movementCost += 100;
                                        }
                                    }
                                    break;

                                default:
                                    movementCost += 1;
                                    break;
                                }
                            }
                        }

                        //Score should be the distance it took to get there + the shortest distance to the goal
                        tile.distanceFromStart = currentTile.distanceFromStart + ((pos - currentTile.position).magnitude * movementCost);
                        tile.distanceToEnd     = (int)(destinationTile.position - (tile.position)).magnitude * movementCost * movementRatio;
                        tile.score             = tile.distanceToEnd + tile.distanceFromStart;

                        //If the tile is the same as the destination;
                        if (Vector3Int.Distance(tile.position, destinationTile.position) <= acceptableTargetDistance)
                        {
                            destinationTile.parent = tile.position;
                            foundPath = true;
                        }

                        //Check if this tile is not in the closed list, and is empty
                        if (!closedTiles.Contains(tile.position))
                        {
                            //Check if the tile is already in the open list
                            if (availableTiles.Contains(tile.position))
                            {
                                Tile t = tiles[tile.position.x, tile.position.y];
                                if (tile.score < t.score)
                                {
                                    tiles[tile.position.x, tile.position.y] = tile;
                                }
                            }
                            else
                            {
                                tiles[tile.position.x, tile.position.y] = tile;
                                //Add it to the list of positions we can use
                                availableTiles.Add(tile.position);
                            }
                        }
                    }
                }
            }

            if (waitPerFrame)
            {
                yield return(new WaitForEndOfFrame());
            }

            //Go through the different positions in the open list, and deside which to use
            closedTiles.Add(currentTile.position);
            availableTiles.Remove(currentTile.position);

            if (availableTiles.Count > 0)
            {
                Vector3Int nextTile = availableTiles[0];
                foreach (Vector3Int tilePos in availableTiles)
                {
                    if (tiles[tilePos.x, tilePos.y].score < tiles[nextTile.x, nextTile.y].score)
                    {
                        nextTile = tilePos;
                    }
                }
                currentTile = tiles[nextTile.x, nextTile.y];
            }
            else
            {
                stuck = true;
                StartCoroutine(GeneratePath(targetPosition, true));
                Debug.LogWarning("AI '" + gameObject.name + "' was stuck.");
                continue;
            }
        }

        path = new List <Vector3Int>();

        Vector3Int position = destinationTile.parent;

        //Add each position to the path for later
        while (position != tiles[position.x, position.y].parent)
        {
            path.Insert(0, origin + position);
            position = tiles[position.x, position.y].parent;
        }

        //If we are told to start moving after completing, start moving
        moving = startMoving;
    }
Beispiel #4
0
    void CheckObject(SaveableObject electronicObj, Vector3Int pos)
    {
        //If the object is a generator and we have none, use the object
        Generator gen = electronicObj.GetComponent <Generator>();

        if (gen != null)
        {
            if (!input.Contains(gen))
            {
                input.Add(gen);
            }
            SetGenerator(gen);

            Debug.DrawRay(transform.position, pos, Color.green, 1);
        }
        else
        {
            Electronic electronic = (Electronic)electronicObj;

            //If the object is a wire, it will check it's connections to update other wires and/or add this wire to the list
            if (electronic.GetComponent <Wire>() != null && electronic.generator != null && electronic.generator != generator)
            //|| electronic.GetComponent<Wire>() != null && electronic.generator != null && electronic.generatorDistance <= generatorDistance)
            {
                ((Wire)electronic).CheckConnections();

                Debug.DrawRay(transform.position, pos, Color.blue, 1);
                return;
            }

            if (generator == null || input.Contains(electronic))
            {
                return;
            }

            //if the object has no generator and isn't already connected to our generator,
            if (electronic.generator == null || electronic.generator != generator)
            {
                electronic.input.Add(this);

                //Set the objects breaker to ours
                if (breaker != null)
                {
                    electronic.SetBreaker(breaker);
                }

                //Set the objects distance
                electronic.generatorDistance = generatorDistance + 1;
                electronic.SetGenerator(generator);

                //Make sure the objects current is consistant
                if (on)
                {
                    electronic.Enable();
                }
                else
                {
                    electronic.Disable();
                }

                if (!output.Contains(electronic))
                {
                    output.Add(electronic);
                }

                Debug.DrawRay(transform.position, pos, Color.green, 1);
            }

            //This is to reconnect chains
            if (electronic.GetComponent <Wire>() != null)
            {
                ((Wire)electronic).CheckConnections();
            }
        }
    }