public override void OnEnter(GameManager gameManager) { gameManager.GetGUIManager().HideActions(); gameManager.HideTargetingIndicator(); GUIManager guiManager = gameManager.GetGUIManager(); guiManager.ShowStatusPanel(); guiManager.SetStatusLabelText(""); isProcessingQueue = false; currentAction = null; }
void ProcessNextQueueItem() { List<CombatantAction> queue = gameManager.GetQueuedActions(); if (queue.Count > 0) { currentAction = queue[0]; queue.RemoveAt(0); if (currentAction != null && currentAction.CanExecute()) { StartCoroutine(ExecuteAction()); } else { ProcessNextQueueItem(); } } else { gameManager.SetState(gameManager.CreateStateByName("SelectMoveState")); } }
public override CombatantAction GetAction(ref List <Direction> aMoves, ref int aBombTime) { // Check all directions m_RightTile = UseSensor(Direction.Right); m_LeftTile = UseSensor(Direction.Left); m_UpTile = UseSensor(Direction.Up); m_DownTile = UseSensor(Direction.Down); m_CurrentTile = UseSensor(Direction.Current); // Update the surrounding tiles UpdateSurroundingTiles(); aBombTime = Random.Range(m_BombTime.min, m_BombTime.max + 1); // Managing Movement // For each node, check to make sure that the node was not yet visited and is not dangerous, or // check if the diamond is there // If so, then try to move to that position if (m_CurrentNode.left.visited == false && m_CurrentNode.left.tile.Contains(m_DangerousAreas) == false || m_CurrentNode.left.tile.Contains(SensorData.Diamond)) { // If an enemy is there, drop a bomb if (m_CurrentNode.left.tile.Contains(SensorData.Enemy)) { return(CombatantAction.DropBomb); } aMoves.Add(Direction.Left); } // Same logic as the first part, but for different nodes else if (m_CurrentNode.right.visited == false && m_CurrentNode.right.tile.Contains(m_DangerousAreas) == false || m_CurrentNode.right.tile.Contains(SensorData.Diamond)) { if (m_CurrentNode.right.tile.Contains(SensorData.Enemy)) { return(CombatantAction.DropBomb); } aMoves.Add(Direction.Right); } else if (m_CurrentNode.up.visited == false && m_CurrentNode.up.tile.Contains(m_DangerousAreas) == false || m_CurrentNode.up.tile.Contains(SensorData.Diamond)) { if (m_CurrentNode.up.tile.Contains(SensorData.Enemy)) { return(CombatantAction.DropBomb); } aMoves.Add(Direction.Up); } else if (m_CurrentNode.down.visited == false && m_CurrentNode.down.tile.Contains(m_DangerousAreas) == false || m_CurrentNode.down.tile.Contains(SensorData.Diamond)) { if (m_CurrentNode.down.tile.Contains(SensorData.Enemy)) { return(CombatantAction.DropBomb); } aMoves.Add(Direction.Down); } else { // Go into a random direction if all tiles are already visited // keep re-rolling until we get a proper direction, or until we've tried 10 more times Direction dir = (Direction)Random.Range(0, 4); SensorData targetTile = UseSensor(dir); for (int i = 0; i < 10; i++) { if (targetTile.Contains(m_DangerousAreas)) { dir = (Direction)Random.Range(0, 4); targetTile = UseSensor(dir); } else { break; } } // just pass if for some reason, our AI wants to walk into a wall if (targetTile.Contains(SensorData.OffGrid, SensorData.Wall)) { return(CombatantAction.Pass); } else if (targetTile.Contains(SensorData.Enemy)) { return(CombatantAction.DropBomb); } // Just move to the position aMoves.Add(dir); } // This will update the coordinates and return a movement action CombatantAction action = MoveAndUpdateCoords(ref aMoves); Debug.LogFormat("[{0}][{1}]", m_Horizontal, m_Vertical); return(action); }
void Start() { isProcessingQueue = false; currentAction = null; }
public override CombatantAction GetAction(ref List <GameManager.Direction> aMoves, ref int aBombTime) { // Initialize world data for anything we don't currently have if (world.up == null) { world.up = new WorldData(); world.up.down = world; world.up.right = FindNode(1, 1); if (world.up.right != null) { world.up.right.left = world.up; } world.up.left = FindNode(-1, 1); if (world.up.left != null) { world.up.left.right = world.up; } world.up.up = FindNode(0, 2); if (world.up.up != null) { world.up.up.down = world.up; } } if (world.down == null) { world.down = new WorldData(); world.down.up = world; world.down.right = FindNode(1, -1); if (world.down.right != null) { world.down.right.left = world.down; } world.down.left = FindNode(-1, -1); if (world.down.left != null) { world.down.left.right = world.down; } world.down.down = FindNode(0, -2); if (world.down.down != null) { world.down.down.up = world.down; } } if (world.left == null) { world.left = new WorldData(); world.left.right = world; world.left.left = FindNode(-2, 0); if (world.left.left != null) { world.left.left.right = world.left; } world.left.up = FindNode(-1, 1); if (world.left.up != null) { world.left.up.down = world.left; } world.left.down = FindNode(-1, -1); if (world.left.down != null) { world.left.down.up = world.left; } } if (world.right == null) { world.right = new WorldData(); world.right.left = world; world.right.right = FindNode(2, 0); if (world.right.right != null) { world.right.right.left = world.right; } world.right.down = FindNode(1, -1); if (world.right.down != null) { world.right.down.up = world.right; } world.right.up = FindNode(1, 1); if (world.right.up != null) { world.right.up.down = world.right; } } // Update our scans world.state = UseSensor(GameManager.Direction.Current); world.up.state = UseSensor(GameManager.Direction.Up); world.down.state = UseSensor(GameManager.Direction.Down); world.left.state = UseSensor(GameManager.Direction.Left); world.right.state = UseSensor(GameManager.Direction.Right); // Do any of the scans show us where the edge of the world is? if ((world.up.state & GameManager.SensorData.OffGrid) != 0) { //Debug.Log("Found top edge at 1"); topEdgeOffset = 1; FillEdgeData(); } if ((world.down.state & GameManager.SensorData.OffGrid) != 0) { //Debug.Log("Found bottom edge at -1"); bottomEdgeOffset = -1; FillEdgeData(); } if ((world.left.state & GameManager.SensorData.OffGrid) != 0) { //Debug.Log("Found left edge at -1"); leftEdgeOffset = -1; FillEdgeData(); } if ((world.right.state & GameManager.SensorData.OffGrid) != 0) { //Debug.Log("Found right edge at 1"); rightEdgeOffset = 1; FillEdgeData(); } // Check if we've found the diamond, and no one is carrying it if ((world.up.state & GameManager.SensorData.Diamond) != 0 && (world.up.state & GameManager.SensorData.Enemy) == 0) { myState = AIState.GetDiamond; } if ((world.down.state & GameManager.SensorData.Diamond) != 0 && (world.up.state & GameManager.SensorData.Enemy) == 0) { myState = AIState.GetDiamond; } if ((world.left.state & GameManager.SensorData.Diamond) != 0 && (world.up.state & GameManager.SensorData.Enemy) == 0) { myState = AIState.GetDiamond; } if ((world.right.state & GameManager.SensorData.Diamond) != 0 && (world.up.state & GameManager.SensorData.Enemy) == 0) { myState = AIState.GetDiamond; } // What action are we taking this turn? CombatantAction action = CombatantAction.Pass; // Which state are we in? if (myState == AIState.GoToGoal) { WorldData newPosition = FindGoal(ref aMoves); if (newPosition != null) { world = newPosition; return(CombatantAction.Move); } myState = AIState.Search; } if (myState == AIState.Search) { // To search, first find the best leaf node and move there WorldData newPosition = FindBestLeaf(ref aMoves); if (newPosition != null) { world = newPosition; action = CombatantAction.Move; } if (newPosition == null) { myState = AIState.DropBomb; } } if (myState == AIState.DropBomb) { aBombTime = 2; myState = AIState.HuntForTarget; return(CombatantAction.DropBomb); } if (myState == AIState.HuntForTarget) { WorldData newPosition = null; //FindRandom(ref aMoves); if (newPosition != null) { myState = AIState.DropBomb; world = newPosition; return(CombatantAction.Move); } } if (myState == AIState.GetDiamond) { WorldData newPosition = FindDiamond(ref aMoves); if (newPosition != null) { myState = AIState.GoToGoal; world = newPosition; return(CombatantAction.Move); } } if (myState == AIState.BombSweepPlaceBomb) { } if (myState == AIState.BombSweepMove) { } // Logic depending on which action we've decided to take if (action == CombatantAction.Move) { // Update the edge offsets based on our movement foreach (GameManager.Direction dir in aMoves) { if (dir == GameManager.Direction.Up) { topEdgeOffset -= 1; bottomEdgeOffset -= 1; } else if (dir == GameManager.Direction.Down) { bottomEdgeOffset += 1; topEdgeOffset += 1; } else if (dir == GameManager.Direction.Left) { leftEdgeOffset += 1; rightEdgeOffset += 1; } else if (dir == GameManager.Direction.Right) { leftEdgeOffset -= 1; rightEdgeOffset -= 1; } } } else if (action == CombatantAction.DropBomb) { world.state |= GameManager.SensorData.Bomb; world.bombTime = aBombTime; } //CountdownBombTimes(); return(action); }
// Get the action the combatant wants to take // If you are returning CombatantAction.Move: // - You must specify how you would like to move by adding data to the aMoves list // - You will move along the path until you bump into something or reach the end // If you are returning CombatantAction.DropBomb: // - You must specify what the timer on the bomb should be set by setting the aBombTime argument public override CombatantAction GetAction(ref List <Direction> aMoves, ref int aBombTime) { CombatantAction returnAction = CombatantAction.Pass; // Do logic based on the current mood of the AI // If currentAIMood is passive, then map out the area /* * ===================================== * | NOTE | * |-----------------------------------| * | If we move to a new tile, we MUST | * | update currentPos! | * |-----------------------------------| */ // Check the surrounding tiles UpdateTileMap(); if (MovementScript.CheckMovement(this, Direction.Current) && (MovementScript.CheckForBomb(this, Direction.Current) || MovementScript.CheckForBomb(this, Direction.Up) || MovementScript.CheckForBomb(this, Direction.Down) || MovementScript.CheckForBomb(this, Direction.Left) || MovementScript.CheckForBomb(this, Direction.Right))) { Direction dirToMove = (Direction)UnityEngine.Random.Range(1, 5); if (MovementScript.CheckMovement(this, dirToMove)) { aMoves.Add(dirToMove); } else { Direction newDirToMove = (Direction)UnityEngine.Random.Range(1, 5); if (newDirToMove != dirToMove && MovementScript.CheckMovement(this, newDirToMove)) { dirToMove = newDirToMove; aMoves.Add(newDirToMove); } } if (MovementScript.CheckMovement(this, dirToMove) && (MovementScript.CheckForBomb(this, Direction.Current) || MovementScript.CheckForBomb(this, Direction.Up) || MovementScript.CheckForBomb(this, Direction.Down) || MovementScript.CheckForBomb(this, Direction.Left) || MovementScript.CheckForBomb(this, Direction.Right))) { // There's still a bomb near us, so let's move again Direction newNewDir = (Direction)UnityEngine.Random.Range(1, 5); if (MovementScript.CheckMovement(this, newNewDir) && !MovementScript.CheckForBomb(this, newNewDir)) { aMoves.Add(newNewDir); } else { Direction nextNewDirToMove = (Direction)UnityEngine.Random.Range(1, 5); if (nextNewDirToMove != newNewDir && MovementScript.CheckMovement(this, nextNewDirToMove) && !MovementScript.CheckForBomb(this, nextNewDirToMove)) { dirToMove = nextNewDirToMove; aMoves.Add(nextNewDirToMove); } } } returnAction = CombatantAction.Move; } else if (MovementScript.CheckMovement(this, Direction.Current) && !MovementScript.CheckForBomb(this, Direction.Current)) { aBombTime = UnityEngine.Random.Range(2, 20); returnAction = CombatantAction.DropBomb; } return(returnAction); }
int ActionQueueSorter(CombatantAction a, CombatantAction b) { if (a == null && b == null) { return 0; } else if (a == null) { return -1; } else if (b == null) { return 1; } else { return a.CastTime.CompareTo(b.CastTime); } }
/// <summary> /// Queues the action. /// </summary> /// <param name="action">Action.</param> public void QueueAction(CombatantAction action) { queuedActions.Add(action); queuedActions.Sort (ActionQueueSorter); }