コード例 #1
0
        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);
            }
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        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);
        }
コード例 #4
0
        /// <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);
        }
コード例 #5
0
        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);
            }
        }
コード例 #6
0
        /// <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);
            }
        }
コード例 #7
0
        /// <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);
            }
        }