예제 #1
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, false, TraverseMode.ByPawn))
            {
                return;
            }
            Region region = near.GetRegion(pawn.Map, RegionType.Set_Passable);

            if (region == null)
            {
                return;
            }
            TraverseParms traverseParams = TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false);

            RegionTraverser.BreadthFirstTraverse(region, (Region from, Region to) => to.Allows(traverseParams, 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, (float)maxDistance) && TantrumMentalStateUtility.CanSmash(pawn, list[i], 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, (float)maxDistance) && TantrumMentalStateUtility.CanSmash(pawn, list2[j], 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, (float)maxDistance) && TantrumMentalStateUtility.CanSmash(pawn, list3[k], true, customValidator, extraMinBuildingOrItemMarketValue))
                    {
                        outCandidates.Add(list3[k]);
                    }
                }
                return(false);
            }, 40, RegionType.Set_Passable);
        }
예제 #2
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);
        }
        /// <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_TurretGunCE reloadable)
        {
            int quantity = reloadable.CompAmmo.MissingToFullMagazine;
            var ammoKind = reloadable.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);
        }
        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);
        }
예제 #5
0
 public static void NotifyFacilitiesAboutChangedLOSBlockers(List <Region> affectedRegions)
 {
     if (FacilitiesUtility.working)
     {
         Log.Warning("Tried to update facilities while already updating.");
         return;
     }
     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();
     }
 }
예제 #6
0
        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);
        }
예제 #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 = 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);
        }
예제 #8
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);
        }
예제 #9
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);
        }
예제 #10
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);
    }
        // Token: 0x06000435 RID: 1077 RVA: 0x0002D9FC File Offset: 0x0002BDFC
        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, 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);
                }
            }
            return(null);
        }
예제 #12
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);
 }
예제 #13
0
        private bool TryFindBestItem(Pawn pawn, ThingDef thingDef, int need, List <ThingCount> chosen)
        {
            chosen.Clear();

            Region rootReg = Position.GetRegion(pawn.Map);

            if (rootReg == null)
            {
                return(false);
            }

            Predicate <Thing>    baseValidator       = (Thing t) => t.Spawned && !t.IsForbidden(pawn) && pawn.CanReserve(t);
            TraverseParms        traverseParams      = TraverseParms.For(pawn);
            RegionEntryPredicate entryCondition      = (Region from, Region r) => r.Allows(traverseParams, isDestination: false);
            int             adjacentRegionsAvailable = rootReg.Neighbors.Count((Region region) => entryCondition(rootReg, region));
            bool            found           = false;
            RegionProcessor regionProcessor = delegate(Region r)
            {
                List <Thing> list = r.ListerThings.ThingsOfDef(thingDef);
                for (int i = 0; i < list.Count; i++)
                {
                    Thing thing = list[i];

                    int count = Mathf.Min(thing.stackCount, need);
                    chosen.Add(new ThingCount(thing, count));
                    need -= count;

                    if (need <= 0)
                    {
                        found = true;
                        return(true);
                    }
                }
                return(false);
            };

            RegionTraverser.BreadthFirstTraverse(rootReg, entryCondition, regionProcessor, 99999);

            return(found);
        }
예제 #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;
                bool result;
                if (pawn2 != null && !pawn2.Downed && (float)(pawn.Position - pawn2.Position).LengthHorizontalSquared < 144f && pawn2.HostileTo(pawn.Faction))
                {
                    found  = true;
                    result = true;
                }
                else
                {
                    result = false;
                }
                return(result);
            }), 9, RegionType.Set_Passable);
            return(found);
        }
        private Job FleeLargeFireJob(Pawn pawn)
        {
            if (pawn.Map.listerThings.ThingsInGroup(ThingRequestGroup.Fire).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> list = x.ListerThings.ThingsInGroup(ThingRequestGroup.Fire);
                for (int i = 0; i < list.Count; i++)
                {
                    float num = pawn.Position.DistanceToSquared(list[i].Position);
                    if (!(num > 400f))
                    {
                        if (closestFire == null || num < closestDistSq)
                        {
                            closestDistSq = num;
                            closestFire   = (Fire)list[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);
        }
예제 #16
0
        public override void StartExplosion(SoundDef explosionSound, List <Thing> ignoredThings)
        {
            bool flag = !base.Spawned;

            if (flag)
            {
                Log.Error("Called StartExplosion() on unspawned thing.", false);
            }
            else
            {
                this.startTick     = Find.TickManager.TicksGame;
                this.ignoredThings = ignoredThings;
                this.damagedThings.Clear();
                this.addedCellsAffectedOnlyByDamage.Clear();
                bool applyDamageToExplosionCellsNeighbors = this.applyDamageToExplosionCellsNeighbors;
                if (applyDamageToExplosionCellsNeighbors)
                {
                    this.AddCellsNeighbors(this.cellsToAffect);
                }
                this.damType.Worker.ExplosionStart(this, this.cellsToAffect);
                this.PlayExplosionSound(explosionSound);
                MoteMaker.MakeWaterSplash(base.Position.ToVector3Shifted(), base.Map, this.radius * 6f, 20f);
                this.cellsToAffect.Sort((IntVec3 a, IntVec3 b) => this.GetCellAffectTick(b).CompareTo(this.GetCellAffectTick(a)));
                RegionTraverser.BreadthFirstTraverse(base.Position, base.Map, (Region from, Region to) => true, delegate(Region x)
                {
                    List <Thing> allThings = x.ListerThings.AllThings;
                    for (int i = allThings.Count - 1; i >= 0; i--)
                    {
                        bool spawned = allThings[i].Spawned;
                        if (spawned)
                        {
                            allThings[i].Notify_Explosion(this);
                        }
                    }
                    return(false);
                }, 25, RegionType.Set_Passable);
            }
        }
        public static void GetInsultCandidatesFor(Pawn bully, List <Pawn> outCandidates, bool allowPrisoners = true)
        {
            outCandidates.Clear();
            Region region = bully.GetRegion();

            if (region != null)
            {
                TraverseParms traverseParams = TraverseParms.For(bully);
                RegionTraverser.BreadthFirstTraverse(region, (Region from, Region to) => to.Allows(traverseParams, isDestination : false), delegate(Region r)
                {
                    List <Thing> list = r.ListerThings.ThingsInGroup(ThingRequestGroup.Pawn);
                    for (int i = 0; i < list.Count; i++)
                    {
                        Pawn pawn = (Pawn)list[i];
                        if (CanChaseAndInsult(bully, pawn, skipReachabilityCheck: true, allowPrisoners))
                        {
                            outCandidates.Add(pawn);
                        }
                    }
                    return(false);
                }, 40);
            }
        }
예제 #18
0
        private static IntVec3 TryFindSnowmanBuildCell(Pawn pawn)
        {
            if (!CellFinder.TryFindClosestRegionWith(pawn.GetRegion(), TraverseParms.For(pawn), (Region r) => r.Room.PsychologicallyOutdoors, 100, out Region rootReg))
            {
                return(IntVec3.Invalid);
            }
            IntVec3 result = IntVec3.Invalid;

            RegionTraverser.BreadthFirstTraverse(rootReg, (Region from, Region r) => r.Room == rootReg.Room, delegate(Region r)
            {
                for (int i = 0; i < 5; i++)
                {
                    IntVec3 randomCell = r.RandomCell;
                    if (IsGoodSnowmanCell(randomCell, pawn))
                    {
                        result = randomCell;
                        return(true);
                    }
                }
                return(false);
            }, 30);
            return(result);
        }
예제 #19
0
        private static int BreadthFirstTraverse(Pawn pawn, TraverseParms tp, float closestDistSq, Fire closestFire, int firesCount)
        {
            RegionTraverser.BreadthFirstTraverse(pawn.Position, pawn.Map, (Region from, Region to) => to.Allows(tp, isDestination : false), delegate(Region x)
            {
                List <Thing> list = x.ListerThings.ThingsInGroup(ThingRequestGroup.Fire);
                for (int i = 0; i < list.Count; i++)
                {
                    float num = pawn.Position.DistanceToSquared(list[i].Position);
                    if (!(num > 400f))
                    {
                        if (closestFire == null || num < closestDistSq)
                        {
                            closestDistSq = num;
                            closestFire   = (Fire)list[i];
                        }
                        firesCount++;
                    }
                }

                return(closestDistSq <= 100f && firesCount >= 60);
            }, 18);
            return(firesCount);
        }
        public static void GetInsultCandidatesFor(Pawn bully, List <Pawn> outCandidates, bool allowPrisoners = true)
        {
            outCandidates.Clear();
            Region region = bully.GetRegion(RegionType.Set_Passable);

            if (region != null)
            {
                TraverseParms traverseParams = TraverseParms.For(bully, Danger.Deadly, TraverseMode.ByPawn, false);
                RegionTraverser.BreadthFirstTraverse(region, (Region from, Region to) => to.Allows(traverseParams, false), delegate(Region r)
                {
                    List <Thing> list = r.ListerThings.ThingsInGroup(ThingRequestGroup.Pawn);
                    for (int i = 0; i < list.Count; i++)
                    {
                        Pawn pawn = (Pawn)list[i];
                        if (InsultingSpreeMentalStateUtility.CanChaseAndInsult(bully, pawn, true, allowPrisoners))
                        {
                            outCandidates.Add(pawn);
                        }
                    }
                    return(false);
                }, 40, RegionType.Set_Passable);
            }
        }
예제 #21
0
        // Token: 0x06000007 RID: 7 RVA: 0x0000219C File Offset: 0x0000039C
        public List <IntVec3> ValidCellsAround(IntVec3 pos, Map map, CellRect rect)
        {
            CompBell.validCells.Clear();
            bool           flag = !pos.InBounds(map);
            List <IntVec3> result;

            if (flag)
            {
                result = CompBell.validCells;
            }
            else
            {
                Region region = pos.GetRegion(map, RegionType.Set_Passable);
                bool   flag2  = region == null;
                if (flag2)
                {
                    result = CompBell.validCells;
                }
                else
                {
                    RegionTraverser.BreadthFirstTraverse(region, (Region from, Region r) => r.door == null, delegate(Region r)
                    {
                        foreach (IntVec3 item in r.Cells)
                        {
                            bool flag3 = this.InDistOfRect(item, pos, rect);
                            if (flag3)
                            {
                                CompBell.validCells.Add(item);
                            }
                        }
                        return(false);
                    }, 13, RegionType.Set_Passable);
                    result = CompBell.validCells;
                }
            }
            return(result);
        }
예제 #22
0
        private bool ShouldStartEscaping(Pawn pawn)
        {
            bool result;

            if (!pawn.guest.IsPrisoner || pawn.guest.HostFaction != Faction.OfPlayer || !pawn.guest.PrisonerIsSecure)
            {
                result = false;
            }
            else
            {
                Room room = pawn.GetRoom(RegionType.Set_Passable);
                if (room.TouchesMapEdge)
                {
                    result = true;
                }
                else
                {
                    bool found = false;
                    RegionTraverser.BreadthFirstTraverse(room.Regions[0], (Region from, Region reg) => reg.portal == null || reg.portal.FreePassage, delegate(Region reg)
                    {
                        bool result2;
                        if (reg.Room.TouchesMapEdge)
                        {
                            found   = true;
                            result2 = true;
                        }
                        else
                        {
                            result2 = false;
                        }
                        return(result2);
                    }, 25, RegionType.Set_Passable);
                    result = found;
                }
            }
            return(result);
        }
        private static Region ClosestRegionWithinTemperatureRange(IntVec3 root, Map map, FloatRange tempRange, TraverseParms traverseParms, RegionType traversableRegionTypes = RegionType.Set_Passable)
        {
            Region region = root.GetRegion(map, traversableRegionTypes);
            Region result;

            if (region == null)
            {
                result = null;
            }
            else
            {
                RegionEntryPredicate entryCondition = (Region from, Region r) => r.Allows(traverseParms, false);
                Region          foundReg            = null;
                RegionProcessor regionProcessor     = delegate(Region r)
                {
                    bool result2;
                    if (r.portal != null)
                    {
                        result2 = false;
                    }
                    else if (tempRange.Includes(r.Room.Temperature))
                    {
                        foundReg = r;
                        result2  = true;
                    }
                    else
                    {
                        result2 = false;
                    }
                    return(result2);
                };
                RegionTraverser.BreadthFirstTraverse(region, entryCondition, regionProcessor, 9999, traversableRegionTypes);
                result = foundReg;
            }
            return(result);
        }
예제 #24
0
        private bool ShouldStartEscaping(Pawn pawn)
        {
            if (!pawn.guest.IsPrisoner || pawn.guest.HostFaction != Faction.OfPlayer || !pawn.guest.PrisonerIsSecure)
            {
                return(false);
            }
            Room room = pawn.GetRoom();

            if (room.TouchesMapEdge)
            {
                return(true);
            }
            bool found = false;

            RegionTraverser.BreadthFirstTraverse(room.Regions[0], delegate(Region from, Region reg)
            {
                if (reg.door != null && !reg.door.FreePassage)
                {
                    return(false);
                }
                return(true);
            }, delegate(Region reg)
            {
                if (reg.Room.TouchesMapEdge)
                {
                    found = true;
                    return(true);
                }
                return(false);
            }, 25);
            if (found)
            {
                return(true);
            }
            return(false);
        }
예제 #25
0
        private static bool TryFindSpotToPlaceHaulableCloseTo(Thing haulable, Pawn worker, IntVec3 center, out IntVec3 spot)
        {
            Region region = center.GetRegion(worker.Map);

            if (region == null)
            {
                spot = center;
                return(false);
            }
            TraverseParms traverseParms = TraverseParms.For(worker);
            IntVec3       foundCell     = IntVec3.Invalid;

            RegionTraverser.BreadthFirstTraverse(region, (Region from, Region r) => r.Allows(traverseParms, isDestination : false), delegate(Region r)
            {
                candidates.Clear();
                candidates.AddRange(r.Cells);
                candidates.Sort((IntVec3 a, IntVec3 b) => a.DistanceToSquared(center).CompareTo(b.DistanceToSquared(center)));
                for (int i = 0; i < candidates.Count; i++)
                {
                    IntVec3 intVec = candidates[i];
                    if (HaulablePlaceValidator(haulable, worker, intVec))
                    {
                        foundCell = intVec;
                        return(true);
                    }
                }
                return(false);
            }, 100);
            if (foundCell.IsValid)
            {
                spot = foundCell;
                return(true);
            }
            spot = center;
            return(false);
        }
예제 #26
0
        public static bool ShouldStartFleeing(Pawn pawn)
        {
            List <Thing> list = pawn.Map.listerThings.ThingsInGroup(ThingRequestGroup.AlwaysFlee);

            for (int i = 0; i < list.Count; i++)
            {
                if (SelfDefenseUtility.ShouldFleeFrom(list[i], pawn, true, false))
                {
                    return(true);
                }
            }
            bool   foundThreat = false;
            Region region      = pawn.GetRegion(RegionType.Set_Passable);

            if (region == null)
            {
                return(false);
            }
            RegionTraverser.BreadthFirstTraverse(region, (Region from, Region reg) => reg.portal == null || reg.portal.Open, delegate(Region reg)
            {
                List <Thing> list2 = reg.ListerThings.ThingsInGroup(ThingRequestGroup.AttackTarget);
                int num            = 0;
                while (num < list2.Count)
                {
                    if (!SelfDefenseUtility.ShouldFleeFrom(list2[num], pawn, true, true))
                    {
                        num++;
                        continue;
                    }
                    foundThreat = true;
                    break;
                }
                return(foundThreat);
            }, 9, RegionType.Set_Passable);
            return(foundThreat);
        }
예제 #27
0
        private static bool IsSafeDropSpot(IntVec3 cell, Map map, Faction faction, IntVec2?size = null, int distToEdge = 25, int distToHostiles = 35, int distToFires = 15)
        {
            Faction factionBaseFaction = map.ParentFaction ?? Faction.OfPlayer;

            if (size.HasValue)
            {
                foreach (IntVec3 item in GenAdj.OccupiedRect(cell, Rot4.North, size.Value))
                {
                    if (!IsGoodDropSpot(item, map, allowFogged: false, canRoofPunch: false, allowIndoors: false))
                    {
                        return(false);
                    }
                }
            }
            else if (!IsGoodDropSpot(cell, map, allowFogged: false, canRoofPunch: false, allowIndoors: false))
            {
                return(false);
            }
            if (distToEdge > 0 && cell.CloseToEdge(map, distToEdge))
            {
                return(false);
            }
            if (faction != null)
            {
                foreach (IAttackTarget item2 in map.attackTargetsCache.TargetsHostileToFaction(faction))
                {
                    if (!item2.ThreatDisabled(null) && item2.Thing.Position.InHorDistOf(cell, distToHostiles))
                    {
                        return(false);
                    }
                }
            }
            if (!map.reachability.CanReachFactionBase(cell, factionBaseFaction))
            {
                return(false);
            }
            if (size.HasValue)
            {
                foreach (IntVec3 cell2 in CellRect.CenteredOn(cell, size.Value.x, size.Value.z).Cells)
                {
                    if (CellHasCrops(cell2))
                    {
                        return(false);
                    }
                }
            }
            else if (CellHasCrops(cell))
            {
                return(false);
            }
            float minDistToFiresSq = distToFires * distToFires;
            float closestDistSq    = float.MaxValue;
            int   firesCount       = 0;

            RegionTraverser.BreadthFirstTraverse(cell, map, (Region from, Region to) => true, delegate(Region x)
            {
                List <Thing> list = x.ListerThings.ThingsInGroup(ThingRequestGroup.Fire);
                for (int i = 0; i < list.Count; i++)
                {
                    float num = cell.DistanceToSquared(list[i].Position);
                    if (!(num > minDistToFiresSq))
                    {
                        if (num < closestDistSq)
                        {
                            closestDistSq = num;
                        }
                        firesCount++;
                    }
                }
                return(closestDistSq <= minDistToFiresSq && firesCount >= 5);
            }, 15);
            if (closestDistSq <= minDistToFiresSq && firesCount >= 5)
            {
                return(false);
            }
            return(true);

            bool CellHasCrops(IntVec3 c)
            {
                Plant plant = c.GetPlant(map);

                if (plant != null && plant.sown)
                {
                    return(map.zoneManager.ZoneAt(c) is Zone_Growing);
                }
                return(false);
            }
        }
예제 #28
0
        // RimWorld.FoodUtility
        private static Pawn BestPawnToHuntForPredator(Pawn predator, bool forceScanWholeMap)
        {
            if (predator.meleeVerbs.TryGetMeleeVerb(null) == null)
            {
                return(null);
            }
            bool  flag = false;
            float summaryHealthPercent = predator.health.summaryHealth.SummaryHealthPercent;

            if (summaryHealthPercent < 0.25f)
            {
                flag = true;
            }
            tmpPredatorCandidates.Clear();
            int maxRegionsToScan = GetMaxRegionsToScan(predator, forceScanWholeMap);

            if (maxRegionsToScan < 0)
            {
                tmpPredatorCandidates.AddRange(predator.Map.mapPawns.AllPawnsSpawned);
            }
            else
            {
                TraverseParms traverseParms = TraverseParms.For(predator, Danger.Deadly, TraverseMode.ByPawn, false);
                RegionTraverser.BreadthFirstTraverse(predator.Position, predator.Map, (Region from, Region to) => to.Allows(traverseParms, true), delegate(Region x)
                {
                    List <Thing> list = x.ListerThings.ThingsInGroup(ThingRequestGroup.Pawn);
                    for (int j = 0; j < list.Count; j++)
                    {
                        bool XenoInfection = (((Pawn)list[j]).health.hediffSet.HasHediff(XenomorphDefOf.RRY_FaceHuggerInfection) || ((Pawn)list[j]).health.hediffSet.HasHediff(XenomorphDefOf.RRY_HiddenXenomorphImpregnation) || ((Pawn)list[j]).health.hediffSet.HasHediff(XenomorphDefOf.RRY_XenomorphImpregnation)) ? true : false;
                        bool IsXenos       = (((Pawn)list[j]).kindDef == XenomorphDefOf.RRY_Xenomorph_Drone || ((Pawn)list[j]).kindDef == XenomorphDefOf.RRY_Xenomorph_FaceHugger || ((Pawn)list[j]).kindDef == XenomorphDefOf.RRY_Xenomorph_Queen || ((Pawn)list[j]).kindDef == XenomorphDefOf.RRY_Xenomorph_Runner || ((Pawn)list[j]).kindDef == XenomorphDefOf.RRY_Xenomorph_Warrior) ? true : false;

                        if (!XenoInfection && !IsXenos)
                        {
                            tmpPredatorCandidates.Add((Pawn)list[j]);
                        }
                        else
                        {
                            //    Log.Message(string.Format("{0} cannae hunt {2} XenoInfection:{1} IsXenos:{3}", predator.Label, XenoInfection, ((Pawn)list[j]).Label, IsXenos));
                        }
                    }
                    return(false);
                }, 999999, RegionType.Set_Passable);
            }
            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(RegionType.Set_Passable) == pawn2.GetRoom(RegionType.Set_Passable))
                {
                    if (predator != pawn2)
                    {
                        if (!flag || pawn2.Downed)
                        {
                            if (IsAcceptablePreyFor(predator, pawn2))
                            {
                                if (predator.CanReach(pawn2, PathEndMode.ClosestTouch, Danger.Deadly, false, TraverseMode.ByPawn))
                                {
                                    if (!pawn2.IsForbidden(predator) && !(XenoInfection(pawn2)))
                                    {
                                        if (!tutorialMode || pawn2.Faction != Faction.OfPlayer)
                                        {
                                            float preyScoreFor = FoodUtility.GetPreyScoreFor(predator, pawn2);
                                            if (preyScoreFor > num || pawn == null)
                                            {
                                                num  = preyScoreFor;
                                                pawn = pawn2;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            tmpPredatorCandidates.Clear();
            return(pawn);
        }
예제 #29
0
        private static bool TryFindSpotToPlaceHaulableCloseTo(Thing haulable, Pawn worker, IntVec3 center,
                                                              out IntVec3 spot)
        {
            List <string> debugMessages = new List <string>();

            Region region = center.GetRegion(worker.Map);

            if (region == null)
            {
                spot = center;
                return(false);
            }
            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)
            {
                candidates.Clear();
                candidates.AddRange(r.Cells);

                // This function helps to identify cells which are part of the haulable's current stockpile
                // (which it is not supposed to be in.
                bool currentStockpile(IntVec3 slot) =>
                worker.Map.haulDestinationManager.SlotGroupAt(haulable.Position).CellsList.Contains(slot);

                // We remove cells which we could never haul this thing to.
                candidates.RemoveAll(currentStockpile);

                candidates.Sort((IntVec3 a, IntVec3 b) => a.DistanceToSquared(center).CompareTo(b.DistanceToSquared(center)));
                IntVec3 intVec;
                for (int i = 0; i < candidates.Count; i++)
                {
                    intVec = candidates[i];
                    if (HaulablePlaceValidator(haulable, worker, intVec, out string debugMsg))
                    {
                        foundCell = intVec;

                        if (CTS_Loader.settings.debug)
                        {
                            debugMessages.Add(debugMsg);
                        }

                        //Debugging output.
                        if (debugMessages.Count != 0)
                        {
                            foreach (string s in debugMessages)
                            {
                                Log.Message(s);
                            }
                        }
                        return(true);
                    }
                    else if (CTS_Loader.settings.debug)
                    {
                        debugMessages.Add(debugMsg);
                    }
                }

                //Debugging output.
                if (debugMessages.Count != 0)
                {
                    foreach (string s in debugMessages)
                    {
                        Log.Message(s);
                    }
                }
                return(false);
            }, cellsToSearch);

            if (foundCell.IsValid)
            {
                spot = foundCell;
                return(true);
            }
            spot = center;
            return(false);
        }
예제 #30
0
        //public class JobGiver_SeekAllowedArea : ThinkNode_JobGiver
        public static bool SeekAllowedArea_TryGiveJob(JobGiver_SeekAllowedArea __instance, Pawn pawn, ref Job __result)
        {
            if (!pawn.AnimalOrWildMan())
            {
                return(true);
            }
            if (pawn.playerSettings == null)
            {
                return(true);
            }
            //StringBuilder res = new StringBuilder();
            //Log.Message($"{pawn.Label} sought an allowed area.");
            if (!pawn.Position.IsForbidden(pawn))
            {
                //Log.Message("Not Forbidden cur position");
                __result = null;
                return(false);
            }

            if (Traverse.Create(__instance).Method("HasJobWithSpawnedAllowedTarget", pawn).GetValue <bool>())
            {
                //Log.Message("Has job with spawned allowed target");
                __result = null;
                return(false);
            }

            Region region = pawn.GetRegion(RegionType.Set_Passable);

            if (region == null)
            {
                //Log.Message("No passable region");
                __result = null;
                return(false);
            }

            var                  allows         = false;
            TraverseParms        traverseParms  = TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false);
            RegionEntryPredicate entryCondition = (Region from, Region r) =>
            {
                allows = r.Allows(traverseParms, false);
                if (allows)
                {
                    //Log.Message("Move allowed.");
                    return(true);
                }

                //Log.Message("Entry barred");
                if (r.door == null)
                {
                    //Log.Message("Door Null");
                    //Log.Message("Return True");
                }
                ByteGrid avoidGrid = traverseParms.pawn.GetAvoidGrid(true);
                if (avoidGrid != null && avoidGrid[r.door.Position] == 255)
                {
                    //Log.Message("Door Position == 255");

                    //Log.Message("Return False");
                }
                if (traverseParms.pawn.HostileTo(r.door))
                {
                    //Log.Message("Door Position == 255");
                    //Log.Message("CanPhysicallyPass: "******"CanBash: " + traverseParms.canBash.ToString());
                }
                //Log.Message("door.CanPhysicallyPass(tp.pawn) == " + r.door.CanPhysicallyPass(traverseParms.pawn));
                //Log.Message("!r.door.IsForbiddenToPass(traverseParms.pawn); == " + !r.door.IsForbiddenToPass(traverseParms.pawn));
                //Log.Message("Return " + (r.door.CanPhysicallyPass(traverseParms.pawn) && !r.door.IsForbiddenToPass(traverseParms.pawn)));
                //return this.door.CanPhysicallyPass(tp.pawn) && !this.door.IsForbiddenToPass(tp.pawn);
                return(false);
            };
            Region          reg             = null;
            RegionProcessor regionProcessor = delegate(Region r)
            {
                if (r.IsDoorway && r?.ListerThings?.AllThings?.Any(x => x is Building_DoorRegionHandler) == false)
                {
                    Log.Message("Doorway disallowed");
                    return(false);
                }

                if (!r.IsForbiddenEntirely(pawn))
                {
                    Log.Message("Allowed passage");
                    reg = r;
                    return(true);
                }

                return(false);
            };

            RegionTraverser.BreadthFirstTraverse(region, entryCondition, regionProcessor, 9999,
                                                 RegionType.Set_Passable);
            if (reg == null)
            {
                Log.Message(pawn.LabelShort + " No region found");
                __result = null;
                return(false);
            }

            IntVec3 c;

            if (!reg.TryFindRandomCellInRegionUnforbidden(pawn, null, out c))
            {
                Log.Message(pawn.LabelShort + " Failed to find random cell in region unforbidden");
                __result = null;
                return(false);
            }

            __result = new Job(JobDefOf.Goto, c);
            return(false);
        }