public static bool canCarrySidearmInstance(ThingWithComps sidearmThing, Pawn pawn, out string errString) { //nicked from EquipmentUtility.CanEquip CompBladelinkWeapon compBladelinkWeapon = sidearmThing.TryGetComp <CompBladelinkWeapon>(); if (compBladelinkWeapon != null && compBladelinkWeapon.bondedPawn != null && compBladelinkWeapon.bondedPawn != pawn) { errString = "BladelinkBondedToSomeoneElse".Translate(); return(false); } if (EquipmentUtility.IsBiocoded(sidearmThing) && pawn != sidearmThing.TryGetComp <CompBiocodableWeapon>().CodedPawn) { errString = "BiocodedCodedForSomeoneElse".Translate(); return(false); } if (compBladelinkWeapon != null && compBladelinkWeapon.bondedPawn == null) { errString = "SidearmPickupFail_NotYetBladelinkBonded".Translate(); return(false); } ThingDefStuffDefPair sidearm = sidearmThing.toThingDefStuffDefPair(); return(canCarrySidearmType(sidearm, pawn, out errString)); }
private static bool CanEquipThis(bool combat, Pawn pawn, CompMeeseeksMemory compMeeseeksMemory, Thing weapon, List <SkillDef> relevantSkills) { if (weapon.IsForbidden(pawn)) { AddDebugLine("Forbidden: " + weapon.GetUniqueLoadID()); return(false); } if (weapon.IsBurning()) { AddDebugLine("Burning: " + weapon.GetUniqueLoadID()); return(false); } if (EquipmentUtility.IsBiocoded(weapon)) { AddDebugLine("Biocoded: " + weapon.GetUniqueLoadID()); return(false); } if (!pawn.CanReserveAndReach(weapon, PathEndMode.OnCell, pawn.NormalMaxDanger())) { AddDebugLine("Can't touch this: " + weapon.GetUniqueLoadID()); return(false); } if (!combat && !HasReleventStatModifiers(weapon, relevantSkills)) { AddDebugLine("Irrelevant: " + weapon.GetUniqueLoadID()); return(false); } return(true); }
public override void TransformValue(StatRequest req, ref float val) { if (req.HasThing && EquipmentUtility.IsBiocoded(req.Thing)) { val *= 0f; } }
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) && (!EquipmentUtility.IsBiocoded(apparel) || EquipmentUtility.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); }
private bool WillDrop(Pawn pawn, Thing i) { // To prevent dropping ammo from CE or similar var ammoCategory = DefDatabase <ThingCategoryDef> .GetNamedSilentFail("Ammo"); if (ammoCategory != null && i.def.IsWithinCategory(ammoCategory)) { return(false); } if (EquipmentUtility.IsBiocoded(i)) { return(false); } if (i.TryGetComp <CompBladelinkWeapon>()?.bondedPawn != null) { return(false); } return(i.def != ThingDefOf.Silver && !i.IsMeal() && !pawn.Bought(i) && !BoughtOrSoldByPlayer(i) && !pawn.inventory.NotForSale(i)); }
private static bool CanWearThis(Pawn pawn, CompMeeseeksMemory compMeeseeksMemory, Thing apparel, List <SkillDef> relevantSkills) { if (apparel.IsForbidden(pawn)) { return(false); } if (apparel.IsBurning()) { return(false); } if (EquipmentUtility.IsBiocoded(apparel)) { return(false); } if (!ApparelUtility.HasPartsToWear(pawn, apparel.def)) { return(false); } if (!pawn.CanReserveAndReach(apparel, PathEndMode.OnCell, pawn.NormalMaxDanger())) { return(false); } bool armor = false; foreach (ThingCategoryDef thingCategoryDef in apparel.def.thingCategories) { if (thingCategoryDef.defName.ToLower().Contains("armor".ToLower())) { armor = true; break; } } if (pawn.Drafted || compMeeseeksMemory.guardPosition.IsValid) { if (!armor) { return(false); } } else { if (armor) { return(false); } if (!HasReleventStatModifiers(apparel, relevantSkills)) { return(false); } } List <Apparel> wornApparel = pawn.apparel.WornApparel; for (int i = 0; i < wornApparel.Count; i++) { if (!ApparelUtility.CanWearTogether(wornApparel[i].def, apparel.def, pawn.RaceProps.body)) { return(false); } } return(true); }
public static Thing PickBestWeaponFor(Pawn pawn) { if (pawn.equipment == null) { return(null); } if (pawn.Faction != Faction.OfPlayer) { return(null); } if (pawn.IsQuestLodger()) { return(null); } if (!pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation) || pawn.WorkTagIsDisabled(WorkTags.Violent)) { return(null); } if (pawn.Map == null) { return(null); } bool isBrawler = pawn.story?.traits?.HasTrait(TraitDefOf.Brawler) ?? false; bool preferRanged = !isBrawler && (!pawn.equipment.Primary?.def.IsMeleeWeapon ?? false || pawn.equipment.Primary == null); Predicate <Thing> validator = delegate(Thing t) { if (!t.def.IsWeapon) { return(false); } if (t.IsForbidden(pawn)) { return(false); } if (isBrawler && t.def.IsRangedWeapon) { return(false); } if (preferRanged && t.def.IsMeleeWeapon) { return(false); } if (!preferRanged && t.def.IsRangedWeapon) { return(false); } if (t.def.weaponTags != null && t.def.weaponTags.Where(x => x.ToLower().Contains("grenade")).Any()) { return(false); } if (t.def.IsRangedWeapon && t.def.Verbs.Where(x => x.verbClass == typeof(Verb_ShootOneUse)).Any()) { return(false); } return(true); }; Thing thing = null; float num2 = 0f; List <Thing> list = pawn.Map.listerThings.ThingsInGroup(ThingRequestGroup.Weapon).Where(x => validator(x)).ToList(); if (list.Count == 0) { return(null); } List <Thing> weapons = pawn.inventory.innerContainer.InnerListForReading.Where(x => validator(x)).ToList(); list.AddRange(weapons); if (pawn.equipment.Primary != null) { list.Add(pawn.equipment.Primary); } for (int j = 0; j < list.Count; j++) { Thing weapon = list[j]; if (!weapon.IsBurning()) { float num3 = WeaponScoreGain(weapon, StatDefOf.AccuracyMedium); if (!(num3 < 0.05f) && !(num3 < num2) && (!EquipmentUtility.IsBiocoded(weapon) || EquipmentUtility.IsBiocodedFor(weapon, pawn)) && EquipmentUtility.CanEquip(weapon, pawn) && pawn.CanReserveAndReach(weapon, PathEndMode.OnCell, pawn.NormalMaxDanger())) { thing = weapon; num2 = num3; } } } return(thing); }
private static float Likey(Pawn pawn, Thing thing) { if (thing == null) { return(0); } // Health of object var hpFactor = thing.def.useHitPoints?(float)thing.HitPoints / thing.MaxHitPoints:1; // Apparel var appFactor = thing is Apparel apparel ? 1 + ApparelScoreGain(pawn, apparel) : 0.8f; // Not apparel, less likey //Log.Message(thing.Label + " - apparel score: " + appFactor); var hungerFactor = GetHungerFactor(pawn); // Food if (ItemUtility.IsFood(thing) && pawn.RaceProps.CanEverEat(thing)) { appFactor = FoodUtility.FoodOptimality(pawn, thing, FoodUtility.GetFinalIngestibleDef(thing), 0, true) / 300f; // 300 = optimality max //Log.Message($"{pawn.LabelShort} looked at {thing.LabelShort} at {thing.Position} and scored it {appFactor}."); appFactor += hungerFactor; //Log.Message($"{pawn.LabelShort} added {hungerFactor} to the score for his hunger."); if (thing.def.IsWithinCategory(ThingCategoryDefOf.PlantFoodRaw)) { appFactor -= 0.25f; } if (thing.def.IsWithinCategory(ThingCategoryDefOf.MeatRaw)) { appFactor -= 0.5f; } } // Other consumables else if (ItemUtility.IsIngestible(thing) && thing.def.ingestible.joy > 0) { appFactor = 1 + thing.def.ingestible.joy * 0.5f; // Hungry? Care less about other stuff if (hungerFactor > 0) { appFactor -= hungerFactor; } } else { // Hungry? Care less about other stuff if (hungerFactor > 0) { appFactor -= hungerFactor; } } if (EquipmentUtility.IsBiocoded(thing) && !EquipmentUtility.IsBiocodedFor(thing, pawn)) { return(0); } // Weapon if (thing.def.IsRangedWeapon) { if (pawn.story.traits.HasTrait(TraitDefOf.Brawler)) { return(0); } if (pawn.apparel.WornApparel.OfType <ShieldBelt>().Any()) { return(0); } } if (thing.def.IsWeapon) { // Weapon is also good! appFactor = 1; if (pawn.RaceProps.Humanlike && pawn.WorkTagIsDisabled(WorkTags.Violent)) { return(0); } if (!pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation)) { return(0); } if (!ItemUtility.AlienFrameworkAllowsIt(pawn.def, thing.def, "CanEquip")) { return(0); } } // Shield belt if (thing is ShieldBelt) { if (pawn.equipment.Primary?.def.IsRangedWeapon == true) { return(0); } if (!ItemUtility.AlienFrameworkAllowsIt(pawn.def, thing.def, "CanEquip")) { return(0); } } // Quality of object var qFactor = 0.7f; if (thing.TryGetQuality(out var cat)) { qFactor = (float)cat; qFactor -= (float)QualityCategory.Normal; qFactor /= (float)QualityCategory.Masterwork - (float)QualityCategory.Normal; qFactor += 1; //Log.Message(thing.Label+" - quality: "+cat+" = "+ qFactor); } // Tech level of object var tFactor = 0.8f; if (thing.def.techLevel != TechLevel.Undefined) { tFactor = (float)thing.def.techLevel; tFactor -= (float)pawn.Faction.def.techLevel; tFactor /= (float)TechLevel.Spacer; tFactor += 1; //Log.Message(thing.Label + " - techlevel: " + thing.def.techLevel + " = " + tFactor); } var rFactor = Rand.RangeSeeded(0.5f, 1.7f, pawn.thingIDNumber * 60509 + thing.thingIDNumber * 33151); //if(hpFactor*hpFactor*qFactor*qFactor*tFactor*appFactor > 0.5) // Log.Message($"{thing.LabelShort.Colorize(Color.yellow)} - score: {hpFactor * hpFactor * qFactor * qFactor * tFactor * appFactor}, random: {rFactor}"); return(Mathf.Max(0, hpFactor * hpFactor * qFactor * qFactor * tFactor * appFactor * rFactor)); // <= 0.5 = don't buy }
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); }