void IMutationEventReceiver.MutationRemoved(Hediff_AddedMutation mutation, MutationTracker tracker)
 {
     foreach (IMutationEventReceiver affinity in _aspects.OfType <IMutationEventReceiver>())
     {
         affinity.MutationRemoved(mutation, tracker);
     }
 }
Exemple #2
0
        public static MorphDef GetHighestInfluence([NotNull] this Pawn pawn)
        {
            MutationTracker comp = pawn.GetMutationTracker();

            if (comp == null)
            {
                return(null);
            }

            MorphDef highest = null;
            float    max     = float.NegativeInfinity;

            foreach (KeyValuePair <AnimalClassBase, float> keyValuePair in comp)
            {
                if (!(keyValuePair.Key is MorphDef morph))
                {
                    continue;
                }
                if (max < keyValuePair.Value)
                {
                    max     = keyValuePair.Value;
                    highest = morph;
                }
            }

            return(highest);
        }
Exemple #3
0
        /// <summary>
        /// Checks the race of this pawn. If the pawn is mutated enough it's race is changed to one of the hybrids
        /// </summary>
        /// <param name="pawn">The pawn.</param>
        /// <param name="addMissingMutations">if true, any missing mutations from the highest morph influence will be added</param>
        /// <param name="displayNotifications">if set to <c>true</c> display race shift notifications.</param>
        /// <exception cref="ArgumentNullException">pawn</exception>
        /// <exception cref="System.ArgumentNullException">pawn</exception>
        public static void CheckRace([NotNull] this Pawn pawn, bool addMissingMutations = true, bool displayNotifications = true)
        {
            if (pawn == null)
            {
                throw new ArgumentNullException(nameof(pawn));
            }

            if (pawn.ShouldBeConsideredHuman())
            {
                return;
            }

            MutationTracker mutTracker = pawn.GetMutationTracker();

            var hInfluence = mutTracker.HighestInfluence;

            if (hInfluence == null)
            {
                return;
            }
            float morphInfluence          = mutTracker.GetDirectNormalizedInfluence(hInfluence);
            int   morphInfluenceCount     = mutTracker.Count();
            var   isBelowChimeraThreshold = morphInfluence < CHIMERA_THRESHOLD && morphInfluenceCount > 1;

            MorphDef setMorph = GetMorphForPawn(pawn, isBelowChimeraThreshold, hInfluence, out MorphDef curMorph);

            if (setMorph?.raceSettings?.PawnCanBecomeHybrid(pawn) == false)
            {
                return;
            }
            if (curMorph != setMorph && setMorph != null)
            {
                RaceShiftUtilities.ChangePawnToMorph(pawn, setMorph, addMissingMutations, displayNotifications);
            }
        }
        private void DrawMorphInfluenceList(ref Vector2 curPos, float width)
        {
            // Set up the mutation tracker.
            MutationTracker mutationTracker = PawnToShowMutationsFor.GetMutationTracker();

            if (mutationTracker == null)
            {
                return;
            }

            // Create a list of the current morph influences upon the pawn.
            var influences = mutationTracker.ToList();

            // Determine the remaining human influence.
            float humInf = MorphUtilities.GetMaxInfluenceOfRace(PawnToShowMutationsFor.def);

            foreach (var influence in influences)
            {
                humInf -= influence.Value;
            }
            var maxRaceInfluence = MorphUtilities.GetMaxInfluenceOfRace(PawnToShowMutationsFor.def);

            // If the remaining human influence is greater than 0.0001, print its influence first.
            // (0.0001 is used to compensate for floating point number's occasional lack of precision.)
            if (humInf > EPSILON)
            {
                GUI.color = Color.green;
                string text       = $"Human ({(humInf/maxRaceInfluence).ToStringPercent()})";
                float  rectHeight = Text.CalcHeight(text, width);
                Widgets.Label(new Rect(curPos.x, curPos.y, width, rectHeight), text);
                curPos.y += rectHeight;
                GUI.color = Color.white;
            }

            if (influences.Count == 0)
            {
                return;
            }

            float maxInfluence = influences.MaxBy(x => x.Value).Value;

            // List the morph influences upon the pawn in descending order.
            foreach (var influence in influences.OrderByDescending(x => x.Value))
            {
                // Set the greatest influence's color to cyan
                if (Math.Abs(influence.Value - maxInfluence) < EPSILON)
                {
                    GUI.color = Color.cyan;
                }
                var    nVal       = influence.Value / maxRaceInfluence;
                string text       = $"{influence.Key.LabelCap} ({nVal.ToStringPercent()})";
                float  rectHeight = Text.CalcHeight(text, width);
                Widgets.Label(new Rect(curPos.x, curPos.y, width, rectHeight), text);
                curPos.y += rectHeight;
                GUI.color = Color.white;
            }
        }
        /// <summary> Gets the amount of influence a pawn has that's still human.</summary>
        /// <param name="pawn">the pawn</param>
        /// <param name="normalize"> Whether or not the resulting influence should be normalized between [0,1] </param>
        /// <returns></returns>
        public static float GetHumanInfluence([NotNull] this Pawn pawn, bool normalize = false)
        {
            MutationTracker mTracker = pawn.GetMutationTracker();

            if (mTracker == null)
            {
                return(MaxHumanInfluence); //always have non mutatable pawns be considered 'human' so the hybrid system never triggers for them
            }

            var hInfluence = MaxHumanInfluence - mTracker.TotalInfluence;

            if (normalize)
            {
                hInfluence /= MaxHumanInfluence;
            }
            return(hInfluence);
        }
Exemple #6
0
        /// <summary> Get whether or not the given pawn should still be considered 'human'. </summary>
        public static bool ShouldBeConsideredHuman([NotNull] this Pawn pawn)
        {
            if (pawn == null)
            {
                throw new ArgumentNullException(nameof(pawn));
            }
            if (pawn.health?.hediffSet?.hediffs == null)
            {
                return(true);
            }

            MutationTracker tracker = pawn.GetMutationTracker();

            if (tracker == null)
            {
                return(true);
            }


            float humanInfluence = GetHumanInfluence(pawn, true);

            return(humanInfluence > MORPH_TF_THRESHOLD);
        }