예제 #1
0
        protected override ThoughtState CurrentSocialStateInternal(Pawn p, Pawn otherPawn)
        {
            if (!RelationsUtility.PawnsKnowEachOther(p, otherPawn))
            {
                return(false);
            }
            if (!LovePartnerRelationUtility.LovePartnerRelationExists(p, otherPawn))
            {
                return(false);
            }
            if (!PsycheHelper.PsychologyEnabled(p))
            {
                return(false);
            }
            if (p.Map == otherPawn.Map)
            {
                PsycheHelper.Comp(p).LDRTick = Find.TickManager.TicksAbs;
                return(false);
            }
            int tickSinceLastSeen = PsycheHelper.Comp(p).LDRTick;
            int ticksApart        = Find.TickManager.TicksAbs - tickSinceLastSeen;
            int quadrumsApart     = Mathf.FloorToInt((float)ticksApart / (float)GenDate.TicksPerQuadrum);
            int maxApart          = (p.relations.GetDirectRelation(PawnRelationDefOf.Spouse, otherPawn) == null ? 7 : 6);

            if (quadrumsApart > maxApart)
            {
                quadrumsApart = maxApart;
            }
            if (quadrumsApart > 1)
            {
                return(ThoughtState.ActiveAtStage(quadrumsApart - 1));
            }
            return(false);
        }
예제 #2
0
 public static void DrawPsycheCard(Rect rect, Pawn pawn)
 {
     if (PsycheHelper.PsychologyEnabled(pawn))
     {
         GUI.BeginGroup(rect);
         Text.Font = GameFont.Small;
         Rect rect2 = new Rect(20f, 20f, rect.width - 20f, rect.height - 20f);
         Rect rect3 = rect2.ContractedBy(10f);
         Rect rect4 = rect3;
         Rect rect5 = rect3;
         rect4.width *= 0.6f;
         rect5.x      = rect4.xMax + 17f;
         rect5.xMax   = rect3.xMax;
         GUI.color    = new Color(1f, 1f, 1f, 0.5f);
         Widgets.DrawLineVertical(rect4.xMax, 0f, rect.height);
         GUI.color = Color.white;
         if (Prefs.DevMode)
         {
             Rect rect6 = new Rect(0f, 5f, rect3.width, 22f);
             PsycheCardUtility.DrawDebugOptions(rect6, pawn);
         }
         PsycheCardUtility.DrawPersonalityNodes(rect4, pawn);
         PsycheCardUtility.DrawSexuality(rect5, pawn, true);
         GUI.EndGroup();
     }
 }
예제 #3
0
 public void LearnSexuality(Pawn p)
 {
     if (p != null && PsycheHelper.PsychologyEnabled(pawn) && !knownSexualities.Keys.Contains(p))
     {
         knownSexualities.Add(p, PsycheHelper.Comp(p).Sexuality.kinseyRating);
     }
 }
 public override float RandomSelectionWeight(Pawn initiator, Pawn recipient)
 {
     if (!initiator.IsColonist || !recipient.IsColonist)
     {
         return(0f);
     }
     if (!RendezvousUtility.AcceptableGameConditionsToStartHangingOut(initiator.Map))
     {
         return(0f);
     }
     if (!PsycheHelper.PsychologyEnabled(initiator) || !PsycheHelper.PsychologyEnabled(recipient))
     {
         return(0f);
     }
     if (!LovePartnerRelationUtility.LovePartnerRelationExists(initiator, recipient))
     {
         return(0f);
     }
     if (PsycheHelper.Comp(initiator).Psyche.lastDateTick >= Find.TickManager.TicksGame - GenDate.TicksPerDay * 7 || PsycheHelper.Comp(recipient).Psyche.lastDateTick >= Find.TickManager.TicksGame - GenDate.TicksPerDay * 7)
     {
         return(0f);
     }
     if (!GatheringsUtility.ShouldGuestKeepAttendingGathering(initiator) || !GatheringsUtility.ShouldGuestKeepAttendingGathering(recipient))
     {
         return(0f);
     }
     return(1.2f * (1f + Mathf.InverseLerp(100f, 0f, initiator.needs.mood.thoughts.TotalOpinionOffset(recipient))) * PsycheHelper.Comp(initiator).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Romantic) * (1f - PsycheHelper.Comp(initiator).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Independent))
            * PsycheHelper.Comp(recipient).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Romantic) * (1f - PsycheHelper.Comp(recipient).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Independent)) * RendezvousUtility.ColonySizeFactor(initiator));
 }
        private void Finished()
        {
            StringBuilder attendedString = new StringBuilder();

            foreach (Pawn p in attendees)
            {
                attendedString.AppendLine(p.Name.ToString());
                if (PsycheHelper.PsychologyEnabled(p))
                {
                    ThoughtDef def = new ThoughtDef();
                    def.defName          = p.GetHashCode() + "AttendedFuneral" + dead.GetHashCode();
                    def.durationDays     = 20f;
                    def.nullifyingTraits = new List <TraitDef>();
                    def.nullifyingTraits.Add(TraitDefOf.Psychopath);
                    def.nullifyingTraits.Add(TraitDefOfPsychology.Desensitized);
                    def.thoughtClass = typeof(Thought_MemoryDynamic);
                    ThoughtStage stage = new ThoughtStage();
                    stage.label          = "AttendedFuneralThought".Translate(dead);
                    stage.baseMoodEffect = Mathf.RoundToInt((p.relations.OpinionOf(dead) / 15f) * (0.33f + PsycheHelper.Comp(p).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Nostalgic)));
                    stage.description    = "AttendedFuneralDesc".Translate().AdjustedFor(dead);
                    def.stages.Add(stage);
                    p.needs.mood.thoughts.memories.TryGainMemory(def);
                }
                else
                {
                    p.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOfPsychology.AttendedFuneral);
                }
            }
            if (attendees.Count == 0)
            {
                attendedString.AppendLine("No one.");
            }
            Find.LetterStack.ReceiveLetter("LetterLabelFuneralEnded".Translate(dead), "LetterFuneralEnded".Translate(dead, attendedString), LetterDefOf.NeutralEvent, null);
        }
예제 #6
0
 public override void PostMake()
 {
     base.PostMake();
     if (!PsycheHelper.PsychologyEnabled(this.pawn))
     {
         this.pawn.health.RemoveHediff(this);
     }
 }
예제 #7
0
        public override float RandomSelectionWeight(Pawn initiator, Pawn recipient)
        {
            if (!GatheringsUtility.ShouldGuestKeepAttendingGathering(initiator) || !GatheringsUtility.ShouldGuestKeepAttendingGathering(recipient))
            {
                return(0f);
            }
            if (!PsycheHelper.PsychologyEnabled(initiator) || !PsycheHelper.PsychologyEnabled(recipient))
            {
                return(0f);
            }
            if (initiator.GetLord() != null || recipient.GetLord() != null)
            {
                return(0f);
            }
            if (initiator.Drafted || recipient.Drafted)
            {
                return(0f);
            }
            if (!RendezvousUtility.AcceptableGameConditionsToStartHangingOut(initiator.Map))
            {
                return(0f);
            }
            if (initiator.Faction != recipient.Faction)
            {
                return(0f);
            }
            float initiatorFactor = 0f;
            float recipientFactor = 0f;

            if (initiator.relations.OpinionOf(recipient) > -20)
            {
                initiatorFactor = PsycheHelper.Comp(initiator).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Extroverted) + 0.15f + Mathf.InverseLerp(0f, 100f, initiator.relations.OpinionOf(recipient));
                recipientFactor = (PsycheHelper.Comp(recipient).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Friendly) + PsycheHelper.Comp(recipient).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Cool)) / 2f;
            }
            else if (initiator.relations.OpinionOf(recipient) <= -20)
            {
                initiatorFactor = Mathf.InverseLerp(0.6f, 1f, PsycheHelper.Comp(initiator).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Empathetic));
                recipientFactor = PsycheHelper.Comp(recipient).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Trusting);
            }
            float scheduleFactor = 0f;

            if (initiator.GetTimeAssignment() == TimeAssignmentDefOf.Anything)
            {
                scheduleFactor = 0.33f;
            }
            else if (initiator.GetTimeAssignment() == TimeAssignmentDefOf.Joy)
            {
                scheduleFactor = 1f;
            }
            if (initiator.mindState.IsIdle && recipient.mindState.IsIdle && initiator.GetTimeAssignment() != TimeAssignmentDefOf.Work && recipient.GetTimeAssignment() != TimeAssignmentDefOf.Work)
            {
                scheduleFactor = 5f;
            }
            return(0.05f * initiatorFactor * recipientFactor * scheduleFactor * RendezvousUtility.ColonySizeFactor(initiator));
        }
 public override void Init()
 {
     this.topic             = def.defName;
     this.label             = def.stages[0].label;
     this.baseOpinionOffset = def.stages[0].baseOpinionOffset;
     if (PsycheHelper.PsychologyEnabled(pawn))
     {
         PsycheHelper.Comp(pawn).Psyche.OpinionCacheDirty[otherPawn.ThingID] = true;
         Pair <string, string> disagreeKey = new Pair <string, string>(otherPawn.ThingID, label);
         PsycheHelper.Comp(pawn).Psyche.DisagreementCacheDirty[disagreeKey] = true;
     }
     base.Init();
 }
예제 #9
0
        private bool ShouldPawnKeepVoting(Pawn p)
        {
            if (!PsycheHelper.PsychologyEnabled(p))
            {
                return(false);
            }
            bool matchingCandidates = (from c in candidates
                                       where c.pawn == p
                                       select c).Count() > 0;

            if (voters.Contains(p.GetHashCode()) && !matchingCandidates)
            {
                return(false);
            }
            bool notApathetic = PsycheHelper.Comp(p).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Passionate) > (0.6f / candidates.Count);

            return(GatheringsUtility.ShouldGuestKeepAttendingGathering(p) && (notApathetic || matchingCandidates));
        }
예제 #10
0
 public override void MapLoaded(Map map)
 {
     if (ModIsActive && PsychologyBase.ActivateKinsey())
     {
         /* Remove Gay trait from pawns if Kinsey scale is enabled */
         IEnumerable <Pawn> gayPawns = (from p in map.mapPawns.AllPawns
                                        where p.story != null && p.story.traits.HasTrait(TraitDefOf.Gay)
                                        select p);
         foreach (Pawn pawn in gayPawns)
         {
             RemoveTrait(pawn, TraitDefOf.Gay);
             if (PsycheHelper.PsychologyEnabled(pawn) && PsycheHelper.Comp(pawn).Sexuality.kinseyRating < 5)
             {
                 PsycheHelper.Comp(pawn).Sexuality.kinseyRating = Rand.RangeInclusive(5, 6);
             }
         }
     }
 }
예제 #11
0
 public static void DrawPsycheMenuCard(Rect rect, Pawn pawn)
 {
     if (PsycheHelper.PsychologyEnabled(pawn))
     {
         GUI.BeginGroup(rect);
         Text.Font = GameFont.Small;
         Rect rect2 = new Rect(10f, 10f, rect.width - 10f, rect.height - 10f);
         Rect rect4 = rect2;
         Rect rect5 = rect2;
         rect4.width *= 0.6f;
         rect4.xMin  -= 20f;
         rect5.x      = rect4.xMax + 17f;
         rect5.xMax   = rect.xMax;
         GUI.color    = new Color(1f, 1f, 1f, 0.5f);
         Widgets.DrawLineVertical(rect4.xMax, 0f, rect.height);
         GUI.color = Color.white;
         PsycheCardUtility.DrawPersonalityNodes(rect4, pawn);
         PsycheCardUtility.DrawSexuality(rect5, pawn, false);
         GUI.EndGroup();
     }
 }
        public override float RandomSelectionWeight(Pawn initiator, Pawn recipient)
        {
            if (!PsycheHelper.PsychologyEnabled(initiator) || !PsycheHelper.PsychologyEnabled(recipient))
            {
                return(0f);
            }
            if (!initiator.health.capacities.CapableOf(PawnCapacityDefOf.Talking) || !recipient.health.capacities.CapableOf(PawnCapacityDefOf.Talking))
            {
                return(0f);
            }
            float baseChance = 0.45f;
            Lord  lord       = LordUtility.GetLord(initiator);

            if (lord != null && (lord.LordJob is LordJob_HangOut || lord.LordJob is LordJob_Date) && LordUtility.GetLord(recipient) == lord)
            {
                baseChance = 0.75f;
            }
            if (initiator.story.traits.HasTrait(TraitDefOfPsychology.Chatty))
            {
                baseChance *= 1.2f;
            }
            return(Mathf.Max(0f, baseChance + (PsycheHelper.Comp(recipient).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Friendly) - 0.6f) + (PsycheHelper.Comp(initiator).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Extroverted) - 0.5f)));
        }
예제 #13
0
        public override void Notify_ReachedDutyLocation(Pawn voter)
        {
            LordJob_Joinable_Election election = voter.GetLord().LordJob as LordJob_Joinable_Election;

            if (election != null && PsycheHelper.PsychologyEnabled(voter) && !election.voters.Contains(voter.GetHashCode()))
            {
                election.voters.Add(voter.GetHashCode());
                if (election.candidates.Find(c => c.pawn == voter) == null)
                {
                    List <Pair <Pawn, float> > possibleVotes = new List <Pair <Pawn, float> >();
                    foreach (Candidate candidate in election.candidates)
                    {
                        float issueWeighting = 0f;
                        candidate.nodes.ForEach(p => issueWeighting += (4f * Mathf.Pow(1f - Mathf.Abs(PsycheHelper.Comp(candidate.pawn).Psyche.GetPersonalityRating(p) - PsycheHelper.Comp(voter).Psyche.GetPersonalityRating(p)), 5f)) * Mathf.Pow(2.5f, p.controversiality));
                        possibleVotes.Add(new Pair <Pawn, float>(candidate.pawn, issueWeighting + voter.relations.OpinionOf(candidate.pawn)));
                    }
                    IEnumerable <Pair <Pawn, float> > orderedPossibleVotes = (from v in possibleVotes
                                                                              orderby v.Second descending
                                                                              select v);
                    if (Prefs.DevMode && Prefs.LogVerbose)
                    {
                        StringBuilder voteString = new StringBuilder("Psychology :: Vote weights for " + voter.LabelShort + ": ");
                        foreach (Pair <Pawn, float> v in orderedPossibleVotes)
                        {
                            voteString.Append(v.First.LabelShort + " " + v.Second + " ");
                        }
                        Log.Message(voteString.ToString());
                    }
                    election.votes.Add(orderedPossibleVotes.First().First.LabelShort);
                }
                else
                {
                    election.votes.Add(voter.LabelShort);
                }
            }
        }
예제 #14
0
        public override void Init()
        {
            base.Init();
            //Make sure the election occurs during the day if possible.
            int plannedStart = GenDate.HourOfDay(this.Duration + Find.TickManager.TicksAbs, Find.WorldGrid.LongLatOf(this.SingleMap.Tile).x);

            if (plannedStart < 7)
            {
                this.Duration += (7 - plannedStart) * GenDate.TicksPerHour;
            }
            else if (plannedStart > 18)
            {
                this.Duration -= (plannedStart - 18) * GenDate.TicksPerHour;
            }
            IEnumerable <Pawn> psychologyColonists = (from p in this.SingleMap.mapPawns.FreeColonistsSpawned
                                                      where PsycheHelper.PsychologyEnabled(p)
                                                      select p);
            int   maxCandidatesThisColonySupports = Mathf.RoundToInt(psychologyColonists.Count() * 0.3f);
            float totalOutspoken = 0f;

            foreach (Pawn p in psychologyColonists)
            {
                totalOutspoken += PsycheHelper.Comp(p).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Outspoken);
            }
            int numCandidates = Rand.RangeInclusive(Mathf.Min(maxCandidatesThisColonySupports, 1 + Mathf.RoundToInt(totalOutspoken * 0.1f)), maxCandidatesThisColonySupports);
            int tries         = 0;

            while (this.candidates.Count < numCandidates && tries < 500)
            {
                Pawn candidate = psychologyColonists.RandomElementByWeight(p => (p.ageTracker.CurLifeStageIndex >= 3) ? PsycheHelper.Comp(p).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Outspoken) * 2 + (p.health.hediffSet.HasHediff(HediffDefOfPsychology.Mayor) ? p.needs.mood.CurLevel - 0.5f : 0f) : 0f);
                List <PersonalityNodeDef> issues = new List <PersonalityNodeDef>();
                int tries2 = 0;
                while (issues.Count < 5 && tries2 < 500)
                {
                    PersonalityNodeDef issue = (from node in PsycheHelper.Comp(candidate).Psyche.PersonalityNodes
                                                where !node.Core
                                                select node.def).RandomElementByWeight(n => Mathf.Pow(Mathf.Abs(0.5f - PsycheHelper.Comp(candidate).Psyche.GetPersonalityRating(n)), 4) * Mathf.Pow(2, n.controversiality));
                    if (!issues.Contains(issue))
                    {
                        issues.Add(issue);
                    }
                    else
                    {
                        tries2++;
                    }
                }
                if (issues.Count >= 5 && this.candidates.Find(c => c.pawn == candidate) == null)
                {
                    this.candidates.Add(new Candidate(candidate, issues));
                }
                else
                {
                    if (issues.Count < 5)
                    {
                        Log.Error("[Psychology] Could not find five unique issues for " + candidate.LabelShort + "'s platform.");
                    }
                    tries++;
                }
            }
            if (candidates.Count == 0)
            {
                this.End();
                Log.Error("[Psychology] Tried to start election but could not find anyone to run.");
                return;
            }
            foreach (Candidate candidate in candidates)
            {
                StringBuilder issuesString = new StringBuilder();
                for (int i = 0; i < candidate.nodes.Count; i++)
                {
                    issuesString.AppendFormat("{0}) {1}{2}", i + 1, PsycheHelper.Comp(candidate.pawn).Psyche.GetPersonalityNodeOfDef(candidate.nodes[i]).PlatformIssue, (i != candidate.nodes.Count - 1 ? "\n" : ""));
                }
                Find.LetterStack.ReceiveLetter("LetterLabelElectionCandidate".Translate(candidate.pawn.LabelShort), "LetterElectionCandidate".Translate(candidate.pawn.LabelShort, Find.WorldObjects.ObjectsAt(candidate.pawn.Map.Tile).OfType <SettlementBase>().First().Label, issuesString.ToString()).AdjustedFor(candidate.pawn), LetterDefOf.NeutralEvent, candidate.pawn, null);
            }
        }
예제 #15
0
 private void Finished()
 {
     if (PsycheHelper.PsychologyEnabled(mayor) && PsycheHelper.PsychologyEnabled(constituent))
     {
         if (this.ticksInSameRoom > 0)
         {
             if (this.complaint)
             {
                 ThoughtDef complaintDef = new ThoughtDef();
                 complaintDef.label        = "MayorComplaint";
                 complaintDef.durationDays = 1f + 4f * this.mayor.GetStatValue(StatDefOf.SocialImpact);
                 //Constituent thought duration affected by mayor's Social stat
                 complaintDef.thoughtClass            = typeof(Thought_MemoryDynamic);
                 complaintDef.stackedEffectMultiplier = 1f;
                 complaintDef.stackLimit = 999;
                 ThoughtStage complaintStage = new ThoughtStage();
                 float        complaintMood  = 18f * (PsycheHelper.Comp(mayor).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Empathetic) - 0.33f);
                 //Base complaint mood determined by mayor's Empathetic trait
                 complaintMood *= (float)this.ticksInSameRoom / (float)GenDate.TicksPerHour;
                 //Length of meeting also affects mood
                 complaintMood *= (complaintMood < 0f ? Mathf.Lerp(1.25f, 0.75f, PsycheHelper.Comp(constituent).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Polite)) : 1f);
                 //Negative meeting thoughts (unempathetic mayors) mitigated by mayor's politeness
                 complaintMood += (BeautyUtility.AverageBeautyPerceptible(this.constituent.Position, this.constituent.Map) / 10f);
                 //Beauty of the room has a net positive effect on the thought
                 complaintMood *= 0.75f + (PsycheHelper.Comp(constituent).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Judgmental) / 2f);
                 //Constituent's Judgmental trait changes how much the thought affects them
                 complaintStage.label          = "ComplaintLabel".Translate();
                 complaintStage.description    = "ComplaintDesc".Translate();
                 complaintStage.baseMoodEffect = Mathf.RoundToInt(complaintMood);
                 complaintDef.defName          = this.constituent.GetHashCode() + "MayorComplaint" + complaintStage.baseMoodEffect;
                 complaintDef.stages.Add(complaintStage);
                 if (complaintStage.baseMoodEffect != 0)
                 {
                     this.constituent.needs.mood.thoughts.memories.TryGainMemory(complaintDef, this.mayor);
                 }
             }
             ThoughtDef visitDef = new ThoughtDef();
             visitDef.label        = "MayorVisited";
             visitDef.durationDays = 0.75f + 2f * (1f - PsycheHelper.Comp(mayor).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Independent));
             //Mayor thought duration affected by mayor's Independent trait
             visitDef.thoughtClass            = typeof(Thought_MemoryDynamic);
             visitDef.stackedEffectMultiplier = 1f;
             visitDef.stackLimit = 999;
             ThoughtStage stage = new ThoughtStage();
             float        mood  = 7f * (complaint ? -0.5f - (1f - this.constituent.needs.mood.CurLevel) : 0.1f + (this.constituent.needs.mood.CurLevel * 0.65f));
             //Base visit mood determined by the mood level of the constituent
             mood *= (float)this.ticksInSameRoom / (float)GenDate.TicksPerHour;
             //Length of meeting also affects mood
             mood *= (mood < 0f ? Mathf.Lerp(1.25f, 0.75f, PsycheHelper.Comp(constituent).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Polite)) : 1f);
             //Negative meeting thoughts (unhappy constituents) mitigated by constituent's politeness
             mood *= 0.5f + (1f - PsycheHelper.Comp(this.mayor).Psyche.GetPersonalityRating(PersonalityNodeDefOf.LaidBack));
             //Mayor's Laid-Back trait strongly impacts how much the thought affects them
             stage.label          = "VisitLabel".Translate();
             stage.description    = "VisitDesc".Translate();
             stage.baseMoodEffect = Mathf.RoundToInt(mood);
             visitDef.defName     = this.mayor.GetHashCode() + "MayorVisited" + stage.baseMoodEffect;
             visitDef.stages.Add(stage);
             if (stage.baseMoodEffect != 0)
             {
                 this.mayor.needs.mood.thoughts.memories.TryGainMemory(visitDef, this.constituent);
             }
             InteractionDef endConversation = new InteractionDef();
             endConversation.defName = "EndConversation";
             FieldInfo     RuleStrings     = typeof(RulePack).GetField("rulesStrings", BindingFlags.Instance | BindingFlags.NonPublic);
             RulePack      goodbyeTextInit = new RulePack();
             List <string> text            = new List <string>(1);
             if (complaint)
             {
                 text.Add("r_logentry->" + "Complained".Translate());
             }
             else
             {
                 text.Add("r_logentry->" + "Supported".Translate());
             }
             RuleStrings.SetValue(goodbyeTextInit, text);
             endConversation.logRulesInitiator = goodbyeTextInit;
             FieldInfo Symbol = typeof(InteractionDef).GetField("symbol", BindingFlags.Instance | BindingFlags.NonPublic);
             Symbol.SetValue(endConversation, Symbol.GetValue(InteractionDefOfPsychology.HangOut));
             PlayLogEntry_InteractionConversation log = new PlayLogEntry_InteractionConversation(endConversation, this.constituent, this.mayor, new List <RulePackDef>());
             Find.PlayLog.Add(log);
             MoteMaker.MakeInteractionBubble(this.mayor, this.constituent, InteractionDefOf.Chitchat.interactionMote, InteractionDefOf.Chitchat.Symbol);
         }
     }
 }
예제 #16
0
 public override void Tick(int currentTick)
 {
     //Performance reporting tick
     if (EnablePerformanceTesting() && currentTick % GenDate.TicksPerDay == 0 && PerformanceSetup.performanceTotals.Keys.Count > 0)
     {
         Dictionary <string, float> averages = PerformanceSetup.performanceTotals.ToDictionary(x => x.Key, x => (float)x.Value / (float)PerformanceSetup.performanceCalls[x.Key]);
         int topAmt = Math.Min(10, averages.Count);
         List <KeyValuePair <string, float> > avgTicks = (from avg in averages orderby avg.Value descending select avg).Take(topAmt).ToList();
         List <KeyValuePair <string, float> > topTicks = (from avg in averages orderby avg.Value * PerformanceSetup.performanceCalls[avg.Key] descending select avg).Take(topAmt).ToList();
         StringBuilder avgString = new StringBuilder();
         foreach (KeyValuePair <string, float> t in avgTicks)
         {
             avgString.AppendLine(t.Key + " (" + t.Value + ")");
         }
         StringBuilder topString = new StringBuilder();
         foreach (KeyValuePair <string, float> t in topTicks)
         {
             topString.AppendLine(t.Key + " (" + avgTicks.Find(x => x.Key == t.Key).Value + ")");
         }
         Log.Message("Psychology :: Performance Report :: Top " + topAmt + " average tick consumers:\n" + avgString.ToString() + "\nTop " + topAmt + " weighted tick consumers: " + topString.ToString());
     }
     //Constituent tick
     if (currentTick % GenDate.TicksPerHour * 2 == 0)
     {
         Map playerFactionMap            = Find.WorldObjects.SettlementBases.Find(b => b.Faction.IsPlayer).Map;
         IEnumerable <Pawn> constituents = (from p in playerFactionMap.mapPawns.FreeColonistsSpawned
                                            where !p.health.hediffSet.HasHediff(HediffDefOfPsychology.Mayor) && p.GetLord() == null && p.GetTimeAssignment() != TimeAssignmentDefOf.Work && p.Awake()
                                            select p);
         if (constituents.Count() > 0)
         {
             Pawn potentialConstituent       = constituents.RandomElementByWeight(p => 0.0001f + Mathf.Pow(Mathf.Abs(0.7f - p.needs.mood.CurLevel), 2));
             IEnumerable <Pawn> activeMayors = (from m in playerFactionMap.mapPawns.FreeColonistsSpawned
                                                where !m.Dead && m.health.hediffSet.HasHediff(HediffDefOfPsychology.Mayor) && ((Hediff_Mayor)m.health.hediffSet.GetFirstHediffOfDef(HediffDefOfPsychology.Mayor)).worldTileElectedOn == potentialConstituent.Map.Tile &&
                                                m.GetTimeAssignment() != TimeAssignmentDefOf.Work && m.GetTimeAssignment() != TimeAssignmentDefOf.Sleep && m.GetLord() == null && m.Awake() && m.GetLord() == null
                                                select m);
             if (potentialConstituent != null && !potentialConstituent.Downed && !potentialConstituent.Drafted && potentialConstituent.health.summaryHealth.SummaryHealthPercent >= 1f && potentialConstituent.GetTimeAssignment() != TimeAssignmentDefOf.Work && activeMayors.Count() > 0)
             {
                 Pawn    mayor  = activeMayors.RandomElement(); //There should only be one.
                 IntVec3 gather = default(IntVec3);
                 String  found  = null;
                 if (mayor.Map.GetComponent <OfficeTableMapComponent>().officeTable != null)
                 {
                     gather = mayor.Map.GetComponent <OfficeTableMapComponent>().officeTable.parent.Position;
                     found  = "office";
                 }
                 else if (mayor.ownership != null && mayor.ownership.OwnedBed != null)
                 {
                     gather = mayor.ownership.OwnedBed.Position;
                     found  = "bed";
                 }
                 if (PsycheHelper.PsychologyEnabled(potentialConstituent) && Rand.Chance((1f - PsycheHelper.Comp(potentialConstituent).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Independent)) / 5f) && (found != null || RCellFinder.TryFindPartySpot(mayor, out gather)) &&
                     (!mayor.Drafted && !mayor.Downed && mayor.health.summaryHealth.SummaryHealthPercent >= 1f && mayor.GetTimeAssignment() != TimeAssignmentDefOf.Work && (mayor.CurJob == null || mayor.CurJob.def != JobDefOf.TendPatient)))
                 {
                     List <Pawn> pawns = new List <Pawn>();
                     pawns.Add(mayor);
                     pawns.Add(potentialConstituent);
                     Lord meeting = LordMaker.MakeNewLord(mayor.Faction, new LordJob_VisitMayor(gather, potentialConstituent, mayor, (potentialConstituent.needs.mood.CurLevel < (potentialConstituent.mindState.mentalBreaker.BreakThresholdMinor * 1.25f))), mayor.Map, pawns);
                     mayor.jobs.EndCurrentJob(Verse.AI.JobCondition.InterruptForced);
                     potentialConstituent.jobs.EndCurrentJob(Verse.AI.JobCondition.InterruptForced);
                     if (found == "bed")
                     {
                         mayor.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOfPsychology.MayorNoOffice);
                     }
                     else if (found == null)
                     {
                         mayor.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOfPsychology.MayorNoBedroom);
                     }
                 }
             }
         }
     }
     //Election tick
     if (currentTick % (GenDate.TicksPerDay / 4f) == 0)
     {
         foreach (Settlement settlement in Find.WorldObjects.Settlements)
         {
             //Self-explanatory.
             if (!PsychologyBase.ActivateElections())
             {
                 continue;
             }
             //If the base isn't owned or named by the player, no election can be held.
             if (!settlement.Faction.IsPlayer || !settlement.namedByPlayer)
             {
                 continue;
             }
             //If the base is not at least a year old, no election will be held.
             if ((Find.TickManager.TicksGame - settlement.creationGameTicks) / GenDate.TicksPerYear < 1)
             {
                 continue;
             }
             //A base must have at least 7 people in it to hold an election.
             if (settlement.Map.mapPawns.FreeColonistsSpawnedCount < 7)
             {
                 continue;
             }
             //If an election is already being held, don't start a new one.
             if (settlement.Map.gameConditionManager.ConditionIsActive(GameConditionDefOfPsychology.Election) || settlement.Map.lordManager.lords.Find(l => l.LordJob is LordJob_Joinable_Election) != null)
             {
                 continue;
             }
             //Elections are held in Septober (because I guess some maps don't have fall?) and during the day.
             if (GenDate.Quadrum(Find.TickManager.TicksAbs, Find.WorldGrid.LongLatOf(settlement.Tile).x) != Quadrum.Septober || (GenLocalDate.HourOfDay(settlement.Map) < 7 || GenLocalDate.HourOfDay(settlement.Map) > 20))
             {
                 continue;
             }
             //If an election has already been completed this year, don't start a new one.
             IEnumerable <Pawn> activeMayors = (from m in settlement.Map.mapPawns.FreeColonistsSpawned
                                                where !m.Dead && m.health.hediffSet.HasHediff(HediffDefOfPsychology.Mayor) && ((Hediff_Mayor)m.health.hediffSet.GetFirstHediffOfDef(HediffDefOfPsychology.Mayor)).worldTileElectedOn == settlement.Map.Tile && ((Hediff_Mayor)m.health.hediffSet.GetFirstHediffOfDef(HediffDefOfPsychology.Mayor)).yearElected == GenLocalDate.Year(settlement.Map.Tile)
                                                select m);
             if (activeMayors.Count() > 0)
             {
                 continue;
             }
             //Try to space out the elections so they don't all proc at once.
             if (Rand.RangeInclusive(1, 15 - GenLocalDate.DayOfQuadrum(settlement.Map.Tile)) > 1)
             {
                 continue;
             }
             IncidentParms parms = new IncidentParms();
             parms.target  = settlement.Map;
             parms.faction = settlement.Faction;
             FiringIncident fi = new FiringIncident(IncidentDefOfPsychology.Election, null, parms);
             Find.Storyteller.TryFire(fi);
         }
     }
 }
예제 #17
0
 public override void PostRemoved()
 {
     base.PostRemoved();
     if (this.pawn != null && this.otherPawn != null)
     {
         if (this.pawn.Dead || this.otherPawn.Dead || !PsycheHelper.PsychologyEnabled(pawn) || !PsycheHelper.PsychologyEnabled(otherPawn))
         {
             return;
         }
         Hediff_Conversation otherConvo = otherPawn.health.hediffSet.hediffs.Find(h => h is Hediff_Conversation && ((Hediff_Conversation)h).otherPawn == this.pawn) as Hediff_Conversation;
         if (otherConvo != null)
         {
             this.otherPawn.health.RemoveHediff(otherConvo);
             this.startedFight = otherConvo.startedFight;
         }
         string talkDesc;
         if (this.ageTicks < 500)
         {
             int numShortTalks = int.Parse("NumberOfShortTalks".Translate());
             talkDesc = "ShortTalk" + Rand.RangeInclusive(1, numShortTalks);
         }
         else if (this.ageTicks < GenDate.TicksPerHour / 2)
         {
             int numNormalTalks = int.Parse("NumberOfNormalTalks".Translate());
             talkDesc = "NormalTalk" + Rand.RangeInclusive(1, numNormalTalks);
         }
         else if (this.ageTicks < GenDate.TicksPerHour * 2.5)
         {
             int numLongTalks = int.Parse("NumberOfLongTalks".Translate());
             talkDesc = "LongTalk" + Rand.RangeInclusive(1, numLongTalks);
         }
         else
         {
             int numEpicTalks = int.Parse("NumberOfEpicTalks".Translate());
             talkDesc = "EpicTalk" + Rand.RangeInclusive(1, numEpicTalks);
         }
         float          opinionMod;
         ThoughtDef     def             = CreateSocialThought(out opinionMod);
         bool           mattered        = TryGainThought(def, Mathf.RoundToInt(opinionMod));
         InteractionDef endConversation = new InteractionDef();
         endConversation.socialFightBaseChance = 0.2f * PsycheHelper.Comp(pawn).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Aggressive) * PopulationModifier * Mathf.InverseLerp(0f, -80f, opinionMod);
         endConversation.defName = "EndConversation";
         endConversation.label   = def.label;
         List <RulePackDef> socialFightPacks = new List <RulePackDef>();
         if (otherConvo != null && (startedFight || (mattered && this.pawn.interactions.CheckSocialFightStart(endConversation, otherPawn))))
         {
             if (startedFight)
             {
                 socialFightPacks.Add(RulePackDefOfPsychology.Sentence_SocialFightConvoRecipientStarted);
             }
             else
             {
                 socialFightPacks.Add(RulePackDefOfPsychology.Sentence_SocialFightConvoInitiatorStarted);
             }
             this.startedFight = true;
             if (!this.waveGoodbye && otherConvo.convoLog != null && !otherConvo.startedFight)
             {
                 //The main conversation hediff was the other conversation, and didn't start a fight, so we have to add the extra sentence in after the fact.
                 Traverse.Create(otherConvo.convoLog).Field("extraSentencePacks").GetValue <List <RulePackDef> >().AddRange(socialFightPacks);
             }
         }
         if (this.waveGoodbye && this.pawn.Map != null)
         {
             RulePack      goodbyeText = new RulePack();
             FieldInfo     RuleStrings = typeof(RulePack).GetField("rulesStrings", BindingFlags.Instance | BindingFlags.NonPublic);
             List <string> text        = new List <string>(1);
             text.Add("r_logentry->" + talkDesc.Translate(convoTopic, pawn.Named("INITIATOR"), otherPawn.Named("RECIPIENT")));
             RuleStrings.SetValue(goodbyeText, text);
             endConversation.logRulesInitiator = goodbyeText;
             FieldInfo Symbol = typeof(InteractionDef).GetField("symbol", BindingFlags.Instance | BindingFlags.NonPublic);
             Symbol.SetValue(endConversation, Symbol.GetValue(InteractionDefOfPsychology.EndConversation));
             PlayLogEntry_InteractionConversation log = new PlayLogEntry_InteractionConversation(endConversation, pawn, this.otherPawn, socialFightPacks);
             Find.PlayLog.Add(log);
             convoLog = log;
             MoteMaker.MakeInteractionBubble(this.pawn, this.otherPawn, InteractionDefOf.Chitchat.interactionMote, InteractionDefOf.Chitchat.Symbol);
         }
     }
 }
예제 #18
0
 private bool IsInvited(Pawn p)
 {
     return(p.Faction == this.lord.faction && p.needs.mood != null && p.relations.OpinionOf(dead) > 0 && (!PsycheHelper.PsychologyEnabled(p) || Mathf.Lerp(0, 100, p.relations.OpinionOf(dead)) >= (1f - PsycheHelper.Comp(p).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Nostalgic))));
 }