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); } } }
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); }
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); }
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); }
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); }