public override float RandomSelectionWeight(Pawn initiator, Pawn recipient)
        {
            if (!initiator.IsColonist || !recipient.IsColonist)
            {
                return(0f);
            }
            if (!PartyUtility.AcceptableGameConditionsToStartParty(initiator.Map))
            {
                return(0f);
            }
            PsychologyPawn realRecipient = recipient as PsychologyPawn;
            PsychologyPawn realInitiator = initiator as PsychologyPawn;

            if (realRecipient == null || realInitiator == null)
            {
                return(0f);
            }
            if (!LovePartnerRelationUtility.LovePartnerRelationExists(initiator, recipient))
            {
                return(0f);
            }
            if (realInitiator.psyche.lastDateTick >= Find.TickManager.TicksGame - GenDate.TicksPerDay * 7 || realRecipient.psyche.lastDateTick >= Find.TickManager.TicksGame - GenDate.TicksPerDay * 7)
            {
                return(0f);
            }
            if (initiator.health.summaryHealth.SummaryHealthPercent < 1f || recipient.health.summaryHealth.SummaryHealthPercent < 1f)
            {
                return(0f);
            }
            return(1.2f * realInitiator.psyche.GetPersonalityRating(PersonalityNodeDefOf.Romantic) * (1f - realInitiator.psyche.GetPersonalityRating(PersonalityNodeDefOf.Independent))
                   * realRecipient.psyche.GetPersonalityRating(PersonalityNodeDefOf.Romantic) * (1f - realRecipient.psyche.GetPersonalityRating(PersonalityNodeDefOf.Independent)) * RendezvousUtility.ColonySizeFactor(initiator));
        }
        public static void DrawPsycheCard(Rect rect, Pawn pawn)
        {
            PsychologyPawn realPawn = pawn as PsychologyPawn;

            if (realPawn != null)
            {
                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, realPawn);
                }
                PsycheCardUtility.DrawPersonalityNodes(rect4, realPawn);
                PsycheCardUtility.DrawSexuality(rect5, realPawn, true);
                GUI.EndGroup();
            }
        }
 public void LearnSexuality(PsychologyPawn p)
 {
     if (p != null && !knownSexualities.Keys.Contains(p))
     {
         knownSexualities.Add(p, p.sexuality.kinseyRating);
     }
 }
        public static PersonalityNode MakeNode(PersonalityNodeDef def, PsychologyPawn pawn)
        {
            PersonalityNode node = new PersonalityNode(pawn);

            node.def = def;
            node.Initialize();
            return(node);
        }
 public static void DrawDebugOptions(Rect rect, PsychologyPawn pawn)
 {
     GUI.BeginGroup(rect);
     if (Widgets.ButtonText(new Rect((rect.width * 0.6f) - 80f, 0f, 100f, 22f), "EditPsyche".Translate(), true, false, true))
     {
         Find.WindowStack.Add(new Dialog_EditPsyche(pawn));
     }
     GUI.EndGroup();
 }
        public override float RandomSelectionWeight(Pawn initiator, Pawn recipient)
        {
            PsychologyPawn realRecipient = recipient as PsychologyPawn;
            PsychologyPawn realInitiator = initiator as PsychologyPawn;

            if (realRecipient == null || realInitiator == null)
            {
                return(0f);
            }
            return(Mathf.Max(0f, 0.45f + (realRecipient.psyche.GetPersonalityRating(PersonalityNodeDefOf.Friendly) - 0.6f) + (realInitiator.psyche.GetPersonalityRating(PersonalityNodeDefOf.Extroverted) - 0.5f)));
        }
Beispiel #7
0
        public float TotalThoughtOpinion(PsychologyPawn other)
        {
            float knownThoughtOpinion           = 1f;
            IEnumerable <Thought_Memory> convos = (from m in this.pawn.needs.mood.thoughts.memories.Memories
                                                   where m.def.defName.Contains("Conversation") && m.otherPawn.ThingID == other.ThingID
                                                   select m);

            foreach (Thought_Memory m in convos)
            {
                knownThoughtOpinion += Mathf.Abs(m.CurStage.baseOpinionOffset);
            }
            return(knownThoughtOpinion);
        }
        private static void DrawSexuality(Rect rect, PsychologyPawn pawn, bool notOnMenu)
        {
            float width = rect.width - 26f - 3f;

            GUI.color = Color.white;
            if (PsychologyBase.ActivateKinsey())
            {
                Text.Font = GameFont.Medium;
                Rect rect2 = rect;
                rect2.yMax = rect2.y + 30f;
                Widgets.Label(rect2, "Sexuality".Translate());
                Text.Font = GameFont.Small;
                Rect rect3 = rect;
                rect3.y = rect2.yMax + RowTopPadding;
                string text = "KinseyRating".Translate() + "    " + pawn.sexuality.kinseyRating;
                float  num4 = Mathf.Max(50f, Text.CalcHeight(text, width));
                rect3.yMax = rect3.y + num4;
                Widgets.Label(rect3, text);
                bool asexual = false;
                Rect rect4   = rect;
                if (pawn.sexuality.sexDrive < 0.1f)
                {
                    rect4.y = rect3.yMax;
                    string text2 = "Asexual".Translate();
                    float  num5  = Mathf.Max(26f, Text.CalcHeight(text2, width));
                    rect4.yMax = rect4.y + num5;
                    Widgets.Label(rect4, text2);
                    TooltipHandler.TipRegion(rect4, () => "AsexualDescription".Translate(), 613261 + (int)(100 * pawn.sexuality.sexDrive));
                    asexual = true;
                }
                if (pawn.sexuality.romanticDrive < 0.1f)
                {
                    Rect rect5 = rect;
                    rect5.y = (asexual ? rect4.yMax : rect3.yMax);
                    string text2 = "Aromantic".Translate();
                    float  num5  = Mathf.Max(26f, Text.CalcHeight(text2, width));
                    rect5.yMax = rect5.y + num5;
                    Widgets.Label(rect5, text2);
                    TooltipHandler.TipRegion(rect5, () => "AromanticDescription".Translate(), 613261 + (int)(100 * pawn.sexuality.romanticDrive));
                }
            }
            else if (notOnMenu)
            {
                GUI.color = Color.red;
                string text = "SexualityDisabledWarning".Translate();
                Widgets.Label(rect, text);
                GUI.color = Color.white;
            }
        }
Beispiel #9
0
 public Dialog_EditPsyche(PsychologyPawn editFor)
 {
     pawn = editFor;
     if (PsychologyBase.ActivateKinsey())
     {
         pawnKinseyRating  = pawn.sexuality.kinseyRating;
         pawnSexDrive      = pawn.sexuality.sexDrive;
         pawnRomanticDrive = pawn.sexuality.romanticDrive;
     }
     foreach (PersonalityNode node in this.pawn.psyche.PersonalityNodes)
     {
         cachedList.Add(new Pair <string, float>(node.def.label.CapitalizeFirst(), node.rawRating));
         descriptions.Add(node.def.label.CapitalizeFirst(), node.def.description);
     }
     cachedList.SortBy(n => n.First);
 }
Beispiel #10
0
 public override void MapLoaded(Map map)
 {
     if (ModIsActive && PsychologyBase.ActivateKinsey())
     {
         List <Pawn> gayPawns = (from p in map.mapPawns.AllPawns
                                 where p.RaceProps.Humanlike && p.story.traits.HasTrait(TraitDefOf.Gay)
                                 select p).ToList();
         foreach (Pawn pawn in gayPawns)
         {
             PsychologyBase.RemoveTrait(pawn, TraitDefOf.Gay);
             PsychologyPawn realPawn = pawn as PsychologyPawn;
             if (realPawn != null && realPawn.sexuality.kinseyRating < 5)
             {
                 realPawn.sexuality.kinseyRating = Rand.RangeInclusive(5, 6);
             }
         }
     }
 }
Beispiel #11
0
        public override void End()
        {
            base.End();
            if (candidates.Count == 0)
            {
                return;
            }
            IntVec3        intVec;
            PsychologyPawn organizer = candidates.RandomElement().pawn;
            string         baseName  = Find.WorldObjects.ObjectsAt(organizer.Map.Tile).OfType <FactionBase>().First().Label;

            if (!RCellFinder.TryFindPartySpot(organizer, out intVec))
            {
                return;
            }
            LordMaker.MakeNewLord(organizer.Faction, new LordJob_Joinable_Election(intVec, candidates, baseName), organizer.Map, null);
            Find.LetterStack.ReceiveLetter("LetterLabelElectionHeld".Translate(baseName), "LetterElectionHeld".Translate(baseName), LetterDefOf.Good, new TargetInfo(intVec, organizer.Map, false), null);
        }
        private static void DrawPersonalityNodes(Rect rect, PsychologyPawn pawn)
        {
            float width = rect.width - 26f - 3f;
            List <PersonalityNode> allNodes = pawn.psyche.PersonalityNodes;

            allNodes.SortBy(p => - p.AdjustedRating, p => p.def.defName);
            PsycheCardUtility.nodeStrings.Clear();
            float num = 0f;

            for (int i = 0; i < allNodes.Count; i++)
            {
                int category = Mathf.RoundToInt(6f * Mathf.InverseLerp(0.16f, 0.83f, allNodes[i].AdjustedRating));
                if (/*!allNodes[i].Core && */ category != 3)
                {
                    string text = (NodeDescriptions[category] == "" ? "" : ("Psyche" + NodeDescriptions[category]).Translate());
                    PsycheCardUtility.nodeStrings.Add(new Pair <string, int>(text, i));
                    num += Mathf.Max(26f, Text.CalcHeight(text, width));
                }
            }
            Rect viewRect = new Rect(0f, 0f, rect.width, num);

            viewRect.xMax *= 0.9f;
            Widgets.BeginScrollView(rect, ref PsycheCardUtility.nodeScrollPosition, viewRect);
            float num3 = 0f;

            for (int j = 0; j < PsycheCardUtility.nodeStrings.Count; j++)
            {
                string          first    = PsycheCardUtility.nodeStrings[j].First;
                PersonalityNode node     = allNodes[PsycheCardUtility.nodeStrings[j].Second];
                float           num4     = Mathf.Max(26f, Text.CalcHeight(first, width));
                Rect            rect2    = new Rect(10f, num3, width / 3, num4);
                Rect            rect3    = new Rect(10f + width / 3, num3, (2 * width) / 3, num4);
                int             category = Mathf.RoundToInt(6f * Mathf.InverseLerp(0.16f, 0.83f, allNodes[PsycheCardUtility.nodeStrings[j].Second].AdjustedRating));
                GUI.color = NodeColors[category];
                Widgets.Label(rect2, first.ToString());
                GUI.color = Color.white;
                Widgets.DrawHighlightIfMouseover(rect3);
                Widgets.Label(rect3, node.def.label.CapitalizeFirst());
                TooltipHandler.TipRegion(rect3, () => node.def.description, 613261 + j * 612);
                num3 += num4;
            }
            GUI.EndScrollView();
        }
Beispiel #13
0
        private bool ShouldPawnKeepVoting(Pawn p)
        {
            if (!(p is PsychologyPawn))
            {
                return(false);
            }
            PsychologyPawn realPawn           = p as PsychologyPawn;
            bool           matchingCandidates = (from c in candidates
                                                 where c.pawn == realPawn
                                                 select c).Count() > 0;

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

            return(GatheringsUtility.ShouldGuestKeepAttendingGathering(p) && (notApathetic || matchingCandidates));
        }
        public override void Interacted(Pawn initiator, Pawn recipient, List <RulePackDef> extraSentencePacks)
        {
            PsychologyPawn  realInitiator = initiator as PsychologyPawn;
            PsychologyPawn  realRecipient = recipient as PsychologyPawn;
            PersonalityNode topic         = (from node in realInitiator.psyche.PersonalityNodes
                                             where !node.Core
                                             select node).RandomElementByWeight(node => realInitiator.psyche.GetConversationTopicWeight(node.def, realRecipient));
            Hediff_Conversation initiatorHediff = (Hediff_Conversation)HediffMaker.MakeHediff(HediffDefOfPsychology.HoldingConversation, realInitiator);

            initiatorHediff.otherPawn   = realRecipient;
            initiatorHediff.topic       = topic.def;
            initiatorHediff.waveGoodbye = true;
            realInitiator.health.AddHediff(initiatorHediff);
            Hediff_Conversation recipientHediff = (Hediff_Conversation)HediffMaker.MakeHediff(HediffDefOfPsychology.HoldingConversation, realRecipient);

            recipientHediff.otherPawn   = realInitiator;
            recipientHediff.topic       = topic.def;
            recipientHediff.waveGoodbye = false;
            realRecipient.health.AddHediff(recipientHediff);
        }
Beispiel #15
0
        public float GetConversationTopicWeight(PersonalityNodeDef def, PsychologyPawn otherPawn)
        {
            /* Pawns will avoid controversial topics until they know someone better.
             * This isn't a perfect system, but the weights will be closer together the higher totalOpinionModifiers is.
             */
            float weight = 10f / (Mathf.Lerp(1f + (8 * def.controversiality), 1f + (def.controversiality / 2), Mathf.Clamp01(this.TotalThoughtOpinion(otherPawn) / 75) + this.GetPersonalityRating(PersonalityNodeDefOf.Aggressive)));
            /* Polite pawns will avoid topics they already know are contentious. */
            float knownDisagreements = 0f;
            IEnumerable <Thought_MemorySocialDynamic> allConvos = (from m in this.pawn.needs.mood.thoughts.memories.Memories.OfType <Thought_MemorySocialDynamic>()
                                                                   where m.def.defName.Contains("Conversation")
                                                                   select m);

            foreach (Thought_MemorySocialDynamic memory in allConvos)
            {
                if (memory.CurStage.label == def.defName && memory.opinionOffset < 0f)
                {
                    knownDisagreements += Mathf.Abs(memory.opinionOffset);
                }
            }
            weight *= Mathf.Clamp01(1f / (knownDisagreements / 50)) * Mathf.Lerp(0.25f, 1f, this.GetPersonalityRating(PersonalityNodeDefOf.Polite));
            return(weight);
        }
        public static void DrawPsycheMenuCard(Rect rect, Pawn pawn)
        {
            PsychologyPawn realPawn = pawn as PsychologyPawn;

            if (realPawn != null)
            {
                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, realPawn);
                PsycheCardUtility.DrawSexuality(rect5, realPawn, false);
                GUI.EndGroup();
            }
        }
Beispiel #17
0
        public override void Notify_ReachedDutyLocation(Pawn pawn)
        {
            LordJob_Joinable_Election election = pawn.GetLord().LordJob as LordJob_Joinable_Election;
            PsychologyPawn            voter    = pawn as PsychologyPawn;

            if (election != null && voter != null && !election.voters.Contains(pawn.GetHashCode()))
            {
                election.voters.Add(pawn.GetHashCode());
                if (election.candidates.Find(c => c.pawn == voter) == null)
                {
                    List <Pair <PsychologyPawn, float> > possibleVotes = new List <Pair <PsychologyPawn, float> >();
                    foreach (Candidate candidate in election.candidates)
                    {
                        float issueWeighting = 0f;
                        candidate.nodes.ForEach(p => issueWeighting += Mathf.Pow((1f - Mathf.Abs(candidate.pawn.psyche.GetPersonalityRating(p) - voter.psyche.GetPersonalityRating(p))), 2) * Mathf.Pow(10, p.controversiality));
                        possibleVotes.Add(new Pair <PsychologyPawn, float>(candidate.pawn, issueWeighting + voter.relations.OpinionOf(candidate.pawn)));
                    }
                    IEnumerable <Pair <PsychologyPawn, 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 <PsychologyPawn, 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);
                }
            }
        }
        public override void Interacted(Pawn initiator, Pawn recipient, List <RulePackDef> extraSentencePacks)
        {
            PsychologyPawn realRecipient = recipient as PsychologyPawn;
            PsychologyPawn realInitiator = initiator as PsychologyPawn;
            //Choose a time that works with their schedule, based on their personality
            Dictionary <int, float> possibleHours = new Dictionary <int, float>();

            for (int i = 0; i < GenDate.HoursPerDay; i++)
            {
                possibleHours.Add(i, 0f);
            }
            foreach (PersonalityNodeDef d in DefDatabase <PersonalityNodeDef> .AllDefsListForReading)
            {
                if (d.preferredDateHours != null)
                {
                    foreach (int h in d.preferredDateHours)
                    {
                        possibleHours[h] += (Mathf.Pow(Mathf.Abs(0.5f - realInitiator.psyche.GetPersonalityRating(d)), 2) / (1.3f - realInitiator.psyche.GetPersonalityRating(PersonalityNodeDefOf.Aggressive)) + Mathf.Pow(Mathf.Abs(0.5f - realRecipient.psyche.GetPersonalityRating(d)), 2) / (1.3f - realRecipient.psyche.GetPersonalityRating(PersonalityNodeDefOf.Aggressive)) / 2f);
                    }
                }
            }
            int hour = possibleHours.Keys.RandomElementByWeight(h => possibleHours[h] * RendezvousUtility.TimeAssignmentFactor(initiator, h) * RendezvousUtility.TimeAssignmentFactor(recipient, h));
            //More Spontaneous couples will plan their dates sooner; possibly even immediately!
            int day = Find.TickManager.TicksGame + Mathf.RoundToInt(GenDate.TicksPerDay * 5 * (((1f - realInitiator.psyche.GetPersonalityRating(PersonalityNodeDefOf.Spontaneous)) + (1f - realRecipient.psyche.GetPersonalityRating(PersonalityNodeDefOf.Spontaneous))) / 2f));
            Hediff_PlannedDate plannedDate = HediffMaker.MakeHediff(HediffDefOfPsychology.PlannedDate, initiator) as Hediff_PlannedDate;

            plannedDate.partner = recipient;
            plannedDate.day     = day;
            plannedDate.hour    = hour;
            initiator.health.AddHediff(plannedDate);
            realInitiator.psyche.lastDateTick = day;
            realRecipient.psyche.lastDateTick = day;
            if (Prefs.DevMode && Prefs.LogVerbose)
            {
                Log.Message(initiator.LabelShort + " planned date with " + recipient.LabelShort + " for hour " + hour + " on date " + GenDate.DateFullStringAt(GenDate.TickGameToAbs(day), Find.WorldGrid.LongLatOf(initiator.Map.Tile)));
            }
        }
Beispiel #19
0
 public override void Tick(int currentTick)
 {
     //Constituent tick
     if (currentTick % GenDate.TicksPerHour * 2 == 0)
     {
         Map playerFactionMap            = Find.WorldObjects.FactionBases.Find(b => b.Faction.IsPlayer).Map;
         IEnumerable <Pawn> constituents = (from p in playerFactionMap.mapPawns.FreeColonistsSpawned
                                            where !p.health.hediffSet.HasHediff(HediffDefOfPsychology.Mayor) && 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()
                                                select m);
             if (potentialConstituent != null && activeMayors.Count() > 0)
             {
                 Pawn           mayor = activeMayors.RandomElement(); //There should only be one.
                 PsychologyPawn psychologyConstituent = potentialConstituent as PsychologyPawn;
                 IntVec3        gather   = default(IntVec3);
                 bool           foundBed = false;
                 if (mayor.ownership != null && mayor.ownership.OwnedBed != null)
                 {
                     gather   = mayor.ownership.OwnedBed.Position;
                     foundBed = true;
                 }
                 if ((psychologyConstituent == null || Rand.Value < (1f - psychologyConstituent.psyche.GetPersonalityRating(PersonalityNodeDefOf.Independent)) / 5f) && (foundBed || RCellFinder.TryFindPartySpot(mayor, out gather)))
                 {
                     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 < 0.4f)), mayor.Map, pawns);
                     if (!foundBed)
                     {
                         mayor.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOfPsychology.MayorNoBedroom);
                     }
                 }
             }
         }
     }
     //Election tick
     if (currentTick % (GenDate.TicksPerDay / 4f) == 0)
     {
         foreach (FactionBase factionBase in Find.WorldObjects.FactionBases)
         {
             //If the base isn't owned or named by the player, no election can be held.
             if (!factionBase.Faction.IsPlayer || !factionBase.namedByPlayer)
             {
                 continue;
             }
             //Self-explanatory.
             if (!PsychologyBase.ActivateElections())
             {
                 continue;
             }
             //If the base is not at least a year old, no election will be held.
             if ((Find.TickManager.TicksGame - factionBase.creationGameTicks) / GenDate.TicksPerYear < 1)
             {
                 continue;
             }
             //A base must have at least 7 people in it to hold an election.
             if (factionBase.Map.mapPawns.FreeColonistsSpawnedCount < 7)
             {
                 continue;
             }
             //If an election is already being held, don't start a new one.
             if (factionBase.Map.gameConditionManager.ConditionIsActive(GameConditionDefOfPsychology.Election) || factionBase.Map.lordManager.lords.Find(l => l.LordJob is LordJob_Joinable_Election) != null)
             {
                 continue;
             }
             //Elections are held in the fall and during the day.
             if (GenLocalDate.Season(factionBase.Map) != Season.Fall || (GenLocalDate.HourOfDay(factionBase.Map) < 7 || GenLocalDate.HourOfDay(factionBase.Map) > 20))
             {
                 continue;
             }
             //If an election has already been completed this year, don't start a new one.
             IEnumerable <Pawn> activeMayors = (from m in factionBase.Map.mapPawns.FreeColonistsSpawned
                                                where !m.Dead && m.health.hediffSet.HasHediff(HediffDefOfPsychology.Mayor) && ((Hediff_Mayor)m.health.hediffSet.GetFirstHediffOfDef(HediffDefOfPsychology.Mayor)).worldTileElectedOn == factionBase.Map.Tile && ((Hediff_Mayor)m.health.hediffSet.GetFirstHediffOfDef(HediffDefOfPsychology.Mayor)).yearElected == GenLocalDate.Year(factionBase.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.DayOfSeason(factionBase.Map.Tile)) > 1)
             {
                 continue;
             }
             IncidentParms parms = new IncidentParms();
             parms.target  = factionBase.Map;
             parms.faction = factionBase.Faction;
             FiringIncident fi = new FiringIncident(IncidentDefOfPsychology.Election, null, parms);
             Find.Storyteller.TryFire(fi);
         }
     }
 }
        internal static float _LovePartnerRelationGenerationChance(Pawn generated, Pawn other, PawnGenerationRequest request, bool ex)
        {
            if (generated.ageTracker.AgeBiologicalYearsFloat < 14f)
            {
                return(0f);
            }
            if (other.ageTracker.AgeBiologicalYearsFloat < 14f)
            {
                return(0f);
            }
            if (!PsychologyBase.ActivateKinsey())
            {
                if (generated.gender == other.gender && (!other.story.traits.HasTrait(TraitDefOf.Gay) || !request.AllowGay))
                {
                    return(0f);
                }
                if (generated.gender != other.gender && other.story.traits.HasTrait(TraitDefOf.Gay))
                {
                    return(0f);
                }
            }
            else if (generated.gender == other.gender && !request.AllowGay)
            {
                return(0f);
            }
            float num = 1f;

            if (ex)
            {
                int num2 = 0;
                List <DirectPawnRelation> directRelations = other.relations.DirectRelations;
                for (int i = 0; i < directRelations.Count; i++)
                {
                    if (LovePartnerRelationUtility.IsExLovePartnerRelation(directRelations[i].def))
                    {
                        num2++;
                    }
                }
                num = Mathf.Pow(0.2f, (float)num2);
            }
            else if (LovePartnerRelationUtility.HasAnyLovePartner(other))
            {
                return(0f);
            }
            float          num3          = 1f;
            PsychologyPawn realGenerated = generated as PsychologyPawn;
            PsychologyPawn realOther     = other as PsychologyPawn;

            if (PsychologyBase.ActivateKinsey() && realGenerated != null && realOther != null)
            {
                float kinsey  = 3 - realGenerated.sexuality.kinseyRating;
                float kinsey2 = 3 - realOther.sexuality.kinseyRating;
                float h**o    = (generated.gender == other.gender) ? 1f : -1f;
                num3 *= Mathf.InverseLerp(3f, 0f, kinsey * h**o);
                num3 *= Mathf.InverseLerp(3f, 0f, kinsey2 * h**o);
            }
            else
            {
                num3 = (generated.gender != other.gender) ? 1f : 0.01f;
            }
            var   GetGenerationChanceAgeFactor    = typeof(LovePartnerRelationUtility).GetMethod("GetGenerationChanceAgeFactor", BindingFlags.Static | BindingFlags.NonPublic);
            var   GetGenerationChanceAgeGapFactor = typeof(LovePartnerRelationUtility).GetMethod("GetGenerationChanceAgeGapFactor", BindingFlags.Static | BindingFlags.NonPublic);
            float generationChanceAgeFactor       = (float)GetGenerationChanceAgeFactor.Invoke(null, new object[] { generated });
            float generationChanceAgeFactor2      = (float)GetGenerationChanceAgeFactor.Invoke(null, new object[] { other });
            float generationChanceAgeGapFactor    = (float)GetGenerationChanceAgeGapFactor.Invoke(null, new object[] { generated, other, ex });
            float num4 = 1f;

            if (generated.GetRelations(other).Any((PawnRelationDef x) => x.familyByBloodRelation))
            {
                num4 = 0.01f;
            }
            float num5;

            if (request.FixedMelanin.HasValue)
            {
                num5 = ChildRelationUtility.GetMelaninSimilarityFactor(request.FixedMelanin.Value, other.story.melanin);
            }
            else
            {
                num5 = PawnSkinColors.GetMelaninCommonalityFactor(other.story.melanin);
            }
            return(num * generationChanceAgeFactor * generationChanceAgeFactor2 * generationChanceAgeGapFactor * num3 * num5 * num4);
        }
        private void Finished()
        {
            PsychologyPawn realMayor       = mayor as PsychologyPawn;
            PsychologyPawn realConstituent = constituent as PsychologyPawn;

            if (realMayor != null & realConstituent != null)
            {
                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;
                        ThoughtStage complaintStage = new ThoughtStage();
                        float        complaintMood  = 12f * (realMayor.psyche.GetPersonalityRating(PersonalityNodeDefOf.Empathetic) - 0.33f);
                        //Base complaint mood determined by mayor's Empathetic trait
                        complaintMood *= this.ticksInSameRoom / GenDate.TicksPerHour;
                        //Length of meeting also affects mood
                        complaintMood *= (complaintMood < 0f ? Mathf.Lerp(1.25f, 0.75f, realConstituent.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 + (realConstituent.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);
                        this.constituent.needs.mood.thoughts.memories.TryGainMemory(complaintDef, this.mayor);
                    }
                    ThoughtDef visitDef = new ThoughtDef();
                    visitDef.label        = "MayorVisited";
                    visitDef.durationDays = 0.75f + 2f * (1f - realMayor.psyche.GetPersonalityRating(PersonalityNodeDefOf.Independent));
                    //Mayor thought duration affected by mayor's Independent trait
                    visitDef.thoughtClass            = typeof(Thought_MemoryDynamic);
                    visitDef.stackedEffectMultiplier = 1f;
                    ThoughtStage stage = new ThoughtStage();
                    float        mood  = 5f * (complaint ? -1f - (1f - this.constituent.needs.mood.CurLevel) : 0.25f + Mathf.Max(0f, 0.25f - this.constituent.needs.mood.CurLevel));
                    //Base visit mood determined by the mood level of the constituent
                    mood *= this.ticksInSameRoom / GenDate.TicksPerHour;
                    //Length of meeting also affects mood
                    mood *= (mood < 0f ? Mathf.Lerp(1.25f, 0.75f, realConstituent.psyche.GetPersonalityRating(PersonalityNodeDefOf.Polite)) : 1f);
                    //Negative meeting thoughts (unhappy constituents) mitigated by constituent's politeness
                    mood *= 0.5f + (1f - realConstituent.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);
                    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("logentry->" + "Complained".Translate());
                    }
                    else
                    {
                        text.Add("logentry->" + "Supported".Translate());
                    }
                    RuleStrings.SetValue(goodbyeTextInit, text);
                    RulePack      goodbyeTextRecip = new RulePack();
                    List <String> text2            = new List <string>(1);
                    text2.Add("logentry->" + "HadMeeting".Translate() + ", [other_nameShortIndef].");
                    RuleStrings.SetValue(goodbyeTextRecip, text2);
                    endConversation.logRulesInitiator = goodbyeTextInit;
                    endConversation.logRulesRecipient = goodbyeTextRecip;
                    FieldInfo Symbol = typeof(InteractionDef).GetField("symbol", BindingFlags.Instance | BindingFlags.NonPublic);
                    Symbol.SetValue(endConversation, Symbol.GetValue(InteractionDefOf.DeepTalk));
                    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);
                }
            }
        }
Beispiel #22
0
        public override float RandomSelectionWeight(Pawn initiator, Pawn recipient)
        {
            if (initiator.guest.IsPrisoner || recipient.guest.IsPrisoner)
            {
                return(0f);
            }
            PsychologyPawn realRecipient = recipient as PsychologyPawn;
            PsychologyPawn realInitiator = initiator as PsychologyPawn;

            if (realRecipient == null || realInitiator == null)
            {
                return(0f);
            }
            if (initiator.GetLord() != null || recipient.GetLord() != null)
            {
                return(0f);
            }
            if (initiator.Drafted || recipient.Drafted)
            {
                return(0f);
            }
            if (!PartyUtility.AcceptableGameConditionsToStartParty(initiator.Map))
            {
                return(0f);
            }
            if (initiator.health.summaryHealth.SummaryHealthPercent < 1f || recipient.health.summaryHealth.SummaryHealthPercent < 1f)
            {
                return(0f);
            }
            if (initiator.Faction != recipient.Faction)
            {
                return(0f);
            }
            float initiatorFactor = 0f;
            float recipientFactor = 0f;

            if (initiator.relations.OpinionOf(recipient) > -20)
            {
                initiatorFactor = realInitiator.psyche.GetPersonalityRating(PersonalityNodeDefOf.Extroverted) + 0.15f + Mathf.InverseLerp(0f, 100f, initiator.relations.OpinionOf(recipient));
                recipientFactor = realRecipient.psyche.GetPersonalityRating(PersonalityNodeDefOf.Friendly);
            }
            else if (initiator.relations.OpinionOf(recipient) <= -20)
            {
                initiatorFactor = Mathf.InverseLerp(0f, 0.4f, realInitiator.psyche.GetPersonalityRating(PersonalityNodeDefOf.Empathetic) - 0.6f);
                recipientFactor = realRecipient.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));
        }
Beispiel #23
0
 public PersonalityNode(PsychologyPawn pawn)
 {
     this.pawn = pawn;
 }
Beispiel #24
0
 public Candidate(PsychologyPawn pawn, List <PersonalityNodeDef> nodes)
 {
     this.pawn  = pawn;
     this.nodes = nodes;
 }
 public Pawn_SexualityTracker(PsychologyPawn pawn)
 {
     this.pawn = pawn;
 }
Beispiel #26
0
 public Pawn_PsycheTracker(PsychologyPawn pawn)
 {
     this.pawn = pawn;
 }
 public Pawn_SexualityTracker(PsychologyPawn pawn)
 {
     this.pawn = pawn;
     GenerateSexuality();
 }
Beispiel #28
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.Map.Tile).x);

            if (plannedStart < 7)
            {
                this.duration += (7 - plannedStart) * GenDate.TicksPerHour;
            }
            else if (plannedStart > 18)
            {
                this.duration -= (plannedStart - 18) * GenDate.TicksPerHour;
            }
            IEnumerable <PsychologyPawn> psychologyColonists = this.Map.mapPawns.FreeColonistsSpawned.OfType <PsychologyPawn>();
            int   maxCandidatesThisColonySupports            = Mathf.RoundToInt(psychologyColonists.Count() * 0.3f);
            float totalOutspoken = 0f;

            foreach (PsychologyPawn p in psychologyColonists)
            {
                totalOutspoken += 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)
            {
                PsychologyPawn            candidate = psychologyColonists.RandomElementByWeight(p => p.psyche.GetPersonalityRating(PersonalityNodeDefOf.Outspoken) * 2 + (p.health.hediffSet.HasHediff(HediffDefOfPsychology.Mayor) ? p.needs.mood.CurLevel - 0.5f : 0f));
                List <PersonalityNodeDef> issues    = new List <PersonalityNodeDef>();
                int tries2 = 0;
                while (issues.Count < 5 && tries2 < 500)
                {
                    PersonalityNodeDef issue = (from node in candidate.psyche.PersonalityNodes
                                                where !node.Core
                                                select node.def).RandomElementByWeight(n => Mathf.Pow(Mathf.Abs(0.5f - candidate.psyche.GetPersonalityRating(n)), 2) * 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, 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 <FactionBase>().First().Label, issuesString.ToString()).AdjustedFor(candidate.pawn), LetterDefOf.Good, candidate.pawn, null);
            }
        }