Exemplo n.º 1
0
 public override void FinalizeInit()
 {
     ConstructComponents();
     VehiclePathGrid.RecalculateAllPerceivedPathCosts();
     VehicleRegionAndRoomUpdater.Enabled = true;
     VehicleRegionAndRoomUpdater.RebuildAllWaterRegions();
 }
Exemplo n.º 2
0
 public void ConstructComponents()
 {
     VehiclePathGrid = new VehiclePathGrid(map);
     ShipPathFinder  = new VehiclePathFinder(map);
     ThreadedPathFinderConstrained = new VehiclePathFinder(map, false);
     VehicleReachability           = new VehicleReachability(map);
     VehicleRegionGrid             = new VehicleRegionGrid(map);
     VehicleRegionMaker            = new VehicleRegionMaker(map);
     VehicleRegionAndRoomUpdater   = new VehicleRegionAndRoomUpdater(map);
     VehicleRegionLinkDatabase     = new VehicleRegionLinkDatabase();
     VehicleRegionDirtyer          = new VehicleRegionDirtyer(map);
 }
        private List <int> PathableNeighborIndices(int index)
        {
            tmpPathableNeighborIndices.Clear();
            VehiclePathGrid pathGrid = mapE.VehiclePathGrid;
            int             x        = map.Size.x;
            bool            flag     = index % x > 0;
            bool            flag2    = index % x < x - 1;
            bool            flag3    = index >= x;
            bool            flag4    = index / x < map.Size.z - 1;

            if (flag3 && pathGrid.WalkableFast(index - x))
            {
                tmpPathableNeighborIndices.Add(index - x);
            }
            if (flag2 && pathGrid.WalkableFast(index + 1))
            {
                tmpPathableNeighborIndices.Add(index + 1);
            }
            if (flag && pathGrid.WalkableFast(index - 1))
            {
                tmpPathableNeighborIndices.Add(index - 1);
            }
            if (flag4 && pathGrid.WalkableFast(index + x))
            {
                tmpPathableNeighborIndices.Add(index + x);
            }
            bool flag5 = !flag || VehiclePathFinder.BlocksDiagonalMovement(map, index - 1);
            bool flag6 = !flag2 || VehiclePathFinder.BlocksDiagonalMovement(map, index + 1);

            if (flag3 && !VehiclePathFinder.BlocksDiagonalMovement(map, index - x))
            {
                if (!flag6 && pathGrid.WalkableFast(index - x + 1))
                {
                    tmpPathableNeighborIndices.Add(index - x + 1);
                }
                if (!flag5 && pathGrid.WalkableFast(index - x - 1))
                {
                    tmpPathableNeighborIndices.Add(index - x - 1);
                }
            }
            if (flag4 && !VehiclePathFinder.BlocksDiagonalMovement(map, index + x))
            {
                if (!flag6 && pathGrid.WalkableFast(index + x + 1))
                {
                    tmpPathableNeighborIndices.Add(index + x + 1);
                }
                if (!flag5 && pathGrid.WalkableFast(index + x - 1))
                {
                    tmpPathableNeighborIndices.Add(index + x - 1);
                }
            }
            return(tmpPathableNeighborIndices);
        }
Exemplo n.º 4
0
        public (PawnPath path, bool found) FindVehiclePath(IntVec3 start, LocalTargetInfo dest, TraverseParms traverseParms, CancellationToken token, PathEndMode peMode = PathEndMode.OnCell, bool waterPathing = false)
        {
            if (report)
            {
                Debug.Message($"{VehicleHarmony.LogLabel} MainPath for {traverseParms.pawn.LabelShort} - ThreadId: [{Thread.CurrentThread.ManagedThreadId}] TaskId: [{Task.CurrentId}]");
            }

            postCalculatedCells.Clear();
            VehicleMapping VehicleMapping = map.GetCachedMapComponent <VehicleMapping>();

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

            if (!pawn.IsBoat() && waterPathing)
            {
                Log.Error($"Set to waterPathing but {pawn.LabelShort} is not registered as a Boat. Self Correcting...");
                waterPathing = false;
            }
            if (!(pawn is null) && pawn.Map != map)
            {
                Log.Error(string.Concat(new object[]
                {
                    "Tried to FindVehiclePath for pawn which is spawned in another map. Their map PathFinder should  have been used, not this one. " +
                    "pawn=", pawn,
                    " pawn.Map=", pawn.Map,
                    " map=", map
                }));
                return(PawnPath.NotFound, false);
            }
            if (!start.IsValid)
            {
                Log.Error(string.Concat(new object[]
                {
                    "Tried to FindShipPath with invalid start ",
                    start,
                    ", pawn=", pawn
                }));
                return(PawnPath.NotFound, false);
            }
            if (!dest.IsValid)
            {
                Log.Error(string.Concat(new object[]
                {
                    "Tried to FindPath with invalid dest ",
                    dest,
                    ", pawn= ",
                    pawn
                }));
                return(PawnPath.NotFound, false);
            }
            if (traverseParms.mode == TraverseMode.ByPawn)
            {
                if (waterPathing)
                {
                    if (!ShipReachabilityUtility.CanReachShip(pawn, dest, peMode, Danger.Deadly, false, traverseParms.mode))
                    {
                        return(PawnPath.NotFound, false);
                    }
                }
                else
                {
                    if (!ReachabilityUtility.CanReach(pawn, dest, peMode, Danger.Deadly, false, traverseParms.mode))
                    {
                        return(PawnPath.NotFound, false);
                    }
                }
            }
            else
            {
                if (waterPathing)
                {
                    if (!VehicleMapping.VehicleReachability.CanReachShip(start, dest, peMode, traverseParms))
                    {
                        return(PawnPath.NotFound, false);
                    }
                }
                else
                {
                    if (!map.reachability.CanReach(start, dest, peMode, traverseParms))
                    {
                        return(PawnPath.NotFound, false);
                    }
                }
            }
            cellIndices = map.cellIndices;

            VehiclePathGrid  = VehicleMapping.VehiclePathGrid;
            pathGrid         = map.pathGrid;
            this.edificeGrid = map.edificeGrid.InnerArray;
            blueprintGrid    = map.blueprintGrid.InnerArray;
            int      x        = dest.Cell.x;
            int      z        = dest.Cell.z;
            int      num      = cellIndices.CellToIndex(start);
            int      num2     = cellIndices.CellToIndex(dest.Cell);
            ByteGrid byteGrid = (pawn is null) ? null : pawn.GetAvoidGrid(true);
            bool     flag     = traverseParms.mode == TraverseMode.PassAllDestroyableThings || traverseParms.mode == TraverseMode.PassAllDestroyableThingsNotWater;
            bool     flag2    = traverseParms.mode != TraverseMode.NoPassClosedDoorsOrWater && traverseParms.mode != TraverseMode.PassAllDestroyableThingsNotWater;
            bool     flag3    = !flag;
            CellRect cellRect = CalculateDestinationRect(dest, peMode);
            bool     flag4    = cellRect.Width == 1 && cellRect.Height == 1;

            int[]        boatsArray   = VehiclePathGrid.pathGrid;
            int[]        vehicleArray = pathGrid.pathGrid;
            TerrainDef[] topGrid      = map.terrainGrid.topGrid;
            EdificeGrid  edificeGrid  = map.edificeGrid;
            int          num3         = 0;
            int          num4         = 0;
            Area         allowedArea  = GetAllowedArea(pawn);
            bool         flag5        = !(pawn is null) && PawnUtility.ShouldCollideWithPawns(pawn);
            bool         flag6        = true && DebugViewSettings.drawPaths;
            bool         flag7        = !flag && !(VehicleGridsUtility.GetRegion(start, map, RegionType.Set_Passable) is null) && flag2;
            bool         flag8        = !flag || !flag3;
            bool         flag9        = false;
            bool         flag10       = !(pawn is null) && pawn.Drafted;
            bool         flag11       = !(pawn is null) && !(pawn is null);

            int   num5  = (!flag11) ? NodesToOpenBeforeRegionbasedPathing_NonShip : NodesToOpenBeforeRegionBasedPathing_Ship;
            int   num6  = 0;
            int   num7  = 0;
            float num8  = DetermineHeuristicStrength(pawn, start, dest);
            int   num9  = !(pawn is null) ? pawn.TicksPerMoveCardinal : DefaultMoveTicksCardinal;
            int   num10 = !(pawn is null) ? pawn.TicksPerMoveDiagonal : DefaultMoveTicksDiagonal;

            CalculateAndAddDisallowedCorners(traverseParms, peMode, cellRect);
            InitStatusesAndPushStartNode(ref num, start);
            Rot8 rot        = pawn.FullRotation;
            int  iterations = 0;

            for (;;)
            {
                if (token.IsCancellationRequested)
                {
                    return(PawnPath.NotFound, false);
                }

                iterations++;
                if (openList.Count <= 0)
                {
                    break;
                }
                num6 += openList.Count;
                num7++;
                CostNode costNode = openList.Pop();
                num = costNode.index;
                if (costNode.cost == calcGrid[num].costNodeCost && calcGrid[num].status != statusClosedValue)
                {
                    IntVec3 c        = cellIndices.IndexToCell(num);
                    IntVec3 prevCell = c;
                    int     x2       = c.x;
                    int     z2       = c.z;
                    if (flag6)
                    {
                        DebugFlash(c, calcGrid[num].knownCost / 1500f, calcGrid[num].knownCost.ToString());
                    }
                    if (flag4)
                    {
                        if (num == num2)
                        {
                            goto Block_32;
                        }
                    }
                    else if (cellRect.Contains(c) && !disallowedCornerIndices.Contains(num))
                    {
                        goto Block_32;
                    }
                    if (num3 > SearchLimit)
                    {
                        goto Block_33;
                    }

                    List <IntVec3> fullRectCells = CellRect.CenteredOn(c, pawn.def.size.x, pawn.def.size.z).Where(cl2 => cl2 != c).ToList();

                    for (int i = 0; i < 8; i++)
                    {
                        uint num11 = (uint)(x2 + Directions[i]);                           //x
                        uint num12 = (uint)(z2 + Directions[i + 8]);                       //y

                        if (num11 < ((ulong)mapSizeX) && num12 < (ulong)(mapSizeZ))
                        {
                            int num13 = (int)num11;
                            int num14 = (int)num12;
                            int num15 = cellIndices.CellToIndex(num13, num14);

                            IntVec3 cellToCheck = cellIndices.IndexToCell(num15);
                            if (VehicleMod.settings.main.fullVehiclePathing && pawn.LocationRestrictedBySize(cellToCheck))
                            {
                                goto EndPathing;
                            }

                            if (calcGrid[num15].status != statusClosedValue || flag9)
                            {
                                int  num16  = 0;
                                bool flag12 = false;                                 //Extra cost for traversing water

                                if (flag2 || !new IntVec3(num13, 0, num14).GetTerrain(map).HasTag("Water"))
                                {
                                    if (waterPathing)
                                    {
                                        if (!pawn.DrivableFast(num15))
                                        {
                                            if (!flag)
                                            {
                                                if (flag6)
                                                {
                                                    DebugFlash(new IntVec3(num13, 0, num14), 0.22f, "walk");
                                                }
                                                goto EndPathing;
                                            }

                                            num16 += 70;
                                            Building building = edificeGrid[num15];
                                            if (building is null)
                                            {
                                                goto EndPathing;
                                            }
                                            if (!IsDestroyable(building))
                                            {
                                                goto EndPathing;
                                            }
                                            num16 += (int)(building.HitPoints * 0.2f);
                                        }
                                    }
                                    else
                                    {
                                        if (!pawn.DrivableFast(num15))
                                        {
                                            if (!flag)
                                            {
                                                if (flag6)
                                                {
                                                    DebugFlash(new IntVec3(num13, 0, num14), 0.22f, "walk");
                                                }
                                                goto EndPathing;
                                            }
                                            flag12 = true;
                                            num16 += 70;
                                            Building building = edificeGrid[num15];
                                            if (building is null)
                                            {
                                                goto EndPathing;
                                            }
                                            if (!IsDestroyable(building))
                                            {
                                                goto EndPathing;
                                            }
                                            num16 += (int)(building.HitPoints * 0.2f);
                                        }
                                    }

                                    if (i > 3)
                                    {
                                        switch (i)
                                        {
                                        case 4:
                                            if (BlocksDiagonalMovement(pawn, num - mapSizeX))
                                            {
                                                if (flag8)
                                                {
                                                    if (flag6)
                                                    {
                                                        DebugFlash(new IntVec3(x2, 0, z2 - 1), 0.9f, "ships");
                                                    }
                                                    goto EndPathing;
                                                }
                                                num16 += 70;
                                            }
                                            if (BlocksDiagonalMovement(pawn, num + 1))
                                            {
                                                if (flag8)
                                                {
                                                    if (flag6)
                                                    {
                                                        DebugFlash(new IntVec3(x2 + 1, 0, z2), 0.9f, "ships");
                                                    }
                                                    goto EndPathing;
                                                }
                                                num16 += 70;
                                            }
                                            break;

                                        case 5:
                                            if (BlocksDiagonalMovement(pawn, num + mapSizeX))
                                            {
                                                if (flag8)
                                                {
                                                    if (flag6)
                                                    {
                                                        DebugFlash(new IntVec3(x2, 0, z2 + 1), 0.9f, "ships");
                                                    }
                                                    goto EndPathing;
                                                }
                                                num16 += 70;
                                            }
                                            if (BlocksDiagonalMovement(pawn, num + 1))
                                            {
                                                if (flag8)
                                                {
                                                    if (flag6)
                                                    {
                                                        DebugFlash(new IntVec3(x2 + 1, 0, z2), 0.9f, "ships");
                                                    }
                                                    goto EndPathing;
                                                }
                                                num16 += 70;
                                            }
                                            break;

                                        case 6:
                                            if (BlocksDiagonalMovement(pawn, num + mapSizeX))
                                            {
                                                if (flag8)
                                                {
                                                    if (flag6)
                                                    {
                                                        DebugFlash(new IntVec3(x2, 0, z2 + 1), 0.9f, "ships");
                                                    }
                                                    goto EndPathing;
                                                }
                                                num16 += 70;
                                            }
                                            if (BlocksDiagonalMovement(pawn, num - 1))
                                            {
                                                if (flag8)
                                                {
                                                    if (flag6)
                                                    {
                                                        DebugFlash(new IntVec3(x2 - 1, 0, z2), 0.9f, "ships");
                                                    }
                                                    goto EndPathing;
                                                }
                                                num16 += 70;
                                            }
                                            break;

                                        case 7:
                                            if (BlocksDiagonalMovement(pawn, num - mapSizeX))
                                            {
                                                if (flag8)
                                                {
                                                    if (flag6)
                                                    {
                                                        DebugFlash(new IntVec3(x2, 0, z2 - 1), 0.9f, "ships");
                                                    }
                                                    goto EndPathing;
                                                }
                                                num16 += 70;
                                            }
                                            if (BlocksDiagonalMovement(pawn, num - 1))
                                            {
                                                if (flag8)
                                                {
                                                    if (flag6)
                                                    {
                                                        DebugFlash(new IntVec3(x2 - 1, 0, z2), 0.9f, "ships");
                                                    }
                                                    goto EndPathing;
                                                }
                                                num16 += 70;
                                            }
                                            break;
                                        }
                                    }
                                    int num17 = (i <= 3) ? num9 : num10;
                                    num17 += num16;
                                    //if (Rot8.DirectionFromCells(prevCell, cellToCheck) != rot)
                                    //{
                                    //    Log.Message("Additional Cost");
                                    //    num17 += ChangeDirectionAdditionalCost;
                                    //}
                                    if (!flag12 && !waterPathing)
                                    {
                                        //Extra Terrain costs
                                        if (pawn.VehicleDef.properties.customTerrainCosts?.NotNullAndAny() ?? false)
                                        {
                                            TerrainDef currentTerrain = map.terrainGrid.TerrainAt(num15);
                                            if (pawn.VehicleDef.properties.customTerrainCosts.ContainsKey(currentTerrain))
                                            {
                                                int customCost = pawn.VehicleDef.properties.customTerrainCosts[currentTerrain];
                                                if (customCost < 0)
                                                {
                                                    goto EndPathing;
                                                }
                                                num17 += customCost;
                                            }
                                            else
                                            {
                                                num17 += vehicleArray[num15];
                                            }
                                        }
                                        else
                                        {
                                            num17 += vehicleArray[num15];
                                        }
                                        num17 += flag10 ? topGrid[num15].extraDraftedPerceivedPathCost : topGrid[num15].extraNonDraftedPerceivedPathCost;
                                    }
                                    if (byteGrid != null)
                                    {
                                        num17 += (byteGrid[num15] * 8);
                                    }
                                    //Allowed area cost?
                                    if (flag5 && MultithreadHelper.AnyVehicleBlockingPathAt(new IntVec3(num13, 0, num14), pawn, false, false, true) != null)
                                    {
                                        num17 += Cost_PawnCollision;
                                    }
                                    Building building2 = edificeGrid[num15];
                                    if (!(building2 is null))
                                    {
                                        //Building Costs Here
                                    }
                                    if (blueprintGrid[num15] != null)
                                    {
                                        List <Blueprint> list = new List <Blueprint>(blueprintGrid[num15]);
                                        if (!list.NullOrEmpty())
                                        {
                                            int num18 = 0;
                                            foreach (Blueprint bp in list)
                                            {
                                                num18 = Mathf.Max(num18, GetBlueprintCost(bp, pawn));
                                            }
                                            if (num18 == int.MaxValue)
                                            {
                                                goto EndPathing;
                                            }
                                            num17 += num18;
                                        }
                                    }

                                    int    num19  = num17 + calcGrid[num].knownCost;
                                    ushort status = calcGrid[num15].status;

                                    //if(pawn.Props.useFullHitboxPathing)
                                    //{
                                    //    foreach(IntVec3 fullRect in fullRectCells)
                                    //    {
                                    //        if(fullRect != cellToCheck)
                                    //        {
                                    //            num19 += calcGrid[cellIndices.CellToIndex(fullRect)].knownCost;
                                    //            Log.Message($"Cell: {fullRect} Cost: {num19}");
                                    //            if(postCalculatedCells.ContainsKey(fullRect))
                                    //            {
                                    //                postCalculatedCells[fullRect] = num19;
                                    //            }
                                    //            else
                                    //            {
                                    //                postCalculatedCells.Add(fullRect, num19);
                                    //            }
                                    //        }
                                    //    }
                                    //}

                                    //Only generate path costs for linear non-reverse pathing check
                                    if (report)
                                    {
                                        if (postCalculatedCells.ContainsKey(cellToCheck))
                                        {
                                            postCalculatedCells[cellToCheck] = num19;
                                        }
                                        else
                                        {
                                            postCalculatedCells.Add(cellToCheck, num19);
                                        }
                                    }

                                    if (waterPathing && !map.terrainGrid.TerrainAt(num15).IsWater)
                                    {
                                        num19 += 10000;
                                    }
                                    if (status == statusClosedValue || status == statusOpenValue)
                                    {
                                        int num20 = 0;
                                        if (status == statusClosedValue)
                                        {
                                            num20 = num9;
                                        }
                                        if (calcGrid[num15].knownCost <= num19 + num20)
                                        {
                                            goto EndPathing;
                                        }
                                    }
                                    if (flag9)
                                    {
                                        calcGrid[num15].heuristicCost = waterPathing ? Mathf.RoundToInt(regionCostCalculatorSea.GetPathCostFromDestToRegion(num15) *
                                                                                                        RegionheuristicWeighByNodesOpened.Evaluate(num4)) : Mathf.RoundToInt(regionCostCalculatorLand.GetPathCostFromDestToRegion(num15) *
                                                                                                                                                                             RegionheuristicWeighByNodesOpened.Evaluate(num4));
                                        if (calcGrid[num15].heuristicCost < 0)
                                        {
                                            Log.ErrorOnce(string.Concat(new object[]
                                            {
                                                "Heuristic cost overflow for vehicle ", pawn.ToStringSafe <Pawn>(),
                                                " pathing from ", start,
                                                " to ", dest, "."
                                            }), pawn.GetHashCode() ^ 193840009);
                                            calcGrid[num15].heuristicCost = 0;
                                        }
                                    }
                                    else if (status != statusClosedValue && status != statusOpenValue)
                                    {
                                        int dx    = Math.Abs(num13 - x);
                                        int dz    = Math.Abs(num14 - z);
                                        int num21 = GenMath.OctileDistance(dx, dz, num9, num10);
                                        calcGrid[num15].heuristicCost = Mathf.RoundToInt((float)num21 * num8);
                                    }
                                    int num22 = num19 + calcGrid[num15].heuristicCost;
                                    if (num22 < 0)
                                    {
                                        Log.ErrorOnce(string.Concat(new object[]
                                        {
                                            "Node cost overflow for ship ", pawn.ToStringSafe <Pawn>(),
                                            " pathing from ", start,
                                            " to ", dest, "."
                                        }), pawn.GetHashCode() ^ 87865822);
                                        num22 = 0;
                                    }
                                    calcGrid[num15].parentIndex  = num;
                                    calcGrid[num15].knownCost    = num19;
                                    calcGrid[num15].status       = statusOpenValue;
                                    calcGrid[num15].costNodeCost = num22;
                                    num4++;
                                    rot = Rot8.DirectionFromCells(prevCell, cellToCheck);
                                    openList.Push(new CostNode(num15, num22));
                                }
                            }
                        }
                        EndPathing :;
                    }
                    num3++;
                    calcGrid[num].status = statusClosedValue;
                    if (num4 >= num5 && flag7 && !flag9)
                    {
                        flag9 = true;
                        if (waterPathing)
                        {
                            regionCostCalculatorSea.Init(cellRect, traverseParms, num9, num10, byteGrid, allowedArea, flag10, disallowedCornerIndices);
                        }
                        else
                        {
                            regionCostCalculatorLand.Init(cellRect, traverseParms, num9, num10, byteGrid, allowedArea, flag10, disallowedCornerIndices);
                        }

                        InitStatusesAndPushStartNode(ref num, start);
                        num4 = 0;
                        num3 = 0;
                    }
                }
            }
            string text  = ((pawn is null) || pawn.CurJob is null) ? "null" : pawn.CurJob.ToString();
            string text2 = ((pawn is null) || pawn.Faction is null) ? "null" : pawn.Faction.ToString();

            if (report)
            {
                Log.Warning(string.Concat(new object[]
                {
                    "ship pawn: ", pawn, " pathing from ", start,
                    " to ", dest, " ran out of cells to process.\nJob:", text,
                    "\nFaction: ", text2,
                    "\niterations: ", iterations
                }));
            }
            DebugDrawRichData();
            return(PawnPath.NotFound, false);

Block_32:
            PawnPath result = PawnPath.NotFound;

            if (report)
            {
                result = FinalizedPath(num, flag9);
            }
            DebugDrawPathCost();
            return(result, true);

Block_33:
            Log.Warning(string.Concat(new object[]
            {
                "Ship ", pawn, " pathing from ", start,
                " to ", dest, " hit search limit of ", SearchLimit, " cells."
            }));
            DebugDrawRichData();
            return(PawnPath.NotFound, false);
        }
Exemplo n.º 5
0
        public bool CanReachShip(IntVec3 start, LocalTargetInfo dest, PathEndMode peMode, TraverseParms traverseParms)
        {
            if (working)
            {
                Log.ErrorOnce("Called CanReach() while working for Ships. This should never happen. Suppressing further errors.", 7312233);
                return(false);
            }
            if (!map.terrainGrid.TerrainAt(dest.Cell).IsWater)
            {
                return(false);
            }
            if (!(traverseParms.pawn is null))
            {
                if (!traverseParms.pawn.Spawned)
                {
                    return(false);
                }
                if (traverseParms.pawn.Map != map)
                {
                    Log.Error(string.Concat(new object[]
                    {
                        "Called CanReach() with a ship spawned not on this map. This means that we can't check its reachability here. Pawn's" +
                        "current map should have been used instead of this one. pawn=", traverseParms.pawn,
                        " pawn.Map=", traverseParms.pawn.Map,
                        " map=", map
                    }));
                    return(false);
                }
            }
            if (!dest.IsValid)
            {
                return(false);
            }
            if (dest.HasThing && dest.Thing.Map != map)
            {
                return(false);
            }
            if (!start.InBoundsShip(map) || !dest.Cell.InBoundsShip(map))
            {
                return(false);
            }
            if ((peMode == PathEndMode.OnCell || peMode == PathEndMode.Touch || peMode == PathEndMode.ClosestTouch) && traverseParms.mode != TraverseMode.NoPassClosedDoorsOrWater &&
                traverseParms.mode != TraverseMode.PassAllDestroyableThingsNotWater)
            {
                VehicleRoom room = VehicleRegionAndRoomQuery.RoomAtFast(start, map, RegionType.Set_Passable);
                if (!(room is null) && room == VehicleRegionAndRoomQuery.RoomAtFast(dest.Cell, map, RegionType.Set_Passable))
                {
                    return(true);
                }
            }
            if (traverseParms.mode == TraverseMode.PassAllDestroyableThings)
            {
                TraverseParms traverseParms2 = traverseParms;
                traverseParms.mode = TraverseMode.PassDoors;
                if (CanReachShip(start, dest, peMode, traverseParms2))
                {
                    return(true);
                }
            }
            dest    = (LocalTargetInfo)GenPathVehicles.ResolvePathMode(traverseParms.pawn, dest.ToTargetInfo(map), ref peMode);
            working = true;
            bool result;

            try
            {
                pathGrid      = map.GetCachedMapComponent <VehicleMapping>().VehiclePathGrid;
                regionGrid    = map.GetCachedMapComponent <VehicleMapping>().VehicleRegionGrid;
                reachedIndex += 1u;
                destRegions.Clear();
                if (peMode == PathEndMode.OnCell)
                {
                    VehicleRegion region = VehicleGridsUtility.GetRegion(dest.Cell, map, RegionType.Set_Passable);
                    if (!(region is null) && region.Allows(traverseParms, true))
                    {
                        destRegions.Add(region);
                    }
                }
                else if (peMode == PathEndMode.Touch)
                {
                    TouchPathEndModeUtilityVehicles.AddAllowedAdjacentRegions(dest, traverseParms, map, destRegions);
                }
                if (destRegions.Count == 0 && traverseParms.mode != TraverseMode.PassAllDestroyableThings && traverseParms.mode !=
                    TraverseMode.PassAllDestroyableThingsNotWater)
                {
                    FinalizeCheck();
                    result = false;
                }
                else
                {
                    destRegions.RemoveDuplicates();
                    openQueue.Clear();
                    numRegionsOpened = 0;
                    DetermineStartRegions(start);
                    if (openQueue.Count == 0 && traverseParms.mode != TraverseMode.PassAllDestroyableThings && traverseParms.mode !=
                        TraverseMode.PassAllDestroyableThingsNotWater)
                    {
                        FinalizeCheck();
                        result = false;
                    }
                    else
                    {
                        if (startingRegions.Any() && destRegions.Any() && CanUseCache(traverseParms.mode))
                        {
                            BoolUnknown cachedResult = GetCachedResult(traverseParms);
                            if (cachedResult == BoolUnknown.True)
                            {
                                FinalizeCheck();
                                return(true);
                            }
                            if (cachedResult == BoolUnknown.False)
                            {
                                FinalizeCheck();
                                return(false);
                            }
                        }
                        if (traverseParms.mode == TraverseMode.PassAllDestroyableThings || traverseParms.mode == TraverseMode.PassAllDestroyableThingsNotWater ||
                            traverseParms.mode == TraverseMode.NoPassClosedDoorsOrWater)
                        {
                            bool flag = CheckCellBasedReachability(start, dest, peMode, traverseParms);
                            FinalizeCheck();
                            result = flag;
                        }
                        else
                        {
                            bool flag2 = CheckRegionBasedReachability(traverseParms);
                            //bool flag2 = CheckCellBasedReachability(start, dest, peMode, traverseParms); //REDO?
                            FinalizeCheck();
                            result = flag2;
                        }
                    }
                }
            }
            finally
            {
                working = false;
            }
            return(result);
        }
Exemplo n.º 6
0
        private bool CheckCellBasedReachability(IntVec3 start, LocalTargetInfo dest, PathEndMode peMode, TraverseParms traverseParms)
        {
            IntVec3 foundCell = IntVec3.Invalid;

            VehicleRegion[] directionRegionGrid = regionGrid.DirectGrid;
            VehiclePathGrid pathGrid            = map.GetCachedMapComponent <VehicleMapping>().VehiclePathGrid;
            CellIndices     cellIndices         = map.cellIndices;

            map.floodFiller.FloodFill(start, delegate(IntVec3 c)
            {
                int num = cellIndices.CellToIndex(c);
                if ((traverseParms.mode == TraverseMode.PassAllDestroyableThingsNotWater || traverseParms.mode == TraverseMode.NoPassClosedDoorsOrWater) &&
                    c.GetTerrain(map).IsWater)
                {
                    return(false);
                }
                if (traverseParms.mode == TraverseMode.PassAllDestroyableThings || traverseParms.mode == TraverseMode.PassAllDestroyableThingsNotWater)
                {
                    if (!pathGrid.WalkableFast(num))
                    {
                        Building edifice = c.GetEdifice(map);
                        if (edifice is null || !VehiclePathFinder.IsDestroyable(edifice))
                        {
                            return(false);
                        }
                    }
                }
                else if (traverseParms.mode != TraverseMode.NoPassClosedDoorsOrWater)
                {
                    Log.ErrorOnce("Do not use this method for non-cell based modes!", 938476762);
                    if (!pathGrid.WalkableFast(num))
                    {
                        return(false);
                    }
                }
                VehicleRegion region = directionRegionGrid[num];
                return(region is null || region.Allows(traverseParms, false));
            }, delegate(IntVec3 c)
            {
                if (VehicleReachabilityImmediate.CanReachImmediateShip(c, dest, map, peMode, traverseParms.pawn))
                {
                    foundCell = c;
                    return(true);
                }
                return(false);
            }, int.MaxValue, false, null);

            if (foundCell.IsValid)
            {
                if (CanUseCache(traverseParms.mode))
                {
                    VehicleRegion validRegionAt = regionGrid.GetValidRegionAt(foundCell);
                    if (!(validRegionAt is null))
                    {
                        foreach (VehicleRegion startRegion in startingRegions)
                        {
                            cache.AddCachedResult(startRegion.Room, validRegionAt.Room, traverseParms, true);
                        }
                    }
                }
                return(true);
            }
            if (CanUseCache(traverseParms.mode))
            {
                foreach (VehicleRegion startRegion in startingRegions)
                {
                    foreach (VehicleRegion destRegion in destRegions)
                    {
                        cache.AddCachedResult(startRegion.Room, destRegion.Room, traverseParms, false);
                    }
                }
            }
            return(false);
        }