Example #1
0
 protected override string GrewFirstBreastRow(Creature target, BreastData oldBreasts)
 {
     if (Utils.Rand(2) == 0)
     {
         return(GlobalStrings.NewParagraph() + "Your " + oldBreasts.LongDescription() + " tingle for a moment before becoming larger.");
     }
     else
     {
         return(GlobalStrings.NewParagraph() + "You feel a little weight added to your chest as your " + oldBreasts.LongDescription() +
                " seem to inflate and settle in a larger size.");
     }
 }
Example #2
0
 protected override string StartedLactatingText(Creature target, BreastData preLactation)
 {
     return(GlobalStrings.NewParagraph() + "You gasp as your " + preLactation.LongDescription() + " feel like they are filling up with something. " +
            "Within moments, a drop of milk leaks from your " + preLactation.LongDescription() + "; <b> you are now lactating</b>.");
 }
Example #3
0
 //the original text only used the first row. it may make sense to give you the full collection so you can describe that.
 protected abstract string StartedLactatingText(Creature target, BreastData preLactation);
Example #4
0
 protected abstract string GrewFirstBreastRow(Creature target, BreastData oldBreasts);
Example #5
0
        protected internal override string DoTransformation(Creature target, out bool isBadEnd)
        {
            isBadEnd = false;

            //by default, this is 2 rolls at 50%, so a 25% chance of 0 additional tfs, 50% chance of 1 additional tf, 25% chance of 2 additional tfs.
            //also takes into consideration any perks that increase or decrease tf effectiveness. if you need to roll out your own, feel free to do so.
            int changeCount  = GenerateChangeCount(target, new int[] { 2, 2, 3 }, isEnhanced ? 3 : 1);
            int totalChanges = 0;

            StringBuilder sb = new StringBuilder();

            //For all of these, any text regarding the transformation should be instead abstracted out as an abstract string function. append the result of this abstract function
            //to the string builder declared above (aka sb.Append(FunctionCall(variables));) string builder is just a fancy way of telling the compiler that you'll be creating a
            //long string, piece by piece, so don't do any crazy optimizations first.

            //the initial text for starting the transformation. feel free to add additional variables to this if needed.
            sb.Append(InitialTransformationText(target));

            //Add any free changes here - these can occur even if the change count is 0. these include things such as change in stats (intelligence, etc)
            //change in height, hips, and/or butt, or other similar stats.

            //this will handle the edge case where the change count starts out as 0.

            //paste this line after any tf is applied, and it will: automatically decrement the remaining changes count. if it becomes 0 or less, apply the total number of changes
            //underwent to the target's change count (if applicable) and then return the StringBuilder content.
            //if (--remainingChanges <= 0) return ApplyChangesAndReturn(target, sb, changeCount - remainingChanges);

            //STATS
            //Increase player str:
            if (target.strength < 60 && Utils.Rand(3) == 0)
            {
                double delta = target.IncreaseStrength((60 - target.strength) / 10.0);
                sb.Append(StrengthUpText(delta));
            }
            //Increase player tou:
            if (target.toughness < 60 && Utils.Rand(3) == 0)
            {
                double delta = target.IncreaseToughness((60 - target.toughness) / 10.0);
                sb.Append(ToughnessUpText(delta));
            }
            //Decrease player spd if it is over 30:
            if (target.relativeSpeed > 30 && target.speed > 30 && Utils.Rand(3) == 0)
            {
                double decrease = target.DecreaseSpeed((target.speed - 30) / 10.0);
                sb.Append(SpeedDownText(decrease));
            }
            //Increase Corr, up to a max of 50.
            //this is silent, apparently.
            if (!isPurified && target.corruption < 50)
            {
                target.IncreaseCorruptionBy((50 - target.corruption) / 10.0);
            }

            if (totalChanges >= changeCount)
            {
                return(FinalizeTransformation(target, sb, totalChanges));
            }

            //Sex bits - Duderiffic
            if (target.cocks.Count > 0 && Utils.Rand(2) == 0 && !hyperHappy)
            {
                //If the player has at least one dick, decrease the size of each slightly,

                C**k     biggest   = target.genitals.LongestCock();
                CockData preChange = biggest.AsReadOnlyData();

                if (biggest.DecreaseLengthAndCheckIfNeedsRemoval(Utils.Rand(3) + 1))
                {
                    target.genitals.RemoveCock(biggest);
                    if (target.cocks.Count == 0 && !target.hasVagina)
                    {
                        BallsData oldBalls = target.balls.AsReadOnlyData();
                        target.AddVagina(0.25);
                        target.genitals.RemoveAllBalls();

                        sb.Append(MadeFemale(target, preChange, oldBalls));
                    }
                    else
                    {
                        sb.Append(ShrunkOneCock(target, preChange, true));
                    }
                }
                else
                {
                    sb.Append(ShrunkOneCock(target, preChange, false));
                }

                if (++totalChanges >= changeCount)
                {
                    return(FinalizeTransformation(target, sb, totalChanges));
                }
            }
            //Sex bits - girly
            bool boobsGrew = false;
            //Increase player's breast size, if they are FF or bigger
            //do not increase size, but do the other actions:
            CupSize biggestCup = target.genitals.BiggestCupSize();

            if ((biggestCup < CupSize.DD || (!isPurified && biggestCup < CupSize.FF)) && (isEnhanced || Utils.Rand(3) == 0))
            {
                BreastData oldBreasts = target.breasts[0].AsReadOnlyData();
                if (target.breasts[0].GrowBreasts((byte)(1 + Utils.Rand(3))) > 0)
                {
                    boobsGrew = true;
                    sb.Append(GrewFirstBreastRow(target, oldBreasts));
                    if (++totalChanges >= changeCount)
                    {
                        return(FinalizeTransformation(target, sb, totalChanges));
                    }
                }
                target.DeltaCreatureStats(sens: .5);
            }

            //Remove feathery hair
            HairData oldHair = target.hair.AsReadOnlyData();

            if (base.RemoveFeatheryHair(target))
            {
                sb.Append(RemovedFeatheryHairText(target, oldHair));
                if (++totalChanges >= changeCount)
                {
                    return(FinalizeTransformation(target, sb, totalChanges));
                }
            }

            //refresh the biggest cup size because we may have grown some breasts earlier.
            biggestCup = target.genitals.BiggestCupSize();

            //If breasts are D or bigger and are not lactating, they also start lactating:
            if (biggestCup >= CupSize.D && !target.genitals.isLactating && (isEnhanced || boobsGrew || Utils.Rand(3) == 0))
            {
                BreastData preLactation = target.breasts[0].AsReadOnlyData();
                target.genitals.StartLactating();

                sb.Append(StartedLactatingText(target, preLactation));

                if (++totalChanges >= changeCount)
                {
                    return(FinalizeTransformation(target, sb, totalChanges));
                }

                target.DeltaCreatureStats(sens: .5);
            }
            //Quad nipples and other 'special isEnhanced things.
            if (isEnhanced)
            {
                //QUAD DAMAGE!
                if (!target.genitals.hasQuadNipples)
                {
                    BreastCollectionData oldBreasts = target.genitals.allBreasts.AsReadOnlyData();
                    target.genitals.SetQuadNipples(true);

                    sb.Append(GrantQuadNippleText(target, oldBreasts));

                    if (++totalChanges >= changeCount)
                    {
                        return(FinalizeTransformation(target, sb, totalChanges));
                    }
                }
                else if (target.genitals.isLactating)
                {
                    BreastCollectionData oldBreasts = target.genitals.allBreasts.AsReadOnlyData();

                    target.genitals.BoostLactation(2.5);
                    double delta = 0;

                    if (target.genitals.nippleLength < 1 || (target.genitals.nippleLength < 1.5 && !isPurified))
                    {
                        delta = target.genitals.GrowNipples(0.25);
                        target.DeltaCreatureStats(sens: .5);
                    }

                    sb.Append(BoostedLactationText(target, oldBreasts, delta));

                    if (++totalChanges >= changeCount)
                    {
                        return(FinalizeTransformation(target, sb, totalChanges));
                    }
                }
            }
            //If breasts are already lactating and the player is not lactating beyond a reasonable level, they start lactating more:
            else
            {
                if (target.genitals.isLactating && (target.genitals.lactationStatus < LactationStatus.MODERATE ||
                                                    (!isPurified && target.genitals.lactationStatus < LactationStatus.STRONG)) && (isEnhanced || Utils.Rand(3) == 0))
                {
                    BreastCollectionData oldBreasts = target.genitals.allBreasts.AsReadOnlyData();
                    double delta = 0;

                    target.genitals.BoostLactation(0.75);

                    if (target.genitals.nippleLength < 1 || (target.genitals.nippleLength < 1.5 && !isPurified))
                    {
                        delta = target.genitals.GrowNipples(0.25);
                        target.DeltaCreatureStats(sens: .5);
                    }

                    sb.Append(BoostedLactationText(target, oldBreasts, delta));

                    if (++totalChanges >= changeCount)
                    {
                        return(FinalizeTransformation(target, sb, totalChanges));
                    }
                }
                else if (isPurified && target.genitals.lactationStatus >= LactationStatus.STRONG)
                {
                    BreastCollectionData oldData = target.genitals.allBreasts.AsReadOnlyData();

                    target.DeltaCreatureStats(sens: .5);
                    target.genitals.BoostLactation(-1);

                    sb.Append(BoostedLactationText(target, oldData, 0));


                    if (++totalChanges >= changeCount)
                    {
                        return(FinalizeTransformation(target, sb, totalChanges));
                    }
                }
            }
            //If breasts are lactating at a fair level
            //and the player has not received this status,
            //apply an effect where the player really wants
            //to give their milk to other creatures
            //(capable of getting them addicted):
            biggestCup = target.genitals.BiggestCupSize();

            if (!target.HasPerk <Feeder>() && target.genitals.lactationStatus >= LactationStatus.MODERATE && Utils.Rand(2) == 0 && biggestCup >= CupSize.DD &&
                target.IsCorruptEnough(35))
            {
                target.perks.AddPerk <Feeder>();
                sb.Append(GainedFeederPerk(target));
                if (++totalChanges >= changeCount)
                {
                    return(FinalizeTransformation(target, sb, totalChanges));
                }
            }
            //UNFINISHED
            //If player has addictive quality and drinks pure version, removes addictive quality.
            //if the player has a v****a and it is tight, it loosens.
            if (target.hasVagina)
            {
                VaginalLooseness targetLooseness = EnumHelper.Min(VaginalLooseness.LOOSE, target.genitals.maxVaginalLooseness);
                V****a           tightest        = target.genitals.TightestVagina();

                if (tightest.looseness < targetLooseness && Utils.Rand(2) == 0)
                {
                    VaginaData preLoosened = tightest.AsReadOnlyData();


                    tightest.IncreaseLooseness(2);
                    sb.Append(LoosenedTwatText(target, preLoosened));

                    if (++totalChanges >= changeCount)
                    {
                        return(FinalizeTransformation(target, sb, totalChanges));
                    }

                    target.DeltaCreatureStats(lus: 10);
                }
            }
            //Neck restore
            if (target.neck.type != NeckType.HUMANOID && Utils.Rand(4) == 0)
            {
                NeckData oldData = target.neck.AsReadOnlyData();
                target.RestoreNeck();
                sb.Append(RestoredNeckText(target, oldData));

                if (++totalChanges >= changeCount)
                {
                    return(FinalizeTransformation(target, sb, totalChanges));
                }
            }
            //Rear body restore
            if (target.back.type != BackType.SHARK_FIN && Utils.Rand(5) == 0)
            {
                BackData oldData = target.back.AsReadOnlyData();
                target.RestoreBack();
                sb.Append(RestoredBackText(target, oldData));
                if (++totalChanges >= changeCount)
                {
                    return(FinalizeTransformation(target, sb, totalChanges));
                }
            }
            //Ovi perk loss
            if (!isPurified && target.womb.canRemoveOviposition && Utils.Rand(5) == 0)
            {
                target.womb.ClearOviposition();
                sb.Append(ClearOvipositionText(target));

                if (++totalChanges >= changeCount)
                {
                    return(FinalizeTransformation(target, sb, totalChanges));
                }
            }
            //General Appearance (Tail -> Ears -> Paws(fur stripper) -> Face -> Horns
            //Give the player a bovine tail, same as the minotaur
            if (!isPurified && target.tail.type != TailType.COW && Utils.Rand(3) == 0)
            {
                TailData oldData = target.tail.AsReadOnlyData();

                target.UpdateTail(TailType.COW);
                sb.Append(ChangedTailText(target, oldData));

                if (++totalChanges >= changeCount)
                {
                    return(FinalizeTransformation(target, sb, totalChanges));
                }
            }
            //Give the player bovine ears, same as the minotaur
            if (!isPurified && target.ears.type != EarType.COW && Utils.Rand(4) == 0 && target.tail.type == TailType.COW)
            {
                EarData oldEars = target.ears.AsReadOnlyData();
                target.UpdateEars(EarType.COW);

                sb.Append(ChangedEarsText(target, oldEars));

                if (++totalChanges >= changeCount)
                {
                    return(FinalizeTransformation(target, sb, totalChanges));
                }
            }
            //If the player is under 7 feet in height, increase their height, similar to the minotaur
            if (((isEnhanced && target.build.heightInInches < 96) || target.build.heightInInches < 84) && Utils.Rand(2) == 0)
            {
                int temp = Utils.Rand(5) + 3;
                //Slow rate of growth near ceiling
                if (target.build.heightInInches > 74)
                {
                    temp = (int)Math.Floor(temp / 2.0);
                }
                //Never 0
                if (temp == 0)
                {
                    temp = 1;
                }


                byte delta = target.build.IncreaseHeight((byte)temp);

                sb.Append(GrowTaller(target, delta));

                if (++totalChanges >= changeCount)
                {
                    return(FinalizeTransformation(target, sb, totalChanges));
                }
            }
            //Give the player hoofs, if the player already has hoofs STRIP FUR
            if (!isPurified && target.lowerBody.type != LowerBodyType.HOOVED && target.ears.type == EarType.COW)
            {
                if (Utils.Rand(3) == 0)
                {
                    var oldData = target.lowerBody.AsReadOnlyData();
                    target.UpdateLowerBody(LowerBodyType.HOOVED);

                    sb.Append(ChangedLowerBodyText(target, oldData));

                    if (++totalChanges >= changeCount)
                    {
                        return(FinalizeTransformation(target, sb, totalChanges));
                    }
                }
            }
            //If the player's face is non-human, they gain a human face
            if (!isEnhanced && target.lowerBody.type == LowerBodyType.HOOVED && target.face.type != FaceType.HUMAN && Utils.Rand(4) == 0)
            {
                //Remove face before fur!
                var oldData = target.face.AsReadOnlyData();
                target.RestoreFace();
                sb.Append(RestoredFaceText(target, oldData));

                if (++totalChanges >= changeCount)
                {
                    return(FinalizeTransformation(target, sb, totalChanges));
                }
            }
            //isEnhanced get shitty fur
            var targetFur = new FurColor(HairFurColors.BLACK, HairFurColors.WHITE, FurMulticolorPattern.SPOTTED);

            if (isEnhanced && (!target.body.IsFurBodyType() || !target.body.mainEpidermis.fur.Equals(targetFur)))
            {
                var oldData = target.body.AsReadOnlyData();

                if (target.body.type == BodyType.SIMPLE_FUR)
                {
                    target.body.ChangeMainFur(targetFur);
                }
                else
                {
                    target.UpdateBody(BodyType.SIMPLE_FUR, targetFur);
                }

                if (!oldData.IsFurBodyType())
                {
                    sb.Append(ChangedBodyText(target, oldData));
                }
                else
                {
                    sb.Append(ChandedFurToSpots(target, oldData));
                }

                if (++totalChanges >= changeCount)
                {
                    return(FinalizeTransformation(target, sb, totalChanges));
                }
            }
            //if isEnhanced to probova give a shitty cow face
            else if (isEnhanced && target.face.type != FaceType.COW_MINOTAUR)
            {
                var oldData = target.face.AsReadOnlyData();
                target.UpdateFace(FaceType.COW_MINOTAUR);
                sb.Append(ChangedFaceText(target, oldData));

                if (++totalChanges >= changeCount)
                {
                    return(FinalizeTransformation(target, sb, totalChanges));
                }
            }
            //Give the player bovine horns, or increase their size, same as the minotaur
            //New horns or expanding mino horns
            if (!isPurified && Utils.Rand(3) == 0)
            {
                var oldHorns = target.horns.AsReadOnlyData();
                if (target.horns.type != HornType.BOVINE)
                {
                    target.UpdateHorns(HornType.BOVINE);
                    sb.Append(ChangedHornsText(target, oldHorns));

                    if (++totalChanges >= changeCount)
                    {
                        return(FinalizeTransformation(target, sb, totalChanges));
                    }
                }
                else if (target.horns.type == HornType.BOVINE && target.horns.CanStrengthen && target.horns.significantHornSize < 5)
                {
                    target.horns.StrengthenTransform();
                    sb.Append(MadeHornsBigger(target, oldHorns));

                    if (++totalChanges >= changeCount)
                    {
                        return(FinalizeTransformation(target, sb, totalChanges));
                    }
                }
            }

            //Increase the size of the player's hips, if they are not already childbearing or larger
            if (Utils.Rand(2) == 0 && target.hips.size < 15)
            {
                if (isPurified && target.hips.size < 8 || !isPurified)
                {
                    var oldHips = target.hips.AsReadOnlyData();

                    if (target.build.GrowHips((byte)(1 + Utils.Rand(4))) > 0)
                    {
                        sb.Append(WidenedHipsText(target, oldHips));
                        if (++totalChanges >= changeCount)
                        {
                            return(FinalizeTransformation(target, sb, totalChanges));
                        }
                    }
                }
            }
            // Remove gills
            if (Utils.Rand(4) == 0 && target.gills.type != GillType.NONE)
            {
                var oldData = target.gills.AsReadOnlyData();
                target.RestoreGills();

                sb.Append(RestoredGillsText(target, oldData));

                if (++totalChanges >= changeCount)
                {
                    return(FinalizeTransformation(target, sb, totalChanges));
                }
            }

            //Increase the size of the player's ass (less likely then hips), if it is not already somewhat big
            if (Utils.Rand(2) == 0 && target.butt.size < 8 || (!isPurified && target.butt.size < 13))
            {
                var oldButt = target.butt.AsReadOnlyData();
                if (target.butt.GrowButt((byte)(1 + Utils.Rand(2))) > 0)
                {
                    sb.Append(GrewButtText(target, oldButt));
                    if (++totalChanges >= changeCount)
                    {
                        return(FinalizeTransformation(target, sb, totalChanges));
                    }
                }
            }
            //Nipples Turn Back:
            if (target.genitals.hasBlackNipples && Utils.Rand(3) == 0)
            {
                target.genitals.SetBlackNipples(false);
                sb.Append(RemovedBlackNippleText(target));

                if (++totalChanges >= changeCount)
                {
                    return(FinalizeTransformation(target, sb, totalChanges));
                }
            }
            //Debugcunt
            if (target.hasVagina && target.vaginas.Any(x => x.type != VaginaType.defaultValue) && Utils.Rand(3) == 0)
            {
                var oldCollection = target.genitals.allVaginas.AsReadOnlyData();
                target.vaginas.ForEach(x => target.genitals.RestoreVagina(x));
                sb.Append(RestoreAllVaginasText(target, oldCollection));

                if (++totalChanges >= changeCount)
                {
                    return(FinalizeTransformation(target, sb, totalChanges));
                }
            }


            //this is the fallthrough that occurs when a tf item goes through all the changes, but does not proc enough of them to exit early. it will apply however many changes
            //occurred, then return the contents of the stringbuilder.
            return(FinalizeTransformation(target, sb, changeCount - totalChanges));
        }
 protected virtual string RemovedExcessRow(Creature target, BreastData oldRow)
 {
     return(target.genitals.allBreasts.RemovedExtraBreastRowGenericText(oldRow));
 }
Example #7
0
 protected virtual string RemovedAnExtraRowOfBreasts(Creature target, BreastData removedRow)
 {
     return(target.genitals.allBreasts.RemovedExtraBreastRowGenericText(removedRow));
 }
Example #8
0
        protected internal override string DoTransformation(Creature target, out bool isBadEnd)
        {
            isBadEnd = false;

            int changeCount      = GenerateChangeCount(target, new int[] { 2, 2 });
            int remainingChanges = changeCount;

            StringBuilder sb = new StringBuilder();

            sb.Append(InitialTransformText(target));
            target.DeltaCreatureStats(lus: 3, corr: 1);

            uint hpDelta;

            if (target.hasCock)
            {
                if (target.cocks[0].length < 12)
                {
                    CockData oldData = target.cocks[0].AsReadOnlyData();
                    double   temp    = target.cocks[0].IncreaseLength(Utils.Rand(2) + 2);
                    sb.Append(OneCockGrewLarger(target, oldData, temp));
                }
                hpDelta = 30;
            }
            else
            {
                hpDelta = 20;
            }

            if (target is CombatCreature healthCheck)
            {
                healthCheck.AddHP((uint)(hpDelta + healthCheck.toughness / 3));
                sb.Append(GainVitalityText(target));
            }
            if (remainingChanges <= 0)
            {
                return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges));
            }

            //Red or orange skin!
            if (Utils.Rand(30) == 0 && !Array.Exists(Species.IMP.availableTones, x => x == target.body.primarySkin.tone))
            {
                Tones oldSkinTone = target.body.primarySkin.tone;
                if (target.body.ChangeMainSkin(Utils.RandomChoice(Species.IMP.availableTones)))
                {
                    sb.Append(ChangeSkinColorText(target, oldSkinTone));

                    if (--remainingChanges <= 0)
                    {
                        return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges));
                    }
                }
            }


            //Shrinkage!
            if (Utils.Rand(2) == 0 && target.build.heightInInches > 42)
            {
                byte heightDelta = target.build.DecreaseHeight((byte)(1 + Utils.Rand(3)));
                if (heightDelta > 0)
                {
                    sb.Append(GetShorterText(target, heightDelta));

                    if (--remainingChanges <= 0)
                    {
                        return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges));
                    }
                }
            }
            //Imp wings - I just kinda robbed this from demon changeCount ~Foxwells
            if (Utils.Rand(3) == 0 && ((target.wings.type != WingType.IMP && target.IsCorruptEnough(25)) || (target.wings.type == WingType.IMP && target.IsCorruptEnough(50))))
            {
                bool changedWings = false;
                //grow smalls to large
                if (target.wings.type == WingType.IMP)
                {
                    if (target.wings.GrowLarge())
                    {
                        sb.Append(EnlargenedImpWingsText(target));
                        changedWings = true;
                    }
                }
                else
                {
                    WingData oldData = target.wings.AsReadOnlyData();
                    if (target.UpdateWings(WingType.IMP))
                    {
                        sb.Append(GrowOrChangeWingsText(target, oldData));
                        changedWings = true;
                    }
                }

                if (changedWings)
                {
                    if (--remainingChanges <= 0)
                    {
                        return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges));
                    }
                }
            }

            //Imp tail, because that's a unique thing from what I see?
            if (Utils.Rand(3) == 0 && target.tail.type != TailType.IMP)
            {
                TailData oldData = target.tail.AsReadOnlyData();
                if (target.UpdateTail(TailType.IMP))
                {
                    sb.Append(GrowOrChangeTailText(target, oldData));
                    target.IncreaseCorruption(2);

                    if (--remainingChanges <= 0)
                    {
                        return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges));
                    }
                }
            }

            //Feets, needs red/orange skin and tail
            if (Species.IMP.availableTones.Contains(target.body.primarySkin.tone) && target.tail.type == TailType.IMP && target.lowerBody.type != LowerBodyType.IMP && Utils.Rand(3) == 0)
            {
                LowerBodyData oldData = target.lowerBody.AsReadOnlyData();
                if (target.UpdateLowerBody(LowerBodyType.IMP))
                {
                    sb.Append(ChangeLowerBodyText(target, oldData));

                    target.IncreaseCorruption(2);

                    if (--remainingChanges <= 0)
                    {
                        return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges));
                    }
                }
            }

            //Imp ears, needs red/orange skin and horns
            if (target.horns.type == HornType.IMP && Array.Exists(Species.IMP.availableTones, x => target.body.primarySkin.tone == x) && target.ears.type != EarType.IMP && Utils.Rand(3) == 0)
            {
                EarData oldData = target.ears.AsReadOnlyData();
                if (target.UpdateEars(EarType.IMP))
                {
                    sb.Append(ChangeEarsText(target, oldData));

                    target.IncreaseCorruption(2);
                    if (--remainingChanges <= 0)
                    {
                        return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges));
                    }
                }
            }

            //Horns, because why not?
            if (target.horns.type != HornType.IMP && Utils.RandBool())
            {
                HornData oldData = target.horns.AsReadOnlyData();
                if (target.UpdateHorns(HornType.IMP))
                {
                    sb.Append(ChangeOrGrowHornsText(target, oldData));

                    target.IncreaseCorruption(2);

                    if (--remainingChanges <= 0)
                    {
                        return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges));
                    }
                }
            }

            //Imp arms, needs orange/red skin. Also your hands turn human.
            if (Species.IMP.availableTones.Contains(target.body.primarySkin.tone) && target.arms.type != ArmType.IMP && Utils.Rand(3) == 0)
            {
                ArmData oldData = target.arms.AsReadOnlyData();
                if (target.UpdateArms(ArmType.IMP))
                {
                    sb.Append(ChangeArmText(target, oldData));

                    target.IncreaseCorruption(2);
                    if (--remainingChanges <= 0)
                    {
                        return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges));
                    }
                }
            }

            //Changes hair to red/dark red, shortens it, sets it normal, and makes it curly.
            if (!Species.IMP.availableHairColors.Contains(target.hair.hairColor) && Utils.Rand(3) == 0)
            {
                HairData oldHairData = target.hair.AsReadOnlyData();

                HairFurColors hairColor  = Utils.RandomChoice(Species.IMP.availableHairColors);
                double        hairLength = 1;

                if (target.hair.type != HairType.NORMAL)
                {
                    //also restarts hair growth if disabled.
                    target.UpdateHair(HairType.NORMAL, true, hairColor, newHairLength: hairLength, newStyle: HairStyle.CURLY);
                }
                else
                {
                    //also restarts hair growth if disabled.
                    target.hair.SetAll(hairLength, true, hairColor, style: HairStyle.CURLY);
                }
                sb.Append(HairChangedText(target, oldHairData));

                if (--remainingChanges <= 0)
                {
                    return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges));
                }
            }

            //Remove spare titties
            if (target.breasts.Count > 1 && Utils.Rand(3) == 0 && !hyperHappy)
            {
                BreastData toRemove = target.breasts[target.breasts.Count - 1].AsReadOnlyData();

                if (target.genitals.RemoveBreastRows() > 0)
                {
                    sb.Append(RemovedAnExtraRowOfBreasts(target, toRemove));

                    if (--remainingChanges <= 0)
                    {
                        return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges));
                    }
                }
            }
            //Shrink titties
            if (target.genitals.BiggestCupSize() > CupSize.FLAT && Utils.Rand(3) == 0 && !hyperHappy)
            {
                byte rowsAlreadyModified = 0;
                //temp3 stores how many rows are changed
                foreach (Breasts breast in target.breasts)
                {
                    //If this row is over threshhold
                    if (breast.cupSize > CupSize.FLAT)
                    {
                        CupSize oldSize = breast.cupSize;

                        byte delta;
                        //Big change
                        if (breast.cupSize > CupSize.EE_BIG)
                        {
                            delta = breast.ShrinkBreasts((byte)(2 + Utils.Rand(3)));
                        }
                        else
                        {
                            delta = breast.ShrinkBreasts(1);
                        }

                        if (delta != 0)
                        {
                            sb.Append(CurrentBreastRowChanged(target, breast.rowIndex, delta, rowsAlreadyModified));

                            rowsAlreadyModified++;
                        }
                    }
                }
                if (--remainingChanges <= 0)
                {
                    return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges));
                }
            }


            //Free extra nipple removal service
            if (target.genitals.hasQuadNipples && Utils.Rand(3) == 0)
            {
                target.genitals.SetQuadNipples(false);

                sb.Append(RemovedQuadNippleText(target));

                target.DecreaseSensitivity(3);
                if (--remainingChanges <= 0)
                {
                    return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges));
                }
            }

            //Neck restore
            if (target.neck.type != NeckType.defaultValue && Utils.Rand(4) == 0)
            {
                NeckData oldData = target.neck.AsReadOnlyData();
                if (target.RestoreNeck())
                {
                    sb.Append(RestoredNeckText(target, oldData));

                    if (--remainingChanges <= 0)
                    {
                        return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges));
                    }
                }
            }
            //Rear body restore
            if (target.back.type != BackType.defaultValue && Utils.Rand(5) == 0)
            {
                BackData oldData = target.back.AsReadOnlyData();
                if (target.RestoreBack())
                {
                    sb.Append(RestoredBackText(target, oldData));

                    if (--remainingChanges <= 0)
                    {
                        return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges));
                    }
                }
            }
            //Ovi perk loss
            if (target is Player && Utils.Rand(5) == 0)
            {
                if (((PlayerWomb)target.womb).ClearOviposition())
                {
                    sb.Append(RemovedOvipositionText(target));

                    if (--remainingChanges <= 0)
                    {
                        return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges));
                    }
                }
            }

            //You lotta imp? Time to turn male!
            //Unless you're one of the hyper happy assholes I guess
            //For real tho doesn't seem like female imps exist? Guess they're goblins
            if (target.ImpScore() >= 4 && !hyperHappy)
            {
                bool         changedSomething = false;
                GenitalsData oldGenitals      = target.genitals.AsReadOnlyData();

                changedSomething |= target.genitals.RemoveExtraBreastRows() > 0;
                changedSomething |= target.breasts[0].MakeMale(true);
                changedSomething |= target.RemoveAllVaginas() > 0;

                if (!target.hasCock)
                {
                    changedSomething |= target.AddCock(CockType.HUMAN, 12, 2);
                }
                if (target.balls.count == 0)
                {
                    changedSomething |= target.genitals.GrowBalls(2);
                }

                if (changedSomething)
                {
                    sb.Append(ImpifiedText(target, oldGenitals));
                    remainingChanges--;
                    target.IncreaseCorruption(20);
                }
            }
            return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges));
        }