Beispiel #1
0
        private Job TryGetFleeJob(Pawn pawn)
        {
            if (!SelfDefenseUtility.ShouldStartFleeing(pawn))
            {
                return(null);
            }
            tmpThreats.Clear();
            List <IAttackTarget> potentialTargetsFor = pawn.Map.attackTargetsCache.GetPotentialTargetsFor(pawn);

            for (int i = 0; i < potentialTargetsFor.Count; i++)
            {
                IAttackTarget attackTarget = potentialTargetsFor[i];
                if (!attackTarget.ThreatDisabled())
                {
                    tmpThreats.Add((Thing)attackTarget);
                }
            }
            if (!tmpThreats.Any())
            {
                Log.Warning(pawn.LabelShort + " decided to flee but there is no any threat around.");
                return(null);
            }
            IntVec3 fleeDest = GetFleeDest(pawn, tmpThreats);

            tmpThreats.Clear();
            return(new Job(JobDefOf.FleeAndCower, fleeDest));
        }
        //protected override IEnumerable<Toil> MakeNewToils()
        public static void Postfix(ref IEnumerable <Toil> __result, JobDriver_Flee __instance)
        {
            if (!Mod.settings.stopFlee)
            {
                return;
            }

            if (!(__instance.GetActor() is Pawn pawn) || !pawn.IsFreeColonist)
            {
                return;
            }

            List <Toil> result = __result.ToList();

            Toil goToil = result.Last();

            goToil.AddEndCondition(delegate
            {
                Thing instigator = __instance.job.GetTarget(TargetIndex.B).Thing;
                if (instigator is Pawn badGuy)
                {
                    if (badGuy.Downed || badGuy.Destroyed || badGuy.Dead)
                    {
                        Log.Message($"{pawn}'s instigator {instigator} is down");
                        return(JobCondition.Succeeded);
                    }
                }
                else if (!SelfDefenseUtility.ShouldStartFleeing(pawn))
                {
                    Log.Message($"{pawn} no longer scared");
                    return(JobCondition.Succeeded);
                }
                return(JobCondition.Ongoing);
            });
        private IntVec3 FindSafeCell(Pawn pawn)
        {
            List <Thing>         threats             = new List <Thing>();
            List <IAttackTarget> potentialTargetsFor = pawn.Map.attackTargetsCache.GetPotentialTargetsFor(pawn);

            for (int i = 0; i < potentialTargetsFor.Count; i++)
            {
                Thing thing = potentialTargetsFor[i].Thing;
                if (SelfDefenseUtility.ShouldFleeFrom(thing, pawn, checkDistance: false, checkLOS: false))
                {
                    threats.Add(thing);
                }
            }
            List <Thing> thingsToFlee = pawn.Map.listerThings.ThingsInGroup(ThingRequestGroup.AlwaysFlee);

            for (int j = 0; j < thingsToFlee.Count; j++)
            {
                Thing thing = thingsToFlee[j];
                if (SelfDefenseUtility.ShouldFleeFrom(thing, pawn, checkDistance: false, checkLOS: false))
                {
                    threats.Add(thing);
                }
            }
            return(CellFinderLoose.GetFleeDest(pawn, threats));
        }
Beispiel #4
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);
                for (int index = 0; index < thingList2.Count; ++index)
                {
                    Thing t;
                    try
                    {
                        t = thingList2[index];
                    }
                    catch (ArgumentOutOfRangeException) { break; }
                    if (null != t)
                    {
                        if (SelfDefenseUtility.ShouldFleeFrom(t, pawn, true, true))
                        {
                            foundThreat = true;
                            break;
                        }
                    }
                }

                return(foundThreat);
            }), 9, RegionType.Set_Passable);
            __result = foundThreat;
            return(false);
        }
        protected override Job TryGiveJob(Pawn pawn)
        {
            Job result;

            if (pawn.playerSettings != null && pawn.playerSettings.UsesConfigurableHostilityResponse)
            {
                result = null;
            }
            else if (ThinkNode_ConditionalShouldFollowMaster.ShouldFollowMaster(pawn))
            {
                result = null;
            }
            else
            {
                if (pawn.Faction == null)
                {
                    List <Thing> list = pawn.Map.listerThings.ThingsInGroup(ThingRequestGroup.AlwaysFlee);
                    for (int i = 0; i < list.Count; i++)
                    {
                        if (pawn.Position.InHorDistOf(list[i].Position, 18f) && SelfDefenseUtility.ShouldFleeFrom(list[i], pawn, false, false))
                        {
                            return(ReturnToStationJob((Pawn_Drone)pawn));
                        }
                    }
                    Job job2 = FleeLargeFireJob(pawn);
                    if (job2 != null)
                    {
                        return(job2);
                    }
                }
                else if (pawn.GetLord() == null)
                {
                    List <IAttackTarget> potentialTargetsFor = pawn.Map.attackTargetsCache.GetPotentialTargetsFor(pawn);
                    for (int j = 0; j < potentialTargetsFor.Count; j++)
                    {
                        Thing thing = potentialTargetsFor[j].Thing;
                        if (pawn.Position.InHorDistOf(thing.Position, 18f) && SelfDefenseUtility.ShouldFleeFrom(thing, pawn, false, true))
                        {
                            return(ReturnToStationJob((Pawn_Drone)pawn));
                        }
                    }
                }
                result = null;
            }
            return(result);
        }
        public static bool TryGetFleeJob(JobGiver_ConfigurableHostilityResponse __instance, ref Job __result, Pawn pawn)
        {
            if (!SelfDefenseUtility.ShouldStartFleeing(pawn))
            {
                __result = null;
                return(false);
            }

            IntVec3 c;

            if (pawn.CurJob != null && pawn.CurJob.def == JobDefOf.FleeAndCower)
            {
                c = pawn.CurJob.targetA.Cell;
            }
            else
            {
                //tmpThreats.Clear();
                List <Thing>         tmpThreats          = new List <Thing>();
                List <IAttackTarget> potentialTargetsFor = pawn.Map.attackTargetsCache.GetPotentialTargetsFor(pawn);
                for (int i = 0; i < potentialTargetsFor.Count; i++)
                {
                    Thing thing = potentialTargetsFor[i].Thing;
                    if (SelfDefenseUtility.ShouldFleeFrom(thing, pawn, checkDistance: false, checkLOS: false))
                    {
                        tmpThreats.Add(thing);
                    }
                }

                List <Thing> list = pawn.Map.listerThings.ThingsInGroup(ThingRequestGroup.AlwaysFlee);
                for (int j = 0; j < list.Count; j++)
                {
                    Thing thing2 = list[j];
                    if (SelfDefenseUtility.ShouldFleeFrom(thing2, pawn, checkDistance: false, checkLOS: false))
                    {
                        tmpThreats.Add(thing2);
                    }
                }

                if (!tmpThreats.Any())
                {
                    Log.Error(pawn.LabelShort + " decided to flee but there is not any threat around.");
                    Region region = pawn.GetRegion();
                    if (region == null)
                    {
                        __result = null;
                        return(false);
                    }

                    RegionTraverser.BreadthFirstTraverse(region, (Region from, Region reg) => reg.door == null || reg.door.Open, delegate(Region reg)
                    {
                        List <Thing> list2 = reg.ListerThings.ThingsInGroup(ThingRequestGroup.AttackTarget);
                        for (int k = 0; k < list2.Count; k++)
                        {
                            Thing thing3 = list2[k];
                            if (SelfDefenseUtility.ShouldFleeFrom(thing3, pawn, checkDistance: false, checkLOS: false))
                            {
                                tmpThreats.Add(thing3);
                                Log.Warning($"  Found a viable threat {thing3.LabelShort}; tests are {thing3.Map.attackTargetsCache.Debug_CheckIfInAllTargets(thing3 as IAttackTarget)}, {thing3.Map.attackTargetsCache.Debug_CheckIfHostileToFaction(pawn.Faction, thing3 as IAttackTarget)}, {thing3 is IAttackTarget}");
                            }
                        }

                        return(false);
                    }, 9);
                    if (!tmpThreats.Any())
                    {
                        __result = null;
                        return(false);
                    }
                }

                c = CellFinderLoose.GetFleeDest(pawn, tmpThreats);
                //tmpThreats.Clear();
            }

            __result = JobMaker.MakeJob(JobDefOf.FleeAndCower, c);
            return(false);
        }