public int ShouldUseItem() { //print("ShouldUseItem()"); // TODO: foreach item in inventory, // if any item would give the player any value // set itemToUseIndex to be the item that offers the greatest value and return success // else if none of the items give any value at this moment (ex: no targets, etc...) // return failure int missileIndex = Inventory.GetItemIndex("Rocket"); int boostIndex = Inventory.GetItemIndex("Boost"); int shieldIndex = Inventory.GetItemIndex("Shield"); int oilSpillIndex = Inventory.GetItemIndex("Oil Spill"); if (boostIndex != -1) { itemToUseIndex = boostIndex; } else if (missileIndex != -1) { // check if other players are in sight for missile target foreach (AbstractPlayer p in GameplayManager.Instance.Players) { RaycastHit[] hits = Physics.RaycastAll(transform.position + (Vector3.up * 0.5f), p.transform.position - transform.position); foreach (RaycastHit hit in hits) { // we are colliding with ourself if (hit.transform == transform) { continue; } if (hit.collider.tag.Equals("HumanPlayer") || hit.collider.tag.Equals("AIPlayer")) { AbstractPlayer potentialTarget = hit.collider.GetComponent <AbstractPlayer>(); // check if potentialTarget is in equal or higher place standing. If not, then do not waste the missile on them. if (potentialTarget.checkpoints.Count <= checkpoints.Count) { playerAttackTarget = potentialTarget; itemToUseIndex = missileIndex; } break; } } } } else if (shieldIndex != -1) { // check if player is in sight for foreign missiles foreach (AbstractPlayer p in GameplayManager.Instance.Players) { if (p.Inventory.GetItemIndex("Rocket") != -1) { RaycastHit[] hits = Physics.RaycastAll(p.transform.position + (Vector3.up * 0.5f), transform.position - p.transform.position); Debug.DrawRay(p.transform.position, transform.position - p.transform.position, Color.red, 10000); foreach (RaycastHit hit in hits) { // the ray has hit us if (hit.transform == transform) { itemToUseIndex = shieldIndex; } } // itemToUseIndex = shieldIndex; } } } else if (oilSpillIndex != -1) { // we can only place oil spills on neighbor nodes around us IWeightedDiGraph <GameObject, float> graph = PositionNode.mbGraph.graph; List <GameObject> potentialOilTargets = new List <GameObject>(); foreach (GraphNode <GameObject> graphNode in graph.Neighbors(PositionNode.nodeId)) { // CalculatePathToGoal() and if this node is on that path then do not add it to the list (otherwise we'd be hindering ourselves) potentialOilTargets.Add(graphNode.Data); } Checkpoint checkpointTarget = GetClosestCheckpoint(); MBGraphNode checkpointNode = checkpointTarget == null ? null : checkpointTarget.node; GraphNode <GameObject> optimalGraphNode = reachableNodeIds.Count > 0 ? GameplayManager.Instance.gridGraph.graph[reachableNodeIds[0]] : null; float dist = Mathf.Infinity; foreach (string nodeId in reachableNodeIds) { GraphNode <GameObject> gNode = GameplayManager.Instance.gridGraph.graph[nodeId]; float tempDist = (gNode.Data.transform.position - checkpointNode.transform.position).magnitude; if (tempDist < dist) { optimalGraphNode = gNode; dist = tempDist; } } if (optimalGraphNode != null) { List <GraphNode <GameObject> > path = pathFinding.FindPath(PositionNode.nodeId, optimalGraphNode.Id, MovementHeuristic, checkpoints.Count <= 1); if (path.Count > 0) { path.RemoveAt(0); } if (path.Count == 0) { return((int)BTNode.EState.Failure); } // If there 1 or less nodes that don't have an oil spill on them then don't place the oil spill or else we would be trapping ourselves if (potentialOilTargets.Count > 1) { // select the first potential oil target nodeToSpillOn = potentialOilTargets[0]; foreach (GameObject ot in potentialOilTargets) { if (!path.Contains(GameplayManager.Instance.gridGraph.graph[ot.GetComponent <MBGraphNode>().nodeId])) { nodeToSpillOn = ot; itemToUseIndex = oilSpillIndex; break; } } } } } return(itemToUseIndex >= 0 ? (int)BTNode.EState.Success : (int)BTNode.EState.Failure); }
public int ShouldTakeCover() { //print("ShouldTakeCover()"); // foreach player in the game, check if they have ranged/attack items // if they do, then get the item with the longest range and check if they can reach this player // if they can reach us // set shouldTakeCover to true // add players who are a threat to playerAttackThreats list // return Success // else if no one can reach us with an attack // return failure if (shieldObject.activeSelf) { return((int)BTNode.EState.Failure); } bool shouldTakeCover = false; foreach (AbstractPlayer p in GameplayManager.Instance.Players) { int pOilSpillIndex = p.Inventory.GetItemIndex("Oil Spill"); int pMissileIndex = p.Inventory.GetItemIndex("Rocket"); if (pMissileIndex != -1) { RaycastHit[] hits = Physics.RaycastAll(p.transform.position + (Vector3.up * 0.5f), transform.position - p.transform.position); foreach (RaycastHit hit in hits) { // the ray has hit us if (hit.transform == transform) { playerAttackThreats.Add(p); shouldTakeCover = true; } } } else if (pOilSpillIndex != -1) { IWeightedDiGraph <GameObject, float> graph = PositionNode.mbGraph.graph; foreach (GraphNode <GameObject> graphNode in graph.Neighbors(PositionNode.nodeId)) { if (graphNode.Data.transform == PositionNode.transform) { // we can be hit by this player's oil spill directly playerAttackThreats.Add(p); shouldTakeCover = true; } } } } if (shouldTakeCover) { return((int)BTNode.EState.Success); } else { return((int)BTNode.EState.Failure); } }
public List <GraphNode <GameObject> > FindPath(string startId, string goalId, Heuristic heuristic = null, bool blockedOffNodesAreAllowed = false, bool isAdmissible = true) { if (mbGraph == null) { return(new List <GraphNode <GameObject> >()); } IWeightedDiGraph <GameObject, float> graph = mbGraph.graph; if (heuristic == null) { heuristic = (Transform s, Transform e) => 0; } List <GraphNode <GameObject> > path = null; bool solutionFound = false; Dictionary <string, float> gnDict = new Dictionary <string, float>(); gnDict.Add(startId, default); Dictionary <string, float> fnDict = new Dictionary <string, float>(); fnDict.Add(startId, heuristic(graph[startId].Data.transform, graph[goalId].Data.transform) + gnDict[startId]); Dictionary <string, string> pathDict = new Dictionary <string, string>(); pathDict.Add(startId, null); PriorityQueue <float, string> openPQ = new PriorityQueue <float, string>(); openPQ.Push(fnDict[startId], startId, fnDict[startId]); OrderedDictionary closedODict = new OrderedDictionary(); while (!openPQ.Empty) { string currentId = openPQ.Pop().Value; closedODict[currentId] = true; if (currentId == goalId && isAdmissible) { solutionFound = true; break; } else if (closedODict.Contains(goalId)) { float gGoal = gnDict[goalId]; bool pathIsTheShortest = true; foreach (PQEntry <float, string> entry in openPQ) { if (gGoal > gnDict[entry.Value]) { pathIsTheShortest = false; break; } } if (pathIsTheShortest) { break; } } List <GraphNode <GameObject> > neighbors = graph.Neighbors(currentId); foreach (GraphNode <GameObject> n in neighbors) { float cost = graph.GetEdge(currentId, n.Id).Weight; if (closedODict.Contains(n.Id)) { continue; } if (GameplayManager.Instance.blockedOffNodes.Contains(n.Data.GetComponent <MBGraphNode>()) && !blockedOffNodesAreAllowed) { continue; } if (graph[n.Id].Data.GetComponentInChildren <OilSpillManager>() != null) { cost += 4; // hard coded oil spill cost } float gNeighbor = gnDict[currentId] + cost; if (!gnDict.ContainsKey(n.Id) || gNeighbor < gnDict[n.Id]) { pathDict[n.Id] = currentId; gnDict[n.Id] = gNeighbor; float hNeighbor = heuristic(n.Data.transform, graph[goalId].Data.transform); fnDict[n.Id] = gNeighbor + hNeighbor; openPQ.Push(fnDict[n.Id], n.Id, hNeighbor); if (openPQ.Top.Key > fnDict[n.Id]) { closedODict[currentId] = true; } } } } if (!solutionFound && closedODict.Contains(goalId)) { solutionFound = true; } if (solutionFound) { path = new List <GraphNode <GameObject> >(); string key = goalId; while (key != null && pathDict.ContainsKey(key)) { path.Add(graph[key]); key = pathDict[key]; } path.Reverse(); } return(path); }