public float GetConversationTopicWeight(PersonalityNodeDef def, Pawn 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. */ IEnumerable <Thought_MemorySocialDynamic> convoMemories; float weight = 10f / (Mathf.Lerp(1f + (8 * def.controversiality), 1f + (def.controversiality / 2), Mathf.Clamp01(this.TotalThoughtOpinion(otherPawn, out convoMemories) / 75) + this.GetPersonalityRating(PersonalityNodeDefOf.Aggressive))); /* Polite pawns will avoid topics they already know are contentious. */ Pair <string, string> disagreementKey = new Pair <string, string>(otherPawn.ThingID, def.defName); if (cachedDisagreementWeights.ContainsKey(disagreementKey) && !recalcNodeDisagreement[disagreementKey]) { weight *= cachedDisagreementWeights[disagreementKey]; } else { float knownDisagreements = (from m in convoMemories where m.opinionOffset < 0f && m.CurStage.label == def.defName select Math.Abs(m.opinionOffset)).Sum(); float disagree = 1f; if (knownDisagreements > 0) { disagree = Mathf.Clamp01(1f / (knownDisagreements / 50)) * Mathf.Lerp(0.25f, 1f, this.GetPersonalityRating(PersonalityNodeDefOf.Polite)); } cachedDisagreementWeights[disagreementKey] = disagree; recalcNodeDisagreement[disagreementKey] = false; weight *= disagree; } return(weight); }
public static PersonalityNode MakeNode(PersonalityNodeDef def, Pawn pawn) { PersonalityNode node = new PersonalityNode(pawn); node.def = def; node.Initialize(); return(node); }
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 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); } }
public float GetModifier(PersonalityNodeDef def) { PersonalityNodeParent parent = parents.Find((PersonalityNodeParent p) => p.node == def); return(parent.modifier > 0 ? -1 / parent.modifier : 1 / Mathf.Abs(parent.modifier - 1)); }
public PersonalityNode GetPersonalityNodeOfDef(PersonalityNodeDef def) { return(nodeDict[def]); }
public float GetPersonalityRating(PersonalityNodeDef def) { return(GetPersonalityNodeOfDef(def).AdjustedRating); }
public float GetModifier(PersonalityNodeDef def) { PersonalityNodeParent parent = ParentNodes[def]; return(parent.modifier > 0 ? -1 / parent.modifier : 1 / Mathf.Abs(parent.modifier - 1)); }
public PersonalityNode GetPersonalityNodeOfDef(PersonalityNodeDef def) { return(nodes.Find((PersonalityNode n) => n.def == def)); }
public float GetPersonalityRating(PersonalityNodeDef def) { return(nodes.Find((PersonalityNode n) => n.def == def).AdjustedRating); }