示例#1
0
        public void setCellsToAffect()
        {
            if (this.status == "stable")
            {
                return;
            }
            IntVec3 pos = this.parent.Position;
            Map     map = this.parent.Map;

            this.affectableCells.Clear();
            this.boundaryCellsRough.Clear();
            this.boundaryCells.Clear();
            this.affectableCellsAtmosphere.Clear();
            if (!pos.InBounds(map))
            {
                return;
            }
            int maxArea = (int)Math.Round(this.width + this.Props.borderSize + 5);

            Region region = pos.GetRegion(map, RegionType.Set_Passable);

            if (region == null)
            {
                return;
            }
            RegionTraverser.BreadthFirstTraverse(region, (Region from, Region r) => r.door == null, delegate(Region r)
            {
                foreach (IntVec3 current in r.Cells)
                {
                    if (current.InHorDistOf(pos, this.width))
                    {
                        this.affectableCells.Add(current);
                    }
                    else if (current.InHorDistOf(pos, this.width + 2))
                    {
                        this.boundaryCellsRough.Add(current);
                    }
                    else if (current.InHorDistOf(pos, this.width + this.Props.borderSize + 1))
                    {
                        this.boundaryCells.Add(current);
                    }
                    else if (current.InHorDistOf(pos, this.width + this.Props.borderSize + 5))
                    {
                        this.affectableCellsAtmosphere.Add(current);
                    }
                }
                return(false);
            }, maxArea, RegionType.Set_Passable);
            return;
        }
示例#2
0
            // Copied with minor changes so we don't have to call a private function on the FoodUtility object
            private static Pawn BestPawnToHuntForPredator(Pawn predator, bool forceScanWholeMap)
            {
                if (predator.meleeVerbs.TryGetMeleeVerb(null) == null)
                {
                    return(null);
                }
                bool seriouslyWounded = (predator.health.summaryHealth.SummaryHealthPercent < 0.25f);

                tempPreyCandidates.Clear();
                if (GetMaxRegionsToScan(predator, forceScanWholeMap) < 0)
                {
                    tempPreyCandidates.AddRange(predator.Map.mapPawns.AllPawnsSpawned);
                }
                else
                {
                    TraverseParms traverseParms = TraverseParms.For(predator);
                    RegionTraverser.BreadthFirstTraverse(predator.Position, predator.Map, (Region from, Region to) => to.Allows(traverseParms, isDestination : true), delegate(Region x)
                    {
                        List <Thing> list = x.ListerThings.ThingsInGroup(ThingRequestGroup.Pawn);
                        for (int j = 0; j < list.Count; j++)
                        {
                            tempPreyCandidates.Add((Pawn)list[j]);
                        }
                        return(false);
                    });
                }

                Pawn  bestPrey      = null;
                float bestPreyScore = 0f;
                bool  tutorialMode  = TutorSystem.TutorialMode;

                foreach (Pawn potentialPrey in tempPreyCandidates)
                {
                    bool sameRoom       = predator.GetRoom() == potentialPrey.GetRoom();
                    bool acceptablePrey = IsAcceptablePreyFor(predator, potentialPrey);

                    if (predator != potentialPrey && sameRoom && (!seriouslyWounded || potentialPrey.Downed) && acceptablePrey && predator.CanReach(potentialPrey, PathEndMode.ClosestTouch, Danger.Deadly) && !potentialPrey.IsForbidden(predator) && (!tutorialMode || potentialPrey.Faction != Faction.OfPlayer))
                    {
                        float preyScoreFor = GetPreyScoreFor(predator, potentialPrey);

                        if (preyScoreFor > bestPreyScore || bestPrey == null)
                        {
                            bestPreyScore = preyScoreFor;
                            bestPrey      = potentialPrey;
                        }
                    }
                }
                tempPreyCandidates.Clear();
                return(bestPrey);
            }
示例#3
0
        public static bool ShouldStartFleeing(ref bool __result, Pawn pawn)
        {
            List <Thing> thingList1 = pawn.Map.listerThings.ThingsInGroup(ThingRequestGroup.AlwaysFlee);

            lock (thingList1)
            {
                for (int index = 0; index < thingList1.Count; ++index)
                {
                    Thing t = thingList1[index];
                    if (null != t)
                    {
                        if (SelfDefenseUtility.ShouldFleeFrom(t, pawn, true, false))
                        {
                            __result = true;
                            return(false);
                        }
                    }
                }
            }
            bool   foundThreat = false;
            Region region      = pawn.GetRegion(RegionType.Set_Passable);

            if (region == null)
            {
                __result = false;
                return(false);
            }
            RegionTraverser.BreadthFirstTraverse(region, (RegionEntryPredicate)((from, reg) => reg.door == null || reg.door.Open), (RegionProcessor)(reg =>
            {
                List <Thing> thingList2 = reg.ListerThings.ThingsInGroup(ThingRequestGroup.AttackTarget);
                lock (thingList2)
                {
                    for (int index = 0; index < thingList2.Count; ++index)
                    {
                        Thing t = thingList2[index];
                        if (null != t)
                        {
                            if (SelfDefenseUtility.ShouldFleeFrom(t, pawn, true, true))
                            {
                                foundThreat = true;
                                break;
                            }
                        }
                    }
                }
                return(foundThreat);
            }), 9, RegionType.Set_Passable);
            __result = foundThreat;
            return(false);
        }
示例#4
0
        public static void BreadthFirstTraverse(IntVec3 start, Map map2, RegionEntryPredicate entryCondition, RegionProcessor regionProcessor, int maxRegions = 999999, RegionType traversableRegionTypes = RegionType.Set_Passable)
        {
            Region region = start.GetRegion(map2, traversableRegionTypes);

            if (region == null)
            {
                return;
            }

            lock (region)
            {
                RegionTraverser.BreadthFirstTraverse(region, entryCondition, regionProcessor, maxRegions, traversableRegionTypes);
            }
        }
示例#5
0
        private static Pawn BestPawnToHuntForPredator(Pawn predator, bool forceScanWholeMap)
        {
            if (predator.meleeVerbs.TryGetMeleeVerb(null) == null)
            {
                return(null);
            }
            bool flag = false;

            if (predator.health.summaryHealth.SummaryHealthPercent < 0.25f)
            {
                flag = true;
            }
            tmpPredatorCandidates.Clear();
            if (GetMaxRegionsToScan(predator, forceScanWholeMap) < 0)
            {
                tmpPredatorCandidates.AddRange(predator.Map.mapPawns.AllPawnsSpawned);
            }
            else
            {
                TraverseParms traverseParms = TraverseParms.For(predator);
                RegionTraverser.BreadthFirstTraverse(predator.Position, predator.Map, (Region from, Region to) => to.Allows(traverseParms, isDestination : true), delegate(Region x)
                {
                    List <Thing> list = x.ListerThings.ThingsInGroup(ThingRequestGroup.Pawn);
                    for (int j = 0; j < list.Count; j++)
                    {
                        tmpPredatorCandidates.Add((Pawn)list[j]);
                    }
                    return(false);
                });
            }
            Pawn  pawn         = null;
            float num          = 0f;
            bool  tutorialMode = TutorSystem.TutorialMode;

            for (int i = 0; i < tmpPredatorCandidates.Count; i++)
            {
                Pawn pawn2 = tmpPredatorCandidates[i];
                if (predator.GetRoom() == pawn2.GetRoom() && predator != pawn2 && (!flag || pawn2.Downed) && IsAcceptablePreyFor(predator, pawn2) && predator.CanReach(pawn2, PathEndMode.ClosestTouch, Danger.Deadly) && !pawn2.IsForbidden(predator) && (!tutorialMode || pawn2.Faction != Faction.OfPlayer))
                {
                    float preyScoreFor = GetPreyScoreFor(predator, pawn2);
                    if (preyScoreFor > num || pawn == null)
                    {
                        num  = preyScoreFor;
                        pawn = pawn2;
                    }
                }
            }
            tmpPredatorCandidates.Clear();
            return(pawn);
        }
        private static void CreateOrAttachToExistingRooms2(RegionAndRoomUpdater __instance, int numRegionGroups)
        {
            for (int i = 0; i < numRegionGroups; i++)
            {
                currentRegionGroup(__instance).Clear();
                for (int j = 0; j < newRegions(__instance).Count; j++)
                {
                    if (newRegions(__instance)[j].newRegionGroupIndex == i)
                    {
                        currentRegionGroup(__instance).Add(newRegions(__instance)[j]);
                    }
                }

                if (!currentRegionGroup(__instance)[0].type.AllowsMultipleRegionsPerRoom())
                {
                    if (currentRegionGroup(__instance).Count != 1)
                    {
                        Log.Error("Region type doesn't allow multiple regions per room but there are >1 regions in this group.");
                    }

                    Room room = Room.MakeNew(map(__instance));
                    currentRegionGroup(__instance)[0].Room = room;
                    newRooms(__instance).Add(room);
                    continue;
                }

                bool multipleOldNeighborRooms;
                Room room2 = FindCurrentRegionGroupNeighborWithMostRegions2(__instance, out multipleOldNeighborRooms);
                if (room2 == null)
                {
                    Room item = RegionTraverser.FloodAndSetRooms(currentRegionGroup(__instance)[0], map(__instance), null);
                    newRooms(__instance).Add(item);
                }
                else if (!multipleOldNeighborRooms)
                {
                    for (int k = 0; k < currentRegionGroup(__instance).Count; k++)
                    {
                        currentRegionGroup(__instance)[k].Room = room2;
                    }

                    reusedOldRooms(__instance).Add(room2);
                }
                else
                {
                    RegionTraverser.FloodAndSetRooms(currentRegionGroup(__instance)[0], map(__instance), room2);
                    reusedOldRooms(__instance).Add(room2);
                }
            }
        }
示例#7
0
        private static List <Thing> FindAllFuel(Pawn pawn, Thing refuelable)
        {
            int                  quantity            = refuelable.TryGetComp <CompRefuelable>().GetFuelCountToFullyRefuel();
            ThingFilter          filter              = refuelable.TryGetComp <CompRefuelable>().Props.fuelFilter;
            Predicate <Thing>    validator           = (Thing x) => !x.IsForbidden(pawn) && pawn.CanReserve(x, 1, -1, null, false) && filter.Allows(x);
            IntVec3              position            = refuelable.Position;
            Region               region              = position.GetRegion(pawn.Map, RegionType.Set_Passable);
            TraverseParms        traverseParams      = TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false);
            RegionEntryPredicate entryCondition      = (Region from, Region r) => r.Allows(traverseParams, false);
            List <Thing>         chosenThings        = new List <Thing>();
            int                  accumulatedQuantity = 0;
            RegionProcessor      regionProcessor     = delegate(Region r)
            {
                List <Thing> list = r.ListerThings.ThingsMatching(ThingRequest.ForGroup(ThingRequestGroup.HaulableEver));
                for (int i = 0; i < list.Count; i++)
                {
                    Thing thing = list[i];
                    if (validator(thing))
                    {
                        if (!chosenThings.Contains(thing))
                        {
                            if (ReachabilityWithinRegion.ThingFromRegionListerReachable(thing, r, PathEndMode.ClosestTouch, pawn))
                            {
                                chosenThings.Add(thing);
                                accumulatedQuantity += thing.stackCount;
                                if (accumulatedQuantity >= quantity)
                                {
                                    return(true);
                                }
                            }
                        }
                    }
                }
                return(false);
            };

            RegionTraverser.BreadthFirstTraverse(region, entryCondition, regionProcessor, 99999, RegionType.Set_Passable);
            List <Thing> result;

            if (accumulatedQuantity >= quantity)
            {
                result = chosenThings;
            }
            else
            {
                result = null;
            }
            return(result);
        }
示例#8
0
 public static Lord FindLordToJoin(Thing spawner, Type lordJobType, bool shouldTryJoinParentLord, Func <Thing, List <Pawn> > spawnedPawnSelector = null)
 {
     if (spawner.Spawned)
     {
         if (shouldTryJoinParentLord)
         {
             Lord lord = (spawner as Building)?.GetLord();
             if (lord != null)
             {
                 return(lord);
             }
         }
         if (spawnedPawnSelector == null)
         {
             spawnedPawnSelector = ((Thing s) => s.TryGetComp <CompSpawnerPawn>()?.spawnedPawns);
         }
         Predicate <Pawn> hasJob = delegate(Pawn x)
         {
             Lord lord2 = x.GetLord();
             return(lord2 != null && lord2.LordJob.GetType() == lordJobType);
         };
         Pawn foundPawn = null;
         RegionTraverser.BreadthFirstTraverse(spawner.GetRegion(), (Region from, Region to) => true, delegate(Region r)
         {
             List <Thing> list = r.ListerThings.ThingsOfDef(spawner.def);
             for (int i = 0; i < list.Count; i++)
             {
                 if (list[i].Faction == spawner.Faction)
                 {
                     List <Pawn> list2 = spawnedPawnSelector(list[i]);
                     if (list2 != null)
                     {
                         foundPawn = list2.Find(hasJob);
                     }
                     if (foundPawn != null)
                     {
                         return(true);
                     }
                 }
             }
             return(false);
         }, 40);
         if (foundPawn != null)
         {
             return(foundPawn.GetLord());
         }
     }
     return(null);
 }
        private static int CombineNewRegionsIntoContiguousGroups2(RegionAndRoomUpdater __instance)
        {
            int num = 0;

            for (int i = 0; i < newRegions(__instance).Count; i++)
            {
                if (newRegions(__instance)[i].newRegionGroupIndex < 0)
                {
                    RegionTraverser.FloodAndSetNewRegionIndex(newRegions(__instance)[i], num);
                    num++;
                }
            }

            return(num);
        }
示例#10
0
        public override void StartExplosion(SoundDef explosionSound, List <Thing> ignoredThings)
        {
            if (!base.Spawned)
            {
                Log.Error("Called StartExplosion() on unspawned thing.");
                return;
            }
            startTick          = Find.TickManager.TicksGame;
            this.ignoredThings = ignoredThings;
            cellsToAffect.Clear();
            damagedThings.Clear();
            addedCellsAffectedOnlyByDamage.Clear();
            cellsToAffect.AddRange(damType.Worker.ExplosionCellsToHit(this));
            if (applyDamageToExplosionCellsNeighbors)
            {
                AddCellsNeighbors(cellsToAffect);
            }

            if (validator != null)
            {
                for (int i = 0; i < cellsToAffect.Count; i++)
                {
                    IntVec3 cell = cellsToAffect[i];

                    if (validator(cell))
                    {
                        cellsToAffect.Remove(cell);
                    }
                }
            }

            damType.Worker.ExplosionStart(this, cellsToAffect);
            PlayExplosionSound(explosionSound);
            MoteMaker.MakeWaterSplash(base.Position.ToVector3Shifted(), base.Map, radius * 6f, 20f);
            cellsToAffect.Sort((IntVec3 a, IntVec3 b) => GetCellAffectTick(b).CompareTo(GetCellAffectTick(a)));
            RegionTraverser.BreadthFirstTraverse(base.Position, base.Map, (Region from, Region to) => true, delegate(Region x)
            {
                List <Thing> allThings = x.ListerThings.AllThings;
                for (int num = allThings.Count - 1; num >= 0; num--)
                {
                    if (allThings[num].Spawned)
                    {
                        allThings[num].Notify_Explosion(this);
                    }
                }
                return(false);
            }, 25);
        }
示例#11
0
 static void HavePawnsFleeFromOrbitalStrikes(OrbitalStrike __instance)
 {
     if (__instance.Destroyed)
     {
         return;
     }
     RegionTraverser.BreadthFirstTraverse(__instance.Position, __instance.Map, (from, to) => true, region =>
     {
         region.ListerThings.ThingsInGroup(ThingRequestGroup.Pawn)
         .OfType <Pawn>()
         .Where(p => p.Position.DistanceTo(__instance.Position) <= 20)
         .Where(CanStartFleeingBecauseOfPawnAction)
         .Do(pawn => pawn.mindState.StartFleeingBecauseOfPawnAction(__instance));
         return(false);
     }, 25, RegionType.Set_All);
 }
示例#12
0
        public static bool StartExplosion(Explosion __instance, SoundDef explosionSound, List <Thing> ignoredThings)
        {
            Thing thing = __instance;

            if (!thing.Spawned)
            {
                Log.Error("Called StartExplosion() on unspawned thing.");
                return(false);
            }

            startTick(__instance)       = Find.TickManager.TicksGame;
            ignoredThingsFR(__instance) = ignoredThings;
            //List<IntVec3> cells = cellsToAffect(__instance);
            List <IntVec3> cells = getCellsToAffectFromDict(__instance);

            lock (cells)
            {
                cells.Clear();
                damagedThings(__instance).Clear();
                addedCellsAffectedOnlyByDamage(__instance).Clear();
                cells.AddRange(__instance.damType.Worker.ExplosionCellsToHit(__instance).ToList());
                if (__instance.applyDamageToExplosionCellsNeighbors)
                {
                    AddCellsNeighbors2(__instance, cells);
                }

                __instance.damType.Worker.ExplosionStart(__instance, cells);
                PlayExplosionSound2(__instance, explosionSound);
                MoteMaker.MakeWaterSplash(thing.Position.ToVector3Shifted(), thing.Map, __instance.radius * 6f, 20f);
                cells.Sort((IntVec3 a, IntVec3 b) => GetCellAffectTick2(__instance, b).CompareTo(GetCellAffectTick2(__instance, a)));
            }
            RegionTraverser.BreadthFirstTraverse(thing.Position, thing.Map, (Region from, Region to) => true, delegate(Region x)
            {
                List <Thing> allThings = x.ListerThings.AllThings;
                for (int num = allThings.Count - 1; num >= 0; num--)
                {
                    if (allThings[num].Spawned)
                    {
                        allThings[num].Notify_Explosion(__instance);
                    }
                }

                return(false);
            }, 25);

            return(false);
        }
        public bool CanReachMapEdge(IntVec3 c, TraverseParms traverseParms)
        {
            if (traverseParms.pawn != null)
            {
                if (!traverseParms.pawn.Spawned)
                {
                    return(false);
                }
                if (traverseParms.pawn.Map != this.map)
                {
                    Log.Error(string.Concat(new object[]
                    {
                        "Called CanReachMapEdge() with a pawn spawned not on this map. This means that we can't check his reachability here. Pawn's current map should have been used instead of this one. pawn=",
                        traverseParms.pawn,
                        " pawn.Map=",
                        traverseParms.pawn.Map,
                        " map=",
                        this.map
                    }));
                    return(false);
                }
            }
            Region region = c.GetRegion(this.map, RegionType.Set_Passable);

            if (region == null)
            {
                return(false);
            }
            if (region.Room.TouchesMapEdge)
            {
                return(true);
            }
            RegionEntryPredicate entryCondition = (Region from, Region r) => r.Allows(traverseParms, false);
            bool            foundReg            = false;
            RegionProcessor regionProcessor     = delegate(Region r)
            {
                if (r.Room.TouchesMapEdge)
                {
                    foundReg = true;
                    return(true);
                }
                return(false);
            };

            RegionTraverser.BreadthFirstTraverse(region, entryCondition, regionProcessor, 9999, RegionType.Set_Passable);
            return(foundReg);
        }
示例#14
0
        public static bool InDangerousCombat(Pawn pawn)
        {
            Region root  = pawn.GetRegion(RegionType.Set_Passable);
            bool   found = false;

            RegionTraverser.BreadthFirstTraverse(root, (Region r1, Region r2) => r2.Room == root.Room, (Region r) => r.ListerThings.ThingsInGroup(ThingRequestGroup.Pawn).Any(delegate(Thing t)
            {
                Pawn pawn2 = t as Pawn;
                if (pawn2 != null && !pawn2.Downed && (float)(pawn.Position - pawn2.Position).LengthHorizontalSquared < 144.0 && pawn2.HostileTo(pawn.Faction))
                {
                    found = true;
                    return(true);
                }
                return(false);
            }), 9, RegionType.Set_Passable);
            return(found);
        }
示例#15
0
        /// <summary>
        /// This method is a direct copy/paste of the <see cref="RefuelWorkGiverUtility"/> private FindAllFuel method.
        ///
        /// Finds all relevant ammo in order of distance.
        /// </summary>
        /// <param name="pawn"></param>
        /// <param name="reloadable"></param>
        /// <returns></returns>
        private static List <Thing> FindAllAmmo(Pawn pawn, Building_Turret reloadable)
        {
            var compAmmo = reloadable.GetAmmo();
            int quantity = compAmmo.MissingToFullMagazine;
            var ammoKind = compAmmo.SelectedAmmo;
            Predicate <Thing> validator = (Thing potentialAmmo) =>

            {
                if (potentialAmmo.IsForbidden(pawn) || !pawn.CanReserve(potentialAmmo))
                {
                    return(false);
                }
                return(GetPathCost(pawn, potentialAmmo) <= MaxPathCost);
            };
            Region        region         = reloadable.Position.GetRegion(pawn.Map);
            TraverseParms traverseParams = TraverseParms.For(pawn);

            Verse.RegionEntryPredicate entryCondition = (Region from, Region r) => r.Allows(traverseParams, isDestination: false);
            var chosenThings        = new List <Thing>();
            int accumulatedQuantity = 0;

            Verse.RegionProcessor regionProcessor = (Region r) =>

            {
                List <Thing> list = r.ListerThings.ThingsMatching(ThingRequest.ForDef(ammoKind));
                foreach (var thing in list)
                {
                    if (validator(thing) && !chosenThings.Contains(thing) && ReachabilityWithinRegion.ThingFromRegionListerReachable(thing, r, PathEndMode.ClosestTouch, pawn))
                    {
                        chosenThings.Add(thing);
                        accumulatedQuantity += thing.stackCount;
                        if (accumulatedQuantity >= quantity)
                        {
                            return(true);
                        }
                    }
                }
                return(false);
            };
            RegionTraverser.BreadthFirstTraverse(region, entryCondition, regionProcessor, 99999);
            if (accumulatedQuantity >= quantity)
            {
                return(chosenThings);
            }
            return(null);
        }
示例#16
0
        protected override Job TryGiveJob(Pawn pawn)
        {
            if (!pawn.Position.IsForbidden(pawn))
            {
                return(null);
            }
            if (this.HasJobWithSpawnedAllowedTarget(pawn))
            {
                return(null);
            }
            Region region = pawn.GetRegion(RegionType.Set_Passable);

            if (region == null)
            {
                return(null);
            }
            TraverseParms        traverseParms  = TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false);
            RegionEntryPredicate entryCondition = (Region from, Region r) => r.Allows(traverseParms, false);
            Region          reg             = null;
            RegionProcessor regionProcessor = delegate(Region r)
            {
                if (r.portal != null)
                {
                    return(false);
                }
                if (!r.IsForbiddenEntirely(pawn))
                {
                    reg = r;
                    return(true);
                }
                return(false);
            };

            RegionTraverser.BreadthFirstTraverse(region, entryCondition, regionProcessor, 9999, RegionType.Set_Passable);
            if (reg == null)
            {
                return(null);
            }
            IntVec3 c;

            if (!reg.TryFindRandomCellInRegionUnforbidden(pawn, null, out c))
            {
                return(null);
            }
            return(new Job(JobDefOf.Goto, c));
        }
        private Job FleeLargeFireJob(Pawn pawn)
        {
            List <Thing> list = pawn.Map.listerThings.ThingsInGroup(ThingRequestGroup.Fire);
            Job          result;

            if (list.Count < 60)
            {
                result = null;
            }
            else
            {
                TraverseParms tp            = TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false);
                Fire          closestFire   = null;
                float         closestDistSq = -1f;
                int           firesCount    = 0;
                RegionTraverser.BreadthFirstTraverse(pawn.Position, pawn.Map, (Region from, Region to) => to.Allows(tp, false), delegate(Region x)
                {
                    List <Thing> list2 = x.ListerThings.ThingsInGroup(ThingRequestGroup.Fire);
                    for (int i = 0; i < list2.Count; i++)
                    {
                        float num = (float)pawn.Position.DistanceToSquared(list2[i].Position);
                        if (num <= 400f)
                        {
                            if (closestFire == null || num < closestDistSq)
                            {
                                closestDistSq = num;
                                closestFire   = (Fire)list2[i];
                            }
                            firesCount++;
                        }
                    }
                    return(closestDistSq <= 100f && firesCount >= 60);
                }, 18, RegionType.Set_Passable);
                if (closestDistSq <= 100f && firesCount >= 60)
                {
                    Job job = this.FleeJob(pawn, closestFire);
                    if (job != null)
                    {
                        return(job);
                    }
                }
                result = null;
            }
            return(result);
        }
示例#18
0
 public static void NotifyFacilitiesAboutChangedLOSBlockers(List <Region> affectedRegions)
 {
     if (FacilitiesUtility.working)
     {
         Log.Warning("Tried to update facilities while already updating.");
     }
     else
     {
         FacilitiesUtility.working = true;
         try
         {
             FacilitiesUtility.visited.Clear();
             for (int i = 0; i < affectedRegions.Count; i++)
             {
                 if (!FacilitiesUtility.visited.Contains(affectedRegions[i]))
                 {
                     RegionTraverser.BreadthFirstTraverse(affectedRegions[i], (Region from, Region r) => !FacilitiesUtility.visited.Contains(r), delegate(Region x)
                     {
                         FacilitiesUtility.visited.Add(x);
                         List <Thing> list = x.ListerThings.ThingsInGroup(ThingRequestGroup.BuildingArtificial);
                         for (int j = 0; j < list.Count; j++)
                         {
                             CompFacility compFacility = list[j].TryGetComp <CompFacility>();
                             CompAffectedByFacilities compAffectedByFacilities = list[j].TryGetComp <CompAffectedByFacilities>();
                             if (compFacility != null)
                             {
                                 compFacility.Notify_LOSBlockerSpawnedOrDespawned();
                             }
                             if (compAffectedByFacilities != null)
                             {
                                 compAffectedByFacilities.Notify_LOSBlockerSpawnedOrDespawned();
                             }
                         }
                         return(false);
                     }, FacilitiesUtility.RegionsToSearch, RegionType.Set_Passable);
                 }
             }
         }
         finally
         {
             FacilitiesUtility.working = false;
             FacilitiesUtility.visited.Clear();
         }
     }
 }
        protected override Job TryGiveJob(Pawn pawn)
        {
            if (!pawn.Position.IsForbidden(pawn))
            {
                return(null);
            }
            if (HasJobWithSpawnedAllowedTarget(pawn))
            {
                return(null);
            }
            Region region = pawn.GetRegion();

            if (region == null)
            {
                return(null);
            }
            TraverseParms        traverseParms  = TraverseParms.For(pawn);
            RegionEntryPredicate entryCondition = (Region from, Region r) => r.Allows(traverseParms, isDestination: false);
            Region          reg             = null;
            RegionProcessor regionProcessor = delegate(Region r)
            {
                if (r.IsDoorway)
                {
                    return(false);
                }
                if (!r.IsForbiddenEntirely(pawn))
                {
                    reg = r;
                    return(true);
                }
                return(false);
            };

            RegionTraverser.BreadthFirstTraverse(region, entryCondition, regionProcessor, 9999);
            if (reg != null)
            {
                if (!reg.TryFindRandomCellInRegionUnforbidden(pawn, null, out IntVec3 result))
                {
                    return(null);
                }
                return(JobMaker.MakeJob(JobDefOf.Goto, result));
            }
            return(null);
        }
示例#20
0
        public static void GetSmashableThingsNear(Pawn pawn, IntVec3 near, List <Thing> outCandidates, Predicate <Thing> customValidator = null, int extraMinBuildingOrItemMarketValue = 0, int maxDistance = 40)
        {
            outCandidates.Clear();
            if (!pawn.CanReach(near, PathEndMode.OnCell, Danger.Deadly))
            {
                return;
            }
            Region region = near.GetRegion(pawn.Map);

            if (region == null)
            {
                return;
            }
            TraverseParms traverseParams = TraverseParms.For(pawn);

            RegionTraverser.BreadthFirstTraverse(region, (Region from, Region to) => to.Allows(traverseParams, isDestination : false), delegate(Region r)
            {
                List <Thing> list = r.ListerThings.ThingsInGroup(ThingRequestGroup.BuildingArtificial);
                for (int i = 0; i < list.Count; i++)
                {
                    if (list[i].Position.InHorDistOf(near, maxDistance) && CanSmash(pawn, list[i], skipReachabilityCheck: true, customValidator, extraMinBuildingOrItemMarketValue))
                    {
                        outCandidates.Add(list[i]);
                    }
                }
                List <Thing> list2 = r.ListerThings.ThingsInGroup(ThingRequestGroup.HaulableEver);
                for (int j = 0; j < list2.Count; j++)
                {
                    if (list2[j].Position.InHorDistOf(near, maxDistance) && CanSmash(pawn, list2[j], skipReachabilityCheck: true, customValidator, extraMinBuildingOrItemMarketValue))
                    {
                        outCandidates.Add(list2[j]);
                    }
                }
                List <Thing> list3 = r.ListerThings.ThingsInGroup(ThingRequestGroup.Pawn);
                for (int k = 0; k < list3.Count; k++)
                {
                    if (list3[k].Position.InHorDistOf(near, maxDistance) && CanSmash(pawn, list3[k], skipReachabilityCheck: true, customValidator, extraMinBuildingOrItemMarketValue))
                    {
                        outCandidates.Add(list3[k]);
                    }
                }
                return(false);
            }, 40);
        }
示例#21
0
        private static List <Thing> FindAllFuel(Pawn pawn, Thing refuelable)
        {
            int               quantity  = refuelable.TryGetComp <CompRefuelable>().GetFuelCountToFullyRefuel();
            ThingFilter       filter    = refuelable.TryGetComp <CompRefuelable>().Props.fuelFilter;
            Predicate <Thing> validator = delegate(Thing x)
            {
                if (x.IsForbidden(pawn) || !pawn.CanReserve(x))
                {
                    return(false);
                }
                return(filter.Allows(x) ? true : false);
            };
            Region               region         = refuelable.Position.GetRegion(pawn.Map);
            TraverseParms        traverseParams = TraverseParms.For(pawn);
            RegionEntryPredicate entryCondition = (Region from, Region r) => r.Allows(traverseParams, isDestination: false);
            List <Thing>         chosenThings   = new List <Thing>();
            int             accumulatedQuantity = 0;
            RegionProcessor regionProcessor     = delegate(Region r)
            {
                List <Thing> list = r.ListerThings.ThingsMatching(ThingRequest.ForGroup(ThingRequestGroup.HaulableEver));
                for (int i = 0; i < list.Count; i++)
                {
                    Thing thing = list[i];
                    if (validator(thing) && !chosenThings.Contains(thing) && ReachabilityWithinRegion.ThingFromRegionListerReachable(thing, r, PathEndMode.ClosestTouch, pawn))
                    {
                        chosenThings.Add(thing);
                        accumulatedQuantity += thing.stackCount;
                        if (accumulatedQuantity >= quantity)
                        {
                            return(true);
                        }
                    }
                }
                return(false);
            };

            RegionTraverser.BreadthFirstTraverse(region, entryCondition, regionProcessor, 99999);
            if (accumulatedQuantity >= quantity)
            {
                return(chosenThings);
            }
            return(null);
        }
        private static bool TryFindSpotToPlaceHaulableCloseTo(Thing haulable, Pawn worker, IntVec3 center, out IntVec3 spot)
        {
            Region region = center.GetRegion(worker.Map, RegionType.Set_Passable);
            bool   result;

            if (region == null)
            {
                spot   = center;
                result = false;
            }
            else
            {
                TraverseParms traverseParms = TraverseParms.For(worker, Danger.Deadly, TraverseMode.ByPawn, false);
                IntVec3       foundCell     = IntVec3.Invalid;
                RegionTraverser.BreadthFirstTraverse(region, (Region from, Region r) => r.Allows(traverseParms, false), delegate(Region r)
                {
                    HaulAIUtility.candidates.Clear();
                    HaulAIUtility.candidates.AddRange(r.Cells);
                    HaulAIUtility.candidates.Sort((IntVec3 a, IntVec3 b) => a.DistanceToSquared(center).CompareTo(b.DistanceToSquared(center)));
                    for (int i = 0; i < HaulAIUtility.candidates.Count; i++)
                    {
                        IntVec3 intVec = HaulAIUtility.candidates[i];
                        if (HaulAIUtility.HaulablePlaceValidator(haulable, worker, intVec))
                        {
                            foundCell = intVec;
                            return(true);
                        }
                    }
                    return(false);
                }, 100, RegionType.Set_Passable);
                if (foundCell.IsValid)
                {
                    spot   = foundCell;
                    result = true;
                }
                else
                {
                    spot   = center;
                    result = false;
                }
            }
            return(result);
        }
示例#23
0
        public static bool TryFindPrisonerReleaseCell(Pawn prisoner, Pawn warden, out IntVec3 result)
        {
            if (prisoner.Map != warden.Map)
            {
                result = IntVec3.Invalid;
                return(false);
            }
            Region region = prisoner.GetRegion();

            if (region == null)
            {
                result = default(IntVec3);
                return(false);
            }
            TraverseParms   traverseParms   = TraverseParms.For(warden);
            bool            needMapEdge     = prisoner.Faction != warden.Faction;
            IntVec3         foundResult     = IntVec3.Invalid;
            RegionProcessor regionProcessor = delegate(Region r)
            {
                if (needMapEdge)
                {
                    if (!r.Room.TouchesMapEdge)
                    {
                        return(false);
                    }
                }
                else if (r.Room.isPrisonCell)
                {
                    return(false);
                }
                foundResult = r.RandomCell;
                return(true);
            };

            RegionTraverser.BreadthFirstTraverse(region, (Region from, Region r) => r.Allows(traverseParms, isDestination: false), regionProcessor, 999);
            if (foundResult.IsValid)
            {
                result = foundResult;
                return(true);
            }
            result = default(IntVec3);
            return(false);
        }
        private bool SaturatedAt(IntVec3 c, float plantDensity, bool cavePlants, float wholeMapNumDesiredPlants)
        {
            int num = GenRadial.NumCellsInRadius(20f);

            if (wholeMapNumDesiredPlants * ((float)num / (float)map.Area) <= 4f || !map.Biome.wildPlantsCareAboutLocalFertility)
            {
                return((float)map.listerThings.ThingsInGroup(ThingRequestGroup.Plant).Count >= wholeMapNumDesiredPlants);
            }
            float numDesiredPlantsLocally = 0f;
            int   numPlants = 0;

            RegionTraverser.BreadthFirstTraverse(c, map, (Region from, Region to) => c.InHorDistOf(to.extentsClose.ClosestCellTo(c), 20f), delegate(Region reg)
            {
                numDesiredPlantsLocally += GetDesiredPlantsCountIn(reg, c, plantDensity);
                numPlants += reg.ListerThings.ThingsInGroup(ThingRequestGroup.Plant).Count;
                return(false);
            });
            return((float)numPlants >= numDesiredPlantsLocally);
        }
示例#25
0
        private static bool EnoughLowerOrderPlantsNearby2(WildPlantSpawner __instance, IntVec3 c, float plantDensity, float radiusToScan, ThingDef plantDef)
        {
            float num = 0f;
            //tmpPlantDefsLowerOrder.Clear();
            List <ThingDef> tmpPlantDefsLowerOrder = new List <ThingDef>();
            List <ThingDef> allWildPlants          = map(__instance).Biome.AllWildPlants;

            for (int i = 0; i < allWildPlants.Count; i++)
            {
                ThingDef wildPlant = allWildPlants[i];
                if (null != wildPlant)
                {
                    if (wildPlant.plant.wildOrder < plantDef.plant.wildOrder)
                    {
                        num += GetCommonalityPctOfPlant2(__instance, wildPlant);
                        tmpPlantDefsLowerOrder.Add(wildPlant);
                    }
                }
            }

            float numDesiredPlantsLocally = 0f;
            int   numPlantsLowerOrder     = 0;

            RegionTraverser.BreadthFirstTraverse(c, map(__instance), (Region from, Region to) => c.InHorDistOf(to.extentsClose.ClosestCellTo(c), radiusToScan), delegate(Region reg)
            {
                numDesiredPlantsLocally += GetDesiredPlantsCountIn2(map(__instance), reg, c, plantDensity);
                for (int j = 0; j < tmpPlantDefsLowerOrder.Count; j++)
                {
                    numPlantsLowerOrder += reg.ListerThings.ThingsOfDef(tmpPlantDefsLowerOrder[j]).Count;
                }

                return(false);
            });
            float num2 = numDesiredPlantsLocally * num;

            if (num2 < 4f)
            {
                return(true);
            }

            return((float)numPlantsLowerOrder / num2 >= 0.57f);
        }
示例#26
0
        public static void ClearAllMapsAndWorld()
        {
            if (Current.Game != null && Current.Game.Maps != null)
            {
                List <Map>  maps   = Find.Maps;
                FieldInfo[] fields = typeof(Map).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
                for (int i = 0; i < fields.Length; i++)
                {
                    if (fields[i].FieldType.IsClass)
                    {
                        for (int j = 0; j < maps.Count; j++)
                        {
                            fields[i].SetValue(maps[j], null);
                        }
                    }
                }
                maps.Clear();
                Current.Game.currentMapIndex = -1;
            }
            if (Find.World != null)
            {
                World       world   = Find.World;
                FieldInfo[] fields2 = typeof(World).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
                for (int k = 0; k < fields2.Length; k++)
                {
                    if (fields2[k].FieldType.IsClass)
                    {
                        fields2[k].SetValue(world, null);
                    }
                }
            }
            BillUtility.Clipboard = null;
            RegionTraverser.RecreateWorkers();
            SelectionDrawer.Clear();
            WorldSelectionDrawer.Clear();
            List <MainButtonDef> allDefsListForReading = DefDatabase <MainButtonDef> .AllDefsListForReading;

            for (int l = 0; l < allDefsListForReading.Count; l++)
            {
                allDefsListForReading[l].Notify_ClearingAllMapsMemory();
            }
        }
示例#27
0
        public static bool EnemiesAreNearby(Pawn pawn, int regionsToScan = 9, bool passDoors = false)
        {
            TraverseParms tp         = (!passDoors) ? TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false) : TraverseParms.For(TraverseMode.PassDoors, Danger.Deadly, false);
            bool          foundEnemy = false;

            RegionTraverser.BreadthFirstTraverse(pawn.Position, pawn.Map, (Region from, Region to) => to.Allows(tp, false), delegate(Region r)
            {
                List <Thing> list = r.ListerThings.ThingsInGroup(ThingRequestGroup.AttackTarget);
                for (int i = 0; i < list.Count; i++)
                {
                    if (list[i].HostileTo(pawn))
                    {
                        foundEnemy = true;
                        return(true);
                    }
                }
                return(foundEnemy);
            }, regionsToScan, RegionType.Set_Passable);
            return(foundEnemy);
        }
示例#28
0
    public static Region BrrrClosestRegionWithinTemperatureRange(IntVec3 root, Map map, FloatRange tempRange,
                                                                 TraverseParms traverseParms, RegionType traversableRegionTypes = RegionType.Set_Passable)
    {
        var region = root.GetRegion(map, traversableRegionTypes);

        if (region == null)
        {
            return(null);
        }

        bool entryCondition(Region from, Region r)
        {
            return(r.Allows(traverseParms, false));
        }

        Region foundReg = null;

        bool regionProcessor(Region r)
        {
            if (r.IsDoorway)
            {
                return(false);
            }

            if (!tempRange.Includes(r.Room.Temperature))
            {
                return(false);
            }

            if (!Settings.AllowUnsafeAreas && !r.Cells.Any(vec3 => vec3.InAllowedArea(traverseParms.pawn)))
            {
                return(false);
            }

            foundReg = r;
            return(true);
        }

        RegionTraverser.BreadthFirstTraverse(region, entryCondition, regionProcessor, 9999, traversableRegionTypes);
        return(foundReg);
    }
示例#29
0
        private Job FleeLargeFireJob(Pawn pawn)
        {
            List <Thing> list = pawn.Map.listerThings.ThingsInGroup(ThingRequestGroup.Fire);

            if (list.Count < 60)
            {
                return(null);
            }
            TraverseParms tp            = TraverseParms.For(pawn);
            Fire          closestFire   = null;
            float         closestDistSq = -1f;
            int           firesCount    = 0;

            RegionTraverser.BreadthFirstTraverse(pawn.Position, pawn.Map, (Region from, Region to) => to.Allows(tp, isDestination : false), delegate(Region x)
            {
                List <Thing> list2 = x.ListerThings.ThingsInGroup(ThingRequestGroup.Fire);
                for (int i = 0; i < list2.Count; i++)
                {
                    float num = (float)pawn.Position.DistanceToSquared(list2[i].Position);
                    if (!(num > 400f))
                    {
                        if (closestFire == null || num < closestDistSq)
                        {
                            closestDistSq = num;
                            closestFire   = (Fire)list2[i];
                        }
                        firesCount++;
                    }
                }
                return(closestDistSq <= 100f && firesCount >= 60);
            }, 18);
            if (closestDistSq <= 100f && firesCount >= 60)
            {
                Job job = FleeJob(pawn, closestFire);
                if (job != null)
                {
                    return(job);
                }
            }
            return(null);
        }
示例#30
0
 static void Postfix(Bombardment __instance)
 {
     RegionTraverser.BreadthFirstTraverse(__instance.Position, __instance.Map, (from, to) => true, region =>
     {
         region.ListerThings.ThingsInGroup(ThingRequestGroup.Pawn)
         .Select(p => (Pawn)p)
         .Where(p => !p.Downed && !p.Dead && !p.Drafted)
         .Where(p => p.CurJobDef != JobDefOf.Flee && !p.Downed)
         .Where(p => p.Position.DistanceTo(__instance.Position) <= 24.0f)
         .ToList()
         .ForEach(pawn =>
         {
             var threats = new List <Thing> {
                 __instance
             };
             var fleeDest1 = CellFinderLoose.GetFleeDest(pawn, threats, pawn.Position.DistanceTo(__instance.Position) + Bombardment.EffectiveRadius);
             pawn.jobs.StartJob(new Job(JobDefOf.Flee, fleeDest1, (LocalTargetInfo)__instance), JobCondition.InterruptOptional, null, false, true, null, new JobTag?());
         });
         return(false);
     }, 25, RegionType.Set_All);
 }