static PawnApparelGenerator()
 {
     PawnApparelGenerator.allApparelPairs = new List <ThingStuffPair>();
     PawnApparelGenerator.workingSet      = new PossibleApparelSet();
     PawnApparelGenerator.usableApparel   = new List <ThingStuffPair>();
     PawnApparelGenerator.debugSb         = null;
     PawnApparelGenerator.Reset();
 }
Beispiel #2
0
        private static bool CanUsePair(ThingStuffPair pair, Pawn pawn, float moneyLeft, bool allowHeadgear, int fixedSeed)
        {
            bool result;

            if (pair.Price > moneyLeft)
            {
                result = false;
            }
            else if (!allowHeadgear && PawnApparelGenerator.IsHeadgear(pair.thing))
            {
                result = false;
            }
            else if (pair.stuff != null && pawn.Faction != null && !pawn.Faction.def.CanUseStuffForApparel(pair.stuff))
            {
                result = false;
            }
            else if (PawnApparelGenerator.workingSet.PairOverlapsAnything(pair))
            {
                result = false;
            }
            else
            {
                if (!pawn.kindDef.apparelTags.NullOrEmpty <string>())
                {
                    bool flag = false;
                    for (int i = 0; i < pawn.kindDef.apparelTags.Count; i++)
                    {
                        for (int j = 0; j < pair.thing.apparel.tags.Count; j++)
                        {
                            if (pawn.kindDef.apparelTags[i] == pair.thing.apparel.tags[j])
                            {
                                flag = true;
                                break;
                            }
                        }
                        if (flag)
                        {
                            break;
                        }
                    }
                    if (!flag)
                    {
                        return(false);
                    }
                }
                if (pair.thing.generateAllowChance < 1f)
                {
                    if (!Rand.ChanceSeeded(pair.thing.generateAllowChance, fixedSeed ^ (int)pair.thing.shortHash ^ 64128343))
                    {
                        return(false);
                    }
                }
                result = true;
            }
            return(result);
        }
 public static bool IsDerpAndDisallowed(ThingDef thing, ThingDef stuff, QualityGenerator?qualityGenerator)
 {
     if (qualityGenerator == QualityGenerator.Gift || qualityGenerator == QualityGenerator.Reward || qualityGenerator == QualityGenerator.Super)
     {
         if (!PawnWeaponGenerator.IsDerpWeapon(thing, stuff))
         {
             return(PawnApparelGenerator.IsDerpApparel(thing, stuff));
         }
         return(true);
     }
     return(false);
 }
Beispiel #4
0
        private static NeededWarmth ApparelWarmthNeededNow(Pawn pawn, PawnGenerationRequest request, out float mapTemperature)
        {
            int tile = request.Tile;

            if (tile == -1)
            {
                Map anyPlayerHomeMap = Find.AnyPlayerHomeMap;
                if (anyPlayerHomeMap != null)
                {
                    tile = anyPlayerHomeMap.Tile;
                }
            }
            NeededWarmth result;

            if (tile == -1)
            {
                mapTemperature = 21f;
                result         = NeededWarmth.Any;
            }
            else
            {
                NeededWarmth neededWarmth = NeededWarmth.Any;
                Twelfth      twelfth      = GenLocalDate.Twelfth(tile);
                mapTemperature = GenTemperature.AverageTemperatureAtTileForTwelfth(tile, twelfth);
                for (int i = 0; i < 2; i++)
                {
                    NeededWarmth neededWarmth2 = PawnApparelGenerator.CalculateNeededWarmth(pawn, tile, twelfth);
                    if (neededWarmth2 != NeededWarmth.Any)
                    {
                        neededWarmth = neededWarmth2;
                        break;
                    }
                    twelfth = twelfth.NextTwelfth();
                }
                if (pawn.kindDef.apparelIgnoreSeasons)
                {
                    if (request.ForceAddFreeWarmLayerIfNeeded && neededWarmth == NeededWarmth.Warm)
                    {
                        result = neededWarmth;
                    }
                    else
                    {
                        result = NeededWarmth.Any;
                    }
                }
                else
                {
                    result = neededWarmth;
                }
            }
            return(result);
        }
        internal static void LogHeadwearApparelPairs()
        {
            StringBuilder stringBuilder = new StringBuilder();

            stringBuilder.AppendLine("Listing all entries in allApparelPairs of headwear");
            foreach (ThingStuffPair current in from pa in PawnApparelGenerator.allApparelPairs
                     where PawnApparelGenerator.IsHeadwear(pa.thing)
                     orderby pa.thing.defName
                     select pa)
            {
                stringBuilder.AppendLine(current + "  - " + current.commonalityMultiplier);
            }
            Log.Message(stringBuilder.ToString());
        }
        private static void GenerateWorkingPossibleApparelSetFor(Pawn pawn, float money, bool headwearAllowed)
        {
            PawnApparelGenerator.workingSet.Reset(pawn.RaceProps.body, pawn.def);
            float           num        = money;
            List <ThingDef> reqApparel = pawn.kindDef.apparelRequired;

            if (reqApparel != null)
            {
                int i;
                for (i = 0; i < reqApparel.Count; i++)
                {
                    ThingStuffPair pair = (from pa in PawnApparelGenerator.allApparelPairs
                                           where pa.thing == reqApparel[i]
                                           select pa).RandomElementByWeight((ThingStuffPair pa) => pa.Commonality);
                    PawnApparelGenerator.workingSet.Add(pair);
                    num -= pair.Price;
                }
            }
            int @int = Rand.Int;

            while (Rand.Value >= 0.1f)
            {
                PawnApparelGenerator.usableApparel.Clear();
                for (int j = 0; j < PawnApparelGenerator.allApparelPairs.Count; j++)
                {
                    ThingStuffPair thingStuffPair = PawnApparelGenerator.allApparelPairs[j];
                    if (PawnApparelGenerator.CanUsePair(thingStuffPair, pawn, num, headwearAllowed, @int))
                    {
                        PawnApparelGenerator.usableApparel.Add(thingStuffPair);
                    }
                }
                ThingStuffPair pair2;
                bool           flag = PawnApparelGenerator.usableApparel.TryRandomElementByWeight((ThingStuffPair pa) => pa.Commonality, out pair2);
                PawnApparelGenerator.usableApparel.Clear();
                if (!flag)
                {
                    return;
                }
                PawnApparelGenerator.workingSet.Add(pair2);
                num -= pair2.Price;
            }
        }
 internal static void MakeTableWeaponPairsByThing()
 {
     PawnApparelGenerator.MakeTablePairsByThing(PawnWeaponGenerator.allWeaponPairs);
 }
Beispiel #8
0
        protected override Job TryGiveJob(Pawn pawn)
        {
            Job result;

            if (pawn.outfits == null)
            {
                Log.ErrorOnce(pawn + " tried to run JobGiver_OptimizeApparel without an OutfitTracker", 5643897, false);
                result = null;
            }
            else if (pawn.Faction != Faction.OfPlayer)
            {
                Log.ErrorOnce("Non-colonist " + pawn + " tried to optimize apparel.", 764323, false);
                result = null;
            }
            else
            {
                if (!DebugViewSettings.debugApparelOptimize)
                {
                    if (Find.TickManager.TicksGame < pawn.mindState.nextApparelOptimizeTick)
                    {
                        return(null);
                    }
                }
                else
                {
                    JobGiver_OptimizeApparel.debugSb = new StringBuilder();
                    JobGiver_OptimizeApparel.debugSb.AppendLine(string.Concat(new object[]
                    {
                        "Scanning for ",
                        pawn,
                        " at ",
                        pawn.Position
                    }));
                }
                Outfit         currentOutfit = pawn.outfits.CurrentOutfit;
                List <Apparel> wornApparel   = pawn.apparel.WornApparel;
                for (int i = wornApparel.Count - 1; i >= 0; i--)
                {
                    if (!currentOutfit.filter.Allows(wornApparel[i]) && pawn.outfits.forcedHandler.AllowedToAutomaticallyDrop(wornApparel[i]))
                    {
                        return(new Job(JobDefOf.RemoveApparel, wornApparel[i])
                        {
                            haulDroppedApparel = true
                        });
                    }
                }
                Thing        thing = null;
                float        num   = 0f;
                List <Thing> list  = pawn.Map.listerThings.ThingsInGroup(ThingRequestGroup.Apparel);
                if (list.Count == 0)
                {
                    this.SetNextOptimizeTick(pawn);
                    result = null;
                }
                else
                {
                    JobGiver_OptimizeApparel.neededWarmth = PawnApparelGenerator.CalculateNeededWarmth(pawn, pawn.Map.Tile, GenLocalDate.Twelfth(pawn));
                    for (int j = 0; j < list.Count; j++)
                    {
                        Apparel apparel = (Apparel)list[j];
                        if (currentOutfit.filter.Allows(apparel))
                        {
                            if (apparel.IsInAnyStorage())
                            {
                                if (!apparel.IsForbidden(pawn))
                                {
                                    float num2 = JobGiver_OptimizeApparel.ApparelScoreGain(pawn, apparel);
                                    if (DebugViewSettings.debugApparelOptimize)
                                    {
                                        JobGiver_OptimizeApparel.debugSb.AppendLine(apparel.LabelCap + ": " + num2.ToString("F2"));
                                    }
                                    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 (DebugViewSettings.debugApparelOptimize)
                    {
                        JobGiver_OptimizeApparel.debugSb.AppendLine("BEST: " + thing);
                        Log.Message(JobGiver_OptimizeApparel.debugSb.ToString(), false);
                        JobGiver_OptimizeApparel.debugSb = null;
                    }
                    if (thing == null)
                    {
                        this.SetNextOptimizeTick(pawn);
                        result = null;
                    }
                    else
                    {
                        result = new Job(JobDefOf.Wear, thing);
                    }
                }
            }
            return(result);
        }
 public static void MakeTableApparelPairsByThing()
 {
     PawnApparelGenerator.MakeTablePairsByThing(PawnApparelGenerator.allApparelPairs);
 }
        private static void GenerateWorkingPossibleApparelSetFor(Pawn pawn, float money, bool headwearAllowed)
        {
            PawnApparelGenerator.workingSet.Reset(pawn.RaceProps.body, pawn.def);
            List <ThingDef> reqApparel = pawn.kindDef.apparelRequired;

            if (reqApparel != null)
            {
                int i;
                for (i = 0; i < reqApparel.Count; i++)
                {
                    ThingStuffPair pair = (from pa in PawnApparelGenerator.allApparelPairs
                                           where pa.thing == reqApparel[i]
                                           select pa).RandomElementByWeight((ThingStuffPair pa) => pa.Commonality);
                    PawnApparelGenerator.workingSet.Add(pair);
                    money -= pair.Price;
                }
            }
            int specialSeed = Rand.Int;

            while (!(Rand.Value < 0.10000000149011612))
            {
                Predicate <ThingStuffPair> predicate = delegate(ThingStuffPair pa)
                {
                    if (pa.Price > money)
                    {
                        return(false);
                    }
                    if (!headwearAllowed && PawnApparelGenerator.IsHeadwear(pa.thing))
                    {
                        return(false);
                    }
                    if (pa.stuff != null && !pawn.Faction.def.CanUseStuffForApparel(pa.stuff))
                    {
                        return(false);
                    }
                    if (PawnApparelGenerator.workingSet.PairOverlapsAnything(pa))
                    {
                        return(false);
                    }
                    if (!pawn.kindDef.apparelTags.NullOrEmpty())
                    {
                        bool flag2 = false;
                        int  num   = 0;
                        while (num < pawn.kindDef.apparelTags.Count)
                        {
                            int num2 = 0;
                            while (num2 < pa.thing.apparel.tags.Count)
                            {
                                if (!(pawn.kindDef.apparelTags[num] == pa.thing.apparel.tags[num2]))
                                {
                                    num2++;
                                    continue;
                                }
                                flag2 = true;
                                break;
                            }
                            if (!flag2)
                            {
                                num++;
                                continue;
                            }
                            break;
                        }
                        if (!flag2)
                        {
                            return(false);
                        }
                    }
                    if (pa.thing.generateAllowChance < 1.0 && Rand.ValueSeeded(specialSeed ^ pa.thing.index ^ 64128343) > pa.thing.generateAllowChance)
                    {
                        return(false);
                    }
                    return(true);
                };
                for (int j = 0; j < PawnApparelGenerator.allApparelPairs.Count; j++)
                {
                    if (predicate(PawnApparelGenerator.allApparelPairs[j]))
                    {
                        PawnApparelGenerator.usableApparel.Add(PawnApparelGenerator.allApparelPairs[j]);
                    }
                }
                ThingStuffPair pair2 = default(ThingStuffPair);
                bool           flag  = ((IEnumerable <ThingStuffPair>)PawnApparelGenerator.usableApparel).TryRandomElementByWeight <ThingStuffPair>((Func <ThingStuffPair, float>)((ThingStuffPair pa) => pa.Commonality), out pair2);
                PawnApparelGenerator.usableApparel.Clear();
                if (!flag)
                {
                    break;
                }
                PawnApparelGenerator.workingSet.Add(pair2);
                money -= pair2.Price;
            }
        }
        public static void GenerateStartingApparelFor(Pawn pawn, PawnGenerationRequest request)
        {
            if (pawn.RaceProps.ToolUser && pawn.RaceProps.IsFlesh)
            {
                if (pawn.Faction == null)
                {
                    Log.Error("Cannot generate apparel for faction-less pawn " + pawn);
                }
                else
                {
                    pawn.apparel.DestroyAll(DestroyMode.Vanish);
                    float        randomInRange  = pawn.kindDef.apparelMoney.RandomInRange;
                    float        mapTemperature = default(float);
                    NeededWarmth neededWarmth   = PawnApparelGenerator.ApparelWarmthNeededNow(pawn, request, out mapTemperature);
                    bool         flag           = Rand.Value < pawn.kindDef.apparelAllowHeadwearChance;
                    PawnApparelGenerator.debugSb = null;
                    if (DebugViewSettings.logApparelGeneration)
                    {
                        PawnApparelGenerator.debugSb = new StringBuilder();
                        PawnApparelGenerator.debugSb.AppendLine("Generating apparel for " + pawn);
                        PawnApparelGenerator.debugSb.AppendLine("Money: " + randomInRange.ToString("F0"));
                        PawnApparelGenerator.debugSb.AppendLine("Needed warmth: " + neededWarmth);
                        PawnApparelGenerator.debugSb.AppendLine("Headwear allowed: " + flag);
                    }
                    if (randomInRange >= 0.0010000000474974513)
                    {
                        int num = 0;
                        while (true)
                        {
                            PawnApparelGenerator.GenerateWorkingPossibleApparelSetFor(pawn, randomInRange, flag);
                            if (DebugViewSettings.logApparelGeneration)
                            {
                                PawnApparelGenerator.debugSb.Append(num.ToString().PadRight(5) + "Trying: " + PawnApparelGenerator.workingSet.ToString());
                            }
                            if (num < 10 && Rand.Value < 0.85000002384185791)
                            {
                                float num2       = Rand.Range(0.45f, 0.8f);
                                float totalPrice = PawnApparelGenerator.workingSet.TotalPrice;
                                if (totalPrice < randomInRange * num2)
                                {
                                    if (DebugViewSettings.logApparelGeneration)
                                    {
                                        PawnApparelGenerator.debugSb.AppendLine(" -- Failed: Spent $" + totalPrice.ToString("F0") + ", < " + ((float)(num2 * 100.0)).ToString("F0") + "% of money.");
                                    }
                                    goto IL_036d;
                                }
                            }
                            if (num < 20 && Rand.Value < 0.97000002861022949 && !PawnApparelGenerator.workingSet.Covers(BodyPartGroupDefOf.Torso))
                            {
                                if (DebugViewSettings.logApparelGeneration)
                                {
                                    PawnApparelGenerator.debugSb.AppendLine(" -- Failed: Does not cover torso.");
                                }
                            }
                            else if (num < 30 && Rand.Value < 0.800000011920929 && PawnApparelGenerator.workingSet.CoatButNoShirt())
                            {
                                if (DebugViewSettings.logApparelGeneration)
                                {
                                    PawnApparelGenerator.debugSb.AppendLine(" -- Failed: Coat but no shirt.");
                                }
                            }
                            else
                            {
                                if (num < 50)
                                {
                                    bool mustBeSafe = num < 17;
                                    if (!PawnApparelGenerator.workingSet.SatisfiesNeededWarmth(neededWarmth, mustBeSafe, mapTemperature))
                                    {
                                        if (DebugViewSettings.logApparelGeneration)
                                        {
                                            PawnApparelGenerator.debugSb.AppendLine(" -- Failed: Wrong warmth.");
                                        }
                                        goto IL_036d;
                                    }
                                }
                                if (num >= 80)
                                {
                                    break;
                                }
                                if (!PawnApparelGenerator.workingSet.IsNaked(pawn.gender))
                                {
                                    break;
                                }
                                if (DebugViewSettings.logApparelGeneration)
                                {
                                    PawnApparelGenerator.debugSb.AppendLine(" -- Failed: Naked.");
                                }
                            }
                            goto IL_036d;
IL_036d:
                            num++;
                        }
                        if (DebugViewSettings.logApparelGeneration)
                        {
                            PawnApparelGenerator.debugSb.Append(" -- Approved! Total price: $" + PawnApparelGenerator.workingSet.TotalPrice.ToString("F0") + ", TotalInsulationCold: " + PawnApparelGenerator.workingSet.TotalInsulationCold);
                        }
                    }
                    if ((!pawn.kindDef.apparelIgnoreSeasons || request.ForceAddFreeWarmLayerIfNeeded) && !PawnApparelGenerator.workingSet.SatisfiesNeededWarmth(neededWarmth, false, 21f))
                    {
                        PawnApparelGenerator.workingSet.AddFreeWarmthAsNeeded(neededWarmth);
                    }
                    if (DebugViewSettings.logApparelGeneration)
                    {
                        Log.Message(PawnApparelGenerator.debugSb.ToString());
                    }
                    PawnApparelGenerator.workingSet.GiveToPawn(pawn);
                    PawnApparelGenerator.workingSet.Reset(null, null);
                }
            }
        }
 static PawnApparelGenerator()
 {
     PawnApparelGenerator.Reset();
 }
 private static string <ApparelPairs> m__A(ThingStuffPair p)
 {
     return((!PawnApparelGenerator.IsHeadgear(p.thing)) ? string.Empty : "*");
 }
        private static void ApparelPairs()
        {
            IEnumerable <ThingStuffPair> dataSources = from p in PawnApparelGenerator.allApparelPairs
                                                       orderby p.thing.defName descending
                                                       select p;

            TableDataGetter <ThingStuffPair>[] array = new TableDataGetter <ThingStuffPair> [7];
            array[0] = new TableDataGetter <ThingStuffPair>("thing", (ThingStuffPair p) => p.thing.defName);
            array[1] = new TableDataGetter <ThingStuffPair>("stuff", (ThingStuffPair p) => (p.stuff == null) ? string.Empty : p.stuff.defName);
            array[2] = new TableDataGetter <ThingStuffPair>("price", (ThingStuffPair p) => p.Price.ToString());
            array[3] = new TableDataGetter <ThingStuffPair>("commonality", (ThingStuffPair p) => (p.Commonality * 100f).ToString("F4"));
            array[4] = new TableDataGetter <ThingStuffPair>("generateCommonality", (ThingStuffPair p) => p.thing.generateCommonality.ToString("F4"));
            array[5] = new TableDataGetter <ThingStuffPair>("insulationCold", (ThingStuffPair p) => (p.InsulationCold != 0f) ? p.InsulationCold.ToString() : string.Empty);
            array[6] = new TableDataGetter <ThingStuffPair>("headgear", (ThingStuffPair p) => (!PawnApparelGenerator.IsHeadgear(p.thing)) ? string.Empty : "*");
            DebugTables.MakeTablesDialog <ThingStuffPair>(dataSources, array);
        }
        protected override Job TryGiveJob(Pawn pawn)
        {
            if (pawn.outfits == null)
            {
                Log.ErrorOnce(pawn + " tried to run JobGiver_OptimizeApparel without an OutfitTracker", 5643897);
                return(null);
            }
            if (pawn.Faction != Faction.OfPlayer)
            {
                Log.ErrorOnce("Non-colonist " + pawn + " tried to optimize apparel.", 764323);
                return(null);
            }
            if (pawn.IsQuestLodger())
            {
                return(null);
            }
            if (!DebugViewSettings.debugApparelOptimize)
            {
                if (Find.TickManager.TicksGame < pawn.mindState.nextApparelOptimizeTick)
                {
                    return(null);
                }
            }
            else
            {
                debugSb = new StringBuilder();
                debugSb.AppendLine("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;
                    return(job);
                }
            }
            Thing        thing = null;
            float        num2  = 0f;
            List <Thing> list  = pawn.Map.listerThings.ThingsInGroup(ThingRequestGroup.Apparel);

            if (list.Count == 0)
            {
                SetNextOptimizeTick(pawn);
                return(null);
            }
            neededWarmth = PawnApparelGenerator.CalculateNeededWarmth(pawn, pawn.Map.Tile, GenLocalDate.Twelfth(pawn));
            for (int i = 0; i < list.Count; i++)
            {
                Apparel apparel = (Apparel)list[i];
                if (currentOutfit.filter.Allows(apparel) && apparel.IsInAnyStorage() && !apparel.IsForbidden(pawn) && !apparel.IsBurning() && (apparel.def.apparel.gender == Gender.None || apparel.def.apparel.gender == pawn.gender) && (!apparel.def.apparel.tags.Contains("Royal") || pawn.royalty.AllTitlesInEffectForReading.Count != 0))
                {
                    float num3 = ApparelScoreGain(pawn, apparel);
                    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)
            {
                SetNextOptimizeTick(pawn);
                return(null);
            }
            return(JobMaker.MakeJob(JobDefOf.Wear, thing));
        }
        public static void GenerateStartingApparelFor(Pawn pawn, PawnGenerationRequest request)
        {
            if (!pawn.RaceProps.ToolUser || !pawn.RaceProps.IsFlesh)
            {
                return;
            }
            pawn.apparel.DestroyAll(DestroyMode.Vanish);
            float        randomInRange = pawn.kindDef.apparelMoney.RandomInRange;
            float        mapTemperature;
            NeededWarmth neededWarmth = PawnApparelGenerator.ApparelWarmthNeededNow(pawn, request, out mapTemperature);
            bool         flag         = Rand.Value < pawn.kindDef.apparelAllowHeadgearChance;

            PawnApparelGenerator.debugSb = null;
            if (DebugViewSettings.logApparelGeneration)
            {
                PawnApparelGenerator.debugSb = new StringBuilder();
                PawnApparelGenerator.debugSb.AppendLine("Generating apparel for " + pawn);
                PawnApparelGenerator.debugSb.AppendLine("Money: " + randomInRange.ToString("F0"));
                PawnApparelGenerator.debugSb.AppendLine("Needed warmth: " + neededWarmth);
                PawnApparelGenerator.debugSb.AppendLine("Headgear allowed: " + flag);
            }
            if (randomInRange < 0.001f)
            {
                PawnApparelGenerator.GenerateWorkingPossibleApparelSetFor(pawn, randomInRange, flag);
            }
            else
            {
                int num = 0;
                for (;;)
                {
                    PawnApparelGenerator.GenerateWorkingPossibleApparelSetFor(pawn, randomInRange, flag);
                    if (DebugViewSettings.logApparelGeneration)
                    {
                        PawnApparelGenerator.debugSb.Append(num.ToString().PadRight(5) + "Trying: " + PawnApparelGenerator.workingSet.ToString());
                    }
                    if (num >= 10 || Rand.Value >= 0.85f)
                    {
                        goto IL_1EB;
                    }
                    float num2       = Rand.Range(0.45f, 0.8f);
                    float totalPrice = PawnApparelGenerator.workingSet.TotalPrice;
                    if (totalPrice >= randomInRange * num2)
                    {
                        goto IL_1EB;
                    }
                    if (DebugViewSettings.logApparelGeneration)
                    {
                        PawnApparelGenerator.debugSb.AppendLine(string.Concat(new string[]
                        {
                            " -- Failed: Spent $",
                            totalPrice.ToString("F0"),
                            ", < ",
                            (num2 * 100f).ToString("F0"),
                            "% of money."
                        }));
                    }
IL_35E:
                    num++;
                    continue;
IL_1EB:
                    if (num < 20 && Rand.Value < 0.97f && !PawnApparelGenerator.workingSet.Covers(BodyPartGroupDefOf.Torso))
                    {
                        if (DebugViewSettings.logApparelGeneration)
                        {
                            PawnApparelGenerator.debugSb.AppendLine(" -- Failed: Does not cover torso.");
                        }
                        goto IL_35E;
                    }
                    if (num < 30 && Rand.Value < 0.8f && PawnApparelGenerator.workingSet.CoatButNoShirt())
                    {
                        if (DebugViewSettings.logApparelGeneration)
                        {
                            PawnApparelGenerator.debugSb.AppendLine(" -- Failed: Coat but no shirt.");
                        }
                        goto IL_35E;
                    }
                    if (num < 50)
                    {
                        bool mustBeSafe = num < 17;
                        if (!PawnApparelGenerator.workingSet.SatisfiesNeededWarmth(neededWarmth, mustBeSafe, mapTemperature))
                        {
                            if (DebugViewSettings.logApparelGeneration)
                            {
                                PawnApparelGenerator.debugSb.AppendLine(" -- Failed: Wrong warmth.");
                            }
                            goto IL_35E;
                        }
                    }
                    if (num < 80 && PawnApparelGenerator.workingSet.IsNaked(pawn.gender))
                    {
                        if (DebugViewSettings.logApparelGeneration)
                        {
                            PawnApparelGenerator.debugSb.AppendLine(" -- Failed: Naked.");
                        }
                        goto IL_35E;
                    }
                    break;
                }
                if (DebugViewSettings.logApparelGeneration)
                {
                    PawnApparelGenerator.debugSb.Append(string.Concat(new object[]
                    {
                        " -- Approved! Total price: $",
                        PawnApparelGenerator.workingSet.TotalPrice.ToString("F0"),
                        ", TotalInsulationCold: ",
                        PawnApparelGenerator.workingSet.TotalInsulationCold
                    }));
                }
            }
            if ((!pawn.kindDef.apparelIgnoreSeasons || request.ForceAddFreeWarmLayerIfNeeded) && !PawnApparelGenerator.workingSet.SatisfiesNeededWarmth(neededWarmth, true, mapTemperature))
            {
                PawnApparelGenerator.workingSet.AddFreeWarmthAsNeeded(neededWarmth, mapTemperature);
            }
            if (DebugViewSettings.logApparelGeneration)
            {
                Log.Message(PawnApparelGenerator.debugSb.ToString(), false);
            }
            PawnApparelGenerator.workingSet.GiveToPawn(pawn);
            PawnApparelGenerator.workingSet.Reset(null, null);
            if (pawn.kindDef.apparelColor != Color.white)
            {
                List <Apparel> wornApparel = pawn.apparel.WornApparel;
                for (int i = 0; i < wornApparel.Count; i++)
                {
                    wornApparel[i].SetColor(pawn.kindDef.apparelColor, false);
                }
            }
        }
        protected override Job TryGiveJob(Pawn pawn)
        {
            if (pawn.outfits == null)
            {
                Log.ErrorOnce(pawn + " tried to run JobGiver_OptimizeApparel without an OutfitTracker", 5643897);
                return(null);
            }
            if (pawn.Faction != Faction.OfPlayer)
            {
                Log.ErrorOnce("Non-colonist " + pawn + " tried to optimize apparel.", 764323);
                return(null);
            }
            if (!DebugViewSettings.debugApparelOptimize)
            {
                if (Find.TickManager.TicksGame < pawn.mindState.nextApparelOptimizeTick)
                {
                    return(null);
                }
            }
            else
            {
                JobGiver_OptimizeApparel.debugSb = new StringBuilder();
                JobGiver_OptimizeApparel.debugSb.AppendLine("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]))
                {
                    Job job = new Job(JobDefOf.RemoveApparel, wornApparel[num]);
                    job.haulDroppedApparel = true;
                    return(job);
                }
            }
            Thing        thing = null;
            float        num2  = 0f;
            List <Thing> list  = pawn.Map.listerThings.ThingsInGroup(ThingRequestGroup.Apparel);

            if (list.Count == 0)
            {
                this.SetNextOptimizeTick(pawn);
                return(null);
            }
            JobGiver_OptimizeApparel.neededWarmth = PawnApparelGenerator.CalculateNeededWarmth(pawn, pawn.Map.Tile, GenLocalDate.Twelfth(pawn));
            for (int i = 0; i < list.Count; i++)
            {
                Apparel apparel = (Apparel)list[i];
                if (currentOutfit.filter.Allows(apparel))
                {
                    SlotGroup slotGroup = apparel.Map.slotGroupManager.SlotGroupAt(apparel.Position);
                    if (slotGroup != null && !apparel.IsForbidden(pawn))
                    {
                        float num3 = JobGiver_OptimizeApparel.ApparelScoreGain(pawn, apparel);
                        if (DebugViewSettings.debugApparelOptimize)
                        {
                            JobGiver_OptimizeApparel.debugSb.AppendLine(apparel.LabelCap + ": " + num3.ToString("F2"));
                        }
                        if (!(num3 < 0.05000000074505806) && !(num3 < num2) && ApparelUtility.HasPartsToWear(pawn, apparel.def) && pawn.CanReserveAndReach(apparel, PathEndMode.OnCell, pawn.NormalMaxDanger(), 1, -1, null, false))
                        {
                            thing = apparel;
                            num2  = num3;
                        }
                    }
                }
            }
            if (DebugViewSettings.debugApparelOptimize)
            {
                JobGiver_OptimizeApparel.debugSb.AppendLine("BEST: " + thing);
                Log.Message(JobGiver_OptimizeApparel.debugSb.ToString());
                JobGiver_OptimizeApparel.debugSb = null;
            }
            if (thing == null)
            {
                this.SetNextOptimizeTick(pawn);
                return(null);
            }
            return(new Job(JobDefOf.Wear, thing));
        }
        private static void GenerateWorkingPossibleApparelSetFor(Pawn pawn, float money, bool headwearAllowed)
        {
            PawnApparelGenerator.workingSet.Reset(pawn.RaceProps.body, pawn.def);
            List <ThingDef> reqApparel = pawn.kindDef.apparelRequired;

            if (reqApparel != null)
            {
                int i;
                for (i = 0; i < reqApparel.Count; i++)
                {
                    ThingStuffPair pair = (from pa in PawnApparelGenerator.allApparelPairs
                                           where pa.thing == reqApparel[i]
                                           select pa).RandomElementByWeight((ThingStuffPair pa) => pa.Commonality);
                    PawnApparelGenerator.workingSet.Add(pair);
                    money -= pair.Price;
                }
            }
            int specialSeed = Rand.Int;

            while (Rand.Value >= 0.1f)
            {
                Predicate <ThingStuffPair> predicate = delegate(ThingStuffPair pa)
                {
                    if (pa.Price > money)
                    {
                        return(false);
                    }
                    if (!headwearAllowed && PawnApparelGenerator.IsHeadwear(pa.thing))
                    {
                        return(false);
                    }
                    if (pa.stuff != null && !pawn.Faction.def.CanUseStuffForApparel(pa.stuff))
                    {
                        return(false);
                    }
                    if (PawnApparelGenerator.workingSet.PairOverlapsAnything(pa))
                    {
                        return(false);
                    }
                    if (!pawn.kindDef.apparelTags.NullOrEmpty <string>())
                    {
                        bool flag2 = false;
                        for (int i = 0; i < pawn.kindDef.apparelTags.Count; i++)
                        {
                            for (int k = 0; k < pa.thing.apparel.tags.Count; k++)
                            {
                                if (pawn.kindDef.apparelTags[i] == pa.thing.apparel.tags[k])
                                {
                                    flag2 = true;
                                    break;
                                }
                            }
                            if (flag2)
                            {
                                break;
                            }
                        }
                        if (!flag2)
                        {
                            return(false);
                        }
                    }
                    return(pa.thing.generateAllowChance >= 1f || Rand.ValueSeeded(specialSeed ^ (int)pa.thing.index ^ 64128343) <= pa.thing.generateAllowChance);
                };
                for (int j = 0; j < PawnApparelGenerator.allApparelPairs.Count; j++)
                {
                    if (predicate(PawnApparelGenerator.allApparelPairs[j]))
                    {
                        PawnApparelGenerator.usableApparel.Add(PawnApparelGenerator.allApparelPairs[j]);
                    }
                }
                ThingStuffPair pair2;
                bool           flag = PawnApparelGenerator.usableApparel.TryRandomElementByWeight((ThingStuffPair pa) => pa.Commonality, out pair2);
                PawnApparelGenerator.usableApparel.Clear();
                if (!flag)
                {
                    return;
                }
                PawnApparelGenerator.workingSet.Add(pair2);
                money -= pair2.Price;
            }
        }