public static void Postfix(ref float __result, Pawn initiator, Pawn recipient) { // one in mental break OR is already lover of the initiator can't be targeted if (recipient.InMentalState || LovePartnerRelationUtility.LovePartnerRelationExists(initiator, recipient)) { __result = 0f; return; } // one can't perform romance atempt if recently rebuffed if (initiator.needs.mood.thoughts.memories.NumMemoriesOfDef(ThoughtDefOf.RebuffedMyRomanceAttempt) > 0) { __result = 0f; return; } // one can't target other people if current lover is good enough var initiator_partner = LovePartnerRelationUtility.ExistingMostLikedLovePartner(initiator, false); if (initiator_partner != null && initiator.relations.OpinionOf(initiator_partner) >= 25) { __result = 0f; return; } // one can't be targeted if current lover is good enough var recipient_partner = LovePartnerRelationUtility.ExistingMostLikedLovePartner(recipient, false); if (recipient_partner != null && recipient.relations.OpinionOf(recipient_partner) >= 25) { __result = 0f; } }
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); }
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)); }
private static bool TryFindMarriageSeeker(out Pawn marriageSeeker) { return((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.def.techLevel <= TechLevel.Medieval && x.Faction.leader != null && !x.Faction.leader.IsPrisoner && !x.Faction.leader.Spawned && !x.IsPrisoner && !x.Spawned && x.relations != null && x.RaceProps.Humanlike && !SettlementUtility.IsPlayerAttackingAnySettlementOf(x.Faction) && !PeaceTalksExist(x.Faction) && (!LovePartnerRelationUtility.HasAnyLovePartner(x) || LovePartnerRelationUtility.ExistingMostLikedLovePartner(x, false)?.Faction == Faction.OfPlayer) select x).TryRandomElement(out marriageSeeker)); //todo: make more likely to select hostile. }
// 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); }
public static bool WillPawnTryHookup(Pawn target) { if (target.story.traits.HasTrait(TraitDefOf.Asexual)) { return(false); } Pawn lover = LovePartnerRelationUtility.ExistingMostLikedLovePartner(target, false); if (lover == null) { return(true); } float num = target.relations.OpinionOf(lover); float num2 = Mathf.InverseLerp(30f, -80f, num); if (xxx.is_prude(target)) { num2 = 0f; } else if (xxx.is_lecher(target)) { //Lechers are always up for it. num2 = Mathf.InverseLerp(100f, 50f, num); } else if (target.Map == lover.Map) { //Less likely to cheat if the lover is on the same map. num2 = Mathf.InverseLerp(70f, 15f, num); } //else default values if (xxx.is_frustrated(target)) { num2 *= 1.8f; } else if (xxx.is_hornyorfrustrated(target)) { num2 *= 1.4f; } num2 /= 1.5f; //Rand.PopState(); //Rand.PushState(RJW_Multiplayer.PredictableSeed()); return(Rand.Range(0f, 1f) < num2); }
public override float RandomSelectionWeight(Pawn initiator, Pawn recipient) { if (LovePartnerRelationUtility.LovePartnerRelationExists(initiator, recipient)) { return(0f); } var num = initiator.relations.SecondaryRomanceChanceFactor(recipient); if (num < 0.25f) { return(0f); } var num2 = initiator.relations.OpinionOf(recipient); if (num2 < 5) { return(0f); } if (recipient.relations.OpinionOf(initiator) < 5) { return(0f); } var num3 = 1f; var pawn = LovePartnerRelationUtility.ExistingMostLikedLovePartner(initiator, false); if (pawn != null) { float value = initiator.relations.OpinionOf(pawn); num3 = Mathf.InverseLerp(50f, -50f, value); } var num5 = Mathf.InverseLerp(0.25f, 1f, num); var num6 = Mathf.InverseLerp(5f, 100f, num2); return(1.15f * num5 * num6 * num3); }
public override float RandomSelectionWeight(Pawn initiator, Pawn recipient) { if (LovePartnerRelationUtility.LovePartnerRelationExists(initiator, recipient)) { return(0f); } float num = initiator.relations.SecondaryRomanceChanceFactor(recipient); if (num < 0.25f) { return(0f); } int num2 = initiator.relations.OpinionOf(recipient); if (num2 < 5) { return(0f); } if (recipient.relations.OpinionOf(initiator) < 5) { return(0f); } float num3 = 1f; Pawn pawn = LovePartnerRelationUtility.ExistingMostLikedLovePartner(initiator, false); if (pawn != null) { float value = initiator.relations.OpinionOf(pawn); num3 = Mathf.InverseLerp(50f, -50f, value); } 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, num2); float num7 = initiator.gender != recipient.gender || (initiator.story.traits.HasTrait(TraitDefOf.Gay) && recipient.story.traits.HasTrait(TraitDefOf.Gay)) ? 1f : 0.15f; return(1.15f * num4 * num5 * num6 * num3 * num7); }
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; }
public static bool Listener(Map map, ref bool __result) { try { if (!map.IsPlayerHome) { return(false); } var num = 0; var num2 = 0; var allBuildingsColonist = map.listerBuildings.allBuildingsColonist; foreach (var building_Bed in allBuildingsColonist.Select(building => building as Building_Bed).Where(building_Bed => building_Bed != null && !building_Bed.ForPrisoners && !building_Bed.Medical && building_Bed.def.building.bed_humanlike)) { if (building_Bed.SleepingSlotsCount == 1) { num++; } else { num2++; } } var num3 = 0; var num4 = 0; foreach (var current in map.mapPawns.FreeColonistsSpawned) { if (Utils.ExceptionAndroidList.Contains(current.def.defName)) { continue; } var pawn = LovePartnerRelationUtility.ExistingMostLikedLovePartner(current, false); if (pawn == null || !pawn.Spawned || pawn.Map != current.Map || pawn.Faction != Faction.OfPlayer || pawn.HostFaction != null) { num3++; } else { num4++; } } if (num4 % 2 != 0) { } for (var j = 0; j < num4 / 2; j++) { if (num2 > 0) { num2--; } else { num -= 2; } } for (var k = 0; k < num3; k++) { if (num2 > 0) { num2--; } else { num--; } } __result = num < 0 || num2 < 0; return(false); } catch (Exception e) { Log.Message("[ATPP] ALert_NeedColonistBeds.NeedColonistBeds :" + e.Message + " - " + e.StackTrace); return(true); } }
public static bool Listener(Map map, ref bool __result) { try { if (!map.IsPlayerHome) { return(false); } int num = 0; int num2 = 0; List <Building> allBuildingsColonist = map.listerBuildings.allBuildingsColonist; for (int i = 0; i < allBuildingsColonist.Count; i++) { Building_Bed building_Bed = allBuildingsColonist[i] as Building_Bed; if (building_Bed != null && !building_Bed.ForPrisoners && !building_Bed.Medical && building_Bed.def.building.bed_humanlike) { if (building_Bed.SleepingSlotsCount == 1) { num++; } else { num2++; } } } int num3 = 0; int num4 = 0; foreach (Pawn current in map.mapPawns.FreeColonistsSpawned) { //On ignore les androis dans la comptabilisation if (Utils.ExceptionAndroidList.Contains(current.def.defName)) { continue; } Pawn pawn = LovePartnerRelationUtility.ExistingMostLikedLovePartner(current, false); if (pawn == null || !pawn.Spawned || pawn.Map != current.Map || pawn.Faction != Faction.OfPlayer || pawn.HostFaction != null) { num3++; } else { num4++; } } if (num4 % 2 != 0) { //Log.ErrorOnce("partneredCols % 2 != 0", 743211, false); } for (int j = 0; j < num4 / 2; j++) { if (num2 > 0) { num2--; } else { num -= 2; } } for (int k = 0; k < num3; k++) { if (num2 > 0) { num2--; } else { num--; } } __result = num < 0 || num2 < 0; return(false); } catch (Exception e) { Log.Message("[ATPP] ALert_NeedColonistBeds.NeedColonistBeds :" + e.Message + " - " + e.StackTrace); return(true); } }
private static float RandomSelectionWeight_Method(Pawn initiator, Pawn recipient) { CompIndividuality compOther = recipient.TryGetComp <CompIndividuality>(); CompIndividuality comp = initiator.TryGetComp <CompIndividuality>(); if (LovePartnerRelationUtility.LovePartnerRelationExists(initiator, recipient)) { return(0f); } float attractiveness = initiator.relations.SecondaryRomanceChanceFactor(recipient); if (attractiveness < 0.15f) { return(0f); } int opinionOfOther = initiator.relations.OpinionOf(recipient); if (opinionOfOther < 5) { return(0f); } if (recipient.relations.OpinionOf(initiator) < 5) { return(0f); } float existingLovePartnerFactor = 1f; Pawn pawn = LovePartnerRelationUtility.ExistingMostLikedLovePartner(initiator, false); if (pawn != null) { float opinionOfSpouse = initiator.relations.OpinionOf(pawn); existingLovePartnerFactor = Mathf.InverseLerp(50f, -50f, opinionOfSpouse); } float romanceFactor; if (compOther != null) { romanceFactor = compOther.RomanceFactor * 2f; } else { romanceFactor = 1f; } float attractivenessFactor = Mathf.InverseLerp(0.15f, 1f, attractiveness); float opinionFactor = Mathf.InverseLerp(5f, 100f, opinionOfOther); float genderFactor = 1f; if (initiator.gender != recipient.gender && compOther != null && comp != null) { if (compOther.sexuality == CompIndividuality.Sexuality.Straight) { genderFactor = 1.0f; } else if (compOther.sexuality == CompIndividuality.Sexuality.Bisexual) { genderFactor = 0.75f; } else if (compOther.sexuality == CompIndividuality.Sexuality.Gay) { genderFactor = 0.1f; } else if (compOther.sexuality == CompIndividuality.Sexuality.Asexual && comp.sexuality == CompIndividuality.Sexuality.Asexual) { genderFactor = 1.0f; } } if (initiator.gender == recipient.gender && compOther != null && comp != null) { if (compOther.sexuality == CompIndividuality.Sexuality.Gay) { genderFactor = 1.0f; } else if (compOther.sexuality == CompIndividuality.Sexuality.Bisexual) { genderFactor = 0.75f; } else if (compOther.sexuality == CompIndividuality.Sexuality.Straight) { genderFactor = 0.1f; } else if (compOther.sexuality == CompIndividuality.Sexuality.Asexual && comp.sexuality == CompIndividuality.Sexuality.Asexual) { genderFactor = 0.5f; } } return(1.15f * romanceFactor * attractivenessFactor * opinionFactor * existingLovePartnerFactor * genderFactor); }
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.defeated && !SettlementUtility.IsPlayerAttackingAnySettlementOf(faction : x.Faction) && !PeaceTalksExist(faction : x.Faction) && x.Faction.leader != null && !x.Faction.leader.IsPrisoner && !x.Faction.leader.Spawned && (x.Faction.def.techLevel <= TechLevel.Medieval) && /*|| x.Faction.def.techLevel == TechLevel.Archotech*/ // not today space kitties !x.IsPrisoner && !x.Spawned && (!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.
protected override float MtbHours(Pawn pawn) { float base_mtb = xxx.config.comfort_prisoner_rape_mtbh_mul; // Default is 4.0 float desire_factor; { Need_Sex need_sex = pawn.needs.TryGetNeed <Need_Sex>(); if (need_sex != null) { if (need_sex.CurLevel <= need_sex.thresh_frustrated()) { desire_factor = 0.40f; } else if (need_sex.CurLevel <= need_sex.thresh_horny()) { desire_factor = 0.80f; } else { desire_factor = 1.00f; } } else { desire_factor = 1.00f; } } float personality_factor; { personality_factor = 1.0f; if (xxx.is_nympho(pawn)) { personality_factor *= 0.5f; } else if (xxx.is_prude(pawn) || pawn.story.traits.HasTrait(TraitDefOf.BodyPurist)) { personality_factor *= 2f; } if (pawn.story.traits.HasTrait(TraitDefOf.Nudist)) { personality_factor *= 0.9f; } // Pawns with no zoophile trait should first try to find other outlets. if (!xxx.is_zoophile(pawn)) { personality_factor *= 8f; } // Less likely to engage in bestiality if the pawn has a lover... unless the lover is an animal (there's mods for that, so need to check). if (!xxx.isSingleOrPartnerNotHere(pawn) && !xxx.is_animal(LovePartnerRelationUtility.ExistingMostLikedLovePartner(pawn, false)) && !xxx.is_lecher(pawn) && !xxx.is_nympho(pawn)) { personality_factor *= 2.5f; } // Pawns with few or no prior animal encounters are more reluctant to engage in bestiality. if (pawn.records.GetValue(xxx.CountOfSexWithAnimals) < 3) { personality_factor *= 3f; } else if (pawn.records.GetValue(xxx.CountOfSexWithAnimals) > 10) { personality_factor *= 0.8f; } } float fun_factor; { if ((pawn.needs.joy != null) && (xxx.is_bloodlust(pawn))) { fun_factor = Mathf.Clamp01(0.50f + pawn.needs.joy.CurLevel); } else { fun_factor = 1.00f; } } return(base_mtb * desire_factor * personality_factor * fun_factor); }