void IMutationEventReceiver.MutationRemoved(Hediff_AddedMutation mutation, MutationTracker tracker) { foreach (IMutationEventReceiver affinity in _aspects.OfType <IMutationEventReceiver>()) { affinity.MutationRemoved(mutation, tracker); } }
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); }
/// <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); }
/// <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); }