Exemple #1
0
        private void FloodFillAt(int tile)
        {
            World world = Find.World;

            if (world.Impassable(tile))
            {
                this.fields[tile] = this.impassableFieldID;
                return;
            }
            Find.WorldFloodFiller.FloodFill(tile, (int x) => !world.Impassable(x), delegate(int x)
            {
                this.fields[x] = this.nextFieldID;
            }, 2147483647, null);
            this.nextFieldID++;
        }
        private void FloodFillAt(int tile)
        {
            World world = Find.World;

            if (world.Impassable(tile))
            {
                fields[tile] = impassableFieldID;
                return;
            }
            Find.WorldFloodFiller.FloodFill(tile, (int x) => !world.Impassable(x), delegate(int x)
            {
                fields[x] = nextFieldID;
            });
            nextFieldID++;
        }
        private void FloodFillAt(int tile)
        {
            World world = Find.World;

            if (world.Impassable(tile))
            {
                this.fields[tile] = this.impassableFieldID;
            }
            else
            {
                Find.WorldFloodFiller.FloodFill(tile, (int x) => !world.Impassable(x), delegate(int x)
                {
                    this.fields[x] = this.nextFieldID;
                }, int.MaxValue, null);
                this.nextFieldID++;
            }
        }
Exemple #4
0
        public static bool CanReach(int startTile, int destTile)
        {
            //all reachability for a war object should be verified prior to creating it
            //this might cause bugs during return path or repathing
            //does "WorldReachability" work better?
            //return true;
            int[] fields            = new int[Verse.Find.WorldGrid.TilesCount];
            int   nextFieldID       = 1;
            int   impassableFieldID = nextFieldID;
            int   minValidFieldID   = nextFieldID;

            nextFieldID++;
            if (startTile < 0 || startTile >= fields.Length || destTile < 0 || destTile >= fields.Length)
            {
                return(false);
            }
            if (fields[startTile] == impassableFieldID || fields[destTile] == impassableFieldID)
            {
                return(false);
            }
            if ((fields[startTile] >= minValidFieldID) || (fields[destTile] >= minValidFieldID))
            {
                return(fields[startTile] == fields[destTile]);
            }
            RimWorld.Planet.World world = Verse.Find.World;
            if (world.Impassable(startTile))
            {
                fields[startTile] = impassableFieldID;
            }
            else
            {
                Verse.Find.WorldFloodFiller.FloodFill(startTile, (int x) => !world.Impassable(x), delegate(int x)
                {
                    fields[x] = nextFieldID;
                });
                nextFieldID++;
            }
            if (fields[startTile] == impassableFieldID)
            {
                return(false);
            }
            return(fields[startTile] == fields[destTile]);
        }
Exemple #5
0
        public int FindMostReasonableAdjacentTileForDisplayedPathCost(int fromTile)
        {
            Tile  tile = tiles[fromTile];
            float num  = 1f;
            int   num2 = -1;
            List <Tile.RoadLink> roads = tile.Roads;

            if (roads != null)
            {
                for (int i = 0; i < roads.Count; i++)
                {
                    Tile.RoadLink roadLink = roads[i];
                    float         movementCostMultiplier = roadLink.road.movementCostMultiplier;
                    if (movementCostMultiplier < num)
                    {
                        World         world     = Find.World;
                        Tile.RoadLink roadLink2 = roads[i];
                        if (!world.Impassable(roadLink2.neighbor))
                        {
                            num = movementCostMultiplier;
                            Tile.RoadLink roadLink3 = roads[i];
                            num2 = roadLink3.neighbor;
                        }
                    }
                }
            }
            if (num2 != -1)
            {
                return(num2);
            }
            tmpNeighbors.Clear();
            GetTileNeighbors(fromTile, tmpNeighbors);
            for (int j = 0; j < tmpNeighbors.Count; j++)
            {
                if (!Find.World.Impassable(tmpNeighbors[j]))
                {
                    return(tmpNeighbors[j]);
                }
            }
            return(fromTile);
        }
Exemple #6
0
        public WorldPath FindPath(int startTile, int destTile, Caravan caravan, Func <float, bool> terminator = null)
        {
            if (startTile < 0)
            {
                Log.Error("Tried to FindPath with invalid start tile " + startTile + ", caravan= " + caravan);
                return(WorldPath.NotFound);
            }
            if (destTile < 0)
            {
                Log.Error("Tried to FindPath with invalid dest tile " + destTile + ", caravan= " + caravan);
                return(WorldPath.NotFound);
            }
            if (caravan != null)
            {
                if (!caravan.CanReach(destTile))
                {
                    return(WorldPath.NotFound);
                }
            }
            else if (!Find.WorldReachability.CanReach(startTile, destTile))
            {
                return(WorldPath.NotFound);
            }
            World      world = Find.World;
            WorldGrid  grid  = world.grid;
            List <int> tileIDToNeighbors_offsets = grid.tileIDToNeighbors_offsets;
            List <int> tileIDToNeighbors_values  = grid.tileIDToNeighbors_values;
            Vector3    normalized = grid.GetTileCenter(destTile).normalized;

            float[] movementDifficulty = world.pathGrid.movementDifficulty;
            int     num  = 0;
            int     num2 = caravan?.TicksPerMove ?? 3300;
            int     num3 = CalculateHeuristicStrength(startTile, destTile);

            statusOpenValue   += 2;
            statusClosedValue += 2;
            if (statusClosedValue >= 65435)
            {
                ResetStatuses();
            }
            calcGrid[startTile].knownCost     = 0;
            calcGrid[startTile].heuristicCost = 0;
            calcGrid[startTile].costNodeCost  = 0;
            calcGrid[startTile].parentTile    = startTile;
            calcGrid[startTile].status        = statusOpenValue;
            openList.Clear();
            openList.Push(new CostNode(startTile, 0));
            while (true)
            {
                if (openList.Count <= 0)
                {
                    Log.Warning(caravan + " pathing from " + startTile + " to " + destTile + " ran out of tiles to process.");
                    return(WorldPath.NotFound);
                }
                CostNode costNode = openList.Pop();
                if (costNode.cost != calcGrid[costNode.tile].costNodeCost)
                {
                    continue;
                }
                int tile = costNode.tile;
                if (calcGrid[tile].status == statusClosedValue)
                {
                    continue;
                }
                if (tile == destTile)
                {
                    return(FinalizedPath(tile));
                }
                if (num > 500000)
                {
                    Log.Warning(caravan + " pathing from " + startTile + " to " + destTile + " hit search limit of " + 500000 + " tiles.");
                    return(WorldPath.NotFound);
                }
                int num4 = (tile + 1 < tileIDToNeighbors_offsets.Count) ? tileIDToNeighbors_offsets[tile + 1] : tileIDToNeighbors_values.Count;
                for (int i = tileIDToNeighbors_offsets[tile]; i < num4; i++)
                {
                    int num5 = tileIDToNeighbors_values[i];
                    if (calcGrid[num5].status == statusClosedValue || world.Impassable(num5))
                    {
                        continue;
                    }
                    int    num6   = (int)((float)num2 * movementDifficulty[num5] * grid.GetRoadMovementDifficultyMultiplier(tile, num5)) + calcGrid[tile].knownCost;
                    ushort status = calcGrid[num5].status;
                    if ((status != statusClosedValue && status != statusOpenValue) || calcGrid[num5].knownCost > num6)
                    {
                        Vector3 tileCenter = grid.GetTileCenter(num5);
                        if (status != statusClosedValue && status != statusOpenValue)
                        {
                            float num7 = grid.ApproxDistanceInTiles(GenMath.SphericalDistance(tileCenter.normalized, normalized));
                            calcGrid[num5].heuristicCost = Mathf.RoundToInt((float)num2 * num7 * (float)num3 * 0.5f);
                        }
                        int num8 = num6 + calcGrid[num5].heuristicCost;
                        calcGrid[num5].parentTile   = tile;
                        calcGrid[num5].knownCost    = num6;
                        calcGrid[num5].status       = statusOpenValue;
                        calcGrid[num5].costNodeCost = num8;
                        openList.Push(new CostNode(num5, num8));
                    }
                }
                num++;
                calcGrid[tile].status = statusClosedValue;
                if (terminator != null && terminator(calcGrid[tile].costNodeCost))
                {
                    break;
                }
            }
            return(WorldPath.NotFound);
        }
Exemple #7
0
        public void FloodPathsWithCost(List <int> startTiles, Func <int, int, int> costFunc, Func <int, bool> impassable = null, Func <int, float, bool> terminator = null)
        {
            if (startTiles.Count < 1 || startTiles.Contains(-1))
            {
                Log.Error("Tried to FindPath with invalid start tiles");
                return;
            }
            World      world = Find.World;
            WorldGrid  grid  = world.grid;
            List <int> tileIDToNeighbors_offsets = grid.tileIDToNeighbors_offsets;
            List <int> tileIDToNeighbors_values  = grid.tileIDToNeighbors_values;

            if (impassable == null)
            {
                impassable = ((int tid) => world.Impassable(tid));
            }
            statusOpenValue   += 2;
            statusClosedValue += 2;
            if (statusClosedValue >= 65435)
            {
                ResetStatuses();
            }
            openList.Clear();
            foreach (int startTile in startTiles)
            {
                calcGrid[startTile].knownCost    = 0;
                calcGrid[startTile].costNodeCost = 0;
                calcGrid[startTile].parentTile   = startTile;
                calcGrid[startTile].status       = statusOpenValue;
                openList.Push(new CostNode(startTile, 0));
            }
            while (openList.Count > 0)
            {
                CostNode costNode = openList.Pop();
                if (costNode.cost != calcGrid[costNode.tile].costNodeCost)
                {
                    continue;
                }
                int tile = costNode.tile;
                if (calcGrid[tile].status == statusClosedValue)
                {
                    continue;
                }
                int num = (tile + 1 < tileIDToNeighbors_offsets.Count) ? tileIDToNeighbors_offsets[tile + 1] : tileIDToNeighbors_values.Count;
                for (int i = tileIDToNeighbors_offsets[tile]; i < num; i++)
                {
                    int num2 = tileIDToNeighbors_values[i];
                    if (calcGrid[num2].status != statusClosedValue && !impassable(num2))
                    {
                        int    num3   = costFunc(tile, num2) + calcGrid[tile].knownCost;
                        ushort status = calcGrid[num2].status;
                        if ((status != statusClosedValue && status != statusOpenValue) || calcGrid[num2].knownCost > num3)
                        {
                            int num4 = num3;
                            calcGrid[num2].parentTile   = tile;
                            calcGrid[num2].knownCost    = num3;
                            calcGrid[num2].status       = statusOpenValue;
                            calcGrid[num2].costNodeCost = num4;
                            openList.Push(new CostNode(num2, num4));
                        }
                    }
                }
                calcGrid[tile].status = statusClosedValue;
                if (terminator != null && terminator(tile, calcGrid[tile].costNodeCost))
                {
                    break;
                }
            }
        }
Exemple #8
0
        public WorldPath FindPath(int startTile, int destTile, Caravan caravan, Func <float, bool> terminator = null)
        {
            if (startTile < 0)
            {
                Log.Error("Tried to FindPath with invalid start tile " + startTile + ", caravan= " + caravan);
                return(WorldPath.NotFound);
            }
            if (destTile < 0)
            {
                Log.Error("Tried to FindPath with invalid dest tile " + destTile + ", caravan= " + caravan);
                return(WorldPath.NotFound);
            }
            if (caravan != null)
            {
                if (!caravan.CanReach(destTile))
                {
                    return(WorldPath.NotFound);
                }
            }
            else if (!Find.WorldReachability.CanReach(startTile, destTile))
            {
                return(WorldPath.NotFound);
            }
            World      world = Find.World;
            WorldGrid  grid  = world.grid;
            List <int> tileIDToNeighbors_offsets = grid.tileIDToNeighbors_offsets;
            List <int> tileIDToNeighbors_values  = grid.tileIDToNeighbors_values;
            Vector3    normalized = grid.GetTileCenter(destTile).normalized;

            int[] pathGrid = world.pathGrid.pathGrid;
            int   num      = 0;
            int   num2     = (caravan == null) ? 2500 : caravan.TicksPerMove;
            int   num3     = this.CalculateHeuristicStrength(startTile, destTile);

            this.statusOpenValue   += 2;
            this.statusClosedValue += 2;
            if (this.statusClosedValue >= 65435)
            {
                this.ResetStatuses();
            }
            this.calcGrid[startTile].knownCost     = 0;
            this.calcGrid[startTile].heuristicCost = 0;
            this.calcGrid[startTile].costNodeCost  = 0;
            this.calcGrid[startTile].parentTile    = startTile;
            this.calcGrid[startTile].status        = this.statusOpenValue;
            this.openList.Clear();
            this.openList.Push(new CostNode(startTile, 0));
            while (true)
            {
                if (this.openList.Count <= 0)
                {
                    Log.Warning(caravan + " pathing from " + startTile + " to " + destTile + " ran out of tiles to process.");
                    return(WorldPath.NotFound);
                }
                CostNode costNode = this.openList.Pop();
                if (costNode.cost == this.calcGrid[costNode.tile].costNodeCost)
                {
                    int tile = costNode.tile;
                    if (this.calcGrid[tile].status != this.statusClosedValue)
                    {
                        if (DebugViewSettings.drawPaths)
                        {
                            Find.WorldDebugDrawer.FlashTile(tile, (float)((float)this.calcGrid[tile].knownCost / 375000.0), this.calcGrid[tile].knownCost.ToString(), 50);
                        }
                        if (tile == destTile)
                        {
                            return(this.FinalizedPath(tile));
                        }
                        if (num > 500000)
                        {
                            Log.Warning(caravan + " pathing from " + startTile + " to " + destTile + " hit search limit of " + 500000 + " tiles.");
                            return(WorldPath.NotFound);
                        }
                        int num4 = (tile + 1 >= tileIDToNeighbors_offsets.Count) ? tileIDToNeighbors_values.Count : tileIDToNeighbors_offsets[tile + 1];
                        for (int i = tileIDToNeighbors_offsets[tile]; i < num4; i++)
                        {
                            int    num5 = tileIDToNeighbors_values[i];
                            int    num7;
                            ushort status;
                            if (this.calcGrid[num5].status != this.statusClosedValue && !world.Impassable(num5))
                            {
                                int num6 = num2;
                                num6  += pathGrid[num5];
                                num6   = (int)((float)num6 * grid.GetRoadMovementMultiplierFast(tile, num5));
                                num7   = num6 + this.calcGrid[tile].knownCost;
                                status = this.calcGrid[num5].status;
                                if (status != this.statusClosedValue && status != this.statusOpenValue)
                                {
                                    goto IL_041e;
                                }
                                if (this.calcGrid[num5].knownCost > num7)
                                {
                                    goto IL_041e;
                                }
                            }
                            continue;
IL_041e:
                            Vector3 tileCenter = grid.GetTileCenter(num5);
                            if (status != this.statusClosedValue && status != this.statusOpenValue)
                            {
                                float num8 = grid.ApproxDistanceInTiles(GenMath.SphericalDistance(tileCenter.normalized, normalized));
                                this.calcGrid[num5].heuristicCost = Mathf.RoundToInt((float)((float)num2 * num8 * (float)num3 * 0.5));
                            }
                            int num9 = num7 + this.calcGrid[num5].heuristicCost;
                            this.calcGrid[num5].parentTile   = tile;
                            this.calcGrid[num5].knownCost    = num7;
                            this.calcGrid[num5].status       = this.statusOpenValue;
                            this.calcGrid[num5].costNodeCost = num9;
                            this.openList.Push(new CostNode(num5, num9));
                        }
                        num++;
                        this.calcGrid[tile].status = this.statusClosedValue;
                        if (terminator != null && terminator((float)this.calcGrid[tile].costNodeCost))
                        {
                            break;
                        }
                    }
                }
            }
            return(WorldPath.NotFound);
        }
Exemple #9
0
        public void FloodPathsWithCost(List <int> startTiles, Func <int, int, int> costFunc, Func <int, bool> impassable = null, Func <int, float, bool> terminator = null)
        {
            if (startTiles.Count < 1 || startTiles.Contains(-1))
            {
                Log.Error("Tried to FindPath with invalid start tiles");
            }
            else
            {
                World      world = Find.World;
                WorldGrid  grid  = world.grid;
                List <int> tileIDToNeighbors_offsets = grid.tileIDToNeighbors_offsets;
                List <int> tileIDToNeighbors_values  = grid.tileIDToNeighbors_values;
                if (impassable == null)
                {
                    impassable = ((int tid) => world.Impassable(tid));
                }
                this.statusOpenValue   += 2;
                this.statusClosedValue += 2;
                if (this.statusClosedValue >= 65435)
                {
                    this.ResetStatuses();
                }
                this.openList.Clear();
                foreach (int startTile in startTiles)
                {
                    this.calcGrid[startTile].knownCost    = 0;
                    this.calcGrid[startTile].costNodeCost = 0;
                    this.calcGrid[startTile].parentTile   = startTile;
                    this.calcGrid[startTile].status       = this.statusOpenValue;
                    this.openList.Push(new CostNode(startTile, 0));
                }
                while (this.openList.Count > 0)
                {
                    CostNode costNode = this.openList.Pop();
                    if (costNode.cost == this.calcGrid[costNode.tile].costNodeCost)
                    {
                        int tile = costNode.tile;
                        if (this.calcGrid[tile].status != this.statusClosedValue)
                        {
                            int num = (tile + 1 >= tileIDToNeighbors_offsets.Count) ? tileIDToNeighbors_values.Count : tileIDToNeighbors_offsets[tile + 1];
                            for (int i = tileIDToNeighbors_offsets[tile]; i < num; i++)
                            {
                                int num2 = tileIDToNeighbors_values[i];
                                int num4;
                                if (this.calcGrid[num2].status != this.statusClosedValue && !impassable(num2))
                                {
                                    int num3 = costFunc(tile, num2);
                                    num4 = num3 + this.calcGrid[tile].knownCost;
                                    ushort status = this.calcGrid[num2].status;
                                    if (status != this.statusClosedValue && status != this.statusOpenValue)
                                    {
                                        goto IL_0282;
                                    }
                                    if (this.calcGrid[num2].knownCost > num4)
                                    {
                                        goto IL_0282;
                                    }
                                }
                                continue;
IL_0282:
                                int num5 = num4;
                                this.calcGrid[num2].parentTile   = tile;
                                this.calcGrid[num2].knownCost    = num4;
                                this.calcGrid[num2].status       = this.statusOpenValue;
                                this.calcGrid[num2].costNodeCost = num5;
                                this.openList.Push(new CostNode(num2, num5));
                            }
                            this.calcGrid[tile].status = this.statusClosedValue;
                            if (terminator != null && terminator(tile, (float)this.calcGrid[tile].costNodeCost))
                            {
                                break;
                            }
                        }
                    }
                }
            }
        }
Exemple #10
0
        public WorldPath FindPath(int startTile, int destTile, Caravan caravan, Func <float, bool> terminator = null)
        {
            WorldPath notFound;

            if (startTile < 0)
            {
                Log.Error(string.Concat(new object[]
                {
                    "Tried to FindPath with invalid start tile ",
                    startTile,
                    ", caravan= ",
                    caravan
                }), false);
                notFound = WorldPath.NotFound;
            }
            else if (destTile < 0)
            {
                Log.Error(string.Concat(new object[]
                {
                    "Tried to FindPath with invalid dest tile ",
                    destTile,
                    ", caravan= ",
                    caravan
                }), false);
                notFound = WorldPath.NotFound;
            }
            else
            {
                if (caravan != null)
                {
                    if (!caravan.CanReach(destTile))
                    {
                        return(WorldPath.NotFound);
                    }
                }
                else if (!Find.WorldReachability.CanReach(startTile, destTile))
                {
                    return(WorldPath.NotFound);
                }
                World      world = Find.World;
                WorldGrid  grid  = world.grid;
                List <int> tileIDToNeighbors_offsets = grid.tileIDToNeighbors_offsets;
                List <int> tileIDToNeighbors_values  = grid.tileIDToNeighbors_values;
                Vector3    normalized         = grid.GetTileCenter(destTile).normalized;
                float[]    movementDifficulty = world.pathGrid.movementDifficulty;
                int        num  = 0;
                int        num2 = (caravan == null) ? 3500 : caravan.TicksPerMove;
                int        num3 = this.CalculateHeuristicStrength(startTile, destTile);
                this.statusOpenValue   += 2;
                this.statusClosedValue += 2;
                if (this.statusClosedValue >= 65435)
                {
                    this.ResetStatuses();
                }
                this.calcGrid[startTile].knownCost     = 0;
                this.calcGrid[startTile].heuristicCost = 0;
                this.calcGrid[startTile].costNodeCost  = 0;
                this.calcGrid[startTile].parentTile    = startTile;
                this.calcGrid[startTile].status        = this.statusOpenValue;
                this.openList.Clear();
                this.openList.Push(new WorldPathFinder.CostNode(startTile, 0));
                while (this.openList.Count > 0)
                {
                    WorldPathFinder.CostNode costNode = this.openList.Pop();
                    if (costNode.cost == this.calcGrid[costNode.tile].costNodeCost)
                    {
                        int tile = costNode.tile;
                        if (this.calcGrid[tile].status != this.statusClosedValue)
                        {
                            if (DebugViewSettings.drawPaths)
                            {
                                Find.WorldDebugDrawer.FlashTile(tile, (float)this.calcGrid[tile].knownCost / 375000f, this.calcGrid[tile].knownCost.ToString(), 50);
                            }
                            if (tile == destTile)
                            {
                                return(this.FinalizedPath(tile));
                            }
                            if (num > 500000)
                            {
                                Log.Warning(string.Concat(new object[]
                                {
                                    caravan,
                                    " pathing from ",
                                    startTile,
                                    " to ",
                                    destTile,
                                    " hit search limit of ",
                                    500000,
                                    " tiles."
                                }), false);
                                return(WorldPath.NotFound);
                            }
                            int num4 = (tile + 1 >= tileIDToNeighbors_offsets.Count) ? tileIDToNeighbors_values.Count : tileIDToNeighbors_offsets[tile + 1];
                            for (int i = tileIDToNeighbors_offsets[tile]; i < num4; i++)
                            {
                                int num5 = tileIDToNeighbors_values[i];
                                if (this.calcGrid[num5].status != this.statusClosedValue)
                                {
                                    if (!world.Impassable(num5))
                                    {
                                        int    num6   = (int)((float)num2 * movementDifficulty[num5] * grid.GetRoadMovementDifficultyMultiplier(tile, num5, null));
                                        int    num7   = num6 + this.calcGrid[tile].knownCost;
                                        ushort status = this.calcGrid[num5].status;
                                        if ((status != this.statusClosedValue && status != this.statusOpenValue) || this.calcGrid[num5].knownCost > num7)
                                        {
                                            Vector3 tileCenter = grid.GetTileCenter(num5);
                                            if (status != this.statusClosedValue && status != this.statusOpenValue)
                                            {
                                                float num8 = grid.ApproxDistanceInTiles(GenMath.SphericalDistance(tileCenter.normalized, normalized));
                                                this.calcGrid[num5].heuristicCost = Mathf.RoundToInt((float)num2 * num8 * (float)num3 * 0.5f);
                                            }
                                            int num9 = num7 + this.calcGrid[num5].heuristicCost;
                                            this.calcGrid[num5].parentTile   = tile;
                                            this.calcGrid[num5].knownCost    = num7;
                                            this.calcGrid[num5].status       = this.statusOpenValue;
                                            this.calcGrid[num5].costNodeCost = num9;
                                            this.openList.Push(new WorldPathFinder.CostNode(num5, num9));
                                        }
                                    }
                                }
                            }
                            num++;
                            this.calcGrid[tile].status = this.statusClosedValue;
                            if (terminator != null && terminator((float)this.calcGrid[tile].costNodeCost))
                            {
                                return(WorldPath.NotFound);
                            }
                        }
                    }
                }
                Log.Warning(string.Concat(new object[]
                {
                    caravan,
                    " pathing from ",
                    startTile,
                    " to ",
                    destTile,
                    " ran out of tiles to process."
                }), false);
                notFound = WorldPath.NotFound;
            }
            return(notFound);
        }