public VehicleRegionLink LinkFrom(EdgeSpan span) { ulong key = span.UniqueHashCode(); if (!links.TryGetValue(key, out VehicleRegionLink regionLink)) { regionLink = new VehicleRegionLink(); regionLink.span = span; links.Add(key, regionLink); } return(regionLink); }
public void BreadthFirstTraverseWork(VehicleRegion root, WaterRegionEntryPredicate entryCondition, WaterRegionProcessor regionProcessor, int maxRegions, RegionType traversableRegionTypes) { if ((root.type & traversableRegionTypes) == RegionType.None) { return; } closedIndex += 1u; open.Clear(); numRegionsProcessed = 0; QueueNewOpenRegion(root); while (open.Count > 0) { VehicleRegion region = open.Dequeue(); if (VehicleHarmony.debug) { region.Debug_Notify_Traversed(); } if (!(regionProcessor is null) && regionProcessor(region)) { FinalizeSearch(); return; } if (ShouldCountRegion(region)) { numRegionsProcessed++; } if (numRegionsProcessed >= maxRegions) { FinalizeSearch(); return; } for (int i = 0; i < region.links.Count; i++) { VehicleRegionLink regionLink = region.links[i]; for (int j = 0; j < 2; j++) { VehicleRegion region2 = regionLink.regions[j]; if (!(region2 is null) && region2.closedIndex[closedArrayPos] != closedIndex && (region2.type & traversableRegionTypes) != RegionType.None && (entryCondition is null || entryCondition(region, region2))) { QueueNewOpenRegion(region2); } } } } FinalizeSearch(); }
public void Notify_LinkHasNoRegions(VehicleRegionLink link) { links.Remove(link.UniqueHashCode()); }
private void SweepInTwoDirectionsAndTryToCreateLink(Rot4 potentialOtherRegionDir, IntVec3 c) { if (!potentialOtherRegionDir.IsValid) { return; } HashSet <IntVec3> hashSet = linksProcessedAt[potentialOtherRegionDir.AsInt]; if (hashSet.Contains(c)) { return; } IntVec3 c2 = c + potentialOtherRegionDir.FacingCell; if (c2.InBoundsShip(map) && regionGrid.GetRegionAt_NoRebuild_InvalidAllowed(c2) == newReg) { return; } RegionType expectedRegionType = WaterRegionTypeUtility.GetExpectedRegionType(c2, map); if (expectedRegionType == RegionType.None) { return; } Rot4 rot = potentialOtherRegionDir; rot.Rotate(RotationDirection.Clockwise); int num = 0; int num2 = 0; hashSet.Add(c); if (!WaterRegionTypeUtility.IsOneCellRegion(expectedRegionType)) { for (;;) { IntVec3 intVec = c + rot.FacingCell * (num + 1); if (!intVec.InBoundsShip(map) || regionGrid.GetRegionAt_NoRebuild_InvalidAllowed(intVec) != newReg || WaterRegionTypeUtility.GetExpectedRegionType(intVec + potentialOtherRegionDir.FacingCell, map) != expectedRegionType) { break; } if (!hashSet.Add(intVec)) { Log.Error("We've processed the same cell twice."); } num++; } for (; ;) { IntVec3 intVec2 = c - rot.FacingCell * (num2 + 1); if (!intVec2.InBoundsShip(map) || regionGrid.GetRegionAt_NoRebuild_InvalidAllowed(intVec2) != newReg || WaterRegionTypeUtility.GetExpectedRegionType(intVec2 + potentialOtherRegionDir.FacingCell, map) != expectedRegionType) { break; } if (!hashSet.Add(intVec2)) { Log.Error("We've processed the same cell twice."); } num2++; } } int length = num + num2 + 1; SpanDirection dir; IntVec3 root; if (potentialOtherRegionDir == Rot4.North) { dir = SpanDirection.East; root = c - rot.FacingCell * num2; root.z++; } else if (potentialOtherRegionDir == Rot4.South) { dir = SpanDirection.East; root = c + rot.FacingCell * num; } else if (potentialOtherRegionDir == Rot4.East) { dir = SpanDirection.North; root = c + rot.FacingCell * num; root.x++; } else { dir = SpanDirection.North; root = c - rot.FacingCell * num2; } EdgeSpan span = new EdgeSpan(root, dir, length); VehicleRegionLink regionLink = map.GetCachedMapComponent <VehicleMapping>().VehicleRegionLinkDatabase.LinkFrom(span); regionLink.Register(newReg); newReg.links.Add(regionLink); }