public CaninePepperGeneric(CanineModifiers canineModifiers, SimpleDescriptor abbreviatedName, SimpleDescriptor itemName, ItemDescriptor itemDescription,
                                   SimpleDescriptor appearance, int value = 10) : base()
        {
            modifiers     = canineModifiers;
            monetaryValue = value;

            abbreviated = abbreviatedName ?? throw new ArgumentNullException(nameof(abbreviatedName));
            name        = itemName ?? throw new ArgumentNullException(nameof(itemName));
            description = itemDescription ?? throw new ArgumentNullException(nameof(itemDescription));
            appearText  = appearance ?? throw new ArgumentNullException(nameof(appearance));
        }
Beispiel #2
0
        private static string StatChangeText(Creature target, CanineModifiers modifiers, double strengthIncrease, double speedIncrease, double intelligenceDecrease)
        {
            StringBuilder sb = new StringBuilder();

            if (modifiers.HasFlag(CanineModifiers.BLACK))
            {
                sb.Append(GlobalStrings.NewParagraph() + "You feel yourself relaxing as gentle warmth spreads through your body. Honestly you don't think you'd mind running into a demon or monster right now, they'd make for good entertainment.");
                if (target.relativeCorruption < 50)
                {
                    sb.Append(" You shake your head, blushing hotly. Where did that thought come from?");
                }
            }

            if (strengthIncrease > 0)
            {
                sb.Append(GlobalStrings.NewParagraph());
                if (strengthIncrease > 1)
                {
                    sb.Append("Your muscles ripple and grow, bulging outwards.");
                }
                else
                {
                    sb.Append("Your muscles feel more toned.");
                }
            }

            if (speedIncrease > 0)
            {
                sb.Append(GlobalStrings.NewParagraph());
                if (speedIncrease > 1)
                {
                    sb.Append("You find your muscles responding quicker, faster, and you feel an odd desire to go for a walk.");
                }
                else
                {
                    sb.Append("You feel quicker.");
                }
            }
            if (intelligenceDecrease > 0)
            {
                string howDumb = intelligenceDecrease > 1 ? "MUCH " : "";
                sb.Append(GlobalStrings.NewParagraph() + "You feel " + howDumb + "dumber.");
            }
            return(sb.ToString());
        }
 public CanineTFs(CanineModifiers canineModifiers) : base(canineModifiers)
 {
 }
 protected override string InitialTransformationText(CanineModifiers modifiers, bool crit) => CaninePepperGeneric.InitialTransformationText(modifiers, crit);
Beispiel #5
0
        private static string InitialTransformationText(CanineModifiers modifiers, bool crit)
        {
            //standard. simple, to the point.
            if (modifiers == CanineModifiers.STANDARD)
            {
                if (crit)
                {
                    return("The pepper tastes particularly potent, searingly hot and spicy.");
                }
                else
                {
                    return("The pepper is strangely spicy but very tasty.");
                }
            }

            //compound or non-standard type. start with appearance.
            StringBuilder sb = new StringBuilder();

            //by default, we're not expecting compound types, but we do support them
            //so, we check to see if each modifier flags is set, but we exit early whenever
            //we only have that modifier flag.
            //I'm fully expecting the compound nonsense to never be used, but whatever, it wasn't that hard to write.
            bool plural = modifiers.HasFlag(CanineModifiers.DOUBLE);

            if (modifiers.HasFlag(CanineModifiers.DOUBLE))
            {
                if (modifiers == CanineModifiers.DOUBLE)
                {
                    return("The double-pepper is strange, looking like it was formed when two peppers grew together near their bases. Not surprisingly, it takes twice as long to finish, and you could swear it was twice as delicious as well.");
                }
                else
                {
                    sb.Append("The double-pepper is strange, looking like it was formed when two peppers grew together near their bases. ");
                }
            }
            if (modifiers.HasFlag(CanineModifiers.LARGE))
            {
                if (modifiers == CanineModifiers.LARGE)
                {
                    return("The pepper is so large and thick that you have to eat it in several large bites. It is not as spicy as the normal ones, but is delicious and flavorful.");
                }
                else
                {
                    sb.Append((plural ? "Each section " : "This pepper ") + "is so large and thick, you have no doubt it'll take several bites to eat. ");
                    if (plural)
                    {
                        sb.Append(" them");
                    }
                    sb.Append(". ");
                }
            }
            if (modifiers.HasFlag(CanineModifiers.BLACK))
            {
                if (modifiers == CanineModifiers.BLACK)
                {
                    return("This pepper appears like a standard one, but with a distinct black color. It tastes sweet, but has a bit of a tangy aftertaste.");
                }
                else
                {
                    sb.Append("Its color, a distinct shade of black, " + (sb.Length != 0 ? "also " : "") + "sets it apart from other peppers, and you have little doubt that affects the flavor. ");
                }
            }
            if (modifiers.HasFlag(CanineModifiers.BULBY) || modifiers.HasFlag(CanineModifiers.KNOTTY))
            {
                if (modifiers == CanineModifiers.BULBY)
                {
                    return("You eat the pepper, even the two orb-like growths that have grown out from the base. It's delicious!");
                }
                else if (modifiers == CanineModifiers.KNOTTY)
                {
                    return("The pepper is a bit tough to eat due to the swollen bulge near the base, but you manage to cram it down and munch on it. It's extra spicy!");
                }
                else
                {
                    sb.Append("Its base has a distinct shape, bulging in a manner unlike what you're used to. It'll probably further complicate eating the thing, but you're sure you'll manage. ");
                }
            }

            //compound shape generic text.
            sb.Append("Despite the strage shape, you eventually manage to eat the entire thing. ");

            //now for the flavor. We only use one modifier for this, whichever procs first. Any modifiers with distinct
            //flavors are given first priority.
            if (modifiers.HasFlag(CanineModifiers.BLACK))
            {
                sb.Append("It initially tasted sweet, but your definitely getting a tangy after-taste. ");
            }
            else if (modifiers.HasFlag(CanineModifiers.KNOTTY))
            {
                sb.Append("It is definitely spicier than most other peppers, causing you to blink a few times. ");
            }
            else if (modifiers.HasFlag(CanineModifiers.LARGE))
            {
                sb.Append("It's far more mellow than your standard pepper, but it makes up for that in flavor");
            }
            else
            {
                sb.Append("It's quite delicious! ");
            }
            return(sb.ToString());
        }
Beispiel #6
0
 protected abstract string InitialTransformationText(CanineModifiers modifiers, bool crit);
Beispiel #7
0
        protected internal override string DoTransformation(Creature target, out bool isBadEnd)
        {
            isBadEnd = false;

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

            //crit is our modifier for basically all stats. 1 is default, though any non-standard will proc the non-default
            //standard also has a 15% chance of proccing it too.
            int crit = 1;

            if (modifiers > CanineModifiers.STANDARD || Utils.Rand(20) < 3)
            {
                crit = Utils.Rand(20) / 10 + 2;
            }
            bool hasCrit() => crit > 1;

            StringBuilder sb = new StringBuilder();

            bool DoKnotChanges(double delta)
            {
                if (target.hasCock)
                {
                    bool changed      = false;
                    int  dogCockCount = target.genitals.CountCocksOfType(CockType.DOG);
                    if (dogCockCount > 0)
                    {
                        C**k smallestKnot = target.cocks.MinItem(x => x.type == CockType.DOG ? (double?)x.knotMultiplier : null);
                        if (smallestKnot.knotMultiplier > 2)
                        {
                            delta /= 10;
                        }
                        else if (smallestKnot.knotMultiplier > 1.75)
                        {
                            delta /= 5;
                        }
                        else if (smallestKnot.knotMultiplier > 1.5)
                        {
                            delta /= 2;
                        }

                        double knotMultiplierDelta = smallestKnot.IncreaseKnotMultiplier(delta);
                        if (knotMultiplierDelta != 0)
                        {
                            sb.Append(EnlargedSmallestKnotText(target, target.cocks.IndexOf(smallestKnot), knotMultiplierDelta, dogCockCount > 1));
                            changed = true;
                        }
                    }


                    target.DeltaCreatureStats(sens: 0.5, lus: 5 * crit);
                    return(changed);
                }
                return(false);
            }

            sb.Append(InitialTransformationText(modifiers, hasCrit()));

            //bad end related checks
            if (hasCrit() && target.body.hasActiveFurData && target.face.type == FaceType.DOG && target.ears.type == EarType.DOG &&
                target.lowerBody.type == LowerBodyType.DOG && target.tail.type == TailType.DOG && target is IExtendedCreature extended)
            {
                //can get bad end.
                if (extended.extendedData.hasDoggoWarning && !extended.extendedData.resistsTFBadEnds)
                {
                    //bad end.
                    if (Utils.RandBool())
                    {
                        sb.Append(BadEndText(target));
                        isBadEnd = true;
                        return(ApplyChangesAndReturn(target, sb, 0));
                    }
                    //get lucky, but warn that they got lucky
                    else
                    {
                        sb.Append(DoggoWarningText(target, true));
                    }
                }
                //not warned
                else if (!extended.extendedData.hasDoggoWarning)
                {
                    //warn
                    extended.extendedData.hasDoggoWarning = true;
                    sb.Append(DoggoWarningText(target, false));
                }
            }
            //stat changes
            if (modifiers.HasFlag(CanineModifiers.BLACK))
            {
                target.IncreaseCreatureStats(lus: (byte)(5 + Utils.Rand(5)), lib: (byte)(2 + Utils.Rand(4)), corr: (byte)(2 + Utils.Rand(4)));
            }
            //stat changes (cont.)
            double strengthIncrease     = 0;
            double speedIncrease        = 0;
            double intelligenceDecrease = 0;

            if (target.relativeStrength < 50 && Utils.Rand(3) == 0)
            {
                strengthIncrease = target.IncreaseStrength(crit);
            }
            if (target.relativeSpeed < 30 && Utils.Rand(3) == 0)
            {
                speedIncrease = target.IncreaseSpeed(crit);
            }
            if (target.relativeIntelligence > 30 && Utils.Rand(3) == 0)
            {
                intelligenceDecrease = target.DecreaseIntelligence(crit);
            }

            sb.Append(StatChangeText(target, strengthIncrease, speedIncrease, intelligenceDecrease));

            //modifier effects (no cost)

            //double pepper
            if (modifiers.HasFlag(CanineModifiers.DOUBLE))
            {
                int dogCocks = target.genitals.CountCocksOfType(CockType.DOG);
                //already has 2+ dog cocks.
                if (dogCocks >= 2)
                {
                    //just treat it like a large. so we'll just bitwise or the
                    //large flag in.
                    modifiers |= CanineModifiers.LARGE;
                }
                //has no dog cocks.
                else if (dogCocks == 0)
                {
                    //has no cocks. - grow 2
                    if (target.cocks.Count == 0)
                    {
                        target.AddCock(CockType.DOG, 7 + Utils.Rand(7), 1.5 + Utils.Rand(10) / 10, 1.7);
                        target.AddCock(CockType.DOG, 7 + Utils.Rand(7), 1.5 + Utils.Rand(10) / 10, 1.7);

                        sb.Append(GrewTwoDogCocksHadNone(target));
                    }
                    //has one c**k. - grow one, change one
                    else if (target.cocks.Count == 1)
                    {
                        CockData oldCockData = target.cocks[0].AsReadOnlyData();

                        target.genitals.UpdateCockWithKnot(0, CockType.DOG, 1.5);
                        if (target.cocks[0].length < 10)
                        {
                            target.cocks[0].SetLength(10);
                        }
                        target.AddCock(CockType.DOG, 7 + Utils.Rand(7), 1.5 + Utils.Rand(10) / 10.0, 1.7);

                        sb.Append(ConvertedFirstDogCockGrewSecond(target, oldCockData));
                    }
                    //has 2+ cocks. -change 2
                    else
                    {
                        CockData firstOldData  = target.cocks[0].AsReadOnlyData();
                        CockData secondOldData = target.cocks[1].AsReadOnlyData();

                        target.genitals.UpdateCockWithKnot(0, CockType.DOG, 1.5);
                        if (target.cocks[0].length < 10)
                        {
                            target.cocks[0].SetLength(10);
                        }
                        target.genitals.UpdateCockWithKnot(1, CockType.DOG, 1.5);
                        if (target.cocks[1].length < 10)
                        {
                            target.cocks[1].SetLength(10);
                        }
                        sb.Append(ConvertedTwoCocksToDog(target, firstOldData, secondOldData));
                    }
                }
                //one dog c**k.
                else
                {
                    if (target.cocks.Count == 1)
                    {
                        target.AddCock(CockType.DOG, 7 + Utils.Rand(7), 1.5 + Utils.Rand(10) / 10.0, 1.7);
                        sb.Append(GrewSecondDogCockHadOne(target));
                    }
                    else
                    {
                        if (target.cocks[0].type == CockType.DOG)
                        {
                            CockData oldData = target.cocks[1].AsReadOnlyData();
                            target.genitals.UpdateCockWithKnot(1, CockType.DOG, 1.5);
                            if (target.cocks[1].length < 10)
                            {
                                target.cocks[1].SetLength(10);
                            }
                            sb.Append(ConvertedOneCockToDogHadOne(target, 1, oldData));
                        }
                        else
                        {
                            CockData oldData = target.cocks[0].AsReadOnlyData();

                            target.genitals.UpdateCockWithKnot(0, CockType.DOG, 1.5);
                            if (target.cocks[0].length < 10)
                            {
                                target.cocks[0].SetLength(10);
                            }
                            sb.Append(ConvertedOneCockToDogHadOne(target, 0, oldData));
                        }
                    }
                }

                target.IncreaseCreatureStats(lib: 2, lus: 50);
            }

            //there are two ways to proc this - either via a knotty modifier (written here), or via random chance and/or with a large pepper (written later)
            //however, a knotty pepper modifier has no tf cost, the other check does. also, this will modify a c**k if none have a dog knot, the other will not.
            if (modifiers.HasFlag(CanineModifiers.KNOTTY))
            {
                double delta = ((Utils.Rand(2) + 5) / 20) * crit;

                if (!DoKnotChanges(delta))
                {
                    if (target.hasCock)
                    {
                        CockData oldCockData = target.cocks[0].AsReadOnlyData();

                        double knotSize = 1.75;

                        if (target.cocks[0].hasKnot)
                        {
                            knotSize = Math.Max(2.1, target.cocks[0].knotMultiplier);
                        }

                        target.genitals.UpdateCockWithKnot(0, CockType.DOG, knotSize);
                        if (target.cocks[0].length < 10)
                        {
                            target.cocks[0].SetLength(10);
                        }
                        sb.Append(ConvertedOneCockToDog(target, 0, oldCockData));
                    }


                    else
                    {
                        sb.Append(WastedKnottyText(target));
                    }
                }
            }

            //bulby
            if (modifiers.HasFlag(CanineModifiers.BULBY))
            {
                if (!target.hasBalls)
                {
                    target.genitals.GrowBalls(2, 1);
                    target.DeltaCreatureStats(lib: 2, lus: -10);
                    sb.Append(GrewBallsText(target));
                }
                else if (target.balls.uniBall)
                {
                    BallsData oldData = target.balls.AsReadOnlyData();
                    target.genitals.ConvertToNormalBalls();
                    target.DeltaCreatureStats(lib: 1, lus: 1);

                    sb.Append(EnlargedBallsText(target, oldData));
                }
                else
                {
                    BallsData oldData = target.balls.AsReadOnlyData();

                    byte enlargeAmount = target.genitals.balls.EnlargeBalls(1);
                    target.IncreaseCreatureStats(lib: 1, lus: 3);

                    sb.Append(EnlargedBallsText(target, oldData));
                }
            }

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

            //tfs (cost 1).

            //restore neck
            if (target.neck.type != NeckType.defaultValue && Utils.Rand(4) == 0)
            {
                NeckData oldNeck = target.neck.AsReadOnlyData();
                target.RestoreNeck();

                sb.Append(RestoredNeckText(target, oldNeck));
                if (--remainingChanges <= 0)
                {
                    return(ApplyChangesAndReturn(target, sb, changeLimit - remainingChanges));
                }
            }

            //remove oviposition
            if (target.womb.canRemoveOviposition && Utils.Rand(5) == 0)
            {
                if (target.womb.ClearOviposition())
                {
                    sb.Append(RemovedOvipositionText(target));
                    if (--remainingChanges <= 0)
                    {
                        return(ApplyChangesAndReturn(target, sb, changeLimit - remainingChanges));
                    }
                }
            }

            //remove feather-hair
            if (RemoveFeatheryHair(target))
            {
                sb.Append(RemovedFeatheryHairText(target));
                if (--remainingChanges <= 0)
                {
                    return(ApplyChangesAndReturn(target, sb, changeLimit - remainingChanges));
                }
            }

            //knot multiplier (but not knotty)
            if (!modifiers.HasFlag(CanineModifiers.KNOTTY) && target.genitals.CountCocksOfType(CockType.DOG) > 0 && (modifiers.HasFlag(CanineModifiers.LARGE) || Utils.Rand(7) < 5))
            {
                double delta = ((Utils.Rand(2) + 1) / 20.0) * crit;
                if (DoKnotChanges(delta))
                {
                    if (--remainingChanges <= 0)
                    {
                        return(ApplyChangesAndReturn(target, sb, changeLimit - remainingChanges));
                    }
                }
            }

            //transform a c**k.
            if (target.genitals.CountCocksOfType(CockType.DOG) < target.cocks.Count && (modifiers.HasFlag(CanineModifiers.LARGE) || Utils.Rand(8) < 5))
            {
                C**k nonDoggo = target.cocks.FirstOrDefault(x => x.type != CockType.DOG && x.type != CockType.DEMON);                 //find any c**k that isn't a dog, but also isn't a demon c**k.
                if (nonDoggo != null)
                {
                    CockData oldData = nonDoggo.AsReadOnlyData();
                    int      index   = target.cocks.IndexOf(nonDoggo);
                    target.genitals.UpdateCock(index, CockType.DOG);

                    sb.Append(ConvertedOneCockToDog(target, index, oldData));


                    if (--remainingChanges <= 0)
                    {
                        return(ApplyChangesAndReturn(target, sb, changeLimit - remainingChanges));
                    }
                }
                else
                {
                    C**k demonSpecialCase = target.cocks.FirstOrDefault(x => x.type == CockType.DEMON);
                    int  index            = demonSpecialCase.cockIndex;
                    if (demonSpecialCase != null)
                    {
                        double delta = demonSpecialCase.IncreaseThickness(2);

                        if (delta != 0)
                        {
                            sb.Append(CouldntConvertDemonCockThickenedInstead(target, index, delta));
                            if (--remainingChanges <= 0)
                            {
                                return(ApplyChangesAndReturn(target, sb, changeLimit - remainingChanges));
                            }
                        }
                    }
                }
            }

            //update cum. now, if it reaches the cap, it simply uses the new flat amount adder (up to a certain point). it does not use the messy o****m perk
            //anymore because i've tried to remove calls to random perks because it's not very future-proof - what happens when a new perk is added that has a
            //similar effect? do we add that check literally everywhere too? (of course, if a perk is unique enough that nothing else will act in the same way,
            //that's fine. i dunno, it's difficult to try and clean everything up without being able to predict the future, which is admittedly impossible)
            if (target.hasCock && (target.genitals.cumMultiplier < 1.5 || target.genitals.additionalCum < 500) && Utils.RandBool())
            {
                double delta;
                bool   wasMultiplier;
                if (target.genitals.cumMultiplier < 1.5)
                {
                    delta         = target.genitals.IncreaseCumMultiplier(0.05 * crit);
                    wasMultiplier = true;
                }
                else
                {
                    delta         = target.genitals.AddFlatCumAmount(50);
                    wasMultiplier = false;
                }
                sb.Append(AddedCumText(target, delta, wasMultiplier));
            }

            if (target.hasCock && modifiers.HasFlag(CanineModifiers.LARGE))
            {
                C**k     smallest = target.genitals.ShortestCock();
                CockData oldData  = smallest.AsReadOnlyData();

                smallest.IncreaseLength(Utils.Rand(4) + 3);
                if (smallest.girth < 1)
                {
                    double delta = 1 - smallest.girth;
                    smallest.IncreaseThickness(delta);
                }
                sb.Append(GrewSmallestCockText(target, smallest.cockIndex, oldData));
            }

            //do female changes.

            //if we have a vag and > flat breasts.
            if (target.hasVagina && target.genitals.BiggestCupSize() > CupSize.FLAT)
            {
                byte breastCount = (byte)target.breasts.Count;
                if (breastCount < 3)
                {
                    BreastCollectionData oldBreastData = target.genitals.allBreasts.AsReadOnlyData();

                    //in vanilla code, we had some strange checks here that required the first row (and only the first row) be a certain size.
                    //now, we check all the rows, but no longer require any of them to be a certain size. instead, if it's not the right size, we make it that size,
                    //then add the row. so, for two rows, your first row must be at least a B-Cup. for 3: first must be a C cup, second an A cup.
                    //if we supported 4 rows, it'd be D, B, A.

                    for (int x = 0; x < target.breasts.Count; x++)
                    {
                        CupSize requiredSize = (CupSize)(byte)(target.breasts.Count - x);
                        if (x == 0)
                        {
                            requiredSize++;
                        }
                        if (target.breasts[x].cupSize < requiredSize)
                        {
                            target.breasts[x].SetCupSize(requiredSize);
                        }
                    }

                    target.genitals.AddBreastRow(target.breasts[breastCount - 1].cupSize.ByteEnumSubtract(1));


                    bool doCrit = false, uberCrit = false;
                    if (target.breasts.Count == 2)
                    {
                        target.IncreaseCreatureStats(lus: 5, sens: 6);
                    }
                    else if (hasCrit())
                    {
                        doCrit = true;
                        if (crit > 2)
                        {
                            target.IncreaseCreatureStats(sens: 6, lus: 15);
                            uberCrit = true;
                        }
                        else
                        {
                            target.IncreaseCreatureStats(sens: 3, lus: 10);
                        }
                    }

                    sb.Append(UpdateAndGrowAdditionalRowText(target, oldBreastData, doCrit, uberCrit));


                    if (--remainingChanges <= 0)
                    {
                        return(ApplyChangesAndReturn(target, sb, changeLimit - remainingChanges));
                    }
                }
                else
                {
                    BreastCollectionData oldBreastData = target.genitals.allBreasts.AsReadOnlyData();

                    //only call the normalize text if we actually did anything. related, anthro breasts now returns a bool. thanks, fox tfs.
                    if (target.genitals.AnthropomorphizeBreasts())
                    {
                        sb.Append(NormalizedBreastSizeText(target, oldBreastData));
                    }
                }
            }

            //Go into heat
            if (EnterHeat(target, out bool increased))
            {
                sb.Append(EnterOrIncreaseHeatText(target, increased));

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

            //doggo fantasies
            if (target.DogScore() > 3 && Utils.Rand(4) == 0)
            {
                sb.Append(DoggoFantasyText(target));
                target.IncreaseLust(5 + (target.libidoTrue / 20));

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

            //doggo tfs.

            if (!target.eyes.isDefault && Utils.Rand(5) == 0)
            {
                EyeData oldData = target.eyes.AsReadOnlyData();

                target.RestoreEyes();

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

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

            if (modifiers.HasFlag(CanineModifiers.BLACK) && !target.body.mainEpidermis.fur.IsIdenticalTo(HairFurColors.BLACK))
            {
                //for now, we're ignoring underbody, apparently.
                if (target.body.type != BodyType.SIMPLE_FUR)
                //if (target.body.mainEpidermis.currentType != EpidermisType.FUR)
                {
                    BodyData oldBodyData = target.body.AsReadOnlyData();

                    target.UpdateBody(BodyType.SIMPLE_FUR, new FurColor(HairFurColors.BLACK), FurTexture.THICK);

                    sb.Append(ChangedBodyTypeText(target, oldBodyData));
                }
                else
                {
                    ReadOnlyFurColor oldFur = target.body.mainEpidermis.fur.AsReadOnly();
                    target.body.ChangeMainFur(new FurColor(HairFurColors.MIDNIGHT_BLACK), FurTexture.THICK);
                    sb.Append(ChangedFurText(target, oldFur));
                }

                if (--remainingChanges <= 0)
                {
                    return(ApplyChangesAndReturn(target, sb, changeLimit - remainingChanges));
                }
            }
            //again, we're ignoring underbody for now, idk.
            else if (target.lowerBody.type == LowerBodyType.DOG && target.tail.type == TailType.DOG &&
                     //target.body.mainEpidermis.currentType != EpidermisType.FUR
                     target.body.type != BodyType.SIMPLE_FUR &&
                     Utils.Rand(4) == 0)
            {
                BodyData oldBodyData = target.body.AsReadOnlyData();

                FurColor oldFur = target.body.mainEpidermis.fur;

                target.UpdateBody(BodyType.SIMPLE_FUR, Utils.RandomChoice(Species.DOG.availableColors));

                sb.Append(ChangedBodyTypeText(target, oldBodyData));

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

            if (target.lowerBody.type != LowerBodyType.DOG && target.tail.type == TailType.DOG && target.ears.type == EarType.DOG && Utils.Rand(3) == 0)
            {
                LowerBodyData oldData = target.lowerBody.AsReadOnlyData();

                target.UpdateLowerBody(LowerBodyType.DOG);
                sb.Append(ChangedLowerBodyText(target, oldData));

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

            if (target.ears.type != EarType.DOG && target.tail.type == TailType.DOG && Utils.RandBool())
            {
                EarData oldData = target.ears.AsReadOnlyData();

                target.UpdateEars(EarType.DOG);

                sb.Append(ChangedEarsText(target, oldData));
                if (--remainingChanges <= 0)
                {
                    return(ApplyChangesAndReturn(target, sb, changeLimit - remainingChanges));
                }
            }

            if (target.tail.type != TailType.DOG && Utils.Rand(3) == 0)
            {
                TailData oldData = target.tail.AsReadOnlyData();

                target.UpdateTail(TailType.DOG);

                sb.Append(ChangedTailText(target, oldData));
                if (--remainingChanges <= 0)
                {
                    return(ApplyChangesAndReturn(target, sb, changeLimit - remainingChanges));
                }
            }

            if (target.arms.type != ArmType.DOG && target.body.isFurry && target.tail.type == TailType.DOG &&
                target.lowerBody.type == LowerBodyType.DOG && Utils.Rand(4) == 0)
            {
                ArmData oldArmData = target.arms.AsReadOnlyData();

                target.UpdateArms(ArmType.DOG);

                sb.Append(ChangedArmsText(target, oldArmData));
                if (--remainingChanges <= 0)
                {
                    return(ApplyChangesAndReturn(target, sb, changeLimit - remainingChanges));
                }
            }

            if (!target.gills.isDefault && Utils.Rand(4) == 0)
            {
                GillData oldGillData = target.gills.AsReadOnlyData();

                target.RestoreGills();

                sb.Append(RemovedGillsText(target, oldGillData));
                if (--remainingChanges <= 0)
                {
                    return(ApplyChangesAndReturn(target, sb, changeLimit - remainingChanges));
                }
            }

            if (target.body.isFurry && Utils.Rand(3) == 0)
            {
                target.DeltaCreatureStats(tou: 4, sens: -3);


                sb.Append(FallbackToughenUpText(target));

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

            if (target is CombatCreature cc2 && remainingChanges == changeLimit)
            {
                cc2.AddHP(20);
                sb.Append(NothingHappenedGainHpText(target));
                target.IncreaseLust(3);
            }

            return(ApplyChangesAndReturn(target, sb, changeLimit - remainingChanges));
        }
Beispiel #8
0
 public CanineTransformations(CanineModifiers canineModifiers)
 {
     modifiers = canineModifiers;
 }