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; } } } } } } } }
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; } } } }
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; }
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(); } } }