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); }
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(); } }
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); }
public override void PostMake() { base.PostMake(); if (!PsycheHelper.PsychologyEnabled(this.pawn)) { this.pawn.health.RemoveHediff(this); } }
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(); }
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)); }
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); } } } }
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))); }
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); } } }
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); } }
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); } } }
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); } } }
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); } } }
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)))); }