// Copied so outfits can be commented
        public static float ApparelScoreGain(Pawn pawn, Apparel ap)
        {
            if (ap is ShieldBelt && pawn.equipment.Primary != null && pawn.equipment.Primary.def.IsWeaponUsingProjectiles)
            {
                return(-1000f);
            }
            float          num         = JobGiver_OptimizeApparel.ApparelScoreRaw(pawn, ap);
            List <Apparel> wornApparel = pawn.apparel.WornApparel;
            bool           flag        = false;

            for (int index = 0; index < wornApparel.Count; ++index)
            {
                if (!ApparelUtility.CanWearTogether(wornApparel[index].def, ap.def, pawn.RaceProps.body))
                {
                    //if (!pawn.outfits.forcedHandler.AllowedToAutomaticallyDrop(wornApparel[index]))
                    //    return -1000f;
                    num -= JobGiver_OptimizeApparel.ApparelScoreRaw(pawn, wornApparel[index]);
                    flag = true;
                }
            }
            if (!flag)
            {
                num *= 10f;
            }
            return(num);
        }
Exemple #2
0
        private bool CalculateApparelScoreGain(Apparel apparel, float score, out float gain)
        {
            if (apparel.def == ThingDefOf.Apparel_PersonalShield && this.pawn.equipment.Primary != null && !this.pawn.equipment.Primary.def.Verbs[0].MeleeRange)
            {
                gain = -1000f;
                return(false);
            }

            gain = score;
            for (int i = 0; i < this.calculedApparelItems.Count; i++)
            {
                Apparel wornApparel = this.calculedApparelItems[i];

                if (!ApparelUtility.CanWearTogether(wornApparel.def, apparel.def))
                {
                    if (!pawn.outfits.forcedHandler.AllowedToAutomaticallyDrop(wornApparel))
                    {
                        return(false);
                    }
                    gain -= this.calculedApparelScore[i];
                }
            }

            return(true);
        }
        public static Job FindEquipJobs(Pawn pawn)
        {
            Log.Message("Finding equip from inv for " + pawn);

            Outfit currentOutfit = pawn.outfits.CurrentOutfit;

            foreach (Apparel apparel in pawn.inventory.innerContainer
                     .Where(t => t is Apparel a &&
                            ApparelUtility.HasPartsToWear(pawn, a.def) &&
                            currentOutfit.filter.Allows(a)))
            {
                Log.Message("Does this work? " + apparel);
                bool conflict = false;
                foreach (Apparel wornApparel in pawn.apparel.WornApparel)
                {
                    if (!ApparelUtility.CanWearTogether(wornApparel.def, apparel.def, pawn.RaceProps.body))
                    {
                        Log.Message("NO. conflicts with " + wornApparel);
                        conflict = true;
                        continue;
                    }
                }
                if (!conflict)
                {
                    Log.Message("totally! Wearing " + apparel + "from inventory");
                    return(new Job(GearUpAndGoJobDefOf.SwapApparelWithInventory, null, apparel));
                }
            }
            return(null);
        }
        private void TryUnequipSomething()
        {
            if (TargetApparel == null)
            {
                return;
            }

            unequipBuffer++;
            Apparel        apparel     = TargetApparel;
            List <Apparel> wornApparel = pawn.apparel.WornApparel;

            for (int num = wornApparel.Count - 1; num >= 0; num--)
            {
                if (!ApparelUtility.CanWearTogether(apparel.def, wornApparel[num].def, pawn.RaceProps.body))
                {
                    int num2 = (int)(wornApparel[num].GetStatValue(StatDefOf.EquipDelay) * 60f);
                    if (unequipBuffer >= num2)
                    {
                        bool forbid = pawn.Faction != null && pawn.Faction.HostileTo(Faction.OfPlayer);
                        if (!pawn.apparel.TryDrop(wornApparel[num], out var _, pawn.PositionHeld, forbid))
                        {
                            Log.Error(string.Concat(pawn, " could not drop ", wornApparel[num].ToStringSafe()));
                            EndJobWith(JobCondition.Errored);
                        }
                    }
                    break;
                }
            }
        }
Exemple #5
0
        public static float ApparelScoreGain_NewTmp(Pawn pawn, Apparel ap, List <float> wornScoresCache)
        {
            if (ap is ShieldBelt && pawn.equipment.Primary != null && pawn.equipment.Primary.def.IsWeaponUsingProjectiles)
            {
                return(-1000f);
            }
            float          num         = ApparelScoreRaw(pawn, ap);
            List <Apparel> wornApparel = pawn.apparel.WornApparel;
            bool           flag        = false;

            for (int i = 0; i < wornApparel.Count; i++)
            {
                if (!ApparelUtility.CanWearTogether(wornApparel[i].def, ap.def, pawn.RaceProps.body))
                {
                    if (!pawn.outfits.forcedHandler.AllowedToAutomaticallyDrop(wornApparel[i]) || pawn.apparel.IsLocked(wornApparel[i]))
                    {
                        return(-1000f);
                    }
                    num -= wornScoresCache[i];
                    flag = true;
                }
            }
            if (!flag)
            {
                num *= 10f;
            }
            return(num);
        }
        public static Job FindSwapJobs(Pawn pawn)
        {
            List <Apparel> wornApparel   = pawn.apparel.WornApparel;
            Outfit         currentOutfit = pawn.outfits.CurrentOutfit;

            //Looping all apparel is a bit redundant because the caller is already in apparel loop, but the order might not work for this
            for (int i = wornApparel.Count - 1; i >= 0; i--)
            {
                Apparel takeOff = wornApparel[i];
                if (!currentOutfit.filter.Allows(takeOff) && pawn.outfits.forcedHandler.AllowedToAutomaticallyDrop(takeOff))
                {
                    Log.Message("Finding swaps for " + pawn + ", could take off " + takeOff);

                    HashSet <Thing> haulingThings = null;
                    Log.Message("Mods: " + ModsConfig.ActiveModsInLoadOrder.ToStringSafeEnumerable());

                    try
                    {
                        ((Action)(() =>
                        {
                            haulingThings = pawn.TryGetComp <CompHauledToInventory>()?.GetHashSet();
                        }))();
                    }
                    catch (TypeLoadException) { }

                    foreach (Thing t in pawn.inventory.innerContainer)
                    {
                        Log.Message("could wear " + t + "?");
                        if ((haulingThings == null || !haulingThings.Contains(t)) &&
                            t is Apparel swapTo &&
                            currentOutfit.filter.Allows(swapTo) &&
                            ApparelUtility.HasPartsToWear(pawn, swapTo.def))
                        {
                            Log.Message("does " + t + " match?");
                            if (ApparelUtility.CanWearTogether(takeOff.def, swapTo.def, pawn.RaceProps.body))
                            {
                                continue;
                            }
                            Log.Message("does " + t + " fit?");
                            if (FitsAfterSwap(swapTo, pawn, takeOff))
                            {
                                Log.Message("yes totally I'm swapping " + takeOff + " for " + swapTo);
                                return(new Job(GearUpAndGoJobDefOf.SwapApparelWithInventory, takeOff, swapTo));
                            }
                        }
                    }
                    Log.Message("Nothing to swap to: should I return it to inventory?");

                    HashSet <Thing> wornThings = pawn.TryGetComp <CompWornFromInventory>()?.GetHashSet();
                    if (wornThings?.Contains(takeOff) ?? false)
                    {
                        Log.Message("yes totally I'm removing " + takeOff + " back into inventory");
                        return(new Job(GearUpAndGoJobDefOf.SwapApparelWithInventory, takeOff));
                    }
                }
            }
            return(null);
        }
Exemple #7
0
        // Most part is from the source code
        public static void Wear(Pawn pawn, Apparel newApparel, bool dropReplacedApparel = true)
        {
            ValidateArg.NotNull(newApparel, nameof(newApparel));
            ValidateArg.NotNull(pawn, nameof(pawn));

            if (newApparel.Spawned)
            {
                newApparel.DeSpawn();
            }

            if (!ApparelUtility.HasPartsToWear(pawn, newApparel.def))
            {
                Log.Warning(pawn + " tried to wear " + newApparel + " but he has no body parts required to wear it.");
                return;
            }

            List <Apparel> apparelsToReplace = new List <Apparel>();

            for (int num = pawn.apparel.WornApparelCount - 1; num >= 0; num--)
            {
                Apparel oldApparel = pawn.apparel.WornApparel[num];
                if (!ApparelUtility.CanWearTogether(newApparel.def, oldApparel.def, pawn.RaceProps.body))
                {
                    apparelsToReplace.Add(oldApparel);
                }
            }

            foreach (Apparel apparel in apparelsToReplace)
            {
                if (dropReplacedApparel)
                {
                    bool forbid = pawn.Faction != null && pawn.Faction.HostileTo(Faction.OfPlayer);
                    if (!pawn.apparel.TryDrop(apparel, out Apparel _, pawn.PositionHeld, forbid))
                    {
                        Messages.Message(UIText.FailToDrop.Translate(pawn, apparel), MessageTypeDefOf.NeutralEvent);
                        return;
                    }
                }
                else
                {
                    pawn.inventory.innerContainer.TryAddOrTransfer(apparel);
                }
            }

            if (newApparel.Wearer != null)
            {
                Log.Warning(pawn + " is trying to wear " + newApparel + " but this apparel already has a wearer (" + newApparel.Wearer + "). This may or may not cause bugs.");
            }

            // Circumvene accessibility restriction and add apparel directly to inner list.
            object wornApparel = pawn.apparel
                                 .GetType()
                                 .GetField("wornApparel", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)
                                 .GetValue(pawn.apparel);

            wornApparel.GetType().GetMethod("TryAdd", new Type[] { typeof(Thing), typeof(bool) }).Invoke(wornApparel, new object[] { newApparel, false });
        }
 // Token: 0x06000070 RID: 112 RVA: 0x00004858 File Offset: 0x00002A58
 public bool CanWearWithoutDroppingAnything(ThingDef apDef)
 {
     for (int i = 0; i < this.wornApparelDefs.Count; i++)
     {
         if (!ApparelUtility.CanWearTogether(apDef, this.wornApparelDefs[i], ThingDefOf.Human.race.body))
         {
             return(false);
         }
     }
     return(true);
 }
Exemple #9
0
 private bool CanWear(Apparel apparel)
 {
     foreach (Apparel a in this.customOutfit.Apparel)
     {
         if (!ApparelUtility.CanWearTogether(a.def, apparel.def, this.pawn.RaceProps.body))
         {
             return(false);
         }
     }
     return(true);
 }
 private bool CanWear(List <Apparel> worn, Apparel newApparel)
 {
     for (int i = worn.Count - 1; i >= 0; i--)
     {
         Apparel apparel = worn[i];
         if (!ApparelUtility.CanWearTogether(newApparel.def, apparel.def))
         {
             return(false);
         }
     }
     return(true);
 }
Exemple #11
0
        private static bool conflicts(Pawn_ApparelTracker tra, Apparel new_app)
        {
            foreach (var worn_app in tra.WornApparel)
            {
                if (worn_app.has_lock() && (!ApparelUtility.CanWearTogether(worn_app.def, new_app.def, tra.pawn.RaceProps.body)))
                {
                    return(true);
                }
            }

            return(false);
        }
Exemple #12
0
        // Copied so we can make some adjustments
        public static float ApparelScoreGain(Pawn pawn, Apparel ap)
        {
            if (ap is ShieldBelt && pawn.equipment.Primary?.def.IsWeaponUsingProjectiles == true)
            {
                return(-1000);
            }
            // Added
            if (!ItemUtility.AlienFrameworkAllowsIt(pawn.def, ap.def, "CanWear"))
            {
                return(-1000);
            }
            if (!ApparelUtility.HasPartsToWear(pawn, ap.def))
            {
                return(-1000);
            }
            if (pawn.story.traits.HasTrait(TraitDefOf.Nudist))
            {
                return(-1000);
            }
            //if (PawnApparelGenerator.IsHeadgear(ap.def)) return 0;
            float          num         = JobGiver_OptimizeApparel.ApparelScoreRaw(pawn, ap);
            List <Apparel> wornApparel = pawn.apparel.WornApparel;
            bool           flag        = false;
            // Added:
            var newReq = ItemUtility.IsRequiredByRoyalty(pawn, ap.def);

            for (int i = 0; i < wornApparel.Count; ++i)
            {
                if (!ApparelUtility.CanWearTogether(wornApparel[i].def, ap.def, pawn.RaceProps.body))
                {
                    if (pawn.apparel.IsLocked(wornApparel[i]))
                    {
                        return(-1000);
                    }
                    // Added:
                    var wornReq = ItemUtility.IsRequiredByRoyalty(pawn, wornApparel[i].def);
                    if (wornReq && !newReq)
                    {
                        return(-1000);
                    }
                    //if (!pawn.outfits.forcedHandler.AllowedToAutomaticallyDrop(wornApparel[index]))
                    //    return -1000f;
                    num -= JobGiver_OptimizeApparel.ApparelScoreRaw(pawn, wornApparel[i]);
                    flag = true;
                }
            }
            if (!flag)
            {
                num *= 10f;
            }
            return(num);
        }
Exemple #13
0
        internal static void Wear(this Pawn_ApparelTracker _this, Apparel newApparel, bool dropReplacedApparel = true)
        {
            SlotGroupUtility.Notify_TakingThing(newApparel);
            if (newApparel.Spawned)
            {
                newApparel.DeSpawn();
            }
            if (!ApparelUtility.HasPartsToWear(_this.pawn, newApparel.def))
            {
                Log.Warning(string.Concat(new object[]
                {
                    _this.pawn,
                    " tried to wear ",
                    newApparel,
                    " but he has no body parts required to wear it."
                }));
                return;
            }
            for (int i = _this.WornApparel.Count - 1; i >= 0; i--)
            {
                Apparel apparel = _this.WornApparel[i];
                if (!ApparelUtility.CanWearTogether(newApparel.def, apparel.def))
                {
                    bool forbid = _this.pawn.Faction.HostileTo(Faction.OfPlayer);
                    if (dropReplacedApparel)
                    {
                        Apparel apparel2;
                        if (!_this.TryDrop(apparel, out apparel2, _this.pawn.Position, forbid))
                        {
                            Log.Error(_this.pawn + " could not drop " + apparel);
                            return;
                        }
                    }
                    else
                    {
                        _this.WornApparel.Remove(apparel);
                    }
                }
            }
            _this.WornApparel.Add(newApparel);
            newApparel.wearer = _this.pawn;
            _this.SortWornApparelIntoDrawOrder();
            _this.ApparelChanged();

            Utility.TryUpdateInventory(_this.pawn);     // Apparel was added, update inventory
            MethodInfo methodInfo = typeof(Pawn_ApparelTracker).GetMethod("SortWornApparelIntoDrawOrder", BindingFlags.Instance | BindingFlags.NonPublic);

            methodInfo.Invoke(_this, new object[] { });

            LongEventHandler.ExecuteWhenFinished(new Action(_this.ApparelChanged));
        }
Exemple #14
0
        /// <summary>
        /// Order <paramref name="pawn"/> to wear new apparel.
        /// </summary>
        /// <param name="pawn"> Pawn who is about to wear <paramref name="newApparel"/>. </param>
        /// <param name="newApparel"> Apparel to wear. </param>
        /// <param name="dropReplacedApparel"> If true, drop the old apparel. </param>
        public static void Wear(Pawn pawn, Apparel newApparel, bool dropReplacedApparel = true)
        {
            ValidateArg.NotNull(newApparel, nameof(newApparel));
            ValidateArg.NotNull(pawn, nameof(pawn));

            if (newApparel.Spawned)
            {
                newApparel.DeSpawn();
            }

            if (!ApparelUtility.HasPartsToWear(pawn, newApparel.def))
            {
                Log.Warning(pawn + " tried to wear " + newApparel + " but he has no body parts required to wear it.");
                return;
            }

            List <Apparel> apparelsToReplace = new List <Apparel>();

            for (int num = pawn.apparel.WornApparelCount - 1; num >= 0; num--)
            {
                Apparel oldApparel = pawn.apparel.WornApparel[num];
                if (!ApparelUtility.CanWearTogether(newApparel.def, oldApparel.def, pawn.RaceProps.body))
                {
                    apparelsToReplace.Add(oldApparel);
                }
            }

            foreach (Apparel apparel in apparelsToReplace)
            {
                if (dropReplacedApparel)
                {
                    bool forbid = pawn.Faction != null && pawn.Faction.HostileTo(Faction.OfPlayer);
                    if (!pawn.apparel.TryDrop(apparel, out Apparel _, pawn.PositionHeld, forbid))
                    {
                        Messages.Message(UIText.FailToDrop.Translate(pawn, apparel), MessageTypeDefOf.NeutralEvent);
                        return;
                    }
                }
                else
                {
                    pawn.inventory.innerContainer.TryAddOrTransfer(apparel);
                }
            }

            if (newApparel.Wearer != null)
            {
                Log.Warning(pawn + " is trying to wear " + newApparel + " but this apparel already has a wearer (" + newApparel.Wearer + "). This may or may not cause bugs.");
            }

            pawn.apparel.GetDirectlyHeldThings().TryAdd(newApparel);
        }
        public static void CalculateScoreForSpecialStats(Apparel ap, StatPriority statPriority, Pawn thisPawn,
                                                         float apStat, ref float score)
        {
            var current     = thisPawn.GetStatValue(statPriority.Stat);
            var goal        = statPriority.Weight;
            var defaultStat = thisPawn.def.GetStatValueAbstract(statPriority.Stat);

            if (thisPawn.story != null)
            {
                foreach (var trait in thisPawn.story.traits.allTraits)
                {
                    defaultStat += trait.OffsetOfStat(statPriority.Stat);
                }

                foreach (var trait in thisPawn.story.traits.allTraits)
                {
                    defaultStat *= trait.MultiplierOfStat(statPriority.Stat);
                }
            }

            if (ap.Wearer == thisPawn)
            {
                current -= apStat;
            }
            else
            {
                foreach (var worn in thisPawn.apparel.WornApparel)
                {
                    if (ApparelUtility.CanWearTogether(worn.def, ap.def, thisPawn.RaceProps.body))
                    {
                        continue;
                    }

                    var stat1 = worn.GetStatValue(statPriority.Stat);
                    var stat2 = worn.GetEquippedStatValue(thisPawn, statPriority.Stat);
                    DoApparelScoreRaw_PawnStatsHandlers(worn, statPriority.Stat, out var stat3);
                    current -= stat1 + stat2 + stat3;
                }
            }

            if (!(Math.Abs(current - goal) > 0.01f))
            {
                return;
            }

            var need = 1f - Mathf.InverseLerp(defaultStat, goal, current);

            score += Mathf.InverseLerp(current, goal, current + apStat) * need;
        }
Exemple #16
0
 public bool CanStoreApparel(Apparel apparel)
 {
     if (ArmorRackJobUtil.RaceCanWear(apparel.def, PawnKindDef.race) == false)
     {
         return(false);
     }
     foreach (Apparel storedApparel in GetStoredApparel())
     {
         if (!ApparelUtility.CanWearTogether(storedApparel.def, apparel.def, PawnKindDef.RaceProps.body))
         {
             return(false);
         }
     }
     return(true);
 }
        // ReSharper disable once UnusedMember.Global
        public static float ApparelScoreGain([NotNull] this Pawn pawn, [NotNull] Apparel newAp,
                                             List <Apparel> wornApparel = null)
        {
            var conf = pawn.GetApparelStatCache();

            // get the score of the considered apparel
            var candidateScore = conf.ApparelScoreRaw(newAp);

            // float candidateScore = StatCache.WeaponScoreRaw(ap, pawn);

            // get the current list of worn apparel
            if (wornApparel.NullOrEmpty())
            {
                wornApparel = pawn.apparel.WornApparel;
            }

            var willReplace = false;

            // check if the candidate will replace existing gear
            if (wornApparel != null)
            {
                foreach (var wornAp in wornApparel)
                {
                    if (ApparelUtility.CanWearTogether(wornAp.def, newAp.def, pawn.RaceProps.body))
                    {
                        continue;
                    }

                    // can't drop forced gear
                    if (!pawn.outfits.forcedHandler.AllowedToAutomaticallyDrop(wornAp))
                    {
                        return(-1000f);
                    }

                    // if replaces, score is difference of the two pieces of gear + penalty
                    candidateScore -= conf.ApparelScoreRaw(wornAp);
                    willReplace     = true;
                }
            }

            // increase score if this piece can be worn without replacing existing gear.
            if (!willReplace)
            {
                candidateScore *= ScoreFactorIfNotReplacing;
            }

            return(candidateScore);
        }
        /// <summary>
        /// When notified job is about to start, calculate unequip delay for underlying apparel.
        /// </summary>
        public override void Notify_Starting()
        {
            base.Notify_Starting();
            _apparel  = TargetThingA as Apparel;
            _duration = (int)(_apparel.GetStatValue(StatDefOf.EquipDelay) * 60f);

            List <Apparel> wornApparel = pawn.apparel.WornApparel;

            for (int num = wornApparel.Count - 1; num >= 0; num--)
            {
                if (!ApparelUtility.CanWearTogether(_apparel.def, wornApparel[num].def, pawn.RaceProps.body))
                {
                    _duration += (int)(wornApparel[num].GetStatValue(StatDefOf.EquipDelay) * 60f);
                }
            }
        }
        public static bool FitsAfterSwap(Apparel newAp, Pawn pawn, Apparel skipAp)
        {
            foreach (Apparel pairAp in pawn.apparel.WornApparel)
            {
                if (pairAp == skipAp)
                {
                    continue;
                }
                Log.Message("Does " + newAp + " fit with " + pairAp + "?");

                if (!ApparelUtility.CanWearTogether(newAp.def, pairAp.def, pawn.RaceProps.body))
                {
                    Log.Message("NO");
                    return(false);
                }
            }
            return(true);
        }
Exemple #20
0
        private static bool prevent_wear_by_gear(Pawn_ApparelTracker __instance, ref Apparel newApparel)
        {
            var tra = __instance;

            // //--Log.Message ("Pawn_ApparelTracker.Wear called for " + newApparel.Label + " on " + tra.pawn.NameStringShort);
            foreach (var app in tra.WornApparel)
            {
                if (app.has_lock() && (!ApparelUtility.CanWearTogether(newApparel.def, app.def, tra.pawn.RaceProps.body)))
                {
                    if (PawnUtility.ShouldSendNotificationAbout(tra.pawn))
                    {
                        Messages.Message(tra.pawn.NameStringShort + " can't wear " + newApparel.def.label + " (blocked by " + app.def.label + ")", tra.pawn, MessageTypeDefOf.NegativeEvent);
                    }
                    return(false);
                }
            }
            return(true);
        }
Exemple #21
0
        public static bool ApparelScoreGain_NewTmp(ref float __result, Pawn pawn, Apparel ap, List <float> wornScoresCache)
        {
            if (ap is ShieldBelt && pawn.equipment.Primary != null && pawn.equipment.Primary.def.IsWeaponUsingProjectiles)
            {
                __result = -1000f;
                return(false);
            }

            float          num         = JobGiver_OptimizeApparel.ApparelScoreRaw(pawn, ap);
            List <Apparel> wornApparel = pawn.apparel.WornApparel;
            bool           flag        = false;

            for (int i = 0; i < wornApparel.Count; i++)
            {
                Apparel apparel;
                try
                {
                    apparel = wornApparel[i];
                }
                catch (ArgumentOutOfRangeException)
                {
                    break;
                }
                if (!ApparelUtility.CanWearTogether(apparel.def, ap.def, pawn.RaceProps.body))
                {
                    if (!pawn.outfits.forcedHandler.AllowedToAutomaticallyDrop(apparel) || pawn.apparel.IsLocked(apparel))
                    {
                        __result = -1000f;
                        return(false);
                    }

                    num -= wornScoresCache[i];
                    flag = true;
                }
            }

            if (!flag)
            {
                num *= 10f;
            }

            __result = num;
            return(false);
        }
Exemple #22
0
        public static IEnumerator GenerateStartingApparelFor(Zombie zombie)
        {
            var possibleApparel = AllApparelPairs().Where(pair => CanWear(zombie, pair)).ToList();

            yield return(null);

            if (possibleApparel.Count > 0)
            {
                for (var i = 0; i < Rand.Range(0, 4); i++)
                {
                    var pair = possibleApparel.RandomElement();
                    yield return(null);

                    var apparel = (Apparel)ThingMaker.MakeThing(pair.thing, pair.stuff);
                    yield return(null);

                    PawnGenerator.PostProcessGeneratedGear(apparel, zombie);
                    yield return(null);

                    if (ApparelUtility.HasPartsToWear(zombie, apparel.def))
                    {
                        if (zombie.apparel.WornApparel.All(pa => ApparelUtility.CanWearTogether(pair.thing, pa.def, zombie.RaceProps.body)))
                        {
                            apparel.SetColor(Zombie.zombieColors[Rand.Range(0, Zombie.zombieColors.Length)].SaturationChanged(0.25f));
                            Graphic_Multi_Init_Patch.suppressError = true;
                            Graphic_Multi_Init_Patch.textureError  = false;
                            try
                            {
                                zombie.apparel.Wear(apparel, false);
                            }
                            catch (Exception)
                            {
                            }
                            if (Graphic_Multi_Init_Patch.textureError)
                            {
                                zombie.apparel.Remove(apparel);
                            }
                            Graphic_Multi_Init_Patch.suppressError = false;
                        }
                    }
                    yield return(null);
                }
            }
        }
        public static void CalculateScoreForSpecialStats(Apparel ap, StatPriority statPriority, Pawn thisPawn, float apStat, ref float score)
        {
            float current     = thisPawn.GetStatValue(statPriority.Stat);
            float goal        = statPriority.Weight;
            float defaultStat = thisPawn.def.GetStatValueAbstract(statPriority.Stat);

            if (thisPawn.story != null)
            {
                for (int k = 0; k < thisPawn.story.traits.allTraits.Count; k++)
                {
                    defaultStat += thisPawn.story.traits.allTraits[k].OffsetOfStat(statPriority.Stat);
                }

                for (int n = 0; n < thisPawn.story.traits.allTraits.Count; n++)
                {
                    defaultStat *= thisPawn.story.traits.allTraits[n].MultiplierOfStat(statPriority.Stat);
                }
            }

            if (ap.Wearer == thisPawn)
            {
                current -= apStat;
            }
            else
            {
                foreach (Apparel worn in thisPawn.apparel.WornApparel)
                {
                    if (!ApparelUtility.CanWearTogether(worn.def, ap.def, thisPawn.RaceProps.body))
                    {
                        float stat1 = worn.GetStatValue(statPriority.Stat);
                        float stat2 = worn.GetEquippedStatValue(thisPawn, statPriority.Stat);
                        DoApparelScoreRaw_PawnStatsHandlers(worn, statPriority.Stat, out float stat3);
                        current -= stat1 + stat2 + stat3;
                    }
                }
            }

            if (Math.Abs(current - goal) > 0.01f)
            {
                float need = 1f - Mathf.InverseLerp(defaultStat, goal, current);
                score += Mathf.InverseLerp(current, goal, current + apStat) * need;
            }
        }
Exemple #24
0
        public static float ApparelScoreGain(Pawn pawn, Apparel ap)
        {
            // only allow shields to be considered if a primary weapon is equipped and is melee
            if (ap.def == ThingDefOf.Apparel_PersonalShield &&
                pawn.equipment.Primary != null &&
                !pawn.equipment.Primary.def.Verbs[0].MeleeRange)
            {
                return(-1000f);
            }

            // get the score of the considered apparel
            float candidateScore = ApparelScoreRaw(ap, pawn);

            // get the current list of worn apparel
            List <Apparel> wornApparel = pawn.apparel.WornApparel;

            // check if the candidate will replace existing gear
            bool willReplace = false;

            for (int i = 0; i < wornApparel.Count; i++)
            {
                if (!ApparelUtility.CanWearTogether(wornApparel[i].def, ap.def))
                {
                    // can't drop forced gear
                    if (!pawn.outfits.forcedHandler.AllowedToAutomaticallyDrop(wornApparel[i]))
                    {
                        return(-1000f);
                    }

                    // if replaces, score is difference of the two pieces of gear
                    candidateScore -= ApparelScoreRaw(wornApparel[i], pawn);
                    willReplace     = true;
                }
            }

            // increase score if this piece can be worn without replacing existing gear.
            if (!willReplace)
            {
                candidateScore *= 10f;
            }

            return(candidateScore);
        }
Exemple #25
0
        private static bool prevent_locked_apparel_conflict(WITab_Caravan_Gear __instance, ref Pawn p)
        {
            if (__instance == null)
            {
                return(true);
            }
            if (get_dragged_item(__instance) is Apparel dragged_app && p.apparel != null && dragged_app.has_lock())
            {
                foreach (var equipped_app in p.apparel.WornApparel)
                {
                    if (equipped_app.has_lock() && (!ApparelUtility.CanWearTogether(dragged_app.def, equipped_app.def, p.RaceProps.body)))
                    {
                        set_dragged_item(__instance, null);
                        return(false);
                    }
                }
            }

            return(true);
        }
        /// <summary>
        /// Check wheter pawn has an empty slot to wear <paramref name="newApparel"/>.
        /// </summary>
        /// <param name="pawn"> Selected pawn. </param>
        /// <param name="newApparel"> Apparel to wear. </param>
        /// <returns> Returns true if there is an empty slot. </returns>
        public static bool IsOldApparelForced(this Pawn pawn, Apparel newApparel)
        {
            if (pawn.apparel?.WornApparel == null || newApparel == null)
            {
                return(false);
            }

            foreach (Apparel wornApparel in pawn.apparel.WornApparel)
            {
                if (ApparelUtility.CanWearTogether(wornApparel.def, newApparel.def, BodyDefOf.Human))
                {
                    continue;
                }
                else if (pawn.outfits.forcedHandler.IsForced(wornApparel))
                {
                    return(true);
                }
            }

            return(false);
        }
        private void SetDuration()
        {
            unequipBuffer = 0;

            if (TargetApparel == null)
            {
                duration = 2;
                return;
            }

            duration = (int)(TargetApparel.GetStatValue(StatDefOf.EquipDelay) * 60f);

            List <Apparel> wornApparel = pawn.apparel.WornApparel;

            for (int num = wornApparel.Count - 1; num >= 0; num--)
            {
                if (!ApparelUtility.CanWearTogether(TargetApparel.def, wornApparel[num].def, pawn.RaceProps.body))
                {
                    duration += (int)(wornApparel[num].GetStatValue(StatDefOf.EquipDelay) * 60f);
                }
            }
        }
Exemple #28
0
        public override void Notify_Starting()
        {
            base.Notify_Starting();
            apparel = TargetThingA as Apparel;

            mode     = job.count;
            duration = (int)(apparel.GetStatValue(StatDefOf.EquipDelay) * 60f);
            if (mode > 0)
            {
                List <Apparel> wornApparel = pawn.apparel.WornApparel;
                int            count       = wornApparel.Count;
                Log.Message("wornApparel.Count: " + wornApparel.Count);
                Log.Message("Count: " + count);
                for (int num = 0; num < count; ++num)
                {
                    Log.Message("wornApparel.Count2: " + wornApparel.Count);
                    Log.Message("num: " + num);
                    if (!ApparelUtility.CanWearTogether(apparel.def, wornApparel[num].def, pawn.RaceProps.body))
                    {
                        duration += (int)(wornApparel[num].GetStatValue(StatDefOf.EquipDelay) * 60f);
                    }
                }
            }
        }
 public override IEnumerable <string> ConfigErrors()
 {
     foreach (string err in base.ConfigErrors())
     {
         yield return(err);
     }
     if (this.race == null)
     {
         yield return("no race");
     }
     else if (this.RaceProps.Humanlike && this.backstoryCategories.NullOrEmpty <string>())
     {
         yield return("Humanlike needs backstoryCategories.");
     }
     if (this.baseRecruitDifficulty > 1.0001f)
     {
         yield return(this.defName + " recruitDifficulty is greater than 1. 1 means impossible to recruit.");
     }
     if (this.combatPower < 0f)
     {
         yield return(this.defName + " has no combatPower.");
     }
     if (this.weaponMoney != FloatRange.Zero)
     {
         float minCost = 999999f;
         int   i;
         for (i = 0; i < this.weaponTags.Count; i++)
         {
             IEnumerable <ThingDef> enumerable = from d in DefDatabase <ThingDef> .AllDefs
                                                 where d.weaponTags != null && d.weaponTags.Contains(this.weaponTags[i])
                                                 select d;
             if (enumerable.Any <ThingDef>())
             {
                 float a = minCost;
                 IEnumerable <ThingDef> source = enumerable;
                 if (PawnKindDef.< > f__mg$cache0 == null)
                 {
                     PawnKindDef.< > f__mg$cache0 = new Func <ThingDef, float>(PawnWeaponGenerator.CheapestNonDerpPriceFor);
                 }
                 minCost = Mathf.Min(a, source.Min(PawnKindDef.< > f__mg$cache0));
             }
         }
         if (minCost > this.weaponMoney.min)
         {
             yield return(string.Concat(new object[]
             {
                 "Cheapest weapon with one of my weaponTags costs ",
                 minCost,
                 " but weaponMoney min is ",
                 this.weaponMoney.min,
                 ", so could end up weaponless."
             }));
         }
     }
     if (!this.RaceProps.Humanlike && this.lifeStages.Count != this.RaceProps.lifeStageAges.Count)
     {
         yield return(string.Concat(new object[]
         {
             "PawnKindDef defines ",
             this.lifeStages.Count,
             " lifeStages while race def defines ",
             this.RaceProps.lifeStageAges.Count
         }));
     }
     if (this.apparelRequired != null)
     {
         for (int k = 0; k < this.apparelRequired.Count; k++)
         {
             for (int j = k + 1; j < this.apparelRequired.Count; j++)
             {
                 if (!ApparelUtility.CanWearTogether(this.apparelRequired[k], this.apparelRequired[j], this.race.race.body))
                 {
                     yield return(string.Concat(new object[]
                     {
                         "required apparel can't be worn together (",
                         this.apparelRequired[k],
                         ", ",
                         this.apparelRequired[j],
                         ")"
                     }));
                 }
             }
         }
     }
     yield break;
 }
Exemple #30
0
        public static void Postfix(Pawn pawn, ref Job __result, JobGiver_OptimizeApparel __instance)
        {
            if (__result == null)
            {
                return;
            }

            CompAwesomeInventoryLoadout comp = pawn.TryGetComp <CompAwesomeInventoryLoadout>();

            if (comp == null)
            {
                return;
            }

            Job   job          = __result;
            Thing targetThingA = job.targetA.Thing;

            if (comp.Loadout is AwesomeInventoryCostume costume)
            {
                if (__result.def == JobDefOf.Wear)
                {
                    if (targetThingA != null &&
                        !costume.CostumeItems.Any(s => s.Allows(targetThingA, out _)) &&
                        !costume.CostumeItems.All(s => ApparelUtility.CanWearTogether(targetThingA.def, s.AllowedThing, BodyDefOf.Human)))
                    {
                        __result = null;
                        JobMaker.ReturnToPool(job);
                        _setNextOptimizeTick.Invoke(__instance, new[] { pawn });
                        return;
                    }
                }
            }
            else if (comp.Loadout is AwesomeInventoryLoadout loadout)
            {
                CancellationTokenSource source = new CancellationTokenSource();
                CancellationToken       token  = source.Token;
                try
                {
                    bool conflict = false;

                    if (!loadout.Any(selector => selector.Allows(targetThingA, out _)))
                    {
                        Parallel.ForEach(
                            Partitioner.Create(pawn.apparel.WornApparel)
                            , (Apparel apparel) =>
                        {
                            if (!token.IsCancellationRequested &&
                                targetThingA != null &&
                                !ApparelUtility.CanWearTogether(apparel.def, targetThingA.def, BodyDefOf.Human))
                            {
                                if (comp.Loadout.Any(selector => selector.Allows(apparel, out _)))
                                {
                                    conflict = true;
                                    source.Cancel();
                                }
                            }
                        });
                    }

                    if (conflict)
                    {
                        __result = new DressJob(AwesomeInventory_JobDefOf.AwesomeInventory_Dress, targetThingA, false);
                        JobMaker.ReturnToPool(job);
                    }
                }
                catch (Exception e)
                {
                    __result = JobMaker.MakeJob(JobDefOf.Wear, targetThingA);
                }
                finally
                {
                    source.Dispose();
                }
            }
        }