private void TransformPawn(ThingDef @into, PawnKindDef intoKind) { Log.Message("Performing Transform on " + pawn + " to a " + into + "with a kind of " + intoKind); if (into == null || into == pawn.def) { return; } var map = pawn.Map; RegionListersUpdater.DeregisterInRegions(pawn, map); pawn.def = into; pawn.ChangeKind(intoKind); RegionListersUpdater.RegisterInRegions(pawn, map); map.mapPawns.UpdateRegistryForPawn(pawn); //save the pawn pawn.ExposeData(); //magic to make image change pawn.ageTracker.AgeBiologicalTicks = pawn.ageTracker.AgeBiologicalTicks - 1; //pawn.SpawnSetup(map, true); didIt = true; }
private void TransformPawn(bool changeDef = true, bool keep = false) { IntVec3 where = pawn.Position; Map map = pawn.Map; //Body change to Astarte pawn.DeSpawn(); // pawn.DestroyOrPassToWorld(); RegionListersUpdater.DeregisterInRegions(pawn, map); var thingDef = PawnThingDef(); if (changeDef && thingDef != null) { HediffSet set = pawn.health.hediffSet; pawn.def = thingDef; pawn.health = new Pawn_HealthTracker(pawn); pawn.health.hediffSet.DirtyCache(); pawn.health.hediffSet = set; } // pawn.SpawnSetup(map, true); RegionListersUpdater.RegisterInRegions(pawn, map); map.mapPawns.UpdateRegistryForPawn(pawn); //remove the 19 if (BlowOffParts(keep)) { RemoveAstarteParts(); } //decache graphics pawn.Drawer.renderer.graphics.ResolveAllGraphics(); //save the pawn pawn.ExposeData(); GenSpawn.Spawn(pawn, where, map); // pawn.Position = map.Center; }
private void TransformPawn(bool changeDef = true, bool keep = false) { //Body change to Astarte var where = pawn.Position; var map = pawn.Map; pawn.DestroyOrPassToWorld(); pawn.DeSpawn(); RegionListersUpdater.DeregisterInRegions(pawn, map); var thingDef = PawnThingDef(); if (changeDef && thingDef != null) { pawn.def = thingDef; } pawn.SpawnSetup(map, true); RegionListersUpdater.RegisterInRegions(pawn, map); map.mapPawns.UpdateRegistryForPawn(pawn); //remove the 19 if (BlowOffParts(keep)) { RemoveAstarteParts(); } //decache graphics pawn.Drawer.renderer.graphics.ResolveAllGraphics(); //save the pawn pawn.ExposeData(); pawn.Position = map.Center; }
private void TransformPawn(bool changeDef = true, bool keep = false) { //sets position, faction and map IntVec3 intv = Pawn.Position; Faction faction = Pawn.Faction; Map map = Pawn.Map; RegionListersUpdater.DeregisterInRegions(Pawn, map); //Change Race to Props.raceDef if (changeDef && alienRace != null && alienRace != Pawn.def) { Pawn.def = alienRace; long ageB = Pawn.ageTracker.AgeBiologicalTicks; long ageC = Pawn.ageTracker.AgeChronologicalTicks; Pawn.ageTracker = new Pawn_AgeTracker(Pawn); Pawn.ageTracker.AgeBiologicalTicks = ageB; Pawn.ageTracker.AgeChronologicalTicks = ageC; if (!Pawn.RaceProps.hasGenders) { Pawn.gender = Gender.None; } if (Props.removeHair) { // Pawn.story.hairDef = DefDatabase<HairDef>.GetNamed("Shaved", true); Pawn.story.hairDef = PawnHairChooser.RandomHairDefFor(Pawn, noHairFaction); // Pawn.Drawer.renderer.graphics.hairGraphic; } else { if (Props.colourHairTwo || Props.colourHair) { if (compAlien != null) { ColorChannelGenerator Alienhair = alienRace.alienRace.generalSettings.alienPartGenerator.colorChannels.Find(x => x.name == "hair"); AlienPartGenerator.ExposableValueTuple <UnityEngine.Color, UnityEngine.Color> hair; if (compAlien.ColorChannels.TryGetValue("hair", out hair)) { if (Props.colourHair && Alienhair?.first != null) { hair.first = Alienhair.first.NewRandomizedColor(); } if (Props.colourHairTwo && Alienhair?.second != null) { hair.second = Alienhair.second.NewRandomizedColor(); } compAlien.ColorChannels.SetOrAdd("hair", hair); } Pawn.Notify_ColorChanged(); } } } //Change BodyType to Props.bodyTypeDef if (Props.changeBody) { if (Props.bodyTypeDef != null) { ChangeBodyType(Pawn, Props.bodyTypeDef); } else { ChangeBodyType(Pawn, alienRace.alienRace.generalSettings.alienPartGenerator.alienbodytypes[Rand.Range(0, alienRace.alienRace.generalSettings.alienPartGenerator.alienbodytypes.Count)]); } } } //Remove Disallowed Traits int maxTraits; if (MoreTraitSlotsUtil.TryGetMaxTraitSlots(out int max)) { maxTraits = max; } else { maxTraits = 4; } if (!Props.traitsToRemove.NullOrEmpty()) { if (Pawn.story.traits.allTraits.Any(x => Props.traitsToRemove.Any(y => y.def == x.def))) { foreach (ExtendedTraitEntry item in Props.traitsToRemove) { if (Pawn.story.traits.HasTrait(item.def)) { Rand.PushState(); if (Rand.Chance(item.Chance)) { Pawn.story.traits.allTraits.Remove(Pawn.story.traits.allTraits.Find(x => x.def == item.def)); } Rand.PopState(); } } } } if (!Props.traitsToAdd.NullOrEmpty()) { if (Props.traitsToAdd.Any(x => !Pawn.story.traits.HasTrait(x.def))) { foreach (ExtendedTraitEntry item in Props.traitsToAdd) { if (!Pawn.story.traits.HasTrait(item.def)) { Rand.PushState(); if (Rand.Chance(item.Chance)) { bool replace = false; int countTraits = Pawn.story.traits.allTraits.Count; if (countTraits >= maxTraits) { replace = true; } // Log.Message(string.Format("i have {0} of a max of {1} traits", countTraits, maxTraits)); Trait replacedTrait = Pawn.story.traits.allTraits.Where(x => Props.traitsToAdd.Any(y => y.def != x.def)).RandomElement(); if (replace) { Pawn.story.traits.allTraits.Remove(replacedTrait); } Pawn.story.traits.allTraits.Add(new Trait(item.def, item.degree)); } Rand.PopState(); } } } } RegionListersUpdater.RegisterInRegions(Pawn, map); map.mapPawns.UpdateRegistryForPawn(Pawn); //decache graphics Pawn.Drawer.renderer.graphics.ResolveAllGraphics(); Find.ColonistBar.drawer.Notify_RecachedEntries(); //save the pawn Pawn.ExposeData(); if (Pawn.Faction != faction) { Pawn.SetFaction(faction); } // pawn.Position = intv; }
private void TransformPawn(bool changeDef = true, bool keep = false) { //sets position, faction and map IntVec3 intv = parent.pawn.Position; Faction faction = parent.pawn.Faction; Map map = parent.pawn.Map; RegionListersUpdater.DeregisterInRegions(parent.pawn, map); //Change Race to Props.raceDef var thingDef = Props.raceDef ?? null; if (changeDef && thingDef != null && thingDef != parent.pawn.def) { parent.pawn.def = thingDef; long ageB = Pawn.ageTracker.AgeBiologicalTicks; long ageC = Pawn.ageTracker.AgeChronologicalTicks; Pawn.ageTracker = new Pawn_AgeTracker(Pawn); Pawn.ageTracker.AgeBiologicalTicks = ageB; Pawn.ageTracker.AgeChronologicalTicks = ageC; AlienRace.ThingDef_AlienRace alienRace = (AlienRace.ThingDef_AlienRace)thingDef; AlienRace.AlienPartGenerator.AlienComp alien = parent.pawn.TryGetComp <AlienRace.AlienPartGenerator.AlienComp>(); if (Props.colourSkinTwo || Props.colourSkin) { if (Props.colourSkin) { if (alien != null) { alien.skinColor = alienRace.alienRace.generalSettings.alienPartGenerator.SkinColor(parent.pawn); } } if (Props.colourSkinTwo) { if (alien != null) { alien.skinColorSecond = alienRace.alienRace.generalSettings.alienPartGenerator.SkinColor(parent.pawn, false); } } parent.pawn.Notify_ColorChanged(); } if (Props.removeHair) { parent.pawn.story.hairDef = PawnHairChooser.RandomHairDefFor(Pawn, noHairFaction); } else { if (Props.colourHairTwo || Props.colourHair) { if (Props.colourHair) { if (alien != null) { Pawn.story.hairColor = alienRace.alienRace.generalSettings.alienPartGenerator.alienhaircolorgen.NewRandomizedColor();; } } if (Props.colourHairTwo) { if (alien != null) { alien.hairColorSecond = alienRace.alienRace.generalSettings.alienPartGenerator.alienhaircolorgen.NewRandomizedColor(); } } parent.pawn.Notify_ColorChanged(); } } string head = alienRace.alienRace.graphicPaths.GetCurrentGraphicPath(Pawn.ageTracker.CurLifeStageRace.def).head; Traverse.Create(Pawn.story).Field("headGraphicPath").SetValue(alienRace.alienRace.generalSettings.alienPartGenerator.RandomAlienHead(head, Pawn)); } //Remove Disallowed Traits int maxTraits; if (MoreTraitSlotsUtil.TryGetMaxTraitSlots(out int max)) { maxTraits = max; } else { maxTraits = 4; } if (parent.pawn.story.traits.allTraits.Any(x => Props.traitsToRemove.Any(y => y.def == x.def))) { foreach (ExtendedTraitEntry item in Props.traitsToRemove) { if (parent.pawn.story.traits.HasTrait(item.def)) { Rand.PushState(); if (Rand.Chance(item.Chance)) { parent.pawn.story.traits.allTraits.Remove(parent.pawn.story.traits.allTraits.Find(x => x.def == item.def)); } Rand.PopState(); } } } if (Props.traitsToAdd.Any(x => !parent.pawn.story.traits.HasTrait(x.def))) { foreach (ExtendedTraitEntry item in Props.traitsToAdd) { if (!parent.pawn.story.traits.HasTrait(item.def)) { Rand.PushState(); if (Rand.Chance(item.Chance)) { bool replace = false; int countTraits = parent.pawn.story.traits.allTraits.Count; if (countTraits >= maxTraits) { replace = true; } // Log.Message(string.Format("i have {0} of a max of {1} traits", countTraits, maxTraits)); Trait replacedTrait = parent.pawn.story.traits.allTraits.Where(x => Props.traitsToAdd.Any(y => y.def != x.def)).RandomElement(); if (replace) { parent.pawn.story.traits.allTraits.Remove(replacedTrait); } parent.pawn.story.traits.allTraits.Add(new Trait(item.def, item.degree)); } Rand.PopState(); } } } RegionListersUpdater.RegisterInRegions(parent.pawn, map); map.mapPawns.UpdateRegistryForPawn(parent.pawn); //Change BodyType to Props.bodyTypeDef if (!Pawn.RaceProps.hasGenders) { Pawn.gender = Gender.None; } if (Props.bodyTypeDef != null) { ChangeBodyType(parent.pawn, Props.bodyTypeDef); } //decache graphics parent.pawn.Drawer.renderer.graphics.ResolveAllGraphics(); Find.ColonistBar.drawer.Notify_RecachedEntries(); //save the pawn parent.pawn.ExposeData(); if (parent.pawn.Faction != faction) { parent.pawn.SetFaction(faction); } // pawn.Position = intv; }
/// <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); } }
private void TransformPawn(PawnKindDef kindDef, bool changeDef = true, bool keep = false) { //sets position, faction and map IntVec3 intv = parent.pawn.Position; Faction faction = parent.pawn.Faction; Map map = parent.pawn.Map; RegionListersUpdater.DeregisterInRegions(parent.pawn, map); //Change Race to Props.raceDef if (changeDef && kindDef != null && kindDef != parent.pawn.kindDef) { parent.pawn.def = kindDef.race; parent.pawn.kindDef = kindDef; long ageB = Pawn.ageTracker.AgeBiologicalTicks; long ageC = Pawn.ageTracker.AgeChronologicalTicks; Pawn.ageTracker = new Pawn_AgeTracker(Pawn); Pawn.ageTracker.AgeBiologicalTicks = ageB; Pawn.ageTracker.AgeChronologicalTicks = ageC; } RegionListersUpdater.RegisterInRegions(parent.pawn, map); map.mapPawns.UpdateRegistryForPawn(parent.pawn); //decache graphics parent.pawn.Drawer.renderer.graphics.ResolveAllGraphics(); // remove non whitelisted hediffs if (!Pawn.health.hediffSet.hediffs.NullOrEmpty()) { if (!Props.whitelists.NullOrEmpty()) { foreach (MetroidWhitelistDef list in Props.whitelists) { if (parent.pawn.health.hediffSet.hediffs.Any(x => !list.whitelist.Contains(x.def) && x != this.parent)) { List <Hediff> removeable = parent.pawn.health.hediffSet.hediffs.Where(x => !list.whitelist.Contains(x.def) && x != this.parent).ToList(); foreach (Hediff item in removeable) { if (item != this.parent) { Pawn.health.RemoveHediff(item); } } } } } else { List <Hediff> removeable = parent.pawn.health.hediffSet.hediffs; foreach (Hediff item in removeable) { if (item != this.parent) { Pawn.health.RemoveHediff(item); } } } } //save the pawn parent.pawn.ExposeData(); if (parent.pawn.Faction != faction) { parent.pawn.SetFaction(faction); } //spawn Husk if set if (Props.huskDef != null) { GenSpawn.Spawn(ThingMaker.MakeThing(Props.huskDef), parent.pawn.Position, parent.pawn.Map); } }
/// <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); } }