Exemple #1
0
        public override float Calculate(Pawn observer, Pawn assessed)
        {
            float opinion       = AttractionUtility.GetRelationshipUnmodifiedOpinion(observer, assessed);
            float romanceFactor = Mathf.InverseLerp(-100, 100, opinion) * 2f;

            return(Mathf.Pow(romanceFactor, UniversalOpinionImportance));
        }
        public float SuccessChance(Pawn initiator, Pawn recipient)
        {
            float successChance = 0.6f * GradualRomanceMod.RomanticSuccessRate;

            successChance *= AttractionUtility.CalculateAttraction(recipient, initiator, false, true, out veryLowRecipientReasons, out lowRecipientReasons, out highRecipientReasons, out veryHighRecipientReasons, out AttractionFactorDef reasonForInstantFailure);
            return(Mathf.Clamp01(successChance));
        }
Exemple #3
0
        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);
        }
Exemple #4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="initiator"></param>
        /// <param name="recipient"></param>
        /// <returns></returns>
        public override float RandomSelectionWeight(Pawn initiator, Pawn recipient)
        {
            if (!AttractionUtility.QuickCheck(initiator, recipient))
            {
                return(0f);
            }
            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);
            //if (intiatorFailureReasons.Count() > 0)
            //{
            //    EmptyReasons();
            //    return 0f;
            //}
            float romanceChance = recipientPhysicalAttraction * recipientRomanticAttraction * recipientRomanticAttraction * initiatorCircumstances;
            float flirtFactor   = 0.5f;

            List <Thought_Memory> memoryList = initiator.needs.mood.thoughts.memories.Memories;

            for (int i = 0; i < memoryList.Count; i++)
            {
                Thought_Memory curMemory = memoryList[i];
                if (curMemory.def == ThoughtDefOfGR.RomanticDisinterest && curMemory.otherPawn == recipient)
                {
                    flirtFactor = flirtFactor * BadFlirtPenalty;
                }
            }
            flirtFactor   = Mathf.Max(flirtFactor, 0.05f);
            lastInitiator = initiator;
            lastRecipient = recipient;
            return(GradualRomanceMod.BaseFlirtChance * romanceChance * flirtFactor * BaseFlirtWeight);
        }
        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 ask their girlfriend/boyfriend to move in
            if (!initiator.relations.DirectRelationExists(PawnRelationDefOfGR.Lovefriend, recipient))
            {
                return(0f);
            }
            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);
            }

            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 ask to move in.
                float personalityFactor = Mathf.Pow(12f, (1f - PsycheHelper.Comp(initiator).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Romantic)));
                romanceChance *= personalityFactor * 0.02f;
            }
            //If their potential 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.2f;
            }

            lastInitiator = initiator;
            lastRecipient = recipient;

            return(romanceChance * attractiveness);
        }
        /*
         * 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)
        {
            AttractionFactorDef whoCares;

            if (lastInitiator != initiator || lastRecipient != recipient)
            {
                EmptyReasons();
                initiatorAttraction = AttractionUtility.CalculateAttraction(initiator, recipient, false, false, out veryLowInitiatorReasons, out lowInitiatorReasons, out highInitiatorReasons, out veryHighInitiatorReasons, out whoCares);
            }

            pressureCache = AttractionUtility.RelationshipStress(initiator, recipient);


            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);
             *          }
             *      }
             *  }
             *
             *
             * }
             */
        }
Exemple #7
0
        public override float Calculate(Pawn observer, Pawn assessed)
        {
            if (AttractionUtility.IsWeaklyGynephilic(observer) || AttractionUtility.IsExclusivelyAndrophilic(observer))
            {
                return(0f);
            }
            if (AttractionUtility.IsOccasionallyGynephilic(observer))
            {
                return(0.5f);
            }

            return(1f);
        }
Exemple #8
0
        public override float Calculate(Pawn observer, Pawn assessed)
        {
            if (!AttractionUtility.IsGynephilic(observer))
            {
                return(0f);
            }
            if (AttractionUtility.IsWeaklyGynephilic(observer))
            {
                return(0.5f);
            }

            return(1f);
        }
            public AttractionRecord(Pawn pawn, Pawn other)
            {
                //Log.Message("Start constructor for " + pawn.Name.ToStringShort + " : " + other.Name.ToStringShort);
                lastRefreshedGameTick = Find.TickManager.TicksGame;
                //Log.Message("Made dictionary.");
                categoryCalculations = new Dictionary <AttractionFactorCategoryDef, float>();
                if (pawn == other)
                {
                    return;
                }
                totalAttraction = 1f;
                //Log.Message("Going through categories.");
                List <AttractionFactorCategoryDef> allDefs = DefDatabase <AttractionFactorCategoryDef> .AllDefsListForReading;

                foreach (AttractionFactorCategoryDef category in allDefs)
                {
                    //Log.Message("Processing " + category.defName);
                    AttractionFactorDef        whoCares;
                    List <AttractionFactorDef> newVeryHighFactors = new List <AttractionFactorDef>()
                    {
                    };
                    List <AttractionFactorDef> newHighFactors = new List <AttractionFactorDef>()
                    {
                    };
                    List <AttractionFactorDef> newLowFactors = new List <AttractionFactorDef>()
                    {
                    };
                    List <AttractionFactorDef> newVeryLowFactors = new List <AttractionFactorDef>()
                    {
                    };
                    if (category.alwaysRecalculate)
                    {
                        //Log.Message("Passing " + category.defName);
                        continue;
                    }
                    else
                    {
                        //Log.Message("Adding result " + category.defName);
                        float result = AttractionUtility.CalculateAttractionCategory(category, pawn, other, out newVeryLowFactors, out newLowFactors, out newHighFactors, out newVeryHighFactors, out whoCares);

                        categoryCalculations.Add(category, result);
                        totalAttraction *= result;
                    }
                    //Log.Message("Adding factors.");
                    veryHighFactors.AddRange(newVeryHighFactors);
                    highFactors.AddRange(newHighFactors);
                    lowFactors.AddRange(newLowFactors);
                    veryLowFactors.AddRange(newVeryLowFactors);
                    //Log.Message("Finished adding factors.");
                }
            }
Exemple #10
0
        public override float Calculate(Pawn observer, Pawn assessed)
        {
            float observerValue = AttractionUtility.GetObjectiveSkillAttractiveness(observer);
            float assessedValue = AttractionUtility.GetObjectiveSkillAttractiveness(assessed);
            float value         = assessedValue / observerValue;

            if (value < 1)
            {
                value = Mathf.Pow(value, SkillAttractivenessDampenerUpper);
            }
            else
            {
                value = Mathf.Pow(value, SkillAttractivenessDampenerLower);
            }
            return(value);
        }
        public static bool RelationshipCanEvolveTo(Pawn pawn, Pawn other, PawnRelationDef newRelation)
        {
            List <ThoughtCondition> conditions;

            try
            {
                conditions = newRelation.GetModExtension <RomanticRelationExtension>().conditions;
            }
            catch (NullReferenceException)
            {
                return(false);
            }
            if (conditions.NullOrEmpty())
            {
                return(false);
            }
            if (!AttractionUtility.IsAgeAppropriate(pawn) || !AttractionUtility.IsAgeAppropriate(other))
            {
                try
                {
                    if (newRelation.GetModExtension <RomanticRelationExtension>().doesLovin)
                    {
                        return(false);
                    }
                }
                catch (NullReferenceException)
                {
                    return(false);
                }
            }
            for (int i = 0; i < conditions.Count(); i++)
            {
                Log.Message(conditions[i].thought.defName + ": " + pawn.needs.mood.thoughts.memories.NumMemoriesOfDef(conditions[i].thought).ToString() + " " + other.needs.mood.thoughts.memories.NumMemoriesOfDef(conditions[i].thought) + " needs " + conditions[i].numberRequired.ToString());

                if (GRThoughtUtility.NumOfMemoriesOfDefWhereOtherPawnIs(pawn, other, conditions[i].thought) < conditions[i].numberRequired || GRThoughtUtility.NumOfMemoriesOfDefWhereOtherPawnIs(other, pawn, conditions[i].thought) < conditions[i].numberRequired)
                {
                    return(false);
                }
            }
            return(true);
        }
Exemple #12
0
        private float CalculateAndSort(AttractionFactorCategoryDef category, Pawn observer, Pawn assessed, bool observerIsInitiator = true)
        {
            float result = AttractionUtility.CalculateAttractionCategory(category, observer, assessed, out List <AttractionFactorDef> veryLowFactors, out List <AttractionFactorDef> lowFactors, out List <AttractionFactorDef> hightFactors, out List <AttractionFactorDef> veryHighFactors, out AttractionFactorDef reasonForInstantFailure);

            if (observerIsInitiator)
            {
                veryHighInitiatorReasons.AddRange(veryHighFactors);
                highInitiatorReasons.AddRange(hightFactors);
                lowInitiatorReasons.AddRange(lowFactors);
                veryLowInitiatorReasons.AddRange(veryLowFactors);
                intiatorFailureReasons.Add(reasonForInstantFailure);
            }
            else
            {
                veryHighRecipientReasons.AddRange(veryHighFactors);
                highRecipientReasons.AddRange(hightFactors);
                lowRecipientReasons.AddRange(lowFactors);
                veryLowRecipientReasons.AddRange(veryLowFactors);
                recipientFailureReasons.Add(reasonForInstantFailure);
            }
            return(result);
        }
            public void Update(Pawn pawn, Pawn other)
            {
                lastRefreshedGameTick = Find.TickManager.TicksGame;
                veryHighFactors.Clear();
                highFactors.Clear();
                lowFactors.Clear();
                veryLowFactors.Clear();
                if (pawn == other)
                {
                    return;
                }
                float oldAttraction = totalAttraction;

                totalAttraction = 1f;
                foreach (AttractionFactorCategoryDef category in DefDatabase <AttractionFactorCategoryDef> .AllDefs)
                {
                    AttractionFactorDef        whoCares;
                    List <AttractionFactorDef> newVeryHighFactors;
                    List <AttractionFactorDef> newHighFactors;
                    List <AttractionFactorDef> newLowFactors;
                    List <AttractionFactorDef> newVeryLowFactors;
                    if (category.alwaysRecalculate || category.chanceOnly)
                    {
                        continue;
                    }
                    else
                    {
                        float result = AttractionUtility.CalculateAttractionCategory(category, pawn, other, out newVeryLowFactors, out newLowFactors, out newHighFactors, out newVeryHighFactors, out whoCares);

                        categoryCalculations[category] = result;
                        totalAttraction *= result;
                    }
                    veryHighFactors.AddRange(newVeryHighFactors);
                    highFactors.AddRange(newHighFactors);
                    lowFactors.AddRange(newLowFactors);
                    veryLowFactors.AddRange(newVeryLowFactors);
                }
            }
        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))
            {
                GRPawnRelationUtility.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;
            }
        }
Exemple #15
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="initiator"></param>
        /// <param name="recipient"></param>
        /// <returns></returns>
        public override float RandomSelectionWeight(Pawn initiator, Pawn recipient)
        {
            if (!AttractionUtility.QuickCheck(initiator, recipient))
            {
                return(0f);
            }
            EmptyReasons();
            AttractionFactorDef whoCares;
            float currentAttraction = AttractionUtility.CalculateAttraction(initiator, recipient, false, false, out veryLowInitiatorReasons, out lowInitiatorReasons, out highInitiatorReasons, out veryHighInitiatorReasons, out whoCares);

            recipientPhysicalAttraction = GRHelper.GRPawnComp(initiator).RetrieveAttractionForCategory(recipient, AttractionFactorCategoryDefOf.Physical);
            recipientRomanticAttraction = GRHelper.GRPawnComp(initiator).RetrieveAttractionForCategory(recipient, AttractionFactorCategoryDefOf.Romantic);
            recipientSocialAttraction   = GRHelper.GRPawnComp(initiator).RetrieveAttractionForCategory(recipient, AttractionFactorCategoryDefOf.Social);

            //initiatorCircumstances = CalculateAndSort(AttractionFactorCategoryDefOf.Circumstance, initiator, recipient);
            //if (intiatorFailureReasons.Count() > 0)
            //{
            //    EmptyReasons();
            //    return 0f;
            //}
            float flirtFactor = 0.5f;

            List <Thought_Memory> memoryList = initiator.needs.mood.thoughts.memories.Memories;

            for (int i = 0; i < memoryList.Count; i++)
            {
                Thought_Memory curMemory = memoryList[i];
                if (curMemory.def == ThoughtDefOfGR.RomanticDisinterest && curMemory.otherPawn == recipient)
                {
                    flirtFactor = flirtFactor * BadFlirtPenalty;
                }
            }
            flirtFactor   = Mathf.Max(flirtFactor, 0.05f);
            lastInitiator = initiator;
            lastRecipient = recipient;
            return(GradualRomanceMod.BaseFlirtChance * currentAttraction * flirtFactor * BaseFlirtWeight);
        }
Exemple #16
0
        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);
        }
Exemple #17
0
        public static float CalculateAttraction(Pawn observer, Pawn assessed, bool attractionOnly, bool formalRelationship, out List <AttractionFactorDef> veryLowFactors, out List <AttractionFactorDef> lowFactors, out List <AttractionFactorDef> highFactors, out List <AttractionFactorDef> veryHighFactors, out AttractionFactorDef reasonForInstantFailure)
        {
            veryLowFactors = new List <AttractionFactorDef>()
            {
            };
            lowFactors = new List <AttractionFactorDef>()
            {
            };
            highFactors = new List <AttractionFactorDef>()
            {
            };
            veryHighFactors = new List <AttractionFactorDef>()
            {
            };
            reasonForInstantFailure = null;
            float result = observer.GetComp <GRPawnComp>().RetrieveAttractionAndFactors(assessed, out veryLowFactors, out lowFactors, out highFactors, out veryHighFactors, formalRelationship, !attractionOnly);

            List <AttractionFactorCategoryDef> allCategories = DefDatabase <AttractionFactorCategoryDef> .AllDefsListForReading;

            foreach (AttractionFactorCategoryDef category in allCategories)
            {
                /*
                 * if (!formalRelationship && category.onlyForRomance)
                 * {
                 *  continue;
                 * }
                 * if (attractionOnly && category.chanceOnly)
                 * {
                 *  continue;
                 * }
                 */
                if (!category.alwaysRecalculate)
                {
                    continue;
                }
                result *= AttractionUtility.CalculateAttractionCategory(category, observer, assessed, out List <AttractionFactorDef> newVeryLowFactors, out List <AttractionFactorDef> newLowFactors, out List <AttractionFactorDef> newHighFactors, out List <AttractionFactorDef> newVeryHighFactors, out AttractionFactorDef newReasonForInstantFailure);

                veryHighFactors.AddRange(newVeryHighFactors);
                highFactors.AddRange(newHighFactors);
                lowFactors.AddRange(newLowFactors);
                veryLowFactors.AddRange(newVeryLowFactors);
                if (reasonForInstantFailure == null && newReasonForInstantFailure != null)
                {
                    reasonForInstantFailure = newReasonForInstantFailure;
                }
            }
            if (!formalRelationship)
            {
                veryHighFactors.RemoveAll(x => x.category.onlyForRomance);
                highFactors.RemoveAll(x => x.category.onlyForRomance);
                lowFactors.RemoveAll(x => x.category.onlyForRomance);
                veryLowFactors.RemoveAll(x => x.category.onlyForRomance);
            }
            if (!attractionOnly)
            {
                veryHighFactors.RemoveAll(x => x.category.chanceOnly);
                highFactors.RemoveAll(x => x.category.chanceOnly);
                lowFactors.RemoveAll(x => x.category.chanceOnly);
                veryLowFactors.RemoveAll(x => x.category.chanceOnly);
            }
            return(result);
        }
        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));
        }
Exemple #19
0
        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);
                GRPawnRelationUtility.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;
            }
        }
Exemple #20
0
        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);
        }
Exemple #21
0
        /*
         * 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"));
                     *      }
                     *  }*/
                }
            }
        }
Exemple #22
0
 public override float Calculate(Pawn observer, Pawn assessed)
 {
     return(Mathf.InverseLerp(0f, AttractionUtility.GetObjectiveWealthAttractiveness(observer), AttractionUtility.GetObjectiveWealthAttractiveness(assessed)));
 }