示例#1
0
        public int GetOpenDirections()
        {
            var openDirections = (int)DirectionFlags.East | (int)DirectionFlags.North | (int)DirectionFlags.South | (int)DirectionFlags.West;

            // If the route is empty then all directions are open!
            if (!Route.Any())
            {
                return(openDirections);
            }

            var x = StartX;
            var y = StartY;

            foreach (var direction in _route.FastReverse())
            {
                if (DirectionFlagsHelper.HasDirectionFlag(openDirections, DirectionFlags.North) && x == EndX && y == EndY + 1)
                {
                    openDirections = DirectionFlagsHelper.UnsetDirectionFlag(openDirections, DirectionFlags.North);
                }

                if (DirectionFlagsHelper.HasDirectionFlag(openDirections, DirectionFlags.South) && x == EndX && y == EndY - 1)
                {
                    openDirections = DirectionFlagsHelper.UnsetDirectionFlag(openDirections, DirectionFlags.South);
                }

                if (DirectionFlagsHelper.HasDirectionFlag(openDirections, DirectionFlags.East) && x == EndX + 1 && y == EndY)
                {
                    openDirections = DirectionFlagsHelper.UnsetDirectionFlag(openDirections, DirectionFlags.East);
                }

                if (DirectionFlagsHelper.HasDirectionFlag(openDirections, DirectionFlags.West) && x == EndX - 1 && y == EndY)
                {
                    openDirections = DirectionFlagsHelper.UnsetDirectionFlag(openDirections, DirectionFlags.West);
                }

                // If we're out of open directions we can go there's no need to continue checking and just return nothing
                if (openDirections == 0)
                {
                    break;
                }
            }

            return(openDirections);
        }
示例#2
0
        public void ProcessBreadthSearchQueueItem(Queue <GetRouteSearchParams> searchQueue, GetRouteSearchParams searchParameters, Dictionary <int, IGameMapMovementRoute> routesFound, IGameUnit unit, int availableMovement)
        {
            // still wonderin'
            if (searchParameters.Direction == Direction.None)
            {
                return;
            }

            // We need to find what tiles we're going to check the movement cost for. Since units cover multiple tiles they have both an area we need to calculate and the edge of the unit we're looking for
            var targetX = searchParameters.BaseRoute.EndX;
            var targetY = searchParameters.BaseRoute.EndY;

            if (searchParameters.Direction == Direction.East)
            {
                targetX += unit.TileWidth;
            }
            else if (searchParameters.Direction == Direction.West)
            {
                targetX -= 1;
            }
            else if (searchParameters.Direction == Direction.North)
            {
                targetY += unit.TileHeight;
            }
            else if (searchParameters.Direction == Direction.South)
            {
                targetY -= 1;
            }

            // Grab the area that we're going to check
            var areaWidth  = DirectionHelper.DirectionVertical(searchParameters.Direction) ? unit.TileWidth : 1;
            var areaHeight = DirectionHelper.DirectionHorizontal(searchParameters.Direction) ? unit.TileHeight : 1;

            // Get the movement cost for this unit to move this direction by one tile
            var movementCost = AreaMovementCostForUnit(unit, targetX, targetY, areaWidth, areaHeight);

            // If the movement cost is IMPASSIBLE or exceeds our available movement then this movement isn't possible
            var totalCost = Mathf.CeilToInt(searchParameters.BaseRoute.RouteCost.Cost + movementCost.Cost); // we do this just as a check here, movement cost can be fractional (TODO: there is a bug here, check half steps logic)

            if (!movementCost.IsPassable || totalCost > availableMovement)
            {
                return;
            }

            // If it is possible to make this movement then we can create a new route for it!
            var routeHere = searchParameters.BaseRoute.CreateExtendRoute(searchParameters.Direction, movementCost);

            // See if we have an existing route to this ending X,Y
            if (routesFound.ContainsKey(routeHere.EndSortKey))
            {
                var compare = GameMapMovementRouteComparer.Instance.Compare(routeHere, routesFound[routeHere.EndSortKey]);
                if (compare < 0)
                {
                    routesFound[routeHere.EndSortKey] = routeHere;
                }
                else if (compare > 0)
                {
                    return;
                }
                else
                {
                    return;  // collision strat: drop latest
                }
            }
            else
            {
                routesFound.Add(routeHere.EndSortKey, routeHere);
            }

            // Find which directions don't overlap the current route
            var openDirections = routeHere.GetOpenDirections();

            // Then add each non-overlapping direction to our queue of searches to perform with this current route
            if (searchParameters.Direction != Direction.North && DirectionFlagsHelper.HasDirectionFlag(openDirections, DirectionFlags.South))
            {
                searchQueue.Enqueue(new GetRouteSearchParams(routeHere, Direction.South));
            }

            if (searchParameters.Direction != Direction.South && DirectionFlagsHelper.HasDirectionFlag(openDirections, DirectionFlags.North))
            {
                searchQueue.Enqueue(new GetRouteSearchParams(routeHere, Direction.North));
            }

            if (searchParameters.Direction != Direction.East && DirectionFlagsHelper.HasDirectionFlag(openDirections, DirectionFlags.West))
            {
                searchQueue.Enqueue(new GetRouteSearchParams(routeHere, Direction.West));
            }

            if (searchParameters.Direction != Direction.West && DirectionFlagsHelper.HasDirectionFlag(openDirections, DirectionFlags.East))
            {
                searchQueue.Enqueue(new GetRouteSearchParams(routeHere, Direction.East));
            }
        }