private List <int> PathableNeighborIndices(int index) { RegionCostCalculatorShips.tmpPathableNeighborIndices.Clear(); ShipPathGrid pathGrid = mapE.getShipPathGrid; int x = this.map.Size.x; bool flag = index % x > 0; bool flag2 = index % x < x - 1; bool flag3 = index >= x; bool flag4 = index / x < this.map.Size.z - 1; if (flag3 && pathGrid.WalkableFast(index - x)) { RegionCostCalculatorShips.tmpPathableNeighborIndices.Add(index - x); } if (flag2 && pathGrid.WalkableFast(index + 1)) { RegionCostCalculatorShips.tmpPathableNeighborIndices.Add(index + 1); } if (flag && pathGrid.WalkableFast(index - 1)) { RegionCostCalculatorShips.tmpPathableNeighborIndices.Add(index - 1); } if (flag4 && pathGrid.WalkableFast(index + x)) { RegionCostCalculatorShips.tmpPathableNeighborIndices.Add(index + x); } bool flag5 = !flag || ShipPathFinder.BlocksDiagonalMovement(index - 1, this.map, this.mapE); bool flag6 = !flag2 || ShipPathFinder.BlocksDiagonalMovement(index + 1, this.map, this.mapE); if (flag3 && !ShipPathFinder.BlocksDiagonalMovement(index - x, this.map, this.mapE)) { if (!flag6 && pathGrid.WalkableFast(index - x + 1)) { RegionCostCalculatorShips.tmpPathableNeighborIndices.Add(index - x + 1); } if (!flag5 && pathGrid.WalkableFast(index - x - 1)) { RegionCostCalculatorShips.tmpPathableNeighborIndices.Add(index - x - 1); } } if (flag4 && !ShipPathFinder.BlocksDiagonalMovement(index + x, this.map, this.mapE)) { if (!flag6 && pathGrid.WalkableFast(index + x + 1)) { RegionCostCalculatorShips.tmpPathableNeighborIndices.Add(index + x + 1); } if (!flag5 && pathGrid.WalkableFast(index + x - 1)) { RegionCostCalculatorShips.tmpPathableNeighborIndices.Add(index + x - 1); } } return(RegionCostCalculatorShips.tmpPathableNeighborIndices); }
private bool CheckCellBasedReachability(IntVec3 start, LocalTargetInfo dest, PathEndMode peMode, TraverseParms traverseParms) { IntVec3 foundCell = IntVec3.Invalid; WaterRegion[] directionRegionGrid = this.regionGrid.DirectGrid; ShipPathGrid pathGrid = mapExt.getShipPathGrid; CellIndices cellIndices = this.map.cellIndices; this.map.floodFiller.FloodFill(start, delegate(IntVec3 c) { int num = cellIndices.CellToIndex(c); if ((traverseParms.mode == TraverseMode.PassAllDestroyableThingsNotWater || traverseParms.mode == TraverseMode.NoPassClosedDoorsOrWater) && c.GetTerrain(this.map).IsWater) { return(false); } if (traverseParms.mode == TraverseMode.PassAllDestroyableThings || traverseParms.mode == TraverseMode.PassAllDestroyableThingsNotWater) { if (!pathGrid.WalkableFast(num)) { Building edifice = c.GetEdifice(this.map); if (edifice is null || !ShipPathFinder.IsDestroyable(edifice)) { return(false); } } } else if (traverseParms.mode != TraverseMode.NoPassClosedDoorsOrWater) { //Log.ErrorOnce("Do not use this method for non-cell based modes!", 938476762, false); if (!pathGrid.WalkableFast(num)) { return(false); } } WaterRegion region = directionRegionGrid[num]; return(region is null || region.Allows(traverseParms, false)); }, delegate(IntVec3 c) { if (ShipReachabilityImmediate.CanReachImmediateShip(c, dest, this.map, peMode, traverseParms.pawn)) { foundCell = c; return(true); } return(false); }, int.MaxValue, false, null); if (foundCell.IsValid) { if (this.CanUseCache(traverseParms.mode)) { WaterRegion validRegionAt = this.regionGrid.GetValidRegionAt(foundCell); if (!(validRegionAt is null)) { foreach (WaterRegion startRegion in this.startingRegions) { this.cache.AddCachedResult(startRegion.Room, validRegionAt.Room, traverseParms, true); } } } return(true); } if (this.CanUseCache(traverseParms.mode)) { foreach (WaterRegion startRegion in this.startingRegions) { foreach (WaterRegion destRegion in this.destRegions) { this.cache.AddCachedResult(startRegion.Room, destRegion.Room, traverseParms, false); } } } return(false); }
public int GetRegionDistance(WaterRegion region, out WaterRegionLink minLink) { if (this.regionMinLink.TryGetValue(region.id, out minLink)) { return(this.distances[minLink]); } while (this.queue.Count != 0) { RegionCostCalculatorShips.RegionLinkQueueEntry regionLinkQueueEntry = this.queue.Pop(); int num = this.distances[regionLinkQueueEntry.Link]; if (regionLinkQueueEntry.Cost == num) { WaterRegion otherRegion = regionLinkQueueEntry.Link.GetOtherRegion(regionLinkQueueEntry.From); if (!(otherRegion is null) && otherRegion.valid) { int num2 = 0; if (!(otherRegion.door is null)) { num2 = ShipPathFinder.GetBuildingCost(otherRegion.door, this.traverseParms, this.traverseParms.pawn); if (num2 == int.MaxValue) { continue; } num2 += this.OctileDistance(1, 0); } int minPathCost = this.RegionMedianPathCost(otherRegion); foreach (WaterRegionLink regionLink in otherRegion.links) { if (regionLink != regionLinkQueueEntry.Link && regionLink.GetOtherRegion(otherRegion).type.Passable()) { int num3 = (otherRegion.door is null) ? this.RegionLinkDistance(regionLinkQueueEntry.Link, regionLink, minPathCost) : num2; num3 = Math.Max(num3, 1); int num4 = num + num3; int estimatedPathCost = this.MinimumRegionLinkDistance(this.destinationCell, regionLink) + num4; int num5; if (this.distances.TryGetValue(regionLink, out num5)) { if (num4 < num5) { this.distances[regionLink] = num4; this.queue.Push(new RegionCostCalculatorShips.RegionLinkQueueEntry(otherRegion, regionLink, num4, estimatedPathCost)); } } else { this.distances.Add(regionLink, num4); this.queue.Push(new RegionCostCalculatorShips.RegionLinkQueueEntry(otherRegion, regionLink, num4, estimatedPathCost)); } } } if (!this.regionMinLink.ContainsKey(otherRegion.id)) { this.regionMinLink.Add(otherRegion.id, regionLinkQueueEntry.Link); if (otherRegion == region) { minLink = regionLinkQueueEntry.Link; return(regionLinkQueueEntry.Cost); } } } } } return(10000); }
private void DebugFlash(IntVec3 c, float colorPct, string str) { ShipPathFinder.DebugFlash(c, this.map, colorPct, str); }
public static bool BlocksDiagonalMovement(int x, int z, Map map, MapExtension mapE) { return(ShipPathFinder.BlocksDiagonalMovement(map.cellIndices.CellToIndex(x, z), map, mapE)); }
private bool BlocksDiagonalMovement(int index) { return(ShipPathFinder.BlocksDiagonalMovement(index, this.map, mapE)); }
private bool BlocksDiagonalMovement(int x, int z) { return(ShipPathFinder.BlocksDiagonalMovement(x, z, this.map, mapE)); }
public static int GetBuildingCost(Building b, TraverseParms traverseParms, Pawn pawn) { Building_Door building_Door = b as Building_Door; if (building_Door != null) { switch (traverseParms.mode) { case TraverseMode.ByPawn: if (!traverseParms.canBash && building_Door.IsForbiddenToPass(pawn)) { if (DebugViewSettings.drawPaths) { ShipPathFinder.DebugFlash(b.Position, b.Map, 0.77f, "forbid"); } return(int.MaxValue); } if (building_Door.PawnCanOpen(pawn) && !building_Door.FreePassage) { return(building_Door.TicksToOpenNow); } if (building_Door.CanPhysicallyPass(pawn)) { return(0); } if (traverseParms.canBash) { return(300); } if (DebugViewSettings.drawPaths) { ShipPathFinder.DebugFlash(b.Position, b.Map, 0.34f, "cant pass"); } return(int.MaxValue); case TraverseMode.PassDoors: if (pawn != null && building_Door.PawnCanOpen(pawn) && !building_Door.IsForbiddenToPass(pawn) && !building_Door.FreePassage) { return(building_Door.TicksToOpenNow); } if ((pawn != null && building_Door.CanPhysicallyPass(pawn)) || building_Door.FreePassage) { return(0); } return(150); case TraverseMode.NoPassClosedDoors: case TraverseMode.NoPassClosedDoorsOrWater: if (building_Door.FreePassage) { return(0); } return(int.MaxValue); case TraverseMode.PassAllDestroyableThings: case TraverseMode.PassAllDestroyableThingsNotWater: if (pawn != null && building_Door.PawnCanOpen(pawn) && !building_Door.IsForbiddenToPass(pawn) && !building_Door.FreePassage) { return(building_Door.TicksToOpenNow); } if ((pawn != null && building_Door.CanPhysicallyPass(pawn)) || building_Door.FreePassage) { return(0); } return(50 + (int)((float)building_Door.HitPoints * 0.2f)); } } else if (pawn != null) { return((int)b.PathFindCostFor(pawn)); } return(0); }