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); }
public void StartPath(LocalTargetInfo dest, PathEndMode peMode) { if (!pawn.Drafted) { PatherFailed(); return; } if (pawn.IsBoat()) { dest = (LocalTargetInfo)GenPathVehicles.ResolvePathMode(pawn, dest.ToTargetInfo(pawn.Map), ref peMode); if (dest.HasThing && dest.ThingDestroyed) { Log.Error(pawn + " pathing to destroyed thing " + dest.Thing); PatherFailed(); return; } //Add Building and Position Recoverable extras if (!GenGridVehicles.Walkable(pawn.Position, pawn.Map.GetCachedMapComponent <VehicleMapping>())) { return; } if (Moving && curPath != null && destination == dest && this.peMode == peMode) { return; } if (!pawn.Map.GetCachedMapComponent <VehicleMapping>().VehicleReachability?.CanReachShip(pawn.Position, dest, peMode, TraverseParms.For(TraverseMode.PassDoors, Danger.Deadly, false)) ?? false) { PatherFailed(); return; } this.peMode = peMode; destination = dest; if ((GenGridVehicles.Walkable(nextCell, pawn.Map.GetCachedMapComponent <VehicleMapping>()) || WillCollideWithPawnOnNextPathCell()) || nextCellCostLeft == nextCellCostTotal) { ResetToCurrentPosition(); } PawnDestinationReservationManager.PawnDestinationReservation pawnDestinationReservation = pawn.Map.pawnDestinationReservationManager. MostRecentReservationFor(pawn); if (!(pawnDestinationReservation is null) && ((Destination.HasThing && pawnDestinationReservation.target != Destination.Cell) || (pawnDestinationReservation.job != pawn.CurJob && pawnDestinationReservation.target != Destination.Cell))) { pawn.Map.pawnDestinationReservationManager.ObsoleteAllClaimedBy(pawn); } if (VehicleReachabilityImmediate.CanReachImmediateShip(pawn, dest, peMode)) { PatherArrived(); return; } if (curPath != null) { curPath.ReleaseToPool(); } curPath = null; moving = true; pawn.jobs.posture = PawnPosture.Standing; return; } else { dest = (LocalTargetInfo)GenPath.ResolvePathMode(pawn, dest.ToTargetInfo(pawn.Map), ref peMode); if (dest.HasThing && dest.ThingDestroyed) { Log.Error(pawn + " pathing to destroyed thing " + dest.Thing); PatherFailed(); return; } if (!PawnCanOccupy(pawn.Position) && !TryRecoverFromUnwalkablePosition(true)) { return; } if (moving && curPath != null && destination == dest && this.peMode == peMode) { return; } if (!pawn.Map.reachability.CanReach(pawn.Position, dest, peMode, TraverseParms.For(TraverseMode.PassDoors, Danger.Deadly, false))) { PatherFailed(); return; } this.peMode = peMode; destination = dest; if (!IsNextCellWalkable() || NextCellDoorToWaitForOrManuallyOpen() != null || nextCellCostLeft == nextCellCostTotal) { ResetToCurrentPosition(); } PawnDestinationReservationManager.PawnDestinationReservation pawnDestinationReservation = pawn.Map.pawnDestinationReservationManager.MostRecentReservationFor(pawn); if (pawnDestinationReservation != null && ((destination.HasThing && pawnDestinationReservation.target != destination.Cell) || (pawnDestinationReservation.job != pawn.CurJob && pawnDestinationReservation.target != destination.Cell))) { pawn.Map.pawnDestinationReservationManager.ObsoleteAllClaimedBy(pawn); } if (AtDestinationPosition()) { PatherArrived(); return; } if (pawn.Downed) { Log.Error(pawn.LabelCap + " tried to path while downed. This should never happen. curJob=" + pawn.CurJob.ToStringSafe()); PatherFailed(); return; } if (curPath != null) { curPath.ReleaseToPool(); } curPath = null; moving = true; pawn.jobs.posture = PawnPosture.Standing; } }