/// <summary> /// Gets the normalized direct influence of the given morph /// </summary> /// this does not take into account influence the children of the given class might have on the pawn /// <param name="class">The morph.</param> /// <returns></returns> /// <exception cref="ArgumentNullException">morph</exception> public float GetDirectNormalizedInfluence([NotNull] AnimalClassBase @class) { if (@class == null) { throw new ArgumentNullException(nameof(@class)); } return(_influenceDict.TryGetValue(@class) / MorphUtilities.GetMaxInfluenceOfRace(parent.def)); }
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> /// Recalculates the mutation influences if needed. /// </summary> public void RecalcIfNeeded() { int counter = 0; foreach (Hediff hediff in Pawn.health.hediffSet.hediffs) { if (hediff is Hediff_AddedMutation) { counter++; } } if (counter != MutationsCount) { Log.Warning($"{Pawn.Name} mutation tracker has only {MutationsCount} tracked mutations but pawn actually has {counter}"); RecalculateMutationInfluences(); return; } bool anyNegative = false; float totalInfluence = 0; foreach (KeyValuePair <AnimalClassBase, float> keyValuePair in _influenceDict) { if (keyValuePair.Value < 0) { anyNegative = true; } totalInfluence += keyValuePair.Value; } var maxInfluence = MorphUtilities.GetMaxInfluenceOfRace(parent.def); if (anyNegative) { Log.Warning($"{Pawn.Name} has negative mutation influence"); RecalculateMutationInfluences(); } if (Mathf.Abs(totalInfluence - TotalInfluence) > EPSILON) { Log.Warning($"{Pawn.Name} mutation tracker total is incorrect calculated:{totalInfluence} vs cached:{TotalInfluence}"); RecalculateMutationInfluences(); } else if (totalInfluence > maxInfluence) { Log.Warning($"{Pawn.Name} mutation tracker total is incorrect calculated:{totalInfluence} greater then max:{maxInfluence}"); RecalculateMutationInfluences(); } }