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))); }
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; } }
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); }
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); } } } }
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(); }
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); }
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(); } }
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))); } }
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); } } }
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)); }
public PersonalityNode(PsychologyPawn pawn) { this.pawn = pawn; }
public Candidate(PsychologyPawn pawn, List <PersonalityNodeDef> nodes) { this.pawn = pawn; this.nodes = nodes; }
public Pawn_SexualityTracker(PsychologyPawn pawn) { this.pawn = pawn; }
public Pawn_PsycheTracker(PsychologyPawn pawn) { this.pawn = pawn; }
public Pawn_SexualityTracker(PsychologyPawn pawn) { this.pawn = pawn; GenerateSexuality(); }
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); } }