예제 #1
0
 /// <summary>
 ///     Applies the mutation extension to pawn.
 /// </summary>
 /// <param name="pawn">The pawn.</param>
 /// <param name="canApplyRestricted">if set to <c>true</c> restricted mutations can be applied as well as regular ones.</param>
 /// <param name="setAtMaxStage">if set to <c>true</c>all mutations will be set at the maximum stage.</param>
 /// <param name="kindExtension">The kind extension.</param>
 public static void ApplyMutationExtensionToPawn([NotNull] Pawn pawn, bool canApplyRestricted, bool setAtMaxStage,
                                                 [NotNull] MorphPawnKindExtension kindExtension)
 {
     if (pawn == null)
     {
         throw new ArgumentNullException(nameof(pawn));
     }
     if (kindExtension == null)
     {
         throw new ArgumentNullException(nameof(kindExtension));
     }
     ApplyMutations(pawn, canApplyRestricted, setAtMaxStage, kindExtension);
     ApplyAspects(pawn, kindExtension);
 }
예제 #2
0
        private static void ApplyAspects(Pawn pawn, MorphPawnKindExtension extension)
        {
            if (pawn.GetAspectTracker() == null)
            {
                return;
            }
            if (extension.aspects.Count == 0)
            {
                return;
            }

            int addAspect = extension.aspectRange.RandomInRange;

            if (addAspect == 0)
            {
                return;
            }

            AspectTracker aspectTracker = pawn.GetAspectTracker();

            if (aspectTracker == null)
            {
                return;
            }

            List <AspectDef> availableAspects = extension.GetAllAspectDefs().ToList();

            addAspect = Mathf.Min(availableAspects.Count - 1, addAspect);

            if (addAspect == availableAspects.Count - 1)
            {
                foreach (AspectDef aspectDef in availableAspects)
                {
                    int stage = extension.GetAvailableStagesFor(aspectDef).RandomElementWithFallback();
                    aspectTracker.Add(aspectDef, stage);
                }

                return;
            }


            for (var i = 0; i < addAspect; i++)
            {
                int       r     = Rand.Range(0, availableAspects.Count); //pick a random entry
                AspectDef def   = availableAspects[r];
                int       stage = extension.GetAvailableStagesFor(def).RandomElementWithFallback();
                aspectTracker.Add(def, stage);
                availableAspects.RemoveAt(r); //remove it so we don't pick it twice
            }
        }
예제 #3
0
        private static void ApplyMutations([NotNull] Pawn pawn, bool canApplyRestricted, bool setAtMaxStage,
                                           [NotNull] MorphPawnKindExtension kindExtension)
        {
            List <MutationDef> mutations;
            var addedPartsSet = new HashSet <BodyPartDef>();

            if (!canApplyRestricted)
            {
                canApplyRestricted = pawn.CanReceiveRareMutations();
            }


            if (canApplyRestricted)
            {
                mutations = kindExtension.GetRandomMutations(pawn.thingIDNumber).ToList();
            }
            else
            {
                mutations = kindExtension.GetRandomMutations(pawn.thingIDNumber)
                            .Where(g => !g.IsRestricted)              //only keep the unrestricted mutations
                            .ToList();
            }

            if (mutations.Count == 0)
            {
                Warning($"could not get any mutations for {pawn.Name} using extension\n{kindExtension.ToStringFull()}");
            }

            var toGive    = new List <MutationDef>();
            var addedList = new List <BodyPartRecord>();

            int toGiveCount = kindExtension.hediffRange.RandomInRange; //get a random number of mutations to add
            int max         = Mathf.Min(mutations.Count, toGiveCount);
            var i           = 0;

            while (i < max)
            {
                if (mutations.Count == 0)
                {
                    break;
                }
                while (true)
                {
                    if (mutations.Count == 0)
                    {
                        break;
                    }
                    int         rI     = Rand.Range(0, mutations.Count);
                    MutationDef mGiver = mutations[rI];

                    mutations.RemoveAt(rI); //remove the entry so we don't pull duplicates
                    if (mGiver.parts.Any(p => p != null && addedPartsSet.Contains(p))
                        )                   //make sure its for a part we haven't encountered yet
                    {
                        continue;
                    }

                    foreach (BodyPartDef part in mGiver.parts)
                    {
                        addedPartsSet.Add(part);
                    }
                    toGive.Add(mGiver);
                    i++;  //only count 1 regardless of what was added
                    break;
                }
            }


            foreach (MutationDef giver in toGive)
            {
                giver.ClearOverlappingMutations(pawn); // make sure to remove any overlapping hediffs added during a different stage

                var result = MutationUtilities.AddMutation(pawn, giver, int.MaxValue, MutationUtilities.AncillaryMutationEffects.None);
                addedList.AddRange(result.Parts);
            }

            if (toGive.Count > 0 && (addedList.Count == 0 || !pawn.health.hediffSet.hediffs.OfType <Hediff_AddedMutation>().Any()))
            {
                LogMsg(LogLevel.Warnings, $"could not add mutations to pawn {pawn.Name} with ext\n{kindExtension}");
            }

            if (setAtMaxStage)
            {
                var addedMutations = new List <Hediff_AddedMutation>();
                List <Hediff_AddedMutation> allMutationsOnPawn =
                    pawn.health.hediffSet.hediffs.OfType <Hediff_AddedMutation>().ToList(); //save these
                foreach (BodyPartRecord bodyPartRecord in addedList)                        //get a list of all mutations we just added
                {
                    foreach (Hediff_AddedMutation mutation in allMutationsOnPawn)
                    {
                        if (mutation.Part == bodyPartRecord && toGive.Contains(mutation.def as MutationDef))
                        {
                            if (!addedMutations.Contains(mutation))
                            {
                                addedMutations.Add(mutation);
                            }
                        }
                    }
                }


                foreach (Hediff_AddedMutation hediff in addedMutations)
                {
                    if (hediff.pawn == null)
                    {
                        continue;                      //sometimes the hediffs are removed by other mutations
                    }
                    if (hediff.TryGetComp <HediffComp_Production>() != null)
                    {
                        continue;                                                     //do not increase production hediffs
                    }
                    var comp = hediff.TryGetComp <Comp_MutationSeverityAdjust>();
                    if (comp != null)
                    {
                        hediff.Severity = comp.NaturalSeverityLimit;
                        continue;
                    }

                    HediffStage lastStage = hediff.def.stages?.LastOrDefault();
                    if (lastStage == null)
                    {
                        continue;
                    }

                    float severity = lastStage.minSeverity + 0.01f;
                    hediff.Severity = severity;
                }
            }


            pawn.CheckRace(false); //don't apply missing mutations to avoid giving restricted mutations and to respect the limit
        }