public static bool CanReachImmediateShip(IntVec3 start, LocalTargetInfo target, Map map, PathEndMode peMode, Pawn pawn) { if (!target.IsValid) { return(false); } target = (LocalTargetInfo)GenPathVehicles.ResolvePathMode(pawn, target.ToTargetInfo(map), ref peMode); if (target.HasThing) { Thing thing = target.Thing; if (!thing.Spawned) { if (!(pawn is null)) { if (pawn.carryTracker.innerContainer.Contains(thing)) { return(true); } if (pawn.inventory.innerContainer.Contains(thing)) { return(true); } if (pawn.apparel != null && pawn.apparel.Contains(thing)) { return(true); } if (pawn.equipment != null && pawn.equipment.Contains(thing)) { return(true); } } return(false); } if (thing.Map != map) { return(false); } } if (!target.HasThing || target.Thing.def.size.x == 1 && target.Thing.def.size.z == 1) { if (start == target.Cell) { return(true); } } else if (start.IsInside(target.Thing)) { return(true); } return(peMode == PathEndMode.Touch && TouchPathEndModeUtilityVehicles.IsAdjacentOrInsideAndAllowedToTouch(start, target, map)); }
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); }
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; } }