Beispiel #1
0
        private static IEnumerable <BodyPartRecord> WhichPartsMutationIsAllowedOn(
            Pawn pawn,
            MutationDef def,
            BodyPartRecord part,
            Dictionary <string, HashSet <BodyPartDef> > excludedPartDefsForTag,
            Dictionary <string, HashSet <BodyPartRecord> > excludedPartsForTag
            )
        {
            IEnumerable <BodyPartRecord> allParts;

            if (def.affectedParts == null)
            {
                List <BodyPartRecord> list = new List <BodyPartRecord>();
                list.AddRange(GetChildBodyParts(part));
                allParts = list;
            }
            else
            {
                allParts = pawn.health.hediffSet.GetNotMissingParts().Where(x => def.affectedParts.Contains(x.def));
            }

            allParts = allParts.Where(x => !x.def.IsSolid(x, pawn.health.hediffSet.hediffs));

            foreach (string tag in def.exclusives)
            {
                if (def.affectsAllParts)
                {
                    HashSet <BodyPartDef> excluded;
                    if (excludedPartDefsForTag.TryGetValue(tag, out excluded))
                    {
                        allParts = allParts.Where(x => !excluded.Contains(x.def));
                    }
                }
                else
                {
                    HashSet <BodyPartRecord> excluded;
                    if (excludedPartsForTag.TryGetValue(tag, out excluded))
                    {
                        allParts = allParts.Except(excluded);
                    }
                }
            }

            return(allParts);
        }
Beispiel #2
0
        public override void PostPostMake()
        {
            if (!Radiology.itemBodyParts.TryGetValue(parent.def, out part))
            {
                return;
            }

            // add a random mutation; if this item is spawned via operation, the mutation will be removed anyway
            MutationDef mutationDef = DefDatabase <MutationDef> .AllDefs.Where(x => x.affectedParts != null && x.affectedParts.Contains(part)).RandomElementWithFallback();

            Hediff hediff = (Hediff)Activator.CreateInstance(mutationDef.hediffClass);

            hediff.def    = mutationDef;
            hediff.loadID = Find.UniqueIDsManager.GetNextHediffID();
            hediff.PostMake();

            hediffs.Add(hediff);
            parts.Add(part);
        }
Beispiel #3
0
        public static IEnumerable <BodyPartRecord> MutatePawn(Pawn pawn, BodyPartRecord part, float rareRatio, out Mutation mutationResult)
        {
            mutationResult = null;

            info("Finding mutation for part: " + part);
            info("Rare ratio: " + rareRatio);

            Dictionary <string, HashSet <BodyPartDef> >    excludedPartDefsForTag = new Dictionary <string, HashSet <BodyPartDef> >();
            Dictionary <string, HashSet <BodyPartRecord> > excludedPartsForTag    = new Dictionary <string, HashSet <BodyPartRecord> >();
            HashSet <string> excludedGlobalTags = new HashSet <string>();

            foreach (Mutation existingMutation in pawn.health.hediffSet.GetHediffs <Mutation>())
            {
                foreach (string tag in existingMutation.def.exclusives)
                {
                    HashSet <BodyPartDef> setDef = excludedPartDefsForTag.TryGetValue(tag);
                    if (setDef == null)
                    {
                        excludedPartDefsForTag[tag] = setDef = new HashSet <BodyPartDef>();
                    }
                    setDef.Add(existingMutation.Part.def);

                    HashSet <BodyPartRecord> set = excludedPartsForTag.TryGetValue(tag);
                    if (set == null)
                    {
                        excludedPartsForTag[tag] = set = new HashSet <BodyPartRecord>();
                    }
                    set.Add(existingMutation.Part);
                }

                excludedGlobalTags.AddRange(existingMutation.def.exclusivesGlobal);
            }

            info("Excluded parts for tags: " + Debug.AsText(excludedPartsForTag));
            info("Excluded defs for tags: " + Debug.AsText(excludedPartDefsForTag));

            var mutations = Mutations.Where(x => x.relatedParts == null || x.relatedParts.Contains(part.def));

            info("All applicable mutations: " + Debug.AsText(mutations));

            Dictionary <MutationDef, IEnumerable <BodyPartRecord> > allowedMutations = new Dictionary <MutationDef, IEnumerable <BodyPartRecord> >();

            foreach (var mutation in mutations)
            {
                if (mutation.exclusivesGlobal.Intersect(excludedGlobalTags).Any())
                {
                    continue;
                }

                var parts = WhichPartsMutationIsAllowedOn(pawn, mutation, part, excludedPartDefsForTag, excludedPartsForTag);
                info("  " + mutation + ": to " + Debug.AsText(parts));

                if (parts.Count() == 0)
                {
                    continue;
                }
                allowedMutations[mutation] = parts;
            }

            info("All allowed mutations: " + Debug.AsText(allowedMutations));
            if (allowedMutations.Count() == 0)
            {
                info("No mutation possible!");
                return(null);
            }

            MutationDef mutationDef = allowedMutations.Keys.RandomElementByWeight(x => (float)Math.Pow(x.likelihood, 1f - rareRatio));

            info("Chose mutation: " + mutationDef);

            var applicableParts = allowedMutations[mutationDef];

            info("Can be applied to body parts: " + Debug.AsText(applicableParts));

            if (allowedMutations.Count() == 0)
            {
                info("No matching body parts!");
                return(null);
            }

            var chosenPart = applicableParts.RandomElement();

            info("Chose part: " + chosenPart);

            var chosenParts = pawn.health.hediffSet.GetNotMissingParts()
                              .Where(x => mutationDef.affectsAllParts ? x.def == chosenPart.def : x == chosenPart);

            foreach (var partToMutate in chosenParts)
            {
                info("Adding to part: " + partToMutate);

                if (pawn.health.hediffSet.GetHediffs <Mutation>().Where(x => x.def == mutationDef && x.Part == partToMutate).Any())
                {
                    info("  But it already has this mutation!");
                    continue;
                }

                Mutation mutation = HediffMaker.MakeHediff(mutationDef, pawn, partToMutate) as Mutation;
                if (mutation == null)
                {
                    continue;
                }

                mutationResult = mutation;
                pawn.health.AddHediff(mutation, partToMutate, null, null);
            }


            return(chosenParts);
        }