Пример #1
0
            public bool SatisfiesNeededWarmth(NeededWarmth warmth, bool mustBeSafe = false, float mapTemperature = 21f)
            {
                bool result;

                if (warmth == NeededWarmth.Any)
                {
                    result = true;
                }
                else if (mustBeSafe && !GenTemperature.SafeTemperatureRange(this.raceDef, this.aps).Includes(mapTemperature))
                {
                    result = false;
                }
                else if (warmth == NeededWarmth.Cool)
                {
                    float num = this.aps.Sum((ThingStuffPair a) => a.InsulationHeat);
                    result = (num >= -2f);
                }
                else
                {
                    if (warmth != NeededWarmth.Warm)
                    {
                        throw new NotImplementedException();
                    }
                    float num2 = this.aps.Sum((ThingStuffPair a) => a.InsulationCold);
                    result = (num2 >= 52f);
                }
                return(result);
            }
Пример #2
0
            public bool SatisfiesNeededWarmth(NeededWarmth warmth, bool mustBeSafe = false, float mapTemperature = 21f)
            {
                if (warmth == NeededWarmth.Any)
                {
                    return(true);
                }
                if (!mustBeSafe || GenTemperature.SafeTemperatureRange(raceDef, aps).Includes(mapTemperature))
                {
                    switch (warmth)
                    {
                    case NeededWarmth.Cool:
                    {
                        float num2 = aps.Sum((ThingStuffPair a) => a.InsulationHeat);
                        return(num2 >= -2f);
                    }

                    case NeededWarmth.Warm:
                    {
                        float num = aps.Sum((ThingStuffPair a) => a.InsulationCold);
                        return(num >= 52f);
                    }

                    default:
                        throw new NotImplementedException();
                    }
                }
                return(false);
            }
Пример #3
0
        public static float ApparelScoreRaw(Pawn pawn, Apparel apparel, NeededWarmth neededWarmth = NeededWarmth.Any)
        {
            var outfit = pawn.outfits.CurrentOutfit as ExtendedOutfit;

            if (outfit == null)
            {
                Log.ErrorOnce("Outfitted :: Not an ExtendedOutfit, something went wrong.", 399441);
                return(0f);
            }

            float score = 0.1f + ApparelScoreRawPriorities(pawn, apparel, outfit);

            if (outfit.AutoWorkPriorities)
            {
                score += ApparelScoreAutoWorkPriorities(pawn, apparel);
            }

            if (apparel.def.useHitPoints)
            {
                float x = (float)apparel.HitPoints / apparel.MaxHitPoints;
                score *= HitPointsPercentScoreFactorCurve.Evaluate(x);
            }
            score += apparel.GetSpecialApparelScoreOffset();

            score += ApparelScoreRawInsulation(pawn, apparel, outfit, neededWarmth);

            if (outfit.PenaltyWornByCorpse && apparel.WornByCorpse && ThoughtUtility.CanGetThought(pawn, ThoughtDefOf.DeadMansApparel))
            {
                score -= 0.5f;
                if (score > 0f)
                {
                    score *= 0.1f;
                }
            }

            if (apparel.Stuff == ThingDefOf.Human.race.leatherDef)
            {
                if (ThoughtUtility.CanGetThought(pawn, ThoughtDefOf.HumanLeatherApparelSad))
                {
                    score -= 0.5f;
                    if (score > 0f)
                    {
                        score *= 0.1f;
                    }
                }
                if (ThoughtUtility.CanGetThought(pawn, ThoughtDefOf.HumanLeatherApparelHappy))
                {
                    score += 0.12f;
                }
            }

            return(score);
        }
        static bool Prefix(Pawn pawn, Apparel ap, out float __result, NeededWarmth ___neededWarmth)
        {
            //if (pawn == null) {
            //    __result = float.NaN;

            //    return true;
            //}

            __result = OutfittedMod.ApparelScoreRaw(pawn, ap, ___neededWarmth);

            return(false);
        }
Пример #5
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);
        }
Пример #6
0
        public static Thing PickBestArmorFor(Pawn pawn)
        {
            if (pawn.outfits == null)
            {
                return(null);
            }
            if (pawn.Faction != Faction.OfPlayer)
            {
                return(null);
            }
            if (pawn.IsQuestLodger())
            {
                return(null);
            }

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

            if (list.Count == 0)
            {
                return(null);
            }
            neededWarmth      = PawnApparelGenerator.CalculateNeededWarmth(pawn, pawn.Map.Tile, GenLocalDate.Twelfth(pawn));
            wornApparelScores = new List <float>();
            List <Apparel> wornApparel = pawn.apparel.WornApparel;

            for (int i = 0; i < wornApparel.Count; i++)
            {
                wornApparelScores.Add(ApparelScoreRaw(pawn, wornApparel[i]));
            }
            for (int j = 0; j < list.Count; j++)
            {
                Apparel apparel = (Apparel)list[j];                 // && apparel.IsInAnyStorage()
                if (!apparel.IsBurning() && currentOutfit.filter.Allows(apparel) && !apparel.IsForbidden(pawn) &&
                    (apparel.def.apparel.gender == Gender.None || apparel.def.apparel.gender == pawn.gender))
                {
                    float num3 = ApparelScoreGain_NewTmp(pawn, apparel, wornApparelScores);
                    if (!(num3 < 0.05f) && !(num3 < num2) && (!CompBiocodable.IsBiocoded(apparel) || CompBiocodable.IsBiocodedFor(apparel, pawn)) &&
                        ApparelUtility.HasPartsToWear(pawn, apparel.def) &&
                        pawn.CanReserveAndReach(apparel, PathEndMode.OnCell, pawn.NormalMaxDanger()))
                    {
                        thing = apparel;
                        num2  = num3;
                    }
                }
            }
            return(thing);
        }
Пример #7
0
 public bool SatisfiesNeededWarmth(NeededWarmth warmth, bool mustBeSafe = false, float mapTemperature = 21f)
 {
     if (warmth == NeededWarmth.Any)
     {
         return(true);
     }
     if (mustBeSafe && !GenTemperature.SafeTemperatureRange(raceDef, aps).Includes(mapTemperature))
     {
         return(false);
     }
     return(warmth switch
     {
         NeededWarmth.Cool => aps.Sum((ThingStuffPair a) => a.InsulationHeat) >= -2f,
         NeededWarmth.Warm => aps.Sum((ThingStuffPair a) => a.InsulationCold) >= 52f,
         _ => throw new NotImplementedException(),
     });
Пример #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 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);
                }
            }
        }
 public void AddFreeWarmthAsNeeded(NeededWarmth warmth)
 {
     if (warmth != 0 && warmth != NeededWarmth.Cool)
     {
         if (DebugViewSettings.logApparelGeneration)
         {
             PawnApparelGenerator.debugSb.AppendLine();
             PawnApparelGenerator.debugSb.AppendLine("Trying to give free warm layer.");
         }
         if (!this.SatisfiesNeededWarmth(warmth, false, 21f))
         {
             if (DebugViewSettings.logApparelGeneration)
             {
                 PawnApparelGenerator.debugSb.AppendLine("Checking to give free torso-cover at max price " + PawnApparelGenerator.freeWarmParkaMaxPrice);
             }
             Predicate <ThingStuffPair> parkaPairValidator = delegate(ThingStuffPair pa)
             {
                 if (pa.Price > PawnApparelGenerator.freeWarmParkaMaxPrice)
                 {
                     return(false);
                 }
                 if (pa.InsulationCold > -40.0)
                 {
                     return(false);
                 }
                 return(true);
             };
             ThingStuffPair parkaPair;
             if ((from pa in PawnApparelGenerator.allApparelPairs
                  where parkaPairValidator(pa)
                  select pa).TryRandomElementByWeight <ThingStuffPair>((Func <ThingStuffPair, float>)((ThingStuffPair pa) => pa.Commonality / (pa.Price * pa.Price)), out parkaPair))
             {
                 if (DebugViewSettings.logApparelGeneration)
                 {
                     PawnApparelGenerator.debugSb.AppendLine("Giving free torso-cover: " + parkaPair + " insulation=" + parkaPair.InsulationCold);
                     foreach (ThingStuffPair item in from a in this.aps
                              where !ApparelUtility.CanWearTogether(a.thing, parkaPair.thing, this.body)
                              select a)
                     {
                         PawnApparelGenerator.debugSb.AppendLine("    -replaces " + item.ToString() + " InsulationCold=" + item.InsulationCold);
                     }
                 }
                 this.aps.RemoveAll((ThingStuffPair pa) => !ApparelUtility.CanWearTogether(pa.thing, parkaPair.thing, this.body));
                 this.aps.Add(parkaPair);
             }
         }
         if (!this.SatisfiesNeededWarmth(warmth, false, 21f))
         {
             if (DebugViewSettings.logApparelGeneration)
             {
                 PawnApparelGenerator.debugSb.AppendLine("Checking to give free hat at max price " + PawnApparelGenerator.freeWarmHatMaxPrice);
             }
             Predicate <ThingStuffPair> hatPairValidator = delegate(ThingStuffPair pa)
             {
                 if (pa.Price > PawnApparelGenerator.freeWarmHatMaxPrice)
                 {
                     return(false);
                 }
                 if (pa.InsulationCold > -7.0)
                 {
                     return(false);
                 }
                 if (!pa.thing.apparel.bodyPartGroups.Contains(BodyPartGroupDefOf.FullHead) && !pa.thing.apparel.bodyPartGroups.Contains(BodyPartGroupDefOf.UpperHead))
                 {
                     return(false);
                 }
                 return(true);
             };
             ThingStuffPair hatPair;
             if ((from pa in PawnApparelGenerator.allApparelPairs
                  where hatPairValidator(pa)
                  select pa).TryRandomElementByWeight <ThingStuffPair>((Func <ThingStuffPair, float>)((ThingStuffPair pa) => pa.Commonality / (pa.Price * pa.Price)), out hatPair))
             {
                 if (DebugViewSettings.logApparelGeneration)
                 {
                     PawnApparelGenerator.debugSb.AppendLine("Giving free hat: " + hatPair + " insulation=" + hatPair.InsulationCold);
                     foreach (ThingStuffPair item2 in from a in this.aps
                              where !ApparelUtility.CanWearTogether(a.thing, hatPair.thing, this.body)
                              select a)
                     {
                         PawnApparelGenerator.debugSb.AppendLine("    -replaces " + item2.ToString() + " InsulationCold=" + item2.InsulationCold);
                     }
                 }
                 this.aps.RemoveAll((ThingStuffPair pa) => !ApparelUtility.CanWearTogether(pa.thing, hatPair.thing, this.body));
                 this.aps.Add(hatPair);
             }
         }
         if (DebugViewSettings.logApparelGeneration)
         {
             PawnApparelGenerator.debugSb.AppendLine("New TotalInsulationCold: " + this.TotalInsulationCold);
         }
     }
 }
        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);
                }
            }
        }
Пример #12
0
 public void AddFreeWarmthAsNeeded(NeededWarmth warmth)
 {
     if (warmth == NeededWarmth.Any)
     {
         return;
     }
     if (warmth == NeededWarmth.Cool)
     {
         return;
     }
     if (DebugViewSettings.logApparelGeneration)
     {
         PawnApparelGenerator.debugSb.AppendLine();
         PawnApparelGenerator.debugSb.AppendLine("Trying to give free warm layer.");
     }
     if (!this.SatisfiesNeededWarmth(warmth, false, 21f))
     {
         if (DebugViewSettings.logApparelGeneration)
         {
             PawnApparelGenerator.debugSb.AppendLine("Checking to give free torso-cover at max price " + PawnApparelGenerator.freeWarmParkaMaxPrice);
         }
         Predicate <ThingStuffPair> parkaPairValidator = (ThingStuffPair pa) => pa.Price <= PawnApparelGenerator.freeWarmParkaMaxPrice && pa.InsulationCold <= -40f;
         ThingStuffPair             parkaPair;
         if ((from pa in PawnApparelGenerator.allApparelPairs
              where parkaPairValidator(pa)
              select pa).TryRandomElementByWeight((ThingStuffPair pa) => pa.Commonality / (pa.Price * pa.Price), out parkaPair))
         {
             if (DebugViewSettings.logApparelGeneration)
             {
                 PawnApparelGenerator.debugSb.AppendLine(string.Concat(new object[]
                 {
                     "Giving free torso-cover: ",
                     parkaPair,
                     " insulation=",
                     parkaPair.InsulationCold
                 }));
                 foreach (ThingStuffPair current in from a in this.aps
                          where !ApparelUtility.CanWearTogether(a.thing, parkaPair.thing, this.body)
                          select a)
                 {
                     PawnApparelGenerator.debugSb.AppendLine(string.Concat(new object[]
                     {
                         "    -replaces ",
                         current.ToString(),
                         " InsulationCold=",
                         current.InsulationCold
                     }));
                 }
             }
             this.aps.RemoveAll((ThingStuffPair pa) => !ApparelUtility.CanWearTogether(pa.thing, parkaPair.thing, this.body));
             this.aps.Add(parkaPair);
         }
     }
     if (!this.SatisfiesNeededWarmth(warmth, false, 21f))
     {
         if (DebugViewSettings.logApparelGeneration)
         {
             PawnApparelGenerator.debugSb.AppendLine("Checking to give free hat at max price " + PawnApparelGenerator.freeWarmHatMaxPrice);
         }
         Predicate <ThingStuffPair> hatPairValidator = (ThingStuffPair pa) => pa.Price <= PawnApparelGenerator.freeWarmHatMaxPrice && pa.InsulationCold <= -7f && (pa.thing.apparel.bodyPartGroups.Contains(BodyPartGroupDefOf.FullHead) || pa.thing.apparel.bodyPartGroups.Contains(BodyPartGroupDefOf.UpperHead));
         ThingStuffPair             hatPair;
         if ((from pa in PawnApparelGenerator.allApparelPairs
              where hatPairValidator(pa)
              select pa).TryRandomElementByWeight((ThingStuffPair pa) => pa.Commonality / (pa.Price * pa.Price), out hatPair))
         {
             if (DebugViewSettings.logApparelGeneration)
             {
                 PawnApparelGenerator.debugSb.AppendLine(string.Concat(new object[]
                 {
                     "Giving free hat: ",
                     hatPair,
                     " insulation=",
                     hatPair.InsulationCold
                 }));
                 foreach (ThingStuffPair current2 in from a in this.aps
                          where !ApparelUtility.CanWearTogether(a.thing, hatPair.thing, this.body)
                          select a)
                 {
                     PawnApparelGenerator.debugSb.AppendLine(string.Concat(new object[]
                     {
                         "    -replaces ",
                         current2.ToString(),
                         " InsulationCold=",
                         current2.InsulationCold
                     }));
                 }
             }
             this.aps.RemoveAll((ThingStuffPair pa) => !ApparelUtility.CanWearTogether(pa.thing, hatPair.thing, this.body));
             this.aps.Add(hatPair);
         }
     }
     if (DebugViewSettings.logApparelGeneration)
     {
         PawnApparelGenerator.debugSb.AppendLine("New TotalInsulationCold: " + this.TotalInsulationCold);
     }
 }
Пример #13
0
 public void AddFreeWarmthAsNeeded(NeededWarmth warmth, float mapTemperature)
 {
     if (warmth == NeededWarmth.Any || warmth == NeededWarmth.Cool)
     {
         return;
     }
     if (DebugViewSettings.logApparelGeneration)
     {
         debugSb.AppendLine();
         debugSb.AppendLine("Trying to give free warm layer.");
     }
     for (int i = 0; i < 3; i++)
     {
         if (!SatisfiesNeededWarmth(warmth, mustBeSafe: true, mapTemperature))
         {
             if (DebugViewSettings.logApparelGeneration)
             {
                 debugSb.AppendLine("Checking to give free torso-cover at max price " + freeWarmParkaMaxPrice);
             }
             Predicate <ThingStuffPair> parkaPairValidator = delegate(ThingStuffPair pa)
             {
                 if (pa.Price > freeWarmParkaMaxPrice)
                 {
                     return(false);
                 }
                 if (pa.InsulationCold <= 0f)
                 {
                     return(false);
                 }
                 if (!pa.thing.apparel.bodyPartGroups.Contains(BodyPartGroupDefOf.Torso))
                 {
                     return(false);
                 }
                 if (!pa.thing.apparel.canBeGeneratedToSatisfyWarmth)
                 {
                     return(false);
                 }
                 return((!(GetReplacedInsulationCold(pa) >= pa.InsulationCold)) ? true : false);
             };
             for (int j = 0; j < 2; j++)
             {
                 ThingStuffPair candidate;
                 if (j == 0)
                 {
                     if (!allApparelPairs.Where((ThingStuffPair pa) => parkaPairValidator(pa) && pa.InsulationCold < 40f).TryRandomElementByWeight((ThingStuffPair pa) => pa.Commonality / (pa.Price * pa.Price), out candidate))
                     {
                         continue;
                     }
                 }
                 else if (!allApparelPairs.Where((ThingStuffPair pa) => parkaPairValidator(pa)).TryMaxBy((ThingStuffPair x) => x.InsulationCold - GetReplacedInsulationCold(x), out candidate))
                 {
                     continue;
                 }
                 if (DebugViewSettings.logApparelGeneration)
                 {
                     debugSb.AppendLine("Giving free torso-cover: " + candidate + " insulation=" + candidate.InsulationCold);
                     foreach (ThingStuffPair item in aps.Where((ThingStuffPair a) => !ApparelUtility.CanWearTogether(a.thing, candidate.thing, body)))
                     {
                         debugSb.AppendLine("    -replaces " + item.ToString() + " InsulationCold=" + item.InsulationCold);
                     }
                 }
                 aps.RemoveAll((ThingStuffPair pa) => !ApparelUtility.CanWearTogether(pa.thing, candidate.thing, body));
                 aps.Add(candidate);
                 break;
             }
         }
         if (GenTemperature.SafeTemperatureRange(raceDef, aps).Includes(mapTemperature))
         {
             break;
         }
     }
     if (!SatisfiesNeededWarmth(warmth, mustBeSafe: true, mapTemperature))
     {
         if (DebugViewSettings.logApparelGeneration)
         {
             debugSb.AppendLine("Checking to give free hat at max price " + freeWarmHatMaxPrice);
         }
         Predicate <ThingStuffPair> hatPairValidator = delegate(ThingStuffPair pa)
         {
             if (pa.Price > freeWarmHatMaxPrice)
             {
                 return(false);
             }
             if (pa.InsulationCold < 7f)
             {
                 return(false);
             }
             if (!pa.thing.apparel.bodyPartGroups.Contains(BodyPartGroupDefOf.FullHead) && !pa.thing.apparel.bodyPartGroups.Contains(BodyPartGroupDefOf.UpperHead))
             {
                 return(false);
             }
             return((!(GetReplacedInsulationCold(pa) >= pa.InsulationCold)) ? true : false);
         };
         if (allApparelPairs.Where((ThingStuffPair pa) => hatPairValidator(pa)).TryRandomElementByWeight((ThingStuffPair pa) => pa.Commonality / (pa.Price * pa.Price), out ThingStuffPair hatPair))
         {
             if (DebugViewSettings.logApparelGeneration)
             {
                 debugSb.AppendLine("Giving free hat: " + hatPair + " insulation=" + hatPair.InsulationCold);
                 foreach (ThingStuffPair item2 in aps.Where((ThingStuffPair a) => !ApparelUtility.CanWearTogether(a.thing, hatPair.thing, body)))
                 {
                     debugSb.AppendLine("    -replaces " + item2.ToString() + " InsulationCold=" + item2.InsulationCold);
                 }
             }
             aps.RemoveAll((ThingStuffPair pa) => !ApparelUtility.CanWearTogether(pa.thing, hatPair.thing, body));
             aps.Add(hatPair);
         }
     }
     if (DebugViewSettings.logApparelGeneration)
     {
         debugSb.AppendLine("New TotalInsulationCold: " + TotalInsulationCold);
     }
 }
Пример #14
0
        public static float ApparelScoreRaw(Pawn pawn, Apparel apparel, NeededWarmth neededWarmth = NeededWarmth.Any)
        {
            var outfit = pawn?.outfits?.CurrentOutfit as ExtendedOutfit;

            if (pawn != null && outfit == null)
            {
                Log.ErrorOnce("Outfitted :: Not an ExtendedOutfit, something went wrong.", 399441);
                return(0f);
            }

            float score = 0.1f + ApparelScoreRawPriorities(apparel, outfit);

            if (pawn != null && outfit?.AutoWorkPriorities == true)
            {
                score += ApparelScoreAutoWorkPriorities(pawn, apparel);
            }

            if (apparel.def.useHitPoints)
            {
                float x = (float)apparel.HitPoints / apparel.MaxHitPoints;
                score *= HitPointsPercentScoreFactorCurve.Evaluate(x);
            }

            score += apparel.GetSpecialApparelScoreOffset();

            if (pawn != null && outfit != null)
            {
                score += ApparelScoreRawInsulation(pawn, apparel, outfit, neededWarmth);
            }

            if (pawn?.def?.race?.Animal == false)
            {
                if (outfit?.PenaltyWornByCorpse == true && apparel.WornByCorpse && ThoughtUtility.CanGetThought(pawn, ThoughtDefOf.DeadMansApparel, true))
                {
                    score -= 0.5f;
                    if (score > 0f)
                    {
                        score *= 0.1f;
                    }
                }

                if (apparel.Stuff == ThingDefOf.Human.race.leatherDef)
                {
                    if (ThoughtUtility.CanGetThought(pawn, ThoughtDefOf.HumanLeatherApparelSad, true))
                    {
                        score -= 0.5f;
                        if (score > 0f)
                        {
                            score *= 0.1f;
                        }
                    }
                    if (ThoughtUtility.CanGetThought(pawn, ThoughtDefOf.HumanLeatherApparelHappy, true))
                    {
                        score += 0.12f;
                    }
                }
            }

            //royalty titles
            if (pawn?.royalty?.AllTitlesInEffectForReading?.Count > 0)
            {
                HashSet <ThingDef>         tmpAllowedApparels  = new HashSet <ThingDef>();
                HashSet <ThingDef>         tmpRequiredApparels = new HashSet <ThingDef>();
                HashSet <BodyPartGroupDef> tmpBodyPartGroupsWithRequirement = new HashSet <BodyPartGroupDef>();
                QualityCategory            qualityCategory = QualityCategory.Awful;
                foreach (RoyalTitle item in pawn.royalty.AllTitlesInEffectForReading)
                {
                    if (item.def.requiredApparel != null)
                    {
                        for (int i = 0; i < item.def.requiredApparel.Count; i++)
                        {
                            tmpAllowedApparels.AddRange(item.def.requiredApparel[i].AllAllowedApparelForPawn(pawn, ignoreGender: false, includeWorn: true));
                            tmpRequiredApparels.AddRange(item.def.requiredApparel[i].AllRequiredApparelForPawn(pawn, ignoreGender: false, includeWorn: true));
                            tmpBodyPartGroupsWithRequirement.AddRange(item.def.requiredApparel[i].bodyPartGroupsMatchAny);
                        }
                    }
                    if (item.def.requiredMinimumApparelQuality > qualityCategory)
                    {
                        qualityCategory = item.def.requiredMinimumApparelQuality;
                    }
                }

                if (apparel.TryGetQuality(out QualityCategory qc) && qc < qualityCategory)
                {
                    score *= 0.25f;
                }

                bool isRequired = apparel.def.apparel.bodyPartGroups.Any(bp => tmpBodyPartGroupsWithRequirement.Contains(bp));
                if (isRequired)
                {
                    foreach (ThingDef tmpRequiredApparel in tmpRequiredApparels)
                    {
                        tmpAllowedApparels.Remove(tmpRequiredApparel);
                    }
                    if (tmpAllowedApparels.Contains(apparel.def))
                    {
                        score *= 10f;
                    }
                    if (tmpRequiredApparels.Contains(apparel.def))
                    {
                        score *= 25f;
                    }
                }
            }

            return(score);
        }
Пример #15
0
        static float ApparelScoreRawInsulation(Pawn pawn, Apparel apparel, ExtendedOutfit outfit, NeededWarmth neededWarmth)
        {
            float insulation;

            if (outfit.targetTemperaturesOverride)
            {
                // NOTE: We can't rely on the vanilla check for taking off gear for temperature, because
                // we need to consider all the wardrobe changes taken together; each individual change may
                // note push us over the thresholds, but several changes together may.
                // Return 1 for temperature offsets here, we'll look at the effects of any gear we have to
                // take off below.
                // NOTE: This is still suboptimal, because we're still only considering one piece of apparel
                // to wear at each time. A better solution would be reducing the problem to a series of linear
                // equations, and then solving that system.
                // I'm not sure that's feasible at all; first off for simple computational reasons: the linear
                // system to solve would be fairly massive, optimizing for dozens of pawns and hundreds of pieces
                // of gear simultaneously. Second, many of the stat functions aren't actually linear, and would
                // have to be made to be linear.
                bool currentlyWorn = pawn.apparel.WornApparel.Contains(apparel);

                var currentRange   = pawn.ComfortableTemperatureRange();
                var candidateRange = currentRange;
                if (outfit.AutoTemp)
                {
                    var seasonalTemp = pawn.Map.mapTemperature.SeasonalTemp;
                    outfit.targetTemperatures = new FloatRange(seasonalTemp - outfit.autoTempOffset, seasonalTemp + outfit.autoTempOffset);
                }
                var targetRange   = outfit.targetTemperatures;
                var apparelOffset = GetInsulationStats(apparel);

                // effect of this piece of apparel
                candidateRange.min += apparelOffset.min;
                candidateRange.max += apparelOffset.max;
                if (!currentlyWorn)
                {
                    foreach (var otherApparel in pawn.apparel.WornApparel)
                    {
                        // effect of taking off any other apparel that is incompatible
                        if (!ApparelUtility.CanWearTogether(apparel.def, otherApparel.def, pawn.RaceProps.body))
                        {
                            var otherInsulationRange = GetInsulationStats(otherApparel);

                            candidateRange.min -= otherInsulationRange.min;
                            candidateRange.max -= otherInsulationRange.max;
                        }
                    }
                }

                // did we get any closer to our target range? (smaller distance is better, negative values are overkill).
                var currentDistance = new FloatRange(Mathf.Max(currentRange.min - targetRange.min, 0f),
                                                     Mathf.Max(targetRange.max - currentRange.max, 0f));
                var candidateDistance = new FloatRange(Mathf.Max(candidateRange.min - targetRange.min, 0f),
                                                       Mathf.Max(targetRange.max - candidateRange.max, 0f));

                // improvement in distances
                insulation = InsulationFactorCurve.Evaluate(currentDistance.min - candidateDistance.min) +
                             InsulationFactorCurve.Evaluate(currentDistance.max - candidateDistance.max);
#if DEBUG
                Log.Message($"{pawn.Name.ToStringShort} :: {apparel.LabelCap}\n" +
                            $"\ttarget range: {targetRange}, current range: {currentRange}, candidate range {candidateRange}\n" +
                            $"\tcurrent distance: {currentDistance}, candidate distance: {candidateDistance}\n" +
                            $"\timprovement: {(currentDistance.min - candidateDistance.min) + (currentDistance.max - candidateDistance.max)}, insulation score: {insulation}\n");
#endif
            }
            else
            {
                float statValue;
                if (neededWarmth == NeededWarmth.Warm)
                {
                    statValue  = apparel.GetStatValue(StatDefOf.Insulation_Cold, true);
                    insulation = InsulationTemperatureScoreFactorCurve_Need.Evaluate(statValue);
                }
                else if (neededWarmth == NeededWarmth.Cool)
                {
                    statValue  = apparel.GetStatValue(StatDefOf.Insulation_Heat, true);
                    insulation = InsulationTemperatureScoreFactorCurve_Need.Evaluate(statValue);
                }
                else
                {
                    insulation = 1f;
                }
            }
            return(insulation);
        }
Пример #16
0
        public static void GenerateStartingApparelFor(Pawn pawn, PawnGenerationRequest request)
        {
            if (pawn.RaceProps.ToolUser && pawn.RaceProps.IsFlesh)
            {
                pawn.apparel.DestroyAll();
                float        randomInRange = pawn.kindDef.apparelMoney.RandomInRange;
                float        mapTemperature;
                NeededWarmth neededWarmth = ApparelWarmthNeededNow(pawn, request, out mapTemperature);
                bool         flag         = Rand.Value < pawn.kindDef.apparelAllowHeadgearChance;
                debugSb = null;
                if (DebugViewSettings.logApparelGeneration)
                {
                    debugSb = new StringBuilder();
                    debugSb.AppendLine("Generating apparel for " + pawn);
                    debugSb.AppendLine("Money: " + randomInRange.ToString("F0"));
                    debugSb.AppendLine("Needed warmth: " + neededWarmth);
                    debugSb.AppendLine("Headgear allowed: " + flag);
                }
                if (randomInRange < 0.001f)
                {
                    GenerateWorkingPossibleApparelSetFor(pawn, randomInRange, flag);
                }
                else
                {
                    int num = 0;
                    while (true)
                    {
                        GenerateWorkingPossibleApparelSetFor(pawn, randomInRange, flag);
                        if (DebugViewSettings.logApparelGeneration)
                        {
                            debugSb.Append(num.ToString().PadRight(5) + "Trying: " + workingSet.ToString());
                        }
                        if (num < 10 && Rand.Value < 0.85f)
                        {
                            float num2       = Rand.Range(0.45f, 0.8f);
                            float totalPrice = workingSet.TotalPrice;
                            if (totalPrice < randomInRange * num2)
                            {
                                if (DebugViewSettings.logApparelGeneration)
                                {
                                    debugSb.AppendLine(" -- Failed: Spent $" + totalPrice.ToString("F0") + ", < " + (num2 * 100f).ToString("F0") + "% of money.");
                                }
                                goto IL_035e;
                            }
                        }
                        if (num < 20 && Rand.Value < 0.97f && !workingSet.Covers(BodyPartGroupDefOf.Torso))
                        {
                            if (DebugViewSettings.logApparelGeneration)
                            {
                                debugSb.AppendLine(" -- Failed: Does not cover torso.");
                            }
                        }
                        else if (num < 30 && Rand.Value < 0.8f && workingSet.CoatButNoShirt())
                        {
                            if (DebugViewSettings.logApparelGeneration)
                            {
                                debugSb.AppendLine(" -- Failed: Coat but no shirt.");
                            }
                        }
                        else
                        {
                            if (num < 50)
                            {
                                bool mustBeSafe = num < 17;
                                if (!workingSet.SatisfiesNeededWarmth(neededWarmth, mustBeSafe, mapTemperature))
                                {
                                    if (DebugViewSettings.logApparelGeneration)
                                    {
                                        debugSb.AppendLine(" -- Failed: Wrong warmth.");
                                    }
                                    goto IL_035e;
                                }
                            }
                            if (num >= 80 || !workingSet.IsNaked(pawn.gender))
                            {
                                break;
                            }
                            if (DebugViewSettings.logApparelGeneration)
                            {
                                debugSb.AppendLine(" -- Failed: Naked.");
                            }
                        }
                        goto IL_035e;
IL_035e:
                        num++;
                    }
                    if (DebugViewSettings.logApparelGeneration)
                    {
                        debugSb.Append(" -- Approved! Total price: $" + workingSet.TotalPrice.ToString("F0") + ", TotalInsulationCold: " + workingSet.TotalInsulationCold);
                    }
                }
                if ((!pawn.kindDef.apparelIgnoreSeasons || request.ForceAddFreeWarmLayerIfNeeded) && !workingSet.SatisfiesNeededWarmth(neededWarmth, mustBeSafe: true, mapTemperature))
                {
                    workingSet.AddFreeWarmthAsNeeded(neededWarmth, mapTemperature);
                }
                if (DebugViewSettings.logApparelGeneration)
                {
                    Log.Message(debugSb.ToString());
                }
                workingSet.GiveToPawn(pawn);
                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, reportFailure: 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 (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));
        }
Пример #18
0
        public static void GenerateStartingApparelFor(Pawn pawn, PawnGenerationRequest request)
        {
            if (!pawn.RaceProps.ToolUser || !pawn.RaceProps.IsFlesh)
            {
                return;
            }
            pawn.apparel.DestroyAll();
            float        randomInRange = pawn.kindDef.apparelMoney.RandomInRange;
            float        mapTemperature;
            NeededWarmth neededWarmth  = ApparelWarmthNeededNow(pawn, request, out mapTemperature);
            bool         allowHeadgear = Rand.Value < pawn.kindDef.apparelAllowHeadgearChance;

            debugSb = null;
            if (DebugViewSettings.logApparelGeneration)
            {
                debugSb = new StringBuilder();
                debugSb.AppendLine("Generating apparel for " + pawn);
                debugSb.AppendLine("Money: " + randomInRange.ToString("F0"));
                debugSb.AppendLine("Needed warmth: " + neededWarmth);
                debugSb.AppendLine("Headgear allowed: " + allowHeadgear.ToString());
            }
            int @int = Rand.Int;

            tmpApparelCandidates.Clear();
            for (int i = 0; i < allApparelPairs.Count; i++)
            {
                ThingStuffPair thingStuffPair = allApparelPairs[i];
                if (CanUsePair(thingStuffPair, pawn, randomInRange, allowHeadgear, @int))
                {
                    tmpApparelCandidates.Add(thingStuffPair);
                }
            }
            if (randomInRange < 0.001f)
            {
                GenerateWorkingPossibleApparelSetFor(pawn, randomInRange, tmpApparelCandidates);
            }
            else
            {
                int num = 0;
                while (true)
                {
                    GenerateWorkingPossibleApparelSetFor(pawn, randomInRange, tmpApparelCandidates);
                    if (DebugViewSettings.logApparelGeneration)
                    {
                        debugSb.Append(num.ToString().PadRight(5) + "Trying: " + workingSet.ToString());
                    }
                    if (num < 10 && Rand.Value < 0.85f && randomInRange < 9999999f)
                    {
                        float num2       = Rand.Range(0.45f, 0.8f);
                        float totalPrice = workingSet.TotalPrice;
                        if (totalPrice < randomInRange * num2)
                        {
                            if (DebugViewSettings.logApparelGeneration)
                            {
                                debugSb.AppendLine(" -- Failed: Spent $" + totalPrice.ToString("F0") + ", < " + (num2 * 100f).ToString("F0") + "% of money.");
                            }
                            goto IL_037d;
                        }
                    }
                    if (num < 20 && Rand.Value < 0.97f && !workingSet.Covers(BodyPartGroupDefOf.Torso))
                    {
                        if (DebugViewSettings.logApparelGeneration)
                        {
                            debugSb.AppendLine(" -- Failed: Does not cover torso.");
                        }
                    }
                    else if (num < 30 && Rand.Value < 0.8f && workingSet.CoatButNoShirt())
                    {
                        if (DebugViewSettings.logApparelGeneration)
                        {
                            debugSb.AppendLine(" -- Failed: Coat but no shirt.");
                        }
                    }
                    else
                    {
                        if (num < 50)
                        {
                            bool mustBeSafe = num < 17;
                            if (!workingSet.SatisfiesNeededWarmth(neededWarmth, mustBeSafe, mapTemperature))
                            {
                                if (DebugViewSettings.logApparelGeneration)
                                {
                                    debugSb.AppendLine(" -- Failed: Wrong warmth.");
                                }
                                goto IL_037d;
                            }
                        }
                        if (num >= 80 || !workingSet.IsNaked(pawn.gender))
                        {
                            break;
                        }
                        if (DebugViewSettings.logApparelGeneration)
                        {
                            debugSb.AppendLine(" -- Failed: Naked.");
                        }
                    }
                    goto IL_037d;
IL_037d:
                    num++;
                }
                if (DebugViewSettings.logApparelGeneration)
                {
                    debugSb.Append(" -- Approved! Total price: $" + workingSet.TotalPrice.ToString("F0") + ", TotalInsulationCold: " + workingSet.TotalInsulationCold);
                }
            }
            if ((!pawn.kindDef.apparelIgnoreSeasons || request.ForceAddFreeWarmLayerIfNeeded) && !workingSet.SatisfiesNeededWarmth(neededWarmth, mustBeSafe: true, mapTemperature))
            {
                workingSet.AddFreeWarmthAsNeeded(neededWarmth, mapTemperature);
            }
            if (DebugViewSettings.logApparelGeneration)
            {
                Log.Message(debugSb.ToString());
            }
            workingSet.GiveToPawn(pawn);
            workingSet.Reset(null, null);
            if (pawn.kindDef.apparelColor != Color.white)
            {
                List <Apparel> wornApparel = pawn.apparel.WornApparel;
                for (int j = 0; j < wornApparel.Count; j++)
                {
                    wornApparel[j].SetColor(pawn.kindDef.apparelColor, reportFailure: false);
                }
            }
            List <SpecificApparelRequirement> specificApparelRequirements = pawn.kindDef.specificApparelRequirements;

            if (specificApparelRequirements != null)
            {
                foreach (SpecificApparelRequirement item in specificApparelRequirements.Where((SpecificApparelRequirement x) => x.Color != default(Color)))
                {
                    List <Apparel> wornApparel2 = pawn.apparel.WornApparel;
                    for (int k = 0; k < wornApparel2.Count; k++)
                    {
                        if (ApparelRequirementHandlesThing(item, wornApparel2[k].def))
                        {
                            wornApparel2[k].SetColor(item.Color, reportFailure: false);
                        }
                    }
                }
            }
            foreach (Apparel item2 in pawn.apparel.WornApparel)
            {
                CompBiocodable compBiocodable = item2.TryGetComp <CompBiocodable>();
                if (compBiocodable != null && Rand.Chance(request.BiocodeApparelChance))
                {
                    compBiocodable.CodeFor(pawn);
                }
            }
        }
            public void AddFreeWarmthAsNeeded(NeededWarmth warmth, float mapTemperature)
            {
                if (warmth == NeededWarmth.Any)
                {
                    return;
                }
                if (warmth == NeededWarmth.Cool)
                {
                    return;
                }
                if (DebugViewSettings.logApparelGeneration)
                {
                    PawnApparelGenerator.debugSb.AppendLine();
                    PawnApparelGenerator.debugSb.AppendLine("Trying to give free warm layer.");
                }
                for (int i = 0; i < 3; i++)
                {
                    if (!this.SatisfiesNeededWarmth(warmth, true, mapTemperature))
                    {
                        if (DebugViewSettings.logApparelGeneration)
                        {
                            PawnApparelGenerator.debugSb.AppendLine("Checking to give free torso-cover at max price " + PawnApparelGenerator.freeWarmParkaMaxPrice);
                        }
                        Predicate <ThingStuffPair> parkaPairValidator = delegate(ThingStuffPair pa)
                        {
                            if (pa.Price > PawnApparelGenerator.freeWarmParkaMaxPrice)
                            {
                                return(false);
                            }
                            if (pa.InsulationCold <= 0f)
                            {
                                return(false);
                            }
                            if (!pa.thing.apparel.bodyPartGroups.Contains(BodyPartGroupDefOf.Torso))
                            {
                                return(false);
                            }
                            float replacedInsulationCold = this.GetReplacedInsulationCold(pa);
                            return(replacedInsulationCold < pa.InsulationCold);
                        };
                        int j = 0;
                        while (j < 2)
                        {
                            ThingStuffPair candidate;
                            if (j == 0)
                            {
                                if ((from pa in PawnApparelGenerator.allApparelPairs
                                     where parkaPairValidator(pa) && pa.InsulationCold < 40f
                                     select pa).TryRandomElementByWeight((ThingStuffPair pa) => pa.Commonality / (pa.Price * pa.Price), out candidate))
                                {
                                    goto IL_12F;
                                }
                            }
                            else if ((from pa in PawnApparelGenerator.allApparelPairs
                                      where parkaPairValidator(pa)
                                      select pa).TryMaxBy((ThingStuffPair x) => x.InsulationCold - this.GetReplacedInsulationCold(x), out candidate))
                            {
                                goto IL_12F;
                            }
                            j++;
                            continue;
IL_12F:
                            if (DebugViewSettings.logApparelGeneration)
                            {
                                PawnApparelGenerator.debugSb.AppendLine(string.Concat(new object[]
                                {
                                    "Giving free torso-cover: ",
                                    candidate,
                                    " insulation=",
                                    candidate.InsulationCold
                                }));
                                foreach (ThingStuffPair thingStuffPair in from a in this.aps
                                         where !ApparelUtility.CanWearTogether(a.thing, candidate.thing, this.body)
                                         select a)
                                {
                                    PawnApparelGenerator.debugSb.AppendLine(string.Concat(new object[]
                                    {
                                        "    -replaces ",
                                        thingStuffPair.ToString(),
                                        " InsulationCold=",
                                        thingStuffPair.InsulationCold
                                    }));
                                }
                            }
                            this.aps.RemoveAll((ThingStuffPair pa) => !ApparelUtility.CanWearTogether(pa.thing, candidate.thing, this.body));
                            this.aps.Add(candidate);
                            break;
                        }
                    }
                    if (GenTemperature.SafeTemperatureRange(this.raceDef, this.aps).Includes(mapTemperature))
                    {
                        break;
                    }
                }
                if (!this.SatisfiesNeededWarmth(warmth, true, mapTemperature))
                {
                    if (DebugViewSettings.logApparelGeneration)
                    {
                        PawnApparelGenerator.debugSb.AppendLine("Checking to give free hat at max price " + PawnApparelGenerator.freeWarmHatMaxPrice);
                    }
                    Predicate <ThingStuffPair> hatPairValidator = delegate(ThingStuffPair pa)
                    {
                        if (pa.Price > PawnApparelGenerator.freeWarmHatMaxPrice)
                        {
                            return(false);
                        }
                        if (pa.InsulationCold < 7f)
                        {
                            return(false);
                        }
                        if (!pa.thing.apparel.bodyPartGroups.Contains(BodyPartGroupDefOf.FullHead) && !pa.thing.apparel.bodyPartGroups.Contains(BodyPartGroupDefOf.UpperHead))
                        {
                            return(false);
                        }
                        float replacedInsulationCold = this.GetReplacedInsulationCold(pa);
                        return(replacedInsulationCold < pa.InsulationCold);
                    };
                    ThingStuffPair hatPair;
                    if ((from pa in PawnApparelGenerator.allApparelPairs
                         where hatPairValidator(pa)
                         select pa).TryRandomElementByWeight((ThingStuffPair pa) => pa.Commonality / (pa.Price * pa.Price), out hatPair))
                    {
                        if (DebugViewSettings.logApparelGeneration)
                        {
                            PawnApparelGenerator.debugSb.AppendLine(string.Concat(new object[]
                            {
                                "Giving free hat: ",
                                hatPair,
                                " insulation=",
                                hatPair.InsulationCold
                            }));
                            foreach (ThingStuffPair thingStuffPair2 in from a in this.aps
                                     where !ApparelUtility.CanWearTogether(a.thing, hatPair.thing, this.body)
                                     select a)
                            {
                                PawnApparelGenerator.debugSb.AppendLine(string.Concat(new object[]
                                {
                                    "    -replaces ",
                                    thingStuffPair2.ToString(),
                                    " InsulationCold=",
                                    thingStuffPair2.InsulationCold
                                }));
                            }
                        }
                        this.aps.RemoveAll((ThingStuffPair pa) => !ApparelUtility.CanWearTogether(pa.thing, hatPair.thing, this.body));
                        this.aps.Add(hatPair);
                    }
                }
                if (DebugViewSettings.logApparelGeneration)
                {
                    PawnApparelGenerator.debugSb.AppendLine("New TotalInsulationCold: " + this.TotalInsulationCold);
                }
            }
        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));
        }
Пример #21
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);
        }