Esempio n. 1
0
        public static void BreadthFirstTraverse(VehicleRegion root, WaterRegionEntryPredicate entryCondition, WaterRegionProcessor regionProcessor, int maxRegions = 999999, RegionType traversableRegionTypes = RegionType.Set_Passable)
        {
            if (freeWorkers.Count == 0)
            {
                Log.Error("No free workers for BFS. Either BFS recurred deeper than " + NumWorkers + ", or a bug has put this system in an inconsistent state. Resetting.");
                return;
            }
            if (root is null)
            {
                Log.Error("BFS with null root region.");
                return;
            }
            BFSWorker bfsworker = freeWorkers.Dequeue();

            try
            {
                bfsworker.BreadthFirstTraverseWork(root, entryCondition, regionProcessor, maxRegions, traversableRegionTypes);
            }
            catch (Exception ex)
            {
                Log.Error("Exception in BreadthFirstTraverse: " + ex.ToString());
            }
            finally
            {
                bfsworker.Clear();
                freeWorkers.Enqueue(bfsworker);
            }
        }
Esempio n. 2
0
        //FloodAndSetRooms

        //FloodAndSetNewRegionIndex

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

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

            if (regB is null)
            {
                return(false);
            }
            if (region == regB)
            {
                return(true);
            }
            bool entryCondition(VehicleRegion from, VehicleRegion r) => r.Allows(traverseParams, false);

            bool found = false;

            bool regionProcessor(VehicleRegion r)
            {
                if (r == regB)
                {
                    found = true;
                    return(true);
                }
                return(false);
            }

            BreadthFirstTraverse(region, entryCondition, regionProcessor, regionLookCount, traversableRegionTypes);
            return(found);
        }
Esempio n. 3
0
 internal void Notify_WalkabilityChanged(IntVec3 c)
 {
     regionsToDirty.Clear();
     for (int i = 0; i < 9; i++)
     {
         IntVec3 c2 = c + GenAdj.AdjacentCellsAndInside[i];
         if (c2.InBounds(map))
         {
             VehicleRegion regionAt_NoRebuild_InvalidAllowed = map.GetCachedMapComponent <VehicleMapping>().VehicleRegionGrid.GetRegionAt_NoRebuild_InvalidAllowed(c2);
             if (regionAt_NoRebuild_InvalidAllowed != null && regionAt_NoRebuild_InvalidAllowed.valid)
             {
                 regionsToDirty.Add(regionAt_NoRebuild_InvalidAllowed);
             }
         }
     }
     for (int j = 0; j < regionsToDirty.Count; j++)
     {
         SetRegionDirty(regionsToDirty[j], true);
     }
     regionsToDirty.Clear();
     if (c.Walkable(map) && !dirtyCells.Contains(c))
     {
         dirtyCells.Add(c);
     }
 }
Esempio n. 4
0
 private void SetRegionDirty(VehicleRegion reg, bool addCellsToDirtyCells = true)
 {
     if (!reg.valid)
     {
         return;
     }
     reg.valid = false;
     reg.Room  = null;
     for (int i = 0; i < reg.links.Count; i++)
     {
         reg.links[i].Deregister(reg);
     }
     reg.links.Clear();
     if (addCellsToDirtyCells)
     {
         foreach (IntVec3 intVec in reg.Cells)
         {
             dirtyCells.Add(intVec);
             if (DebugViewSettings.drawRegionDirties)
             {
                 map.debugDrawer.FlashCell(intVec, 0f, null, 50);
             }
         }
     }
 }
Esempio n. 5
0
        public VehicleRegion TryGenerateRegionFrom(IntVec3 root)
        {
            RegionType expectedRegionType = WaterRegionTypeUtility.GetExpectedRegionType(root, this.map);

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

            try
            {
                regionGrid  = map.GetCachedMapComponent <VehicleMapping>().VehicleRegionGrid;
                newReg      = VehicleRegion.MakeNewUnfilled(root, map);
                newReg.type = expectedRegionType;
                //Add portal type?
                FloodFillAndAddCells(root);
                CreateLinks();
                RegisterThingsInRegionListers();
                result = newReg;
            }
            finally
            {
                working = false;
            }
            return(result);
        }
Esempio n. 6
0
        public static VehicleRoom FloodAndSetRooms(VehicleRegion root, Map map, VehicleRoom existingRoom)
        {
            VehicleRoom floodingRoom;

            if (existingRoom == null)
            {
                floodingRoom = VehicleRoom.MakeNew(map);
            }
            else
            {
                floodingRoom = existingRoom;
            }
            root.Room = floodingRoom;
            if (!root.type.AllowsMultipleRegionsPerRoom())
            {
                return(floodingRoom);
            }
            bool entryCondition(VehicleRegion from, VehicleRegion r) => r.type == root.type && r.Room != floodingRoom;

            bool regionProcessor(VehicleRegion r)
            {
                r.Room = floodingRoom;
                return(false);
            }

            BreadthFirstTraverse(root, entryCondition, regionProcessor, 999999, RegionType.Set_All);
            return(floodingRoom);
        }
Esempio n. 7
0
        public static void GetTouchableRegions(Thing thing, Map map, List <VehicleRegion> outRegions, bool allowAdjacenttEvenIfCantTouch = false)
        {
            outRegions.Clear();
            CellRect cellRect  = thing.OccupiedRect();
            CellRect cellRect2 = cellRect;

            if (CanRegisterInAdjacentRegions(thing))
            {
                cellRect2 = cellRect2.ExpandedBy(1);
            }
            foreach (IntVec3 intVec in cellRect2)
            {
                if (intVec.InBoundsShip(map))
                {
                    VehicleRegion validRegionAt_NoRebuild = map.GetCachedMapComponent <VehicleMapping>().VehicleRegionGrid.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 || VehicleReachabilityImmediate.CanReachImmediateShip(intVec, thing, map, PathEndMode.Touch, null))
                        {
                            outRegions.Add(validRegionAt_NoRebuild);
                        }
                    }
                }
            }
        }
Esempio n. 8
0
 public static void MarkRegionsBFS(VehicleRegion root, WaterRegionEntryPredicate entryCondition, int maxRegions, int inRadiusMark, RegionType traversableRegionTypes = RegionType.Set_Passable)
 {
     BreadthFirstTraverse(root, entryCondition, delegate(VehicleRegion r)
     {
         r.mark = inRadiusMark;
         return(false);
     }, maxRegions, traversableRegionTypes);
 }
Esempio n. 9
0
        public bool Allows(TraverseParms tp, bool isDestination)
        {
            if (tp.mode != TraverseMode.PassAllDestroyableThings && tp.mode != TraverseMode.PassAllDestroyableThingsNotWater && !type.Passable())
            {
                return(false);
            }
            if (tp.maxDanger < Danger.Deadly && tp.pawn != null)
            {
                Danger danger = DangerFor(tp.pawn);
                if (isDestination || danger == Danger.Deadly)
                {
                    VehicleRegion region = VehicleRegionAndRoomQuery.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 (door == null)
                {
                    return(true);
                }
                ByteGrid avoidGrid = tp.pawn.GetAvoidGrid(true);
                if (avoidGrid != null && avoidGrid[door.Position] == 255)
                {
                    return(false);
                }
                if (tp.pawn.HostileTo(door))
                {
                    return(door.CanPhysicallyPass(tp.pawn) || tp.canBash);
                }
                return(door.CanPhysicallyPass(tp.pawn) && !door.IsForbiddenToPass(tp.pawn));
            }

            case TraverseMode.PassDoors:
                return(true);

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

            case TraverseMode.PassAllDestroyableThings:
                return(true);

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

            case TraverseMode.PassAllDestroyableThingsNotWater:
                return(true);

            default:
                throw new NotImplementedException();
            }
        }
Esempio n. 10
0
 private void QueueNewOpenRegion(VehicleRegion region)
 {
     if (region.closedIndex[closedArrayPos] == closedIndex)
     {
         throw new InvalidOperationException("Region is already closed; you can't open it. Region: " + region.ToString());
     }
     open.Enqueue(region);
     region.closedIndex[closedArrayPos] = closedIndex;
 }
        public static VehicleRegion RegionAt(IntVec3 c, Map map, RegionType allowedRegionTypes = RegionType.Set_Passable)
        {
            if (!c.InBoundsShip(map))
            {
                return(null);
            }
            VehicleRegion validRegionAt = map.GetCachedMapComponent <VehicleMapping>().VehicleRegionGrid.GetValidRegionAt(c);

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

        public static VehicleRoom RoomAtFast(IntVec3 c, Map map, RegionType allowedRegionTypes = RegionType.Set_Passable)
        {
            VehicleRegion validRegionAt = map.GetCachedMapComponent <VehicleMapping>()?.VehicleRegionGrid?.GetValidRegionAt(c);

            if (!(validRegionAt is null) && (validRegionAt.type & allowedRegionTypes) != RegionType.None)
            {
                return(validRegionAt.Room);
            }
            return(null);
        }
Esempio n. 13
0
        public static void BreadthFirstTraverse(IntVec3 start, Map map, WaterRegionEntryPredicate entryCondition, WaterRegionProcessor regionProcessor, int maxRegions = 999999, RegionType traversableRegionTypes = RegionType.Set_Passable)
        {
            VehicleRegion region = VehicleGridsUtility.GetRegion(start, map, traversableRegionTypes);

            if (region is null)
            {
                return;
            }
            BreadthFirstTraverse(region, entryCondition, regionProcessor, maxRegions, traversableRegionTypes);
        }
Esempio n. 14
0
        public VehicleRegion GetValidRegionAt_NoRebuild(IntVec3 c)
        {
            if (!c.InBoundsShip(map))
            {
                Log.Error("Tried to get valid region out of bounds at " + c);
            }
            VehicleRegion region = regionGrid[map.cellIndices.CellToIndex(c)];

            return(!(region is null) && region.valid ? region : null);
        }
Esempio n. 15
0
        public VehicleRegion GetValidRegionAt(IntVec3 c)
        {
            if (!c.InBoundsShip(map))
            {
                Log.Error("Tried to get valid water region out of bounds at " + c);
            }
            if (!map.GetCachedMapComponent <VehicleMapping>().VehicleRegionAndRoomUpdater.Enabled&& map.GetCachedMapComponent <VehicleMapping>().VehicleRegionAndRoomUpdater.AnythingToRebuild)
            {
                Log.Warning("Trying to get valid water region at " + c + " but RegionAndRoomUpdater is disabled. The result may be incorrect.");
            }
            map.GetCachedMapComponent <VehicleMapping>().VehicleRegionAndRoomUpdater.TryRebuildWaterRegions();
            VehicleRegion region = regionGrid[map.cellIndices.CellToIndex(c)];

            return(!(region is null) && region.valid ? region : null);
        }
Esempio n. 16
0
 public void Register(VehicleRegion reg)
 {
     if (regions[0] == reg || regions[1] == reg)
     {
         Log.Error(string.Concat(new object[]
         {
             "Tried to double-register water region ",
             reg.ToString(), " in ", this
         }));
         return;
     }
     if (RegionA is null || !RegionA.valid)
     {
         RegionA = reg;
     }
Esempio n. 17
0
 public void UpdateClean()
 {
     for (int i = 0; i < CleanSquaresPerFrame; i++)
     {
         if (curCleanIndex >= regionGrid.Length)
         {
             curCleanIndex = 0;
         }
         VehicleRegion region = regionGrid[curCleanIndex];
         if (!(region is null) && !region.valid)
         {
             regionGrid[curCleanIndex] = null;
         }
         curCleanIndex++;
     }
 }
Esempio n. 18
0
 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();
 }
Esempio n. 19
0
 internal void Notify_ThingAffectingRegionsSpawned(Thing b)
 {
     regionsToDirty.Clear();
     foreach (IntVec3 c in b.OccupiedRect().ExpandedBy(1).ClipInsideMap(b.Map))
     {
         VehicleRegion validRegionAt_NoRebuild = b.Map.GetCachedMapComponent <VehicleMapping>().VehicleRegionGrid.GetValidRegionAt_NoRebuild(c);
         if (validRegionAt_NoRebuild != null)
         {
             regionsToDirty.Add(validRegionAt_NoRebuild);
         }
     }
     for (int i = 0; i < regionsToDirty.Count; i++)
     {
         SetRegionDirty(regionsToDirty[i], true);
     }
     regionsToDirty.Clear();
 }
Esempio n. 20
0
        public static void FloodAndSetNewRegionIndex(VehicleRegion root, int newRegionGroupIndex)
        {
            root.newRegionGroupIndex = newRegionGroupIndex;
            if (!root.type.AllowsMultipleRegionsPerRoom())
            {
                return;
            }
            bool entryCondition(VehicleRegion from, VehicleRegion r) => r.type == root.type && r.newRegionGroupIndex < 0;

            bool regionProcessor(VehicleRegion r)
            {
                r.newRegionGroupIndex = newRegionGroupIndex;
                return(false);
            }

            BreadthFirstTraverse(root, entryCondition, regionProcessor, 999999, RegionType.Set_All);
        }
        private void RegenerateNewWaterRegions()
        {
            newRegions.Clear();
            List <IntVec3> cells = map.GetCachedMapComponent <VehicleMapping>().VehicleRegionDirtyer.DirtyCells;

            foreach (IntVec3 c  in cells)
            {
                if (VehicleGridsUtility.GetRegion(c, map, RegionType.Set_All) is null)
                {
                    VehicleRegion region = map.GetCachedMapComponent <VehicleMapping>().VehicleRegionMaker.TryGenerateRegionFrom(c);

                    if (!(region is null))
                    {
                        newRegions.Add(region);
                    }
                }
            }
        }
Esempio n. 22
0
 public void TryRegenerateRegionFrom(VehicleRegion region, IntVec3 root)
 {
     if (working)
     {
         Log.Error("Trying to regenerate a current water region but we are currently generating one. Nested calls are not allowed.");
         return;
     }
     working = true;
     try
     {
         FloodFillAndAddCells(root);
         CreateLinks();
         RegisterThingsInRegionListers();
     }
     finally
     {
         working = false;
     }
 }
Esempio n. 23
0
        public static VehicleRegion MakeNewUnfilled(IntVec3 root, Map map)
        {
            VehicleRegion region = new VehicleRegion();

            region.debug_makeTick = Find.TickManager.TicksGame;
            region.id             = nextId;
            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);
        }
Esempio n. 24
0
        internal void Notify_ThingAffectingRegionsDespawned(Thing b)
        {
            regionsToDirty.Clear();
            VehicleRegion validRegionAt_NoRebuild = map.GetCachedMapComponent <VehicleMapping>().VehicleRegionGrid.GetValidRegionAt_NoRebuild(b.Position);

            if (validRegionAt_NoRebuild != null)
            {
                regionsToDirty.Add(validRegionAt_NoRebuild);
            }
            foreach (IntVec3 c in GenAdj.CellsAdjacent8Way(b))
            {
                if (c.InBounds(map))
                {
                    VehicleRegion validRegionAt_NoRebuild2 = map.GetCachedMapComponent <VehicleMapping>().VehicleRegionGrid.GetValidRegionAt_NoRebuild(c);
                    if (validRegionAt_NoRebuild2 != null)
                    {
                        regionsToDirty.Add(validRegionAt_NoRebuild2);
                    }
                }
            }
            for (int i = 0; i < regionsToDirty.Count; i++)
            {
                SetRegionDirty(regionsToDirty[i], true);
            }
            regionsToDirty.Clear();
            if (b.def.size.x == 1 && b.def.size.z == 1)
            {
                dirtyCells.Add(b.Position);
                return;
            }
            CellRect cellRect = b.OccupiedRect();

            for (int j = cellRect.minZ; j <= cellRect.maxZ; j++)
            {
                for (int k = cellRect.minX; k <= cellRect.maxX; k++)
                {
                    IntVec3 item = new IntVec3(k, 0, j);
                    dirtyCells.Add(item);
                }
            }
        }
Esempio n. 25
0
        public static bool TryFindRandomReachableCellNear(IntVec3 root, Map map, float radius, TraverseParms traverseParms, Predicate <IntVec3> validator, Predicate <VehicleRegion> regionValidator, out IntVec3 result,
                                                          int maxRegions = 999999)
        {
            if (map is null)
            {
                Log.ErrorOnce("Tried to find reachable cell using SPExtended in a null map", 61037855);
                result = IntVec3.Invalid;
                return(false);
            }
            VehicleRegion region = VehicleGridsUtility.GetRegion(root, map, RegionType.Set_Passable);

            if (region is null)
            {
                result = IntVec3.Invalid;
                return(false);
            }
            Rot4 dir = Find.World.CoastDirectionAt(map.Tile).IsValid ? Find.World.CoastDirectionAt(map.Tile) : !Find.WorldGrid[map.Tile].Rivers.NullOrEmpty() ? Ext_Map.RiverDirection(map) : Rot4.Invalid;

            result = RandomEdgeCell(dir, map, (IntVec3 c) => GenGridVehicles.Standable(c, map) && !c.Fogged(map), 0);
            return(true);
        }
Esempio n. 26
0
 public void AddRegion(VehicleRegion region)
 {
     if (Regions.Contains(region))
     {
         Log.Error(string.Concat(new object[]
         {
             "Tried to add the same region twice to Room. region=",
             region,
             ", room=",
             this
         }));
         return;
     }
     Regions.Add(region);
     if (region.touchesMapEdge)
     {
         numRegionsTouchingMapEdge++;
     }
     if (Regions.Count == 1)
     {
         Map.GetCachedMapComponent <VehicleMapping>().VehicleRegionGrid.allRooms.Add(this);
     }
 }
Esempio n. 27
0
 public void RemoveRegion(VehicleRegion r)
 {
     if (!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
         }));
         return;
     }
     Regions.Remove(r);
     if (r.touchesMapEdge)
     {
         numRegionsTouchingMapEdge--;
     }
     if (Regions.Count == 0)
     {
         Map.GetCachedMapComponent <VehicleMapping>().VehicleRegionGrid.allRooms.Remove(this);
     }
 }
Esempio n. 28
0
        public void DebugDraw()
        {
            if (map != Find.CurrentMap)
            {
                return;
            }

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

            if (intVec.InBoundsShip(map))
            {
                //Room?
                //Room Group?
                VehicleRegion regionAt_NoRebuild_InvalidAllowed = GetRegionAt_NoRebuild_InvalidAllowed(intVec);
                if (!(regionAt_NoRebuild_InvalidAllowed is null))
                {
                    regionAt_NoRebuild_InvalidAllowed.DebugDrawMouseover();
                }
            }
        }
Esempio n. 29
0
        public static bool TryFindRandomCellInWaterRegion(this VehicleRegion 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);
        }
Esempio n. 30
0
 public static bool ShouldCountRegion(VehicleRegion r)
 {
     return(!r.IsDoorway);
 }