private void AddAspect(Pawn p) { AspectTracker aspectTracker = p.GetAspectTracker(); if (aspectTracker == null) { return; } var aspect = aspectTracker.GetAspect(aspectDef); if (aspect == null) { aspectTracker.Add(aspectDef, stageIndex); } }
private List <DebugMenuOption> GetAddAspectOptions(Pawn pawn) { AspectTracker tracker = pawn.GetAspectTracker(); var outLst = new List <DebugMenuOption>(); foreach (AspectDef aspectDef in DefDatabase <AspectDef> .AllDefs.Where(d => !tracker.Contains(d)) ) //don't allow aspects to be added more then once { AspectDef tmpDef = aspectDef; outLst.Add(new DebugMenuOption($"{aspectDef.defName}", DebugMenuOptionMode.Action, () => Find.WindowStack .Add(new Dialog_DebugOptionListLister(GetAddAspectOptions(tmpDef, pawn))))); } return(outLst); }
private List <DebugMenuOption> GetRemoveAspectOptions(Pawn p) { var outLst = new List <DebugMenuOption>(); AspectTracker aspectTracker = p.GetAspectTracker(); if (aspectTracker == null) { return(outLst); } foreach (Aspect aspect in aspectTracker.Aspects.ToList()) { Aspect tmpAspect = aspect; outLst.Add(new DebugMenuOption($"{aspect.Label}", DebugMenuOptionMode.Action, () => aspectTracker.Remove(tmpAspect))); } return(outLst); }
/// <summary> /// checks if the given pawn passes the restriction. /// </summary> /// <param name="pawn">The pawn.</param> /// <returns> /// if the def can be used with the given pawn /// </returns> /// <exception cref="ArgumentNullException">pawn</exception> protected override bool PassesRestrictionImpl(Pawn pawn) { if (pawn == null) { throw new ArgumentNullException(nameof(pawn)); } bool hasAspect; AspectTracker tracker = pawn.GetAspectTracker(); if (tracker == null) { hasAspect = false; //no tracker, then they cannot have an aspect } else { hasAspect = false; foreach (Aspect aspect in tracker) { List <int> indexLst = GetStagesForAspect(aspect.def); if (indexLst == null) { continue; } if (indexLst.Any(i => i < 0)) { hasAspect = true; break; } if (indexLst.Contains(aspect.StageIndex)) { hasAspect = true; break; } } } return(hasAspect); }
void AddOutlook(MutationOutlook mOutlook) { TraitSet st = Pawn.story?.traits; AspectTracker at = Pawn.GetAspectTracker(); if (st == null) { return; } if (at == null) { return; } switch (mOutlook) { case MutationOutlook.Neutral: return; case MutationOutlook.Furry: st.GainTrait(new Trait(PMTraitDefOf.MutationAffinity, 0, true)); break; case MutationOutlook.BodyPurist: st.GainTrait(new Trait(TraitDefOf.BodyPurist, 0, true)); break; case MutationOutlook.PrimalWish: at.Add(AspectDefOf.PrimalWish); break; default: throw new ArgumentOutOfRangeException(nameof(mOutlook), mOutlook, null); } }
/// <summary> /// safely change the pawns race /// </summary> /// <param name="pawn"></param> /// <param name="race"></param> /// <param name="reRollTraits">if race related traits should be reRolled</param> public static void ChangePawnRace([NotNull] Pawn pawn, ThingDef race, bool reRollTraits = false) { if (pawn == null) { throw new ArgumentNullException(nameof(pawn)); } MorphDef oldMorph = pawn.def.GetMorphOfRace(); ThingDef oldRace = pawn.def; AspectTracker aTracker = pawn.GetAspectTracker(); AspectDef oldMorphAspectDef = oldMorph?.group?.aspectDef; if (oldMorphAspectDef != null && aTracker != null) { Aspect aspect = aTracker.GetAspect(oldMorphAspectDef); if (aspect != null) { aTracker.Remove(aspect); } } //var pos = pawn.Position; Faction faction = pawn.Faction; Map map = pawn.Map; if (map != null) { RegionListersUpdater.DeregisterInRegions(pawn, map); } var removed = false; if (map != null) { if (map.listerThings.Contains(pawn)) { map.listerThings.Remove(pawn); //make sure to update the lister things or else dying will break removed = true; } } pawn.def = race; if (removed && !map.listerThings.Contains(pawn)) { map.listerThings.Add(pawn); } if (map != null) { RegionListersUpdater.RegisterInRegions(pawn, map); } map?.mapPawns.UpdateRegistryForPawn(pawn); //add the group hediff if applicable AspectDef aspectDef = race.GetMorphOfRace()?.group?.aspectDef; if (aspectDef != null) { aTracker?.Add(aspectDef); } if (map != null) { var comp = map.GetComponent <MorphTracker>(); comp.NotifyPawnRaceChanged(pawn, oldMorph); } //no idea what HarmonyPatches.Patch.ChangeBodyType is for, not listed in pasterbin pawn.RefreshGraphics(); if (reRollTraits && race is ThingDef_AlienRace alienDef) { ReRollRaceTraits(pawn, alienDef); } //save location if (Current.ProgramState == ProgramState.Playing) { pawn.ExposeData(); } if (pawn.Faction != faction) { pawn.SetFaction(faction); } foreach (IRaceChangeEventReceiver raceChangeEventReceiver in pawn.AllComps.OfType <IRaceChangeEventReceiver>()) { raceChangeEventReceiver.OnRaceChange(oldRace); } }
/// <summary> /// safely change the pawns race /// </summary> /// <param name="pawn">The pawn.</param> /// <param name="race">The race.</param> /// <param name="reRollTraits">if race related traits should be reRolled</param> /// <exception cref="ArgumentNullException">pawn</exception> public static void ChangePawnRace([NotNull] Pawn pawn, [NotNull] ThingDef race, bool reRollTraits = false) { if (pawn == null) { throw new ArgumentNullException(nameof(pawn)); } if (race == null) { throw new ArgumentNullException(nameof(race)); } MorphDef oldMorph = pawn.def.GetMorphOfRace(); ThingDef oldRace = pawn.def; AspectTracker aTracker = pawn.GetAspectTracker(); AspectDef oldMorphAspectDef = oldMorph?.group?.aspectDef; if (oldMorphAspectDef != null && aTracker != null) { Aspect aspect = aTracker.GetAspect(oldMorphAspectDef); if (aspect != null) { aTracker.Remove(aspect); } } TransformerUtility.ScaleInjuriesToNewRace(pawn, race); //var pos = pawn.Position; Faction faction = pawn.Faction; Map map = pawn.Map; if (map != null) { RegionListersUpdater.DeregisterInRegions(pawn, map); } var removed = false; if (map?.listerThings != null) { if (map.listerThings.Contains(pawn)) { map.listerThings.Remove(pawn); //make sure to update the lister things or else dying will break removed = true; } } pawn.def = race; if (removed && !map.listerThings.Contains(pawn)) { map.listerThings.Add(pawn); } if (map != null) { RegionListersUpdater.RegisterInRegions(pawn, map); } map?.mapPawns.UpdateRegistryForPawn(pawn); //add the group hediff if applicable AspectDef aspectDef = race.GetMorphOfRace()?.group?.aspectDef; if (aspectDef != null) { aTracker?.Add(aspectDef); } if (map != null) { var comp = map.GetComponent <MorphTracker>(); comp.NotifyPawnRaceChanged(pawn, oldMorph); } //always revert to human settings first so the race change is consistent ValidateReversion(pawn); //check if the body def changed and handle any apparel changes if (oldRace.race.body != race.race.body) { ValidateApparelForChangedPawn(pawn, oldRace); } if (race != ThingDefOf.Human) { ValidateExplicitRaceChange(pawn, race, oldRace); } var mTracker = pawn.GetComp <MorphTrackingComp>(); if (mTracker == null) { Warning($"changing the race of {pawn.Name} but they have no {nameof(MorphTrackingComp)}!"); } else { mTracker.needsRaceCompCheck = true; } //no idea what HarmonyPatches.Patch.ChangeBodyType is for, not listed in pasterbin pawn.RefreshGraphics(); if (reRollTraits && race is ThingDef_AlienRace alienDef) { ReRollRaceTraits(pawn, alienDef); } //save location if (Current.ProgramState == ProgramState.Playing) { pawn.ExposeData(); } if (pawn.Faction != faction) { pawn.SetFaction(faction); } foreach (IRaceChangeEventReceiver raceChangeEventReceiver in pawn.AllComps.OfType <IRaceChangeEventReceiver>()) { raceChangeEventReceiver.OnRaceChange(oldRace); } }