Beispiel #1
0
 public static RegionCostCalculatorWrapper get_regionCostCalculator(PathFinder __instance)
 {
     if (!regionCostCalculatorDict.TryGetValue(__instance, out RegionCostCalculatorWrapper regionCostCalculatorWrapper))
     {
         regionCostCalculatorWrapper          = new RegionCostCalculatorWrapper(mapField(__instance));
         regionCostCalculatorDict[__instance] = regionCostCalculatorWrapper;
     }
     return(regionCostCalculatorWrapper);
 }
Beispiel #2
0
 public CVPathFinder(Map map)
 {
     this.map                  = map;
     this.mapSizeX             = map.Size.x;
     this.mapSizeZ             = map.Size.z;
     this.calcGrid             = new CVPathFinder.CVPathFinderNodeFast[this.mapSizeX * this.mapSizeZ];
     this.openList             = new FastPriorityQueue <CVPathFinder.CostNode>(new CVPathFinder.CostNodeComparer());
     this.regionCostCalculator = new RegionCostCalculatorWrapper(map);
 }
        public static bool Init(RegionCostCalculatorWrapper __instance, CellRect end, TraverseParms traverseParms, int moveTicksCardinal, int moveTicksDiagonal, ByteGrid avoidGrid, Area allowedArea, bool drafted, List <int> disallowedCorners)
        {
            moveTicksCardinalField(__instance) = moveTicksCardinal;
            moveTicksDiagonalField(__instance) = moveTicksDiagonal;
            endCell(__instance)              = end.CenterCell;
            cachedRegion(__instance)         = null;
            cachedBestLink(__instance)       = null;
            cachedSecondBestLink(__instance) = null;
            cachedBestLinkCost(__instance)       = 0;
            cachedSecondBestLinkCost(__instance) = 0;
            cachedRegionIsDestination(__instance) = false;
            Map        map1        = map(__instance);
            RegionGrid regionGrid1 = map1.regionGrid;

            if (regionGrid1 == null)
            {
                Log.Error("regionGrid is null for map: " + map1.ToString());
                return(false);
            }
            regionGrid(__instance) = regionGrid1.DirectGrid;
            destRegions(__instance).Clear();
            if (end.Width == 1 && end.Height == 1)
            {
                Region region = endCell(__instance).GetRegion(map(__instance));
                if (region != null)
                {
                    destRegions(__instance).Add(region);
                }
            }
            else
            {
                foreach (IntVec3 item in end)
                {
                    if (item.InBounds(map(__instance)) && !disallowedCorners.Contains(map(__instance).cellIndices.CellToIndex(item)))
                    {
                        Region region2 = item.GetRegion(map(__instance));
                        if (region2 != null && region2.Allows(traverseParms, isDestination: true))
                        {
                            destRegions(__instance).Add(region2);
                        }
                    }
                }
            }

            if (destRegions(__instance).Count == 0)
            {
                Log.Error("Couldn't find any destination regions. This shouldn't ever happen because we've checked reachability.");
            }

            regionCostCalculator(__instance).Init(
                end, destRegions(__instance), traverseParms, moveTicksCardinal, moveTicksDiagonal, avoidGrid, allowedArea, drafted);

            return(false);
        }
 public VehiclePathFinder(Map map, bool report = true)
 {
     this.map = map;
     mapSizeX = map.Size.x;
     mapSizeZ = map.Size.z;
     calcGrid = new VehiclePathFinderNodeFast[mapSizeX * mapSizeZ];
     openList = new FastPriorityQueue <CostNode>(new CostNodeComparer());
     regionCostCalculatorSea  = new VehicleRegionCostCalculatorWrapper(map);
     regionCostCalculatorLand = new RegionCostCalculatorWrapper(map);
     postCalculatedCells      = new Dictionary <IntVec3, int>();
     this.report = report;
 }
Beispiel #5
0
        public DebugPathFinder(Map map)
        {
            this.map = map;
            IntVec3 size = map.Size;

            mapSizeX = size.x;
            IntVec3 size2 = map.Size;

            mapSizeZ             = size2.z;
            calcGrid             = new PathFinderNodeFast[mapSizeX * mapSizeZ];
            openList             = new FastPriorityQueue <CostNode>(new CostNodeComparer());
            regionCostCalculator = new RegionCostCalculatorWrapper(map);
        }
Beispiel #6
0
        public TerrainAwarePathFinder(Map map)
        {
            this.map = map;
            mapSizeX = map.Size.x;
            mapSizeZ = map.Size.z;
            int num = mapSizeX * mapSizeZ;

            if (calcGrid == null || calcGrid.Length < num)
            {
                calcGrid = new PathFinderNodeFast[num];
            }
            openList             = new FastPriorityQueue <CostNode>(new CostNodeComparer());
            regionCostCalculator = new RegionCostCalculatorWrapper(map);
        }
        //public static FastPriorityQueue<CostNode2> openList = new FastPriorityQueue<CostNode2>(new CostNodeComparer2());
        //public static PathFinderNodeFast[] calcGrid = new PathFinderNodeFast[40000];
        //public static ushort statusOpenValue = 1;
        //public static ushort statusClosedValue = 2;
        public static bool FindPath(PathFinder __instance, ref PawnPath __result, IntVec3 start, LocalTargetInfo dest, TraverseParms traverseParms, PathEndMode peMode = PathEndMode.OnCell)
        {
            FastPriorityQueue <CostNode2> openList = getOpenList();
            ushort statusOpenValue   = getOpenValue();
            ushort statusClosedValue = getClosedValue();

            PathFinderNodeFast[]        calcGrid             = getCalcGrid(__instance);
            RegionCostCalculatorWrapper regionCostCalculator = getRegionCostCalculatorWrapper(__instance);

            if (DebugSettings.pathThroughWalls)
            {
                traverseParms.mode = TraverseMode.PassAllDestroyableThings;
            }

            Pawn pawn = traverseParms.pawn;

            if (pawn != null && pawn.Map != mapField(__instance))
            {
                Log.Error(string.Concat("Tried to FindPath for pawn which is spawned in another map. His map PathFinder should have been used, not this one. pawn=", pawn, " pawn.Map=", pawn.Map, " map=", mapField(__instance)));
                __result = PawnPath.NotFound;
                return(false);
            }

            if (!start.IsValid)
            {
                Log.Error(string.Concat("Tried to FindPath with invalid start ", start, ", pawn= ", pawn));
                __result = PawnPath.NotFound;
                return(false);
            }

            if (!dest.IsValid)
            {
                Log.Error(string.Concat("Tried to FindPath with invalid dest ", dest, ", pawn= ", pawn));
                __result = PawnPath.NotFound;
                return(false);
            }

            if (traverseParms.mode == TraverseMode.ByPawn)
            {
                if (!pawn.CanReach(dest, peMode, Danger.Deadly, traverseParms.canBash, traverseParms.mode))
                {
                    __result = PawnPath.NotFound;
                    return(false);
                }
            }
            else if (!mapField(__instance).reachability.CanReach(start, dest, peMode, traverseParms))
            {
                __result = PawnPath.NotFound;
                return(false);
            }

            PfProfilerBeginSample(string.Concat("FindPath for ", pawn, " from ", start, " to ", dest, dest.HasThing ? (" at " + dest.Cell) : ""));
            cellIndicesField(__instance)   = mapField(__instance).cellIndices;
            pathGridField(__instance)      = mapField(__instance).pathGrid;
            edificeGridField(__instance)   = mapField(__instance).edificeGrid.InnerArray;
            blueprintGridField(__instance) = mapField(__instance).blueprintGrid.InnerArray;
            int      x               = dest.Cell.x;
            int      z               = dest.Cell.z;
            int      curIndex        = cellIndicesField(__instance).CellToIndex(start);
            int      num             = cellIndicesField(__instance).CellToIndex(dest.Cell);
            ByteGrid byteGrid        = pawn?.GetAvoidGrid();
            bool     flag            = traverseParms.mode == TraverseMode.PassAllDestroyableThings || traverseParms.mode == TraverseMode.PassAllDestroyableThingsNotWater;
            bool     flag2           = traverseParms.mode != TraverseMode.NoPassClosedDoorsOrWater && traverseParms.mode != TraverseMode.PassAllDestroyableThingsNotWater;
            bool     flag3           = !flag;
            CellRect destinationRect = CalculateDestinationRect(dest, peMode);
            bool     flag4           = destinationRect.Width == 1 && destinationRect.Height == 1;

            int[]        array       = mapField(__instance).pathGrid.pathGrid;
            TerrainDef[] topGrid     = mapField(__instance).terrainGrid.topGrid;
            EdificeGrid  edificeGrid = mapField(__instance).edificeGrid;
            int          num2        = 0;
            int          num3        = 0;
            Area         allowedArea = GetAllowedArea(pawn);
            bool         flag5       = pawn != null && PawnUtility.ShouldCollideWithPawns(pawn);
            bool         flag6       = !flag && start.GetRegion(mapField(__instance)) != null && flag2;
            bool         flag7       = !flag || !flag3;
            bool         flag8       = false;
            bool         flag9       = pawn?.Drafted ?? false;
            int          num4        = (pawn?.IsColonist ?? false) ? 100000 : 2000;
            int          num5        = 0;
            int          num6        = 0;
            float        num7        = DetermineHeuristicStrength(pawn, start, dest);
            int          num8;
            int          num9;

            if (pawn != null)
            {
                num8 = pawn.TicksPerMoveCardinal;
                num9 = pawn.TicksPerMoveDiagonal;
            }
            else
            {
                num8 = 13;
                num9 = 18;
            }

            CalculateAndAddDisallowedCorners2(disallowedCornerIndicesField(__instance), mapField(__instance), peMode, destinationRect);
            InitStatusesAndPushStartNode3(ref curIndex, start, cellIndicesField(__instance), calcGrid, ref statusOpenValue, ref statusClosedValue);
            openList.Clear();
            openList.Push(new CostNode2(curIndex, 0));
            while (true)
            {
                PfProfilerBeginSample("Open cell");
                if (openList.Count <= 0)
                {
                    string text  = (pawn != null && pawn.CurJob != null) ? pawn.CurJob.ToString() : "null";
                    string text2 = (pawn != null && pawn.Faction != null) ? pawn.Faction.ToString() : "null";
                    Log.Warning(string.Concat(pawn, " pathing from ", start, " to ", dest, " ran out of cells to process.\nJob:", text, "\nFaction: ", text2));
                    DebugDrawRichData();
                    PfProfilerEndSample();
                    PfProfilerEndSample();
                    __result = PawnPath.NotFound;
                    return(false);
                }

                num5 += openList.Count;
                num6++;
                CostNode2 costNode = openList.Pop();
                curIndex = costNode.index;
                if (costNode.cost != calcGrid[curIndex].costNodeCost)
                {
                    PfProfilerEndSample();
                    continue;
                }

                if (calcGrid[curIndex].status == statusClosedValue)
                {
                    PfProfilerEndSample();
                    continue;
                }

                IntVec3 c  = cellIndicesField(__instance).IndexToCell(curIndex);
                int     x2 = c.x;
                int     z2 = c.z;
                if (flag4)
                {
                    if (curIndex == num)
                    {
                        PfProfilerEndSample();
                        PawnPath result = FinalizedPath2(curIndex, flag8, cellIndicesField(__instance), calcGrid);
                        PfProfilerEndSample();
                        __result = result;
                        return(false);
                    }
                }
                else if (destinationRect.Contains(c) && !disallowedCornerIndicesField(__instance).Contains(curIndex))
                {
                    PfProfilerEndSample();
                    PawnPath result2 = FinalizedPath2(curIndex, flag8, cellIndicesField(__instance), calcGrid);
                    PfProfilerEndSample();
                    __result = result2;
                    return(false);
                }

                if (num2 > 160000)
                {
                    break;
                }

                PfProfilerEndSample();
                PfProfilerBeginSample("Neighbor consideration");
                for (int i = 0; i < 8; i++)
                {
                    uint num10 = (uint)(x2 + Directions[i]);
                    uint num11 = (uint)(z2 + Directions[i + 8]);
                    if (num10 >= mapSizeXField(__instance) || num11 >= mapSizeZField(__instance))
                    {
                        continue;
                    }

                    int num12 = (int)num10;
                    int num13 = (int)num11;
                    int num14 = cellIndicesField(__instance).CellToIndex(num12, num13);
                    if (calcGrid[num14].status == statusClosedValue && !flag8)
                    {
                        continue;
                    }

                    int  num15  = 0;
                    bool flag10 = false;
                    if (!flag2 && new IntVec3(num12, 0, num13).GetTerrain(mapField(__instance)).HasTag("Water"))
                    {
                        continue;
                    }

                    if (!pathGridField(__instance).WalkableFast(num14))
                    {
                        if (!flag)
                        {
                            continue;
                        }

                        flag10 = true;
                        num15 += 70;
                        Building building = edificeGrid[num14];
                        if (building == null || !PathFinder.IsDestroyable(building))
                        {
                            continue;
                        }

                        num15 += (int)(building.HitPoints * 0.2f);
                    }

                    switch (i)
                    {
                    case 4:
                        if (PathFinder.BlocksDiagonalMovement(curIndex - mapSizeXField(__instance), mapField(__instance)))
                        {
                            if (flag7)
                            {
                                continue;
                            }

                            num15 += 70;
                        }

                        if (PathFinder.BlocksDiagonalMovement(curIndex + 1, mapField(__instance)))
                        {
                            if (flag7)
                            {
                                continue;
                            }

                            num15 += 70;
                        }

                        break;

                    case 5:
                        if (PathFinder.BlocksDiagonalMovement(curIndex + mapSizeXField(__instance), mapField(__instance)))
                        {
                            if (flag7)
                            {
                                continue;
                            }

                            num15 += 70;
                        }

                        if (PathFinder.BlocksDiagonalMovement(curIndex + 1, mapField(__instance)))
                        {
                            if (flag7)
                            {
                                continue;
                            }

                            num15 += 70;
                        }

                        break;

                    case 6:
                        if (PathFinder.BlocksDiagonalMovement(curIndex + mapSizeXField(__instance), mapField(__instance)))
                        {
                            if (flag7)
                            {
                                continue;
                            }

                            num15 += 70;
                        }

                        if (PathFinder.BlocksDiagonalMovement(curIndex - 1, mapField(__instance)))
                        {
                            if (flag7)
                            {
                                continue;
                            }

                            num15 += 70;
                        }

                        break;

                    case 7:
                        if (PathFinder.BlocksDiagonalMovement(curIndex - mapSizeXField(__instance), mapField(__instance)))
                        {
                            if (flag7)
                            {
                                continue;
                            }

                            num15 += 70;
                        }

                        if (PathFinder.BlocksDiagonalMovement(curIndex - 1, mapField(__instance)))
                        {
                            if (flag7)
                            {
                                continue;
                            }

                            num15 += 70;
                        }

                        break;
                    }

                    int num16 = (i > 3) ? num9 : num8;
                    num16 += num15;
                    if (!flag10)
                    {
                        num16 += array[num14];
                        num16  = ((!flag9) ? (num16 + topGrid[num14].extraNonDraftedPerceivedPathCost) : (num16 + topGrid[num14].extraDraftedPerceivedPathCost));
                    }

                    if (byteGrid != null)
                    {
                        num16 += byteGrid[num14] * 8;
                    }

                    if (allowedArea != null && !allowedArea[num14])
                    {
                        num16 += 600;
                    }

                    if (flag5 && PawnUtility.AnyPawnBlockingPathAt(new IntVec3(num12, 0, num13), pawn, actAsIfHadCollideWithPawnsJob: false, collideOnlyWithStandingPawns: false, forPathFinder: true))
                    {
                        num16 += 175;
                    }

                    Building building2 = edificeGridField(__instance)[num14];
                    if (building2 != null)
                    {
                        PfProfilerBeginSample("Edifices");
                        int buildingCost = PathFinder.GetBuildingCost(building2, traverseParms, pawn);
                        if (buildingCost == int.MaxValue)
                        {
                            PfProfilerEndSample();
                            continue;
                        }

                        num16 += buildingCost;
                        PfProfilerEndSample();
                    }

                    List <Blueprint> list = blueprintGridField(__instance)[num14];
                    if (list != null)
                    {
                        PfProfilerBeginSample("Blueprints");
                        int num17 = 0;
                        for (int j = 0; j < list.Count; j++)
                        {
                            num17 = Mathf.Max(num17, PathFinder.GetBlueprintCost(list[j], pawn));
                        }

                        if (num17 == int.MaxValue)
                        {
                            PfProfilerEndSample();
                            continue;
                        }

                        num16 += num17;
                        PfProfilerEndSample();
                    }

                    int    num18  = num16 + calcGrid[curIndex].knownCost;
                    ushort status = calcGrid[num14].status;
                    if (status == statusClosedValue || status == statusOpenValue)
                    {
                        int num19 = 0;
                        if (status == statusClosedValue)
                        {
                            num19 = num8;
                        }

                        if (calcGrid[num14].knownCost <= num18 + num19)
                        {
                            continue;
                        }
                    }

                    if (flag8)
                    {
                        calcGrid[num14].heuristicCost = Mathf.RoundToInt((float)regionCostCalculator.GetPathCostFromDestToRegion(num14) * RegionHeuristicWeightByNodesOpened.Evaluate(num3));
                        if (calcGrid[num14].heuristicCost < 0)
                        {
                            Log.ErrorOnce(string.Concat("Heuristic cost overflow for ", pawn.ToStringSafe(), " pathing from ", start, " to ", dest, "."), pawn.GetHashCode() ^ 0xB8DC389);
                            calcGrid[num14].heuristicCost = 0;
                        }
                    }
                    else if (status != statusClosedValue && status != statusOpenValue)
                    {
                        int dx    = Math.Abs(num12 - x);
                        int dz    = Math.Abs(num13 - z);
                        int num20 = GenMath.OctileDistance(dx, dz, num8, num9);
                        calcGrid[num14].heuristicCost = Mathf.RoundToInt((float)num20 * num7);
                    }

                    int num21 = num18 + calcGrid[num14].heuristicCost;
                    if (num21 < 0)
                    {
                        Log.ErrorOnce(string.Concat("Node cost overflow for ", pawn.ToStringSafe(), " pathing from ", start, " to ", dest, "."), pawn.GetHashCode() ^ 0x53CB9DE);
                        num21 = 0;
                    }

                    calcGrid[num14].parentIndex  = curIndex;
                    calcGrid[num14].knownCost    = num18;
                    calcGrid[num14].status       = statusOpenValue;
                    calcGrid[num14].costNodeCost = num21;
                    num3++;
                    openList.Push(new CostNode2(num14, num21));
                }

                PfProfilerEndSample();
                num2++;
                calcGrid[curIndex].status = statusClosedValue;
                if (num3 >= num4 && flag6 && !flag8)
                {
                    flag8 = true;
                    regionCostCalculator.Init(destinationRect, traverseParms, num8, num9, byteGrid, allowedArea, flag9, disallowedCornerIndicesField(__instance));
                    InitStatusesAndPushStartNode3(ref curIndex, start, cellIndicesField(__instance), calcGrid, ref statusOpenValue, ref statusClosedValue);
                    openList.Clear();
                    openList.Push(new CostNode2(curIndex, 0));
                    num3 = 0;
                    num2 = 0;
                }
            }

            Log.Warning(string.Concat(pawn, " pathing from ", start, " to ", dest, " hit search limit of ", 160000, " cells."));
            DebugDrawRichData();
            PfProfilerEndSample();
            PfProfilerEndSample();
            __result = PawnPath.NotFound;
            return(false);
        }
Beispiel #8
0
 public static void SetRegionCostCalculator(PathFinder __instance, RegionCostCalculatorWrapper regionCostCalculatorWrapper)
 {
     regionCostCalculatorDict[__instance] = regionCostCalculatorWrapper;
     return;
 }