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