Alter updateTraits to properly handle zygotic twin inheritance for differing number of natural traits

This commit is contained in:
lutepickle 2022-03-17 12:14:01 -07:00
parent 26b49379b1
commit 052b7661e4
2 changed files with 47 additions and 29 deletions

Binary file not shown.

View File

@ -614,41 +614,59 @@ namespace RJW_Menstruation
/// Copy from RJW
/// </summary>
/// <param name="pawn"></param>
/// <param name="parenttraits"></param>
/// <param name="parentTraits"></param>
///
public void updateTraits(Pawn pawn, List<Trait> parenttraits)
public void updateTraits(Pawn pawn, List<Trait> parentTraits)
{
if (pawn?.story?.traits == null) return;
List<Trait> traitlist = new List<Trait>(pawn.story.traits.allTraits);
if (!parenttraits.NullOrEmpty()) traitlist.AddRange(parenttraits);
else return;
var forcedTraits = traitlist
.Where(x => x.ScenForced)
.Distinct(new TraitComparer(ignoreDegree: true));
List<Trait> res = new List<Trait>();
res.AddRange(forcedTraits);
var comparer = new TraitComparer(); // trait comparision implementation, because without game compares traits *by reference*, makeing them all unique.
while (res.Count < traitlist.Count && traitlist.Count > 0)
if (pawn?.story?.traits == null)
{
// Has to be the only use of Rand in the function for the push/pop trick to work right
int index = Rand.Range(0, traitlist.Count); // getting trait and removing from the pull
var trait = traitlist[index];
traitlist.RemoveAt(index);
if (!res.Any(x => comparer.Equals(x, trait) || // skipping traits conflicting with already added
x.def.ConflictsWith(trait)))
{
res.Add(new Trait(trait.def, trait.Degree, false));
}
return;
}
int traitLimit = pawn.story.traits.allTraits.Count;
pawn.story.traits.allTraits = res;
//Personal pool
List<Trait> personalTraitPool = new List<Trait>(pawn.story.traits.allTraits);
//Parents
List<Trait> parentTraitPool = new List<Trait>(parentTraits);
parentTraitPool.RemoveAll(x => x.ScenForced);
int numberInherited;
if (parentTraitPool != null)
numberInherited = System.Math.Min(parentTraitPool.Count(), Rand.RangeInclusive(0,2)); // Not 3; give a better chance for a natural trait to appear
else
numberInherited = 0;
//Game suggested traits.
var forcedTraits = personalTraitPool
.Where(x => x.ScenForced)
.Distinct(new TraitComparer(ignoreDegree: true)); // result can be a mess, because game allows this mess to be created in scenario editor
List<Trait> selectedTraits = new List<Trait>();
var comparer = new TraitComparer(); // trait comparision implementation, because without game compares traits *by reference*, makeing them all unique.
selectedTraits.AddRange(forcedTraits); // enforcing scenario forced traits
for (int i = 0; i < numberInherited; i++) // add parent traits first
{
int index = Rand.Range(0, parentTraitPool.Count);
Trait trait = parentTraitPool[index];
parentTraitPool.RemoveAt(index);
if (!selectedTraits.Any(x => comparer.Equals(x, trait) ||
x.def.ConflictsWith(trait)))
selectedTraits.Add(new Trait(trait.def, trait.Degree, false));
}
while (selectedTraits.Count < traitLimit && personalTraitPool.Count > 0)
{
int index = Rand.Range(0, personalTraitPool.Count); // getting trait and removing from the pull
var trait = personalTraitPool[index];
personalTraitPool.RemoveAt(index);
if (!selectedTraits.Any(x => comparer.Equals(x, trait) || // skipping traits conflicting with already added
x.def.ConflictsWith(trait)))
selectedTraits.Add(new Trait(trait.def, trait.Degree, false));
}
pawn.story.traits.allTraits = selectedTraits;
}