private void ProcessNodeDepthFirst(ref PathfindingResult results, Map map, TileCoordinate targetCoords, TileCoordinate nodeCoords, TileCoordinate prevNodeCoords) { if (results.IsResultFound) { return; } var aggregator = new PathAggregator(nodeCoords, prevNodeCoords); if (results.Aggregator.ContainsKey(nodeCoords)) { return; } results.Visualizations.Enqueue(new VisualizationCommand(nodeCoords)); results.Aggregator.Add(nodeCoords, prevNodeCoords); if (nodeCoords == targetCoords) { results.IsResultFound = true; return; } var neighbours = map.GetNeighbouringTiles(nodeCoords); foreach (var potentialNeighbour in neighbours) { if (!potentialNeighbour.HasValue) { continue; } ProcessNodeDepthFirst(ref results, map, targetCoords, potentialNeighbour.Value, nodeCoords); } }
private WorldPath ComputeSafePathOpportunity(Army army, WorldPosition destination, WorldPath unsafePath) { if (this.SafePathOpportunityMax < 1f) { return(unsafePath); } bool flag = true; for (int i = 0; i < unsafePath.ControlPoints.Length; i++) { if (this.worldPositionningService.HasRetaliationFor(unsafePath.WorldPositions[(int)unsafePath.ControlPoints[i]], army.Empire)) { flag = false; break; } } if (!flag) { PathfindingContext pathfindingContext = army.GenerateContext(); pathfindingContext.Greedy = true; PathfindingResult pathfindingResult = this.pathfindingService.FindPath(pathfindingContext, army.WorldPosition, destination, PathfindingManager.RequestMode.AvoidToBeHurtByDefensiveTiles, null, this.currentFlags, null); if (pathfindingResult != null) { WorldPath worldPath = new WorldPath(); worldPath.Build(pathfindingResult, army.GetPropertyValue(SimulationProperties.MovementRatio), this.numberOfTurnForWorldPath, false); if (worldPath.IsValid && (float)worldPath.ControlPoints.Length < this.SafePathOpportunityMax * (float)unsafePath.ControlPoints.Length) { return(worldPath); } } } return(unsafePath); }
private bool IsDetourWorthChecking(Army army, WorldPosition opportunityPosition, WorldPosition mainTargetPosition, out int numberOfTurnsTillMainTarget, out int numberOfTurnsAfterDetour) { int num = 0; int num2 = 0; int num3 = 0; numberOfTurnsTillMainTarget = 0; numberOfTurnsAfterDetour = 0; PathfindingContext pathfindingContext = army.GenerateContext(); pathfindingContext.Greedy = true; PathfindingResult pathfindingResult = this.pathfindingService.FindPath(pathfindingContext, army.WorldPosition, opportunityPosition, PathfindingManager.RequestMode.Default, null, PathfindingFlags.IgnoreFogOfWar, null); if (pathfindingResult == null) { if (this.worldPositionningService.GetDistance(army.WorldPosition, opportunityPosition) != 1) { return(false); } } else { num = pathfindingResult.CompletPathLength; } PathfindingResult pathfindingResult2 = this.pathfindingService.FindPath(pathfindingContext, army.WorldPosition, mainTargetPosition, PathfindingManager.RequestMode.Default, null, PathfindingFlags.IgnoreFogOfWar, null); if (pathfindingResult2 == null) { if (this.worldPositionningService.GetDistance(army.WorldPosition, mainTargetPosition) != 1) { return(false); } } else { num2 = pathfindingResult2.CompletPathLength; } if (num2 < num) { return(false); } PathfindingResult pathfindingResult3 = this.pathfindingService.FindPath(pathfindingContext, opportunityPosition, mainTargetPosition, PathfindingManager.RequestMode.Default, null, PathfindingFlags.IgnoreFogOfWar, null); if (pathfindingResult3 == null) { if (this.worldPositionningService.GetDistance(opportunityPosition, mainTargetPosition) != 1) { return(false); } } else { num3 = pathfindingResult3.CompletPathLength; } float propertyValue = army.GetPropertyValue(SimulationProperties.MaximumMovement); numberOfTurnsTillMainTarget = (int)((float)num2 / propertyValue); numberOfTurnsAfterDetour = (int)((float)(num + num3) / propertyValue); return(true); }
public PathfindingResponse(PathfindingResult result, List <Position> positions, int nodesOpen, int nodesClosed) { Result = result; Positions = positions; NodesOpen = nodesOpen; NodesClosed = nodesClosed; }
protected WorldPath ComputePathToPosition(ArmyWithTask army, WorldPosition targetPosition, WorldPath currentPath) { if (currentPath != null && currentPath.Destination == targetPosition && currentPath.Origin == army.Garrison.WorldPosition) { for (int i = 0; i < currentPath.WorldPositions.Length; i++) { if (currentPath.WorldPositions[i] == army.Garrison.WorldPosition) { return(currentPath); } } } IPathfindingContextProvider pathfindingContextProvider = army.Garrison as IPathfindingContextProvider; if (pathfindingContextProvider == null) { return(null); } PathfindingContext pathfindingContext = pathfindingContextProvider.GenerateContext(); pathfindingContext.Greedy = true; WorldPosition worldPosition = army.Garrison.WorldPosition; PathfindingResult pathfindingResult = this.pathfindingService.FindPath(pathfindingContext, worldPosition, targetPosition, PathfindingManager.RequestMode.Default, null, PathfindingFlags.IgnoreFogOfWar, null); if (pathfindingResult == null) { return(null); } WorldPath worldPath = new WorldPath(); worldPath.Build(pathfindingResult, army.Garrison.GetPropertyValue(SimulationProperties.MovementRatio), 1, false); return(worldPath); }
private void PathDone(PathfindingResult result, List <PNode> fullPath) { if (result != PathfindingResult.SUCCESSFUL) { // Did not succeed? Oh well. return; } if (fullPath == null) { // Path was not built, should never be true when sucessful is true but we check anyway. return; } var tn = GetTargetNode(); if (fullPath.Count >= 2 && tn != null && tn.Equals(fullPath[1])) { // The current target node is equal to the second node on the new path. // Going to the first node is probably a stupid idea, let's remove it! fullPath.RemoveAt(0); } CurrentPathTarget = (Vector2Int)fullPath[fullPath.Count - 1]; path = fullPath; pathRebuildCount++; }
private void VisualizePathfinding(PathfindingResult result) { StopVisualizingCoroutines(); visualizeImmediately = false; visualizePathfindingCoroutine = StartCoroutine(VisualizePathfindingOverTime(result)); }
private bool CanReachPositionInTurn(Army army, WorldPosition destination, int maximumNumberOfTurns, out int numberOfTurns) { numberOfTurns = maximumNumberOfTurns; IGameService service = Services.GetService <IGameService>(); Diagnostics.Assert(service != null); IPathfindingService service2 = service.Game.Services.GetService <IPathfindingService>(); Diagnostics.Assert(service2 != null); if (army.WorldPosition.Equals(destination)) { return(true); } PathfindingContext pathfindingContext = army.GenerateContext(); pathfindingContext.Greedy = true; PathfindingResult pathfindingResult = service2.FindPath(pathfindingContext, army.WorldPosition, destination, PathfindingManager.RequestMode.Default, null, PathfindingFlags.IgnoreFogOfWar, null); if (pathfindingResult == null) { return(false); } WorldPath worldPath = new WorldPath(); worldPath.Build(pathfindingResult, army.GetPropertyValue(SimulationProperties.MovementRatio), maximumNumberOfTurns, false); numberOfTurns = worldPath.ControlPoints.Length; if (worldPath.ControlPoints.Length < maximumNumberOfTurns) { return(true); } WorldPosition left = worldPath.WorldPositions[(int)worldPath.ControlPoints[maximumNumberOfTurns - 1]]; return(left == destination && left == worldPath.WorldPositions[worldPath.Length - 1]); }
public PathReturn(int id, PathfindingResult result, List <Point3> path, PathFound callback, IPathfindingGrid grid) { ID = id; Result = result; Path = path; Callback = callback; Grid = grid; }
private void UponPathCompleted(PathfindingResult result, List <PNode> path) { if (result == PathfindingResult.SUCCESSFUL) { this.path = path; } Completed++; }
public PathfindingResult FindPath(Node from, Func <Node, bool> goal, Func <Node, float> hueristic) { var nodes = new Dictionary <Node, PathNode>(); var head = new PathNode { parent = null, realNode = from, state = NodeState.Closed }; nodes.Add(from, head); var openNodes = new List <PathNode>(); var result = new PathfindingResult(); result.FoundPath = false; while (head != null) { if (goal(head.realNode)) { var pathEnd = head; result.Path = new List <Node>(); while (pathEnd != null) { result.Path.Add(pathEnd.realNode); pathEnd = pathEnd.parent; } result.Path.Reverse(); result.FoundPath = true; return(result); } foreach (var newOpenNode in enumerateNeighbors(head.realNode)) { if (nodes.ContainsKey(newOpenNode)) { continue; } var newNode = new PathNode { parent = head, realNode = newOpenNode, state = NodeState.Open }; nodes.Add(newOpenNode, newNode); openNodes.Add(newNode); //TODO: Sort addition based on heuristic } if (openNodes.Count == 0) { head = null; } else { head = openNodes[0]; head.state = NodeState.Closed; openNodes.RemoveAt(0); } } result.FoundPath = false; return(result); }
private IEnumerator VisualizePathfindingOverTime(PathfindingResult result) { isCurrentlyVisualizingPathfinding = true; yield return visualizeSearchingCoroutine = StartCoroutine(VisualizeSearching(result.VisitedNodes)); VisualizePath(result.Path); isCurrentlyVisualizingPathfinding = false; }
public void InvokeCompleted(PathfindingResult res, List <PNode> path) { Completed = true; if (UponCompleted != null) { UponCompleted.Invoke(res, path); } }
public PathfindingResponseDto MapPathfindingResult(PathfindingResult pathfindingResult) { return new PathfindingResponseDto { ShortestPath = pathfindingResult.ShortestPath .Select(node => new PositionDto(node.Position.Row, node.Position.Col)), VisitedPositions = pathfindingResult.VisitedNodes .Select(node => new PositionDto(node.Position.Row, node.Position.Col)) }; }
public static LinkedList <Vector2> GetRawPath(Vector2 start, Vector2 end, bool addToDebug = false) { PathfindingResult result = RunPathfinder(Utility.WorldToAxialPosition(start), Utility.WorldToAxialPosition(end)); if (addToDebug) { SendToDebugging(result); } return(result.FinishedPath); }
public void Execute() { if (getDesiredPathData == null || finalAction == null || graphHandler == null) { Debug.LogError("FindPathCommand was not initialized properly!"); return; } DesiredPathData desiredPathData = getDesiredPathData(); PathfindingResult result = graphHandler.FindPath(desiredPathData); finalAction(result); }
private PathfindingResult CalculatePathDepthFirst(Map map, TileCoordinate from, TileCoordinate to) { var result = new PathfindingResult(); result.Path = new List <Vector2Int>(); result.UnvisitedSet = new HashSet <TileCoordinate>(); result.VisitedSet = new HashSet <TileCoordinate>(); result.Aggregator = new Dictionary <Vector2Int, Vector2Int>(); result.Visualizations = new Queue <VisualizationCommand>(); result.targetTile = to; ProcessNodeDepthFirst(ref result, map, to, from, new TileCoordinate(-1, -1)); result.ExtractPathFromAggregator(); return(result); }
private void PathCallback(ThreadedRequestResult requestResult, PathfindingResult pathResult) { if (requestResult == ThreadedRequestResult.Cancelled) { return; } if (requestResult == ThreadedRequestResult.Run) { CurrentPath = pathResult.Path; } realPathReq = null; OnPathfindingReturn(requestResult, pathResult); }
private IEnumerator VisualizePathfindingResult(PathfindingResult result) { _currentVisualizations.ForEach(Destroy); _currentVisualizations.Clear(); do { var currentCommand = result.Visualizations.Dequeue(); var currentVis = Instantiate(singleStepVisualizationObject, transform) as GameObject; currentVis.transform.position = new Vector3(sizeBetweenTiles * currentCommand.Coordinate.x, 0.0f, sizeBetweenTiles * currentCommand.Coordinate.y); _currentVisualizations.Add(currentVis); yield return(new WaitForSeconds(timeBetweenTicks)); } while (result.Visualizations.Count > 0); var foundPath = result.Path; _lineRenderer.positionCount = foundPath.Count; _lineRenderer.SetPositions(foundPath.Select(coord => new Vector3(coord.x * sizeBetweenTiles, 0.0f, coord.y * sizeBetweenTiles)).ToArray()); }
public PathfindingResult CalculatePath(Map map, TileCoordinate @from, TileCoordinate to) { var result = new PathfindingResult(); result.Path = new List <Vector2Int>(); result.UnvisitedSet = new HashSet <TileCoordinate>(); result.VisitedSet = new HashSet <TileCoordinate>(); result.Aggregator = new Dictionary <Vector2Int, Vector2Int>(); result.Visualizations = new Queue <VisualizationCommand>(); result.targetTile = to; pathfindingQueue.Clear(); pathfindingQueue.Enqueue(from); result.Aggregator.Add(from, new TileCoordinate(-1, -1)); do { var currentCoord = pathfindingQueue.Dequeue(); result.Visualizations.Enqueue(new VisualizationCommand(currentCoord)); if (currentCoord == to) { result.IsResultFound = true; break; } var neighbours = map.GetNeighbouringTiles(currentCoord); foreach (var potentialNeighbour in neighbours) { if (!potentialNeighbour.HasValue) { continue; } if (result.Aggregator.ContainsKey(potentialNeighbour.Value)) { continue; } result.Aggregator.Add(potentialNeighbour.Value, currentCoord); pathfindingQueue.Enqueue(potentialNeighbour.Value); } } while (pathfindingQueue.Count > 0); result.ExtractPathFromAggregator(); return(result); }
private void UponPathCompleted(PathfindingResult result, List <PNode> path) { // This means that the request has completed, so it is important to dispose of it now. CurrentRequest.Dispose(); CurrentRequest = null; // Check the result... if (result != PathfindingResult.SUCCESSFUL) { // Debug.LogWarning("Pathfinding failed: " + result); // Most likely is that it was impossible to find a route from the start to end. // Request a new path then, hopefully this time it won't be a failure. CurrentRequest = CreateNewRequest(); } else { // Apply the path that was just calculated. currentPath = path; previousNodeIndex = 0; movementTimer = 0f; } }
private static PathfindingResult RunPathfinder(Axial start, Axial end) { SimplePriorityQueue <Node> openNodes = new SimplePriorityQueue <Node>(); Dictionary <Axial, Node> closedNodes = new Dictionary <Axial, Node>(); Node startNode = new Node(start, 0, GetHeuristic(start, end)); Node current = null; openNodes.Enqueue(startNode, startNode.Cost); while (openNodes.Count > 0) { current = openNodes.Dequeue(); closedNodes.Add(current.Position, current); if (current == end) // Reached end { break; } foreach (AxialDirection direction in AxialDirection.AllDirections) { Axial neighborPosition = current.Position + direction; if (!Utility.IsAxialPositionWalkable(neighborPosition)) { continue; } float newNeighborCost = current.Cost + GetMovementCost(current, direction); float heuristic = GetHeuristic(neighborPosition, end); Node neighbor = new Node(neighborPosition, newNeighborCost, heuristic, current); // Update surrounding nodes if we have a better path, even if they've already been evaluated if (openNodes.Contains(neighbor)) { // The heuristic is deterministic, so this will get us the pure cost of the node float currentCost = openNodes.GetPriority(neighbor) - heuristic; if (newNeighborCost < currentCost) { openNodes.Remove(neighbor); } } if (closedNodes.ContainsKey(neighborPosition)) { float currentCost = closedNodes[neighborPosition].Cost; if (newNeighborCost < currentCost) { closedNodes.Remove(neighborPosition); } } // Add them to the queue if applicable if (!openNodes.Contains(neighbor) && !closedNodes.ContainsKey(neighbor.Position)) { openNodes.Enqueue(neighbor, neighbor.FullValue); } } } return(CalculateResults(current)); PathfindingResult CalculateResults(Node endNode) { if (endNode == null) { Debug.LogError($"Couldn't calculate path between {start} and {end}"); return(null); } PathfindingResult result = new PathfindingResult() { OpenNodes = openNodes, CloesdNodes = closedNodes, }; result.FinishedPath = new LinkedList <Vector2>(); result.FinishedPath.AddFirst(endNode); Node currentNode = endNode; while (currentNode.Parent != null) { currentNode = closedNodes[currentNode.Parent.Value]; result.FinishedPath.AddFirst(currentNode); } // We're already in the first node, walking to it would just force us to walk to the center of the node, and we don't want that. result.FinishedPath.RemoveFirst(); return(result); } }
private State MykaraExecute(AIBehaviorTree aiBehaviorTree, Army army) { WorldPosition worldPosition = (WorldPosition)aiBehaviorTree.Variables[this.DestinationVarName]; aiBehaviorTree.LastPathfindTargetPosition = worldPosition; if (!worldPosition.IsValid) { aiBehaviorTree.ErrorCode = 3; return(State.Failure); } if (this.CurrentPathCollection != null && this.CurrentPathCollection.ExitNode != null) { IFastTravelNodeGameEntity[] entryTravelNodesFor = this.departmentOfTransportation.GetEntryTravelNodesFor(army, this.armyAction_FastTravel.EntryPrerequisites); if (entryTravelNodesFor.Length != 0) { if (!entryTravelNodesFor.Contains(this.CurrentPathCollection.ExitNode) && this.departmentOfTransportation.GetExitTravelNodesFor(army, this.armyAction_FastTravel.EntryPrerequisites).Contains(this.CurrentPathCollection.ExitNode)) { return(this.FastTravelExecute(aiBehaviorTree, army)); } this.CurrentPathCollection = null; this.WorldPath = null; } } if (army.GetPropertyValue(SimulationProperties.Movement) < 0.001f) { aiBehaviorTree.ErrorCode = 24; return(State.Failure); } if (this.CurrentPathCollection != null && (this.CurrentPathCollection.PathFromNodeExitToDestination.Destination == worldPosition || (this.WorldPath != null && this.WorldPath.Destination == worldPosition))) { return(State.Success); } this.currentFlags = PathfindingFlags.IgnoreFogOfWar; if (!aiBehaviorTree.AICommander.MayUseFrozenTiles()) { this.currentFlags |= PathfindingFlags.IgnoreFrozenWaters; } this.WorldPath = new WorldPath(); if (army.WorldPosition == worldPosition) { aiBehaviorTree.ErrorCode = 4; return(State.Failure); } int distance = this.worldPositionningService.GetDistance(army.WorldPosition, worldPosition); bool flag = this.pathfindingService.IsTransitionPassable(army.WorldPosition, worldPosition, army, (PathfindingFlags)0, null); if (distance == 1 && flag && !this.pathfindingService.IsTileStopable(worldPosition, army, (PathfindingFlags)0, null)) { aiBehaviorTree.ErrorCode = 4; return(State.Failure); } PathfindingContext pathfindingContext = army.GenerateContext(); pathfindingContext.Greedy = true; PathfindingResult pathfindingResult = this.pathfindingService.FindPath(pathfindingContext, army.WorldPosition, worldPosition, PathfindingManager.RequestMode.Default, null, this.currentFlags, null); this.CurrentPathCollection = new AIBehaviorTreeNode_Action_GeneratePath.MykaraPathCollection(); this.CurrentPathCollection.NormalPath = this.WorldPath; this.CurrentPathCollection.PathToNodeEntrance = new WorldPath(); this.CurrentPathCollection.PathFromNodeExitToDestination = new WorldPath(); if (pathfindingResult != null) { this.WorldPath.Build(pathfindingResult, army.GetPropertyValue(SimulationProperties.MovementRatio), 10, false); this.WorldPath = this.ComputeSafePathOpportunity(army, worldPosition, this.WorldPath); if (Amplitude.Unity.Framework.Application.Preferences.EnableModdingTools) { Diagnostics.Log("ELCP: {0}/{1}/{2} original path: {3} {4} {5}", new object[] { army.Empire, army.LocalizedName, army.WorldPosition, pathfindingResult.CompletPathLength, this.WorldPath.Length, this.WorldPath.ControlPoints.Length }); } } bool flag2 = false; if (!this.WorldPath.IsValid || this.WorldPath.ControlPoints.Length > 2) { if (Amplitude.Unity.Framework.Application.Preferences.EnableModdingTools) { Diagnostics.Log("ELCP: {0}/{1} trying to find alternative path to target {2}", new object[] { army.Empire, army.LocalizedName, worldPosition }); } int num = int.MaxValue; int num2 = int.MaxValue; IFastTravelNodeGameEntity fastTravelNodeGameEntity = null; IFastTravelNodeGameEntity fastTravelNodeGameEntity2 = null; List <IFastTravelNodeGameEntity> list = this.departmentOfTransportation.GetEntryTravelNodesFor(army, this.armyAction_FastTravel.EntryPrerequisites).ToList <IFastTravelNodeGameEntity>(); list.AddRange(this.departmentOfTransportation.GetExitTravelNodesFor(army, this.armyAction_FastTravel.EntryPrerequisites)); foreach (IFastTravelNodeGameEntity fastTravelNodeGameEntity3 in list) { if (fastTravelNodeGameEntity3.GetTravelEntrancePositions().Length != 0) { int distance2 = this.worldPositionningService.GetDistance(fastTravelNodeGameEntity3.WorldPosition, army.WorldPosition); int distance3 = this.worldPositionningService.GetDistance(fastTravelNodeGameEntity3.WorldPosition, worldPosition); if (distance2 < num) { num = distance2; fastTravelNodeGameEntity = fastTravelNodeGameEntity3; if (distance2 == 1) { flag2 = true; } } if (distance3 < num2) { num2 = distance3; fastTravelNodeGameEntity2 = fastTravelNodeGameEntity3; } } } if (fastTravelNodeGameEntity != null && fastTravelNodeGameEntity2 != null && fastTravelNodeGameEntity != fastTravelNodeGameEntity2) { int num3 = 1; WorldPosition worldPosition2 = army.WorldPosition; if (!flag2) { worldPosition2 = this.GetValidTileForFastTravel(fastTravelNodeGameEntity.WorldPosition, army.WorldPosition, true); } if (worldPosition2.IsValid) { PathfindingResult pathfindingResult2 = this.pathfindingService.FindPath(pathfindingContext, army.WorldPosition, fastTravelNodeGameEntity.WorldPosition, PathfindingManager.RequestMode.Default, null, this.currentFlags, null); WorldPath worldPath = new WorldPath(); if (pathfindingResult2 != null) { worldPath.Build(pathfindingResult2, army.GetPropertyValue(SimulationProperties.MovementRatio), 10, false); num3 += worldPath.ControlPoints.Length; if (this.GetValidTileForFastTravel(fastTravelNodeGameEntity2.WorldPosition, worldPosition, false).IsValid) { PathfindingResult pathfindingResult3 = this.pathfindingService.FindPath(pathfindingContext, worldPosition, fastTravelNodeGameEntity2.WorldPosition, PathfindingManager.RequestMode.Default, null, this.currentFlags | PathfindingFlags.IgnoreArmies | PathfindingFlags.IgnorePOI, null); WorldPath worldPath2 = new WorldPath(); if (pathfindingResult3 != null) { worldPath2.Build(pathfindingResult3, army.GetPropertyValue(SimulationProperties.MovementRatio), 10, false); num3 += worldPath2.ControlPoints.Length; if (!this.WorldPath.IsValid || num3 < this.WorldPath.ControlPoints.Length) { this.CurrentPathCollection.EntryNode = fastTravelNodeGameEntity; this.CurrentPathCollection.ExitNode = fastTravelNodeGameEntity2; this.CurrentPathCollection.PathToNodeEntrance = worldPath; this.CurrentPathCollection.PathFromNodeExitToDestination = worldPath2; if (Amplitude.Unity.Framework.Application.Preferences.EnableModdingTools) { Diagnostics.Log("ELCP: {0}/{1} alternative path found through {2} {3}, {4} < {5}, {6}", new object[] { army.Empire, army.LocalizedName, fastTravelNodeGameEntity.WorldPosition + "/" + worldPath.Destination, fastTravelNodeGameEntity2.WorldPosition + "/" + worldPath2.Destination, num3, this.WorldPath.ControlPoints.Length, flag2 }); } } } } } } } } if (!this.WorldPath.IsValid && !this.CurrentPathCollection.PathToNodeEntrance.IsValid && (!flag2 || this.CurrentPathCollection.ExitNode == null)) { aiBehaviorTree.ErrorCode = 3; return(State.Failure); } WorldPath value = this.CurrentPathCollection.PathToNodeEntrance.IsValid ? this.CurrentPathCollection.PathToNodeEntrance : this.WorldPath; if (aiBehaviorTree.Variables.ContainsKey(this.Output_PathVarName)) { aiBehaviorTree.Variables[this.Output_PathVarName] = value; } else { aiBehaviorTree.Variables.Add(this.Output_PathVarName, value); } if (flag2 && this.CurrentPathCollection.ExitNode != null && this.departmentOfTransportation.GetExitTravelNodesFor(army, this.armyAction_FastTravel.EntryPrerequisites).Contains(this.CurrentPathCollection.ExitNode)) { if (Amplitude.Unity.Framework.Application.Preferences.EnableModdingTools) { Diagnostics.Log("ELCP: {0}/{1} initiating instant teleport {3} {2} to {4}", new object[] { army.Empire, army.LocalizedName, this.CurrentPathCollection.EntryNode.WorldPosition, army.WorldPosition, this.CurrentPathCollection.ExitNode }); } return(this.FastTravelExecute(aiBehaviorTree, army)); } return(State.Success); }
private static void SendToDebugging(PathfindingResult result) { PathfindingDebugger.AddPath(result.FinishedPath, result.OpenNodes, result.CloesdNodes); }
protected virtual void OnPathfindingReturn(ThreadedRequestResult requestResult, PathfindingResult pathResult) { }
public PathfindingResult FindPath(PathfindingParameters parameters) { PathfindingResult result = new PathfindingResult(); System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); sw.Start(); Node startNode = grid.GetNodeAt(parameters.startPos); Node endNode = grid.GetNodeAt(parameters.endPos); Node bestNode = null; Heap<Node> openList = new Heap<Node>(grid.gridMaxSize); HashSet<Node> closedList = new HashSet<Node>(); if (drawPathfinding) grid.ResetColors(); openList.Add(startNode); while (openList.Count > 0) { Node currentNode = openList.RemoveFirst(); if (currentNode == endNode || (parameters.endNodes != null && parameters.endNodes.Contains(currentNode))) { sw.Stop(); //print(sw.ElapsedMilliseconds + "ms"); result.path = GetPath(RetracePath(currentNode, startNode), parameters); return result; } if (drawPathfinding) currentNode.color = Color.red; closedList.Add(currentNode); foreach (Node n in grid.GetNeighbours(currentNode)) { //if (!n.walkable || closedList.Contains(n)) if (!grid.GetWalkable(n, parameters.radius) || closedList.Contains(n)) continue; int newGCost = currentNode.gCost + grid.GetDistance(n, currentNode); if (newGCost < n.gCost || !openList.Contains(n)) { n.gCost = newGCost; n.hCost = grid.GetDistance(n, endNode); n.parent = currentNode; if (drawPathfinding) n.color = Color.yellow; if (bestNode == null || n.hCost < bestNode.hCost) bestNode = n; if (!openList.Contains(n)) openList.Add(n); else openList.UpdateItem(n); } } } sw.Stop(); //print("no path found, " + sw.ElapsedMilliseconds + "ms"); if (bestNode != null) result.path = GetPath(RetracePath(bestNode, startNode), parameters); else result.path = new List<Vector3>(); return result; }
public PathfindingResponse(PathfindingResult result) { Result = result; }
public void OnPathFound(PathfindingResult result) { StopCoroutine("Move"); StartCoroutine("Move", result.path); }
protected override State Execute(AIBehaviorTree aiBehaviorTree, params object[] parameters) { if (this.currentTicket != null) { if (!this.currentTicket.Raised) { return(State.Running); } bool flag = this.currentTicket.PostOrderResponse == PostOrderResponse.PreprocessHasFailed || this.currentTicket.PostOrderResponse == PostOrderResponse.AuthenticationHasFailed; this.currentTicket = null; if (flag) { aiBehaviorTree.ErrorCode = 1; return(State.Failure); } if (this.fastTravel) { Army army; if (this.CurrentPathCollection != null && base.GetArmyUnlessLocked(aiBehaviorTree, "$Army", out army) == AIArmyMission.AIArmyMissionErrorCode.None) { PointOfInterest pointOfInterest = this.worldPositionningService.GetPointOfInterest(this.CurrentPathCollection.ExitNode.WorldPosition); IGameService service = Services.GetService <IGameService>(); IQuestManagementService service2 = service.Game.Services.GetService <IQuestManagementService>(); IQuestRepositoryService service3 = service.Game.Services.GetService <IQuestRepositoryService>(); if (pointOfInterest != null && ELCPUtilities.CanSearch(army.Empire, pointOfInterest, service2, service3) && this.worldPositionningService.GetDistance(army.WorldPosition, pointOfInterest.WorldPosition) < 2 && this.pathfindingService.IsTransitionPassable(army.WorldPosition, pointOfInterest.WorldPosition, army, OrderAttack.AttackFlags, null)) { OrderInteractWith orderInteractWith = new OrderInteractWith(army.Empire.Index, army.GUID, "ArmyActionSearch"); orderInteractWith.WorldPosition = army.WorldPosition; orderInteractWith.Tags.AddTag("Interact"); orderInteractWith.TargetGUID = pointOfInterest.GUID; army.Empire.PlayerControllers.AI.PostOrder(orderInteractWith); } } this.fastTravel = false; this.CurrentPathCollection = null; } return(State.Success); } else { Army army2; if (base.GetArmyUnlessLocked(aiBehaviorTree, "$Army", out army2) != AIArmyMission.AIArmyMissionErrorCode.None) { return(State.Failure); } if (!aiBehaviorTree.Variables.ContainsKey(this.DestinationVarName)) { aiBehaviorTree.LogError("{0} not set", new object[] { this.DestinationVarName }); return(State.Failure); } if (this.AllowFastTravel && !(army2 is KaijuArmy) && aiBehaviorTree.AICommander.Empire is MajorEmpire && aiBehaviorTree.AICommander.Empire.SimulationObject.Tags.Contains(FactionTrait.FactionTraitMimics1)) { float propertyValue = army2.GetPropertyValue(SimulationProperties.MaximumNumberOfActionPoints); float propertyValue2 = army2.GetPropertyValue(SimulationProperties.ActionPointsSpent); if (propertyValue > propertyValue2) { return(this.MykaraExecute(aiBehaviorTree, army2)); } if (this.CurrentPathCollection != null) { this.CurrentPathCollection = null; this.WorldPath = null; } } if (army2.GetPropertyValue(SimulationProperties.Movement) < 0.001f) { aiBehaviorTree.ErrorCode = 24; return(State.Failure); } WorldPosition worldPosition = (WorldPosition)aiBehaviorTree.Variables[this.DestinationVarName]; aiBehaviorTree.LastPathfindTargetPosition = worldPosition; if (!worldPosition.IsValid) { aiBehaviorTree.ErrorCode = 3; return(State.Failure); } if (this.WorldPath != null && this.WorldPath.Destination == worldPosition) { return(State.Success); } this.currentFlags = PathfindingFlags.IgnoreFogOfWar; if (!aiBehaviorTree.AICommander.MayUseFrozenTiles()) { this.currentFlags |= PathfindingFlags.IgnoreFrozenWaters; } this.WorldPath = new WorldPath(); if (army2.WorldPosition == worldPosition) { aiBehaviorTree.ErrorCode = 4; return(State.Failure); } int distance = this.worldPositionningService.GetDistance(army2.WorldPosition, worldPosition); bool flag2 = this.pathfindingService.IsTransitionPassable(army2.WorldPosition, worldPosition, army2, (PathfindingFlags)0, null); if (distance == 1 && flag2 && !this.pathfindingService.IsTileStopable(worldPosition, army2, (PathfindingFlags)0, null)) { aiBehaviorTree.ErrorCode = 4; return(State.Failure); } PathfindingContext pathfindingContext = army2.GenerateContext(); pathfindingContext.Greedy = true; PathfindingResult pathfindingResult = this.pathfindingService.FindPath(pathfindingContext, army2.WorldPosition, worldPosition, PathfindingManager.RequestMode.Default, null, this.currentFlags, null); if (pathfindingResult == null && this.IgnoreArmies) { this.currentFlags |= PathfindingFlags.IgnoreArmies; pathfindingResult = this.pathfindingService.FindPath(pathfindingContext, army2.WorldPosition, worldPosition, PathfindingManager.RequestMode.Default, null, this.currentFlags, null); } if (pathfindingResult == null) { aiBehaviorTree.ErrorCode = 3; if (ELCPUtilities.ELCPVerboseMode) { Diagnostics.Log("ELCP {0}/{1} didnt find pathfindingResult to {2} with flags {3}", new object[] { army2.Empire, army2.LocalizedName, worldPosition, this.currentFlags }); } return(State.Failure); } this.WorldPath.Build(pathfindingResult, army2.GetPropertyValue(SimulationProperties.MovementRatio), this.numberOfTurnForWorldPath, false); this.WorldPath = this.ComputeSafePathOpportunity(army2, worldPosition, this.WorldPath); if (!this.WorldPath.IsValid) { aiBehaviorTree.ErrorCode = 3; if (ELCPUtilities.ELCPVerboseMode) { Diagnostics.Log("ELCP {0}/{1} worldpath invalid {2} with flags {3}", new object[] { army2.Empire, army2.LocalizedName, worldPosition, this.currentFlags }); } return(State.Failure); } if (aiBehaviorTree.Variables.ContainsKey(this.Output_PathVarName)) { aiBehaviorTree.Variables[this.Output_PathVarName] = this.WorldPath; } else { aiBehaviorTree.Variables.Add(this.Output_PathVarName, this.WorldPath); } return(State.Success); } }
ushort[] ICadasterService.Connect(City city, PathfindingMovementCapacity movementCapacity, bool proxied) { if (city == null) { throw new ArgumentNullException("city"); } if ((movementCapacity & PathfindingMovementCapacity.Water) == PathfindingMovementCapacity.Water) { StaticString type = new StaticString("DistrictImprovement"); StaticString y = new StaticString("DistrictImprovementDocks"); WorldPosition start = WorldPosition.Invalid; for (int i = 0; i < city.Districts.Count; i++) { District district = city.Districts[i]; if (district.Type == DistrictType.Improvement && district.GetDescriptorNameFromType(type) == y) { start = district.WorldPosition; break; } } if (!start.IsValid) { return(null); } DepartmentOfForeignAffairs agency = city.Empire.GetAgency <DepartmentOfForeignAffairs>(); this.OceanPathfindingWorldContext.RegionIndexList.Clear(); this.OceanPathfindingWorldContext.RegionIndexList.Add((int)this.WorldPositionningService.GetRegionIndex(city.WorldPosition)); for (int j = 0; j < city.Region.Borders.Length; j++) { Region region = this.WorldPositionningService.GetRegion(city.Region.Borders[j].NeighbourRegionIndex); if (region.Owner == null || !(region.Owner is MajorEmpire) || region.Owner.Index == city.Empire.Index || agency.GetDiplomaticRelation(region.Owner).HasActiveAbility(DiplomaticAbilityDefinition.TradeRoute)) { this.OceanPathfindingWorldContext.RegionIndexList.Add(city.Region.Borders[j].NeighbourRegionIndex); } } Diagnostics.Assert(city.CadastralMap != null); Diagnostics.Assert((city.CadastralMap.ConnectedMovementCapacity & PathfindingMovementCapacity.Water) == PathfindingMovementCapacity.Water); List <ushort> list = new List <ushort>(); List <Region> list2 = new List <Region>(); List <Region> list3 = new List <Region>(); list3.Add(city.Region); int k = 0; int l = 2; while (l > 0) { l--; list2.AddRange(list3); list3.Clear(); while (k < list2.Count) { Region region2 = list2[k]; for (int m = 0; m < region2.Borders.Length; m++) { short regionIndex = (short)region2.Borders[m].NeighbourRegionIndex; Region region3 = this.WorldPositionningService.GetRegion((int)regionIndex); if (region3 != null && !list2.Contains(region3)) { if (region3.City != null) { Diagnostics.Assert(region3.City.CadastralMap != null); if ((region3.City.CadastralMap.ConnectedMovementCapacity & PathfindingMovementCapacity.Water) == PathfindingMovementCapacity.Water) { for (int n = 0; n < region3.City.Districts.Count; n++) { District district2 = region3.City.Districts[n]; if (district2.Type == DistrictType.Improvement && district2.GetDescriptorNameFromType(type) == y) { PathfindingFlags pathfindingFlags = PathfindingFlags.IgnoreAll; pathfindingFlags &= ~PathfindingFlags.IgnoreMovementCapacities; pathfindingFlags &= ~PathfindingFlags.IgnorePOI; PathfindingContext pathfindingContext = new PathfindingContext(GameEntityGUID.Zero, city.Empire, PathfindingMovementCapacity.Water); pathfindingContext.RefreshProperties(1f, 1f, false, false, 1f, 1f); bool flag = false; if (!this.OceanPathfindingWorldContext.RegionIndexList.Contains(region2.Borders[m].NeighbourRegionIndex)) { flag = true; this.OceanPathfindingWorldContext.RegionIndexList.Add(region2.Borders[m].NeighbourRegionIndex); } PathfindingResult pathfindingResult = this.PathfindingService.FindPath(pathfindingContext, start, district2.WorldPosition, PathfindingManager.RequestMode.Default, this.OceanPathfindingWorldContext, pathfindingFlags, null); if (flag) { this.OceanPathfindingWorldContext.RegionIndexList.Remove(region2.Borders[m].NeighbourRegionIndex); } if (pathfindingResult == null) { pathfindingResult = this.PathfindingService.FindPath(pathfindingContext, start, district2.WorldPosition, PathfindingManager.RequestMode.Default, null, pathfindingFlags, null); } if (pathfindingResult != null) { ushort item = this.Reserve(new Road { FromRegion = (short)city.Region.Index, ToRegion = (short)region3.Index, WorldPositions = pathfindingResult.GetCompletePath().ToArray <WorldPosition>(), PathfindingMovementCapacity = PathfindingMovementCapacity.Water }); list.Add(item); } } } } } if (region3.IsOcean) { list3.AddOnce(region3); } else { list2.Insert(k, region3); k++; } } } k++; } } this.OceanPathfindingWorldContext.RegionIndexList.Clear(); return(list.ToArray()); } else { if (city.Region.Borders != null) { List <ushort> list4 = new List <ushort>(); for (int num = 0; num < city.Region.Borders.Length; num++) { short regionIndex2 = (short)city.Region.Borders[num].NeighbourRegionIndex; Region region4 = this.WorldPositionningService.GetRegion((int)regionIndex2); if (region4 != null && region4.City != null) { if (proxied) { if ((movementCapacity & PathfindingMovementCapacity.Ground) != PathfindingMovementCapacity.Ground) { goto IL_75D; } Diagnostics.Assert(region4.City.CadastralMap != null); if ((region4.City.CadastralMap.ConnectedMovementCapacity & PathfindingMovementCapacity.Ground) != PathfindingMovementCapacity.Ground) { goto IL_75D; } } bool flag2 = false; if (region4.City.CadastralMap.Roads != null) { for (int num2 = 0; num2 < region4.City.CadastralMap.Roads.Count; num2++) { ushort num3 = region4.City.CadastralMap.Roads[num2]; Road road = this.roads[(int)num3]; if (road != null && (city.Region.Index == (int)road.FromRegion || city.Region.Index == (int)road.ToRegion) && (road.PathfindingMovementCapacity & movementCapacity) != PathfindingMovementCapacity.None) { if (this.RoadModified != null) { this.RoadModified(this, new RoadEventArgs(num3, road)); } flag2 = true; list4.Add(num3); } } } if (!flag2) { PathfindingFlags pathfindingFlags2 = PathfindingFlags.IgnoreAll; pathfindingFlags2 &= ~PathfindingFlags.IgnoreMovementCapacities; pathfindingFlags2 &= ~PathfindingFlags.IgnorePOI; pathfindingFlags2 &= ~PathfindingFlags.IgnoreRoad; PathfindingContext pathfindingContext2 = new PathfindingContext(GameEntityGUID.Zero, city.Empire, movementCapacity); pathfindingContext2.RefreshProperties(1f, 1f, false, false, 1f, 1f); pathfindingContext2.RemoveMovementCapacity(PathfindingMovementCapacity.FrozenWater); Diagnostics.Assert(this.pathfindingWorldContext != null && this.pathfindingWorldContext.RegionIndexList != null && this.pathfindingWorldContext.RegionIndexList.Count == 2); this.pathfindingWorldContext.RegionIndexList[0] = (int)this.WorldPositionningService.GetRegionIndex(city.WorldPosition); this.pathfindingWorldContext.RegionIndexList[1] = (int)this.WorldPositionningService.GetRegionIndex(region4.City.WorldPosition); PathfindingResult pathfindingResult2 = this.PathfindingService.FindPath(pathfindingContext2, city.WorldPosition, region4.City.WorldPosition, PathfindingManager.RequestMode.Default, this.pathfindingWorldContext, pathfindingFlags2, null); if (pathfindingResult2 == null) { pathfindingFlags2 |= PathfindingFlags.IgnorePOI; pathfindingResult2 = this.PathfindingService.FindPath(pathfindingContext2, city.WorldPosition, region4.City.WorldPosition, PathfindingManager.RequestMode.Default, this.pathfindingWorldContext, pathfindingFlags2, null); } if (pathfindingResult2 != null) { ushort item2 = this.Reserve(new Road { FromRegion = (short)city.Region.Index, ToRegion = (short)region4.Index, WorldPositions = pathfindingResult2.GetCompletePath().ToList <WorldPosition>().ToArray(), PathfindingMovementCapacity = movementCapacity }); list4.Add(item2); } } } IL_75D :; } return(list4.ToArray()); } return(null); } }
private bool BuildWorldPath() { this.TemporaryWorldPath.Clear(); if (this.LastHighlightedWorldPosition == WorldPosition.Invalid) { return(false); } if (base.IsTransferable(WorldCursor.HighlightedWorldPosition)) { return(false); } if ((!base.PathfindingService.IsTileStopable(this.LastHighlightedWorldPosition, base.PathfindingContext, (PathfindingFlags)0, null) || !base.PathfindingService.IsTilePassable(this.LastHighlightedWorldPosition, base.PathfindingContext, (PathfindingFlags)0, null) || this.OtherEmpireCreepingNodeAtPosition(this.Army.Empire, this.LastHighlightedWorldPosition)) && base.PathfindingService.IsTransitionPassable(this.GarrisonPosition, this.LastHighlightedWorldPosition, base.PathfindingContext, PathfindingFlags.IgnoreArmies | PathfindingFlags.IgnoreOtherEmpireDistrict | PathfindingFlags.IgnoreDiplomacy | PathfindingFlags.IgnorePOI | PathfindingFlags.IgnoreSieges | PathfindingFlags.IgnoreKaijuGarrisons, null)) { return(true); } PathfindingFlags pathfindingFlags = PathfindingFlags.IgnoreArmies; District district = base.WorldPositionningService.GetDistrict(this.GarrisonPosition); if (district != null && (district.Type == DistrictType.Center || district.Type == DistrictType.Extension) && district.City != null && district.City.BesiegingEmpireIndex != -1) { pathfindingFlags &= ~PathfindingFlags.IgnoreArmies; } Army army = null; if (this.LastHighlightedWorldPosition != WorldPosition.Invalid) { army = base.WorldPositionningService.GetArmyAtPosition(this.LastHighlightedWorldPosition); } bool flag = base.VisibilityService.IsWorldPositionDetectedFor(this.LastHighlightedWorldPosition, this.Army.Empire) || (army != null && !army.IsCamouflaged); bool flag2 = base.WorldPositionningService.GetDistance(this.GarrisonPosition, this.LastHighlightedWorldPosition) <= this.Army.LineOfSightVisionRange; if (flag && flag2) { pathfindingFlags &= ~PathfindingFlags.IgnoreArmies; } PathfindingResult pathfindingResult = base.PathfindingService.FindPath(base.PathfindingContext, this.GarrisonPosition, this.LastHighlightedWorldPosition, PathfindingManager.RequestMode.Default, null, pathfindingFlags, null); if (base.WorldPositionningService != null && pathfindingResult != null && this.LastHighlightedWorldPosition != WorldPosition.Invalid) { if (!base.PathfindingService.IsTileStopable(this.LastHighlightedWorldPosition, base.PathfindingContext, (PathfindingFlags)0, null)) { WorldPosition lastHighlightedWorldPosition = this.LastHighlightedWorldPosition; WorldPosition position = pathfindingResult.GetCompletePath().Last <WorldPosition>(); bool flag3 = base.WorldPositionningService.IsWaterTile(lastHighlightedWorldPosition); bool flag4 = base.WorldPositionningService.IsWaterTile(position); if (flag3 != flag4) { World world = (base.GameService.Game as global::Game).World; List <WorldPosition> neighbours = lastHighlightedWorldPosition.GetNeighbours(world.WorldParameters); List <WorldPosition> list = new List <WorldPosition>(); for (int i = 0; i < neighbours.Count; i++) { if (base.WorldPositionningService.IsWaterTile(neighbours[i]) == flag3 && !base.WorldPositionningService.HasRidge(neighbours[i]) && base.PathfindingService.IsTileStopable(neighbours[i], base.PathfindingContext, (PathfindingFlags)0, null)) { list.Add(neighbours[i]); } } if (list.Count > 0) { PathfindingResult pathfindingResult2 = null; float num = float.MaxValue; for (int j = 0; j < list.Count; j++) { PathfindingResult pathfindingResult3 = base.PathfindingService.FindPath(base.PathfindingContext, this.GarrisonPosition, list[j], PathfindingManager.RequestMode.Default, null, pathfindingFlags, null); if (pathfindingResult3 != null && pathfindingResult3.GetCost() < num) { num = pathfindingResult3.GetCost(); pathfindingResult2 = pathfindingResult3; } } if (pathfindingResult2 != null) { pathfindingResult = pathfindingResult2; } } } } else if (this.OtherEmpireCreepingNodeAtPosition(this.Army.Empire, this.LastHighlightedWorldPosition)) { List <WorldPosition> list2 = pathfindingResult.GetCompletePath().ToList <WorldPosition>(); if (list2.Count > 0) { list2.RemoveAt(list2.Count - 1); PathfindingResult pathfindingResult4 = base.PathfindingService.FindPath(base.PathfindingContext, this.GarrisonPosition, list2.Last <WorldPosition>(), PathfindingManager.RequestMode.Default, null, pathfindingFlags, null); if (pathfindingResult4 != null) { pathfindingResult = pathfindingResult4; this.TemporaryWorldPath.Build(pathfindingResult, this.WorldArmy.Army.GetPropertyValue(SimulationProperties.MovementRatio), int.MaxValue, false); return(true); } } } } if (pathfindingResult == null) { return(base.PathfindingService.IsTransitionPassable(this.GarrisonPosition, this.LastHighlightedWorldPosition, base.PathfindingContext, PathfindingFlags.IgnoreArmies | PathfindingFlags.IgnoreOtherEmpireDistrict | PathfindingFlags.IgnoreDiplomacy | PathfindingFlags.IgnorePOI | PathfindingFlags.IgnoreSieges | PathfindingFlags.IgnoreKaijuGarrisons, null)); } Army army2 = this.WorldArmy.Army; this.TemporaryWorldPath.Build(pathfindingResult, army2.GetPropertyValue(SimulationProperties.MovementRatio), int.MaxValue, false); return(true); }
protected override bool TryComputeArmyMissionParameter() { if (!base.AIDataArmyGUID.IsValid) { base.Completion = AICommanderMission.AICommanderMissionCompletion.Fail; return(false); } AIData_Army aidata = this.aiDataRepository.GetAIData <AIData_Army>(base.AIDataArmyGUID); if (aidata == null || aidata.Army == null) { base.Completion = AICommanderMission.AICommanderMissionCompletion.Fail; return(false); } if (aidata.Army.IsLocked || aidata.Army.IsInEncounter) { return(false); } if (this.AICommanderRegroupArmies.MissionHasAllUnits(this)) { RequestGarrisonMessage requestGarrisonMessage = null; if (this.AICommanderRegroupArmies != null && this.AICommanderRegroupArmies.RequestUnitListMessageID != 0UL) { requestGarrisonMessage = (base.Commander.AIPlayer.Blackboard.GetMessage(this.AICommanderRegroupArmies.RequestUnitListMessageID) as RequestGarrisonMessage); } if (requestGarrisonMessage == null) { RequestGarrisonCampMessage requestGarrisonCampMessage = null; if (this.AICommanderRegroupArmies != null && this.AICommanderRegroupArmies.RequestUnitListMessageID != 0UL) { requestGarrisonCampMessage = (base.Commander.AIPlayer.Blackboard.GetMessage(this.AICommanderRegroupArmies.RequestUnitListMessageID) as RequestGarrisonCampMessage); } if (requestGarrisonCampMessage == null) { base.Completion = AICommanderMission.AICommanderMissionCompletion.Success; return(false); } IGameEntity gameEntity; if (!this.gameEntityRepositoryService.TryGetValue(requestGarrisonCampMessage.CampGuid, out gameEntity)) { base.Completion = AICommanderMission.AICommanderMissionCompletion.Fail; return(false); } Camp camp = gameEntity as Camp; if (camp == null) { base.Completion = AICommanderMission.AICommanderMissionCompletion.Fail; return(false); } if (!this.AICommanderRegroupArmies.FinalPosition.IsValid) { this.AICommanderRegroupArmies.FinalPosition = camp.GetValidDistrictToTarget(aidata.Army).WorldPosition; requestGarrisonCampMessage.FinalPosition = this.AICommanderRegroupArmies.FinalPosition; } Army armyAtPosition = this.worldPositionningService.GetArmyAtPosition(this.AICommanderRegroupArmies.FinalPosition); if (armyAtPosition != null && armyAtPosition.GUID != base.AIDataArmyGUID) { this.AICommanderRegroupArmies.FinalPosition = camp.GetValidDistrictToTarget(aidata.Army).WorldPosition; requestGarrisonCampMessage.FinalPosition = this.AICommanderRegroupArmies.FinalPosition; } bool flag = false; for (int i = 0; i < camp.Districts.Count; i++) { if (camp.Districts[i].Type != DistrictType.Exploitation && camp.Districts[i].Type != DistrictType.Improvement && this.worldPositionningService.GetDistance(this.AICommanderRegroupArmies.FinalPosition, camp.Districts[i].WorldPosition) <= 1) { flag = true; break; } } if (!flag) { this.AICommanderRegroupArmies.FinalPosition = camp.GetValidDistrictToTarget(aidata.Army).WorldPosition; requestGarrisonCampMessage.FinalPosition = this.AICommanderRegroupArmies.FinalPosition; } if (aidata.Army.WorldPosition == this.AICommanderRegroupArmies.FinalPosition) { base.Completion = AICommanderMission.AICommanderMissionCompletion.Success; return(false); } } else { IGameEntity gameEntity2; if (!this.gameEntityRepositoryService.TryGetValue(requestGarrisonMessage.CityGuid, out gameEntity2)) { base.Completion = AICommanderMission.AICommanderMissionCompletion.Fail; return(false); } City city = gameEntity2 as City; if (city == null) { base.Completion = AICommanderMission.AICommanderMissionCompletion.Fail; return(false); } if (city.IsInEncounter) { return(false); } if (city.BesiegingEmpire != null) { base.Completion = AICommanderMission.AICommanderMissionCompletion.Fail; return(false); } if (!this.AICommanderRegroupArmies.FinalPosition.IsValid) { this.AICommanderRegroupArmies.FinalPosition = city.GetValidDistrictToTarget(aidata.Army).WorldPosition; requestGarrisonMessage.FinalPosition = this.AICommanderRegroupArmies.FinalPosition; } Army armyAtPosition2 = this.worldPositionningService.GetArmyAtPosition(this.AICommanderRegroupArmies.FinalPosition); if (armyAtPosition2 != null && armyAtPosition2.GUID != base.AIDataArmyGUID) { this.AICommanderRegroupArmies.FinalPosition = city.GetValidDistrictToTarget(aidata.Army).WorldPosition; requestGarrisonMessage.FinalPosition = this.AICommanderRegroupArmies.FinalPosition; } bool flag2 = false; for (int j = 0; j < city.Districts.Count; j++) { if (city.Districts[j].Type != DistrictType.Exploitation && city.Districts[j].Type != DistrictType.Improvement && this.worldPositionningService.GetDistance(this.AICommanderRegroupArmies.FinalPosition, city.Districts[j].WorldPosition) <= 1) { flag2 = true; break; } } if (!flag2) { this.AICommanderRegroupArmies.FinalPosition = city.GetValidDistrictToTarget(aidata.Army).WorldPosition; requestGarrisonMessage.FinalPosition = this.AICommanderRegroupArmies.FinalPosition; } if (aidata.Army.WorldPosition == this.AICommanderRegroupArmies.FinalPosition) { base.Completion = AICommanderMission.AICommanderMissionCompletion.Success; return(false); } } } if (this.targetTransferArmy != null) { if (this.targetTransferArmy.Army == null) { this.targetTransferArmy = null; } else { if (!this.targetTransferArmy.Army.IsInEncounter && !this.targetTransferArmy.Army.IsLocked) { return(false); } this.targetTransferArmy = null; } } foreach (AICommanderMission aicommanderMission in this.AICommanderRegroupArmies.Missions) { AICommanderMission_RegroupArmyAt aicommanderMission_RegroupArmyAt = (AICommanderMission_RegroupArmyAt)aicommanderMission; if (aicommanderMission_RegroupArmyAt != this && aicommanderMission_RegroupArmyAt.targetTransferArmy == aidata) { if (!aidata.Army.IsLocked && !aidata.Army.IsInEncounter) { return(false); } aicommanderMission_RegroupArmyAt.targetTransferArmy = null; } } if (this.AICommanderRegroupArmies != null && this.AICommanderRegroupArmies.AIPlayer != null && this.AICommanderRegroupArmies.AIPlayer.AIEntities != null) { AIEntity_Empire aientity_Empire = this.AICommanderRegroupArmies.AIPlayer.AIEntities.Find((AIEntity match) => match is AIEntity_Empire) as AIEntity_Empire; if (aientity_Empire != null) { AICommanderMission_PrivateersHarass aicommanderMission_PrivateersHarass = aientity_Empire.GetCommanderMissionBasedOnItsArmyRequestArmy(this.AICommanderRegroupArmies.RequestUnitListMessageID) as AICommanderMission_PrivateersHarass; if (aicommanderMission_PrivateersHarass != null && aicommanderMission_PrivateersHarass.TargetCity != null && !aidata.Army.IsPrivateers && base.TryCreateArmyMission("ConvertToPrivateers", new List <object> { aicommanderMission_PrivateersHarass.TargetCity })) { base.State = TickableState.NeedTick; RequestUnitListMessage requestUnitListMessage = base.Commander.AIPlayer.Blackboard.GetMessage(this.AICommanderRegroupArmies.RequestUnitListMessageID) as RequestUnitListMessage; if (requestUnitListMessage != null) { requestUnitListMessage.ExecutionState = RequestUnitListMessage.RequestUnitListState.Regrouping; } return(true); } } } WorldPosition worldPosition; if (this.IsMaster) { if (this.IsArmyBesiegingACity(base.AIDataArmyGUID) && !aidata.Army.IsPrivateers) { return(false); } if (this.CanTransferToNearMission()) { return(false); } AICommanderMission_RegroupArmyAt aicommanderMission_RegroupArmyAt2 = null; int num = int.MaxValue; foreach (AICommanderMission aicommanderMission2 in this.AICommanderRegroupArmies.Missions) { AICommanderMission_RegroupArmyAt aicommanderMission_RegroupArmyAt3 = (AICommanderMission_RegroupArmyAt)aicommanderMission2; if (aicommanderMission_RegroupArmyAt3 != this) { WorldPosition unitsToRegroupPosition = aicommanderMission_RegroupArmyAt3.GetUnitsToRegroupPosition(); if (unitsToRegroupPosition.IsValid) { int distance = this.worldPositionningService.GetDistance(aidata.Army.WorldPosition, unitsToRegroupPosition); if (distance < num) { num = distance; aicommanderMission_RegroupArmyAt2 = aicommanderMission_RegroupArmyAt3; } } } } if (aicommanderMission_RegroupArmyAt2 == null) { if (!this.AICommanderRegroupArmies.FinalPosition.IsValid) { base.Completion = AICommanderMission.AICommanderMissionCompletion.Success; return(false); } worldPosition = this.AICommanderRegroupArmies.FinalPosition; } else { worldPosition = aicommanderMission_RegroupArmyAt2.GetUnitsToRegroupPosition(); } } else { if (this.CanTransferToNearMission()) { return(false); } AICommanderMission_RegroupArmyAt masterMission = this.AICommanderRegroupArmies.MasterMission; if (masterMission == null) { return(false); } worldPosition = masterMission.GetUnitsToRegroupPosition(); } base.State = TickableState.NoTick; if (aidata.Army.GetPropertyValue(SimulationProperties.Movement) > 0f) { int num2 = Math.Min(4, Math.Max(1, (this.worldPositionningService.GetDistance(worldPosition, aidata.Army.WorldPosition) - 1) / 2)); PathfindingContext pathfindingContext = aidata.Army.GenerateContext(); pathfindingContext.Greedy = true; PathfindingResult pathfindingResult = this.pathfindingService.FindPath(pathfindingContext, aidata.Army.WorldPosition, worldPosition, PathfindingManager.RequestMode.Default, null, PathfindingFlags.IgnoreFogOfWar, null); if (pathfindingResult != null) { int num3 = 0; WorldPosition worldPosition2 = WorldPosition.Invalid; foreach (WorldPosition worldPosition3 in pathfindingResult.GetCompletePath()) { if (worldPosition3 != pathfindingResult.Start) { num3++; if ((num3 <= num2 || !worldPosition2.IsValid) && worldPosition3 != worldPosition && this.pathfindingService.IsTileStopable(worldPosition3, aidata.Army, (PathfindingFlags)0, null)) { worldPosition2 = worldPosition3; } if (num3 >= num2 && worldPosition2.IsValid && base.TryCreateArmyMission("ReachPosition", new List <object> { worldPosition2 })) { base.State = TickableState.NeedTick; this.SetRequestMessageExecutionState(RequestUnitListMessage.RequestUnitListState.Regrouping); return(true); } } } } if (base.Commander.Empire.SimulationObject.Tags.Contains(FactionTrait.FactionTraitMimics1)) { DepartmentOfTheInterior agency = base.Commander.Empire.GetAgency <DepartmentOfTheInterior>(); if (agency.NonInfectedCities.Count > 0 && base.TryCreateArmyMission("ReachPositionMykara", new List <object> { agency.NonInfectedCities[0].WorldPosition })) { base.State = TickableState.NeedTick; this.SetRequestMessageExecutionState(RequestUnitListMessage.RequestUnitListState.Regrouping); return(true); } } } return(false); }