public static Boolean HasMood(Pawn pawn, ThoughtDef Tdef) { if (pawn.needs.mood.thoughts.DistinctThoughtDefs.Contains(Tdef)) { return true; } else { return false; } }
public static bool NewInteracted(InteractionWorker_MarriageProposal __instance, Pawn initiator, Pawn recipient, List <RulePackDef> extraSentencePacks) { //TODO: Turn this into a transpihahaha no. float num = __instance.AcceptanceChance(initiator, recipient); bool flag = Rand.Value < num; bool brokeUp = false; if (flag) { initiator.relations.RemoveDirectRelation(PawnRelationDefOf.Lover, recipient); initiator.relations.AddDirectRelation(PawnRelationDefOf.Fiance, recipient); initiator.needs.mood.thoughts.memories.RemoveMemoriesOfDefWhereOtherPawnIs(ThoughtDefOf.RejectedMyProposal, recipient); recipient.needs.mood.thoughts.memories.RemoveMemoriesOfDefWhereOtherPawnIs(ThoughtDefOf.RejectedMyProposal, initiator); /* Remove custom Psychology rejection thoughts */ foreach (ThoughtDef d in (from tgt in initiator.needs.mood.thoughts.memories.Memories where tgt.def.defName.Contains("RejectedMyProposal") select tgt.def)) { initiator.needs.mood.thoughts.memories.RemoveMemoriesOfDefWhereOtherPawnIs(d, recipient); } foreach (ThoughtDef d in (from tgt in recipient.needs.mood.thoughts.memories.Memories where tgt.def.defName.Contains("RejectedMyProposal") select tgt.def)) { recipient.needs.mood.thoughts.memories.RemoveMemoriesOfDefWhereOtherPawnIs(d, initiator); } initiator.needs.mood.thoughts.memories.RemoveMemoriesOfDefWhereOtherPawnIs(ThoughtDefOf.IRejectedTheirProposal, recipient); recipient.needs.mood.thoughts.memories.RemoveMemoriesOfDefWhereOtherPawnIs(ThoughtDefOf.IRejectedTheirProposal, initiator); extraSentencePacks.Add(RulePackDefOf.Sentence_MarriageProposalAccepted); } else { PsychologyPawn realInitiator = initiator as PsychologyPawn; PsychologyPawn realRecipient = recipient as PsychologyPawn; if (realInitiator != null) { ThoughtDef rejectedProposalDef = new ThoughtDef(); rejectedProposalDef.defName = "RejectedMyProposal" + realInitiator.LabelShort + Find.TickManager.TicksGame; rejectedProposalDef.durationDays = 40f; rejectedProposalDef.thoughtClass = typeof(Thought_MemorySocialDynamic); ThoughtStage rejectedProposalStage = new ThoughtStage(); rejectedProposalStage.label = "rejected my proposal"; rejectedProposalStage.baseOpinionOffset = Mathf.RoundToInt(-30f * realInitiator.psyche.GetPersonalityRating(PersonalityNodeDefOf.Romantic) * Mathf.InverseLerp(100f, 5f, realInitiator.relations.OpinionOf(realRecipient))); rejectedProposalDef.stages.Add(rejectedProposalStage); ThoughtDef rejectedProposalMoodDef = new ThoughtDef(); rejectedProposalMoodDef.defName = "RejectedMyProposalMood" + realInitiator.LabelShort + Find.TickManager.TicksGame; rejectedProposalMoodDef.durationDays = 25f; rejectedProposalMoodDef.thoughtClass = typeof(Thought_MemoryDynamic); rejectedProposalMoodDef.stackedEffectMultiplier = 1f; ThoughtStage rejectedProposalMoodStage = new ThoughtStage(); rejectedProposalMoodStage.label = "proposal rejected by {0}"; rejectedProposalMoodStage.baseMoodEffect = Mathf.RoundToInt(-25f * realInitiator.psyche.GetPersonalityRating(PersonalityNodeDefOf.Romantic) * Mathf.InverseLerp(100f, 5f, realInitiator.relations.OpinionOf(realRecipient))); if (rejectedProposalMoodStage.baseMoodEffect < -5f) { rejectedProposalMoodStage.description = "My lover isn't ready for that kind of commitment right now, and I understand, but rejection is hard to take."; } else { rejectedProposalMoodStage.description = "I can't believe I got turned down. Maybe we're not meant to be together after all?"; } rejectedProposalMoodDef.stages.Add(rejectedProposalMoodStage); if (rejectedProposalMoodStage.baseMoodEffect > 0) { realInitiator.needs.mood.thoughts.memories.TryGainMemory(rejectedProposalMoodDef, realRecipient); } realInitiator.needs.mood.thoughts.memories.TryGainMemory(rejectedProposalDef, realRecipient); } else { initiator.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOf.RejectedMyProposal, recipient); } recipient.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOf.IRejectedTheirProposal, initiator); extraSentencePacks.Add(RulePackDefOf.Sentence_MarriageProposalRejected); if (realRecipient != null && !recipient.story.traits.HasTrait(TraitDefOfPsychology.Codependent) && Rand.Value > 2f * realRecipient.psyche.GetPersonalityRating(PersonalityNodeDefOf.Romantic)) { recipient.interactions.TryInteractWith(initiator, DefDatabase <InteractionDef> .GetNamed("Breakup")); } else if (realRecipient == null && !recipient.story.traits.HasTrait(TraitDefOfPsychology.Codependent) && Rand.Value < 0.4f) { initiator.relations.RemoveDirectRelation(PawnRelationDefOf.Lover, recipient); initiator.relations.AddDirectRelation(PawnRelationDefOf.ExLover, recipient); brokeUp = true; extraSentencePacks.Add(RulePackDefOf.Sentence_MarriageProposalRejectedBrokeUp); } } if (initiator.IsColonist || recipient.IsColonist) { Traverse.Create(__instance).Method("SendLetter", new[] { typeof(Pawn), typeof(Pawn), typeof(bool), typeof(bool) }).GetValue(new object[] { initiator, recipient, flag, brokeUp }); } return(false); }
protected override IEnumerable <Toil> MakeNewToils() { this.FailOnDespawnedOrNull(TargetPawnIndex); this.FailOnDespawnedNullOrForbidden(TargetBedIndex); this.FailOn(() => W***e is null || !xxx.CanUse(W***e, TargetBed)); //|| !W***e.CanReserve(TargetPawn) this.FailOn(() => pawn.Drafted); yield return(Toils_Goto.GotoThing(TargetPawnIndex, PathEndMode.Touch)); Toil TryItOn = new Toil(); TryItOn.AddFailCondition(() => !xxx.IsTargetPawnOkay(TargetPawn)); TryItOn.defaultCompleteMode = ToilCompleteMode.Delay; TryItOn.initAction = delegate { //Log.Message("[RJW]JobDriver_InvitingVisitors::MakeNewToils - TryItOn - initAction is called"); W***e.jobs.curDriver.ticksLeftThisToil = 50; MoteMaker.ThrowMetaIcon(W***e.Position, W***e.Map, ThingDefOf.Mote_Heart); }; yield return(TryItOn); Toil AwaitResponse = new Toil(); AwaitResponse.AddFailCondition(() => !successfulPass); AwaitResponse.defaultCompleteMode = ToilCompleteMode.Instant; AwaitResponse.initAction = delegate { List <RulePackDef> extraSentencePacks = new List <RulePackDef>(); successfulPass = DoesTargetPawnAcceptAdvance(); //Log.Message("[RJW]JobDriver_InvitingVisitors::MakeNewToils - AwaitResponse - initAction is called"); if (successfulPass) { MoteMaker.ThrowMetaIcon(TargetPawn.Position, TargetPawn.Map, ThingDefOf.Mote_Heart); TargetPawn.jobs.EndCurrentJob(JobCondition.Incompletable); if (xxx.RomanceDiversifiedIsActive) { extraSentencePacks.Add(RulePackDef.Named("HookupSucceeded")); } if (W***e.health.HasHediffsNeedingTend()) { successfulPass = false; const string key = "RJW_VisitorSickWhore"; string text = key.Translate(TargetPawn.LabelIndefinite(), W***e.LabelIndefinite()).CapitalizeFirst(); Messages.Message(text, W***e, MessageTypeDefOf.TaskCompletion); } else { const string key = "RJW_VisitorAcceptWhore"; string text = key.Translate(TargetPawn.LabelIndefinite(), W***e.LabelIndefinite()).CapitalizeFirst(); Messages.Message(text, TargetPawn, MessageTypeDefOf.TaskCompletion); } } if (!successfulPass) { MoteMaker.ThrowMetaIcon(TargetPawn.Position, TargetPawn.Map, ThingDefOf.Mote_IncapIcon); TargetPawn.needs.mood.thoughts.memories.TryGainMemory( TargetPawn.Faction == W***e.Faction ? ThoughtDef.Named("RJWTurnedDownWhore") : ThoughtDef.Named("RJWFailedSolicitation"), W***e); if (xxx.RomanceDiversifiedIsActive) { W***e.needs.mood.thoughts.memories.TryGainMemory(ThoughtDef.Named("RebuffedMyHookupAttempt"), TargetPawn); TargetPawn.needs.mood.thoughts.memories.TryGainMemory(ThoughtDef.Named("FailedHookupAttemptOnMe"), W***e); extraSentencePacks.Add(RulePackDef.Named("HookupFailed")); } //Disabled rejection notifications //Messages.Message("RJW_VisitorRejectWhore".Translate(new object[] { xxx.get_pawnname(TargetPawn), xxx.get_pawnname(W***e) }), TargetPawn, MessageTypeDefOf.SilentInput); } if (xxx.RomanceDiversifiedIsActive) { Find.PlayLog.Add(new PlayLogEntry_Interaction(DefDatabase <InteractionDef> .GetNamed("TriedHookupWith"), pawn, TargetPawn, extraSentencePacks)); } }; yield return(AwaitResponse); Toil BothGoToBed = new Toil(); BothGoToBed.AddFailCondition(() => !successfulPass || !xxx.CanUse(W***e, TargetBed)); BothGoToBed.defaultCompleteMode = ToilCompleteMode.Instant; BothGoToBed.initAction = delegate { //Log.Message("[RJW]JobDriver_InvitingVisitors::MakeNewToils - BothGoToBed - initAction is called0"); if (!successfulPass) { return; } if (!xxx.CanUse(W***e, TargetBed) && W***e.CanReserve(TargetPawn, 1, 0)) { //Log.Message("[RJW]JobDriver_InvitingVisitors::MakeNewToils - BothGoToBed - cannot use the w***e bed"); return; } //Log.Message("[RJW]JobDriver_InvitingVisitors::MakeNewToils - BothGoToBed - initAction is called1"); W***e.jobs.jobQueue.EnqueueFirst(JobMaker.MakeJob(xxx.whore_is_serving_visitors, TargetPawn, TargetBed)); //TargetPawn.jobs.jobQueue.EnqueueFirst(JobMaker.MakeJob(DefDatabase<JobDef>.GetNamed("WhoreIsServingVisitors"), W***e, TargetBed, (TargetBed.MaxAssignedPawnsCount>1)?TargetBed.GetSleepingSlotPos(1): TargetBed.)), null); W***e.jobs.curDriver.EndJobWith(JobCondition.InterruptOptional); //TargetPawn.jobs.curDriver.EndJobWith(JobCondition.InterruptOptional); }; yield return(BothGoToBed); }
private bool DrawThoughtGroup(Rect rect, ThoughtDef def) { float num = 12f; float num2 = 4f; float num3 = rect.width - num - num2 - ITab_Pawn_Needs_Alternate.ThoughtValueWidth - 16f; float num4 = num + num3; try { List <Thought> list = base.SelPawn.needs.mood.thoughts.ThoughtsOfDef(def).ToList <Thought>(); int index = 0; int num5 = -1; for (int i = 0; i < list.Count; i++) { if (list[i].CurStageIndex > num5) { num5 = list[i].CurStageIndex; index = i; } } if (!list[index].Visible) { return(false); } if (Mouse.IsOver(rect)) { Widgets.DrawHighlight(rect); } if (def.DurationTicks > 5) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(list[index].Description); stringBuilder.AppendLine(); stringBuilder.AppendLine(); Thought_Memory thought_Memory = list[index] as Thought_Memory; if (thought_Memory != null) { if (list.Count == 1) { stringBuilder.Append("ThoughtExpiresIn".Translate(new object[] { (def.DurationTicks - thought_Memory.age).TickstoDaysString() })); } else { Thought_Memory thought_Memory2 = (Thought_Memory)list[list.Count - 1]; stringBuilder.Append("ThoughtStartsExpiringIn".Translate(new object[] { (def.DurationTicks - thought_Memory.age).TickstoDaysString() })); stringBuilder.AppendLine(); stringBuilder.Append("ThoughtFinishesExpiringIn".Translate(new object[] { (def.DurationTicks - thought_Memory2.age).TickstoDaysString() })); } } TooltipHandler.TipRegion(rect, new TipSignal(stringBuilder.ToString(), 7291)); } else { TooltipHandler.TipRegion(rect, new TipSignal(list[index].Description, 7141)); } Text.WordWrap = false; Text.Anchor = TextAnchor.MiddleLeft; Rect rect2 = new Rect(rect.x + num, rect.y, num3, rect.height); rect2.yMin -= 3f; rect2.yMax += 3f; string text = list[index].LabelCap; if (list.Count > 1) { text = text + " x" + list.Count; } Widgets.Label(rect2, text); Text.Anchor = TextAnchor.MiddleCenter; float num6 = base.SelPawn.needs.mood.thoughts.MoodOffsetOfThoughtGroup(def); if (num6 == 0f) { GUI.color = ITab_Pawn_Needs_Alternate.NoEffectColor; } else if (num6 > 0f) { GUI.color = ITab_Pawn_Needs_Alternate.MoodColor; } else { GUI.color = ITab_Pawn_Needs_Alternate.MoodColorNegative; } Rect rect3 = new Rect(rect.x + num4, rect.y, ITab_Pawn_Needs_Alternate.ThoughtValueWidth, rect.height); Text.Anchor = TextAnchor.MiddleRight; Widgets.Label(rect3, num6.ToString("##0")); Text.Anchor = TextAnchor.UpperLeft; GUI.color = Color.white; Text.WordWrap = true; } catch (Exception ex) { Log.ErrorOnce(string.Concat(new object[] { "Exception in DrawThoughtGroup for ", def, " on ", base.SelPawn, ": ", ex.ToString() }), 3452698); } return(true); }
private void AddNuzzledThought(Pawn initiator, Pawn recipient) { Thought_Memory newThought = (Thought_Memory)ThoughtMaker.MakeThought(ThoughtDef.Named("AA_BeenPsionicallyNuzzled")); recipient.needs.mood.thoughts.memories.TryGainMemory(newThought, null); }
private void Produce(int amount, float chance, ThingDef resource, ThingDef rareResource, ThoughtDef stageThought) { MemoryThoughtHandler thoughts = Pawn.needs?.mood?.thoughts?.memories; EtherState etherState = Pawn.GetEtherState(); HatchingTicker = 0; var thingCount = 0; var rareThingCount = 0; Aspect infusedAspect = Pawn.GetAspectTracker()?.GetAspect(AspectDefOf.MutagenInfused); int?sIndex = infusedAspect?.StageIndex; for (var i = 0; i < amount; i++) { bool shouldProduceRare; switch (sIndex) { case null: shouldProduceRare = Rand.RangeInclusive(0, 100) <= chance; break; case 0: shouldProduceRare = true; break; case 1: shouldProduceRare = false; break; case 2: return; //produce nothing default: throw new ArgumentOutOfRangeException(sIndex.Value.ToString()); } if (shouldProduceRare && rareResource != null) { rareThingCount++; } else { thingCount++; } } Thing thing = ThingMaker.MakeThing(resource); thing.stackCount = thingCount; Color?skinColor = Pawn.GetHighestInfluence()?.GetSkinColorOverride(Pawn); //dont want wool thats mostly human-skin colored if (resource.thingCategories.Contains(PMThingCategoryDefOf.Textiles) && resource.CompDefFor <CompColorable>() != null && skinColor.HasValue) { thing.SetColor(skinColor.Value); } if (thing.stackCount > 0) { GenPlace.TryPlaceThing(thing, Pawn.PositionHeld, Pawn.Map, ThingPlaceMode.Near); } if (rareResource != null) { Thing rareThing = ThingMaker.MakeThing(rareResource); rareThing.stackCount = rareThingCount; if (rareResource.thingCategories.Contains(PMThingCategoryDefOf.Textiles) && resource.CompDefFor <CompColorable>() != null && skinColor.HasValue) { thing.SetColor(skinColor.Value); } if (rareThing.stackCount > 0) { GenPlace.TryPlaceThing(rareThing, Pawn.PositionHeld, Pawn.Map, ThingPlaceMode.Near); } } if (etherState == EtherState.None) { if (Rand.RangeInclusive(0, 100) <= bondChance) { GiveEtherState(EtherState.Bond); etherState = EtherState.Bond; Find.LetterStack.ReceiveLetter( "LetterHediffFromEtherBondLabel".Translate(Pawn).CapitalizeFirst(), "LetterHediffFromEtherBond".Translate(Pawn).CapitalizeFirst(), LetterDefOf.NeutralEvent, Pawn); } else if (Rand.RangeInclusive(0, 100) <= brokenChance) { GiveEtherState(EtherState.Broken); etherState = EtherState.Broken; Find.LetterStack.ReceiveLetter( "LetterHediffFromEtherBrokenLabel".Translate(Pawn).CapitalizeFirst(), "LetterHediffFromEtherBroken".Translate(Pawn).CapitalizeFirst(), LetterDefOf.NeutralEvent, Pawn); } } if (stageThought != null) { thoughts?.TryGainMemory(stageThought); } ThoughtDef addThought; switch (etherState) { case EtherState.None: addThought = Props.genderAversion == Pawn.gender ? Props.wrongGenderThought ?? Props.thought : Props.thought; break; case EtherState.Broken: addThought = Props.etherBrokenThought; break; case EtherState.Bond: addThought = Props.etherBondThought; break; default: throw new ArgumentOutOfRangeException(); } if (addThought != null) { thoughts?.TryGainMemory(addThought); } if (etherState == EtherState.None) { brokenChance += 0.5f; bondChance += 0.2f; } totalProduced += rareThingCount + thingCount; }
protected override IEnumerable <Toil> MakeNewToils() { this.FailOnDestroyedOrNull(TargetIndex.A); this.FailOnDestroyedOrNull(TargetIndex.B); this.FailOnAggroMentalState(TargetIndex.A); if (base.CurJob.def == JobDefOf.Rescue) { this.FailOnNotDowned(TargetIndex.A); } this.FailOn(delegate { if (this.CurJob.def.makeTargetPrisoner) { if (!this.DropBed.ForPrisoners) { return(true); } } else if (this.DropBed.ForPrisoners != ((Pawn)((Thing)this.TargetA)).IsPrisoner) { return(true); } return(false); }); yield return(Toils_Reserve.Reserve(TargetIndex.A, 1)); yield return(Toils_Reserve.Reserve(TargetIndex.B, this.DropBed.SleepingSlotsCount)); yield return(Toils_Bed.ClaimBedIfNonMedical(TargetIndex.B, TargetIndex.A)); this.globalFinishActions.Add(delegate { if (this.CurJob.def.makeTargetPrisoner && this.Takee.ownership.OwnedBed == this.DropBed && this.Takee.Position != RestUtility.GetBedSleepingSlotPosFor(this.Takee, this.DropBed)) { this.Takee.ownership.UnclaimBed(); } }); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.A).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOnNonMedicalBedNotOwned(TargetIndex.B, TargetIndex.A).FailOn(() => this.CurJob.def == JobDefOf.Arrest && !this.Takee.CanBeArrested()).FailOn(() => !this.pawn.CanReach(this.DropBed, PathEndMode.OnCell, Danger.Deadly, false, TraverseMode.ByPawn)).FailOnSomeonePhysicallyInteracting(TargetIndex.A)); yield return(new Toil { initAction = delegate { if (this.CurJob.def.makeTargetPrisoner) { Pawn pawn = (Pawn)this.CurJob.targetA.Thing; Lord lord = pawn.GetLord(); if (lord != null) { lord.Notify_PawnAttemptArrested(pawn); } GenClamor.DoClamor(pawn, 10f, ClamorDefOf.Harm); if (Rand.Value < 0.1f) { Messages.Message("MessageRefusedArrest".Translate(new object[] { pawn.LabelShort }), pawn, MessageTypeDefOf.NegativeEvent); pawn.mindState.mentalStateHandler.TryStartMentalState(MentalStateDefOf.Berserk, null, false, false, null); IncidentWorker_Rebellion.removeLeadership(pawn); pawn.needs.mood.thoughts.memories.TryGainMemory(ThoughtDef.Named("LeaderArrested")); this.pawn.mindState.mentalStateHandler.CurState.RecoverFromState(); Find.LetterStack.ReceiveLetter("LeaderEndLetter".Translate(), "LeaderEndLetterDesc".Translate(new object[] { pawn.Name.ToStringFull }), LetterDefOf.NegativeEvent, pawn, null); this.pawn.jobs.EndCurrentJob(JobCondition.Incompletable, true); } } } }); yield return(Toils_Haul.StartCarryThing(TargetIndex.A, false, false)); yield return(Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.Touch)); yield return(new Toil { initAction = delegate { if (this.CurJob.def.makeTargetPrisoner) { this.pawn.mindState.mentalStateHandler.CurState.RecoverFromState(); IncidentWorker_Rebellion.removeLeadership(this.Takee); this.Takee.needs.mood.thoughts.memories.TryGainMemory(ThoughtDef.Named("LeaderArrested")); Find.LetterStack.ReceiveLetter("LeaderEndLetterArrested".Translate(), "LeaderEndLetterDescArrested".Translate(new object[] { Takee.Name.ToStringFull }), LetterDefOf.NegativeEvent, this.pawn, null); foreach (Pawn p in IncidentWorker_LeaderElection.getAllColonists()) { if (p != this.Takee) { p.needs.mood.thoughts.memories.TryGainMemory(ThoughtDef.Named("LeaderArrestedColonist"), null); } } if (this.Takee.guest.released) { this.Takee.guest.released = false; this.Takee.guest.interactionMode = PrisonerInteractionModeDefOf.NoInteraction; } if (!this.Takee.IsPrisonerOfColony) { if (this.Takee.Faction != null) { this.Takee.Faction.Notify_MemberCaptured(this.Takee, this.pawn.Faction); } this.Takee.guest.SetGuestStatus(Faction.OfPlayer, true); if (this.Takee.guest.IsPrisoner) { TaleRecorder.RecordTale(TaleDefOf.Captured, new object[] { this.pawn, this.Takee }); this.pawn.records.Increment(RecordDefOf.PeopleCaptured); } } } else if (this.Takee.Faction != Faction.OfPlayer && this.Takee.HostFaction != Faction.OfPlayer && this.Takee.guest != null) { this.Takee.guest.SetGuestStatus(Faction.OfPlayer, false); } if (this.Takee.playerSettings == null) { this.Takee.playerSettings = new Pawn_PlayerSettings(this.Takee); } } }); yield return(Toils_Reserve.Release(TargetIndex.B)); yield return(new Toil { initAction = delegate { IntVec3 position = this.DropBed.Position; Thing thing; this.pawn.carryTracker.TryDropCarriedThing(position, ThingPlaceMode.Direct, out thing, null); if (!this.DropBed.Destroyed && (this.DropBed.owners.Contains(this.Takee) || (this.DropBed.Medical && this.DropBed.AnyUnoccupiedSleepingSlot) || this.Takee.ownership == null)) { this.Takee.jobs.Notify_TuckedIntoBed(this.DropBed); if (this.Takee.RaceProps.Humanlike && this.CurJob.def != JobDefOf.Arrest && !this.Takee.IsPrisonerOfColony) { this.Takee.relations.Notify_RescuedBy(this.pawn); } } if (this.Takee.IsPrisonerOfColony) { LessonAutoActivator.TeachOpportunity(ConceptDefOf.PrisonerTab, this.Takee, OpportunityType.GoodToKnow); } }, defaultCompleteMode = ToilCompleteMode.Instant }); }
public static bool NumMemoriesOfDef(MemoryThoughtHandler __instance, ref int __result, ThoughtDef def) { int num = 0; List <Thought_Memory> memories = __instance.memories; for (int index = 0; index < memories.Count; ++index) { Thought_Memory memory = memories[index]; if (memory != null && memory.def == def) { ++num; } } __result = num; return(false); }
private static void GainThought(this Pawn target, ThoughtDef thoughtDef) { var thoughtMemory = (Thought_Memory)ThoughtMaker.MakeThought(thoughtDef); target?.needs?.mood?.thoughts?.memories?.TryGainMemory(thoughtMemory); // *cough* Extra defensive }
internal static List <ThoughtDef> _ThoughtsFromIngesting(Pawn ingester, Thing t) { ingestThoughts.Clear(); if (ingester.needs == null || ingester.needs.mood == null) { return(ingestThoughts); } ThingDef thingDef = t.def; if (thingDef == ThingDefOf.NutrientPasteDispenser) { thingDef = ThingDefOf.MealNutrientPaste; } if (!ingester.story.traits.HasTrait(TraitDefOf.Ascetic) && thingDef.ingestible.tasteThought != null) { ingestThoughts.Add(thingDef.ingestible.tasteThought); } CompIngredients compIngredients = t.TryGetComp <CompIngredients>(); if (FoodUtility.IsHumanlikeMeat(thingDef) && ingester.RaceProps.Humanlike) { ingestThoughts.Add((!ingester.story.traits.HasTrait(TraitDefOf.Cannibal)) ? ThoughtDefOf.AteHumanlikeMeatDirect : ThoughtDefOf.AteHumanlikeMeatDirectCannibal); } else if (compIngredients != null) { for (int i = 0; i < compIngredients.ingredients.Count; i++) { ThingDef thingDef2 = compIngredients.ingredients[i]; if (thingDef2.ingestible != null) { if (ingester.RaceProps.Humanlike && FoodUtility.IsHumanlikeMeat(thingDef2)) { ingestThoughts.Add((!ingester.story.traits.HasTrait(TraitDefOf.Cannibal)) ? ThoughtDefOf.AteHumanlikeMeatAsIngredient : ThoughtDefOf.AteHumanlikeMeatAsIngredientCannibal); } else if (thingDef2.ingestible.specialThoughtAsIngredient != null) { ingestThoughts.Add(thingDef2.ingestible.specialThoughtAsIngredient); } } } } else if (thingDef.ingestible.specialThoughtDirect != null) { ingestThoughts.Add(thingDef.ingestible.specialThoughtDirect); } if (t.IsNotFresh()) { ingestThoughts.Add(ThoughtDefOf.AteRottenFood); } List <ThoughtDef> newThoughts = new List <ThoughtDef>(); foreach (var thought in ingestThoughts) { if (DefDatabase <ThoughtDef> .GetNamedSilentFail(thought.defName + "PickyEater") != null) { newThoughts.Add(ThoughtDef.Named(thought.defName + "PickyEater")); } } ingestThoughts.AddRange(newThoughts); return(ingestThoughts); }
public static bool IsDeathThought(this ThoughtDef tDef) { return(deathThought.Contains(tDef)); }
protected override IEnumerable <Toil> MakeNewToils() { this.FailOnDestroyedOrNull(TargetIndex.A); // yield return Toils_Reserve.Reserve(SpotIndex, 1, -1, null); yield return(new Toil { initAction = delegate { Spot.ChangeState(Building_TeachingSpot.State.lesson, Building_TeachingSpot.LessonState.gathering); } }); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell)); Toil waitingTime = new Toil(); waitingTime.defaultCompleteMode = ToilCompleteMode.Delay; TeachingUtility.remainingDuration = TeachingUtility.ritualDuration; waitingTime.defaultDuration = TeachingUtility.remainingDuration - 360; waitingTime.initAction = delegate { // Spot.lastLessonTick = Find.TickManager.TicksGame; // HediffLeader hediff = TeachingUtility.leaderH(this.pawn); //if (hediff != null) hediff.lastLessonTick = Find.TickManager.TicksGame; report = "WaitingDesc".Translate(); MoteMaker.MakeInteractionBubble(this.pawn, null, ThingDefOf.Mote_Speech, ModTextures.waiting); Spot.ChangeState(Building_TeachingSpot.State.lesson, Building_TeachingSpot.LessonState.teaching); List <Thing> list = GenRadial.RadialDistinctThingsAround(this.pawn.Position, this.pawn.Map, 10f, true).ToList <Thing>(); foreach (Thing current in list) { Building_Chalkboard chalk = current as Building_Chalkboard; bool flag2 = chalk != null; if (flag2) { if (current.def.defName == "ChalkboardCL" && current.Faction == this.pawn.Faction) { if (current.GetRoom() == this.pawn.GetRoom()) { string s = TeachingUtility.getLeaderType(this.pawn); chalkboards.Add(chalk); chalk.frame = -1; this.Map.mapDrawer.MapMeshDirty(chalk.Position, MapMeshFlag.Things, true, false); } } } } }; yield return(waitingTime); for (int i = 0; i < 3; i++) { Toil teachingTime = new Toil(); teachingTime.defaultCompleteMode = ToilCompleteMode.Delay; TeachingUtility.remainingDuration = TeachingUtility.ritualDuration; teachingTime.defaultDuration = TeachingUtility.remainingDuration - 120; teachingTime.initAction = delegate { string s = TeachingUtility.getLeaderType(this.pawn); foreach (Building_Chalkboard chalk in chalkboards) { if (chalk != null) { if (s == "leader1") { chalk.state = 1; } else if (s == "leader2") { chalk.state = 2; } else if (s == "leader3") { chalk.state = 3; } else if (s == "leader4") { chalk.state = 4; } chalk.frame++; this.Map.mapDrawer.MapMeshDirty(chalk.Position, MapMeshFlag.Things, true, false); } } report = "TeachingDesc".Translate(); MoteMaker.MakeInteractionBubble(this.pawn, null, ThingDefOf.Mote_Speech, iconList(this.pawn).RandomElement()); }; teachingTime.tickAction = delegate { Pawn actor = this.pawn; actor.skills.Learn(SkillDefOf.Social, 0.25f); actor.GainComfortFromCellIfPossible(); }; yield return(teachingTime); } Toil finishingTime = new Toil(); finishingTime.defaultCompleteMode = ToilCompleteMode.Delay; TeachingUtility.remainingDuration = TeachingUtility.ritualDuration; finishingTime.defaultDuration = TeachingUtility.remainingDuration - 360; finishingTime.WithProgressBarToilDelay(TargetIndex.A, false, -0.5f); finishingTime.initAction = delegate { report = "FinishLessonDesc".Translate(); MoteMaker.MakeInteractionBubble(this.pawn, null, ThingDefOf.Mote_Speech, iconList(this.pawn).RandomElement()); }; finishingTime.tickAction = delegate { if (tickC == 120 || tickC == 240 || tickC == 360) { foreach (Building_Chalkboard chalk in chalkboards) { if (chalk != null) { if (chalk.frame > -1) { chalk.frame--; } this.Map.mapDrawer.MapMeshDirty(chalk.Position, MapMeshFlag.Things, true, false); } } } Pawn actor = this.pawn; actor.skills.Learn(SkillDefOf.Social, 0.25f); actor.GainComfortFromCellIfPossible(); tickC++; }; yield return(finishingTime); yield return(new Toil { initAction = delegate { tickC = 0; TeachingUtility.TeachingComplete(this.pawn, Spot); }, defaultCompleteMode = ToilCompleteMode.Instant }); yield return(new Toil { initAction = delegate { if (Spot != null) { if (Spot.currentLessonState != Building_TeachingSpot.LessonState.finished) { Spot.ChangeState(Building_TeachingSpot.State.lesson, Building_TeachingSpot.LessonState.finished); //Map.GetComponent<MapComponent_SacrificeTracker>().ClearVariables(); } } }, defaultCompleteMode = ToilCompleteMode.Instant }); this.AddFinishAction(() => { foreach (Building_Chalkboard chalk in chalkboards) { if (chalk != null) { chalk.frame = 0; chalk.state = 0; this.Map.mapDrawer.MapMeshDirty(chalk.Position, MapMeshFlag.Things, true, false); } } if (Spot.currentLessonState == Building_TeachingSpot.LessonState.finishing || Spot.currentLessonState == Building_TeachingSpot.LessonState.finished) { this.pawn.needs.mood.thoughts.memories.TryGainMemory(ThoughtDef.Named("TaughtCL"), null); } }); yield break; }
private static bool Prefix(MemoryThoughtHandler __instance, ref Thought_Memory newThought, Pawn otherPawn) { if (__instance.pawn.HasTrait(VTEDefOf.VTE_AnimalHater) && animalThoughtDefs.Contains(newThought.def)) { newThought = (Thought_Memory)ThoughtMaker.MakeThought(inverseAnimalThoughDefs[newThought.def]); } if (__instance.pawn.HasTrait(VTEDefOf.VTE_Squeamish) && newThought.def == VTEDefOf.ObservedLayingRottingCorpse) { var comp = Current.Game.GetComponent <TraitsManager>(); if ((!comp.squeamishWithLastVomitedTick.ContainsKey(__instance.pawn) || GenTicks.TicksAbs >= comp.squeamishWithLastVomitedTick[__instance.pawn] + (30 * 60)) && Rand.Chance(0.5f)) { Job vomit = JobMaker.MakeJob(JobDefOf.Vomit); __instance.pawn.jobs.TryTakeOrderedJob(vomit); comp.squeamishWithLastVomitedTick[__instance.pawn] = GenTicks.TicksAbs; } } if (__instance.pawn.HasTrait(VTEDefOf.VTE_Desensitized) && horribleThoughts.Contains(newThought.def.defName)) { return(false); } if (__instance.pawn.HasTrait(VTEDefOf.VTE_ColdInclined) && (newThought.CurStageIndex < 1 && newThought.def == ThoughtDef.Named("EnvironmentCold") || newThought.def == ThoughtDefOf.SleptInCold)) { return(false); } if (__instance.pawn.HasTrait(VTEDefOf.VTE_HeatInclined) && (newThought.CurStageIndex < 1 && newThought.def == ThoughtDef.Named("EnvironmentHot") || newThought.def == ThoughtDefOf.SleptInHeat)) { return(false); } if (__instance.pawn.HasTrait(VTEDefOf.VTE_ChildOfMountain) && newThought.def == ThoughtDef.Named("EnvironmentDark")) { return(false); } if (__instance.pawn.HasTrait(VTEDefOf.VTE_ChildOfSea) && newThought.def == ThoughtDef.Named("SoakingWet")) { __instance.pawn.TryGiveThought(VTEDefOf.VTE_SoakingWetChildOfTheSea); return(false); } if (__instance.pawn.HasTrait(VTEDefOf.VTE_HeavySleeper) && newThought.def == ThoughtDefOf.SleepDisturbed) { return(false); } if (__instance.pawn.HasTrait(VTEDefOf.VTE_MadSurgeon) && (newThought.def == ThoughtDefOf.KnowColonistOrganHarvested || newThought.def == ThoughtDefOf.KnowGuestOrganHarvested || newThought.def == ThoughtDefOf.ButcheredHumanlikeCorpse || newThought.def == ThoughtDefOf.KnowButcheredHumanlikeCorpse || newThought.def == VTEDefOf.ObservedLayingCorpse || newThought.def == VTEDefOf.ObservedLayingRottingCorpse || newThought.def == ThoughtDefOf.KnowPrisonerDiedInnocent || newThought.def == ThoughtDefOf.KnowColonistExecuted && newThought.CurStageIndex == 3 )) { return(false); } return(true); }
public static void RemoveThought(Pawn pawn, ThoughtDef thought) { pawn.needs.mood.thoughts.memories.RemoveMemoriesOfDef(thought); }
public static void AddThought(Pawn pawn, ThoughtDef thought, int stage) { pawn.needs.mood.thoughts.memories.TryGainMemory(thought); pawn.needs.mood.thoughts.memories.GetFirstMemoryOfDef(thought).SetForcedStage(stage); }
/// <summary> /// Tries to revert the given pawn. /// </summary> /// <param name="transformedPawn">The transformed pawn.</param> /// <returns></returns> public override bool TryRevert(Pawn transformedPawn) { if (transformedPawn == null) { throw new ArgumentNullException(nameof(transformedPawn)); } var pawnStatus = GameComp.GetTransformedPawnContaining(transformedPawn); var sState = transformedPawn.GetSapienceState(); if (sState == null) { return(false); } if (pawnStatus != null) { if (pawnStatus.Value.status != TransformedStatus.Transformed) { return(false); } if (pawnStatus.Value.pawn is MergedPawns merged) { if (sState.StateDef != def.transformedSapienceState) { return(false); } if (TryRevertImpl(merged)) { GameComp.RemoveInstance(merged); return(true); } } return(false); } if (sState.StateDef == def.transformedSapienceState) { ThoughtDef thoughtDef = null; for (var i = 0; i < 2; i++) { PawnGenerationRequest request = TransformerUtility.GenerateRandomPawnFromAnimal(transformedPawn); Pawn pawnTf = PawnGenerator.GeneratePawn(request); pawnTf.needs.food.CurLevel = transformedPawn.needs.food.CurInstantLevel; pawnTf.needs.rest.CurLevel = transformedPawn.needs.rest.CurLevel; var spawnedPawn = (Pawn)GenSpawn.Spawn(pawnTf, transformedPawn.PositionHeld, transformedPawn.MapHeld); spawnedPawn.apparel.DestroyAll(); spawnedPawn.equipment.DestroyAllEquipment(); for (var j = 0; j < 10; j++) { IntermittentMagicSprayer.ThrowMagicPuffDown(spawnedPawn.Position.ToVector3(), spawnedPawn.MapHeld); IntermittentMagicSprayer.ThrowMagicPuffUp(spawnedPawn.Position.ToVector3(), spawnedPawn.MapHeld); } _scratchArray[i] = spawnedPawn; } PawnRelationDef relationDef; bool relationIsMergeMate = thoughtDef == def.revertedThoughtGood; relationDef = relationIsMergeMate ? TfRelationDefOf.MergeMate : TfRelationDefOf.ExMerged; _scratchArray[0].relations.AddDirectRelation(relationDef, _scratchArray[1]); CheckForBrainDamage(transformedPawn, _scratchArray[0], _scratchArray[1]); transformedPawn.Destroy(); return(true); } return(false); }
public static void addMemoryOfOther(Pawn p, ThoughtDef thoughtDef, Pawn other) { p.needs.mood.thoughts.memories.TryGainMemory(thoughtDef, other); }
public void ConclusionAdder(Pawn pawn) { pawn.health.AddHediff(HediffDef.Named("Rewire"), null, null); if (PawnChanger.HasMood(pawn, ThoughtDef.Named("Wrecked")) || PawnChanger.HasMood(pawn, ThoughtDef.Named("Scrambled"))) { PawnChanger.ExecuteBadThings(pawn); } PawnChanger.SetMood(pawn); }
// ================== Ticks ================== public override void Tick() { base.Tick(); // Do init work after spawning if (!init) { HelperAIPawn.ReApplyThingToListerThings(this.Position, this); Drawer.renderer.graphics.ResolveAllGraphics(); //Causes errors! UpdateGraphics(); initTicks--; if (initTicks <= 0) { // Replace invalid Mai with valid Mai if (!story.childhood.identifier.Contains(BackstoryHelper.BackstoryDefNameIdentifier)) { string savedDefName = def.defName; IntVec3 savedPosition = Position; Map savedMap = Map; Gender savedGender = this.gender; // Destroy me destroyMeWithoutExplosion = true; Destroy(DestroyMode.Vanish); // Create a new me AIPawn mai = Building_AIPawnCreator.CreateAIPawn(savedDefName, savedPosition, savedMap, savedGender); return; } BackstoryHelper.RemoveNewBackstoriesFromDatabase(); init = true; } return; } //// To circumvent the strange pathing error! //if ((this.CurJob == null || this.CurJob != curJobOld) && Map != null) //{ // HelperAIPawn.ReApplyThingToListerThings(this.Position, this); // curJobOld = this.CurJob; //} // To circumvent the destroy apparel error if (this.CurJob != null && this.CurJob.def.defName == "Wear" && this.CurJob.targetA.Cell == this.Position) { AIPawnGenerator.DestroyBaseShielding(this); } // Update drafted graphics if (draftedActiveOld != this.Drafted) { UpdateGraphics(); draftedActiveOld = this.Drafted; } // When AIPawn is in a Container, do nothing if (this.InContainerEnclosed) { return; } // When AIPawn is in a bed, fix rest value to prevent explosions in the hospital room if (Find.TickManager.TicksGame % fixRestWhenInBedCounter == 0) { Building_AIPawnRechargeStation rechargeStation; if (this.InBed() && !this.IsInAIRechargeStation(Map, out rechargeStation)) { needs.rest.CurLevel = fixRestWhenInBedFixedValue; } else { fixRestWhenInBedFixedValue = needs.rest.CurLevel; } } // Disable food reduction <-- Food is needed or some errors are thrown if (needs != null && needs.food != null && needs.food.CurLevel <= 0.95f) { needs.food.CurLevel = 1.0f; } //// Disable joy reduction //if (needs != null && needs.joy != null && needs.joy.CurLevel <= 0.95f) // needs.joy.CurLevel = 1.0f; //// Disable beauty reduction //if (needs != null && needs.beauty != null && needs.beauty.CurLevel <= 0.95f) // needs.beauty.CurLevel = 1.0f; //// Disable comfort reduction //if (needs != null && needs.comfort != null && needs.comfort.CurLevel <= 0.95f) // needs.comfort.CurLevel = 1.0f; //// Disable rest reduction when traveling in a caravan! //if (needs != null && needs.rest != null && needs.rest.CurLevel <= 0.95f && !Destroyed && !Downed && Map == null) // needs.rest.CurLevel += 0.01f / 60f; // If in bed, slowly increase rest (to circumvent bed problems) if (IsInBed(Map)) { needs.rest.CurLevel += 0.025f / 60f; } // Self healing ability (Nanobots) healDamagedPartsCounter -= 1; if (healDamagedPartsCounter <= 0) { DoHealDamagedBodyPart(enhancedAI); healDamagedPartsCounter = healDamagedPartsCounterStartValue; } refreshQuickCount += 1; if (refreshQuickCount >= refreshQuickMax) { refreshQuickCount = 0; } if (refreshQuickCount == 0) { // Add thought when health < x if (this.health.summaryHealth.SummaryHealthPercent < 0.75) { this.needs.mood.thoughts.memories.TryGainMemory(ThoughtDef.Named("AIShieldingError")); } // disable diseases DoDiseaseHandling(); if (Destroyed) { destroyMeWithoutExplosion = true; Destroy(DestroyMode.Vanish); return; } // Do explosion when downed, dead or incapable of moving if (Dead || (!isAnestheticIncap && !IsInBed(Map) && (Downed || health.capacities.GetLevel(PawnCapacityDefOf.Moving) < 0.1f))) { incapToExplosionCounter -= refreshQuickMax; if (incapToExplosionCounter <= 0) { Destroy(DestroyMode.KillFinalize); return; } } // Reset counter when health is rising -- Not working right now if ((Downed && this.health.summaryHealth.SummaryHealthPercent > incapHealthOld) || !Downed && (incapToExplosionCounter < incapToExplosionCounterStartValue)) { incapToExplosionCounter = incapToExplosionCounterStartValue; } incapHealthOld = this.health.summaryHealth.SummaryHealthPercent; //// Add thought when rested //if (rest.Rest.CurLevel >= 98.9f) // psychology.thoughts.memories.TryGainMemoryThought(ThoughtDef.Named("AIBatteriesRefilled")); // Change color when near exhausted float levelLowBatterie = 0.25f; float levelLowCriticalBatterie = 0.15f; if (needs.rest.CurLevel <= levelLowCriticalBatterie && !graphicHueActive) { // Switch to alternate graphic graphicHueActive = true; UpdateGraphics(); } else if (needs.rest.CurLevel > levelLowCriticalBatterie && graphicHueActive) { // Switch back to normal graphic graphicHueActive = false; UpdateGraphics(); } // Add thought when rest(batteries) < x if (needs.rest.CurLevel < levelLowCriticalBatterie) { needs.mood.thoughts.memories.TryGainMemory(ThoughtDef.Named("AILowCriticalBattery")); } // Add thought when rest(batteries) < x else if (needs.rest.CurLevel < levelLowBatterie) { needs.mood.thoughts.memories.TryGainMemory(ThoughtDef.Named("AILowBattery")); } // Explosion when exhausted if (needs.rest.CurLevel <= 0.011f) { if (!Downed) { HealthUtility.DamageUntilDowned(this, false); } } else if (needs.rest.CurLevel < 0.2f) { TryGoRecharging(); } // unclaim bed when fully rested // Activate? Don't Activate? //if (ownership != null && (rest.Rest.CurLevel >= 94.8f || rest.DoneResting)) // ownership.UnclaimBed(); } // Update base AI thought every x refreshBaseInfosCount += 1; if (refreshBaseInfosCount >= refreshBaseInfosMax || refreshBaseInfosCount < 0) { refreshBaseInfosCount = 0; this.mindState.canFleeIndividual = false; DoRelationHandling(); //Base thought is only available after save/load (why?) so it needs to be set this.needs.mood.thoughts.memories.TryGainMemory(ThoughtDef.Named("AIBaseThought")); // Rebuild Base Shielding if needed Building_AIPawnRechargeStation rs2; AIPawnGenerator.GiveBaseApparelWhileInBed(this, IsInAIRechargeStation(Map, out rs2)); } }
public void CookIt() { foreach (Thing current in this.container) { Pawn pawn = current as Pawn; if (pawn != null) { PawnChanger.SetPawnTraits(pawn, Rand.RangeInclusive(2, 3)); pawn.health.AddHediff(HediffDef.Named("Rewire"), null, null); if (PawnChanger.HasMood(pawn, ThoughtDef.Named("Wrecked")) || PawnChanger.HasMood(pawn, ThoughtDef.Named("Scrambled"))) { PawnChanger.ExecuteBadThings(pawn); } PawnChanger.SetMood(pawn); } } }
public Crime(JobDef newCrimeDef, ThoughtDef newColonistThought, ThoughtDef newVisitorThought) { CrimeDef = newCrimeDef; ColonistThought = newColonistThought; VisitorThought = newVisitorThought; }
public static void TryPleaseGuest(Pawn recruiter, Pawn guest, bool focusOnRecruiting, List <RulePackDef> extraSentencePacks) { // TODO: pawn.records.Increment(RecordDefOf.GuestsCharmAttempts); recruiter.skills.Learn(SkillDefOf.Social, 35f); float pleaseChance = recruiter.GetStatValue(statPleaseGuestChance); pleaseChance = AdjustPleaseChance(pleaseChance, recruiter, guest); pleaseChance = Mathf.Clamp01(pleaseChance); var failedCharms = guest.GetComp <CompGuest>().failedCharms; if (Rand.Value > pleaseChance) { var isAbrasive = recruiter.story.traits.HasTrait(TraitDefOf.Abrasive); int multiplier = isAbrasive ? 2 : 1; string multiplierText = multiplier > 1 ? " x" + multiplier : String.Empty; int amount; if (failedCharms.TryGetValue(recruiter, out amount)) { amount++; failedCharms[recruiter] = amount; } else { failedCharms.Add(recruiter, 1); } if (amount >= 3) { Messages.Message( "RecruitAngerMultiple".Translate(recruiter.NameStringShort, guest.NameStringShort, amount), guest, MessageSound.Negative); } extraSentencePacks.Add(RulePackDef.Named("Sentence_CharmAttemptRejected")); for (int i = 0; i < multiplier; i++) { GainSocialThought(recruiter, guest, ThoughtDef.Named("GuestOffendedRelationship")); } MoteMaker.ThrowText((recruiter.DrawPos + guest.DrawPos) / 2f, recruiter.Map, "TextMote_CharmFail".Translate() + multiplierText, 8f); } else { failedCharms.Remove(recruiter); var statValue = recruiter.GetStatValue(statRecruitEffectivity); var floor = Mathf.FloorToInt(statValue); int multiplier = floor + (Rand.Value < statValue - floor ? 1 : 0); // Multiplier is for what the focus is one for (int i = 0; i < multiplier; i++) { if (focusOnRecruiting) { EndorseColonists(recruiter, guest); } else { GainSocialThought(recruiter, guest, ThoughtDef.Named("GuestPleasedRelationship")); } } // And then one more of the other multiplier++; if (focusOnRecruiting) { GainSocialThought(recruiter, guest, ThoughtDef.Named("GuestPleasedRelationship")); } else { EndorseColonists(recruiter, guest); } extraSentencePacks.Add(RulePackDef.Named("Sentence_CharmAttemptAccepted")); string multiplierText = multiplier > 1 ? " x" + multiplier : String.Empty; MoteMaker.ThrowText((recruiter.DrawPos + guest.DrawPos) / 2f, recruiter.Map, "TextMote_CharmSuccess".Translate() + multiplierText, 8f); } GainSocialThought(recruiter, guest, ThoughtDef.Named("GuestDismissiveAttitude")); }
private string GetOpinionRange(ThoughtDef def, out Color color) { color = def.stages.First().baseOpinionOffset >= 0 ? Color.green : Color.red; return($"{def.stages.First().baseOpinionOffset} {"Religion_To".Translate()} {def.stages.Last().baseOpinionOffset}"); }
public ThoughtDef ReplaceIfApplicable(ThoughtDef def) => (this.replacerList == null || this.replacerList.Select(selector: tr => tr.replacer).Contains(def)) ? def : this.replacerList.FirstOrDefault(predicate: tr => tr.original == def)?.replacer ?? def;
internal static void RemoveChildDiedThought(Pawn pawn, Pawn child) { // Does the pawn have a "my child died thought"? MemoryThoughtHandler mems = pawn.needs.mood.thoughts.memories; if (mems.NumMemoriesOfDef(ThoughtDef.Named("MySonDied")) > 0 || mems.NumMemoriesOfDef(ThoughtDef.Named("MyDaughterDied")) > 0) { // Let's look through the list of memories foreach (Thought_Memory thought in mems.Memories.ToList()) { // Check if it's one of the right defs if (thought.def == ThoughtDef.Named("MySonDied") || thought.def == ThoughtDef.Named("MyDaughterDied")) { // We found the thought if (thought.otherPawn == child) { // Let's remove it mems.Memories.Remove(thought); } } } } }
public static IEnumerable <ThingDef> ImpliedBloodDefs() { foreach (ThingDef sourceDef in DefDatabase <ThingDef> .AllDefs.ToList()) { if (sourceDef.category != ThingCategory.Pawn || sourceDef.race.useMeatFrom != null || !sourceDef.race.IsFlesh) { continue; } ThingDef bloodDef = new ThingDef(); bloodDef.defName = "Blood_" + sourceDef.defName; bloodDef.label = GetBloodLabel(sourceDef); bloodDef.resourceReadoutPriority = ResourceCountPriority.Middle; bloodDef.category = ThingCategory.Item; bloodDef.thingClass = typeof(ThingWithComps); bloodDef.useHitPoints = true; bloodDef.selectable = true; bloodDef.altitudeLayer = AltitudeLayer.Item; bloodDef.stackLimit = 25; bloodDef.SetStatBaseValue(StatDefOf.Beauty, -4f); bloodDef.SetStatBaseValue(StatDefOf.MaxHitPoints, 60f); bloodDef.SetStatBaseValue(StatDefOf.DeteriorationRate, 10f); bloodDef.SetStatBaseValue(StatDefOf.Mass, 0.5f); bloodDef.SetStatBaseValue(StatDefOf.Flammability, 2f); bloodDef.SetStatBaseValue(StatDefOf.Nutrition, 0.01f); bloodDef.SetStatBaseValue(StatDefOf.FoodPoisonChanceFixedHuman, 0.02f); bloodDef.tickerType = TickerType.Rare; bloodDef.comps.Add(new CompProperties_Forbiddable()); bloodDef.comps.Add(new CompProperties_Rottable { daysToRotStart = 0.5f, rotDestroys = true }); bloodDef.comps.Add(new CompProperties_Blood { bloodAmount = 0.1f, minSeverityForBadThought = 0.4f, harvestEfficiencyFactor = 2f }); //humanlike blood can be self-administered (if same race) if (sourceDef.race.Humanlike) { bloodDef.comps.Add(new CompProperties_Usable { useJob = DefDatabase <JobDef> .GetNamed("UseItem"), useLabel = "GiveSelfTransfusion".Translate(bloodDef.label) }); bloodDef.comps.Add(new CompProperties_RestrictUsableWithSkill { skillRequirements = new List <SkillRequirement> { new SkillRequirement { skill = SkillDefOf.Medicine, minLevel = 4 } } }); bloodDef.comps.Add(new CompProperties_RestrictUsableByRace { allowedRaces = new List <ThingDef> { sourceDef } }); bloodDef.comps.Add(new CompProperties_UseEffect { compClass = typeof(CompUseEffect_AdministerBloodTransfusion) }); bloodDef.comps.Add(new CompProperties_UseEffect { compClass = typeof(CompUseEffect_DestroySelf) }); } bloodDef.alwaysHaulable = true; bloodDef.drawGUIOverlay = true; bloodDef.rotatable = false; bloodDef.pathCost = 15; if (bloodDef.thingCategories == null) { bloodDef.thingCategories = new List <ThingCategoryDef>(); } DirectXmlCrossRefLoader.RegisterListWantsCrossRef(bloodDef.thingCategories, "RawBlood", bloodDef); bloodDef.uiIconForStackCount = 1; bloodDef.soundInteract = SoundDefOf.Standard_Drop; bloodDef.soundDrop = SoundDefOf.Standard_Drop; bloodDef.techLevel = TechLevel.Industrial; bloodDef.socialPropernessMatters = true; bloodDef.modContentPack = sourceDef.modContentPack; //does this matter? //worth 4x as much as the meat of the same animal if humanlike, half as much for critters bloodDef.BaseMarketValue = sourceDef.race.Humanlike ? sourceDef.race.meatMarketValue * 4f : sourceDef.race.meatMarketValue / 2f; bloodDef.graphicData = new GraphicData { graphicClass = typeof(Graphic_StackCount), texPath = sourceDef.race.FleshType == FleshTypeDefOf.Insectoid ? "Things/Item/Resource/InsectBloodPack" : "Things/Item/Resource/BloodPack", drawSize = Vector2.one * 0.85f }; if (sourceDef.race.Humanlike) { bloodDef.description = "BloodHumanlikeDesc".Translate(sourceDef.label); } else if (sourceDef.race.FleshType == FleshTypeDefOf.Insectoid) { bloodDef.description = "BloodInsectDesc".Translate(sourceDef.label); } else { bloodDef.description = "BloodDesc".Translate(sourceDef.label); } bloodDef.ingestible = new IngestibleProperties { parent = bloodDef, foodType = FoodTypeFlags.Fluid | FoodTypeFlags.AnimalProduct, preferability = FoodPreferability.DesperateOnlyForHumanlikes, ingestCommandString = "Drink {0}", ingestReportString = "Drinking {0}.", ingestEffect = EffecterDefOf.EatMeat, ingestSound = SoundDef.Named("Ingest_Drink"), sourceDef = sourceDef, specialThoughtDirect = sourceDef.race.Humanlike ? ThoughtDef.Named("DrankHumanlikeBlood") : sourceDef.race.FleshType == FleshTypeDefOf.Insectoid ? ThoughtDef.Named("ConsumedInsectHemolymph") : null, specialThoughtAsIngredient = sourceDef.race.Humanlike ? ThoughtDef.Named("ConsumedHumanlikeBloodAsIngredient") : sourceDef.race.FleshType == FleshTypeDefOf.Insectoid ? ThoughtDef.Named("ConsumedInsectHemolymphAsIngredient") : null, }; DirectXmlCrossRefLoader.RegisterObjectWantsCrossRef(bloodDef.ingestible, "tasteThought", "DrankRawBlood"); yield return(bloodDef); } }
public static bool Prefix(object __instance, Pawn actor) { bool result; if (actor.needs.mood == null) { result = false; } else if (actor.CurrentBed() == null) { result = true; } else { //Log.Message("ApplyBedThoughts is relevant for " + actor); Building_Bed bed = new Building_Bed(); bed = actor.CurrentBed(); bool hospitalityIsGuest = false; if (isHospitalityLoaded) { //Correcting for Hospitality 1.0.25 hospitalityIsGuest = AddedBedIsOwned(__instance, actor, bed); // } actor.needs.mood.thoughts.memories.RemoveMemoriesOfDef(ThoughtDefOf.SleptInBedroom); actor.needs.mood.thoughts.memories.RemoveMemoriesOfDef(ThoughtDefOf.SleptInBarracks); actor.needs.mood.thoughts.memories.RemoveMemoriesOfDef(ThoughtDefOf.SleptOutside); actor.needs.mood.thoughts.memories.RemoveMemoriesOfDef(ThoughtDefOf.SleptOnGround); actor.needs.mood.thoughts.memories.RemoveMemoriesOfDef(ThoughtDefOf.SleptInCold); actor.needs.mood.thoughts.memories.RemoveMemoriesOfDef(ThoughtDefOf.SleptInHeat); if (actor.GetRoom(RegionType.Set_Passable).PsychologicallyOutdoors) { actor.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOf.SleptOutside, null); } if (bed == null || bed.CostListAdjusted().Count == 0) { actor.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOf.SleptOnGround, null); } //taking bed insulation into consideration: //Log.Message("bedStats: cold = " + bed.GetStatValue(BedInsulationCold.Bed_Insulation_Cold, true)+", heat ="+ bed.GetStatValue(BedInsulationHeat.Bed_Insulation_Heat)); float minTempInBed = actor.def.GetStatValueAbstract(StatDefOf.ComfyTemperatureMin, null) - bed.GetStatValue(BedInsulationCold.Bed_Insulation_Cold, true); float maxTempInBed = actor.def.GetStatValueAbstract(StatDefOf.ComfyTemperatureMax, null) + bed.GetStatValue(BedInsulationHeat.Bed_Insulation_Heat, true); if (actor.AmbientTemperature < minTempInBed) { actor.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOf.SleptInCold, null); //Log.Message("Temperature is " + actor.AmbientTemperature + " and bed insulation is " + minTempInBed + ", so " + actor + " gains cold memory"); } if (actor.AmbientTemperature > maxTempInBed) { actor.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOf.SleptInHeat, null); //Log.Message("Temperature is " + actor.AmbientTemperature + " and bed insulation is " + maxTempInBed + ", so " + actor + " gains heat memory"); } //adapted for hospitality: if (bed != null && (hospitalityIsGuest || bed == actor.ownership.OwnedBed) && !bed.ForPrisoners && !actor.story.traits.HasTrait(TraitDefOf.Ascetic)) { ThoughtDef thoughtDef = null; Room room = bed.GetRoom(); //Correcting for Hospitality 1.0.25 if (hospitalityIsGuest) { bool hospitalityOnlyOneBed = room.ContainedBeds.Count() == 1; if (room.Role == DefDatabase <RoomRoleDef> .GetNamed("GuestRoom", true))// easier to replicate GuestUtility.roleDefGuestRoom than reflecting it! { thoughtDef = hospitalityOnlyOneBed ? ThoughtDefOf.SleptInBedroom : ThoughtDefOf.SleptInBarracks; } } else if (room.Role == RoomRoleDefOf.Bedroom) { thoughtDef = ThoughtDefOf.SleptInBedroom; } else if (room.Role == RoomRoleDefOf.Barracks) { thoughtDef = ThoughtDefOf.SleptInBarracks; } if (thoughtDef != null) { int scoreStageIndex = RoomStatDefOf.Impressiveness.GetScoreStageIndex(bed.GetRoom(RegionType.Set_Passable).GetStat(RoomStatDefOf.Impressiveness)); if (thoughtDef.stages[scoreStageIndex] != null) { actor.needs.mood.thoughts.memories.TryGainMemory(ThoughtMaker.MakeThought(thoughtDef, scoreStageIndex), null); } } } result = false; } return(result); }
public static void AddPsychRejectedThoughts(Pawn initiator, Pawn recipient) { if (PsycheHelper.PsychologyEnabled(initiator)) { ThoughtDef rejectedProposalDef = new ThoughtDef(); rejectedProposalDef.defName = "RejectedMyProposal" + initiator.LabelShort + Find.TickManager.TicksGame; rejectedProposalDef.durationDays = 60f * PsycheHelper.Comp(initiator).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Romantic); rejectedProposalDef.thoughtClass = typeof(Thought_MemorySocialDynamic); ThoughtStage rejectedProposalStage = new ThoughtStage(); rejectedProposalStage.label = "rejected my proposal"; rejectedProposalStage.baseOpinionOffset = Mathf.RoundToInt(-40f * PsycheHelper.Comp(initiator).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Romantic) * (PsychologyBase.ActivateKinsey() ? PsycheHelper.Comp(initiator).Sexuality.AdjustedRomanticDrive : 1f)); rejectedProposalDef.stages.Add(rejectedProposalStage); ThoughtDef rejectedProposalMoodDef = new ThoughtDef(); rejectedProposalMoodDef.defName = "RejectedMyProposalMood" + initiator.LabelShort + Find.TickManager.TicksGame; rejectedProposalMoodDef.durationDays = 25f; rejectedProposalMoodDef.thoughtClass = typeof(Thought_MemoryDynamic); rejectedProposalMoodDef.stackLimit = 999; rejectedProposalMoodDef.stackedEffectMultiplier = 1f; ThoughtStage rejectedProposalMoodStage = new ThoughtStage(); rejectedProposalMoodStage.label = "proposal rejected by {0}"; rejectedProposalMoodStage.baseMoodEffect = Mathf.RoundToInt(-25f * PsycheHelper.Comp(initiator).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Romantic) * Mathf.InverseLerp(100f, 5f, initiator.relations.OpinionOf(recipient))); if (rejectedProposalMoodStage.baseMoodEffect < -5f) { rejectedProposalMoodStage.description = "My lover isn't ready for that kind of commitment right now, and I understand, but rejection is hard to take."; } else { rejectedProposalMoodStage.description = "I can't believe I got turned down. Maybe we're not meant to be together after all?"; } rejectedProposalMoodDef.stages.Add(rejectedProposalMoodStage); if (rejectedProposalMoodStage.baseMoodEffect < 0f) { initiator.needs.mood.thoughts.memories.TryGainMemory(rejectedProposalMoodDef, recipient); } initiator.needs.mood.thoughts.memories.TryGainMemory(rejectedProposalDef, recipient); } else { initiator.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOf.RejectedMyProposal, recipient); } if (PsycheHelper.PsychologyEnabled(recipient)) { ThoughtDef rejectedTheirProposalDef = new ThoughtDef(); rejectedTheirProposalDef.defName = "IRejectedTheirProposal" + recipient.LabelShort + Find.TickManager.TicksGame; rejectedTheirProposalDef.durationDays = 60f * PsycheHelper.Comp(recipient).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Romantic); rejectedTheirProposalDef.thoughtClass = typeof(Thought_MemorySocialDynamic); ThoughtStage rejectedTheirProposalStage = new ThoughtStage(); rejectedTheirProposalStage.label = "I rejected their proposal"; rejectedTheirProposalStage.baseOpinionOffset = Mathf.RoundToInt(-30f * PsycheHelper.Comp(recipient).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Romantic) * (PsychologyBase.ActivateKinsey() ? 1.75f - PsycheHelper.Comp(recipient).Sexuality.AdjustedRomanticDrive : 1f)); rejectedTheirProposalDef.stages.Add(rejectedTheirProposalStage); ThoughtDef rejectedTheirProposalMoodDef = new ThoughtDef(); rejectedTheirProposalMoodDef.defName = "IRejectedTheirProposalMood" + recipient.LabelShort + Find.TickManager.TicksGame; rejectedTheirProposalMoodDef.durationDays = 25f; rejectedTheirProposalMoodDef.thoughtClass = typeof(Thought_MemoryDynamic); rejectedTheirProposalMoodDef.stackLimit = 999; rejectedTheirProposalMoodDef.stackedEffectMultiplier = 1f; ThoughtStage rejectedTheirProposalMoodStage = new ThoughtStage(); rejectedTheirProposalMoodStage.label = "rejected {0}'s proposal"; rejectedTheirProposalMoodStage.baseMoodEffect = Mathf.RoundToInt(-25f * PsycheHelper.Comp(recipient).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Romantic) * Mathf.InverseLerp(100f, 5f, recipient.relations.OpinionOf(initiator))); if (rejectedTheirProposalMoodStage.baseMoodEffect < -5f) { rejectedTheirProposalMoodStage.description = "I wish they wouldn't spring something like that on me."; } else { rejectedTheirProposalMoodStage.description = "I'm not ready for that kind of commitment. If they don't know that, maybe we're not meant to be together after all?"; } rejectedTheirProposalMoodDef.stages.Add(rejectedTheirProposalMoodStage); if (rejectedTheirProposalMoodStage.baseMoodEffect < 0f) { recipient.needs.mood.thoughts.memories.TryGainMemory(rejectedTheirProposalMoodDef, initiator); } recipient.needs.mood.thoughts.memories.TryGainMemory(rejectedTheirProposalDef, initiator); } else { recipient.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOf.IRejectedTheirProposal, initiator); } }
// // Methods // public void DoBirthSpawn(Pawn mother, Pawn father, float chance_successful = 1.0f) { if (mother == null) { Log.Error("No mother defined"); return; } if (father == null) { Log.Warning("No father defined"); } float birthing_quality = mother.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("GivingBirth")).TryGetComp <HediffComp_TendDuration> ().tendQuality; mother.health.AddHediff(HediffDef.Named("PostPregnancy"), null, null); mother.health.AddHediff(HediffDef.Named("Lactating"), ChildrenUtility.GetPawnBodyPart(pawn, "Torso"), null); int num = (mother.RaceProps.litterSizeCurve == null) ? 1 : Mathf.RoundToInt(Rand.ByCurve(mother.RaceProps.litterSizeCurve, 300)); if (num < 1) { num = 1; } // Make sure the pawn looks like mommy and daddy float skin_whiteness = Rand.Range(0, 1); // Pool of "genetic traits" the baby can inherit List <Trait> traitpool = new List <Trait>(); if (mother.RaceProps.Humanlike) { // Add mom's traits to the pool foreach (Trait momtrait in mother.story.traits.allTraits) { traitpool.Add(momtrait); } if (father != null) { // Add dad's traits to the pool foreach (Trait dadtrait in father.story.traits.allTraits) { traitpool.Add(dadtrait); } // Blend skin colour between mom and dad skin_whiteness = Rand.Range(mother.story.melanin, father.story.melanin); } else { // If dad doesn't exist, just use mom's skin colour skin_whiteness = mother.story.melanin; } // Clear out any traits that aren't genetic from the list if (traitpool.Count > 0) { foreach (Trait trait in traitpool.ToArray()) { bool is_genetic = false; foreach (TraitDef gentrait in genetic_traits) { if (gentrait.defName == trait.def.defName) { is_genetic = true; } } if (!is_genetic) { traitpool.Remove(trait); } } } } // Surname passing string last_name = null; if (mother.RaceProps.Humanlike) { if (father == null) { last_name = NameTriple.FromString(mother.Name.ToStringFull).Last; } else { last_name = NameTriple.FromString(father.Name.ToStringFull).Last; } //Log.Message ("Debug: Newborn is born to the " + last_name + " family."); } //PawnGenerationRequest request = new PawnGenerationRequest (mother.kindDef, mother.Faction, PawnGenerationContext.NonPlayer, mother.Map, false, true, false, false, true, false, 1, false, true, true, null, 0, 0, null, skin_whiteness, last_name); PawnGenerationRequest request = new PawnGenerationRequest(mother.kindDef, mother.Faction, PawnGenerationContext.NonPlayer, mother.Map.Tile, false, true, false, false, false, false, 1, false, true, true, false, false, null, 0, 0, null, skin_whiteness, last_name); Pawn baby = null; for (int i = 0; i < num; i++) { baby = PawnGenerator.GeneratePawn(request); if (PawnUtility.TrySpawnHatchedOrBornPawn(baby, mother)) { if (baby.playerSettings != null && mother.playerSettings != null) { baby.playerSettings.AreaRestriction = mother.playerSettings.AreaRestriction; } if (baby.RaceProps.IsFlesh) { baby.relations.AddDirectRelation(PawnRelationDefOf.Parent, mother); if (father != null) { baby.relations.AddDirectRelation(PawnRelationDefOf.Parent, father); } } // Good until otherwise proven bad bool successful_birth = true; var disabledBaby = BackstoryDatabase.allBackstories ["CustomBackstory_NA_Childhood_Disabled"]; if (disabledBaby != null) { baby.story.childhood = disabledBaby; } else { Log.Error("Couldn't find the required Backstory: CustomBackstory_NA_Childhood_Disabled!"); baby.story.childhood = null; } baby.story.adulthood = null; baby.workSettings.Disable(WorkTypeDefOf.Hunting); //hushes up the "has no ranged weapon" alert // remove all traits baby.story.traits.allTraits.Clear(); // Add some genetic traits if (traitpool.Count > 0) { for (int j = 0; j != 2; j++) { Trait gentrait = traitpool.RandomElement(); if (!baby.story.traits.HasTrait(gentrait.def)) { baby.story.traits.GainTrait(gentrait); } } } // Move the baby in front of the mother, rather than on top if (mother.CurrentBed() != null) { baby.Position = baby.Position + new IntVec3(0, 0, 1).RotatedBy(mother.CurrentBed().Rotation); } // else // baby.Position = baby.Position + new IntVec3 (0, 0, 1).RotatedBy (mother.Rotation); // The baby died from bad chance of success if (Rand.Value > chance_successful || chance_successful == 0) { successful_birth = false; } // Birth defects via drugs or alcohol if (mother.health.hediffSet.HasHediff(HediffDef.Named("BirthDefectTracker"))) { Hediff_BirthDefectTracker tracker = (Hediff_BirthDefectTracker)mother.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("BirthDefectTracker")); // The baby died in utero from chemical affect if (tracker.stillbirth) { successful_birth = false; } // The baby lived! So far, anyways else { // Should the baby get fetal alcohol syndrome? if (tracker.fetal_alcohol) { baby.health.AddHediff(HediffDef.Named("FetalAlcoholSyndrome")); } // If the mother got high while pregnant, crongrats retard // now your baby is addicted to crack if (tracker.drug_addictions.Count > 0) { foreach (HediffDef addiction in tracker.drug_addictions) { baby.health.AddHediff(addiction, null, null); } } } } if (father != null) { // Inbred? if (mother.relations.FamilyByBlood.Contains <Pawn> (father)) { // 50% chance to get a birth defect from inbreeding if (Rand.Range(0, 1) == 1) { GiveRandomBirthDefect(baby); if (baby.health.hediffSet.HasHediff(HediffDef.Named("DefectStillborn"))) { successful_birth = false; } } } if (successful_birth == true) { // The father is happy the baby was born //father.needs.mood.thoughts.memories.TryGainMemoryThought (ThoughtDef.Named ("PartnerGaveBirth")); father.needs.mood.thoughts.memories.TryGainMemory(ThoughtDef.Named("PartnerGaveBirth")); } } // The baby was born! Yay! if (successful_birth == true) { // Send a message that the baby was born if (mother.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("HumanPregnancy")).Visible&& PawnUtility.ShouldSendNotificationAbout(mother)) { //Messages.Message ("MessageGaveBirth".Translate (new object[] {mother.LabelIndefinite ()}).CapitalizeFirst (), mother, MessageSound.Benefit); Find.LetterStack.ReceiveLetter("LabelGaveBirth".Translate(new object[] { baby.LabelIndefinite() }), "MessageHumanBirth".Translate(new object[] { mother.LabelIndefinite(), baby.Name.ToStringShort }), LetterDefOf.Good, baby, null); } // Try to give PPD. If not, give "New baby" thought float chance = 0.2f; if (mother.story.traits.HasTrait(TraitDefOf.Psychopath)) { chance -= 1; } if (mother.story.traits.HasTrait(TraitDef.Named("Nerves"))) { chance -= 0.2f * mother.story.traits.GetTrait(TraitDef.Named("Nerves")).Degree; } else if (mother.story.traits.HasTrait(TraitDef.Named("NaturalMood"))) { if (mother.story.traits.GetTrait(TraitDef.Named("NaturalMood")).Degree == 2) { chance -= 1; } if (mother.story.traits.GetTrait(TraitDef.Named("NaturalMood")).Degree == -2) { chance += 0.6f; } // For some reason this is broken /*} else if (mother.story.traits.HasTrait (TraitDef.Named ("Neurotic"))) { * if (mother.story.traits.GetTrait (TraitDef.Named ("Neurotic")).Degree == 1) { * chance += 0.2f; * } else * chance += 0.4f;*/ } // Because for whatever dumb reason the Math class doesn't have a Clamp method if (chance < 0) { chance = 0; } if (chance > 1) { chance = 1; } Log.Message("Debugging: Chance of PPD is " + chance * 100 + "%"); // Try to give PPD if (Rand.Value < chance) { mother.needs.mood.thoughts.memories.TryGainMemory(ThoughtDef.Named("PostPartumDepression"), null); bool verybad = false; if (mother.story.traits.HasTrait(TraitDef.Named("NaturalMood"))) { if (mother.story.traits.GetTrait(TraitDef.Named("NaturalMood")).Degree == -2) { verybad = true; } } else if (mother.story.traits.HasTrait(TraitDef.Named("Neurotic"))) { if (mother.story.traits.GetTrait(TraitDef.Named("Neurotic")).Degree == 2) { verybad = true; } } // This pawn gets an exceptionally bad case of PPD if (verybad) { foreach (Thought_Memory thought in mother.needs.mood.thoughts.memories.Memories) { if (thought.def.defName == "PostPartumDepression") { thought.SetForcedStage(thought.CurStageIndex + 1); } } } } else { // If we didn't get PPD, then the pawn gets a mood buff if (mother.health.hediffSet.HasHediff(HediffDef.Named("GaveBirthFlag")) == false) { mother.needs.mood.thoughts.memories.TryGainMemory(ThoughtDef.Named("IGaveBirthFirstTime")); } else { mother.needs.mood.thoughts.memories.TryGainMemory(ThoughtDef.Named("IGaveBirth")); } } } // The birth was not successful if (successful_birth == false) { bool aborted = false; if (chance_successful < 0f) { aborted = true; } if (baby != null) { Miscarry(baby, aborted); } } } else { Find.WorldPawns.PassToWorld(baby, PawnDiscardDecideMode.Discard); } } if (mother.Spawned) { // Spawn guck FilthMaker.MakeFilth(mother.Position, mother.Map, ThingDefOf.FilthAmnioticFluid, mother.LabelIndefinite(), 5); if (mother.caller != null) { mother.caller.DoCall(); } if (baby != null) { if (baby.caller != null) { baby.caller.DoCall(); } } Log.Message("Birth quality = " + birthing_quality); // Possible tearing from pregnancy if (birthing_quality < 0.75f) { if (birthing_quality < Rand.Value) { // Add a tear from giving birth if (birthing_quality < Rand.Value) { mother.health.AddHediff(HediffDef.Named("PregnancyTearMajor"), ChildrenUtility.GetPawnBodyPart(mother, "Torso"), null); } else { mother.health.AddHediff(HediffDef.Named("PregnancyTear"), ChildrenUtility.GetPawnBodyPart(mother, "Torso"), null); } } } } pawn.health.RemoveHediff(pawn.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("GivingBirth"))); pawn.health.RemoveHediff(this); }
public static void addMemory(Pawn p, ThoughtDef thoughtDef) { p.needs.mood.thoughts.memories.TryGainMemory(thoughtDef); }
public override void DefsLoaded() { if (ModIsActive) { /* Mod settings */ toggleEmpathy = Settings.GetHandle <bool>("EnableEmpathy", "EmpathyChangesTitle".Translate(), "EmpathyChangesTooltip".Translate(), true); toggleKinsey = Settings.GetHandle <bool>("EnableSexuality", "SexualityChangesTitle".Translate(), "SexualityChangesTooltip".Translate(), true); kinseyMode = Settings.GetHandle <KinseyMode>("KinseyMode", "KinseyModeTitle".Translate(), "KinseyModeTooltip".Translate(), KinseyMode.Realistic, null, "KinseyMode_"); toggleIndividuality = Settings.GetHandle <bool>("EnableIndividuality", "IndividualityTitle".Translate(), "IndividualityTooltip".Translate(), true); toggleElections = Settings.GetHandle <bool>("EnableElections", "ElectionsTitle".Translate(), "ElectionsTooltip".Translate(), true); conversationDuration = Settings.GetHandle <float>("ConversationDuration", "DurationTitle".Translate(), "DurationTooltip".Translate(), 60f, (String s) => float.Parse(s) >= 15f && float.Parse(s) <= 180f); toggleDateLetters = Settings.GetHandle <bool>("SendDateLetters", "SendDateLettersTitle".Translate(), "SendDateLettersTooltip".Translate(), true); toggleBenchmarking = Settings.GetHandle <bool>("Benchmarking", "BenchmarkingTitle".Translate(), "BenchmarkingTooltip".Translate(), false); kinsey = toggleKinsey.Value; notBabyMode = toggleIndividuality.Value; elections = toggleElections.Value; dateLetters = toggleDateLetters.Value; benchmark = toggleBenchmarking.Value; convoDuration = conversationDuration.Value; if (PsychologyBase.ActivateKinsey()) { mode = kinseyMode.Value; } /* Mod conflict detection */ TraitDef bisexual = DefDatabase <TraitDef> .GetNamedSilentFail("Bisexual"); TraitDef asexual = DefDatabase <TraitDef> .GetNamedSilentFail("Asexual"); if (bisexual != null || asexual != null || !toggleKinsey) { if (toggleKinsey) { Logger.Message("KinseyDisable".Translate()); } kinsey = false; } /* Conditional vanilla Def edits */ ThoughtDef knowGuestExecuted = AddNullifyingTraits("KnowGuestExecuted", new TraitDef[] { TraitDefOfPsychology.BleedingHeart }); if (knowGuestExecuted != null && toggleEmpathy) { knowGuestExecuted = ModifyThoughtStages(knowGuestExecuted, new int[] { -1, -2, -4, -5 }); } ThoughtDef knowColonistExecuted = AddNullifyingTraits("KnowColonistExecuted", new TraitDef[] { TraitDefOfPsychology.BleedingHeart }); if (knowColonistExecuted != null && toggleEmpathy) { knowColonistExecuted = ModifyThoughtStages(knowColonistExecuted, new int[] { -1, -2, -4, -5 }); } ThoughtDef knowPrisonerDiedInnocent = AddNullifyingTraits("KnowPrisonerDiedInnocent", new TraitDef[] { TraitDefOfPsychology.BleedingHeart }); if (knowPrisonerDiedInnocent != null && toggleEmpathy) { knowPrisonerDiedInnocent = ModifyThoughtStages(knowPrisonerDiedInnocent, new int[] { -4 }); } ThoughtDef knowColonistDied = AddNullifyingTraits("KnowColonistDied", new TraitDef[] { TraitDefOfPsychology.BleedingHeart }); if (knowColonistDied != null && toggleEmpathy) { knowColonistDied = ModifyThoughtStages(knowColonistDied, new int[] { -2 }); } ThoughtDef colonistAbandoned = AddNullifyingTraits("ColonistBanished", new TraitDef[] { TraitDefOfPsychology.BleedingHeart }); if (colonistAbandoned != null && toggleEmpathy) { colonistAbandoned = ModifyThoughtStages(colonistAbandoned, new int[] { -2 }); } ThoughtDef colonistAbandonedToDie = AddNullifyingTraits("ColonistBanishedToDie", new TraitDef[] { TraitDefOfPsychology.BleedingHeart }); if (colonistAbandonedToDie != null && toggleEmpathy) { colonistAbandonedToDie = ModifyThoughtStages(colonistAbandonedToDie, new int[] { -4 }); } ThoughtDef prisonerAbandonedToDie = AddNullifyingTraits("PrisonerBanishedToDie", new TraitDef[] { TraitDefOfPsychology.BleedingHeart }); if (prisonerAbandonedToDie != null && toggleEmpathy) { prisonerAbandonedToDie = ModifyThoughtStages(prisonerAbandonedToDie, new int[] { -3 }); } ThoughtDef knowPrisonerSold = AddNullifyingTraits("KnowPrisonerSold", new TraitDef[] { TraitDefOfPsychology.BleedingHeart }); if (knowPrisonerSold != null && toggleEmpathy) { knowPrisonerSold = ModifyThoughtStages(knowPrisonerSold, new int[] { -4 }); } ThoughtDef knowGuestOrganHarvested = AddNullifyingTraits("KnowGuestOrganHarvested", new TraitDef[] { TraitDefOfPsychology.BleedingHeart }); if (knowGuestOrganHarvested != null && toggleEmpathy) { knowGuestOrganHarvested = ModifyThoughtStages(knowGuestOrganHarvested, new int[] { -4 }); } ThoughtDef knowColonistOrganHarvested = AddNullifyingTraits("KnowColonistOrganHarvested", new TraitDef[] { TraitDefOfPsychology.BleedingHeart }); if (knowColonistOrganHarvested != null && toggleEmpathy) { knowColonistOrganHarvested = ModifyThoughtStages(knowColonistOrganHarvested, new int[] { -4 }); } ThoughtDef beauty = AddNullifyingTraits("KnowColonistOrganHarvested", new TraitDef[] { TraitDefOfPsychology.BleedingHeart }); if (knowColonistOrganHarvested != null && toggleEmpathy) { knowColonistOrganHarvested = ModifyThoughtStages(knowColonistOrganHarvested, new int[] { -4 }); } /* ThingDef injection reworked by notfood */ var zombieThinkTree = DefDatabase <ThinkTreeDef> .GetNamedSilentFail("Zombie"); IEnumerable <ThingDef> things = ( from def in DefDatabase <ThingDef> .AllDefs where typeof(Pawn).IsAssignableFrom(def.thingClass) && def.race?.intelligence == Intelligence.Humanlike && !def.defName.Contains("AIPawn") && (zombieThinkTree == null || def.race.thinkTreeMain != zombieThinkTree) select def ); List <string> registered = new List <string>(); foreach (ThingDef t in things) { if (t.inspectorTabsResolved == null) { t.inspectorTabsResolved = new List <InspectTabBase>(1); } t.inspectorTabsResolved.Add(InspectTabManager.GetSharedInstance(typeof(ITab_Pawn_Psyche))); if (t.recipes == null) { t.recipes = new List <RecipeDef>(6); } t.recipes.Add(RecipeDefOfPsychology.TreatPyromania); t.recipes.Add(RecipeDefOfPsychology.TreatChemicalInterest); t.recipes.Add(RecipeDefOfPsychology.TreatChemicalFascination); t.recipes.Add(RecipeDefOfPsychology.TreatDepression); t.recipes.Add(RecipeDefOfPsychology.TreatInsomnia); t.recipes.Add(RecipeDefOfPsychology.CureAnxiety); if (t.comps == null) { t.comps = new List <CompProperties>(1); } t.comps.Add(new CompProperties_Psychology()); if (!t.race.hediffGiverSets.NullOrEmpty()) { if (t.race.hediffGiverSets.Contains(DefDatabase <HediffGiverSetDef> .GetNamed("OrganicStandard"))) { t.race.hediffGiverSets.Add(DefDatabase <HediffGiverSetDef> .GetNamed("OrganicPsychology")); } } registered.Add(t.defName); } if (Prefs.DevMode && Prefs.LogVerbose) { Log.Message("Psychology :: Registered " + string.Join(", ", registered.ToArray())); } /* * Now to enjoy the benefits of having made a popular mod! * This will be our little secret. */ Traverse.Create(child).Field("bodyTypeMale").SetValue("Male"); Traverse.Create(child).Field("bodyTypeFemale").SetValue("Female"); child.slot = BackstorySlot.Childhood; child.SetTitle("Child soldier", "Child soldier"); child.SetTitleShort("Scout", "Scout"); child.baseDesc = "[PAWN_nameDef] was born into a dictatorial outlander society on a nearby rimworld. Their chief export was war, and [PAWN_pronoun] was conscripted at a young age into the military to serve as a scout due to [PAWN_possessive] runner's build. [PAWN_pronoun] learned how to use a gun, patch wounds on the battlefield, and communicate with [PAWN_possessive] squad. It was there [PAWN_pronoun] earned [PAWN_possessive] nickname."; Traverse.Create(child).Field("skillGains").GetValue <Dictionary <string, int> >().Add("Shooting", 4); Traverse.Create(child).Field("skillGains").GetValue <Dictionary <string, int> >().Add("Medicine", 2); Traverse.Create(child).Field("skillGains").GetValue <Dictionary <string, int> >().Add("Social", 1); child.requiredWorkTags = WorkTags.Violent; child.shuffleable = false; child.PostLoad(); child.ResolveReferences(); Backstory adultMale = new Backstory(); Traverse.Create(adultMale).Field("bodyTypeMale").SetValue("Male"); Traverse.Create(adultMale).Field("bodyTypeFemale").SetValue("Female"); adultMale.slot = BackstorySlot.Adulthood; adultMale.SetTitle("Missing in action", "Missing in action"); adultMale.SetTitleShort("Ex-P.O.W.", "Ex-P.O.W."); adultMale.baseDesc = "Eventually, [PAWN_pronoun] was captured on a mission by one of [PAWN_possessive] faction's many enemies. [PAWN_pronoun] was tortured for information, the techniques of which [PAWN_pronoun] never forgot. When they could get no more out of [PAWN_objective], [PAWN_pronoun] was sent to a prison camp, where [PAWN_pronoun] worked for years before staging an escape and fleeing into civilization."; Traverse.Create(adultMale).Field("skillGains").GetValue <Dictionary <string, int> >().Add("Crafting", 4); Traverse.Create(adultMale).Field("skillGains").GetValue <Dictionary <string, int> >().Add("Construction", 3); Traverse.Create(adultMale).Field("skillGains").GetValue <Dictionary <string, int> >().Add("Mining", 2); Traverse.Create(adultMale).Field("skillGains").GetValue <Dictionary <string, int> >().Add("Social", 1); adultMale.spawnCategories = new List <string>(); adultMale.spawnCategories.AddRange(new string[] { "Civil", "Raider", "Slave", "Trader", "Traveler" }); adultMale.shuffleable = false; adultMale.PostLoad(); adultMale.ResolveReferences(); Backstory adultFemale = new Backstory(); Traverse.Create(adultFemale).Field("bodyTypeMale").SetValue("Male"); Traverse.Create(adultFemale).Field("bodyTypeFemale").SetValue("Female"); adultFemale.slot = BackstorySlot.Adulthood; adultFemale.SetTitle("Battlefield medic", "Battlefield medic"); adultFemale.SetTitleShort("Medic", "Medic"); adultFemale.baseDesc = "[PAWN_pronoun] continued to serve in the military, being promoted through the ranks as [PAWN_possessive] skill increased. [PAWN_pronoun] learned how to treat more serious wounds as [PAWN_possessive] role slowly transitioned from scout to medic, as well as how to make good use of army rations. [PAWN_pronoun] built good rapport with [PAWN_possessive] squad as a result."; Traverse.Create(adultFemale).Field("skillGains").GetValue <Dictionary <string, int> >().Add("Shooting", 4); Traverse.Create(adultFemale).Field("skillGains").GetValue <Dictionary <string, int> >().Add("Medicine", 3); Traverse.Create(adultFemale).Field("skillGains").GetValue <Dictionary <string, int> >().Add("Cooking", 2); Traverse.Create(adultFemale).Field("skillGains").GetValue <Dictionary <string, int> >().Add("Social", 1); adultFemale.spawnCategories = new List <string>(); adultFemale.spawnCategories.AddRange(new string[] { "Civil", "Raider", "Slave", "Trader", "Traveler" }); adultFemale.shuffleable = false; adultFemale.PostLoad(); adultFemale.ResolveReferences(); PawnBio male = new PawnBio(); male.childhood = child; male.adulthood = adultMale; male.gender = GenderPossibility.Male; male.name = NameTriple.FromString("Jason 'Jackal' Tarai"); male.PostLoad(); SolidBioDatabase.allBios.Add(male); PawnBio female = new PawnBio(); female.childhood = child; female.adulthood = adultFemale; female.gender = GenderPossibility.Female; female.name = NameTriple.FromString("Elizabeth 'Eagle' Tarai"); female.PostLoad(); SolidBioDatabase.allBios.Add(female); BackstoryDatabase.AddBackstory(child); BackstoryDatabase.AddBackstory(adultMale); BackstoryDatabase.AddBackstory(adultFemale); } }
public static void GiveMood(Pawn pawn, ThoughtDef Tdef) { pawn.needs.mood.thoughts.TryGainThought(Tdef); }