/// <summary> /// preform the requested transform /// </summary> /// <param name="request">The request.</param> /// <returns></returns> protected override TransformedPawnSingle TransformImpl(TransformationRequest request) { Pawn original = request.originals[0]; if (request.addMutationToOriginal) { TryAddMutationsToPawn(original, request.cause, request.outputDef); } var reactionStatus = original.GetFormerHumanReactionStatus(); float newAge = TransformerUtility.ConvertAge(original, request.outputDef.race.race); Faction faction; faction = GetFaction(request, original); Gender newGender = TransformerUtility.GetTransformedGender(original, request.forcedGender, request.forcedGenderChance); var pRequest = FormerHumanUtilities.CreateSapientAnimalRequest(request.outputDef, original, faction, fixedGender: newGender); Pawn animalToSpawn = PawnGenerator.GeneratePawn(pRequest); //make the temp pawn animalToSpawn.needs.food.CurLevel = original.needs.food.CurLevel; // Copies the original pawn's food need to the animal's. animalToSpawn.needs.rest.CurLevel = original.needs.rest.CurLevel; // Copies the original pawn's rest need to the animal's. animalToSpawn.Name = original.Name; // Copies the original pawn's name to the animal's. float sapienceLevel = request.forcedSapienceLevel ?? GetSapienceLevel(original, animalToSpawn); if (request.forcedFaction == null && original.Faction != faction && original.Faction != animalToSpawn.Faction && FormerHumanUtilities.GetQuantizedSapienceLevel(sapienceLevel) <= SapienceLevel.MostlySapient) { //set the faction to the original's if mostly sapient or above animalToSpawn.SetFaction(original.Faction); } GiveTransformedPawnSapienceState(animalToSpawn, sapienceLevel); FormerHumanUtilities.InitializeTransformedPawn(original, animalToSpawn, sapienceLevel); //use a normal distribution? Pawn spawnedAnimal = SpawnAnimal(original, animalToSpawn); // Spawns the animal into the map. ReactionsHelper.OnPawnTransforms(original, animalToSpawn, reactionStatus); //this needs to happen before MakeSapientAnimal because that removes relations var rFaction = request.factionResponsible ?? GetFactionResponsible(original); var inst = new TransformedPawnSingle { original = original, animal = spawnedAnimal, factionResponsible = rFaction, reactionStatus = reactionStatus }; if (original.Spawned) { for (var i = 0; i < 10; i++) // Create a cloud of magic. { IntermittentMagicSprayer.ThrowMagicPuffDown(spawnedAnimal.Position.ToVector3(), spawnedAnimal.MapHeld); IntermittentMagicSprayer.ThrowMagicPuffUp(spawnedAnimal.Position.ToVector3(), spawnedAnimal.MapHeld); } } if (request.tale != null) // If a tale was provided, push it to the tale recorder. { TaleRecorder.RecordTale(request.tale, original, animalToSpawn); } Faction oFaction = original.FactionOrExtraHomeFaction; Map oMap = original.Map; //apply any other post tf effects ApplyPostTfEffects(original, animalToSpawn, request); TransformerUtility .CleanUpHumanPawnPostTf(original, request.cause); //now clean up the original pawn (remove apparel, drop'em, ect) //notify the faction that their member has been transformed oFaction?.Notify_MemberTransformed(original, animalToSpawn, oMap == null, oMap); if (!request.noLetter && reactionStatus == FormerHumanReactionStatus.Colonist || reactionStatus == FormerHumanReactionStatus.Prisoner) //only send the letter for colonists and prisoners { SendLetter(request, original, spawnedAnimal); } if (original.Spawned) { original.DeSpawn(); // Remove the original pawn from the current map. } DebugLogUtils.Assert(!PrisonBreakUtility.CanParticipateInPrisonBreak(original), $"{original.Name} has been cleaned up and de-spawned but can still participate in prison breaks"); return(inst); }