Пример #1
0
    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);
    }
Пример #3
0
    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);
    }