Пример #1
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);
        }
Пример #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) && (!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);
        }
Пример #3
0
        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
        }
Пример #4
0
        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);
        }
Пример #5
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);
        }