protected override ThoughtState CurrentStateInternal(Pawn p) { if (!p.Spawned) { return(ThoughtState.Inactive); } if (!p.RaceProps.Humanlike) { return(ThoughtState.Inactive); } if (!p.story.traits.HasTrait(TraitDefOfPsychology.Polygamous)) { return(ThoughtState.Inactive); } if (!LovePartnerRelationUtility.HasAnyLovePartner(p)) { return(ThoughtState.Inactive); } List <Pawn> lovers = new List <Pawn>(); List <DirectPawnRelation> directRelations = p.relations.DirectRelations; foreach (DirectPawnRelation rel in directRelations) { if (LovePartnerRelationUtility.IsLovePartnerRelation(rel.def) && !rel.otherPawn.Dead) { lovers.Add(rel.otherPawn); } } if (lovers.Count == 1 && !lovers[0].story.traits.HasTrait(TraitDefOfPsychology.Polygamous)) { return(ThoughtState.ActiveAtStage(0)); } return(ThoughtState.Inactive); }
private static bool TryFindMarriageSeeker(out Pawn marriageSeeker) => (from x in Find.WorldPawns.AllPawnsAlive where x.Faction != null && !x.Faction.def.hidden && !x.Faction.def.permanentEnemy && !x.Faction.IsPlayer && x.Faction.PlayerGoodwill <= 50 && !x.Faction.defeated && x.Faction.leader != null && !x.Faction.leader.IsPrisoner && !x.Faction.leader.Spawned && x.Faction.def.techLevel <= TechLevel.Medieval && !x.IsPrisoner && !x.Spawned && x.relations != null && x.RaceProps.Humanlike && !SettlementUtility.IsPlayerAttackingAnySettlementOf(faction : x.Faction) && !PeaceTalksExist(faction : x.Faction) && (!LovePartnerRelationUtility.HasAnyLovePartner(pawn : x) || LovePartnerRelationUtility.ExistingMostLikedLovePartner(p : x, allowDead : false)?.Faction == Faction.OfPlayer) select x).TryRandomElement(result : out marriageSeeker); //todo: make more likely to select hostile.
public static void PsychologyFormula(ref float __result, Pawn generated, Pawn other, PawnGenerationRequest request, bool ex) { /* Throw away the existing result and substitute our own formula. */ float sexualityFactor = 1f; PsychologyPawn realGenerated = generated as PsychologyPawn; PsychologyPawn realOther = other as PsychologyPawn; if (PsychologyBase.ActivateKinsey() && realGenerated != null && realOther != null && realGenerated.sexuality != null && realOther.sexuality != null) { float kinsey = 3 - realGenerated.sexuality.kinseyRating; float kinsey2 = 3 - realOther.sexuality.kinseyRating; float h**o = (generated.gender == other.gender) ? 1f : -1f; sexualityFactor *= Mathf.InverseLerp(3f, 0f, kinsey * h**o); sexualityFactor *= Mathf.InverseLerp(3f, 0f, kinsey2 * h**o); } else { sexualityFactor = (generated.gender != other.gender) ? 1f : 0.01f; } float existingExLoverFactor = 1f; if (ex) { int exLovers = 0; List <DirectPawnRelation> directRelations = other.relations.DirectRelations; for (int i = 0; i < directRelations.Count; i++) { if (LovePartnerRelationUtility.IsExLovePartnerRelation(directRelations[i].def)) { exLovers++; } } existingExLoverFactor = Mathf.Pow(0.2f, (float)exLovers); } else if (LovePartnerRelationUtility.HasAnyLovePartner(other)) { __result = 0f; return; } float generationChanceAgeFactor = Traverse.Create(typeof(LovePartnerRelationUtility)).Method("GetGenerationChanceAgeFactor", new[] { typeof(Pawn) }).GetValue <float>(new object[] { generated }); float generationChanceAgeFactor2 = Traverse.Create(typeof(LovePartnerRelationUtility)).Method("GetGenerationChanceAgeFactor", new[] { typeof(Pawn) }).GetValue <float>(new object[] { other }); float generationChanceAgeGapFactor = Traverse.Create(typeof(LovePartnerRelationUtility)).Method("GetGenerationChanceAgeGapFactor", new[] { typeof(Pawn), typeof(Pawn), typeof(bool) }).GetValue <float>(new object[] { generated, other, ex }); float incestFactor = 1f; if (generated.GetRelations(other).Any((PawnRelationDef x) => x.familyByBloodRelation)) { incestFactor = 0.01f; } float melaninFactor; if (request.FixedMelanin.HasValue) { melaninFactor = ChildRelationUtility.GetMelaninSimilarityFactor(request.FixedMelanin.Value, other.story.melanin); } else { melaninFactor = PawnSkinColors.GetMelaninCommonalityFactor(other.story.melanin); } __result = existingExLoverFactor * sexualityFactor * generationChanceAgeFactor * generationChanceAgeFactor2 * generationChanceAgeGapFactor * incestFactor * melaninFactor; }
internal static float _RandomSelectionWeight(this InteractionWorker_RomanceAttempt _this, Pawn initiator, Pawn recipient) { PsychologyPawn realInitiator = initiator as PsychologyPawn; //Lovers won't romance each other if (LovePartnerRelationUtility.LovePartnerRelationExists(initiator, recipient)) { return(0f); } //Codependents won't romance anyone if they are in a relationship if (LovePartnerRelationUtility.HasAnyLovePartner(initiator) && initiator.story.traits.HasTrait(TraitDefOfPsychology.Codependent)) { return(0f); } //No one will romance someone they find less than 25% attractive float num = initiator.relations.SecondaryRomanceChanceFactor(recipient); if (num < 0.25f) { return(0f); } //No one will romance someone they have less than +5 opinion of int num2 = initiator.relations.OpinionOf(recipient); if (num2 < 5) { return(0f); } //Only lechers will romance someone that has less than +5 opinion of them if (recipient.relations.OpinionOf(initiator) < 5 && !initiator.story.traits.HasTrait(TraitDefOfPsychology.Lecher)) { return(0f); } //A pawn with +50 or more opinion of their lover will not hit on other pawns unless they are lecherous or polygamous (and their lover is also polygamous). float num3 = 1f; Pawn pawn = LovePartnerRelationUtility.ExistingMostLikedLovePartner(initiator, false); if (pawn != null && !initiator.story.traits.HasTrait(TraitDefOfPsychology.Lecher) && (!initiator.story.traits.HasTrait(TraitDefOfPsychology.Polygamous) && !pawn.story.traits.HasTrait(TraitDefOfPsychology.Polygamous))) { float value = (float)initiator.relations.OpinionOf(pawn); num3 = Mathf.InverseLerp(50f, -50f, value); } //Straight women are 15% as likely to romance anyone. float num4 = (!initiator.story.traits.HasTrait(TraitDefOf.Gay)) ? ((initiator.gender != Gender.Female) ? 1f : 0.15f) : 1f; float num5 = Mathf.InverseLerp(0.25f, 1f, num); float num6 = Mathf.InverseLerp(5f, 100f, (float)num2); //People who have hit on someone in the past and been rejected because of their sexuality will rarely attempt to hit on them again. float num7 = (realInitiator != null && realInitiator.sexuality.IncompatibleSexualityKnown(recipient)) ? 0.05f : 1f; //Only lechers will try to romance someone in a stable relationship. float num8 = 1f; Pawn pawn2 = LovePartnerRelationUtility.ExistingMostLikedLovePartner(recipient, false); if (pawn2 != null && !initiator.story.traits.HasTrait(TraitDefOfPsychology.Lecher)) { int value = recipient.relations.OpinionOf(pawn2); num8 = Mathf.InverseLerp(5f, -100f, (float)value); } return(1.15f * num3 * num4 * num5 * num6 * num3 * num7 * num8); }
// // Methods // // EdB: Copy of CreateRelation() with changes to assign the other pawn's mother or father to this sibling if // they exist. The logic that's in there already seems to take this into account, but doing it this // results in more predictable behavior in the context of Prepare Carefully customization. public override void CreateRelation(Pawn generated, Pawn other, ref PawnGenerationRequest request) { // EdB: Added this block to immediately assign the other pawn's parent to the sibling. bool otherPawnHasMother = other.GetMother() != null; bool otherPawnHasFather = other.GetFather() != null; if (generated.GetMother() != null && generated.GetFather() != null && !otherPawnHasMother && !otherPawnHasFather) { other.SetMother(generated.GetMother()); other.SetFather(generated.GetFather()); return; } // EdB: This is the end of the change. Everything after this is the original implementation. bool flag = other.GetMother() != null; bool flag2 = other.GetFather() != null; bool flag3 = Rand.Value < 0.85f; if (flag && LovePartnerRelationUtility.HasAnyLovePartner(other.GetMother())) { flag3 = false; } if (flag2 && LovePartnerRelationUtility.HasAnyLovePartner(other.GetFather())) { flag3 = false; } if (!flag) { Pawn newMother = PawnRelationWorker_Sibling.GenerateParent(generated, other, Gender.Female, request, flag3); other.SetMother(newMother); } generated.SetMother(other.GetMother()); if (!flag2) { Pawn newFather = PawnRelationWorker_Sibling.GenerateParent(generated, other, Gender.Male, request, flag3); other.SetFather(newFather); } generated.SetFather(other.GetFather()); if (!flag || !flag2) { bool flag4 = other.GetMother().story.traits.HasTrait(TraitDefOf.Gay) || other.GetFather().story.traits.HasTrait(TraitDefOf.Gay); if (flag4) { other.GetFather().relations.AddDirectRelation(PawnRelationDefOf.ExLover, other.GetMother()); } else if (flag3) { other.GetFather().relations.AddDirectRelation(PawnRelationDefOf.Spouse, other.GetMother()); } else { LovePartnerRelationUtility.GiveRandomExLoverOrExSpouseRelation(other.GetFather(), other.GetMother()); } } PawnRelationWorker_Sibling.ResolveMyName(ref request, generated); PawnRelationWorker_Sibling.ResolveMySkinColor(ref request, generated); }
private bool TryFindBetrothed(out Pawn betrothed) { return((from potentialPartners in PawnsFinder .AllMapsCaravansAndTravelingTransportPods_Alive_FreeColonistsAndPrisoners_NoCryptosleep where !LovePartnerRelationUtility.HasAnyLovePartner(potentialPartners) || LovePartnerRelationUtility.ExistingMostLikedLovePartner(potentialPartners, false) == marriageSeeker select potentialPartners).TryRandomElementByWeight( marriageSeeker2 => marriageSeeker.relations.SecondaryLovinChanceFactor(marriageSeeker2), out betrothed)); }
// LovePartnerRelationUtility.LovePartnerRelationGenerationChance, but with the gender and sexuality code removed. public static float LovePartnerRelationGenerationChance(Pawn generated, Pawn other, PawnGenerationRequest request, bool ex) { if (generated.ageTracker.AgeBiologicalYearsFloat < 14f) { return(0f); } if (other.ageTracker.AgeBiologicalYearsFloat < 14f) { return(0f); } var num = 1f; if (ex) { var num2 = 0; var directRelations = other.relations.DirectRelations; foreach (var directPawnRelation in directRelations) { if (LovePartnerRelationUtility.IsExLovePartnerRelation(directPawnRelation.def)) { num2++; } } num = Mathf.Pow(0.2f, num2); } else if (LovePartnerRelationUtility.HasAnyLovePartner(other)) { return(0f); } var generationChanceAgeFactor = GetGenerationChanceAgeFactor(generated); var generationChanceAgeFactor2 = GetGenerationChanceAgeFactor(other); var generationChanceAgeGapFactor = GetGenerationChanceAgeGapFactor(generated, other, ex); var num3 = 1f; if (generated.GetRelations(other).Any(x => x.familyByBloodRelation)) { num3 = 0.01f; } var num4 = request.FixedMelanin.HasValue ? ChildRelationUtility.GetMelaninSimilarityFactor(request.FixedMelanin.Value, other.story.melanin) : PawnSkinColors.GetMelaninCommonalityFactor(other.story.melanin); return(num * generationChanceAgeFactor * generationChanceAgeFactor2 * generationChanceAgeGapFactor * num3 * num4); }
// Token: 0x06000C7E RID: 3198 RVA: 0x0003DCB8 File Offset: 0x0003BEB8 internal static float _RandomSelectionWeight(this InteractionWorker_RomanceAttempt _this, Pawn initiator, Pawn recipient) { if (LovePartnerRelationUtility.LovePartnerRelationExists(initiator, recipient)) { return(0f); } if (LovePartnerRelationUtility.HasAnyLovePartner(initiator) && initiator.story.traits.HasTrait(TraitDefOfPsychology.Codependent)) { return(0f); } float num = initiator.relations.AttractionTo(recipient); int num2 = initiator.relations.OpinionOf(recipient); if (!initiator.story.traits.HasTrait(TraitDefOfPsychology.Lecher)) { if (num < 0.25f) { return(0f); } if (num2 < 5) { return(0f); } if (recipient.relations.OpinionOf(initiator) < 5) { return(0f); } } else { num = 0.25f; num2 = 5; } float num3 = 1f; Pawn pawn = LovePartnerRelationUtility.ExistingMostLikedLovePartner(initiator, false); if (pawn != null) { float value = (float)initiator.relations.OpinionOf(pawn); num3 = Mathf.InverseLerp(50f, -50f, value); } float num4 = (initiator.gender != Gender.Female) ? 1f : 0.125f; float num5 = Mathf.InverseLerp(0.25f, 1f, num); float num6 = Mathf.InverseLerp(5f, 100f, (float)num2); float num7 = (initiator.story.traits.HasTrait(TraitDefOfPsychology.Lecher)) ? 0.25f : 0f; return(1.15f * num4 * num5 * num6 * num3 + num7); }
protected override ThoughtState CurrentStateInternal(Pawn p) { if (!p.Spawned) { return(ThoughtState.Inactive); } if (!p.RaceProps.Humanlike) { return(ThoughtState.Inactive); } if (!p.story.traits.HasTrait(TraitDefOfPsychology.Codependent)) { return(ThoughtState.Inactive); } if (!LovePartnerRelationUtility.HasAnyLovePartner(p)) { return(ThoughtState.ActiveAtStage(0)); } else { Pawn lover = p.relations.GetFirstDirectRelationPawn(PawnRelationDefOf.Lover, null); if (lover == null) { lover = p.relations.GetFirstDirectRelationPawn(PawnRelationDefOf.Fiance, null); if (lover == null) { lover = p.relations.GetFirstDirectRelationPawn(PawnRelationDefOf.Spouse, null); } if (lover == null) { throw new NotImplementedException(); } if (lover.Dead == false) { return(ThoughtState.ActiveAtStage(2)); } else { return(ThoughtState.ActiveAtStage(3)); } } else { return(ThoughtState.ActiveAtStage(1)); } } }
// Token: 0x06000052 RID: 82 RVA: 0x00005688 File Offset: 0x00003888 public static Pawn GetCondomPartnerInMyBed(Pawn pawn, Building_Bed LovinBed) { if (LovinBed.SleepingSlotsCount <= 1) { return(null); } if (!LovePartnerRelationUtility.HasAnyLovePartner(pawn)) { return(null); } foreach (Pawn curOccupant in LovinBed.CurOccupants) { if (curOccupant != pawn && LovePartnerRelationUtility.LovePartnerRelationExists(pawn, curOccupant)) { return(curOccupant); } } return(null); }
public static void PsychologyException(ref float __result, Pawn initiator, Pawn recipient) { //Don't hit on people in mental breaks... unless you're really freaky. if (recipient.InMentalState && PsycheHelper.PsychologyEnabled(initiator) && PsycheHelper.Comp(initiator).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Experimental) < 0.8f) { __result = 0f; return; } //Pawns won't hit on their spouses. if (LovePartnerRelationUtility.LovePartnerRelationExists(initiator, recipient)) { __result = 0f; return; } //Codependents won't romance anyone if they are in a relationship if (LovePartnerRelationUtility.HasAnyLovePartner(initiator) && initiator.story.traits.HasTrait(TraitDefOfPsychology.Codependent)) { __result = 0f; return; } //Only lechers will romance someone that has less than +5 opinion of them if (recipient.relations.OpinionOf(initiator) < 5 && !initiator.story.traits.HasTrait(TraitDefOfPsychology.Lecher)) { __result = 0f; return; } float attractiveness = initiator.relations.SecondaryRomanceChanceFactor(recipient); int opinion = initiator.relations.OpinionOf(recipient); float romanceChance = 1.15f; if (!PsycheHelper.PsychologyEnabled(initiator)) { //Vanilla: Straight women are 15% as likely to romance anyone. romanceChance = (!initiator.story.traits.HasTrait(TraitDefOf.Gay)) ? ((initiator.gender != Gender.Female) ? romanceChance : romanceChance * 0.15f) : romanceChance; } else { //Psychology: A pawn's likelihood to romance is based on how Aggressive and Romantic they are. float personalityFactor = Mathf.Pow(20f, PsycheHelper.Comp(initiator).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Aggressive)) * Mathf.Pow(12f, (1f - PsycheHelper.Comp(initiator).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Romantic))); romanceChance = personalityFactor * 0.02f; } //A pawn with +50 or more opinion of their lover will not hit on other pawns unless they are lecherous or polygamous (and their lover is also polygamous). float existingLovePartnerFactor = 1f; Pawn pawn = LovePartnerRelationUtility.ExistingMostLikedLovePartner(initiator, false); if (pawn != null && !initiator.story.traits.HasTrait(TraitDefOfPsychology.Lecher) && (!initiator.story.traits.HasTrait(TraitDefOfPsychology.Polygamous) && !pawn.story.traits.HasTrait(TraitDefOfPsychology.Polygamous))) { float value = (float)initiator.relations.OpinionOf(pawn); existingLovePartnerFactor = Mathf.InverseLerp(50f, -50f, value); } float attractivenessFactor = Mathf.InverseLerp(0.25f, 1f, attractiveness); float opinionFactor = Mathf.InverseLerp(-5f, 100f, (float)opinion) * 2f; //People who have hit on someone in the past and been rejected because of their sexuality will rarely attempt to hit on them again. float knownSexualityFactor = (PsycheHelper.PsychologyEnabled(initiator) && PsychologyBase.ActivateKinsey() && PsycheHelper.Comp(initiator).Sexuality.IncompatibleSexualityKnown(recipient) && !initiator.story.traits.HasTrait(TraitDefOfPsychology.Lecher)) ? 0.05f : (PsycheHelper.PsychologyEnabled(initiator) ? (initiator.gender == recipient.gender ? (initiator.story.traits.HasTrait(TraitDefOf.Gay) && recipient.story.traits.HasTrait(TraitDefOf.Gay) ? 1f : 0.15f) : (!initiator.story.traits.HasTrait(TraitDefOf.Gay) && !recipient.story.traits.HasTrait(TraitDefOf.Gay) ? 1f : 0.15f)) : 1f); //Only lechers will try to romance someone in a stable relationship. float recipientLovePartnerFactor = 1f; Pawn pawn2 = LovePartnerRelationUtility.ExistingMostLikedLovePartner(recipient, false); if (pawn2 != null && !initiator.story.traits.HasTrait(TraitDefOfPsychology.Lecher)) { int value = recipient.relations.OpinionOf(pawn2); recipientLovePartnerFactor = Mathf.InverseLerp(5f, -100f, (float)value); } __result = romanceChance * existingLovePartnerFactor * attractivenessFactor * opinionFactor * knownSexualityFactor * recipientLovePartnerFactor; return; }
internal static float _LovePartnerRelationGenerationChance(Pawn generated, Pawn other, PawnGenerationRequest request, bool ex) { if (generated.ageTracker.AgeBiologicalYearsFloat < 14f) { return(0f); } if (other.ageTracker.AgeBiologicalYearsFloat < 14f) { return(0f); } if (!PsychologyBase.ActivateKinsey()) { if (generated.gender == other.gender && (!other.story.traits.HasTrait(TraitDefOf.Gay) || !request.AllowGay)) { return(0f); } if (generated.gender != other.gender && other.story.traits.HasTrait(TraitDefOf.Gay)) { return(0f); } } else if (generated.gender == other.gender && !request.AllowGay) { return(0f); } float num = 1f; if (ex) { int num2 = 0; List <DirectPawnRelation> directRelations = other.relations.DirectRelations; for (int i = 0; i < directRelations.Count; i++) { if (LovePartnerRelationUtility.IsExLovePartnerRelation(directRelations[i].def)) { num2++; } } num = Mathf.Pow(0.2f, (float)num2); } else if (LovePartnerRelationUtility.HasAnyLovePartner(other)) { return(0f); } float num3 = 1f; PsychologyPawn realGenerated = generated as PsychologyPawn; PsychologyPawn realOther = other as PsychologyPawn; if (PsychologyBase.ActivateKinsey() && realGenerated != null && realOther != null) { float kinsey = 3 - realGenerated.sexuality.kinseyRating; float kinsey2 = 3 - realOther.sexuality.kinseyRating; float h**o = (generated.gender == other.gender) ? 1f : -1f; num3 *= Mathf.InverseLerp(3f, 0f, kinsey * h**o); num3 *= Mathf.InverseLerp(3f, 0f, kinsey2 * h**o); } else { num3 = (generated.gender != other.gender) ? 1f : 0.01f; } var GetGenerationChanceAgeFactor = typeof(LovePartnerRelationUtility).GetMethod("GetGenerationChanceAgeFactor", BindingFlags.Static | BindingFlags.NonPublic); var GetGenerationChanceAgeGapFactor = typeof(LovePartnerRelationUtility).GetMethod("GetGenerationChanceAgeGapFactor", BindingFlags.Static | BindingFlags.NonPublic); float generationChanceAgeFactor = (float)GetGenerationChanceAgeFactor.Invoke(null, new object[] { generated }); float generationChanceAgeFactor2 = (float)GetGenerationChanceAgeFactor.Invoke(null, new object[] { other }); float generationChanceAgeGapFactor = (float)GetGenerationChanceAgeGapFactor.Invoke(null, new object[] { generated, other, ex }); float num4 = 1f; if (generated.GetRelations(other).Any((PawnRelationDef x) => x.familyByBloodRelation)) { num4 = 0.01f; } float num5; if (request.FixedMelanin.HasValue) { num5 = ChildRelationUtility.GetMelaninSimilarityFactor(request.FixedMelanin.Value, other.story.melanin); } else { num5 = PawnSkinColors.GetMelaninCommonalityFactor(other.story.melanin); } return(num * generationChanceAgeFactor * generationChanceAgeFactor2 * generationChanceAgeGapFactor * num3 * num5 * num4); }
// Token: 0x06000C9A RID: 3226 RVA: 0x0003EAD8 File Offset: 0x0003CCD8 internal static float _LovePartnerRelationGenerationChance(Pawn generated, Pawn other, PawnGenerationRequest request, bool ex) { if (generated.ageTracker.AgeBiologicalYearsFloat < 14f) { return(0f); } if (other.ageTracker.AgeBiologicalYearsFloat < 14f) { return(0f); } if (generated.gender == other.gender && (!other.story.traits.HasTrait(TraitDefOf.Gay) || !other.story.traits.HasTrait(TraitDefOfPsychology.Bisexual) || !request.AllowGay)) { return(0f); } if (generated.gender != other.gender && other.story.traits.HasTrait(TraitDefOf.Gay)) { return(0f); } var GetGenerationChanceAgeFactor = typeof(LovePartnerRelationUtility).GetMethod("GetGenerationChanceAgeFactor", BindingFlags.Static | BindingFlags.NonPublic); var GetGenerationChanceAgeGapFactor = typeof(LovePartnerRelationUtility).GetMethod("GetGenerationChanceAgeGapFactor", BindingFlags.Static | BindingFlags.NonPublic); if (GetGenerationChanceAgeFactor == null) { Log.ErrorOnce("Unable to reflect LovePartnerRelationUtility.GetGenerationChanceAgeFactor!", 305432421); return(0f); } if (GetGenerationChanceAgeGapFactor == null) { Log.ErrorOnce("Unable to reflect LovePartnerRelationUtility.GetGenerationChanceAgeGapFactor!", 305432421); return(0f); } float num = 1f; if (ex) { int num2 = 0; List <DirectPawnRelation> directRelations = other.relations.DirectRelations; for (int i = 0; i < directRelations.Count; i++) { if (LovePartnerRelationUtility.IsExLovePartnerRelation(directRelations[i].def)) { num2++; } } num = Mathf.Pow(0.2f, (float)num2); } else if (LovePartnerRelationUtility.HasAnyLovePartner(other)) { return(0f); } float num3 = (generated.gender != other.gender) ? 1f : 0.01f; float generationChanceAgeFactor = (float)GetGenerationChanceAgeFactor.Invoke(null, new object[] { generated }); float generationChanceAgeFactor2 = (float)GetGenerationChanceAgeFactor.Invoke(null, new object[] { other }); float generationChanceAgeGapFactor = (float)GetGenerationChanceAgeGapFactor.Invoke(null, new object[] { generated, other, ex }); float num4 = 1f; if (generated.GetRelations(other).Any((PawnRelationDef x) => x.familyByBloodRelation)) { num4 = 0.01f; } float num5; if (request.FixedSkinWhiteness.HasValue) { num5 = ChildRelationUtility.GetSkinSimilarityFactor(request.FixedSkinWhiteness.Value, other.story.skinWhiteness); } else { num5 = PawnSkinColors.GetWhitenessCommonalityFactor(other.story.skinWhiteness); } return(num * generationChanceAgeFactor * generationChanceAgeFactor2 * generationChanceAgeGapFactor * num3 * num5 * num4); }
public override float RandomSelectionWeight(Pawn initiator, Pawn recipient) { //Don't hit on people in mental breaks... unless you're really freaky. if (recipient.InMentalState && PsycheHelper.PsychologyEnabled(initiator) && PsycheHelper.Comp(initiator).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Experimental) < 0.8f) { return(0f); } //Pawns will only romance characters with which they have a mild relationship if (!GRPawnRelationUtility.HasInformalRelationship(initiator, recipient)) { return(0f); } //Pawns won't hit on their spouses. if (LovePartnerRelationUtility.LovePartnerRelationExists(initiator, recipient)) { return(0f); } //Codependents won't romance anyone if they are in a relationship if (LovePartnerRelationUtility.HasAnyLovePartner(initiator) && initiator.story.traits.HasTrait(TraitDefOfPsychology.Codependent)) { return(0f); } //Only lechers will romance someone that has less than +5 opinion of them if (recipient.relations.OpinionOf(initiator) < 5 && !initiator.story.traits.HasTrait(TraitDefOfPsychology.Lecher)) { return(0f); } //People only hit on people if they would consider a formal relationship with them. if (!AttractionUtility.WouldConsiderFormalRelationship(initiator, recipient)) { return(0f); } if (!AttractionUtility.QuickCheck(initiator, recipient)) { return(0f); } EmptyReasons(); float attractiveness = AttractionUtility.CalculateAttraction(initiator, recipient, false, true, out veryLowInitiatorReasons, out lowInitiatorReasons, out highInitiatorReasons, out veryHighInitiatorReasons, out AttractionFactorDef reasonForInstantFailure); if (attractiveness == 0f) { return(0f); } int opinion = initiator.relations.OpinionOf(recipient); float romanceChance = GradualRomanceMod.BaseRomanceChance; if (!PsycheHelper.PsychologyEnabled(initiator)) { //Vanilla: Straight women are 15% as likely to romance anyone. romanceChance *= (!initiator.story.traits.HasTrait(TraitDefOf.Gay)) ? ((initiator.gender != Gender.Female) ? romanceChance : romanceChance * 0.15f) : romanceChance; } else { //Psychology: A pawn's likelihood to romance is based on how Aggressive and Romantic they are. float personalityFactor = Mathf.Pow(20f, PsycheHelper.Comp(initiator).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Aggressive)) * Mathf.Pow(12f, (1f - PsycheHelper.Comp(initiator).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Romantic))); romanceChance *= personalityFactor * 0.02f; } //If their partner wouldn't consider a relationship with them, they're less likely to try and hit on them. But it doesn't put them off that much. if (AttractionUtility.WouldConsiderFormalRelationship(recipient, initiator)) { romanceChance *= 0.4f; } lastInitiator = initiator; lastRecipient = recipient; return(romanceChance * attractiveness); }
public static Pawn FindAttractivePawn(Pawn p1, out int price) { price = 0; if (p1 == null) { //--Log.Message("[RJW] JobGiver_WhoreInvitingVisitors::FindAttractivePawn - p1 is null"); return(null); } FindAttractivePawnHelper findPawnHelper = new FindAttractivePawnHelper { p1 = p1 }; if (xxx.RomanceDiversifiedIsActive && findPawnHelper.p1.story.traits.HasTrait(xxx.asexual)) { return(null); } price = xxx.PriceOfWhore(p1); int priceOfWhore = price; IEnumerable <Pawn> guestsSpawned = p1.Map.mapPawns.AllPawnsSpawned; guestsSpawned = (guestsSpawned.Except(guestsSpawned.Where(findPawnHelper.TraitCheckFail)).Where(findPawnHelper.FactionCheckPass)); if (guestsSpawned.Count() > 0) { guestsSpawned = guestsSpawned.Where((x => !x.Position.IsForbidden(p1) && (!LovePartnerRelationUtility.HasAnyLovePartner(x) || x != LovePartnerRelationUtility.ExistingLovePartner(p1)) && Roll_to_skip(x, p1) && xxx.CanAfford(x, p1, priceOfWhore) && p1.CanReserve(x, 1, 0))); } Pawn whoreTarget = null; if (guestsSpawned.Count() > 0) { guestsSpawned.TryRandomElement(out whoreTarget); } if (whoreTarget != null) { return(whoreTarget); } //--Log.Message("[RJW] JobGiver_WhoreInvitingVisitors::FindAttractivePawn - found no visitors"); if (!xxx.WillPawnTryHookup(p1)) { return(null); } whoreTarget = null; IEnumerable <Pawn> freeColonistsSpawned = findPawnHelper.p1.Map.mapPawns.FreeColonistsSpawned; freeColonistsSpawned = (freeColonistsSpawned.Except(freeColonistsSpawned.Where(findPawnHelper.TraitCheckFail)).Where(x => findPawnHelper.RelationCheckPass(x) && !x.Position.IsForbidden(p1) && Roll_to_skip(x, p1) && p1.CanReserve(x, 1, 0))); if (freeColonistsSpawned == null || !freeColonistsSpawned.Any()) { return(null); } freeColonistsSpawned.TryRandomElement(out whoreTarget); if (whoreTarget == null) { return(null); } if (p1.relations.SecondaryRomanceChanceFactor(whoreTarget) < 0.05f) { return(null); } return(whoreTarget); }
private static float LovePartnerRelationGenerationChance_Method(Pawn generated, Pawn other, PawnGenerationRequest request, bool ex) { if (generated.ageTracker.AgeBiologicalYearsFloat < 14f || other.ageTracker.AgeBiologicalYearsFloat < 14f) { return(0f); } float LoveChance = 1f; float GenderFactor = 1f; var comp = other.TryGetComp <CompIndividuality>(); if (generated.gender != other.gender && comp != null) { if (comp.sexuality == CompIndividuality.Sexuality.Straight) { GenderFactor = 1.0f; } else if (comp.sexuality == CompIndividuality.Sexuality.Bisexual) { GenderFactor = 0.75f; } else if (comp.sexuality == CompIndividuality.Sexuality.Gay) { GenderFactor = 0.05f; } } if (generated.gender == other.gender && comp != null) { if (comp.sexuality == CompIndividuality.Sexuality.Gay) { GenderFactor = 1.0f; } else if (comp.sexuality == CompIndividuality.Sexuality.Bisexual) { GenderFactor = 0.75f; } else if (comp.sexuality == CompIndividuality.Sexuality.Straight) { GenderFactor = 0.05f; } } if (ex) { int ExLovers = 0; List <DirectPawnRelation> directRelations = other.relations.DirectRelations; for (int i = 0; i < directRelations.Count; i++) { if (LovePartnerRelationUtility.IsExLovePartnerRelation(directRelations[i].def)) { ExLovers++; } } LoveChance = Mathf.Pow(0.2f, (float)ExLovers); } else if (LovePartnerRelationUtility.HasAnyLovePartner(other)) { return(0f); } float generationChanceAgeFactor = Mathf.Clamp(GenMath.LerpDouble(14f, 27f, 0f, 1f, generated.ageTracker.AgeBiologicalYearsFloat), 0f, 1f); float generationChanceAgeFactor2 = Mathf.Clamp(GenMath.LerpDouble(14f, 27f, 0f, 1f, other.ageTracker.AgeBiologicalYearsFloat), 0f, 1f); float generationChanceAgeGapFactor = (float)GetGenerationChanceAgeGapFactor.Invoke(null, new object[] { generated, other, ex }); float IncestFactor = 1f; if (generated.GetRelations(other).Any((PawnRelationDef x) => x.familyByBloodRelation)) { IncestFactor = 0.01f; } float MelaninFactor; if (request.FixedMelanin != null) { MelaninFactor = ChildRelationUtility.GetMelaninSimilarityFactor(request.FixedMelanin.Value, other.story.melanin); } else { MelaninFactor = PawnSkinColors.GetMelaninCommonalityFactor(other.story.melanin); } return(LoveChance * generationChanceAgeFactor * generationChanceAgeFactor2 * generationChanceAgeGapFactor * GenderFactor * MelaninFactor * IncestFactor); }