示例#1
0
        private void OptimeFromList(ref bool changed)
        {
            if (this.optimized)
            {
                return;
            }

            while (true)
            {
                int     changeIndex            = -1;
                Apparel changeApparel          = null;
                float   changeApparelRawScore  = 0;
                float   changeApparelScoreGain = 0;

                for (int i = 0; i < this.allApparelsItems.Count; i++)
                {
                    Apparel apparel = this.allApparelsItems[i];
                    if ((!apparel.IsForbidden(this.saveablePawn.pawn)) &&
                        (this.outfit.filter.Allows(apparel)))
                    {
                        float apparelRawScore = this.allApparelsScore[i];
                        float apparelGainScore;
                        if (this.CalculateApparelScoreGain(apparel, apparelRawScore, out apparelGainScore))
                        {
                            if ((apparelGainScore > changeApparelScoreGain) ||
                                ((apparelGainScore == changeApparelScoreGain) && (saveablePawn.pawn.apparel.WornApparel.Contains(apparel))))
                            {
                                changeIndex            = i;
                                changeApparel          = apparel;
                                changeApparelRawScore  = apparelRawScore;
                                changeApparelScoreGain = apparelGainScore;
                            }
                        }
                    }
                }

                if (changeApparel == null)
                {
                    this.optimized = true;
                    return;
                }
                else
                {
                    changed = true;
                    this.allApparelsItems.RemoveAt(changeIndex);
                    this.allApparelsScore.RemoveAt(changeIndex);

                    this.calculedApparelItems.Add(changeApparel);
                    this.calculedApparelScore.Add(changeApparelRawScore);
                }
            }
        }
示例#2
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);
        }
示例#3
0
        private static bool CanWearApparel(Pawn pawn, Apparel apparel)
        {
            if (EquipmentUtility.IsBiocoded(apparel) && !EquipmentUtility.IsBiocodedFor(apparel, pawn))
            {
                return(false);
            }

            if (pawn.apparel.WouldReplaceLockedApparel(apparel))
            {
                return(false);
            }

            if (apparel.IsForbidden(pawn))
            {
                return(false);
            }

            return(true);
        }
示例#4
0
        public void AddApparel(Apparel a)
        {
#if DEBUG
            Log.Warning("AddApparel " + a.Label + " Spawned: " + a.Spawned + " IsForbidden: " + a.IsForbidden(Faction.OfPlayer));
#endif
            if (a != null)
            {
                if (this.settings.AllowedToAccept(a))
                {
                    if (a.Spawned)
                    {
                        a.DeSpawn();
                    }
                    this.StoredApparel.AddApparel(a);
                }
                else // Not Allowed
                {
                    if (!WorldComp.AddApparel(a))
                    {
                        if (!a.Spawned)
                        {
                            BuildingUtil.DropThing(a, this, this.CurrentMap, false);
                        }
                    }
                }
            }
        }
        // private static NeededWarmth neededWarmth;
        // ReSharper disable once InconsistentNaming
        public static bool TryGiveJob_Prefix([CanBeNull] ref Job __result, Pawn pawn)
        {
            __result = null;
            if (pawn.outfits == null)
            {
                Log.ErrorOnce(
                    pawn + " tried to run JobGiver_OutfitterOptimizeApparel without an OutfitTracker",
                    5643897);
                return(false);
            }

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

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

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

            for (int i = 0; i < wornApparel.Count; i++)
            {
                Apparel          ap   = wornApparel[i];
                ApparelStatCache conf = pawn.GetApparelStatCache();

                bool notAllowed = !currentOutfit.filter.Allows(ap) &&
                                  pawn.outfits.forcedHandler.AllowedToAutomaticallyDrop(ap);

                bool shouldDrop = conf.ApparelScoreRaw(ap) < 0f &&
                                  pawn.outfits.forcedHandler.AllowedToAutomaticallyDrop(ap);

                bool someoneWantsIt = pawn.GetApparelStatCache().ToDropList.ContainsKey(ap);

                if (notAllowed || shouldDrop || someoneWantsIt)
                {
                    __result = new Job(JobDefOf.RemoveApparel, ap)
                    {
                        haulDroppedApparel = true
                    };
                    if (someoneWantsIt)
                    {
                        pawn.GetApparelStatCache().ToDropList[ap].mindState.nextApparelOptimizeTick = -5000;
                        pawn.GetApparelStatCache().ToDropList[ap].mindState.Notify_OutfitChanged();
                        pawn.GetApparelStatCache().ToDropList.Remove(ap);
                    }

                    return(false);
                }
            }

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

            if (list.Count == 0)
            {
                SetNextOptimizeTick(pawn);
                return(false);
            }

            for (int i = 0; i < list.Count; i++)
            {
                Thing   t       = list[i];
                Apparel apparel = (Apparel)t;

                // Not allowed
                if (!currentOutfit.filter.Allows(apparel))
                {
                    continue;
                }

                // Not in store
                if (apparel.Map.haulDestinationManager.SlotGroupAt(apparel.Position) == null)
                {
                    continue;
                }

                // Forbidden
                if (apparel.IsForbidden(pawn))
                {
                    continue;
                }

                float gain = pawn.ApparelScoreGain(apparel);

                // this blocks pawns constantly switching between the recent apparel, due to shifting calculations
                // not very elegant but working
                // if (pawn.GetApparelStatCache().recentApparel.Contains(apparel))
                // {
                // gain *= 0.01f;
                // }
                if (DebugViewSettings.debugApparelOptimize)
                {
                    _debugSb.AppendLine(apparel.LabelCap + ": " + gain.ToString("F2"));
                }

                //  float otherGain = 0f;
                //  Pawn otherPawn = null;
                //  foreach (Pawn otherP in pawn.Map.mapPawns.FreeColonistsSpawned.ToList())
                //  {
                //      if (otherP == pawn)
                //      {
                //          continue;
                //      }
                //      if (otherP.ApparelScoreGain(apparel) >= MinScoreGainToCare)
                //      {
                //          if (ApparelUtility.HasPartsToWear(pawn, apparel.def))
                //          {
                //              if (pawn.CanReserveAndReach(apparel, PathEndMode.OnCell, pawn.NormalMaxDanger(), 1))
                //              {
                //                  thing = apparel;
                //                  score = gain;
                //              }
                //          }
                //          otherPawn = otherP;
                //          otherGain = Mathf.Max(otherGain, otherP.ApparelScoreGain(apparel));
                //      }
                //  }

                if (gain >= MinScoreGainToCare && gain >= score)
                {
                    if (ApparelUtility.HasPartsToWear(pawn, apparel.def))
                    {
                        if (pawn.CanReserveAndReach(apparel, PathEndMode.OnCell, pawn.NormalMaxDanger()))
                        {
                            thing = apparel;
                            score = gain;
                        }
                    }
                }
            }

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

            // New stuff
            if (false)
            {
                IEnumerable <Pawn> list2 =
                    pawn.Map.mapPawns.FreeColonistsSpawned.Where(x => x.IsColonistPlayerControlled);
                foreach (Apparel ap in wornApparel)
                {
                    foreach (Pawn otherPawn in list2)
                    {
                        foreach (Apparel otherAp in otherPawn.apparel.WornApparel.Where(
                                     x => !ApparelUtility.CanWearTogether(ap.def, x.def, pawn.RaceProps.body)))
                        {
                            float gain      = pawn.ApparelScoreGain(otherAp);
                            float otherGain = otherPawn.ApparelScoreGain(ap);
                            if (gain > MinScoreGainToCare && gain >= score && otherGain > MinScoreGainToCare)
                            {
                                score = gain;
                                Log.Message(
                                    "OUTFITTER: " + pawn + " wants " + otherAp + " currently worn by " + otherPawn
                                    + ", scores: " + gain + " - " + otherGain + " - " + score);

                                if (!otherPawn.GetApparelStatCache().ToDropList.ContainsKey(ap))
                                {
                                    otherPawn.GetApparelStatCache().ToDropList.Add(otherAp, otherPawn);
                                    otherPawn.mindState.nextApparelOptimizeTick = -5000;
                                    otherPawn.mindState.Notify_OutfitChanged();
                                }
                            }
                        }
                    }
                }
            }

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

            // foreach (Apparel apparel in wornApparel)
            // {
            // pawn.GetApparelStatCache().recentApparel.Add(apparel);
            // }
            __result = new Job(JobDefOf.Wear, thing);
            pawn.Reserve(thing, __result, 1, 1);
            return(false);
        }
示例#6
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);
        }