Exemple #1
0
        private Point?GetExploreDestination()
        {
            //todo, clean up later
            var potentiallyReachable = FloodFill.ScanToArray(Player.Position, point => !point.IsMapEdge() && (!Map.Seen[point] || TileDefinition.IsPassable(TileTypeAt(point))));
            var dm2 = new DijkstraMap(p => (Map.Seen[p] || p.IsMapEdge())? -1 : 1)              //todo, seen==blocked?
            {
                IsSource = p => (Map.Seen[p] || p.IsMapEdge())
            };

            dm2.Scan();
            //CharacterScreens.PrintDijkstraTest(dm2);
            foreach (Point p in Map.GetAllPoints(false))
            {
                if (dm2[p] == DijkstraMap.Unexplored || dm2[p] == DijkstraMap.Blocked)
                {
                    continue;
                }
                dm2[p] = -(dm2[p] * dm2[p]);
            }
            dm2.RescanWithCurrentValues();
            //CharacterScreens.PrintDijkstraTest(dm2);
            var dm = new DijkstraMap(p => (!Map.Seen[p] || !TileDefinition.IsPassable(TileTypeAt(p)))? -1 : 1)
            {
                IsSource       = p => !Map.Seen[p] && potentiallyReachable[p],
                GetSourceValue = p => - (dm2[p])
            };

            dm.Scan();
            //CharacterScreens.PrintDijkstraTest(dm2);
            //CharacterScreens.PrintDijkstraTest(dm);
            List <Point> playerPath = dm.GetDownhillPath(Player.Position, true, earlyStopCondition: p => !Map.Seen[p]);

            if (playerPath.Count == 0)
            {
                return(null);
            }
            else
            {
                return(playerPath[playerPath.Count - 1]);
            }
        }
Exemple #2
0
        private List <Point> GetPathToNearbyReachable(Point potentialDestination, DijkstraMap playerMovementMap, ref PointArray <bool> knownReachable, ref DijkstraMap distanceToKnownReachable)
        {
            Point destination = potentialDestination;

            // First, figure out whether the destination cell is known-reachable:
            if (knownReachable == null)
            {
                knownReachable = FloodFill.ScanToArray(Player.Position, CellIsKnownPassable);
            }
            PointArray <bool> knownReachable2 = knownReachable;            // Can't use a ref parameter inside a lambda, but using a 2nd variable works.

            if (!knownReachable[destination])
            {
                // If not, then find the nearest known reachable spaces:
                if (distanceToKnownReachable == null)
                {
                    distanceToKnownReachable = new DijkstraMap(point => 1)
                    {
                        IsSource = point => knownReachable2[point]
                    };
                    distanceToKnownReachable.Scan();
                }
                if (distanceToKnownReachable[destination] > 1)                                                                       // If distance is 1, then we can reach it anyway
                {
                    destination = destination.EnumeratePointsAtChebyshevDistance(distanceToKnownReachable[destination], true, false) // We know the distance already, so check only those cells...
                                  .Where(nearby => nearby.ExistsBetweenMapEdges() && knownReachable2[nearby])                        // ...make sure only reachable ones are considered...
                                  .WhereLeast(nearby => destination.GetHalfStepMetricDistance(nearby))                               // ...get the nearest ones to the targeted point...
                                  .WhereLeast(nearby => Player.Position.GetHalfStepMetricDistance(nearby))[0];                       // ...and finally get whichever one of those is closest to the player.
                }
            }
            if (destination == Player.Position)
            {
                return(new List <Point>());
            }
            List <Point> path = playerMovementMap.GetDownhillPath(destination, preferCardinalDirections: true, includePathSource: true, includePathDestination: false, ignorePathSourceCost: true);

            path.Reverse();
            return(path);
        }
Exemple #3
0
        private void ChooseAutoexploreAction(PlayerTurnEvent e)
        {
            var potentiallyReachable = FloodFill.ScanToArray(Player.Position, point => !point.IsMapEdge() && (!Map.Seen[point] || TileDefinition.IsPassable(TileTypeAt(point))));
            var distanceToKnown      = new DijkstraMap(p => (Map.Seen[p] || p.IsMapEdge())? -1 : 1)
            {
                IsSource = p => (Map.Seen[p] || p.IsMapEdge())
            };

            distanceToKnown.Scan();
            foreach (Point p in Map.GetAllPoints(false))
            {
                if (distanceToKnown[p] == DijkstraMap.Unexplored || distanceToKnown[p] == DijkstraMap.Blocked)
                {
                    continue;
                }
                distanceToKnown[p] = -(distanceToKnown[p] * distanceToKnown[p]);
            }
            distanceToKnown.RescanWithCurrentValues();
            var exploreMap = new DijkstraMap(p => (!Map.Seen[p] || !TileDefinition.IsPassable(TileTypeAt(p)))? -1 : 1)              // todo, needs items, shrines, etc. eventually
            {
                IsSource       = p => !Map.Seen[p] && potentiallyReachable[p],
                GetSourceValue = p => - (distanceToKnown[p])
            };

            exploreMap.Scan();
            List <Point> playerPath = exploreMap.GetDownhillPath(Player.Position, true, earlyStopCondition: p => true);

            if (playerPath.Count == 0)
            {
                return;
            }
            else
            {
                e.ChosenAction = new WalkAction(Player, playerPath[0]);
            }
        }