//public float facialAttractiveness = 0f; public override void CompTick() { Pawn pawn = this.parent as Pawn; int gameTicks = Find.TickManager.TicksGame; if (gameTicks % recachePerTick == 0 && pawn.Spawned && !pawn.Dead) { refreshCache(pawn); } if (gameTicks % GenDate.TicksPerDay == 0 && pawn.Spawned && !pawn.Dead) { List <DirectPawnRelation> relations = pawn.relations.DirectRelations; for (int i = 0; i < relations.Count(); i++) { if (RelationshipUtility.ListOfRomanceStages().Contains(relations[i].def)) { if (BreakupUtility.CanDecay(pawn, relations[i].otherPawn, relations[i].def)) { if (GradualRomanceMod.DecayRate <= Rand.Value) { BreakupUtility.DecayRelationship(pawn, relations[i].otherPawn, relations[i].def); } } } } CleanAttractionRecords(); } }
private void BreakLoverAndFianceRelations(Pawn pawn, out List <Pawn> oldLoversAndFiances) { oldLoversAndFiances = new List <Pawn> { }; List <PawnRelationDef> relationsToBreak = RelationshipUtility.ListOfBreakupRelationships(); for (int i = 0; i < relationsToBreak.Count(); i++) { PawnRelationDef relation = relationsToBreak[i]; List <Pawn> pawns = RelationshipUtility.GetAllPawnsWithGivenRelationshipTo(pawn, relation); for (int i2 = 1; i2 < pawns.Count(); i2++) { Pawn other = pawns[i2]; if (!RelationshipUtility.IsPolygamist(pawn) || !RelationshipUtility.IsPolygamist(other)) { if (!relation.GetModExtension <RomanticRelationExtension>().isFormalRelationship&& !BreakupUtility.ShouldImplicitlyEndInformalRelationship(pawn, other, relation)) { continue; } BreakupUtility.ResolveBreakup(pawn, other, relation); oldLoversAndFiances.Add(other); } } } }
public static bool HasReasonForBreakup(Pawn pawn, Pawn other) { PawnRelationDef relation = RelationshipUtility.MostAdvancedRelationshipBetween(pawn, other); if (relation == null) { return(false); } if (AttractionUtility.GetRelationshipUnmodifiedOpinion(pawn, other) < unmodifiedRelationshipBreakupThreshold) { return(true); } if (pawn.needs.mood.thoughts.memories.Memories.Any <Thought_Memory>(x => x.def.defName == "CheatedOnMe" && x.otherPawn == other)) { return(true); } if (pawn.needs.mood.thoughts.memories.Memories.Any <Thought_Memory>(x => x.def.defName == "CaughtFlirting" && x.otherPawn == other)) { return(true); } if (ThoughtDetector.HasSocialSituationalThought(pawn, other, ThoughtDefOfGR.FeelingNeglected)) { return(true); } return(false); }
// Plundered and adapted from Psychology public override float RandomSelectionWeight(Pawn initiator, Pawn recipient) { if (!RelationshipUtility.HasInformalRelationship(initiator, recipient) && !LovePartnerRelationUtility.LovePartnerRelationExists(initiator, recipient)) { return(0f); } else if (initiator.story.traits.HasTrait(TraitDefOfPsychology.Codependent)) { return(0f); } float chance = 0.02f * GradualRomanceMod.BaseBreakupChance; float romanticFactor = 1f; if (PsycheHelper.PsychologyEnabled(initiator)) { chance = 0.05f * GradualRomanceMod.BaseBreakupChance; romanticFactor = Mathf.InverseLerp(1.05f, 0f, PsycheHelper.Comp(initiator).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Romantic)); } float opinionFactor = Mathf.InverseLerp(100f, -100f, (float)initiator.relations.OpinionOf(recipient)); float spouseFactor = 1f; PawnRelationDef relation = RelationshipUtility.MostAdvancedRelationshipBetween(initiator, recipient); spouseFactor = relation.GetModExtension <RomanticRelationExtension>().baseAffairReluctance; float justificationFactor = 0.75f; if (BreakupUtility.HasReasonForBreakup(initiator, recipient)) { justificationFactor = 2f; } return(chance * romanticFactor * opinionFactor * spouseFactor * justificationFactor); }
public override bool Check(Pawn observer, Pawn assessed) { if (RelationshipUtility.IsAnAffair(observer, assessed, out Pawn cuck1, out Pawn cuck2)) { observerCuckold = cuck1; assessedCuckold = cuck2; return(true); } return(false); }
//break all relations of given relation public static void BreakAllGivenRelations(Pawn pawn, PawnRelationDef relation, bool testRelations = false) { if (!RelationshipUtility.IsRomanticOrSexualRelationship(relation)) { return; } List <Pawn> allPawns = RelationshipUtility.GetAllPawnsWithGivenRelationshipTo(pawn, relation); for (int i = 0; i < allPawns.Count(); i++) { RelationToEx(pawn, allPawns[i], relation); } }
public override float Calculate(Pawn observer, Pawn assessed) { float weight = 1f; if (RelationshipUtility.IsPolygamist(assessed) && !RelationshipUtility.IsPolygamist(observer)) { weight *= .85f; } else if (RelationshipUtility.IsPolygamist(assessed) && RelationshipUtility.IsPolygamist(observer)) { weight *= 1.2f; } return(weight); }
public static void TryAddCheaterThought(Pawn pawn, Pawn cheater, Pawn cheaterLover) { { if (pawn.Dead) { return; } if (RelationshipUtility.IsPolygamist(pawn)) { pawn.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOfGR.CheatedOnMePolygamist, cheater); } else { float toleranceChance = 0.4f; //people who are codependent are more tolerant of cheating, even though they are less likely to cheat if (pawn.story.traits.HasTrait(TraitDefOfPsychology.Codependent)) { toleranceChance *= 2f; } //moralistic characters are less tolerant of cheating. if (PsycheHelper.PsychologyEnabled(pawn)) { toleranceChance *= (1.5f - PsycheHelper.Comp(pawn).Psyche.GetPersonalityRating(PersonalityNodeDefOfGR.Moralistic)); } //they are more likely to tolerate cheating if they like the person who the cheater is cheating with. toleranceChance *= Mathf.Min(0f, Mathf.InverseLerp(-80f, 30f, pawn.relations.OpinionOf(cheaterLover))); toleranceChance = Mathf.Clamp01(toleranceChance); if (Rand.Value < toleranceChance) { pawn.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOfGR.CheatedOnMeTolerated, cheater); } else { if (pawn.relations.OpinionOf(cheaterLover) >= 30f) { pawn.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOfGR.CheatedOnMeHighOpinion, cheater); } else { pawn.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOf.CheatedOnMe, cheater); } } pawn.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOfGR.LoversLover, cheaterLover); //cheaterLover.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOfGR.LoversLover, pawn); } } }
public override float Calculate(Pawn observer, Pawn assessed) { float affairReluctance = 1f; float affairReluctance2 = 1f; if (observerCuckold != null) { affairReluctance = RelationshipUtility.AffairReluctance(RelationshipUtility.MostAdvancedRelationshipBetween(observer, observerCuckold)); affairReluctance *= Mathf.Pow(Mathf.InverseLerp(-100f, 5f, observer.relations.OpinionOf(observerCuckold)), -0.33f); } if (assessedCuckold != null) { affairReluctance2 = RelationshipUtility.AffairReluctance(RelationshipUtility.MostAdvancedRelationshipBetween(assessed, assessedCuckold)); affairReluctance2 *= Mathf.Pow(Mathf.InverseLerp(-100f, 5f, observer.relations.OpinionOf(assessedCuckold)), -0.33f); } return(Mathf.Min(affairReluctance, affairReluctance2)); }
protected override ThoughtState CurrentStateInternal(Pawn pawn) { if (pawn.ownership.OwnedBed == null) { return(ThoughtState.Inactive); } IEnumerable <Pawn> bedPartners = from partner in pawn.ownership.OwnedBed.AssignedPawns where partner != pawn && RelationshipUtility.MostAdvancedRelationshipBetween(pawn, partner) != null && RelationshipUtility.ShouldShareBed(pawn, partner) == false select partner; if (bedPartners.Count() == 0) { return(ThoughtState.Inactive); } else { return(ThoughtState.ActiveAtStage(0)); } }
public static bool CanDecay(Pawn pawn, Pawn other, PawnRelationDef relation) { DirectPawnRelation directPawnRelation = pawn.relations.GetDirectRelation(relation, other); if (directPawnRelation == null) { //GradualRomanceMod.Error_TriedDecayNullRelationship(pawn, other, relation); return(false); } if (!GRHelper.RomanticRelationExtension(relation).decayable) { return(false); } //TODO - Revise to reflect lovin' if (RelationshipUtility.LevelOfTension(pawn, other) == 0) { return(true); } return(false); }
/// This is a mish-mash of copy-pasted code. /// Mostly copy-pasted from Psychology Mod by Word-Mule /// /// Does the same function but excludes lovefriends and sweethearts /// /// protected override ThoughtState CurrentStateInternal(Pawn p) { DirectPawnRelation directPawnRelation = RelationshipUtility.MostLikedBedSharingRelationship(p, false); if (directPawnRelation == null) { return(ThoughtState.Inactive); } bool multiplePartners = (from r in p.relations.PotentiallyRelatedPawns where RelationshipUtility.ShouldShareBed(p, r) select r).Count() > 1; bool partnerBedInRoom; if (p.ownership.OwnedBed != null) { partnerBedInRoom = (from t in p.ownership.OwnedBed.GetRoom().ContainedBeds where t.AssignedPawns.Contains(directPawnRelation.otherPawn) select t).Count() > 0; } else { partnerBedInRoom = false; } if (directPawnRelation != null && p.ownership.OwnedBed != null && RelationshipUtility.IsPolygamist(p) && multiplePartners && partnerBedInRoom) { return(ThoughtState.Inactive); } if (p.ownership.OwnedBed != null && p.ownership.OwnedBed == directPawnRelation.otherPawn.ownership.OwnedBed) { return(ThoughtState.Inactive); } if (p.relations.OpinionOf(directPawnRelation.otherPawn) <= 0) { return(ThoughtState.Inactive); } return(ThoughtState.ActiveDefault); }
public override void Interacted(Pawn initiator, Pawn recipient, List <RulePackDef> extraSentencePacks, out string letterText, out string letterLabel, out LetterDef letterDef) { if (lastInitiator != initiator || lastRecipient != recipient) { AttractionUtility.CalculateAttraction(initiator, recipient, false, true, out veryLowInitiatorReasons, out lowInitiatorReasons, out highInitiatorReasons, out veryHighInitiatorReasons, out AttractionFactorDef reasonForInstantFailure); } if (Rand.Value < this.SuccessChance(initiator, recipient)) { RelationshipUtility.AdvanceRelationship(initiator, recipient, PawnRelationDefOf.Lover); LovePartnerRelationUtility.TryToShareBed(initiator, recipient); //TODO Add Move In tale if (PawnUtility.ShouldSendNotificationAbout(initiator) || PawnUtility.ShouldSendNotificationAbout(recipient)) { letterText = "MoveInLetterText".Translate(initiator.Named("PAWN1"), recipient.Named("PAWN2")); letterText += AttractionUtility.WriteReasonsParagraph(initiator, recipient, veryHighInitiatorReasons, highInitiatorReasons, lowInitiatorReasons, veryLowInitiatorReasons); letterText += AttractionUtility.WriteReasonsParagraph(recipient, initiator, veryHighRecipientReasons, highRecipientReasons, lowRecipientReasons, veryLowRecipientReasons); letterLabel = "MoveInLetterTitle".Translate(); letterDef = LetterDefOf.PositiveEvent; } else { letterText = null; letterLabel = null; letterDef = null; } //extraSentencePacks.Add(RulePackDefOf.Sentence_RomanceAttemptAccepted); } else { //extraSentencePacks.Add(RulePackDefOf.Sentence_RomanceAttemptRejected); letterText = null; letterLabel = null; letterDef = null; } }
public static bool ShouldBeJealous(Pawn observer, Pawn initiator, Pawn recipient) { if (RelationshipUtility.IsPolygamist(observer)) { return(false); } PawnRelationDef initiatorRelationship = RelationshipUtility.MostAdvancedRelationshipBetween(observer, initiator); PawnRelationDef recipientRelationship = RelationshipUtility.MostAdvancedRelationshipBetween(observer, recipient); if (initiatorRelationship == null) { return(false); } if (!initiatorRelationship.GetModExtension <RomanticRelationExtension>().caresAboutCheating) { return(false); } if (recipientRelationship != null && !observer.story.traits.HasTrait(TraitDefOfGR.Jealous)) { return(false); } return(true); }
protected override ThoughtState CurrentSocialStateInternal(Pawn pawn, Pawn other) { if (!other.RaceProps.Humanlike || !RelationsUtility.PawnsKnowEachOther(pawn, other)) { return(false); } PawnRelationDef pawnRelationDef = RelationshipUtility.MostAdvancedRelationshipBetween(pawn, other); if (pawnRelationDef == null) { return(false); } if (!pawnRelationDef.GetModExtension <RomanticRelationExtension>().isFormalRelationship) { return(false); } if (RelationshipUtility.LevelOfTension(pawn, other) == 0) { return(ThoughtState.ActiveDefault); } return(false); }
public static bool ShouldImplicitlyEndInformalRelationship(Pawn pawn, Pawn other, PawnRelationDef relation) { if (CanDecay(pawn, other, relation)) { return(true); } if (RelationshipUtility.IsPolygamist(pawn)) { return(false); } float chance = Mathf.InverseLerp(80, -20, AttractionUtility.GetRelationshipUnmodifiedOpinion(pawn, other)); chance *= (relation.GetModExtension <RomanticRelationExtension>().relationshipLevel / (relation.GetModExtension <RomanticRelationExtension>().relationshipLevel + 1)); if (PsycheHelper.PsychologyEnabled(pawn)) { chance *= Mathf.Lerp(0f, 2f, PsycheHelper.Comp(pawn).Psyche.GetPersonalityRating(PersonalityNodeDefOfGR.Moralistic)); } if (Rand.Value < chance) { return(true); } return(false); }
public override float Calculate(Pawn observer, Pawn assessed) { //List<Pawn> allPawns = assessed.MapHeld.mapPawns.AllPawnsSpawned; float numOfAssessedFriends = 0f; float numOfObservedFriends = 0f; /* * if (cachedValues) * { * numOfAssessedFriends = GRHelper.GRPawnComp(assessedPawn).cachedNumberOfColonyFriends; * numOfObservedFriends = GRHelper.GRPawnComp(observerPawn).cachedNumberOfColonyFriends; * } */ numOfAssessedFriends = RelationshipUtility.NumberOfFriends(assessed); numOfObservedFriends = RelationshipUtility.NumberOfFriends(observer); float friendDifference = numOfAssessedFriends - numOfObservedFriends; if (friendDifference == 0f) { return(1f); } return(Mathf.Pow(((numOfAssessedFriends + 1f) / (numOfObservedFriends + 1f)), FriendAttractionDampener)); }
/* * public float SuccessChance(Pawn initiator, Pawn recipient) * { * float recipientAttraction = recipient.relations.SecondaryRomanceChanceFactor(initiator); * return 1f; * } */ // //allDefsListForReading.TryRandomElementByWeight((InteractionDef x) => x.Worker.RandomSelectionWeight(this.pawn, p), out intDef) public override void Interacted(Pawn initiator, Pawn recipient, List <RulePackDef> extraSentencePacks, out string letterText, out string letterLabel, out LetterDef letterDef) { if (lastInitiator != initiator || lastRecipient != recipient) { EmptyReasons(); recipientPhysicalAttraction = CalculateAndSort(AttractionFactorCategoryDefOf.Physical, initiator, recipient); recipientRomanticAttraction = CalculateAndSort(AttractionFactorCategoryDefOf.Romantic, initiator, recipient); recipientSocialAttraction = CalculateAndSort(AttractionFactorCategoryDefOf.Social, initiator, recipient); initiatorCircumstances = CalculateAndSort(AttractionFactorCategoryDefOf.Circumstance, initiator, recipient); } AttractionFactorDef whoCares; /* * initiatorPhysicalAttraction = CalculateAndSort(AttractionFactorCategoryDefOf.Physical, recipient, initiator, false); * initiatorRomanticAttraction = CalculateAndSort(AttractionFactorCategoryDefOf.Romantic, recipient, initiator, false); * initiatorSocialAttraction = CalculateAndSort(AttractionFactorCategoryDefOf.Social, recipient, initiator, false); * recipientCircumstances = CalculateAndSort(AttractionFactorCategoryDefOf.Circumstance, recipient, initiator, false); */ recipientCircumstances = AttractionUtility.CalculateAttractionCategory(AttractionFactorCategoryDefOf.Circumstance, recipient, initiator); float totalAttraction = AttractionUtility.CalculateAttraction(recipient, initiator, false, false, out veryLowRecipientReasons, out lowRecipientReasons, out highRecipientReasons, out veryHighRecipientReasons, out whoCares); initiatorPhysicalAttraction = GRHelper.GRPawnComp(recipient).RetrieveAttractionForCategory(initiator, AttractionFactorCategoryDefOf.Physical); initiatorRomanticAttraction = GRHelper.GRPawnComp(recipient).RetrieveAttractionForCategory(initiator, AttractionFactorCategoryDefOf.Romantic); initiatorSocialAttraction = GRHelper.GRPawnComp(recipient).RetrieveAttractionForCategory(initiator, AttractionFactorCategoryDefOf.Social); LogFlirt(initiator.Name.ToStringShort + "=>" + recipient.Name.ToStringShort + " attraction: physical " + recipientPhysicalAttraction.ToString() + ", romantic " + recipientRomanticAttraction.ToString() + ", social " + recipientSocialAttraction.ToString() + "."); List <FlirtStyleDef> allDefsListForReading = DefDatabase <FlirtStyleDef> .AllDefsListForReading; FlirtStyleDef flirtStyle; pressureCache = AttractionUtility.RelationshipStress(initiator, recipient); allDefsListForReading.TryRandomElementByWeight((FlirtStyleDef x) => CalculateFlirtStyleWeight(x, initiator, recipient), out flirtStyle); if (flirtStyle == null) { Log.Error("FailedToFindFlirt_error".Translate()); letterText = null; letterLabel = null; letterDef = null; return; } if (veryHighInitiatorReasons.Count() > 0) { AttractionFactorDef reason = veryHighInitiatorReasons.RandomElement <AttractionFactorDef>(); extraSentencePacks.Add(reason.intriguedByText); } else if (highInitiatorReasons.Count() > 0) { AttractionFactorDef reason = highInitiatorReasons.RandomElement <AttractionFactorDef>(); extraSentencePacks.Add(reason.intriguedByText); } if (recipient.gender == Gender.Male) { extraSentencePacks.Add(flirtStyle.rulePackMale); } if (recipient.gender == Gender.Female) { extraSentencePacks.Add(flirtStyle.rulePackFemale); } LogFlirt("Flirt chosen: " + flirtStyle.defName + "."); LogFlirt(recipient.Name.ToStringShort + "=>" + initiator.Name.ToStringShort + " attraction: physical " + initiatorPhysicalAttraction.ToString() + ", romantic " + initiatorRomanticAttraction.ToString() + ", social " + initiatorSocialAttraction.ToString() + "."); if (initiatorPhysicalAttraction == 0f || initiatorRomanticAttraction == 0f || initiatorSocialAttraction == 0f) { successImpossible = true; } else { successImpossible = false; } FlirtReactionDef flirtReaction = null; IEnumerable <FlirtReactionDef> successfulFlirtReactions = (from reaction in DefDatabase <FlirtReactionDef> .AllDefsListForReading where reaction.successful select reaction); IEnumerable <FlirtReactionDef> unsuccessfulFlirtReactions = (from reaction in DefDatabase <FlirtReactionDef> .AllDefsListForReading where !reaction.successful select reaction); List <FlirtReactionDef> allFlirtReactions = DefDatabase <FlirtReactionDef> .AllDefsListForReading; FlirtReactionDef successfulFlirt; FlirtReactionDef unsuccessfulFlirt; successfulFlirtReactions.TryRandomElementByWeight((FlirtReactionDef x) => CalculateFlirtReactionWeight(flirtStyle, x, initiator, recipient), out successfulFlirt); unsuccessfulFlirtReactions.TryRandomElementByWeight((FlirtReactionDef x) => CalculateFlirtReactionWeight(flirtStyle, x, initiator, recipient), out unsuccessfulFlirt); if (successImpossible) { flirtReaction = unsuccessfulFlirt; } else { //revise to include flirt type float chance = Mathf.Clamp01(GradualRomanceMod.RomanticSuccessRate * Mathf.Pow(initiatorPhysicalAttraction, flirtStyle.baseSexiness) * Mathf.Pow(initiatorRomanticAttraction, flirtStyle.baseRomance) * Mathf.Pow(initiatorSocialAttraction, flirtStyle.baseLogic) * recipientCircumstances * 0.65f); Log.Message("Romance success chance: " + chance.ToString()); if (Rand.Value < chance) { flirtReaction = successfulFlirt; } else { flirtReaction = unsuccessfulFlirt; } LogFlirt(recipient.Name.ToStringShort + " chose reaction " + flirtReaction.defName + " from Successful: " + successfulFlirt.defName + "; Unsuccessful: " + unsuccessfulFlirt.defName + "."); } if (flirtReaction == null) { Log.Error("FailedToFindReaction_error".Translate()); letterText = null; letterLabel = null; letterDef = null; return; } if (initiator.gender == Gender.Male) { extraSentencePacks.Add(flirtReaction.maleRulePack); } if (initiator.gender == Gender.Female) { extraSentencePacks.Add(flirtReaction.femaleRulePack); } if (flirtReaction != FlirtReactionDefOf.Ignorant) { if (flirtReaction.successful) { if (veryHighRecipientReasons.Count() > 0) { AttractionFactorDef reason = veryHighRecipientReasons.RandomElement <AttractionFactorDef>(); extraSentencePacks.Add(reason.reactionPositiveText); } else if (highRecipientReasons.Count() > 0) { AttractionFactorDef reason = highRecipientReasons.RandomElement <AttractionFactorDef>(); extraSentencePacks.Add(reason.reactionPositiveText); } } else { if (veryLowRecipientReasons.Count() > 0) { AttractionFactorDef reason = veryLowRecipientReasons.RandomElement <AttractionFactorDef>(); extraSentencePacks.Add(reason.reactionNegativeText); } else if (lowRecipientReasons.Count() > 0) { AttractionFactorDef reason = lowRecipientReasons.RandomElement <AttractionFactorDef>(); extraSentencePacks.Add(reason.reactionNegativeText); } } } flirtReaction.worker.GiveThoughts(initiator, recipient, out List <RulePackDef> yetMoreSentencePacks); extraSentencePacks.AddRange(yetMoreSentencePacks); letterText = null; letterLabel = null; letterDef = null; List <Pawn> loversInSight = RelationshipUtility.PotentiallyJealousPawnsInLineOfSight(initiator); List <Pawn> loversInSight2 = RelationshipUtility.PotentiallyJealousPawnsInLineOfSight(recipient); for (int i = 0; i < loversInSight.Count(); i++) { if (BreakupUtility.ShouldBeJealous(loversInSight[i], initiator, recipient)) { loversInSight[i].needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOfGR.CaughtFlirting, initiator); if (flirtReaction.successful) { loversInSight[i].needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOfGR.CaughtFlirtingWithLover, recipient); } } } if (flirtReaction.successful) { if (flirtReaction.provokesJealousy) { for (int i = 0; i < loversInSight2.Count(); i++) { if (BreakupUtility.ShouldBeJealous(loversInSight2[i], initiator, recipient)) { loversInSight2[i].needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOfGR.CaughtFlirting, recipient); loversInSight2[i].needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOfGR.CaughtFlirtingWithLover, initiator); } } } RelationshipUtility.AdvanceInformalRelationship(initiator, recipient, out PawnRelationDef newRelation, (flirtStyle.baseSweetheartChance * flirtReaction.sweetheartModifier)); if (newRelation != null && (PawnUtility.ShouldSendNotificationAbout(initiator) || PawnUtility.ShouldSendNotificationAbout(recipient))) { string initiatorParagraph = AttractionUtility.WriteReasonsParagraph(initiator, recipient, veryHighInitiatorReasons, highInitiatorReasons, lowInitiatorReasons, veryLowInitiatorReasons); string recipientParagraph = AttractionUtility.WriteReasonsParagraph(recipient, initiator, veryHighRecipientReasons, highRecipientReasons, lowRecipientReasons, veryLowRecipientReasons); letterDef = LetterDefOf.PositiveEvent; letterLabel = newRelation.GetModExtension <RomanticRelationExtension>().newRelationshipTitleText.Translate(); letterText = newRelation.GetModExtension <RomanticRelationExtension>().newRelationshipLetterText.Translate(initiator.Named("PAWN1"), recipient.Named("PAWN2")); letterText += initiatorParagraph; letterText += recipientParagraph; /* if (newRelation == PawnRelationDefOfGR.Sweetheart) * { * letterDef = LetterDefOf.PositiveEvent; * letterLabel = "NewSweetheartsLabel".Translate(); * letterText = "NewSweetheartsText".Translate(initiator.Named("PAWN1"), recipient.Named("PAWN2")); * } * if (newRelation == PawnRelationDefOfGR.Lovebuddy) * { * letterDef = LetterDefOf.PositiveEvent; * letterLabel = "NewLovebuddiesLabel".Translate(); * letterText = "NewLovebuddiesText".Translate(initiator.Named("PAWN1"), recipient.Named("PAWN2")); * } * if (newRelation == PawnRelationDefOfGR.Paramour) * { * if (RelationshipUtility.IsAnAffair(initiator, recipient, out Pawn initiatorSO, out Pawn recipientSO)) * { * letterDef = LetterDefOf.NegativeEvent; * letterLabel = "ParamoursAffairLabel".Translate(); * if (initiatorSO != null && recipientSO != null) * { * letterText = "ParamoursAffairTwoCuckoldsText".Translate(initiator.Named("PAWN1"), recipient.Named("PAWN2"), initiatorSO.Named("CUCKOLD1"), recipientSO.Named("CUCKOLD2")); * } * if (initiatorSO != null && recipientSO == null) * { * letterText = "ParamoursAffairInitiatorCuckoldText".Translate(initiator.Named("PAWN1"), recipient.Named("PAWN2"), initiatorSO.Named("CUCKOLD1")); * } * if (initiatorSO == null && recipientSO != null) * { * letterText = "ParamoursAffairRecipientCuckoldText".Translate(initiator.Named("PAWN1"), recipient.Named("PAWN2"), recipientSO.Named("CUCKOLD1")); * } * } * else * { * letterDef = LetterDefOf.PositiveEvent; * letterLabel = "NewParamoursLabel".Translate(); * letterText = "NewParamoursText".Translate(initiator.Named("PAWN1"), recipient.Named("PAWN2")); * } * }*/ } } }
public override void Interacted(Pawn initiator, Pawn recipient, List <RulePackDef> extraSentencePacks, out string letterText, out string letterLabel, out LetterDef letterDef) { if (lastInitiator != initiator || lastRecipient != recipient) { AttractionUtility.CalculateAttraction(initiator, recipient, false, true, out veryLowInitiatorReasons, out lowInitiatorReasons, out highInitiatorReasons, out veryHighInitiatorReasons, out AttractionFactorDef reasonForInstantFailure); } if (Rand.Value < this.SuccessChance(initiator, recipient)) { List <Pawn> list; this.BreakLoverAndFianceRelations(initiator, out list); List <Pawn> list2; this.BreakLoverAndFianceRelations(recipient, out list2); for (int i = 0; i < list.Count; i++) { BreakupUtility.TryAddCheaterThought(list[i], initiator, recipient); } for (int j = 0; j < list2.Count; j++) { BreakupUtility.TryAddCheaterThought(list2[j], recipient, initiator); } initiator.relations.TryRemoveDirectRelation(PawnRelationDefOf.ExLover, recipient); initiator.relations.TryRemoveDirectRelation(PawnRelationDefOfGR.ExLovefriend, recipient); RelationshipUtility.AdvanceRelationship(recipient, initiator, PawnRelationDefOfGR.Lovefriend); //TODO Change record tale TaleRecorder.RecordTale(TaleDefOf.BecameLover, new object[] { initiator, recipient }); initiator.needs.mood.thoughts.memories.RemoveMemoriesOfDefWhereOtherPawnIs(ThoughtDefOf.BrokeUpWithMe, recipient); recipient.needs.mood.thoughts.memories.RemoveMemoriesOfDefWhereOtherPawnIs(ThoughtDefOf.BrokeUpWithMe, initiator); initiator.needs.mood.thoughts.memories.RemoveMemoriesOfDefWhereOtherPawnIs(ThoughtDefOf.FailedRomanceAttemptOnMe, recipient); initiator.needs.mood.thoughts.memories.RemoveMemoriesOfDefWhereOtherPawnIs(ThoughtDefOf.FailedRomanceAttemptOnMeLowOpinionMood, recipient); recipient.needs.mood.thoughts.memories.RemoveMemoriesOfDefWhereOtherPawnIs(ThoughtDefOf.FailedRomanceAttemptOnMe, initiator); recipient.needs.mood.thoughts.memories.RemoveMemoriesOfDefWhereOtherPawnIs(ThoughtDefOf.FailedRomanceAttemptOnMeLowOpinionMood, initiator); if (PawnUtility.ShouldSendNotificationAbout(initiator) || PawnUtility.ShouldSendNotificationAbout(recipient)) { this.GetNewLoversLetter(initiator, recipient, list, list2, out letterText, out letterLabel, out letterDef); letterText += AttractionUtility.WriteReasonsParagraph(initiator, recipient, veryHighInitiatorReasons, highInitiatorReasons, lowInitiatorReasons, veryLowInitiatorReasons); letterText += AttractionUtility.WriteReasonsParagraph(recipient, initiator, veryHighRecipientReasons, highRecipientReasons, lowRecipientReasons, veryLowRecipientReasons); } else { letterText = null; letterLabel = null; letterDef = null; } extraSentencePacks.Add(RulePackDefOf.Sentence_RomanceAttemptAccepted); } else { initiator.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOf.RebuffedMyRomanceAttempt, recipient); recipient.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOf.FailedRomanceAttemptOnMe, initiator); if (recipient.relations.OpinionOf(initiator) <= 0) { recipient.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOf.FailedRomanceAttemptOnMeLowOpinionMood, initiator); } extraSentencePacks.Add(RulePackDefOf.Sentence_RomanceAttemptRejected); letterText = null; letterLabel = null; letterDef = null; } }
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 (!RelationshipUtility.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); }
private float CalculateFlirtReactionWeight(FlirtStyleDef flirtStyle, FlirtReactionDef flirtReaction, Pawn initiator, Pawn recipient) { float chance = GradualRomanceMod.RomanticSuccessRate * flirtReaction.baseChance; string log = "Reaction " + flirtReaction.defName + ": base chance " + chance.ToString(); if (successImpossible && flirtReaction.successful) { log += ". Canceled, success impossible."; LogFlirt(log); return(0f); } if (successImpossible == false) { chance *= Mathf.Pow(flirtReaction.sexyReaction * initiatorPhysicalAttraction, flirtStyle.baseSexiness); log += " sexiness " + chance.ToString(); chance *= Mathf.Pow(flirtReaction.romanticReaction * initiatorRomanticAttraction, flirtStyle.baseRomance); log += " romance " + chance.ToString(); chance *= Mathf.Pow(flirtReaction.logicalReaction * initiatorSocialAttraction, flirtStyle.baseLogic); log += " logic " + chance.ToString(); } chance *= Mathf.Pow(flirtReaction.obscureReaction, flirtStyle.baseObscurity); log += " obscurity " + chance.ToString(); //risky flirts are less risky if the two pawns are familiar with each other. if (RelationshipUtility.MostAdvancedRelationshipBetween(initiator, recipient) == null) { chance *= Mathf.Pow(flirtReaction.riskyReaction, flirtStyle.baseRiskiness); } else { chance *= Mathf.Pow(Mathf.Pow(flirtReaction.riskyReaction, flirtStyle.baseRiskiness), FamiliarityFactor); } chance *= Mathf.Pow(flirtReaction.riskyReaction, flirtStyle.baseRiskiness); log += " riskiness " + chance.ToString(); chance *= Mathf.Pow(flirtReaction.awkwardReaction, flirtStyle.baseAwkwardness); log += " awkward " + chance.ToString() + "; "; if (GradualRomanceMod.AttractionCalculation == GradualRomanceMod.AttractionCalculationSetting.Complex) { for (int i = 0; i < flirtReaction.personalityModifiers.Count(); i++) { PersonalityNodeModifier node = flirtReaction.personalityModifiers[i]; if (node.modifier >= 0) { chance = chance * Mathf.Pow(Mathf.Lerp(0.5f, 1.5f, PsycheHelper.Comp(recipient).Psyche.GetPersonalityRating(node.personalityNode)), node.modifier); log += node.personalityNode.defName + "+: " + chance.ToString() + ", "; } else { chance = chance * Mathf.Pow(Mathf.Lerp(0.5f, 1.5f, Mathf.Abs(1 - PsycheHelper.Comp(recipient).Psyche.GetPersonalityRating(node.personalityNode))), Mathf.Abs(node.modifier)); log += node.personalityNode.defName + "-: " + chance.ToString() + ", "; } } } for (int i = 0; i < flirtReaction.traitModifiers.Count(); i++) { if (recipient.story.traits.HasTrait(flirtReaction.traitModifiers[i].trait)) { chance *= flirtReaction.traitModifiers[i].modifier; log += flirtReaction.traitModifiers[i].trait.defName + " " + chance.ToString() + ", "; } } /* * if (flirtReaction.successful == true) * { * chance *= initiator.GetStatValue(StatDefOf.SocialImpact); * log += "social impact: " + chance.ToString() + ", "; * //chance *= recipientCircumstances; * }*/ log += "end."; LogFlirt(log); return(chance); }
public override bool Check(Pawn observer, Pawn assessed) { return(RelationshipUtility.GetAllPawnsRomanticWith(observer).Count() >= GradualRomanceMod.numberOfRelationships && !RelationshipUtility.GetAllPawnsRomanticWith(observer).Contains(assessed)); }
public override void Interacted(Pawn initiator, Pawn recipient, List <RulePackDef> extraSentencePacks, out string letterText, out string letterLabel, out LetterDef letterDef) { ///Stitched in from Psychology. Thought thought = this.RandomBreakupReason(initiator, recipient); PawnRelationDef relation = RelationshipUtility.MostAdvancedRelationshipBetween(initiator, recipient); if (initiator.relations.DirectRelationExists(PawnRelationDefOf.Spouse, recipient)) { BreakupUtility.RelationToEx(initiator, recipient, PawnRelationDefOf.Spouse); recipient.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOf.DivorcedMe, initiator); recipient.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOfPsychology.BrokeUpWithMeCodependent, initiator); initiator.needs.mood.thoughts.memories.RemoveMemoriesOfDef(ThoughtDefOf.GotMarried); recipient.needs.mood.thoughts.memories.RemoveMemoriesOfDef(ThoughtDefOf.GotMarried); initiator.needs.mood.thoughts.memories.RemoveMemoriesOfDefWhereOtherPawnIs(ThoughtDefOf.HoneymoonPhase, recipient); recipient.needs.mood.thoughts.memories.RemoveMemoriesOfDefWhereOtherPawnIs(ThoughtDefOf.HoneymoonPhase, initiator); } else { BreakupUtility.ResolveBreakup(initiator, recipient, RelationshipUtility.MostAdvancedRelationshipBetween(initiator, recipient)); } //Idea - who gets the bedroom? Could be interesting. if (initiator.ownership.OwnedBed != null && initiator.ownership.OwnedBed == recipient.ownership.OwnedBed) { Pawn pawn = (Rand.Value >= 0.5f) ? recipient : initiator; pawn.ownership.UnclaimBed(); } TaleRecorder.RecordTale(TaleDefOf.Breakup, new object[] { initiator, recipient }); StringBuilder stringBuilder = new StringBuilder(); if (RelationshipUtility.IsInformalRelationship(relation)) { stringBuilder.AppendLine("LetterInformalRelationsEnds".Translate(initiator.Named("PAWN1"), recipient.Named("PAWN2"))); letterDef = LetterDefOf.NeutralEvent; letterLabel = "LetterLabelInformalRelationsEnds".Translate(); } else { stringBuilder.AppendLine("LetterNoLongerLovers".Translate(initiator.LabelShort, recipient.LabelShort, initiator.Named("PAWN1"), recipient.Named("PAWN2"))); letterDef = LetterDefOf.NegativeEvent; letterLabel = "LetterLabelBreakup".Translate(); } if (thought != null) { stringBuilder.AppendLine(); stringBuilder.AppendLine("FinalStraw".Translate(thought.CurStage.label.CapitalizeFirst())); } if (PawnUtility.ShouldSendNotificationAbout(initiator) || PawnUtility.ShouldSendNotificationAbout(recipient)) { letterDef = null; letterLabel = null; letterText = null; } else if (RelationshipUtility.IsInformalRelationship(relation) && GradualRomanceMod.informalRomanceLetters == false) { letterDef = null; letterLabel = null; letterText = null; } else { letterText = stringBuilder.ToString(); } }
public override float RandomSelectionWeight(Pawn initiator, Pawn recipient) { PawnRelationDef pawnRelation = RelationshipUtility.MostAdvancedRelationshipBetween(initiator, recipient); if (!AttractionUtility.QuickCheck(initiator, recipient)) { return(0f); } if (GradualRomanceMod.SeductionMode == GradualRomanceMod.SeductionModeSetting.NoSeduction) { return(0f); } else if (GradualRomanceMod.SeductionMode == GradualRomanceMod.SeductionModeSetting.OnlyRelationship) { if (pawnRelation == null || !RelationshipUtility.IsSexualRelationship(pawnRelation)) { return(0f); } } else if (GradualRomanceMod.SeductionMode == GradualRomanceMod.SeductionModeSetting.RelationshipAndNonColonists) { if (pawnRelation == null && recipient.IsColonist) { return(0f); } if (pawnRelation != null && !RelationshipUtility.IsSexualRelationship(pawnRelation) && recipient.IsColonist) { return(0f); } } //shouldn't seduce if you can't move if (initiator.health.capacities.GetLevel(PawnCapacityDefOf.Consciousness) <= 0.5f || initiator.health.capacities.GetLevel(PawnCapacityDefOf.Moving) <= 0.25f) { return(0f); } if (recipient.health.capacities.GetLevel(PawnCapacityDefOf.Consciousness) <= 0.5f || recipient.health.capacities.GetLevel(PawnCapacityDefOf.Moving) <= 0.25f) { return(0f); } //shouldn't seduce while working TimeAssignmentDef initiatorAssignment = initiator.timetable.GetAssignment(GenLocalDate.HourOfDay(initiator.Map)); TimeAssignmentDef recipientAssignment = recipient.timetable.GetAssignment(GenLocalDate.HourOfDay(recipient.Map)); if (initiatorAssignment != TimeAssignmentDefOf.Joy || initiatorAssignment != TimeAssignmentDefOf.Anything) { return(0f); } if (recipientAssignment != TimeAssignmentDefOf.Joy || recipientAssignment != TimeAssignmentDefOf.Anything) { return(0f); } EmptyReasons(); AttractionFactorDef whoCares; initiatorAttraction = AttractionUtility.CalculateAttraction(initiator, recipient, false, false, out veryLowInitiatorReasons, out lowInitiatorReasons, out highInitiatorReasons, out veryHighInitiatorReasons, out whoCares); float tensionFactor = 1.33f * RelationshipUtility.LevelOfSexualTension(initiator, recipient); tensionFactor = Mathf.Max(1f, tensionFactor); lastInitiator = initiator; lastRecipient = recipient; return(GradualRomanceMod.BaseSeductionChance * initiatorAttraction * tensionFactor * AttractionUtility.PropensityToSeduce(initiator)); }
public override float Calculate(Pawn observer, Pawn assessed) { return(GradualRomanceMod.numberOfRelationships / (RelationshipUtility.GetAllPawnsRomanticWith(observer).Count() + 1)); }
private float CalculateFlirtStyleWeight(FlirtStyleDef flirtStyle, Pawn pawn, Pawn other) { string flirtLog = pawn.Name.ToStringShort + " => " + other.Name.ToStringShort + " considers " + flirtStyle.defName + ": "; //if a pawn has a canceling trait, we abort immediately for (int i = 0; i < flirtStyle.cancelingTraits.Count(); i++) { if (pawn.story.traits.HasTrait(flirtStyle.cancelingTraits[i])) { flirtLog += "canceled by " + flirtStyle.cancelingTraits[i].defName + "."; LogFlirt(flirtLog); return(0f); } } //we start with base weight chance float weight = flirtStyle.baseChance; //add relationship factor weight *= RelationshipFactorForFlirtStyle(RelationshipUtility.MostAdvancedRomanceOrExStage(pawn, other), flirtStyle); flirtLog += "base " + weight.ToString() + " "; //calculate attraction factors /* * weight *= recipientPhysicalAttraction * flirtStyle.baseSexiness; * flirtLog += "physical " + weight.ToString() + " "; * weight *= recipientRomanticAttraction * flirtStyle.baseRomance; * flirtLog += "romantic " + weight.ToString() + " "; * weight *= recipientSocialAttraction * flirtStyle.baseLogic; * flirtLog += "logical " + weight.ToString() + " "; */ //calculate promoting traits for (int i = 0; i < flirtStyle.traitModifiers.Count(); i++) { if (pawn.story.traits.HasTrait(flirtStyle.traitModifiers[i].trait)) { weight = weight * flirtStyle.traitModifiers[i].modifier; flirtLog += flirtStyle.traitModifiers[i].trait.defName + ": " + weight.ToString() + " "; } } if (PsycheHelper.PsychologyEnabled(pawn) && GradualRomanceMod.AttractionCalculation == GradualRomanceMod.AttractionCalculationSetting.Complex) { //calculate contributing personality traits for (int i = 0; i < flirtStyle.moreLikelyPersonalities.Count(); i++) { PersonalityNodeModifier currentModifier = flirtStyle.moreLikelyPersonalities[i]; weight = weight * Mathf.Pow(Mathf.Lerp(0.5f, 1.5f, PsycheHelper.Comp(pawn).Psyche.GetPersonalityRating(currentModifier.personalityNode)), currentModifier.modifier); flirtLog += currentModifier.personalityNode.defName + "+: " + weight.ToString() + " "; } for (int i = 0; i < flirtStyle.lessLikelyPersonalities.Count(); i++) { PersonalityNodeModifier currentModifier = flirtStyle.lessLikelyPersonalities[i]; weight = weight * Mathf.Pow(Mathf.Lerp(0.5f, 1.5f, Mathf.Abs(1 - PsycheHelper.Comp(pawn).Psyche.GetPersonalityRating(currentModifier.personalityNode))), currentModifier.modifier); flirtLog += currentModifier.personalityNode.defName + "-: " + weight.ToString() + " "; } } if (flirtStyle.incompetent) { weight *= pressureCache; flirtLog += "pressure: " + weight.ToString() + " "; } flirtLog += "end."; LogFlirt(flirtLog); return(weight); }