Esempio n. 1
0
        /// <summary>
        ///     Does the find.
        /// </summary>
        /// <param name="worker">The worker.</param>
        /// <exception cref="System.NotImplementedException"></exception>
        protected override void DoFind(Pawn worker)
        {
            if (_chosenAnimalToScan == null)
            {
                Log.Error($"calling DoFind on {parent.ThingID} which does not have a chosen animal!");
                return;
            }

            _scratchList.Clear();
            _scratchList.AddRange(_chosenAnimalToScan.GetAllMutationsFrom().Where(m => !DB.StoredMutations.Contains(m)));

            if (_scratchList.Count == 0)
            {
                Log.Warning("unable to find mutation to give!");
                _chosenAnimalToScan = null;
                return;
            }

            MutationDef mutation = _scratchList.RandomElement();

            DB.AddToDatabase(mutation);

            TaggedString msg = MUTATION_GATHERED_LABEL.Translate(mutation.Named("mutation"),
                                                                 _chosenAnimalToScan.Named("animal")
                                                                 );

            Messages.Message(msg, MessageTypeDefOf.PositiveEvent);
            if (_scratchList.Count - 1 == 0)
            {
                _chosenAnimalToScan = null;
            }
        }
Esempio n. 2
0
        private void StoreRemovedMutations(MutationDef mDef, List <Hediff_AddedMutation> mutations,
                                           List <RemoveMutationDurationComp.MutationEntry> outList)
        {
            if (mDef.RemoveComp == null)
            {
                return;
            }

            foreach (Hediff_AddedMutation mutation in mutations)
            {
                var mRmComp = mutation.TryGetComp <RemoveFromPartComp>();
                if (mRmComp == null)
                {
                    continue;
                }
                var otherMDef = mutation.def as MutationDef;
                if (otherMDef == null)
                {
                    Log.Warning($"encountered mutation {mutation.def.defName} that does not use a MutationDef!");
                }
                if (mRmComp.Layer == mDef.RemoveComp.layer && mDef.parts.MakeSafe().Contains(mutation.Part?.def))
                {
                    outList.Add(new RemoveMutationDurationComp.MutationEntry
                    {
                        mDef     = otherMDef,
                        severity = mutation.Severity,
                        record   = mutation.Part
                    });
                }
            }
        }
Esempio n. 3
0
 /// <summary>
 /// Constructor for MutationData used to gather all relevant information.
 /// </summary>
 /// <param name="mutation">The def of the mutation to add to the pawn.</param>
 /// <param name="part">The body part record to add the mutation to.</param>
 /// <param name="severity">The severity the mutation should be initialized with.</param>
 /// <param name="isHalted">Wether the mutation should be able to progress, or should be locked at it's current stage.</param>
 /// <param name="removing">Whether or not this entry is designated to instead remove mutations from the body part.</param>
 public MutationData(MutationDef mutation, BodyPartRecord part, float severity, bool isHalted, bool removing)
 {
     this.mutation = mutation;
     this.part     = part;
     this.severity = severity;
     this.isHalted = isHalted;
     this.removing = removing;
 }
 private static bool IsDepricated([NotNull] MutationDef def)
 {
     if (string.Compare("depricated", def.label, StringComparison.InvariantCultureIgnoreCase) == 0)
     {
         return(true);
     }
     return(string.Compare("obsolete", def.label, StringComparison.InvariantCultureIgnoreCase) == 0);
 }
Esempio n. 5
0
 /// <summary>
 /// Gets the required storage.
 /// </summary>
 /// <param name="mutationDef">The mutation definition.</param>
 /// <returns></returns>
 /// <exception cref="ArgumentNullException">mutationDef</exception>
 public static int GetRequiredStorage([NotNull] this MutationDef mutationDef)
 {
     if (mutationDef == null)
     {
         throw new ArgumentNullException(nameof(mutationDef));
     }
     return((int)Mathf.Max(MIN_MUTATION_STORAGE_SPACE, mutationDef.value * STORAGE_PER_VALUE_MUTATION));
 }
Esempio n. 6
0
 /// <summary>
 /// Tries to add the specified mutation to the database, returning false on failure.
 /// </summary>
 /// <param name="db">The database.</param>
 /// <param name="def">The definition.</param>
 /// <returns></returns>
 public static bool TryAddToDatabase([NotNull] this ChamberDatabase db, [NotNull] MutationDef def)
 {
     if (!db.CanAddToDatabase(def))
     {
         return(false);
     }
     db.AddToDatabase(def);
     return(true);
 }
Esempio n. 7
0
 MutationEntry CreateEntry(MutationDef mDef)
 {
     return(new MutationEntry
     {
         addChance = 0.3f,
         blocks = false,
         mutation = mDef
     });
 }
Esempio n. 8
0
        /// <summary>
        ///     Adds the mutation to the given pawn
        /// </summary>
        /// <param name="pawn">The pawn.</param>
        /// <param name="mutation">The mutation.</param>
        /// <param name="parts">The parts.</param>
        /// <param name="countToAdd">The count to add.</param>
        /// <param name="ancillaryEffects">The ancillary effects.</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException">
        ///     pawn
        ///     or
        ///     mutation
        /// </exception>
        public static MutationResult AddMutation([NotNull] Pawn pawn, [NotNull] MutationDef mutation, [CanBeNull] List <BodyPartDef> parts,
                                                 int countToAdd = int.MaxValue,
                                                 AncillaryMutationEffects?ancillaryEffects = null)
        {
            if (pawn == null)
            {
                throw new ArgumentNullException(nameof(pawn));
            }
            if (mutation == null)
            {
                throw new ArgumentNullException(nameof(mutation));
            }

            var addLst = new List <BodyPartRecord>();

            if (parts != null)
            {
                foreach (BodyPartRecord notMissingPart in pawn.health.hediffSet.GetAllNonMissingWithoutProsthetics())
                {
                    if (parts.Contains(notMissingPart.def))
                    {
                        addLst.Add(notMissingPart);
                        if (parts.Count >= countToAdd)
                        {
                            break;
                        }
                    }
                }

                if (addLst.Count == 0)
                {
                    return(MutationResult.Empty);
                }
                return(AddMutation(pawn, mutation, addLst, ancillaryEffects));
            }


            var existingHediff = pawn.health.hediffSet.hediffs.FirstOrDefault(m => m.def == mutation && m.Part == null);

            if (existingHediff != null)
            {
                (existingHediff as Hediff_AddedMutation)?.ResumeAdaption();
                return(MutationResult.Empty);
            }

            if (!(HediffMaker.MakeHediff(mutation, pawn) is Hediff_AddedMutation hDef))
            {
                Log.Error($"{mutation.defName} is not a mutation but is being added like one!");
                return(MutationResult.Empty);
            }

            pawn.health.AddHediff(hDef);

            DoAncillaryMutationEffects(pawn, mutation, hDef, ancillaryEffects ?? AncillaryMutationEffects.Default);

            return(new MutationResult(hDef));
        }
Esempio n. 9
0
        /// <summary>
        ///     Determines whether the specified hediff definition is an associated mutation .
        /// </summary>
        /// <param name="mutationDef">The hediff definition.</param>
        /// <returns>
        ///     <c>true</c> if the specified hediff definition is an associated mutation; otherwise, <c>false</c>.
        /// </returns>
        /// <exception cref="ArgumentNullException">hediffDef</exception>
        public bool IsAnAssociatedMutation([NotNull] MutationDef mutationDef)
        {
            if (mutationDef == null)
            {
                throw new ArgumentNullException(nameof(mutationDef));
            }

            return(AllAssociatedMutations.Contains(mutationDef));
        }
Esempio n. 10
0
        /// <summary>
        /// checks if this mutation blocks the addition of a new mutation at the given part
        /// </summary>
        /// <param name="otherMutation">The other mutation.</param>
        /// <param name="addPart">The add part.</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException">otherMutation</exception>
        public virtual bool Blocks([NotNull] MutationDef otherMutation, [CanBeNull] BodyPartRecord addPart)
        {
            if (otherMutation == null)
            {
                throw new ArgumentNullException(nameof(otherMutation));
            }
            var mDef = def as MutationDef;

            return(mDef?.BlocksMutation(otherMutation, Part, addPart) == true);
        }
Esempio n. 11
0
        /// <summary>
        /// Determines whether this instance is tagged.
        /// </summary>
        /// <param name="mutationDef">The mutation definition.</param>
        /// <returns>
        ///   <c>true</c> if the specified mutation definition is tagged; otherwise, <c>false</c>.
        /// </returns>
        /// <exception cref="ArgumentNullException">mutationDef</exception>
        public static bool IsTagged([NotNull] this MutationDef mutationDef)
        {
            if (mutationDef == null)
            {
                throw new ArgumentNullException(nameof(mutationDef));
            }
            var db = Find.World.GetComponent <ChamberDatabase>();

            return(db?.StoredMutations.Contains(mutationDef) == true);
        }
Esempio n. 12
0
        /// <summary>
        /// Gets the required storage.
        /// </summary>
        /// <param name="mutationDef">The mutation definition.</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException">mutationDef</exception>
        public static int GetRequiredStorage([NotNull] this MutationDef mutationDef)
        {
            if (mutationDef == null)
            {
                throw new ArgumentNullException(nameof(mutationDef));
            }
            float spvM = mutationDef.value * STORAGE_PER_VALUE_MUTATION;

            return(Mathf.Max(MIN_MUTATION_STORAGE_SPACE, Mathf.RoundToInt(spvM)));
        }
Esempio n. 13
0
        /// <summary>
        /// Determines whether this instance has the specified mutation.
        /// </summary>
        /// <param name="requiredMutation">The required mutation.</param>
        /// <returns>
        ///   <c>true</c> if the specified required mutation has mutation; otherwise, <c>false</c>.
        /// </returns>
        /// <exception cref="NotImplementedException"></exception>
        public bool HasMutation([NotNull] MutationDef requiredMutation)
        {
            foreach (Hediff_AddedMutation mutation in _mutationList)
            {
                if (mutation.def == requiredMutation)
                {
                    return(true);
                }
            }

            return(false);
        }
Esempio n. 14
0
 /// <summary>
 /// Initializes a new instance of the <see cref="MutationData"/> class.
 /// </summary>
 /// <param name="mData">The m data.</param>
 public MutationData([NotNull] IReadOnlyMutationData mData)
 {
     if (mData == null)
     {
         throw new ArgumentNullException(nameof(mData));
     }
     mutation = mData.Mutation;
     part     = mData.Part;
     severity = mData.Severity;
     isHalted = mData.IsHalted;
     removing = mData.Removing;
 }
Esempio n. 15
0
 /// <summary>
 ///     Adds the mutation to the given pawn
 /// </summary>
 /// <param name="pawn">The pawn.</param>
 /// <param name="mutation">The mutation.</param>
 /// <param name="countToAdd">The count to add.</param>
 /// <param name="ancillaryEffects">The ancillary effects.</param>
 /// <returns></returns>
 /// <exception cref="ArgumentNullException">
 ///     pawn
 ///     or
 ///     mutation
 /// </exception>
 public static MutationResult AddMutation([NotNull] Pawn pawn, [NotNull] MutationDef mutation, int countToAdd = int.MaxValue, AncillaryMutationEffects?ancillaryEffects = null)
 {
     if (pawn == null)
     {
         throw new ArgumentNullException(nameof(pawn));
     }
     if (mutation == null)
     {
         throw new ArgumentNullException(nameof(mutation));
     }
     return(AddMutation(pawn, mutation, mutation.parts, countToAdd, ancillaryEffects));
 }
Esempio n. 16
0
 /// <summary>
 /// Tries to add the specified mutation to the database, returning false on failure.
 /// </summary>
 /// <param name="db">The database.</param>
 /// <param name="def">The definition.</param>
 /// <param name="displayMessageIfAdded">if set to <c>true</c> [display message if added].</param>
 /// <returns></returns>
 public static bool TryAddToDatabase([NotNull] this ChamberDatabase db, [NotNull] MutationDef def, bool displayMessageIfAdded = true)
 {
     if (!db.CanAddToDatabase(def))
     {
         return(false);
     }
     db.AddToDatabase(def);
     if (displayMessageIfAdded)
     {
         Messages.Message(MUTATION_ADDED_MESSAGE.Translate(def.Named("Mutation")), MessageTypeDefOf.PositiveEvent);
     }
     return(true);
 }
Esempio n. 17
0
 /// <summary>
 /// Determines whether this instance can generate the specified mutation.
 /// </summary>
 /// <param name="mDef">The m definition.</param>
 /// <returns>
 ///   <c>true</c> if this instance with the specified m definition can generate ; otherwise, <c>false</c>.
 /// </returns>
 public bool CanGenerate(MutationDef mDef)
 {
     return(mutations?.Contains(mDef) == true);
 }
Esempio n. 18
0
 /// <summary>
 /// Adds a new entry to the list of mutations to give the pawn.
 /// </summary>
 /// <param name="mutation">The def of the mutation to add to the pawn.</param>
 /// <param name="part">The body part record to apply the mutation to.</param>
 /// <param name="severity">What severity the added mutation should be intialized with.</param>
 /// <param name="isHalted">Whether or not the addded mutation will be able to progress.</param>
 /// <param name="removing">Whether or not this entry is intended to remove the mutation.</param>
 public void AddData(MutationDef mutation, BodyPartRecord part, float severity, bool isHalted, bool removing)
 {
     mutationData.Add(new MutationData(mutation, part, severity, isHalted, removing));
 }
Esempio n. 19
0
 public DebugMenu_AddMutation([NotNull] MutationDef mDef, [NotNull] Pawn pawn)
 {
     _mutationDef = mDef ?? throw new ArgumentNullException(nameof(mDef));
     _pawn        = pawn ?? throw new ArgumentNullException(nameof(pawn));
 }
 /// <summary>
 /// Gets the market value for this mutation.
 /// </summary>
 /// this can be negative for bad mutations
 /// <param name="mDef">The m definition.</param>
 /// <returns></returns>
 public static float GetMarketValueFor([NotNull] this MutationDef mDef)
 {
     return(mDef.value * MARKET_VALUE_PER_VALUE);
 }
Esempio n. 21
0
 void AddMutationAction([NotNull] MutationDef mutationDef)
 {
     Find.WindowStack.Add(new DebugMenu_AddMutation(mutationDef, _pawn));
 }
 public RowEntry(MutationDef mDef)
 {
     label            = mDef.label;
     storageSpaceUsed = mDef.GetRequiredStorage();
     def = mDef;
 }
Esempio n. 23
0
        private void DrawSeverityBar(ref float curY, ref Rect partListViewRect, MutationLayer layer, MutationDef mutationDef, List <Hediff_AddedMutation> mutationsOfDef)
        {
            // Draw the various labels for the severity bar (need to refine this later).
            string stageLabelText     = $"Stage {mutationsOfDef.FirstOrDefault().CurStageIndex}: {mutationsOfDef.FirstOrDefault().LabelCap}";
            Rect   severityLabelsRect = new Rect(partListViewRect.x, curY, partListViewRect.width, Text.CalcHeight(stageLabelText, partListViewRect.width));

            Text.Anchor = TextAnchor.MiddleLeft;
            Widgets.Label(severityLabelsRect, stageLabelText);
            Text.Anchor = TextAnchor.MiddleRight;
            Widgets.Label(severityLabelsRect, mutationsOfDef.FirstOrDefault().Severity.ToString("n2"));
            Text.Anchor = TextAnchor.UpperLeft;
            curY       += severityLabelsRect.height;

            // Draw the severity slider
            float curSeverity = mutationsOfDef.Select(n => n.Severity).Average();
            float newSeverity = Widgets.HorizontalSlider(new Rect(partListViewRect.x, curY, partListViewRect.width, SLIDER_HEIGHT), curSeverity, mutationDef.minSeverity, mutationDef.maxSeverity);

            if (curSeverity != newSeverity)
            {
                curSeverity = newSeverity;
                foreach (Hediff_AddedMutation mutationOfDef in mutationsOfDef)
                {
                    MutationData relevantEntry = addedMutations.MutationsByPartAndLayer(mutationOfDef.Part, layer);
                    if (relevantEntry != null)
                    {
                        relevantEntry.severity = newSeverity;
                    }
                    else
                    {
                        addedMutations.AddData(mutationOfDef.Def, mutationOfDef.Part, newSeverity, mutationOfDef.ProgressionHalted, false);
                    }
                    mutationOfDef.Severity = newSeverity;
                }
                recachePreview = true;
            }
            curY += SLIDER_HEIGHT;
        }
Esempio n. 24
0
        /// <summary>
        ///     Adds the mutation to the given pawn
        /// </summary>
        /// <param name="pawn">The pawn.</param>
        /// <param name="mutation">The mutation.</param>
        /// <param name="records">The records to add mutations to</param>
        /// <param name="ancillaryEffects">The ancillary effects.</param>
        /// <exception cref="ArgumentNullException">
        ///     pawn
        ///     or
        ///     mutation
        ///     or
        ///     records
        /// </exception>
        public static MutationResult AddMutation([NotNull] Pawn pawn, [NotNull] MutationDef mutation,
                                                 [NotNull] IEnumerable <BodyPartRecord> records,
                                                 AncillaryMutationEffects?ancillaryEffects = null)
        {
            if (pawn == null)
            {
                throw new ArgumentNullException(nameof(pawn));
            }
            if (mutation == null)
            {
                throw new ArgumentNullException(nameof(mutation));
            }
            if (records == null)
            {
                throw new ArgumentNullException(nameof(records));
            }
            HediffSet hSet = pawn.health?.hediffSet;

            if (hSet == null)
            {
                return(MutationResult.Empty);
            }
            List <Hediff_AddedMutation> lst = new List <Hediff_AddedMutation>();

            foreach (BodyPartRecord bodyPartRecord in records)
            {
                if (bodyPartRecord.IsMissingAtAllIn(pawn))
                {
                    LogMsg(LogLevel.Pedantic, $"could not add {mutation.defName} to {pawn.Name} on {bodyPartRecord.Label} because it is missing or has a prosthetic");
                    continue;
                }

                if (HasAnyBlockingMutations(pawn, mutation, bodyPartRecord))
                {
                    continue;
                }

                var existingMutation = hSet.hediffs.FirstOrDefault(h => h.def == mutation && h.Part == bodyPartRecord);
                if (existingMutation != null) //resume adaption for mutations that are already added instead of re adding them
                {
                    LogMsg(LogLevel.Pedantic, $"could not add {mutation.defName} to {pawn.Name} on {bodyPartRecord.Label} because it already has that mutation");

                    existingMutation.ResumeAdjustment(); //don't do count restarted mutations as new ones
                    continue;
                }

                var hediff = HediffMaker.MakeHediff(mutation, pawn, bodyPartRecord) as Hediff_AddedMutation;
                if (hediff == null)
                {
                    Log.Error($"{mutation.defName} is not a mutation but is being added like one!");
                    continue;
                }

                lst.Add(hediff);
                hSet.AddDirect(hediff);
            }

            AncillaryMutationEffects aEffects = ancillaryEffects ?? AncillaryMutationEffects.Default;

            if (lst.Count > 0) //only do this if we actually added any mutations
            {
                DoAncillaryMutationEffects(pawn, mutation, lst, aEffects);
            }

            return(new MutationResult(lst));
        }
Esempio n. 25
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
        }
Esempio n. 26
0
 private static void DoAncillaryMutationEffects(Pawn pawn, MutationDef mutation, List <Hediff_AddedMutation> addedParts, in AncillaryMutationEffects aEffects)
Esempio n. 27
0
 /// <summary>
 /// Determines whether this instance can generate the specified mutation.
 /// </summary>
 /// <param name="mDef">The m definition.</param>
 /// <returns>
 ///   <c>true</c> if this instance with the specified m definition can generate ; otherwise, <c>false</c>.
 /// </returns>
 public bool CanGenerate(MutationDef mDef)
 {
     return(mDef.classInfluence.Contains(animalClass));
 }