Beispiel #1
0
        public static void GetTouchableRegions(Thing thing, Map map, List <WaterRegion> outRegions, bool allowAdjacenttEvenIfCantTouch = false)
        {
            outRegions.Clear();
            CellRect cellRect  = thing.OccupiedRect();
            CellRect cellRect2 = cellRect;

            if (WaterRegionListersUpdater.CanRegisterInAdjacentRegions(thing))
            {
                cellRect2 = cellRect2.ExpandedBy(1);
            }
            CellRect.CellRectIterator iterator = cellRect2.GetIterator();
            while (!iterator.Done())
            {
                IntVec3 intVec = iterator.Current;
                if (intVec.InBoundsShip(map))
                {
                    WaterRegion validRegionAt_NoRebuild = MapExtensionUtility.GetExtensionToMap(map).getWaterRegionGrid.GetValidRegionAt_NoRebuild(intVec);
                    if (!(validRegionAt_NoRebuild is null) && validRegionAt_NoRebuild.type.Passable() && !outRegions.Contains(validRegionAt_NoRebuild))
                    {
                        if (cellRect.Contains(intVec))
                        {
                            outRegions.Add(validRegionAt_NoRebuild);
                        }
                        else if (allowAdjacenttEvenIfCantTouch || ShipReachabilityImmediate.CanReachImmediateShip(intVec, thing, map, PathEndMode.Touch, null))
                        {
                            outRegions.Add(validRegionAt_NoRebuild);
                        }
                    }
                }
                iterator.MoveNext();
            }
        }
Beispiel #2
0
        public void RemoveRegion(WaterRegion r)
        {
            if (!this.regions.Contains(r))
            {
                Log.Error(string.Concat(new object[]
                {
                    "Tried to remove region from Room but this region is not here. region=",
                    r,
                    ", room=",
                    this
                }), false);
                return;
            }
            this.regions.Remove(r);
            if (r.touchesMapEdge)
            {
                this.numRegionsTouchingMapEdge--;
            }
            if (this.regions.Count == 0)
            {
                //this.Group = null;

                /*this.cachedOpenRoofCount = -1;
                *  this.cachedOpenRoofState = null;
                *  this.statsAndRoleDirty = true;*/
                MapExtensionUtility.GetExtensionToMap(this.Map).getWaterRegionGrid.allRooms.Remove(this);
            }
        }
Beispiel #3
0
        //FloodAndSetRooms

        //FloodAndSetNewRegionIndex

        public static bool WithinRegions(this IntVec3 A, IntVec3 B, Map map, int regionLookCount, TraverseParms traverseParams, RegionType traversableRegionTypes = RegionType.Set_Passable)
        {
            WaterRegion region = WaterGridsUtility.GetRegion(A, map, traversableRegionTypes);

            if (region is null)
            {
                return(false);
            }
            WaterRegion regB = WaterGridsUtility.GetRegion(B, map, traversableRegionTypes);

            if (regB is null)
            {
                return(false);
            }
            if (region == regB)
            {
                return(true);
            }
            WaterRegionEntryPredicate entryCondition = (WaterRegion from, WaterRegion r) => r.Allows(traverseParams, false);
            bool found = false;
            WaterRegionProcessor regionProcessor = delegate(WaterRegion r)
            {
                if (r == regB)
                {
                    found = true;
                    return(true);
                }
                return(false);
            };

            WaterRegionTraverser.BreadthFirstTraverse(region, entryCondition, regionProcessor, regionLookCount, traversableRegionTypes);
            return(found);
        }
Beispiel #4
0
        public WaterRegion TryGenerateRegionFrom(IntVec3 root)
        {
            RegionType expectedRegionType = WaterRegionTypeUtility.GetExpectedRegionType(root, this.map);

            if (expectedRegionType == RegionType.None)
            {
                return(null);
            }
            if (this.working)
            {
                Log.Error("Trying to generate a new water region but we are currently generating one. Nested calls are not allowed.", false);
                return(null);
            }
            this.working = true;
            WaterRegion result;

            try
            {
                this.regionGrid  = MapExtensionUtility.GetExtensionToMap(this.map).getWaterRegionGrid;
                this.newReg      = WaterRegion.MakeNewUnfilled(root, this.map);
                this.newReg.type = expectedRegionType;
                //Portal type?
                this.FloodFillAndAddCells(root);
                this.CreateLinks();
                this.RegisterThingsInRegionListers();
                result = this.newReg;
            }
            finally
            {
                this.working = false;
            }
            return(result);
        }
Beispiel #5
0
 public static void BreadthFirstTraverse(WaterRegion root, WaterRegionEntryPredicate entryCondition, WaterRegionProcessor regionProcessor, int maxRegions = 999999, RegionType traversableRegionTypes = RegionType.Set_Passable)
 {
     if (WaterRegionTraverser.freeWorkers.Count == 0)
     {
         Log.Error("No free workers for BFS. Either BFS recurred deeper than " + WaterRegionTraverser.NumWorkers + ", or a bug has put this system in an inconsistent state. Resetting.", false);
         return;
     }
     if (root is null)
     {
         Log.Error("BFS with null root region.", false);
         return;
     }
     WaterRegionTraverser.BFSWorker bfsworker = WaterRegionTraverser.freeWorkers.Dequeue();
     try
     {
         bfsworker.BreadthFirstTraverseWork(root, entryCondition, regionProcessor, maxRegions, traversableRegionTypes);
     }
     catch (Exception ex)
     {
         Log.Error("Exception in BreadthFirstTraverse: " + ex.ToString(), false);
     }
     finally
     {
         bfsworker.Clear();
         WaterRegionTraverser.freeWorkers.Enqueue(bfsworker);
     }
 }
Beispiel #6
0
 public static void MarkRegionsBFS(WaterRegion root, WaterRegionEntryPredicate entryCondition, int maxRegions, int inRadiusMark, RegionType traversableRegionTypes = RegionType.Set_Passable)
 {
     WaterRegionTraverser.BreadthFirstTraverse(root, entryCondition, delegate(WaterRegion r)
     {
         r.mark = inRadiusMark;
         return(false);
     }, maxRegions, traversableRegionTypes);
 }
Beispiel #7
0
 private void QueueNewOpenRegion(WaterRegion region)
 {
     if (region.closedIndex[this.closedArrayPos] == this.closedIndex)
     {
         throw new InvalidOperationException("Region is already closed; you can't open it. Region: " + region.ToString());
     }
     this.open.Enqueue(region);
     region.closedIndex[this.closedArrayPos] = this.closedIndex;
 }
Beispiel #8
0
        public bool Allows(TraverseParms tp, bool isDestination)
        {
            if (tp.mode != TraverseMode.PassAllDestroyableThings && tp.mode != TraverseMode.PassAllDestroyableThingsNotWater && !this.type.Passable())
            {
                return(false);
            }
            if (tp.maxDanger < Danger.Deadly && tp.pawn != null)
            {
                Danger danger = this.DangerFor(tp.pawn);
                if (isDestination || danger == Danger.Deadly)
                {
                    WaterRegion region = WaterRegionAndRoomQuery.GetRegion(tp.pawn, RegionType.Set_All);
                    if ((region == null || danger > region.DangerFor(tp.pawn)) && danger > tp.maxDanger)
                    {
                        return(false);
                    }
                }
            }
            switch (tp.mode)
            {
            case TraverseMode.ByPawn:
            {
                if (this.door == null)
                {
                    return(true);
                }
                ByteGrid avoidGrid = tp.pawn.GetAvoidGrid(true);
                if (avoidGrid != null && avoidGrid[this.door.Position] == 255)
                {
                    return(false);
                }
                if (tp.pawn.HostileTo(this.door))
                {
                    return(this.door.CanPhysicallyPass(tp.pawn) || tp.canBash);
                }
                return(this.door.CanPhysicallyPass(tp.pawn) && !this.door.IsForbiddenToPass(tp.pawn));
            }

            case TraverseMode.PassDoors:
                return(true);

            case TraverseMode.NoPassClosedDoors:
                return(this.door == null || this.door.FreePassage);

            case TraverseMode.PassAllDestroyableThings:
                return(true);

            case TraverseMode.NoPassClosedDoorsOrWater:
                return(this.door == null || this.door.FreePassage);

            case TraverseMode.PassAllDestroyableThingsNotWater:
                return(true);

            default:
                throw new NotImplementedException();
            }
        }
        public static WaterRegion RegionAt(IntVec3 c, Map map, RegionType allowedRegionTypes = RegionType.Set_Passable)
        {
            if (!c.InBoundsShip(map))
            {
                return(null);
            }
            WaterRegion validRegionAt = MapExtensionUtility.GetExtensionToMap(map).getWaterRegionGrid.GetValidRegionAt(c);

            return(!(validRegionAt is null) && (validRegionAt.type & allowedRegionTypes) != RegionType.None ? validRegionAt : null);
        }
        //GetRoomGroup

        public static WaterRoom RoomAtFast(IntVec3 c, Map map, RegionType allowedRegionTypes = RegionType.Set_Passable)
        {
            WaterRegion validRegionAt = MapExtensionUtility.GetExtensionToMap(map)?.getWaterRegionGrid?.GetValidRegionAt(c);

            if (!(validRegionAt is null) && (validRegionAt.type & allowedRegionTypes) != RegionType.None)
            {
                return(validRegionAt.Room);
            }
            return(null);
        }
Beispiel #11
0
        public WaterRegion GetValidRegionAt_NoRebuild(IntVec3 c)
        {
            if (!c.InBoundsShip(this.map))
            {
                Log.Error("Tried to get valid region out of bounds at " + c, false);
            }
            WaterRegion region = this.regionGrid[this.map.cellIndices.CellToIndex(c)];

            return(!(region is null) && region.valid ? region : null);
        }
Beispiel #12
0
        public static void BreadthFirstTraverse(IntVec3 start, Map map, WaterRegionEntryPredicate entryCondition, WaterRegionProcessor regionProcessor, int maxRegions = 999999, RegionType traversableRegionTypes = RegionType.Set_Passable)
        {
            WaterRegion region = WaterGridsUtility.GetRegion(start, map, traversableRegionTypes);

            if (region is null)
            {
                return;
            }
            WaterRegionTraverser.BreadthFirstTraverse(region, entryCondition, regionProcessor, maxRegions, traversableRegionTypes);
        }
Beispiel #13
0
        public override bool Equals(object obj)
        {
            if (obj is null)
            {
                return(false);
            }

            WaterRegion region = obj as WaterRegion;

            return(!(region is null) && region.id == this.id);
        }
Beispiel #14
0
        public WaterRegion GetValidRegionAt(IntVec3 c)
        {
            if (!c.InBoundsShip(this.map))
            {
                Log.Error("Tried to get valid water region out of bounds at " + c, false);
            }
            if (!MapExtensionUtility.GetExtensionToMap(this.map).getWaterRegionAndRoomUpdater.Enabled&& MapExtensionUtility.GetExtensionToMap(this.map).getWaterRegionAndRoomUpdater.AnythingToRebuild)
            {
                Log.Warning("Trying to get valid water region at " + c + " but RegionAndRoomUpdater is disabled. The result may be incorrect.", false);
            }
            MapExtensionUtility.GetExtensionToMap(this.map).getWaterRegionAndRoomUpdater.TryRebuildWaterRegions();
            WaterRegion region = this.regionGrid[this.map.cellIndices.CellToIndex(c)];

            return(!(region is null) && region.valid ? region : null);
        }
Beispiel #15
0
 public void Register(WaterRegion reg)
 {
     if (this.regions[0] == reg || this.regions[1] == reg)
     {
         Log.Error(string.Concat(new object[]
         {
             "Tried to double-register water region ",
             reg.ToString(), " in ", this
         }), false);
         return;
     }
     if (this.RegionA is null || !this.RegionA.valid)
     {
         this.RegionA = reg;
     }
Beispiel #16
0
 public void UpdateClean()
 {
     for (int i = 0; i < 16; i++)
     {
         if (this.curCleanIndex >= this.regionGrid.Length)
         {
             this.curCleanIndex = 0;
         }
         WaterRegion region = this.regionGrid[this.curCleanIndex];
         if (!(region is null) && !region.valid)
         {
             this.regionGrid[this.curCleanIndex] = null;
         }
         this.curCleanIndex++;
     }
 }
Beispiel #17
0
 public void BreadthFirstTraverseWork(WaterRegion root, WaterRegionEntryPredicate entryCondition, WaterRegionProcessor regionProcessor, int maxRegions, RegionType traversableRegionTypes)
 {
     if ((root.type & traversableRegionTypes) == RegionType.None)
     {
         return;
     }
     this.closedIndex += 1u;
     this.open.Clear();
     this.numRegionsProcessed = 0;
     this.QueueNewOpenRegion(root);
     while (this.open.Count > 0)
     {
         WaterRegion region = this.open.Dequeue();
         if (ShipHarmony.debug)
         {
             region.Debug_Notify_Traversed();
         }
         if (!(regionProcessor is null) && regionProcessor(region))
         {
             this.FinalizeSearch();
             return;
         }
         if (WaterRegionTraverser.ShouldCountRegion(region))
         {
             this.numRegionsProcessed++;
         }
         if (this.numRegionsProcessed >= maxRegions)
         {
             this.FinalizeSearch();
             return;
         }
         for (int i = 0; i < region.links.Count; i++)
         {
             WaterRegionLink regionLink = region.links[i];
             for (int j = 0; j < 2; j++)
             {
                 WaterRegion region2 = regionLink.regions[j];
                 if (!(region2 is null) && region2.closedIndex[this.closedArrayPos] != this.closedIndex && (region2.type & traversableRegionTypes) != RegionType.None &&
                     (entryCondition is null || entryCondition(region, region2)))
                 {
                     this.QueueNewOpenRegion(region2);
                 }
             }
         }
     }
     this.FinalizeSearch();
 }
Beispiel #18
0
        private void RegenerateNewWaterRegions()
        {
            this.newRegions.Clear();
            List <IntVec3> cells = this.map.regionDirtyer.DirtyCells;

            foreach (IntVec3 c  in cells)
            {
                if (WaterGridsUtility.GetRegion(c, this.map, RegionType.Set_All) is null)
                {
                    WaterRegion region = MapExtensionUtility.GetExtensionToMap(map).getWaterRegionmaker.TryGenerateRegionFrom(c);
                    if (!(region is null))
                    {
                        this.newRegions.Add(region);
                    }
                }
            }
        }
Beispiel #19
0
 public void TryRegenerateRegionFrom(WaterRegion region, IntVec3 root)
 {
     if (this.working)
     {
         Log.Error("Trying to regenerate a current water region but we are currently generating one. Nested calls are not allowed.", false);
         return;
     }
     this.working = true;
     try
     {
         this.FloodFillAndAddCells(root);
         this.CreateLinks();
         this.RegisterThingsInRegionListers();
     }
     finally
     {
         this.working = false;
     }
 }
        public static bool TryFindRandomReachableCellNear(IntVec3 root, Map map, float radius, TraverseParms traverseParms, Predicate <IntVec3> validator, out IntVec3 result,
                                                          Predicate <WaterRegion> regionValidator, int maxRegions = 999999)
        {
            if (map is null)
            {
                Log.ErrorOnce("Tried to find reachable cell using SPExtended in a null map", 61037855, false);
                result = IntVec3.Invalid;
                return(false);
            }
            WaterRegion region = WaterGridsUtility.GetRegion(root, map, RegionType.Set_Passable);

            if (region is null)
            {
                result = IntVec3.Invalid;
                return(false);
            }
            result = CellFinderExtended.RandomEdgeCell(Find.World.CoastDirectionAt(map.Tile), map, (IntVec3 c) => GenGridShips.Standable(c, map, MapExtensionUtility.GetExtensionToMap(map)) && !c.Fogged(map));
            return(true);
        }
Beispiel #21
0
        public static WaterRegion MakeNewUnfilled(IntVec3 root, Map map)
        {
            WaterRegion region = new WaterRegion();

            region.debug_makeTick = Find.TickManager.TicksGame;
            region.id             = WaterRegion.nextId;
            WaterRegion.nextId++;
            region.mapIndex = (sbyte)map.Index;
            region.precalculatedHashCode = Gen.HashCombineInt(region.id, 1295813358);
            region.extentsClose.minX     = root.x;
            region.extentsClose.maxX     = root.x;
            region.extentsClose.minZ     = root.z;
            region.extentsClose.maxZ     = root.z;
            region.extentsLimit.minX     = root.x - root.x % GridSize;
            region.extentsLimit.maxX     = root.x + GridSize - (root.x + GridSize) % GridSize - 1;
            region.extentsLimit.minZ     = root.z - root.z % GridSize;
            region.extentsLimit.maxZ     = root.z + GridSize - (root.z + GridSize) % GridSize - 1;
            region.extentsLimit.ClipInsideMap(map);
            return(region);
        }
Beispiel #22
0
 public void AddRegion(WaterRegion r)
 {
     if (this.regions.Contains(r))
     {
         Log.Error(string.Concat(new object[]
         {
             "Tried to add the same region twice to Room. region=",
             r,
             ", room=",
             this
         }), false);
         return;
     }
     this.regions.Add(r);
     if (r.touchesMapEdge)
     {
         this.numRegionsTouchingMapEdge++;
     }
     if (this.regions.Count == 1)
     {
         MapExtensionUtility.GetExtensionToMap(this.Map).getWaterRegionGrid.allRooms.Add(this);
     }
 }
Beispiel #23
0
        public void DebugDraw()
        {
            if (this.map != Find.CurrentMap)
            {
                return;
            }

            //Region Traversal
            if (ShipHarmony.debug)
            {
                CellRect currentViewRect = Find.CameraDriver.CurrentViewRect;
                currentViewRect.ClipInsideMap(this.map);
                foreach (IntVec3 c in currentViewRect)
                {
                    WaterRegion validRegionAt = this.GetValidRegionAt(c);
                    if (!(validRegionAt is null) && !this.drawnRegions.Contains(validRegionAt))
                    {
                        validRegionAt.DebugDraw();
                        this.drawnRegions.Add(validRegionAt);
                    }
                }
                this.drawnRegions.Clear();
            }
            IntVec3 intVec = Verse.UI.MouseCell();

            if (intVec.InBoundsShip(this.map))
            {
                //Room?
                //Room Group?
                WaterRegion regionAt_NoRebuild_InvalidAllowed = this.GetRegionAt_NoRebuild_InvalidAllowed(intVec);
                if (!(regionAt_NoRebuild_InvalidAllowed is null))
                {
                    regionAt_NoRebuild_InvalidAllowed.DebugDrawMouseover();
                }
            }
        }
        public static bool TryFindRandomCellInWaterRegion(this WaterRegion reg, Predicate <IntVec3> validator, out IntVec3 result)
        {
            for (int i = 0; i < 10; i++)
            {
                result = reg.RandomCell;
                if (validator is null || validator(result))
                {
                    return(true);
                }
            }
            List <IntVec3> workingCells = new List <IntVec3>(reg.Cells);

            workingCells.Shuffle <IntVec3>();
            foreach (IntVec3 c in workingCells)
            {
                result = c;
                if (validator is null || validator(result))
                {
                    return(true);
                }
            }
            result = reg.RandomCell;
            return(false);
        }
Beispiel #25
0
 public void SetRegionAt(IntVec3 c, WaterRegion reg)
 {
     this.regionGrid[this.map.cellIndices.CellToIndex(c)] = reg;
 }
        public static WaterRoom RoomAt(IntVec3 c, Map map, RegionType allowedRegionTypes = RegionType.Set_Passable)
        {
            WaterRegion region = WaterRegionAndRoomQuery.RegionAt(c, map, allowedRegionTypes);

            return(region is null ? null : region.Room);
        }
Beispiel #27
0
 public static bool ShouldCountRegion(WaterRegion r)
 {
     return(!r.IsDoorway);
 }