Ejemplo n.º 1
0
        public static Job FindUpgradeInvJob(Pawn pawn, List <Thing> groundItems)
        {
            Log.Message("Finding if " + pawn + " can upgrade his inventory");

            foreach (Apparel toReplace in pawn.inventory.innerContainer
                     .Where(t => t is Apparel a))
            {
                Thing upgradeItem = null;
                float bestScore   = JobGiver_OptimizeApparel.ApparelScoreRaw(pawn, toReplace);
                Log.Message("Looking for an upgrade to " + toReplace + "(" + bestScore + ")");

                foreach (Apparel possibleUpgrade in groundItems.Where(i => i is Apparel a &&
                                                                      toReplace.def == a.def &&
                                                                      a.Map.slotGroupManager.SlotGroupAt(a.Position) != null &&
                                                                      !a.IsForbidden(pawn)))
                {
                    float thisScore = JobGiver_OptimizeApparel.ApparelScoreRaw(pawn, possibleUpgrade);
                    Log.Message("possible upgrade is " + possibleUpgrade + "(" + thisScore + ")");
                    if (thisScore > bestScore &&
                        pawn.CanReserveAndReach(possibleUpgrade, PathEndMode.OnCell, pawn.NormalMaxDanger(), 1, -1, null, false))
                    {
                        Log.Message("It's better!");
                        upgradeItem = possibleUpgrade;
                        bestScore   = thisScore;
                    }
                }
                if (upgradeItem != null)
                {
                    return(new Job(GearUpAndGoJobDefOf.UpgradeApparelInInventory, upgradeItem, toReplace));
                }
            }
            return(null);
        }
Ejemplo n.º 2
0
 static void TryGiveJob_Patch(JobGiver_OptimizeApparel __instance, ref Job __result, Pawn pawn)
 {
     if (__result != null)
     {
         // Stop the game from automatically allocating pawns Wear jobs they cannot fulfil
         if ((pawn.ageTracker.CurLifeStageIndex <= AgeStage.Toddler && __result.targetA.Thing.TryGetComp <CompBabyGear>() == null && ChildrenUtility.RaceUsesChildren(pawn)) ||
             (pawn.ageTracker.CurLifeStageIndex >= AgeStage.Child && __result.targetA.Thing.TryGetComp <CompBabyGear>() != null))
         {
             __result = null;
         }
     }
     else
     {
         // makes pawn to remove baby clothes when too old for them.
         List <Apparel> wornApparel = pawn.apparel.WornApparel;
         if (pawn.ageTracker.CurLifeStageIndex >= AgeStage.Child)
         {
             for (int i = wornApparel.Count - 1; i >= 0; i--)
             {
                 CompBabyGear compBabyGear = wornApparel[i].TryGetComp <CompBabyGear>();
                 if (compBabyGear != null)
                 {
                     __result = new Job(JobDefOf.RemoveApparel, wornApparel[i])
                     {
                         haulDroppedApparel = true
                     };
                     return;
                 }
             }
         }
     }
 }
Ejemplo n.º 3
0
        // Copied so outfits can be commented
        public static float ApparelScoreGain(Pawn pawn, Apparel ap)
        {
            if (ap is ShieldBelt && pawn.equipment.Primary != null && pawn.equipment.Primary.def.IsWeaponUsingProjectiles)
            {
                return(-1000f);
            }
            float          num         = JobGiver_OptimizeApparel.ApparelScoreRaw(pawn, ap);
            List <Apparel> wornApparel = pawn.apparel.WornApparel;
            bool           flag        = false;

            for (int index = 0; index < wornApparel.Count; ++index)
            {
                if (!ApparelUtility.CanWearTogether(wornApparel[index].def, ap.def, pawn.RaceProps.body))
                {
                    //if (!pawn.outfits.forcedHandler.AllowedToAutomaticallyDrop(wornApparel[index]))
                    //    return -1000f;
                    num -= JobGiver_OptimizeApparel.ApparelScoreRaw(pawn, wornApparel[index]);
                    flag = true;
                }
            }
            if (!flag)
            {
                num *= 10f;
            }
            return(num);
        }
Ejemplo n.º 4
0
        protected override Job TryGiveJob(Pawn pawn)
        {
            //if (pawn.outfits == null)
            //{
            //    Log.ErrorOnce(pawn + " tried to run JobGiver_TakeFromLocker without an OutfitTracker", 5643897);
            //    return null;
            //}
            if (!pawn.IsPrisoner)
            {
                Log.ErrorOnce("Non-prisoner " + pawn + " tried to take from locker.", 764323);
                return(null);
            }

            if (Find.TickManager.TicksGame < pawn.mindState.nextApparelOptimizeTick)
            {
                return(null);
            }

            //Outfit currentOutfit = pawn.outfits.CurrentOutfit;
            List <Apparel> wornApparel = pawn.apparel.WornApparel;

            Thing        thing = null;
            float        num   = 0f;
            List <Thing> list  = FindItemToWear(pawn);

            if (list.Count == 0)
            {
                SetNextOptimizeTick(pawn);
                return(null);
            }
            var neededWarmth = PawnApparelGenerator.CalculateNeededWarmth(pawn, pawn.Map.Tile, GenLocalDate.Twelfth(pawn));

            for (int j = 0; j < list.Count; j++)
            {
                Apparel apparel = (Apparel)list[j];
                if (apparel.Map.slotGroupManager.SlotGroupAt(apparel.Position) != null)
                {
                    float num2 = JobGiver_OptimizeApparel.ApparelScoreGain(pawn, apparel);

                    if (num2 >= 0.05f && num2 >= num)
                    {
                        if (ApparelUtility.HasPartsToWear(pawn, apparel.def))
                        {
                            if (pawn.CanReserveAndReach(apparel, PathEndMode.OnCell, pawn.NormalMaxDanger(), 1, -1, null, false))
                            {
                                thing = apparel;
                                num   = num2;
                            }
                        }
                    }
                }
            }
            if (thing == null)
            {
                SetNextOptimizeTick(pawn);
                return(null);
            }
            return(new Job(JobDefOf.Wear, thing));
        }
Ejemplo n.º 5
0
 // RimWorld.JobGiver_OptimizeApparel
 public static bool DontOptimizeHulkApparel(JobGiver_OptimizeApparel __instance, ref Job __result, Pawn pawn)
 {
     if (pawn?.GetComp <CompHulk>() is CompHulk ww && ww.IsTransformed)
     {
         __result = null;
         return(false);
     }
     return(true);
 }
Ejemplo n.º 6
0
        static bool Prefix(ref float __result, JobGiver_OptimizeApparel __instance, Pawn pawn, Apparel ap)
        {
            Log.Message("1 pawn is " + ((pawn == null) ? "null" : "not null"));

            if (pawn != null)
            {
                return(true);
            }
            Log.Message("2");

            if (HitPointsPercentScoreFactorCurve == null)
            {
                HitPointsPercentScoreFactorCurve        = typeof(JobGiver_OptimizeApparel).GetField("HitPointsPercentScoreFactorCurve", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null) as SimpleCurve;
                InsulationColdScoreFactorCurve_NeedWarm = typeof(JobGiver_OptimizeApparel).GetField("InsulationColdScoreFactorCurve_NeedWarm", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null) as SimpleCurve;
                NeedWarmthFI = typeof(JobGiver_OptimizeApparel).GetField("neededWarmth", BindingFlags.Static | BindingFlags.NonPublic);
            }
            Log.Message("HitPointsPercentScoreFactorCurve is " + ((HitPointsPercentScoreFactorCurve == null) ? "null" : "not null"));
            Log.Message("InsulationColdScoreFactorCurve_NeedWarm is " + ((InsulationColdScoreFactorCurve_NeedWarm == null) ? "null" : "not null"));
            Log.Message("NeedWarmthFI is " + ((NeedWarmthFI == null) ? "null" : "not null"));
            Log.Message("NeedWarmth is " + NeedWarmthFI.GetValue(null));

            float result = 0.1f + ap.GetStatValue(StatDefOf.ArmorRating_Sharp) + ap.GetStatValue(StatDefOf.ArmorRating_Blunt);

            if (ap.def.useHitPoints)
            {
                float x = (float)ap.HitPoints / (float)ap.MaxHitPoints;
                result *= HitPointsPercentScoreFactorCurve.Evaluate(x);
            }
            result += ap.GetSpecialApparelScoreOffset();
            float num3 = 1f;

            if ((NeededWarmth)NeedWarmthFI.GetValue(null) == NeededWarmth.Warm)
            {
                float statValue = ap.GetStatValue(StatDefOf.Insulation_Cold);
                num3 *= InsulationColdScoreFactorCurve_NeedWarm.Evaluate(statValue);
            }
            result *= num3;
            if (ap.WornByCorpse)
            {
                result -= 0.5f;
                if (result > 0f)
                {
                    result *= 0.1f;
                }
            }
            if (ap.Stuff == ThingDefOf.Human.race.leatherDef)
            {
                result -= 0.5f;
                if (result > 0f)
                {
                    result *= 0.1f;
                }
            }
            __result = result;
            return(false);
        }
Ejemplo n.º 7
0
        // Copied so we can make some adjustments
        public static float ApparelScoreGain(Pawn pawn, Apparel ap)
        {
            if (ap is ShieldBelt && pawn.equipment.Primary?.def.IsWeaponUsingProjectiles == true)
            {
                return(-1000);
            }
            // Added
            if (!ItemUtility.AlienFrameworkAllowsIt(pawn.def, ap.def, "CanWear"))
            {
                return(-1000);
            }
            if (!ApparelUtility.HasPartsToWear(pawn, ap.def))
            {
                return(-1000);
            }
            if (pawn.story.traits.HasTrait(TraitDefOf.Nudist))
            {
                return(-1000);
            }
            //if (PawnApparelGenerator.IsHeadgear(ap.def)) return 0;
            float          num         = JobGiver_OptimizeApparel.ApparelScoreRaw(pawn, ap);
            List <Apparel> wornApparel = pawn.apparel.WornApparel;
            bool           flag        = false;
            // Added:
            var newReq = ItemUtility.IsRequiredByRoyalty(pawn, ap.def);

            for (int i = 0; i < wornApparel.Count; ++i)
            {
                if (!ApparelUtility.CanWearTogether(wornApparel[i].def, ap.def, pawn.RaceProps.body))
                {
                    if (pawn.apparel.IsLocked(wornApparel[i]))
                    {
                        return(-1000);
                    }
                    // Added:
                    var wornReq = ItemUtility.IsRequiredByRoyalty(pawn, wornApparel[i].def);
                    if (wornReq && !newReq)
                    {
                        return(-1000);
                    }
                    //if (!pawn.outfits.forcedHandler.AllowedToAutomaticallyDrop(wornApparel[index]))
                    //    return -1000f;
                    num -= JobGiver_OptimizeApparel.ApparelScoreRaw(pawn, wornApparel[i]);
                    flag = true;
                }
            }
            if (!flag)
            {
                num *= 10f;
            }
            return(num);
        }
Ejemplo n.º 8
0
        static void Postfix(Pawn pawn, ref Job __result)
        {
            IEnumerable <Building_Dresser> dressers = pawn.Map.listerBuildings.AllBuildingsColonistOfClass <Building_Dresser>();

            if (!DoesDressersHaveApparel(dressers))
            {
                return;
            }

            Thing thing = null;

            if (__result != null)
            {
                thing = __result.targetA.Thing;
            }

            Building_Dresser containingDresser = null;
            Outfit           currentOutfit     = pawn.outfits.CurrentOutfit;
            float            baseApparelScore  = 0f;

            foreach (Building_Dresser dresser in dressers)
            {
                foreach (Apparel apparel in dresser.StoredApparel)
                {
                    if (currentOutfit.filter.Allows(apparel))
                    {
                        if (!apparel.IsForbidden(pawn))
                        {
                            float newApparelScore = JobGiver_OptimizeApparel.ApparelScoreGain(pawn, apparel);
                            if (newApparelScore >= 0.05f && newApparelScore >= baseApparelScore)
                            {
                                if (ApparelUtility.HasPartsToWear(pawn, apparel.def))
                                {
                                    if (ReservationUtility.CanReserveAndReach(pawn, dresser, PathEndMode.OnCell, pawn.NormalMaxDanger(), 1))
                                    {
                                        containingDresser = dresser;
                                        thing             = apparel;
                                        baseApparelScore  = newApparelScore;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            if (thing != null && containingDresser != null)
            {
                __result = new Job(containingDresser.wearApparelFromStorageJobDef, containingDresser, thing);
            }
        }
        static void Postfix(Thing __instance)
        {
            if (!OutfittedMod.showApparelScores)
            {
                return;
            }

            if (Find.CameraDriver.CurrentZoom != CameraZoomRange.Closest)
            {
                return;
            }

            var pawn = Find.Selector.SingleSelectedThing as Pawn;

            if (pawn == null || !pawn.IsColonistPlayerControlled)
            {
                return;
            }

            var apparel = __instance as Apparel;

            if (apparel == null)
            {
                return;
            }

            var outfit = pawn.outfits.CurrentOutfit as ExtendedOutfit;

            if (outfit == null)
            {
                return;
            }

            if (!outfit.filter.Allows(apparel))
            {
                return;
            }

            var scores = CachedScoresForPawn(pawn);

            float score = JobGiver_OptimizeApparel.ApparelScoreGain_NewTmp(pawn, apparel, scores);

            if (Math.Abs(score) > 0.01f)
            {
                var pos = GenMapUI.LabelDrawPosFor(apparel, 0f);
                GenMapUI.DrawThingLabel(pos, score.ToString("F1"), BeautyDrawer.BeautyColor(score, 3f));
            }
        }
Ejemplo n.º 10
0
        public static bool ApparelScoreGain(ref float __result, Pawn pawn, Apparel ap)
        {
            List <float> wornApparelScores = new List <float>();

            //wornApparelScores.Clear();
            for (int i = 0; i < pawn.apparel.WornApparel.Count; i++)
            {
                Apparel apparel = pawn.apparel.WornApparel[i];
                wornApparelScores.Add(JobGiver_OptimizeApparel.ApparelScoreRaw(pawn, apparel));
            }
            float scoreGain = 0f;

            ApparelScoreGain_NewTmp(ref scoreGain, pawn, ap, wornApparelScores);
            __result = scoreGain;
            return(false);
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            Toil toil = new Toil();

            toil.initAction = delegate
            {
                Pawn pawn = toil.actor;
                if (pawn.thinker == null)
                {
                    return;
                }

                JobGiver_OptimizeApparel optimizer = pawn.thinker.TryGetMainTreeThinkNode <JobGiver_OptimizeApparel>();
                if (optimizer == null)
                {
                    return;
                }

                pawn.mindState?.Notify_OutfitChanged();                                        // Lie so that it re-equips things
                ThinkResult result = optimizer.TryIssueJobPackage(pawn, new JobIssueParams()); //TryGiveJob is protected :(
                if (result == ThinkResult.NoJob)
                {
                    Log.Message(pawn + " JobDriver_GearUpAndGo result NoJob");
                    IntVec3 intVec = RCellFinder.BestOrderedGotoDestNear(TargetA.Cell, pawn);
                    Job     job    = new Job(JobDefOf.Goto, intVec);
                    if (pawn.Map.exitMapGrid.IsExitCell(UI.MouseCell()))
                    {
                        job.exitMapOnArrival = true;                         // I guess
                    }
                    pawn.drafter.Drafted = true;
                    pawn.jobs.StartJob(job, JobCondition.Succeeded);
                    MoteMaker.MakeStaticMote(intVec, pawn.Map, ThingDefOf.Mote_FeedbackGoto, 1f);
                }
                else
                {
                    Job optJob = result.Job;
                    Log.Message(pawn + " JobDriver_GearUpAndGo job " + optJob);
                    if (optJob.def == JobDefOf.Wear)
                    {
                        pawn.Reserve(optJob.targetA, optJob);
                    }
                    pawn.jobs.jobQueue.EnqueueFirst(new Job(GearUpAndGoJobDefOf.GearUpAndGo, TargetA));
                    pawn.jobs.jobQueue.EnqueueFirst(optJob);
                }
            };
            yield return(toil);
        }
Ejemplo n.º 12
0
        public static bool ApparelScoreGain_NewTmp(ref float __result, Pawn pawn, Apparel ap, List <float> wornScoresCache)
        {
            if (ap is ShieldBelt && pawn.equipment.Primary != null && pawn.equipment.Primary.def.IsWeaponUsingProjectiles)
            {
                __result = -1000f;
                return(false);
            }

            float          num         = JobGiver_OptimizeApparel.ApparelScoreRaw(pawn, ap);
            List <Apparel> wornApparel = pawn.apparel.WornApparel;
            bool           flag        = false;

            for (int i = 0; i < wornApparel.Count; i++)
            {
                Apparel apparel;
                try
                {
                    apparel = wornApparel[i];
                }
                catch (ArgumentOutOfRangeException)
                {
                    break;
                }
                if (!ApparelUtility.CanWearTogether(apparel.def, ap.def, pawn.RaceProps.body))
                {
                    if (!pawn.outfits.forcedHandler.AllowedToAutomaticallyDrop(apparel) || pawn.apparel.IsLocked(apparel))
                    {
                        __result = -1000f;
                        return(false);
                    }

                    num -= wornScoresCache[i];
                    flag = true;
                }
            }

            if (!flag)
            {
                num *= 10f;
            }

            __result = num;
            return(false);
        }
        private static void Postfix(Thing __instance)
        {
            if (!OutfitManagerMod.ShowApparelScores)
            {
                return;
            }
            if (Find.CameraDriver.CurrentZoom != CameraZoomRange.Closest)
            {
                return;
            }
            if (!(Find.Selector.SingleSelectedThing is Pawn pawn) || !pawn.IsColonistPlayerControlled)
            {
                return;
            }
            if (!(__instance is Apparel apparel))
            {
                return;
            }
            if (!(pawn.outfits.CurrentOutfit is ExtendedOutfit outfit))
            {
                return;
            }
            if (!outfit.filter.Allows(apparel))
            {
                return;
            }
            var wornApparelScores = pawn.apparel.WornApparel
                                    .Select(wornApparel => OutfitManagerMod.ApparelScoreRaw(pawn, wornApparel)).ToList();
            var score = JobGiver_OptimizeApparel.ApparelScoreGain_NewTmp(pawn, apparel, wornApparelScores);

            if (!(Math.Abs(score) > 0.01f))
            {
                return;
            }
            var pos = GenMapUI.LabelDrawPosFor(apparel, 0f);

            GenMapUI.DrawThingLabel(pos, score.ToString("F1", CultureInfo.InvariantCulture),
                                    BeautyDrawer.BeautyColor(score, 3f));
        }
        // RimWorld.JobGiver_OptimizeApparel

        /*
         *  PreFix
         *
         *  This code prevents prisoners/colonists from automatically changing
         *  out of straitjackets into other clothes.
         *
         */
        public static bool SetNextOptimizeTickPreFix(JobGiver_OptimizeApparel __instance, Pawn pawn)
        {
            if (pawn != null)
            {
                if (pawn.outfits != null)
                {
                    Outfit         currentOutfit = pawn.outfits.CurrentOutfit;
                    List <Apparel> wornApparel   = pawn.apparel.WornApparel;
                    if (wornApparel != null)
                    {
                        if (wornApparel.Count > 0)
                        {
                            if (wornApparel.FirstOrDefault((Apparel x) => x.def == StraitjacketDefOf.ROM_Straitjacket) != null)
                            {
                                return(false);
                            }
                        }
                    }
                }
            }
            return(true);
        }
Ejemplo n.º 15
0
        private void AddApparelToLinkedList(Apparel apparel, LinkedList <Apparel> l)
        {
            if (!l.Contains(apparel))
            {
                float score = JobGiver_OptimizeApparel.ApparelScoreRaw(null, apparel);
                for (LinkedListNode <Apparel> n = l.First; n != null; n = n.Next)
                {
                    float nScore = JobGiver_OptimizeApparel.ApparelScoreRaw(null, apparel);
                    if (score >= nScore)
                    {
                        l.AddBefore(n, apparel);
                        return;
                    }
                    else if (score < nScore)
                    {
                        l.AddAfter(n, apparel);
                        return;
                    }
                }
                l.AddLast(apparel);
            }

            /*
             #if TRACE
             * Log.Message("Start StoredApparel.AddApparelToLinkedList");
             * Log.Warning("Apparel: " + apparel.Label);
             * StringBuilder sb = new StringBuilder("LinkedList: ");
             * foreach (Apparel a in l)
             * {
             *  sb.Append(a.LabelShort);
             *  sb.Append(", ");
             * }
             * Log.Warning(sb.ToString());
             #endif
             * QualityCategory q;
             * if (!apparel.TryGetQuality(out q))
             * {
             #if TRACE
             *  Log.Message("AddLast - quality not found");
             #endif
             *  l.AddLast(apparel);
             * }
             * else
             * {
             #if TRACE
             *  Log.Message("HP: " + apparel.HitPoints + " HPMax: " + apparel.MaxHitPoints);
             #endif
             *  int hpPercent = apparel.HitPoints / apparel.MaxHitPoints;
             *  for (LinkedListNode<Apparel> n = l.First; n != null; n = n.Next)
             *  {
             *      QualityCategory nq;
             *      if (!n.Value.TryGetQuality(out nq) ||
             *          q > nq ||
             *          (q == nq && hpPercent >= (n.Value.HitPoints / n.Value.MaxHitPoints)))
             *      {
             *          l.AddBefore(n, apparel);
             *          return;
             *      }
             *  }
             *  l.AddLast(apparel);
             * }
             #if TRACE
             * Log.Message("End StoredApparel.AddApparelToLinkedList");
             #endif
             */
        }
Ejemplo n.º 16
0
        public static void Postfix(Pawn pawn, ref Job __result, JobGiver_OptimizeApparel __instance)
        {
            if (__result == null)
            {
                return;
            }

            CompAwesomeInventoryLoadout comp = pawn.TryGetComp <CompAwesomeInventoryLoadout>();

            if (comp == null)
            {
                return;
            }

            Job   job          = __result;
            Thing targetThingA = job.targetA.Thing;

            if (comp.Loadout is AwesomeInventoryCostume costume)
            {
                if (__result.def == JobDefOf.Wear)
                {
                    if (targetThingA != null &&
                        !costume.CostumeItems.Any(s => s.Allows(targetThingA, out _)) &&
                        !costume.CostumeItems.All(s => ApparelUtility.CanWearTogether(targetThingA.def, s.AllowedThing, BodyDefOf.Human)))
                    {
                        __result = null;
                        JobMaker.ReturnToPool(job);
                        _setNextOptimizeTick.Invoke(__instance, new[] { pawn });
                        return;
                    }
                }
            }
            else if (comp.Loadout is AwesomeInventoryLoadout loadout)
            {
                CancellationTokenSource source = new CancellationTokenSource();
                CancellationToken       token  = source.Token;
                try
                {
                    bool conflict = false;

                    if (!loadout.Any(selector => selector.Allows(targetThingA, out _)))
                    {
                        Parallel.ForEach(
                            Partitioner.Create(pawn.apparel.WornApparel)
                            , (Apparel apparel) =>
                        {
                            if (!token.IsCancellationRequested &&
                                targetThingA != null &&
                                !ApparelUtility.CanWearTogether(apparel.def, targetThingA.def, BodyDefOf.Human))
                            {
                                if (comp.Loadout.Any(selector => selector.Allows(apparel, out _)))
                                {
                                    conflict = true;
                                    source.Cancel();
                                }
                            }
                        });
                    }

                    if (conflict)
                    {
                        __result = new DressJob(AwesomeInventory_JobDefOf.AwesomeInventory_Dress, targetThingA, false);
                        JobMaker.ReturnToPool(job);
                    }
                }
                catch (Exception e)
                {
                    __result = JobMaker.MakeJob(JobDefOf.Wear, targetThingA);
                }
                finally
                {
                    source.Dispose();
                }
            }
        }
Ejemplo n.º 17
0
        public static bool TryGiveJob(JobGiver_OptimizeApparel __instance, ref Job __result, Pawn pawn)
        {
            if (pawn.outfits == null)
            {
                Log.ErrorOnce(string.Concat(pawn, " tried to run JobGiver_OptimizeApparel without an OutfitTracker"), 5643897);
                __result = null;
                return(false);
            }

            if (pawn.Faction != Faction.OfPlayer)
            {
                Log.ErrorOnce(string.Concat("Non-colonist ", pawn, " tried to optimize apparel."), 764323);
                __result = null;
                return(false);
            }

            if (pawn.IsQuestLodger())
            {
                __result = null;
                return(false);
            }

            if (!DebugViewSettings.debugApparelOptimize)
            {
                if (Find.TickManager.TicksGame < pawn.mindState.nextApparelOptimizeTick)
                {
                    __result = null;
                    return(false);
                }
            }
            else
            {
                debugSb = new StringBuilder();
                debugSb.AppendLine(string.Concat("Scanning for ", pawn, " at ", pawn.Position));
            }

            Outfit         currentOutfit = pawn.outfits.CurrentOutfit;
            List <Apparel> wornApparel   = pawn.apparel.WornApparel;

            for (int num = wornApparel.Count - 1; num >= 0; num--)
            {
                if (!currentOutfit.filter.Allows(wornApparel[num]) && pawn.outfits.forcedHandler.AllowedToAutomaticallyDrop(wornApparel[num]) && !pawn.apparel.IsLocked(wornApparel[num]))
                {
                    Job job = JobMaker.MakeJob(JobDefOf.RemoveApparel, wornApparel[num]);
                    job.haulDroppedApparel = true;
                    __result = job;
                    return(false);
                }
            }

            Thing        thing = null;
            float        num2  = 0f;
            List <Thing> list  = pawn.Map.listerThings.ThingsInGroup(ThingRequestGroup.Apparel);

            if (list.Count == 0)
            {
                SetNextOptimizeTick2(pawn);
                __result = null;
                return(false);
            }

            neededWarmth = PawnApparelGenerator.CalculateNeededWarmth(pawn, pawn.Map.Tile, GenLocalDate.Twelfth(pawn));
            //wornApparelScores.Clear();
            List <float> wornApparelScores = new List <float>();

            for (int i = 0; i < wornApparel.Count; i++)
            {
                wornApparelScores.Add(JobGiver_OptimizeApparel.ApparelScoreRaw(pawn, wornApparel[i]));
            }

            for (int j = 0; j < list.Count; j++)
            {
                Apparel apparel = (Apparel)list[j];
                if (currentOutfit.filter.Allows(apparel) && apparel.IsInAnyStorage() && !apparel.IsForbidden(pawn) && !apparel.IsBurning() && (apparel.def.apparel.gender == Gender.None || apparel.def.apparel.gender == pawn.gender))
                {
                    float num3 = JobGiver_OptimizeApparel.ApparelScoreGain_NewTmp(pawn, apparel, wornApparelScores);
                    if (DebugViewSettings.debugApparelOptimize)
                    {
                        debugSb.AppendLine(apparel.LabelCap + ": " + num3.ToString("F2"));
                    }

                    if (!(num3 < 0.05f) && !(num3 < num2) && (!EquipmentUtility.IsBiocoded(apparel) || EquipmentUtility.IsBiocodedFor(apparel, pawn)) && ApparelUtility.HasPartsToWear(pawn, apparel.def) && pawn.CanReserveAndReach(apparel, PathEndMode.OnCell, pawn.NormalMaxDanger()))
                    {
                        thing = apparel;
                        num2  = num3;
                    }
                }
            }

            if (DebugViewSettings.debugApparelOptimize)
            {
                debugSb.AppendLine("BEST: " + thing);
                Log.Message(debugSb.ToString());
                debugSb = null;
            }

            if (thing == null)
            {
                SetNextOptimizeTick2(pawn);
                __result = null;
                return(false);
            }

            __result = JobMaker.MakeJob(JobDefOf.Wear, thing);
            return(false);
        }
Ejemplo n.º 18
0
        /// <inheritdoc/>
        public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams)
        {
            ValidateArg.NotNull(pawn, nameof(pawn));

            if (Find.TickManager.TicksGame < _optimizedTick)
            {
                return(ThinkResult.NoJob);
            }

            CompAwesomeInventoryLoadout comp = pawn.TryGetComp <CompAwesomeInventoryLoadout>();

            if (comp == null || !(comp.Loadout is AwesomeInventoryLoadout))
            {
                return(ThinkResult.NoJob);
            }

            List <Thing> list = pawn.inventory?.innerContainer?.ToList();

            if (list == null)
            {
                return(ThinkResult.NoJob);
            }

            if (!list.Any())
            {
                _optimizedTick = _optmizedInterval + Find.TickManager.TicksGame;
                return(ThinkResult.NoJob);
            }

            float bestScore = 0f;
            Thing thing     = null;

            for (int i = 0; i < list.Count; i++)
            {
                if (list[i] is Apparel apparel && ApparelOptionUtility.CanWear(pawn, apparel))
                {
                    if (comp.Loadout is AwesomeInventoryCostume costume)
                    {
                        if (!costume.CostumeItems.Any(c => c.Allows(apparel, out _)))
                        {
                            continue;
                        }
                    }

                    float score = JobGiver_OptimizeApparel.ApparelScoreGain(pawn, apparel);
                    if (!(score < 0.05f) && !(score < bestScore))
                    {
                        thing     = apparel;
                        bestScore = score;
                    }
                }
            }

            if (thing == null)
            {
                _optimizedTick = _optmizedInterval + Find.TickManager.TicksGame;
                return(ThinkResult.NoJob);
            }
            else
            {
                return(new ThinkResult(new DressJob(AwesomeInventory_JobDefOf.AwesomeInventory_Dress, thing, false), this, JobTag.ChangingApparel));
            }
        }
Ejemplo n.º 19
0
        public static void OptimizeApparel(Pawn pawn)
        {
            if (!WorldComp.HasDressers(pawn.Map))
            {
                // When pawns are not on the home map they will not get dressed using the game's normal method

                // This logic works but pawns will run back to the dresser to change cloths
                foreach (ThingDef def in pawn.outfits.CurrentOutfit.filter.AllowedThingDefs)
                {
#if TRACE && SWAP_APPAREL
                    Log.Warning("        Try Find Def " + def.label);
#endif
                    if (pawn.apparel.CanWearWithoutDroppingAnything(def))
                    {
#if TRACE && SWAP_APPAREL
                        Log.Warning("        Can Wear. Check Dressers for apparel:");
#endif
                        foreach (Building_Dresser d in WorldComp.DressersToUse)
                        {
#if TRACE && SWAP_APPAREL
                            Log.Warning("            " + d.Label);
#endif
                            Apparel apparel;
                            if (d.TryRemoveBestApparel(def, pawn.outfits.CurrentOutfit.filter, out apparel))
                            {
                                WorldComp.ApparelColorTracker.RemoveApparel(apparel);
#if TRACE && SWAP_APPAREL
                                Log.Warning("            Found : " + apparel.Label);
#endif
                                pawn.apparel.Wear(apparel);
                                break;
                            }
#if TRACE && SWAP_APPAREL
                            else
                            {
                                Log.Warning("            No matching apparel found");
                            }
#endif
                        }
                    }
#if TRACE && SWAP_APPAREL
                    else
                    {
                        Log.Warning("        Can't wear");
                    }
#endif
                }
                return;
            }

#if DRESSER_OUTFIT
            Log.Warning("Begin OptimizeApparelUtil.OptimizeApparel(Pawn: " + pawn.Name + ")");
#endif
            MethodInfo mi = typeof(JobGiver_OptimizeApparel).GetMethod("TryGiveJob", BindingFlags.Instance | BindingFlags.NonPublic);
            JobGiver_OptimizeApparel apparelOptimizer = new JobGiver_OptimizeApparel();
            object[] param = new object[] { pawn };

            for (int i = 0; i < 10; ++i)
            {
#if TRACE && DRESSER_OUTFIT
                Log.Message(i + " start equip for loop");
#endif
                Job job = mi.Invoke(apparelOptimizer, param) as Job;
#if TRACE && DRESSER_OUTFIT
                Log.Message(i + " job is null: " + (string)((job == null) ? "yes" : "no"));
#endif
                if (job == null)
                {
                    break;
                }
#if TRACE && DRESSER_OUTFIT
                Log.Message(job.def.defName);
#endif
                if (job.def == JobDefOf.Wear)
                {
                    Apparel a = ((job.targetB != null) ? job.targetB.Thing : null) as Apparel;
                    if (a == null)
                    {
                        Log.Warning("ChangeDresser: OptimizeApparelUtil.OptimizeApparel: Problem equiping pawn. Apparel is null.");
                        break;
                    }
#if TRACE && DRESSER_OUTFIT
                    Log.Message("Wear from ground " + a.Label);
#endif
                    pawn.apparel.Wear(a);
                }
                else if (job.def == Building_Dresser.WEAR_APPAREL_FROM_DRESSER_JOB_DEF)
                {
                    Building_Dresser d = ((job.targetA != null) ? job.targetA.Thing : null) as Building_Dresser;
                    Apparel          a = ((job.targetB != null) ? job.targetB.Thing : null) as Apparel;

                    if (d == null || a == null)
                    {
                        Log.Warning("ChangeDresser: OptimizeApparelUtil.OptimizeApparel: Problem equiping pawn. Dresser or Apparel is null.");
                        break;
                    }
#if TRACE && DRESSER_OUTFIT
                    Log.Message("Wear from dresser " + d.Label + " " + a.Label);
#endif
                    d.RemoveNoDrop(a);
                    pawn.apparel.Wear(a);
                }
#if TRACE && DRESSER_OUTFIT
                Log.Message(i + " end equip for loop");
#endif
            }
#if DRESSER_OUTFIT
            Log.Warning("End OptimizeApparelUtil.OptimizeApparel");
#endif
        }
Ejemplo n.º 20
0
        public static bool FindBetterApparel(
            ref float baseApparelScore, ref Apparel betterApparel, Pawn pawn, Outfit currentOutfit, IEnumerable <Apparel> apparelToCheck, Building dresser)
        {
            if (betterApparel == null)
            {
                baseApparelScore = 0f;
            }
#if BETTER_OUTFIT
            Log.Warning("Begin ApparelUtil.FindBetterApparel(Score: " + baseApparelScore + "    Apparel: " + ((betterApparel == null) ? "<null>" : betterApparel.Label));
#endif
            bool result = false;
#if TRACE && BETTER_OUTFIT
            Log.Message("    Apparel:");
#endif
            foreach (Apparel apparel in apparelToCheck)
            {
#if TRACE && BETTER_OUTFIT
                Log.Message("        " + ((apparel == null) ? "<null>" : apparel.Label));
#endif
                if (!currentOutfit.filter.Allows(apparel.def))
                {
#if TRACE && BETTER_OUTFIT
                    Log.Message("        Filters does not allow");
#endif
                    break;
                }
                if (!currentOutfit.filter.Allows(apparel) ||
                    apparel.IsForbidden(pawn))
                {
#if TRACE && BETTER_OUTFIT
                    Log.Message("        Current Outfit Does Not Allow: " + !currentOutfit.filter.Allows(apparel) + "    or     Is Forbidden: " + apparel.IsForbidden(pawn));
#endif
                    continue;
                }

#if TRACE && BETTER_OUTFIT
                Log.Message("        Keep Forced Apparel: " + Settings.KeepForcedApparel);
#endif
                if (Settings.KeepForcedApparel)
                {
                    bool           skipApparelType = false;
                    List <Apparel> wornApparel     = pawn.apparel.WornApparel;
                    for (int i = 0; i < wornApparel.Count; i++)
                    {
                        if (!ApparelUtility.CanWearTogether(wornApparel[i].def, apparel.def, pawn.RaceProps.body) &&
                            !pawn.outfits.forcedHandler.IsForced(wornApparel[i]))
                        {
#if TRACE && BETTER_OUTFIT
                            Log.Message("        Cannot wear together");
#endif
                            skipApparelType = true;
                            break;
                        }
                    }
                    if (skipApparelType)
                    {
                        break;
                    }
                }

                float gain = JobGiver_OptimizeApparel.ApparelScoreGain(pawn, apparel);
#if TRACE && BETTER_OUTFIT
                Log.Message("    Gain: " + gain + "     Base Score: " + baseApparelScore);
#endif
                if (gain >= 0.05f && gain > baseApparelScore)
                {
#if TRACE && BETTER_OUTFIT
                    Log.Message("    Gain is better");
#endif
                    if (ApparelUtility.HasPartsToWear(pawn, apparel.def))
                    {
#if TRACE && BETTER_OUTFIT
                        Log.Message("    Has parts to wear");
#endif
                        if (dresser == null ||
                            ReservationUtility.CanReserveAndReach(pawn, dresser, PathEndMode.OnCell, pawn.NormalMaxDanger(), 1))
                        {
#if TRACE && BETTER_OUTFIT
                            Log.Message("    Can reach dresser");
#endif
                            betterApparel    = apparel;
                            baseApparelScore = gain;
                            result           = true;
                        }
                    }
                }
            }
#if BETTER_OUTFIT
            Log.Warning("End ApparelUtil.FindBetterApparel    result = " + result);
#endif
            return(result);
        }
Ejemplo n.º 21
0
        /// <inheritdoc/>
        public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams)
        {
            ValidateArg.NotNull(pawn, nameof(pawn));

            if (Find.TickManager.TicksGame < _optimizedTick)
            {
                return(ThinkResult.NoJob);
            }

            CompAwesomeInventoryLoadout comp = pawn.TryGetComp <CompAwesomeInventoryLoadout>();

            if (comp?.Loadout == null || comp.Loadout.GetType() == typeof(AwesomeInventoryCostume))
            {
                return(ThinkResult.NoJob);
            }

            List <Thing> list = pawn.inventory?.innerContainer?.ToList();

            if (list == null)
            {
                return(ThinkResult.NoJob);
            }

            if (!list.Any())
            {
                _optimizedTick = _optmizedInterval + Find.TickManager.TicksGame;
                return(ThinkResult.NoJob);
            }

            List <Apparel> wornApparels = pawn.apparel?.WornApparel;

            if (wornApparels == null)
            {
                return(ThinkResult.NoJob);
            }

            AwesomeInventoryCostume costume = comp.Loadout as AwesomeInventoryCostume;

            var thingList = list
                            .Where(t => t is Apparel apparel && ApparelOptionUtility.CanWear(pawn, apparel))
                            .Select(t => new { thing = t, score = JobGiver_OptimizeApparel.ApparelScoreGain(pawn, (Apparel)t) })
                            .Where(thingScore => thingScore.score > 0.05f)
                            .OrderByDescending(s => s.score)
                            .ToList();

            if (!thingList.Any())
            {
                _optimizedTick = _optmizedInterval + Find.TickManager.TicksGame;
                return(ThinkResult.NoJob);
            }

            List <Apparel> wornCostume = null;

            if (costume != null)
            {
                wornCostume = pawn.apparel.WornApparel
                              .AsParallel()
                              .Where(a => costume.CostumeItems.Any(c => c.Allows(a, out _)))
                              .ToList();
            }

            foreach (var t in thingList)
            {
                Thing thing = null;

                if (costume == null)
                {
                    thing = t.thing;
                }
                else
                {
                    foreach (ThingGroupSelector selector in costume.CostumeItems)
                    {
                        if (selector.Allows(t.thing, out _))
                        {
                            thing = t.thing;
                            break;
                        }
                    }

                    if (thing == null)
                    {
                        if (wornCostume.NullOrEmpty() || wornCostume.All(c => ApparelUtility.CanWearTogether(c.def, t.thing.def, BodyDefOf.Human)))
                        {
                            thing = t.thing;
                        }
                    }
                }

                if (thing != null)
                {
                    return(new ThinkResult(
                               new DressJob(AwesomeInventory_JobDefOf.AwesomeInventory_Dress, thing, false)
                               , this
                               , JobTag.ChangingApparel));
                }
            }

            _optimizedTick = _optmizedInterval + Find.TickManager.TicksGame;
            return(ThinkResult.NoJob);
        }
Ejemplo n.º 22
0
        static void Postfix(Pawn pawn, ref bool __state, ref Job __result)
        {
            if (!__state)
            {
                return;
            }

#if BETTER_OUTFIT
            Log.Warning("Begin JobGiver_OptimizeApparel.Postfix(Pawn: " + pawn.Name.ToStringShort + "     Job: " + ((__result == null) ? "<null>" : __result.ToString()) + ")");
#endif
            if (!DoDressersHaveApparel() || pawn.apparel?.LockedApparel?.Count > 0)
            {
                return;
            }

            Thing thing            = null;
            float baseApparelScore = 0f;
            if (__result != null && __result.targetA.Thing is Apparel)
            {
                thing            = __result.targetA.Thing;
                baseApparelScore = JobGiver_OptimizeApparel.ApparelScoreGain(pawn, thing as Apparel);
                if (thing == null)
                {
                    baseApparelScore = 0f;
                }
                else
                {
#if BETTER_OUTFIT
                    Log.Message("    Game Found Better Apparel: " + ((thing == null) ? "<null>" : thing.Label) + "    Score: " + baseApparelScore);
#endif
                }
            }

            Apparel          a = null;
            Building_Dresser containingDresser = null;

#if BETTER_OUTFIT
            Log.Message("    Loop Through Dressers:");
#endif
            foreach (Building_Dresser dresser in WorldComp.DressersToUse)
            {
#if TRACE && BETTER_OUTFIT
                Log.Message("        Dresser: " + dresser.Label);
#endif
                float score = baseApparelScore;
                if (dresser.FindBetterApparel(ref score, ref a, pawn, pawn.outfits.CurrentOutfit))
                {
                    thing             = a;
                    baseApparelScore  = score;
                    containingDresser = dresser;
#if BETTER_OUTFIT
                    Log.Message("    Dresser Found Better Apparel: " + ((a == null) ? "<null>" : a.Label) + "    Score: " + baseApparelScore);
#endif
                }
            }
#if BETTER_OUTFIT
            Log.Message("    Best Apparel: " + ((a == null) ? "<null>" : a.Label) + "    Score: " + baseApparelScore);
#endif
            if (a != null && containingDresser != null)
            {
                __result = new Job(containingDresser.wearApparelFromStorageJobDef, containingDresser, a);
            }
#if BETTER_OUTFIT
            Log.Warning("End JobGiver_OptimizeApparel.Postfix");
#endif
        }
Ejemplo n.º 23
0
        private string CurrentDebugString()
        {
            StringBuilder stringBuilder = new StringBuilder();

            if (DebugViewSettings.writeGame)
            {
                stringBuilder.AppendLine("---");
                stringBuilder.AppendLine((Current.Game != null) ? Current.Game.DebugString() : "Current.Game = null");
            }
            if (DebugViewSettings.writeMusicManagerPlay)
            {
                stringBuilder.AppendLine("---");
                stringBuilder.AppendLine(Find.MusicManagerPlay.DebugString());
            }
            if (DebugViewSettings.writePlayingSounds)
            {
                stringBuilder.AppendLine("---");
                stringBuilder.AppendLine("Sustainers:");
                foreach (Sustainer sustainer in Find.SoundRoot.sustainerManager.AllSustainers)
                {
                    stringBuilder.AppendLine(sustainer.DebugString());
                }
                stringBuilder.AppendLine();
                stringBuilder.AppendLine("OneShots:");
                foreach (SampleOneShot sampleOneShot in Find.SoundRoot.oneShotManager.PlayingOneShots)
                {
                    stringBuilder.AppendLine(sampleOneShot.ToString());
                }
            }
            if (DebugViewSettings.writeSoundEventsRecord)
            {
                stringBuilder.AppendLine("---");
                stringBuilder.AppendLine("Recent sound events:\n       ...");
                stringBuilder.AppendLine(DebugSoundEventsLog.EventsListingDebugString);
            }
            if (DebugViewSettings.writeSteamItems)
            {
                stringBuilder.AppendLine("---");
                stringBuilder.AppendLine(WorkshopItems.DebugOutput());
            }
            if (DebugViewSettings.writeConcepts)
            {
                stringBuilder.AppendLine("---");
                stringBuilder.AppendLine(LessonAutoActivator.DebugString());
            }
            if (DebugViewSettings.writeMemoryUsage)
            {
                stringBuilder.AppendLine("---");
                stringBuilder.AppendLine("Total allocated: " + Profiler.GetTotalAllocatedMemoryLong().ToStringBytes("F2"));
                stringBuilder.AppendLine("Total reserved: " + Profiler.GetTotalReservedMemoryLong().ToStringBytes("F2"));
                stringBuilder.AppendLine("Total reserved unused: " + Profiler.GetTotalUnusedReservedMemoryLong().ToStringBytes("F2"));
                stringBuilder.AppendLine("Mono heap size: " + Profiler.GetMonoHeapSizeLong().ToStringBytes("F2"));
                stringBuilder.AppendLine("Mono used size: " + Profiler.GetMonoUsedSizeLong().ToStringBytes("F2"));
            }
            if (Current.ProgramState == ProgramState.Playing)
            {
                stringBuilder.AppendLine("Tick " + Find.TickManager.TicksGame);
                if (DebugViewSettings.writeStoryteller)
                {
                    stringBuilder.AppendLine("---");
                    stringBuilder.AppendLine(Find.Storyteller.DebugString());
                }
            }
            if (Current.ProgramState == ProgramState.Playing && Find.CurrentMap != null)
            {
                if (DebugViewSettings.writeMapGameConditions)
                {
                    stringBuilder.AppendLine("---");
                    stringBuilder.AppendLine(Find.CurrentMap.gameConditionManager.DebugString());
                }
                if (DebugViewSettings.drawPawnDebug)
                {
                    stringBuilder.AppendLine("---");
                    stringBuilder.AppendLine(Find.CurrentMap.reservationManager.DebugString());
                }
                if (DebugViewSettings.writeMoteSaturation)
                {
                    stringBuilder.AppendLine("---");
                    stringBuilder.AppendLine("Mote count: " + Find.CurrentMap.moteCounter.MoteCount);
                    stringBuilder.AppendLine("Mote saturation: " + Find.CurrentMap.moteCounter.Saturation);
                }
                if (DebugViewSettings.writeEcosystem)
                {
                    stringBuilder.AppendLine("---");
                    stringBuilder.AppendLine(Find.CurrentMap.wildAnimalSpawner.DebugString());
                }
                if (DebugViewSettings.writeTotalSnowDepth)
                {
                    stringBuilder.AppendLine("---");
                    stringBuilder.AppendLine("Total snow depth: " + Find.CurrentMap.snowGrid.TotalDepth);
                }
                if (DebugViewSettings.writeWind)
                {
                    stringBuilder.AppendLine("---");
                    stringBuilder.AppendLine(Find.CurrentMap.windManager.DebugString());
                }
                if (DebugViewSettings.writeRecentStrikes)
                {
                    stringBuilder.AppendLine("---");
                    stringBuilder.AppendLine(Find.CurrentMap.mineStrikeManager.DebugStrikeRecords());
                }
                if (DebugViewSettings.writeListRepairableBldgs)
                {
                    stringBuilder.AppendLine("---");
                    stringBuilder.AppendLine(Find.CurrentMap.listerBuildingsRepairable.DebugString());
                }
                if (DebugViewSettings.writeListFilthInHomeArea)
                {
                    stringBuilder.AppendLine("---");
                    stringBuilder.AppendLine(Find.CurrentMap.listerFilthInHomeArea.DebugString());
                }
                if (DebugViewSettings.writeListHaulables)
                {
                    stringBuilder.AppendLine("---");
                    stringBuilder.AppendLine(Find.CurrentMap.listerHaulables.DebugString());
                }
                if (DebugViewSettings.writeListMergeables)
                {
                    stringBuilder.AppendLine("---");
                    stringBuilder.AppendLine(Find.CurrentMap.listerMergeables.DebugString());
                }
                if (DebugViewSettings.drawLords)
                {
                    foreach (Lord lord in Find.CurrentMap.lordManager.lords)
                    {
                        stringBuilder.AppendLine("---");
                        stringBuilder.AppendLine(lord.DebugString());
                    }
                }
                IntVec3 intVec = UI.MouseCell();
                if (intVec.InBounds(Find.CurrentMap))
                {
                    stringBuilder.AppendLine("Inspecting " + intVec.ToString());
                    if (DebugViewSettings.writeTerrain)
                    {
                        stringBuilder.AppendLine("---");
                        stringBuilder.AppendLine(Find.CurrentMap.terrainGrid.DebugStringAt(intVec));
                    }
                    if (DebugViewSettings.writeAttackTargets)
                    {
                        foreach (Pawn pawn in Find.CurrentMap.thingGrid.ThingsAt(UI.MouseCell()).OfType <Pawn>())
                        {
                            stringBuilder.AppendLine("---");
                            stringBuilder.AppendLine("Potential attack targets for " + pawn.LabelShort + ":");
                            List <IAttackTarget> potentialTargetsFor = Find.CurrentMap.attackTargetsCache.GetPotentialTargetsFor(pawn);
                            for (int i = 0; i < potentialTargetsFor.Count; i++)
                            {
                                Thing thing = (Thing)potentialTargetsFor[i];
                                stringBuilder.AppendLine(string.Concat(new object[]
                                {
                                    thing.LabelShort,
                                    ", ",
                                    thing.Faction,
                                    (!potentialTargetsFor[i].ThreatDisabled(null)) ? "" : " (threat disabled)"
                                }));
                            }
                        }
                    }
                    if (DebugViewSettings.writeSnowDepth)
                    {
                        stringBuilder.AppendLine("---");
                        stringBuilder.AppendLine("Snow depth: " + Find.CurrentMap.snowGrid.GetDepth(intVec));
                    }
                    if (DebugViewSettings.drawDeepResources)
                    {
                        stringBuilder.AppendLine("---");
                        stringBuilder.AppendLine("Deep resource def: " + Find.CurrentMap.deepResourceGrid.ThingDefAt(intVec));
                        stringBuilder.AppendLine("Deep resource count: " + Find.CurrentMap.deepResourceGrid.CountAt(intVec));
                    }
                    if (DebugViewSettings.writeCanReachColony)
                    {
                        stringBuilder.AppendLine("---");
                        stringBuilder.AppendLine("CanReachColony: " + Find.CurrentMap.reachability.CanReachColony(UI.MouseCell()));
                    }
                    if (DebugViewSettings.writeMentalStateCalcs)
                    {
                        stringBuilder.AppendLine("---");
                        foreach (Pawn pawn2 in (from t in Find.CurrentMap.thingGrid.ThingsAt(UI.MouseCell())
                                                where t is Pawn
                                                select t).Cast <Pawn>())
                        {
                            stringBuilder.AppendLine(pawn2.mindState.mentalBreaker.DebugString());
                        }
                    }
                    if (DebugViewSettings.writeWorkSettings)
                    {
                        foreach (Pawn pawn3 in (from t in Find.CurrentMap.thingGrid.ThingsAt(UI.MouseCell())
                                                where t is Pawn
                                                select t).Cast <Pawn>())
                        {
                            if (pawn3.workSettings != null)
                            {
                                stringBuilder.AppendLine("---");
                                stringBuilder.AppendLine(pawn3.workSettings.DebugString());
                            }
                        }
                    }
                    if (DebugViewSettings.writeApparelScore)
                    {
                        stringBuilder.AppendLine("---");
                        if (intVec.InBounds(Find.CurrentMap))
                        {
                            foreach (Thing thing2 in intVec.GetThingList(Find.CurrentMap))
                            {
                                Apparel apparel = thing2 as Apparel;
                                if (apparel != null)
                                {
                                    stringBuilder.AppendLine(apparel.Label + ": " + JobGiver_OptimizeApparel.ApparelScoreRaw(null, apparel).ToString("F2"));
                                }
                            }
                        }
                    }
                    if (DebugViewSettings.writeCellContents || this.fullMode)
                    {
                        stringBuilder.AppendLine("---");
                        if (intVec.InBounds(Find.CurrentMap))
                        {
                            foreach (Designation designation in Find.CurrentMap.designationManager.AllDesignationsAt(intVec))
                            {
                                stringBuilder.AppendLine(designation.ToString());
                            }
                            foreach (Thing thing3 in Find.CurrentMap.thingGrid.ThingsAt(intVec))
                            {
                                if (!this.fullMode)
                                {
                                    stringBuilder.AppendLine(thing3.LabelCap + " - " + thing3.ToString());
                                }
                                else
                                {
                                    stringBuilder.AppendLine(Scribe.saver.DebugOutputFor(thing3));
                                    stringBuilder.AppendLine();
                                }
                            }
                        }
                    }
                    if (DebugViewSettings.debugApparelOptimize)
                    {
                        stringBuilder.AppendLine("---");
                        foreach (Thing thing4 in Find.CurrentMap.thingGrid.ThingsAt(intVec))
                        {
                            Apparel apparel2 = thing4 as Apparel;
                            if (apparel2 != null)
                            {
                                stringBuilder.AppendLine(apparel2.LabelCap);
                                stringBuilder.AppendLine("   raw: " + JobGiver_OptimizeApparel.ApparelScoreRaw(null, apparel2).ToString("F2"));
                                Pawn pawn4 = Find.Selector.SingleSelectedThing as Pawn;
                                if (pawn4 != null)
                                {
                                    stringBuilder.AppendLine("  Pawn: " + pawn4);
                                    stringBuilder.AppendLine("  gain: " + JobGiver_OptimizeApparel.ApparelScoreGain(pawn4, apparel2).ToString("F2"));
                                }
                            }
                        }
                    }
                    if (DebugViewSettings.drawRegions)
                    {
                        stringBuilder.AppendLine("---");
                        Region regionAt_NoRebuild_InvalidAllowed = Find.CurrentMap.regionGrid.GetRegionAt_NoRebuild_InvalidAllowed(intVec);
                        stringBuilder.AppendLine("Region:\n" + ((regionAt_NoRebuild_InvalidAllowed == null) ? "null" : regionAt_NoRebuild_InvalidAllowed.DebugString));
                    }
                    if (DebugViewSettings.drawRooms)
                    {
                        stringBuilder.AppendLine("---");
                        Room room = intVec.GetRoom(Find.CurrentMap, RegionType.Set_All);
                        if (room != null)
                        {
                            stringBuilder.AppendLine(room.DebugString());
                        }
                        else
                        {
                            stringBuilder.AppendLine("(no room)");
                        }
                    }
                    if (DebugViewSettings.drawRoomGroups)
                    {
                        stringBuilder.AppendLine("---");
                        RoomGroup roomGroup = intVec.GetRoomGroup(Find.CurrentMap);
                        if (roomGroup != null)
                        {
                            stringBuilder.AppendLine(roomGroup.DebugString());
                        }
                        else
                        {
                            stringBuilder.AppendLine("(no room group)");
                        }
                    }
                    if (DebugViewSettings.drawGlow)
                    {
                        stringBuilder.AppendLine("---");
                        stringBuilder.AppendLine("Game glow: " + Find.CurrentMap.glowGrid.GameGlowAt(intVec, false));
                        stringBuilder.AppendLine("Psych glow: " + Find.CurrentMap.glowGrid.PsychGlowAt(intVec));
                        stringBuilder.AppendLine("Visual Glow: " + Find.CurrentMap.glowGrid.VisualGlowAt(intVec));
                        stringBuilder.AppendLine("GlowReport:\n" + ((SectionLayer_LightingOverlay)Find.CurrentMap.mapDrawer.SectionAt(intVec).GetLayer(typeof(SectionLayer_LightingOverlay))).GlowReportAt(intVec));
                        stringBuilder.AppendLine("SkyManager.CurSkyGlow: " + Find.CurrentMap.skyManager.CurSkyGlow);
                    }
                    if (DebugViewSettings.writePathCosts)
                    {
                        stringBuilder.AppendLine("---");
                        stringBuilder.AppendLine("Perceived path cost: " + Find.CurrentMap.pathGrid.PerceivedPathCostAt(intVec));
                        stringBuilder.AppendLine("Real path cost: " + Find.CurrentMap.pathGrid.CalculatedCostAt(intVec, false, IntVec3.Invalid));
                    }
                    if (DebugViewSettings.writeFertility)
                    {
                        stringBuilder.AppendLine("---");
                        stringBuilder.AppendLine("\nFertility: " + Find.CurrentMap.fertilityGrid.FertilityAt(intVec).ToString("##0.00"));
                    }
                    if (DebugViewSettings.writeLinkFlags)
                    {
                        stringBuilder.AppendLine("---");
                        stringBuilder.AppendLine("\nLinkFlags: ");
                        IEnumerator enumerator11 = Enum.GetValues(typeof(LinkFlags)).GetEnumerator();
                        try
                        {
                            while (enumerator11.MoveNext())
                            {
                                object obj = enumerator11.Current;
                                if ((Find.CurrentMap.linkGrid.LinkFlagsAt(intVec) & (LinkFlags)obj) != LinkFlags.None)
                                {
                                    stringBuilder.Append(" " + obj);
                                }
                            }
                        }
                        finally
                        {
                            IDisposable disposable;
                            if ((disposable = (enumerator11 as IDisposable)) != null)
                            {
                                disposable.Dispose();
                            }
                        }
                    }
                    if (DebugViewSettings.writeSkyManager)
                    {
                        stringBuilder.AppendLine("---");
                        stringBuilder.AppendLine(Find.CurrentMap.skyManager.DebugString());
                    }
                    if (DebugViewSettings.writeCover)
                    {
                        stringBuilder.AppendLine("---");
                        stringBuilder.Append("Cover: ");
                        Thing thing5 = Find.CurrentMap.coverGrid[intVec];
                        if (thing5 == null)
                        {
                            stringBuilder.AppendLine("null");
                        }
                        else
                        {
                            stringBuilder.AppendLine(thing5.ToString());
                        }
                    }
                    if (DebugViewSettings.drawPower)
                    {
                        stringBuilder.AppendLine("---");
                        foreach (Thing thing6 in Find.CurrentMap.thingGrid.ThingsAt(intVec))
                        {
                            ThingWithComps thingWithComps = thing6 as ThingWithComps;
                            if (thingWithComps != null && thingWithComps.GetComp <CompPowerTrader>() != null)
                            {
                                stringBuilder.AppendLine(" " + thingWithComps.GetComp <CompPowerTrader>().DebugString);
                            }
                        }
                        PowerNet powerNet = Find.CurrentMap.powerNetGrid.TransmittedPowerNetAt(intVec);
                        if (powerNet != null)
                        {
                            stringBuilder.AppendLine("" + powerNet.DebugString());
                        }
                        else
                        {
                            stringBuilder.AppendLine("(no PowerNet here)");
                        }
                    }
                    if (DebugViewSettings.drawPreyInfo)
                    {
                        Pawn pawn5 = Find.Selector.SingleSelectedThing as Pawn;
                        if (pawn5 != null)
                        {
                            List <Thing> thingList = intVec.GetThingList(Find.CurrentMap);
                            for (int j = 0; j < thingList.Count; j++)
                            {
                                Pawn pawn6 = thingList[j] as Pawn;
                                if (pawn6 != null)
                                {
                                    stringBuilder.AppendLine("---");
                                    if (FoodUtility.IsAcceptablePreyFor(pawn5, pawn6))
                                    {
                                        stringBuilder.AppendLine("Prey score: " + FoodUtility.GetPreyScoreFor(pawn5, pawn6));
                                    }
                                    else
                                    {
                                        stringBuilder.AppendLine("Prey score: None");
                                    }
                                    break;
                                }
                            }
                        }
                    }
                }
            }
            return(stringBuilder.ToString());
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            Toil toil = new Toil();

            toil.initAction = delegate
            {
                Pawn pawn = toil.actor;
                if (pawn.thinker == null)
                {
                    return;
                }

                //Find apparel
                JobGiver_OptimizeApparel optimizer = pawn.thinker.TryGetMainTreeThinkNode <JobGiver_OptimizeApparel>();
                if (optimizer == null)
                {
                    return;
                }

                pawn.mindState?.Notify_OutfitChanged();                                        // Lie so that it re-equips things
                ThinkResult result = optimizer.TryIssueJobPackage(pawn, new JobIssueParams()); //TryGiveJob is protected :(

                //Find loadout, Combat Extended
                if (result == ThinkResult.NoJob)
                {
                    if (CEloadoutGiverType != null)
                    {
                        if (CEloadoutGetter == null)
                        {
                            CEloadoutGetter = AccessTools.Method(typeof(Pawn_Thinker), nameof(Pawn_Thinker.TryGetMainTreeThinkNode)).MakeGenericMethod(new Type[] { CEloadoutGiverType });
                        }
                        if (CEloadoutGetter != null)
                        {
                            object CELoadoutGiver = CEloadoutGetter.Invoke(pawn.thinker, new object[] { });
                            if (CELoadoutGiver != null)
                            {
                                result = (ThinkResult)TryIssueJobPackageInfo.Invoke(CELoadoutGiver, new object[] { pawn, new JobIssueParams() });
                            }
                        }
                    }
                }
                //Find weapons, Weapons of Choice
                if (result == ThinkResult.NoJob)
                {
                    if (WOCGiverType != null)
                    {
                        if (WOCGetter == null)
                        {
                            WOCGetter = AccessTools.Method(typeof(Pawn_Thinker), nameof(Pawn_Thinker.TryGetMainTreeThinkNode)).MakeGenericMethod(new Type[] { WOCGiverType });
                        }
                        if (WOCGetter != null)
                        {
                            object WOCLoadoutGiver = WOCGetter.Invoke(pawn.thinker, new object[] { });
                            if (WOCLoadoutGiver != null)
                            {
                                result = (ThinkResult)TryIssueJobPackageInfo.Invoke(WOCLoadoutGiver, new object[] { pawn, new JobIssueParams() });
                            }
                        }
                    }
                }
                //Okay, nothing to do, go to target
                if (result == ThinkResult.NoJob)
                {
                    IntVec3 intVec = RCellFinder.BestOrderedGotoDestNear(TargetA.Cell, pawn);
                    Job     job    = new Job(JobDefOf.Goto, intVec);
                    if (pawn.Map.exitMapGrid.IsExitCell(UI.MouseCell()))
                    {
                        job.exitMapOnArrival = true;                         // I guess
                    }

                    if (!pawn.Drafted)
                    {
                        //Drafting clears the job queue. We want to keep the queue.
                        //It'll also return jobs to the pool, and clear each job too.
                        //So extract each job and clear the queue manually, then re-queue them all.

                        List <QueuedJob> queue = new List <QueuedJob>();
                        while (pawn.jobs.jobQueue.Count > 0)
                        {
                            queue.Add(pawn.jobs.jobQueue.Dequeue());
                        }

                        pawn.drafter.Drafted = true;

                        pawn.jobs.StartJob(job, JobCondition.Succeeded);

                        foreach (QueuedJob qj in queue)
                        {
                            pawn.jobs.jobQueue.EnqueueLast(qj.job, qj.tag);
                        }
                    }
                    else
                    {
                        pawn.jobs.StartJob(job, JobCondition.Succeeded);
                    }

                    MoteMaker.MakeStaticMote(intVec, pawn.Map, ThingDefOf.Mote_FeedbackGoto, 1f);
                }
                //Queue up the Gear job, then do another Gear+Go job
                else
                {
                    Job optJob = result.Job;
                    Log.Message($"{pawn} JobDriver_GearUpAndGo job {optJob}");
                    if (optJob.def == JobDefOf.Wear)
                    {
                        pawn.Reserve(optJob.targetA, optJob);
                    }
                    pawn.jobs.jobQueue.EnqueueFirst(new Job(GearUpAndGoJobDefOf.GearUpAndGo, TargetA));
                    pawn.jobs.jobQueue.EnqueueFirst(optJob);
                }
            };
            yield return(toil);
        }